Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 //
0003 // Ingenic JZ4760 CODEC driver
0004 //
0005 // Copyright (C) 2021, Christophe Branchereau <cbranchereau@gmail.com>
0006 // Copyright (C) 2021, Paul Cercueil <paul@crapouillou.net>
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 /* ICDC internal register access control register(RGADW) */
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 /* ICDC internal register data output register (RGDATA)*/
0031 #define ICDC_RGDATA_IRQ         BIT(8)
0032 #define ICDC_RGDATA_RGDOUT_MASK     GENMASK(7, 0)
0033 
0034 /* Internal register space, accessed through regmap */
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 /* codec private data */
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         /* Reset all interrupt flags. */
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      * SYSCLK output from the codec to the AIC is required to keep the
0205      * DMA transfer going during playback when all audible outputs have
0206      * been disabled.
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         /* do nothing */
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         /* clear GUP/GDO flag */
0277         regmap_write(jz_codec->regmap, JZ4760_CODEC_REG_IFR, gain_bit);
0278     }
0279 
0280     regmap_read(jz_codec->regmap, JZ4760_CODEC_REG_CR2, &reg);
0281 
0282     return 0;
0283 }
0284 
0285 /* unit: 0.01dB */
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 /* Unconditional controls. */
0292 static const struct snd_kcontrol_new jz4760_codec_snd_controls[] = {
0293     /* record gain control */
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         /* unmute HP */
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         /* wait for ramp-up complete (RUP) */
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         /* clear RUP flag */
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         /* mute HP */
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         /* clear RDO flag */
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 /* Unconditional routes. */
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     /* Collect updates for later sending. */
0570     regcache_cache_only(regmap, true);
0571 
0572     /* default Amp output to PCM */
0573     regmap_set_bits(regmap, JZ4760_CODEC_REG_CR1, REG_CR1_OUTSEL_MASK);
0574 
0575     /* Disable stereo mic */
0576     regmap_clear_bits(regmap, JZ4760_CODEC_REG_CR3,
0577               BIT(REG_CR3_MICSTEREO_OFFSET));
0578 
0579     /* Set mic 1 as default source for ADC */
0580     regmap_clear_bits(regmap, JZ4760_CODEC_REG_CR3,
0581               REG_CR3_ADC_INSEL_MASK);
0582 
0583     /* ADC/DAC: serial + i2s */
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     /* The generated IRQ is a high level */
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     /* 12M oscillator */
0596     regmap_clear_bits(regmap, JZ4760_CODEC_REG_CCR1, REG_CCR1_CRYSTAL_MASK);
0597 
0598     /* 0: 16ohm/220uF, 1: 10kohm/1uF */
0599     regmap_clear_bits(regmap, JZ4760_CODEC_REG_CR1, REG_CR1_HP_LOAD);
0600 
0601     /* default to NOMAD */
0602     regmap_set_bits(jz_codec->regmap, JZ4760_CODEC_REG_CR2,
0603             REG_CR2_DAC_NOMAD);
0604 
0605     /* disable automatic gain */
0606     regmap_clear_bits(regmap, JZ4760_CODEC_REG_AGC1, REG_AGC1_EN);
0607 
0608     /* Independent L/R DAC gain control */
0609     regmap_clear_bits(regmap, JZ4760_CODEC_REG_GCR5,
0610               REG_GCR_RL);
0611 
0612     /* Send collected updates. */
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     /* wait 6+ cycles */
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     { /* sentinel */ }
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");