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