diff --git a/Documentation/devicetree/bindings/input/touchscreen/atmel-mxt-ts.txt b/Documentation/devicetree/bindings/input/touchscreen/atmel-mxt-ts.txt index bcea3554b1b..dde1a16c7c1 100644 --- a/Documentation/devicetree/bindings/input/touchscreen/atmel-mxt-ts.txt +++ b/Documentation/devicetree/bindings/input/touchscreen/atmel-mxt-ts.txt @@ -22,6 +22,8 @@ Required properties: - atmel,fw-name : firmware name to used for flashing firmware Optional property: + - atmel,bl-addr : bootloader address, by default is looked up + in mxt_slave_addresses structure - atmel,config : configuration parameter for the controller - atmel,i2c-pull-up : specify to indicate pull up is needed - vcc_i2c-supply : Power source required to pull up i2c bus diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index 2e807acd846..a867fc9481d 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -3,7 +3,7 @@ * * Copyright (C) 2010 Samsung Electronics Co.Ltd * Author: Joonyoung Shim - * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved. + * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -356,6 +356,7 @@ struct mxt_data { struct regulator *vcc_ana; struct regulator *vcc_dig; struct regulator *vcc_i2c; + struct mxt_address_pair addr_pair; #if defined(CONFIG_HAS_EARLYSUSPEND) struct early_suspend early_suspend; #endif @@ -470,9 +471,27 @@ static void mxt_dump_message(struct device *dev, dev_dbg(dev, "checksum:\t0x%x\n", message->checksum); } -static int mxt_switch_to_bootloader_address(struct mxt_data *data) +static int mxt_lookup_bootloader_address(struct mxt_data *data) { int i; + + for (i = 0; mxt_slave_addresses[i].application != 0; i++) { + if (mxt_slave_addresses[i].application == + data->client->addr) { + data->addr_pair.bootloader = + mxt_slave_addresses[i].bootloader; + return 0; + } + } + + dev_err(&data->client->dev, "Address 0x%02x not found in address table", + data->client->addr); + return -EINVAL; + +}; + +static int mxt_switch_to_bootloader_address(struct mxt_data *data) +{ struct i2c_client *client = data->client; if (data->state == BOOTLOADER) { @@ -480,27 +499,16 @@ static int mxt_switch_to_bootloader_address(struct mxt_data *data) return -EINVAL; } - for (i = 0; mxt_slave_addresses[i].application != 0; i++) { - if (mxt_slave_addresses[i].application == client->addr) { - dev_info(&client->dev, "Changing to bootloader address: " - "%02x -> %02x", - client->addr, - mxt_slave_addresses[i].bootloader); + dev_info(&client->dev, "Changing to bootloader address: 0x%02x -> 0x%02x", + client->addr, data->addr_pair.bootloader); - client->addr = mxt_slave_addresses[i].bootloader; - data->state = BOOTLOADER; - return 0; - } - } - - dev_err(&client->dev, "Address 0x%02x not found in address table", - client->addr); - return -EINVAL; + client->addr = data->addr_pair.bootloader; + data->state = BOOTLOADER; + return 0; } static int mxt_switch_to_appmode_address(struct mxt_data *data) { - int i; struct i2c_client *client = data->client; if (data->state == APPMODE) { @@ -508,23 +516,13 @@ static int mxt_switch_to_appmode_address(struct mxt_data *data) return -EINVAL; } - for (i = 0; mxt_slave_addresses[i].application != 0; i++) { - if (mxt_slave_addresses[i].bootloader == client->addr) { - dev_info(&client->dev, - "Changing to application mode address: " - "0x%02x -> 0x%02x", - client->addr, - mxt_slave_addresses[i].application); + dev_info(&client->dev, "Changing to application mode address: " \ + "0x%02x -> 0x%02x", client->addr, + data->addr_pair.application); - client->addr = mxt_slave_addresses[i].application; - data->state = APPMODE; - return 0; - } - } - - dev_err(&client->dev, "Address 0x%02x not found in address table", - client->addr); - return -EINVAL; + client->addr = data->addr_pair.application; + data->state = APPMODE; + return 0; } static int mxt_get_bootloader_version(struct i2c_client *client, u8 val) @@ -1655,9 +1653,11 @@ static int mxt_load_fw(struct device *dev, const char *fn) switch (data->info.family_id) { case MXT224_ID: case MXT224E_ID: + case MXT336S_ID: max_frame_size = MXT_SINGLE_FW_MAX_FRAME_SIZE; break; case MXT1386_ID: + case MXT1664S_ID: max_frame_size = MXT_CHIPSET_FW_MAX_FRAME_SIZE; break; default: @@ -2564,6 +2564,12 @@ static int mxt_parse_dt(struct device *dev, struct mxt_platform_data *pdata) return -ENOMEM; } + rc = of_property_read_u32(np, "atmel,bl-addr", &temp_val); + if (rc && (rc != -EINVAL)) + dev_err(dev, "Unable to read bootloader address\n"); + else if (rc != -EINVAL) + pdata->bl_addr = (u8) temp_val; + pdata->config_array = info; for_each_child_of_node(np, temp) { @@ -2602,7 +2608,7 @@ static int mxt_parse_dt(struct device *dev, struct mxt_platform_data *pdata) } else info->build = (u8) temp_val; - info->bootldr_id = of_property_read_u32(temp, + rc = of_property_read_u32(temp, "atmel,bootldr-id", &temp_val); if (rc) { dev_err(dev, "Unable to read bootldr-id\n"); @@ -2767,6 +2773,13 @@ static int __devinit mxt_probe(struct i2c_client *client, mxt_power_on_delay(data); + data->addr_pair.application = data->client->addr; + + if (pdata->bl_addr) + data->addr_pair.bootloader = pdata->bl_addr; + else + mxt_lookup_bootloader_address(data); + error = mxt_initialize(data); if (error) goto err_reset_gpio_req; diff --git a/include/linux/i2c/atmel_mxt_ts.h b/include/linux/i2c/atmel_mxt_ts.h index fe239932589..b903dfbd91e 100644 --- a/include/linux/i2c/atmel_mxt_ts.h +++ b/include/linux/i2c/atmel_mxt_ts.h @@ -3,7 +3,7 @@ * * Copyright (C) 2010 Samsung Electronics Co.Ltd * Author: Joonyoung Shim - * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved. + * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -32,8 +32,10 @@ /* Bootoader IDs */ #define MXT_BOOTLOADER_ID_224 0x0A #define MXT_BOOTLOADER_ID_224E 0x06 +#define MXT_BOOTLOADER_ID_336S 0x1A #define MXT_BOOTLOADER_ID_1386 0x01 #define MXT_BOOTLOADER_ID_1386E 0x10 +#define MXT_BOOTLOADER_ID_1664S 0x14 /* Config data for a given maXTouch controller with a specific firmware */ struct mxt_config_info { @@ -75,6 +77,7 @@ struct mxt_platform_data { int *key_codes; bool need_calibration; bool no_force_update; + u8 bl_addr; u8(*read_chg) (void); int (*init_hw) (bool);