[PATCH v4 01/20] media: i2c: imx219: Convert to CCI register access helpers

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Use the new common CCI register access helpers to replace the private
register access helpers in the imx219 driver. This simplifies the driver
by reducing the amount of code.

Signed-off-by: Laurent Pinchart <laurent.pinchart@xxxxxxxxxxxxxxxx>
Reviewed-by: Dave Stevenson <dave.stevenson@xxxxxxxxxxxxxxx>
---
 drivers/media/i2c/Kconfig  |   1 +
 drivers/media/i2c/imx219.c | 515 ++++++++++++++++---------------------
 2 files changed, 221 insertions(+), 295 deletions(-)

diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
index 74ff833ff48c..53b443be5a59 100644
--- a/drivers/media/i2c/Kconfig
+++ b/drivers/media/i2c/Kconfig
@@ -99,6 +99,7 @@ config VIDEO_IMX214
 
 config VIDEO_IMX219
 	tristate "Sony IMX219 sensor support"
+	select V4L2_CCI_I2C
 	help
 	  This is a Video4Linux2 sensor driver for the Sony
 	  IMX219 camera.
diff --git a/drivers/media/i2c/imx219.c b/drivers/media/i2c/imx219.c
index af29398c657d..9d84f09bcced 100644
--- a/drivers/media/i2c/imx219.c
+++ b/drivers/media/i2c/imx219.c
@@ -21,40 +21,49 @@
 #include <linux/module.h>
 #include <linux/pm_runtime.h>
 #include <linux/regulator/consumer.h>
+
+#include <media/v4l2-cci.h>
 #include <media/v4l2-ctrls.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-event.h>
 #include <media/v4l2-fwnode.h>
 #include <media/v4l2-mediabus.h>
-#include <asm/unaligned.h>
 
-#define IMX219_REG_VALUE_08BIT		1
-#define IMX219_REG_VALUE_16BIT		2
+/* Chip ID */
+#define IMX219_REG_CHIP_ID		CCI_REG16(0x0000)
+#define IMX219_CHIP_ID			0x0219
 
-#define IMX219_REG_MODE_SELECT		0x0100
+#define IMX219_REG_MODE_SELECT		CCI_REG8(0x0100)
 #define IMX219_MODE_STANDBY		0x00
 #define IMX219_MODE_STREAMING		0x01
 
-/* Chip ID */
-#define IMX219_REG_CHIP_ID		0x0000
-#define IMX219_CHIP_ID			0x0219
-
-/* External clock frequency is 24.0M */
-#define IMX219_XCLK_FREQ		24000000
-
-/* Pixel rate is fixed for all the modes */
-#define IMX219_PIXEL_RATE		182400000
-#define IMX219_PIXEL_RATE_4LANE		280800000
-
-#define IMX219_DEFAULT_LINK_FREQ	456000000
-#define IMX219_DEFAULT_LINK_FREQ_4LANE	363000000
-
-#define IMX219_REG_CSI_LANE_MODE	0x0114
+#define IMX219_REG_CSI_LANE_MODE	CCI_REG8(0x0114)
 #define IMX219_CSI_2_LANE_MODE		0x01
 #define IMX219_CSI_4_LANE_MODE		0x03
 
+/* Analog gain control */
+#define IMX219_REG_ANALOG_GAIN		CCI_REG8(0x0157)
+#define IMX219_ANA_GAIN_MIN		0
+#define IMX219_ANA_GAIN_MAX		232
+#define IMX219_ANA_GAIN_STEP		1
+#define IMX219_ANA_GAIN_DEFAULT		0x0
+
+/* Digital gain control */
+#define IMX219_REG_DIGITAL_GAIN		CCI_REG16(0x0158)
+#define IMX219_DGTL_GAIN_MIN		0x0100
+#define IMX219_DGTL_GAIN_MAX		0x0fff
+#define IMX219_DGTL_GAIN_DEFAULT	0x0100
+#define IMX219_DGTL_GAIN_STEP		1
+
+/* Exposure control */
+#define IMX219_REG_EXPOSURE		CCI_REG16(0x015a)
+#define IMX219_EXPOSURE_MIN		4
+#define IMX219_EXPOSURE_STEP		1
+#define IMX219_EXPOSURE_DEFAULT		0x640
+#define IMX219_EXPOSURE_MAX		65535
+
 /* V_TIMING internal */
-#define IMX219_REG_VTS			0x0160
+#define IMX219_REG_VTS			CCI_REG16(0x0160)
 #define IMX219_VTS_15FPS		0x0dc6
 #define IMX219_VTS_30FPS_1080P		0x06e3
 #define IMX219_VTS_30FPS_BINNED		0x06e3
@@ -72,37 +81,16 @@
 /* HBLANK control - read only */
 #define IMX219_PPL_DEFAULT		3448
 
