[PATCH 07/10] Input: atmel_mxt_ts - refactor bootloader entry/exit
From: Benson Leung Refactor bootloading into a three parts: 1) bl enter that only happens when device is not yet in bl. bl enter frees old driver state and switches to BL i2c addr. 2) the actual fw_update 3) bl exit that only happens if fw update is successful. bl exit switches to APP i2c addr and reloads object table and creates a new input device. Signed-off-by: Benson Leung Signed-off-by: Daniel Kurtz Signed-off-by: Yufeng Shen --- drivers/input/touchscreen/atmel_mxt_ts.c | 128 +-- 1 file changed, 87 insertions(+), 41 deletions(-) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index c74f5a5..be96be3 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -253,6 +253,11 @@ struct mxt_data { u8 T9_reportid_max; }; +static void mxt_free_object_table(struct mxt_data *data); +static int mxt_initialize(struct mxt_data *data); +static int mxt_input_dev_create(struct mxt_data *data); +static int mxt_make_highchg(struct mxt_data *data); + static bool mxt_object_readable(unsigned int type) { switch (type) { @@ -402,6 +407,8 @@ recheck: if (val != state) { dev_err(>dev, "Unvalid bootloader mode state\n"); + dev_err(>dev, "Invalid bootloader mode state %d, %d\n", + val, state); return -EINVAL; } @@ -581,6 +588,81 @@ static bool mxt_is_T9_message(struct mxt_data *data, struct mxt_message *msg) return (id >= data->T9_reportid_min && id <= data->T9_reportid_max); } +static int mxt_enter_bl(struct mxt_data *data) +{ + struct i2c_client *client = data->client; + int ret; + + if (mxt_in_bootloader(data)) + return 0; + + disable_irq(data->irq); + + /* Change to the bootloader mode */ + ret = mxt_write_object(data, MXT_GEN_COMMAND_T6, + MXT_COMMAND_RESET, MXT_BOOT_VALUE); + if (ret) { + enable_irq(data->irq); + return ret; + } + + /* Change to slave address of bootloader */ + if (client->addr == MXT_APP_LOW) + client->addr = MXT_BOOT_LOW; + else + client->addr = MXT_BOOT_HIGH; + + /* Free any driver state. It will get reinitialized after fw update. */ + mxt_free_object_table(data); + if (data->input_dev) { + input_unregister_device(data->input_dev); + data->input_dev = NULL; + } + + enable_irq(data->irq); + msleep(MXT_RESET_TIME); + return 0; +} + +static void mxt_exit_bl(struct mxt_data *data) +{ + struct i2c_client *client = data->client; + struct device *dev = >dev; + int error; + + if (!mxt_in_bootloader(data)) + return; + + disable_irq(data->irq); + /* Wait for reset */ + msleep(MXT_FWRESET_TIME); + + if (client->addr == MXT_BOOT_LOW) + client->addr = MXT_APP_LOW; + else + client->addr = MXT_APP_HIGH; + + error = mxt_initialize(data); + if (error) { + dev_err(dev, "Failed to initialize on exit bl. error = %d\n", + error); + return; + } + + error = mxt_input_dev_create(data); + if (error) { + dev_err(dev, "Create input dev failed after init. error = %d\n", + error); + return; + } + + error = mxt_make_highchg(data); + if (error) + dev_err(dev, "Failed to clear CHG after init. error = %d\n", + error); + enable_irq(data->irq); +} + static irqreturn_t mxt_interrupt(int irq, void *dev_id) { struct mxt_data *data = dev_id; @@ -984,28 +1066,10 @@ static int mxt_load_fw(struct device *dev, const char *fn) return ret; } - if (mxt_in_bootloader(data)) - goto bootloader_ready; - - /* Change to the bootloader mode */ - ret = mxt_write_object(data, MXT_GEN_COMMAND_T6, - MXT_COMMAND_RESET, MXT_BOOT_VALUE); - if (ret) + ret = mxt_enter_bl(data); + if (ret) { + dev_err(dev, "Failed to reset to bootloader.\n"); goto out; - msleep(MXT_RESET_TIME); - - /* Change to slave address of bootloader */ - if (client->addr == MXT_APP_LOW) - client->addr = MXT_BOOT_LOW; - else - client->addr = MXT_BOOT_HIGH; - -bootloader_ready: - /* Free any driver state. It will get reinitialized after fw update. */ - mxt_free_object_table(data); - if (data->input_dev) { - input_unregister_device(data->input_dev); - data->input_dev = NULL; } ret = mxt_check_bootloader(client, MXT_WAITING_BOOTLOAD_CMD); @@ -1045,11 +1109,8 @@
[PATCH 07/10] Input: atmel_mxt_ts - refactor bootloader entry/exit
From: Benson Leung ble...@chromium.org Refactor bootloading into a three parts: 1) bl enter that only happens when device is not yet in bl. bl enter frees old driver state and switches to BL i2c addr. 2) the actual fw_update 3) bl exit that only happens if fw update is successful. bl exit switches to APP i2c addr and reloads object table and creates a new input device. Signed-off-by: Benson Leung ble...@chromium.org Signed-off-by: Daniel Kurtz djku...@chromium.org Signed-off-by: Yufeng Shen mile...@chromium.org --- drivers/input/touchscreen/atmel_mxt_ts.c | 128 +-- 1 file changed, 87 insertions(+), 41 deletions(-) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index c74f5a5..be96be3 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -253,6 +253,11 @@ struct mxt_data { u8 T9_reportid_max; }; +static void mxt_free_object_table(struct mxt_data *data); +static int mxt_initialize(struct mxt_data *data); +static int mxt_input_dev_create(struct mxt_data *data); +static int mxt_make_highchg(struct mxt_data *data); + static bool mxt_object_readable(unsigned int type) { switch (type) { @@ -402,6 +407,8 @@ recheck: if (val != state) { dev_err(client-dev, Unvalid bootloader mode state\n); + dev_err(client-dev, Invalid bootloader mode state %d, %d\n, + val, state); return -EINVAL; } @@ -581,6 +588,81 @@ static bool mxt_is_T9_message(struct mxt_data *data, struct mxt_message *msg) return (id = data-T9_reportid_min id = data-T9_reportid_max); } +static int mxt_enter_bl(struct mxt_data *data) +{ + struct i2c_client *client = data-client; + int ret; + + if (mxt_in_bootloader(data)) + return 0; + + disable_irq(data-irq); + + /* Change to the bootloader mode */ + ret = mxt_write_object(data, MXT_GEN_COMMAND_T6, + MXT_COMMAND_RESET, MXT_BOOT_VALUE); + if (ret) { + enable_irq(data-irq); + return ret; + } + + /* Change to slave address of bootloader */ + if (client-addr == MXT_APP_LOW) + client-addr = MXT_BOOT_LOW; + else + client-addr = MXT_BOOT_HIGH; + + /* Free any driver state. It will get reinitialized after fw update. */ + mxt_free_object_table(data); + if (data-input_dev) { + input_unregister_device(data-input_dev); + data-input_dev = NULL; + } + + enable_irq(data-irq); + msleep(MXT_RESET_TIME); + return 0; +} + +static void mxt_exit_bl(struct mxt_data *data) +{ + struct i2c_client *client = data-client; + struct device *dev = client-dev; + int error; + + if (!mxt_in_bootloader(data)) + return; + + disable_irq(data-irq); + /* Wait for reset */ + msleep(MXT_FWRESET_TIME); + + if (client-addr == MXT_BOOT_LOW) + client-addr = MXT_APP_LOW; + else + client-addr = MXT_APP_HIGH; + + error = mxt_initialize(data); + if (error) { + dev_err(dev, Failed to initialize on exit bl. error = %d\n, + error); + return; + } + + error = mxt_input_dev_create(data); + if (error) { + dev_err(dev, Create input dev failed after init. error = %d\n, + error); + return; + } + + error = mxt_make_highchg(data); + if (error) + dev_err(dev, Failed to clear CHG after init. error = %d\n, + error); + enable_irq(data-irq); +} + static irqreturn_t mxt_interrupt(int irq, void *dev_id) { struct mxt_data *data = dev_id; @@ -984,28 +1066,10 @@ static int mxt_load_fw(struct device *dev, const char *fn) return ret; } - if (mxt_in_bootloader(data)) - goto bootloader_ready; - - /* Change to the bootloader mode */ - ret = mxt_write_object(data, MXT_GEN_COMMAND_T6, - MXT_COMMAND_RESET, MXT_BOOT_VALUE); - if (ret) + ret = mxt_enter_bl(data); + if (ret) { + dev_err(dev, Failed to reset to bootloader.\n); goto out; - msleep(MXT_RESET_TIME); - - /* Change to slave address of bootloader */ - if (client-addr == MXT_APP_LOW) - client-addr = MXT_BOOT_LOW; - else - client-addr = MXT_BOOT_HIGH; - -bootloader_ready: - /* Free any driver state. It will get reinitialized after fw update. */ - mxt_free_object_table(data); - if (data-input_dev) { - input_unregister_device(data-input_dev); - data-input_dev = NULL; } ret = mxt_check_bootloader(client,