Skip to content

Commit

Permalink
Input: atmel_mxt_ts - handle cfg filename via pdata/sysfs
Browse files Browse the repository at this point in the history
There may be multiple maXTouch chips on a single device which will require
different configuration files. Add a platform data value for the
configuration filename.

Add sysfs entry to write configuration file if the platform data is not
set.

Split out the object initialisation code from mxt_initialize() into
mxt_configure_objects() to allow this.

Signed-off-by: Nick Dyer <[email protected]>
Acked-by: Yufeng Shen <[email protected]>
  • Loading branch information
ndyer committed Apr 26, 2016
1 parent 0ae4709 commit 71a2a4d
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 11 deletions.
3 changes: 3 additions & 0 deletions Documentation/devicetree/bindings/input/atmel,maxtouch.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ Optional properties for main touchpad device:

- atmel,reset-gpio: Configure RESET GPIO. Required for regulator support.

- atmel,cfg_name: Provide name of configuration file in OBP_RAW format. This
will be downloaded from the firmware loader on probe to the device.

Example:

touch@4b {
Expand Down
95 changes: 84 additions & 11 deletions drivers/input/touchscreen/atmel_mxt_ts.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
#include <linux/gpio.h>

/* Configuration file */
#define MXT_CFG_NAME "maxtouch.cfg"
#define MXT_CFG_MAGIC "OBP_RAW V1"

/* Registers */
Expand Down Expand Up @@ -279,6 +278,7 @@ struct mxt_data {
struct regulator *reg_vdd;
struct regulator *reg_avdd;
char *fw_name;
char *cfg_name;

/* Cached parameters from object table */
u16 T5_address;
Expand Down Expand Up @@ -316,6 +316,9 @@ struct mxt_data {

/* Indicates whether device is in suspend */
bool suspended;

/* Indicates whether device is updating configuration */
bool updating_config;
};

static size_t mxt_obj_size(const struct mxt_object *obj)
Expand Down Expand Up @@ -2477,13 +2480,19 @@ static int mxt_initialize(struct mxt_data *data)
if (error)
goto err_free_object_table;

error = request_firmware_nowait(THIS_MODULE, true, MXT_CFG_NAME,
&client->dev, GFP_KERNEL, data,
mxt_config_cb);
if (error) {
dev_err(&client->dev, "Failed to invoke firmware loader: %d\n",
error);
goto err_free_object_table;
if (data->cfg_name) {
error = request_firmware_nowait(THIS_MODULE, true,
data->cfg_name, &data->client->dev,
GFP_KERNEL, data, mxt_config_cb);
if (error) {
dev_err(&client->dev, "Failed to invoke firmware loader: %d\n",
error);
goto err_free_object_table;
}
} else {
error = mxt_configure_objects(data, NULL);
if (error)
goto err_free_object_table;
}

return 0;
Expand Down Expand Up @@ -2556,7 +2565,7 @@ static int mxt_configure_objects(struct mxt_data *data,
error = mxt_init_t7_power_cfg(data);
if (error) {
dev_err(dev, "Failed to initialize power cfg\n");
return error;
goto err_free_object_table;
}

if (cfg) {
Expand All @@ -2568,12 +2577,16 @@ static int mxt_configure_objects(struct mxt_data *data,
if (data->multitouch) {
error = mxt_initialize_input_device(data);
if (error)
return error;
goto err_free_object_table;
} else {
dev_warn(dev, "No touch object detected\n");
}

return 0;

err_free_object_table:
mxt_free_object_table(data);
return error;
}

/* Firmware Version is returned as Major.Minor.Build */
Expand Down Expand Up @@ -2866,6 +2879,56 @@ static ssize_t mxt_update_fw_store(struct device *dev,
return count;
}

static ssize_t mxt_update_cfg_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct mxt_data *data = dev_get_drvdata(dev);
const struct mxt_platform_data *pdata = data->pdata;
const struct firmware *cfg;
int ret;

ret = mxt_update_file_name(dev, &data->cfg_name, buf, count);
if (ret)
return ret;

ret = request_firmware(&cfg, data->cfg_name, dev);
if (ret < 0) {
dev_err(dev, "Failure to request config file %s\n",
data->cfg_name);
ret = -ENOENT;
goto out;
}

data->updating_config = true;

mxt_free_input_device(data);

if (data->suspended) {
if (pdata->suspend_mode == MXT_SUSPEND_REGULATOR) {
enable_irq(data->irq);
mxt_regulator_enable(data);
} else if (pdata->suspend_mode == MXT_SUSPEND_DEEP_SLEEP) {
mxt_set_t7_power_cfg(data, MXT_POWER_CFG_RUN);
mxt_acquire_irq(data);
}

data->suspended = false;
}

ret = mxt_configure_objects(data, cfg);
if (ret)
goto release;

ret = count;

release:
release_firmware(cfg);
out:
data->updating_config = false;
return ret;
}

static DEVICE_ATTR(update_fw, S_IWUSR, NULL, mxt_update_fw_store);

static struct attribute *mxt_fw_attrs[] = {
Expand All @@ -2880,11 +2943,13 @@ static const struct attribute_group mxt_fw_attr_group = {
static DEVICE_ATTR(fw_version, S_IRUGO, mxt_fw_version_show, NULL);
static DEVICE_ATTR(hw_version, S_IRUGO, mxt_hw_version_show, NULL);
static DEVICE_ATTR(object, S_IRUGO, mxt_object_show, NULL);
static DEVICE_ATTR(update_cfg, S_IWUSR, NULL, mxt_update_cfg_store);

static struct attribute *mxt_attrs[] = {
&dev_attr_fw_version.attr,
&dev_attr_hw_version.attr,
&dev_attr_object.attr,
&dev_attr_update_cfg.attr,
NULL
};

Expand Down Expand Up @@ -2985,7 +3050,7 @@ static int mxt_stop(struct mxt_data *data)
{
int ret;

if (data->suspended || data->in_bootloader)
if (data->suspended || data->in_bootloader || data->updating_config)
return 0;

switch (data->pdata->suspend_mode) {
Expand Down Expand Up @@ -3062,6 +3127,8 @@ static const struct mxt_platform_data *mxt_parse_dt(struct i2c_client *client)
pdata->gpio_reset = of_get_named_gpio_flags(np, "atmel,reset-gpio",
0, NULL);

of_property_read_string(np, "atmel,cfg_name", &pdata->cfg_name);

if (of_find_property(np, "linux,gpio-keymap", &proplen)) {
pdata->t19_num_keys = proplen / sizeof(u32);

Expand Down Expand Up @@ -3275,6 +3342,12 @@ static int mxt_probe(struct i2c_client *client, const struct i2c_device_id *id)
data->irq = client->irq;
i2c_set_clientdata(client, data);

if (data->pdata->cfg_name)
mxt_update_file_name(&data->client->dev,
&data->cfg_name,
data->pdata->cfg_name,
strlen(data->pdata->cfg_name));

init_completion(&data->bl_completion);
init_completion(&data->reset_completion);
init_completion(&data->crc_completion);
Expand Down
1 change: 1 addition & 0 deletions include/linux/platform_data/atmel_mxt_ts.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ struct mxt_platform_data {
int t15_num_keys;
const unsigned int *t15_keymap;
unsigned long gpio_reset;
const char *cfg_name;
};

#endif /* __LINUX_PLATFORM_DATA_ATMEL_MXT_TS_H */

0 comments on commit 71a2a4d

Please sign in to comment.