Lines Matching +full:conversion +full:- +full:start +full:- +full:gpios

1 // SPDX-License-Identifier: GPL-2.0
8 * V0.0X01.0X01 support conversion gain switch.
9 * V0.0X01.0X02 add debug interface for conversion gain switch.
33 #include <linux/rk-camera-module.h>
34 #include <media/media-entity.h>
35 #include <media/v4l2-async.h>
36 #include <media/v4l2-ctrls.h>
37 #include <media/v4l2-subdev.h>
38 #include <media/v4l2-fwnode.h>
40 #include <linux/rk-preisp.h>
58 #define OF_CAMERA_HDR_MODE "rockchip,camera-hdr-mode"
5914 return -EINVAL; in ov50c40_write_reg()
5922 val_i = 4 - len; in ov50c40_write_reg()
5928 dev_err(&client->dev, "Failed to write 0x%04x,0x%x\n", reg, val); in ov50c40_write_reg()
5929 return -EIO; in ov50c40_write_reg()
5960 return -EINVAL; in ov50c40_read_reg()
5964 msgs[0].addr = client->addr; in ov50c40_read_reg()
5970 msgs[1].addr = client->addr; in ov50c40_read_reg()
5973 msgs[1].buf = &data_be_p[4 - len]; in ov50c40_read_reg()
5975 ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); in ov50c40_read_reg()
5977 return -EIO; in ov50c40_read_reg()
5987 return abs(mode->width - framefmt->width) + in ov50c40_get_reso_dist()
5988 abs(mode->height - framefmt->height); in ov50c40_get_reso_dist()
5994 struct v4l2_mbus_framefmt *framefmt = &fmt->format; in ov50c40_find_best_fit()
5997 int cur_best_fit_dist = -1; in ov50c40_find_best_fit()
6000 for (i = 0; i < ov50c40->cfg_num; i++) { in ov50c40_find_best_fit()
6001 dist = ov50c40_get_reso_dist(&ov50c40->support_modes[i], framefmt); in ov50c40_find_best_fit()
6002 if ((cur_best_fit_dist == -1 || dist < cur_best_fit_dist) && in ov50c40_find_best_fit()
6003 (ov50c40->support_modes[i].bus_fmt == framefmt->code)) { in ov50c40_find_best_fit()
6008 dev_info(&ov50c40->client->dev, "%s: cur_best_fit(%d)", in ov50c40_find_best_fit()
6010 return &ov50c40->support_modes[cur_best_fit]; in ov50c40_find_best_fit()
6021 u32 lane_num = ov50c40->bus_cfg.bus.mipi_csi2.num_data_lanes; in ov50c40_set_fmt()
6023 mutex_lock(&ov50c40->mutex); in ov50c40_set_fmt()
6026 fmt->format.code = mode->bus_fmt; in ov50c40_set_fmt()
6027 fmt->format.width = mode->width; in ov50c40_set_fmt()
6028 fmt->format.height = mode->height; in ov50c40_set_fmt()
6029 fmt->format.field = V4L2_FIELD_NONE; in ov50c40_set_fmt()
6030 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { in ov50c40_set_fmt()
6032 *v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format; in ov50c40_set_fmt()
6034 mutex_unlock(&ov50c40->mutex); in ov50c40_set_fmt()
6035 return -ENOTTY; in ov50c40_set_fmt()
6038 ov50c40->cur_mode = mode; in ov50c40_set_fmt()
6039 h_blank = mode->hts_def - mode->width; in ov50c40_set_fmt()
6040 __v4l2_ctrl_modify_range(ov50c40->hblank, h_blank, in ov50c40_set_fmt()
6042 vblank_def = mode->vts_def - mode->height; in ov50c40_set_fmt()
6043 __v4l2_ctrl_modify_range(ov50c40->vblank, vblank_def, in ov50c40_set_fmt()
6044 OV50C40_VTS_MAX - mode->height, in ov50c40_set_fmt()
6046 __v4l2_ctrl_s_ctrl(ov50c40->vblank, vblank_def); in ov50c40_set_fmt()
6047 pixel_rate = (u32)link_freq_items[mode->mipi_freq_idx] / mode->bpp * 2 * lane_num; in ov50c40_set_fmt()
6048 __v4l2_ctrl_s_ctrl_int64(ov50c40->pixel_rate, in ov50c40_set_fmt()
6050 __v4l2_ctrl_s_ctrl(ov50c40->link_freq, in ov50c40_set_fmt()
6051 mode->mipi_freq_idx); in ov50c40_set_fmt()
6053 dev_info(&ov50c40->client->dev, "%s: mode->mipi_freq_idx(%d)", in ov50c40_set_fmt()
6054 __func__, mode->mipi_freq_idx); in ov50c40_set_fmt()
6056 mutex_unlock(&ov50c40->mutex); in ov50c40_set_fmt()
6066 const struct ov50c40_mode *mode = ov50c40->cur_mode; in ov50c40_get_fmt()
6068 mutex_lock(&ov50c40->mutex); in ov50c40_get_fmt()
6069 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { in ov50c40_get_fmt()
6071 fmt->format = *v4l2_subdev_get_try_format(sd, cfg, fmt->pad); in ov50c40_get_fmt()
6073 mutex_unlock(&ov50c40->mutex); in ov50c40_get_fmt()
6074 return -ENOTTY; in ov50c40_get_fmt()
6077 fmt->format.width = mode->width; in ov50c40_get_fmt()
6078 fmt->format.height = mode->height; in ov50c40_get_fmt()
6079 fmt->format.code = mode->bus_fmt; in ov50c40_get_fmt()
6080 fmt->format.field = V4L2_FIELD_NONE; in ov50c40_get_fmt()
6082 mutex_unlock(&ov50c40->mutex); in ov50c40_get_fmt()
6093 if (code->index != 0) in ov50c40_enum_mbus_code()
6094 return -EINVAL; in ov50c40_enum_mbus_code()
6095 code->code = ov50c40->cur_mode->bus_fmt; in ov50c40_enum_mbus_code()
6106 if (fse->index >= ov50c40->cfg_num) in ov50c40_enum_frame_sizes()
6107 return -EINVAL; in ov50c40_enum_frame_sizes()
6109 if (fse->code != ov50c40->support_modes[fse->index].bus_fmt) in ov50c40_enum_frame_sizes()
6110 return -EINVAL; in ov50c40_enum_frame_sizes()
6112 fse->min_width = ov50c40->support_modes[fse->index].width; in ov50c40_enum_frame_sizes()
6113 fse->max_width = ov50c40->support_modes[fse->index].width; in ov50c40_enum_frame_sizes()
6114 fse->max_height = ov50c40->support_modes[fse->index].height; in ov50c40_enum_frame_sizes()
6115 fse->min_height = ov50c40->support_modes[fse->index].height; in ov50c40_enum_frame_sizes()
6126 val = ((pattern - 1) << 4) | OV50C40_TEST_PATTERN_ENABLE; in ov50c40_enable_test_pattern()
6129 ret = ov50c40_write_reg(ov50c40->client, OV50C40_REG_TEST_PATTERN, in ov50c40_enable_test_pattern()
6138 const struct ov50c40_mode *mode = ov50c40->cur_mode; in ov50c40_g_frame_interval()
6140 fi->interval = mode->max_fps; in ov50c40_g_frame_interval()
6149 u32 lane_num = ov50c40->bus_cfg.bus.mipi_csi2.num_data_lanes; in ov50c40_g_mbus_config()
6152 val = 1 << (lane_num - 1) | in ov50c40_g_mbus_config()
6156 config->type = ov50c40->bus_cfg.bus_type; in ov50c40_g_mbus_config()
6157 config->flags = val; in ov50c40_g_mbus_config()
6169 if (otp->awb_data.flag) { in ov50c40_get_otp()
6170 inf->awb.flag = 1; in ov50c40_get_otp()
6171 inf->awb.r_value = otp->awb_data.r_ratio; in ov50c40_get_otp()
6172 inf->awb.b_value = otp->awb_data.b_ratio; in ov50c40_get_otp()
6173 inf->awb.gr_value = otp->awb_data.g_ratio; in ov50c40_get_otp()
6174 inf->awb.gb_value = 0x0; in ov50c40_get_otp()
6176 inf->awb.golden_r_value = otp->awb_data.r_golden; in ov50c40_get_otp()
6177 inf->awb.golden_b_value = otp->awb_data.b_golden; in ov50c40_get_otp()
6178 inf->awb.golden_gr_value = otp->awb_data.g_golden; in ov50c40_get_otp()
6179 inf->awb.golden_gb_value = 0x0; in ov50c40_get_otp()
6183 if (otp->lsc_data.flag) { in ov50c40_get_otp()
6184 inf->lsc.flag = 1; in ov50c40_get_otp()
6185 inf->lsc.width = otp->basic_data.size.width; in ov50c40_get_otp()
6186 inf->lsc.height = otp->basic_data.size.height; in ov50c40_get_otp()
6187 inf->lsc.table_size = otp->lsc_data.table_size; in ov50c40_get_otp()
6190 inf->lsc.lsc_r[i] = (otp->lsc_data.data[i * 2] << 8) | in ov50c40_get_otp()
6191 otp->lsc_data.data[i * 2 + 1]; in ov50c40_get_otp()
6192 inf->lsc.lsc_gr[i] = (otp->lsc_data.data[i * 2 + 578] << 8) | in ov50c40_get_otp()
6193 otp->lsc_data.data[i * 2 + 579]; in ov50c40_get_otp()
6194 inf->lsc.lsc_gb[i] = (otp->lsc_data.data[i * 2 + 1156] << 8) | in ov50c40_get_otp()
6195 otp->lsc_data.data[i * 2 + 1157]; in ov50c40_get_otp()
6196 inf->lsc.lsc_b[i] = (otp->lsc_data.data[i * 2 + 1734] << 8) | in ov50c40_get_otp()
6197 otp->lsc_data.data[i * 2 + 1735]; in ov50c40_get_otp()
6202 if (otp->pdaf_data.flag) { in ov50c40_get_otp()
6203 inf->pdaf.flag = 1; in ov50c40_get_otp()
6204 inf->pdaf.gainmap_width = otp->pdaf_data.gainmap_width; in ov50c40_get_otp()
6205 inf->pdaf.gainmap_height = otp->pdaf_data.gainmap_height; in ov50c40_get_otp()
6206 inf->pdaf.dcc_mode = otp->pdaf_data.dcc_mode; in ov50c40_get_otp()
6207 inf->pdaf.dcc_dir = otp->pdaf_data.dcc_dir; in ov50c40_get_otp()
6208 inf->pdaf.dccmap_width = otp->pdaf_data.dccmap_width; in ov50c40_get_otp()
6209 inf->pdaf.dccmap_height = otp->pdaf_data.dccmap_height; in ov50c40_get_otp()
6210 w = otp->pdaf_data.gainmap_width; in ov50c40_get_otp()
6211 h = otp->pdaf_data.gainmap_height; in ov50c40_get_otp()
6214 inf->pdaf.gainmap[i * w + j] = in ov50c40_get_otp()
6215 (otp->pdaf_data.gainmap[(i * w + j) * 2] << 8) | in ov50c40_get_otp()
6216 otp->pdaf_data.gainmap[(i * w + j) * 2 + 1]; in ov50c40_get_otp()
6219 w = otp->pdaf_data.dccmap_width; in ov50c40_get_otp()
6220 h = otp->pdaf_data.dccmap_height; in ov50c40_get_otp()
6223 inf->pdaf.dccmap[i * w + j] = in ov50c40_get_otp()
6224 (otp->pdaf_data.dccmap[(i * w + j) * 2] << 8) | in ov50c40_get_otp()
6225 otp->pdaf_data.dccmap[(i * w + j) * 2 + 1]; in ov50c40_get_otp()
6231 if (otp->af_data.flag) { in ov50c40_get_otp()
6232 inf->af.flag = 1; in ov50c40_get_otp()
6233 inf->af.dir_cnt = 1; in ov50c40_get_otp()
6234 inf->af.af_otp[0].vcm_start = otp->af_data.af_inf; in ov50c40_get_otp()
6235 inf->af.af_otp[0].vcm_end = otp->af_data.af_macro; in ov50c40_get_otp()
6236 inf->af.af_otp[0].vcm_dir = 0; in ov50c40_get_otp()
6244 struct otp_info *otp = ov50c40->otp; in ov50c40_get_module_inf()
6247 strscpy(inf->base.sensor, OV50C40_NAME, sizeof(inf->base.sensor)); in ov50c40_get_module_inf()
6248 strscpy(inf->base.module, ov50c40->module_name, in ov50c40_get_module_inf()
6249 sizeof(inf->base.module)); in ov50c40_get_module_inf()
6250 strscpy(inf->base.lens, ov50c40->len_name, sizeof(inf->base.lens)); in ov50c40_get_module_inf()
6257 const struct ov50c40_mode *mode = ov50c40->cur_mode; in ov50c40_get_channel_info()
6259 if (ch_info->index < PAD0 || ch_info->index >= PAD_MAX) in ov50c40_get_channel_info()
6260 return -EINVAL; in ov50c40_get_channel_info()
6262 if (ch_info->index == ov50c40->spd_id && mode->spd) { in ov50c40_get_channel_info()
6263 ch_info->vc = V4L2_MBUS_CSI2_CHANNEL_1; in ov50c40_get_channel_info()
6264 ch_info->width = mode->spd->width; in ov50c40_get_channel_info()
6265 ch_info->height = mode->spd->height; in ov50c40_get_channel_info()
6266 ch_info->bus_fmt = mode->spd->bus_fmt; in ov50c40_get_channel_info()
6267 ch_info->data_type = mode->spd->data_type; in ov50c40_get_channel_info()
6268 ch_info->data_bit = mode->spd->data_bit; in ov50c40_get_channel_info()
6270 ch_info->vc = ov50c40->cur_mode->vc[ch_info->index]; in ov50c40_get_channel_info()
6271 ch_info->width = ov50c40->cur_mode->width; in ov50c40_get_channel_info()
6272 ch_info->height = ov50c40->cur_mode->height; in ov50c40_get_channel_info()
6273 ch_info->bus_fmt = ov50c40->cur_mode->bus_fmt; in ov50c40_get_channel_info()
6290 w = ov50c40->cur_mode->width; in ov50c40_ioctl()
6291 h = ov50c40->cur_mode->height; in ov50c40_ioctl()
6292 for (i = 0; i < ov50c40->cfg_num; i++) { in ov50c40_ioctl()
6293 if (w == ov50c40->support_modes[i].width && in ov50c40_ioctl()
6294 h == ov50c40->support_modes[i].height && in ov50c40_ioctl()
6295 ov50c40->support_modes[i].hdr_mode == hdr_cfg->hdr_mode) { in ov50c40_ioctl()
6296 ov50c40->cur_mode = &ov50c40->support_modes[i]; in ov50c40_ioctl()
6300 if (i == ov50c40->cfg_num) { in ov50c40_ioctl()
6301 dev_err(&ov50c40->client->dev, in ov50c40_ioctl()
6303 hdr_cfg->hdr_mode, w, h); in ov50c40_ioctl()
6304 ret = -EINVAL; in ov50c40_ioctl()
6306 w = ov50c40->cur_mode->hts_def - ov50c40->cur_mode->width; in ov50c40_ioctl()
6307 h = ov50c40->cur_mode->vts_def - ov50c40->cur_mode->height; in ov50c40_ioctl()
6308 __v4l2_ctrl_modify_range(ov50c40->hblank, w, w, 1, w); in ov50c40_ioctl()
6309 __v4l2_ctrl_modify_range(ov50c40->vblank, h, in ov50c40_ioctl()
6310 OV50C40_VTS_MAX - ov50c40->cur_mode->height, in ov50c40_ioctl()
6312 dev_info(&ov50c40->client->dev, in ov50c40_ioctl()
6314 ov50c40->cur_mode->hdr_mode); in ov50c40_ioctl()
6316 dev_info(&ov50c40->client->dev, "%s: matched mode index(%d)", in ov50c40_ioctl()
6324 hdr_cfg->esp.mode = HDR_NORMAL_VC; in ov50c40_ioctl()
6325 hdr_cfg->hdr_mode = ov50c40->cur_mode->hdr_mode; in ov50c40_ioctl()
6332 ret = ov50c40_write_reg(ov50c40->client, OV50C40_REG_CTRL_MODE, in ov50c40_ioctl()
6335 ret = ov50c40_write_reg(ov50c40->client, OV50C40_REG_CTRL_MODE, in ov50c40_ioctl()
6343 ret = -ENOIOCTLCMD; in ov50c40_ioctl()
6366 ret = -ENOMEM; in ov50c40_compat_ioctl32()
6374 ret = -EFAULT; in ov50c40_compat_ioctl32()
6381 ret = -ENOMEM; in ov50c40_compat_ioctl32()
6389 ret = -EFAULT; in ov50c40_compat_ioctl32()
6395 ret = -ENOMEM; in ov50c40_compat_ioctl32()
6403 ret = -EFAULT; in ov50c40_compat_ioctl32()
6410 ret = -ENOMEM; in ov50c40_compat_ioctl32()
6418 ret = -EFAULT; in ov50c40_compat_ioctl32()
6426 ret = -EFAULT; in ov50c40_compat_ioctl32()
6431 ret = -ENOMEM; in ov50c40_compat_ioctl32()
6437 ret = -EFAULT; in ov50c40_compat_ioctl32()
6445 ret = -EFAULT; in ov50c40_compat_ioctl32()
6450 ret = -ENOIOCTLCMD; in ov50c40_compat_ioctl32()
6462 if (!ov50c40->is_thunderboot) { in __ov50c40_start_stream()
6463 ret = ov50c40_write_array(ov50c40->client, ov50c40->cur_mode->reg_list); in __ov50c40_start_stream()
6469 ret = __v4l2_ctrl_handler_setup(&ov50c40->ctrl_handler); in __ov50c40_start_stream()
6473 return ov50c40_write_reg(ov50c40->client, OV50C40_REG_CTRL_MODE, in __ov50c40_start_stream()
6479 if (ov50c40->is_thunderboot) in __ov50c40_stop_stream()
6480 ov50c40->is_first_streamoff = true; in __ov50c40_stop_stream()
6481 return ov50c40_write_reg(ov50c40->client, OV50C40_REG_CTRL_MODE, in __ov50c40_stop_stream()
6488 struct i2c_client *client = ov50c40->client; in ov50c40_s_stream()
6491 dev_info(&client->dev, "%s: on: %d, %dx%d@%d\n", __func__, on, in ov50c40_s_stream()
6492 ov50c40->cur_mode->width, in ov50c40_s_stream()
6493 ov50c40->cur_mode->height, in ov50c40_s_stream()
6494 DIV_ROUND_CLOSEST(ov50c40->cur_mode->max_fps.denominator, in ov50c40_s_stream()
6495 ov50c40->cur_mode->max_fps.numerator)); in ov50c40_s_stream()
6497 mutex_lock(&ov50c40->mutex); in ov50c40_s_stream()
6499 if (on == ov50c40->streaming) in ov50c40_s_stream()
6503 if (ov50c40->is_thunderboot && rkisp_tb_get_state() == RKISP_TB_NG) { in ov50c40_s_stream()
6504 ov50c40->is_thunderboot = false; in ov50c40_s_stream()
6507 ret = pm_runtime_get_sync(&client->dev); in ov50c40_s_stream()
6509 pm_runtime_put_noidle(&client->dev); in ov50c40_s_stream()
6515 v4l2_err(sd, "start stream failed while write regs\n"); in ov50c40_s_stream()
6516 pm_runtime_put(&client->dev); in ov50c40_s_stream()
6521 pm_runtime_put(&client->dev); in ov50c40_s_stream()
6524 ov50c40->streaming = on; in ov50c40_s_stream()
6527 mutex_unlock(&ov50c40->mutex); in ov50c40_s_stream()
6535 struct i2c_client *client = ov50c40->client; in ov50c40_s_power()
6538 mutex_lock(&ov50c40->mutex); in ov50c40_s_power()
6540 /* If the power state is not modified - no work to do. */ in ov50c40_s_power()
6541 if (ov50c40->power_on == !!on) in ov50c40_s_power()
6545 ret = pm_runtime_get_sync(&client->dev); in ov50c40_s_power()
6547 pm_runtime_put_noidle(&client->dev); in ov50c40_s_power()
6551 if (!ov50c40->is_thunderboot) { in ov50c40_s_power()
6552 ret |= ov50c40_write_reg(ov50c40->client, in ov50c40_s_power()
6559 ov50c40->power_on = true; in ov50c40_s_power()
6561 pm_runtime_put(&client->dev); in ov50c40_s_power()
6562 ov50c40->power_on = false; in ov50c40_s_power()
6566 mutex_unlock(&ov50c40->mutex); in ov50c40_s_power()
6581 struct device *dev = &ov50c40->client->dev; in __ov50c40_power_on()
6583 if (ov50c40->is_thunderboot) in __ov50c40_power_on()
6586 if (!IS_ERR_OR_NULL(ov50c40->pins_default)) { in __ov50c40_power_on()
6587 ret = pinctrl_select_state(ov50c40->pinctrl, in __ov50c40_power_on()
6588 ov50c40->pins_default); in __ov50c40_power_on()
6592 ret = clk_set_rate(ov50c40->xvclk, OV50C40_XVCLK_FREQ); in __ov50c40_power_on()
6595 if (clk_get_rate(ov50c40->xvclk) != OV50C40_XVCLK_FREQ) in __ov50c40_power_on()
6597 ret = clk_prepare_enable(ov50c40->xvclk); in __ov50c40_power_on()
6602 if (!IS_ERR(ov50c40->reset_gpio)) in __ov50c40_power_on()
6603 gpiod_direction_output(ov50c40->reset_gpio, 1); in __ov50c40_power_on()
6605 ret = regulator_bulk_enable(OV50C40_NUM_SUPPLIES, ov50c40->supplies); in __ov50c40_power_on()
6611 if (!IS_ERR(ov50c40->reset_gpio)) in __ov50c40_power_on()
6612 gpiod_direction_output(ov50c40->reset_gpio, 0); in __ov50c40_power_on()
6615 if (!IS_ERR(ov50c40->pwdn_gpio)) in __ov50c40_power_on()
6616 gpiod_direction_output(ov50c40->pwdn_gpio, 0); in __ov50c40_power_on()
6621 if (!IS_ERR(ov50c40->reset_gpio)) in __ov50c40_power_on()
6633 clk_disable_unprepare(ov50c40->xvclk); in __ov50c40_power_on()
6641 struct device *dev = &ov50c40->client->dev; in __ov50c40_power_off()
6643 if (ov50c40->is_thunderboot) { in __ov50c40_power_off()
6644 if (ov50c40->is_first_streamoff) { in __ov50c40_power_off()
6645 ov50c40->is_thunderboot = false; in __ov50c40_power_off()
6646 ov50c40->is_first_streamoff = false; in __ov50c40_power_off()
6652 if (!IS_ERR(ov50c40->pwdn_gpio)) in __ov50c40_power_off()
6653 gpiod_direction_output(ov50c40->pwdn_gpio, 1); in __ov50c40_power_off()
6655 clk_disable_unprepare(ov50c40->xvclk); in __ov50c40_power_off()
6657 if (!IS_ERR(ov50c40->reset_gpio)) in __ov50c40_power_off()
6658 gpiod_direction_output(ov50c40->reset_gpio, 1); in __ov50c40_power_off()
6659 if (!IS_ERR_OR_NULL(ov50c40->pins_sleep)) { in __ov50c40_power_off()
6660 ret = pinctrl_select_state(ov50c40->pinctrl, in __ov50c40_power_off()
6661 ov50c40->pins_sleep); in __ov50c40_power_off()
6666 if (ov50c40->is_thunderboot_ng) { in __ov50c40_power_off()
6667 ov50c40->is_thunderboot_ng = false; in __ov50c40_power_off()
6669 regulator_bulk_disable(OV50C40_NUM_SUPPLIES, ov50c40->supplies); in __ov50c40_power_off()
6697 v4l2_subdev_get_try_format(sd, fh->pad, 0); in ov50c40_open()
6698 const struct ov50c40_mode *def_mode = &ov50c40->support_modes[0]; in ov50c40_open()
6700 mutex_lock(&ov50c40->mutex); in ov50c40_open()
6702 try_fmt->width = def_mode->width; in ov50c40_open()
6703 try_fmt->height = def_mode->height; in ov50c40_open()
6704 try_fmt->code = def_mode->bus_fmt; in ov50c40_open()
6705 try_fmt->field = V4L2_FIELD_NONE; in ov50c40_open()
6707 mutex_unlock(&ov50c40->mutex); in ov50c40_open()
6720 if (fie->index >= ov50c40->cfg_num) in ov50c40_enum_frame_interval()
6721 return -EINVAL; in ov50c40_enum_frame_interval()
6723 fie->code = ov50c40->support_modes[fie->index].bus_fmt; in ov50c40_enum_frame_interval()
6724 fie->width = ov50c40->support_modes[fie->index].width; in ov50c40_enum_frame_interval()
6725 fie->height = ov50c40->support_modes[fie->index].height; in ov50c40_enum_frame_interval()
6726 fie->interval = ov50c40->support_modes[fie->index].max_fps; in ov50c40_enum_frame_interval()
6727 fie->reserved[0] = ov50c40->support_modes[fie->index].hdr_mode; in ov50c40_enum_frame_interval()
6732 #define CROP_START(SRC, DST) (((SRC) - (DST)) / 2 / 4 * 4)
6741 if (sel->target == V4L2_SEL_TGT_CROP_BOUNDS) { in ov50c40_get_selection()
6742 sel->r.left = CROP_START(ov50c40->cur_mode->width, DST_WIDTH); in ov50c40_get_selection()
6743 sel->r.width = DST_WIDTH; in ov50c40_get_selection()
6744 sel->r.top = CROP_START(ov50c40->cur_mode->height, DST_HEIGHT); in ov50c40_get_selection()
6745 sel->r.height = DST_HEIGHT; in ov50c40_get_selection()
6748 return -EINVAL; in ov50c40_get_selection()
6796 struct ov50c40 *ov50c40 = container_of(ctrl->handler, in ov50c40_set_ctrl()
6798 struct i2c_client *client = ov50c40->client; in ov50c40_set_ctrl()
6807 switch (ctrl->id) { in ov50c40_set_ctrl()
6810 if (ov50c40->cur_mode->height == 6144) in ov50c40_set_ctrl()
6811 max = ov50c40->cur_mode->height + ctrl->val - 44; in ov50c40_set_ctrl()
6813 max = ov50c40->cur_mode->height + ctrl->val - 22; in ov50c40_set_ctrl()
6814 __v4l2_ctrl_modify_range(ov50c40->exposure, in ov50c40_set_ctrl()
6815 ov50c40->exposure->minimum, max, in ov50c40_set_ctrl()
6816 ov50c40->exposure->step, in ov50c40_set_ctrl()
6817 ov50c40->exposure->default_value); in ov50c40_set_ctrl()
6821 if (!pm_runtime_get_if_in_use(&client->dev)) in ov50c40_set_ctrl()
6824 switch (ctrl->id) { in ov50c40_set_ctrl()
6826 if (ov50c40->cur_mode->height == 6144) in ov50c40_set_ctrl()
6827 exp = ctrl->val / 2; in ov50c40_set_ctrl()
6829 exp = ctrl->val; in ov50c40_set_ctrl()
6830 ret = ov50c40_write_reg(ov50c40->client, in ov50c40_set_ctrl()
6834 dev_dbg(&client->dev, "set exposure 0x%x\n", in ov50c40_set_ctrl()
6835 ctrl->val); in ov50c40_set_ctrl()
6838 if (ctrl->val > 1984) { in ov50c40_set_ctrl()
6839 dgain = ctrl->val * 1024 / 1984; in ov50c40_set_ctrl()
6843 again = ctrl->val; in ov50c40_set_ctrl()
6845 ret = ov50c40_write_reg(ov50c40->client, in ov50c40_set_ctrl()
6849 ret |= ov50c40_write_reg(ov50c40->client, in ov50c40_set_ctrl()
6853 dev_dbg(&client->dev, "set analog gain 0x%x\n", in ov50c40_set_ctrl()
6854 ctrl->val); in ov50c40_set_ctrl()
6857 vts = ctrl->val + ov50c40->cur_mode->height; in ov50c40_set_ctrl()
6858 if (ov50c40->cur_mode->height == 6144) in ov50c40_set_ctrl()
6860 ret = ov50c40_write_reg(ov50c40->client, OV50C40_REG_VTS, in ov50c40_set_ctrl()
6863 dev_dbg(&client->dev, "set vblank 0x%x\n", in ov50c40_set_ctrl()
6864 ctrl->val); in ov50c40_set_ctrl()
6867 ret = ov50c40_enable_test_pattern(ov50c40, ctrl->val); in ov50c40_set_ctrl()
6870 ret = ov50c40_read_reg(ov50c40->client, OV50C40_MIRROR_REG, in ov50c40_set_ctrl()
6873 if (ctrl->val) in ov50c40_set_ctrl()
6877 ret = ov50c40_write_reg(ov50c40->client, OV50C40_MIRROR_REG, in ov50c40_set_ctrl()
6882 ret = ov50c40_read_reg(ov50c40->client, OV50C40_FLIP_REG, in ov50c40_set_ctrl()
6885 if (ctrl->val) in ov50c40_set_ctrl()
6889 ret = ov50c40_write_reg(ov50c40->client, OV50C40_FLIP_REG, in ov50c40_set_ctrl()
6894 dev_warn(&client->dev, "%s Unhandled id:0x%x, val:0x%x\n", in ov50c40_set_ctrl()
6895 __func__, ctrl->id, ctrl->val); in ov50c40_set_ctrl()
6899 pm_runtime_put(&client->dev); in ov50c40_set_ctrl()
6916 u32 lane_num = ov50c40->bus_cfg.bus.mipi_csi2.num_data_lanes; in ov50c40_initialize_controls()
6918 handler = &ov50c40->ctrl_handler; in ov50c40_initialize_controls()
6919 mode = ov50c40->cur_mode; in ov50c40_initialize_controls()
6923 handler->lock = &ov50c40->mutex; in ov50c40_initialize_controls()
6925 ov50c40->link_freq = v4l2_ctrl_new_int_menu(handler, NULL, in ov50c40_initialize_controls()
6929 dst_pixel_rate = (u32)link_freq_items[mode->mipi_freq_idx] / mode->bpp * 2 * lane_num; in ov50c40_initialize_controls()
6931 ov50c40->pixel_rate = v4l2_ctrl_new_std(handler, NULL, in ov50c40_initialize_controls()
6936 __v4l2_ctrl_s_ctrl(ov50c40->link_freq, in ov50c40_initialize_controls()
6937 mode->mipi_freq_idx); in ov50c40_initialize_controls()
6939 h_blank = mode->hts_def - mode->width; in ov50c40_initialize_controls()
6940 ov50c40->hblank = v4l2_ctrl_new_std(handler, NULL, V4L2_CID_HBLANK, in ov50c40_initialize_controls()
6942 if (ov50c40->hblank) in ov50c40_initialize_controls()
6943 ov50c40->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY; in ov50c40_initialize_controls()
6945 vblank_def = mode->vts_def - mode->height; in ov50c40_initialize_controls()
6946 ov50c40->vblank = v4l2_ctrl_new_std(handler, &ov50c40_ctrl_ops, in ov50c40_initialize_controls()
6948 OV50C40_VTS_MAX - mode->height, in ov50c40_initialize_controls()
6950 if (mode->height == 6144) in ov50c40_initialize_controls()
6951 exposure_max = mode->vts_def - 44; in ov50c40_initialize_controls()
6953 exposure_max = mode->vts_def - 22; in ov50c40_initialize_controls()
6954 ov50c40->exposure = v4l2_ctrl_new_std(handler, &ov50c40_ctrl_ops, in ov50c40_initialize_controls()
6957 mode->exp_def); in ov50c40_initialize_controls()
6959 ov50c40->anal_gain = v4l2_ctrl_new_std(handler, &ov50c40_ctrl_ops, in ov50c40_initialize_controls()
6964 ov50c40->test_pattern = v4l2_ctrl_new_std_menu_items(handler, in ov50c40_initialize_controls()
6966 ARRAY_SIZE(ov50c40_test_pattern_menu) - 1, in ov50c40_initialize_controls()
6969 ov50c40->h_flip = v4l2_ctrl_new_std(handler, &ov50c40_ctrl_ops, in ov50c40_initialize_controls()
6972 ov50c40->v_flip = v4l2_ctrl_new_std(handler, &ov50c40_ctrl_ops, in ov50c40_initialize_controls()
6974 if (handler->error) { in ov50c40_initialize_controls()
6975 ret = handler->error; in ov50c40_initialize_controls()
6976 dev_err(&ov50c40->client->dev, in ov50c40_initialize_controls()
6981 ov50c40->subdev.ctrl_handler = handler; in ov50c40_initialize_controls()
6994 struct device *dev = &ov50c40->client->dev; in ov50c40_check_sensor_id()
6998 if (ov50c40->is_thunderboot) { in ov50c40_check_sensor_id()
7007 return -ENODEV; in ov50c40_check_sensor_id()
7020 ov50c40->supplies[i].supply = ov50c40_supply_names[i]; in ov50c40_configure_regulators()
7022 return devm_regulator_bulk_get(&ov50c40->client->dev, in ov50c40_configure_regulators()
7024 ov50c40->supplies); in ov50c40_configure_regulators()
7030 struct device *dev = &client->dev; in ov50c40_probe()
7031 struct device_node *node = dev->of_node; in ov50c40_probe()
7049 return -ENOMEM; in ov50c40_probe()
7052 &ov50c40->module_index); in ov50c40_probe()
7054 &ov50c40->module_facing); in ov50c40_probe()
7056 &ov50c40->module_name); in ov50c40_probe()
7058 &ov50c40->len_name); in ov50c40_probe()
7061 return -EINVAL; in ov50c40_probe()
7064 ov50c40->is_thunderboot = IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP); in ov50c40_probe()
7066 endpoint = of_graph_get_next_endpoint(dev->of_node, NULL); in ov50c40_probe()
7069 return -EINVAL; in ov50c40_probe()
7072 &ov50c40->bus_cfg); in ov50c40_probe()
7073 if (ov50c40->bus_cfg.bus_type == V4L2_MBUS_CSI2_DPHY) { in ov50c40_probe()
7074 ov50c40->support_modes = supported_modes_dphy; in ov50c40_probe()
7075 ov50c40->cfg_num = ARRAY_SIZE(supported_modes_dphy); in ov50c40_probe()
7077 ov50c40->support_modes = supported_modes_cphy; in ov50c40_probe()
7078 ov50c40->cfg_num = ARRAY_SIZE(supported_modes_cphy); in ov50c40_probe()
7081 ov50c40->client = client; in ov50c40_probe()
7082 ov50c40->cur_mode = &ov50c40->support_modes[0]; in ov50c40_probe()
7084 ov50c40->xvclk = devm_clk_get(dev, "xvclk"); in ov50c40_probe()
7085 if (IS_ERR(ov50c40->xvclk)) { in ov50c40_probe()
7087 return -EINVAL; in ov50c40_probe()
7090 ov50c40->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_ASIS); in ov50c40_probe()
7091 if (IS_ERR(ov50c40->reset_gpio)) in ov50c40_probe()
7092 dev_warn(dev, "Failed to get reset-gpios\n"); in ov50c40_probe()
7094 ov50c40->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_ASIS); in ov50c40_probe()
7095 if (IS_ERR(ov50c40->pwdn_gpio)) in ov50c40_probe()
7096 dev_warn(dev, "Failed to get pwdn-gpios\n"); in ov50c40_probe()
7099 "rockchip,spd-id", in ov50c40_probe()
7100 &ov50c40->spd_id); in ov50c40_probe()
7102 ov50c40->spd_id = PAD_MAX; in ov50c40_probe()
7107 ov50c40->pinctrl = devm_pinctrl_get(dev); in ov50c40_probe()
7108 if (!IS_ERR(ov50c40->pinctrl)) { in ov50c40_probe()
7109 ov50c40->pins_default = in ov50c40_probe()
7110 pinctrl_lookup_state(ov50c40->pinctrl, in ov50c40_probe()
7112 if (IS_ERR(ov50c40->pins_default)) in ov50c40_probe()
7115 ov50c40->pins_sleep = in ov50c40_probe()
7116 pinctrl_lookup_state(ov50c40->pinctrl, in ov50c40_probe()
7118 if (IS_ERR(ov50c40->pins_sleep)) in ov50c40_probe()
7130 mutex_init(&ov50c40->mutex); in ov50c40_probe()
7132 sd = &ov50c40->subdev; in ov50c40_probe()
7144 eeprom_ctrl_node = of_parse_phandle(node, "eeprom-ctrl", 0); in ov50c40_probe()
7159 return -ENOMEM; in ov50c40_probe()
7163 ov50c40->otp = otp_ptr; in ov50c40_probe()
7165 ov50c40->otp = NULL; in ov50c40_probe()
7173 sd->internal_ops = &ov50c40_internal_ops; in ov50c40_probe()
7174 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; in ov50c40_probe()
7177 ov50c40->pad.flags = MEDIA_PAD_FL_SOURCE; in ov50c40_probe()
7178 sd->entity.function = MEDIA_ENT_F_CAM_SENSOR; in ov50c40_probe()
7179 ret = media_entity_pads_init(&sd->entity, 1, &ov50c40->pad); in ov50c40_probe()
7185 if (strcmp(ov50c40->module_facing, "back") == 0) in ov50c40_probe()
7190 snprintf(sd->name, sizeof(sd->name), "m%02d_%s_%s %s", in ov50c40_probe()
7191 ov50c40->module_index, facing, in ov50c40_probe()
7192 OV50C40_NAME, dev_name(sd->dev)); in ov50c40_probe()
7206 media_entity_cleanup(&sd->entity); in ov50c40_probe()
7211 v4l2_ctrl_handler_free(&ov50c40->ctrl_handler); in ov50c40_probe()
7213 mutex_destroy(&ov50c40->mutex); in ov50c40_probe()
7225 media_entity_cleanup(&sd->entity); in ov50c40_remove()
7227 v4l2_ctrl_handler_free(&ov50c40->ctrl_handler); in ov50c40_remove()
7228 mutex_destroy(&ov50c40->mutex); in ov50c40_remove()
7230 pm_runtime_disable(&client->dev); in ov50c40_remove()
7231 if (!pm_runtime_status_suspended(&client->dev)) in ov50c40_remove()
7233 pm_runtime_set_suspended(&client->dev); in ov50c40_remove()