* @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);
        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;
 };
 
 
        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,
                                   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, ®, 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, ®, 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;
 
        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, ®, &val);
+       if (rval == -ENOIOCTLCMD)
+               return 0;
+       if (rval < 0)
+               return rval;
+
+       return smiapp_write_no_quirk(sensor, reg, val);
+}
 
 
 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