media: i2c: imx214: Convert to CCI register access helpers

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

Acked-by: Ricardo Ribalda <ribalda@chromium.org>
Signed-off-by: André Apitzsch <git@apitzsch.eu>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
This commit is contained in:
André Apitzsch 2024-12-20 14:26:02 +01:00 committed by Hans Verkuil
parent 5d6dc133e6
commit 4f0aeba4f1
2 changed files with 288 additions and 341 deletions

View file

@ -140,6 +140,7 @@ config VIDEO_IMX214
tristate "Sony IMX214 sensor support" tristate "Sony IMX214 sensor support"
depends on GPIOLIB depends on GPIOLIB
select REGMAP_I2C select REGMAP_I2C
select V4L2_CCI_I2C
help help
This is a Video4Linux2 sensor driver for the Sony This is a Video4Linux2 sensor driver for the Sony
IMX214 camera. IMX214 camera.

View file

@ -15,11 +15,12 @@
#include <linux/regmap.h> #include <linux/regmap.h>
#include <linux/regulator/consumer.h> #include <linux/regulator/consumer.h>
#include <media/media-entity.h> #include <media/media-entity.h>
#include <media/v4l2-cci.h>
#include <media/v4l2-ctrls.h> #include <media/v4l2-ctrls.h>
#include <media/v4l2-fwnode.h> #include <media/v4l2-fwnode.h>
#include <media/v4l2-subdev.h> #include <media/v4l2-subdev.h>
#define IMX214_REG_MODE_SELECT 0x0100 #define IMX214_REG_MODE_SELECT CCI_REG8(0x0100)
#define IMX214_MODE_STANDBY 0x00 #define IMX214_MODE_STANDBY 0x00
#define IMX214_MODE_STREAMING 0x01 #define IMX214_MODE_STREAMING 0x01
@ -30,7 +31,7 @@
#define IMX214_MBUS_CODE MEDIA_BUS_FMT_SRGGB10_1X10 #define IMX214_MBUS_CODE MEDIA_BUS_FMT_SRGGB10_1X10
/* Exposure control */ /* Exposure control */
#define IMX214_REG_EXPOSURE 0x0202 #define IMX214_REG_EXPOSURE CCI_REG16(0x0202)
#define IMX214_EXPOSURE_MIN 0 #define IMX214_EXPOSURE_MIN 0
#define IMX214_EXPOSURE_MAX 3184 #define IMX214_EXPOSURE_MAX 3184
#define IMX214_EXPOSURE_STEP 1 #define IMX214_EXPOSURE_STEP 1
@ -71,345 +72,324 @@ struct imx214 {
struct gpio_desc *enable_gpio; struct gpio_desc *enable_gpio;
}; };
struct reg_8 {
u16 addr;
u8 val;
};
enum {
IMX214_TABLE_WAIT_MS = 0,
IMX214_TABLE_END,
IMX214_MAX_RETRIES,
IMX214_WAIT_MS
};
/*From imx214_mode_tbls.h*/ /*From imx214_mode_tbls.h*/
static const struct reg_8 mode_4096x2304[] = { static const struct cci_reg_sequence mode_4096x2304[] = {
{0x0114, 0x03}, { CCI_REG8(0x0114), 0x03 },
{0x0220, 0x00}, { CCI_REG8(0x0220), 0x00 },
{0x0221, 0x11}, { CCI_REG8(0x0221), 0x11 },
{0x0222, 0x01}, { CCI_REG8(0x0222), 0x01 },
{0x0340, 0x0C}, { CCI_REG8(0x0340), 0x0C },
{0x0341, 0x7A}, { CCI_REG8(0x0341), 0x7A },
{0x0342, 0x13}, { CCI_REG8(0x0342), 0x13 },
{0x0343, 0x90}, { CCI_REG8(0x0343), 0x90 },
{0x0344, 0x00}, { CCI_REG8(0x0344), 0x00 },
{0x0345, 0x38}, { CCI_REG8(0x0345), 0x38 },
{0x0346, 0x01}, { CCI_REG8(0x0346), 0x01 },
{0x0347, 0x98}, { CCI_REG8(0x0347), 0x98 },
{0x0348, 0x10}, { CCI_REG8(0x0348), 0x10 },
{0x0349, 0x37}, { CCI_REG8(0x0349), 0x37 },
{0x034A, 0x0A}, { CCI_REG8(0x034A), 0x0A },
{0x034B, 0x97}, { CCI_REG8(0x034B), 0x97 },
{0x0381, 0x01}, { CCI_REG8(0x0381), 0x01 },
{0x0383, 0x01}, { CCI_REG8(0x0383), 0x01 },
{0x0385, 0x01}, { CCI_REG8(0x0385), 0x01 },
{0x0387, 0x01}, { CCI_REG8(0x0387), 0x01 },
{0x0900, 0x00}, { CCI_REG8(0x0900), 0x00 },
{0x0901, 0x00}, { CCI_REG8(0x0901), 0x00 },
{0x0902, 0x00}, { CCI_REG8(0x0902), 0x00 },
{0x3000, 0x35}, { CCI_REG8(0x3000), 0x35 },
{0x3054, 0x01}, { CCI_REG8(0x3054), 0x01 },
{0x305C, 0x11}, { CCI_REG8(0x305C), 0x11 },
{0x0112, 0x0A}, { CCI_REG8(0x0112), 0x0A },
{0x0113, 0x0A}, { CCI_REG8(0x0113), 0x0A },
{0x034C, 0x10}, { CCI_REG8(0x034C), 0x10 },
{0x034D, 0x00}, { CCI_REG8(0x034D), 0x00 },
{0x034E, 0x09}, { CCI_REG8(0x034E), 0x09 },
{0x034F, 0x00}, { CCI_REG8(0x034F), 0x00 },
{0x0401, 0x00}, { CCI_REG8(0x0401), 0x00 },
{0x0404, 0x00}, { CCI_REG8(0x0404), 0x00 },
{0x0405, 0x10}, { CCI_REG8(0x0405), 0x10 },
{0x0408, 0x00}, { CCI_REG8(0x0408), 0x00 },
{0x0409, 0x00}, { CCI_REG8(0x0409), 0x00 },
{0x040A, 0x00}, { CCI_REG8(0x040A), 0x00 },
{0x040B, 0x00}, { CCI_REG8(0x040B), 0x00 },
{0x040C, 0x10}, { CCI_REG8(0x040C), 0x10 },
{0x040D, 0x00}, { CCI_REG8(0x040D), 0x00 },
{0x040E, 0x09}, { CCI_REG8(0x040E), 0x09 },
{0x040F, 0x00}, { CCI_REG8(0x040F), 0x00 },
{0x0301, 0x05}, { CCI_REG8(0x0301), 0x05 },
{0x0303, 0x02}, { CCI_REG8(0x0303), 0x02 },
{0x0305, 0x03}, { CCI_REG8(0x0305), 0x03 },
{0x0306, 0x00}, { CCI_REG8(0x0306), 0x00 },
{0x0307, 0x96}, { CCI_REG8(0x0307), 0x96 },
{0x0309, 0x0A}, { CCI_REG8(0x0309), 0x0A },
{0x030B, 0x01}, { CCI_REG8(0x030B), 0x01 },
{0x0310, 0x00}, { CCI_REG8(0x0310), 0x00 },
{0x0820, 0x12}, { CCI_REG8(0x0820), 0x12 },
{0x0821, 0xC0}, { CCI_REG8(0x0821), 0xC0 },
{0x0822, 0x00}, { CCI_REG8(0x0822), 0x00 },
{0x0823, 0x00}, { CCI_REG8(0x0823), 0x00 },
{0x3A03, 0x09}, { CCI_REG8(0x3A03), 0x09 },
{0x3A04, 0x50}, { CCI_REG8(0x3A04), 0x50 },
{0x3A05, 0x01}, { CCI_REG8(0x3A05), 0x01 },
{0x0B06, 0x01}, { CCI_REG8(0x0B06), 0x01 },
{0x30A2, 0x00}, { CCI_REG8(0x30A2), 0x00 },
{0x30B4, 0x00}, { CCI_REG8(0x30B4), 0x00 },
{0x3A02, 0xFF}, { CCI_REG8(0x3A02), 0xFF },
{0x3011, 0x00}, { CCI_REG8(0x3011), 0x00 },
{0x3013, 0x01}, { CCI_REG8(0x3013), 0x01 },
{0x0202, 0x0C}, { CCI_REG8(0x0202), 0x0C },
{0x0203, 0x70}, { CCI_REG8(0x0203), 0x70 },
{0x0224, 0x01}, { CCI_REG8(0x0224), 0x01 },
{0x0225, 0xF4}, { CCI_REG8(0x0225), 0xF4 },
{0x0204, 0x00}, { CCI_REG8(0x0204), 0x00 },
{0x0205, 0x00}, { CCI_REG8(0x0205), 0x00 },
{0x020E, 0x01}, { CCI_REG8(0x020E), 0x01 },
{0x020F, 0x00}, { CCI_REG8(0x020F), 0x00 },
{0x0210, 0x01}, { CCI_REG8(0x0210), 0x01 },
{0x0211, 0x00}, { CCI_REG8(0x0211), 0x00 },
{0x0212, 0x01}, { CCI_REG8(0x0212), 0x01 },
{0x0213, 0x00}, { CCI_REG8(0x0213), 0x00 },
{0x0214, 0x01}, { CCI_REG8(0x0214), 0x01 },
{0x0215, 0x00}, { CCI_REG8(0x0215), 0x00 },
{0x0216, 0x00}, { CCI_REG8(0x0216), 0x00 },
{0x0217, 0x00}, { CCI_REG8(0x0217), 0x00 },
{0x4170, 0x00}, { CCI_REG8(0x4170), 0x00 },
{0x4171, 0x10}, { CCI_REG8(0x4171), 0x10 },
{0x4176, 0x00}, { CCI_REG8(0x4176), 0x00 },
{0x4177, 0x3C}, { CCI_REG8(0x4177), 0x3C },
{0xAE20, 0x04}, { CCI_REG8(0xAE20), 0x04 },
{0xAE21, 0x5C}, { CCI_REG8(0xAE21), 0x5C },
{IMX214_TABLE_WAIT_MS, 10},
{0x0138, 0x01},
{IMX214_TABLE_END, 0x00}
}; };
static const struct reg_8 mode_1920x1080[] = { static const struct cci_reg_sequence mode_1920x1080[] = {
{0x0114, 0x03}, { CCI_REG8(0x0114), 0x03 },
{0x0220, 0x00}, { CCI_REG8(0x0220), 0x00 },
{0x0221, 0x11}, { CCI_REG8(0x0221), 0x11 },
{0x0222, 0x01}, { CCI_REG8(0x0222), 0x01 },
{0x0340, 0x0C}, { CCI_REG8(0x0340), 0x0C },
{0x0341, 0x7A}, { CCI_REG8(0x0341), 0x7A },
{0x0342, 0x13}, { CCI_REG8(0x0342), 0x13 },
{0x0343, 0x90}, { CCI_REG8(0x0343), 0x90 },
{0x0344, 0x04}, { CCI_REG8(0x0344), 0x04 },
{0x0345, 0x78}, { CCI_REG8(0x0345), 0x78 },
{0x0346, 0x03}, { CCI_REG8(0x0346), 0x03 },
{0x0347, 0xFC}, { CCI_REG8(0x0347), 0xFC },
{0x0348, 0x0B}, { CCI_REG8(0x0348), 0x0B },
{0x0349, 0xF7}, { CCI_REG8(0x0349), 0xF7 },
{0x034A, 0x08}, { CCI_REG8(0x034A), 0x08 },
{0x034B, 0x33}, { CCI_REG8(0x034B), 0x33 },
{0x0381, 0x01}, { CCI_REG8(0x0381), 0x01 },
{0x0383, 0x01}, { CCI_REG8(0x0383), 0x01 },
{0x0385, 0x01}, { CCI_REG8(0x0385), 0x01 },
{0x0387, 0x01}, { CCI_REG8(0x0387), 0x01 },
{0x0900, 0x00}, { CCI_REG8(0x0900), 0x00 },
{0x0901, 0x00}, { CCI_REG8(0x0901), 0x00 },
{0x0902, 0x00}, { CCI_REG8(0x0902), 0x00 },
{0x3000, 0x35}, { CCI_REG8(0x3000), 0x35 },
{0x3054, 0x01}, { CCI_REG8(0x3054), 0x01 },
{0x305C, 0x11}, { CCI_REG8(0x305C), 0x11 },
{0x0112, 0x0A}, { CCI_REG8(0x0112), 0x0A },
{0x0113, 0x0A}, { CCI_REG8(0x0113), 0x0A },
{0x034C, 0x07}, { CCI_REG8(0x034C), 0x07 },
{0x034D, 0x80}, { CCI_REG8(0x034D), 0x80 },
{0x034E, 0x04}, { CCI_REG8(0x034E), 0x04 },
{0x034F, 0x38}, { CCI_REG8(0x034F), 0x38 },
{0x0401, 0x00}, { CCI_REG8(0x0401), 0x00 },
{0x0404, 0x00}, { CCI_REG8(0x0404), 0x00 },
{0x0405, 0x10}, { CCI_REG8(0x0405), 0x10 },
{0x0408, 0x00}, { CCI_REG8(0x0408), 0x00 },
{0x0409, 0x00}, { CCI_REG8(0x0409), 0x00 },
{0x040A, 0x00}, { CCI_REG8(0x040A), 0x00 },
{0x040B, 0x00}, { CCI_REG8(0x040B), 0x00 },
{0x040C, 0x07}, { CCI_REG8(0x040C), 0x07 },
{0x040D, 0x80}, { CCI_REG8(0x040D), 0x80 },
{0x040E, 0x04}, { CCI_REG8(0x040E), 0x04 },
{0x040F, 0x38}, { CCI_REG8(0x040F), 0x38 },
{0x0301, 0x05}, { CCI_REG8(0x0301), 0x05 },
{0x0303, 0x02}, { CCI_REG8(0x0303), 0x02 },
{0x0305, 0x03}, { CCI_REG8(0x0305), 0x03 },
{0x0306, 0x00}, { CCI_REG8(0x0306), 0x00 },
{0x0307, 0x96}, { CCI_REG8(0x0307), 0x96 },
{0x0309, 0x0A}, { CCI_REG8(0x0309), 0x0A },
{0x030B, 0x01}, { CCI_REG8(0x030B), 0x01 },
{0x0310, 0x00}, { CCI_REG8(0x0310), 0x00 },
{0x0820, 0x12}, { CCI_REG8(0x0820), 0x12 },
{0x0821, 0xC0}, { CCI_REG8(0x0821), 0xC0 },
{0x0822, 0x00}, { CCI_REG8(0x0822), 0x00 },
{0x0823, 0x00}, { CCI_REG8(0x0823), 0x00 },
{0x3A03, 0x04}, { CCI_REG8(0x3A03), 0x04 },
{0x3A04, 0xF8}, { CCI_REG8(0x3A04), 0xF8 },
{0x3A05, 0x02}, { CCI_REG8(0x3A05), 0x02 },
{0x0B06, 0x01}, { CCI_REG8(0x0B06), 0x01 },
{0x30A2, 0x00}, { CCI_REG8(0x30A2), 0x00 },
{0x30B4, 0x00}, { CCI_REG8(0x30B4), 0x00 },
{0x3A02, 0xFF}, { CCI_REG8(0x3A02), 0xFF },
{0x3011, 0x00}, { CCI_REG8(0x3011), 0x00 },
{0x3013, 0x01}, { CCI_REG8(0x3013), 0x01 },
{0x0202, 0x0C}, { CCI_REG8(0x0202), 0x0C },
{0x0203, 0x70}, { CCI_REG8(0x0203), 0x70 },
{0x0224, 0x01}, { CCI_REG8(0x0224), 0x01 },
{0x0225, 0xF4}, { CCI_REG8(0x0225), 0xF4 },
{0x0204, 0x00}, { CCI_REG8(0x0204), 0x00 },
{0x0205, 0x00}, { CCI_REG8(0x0205), 0x00 },
{0x020E, 0x01}, { CCI_REG8(0x020E), 0x01 },
{0x020F, 0x00}, { CCI_REG8(0x020F), 0x00 },
{0x0210, 0x01}, { CCI_REG8(0x0210), 0x01 },
{0x0211, 0x00}, { CCI_REG8(0x0211), 0x00 },
{0x0212, 0x01}, { CCI_REG8(0x0212), 0x01 },
{0x0213, 0x00}, { CCI_REG8(0x0213), 0x00 },
{0x0214, 0x01}, { CCI_REG8(0x0214), 0x01 },
{0x0215, 0x00}, { CCI_REG8(0x0215), 0x00 },
{0x0216, 0x00}, { CCI_REG8(0x0216), 0x00 },
{0x0217, 0x00}, { CCI_REG8(0x0217), 0x00 },
{0x4170, 0x00}, { CCI_REG8(0x4170), 0x00 },
{0x4171, 0x10}, { CCI_REG8(0x4171), 0x10 },
{0x4176, 0x00}, { CCI_REG8(0x4176), 0x00 },
{0x4177, 0x3C}, { CCI_REG8(0x4177), 0x3C },
{0xAE20, 0x04}, { CCI_REG8(0xAE20), 0x04 },
{0xAE21, 0x5C}, { CCI_REG8(0xAE21), 0x5C },
{IMX214_TABLE_WAIT_MS, 10},
{0x0138, 0x01},
{IMX214_TABLE_END, 0x00}
}; };
static const struct reg_8 mode_table_common[] = { static const struct cci_reg_sequence mode_table_common[] = {
/* software reset */ /* software reset */
/* software standby settings */ /* software standby settings */
{0x0100, 0x00}, { CCI_REG8(0x0100), 0x00 },
/* ATR setting */ /* ATR setting */
{0x9300, 0x02}, { CCI_REG8(0x9300), 0x02 },
/* external clock setting */ /* external clock setting */
{0x0136, 0x18}, { CCI_REG8(0x0136), 0x18 },
{0x0137, 0x00}, { CCI_REG8(0x0137), 0x00 },
/* global setting */ /* global setting */
/* basic config */ /* basic config */
{0x0101, 0x00}, { CCI_REG8(0x0101), 0x00 },
{0x0105, 0x01}, { CCI_REG8(0x0105), 0x01 },
{0x0106, 0x01}, { CCI_REG8(0x0106), 0x01 },
{0x4550, 0x02}, { CCI_REG8(0x4550), 0x02 },
{0x4601, 0x00}, { CCI_REG8(0x4601), 0x00 },
{0x4642, 0x05}, { CCI_REG8(0x4642), 0x05 },
{0x6227, 0x11}, { CCI_REG8(0x6227), 0x11 },
{0x6276, 0x00}, { CCI_REG8(0x6276), 0x00 },
{0x900E, 0x06}, { CCI_REG8(0x900E), 0x06 },
{0xA802, 0x90}, { CCI_REG8(0xA802), 0x90 },
{0xA803, 0x11}, { CCI_REG8(0xA803), 0x11 },
{0xA804, 0x62}, { CCI_REG8(0xA804), 0x62 },
{0xA805, 0x77}, { CCI_REG8(0xA805), 0x77 },
{0xA806, 0xAE}, { CCI_REG8(0xA806), 0xAE },
{0xA807, 0x34}, { CCI_REG8(0xA807), 0x34 },
{0xA808, 0xAE}, { CCI_REG8(0xA808), 0xAE },
{0xA809, 0x35}, { CCI_REG8(0xA809), 0x35 },
{0xA80A, 0x62}, { CCI_REG8(0xA80A), 0x62 },
{0xA80B, 0x83}, { CCI_REG8(0xA80B), 0x83 },
{0xAE33, 0x00}, { CCI_REG8(0xAE33), 0x00 },
/* analog setting */ /* analog setting */
{0x4174, 0x00}, { CCI_REG8(0x4174), 0x00 },
{0x4175, 0x11}, { CCI_REG8(0x4175), 0x11 },
{0x4612, 0x29}, { CCI_REG8(0x4612), 0x29 },
{0x461B, 0x12}, { CCI_REG8(0x461B), 0x12 },
{0x461F, 0x06}, { CCI_REG8(0x461F), 0x06 },
{0x4635, 0x07}, { CCI_REG8(0x4635), 0x07 },
{0x4637, 0x30}, { CCI_REG8(0x4637), 0x30 },
{0x463F, 0x18}, { CCI_REG8(0x463F), 0x18 },
{0x4641, 0x0D}, { CCI_REG8(0x4641), 0x0D },
{0x465B, 0x12}, { CCI_REG8(0x465B), 0x12 },
{0x465F, 0x11}, { CCI_REG8(0x465F), 0x11 },
{0x4663, 0x11}, { CCI_REG8(0x4663), 0x11 },
{0x4667, 0x0F}, { CCI_REG8(0x4667), 0x0F },
{0x466F, 0x0F}, { CCI_REG8(0x466F), 0x0F },
{0x470E, 0x09}, { CCI_REG8(0x470E), 0x09 },
{0x4909, 0xAB}, { CCI_REG8(0x4909), 0xAB },
{0x490B, 0x95}, { CCI_REG8(0x490B), 0x95 },
{0x4915, 0x5D}, { CCI_REG8(0x4915), 0x5D },
{0x4A5F, 0xFF}, { CCI_REG8(0x4A5F), 0xFF },
{0x4A61, 0xFF}, { CCI_REG8(0x4A61), 0xFF },
{0x4A73, 0x62}, { CCI_REG8(0x4A73), 0x62 },
{0x4A85, 0x00}, { CCI_REG8(0x4A85), 0x00 },
{0x4A87, 0xFF}, { CCI_REG8(0x4A87), 0xFF },
/* embedded data */ /* embedded data */
{0x5041, 0x04}, { CCI_REG8(0x5041), 0x04 },
{0x583C, 0x04}, { CCI_REG8(0x583C), 0x04 },
{0x620E, 0x04}, { CCI_REG8(0x620E), 0x04 },
{0x6EB2, 0x01}, { CCI_REG8(0x6EB2), 0x01 },
{0x6EB3, 0x00}, { CCI_REG8(0x6EB3), 0x00 },
{0x9300, 0x02}, { CCI_REG8(0x9300), 0x02 },
/* imagequality */ /* imagequality */
/* HDR setting */ /* HDR setting */
{0x3001, 0x07}, { CCI_REG8(0x3001), 0x07 },
{0x6D12, 0x3F}, { CCI_REG8(0x6D12), 0x3F },
{0x6D13, 0xFF}, { CCI_REG8(0x6D13), 0xFF },
{0x9344, 0x03}, { CCI_REG8(0x9344), 0x03 },
{0x9706, 0x10}, { CCI_REG8(0x9706), 0x10 },
{0x9707, 0x03}, { CCI_REG8(0x9707), 0x03 },
{0x9708, 0x03}, { CCI_REG8(0x9708), 0x03 },
{0x9E04, 0x01}, { CCI_REG8(0x9E04), 0x01 },
{0x9E05, 0x00}, { CCI_REG8(0x9E05), 0x00 },
{0x9E0C, 0x01}, { CCI_REG8(0x9E0C), 0x01 },
{0x9E0D, 0x02}, { CCI_REG8(0x9E0D), 0x02 },
{0x9E24, 0x00}, { CCI_REG8(0x9E24), 0x00 },
{0x9E25, 0x8C}, { CCI_REG8(0x9E25), 0x8C },
{0x9E26, 0x00}, { CCI_REG8(0x9E26), 0x00 },
{0x9E27, 0x94}, { CCI_REG8(0x9E27), 0x94 },
{0x9E28, 0x00}, { CCI_REG8(0x9E28), 0x00 },
{0x9E29, 0x96}, { CCI_REG8(0x9E29), 0x96 },
/* CNR parameter setting */ /* CNR parameter setting */
{0x69DB, 0x01}, { CCI_REG8(0x69DB), 0x01 },
/* Moire reduction */ /* Moire reduction */
{0x6957, 0x01}, { CCI_REG8(0x6957), 0x01 },
/* image enhancement */ /* image enhancement */
{0x6987, 0x17}, { CCI_REG8(0x6987), 0x17 },
{0x698A, 0x03}, { CCI_REG8(0x698A), 0x03 },
{0x698B, 0x03}, { CCI_REG8(0x698B), 0x03 },
/* white balanace */ /* white balanace */
{0x0B8E, 0x01}, { CCI_REG8(0x0B8E), 0x01 },
{0x0B8F, 0x00}, { CCI_REG8(0x0B8F), 0x00 },
{0x0B90, 0x01}, { CCI_REG8(0x0B90), 0x01 },
{0x0B91, 0x00}, { CCI_REG8(0x0B91), 0x00 },
{0x0B92, 0x01}, { CCI_REG8(0x0B92), 0x01 },
{0x0B93, 0x00}, { CCI_REG8(0x0B93), 0x00 },
{0x0B94, 0x01}, { CCI_REG8(0x0B94), 0x01 },
{0x0B95, 0x00}, { CCI_REG8(0x0B95), 0x00 },
/* ATR setting */ /* ATR setting */
{0x6E50, 0x00}, { CCI_REG8(0x6E50), 0x00 },
{0x6E51, 0x32}, { CCI_REG8(0x6E51), 0x32 },
{0x9340, 0x00}, { CCI_REG8(0x9340), 0x00 },
{0x9341, 0x3C}, { CCI_REG8(0x9341), 0x3C },
{0x9342, 0x03}, { CCI_REG8(0x9342), 0x03 },
{0x9343, 0xFF}, { CCI_REG8(0x9343), 0xFF },
{IMX214_TABLE_END, 0x00}
}; };
/* /*
@ -419,16 +399,19 @@ static const struct reg_8 mode_table_common[] = {
static const struct imx214_mode { static const struct imx214_mode {
u32 width; u32 width;
u32 height; u32 height;
const struct reg_8 *reg_table; unsigned int num_of_regs;
const struct cci_reg_sequence *reg_table;
} imx214_modes[] = { } imx214_modes[] = {
{ {
.width = 4096, .width = 4096,
.height = 2304, .height = 2304,
.num_of_regs = ARRAY_SIZE(mode_4096x2304),
.reg_table = mode_4096x2304, .reg_table = mode_4096x2304,
}, },
{ {
.width = 1920, .width = 1920,
.height = 1080, .height = 1080,
.num_of_regs = ARRAY_SIZE(mode_1920x1080),
.reg_table = mode_1920x1080, .reg_table = mode_1920x1080,
}, },
}; };
@ -630,7 +613,6 @@ static int imx214_set_ctrl(struct v4l2_ctrl *ctrl)
{ {
struct imx214 *imx214 = container_of(ctrl->handler, struct imx214 *imx214 = container_of(ctrl->handler,
struct imx214, ctrls); struct imx214, ctrls);
u8 vals[2];
int ret; int ret;
/* /*
@ -642,12 +624,7 @@ static int imx214_set_ctrl(struct v4l2_ctrl *ctrl)
switch (ctrl->id) { switch (ctrl->id) {
case V4L2_CID_EXPOSURE: case V4L2_CID_EXPOSURE:
vals[1] = ctrl->val; cci_write(imx214->regmap, IMX214_REG_EXPOSURE, ctrl->val, &ret);
vals[0] = ctrl->val >> 8;
ret = regmap_bulk_write(imx214->regmap, IMX214_REG_EXPOSURE, vals, 2);
if (ret < 0)
dev_err(imx214->dev, "Error %d\n", ret);
ret = 0;
break; break;
default: default:
@ -733,40 +710,6 @@ static int imx214_ctrls_init(struct imx214 *imx214)
return 0; return 0;
}; };
#define MAX_CMD 4
static int imx214_write_table(struct imx214 *imx214,
const struct reg_8 table[])
{
u8 vals[MAX_CMD];
int i;
int ret;
for (; table->addr != IMX214_TABLE_END ; table++) {
if (table->addr == IMX214_TABLE_WAIT_MS) {
usleep_range(table->val * 1000,
table->val * 1000 + 500);
continue;
}
for (i = 0; i < MAX_CMD; i++) {
if (table[i].addr != (table[0].addr + i))
break;
vals[i] = table[i].val;
}
ret = regmap_bulk_write(imx214->regmap, table->addr, vals, i);
if (ret) {
dev_err(imx214->dev, "write_table error: %d\n", ret);
return ret;
}
table += i - 1;
}
return 0;
}
static int imx214_start_streaming(struct imx214 *imx214) static int imx214_start_streaming(struct imx214 *imx214)
{ {
const struct v4l2_mbus_framefmt *fmt; const struct v4l2_mbus_framefmt *fmt;
@ -774,7 +717,8 @@ static int imx214_start_streaming(struct imx214 *imx214)
const struct imx214_mode *mode; const struct imx214_mode *mode;
int ret; int ret;
ret = imx214_write_table(imx214, mode_table_common); ret = cci_multi_reg_write(imx214->regmap, mode_table_common,
ARRAY_SIZE(mode_table_common), NULL);
if (ret < 0) { if (ret < 0) {
dev_err(imx214->dev, "could not sent common table %d\n", ret); dev_err(imx214->dev, "could not sent common table %d\n", ret);
return ret; return ret;
@ -784,17 +728,24 @@ static int imx214_start_streaming(struct imx214 *imx214)
fmt = v4l2_subdev_state_get_format(state, 0); fmt = v4l2_subdev_state_get_format(state, 0);
mode = v4l2_find_nearest_size(imx214_modes, ARRAY_SIZE(imx214_modes), mode = v4l2_find_nearest_size(imx214_modes, ARRAY_SIZE(imx214_modes),
width, height, fmt->width, fmt->height); width, height, fmt->width, fmt->height);
ret = imx214_write_table(imx214, mode->reg_table); ret = cci_multi_reg_write(imx214->regmap, mode->reg_table,
mode->num_of_regs, NULL);
if (ret < 0) { if (ret < 0) {
dev_err(imx214->dev, "could not sent mode table %d\n", ret); dev_err(imx214->dev, "could not sent mode table %d\n", ret);
return ret; return ret;
} }
usleep_range(10000, 10500);
cci_write(imx214->regmap, CCI_REG8(0x0138), 0x01, NULL);
ret = __v4l2_ctrl_handler_setup(&imx214->ctrls); ret = __v4l2_ctrl_handler_setup(&imx214->ctrls);
if (ret < 0) { if (ret < 0) {
dev_err(imx214->dev, "could not sync v4l2 controls\n"); dev_err(imx214->dev, "could not sync v4l2 controls\n");
return ret; return ret;
} }
ret = regmap_write(imx214->regmap, IMX214_REG_MODE_SELECT, IMX214_MODE_STREAMING); ret = cci_write(imx214->regmap, IMX214_REG_MODE_SELECT,
IMX214_MODE_STREAMING, NULL);
if (ret < 0) if (ret < 0)
dev_err(imx214->dev, "could not sent start table %d\n", ret); dev_err(imx214->dev, "could not sent start table %d\n", ret);
@ -805,7 +756,8 @@ static int imx214_stop_streaming(struct imx214 *imx214)
{ {
int ret; int ret;
ret = regmap_write(imx214->regmap, IMX214_REG_MODE_SELECT, IMX214_MODE_STANDBY); ret = cci_write(imx214->regmap, IMX214_REG_MODE_SELECT,
IMX214_MODE_STANDBY, NULL);
if (ret < 0) if (ret < 0)
dev_err(imx214->dev, "could not sent stop table %d\n", ret); dev_err(imx214->dev, "could not sent stop table %d\n", ret);
@ -906,12 +858,6 @@ static const struct v4l2_subdev_internal_ops imx214_internal_ops = {
.init_state = imx214_entity_init_state, .init_state = imx214_entity_init_state,
}; };
static const struct regmap_config sensor_regmap_config = {
.reg_bits = 16,
.val_bits = 8,
.cache_type = REGCACHE_MAPLE,
};
static int imx214_get_regulators(struct device *dev, struct imx214 *imx214) static int imx214_get_regulators(struct device *dev, struct imx214 *imx214)
{ {
unsigned int i; unsigned int i;
@ -995,10 +941,10 @@ static int imx214_probe(struct i2c_client *client)
return dev_err_probe(dev, PTR_ERR(imx214->enable_gpio), return dev_err_probe(dev, PTR_ERR(imx214->enable_gpio),
"failed to get enable gpio\n"); "failed to get enable gpio\n");
imx214->regmap = devm_regmap_init_i2c(client, &sensor_regmap_config); imx214->regmap = devm_cci_regmap_init_i2c(client, 16);
if (IS_ERR(imx214->regmap)) if (IS_ERR(imx214->regmap))
return dev_err_probe(dev, PTR_ERR(imx214->regmap), return dev_err_probe(dev, PTR_ERR(imx214->regmap),
"regmap init failed\n"); "failed to initialize CCI\n");
v4l2_i2c_subdev_init(&imx214->sd, client, &imx214_subdev_ops); v4l2_i2c_subdev_init(&imx214->sd, client, &imx214_subdev_ops);
imx214->sd.internal_ops = &imx214_internal_ops; imx214->sd.internal_ops = &imx214_internal_ops;