input: touchscreen: raydium_wt030: add regulator support
Get and configure vcc and vdd regulators. Also add
disable sequence for the regulators.
Change-Id: I9e5eb9a4582eeb9236b87d486be9abbb7dc3e862
Signed-off-by: Venkata Prahlad Valluru <vvalluru@codeaurora.org>
diff --git a/drivers/input/touchscreen/raydium_wt030/raydium_driver.c b/drivers/input/touchscreen/raydium_wt030/raydium_driver.c
index a6aaf52..c101c1f 100644
--- a/drivers/input/touchscreen/raydium_wt030/raydium_driver.c
+++ b/drivers/input/touchscreen/raydium_wt030/raydium_driver.c
@@ -1924,6 +1924,7 @@
pdata->num_max_touches = temp_val;
else
return rc;
+
#ifdef FW_MAPPING_BYID_EN
rc = of_property_read_u32(np, "raydium,fw_id", &temp_val);
if (!rc)
@@ -2016,6 +2017,144 @@
return i32_ret;
}
+static int raydium_get_regulators(struct raydium_ts_data *ts)
+{
+ struct device *dev = &ts->client->dev;
+ int rc;
+
+ ts->vdd = devm_regulator_get(dev, "vdd_ana");
+ if (IS_ERR(ts->vdd)) {
+ rc = PTR_ERR(ts->vdd);
+ dev_err(dev, "Failed to get 'vdd_ana' regulator: %d\n", rc);
+ return rc;
+ }
+
+ ts->vcc_i2c = devm_regulator_get(dev, "vcc_i2c");
+ if (IS_ERR(ts->vcc_i2c)) {
+ rc = PTR_ERR(ts->vcc_i2c);
+ dev_err(dev, "Failed to get 'vcc_i2c' regulator: %d\n", rc);
+ return rc;
+ }
+
+ return 0;
+}
+
+static int raydium_config_regulators(struct raydium_ts_data *ts, bool enable)
+{
+ int retval = 0;
+
+ if (!enable)
+ goto hw_shutdown;
+
+ if (ts->vdd) {
+ if (regulator_count_voltages(ts->vdd) > 0) {
+ retval = regulator_set_voltage(ts->vdd,
+ VDD_VTG_MIN_UV, VDD_VTG_MAX_UV);
+ if (retval) {
+ dev_err(&ts->client->dev,
+ "regulator set_vtg failed retval =%d\n",
+ retval);
+ return retval;
+ }
+ }
+ }
+
+ if (ts->vcc_i2c) {
+ if (regulator_count_voltages(ts->vcc_i2c) > 0) {
+ retval = regulator_set_voltage(ts->vcc_i2c,
+ I2C_VTG_MIN_UV, I2C_VTG_MAX_UV);
+ if (retval) {
+ dev_err(&ts->client->dev,
+ "regulator set_vtg failed retval =%d\n",
+ retval);
+ goto err_set_vtg_bus;
+ }
+ }
+ }
+
+ return 0;
+
+hw_shutdown:
+ if (ts->vcc_i2c &&
+ regulator_count_voltages(ts->vcc_i2c) > 0)
+ regulator_set_voltage(ts->vcc_i2c, 0, I2C_VTG_MAX_UV);
+err_set_vtg_bus:
+ if (ts->vdd &&
+ regulator_count_voltages(ts->vdd) > 0)
+ regulator_set_voltage(ts->vdd, 0, VDD_VTG_MAX_UV);
+
+ return retval;
+}
+
+static int raydium_enable_regulators(struct raydium_ts_data *ts, bool enable)
+{
+ int retval = 0;
+
+ if (!enable)
+ goto disable_vdd;
+
+ if (ts->vcc_i2c) {
+ retval = regulator_enable(ts->vcc_i2c);
+ if (retval < 0) {
+ dev_err(&ts->client->dev,
+ "%s: Failed to enable vcc regulator\n",
+ __func__);
+ return retval;
+ }
+ }
+
+ if (ts->vdd) {
+ retval = regulator_enable(ts->vdd);
+ if (retval < 0) {
+ dev_err(&ts->client->dev,
+ "%s: Failed to enable vdd regulator\n",
+ __func__);
+ goto disable_vcc_i2c;
+ }
+ }
+
+ return 0;
+disable_vdd:
+ if (ts->vdd)
+ regulator_disable(ts->vdd);
+disable_vcc_i2c:
+ if (ts->vcc_i2c)
+ regulator_disable(ts->vcc_i2c);
+
+ return retval;
+}
+
+static int raydium_power_on(struct raydium_ts_data *ts, bool on)
+{
+ int retval = 0;
+
+ if (!on)
+ goto disable_reg;
+
+ retval = raydium_config_regulators(ts, true);
+ if (retval) {
+ dev_err(&ts->client->dev,
+ "%s: Failed to config regulator\n",
+ __func__);
+ return retval;
+ }
+
+ retval = raydium_enable_regulators(ts, true);
+ if (retval) {
+ dev_err(&ts->client->dev,
+ "%s: Failed to enable regulator\n",
+ __func__);
+ goto err_config_reg;
+ }
+
+ return 0;
+disable_reg:
+ raydium_enable_regulators(ts, false);
+err_config_reg:
+ raydium_config_regulators(ts, false);
+ return retval;
+}
+
static int raydium_ts_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
@@ -2098,6 +2237,18 @@
}
#endif /*end of MSM_NEW_VER*/
+ ret = raydium_get_regulators(g_raydium_ts);
+ if (ret < 0) {
+ pr_err("[touch]failed to get regulators\n");
+ return -EINVAL;
+ }
+
+ ret = raydium_power_on(g_raydium_ts, true);
+ if (ret < 0) {
+ pr_err("[touch]failed to power on\n");
+ goto err_reg_req;
+ }
+
ret = raydium_gpio_configure(true);
if (ret < 0) {
pr_err("[touch]failed to configure the gpios\n");
@@ -2229,6 +2380,8 @@
}
#endif/*end of MSM_NEW_VER*/
+err_reg_req:
+ raydium_power_on(g_raydium_ts, false);
parse_dt_failed:
exit_check_functionality_failed:
return ret;
diff --git a/drivers/input/touchscreen/raydium_wt030/raydium_driver.h b/drivers/input/touchscreen/raydium_wt030/raydium_driver.h
index e47eb78..e604a59 100644
--- a/drivers/input/touchscreen/raydium_wt030/raydium_driver.h
+++ b/drivers/input/touchscreen/raydium_wt030/raydium_driver.h
@@ -19,8 +19,10 @@
#define __LINUX_RAYDIUM_H
#define RAYDIUM_NAME "raydium_ts"
#define COORDS_ARR_SIZE 4
-#define I2C_VTG_MIN_UV 1800000
-#define I2C_VTG_MAX_UV 1800000
+#define I2C_VTG_MIN_UV 1650000
+#define I2C_VTG_MAX_UV 1950000
+#define VDD_VTG_MIN_UV 1650000
+#define VDD_VTG_MAX_UV 1950000
#define RAD_MAIN_VERSION 0x01
#define RAD_MINOR_VERSION 0x07
#define RAD_CUSTOMER_VERSION 0x0100
@@ -235,7 +237,7 @@
struct early_suspend early_suspend;
#endif /*end of CONFIG_FB*/
- /*struct regulator *vdd;*/
+ struct regulator *vdd;
struct regulator *vcc_i2c;
unsigned int fw_version;
unsigned short id;