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