[PATCH 07/10] Input: atmel_mxt_ts - refactor bootloader entry/exit

2013-02-01 Thread Daniel Kurtz
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

2013-02-01 Thread Daniel Kurtz
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,