Commit 6f7481b6 authored by Sakari Ailus's avatar Sakari Ailus Committed by Mauro Carvalho Chehab

[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: default avatarSakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: default avatarMauro Carvalho Chehab <m.chehab@samsung.com>
parent 03efb2a0
......@@ -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;
};
......
......@@ -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);
}
......@@ -37,8 +37,10 @@
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
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment