1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Copyright 2014 Emilio López <emilio@elopez.com.ar> 4 * Copyright 2014 Jon Smirl <jonsmirl@gmail.com> 5 * Copyright 2015 Maxime Ripard <maxime.ripard@free-electrons.com> 6 * Copyright 2015 Adam Sampson <ats@offog.org> 7 * Copyright 2016 Chen-Yu Tsai <wens@csie.org> 8 * 9 * Based on the Allwinner SDK driver, released under the GPL. 10 */ 11 12 #include <linux/init.h> 13 #include <linux/kernel.h> 14 #include <linux/module.h> 15 #include <linux/platform_device.h> 16 #include <linux/delay.h> 17 #include <linux/slab.h> 18 #include <linux/clk.h> 19 #include <linux/regmap.h> 20 #include <linux/reset.h> 21 #include <linux/gpio/consumer.h> 22 23 #include <sound/core.h> 24 #include <sound/pcm.h> 25 #include <sound/pcm_params.h> 26 #include <sound/soc.h> 27 #include <sound/tlv.h> 28 #include <sound/initval.h> 29 #include <sound/dmaengine_pcm.h> 30 31 /* Codec DAC digital controls and FIFO registers */ 32 #define SUN4I_CODEC_DAC_DPC (0x00) 33 #define SUN4I_CODEC_DAC_DPC_EN_DA (31) 34 #define SUN4I_CODEC_DAC_DPC_DVOL (12) 35 #define SUN4I_CODEC_DAC_FIFOC (0x04) 36 #define SUN4I_CODEC_DAC_FIFOC_DAC_FS (29) 37 #define SUN4I_CODEC_DAC_FIFOC_FIR_VERSION (28) 38 #define SUN4I_CODEC_DAC_FIFOC_SEND_LASAT (26) 39 #define SUN4I_CODEC_DAC_FIFOC_TX_FIFO_MODE (24) 40 #define SUN4I_CODEC_DAC_FIFOC_DRQ_CLR_CNT (21) 41 #define SUN4I_CODEC_DAC_FIFOC_TX_TRIG_LEVEL (8) 42 #define SUN4I_CODEC_DAC_FIFOC_MONO_EN (6) 43 #define SUN4I_CODEC_DAC_FIFOC_TX_SAMPLE_BITS (5) 44 #define SUN4I_CODEC_DAC_FIFOC_DAC_DRQ_EN (4) 45 #define SUN4I_CODEC_DAC_FIFOC_FIFO_FLUSH (0) 46 #define SUN4I_CODEC_DAC_FIFOS (0x08) 47 #define SUN4I_CODEC_DAC_TXDATA (0x0c) 48 49 /* Codec DAC side analog signal controls */ 50 #define SUN4I_CODEC_DAC_ACTL (0x10) 51 #define SUN4I_CODEC_DAC_ACTL_DACAENR (31) 52 #define SUN4I_CODEC_DAC_ACTL_DACAENL (30) 53 #define SUN4I_CODEC_DAC_ACTL_MIXEN (29) 54 #define SUN4I_CODEC_DAC_ACTL_LNG (26) 55 #define SUN4I_CODEC_DAC_ACTL_FMG (23) 56 #define SUN4I_CODEC_DAC_ACTL_MICG (20) 57 #define SUN4I_CODEC_DAC_ACTL_LLNS (19) 58 #define SUN4I_CODEC_DAC_ACTL_RLNS (18) 59 #define SUN4I_CODEC_DAC_ACTL_LFMS (17) 60 #define SUN4I_CODEC_DAC_ACTL_RFMS (16) 61 #define SUN4I_CODEC_DAC_ACTL_LDACLMIXS (15) 62 #define SUN4I_CODEC_DAC_ACTL_RDACRMIXS (14) 63 #define SUN4I_CODEC_DAC_ACTL_LDACRMIXS (13) 64 #define SUN4I_CODEC_DAC_ACTL_MIC1LS (12) 65 #define SUN4I_CODEC_DAC_ACTL_MIC1RS (11) 66 #define SUN4I_CODEC_DAC_ACTL_MIC2LS (10) 67 #define SUN4I_CODEC_DAC_ACTL_MIC2RS (9) 68 #define SUN4I_CODEC_DAC_ACTL_DACPAS (8) 69 #define SUN4I_CODEC_DAC_ACTL_MIXPAS (7) 70 #define SUN4I_CODEC_DAC_ACTL_PA_MUTE (6) 71 #define SUN4I_CODEC_DAC_ACTL_PA_VOL (0) 72 #define SUN4I_CODEC_DAC_TUNE (0x14) 73 #define SUN4I_CODEC_DAC_DEBUG (0x18) 74 75 /* Codec ADC digital controls and FIFO registers */ 76 #define SUN4I_CODEC_ADC_FIFOC (0x1c) 77 #define SUN4I_CODEC_ADC_FIFOC_ADC_FS (29) 78 #define SUN4I_CODEC_ADC_FIFOC_EN_AD (28) 79 #define SUN4I_CODEC_ADC_FIFOC_RX_FIFO_MODE (24) 80 #define SUN4I_CODEC_ADC_FIFOC_RX_TRIG_LEVEL (8) 81 #define SUN4I_CODEC_ADC_FIFOC_MONO_EN (7) 82 #define SUN4I_CODEC_ADC_FIFOC_RX_SAMPLE_BITS (6) 83 #define SUN4I_CODEC_ADC_FIFOC_ADC_DRQ_EN (4) 84 #define SUN4I_CODEC_ADC_FIFOC_FIFO_FLUSH (0) 85 #define SUN4I_CODEC_ADC_FIFOS (0x20) 86 #define SUN4I_CODEC_ADC_RXDATA (0x24) 87 88 /* Codec ADC side analog signal controls */ 89 #define SUN4I_CODEC_ADC_ACTL (0x28) 90 #define SUN4I_CODEC_ADC_ACTL_ADC_R_EN (31) 91 #define SUN4I_CODEC_ADC_ACTL_ADC_L_EN (30) 92 #define SUN4I_CODEC_ADC_ACTL_PREG1EN (29) 93 #define SUN4I_CODEC_ADC_ACTL_PREG2EN (28) 94 #define SUN4I_CODEC_ADC_ACTL_VMICEN (27) 95 #define SUN4I_CODEC_ADC_ACTL_PREG1 (25) 96 #define SUN4I_CODEC_ADC_ACTL_PREG2 (23) 97 #define SUN4I_CODEC_ADC_ACTL_VADCG (20) 98 #define SUN4I_CODEC_ADC_ACTL_ADCIS (17) 99 #define SUN4I_CODEC_ADC_ACTL_LNPREG (13) 100 #define SUN4I_CODEC_ADC_ACTL_PA_EN (4) 101 #define SUN4I_CODEC_ADC_ACTL_DDE (3) 102 #define SUN4I_CODEC_ADC_DEBUG (0x2c) 103 104 /* FIFO counters */ 105 #define SUN4I_CODEC_DAC_TXCNT (0x30) 106 #define SUN4I_CODEC_ADC_RXCNT (0x34) 107 108 /* Calibration register (sun7i only) */ 109 #define SUN7I_CODEC_AC_DAC_CAL (0x38) 110 111 /* Microphone controls (sun7i only) */ 112 #define SUN7I_CODEC_AC_MIC_PHONE_CAL (0x3c) 113 114 #define SUN7I_CODEC_AC_MIC_PHONE_CAL_PREG1 (29) 115 #define SUN7I_CODEC_AC_MIC_PHONE_CAL_PREG2 (26) 116 117 /* 118 * sun6i specific registers 119 * 120 * sun6i shares the same digital control and FIFO registers as sun4i, 121 * but only the DAC digital controls are at the same offset. The others 122 * have been moved around to accommodate extra analog controls. 123 */ 124 125 /* Codec DAC digital controls and FIFO registers */ 126 #define SUN6I_CODEC_ADC_FIFOC (0x10) 127 #define SUN6I_CODEC_ADC_FIFOC_EN_AD (28) 128 #define SUN6I_CODEC_ADC_FIFOS (0x14) 129 #define SUN6I_CODEC_ADC_RXDATA (0x18) 130 131 /* Output mixer and gain controls */ 132 #define SUN6I_CODEC_OM_DACA_CTRL (0x20) 133 #define SUN6I_CODEC_OM_DACA_CTRL_DACAREN (31) 134 #define SUN6I_CODEC_OM_DACA_CTRL_DACALEN (30) 135 #define SUN6I_CODEC_OM_DACA_CTRL_RMIXEN (29) 136 #define SUN6I_CODEC_OM_DACA_CTRL_LMIXEN (28) 137 #define SUN6I_CODEC_OM_DACA_CTRL_RMIX_MIC1 (23) 138 #define SUN6I_CODEC_OM_DACA_CTRL_RMIX_MIC2 (22) 139 #define SUN6I_CODEC_OM_DACA_CTRL_RMIX_PHONE (21) 140 #define SUN6I_CODEC_OM_DACA_CTRL_RMIX_PHONEP (20) 141 #define SUN6I_CODEC_OM_DACA_CTRL_RMIX_LINEINR (19) 142 #define SUN6I_CODEC_OM_DACA_CTRL_RMIX_DACR (18) 143 #define SUN6I_CODEC_OM_DACA_CTRL_RMIX_DACL (17) 144 #define SUN6I_CODEC_OM_DACA_CTRL_LMIX_MIC1 (16) 145 #define SUN6I_CODEC_OM_DACA_CTRL_LMIX_MIC2 (15) 146 #define SUN6I_CODEC_OM_DACA_CTRL_LMIX_PHONE (14) 147 #define SUN6I_CODEC_OM_DACA_CTRL_LMIX_PHONEN (13) 148 #define SUN6I_CODEC_OM_DACA_CTRL_LMIX_LINEINL (12) 149 #define SUN6I_CODEC_OM_DACA_CTRL_LMIX_DACL (11) 150 #define SUN6I_CODEC_OM_DACA_CTRL_LMIX_DACR (10) 151 #define SUN6I_CODEC_OM_DACA_CTRL_RHPIS (9) 152 #define SUN6I_CODEC_OM_DACA_CTRL_LHPIS (8) 153 #define SUN6I_CODEC_OM_DACA_CTRL_RHPPAMUTE (7) 154 #define SUN6I_CODEC_OM_DACA_CTRL_LHPPAMUTE (6) 155 #define SUN6I_CODEC_OM_DACA_CTRL_HPVOL (0) 156 #define SUN6I_CODEC_OM_PA_CTRL (0x24) 157 #define SUN6I_CODEC_OM_PA_CTRL_HPPAEN (31) 158 #define SUN6I_CODEC_OM_PA_CTRL_HPCOM_CTL (29) 159 #define SUN6I_CODEC_OM_PA_CTRL_COMPTEN (28) 160 #define SUN6I_CODEC_OM_PA_CTRL_MIC1G (15) 161 #define SUN6I_CODEC_OM_PA_CTRL_MIC2G (12) 162 #define SUN6I_CODEC_OM_PA_CTRL_LINEING (9) 163 #define SUN6I_CODEC_OM_PA_CTRL_PHONEG (6) 164 #define SUN6I_CODEC_OM_PA_CTRL_PHONEPG (3) 165 #define SUN6I_CODEC_OM_PA_CTRL_PHONENG (0) 166 167 /* Microphone, line out and phone out controls */ 168 #define SUN6I_CODEC_MIC_CTRL (0x28) 169 #define SUN6I_CODEC_MIC_CTRL_HBIASEN (31) 170 #define SUN6I_CODEC_MIC_CTRL_MBIASEN (30) 171 #define SUN6I_CODEC_MIC_CTRL_MIC1AMPEN (28) 172 #define SUN6I_CODEC_MIC_CTRL_MIC1BOOST (25) 173 #define SUN6I_CODEC_MIC_CTRL_MIC2AMPEN (24) 174 #define SUN6I_CODEC_MIC_CTRL_MIC2BOOST (21) 175 #define SUN6I_CODEC_MIC_CTRL_MIC2SLT (20) 176 #define SUN6I_CODEC_MIC_CTRL_LINEOUTLEN (19) 177 #define SUN6I_CODEC_MIC_CTRL_LINEOUTREN (18) 178 #define SUN6I_CODEC_MIC_CTRL_LINEOUTLSRC (17) 179 #define SUN6I_CODEC_MIC_CTRL_LINEOUTRSRC (16) 180 #define SUN6I_CODEC_MIC_CTRL_LINEOUTVC (11) 181 #define SUN6I_CODEC_MIC_CTRL_PHONEPREG (8) 182 183 /* ADC mixer controls */ 184 #define SUN6I_CODEC_ADC_ACTL (0x2c) 185 #define SUN6I_CODEC_ADC_ACTL_ADCREN (31) 186 #define SUN6I_CODEC_ADC_ACTL_ADCLEN (30) 187 #define SUN6I_CODEC_ADC_ACTL_ADCRG (27) 188 #define SUN6I_CODEC_ADC_ACTL_ADCLG (24) 189 #define SUN6I_CODEC_ADC_ACTL_RADCMIX_MIC1 (13) 190 #define SUN6I_CODEC_ADC_ACTL_RADCMIX_MIC2 (12) 191 #define SUN6I_CODEC_ADC_ACTL_RADCMIX_PHONE (11) 192 #define SUN6I_CODEC_ADC_ACTL_RADCMIX_PHONEP (10) 193 #define SUN6I_CODEC_ADC_ACTL_RADCMIX_LINEINR (9) 194 #define SUN6I_CODEC_ADC_ACTL_RADCMIX_OMIXR (8) 195 #define SUN6I_CODEC_ADC_ACTL_RADCMIX_OMIXL (7) 196 #define SUN6I_CODEC_ADC_ACTL_LADCMIX_MIC1 (6) 197 #define SUN6I_CODEC_ADC_ACTL_LADCMIX_MIC2 (5) 198 #define SUN6I_CODEC_ADC_ACTL_LADCMIX_PHONE (4) 199 #define SUN6I_CODEC_ADC_ACTL_LADCMIX_PHONEN (3) 200 #define SUN6I_CODEC_ADC_ACTL_LADCMIX_LINEINL (2) 201 #define SUN6I_CODEC_ADC_ACTL_LADCMIX_OMIXL (1) 202 #define SUN6I_CODEC_ADC_ACTL_LADCMIX_OMIXR (0) 203 204 /* Analog performance tuning controls */ 205 #define SUN6I_CODEC_ADDA_TUNE (0x30) 206 207 /* Calibration controls */ 208 #define SUN6I_CODEC_CALIBRATION (0x34) 209 210 /* FIFO counters */ 211 #define SUN6I_CODEC_DAC_TXCNT (0x40) 212 #define SUN6I_CODEC_ADC_RXCNT (0x44) 213 214 /* headset jack detection and button support registers */ 215 #define SUN6I_CODEC_HMIC_CTL (0x50) 216 #define SUN6I_CODEC_HMIC_DATA (0x54) 217 218 /* TODO sun6i DAP (Digital Audio Processing) bits */ 219 220 /* FIFO counters moved on A23 */ 221 #define SUN8I_A23_CODEC_DAC_TXCNT (0x1c) 222 #define SUN8I_A23_CODEC_ADC_RXCNT (0x20) 223 224 /* TX FIFO moved on H3 */ 225 #define SUN8I_H3_CODEC_DAC_TXDATA (0x20) 226 #define SUN8I_H3_CODEC_DAC_DBG (0x48) 227 #define SUN8I_H3_CODEC_ADC_DBG (0x4c) 228 229 /* TODO H3 DAP (Digital Audio Processing) bits */ 230 231 struct sun4i_codec { 232 struct device *dev; 233 struct regmap *regmap; 234 struct clk *clk_apb; 235 struct clk *clk_module; 236 struct reset_control *rst; 237 struct gpio_desc *gpio_pa; 238 239 /* ADC_FIFOC register is at different offset on different SoCs */ 240 struct regmap_field *reg_adc_fifoc; 241 242 struct snd_dmaengine_dai_dma_data capture_dma_data; 243 struct snd_dmaengine_dai_dma_data playback_dma_data; 244 }; 245 246 static void sun4i_codec_start_playback(struct sun4i_codec *scodec) 247 { 248 /* Flush TX FIFO */ 249 regmap_set_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, 250 BIT(SUN4I_CODEC_DAC_FIFOC_FIFO_FLUSH)); 251 252 /* Enable DAC DRQ */ 253 regmap_set_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, 254 BIT(SUN4I_CODEC_DAC_FIFOC_DAC_DRQ_EN)); 255 } 256 257 static void sun4i_codec_stop_playback(struct sun4i_codec *scodec) 258 { 259 /* Disable DAC DRQ */ 260 regmap_clear_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, 261 BIT(SUN4I_CODEC_DAC_FIFOC_DAC_DRQ_EN)); 262 } 263 264 static void sun4i_codec_start_capture(struct sun4i_codec *scodec) 265 { 266 /* Enable ADC DRQ */ 267 regmap_field_set_bits(scodec->reg_adc_fifoc, 268 BIT(SUN4I_CODEC_ADC_FIFOC_ADC_DRQ_EN)); 269 } 270 271 static void sun4i_codec_stop_capture(struct sun4i_codec *scodec) 272 { 273 /* Disable ADC DRQ */ 274 regmap_field_clear_bits(scodec->reg_adc_fifoc, 275 BIT(SUN4I_CODEC_ADC_FIFOC_ADC_DRQ_EN)); 276 } 277 278 static int sun4i_codec_trigger(struct snd_pcm_substream *substream, int cmd, 279 struct snd_soc_dai *dai) 280 { 281 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); 282 struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card); 283 284 switch (cmd) { 285 case SNDRV_PCM_TRIGGER_START: 286 case SNDRV_PCM_TRIGGER_RESUME: 287 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 288 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 289 sun4i_codec_start_playback(scodec); 290 else 291 sun4i_codec_start_capture(scodec); 292 break; 293 294 case SNDRV_PCM_TRIGGER_STOP: 295 case SNDRV_PCM_TRIGGER_SUSPEND: 296 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 297 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 298 sun4i_codec_stop_playback(scodec); 299 else 300 sun4i_codec_stop_capture(scodec); 301 break; 302 303 default: 304 return -EINVAL; 305 } 306 307 return 0; 308 } 309 310 static int sun4i_codec_prepare_capture(struct snd_pcm_substream *substream, 311 struct snd_soc_dai *dai) 312 { 313 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); 314 struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card); 315 316 317 /* Flush RX FIFO */ 318 regmap_field_set_bits(scodec->reg_adc_fifoc, 319 BIT(SUN4I_CODEC_ADC_FIFOC_FIFO_FLUSH)); 320 321 322 /* Set RX FIFO trigger level */ 323 regmap_field_update_bits(scodec->reg_adc_fifoc, 324 0xf << SUN4I_CODEC_ADC_FIFOC_RX_TRIG_LEVEL, 325 0x7 << SUN4I_CODEC_ADC_FIFOC_RX_TRIG_LEVEL); 326 327 /* 328 * FIXME: Undocumented in the datasheet, but 329 * Allwinner's code mentions that it is 330 * related to microphone gain 331 */ 332 if (of_device_is_compatible(scodec->dev->of_node, 333 "allwinner,sun4i-a10-codec") || 334 of_device_is_compatible(scodec->dev->of_node, 335 "allwinner,sun7i-a20-codec")) { 336 regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_ACTL, 337 0x3 << 25, 338 0x1 << 25); 339 } 340 341 if (of_device_is_compatible(scodec->dev->of_node, 342 "allwinner,sun7i-a20-codec")) 343 /* FIXME: Undocumented bits */ 344 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_TUNE, 345 0x3 << 8, 346 0x1 << 8); 347 348 return 0; 349 } 350 351 static int sun4i_codec_prepare_playback(struct snd_pcm_substream *substream, 352 struct snd_soc_dai *dai) 353 { 354 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); 355 struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card); 356 u32 val; 357 358 /* Flush the TX FIFO */ 359 regmap_set_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, 360 BIT(SUN4I_CODEC_DAC_FIFOC_FIFO_FLUSH)); 361 362 /* Set TX FIFO Empty Trigger Level */ 363 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, 364 0x3f << SUN4I_CODEC_DAC_FIFOC_TX_TRIG_LEVEL, 365 0xf << SUN4I_CODEC_DAC_FIFOC_TX_TRIG_LEVEL); 366 367 if (substream->runtime->rate > 32000) 368 /* Use 64 bits FIR filter */ 369 val = 0; 370 else 371 /* Use 32 bits FIR filter */ 372 val = BIT(SUN4I_CODEC_DAC_FIFOC_FIR_VERSION); 373 374 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, 375 BIT(SUN4I_CODEC_DAC_FIFOC_FIR_VERSION), 376 val); 377 378 /* Send zeros when we have an underrun */ 379 regmap_clear_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, 380 BIT(SUN4I_CODEC_DAC_FIFOC_SEND_LASAT)); 381 382 return 0; 383 }; 384 385 static int sun4i_codec_prepare(struct snd_pcm_substream *substream, 386 struct snd_soc_dai *dai) 387 { 388 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 389 return sun4i_codec_prepare_playback(substream, dai); 390 391 return sun4i_codec_prepare_capture(substream, dai); 392 } 393 394 static unsigned long sun4i_codec_get_mod_freq(struct snd_pcm_hw_params *params) 395 { 396 unsigned int rate = params_rate(params); 397 398 switch (rate) { 399 case 176400: 400 case 88200: 401 case 44100: 402 case 33075: 403 case 22050: 404 case 14700: 405 case 11025: 406 case 7350: 407 return 22579200; 408 409 case 192000: 410 case 96000: 411 case 48000: 412 case 32000: 413 case 24000: 414 case 16000: 415 case 12000: 416 case 8000: 417 return 24576000; 418 419 default: 420 return 0; 421 } 422 } 423 424 static int sun4i_codec_get_hw_rate(struct snd_pcm_hw_params *params) 425 { 426 unsigned int rate = params_rate(params); 427 428 switch (rate) { 429 case 192000: 430 case 176400: 431 return 6; 432 433 case 96000: 434 case 88200: 435 return 7; 436 437 case 48000: 438 case 44100: 439 return 0; 440 441 case 32000: 442 case 33075: 443 return 1; 444 445 case 24000: 446 case 22050: 447 return 2; 448 449 case 16000: 450 case 14700: 451 return 3; 452 453 case 12000: 454 case 11025: 455 return 4; 456 457 case 8000: 458 case 7350: 459 return 5; 460 461 default: 462 return -EINVAL; 463 } 464 } 465 466 static int sun4i_codec_hw_params_capture(struct sun4i_codec *scodec, 467 struct snd_pcm_hw_params *params, 468 unsigned int hwrate) 469 { 470 /* Set ADC sample rate */ 471 regmap_field_update_bits(scodec->reg_adc_fifoc, 472 7 << SUN4I_CODEC_ADC_FIFOC_ADC_FS, 473 hwrate << SUN4I_CODEC_ADC_FIFOC_ADC_FS); 474 475 /* Set the number of channels we want to use */ 476 if (params_channels(params) == 1) 477 regmap_field_set_bits(scodec->reg_adc_fifoc, 478 BIT(SUN4I_CODEC_ADC_FIFOC_MONO_EN)); 479 else 480 regmap_field_clear_bits(scodec->reg_adc_fifoc, 481 BIT(SUN4I_CODEC_ADC_FIFOC_MONO_EN)); 482 483 /* Set the number of sample bits to either 16 or 24 bits */ 484 if (hw_param_interval(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS)->min == 32) { 485 regmap_field_set_bits(scodec->reg_adc_fifoc, 486 BIT(SUN4I_CODEC_ADC_FIFOC_RX_SAMPLE_BITS)); 487 488 regmap_field_clear_bits(scodec->reg_adc_fifoc, 489 BIT(SUN4I_CODEC_ADC_FIFOC_RX_FIFO_MODE)); 490 491 scodec->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; 492 } else { 493 regmap_field_clear_bits(scodec->reg_adc_fifoc, 494 BIT(SUN4I_CODEC_ADC_FIFOC_RX_SAMPLE_BITS)); 495 496 /* Fill most significant bits with valid data MSB */ 497 regmap_field_set_bits(scodec->reg_adc_fifoc, 498 BIT(SUN4I_CODEC_ADC_FIFOC_RX_FIFO_MODE)); 499 500 scodec->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; 501 } 502 503 return 0; 504 } 505 506 static int sun4i_codec_hw_params_playback(struct sun4i_codec *scodec, 507 struct snd_pcm_hw_params *params, 508 unsigned int hwrate) 509 { 510 u32 val; 511 512 /* Set DAC sample rate */ 513 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, 514 7 << SUN4I_CODEC_DAC_FIFOC_DAC_FS, 515 hwrate << SUN4I_CODEC_DAC_FIFOC_DAC_FS); 516 517 /* Set the number of channels we want to use */ 518 if (params_channels(params) == 1) 519 val = BIT(SUN4I_CODEC_DAC_FIFOC_MONO_EN); 520 else 521 val = 0; 522 523 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, 524 BIT(SUN4I_CODEC_DAC_FIFOC_MONO_EN), 525 val); 526 527 /* Set the number of sample bits to either 16 or 24 bits */ 528 if (hw_param_interval(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS)->min == 32) { 529 regmap_set_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, 530 BIT(SUN4I_CODEC_DAC_FIFOC_TX_SAMPLE_BITS)); 531 532 /* Set TX FIFO mode to padding the LSBs with 0 */ 533 regmap_clear_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, 534 BIT(SUN4I_CODEC_DAC_FIFOC_TX_FIFO_MODE)); 535 536 scodec->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; 537 } else { 538 regmap_clear_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, 539 BIT(SUN4I_CODEC_DAC_FIFOC_TX_SAMPLE_BITS)); 540 541 /* Set TX FIFO mode to repeat the MSB */ 542 regmap_set_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, 543 BIT(SUN4I_CODEC_DAC_FIFOC_TX_FIFO_MODE)); 544 545 scodec->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; 546 } 547 548 return 0; 549 } 550 551 static int sun4i_codec_hw_params(struct snd_pcm_substream *substream, 552 struct snd_pcm_hw_params *params, 553 struct snd_soc_dai *dai) 554 { 555 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); 556 struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card); 557 unsigned long clk_freq; 558 int ret, hwrate; 559 560 clk_freq = sun4i_codec_get_mod_freq(params); 561 if (!clk_freq) 562 return -EINVAL; 563 564 ret = clk_set_rate(scodec->clk_module, clk_freq); 565 if (ret) 566 return ret; 567 568 hwrate = sun4i_codec_get_hw_rate(params); 569 if (hwrate < 0) 570 return hwrate; 571 572 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 573 return sun4i_codec_hw_params_playback(scodec, params, 574 hwrate); 575 576 return sun4i_codec_hw_params_capture(scodec, params, 577 hwrate); 578 } 579 580 static int sun4i_codec_startup(struct snd_pcm_substream *substream, 581 struct snd_soc_dai *dai) 582 { 583 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); 584 struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card); 585 586 /* 587 * Stop issuing DRQ when we have room for less than 16 samples 588 * in our TX FIFO 589 */ 590 regmap_set_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, 591 3 << SUN4I_CODEC_DAC_FIFOC_DRQ_CLR_CNT); 592 593 return clk_prepare_enable(scodec->clk_module); 594 } 595 596 static void sun4i_codec_shutdown(struct snd_pcm_substream *substream, 597 struct snd_soc_dai *dai) 598 { 599 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); 600 struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card); 601 602 clk_disable_unprepare(scodec->clk_module); 603 } 604 605 static const struct snd_soc_dai_ops sun4i_codec_dai_ops = { 606 .startup = sun4i_codec_startup, 607 .shutdown = sun4i_codec_shutdown, 608 .trigger = sun4i_codec_trigger, 609 .hw_params = sun4i_codec_hw_params, 610 .prepare = sun4i_codec_prepare, 611 }; 612 613 #define SUN4I_CODEC_RATES ( \ 614 SNDRV_PCM_RATE_8000_48000 | \ 615 SNDRV_PCM_RATE_12000 | \ 616 SNDRV_PCM_RATE_24000 | \ 617 SNDRV_PCM_RATE_96000 | \ 618 SNDRV_PCM_RATE_192000) 619 620 static struct snd_soc_dai_driver sun4i_codec_dai = { 621 .name = "Codec", 622 .ops = &sun4i_codec_dai_ops, 623 .playback = { 624 .stream_name = "Codec Playback", 625 .channels_min = 1, 626 .channels_max = 2, 627 .rate_min = 8000, 628 .rate_max = 192000, 629 .rates = SUN4I_CODEC_RATES, 630 .formats = SNDRV_PCM_FMTBIT_S16_LE | 631 SNDRV_PCM_FMTBIT_S32_LE, 632 .sig_bits = 24, 633 }, 634 .capture = { 635 .stream_name = "Codec Capture", 636 .channels_min = 1, 637 .channels_max = 2, 638 .rate_min = 8000, 639 .rate_max = 48000, 640 .rates = SUN4I_CODEC_RATES, 641 .formats = SNDRV_PCM_FMTBIT_S16_LE | 642 SNDRV_PCM_FMTBIT_S32_LE, 643 .sig_bits = 24, 644 }, 645 }; 646 647 /*** sun4i Codec ***/ 648 static const struct snd_kcontrol_new sun4i_codec_pa_mute = 649 SOC_DAPM_SINGLE("Switch", SUN4I_CODEC_DAC_ACTL, 650 SUN4I_CODEC_DAC_ACTL_PA_MUTE, 1, 0); 651 652 static DECLARE_TLV_DB_SCALE(sun4i_codec_pa_volume_scale, -6300, 100, 1); 653 static DECLARE_TLV_DB_SCALE(sun4i_codec_linein_loopback_gain_scale, -150, 150, 654 0); 655 static DECLARE_TLV_DB_SCALE(sun4i_codec_linein_preamp_gain_scale, -1200, 300, 656 0); 657 static DECLARE_TLV_DB_SCALE(sun4i_codec_fmin_loopback_gain_scale, -450, 150, 658 0); 659 static DECLARE_TLV_DB_SCALE(sun4i_codec_micin_loopback_gain_scale, -450, 150, 660 0); 661 static DECLARE_TLV_DB_RANGE(sun4i_codec_micin_preamp_gain_scale, 662 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0), 663 1, 7, TLV_DB_SCALE_ITEM(3500, 300, 0)); 664 static DECLARE_TLV_DB_RANGE(sun7i_codec_micin_preamp_gain_scale, 665 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0), 666 1, 7, TLV_DB_SCALE_ITEM(2400, 300, 0)); 667 668 static const struct snd_kcontrol_new sun4i_codec_controls[] = { 669 SOC_SINGLE_TLV("Power Amplifier Volume", SUN4I_CODEC_DAC_ACTL, 670 SUN4I_CODEC_DAC_ACTL_PA_VOL, 0x3F, 0, 671 sun4i_codec_pa_volume_scale), 672 SOC_SINGLE_TLV("Line Playback Volume", SUN4I_CODEC_DAC_ACTL, 673 SUN4I_CODEC_DAC_ACTL_LNG, 1, 0, 674 sun4i_codec_linein_loopback_gain_scale), 675 SOC_SINGLE_TLV("Line Boost Volume", SUN4I_CODEC_ADC_ACTL, 676 SUN4I_CODEC_ADC_ACTL_LNPREG, 7, 0, 677 sun4i_codec_linein_preamp_gain_scale), 678 SOC_SINGLE_TLV("FM Playback Volume", SUN4I_CODEC_DAC_ACTL, 679 SUN4I_CODEC_DAC_ACTL_FMG, 3, 0, 680 sun4i_codec_fmin_loopback_gain_scale), 681 SOC_SINGLE_TLV("Mic Playback Volume", SUN4I_CODEC_DAC_ACTL, 682 SUN4I_CODEC_DAC_ACTL_MICG, 7, 0, 683 sun4i_codec_micin_loopback_gain_scale), 684 SOC_SINGLE_TLV("Mic1 Boost Volume", SUN4I_CODEC_ADC_ACTL, 685 SUN4I_CODEC_ADC_ACTL_PREG1, 3, 0, 686 sun4i_codec_micin_preamp_gain_scale), 687 SOC_SINGLE_TLV("Mic2 Boost Volume", SUN4I_CODEC_ADC_ACTL, 688 SUN4I_CODEC_ADC_ACTL_PREG2, 3, 0, 689 sun4i_codec_micin_preamp_gain_scale), 690 }; 691 692 static const struct snd_kcontrol_new sun7i_codec_controls[] = { 693 SOC_SINGLE_TLV("Power Amplifier Volume", SUN4I_CODEC_DAC_ACTL, 694 SUN4I_CODEC_DAC_ACTL_PA_VOL, 0x3F, 0, 695 sun4i_codec_pa_volume_scale), 696 SOC_SINGLE_TLV("Line Playback Volume", SUN4I_CODEC_DAC_ACTL, 697 SUN4I_CODEC_DAC_ACTL_LNG, 1, 0, 698 sun4i_codec_linein_loopback_gain_scale), 699 SOC_SINGLE_TLV("Line Boost Volume", SUN4I_CODEC_ADC_ACTL, 700 SUN4I_CODEC_ADC_ACTL_LNPREG, 7, 0, 701 sun4i_codec_linein_preamp_gain_scale), 702 SOC_SINGLE_TLV("FM Playback Volume", SUN4I_CODEC_DAC_ACTL, 703 SUN4I_CODEC_DAC_ACTL_FMG, 3, 0, 704 sun4i_codec_fmin_loopback_gain_scale), 705 SOC_SINGLE_TLV("Mic Playback Volume", SUN4I_CODEC_DAC_ACTL, 706 SUN4I_CODEC_DAC_ACTL_MICG, 7, 0, 707 sun4i_codec_micin_loopback_gain_scale), 708 SOC_SINGLE_TLV("Mic1 Boost Volume", SUN7I_CODEC_AC_MIC_PHONE_CAL, 709 SUN7I_CODEC_AC_MIC_PHONE_CAL_PREG1, 7, 0, 710 sun7i_codec_micin_preamp_gain_scale), 711 SOC_SINGLE_TLV("Mic2 Boost Volume", SUN7I_CODEC_AC_MIC_PHONE_CAL, 712 SUN7I_CODEC_AC_MIC_PHONE_CAL_PREG2, 7, 0, 713 sun7i_codec_micin_preamp_gain_scale), 714 }; 715 716 static const struct snd_kcontrol_new sun4i_codec_mixer_controls[] = { 717 SOC_DAPM_SINGLE("Left Mixer Left DAC Playback Switch", 718 SUN4I_CODEC_DAC_ACTL, SUN4I_CODEC_DAC_ACTL_LDACLMIXS, 719 1, 0), 720 SOC_DAPM_SINGLE("Right Mixer Right DAC Playback Switch", 721 SUN4I_CODEC_DAC_ACTL, SUN4I_CODEC_DAC_ACTL_RDACRMIXS, 722 1, 0), 723 SOC_DAPM_SINGLE("Right Mixer Left DAC Playback Switch", 724 SUN4I_CODEC_DAC_ACTL, 725 SUN4I_CODEC_DAC_ACTL_LDACRMIXS, 1, 0), 726 SOC_DAPM_DOUBLE("Line Playback Switch", SUN4I_CODEC_DAC_ACTL, 727 SUN4I_CODEC_DAC_ACTL_LLNS, 728 SUN4I_CODEC_DAC_ACTL_RLNS, 1, 0), 729 SOC_DAPM_DOUBLE("FM Playback Switch", SUN4I_CODEC_DAC_ACTL, 730 SUN4I_CODEC_DAC_ACTL_LFMS, 731 SUN4I_CODEC_DAC_ACTL_RFMS, 1, 0), 732 SOC_DAPM_DOUBLE("Mic1 Playback Switch", SUN4I_CODEC_DAC_ACTL, 733 SUN4I_CODEC_DAC_ACTL_MIC1LS, 734 SUN4I_CODEC_DAC_ACTL_MIC1RS, 1, 0), 735 SOC_DAPM_DOUBLE("Mic2 Playback Switch", SUN4I_CODEC_DAC_ACTL, 736 SUN4I_CODEC_DAC_ACTL_MIC2LS, 737 SUN4I_CODEC_DAC_ACTL_MIC2RS, 1, 0), 738 }; 739 740 static const struct snd_kcontrol_new sun4i_codec_pa_mixer_controls[] = { 741 SOC_DAPM_SINGLE("DAC Playback Switch", SUN4I_CODEC_DAC_ACTL, 742 SUN4I_CODEC_DAC_ACTL_DACPAS, 1, 0), 743 SOC_DAPM_SINGLE("Mixer Playback Switch", SUN4I_CODEC_DAC_ACTL, 744 SUN4I_CODEC_DAC_ACTL_MIXPAS, 1, 0), 745 }; 746 747 static const struct snd_soc_dapm_widget sun4i_codec_codec_dapm_widgets[] = { 748 /* Digital parts of the ADCs */ 749 SND_SOC_DAPM_SUPPLY("ADC", SUN4I_CODEC_ADC_FIFOC, 750 SUN4I_CODEC_ADC_FIFOC_EN_AD, 0, 751 NULL, 0), 752 753 /* Digital parts of the DACs */ 754 SND_SOC_DAPM_SUPPLY("DAC", SUN4I_CODEC_DAC_DPC, 755 SUN4I_CODEC_DAC_DPC_EN_DA, 0, 756 NULL, 0), 757 758 /* Analog parts of the ADCs */ 759 SND_SOC_DAPM_ADC("Left ADC", "Codec Capture", SUN4I_CODEC_ADC_ACTL, 760 SUN4I_CODEC_ADC_ACTL_ADC_L_EN, 0), 761 SND_SOC_DAPM_ADC("Right ADC", "Codec Capture", SUN4I_CODEC_ADC_ACTL, 762 SUN4I_CODEC_ADC_ACTL_ADC_R_EN, 0), 763 764 /* Analog parts of the DACs */ 765 SND_SOC_DAPM_DAC("Left DAC", "Codec Playback", SUN4I_CODEC_DAC_ACTL, 766 SUN4I_CODEC_DAC_ACTL_DACAENL, 0), 767 SND_SOC_DAPM_DAC("Right DAC", "Codec Playback", SUN4I_CODEC_DAC_ACTL, 768 SUN4I_CODEC_DAC_ACTL_DACAENR, 0), 769 770 /* Mixers */ 771 SND_SOC_DAPM_MIXER("Left Mixer", SND_SOC_NOPM, 0, 0, 772 sun4i_codec_mixer_controls, 773 ARRAY_SIZE(sun4i_codec_mixer_controls)), 774 SND_SOC_DAPM_MIXER("Right Mixer", SND_SOC_NOPM, 0, 0, 775 sun4i_codec_mixer_controls, 776 ARRAY_SIZE(sun4i_codec_mixer_controls)), 777 778 /* Global Mixer Enable */ 779 SND_SOC_DAPM_SUPPLY("Mixer Enable", SUN4I_CODEC_DAC_ACTL, 780 SUN4I_CODEC_DAC_ACTL_MIXEN, 0, NULL, 0), 781 782 /* VMIC */ 783 SND_SOC_DAPM_SUPPLY("VMIC", SUN4I_CODEC_ADC_ACTL, 784 SUN4I_CODEC_ADC_ACTL_VMICEN, 0, NULL, 0), 785 786 /* Mic Pre-Amplifiers */ 787 SND_SOC_DAPM_PGA("MIC1 Pre-Amplifier", SUN4I_CODEC_ADC_ACTL, 788 SUN4I_CODEC_ADC_ACTL_PREG1EN, 0, NULL, 0), 789 SND_SOC_DAPM_PGA("MIC2 Pre-Amplifier", SUN4I_CODEC_ADC_ACTL, 790 SUN4I_CODEC_ADC_ACTL_PREG2EN, 0, NULL, 0), 791 792 /* Power Amplifier */ 793 SND_SOC_DAPM_MIXER("Power Amplifier", SUN4I_CODEC_ADC_ACTL, 794 SUN4I_CODEC_ADC_ACTL_PA_EN, 0, 795 sun4i_codec_pa_mixer_controls, 796 ARRAY_SIZE(sun4i_codec_pa_mixer_controls)), 797 SND_SOC_DAPM_SWITCH("Power Amplifier Mute", SND_SOC_NOPM, 0, 0, 798 &sun4i_codec_pa_mute), 799 800 SND_SOC_DAPM_INPUT("Line Right"), 801 SND_SOC_DAPM_INPUT("Line Left"), 802 SND_SOC_DAPM_INPUT("FM Right"), 803 SND_SOC_DAPM_INPUT("FM Left"), 804 SND_SOC_DAPM_INPUT("Mic1"), 805 SND_SOC_DAPM_INPUT("Mic2"), 806 807 SND_SOC_DAPM_OUTPUT("HP Right"), 808 SND_SOC_DAPM_OUTPUT("HP Left"), 809 }; 810 811 static const struct snd_soc_dapm_route sun4i_codec_codec_dapm_routes[] = { 812 /* Left ADC / DAC Routes */ 813 { "Left ADC", NULL, "ADC" }, 814 { "Left DAC", NULL, "DAC" }, 815 816 /* Right ADC / DAC Routes */ 817 { "Right ADC", NULL, "ADC" }, 818 { "Right DAC", NULL, "DAC" }, 819 820 /* Right Mixer Routes */ 821 { "Right Mixer", NULL, "Mixer Enable" }, 822 { "Right Mixer", "Right Mixer Left DAC Playback Switch", "Left DAC" }, 823 { "Right Mixer", "Right Mixer Right DAC Playback Switch", "Right DAC" }, 824 { "Right Mixer", "Line Playback Switch", "Line Right" }, 825 { "Right Mixer", "FM Playback Switch", "FM Right" }, 826 { "Right Mixer", "Mic1 Playback Switch", "MIC1 Pre-Amplifier" }, 827 { "Right Mixer", "Mic2 Playback Switch", "MIC2 Pre-Amplifier" }, 828 829 /* Left Mixer Routes */ 830 { "Left Mixer", NULL, "Mixer Enable" }, 831 { "Left Mixer", "Left Mixer Left DAC Playback Switch", "Left DAC" }, 832 { "Left Mixer", "Line Playback Switch", "Line Left" }, 833 { "Left Mixer", "FM Playback Switch", "FM Left" }, 834 { "Left Mixer", "Mic1 Playback Switch", "MIC1 Pre-Amplifier" }, 835 { "Left Mixer", "Mic2 Playback Switch", "MIC2 Pre-Amplifier" }, 836 837 /* Power Amplifier Routes */ 838 { "Power Amplifier", "Mixer Playback Switch", "Left Mixer" }, 839 { "Power Amplifier", "Mixer Playback Switch", "Right Mixer" }, 840 { "Power Amplifier", "DAC Playback Switch", "Left DAC" }, 841 { "Power Amplifier", "DAC Playback Switch", "Right DAC" }, 842 843 /* Headphone Output Routes */ 844 { "Power Amplifier Mute", "Switch", "Power Amplifier" }, 845 { "HP Right", NULL, "Power Amplifier Mute" }, 846 { "HP Left", NULL, "Power Amplifier Mute" }, 847 848 /* Mic1 Routes */ 849 { "Left ADC", NULL, "MIC1 Pre-Amplifier" }, 850 { "Right ADC", NULL, "MIC1 Pre-Amplifier" }, 851 { "MIC1 Pre-Amplifier", NULL, "Mic1"}, 852 { "Mic1", NULL, "VMIC" }, 853 854 /* Mic2 Routes */ 855 { "Left ADC", NULL, "MIC2 Pre-Amplifier" }, 856 { "Right ADC", NULL, "MIC2 Pre-Amplifier" }, 857 { "MIC2 Pre-Amplifier", NULL, "Mic2"}, 858 { "Mic2", NULL, "VMIC" }, 859 }; 860 861 static const struct snd_soc_component_driver sun4i_codec_codec = { 862 .controls = sun4i_codec_controls, 863 .num_controls = ARRAY_SIZE(sun4i_codec_controls), 864 .dapm_widgets = sun4i_codec_codec_dapm_widgets, 865 .num_dapm_widgets = ARRAY_SIZE(sun4i_codec_codec_dapm_widgets), 866 .dapm_routes = sun4i_codec_codec_dapm_routes, 867 .num_dapm_routes = ARRAY_SIZE(sun4i_codec_codec_dapm_routes), 868 .idle_bias_on = 1, 869 .use_pmdown_time = 1, 870 .endianness = 1, 871 }; 872 873 static const struct snd_soc_component_driver sun7i_codec_codec = { 874 .controls = sun7i_codec_controls, 875 .num_controls = ARRAY_SIZE(sun7i_codec_controls), 876 .dapm_widgets = sun4i_codec_codec_dapm_widgets, 877 .num_dapm_widgets = ARRAY_SIZE(sun4i_codec_codec_dapm_widgets), 878 .dapm_routes = sun4i_codec_codec_dapm_routes, 879 .num_dapm_routes = ARRAY_SIZE(sun4i_codec_codec_dapm_routes), 880 .idle_bias_on = 1, 881 .use_pmdown_time = 1, 882 .endianness = 1, 883 }; 884 885 /*** sun6i Codec ***/ 886 887 /* mixer controls */ 888 static const struct snd_kcontrol_new sun6i_codec_mixer_controls[] = { 889 SOC_DAPM_DOUBLE("DAC Playback Switch", 890 SUN6I_CODEC_OM_DACA_CTRL, 891 SUN6I_CODEC_OM_DACA_CTRL_LMIX_DACL, 892 SUN6I_CODEC_OM_DACA_CTRL_RMIX_DACR, 1, 0), 893 SOC_DAPM_DOUBLE("DAC Reversed Playback Switch", 894 SUN6I_CODEC_OM_DACA_CTRL, 895 SUN6I_CODEC_OM_DACA_CTRL_LMIX_DACR, 896 SUN6I_CODEC_OM_DACA_CTRL_RMIX_DACL, 1, 0), 897 SOC_DAPM_DOUBLE("Line In Playback Switch", 898 SUN6I_CODEC_OM_DACA_CTRL, 899 SUN6I_CODEC_OM_DACA_CTRL_LMIX_LINEINL, 900 SUN6I_CODEC_OM_DACA_CTRL_RMIX_LINEINR, 1, 0), 901 SOC_DAPM_DOUBLE("Mic1 Playback Switch", 902 SUN6I_CODEC_OM_DACA_CTRL, 903 SUN6I_CODEC_OM_DACA_CTRL_LMIX_MIC1, 904 SUN6I_CODEC_OM_DACA_CTRL_RMIX_MIC1, 1, 0), 905 SOC_DAPM_DOUBLE("Mic2 Playback Switch", 906 SUN6I_CODEC_OM_DACA_CTRL, 907 SUN6I_CODEC_OM_DACA_CTRL_LMIX_MIC2, 908 SUN6I_CODEC_OM_DACA_CTRL_RMIX_MIC2, 1, 0), 909 }; 910 911 /* ADC mixer controls */ 912 static const struct snd_kcontrol_new sun6i_codec_adc_mixer_controls[] = { 913 SOC_DAPM_DOUBLE("Mixer Capture Switch", 914 SUN6I_CODEC_ADC_ACTL, 915 SUN6I_CODEC_ADC_ACTL_LADCMIX_OMIXL, 916 SUN6I_CODEC_ADC_ACTL_RADCMIX_OMIXR, 1, 0), 917 SOC_DAPM_DOUBLE("Mixer Reversed Capture Switch", 918 SUN6I_CODEC_ADC_ACTL, 919 SUN6I_CODEC_ADC_ACTL_LADCMIX_OMIXR, 920 SUN6I_CODEC_ADC_ACTL_RADCMIX_OMIXL, 1, 0), 921 SOC_DAPM_DOUBLE("Line In Capture Switch", 922 SUN6I_CODEC_ADC_ACTL, 923 SUN6I_CODEC_ADC_ACTL_LADCMIX_LINEINL, 924 SUN6I_CODEC_ADC_ACTL_RADCMIX_LINEINR, 1, 0), 925 SOC_DAPM_DOUBLE("Mic1 Capture Switch", 926 SUN6I_CODEC_ADC_ACTL, 927 SUN6I_CODEC_ADC_ACTL_LADCMIX_MIC1, 928 SUN6I_CODEC_ADC_ACTL_RADCMIX_MIC1, 1, 0), 929 SOC_DAPM_DOUBLE("Mic2 Capture Switch", 930 SUN6I_CODEC_ADC_ACTL, 931 SUN6I_CODEC_ADC_ACTL_LADCMIX_MIC2, 932 SUN6I_CODEC_ADC_ACTL_RADCMIX_MIC2, 1, 0), 933 }; 934 935 /* headphone controls */ 936 static const char * const sun6i_codec_hp_src_enum_text[] = { 937 "DAC", "Mixer", 938 }; 939 940 static SOC_ENUM_DOUBLE_DECL(sun6i_codec_hp_src_enum, 941 SUN6I_CODEC_OM_DACA_CTRL, 942 SUN6I_CODEC_OM_DACA_CTRL_LHPIS, 943 SUN6I_CODEC_OM_DACA_CTRL_RHPIS, 944 sun6i_codec_hp_src_enum_text); 945 946 static const struct snd_kcontrol_new sun6i_codec_hp_src[] = { 947 SOC_DAPM_ENUM("Headphone Source Playback Route", 948 sun6i_codec_hp_src_enum), 949 }; 950 951 /* microphone controls */ 952 static const char * const sun6i_codec_mic2_src_enum_text[] = { 953 "Mic2", "Mic3", 954 }; 955 956 static SOC_ENUM_SINGLE_DECL(sun6i_codec_mic2_src_enum, 957 SUN6I_CODEC_MIC_CTRL, 958 SUN6I_CODEC_MIC_CTRL_MIC2SLT, 959 sun6i_codec_mic2_src_enum_text); 960 961 static const struct snd_kcontrol_new sun6i_codec_mic2_src[] = { 962 SOC_DAPM_ENUM("Mic2 Amplifier Source Route", 963 sun6i_codec_mic2_src_enum), 964 }; 965 966 /* line out controls */ 967 static const char * const sun6i_codec_lineout_src_enum_text[] = { 968 "Stereo", "Mono Differential", 969 }; 970 971 static SOC_ENUM_DOUBLE_DECL(sun6i_codec_lineout_src_enum, 972 SUN6I_CODEC_MIC_CTRL, 973 SUN6I_CODEC_MIC_CTRL_LINEOUTLSRC, 974 SUN6I_CODEC_MIC_CTRL_LINEOUTRSRC, 975 sun6i_codec_lineout_src_enum_text); 976 977 static const struct snd_kcontrol_new sun6i_codec_lineout_src[] = { 978 SOC_DAPM_ENUM("Line Out Source Playback Route", 979 sun6i_codec_lineout_src_enum), 980 }; 981 982 /* volume / mute controls */ 983 static const DECLARE_TLV_DB_SCALE(sun6i_codec_dvol_scale, -7308, 116, 0); 984 static const DECLARE_TLV_DB_SCALE(sun6i_codec_hp_vol_scale, -6300, 100, 1); 985 static const DECLARE_TLV_DB_SCALE(sun6i_codec_out_mixer_pregain_scale, 986 -450, 150, 0); 987 static const DECLARE_TLV_DB_RANGE(sun6i_codec_lineout_vol_scale, 988 0, 1, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 1), 989 2, 31, TLV_DB_SCALE_ITEM(-4350, 150, 0), 990 ); 991 static const DECLARE_TLV_DB_RANGE(sun6i_codec_mic_gain_scale, 992 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0), 993 1, 7, TLV_DB_SCALE_ITEM(2400, 300, 0), 994 ); 995 996 static const struct snd_kcontrol_new sun6i_codec_codec_widgets[] = { 997 SOC_SINGLE_TLV("DAC Playback Volume", SUN4I_CODEC_DAC_DPC, 998 SUN4I_CODEC_DAC_DPC_DVOL, 0x3f, 1, 999 sun6i_codec_dvol_scale), 1000 SOC_SINGLE_TLV("Headphone Playback Volume", 1001 SUN6I_CODEC_OM_DACA_CTRL, 1002 SUN6I_CODEC_OM_DACA_CTRL_HPVOL, 0x3f, 0, 1003 sun6i_codec_hp_vol_scale), 1004 SOC_SINGLE_TLV("Line Out Playback Volume", 1005 SUN6I_CODEC_MIC_CTRL, 1006 SUN6I_CODEC_MIC_CTRL_LINEOUTVC, 0x1f, 0, 1007 sun6i_codec_lineout_vol_scale), 1008 SOC_DOUBLE("Headphone Playback Switch", 1009 SUN6I_CODEC_OM_DACA_CTRL, 1010 SUN6I_CODEC_OM_DACA_CTRL_LHPPAMUTE, 1011 SUN6I_CODEC_OM_DACA_CTRL_RHPPAMUTE, 1, 0), 1012 SOC_DOUBLE("Line Out Playback Switch", 1013 SUN6I_CODEC_MIC_CTRL, 1014 SUN6I_CODEC_MIC_CTRL_LINEOUTLEN, 1015 SUN6I_CODEC_MIC_CTRL_LINEOUTREN, 1, 0), 1016 /* Mixer pre-gains */ 1017 SOC_SINGLE_TLV("Line In Playback Volume", 1018 SUN6I_CODEC_OM_PA_CTRL, SUN6I_CODEC_OM_PA_CTRL_LINEING, 1019 0x7, 0, sun6i_codec_out_mixer_pregain_scale), 1020 SOC_SINGLE_TLV("Mic1 Playback Volume", 1021 SUN6I_CODEC_OM_PA_CTRL, SUN6I_CODEC_OM_PA_CTRL_MIC1G, 1022 0x7, 0, sun6i_codec_out_mixer_pregain_scale), 1023 SOC_SINGLE_TLV("Mic2 Playback Volume", 1024 SUN6I_CODEC_OM_PA_CTRL, SUN6I_CODEC_OM_PA_CTRL_MIC2G, 1025 0x7, 0, sun6i_codec_out_mixer_pregain_scale), 1026 1027 /* Microphone Amp boost gains */ 1028 SOC_SINGLE_TLV("Mic1 Boost Volume", SUN6I_CODEC_MIC_CTRL, 1029 SUN6I_CODEC_MIC_CTRL_MIC1BOOST, 0x7, 0, 1030 sun6i_codec_mic_gain_scale), 1031 SOC_SINGLE_TLV("Mic2 Boost Volume", SUN6I_CODEC_MIC_CTRL, 1032 SUN6I_CODEC_MIC_CTRL_MIC2BOOST, 0x7, 0, 1033 sun6i_codec_mic_gain_scale), 1034 SOC_DOUBLE_TLV("ADC Capture Volume", 1035 SUN6I_CODEC_ADC_ACTL, SUN6I_CODEC_ADC_ACTL_ADCLG, 1036 SUN6I_CODEC_ADC_ACTL_ADCRG, 0x7, 0, 1037 sun6i_codec_out_mixer_pregain_scale), 1038 }; 1039 1040 static const struct snd_soc_dapm_widget sun6i_codec_codec_dapm_widgets[] = { 1041 /* Microphone inputs */ 1042 SND_SOC_DAPM_INPUT("MIC1"), 1043 SND_SOC_DAPM_INPUT("MIC2"), 1044 SND_SOC_DAPM_INPUT("MIC3"), 1045 1046 /* Microphone Bias */ 1047 SND_SOC_DAPM_SUPPLY("HBIAS", SUN6I_CODEC_MIC_CTRL, 1048 SUN6I_CODEC_MIC_CTRL_HBIASEN, 0, NULL, 0), 1049 SND_SOC_DAPM_SUPPLY("MBIAS", SUN6I_CODEC_MIC_CTRL, 1050 SUN6I_CODEC_MIC_CTRL_MBIASEN, 0, NULL, 0), 1051 1052 /* Mic input path */ 1053 SND_SOC_DAPM_MUX("Mic2 Amplifier Source Route", 1054 SND_SOC_NOPM, 0, 0, sun6i_codec_mic2_src), 1055 SND_SOC_DAPM_PGA("Mic1 Amplifier", SUN6I_CODEC_MIC_CTRL, 1056 SUN6I_CODEC_MIC_CTRL_MIC1AMPEN, 0, NULL, 0), 1057 SND_SOC_DAPM_PGA("Mic2 Amplifier", SUN6I_CODEC_MIC_CTRL, 1058 SUN6I_CODEC_MIC_CTRL_MIC2AMPEN, 0, NULL, 0), 1059 1060 /* Line In */ 1061 SND_SOC_DAPM_INPUT("LINEIN"), 1062 1063 /* Digital parts of the ADCs */ 1064 SND_SOC_DAPM_SUPPLY("ADC Enable", SUN6I_CODEC_ADC_FIFOC, 1065 SUN6I_CODEC_ADC_FIFOC_EN_AD, 0, 1066 NULL, 0), 1067 1068 /* Analog parts of the ADCs */ 1069 SND_SOC_DAPM_ADC("Left ADC", "Codec Capture", SUN6I_CODEC_ADC_ACTL, 1070 SUN6I_CODEC_ADC_ACTL_ADCLEN, 0), 1071 SND_SOC_DAPM_ADC("Right ADC", "Codec Capture", SUN6I_CODEC_ADC_ACTL, 1072 SUN6I_CODEC_ADC_ACTL_ADCREN, 0), 1073 1074 /* ADC Mixers */ 1075 SOC_MIXER_ARRAY("Left ADC Mixer", SND_SOC_NOPM, 0, 0, 1076 sun6i_codec_adc_mixer_controls), 1077 SOC_MIXER_ARRAY("Right ADC Mixer", SND_SOC_NOPM, 0, 0, 1078 sun6i_codec_adc_mixer_controls), 1079 1080 /* Digital parts of the DACs */ 1081 SND_SOC_DAPM_SUPPLY("DAC Enable", SUN4I_CODEC_DAC_DPC, 1082 SUN4I_CODEC_DAC_DPC_EN_DA, 0, 1083 NULL, 0), 1084 1085 /* Analog parts of the DACs */ 1086 SND_SOC_DAPM_DAC("Left DAC", "Codec Playback", 1087 SUN6I_CODEC_OM_DACA_CTRL, 1088 SUN6I_CODEC_OM_DACA_CTRL_DACALEN, 0), 1089 SND_SOC_DAPM_DAC("Right DAC", "Codec Playback", 1090 SUN6I_CODEC_OM_DACA_CTRL, 1091 SUN6I_CODEC_OM_DACA_CTRL_DACAREN, 0), 1092 1093 /* Mixers */ 1094 SOC_MIXER_ARRAY("Left Mixer", SUN6I_CODEC_OM_DACA_CTRL, 1095 SUN6I_CODEC_OM_DACA_CTRL_LMIXEN, 0, 1096 sun6i_codec_mixer_controls), 1097 SOC_MIXER_ARRAY("Right Mixer", SUN6I_CODEC_OM_DACA_CTRL, 1098 SUN6I_CODEC_OM_DACA_CTRL_RMIXEN, 0, 1099 sun6i_codec_mixer_controls), 1100 1101 /* Headphone output path */ 1102 SND_SOC_DAPM_MUX("Headphone Source Playback Route", 1103 SND_SOC_NOPM, 0, 0, sun6i_codec_hp_src), 1104 SND_SOC_DAPM_OUT_DRV("Headphone Amp", SUN6I_CODEC_OM_PA_CTRL, 1105 SUN6I_CODEC_OM_PA_CTRL_HPPAEN, 0, NULL, 0), 1106 SND_SOC_DAPM_SUPPLY("HPCOM Protection", SUN6I_CODEC_OM_PA_CTRL, 1107 SUN6I_CODEC_OM_PA_CTRL_COMPTEN, 0, NULL, 0), 1108 SND_SOC_DAPM_REG(snd_soc_dapm_supply, "HPCOM", SUN6I_CODEC_OM_PA_CTRL, 1109 SUN6I_CODEC_OM_PA_CTRL_HPCOM_CTL, 0x3, 0x3, 0), 1110 SND_SOC_DAPM_OUTPUT("HP"), 1111 1112 /* Line Out path */ 1113 SND_SOC_DAPM_MUX("Line Out Source Playback Route", 1114 SND_SOC_NOPM, 0, 0, sun6i_codec_lineout_src), 1115 SND_SOC_DAPM_OUTPUT("LINEOUT"), 1116 }; 1117 1118 static const struct snd_soc_dapm_route sun6i_codec_codec_dapm_routes[] = { 1119 /* DAC Routes */ 1120 { "Left DAC", NULL, "DAC Enable" }, 1121 { "Right DAC", NULL, "DAC Enable" }, 1122 1123 /* Microphone Routes */ 1124 { "Mic1 Amplifier", NULL, "MIC1"}, 1125 { "Mic2 Amplifier Source Route", "Mic2", "MIC2" }, 1126 { "Mic2 Amplifier Source Route", "Mic3", "MIC3" }, 1127 { "Mic2 Amplifier", NULL, "Mic2 Amplifier Source Route"}, 1128 1129 /* Left Mixer Routes */ 1130 { "Left Mixer", "DAC Playback Switch", "Left DAC" }, 1131 { "Left Mixer", "DAC Reversed Playback Switch", "Right DAC" }, 1132 { "Left Mixer", "Line In Playback Switch", "LINEIN" }, 1133 { "Left Mixer", "Mic1 Playback Switch", "Mic1 Amplifier" }, 1134 { "Left Mixer", "Mic2 Playback Switch", "Mic2 Amplifier" }, 1135 1136 /* Right Mixer Routes */ 1137 { "Right Mixer", "DAC Playback Switch", "Right DAC" }, 1138 { "Right Mixer", "DAC Reversed Playback Switch", "Left DAC" }, 1139 { "Right Mixer", "Line In Playback Switch", "LINEIN" }, 1140 { "Right Mixer", "Mic1 Playback Switch", "Mic1 Amplifier" }, 1141 { "Right Mixer", "Mic2 Playback Switch", "Mic2 Amplifier" }, 1142 1143 /* Left ADC Mixer Routes */ 1144 { "Left ADC Mixer", "Mixer Capture Switch", "Left Mixer" }, 1145 { "Left ADC Mixer", "Mixer Reversed Capture Switch", "Right Mixer" }, 1146 { "Left ADC Mixer", "Line In Capture Switch", "LINEIN" }, 1147 { "Left ADC Mixer", "Mic1 Capture Switch", "Mic1 Amplifier" }, 1148 { "Left ADC Mixer", "Mic2 Capture Switch", "Mic2 Amplifier" }, 1149 1150 /* Right ADC Mixer Routes */ 1151 { "Right ADC Mixer", "Mixer Capture Switch", "Right Mixer" }, 1152 { "Right ADC Mixer", "Mixer Reversed Capture Switch", "Left Mixer" }, 1153 { "Right ADC Mixer", "Line In Capture Switch", "LINEIN" }, 1154 { "Right ADC Mixer", "Mic1 Capture Switch", "Mic1 Amplifier" }, 1155 { "Right ADC Mixer", "Mic2 Capture Switch", "Mic2 Amplifier" }, 1156 1157 /* Headphone Routes */ 1158 { "Headphone Source Playback Route", "DAC", "Left DAC" }, 1159 { "Headphone Source Playback Route", "DAC", "Right DAC" }, 1160 { "Headphone Source Playback Route", "Mixer", "Left Mixer" }, 1161 { "Headphone Source Playback Route", "Mixer", "Right Mixer" }, 1162 { "Headphone Amp", NULL, "Headphone Source Playback Route" }, 1163 { "HP", NULL, "Headphone Amp" }, 1164 { "HPCOM", NULL, "HPCOM Protection" }, 1165 1166 /* Line Out Routes */ 1167 { "Line Out Source Playback Route", "Stereo", "Left Mixer" }, 1168 { "Line Out Source Playback Route", "Stereo", "Right Mixer" }, 1169 { "Line Out Source Playback Route", "Mono Differential", "Left Mixer" }, 1170 { "Line Out Source Playback Route", "Mono Differential", "Right Mixer" }, 1171 { "LINEOUT", NULL, "Line Out Source Playback Route" }, 1172 1173 /* ADC Routes */ 1174 { "Left ADC", NULL, "ADC Enable" }, 1175 { "Right ADC", NULL, "ADC Enable" }, 1176 { "Left ADC", NULL, "Left ADC Mixer" }, 1177 { "Right ADC", NULL, "Right ADC Mixer" }, 1178 }; 1179 1180 static const struct snd_soc_component_driver sun6i_codec_codec = { 1181 .controls = sun6i_codec_codec_widgets, 1182 .num_controls = ARRAY_SIZE(sun6i_codec_codec_widgets), 1183 .dapm_widgets = sun6i_codec_codec_dapm_widgets, 1184 .num_dapm_widgets = ARRAY_SIZE(sun6i_codec_codec_dapm_widgets), 1185 .dapm_routes = sun6i_codec_codec_dapm_routes, 1186 .num_dapm_routes = ARRAY_SIZE(sun6i_codec_codec_dapm_routes), 1187 .idle_bias_on = 1, 1188 .use_pmdown_time = 1, 1189 .endianness = 1, 1190 }; 1191 1192 /* sun8i A23 codec */ 1193 static const struct snd_kcontrol_new sun8i_a23_codec_codec_controls[] = { 1194 SOC_SINGLE_TLV("DAC Playback Volume", SUN4I_CODEC_DAC_DPC, 1195 SUN4I_CODEC_DAC_DPC_DVOL, 0x3f, 1, 1196 sun6i_codec_dvol_scale), 1197 }; 1198 1199 static const struct snd_soc_dapm_widget sun8i_a23_codec_codec_widgets[] = { 1200 /* Digital parts of the ADCs */ 1201 SND_SOC_DAPM_SUPPLY("ADC Enable", SUN6I_CODEC_ADC_FIFOC, 1202 SUN6I_CODEC_ADC_FIFOC_EN_AD, 0, NULL, 0), 1203 /* Digital parts of the DACs */ 1204 SND_SOC_DAPM_SUPPLY("DAC Enable", SUN4I_CODEC_DAC_DPC, 1205 SUN4I_CODEC_DAC_DPC_EN_DA, 0, NULL, 0), 1206 1207 }; 1208 1209 static const struct snd_soc_component_driver sun8i_a23_codec_codec = { 1210 .controls = sun8i_a23_codec_codec_controls, 1211 .num_controls = ARRAY_SIZE(sun8i_a23_codec_codec_controls), 1212 .dapm_widgets = sun8i_a23_codec_codec_widgets, 1213 .num_dapm_widgets = ARRAY_SIZE(sun8i_a23_codec_codec_widgets), 1214 .idle_bias_on = 1, 1215 .use_pmdown_time = 1, 1216 .endianness = 1, 1217 }; 1218 1219 static const struct snd_soc_component_driver sun4i_codec_component = { 1220 .name = "sun4i-codec", 1221 .legacy_dai_naming = 1, 1222 #ifdef CONFIG_DEBUG_FS 1223 .debugfs_prefix = "cpu", 1224 #endif 1225 }; 1226 1227 #define SUN4I_CODEC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ 1228 SNDRV_PCM_FMTBIT_S32_LE) 1229 1230 static int sun4i_codec_dai_probe(struct snd_soc_dai *dai) 1231 { 1232 struct snd_soc_card *card = snd_soc_dai_get_drvdata(dai); 1233 struct sun4i_codec *scodec = snd_soc_card_get_drvdata(card); 1234 1235 snd_soc_dai_init_dma_data(dai, &scodec->playback_dma_data, 1236 &scodec->capture_dma_data); 1237 1238 return 0; 1239 } 1240 1241 static const struct snd_soc_dai_ops dummy_dai_ops = { 1242 .probe = sun4i_codec_dai_probe, 1243 }; 1244 1245 static struct snd_soc_dai_driver dummy_cpu_dai = { 1246 .name = "sun4i-codec-cpu-dai", 1247 .playback = { 1248 .stream_name = "Playback", 1249 .channels_min = 1, 1250 .channels_max = 2, 1251 .rates = SUN4I_CODEC_RATES, 1252 .formats = SUN4I_CODEC_FORMATS, 1253 .sig_bits = 24, 1254 }, 1255 .capture = { 1256 .stream_name = "Capture", 1257 .channels_min = 1, 1258 .channels_max = 2, 1259 .rates = SUN4I_CODEC_RATES, 1260 .formats = SUN4I_CODEC_FORMATS, 1261 .sig_bits = 24, 1262 }, 1263 .ops = &dummy_dai_ops, 1264 }; 1265 1266 static struct snd_soc_dai_link *sun4i_codec_create_link(struct device *dev, 1267 int *num_links) 1268 { 1269 struct snd_soc_dai_link *link = devm_kzalloc(dev, sizeof(*link), 1270 GFP_KERNEL); 1271 struct snd_soc_dai_link_component *dlc = devm_kzalloc(dev, 1272 3 * sizeof(*dlc), GFP_KERNEL); 1273 if (!link || !dlc) 1274 return NULL; 1275 1276 link->cpus = &dlc[0]; 1277 link->codecs = &dlc[1]; 1278 link->platforms = &dlc[2]; 1279 1280 link->num_cpus = 1; 1281 link->num_codecs = 1; 1282 link->num_platforms = 1; 1283 1284 link->name = "cdc"; 1285 link->stream_name = "CDC PCM"; 1286 link->codecs->dai_name = "Codec"; 1287 link->cpus->dai_name = dev_name(dev); 1288 link->codecs->name = dev_name(dev); 1289 link->platforms->name = dev_name(dev); 1290 link->dai_fmt = SND_SOC_DAIFMT_I2S; 1291 1292 *num_links = 1; 1293 1294 return link; 1295 }; 1296 1297 static int sun4i_codec_spk_event(struct snd_soc_dapm_widget *w, 1298 struct snd_kcontrol *k, int event) 1299 { 1300 struct sun4i_codec *scodec = snd_soc_card_get_drvdata(w->dapm->card); 1301 1302 gpiod_set_value_cansleep(scodec->gpio_pa, 1303 !!SND_SOC_DAPM_EVENT_ON(event)); 1304 1305 if (SND_SOC_DAPM_EVENT_ON(event)) { 1306 /* 1307 * Need a delay to wait for DAC to push the data. 700ms seems 1308 * to be the best compromise not to feel this delay while 1309 * playing a sound. 1310 */ 1311 msleep(700); 1312 } 1313 1314 return 0; 1315 } 1316 1317 static const struct snd_soc_dapm_widget sun4i_codec_card_dapm_widgets[] = { 1318 SND_SOC_DAPM_SPK("Speaker", sun4i_codec_spk_event), 1319 }; 1320 1321 static const struct snd_soc_dapm_route sun4i_codec_card_dapm_routes[] = { 1322 { "Speaker", NULL, "HP Right" }, 1323 { "Speaker", NULL, "HP Left" }, 1324 }; 1325 1326 static struct snd_soc_card *sun4i_codec_create_card(struct device *dev) 1327 { 1328 struct snd_soc_card *card; 1329 1330 card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL); 1331 if (!card) 1332 return ERR_PTR(-ENOMEM); 1333 1334 card->dai_link = sun4i_codec_create_link(dev, &card->num_links); 1335 if (!card->dai_link) 1336 return ERR_PTR(-ENOMEM); 1337 1338 card->dev = dev; 1339 card->owner = THIS_MODULE; 1340 card->name = "sun4i-codec"; 1341 card->dapm_widgets = sun4i_codec_card_dapm_widgets; 1342 card->num_dapm_widgets = ARRAY_SIZE(sun4i_codec_card_dapm_widgets); 1343 card->dapm_routes = sun4i_codec_card_dapm_routes; 1344 card->num_dapm_routes = ARRAY_SIZE(sun4i_codec_card_dapm_routes); 1345 1346 return card; 1347 }; 1348 1349 static const struct snd_soc_dapm_widget sun6i_codec_card_dapm_widgets[] = { 1350 SND_SOC_DAPM_HP("Headphone", NULL), 1351 SND_SOC_DAPM_LINE("Line In", NULL), 1352 SND_SOC_DAPM_LINE("Line Out", NULL), 1353 SND_SOC_DAPM_MIC("Headset Mic", NULL), 1354 SND_SOC_DAPM_MIC("Mic", NULL), 1355 SND_SOC_DAPM_SPK("Speaker", sun4i_codec_spk_event), 1356 }; 1357 1358 static struct snd_soc_card *sun6i_codec_create_card(struct device *dev) 1359 { 1360 struct snd_soc_card *card; 1361 int ret; 1362 1363 card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL); 1364 if (!card) 1365 return ERR_PTR(-ENOMEM); 1366 1367 card->dai_link = sun4i_codec_create_link(dev, &card->num_links); 1368 if (!card->dai_link) 1369 return ERR_PTR(-ENOMEM); 1370 1371 card->dev = dev; 1372 card->owner = THIS_MODULE; 1373 card->name = "A31 Audio Codec"; 1374 card->dapm_widgets = sun6i_codec_card_dapm_widgets; 1375 card->num_dapm_widgets = ARRAY_SIZE(sun6i_codec_card_dapm_widgets); 1376 card->fully_routed = true; 1377 1378 ret = snd_soc_of_parse_audio_routing(card, "allwinner,audio-routing"); 1379 if (ret) 1380 dev_warn(dev, "failed to parse audio-routing: %d\n", ret); 1381 1382 return card; 1383 }; 1384 1385 /* Connect digital side enables to analog side widgets */ 1386 static const struct snd_soc_dapm_route sun8i_codec_card_routes[] = { 1387 /* ADC Routes */ 1388 { "Left ADC", NULL, "ADC Enable" }, 1389 { "Right ADC", NULL, "ADC Enable" }, 1390 { "Codec Capture", NULL, "Left ADC" }, 1391 { "Codec Capture", NULL, "Right ADC" }, 1392 1393 /* DAC Routes */ 1394 { "Left DAC", NULL, "DAC Enable" }, 1395 { "Right DAC", NULL, "DAC Enable" }, 1396 { "Left DAC", NULL, "Codec Playback" }, 1397 { "Right DAC", NULL, "Codec Playback" }, 1398 }; 1399 1400 static struct snd_soc_aux_dev aux_dev = { 1401 .dlc = COMP_EMPTY(), 1402 }; 1403 1404 static struct snd_soc_card *sun8i_a23_codec_create_card(struct device *dev) 1405 { 1406 struct snd_soc_card *card; 1407 int ret; 1408 1409 card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL); 1410 if (!card) 1411 return ERR_PTR(-ENOMEM); 1412 1413 aux_dev.dlc.of_node = of_parse_phandle(dev->of_node, 1414 "allwinner,codec-analog-controls", 1415 0); 1416 if (!aux_dev.dlc.of_node) { 1417 dev_err(dev, "Can't find analog controls for codec.\n"); 1418 return ERR_PTR(-EINVAL); 1419 } 1420 1421 card->dai_link = sun4i_codec_create_link(dev, &card->num_links); 1422 if (!card->dai_link) 1423 return ERR_PTR(-ENOMEM); 1424 1425 card->dev = dev; 1426 card->owner = THIS_MODULE; 1427 card->name = "A23 Audio Codec"; 1428 card->dapm_widgets = sun6i_codec_card_dapm_widgets; 1429 card->num_dapm_widgets = ARRAY_SIZE(sun6i_codec_card_dapm_widgets); 1430 card->dapm_routes = sun8i_codec_card_routes; 1431 card->num_dapm_routes = ARRAY_SIZE(sun8i_codec_card_routes); 1432 card->aux_dev = &aux_dev; 1433 card->num_aux_devs = 1; 1434 card->fully_routed = true; 1435 1436 ret = snd_soc_of_parse_audio_routing(card, "allwinner,audio-routing"); 1437 if (ret) 1438 dev_warn(dev, "failed to parse audio-routing: %d\n", ret); 1439 1440 return card; 1441 }; 1442 1443 static struct snd_soc_card *sun8i_h3_codec_create_card(struct device *dev) 1444 { 1445 struct snd_soc_card *card; 1446 int ret; 1447 1448 card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL); 1449 if (!card) 1450 return ERR_PTR(-ENOMEM); 1451 1452 aux_dev.dlc.of_node = of_parse_phandle(dev->of_node, 1453 "allwinner,codec-analog-controls", 1454 0); 1455 if (!aux_dev.dlc.of_node) { 1456 dev_err(dev, "Can't find analog controls for codec.\n"); 1457 return ERR_PTR(-EINVAL); 1458 } 1459 1460 card->dai_link = sun4i_codec_create_link(dev, &card->num_links); 1461 if (!card->dai_link) 1462 return ERR_PTR(-ENOMEM); 1463 1464 card->dev = dev; 1465 card->owner = THIS_MODULE; 1466 card->name = "H3 Audio Codec"; 1467 card->dapm_widgets = sun6i_codec_card_dapm_widgets; 1468 card->num_dapm_widgets = ARRAY_SIZE(sun6i_codec_card_dapm_widgets); 1469 card->dapm_routes = sun8i_codec_card_routes; 1470 card->num_dapm_routes = ARRAY_SIZE(sun8i_codec_card_routes); 1471 card->aux_dev = &aux_dev; 1472 card->num_aux_devs = 1; 1473 card->fully_routed = true; 1474 1475 ret = snd_soc_of_parse_audio_routing(card, "allwinner,audio-routing"); 1476 if (ret) 1477 dev_warn(dev, "failed to parse audio-routing: %d\n", ret); 1478 1479 return card; 1480 }; 1481 1482 static struct snd_soc_card *sun8i_v3s_codec_create_card(struct device *dev) 1483 { 1484 struct snd_soc_card *card; 1485 int ret; 1486 1487 card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL); 1488 if (!card) 1489 return ERR_PTR(-ENOMEM); 1490 1491 aux_dev.dlc.of_node = of_parse_phandle(dev->of_node, 1492 "allwinner,codec-analog-controls", 1493 0); 1494 if (!aux_dev.dlc.of_node) { 1495 dev_err(dev, "Can't find analog controls for codec.\n"); 1496 return ERR_PTR(-EINVAL); 1497 } 1498 1499 card->dai_link = sun4i_codec_create_link(dev, &card->num_links); 1500 if (!card->dai_link) 1501 return ERR_PTR(-ENOMEM); 1502 1503 card->dev = dev; 1504 card->owner = THIS_MODULE; 1505 card->name = "V3s Audio Codec"; 1506 card->dapm_widgets = sun6i_codec_card_dapm_widgets; 1507 card->num_dapm_widgets = ARRAY_SIZE(sun6i_codec_card_dapm_widgets); 1508 card->dapm_routes = sun8i_codec_card_routes; 1509 card->num_dapm_routes = ARRAY_SIZE(sun8i_codec_card_routes); 1510 card->aux_dev = &aux_dev; 1511 card->num_aux_devs = 1; 1512 card->fully_routed = true; 1513 1514 ret = snd_soc_of_parse_audio_routing(card, "allwinner,audio-routing"); 1515 if (ret) 1516 dev_warn(dev, "failed to parse audio-routing: %d\n", ret); 1517 1518 return card; 1519 }; 1520 1521 static const struct regmap_config sun4i_codec_regmap_config = { 1522 .reg_bits = 32, 1523 .reg_stride = 4, 1524 .val_bits = 32, 1525 .max_register = SUN4I_CODEC_ADC_RXCNT, 1526 }; 1527 1528 static const struct regmap_config sun6i_codec_regmap_config = { 1529 .reg_bits = 32, 1530 .reg_stride = 4, 1531 .val_bits = 32, 1532 .max_register = SUN6I_CODEC_HMIC_DATA, 1533 }; 1534 1535 static const struct regmap_config sun7i_codec_regmap_config = { 1536 .reg_bits = 32, 1537 .reg_stride = 4, 1538 .val_bits = 32, 1539 .max_register = SUN7I_CODEC_AC_MIC_PHONE_CAL, 1540 }; 1541 1542 static const struct regmap_config sun8i_a23_codec_regmap_config = { 1543 .reg_bits = 32, 1544 .reg_stride = 4, 1545 .val_bits = 32, 1546 .max_register = SUN8I_A23_CODEC_ADC_RXCNT, 1547 }; 1548 1549 static const struct regmap_config sun8i_h3_codec_regmap_config = { 1550 .reg_bits = 32, 1551 .reg_stride = 4, 1552 .val_bits = 32, 1553 .max_register = SUN8I_H3_CODEC_ADC_DBG, 1554 }; 1555 1556 static const struct regmap_config sun8i_v3s_codec_regmap_config = { 1557 .reg_bits = 32, 1558 .reg_stride = 4, 1559 .val_bits = 32, 1560 .max_register = SUN8I_H3_CODEC_ADC_DBG, 1561 }; 1562 1563 struct sun4i_codec_quirks { 1564 const struct regmap_config *regmap_config; 1565 const struct snd_soc_component_driver *codec; 1566 struct snd_soc_card * (*create_card)(struct device *dev); 1567 struct reg_field reg_adc_fifoc; /* used for regmap_field */ 1568 unsigned int reg_dac_txdata; /* TX FIFO offset for DMA config */ 1569 unsigned int reg_adc_rxdata; /* RX FIFO offset for DMA config */ 1570 bool has_reset; 1571 }; 1572 1573 static const struct sun4i_codec_quirks sun4i_codec_quirks = { 1574 .regmap_config = &sun4i_codec_regmap_config, 1575 .codec = &sun4i_codec_codec, 1576 .create_card = sun4i_codec_create_card, 1577 .reg_adc_fifoc = REG_FIELD(SUN4I_CODEC_ADC_FIFOC, 0, 31), 1578 .reg_dac_txdata = SUN4I_CODEC_DAC_TXDATA, 1579 .reg_adc_rxdata = SUN4I_CODEC_ADC_RXDATA, 1580 }; 1581 1582 static const struct sun4i_codec_quirks sun6i_a31_codec_quirks = { 1583 .regmap_config = &sun6i_codec_regmap_config, 1584 .codec = &sun6i_codec_codec, 1585 .create_card = sun6i_codec_create_card, 1586 .reg_adc_fifoc = REG_FIELD(SUN6I_CODEC_ADC_FIFOC, 0, 31), 1587 .reg_dac_txdata = SUN4I_CODEC_DAC_TXDATA, 1588 .reg_adc_rxdata = SUN6I_CODEC_ADC_RXDATA, 1589 .has_reset = true, 1590 }; 1591 1592 static const struct sun4i_codec_quirks sun7i_codec_quirks = { 1593 .regmap_config = &sun7i_codec_regmap_config, 1594 .codec = &sun7i_codec_codec, 1595 .create_card = sun4i_codec_create_card, 1596 .reg_adc_fifoc = REG_FIELD(SUN4I_CODEC_ADC_FIFOC, 0, 31), 1597 .reg_dac_txdata = SUN4I_CODEC_DAC_TXDATA, 1598 .reg_adc_rxdata = SUN4I_CODEC_ADC_RXDATA, 1599 }; 1600 1601 static const struct sun4i_codec_quirks sun8i_a23_codec_quirks = { 1602 .regmap_config = &sun8i_a23_codec_regmap_config, 1603 .codec = &sun8i_a23_codec_codec, 1604 .create_card = sun8i_a23_codec_create_card, 1605 .reg_adc_fifoc = REG_FIELD(SUN6I_CODEC_ADC_FIFOC, 0, 31), 1606 .reg_dac_txdata = SUN4I_CODEC_DAC_TXDATA, 1607 .reg_adc_rxdata = SUN6I_CODEC_ADC_RXDATA, 1608 .has_reset = true, 1609 }; 1610 1611 static const struct sun4i_codec_quirks sun8i_h3_codec_quirks = { 1612 .regmap_config = &sun8i_h3_codec_regmap_config, 1613 /* 1614 * TODO Share the codec structure with A23 for now. 1615 * This should be split out when adding digital audio 1616 * processing support for the H3. 1617 */ 1618 .codec = &sun8i_a23_codec_codec, 1619 .create_card = sun8i_h3_codec_create_card, 1620 .reg_adc_fifoc = REG_FIELD(SUN6I_CODEC_ADC_FIFOC, 0, 31), 1621 .reg_dac_txdata = SUN8I_H3_CODEC_DAC_TXDATA, 1622 .reg_adc_rxdata = SUN6I_CODEC_ADC_RXDATA, 1623 .has_reset = true, 1624 }; 1625 1626 static const struct sun4i_codec_quirks sun8i_v3s_codec_quirks = { 1627 .regmap_config = &sun8i_v3s_codec_regmap_config, 1628 /* 1629 * TODO The codec structure should be split out, like 1630 * H3, when adding digital audio processing support. 1631 */ 1632 .codec = &sun8i_a23_codec_codec, 1633 .create_card = sun8i_v3s_codec_create_card, 1634 .reg_adc_fifoc = REG_FIELD(SUN6I_CODEC_ADC_FIFOC, 0, 31), 1635 .reg_dac_txdata = SUN8I_H3_CODEC_DAC_TXDATA, 1636 .reg_adc_rxdata = SUN6I_CODEC_ADC_RXDATA, 1637 .has_reset = true, 1638 }; 1639 1640 static const struct of_device_id sun4i_codec_of_match[] = { 1641 { 1642 .compatible = "allwinner,sun4i-a10-codec", 1643 .data = &sun4i_codec_quirks, 1644 }, 1645 { 1646 .compatible = "allwinner,sun6i-a31-codec", 1647 .data = &sun6i_a31_codec_quirks, 1648 }, 1649 { 1650 .compatible = "allwinner,sun7i-a20-codec", 1651 .data = &sun7i_codec_quirks, 1652 }, 1653 { 1654 .compatible = "allwinner,sun8i-a23-codec", 1655 .data = &sun8i_a23_codec_quirks, 1656 }, 1657 { 1658 .compatible = "allwinner,sun8i-h3-codec", 1659 .data = &sun8i_h3_codec_quirks, 1660 }, 1661 { 1662 .compatible = "allwinner,sun8i-v3s-codec", 1663 .data = &sun8i_v3s_codec_quirks, 1664 }, 1665 {} 1666 }; 1667 MODULE_DEVICE_TABLE(of, sun4i_codec_of_match); 1668 1669 static int sun4i_codec_probe(struct platform_device *pdev) 1670 { 1671 struct snd_soc_card *card; 1672 struct sun4i_codec *scodec; 1673 const struct sun4i_codec_quirks *quirks; 1674 struct resource *res; 1675 void __iomem *base; 1676 int ret; 1677 1678 scodec = devm_kzalloc(&pdev->dev, sizeof(*scodec), GFP_KERNEL); 1679 if (!scodec) 1680 return -ENOMEM; 1681 1682 scodec->dev = &pdev->dev; 1683 1684 base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); 1685 if (IS_ERR(base)) 1686 return PTR_ERR(base); 1687 1688 quirks = of_device_get_match_data(&pdev->dev); 1689 if (quirks == NULL) { 1690 dev_err(&pdev->dev, "Failed to determine the quirks to use\n"); 1691 return -ENODEV; 1692 } 1693 1694 scodec->regmap = devm_regmap_init_mmio(&pdev->dev, base, 1695 quirks->regmap_config); 1696 if (IS_ERR(scodec->regmap)) { 1697 dev_err(&pdev->dev, "Failed to create our regmap\n"); 1698 return PTR_ERR(scodec->regmap); 1699 } 1700 1701 /* Get the clocks from the DT */ 1702 scodec->clk_apb = devm_clk_get(&pdev->dev, "apb"); 1703 if (IS_ERR(scodec->clk_apb)) { 1704 dev_err(&pdev->dev, "Failed to get the APB clock\n"); 1705 return PTR_ERR(scodec->clk_apb); 1706 } 1707 1708 scodec->clk_module = devm_clk_get(&pdev->dev, "codec"); 1709 if (IS_ERR(scodec->clk_module)) { 1710 dev_err(&pdev->dev, "Failed to get the module clock\n"); 1711 return PTR_ERR(scodec->clk_module); 1712 } 1713 1714 if (quirks->has_reset) { 1715 scodec->rst = devm_reset_control_get_exclusive(&pdev->dev, 1716 NULL); 1717 if (IS_ERR(scodec->rst)) { 1718 dev_err(&pdev->dev, "Failed to get reset control\n"); 1719 return PTR_ERR(scodec->rst); 1720 } 1721 } 1722 1723 scodec->gpio_pa = devm_gpiod_get_optional(&pdev->dev, "allwinner,pa", 1724 GPIOD_OUT_LOW); 1725 if (IS_ERR(scodec->gpio_pa)) { 1726 ret = PTR_ERR(scodec->gpio_pa); 1727 dev_err_probe(&pdev->dev, ret, "Failed to get pa gpio\n"); 1728 return ret; 1729 } 1730 1731 /* reg_field setup */ 1732 scodec->reg_adc_fifoc = devm_regmap_field_alloc(&pdev->dev, 1733 scodec->regmap, 1734 quirks->reg_adc_fifoc); 1735 if (IS_ERR(scodec->reg_adc_fifoc)) { 1736 ret = PTR_ERR(scodec->reg_adc_fifoc); 1737 dev_err(&pdev->dev, "Failed to create regmap fields: %d\n", 1738 ret); 1739 return ret; 1740 } 1741 1742 /* Enable the bus clock */ 1743 if (clk_prepare_enable(scodec->clk_apb)) { 1744 dev_err(&pdev->dev, "Failed to enable the APB clock\n"); 1745 return -EINVAL; 1746 } 1747 1748 /* Deassert the reset control */ 1749 if (scodec->rst) { 1750 ret = reset_control_deassert(scodec->rst); 1751 if (ret) { 1752 dev_err(&pdev->dev, 1753 "Failed to deassert the reset control\n"); 1754 goto err_clk_disable; 1755 } 1756 } 1757 1758 /* DMA configuration for TX FIFO */ 1759 scodec->playback_dma_data.addr = res->start + quirks->reg_dac_txdata; 1760 scodec->playback_dma_data.maxburst = 8; 1761 scodec->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; 1762 1763 /* DMA configuration for RX FIFO */ 1764 scodec->capture_dma_data.addr = res->start + quirks->reg_adc_rxdata; 1765 scodec->capture_dma_data.maxburst = 8; 1766 scodec->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; 1767 1768 ret = devm_snd_soc_register_component(&pdev->dev, quirks->codec, 1769 &sun4i_codec_dai, 1); 1770 if (ret) { 1771 dev_err(&pdev->dev, "Failed to register our codec\n"); 1772 goto err_assert_reset; 1773 } 1774 1775 ret = devm_snd_soc_register_component(&pdev->dev, 1776 &sun4i_codec_component, 1777 &dummy_cpu_dai, 1); 1778 if (ret) { 1779 dev_err(&pdev->dev, "Failed to register our DAI\n"); 1780 goto err_assert_reset; 1781 } 1782 1783 ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0); 1784 if (ret) { 1785 dev_err(&pdev->dev, "Failed to register against DMAEngine\n"); 1786 goto err_assert_reset; 1787 } 1788 1789 card = quirks->create_card(&pdev->dev); 1790 if (IS_ERR(card)) { 1791 ret = PTR_ERR(card); 1792 dev_err(&pdev->dev, "Failed to create our card\n"); 1793 goto err_assert_reset; 1794 } 1795 1796 snd_soc_card_set_drvdata(card, scodec); 1797 1798 ret = snd_soc_register_card(card); 1799 if (ret) { 1800 dev_err_probe(&pdev->dev, ret, "Failed to register our card\n"); 1801 goto err_assert_reset; 1802 } 1803 1804 return 0; 1805 1806 err_assert_reset: 1807 if (scodec->rst) 1808 reset_control_assert(scodec->rst); 1809 err_clk_disable: 1810 clk_disable_unprepare(scodec->clk_apb); 1811 return ret; 1812 } 1813 1814 static void sun4i_codec_remove(struct platform_device *pdev) 1815 { 1816 struct snd_soc_card *card = platform_get_drvdata(pdev); 1817 struct sun4i_codec *scodec = snd_soc_card_get_drvdata(card); 1818 1819 snd_soc_unregister_card(card); 1820 if (scodec->rst) 1821 reset_control_assert(scodec->rst); 1822 clk_disable_unprepare(scodec->clk_apb); 1823 } 1824 1825 static struct platform_driver sun4i_codec_driver = { 1826 .driver = { 1827 .name = "sun4i-codec", 1828 .of_match_table = sun4i_codec_of_match, 1829 }, 1830 .probe = sun4i_codec_probe, 1831 .remove = sun4i_codec_remove, 1832 }; 1833 module_platform_driver(sun4i_codec_driver); 1834 1835 MODULE_DESCRIPTION("Allwinner A10 codec driver"); 1836 MODULE_AUTHOR("Emilio López <emilio@elopez.com.ar>"); 1837 MODULE_AUTHOR("Jon Smirl <jonsmirl@gmail.com>"); 1838 MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>"); 1839 MODULE_AUTHOR("Chen-Yu Tsai <wens@csie.org>"); 1840 MODULE_LICENSE("GPL"); 1841