All of lore.kernel.org
 help / color / mirror / Atom feed
From: Marek Vasut <marex@denx.de>
To: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Cc: linux-input@vger.kernel.org, ch@denx.de,
	Joe Hung <joe_hung@ilitek.com>, Luca Hsu <luca_hsu@ilitek.com>
Subject: Re: [PATCH v2 3/3] Input: ili210x - add ili251x firmware update support
Date: Tue, 31 Aug 2021 01:27:21 +0200	[thread overview]
Message-ID: <3233bfac-6d9d-da86-c4f9-18a9eab326d4@denx.de> (raw)
In-Reply-To: <YS1KLkCX01tlHBcy@google.com>

On 8/30/21 11:14 PM, Dmitry Torokhov wrote:

[...]

>> +	if (ret) {
>> +		dev_err(dev, "Failed to request firmware %s, ret=%d\n", fwname, ret);
>> +		return ret;
>> +	}
>> +
>> +	/*
>> +	 * The firmware ihex blob can never be bigger than 64 kiB, so make this
>> +	 * simple -- allocate a 64 kiB buffer, iterate over the ihex blob records
>> +	 * once, copy them all into this buffer at the right locations, and then
>> +	 * do all operations on this linear buffer.
>> +	 */
>> +	fw_buf = kcalloc(1, SZ_64K, GFP_KERNEL);
> 
> Why kcalloc and not kzalloc?

Because the firmware blob might be sparse (with gaps in it) and those 
gaps should be zeroed out instead of random data (see your question 
about the 32 byte long memcpy() below (*) as well).

>> +	if (!fw_buf) {
>> +		ret = -ENOMEM;
>> +		goto err_alloc;
>> +	}
>> +
>> +	rec = (const struct ihex_binrec *)fw->data;
>> +	while (rec) {
>> +		fw_addr = be32_to_cpu(rec->addr);
>> +		fw_len = be16_to_cpu(rec->len);
>> +
>> +		if (fw_addr + fw_len > SZ_64K) {
>> +			ret = -EFBIG;
>> +			goto err_big;
>> +		}
>> +
>> +		/* Find the last address before DF start address, that is AC end */
>> +		if (fw_addr == 0xf000)
>> +			*ac_end = fw_last_addr;
>> +		fw_last_addr = fw_addr + fw_len;
>> +
>> +		memcpy(fw_buf + fw_addr, rec->data, fw_len);
>> +		rec = ihex_next_binrec(rec);
>> +	}

[...]

>> +static int ili251x_firmware_busy(struct i2c_client *client)
>> +{
>> +	struct ili210x *priv = i2c_get_clientdata(client);
>> +	int ret, i = 0;
>> +	u8 data;
>> +
>> +	do {
>> +		/* The read_reg already contains suitable delay */
>> +		ret = priv->chip->read_reg(client, 0x80, &data, 1);
> 
> Can we have symbolic name for this register (and others).

The name of this one isn't part of the example code, so ... I can call 
it something, but who knows what it really is.

I believe I did manage to find what the other registers are called already.

[...]

>> +	ret = ili251x_firmware_busy(client);
>> +	if (ret)
>> +		return ret;
>> +
>> +	for (fw_addr = start; fw_addr < end; fw_addr += 32) {
>> +		fw_data[0] = REG_WRITE_DATA;
>> +		memcpy(&(fw_data[1]), fwbuf + fw_addr, 32);
> 
> Is it guaranteed that we have enough data (32 bytes) and we will not
> reach past the buffer?

Yes, see above (*). If the firmware blob entry were too short, this 
would pull in zeroes.

I tried iterating through the firmware file, but using linear buffer for 
the firmware results in far less convoluted code, and considering it is 
not performance critical, I think this is ok.

[...]

>> +static ssize_t ili210x_firmware_update_store(struct device *dev,
>> +					     struct device_attribute *attr,
>> +					     const char *buf, size_t count)
>> +{
>> +	struct i2c_client *client = to_i2c_client(dev);
>> +	struct ili210x *priv = i2c_get_clientdata(client);
>> +	char fwname[NAME_MAX];
>> +	u16 ac_end, df_end;
>> +	u8 *fwbuf;
>> +	int ret;
>> +	int i;
>> +
>> +	if (count >= NAME_MAX) {
>> +		dev_err(dev, "File name too long\n");
>> +		return -EINVAL;
>> +	}
>> +
>> +	memcpy(fwname, buf, count);
>> +	if (fwname[count - 1] == '\n')
>> +		fwname[count - 1] = '\0';
>> +	else
>> +		fwname[count] = '\0';
> 
> I believe the practice is to use constant firmware name based on driver
> or chip name. If there is desire to allow dynamic firmware name for
> given device I think it should be handled at firmware loader core.

There are a couple of input devices which do similar thing, see e.g.:
drivers/input/mouse/cyapa.c
drivers/input/rmi4/rmi_f34.c

The ilitek firmware contains both firmware and calibration data, so you 
might end up with a usecase where you switch between different firmware 
blobs at runtime.

That's why it is implemented this way.

[...]

  reply	other threads:[~2021-08-30 23:27 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-08-27 21:12 [PATCH v2 1/3] Input: ili210x - use resolution from ili251x firmware Marek Vasut
2021-08-27 21:12 ` [PATCH v2 2/3] Input: ili210x - export ili251x version details via sysfs Marek Vasut
2021-08-30 21:01   ` Dmitry Torokhov
2021-08-30 23:02     ` Marek Vasut
2021-08-30 23:20       ` Dmitry Torokhov
2021-08-30 23:33         ` Marek Vasut
2021-08-30 23:45           ` Dmitry Torokhov
2021-08-27 21:12 ` [PATCH v2 3/3] Input: ili210x - add ili251x firmware update support Marek Vasut
2021-08-30 21:14   ` Dmitry Torokhov
2021-08-30 23:27     ` Marek Vasut [this message]
2021-08-31  2:05       ` Dmitry Torokhov
2021-08-30 20:55 ` [PATCH v2 1/3] Input: ili210x - use resolution from ili251x firmware Dmitry Torokhov
2021-08-30 22:49   ` Marek Vasut
2021-08-30 23:21     ` Dmitry Torokhov
2021-08-30 23:31       ` Marek Vasut
2021-08-30 23:46         ` Dmitry Torokhov
2021-08-31  0:01           ` Marek Vasut

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=3233bfac-6d9d-da86-c4f9-18a9eab326d4@denx.de \
    --to=marex@denx.de \
    --cc=ch@denx.de \
    --cc=dmitry.torokhov@gmail.com \
    --cc=joe_hung@ilitek.com \
    --cc=linux-input@vger.kernel.org \
    --cc=luca_hsu@ilitek.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.