@@ -134,6 +134,7 @@ static int gc0310_write_reg(struct i2c_client *client, u16 data_length,
* gc0310_write_reg_array - Initializes a list of GC0310 registers
* @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
@@ -202,39 +203,28 @@ static int __gc0310_write_reg_is_consecutive(struct i2c_client *client,
}
static int gc0310_write_reg_array(struct i2c_client *client,
- const struct gc0310_reg *reglist)
+ const struct gc0310_reg *reglist, int count)
{
- const struct gc0310_reg *next = reglist;
struct gc0310_write_ctrl ctrl;
- int err;
+ int i, err;
ctrl.index = 0;
- for (; next->type != GC0310_TOK_TERM; next++) {
- switch (next->type & GC0310_TOK_MASK) {
- case GC0310_TOK_DELAY:
+ 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,
+ ®list[i])) {
err = __gc0310_flush_reg_array(client, &ctrl);
if (err)
return err;
- msleep(next->val);
- break;
- default:
- /*
- * If next address is not consecutive, data needs to be
- * flushed before proceed.
- */
- if (!__gc0310_write_reg_is_consecutive(client, &ctrl,
- next)) {
- err = __gc0310_flush_reg_array(client, &ctrl);
- if (err)
- return err;
- }
- err = __gc0310_buf_reg_array(client, &ctrl, next);
- if (err) {
- dev_err(&client->dev, "%s: write error, aborted\n",
- __func__);
- return err;
- }
- break;
+ }
+ err = __gc0310_buf_reg_array(client, &ctrl, ®list[i]);
+ if (err) {
+ dev_err(&client->dev, "%s: write error, aborted\n",
+ __func__);
+ return err;
}
}
@@ -478,7 +468,8 @@ static int gc0310_init(struct v4l2_subdev *sd)
mutex_lock(&dev->input_lock);
/* set initial registers */
- ret = gc0310_write_reg_array(client, gc0310_reset_register);
+ ret = gc0310_write_reg_array(client, gc0310_reset_register,
+ ARRAY_SIZE(gc0310_reset_register));
/* restore settings */
gc0310_res = gc0310_res_preview;
@@ -648,7 +639,7 @@ static int startup(struct v4l2_subdev *sd)
struct i2c_client *client = v4l2_get_subdevdata(sd);
int ret = 0;
- ret = gc0310_write_reg_array(client, dev->res->regs);
+ ret = gc0310_write_reg_array(client, dev->res->regs, dev->res->reg_count);
if (ret) {
dev_err(&client->dev, "gc0310 write register err.\n");
return ret;
@@ -110,6 +110,7 @@
struct gc0310_resolution {
u8 *desc;
const struct gc0310_reg *regs;
+ int reg_count;
int res;
int width;
int height;
@@ -139,9 +140,6 @@ struct gc0310_device {
enum gc0310_tok_type {
GC0310_8BIT = 0x0001,
- GC0310_TOK_TERM = 0xf000, /* terminating token for reg list */
- GC0310_TOK_DELAY = 0xfe00, /* delay token for reg list */
- GC0310_TOK_MASK = 0xfff0
};
/**
@@ -330,8 +328,6 @@ static const struct gc0310_reg gc0310_reset_register[] = {
{GC0310_8BIT, 0x48, 0x03}, //sun mode
{GC0310_8BIT, 0x4f, 0x60}, //sun_clamp
{GC0310_8BIT, 0xfe, 0x00},
-
- {GC0310_TOK_TERM, 0, 0},
};
static struct gc0310_reg const gc0310_VGA_30fps[] = {
@@ -356,8 +352,6 @@ static struct gc0310_reg const gc0310_VGA_30fps[] = {
{GC0310_8BIT, 0x13, 0x02},//05 //05 //LWC[15:8]
{GC0310_8BIT, 0xfe, 0x00},
-
- {GC0310_TOK_TERM, 0, 0},
};
static struct gc0310_resolution gc0310_res_preview[] = {
@@ -374,6 +368,7 @@ static struct gc0310_resolution gc0310_res_preview[] = {
#endif
.skip_frames = 2,
.regs = gc0310_VGA_30fps,
+ .reg_count = ARRAY_SIZE(gc0310_VGA_30fps),
},
};
Remove the ability to have special tokens in a reg-list, GC0310_TOK_DELAY is not used and GC0310_TOK_TERM can be replaced with ARRAY_SIZE, simplifying the code. Signed-off-by: Hans de Goede <hdegoede@redhat.com> --- .../media/atomisp/i2c/atomisp-gc0310.c | 47 ++++++++----------- drivers/staging/media/atomisp/i2c/gc0310.h | 9 +--- 2 files changed, 21 insertions(+), 35 deletions(-)