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

Commit a6869e3a authored by Nick Dyer's avatar Nick Dyer Committed by Dmitry Torokhov
Browse files

Input: synaptics-rmi4 - enable IRQ operation in F34 V7



The polled firmware update proved unreliable when testing on S7817. Use
attention to signal commands are complete.

Signed-off-by: default avatarNick Dyer <nick@shmanahar.org>
Tested-by: default avatarChris Healy <cphealy@gmail.com>
Acked-by: default avatarBenjamin Tissoires <benjamin.tissoires@redhat.com>
Signed-off-by: default avatarDmitry Torokhov <dmitry.torokhov@gmail.com>
parent 25670fb0
Loading
Loading
Loading
Loading
+19 −8
Original line number Original line Diff line number Diff line
@@ -105,16 +105,27 @@ static int rmi_f34_attention(struct rmi_function *fn, unsigned long *irq_bits)
{
{
	struct f34_data *f34 = dev_get_drvdata(&fn->dev);
	struct f34_data *f34 = dev_get_drvdata(&fn->dev);
	int ret;
	int ret;
	u8 status;


	if (f34->bl_version != 5)
	if (f34->bl_version == 5) {
		return 0;
		ret = rmi_read(f34->fn->rmi_dev, f34->v5.ctrl_address,

			       &status);
	ret = rmi_read(f34->fn->rmi_dev, f34->v5.ctrl_address, &f34->v5.status);
		rmi_dbg(RMI_DEBUG_FN, &fn->dev, "%s: status: %#02x, ret: %d\n",
		rmi_dbg(RMI_DEBUG_FN, &fn->dev, "%s: status: %#02x, ret: %d\n",
		__func__, f34->v5.status, ret);
			__func__, status, ret);


	if (!ret && !(f34->v5.status & 0x7f))
		if (!ret && !(status & 0x7f))
			complete(&f34->v5.cmd_done);
			complete(&f34->v5.cmd_done);
	} else {
		ret = rmi_read_block(f34->fn->rmi_dev,
				     f34->fn->fd.data_base_addr +
						f34->v7.off.flash_status,
				     &status, sizeof(status));
		rmi_dbg(RMI_DEBUG_FN, &fn->dev, "%s: status: %#02x, ret: %d\n",
			__func__, status, ret);

		if (!ret && !(status & 0x1f))
			complete(&f34->v7.cmd_done);
	}


	return 0;
	return 0;
}
}
+2 −5
Original line number Original line Diff line number Diff line
@@ -30,6 +30,7 @@
#define F34_IDLE_WAIT_MS	500
#define F34_IDLE_WAIT_MS	500
#define F34_ENABLE_WAIT_MS	300
#define F34_ENABLE_WAIT_MS	300
#define F34_ERASE_WAIT_MS	5000
#define F34_ERASE_WAIT_MS	5000
#define F34_WRITE_WAIT_MS	3000


#define F34_BOOTLOADER_ID_LEN	2
#define F34_BOOTLOADER_ID_LEN	2


@@ -47,11 +48,6 @@
#define CONFIG_ID_SIZE			32
#define CONFIG_ID_SIZE			32
#define PRODUCT_ID_SIZE			10
#define PRODUCT_ID_SIZE			10


#define ENABLE_WAIT_MS			(1 * 1000)
#define WRITE_WAIT_MS			(3 * 1000)

#define MIN_SLEEP_TIME_US		50
#define MAX_SLEEP_TIME_US		100


#define HAS_BSR				BIT(5)
#define HAS_BSR				BIT(5)
#define HAS_CONFIG_ID			BIT(3)
#define HAS_CONFIG_ID			BIT(3)
@@ -292,6 +288,7 @@ struct f34v7_data {


	const void *config_data;
	const void *config_data;
	const void *image;
	const void *image;
	struct completion cmd_done;
};
};


