Commit e1a4b3a7 authored by Hans de Goede's avatar Hans de Goede Committed by Mauro Carvalho Chehab

media: atomisp: gc0310: Simplify gc0310_write_reg_array()

Remove the complex optimization to send multiple registers in
one i2c-transfer. None of the other sensor drivers are doing this
and the reg-lists are only used once at stream-start time, so
this does not need to be highly optimized.
Reviewed-by: default avatarAndy Shevchenko <andy.shevchenko@gmail.com>
Signed-off-by: default avatarHans de Goede <hdegoede@redhat.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@kernel.org>
parent bfe06aee
......@@ -135,100 +135,19 @@ static int gc0310_write_reg(struct i2c_client *client, u16 data_length,
* @client: i2c driver client structure
* @reglist: list of registers to be written
* @count: number of register, value pairs in the list
*
* This function initializes a list of registers. When consecutive addresses
* are found in a row on the list, this function creates a buffer and sends
* consecutive data in a single i2c_transfer().
*
* __gc0310_flush_reg_array, __gc0310_buf_reg_array() and
* __gc0310_write_reg_is_consecutive() are internal functions to
* gc0310_write_reg_array_fast() and should be not used anywhere else.
*
*/
static int __gc0310_flush_reg_array(struct i2c_client *client,
struct gc0310_write_ctrl *ctrl)
{
u16 size;
if (ctrl->index == 0)
return 0;
size = sizeof(u8) + ctrl->index; /* 8-bit address + data */
ctrl->buffer.addr = (u8)(ctrl->buffer.addr);
ctrl->index = 0;
return gc0310_i2c_write(client, size, (u8 *)&ctrl->buffer);
}
static int __gc0310_buf_reg_array(struct i2c_client *client,
struct gc0310_write_ctrl *ctrl,
const struct gc0310_reg *next)
{
int size;
switch (next->type) {
case GC0310_8BIT:
size = 1;
ctrl->buffer.data[ctrl->index] = (u8)next->val;
break;
default:
return -EINVAL;
}
/* When first item is added, we need to store its starting address */
if (ctrl->index == 0)
ctrl->buffer.addr = next->reg;
ctrl->index += size;
/*
* Buffer cannot guarantee free space for u32? Better flush it to avoid
* possible lack of memory for next item.
*/
if (ctrl->index + sizeof(u8) >= GC0310_MAX_WRITE_BUF_SIZE)
return __gc0310_flush_reg_array(client, ctrl);
return 0;
}
static int __gc0310_write_reg_is_consecutive(struct i2c_client *client,
struct gc0310_write_ctrl *ctrl,
const struct gc0310_reg *next)
{
if (ctrl->index == 0)
return 1;
return ctrl->buffer.addr + ctrl->index == next->reg;
}
static int gc0310_write_reg_array(struct i2c_client *client,
const struct gc0310_reg *reglist, int count)
{
struct gc0310_write_ctrl ctrl;
int i, err;
ctrl.index = 0;
for (i = 0; i < count; i++) {
/*
* If next address is not consecutive, data needs to be
* flushed before proceed.
*/
if (!__gc0310_write_reg_is_consecutive(client, &ctrl,
&reglist[i])) {
err = __gc0310_flush_reg_array(client, &ctrl);
if (err)
return err;
}
err = __gc0310_buf_reg_array(client, &ctrl, &reglist[i]);
if (err) {
dev_err(&client->dev, "%s: write error, aborted\n",
__func__);
err = gc0310_write_reg(client, GC0310_8BIT, reglist[i].reg, reglist[i].val);
if (err)
return err;
}
}
return __gc0310_flush_reg_array(client, &ctrl);
return 0;
}
static int gc0310_set_gain(struct v4l2_subdev *sd, int gain)
......
......@@ -158,18 +158,6 @@ struct gc0310_reg {
#define to_gc0310_sensor(x) container_of(x, struct gc0310_device, sd)
#define GC0310_MAX_WRITE_BUF_SIZE 30
struct gc0310_write_buffer {
u8 addr;
u8 data[GC0310_MAX_WRITE_BUF_SIZE];
};
struct gc0310_write_ctrl {
int index;
struct gc0310_write_buffer buffer;
};
/*
* Register settings for various resolution
*/
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment