input: atmel_mxt_ts: Allow bootloader address to be set

The driver maintains a default mapping between appmode address
and bootloader address. Some appmode addresses may have
different corresponding bootloader addresses than what is
currently mapped. When this is the case, looking through an
array will not work and bootloader address must be passed in
through device tree or pdata. Appmode address is already
present in i2c client structure.

With this support, firmware upgrade for mxt336s and mxt1664s
touch controllers is now present.

Change-Id: I605b4ae615f30a05620847a5a9af826bc906f1c3
Signed-off-by: Amy Maloche <amaloche@codeaurora.org>
This commit is contained in:
Amy Maloche
2013-01-18 14:13:42 -08:00
parent 887a9bbbb0
commit 71b8f029e7
3 changed files with 54 additions and 36 deletions
@@ -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
+48 -35
View File
@@ -3,7 +3,7 @@
*
* Copyright (C) 2010 Samsung Electronics Co.Ltd
* Author: Joonyoung Shim <jy0922.shim@samsung.com>
* 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;
+4 -1
View File
@@ -3,7 +3,7 @@
*
* Copyright (C) 2010 Samsung Electronics Co.Ltd
* Author: Joonyoung Shim <jy0922.shim@samsung.com>
* 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);