struct f34_data {
struct f34_data {
+62 −55
Original line number Original line Diff line number Diff line
@@ -15,6 +15,7 @@
#include <asm/unaligned.h>
#include <asm/unaligned.h>
#include <linux/delay.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/slab.h>
#include <linux/jiffies.h>


#include "rmi_driver.h"
#include "rmi_driver.h"
#include "rmi_f34.h"
#include "rmi_f34.h"
@@ -31,7 +32,7 @@ static int rmi_f34v7_read_flash_status(struct f34_data *f34)
			sizeof(status));
			sizeof(status));
	if (ret < 0) {
	if (ret < 0) {
		rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev,
		rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev,
			"%s: Failed to read flash status\n", __func__);
			"%s: Error %d reading flash status\n", __func__, ret);
		return ret;
		return ret;
	}
	}


@@ -60,28 +61,17 @@ static int rmi_f34v7_read_flash_status(struct f34_data *f34)


static int rmi_f34v7_wait_for_idle(struct f34_data *f34, int timeout_ms)
static int rmi_f34v7_wait_for_idle(struct f34_data *f34, int timeout_ms)
{
{
	int count = 0;
	unsigned long timeout;
	int timeout_count = ((timeout_ms * 1000) / MAX_SLEEP_TIME_US) + 1;


	do {
	timeout = msecs_to_jiffies(timeout_ms);
		usleep_range(MIN_SLEEP_TIME_US, MAX_SLEEP_TIME_US);

		count++;

		rmi_f34v7_read_flash_status(f34);


		if ((f34->v7.command == v7_CMD_IDLE)
	if (!wait_for_completion_timeout(&f34->v7.cmd_done, timeout)) {
		    && (f34->v7.flash_status == 0x00)) {
		dev_warn(&f34->fn->dev, "%s: Timed out waiting for idle status\n",
			rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev,
			 __func__);
				"Idle status detected\n");
		return -ETIMEDOUT;
			return 0;
	}
	}
	} while (count < timeout_count);

	dev_err(&f34->fn->dev,
		"%s: Timed out waiting for idle status\n", __func__);


	return -ETIMEDOUT;
	return 0;
}
}


static int rmi_f34v7_write_command_single_transaction(struct f34_data *f34,
static int rmi_f34v7_write_command_single_transaction(struct f34_data *f34,
@@ -285,9 +275,10 @@ static int rmi_f34v7_write_partition_id(struct f34_data *f34, u8 cmd)
	return 0;
	return 0;
}
}


