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

Commit 96700d24 authored by Antti Palosaari's avatar Antti Palosaari Committed by Mauro Carvalho Chehab
Browse files

[media] af9013: refactor firmware download routine



Refactor firmware download routine.

Signed-off-by: default avatarAntti Palosaari <crope@iki.fi>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@s-opensource.com>
parent b5e0e1a3
Loading
Loading
Loading
Loading
+30 −35
Original line number Original line Diff line number Diff line
@@ -1137,64 +1137,59 @@ static const struct dvb_frontend_ops af9013_ops;
static int af9013_download_firmware(struct af9013_state *state)
static int af9013_download_firmware(struct af9013_state *state)
{
{
	struct i2c_client *client = state->client;
	struct i2c_client *client = state->client;
	int ret, i, len, remaining;
	int ret, i, len, rem;
	unsigned int utmp;
	unsigned int utmp;
	const struct firmware *fw;
	u8 buf[4];
	u16 checksum = 0;
	u16 checksum = 0;
	u8 fw_params[4];
	const struct firmware *firmware;
	u8 *fw_file = AF9013_FIRMWARE;
	const char *name = AF9013_FIRMWARE;


	msleep(100);
	dev_dbg(&client->dev, "\n");
	/* check whether firmware is already running */

	/* Check whether firmware is already running */
	ret = regmap_read(state->regmap, 0x98be, &utmp);
	ret = regmap_read(state->regmap, 0x98be, &utmp);
	if (ret)
	if (ret)
		goto err;
		goto err;


	dev_dbg(&client->dev, "firmware status %02x\n", utmp);
	dev_dbg(&client->dev, "firmware status %02x\n", utmp);


	if (utmp == 0x0c) /* fw is running, no need for download */
	if (utmp == 0x0c)
		return 0;
		return 0;


	dev_info(&client->dev, "found a '%s' in cold state, will try to load a firmware\n",
	dev_info(&client->dev, "found a '%s' in cold state, will try to load a firmware\n",
		 af9013_ops.info.name);
		 af9013_ops.info.name);


	/* request the firmware, this will block and timeout */
	/* Request the firmware, will block and timeout */
	ret = request_firmware(&fw, fw_file, &client->dev);
	ret = request_firmware(&firmware, name, &client->dev);
	if (ret) {
	if (ret) {
		dev_info(&client->dev, "firmware file '%s' not found %d\n",
		dev_info(&client->dev, "firmware file '%s' not found %d\n",
			 fw_file, ret);
			 name, ret);
		goto err;
		goto err;
	}
	}


	dev_info(&client->dev, "downloading firmware from file '%s'\n",
	dev_info(&client->dev, "downloading firmware from file '%s'\n",
		 fw_file);
		 name);

	/* calc checksum */
	for (i = 0; i < fw->size; i++)
		checksum += fw->data[i];


	fw_params[0] = checksum >> 8;
	/* Write firmware checksum & size */
	fw_params[1] = checksum & 0xff;
	for (i = 0; i < firmware->size; i++)
	fw_params[2] = fw->size >> 8;
		checksum += firmware->data[i];
	fw_params[3] = fw->size & 0xff;

	/* write fw checksum & size */
	ret = regmap_bulk_write(state->regmap, 0x50fc, fw_params,
				sizeof(fw_params));


	buf[0] = (checksum >> 8) & 0xff;
	buf[1] = (checksum >> 0) & 0xff;
	buf[2] = (firmware->size >> 8) & 0xff;
	buf[3] = (firmware->size >> 0) & 0xff;
	ret = regmap_bulk_write(state->regmap, 0x50fc, buf, 4);
	if (ret)
	if (ret)
		goto err_release_firmware;
		goto err_release_firmware;


	#define FW_ADDR 0x5100 /* firmware start address */
	/* Download firmware */
	#define LEN_MAX 16 /* max packet size */
	#define LEN_MAX 16
	for (remaining = fw->size; remaining > 0; remaining -= LEN_MAX) {
	for (rem = firmware->size; rem > 0; rem -= LEN_MAX) {
		len = remaining;
		len = min(LEN_MAX, rem);
		if (len > LEN_MAX)
			len = LEN_MAX;

		ret = regmap_bulk_write(state->regmap,
		ret = regmap_bulk_write(state->regmap,
					FW_ADDR + fw->size - remaining,
					0x5100 + firmware->size - rem,
					&fw->data[fw->size - remaining], len);
					&firmware->data[firmware->size - rem],
					len);
		if (ret) {
		if (ret) {
			dev_err(&client->dev, "firmware download failed %d\n",
			dev_err(&client->dev, "firmware download failed %d\n",
				ret);
				ret);
@@ -1202,9 +1197,9 @@ static int af9013_download_firmware(struct af9013_state *state)
		}
		}
	}
	}


	release_firmware(fw);
	release_firmware(firmware);


	/* request boot firmware */
	/* Boot firmware */
	ret = regmap_write(state->regmap, 0xe205, 0x01);
	ret = regmap_write(state->regmap, 0xe205, 0x01);
	if (ret)
	if (ret)
		goto err;
		goto err;
@@ -1233,7 +1228,7 @@ static int af9013_download_firmware(struct af9013_state *state)


	return 0;
	return 0;
err_release_firmware:
err_release_firmware:
	release_firmware(fw);
	release_firmware(firmware);
err:
err:
	dev_dbg(&client->dev, "failed %d\n", ret);
	dev_dbg(&client->dev, "failed %d\n", ret);
	return ret;
	return ret;