1 // SPDX-License-Identifier: GPL-2.0 2 // 3 // Ingenic JZ4760 CODEC driver 4 // 5 // Copyright (C) 2021, Christophe Branchereau <cbranchereau@gmail.com> 6 // Copyright (C) 2021, Paul Cercueil <paul@crapouillou.net> 7 8 #include <linux/bitfield.h> 9 #include <linux/clk.h> 10 #include <linux/delay.h> 11 #include <linux/iopoll.h> 12 #include <linux/module.h> 13 #include <linux/regmap.h> 14 #include <linux/time64.h> 15 16 #include <sound/pcm_params.h> 17 #include <sound/soc.h> 18 #include <sound/soc-dai.h> 19 #include <sound/soc-dapm.h> 20 #include <sound/tlv.h> 21 22 #define ICDC_RGADW_OFFSET 0x00 23 #define ICDC_RGDATA_OFFSET 0x04 24 25 /* ICDC internal register access control register(RGADW) */ 26 #define ICDC_RGADW_RGWR BIT(16) 27 #define ICDC_RGADW_RGADDR_MASK GENMASK(14, 8) 28 #define ICDC_RGADW_RGDIN_MASK GENMASK(7, 0) 29 30 /* ICDC internal register data output register (RGDATA)*/ 31 #define ICDC_RGDATA_IRQ BIT(8) 32 #define ICDC_RGDATA_RGDOUT_MASK GENMASK(7, 0) 33 34 /* Internal register space, accessed through regmap */ 35 enum { 36 JZ4760_CODEC_REG_SR, 37 JZ4760_CODEC_REG_AICR, 38 JZ4760_CODEC_REG_CR1, 39 JZ4760_CODEC_REG_CR2, 40 JZ4760_CODEC_REG_CR3, 41 JZ4760_CODEC_REG_CR4, 42 JZ4760_CODEC_REG_CCR1, 43 JZ4760_CODEC_REG_CCR2, 44 JZ4760_CODEC_REG_PMR1, 45 JZ4760_CODEC_REG_PMR2, 46 JZ4760_CODEC_REG_ICR, 47 JZ4760_CODEC_REG_IFR, 48 JZ4760_CODEC_REG_GCR1, 49 JZ4760_CODEC_REG_GCR2, 50 JZ4760_CODEC_REG_GCR3, 51 JZ4760_CODEC_REG_GCR4, 52 JZ4760_CODEC_REG_GCR5, 53 JZ4760_CODEC_REG_GCR6, 54 JZ4760_CODEC_REG_GCR7, 55 JZ4760_CODEC_REG_GCR8, 56 JZ4760_CODEC_REG_GCR9, 57 JZ4760_CODEC_REG_AGC1, 58 JZ4760_CODEC_REG_AGC2, 59 JZ4760_CODEC_REG_AGC3, 60 JZ4760_CODEC_REG_AGC4, 61 JZ4760_CODEC_REG_AGC5, 62 JZ4760_CODEC_REG_MIX1, 63 JZ4760_CODEC_REG_MIX2, 64 }; 65 66 #define REG_AICR_DAC_ADWL_MASK GENMASK(7, 6) 67 #define REG_AICR_DAC_SERIAL BIT(3) 68 #define REG_AICR_DAC_I2S BIT(1) 69 70 #define REG_AICR_ADC_ADWL_MASK GENMASK(5, 4) 71 72 #define REG_AICR_ADC_SERIAL BIT(2) 73 #define REG_AICR_ADC_I2S BIT(0) 74 75 #define REG_CR1_HP_LOAD BIT(7) 76 #define REG_CR1_HP_MUTE BIT(5) 77 #define REG_CR1_LO_MUTE_OFFSET 4 78 #define REG_CR1_BTL_MUTE_OFFSET 3 79 #define REG_CR1_OUTSEL_OFFSET 0 80 #define REG_CR1_OUTSEL_MASK GENMASK(1, REG_CR1_OUTSEL_OFFSET) 81 82 #define REG_CR2_DAC_MONO BIT(7) 83 #define REG_CR2_DAC_MUTE BIT(5) 84 #define REG_CR2_DAC_NOMAD BIT(1) 85 #define REG_CR2_DAC_RIGHT_ONLY BIT(0) 86 87 #define REG_CR3_ADC_INSEL_OFFSET 2 88 #define REG_CR3_ADC_INSEL_MASK GENMASK(3, REG_CR3_ADC_INSEL_OFFSET) 89 #define REG_CR3_MICSTEREO_OFFSET 1 90 #define REG_CR3_MICDIFF_OFFSET 0 91 92 #define REG_CR4_ADC_HPF_OFFSET 7 93 #define REG_CR4_ADC_RIGHT_ONLY BIT(0) 94 95 #define REG_CCR1_CRYSTAL_MASK GENMASK(3, 0) 96 97 #define REG_CCR2_DAC_FREQ_MASK GENMASK(7, 4) 98 #define REG_CCR2_ADC_FREQ_MASK GENMASK(3, 0) 99 100 #define REG_PMR1_SB BIT(7) 101 #define REG_PMR1_SB_SLEEP BIT(6) 102 #define REG_PMR1_SB_AIP_OFFSET 5 103 #define REG_PMR1_SB_LINE_OFFSET 4 104 #define REG_PMR1_SB_MIC1_OFFSET 3 105 #define REG_PMR1_SB_MIC2_OFFSET 2 106 #define REG_PMR1_SB_BYPASS_OFFSET 1 107 #define REG_PMR1_SB_MICBIAS_OFFSET 0 108 109 #define REG_PMR2_SB_ADC_OFFSET 4 110 #define REG_PMR2_SB_HP_OFFSET 3 111 #define REG_PMR2_SB_BTL_OFFSET 2 112 #define REG_PMR2_SB_LOUT_OFFSET 1 113 #define REG_PMR2_SB_DAC_OFFSET 0 114 115 #define REG_ICR_INT_FORM_MASK GENMASK(7, 6) 116 #define REG_ICR_ALL_MASK GENMASK(5, 0) 117 #define REG_ICR_JACK_MASK BIT(5) 118 #define REG_ICR_SCMC_MASK BIT(4) 119 #define REG_ICR_RUP_MASK BIT(3) 120 #define REG_ICR_RDO_MASK BIT(2) 121 #define REG_ICR_GUP_MASK BIT(1) 122 #define REG_ICR_GDO_MASK BIT(0) 123 124 #define REG_IFR_ALL_MASK GENMASK(5, 0) 125 #define REG_IFR_JACK BIT(6) 126 #define REG_IFR_JACK_EVENT BIT(5) 127 #define REG_IFR_SCMC BIT(4) 128 #define REG_IFR_RUP BIT(3) 129 #define REG_IFR_RDO BIT(2) 130 #define REG_IFR_GUP BIT(1) 131 #define REG_IFR_GDO BIT(0) 132 133 #define REG_GCR_GAIN_OFFSET 0 134 #define REG_GCR_GAIN_MAX 0x1f 135 136 #define REG_GCR_RL BIT(7) 137 138 #define REG_GCR_GIM1_MASK GENMASK(5, 3) 139 #define REG_GCR_GIM2_MASK GENMASK(2, 0) 140 #define REG_GCR_GIM_GAIN_MAX 7 141 142 #define REG_AGC1_EN BIT(7) 143 #define REG_AGC1_TARGET_MASK GENMASK(5, 2) 144 145 #define REG_AGC2_NG_THR_MASK GENMASK(6, 4) 146 #define REG_AGC2_HOLD_MASK GENMASK(3, 0) 147 148 #define REG_AGC3_ATK_MASK GENMASK(7, 4) 149 #define REG_AGC3_DCY_MASK GENMASK(3, 0) 150 151 #define REG_AGC4_AGC_MAX_MASK GENMASK(4, 0) 152 153 #define REG_AGC5_AGC_MIN_MASK GENMASK(4, 0) 154 155 #define REG_MIX1_MIX_REC_MASK GENMASK(7, 6) 156 #define REG_MIX1_GIMIX_MASK GENMASK(4, 0) 157 158 #define REG_MIX2_DAC_MIX_MASK GENMASK(7, 6) 159 #define REG_MIX2_GOMIX_MASK GENMASK(4, 0) 160 161 /* codec private data */ 162 struct jz_codec { 163 struct device *dev; 164 struct regmap *regmap; 165 void __iomem *base; 166 struct clk *clk; 167 }; 168 169 static int jz4760_codec_set_bias_level(struct snd_soc_component *codec, 170 enum snd_soc_bias_level level) 171 { 172 struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec); 173 struct regmap *regmap = jz_codec->regmap; 174 175 switch (level) { 176 case SND_SOC_BIAS_PREPARE: 177 /* Reset all interrupt flags. */ 178 regmap_write(regmap, JZ4760_CODEC_REG_IFR, REG_IFR_ALL_MASK); 179 180 regmap_clear_bits(regmap, JZ4760_CODEC_REG_PMR1, REG_PMR1_SB); 181 msleep(250); 182 regmap_clear_bits(regmap, JZ4760_CODEC_REG_PMR1, REG_PMR1_SB_SLEEP); 183 msleep(400); 184 break; 185 case SND_SOC_BIAS_STANDBY: 186 regmap_set_bits(regmap, JZ4760_CODEC_REG_PMR1, REG_PMR1_SB_SLEEP); 187 regmap_set_bits(regmap, JZ4760_CODEC_REG_PMR1, REG_PMR1_SB); 188 break; 189 default: 190 break; 191 } 192 193 return 0; 194 } 195 196 static int jz4760_codec_startup(struct snd_pcm_substream *substream, 197 struct snd_soc_dai *dai) 198 { 199 struct snd_soc_component *codec = dai->component; 200 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(codec); 201 int ret = 0; 202 203 /* 204 * SYSCLK output from the codec to the AIC is required to keep the 205 * DMA transfer going during playback when all audible outputs have 206 * been disabled. 207 */ 208 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 209 ret = snd_soc_dapm_force_enable_pin(dapm, "SYSCLK"); 210 return ret; 211 } 212 213 static void jz4760_codec_shutdown(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 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 220 snd_soc_dapm_disable_pin(dapm, "SYSCLK"); 221 } 222 223 224 static int jz4760_codec_pcm_trigger(struct snd_pcm_substream *substream, 225 int cmd, struct snd_soc_dai *dai) 226 { 227 struct snd_soc_component *codec = dai->component; 228 int ret = 0; 229 230 switch (cmd) { 231 case SNDRV_PCM_TRIGGER_START: 232 case SNDRV_PCM_TRIGGER_RESUME: 233 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 234 if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK) 235 snd_soc_component_force_bias_level(codec, SND_SOC_BIAS_ON); 236 break; 237 case SNDRV_PCM_TRIGGER_STOP: 238 case SNDRV_PCM_TRIGGER_SUSPEND: 239 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 240 /* do nothing */ 241 break; 242 default: 243 ret = -EINVAL; 244 } 245 246 return ret; 247 } 248 249 static int jz4760_codec_mute_stream(struct snd_soc_dai *dai, int mute, int direction) 250 { 251 struct snd_soc_component *codec = dai->component; 252 struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec); 253 unsigned int gain_bit = mute ? REG_IFR_GDO : REG_IFR_GUP; 254 unsigned int val, reg; 255 int change, err; 256 257 change = snd_soc_component_update_bits(codec, JZ4760_CODEC_REG_CR2, 258 REG_CR2_DAC_MUTE, 259 mute ? REG_CR2_DAC_MUTE : 0); 260 if (change == 1) { 261 regmap_read(jz_codec->regmap, JZ4760_CODEC_REG_PMR2, &val); 262 263 if (val & BIT(REG_PMR2_SB_DAC_OFFSET)) 264 return 1; 265 266 err = regmap_read_poll_timeout(jz_codec->regmap, 267 JZ4760_CODEC_REG_IFR, 268 val, val & gain_bit, 269 1000, 1 * USEC_PER_SEC); 270 if (err) { 271 dev_err(jz_codec->dev, 272 "Timeout while setting digital mute: %d", err); 273 return err; 274 } 275 276 /* clear GUP/GDO flag */ 277 regmap_write(jz_codec->regmap, JZ4760_CODEC_REG_IFR, gain_bit); 278 } 279 280 regmap_read(jz_codec->regmap, JZ4760_CODEC_REG_CR2, ®); 281 282 return 0; 283 } 284 285 /* unit: 0.01dB */ 286 static const DECLARE_TLV_DB_MINMAX_MUTE(dac_tlv, -3100, 100); 287 static const DECLARE_TLV_DB_SCALE(adc_tlv, 0, 100, 0); 288 static const DECLARE_TLV_DB_MINMAX(out_tlv, -2500, 100); 289 static const DECLARE_TLV_DB_SCALE(linein_tlv, -2500, 100, 0); 290 291 /* Unconditional controls. */ 292 static const struct snd_kcontrol_new jz4760_codec_snd_controls[] = { 293 /* record gain control */ 294 SOC_DOUBLE_R_TLV("PCM Capture Volume", 295 JZ4760_CODEC_REG_GCR9, JZ4760_CODEC_REG_GCR8, 296 REG_GCR_GAIN_OFFSET, REG_GCR_GAIN_MAX, 0, adc_tlv), 297 298 SOC_DOUBLE_R_TLV("Line In Bypass Playback Volume", 299 JZ4760_CODEC_REG_GCR4, JZ4760_CODEC_REG_GCR3, 300 REG_GCR_GAIN_OFFSET, REG_GCR_GAIN_MAX, 1, linein_tlv), 301 302 SOC_SINGLE("High-Pass Filter Capture Switch", 303 JZ4760_CODEC_REG_CR4, 304 REG_CR4_ADC_HPF_OFFSET, 1, 0), 305 }; 306 307 static const struct snd_kcontrol_new jz4760_codec_pcm_playback_controls[] = { 308 { 309 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 310 .name = "Volume", 311 .info = snd_soc_info_volsw, 312 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ 313 | SNDRV_CTL_ELEM_ACCESS_READWRITE, 314 .tlv.p = dac_tlv, 315 .get = snd_soc_dapm_get_volsw, 316 .put = snd_soc_dapm_put_volsw, 317 .private_value = SOC_DOUBLE_R_VALUE(JZ4760_CODEC_REG_GCR6, 318 JZ4760_CODEC_REG_GCR5, 319 REG_GCR_GAIN_OFFSET, 320 REG_GCR_GAIN_MAX, 1), 321 }, 322 }; 323 324 static const struct snd_kcontrol_new jz4760_codec_hp_playback_controls[] = { 325 { 326 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 327 .name = "Volume", 328 .info = snd_soc_info_volsw, 329 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ 330 | SNDRV_CTL_ELEM_ACCESS_READWRITE, 331 .tlv.p = out_tlv, 332 .get = snd_soc_dapm_get_volsw, 333 .put = snd_soc_dapm_put_volsw, 334 .private_value = SOC_DOUBLE_R_VALUE(JZ4760_CODEC_REG_GCR2, 335 JZ4760_CODEC_REG_GCR1, 336 REG_GCR_GAIN_OFFSET, 337 REG_GCR_GAIN_MAX, 1), 338 }, 339 }; 340 341 static int hpout_event(struct snd_soc_dapm_widget *w, 342 struct snd_kcontrol *kcontrol, int event) 343 { 344 struct snd_soc_component *codec = snd_soc_dapm_to_component(w->dapm); 345 struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec); 346 unsigned int val; 347 int err; 348 349 switch (event) { 350 case SND_SOC_DAPM_PRE_PMU: 351 /* unmute HP */ 352 regmap_clear_bits(jz_codec->regmap, JZ4760_CODEC_REG_CR1, 353 REG_CR1_HP_MUTE); 354 break; 355 356 case SND_SOC_DAPM_POST_PMU: 357 /* wait for ramp-up complete (RUP) */ 358 err = regmap_read_poll_timeout(jz_codec->regmap, 359 JZ4760_CODEC_REG_IFR, 360 val, val & REG_IFR_RUP, 361 1000, 1 * USEC_PER_SEC); 362 if (err) { 363 dev_err(jz_codec->dev, "RUP timeout: %d", err); 364 return err; 365 } 366 367 /* clear RUP flag */ 368 regmap_set_bits(jz_codec->regmap, JZ4760_CODEC_REG_IFR, 369 REG_IFR_RUP); 370 371 break; 372 373 case SND_SOC_DAPM_POST_PMD: 374 /* mute HP */ 375 regmap_set_bits(jz_codec->regmap, JZ4760_CODEC_REG_CR1, 376 REG_CR1_HP_MUTE); 377 378 err = regmap_read_poll_timeout(jz_codec->regmap, 379 JZ4760_CODEC_REG_IFR, 380 val, val & REG_IFR_RDO, 381 1000, 1 * USEC_PER_SEC); 382 if (err) { 383 dev_err(jz_codec->dev, "RDO timeout: %d", err); 384 return err; 385 } 386 387 /* clear RDO flag */ 388 regmap_set_bits(jz_codec->regmap, JZ4760_CODEC_REG_IFR, 389 REG_IFR_RDO); 390 391 break; 392 } 393 394 return 0; 395 } 396 397 static const char * const jz4760_codec_hp_texts[] = { 398 "PCM", "Line In", "Mic 1", "Mic 2" 399 }; 400 401 static const unsigned int jz4760_codec_hp_values[] = { 3, 2, 0, 1 }; 402 403 static SOC_VALUE_ENUM_SINGLE_DECL(jz4760_codec_hp_enum, 404 JZ4760_CODEC_REG_CR1, 405 REG_CR1_OUTSEL_OFFSET, 406 REG_CR1_OUTSEL_MASK >> REG_CR1_OUTSEL_OFFSET, 407 jz4760_codec_hp_texts, 408 jz4760_codec_hp_values); 409 static const struct snd_kcontrol_new jz4760_codec_hp_source = 410 SOC_DAPM_ENUM("Route", jz4760_codec_hp_enum); 411 412 static const char * const jz4760_codec_cap_texts[] = { 413 "Line In", "Mic 1", "Mic 2" 414 }; 415 416 static const unsigned int jz4760_codec_cap_values[] = { 2, 0, 1 }; 417 418 static SOC_VALUE_ENUM_SINGLE_DECL(jz4760_codec_cap_enum, 419 JZ4760_CODEC_REG_CR3, 420 REG_CR3_ADC_INSEL_OFFSET, 421 REG_CR3_ADC_INSEL_MASK >> REG_CR3_ADC_INSEL_OFFSET, 422 jz4760_codec_cap_texts, 423 jz4760_codec_cap_values); 424 static const struct snd_kcontrol_new jz4760_codec_cap_source = 425 SOC_DAPM_ENUM("Route", jz4760_codec_cap_enum); 426 427 static const struct snd_kcontrol_new jz4760_codec_mic_controls[] = { 428 SOC_DAPM_SINGLE("Stereo Capture Switch", JZ4760_CODEC_REG_CR3, 429 REG_CR3_MICSTEREO_OFFSET, 1, 0), 430 }; 431 432 static const struct snd_kcontrol_new jz4760_codec_line_out_switch = 433 SOC_DAPM_SINGLE("Switch", JZ4760_CODEC_REG_CR1, 434 REG_CR1_LO_MUTE_OFFSET, 0, 0); 435 static const struct snd_kcontrol_new jz4760_codec_btl_out_switch = 436 SOC_DAPM_SINGLE("Switch", JZ4760_CODEC_REG_CR1, 437 REG_CR1_BTL_MUTE_OFFSET, 0, 0); 438 439 static const struct snd_soc_dapm_widget jz4760_codec_dapm_widgets[] = { 440 SND_SOC_DAPM_PGA_E("HP Out", JZ4760_CODEC_REG_PMR2, 441 REG_PMR2_SB_HP_OFFSET, 1, NULL, 0, hpout_event, 442 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 443 SND_SOC_DAPM_POST_PMD), 444 445 SND_SOC_DAPM_SWITCH("Line Out", JZ4760_CODEC_REG_PMR2, 446 REG_PMR2_SB_LOUT_OFFSET, 1, 447 &jz4760_codec_line_out_switch), 448 449 SND_SOC_DAPM_SWITCH("BTL Out", JZ4760_CODEC_REG_PMR2, 450 REG_PMR2_SB_BTL_OFFSET, 1, 451 &jz4760_codec_btl_out_switch), 452 453 SND_SOC_DAPM_PGA("Line In", JZ4760_CODEC_REG_PMR1, 454 REG_PMR1_SB_LINE_OFFSET, 1, NULL, 0), 455 456 SND_SOC_DAPM_MUX("Headphones Source", SND_SOC_NOPM, 0, 0, 457 &jz4760_codec_hp_source), 458 459 SND_SOC_DAPM_MUX("Capture Source", SND_SOC_NOPM, 0, 0, 460 &jz4760_codec_cap_source), 461 462 SND_SOC_DAPM_PGA("Mic 1", JZ4760_CODEC_REG_PMR1, 463 REG_PMR1_SB_MIC1_OFFSET, 1, NULL, 0), 464 465 SND_SOC_DAPM_PGA("Mic 2", JZ4760_CODEC_REG_PMR1, 466 REG_PMR1_SB_MIC2_OFFSET, 1, NULL, 0), 467 468 SND_SOC_DAPM_PGA("Mic Diff", JZ4760_CODEC_REG_CR3, 469 REG_CR3_MICDIFF_OFFSET, 0, NULL, 0), 470 471 SND_SOC_DAPM_MIXER("Mic", SND_SOC_NOPM, 0, 0, 472 jz4760_codec_mic_controls, 473 ARRAY_SIZE(jz4760_codec_mic_controls)), 474 475 SND_SOC_DAPM_PGA("Line In Bypass", JZ4760_CODEC_REG_PMR1, 476 REG_PMR1_SB_BYPASS_OFFSET, 1, NULL, 0), 477 478 SND_SOC_DAPM_ADC("ADC", "Capture", JZ4760_CODEC_REG_PMR2, 479 REG_PMR2_SB_ADC_OFFSET, 1), 480 481 SND_SOC_DAPM_DAC("DAC", "Playback", JZ4760_CODEC_REG_PMR2, 482 REG_PMR2_SB_DAC_OFFSET, 1), 483 484 SND_SOC_DAPM_MIXER("PCM Playback", SND_SOC_NOPM, 0, 0, 485 jz4760_codec_pcm_playback_controls, 486 ARRAY_SIZE(jz4760_codec_pcm_playback_controls)), 487 488 SND_SOC_DAPM_MIXER("Headphones Playback", SND_SOC_NOPM, 0, 0, 489 jz4760_codec_hp_playback_controls, 490 ARRAY_SIZE(jz4760_codec_hp_playback_controls)), 491 492 SND_SOC_DAPM_SUPPLY("MICBIAS", JZ4760_CODEC_REG_PMR1, 493 REG_PMR1_SB_MICBIAS_OFFSET, 1, NULL, 0), 494 495 SND_SOC_DAPM_INPUT("MIC1P"), 496 SND_SOC_DAPM_INPUT("MIC1N"), 497 SND_SOC_DAPM_INPUT("MIC2P"), 498 SND_SOC_DAPM_INPUT("MIC2N"), 499 500 SND_SOC_DAPM_INPUT("LLINEIN"), 501 SND_SOC_DAPM_INPUT("RLINEIN"), 502 503 SND_SOC_DAPM_OUTPUT("LHPOUT"), 504 SND_SOC_DAPM_OUTPUT("RHPOUT"), 505 506 SND_SOC_DAPM_OUTPUT("LOUT"), 507 SND_SOC_DAPM_OUTPUT("ROUT"), 508 509 SND_SOC_DAPM_OUTPUT("BTLP"), 510 SND_SOC_DAPM_OUTPUT("BTLN"), 511 512 SND_SOC_DAPM_OUTPUT("SYSCLK"), 513 }; 514 515 /* Unconditional routes. */ 516 static const struct snd_soc_dapm_route jz4760_codec_dapm_routes[] = { 517 { "Mic 1", NULL, "MIC1P" }, 518 { "Mic Diff", NULL, "MIC1N" }, 519 { "Mic 1", NULL, "Mic Diff" }, 520 { "Mic 2", NULL, "MIC2P" }, 521 { "Mic Diff", NULL, "MIC2N" }, 522 { "Mic 2", NULL, "Mic Diff" }, 523 524 { "Line In", NULL, "LLINEIN" }, 525 { "Line In", NULL, "RLINEIN" }, 526 527 { "Mic", "Stereo Capture Switch", "Mic 1" }, 528 { "Mic", "Stereo Capture Switch", "Mic 2" }, 529 { "Headphones Source", "Mic 1", "Mic" }, 530 { "Headphones Source", "Mic 2", "Mic" }, 531 { "Capture Source", "Mic 1", "Mic" }, 532 { "Capture Source", "Mic 2", "Mic" }, 533 534 { "Capture Source", "Line In", "Line In" }, 535 { "Capture Source", "Mic 1", "Mic 1" }, 536 { "Capture Source", "Mic 2", "Mic 2" }, 537 { "ADC", NULL, "Capture Source" }, 538 539 { "Line In Bypass", NULL, "Line In" }, 540 541 { "Headphones Source", "Mic 1", "Mic 1" }, 542 { "Headphones Source", "Mic 2", "Mic 2" }, 543 { "Headphones Source", "Line In", "Line In Bypass" }, 544 { "Headphones Source", "PCM", "Headphones Playback" }, 545 { "HP Out", NULL, "Headphones Source" }, 546 547 { "LHPOUT", NULL, "HP Out" }, 548 { "RHPOUT", NULL, "HP Out" }, 549 { "Line Out", "Switch", "HP Out" }, 550 551 { "LOUT", NULL, "Line Out" }, 552 { "ROUT", NULL, "Line Out" }, 553 { "BTL Out", "Switch", "Line Out" }, 554 555 { "BTLP", NULL, "BTL Out"}, 556 { "BTLN", NULL, "BTL Out"}, 557 558 { "PCM Playback", "Volume", "DAC" }, 559 { "Headphones Playback", "Volume", "PCM Playback" }, 560 561 { "SYSCLK", NULL, "DAC" }, 562 }; 563 564 static void jz4760_codec_codec_init_regs(struct snd_soc_component *codec) 565 { 566 struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec); 567 struct regmap *regmap = jz_codec->regmap; 568 569 /* Collect updates for later sending. */ 570 regcache_cache_only(regmap, true); 571 572 /* default Amp output to PCM */ 573 regmap_set_bits(regmap, JZ4760_CODEC_REG_CR1, REG_CR1_OUTSEL_MASK); 574 575 /* Disable stereo mic */ 576 regmap_clear_bits(regmap, JZ4760_CODEC_REG_CR3, 577 BIT(REG_CR3_MICSTEREO_OFFSET)); 578 579 /* Set mic 1 as default source for ADC */ 580 regmap_clear_bits(regmap, JZ4760_CODEC_REG_CR3, 581 REG_CR3_ADC_INSEL_MASK); 582 583 /* ADC/DAC: serial + i2s */ 584 regmap_set_bits(regmap, JZ4760_CODEC_REG_AICR, 585 REG_AICR_ADC_SERIAL | REG_AICR_ADC_I2S | 586 REG_AICR_DAC_SERIAL | REG_AICR_DAC_I2S); 587 588 /* The generated IRQ is a high level */ 589 regmap_clear_bits(regmap, JZ4760_CODEC_REG_ICR, REG_ICR_INT_FORM_MASK); 590 regmap_update_bits(regmap, JZ4760_CODEC_REG_ICR, REG_ICR_ALL_MASK, 591 REG_ICR_JACK_MASK | REG_ICR_RUP_MASK | 592 REG_ICR_RDO_MASK | REG_ICR_GUP_MASK | 593 REG_ICR_GDO_MASK); 594 595 /* 12M oscillator */ 596 regmap_clear_bits(regmap, JZ4760_CODEC_REG_CCR1, REG_CCR1_CRYSTAL_MASK); 597 598 /* 0: 16ohm/220uF, 1: 10kohm/1uF */ 599 regmap_clear_bits(regmap, JZ4760_CODEC_REG_CR1, REG_CR1_HP_LOAD); 600 601 /* default to NOMAD */ 602 regmap_set_bits(jz_codec->regmap, JZ4760_CODEC_REG_CR2, 603 REG_CR2_DAC_NOMAD); 604 605 /* disable automatic gain */ 606 regmap_clear_bits(regmap, JZ4760_CODEC_REG_AGC1, REG_AGC1_EN); 607 608 /* Independent L/R DAC gain control */ 609 regmap_clear_bits(regmap, JZ4760_CODEC_REG_GCR5, 610 REG_GCR_RL); 611 612 /* Send collected updates. */ 613 regcache_cache_only(regmap, false); 614 regcache_sync(regmap); 615 } 616 617 static int jz4760_codec_codec_probe(struct snd_soc_component *codec) 618 { 619 struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec); 620 621 clk_prepare_enable(jz_codec->clk); 622 623 jz4760_codec_codec_init_regs(codec); 624 625 return 0; 626 } 627 628 static void jz4760_codec_codec_remove(struct snd_soc_component *codec) 629 { 630 struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec); 631 632 clk_disable_unprepare(jz_codec->clk); 633 } 634 635 static const struct snd_soc_component_driver jz4760_codec_soc_codec_dev = { 636 .probe = jz4760_codec_codec_probe, 637 .remove = jz4760_codec_codec_remove, 638 .set_bias_level = jz4760_codec_set_bias_level, 639 .controls = jz4760_codec_snd_controls, 640 .num_controls = ARRAY_SIZE(jz4760_codec_snd_controls), 641 .dapm_widgets = jz4760_codec_dapm_widgets, 642 .num_dapm_widgets = ARRAY_SIZE(jz4760_codec_dapm_widgets), 643 .dapm_routes = jz4760_codec_dapm_routes, 644 .num_dapm_routes = ARRAY_SIZE(jz4760_codec_dapm_routes), 645 .suspend_bias_off = 1, 646 .use_pmdown_time = 1, 647 }; 648 649 static const unsigned int jz4760_codec_sample_rates[] = { 650 96000, 48000, 44100, 32000, 651 24000, 22050, 16000, 12000, 652 11025, 9600, 8000, 653 }; 654 655 static int jz4760_codec_hw_params(struct snd_pcm_substream *substream, 656 struct snd_pcm_hw_params *params, 657 struct snd_soc_dai *dai) 658 { 659 struct jz_codec *codec = snd_soc_component_get_drvdata(dai->component); 660 unsigned int rate, bit_width; 661 662 switch (params_format(params)) { 663 case SNDRV_PCM_FORMAT_S16_LE: 664 bit_width = 0; 665 break; 666 case SNDRV_PCM_FORMAT_S18_3LE: 667 bit_width = 1; 668 break; 669 case SNDRV_PCM_FORMAT_S20_3LE: 670 bit_width = 2; 671 break; 672 case SNDRV_PCM_FORMAT_S24_3LE: 673 bit_width = 3; 674 break; 675 default: 676 return -EINVAL; 677 } 678 679 for (rate = 0; rate < ARRAY_SIZE(jz4760_codec_sample_rates); rate++) { 680 if (jz4760_codec_sample_rates[rate] == params_rate(params)) 681 break; 682 } 683 684 if (rate == ARRAY_SIZE(jz4760_codec_sample_rates)) 685 return -EINVAL; 686 687 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 688 regmap_update_bits(codec->regmap, JZ4760_CODEC_REG_AICR, 689 REG_AICR_DAC_ADWL_MASK, 690 FIELD_PREP(REG_AICR_DAC_ADWL_MASK, bit_width)); 691 regmap_update_bits(codec->regmap, JZ4760_CODEC_REG_CCR2, 692 REG_CCR2_DAC_FREQ_MASK, 693 FIELD_PREP(REG_CCR2_DAC_FREQ_MASK, rate)); 694 } else { 695 regmap_update_bits(codec->regmap, JZ4760_CODEC_REG_AICR, 696 REG_AICR_ADC_ADWL_MASK, 697 FIELD_PREP(REG_AICR_ADC_ADWL_MASK, bit_width)); 698 regmap_update_bits(codec->regmap, JZ4760_CODEC_REG_CCR2, 699 REG_CCR2_ADC_FREQ_MASK, 700 FIELD_PREP(REG_CCR2_ADC_FREQ_MASK, rate)); 701 } 702 703 return 0; 704 } 705 706 static const struct snd_soc_dai_ops jz4760_codec_dai_ops = { 707 .startup = jz4760_codec_startup, 708 .shutdown = jz4760_codec_shutdown, 709 .hw_params = jz4760_codec_hw_params, 710 .trigger = jz4760_codec_pcm_trigger, 711 .mute_stream = jz4760_codec_mute_stream, 712 .no_capture_mute = 1, 713 }; 714 715 #define JZ_CODEC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ 716 SNDRV_PCM_FMTBIT_S18_3LE | \ 717 SNDRV_PCM_FMTBIT_S20_3LE | \ 718 SNDRV_PCM_FMTBIT_S24_3LE) 719 720 static struct snd_soc_dai_driver jz4760_codec_dai = { 721 .name = "jz4760-hifi", 722 .playback = { 723 .stream_name = "Playback", 724 .channels_min = 2, 725 .channels_max = 2, 726 .rates = SNDRV_PCM_RATE_8000_96000, 727 .formats = JZ_CODEC_FORMATS, 728 }, 729 .capture = { 730 .stream_name = "Capture", 731 .channels_min = 2, 732 .channels_max = 2, 733 .rates = SNDRV_PCM_RATE_8000_96000, 734 .formats = JZ_CODEC_FORMATS, 735 }, 736 .ops = &jz4760_codec_dai_ops, 737 }; 738 739 static bool jz4760_codec_volatile(struct device *dev, unsigned int reg) 740 { 741 return reg == JZ4760_CODEC_REG_SR || reg == JZ4760_CODEC_REG_IFR; 742 } 743 744 static bool jz4760_codec_writeable(struct device *dev, unsigned int reg) 745 { 746 switch (reg) { 747 case JZ4760_CODEC_REG_SR: 748 return false; 749 default: 750 return true; 751 } 752 } 753 754 static int jz4760_codec_io_wait(struct jz_codec *codec) 755 { 756 u32 reg; 757 758 return readl_poll_timeout(codec->base + ICDC_RGADW_OFFSET, reg, 759 !(reg & ICDC_RGADW_RGWR), 760 1000, 1 * USEC_PER_SEC); 761 } 762 763 static int jz4760_codec_reg_read(void *context, unsigned int reg, 764 unsigned int *val) 765 { 766 struct jz_codec *codec = context; 767 unsigned int i; 768 u32 tmp; 769 int ret; 770 771 ret = jz4760_codec_io_wait(codec); 772 if (ret) 773 return ret; 774 775 tmp = readl(codec->base + ICDC_RGADW_OFFSET); 776 tmp &= ~ICDC_RGADW_RGADDR_MASK; 777 tmp |= FIELD_PREP(ICDC_RGADW_RGADDR_MASK, reg); 778 writel(tmp, codec->base + ICDC_RGADW_OFFSET); 779 780 /* wait 6+ cycles */ 781 for (i = 0; i < 6; i++) 782 *val = readl(codec->base + ICDC_RGDATA_OFFSET) & 783 ICDC_RGDATA_RGDOUT_MASK; 784 785 return 0; 786 } 787 788 static int jz4760_codec_reg_write(void *context, unsigned int reg, 789 unsigned int val) 790 { 791 struct jz_codec *codec = context; 792 int ret; 793 794 ret = jz4760_codec_io_wait(codec); 795 if (ret) 796 return ret; 797 798 writel(ICDC_RGADW_RGWR | FIELD_PREP(ICDC_RGADW_RGADDR_MASK, reg) | val, 799 codec->base + ICDC_RGADW_OFFSET); 800 801 ret = jz4760_codec_io_wait(codec); 802 if (ret) 803 return ret; 804 805 return 0; 806 } 807 808 static const u8 jz4760_codec_reg_defaults[] = { 809 0x00, 0xFC, 0x1B, 0x20, 0x00, 0x80, 0x00, 0x00, 810 0xFF, 0x1F, 0x3F, 0x00, 0x06, 0x06, 0x06, 0x06, 811 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x07, 0x44, 812 0x1F, 0x00, 0x00, 0x00 813 }; 814 815 static struct regmap_config jz4760_codec_regmap_config = { 816 .reg_bits = 7, 817 .val_bits = 8, 818 819 .max_register = JZ4760_CODEC_REG_MIX2, 820 .volatile_reg = jz4760_codec_volatile, 821 .writeable_reg = jz4760_codec_writeable, 822 823 .reg_read = jz4760_codec_reg_read, 824 .reg_write = jz4760_codec_reg_write, 825 826 .reg_defaults_raw = jz4760_codec_reg_defaults, 827 .num_reg_defaults_raw = ARRAY_SIZE(jz4760_codec_reg_defaults), 828 .cache_type = REGCACHE_FLAT, 829 }; 830 831 static int jz4760_codec_probe(struct platform_device *pdev) 832 { 833 struct device *dev = &pdev->dev; 834 struct jz_codec *codec; 835 int ret; 836 837 codec = devm_kzalloc(dev, sizeof(*codec), GFP_KERNEL); 838 if (!codec) 839 return -ENOMEM; 840 841 codec->dev = dev; 842 843 codec->base = devm_platform_ioremap_resource(pdev, 0); 844 if (IS_ERR(codec->base)) 845 return PTR_ERR(codec->base); 846 847 codec->regmap = devm_regmap_init(dev, NULL, codec, 848 &jz4760_codec_regmap_config); 849 if (IS_ERR(codec->regmap)) 850 return PTR_ERR(codec->regmap); 851 852 codec->clk = devm_clk_get(dev, "aic"); 853 if (IS_ERR(codec->clk)) 854 return PTR_ERR(codec->clk); 855 856 platform_set_drvdata(pdev, codec); 857 858 ret = devm_snd_soc_register_component(dev, &jz4760_codec_soc_codec_dev, 859 &jz4760_codec_dai, 1); 860 if (ret) { 861 dev_err(dev, "Failed to register codec: %d\n", ret); 862 return ret; 863 } 864 865 return 0; 866 } 867 868 static const struct of_device_id jz4760_codec_of_matches[] = { 869 { .compatible = "ingenic,jz4760-codec", }, 870 { /* sentinel */ } 871 }; 872 MODULE_DEVICE_TABLE(of, jz4760_codec_of_matches); 873 874 static struct platform_driver jz4760_codec_driver = { 875 .probe = jz4760_codec_probe, 876 .driver = { 877 .name = "jz4760-codec", 878 .of_match_table = jz4760_codec_of_matches, 879 }, 880 }; 881 module_platform_driver(jz4760_codec_driver); 882 883 MODULE_DESCRIPTION("JZ4760 SoC internal codec driver"); 884 MODULE_AUTHOR("Christophe Branchereau <cbranchereau@gmail.com>"); 885 MODULE_AUTHOR("Paul Cercueil <paul@crapouillou.net>"); 886 MODULE_LICENSE("GPL v2"); 887