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