Lines Matching +full:trig +full:- +full:gpios

1 // SPDX-License-Identifier: GPL-2.0
30 #include <linux/rk-camera-module.h>
32 #include <media/v4l2-async.h>
33 #include <media/media-entity.h>
34 #include <media/v4l2-common.h>
35 #include <media/v4l2-ctrls.h>
36 #include <media/v4l2-device.h>
37 #include <media/v4l2-event.h>
38 #include <media/v4l2-fwnode.h>
39 #include <media/v4l2-image-sizes.h>
40 #include <media/v4l2-mediabus.h>
41 #include <media/v4l2-subdev.h>
215 {0x03, "A-kerr"},
233 {0x15, "Lite-on"},
276 {0xd8, "XinXu DS-8335"},
277 {0xd9, "XinXu DS-8341"},
718 {0x3031, 0x0a}, //MIPI 10-bit mode
1045 // AM19 : 3617 <- 0xC0
1102 {0x3031, 0x0a}, // MIPI 10-bit mode
1375 // AM19 : 3617 <- 0xC0
1458 // AM19 : 3617 <- 0xC0
1515 {0x3031, 0x0a}, // MIPI 10-bit mode
1671 {0x4000, 0xf1}, // out_range/format_chg/gain/exp_chg trig enable
1922 return -EINVAL; in ov8858_write_reg()
1930 val_i = 4 - len; in ov8858_write_reg()
1936 return -EIO; in ov8858_write_reg()
1966 return -EINVAL; in ov8858_read_reg()
1970 msgs[0].addr = client->addr; in ov8858_read_reg()
1976 msgs[1].addr = client->addr; in ov8858_read_reg()
1979 msgs[1].buf = &data_be_p[4 - len]; in ov8858_read_reg()
1981 ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); in ov8858_read_reg()
1983 return -EIO; in ov8858_read_reg()
1993 return abs(mode->width - framefmt->width) + in ov8858_get_reso_dist()
1994 abs(mode->height - framefmt->height); in ov8858_get_reso_dist()
2001 struct v4l2_mbus_framefmt *framefmt = &fmt->format; in ov8858_find_best_fit()
2004 int cur_best_fit_dist = -1; in ov8858_find_best_fit()
2007 for (i = 0; i < ov8858->cfg_num; i++) { in ov8858_find_best_fit()
2009 if (cur_best_fit_dist == -1 || dist < cur_best_fit_dist) { in ov8858_find_best_fit()
2026 mutex_lock(&ov8858->mutex); in ov8858_set_fmt()
2029 fmt->format.code = OV8858_MEDIA_BUS_FMT; in ov8858_set_fmt()
2030 fmt->format.width = mode->width; in ov8858_set_fmt()
2031 fmt->format.height = mode->height; in ov8858_set_fmt()
2032 fmt->format.field = V4L2_FIELD_NONE; in ov8858_set_fmt()
2033 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { in ov8858_set_fmt()
2035 *v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format; in ov8858_set_fmt()
2037 mutex_unlock(&ov8858->mutex); in ov8858_set_fmt()
2038 return -ENOTTY; in ov8858_set_fmt()
2041 ov8858->cur_mode = mode; in ov8858_set_fmt()
2042 h_blank = mode->hts_def - mode->width; in ov8858_set_fmt()
2043 __v4l2_ctrl_modify_range(ov8858->hblank, h_blank, in ov8858_set_fmt()
2045 vblank_def = mode->vts_def - mode->height; in ov8858_set_fmt()
2046 __v4l2_ctrl_modify_range(ov8858->vblank, vblank_def, in ov8858_set_fmt()
2047 OV8858_VTS_MAX - mode->height, in ov8858_set_fmt()
2051 mutex_unlock(&ov8858->mutex); in ov8858_set_fmt()
2061 const struct ov8858_mode *mode = ov8858->cur_mode; in ov8858_get_fmt()
2063 mutex_lock(&ov8858->mutex); in ov8858_get_fmt()
2064 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { in ov8858_get_fmt()
2066 fmt->format = *v4l2_subdev_get_try_format(sd, cfg, fmt->pad); in ov8858_get_fmt()
2068 mutex_unlock(&ov8858->mutex); in ov8858_get_fmt()
2069 return -ENOTTY; in ov8858_get_fmt()
2072 fmt->format.width = mode->width; in ov8858_get_fmt()
2073 fmt->format.height = mode->height; in ov8858_get_fmt()
2074 fmt->format.code = OV8858_MEDIA_BUS_FMT; in ov8858_get_fmt()
2075 fmt->format.field = V4L2_FIELD_NONE; in ov8858_get_fmt()
2077 mutex_unlock(&ov8858->mutex); in ov8858_get_fmt()
2086 if (code->index != 0) in ov8858_enum_mbus_code()
2087 return -EINVAL; in ov8858_enum_mbus_code()
2088 code->code = OV8858_MEDIA_BUS_FMT; in ov8858_enum_mbus_code()
2099 if (fse->index >= ov8858->cfg_num) in ov8858_enum_frame_sizes()
2100 return -EINVAL; in ov8858_enum_frame_sizes()
2102 if (fse->code != OV8858_MEDIA_BUS_FMT) in ov8858_enum_frame_sizes()
2103 return -EINVAL; in ov8858_enum_frame_sizes()
2105 fse->min_width = supported_modes[fse->index].width; in ov8858_enum_frame_sizes()
2106 fse->max_width = supported_modes[fse->index].width; in ov8858_enum_frame_sizes()
2107 fse->max_height = supported_modes[fse->index].height; in ov8858_enum_frame_sizes()
2108 fse->min_height = supported_modes[fse->index].height; in ov8858_enum_frame_sizes()
2118 val = (pattern - 1) | OV8858_TEST_PATTERN_ENABLE; in ov8858_enable_test_pattern()
2122 return ov8858_write_reg(ov8858->client, in ov8858_enable_test_pattern()
2132 const struct ov8858_mode *mode = ov8858->cur_mode; in ov8858_g_frame_interval()
2134 fi->interval = mode->max_fps; in ov8858_g_frame_interval()
2146 if (otp_r1a->flag & 0x80) { in ov8858_get_r1a_otp()
2147 inf->fac.flag = 1; in ov8858_get_r1a_otp()
2148 inf->fac.year = otp_r1a->year; in ov8858_get_r1a_otp()
2149 inf->fac.month = otp_r1a->month; in ov8858_get_r1a_otp()
2150 inf->fac.day = otp_r1a->day; in ov8858_get_r1a_otp()
2152 for (i = 0; i < ARRAY_SIZE(ov8858_module_info) - 1; i++) { in ov8858_get_r1a_otp()
2153 if (ov8858_module_info[i].id == otp_r1a->module_id) in ov8858_get_r1a_otp()
2156 strlcpy(inf->fac.module, ov8858_module_info[i].name, in ov8858_get_r1a_otp()
2157 sizeof(inf->fac.module)); in ov8858_get_r1a_otp()
2159 for (i = 0; i < ARRAY_SIZE(ov8858_lens_info) - 1; i++) { in ov8858_get_r1a_otp()
2160 if (ov8858_lens_info[i].id == otp_r1a->lens_id) in ov8858_get_r1a_otp()
2163 strlcpy(inf->fac.lens, ov8858_lens_info[i].name, in ov8858_get_r1a_otp()
2164 sizeof(inf->fac.lens)); in ov8858_get_r1a_otp()
2168 if (otp_r1a->flag & 0x40) { in ov8858_get_r1a_otp()
2169 if (otp_r1a->light_rg == 0) in ov8858_get_r1a_otp()
2171 rg = otp_r1a->rg_ratio; in ov8858_get_r1a_otp()
2173 rg = otp_r1a->rg_ratio * (otp_r1a->light_rg + 512) / 1024; in ov8858_get_r1a_otp()
2175 if (otp_r1a->light_bg == 0) in ov8858_get_r1a_otp()
2177 bg = otp_r1a->bg_ratio; in ov8858_get_r1a_otp()
2179 bg = otp_r1a->bg_ratio * (otp_r1a->light_bg + 512) / 1024; in ov8858_get_r1a_otp()
2181 inf->awb.flag = 1; in ov8858_get_r1a_otp()
2182 inf->awb.r_value = rg; in ov8858_get_r1a_otp()
2183 inf->awb.b_value = bg; in ov8858_get_r1a_otp()
2184 inf->awb.gr_value = 0x200; in ov8858_get_r1a_otp()
2185 inf->awb.gb_value = 0x200; in ov8858_get_r1a_otp()
2187 inf->awb.golden_r_value = 0; in ov8858_get_r1a_otp()
2188 inf->awb.golden_b_value = 0; in ov8858_get_r1a_otp()
2189 inf->awb.golden_gr_value = 0; in ov8858_get_r1a_otp()
2190 inf->awb.golden_gb_value = 0; in ov8858_get_r1a_otp()
2194 if (otp_r1a->flag & 0x20) { in ov8858_get_r1a_otp()
2195 inf->af.flag = 1; in ov8858_get_r1a_otp()
2196 inf->af.dir_cnt = 1; in ov8858_get_r1a_otp()
2197 inf->af.af_otp[0].vcm_start = otp_r1a->vcm_start; in ov8858_get_r1a_otp()
2198 inf->af.af_otp[0].vcm_end = otp_r1a->vcm_end; in ov8858_get_r1a_otp()
2199 inf->af.af_otp[0].vcm_dir = otp_r1a->vcm_dir; in ov8858_get_r1a_otp()
2203 if (otp_r1a->flag & 0x10) { in ov8858_get_r1a_otp()
2204 inf->lsc.flag = 1; in ov8858_get_r1a_otp()
2205 inf->lsc.decimal_bits = 0; in ov8858_get_r1a_otp()
2206 inf->lsc.lsc_w = 6; in ov8858_get_r1a_otp()
2207 inf->lsc.lsc_h = 6; in ov8858_get_r1a_otp()
2211 inf->lsc.lsc_gr[i] = otp_r1a->lenc[j++]; in ov8858_get_r1a_otp()
2212 inf->lsc.lsc_gb[i] = inf->lsc.lsc_gr[i]; in ov8858_get_r1a_otp()
2215 inf->lsc.lsc_b[i] = otp_r1a->lenc[j++] + otp_r1a->lenc[108]; in ov8858_get_r1a_otp()
2217 inf->lsc.lsc_r[i] = otp_r1a->lenc[j++] + otp_r1a->lenc[109]; in ov8858_get_r1a_otp()
2228 if (otp_r2a->flag & 0xC0) { in ov8858_get_r2a_otp()
2229 inf->fac.flag = 1; in ov8858_get_r2a_otp()
2230 inf->fac.year = otp_r2a->year; in ov8858_get_r2a_otp()
2231 inf->fac.month = otp_r2a->month; in ov8858_get_r2a_otp()
2232 inf->fac.day = otp_r2a->day; in ov8858_get_r2a_otp()
2234 for (i = 0; i < ARRAY_SIZE(ov8858_module_info) - 1; i++) { in ov8858_get_r2a_otp()
2235 if (ov8858_module_info[i].id == otp_r2a->module_id) in ov8858_get_r2a_otp()
2238 strlcpy(inf->fac.module, ov8858_module_info[i].name, in ov8858_get_r2a_otp()
2239 sizeof(inf->fac.module)); in ov8858_get_r2a_otp()
2241 for (i = 0; i < ARRAY_SIZE(ov8858_lens_info) - 1; i++) { in ov8858_get_r2a_otp()
2242 if (ov8858_lens_info[i].id == otp_r2a->lens_id) in ov8858_get_r2a_otp()
2245 strlcpy(inf->fac.lens, ov8858_lens_info[i].name, in ov8858_get_r2a_otp()
2246 sizeof(inf->fac.lens)); in ov8858_get_r2a_otp()
2248 rg = otp_r2a->rg_ratio; in ov8858_get_r2a_otp()
2249 bg = otp_r2a->bg_ratio; in ov8858_get_r2a_otp()
2251 inf->awb.flag = 1; in ov8858_get_r2a_otp()
2252 inf->awb.r_value = rg; in ov8858_get_r2a_otp()
2253 inf->awb.b_value = bg; in ov8858_get_r2a_otp()
2254 inf->awb.gr_value = 0x200; in ov8858_get_r2a_otp()
2255 inf->awb.gb_value = 0x200; in ov8858_get_r2a_otp()
2257 inf->awb.golden_r_value = 0; in ov8858_get_r2a_otp()
2258 inf->awb.golden_b_value = 0; in ov8858_get_r2a_otp()
2259 inf->awb.golden_gr_value = 0; in ov8858_get_r2a_otp()
2260 inf->awb.golden_gb_value = 0; in ov8858_get_r2a_otp()
2264 if (otp_r2a->flag & 0x20) { in ov8858_get_r2a_otp()
2265 inf->af.flag = 1; in ov8858_get_r2a_otp()
2266 inf->af.dir_cnt = 1; in ov8858_get_r2a_otp()
2267 inf->af.af_otp[0].vcm_start = otp_r2a->vcm_start; in ov8858_get_r2a_otp()
2268 inf->af.af_otp[0].vcm_end = otp_r2a->vcm_end; in ov8858_get_r2a_otp()
2269 inf->af.af_otp[0].vcm_dir = otp_r2a->vcm_dir; in ov8858_get_r2a_otp()
2273 if (otp_r2a->flag & 0x10) { in ov8858_get_r2a_otp()
2274 inf->lsc.flag = 1; in ov8858_get_r2a_otp()
2275 inf->lsc.decimal_bits = 0; in ov8858_get_r2a_otp()
2276 inf->lsc.lsc_w = 8; in ov8858_get_r2a_otp()
2277 inf->lsc.lsc_h = 10; in ov8858_get_r2a_otp()
2281 inf->lsc.lsc_gr[i] = otp_r2a->lenc[j++]; in ov8858_get_r2a_otp()
2282 inf->lsc.lsc_gb[i] = inf->lsc.lsc_gr[i]; in ov8858_get_r2a_otp()
2285 inf->lsc.lsc_b[i] = otp_r2a->lenc[j++]; in ov8858_get_r2a_otp()
2287 inf->lsc.lsc_r[i] = otp_r2a->lenc[j++]; in ov8858_get_r2a_otp()
2294 struct ov8858_otp_info_r1a *otp_r1a = ov8858->otp_r1a; in ov8858_get_module_inf()
2295 struct ov8858_otp_info_r2a *otp_r2a = ov8858->otp_r2a; in ov8858_get_module_inf()
2297 strlcpy(inf->base.sensor, OV8858_NAME, sizeof(inf->base.sensor)); in ov8858_get_module_inf()
2298 strlcpy(inf->base.module, ov8858->module_name, sizeof(inf->base.module)); in ov8858_get_module_inf()
2299 strlcpy(inf->base.lens, ov8858->len_name, sizeof(inf->base.lens)); in ov8858_get_module_inf()
2301 if (ov8858->is_r2a) { in ov8858_get_module_inf()
2313 mutex_lock(&ov8858->mutex); in ov8858_set_awb_cfg()
2314 memcpy(&ov8858->awb_cfg, cfg, sizeof(*cfg)); in ov8858_set_awb_cfg()
2315 mutex_unlock(&ov8858->mutex); in ov8858_set_awb_cfg()
2321 mutex_lock(&ov8858->mutex); in ov8858_set_lsc_cfg()
2322 memcpy(&ov8858->lsc_cfg, cfg, sizeof(*cfg)); in ov8858_set_lsc_cfg()
2323 mutex_unlock(&ov8858->mutex); in ov8858_set_lsc_cfg()
2347 ret = ov8858_write_reg(ov8858->client, in ov8858_ioctl()
2352 ret = ov8858_write_reg(ov8858->client, in ov8858_ioctl()
2358 ret = -ENOTTY; in ov8858_ioctl()
2380 ret = -ENOMEM; in ov8858_compat_ioctl32()
2392 ret = -ENOMEM; in ov8858_compat_ioctl32()
2404 ret = -ENOMEM; in ov8858_compat_ioctl32()
2419 ret = -ENOTTY; in ov8858_compat_ioctl32()
2427 /*--------------------------------------------------------------------------*/
2431 struct i2c_client *client = ov8858->client; in ov8858_apply_otp_r1a()
2432 struct ov8858_otp_info_r1a *otp_ptr = ov8858->otp_r1a; in ov8858_apply_otp_r1a()
2433 struct rkmodule_awb_cfg *awb_cfg = &ov8858->awb_cfg; in ov8858_apply_otp_r1a()
2434 struct rkmodule_lsc_cfg *lsc_cfg = &ov8858->lsc_cfg; in ov8858_apply_otp_r1a()
2440 if (awb_cfg->enable) { in ov8858_apply_otp_r1a()
2441 golden_g_value = (awb_cfg->golden_gb_value + in ov8858_apply_otp_r1a()
2442 awb_cfg->golden_gr_value) / 2; in ov8858_apply_otp_r1a()
2443 golden_bg_ratio = awb_cfg->golden_b_value * 0x200 / golden_g_value; in ov8858_apply_otp_r1a()
2444 golden_rg_ratio = awb_cfg->golden_r_value * 0x200 / golden_g_value; in ov8858_apply_otp_r1a()
2448 if ((otp_ptr->flag & 0x40) && golden_bg_ratio && golden_rg_ratio) { in ov8858_apply_otp_r1a()
2449 if (otp_ptr->light_rg == 0) in ov8858_apply_otp_r1a()
2454 rg = otp_ptr->rg_ratio; in ov8858_apply_otp_r1a()
2456 rg = otp_ptr->rg_ratio * in ov8858_apply_otp_r1a()
2457 (otp_ptr->light_rg + 512) / 1024; in ov8858_apply_otp_r1a()
2459 if (otp_ptr->light_bg == 0) in ov8858_apply_otp_r1a()
2464 bg = otp_ptr->bg_ratio; in ov8858_apply_otp_r1a()
2466 bg = otp_ptr->bg_ratio * in ov8858_apply_otp_r1a()
2467 (otp_ptr->light_bg + 512) / 1024; in ov8858_apply_otp_r1a()
2499 dev_dbg(&client->dev, "apply awb gain: 0x%x, 0x%x, 0x%x\n", in ov8858_apply_otp_r1a()
2504 if ((otp_ptr->flag & 0x10) && lsc_cfg->enable) { in ov8858_apply_otp_r1a()
2508 for (i = 0; i < ARRAY_SIZE(otp_ptr->lenc); i++) { in ov8858_apply_otp_r1a()
2510 otp_ptr->lenc[i]); in ov8858_apply_otp_r1a()
2511 dev_dbg(&client->dev, "apply lenc[%d]: 0x%x\n", in ov8858_apply_otp_r1a()
2512 i, otp_ptr->lenc[i]); in ov8858_apply_otp_r1a()
2522 struct i2c_client *client = ov8858->client; in ov8858_apply_otp_r2a()
2523 struct ov8858_otp_info_r2a *otp_ptr = ov8858->otp_r2a; in ov8858_apply_otp_r2a()
2524 struct rkmodule_awb_cfg *awb_cfg = &ov8858->awb_cfg; in ov8858_apply_otp_r2a()
2525 struct rkmodule_lsc_cfg *lsc_cfg = &ov8858->lsc_cfg; in ov8858_apply_otp_r2a()
2531 if (awb_cfg->enable) { in ov8858_apply_otp_r2a()
2532 golden_g_value = (awb_cfg->golden_gb_value + in ov8858_apply_otp_r2a()
2533 awb_cfg->golden_gr_value) / 2; in ov8858_apply_otp_r2a()
2534 golden_bg_ratio = awb_cfg->golden_b_value * 0x200 / golden_g_value; in ov8858_apply_otp_r2a()
2535 golden_rg_ratio = awb_cfg->golden_r_value * 0x200 / golden_g_value; in ov8858_apply_otp_r2a()
2539 if ((otp_ptr->flag & 0xC0) && golden_bg_ratio && golden_rg_ratio) { in ov8858_apply_otp_r2a()
2540 rg = otp_ptr->rg_ratio; in ov8858_apply_otp_r2a()
2541 bg = otp_ptr->bg_ratio; in ov8858_apply_otp_r2a()
2572 dev_dbg(&client->dev, "apply awb gain: 0x%x, 0x%x, 0x%x\n", in ov8858_apply_otp_r2a()
2577 if ((otp_ptr->flag & 0x10) && lsc_cfg->enable) { in ov8858_apply_otp_r2a()
2581 for (i = 0; i < ARRAY_SIZE(otp_ptr->lenc); i++) { in ov8858_apply_otp_r2a()
2583 otp_ptr->lenc[i]); in ov8858_apply_otp_r2a()
2584 dev_dbg(&client->dev, "apply lenc[%d]: 0x%x\n", in ov8858_apply_otp_r2a()
2585 i, otp_ptr->lenc[i]); in ov8858_apply_otp_r2a()
2596 if (ov8858->is_r2a && ov8858->otp_r2a) in ov8858_apply_otp()
2598 else if (ov8858->otp_r1a) in ov8858_apply_otp()
2608 ret = ov8858_write_array(ov8858->client, ov8858->cur_mode->reg_list); in __ov8858_start_stream()
2613 mutex_unlock(&ov8858->mutex); in __ov8858_start_stream()
2614 ret = v4l2_ctrl_handler_setup(&ov8858->ctrl_handler); in __ov8858_start_stream()
2615 mutex_lock(&ov8858->mutex); in __ov8858_start_stream()
2623 return ov8858_write_reg(ov8858->client, in __ov8858_start_stream()
2631 return ov8858_write_reg(ov8858->client, in __ov8858_stop_stream()
2640 struct i2c_client *client = ov8858->client; in ov8858_s_stream()
2643 dev_info(&client->dev, "%s: on: %d, %dx%d@%d\n", __func__, on, in ov8858_s_stream()
2644 ov8858->cur_mode->width, in ov8858_s_stream()
2645 ov8858->cur_mode->height, in ov8858_s_stream()
2646 DIV_ROUND_CLOSEST(ov8858->cur_mode->max_fps.denominator, in ov8858_s_stream()
2647 ov8858->cur_mode->max_fps.numerator)); in ov8858_s_stream()
2649 mutex_lock(&ov8858->mutex); in ov8858_s_stream()
2651 if (on == ov8858->streaming) in ov8858_s_stream()
2655 ret = pm_runtime_get_sync(&client->dev); in ov8858_s_stream()
2657 pm_runtime_put_noidle(&client->dev); in ov8858_s_stream()
2664 pm_runtime_put(&client->dev); in ov8858_s_stream()
2669 pm_runtime_put(&client->dev); in ov8858_s_stream()
2672 ov8858->streaming = on; in ov8858_s_stream()
2675 mutex_unlock(&ov8858->mutex); in ov8858_s_stream()
2683 struct i2c_client *client = ov8858->client; in ov8858_s_power()
2686 mutex_lock(&ov8858->mutex); in ov8858_s_power()
2688 /* If the power state is not modified - no work to do. */ in ov8858_s_power()
2689 if (ov8858->power_on == !!on) in ov8858_s_power()
2693 ret = pm_runtime_get_sync(&client->dev); in ov8858_s_power()
2695 pm_runtime_put_noidle(&client->dev); in ov8858_s_power()
2699 ret = ov8858_write_array(ov8858->client, ov8858_global_regs); in ov8858_s_power()
2702 pm_runtime_put_noidle(&client->dev); in ov8858_s_power()
2706 ov8858->power_on = true; in ov8858_s_power()
2708 pm_runtime_put(&client->dev); in ov8858_s_power()
2709 ov8858->power_on = false; in ov8858_s_power()
2713 mutex_unlock(&ov8858->mutex); in ov8858_s_power()
2728 struct device *dev = &ov8858->client->dev; in __ov8858_power_on()
2730 if (!IS_ERR(ov8858->power_gpio)) in __ov8858_power_on()
2731 gpiod_set_value_cansleep(ov8858->power_gpio, 1); in __ov8858_power_on()
2735 if (!IS_ERR_OR_NULL(ov8858->pins_default)) { in __ov8858_power_on()
2736 ret = pinctrl_select_state(ov8858->pinctrl, in __ov8858_power_on()
2737 ov8858->pins_default); in __ov8858_power_on()
2742 ret = clk_set_rate(ov8858->xvclk, OV8858_XVCLK_FREQ); in __ov8858_power_on()
2745 if (clk_get_rate(ov8858->xvclk) != OV8858_XVCLK_FREQ) in __ov8858_power_on()
2747 ret = clk_prepare_enable(ov8858->xvclk); in __ov8858_power_on()
2753 if (!IS_ERR(ov8858->reset_gpio)) in __ov8858_power_on()
2754 gpiod_set_value_cansleep(ov8858->reset_gpio, 0); in __ov8858_power_on()
2756 ret = regulator_bulk_enable(OV8858_NUM_SUPPLIES, ov8858->supplies); in __ov8858_power_on()
2762 if (!IS_ERR(ov8858->reset_gpio)) in __ov8858_power_on()
2763 gpiod_set_value_cansleep(ov8858->reset_gpio, 1); in __ov8858_power_on()
2766 if (!IS_ERR(ov8858->pwdn_gpio)) in __ov8858_power_on()
2767 gpiod_set_value_cansleep(ov8858->pwdn_gpio, 1); in __ov8858_power_on()
2776 clk_disable_unprepare(ov8858->xvclk); in __ov8858_power_on()
2784 struct device *dev = &ov8858->client->dev; in __ov8858_power_off()
2786 if (!IS_ERR(ov8858->pwdn_gpio)) in __ov8858_power_off()
2787 gpiod_set_value_cansleep(ov8858->pwdn_gpio, 0); in __ov8858_power_off()
2788 clk_disable_unprepare(ov8858->xvclk); in __ov8858_power_off()
2789 if (!IS_ERR(ov8858->reset_gpio)) in __ov8858_power_off()
2790 gpiod_set_value_cansleep(ov8858->reset_gpio, 0); in __ov8858_power_off()
2791 if (!IS_ERR_OR_NULL(ov8858->pins_sleep)) { in __ov8858_power_off()
2792 ret = pinctrl_select_state(ov8858->pinctrl, in __ov8858_power_off()
2793 ov8858->pins_sleep); in __ov8858_power_off()
2798 //if (!IS_ERR(ov8858->power_gpio)) in __ov8858_power_off()
2799 //gpiod_set_value_cansleep(ov8858->power_gpio, 0); in __ov8858_power_off()
2801 regulator_bulk_disable(OV8858_NUM_SUPPLIES, ov8858->supplies); in __ov8858_power_off()
2829 v4l2_subdev_get_try_format(sd, fh->pad, 0); in ov8858_open()
2832 mutex_lock(&ov8858->mutex); in ov8858_open()
2834 try_fmt->width = def_mode->width; in ov8858_open()
2835 try_fmt->height = def_mode->height; in ov8858_open()
2836 try_fmt->code = OV8858_MEDIA_BUS_FMT; in ov8858_open()
2837 try_fmt->field = V4L2_FIELD_NONE; in ov8858_open()
2839 mutex_unlock(&ov8858->mutex); in ov8858_open()
2852 if (fie->index >= ov8858->cfg_num) in ov8858_enum_frame_interval()
2853 return -EINVAL; in ov8858_enum_frame_interval()
2855 fie->code = OV8858_MEDIA_BUS_FMT; in ov8858_enum_frame_interval()
2856 fie->width = supported_modes[fie->index].width; in ov8858_enum_frame_interval()
2857 fie->height = supported_modes[fie->index].height; in ov8858_enum_frame_interval()
2858 fie->interval = supported_modes[fie->index].max_fps; in ov8858_enum_frame_interval()
2866 struct device *dev = &sensor->client->dev; in ov8858_g_mbus_config()
2870 if (2 == sensor->lane_num) { in ov8858_g_mbus_config()
2871 config->type = V4L2_MBUS_CSI2_DPHY; in ov8858_g_mbus_config()
2872 config->flags = V4L2_MBUS_CSI2_2_LANE | in ov8858_g_mbus_config()
2875 } else if (4 == sensor->lane_num) { in ov8858_g_mbus_config()
2876 config->type = V4L2_MBUS_CSI2_DPHY; in ov8858_g_mbus_config()
2877 config->flags = V4L2_MBUS_CSI2_4_LANE | in ov8858_g_mbus_config()
2881 dev_err(&sensor->client->dev, in ov8858_g_mbus_config()
2882 "unsupported lane_num(%d)\n", sensor->lane_num); in ov8858_g_mbus_config()
2928 struct ov8858 *ov8858 = container_of(ctrl->handler, in ov8858_set_ctrl()
2930 struct i2c_client *client = ov8858->client; in ov8858_set_ctrl()
2935 switch (ctrl->id) { in ov8858_set_ctrl()
2938 max = ov8858->cur_mode->height + ctrl->val - 4; in ov8858_set_ctrl()
2939 __v4l2_ctrl_modify_range(ov8858->exposure, in ov8858_set_ctrl()
2940 ov8858->exposure->minimum, max, in ov8858_set_ctrl()
2941 ov8858->exposure->step, in ov8858_set_ctrl()
2942 ov8858->exposure->default_value); in ov8858_set_ctrl()
2946 if (!pm_runtime_get_if_in_use(&client->dev)) in ov8858_set_ctrl()
2949 switch (ctrl->id) { in ov8858_set_ctrl()
2952 dev_dbg(&client->dev, "set exposure value 0x%x\n", ctrl->val); in ov8858_set_ctrl()
2953 ret = ov8858_write_reg(ov8858->client, in ov8858_set_ctrl()
2956 ctrl->val << 4); in ov8858_set_ctrl()
2959 dev_dbg(&client->dev, "set analog gain value 0x%x\n", ctrl->val); in ov8858_set_ctrl()
2960 ret = ov8858_write_reg(ov8858->client, in ov8858_set_ctrl()
2963 (ctrl->val >> OV8858_GAIN_H_SHIFT) & in ov8858_set_ctrl()
2965 ret |= ov8858_write_reg(ov8858->client, in ov8858_set_ctrl()
2968 ctrl->val & OV8858_GAIN_L_MASK); in ov8858_set_ctrl()
2971 dev_dbg(&client->dev, "set vb value 0x%x\n", ctrl->val); in ov8858_set_ctrl()
2972 ret = ov8858_write_reg(ov8858->client, in ov8858_set_ctrl()
2975 ctrl->val + ov8858->cur_mode->height); in ov8858_set_ctrl()
2978 ret = ov8858_enable_test_pattern(ov8858, ctrl->val); in ov8858_set_ctrl()
2981 dev_warn(&client->dev, "%s Unhandled id:0x%x, val:0x%x\n", in ov8858_set_ctrl()
2982 __func__, ctrl->id, ctrl->val); in ov8858_set_ctrl()
2986 pm_runtime_put(&client->dev); in ov8858_set_ctrl()
3004 handler = &ov8858->ctrl_handler; in ov8858_initialize_controls()
3005 mode = ov8858->cur_mode; in ov8858_initialize_controls()
3009 handler->lock = &ov8858->mutex; in ov8858_initialize_controls()
3014 ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; in ov8858_initialize_controls()
3017 0, ov8858->pixel_rate, 1, ov8858->pixel_rate); in ov8858_initialize_controls()
3019 h_blank = mode->hts_def - mode->width; in ov8858_initialize_controls()
3020 ov8858->hblank = v4l2_ctrl_new_std(handler, NULL, V4L2_CID_HBLANK, in ov8858_initialize_controls()
3022 if (ov8858->hblank) in ov8858_initialize_controls()
3023 ov8858->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY; in ov8858_initialize_controls()
3025 vblank_def = mode->vts_def - mode->height; in ov8858_initialize_controls()
3026 ov8858->vblank = v4l2_ctrl_new_std(handler, &ov8858_ctrl_ops, in ov8858_initialize_controls()
3028 OV8858_VTS_MAX - mode->height, in ov8858_initialize_controls()
3031 exposure_max = mode->vts_def - 4; in ov8858_initialize_controls()
3032 ov8858->exposure = v4l2_ctrl_new_std(handler, &ov8858_ctrl_ops, in ov8858_initialize_controls()
3035 mode->exp_def); in ov8858_initialize_controls()
3037 ov8858->anal_gain = v4l2_ctrl_new_std(handler, &ov8858_ctrl_ops, in ov8858_initialize_controls()
3042 ov8858->test_pattern = v4l2_ctrl_new_std_menu_items(handler, in ov8858_initialize_controls()
3044 ARRAY_SIZE(ov8858_test_pattern_menu) - 1, in ov8858_initialize_controls()
3047 if (handler->error) { in ov8858_initialize_controls()
3048 ret = handler->error; in ov8858_initialize_controls()
3049 dev_err(&ov8858->client->dev, in ov8858_initialize_controls()
3054 ov8858->subdev.ctrl_handler = handler; in ov8858_initialize_controls()
3068 struct device *dev = &ov8858->client->dev; in ov8858_otp_read_r1a()
3069 struct i2c_client *client = ov8858->client; in ov8858_otp_read_r1a()
3073 return -ENOMEM; in ov8858_otp_read_r1a()
3087 otp_ptr->flag = 0x80; /* valid info in OTP */ in ov8858_otp_read_r1a()
3088 ov8858_read_1byte(client, addr, &otp_ptr->module_id); in ov8858_otp_read_r1a()
3089 ov8858_read_1byte(client, addr + 1, &otp_ptr->lens_id); in ov8858_otp_read_r1a()
3090 ov8858_read_1byte(client, addr + 2, &otp_ptr->year); in ov8858_otp_read_r1a()
3091 ov8858_read_1byte(client, addr + 3, &otp_ptr->month); in ov8858_otp_read_r1a()
3092 ov8858_read_1byte(client, addr + 4, &otp_ptr->day); in ov8858_otp_read_r1a()
3094 otp_ptr->module_id, in ov8858_otp_read_r1a()
3095 otp_ptr->lens_id, in ov8858_otp_read_r1a()
3096 otp_ptr->year, in ov8858_otp_read_r1a()
3097 otp_ptr->month, in ov8858_otp_read_r1a()
3098 otp_ptr->day); in ov8858_otp_read_r1a()
3113 otp_ptr->flag |= 0x40; /* valid info and AWB in OTP */ in ov8858_otp_read_r1a()
3115 ov8858_read_1byte(client, addr, &otp_ptr->rg_ratio); in ov8858_otp_read_r1a()
3116 otp_ptr->rg_ratio = (otp_ptr->rg_ratio << 2) + in ov8858_otp_read_r1a()
3118 ov8858_read_1byte(client, addr + 1, &otp_ptr->bg_ratio); in ov8858_otp_read_r1a()
3119 otp_ptr->bg_ratio = (otp_ptr->bg_ratio << 2) + in ov8858_otp_read_r1a()
3121 ov8858_read_1byte(client, addr + 2, &otp_ptr->light_rg); in ov8858_otp_read_r1a()
3122 otp_ptr->light_rg = (otp_ptr->light_rg << 2) + in ov8858_otp_read_r1a()
3124 ov8858_read_1byte(client, addr + 3, &otp_ptr->light_bg); in ov8858_otp_read_r1a()
3125 otp_ptr->light_bg = (otp_ptr->light_bg << 2) + in ov8858_otp_read_r1a()
3128 otp_ptr->rg_ratio, otp_ptr->bg_ratio, in ov8858_otp_read_r1a()
3129 otp_ptr->light_rg, otp_ptr->light_bg); in ov8858_otp_read_r1a()
3143 otp_ptr->flag |= 0x20; in ov8858_otp_read_r1a()
3145 ov8858_read_1byte(client, addr, &otp_ptr->vcm_start); in ov8858_otp_read_r1a()
3146 otp_ptr->vcm_start = (otp_ptr->vcm_start << 2) | in ov8858_otp_read_r1a()
3148 ov8858_read_1byte(client, addr + 1, &otp_ptr->vcm_end); in ov8858_otp_read_r1a()
3149 otp_ptr->vcm_end = (otp_ptr->vcm_end << 2) | in ov8858_otp_read_r1a()
3151 otp_ptr->vcm_dir = (temp >> 2) & 0x03; in ov8858_otp_read_r1a()
3153 otp_ptr->vcm_start, in ov8858_otp_read_r1a()
3154 otp_ptr->vcm_end, in ov8858_otp_read_r1a()
3155 otp_ptr->vcm_dir); in ov8858_otp_read_r1a()
3169 otp_ptr->flag |= 0x10; in ov8858_otp_read_r1a()
3171 ov8858_read_1byte(client, addr + i, &otp_ptr->lenc[i]); in ov8858_otp_read_r1a()
3172 dev_dbg(dev, "lsc 0x%x!\n", otp_ptr->lenc[i]); in ov8858_otp_read_r1a()
3179 if (otp_ptr->flag) { in ov8858_otp_read_r1a()
3180 ov8858->otp_r1a = otp_ptr; in ov8858_otp_read_r1a()
3182 ov8858->otp_r1a = NULL; in ov8858_otp_read_r1a()
3194 struct device *dev = &ov8858->client->dev; in ov8858_otp_read_r2a()
3195 struct i2c_client *client = ov8858->client; in ov8858_otp_read_r2a()
3199 return -ENOMEM; in ov8858_otp_read_r2a()
3212 otp_ptr->flag = 0xC0; /* valid info and AWB in OTP */ in ov8858_otp_read_r2a()
3213 ov8858_read_1byte(client, addr, &otp_ptr->module_id); in ov8858_otp_read_r2a()
3214 ov8858_read_1byte(client, addr + 1, &otp_ptr->lens_id); in ov8858_otp_read_r2a()
3215 ov8858_read_1byte(client, addr + 2, &otp_ptr->year); in ov8858_otp_read_r2a()
3216 ov8858_read_1byte(client, addr + 3, &otp_ptr->month); in ov8858_otp_read_r2a()
3217 ov8858_read_1byte(client, addr + 4, &otp_ptr->day); in ov8858_otp_read_r2a()
3219 ov8858_read_1byte(client, addr + 5, &otp_ptr->rg_ratio); in ov8858_otp_read_r2a()
3220 otp_ptr->rg_ratio = (otp_ptr->rg_ratio << 2) + in ov8858_otp_read_r2a()
3222 ov8858_read_1byte(client, addr + 6, &otp_ptr->bg_ratio); in ov8858_otp_read_r2a()
3223 otp_ptr->bg_ratio = (otp_ptr->bg_ratio << 2) + in ov8858_otp_read_r2a()
3227 otp_ptr->module_id, in ov8858_otp_read_r2a()
3228 otp_ptr->lens_id, in ov8858_otp_read_r2a()
3229 otp_ptr->year, in ov8858_otp_read_r2a()
3230 otp_ptr->month, in ov8858_otp_read_r2a()
3231 otp_ptr->day); in ov8858_otp_read_r2a()
3233 otp_ptr->rg_ratio, in ov8858_otp_read_r2a()
3234 otp_ptr->bg_ratio); in ov8858_otp_read_r2a()
3247 otp_ptr->flag |= 0x20; in ov8858_otp_read_r2a()
3249 ov8858_read_1byte(client, addr, &otp_ptr->vcm_start); in ov8858_otp_read_r2a()
3250 otp_ptr->vcm_start = (otp_ptr->vcm_start << 2) | in ov8858_otp_read_r2a()
3252 ov8858_read_1byte(client, addr + 1, &otp_ptr->vcm_end); in ov8858_otp_read_r2a()
3253 otp_ptr->vcm_end = (otp_ptr->vcm_end << 2) | in ov8858_otp_read_r2a()
3255 otp_ptr->vcm_dir = (temp >> 2) & 0x03; in ov8858_otp_read_r2a()
3270 ov8858_read_1byte(client, addr + i, &otp_ptr->lenc[i]); in ov8858_otp_read_r2a()
3271 checksum += otp_ptr->lenc[i]; in ov8858_otp_read_r2a()
3272 dev_dbg(dev, "lsc_info: 0x%x!\n", otp_ptr->lenc[i]); in ov8858_otp_read_r2a()
3275 ov8858_read_1byte(client, addr + 240, &otp_ptr->checksum); in ov8858_otp_read_r2a()
3276 if (otp_ptr->checksum == checksum) in ov8858_otp_read_r2a()
3277 otp_ptr->flag |= 0x10; in ov8858_otp_read_r2a()
3283 if (otp_ptr->flag) { in ov8858_otp_read_r2a()
3284 ov8858->otp_r2a = otp_ptr; in ov8858_otp_read_r2a()
3286 ov8858->otp_r2a = NULL; in ov8858_otp_read_r2a()
3298 struct i2c_client *client = ov8858->client; in ov8858_otp_read()
3312 if (ov8858->is_r2a) { in ov8858_otp_read()
3322 if (ov8858->is_r2a) in ov8858_otp_read()
3342 struct device *dev = &ov8858->client->dev; in ov8858_check_sensor_id()
3350 return -ENODEV; in ov8858_check_sensor_id()
3357 return -ENODEV; in ov8858_check_sensor_id()
3362 if (4 == ov8858->lane_num) { in ov8858_check_sensor_id()
3364 ov8858->cur_mode = &supported_modes_r2a_4lane[0]; in ov8858_check_sensor_id()
3366 ov8858->cfg_num = ARRAY_SIZE(supported_modes_r2a_4lane); in ov8858_check_sensor_id()
3369 ov8858->cur_mode = &supported_modes_r2a_2lane[0]; in ov8858_check_sensor_id()
3371 ov8858->cfg_num = ARRAY_SIZE(supported_modes_r2a_2lane); in ov8858_check_sensor_id()
3374 ov8858->is_r2a = true; in ov8858_check_sensor_id()
3376 if (4 == ov8858->lane_num) { in ov8858_check_sensor_id()
3378 ov8858->cur_mode = &supported_modes_r1a_4lane[0]; in ov8858_check_sensor_id()
3380 ov8858->cfg_num = ARRAY_SIZE(supported_modes_r1a_4lane); in ov8858_check_sensor_id()
3383 ov8858->cur_mode = &supported_modes_r1a_2lane[0]; in ov8858_check_sensor_id()
3385 ov8858->cfg_num = ARRAY_SIZE(supported_modes_r1a_2lane); in ov8858_check_sensor_id()
3388 ov8858->is_r2a = false; in ov8858_check_sensor_id()
3400 ov8858->supplies[i].supply = ov8858_supply_names[i]; in ov8858_configure_regulators()
3402 return devm_regulator_bulk_get(&ov8858->client->dev, in ov8858_configure_regulators()
3404 ov8858->supplies); in ov8858_configure_regulators()
3409 struct device *dev = &ov8858->client->dev; in ov8858_parse_of()
3414 endpoint = of_graph_get_next_endpoint(dev->of_node, NULL); in ov8858_parse_of()
3417 return -EINVAL; in ov8858_parse_of()
3420 rval = fwnode_property_read_u32_array(fwnode, "data-lanes", NULL, 0); in ov8858_parse_of()
3423 return -1; in ov8858_parse_of()
3426 ov8858->lane_num = rval; in ov8858_parse_of()
3427 if (4 == ov8858->lane_num) { in ov8858_parse_of()
3428 ov8858->cur_mode = &supported_modes_r2a_4lane[0]; in ov8858_parse_of()
3430 ov8858->cfg_num = ARRAY_SIZE(supported_modes_r2a_4lane); in ov8858_parse_of()
3433 ov8858->pixel_rate = MIPI_FREQ * 2U * ov8858->lane_num / 10U; in ov8858_parse_of()
3435 ov8858->lane_num, ov8858->pixel_rate); in ov8858_parse_of()
3437 ov8858->cur_mode = &supported_modes_r2a_2lane[0]; in ov8858_parse_of()
3439 ov8858->cfg_num = ARRAY_SIZE(supported_modes_r2a_2lane); in ov8858_parse_of()
3442 ov8858->pixel_rate = MIPI_FREQ * 2U * (ov8858->lane_num) / 10U; in ov8858_parse_of()
3444 ov8858->lane_num, ov8858->pixel_rate); in ov8858_parse_of()
3452 struct device *dev = &client->dev; in ov8858_probe()
3453 struct device_node *node = dev->of_node; in ov8858_probe()
3466 return -ENOMEM; in ov8858_probe()
3468 ov8858->client = client; in ov8858_probe()
3470 &ov8858->module_index); in ov8858_probe()
3472 &ov8858->module_facing); in ov8858_probe()
3474 &ov8858->module_name); in ov8858_probe()
3476 &ov8858->len_name); in ov8858_probe()
3480 return -EINVAL; in ov8858_probe()
3483 ov8858->xvclk = devm_clk_get(dev, "xvclk"); in ov8858_probe()
3484 if (IS_ERR(ov8858->xvclk)) { in ov8858_probe()
3486 return -EINVAL; in ov8858_probe()
3489 ov8858->power_gpio = devm_gpiod_get(dev, "power", GPIOD_OUT_LOW); in ov8858_probe()
3490 if (IS_ERR(ov8858->power_gpio)) in ov8858_probe()
3491 dev_warn(dev, "Failed to get power-gpios, maybe no use\n"); in ov8858_probe()
3493 ov8858->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); in ov8858_probe()
3494 if (IS_ERR(ov8858->reset_gpio)) in ov8858_probe()
3495 dev_warn(dev, "Failed to get reset-gpios, maybe no use\n"); in ov8858_probe()
3497 ov8858->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_OUT_LOW); in ov8858_probe()
3498 if (IS_ERR(ov8858->pwdn_gpio)) in ov8858_probe()
3499 dev_warn(dev, "Failed to get pwdn-gpios, maybe no use\n"); in ov8858_probe()
3509 return -EINVAL; in ov8858_probe()
3511 ov8858->pinctrl = devm_pinctrl_get(dev); in ov8858_probe()
3512 if (!IS_ERR(ov8858->pinctrl)) { in ov8858_probe()
3513 ov8858->pins_default = in ov8858_probe()
3514 pinctrl_lookup_state(ov8858->pinctrl, in ov8858_probe()
3516 if (IS_ERR(ov8858->pins_default)) in ov8858_probe()
3519 ov8858->pins_sleep = in ov8858_probe()
3520 pinctrl_lookup_state(ov8858->pinctrl, in ov8858_probe()
3522 if (IS_ERR(ov8858->pins_sleep)) in ov8858_probe()
3526 mutex_init(&ov8858->mutex); in ov8858_probe()
3528 sd = &ov8858->subdev; in ov8858_probe()
3545 sd->internal_ops = &ov8858_internal_ops; in ov8858_probe()
3546 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | in ov8858_probe()
3550 ov8858->pad.flags = MEDIA_PAD_FL_SOURCE; in ov8858_probe()
3551 sd->entity.function = MEDIA_ENT_F_CAM_SENSOR; in ov8858_probe()
3552 ret = media_entity_pads_init(&sd->entity, 1, &ov8858->pad); in ov8858_probe()
3558 if (strcmp(ov8858->module_facing, "back") == 0) in ov8858_probe()
3563 snprintf(sd->name, sizeof(sd->name), "m%02d_%s_%s %s", in ov8858_probe()
3564 ov8858->module_index, facing, in ov8858_probe()
3565 OV8858_NAME, dev_name(sd->dev)); in ov8858_probe()
3580 media_entity_cleanup(&sd->entity); in ov8858_probe()
3585 v4l2_ctrl_handler_free(&ov8858->ctrl_handler); in ov8858_probe()
3587 mutex_destroy(&ov8858->mutex); in ov8858_probe()
3599 media_entity_cleanup(&sd->entity); in ov8858_remove()
3601 v4l2_ctrl_handler_free(&ov8858->ctrl_handler); in ov8858_remove()
3602 if (ov8858->otp_r2a) in ov8858_remove()
3603 kfree(ov8858->otp_r2a); in ov8858_remove()
3604 if (ov8858->otp_r1a) in ov8858_remove()
3605 kfree(ov8858->otp_r1a); in ov8858_remove()
3606 mutex_destroy(&ov8858->mutex); in ov8858_remove()
3608 pm_runtime_disable(&client->dev); in ov8858_remove()
3609 if (!pm_runtime_status_suspended(&client->dev)) in ov8858_remove()
3611 pm_runtime_set_suspended(&client->dev); in ov8858_remove()