-/* Exposure control */
-#define IMX219_REG_EXPOSURE		0x015a
-#define IMX219_EXPOSURE_MIN		4
-#define IMX219_EXPOSURE_STEP		1
-#define IMX219_EXPOSURE_DEFAULT		0x640
-#define IMX219_EXPOSURE_MAX		65535
-
-/* Analog gain control */
-#define IMX219_REG_ANALOG_GAIN		0x0157
-#define IMX219_ANA_GAIN_MIN		0
-#define IMX219_ANA_GAIN_MAX		232
-#define IMX219_ANA_GAIN_STEP		1
-#define IMX219_ANA_GAIN_DEFAULT		0x0
-
-/* Digital gain control */
-#define IMX219_REG_DIGITAL_GAIN		0x0158
-#define IMX219_DGTL_GAIN_MIN		0x0100
-#define IMX219_DGTL_GAIN_MAX		0x0fff
-#define IMX219_DGTL_GAIN_DEFAULT	0x0100
-#define IMX219_DGTL_GAIN_STEP		1
-
-#define IMX219_REG_ORIENTATION		0x0172
+#define IMX219_REG_ORIENTATION		CCI_REG8(0x0172)
 
 /* Binning  Mode */
-#define IMX219_REG_BINNING_MODE		0x0174
+#define IMX219_REG_BINNING_MODE		CCI_REG16(0x0174)
 #define IMX219_BINNING_NONE		0x0000
 #define IMX219_BINNING_2X2		0x0101
 #define IMX219_BINNING_2X2_ANALOG	0x0303
 
 /* Test Pattern Control */
-#define IMX219_REG_TEST_PATTERN		0x0600
+#define IMX219_REG_TEST_PATTERN		CCI_REG16(0x0600)
 #define IMX219_TEST_PATTERN_DISABLE	0
 #define IMX219_TEST_PATTERN_SOLID_COLOR	1
 #define IMX219_TEST_PATTERN_COLOR_BARS	2
@@ -110,10 +98,10 @@
 #define IMX219_TEST_PATTERN_PN9		4
 
 /* Test pattern colour components */
-#define IMX219_REG_TESTP_RED		0x0602
-#define IMX219_REG_TESTP_GREENR		0x0604
-#define IMX219_REG_TESTP_BLUE		0x0606
-#define IMX219_REG_TESTP_GREENB		0x0608
+#define IMX219_REG_TESTP_RED		CCI_REG16(0x0602)
+#define IMX219_REG_TESTP_GREENR		CCI_REG16(0x0604)
+#define IMX219_REG_TESTP_BLUE		CCI_REG16(0x0606)
+#define IMX219_REG_TESTP_GREENB		CCI_REG16(0x0608)
 #define IMX219_TESTP_COLOUR_MIN		0
 #define IMX219_TESTP_COLOUR_MAX		0x03ff
 #define IMX219_TESTP_COLOUR_STEP	1
@@ -122,6 +110,16 @@
 #define IMX219_TESTP_BLUE_DEFAULT	0
 #define IMX219_TESTP_GREENB_DEFAULT	0
 
+/* External clock frequency is 24.0M */
+#define IMX219_XCLK_FREQ		24000000
+
+/* Pixel rate is fixed for all the modes */
+#define IMX219_PIXEL_RATE		182400000
+#define IMX219_PIXEL_RATE_4LANE		280800000
+
+#define IMX219_DEFAULT_LINK_FREQ	456000000
+#define IMX219_DEFAULT_LINK_FREQ_4LANE	363000000
+
 /* IMX219 native and active pixel array size. */
 #define IMX219_NATIVE_WIDTH		3296U
 #define IMX219_NATIVE_HEIGHT		2480U
@@ -130,14 +128,9 @@
 #define IMX219_PIXEL_ARRAY_WIDTH	3280U
 #define IMX219_PIXEL_ARRAY_HEIGHT	2464U
 
-struct imx219_reg {
-	u16 address;
-	u8 val;
-};
-
 struct imx219_reg_list {
 	unsigned int num_of_regs;
-	const struct imx219_reg *regs;
+	const struct cci_reg_sequence *regs;
 };
 
 /* Mode : resolution and related config&values */
@@ -160,53 +153,53 @@ struct imx219_mode {
 	bool binning;
 };
 
