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