[PATCH 50/51] Input: atmel_mxt_ts - Handle cfg filename via pdata/sysfs

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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 <nick.dyer@xxxxxxxxxxx>
---
 drivers/input/touchscreen/atmel_mxt_ts.c |  104 ++++++++++++++++++++++++------
 include/linux/i2c/atmel_mxt_ts.h         |    1 +
 2 files changed, 86 insertions(+), 19 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index 9aa3a26..9a5ac2c 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -28,7 +28,6 @@
 #include <linux/gpio.h>
 
 /* Configuration file */
-#define MXT_CFG_NAME		"maxtouch.cfg"
 #define MXT_CFG_MAGIC		"OBP_RAW V1"
 
 /* Registers */
@@ -246,6 +245,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;
@@ -1372,10 +1372,15 @@ static int mxt_check_reg_init(struct mxt_data *data)
 	u8 val;
 	u16 reg;
 
-	ret = request_firmware(&cfg, MXT_CFG_NAME, dev);
+	if (!data->cfg_name) {
+		dev_dbg(dev, "Skipping cfg download\n");
+		return 0;
+	}
+
+	ret = request_firmware(&cfg, data->cfg_name, dev);
 	if (ret < 0) {
 		dev_err(dev, "Failure to request config file %s\n",
-			MXT_CFG_NAME);
+			data->cfg_name);
 		return 0;
 	}
 
@@ -1673,6 +1678,14 @@ static int mxt_acquire_irq(struct mxt_data *data)
 	return 0;
 }
 
+static void mxt_free_input_device(struct mxt_data *data)
+{
+	if (data->input_dev) {
+		input_unregister_device(data->input_dev);
+		data->input_dev = NULL;
+	}
+}
+
 static void mxt_free_object_table(struct mxt_data *data)
 {
 	kfree(data->raw_info_block);
@@ -1682,10 +1695,7 @@ static void mxt_free_object_table(struct mxt_data *data)
 	kfree(data->msg_buf);
 	data->msg_buf = NULL;
 
-	if (data->input_dev) {
-		input_unregister_device(data->input_dev);
-		data->input_dev = NULL;
-	}
+	mxt_free_input_device(data);
 
 	data->enable_reporting = false;
 	data->T5_address = 0;
@@ -2181,6 +2191,7 @@ err_free_mem:
 }
 
 static int mxt_initialize_t9_input_device(struct mxt_data *data);
+static int mxt_configure_objects(struct mxt_data *data);
 
 static int mxt_initialize(struct mxt_data *data)
 {
@@ -2224,16 +2235,28 @@ retry_bootloader:
 
 	error = mxt_check_retrigen(data);
 	if (error)
-		goto err_free_object_table;
+		return error;
 
 	error = mxt_acquire_irq(data);
 	if (error)
-		goto err_free_object_table;
+		return error;
+
+	error = mxt_configure_objects(data);
+	if (error)
+		return error;
+
+	return 0;
+}
+
+static int mxt_configure_objects(struct mxt_data *data)
+{
+	struct i2c_client *client = data->client;
+	int error;
 
 	error = mxt_init_t7_power_cfg(data);
 	if (error) {
 		dev_err(&client->dev, "Failed to initialize power cfg\n");
-		goto err_free_object_table;
+		return error;
 	}
 
 	/* Check register init values */
@@ -2241,28 +2264,23 @@ retry_bootloader:
 	if (error) {
 		dev_err(&client->dev, "Error %d initialising configuration\n",
 			error);
-		goto err_free_object_table;
+		return error;
 	}
 
 	if (data->T9_reportid_min) {
 		error = mxt_initialize_t9_input_device(data);
 		if (error)
-			goto err_free_object_table;
+			return error;
 	} else if (data->T100_reportid_min) {
 		error = mxt_initialize_t100_input_device(data);
 		if (error)
-			goto err_free_object_table;
+			return error;
 	} else {
 		dev_warn(&client->dev, "No touch object detected\n");
 	}
 
 	data->enable_reporting = true;
-
 	return 0;
-
-err_free_object_table:
-	mxt_free_object_table(data);
-	return error;
 }
 
 /* Firmware Version is returned as Major.Minor.Build */
@@ -2550,16 +2568,57 @@ 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);
+	int ret;
+
+	if (data->in_bootloader) {
+		dev_err(dev, "Not in appmode\n");
+		return -EINVAL;
+	}
+
+	ret = mxt_update_file_name(dev, &data->cfg_name, buf, count);
+	if (ret)
+		return ret;
+
+	data->enable_reporting = false;
+	mxt_free_input_device(data);
+
+	if (data->suspended) {
+		if (data->use_regulator)
+			mxt_regulator_enable(data);
+		else
+			mxt_set_t7_power_cfg(data, MXT_POWER_CFG_RUN);
+
+		mxt_acquire_irq(data);
+
+		data->suspended = false;
+	}
+
+	ret = mxt_configure_objects(data);
+	if (ret)
+		goto out;
+
+	ret = count;
+out:
+	return ret;
+}
+
 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_fw, S_IWUSR, NULL, mxt_update_fw_store);
+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_fw.attr,
+	&dev_attr_update_cfg.attr,
 	NULL
 };
 
@@ -2644,8 +2703,15 @@ static int mxt_handle_pdata(struct mxt_data *data)
 	data->pdata = dev_get_platdata(&data->client->dev);
 
 	/* Use provided platform data if present */
-	if (data->pdata)
+	if (data->pdata) {
+		if (data->pdata->cfg_name)
+			mxt_update_file_name(&data->client->dev,
+					     &data->cfg_name,
+					     data->pdata->cfg_name,
+					     strlen(data->pdata->cfg_name));
+
 		return 0;
+	}
 
 	data->pdata = kzalloc(sizeof(*data->pdata), GFP_KERNEL);
 	if (!data->pdata) {
diff --git a/include/linux/i2c/atmel_mxt_ts.h b/include/linux/i2c/atmel_mxt_ts.h
index a01f2e8..3422bd0 100644
--- a/include/linux/i2c/atmel_mxt_ts.h
+++ b/include/linux/i2c/atmel_mxt_ts.h
@@ -23,6 +23,7 @@ struct mxt_platform_data {
 	int t15_num_keys;
 	const unsigned int *t15_keymap;
 	unsigned long gpio_reset;
+	const char *cfg_name;
 };
 
 #endif /* __LINUX_ATMEL_MXT_TS_H */
-- 
1.7.10.4

--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Media Devel]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Linux Wireless Networking]     [Linux Omap]

  Powered by Linux