1 // SPDX-License-Identifier: GPL-2.0 2 // 3 // Ingenic JZ4770 CODEC driver 4 // 5 // Copyright (C) 2012, Maarten ter Huurne <maarten@treewalker.org> 6 // Copyright (C) 2019, Paul Cercueil <paul@crapouillou.net> 7 8 #include <linux/clk.h> 9 #include <linux/delay.h> 10 #include <linux/iopoll.h> 11 #include <linux/module.h> 12 #include <linux/regmap.h> 13 #include <linux/time64.h> 14 15 #include <sound/pcm_params.h> 16 #include <sound/soc.h> 17 #include <sound/soc-dai.h> 18 #include <sound/soc-dapm.h> 19 #include <sound/tlv.h> 20 21 #define ICDC_RGADW_OFFSET 0x00 22 #define ICDC_RGDATA_OFFSET 0x04 23 24 /* ICDC internal register access control register(RGADW) */ 25 #define ICDC_RGADW_RGWR BIT(16) 26 27 #define ICDC_RGADW_RGADDR_OFFSET 8 28 #define ICDC_RGADW_RGADDR_MASK GENMASK(14, ICDC_RGADW_RGADDR_OFFSET) 29 30 #define ICDC_RGADW_RGDIN_OFFSET 0 31 #define ICDC_RGADW_RGDIN_MASK GENMASK(7, ICDC_RGADW_RGDIN_OFFSET) 32 33 /* ICDC internal register data output register (RGDATA)*/ 34 #define ICDC_RGDATA_IRQ BIT(8) 35 36 #define ICDC_RGDATA_RGDOUT_OFFSET 0 37 #define ICDC_RGDATA_RGDOUT_MASK GENMASK(7, ICDC_RGDATA_RGDOUT_OFFSET) 38 39 /* Internal register space, accessed through regmap */ 40 enum { 41 JZ4770_CODEC_REG_SR, 42 JZ4770_CODEC_REG_AICR_DAC, 43 JZ4770_CODEC_REG_AICR_ADC, 44 JZ4770_CODEC_REG_CR_LO, 45 JZ4770_CODEC_REG_CR_HP, 46 47 JZ4770_CODEC_REG_MISSING_REG1, 48 49 JZ4770_CODEC_REG_CR_DAC, 50 JZ4770_CODEC_REG_CR_MIC, 51 JZ4770_CODEC_REG_CR_LI, 52 JZ4770_CODEC_REG_CR_ADC, 53 JZ4770_CODEC_REG_CR_MIX, 54 JZ4770_CODEC_REG_CR_VIC, 55 JZ4770_CODEC_REG_CCR, 56 JZ4770_CODEC_REG_FCR_DAC, 57 JZ4770_CODEC_REG_FCR_ADC, 58 JZ4770_CODEC_REG_ICR, 59 JZ4770_CODEC_REG_IMR, 60 JZ4770_CODEC_REG_IFR, 61 JZ4770_CODEC_REG_GCR_HPL, 62 JZ4770_CODEC_REG_GCR_HPR, 63 JZ4770_CODEC_REG_GCR_LIBYL, 64 JZ4770_CODEC_REG_GCR_LIBYR, 65 JZ4770_CODEC_REG_GCR_DACL, 66 JZ4770_CODEC_REG_GCR_DACR, 67 JZ4770_CODEC_REG_GCR_MIC1, 68 JZ4770_CODEC_REG_GCR_MIC2, 69 JZ4770_CODEC_REG_GCR_ADCL, 70 JZ4770_CODEC_REG_GCR_ADCR, 71 72 JZ4770_CODEC_REG_MISSING_REG2, 73 74 JZ4770_CODEC_REG_GCR_MIXADC, 75 JZ4770_CODEC_REG_GCR_MIXDAC, 76 JZ4770_CODEC_REG_AGC1, 77 JZ4770_CODEC_REG_AGC2, 78 JZ4770_CODEC_REG_AGC3, 79 JZ4770_CODEC_REG_AGC4, 80 JZ4770_CODEC_REG_AGC5, 81 }; 82 83 #define REG_AICR_DAC_ADWL_OFFSET 6 84 #define REG_AICR_DAC_ADWL_MASK (0x3 << REG_AICR_DAC_ADWL_OFFSET) 85 #define REG_AICR_DAC_SERIAL BIT(1) 86 #define REG_AICR_DAC_I2S BIT(0) 87 88 #define REG_AICR_ADC_ADWL_OFFSET 6 89 #define REG_AICR_ADC_ADWL_MASK (0x3 << REG_AICR_ADC_ADWL_OFFSET) 90 #define REG_AICR_ADC_SERIAL BIT(1) 91 #define REG_AICR_ADC_I2S BIT(0) 92 93 #define REG_CR_LO_MUTE_OFFSET 7 94 #define REG_CR_LO_SB_OFFSET 4 95 #define REG_CR_LO_SEL_OFFSET 0 96 #define REG_CR_LO_SEL_MASK (0x3 << REG_CR_LO_SEL_OFFSET) 97 98 #define REG_CR_HP_MUTE BIT(7) 99 #define REG_CR_HP_LOAD BIT(6) 100 #define REG_CR_HP_SB_OFFSET 4 101 #define REG_CR_HP_SB_HPCM BIT(3) 102 #define REG_CR_HP_SEL_OFFSET 0 103 #define REG_CR_HP_SEL_MASK (0x3 << REG_CR_HP_SEL_OFFSET) 104 105 #define REG_CR_DAC_MUTE BIT(7) 106 #define REG_CR_DAC_MONO BIT(6) 107 #define REG_CR_DAC_LEFT_ONLY BIT(5) 108 #define REG_CR_DAC_SB_OFFSET 4 109 #define REG_CR_DAC_LRSWAP BIT(3) 110 111 #define REG_CR_MIC_STEREO_OFFSET 7 112 #define REG_CR_MIC_IDIFF_OFFSET 6 113 #define REG_CR_MIC_SB_MIC2_OFFSET 5 114 #define REG_CR_MIC_SB_MIC1_OFFSET 4 115 #define REG_CR_MIC_BIAS_V0_OFFSET 1 116 #define REG_CR_MIC_BIAS_SB_OFFSET 0 117 118 #define REG_CR_LI_LIBY_OFFSET 4 119 #define REG_CR_LI_SB_OFFSET 0 120 121 #define REG_CR_ADC_DMIC_SEL BIT(7) 122 #define REG_CR_ADC_MONO BIT(6) 123 #define REG_CR_ADC_LEFT_ONLY BIT(5) 124 #define REG_CR_ADC_SB_OFFSET 4 125 #define REG_CR_ADC_LRSWAP BIT(3) 126 #define REG_CR_ADC_IN_SEL_OFFSET 0 127 #define REG_CR_ADC_IN_SEL_MASK (0x3 << REG_CR_ADC_IN_SEL_OFFSET) 128 129 #define REG_CR_VIC_SB_SLEEP BIT(1) 130 #define REG_CR_VIC_SB BIT(0) 131 132 #define REG_CCR_CRYSTAL_OFFSET 0 133 #define REG_CCR_CRYSTAL_MASK (0xf << REG_CCR_CRYSTAL_OFFSET) 134 135 #define REG_FCR_DAC_FREQ_OFFSET 0 136 #define REG_FCR_DAC_FREQ_MASK (0xf << REG_FCR_DAC_FREQ_OFFSET) 137 138 #define REG_FCR_ADC_FREQ_OFFSET 0 139 #define REG_FCR_ADC_FREQ_MASK (0xf << REG_FCR_ADC_FREQ_OFFSET) 140 141 #define REG_ICR_INT_FORM_OFFSET 6 142 #define REG_ICR_INT_FORM_MASK (0x3 << REG_ICR_INT_FORM_OFFSET) 143 144 #define REG_IMR_ALL_MASK (0x7f) 145 #define REG_IMR_SCLR_MASK BIT(6) 146 #define REG_IMR_JACK_MASK BIT(5) 147 #define REG_IMR_SCMC_MASK BIT(4) 148 #define REG_IMR_RUP_MASK BIT(3) 149 #define REG_IMR_RDO_MASK BIT(2) 150 #define REG_IMR_GUP_MASK BIT(1) 151 #define REG_IMR_GDO_MASK BIT(0) 152 153 #define REG_IFR_ALL_MASK (0x7f) 154 #define REG_IFR_SCLR BIT(6) 155 #define REG_IFR_JACK BIT(5) 156 #define REG_IFR_SCMC BIT(4) 157 #define REG_IFR_RUP BIT(3) 158 #define REG_IFR_RDO BIT(2) 159 #define REG_IFR_GUP BIT(1) 160 #define REG_IFR_GDO BIT(0) 161 162 #define REG_GCR_HPL_LRGO BIT(7) 163 164 #define REG_GCR_DACL_RLGOD BIT(7) 165 166 #define REG_GCR_GAIN_OFFSET 0 167 #define REG_GCR_GAIN_MAX 0x1f 168 169 #define REG_GCR_MIC_GAIN_OFFSET 0 170 #define REG_GCR_MIC_GAIN_MAX 5 171 172 #define REG_GCR_ADC_GAIN_OFFSET 0 173 #define REG_GCR_ADC_GAIN_MAX 23 174 175 #define REG_AGC1_EN BIT(7) 176 177 /* codec private data */ 178 struct jz_codec { 179 struct device *dev; 180 struct regmap *regmap; 181 void __iomem *base; 182 struct clk *clk; 183 }; 184 185 static int jz4770_codec_set_bias_level(struct snd_soc_component *codec, 186 enum snd_soc_bias_level level) 187 { 188 struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec); 189 struct regmap *regmap = jz_codec->regmap; 190 191 switch (level) { 192 case SND_SOC_BIAS_PREPARE: 193 regmap_update_bits(regmap, JZ4770_CODEC_REG_CR_VIC, 194 REG_CR_VIC_SB, 0); 195 msleep(250); 196 regmap_update_bits(regmap, JZ4770_CODEC_REG_CR_VIC, 197 REG_CR_VIC_SB_SLEEP, 0); 198 msleep(400); 199 break; 200 case SND_SOC_BIAS_STANDBY: 201 regmap_update_bits(regmap, JZ4770_CODEC_REG_CR_VIC, 202 REG_CR_VIC_SB_SLEEP, REG_CR_VIC_SB_SLEEP); 203 regmap_update_bits(regmap, JZ4770_CODEC_REG_CR_VIC, 204 REG_CR_VIC_SB, REG_CR_VIC_SB); 205 /* fall-through */ 206 default: 207 break; 208 } 209 210 return 0; 211 } 212 213 static int jz4770_codec_startup(struct snd_pcm_substream *substream, 214 struct snd_soc_dai *dai) 215 { 216 struct snd_soc_component *codec = dai->component; 217 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(codec); 218 219 /* 220 * SYSCLK output from the codec to the AIC is required to keep the 221 * DMA transfer going during playback when all audible outputs have 222 * been disabled. 223 */ 224 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 225 snd_soc_dapm_force_enable_pin(dapm, "SYSCLK"); 226 227 return 0; 228 } 229 230 static void jz4770_codec_shutdown(struct snd_pcm_substream *substream, 231 struct snd_soc_dai *dai) 232 { 233 struct snd_soc_component *codec = dai->component; 234 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(codec); 235 236 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 237 snd_soc_dapm_disable_pin(dapm, "SYSCLK"); 238 } 239 240 241 static int jz4770_codec_pcm_trigger(struct snd_pcm_substream *substream, 242 int cmd, struct snd_soc_dai *dai) 243 { 244 struct snd_soc_component *codec = dai->component; 245 int ret = 0; 246 247 switch (cmd) { 248 case SNDRV_PCM_TRIGGER_START: 249 case SNDRV_PCM_TRIGGER_RESUME: 250 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 251 if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK) 252 snd_soc_component_force_bias_level(codec, 253 SND_SOC_BIAS_ON); 254 break; 255 case SNDRV_PCM_TRIGGER_STOP: 256 case SNDRV_PCM_TRIGGER_SUSPEND: 257 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 258 /* do nothing */ 259 break; 260 default: 261 ret = -EINVAL; 262 } 263 264 return ret; 265 } 266 267 static int jz4770_codec_digital_mute(struct snd_soc_dai *dai, int mute) 268 { 269 struct snd_soc_component *codec = dai->component; 270 struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec); 271 unsigned int gain_bit = mute ? REG_IFR_GDO : REG_IFR_GUP; 272 unsigned int val; 273 int change, err; 274 275 change = snd_soc_component_update_bits(codec, JZ4770_CODEC_REG_CR_DAC, 276 REG_CR_DAC_MUTE, 277 mute ? REG_CR_DAC_MUTE : 0); 278 if (change == 1) { 279 regmap_read(jz_codec->regmap, JZ4770_CODEC_REG_CR_DAC, &val); 280 281 if (val & BIT(REG_CR_DAC_SB_OFFSET)) 282 return 1; 283 284 err = regmap_read_poll_timeout(jz_codec->regmap, 285 JZ4770_CODEC_REG_IFR, 286 val, val & gain_bit, 287 1000, 100 * USEC_PER_MSEC); 288 if (err) { 289 dev_err(jz_codec->dev, 290 "Timeout while setting digital mute: %d", err); 291 return err; 292 } 293 294 /* clear GUP/GDO flag */ 295 regmap_update_bits(jz_codec->regmap, JZ4770_CODEC_REG_IFR, 296 gain_bit, gain_bit); 297 } 298 299 return 0; 300 } 301 302 /* unit: 0.01dB */ 303 static const DECLARE_TLV_DB_MINMAX_MUTE(dac_tlv, -3100, 0); 304 static const DECLARE_TLV_DB_SCALE(adc_tlv, 0, 100, 0); 305 static const DECLARE_TLV_DB_MINMAX(out_tlv, -2500, 600); 306 static const DECLARE_TLV_DB_SCALE(mic_boost_tlv, 0, 400, 0); 307 static const DECLARE_TLV_DB_SCALE(linein_tlv, -2500, 100, 0); 308 309 /* Unconditional controls. */ 310 static const struct snd_kcontrol_new jz4770_codec_snd_controls[] = { 311 /* record gain control */ 312 SOC_DOUBLE_R_TLV("PCM Capture Volume", 313 JZ4770_CODEC_REG_GCR_ADCL, JZ4770_CODEC_REG_GCR_ADCR, 314 REG_GCR_ADC_GAIN_OFFSET, REG_GCR_ADC_GAIN_MAX, 315 0, adc_tlv), 316 317 SOC_DOUBLE_R_TLV("Line In Bypass Playback Volume", 318 JZ4770_CODEC_REG_GCR_LIBYL, JZ4770_CODEC_REG_GCR_LIBYR, 319 REG_GCR_GAIN_OFFSET, REG_GCR_GAIN_MAX, 1, linein_tlv), 320 }; 321 322 static const struct snd_kcontrol_new jz4770_codec_pcm_playback_controls[] = { 323 { 324 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 325 .name = "Volume", 326 .info = snd_soc_info_volsw, 327 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ 328 | SNDRV_CTL_ELEM_ACCESS_READWRITE, 329 .tlv.p = dac_tlv, 330 .get = snd_soc_dapm_get_volsw, 331 .put = snd_soc_dapm_put_volsw, 332 /* 333 * NOTE: DACR/DACL are inversed; the gain value written to DACR 334 * seems to affect the left channel, and the gain value written 335 * to DACL seems to affect the right channel. 336 */ 337 .private_value = SOC_DOUBLE_R_VALUE(JZ4770_CODEC_REG_GCR_DACR, 338 JZ4770_CODEC_REG_GCR_DACL, 339 REG_GCR_GAIN_OFFSET, 340 REG_GCR_GAIN_MAX, 1), 341 }, 342 }; 343 344 static const struct snd_kcontrol_new jz4770_codec_hp_playback_controls[] = { 345 { 346 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 347 .name = "Volume", 348 .info = snd_soc_info_volsw, 349 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ 350 | SNDRV_CTL_ELEM_ACCESS_READWRITE, 351 .tlv.p = out_tlv, 352 .get = snd_soc_dapm_get_volsw, 353 .put = snd_soc_dapm_put_volsw, 354 /* HPR/HPL inversed for the same reason as above */ 355 .private_value = SOC_DOUBLE_R_VALUE(JZ4770_CODEC_REG_GCR_HPR, 356 JZ4770_CODEC_REG_GCR_HPL, 357 REG_GCR_GAIN_OFFSET, 358 REG_GCR_GAIN_MAX, 1), 359 }, 360 }; 361 362 static int hpout_event(struct snd_soc_dapm_widget *w, 363 struct snd_kcontrol *kcontrol, int event) 364 { 365 struct snd_soc_component *codec = snd_soc_dapm_to_component(w->dapm); 366 struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec); 367 unsigned int val; 368 int err; 369 370 switch (event) { 371 case SND_SOC_DAPM_PRE_PMU: 372 /* set cap-less, unmute HP */ 373 regmap_update_bits(jz_codec->regmap, JZ4770_CODEC_REG_CR_HP, 374 REG_CR_HP_SB_HPCM | REG_CR_HP_MUTE, 0); 375 break; 376 377 case SND_SOC_DAPM_POST_PMU: 378 /* wait for ramp-up complete (RUP) */ 379 err = regmap_read_poll_timeout(jz_codec->regmap, 380 JZ4770_CODEC_REG_IFR, 381 val, val & REG_IFR_RUP, 382 1000, 100 * USEC_PER_MSEC); 383 if (err) { 384 dev_err(jz_codec->dev, "RUP timeout: %d", err); 385 return err; 386 } 387 388 /* clear RUP flag */ 389 regmap_update_bits(jz_codec->regmap, JZ4770_CODEC_REG_IFR, 390 REG_IFR_RUP, REG_IFR_RUP); 391 392 break; 393 394 case SND_SOC_DAPM_POST_PMD: 395 /* set cap-couple, mute HP */ 396 regmap_update_bits(jz_codec->regmap, JZ4770_CODEC_REG_CR_HP, 397 REG_CR_HP_SB_HPCM | REG_CR_HP_MUTE, 398 REG_CR_HP_SB_HPCM | REG_CR_HP_MUTE); 399 400 err = regmap_read_poll_timeout(jz_codec->regmap, 401 JZ4770_CODEC_REG_IFR, 402 val, val & REG_IFR_RDO, 403 1000, 100 * USEC_PER_MSEC); 404 if (err) { 405 dev_err(jz_codec->dev, "RDO timeout: %d", err); 406 return err; 407 } 408 409 /* clear RDO flag */ 410 regmap_update_bits(jz_codec->regmap, JZ4770_CODEC_REG_IFR, 411 REG_IFR_RDO, REG_IFR_RDO); 412 413 break; 414 } 415 416 return 0; 417 } 418 419 static int adc_poweron_event(struct snd_soc_dapm_widget *w, 420 struct snd_kcontrol *kcontrol, int event) 421 { 422 if (event == SND_SOC_DAPM_POST_PMU) 423 msleep(1000); 424 425 return 0; 426 } 427 428 static const char * const jz4770_codec_hp_texts[] = { 429 "PCM", "Line In", "Mic 1", "Mic 2" 430 }; 431 static const unsigned int jz4770_codec_hp_values[] = { 3, 2, 0, 1 }; 432 static SOC_VALUE_ENUM_SINGLE_DECL(jz4770_codec_hp_enum, 433 JZ4770_CODEC_REG_CR_HP, 434 REG_CR_HP_SEL_OFFSET, 435 REG_CR_HP_SEL_MASK, 436 jz4770_codec_hp_texts, 437 jz4770_codec_hp_values); 438 static const struct snd_kcontrol_new jz4770_codec_hp_source = 439 SOC_DAPM_ENUM("Route", jz4770_codec_hp_enum); 440 441 static SOC_VALUE_ENUM_SINGLE_DECL(jz4770_codec_lo_enum, 442 JZ4770_CODEC_REG_CR_LO, 443 REG_CR_LO_SEL_OFFSET, 444 REG_CR_LO_SEL_MASK, 445 jz4770_codec_hp_texts, 446 jz4770_codec_hp_values); 447 static const struct snd_kcontrol_new jz4770_codec_lo_source = 448 SOC_DAPM_ENUM("Route", jz4770_codec_lo_enum); 449 450 static const char * const jz4770_codec_cap_texts[] = { 451 "Line In", "Mic 1", "Mic 2" 452 }; 453 static const unsigned int jz4770_codec_cap_values[] = { 2, 0, 1 }; 454 static SOC_VALUE_ENUM_SINGLE_DECL(jz4770_codec_cap_enum, 455 JZ4770_CODEC_REG_CR_ADC, 456 REG_CR_ADC_IN_SEL_OFFSET, 457 REG_CR_ADC_IN_SEL_MASK, 458 jz4770_codec_cap_texts, 459 jz4770_codec_cap_values); 460 static const struct snd_kcontrol_new jz4770_codec_cap_source = 461 SOC_DAPM_ENUM("Route", jz4770_codec_cap_enum); 462 463 static const struct snd_kcontrol_new jz4770_codec_mic_controls[] = { 464 SOC_DAPM_SINGLE("Stereo Capture Switch", JZ4770_CODEC_REG_CR_MIC, 465 REG_CR_MIC_STEREO_OFFSET, 1, 0), 466 }; 467 468 static const struct snd_soc_dapm_widget jz4770_codec_dapm_widgets[] = { 469 SND_SOC_DAPM_PGA_E("HP Out", JZ4770_CODEC_REG_CR_HP, 470 REG_CR_HP_SB_OFFSET, 1, NULL, 0, hpout_event, 471 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 472 SND_SOC_DAPM_POST_PMD), 473 474 SND_SOC_DAPM_PGA("Line Out", JZ4770_CODEC_REG_CR_LO, 475 REG_CR_LO_SB_OFFSET, 1, NULL, 0), 476 477 SND_SOC_DAPM_PGA("Line Out Switch 2", JZ4770_CODEC_REG_CR_LO, 478 REG_CR_LO_MUTE_OFFSET, 1, NULL, 0), 479 480 SND_SOC_DAPM_PGA("Line In", JZ4770_CODEC_REG_CR_LI, 481 REG_CR_LI_SB_OFFSET, 1, NULL, 0), 482 483 SND_SOC_DAPM_MUX("Headphones Source", SND_SOC_NOPM, 0, 0, 484 &jz4770_codec_hp_source), 485 SND_SOC_DAPM_MUX("Capture Source", SND_SOC_NOPM, 0, 0, 486 &jz4770_codec_cap_source), 487 SND_SOC_DAPM_MUX("Line Out Source", SND_SOC_NOPM, 0, 0, 488 &jz4770_codec_lo_source), 489 490 SND_SOC_DAPM_PGA("Mic 1", JZ4770_CODEC_REG_CR_MIC, 491 REG_CR_MIC_SB_MIC1_OFFSET, 1, NULL, 0), 492 SND_SOC_DAPM_PGA("Mic 2", JZ4770_CODEC_REG_CR_MIC, 493 REG_CR_MIC_SB_MIC2_OFFSET, 1, NULL, 0), 494 495 SND_SOC_DAPM_PGA("Mic Diff", JZ4770_CODEC_REG_CR_MIC, 496 REG_CR_MIC_IDIFF_OFFSET, 0, NULL, 0), 497 498 SND_SOC_DAPM_MIXER("Mic", SND_SOC_NOPM, 0, 0, 499 jz4770_codec_mic_controls, 500 ARRAY_SIZE(jz4770_codec_mic_controls)), 501 502 SND_SOC_DAPM_PGA("Line In Bypass", JZ4770_CODEC_REG_CR_LI, 503 REG_CR_LI_LIBY_OFFSET, 1, NULL, 0), 504 505 SND_SOC_DAPM_ADC_E("ADC", "HiFi Capture", JZ4770_CODEC_REG_CR_ADC, 506 REG_CR_ADC_SB_OFFSET, 1, adc_poweron_event, 507 SND_SOC_DAPM_POST_PMU), 508 SND_SOC_DAPM_DAC("DAC", "HiFi Playback", JZ4770_CODEC_REG_CR_DAC, 509 REG_CR_DAC_SB_OFFSET, 1), 510 511 SND_SOC_DAPM_MIXER("PCM Playback", SND_SOC_NOPM, 0, 0, 512 jz4770_codec_pcm_playback_controls, 513 ARRAY_SIZE(jz4770_codec_pcm_playback_controls)), 514 SND_SOC_DAPM_MIXER("Headphones Playback", SND_SOC_NOPM, 0, 0, 515 jz4770_codec_hp_playback_controls, 516 ARRAY_SIZE(jz4770_codec_hp_playback_controls)), 517 518 SND_SOC_DAPM_SUPPLY("MICBIAS", JZ4770_CODEC_REG_CR_MIC, 519 REG_CR_MIC_BIAS_SB_OFFSET, 1, NULL, 0), 520 521 SND_SOC_DAPM_INPUT("MIC1P"), 522 SND_SOC_DAPM_INPUT("MIC1N"), 523 SND_SOC_DAPM_INPUT("MIC2P"), 524 SND_SOC_DAPM_INPUT("MIC2N"), 525 526 SND_SOC_DAPM_OUTPUT("LOUT"), 527 SND_SOC_DAPM_OUTPUT("ROUT"), 528 529 SND_SOC_DAPM_OUTPUT("LHPOUT"), 530 SND_SOC_DAPM_OUTPUT("RHPOUT"), 531 532 SND_SOC_DAPM_INPUT("LLINEIN"), 533 SND_SOC_DAPM_INPUT("RLINEIN"), 534 535 SND_SOC_DAPM_OUTPUT("SYSCLK"), 536 }; 537 538 /* Unconditional routes. */ 539 static const struct snd_soc_dapm_route jz4770_codec_dapm_routes[] = { 540 { "Mic 1", NULL, "MIC1P" }, 541 { "Mic Diff", NULL, "MIC1N" }, 542 { "Mic 1", NULL, "Mic Diff" }, 543 { "Mic 2", NULL, "MIC2P" }, 544 { "Mic Diff", NULL, "MIC2N" }, 545 { "Mic 2", NULL, "Mic Diff" }, 546 547 { "Line In", NULL, "LLINEIN" }, 548 { "Line In", NULL, "RLINEIN" }, 549 550 { "Mic", "Stereo Capture Switch", "Mic 1" }, 551 { "Mic", "Stereo Capture Switch", "Mic 2" }, 552 { "Headphones Source", "Mic 1", "Mic" }, 553 { "Headphones Source", "Mic 2", "Mic" }, 554 { "Capture Source", "Mic 1", "Mic" }, 555 { "Capture Source", "Mic 2", "Mic" }, 556 557 { "Headphones Source", "Mic 1", "Mic 1" }, 558 { "Headphones Source", "Mic 2", "Mic 2" }, 559 { "Headphones Source", "Line In", "Line In Bypass" }, 560 { "Headphones Source", "PCM", "Headphones Playback" }, 561 { "HP Out", NULL, "Headphones Source" }, 562 563 { "Capture Source", "Line In", "Line In" }, 564 { "Capture Source", "Mic 1", "Mic 1" }, 565 { "Capture Source", "Mic 2", "Mic 2" }, 566 { "ADC", NULL, "Capture Source" }, 567 568 { "Line In Bypass", NULL, "Line In" }, 569 { "Line Out Source", "Line In", "Line In Bypass" }, 570 { "Line Out Source", "PCM", "PCM Playback" }, 571 572 { "LHPOUT", NULL, "HP Out"}, 573 { "RHPOUT", NULL, "HP Out"}, 574 575 { "Line Out", NULL, "Line Out Source" }, 576 { "Line Out Switch 2", NULL, "Line Out" }, 577 578 { "LOUT", NULL, "Line Out Switch 2"}, 579 { "ROUT", NULL, "Line Out Switch 2"}, 580 581 { "PCM Playback", "Volume", "DAC" }, 582 { "Headphones Playback", "Volume", "PCM Playback" }, 583 584 { "SYSCLK", NULL, "DAC" }, 585 }; 586 587 static void jz4770_codec_codec_init_regs(struct snd_soc_component *codec) 588 { 589 struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec); 590 struct regmap *regmap = jz_codec->regmap; 591 592 /* Collect updates for later sending. */ 593 regcache_cache_only(regmap, true); 594 595 /* default HP output to PCM */ 596 regmap_update_bits(regmap, JZ4770_CODEC_REG_CR_HP, 597 REG_CR_HP_SEL_MASK, REG_CR_HP_SEL_MASK); 598 599 /* default line output to PCM */ 600 regmap_update_bits(regmap, JZ4770_CODEC_REG_CR_LO, 601 REG_CR_LO_SEL_MASK, REG_CR_LO_SEL_MASK); 602 603 /* Disable stereo mic */ 604 regmap_update_bits(regmap, JZ4770_CODEC_REG_CR_MIC, 605 BIT(REG_CR_MIC_STEREO_OFFSET), 0); 606 607 /* Set mic 1 as default source for ADC */ 608 regmap_update_bits(regmap, JZ4770_CODEC_REG_CR_ADC, 609 REG_CR_ADC_IN_SEL_MASK, 0); 610 611 /* ADC/DAC: serial + i2s */ 612 regmap_update_bits(regmap, JZ4770_CODEC_REG_AICR_ADC, 613 REG_AICR_ADC_SERIAL | REG_AICR_ADC_I2S, 614 REG_AICR_ADC_SERIAL | REG_AICR_ADC_I2S); 615 regmap_update_bits(regmap, JZ4770_CODEC_REG_AICR_DAC, 616 REG_AICR_DAC_SERIAL | REG_AICR_DAC_I2S, 617 REG_AICR_DAC_SERIAL | REG_AICR_DAC_I2S); 618 619 /* The generated IRQ is a high level */ 620 regmap_update_bits(regmap, JZ4770_CODEC_REG_ICR, 621 REG_ICR_INT_FORM_MASK, 0); 622 regmap_update_bits(regmap, JZ4770_CODEC_REG_IMR, REG_IMR_ALL_MASK, 623 REG_IMR_JACK_MASK | REG_IMR_RUP_MASK | 624 REG_IMR_RDO_MASK | REG_IMR_GUP_MASK | 625 REG_IMR_GDO_MASK); 626 627 /* 12M oscillator */ 628 regmap_update_bits(regmap, JZ4770_CODEC_REG_CCR, 629 REG_CCR_CRYSTAL_MASK, 0); 630 631 /* 0: 16ohm/220uF, 1: 10kohm/1uF */ 632 regmap_update_bits(regmap, JZ4770_CODEC_REG_CR_HP, 633 REG_CR_HP_LOAD, 0); 634 635 /* disable automatic gain */ 636 regmap_update_bits(regmap, JZ4770_CODEC_REG_AGC1, REG_AGC1_EN, 0); 637 638 /* Disable DAC lrswap */ 639 regmap_update_bits(regmap, JZ4770_CODEC_REG_CR_DAC, 640 REG_CR_DAC_LRSWAP, REG_CR_DAC_LRSWAP); 641 642 /* Independent L/R DAC gain control */ 643 regmap_update_bits(regmap, JZ4770_CODEC_REG_GCR_DACL, 644 REG_GCR_DACL_RLGOD, 0); 645 646 /* Disable ADC lrswap */ 647 regmap_update_bits(regmap, JZ4770_CODEC_REG_CR_ADC, 648 REG_CR_ADC_LRSWAP, REG_CR_ADC_LRSWAP); 649 650 /* default to cap-less mode(0) */ 651 regmap_update_bits(regmap, JZ4770_CODEC_REG_CR_HP, 652 REG_CR_HP_SB_HPCM, 0); 653 654 /* Send collected updates. */ 655 regcache_cache_only(regmap, false); 656 regcache_sync(regmap); 657 658 /* Reset all interrupt flags. */ 659 regmap_write(regmap, JZ4770_CODEC_REG_IFR, REG_IFR_ALL_MASK); 660 } 661 662 static int jz4770_codec_codec_probe(struct snd_soc_component *codec) 663 { 664 struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec); 665 666 clk_prepare_enable(jz_codec->clk); 667 668 jz4770_codec_codec_init_regs(codec); 669 670 return 0; 671 } 672 673 static void jz4770_codec_codec_remove(struct snd_soc_component *codec) 674 { 675 struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec); 676 677 clk_disable_unprepare(jz_codec->clk); 678 } 679 680 static const struct snd_soc_component_driver jz4770_codec_soc_codec_dev = { 681 .probe = jz4770_codec_codec_probe, 682 .remove = jz4770_codec_codec_remove, 683 .set_bias_level = jz4770_codec_set_bias_level, 684 .controls = jz4770_codec_snd_controls, 685 .num_controls = ARRAY_SIZE(jz4770_codec_snd_controls), 686 .dapm_widgets = jz4770_codec_dapm_widgets, 687 .num_dapm_widgets = ARRAY_SIZE(jz4770_codec_dapm_widgets), 688 .dapm_routes = jz4770_codec_dapm_routes, 689 .num_dapm_routes = ARRAY_SIZE(jz4770_codec_dapm_routes), 690 .suspend_bias_off = 1, 691 .use_pmdown_time = 1, 692 }; 693 694 static const unsigned int jz4770_codec_sample_rates[] = { 695 96000, 48000, 44100, 32000, 696 24000, 22050, 16000, 12000, 697 11025, 9600, 8000, 698 }; 699 700 static int jz4770_codec_hw_params(struct snd_pcm_substream *substream, 701 struct snd_pcm_hw_params *params, 702 struct snd_soc_dai *dai) 703 { 704 struct jz_codec *codec = snd_soc_component_get_drvdata(dai->component); 705 unsigned int rate, bit_width; 706 707 switch (params_format(params)) { 708 case SNDRV_PCM_FORMAT_S16_LE: 709 bit_width = 0; 710 break; 711 case SNDRV_PCM_FORMAT_S18_3LE: 712 bit_width = 1; 713 break; 714 case SNDRV_PCM_FORMAT_S20_3LE: 715 bit_width = 2; 716 break; 717 case SNDRV_PCM_FORMAT_S24_3LE: 718 bit_width = 3; 719 break; 720 default: 721 return -EINVAL; 722 } 723 724 for (rate = 0; rate < ARRAY_SIZE(jz4770_codec_sample_rates); rate++) { 725 if (jz4770_codec_sample_rates[rate] == params_rate(params)) 726 break; 727 } 728 729 if (rate == ARRAY_SIZE(jz4770_codec_sample_rates)) 730 return -EINVAL; 731 732 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 733 regmap_update_bits(codec->regmap, JZ4770_CODEC_REG_AICR_DAC, 734 REG_AICR_DAC_ADWL_MASK, 735 bit_width << REG_AICR_DAC_ADWL_OFFSET); 736 regmap_update_bits(codec->regmap, JZ4770_CODEC_REG_FCR_DAC, 737 REG_FCR_DAC_FREQ_MASK, 738 rate << REG_FCR_DAC_FREQ_OFFSET); 739 } else { 740 regmap_update_bits(codec->regmap, JZ4770_CODEC_REG_AICR_ADC, 741 REG_AICR_ADC_ADWL_MASK, 742 bit_width << REG_AICR_ADC_ADWL_OFFSET); 743 regmap_update_bits(codec->regmap, JZ4770_CODEC_REG_FCR_ADC, 744 REG_FCR_ADC_FREQ_MASK, 745 rate << REG_FCR_ADC_FREQ_OFFSET); 746 } 747 748 return 0; 749 } 750 751 static const struct snd_soc_dai_ops jz4770_codec_dai_ops = { 752 .startup = jz4770_codec_startup, 753 .shutdown = jz4770_codec_shutdown, 754 .hw_params = jz4770_codec_hw_params, 755 .trigger = jz4770_codec_pcm_trigger, 756 .digital_mute = jz4770_codec_digital_mute, 757 }; 758 759 #define JZ_CODEC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ 760 SNDRV_PCM_FMTBIT_S18_3LE | \ 761 SNDRV_PCM_FMTBIT_S20_3LE | \ 762 SNDRV_PCM_FMTBIT_S24_3LE) 763 764 static struct snd_soc_dai_driver jz4770_codec_dai = { 765 .name = "jz4770-hifi", 766 .playback = { 767 .stream_name = "Playback", 768 .channels_min = 2, 769 .channels_max = 2, 770 .rates = SNDRV_PCM_RATE_8000_96000, 771 .formats = JZ_CODEC_FORMATS, 772 }, 773 .capture = { 774 .stream_name = "Capture", 775 .channels_min = 2, 776 .channels_max = 2, 777 .rates = SNDRV_PCM_RATE_8000_96000, 778 .formats = JZ_CODEC_FORMATS, 779 }, 780 .ops = &jz4770_codec_dai_ops, 781 }; 782 783 static bool jz4770_codec_volatile(struct device *dev, unsigned int reg) 784 { 785 return reg == JZ4770_CODEC_REG_SR || reg == JZ4770_CODEC_REG_IFR; 786 } 787 788 static bool jz4770_codec_readable(struct device *dev, unsigned int reg) 789 { 790 switch (reg) { 791 case JZ4770_CODEC_REG_MISSING_REG1: 792 case JZ4770_CODEC_REG_MISSING_REG2: 793 return false; 794 default: 795 return true; 796 } 797 } 798 799 static bool jz4770_codec_writeable(struct device *dev, unsigned int reg) 800 { 801 switch (reg) { 802 case JZ4770_CODEC_REG_SR: 803 case JZ4770_CODEC_REG_MISSING_REG1: 804 case JZ4770_CODEC_REG_MISSING_REG2: 805 return false; 806 default: 807 return true; 808 } 809 } 810 811 static int jz4770_codec_io_wait(struct jz_codec *codec) 812 { 813 u32 reg; 814 815 return readl_poll_timeout(codec->base + ICDC_RGADW_OFFSET, reg, 816 !(reg & ICDC_RGADW_RGWR), 817 1000, 10 * USEC_PER_MSEC); 818 } 819 820 static int jz4770_codec_reg_read(void *context, unsigned int reg, 821 unsigned int *val) 822 { 823 struct jz_codec *codec = context; 824 unsigned int i; 825 u32 tmp; 826 int ret; 827 828 ret = jz4770_codec_io_wait(codec); 829 if (ret) 830 return ret; 831 832 tmp = readl(codec->base + ICDC_RGADW_OFFSET); 833 tmp = (tmp & ~ICDC_RGADW_RGADDR_MASK) 834 | (reg << ICDC_RGADW_RGADDR_OFFSET); 835 writel(tmp, codec->base + ICDC_RGADW_OFFSET); 836 837 /* wait 6+ cycles */ 838 for (i = 0; i < 6; i++) 839 *val = readl(codec->base + ICDC_RGDATA_OFFSET) & 840 ICDC_RGDATA_RGDOUT_MASK; 841 842 return 0; 843 } 844 845 static int jz4770_codec_reg_write(void *context, unsigned int reg, 846 unsigned int val) 847 { 848 struct jz_codec *codec = context; 849 int ret; 850 851 ret = jz4770_codec_io_wait(codec); 852 if (ret) 853 return ret; 854 855 writel(ICDC_RGADW_RGWR | (reg << ICDC_RGADW_RGADDR_OFFSET) | val, 856 codec->base + ICDC_RGADW_OFFSET); 857 858 ret = jz4770_codec_io_wait(codec); 859 if (ret) 860 return ret; 861 862 return 0; 863 } 864 865 static const u8 jz4770_codec_reg_defaults[] = { 866 0x00, 0xC3, 0xC3, 0x90, 0x98, 0xFF, 0x90, 0xB1, 867 0x11, 0x10, 0x00, 0x03, 0x00, 0x00, 0x40, 0x00, 868 0xFF, 0x00, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 869 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x34, 870 0x07, 0x44, 0x1F, 0x00 871 }; 872 873 static struct regmap_config jz4770_codec_regmap_config = { 874 .reg_bits = 7, 875 .val_bits = 8, 876 877 .max_register = JZ4770_CODEC_REG_AGC5, 878 .volatile_reg = jz4770_codec_volatile, 879 .readable_reg = jz4770_codec_readable, 880 .writeable_reg = jz4770_codec_writeable, 881 882 .reg_read = jz4770_codec_reg_read, 883 .reg_write = jz4770_codec_reg_write, 884 885 .reg_defaults_raw = jz4770_codec_reg_defaults, 886 .num_reg_defaults_raw = ARRAY_SIZE(jz4770_codec_reg_defaults), 887 .cache_type = REGCACHE_FLAT, 888 }; 889 890 static int jz4770_codec_probe(struct platform_device *pdev) 891 { 892 struct device *dev = &pdev->dev; 893 struct jz_codec *codec; 894 int ret; 895 896 codec = devm_kzalloc(dev, sizeof(*codec), GFP_KERNEL); 897 if (!codec) 898 return -ENOMEM; 899 900 codec->dev = dev; 901 902 codec->base = devm_platform_ioremap_resource(pdev, 0); 903 if (IS_ERR(codec->base)) { 904 ret = PTR_ERR(codec->base); 905 dev_err(dev, "Failed to ioremap mmio memory: %d\n", ret); 906 return ret; 907 } 908 909 codec->regmap = devm_regmap_init(dev, NULL, codec, 910 &jz4770_codec_regmap_config); 911 if (IS_ERR(codec->regmap)) 912 return PTR_ERR(codec->regmap); 913 914 codec->clk = devm_clk_get(dev, "aic"); 915 if (IS_ERR(codec->clk)) 916 return PTR_ERR(codec->clk); 917 918 platform_set_drvdata(pdev, codec); 919 920 ret = devm_snd_soc_register_component(dev, &jz4770_codec_soc_codec_dev, 921 &jz4770_codec_dai, 1); 922 if (ret) { 923 dev_err(dev, "Failed to register codec: %d\n", ret); 924 return ret; 925 } 926 927 return 0; 928 } 929 930 static const struct of_device_id jz4770_codec_of_matches[] = { 931 { .compatible = "ingenic,jz4770-codec", }, 932 { /* sentinel */ } 933 }; 934 MODULE_DEVICE_TABLE(of, jz4770_codec_of_matches); 935 936 static struct platform_driver jz4770_codec_driver = { 937 .probe = jz4770_codec_probe, 938 .driver = { 939 .name = "jz4770-codec", 940 .of_match_table = jz4770_codec_of_matches, 941 }, 942 }; 943 module_platform_driver(jz4770_codec_driver); 944 945 MODULE_DESCRIPTION("JZ4770 SoC internal codec driver"); 946 MODULE_AUTHOR("Maarten ter Huurne <maarten@treewalker.org>"); 947 MODULE_AUTHOR("Paul Cercueil <paul@crapouillou.net>"); 948 MODULE_LICENSE("GPL v2"); 949