Merge branch 'for-5.10' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie...
[linux-2.6-microblaze.git] / sound / soc / codecs / rt1015.c
index 3db0729..ac4c9f4 100644 (file)
@@ -497,18 +497,40 @@ static void rt1015_calibrate(struct rt1015_priv *rt1015)
        snd_soc_dapm_mutex_lock(&component->dapm);
        regcache_cache_bypass(regmap, true);
 
-       regmap_write(regmap, RT1015_PWR1, 0xd7df);
-       regmap_write(regmap, RT1015_PWR4, 0x00b2);
-       regmap_write(regmap, RT1015_CLSD_INTERNAL8, 0x2008);
+       regmap_write(regmap, RT1015_PWR9, 0xAA60);
+       regmap_write(regmap, RT1015_PWR_STATE_CTRL, 0x0089);
+       regmap_write(regmap, RT1015_PWR_STATE_CTRL, 0x008A);
+       regmap_write(regmap, RT1015_PWR_STATE_CTRL, 0x008C);
+       regmap_write(regmap, RT1015_PWR_STATE_CTRL, 0x008D);
+       regmap_write(regmap, RT1015_PWR4, 0x80B2);
+       regmap_write(regmap, RT1015_CLASSD_SEQ, 0x5797);
+       regmap_write(regmap, RT1015_CLSD_INTERNAL8, 0x2100);
+       regmap_write(regmap, RT1015_CLSD_INTERNAL9, 0x0100);
+       regmap_write(regmap, RT1015_PWR5, 0x2175);
+       regmap_write(regmap, RT1015_MIXER1, 0x005D);
+       regmap_write(regmap, RT1015_CLSD_INTERNAL1, 0x00A1);
+       regmap_write(regmap, RT1015_CLSD_INTERNAL2, 0x12F7);
+       regmap_write(regmap, RT1015_DC_CALIB_CLSD1, 0x1205);
+       msleep(200);
+       regmap_write(regmap, RT1015_CLSD_INTERNAL8, 0x2000);
+       regmap_write(regmap, RT1015_CLSD_INTERNAL9, 0x0180);
+       regmap_write(regmap, RT1015_CLSD_INTERNAL1, 0x00A1);
+       regmap_write(regmap, RT1015_DC_CALIB_CLSD1, 0x0A05);
+       msleep(200);
+       regmap_write(regmap, RT1015_PWR4, 0x00B2);
+       regmap_write(regmap, RT1015_CLSD_INTERNAL8, 0x2028);
        regmap_write(regmap, RT1015_CLSD_INTERNAL9, 0x0140);
-       regmap_write(regmap, RT1015_GAT_BOOST, 0x0efe);
-       regmap_write(regmap, RT1015_PWR_STATE_CTRL, 0x000d);
-       regmap_write(regmap, RT1015_PWR_STATE_CTRL, 0x000e);
-       regmap_write(regmap, RT1015_DC_CALIB_CLSD1, 0x5a00);
-       regmap_write(regmap, RT1015_DC_CALIB_CLSD1, 0x5a01);
-       regmap_write(regmap, RT1015_DC_CALIB_CLSD1, 0x5a05);
-       msleep(500);
-       regmap_write(regmap, RT1015_PWR1, 0x0);
+       regmap_write(regmap, RT1015_PWR5, 0x0175);
+       regmap_write(regmap, RT1015_CLSD_INTERNAL1, 0x1721);
+       regmap_write(regmap, RT1015_CLASSD_SEQ, 0x570E);
+       regmap_write(regmap, RT1015_MIXER1, 0x203D);
+       regmap_write(regmap, RT1015_DC_CALIB_CLSD1, 0x5A01);
+       regmap_write(regmap, RT1015_CLSD_INTERNAL2, 0x12FF);
+       regmap_write(regmap, RT1015_GAT_BOOST, 0x0eFE);
+       regmap_write(regmap, RT1015_PWR_STATE_CTRL, 0x008E);
+       regmap_write(regmap, RT1015_PWR_STATE_CTRL, 0x0088);
+       regmap_write(regmap, RT1015_SYS_RST1, 0x05F5);
+       regmap_write(regmap, RT1015_SYS_RST2, 0x0b9a);
 
        regcache_cache_bypass(regmap, false);
        regcache_mark_dirty(regmap);
