0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/bitfield.h>
0009 #include <linux/clk.h>
0010 #include <linux/delay.h>
0011 #include <linux/iopoll.h>
0012 #include <linux/module.h>
0013 #include <linux/regmap.h>
0014 #include <linux/time64.h>
0015
0016 #include <sound/pcm_params.h>
0017 #include <sound/soc.h>
0018 #include <sound/soc-dai.h>
0019 #include <sound/soc-dapm.h>
0020 #include <sound/tlv.h>
0021
0022 #define ICDC_RGADW_OFFSET 0x00
0023 #define ICDC_RGDATA_OFFSET 0x04
0024
0025
0026 #define ICDC_RGADW_RGWR BIT(16)
0027 #define ICDC_RGADW_RGADDR_MASK GENMASK(14, 8)
0028 #define ICDC_RGADW_RGDIN_MASK GENMASK(7, 0)
0029
0030
0031 #define ICDC_RGDATA_IRQ BIT(8)
0032 #define ICDC_RGDATA_RGDOUT_MASK GENMASK(7, 0)
0033
0034
0035 enum {
0036 JZ4760_CODEC_REG_SR,
0037 JZ4760_CODEC_REG_AICR,
0038 JZ4760_CODEC_REG_CR1,
0039 JZ4760_CODEC_REG_CR2,
0040 JZ4760_CODEC_REG_CR3,
0041 JZ4760_CODEC_REG_CR4,
0042 JZ4760_CODEC_REG_CCR1,
0043 JZ4760_CODEC_REG_CCR2,
0044 JZ4760_CODEC_REG_PMR1,
0045 JZ4760_CODEC_REG_PMR2,
0046 JZ4760_CODEC_REG_ICR,
0047 JZ4760_CODEC_REG_IFR,
0048 JZ4760_CODEC_REG_GCR1,
0049 JZ4760_CODEC_REG_GCR2,
0050 JZ4760_CODEC_REG_GCR3,
0051 JZ4760_CODEC_REG_GCR4,
0052 JZ4760_CODEC_REG_GCR5,
0053 JZ4760_CODEC_REG_GCR6,
0054 JZ4760_CODEC_REG_GCR7,
0055 JZ4760_CODEC_REG_GCR8,
0056 JZ4760_CODEC_REG_GCR9,
0057 JZ4760_CODEC_REG_AGC1,
0058 JZ4760_CODEC_REG_AGC2,
0059 JZ4760_CODEC_REG_AGC3,
0060 JZ4760_CODEC_REG_AGC4,
0061 JZ4760_CODEC_REG_AGC5,
0062 JZ4760_CODEC_REG_MIX1,
0063 JZ4760_CODEC_REG_MIX2,
0064 };
0065
0066 #define REG_AICR_DAC_ADWL_MASK GENMASK(7, 6)
0067 #define REG_AICR_DAC_SERIAL BIT(3)
0068 #define REG_AICR_DAC_I2S BIT(1)
0069
0070 #define REG_AICR_ADC_ADWL_MASK GENMASK(5, 4)
0071
0072 #define REG_AICR_ADC_SERIAL BIT(2)
0073 #define REG_AICR_ADC_I2S BIT(0)
0074
0075 #define REG_CR1_HP_LOAD BIT(7)
0076 #define REG_CR1_HP_MUTE BIT(5)
0077 #define REG_CR1_LO_MUTE_OFFSET 4
0078 #define REG_CR1_BTL_MUTE_OFFSET 3
0079 #define REG_CR1_OUTSEL_OFFSET 0
0080 #define REG_CR1_OUTSEL_MASK GENMASK(1, REG_CR1_OUTSEL_OFFSET)
0081
0082 #define REG_CR2_DAC_MONO BIT(7)
0083 #define REG_CR2_DAC_MUTE BIT(5)
0084 #define REG_CR2_DAC_NOMAD BIT(1)
0085 #define REG_CR2_DAC_RIGHT_ONLY BIT(0)
0086
0087 #define REG_CR3_ADC_INSEL_OFFSET 2
0088 #define REG_CR3_ADC_INSEL_MASK GENMASK(3, REG_CR3_ADC_INSEL_OFFSET)
0089 #define REG_CR3_MICSTEREO_OFFSET 1
0090 #define REG_CR3_MICDIFF_OFFSET 0
0091
0092 #define REG_CR4_ADC_HPF_OFFSET 7
0093 #define REG_CR4_ADC_RIGHT_ONLY BIT(0)
0094
0095 #define REG_CCR1_CRYSTAL_MASK GENMASK(3, 0)
0096
0097 #define REG_CCR2_DAC_FREQ_MASK GENMASK(7, 4)
0098 #define REG_CCR2_ADC_FREQ_MASK GENMASK(3, 0)
0099
0100 #define REG_PMR1_SB BIT(7)
0101 #define REG_PMR1_SB_SLEEP BIT(6)
0102 #define REG_PMR1_SB_AIP_OFFSET 5
0103 #define REG_PMR1_SB_LINE_OFFSET 4
0104 #define REG_PMR1_SB_MIC1_OFFSET 3
0105 #define REG_PMR1_SB_MIC2_OFFSET 2
0106 #define REG_PMR1_SB_BYPASS_OFFSET 1
0107 #define REG_PMR1_SB_MICBIAS_OFFSET 0
0108
0109 #define REG_PMR2_SB_ADC_OFFSET 4
0110 #define REG_PMR2_SB_HP_OFFSET 3
0111 #define REG_PMR2_SB_BTL_OFFSET 2
0112 #define REG_PMR2_SB_LOUT_OFFSET 1
0113 #define REG_PMR2_SB_DAC_OFFSET 0
0114
0115 #define REG_ICR_INT_FORM_MASK GENMASK(7, 6)
0116 #define REG_ICR_ALL_MASK GENMASK(5, 0)
0117 #define REG_ICR_JACK_MASK BIT(5)
0118 #define REG_ICR_SCMC_MASK BIT(4)
0119 #define REG_ICR_RUP_MASK BIT(3)
0120 #define REG_ICR_RDO_MASK BIT(2)
0121 #define REG_ICR_GUP_MASK BIT(1)
0122 #define REG_ICR_GDO_MASK BIT(0)
0123
0124 #define REG_IFR_ALL_MASK GENMASK(5, 0)
0125 #define REG_IFR_JACK BIT(6)
0126 #define REG_IFR_JACK_EVENT BIT(5)
0127 #define REG_IFR_SCMC BIT(4)
0128 #define REG_IFR_RUP BIT(3)
0129 #define REG_IFR_RDO BIT(2)
0130 #define REG_IFR_GUP BIT(1)
0131 #define REG_IFR_GDO BIT(0)
0132
0133 #define REG_GCR_GAIN_OFFSET 0
0134 #define REG_GCR_GAIN_MAX 0x1f
0135
0136 #define REG_GCR_RL BIT(7)
0137
0138 #define REG_GCR_GIM1_MASK GENMASK(5, 3)
0139 #define REG_GCR_GIM2_MASK GENMASK(2, 0)
0140 #define REG_GCR_GIM_GAIN_MAX 7
0141
0142 #define REG_AGC1_EN BIT(7)
0143 #define REG_AGC1_TARGET_MASK GENMASK(5, 2)
0144
0145 #define REG_AGC2_NG_THR_MASK GENMASK(6, 4)
0146 #define REG_AGC2_HOLD_MASK GENMASK(3, 0)
0147
0148 #define REG_AGC3_ATK_MASK GENMASK(7, 4)
0149 #define REG_AGC3_DCY_MASK GENMASK(3, 0)
0150
0151 #define REG_AGC4_AGC_MAX_MASK GENMASK(4, 0)
0152
0153 #define REG_AGC5_AGC_MIN_MASK GENMASK(4, 0)
0154
0155 #define REG_MIX1_MIX_REC_MASK GENMASK(7, 6)
0156 #define REG_MIX1_GIMIX_MASK GENMASK(4, 0)
0157
0158 #define REG_MIX2_DAC_MIX_MASK GENMASK(7, 6)
0159 #define REG_MIX2_GOMIX_MASK GENMASK(4, 0)
0160
0161
0162 struct jz_codec {
0163 struct device *dev;
0164 struct regmap *regmap;
0165 void __iomem *base;
0166 struct clk *clk;
0167 };
0168
0169 static int jz4760_codec_set_bias_level(struct snd_soc_component *codec,
0170 enum snd_soc_bias_level level)
0171 {
0172 struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec);
0173 struct regmap *regmap = jz_codec->regmap;
0174
0175 switch (level) {
0176 case SND_SOC_BIAS_PREPARE:
0177
0178 regmap_write(regmap, JZ4760_CODEC_REG_IFR, REG_IFR_ALL_MASK);
0179
0180 regmap_clear_bits(regmap, JZ4760_CODEC_REG_PMR1, REG_PMR1_SB);
0181 msleep(250);
0182 regmap_clear_bits(regmap, JZ4760_CODEC_REG_PMR1, REG_PMR1_SB_SLEEP);
0183 msleep(400);
0184 break;
0185 case SND_SOC_BIAS_STANDBY:
0186 regmap_set_bits(regmap, JZ4760_CODEC_REG_PMR1, REG_PMR1_SB_SLEEP);
0187 regmap_set_bits(regmap, JZ4760_CODEC_REG_PMR1, REG_PMR1_SB);
0188 break;
0189 default:
0190 break;
0191 }
0192
0193 return 0;
0194 }
0195
0196 static int jz4760_codec_startup(struct snd_pcm_substream *substream,
0197 struct snd_soc_dai *dai)
0198 {
0199 struct snd_soc_component *codec = dai->component;
0200 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(codec);
0201 int ret = 0;
0202
0203
0204
0205
0206
0207
0208 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
0209 ret = snd_soc_dapm_force_enable_pin(dapm, "SYSCLK");
0210 return ret;
0211 }
0212
0213 static void jz4760_codec_shutdown(struct snd_pcm_substream *substream,
0214 struct snd_soc_dai *dai)
0215 {
0216 struct snd_soc_component *codec = dai->component;
0217 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(codec);
0218
0219 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
0220 snd_soc_dapm_disable_pin(dapm, "SYSCLK");
0221 }
0222
0223
0224 static int jz4760_codec_pcm_trigger(struct snd_pcm_substream *substream,
0225 int cmd, struct snd_soc_dai *dai)
0226 {
0227 struct snd_soc_component *codec = dai->component;
0228 int ret = 0;
0229
0230 switch (cmd) {
0231 case SNDRV_PCM_TRIGGER_START:
0232 case SNDRV_PCM_TRIGGER_RESUME:
0233 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
0234 if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
0235 snd_soc_component_force_bias_level(codec, SND_SOC_BIAS_ON);
0236 break;
0237 case SNDRV_PCM_TRIGGER_STOP:
0238 case SNDRV_PCM_TRIGGER_SUSPEND:
0239 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
0240
0241 break;
0242 default:
0243 ret = -EINVAL;
0244 }
0245
0246 return ret;
0247 }
0248
0249 static int jz4760_codec_mute_stream(struct snd_soc_dai *dai, int mute, int direction)
0250 {
0251 struct snd_soc_component *codec = dai->component;
0252 struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec);
0253 unsigned int gain_bit = mute ? REG_IFR_GDO : REG_IFR_GUP;
0254 unsigned int val, reg;
0255 int change, err;
0256
0257 change = snd_soc_component_update_bits(codec, JZ4760_CODEC_REG_CR2,
0258 REG_CR2_DAC_MUTE,
0259 mute ? REG_CR2_DAC_MUTE : 0);
0260 if (change == 1) {
0261 regmap_read(jz_codec->regmap, JZ4760_CODEC_REG_PMR2, &val);
0262
0263 if (val & BIT(REG_PMR2_SB_DAC_OFFSET))
0264 return 1;
0265
0266 err = regmap_read_poll_timeout(jz_codec->regmap,
0267 JZ4760_CODEC_REG_IFR,
0268 val, val & gain_bit,
0269 1000, 1 * USEC_PER_SEC);
0270 if (err) {
0271 dev_err(jz_codec->dev,
0272 "Timeout while setting digital mute: %d", err);
0273 return err;
0274 }
0275
0276
0277 regmap_write(jz_codec->regmap, JZ4760_CODEC_REG_IFR, gain_bit);
0278 }
0279
0280 regmap_read(jz_codec->regmap, JZ4760_CODEC_REG_CR2, ®);
0281
0282 return 0;
0283 }
0284
0285
0286 static const DECLARE_TLV_DB_MINMAX_MUTE(dac_tlv, -3100, 100);
0287 static const DECLARE_TLV_DB_SCALE(adc_tlv, 0, 100, 0);
0288 static const DECLARE_TLV_DB_MINMAX(out_tlv, -2500, 100);
0289 static const DECLARE_TLV_DB_SCALE(linein_tlv, -2500, 100, 0);
0290
0291
0292 static const struct snd_kcontrol_new jz4760_codec_snd_controls[] = {
0293
0294 SOC_DOUBLE_R_TLV("PCM Capture Volume",
0295 JZ4760_CODEC_REG_GCR9, JZ4760_CODEC_REG_GCR8,
0296 REG_GCR_GAIN_OFFSET, REG_GCR_GAIN_MAX, 0, adc_tlv),
0297
0298 SOC_DOUBLE_R_TLV("Line In Bypass Playback Volume",
0299 JZ4760_CODEC_REG_GCR4, JZ4760_CODEC_REG_GCR3,
0300 REG_GCR_GAIN_OFFSET, REG_GCR_GAIN_MAX, 1, linein_tlv),
0301
0302 SOC_SINGLE("High-Pass Filter Capture Switch",
0303 JZ4760_CODEC_REG_CR4,
0304 REG_CR4_ADC_HPF_OFFSET, 1, 0),
0305 };
0306
0307 static const struct snd_kcontrol_new jz4760_codec_pcm_playback_controls[] = {
0308 {
0309 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0310 .name = "Volume",
0311 .info = snd_soc_info_volsw,
0312 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ
0313 | SNDRV_CTL_ELEM_ACCESS_READWRITE,
0314 .tlv.p = dac_tlv,
0315 .get = snd_soc_dapm_get_volsw,
0316 .put = snd_soc_dapm_put_volsw,
0317 .private_value = SOC_DOUBLE_R_VALUE(JZ4760_CODEC_REG_GCR6,
0318 JZ4760_CODEC_REG_GCR5,
0319 REG_GCR_GAIN_OFFSET,
0320 REG_GCR_GAIN_MAX, 1),
0321 },
0322 };
0323
0324 static const struct snd_kcontrol_new jz4760_codec_hp_playback_controls[] = {
0325 {
0326 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0327 .name = "Volume",
0328 .info = snd_soc_info_volsw,
0329 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ
0330 | SNDRV_CTL_ELEM_ACCESS_READWRITE,
0331 .tlv.p = out_tlv,
0332 .get = snd_soc_dapm_get_volsw,
0333 .put = snd_soc_dapm_put_volsw,
0334 .private_value = SOC_DOUBLE_R_VALUE(JZ4760_CODEC_REG_GCR2,
0335 JZ4760_CODEC_REG_GCR1,
0336 REG_GCR_GAIN_OFFSET,
0337 REG_GCR_GAIN_MAX, 1),
0338 },
0339 };
0340
0341 static int hpout_event(struct snd_soc_dapm_widget *w,
0342 struct snd_kcontrol *kcontrol, int event)
0343 {
0344 struct snd_soc_component *codec = snd_soc_dapm_to_component(w->dapm);
0345 struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec);
0346 unsigned int val;
0347 int err;
0348
0349 switch (event) {
0350 case SND_SOC_DAPM_PRE_PMU:
0351
0352 regmap_clear_bits(jz_codec->regmap, JZ4760_CODEC_REG_CR1,
0353 REG_CR1_HP_MUTE);
0354 break;
0355
0356 case SND_SOC_DAPM_POST_PMU:
0357
0358 err = regmap_read_poll_timeout(jz_codec->regmap,
0359 JZ4760_CODEC_REG_IFR,
0360 val, val & REG_IFR_RUP,
0361 1000, 1 * USEC_PER_SEC);
0362 if (err) {
0363 dev_err(jz_codec->dev, "RUP timeout: %d", err);
0364 return err;
0365 }
0366
0367
0368 regmap_set_bits(jz_codec->regmap, JZ4760_CODEC_REG_IFR,
0369 REG_IFR_RUP);
0370
0371 break;
0372
0373 case SND_SOC_DAPM_POST_PMD:
0374
0375 regmap_set_bits(jz_codec->regmap, JZ4760_CODEC_REG_CR1,
0376 REG_CR1_HP_MUTE);
0377
0378 err = regmap_read_poll_timeout(jz_codec->regmap,
0379 JZ4760_CODEC_REG_IFR,
0380 val, val & REG_IFR_RDO,
0381 1000, 1 * USEC_PER_SEC);
0382 if (err) {
0383 dev_err(jz_codec->dev, "RDO timeout: %d", err);
0384 return err;
0385 }
0386
0387
0388 regmap_set_bits(jz_codec->regmap, JZ4760_CODEC_REG_IFR,
0389 REG_IFR_RDO);
0390
0391 break;
0392 }
0393
0394 return 0;
0395 }
0396
0397 static const char * const jz4760_codec_hp_texts[] = {
0398 "PCM", "Line In", "Mic 1", "Mic 2"
0399 };
0400
0401 static const unsigned int jz4760_codec_hp_values[] = { 3, 2, 0, 1 };
0402
0403 static SOC_VALUE_ENUM_SINGLE_DECL(jz4760_codec_hp_enum,
0404 JZ4760_CODEC_REG_CR1,
0405 REG_CR1_OUTSEL_OFFSET,
0406 REG_CR1_OUTSEL_MASK >> REG_CR1_OUTSEL_OFFSET,
0407 jz4760_codec_hp_texts,
0408 jz4760_codec_hp_values);
0409 static const struct snd_kcontrol_new jz4760_codec_hp_source =
0410 SOC_DAPM_ENUM("Route", jz4760_codec_hp_enum);
0411
0412 static const char * const jz4760_codec_cap_texts[] = {
0413 "Line In", "Mic 1", "Mic 2"
0414 };
0415
0416 static const unsigned int jz4760_codec_cap_values[] = { 2, 0, 1 };
0417
0418 static SOC_VALUE_ENUM_SINGLE_DECL(jz4760_codec_cap_enum,
0419 JZ4760_CODEC_REG_CR3,
0420 REG_CR3_ADC_INSEL_OFFSET,
0421 REG_CR3_ADC_INSEL_MASK >> REG_CR3_ADC_INSEL_OFFSET,
0422 jz4760_codec_cap_texts,
0423 jz4760_codec_cap_values);
0424 static const struct snd_kcontrol_new jz4760_codec_cap_source =
0425 SOC_DAPM_ENUM("Route", jz4760_codec_cap_enum);
0426
0427 static const struct snd_kcontrol_new jz4760_codec_mic_controls[] = {
0428 SOC_DAPM_SINGLE("Stereo Capture Switch", JZ4760_CODEC_REG_CR3,
0429 REG_CR3_MICSTEREO_OFFSET, 1, 0),
0430 };
0431
0432 static const struct snd_kcontrol_new jz4760_codec_line_out_switch =
0433 SOC_DAPM_SINGLE("Switch", JZ4760_CODEC_REG_CR1,
0434 REG_CR1_LO_MUTE_OFFSET, 0, 0);
0435 static const struct snd_kcontrol_new jz4760_codec_btl_out_switch =
0436 SOC_DAPM_SINGLE("Switch", JZ4760_CODEC_REG_CR1,
0437 REG_CR1_BTL_MUTE_OFFSET, 0, 0);
0438
0439 static const struct snd_soc_dapm_widget jz4760_codec_dapm_widgets[] = {
0440 SND_SOC_DAPM_PGA_E("HP Out", JZ4760_CODEC_REG_PMR2,
0441 REG_PMR2_SB_HP_OFFSET, 1, NULL, 0, hpout_event,
0442 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
0443 SND_SOC_DAPM_POST_PMD),
0444
0445 SND_SOC_DAPM_SWITCH("Line Out", JZ4760_CODEC_REG_PMR2,
0446 REG_PMR2_SB_LOUT_OFFSET, 1,
0447 &jz4760_codec_line_out_switch),
0448
0449 SND_SOC_DAPM_SWITCH("BTL Out", JZ4760_CODEC_REG_PMR2,
0450 REG_PMR2_SB_BTL_OFFSET, 1,
0451 &jz4760_codec_btl_out_switch),
0452
0453 SND_SOC_DAPM_PGA("Line In", JZ4760_CODEC_REG_PMR1,
0454 REG_PMR1_SB_LINE_OFFSET, 1, NULL, 0),
0455
0456 SND_SOC_DAPM_MUX("Headphones Source", SND_SOC_NOPM, 0, 0,
0457 &jz4760_codec_hp_source),
0458
0459 SND_SOC_DAPM_MUX("Capture Source", SND_SOC_NOPM, 0, 0,
0460 &jz4760_codec_cap_source),
0461
0462 SND_SOC_DAPM_PGA("Mic 1", JZ4760_CODEC_REG_PMR1,
0463 REG_PMR1_SB_MIC1_OFFSET, 1, NULL, 0),
0464
0465 SND_SOC_DAPM_PGA("Mic 2", JZ4760_CODEC_REG_PMR1,
0466 REG_PMR1_SB_MIC2_OFFSET, 1, NULL, 0),
0467
0468 SND_SOC_DAPM_PGA("Mic Diff", JZ4760_CODEC_REG_CR3,
0469 REG_CR3_MICDIFF_OFFSET, 0, NULL, 0),
0470
0471 SND_SOC_DAPM_MIXER("Mic", SND_SOC_NOPM, 0, 0,
0472 jz4760_codec_mic_controls,
0473 ARRAY_SIZE(jz4760_codec_mic_controls)),
0474
0475 SND_SOC_DAPM_PGA("Line In Bypass", JZ4760_CODEC_REG_PMR1,
0476 REG_PMR1_SB_BYPASS_OFFSET, 1, NULL, 0),
0477
0478 SND_SOC_DAPM_ADC("ADC", "Capture", JZ4760_CODEC_REG_PMR2,
0479 REG_PMR2_SB_ADC_OFFSET, 1),
0480
0481 SND_SOC_DAPM_DAC("DAC", "Playback", JZ4760_CODEC_REG_PMR2,
0482 REG_PMR2_SB_DAC_OFFSET, 1),
0483
0484 SND_SOC_DAPM_MIXER("PCM Playback", SND_SOC_NOPM, 0, 0,
0485 jz4760_codec_pcm_playback_controls,
0486 ARRAY_SIZE(jz4760_codec_pcm_playback_controls)),
0487
0488 SND_SOC_DAPM_MIXER("Headphones Playback", SND_SOC_NOPM, 0, 0,
0489 jz4760_codec_hp_playback_controls,
0490 ARRAY_SIZE(jz4760_codec_hp_playback_controls)),
0491
0492 SND_SOC_DAPM_SUPPLY("MICBIAS", JZ4760_CODEC_REG_PMR1,
0493 REG_PMR1_SB_MICBIAS_OFFSET, 1, NULL, 0),
0494
0495 SND_SOC_DAPM_INPUT("MIC1P"),
0496 SND_SOC_DAPM_INPUT("MIC1N"),
0497 SND_SOC_DAPM_INPUT("MIC2P"),
0498 SND_SOC_DAPM_INPUT("MIC2N"),
0499
0500 SND_SOC_DAPM_INPUT("LLINEIN"),
0501 SND_SOC_DAPM_INPUT("RLINEIN"),
0502
0503 SND_SOC_DAPM_OUTPUT("LHPOUT"),
0504 SND_SOC_DAPM_OUTPUT("RHPOUT"),
0505
0506 SND_SOC_DAPM_OUTPUT("LOUT"),
0507 SND_SOC_DAPM_OUTPUT("ROUT"),
0508
0509 SND_SOC_DAPM_OUTPUT("BTLP"),
0510 SND_SOC_DAPM_OUTPUT("BTLN"),
0511
0512 SND_SOC_DAPM_OUTPUT("SYSCLK"),
0513 };
0514
0515
0516 static const struct snd_soc_dapm_route jz4760_codec_dapm_routes[] = {
0517 { "Mic 1", NULL, "MIC1P" },
0518 { "Mic Diff", NULL, "MIC1N" },
0519 { "Mic 1", NULL, "Mic Diff" },
0520 { "Mic 2", NULL, "MIC2P" },
0521 { "Mic Diff", NULL, "MIC2N" },
0522 { "Mic 2", NULL, "Mic Diff" },
0523
0524 { "Line In", NULL, "LLINEIN" },
0525 { "Line In", NULL, "RLINEIN" },
0526
0527 { "Mic", "Stereo Capture Switch", "Mic 1" },
0528 { "Mic", "Stereo Capture Switch", "Mic 2" },
0529 { "Headphones Source", "Mic 1", "Mic" },
0530 { "Headphones Source", "Mic 2", "Mic" },
0531 { "Capture Source", "Mic 1", "Mic" },
0532 { "Capture Source", "Mic 2", "Mic" },
0533
0534 { "Capture Source", "Line In", "Line In" },
0535 { "Capture Source", "Mic 1", "Mic 1" },
0536 { "Capture Source", "Mic 2", "Mic 2" },
0537 { "ADC", NULL, "Capture Source" },
0538
0539 { "Line In Bypass", NULL, "Line In" },
0540
0541 { "Headphones Source", "Mic 1", "Mic 1" },
0542 { "Headphones Source", "Mic 2", "Mic 2" },
0543 { "Headphones Source", "Line In", "Line In Bypass" },
0544 { "Headphones Source", "PCM", "Headphones Playback" },
0545 { "HP Out", NULL, "Headphones Source" },
0546
0547 { "LHPOUT", NULL, "HP Out" },
0548 { "RHPOUT", NULL, "HP Out" },
0549 { "Line Out", "Switch", "HP Out" },
0550
0551 { "LOUT", NULL, "Line Out" },
0552 { "ROUT", NULL, "Line Out" },
0553 { "BTL Out", "Switch", "Line Out" },
0554
0555 { "BTLP", NULL, "BTL Out"},
0556 { "BTLN", NULL, "BTL Out"},
0557
0558 { "PCM Playback", "Volume", "DAC" },
0559 { "Headphones Playback", "Volume", "PCM Playback" },
0560
0561 { "SYSCLK", NULL, "DAC" },
0562 };
0563
0564 static void jz4760_codec_codec_init_regs(struct snd_soc_component *codec)
0565 {
0566 struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec);
0567 struct regmap *regmap = jz_codec->regmap;
0568
0569
0570 regcache_cache_only(regmap, true);
0571
0572
0573 regmap_set_bits(regmap, JZ4760_CODEC_REG_CR1, REG_CR1_OUTSEL_MASK);
0574
0575
0576 regmap_clear_bits(regmap, JZ4760_CODEC_REG_CR3,
0577 BIT(REG_CR3_MICSTEREO_OFFSET));
0578
0579
0580 regmap_clear_bits(regmap, JZ4760_CODEC_REG_CR3,
0581 REG_CR3_ADC_INSEL_MASK);
0582
0583
0584 regmap_set_bits(regmap, JZ4760_CODEC_REG_AICR,
0585 REG_AICR_ADC_SERIAL | REG_AICR_ADC_I2S |
0586 REG_AICR_DAC_SERIAL | REG_AICR_DAC_I2S);
0587
0588
0589 regmap_clear_bits(regmap, JZ4760_CODEC_REG_ICR, REG_ICR_INT_FORM_MASK);
0590 regmap_update_bits(regmap, JZ4760_CODEC_REG_ICR, REG_ICR_ALL_MASK,
0591 REG_ICR_JACK_MASK | REG_ICR_RUP_MASK |
0592 REG_ICR_RDO_MASK | REG_ICR_GUP_MASK |
0593 REG_ICR_GDO_MASK);
0594
0595
0596 regmap_clear_bits(regmap, JZ4760_CODEC_REG_CCR1, REG_CCR1_CRYSTAL_MASK);
0597
0598
0599 regmap_clear_bits(regmap, JZ4760_CODEC_REG_CR1, REG_CR1_HP_LOAD);
0600
0601
0602 regmap_set_bits(jz_codec->regmap, JZ4760_CODEC_REG_CR2,
0603 REG_CR2_DAC_NOMAD);
0604
0605
0606 regmap_clear_bits(regmap, JZ4760_CODEC_REG_AGC1, REG_AGC1_EN);
0607
0608
0609 regmap_clear_bits(regmap, JZ4760_CODEC_REG_GCR5,
0610 REG_GCR_RL);
0611
0612
0613 regcache_cache_only(regmap, false);
0614 regcache_sync(regmap);
0615 }
0616
0617 static int jz4760_codec_codec_probe(struct snd_soc_component *codec)
0618 {
0619 struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec);
0620
0621 clk_prepare_enable(jz_codec->clk);
0622
0623 jz4760_codec_codec_init_regs(codec);
0624
0625 return 0;
0626 }
0627
0628 static void jz4760_codec_codec_remove(struct snd_soc_component *codec)
0629 {
0630 struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec);
0631
0632 clk_disable_unprepare(jz_codec->clk);
0633 }
0634
0635 static const struct snd_soc_component_driver jz4760_codec_soc_codec_dev = {
0636 .probe = jz4760_codec_codec_probe,
0637 .remove = jz4760_codec_codec_remove,
0638 .set_bias_level = jz4760_codec_set_bias_level,
0639 .controls = jz4760_codec_snd_controls,
0640 .num_controls = ARRAY_SIZE(jz4760_codec_snd_controls),
0641 .dapm_widgets = jz4760_codec_dapm_widgets,
0642 .num_dapm_widgets = ARRAY_SIZE(jz4760_codec_dapm_widgets),
0643 .dapm_routes = jz4760_codec_dapm_routes,
0644 .num_dapm_routes = ARRAY_SIZE(jz4760_codec_dapm_routes),
0645 .suspend_bias_off = 1,
0646 .use_pmdown_time = 1,
0647 };
0648
0649 static const unsigned int jz4760_codec_sample_rates[] = {
0650 96000, 48000, 44100, 32000,
0651 24000, 22050, 16000, 12000,
0652 11025, 9600, 8000,
0653 };
0654
0655 static int jz4760_codec_hw_params(struct snd_pcm_substream *substream,
0656 struct snd_pcm_hw_params *params,
0657 struct snd_soc_dai *dai)
0658 {
0659 struct jz_codec *codec = snd_soc_component_get_drvdata(dai->component);
0660 unsigned int rate, bit_width;
0661
0662 switch (params_format(params)) {
0663 case SNDRV_PCM_FORMAT_S16_LE:
0664 bit_width = 0;
0665 break;
0666 case SNDRV_PCM_FORMAT_S18_3LE:
0667 bit_width = 1;
0668 break;
0669 case SNDRV_PCM_FORMAT_S20_3LE:
0670 bit_width = 2;
0671 break;
0672 case SNDRV_PCM_FORMAT_S24_3LE:
0673 bit_width = 3;
0674 break;
0675 default:
0676 return -EINVAL;
0677 }
0678
0679 for (rate = 0; rate < ARRAY_SIZE(jz4760_codec_sample_rates); rate++) {
0680 if (jz4760_codec_sample_rates[rate] == params_rate(params))
0681 break;
0682 }
0683
0684 if (rate == ARRAY_SIZE(jz4760_codec_sample_rates))
0685 return -EINVAL;
0686
0687 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
0688 regmap_update_bits(codec->regmap, JZ4760_CODEC_REG_AICR,
0689 REG_AICR_DAC_ADWL_MASK,
0690 FIELD_PREP(REG_AICR_DAC_ADWL_MASK, bit_width));
0691 regmap_update_bits(codec->regmap, JZ4760_CODEC_REG_CCR2,
0692 REG_CCR2_DAC_FREQ_MASK,
0693 FIELD_PREP(REG_CCR2_DAC_FREQ_MASK, rate));
0694 } else {
0695 regmap_update_bits(codec->regmap, JZ4760_CODEC_REG_AICR,
0696 REG_AICR_ADC_ADWL_MASK,
0697 FIELD_PREP(REG_AICR_ADC_ADWL_MASK, bit_width));
0698 regmap_update_bits(codec->regmap, JZ4760_CODEC_REG_CCR2,
0699 REG_CCR2_ADC_FREQ_MASK,
0700 FIELD_PREP(REG_CCR2_ADC_FREQ_MASK, rate));
0701 }
0702
0703 return 0;
0704 }
0705
0706 static const struct snd_soc_dai_ops jz4760_codec_dai_ops = {
0707 .startup = jz4760_codec_startup,
0708 .shutdown = jz4760_codec_shutdown,
0709 .hw_params = jz4760_codec_hw_params,
0710 .trigger = jz4760_codec_pcm_trigger,
0711 .mute_stream = jz4760_codec_mute_stream,
0712 .no_capture_mute = 1,
0713 };
0714
0715 #define JZ_CODEC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
0716 SNDRV_PCM_FMTBIT_S18_3LE | \
0717 SNDRV_PCM_FMTBIT_S20_3LE | \
0718 SNDRV_PCM_FMTBIT_S24_3LE)
0719
0720 static struct snd_soc_dai_driver jz4760_codec_dai = {
0721 .name = "jz4760-hifi",
0722 .playback = {
0723 .stream_name = "Playback",
0724 .channels_min = 2,
0725 .channels_max = 2,
0726 .rates = SNDRV_PCM_RATE_8000_96000,
0727 .formats = JZ_CODEC_FORMATS,
0728 },
0729 .capture = {
0730 .stream_name = "Capture",
0731 .channels_min = 2,
0732 .channels_max = 2,
0733 .rates = SNDRV_PCM_RATE_8000_96000,
0734 .formats = JZ_CODEC_FORMATS,
0735 },
0736 .ops = &jz4760_codec_dai_ops,
0737 };
0738
0739 static bool jz4760_codec_volatile(struct device *dev, unsigned int reg)
0740 {
0741 return reg == JZ4760_CODEC_REG_SR || reg == JZ4760_CODEC_REG_IFR;
0742 }
0743
0744 static bool jz4760_codec_writeable(struct device *dev, unsigned int reg)
0745 {
0746 switch (reg) {
0747 case JZ4760_CODEC_REG_SR:
0748 return false;
0749 default:
0750 return true;
0751 }
0752 }
0753
0754 static int jz4760_codec_io_wait(struct jz_codec *codec)
0755 {
0756 u32 reg;
0757
0758 return readl_poll_timeout(codec->base + ICDC_RGADW_OFFSET, reg,
0759 !(reg & ICDC_RGADW_RGWR),
0760 1000, 1 * USEC_PER_SEC);
0761 }
0762
0763 static int jz4760_codec_reg_read(void *context, unsigned int reg,
0764 unsigned int *val)
0765 {
0766 struct jz_codec *codec = context;
0767 unsigned int i;
0768 u32 tmp;
0769 int ret;
0770
0771 ret = jz4760_codec_io_wait(codec);
0772 if (ret)
0773 return ret;
0774
0775 tmp = readl(codec->base + ICDC_RGADW_OFFSET);
0776 tmp &= ~ICDC_RGADW_RGADDR_MASK;
0777 tmp |= FIELD_PREP(ICDC_RGADW_RGADDR_MASK, reg);
0778 writel(tmp, codec->base + ICDC_RGADW_OFFSET);
0779
0780
0781 for (i = 0; i < 6; i++)
0782 *val = readl(codec->base + ICDC_RGDATA_OFFSET) &
0783 ICDC_RGDATA_RGDOUT_MASK;
0784
0785 return 0;
0786 }
0787
0788 static int jz4760_codec_reg_write(void *context, unsigned int reg,
0789 unsigned int val)
0790 {
0791 struct jz_codec *codec = context;
0792 int ret;
0793
0794 ret = jz4760_codec_io_wait(codec);
0795 if (ret)
0796 return ret;
0797
0798 writel(ICDC_RGADW_RGWR | FIELD_PREP(ICDC_RGADW_RGADDR_MASK, reg) | val,
0799 codec->base + ICDC_RGADW_OFFSET);
0800
0801 ret = jz4760_codec_io_wait(codec);
0802 if (ret)
0803 return ret;
0804
0805 return 0;
0806 }
0807
0808 static const u8 jz4760_codec_reg_defaults[] = {
0809 0x00, 0xFC, 0x1B, 0x20, 0x00, 0x80, 0x00, 0x00,
0810 0xFF, 0x1F, 0x3F, 0x00, 0x06, 0x06, 0x06, 0x06,
0811 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x07, 0x44,
0812 0x1F, 0x00, 0x00, 0x00
0813 };
0814
0815 static struct regmap_config jz4760_codec_regmap_config = {
0816 .reg_bits = 7,
0817 .val_bits = 8,
0818
0819 .max_register = JZ4760_CODEC_REG_MIX2,
0820 .volatile_reg = jz4760_codec_volatile,
0821 .writeable_reg = jz4760_codec_writeable,
0822
0823 .reg_read = jz4760_codec_reg_read,
0824 .reg_write = jz4760_codec_reg_write,
0825
0826 .reg_defaults_raw = jz4760_codec_reg_defaults,
0827 .num_reg_defaults_raw = ARRAY_SIZE(jz4760_codec_reg_defaults),
0828 .cache_type = REGCACHE_FLAT,
0829 };
0830
0831 static int jz4760_codec_probe(struct platform_device *pdev)
0832 {
0833 struct device *dev = &pdev->dev;
0834 struct jz_codec *codec;
0835 int ret;
0836
0837 codec = devm_kzalloc(dev, sizeof(*codec), GFP_KERNEL);
0838 if (!codec)
0839 return -ENOMEM;
0840
0841 codec->dev = dev;
0842
0843 codec->base = devm_platform_ioremap_resource(pdev, 0);
0844 if (IS_ERR(codec->base))
0845 return PTR_ERR(codec->base);
0846
0847 codec->regmap = devm_regmap_init(dev, NULL, codec,
0848 &jz4760_codec_regmap_config);
0849 if (IS_ERR(codec->regmap))
0850 return PTR_ERR(codec->regmap);
0851
0852 codec->clk = devm_clk_get(dev, "aic");
0853 if (IS_ERR(codec->clk))
0854 return PTR_ERR(codec->clk);
0855
0856 platform_set_drvdata(pdev, codec);
0857
0858 ret = devm_snd_soc_register_component(dev, &jz4760_codec_soc_codec_dev,
0859 &jz4760_codec_dai, 1);
0860 if (ret) {
0861 dev_err(dev, "Failed to register codec: %d\n", ret);
0862 return ret;
0863 }
0864
0865 return 0;
0866 }
0867
0868 static const struct of_device_id jz4760_codec_of_matches[] = {
0869 { .compatible = "ingenic,jz4760-codec", },
0870 { }
0871 };
0872 MODULE_DEVICE_TABLE(of, jz4760_codec_of_matches);
0873
0874 static struct platform_driver jz4760_codec_driver = {
0875 .probe = jz4760_codec_probe,
0876 .driver = {
0877 .name = "jz4760-codec",
0878 .of_match_table = jz4760_codec_of_matches,
0879 },
0880 };
0881 module_platform_driver(jz4760_codec_driver);
0882
0883 MODULE_DESCRIPTION("JZ4760 SoC internal codec driver");
0884 MODULE_AUTHOR("Christophe Branchereau <cbranchereau@gmail.com>");
0885 MODULE_AUTHOR("Paul Cercueil <paul@crapouillou.net>");
0886 MODULE_LICENSE("GPL v2");