Merge "ASoC: wsa883x: Add support for VBAT monitor" into audio-drivers.lnx.5.0

This commit is contained in:
Linux Build Service Account
2020-01-08 17:20:33 -08:00
committed by Gerrit - the friendly Code Review server
2 changed files with 57 additions and 5 deletions

View File

@@ -118,6 +118,7 @@ struct wsa883x_priv {
void *handle;
int (*register_notifier)(void *handle,
struct notifier_block *nblock, bool enable);
struct delayed_work vbat_work;
};
#endif /* WSA883X_INTERNAL_H */

View File

@@ -35,6 +35,11 @@
#define HIGH_TEMP_THRESHOLD 45
#define TEMP_INVALID 0xFFFF
#define WSA883X_TEMP_RETRY 3
#define WSA883X_VBAT_TIMER_SEC 2
static int wsa883x_vbat_timer_sec = WSA883X_VBAT_TIMER_SEC;
module_param(wsa883x_vbat_timer_sec, int, 0664);
MODULE_PARM_DESC(wsa883x_vbat_timer_sec, "timer for VBAT monitor polling");
#define DRV_NAME "wsa-codec"
@@ -875,17 +880,29 @@ static int wsa883x_spkr_event(struct snd_soc_dapm_widget *w,
dev_dbg(component->dev, "%s: %s %d\n", __func__, w->name, event);
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
case SND_SOC_DAPM_POST_PMU:
snd_soc_component_update_bits(component, WSA883X_PA_FSM_CTL,
0x01, 0x01);
break;
case SND_SOC_DAPM_POST_PMU:
/* Force remove group */
swr_remove_from_group(wsa883x->swr_slave,
wsa883x->swr_slave->dev_num);
snd_soc_component_update_bits(component,
WSA883X_VBAT_ADC_FLT_CTL,
0x0E, 0x06);
snd_soc_component_update_bits(component,
WSA883X_VBAT_ADC_FLT_CTL,
0x01, 0x01);
schedule_delayed_work(&wsa883x->vbat_work,
msecs_to_jiffies(wsa883x_vbat_timer_sec * 1000));
break;
case SND_SOC_DAPM_POST_PMD:
case SND_SOC_DAPM_PRE_PMD:
cancel_delayed_work_sync(&wsa883x->vbat_work);
snd_soc_component_update_bits(component,
WSA883X_VBAT_ADC_FLT_CTL,
0x01, 0x00);
snd_soc_component_update_bits(component,
WSA883X_VBAT_ADC_FLT_CTL,
0x0E, 0x00);
snd_soc_component_update_bits(component, WSA883X_PA_FSM_CTL,
0x01, 0x00);
break;
@@ -1053,6 +1070,37 @@ static int wsa883x_get_temperature(struct snd_soc_component *component,
return ret;
}
static void wsa883x_vbat_monitor_work(struct work_struct *work)
{
struct wsa883x_priv *wsa883x;
struct delayed_work *dwork;
struct snd_soc_component *component;
u16 val = 0, vbat_code = 0;
int vbat_val = 0;
dwork = to_delayed_work(work);
wsa883x = container_of(dwork, struct wsa883x_priv, vbat_work);
component = wsa883x->component;
val = snd_soc_component_read32(component, WSA883X_VBAT_DIN_MSB);
vbat_code = (val << 2);
val = (snd_soc_component_read32(component, WSA883X_VBAT_DIN_LSB)
& 0xC0);
vbat_code |= (val >> 6);
vbat_val = ((vbat_code * 5) / 1023);
dev_dbg(component->dev, "%s: instant vbat code = %d val = %d\n",
__func__, vbat_code, vbat_val);
val = snd_soc_component_read32(component, WSA883X_VBAT_DOUT);
vbat_val = ((val * 5) / 255);
dev_dbg(component->dev, "%s: low pass vbat code = %d val = %d\n",
__func__, val, vbat_val);
schedule_delayed_work(&wsa883x->vbat_work,
msecs_to_jiffies(wsa883x_vbat_timer_sec * 1000));
}
static int wsa883x_codec_probe(struct snd_soc_component *component)
{
struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component);
@@ -1066,6 +1114,7 @@ static int wsa883x_codec_probe(struct snd_soc_component *component)
wsa883x->component = component;
wsa883x_codec_init(component);
wsa883x->global_pa_cnt = 0;
INIT_DELAYED_WORK(&wsa883x->vbat_work, wsa883x_vbat_monitor_work);
return 0;
}
@@ -1124,6 +1173,8 @@ static int wsa883x_event_notify(struct notifier_block *nb,
switch (event) {
case BOLERO_WSA_EVT_PA_OFF_PRE_SSR:
if (delayed_work_pending(&wsa883x->vbat_work))
cancel_delayed_work_sync(&wsa883x->vbat_work);
snd_soc_component_update_bits(wsa883x->component,
WSA883X_PA_FSM_CTL,
0x01, 0x00);