Merge remote-tracking branch 'asoc/for-5.9' into asoc-linus
authorMark Brown <broonie@kernel.org>
Fri, 11 Dec 2020 17:47:52 +0000 (17:47 +0000)
committerMark Brown <broonie@kernel.org>
Fri, 11 Dec 2020 17:47:52 +0000 (17:47 +0000)
19 files changed:
MAINTAINERS
sound/soc/codecs/cs47l15.c
sound/soc/codecs/cs47l35.c
sound/soc/codecs/rt1015.c
sound/soc/codecs/rt1015.h
sound/soc/codecs/rt700-sdw.c
sound/soc/codecs/rt711-sdw.c
sound/soc/codecs/tas2770.c
sound/soc/codecs/tlv320adcx140.c
sound/soc/codecs/tlv320adcx140.h
sound/soc/codecs/tlv320aic32x4-clk.c
sound/soc/codecs/tlv320aic32x4.c
sound/soc/codecs/tlv320aic32x4.h
sound/soc/codecs/wm_adsp.c
sound/soc/fsl/fsl_audmix.c
sound/soc/fsl/fsl_sai.c
sound/soc/fsl/fsl_sai.h
sound/soc/mediatek/mt8183/mt8183-da7219-max98357.c
sound/soc/soc-topology.c

index 8671573..86d936f 100644 (file)
@@ -4175,6 +4175,7 @@ CIRRUS LOGIC AUDIO CODEC DRIVERS
 M:     James Schulman <james.schulman@cirrus.com>
 M:     David Rhodes <david.rhodes@cirrus.com>
 L:     alsa-devel@alsa-project.org (moderated for non-subscribers)
+L:     patches@opensource.cirrus.com
 S:     Maintained
 F:     sound/soc/codecs/cs*
 
