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