asoc: swr-haptics: Handle VMAX_CLAMP notification
Handle VMAX_CLAMP notification which is notified from charger driver that hBoost is used by the charger firmware and haptics Vmax need to be clamped to a specific level for the following vibrations. Change-Id: I3d783467aad71e0d9b31a96120db7e89fd54c5cb Signed-off-by: Fenglin Wu <quic_fenglinw@quicinc.com>
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
#include <soc/soundwire.h>
|
||||
#include <sound/soc.h>
|
||||
#include <sound/soc-dapm.h>
|
||||
#include <linux/soc/qcom/battery_charger.h>
|
||||
|
||||
#define HAPTICS_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
|
||||
SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\
|
||||
@@ -89,11 +90,13 @@ struct swr_haptics_dev {
|
||||
struct swr_port port;
|
||||
struct regulator *slave_vdd;
|
||||
struct regulator *hpwr_vreg;
|
||||
struct notifier_block hboost_nb;
|
||||
u32 hpwr_voltage_mv;
|
||||
bool slave_enabled;
|
||||
bool hpwr_vreg_enabled;
|
||||
bool ssr_recovery;
|
||||
u8 vmax;
|
||||
u8 clamped_vmax;
|
||||
u8 flags;
|
||||
};
|
||||
|
||||
@@ -254,6 +257,7 @@ static int hap_enable_swr_dac_port(struct snd_soc_dapm_widget *w,
|
||||
snd_soc_dapm_to_component(w->dapm);
|
||||
struct swr_haptics_dev *swr_hap;
|
||||
u8 port_id, ch_mask, num_ch, port_type, num_port;
|
||||
u8 vmax;
|
||||
u32 ch_rate;
|
||||
unsigned int val;
|
||||
int rc;
|
||||
@@ -287,7 +291,11 @@ static int hap_enable_swr_dac_port(struct snd_soc_dapm_widget *w,
|
||||
swr_hap->ssr_recovery = false;
|
||||
}
|
||||
|
||||
rc = regmap_write(swr_hap->regmap, SWR_VMAX_REG, swr_hap->vmax);
|
||||
vmax = swr_hap->vmax;
|
||||
if ((swr_hap->clamped_vmax != 0) && (swr_hap->vmax > swr_hap->clamped_vmax))
|
||||
vmax = swr_hap->clamped_vmax;
|
||||
|
||||
rc = regmap_write(swr_hap->regmap, SWR_VMAX_REG, vmax);
|
||||
if (rc) {
|
||||
dev_err_ratelimited(swr_hap->dev, "%s: SWR_VMAX update failed, rc=%d\n",
|
||||
__func__, rc);
|
||||
@@ -488,6 +496,33 @@ static int swr_haptics_parse_port_mapping(struct swr_device *sdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define MAX_HAPTICS_VMAX_MV 10000
|
||||
#define VMAX_STEP_MV 50
|
||||
static int hboost_notifier(struct notifier_block *nb, unsigned long event, void *val)
|
||||
{
|
||||
struct swr_haptics_dev *swr_hap = container_of(nb, struct swr_haptics_dev, hboost_nb);
|
||||
u32 vmax_mv;
|
||||
|
||||
switch (event) {
|
||||
case VMAX_CLAMP:
|
||||
vmax_mv = *(u32 *)val;
|
||||
if (vmax_mv > MAX_HAPTICS_VMAX_MV) {
|
||||
dev_err_ratelimited(swr_hap->dev, "%s: voted Vmax (%u mv) is higher than maximum (%u mv)\n",
|
||||
__func__, vmax_mv, MAX_HAPTICS_VMAX_MV);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
dev_dbg(swr_hap->dev, "%s: Vmax is clamped at %u mv to support hBoost concurrency\n",
|
||||
__func__, vmax_mv);
|
||||
swr_hap->clamped_vmax = vmax_mv / VMAX_STEP_MV;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int swr_haptics_probe(struct swr_device *sdev)
|
||||
{
|
||||
struct swr_haptics_dev *swr_hap;
|
||||
@@ -584,6 +619,8 @@ static int swr_haptics_probe(struct swr_device *sdev)
|
||||
goto dev_err;
|
||||
}
|
||||
|
||||
swr_hap->hboost_nb.notifier_call = hboost_notifier;
|
||||
register_hboost_event_notifier(&swr_hap->hboost_nb);
|
||||
return 0;
|
||||
dev_err:
|
||||
swr_haptics_slave_disable(swr_hap);
|
||||
@@ -605,6 +642,7 @@ static int swr_haptics_remove(struct swr_device *sdev)
|
||||
goto clean;
|
||||
}
|
||||
|
||||
unregister_hboost_event_notifier(&swr_hap->hboost_nb);
|
||||
rc = swr_haptics_slave_disable(swr_hap);
|
||||
if (rc < 0) {
|
||||
dev_err(swr_hap->dev, "%s: disable swr-slave failed, rc=%d\n",
|
||||
|
Reference in New Issue
Block a user