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