mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-30 18:47:06 +00:00
182 lines
4.9 KiB
Diff
182 lines
4.9 KiB
Diff
|
From 4ae4ea08f58f394a82b99417230ce63ce53e68e3 Mon Sep 17 00:00:00 2001
|
||
|
From: Markus Proeller <markus.proeller@pieye.org>
|
||
|
Date: Tue, 16 Jun 2020 13:33:56 +0200
|
||
|
Subject: [PATCH] media: irs1125: Keep HW in sync after imager reset
|
||
|
|
||
|
When closing the video device, the irs1125 is put in power down state.
|
||
|
To keep V4L2 ctrls and the HW in sync, v4l2_ctrl_handler_setup is
|
||
|
called after power up.
|
||
|
|
||
|
The compound ctrl IRS1125_CID_MOD_PLL however has a default value
|
||
|
of all zeros, which puts the imager into a non responding state.
|
||
|
Thus, this ctrl is not written by the driver into HW after power up.
|
||
|
The userspace has to take care to write senseful data.
|
||
|
|
||
|
Signed-off-by: Markus Proeller <markus.proeller@pieye.org>
|
||
|
---
|
||
|
drivers/media/i2c/irs1125.c | 121 +++++++++++++++++-------------------
|
||
|
1 file changed, 58 insertions(+), 63 deletions(-)
|
||
|
|
||
|
--- a/drivers/media/i2c/irs1125.c
|
||
|
+++ b/drivers/media/i2c/irs1125.c
|
||
|
@@ -82,6 +82,7 @@ struct irs1125 {
|
||
|
struct v4l2_ctrl *ctrl_numseq;
|
||
|
|
||
|
int power_count;
|
||
|
+ bool mod_pll_init;
|
||
|
};
|
||
|
|
||
|
static inline struct irs1125 *to_state(struct v4l2_subdev *sd)
|
||
|
@@ -276,8 +277,7 @@ static struct regval_list irs1125_seq_cf
|
||
|
{0xC039, 0x0000},
|
||
|
{0xC401, 0x0002},
|
||
|
|
||
|
- {0xFFFF, 1},
|
||
|
- {0xA87C, 0x0001}
|
||
|
+ {0xFFFF, 1}
|
||
|
};
|
||
|
|
||
|
static int irs1125_write(struct v4l2_subdev *sd, u16 reg, u16 val)
|
||
|
@@ -471,7 +471,11 @@ static int __sensor_init(struct v4l2_sub
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
- return 0;
|
||
|
+ irs1125->mod_pll_init = true;
|
||
|
+ v4l2_ctrl_handler_setup(&irs1125->ctrl_handler);
|
||
|
+ irs1125->mod_pll_init = false;
|
||
|
+
|
||
|
+ return irs1125_write(sd, 0xA87C, 0x0001);
|
||
|
}
|
||
|
|
||
|
static int irs1125_sensor_power(struct v4l2_subdev *sd, int on)
|
||
|
@@ -607,8 +611,6 @@ static int irs1125_s_ctrl(struct v4l2_ct
|
||
|
struct irs1125 *dev = container_of(ctrl->handler,
|
||
|
struct irs1125, ctrl_handler);
|
||
|
struct i2c_client *client = v4l2_get_subdevdata(&dev->sd);
|
||
|
- struct irs1125_mod_pll *mod_cur, *mod_new;
|
||
|
- u16 addr, val;
|
||
|
int err = 0, i;
|
||
|
|
||
|
switch (ctrl->id) {
|
||
|
@@ -660,68 +662,61 @@ static int irs1125_s_ctrl(struct v4l2_ct
|
||
|
ctrl->val);
|
||
|
break;
|
||
|
}
|
||
|
- case IRS1125_CID_MOD_PLL:
|
||
|
+ case IRS1125_CID_MOD_PLL: {
|
||
|
+ struct irs1125_mod_pll *mod_new;
|
||
|
+
|
||
|
+ if (dev->mod_pll_init)
|
||
|
+ break;
|
||
|
+
|
||
|
mod_new = (struct irs1125_mod_pll *)ctrl->p_new.p;
|
||
|
- mod_cur = (struct irs1125_mod_pll *)ctrl->p_cur.p;
|
||
|
for (i = 0; i < IRS1125_NUM_MOD_PLLS; i++) {
|
||
|
- if (mod_cur[i].pllcfg1 != mod_new[i].pllcfg1) {
|
||
|
- addr = 0xC3A0 + i * 3;
|
||
|
- val = mod_new[i].pllcfg1;
|
||
|
- err = irs1125_write(&dev->sd, addr, val);
|
||
|
- if (err < 0)
|
||
|
- break;
|
||
|
- }
|
||
|
- if (mod_cur[i].pllcfg2 != mod_new[i].pllcfg2) {
|
||
|
- addr = 0xC3A1 + i * 3;
|
||
|
- val = mod_new[i].pllcfg2;
|
||
|
- err = irs1125_write(&dev->sd, addr, val);
|
||
|
- if (err < 0)
|
||
|
- break;
|
||
|
- }
|
||
|
- if (mod_cur[i].pllcfg3 != mod_new[i].pllcfg3) {
|
||
|
- addr = 0xC3A2 + i * 3;
|
||
|
- val = mod_new[i].pllcfg3;
|
||
|
- err = irs1125_write(&dev->sd, addr, val);
|
||
|
- if (err < 0)
|
||
|
- break;
|
||
|
- }
|
||
|
- if (mod_cur[i].pllcfg4 != mod_new[i].pllcfg4) {
|
||
|
- addr = 0xC24C + i * 5;
|
||
|
- val = mod_new[i].pllcfg4;
|
||
|
- err = irs1125_write(&dev->sd, addr, val);
|
||
|
- if (err < 0)
|
||
|
- break;
|
||
|
- }
|
||
|
- if (mod_cur[i].pllcfg5 != mod_new[i].pllcfg5) {
|
||
|
- addr = 0xC24D + i * 5;
|
||
|
- val = mod_new[i].pllcfg5;
|
||
|
- err = irs1125_write(&dev->sd, addr, val);
|
||
|
- if (err < 0)
|
||
|
- break;
|
||
|
- }
|
||
|
- if (mod_cur[i].pllcfg6 != mod_new[i].pllcfg6) {
|
||
|
- addr = 0xC24E + i * 5;
|
||
|
- val = mod_new[i].pllcfg6;
|
||
|
- err = irs1125_write(&dev->sd, addr, val);
|
||
|
- if (err < 0)
|
||
|
- break;
|
||
|
- }
|
||
|
- if (mod_cur[i].pllcfg7 != mod_new[i].pllcfg7) {
|
||
|
- addr = 0xC24F + i * 5;
|
||
|
- val = mod_new[i].pllcfg7;
|
||
|
- err = irs1125_write(&dev->sd, addr, val);
|
||
|
- if (err < 0)
|
||
|
- break;
|
||
|
- }
|
||
|
- if (mod_cur[i].pllcfg8 != mod_new[i].pllcfg8) {
|
||
|
- addr = 0xC250 + i * 5;
|
||
|
- val = mod_new[i].pllcfg8;
|
||
|
- err = irs1125_write(&dev->sd, addr, val);
|
||
|
- if (err < 0)
|
||
|
- break;
|
||
|
- }
|
||
|
+ unsigned int pll_offset, ssc_offset;
|
||
|
+
|
||
|
+ pll_offset = i * 3;
|
||
|
+ ssc_offset = i * 5;
|
||
|
+
|
||
|
+ err = irs1125_write(&dev->sd, 0xC3A0 + pll_offset,
|
||
|
+ mod_new[i].pllcfg1);
|
||
|
+ if (err < 0)
|
||
|
+ break;
|
||
|
+
|
||
|
+ err = irs1125_write(&dev->sd, 0xC3A1 + pll_offset,
|
||
|
+ mod_new[i].pllcfg2);
|
||
|
+ if (err < 0)
|
||
|
+ break;
|
||
|
+
|
||
|
+ err = irs1125_write(&dev->sd, 0xC3A2 + pll_offset,
|
||
|
+ mod_new[i].pllcfg3);
|
||
|
+ if (err < 0)
|
||
|
+ break;
|
||
|
+
|
||
|
+ err = irs1125_write(&dev->sd, 0xC24C + ssc_offset,
|
||
|
+ mod_new[i].pllcfg4);
|
||
|
+ if (err < 0)
|
||
|
+ break;
|
||
|
+
|
||
|
+ err = irs1125_write(&dev->sd, 0xC24D + ssc_offset,
|
||
|
+ mod_new[i].pllcfg5);
|
||
|
+ if (err < 0)
|
||
|
+ break;
|
||
|
+
|
||
|
+ err = irs1125_write(&dev->sd, 0xC24E + ssc_offset,
|
||
|
+ mod_new[i].pllcfg6);
|
||
|
+ if (err < 0)
|
||
|
+ break;
|
||
|
+
|
||
|
+ err = irs1125_write(&dev->sd, 0xC24F + ssc_offset,
|
||
|
+ mod_new[i].pllcfg7);
|
||
|
+ if (err < 0)
|
||
|
+ break;
|
||
|
+
|
||
|
+ err = irs1125_write(&dev->sd, 0xC250 + ssc_offset,
|
||
|
+ mod_new[i].pllcfg8);
|
||
|
+ if (err < 0)
|
||
|
+ break;
|
||
|
}
|
||
|
break;
|
||
|
+ }
|
||
|
case IRS1125_CID_SEQ_CONFIG: {
|
||
|
struct irs1125_seq_cfg *cfg_new;
|
||
|
|