Loading MAINTAINERS +1 −0 Original line number Diff line number Diff line Loading @@ -4170,6 +4170,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* Loading sound/soc/codecs/cs47l15.c +1 −1 Original line number Diff line number Diff line Loading @@ -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" }, Loading Loading @@ -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) Loading sound/soc/codecs/cs47l35.c +1 −1 Original line number Diff line number Diff line Loading @@ -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" }, Loading Loading @@ -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) Loading sound/soc/codecs/rt1015.c +90 −21 Original line number Diff line number Diff line Loading @@ -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) { Loading @@ -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"); Loading @@ -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), Loading Loading @@ -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); } break; case SND_SOC_DAPM_POST_PMD: Loading @@ -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: Loading @@ -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), Loading Loading @@ -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"), }; Loading @@ -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, Loading Loading @@ -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; } Loading @@ -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); } Loading Loading @@ -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, Loading sound/soc/codecs/rt1015.h +8 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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__ */ Loading
MAINTAINERS +1 −0 Original line number Diff line number Diff line Loading @@ -4170,6 +4170,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* Loading
sound/soc/codecs/cs47l15.c +1 −1 Original line number Diff line number Diff line Loading @@ -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" }, Loading Loading @@ -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) Loading
sound/soc/codecs/cs47l35.c +1 −1 Original line number Diff line number Diff line Loading @@ -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" }, Loading Loading @@ -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) Loading
sound/soc/codecs/rt1015.c +90 −21 Original line number Diff line number Diff line Loading @@ -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) { Loading @@ -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"); Loading @@ -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), Loading Loading @@ -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); } break; case SND_SOC_DAPM_POST_PMD: Loading @@ -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: Loading @@ -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), Loading Loading @@ -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"), }; Loading @@ -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, Loading Loading @@ -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; } Loading @@ -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); } Loading Loading @@ -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, Loading
sound/soc/codecs/rt1015.h +8 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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__ */