mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 12:28:41 +08:00
media: v4l2-cci: Add support for little-endian encoded registers
[ Upstream commitd92e7a013f
] Some sensors, e.g. Sony IMX290, are using little-endian registers. Add support for those by encoding the endianness into Bit 20 of the register address. Fixes:af73323b97
("media: imx290: Convert to new CCI register access helpers") Cc: stable@vger.kernel.org Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com> Reviewed-by: Hans de Goede <hdegoede@redhat.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> [Sakari Ailus: Fixed commit message.] Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
8d2cd1724e
commit
8798fdc284
@ -18,6 +18,7 @@
|
||||
|
||||
int cci_read(struct regmap *map, u32 reg, u64 *val, int *err)
|
||||
{
|
||||
bool little_endian;
|
||||
unsigned int len;
|
||||
u8 buf[8];
|
||||
int ret;
|
||||
@ -25,6 +26,7 @@ int cci_read(struct regmap *map, u32 reg, u64 *val, int *err)
|
||||
if (err && *err)
|
||||
return *err;
|
||||
|
||||
little_endian = reg & CCI_REG_LE;
|
||||
len = CCI_REG_WIDTH_BYTES(reg);
|
||||
reg = CCI_REG_ADDR(reg);
|
||||
|
||||
@ -40,16 +42,28 @@ int cci_read(struct regmap *map, u32 reg, u64 *val, int *err)
|
||||
*val = buf[0];
|
||||
break;
|
||||
case 2:
|
||||
*val = get_unaligned_be16(buf);
|
||||
if (little_endian)
|
||||
*val = get_unaligned_le16(buf);
|
||||
else
|
||||
*val = get_unaligned_be16(buf);
|
||||
break;
|
||||
case 3:
|
||||
*val = get_unaligned_be24(buf);
|
||||
if (little_endian)
|
||||
*val = get_unaligned_le24(buf);
|
||||
else
|
||||
*val = get_unaligned_be24(buf);
|
||||
break;
|
||||
case 4:
|
||||
*val = get_unaligned_be32(buf);
|
||||
if (little_endian)
|
||||
*val = get_unaligned_le32(buf);
|
||||
else
|
||||
*val = get_unaligned_be32(buf);
|
||||
break;
|
||||
case 8:
|
||||
*val = get_unaligned_be64(buf);
|
||||
if (little_endian)
|
||||
*val = get_unaligned_le64(buf);
|
||||
else
|
||||
*val = get_unaligned_be64(buf);
|
||||
break;
|
||||
default:
|
||||
dev_err(regmap_get_device(map), "Error invalid reg-width %u for reg 0x%04x\n",
|
||||
@ -68,6 +82,7 @@ EXPORT_SYMBOL_GPL(cci_read);
|
||||
|
||||
int cci_write(struct regmap *map, u32 reg, u64 val, int *err)
|
||||
{
|
||||
bool little_endian;
|
||||
unsigned int len;
|
||||
u8 buf[8];
|
||||
int ret;
|
||||
@ -75,6 +90,7 @@ int cci_write(struct regmap *map, u32 reg, u64 val, int *err)
|
||||
if (err && *err)
|
||||
return *err;
|
||||
|
||||
little_endian = reg & CCI_REG_LE;
|
||||
len = CCI_REG_WIDTH_BYTES(reg);
|
||||
reg = CCI_REG_ADDR(reg);
|
||||
|
||||
@ -83,16 +99,28 @@ int cci_write(struct regmap *map, u32 reg, u64 val, int *err)
|
||||
buf[0] = val;
|
||||
break;
|
||||
case 2:
|
||||
put_unaligned_be16(val, buf);
|
||||
if (little_endian)
|
||||
put_unaligned_le16(val, buf);
|
||||
else
|
||||
put_unaligned_be16(val, buf);
|
||||
break;
|
||||
case 3:
|
||||
put_unaligned_be24(val, buf);
|
||||
if (little_endian)
|
||||
put_unaligned_le24(val, buf);
|
||||
else
|
||||
put_unaligned_be24(val, buf);
|
||||
break;
|
||||
case 4:
|
||||
put_unaligned_be32(val, buf);
|
||||
if (little_endian)
|
||||
put_unaligned_le32(val, buf);
|
||||
else
|
||||
put_unaligned_be32(val, buf);
|
||||
break;
|
||||
case 8:
|
||||
put_unaligned_be64(val, buf);
|
||||
if (little_endian)
|
||||
put_unaligned_le64(val, buf);
|
||||
else
|
||||
put_unaligned_be64(val, buf);
|
||||
break;
|
||||
default:
|
||||
dev_err(regmap_get_device(map), "Error invalid reg-width %u for reg 0x%04x\n",
|
||||
|
@ -38,12 +38,17 @@ struct cci_reg_sequence {
|
||||
#define CCI_REG_WIDTH_BYTES(x) FIELD_GET(CCI_REG_WIDTH_MASK, x)
|
||||
#define CCI_REG_WIDTH(x) (CCI_REG_WIDTH_BYTES(x) << 3)
|
||||
#define CCI_REG_ADDR(x) FIELD_GET(CCI_REG_ADDR_MASK, x)
|
||||
#define CCI_REG_LE BIT(20)
|
||||
|
||||
#define CCI_REG8(x) ((1 << CCI_REG_WIDTH_SHIFT) | (x))
|
||||
#define CCI_REG16(x) ((2 << CCI_REG_WIDTH_SHIFT) | (x))
|
||||
#define CCI_REG24(x) ((3 << CCI_REG_WIDTH_SHIFT) | (x))
|
||||
#define CCI_REG32(x) ((4 << CCI_REG_WIDTH_SHIFT) | (x))
|
||||
#define CCI_REG64(x) ((8 << CCI_REG_WIDTH_SHIFT) | (x))
|
||||
#define CCI_REG16_LE(x) (CCI_REG_LE | (2U << CCI_REG_WIDTH_SHIFT) | (x))
|
||||
#define CCI_REG24_LE(x) (CCI_REG_LE | (3U << CCI_REG_WIDTH_SHIFT) | (x))
|
||||
#define CCI_REG32_LE(x) (CCI_REG_LE | (4U << CCI_REG_WIDTH_SHIFT) | (x))
|
||||
#define CCI_REG64_LE(x) (CCI_REG_LE | (8U << CCI_REG_WIDTH_SHIFT) | (x))
|
||||
|
||||
/**
|
||||
* cci_read() - Read a value from a single CCI register
|
||||
|
Loading…
Reference in New Issue
Block a user