asoc: swr-haptics: add non-HBoost regulator support

Haptics module is supplied by HBoost regulator by default, it requests
voltage to HBoost regulator through hardware channel. Haptics module
can also be configured to use other regulator device, in this case, it
requires software to request the voltage from the regulator before
enabling the play. Add support for this.

Change-Id: I4a8305ff2732a92bc8be90bd3ed197fa643a101e
Signed-off-by: Fenglin Wu <fenglinw@codeaurora.org>
This commit is contained in:
Fenglin Wu 2020-10-13 18:07:35 +08:00
parent 27e52b9f18
commit 2f2e85ea28

View File

@ -78,6 +78,9 @@ struct swr_haptics_dev {
struct swr_port port;
struct regulator *vdd;
u32 enable_cnt;
struct regulator *hpwr_vreg;
u32 hpwr_voltage_mv;
bool hpwr_vreg_enabled;
};
static bool swr_hap_volatile_register(struct device *dev, unsigned int reg)
@ -119,6 +122,51 @@ static bool swr_hap_writeable_register(struct device *dev, unsigned int reg)
return 1;
}
static int swr_hap_enable_hpwr_vreg(struct swr_haptics_dev *swr_hap, bool en)
{
int rc;
if (swr_hap->hpwr_vreg == NULL || swr_hap->hpwr_vreg_enabled == en)
return 0;
if (en) {
rc = regulator_set_voltage(swr_hap->hpwr_vreg,
swr_hap->hpwr_voltage_mv * 1000, INT_MAX);
if (rc < 0) {
dev_err(swr_hap->dev, "%s: Set hpwr voltage failed, rc=%d\n",
__func__, rc);
return rc;
}
rc = regulator_enable(swr_hap->hpwr_vreg);
if (rc < 0) {
dev_err(swr_hap->dev, "%s: Enable hpwr failed, rc=%d\n",
__func__, rc);
regulator_set_voltage(swr_hap->hpwr_vreg, 0, INT_MAX);
return rc;
}
} else {
rc = regulator_disable(swr_hap->hpwr_vreg);
if (rc < 0) {
dev_err(swr_hap->dev, "%s: Disable hpwr failed, rc=%d\n",
__func__, rc);
return rc;
}
rc = regulator_set_voltage(swr_hap->hpwr_vreg, 0, INT_MAX);
if (rc < 0) {
dev_err(swr_hap->dev, "%s: Set hpwr voltage failed, rc=%d\n",
__func__, rc);
return rc;
}
}
dev_dbg(swr_hap->dev, "%s: swr-haptics: %s hpwr_regulator\n",
__func__, en ? "enabled" : "disabled");
swr_hap->hpwr_vreg_enabled = en;
return 0;
}
struct regmap_config swr_hap_regmap_config = {
.reg_bits = 16,
.val_bits = 8,
@ -175,6 +223,13 @@ static int hap_enable_swr_dac_port(struct snd_soc_dapm_widget *w,
&ch_mask, &ch_rate, &num_ch, &port_type);
break;
case SND_SOC_DAPM_POST_PMU:
rc = swr_hap_enable_hpwr_vreg(swr_hap, true);
if (rc < 0) {
dev_err(swr_hap->dev, "%s: Enable hpwr_vreg failed, rc=%d\n",
__func__, rc);
return rc;
}
swr_slvdev_datapath_control(swr_hap->swr_slave,
swr_hap->swr_slave->dev_num, true);
/* trigger SWR play */
@ -183,6 +238,9 @@ static int hap_enable_swr_dac_port(struct snd_soc_dapm_widget *w,
if (rc) {
dev_err(swr_hap->dev, "%s: Enable SWR_PLAY failed, rc=%d\n",
__func__, rc);
swr_slvdev_datapath_control(swr_hap->swr_slave,
swr_hap->swr_slave->dev_num, false);
swr_hap_enable_hpwr_vreg(swr_hap, false);
return rc;
}
break;
@ -195,6 +253,13 @@ static int hap_enable_swr_dac_port(struct snd_soc_dapm_widget *w,
__func__, rc);
return rc;
}
rc = swr_hap_enable_hpwr_vreg(swr_hap, false);
if (rc < 0) {
dev_err(swr_hap->dev, "%s: Disable hpwr_vreg failed, rc=%d\n",
__func__, rc);
return rc;
}
break;
case SND_SOC_DAPM_POST_PMD:
swr_disconnect_port(swr_hap->swr_slave, &port_id, num_port,
@ -313,6 +378,7 @@ static int swr_haptics_parse_port_mapping(struct swr_device *sdev)
static int swr_haptics_probe(struct swr_device *sdev)
{
struct swr_haptics_dev *swr_hap;
struct device_node *node = sdev->dev.of_node;
int rc;
u8 devnum;
int retry = 5;
@ -343,6 +409,26 @@ static int swr_haptics_probe(struct swr_device *sdev)
goto clean;
}
if (of_find_property(node, "qcom,hpwr-supply", NULL)) {
swr_hap->hpwr_vreg = devm_regulator_get(swr_hap->dev,
"qcom,hpwr");
if (IS_ERR(swr_hap->hpwr_vreg)) {
rc = PTR_ERR(swr_hap->hpwr_vreg);
if (rc != -EPROBE_DEFER)
dev_err(swr_hap->dev, "%s: Get qcom,hpwr-supply failed, rc=%d\n",
__func__, rc);
goto clean;
}
rc = of_property_read_u32(node, "qcom,hpwr-voltage-mv",
&swr_hap->hpwr_voltage_mv);
if (rc < 0) {
dev_err(swr_hap->dev, "%s: Failed to read qcom,hpwr-voltage-mv, rc=%d\n",
__func__, rc);
goto clean;
}
}
rc = regulator_enable(swr_hap->vdd);
if (rc < 0) {
dev_err(swr_hap->dev, "%s: enable swr-slave-vdd failed, rc=%d\n",
@ -459,6 +545,15 @@ static int swr_haptics_device_down(struct swr_device *sdev)
} else {
swr_hap->enable_cnt = 0;
}
/* Disable HAP_PWR regulator */
rc = swr_hap_enable_hpwr_vreg(swr_hap, false);
if (rc < 0) {
dev_err(swr_hap->dev, "Disable hpwr_vreg failed, rc=%d\n",
rc);
return rc;
}
return 0;
}