1 /* 2 * Copyright 2014 Emilio López <emilio@elopez.com.ar> 3 * Copyright 2014 Jon Smirl <jonsmirl@gmail.com> 4 * Copyright 2015 Maxime Ripard <maxime.ripard@free-electrons.com> 5 * 6 * Based on the Allwinner SDK driver, released under the GPL. 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 */ 18 19 #include <linux/init.h> 20 #include <linux/kernel.h> 21 #include <linux/module.h> 22 #include <linux/platform_device.h> 23 #include <linux/delay.h> 24 #include <linux/slab.h> 25 #include <linux/of.h> 26 #include <linux/of_platform.h> 27 #include <linux/of_address.h> 28 #include <linux/clk.h> 29 #include <linux/regmap.h> 30 31 #include <sound/core.h> 32 #include <sound/pcm.h> 33 #include <sound/pcm_params.h> 34 #include <sound/soc.h> 35 #include <sound/tlv.h> 36 #include <sound/initval.h> 37 #include <sound/dmaengine_pcm.h> 38 39 /* Codec DAC register offsets and bit fields */ 40 #define SUN4I_CODEC_DAC_DPC (0x00) 41 #define SUN4I_CODEC_DAC_DPC_EN_DA (31) 42 #define SUN4I_CODEC_DAC_DPC_DVOL (12) 43 #define SUN4I_CODEC_DAC_FIFOC (0x04) 44 #define SUN4I_CODEC_DAC_FIFOC_DAC_FS (29) 45 #define SUN4I_CODEC_DAC_FIFOC_FIR_VERSION (28) 46 #define SUN4I_CODEC_DAC_FIFOC_SEND_LASAT (26) 47 #define SUN4I_CODEC_DAC_FIFOC_TX_FIFO_MODE (24) 48 #define SUN4I_CODEC_DAC_FIFOC_DRQ_CLR_CNT (21) 49 #define SUN4I_CODEC_DAC_FIFOC_TX_TRIG_LEVEL (8) 50 #define SUN4I_CODEC_DAC_FIFOC_MONO_EN (6) 51 #define SUN4I_CODEC_DAC_FIFOC_TX_SAMPLE_BITS (5) 52 #define SUN4I_CODEC_DAC_FIFOC_DAC_DRQ_EN (4) 53 #define SUN4I_CODEC_DAC_FIFOC_FIFO_FLUSH (0) 54 #define SUN4I_CODEC_DAC_FIFOS (0x08) 55 #define SUN4I_CODEC_DAC_TXDATA (0x0c) 56 #define SUN4I_CODEC_DAC_ACTL (0x10) 57 #define SUN4I_CODEC_DAC_ACTL_DACAENR (31) 58 #define SUN4I_CODEC_DAC_ACTL_DACAENL (30) 59 #define SUN4I_CODEC_DAC_ACTL_MIXEN (29) 60 #define SUN4I_CODEC_DAC_ACTL_LDACLMIXS (15) 61 #define SUN4I_CODEC_DAC_ACTL_RDACRMIXS (14) 62 #define SUN4I_CODEC_DAC_ACTL_LDACRMIXS (13) 63 #define SUN4I_CODEC_DAC_ACTL_DACPAS (8) 64 #define SUN4I_CODEC_DAC_ACTL_MIXPAS (7) 65 #define SUN4I_CODEC_DAC_ACTL_PA_MUTE (6) 66 #define SUN4I_CODEC_DAC_ACTL_PA_VOL (0) 67 #define SUN4I_CODEC_DAC_TUNE (0x14) 68 #define SUN4I_CODEC_DAC_DEBUG (0x18) 69 70 /* Codec ADC register offsets and bit fields */ 71 #define SUN4I_CODEC_ADC_FIFOC (0x1c) 72 #define SUN4I_CODEC_ADC_FIFOC_EN_AD (28) 73 #define SUN4I_CODEC_ADC_FIFOC_RX_FIFO_MODE (24) 74 #define SUN4I_CODEC_ADC_FIFOC_RX_TRIG_LEVEL (8) 75 #define SUN4I_CODEC_ADC_FIFOC_MONO_EN (7) 76 #define SUN4I_CODEC_ADC_FIFOC_RX_SAMPLE_BITS (6) 77 #define SUN4I_CODEC_ADC_FIFOC_ADC_DRQ_EN (4) 78 #define SUN4I_CODEC_ADC_FIFOC_FIFO_FLUSH (0) 79 #define SUN4I_CODEC_ADC_FIFOS (0x20) 80 #define SUN4I_CODEC_ADC_RXDATA (0x24) 81 #define SUN4I_CODEC_ADC_ACTL (0x28) 82 #define SUN4I_CODEC_ADC_ACTL_ADC_R_EN (31) 83 #define SUN4I_CODEC_ADC_ACTL_ADC_L_EN (30) 84 #define SUN4I_CODEC_ADC_ACTL_PREG1EN (29) 85 #define SUN4I_CODEC_ADC_ACTL_PREG2EN (28) 86 #define SUN4I_CODEC_ADC_ACTL_VMICEN (27) 87 #define SUN4I_CODEC_ADC_ACTL_VADCG (20) 88 #define SUN4I_CODEC_ADC_ACTL_ADCIS (17) 89 #define SUN4I_CODEC_ADC_ACTL_PA_EN (4) 90 #define SUN4I_CODEC_ADC_ACTL_DDE (3) 91 #define SUN4I_CODEC_ADC_DEBUG (0x2c) 92 93 /* Other various ADC registers */ 94 #define SUN4I_CODEC_DAC_TXCNT (0x30) 95 #define SUN4I_CODEC_ADC_RXCNT (0x34) 96 #define SUN4I_CODEC_AC_SYS_VERI (0x38) 97 #define SUN4I_CODEC_AC_MIC_PHONE_CAL (0x3c) 98 99 struct sun4i_codec { 100 struct device *dev; 101 struct regmap *regmap; 102 struct clk *clk_apb; 103 struct clk *clk_module; 104 105 struct snd_dmaengine_dai_dma_data playback_dma_data; 106 }; 107 108 static void sun4i_codec_start_playback(struct sun4i_codec *scodec) 109 { 110 /* 111 * FIXME: according to the BSP, we might need to drive a PA 112 * GPIO high here on some boards 113 */ 114 115 /* Flush TX FIFO */ 116 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, 117 BIT(SUN4I_CODEC_DAC_FIFOC_FIFO_FLUSH), 118 BIT(SUN4I_CODEC_DAC_FIFOC_FIFO_FLUSH)); 119 120 /* Enable DAC DRQ */ 121 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, 122 BIT(SUN4I_CODEC_DAC_FIFOC_DAC_DRQ_EN), 123 BIT(SUN4I_CODEC_DAC_FIFOC_DAC_DRQ_EN)); 124 } 125 126 static void sun4i_codec_stop_playback(struct sun4i_codec *scodec) 127 { 128 /* 129 * FIXME: according to the BSP, we might need to drive a PA 130 * GPIO low here on some boards 131 */ 132 133 /* Disable DAC DRQ */ 134 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, 135 BIT(SUN4I_CODEC_DAC_FIFOC_DAC_DRQ_EN), 136 0); 137 } 138 139 static int sun4i_codec_trigger(struct snd_pcm_substream *substream, int cmd, 140 struct snd_soc_dai *dai) 141 { 142 struct snd_soc_pcm_runtime *rtd = substream->private_data; 143 struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card); 144 145 if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK) 146 return -ENOTSUPP; 147 148 switch (cmd) { 149 case SNDRV_PCM_TRIGGER_START: 150 case SNDRV_PCM_TRIGGER_RESUME: 151 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 152 sun4i_codec_start_playback(scodec); 153 break; 154 155 case SNDRV_PCM_TRIGGER_STOP: 156 case SNDRV_PCM_TRIGGER_SUSPEND: 157 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 158 sun4i_codec_stop_playback(scodec); 159 break; 160 161 default: 162 return -EINVAL; 163 } 164 165 return 0; 166 } 167 168 static int sun4i_codec_prepare(struct snd_pcm_substream *substream, 169 struct snd_soc_dai *dai) 170 { 171 struct snd_soc_pcm_runtime *rtd = substream->private_data; 172 struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card); 173 u32 val; 174 175 if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK) 176 return -ENOTSUPP; 177 178 /* Flush the TX FIFO */ 179 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, 180 BIT(SUN4I_CODEC_DAC_FIFOC_FIFO_FLUSH), 181 BIT(SUN4I_CODEC_DAC_FIFOC_FIFO_FLUSH)); 182 183 /* Set TX FIFO Empty Trigger Level */ 184 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, 185 0x3f << SUN4I_CODEC_DAC_FIFOC_TX_TRIG_LEVEL, 186 0xf << SUN4I_CODEC_DAC_FIFOC_TX_TRIG_LEVEL); 187 188 if (substream->runtime->rate > 32000) 189 /* Use 64 bits FIR filter */ 190 val = 0; 191 else 192 /* Use 32 bits FIR filter */ 193 val = BIT(SUN4I_CODEC_DAC_FIFOC_FIR_VERSION); 194 195 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, 196 BIT(SUN4I_CODEC_DAC_FIFOC_FIR_VERSION), 197 val); 198 199 /* Send zeros when we have an underrun */ 200 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, 201 BIT(SUN4I_CODEC_DAC_FIFOC_SEND_LASAT), 202 0); 203 204 return 0; 205 } 206 207 static unsigned long sun4i_codec_get_mod_freq(struct snd_pcm_hw_params *params) 208 { 209 unsigned int rate = params_rate(params); 210 211 switch (rate) { 212 case 176400: 213 case 88200: 214 case 44100: 215 case 33075: 216 case 22050: 217 case 14700: 218 case 11025: 219 case 7350: 220 return 22579200; 221 222 case 192000: 223 case 96000: 224 case 48000: 225 case 32000: 226 case 24000: 227 case 16000: 228 case 12000: 229 case 8000: 230 return 24576000; 231 232 default: 233 return 0; 234 } 235 } 236 237 static int sun4i_codec_get_hw_rate(struct snd_pcm_hw_params *params) 238 { 239 unsigned int rate = params_rate(params); 240 241 switch (rate) { 242 case 192000: 243 case 176400: 244 return 6; 245 246 case 96000: 247 case 88200: 248 return 7; 249 250 case 48000: 251 case 44100: 252 return 0; 253 254 case 32000: 255 case 33075: 256 return 1; 257 258 case 24000: 259 case 22050: 260 return 2; 261 262 case 16000: 263 case 14700: 264 return 3; 265 266 case 12000: 267 case 11025: 268 return 4; 269 270 case 8000: 271 case 7350: 272 return 5; 273 274 default: 275 return -EINVAL; 276 } 277 } 278 279 static int sun4i_codec_hw_params(struct snd_pcm_substream *substream, 280 struct snd_pcm_hw_params *params, 281 struct snd_soc_dai *dai) 282 { 283 struct snd_soc_pcm_runtime *rtd = substream->private_data; 284 struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card); 285 unsigned long clk_freq; 286 int ret, hwrate; 287 u32 val; 288 289 if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK) 290 return -ENOTSUPP; 291 292 clk_freq = sun4i_codec_get_mod_freq(params); 293 if (!clk_freq) 294 return -EINVAL; 295 296 ret = clk_set_rate(scodec->clk_module, clk_freq); 297 if (ret) 298 return ret; 299 300 hwrate = sun4i_codec_get_hw_rate(params); 301 if (hwrate < 0) 302 return hwrate; 303 304 /* Set DAC sample rate */ 305 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, 306 7 << SUN4I_CODEC_DAC_FIFOC_DAC_FS, 307 hwrate << SUN4I_CODEC_DAC_FIFOC_DAC_FS); 308 309 /* Set the number of channels we want to use */ 310 if (params_channels(params) == 1) 311 val = BIT(SUN4I_CODEC_DAC_FIFOC_MONO_EN); 312 else 313 val = 0; 314 315 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, 316 BIT(SUN4I_CODEC_DAC_FIFOC_MONO_EN), 317 val); 318 319 /* Set the number of sample bits to either 16 or 24 bits */ 320 if (hw_param_interval(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS)->min == 32) { 321 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, 322 BIT(SUN4I_CODEC_DAC_FIFOC_TX_SAMPLE_BITS), 323 BIT(SUN4I_CODEC_DAC_FIFOC_TX_SAMPLE_BITS)); 324 325 /* Set TX FIFO mode to padding the LSBs with 0 */ 326 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, 327 BIT(SUN4I_CODEC_DAC_FIFOC_TX_FIFO_MODE), 328 0); 329 330 scodec->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; 331 } else { 332 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, 333 BIT(SUN4I_CODEC_DAC_FIFOC_TX_SAMPLE_BITS), 334 0); 335 336 /* Set TX FIFO mode to repeat the MSB */ 337 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, 338 BIT(SUN4I_CODEC_DAC_FIFOC_TX_FIFO_MODE), 339 BIT(SUN4I_CODEC_DAC_FIFOC_TX_FIFO_MODE)); 340 341 scodec->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; 342 } 343 344 return 0; 345 } 346 347 static int sun4i_codec_startup(struct snd_pcm_substream *substream, 348 struct snd_soc_dai *dai) 349 { 350 struct snd_soc_pcm_runtime *rtd = substream->private_data; 351 struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card); 352 353 /* 354 * Stop issuing DRQ when we have room for less than 16 samples 355 * in our TX FIFO 356 */ 357 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, 358 3 << SUN4I_CODEC_DAC_FIFOC_DRQ_CLR_CNT, 359 3 << SUN4I_CODEC_DAC_FIFOC_DRQ_CLR_CNT); 360 361 return clk_prepare_enable(scodec->clk_module); 362 } 363 364 static void sun4i_codec_shutdown(struct snd_pcm_substream *substream, 365 struct snd_soc_dai *dai) 366 { 367 struct snd_soc_pcm_runtime *rtd = substream->private_data; 368 struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card); 369 370 clk_disable_unprepare(scodec->clk_module); 371 } 372 373 static const struct snd_soc_dai_ops sun4i_codec_dai_ops = { 374 .startup = sun4i_codec_startup, 375 .shutdown = sun4i_codec_shutdown, 376 .trigger = sun4i_codec_trigger, 377 .hw_params = sun4i_codec_hw_params, 378 .prepare = sun4i_codec_prepare, 379 }; 380 381 static struct snd_soc_dai_driver sun4i_codec_dai = { 382 .name = "Codec", 383 .ops = &sun4i_codec_dai_ops, 384 .playback = { 385 .stream_name = "Codec Playback", 386 .channels_min = 1, 387 .channels_max = 2, 388 .rate_min = 8000, 389 .rate_max = 192000, 390 .rates = SNDRV_PCM_RATE_8000_48000 | 391 SNDRV_PCM_RATE_96000 | 392 SNDRV_PCM_RATE_192000, 393 .formats = SNDRV_PCM_FMTBIT_S16_LE | 394 SNDRV_PCM_FMTBIT_S32_LE, 395 .sig_bits = 24, 396 }, 397 }; 398 399 /*** Codec ***/ 400 static const struct snd_kcontrol_new sun4i_codec_pa_mute = 401 SOC_DAPM_SINGLE("Switch", SUN4I_CODEC_DAC_ACTL, 402 SUN4I_CODEC_DAC_ACTL_PA_MUTE, 1, 0); 403 404 static DECLARE_TLV_DB_SCALE(sun4i_codec_pa_volume_scale, -6300, 100, 1); 405 406 static const struct snd_kcontrol_new sun4i_codec_widgets[] = { 407 SOC_SINGLE_TLV("PA Volume", SUN4I_CODEC_DAC_ACTL, 408 SUN4I_CODEC_DAC_ACTL_PA_VOL, 0x3F, 0, 409 sun4i_codec_pa_volume_scale), 410 }; 411 412 static const struct snd_kcontrol_new sun4i_codec_left_mixer_controls[] = { 413 SOC_DAPM_SINGLE("Left DAC Playback Switch", SUN4I_CODEC_DAC_ACTL, 414 SUN4I_CODEC_DAC_ACTL_LDACLMIXS, 1, 0), 415 }; 416 417 static const struct snd_kcontrol_new sun4i_codec_right_mixer_controls[] = { 418 SOC_DAPM_SINGLE("Right DAC Playback Switch", SUN4I_CODEC_DAC_ACTL, 419 SUN4I_CODEC_DAC_ACTL_RDACRMIXS, 1, 0), 420 SOC_DAPM_SINGLE("Left DAC Playback Switch", SUN4I_CODEC_DAC_ACTL, 421 SUN4I_CODEC_DAC_ACTL_LDACRMIXS, 1, 0), 422 }; 423 424 static const struct snd_kcontrol_new sun4i_codec_pa_mixer_controls[] = { 425 SOC_DAPM_SINGLE("DAC Playback Switch", SUN4I_CODEC_DAC_ACTL, 426 SUN4I_CODEC_DAC_ACTL_DACPAS, 1, 0), 427 SOC_DAPM_SINGLE("Mixer Playback Switch", SUN4I_CODEC_DAC_ACTL, 428 SUN4I_CODEC_DAC_ACTL_MIXPAS, 1, 0), 429 }; 430 431 static const struct snd_soc_dapm_widget sun4i_codec_dapm_widgets[] = { 432 /* Digital parts of the DACs */ 433 SND_SOC_DAPM_SUPPLY("DAC", SUN4I_CODEC_DAC_DPC, 434 SUN4I_CODEC_DAC_DPC_EN_DA, 0, 435 NULL, 0), 436 437 /* Analog parts of the DACs */ 438 SND_SOC_DAPM_DAC("Left DAC", "Codec Playback", SUN4I_CODEC_DAC_ACTL, 439 SUN4I_CODEC_DAC_ACTL_DACAENL, 0), 440 SND_SOC_DAPM_DAC("Right DAC", "Codec Playback", SUN4I_CODEC_DAC_ACTL, 441 SUN4I_CODEC_DAC_ACTL_DACAENR, 0), 442 443 /* Mixers */ 444 SND_SOC_DAPM_MIXER("Left Mixer", SND_SOC_NOPM, 0, 0, 445 sun4i_codec_left_mixer_controls, 446 ARRAY_SIZE(sun4i_codec_left_mixer_controls)), 447 SND_SOC_DAPM_MIXER("Right Mixer", SND_SOC_NOPM, 0, 0, 448 sun4i_codec_right_mixer_controls, 449 ARRAY_SIZE(sun4i_codec_right_mixer_controls)), 450 451 /* Global Mixer Enable */ 452 SND_SOC_DAPM_SUPPLY("Mixer Enable", SUN4I_CODEC_DAC_ACTL, 453 SUN4I_CODEC_DAC_ACTL_MIXEN, 0, NULL, 0), 454 455 /* Pre-Amplifier */ 456 SND_SOC_DAPM_MIXER("Pre-Amplifier", SUN4I_CODEC_ADC_ACTL, 457 SUN4I_CODEC_ADC_ACTL_PA_EN, 0, 458 sun4i_codec_pa_mixer_controls, 459 ARRAY_SIZE(sun4i_codec_pa_mixer_controls)), 460 SND_SOC_DAPM_SWITCH("Pre-Amplifier Mute", SND_SOC_NOPM, 0, 0, 461 &sun4i_codec_pa_mute), 462 463 SND_SOC_DAPM_OUTPUT("HP Right"), 464 SND_SOC_DAPM_OUTPUT("HP Left"), 465 }; 466 467 static const struct snd_soc_dapm_route sun4i_codec_dapm_routes[] = { 468 /* Left DAC Routes */ 469 { "Left DAC", NULL, "DAC" }, 470 471 /* Right DAC Routes */ 472 { "Right DAC", NULL, "DAC" }, 473 474 /* Right Mixer Routes */ 475 { "Right Mixer", NULL, "Mixer Enable" }, 476 { "Right Mixer", "Left DAC Playback Switch", "Left DAC" }, 477 { "Right Mixer", "Right DAC Playback Switch", "Right DAC" }, 478 479 /* Left Mixer Routes */ 480 { "Left Mixer", NULL, "Mixer Enable" }, 481 { "Left Mixer", "Left DAC Playback Switch", "Left DAC" }, 482 483 /* Pre-Amplifier Mixer Routes */ 484 { "Pre-Amplifier", "Mixer Playback Switch", "Left Mixer" }, 485 { "Pre-Amplifier", "Mixer Playback Switch", "Right Mixer" }, 486 { "Pre-Amplifier", "DAC Playback Switch", "Left DAC" }, 487 { "Pre-Amplifier", "DAC Playback Switch", "Right DAC" }, 488 489 /* PA -> HP path */ 490 { "Pre-Amplifier Mute", "Switch", "Pre-Amplifier" }, 491 { "HP Right", NULL, "Pre-Amplifier Mute" }, 492 { "HP Left", NULL, "Pre-Amplifier Mute" }, 493 }; 494 495 static struct snd_soc_codec_driver sun4i_codec_codec = { 496 .controls = sun4i_codec_widgets, 497 .num_controls = ARRAY_SIZE(sun4i_codec_widgets), 498 .dapm_widgets = sun4i_codec_dapm_widgets, 499 .num_dapm_widgets = ARRAY_SIZE(sun4i_codec_dapm_widgets), 500 .dapm_routes = sun4i_codec_dapm_routes, 501 .num_dapm_routes = ARRAY_SIZE(sun4i_codec_dapm_routes), 502 }; 503 504 static const struct snd_soc_component_driver sun4i_codec_component = { 505 .name = "sun4i-codec", 506 }; 507 508 #define SUN4I_CODEC_RATES SNDRV_PCM_RATE_8000_192000 509 #define SUN4I_CODEC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ 510 SNDRV_PCM_FMTBIT_S32_LE) 511 512 static int sun4i_codec_dai_probe(struct snd_soc_dai *dai) 513 { 514 struct snd_soc_card *card = snd_soc_dai_get_drvdata(dai); 515 struct sun4i_codec *scodec = snd_soc_card_get_drvdata(card); 516 517 snd_soc_dai_init_dma_data(dai, &scodec->playback_dma_data, 518 NULL); 519 520 return 0; 521 } 522 523 static struct snd_soc_dai_driver dummy_cpu_dai = { 524 .name = "sun4i-codec-cpu-dai", 525 .probe = sun4i_codec_dai_probe, 526 .playback = { 527 .stream_name = "Playback", 528 .channels_min = 1, 529 .channels_max = 2, 530 .rates = SUN4I_CODEC_RATES, 531 .formats = SUN4I_CODEC_FORMATS, 532 .sig_bits = 24, 533 }, 534 }; 535 536 static const struct regmap_config sun4i_codec_regmap_config = { 537 .reg_bits = 32, 538 .reg_stride = 4, 539 .val_bits = 32, 540 .max_register = SUN4I_CODEC_AC_MIC_PHONE_CAL, 541 }; 542 543 static const struct of_device_id sun4i_codec_of_match[] = { 544 { .compatible = "allwinner,sun4i-a10-codec" }, 545 { .compatible = "allwinner,sun7i-a20-codec" }, 546 {} 547 }; 548 MODULE_DEVICE_TABLE(of, sun4i_codec_of_match); 549 550 static struct snd_soc_dai_link *sun4i_codec_create_link(struct device *dev, 551 int *num_links) 552 { 553 struct snd_soc_dai_link *link = devm_kzalloc(dev, sizeof(*link), 554 GFP_KERNEL); 555 if (!link) 556 return NULL; 557 558 link->name = "cdc"; 559 link->stream_name = "CDC PCM"; 560 link->codec_dai_name = "Codec"; 561 link->cpu_dai_name = dev_name(dev); 562 link->codec_name = dev_name(dev); 563 link->platform_name = dev_name(dev); 564 link->dai_fmt = SND_SOC_DAIFMT_I2S; 565 566 *num_links = 1; 567 568 return link; 569 }; 570 571 static struct snd_soc_card *sun4i_codec_create_card(struct device *dev) 572 { 573 struct snd_soc_card *card; 574 575 card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL); 576 if (!card) 577 return NULL; 578 579 card->dai_link = sun4i_codec_create_link(dev, &card->num_links); 580 if (!card->dai_link) 581 return NULL; 582 583 card->dev = dev; 584 card->name = "sun4i-codec"; 585 586 return card; 587 }; 588 589 static int sun4i_codec_probe(struct platform_device *pdev) 590 { 591 struct snd_soc_card *card; 592 struct sun4i_codec *scodec; 593 struct resource *res; 594 void __iomem *base; 595 int ret; 596 597 scodec = devm_kzalloc(&pdev->dev, sizeof(*scodec), GFP_KERNEL); 598 if (!scodec) 599 return -ENOMEM; 600 601 scodec->dev = &pdev->dev; 602 603 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 604 base = devm_ioremap_resource(&pdev->dev, res); 605 if (IS_ERR(base)) { 606 dev_err(&pdev->dev, "Failed to map the registers\n"); 607 return PTR_ERR(base); 608 } 609 610 scodec->regmap = devm_regmap_init_mmio(&pdev->dev, base, 611 &sun4i_codec_regmap_config); 612 if (IS_ERR(scodec->regmap)) { 613 dev_err(&pdev->dev, "Failed to create our regmap\n"); 614 return PTR_ERR(scodec->regmap); 615 } 616 617 /* Get the clocks from the DT */ 618 scodec->clk_apb = devm_clk_get(&pdev->dev, "apb"); 619 if (IS_ERR(scodec->clk_apb)) { 620 dev_err(&pdev->dev, "Failed to get the APB clock\n"); 621 return PTR_ERR(scodec->clk_apb); 622 } 623 624 scodec->clk_module = devm_clk_get(&pdev->dev, "codec"); 625 if (IS_ERR(scodec->clk_module)) { 626 dev_err(&pdev->dev, "Failed to get the module clock\n"); 627 return PTR_ERR(scodec->clk_module); 628 } 629 630 /* Enable the bus clock */ 631 if (clk_prepare_enable(scodec->clk_apb)) { 632 dev_err(&pdev->dev, "Failed to enable the APB clock\n"); 633 return -EINVAL; 634 } 635 636 /* DMA configuration for TX FIFO */ 637 scodec->playback_dma_data.addr = res->start + SUN4I_CODEC_DAC_TXDATA; 638 scodec->playback_dma_data.maxburst = 4; 639 scodec->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; 640 641 ret = snd_soc_register_codec(&pdev->dev, &sun4i_codec_codec, 642 &sun4i_codec_dai, 1); 643 if (ret) { 644 dev_err(&pdev->dev, "Failed to register our codec\n"); 645 goto err_clk_disable; 646 } 647 648 ret = devm_snd_soc_register_component(&pdev->dev, 649 &sun4i_codec_component, 650 &dummy_cpu_dai, 1); 651 if (ret) { 652 dev_err(&pdev->dev, "Failed to register our DAI\n"); 653 goto err_unregister_codec; 654 } 655 656 ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0); 657 if (ret) { 658 dev_err(&pdev->dev, "Failed to register against DMAEngine\n"); 659 goto err_unregister_codec; 660 } 661 662 card = sun4i_codec_create_card(&pdev->dev); 663 if (!card) { 664 dev_err(&pdev->dev, "Failed to create our card\n"); 665 goto err_unregister_codec; 666 } 667 668 platform_set_drvdata(pdev, card); 669 snd_soc_card_set_drvdata(card, scodec); 670 671 ret = snd_soc_register_card(card); 672 if (ret) { 673 dev_err(&pdev->dev, "Failed to register our card\n"); 674 goto err_unregister_codec; 675 } 676 677 return 0; 678 679 err_unregister_codec: 680 snd_soc_unregister_codec(&pdev->dev); 681 err_clk_disable: 682 clk_disable_unprepare(scodec->clk_apb); 683 return ret; 684 } 685 686 static int sun4i_codec_remove(struct platform_device *pdev) 687 { 688 struct snd_soc_card *card = platform_get_drvdata(pdev); 689 struct sun4i_codec *scodec = snd_soc_card_get_drvdata(card); 690 691 snd_soc_unregister_card(card); 692 snd_soc_unregister_codec(&pdev->dev); 693 clk_disable_unprepare(scodec->clk_apb); 694 695 return 0; 696 } 697 698 static struct platform_driver sun4i_codec_driver = { 699 .driver = { 700 .name = "sun4i-codec", 701 .of_match_table = sun4i_codec_of_match, 702 }, 703 .probe = sun4i_codec_probe, 704 .remove = sun4i_codec_remove, 705 }; 706 module_platform_driver(sun4i_codec_driver); 707 708 MODULE_DESCRIPTION("Allwinner A10 codec driver"); 709 MODULE_AUTHOR("Emilio López <emilio@elopez.com.ar>"); 710 MODULE_AUTHOR("Jon Smirl <jonsmirl@gmail.com>"); 711 MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>"); 712 MODULE_LICENSE("GPL"); 713