[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>
This commit is contained in:
parent
03efb2a067
commit
6f7481b668
3 changed files with 57 additions and 6 deletions
|
@ -35,6 +35,17 @@ struct smiapp_sensor;
|
||||||
* @post_poweron: Called always after the sensor has been fully powered on.
|
* @post_poweron: Called always after the sensor has been fully powered on.
|
||||||
* @pre_streamon: Called just before streaming is enabled.
|
* @pre_streamon: Called just before streaming is enabled.
|
||||||
* @post_streamon: Called right after stopping streaming.
|
* @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 {
|
struct smiapp_quirk {
|
||||||
int (*limits)(struct smiapp_sensor *sensor);
|
int (*limits)(struct smiapp_sensor *sensor);
|
||||||
|
@ -42,6 +53,8 @@ struct smiapp_quirk {
|
||||||
int (*pre_streamon)(struct smiapp_sensor *sensor);
|
int (*pre_streamon)(struct smiapp_sensor *sensor);
|
||||||
int (*post_streamoff)(struct smiapp_sensor *sensor);
|
int (*post_streamoff)(struct smiapp_sensor *sensor);
|
||||||
unsigned long (*pll_flags)(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;
|
unsigned long flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -185,7 +185,7 @@ static int __smiapp_read(struct smiapp_sensor *sensor, u32 reg, u32 *val,
|
||||||
return 0;
|
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(
|
return __smiapp_read(
|
||||||
sensor, reg, val,
|
sensor, reg, val,
|
||||||
|
@ -193,16 +193,35 @@ int smiapp_read(struct smiapp_sensor *sensor, u32 reg, u32 *val)
|
||||||
SMIAPP_QUIRK_FLAG_8BIT_READ_ONLY));
|
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 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);
|
return __smiapp_read(sensor, reg, val, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
int smiapp_write_no_quirk(struct smiapp_sensor *sensor, u32 reg, u32 val)
|
||||||
* 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)
|
|
||||||
{
|
{
|
||||||
struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
|
struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
|
||||||
struct i2c_msg msg;
|
struct i2c_msg msg;
|
||||||
|
@ -267,3 +286,20 @@ int smiapp_write(struct smiapp_sensor *sensor, u32 reg, u32 val)
|
||||||
|
|
||||||
return r;
|
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);
|
||||||
|
}
|
||||||
|
|
|
@ -37,8 +37,10 @@
|
||||||
|
|
||||||
struct smiapp_sensor;
|
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(struct smiapp_sensor *sensor, u32 reg, u32 *val);
|
||||||
int smiapp_read_8only(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);
|
int smiapp_write(struct smiapp_sensor *sensor, u32 reg, u32 val);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Reference in a new issue