root/sound/soc/bcm/cygnus-ssp.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. cygnus_dai_get_portinfo
  2. audio_ssp_init_portregs
  3. audio_ssp_in_enable
  4. audio_ssp_in_disable
  5. audio_ssp_out_enable
  6. audio_ssp_out_disable
  7. pll_configure_mclk
  8. cygnus_ssp_set_clocks
  9. cygnus_ssp_hw_params
  10. cygnus_ssp_set_sysclk
  11. cygnus_ssp_startup
  12. cygnus_ssp_shutdown
  13. cygnus_ssp_set_custom_fsync_width
  14. cygnus_ssp_set_fmt
  15. cygnus_ssp_trigger
  16. cygnus_set_dai_tdm_slot
  17. cygnus_ssp_suspend
  18. cygnus_ssp_resume
  19. parse_ssp_child_node
  20. audio_clk_init
  21. cygnus_ssp_probe
  22. cygnus_ssp_remove

   1 /*
   2  * Copyright (C) 2014-2015 Broadcom Corporation
   3  *
   4  * This program is free software; you can redistribute it and/or
   5  * modify it under the terms of the GNU General Public License as
   6  * published by the Free Software Foundation version 2.
   7  *
   8  * This program is distributed "as is" WITHOUT ANY WARRANTY of any
   9  * kind, whether express or implied; without even the implied warranty
  10  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11  * GNU General Public License for more details.
  12  */
  13 #include <linux/clk.h>
  14 #include <linux/delay.h>
  15 #include <linux/init.h>
  16 #include <linux/io.h>
  17 #include <linux/module.h>
  18 #include <linux/of_device.h>
  19 #include <linux/slab.h>
  20 #include <sound/core.h>
  21 #include <sound/pcm.h>
  22 #include <sound/pcm_params.h>
  23 #include <sound/soc.h>
  24 #include <sound/soc-dai.h>
  25 
  26 #include "cygnus-ssp.h"
  27 
  28 #define DEFAULT_VCO    1354750204
  29 
  30 #define CAPTURE_FCI_ID_BASE 0x180
  31 #define CYGNUS_SSP_TRISTATE_MASK 0x001fff
  32 #define CYGNUS_PLLCLKSEL_MASK 0xf
  33 
  34 /* Used with stream_on field to indicate which streams are active */
  35 #define  PLAYBACK_STREAM_MASK   BIT(0)
  36 #define  CAPTURE_STREAM_MASK    BIT(1)
  37 
  38 #define I2S_STREAM_CFG_MASK      0xff003ff
  39 #define I2S_CAP_STREAM_CFG_MASK  0xf0
  40 #define SPDIF_STREAM_CFG_MASK    0x3ff
  41 #define CH_GRP_STEREO            0x1
  42 
  43 /* Begin register offset defines */
  44 #define AUD_MISC_SEROUT_OE_REG_BASE  0x01c
  45 #define AUD_MISC_SEROUT_SPDIF_OE  12
  46 #define AUD_MISC_SEROUT_MCLK_OE   3
  47 #define AUD_MISC_SEROUT_LRCK_OE   2
  48 #define AUD_MISC_SEROUT_SCLK_OE   1
  49 #define AUD_MISC_SEROUT_SDAT_OE   0
  50 
  51 /* AUD_FMM_BF_CTRL_xxx regs */
  52 #define BF_DST_CFG0_OFFSET  0x100
  53 #define BF_DST_CFG1_OFFSET  0x104
  54 #define BF_DST_CFG2_OFFSET  0x108
  55 
  56 #define BF_DST_CTRL0_OFFSET 0x130
  57 #define BF_DST_CTRL1_OFFSET 0x134
  58 #define BF_DST_CTRL2_OFFSET 0x138
  59 
  60 #define BF_SRC_CFG0_OFFSET  0x148
  61 #define BF_SRC_CFG1_OFFSET  0x14c
  62 #define BF_SRC_CFG2_OFFSET  0x150
  63 #define BF_SRC_CFG3_OFFSET  0x154
  64 
  65 #define BF_SRC_CTRL0_OFFSET 0x1c0
  66 #define BF_SRC_CTRL1_OFFSET 0x1c4
  67 #define BF_SRC_CTRL2_OFFSET 0x1c8
  68 #define BF_SRC_CTRL3_OFFSET 0x1cc
  69 
  70 #define BF_SRC_GRP0_OFFSET  0x1fc
  71 #define BF_SRC_GRP1_OFFSET  0x200
  72 #define BF_SRC_GRP2_OFFSET  0x204
  73 #define BF_SRC_GRP3_OFFSET  0x208
  74 
  75 #define BF_SRC_GRP_EN_OFFSET        0x320
  76 #define BF_SRC_GRP_FLOWON_OFFSET    0x324
  77 #define BF_SRC_GRP_SYNC_DIS_OFFSET  0x328
  78 
  79 /* AUD_FMM_IOP_OUT_I2S_xxx regs */
  80 #define OUT_I2S_0_STREAM_CFG_OFFSET 0xa00
  81 #define OUT_I2S_0_CFG_OFFSET        0xa04
  82 #define OUT_I2S_0_MCLK_CFG_OFFSET   0xa0c
  83 
  84 #define OUT_I2S_1_STREAM_CFG_OFFSET 0xa40
  85 #define OUT_I2S_1_CFG_OFFSET        0xa44
  86 #define OUT_I2S_1_MCLK_CFG_OFFSET   0xa4c
  87 
  88 #define OUT_I2S_2_STREAM_CFG_OFFSET 0xa80
  89 #define OUT_I2S_2_CFG_OFFSET        0xa84
  90 #define OUT_I2S_2_MCLK_CFG_OFFSET   0xa8c
  91 
  92 /* AUD_FMM_IOP_OUT_SPDIF_xxx regs */
  93 #define SPDIF_STREAM_CFG_OFFSET  0xac0
  94 #define SPDIF_CTRL_OFFSET        0xac4
  95 #define SPDIF_FORMAT_CFG_OFFSET  0xad8
  96 #define SPDIF_MCLK_CFG_OFFSET    0xadc
  97 
  98 /* AUD_FMM_IOP_PLL_0_xxx regs */
  99 #define IOP_PLL_0_MACRO_OFFSET    0xb00
 100 #define IOP_PLL_0_MDIV_Ch0_OFFSET 0xb14
 101 #define IOP_PLL_0_MDIV_Ch1_OFFSET 0xb18
 102 #define IOP_PLL_0_MDIV_Ch2_OFFSET 0xb1c
 103 
 104 #define IOP_PLL_0_ACTIVE_MDIV_Ch0_OFFSET 0xb30
 105 #define IOP_PLL_0_ACTIVE_MDIV_Ch1_OFFSET 0xb34
 106 #define IOP_PLL_0_ACTIVE_MDIV_Ch2_OFFSET 0xb38
 107 
 108 /* AUD_FMM_IOP_xxx regs */
 109 #define IOP_PLL_0_CONTROL_OFFSET     0xb04
 110 #define IOP_PLL_0_USER_NDIV_OFFSET   0xb08
 111 #define IOP_PLL_0_ACTIVE_NDIV_OFFSET 0xb20
 112 #define IOP_PLL_0_RESET_OFFSET       0xb5c
 113 
 114 /* AUD_FMM_IOP_IN_I2S_xxx regs */
 115 #define IN_I2S_0_STREAM_CFG_OFFSET 0x00
 116 #define IN_I2S_0_CFG_OFFSET        0x04
 117 #define IN_I2S_1_STREAM_CFG_OFFSET 0x40
 118 #define IN_I2S_1_CFG_OFFSET        0x44
 119 #define IN_I2S_2_STREAM_CFG_OFFSET 0x80
 120 #define IN_I2S_2_CFG_OFFSET        0x84
 121 
 122 /* AUD_FMM_IOP_MISC_xxx regs */
 123 #define IOP_SW_INIT_LOGIC          0x1c0
 124 
 125 /* End register offset defines */
 126 
 127 
 128 /* AUD_FMM_IOP_OUT_I2S_x_MCLK_CFG_0_REG */
 129 #define I2S_OUT_MCLKRATE_SHIFT 16
 130 
 131 /* AUD_FMM_IOP_OUT_I2S_x_MCLK_CFG_REG */
 132 #define I2S_OUT_PLLCLKSEL_SHIFT  0
 133 
 134 /* AUD_FMM_IOP_OUT_I2S_x_STREAM_CFG */
 135 #define I2S_OUT_STREAM_ENA  31
 136 #define I2S_OUT_STREAM_CFG_GROUP_ID  20
 137 #define I2S_OUT_STREAM_CFG_CHANNEL_GROUPING  24
 138 
 139 /* AUD_FMM_IOP_IN_I2S_x_CAP */
 140 #define I2S_IN_STREAM_CFG_CAP_ENA   31
 141 #define I2S_IN_STREAM_CFG_0_GROUP_ID 4
 142 
 143 /* AUD_FMM_IOP_OUT_I2S_x_I2S_CFG_REG */
 144 #define I2S_OUT_CFGX_CLK_ENA         0
 145 #define I2S_OUT_CFGX_DATA_ENABLE     1
 146 #define I2S_OUT_CFGX_DATA_ALIGNMENT  6
 147 #define I2S_OUT_CFGX_BITS_PER_SLOT  13
 148 #define I2S_OUT_CFGX_VALID_SLOT     14
 149 #define I2S_OUT_CFGX_FSYNC_WIDTH    18
 150 #define I2S_OUT_CFGX_SCLKS_PER_1FS_DIV32 26
 151 #define I2S_OUT_CFGX_SLAVE_MODE     30
 152 #define I2S_OUT_CFGX_TDM_MODE       31
 153 
 154 /* AUD_FMM_BF_CTRL_SOURCECH_CFGx_REG */
 155 #define BF_SRC_CFGX_SFIFO_ENA              0
 156 #define BF_SRC_CFGX_BUFFER_PAIR_ENABLE     1
 157 #define BF_SRC_CFGX_SAMPLE_CH_MODE         2
 158 #define BF_SRC_CFGX_SFIFO_SZ_DOUBLE        5
 159 #define BF_SRC_CFGX_NOT_PAUSE_WHEN_EMPTY  10
 160 #define BF_SRC_CFGX_BIT_RES               20
 161 #define BF_SRC_CFGX_PROCESS_SEQ_ID_VALID  31
 162 
 163 /* AUD_FMM_BF_CTRL_DESTCH_CFGx_REG */
 164 #define BF_DST_CFGX_CAP_ENA              0
 165 #define BF_DST_CFGX_BUFFER_PAIR_ENABLE   1
 166 #define BF_DST_CFGX_DFIFO_SZ_DOUBLE      2
 167 #define BF_DST_CFGX_NOT_PAUSE_WHEN_FULL 11
 168 #define BF_DST_CFGX_FCI_ID              12
 169 #define BF_DST_CFGX_CAP_MODE            24
 170 #define BF_DST_CFGX_PROC_SEQ_ID_VALID   31
 171 
 172 /* AUD_FMM_IOP_OUT_SPDIF_xxx */
 173 #define SPDIF_0_OUT_DITHER_ENA     3
 174 #define SPDIF_0_OUT_STREAM_ENA    31
 175 
 176 /* AUD_FMM_IOP_PLL_0_USER */
 177 #define IOP_PLL_0_USER_NDIV_FRAC   10
 178 
 179 /* AUD_FMM_IOP_PLL_0_ACTIVE */
 180 #define IOP_PLL_0_ACTIVE_NDIV_FRAC 10
 181 
 182 
 183 #define INIT_SSP_REGS(num) (struct cygnus_ssp_regs){ \
 184                 .i2s_stream_cfg = OUT_I2S_ ##num## _STREAM_CFG_OFFSET, \
 185                 .i2s_cap_stream_cfg = IN_I2S_ ##num## _STREAM_CFG_OFFSET, \
 186                 .i2s_cfg = OUT_I2S_ ##num## _CFG_OFFSET, \
 187                 .i2s_cap_cfg = IN_I2S_ ##num## _CFG_OFFSET, \
 188                 .i2s_mclk_cfg = OUT_I2S_ ##num## _MCLK_CFG_OFFSET, \
 189                 .bf_destch_ctrl = BF_DST_CTRL ##num## _OFFSET, \
 190                 .bf_destch_cfg = BF_DST_CFG ##num## _OFFSET, \
 191                 .bf_sourcech_ctrl = BF_SRC_CTRL ##num## _OFFSET, \
 192                 .bf_sourcech_cfg = BF_SRC_CFG ##num## _OFFSET, \
 193                 .bf_sourcech_grp = BF_SRC_GRP ##num## _OFFSET \
 194 }
 195 
 196 struct pll_macro_entry {
 197         u32 mclk;
 198         u32 pll_ch_num;
 199 };
 200 
 201 /*
 202  * PLL has 3 output channels (1x, 2x, and 4x). Below are
 203  * the common MCLK frequencies used by audio driver
 204  */
 205 static const struct pll_macro_entry pll_predef_mclk[] = {
 206         { 4096000, 0},
 207         { 8192000, 1},
 208         {16384000, 2},
 209 
 210         { 5644800, 0},
 211         {11289600, 1},
 212         {22579200, 2},
 213 
 214         { 6144000, 0},
 215         {12288000, 1},
 216         {24576000, 2},
 217 
 218         {12288000, 0},
 219         {24576000, 1},
 220         {49152000, 2},
 221 
 222         {22579200, 0},
 223         {45158400, 1},
 224         {90316800, 2},
 225 
 226         {24576000, 0},
 227         {49152000, 1},
 228         {98304000, 2},
 229 };
 230 
 231 #define CYGNUS_RATE_MIN     8000
 232 #define CYGNUS_RATE_MAX   384000
 233 
 234 /* List of valid frame sizes for tdm mode */
 235 static const int ssp_valid_tdm_framesize[] = {32, 64, 128, 256, 512};
 236 
 237 static const unsigned int cygnus_rates[] = {
 238          8000, 11025,  16000,  22050,  32000,  44100, 48000,
 239         88200, 96000, 176400, 192000, 352800, 384000
 240 };
 241 
 242 static const struct snd_pcm_hw_constraint_list cygnus_rate_constraint = {
 243         .count = ARRAY_SIZE(cygnus_rates),
 244         .list = cygnus_rates,
 245 };
 246 
 247 static struct cygnus_aio_port *cygnus_dai_get_portinfo(struct snd_soc_dai *dai)
 248 {
 249         struct cygnus_audio *cygaud = snd_soc_dai_get_drvdata(dai);
 250 
 251         return &cygaud->portinfo[dai->id];
 252 }
 253 
 254 static int audio_ssp_init_portregs(struct cygnus_aio_port *aio)
 255 {
 256         u32 value, fci_id;
 257         int status = 0;
 258 
 259         switch (aio->port_type) {
 260         case PORT_TDM:
 261                 value = readl(aio->cygaud->audio + aio->regs.i2s_stream_cfg);
 262                 value &= ~I2S_STREAM_CFG_MASK;
 263 
 264                 /* Set Group ID */
 265                 writel(aio->portnum,
 266                         aio->cygaud->audio + aio->regs.bf_sourcech_grp);
 267 
 268                 /* Configure the AUD_FMM_IOP_OUT_I2S_x_STREAM_CFG reg */
 269                 value |= aio->portnum << I2S_OUT_STREAM_CFG_GROUP_ID;
 270                 value |= aio->portnum; /* FCI ID is the port num */
 271                 value |= CH_GRP_STEREO << I2S_OUT_STREAM_CFG_CHANNEL_GROUPING;
 272                 writel(value, aio->cygaud->audio + aio->regs.i2s_stream_cfg);
 273 
 274                 /* Configure the AUD_FMM_BF_CTRL_SOURCECH_CFGX reg */
 275                 value = readl(aio->cygaud->audio + aio->regs.bf_sourcech_cfg);
 276                 value &= ~BIT(BF_SRC_CFGX_NOT_PAUSE_WHEN_EMPTY);
 277                 value |= BIT(BF_SRC_CFGX_SFIFO_SZ_DOUBLE);
 278                 value |= BIT(BF_SRC_CFGX_PROCESS_SEQ_ID_VALID);
 279                 writel(value, aio->cygaud->audio + aio->regs.bf_sourcech_cfg);
 280 
 281                 /* Configure the AUD_FMM_IOP_IN_I2S_x_CAP_STREAM_CFG_0 reg */
 282                 value = readl(aio->cygaud->i2s_in +
 283                         aio->regs.i2s_cap_stream_cfg);
 284                 value &= ~I2S_CAP_STREAM_CFG_MASK;
 285                 value |= aio->portnum << I2S_IN_STREAM_CFG_0_GROUP_ID;
 286                 writel(value, aio->cygaud->i2s_in +
 287                         aio->regs.i2s_cap_stream_cfg);
 288 
 289                 /* Configure the AUD_FMM_BF_CTRL_DESTCH_CFGX_REG_BASE reg */
 290                 fci_id = CAPTURE_FCI_ID_BASE + aio->portnum;
 291 
 292                 value = readl(aio->cygaud->audio + aio->regs.bf_destch_cfg);
 293                 value |= BIT(BF_DST_CFGX_DFIFO_SZ_DOUBLE);
 294                 value &= ~BIT(BF_DST_CFGX_NOT_PAUSE_WHEN_FULL);
 295                 value |= (fci_id << BF_DST_CFGX_FCI_ID);
 296                 value |= BIT(BF_DST_CFGX_PROC_SEQ_ID_VALID);
 297                 writel(value, aio->cygaud->audio + aio->regs.bf_destch_cfg);
 298 
 299                 /* Enable the transmit pin for this port */
 300                 value = readl(aio->cygaud->audio + AUD_MISC_SEROUT_OE_REG_BASE);
 301                 value &= ~BIT((aio->portnum * 4) + AUD_MISC_SEROUT_SDAT_OE);
 302                 writel(value, aio->cygaud->audio + AUD_MISC_SEROUT_OE_REG_BASE);
 303                 break;
 304         case PORT_SPDIF:
 305                 writel(aio->portnum, aio->cygaud->audio + BF_SRC_GRP3_OFFSET);
 306 
 307                 value = readl(aio->cygaud->audio + SPDIF_CTRL_OFFSET);
 308                 value |= BIT(SPDIF_0_OUT_DITHER_ENA);
 309                 writel(value, aio->cygaud->audio + SPDIF_CTRL_OFFSET);
 310 
 311                 /* Enable and set the FCI ID for the SPDIF channel */
 312                 value = readl(aio->cygaud->audio + SPDIF_STREAM_CFG_OFFSET);
 313                 value &= ~SPDIF_STREAM_CFG_MASK;
 314                 value |= aio->portnum; /* FCI ID is the port num */
 315                 value |= BIT(SPDIF_0_OUT_STREAM_ENA);
 316                 writel(value, aio->cygaud->audio + SPDIF_STREAM_CFG_OFFSET);
 317 
 318                 value = readl(aio->cygaud->audio + aio->regs.bf_sourcech_cfg);
 319                 value &= ~BIT(BF_SRC_CFGX_NOT_PAUSE_WHEN_EMPTY);
 320                 value |= BIT(BF_SRC_CFGX_SFIFO_SZ_DOUBLE);
 321                 value |= BIT(BF_SRC_CFGX_PROCESS_SEQ_ID_VALID);
 322                 writel(value, aio->cygaud->audio + aio->regs.bf_sourcech_cfg);
 323 
 324                 /* Enable the spdif output pin */
 325                 value = readl(aio->cygaud->audio + AUD_MISC_SEROUT_OE_REG_BASE);
 326                 value &= ~BIT(AUD_MISC_SEROUT_SPDIF_OE);
 327                 writel(value, aio->cygaud->audio + AUD_MISC_SEROUT_OE_REG_BASE);
 328                 break;
 329         default:
 330                 dev_err(aio->cygaud->dev, "Port not supported\n");
 331                 status = -EINVAL;
 332         }
 333 
 334         return status;
 335 }
 336 
 337 static void audio_ssp_in_enable(struct cygnus_aio_port *aio)
 338 {
 339         u32 value;
 340 
 341         value = readl(aio->cygaud->audio + aio->regs.bf_destch_cfg);
 342         value |= BIT(BF_DST_CFGX_CAP_ENA);
 343         writel(value, aio->cygaud->audio + aio->regs.bf_destch_cfg);
 344 
 345         writel(0x1, aio->cygaud->audio + aio->regs.bf_destch_ctrl);
 346 
 347         value = readl(aio->cygaud->audio + aio->regs.i2s_cfg);
 348         value |= BIT(I2S_OUT_CFGX_CLK_ENA);
 349         value |= BIT(I2S_OUT_CFGX_DATA_ENABLE);
 350         writel(value, aio->cygaud->audio + aio->regs.i2s_cfg);
 351 
 352         value = readl(aio->cygaud->i2s_in + aio->regs.i2s_cap_stream_cfg);
 353         value |= BIT(I2S_IN_STREAM_CFG_CAP_ENA);
 354         writel(value, aio->cygaud->i2s_in + aio->regs.i2s_cap_stream_cfg);
 355 
 356         aio->streams_on |= CAPTURE_STREAM_MASK;
 357 }
 358 
 359 static void audio_ssp_in_disable(struct cygnus_aio_port *aio)
 360 {
 361         u32 value;
 362 
 363         value = readl(aio->cygaud->i2s_in + aio->regs.i2s_cap_stream_cfg);
 364         value &= ~BIT(I2S_IN_STREAM_CFG_CAP_ENA);
 365         writel(value, aio->cygaud->i2s_in + aio->regs.i2s_cap_stream_cfg);
 366 
 367         aio->streams_on &= ~CAPTURE_STREAM_MASK;
 368 
 369         /* If both playback and capture are off */
 370         if (!aio->streams_on) {
 371                 value = readl(aio->cygaud->audio + aio->regs.i2s_cfg);
 372                 value &= ~BIT(I2S_OUT_CFGX_CLK_ENA);
 373                 value &= ~BIT(I2S_OUT_CFGX_DATA_ENABLE);
 374                 writel(value, aio->cygaud->audio + aio->regs.i2s_cfg);
 375         }
 376 
 377         writel(0x0, aio->cygaud->audio + aio->regs.bf_destch_ctrl);
 378 
 379         value = readl(aio->cygaud->audio + aio->regs.bf_destch_cfg);
 380         value &= ~BIT(BF_DST_CFGX_CAP_ENA);
 381         writel(value, aio->cygaud->audio + aio->regs.bf_destch_cfg);
 382 }
 383 
 384 static int audio_ssp_out_enable(struct cygnus_aio_port *aio)
 385 {
 386         u32 value;
 387         int status = 0;
 388 
 389         switch (aio->port_type) {
 390         case PORT_TDM:
 391                 value = readl(aio->cygaud->audio + aio->regs.i2s_stream_cfg);
 392                 value |= BIT(I2S_OUT_STREAM_ENA);
 393                 writel(value, aio->cygaud->audio + aio->regs.i2s_stream_cfg);
 394 
 395                 writel(1, aio->cygaud->audio + aio->regs.bf_sourcech_ctrl);
 396 
 397                 value = readl(aio->cygaud->audio + aio->regs.i2s_cfg);
 398                 value |= BIT(I2S_OUT_CFGX_CLK_ENA);
 399                 value |= BIT(I2S_OUT_CFGX_DATA_ENABLE);
 400                 writel(value, aio->cygaud->audio + aio->regs.i2s_cfg);
 401 
 402                 value = readl(aio->cygaud->audio + aio->regs.bf_sourcech_cfg);
 403                 value |= BIT(BF_SRC_CFGX_SFIFO_ENA);
 404                 writel(value, aio->cygaud->audio + aio->regs.bf_sourcech_cfg);
 405 
 406                 aio->streams_on |= PLAYBACK_STREAM_MASK;
 407                 break;
 408         case PORT_SPDIF:
 409                 value = readl(aio->cygaud->audio + SPDIF_FORMAT_CFG_OFFSET);
 410                 value |= 0x3;
 411                 writel(value, aio->cygaud->audio + SPDIF_FORMAT_CFG_OFFSET);
 412 
 413                 writel(1, aio->cygaud->audio + aio->regs.bf_sourcech_ctrl);
 414 
 415                 value = readl(aio->cygaud->audio + aio->regs.bf_sourcech_cfg);
 416                 value |= BIT(BF_SRC_CFGX_SFIFO_ENA);
 417                 writel(value, aio->cygaud->audio + aio->regs.bf_sourcech_cfg);
 418                 break;
 419         default:
 420                 dev_err(aio->cygaud->dev,
 421                         "Port not supported %d\n", aio->portnum);
 422                 status = -EINVAL;
 423         }
 424 
 425         return status;
 426 }
 427 
 428 static int audio_ssp_out_disable(struct cygnus_aio_port *aio)
 429 {
 430         u32 value;
 431         int status = 0;
 432 
 433         switch (aio->port_type) {
 434         case PORT_TDM:
 435                 aio->streams_on &= ~PLAYBACK_STREAM_MASK;
 436 
 437                 /* If both playback and capture are off */
 438                 if (!aio->streams_on) {
 439                         value = readl(aio->cygaud->audio + aio->regs.i2s_cfg);
 440                         value &= ~BIT(I2S_OUT_CFGX_CLK_ENA);
 441                         value &= ~BIT(I2S_OUT_CFGX_DATA_ENABLE);
 442                         writel(value, aio->cygaud->audio + aio->regs.i2s_cfg);
 443                 }
 444 
 445                 /* set group_sync_dis = 1 */
 446                 value = readl(aio->cygaud->audio + BF_SRC_GRP_SYNC_DIS_OFFSET);
 447                 value |= BIT(aio->portnum);
 448                 writel(value, aio->cygaud->audio + BF_SRC_GRP_SYNC_DIS_OFFSET);
 449 
 450                 writel(0, aio->cygaud->audio + aio->regs.bf_sourcech_ctrl);
 451 
 452                 value = readl(aio->cygaud->audio + aio->regs.bf_sourcech_cfg);
 453                 value &= ~BIT(BF_SRC_CFGX_SFIFO_ENA);
 454                 writel(value, aio->cygaud->audio + aio->regs.bf_sourcech_cfg);
 455 
 456                 /* set group_sync_dis = 0 */
 457                 value = readl(aio->cygaud->audio + BF_SRC_GRP_SYNC_DIS_OFFSET);
 458                 value &= ~BIT(aio->portnum);
 459                 writel(value, aio->cygaud->audio + BF_SRC_GRP_SYNC_DIS_OFFSET);
 460 
 461                 value = readl(aio->cygaud->audio + aio->regs.i2s_stream_cfg);
 462                 value &= ~BIT(I2S_OUT_STREAM_ENA);
 463                 writel(value, aio->cygaud->audio + aio->regs.i2s_stream_cfg);
 464 
 465                 /* IOP SW INIT on OUT_I2S_x */
 466                 value = readl(aio->cygaud->i2s_in + IOP_SW_INIT_LOGIC);
 467                 value |= BIT(aio->portnum);
 468                 writel(value, aio->cygaud->i2s_in + IOP_SW_INIT_LOGIC);
 469                 value &= ~BIT(aio->portnum);
 470                 writel(value, aio->cygaud->i2s_in + IOP_SW_INIT_LOGIC);
 471                 break;
 472         case PORT_SPDIF:
 473                 value = readl(aio->cygaud->audio + SPDIF_FORMAT_CFG_OFFSET);
 474                 value &= ~0x3;
 475                 writel(value, aio->cygaud->audio + SPDIF_FORMAT_CFG_OFFSET);
 476                 writel(0, aio->cygaud->audio + aio->regs.bf_sourcech_ctrl);
 477 
 478                 value = readl(aio->cygaud->audio + aio->regs.bf_sourcech_cfg);
 479                 value &= ~BIT(BF_SRC_CFGX_SFIFO_ENA);
 480                 writel(value, aio->cygaud->audio + aio->regs.bf_sourcech_cfg);
 481                 break;
 482         default:
 483                 dev_err(aio->cygaud->dev,
 484                         "Port not supported %d\n", aio->portnum);
 485                 status = -EINVAL;
 486         }
 487 
 488         return status;
 489 }
 490 
 491 static int pll_configure_mclk(struct cygnus_audio *cygaud, u32 mclk,
 492         struct cygnus_aio_port *aio)
 493 {
 494         int i = 0, error;
 495         bool found = false;
 496         const struct pll_macro_entry *p_entry;
 497         struct clk *ch_clk;
 498 
 499         for (i = 0; i < ARRAY_SIZE(pll_predef_mclk); i++) {
 500                 p_entry = &pll_predef_mclk[i];
 501                 if (p_entry->mclk == mclk) {
 502                         found = true;
 503                         break;
 504                 }
 505         }
 506         if (!found) {
 507                 dev_err(cygaud->dev,
 508                         "%s No valid mclk freq (%u) found!\n", __func__, mclk);
 509                 return -EINVAL;
 510         }
 511 
 512         ch_clk = cygaud->audio_clk[p_entry->pll_ch_num];
 513 
 514         if ((aio->clk_trace.cap_en) && (!aio->clk_trace.cap_clk_en)) {
 515                 error = clk_prepare_enable(ch_clk);
 516                 if (error) {
 517                         dev_err(cygaud->dev, "%s clk_prepare_enable failed %d\n",
 518                                 __func__, error);
 519                         return error;
 520                 }
 521                 aio->clk_trace.cap_clk_en = true;
 522         }
 523 
 524         if ((aio->clk_trace.play_en) && (!aio->clk_trace.play_clk_en)) {
 525                 error = clk_prepare_enable(ch_clk);
 526                 if (error) {
 527                         dev_err(cygaud->dev, "%s clk_prepare_enable failed %d\n",
 528                                 __func__, error);
 529                         return error;
 530                 }
 531                 aio->clk_trace.play_clk_en = true;
 532         }
 533 
 534         error = clk_set_rate(ch_clk, mclk);
 535         if (error) {
 536                 dev_err(cygaud->dev, "%s Set MCLK rate failed: %d\n",
 537                         __func__, error);
 538                 return error;
 539         }
 540 
 541         return p_entry->pll_ch_num;
 542 }
 543 
 544 static int cygnus_ssp_set_clocks(struct cygnus_aio_port *aio)
 545 {
 546         u32 value;
 547         u32 mask = 0xf;
 548         u32 sclk;
 549         u32 mclk_rate;
 550         unsigned int bit_rate;
 551         unsigned int ratio;
 552 
 553         bit_rate = aio->bit_per_frame * aio->lrclk;
 554 
 555         /*
 556          * Check if the bit clock can be generated from the given MCLK.
 557          * MCLK must be a perfect multiple of bit clock and must be one of the
 558          * following values... (2,4,6,8,10,12,14)
 559          */
 560         if ((aio->mclk % bit_rate) != 0)
 561                 return -EINVAL;
 562 
 563         ratio = aio->mclk / bit_rate;
 564         switch (ratio) {
 565         case 2:
 566         case 4:
 567         case 6:
 568         case 8:
 569         case 10:
 570         case 12:
 571         case 14:
 572                 mclk_rate = ratio / 2;
 573                 break;
 574 
 575         default:
 576                 dev_err(aio->cygaud->dev,
 577                         "Invalid combination of MCLK and BCLK\n");
 578                 dev_err(aio->cygaud->dev, "lrclk = %u, bits/frame = %u, mclk = %u\n",
 579                         aio->lrclk, aio->bit_per_frame, aio->mclk);
 580                 return -EINVAL;
 581         }
 582 
 583         /* Set sclk rate */
 584         switch (aio->port_type) {
 585         case PORT_TDM:
 586                 sclk = aio->bit_per_frame;
 587                 if (sclk == 512)
 588                         sclk = 0;
 589 
 590                 /* sclks_per_1fs_div = sclk cycles/32 */
 591                 sclk /= 32;
 592 
 593                 /* Set number of bitclks per frame */
 594                 value = readl(aio->cygaud->audio + aio->regs.i2s_cfg);
 595                 value &= ~(mask << I2S_OUT_CFGX_SCLKS_PER_1FS_DIV32);
 596                 value |= sclk << I2S_OUT_CFGX_SCLKS_PER_1FS_DIV32;
 597                 writel(value, aio->cygaud->audio + aio->regs.i2s_cfg);
 598                 dev_dbg(aio->cygaud->dev,
 599                         "SCLKS_PER_1FS_DIV32 = 0x%x\n", value);
 600                 break;
 601         case PORT_SPDIF:
 602                 break;
 603         default:
 604                 dev_err(aio->cygaud->dev, "Unknown port type\n");
 605                 return -EINVAL;
 606         }
 607 
 608         /* Set MCLK_RATE ssp port (spdif and ssp are the same) */
 609         value = readl(aio->cygaud->audio + aio->regs.i2s_mclk_cfg);
 610         value &= ~(0xf << I2S_OUT_MCLKRATE_SHIFT);
 611         value |= (mclk_rate << I2S_OUT_MCLKRATE_SHIFT);
 612         writel(value, aio->cygaud->audio + aio->regs.i2s_mclk_cfg);
 613 
 614         dev_dbg(aio->cygaud->dev, "mclk cfg reg = 0x%x\n", value);
 615         dev_dbg(aio->cygaud->dev, "bits per frame = %u, mclk = %u Hz, lrclk = %u Hz\n",
 616                         aio->bit_per_frame, aio->mclk, aio->lrclk);
 617         return 0;
 618 }
 619 
 620 static int cygnus_ssp_hw_params(struct snd_pcm_substream *substream,
 621                                  struct snd_pcm_hw_params *params,
 622                                  struct snd_soc_dai *dai)
 623 {
 624         struct cygnus_aio_port *aio = cygnus_dai_get_portinfo(dai);
 625         int rate, bitres;
 626         u32 value;
 627         u32 mask = 0x1f;
 628         int ret = 0;
 629 
 630         dev_dbg(aio->cygaud->dev, "%s port = %d\n", __func__, aio->portnum);
 631         dev_dbg(aio->cygaud->dev, "params_channels %d\n",
 632                         params_channels(params));
 633         dev_dbg(aio->cygaud->dev, "rate %d\n", params_rate(params));
 634         dev_dbg(aio->cygaud->dev, "format %d\n", params_format(params));
 635 
 636         rate = params_rate(params);
 637 
 638         switch (aio->mode) {
 639         case CYGNUS_SSPMODE_TDM:
 640                 if ((rate == 192000) && (params_channels(params) > 4)) {
 641                         dev_err(aio->cygaud->dev, "Cannot run %d channels at %dHz\n",
 642                                 params_channels(params), rate);
 643                         return -EINVAL;
 644                 }
 645                 break;
 646         case CYGNUS_SSPMODE_I2S:
 647                 aio->bit_per_frame = 64; /* I2S must be 64 bit per frame */
 648                 break;
 649         default:
 650                 dev_err(aio->cygaud->dev,
 651                         "%s port running in unknown mode\n", __func__);
 652                 return -EINVAL;
 653         }
 654 
 655         if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 656                 value = readl(aio->cygaud->audio + aio->regs.bf_sourcech_cfg);
 657                 value &= ~BIT(BF_SRC_CFGX_BUFFER_PAIR_ENABLE);
 658                 value &= ~BIT(BF_SRC_CFGX_SAMPLE_CH_MODE);
 659                 writel(value, aio->cygaud->audio + aio->regs.bf_sourcech_cfg);
 660 
 661                 switch (params_format(params)) {
 662                 case SNDRV_PCM_FORMAT_S16_LE:
 663                         bitres = 16;
 664                         break;
 665 
 666                 case SNDRV_PCM_FORMAT_S32_LE:
 667                         /* 32 bit mode is coded as 0 */
 668                         bitres = 0;
 669                         break;
 670 
 671                 default:
 672                         return -EINVAL;
 673                 }
 674 
 675                 value = readl(aio->cygaud->audio + aio->regs.bf_sourcech_cfg);
 676                 value &= ~(mask << BF_SRC_CFGX_BIT_RES);
 677                 value |= (bitres << BF_SRC_CFGX_BIT_RES);
 678                 writel(value, aio->cygaud->audio + aio->regs.bf_sourcech_cfg);
 679 
 680         } else {
 681 
 682                 switch (params_format(params)) {
 683                 case SNDRV_PCM_FORMAT_S16_LE:
 684                         value = readl(aio->cygaud->audio +
 685                                         aio->regs.bf_destch_cfg);
 686                         value |= BIT(BF_DST_CFGX_CAP_MODE);
 687                         writel(value, aio->cygaud->audio +
 688                                         aio->regs.bf_destch_cfg);
 689                         break;
 690 
 691                 case SNDRV_PCM_FORMAT_S32_LE:
 692                         value = readl(aio->cygaud->audio +
 693                                         aio->regs.bf_destch_cfg);
 694                         value &= ~BIT(BF_DST_CFGX_CAP_MODE);
 695                         writel(value, aio->cygaud->audio +
 696                                         aio->regs.bf_destch_cfg);
 697                         break;
 698 
 699                 default:
 700                         return -EINVAL;
 701                 }
 702         }
 703 
 704         aio->lrclk = rate;
 705 
 706         if (!aio->is_slave)
 707                 ret = cygnus_ssp_set_clocks(aio);
 708 
 709         return ret;
 710 }
 711 
 712 /*
 713  * This function sets the mclk frequency for pll clock
 714  */
 715 static int cygnus_ssp_set_sysclk(struct snd_soc_dai *dai,
 716                         int clk_id, unsigned int freq, int dir)
 717 {
 718         int sel;
 719         u32 value;
 720         struct cygnus_aio_port *aio = cygnus_dai_get_portinfo(dai);
 721         struct cygnus_audio *cygaud = snd_soc_dai_get_drvdata(dai);
 722 
 723         dev_dbg(aio->cygaud->dev,
 724                 "%s Enter port = %d\n", __func__, aio->portnum);
 725         sel = pll_configure_mclk(cygaud, freq, aio);
 726         if (sel < 0) {
 727                 dev_err(aio->cygaud->dev,
 728                         "%s Setting mclk failed.\n", __func__);
 729                 return -EINVAL;
 730         }
 731 
 732         aio->mclk = freq;
 733 
 734         dev_dbg(aio->cygaud->dev, "%s Setting MCLKSEL to %d\n", __func__, sel);
 735         value = readl(aio->cygaud->audio + aio->regs.i2s_mclk_cfg);
 736         value &= ~(0xf << I2S_OUT_PLLCLKSEL_SHIFT);
 737         value |= (sel << I2S_OUT_PLLCLKSEL_SHIFT);
 738         writel(value, aio->cygaud->audio + aio->regs.i2s_mclk_cfg);
 739 
 740         return 0;
 741 }
 742 
 743 static int cygnus_ssp_startup(struct snd_pcm_substream *substream,
 744                                struct snd_soc_dai *dai)
 745 {
 746         struct cygnus_aio_port *aio = cygnus_dai_get_portinfo(dai);
 747 
 748         snd_soc_dai_set_dma_data(dai, substream, aio);
 749         if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 750                 aio->clk_trace.play_en = true;
 751         else
 752                 aio->clk_trace.cap_en = true;
 753 
 754         substream->runtime->hw.rate_min = CYGNUS_RATE_MIN;
 755         substream->runtime->hw.rate_max = CYGNUS_RATE_MAX;
 756 
 757         snd_pcm_hw_constraint_list(substream->runtime, 0,
 758                         SNDRV_PCM_HW_PARAM_RATE, &cygnus_rate_constraint);
 759         return 0;
 760 }
 761 
 762 static void cygnus_ssp_shutdown(struct snd_pcm_substream *substream,
 763                                struct snd_soc_dai *dai)
 764 {
 765         struct cygnus_aio_port *aio = cygnus_dai_get_portinfo(dai);
 766 
 767         if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 768                 aio->clk_trace.play_en = false;
 769         else
 770                 aio->clk_trace.cap_en = false;
 771 
 772         if (!aio->is_slave) {
 773                 u32 val;
 774 
 775                 val = readl(aio->cygaud->audio + aio->regs.i2s_mclk_cfg);
 776                 val &= CYGNUS_PLLCLKSEL_MASK;
 777                 if (val >= ARRAY_SIZE(aio->cygaud->audio_clk)) {
 778                         dev_err(aio->cygaud->dev, "Clk index %u is out of bounds\n",
 779                                 val);
 780                         return;
 781                 }
 782 
 783                 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 784                         if (aio->clk_trace.play_clk_en) {
 785                                 clk_disable_unprepare(aio->cygaud->
 786                                                 audio_clk[val]);
 787                                 aio->clk_trace.play_clk_en = false;
 788                         }
 789                 } else {
 790                         if (aio->clk_trace.cap_clk_en) {
 791                                 clk_disable_unprepare(aio->cygaud->
 792                                                 audio_clk[val]);
 793                                 aio->clk_trace.cap_clk_en = false;
 794                         }
 795                 }
 796         }
 797 }
 798 
 799 /*
 800  * Bit    Update  Notes
 801  * 31     Yes     TDM Mode        (1 = TDM, 0 = i2s)
 802  * 30     Yes     Slave Mode      (1 = Slave, 0 = Master)
 803  * 29:26  No      Sclks per frame
 804  * 25:18  Yes     FS Width
 805  * 17:14  No      Valid Slots
 806  * 13     No      Bits            (1 = 16 bits, 0 = 32 bits)
 807  * 12:08  No     Bits per samp
 808  * 07     Yes     Justifcation    (1 = LSB, 0 = MSB)
 809  * 06     Yes     Alignment       (1 = Delay 1 clk, 0 = no delay
 810  * 05     Yes     SCLK polarity   (1 = Rising, 0 = Falling)
 811  * 04     Yes     LRCLK Polarity  (1 = High for left, 0 = Low for left)
 812  * 03:02  Yes     Reserved - write as zero
 813  * 01     No      Data Enable
 814  * 00     No      CLK Enable
 815  */
 816 #define I2S_OUT_CFG_REG_UPDATE_MASK   0x3C03FF03
 817 
 818 /* Input cfg is same as output, but the FS width is not a valid field */
 819 #define I2S_IN_CFG_REG_UPDATE_MASK  (I2S_OUT_CFG_REG_UPDATE_MASK | 0x03FC0000)
 820 
 821 int cygnus_ssp_set_custom_fsync_width(struct snd_soc_dai *cpu_dai, int len)
 822 {
 823         struct cygnus_aio_port *aio = cygnus_dai_get_portinfo(cpu_dai);
 824 
 825         if ((len > 0) && (len < 256)) {
 826                 aio->fsync_width = len;
 827                 return 0;
 828         } else {
 829                 return -EINVAL;
 830         }
 831 }
 832 EXPORT_SYMBOL_GPL(cygnus_ssp_set_custom_fsync_width);
 833 
 834 static int cygnus_ssp_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
 835 {
 836         struct cygnus_aio_port *aio = cygnus_dai_get_portinfo(cpu_dai);
 837         u32 ssp_curcfg;
 838         u32 ssp_newcfg;
 839         u32 ssp_outcfg;
 840         u32 ssp_incfg;
 841         u32 val;
 842         u32 mask;
 843 
 844         dev_dbg(aio->cygaud->dev, "%s Enter  fmt: %x\n", __func__, fmt);
 845 
 846         if (aio->port_type == PORT_SPDIF)
 847                 return -EINVAL;
 848 
 849         ssp_newcfg = 0;
 850 
 851         switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 852         case SND_SOC_DAIFMT_CBM_CFM:
 853                 ssp_newcfg |= BIT(I2S_OUT_CFGX_SLAVE_MODE);
 854                 aio->is_slave = 1;
 855                 break;
 856         case SND_SOC_DAIFMT_CBS_CFS:
 857                 ssp_newcfg &= ~BIT(I2S_OUT_CFGX_SLAVE_MODE);
 858                 aio->is_slave = 0;
 859                 break;
 860         default:
 861                 return -EINVAL;
 862         }
 863 
 864         switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
 865         case SND_SOC_DAIFMT_I2S:
 866                 ssp_newcfg |= BIT(I2S_OUT_CFGX_DATA_ALIGNMENT);
 867                 ssp_newcfg |= BIT(I2S_OUT_CFGX_FSYNC_WIDTH);
 868                 aio->mode = CYGNUS_SSPMODE_I2S;
 869                 break;
 870 
 871         case SND_SOC_DAIFMT_DSP_A:
 872         case SND_SOC_DAIFMT_DSP_B:
 873                 ssp_newcfg |= BIT(I2S_OUT_CFGX_TDM_MODE);
 874 
 875                 /* DSP_A = data after FS, DSP_B = data during FS */
 876                 if ((fmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_DSP_A)
 877                         ssp_newcfg |= BIT(I2S_OUT_CFGX_DATA_ALIGNMENT);
 878 
 879                 if ((aio->fsync_width > 0) && (aio->fsync_width < 256))
 880                         ssp_newcfg |=
 881                                 (aio->fsync_width << I2S_OUT_CFGX_FSYNC_WIDTH);
 882                 else
 883                         ssp_newcfg |= BIT(I2S_OUT_CFGX_FSYNC_WIDTH);
 884 
 885                 aio->mode = CYGNUS_SSPMODE_TDM;
 886                 break;
 887 
 888         default:
 889                 return -EINVAL;
 890         }
 891 
 892         /*
 893          * SSP out cfg.
 894          * Retain bits we do not want to update, then OR in new bits
 895          */
 896         ssp_curcfg = readl(aio->cygaud->audio + aio->regs.i2s_cfg);
 897         ssp_outcfg = (ssp_curcfg & I2S_OUT_CFG_REG_UPDATE_MASK) | ssp_newcfg;
 898         writel(ssp_outcfg, aio->cygaud->audio + aio->regs.i2s_cfg);
 899 
 900         /*
 901          * SSP in cfg.
 902          * Retain bits we do not want to update, then OR in new bits
 903          */
 904         ssp_curcfg = readl(aio->cygaud->i2s_in + aio->regs.i2s_cap_cfg);
 905         ssp_incfg = (ssp_curcfg & I2S_IN_CFG_REG_UPDATE_MASK) | ssp_newcfg;
 906         writel(ssp_incfg, aio->cygaud->i2s_in + aio->regs.i2s_cap_cfg);
 907 
 908         val = readl(aio->cygaud->audio + AUD_MISC_SEROUT_OE_REG_BASE);
 909 
 910         /*
 911          * Configure the word clk and bit clk as output or tristate
 912          * Each port has 4 bits for controlling its pins.
 913          * Shift the mask based upon port number.
 914          */
 915         mask = BIT(AUD_MISC_SEROUT_LRCK_OE)
 916                         | BIT(AUD_MISC_SEROUT_SCLK_OE)
 917                         | BIT(AUD_MISC_SEROUT_MCLK_OE);
 918         mask = mask << (aio->portnum * 4);
 919         if (aio->is_slave)
 920                 /* Set bit for tri-state */
 921                 val |= mask;
 922         else
 923                 /* Clear bit for drive */
 924                 val &= ~mask;
 925 
 926         dev_dbg(aio->cygaud->dev, "%s  Set OE bits 0x%x\n", __func__, val);
 927         writel(val, aio->cygaud->audio + AUD_MISC_SEROUT_OE_REG_BASE);
 928 
 929         return 0;
 930 }
 931 
 932 static int cygnus_ssp_trigger(struct snd_pcm_substream *substream, int cmd,
 933                                struct snd_soc_dai *dai)
 934 {
 935         struct cygnus_aio_port *aio = cygnus_dai_get_portinfo(dai);
 936         struct cygnus_audio *cygaud = snd_soc_dai_get_drvdata(dai);
 937 
 938         dev_dbg(aio->cygaud->dev,
 939                 "%s cmd %d at port = %d\n", __func__, cmd, aio->portnum);
 940 
 941         switch (cmd) {
 942         case SNDRV_PCM_TRIGGER_START:
 943         case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
 944         case SNDRV_PCM_TRIGGER_RESUME:
 945                 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 946                         audio_ssp_out_enable(aio);
 947                 else
 948                         audio_ssp_in_enable(aio);
 949                 cygaud->active_ports++;
 950 
 951                 break;
 952 
 953         case SNDRV_PCM_TRIGGER_STOP:
 954         case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
 955         case SNDRV_PCM_TRIGGER_SUSPEND:
 956                 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 957                         audio_ssp_out_disable(aio);
 958                 else
 959                         audio_ssp_in_disable(aio);
 960                 cygaud->active_ports--;
 961                 break;
 962 
 963         default:
 964                 return -EINVAL;
 965         }
 966 
 967         return 0;
 968 }
 969 
 970 static int cygnus_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai,
 971         unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width)
 972 {
 973         struct cygnus_aio_port *aio = cygnus_dai_get_portinfo(cpu_dai);
 974         u32 value;
 975         int bits_per_slot = 0;     /* default to 32-bits per slot */
 976         int frame_bits;
 977         unsigned int active_slots;
 978         bool found = false;
 979         int i;
 980 
 981         if (tx_mask != rx_mask) {
 982                 dev_err(aio->cygaud->dev,
 983                         "%s tx_mask must equal rx_mask\n", __func__);
 984                 return -EINVAL;
 985         }
 986 
 987         active_slots = hweight32(tx_mask);
 988 
 989         if (active_slots > 16)
 990                 return -EINVAL;
 991 
 992         /* Slot value must be even */
 993         if (active_slots % 2)
 994                 return -EINVAL;
 995 
 996         /* We encode 16 slots as 0 in the reg */
 997         if (active_slots == 16)
 998                 active_slots = 0;
 999 
1000         /* Slot Width is either 16 or 32 */
1001         switch (slot_width) {
1002         case 16:
1003                 bits_per_slot = 1;
1004                 break;
1005         case 32:
1006                 bits_per_slot = 0;
1007                 break;
1008         default:
1009                 bits_per_slot = 0;
1010                 dev_warn(aio->cygaud->dev,
1011                         "%s Defaulting Slot Width to 32\n", __func__);
1012         }
1013 
1014         frame_bits = slots * slot_width;
1015 
1016         for (i = 0; i < ARRAY_SIZE(ssp_valid_tdm_framesize); i++) {
1017                 if (ssp_valid_tdm_framesize[i] == frame_bits) {
1018                         found = true;
1019                         break;
1020                 }
1021         }
1022 
1023         if (!found) {
1024                 dev_err(aio->cygaud->dev,
1025                         "%s In TDM mode, frame bits INVALID (%d)\n",
1026                         __func__, frame_bits);
1027                 return -EINVAL;
1028         }
1029 
1030         aio->bit_per_frame = frame_bits;
1031 
1032         dev_dbg(aio->cygaud->dev, "%s active_slots %u, bits per frame %d\n",
1033                         __func__, active_slots, frame_bits);
1034 
1035         /* Set capture side of ssp port */
1036         value = readl(aio->cygaud->i2s_in + aio->regs.i2s_cap_cfg);
1037         value &= ~(0xf << I2S_OUT_CFGX_VALID_SLOT);
1038         value |= (active_slots << I2S_OUT_CFGX_VALID_SLOT);
1039         value &= ~BIT(I2S_OUT_CFGX_BITS_PER_SLOT);
1040         value |= (bits_per_slot << I2S_OUT_CFGX_BITS_PER_SLOT);
1041         writel(value, aio->cygaud->i2s_in + aio->regs.i2s_cap_cfg);
1042 
1043         /* Set playback side of ssp port */
1044         value = readl(aio->cygaud->audio + aio->regs.i2s_cfg);
1045         value &= ~(0xf << I2S_OUT_CFGX_VALID_SLOT);
1046         value |= (active_slots << I2S_OUT_CFGX_VALID_SLOT);
1047         value &= ~BIT(I2S_OUT_CFGX_BITS_PER_SLOT);
1048         value |= (bits_per_slot << I2S_OUT_CFGX_BITS_PER_SLOT);
1049         writel(value, aio->cygaud->audio + aio->regs.i2s_cfg);
1050 
1051         return 0;
1052 }
1053 
1054 #ifdef CONFIG_PM_SLEEP
1055 static int cygnus_ssp_suspend(struct snd_soc_dai *cpu_dai)
1056 {
1057         struct cygnus_aio_port *aio = cygnus_dai_get_portinfo(cpu_dai);
1058 
1059         if (!aio->is_slave) {
1060                 u32 val;
1061 
1062                 val = readl(aio->cygaud->audio + aio->regs.i2s_mclk_cfg);
1063                 val &= CYGNUS_PLLCLKSEL_MASK;
1064                 if (val >= ARRAY_SIZE(aio->cygaud->audio_clk)) {
1065                         dev_err(aio->cygaud->dev, "Clk index %u is out of bounds\n",
1066                                 val);
1067                         return -EINVAL;
1068                 }
1069 
1070                 if (aio->clk_trace.cap_clk_en)
1071                         clk_disable_unprepare(aio->cygaud->audio_clk[val]);
1072                 if (aio->clk_trace.play_clk_en)
1073                         clk_disable_unprepare(aio->cygaud->audio_clk[val]);
1074 
1075                 aio->pll_clk_num = val;
1076         }
1077 
1078         return 0;
1079 }
1080 
1081 static int cygnus_ssp_resume(struct snd_soc_dai *cpu_dai)
1082 {
1083         struct cygnus_aio_port *aio = cygnus_dai_get_portinfo(cpu_dai);
1084         int error;
1085 
1086         if (!aio->is_slave) {
1087                 if (aio->clk_trace.cap_clk_en) {
1088                         error = clk_prepare_enable(aio->cygaud->
1089                                         audio_clk[aio->pll_clk_num]);
1090                         if (error) {
1091                                 dev_err(aio->cygaud->dev, "%s clk_prepare_enable failed\n",
1092                                         __func__);
1093                                 return -EINVAL;
1094                         }
1095                 }
1096                 if (aio->clk_trace.play_clk_en) {
1097                         error = clk_prepare_enable(aio->cygaud->
1098                                         audio_clk[aio->pll_clk_num]);
1099                         if (error) {
1100                                 if (aio->clk_trace.cap_clk_en)
1101                                         clk_disable_unprepare(aio->cygaud->
1102                                                 audio_clk[aio->pll_clk_num]);
1103                                 dev_err(aio->cygaud->dev, "%s clk_prepare_enable failed\n",
1104                                         __func__);
1105                                 return -EINVAL;
1106                         }
1107                 }
1108         }
1109 
1110         return 0;
1111 }
1112 #else
1113 #define cygnus_ssp_suspend NULL
1114 #define cygnus_ssp_resume  NULL
1115 #endif
1116 
1117 static const struct snd_soc_dai_ops cygnus_ssp_dai_ops = {
1118         .startup        = cygnus_ssp_startup,
1119         .shutdown       = cygnus_ssp_shutdown,
1120         .trigger        = cygnus_ssp_trigger,
1121         .hw_params      = cygnus_ssp_hw_params,
1122         .set_fmt        = cygnus_ssp_set_fmt,
1123         .set_sysclk     = cygnus_ssp_set_sysclk,
1124         .set_tdm_slot   = cygnus_set_dai_tdm_slot,
1125 };
1126 
1127 static const struct snd_soc_dai_ops cygnus_spdif_dai_ops = {
1128         .startup        = cygnus_ssp_startup,
1129         .shutdown       = cygnus_ssp_shutdown,
1130         .trigger        = cygnus_ssp_trigger,
1131         .hw_params      = cygnus_ssp_hw_params,
1132         .set_sysclk     = cygnus_ssp_set_sysclk,
1133 };
1134 
1135 #define INIT_CPU_DAI(num) { \
1136         .name = "cygnus-ssp" #num, \
1137         .playback = { \
1138                 .channels_min = 2, \
1139                 .channels_max = 16, \
1140                 .rates = SNDRV_PCM_RATE_KNOT, \
1141                 .formats = SNDRV_PCM_FMTBIT_S16_LE | \
1142                                 SNDRV_PCM_FMTBIT_S32_LE, \
1143         }, \
1144         .capture = { \
1145                 .channels_min = 2, \
1146                 .channels_max = 16, \
1147                 .rates = SNDRV_PCM_RATE_KNOT, \
1148                 .formats =  SNDRV_PCM_FMTBIT_S16_LE | \
1149                                 SNDRV_PCM_FMTBIT_S32_LE, \
1150         }, \
1151         .ops = &cygnus_ssp_dai_ops, \
1152         .suspend = cygnus_ssp_suspend, \
1153         .resume = cygnus_ssp_resume, \
1154 }
1155 
1156 static const struct snd_soc_dai_driver cygnus_ssp_dai_info[] = {
1157         INIT_CPU_DAI(0),
1158         INIT_CPU_DAI(1),
1159         INIT_CPU_DAI(2),
1160 };
1161 
1162 static const struct snd_soc_dai_driver cygnus_spdif_dai_info = {
1163         .name = "cygnus-spdif",
1164         .playback = {
1165                 .channels_min = 2,
1166                 .channels_max = 2,
1167                 .rates = SNDRV_PCM_RATE_KNOT,
1168                 .formats = SNDRV_PCM_FMTBIT_S16_LE |
1169                         SNDRV_PCM_FMTBIT_S32_LE,
1170         },
1171         .ops = &cygnus_spdif_dai_ops,
1172         .suspend = cygnus_ssp_suspend,
1173         .resume = cygnus_ssp_resume,
1174 };
1175 
1176 static struct snd_soc_dai_driver cygnus_ssp_dai[CYGNUS_MAX_PORTS];
1177 
1178 static const struct snd_soc_component_driver cygnus_ssp_component = {
1179         .name           = "cygnus-audio",
1180 };
1181 
1182 /*
1183  * Return < 0 if error
1184  * Return 0 if disabled
1185  * Return 1 if enabled and node is parsed successfully
1186  */
1187 static int parse_ssp_child_node(struct platform_device *pdev,
1188                                 struct device_node *dn,
1189                                 struct cygnus_audio *cygaud,
1190                                 struct snd_soc_dai_driver *p_dai)
1191 {
1192         struct cygnus_aio_port *aio;
1193         struct cygnus_ssp_regs ssp_regs[3];
1194         u32 rawval;
1195         int portnum = -1;
1196         enum cygnus_audio_port_type port_type;
1197 
1198         if (of_property_read_u32(dn, "reg", &rawval)) {
1199                 dev_err(&pdev->dev, "Missing reg property\n");
1200                 return -EINVAL;
1201         }
1202 
1203         portnum = rawval;
1204         switch (rawval) {
1205         case 0:
1206                 ssp_regs[0] = INIT_SSP_REGS(0);
1207                 port_type = PORT_TDM;
1208                 break;
1209         case 1:
1210                 ssp_regs[1] = INIT_SSP_REGS(1);
1211                 port_type = PORT_TDM;
1212                 break;
1213         case 2:
1214                 ssp_regs[2] = INIT_SSP_REGS(2);
1215                 port_type = PORT_TDM;
1216                 break;
1217         case 3:
1218                 port_type = PORT_SPDIF;
1219                 break;
1220         default:
1221                 dev_err(&pdev->dev, "Bad value for reg %u\n", rawval);
1222                 return -EINVAL;
1223         }
1224 
1225         aio = &cygaud->portinfo[portnum];
1226         aio->cygaud = cygaud;
1227         aio->portnum = portnum;
1228         aio->port_type = port_type;
1229         aio->fsync_width = -1;
1230 
1231         switch (port_type) {
1232         case PORT_TDM:
1233                 aio->regs = ssp_regs[portnum];
1234                 *p_dai = cygnus_ssp_dai_info[portnum];
1235                 aio->mode = CYGNUS_SSPMODE_UNKNOWN;
1236                 break;
1237 
1238         case PORT_SPDIF:
1239                 aio->regs.bf_sourcech_cfg = BF_SRC_CFG3_OFFSET;
1240                 aio->regs.bf_sourcech_ctrl = BF_SRC_CTRL3_OFFSET;
1241                 aio->regs.i2s_mclk_cfg = SPDIF_MCLK_CFG_OFFSET;
1242                 aio->regs.i2s_stream_cfg = SPDIF_STREAM_CFG_OFFSET;
1243                 *p_dai = cygnus_spdif_dai_info;
1244 
1245                 /* For the purposes of this code SPDIF can be I2S mode */
1246                 aio->mode = CYGNUS_SSPMODE_I2S;
1247                 break;
1248         default:
1249                 dev_err(&pdev->dev, "Bad value for port_type %d\n", port_type);
1250                 return -EINVAL;
1251         }
1252 
1253         dev_dbg(&pdev->dev, "%s portnum = %d\n", __func__, aio->portnum);
1254         aio->streams_on = 0;
1255         aio->cygaud->dev = &pdev->dev;
1256         aio->clk_trace.play_en = false;
1257         aio->clk_trace.cap_en = false;
1258 
1259         audio_ssp_init_portregs(aio);
1260         return 0;
1261 }
1262 
1263 static int audio_clk_init(struct platform_device *pdev,
1264                                                 struct cygnus_audio *cygaud)
1265 {
1266         int i;
1267         char clk_name[PROP_LEN_MAX];
1268 
1269         for (i = 0; i < ARRAY_SIZE(cygaud->audio_clk); i++) {
1270                 snprintf(clk_name, PROP_LEN_MAX, "ch%d_audio", i);
1271 
1272                 cygaud->audio_clk[i] = devm_clk_get(&pdev->dev, clk_name);
1273                 if (IS_ERR(cygaud->audio_clk[i]))
1274                         return PTR_ERR(cygaud->audio_clk[i]);
1275         }
1276 
1277         return 0;
1278 }
1279 
1280 static int cygnus_ssp_probe(struct platform_device *pdev)
1281 {
1282         struct device *dev = &pdev->dev;
1283         struct device_node *child_node;
1284         struct resource *res;
1285         struct cygnus_audio *cygaud;
1286         int err = -EINVAL;
1287         int node_count;
1288         int active_port_count;
1289 
1290         cygaud = devm_kzalloc(dev, sizeof(struct cygnus_audio), GFP_KERNEL);
1291         if (!cygaud)
1292                 return -ENOMEM;
1293 
1294         dev_set_drvdata(dev, cygaud);
1295 
1296         res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "aud");
1297         cygaud->audio = devm_ioremap_resource(dev, res);
1298         if (IS_ERR(cygaud->audio))
1299                 return PTR_ERR(cygaud->audio);
1300 
1301         res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "i2s_in");
1302         cygaud->i2s_in = devm_ioremap_resource(dev, res);
1303         if (IS_ERR(cygaud->i2s_in))
1304                 return PTR_ERR(cygaud->i2s_in);
1305 
1306         /* Tri-state all controlable pins until we know that we need them */
1307         writel(CYGNUS_SSP_TRISTATE_MASK,
1308                         cygaud->audio + AUD_MISC_SEROUT_OE_REG_BASE);
1309 
1310         node_count = of_get_child_count(pdev->dev.of_node);
1311         if ((node_count < 1) || (node_count > CYGNUS_MAX_PORTS)) {
1312                 dev_err(dev, "child nodes is %d.  Must be between 1 and %d\n",
1313                         node_count, CYGNUS_MAX_PORTS);
1314                 return -EINVAL;
1315         }
1316 
1317         active_port_count = 0;
1318 
1319         for_each_available_child_of_node(pdev->dev.of_node, child_node) {
1320                 err = parse_ssp_child_node(pdev, child_node, cygaud,
1321                                         &cygnus_ssp_dai[active_port_count]);
1322 
1323                 /* negative is err, 0 is active and good, 1 is disabled */
1324                 if (err < 0)
1325                         return err;
1326                 else if (!err) {
1327                         dev_dbg(dev, "Activating DAI: %s\n",
1328                                 cygnus_ssp_dai[active_port_count].name);
1329                         active_port_count++;
1330                 }
1331         }
1332 
1333         cygaud->dev = dev;
1334         cygaud->active_ports = 0;
1335 
1336         dev_dbg(dev, "Registering %d DAIs\n", active_port_count);
1337         err = devm_snd_soc_register_component(dev, &cygnus_ssp_component,
1338                                 cygnus_ssp_dai, active_port_count);
1339         if (err) {
1340                 dev_err(dev, "snd_soc_register_dai failed\n");
1341                 return err;
1342         }
1343 
1344         cygaud->irq_num = platform_get_irq(pdev, 0);
1345         if (cygaud->irq_num <= 0)
1346                 return cygaud->irq_num;
1347 
1348         err = audio_clk_init(pdev, cygaud);
1349         if (err) {
1350                 dev_err(dev, "audio clock initialization failed\n");
1351                 return err;
1352         }
1353 
1354         err = cygnus_soc_platform_register(dev, cygaud);
1355         if (err) {
1356                 dev_err(dev, "platform reg error %d\n", err);
1357                 return err;
1358         }
1359 
1360         return 0;
1361 }
1362 
1363 static int cygnus_ssp_remove(struct platform_device *pdev)
1364 {
1365         cygnus_soc_platform_unregister(&pdev->dev);
1366 
1367         return 0;
1368 }
1369 
1370 static const struct of_device_id cygnus_ssp_of_match[] = {
1371         { .compatible = "brcm,cygnus-audio" },
1372         {},
1373 };
1374 MODULE_DEVICE_TABLE(of, cygnus_ssp_of_match);
1375 
1376 static struct platform_driver cygnus_ssp_driver = {
1377         .probe          = cygnus_ssp_probe,
1378         .remove         = cygnus_ssp_remove,
1379         .driver         = {
1380                 .name   = "cygnus-ssp",
1381                 .of_match_table = cygnus_ssp_of_match,
1382         },
1383 };
1384 
1385 module_platform_driver(cygnus_ssp_driver);
1386 
1387 MODULE_ALIAS("platform:cygnus-ssp");
1388 MODULE_LICENSE("GPL v2");
1389 MODULE_AUTHOR("Broadcom");
1390 MODULE_DESCRIPTION("Cygnus ASoC SSP Interface");

/* [<][>][^][v][top][bottom][index][help] */