media: i2c: imx317 fix exposure issues

fix exposure and gain control issues && adjust register settings

Signed-off-by: Wang Panzhenzhuan <randy.wang@rock-chips.com>
Change-Id: Ia7198cfd60d21689811f789eaf559ae187c644a9
This commit is contained in:
Wang Panzhenzhuan
2020-04-28 09:28:18 +08:00
committed by Tao Huang
parent 5be8f596ff
commit b6451c04d4

View File

@@ -7,6 +7,7 @@
* V0.0X01.0X01 add poweron function.
* V0.0X01.0X02 fix mclk issue when probe multiple camera.
* V0.0X01.0X03 add enum_frame_interval function.
* V0.0X01.0X04 adjust exposue and gain control issues.
*/
#include <linux/clk.h>
@@ -26,20 +27,25 @@
#include <media/v4l2-ctrls.h>
#include <media/v4l2-subdev.h>
#include <linux/pinctrl/consumer.h>
#include <linux/of.h>
#include <linux/of_graph.h>
#include <media/v4l2-fwnode.h>
#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x03)
#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x04)
#ifndef V4L2_CID_DIGITAL_GAIN
#define V4L2_CID_DIGITAL_GAIN V4L2_CID_GAIN
#endif
#define IMX317_LINK_FREQ_360MHZ 360000000
#define MIPI_FREQ 360000000U
/* pixel rate = link frequency * 2 * lanes / BITS_PER_SAMPLE */
#define IMX317_PIXEL_RATE (IMX317_LINK_FREQ_360MHZ * 2 * 2 / 10)
#define IMX317_PIXEL_RATE (MIPI_FREQ * 2LL * 4LL / 10LL)
#define IMX317_XVCLK_FREQ 24000000
#define CHIP_ID 0x03
#define IMX317_REG_CHIP_ID 0x3004
#define CHIP_ID 0x00
#define IMX317_REG_CHIP_ID 0x0000
#define IMX317_REG_CTRL_MODE 0x3000
#define IMX317_MODE_SW_STANDBY 0x12
@@ -56,10 +62,11 @@
#define IMX317_GAIN_H_MASK 0x07
#define IMX317_GAIN_H_SHIFT 8
#define IMX317_GAIN_L_MASK 0xFF
#define IMX317_GAIN_MIN 0x0800
#define IMX317_GAIN_MAX 0xFFFF
#define IMX317_GAIN_MIN 0x80
#define IMX317_GAIN_MAX (22U * IMX317_GAIN_MIN)
#define IMX317_GAIN_STEP 1
#define IMX317_GAIN_DEFAULT 0x0BDF
#define IMX317_GAIN_DEFAULT (20U * IMX317_GAIN_MIN)
#define IMX317_REG_VTS_H 0x30FA
#define IMX317_REG_VTS_M 0x30F9
@@ -79,6 +86,9 @@
#define OF_CAMERA_PINCTRL_STATE_SLEEP "rockchip,camera_sleep"
#define IMX317_NAME "imx317"
#define IMX317_MEDIA_BUS_FMT MEDIA_BUS_FMT_SRGGB10_1X10
static const struct regval *imx317_global_regs;
static const char * const imx317_supply_names[] = {
"avdd", /* Analog power */
@@ -108,6 +118,7 @@ struct imx317 {
struct clk *xvclk;
struct gpio_desc *reset_gpio;
struct gpio_desc *pwdn_gpio;
struct gpio_desc *power_gpio;
struct regulator_bulk_data supplies[IMX317_NUM_SUPPLIES];
struct pinctrl *pinctrl;
@@ -117,6 +128,7 @@ struct imx317 {
struct v4l2_subdev subdev;
struct media_pad pad;
struct v4l2_ctrl_handler ctrl_handler;
struct v4l2_ctrl *link_freq;
struct v4l2_ctrl *exposure;
struct v4l2_ctrl *anal_gain;
struct v4l2_ctrl *digi_gain;
@@ -127,6 +139,9 @@ struct imx317 {
bool streaming;
bool power_on;
const struct imx317_mode *cur_mode;
unsigned int lane_num;
unsigned int cfg_num;
unsigned int pixel_rate;
u32 module_index;
const char *module_facing;
const char *module_name;
@@ -138,17 +153,7 @@ struct imx317 {
/*
* Xclk 24Mhz
*/
static const struct regval imx317_global_regs[] = {
{REG_NULL, 0x00},
};
/*
* Xclk 24Mhz
* max_framerate 30fps
* mipi_datarate per lane 720Mbps
* 4 lane
*/
static const struct regval imx317_1932x1094_regs[] = {
static const struct regval imx317_global_regs_2lane[] = {
{0x3000, 0x1f},
{0x303E, 0x02},
{0x3120, 0xF0},
@@ -191,10 +196,10 @@ static const struct regval imx317_1932x1094_regs[] = {
{0x366F, 0x00},
{0x3670, 0x00},
{0x3671, 0x00},
{0x3004, 0x02},
{0x3005, 0x21},
{0x3004, 0x01},
{0x3005, 0x01},
{0x3006, 0x00},
{0x3007, 0x11},
{0x3007, 0x02},
{0x300E, 0x00},
{0x300F, 0x00},
{0x3037, 0x00},
@@ -207,24 +212,24 @@ static const struct regval imx317_1932x1094_regs[] = {
{0x30DF, 0x00},
{0x30E0, 0x00},
{0x30E1, 0x00},
{0x30E2, 0x02},
{0x30F6, 0x1e},
{0x30F7, 0x01},
{0x30F8, 0xD0},
{0x30F9, 0x20},
{0x30E2, 0x01},
{0x30F6, 0xE0},
{0x30F7, 0x04},
{0x30F8, 0xDA},
{0x30F9, 0x16},
{0x30FA, 0x00},
{0x3130, 0x4e},
{0x3131, 0x04},
{0x3132, 0x46},
{0x3133, 0x04},
{0x3a54, 0x8c},
{0x3a55, 0x07},
{0x3342, 0x0a},
{0x3130, 0x86},
{0x3131, 0x08},
{0x3132, 0x7E},
{0x3133, 0x08},
{0x3A54, 0x18},
{0x3A55, 0x0F},
{0x3342, 0x0A},
{0x3343, 0x00},
{0x3344, 0x1a},
{0x3344, 0x16},
{0x3345, 0x00},
{0x3528, 0x0E},
{0x3554, 0x00},
{0x3554, 0x1F},
{0x3555, 0x01},
{0x3556, 0x01},
{0x3557, 0x01},
@@ -260,6 +265,7 @@ static const struct regval imx317_1932x1094_regs[] = {
{0x3A85, 0x03},
{0x3A86, 0x47},
{0x3A87, 0x00},
{0x3A43, 0x01},
{REG_DELAY, 0x10},
{0x303E, 0x02},
{REG_DELAY, 0x07},
@@ -269,7 +275,10 @@ static const struct regval imx317_1932x1094_regs[] = {
{0x300b, 0x02},
{0x300c, 0x0c},
{0x300d, 0x00},
{0x312e, 0x01}, //CSI_LANE_MODE
{0x3aa2, 0x01}, //PHYSICAL_LANE_NUM
{0x3001, 0x10},
{REG_NULL, 0x00},
};
@@ -277,9 +286,76 @@ static const struct regval imx317_1932x1094_regs[] = {
* Xclk 24Mhz
* max_framerate 30fps
* mipi_datarate per lane 720Mbps
* 4 lane
* 2 lane
*/
static const struct regval imx317_3864x2174_regs[] = {
static const struct regval imx317_1932x1094_regs_2lane[] = {
{0x3000, 0x1f},
{0x3004, 0x02},
{0x3005, 0x21},
{0x3006, 0x00},
{0x3007, 0x11},
/* crop and scale*/
{0x3037, 0x01},
{0x3038, 0x00},
{0x3039, 0x00},
{0x303A, 0x00},
{0x303B, 0x0F},
{0x30E2, 0x02},
{0x30F6, 0x76},
{0x30F7, 0x02},
{0x30F8, 0x0a},
{0x30F9, 0x0f},
{0x30FA, 0x00},
{0x3130, 0x4e},
{0x3131, 0x04},
{0x3132, 0x46},
{0x3133, 0x04},
{0x3a54, 0x8c},
{0x3a55, 0x07},
{0x3344, 0x1a},
{0x3554, 0x00},
{REG_NULL, 0x00},
};
/*
* Xclk 24Mhz
* max_framerate 30fps
* mipi_datarate per lane 720Mbps
* 2 lane
*/
static const struct regval imx317_3864x2174_regs_2lane[] = {
{0x3000, 0x1f},
{0x3004, 0x01},
{0x3005, 0x01},
{0x3006, 0x00},
{0x3007, 0x02},
/* crop and scale*/
{0x3037, 0x00},
{0x3038, 0x00},
{0x3039, 0x00},
{0x303A, 0x00},
{0x303B, 0x0F},
{0x30E2, 0x01},
{0x30F6, 0xE0},
{0x30F7, 0x04},
{0x30F8, 0xDA},
{0x30F9, 0x16},
{0x30FA, 0x00},
{0x3130, 0x86},
{0x3131, 0x08},
{0x3132, 0x7E},
{0x3133, 0x08},
{0x3A54, 0x18},
{0x3A55, 0x0F},
{0x3344, 0x16},
{0x3554, 0x1F},
{0x3A43, 0x01},
{REG_NULL, 0x00},
};
static const struct regval imx317_global_regs_4lane[] = {
{0x3000, 0x1f},
{0x303E, 0x02},
{0x3120, 0xF0},
@@ -401,26 +477,130 @@ static const struct regval imx317_3864x2174_regs[] = {
{0x300b, 0x02},
{0x300c, 0x0c},
{0x300d, 0x00},
{0x312e, 0x03}, //CSI_LANE_MODE
{0x3aa2, 0x03}, //PHYSICAL_LANE_NUM
{0x3001, 0x10},
{REG_NULL, 0x00},
};
static const struct imx317_mode supported_modes[] = {
/*
* Xclk 24Mhz
* max_framerate 30fps
* mipi_datarate per lane 720Mbps
* 4 lane
*/
static const struct regval imx317_1932x1094_regs_4lane[] = {
{0x3000, 0x1f},
{0x3004, 0x02},
{0x3005, 0x21},
{0x3006, 0x00},
{0x3007, 0x11},
/* crop and scale*/
{0x3037, 0x01},
{0x3038, 0x00},
{0x3039, 0x00},
{0x303A, 0x00},
{0x303B, 0x0F},
{0x30E2, 0x02},
{0x30F6, 0x1e},
{0x30F7, 0x01},
{0x30F8, 0xD0},
{0x30F9, 0x20},
{0x30FA, 0x00},
{0x3130, 0x4e},
{0x3131, 0x04},
{0x3132, 0x46},
{0x3133, 0x04},
{0x3a54, 0x8c},
{0x3a55, 0x07},
{0x3344, 0x1a},
{0x3554, 0x00},
{0x3A43, 0x01},
{REG_NULL, 0x00},
};
/*
* Xclk 24Mhz
* max_framerate 30fps
* mipi_datarate per lane 720Mbps
* 4 lane
*/
static const struct regval imx317_3864x2174_regs_4lane[] = {
{0x3000, 0x1f},
{0x3004, 0x01},
{0x3005, 0x01},
{0x3006, 0x00},
{0x3007, 0x02},
/* crop and scale*/
{0x3037, 0x00},
{0x3038, 0x00},
{0x3039, 0x00},
{0x303A, 0x00},
{0x303B, 0x0F},
{0x30E2, 0x01},
{0x30F6, 0x10},
{0x30F7, 0x02},
{0x30F8, 0xc6},
{0x30F9, 0x11},
{0x30FA, 0x00},
{0x3130, 0x86},
{0x3131, 0x08},
{0x3132, 0x7E},
{0x3133, 0x08},
{0x3A54, 0x18},
{0x3A55, 0x0F},
{0x3344, 0x16},
{0x3554, 0x1F},
{0x3A43, 0x01},
{REG_NULL, 0x00},
};
static const struct imx317_mode supported_modes_2lane[] = {
{
.width = 1932,
.height = 1094,
.width = 1920,
.height = 1080,
.max_fps = {
.numerator = 10000,
.denominator = 300000,
},
.exp_def = 0x000C,
.hts_def = 0x011E,
.vts_def = 0x20D0,
.reg_list = imx317_1932x1094_regs,
.hts_def = 0x0276,
.vts_def = 0x0f0a,
.reg_list = imx317_1932x1094_regs_2lane,
},
{
.width = 3864,
.height = 2174,
.width = 3840,
.height = 2160,
.max_fps = {
.numerator = 10000,
.denominator = 100000,
},
.exp_def = 0x000c,
.hts_def = 0x04E0,
.vts_def = 0x16DA,
.reg_list = imx317_3864x2174_regs_2lane,
},
};
static const struct imx317_mode supported_modes_4lane[] = {
{
.width = 1920,
.height = 1080,
.max_fps = {
.numerator = 10000,
.denominator = 300000,
},
.exp_def = 0x000c,
.hts_def = 0x011E,
.vts_def = 0x20D0,
.reg_list = imx317_1932x1094_regs_4lane,
},
{
.width = 3840,
.height = 2160,
.max_fps = {
.numerator = 10000,
.denominator = 300000,
@@ -428,12 +608,14 @@ static const struct imx317_mode supported_modes[] = {
.exp_def = 0x000C,
.hts_def = 0x0210,
.vts_def = 0x11C6,
.reg_list = imx317_3864x2174_regs,
.reg_list = imx317_3864x2174_regs_4lane,
},
};
static const struct imx317_mode *supported_modes;
static const s64 link_freq_menu_items[] = {
IMX317_LINK_FREQ_360MHZ
MIPI_FREQ,
};
static const char * const imx317_test_pattern_menu[] = {
@@ -535,7 +717,8 @@ static int imx317_get_reso_dist(const struct imx317_mode *mode,
}
static const struct imx317_mode *
imx317_find_best_fit(struct v4l2_subdev_format *fmt)
imx317_find_best_fit(struct imx317 *imx317,
struct v4l2_subdev_format *fmt)
{
struct v4l2_mbus_framefmt *framefmt = &fmt->format;
int dist;
@@ -543,7 +726,7 @@ imx317_find_best_fit(struct v4l2_subdev_format *fmt)
int cur_best_fit_dist = -1;
unsigned int i;
for (i = 0; i < ARRAY_SIZE(supported_modes); i++) {
for (i = 0; i < imx317->cfg_num; i++) {
dist = imx317_get_reso_dist(&supported_modes[i], framefmt);
if (cur_best_fit_dist == -1 || dist < cur_best_fit_dist) {
cur_best_fit_dist = dist;
@@ -564,8 +747,8 @@ static int imx317_set_fmt(struct v4l2_subdev *sd,
mutex_lock(&imx317->mutex);
mode = imx317_find_best_fit(fmt);
fmt->format.code = MEDIA_BUS_FMT_SBGGR10_1X10;
mode = imx317_find_best_fit(imx317, fmt);
fmt->format.code = IMX317_MEDIA_BUS_FMT;
fmt->format.width = mode->width;
fmt->format.height = mode->height;
fmt->format.field = V4L2_FIELD_NONE;
@@ -578,7 +761,7 @@ static int imx317_set_fmt(struct v4l2_subdev *sd,
#endif
} else {
imx317->cur_mode = mode;
h_blank = mode->hts_def - mode->width;
h_blank = mode->hts_def;
__v4l2_ctrl_modify_range(imx317->hblank, h_blank,
h_blank, 1, h_blank);
vblank_def = mode->vts_def - mode->height;
@@ -610,7 +793,7 @@ static int imx317_get_fmt(struct v4l2_subdev *sd,
} else {
fmt->format.width = mode->width;
fmt->format.height = mode->height;
fmt->format.code = MEDIA_BUS_FMT_SBGGR10_1X10;
fmt->format.code = IMX317_MEDIA_BUS_FMT;
fmt->format.field = V4L2_FIELD_NONE;
}
mutex_unlock(&imx317->mutex);
@@ -624,7 +807,7 @@ static int imx317_enum_mbus_code(struct v4l2_subdev *sd,
{
if (code->index != 0)
return -EINVAL;
code->code = MEDIA_BUS_FMT_SBGGR10_1X10;
code->code = IMX317_MEDIA_BUS_FMT;
return 0;
}
@@ -633,10 +816,12 @@ static int imx317_enum_frame_sizes(struct v4l2_subdev *sd,
struct v4l2_subdev_pad_config *cfg,
struct v4l2_subdev_frame_size_enum *fse)
{
if (fse->index >= ARRAY_SIZE(supported_modes))
struct imx317 *imx317 = to_imx317(sd);
if (fse->index >= imx317->cfg_num)
return -EINVAL;
if (fse->code != MEDIA_BUS_FMT_SBGGR10_1X10)
if (fse->code != IMX317_MEDIA_BUS_FMT)
return -EINVAL;
fse->min_width = supported_modes[fse->index].width;
@@ -766,6 +951,12 @@ static int imx317_s_stream(struct v4l2_subdev *sd, int on)
struct i2c_client *client = imx317->client;
int ret = 0;
dev_info(&client->dev, "%s: on: %d, %dx%d@%d\n", __func__, on,
imx317->cur_mode->width,
imx317->cur_mode->height,
DIV_ROUND_CLOSEST(imx317->cur_mode->max_fps.denominator,
imx317->cur_mode->max_fps.numerator));
mutex_lock(&imx317->mutex);
on = !!on;
if (on == imx317->streaming)
@@ -847,6 +1038,10 @@ static int __imx317_power_on(struct imx317 *imx317)
u32 delay_us;
struct device *dev = &imx317->client->dev;
if (!IS_ERR(imx317->power_gpio))
gpiod_set_value_cansleep(imx317->power_gpio, 1);
usleep_range(3000, 5000);
if (!IS_ERR_OR_NULL(imx317->pins_default)) {
ret = pinctrl_select_state(imx317->pinctrl,
imx317->pins_default);
@@ -907,6 +1102,8 @@ static void __imx317_power_off(struct imx317 *imx317)
if (ret < 0)
dev_dbg(dev, "could not set pins\n");
}
if (!IS_ERR(imx317->power_gpio))
gpiod_set_value_cansleep(imx317->power_gpio, 0);
regulator_bulk_disable(IMX317_NUM_SUPPLIES, imx317->supplies);
}
@@ -942,7 +1139,7 @@ static int imx317_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
/* Initialize try_fmt */
try_fmt->width = def_mode->width;
try_fmt->height = def_mode->height;
try_fmt->code = MEDIA_BUS_FMT_SBGGR10_1X10;
try_fmt->code = IMX317_MEDIA_BUS_FMT;
try_fmt->field = V4L2_FIELD_NONE;
mutex_unlock(&imx317->mutex);
@@ -956,10 +1153,12 @@ static int imx317_enum_frame_interval(struct v4l2_subdev *sd,
struct v4l2_subdev_pad_config *cfg,
struct v4l2_subdev_frame_interval_enum *fie)
{
if (fie->index >= ARRAY_SIZE(supported_modes))
struct imx317 *imx317 = to_imx317(sd);
if (fie->index >= imx317->cfg_num)
return -EINVAL;
if (fie->code != MEDIA_BUS_FMT_SBGGR10_1X10)
if (fie->code != IMX317_MEDIA_BUS_FMT)
return -EINVAL;
fie->width = supported_modes[fie->index].width;
@@ -1013,6 +1212,7 @@ static int imx317_set_ctrl(struct v4l2_ctrl *ctrl)
struct i2c_client *client = imx317->client;
s64 max;
u32 val = 0;
u32 vts_tmp = 0;
int ret = 0;
/* Propagate change of current control to all related controls */
@@ -1033,6 +1233,17 @@ static int imx317_set_ctrl(struct v4l2_ctrl *ctrl)
switch (ctrl->id) {
case V4L2_CID_EXPOSURE:
/* 4 least significant bits of expsoure are fractional part */
/* calculate actual integration time */
ret = imx317_read_reg(imx317->client, IMX317_REG_VTS_H,
IMX317_REG_VALUE_08BIT, &val);
vts_tmp = (val & 0xff) << 16;
ret |= imx317_read_reg(imx317->client, IMX317_REG_VTS_M,
IMX317_REG_VALUE_08BIT, &val);
vts_tmp = vts_tmp | ((val & 0xff) << 8);
ret |= imx317_read_reg(imx317->client, IMX317_REG_VTS_L,
IMX317_REG_VALUE_08BIT, &val);
vts_tmp = vts_tmp | (val & 0xff);
ctrl->val = vts_tmp + 1 - ctrl->val;
ret = imx317_write_reg(imx317->client,
IMX317_REG_EXPOSURE_H,
IMX317_REG_VALUE_08BIT,
@@ -1043,15 +1254,11 @@ static int imx317_set_ctrl(struct v4l2_ctrl *ctrl)
ctrl->val & 0xFF);
break;
case V4L2_CID_ANALOGUE_GAIN:
val = 2048 * 2048;
do_div(val, ctrl->val);
if (val <= 2048)
val = 2048 - val;
else
val = 0;
if (val > 0x7A5)
val = 0x7A5;
if (ctrl->val > IMX317_GAIN_MAX)
ctrl->val = IMX317_GAIN_MAX;
if (ctrl->val < IMX317_GAIN_MIN)
ctrl->val = IMX317_GAIN_MIN;
val = 2048 - (2048 * IMX317_GAIN_MIN) / ctrl->val;
ret = imx317_write_reg(imx317->client, IMX317_REG_GAIN_H,
IMX317_REG_VALUE_08BIT,
@@ -1094,7 +1301,6 @@ static int imx317_initialize_controls(struct imx317 *imx317)
{
const struct imx317_mode *mode;
struct v4l2_ctrl_handler *handler;
struct v4l2_ctrl *ctrl;
s64 exposure_max, vblank_def;
u32 h_blank;
int ret;
@@ -1106,15 +1312,14 @@ static int imx317_initialize_controls(struct imx317 *imx317)
return ret;
handler->lock = &imx317->mutex;
ctrl = v4l2_ctrl_new_int_menu(handler, NULL, V4L2_CID_LINK_FREQ,
0, 0, link_freq_menu_items);
if (ctrl)
ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
imx317->link_freq = v4l2_ctrl_new_int_menu(handler, NULL,
V4L2_CID_LINK_FREQ, 0, 0,
link_freq_menu_items);
v4l2_ctrl_new_std(handler, NULL, V4L2_CID_PIXEL_RATE,
0, IMX317_PIXEL_RATE, 1, IMX317_PIXEL_RATE);
0, imx317->pixel_rate, 1, imx317->pixel_rate);
h_blank = mode->hts_def - mode->width;
h_blank = mode->hts_def;
imx317->hblank = v4l2_ctrl_new_std(handler, NULL, V4L2_CID_HBLANK,
h_blank, h_blank, 1, h_blank);
if (imx317->hblank)
@@ -1190,6 +1395,49 @@ static int imx317_configure_regulators(struct imx317 *imx317)
imx317->supplies);
}
static int imx317_parse_of(struct imx317 *imx317)
{
struct device *dev = &imx317->client->dev;
struct device_node *endpoint;
struct fwnode_handle *fwnode;
int rval;
endpoint = of_graph_get_next_endpoint(dev->of_node, NULL);
if (!endpoint) {
dev_err(dev, "Failed to get endpoint\n");
return -EINVAL;
}
fwnode = of_fwnode_handle(endpoint);
rval = fwnode_property_read_u32_array(fwnode, "data-lanes", NULL, 0);
of_node_put(endpoint);
if (rval <= 0) {
dev_warn(dev, " Get mipi lane num failed!\n");
return -1;
}
imx317->lane_num = rval;
if (4 == imx317->lane_num) {
imx317->cur_mode = &supported_modes_4lane[0];
supported_modes = supported_modes_4lane;
imx317->cfg_num = ARRAY_SIZE(supported_modes_4lane);
imx317_global_regs = imx317_global_regs_4lane;
/* pixel rate = link frequency * 2 * lanes / BITS_PER_SAMPLE */
imx317->pixel_rate = MIPI_FREQ * 2U * imx317->lane_num / 10U;
dev_info(dev, "lane_num(%d) pixel_rate(%u)\n",
imx317->lane_num, imx317->pixel_rate);
} else {
imx317->cur_mode = &supported_modes_2lane[0];
supported_modes = supported_modes_2lane;
imx317->cfg_num = ARRAY_SIZE(supported_modes_2lane);
imx317_global_regs = imx317_global_regs_2lane;
/*pixel rate = link frequency * 2 * lanes / BITS_PER_SAMPLE */
imx317->pixel_rate = MIPI_FREQ * 2U * (imx317->lane_num) / 10U;
dev_info(dev, "lane_num(%d) pixel_rate(%u), not supported yet!\n",
imx317->lane_num, imx317->pixel_rate);
}
return 0;
}
static int imx317_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
@@ -1231,6 +1479,9 @@ static int imx317_probe(struct i2c_client *client,
return -EINVAL;
}
imx317->power_gpio = devm_gpiod_get(dev, "power", GPIOD_OUT_LOW);
if (IS_ERR(imx317->power_gpio))
dev_warn(dev, "Failed to get power-gpios\n");
imx317->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
if (IS_ERR(imx317->reset_gpio))
dev_warn(dev, "Failed to get reset-gpios\n");
@@ -1239,6 +1490,10 @@ static int imx317_probe(struct i2c_client *client,
if (IS_ERR(imx317->pwdn_gpio))
dev_warn(dev, "Failed to get pwdn-gpios\n");
ret = imx317_parse_of(imx317);
if (ret != 0)
return -EINVAL;
imx317->pinctrl = devm_pinctrl_get(dev);
if (!IS_ERR(imx317->pinctrl)) {
imx317->pins_default =