Merge "msm: qpnp-haptic: add PON regulator support"

This commit is contained in:
Linux Build Service Account 2016-07-09 13:40:45 -07:00 committed by Gerrit - the friendly Code Review server
commit f8c2cd940b
2 changed files with 37 additions and 1 deletions

View File

@ -30,6 +30,7 @@ Optional Properties:
short circuit are <0x3 0xc0 0x0> and <0x3 0xc0 0x1>.
- interrupt-names: Specify the interrupt names associated with interrupts. Must be
one of "play-irq" or "sc-irq"
- vcc_pon-supply: power-on driver regulator
Optional properties for buffer play mode:
- qcom,wave-samples : 8 byte buffer representing the wave. The bits in each sample
@ -74,6 +75,7 @@ Example:
interrupts = <0x3 0xc0 0x0>,
<0x3 0xc0 0x1>;
interrupt-names = "sc-irq", "play-irq";
vcc_pon-supply = <&pon_perph_reg>;
qcom,play-mode = "direct";
qcom,wave-play-rate-us = <5263>;
qcom,actuator-type = "lra";

View File

@ -18,6 +18,7 @@
#include <linux/hrtimer.h>
#include <linux/of_device.h>
#include <linux/spmi.h>
#include <linux/regulator/consumer.h>
#include <linux/interrupt.h>
#include <linux/qpnp/pwm.h>
#include <linux/err.h>
@ -280,6 +281,7 @@ struct qpnp_pwm_info {
*/
struct qpnp_hap {
struct spmi_device *spmi;
struct regulator *vcc_pon;
struct hrtimer hap_timer;
struct hrtimer auto_res_err_poll_timer;
struct timed_output_dev timed_dev;
@ -320,6 +322,7 @@ struct qpnp_hap {
bool state;
bool use_play_irq;
bool use_sc_irq;
bool manage_pon_supply;
bool wf_update;
bool pwm_cfg_state;
bool buffer_cfg_state;
@ -1630,7 +1633,14 @@ static void qpnp_hap_worker(struct work_struct *work)
struct qpnp_hap *hap = container_of(work, struct qpnp_hap,
work);
u8 val = 0x00;
int rc;
int rc, reg_en;
if (hap->vcc_pon) {
reg_en = regulator_enable(hap->vcc_pon);
if (reg_en)
pr_err("%s: could not enable vcc_pon regulator\n",
__func__);
}
/* Disable haptics module if the duration of short circuit
* exceeds the maximum limit (5 secs).
@ -1643,6 +1653,13 @@ static void qpnp_hap_worker(struct work_struct *work)
qpnp_hap_mod_enable(hap, hap->state);
qpnp_hap_set(hap, hap->state);
}
if (hap->vcc_pon && !reg_en) {
rc = regulator_disable(hap->vcc_pon);
if (rc)
pr_err("%s: could not disable vcc_pon regulator\n",
__func__);
}
}
/* get time api to know the remaining time */
@ -2158,6 +2175,9 @@ static int qpnp_hap_parse_dt(struct qpnp_hap *hap)
}
}
if (of_find_property(spmi->dev.of_node, "vcc_pon-supply", NULL))
hap->manage_pon_supply = true;
return 0;
}
@ -2165,6 +2185,7 @@ static int qpnp_haptic_probe(struct spmi_device *spmi)
{
struct qpnp_hap *hap;
struct resource *hap_resource;
struct regulator *vcc_pon;
int rc, i;
hap = devm_kzalloc(&spmi->dev, sizeof(*hap), GFP_KERNEL);
@ -2232,6 +2253,17 @@ static int qpnp_haptic_probe(struct spmi_device *spmi)
}
}
if (hap->manage_pon_supply) {
vcc_pon = regulator_get(&spmi->dev, "vcc_pon");
if (IS_ERR(vcc_pon)) {
rc = PTR_ERR(vcc_pon);
dev_err(&spmi->dev,
"regulator get failed vcc_pon rc=%d\n", rc);
goto sysfs_fail;
}
hap->vcc_pon = vcc_pon;
}
ghap = hap;
return 0;
@ -2268,6 +2300,8 @@ static int qpnp_haptic_remove(struct spmi_device *spmi)
timed_output_dev_unregister(&hap->timed_dev);
mutex_destroy(&hap->lock);
mutex_destroy(&hap->wf_lock);
if (hap->vcc_pon)
regulator_put(hap->vcc_pon);
return 0;
}