-static const struct imx219_reg imx219_common_regs[] = {
-	{0x0100, 0x00},	/* Mode Select */
+static const struct cci_reg_sequence imx219_common_regs[] = {
+	{ CCI_REG8(0x0100), 0x00 },	/* Mode Select */
 
 	/* To Access Addresses 3000-5fff, send the following commands */
-	{0x30eb, 0x0c},
-	{0x30eb, 0x05},
-	{0x300a, 0xff},
-	{0x300b, 0xff},
-	{0x30eb, 0x05},
-	{0x30eb, 0x09},
+	{ CCI_REG8(0x30eb), 0x0c },
+	{ CCI_REG8(0x30eb), 0x05 },
+	{ CCI_REG8(0x300a), 0xff },
+	{ CCI_REG8(0x300b), 0xff },
+	{ CCI_REG8(0x30eb), 0x05 },
+	{ CCI_REG8(0x30eb), 0x09 },
 
 	/* PLL Clock Table */
-	{0x0301, 0x05},	/* VTPXCK_DIV */
-	{0x0303, 0x01},	/* VTSYSCK_DIV */
-	{0x0304, 0x03},	/* PREPLLCK_VT_DIV 0x03 = AUTO set */
-	{0x0305, 0x03}, /* PREPLLCK_OP_DIV 0x03 = AUTO set */
-	{0x0306, 0x00},	/* PLL_VT_MPY */
-	{0x0307, 0x39},
-	{0x030b, 0x01},	/* OP_SYS_CLK_DIV */
-	{0x030c, 0x00},	/* PLL_OP_MPY */
-	{0x030d, 0x72},
+	{ CCI_REG8(0x0301), 0x05 },	/* VTPXCK_DIV */
+	{ CCI_REG8(0x0303), 0x01 },	/* VTSYSCK_DIV */
+	{ CCI_REG8(0x0304), 0x03 },	/* PREPLLCK_VT_DIV 0x03 = AUTO set */
+	{ CCI_REG8(0x0305), 0x03 },	/* PREPLLCK_OP_DIV 0x03 = AUTO set */
+	{ CCI_REG8(0x0306), 0x00 },	/* PLL_VT_MPY */
+	{ CCI_REG8(0x0307), 0x39 },
+	{ CCI_REG8(0x030b), 0x01 },	/* OP_SYS_CLK_DIV */
+	{ CCI_REG8(0x030c), 0x00 },	/* PLL_OP_MPY */
+	{ CCI_REG8(0x030d), 0x72 },
 
 	/* Undocumented registers */
-	{0x455e, 0x00},
-	{0x471e, 0x4b},
-	{0x4767, 0x0f},
-	{0x4750, 0x14},
-	{0x4540, 0x00},
-	{0x47b4, 0x14},
-	{0x4713, 0x30},
-	{0x478b, 0x10},
-	{0x478f, 0x10},
-	{0x4793, 0x10},
-	{0x4797, 0x0e},
-	{0x479b, 0x0e},
+	{ CCI_REG8(0x455e), 0x00 },
+	{ CCI_REG8(0x471e), 0x4b },
+	{ CCI_REG8(0x4767), 0x0f },
+	{ CCI_REG8(0x4750), 0x14 },
+	{ CCI_REG8(0x4540), 0x00 },
+	{ CCI_REG8(0x47b4), 0x14 },
+	{ CCI_REG8(0x4713), 0x30 },
+	{ CCI_REG8(0x478b), 0x10 },
+	{ CCI_REG8(0x478f), 0x10 },
+	{ CCI_REG8(0x4793), 0x10 },
+	{ CCI_REG8(0x4797), 0x0e },
+	{ CCI_REG8(0x479b), 0x0e },
 
 	/* Frame Bank Register Group "A" */
-	{0x0162, 0x0d},	/* Line_Length_A */
-	{0x0163, 0x78},
-	{0x0170, 0x01}, /* X_ODD_INC_A */
-	{0x0171, 0x01}, /* Y_ODD_INC_A */
+	{ CCI_REG8(0x0162), 0x0d },	/* Line_Length_A */
+	{ CCI_REG8(0x0163), 0x78 },
+	{ CCI_REG8(0x0170), 0x01 },	/* X_ODD_INC_A */
+	{ CCI_REG8(0x0171), 0x01 },	/* Y_ODD_INC_A */
 
 	/* Output setup registers */
-	{0x0114, 0x01},	/* CSI 2-Lane Mode */
-	{0x0128, 0x00},	/* DPHY Auto Mode */
-	{0x012a, 0x18},	/* EXCK_Freq */
-	{0x012b, 0x00},
+	{ CCI_REG8(0x0114), 0x01 },	/* CSI 2-Lane Mode */
+	{ CCI_REG8(0x0128), 0x00 },	/* DPHY Auto Mode */
+	{ CCI_REG8(0x012a), 0x18 },	/* EXCK_Freq */
+	{ CCI_REG8(0x012b), 0x00 },
 };
 
 /*
@@ -214,92 +207,92 @@ static const struct imx219_reg imx219_common_regs[] = {
  * driver.
  * 3280x2464 = mode 2, 1920x1080 = mode 1, 1640x1232 = mode 4, 640x480 = mode 7.
  */
-static const struct imx219_reg mode_3280x2464_regs[] = {
-	{0x0164, 0x00},
-	{0x0165, 0x00},
-	{0x0166, 0x0c},
-	{0x0167, 0xcf},
-	{0x0168, 0x00},
-	{0x0169, 0x00},
-	{0x016a, 0x09},
-	{0x016b, 0x9f},
-	{0x016c, 0x0c},
-	{0x016d, 0xd0},
-	{0x016e, 0x09},
-	{0x016f, 0xa0},
-	{0x0624, 0x0c},
-	{0x0625, 0xd0},
-	{0x0626, 0x09},
-	{0x0627, 0xa0},
+static const struct cci_reg_sequence mode_3280x2464_regs[] = {
+	{ CCI_REG8(0x0164), 0x00 },
+	{ CCI_REG8(0x0165), 0x00 },
+	{ CCI_REG8(0x0166), 0x0c },
+	{ CCI_REG8(0x0167), 0xcf },
+	{ CCI_REG8(0x0168), 0x00 },
+	{ CCI_REG8(0x0169), 0x00 },
+	{ CCI_REG8(0x016a), 0x09 },
+	{ CCI_REG8(0x016b), 0x9f },
+	{ CCI_REG8(0x016c), 0x0c },
+	{ CCI_REG8(0x016d), 0xd0 },
+	{ CCI_REG8(0x016e), 0x09 },
+	{ CCI_REG8(0x016f), 0xa0 },
+	{ CCI_REG8(0x0624), 0x0c },
+	{ CCI_REG8(0x0625), 0xd0 },
+	{ CCI_REG8(0x0626), 0x09 },
+	{ CCI_REG8(0x0627), 0xa0 },
 };
 
-static const struct imx219_reg mode_1920_1080_regs[] = {
-	{0x0164, 0x02},
-	{0x0165, 0xa8},
-	{0x0166, 0x0a},
-	{0x0167, 0x27},
-	{0x0168, 0x02},
-	{0x0169, 0xb4},
-	{0x016a, 0x06},
-	{0x016b, 0xeb},
-	{0x016c, 0x07},
-	{0x016d, 0x80},
-	{0x016e, 0x04},
-	{0x016f, 0x38},
-	{0x0624, 0x07},
-	{0x0625, 0x80},
-	{0x0626, 0x04},
-	{0x0627, 0x38},
+static const struct cci_reg_sequence mode_1920_1080_regs[] = {
+	{ CCI_REG8(0x0164), 0x02 },
+	{ CCI_REG8(0x0165), 0xa8 },
+	{ CCI_REG8(0x0166), 0x0a },
+	{ CCI_REG8(0x0167), 0x27 },
+	{ CCI_REG8(0x0168), 0x02 },
+	{ CCI_REG8(0x0169), 0xb4 },
+	{ CCI_REG8(0x016a), 0x06 },
+	{ CCI_REG8(0x016b), 0xeb },
+	{ CCI_REG8(0x016c), 0x07 },
+	{ CCI_REG8(0x016d), 0x80 },
+	{ CCI_REG8(0x016e), 0x04 },
+	{ CCI_REG8(0x016f), 0x38 },
+	{ CCI_REG8(0x0624), 0x07 },
+	{ CCI_REG8(0x0625), 0x80 },
+	{ CCI_REG8(0x0626), 0x04 },
+	{ CCI_REG8(0x0627), 0x38 },
 };
 
-static const struct imx219_reg mode_1640_1232_regs[] = {
-	{0x0164, 0x00},
-	{0x0165, 0x00},
-	{0x0166, 0x0c},
-	{0x0167, 0xcf},
-	{0x0168, 0x00},
-	{0x0169, 0x00},
-	{0x016a, 0x09},
-	{0x016b, 0x9f},
-	{0x016c, 0x06},
-	{0x016d, 0x68},
-	{0x016e, 0x04},
-	{0x016f, 0xd0},
-	{0x0624, 0x06},
-	{0x0625, 0x68},
-	{0x0626, 0x04},
-	{0x0627, 0xd0},
+static const struct cci_reg_sequence mode_1640_1232_regs[] = {
+	{ CCI_REG8(0x0164), 0x00 },
+	{ CCI_REG8(0x0165), 0x00 },
+	{ CCI_REG8(0x0166), 0x0c },
+	{ CCI_REG8(0x0167), 0xcf },
+	{ CCI_REG8(0x0168), 0x00 },
+	{ CCI_REG8(0x0169), 0x00 },
+	{ CCI_REG8(0x016a), 0x09 },
+	{ CCI_REG8(0x016b), 0x9f },
+	{ CCI_REG8(0x016c), 0x06 },
+	{ CCI_REG8(0x016d), 0x68 },
+	{ CCI_REG8(0x016e), 0x04 },
+	{ CCI_REG8(0x016f), 0xd0 },
+	{ CCI_REG8(0x0624), 0x06 },
+	{ CCI_REG8(0x0625), 0x68 },
+	{ CCI_REG8(0x0626), 0x04 },
+	{ CCI_REG8(0x0627), 0xd0 },
 };
 
-static const struct imx219_reg mode_640_480_regs[] = {
-	{0x0164, 0x03},
-	{0x0165, 0xe8},
-	{0x0166, 0x08},
-	{0x0167, 0xe7},
-	{0x0168, 0x02},
-	{0x0169, 0xf0},
-	{0x016a, 0x06},
-	{0x016b, 0xaf},
-	{0x016c, 0x02},
-	{0x016d, 0x80},
-	{0x016e, 0x01},
-	{0x016f, 0xe0},
-	{0x0624, 0x06},
-	{0x0625, 0x68},
-	{0x0626, 0x04},
-	{0x0627, 0xd0},
+static const struct cci_reg_sequence mode_640_480_regs[] = {
+	{ CCI_REG8(0x0164), 0x03 },
+	{ CCI_REG8(0x0165), 0xe8 },
+	{ CCI_REG8(0x0166), 0x08 },
+	{ CCI_REG8(0x0167), 0xe7 },
+	{ CCI_REG8(0x0168), 0x02 },
+	{ CCI_REG8(0x0169), 0xf0 },
+	{ CCI_REG8(0x016a), 0x06 },
+	{ CCI_REG8(0x016b), 0xaf },
+	{ CCI_REG8(0x016c), 0x02 },
+	{ CCI_REG8(0x016d), 0x80 },
+	{ CCI_REG8(0x016e), 0x01 },
+	{ CCI_REG8(0x016f), 0xe0 },
+	{ CCI_REG8(0x0624), 0x06 },
+	{ CCI_REG8(0x0625), 0x68 },
+	{ CCI_REG8(0x0626), 0x04 },
+	{ CCI_REG8(0x0627), 0xd0 },
 };
 
-static const struct imx219_reg raw8_framefmt_regs[] = {
-	{0x018c, 0x08},
-	{0x018d, 0x08},
-	{0x0309, 0x08},
+static const struct cci_reg_sequence raw8_framefmt_regs[] = {
+	{ CCI_REG8(0x018c), 0x08 },
+	{ CCI_REG8(0x018d), 0x08 },
+	{ CCI_REG8(0x0309), 0x08 },
 };
 
-static const struct imx219_reg raw10_framefmt_regs[] = {
-	{0x018c, 0x0a},
-	{0x018d, 0x0a},
-	{0x0309, 0x0a},
+static const struct cci_reg_sequence raw10_framefmt_regs[] = {
+	{ CCI_REG8(0x018c), 0x0a },
+	{ CCI_REG8(0x018d), 0x0a },
+	{ CCI_REG8(0x0309), 0x0a },
 };
 
 static const s64 imx219_link_freq_menu[] = {
@@ -460,6 +453,7 @@ struct imx219 {
 	struct v4l2_subdev sd;
 	struct media_pad pad;
 
+	struct regmap *regmap;
 	struct clk *xclk; /* system clock to IMX219 */
 	u32 xclk_freq;
 
@@ -488,78 +482,6 @@ static inline struct imx219 *to_imx219(struct v4l2_subdev *_sd)
 	return container_of(_sd, struct imx219, sd);
 }
 
-/* Read registers up to 2 at a time */
-static int imx219_read_reg(struct imx219 *imx219, u16 reg, u32 len, u32 *val)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd);
-	struct i2c_msg msgs[2];
-	u8 addr_buf[2] = { reg >> 8, reg & 0xff };
-	u8 data_buf[4] = { 0, };
-	int ret;
-
-	if (len > 4)
-		return -EINVAL;
-
-	/* Write register address */
-	msgs[0].addr = client->addr;
-	msgs[0].flags = 0;
-	msgs[0].len = ARRAY_SIZE(addr_buf);
-	msgs[0].buf = addr_buf;
-
-	/* Read data from register */
-	msgs[1].addr = client->addr;
-	msgs[1].flags = I2C_M_RD;
-	msgs[1].len = len;
-	msgs[1].buf = &data_buf[4 - len];
-
-	ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
-	if (ret != ARRAY_SIZE(msgs))
-		return -EIO;
-
-	*val = get_unaligned_be32(data_buf);
-
-	return 0;
-}
-
-/* Write registers up to 2 at a time */
-static int imx219_write_reg(struct imx219 *imx219, u16 reg, u32 len, u32 val)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd);
-	u8 buf[6];
-
-	if (len > 4)
-		return -EINVAL;
-
-	put_unaligned_be16(reg, buf);
-	put_unaligned_be32(val << (8 * (4 - len)), buf + 2);
-	if (i2c_master_send(client, buf, len + 2) != len + 2)
-		return -EIO;
-
-	return 0;
-}
-
-/* Write a list of registers */
-static int imx219_write_regs(struct imx219 *imx219,
-			     const struct imx219_reg *regs, u32 len)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd);
-	unsigned int i;
-	int ret;
-
-	for (i = 0; i < len; i++) {
-		ret = imx219_write_reg(imx219, regs[i].address, 1, regs[i].val);
-		if (ret) {
-			dev_err_ratelimited(&client->dev,
-					    "Failed to write reg 0x%4.4x. error = %d\n",
-					    regs[i].address, ret);
-
-			return ret;
-		}
-	}
-
-	return 0;
-}
-
 /* Get bayer order based on flip setting. */
 static u32 imx219_get_format_code(struct imx219 *imx219, u32 code)
 {
@@ -583,7 +505,7 @@ static int imx219_set_ctrl(struct v4l2_ctrl *ctrl)
 	struct imx219 *imx219 =
 		container_of(ctrl->handler, struct imx219, ctrl_handler);
 	struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd);
-	int ret;
+	int ret = 0;
 
 	if (ctrl->id == V4L2_CID_VBLANK) {
 		int exposure_max, exposure_def;
@@ -607,48 +529,45 @@ static int imx219_set_ctrl(struct v4l2_ctrl *ctrl)
 
 	switch (ctrl->id) {
 	case V4L2_CID_ANALOGUE_GAIN:
-		ret = imx219_write_reg(imx219, IMX219_REG_ANALOG_GAIN,
-				       IMX219_REG_VALUE_08BIT, ctrl->val);
+		cci_write(imx219->regmap, IMX219_REG_ANALOG_GAIN,
+			  ctrl->val, &ret);
 		break;
 	case V4L2_CID_EXPOSURE:
-		ret = imx219_write_reg(imx219, IMX219_REG_EXPOSURE,
-				       IMX219_REG_VALUE_16BIT, ctrl->val);
+		cci_write(imx219->regmap, IMX219_REG_EXPOSURE,
+			  ctrl->val, &ret);
 		break;
 	case V4L2_CID_DIGITAL_GAIN:
-		ret = imx219_write_reg(imx219, IMX219_REG_DIGITAL_GAIN,
-				       IMX219_REG_VALUE_16BIT, ctrl->val);
+		cci_write(imx219->regmap, IMX219_REG_DIGITAL_GAIN,
+			  ctrl->val, &ret);
 		break;
 	case V4L2_CID_TEST_PATTERN:
-		ret = imx219_write_reg(imx219, IMX219_REG_TEST_PATTERN,
-				       IMX219_REG_VALUE_16BIT,
-				       imx219_test_pattern_val[ctrl->val]);
+		cci_write(imx219->regmap, IMX219_REG_TEST_PATTERN,
+			  imx219_test_pattern_val[ctrl->val], &ret);
 		break;
 	case V4L2_CID_HFLIP:
 	case V4L2_CID_VFLIP:
-		ret = imx219_write_reg(imx219, IMX219_REG_ORIENTATION, 1,
-				       imx219->hflip->val |
-				       imx219->vflip->val << 1);
+		cci_write(imx219->regmap, IMX219_REG_ORIENTATION,
+			  imx219->hflip->val | imx219->vflip->val << 1, &ret);
 		break;
 	case V4L2_CID_VBLANK:
-		ret = imx219_write_reg(imx219, IMX219_REG_VTS,
-				       IMX219_REG_VALUE_16BIT,
-				       imx219->mode->height + ctrl->val);
+		cci_write(imx219->regmap, IMX219_REG_VTS,
+			  imx219->mode->height + ctrl->val, &ret);
 		break;
 	case V4L2_CID_TEST_PATTERN_RED:
-		ret = imx219_write_reg(imx219, IMX219_REG_TESTP_RED,
-				       IMX219_REG_VALUE_16BIT, ctrl->val);
+		cci_write(imx219->regmap, IMX219_REG_TESTP_RED,
+			  ctrl->val, &ret);
 		break;
 	case V4L2_CID_TEST_PATTERN_GREENR:
-		ret = imx219_write_reg(imx219, IMX219_REG_TESTP_GREENR,
-				       IMX219_REG_VALUE_16BIT, ctrl->val);
+		cci_write(imx219->regmap, IMX219_REG_TESTP_GREENR,
+			  ctrl->val, &ret);
 		break;
 	case V4L2_CID_TEST_PATTERN_BLUE:
-		ret = imx219_write_reg(imx219, IMX219_REG_TESTP_BLUE,
-				       IMX219_REG_VALUE_16BIT, ctrl->val);
+		cci_write(imx219->regmap, IMX219_REG_TESTP_BLUE,
+			  ctrl->val, &ret);
 		break;
 	case V4L2_CID_TEST_PATTERN_GREENB:
-		ret = imx219_write_reg(imx219, IMX219_REG_TESTP_GREENB,
-				       IMX219_REG_VALUE_16BIT, ctrl->val);
+		cci_write(imx219->regmap, IMX219_REG_TESTP_GREENB,
+			  ctrl->val, &ret);
 		break;
 	default:
 		dev_info(&client->dev,
@@ -799,15 +718,15 @@ static int imx219_set_framefmt(struct imx219 *imx219,
 	case MEDIA_BUS_FMT_SGRBG8_1X8:
 	case MEDIA_BUS_FMT_SGBRG8_1X8:
 	case MEDIA_BUS_FMT_SBGGR8_1X8:
-		return imx219_write_regs(imx219, raw8_framefmt_regs,
-					ARRAY_SIZE(raw8_framefmt_regs));
+		return cci_multi_reg_write(imx219->regmap, raw8_framefmt_regs,
+					   ARRAY_SIZE(raw8_framefmt_regs), NULL);
 
 	case MEDIA_BUS_FMT_SRGGB10_1X10:
 	case MEDIA_BUS_FMT_SGRBG10_1X10:
 	case MEDIA_BUS_FMT_SGBRG10_1X10:
 	case MEDIA_BUS_FMT_SBGGR10_1X10:
-		return imx219_write_regs(imx219, raw10_framefmt_regs,
-					ARRAY_SIZE(raw10_framefmt_regs));
+		return cci_multi_reg_write(imx219->regmap, raw10_framefmt_regs,
+					   ARRAY_SIZE(raw10_framefmt_regs), NULL);
 	}
 
 	return -EINVAL;
@@ -816,28 +735,24 @@ static int imx219_set_framefmt(struct imx219 *imx219,
 static int imx219_set_binning(struct imx219 *imx219,
 			      const struct v4l2_mbus_framefmt *format)
 {
-	if (!imx219->mode->binning) {
-		return imx219_write_reg(imx219, IMX219_REG_BINNING_MODE,
-					IMX219_REG_VALUE_16BIT,
-					IMX219_BINNING_NONE);
-	}
+	if (!imx219->mode->binning)
+		return cci_write(imx219->regmap, IMX219_REG_BINNING_MODE,
+				 IMX219_BINNING_NONE, NULL);
 
 	switch (format->code) {
 	case MEDIA_BUS_FMT_SRGGB8_1X8:
 	case MEDIA_BUS_FMT_SGRBG8_1X8:
 	case MEDIA_BUS_FMT_SGBRG8_1X8:
 	case MEDIA_BUS_FMT_SBGGR8_1X8:
-		return imx219_write_reg(imx219, IMX219_REG_BINNING_MODE,
-					IMX219_REG_VALUE_16BIT,
-					IMX219_BINNING_2X2_ANALOG);
+		return cci_write(imx219->regmap, IMX219_REG_BINNING_MODE,
+				 IMX219_BINNING_2X2_ANALOG, NULL);
 
 	case MEDIA_BUS_FMT_SRGGB10_1X10:
 	case MEDIA_BUS_FMT_SGRBG10_1X10:
 	case MEDIA_BUS_FMT_SGBRG10_1X10:
 	case MEDIA_BUS_FMT_SBGGR10_1X10:
-		return imx219_write_reg(imx219, IMX219_REG_BINNING_MODE,
-					IMX219_REG_VALUE_16BIT,
-					IMX219_BINNING_2X2);
+		return cci_write(imx219->regmap, IMX219_REG_BINNING_MODE,
+				 IMX219_BINNING_2X2, NULL);
 	}
 
 	return -EINVAL;
@@ -876,9 +791,9 @@ static int imx219_get_selection(struct v4l2_subdev *sd,
 
 static int imx219_configure_lanes(struct imx219 *imx219)
 {
-	return imx219_write_reg(imx219, IMX219_REG_CSI_LANE_MODE,
-				IMX219_REG_VALUE_08BIT, (imx219->lanes == 2) ?
-				IMX219_CSI_2_LANE_MODE : IMX219_CSI_4_LANE_MODE);
+	return cci_write(imx219->regmap, IMX219_REG_CSI_LANE_MODE,
+			 imx219->lanes == 2 ? IMX219_CSI_2_LANE_MODE :
+			 IMX219_CSI_4_LANE_MODE, NULL);
 };
 
 static int imx219_start_streaming(struct imx219 *imx219,
@@ -894,7 +809,8 @@ static int imx219_start_streaming(struct imx219 *imx219,
 		return ret;
 
 	/* Send all registers that are common to all modes */
-	ret = imx219_write_regs(imx219, imx219_common_regs, ARRAY_SIZE(imx219_common_regs));
+	ret = cci_multi_reg_write(imx219->regmap, imx219_common_regs,
+				  ARRAY_SIZE(imx219_common_regs), NULL);
 	if (ret) {
 		dev_err(&client->dev, "%s failed to send mfg header\n", __func__);
 		goto err_rpm_put;
@@ -909,7 +825,8 @@ static int imx219_start_streaming(struct imx219 *imx219,
 
 	/* Apply default values of current mode */
 	reg_list = &imx219->mode->reg_list;
-	ret = imx219_write_regs(imx219, reg_list->regs, reg_list->num_of_regs);
+	ret = cci_multi_reg_write(imx219->regmap, reg_list->regs,
+				  reg_list->num_of_regs, NULL);
 	if (ret) {
 		dev_err(&client->dev, "%s failed to set mode\n", __func__);
 		goto err_rpm_put;
@@ -936,8 +853,8 @@ static int imx219_start_streaming(struct imx219 *imx219,
 		goto err_rpm_put;
 
 	/* set stream on register */
-	ret = imx219_write_reg(imx219, IMX219_REG_MODE_SELECT,
-			       IMX219_REG_VALUE_08BIT, IMX219_MODE_STREAMING);
+	ret = cci_write(imx219->regmap, IMX219_REG_MODE_SELECT,
+			IMX219_MODE_STREAMING, NULL);
 	if (ret)
 		goto err_rpm_put;
 
@@ -958,8 +875,8 @@ static void imx219_stop_streaming(struct imx219 *imx219)
 	int ret;
 
 	/* set stream off register */
-	ret = imx219_write_reg(imx219, IMX219_REG_MODE_SELECT,
-			       IMX219_REG_VALUE_08BIT, IMX219_MODE_STANDBY);
+	ret = cci_write(imx219->regmap, IMX219_REG_MODE_SELECT,
+			IMX219_MODE_STANDBY, NULL);
 	if (ret)
 		dev_err(&client->dev, "%s failed to set stream\n", __func__);
 
@@ -1058,10 +975,9 @@ static int imx219_identify_module(struct imx219 *imx219)
 {
 	struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd);
 	int ret;
-	u32 val;
+	u64 val;
 
-	ret = imx219_read_reg(imx219, IMX219_REG_CHIP_ID,
-			      IMX219_REG_VALUE_16BIT, &val);
+	ret = cci_read(imx219->regmap, IMX219_REG_CHIP_ID, &val, NULL);
 	if (ret) {
 		dev_err(&client->dev, "failed to read chip id %x\n",
 			IMX219_CHIP_ID);
@@ -1069,7 +985,7 @@ static int imx219_identify_module(struct imx219 *imx219)
 	}
 
 	if (val != IMX219_CHIP_ID) {
-		dev_err(&client->dev, "chip id mismatch: %x!=%x\n",
+		dev_err(&client->dev, "chip id mismatch: %x!=%llx\n",
 			IMX219_CHIP_ID, val);
 		return -EIO;
 	}
@@ -1293,6 +1209,13 @@ static int imx219_probe(struct i2c_client *client)
 	if (imx219_check_hwcfg(dev, imx219))
 		return -EINVAL;
 
+	imx219->regmap = devm_cci_regmap_init_i2c(client, 16);
+	if (IS_ERR(imx219->regmap)) {
+		ret = PTR_ERR(imx219->regmap);
+		dev_err(dev, "failed to initialize CCI: %d\n", ret);
+		return ret;
+	}
+
 	/* Get system clock (xclk) */
 	imx219->xclk = devm_clk_get(dev, NULL);
 	if (IS_ERR(imx219->xclk)) {
@@ -1336,17 +1259,19 @@ static int imx219_probe(struct i2c_client *client)
 	 * streaming is started, so upon power up switch the modes to:
 	 * streaming -> standby
 	 */
-	ret = imx219_write_reg(imx219, IMX219_REG_MODE_SELECT,
-			       IMX219_REG_VALUE_08BIT, IMX219_MODE_STREAMING);
+	ret = cci_write(imx219->regmap, IMX219_REG_MODE_SELECT,
+			IMX219_MODE_STREAMING, NULL);
 	if (ret < 0)
 		goto error_power_off;
+
 	usleep_range(100, 110);
 
 	/* put sensor back to standby mode */
-	ret = imx219_write_reg(imx219, IMX219_REG_MODE_SELECT,
-			       IMX219_REG_VALUE_08BIT, IMX219_MODE_STANDBY);
+	ret = cci_write(imx219->regmap, IMX219_REG_MODE_SELECT,
+			IMX219_MODE_STANDBY, NULL);
 	if (ret < 0)
 		goto error_power_off;
+
 	usleep_range(100, 110);
 
 	ret = imx219_init_controls(imx219);
-- 
Regards,

Laurent Pinchart




[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux