From 80f24245c792b732b49d4d5d6832e5bc8b38e065 Mon Sep 17 00:00:00 2001 From: Konstantin Makariev Date: Thu, 26 Sep 2019 17:12:17 -0500 Subject: [PATCH] goodix_gtx8_v1430_mmi: proper avdd/iovdd handling Touch power supplies AVDD and IOVDD might not be always on and then kernel driver needs to vote for them. Adding optional handling for avdd and iovdd. Both power supplies can be configured in device tree Change-Id: I9e22a4e1fe18c9d1e36defe7c98ce6c3852b722b Signed-off-by: Konstantin Makariev Reviewed-on: https://gerrit.mot.com/1428943 SLTApproved: Slta Waiver SME-Granted: SME Approvals Granted Tested-by: Jira Key Reviewed-by: Konstantin Makariev Submit-Approved: Jira Key --- .../goodix_gtx8_v1430_mmi/goodix_ts_core.c | 65 +++++++++++++------ .../goodix_gtx8_v1430_mmi/goodix_ts_core.h | 4 +- .../goodix_gtx8_v1430_mmi/goodix_ts_i2c.c | 49 ++++++-------- 3 files changed, 70 insertions(+), 48 deletions(-) diff --git a/drivers/input/touchscreen/goodix_gtx8_v1430_mmi/goodix_ts_core.c b/drivers/input/touchscreen/goodix_gtx8_v1430_mmi/goodix_ts_core.c index 80a5b490262f..4ac694d5125d 100644 --- a/drivers/input/touchscreen/goodix_gtx8_v1430_mmi/goodix_ts_core.c +++ b/drivers/input/touchscreen/goodix_gtx8_v1430_mmi/goodix_ts_core.c @@ -1138,7 +1138,7 @@ static int goodix_ts_power_init(struct goodix_ts_core *core_data) dev = core_data->ts_dev->dev; ts_bdata = board_data(core_data); - if (strlen(ts_bdata->avdd_name)) { + if (ts_bdata->avdd_name) { core_data->avdd = devm_regulator_get(dev, ts_bdata->avdd_name); if (IS_ERR_OR_NULL(core_data->avdd)) { @@ -1151,6 +1151,18 @@ static int goodix_ts_power_init(struct goodix_ts_core *core_data) ts_info("Avdd name is NULL[skip]"); } + if (ts_bdata->iovdd_name) { + core_data->iovdd = devm_regulator_get(dev, + ts_bdata->iovdd_name); + if (IS_ERR_OR_NULL(core_data->iovdd)) { + r = PTR_ERR(core_data->iovdd); + ts_err("Failed to get regulator iovdd:%d", r); + core_data->iovdd = NULL; + } + } else { + ts_info("iovdd name is NULL"); + } + return r; } @@ -1162,30 +1174,36 @@ static int goodix_ts_power_init(struct goodix_ts_core *core_data) int goodix_ts_power_on(struct goodix_ts_core *core_data) { struct goodix_ts_board_data *ts_bdata = board_data(core_data); - int r; + int r = 0; ts_info("Device power on"); if (core_data->power_on) return 0; - if (!core_data->avdd) { - core_data->power_on = 1; - return 0; + if (core_data->avdd) { + r = regulator_enable(core_data->avdd); + if (!r) { + ts_info("regulator enable SUCCESS"); + if (ts_bdata->power_on_delay_us) + usleep_range(ts_bdata->power_on_delay_us, + ts_bdata->power_on_delay_us); + } else { + ts_err("Failed to enable avdd:%d", r); + goto err_exit; + } } - r = regulator_enable(core_data->avdd); - if (!r) { - ts_info("regulator enable SUCCESS"); - if (ts_bdata->power_on_delay_us) - usleep_range(ts_bdata->power_on_delay_us, - ts_bdata->power_on_delay_us); - } else { - ts_err("Failed to enable analog power:%d", r); - return r; + if (core_data->iovdd) { + r = regulator_enable(core_data->iovdd); + if (r) { + ts_err("Failed to enable iovdd:%d", r); + goto err_exit; + } } core_data->power_on = 1; - return 0; +err_exit: + return r; } /** @@ -1196,7 +1214,7 @@ int goodix_ts_power_on(struct goodix_ts_core *core_data) int goodix_ts_power_off(struct goodix_ts_core *core_data) { struct goodix_ts_board_data *ts_bdata = board_data(core_data); - int r; + int r = 0; ts_info("Device power off"); if (!core_data->power_on) @@ -1210,13 +1228,22 @@ int goodix_ts_power_off(struct goodix_ts_core *core_data) usleep_range(ts_bdata->power_off_delay_us, ts_bdata->power_off_delay_us); } else { - ts_err("Failed to disable analog power:%d", r); - return r; + ts_err("Failed to disable avdd:%d", r); + goto err_exit; + } + } + + if (core_data->iovdd) { + r = regulator_disable(core_data->iovdd); + if (r) { + ts_err("Failed to disable iovdd:%d", r); + goto err_exit; } } core_data->power_on = 0; - return 0; +err_exit: + return r; } #ifdef CONFIG_PINCTRL diff --git a/drivers/input/touchscreen/goodix_gtx8_v1430_mmi/goodix_ts_core.h b/drivers/input/touchscreen/goodix_gtx8_v1430_mmi/goodix_ts_core.h index df8facc5a465..242420892521 100644 --- a/drivers/input/touchscreen/goodix_gtx8_v1430_mmi/goodix_ts_core.h +++ b/drivers/input/touchscreen/goodix_gtx8_v1430_mmi/goodix_ts_core.h @@ -110,7 +110,8 @@ struct goodix_module { * @fw_name: name of the firmware image */ struct goodix_ts_board_data { - char avdd_name[24]; + const char *avdd_name; + const char *iovdd_name; unsigned int reset_gpio; unsigned int irq_gpio; int irq; @@ -435,6 +436,7 @@ struct goodix_ts_core { struct input_dev *pen_dev; struct regulator *avdd; + struct regulator *iovdd; #ifdef CONFIG_PINCTRL struct pinctrl *pinctrl; struct pinctrl_state *pin_sta_active; diff --git a/drivers/input/touchscreen/goodix_gtx8_v1430_mmi/goodix_ts_i2c.c b/drivers/input/touchscreen/goodix_gtx8_v1430_mmi/goodix_ts_i2c.c index 011276ce501e..72dbc6e1eb59 100644 --- a/drivers/input/touchscreen/goodix_gtx8_v1430_mmi/goodix_ts_i2c.c +++ b/drivers/input/touchscreen/goodix_gtx8_v1430_mmi/goodix_ts_i2c.c @@ -125,6 +125,19 @@ static int goodix_parse_dt_resolution(struct device_node *node, return 0; } +static const char *goodix_parse_dt_text(struct device_node *node, + const char *name) +{ + const char *prop = NULL; + int r; + + r = of_property_read_string(node, name, &prop); + if (r) { + ts_err("%s: error reading property = %d", name, r); + } + return prop; +} + /** * goodix_parse_dt - parse board data from dt * @dev: pointer to device @@ -135,7 +148,6 @@ static int goodix_parse_dt(struct device_node *node, struct goodix_ts_board_data *board_data) { struct property *prop; - const char *name_tmp; int r; if (!board_data) { @@ -166,34 +178,15 @@ static int goodix_parse_dt(struct device_node *node, return -EINVAL; } - board_data->cfg_bin_name = kzalloc(32 * sizeof(char), GFP_KERNEL); - r = of_property_read_string(node, "goodix,cfg_bin_name", - &board_data->cfg_bin_name); - if (r) { - ts_err("Unable to read cfg name %d\n", r); - board_data->cfg_bin_name = NULL; - } + board_data->cfg_bin_name = goodix_parse_dt_text(node, + "goodix,cfg_bin_name"); + board_data->fw_name = goodix_parse_dt_text(node, + "goodix,fw_name"); + board_data->avdd_name = goodix_parse_dt_text(node, + "goodix,avdd-name"); + board_data->iovdd_name = goodix_parse_dt_text(node, + "goodix,iovdd-name"); - board_data->fw_name = kzalloc(32 * sizeof(char), GFP_KERNEL); - r = of_property_read_string(node, "goodix,fw_name", - &board_data->fw_name); - if (r) { - ts_err("Unable to read fw name %d\n", r); - board_data->fw_name = NULL; - } - - memset(board_data->avdd_name, 0, sizeof(board_data->avdd_name)); - r = of_property_read_string(node, "goodix,avdd-name", &name_tmp); - if (!r) { - ts_info("avdd name form dt: %s", name_tmp); - if (strlen(name_tmp) < sizeof(board_data->avdd_name)) - strncpy(board_data->avdd_name, - name_tmp, sizeof(board_data->avdd_name)); - else - ts_info("invalied avdd name length: %ld > %ld", - strlen(name_tmp), - sizeof(board_data->avdd_name)); - } r = of_property_read_u32(node, "goodix,power-on-delay-us", &board_data->power_on_delay_us); if (!r) {