Lines Matching +full:fw +full:- +full:gpios

1 // SPDX-License-Identifier: GPL-2.0-only
24 #include <media/media-entity.h>
25 #include <media/v4l2-ctrls.h>
26 #include <media/v4l2-device.h>
27 #include <media/v4l2-subdev.h>
28 #include <media/v4l2-mediabus.h>
29 #include <media/v4l2-fwnode.h>
38 #define S5K5BAF_FW_FILENAME "s5k5baf-cfg.bin"
50 /* Default number of MIPI CSI-2 data lanes used */
199 /* Auto-algorithms enable mask */
281 struct gpio_desc *gpios[NUM_GPIOS]; member
289 struct s5k5baf_fw *fw; member
325 /* range 16-240 */
345 static int s5k5baf_fw_parse(struct device *dev, struct s5k5baf_fw **fw, in s5k5baf_fw_parse() argument
354 return -EINVAL; in s5k5baf_fw_parse()
360 return -EINVAL; in s5k5baf_fw_parse()
364 count -= S5K5BAG_FW_TAG_LEN; in s5k5baf_fw_parse()
368 return -ENOMEM; in s5k5baf_fw_parse()
374 if (count < 1 + 2 * f->count) { in s5k5baf_fw_parse()
376 f->count, 2 * (count + S5K5BAG_FW_TAG_LEN)); in s5k5baf_fw_parse()
377 return -EINVAL; in s5k5baf_fw_parse()
380 d += 1 + 2 * f->count; in s5k5baf_fw_parse()
382 for (i = 0; i < f->count; ++i) { in s5k5baf_fw_parse()
383 if (f->seq[i].offset + d <= end) in s5k5baf_fw_parse()
386 return -EINVAL; in s5k5baf_fw_parse()
389 *fw = f; in s5k5baf_fw_parse()
396 return &container_of(ctrl->handler, struct s5k5baf, ctrls.handler)->sd; in ctrl_to_sd()
401 return sd->entity.function == MEDIA_ENT_F_CAM_SENSOR; in s5k5baf_is_cis_subdev()
414 struct i2c_client *c = v4l2_get_subdevdata(&state->sd); in s5k5baf_i2c_read()
418 { .addr = c->addr, .flags = 0, in s5k5baf_i2c_read()
420 { .addr = c->addr, .flags = I2C_M_RD, in s5k5baf_i2c_read()
425 if (state->error) in s5k5baf_i2c_read()
429 ret = i2c_transfer(c->adapter, msg, 2); in s5k5baf_i2c_read()
436 state->error = ret; in s5k5baf_i2c_read()
444 struct i2c_client *c = v4l2_get_subdevdata(&state->sd); in s5k5baf_i2c_write()
447 if (state->error) in s5k5baf_i2c_write()
455 state->error = ret; in s5k5baf_i2c_write()
474 struct i2c_client *c = v4l2_get_subdevdata(&state->sd); in s5k5baf_write_arr_seq()
478 if (state->error) in s5k5baf_write_arr_seq()
487 int n = min_t(int, count, ARRAY_SIZE(buf) - 1); in s5k5baf_write_arr_seq()
497 state->error = ret; in s5k5baf_write_arr_seq()
501 count -= n; in s5k5baf_write_arr_seq()
513 * s5k5baf_write_nseq() - Writes sequences of values to sensor memory via i2c
515 * (N, address, value[1]...value[N-1])*,0
526 --count; in s5k5baf_write_nseq()
541 if (state->error || !reg) in s5k5baf_synchronize()
546 v4l2_err(&state->sd, "timeout on register synchronize (%#x)\n", addr); in s5k5baf_synchronize()
547 state->error = -ETIMEDOUT; in s5k5baf_synchronize()
552 struct s5k5baf_fw *fw = state->fw; in s5k5baf_fw_get_seq() local
556 if (fw == NULL) in s5k5baf_fw_get_seq()
559 data = &fw->seq[0].id + 2 * fw->count; in s5k5baf_fw_get_seq()
561 for (i = 0; i < fw->count; ++i) { in s5k5baf_fw_get_seq()
562 if (fw->seq[i].id == seq_id) in s5k5baf_fw_get_seq()
563 return data + fw->seq[i].offset; in s5k5baf_fw_get_seq()
579 unsigned long mclk = state->mclk_frequency / 1000; in s5k5baf_hw_set_clocks()
595 if (!state->error && status) { in s5k5baf_hw_set_clocks()
596 v4l2_err(&state->sd, "error configuring PLL (%d)\n", status); in s5k5baf_hw_set_clocks()
597 state->error = -EINVAL; in s5k5baf_hw_set_clocks()
626 if (state->apply_crop) { in s5k5baf_hw_sync_cfg()
635 u16 flip = state->ctrls.vflip->val | (state->ctrls.vflip->val << 1); in s5k5baf_hw_set_mirror()
638 if (state->streaming) in s5k5baf_hw_set_mirror()
646 if (!state->valid_auto_alg) in s5k5baf_hw_set_alg()
649 cur_alg = state->auto_alg; in s5k5baf_hw_set_alg()
656 if (state->error) in s5k5baf_hw_set_alg()
659 state->valid_auto_alg = 1; in s5k5baf_hw_set_alg()
660 state->auto_alg = new_alg; in s5k5baf_hw_set_alg()
666 struct s5k5baf_ctrls *ctrls = &state->ctrls; in s5k5baf_hw_set_awb()
670 ctrls->gain_red->val, 1, in s5k5baf_hw_set_awb()
672 ctrls->gain_blue->val, 1, in s5k5baf_hw_set_awb()
678 /* Program FW with exposure time, 'exposure' in us units */
698 unsigned int exp_time = state->ctrls.exposure->val; in s5k5baf_hw_set_auto_exposure()
701 s5k5baf_hw_set_user_gain(state, state->ctrls.gain->val); in s5k5baf_hw_set_auto_exposure()
734 int i, c = -1; in s5k5baf_find_pixfmt()
737 if (mf->colorspace != s5k5baf_formats[i].colorspace) in s5k5baf_find_pixfmt()
739 if (mf->code == s5k5baf_formats[i].code) in s5k5baf_find_pixfmt()
749 int ret = state->error; in s5k5baf_clear_error()
751 state->error = 0; in s5k5baf_clear_error()
759 if (state->bus_type == V4L2_MBUS_CSI2_DPHY) in s5k5baf_hw_set_video_bus()
765 state->nlanes, en_pkts, 1); in s5k5baf_hw_set_video_bus()
790 if (state->error) in s5k5baf_hw_find_min_fiv()
793 for (n = 5; n > 0; --n) { in s5k5baf_hw_find_min_fiv()
796 if (state->error) in s5k5baf_hw_find_min_fiv()
803 state->fiv = fiv; in s5k5baf_hw_find_min_fiv()
804 v4l2_info(&state->sd, in s5k5baf_hw_find_min_fiv()
808 v4l2_err(&state->sd, in s5k5baf_hw_find_min_fiv()
810 state->error = -EINVAL; in s5k5baf_hw_find_min_fiv()
813 v4l2_err(&state->sd, "cannot find correct frame interval\n"); in s5k5baf_hw_find_min_fiv()
814 state->error = -ERANGE; in s5k5baf_hw_find_min_fiv()
822 if (state->error) in s5k5baf_hw_validate_cfg()
827 state->apply_cfg = 1; in s5k5baf_hw_validate_cfg()
831 if (!state->error) in s5k5baf_hw_validate_cfg()
832 state->apply_cfg = 1; in s5k5baf_hw_validate_cfg()
835 v4l2_err(&state->sd, in s5k5baf_hw_validate_cfg()
837 state->error = -EINVAL; in s5k5baf_hw_validate_cfg()
845 r->left = v->left * n->width / d->width; in s5k5baf_rescale()
846 r->top = v->top * n->height / d->height; in s5k5baf_rescale()
847 r->width = v->width * n->width / d->width; in s5k5baf_rescale()
848 r->height = v->height * n->height / d->height; in s5k5baf_rescale()
857 p = &state->crop_sink; in s5k5baf_hw_set_crop_rects()
858 s5k5baf_write_seq(state, REG_G_PREVREQ_IN_WIDTH, p->width, p->height, in s5k5baf_hw_set_crop_rects()
859 p->left, p->top); in s5k5baf_hw_set_crop_rects()
861 s5k5baf_rescale(&r, &state->crop_source, &state->crop_sink, in s5k5baf_hw_set_crop_rects()
862 &state->compose); in s5k5baf_hw_set_crop_rects()
884 v4l2_err(&state->sd, in s5k5baf_hw_set_crop_rects()
886 state->error = -EINVAL; in s5k5baf_hw_set_crop_rects()
888 s5k5baf_hw_set_fiv(state, state->req_fiv); in s5k5baf_hw_set_crop_rects()
892 v4l2_err(&state->sd, "crop error: %d\n", err); in s5k5baf_hw_set_crop_rects()
893 return -EINVAL; in s5k5baf_hw_set_crop_rects()
896 if (!state->apply_cfg) in s5k5baf_hw_set_crop_rects()
899 p = &state->crop_source; in s5k5baf_hw_set_crop_rects()
900 s5k5baf_write_seq(state, REG_P_OUT_WIDTH(0), p->width, p->height); in s5k5baf_hw_set_crop_rects()
901 s5k5baf_hw_set_fiv(state, state->req_fiv); in s5k5baf_hw_set_crop_rects()
909 u16 reg_fmt = s5k5baf_formats[state->pixfmt].reg_p_fmt; in s5k5baf_hw_set_config()
910 struct v4l2_rect *r = &state->crop_source; in s5k5baf_hw_set_config()
913 r->width, r->height, reg_fmt, in s5k5baf_hw_set_config()
917 state->req_fiv, S5K5BAF_MIN_FR_TIME); in s5k5baf_hw_set_config()
933 gpiod_set_value_cansleep(state->gpios[id], 1); in s5k5baf_gpio_assert()
938 gpiod_set_value_cansleep(state->gpios[id], 0); in s5k5baf_gpio_deassert()
945 ret = regulator_bulk_enable(S5K5BAF_NUM_SUPPLIES, state->supplies); in s5k5baf_power_on()
949 ret = clk_set_rate(state->clock, state->mclk_frequency); in s5k5baf_power_on()
953 ret = clk_prepare_enable(state->clock); in s5k5baf_power_on()
957 v4l2_dbg(1, debug, &state->sd, "clock frequency: %ld\n", in s5k5baf_power_on()
958 clk_get_rate(state->clock)); in s5k5baf_power_on()
966 regulator_bulk_disable(S5K5BAF_NUM_SUPPLIES, state->supplies); in s5k5baf_power_on()
968 v4l2_err(&state->sd, "%s() failed (%d)\n", __func__, ret); in s5k5baf_power_on()
976 state->streaming = 0; in s5k5baf_power_off()
977 state->apply_cfg = 0; in s5k5baf_power_off()
978 state->apply_crop = 0; in s5k5baf_power_off()
983 if (!IS_ERR(state->clock)) in s5k5baf_power_off()
984 clk_disable_unprepare(state->clock); in s5k5baf_power_off()
987 state->supplies); in s5k5baf_power_off()
989 v4l2_err(&state->sd, "failed to disable regulators\n"); in s5k5baf_power_off()
1009 state->pixfmt = 0; in s5k5baf_initialize_data()
1010 state->req_fiv = 10000 / 15; in s5k5baf_initialize_data()
1011 state->fiv = state->req_fiv; in s5k5baf_initialize_data()
1012 state->valid_auto_alg = 0; in s5k5baf_initialize_data()
1017 struct i2c_client *c = v4l2_get_subdevdata(&state->sd); in s5k5baf_load_setfile()
1018 const struct firmware *fw; in s5k5baf_load_setfile() local
1021 ret = request_firmware(&fw, S5K5BAF_FW_FILENAME, &c->dev); in s5k5baf_load_setfile()
1023 dev_warn(&c->dev, "firmware file (%s) not loaded\n", in s5k5baf_load_setfile()
1028 ret = s5k5baf_fw_parse(&c->dev, &state->fw, fw->size / 2, in s5k5baf_load_setfile()
1029 (__le16 *)fw->data); in s5k5baf_load_setfile()
1031 release_firmware(fw); in s5k5baf_load_setfile()
1041 mutex_lock(&state->lock); in s5k5baf_set_power()
1043 if (state->power != !on) in s5k5baf_set_power()
1047 if (state->fw == NULL) in s5k5baf_set_power()
1069 state->power++; in s5k5baf_set_power()
1072 state->power--; in s5k5baf_set_power()
1076 mutex_unlock(&state->lock); in s5k5baf_set_power()
1079 ret = v4l2_ctrl_handler_setup(&state->ctrls.handler); in s5k5baf_set_power()
1094 mutex_lock(&state->lock); in s5k5baf_s_stream()
1096 if (state->streaming == !!on) { in s5k5baf_s_stream()
1113 state->streaming = !state->streaming; in s5k5baf_s_stream()
1116 mutex_unlock(&state->lock); in s5k5baf_s_stream()
1126 mutex_lock(&state->lock); in s5k5baf_g_frame_interval()
1127 fi->interval.numerator = state->fiv; in s5k5baf_g_frame_interval()
1128 fi->interval.denominator = 10000; in s5k5baf_g_frame_interval()
1129 mutex_unlock(&state->lock); in s5k5baf_g_frame_interval()
1137 struct v4l2_fract *i = &fi->interval; in s5k5baf_set_frame_interval()
1139 if (fi->interval.denominator == 0) in s5k5baf_set_frame_interval()
1140 state->req_fiv = S5K5BAF_MAX_FR_TIME; in s5k5baf_set_frame_interval()
1142 state->req_fiv = clamp_t(u32, in s5k5baf_set_frame_interval()
1143 i->numerator * 10000 / i->denominator, in s5k5baf_set_frame_interval()
1147 state->fiv = state->req_fiv; in s5k5baf_set_frame_interval()
1148 if (state->apply_cfg) { in s5k5baf_set_frame_interval()
1149 s5k5baf_hw_set_fiv(state, state->req_fiv); in s5k5baf_set_frame_interval()
1152 *i = (struct v4l2_fract){ state->fiv, 10000 }; in s5k5baf_set_frame_interval()
1153 if (state->fiv == state->req_fiv) in s5k5baf_set_frame_interval()
1154 v4l2_info(&state->sd, "frame interval changed to %d00us\n", in s5k5baf_set_frame_interval()
1155 state->fiv); in s5k5baf_set_frame_interval()
1163 mutex_lock(&state->lock); in s5k5baf_s_frame_interval()
1165 mutex_unlock(&state->lock); in s5k5baf_s_frame_interval()
1176 if (fie->index > S5K5BAF_MAX_FR_TIME - S5K5BAF_MIN_FR_TIME || in s5k5baf_enum_frame_interval()
1177 fie->pad != PAD_CIS) in s5k5baf_enum_frame_interval()
1178 return -EINVAL; in s5k5baf_enum_frame_interval()
1180 v4l_bound_align_image(&fie->width, S5K5BAF_WIN_WIDTH_MIN, in s5k5baf_enum_frame_interval()
1182 &fie->height, S5K5BAF_WIN_HEIGHT_MIN, in s5k5baf_enum_frame_interval()
1185 fie->interval.numerator = S5K5BAF_MIN_FR_TIME + fie->index; in s5k5baf_enum_frame_interval()
1186 fie->interval.denominator = 10000; in s5k5baf_enum_frame_interval()
1195 if (code->pad == PAD_CIS) { in s5k5baf_enum_mbus_code()
1196 if (code->index > 0) in s5k5baf_enum_mbus_code()
1197 return -EINVAL; in s5k5baf_enum_mbus_code()
1198 code->code = MEDIA_BUS_FMT_FIXED; in s5k5baf_enum_mbus_code()
1202 if (code->index >= ARRAY_SIZE(s5k5baf_formats)) in s5k5baf_enum_mbus_code()
1203 return -EINVAL; in s5k5baf_enum_mbus_code()
1205 code->code = s5k5baf_formats[code->index].code; in s5k5baf_enum_mbus_code()
1215 if (fse->index > 0) in s5k5baf_enum_frame_size()
1216 return -EINVAL; in s5k5baf_enum_frame_size()
1218 if (fse->pad == PAD_CIS) { in s5k5baf_enum_frame_size()
1219 fse->code = MEDIA_BUS_FMT_FIXED; in s5k5baf_enum_frame_size()
1220 fse->min_width = S5K5BAF_CIS_WIDTH; in s5k5baf_enum_frame_size()
1221 fse->max_width = S5K5BAF_CIS_WIDTH; in s5k5baf_enum_frame_size()
1222 fse->min_height = S5K5BAF_CIS_HEIGHT; in s5k5baf_enum_frame_size()
1223 fse->max_height = S5K5BAF_CIS_HEIGHT; in s5k5baf_enum_frame_size()
1228 while (--i) in s5k5baf_enum_frame_size()
1229 if (fse->code == s5k5baf_formats[i].code) in s5k5baf_enum_frame_size()
1231 fse->code = s5k5baf_formats[i].code; in s5k5baf_enum_frame_size()
1232 fse->min_width = S5K5BAF_WIN_WIDTH_MIN; in s5k5baf_enum_frame_size()
1233 fse->max_width = S5K5BAF_CIS_WIDTH; in s5k5baf_enum_frame_size()
1234 fse->max_height = S5K5BAF_WIN_HEIGHT_MIN; in s5k5baf_enum_frame_size()
1235 fse->min_height = S5K5BAF_CIS_HEIGHT; in s5k5baf_enum_frame_size()
1242 mf->width = S5K5BAF_CIS_WIDTH; in s5k5baf_try_cis_format()
1243 mf->height = S5K5BAF_CIS_HEIGHT; in s5k5baf_try_cis_format()
1244 mf->code = MEDIA_BUS_FMT_FIXED; in s5k5baf_try_cis_format()
1245 mf->colorspace = V4L2_COLORSPACE_JPEG; in s5k5baf_try_cis_format()
1246 mf->field = V4L2_FIELD_NONE; in s5k5baf_try_cis_format()
1253 v4l_bound_align_image(&mf->width, S5K5BAF_WIN_WIDTH_MIN, in s5k5baf_try_isp_format()
1255 &mf->height, S5K5BAF_WIN_HEIGHT_MIN, in s5k5baf_try_isp_format()
1260 mf->colorspace = s5k5baf_formats[pixfmt].colorspace; in s5k5baf_try_isp_format()
1261 mf->code = s5k5baf_formats[pixfmt].code; in s5k5baf_try_isp_format()
1262 mf->field = V4L2_FIELD_NONE; in s5k5baf_try_isp_format()
1275 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { in s5k5baf_get_fmt()
1276 mf = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad); in s5k5baf_get_fmt()
1277 fmt->format = *mf; in s5k5baf_get_fmt()
1281 mf = &fmt->format; in s5k5baf_get_fmt()
1282 if (fmt->pad == PAD_CIS) { in s5k5baf_get_fmt()
1286 mf->field = V4L2_FIELD_NONE; in s5k5baf_get_fmt()
1287 mutex_lock(&state->lock); in s5k5baf_get_fmt()
1288 pixfmt = &s5k5baf_formats[state->pixfmt]; in s5k5baf_get_fmt()
1289 mf->width = state->crop_source.width; in s5k5baf_get_fmt()
1290 mf->height = state->crop_source.height; in s5k5baf_get_fmt()
1291 mf->code = pixfmt->code; in s5k5baf_get_fmt()
1292 mf->colorspace = pixfmt->colorspace; in s5k5baf_get_fmt()
1293 mutex_unlock(&state->lock); in s5k5baf_get_fmt()
1302 struct v4l2_mbus_framefmt *mf = &fmt->format; in s5k5baf_set_fmt()
1307 mf->field = V4L2_FIELD_NONE; in s5k5baf_set_fmt()
1309 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { in s5k5baf_set_fmt()
1310 *v4l2_subdev_get_try_format(sd, sd_state, fmt->pad) = *mf; in s5k5baf_set_fmt()
1314 if (fmt->pad == PAD_CIS) { in s5k5baf_set_fmt()
1319 mutex_lock(&state->lock); in s5k5baf_set_fmt()
1321 if (state->streaming) { in s5k5baf_set_fmt()
1322 mutex_unlock(&state->lock); in s5k5baf_set_fmt()
1323 return -EBUSY; in s5k5baf_set_fmt()
1326 state->pixfmt = s5k5baf_try_isp_format(mf); in s5k5baf_set_fmt()
1327 pixfmt = &s5k5baf_formats[state->pixfmt]; in s5k5baf_set_fmt()
1328 mf->code = pixfmt->code; in s5k5baf_set_fmt()
1329 mf->colorspace = pixfmt->colorspace; in s5k5baf_set_fmt()
1330 mf->width = state->crop_source.width; in s5k5baf_set_fmt()
1331 mf->height = state->crop_source.height; in s5k5baf_set_fmt()
1333 mutex_unlock(&state->lock); in s5k5baf_set_fmt()
1368 rtype = s5k5baf_get_sel_rect(sel->pad, sel->target); in s5k5baf_get_selection()
1372 return -EINVAL; in s5k5baf_get_selection()
1374 sel->r = s5k5baf_cis_rect; in s5k5baf_get_selection()
1380 if (sel->which == V4L2_SUBDEV_FORMAT_TRY) { in s5k5baf_get_selection()
1382 sel->r = *v4l2_subdev_get_try_compose(sd, sd_state, in s5k5baf_get_selection()
1383 sel->pad); in s5k5baf_get_selection()
1385 sel->r = *v4l2_subdev_get_try_crop(sd, sd_state, in s5k5baf_get_selection()
1386 sel->pad); in s5k5baf_get_selection()
1390 mutex_lock(&state->lock); in s5k5baf_get_selection()
1393 sel->r = state->crop_sink; in s5k5baf_get_selection()
1396 sel->r = state->compose; in s5k5baf_get_selection()
1399 sel->r = state->crop_source; in s5k5baf_get_selection()
1404 if (s5k5baf_is_bound_target(sel->target)) { in s5k5baf_get_selection()
1405 sel->r.left = 0; in s5k5baf_get_selection()
1406 sel->r.top = 0; in s5k5baf_get_selection()
1408 mutex_unlock(&state->lock); in s5k5baf_get_selection()
1419 *start = max - *len; in s5k5baf_bound_range()
1428 s5k5baf_bound_range(&r->left, &r->width, width); in s5k5baf_bound_rect()
1429 s5k5baf_bound_range(&r->top, &r->height, height); in s5k5baf_bound_rect()
1442 br = rects[i - 1]; in s5k5baf_set_rect_and_adjust()
1443 s5k5baf_bound_rect(r, br->width, br->height); in s5k5baf_set_rect_and_adjust()
1463 rtype = s5k5baf_get_sel_rect(sel->pad, sel->target); in s5k5baf_set_selection()
1464 if (rtype == R_INVALID || s5k5baf_is_bound_target(sel->target)) in s5k5baf_set_selection()
1465 return -EINVAL; in s5k5baf_set_selection()
1469 sel->r.left = 0; in s5k5baf_set_selection()
1470 sel->r.top = 0; in s5k5baf_set_selection()
1473 if (sel->which == V4L2_SUBDEV_FORMAT_TRY) { in s5k5baf_set_selection()
1483 s5k5baf_set_rect_and_adjust(rects, rtype, &sel->r); in s5k5baf_set_selection()
1489 &state->crop_sink, in s5k5baf_set_selection()
1490 &state->compose, in s5k5baf_set_selection()
1491 &state->crop_source in s5k5baf_set_selection()
1493 mutex_lock(&state->lock); in s5k5baf_set_selection()
1494 if (state->streaming) { in s5k5baf_set_selection()
1495 /* adjust sel->r to avoid output resolution change */ in s5k5baf_set_selection()
1497 if (sel->r.width < state->crop_source.width) in s5k5baf_set_selection()
1498 sel->r.width = state->crop_source.width; in s5k5baf_set_selection()
1499 if (sel->r.height < state->crop_source.height) in s5k5baf_set_selection()
1500 sel->r.height = state->crop_source.height; in s5k5baf_set_selection()
1502 sel->r.width = state->crop_source.width; in s5k5baf_set_selection()
1503 sel->r.height = state->crop_source.height; in s5k5baf_set_selection()
1506 s5k5baf_set_rect_and_adjust(rects, rtype, &sel->r); in s5k5baf_set_selection()
1507 if (!s5k5baf_cmp_rect(&state->crop_sink, &s5k5baf_cis_rect) || in s5k5baf_set_selection()
1508 !s5k5baf_cmp_rect(&state->compose, &s5k5baf_cis_rect)) in s5k5baf_set_selection()
1509 state->apply_crop = 1; in s5k5baf_set_selection()
1510 if (state->streaming) in s5k5baf_set_selection()
1512 mutex_unlock(&state->lock); in s5k5baf_set_selection()
1550 v4l2_dbg(1, debug, sd, "ctrl: %s, value: %d\n", ctrl->name, ctrl->val); in s5k5baf_s_ctrl()
1552 mutex_lock(&state->lock); in s5k5baf_s_ctrl()
1554 if (state->power == 0) in s5k5baf_s_ctrl()
1557 switch (ctrl->id) { in s5k5baf_s_ctrl()
1559 s5k5baf_hw_set_awb(state, ctrl->val); in s5k5baf_s_ctrl()
1563 s5k5baf_write(state, REG_USER_BRIGHTNESS, ctrl->val); in s5k5baf_s_ctrl()
1567 s5k5baf_hw_set_colorfx(state, ctrl->val); in s5k5baf_s_ctrl()
1571 s5k5baf_write(state, REG_USER_CONTRAST, ctrl->val); in s5k5baf_s_ctrl()
1575 s5k5baf_hw_set_auto_exposure(state, ctrl->val); in s5k5baf_s_ctrl()
1583 s5k5baf_hw_set_anti_flicker(state, ctrl->val); in s5k5baf_s_ctrl()
1587 s5k5baf_write(state, REG_USER_SATURATION, ctrl->val); in s5k5baf_s_ctrl()
1591 s5k5baf_write(state, REG_USER_SHARPBLUR, ctrl->val); in s5k5baf_s_ctrl()
1595 s5k5baf_write(state, REG_P_COLORTEMP(0), ctrl->val); in s5k5baf_s_ctrl()
1596 if (state->apply_cfg) in s5k5baf_s_ctrl()
1601 s5k5baf_hw_set_test_pattern(state, ctrl->val); in s5k5baf_s_ctrl()
1606 mutex_unlock(&state->lock); in s5k5baf_s_ctrl()
1627 struct s5k5baf_ctrls *ctrls = &state->ctrls; in s5k5baf_initialize_ctrls()
1628 struct v4l2_ctrl_handler *hdl = &ctrls->handler; in s5k5baf_initialize_ctrls()
1633 v4l2_err(&state->sd, "cannot init ctrl handler (%d)\n", ret); in s5k5baf_initialize_ctrls()
1638 ctrls->awb = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_AUTO_WHITE_BALANCE, in s5k5baf_initialize_ctrls()
1640 ctrls->gain_red = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_RED_BALANCE, in s5k5baf_initialize_ctrls()
1642 ctrls->gain_blue = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_BLUE_BALANCE, in s5k5baf_initialize_ctrls()
1644 v4l2_ctrl_auto_cluster(3, &ctrls->awb, 0, false); in s5k5baf_initialize_ctrls()
1646 ctrls->hflip = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_HFLIP, 0, 1, 1, 0); in s5k5baf_initialize_ctrls()
1647 ctrls->vflip = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_VFLIP, 0, 1, 1, 0); in s5k5baf_initialize_ctrls()
1648 v4l2_ctrl_cluster(2, &ctrls->hflip); in s5k5baf_initialize_ctrls()
1650 ctrls->auto_exp = v4l2_ctrl_new_std_menu(hdl, ops, in s5k5baf_initialize_ctrls()
1654 ctrls->exposure = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_EXPOSURE, in s5k5baf_initialize_ctrls()
1657 ctrls->gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_GAIN, in s5k5baf_initialize_ctrls()
1659 v4l2_ctrl_auto_cluster(3, &ctrls->auto_exp, 0, false); in s5k5baf_initialize_ctrls()
1671 v4l2_ctrl_new_std(hdl, ops, V4L2_CID_SATURATION, -127, 127, 1, 0); in s5k5baf_initialize_ctrls()
1672 v4l2_ctrl_new_std(hdl, ops, V4L2_CID_BRIGHTNESS, -127, 127, 1, 0); in s5k5baf_initialize_ctrls()
1673 v4l2_ctrl_new_std(hdl, ops, V4L2_CID_CONTRAST, -127, 127, 1, 0); in s5k5baf_initialize_ctrls()
1674 v4l2_ctrl_new_std(hdl, ops, V4L2_CID_SHARPNESS, -127, 127, 1, 0); in s5k5baf_initialize_ctrls()
1677 ARRAY_SIZE(s5k5baf_test_pattern_menu) - 1, in s5k5baf_initialize_ctrls()
1680 if (hdl->error) { in s5k5baf_initialize_ctrls()
1681 v4l2_err(&state->sd, "error creating controls (%d)\n", in s5k5baf_initialize_ctrls()
1682 hdl->error); in s5k5baf_initialize_ctrls()
1683 ret = hdl->error; in s5k5baf_initialize_ctrls()
1688 state->sd.ctrl_handler = hdl; in s5k5baf_initialize_ctrls()
1699 mf = v4l2_subdev_get_try_format(sd, fh->state, PAD_CIS); in s5k5baf_open()
1705 mf = v4l2_subdev_get_try_format(sd, fh->state, PAD_OUT); in s5k5baf_open()
1706 mf->colorspace = s5k5baf_formats[0].colorspace; in s5k5baf_open()
1707 mf->code = s5k5baf_formats[0].code; in s5k5baf_open()
1708 mf->width = s5k5baf_cis_rect.width; in s5k5baf_open()
1709 mf->height = s5k5baf_cis_rect.height; in s5k5baf_open()
1710 mf->field = V4L2_FIELD_NONE; in s5k5baf_open()
1712 *v4l2_subdev_get_try_crop(sd, fh->state, PAD_CIS) = s5k5baf_cis_rect; in s5k5baf_open()
1713 *v4l2_subdev_get_try_compose(sd, fh->state, PAD_CIS) = s5k5baf_cis_rect; in s5k5baf_open()
1714 *v4l2_subdev_get_try_crop(sd, fh->state, PAD_OUT) = s5k5baf_cis_rect; in s5k5baf_open()
1731 v4l2_info(&state->sd, "FW API=%#x, revision=%#x sensor_id=%#x\n", in s5k5baf_check_fw_revision()
1735 v4l2_err(&state->sd, "FW API version not supported\n"); in s5k5baf_check_fw_revision()
1736 return -ENODEV; in s5k5baf_check_fw_revision()
1747 ret = v4l2_device_register_subdev(sd->v4l2_dev, &state->cis_sd); in s5k5baf_registered()
1750 state->cis_sd.name); in s5k5baf_registered()
1752 ret = media_create_pad_link(&state->cis_sd.entity, PAD_CIS, in s5k5baf_registered()
1753 &state->sd.entity, PAD_CIS, in s5k5baf_registered()
1762 v4l2_device_unregister_subdev(&state->cis_sd); in s5k5baf_unregistered()
1794 struct i2c_client *c = v4l2_get_subdevdata(&state->sd); in s5k5baf_configure_gpios()
1799 gpio = devm_gpiod_get(&c->dev, name[i], GPIOD_OUT_HIGH); in s5k5baf_configure_gpios()
1814 state->gpios[i] = gpio; in s5k5baf_configure_gpios()
1821 struct device_node *node = dev->of_node; in s5k5baf_parse_device_node()
1827 dev_err(dev, "no device-tree node provided\n"); in s5k5baf_parse_device_node()
1828 return -EINVAL; in s5k5baf_parse_device_node()
1831 ret = of_property_read_u32(node, "clock-frequency", in s5k5baf_parse_device_node()
1832 &state->mclk_frequency); in s5k5baf_parse_device_node()
1834 state->mclk_frequency = S5K5BAF_DEFAULT_MCLK_FREQ; in s5k5baf_parse_device_node()
1836 state->mclk_frequency); in s5k5baf_parse_device_node()
1842 return -EINVAL; in s5k5baf_parse_device_node()
1850 state->bus_type = ep.bus_type; in s5k5baf_parse_device_node()
1852 switch (state->bus_type) { in s5k5baf_parse_device_node()
1854 state->nlanes = ep.bus.mipi_csi2.num_data_lanes; in s5k5baf_parse_device_node()
1861 return -EINVAL; in s5k5baf_parse_device_node()
1873 sd = &state->cis_sd; in s5k5baf_configure_subdevs()
1875 sd->owner = THIS_MODULE; in s5k5baf_configure_subdevs()
1877 snprintf(sd->name, sizeof(sd->name), "S5K5BAF-CIS %d-%04x", in s5k5baf_configure_subdevs()
1878 i2c_adapter_id(c->adapter), c->addr); in s5k5baf_configure_subdevs()
1880 sd->internal_ops = &s5k5baf_cis_subdev_internal_ops; in s5k5baf_configure_subdevs()
1881 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; in s5k5baf_configure_subdevs()
1883 state->cis_pad.flags = MEDIA_PAD_FL_SOURCE; in s5k5baf_configure_subdevs()
1884 sd->entity.function = MEDIA_ENT_F_CAM_SENSOR; in s5k5baf_configure_subdevs()
1885 ret = media_entity_pads_init(&sd->entity, NUM_CIS_PADS, &state->cis_pad); in s5k5baf_configure_subdevs()
1889 sd = &state->sd; in s5k5baf_configure_subdevs()
1891 snprintf(sd->name, sizeof(sd->name), "S5K5BAF-ISP %d-%04x", in s5k5baf_configure_subdevs()
1892 i2c_adapter_id(c->adapter), c->addr); in s5k5baf_configure_subdevs()
1894 sd->internal_ops = &s5k5baf_subdev_internal_ops; in s5k5baf_configure_subdevs()
1895 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; in s5k5baf_configure_subdevs()
1897 state->pads[PAD_CIS].flags = MEDIA_PAD_FL_SINK; in s5k5baf_configure_subdevs()
1898 state->pads[PAD_OUT].flags = MEDIA_PAD_FL_SOURCE; in s5k5baf_configure_subdevs()
1899 sd->entity.function = MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN; in s5k5baf_configure_subdevs()
1900 ret = media_entity_pads_init(&sd->entity, NUM_ISP_PADS, state->pads); in s5k5baf_configure_subdevs()
1905 media_entity_cleanup(&state->cis_sd.entity); in s5k5baf_configure_subdevs()
1907 dev_err(&c->dev, "cannot init media entity %s\n", sd->name); in s5k5baf_configure_subdevs()
1913 struct i2c_client *c = v4l2_get_subdevdata(&state->sd); in s5k5baf_configure_regulators()
1918 state->supplies[i].supply = s5k5baf_supply_names[i]; in s5k5baf_configure_regulators()
1920 ret = devm_regulator_bulk_get(&c->dev, S5K5BAF_NUM_SUPPLIES, in s5k5baf_configure_regulators()
1921 state->supplies); in s5k5baf_configure_regulators()
1932 state = devm_kzalloc(&c->dev, sizeof(*state), GFP_KERNEL); in s5k5baf_probe()
1934 return -ENOMEM; in s5k5baf_probe()
1936 mutex_init(&state->lock); in s5k5baf_probe()
1937 state->crop_sink = s5k5baf_cis_rect; in s5k5baf_probe()
1938 state->compose = s5k5baf_cis_rect; in s5k5baf_probe()
1939 state->crop_source = s5k5baf_cis_rect; in s5k5baf_probe()
1941 ret = s5k5baf_parse_device_node(state, &c->dev); in s5k5baf_probe()
1957 state->clock = devm_clk_get(state->sd.dev, S5K5BAF_CLK_NAME); in s5k5baf_probe()
1958 if (IS_ERR(state->clock)) { in s5k5baf_probe()
1959 ret = -EPROBE_DEFER; in s5k5baf_probe()
1965 ret = -EPROBE_DEFER; in s5k5baf_probe()
1979 ret = v4l2_async_register_subdev(&state->sd); in s5k5baf_probe()
1986 v4l2_ctrl_handler_free(state->sd.ctrl_handler); in s5k5baf_probe()
1988 media_entity_cleanup(&state->sd.entity); in s5k5baf_probe()
1989 media_entity_cleanup(&state->cis_sd.entity); in s5k5baf_probe()
1999 v4l2_ctrl_handler_free(sd->ctrl_handler); in s5k5baf_remove()
2000 media_entity_cleanup(&sd->entity); in s5k5baf_remove()
2002 sd = &state->cis_sd; in s5k5baf_remove()
2004 media_entity_cleanup(&sd->entity); in s5k5baf_remove()