Loading asoc/codecs/swr-haptics.c +85 −38 Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -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}, Loading Loading @@ -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) Loading Loading @@ -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, Loading Loading @@ -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", Loading Loading @@ -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, Loading @@ -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) { Loading @@ -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); Loading @@ -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); Loading @@ -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; Loading @@ -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); Loading @@ -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); Loading @@ -548,7 +609,6 @@ static int swr_haptics_remove(struct swr_device *sdev) 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) { Loading @@ -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) Loading @@ -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) { Loading @@ -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) Loading Loading @@ -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 Loading
asoc/codecs/swr-haptics.c +85 −38 Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -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}, Loading Loading @@ -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) Loading Loading @@ -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, Loading Loading @@ -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", Loading Loading @@ -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, Loading @@ -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) { Loading @@ -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); Loading @@ -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); Loading @@ -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; Loading @@ -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); Loading @@ -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); Loading @@ -548,7 +609,6 @@ static int swr_haptics_remove(struct swr_device *sdev) 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) { Loading @@ -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) Loading @@ -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) { Loading @@ -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) Loading Loading @@ -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