index a591e74..254f9d9 100644 (file)
@@ -1089,6 +1089,7 @@ static const struct snd_soc_dapm_route cs47l15_dapm_routes[] = {
        { "HPOUT1 Demux", NULL, "OUT1R" },
 
        { "OUT1R", NULL, "HPOUT1 Mono Mux" },
+       { "HPOUT1 Mono Mux", "EPOUT", "OUT1L" },
 
        { "HPOUTL", "HPOUT", "HPOUT1 Demux" },
        { "HPOUTR", "HPOUT", "HPOUT1 Demux" },
@@ -1268,7 +1269,6 @@ static irqreturn_t cs47l15_adsp2_irq(int irq, void *data)
 
 static const struct snd_soc_dapm_route cs47l15_mono_routes[] = {
        { "HPOUT1 Mono Mux", "HPOUT", "OUT1L" },
-       { "HPOUT1 Mono Mux", "EPOUT", "OUT1L" },
 };
 
 static int cs47l15_component_probe(struct snd_soc_component *component)
index 7f5dd01..e967609 100644 (file)
@@ -1305,6 +1305,7 @@ static const struct snd_soc_dapm_route cs47l35_dapm_routes[] = {
        { "SPKOUTP", NULL, "OUT4L" },
 
        { "OUT1R", NULL, "HPOUT1 Mono Mux" },
+       { "HPOUT1 Mono Mux", "EPOUT", "OUT1L" },
 
        { "HPOUTL", "HPOUT", "HPOUT1 Demux" },
        { "HPOUTR", "HPOUT", "HPOUT1 Demux" },
@@ -1550,7 +1551,6 @@ static irqreturn_t cs47l35_adsp2_irq(int irq, void *data)
 
 static const struct snd_soc_dapm_route cs47l35_mono_routes[] = {
        { "HPOUT1 Mono Mux", "HPOUT", "OUT1L" },
-       { "HPOUT1 Mono Mux", "EPOUT", "OUT1L" },
 };
 
 static int cs47l35_component_probe(struct snd_soc_component *component)
index 548f686..25fe2dd 100644 (file)
@@ -484,6 +484,33 @@ static int rt1015_bypass_boost_get(struct snd_kcontrol *kcontrol,
        return 0;
 }
 
+static void rt1015_calibrate(struct rt1015_priv *rt1015)
+{
+       struct snd_soc_component *component = rt1015->component;
+       struct regmap *regmap = rt1015->regmap;
+
+       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_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);
+
+       regcache_cache_bypass(regmap, false);
+       regcache_mark_dirty(regmap);
+       regcache_sync(regmap);
+       snd_soc_dapm_mutex_unlock(&component->dapm);
+}
+
 static int rt1015_bypass_boost_put(struct snd_kcontrol *kcontrol,
                struct snd_ctl_elem_value *ucontrol)
 {
@@ -494,20 +521,12 @@ static int rt1015_bypass_boost_put(struct snd_kcontrol *kcontrol,
 
        if (!rt1015->dac_is_used) {
                rt1015->bypass_boost = ucontrol->value.integer.value[0];
-               if (rt1015->bypass_boost == RT1015_Bypass_Boost) {
-                       snd_soc_component_write(component,
-                               RT1015_PWR4, 0x00b2);
-                       snd_soc_component_write(component,
-                               RT1015_CLSD_INTERNAL8, 0x2008);
-                       snd_soc_component_write(component,
-                               RT1015_CLSD_INTERNAL9, 0x0140);
-                       snd_soc_component_write(component,
-                               RT1015_GAT_BOOST, 0x0efe);
-                       snd_soc_component_write(component,
-                               RT1015_PWR_STATE_CTRL, 0x000d);
-                       msleep(500);
-                       snd_soc_component_write(component,
-                               RT1015_PWR_STATE_CTRL, 0x000e);
+               if (rt1015->bypass_boost == RT1015_Bypass_Boost &&
+                       !rt1015->cali_done) {
+                       rt1015_calibrate(rt1015);
+                       rt1015->cali_done = 1;
+
+                       regmap_write(rt1015->regmap, RT1015_MONO_DYNA_CTRL, 0x0010);
                }
        } else
                dev_err(component->dev, "DAC is being used!\n");
@@ -515,6 +534,32 @@ static int rt1015_bypass_boost_put(struct snd_kcontrol *kcontrol,
        return 0;
 }
 
+static void rt1015_flush_work(struct work_struct *work)
+{
+       struct rt1015_priv *rt1015 = container_of(work, struct rt1015_priv,
+                                               flush_work.work);
+       struct snd_soc_component *component = rt1015->component;
+       unsigned int val, i = 0, count = 20;
+
+       while (i < count) {
+               usleep_range(1000, 1500);
+               dev_dbg(component->dev, "Flush DAC (retry:%u)\n", i);
+               regmap_read(rt1015->regmap, RT1015_CLK_DET, &val);
+               if (val & 0x800)
+                       break;
+               i++;
+       }
+
+       regmap_write(rt1015->regmap, RT1015_SYS_RST1, 0x0597);
+       regmap_write(rt1015->regmap, RT1015_SYS_RST1, 0x05f7);
+       regmap_write(rt1015->regmap, RT1015_MAN_I2C, 0x0028);
+
+       if (val & 0x800)
+               dev_dbg(component->dev, "Flush DAC completed.\n");
+       else
+               dev_warn(component->dev, "Fail to flush DAC data.\n");
+}
+
 static const struct snd_kcontrol_new rt1015_snd_controls[] = {
        SOC_SINGLE_TLV("DAC Playback Volume", RT1015_DAC1, RT1015_DAC_VOL_SFT,
                127, 0, dac_vol_tlv),
@@ -568,12 +613,7 @@ static int r1015_dac_event(struct snd_soc_dapm_widget *w,
                break;
 
        case SND_SOC_DAPM_POST_PMU:
-               if (rt1015->bypass_boost == RT1015_Bypass_Boost) {
-                       regmap_write(rt1015->regmap, RT1015_MAN_I2C, 0x00a8);
-                       regmap_write(rt1015->regmap, RT1015_SYS_RST1, 0x0597);
-                       regmap_write(rt1015->regmap, RT1015_SYS_RST1, 0x05f7);
-                       regmap_write(rt1015->regmap, RT1015_MAN_I2C, 0x0028);
-               }
+               regmap_write(rt1015->regmap, RT1015_MAN_I2C, 0x00a8);
                break;
 
        case SND_SOC_DAPM_POST_PMD:
@@ -589,6 +629,8 @@ static int r1015_dac_event(struct snd_soc_dapm_widget *w,
                                RT1015_SYS_RST1, 0x05f5);
                }
                rt1015->dac_is_used = 0;
+
+               cancel_delayed_work_sync(&rt1015->flush_work);
                break;
 
        default:
@@ -597,6 +639,24 @@ static int r1015_dac_event(struct snd_soc_dapm_widget *w,
        return 0;
 }
 
+static int rt1015_amp_drv_event(struct snd_soc_dapm_widget *w,
+       struct snd_kcontrol *kcontrol, int event)
+{
+       struct snd_soc_component *component =
+               snd_soc_dapm_to_component(w->dapm);
+       struct rt1015_priv *rt1015 = snd_soc_component_get_drvdata(component);
+
+       switch (event) {
+       case SND_SOC_DAPM_POST_PMU:
+               if (rt1015->hw_config == RT1015_HW_28)
+                       schedule_delayed_work(&rt1015->flush_work, msecs_to_jiffies(10));
+               break;
+       default:
+               break;
+       }
+       return 0;
+}
+
 static const struct snd_soc_dapm_widget rt1015_dapm_widgets[] = {
        SND_SOC_DAPM_SUPPLY("LDO2", RT1015_PWR1, RT1015_PWR_LDO2_BIT, 0,
                NULL, 0),
@@ -630,6 +690,8 @@ static const struct snd_soc_dapm_widget rt1015_dapm_widgets[] = {
                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"),
 };
 
@@ -648,7 +710,8 @@ static const struct snd_soc_dapm_route rt1015_dapm_routes[] = {
        { "DAC", NULL, "MIXERV" },
        { "DAC", NULL, "SUMV" },
        { "DAC", NULL, "VREFLV" },
-       { "SPO", NULL, "DAC" },
+       { "Amp Drv", NULL, "DAC" },
+       { "SPO", NULL, "Amp Drv" },
 };
 
 static int rt1015_hw_params(struct snd_pcm_substream *substream,
@@ -888,8 +951,11 @@ 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);
+
        return 0;
 }
 
@@ -897,6 +963,7 @@ static void rt1015_remove(struct snd_soc_component *component)
 {
        struct rt1015_priv *rt1015 = snd_soc_component_get_drvdata(component);
 
+       cancel_delayed_work_sync(&rt1015->flush_work);
        regmap_write(rt1015->regmap, RT1015_RESET, 0);
 }
 
@@ -1022,6 +1089,8 @@ static int rt1015_i2c_probe(struct i2c_client *i2c,
                return ret;
        }
 
+       rt1015->hw_config = (i2c->addr == 0x29) ? RT1015_HW_29 : RT1015_HW_28;
+
        regmap_read(rt1015->regmap, RT1015_DEVICE_ID, &val);
        if ((val != RT1015_DEVICE_ID_VAL) && (val != RT1015_DEVICE_ID_VAL2)) {
                dev_err(&i2c->dev,
index 7bd159e..d3fdd30 100644 (file)
@@ -373,6 +373,11 @@ enum {
        RT1015_Bypass_Boost,
 };
 
+enum {
+       RT1015_HW_28 = 0,
+       RT1015_HW_29,
+};
+
 struct rt1015_priv {
        struct snd_soc_component *component;
        struct regmap *regmap;
@@ -389,6 +394,9 @@ struct rt1015_priv {
        int bypass_boost;
        int amp_ver;
        int dac_is_used;
+       int cali_done;
+       int hw_config;
+       struct delayed_work flush_work;
 };
 
 #endif /* __RT1015_H__ */
index 1d24bf0..af6e17e 100644 (file)
@@ -490,6 +490,9 @@ static int __maybe_unused rt700_dev_suspend(struct device *dev)
        if (!rt700->hw_init)
                return 0;
 
+       cancel_delayed_work_sync(&rt700->jack_detect_work);
+       cancel_delayed_work_sync(&rt700->jack_btn_check_work);
+
        regcache_cache_only(rt700->regmap, true);
 
        return 0;
index 7efff13..9eabd30 100644 (file)
@@ -491,6 +491,10 @@ static int __maybe_unused rt711_dev_suspend(struct device *dev)
        if (!rt711->hw_init)
                return 0;
 
+       cancel_delayed_work_sync(&rt711->jack_detect_work);
+       cancel_delayed_work_sync(&rt711->jack_btn_check_work);
+       cancel_work_sync(&rt711->calibration_work);
+
        regcache_cache_only(rt711->regmap, true);
 
        return 0;
index c098518..15cdd8b 100644 (file)
@@ -57,7 +57,12 @@ static int tas2770_set_bias_level(struct snd_soc_component *component,
                        TAS2770_PWR_CTRL_MASK,
                        TAS2770_PWR_CTRL_ACTIVE);
                break;
-
+       case SND_SOC_BIAS_STANDBY:
+       case SND_SOC_BIAS_PREPARE:
+               snd_soc_component_update_bits(component,
+                       TAS2770_PWR_CTRL,
+                       TAS2770_PWR_CTRL_MASK, TAS2770_PWR_CTRL_MUTE);
+               break;
        case SND_SOC_BIAS_OFF:
                snd_soc_component_update_bits(component,
                        TAS2770_PWR_CTRL,
@@ -135,23 +140,18 @@ static int tas2770_dac_event(struct snd_soc_dapm_widget *w,
                        TAS2770_PWR_CTRL,
                        TAS2770_PWR_CTRL_MASK,
                        TAS2770_PWR_CTRL_MUTE);
-               if (ret)
-                       goto end;
                break;
        case SND_SOC_DAPM_PRE_PMD:
                ret = snd_soc_component_update_bits(component,
                        TAS2770_PWR_CTRL,
                        TAS2770_PWR_CTRL_MASK,
                        TAS2770_PWR_CTRL_SHUTDOWN);
-               if (ret)
-                       goto end;
                break;
        default:
                dev_err(tas2770->dev, "Not supported evevt\n");
                return -EINVAL;
        }
 
-end:
        if (ret < 0)
                return ret;
 
@@ -243,6 +243,9 @@ static int tas2770_set_bitwidth(struct tas2770_priv *tas2770, int bitwidth)
                return -EINVAL;
        }
 
+       if (ret < 0)
+               return ret;
+
        tas2770->channel_size = bitwidth;
 
        ret = snd_soc_component_update_bits(component,
@@ -251,16 +254,15 @@ static int tas2770_set_bitwidth(struct tas2770_priv *tas2770, int bitwidth)
                TAS2770_TDM_CFG_REG5_50_MASK,
                TAS2770_TDM_CFG_REG5_VSNS_ENABLE |
                tas2770->v_sense_slot);
-       if (ret)
-               goto end;
+       if (ret < 0)
+               return ret;
+
        ret = snd_soc_component_update_bits(component,
                TAS2770_TDM_CFG_REG6,
                TAS2770_TDM_CFG_REG6_ISNS_MASK |
                TAS2770_TDM_CFG_REG6_50_MASK,
                TAS2770_TDM_CFG_REG6_ISNS_ENABLE |
                tas2770->i_sense_slot);
-
-end:
        if (ret < 0)
                return ret;
 
@@ -278,36 +280,35 @@ static int tas2770_set_samplerate(struct tas2770_priv *tas2770, int samplerate)
                        TAS2770_TDM_CFG_REG0,
                        TAS2770_TDM_CFG_REG0_SMP_MASK,
                        TAS2770_TDM_CFG_REG0_SMP_48KHZ);
-               if (ret)
-                       goto end;
+               if (ret < 0)
+                       return ret;
+
                ret = snd_soc_component_update_bits(component,
                        TAS2770_TDM_CFG_REG0,
                        TAS2770_TDM_CFG_REG0_31_MASK,
                        TAS2770_TDM_CFG_REG0_31_44_1_48KHZ);
-               if (ret)
-                       goto end;
                break;
        case 44100:
                ret = snd_soc_component_update_bits(component,
                        TAS2770_TDM_CFG_REG0,
                        TAS2770_TDM_CFG_REG0_SMP_MASK,
                        TAS2770_TDM_CFG_REG0_SMP_44_1KHZ);
-               if (ret)
-                       goto end;
+               if (ret < 0)
+                       return ret;
+
                ret = snd_soc_component_update_bits(component,
                        TAS2770_TDM_CFG_REG0,
                        TAS2770_TDM_CFG_REG0_31_MASK,
                        TAS2770_TDM_CFG_REG0_31_44_1_48KHZ);
-               if (ret)
-                       goto end;
                break;
        case 96000:
                ret = snd_soc_component_update_bits(component,
                        TAS2770_TDM_CFG_REG0,
                        TAS2770_TDM_CFG_REG0_SMP_MASK,
                        TAS2770_TDM_CFG_REG0_SMP_48KHZ);
-               if (ret)
-                       goto end;
+               if (ret < 0)
+                       return ret;
+
                ret = snd_soc_component_update_bits(component,
                        TAS2770_TDM_CFG_REG0,
                        TAS2770_TDM_CFG_REG0_31_MASK,
@@ -318,8 +319,9 @@ static int tas2770_set_samplerate(struct tas2770_priv *tas2770, int samplerate)
                        TAS2770_TDM_CFG_REG0,
                        TAS2770_TDM_CFG_REG0_SMP_MASK,
                        TAS2770_TDM_CFG_REG0_SMP_44_1KHZ);
-               if (ret)
-                       goto end;
+               if (ret < 0)
+                       return ret;
+
                ret = snd_soc_component_update_bits(component,
                        TAS2770_TDM_CFG_REG0,
                        TAS2770_TDM_CFG_REG0_31_MASK,
@@ -330,22 +332,22 @@ static int tas2770_set_samplerate(struct tas2770_priv *tas2770, int samplerate)
                        TAS2770_TDM_CFG_REG0,
                        TAS2770_TDM_CFG_REG0_SMP_MASK,
                        TAS2770_TDM_CFG_REG0_SMP_48KHZ);
-               if (ret)
-                       goto end;
+               if (ret < 0)
+                       return ret;
+
                ret = snd_soc_component_update_bits(component,
                        TAS2770_TDM_CFG_REG0,
                        TAS2770_TDM_CFG_REG0_31_MASK,
                        TAS2770_TDM_CFG_REG0_31_176_4_192KHZ);
-               if (ret)
-                       goto end;
                break;
        case 17640:
                ret = snd_soc_component_update_bits(component,
                        TAS2770_TDM_CFG_REG0,
                        TAS2770_TDM_CFG_REG0_SMP_MASK,
                        TAS2770_TDM_CFG_REG0_SMP_44_1KHZ);
-               if (ret)
-                       goto end;
+               if (ret < 0)
+                       return ret;
+
                ret = snd_soc_component_update_bits(component,
                        TAS2770_TDM_CFG_REG0,
                        TAS2770_TDM_CFG_REG0_31_MASK,
@@ -355,7 +357,6 @@ static int tas2770_set_samplerate(struct tas2770_priv *tas2770, int samplerate)
                ret = -EINVAL;
        }
 
-end:
        if (ret < 0)
                return ret;
 
@@ -575,6 +576,8 @@ static int tas2770_codec_probe(struct snd_soc_component *component)
 
        tas2770->component = component;
 
+       tas2770_reset(tas2770);
+
        return 0;
 }
 
@@ -701,29 +704,28 @@ static int tas2770_parse_dt(struct device *dev, struct tas2770_priv *tas2770)
        rc = fwnode_property_read_u32(dev->fwnode, "ti,asi-format",
                                        &tas2770->asi_format);
        if (rc) {
-               dev_err(tas2770->dev, "Looking up %s property failed %d\n",
-                       "ti,asi-format", rc);
-               goto end;
+               dev_info(tas2770->dev, "Property %s is missing setting default slot\n",
+                       "ti,asi-format");
+               tas2770->asi_format = 0;
        }
 
        rc = fwnode_property_read_u32(dev->fwnode, "ti,imon-slot-no",
                        &tas2770->i_sense_slot);
        if (rc) {
-               dev_err(tas2770->dev, "Looking up %s property failed %d\n",
-                       "ti,imon-slot-no", rc);
-               goto end;
+               dev_info(tas2770->dev, "Property %s is missing setting default slot\n",
+                       "ti,imon-slot-no");
+               tas2770->i_sense_slot = 0;
        }
 
        rc = fwnode_property_read_u32(dev->fwnode, "ti,vmon-slot-no",
                                &tas2770->v_sense_slot);
        if (rc) {
-               dev_err(tas2770->dev, "Looking up %s property failed %d\n",
-                       "ti,vmon-slot-no", rc);
-               goto end;
+               dev_info(tas2770->dev, "Property %s is missing setting default slot\n",
+                       "ti,vmon-slot-no");
+               tas2770->v_sense_slot = 2;
        }
 
-end:
-       return rc;
+       return 0;
 }
 
 static int tas2770_i2c_probe(struct i2c_client *client,
@@ -771,8 +773,6 @@ static int tas2770_i2c_probe(struct i2c_client *client,
        tas2770->channel_size = 0;
        tas2770->slot_width = 0;
 
-       tas2770_reset(tas2770);
-
        result = tas2770_register_codec(tas2770);
        if (result)
                dev_err(tas2770->dev, "Register codec failed.\n");
index 8efe206..936261e 100644 (file)
@@ -30,7 +30,7 @@ struct adcx140_priv {
        struct regmap *regmap;
        struct device *dev;
 
-       int micbias_vg;
+       bool micbias_vg;
 
        unsigned int dai_fmt;
        unsigned int tdm_delay;
@@ -161,7 +161,7 @@ static const struct regmap_config adcx140_i2c_regmap = {
 };
 
 /* Digital Volume control. From -100 to 27 dB in 0.5 dB steps */
-static DECLARE_TLV_DB_SCALE(dig_vol_tlv, -10000, 50, 0);
+static DECLARE_TLV_DB_SCALE(dig_vol_tlv, -10050, 50, 0);
 
 /* ADC gain. From 0 to 42 dB in 1 dB steps */
 static DECLARE_TLV_DB_SCALE(adc_tlv, 0, 100, 0);
@@ -614,11 +614,26 @@ static int adcx140_reset(struct adcx140_priv *adcx140)
        return ret;
 }
 
+static void adcx140_pwr_ctrl(struct adcx140_priv *adcx140, bool power_state)
+{
+       int pwr_ctrl = 0;
+
+       if (power_state)
+               pwr_ctrl = ADCX140_PWR_CFG_ADC_PDZ | ADCX140_PWR_CFG_PLL_PDZ;
+
+       if (adcx140->micbias_vg && power_state)
+               pwr_ctrl |= ADCX140_PWR_CFG_BIAS_PDZ;
+
+       regmap_update_bits(adcx140->regmap, ADCX140_PWR_CFG,
+                          ADCX140_PWR_CTRL_MSK, pwr_ctrl);
+}
+
 static int adcx140_hw_params(struct snd_pcm_substream *substream,
                             struct snd_pcm_hw_params *params,
                             struct snd_soc_dai *dai)
 {
        struct snd_soc_component *component = dai->component;
+       struct adcx140_priv *adcx140 = snd_soc_component_get_drvdata(component);
        u8 data = 0;
 
        switch (params_width(params)) {
@@ -640,9 +655,13 @@ static int adcx140_hw_params(struct snd_pcm_substream *substream,
                return -EINVAL;
        }
 
+       adcx140_pwr_ctrl(adcx140, false);
+
        snd_soc_component_update_bits(component, ADCX140_ASI_CFG0,
                            ADCX140_WORD_LEN_MSK, data);
 
+       adcx140_pwr_ctrl(adcx140, true);
+
        return 0;
 }
 
@@ -654,7 +673,7 @@ static int adcx140_set_dai_fmt(struct snd_soc_dai *codec_dai,
        u8 iface_reg1 = 0;
        u8 iface_reg2 = 0;
        int offset = 0;
-       int width = adcx140->slot_width;
+       bool inverted_bclk = false;
 
        /* set master/slave audio interface */
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -670,24 +689,6 @@ static int adcx140_set_dai_fmt(struct snd_soc_dai *codec_dai,
                return -EINVAL;
        }
 
-       /* signal polarity */
-       switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
-       case SND_SOC_DAIFMT_NB_IF:
-               iface_reg1 |= ADCX140_FSYNCINV_BIT;
-               break;
-       case SND_SOC_DAIFMT_IB_IF:
-               iface_reg1 |= ADCX140_BCLKINV_BIT | ADCX140_FSYNCINV_BIT;
-               break;
-       case SND_SOC_DAIFMT_IB_NF:
-               iface_reg1 |= ADCX140_BCLKINV_BIT;
-               break;
-       case SND_SOC_DAIFMT_NB_NF:
-               break;
-       default:
-               dev_err(component->dev, "Invalid DAI clock signal polarity\n");
-               return -EINVAL;
-       }
-
        /* interface format */
        switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
        case SND_SOC_DAIFMT_I2S:
@@ -697,18 +698,40 @@ static int adcx140_set_dai_fmt(struct snd_soc_dai *codec_dai,
                iface_reg1 |= ADCX140_LEFT_JUST_BIT;
                break;
        case SND_SOC_DAIFMT_DSP_A:
-               offset += (adcx140->tdm_delay * width + 1);
+               offset = 1;
+               inverted_bclk = true;
                break;
        case SND_SOC_DAIFMT_DSP_B:
-               offset += adcx140->tdm_delay * width;
+               inverted_bclk = true;
                break;
        default:
                dev_err(component->dev, "Invalid DAI interface format\n");
                return -EINVAL;
        }
 
+       /* signal polarity */
+       switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+       case SND_SOC_DAIFMT_IB_NF:
+       case SND_SOC_DAIFMT_IB_IF:
+               inverted_bclk = !inverted_bclk;
+               break;
+       case SND_SOC_DAIFMT_NB_IF:
+               iface_reg1 |= ADCX140_FSYNCINV_BIT;
+               break;
+       case SND_SOC_DAIFMT_NB_NF:
+               break;
+       default:
+               dev_err(component->dev, "Invalid DAI clock signal polarity\n");
+               return -EINVAL;
+       }
+
+       if (inverted_bclk)
+               iface_reg1 |= ADCX140_BCLKINV_BIT;
+
        adcx140->dai_fmt = fmt & SND_SOC_DAIFMT_FORMAT_MASK;
 
+       adcx140_pwr_ctrl(adcx140, false);
+
        snd_soc_component_update_bits(component, ADCX140_ASI_CFG0,
                                      ADCX140_FSYNCINV_BIT |
                                      ADCX140_BCLKINV_BIT |
@@ -721,6 +744,7 @@ static int adcx140_set_dai_fmt(struct snd_soc_dai *codec_dai,
        snd_soc_component_update_bits(component, ADCX140_ASI_CFG1,
                                      ADCX140_TX_OFFSET_MASK, offset);
 
+       adcx140_pwr_ctrl(adcx140, true);
 
        return 0;
 }
@@ -818,12 +842,11 @@ static int adcx140_codec_probe(struct snd_soc_component *component)
 
        ret = device_property_read_u32(adcx140->dev, "ti,mic-bias-source",
                                      &bias_source);
-       if (ret)
+       if (ret || bias_source > ADCX140_MIC_BIAS_VAL_AVDD) {
                bias_source = ADCX140_MIC_BIAS_VAL_VREF;
-
-       if (bias_source > ADCX140_MIC_BIAS_VAL_AVDD) {
-               dev_err(adcx140->dev, "Mic Bias source value is invalid\n");
-               return -EINVAL;
+               adcx140->micbias_vg = false;
+       } else {
+               adcx140->micbias_vg = true;
        }
 
        ret = device_property_read_u32(adcx140->dev, "ti,vref-source",
@@ -906,6 +929,8 @@ static int adcx140_codec_probe(struct snd_soc_component *component)
                                ADCX140_MIC_BIAS_VREF_MSK, bias_cfg);
        if (ret)
                dev_err(adcx140->dev, "setting MIC bias failed %d\n", ret);
+
+       adcx140_pwr_ctrl(adcx140, true);
 out:
        return ret;
 }
@@ -914,21 +939,19 @@ static int adcx140_set_bias_level(struct snd_soc_component *component,
                                  enum snd_soc_bias_level level)
 {
        struct adcx140_priv *adcx140 = snd_soc_component_get_drvdata(component);
-       int pwr_cfg = 0;
 
        switch (level) {
        case SND_SOC_BIAS_ON:
        case SND_SOC_BIAS_PREPARE:
        case SND_SOC_BIAS_STANDBY:
-               pwr_cfg = ADCX140_PWR_CFG_BIAS_PDZ | ADCX140_PWR_CFG_PLL_PDZ |
-                         ADCX140_PWR_CFG_ADC_PDZ;
+               adcx140_pwr_ctrl(adcx140, true);
                break;
        case SND_SOC_BIAS_OFF:
-               pwr_cfg = 0x0;
+               adcx140_pwr_ctrl(adcx140, false);
                break;
        }
 
-       return regmap_write(adcx140->regmap, ADCX140_PWR_CFG, pwr_cfg);
+       return 0;
 }
 
 static const struct snd_soc_component_driver soc_codec_driver_adcx140 = {
index eedbc1d..94c6d1f 100644 (file)
 #define ADCX140_MIC_BIAS_VREF_1375V    2
 #define ADCX140_MIC_BIAS_VREF_MSK GENMASK(1, 0)
 
+#define ADCX140_PWR_CTRL_MSK    GENMASK(7, 5)
 #define ADCX140_PWR_CFG_BIAS_PDZ       BIT(7)
 #define ADCX140_PWR_CFG_ADC_PDZ                BIT(6)
 #define ADCX140_PWR_CFG_PLL_PDZ                BIT(5)
 #define ADCX140_GPO_CFG_MAX            4
 #define ADCX140_GPO_DRV_MAX            5
 
+
 #endif /* _TLV320ADCX140_ */
index 156c153..2f78e68 100644 (file)
@@ -230,7 +230,14 @@ static int clk_aic32x4_pll_set_rate(struct clk_hw *hw,
        if (ret < 0)
                return -EINVAL;
 
-       return clk_aic32x4_pll_set_muldiv(pll, &settings);
+       ret = clk_aic32x4_pll_set_muldiv(pll, &settings);
+       if (ret)
+               return ret;
+
+       /* 10ms is the delay to wait before the clocks are stable */
+       msleep(10);
+
+       return 0;
 }
 
 static int clk_aic32x4_pll_set_parent(struct clk_hw *hw, u8 index)
index 4678028..ea8cd44 100644 (file)
@@ -665,7 +665,7 @@ static int aic32x4_set_processing_blocks(struct snd_soc_component *component,
 }
 
 static int aic32x4_setup_clocks(struct snd_soc_component *component,
-                               unsigned int sample_rate)
+                               unsigned int sample_rate, unsigned int channels)
 {
        u8 aosr;
        u16 dosr;
@@ -753,7 +753,9 @@ static int aic32x4_setup_clocks(struct snd_soc_component *component,
                                                        dosr);
 
                                                clk_set_rate(clocks[5].clk,
-                                                       sample_rate * 32);
+                                                       sample_rate * 32 *
+                                                       channels);
+
                                                return 0;
                                        }
                                }
@@ -775,7 +777,8 @@ static int aic32x4_hw_params(struct snd_pcm_substream *substream,
        u8 iface1_reg = 0;
        u8 dacsetup_reg = 0;
 
-       aic32x4_setup_clocks(component, params_rate(params));
+       aic32x4_setup_clocks(component, params_rate(params),
+                            params_channels(params));
 
        switch (params_width(params)) {
        case 16:
@@ -1010,6 +1013,14 @@ static int aic32x4_component_probe(struct snd_soc_component *component)
                                AIC32X4_LADC_EN | AIC32X4_RADC_EN);
        snd_soc_component_write(component, AIC32X4_ADCSETUP, tmp_reg);
 
+       /*
+        * Enable the fast charging feature and ensure the needed 40ms ellapsed
+        * before using the analog circuits.
+        */
+       snd_soc_component_write(component, AIC32X4_REFPOWERUP,
+                               AIC32X4_REFPOWERUP_40MS);
+       msleep(40);
+
        return 0;
 }
 
index 38f4770..7550122 100644 (file)
@@ -96,6 +96,7 @@ int aic32x4_register_clocks(struct device *dev, const char *mclk_name);
 #define AIC32X4_FLOATINGINPUT  AIC32X4_REG(1, 58)
 #define AIC32X4_LMICPGAVOL     AIC32X4_REG(1, 59)
 #define AIC32X4_RMICPGAVOL     AIC32X4_REG(1, 60)
+#define AIC32X4_REFPOWERUP     AIC32X4_REG(1, 123)
 
 /* Bits, masks, and shifts */
 
@@ -205,6 +206,12 @@ int aic32x4_register_clocks(struct device *dev, const char *mclk_name);
 #define AIC32X4_RMICPGANIN_IN1L_10K    0x10
 #define AIC32X4_RMICPGANIN_CM1R_10K    0x40
 
+/* AIC32X4_REFPOWERUP */
+#define AIC32X4_REFPOWERUP_SLOW                0x04
+#define AIC32X4_REFPOWERUP_40MS                0x05
+#define AIC32X4_REFPOWERUP_80MS                0x06
+#define AIC32X4_REFPOWERUP_120MS       0x07
+
 /* Common mask and enable for all of the dividers */
 #define AIC32X4_DIVEN           BIT(7)
 #define AIC32X4_DIV_MASK        GENMASK(6, 0)
index 410cca5..344bd2c 100644 (file)
@@ -2049,6 +2049,7 @@ int wm_adsp_write_ctl(struct wm_adsp *dsp, const char *name, int type,
 {
        struct wm_coeff_ctl *ctl;
        struct snd_kcontrol *kcontrol;
+       char ctl_name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
        int ret;
 
        ctl = wm_adsp_get_ctl(dsp, name, type, alg);
@@ -2059,8 +2060,25 @@ int wm_adsp_write_ctl(struct wm_adsp *dsp, const char *name, int type,
                return -EINVAL;
 
        ret = wm_coeff_write_ctrl(ctl, buf, len);
+       if (ret)
+               return ret;
+
+       if (ctl->flags & WMFW_CTL_FLAG_SYS)
+               return 0;
+
+       if (dsp->component->name_prefix)
+               snprintf(ctl_name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, "%s %s",
+                        dsp->component->name_prefix, ctl->name);
+       else
+               snprintf(ctl_name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, "%s",
+                        ctl->name);
+
+       kcontrol = snd_soc_card_get_kcontrol(dsp->component->card, ctl_name);
+       if (!kcontrol) {
+               adsp_err(dsp, "Can't find kcontrol %s\n", ctl_name);
+               return -EINVAL;
+       }
 
-       kcontrol = snd_soc_card_get_kcontrol(dsp->component->card, ctl->name);
        snd_ctl_notify(dsp->component->card->snd_card,
                       SNDRV_CTL_EVENT_MASK_VALUE, &kcontrol->id);
 
index a447baf..7ad5925 100644 (file)
@@ -199,10 +199,18 @@ static int fsl_audmix_put_out_src(struct snd_kcontrol *kcontrol,
 
 static const struct snd_kcontrol_new fsl_audmix_snd_controls[] = {
        /* FSL_AUDMIX_CTR controls */
-       SOC_ENUM_EXT("Mixing Clock Source", fsl_audmix_enum[0],
-                    snd_soc_get_enum_double, fsl_audmix_put_mix_clk_src),
-       SOC_ENUM_EXT("Output Source", fsl_audmix_enum[1],
-                    snd_soc_get_enum_double, fsl_audmix_put_out_src),
+       {       .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+               .name = "Mixing Clock Source",
+               .info = snd_soc_info_enum_double,
+               .access = SNDRV_CTL_ELEM_ACCESS_WRITE,
+               .put = fsl_audmix_put_mix_clk_src,
+               .private_value = (unsigned long)&fsl_audmix_enum[0] },
+       {       .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+               .name = "Output Source",
+               .info = snd_soc_info_enum_double,
+               .access = SNDRV_CTL_ELEM_ACCESS_WRITE,
+               .put = fsl_audmix_put_out_src,
+               .private_value = (unsigned long)&fsl_audmix_enum[1] },
        SOC_ENUM("Output Width", fsl_audmix_enum[2]),
        SOC_ENUM("Frame Rate Diff Error", fsl_audmix_enum[3]),
        SOC_ENUM("Clock Freq Diff Error", fsl_audmix_enum[4]),
index cdff739..2ea354d 100644 (file)
@@ -694,7 +694,7 @@ static int fsl_sai_dai_probe(struct snd_soc_dai *cpu_dai)
        return 0;
 }
 
-static struct snd_soc_dai_driver fsl_sai_dai = {
+static struct snd_soc_dai_driver fsl_sai_dai_template = {
        .probe = fsl_sai_dai_probe,
        .playback = {
                .stream_name = "CPU-Playback",
@@ -966,12 +966,15 @@ static int fsl_sai_probe(struct platform_device *pdev)
                return ret;
        }
 
+       memcpy(&sai->cpu_dai_drv, &fsl_sai_dai_template,
+              sizeof(fsl_sai_dai_template));
+
        /* Sync Tx with Rx as default by following old DT binding */
        sai->synchronous[RX] = true;
        sai->synchronous[TX] = false;
-       fsl_sai_dai.symmetric_rates = 1;
-       fsl_sai_dai.symmetric_channels = 1;
-       fsl_sai_dai.symmetric_samplebits = 1;
+       sai->cpu_dai_drv.symmetric_rates = 1;
+       sai->cpu_dai_drv.symmetric_channels = 1;
+       sai->cpu_dai_drv.symmetric_samplebits = 1;
 
        if (of_find_property(np, "fsl,sai-synchronous-rx", NULL) &&
            of_find_property(np, "fsl,sai-asynchronous", NULL)) {
@@ -988,9 +991,9 @@ static int fsl_sai_probe(struct platform_device *pdev)
                /* Discard all settings for asynchronous mode */
                sai->synchronous[RX] = false;
                sai->synchronous[TX] = false;
-               fsl_sai_dai.symmetric_rates = 0;
-               fsl_sai_dai.symmetric_channels = 0;
-               fsl_sai_dai.symmetric_samplebits = 0;
+               sai->cpu_dai_drv.symmetric_rates = 0;
+               sai->cpu_dai_drv.symmetric_channels = 0;
+               sai->cpu_dai_drv.symmetric_samplebits = 0;
        }
 
        if (of_find_property(np, "fsl,sai-mclk-direction-output", NULL) &&
@@ -1020,7 +1023,7 @@ static int fsl_sai_probe(struct platform_device *pdev)
        regcache_cache_only(sai->regmap, true);
 
        ret = devm_snd_soc_register_component(&pdev->dev, &fsl_component,
-                       &fsl_sai_dai, 1);
+                                             &sai->cpu_dai_drv, 1);
        if (ret)
                goto err_pm_disable;
 
index 6aba7d2..677ecfc 100644 (file)
@@ -180,6 +180,7 @@ struct fsl_sai {
        unsigned int bclk_ratio;
 
        const struct fsl_sai_soc_data *soc_data;
+       struct snd_soc_dai_driver cpu_dai_drv;
        struct snd_dmaengine_dai_dma_data dma_params_rx;
        struct snd_dmaengine_dai_dma_data dma_params_tx;
 };
index 06d0a4f..a6c690c 100644 (file)
@@ -673,7 +673,7 @@ static int mt8183_da7219_max98357_dev_probe(struct platform_device *pdev)
                        if (card == &mt8183_da7219_max98357_card) {
                                dai_link->be_hw_params_fixup =
                                        mt8183_i2s_hw_params_fixup;
-                               dai_link->ops = &mt8183_mt6358_i2s_ops;
+                               dai_link->ops = &mt8183_da7219_i2s_ops;
                                dai_link->cpus = i2s3_max98357a_cpus;
                                dai_link->num_cpus =
                                        ARRAY_SIZE(i2s3_max98357a_cpus);
index 5b60379..d1e7dbb 100644 (file)
@@ -592,6 +592,17 @@ static int soc_tplg_kcontrol_bind_io(struct snd_soc_tplg_ctl_hdr *hdr,
                k->info = snd_soc_bytes_info_ext;
                k->tlv.c = snd_soc_bytes_tlv_callback;
 
+               /*
+                * When a topology-based implementation abuses the
+                * control interface and uses bytes_ext controls of
+                * more than 512 bytes, we need to disable the size
+                * checks, otherwise accesses to such controls will
+                * return an -EINVAL error and prevent the card from
+                * being configured.
+                */
+               if (IS_ENABLED(CONFIG_SND_CTL_VALIDATION) && sbe->max > 512)
+                       k->access |= SNDRV_CTL_ELEM_ACCESS_SKIP_CHECK;
+
                ext_ops = tplg->bytes_ext_ops;
                num_ops = tplg->bytes_ext_ops_count;
                for (i = 0; i < num_ops; i++) {