@@ -603,6 +625,8 @@ static int r1015_dac_event(struct snd_soc_dapm_widget *w,
                if (rt1015->bypass_boost == RT1015_Enable_Boost) {
                        snd_soc_component_write(component,
                                RT1015_SYS_RST1, 0x05f7);
+                       snd_soc_component_write(component,
+                               RT1015_SYS_RST2, 0x0b0a);
                        snd_soc_component_write(component,
                                RT1015_GAT_BOOST, 0xacfe);
                        snd_soc_component_write(component,
@@ -610,10 +634,14 @@ static int r1015_dac_event(struct snd_soc_dapm_widget *w,
                        snd_soc_component_write(component,
                                RT1015_GAT_BOOST, 0xecfe);
                } else {
+                       snd_soc_component_write(component,
+                               0x032d, 0xaa60);
                        snd_soc_component_write(component,
                                RT1015_SYS_RST1, 0x05f7);
                        snd_soc_component_write(component,
-                               RT1015_PWR_STATE_CTRL, 0x026e);
+                               RT1015_SYS_RST2, 0x0b0a);
+                       snd_soc_component_write(component,
+                               RT1015_PWR_STATE_CTRL, 0x008e);
                }
                break;
 
@@ -627,11 +655,17 @@ static int r1015_dac_event(struct snd_soc_dapm_widget *w,
                                RT1015_PWR9, 0xa800);
                        snd_soc_component_write(component,
                                RT1015_SYS_RST1, 0x05f5);
+                       snd_soc_component_write(component,
+                               RT1015_SYS_RST2, 0x0b9a);
                } else {
                        snd_soc_component_write(component,
-                               RT1015_PWR_STATE_CTRL, 0x0268);
+                               0x032d, 0xaa60);
+                       snd_soc_component_write(component,
+                               RT1015_PWR_STATE_CTRL, 0x0088);
                        snd_soc_component_write(component,
                                RT1015_SYS_RST1, 0x05f5);
+                       snd_soc_component_write(component,
+                               RT1015_SYS_RST2, 0x0b9a);
                }
                rt1015->dac_is_used = 0;
 
