Loading sound/soc/codecs/wsa881x-regmap.c +1 −0 Original line number Diff line number Diff line Loading @@ -281,6 +281,7 @@ static bool wsa881x_volatile_register(struct device *dev, unsigned int reg) case WSA881X_TEMP_DOUT_LSB: case WSA881X_TEMP_OP: case WSA881X_SPKR_PROT_SAR: case WSA881X_SPKR_OCP_CTL: return true; default: return false; Loading sound/soc/codecs/wsa881x.c +32 −1 Original line number Diff line number Diff line Loading @@ -98,6 +98,7 @@ struct wsa881x_priv { struct snd_info_entry *entry; struct snd_info_entry *version_entry; int state; struct delayed_work ocp_ctl_work; }; #define SWR_SLV_MAX_REG_ADDR 0x390 Loading @@ -109,6 +110,8 @@ struct wsa881x_priv { #define SWR_SLV_MAX_DEVICES 2 #define WSA881X_VERSION_ENTRY_SIZE 27 #define WSA881X_OCP_CTL_TIMER_SEC 2 #define WSA881X_OCP_CTL_TEMP_CELSIUS 25 static struct wsa881x_priv *dbgwsa881x; static struct dentry *debugfs_wsa881x_dent; Loading Loading @@ -487,12 +490,15 @@ static void wsa881x_bandgap_ctrl(struct snd_soc_codec *codec, bool enable) 0x08, 0x08); /* 400usec sleep is needed as per HW requirement */ usleep_range(400, 410); snd_soc_update_bits(codec, WSA881X_TEMP_OP, 0x04, 0x04); } } else { --wsa881x->bg_cnt; if (wsa881x->bg_cnt <= 0) { WARN_ON(wsa881x->bg_cnt < 0); wsa881x->bg_cnt = 0; snd_soc_update_bits(codec, WSA881X_TEMP_OP, 0x04, 0x00); snd_soc_update_bits(codec, WSA881X_TEMP_OP, 0x08, 0x00); } } Loading Loading @@ -738,6 +744,26 @@ static int wsa881x_ramp_pa_gain(struct snd_soc_codec *codec, return 0; } static void wsa881x_ocp_ctl_work(struct work_struct *work) { struct wsa881x_priv *wsa881x; struct delayed_work *dwork; struct snd_soc_codec *codec; unsigned long temp_val; dwork = to_delayed_work(work); wsa881x = container_of(dwork, struct wsa881x_priv, ocp_ctl_work); codec = wsa881x->codec; wsa881x_get_temp(wsa881x->tz_pdata.tz_dev, &temp_val); dev_dbg(codec->dev, " temp = %ld\n", temp_val); if (temp_val <= WSA881X_OCP_CTL_TEMP_CELSIUS) snd_soc_update_bits(codec, WSA881X_SPKR_OCP_CTL, 0xC0, 0x00); else snd_soc_update_bits(codec, WSA881X_SPKR_OCP_CTL, 0xC0, 0xC0); } static int wsa881x_spkr_pa_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { Loading @@ -747,6 +773,7 @@ static int wsa881x_spkr_pa_event(struct snd_soc_dapm_widget *w, dev_dbg(codec->dev, "%s: %s %d\n", __func__, w->name, event); switch (event) { case SND_SOC_DAPM_PRE_PMU: snd_soc_update_bits(codec, WSA881X_SPKR_OCP_CTL, 0xC0, 0x80); if (WSA881X_IS_2_0(wsa881x->version)) regmap_multi_reg_write(wsa881x->regmap, wsa881x_pre_pmu_pa_2_0, Loading Loading @@ -789,6 +816,8 @@ static int wsa881x_spkr_pa_event(struct snd_soc_dapm_widget *w, 0x07, 0x01); wsa881x_visense_adc_ctrl(codec, ENABLE); } schedule_delayed_work(&wsa881x->ocp_ctl_work, msecs_to_jiffies(WSA881X_OCP_CTL_TIMER_SEC * 1000)); break; case SND_SOC_DAPM_POST_PMD: if (wsa881x->visense_enable) { Loading @@ -796,6 +825,8 @@ static int wsa881x_spkr_pa_event(struct snd_soc_dapm_widget *w, wsa881x_visense_txfe_ctrl(codec, DISABLE, 0x00, 0x01, 0x01); } cancel_delayed_work_sync(&wsa881x->ocp_ctl_work); snd_soc_update_bits(codec, WSA881X_SPKR_OCP_CTL, 0xC0, 0xC0); break; } return 0; Loading Loading @@ -940,7 +971,6 @@ static int32_t wsa881x_temp_reg_read(struct snd_soc_codec *codec, regcache_sync(wsa881x->regmap); wsa881x_resource_acquire(codec, ENABLE); snd_soc_update_bits(codec, WSA881X_TEMP_OP, 0x04, 0x04); if (WSA881X_IS_2_0(wsa881x->version)) { snd_soc_update_bits(codec, WSA881X_TADC_VALUE_CTL, 0x01, 0x00); wsa_temp_reg->dmeas_msb = snd_soc_read(codec, WSA881X_TEMP_MSB); Loading Loading @@ -984,6 +1014,7 @@ static int wsa881x_probe(struct snd_soc_codec *codec) wsa881x->tz_pdata.codec = codec; wsa881x->tz_pdata.wsa_temp_reg_read = wsa881x_temp_reg_read; wsa881x_init_thermal(&wsa881x->tz_pdata); INIT_DELAYED_WORK(&wsa881x->ocp_ctl_work, wsa881x_ocp_ctl_work); return 0; } Loading Loading
sound/soc/codecs/wsa881x-regmap.c +1 −0 Original line number Diff line number Diff line Loading @@ -281,6 +281,7 @@ static bool wsa881x_volatile_register(struct device *dev, unsigned int reg) case WSA881X_TEMP_DOUT_LSB: case WSA881X_TEMP_OP: case WSA881X_SPKR_PROT_SAR: case WSA881X_SPKR_OCP_CTL: return true; default: return false; Loading
sound/soc/codecs/wsa881x.c +32 −1 Original line number Diff line number Diff line Loading @@ -98,6 +98,7 @@ struct wsa881x_priv { struct snd_info_entry *entry; struct snd_info_entry *version_entry; int state; struct delayed_work ocp_ctl_work; }; #define SWR_SLV_MAX_REG_ADDR 0x390 Loading @@ -109,6 +110,8 @@ struct wsa881x_priv { #define SWR_SLV_MAX_DEVICES 2 #define WSA881X_VERSION_ENTRY_SIZE 27 #define WSA881X_OCP_CTL_TIMER_SEC 2 #define WSA881X_OCP_CTL_TEMP_CELSIUS 25 static struct wsa881x_priv *dbgwsa881x; static struct dentry *debugfs_wsa881x_dent; Loading Loading @@ -487,12 +490,15 @@ static void wsa881x_bandgap_ctrl(struct snd_soc_codec *codec, bool enable) 0x08, 0x08); /* 400usec sleep is needed as per HW requirement */ usleep_range(400, 410); snd_soc_update_bits(codec, WSA881X_TEMP_OP, 0x04, 0x04); } } else { --wsa881x->bg_cnt; if (wsa881x->bg_cnt <= 0) { WARN_ON(wsa881x->bg_cnt < 0); wsa881x->bg_cnt = 0; snd_soc_update_bits(codec, WSA881X_TEMP_OP, 0x04, 0x00); snd_soc_update_bits(codec, WSA881X_TEMP_OP, 0x08, 0x00); } } Loading Loading @@ -738,6 +744,26 @@ static int wsa881x_ramp_pa_gain(struct snd_soc_codec *codec, return 0; } static void wsa881x_ocp_ctl_work(struct work_struct *work) { struct wsa881x_priv *wsa881x; struct delayed_work *dwork; struct snd_soc_codec *codec; unsigned long temp_val; dwork = to_delayed_work(work); wsa881x = container_of(dwork, struct wsa881x_priv, ocp_ctl_work); codec = wsa881x->codec; wsa881x_get_temp(wsa881x->tz_pdata.tz_dev, &temp_val); dev_dbg(codec->dev, " temp = %ld\n", temp_val); if (temp_val <= WSA881X_OCP_CTL_TEMP_CELSIUS) snd_soc_update_bits(codec, WSA881X_SPKR_OCP_CTL, 0xC0, 0x00); else snd_soc_update_bits(codec, WSA881X_SPKR_OCP_CTL, 0xC0, 0xC0); } static int wsa881x_spkr_pa_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { Loading @@ -747,6 +773,7 @@ static int wsa881x_spkr_pa_event(struct snd_soc_dapm_widget *w, dev_dbg(codec->dev, "%s: %s %d\n", __func__, w->name, event); switch (event) { case SND_SOC_DAPM_PRE_PMU: snd_soc_update_bits(codec, WSA881X_SPKR_OCP_CTL, 0xC0, 0x80); if (WSA881X_IS_2_0(wsa881x->version)) regmap_multi_reg_write(wsa881x->regmap, wsa881x_pre_pmu_pa_2_0, Loading Loading @@ -789,6 +816,8 @@ static int wsa881x_spkr_pa_event(struct snd_soc_dapm_widget *w, 0x07, 0x01); wsa881x_visense_adc_ctrl(codec, ENABLE); } schedule_delayed_work(&wsa881x->ocp_ctl_work, msecs_to_jiffies(WSA881X_OCP_CTL_TIMER_SEC * 1000)); break; case SND_SOC_DAPM_POST_PMD: if (wsa881x->visense_enable) { Loading @@ -796,6 +825,8 @@ static int wsa881x_spkr_pa_event(struct snd_soc_dapm_widget *w, wsa881x_visense_txfe_ctrl(codec, DISABLE, 0x00, 0x01, 0x01); } cancel_delayed_work_sync(&wsa881x->ocp_ctl_work); snd_soc_update_bits(codec, WSA881X_SPKR_OCP_CTL, 0xC0, 0xC0); break; } return 0; Loading Loading @@ -940,7 +971,6 @@ static int32_t wsa881x_temp_reg_read(struct snd_soc_codec *codec, regcache_sync(wsa881x->regmap); wsa881x_resource_acquire(codec, ENABLE); snd_soc_update_bits(codec, WSA881X_TEMP_OP, 0x04, 0x04); if (WSA881X_IS_2_0(wsa881x->version)) { snd_soc_update_bits(codec, WSA881X_TADC_VALUE_CTL, 0x01, 0x00); wsa_temp_reg->dmeas_msb = snd_soc_read(codec, WSA881X_TEMP_MSB); Loading Loading @@ -984,6 +1014,7 @@ static int wsa881x_probe(struct snd_soc_codec *codec) wsa881x->tz_pdata.codec = codec; wsa881x->tz_pdata.wsa_temp_reg_read = wsa881x_temp_reg_read; wsa881x_init_thermal(&wsa881x->tz_pdata); INIT_DELAYED_WORK(&wsa881x->ocp_ctl_work, wsa881x_ocp_ctl_work); return 0; } Loading