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.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 186struct 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 */ 195static 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 */ 225static const int ssp_valid_tdm_framesize[] = {32, 64, 128, 256, 512}; 226 227static const unsigned int cygnus_rates[] = { 228 8000, 11025, 16000, 22050, 32000, 44100, 48000, 229 88200, 96000, 176400, 192000, 352800, 384000 230}; 231 232static const struct snd_pcm_hw_constraint_list cygnus_rate_constraint = { 233 .count = ARRAY_SIZE(cygnus_rates), 234 .list = cygnus_rates, 235}; 236 237static 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 244static 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 327static 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 349static 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 374static 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 418static 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 481static 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 534static 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 610static 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 */ 705static 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 733static 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 752static 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 811int 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} 822EXPORT_SYMBOL_GPL(cygnus_ssp_set_custom_fsync_width); 823 824static 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 922static 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 960static 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 1045static 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 1074static 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 1085static 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 1120static 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 1136static 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 1146static 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 1173static 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 1179static 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 1191static struct snd_soc_dai_driver cygnus_ssp_dai[CYGNUS_MAX_PORTS]; 1192 1193static 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 */ 1205static 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 1281static 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 1298static 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 1380static void cygnus_ssp_remove(struct platform_device *pdev) 1381{ 1382 cygnus_soc_platform_unregister(&pdev->dev); 1383} 1384 1385static const struct of_device_id cygnus_ssp_of_match[] = { 1386 { .compatible = "brcm,cygnus-audio" }, 1387 {}, 1388}; 1389MODULE_DEVICE_TABLE(of, cygnus_ssp_of_match); 1390 1391static 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 1400module_platform_driver(cygnus_ssp_driver); 1401 1402MODULE_ALIAS("platform:cygnus-ssp"); 1403MODULE_LICENSE("GPL v2"); 1404MODULE_AUTHOR("Broadcom"); 1405MODULE_DESCRIPTION("Cygnus ASoC SSP Interface"); 1406