@@ -664,38 +698,12 @@ static int rt1015_amp_drv_event(struct snd_soc_dapm_widget *w,
 }
 
 static const struct snd_soc_dapm_widget rt1015_dapm_widgets[] = {
-       SND_SOC_DAPM_SUPPLY("LDO2", RT1015_PWR1, RT1015_PWR_LDO2_BIT, 0,
-               NULL, 0),
-       SND_SOC_DAPM_SUPPLY("INT RC CLK", RT1015_PWR1, RT1015_PWR_INTCLK_BIT,
-               0, NULL, 0),
-       SND_SOC_DAPM_SUPPLY("ISENSE", RT1015_PWR1, RT1015_PWR_ISENSE_BIT, 0,
-               NULL, 0),
-       SND_SOC_DAPM_SUPPLY("VSENSE", RT1015_PWR1, RT1015_PWR_VSENSE_BIT, 0,
-               NULL, 0),
        SND_SOC_DAPM_SUPPLY("PLL", RT1015_PWR1, RT1015_PWR_PLL_BIT, 0,
                NULL, 0),
-       SND_SOC_DAPM_SUPPLY("BG1 BG2", RT1015_PWR1, RT1015_PWR_BG_1_2_BIT, 0,
-               NULL, 0),
-       SND_SOC_DAPM_SUPPLY("MBIAS BG", RT1015_PWR1, RT1015_PWR_MBIAS_BG_BIT, 0,
-               NULL, 0),
-       SND_SOC_DAPM_SUPPLY("VBAT", RT1015_PWR1, RT1015_PWR_VBAT_BIT, 0, NULL,
-               0),
-       SND_SOC_DAPM_SUPPLY("MBIAS", RT1015_PWR1, RT1015_PWR_MBIAS_BIT, 0,
-               NULL, 0),
-       SND_SOC_DAPM_SUPPLY("ADCV", RT1015_PWR1, RT1015_PWR_ADCV_BIT, 0, NULL,
-               0),
-       SND_SOC_DAPM_SUPPLY("MIXERV", RT1015_PWR1, RT1015_PWR_MIXERV_BIT, 0,
-               NULL, 0),
-       SND_SOC_DAPM_SUPPLY("SUMV", RT1015_PWR1, RT1015_PWR_SUMV_BIT, 0, NULL,
-               0),
-       SND_SOC_DAPM_SUPPLY("VREFLV", RT1015_PWR1, RT1015_PWR_VREFLV_BIT, 0,
-               NULL, 0),
-
        SND_SOC_DAPM_AIF_IN("AIFRX", "AIF Playback", 0, SND_SOC_NOPM, 0, 0),
-       SND_SOC_DAPM_DAC_E("DAC", NULL, RT1015_PWR1, RT1015_PWR_DAC_BIT, 0,
+       SND_SOC_DAPM_DAC_E("DAC", NULL, SND_SOC_NOPM, 0, 0,
                r1015_dac_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
                SND_SOC_DAPM_POST_PMD),
-
        SND_SOC_DAPM_OUT_DRV_E("Amp Drv", SND_SOC_NOPM, 0, 0, NULL, 0,
                        rt1015_amp_drv_event, SND_SOC_DAPM_POST_PMU),
        SND_SOC_DAPM_OUTPUT("SPO"),
@@ -703,19 +711,7 @@ static const struct snd_soc_dapm_widget rt1015_dapm_widgets[] = {
 
 static const struct snd_soc_dapm_route rt1015_dapm_routes[] = {
        { "DAC", NULL, "AIFRX" },
-       { "DAC", NULL, "LDO2" },
        { "DAC", NULL, "PLL", rt1015_is_sys_clk_from_pll},
-       { "DAC", NULL, "INT RC CLK" },
-       { "DAC", NULL, "ISENSE" },
-       { "DAC", NULL, "VSENSE" },
-       { "DAC", NULL, "BG1 BG2" },
-       { "DAC", NULL, "MBIAS BG" },
-       { "DAC", NULL, "VBAT" },
-       { "DAC", NULL, "MBIAS" },
-       { "DAC", NULL, "ADCV" },
-       { "DAC", NULL, "MIXERV" },
-       { "DAC", NULL, "SUMV" },
-       { "DAC", NULL, "VREFLV" },
        { "Amp Drv", NULL, "DAC" },
        { "SPO", NULL, "Amp Drv" },
 };
@@ -950,6 +946,106 @@ static int rt1015_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio)
        return 0;
 }
 
+static int rt1015_set_tdm_slot(struct snd_soc_dai *dai,
+       unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width)
+{
+       struct snd_soc_component *component = dai->component;
+       unsigned int val = 0, rx_slotnum, tx_slotnum;
+       int ret = 0, first_bit;
+
+       switch (slots) {
+       case 2:
+               val |= RT1015_I2S_TX_2CH;
+               break;
+       case 4:
+               val |= RT1015_I2S_TX_4CH;
+               break;
+       case 6:
+               val |= RT1015_I2S_TX_6CH;
+               break;
+       case 8:
+               val |= RT1015_I2S_TX_8CH;
+               break;
+       default:
+               ret = -EINVAL;
+               goto _set_tdm_err_;
+       }
+
+       switch (slot_width) {
+       case 16:
+               val |= RT1015_I2S_CH_TX_LEN_16B;
+               break;
+       case 20:
+               val |= RT1015_I2S_CH_TX_LEN_20B;
+               break;
+       case 24:
+               val |= RT1015_I2S_CH_TX_LEN_24B;
+               break;
+       case 32:
+               val |= RT1015_I2S_CH_TX_LEN_32B;
+               break;
+       default:
+               ret = -EINVAL;
+               goto _set_tdm_err_;
+       }
+
+       /* Rx slot configuration */
+       rx_slotnum = hweight_long(rx_mask);
+       if (rx_slotnum != 1) {
+               ret = -EINVAL;
+               dev_err(component->dev, "too many rx slots or zero slot\n");
+               goto _set_tdm_err_;
+       }
+
+       /* This is an assumption that the system sends stereo audio to the amplifier typically.
+        * And the stereo audio is placed in slot 0/2/4/6 as the starting slot.
+        * The users could select the channel from L/R/L+R by "Mono LR Select" control.
+        */
+       first_bit = __ffs(rx_mask);
+       switch (first_bit) {
+       case 0:
+       case 2:
+       case 4:
+       case 6:
+               snd_soc_component_update_bits(component,
+                       RT1015_TDM1_4,
+                       RT1015_TDM_I2S_TX_L_DAC1_1_MASK |
+                       RT1015_TDM_I2S_TX_R_DAC1_1_MASK,
+                       (first_bit << RT1015_TDM_I2S_TX_L_DAC1_1_SFT) |
+                       ((first_bit+1) << RT1015_TDM_I2S_TX_R_DAC1_1_SFT));
+               break;
+       case 1:
+       case 3:
+       case 5:
+       case 7:
+               snd_soc_component_update_bits(component,
+                       RT1015_TDM1_4,
+                       RT1015_TDM_I2S_TX_L_DAC1_1_MASK |
+                       RT1015_TDM_I2S_TX_R_DAC1_1_MASK,
+                       ((first_bit-1) << RT1015_TDM_I2S_TX_L_DAC1_1_SFT) |
+                       (first_bit << RT1015_TDM_I2S_TX_R_DAC1_1_SFT));
+               break;
+       default:
+               ret = -EINVAL;
+               goto _set_tdm_err_;
+       }
+
+       /* Tx slot configuration */
+       tx_slotnum = hweight_long(tx_mask);
+       if (tx_slotnum) {
+               ret = -EINVAL;
+               dev_err(component->dev, "doesn't need to support tx slots\n");
+               goto _set_tdm_err_;
+       }
+
+       snd_soc_component_update_bits(component, RT1015_TDM1_1,
+               RT1015_I2S_CH_TX_MASK | RT1015_I2S_CH_RX_MASK |
+               RT1015_I2S_CH_TX_LEN_MASK | RT1015_I2S_CH_RX_LEN_MASK, val);
+
+_set_tdm_err_:
+       return ret;
+}
+
 static int rt1015_probe(struct snd_soc_component *component)
 {
        struct rt1015_priv *rt1015 =
@@ -958,7 +1054,6 @@ static int rt1015_probe(struct snd_soc_component *component)
        rt1015->component = component;
        rt1015->bclk_ratio = 0;
        rt1015->cali_done = 0;
-       snd_soc_component_write(component, RT1015_BAT_RPO_STEP1, 0x061c);
 
        INIT_DELAYED_WORK(&rt1015->flush_work, rt1015_flush_work);
 
@@ -981,6 +1076,7 @@ static struct snd_soc_dai_ops rt1015_aif_dai_ops = {
        .hw_params = rt1015_hw_params,
        .set_fmt = rt1015_set_dai_fmt,
        .set_bclk_ratio = rt1015_set_bclk_ratio,
+       .set_tdm_slot = rt1015_set_tdm_slot,
 };
 
 static struct snd_soc_dai_driver rt1015_dai[] = {