diff options
author | Sakari Ailus <sakari.ailus@linux.intel.com> | 2014-04-01 07:37:38 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <m.chehab@samsung.com> | 2014-04-23 10:31:33 -0400 |
commit | 6f7481b6685daf693e995e8653f6c8d27cfe5bfc (patch) | |
tree | bde1311964fbd774ec748e70282a238c58f7cc3d | |
parent | 03efb2a067beaea0496bd6e411452ca90dab9d01 (diff) |
[media] smiapp: Add register diversion quirk
Add a quirk for diverting registers for on some sensors, even the standard
registers are not where they can be expected to be found. Add a quirk to
to help using such sensors.
smiapp_write_no_quirk() and smiapp_read_no_quirk() functions are provided
for the use of quirk implementations.
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
-rw-r--r-- | drivers/media/i2c/smiapp/smiapp-quirk.h | 13 | ||||
-rw-r--r-- | drivers/media/i2c/smiapp/smiapp-regs.c | 48 | ||||
-rw-r--r-- | drivers/media/i2c/smiapp/smiapp-regs.h | 2 |
3 files changed, 57 insertions, 6 deletions
diff --git a/drivers/media/i2c/smiapp/smiapp-quirk.h b/drivers/media/i2c/smiapp/smiapp-quirk.h index dddb62beeb29..46e9ea8bfa08 100644 --- a/drivers/media/i2c/smiapp/smiapp-quirk.h +++ b/drivers/media/i2c/smiapp/smiapp-quirk.h | |||
@@ -35,6 +35,17 @@ struct smiapp_sensor; | |||
35 | * @post_poweron: Called always after the sensor has been fully powered on. | 35 | * @post_poweron: Called always after the sensor has been fully powered on. |
36 | * @pre_streamon: Called just before streaming is enabled. | 36 | * @pre_streamon: Called just before streaming is enabled. |
37 | * @post_streamon: Called right after stopping streaming. | 37 | * @post_streamon: Called right after stopping streaming. |
38 | * @reg_access: Register access quirk. The quirk may divert the access | ||
39 | * to another register, or no register at all. | ||
40 | * | ||
41 | * @write: Is this read (false) or write (true) access? | ||
42 | * @reg: Pointer to the register to access | ||
43 | * @value: Register value, set by the caller on write, or | ||
44 | * by the quirk on read | ||
45 | * | ||
46 | * @return: 0 on success, -ENOIOCTLCMD if no register | ||
47 | * access may be done by the caller (default read | ||
48 | * value is zero), else negative error code on error | ||
38 | */ | 49 | */ |
39 | struct smiapp_quirk { | 50 | struct smiapp_quirk { |
40 | int (*limits)(struct smiapp_sensor *sensor); | 51 | int (*limits)(struct smiapp_sensor *sensor); |
@@ -42,6 +53,8 @@ struct smiapp_quirk { | |||
42 | int (*pre_streamon)(struct smiapp_sensor *sensor); | 53 | int (*pre_streamon)(struct smiapp_sensor *sensor); |
43 | int (*post_streamoff)(struct smiapp_sensor *sensor); | 54 | int (*post_streamoff)(struct smiapp_sensor *sensor); |
44 | unsigned long (*pll_flags)(struct smiapp_sensor *sensor); | 55 | unsigned long (*pll_flags)(struct smiapp_sensor *sensor); |
56 | int (*reg_access)(struct smiapp_sensor *sensor, bool write, u32 *reg, | ||
57 | u32 *val); | ||
45 | unsigned long flags; | 58 | unsigned long flags; |
46 | }; | 59 | }; |
47 | 60 | ||
diff --git a/drivers/media/i2c/smiapp/smiapp-regs.c b/drivers/media/i2c/smiapp/smiapp-regs.c index c2db20538ebb..eb5146af9c30 100644 --- a/drivers/media/i2c/smiapp/smiapp-regs.c +++ b/drivers/media/i2c/smiapp/smiapp-regs.c | |||
@@ -185,7 +185,7 @@ static int __smiapp_read(struct smiapp_sensor *sensor, u32 reg, u32 *val, | |||
185 | return 0; | 185 | return 0; |
186 | } | 186 | } |
187 | 187 | ||
188 | int smiapp_read(struct smiapp_sensor *sensor, u32 reg, u32 *val) | 188 | int smiapp_read_no_quirk(struct smiapp_sensor *sensor, u32 reg, u32 *val) |
189 | { | 189 | { |
190 | return __smiapp_read( | 190 | return __smiapp_read( |
191 | sensor, reg, val, | 191 | sensor, reg, val, |
@@ -193,16 +193,35 @@ int smiapp_read(struct smiapp_sensor *sensor, u32 reg, u32 *val) | |||
193 | SMIAPP_QUIRK_FLAG_8BIT_READ_ONLY)); | 193 | SMIAPP_QUIRK_FLAG_8BIT_READ_ONLY)); |
194 | } | 194 | } |
195 | 195 | ||
196 | int smiapp_read(struct smiapp_sensor *sensor, u32 reg, u32 *val) | ||
197 | { | ||
198 | int rval; | ||
199 | |||
200 | *val = 0; | ||
201 | rval = smiapp_call_quirk(sensor, reg_access, false, ®, val); | ||
202 | if (rval == -ENOIOCTLCMD) | ||
203 | return 0; | ||
204 | if (rval < 0) | ||
205 | return rval; | ||
206 | |||
207 | return smiapp_read_no_quirk(sensor, reg, val); | ||
208 | } | ||
209 | |||
196 | int smiapp_read_8only(struct smiapp_sensor *sensor, u32 reg, u32 *val) | 210 | int smiapp_read_8only(struct smiapp_sensor *sensor, u32 reg, u32 *val) |
197 | { | 211 | { |
212 | int rval; | ||
213 | |||
214 | *val = 0; | ||
215 | rval = smiapp_call_quirk(sensor, reg_access, false, ®, val); | ||
216 | if (rval == -ENOIOCTLCMD) | ||
217 | return 0; | ||
218 | if (rval < 0) | ||
219 | return rval; | ||
220 | |||
198 | return __smiapp_read(sensor, reg, val, true); | 221 | return __smiapp_read(sensor, reg, val, true); |
199 | } | 222 | } |
200 | 223 | ||
201 | /* | 224 | int smiapp_write_no_quirk(struct smiapp_sensor *sensor, u32 reg, u32 val) |
202 | * Write to a 8/16-bit register. | ||
203 | * Returns zero if successful, or non-zero otherwise. | ||
204 | */ | ||
205 | int smiapp_write(struct smiapp_sensor *sensor, u32 reg, u32 val) | ||
206 | { | 225 | { |
207 | struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd); | 226 | struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd); |
208 | struct i2c_msg msg; | 227 | struct i2c_msg msg; |
@@ -267,3 +286,20 @@ int smiapp_write(struct smiapp_sensor *sensor, u32 reg, u32 val) | |||
267 | 286 | ||
268 | return r; | 287 | return r; |
269 | } | 288 | } |
289 | |||
290 | /* | ||
291 | * Write to a 8/16-bit register. | ||
292 | * Returns zero if successful, or non-zero otherwise. | ||
293 | */ | ||
294 | int smiapp_write(struct smiapp_sensor *sensor, u32 reg, u32 val) | ||
295 | { | ||
296 | int rval; | ||
297 | |||
298 | rval = smiapp_call_quirk(sensor, reg_access, true, ®, &val); | ||
299 | if (rval == -ENOIOCTLCMD) | ||
300 | return 0; | ||
301 | if (rval < 0) | ||
302 | return rval; | ||
303 | |||
304 | return smiapp_write_no_quirk(sensor, reg, val); | ||
305 | } | ||
diff --git a/drivers/media/i2c/smiapp/smiapp-regs.h b/drivers/media/i2c/smiapp/smiapp-regs.h index 934130bc4cc1..81957cbf6a13 100644 --- a/drivers/media/i2c/smiapp/smiapp-regs.h +++ b/drivers/media/i2c/smiapp/smiapp-regs.h | |||
@@ -37,8 +37,10 @@ | |||
37 | 37 | ||
38 | struct smiapp_sensor; | 38 | struct smiapp_sensor; |
39 | 39 | ||
40 | int smiapp_read_no_quirk(struct smiapp_sensor *sensor, u32 reg, u32 *val); | ||
40 | int smiapp_read(struct smiapp_sensor *sensor, u32 reg, u32 *val); | 41 | int smiapp_read(struct smiapp_sensor *sensor, u32 reg, u32 *val); |
41 | int smiapp_read_8only(struct smiapp_sensor *sensor, u32 reg, u32 *val); | 42 | int smiapp_read_8only(struct smiapp_sensor *sensor, u32 reg, u32 *val); |
43 | int smiapp_write_no_quirk(struct smiapp_sensor *sensor, u32 reg, u32 val); | ||
42 | int smiapp_write(struct smiapp_sensor *sensor, u32 reg, u32 val); | 44 | int smiapp_write(struct smiapp_sensor *sensor, u32 reg, u32 val); |
43 | 45 | ||
44 | #endif | 46 | #endif |