[media] smiapp: Add register diversion quirk
authorSakari Ailus <sakari.ailus@linux.intel.com>
Tue, 1 Apr 2014 11:37:38 +0000 (08:37 -0300)
committerMauro Carvalho Chehab <m.chehab@samsung.com>
Wed, 23 Apr 2014 14:31:33 +0000 (11:31 -0300)
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>
drivers/media/i2c/smiapp/smiapp-quirk.h
drivers/media/i2c/smiapp/smiapp-regs.c
drivers/media/i2c/smiapp/smiapp-regs.h

index dddb62b..46e9ea8 100644 (file)
@@ -35,6 +35,17 @@ struct smiapp_sensor;
  * @post_poweron: Called always after the sensor has been fully powered on.
  * @pre_streamon: Called just before streaming is enabled.
  * @post_streamon: Called right after stopping streaming.
+ * @reg_access: Register access quirk. The quirk may divert the access
+ *             to another register, or no register at all.
+ *
+ *             @write: Is this read (false) or write (true) access?
+ *             @reg: Pointer to the register to access
+ *             @value: Register value, set by the caller on write, or
+ *                     by the quirk on read
+ *
+ *             @return: 0 on success, -ENOIOCTLCMD if no register
+ *                      access may be done by the caller (default read
+ *                      value is zero), else negative error code on error
  */
 struct smiapp_quirk {
        int (*limits)(struct smiapp_sensor *sensor);
@@ -42,6 +53,8 @@ struct smiapp_quirk {
        int (*pre_streamon)(struct smiapp_sensor *sensor);
        int (*post_streamoff)(struct smiapp_sensor *sensor);
        unsigned long (*pll_flags)(struct smiapp_sensor *sensor);
+       int (*reg_access)(struct smiapp_sensor *sensor, bool write, u32 *reg,
+                         u32 *val);
        unsigned long flags;
 };
 
index c2db205..eb5146a 100644 (file)
@@ -185,7 +185,7 @@ static int __smiapp_read(struct smiapp_sensor *sensor, u32 reg, u32 *val,
        return 0;
 }
 
-int smiapp_read(struct smiapp_sensor *sensor, u32 reg, u32 *val)
+int smiapp_read_no_quirk(struct smiapp_sensor *sensor, u32 reg, u32 *val)
 {
        return __smiapp_read(
                sensor, reg, val,
@@ -193,16 +193,35 @@ int smiapp_read(struct smiapp_sensor *sensor, u32 reg, u32 *val)
                                   SMIAPP_QUIRK_FLAG_8BIT_READ_ONLY));
 }
 
+int smiapp_read(struct smiapp_sensor *sensor, u32 reg, u32 *val)
+{
+       int rval;
+
+       *val = 0;
+       rval = smiapp_call_quirk(sensor, reg_access, false, &reg, val);
+       if (rval == -ENOIOCTLCMD)
+               return 0;
+       if (rval < 0)
+               return rval;
+
+       return smiapp_read_no_quirk(sensor, reg, val);
+}
+
 int smiapp_read_8only(struct smiapp_sensor *sensor, u32 reg, u32 *val)
 {
+       int rval;
+
+       *val = 0;
+       rval = smiapp_call_quirk(sensor, reg_access, false, &reg, val);
+       if (rval == -ENOIOCTLCMD)
+               return 0;
+       if (rval < 0)
+               return rval;
+
        return __smiapp_read(sensor, reg, val, true);
 }
 
-/*
- * Write to a 8/16-bit register.
- * Returns zero if successful, or non-zero otherwise.
- */
-int smiapp_write(struct smiapp_sensor *sensor, u32 reg, u32 val)
+int smiapp_write_no_quirk(struct smiapp_sensor *sensor, u32 reg, u32 val)
 {
        struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
        struct i2c_msg msg;
@@ -267,3 +286,20 @@ int smiapp_write(struct smiapp_sensor *sensor, u32 reg, u32 val)
 
        return r;
 }
+
+/*
+ * Write to a 8/16-bit register.
+ * Returns zero if successful, or non-zero otherwise.
+ */
+int smiapp_write(struct smiapp_sensor *sensor, u32 reg, u32 val)
+{
+       int rval;
+
+       rval = smiapp_call_quirk(sensor, reg_access, true, &reg, &val);
+       if (rval == -ENOIOCTLCMD)
+               return 0;
+       if (rval < 0)
+               return rval;
+
+       return smiapp_write_no_quirk(sensor, reg, val);
+}
index 934130b..81957cb 100644 (file)
 
 struct smiapp_sensor;
 
+int smiapp_read_no_quirk(struct smiapp_sensor *sensor, u32 reg, u32 *val);
 int smiapp_read(struct smiapp_sensor *sensor, u32 reg, u32 *val);
 int smiapp_read_8only(struct smiapp_sensor *sensor, u32 reg, u32 *val);
+int smiapp_write_no_quirk(struct smiapp_sensor *sensor, u32 reg, u32 val);
 int smiapp_write(struct smiapp_sensor *sensor, u32 reg, u32 val);
 
 #endif