mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-11 23:24:22 -04:00
Merge "asoc: swr-haptics: Toggle swr-slave-vdd supply for SSR recovery"
This commit is contained in:
commit
3075f30b7f
1 changed files with 85 additions and 38 deletions
|
|
@ -6,6 +6,7 @@
|
|||
#include <linux/device.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
|
|
@ -41,6 +42,14 @@
|
|||
|
||||
#define SWR_HAP_REG_MAX (SWR_HAP_ACCESS_BASE + 0xff)
|
||||
|
||||
enum pmic_type {
|
||||
PM8350B = 1,
|
||||
};
|
||||
|
||||
enum {
|
||||
HAP_SSR_RECOVERY = BIT(0),
|
||||
};
|
||||
|
||||
static struct reg_default swr_hap_reg_defaults[] = {
|
||||
{FIFO_WR_READY_REG, 1},
|
||||
{NUM_PAT_SMPL_REG, 8},
|
||||
|
|
@ -76,12 +85,14 @@ struct swr_haptics_dev {
|
|||
struct snd_soc_component *component;
|
||||
struct regmap *regmap;
|
||||
struct swr_port port;
|
||||
struct regulator *vdd;
|
||||
u32 enable_cnt;
|
||||
struct regulator *slave_vdd;
|
||||
struct regulator *hpwr_vreg;
|
||||
u32 hpwr_voltage_mv;
|
||||
bool slave_enabled;
|
||||
bool hpwr_vreg_enabled;
|
||||
bool ssr_recovery;
|
||||
u8 vmax;
|
||||
u8 flags;
|
||||
};
|
||||
|
||||
static bool swr_hap_volatile_register(struct device *dev, unsigned int reg)
|
||||
|
|
@ -168,6 +179,44 @@ static int swr_hap_enable_hpwr_vreg(struct swr_haptics_dev *swr_hap, bool en)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int swr_haptics_slave_enable(struct swr_haptics_dev *swr_hap)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (swr_hap->slave_enabled)
|
||||
return 0;
|
||||
|
||||
rc = regulator_enable(swr_hap->slave_vdd);
|
||||
if (rc < 0) {
|
||||
dev_err(swr_hap->dev, "%s: enable swr-slave-vdd failed, rc=%d\n",
|
||||
__func__, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
dev_dbg(swr_hap->dev, "%s: enable swr-slave-vdd success\n", __func__);
|
||||
swr_hap->slave_enabled = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int swr_haptics_slave_disable(struct swr_haptics_dev *swr_hap)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (!swr_hap->slave_enabled)
|
||||
return 0;
|
||||
|
||||
rc = regulator_disable(swr_hap->slave_vdd);
|
||||
if (rc < 0) {
|
||||
dev_err(swr_hap->dev, "%s: disable swr-slave-vdd failed, rc=%d\n",
|
||||
__func__, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
dev_dbg(swr_hap->dev, "%s: disable swr-slave-vdd success\n", __func__);
|
||||
swr_hap->slave_enabled = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct regmap_config swr_hap_regmap_config = {
|
||||
.reg_bits = 16,
|
||||
.val_bits = 8,
|
||||
|
|
@ -219,6 +268,14 @@ static int hap_enable_swr_dac_port(struct snd_soc_dapm_widget *w,
|
|||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_PRE_PMU:
|
||||
/* If SSR ever happened, toggle swr-slave-vdd for HW recovery */
|
||||
if ((swr_hap->flags & HAP_SSR_RECOVERY)
|
||||
&& swr_hap->ssr_recovery) {
|
||||
swr_haptics_slave_disable(swr_hap);
|
||||
swr_haptics_slave_enable(swr_hap);
|
||||
swr_hap->ssr_recovery = false;
|
||||
}
|
||||
|
||||
rc = regmap_write(swr_hap->regmap, SWR_VMAX_REG, swr_hap->vmax);
|
||||
if (rc) {
|
||||
dev_err(swr_hap->dev, "%s: SWR_VMAX update failed, rc=%d\n",
|
||||
|
|
@ -426,6 +483,7 @@ static int swr_haptics_probe(struct swr_device *sdev)
|
|||
struct device_node *node = sdev->dev.of_node;
|
||||
int rc;
|
||||
u8 devnum;
|
||||
u32 pmic_type;
|
||||
int retry = 5;
|
||||
|
||||
swr_hap = devm_kzalloc(&sdev->dev,
|
||||
|
|
@ -437,8 +495,11 @@ static int swr_haptics_probe(struct swr_device *sdev)
|
|||
swr_hap->vmax = 100;
|
||||
swr_hap->swr_slave = sdev;
|
||||
swr_hap->dev = &sdev->dev;
|
||||
pmic_type = (uintptr_t)of_device_get_match_data(swr_hap->dev);
|
||||
if (pmic_type == PM8350B)
|
||||
swr_hap->flags |= HAP_SSR_RECOVERY;
|
||||
|
||||
swr_set_dev_data(sdev, swr_hap);
|
||||
swr_hap->enable_cnt = 0;
|
||||
|
||||
rc = swr_haptics_parse_port_mapping(sdev);
|
||||
if (rc < 0) {
|
||||
|
|
@ -447,9 +508,9 @@ static int swr_haptics_probe(struct swr_device *sdev)
|
|||
goto clean;
|
||||
}
|
||||
|
||||
swr_hap->vdd = devm_regulator_get(swr_hap->dev, "swr-slave");
|
||||
if (IS_ERR(swr_hap->vdd)) {
|
||||
rc = PTR_ERR(swr_hap->vdd);
|
||||
swr_hap->slave_vdd = devm_regulator_get(swr_hap->dev, "swr-slave");
|
||||
if (IS_ERR(swr_hap->slave_vdd)) {
|
||||
rc = PTR_ERR(swr_hap->slave_vdd);
|
||||
if (rc != -EPROBE_DEFER)
|
||||
dev_err(swr_hap->dev, "%s: get swr-slave-supply failed, rc=%d\n",
|
||||
__func__, rc);
|
||||
|
|
@ -476,7 +537,7 @@ static int swr_haptics_probe(struct swr_device *sdev)
|
|||
}
|
||||
}
|
||||
|
||||
rc = regulator_enable(swr_hap->vdd);
|
||||
rc = swr_haptics_slave_enable(swr_hap);
|
||||
if (rc < 0) {
|
||||
dev_err(swr_hap->dev, "%s: enable swr-slave-vdd failed, rc=%d\n",
|
||||
__func__, rc);
|
||||
|
|
@ -492,7 +553,7 @@ static int swr_haptics_probe(struct swr_device *sdev)
|
|||
dev_err(swr_hap->dev, "%s: failed to get devnum for swr-haptics, rc=%d\n",
|
||||
__func__, rc);
|
||||
rc = -EPROBE_DEFER;
|
||||
goto clean;
|
||||
goto dev_err;
|
||||
}
|
||||
|
||||
sdev->dev_num = devnum;
|
||||
|
|
@ -514,7 +575,7 @@ static int swr_haptics_probe(struct swr_device *sdev)
|
|||
|
||||
return 0;
|
||||
dev_err:
|
||||
regulator_disable(swr_hap->vdd);
|
||||
swr_haptics_slave_disable(swr_hap);
|
||||
swr_remove_device(sdev);
|
||||
clean:
|
||||
swr_set_dev_data(sdev, NULL);
|
||||
|
|
@ -533,7 +594,7 @@ static int swr_haptics_remove(struct swr_device *sdev)
|
|||
goto clean;
|
||||
}
|
||||
|
||||
rc = regulator_disable(swr_hap->vdd);
|
||||
rc = swr_haptics_slave_disable(swr_hap);
|
||||
if (rc < 0) {
|
||||
dev_err(swr_hap->dev, "%s: disable swr-slave failed, rc=%d\n",
|
||||
__func__, rc);
|
||||
|
|
@ -548,7 +609,6 @@ clean:
|
|||
static int swr_haptics_device_up(struct swr_device *sdev)
|
||||
{
|
||||
struct swr_haptics_dev *swr_hap;
|
||||
int rc;
|
||||
|
||||
swr_hap = swr_get_dev_data(sdev);
|
||||
if (!swr_hap) {
|
||||
|
|
@ -556,17 +616,11 @@ static int swr_haptics_device_up(struct swr_device *sdev)
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* Take SWR slave out of reset */
|
||||
rc = regulator_enable(swr_hap->vdd);
|
||||
if (rc < 0) {
|
||||
dev_err(swr_hap->dev, "%s: enable swr-slave failed, rc=%d\n",
|
||||
__func__, rc);
|
||||
return rc;
|
||||
} else {
|
||||
swr_hap->enable_cnt++;
|
||||
}
|
||||
if (swr_hap->flags & HAP_SSR_RECOVERY)
|
||||
swr_hap->ssr_recovery = true;
|
||||
|
||||
return 0;
|
||||
/* Take SWR slave out of reset */
|
||||
return swr_haptics_slave_enable(swr_hap);
|
||||
}
|
||||
|
||||
static int swr_haptics_device_down(struct swr_device *sdev)
|
||||
|
|
@ -579,20 +633,6 @@ static int swr_haptics_device_down(struct swr_device *sdev)
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* Put SWR slave into reset */
|
||||
if (swr_hap->enable_cnt > 0) {
|
||||
rc = regulator_disable(swr_hap->vdd);
|
||||
if (rc < 0) {
|
||||
dev_err(swr_hap->dev, "%s: disable swr-slave failed, rc=%d\n",
|
||||
__func__, rc);
|
||||
return rc;
|
||||
} else {
|
||||
swr_hap->enable_cnt--;
|
||||
}
|
||||
} else {
|
||||
swr_hap->enable_cnt = 0;
|
||||
}
|
||||
|
||||
/* Disable HAP_PWR regulator */
|
||||
rc = swr_hap_enable_hpwr_vreg(swr_hap, false);
|
||||
if (rc < 0) {
|
||||
|
|
@ -601,7 +641,8 @@ static int swr_haptics_device_down(struct swr_device *sdev)
|
|||
return rc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
/* Put SWR slave into reset */
|
||||
return swr_haptics_slave_disable(swr_hap);
|
||||
}
|
||||
|
||||
static int swr_haptics_suspend(struct device *dev)
|
||||
|
|
@ -635,8 +676,14 @@ static int swr_haptics_resume(struct device *dev)
|
|||
}
|
||||
|
||||
static const struct of_device_id swr_haptics_match_table[] = {
|
||||
{ .compatible = "qcom,swr-haptics", },
|
||||
{ .compatible = "qcom,pm8350b-swr-haptics", },
|
||||
{
|
||||
.compatible = "qcom,swr-haptics",
|
||||
.data = NULL,
|
||||
},
|
||||
{
|
||||
.compatible = "qcom,pm8350b-swr-haptics",
|
||||
.data = (void *)PM8350B,
|
||||
},
|
||||
{ },
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue