Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4216b3b9 authored by Alexandra Chin's avatar Alexandra Chin Committed by Abinaya P
Browse files

input: synaptics: Correct bugs in fw update

- Fixed reset command could fail after firmware update
- Config reset pin if reset gpio is defined in platform data
- Force do a reset in function probe
- Skip fw/config update process if image firmware id is smaller
  than device firmware id

Change-Id: I3525410c791454f64c680506fe4c77e9da650a46
Git-commit: db1a35c603df138842bdee3b0d9e7f9e24012e4e
Git-repo: git://github.com/synaptics-touch/synaptics-dsx-i2c.git


[amaloche@codeaurora.org: modified change w.r.t current driver]
Signed-off-by: default avatarAmy Maloche <amaloche@codeaurora.org>
Signed-off-by: default avatarAbinaya P <abinayap@codeaurora.org>
parent fbd89ef4
Loading
Loading
Loading
Loading
+8 −7
Original line number Diff line number Diff line
@@ -563,12 +563,6 @@ static enum flash_area fwu_go_nogo(void)
		goto exit;
	}

	imagePR = kzalloc(sizeof(MAX_FIRMWARE_ID_LEN), GFP_KERNEL);
	if (!imagePR) {
		flash_area = NONE;
		return flash_area;
	}

	/* Force update firmware when device is in bootloader mode */
	if (f01_device_status.flash_prog) {
		dev_info(&i2c_client->dev,
@@ -621,6 +615,11 @@ static enum flash_area fwu_go_nogo(void)
	if (imageFirmwareID > deviceFirmwareID) {
		flash_area = UI_FIRMWARE;
		goto exit;
	} else if (imageFirmwareID < deviceFirmwareID) {
		flash_area = NONE;
		dev_info(&i2c_client->dev,
			"Img fw is older than device fw.  Skip fw update.\n");
		goto exit;
	}

	/* device config id */
@@ -1640,6 +1639,9 @@ static int synaptics_rmi4_fwu_init(struct synaptics_rmi4_data *rmi4_data)
			&fwu->fwu_work,
			msecs_to_jiffies(1000));
#endif

	init_completion(&remove_complete);

	return 0;

exit_remove_attrs:
@@ -1688,7 +1690,6 @@ static int __init rmi4_fw_update_module_init(void)

static void __exit rmi4_fw_update_module_exit(void)
{
	init_completion(&remove_complete);
	synaptics_rmi4_new_function(RMI_FW_UPDATER, false,
			synaptics_rmi4_fwu_init,
			synaptics_rmi4_fwu_remove,
+61 −26
Original line number Diff line number Diff line
@@ -1467,27 +1467,6 @@ static int synaptics_rmi4_query_device(struct synaptics_rmi4_data *rmi4_data)
				}
				break;

			case SYNAPTICS_RMI4_F34:
				if (rmi_fd.intr_src_count == 0)
					break;

				retval = synaptics_rmi4_alloc_fh(&fhandler,
					&rmi_fd, page_number);
				if (retval < 0) {
					dev_err(&rmi4_data->i2c_client->dev,
					"%s: Failed to alloc for F%d\n",
					__func__,
					rmi_fd.fn_number);
					return retval;
				}
				retval = synaptics_rmi4_i2c_read(rmi4_data,
						rmi_fd.ctrl_base_addr,
						rmi->config_id,
						sizeof(rmi->config_id));
				if (retval < 0)
					return retval;
				break;

			case SYNAPTICS_RMI4_F11:
				if (rmi_fd.intr_src_count == 0)
					break;
@@ -1587,14 +1566,51 @@ flash_prog_mode:
	return 0;
}

static int synaptics_rmi4_reset_device(struct synaptics_rmi4_data *rmi4_data)
static int synaptics_rmi4_reset_command(struct synaptics_rmi4_data *rmi4_data)
{
	int retval;
	int page_number;
	unsigned char command = 0x01;
	struct synaptics_rmi4_fn *fhandler;
	struct synaptics_rmi4_device_info *rmi;
	unsigned short pdt_entry_addr;
	struct synaptics_rmi4_fn_desc rmi_fd;
	bool done = false;

	rmi = &(rmi4_data->rmi4_mod_info);
	/* Scan the page description tables of the pages to service */
	for (page_number = 0; page_number < PAGES_TO_SERVICE; page_number++) {
		for (pdt_entry_addr = PDT_START; pdt_entry_addr > PDT_END;
				pdt_entry_addr -= PDT_ENTRY_SIZE) {
			retval = synaptics_rmi4_i2c_read(rmi4_data,
				pdt_entry_addr,
				(unsigned char *)&rmi_fd,
				sizeof(rmi_fd));
			if (retval < 0)
				return retval;

			if (rmi_fd.fn_number == 0)
				break;

			switch (rmi_fd.fn_number) {
			case SYNAPTICS_RMI4_F01:
				rmi4_data->f01_cmd_base_addr =
					rmi_fd.cmd_base_addr;
				done = true;
				break;
			}
		}
		if (done) {
			dev_info(&rmi4_data->i2c_client->dev,
				"%s: Find F01 in page description table 0x%x\n",
				__func__, rmi4_data->f01_cmd_base_addr);
			break;
		}
	}

	if (!done) {
		dev_err(&rmi4_data->i2c_client->dev,
			"%s: Cannot find F01 in page description table\n",
			__func__);
		return -EINVAL;
	}

	retval = synaptics_rmi4_i2c_write(rmi4_data,
			rmi4_data->f01_cmd_base_addr,
@@ -1608,6 +1624,24 @@ static int synaptics_rmi4_reset_device(struct synaptics_rmi4_data *rmi4_data)
	}

	msleep(100);
	return retval;
};

static int synaptics_rmi4_reset_device(struct synaptics_rmi4_data *rmi4_data)
{
	int retval;
	struct synaptics_rmi4_fn *fhandler;
	struct synaptics_rmi4_device_info *rmi;

	rmi = &(rmi4_data->rmi4_mod_info);

	retval = synaptics_rmi4_reset_command(rmi4_data);
	if (retval < 0) {
		dev_err(&rmi4_data->i2c_client->dev,
			"%s: Failed to send command reset\n",
			__func__);
		return retval;
	}

	if (!list_empty(&rmi->support_fn_list)) {
		list_for_each_entry(fhandler, &rmi->support_fn_list, link) {
@@ -2042,7 +2076,8 @@ static int synaptics_rmi4_probe(struct i2c_client *client,
		usleep_range(RMI4_GPIO_SLEEP_LOW_US, RMI4_GPIO_SLEEP_LOW_US+1);
		gpio_set_value(platform_data->reset_gpio, 1);
		msleep(RMI4_GPIO_WAIT_HIGH_MS);
	}
	} else
		synaptics_rmi4_reset_command(rmi4_data);


	init_waitqueue_head(&rmi4_data->wait);
+1 −1
Original line number Diff line number Diff line
@@ -24,7 +24,7 @@
#define SYNAPTICS_DS4 (1 << 0)
#define SYNAPTICS_DS5 (1 << 1)
#define SYNAPTICS_DSX_DRIVER_PRODUCT SYNAPTICS_DS4
#define SYNAPTICS_DSX_DRIVER_VERSION 0x1002
#define SYNAPTICS_DSX_DRIVER_VERSION 0x1004

#include <linux/version.h>
#ifdef CONFIG_HAS_EARLYSUSPEND
+2 −0
Original line number Diff line number Diff line
@@ -616,6 +616,8 @@ static int rmidev_init_device(struct synaptics_rmi4_data *rmi4_data)
		}
	}

	init_completion(&remove_complete);

	return 0;

err_sysfs_attrs: