aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSakari Ailus <sakari.ailus@linux.intel.com>2014-04-01 07:37:38 -0400
committerMauro Carvalho Chehab <m.chehab@samsung.com>2014-04-23 10:31:33 -0400
commit6f7481b6685daf693e995e8653f6c8d27cfe5bfc (patch)
treebde1311964fbd774ec748e70282a238c58f7cc3d
parent03efb2a067beaea0496bd6e411452ca90dab9d01 (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.h13
-rw-r--r--drivers/media/i2c/smiapp/smiapp-regs.c48
-rw-r--r--drivers/media/i2c/smiapp/smiapp-regs.h2
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 */
39struct smiapp_quirk { 50struct 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
188int smiapp_read(struct smiapp_sensor *sensor, u32 reg, u32 *val) 188int 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
196int 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, &reg, 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
196int smiapp_read_8only(struct smiapp_sensor *sensor, u32 reg, u32 *val) 210int 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, &reg, 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/* 224int 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 */
205int 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 */
294int smiapp_write(struct smiapp_sensor *sensor, u32 reg, u32 val)
295{
296 int rval;
297
298 rval = smiapp_call_quirk(sensor, reg_access, true, &reg, &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
38struct smiapp_sensor; 38struct smiapp_sensor;
39 39
40int smiapp_read_no_quirk(struct smiapp_sensor *sensor, u32 reg, u32 *val);
40int smiapp_read(struct smiapp_sensor *sensor, u32 reg, u32 *val); 41int smiapp_read(struct smiapp_sensor *sensor, u32 reg, u32 *val);
41int smiapp_read_8only(struct smiapp_sensor *sensor, u32 reg, u32 *val); 42int smiapp_read_8only(struct smiapp_sensor *sensor, u32 reg, u32 *val);
43int smiapp_write_no_quirk(struct smiapp_sensor *sensor, u32 reg, u32 val);
42int smiapp_write(struct smiapp_sensor *sensor, u32 reg, u32 val); 44int smiapp_write(struct smiapp_sensor *sensor, u32 reg, u32 val);
43 45
44#endif 46#endif