Some FocalTech TDDI controllers have no flash and run their firmware from RAM, which is lost whenever the controller is reset or powered down. Allow the chip data to provide a boot callback that is run right after the controller is taken out of reset, both at probe time before the controller is identified and when resuming from the power-off sleep mode before the register settings are restored.
The boot ROM of these controllers only accepts commands shortly after reset, so skip the 300 ms settle delay for them and pass the reset GPIO to the callback, letting it restart the boot ROM when it retries. Signed-off-by: Luka Panio <[email protected]> --- drivers/input/touchscreen/edt-ft5x06.c | 25 +++++++++++++++++++++++-- drivers/input/touchscreen/edt-ft5x06.h | 2 ++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c index 536d633d97a7..e57611e48217 100644 --- a/drivers/input/touchscreen/edt-ft5x06.c +++ b/drivers/input/touchscreen/edt-ft5x06.c @@ -148,6 +148,7 @@ struct edt_ft5x06_ts_data { struct edt_reg_addr reg_addr; enum edt_ver version; + int (*boot)(struct device *dev, struct gpio_desc *reset_gpio); unsigned int crc_errors; unsigned int header_errors; }; @@ -1131,7 +1132,16 @@ static int edt_ft5x06_ts_init_hw(struct edt_ft5x06_ts_data *tsdata) if (tsdata->reset_gpio) { usleep_range(5000, 6000); gpiod_set_value_cansleep(tsdata->reset_gpio, 0); - msleep(300); + /* Controllers with a boot callback handle their own timing */ + if (!tsdata->boot) + msleep(300); + } + + if (tsdata->boot) { + error = tsdata->boot(dev, tsdata->reset_gpio); + if (error) + return dev_err_probe(dev, error, + "failed to boot the controller\n"); } error = edt_ft5x06_ts_identify(tsdata); @@ -1233,6 +1243,7 @@ int edt_ft5x06_probe(struct device *dev, struct regmap *regmap, int irq, } tsdata->max_support_points = chip_data->max_support_points; + tsdata->boot = chip_data->boot; tsdata->vcc = devm_regulator_get(dev, "vcc"); if (IS_ERR(tsdata->vcc)) @@ -1437,7 +1448,17 @@ static int edt_ft5x06_ts_resume(struct device *dev) usleep_range(1000, 2000); gpiod_set_value_cansleep(reset_gpio, 0); - msleep(300); + + if (tsdata->boot) { + ret = tsdata->boot(dev, reset_gpio); + if (ret) { + dev_err(dev, "Failed to boot the controller: %d\n", + ret); + return ret; + } + } else { + msleep(300); + } edt_ft5x06_restore_reg_parameters(tsdata); enable_irq(tsdata->irq); diff --git a/drivers/input/touchscreen/edt-ft5x06.h b/drivers/input/touchscreen/edt-ft5x06.h index deadc756cd74..7eaeb562d11f 100644 --- a/drivers/input/touchscreen/edt-ft5x06.h +++ b/drivers/input/touchscreen/edt-ft5x06.h @@ -13,10 +13,12 @@ struct attribute_group; struct dentry; struct dev_pm_ops; struct device; +struct gpio_desc; struct regmap; struct edt_ft5x06_chip_data { int max_support_points; + int (*boot)(struct device *dev, struct gpio_desc *reset_gpio); }; int edt_ft5x06_probe(struct device *dev, struct regmap *regmap, int irq, -- 2.55.0