static int rmi_f34v7_read_f34v7_partition_table(struct f34_data *f34)
static int rmi_f34v7_read_partition_table(struct f34_data *f34)
{
{
	int ret;
	int ret;
	unsigned long timeout;
	u8 base;
	u8 base;
	__le16 length;
	__le16 length;
	u16 block_number = 0;
	u16 block_number = 0;
@@ -320,6 +311,8 @@ static int rmi_f34v7_read_f34v7_partition_table(struct f34_data *f34)
		return ret;
		return ret;
	}
	}


	init_completion(&f34->v7.cmd_done);

	ret = rmi_f34v7_write_command(f34, v7_CMD_READ_CONFIG);
	ret = rmi_f34v7_write_command(f34, v7_CMD_READ_CONFIG);
	if (ret < 0) {
	if (ret < 0) {
		dev_err(&f34->fn->dev, "%s: Failed to write command\n",
		dev_err(&f34->fn->dev, "%s: Failed to write command\n",
@@ -327,11 +320,15 @@ static int rmi_f34v7_read_f34v7_partition_table(struct f34_data *f34)
		return ret;
		return ret;
	}
	}


	ret = rmi_f34v7_wait_for_idle(f34, WRITE_WAIT_MS);
	timeout = msecs_to_jiffies(F34_WRITE_WAIT_MS);
	if (ret < 0) {
	while (time_before(jiffies, timeout)) {
		dev_err(&f34->fn->dev, "%s: Failed to wait for idle status\n",
		usleep_range(5000, 6000);
			__func__);
		rmi_f34v7_read_flash_status(f34);
		return ret;

		if (f34->v7.command == v7_CMD_IDLE &&
		    f34->v7.flash_status == 0x00) {
			break;
		}
	}
	}


	ret = rmi_read_block(f34->fn->rmi_dev,
	ret = rmi_read_block(f34->fn->rmi_dev,
@@ -570,7 +567,7 @@ static int rmi_f34v7_read_queries(struct f34_data *f34)
	f34->v7.read_config_buf_size = f34->v7.partition_table_bytes;
	f34->v7.read_config_buf_size = f34->v7.partition_table_bytes;
	ptable = f34->v7.read_config_buf;
	ptable = f34->v7.read_config_buf;


	ret = rmi_f34v7_read_f34v7_partition_table(f34);
	ret = rmi_f34v7_read_partition_table(f34);
	if (ret < 0) {
	if (ret < 0) {
		dev_err(&f34->fn->dev, "%s: Failed to read partition table\n",
		dev_err(&f34->fn->dev, "%s: Failed to read partition table\n",
				__func__);
				__func__);
@@ -666,6 +663,8 @@ static int rmi_f34v7_erase_config(struct f34_data *f34)


	dev_info(&f34->fn->dev, "Erasing config...\n");
	dev_info(&f34->fn->dev, "Erasing config...\n");


	init_completion(&f34->v7.cmd_done);

	switch (f34->v7.config_area) {
	switch (f34->v7.config_area) {
	case v7_UI_CONFIG_AREA:
	case v7_UI_CONFIG_AREA:
		ret = rmi_f34v7_write_command(f34, v7_CMD_ERASE_UI_CONFIG);
		ret = rmi_f34v7_write_command(f34, v7_CMD_ERASE_UI_CONFIG);
@@ -684,11 +683,11 @@ static int rmi_f34v7_erase_config(struct f34_data *f34)
		break;
		break;
	}
	}


	ret = rmi_f34v7_wait_for_idle(f34, ENABLE_WAIT_MS);
	ret = rmi_f34v7_wait_for_idle(f34, F34_ERASE_WAIT_MS);
	if (ret < 0)
	if (ret < 0)
		return ret;
		return ret;


	return ret;
	return 0;
}
}


static int rmi_f34v7_erase_guest_code(struct f34_data *f34)
static int rmi_f34v7_erase_guest_code(struct f34_data *f34)
@@ -697,11 +696,13 @@ static int rmi_f34v7_erase_guest_code(struct f34_data *f34)


	dev_info(&f34->fn->dev, "Erasing guest code...\n");
	dev_info(&f34->fn->dev, "Erasing guest code...\n");


	init_completion(&f34->v7.cmd_done);

	ret = rmi_f34v7_write_command(f34, v7_CMD_ERASE_GUEST_CODE);
	ret = rmi_f34v7_write_command(f34, v7_CMD_ERASE_GUEST_CODE);
	if (ret < 0)
	if (ret < 0)
		return ret;
		return ret;


	ret = rmi_f34v7_wait_for_idle(f34, ENABLE_WAIT_MS);
	ret = rmi_f34v7_wait_for_idle(f34, F34_ERASE_WAIT_MS);
	if (ret < 0)
	if (ret < 0)
		return ret;
		return ret;


@@ -714,11 +715,13 @@ static int rmi_f34v7_erase_all(struct f34_data *f34)


	dev_info(&f34->fn->dev, "Erasing firmware...\n");
	dev_info(&f34->fn->dev, "Erasing firmware...\n");


	init_completion(&f34->v7.cmd_done);

	ret = rmi_f34v7_write_command(f34, v7_CMD_ERASE_UI_FIRMWARE);
	ret = rmi_f34v7_write_command(f34, v7_CMD_ERASE_UI_FIRMWARE);
	if (ret < 0)
	if (ret < 0)
		return ret;
		return ret;


	ret = rmi_f34v7_wait_for_idle(f34, ENABLE_WAIT_MS);
	ret = rmi_f34v7_wait_for_idle(f34, F34_ERASE_WAIT_MS);
	if (ret < 0)
	if (ret < 0)
		return ret;
		return ret;


@@ -743,8 +746,8 @@ static int rmi_f34v7_erase_all(struct f34_data *f34)
	return 0;
	return 0;
}
}


static int rmi_f34v7_read_f34v7_blocks(struct f34_data *f34, u16 block_cnt,
static int rmi_f34v7_read_blocks(struct f34_data *f34,
				       u8 command)
				 u16 block_cnt, u8 command)
{
{
	int ret;
	int ret;
	u8 base;
	u8 base;
@@ -787,17 +790,15 @@ static int rmi_f34v7_read_f34v7_blocks(struct f34_data *f34, u16 block_cnt,
			return ret;
			return ret;
		}
		}


		init_completion(&f34->v7.cmd_done);

		ret = rmi_f34v7_write_command(f34, command);
		ret = rmi_f34v7_write_command(f34, command);
		if (ret < 0)
		if (ret < 0)
			return ret;
			return ret;


		ret = rmi_f34v7_wait_for_idle(f34, ENABLE_WAIT_MS);
		ret = rmi_f34v7_wait_for_idle(f34, F34_ENABLE_WAIT_MS);
		if (ret < 0) {
		if (ret < 0)
			dev_err(&f34->fn->dev,
				"%s: Wait for idle failed (%d blks remaining)\n",
				__func__, remaining);
			return ret;
			return ret;
		}


		ret = rmi_read_block(f34->fn->rmi_dev,
		ret = rmi_read_block(f34->fn->rmi_dev,
				base + f34->v7.off.payload,
				base + f34->v7.off.payload,
@@ -853,6 +854,8 @@ static int rmi_f34v7_write_f34v7_blocks(struct f34_data *f34,
		transfer = min(remaining, max_transfer);
		transfer = min(remaining, max_transfer);
		put_unaligned_le16(transfer, &length);
		put_unaligned_le16(transfer, &length);


		init_completion(&f34->v7.cmd_done);

		ret = rmi_write_block(f34->fn->rmi_dev,
		ret = rmi_write_block(f34->fn->rmi_dev,
				base + f34->v7.off.transfer_length,
				base + f34->v7.off.transfer_length,
				&length, sizeof(length));
				&length, sizeof(length));
@@ -877,13 +880,9 @@ static int rmi_f34v7_write_f34v7_blocks(struct f34_data *f34,
			return ret;
			return ret;
		}
		}


		ret = rmi_f34v7_wait_for_idle(f34, ENABLE_WAIT_MS);
		ret = rmi_f34v7_wait_for_idle(f34, F34_ENABLE_WAIT_MS);
		if (ret < 0) {
		if (ret < 0)
			dev_err(&f34->fn->dev,
				"%s: Failed wait for idle (%d blks remaining)\n",
				__func__, remaining);
			return ret;
			return ret;
		}


		block_ptr += (transfer * f34->v7.block_size);
		block_ptr += (transfer * f34->v7.block_size);
		remaining -= transfer;
		remaining -= transfer;
@@ -945,6 +944,8 @@ static int rmi_f34v7_write_flash_config(struct f34_data *f34)
		return -EINVAL;
		return -EINVAL;
	}
	}


	init_completion(&f34->v7.cmd_done);

	ret = rmi_f34v7_write_command(f34, v7_CMD_ERASE_FLASH_CONFIG);
	ret = rmi_f34v7_write_command(f34, v7_CMD_ERASE_FLASH_CONFIG);
	if (ret < 0)
	if (ret < 0)
		return ret;
		return ret;
@@ -952,7 +953,7 @@ static int rmi_f34v7_write_flash_config(struct f34_data *f34)
	rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev,
	rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev,
		"%s: Erase flash config command written\n", __func__);
		"%s: Erase flash config command written\n", __func__);


	ret = rmi_f34v7_wait_for_idle(f34, ENABLE_WAIT_MS);
	ret = rmi_f34v7_wait_for_idle(f34, F34_WRITE_WAIT_MS);
	if (ret < 0)
	if (ret < 0)
		return ret;
		return ret;


@@ -981,7 +982,7 @@ static int rmi_f34v7_write_partition_table(struct f34_data *f34)


	f34->v7.read_config_buf_size = f34->v7.config_size;
	f34->v7.read_config_buf_size = f34->v7.config_size;


	ret = rmi_f34v7_read_f34v7_blocks(f34, block_count, v7_CMD_READ_CONFIG);
	ret = rmi_f34v7_read_blocks(f34, block_count, v7_CMD_READ_CONFIG);
	if (ret < 0)
	if (ret < 0)
		return ret;
		return ret;


@@ -1287,6 +1288,8 @@ static int rmi_f34v7_enter_flash_prog(struct f34_data *f34)
{
{
	int ret;
	int ret;


	f34->fn->rmi_dev->driver->set_irq_bits(f34->fn->rmi_dev, f34->fn->irq_mask);

	ret = rmi_f34v7_read_flash_status(f34);
	ret = rmi_f34v7_read_flash_status(f34);
	if (ret < 0)
	if (ret < 0)
		return ret;
		return ret;
@@ -1294,19 +1297,16 @@ static int rmi_f34v7_enter_flash_prog(struct f34_data *f34)
	if (f34->v7.in_bl_mode)
	if (f34->v7.in_bl_mode)
		return 0;
		return 0;


	init_completion(&f34->v7.cmd_done);

	ret = rmi_f34v7_write_command(f34, v7_CMD_ENABLE_FLASH_PROG);
	ret = rmi_f34v7_write_command(f34, v7_CMD_ENABLE_FLASH_PROG);
	if (ret < 0)
	if (ret < 0)
		return ret;
		return ret;


	ret = rmi_f34v7_wait_for_idle(f34, ENABLE_WAIT_MS);
	ret = rmi_f34v7_wait_for_idle(f34, F34_ENABLE_WAIT_MS);
	if (ret < 0)
	if (ret < 0)
		return ret;
		return ret;


	if (!f34->v7.in_bl_mode) {
		dev_err(&f34->fn->dev, "%s: BL mode not entered\n", __func__);
		return -EINVAL;
	}

	return 0;
	return 0;
}
}


@@ -1314,6 +1314,8 @@ int rmi_f34v7_start_reflash(struct f34_data *f34, const struct firmware *fw)
{
{
	int ret = 0;
	int ret = 0;


	f34->fn->rmi_dev->driver->set_irq_bits(f34->fn->rmi_dev, f34->fn->irq_mask);

	f34->v7.config_area = v7_UI_CONFIG_AREA;
	f34->v7.config_area = v7_UI_CONFIG_AREA;
	f34->v7.image = fw->data;
	f34->v7.image = fw->data;


@@ -1376,8 +1378,13 @@ int rmi_f34v7_probe(struct f34_data *f34)


	memset(&f34->v7.blkcount, 0x00, sizeof(f34->v7.blkcount));
	memset(&f34->v7.blkcount, 0x00, sizeof(f34->v7.blkcount));
	memset(&f34->v7.phyaddr, 0x00, sizeof(f34->v7.phyaddr));
	memset(&f34->v7.phyaddr, 0x00, sizeof(f34->v7.phyaddr));
	rmi_f34v7_read_queries(f34);


	f34->v7.force_update = false;
	init_completion(&f34->v7.cmd_done);

	ret = rmi_f34v7_read_queries(f34);
	if (ret < 0)
		return ret;

	f34->v7.force_update = true;
	return 0;
	return 0;
}
}