Lines Matching +full:manual +full:- +full:strobe
1 // SPDX-License-Identifier: GPL-2.0-only
3 * drivers/media/i2c/ccs/ccs-core.c
8 * Copyright (C) 2010--2012 Nokia Corporation
13 * Based on smia-sensor.c by Tuukka Toivonen <tuukkat76@gmail.com>
27 #include <linux/v4l2-mediabus.h>
28 #include <media/v4l2-cci.h>
29 #include <media/v4l2-device.h>
30 #include <media/v4l2-fwnode.h>
46 * ccs_module_idents - supported camera modules
49 CCS_IDENT_L(0x01, 0x022b, -1, "vs6555"),
50 CCS_IDENT_L(0x01, 0x022e, -1, "vw6558"),
51 CCS_IDENT_L(0x07, 0x7698, -1, "ovm7698"),
52 CCS_IDENT_L(0x0b, 0x4242, -1, "smiapp-003"),
53 CCS_IDENT_L(0x0c, 0x208a, -1, "tcm8330md"),
54 CCS_IDENT_LQ(0x0c, 0x2134, -1, "tcm8500md", &smiapp_tcm8500md_quirk),
55 CCS_IDENT_L(0x0c, 0x213e, -1, "et8en2"),
56 CCS_IDENT_L(0x0c, 0x2184, -1, "tcm8580md"),
57 CCS_IDENT_LQ(0x0c, 0x560f, -1, "jt8ew9", &smiapp_jt8ew9_quirk),
58 CCS_IDENT_LQ(0x10, 0x4141, -1, "jt8ev1", &smiapp_jt8ev1_quirk),
59 CCS_IDENT_LQ(0x10, 0x4241, -1, "imx125es", &smiapp_imx125es_quirk),
97 return -EINVAL; in ccs_limit_ptr()
101 if (WARN_ON(!sensor->ccs_limits) || in ccs_limit_ptr()
102 WARN_ON(offset + CCI_REG_WIDTH_BYTES(linfo->reg) > in ccs_limit_ptr()
104 return -EINVAL; in ccs_limit_ptr()
106 *__ptr = sensor->ccs_limits + ccs_limit_offsets[limit].lim + offset; in ccs_limit_ptr()
114 struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd); in ccs_replace_limit()
125 dev_dbg(&client->dev, "quirk: 0x%8.8x \"%s\" %u = %u, 0x%x\n", in ccs_replace_limit()
126 linfo->reg, linfo->name, offset, val, val); in ccs_replace_limit()
128 ccs_assign_limit(ptr, CCI_REG_WIDTH_BYTES(linfo->reg), val); in ccs_replace_limit()
162 struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd); in ccs_read_all_limits()
167 kfree(sensor->ccs_limits); in ccs_read_all_limits()
168 sensor->ccs_limits = NULL; in ccs_read_all_limits()
172 return -ENOMEM; in ccs_read_all_limits()
176 sensor->ccs_limits = alloc; in ccs_read_all_limits()
184 dev_err(&client->dev, in ccs_read_all_limits()
185 "internal error --- end of limit array\n"); in ccs_read_all_limits()
186 ret = -EINVAL; in ccs_read_all_limits()
200 dev_err(&client->dev, in ccs_read_all_limits()
201 "internal error --- no room for regs\n"); in ccs_read_all_limits()
202 ret = -EINVAL; in ccs_read_all_limits()
217 dev_dbg(&client->dev, in ccs_read_all_limits()
230 dev_err(&client->dev, in ccs_read_all_limits()
231 "internal error --- insufficient limits\n"); in ccs_read_all_limits()
232 ret = -EINVAL; in ccs_read_all_limits()
242 sensor->ccs_limits = NULL; in ccs_read_all_limits()
250 struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd); in ccs_read_frame_fmt()
265 dev_dbg(&client->dev, "format_model_type %s\n", in ccs_read_frame_fmt()
271 dev_dbg(&client->dev, "%u column and %u row descriptors\n", in ccs_read_frame_fmt()
300 dev_dbg(&client->dev, in ccs_read_frame_fmt()
303 return -EINVAL; in ccs_read_frame_fmt()
332 dev_dbg(&client->dev, in ccs_read_frame_fmt()
339 sensor->visible_pixel_start = pixel_count; in ccs_read_frame_fmt()
347 if (sensor->embedded_end) in ccs_read_frame_fmt()
349 sensor->embedded_start = line_count; in ccs_read_frame_fmt()
350 sensor->embedded_end = line_count + pixels; in ccs_read_frame_fmt()
353 sensor->image_start = line_count; in ccs_read_frame_fmt()
359 if (sensor->embedded_end > sensor->image_start) { in ccs_read_frame_fmt()
360 dev_dbg(&client->dev, in ccs_read_frame_fmt()
362 sensor->embedded_end, sensor->image_start); in ccs_read_frame_fmt()
363 sensor->image_start = sensor->embedded_end; in ccs_read_frame_fmt()
366 dev_dbg(&client->dev, "embedded data from lines %u to %u\n", in ccs_read_frame_fmt()
367 sensor->embedded_start, sensor->embedded_end); in ccs_read_frame_fmt()
368 dev_dbg(&client->dev, "image data starts at line %u\n", in ccs_read_frame_fmt()
369 sensor->image_start); in ccs_read_frame_fmt()
376 struct ccs_pll *pll = &sensor->pll; in ccs_pll_configure()
379 rval = ccs_write(sensor, VT_PIX_CLK_DIV, pll->vt_bk.pix_clk_div); in ccs_pll_configure()
383 rval = ccs_write(sensor, VT_SYS_CLK_DIV, pll->vt_bk.sys_clk_div); in ccs_pll_configure()
387 rval = ccs_write(sensor, PRE_PLL_CLK_DIV, pll->vt_fr.pre_pll_clk_div); in ccs_pll_configure()
391 rval = ccs_write(sensor, PLL_MULTIPLIER, pll->vt_fr.pll_multiplier); in ccs_pll_configure()
399 DIV_ROUND_UP(pll->op_bk.sys_clk_freq_hz, in ccs_pll_configure()
401 (pll->flags & CCS_PLL_FLAG_LANE_SPEED_MODEL ? in ccs_pll_configure()
402 sensor->pll.csi2.lanes : 1) << in ccs_pll_configure()
403 (pll->flags & CCS_PLL_FLAG_OP_SYS_DDR ? in ccs_pll_configure()
409 if (sensor->pll.flags & CCS_PLL_FLAG_NO_OP_CLOCKS) in ccs_pll_configure()
412 rval = ccs_write(sensor, OP_PIX_CLK_DIV, pll->op_bk.pix_clk_div); in ccs_pll_configure()
416 rval = ccs_write(sensor, OP_SYS_CLK_DIV, pll->op_bk.sys_clk_div); in ccs_pll_configure()
420 if (!(pll->flags & CCS_PLL_FLAG_DUAL_PLL)) in ccs_pll_configure()
428 pll->op_fr.pre_pll_clk_div); in ccs_pll_configure()
432 return ccs_write(sensor, OP_PLL_MULTIPLIER, pll->op_fr.pll_multiplier); in ccs_pll_configure()
437 struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd); in ccs_pll_try()
483 return ccs_pll_calculate(&client->dev, &lim, pll); in ccs_pll_try()
488 struct ccs_pll *pll = &sensor->pll; in ccs_pll_update()
491 pll->binning_horizontal = sensor->binning_horizontal; in ccs_pll_update()
492 pll->binning_vertical = sensor->binning_vertical; in ccs_pll_update()
493 pll->link_freq = in ccs_pll_update()
494 sensor->link_freq->qmenu_int[sensor->link_freq->val]; in ccs_pll_update()
495 pll->scale_m = sensor->scale_m; in ccs_pll_update()
496 pll->bits_per_pixel = sensor->csi_format->compressed; in ccs_pll_update()
502 __v4l2_ctrl_s_ctrl_int64(sensor->pixel_rate_parray, in ccs_pll_update()
503 pll->pixel_rate_pixel_array); in ccs_pll_update()
504 __v4l2_ctrl_s_ctrl_int64(sensor->pixel_rate_csi, pll->pixel_rate_csi); in ccs_pll_update()
518 struct v4l2_ctrl *ctrl = sensor->exposure; in __ccs_update_exposure_limits()
521 max = sensor->pa_src.height + sensor->vblank->val - in __ccs_update_exposure_limits()
524 __v4l2_ctrl_modify_range(ctrl, ctrl->minimum, max, ctrl->step, max); in __ccs_update_exposure_limits()
530 * 1. Bits-per-pixel, descending.
531 * 2. Bits-per-pixel compressed, descending.
565 - (unsigned long)ccs_csi_data_formats) \
570 struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd); in ccs_pixel_order()
573 if (sensor->hflip) { in ccs_pixel_order()
574 if (sensor->hflip->val) in ccs_pixel_order()
577 if (sensor->vflip->val) in ccs_pixel_order()
581 dev_dbg(&client->dev, "flip %u\n", flip); in ccs_pixel_order()
582 return sensor->default_pixel_order ^ flip; in ccs_pixel_order()
587 struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd); in ccs_update_mbus_formats()
589 to_csi_format_idx(sensor->csi_format) & ~3; in ccs_update_mbus_formats()
591 to_csi_format_idx(sensor->internal_csi_format) & ~3; in ccs_update_mbus_formats()
598 sensor->mbus_frame_fmts = in ccs_update_mbus_formats()
599 sensor->default_mbus_frame_fmts << pixel_order; in ccs_update_mbus_formats()
600 sensor->csi_format = in ccs_update_mbus_formats()
602 sensor->internal_csi_format = in ccs_update_mbus_formats()
606 dev_dbg(&client->dev, "new pixel order %s\n", in ccs_update_mbus_formats()
621 container_of(ctrl->handler, struct ccs_subdev, ctrl_handler) in ccs_set_ctrl()
622 ->sensor; in ccs_set_ctrl()
623 struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd); in ccs_set_ctrl()
630 switch (ctrl->id) { in ccs_set_ctrl()
633 if (sensor->streaming) in ccs_set_ctrl()
634 return -EBUSY; in ccs_set_ctrl()
636 if (sensor->hflip->val) in ccs_set_ctrl()
639 if (sensor->vflip->val) in ccs_set_ctrl()
646 exposure = sensor->exposure->val; in ccs_set_ctrl()
650 if (exposure > sensor->exposure->maximum) { in ccs_set_ctrl()
651 sensor->exposure->val = sensor->exposure->maximum; in ccs_set_ctrl()
652 rval = ccs_set_ctrl(sensor->exposure); in ccs_set_ctrl()
659 if (sensor->streaming) in ccs_set_ctrl()
660 return -EBUSY; in ccs_set_ctrl()
668 for (i = 0; i < ARRAY_SIZE(sensor->test_data); i++) in ccs_set_ctrl()
670 sensor->test_data[i], in ccs_set_ctrl()
671 ctrl->val == in ccs_set_ctrl()
677 pm_status = pm_runtime_get_if_active(&client->dev); in ccs_set_ctrl()
681 switch (ctrl->id) { in ccs_set_ctrl()
683 rval = ccs_write(sensor, ANALOG_GAIN_CODE_GLOBAL, ctrl->val); in ccs_set_ctrl()
688 rval = ccs_write(sensor, ANALOG_LINEAR_GAIN_GLOBAL, ctrl->val); in ccs_set_ctrl()
694 ctrl->val); in ccs_set_ctrl()
702 ctrl->val); in ccs_set_ctrl()
708 ctrl->val); in ccs_set_ctrl()
714 ctrl->val); in ccs_set_ctrl()
720 ctrl->val); in ccs_set_ctrl()
726 ctrl->val); in ccs_set_ctrl()
730 rval = ccs_write(sensor, COARSE_INTEGRATION_TIME, ctrl->val); in ccs_set_ctrl()
740 sensor->pa_src.height + ctrl->val); in ccs_set_ctrl()
745 sensor->pa_src.width + ctrl->val); in ccs_set_ctrl()
749 rval = ccs_write(sensor, TEST_PATTERN_MODE, ctrl->val); in ccs_set_ctrl()
753 rval = ccs_write(sensor, TEST_DATA_RED, ctrl->val); in ccs_set_ctrl()
757 rval = ccs_write(sensor, TEST_DATA_GREENR, ctrl->val); in ccs_set_ctrl()
761 rval = ccs_write(sensor, TEST_DATA_BLUE, ctrl->val); in ccs_set_ctrl()
765 rval = ccs_write(sensor, TEST_DATA_GREENB, ctrl->val); in ccs_set_ctrl()
770 ctrl->val ? CCS_SHADING_CORRECTION_EN_ENABLE : in ccs_set_ctrl()
773 if (!rval && sensor->luminance_level) in ccs_set_ctrl()
774 v4l2_ctrl_activate(sensor->luminance_level, ctrl->val); in ccs_set_ctrl()
778 rval = ccs_write(sensor, LUMINANCE_CORRECTION_LEVEL, ctrl->val); in ccs_set_ctrl()
787 rval = -EINVAL; in ccs_set_ctrl()
791 pm_runtime_mark_last_busy(&client->dev); in ccs_set_ctrl()
792 pm_runtime_put_autosuspend(&client->dev); in ccs_set_ctrl()
804 struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd); in ccs_init_controls()
808 rval = v4l2_ctrl_handler_init(&sensor->pixel_array->ctrl_handler, 19); in ccs_init_controls()
812 sensor->pixel_array->ctrl_handler.lock = &sensor->mutex; in ccs_init_controls()
814 rval = v4l2_fwnode_device_parse(&client->dev, &props); in ccs_init_controls()
818 rval = v4l2_ctrl_new_fwnode_properties(&sensor->pixel_array->ctrl_handler, in ccs_init_controls()
853 v4l2_ctrl_new_custom(&sensor->pixel_array->ctrl_handler, in ccs_init_controls()
857 v4l2_ctrl_new_std(&sensor->pixel_array->ctrl_handler, in ccs_init_controls()
905 v4l2_ctrl_new_custom(&sensor->pixel_array->ctrl_handler, in ccs_init_controls()
923 v4l2_ctrl_new_custom(&sensor->pixel_array->ctrl_handler, in ccs_init_controls()
939 sensor->luminance_level = in ccs_init_controls()
940 v4l2_ctrl_new_custom(&sensor->pixel_array->ctrl_handler, in ccs_init_controls()
948 v4l2_ctrl_new_std(&sensor->pixel_array->ctrl_handler, in ccs_init_controls()
957 sensor->exposure = v4l2_ctrl_new_std( in ccs_init_controls()
958 &sensor->pixel_array->ctrl_handler, &ccs_ctrl_ops, in ccs_init_controls()
961 sensor->hflip = v4l2_ctrl_new_std( in ccs_init_controls()
962 &sensor->pixel_array->ctrl_handler, &ccs_ctrl_ops, in ccs_init_controls()
964 sensor->vflip = v4l2_ctrl_new_std( in ccs_init_controls()
965 &sensor->pixel_array->ctrl_handler, &ccs_ctrl_ops, in ccs_init_controls()
968 sensor->vblank = v4l2_ctrl_new_std( in ccs_init_controls()
969 &sensor->pixel_array->ctrl_handler, &ccs_ctrl_ops, in ccs_init_controls()
972 if (sensor->vblank) in ccs_init_controls()
973 sensor->vblank->flags |= V4L2_CTRL_FLAG_UPDATE; in ccs_init_controls()
975 sensor->hblank = v4l2_ctrl_new_std( in ccs_init_controls()
976 &sensor->pixel_array->ctrl_handler, &ccs_ctrl_ops, in ccs_init_controls()
979 if (sensor->hblank) in ccs_init_controls()
980 sensor->hblank->flags |= V4L2_CTRL_FLAG_UPDATE; in ccs_init_controls()
982 sensor->pixel_rate_parray = v4l2_ctrl_new_std( in ccs_init_controls()
983 &sensor->pixel_array->ctrl_handler, &ccs_ctrl_ops, in ccs_init_controls()
986 v4l2_ctrl_new_std_menu_items(&sensor->pixel_array->ctrl_handler, in ccs_init_controls()
988 ARRAY_SIZE(ccs_test_patterns) - 1, in ccs_init_controls()
991 if (sensor->pixel_array->ctrl_handler.error) { in ccs_init_controls()
992 dev_err(&client->dev, in ccs_init_controls()
994 sensor->pixel_array->ctrl_handler.error); in ccs_init_controls()
995 return sensor->pixel_array->ctrl_handler.error; in ccs_init_controls()
998 sensor->pixel_array->sd.ctrl_handler = in ccs_init_controls()
999 &sensor->pixel_array->ctrl_handler; in ccs_init_controls()
1001 v4l2_ctrl_cluster(2, &sensor->hflip); in ccs_init_controls()
1003 rval = v4l2_ctrl_handler_init(&sensor->src->ctrl_handler, 0); in ccs_init_controls()
1007 sensor->src->ctrl_handler.lock = &sensor->mutex; in ccs_init_controls()
1009 sensor->pixel_rate_csi = v4l2_ctrl_new_std( in ccs_init_controls()
1010 &sensor->src->ctrl_handler, &ccs_ctrl_ops, in ccs_init_controls()
1013 if (sensor->src->ctrl_handler.error) { in ccs_init_controls()
1014 dev_err(&client->dev, in ccs_init_controls()
1016 sensor->src->ctrl_handler.error); in ccs_init_controls()
1017 return sensor->src->ctrl_handler.error; in ccs_init_controls()
1020 sensor->src->sd.ctrl_handler = &sensor->src->ctrl_handler; in ccs_init_controls()
1031 unsigned long *valid_link_freqs = &sensor->valid_link_freqs[ in ccs_init_late_controls()
1032 sensor->csi_format->compressed - sensor->compressed_min_bpp]; in ccs_init_late_controls()
1035 for (i = 0; i < ARRAY_SIZE(sensor->test_data); i++) { in ccs_init_late_controls()
1036 int max_value = (1 << sensor->csi_format->width) - 1; in ccs_init_late_controls()
1038 sensor->test_data[i] = v4l2_ctrl_new_std( in ccs_init_late_controls()
1039 &sensor->pixel_array->ctrl_handler, in ccs_init_late_controls()
1044 sensor->link_freq = v4l2_ctrl_new_int_menu( in ccs_init_late_controls()
1045 &sensor->src->ctrl_handler, &ccs_ctrl_ops, in ccs_init_late_controls()
1047 __ffs(*valid_link_freqs), sensor->hwcfg.op_sys_clock); in ccs_init_late_controls()
1049 return sensor->src->ctrl_handler.error; in ccs_init_late_controls()
1056 for (i = 0; i < sensor->ssds_used; i++) in ccs_free_controls()
1057 v4l2_ctrl_handler_free(&sensor->ssds[i].ctrl_handler); in ccs_free_controls()
1062 struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd); in ccs_get_mbus_formats()
1063 struct ccs_pll *pll = &sensor->pll; in ccs_get_mbus_formats()
1071 dev_dbg(&client->dev, "data_format_model_type %u\n", type); in ccs_get_mbus_formats()
1078 dev_dbg(&client->dev, "bad pixel order %u\n", pixel_order); in ccs_get_mbus_formats()
1079 return -EINVAL; in ccs_get_mbus_formats()
1082 dev_dbg(&client->dev, "pixel order %u (%s)\n", pixel_order, in ccs_get_mbus_formats()
1093 return -EINVAL; in ccs_get_mbus_formats()
1096 sensor->default_pixel_order = pixel_order; in ccs_get_mbus_formats()
1097 sensor->mbus_frame_fmts = 0; in ccs_get_mbus_formats()
1104 dev_dbg(&client->dev, "%u: bpp %u, compressed %u\n", in ccs_get_mbus_formats()
1111 if (f->pixel_order != CCS_PIXEL_ORDER_GRBG) in ccs_get_mbus_formats()
1114 if (f->width != fmt >> in ccs_get_mbus_formats()
1116 f->compressed != in ccs_get_mbus_formats()
1120 dev_dbg(&client->dev, "jolly good! %u\n", j); in ccs_get_mbus_formats()
1122 sensor->default_mbus_frame_fmts |= 1 << j; in ccs_get_mbus_formats()
1127 pll->binning_horizontal = 1; in ccs_get_mbus_formats()
1128 pll->binning_vertical = 1; in ccs_get_mbus_formats()
1129 pll->scale_m = sensor->scale_m; in ccs_get_mbus_formats()
1132 sensor->compressed_min_bpp = in ccs_get_mbus_formats()
1134 sensor->compressed_min_bpp); in ccs_get_mbus_formats()
1140 sensor->valid_link_freqs = devm_kcalloc( in ccs_get_mbus_formats()
1141 &client->dev, in ccs_get_mbus_formats()
1142 compressed_max_bpp - sensor->compressed_min_bpp + 1, in ccs_get_mbus_formats()
1143 sizeof(*sensor->valid_link_freqs), GFP_KERNEL); in ccs_get_mbus_formats()
1144 if (!sensor->valid_link_freqs) in ccs_get_mbus_formats()
1145 return -ENOMEM; in ccs_get_mbus_formats()
1151 &sensor->valid_link_freqs[ in ccs_get_mbus_formats()
1152 f->compressed - sensor->compressed_min_bpp]; in ccs_get_mbus_formats()
1155 if (!(sensor->default_mbus_frame_fmts & 1 << i)) in ccs_get_mbus_formats()
1158 pll->bits_per_pixel = f->compressed; in ccs_get_mbus_formats()
1160 for (j = 0; sensor->hwcfg.op_sys_clock[j]; j++) { in ccs_get_mbus_formats()
1161 pll->link_freq = sensor->hwcfg.op_sys_clock[j]; in ccs_get_mbus_formats()
1164 dev_dbg(&client->dev, "link freq %u Hz, bpp %u %s\n", in ccs_get_mbus_formats()
1165 pll->link_freq, pll->bits_per_pixel, in ccs_get_mbus_formats()
1174 dev_info(&client->dev, in ccs_get_mbus_formats()
1176 f->compressed); in ccs_get_mbus_formats()
1177 sensor->default_mbus_frame_fmts &= ~BIT(i); in ccs_get_mbus_formats()
1181 if (!sensor->csi_format in ccs_get_mbus_formats()
1182 || f->width > sensor->csi_format->width in ccs_get_mbus_formats()
1183 || (f->width == sensor->csi_format->width in ccs_get_mbus_formats()
1184 && f->compressed > sensor->csi_format->compressed)) { in ccs_get_mbus_formats()
1185 sensor->csi_format = f; in ccs_get_mbus_formats()
1186 sensor->internal_csi_format = f; in ccs_get_mbus_formats()
1190 if (!sensor->csi_format) { in ccs_get_mbus_formats()
1191 dev_err(&client->dev, "no supported mbus code found\n"); in ccs_get_mbus_formats()
1192 return -EINVAL; in ccs_get_mbus_formats()
1202 struct v4l2_ctrl *vblank = sensor->vblank; in ccs_update_blanking()
1203 struct v4l2_ctrl *hblank = sensor->hblank; in ccs_update_blanking()
1207 if (sensor->binning_vertical > 1 || sensor->binning_horizontal > 1) { in ccs_update_blanking()
1223 min_fll - sensor->pa_src.height); in ccs_update_blanking()
1224 max = max_fll - sensor->pa_src.height; in ccs_update_blanking()
1226 __v4l2_ctrl_modify_range(vblank, min, max, vblank->step, min); in ccs_update_blanking()
1228 min = max_t(int, min_llp - sensor->pa_src.width, min_lbp); in ccs_update_blanking()
1229 max = max_llp - sensor->pa_src.width; in ccs_update_blanking()
1231 __v4l2_ctrl_modify_range(hblank, min, max, hblank->step, min); in ccs_update_blanking()
1238 struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd); in ccs_pll_blanking_update()
1248 dev_dbg(&client->dev, "vblank\t\t%d\n", sensor->vblank->val); in ccs_pll_blanking_update()
1249 dev_dbg(&client->dev, "hblank\t\t%d\n", sensor->hblank->val); in ccs_pll_blanking_update()
1251 dev_dbg(&client->dev, "real timeperframe\t100/%d\n", in ccs_pll_blanking_update()
1252 sensor->pll.pixel_rate_pixel_array / in ccs_pll_blanking_update()
1253 ((sensor->pa_src.width + sensor->hblank->val) * in ccs_pll_blanking_update()
1254 (sensor->pa_src.height + sensor->vblank->val) / 100)); in ccs_pll_blanking_update()
1289 return -ENODATA; in ccs_read_nvm_page()
1294 for (i = 1000; i > 0; i--) { in ccs_read_nvm_page()
1304 return -ETIMEDOUT; in ccs_read_nvm_page()
1333 if (rval == -ENODATA && in ccs_read_nvm()
1351 struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd); in ccs_change_cci_addr()
1355 client->addr = sensor->hwcfg.i2c_addr_dfl; in ccs_change_cci_addr()
1358 sensor->hwcfg.i2c_addr_alt << 1); in ccs_change_cci_addr()
1362 client->addr = sensor->hwcfg.i2c_addr_alt; in ccs_change_cci_addr()
1369 if (val != sensor->hwcfg.i2c_addr_alt << 1) in ccs_change_cci_addr()
1370 return -ENODEV; in ccs_change_cci_addr()
1383 unsigned int ext_freq = sensor->hwcfg.ext_clk; in ccs_setup_flash_strobe()
1389 strobe_setup = sensor->hwcfg.strobe_setup; in ccs_setup_flash_strobe()
1392 * How to calculate registers related to strobe length. Please in ccs_setup_flash_strobe()
1394 * doing. :-) in ccs_setup_flash_strobe()
1396 * Sakari Ailus <sakari.ailus@linux.intel.com> 2010-10-25 in ccs_setup_flash_strobe()
1401 * tFlash_strobe_width_ctrl E N, [1 - 0xffff] in ccs_setup_flash_strobe()
1402 * flash_strobe_adjustment E N, [1 - 0xff] in ccs_setup_flash_strobe()
1417 * The strobe width must be at least as long as requested, in ccs_setup_flash_strobe()
1420 * x = (l * e + 10^6 - 1) / 10^6 in ccs_setup_flash_strobe()
1421 * ----------------------------- in ccs_setup_flash_strobe()
1428 * a = (x + (2^16 - 1) - 1) / (2^16 - 1) in ccs_setup_flash_strobe()
1429 * ------------------------------------- in ccs_setup_flash_strobe()
1433 * w = (x + a - 1) / a in ccs_setup_flash_strobe()
1434 * ------------------- in ccs_setup_flash_strobe()
1438 * x E [1, (2^16 - 1) * (2^8 - 1)] in ccs_setup_flash_strobe()
1443 * (2^16 - 1) * (2^8 - 1) * 10^6 = l * e + 10^6 - 1 in ccs_setup_flash_strobe()
1445 * l = (10^6 * (2^16 - 1) * (2^8 - 1) - 10^6 + 1) / e in ccs_setup_flash_strobe()
1446 * -------------------------------------------------- in ccs_setup_flash_strobe()
1449 * (10^6 * (2^16 - 1) * (2^8 - 1) - 10^6 + 1) / EXTCLK freq. in ccs_setup_flash_strobe()
1454 * EXTCLK freq + 10^6 - 1) / 10^6 + (2^16 - 1) - 1) / (2^16 - 1) in ccs_setup_flash_strobe()
1457 * EXTCLK freq + 10^6 - 1) / 10^6 + in ccs_setup_flash_strobe()
1458 * flash_strobe_adjustment - 1) / flash_strobe_adjustment in ccs_setup_flash_strobe()
1460 tmp = div_u64(1000000ULL * ((1 << 16) - 1) * ((1 << 8) - 1) - in ccs_setup_flash_strobe()
1462 strobe_setup->strobe_width_high_us = in ccs_setup_flash_strobe()
1463 clamp_t(u32, strobe_setup->strobe_width_high_us, 1, tmp); in ccs_setup_flash_strobe()
1465 tmp = div_u64(((u64)strobe_setup->strobe_width_high_us * (u64)ext_freq + in ccs_setup_flash_strobe()
1466 1000000 - 1), 1000000ULL); in ccs_setup_flash_strobe()
1467 strobe_adjustment = (tmp + (1 << 16) - 1 - 1) / ((1 << 16) - 1); in ccs_setup_flash_strobe()
1468 strobe_width_high_rs = (tmp + strobe_adjustment - 1) / in ccs_setup_flash_strobe()
1471 rval = ccs_write(sensor, FLASH_MODE_RS, strobe_setup->mode); in ccs_setup_flash_strobe()
1485 strobe_setup->strobe_delay); in ccs_setup_flash_strobe()
1490 strobe_setup->stobe_start_point); in ccs_setup_flash_strobe()
1494 rval = ccs_write(sensor, FLASH_TRIGGER_RS, strobe_setup->trigger); in ccs_setup_flash_strobe()
1497 sensor->hwcfg.strobe_setup->trigger = 0; in ccs_setup_flash_strobe()
1502 /* -----------------------------------------------------------------------------
1511 sensor->sdata.sensor_manufacturer_regs, in ccs_write_msr_regs()
1512 sensor->sdata.num_sensor_manufacturer_regs); in ccs_write_msr_regs()
1517 sensor->mdata.module_manufacturer_regs, in ccs_write_msr_regs()
1518 sensor->mdata.num_module_manufacturer_regs); in ccs_write_msr_regs()
1523 struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd); in ccs_update_phy_ctrl()
1526 if (!sensor->ccs_limits) in ccs_update_phy_ctrl()
1536 dev_err(&client->dev, "manual PHY control not supported\n"); in ccs_update_phy_ctrl()
1537 return -EINVAL; in ccs_update_phy_ctrl()
1548 * The sub-device related to the I2C device is always the in ccs_power_on()
1557 sensor->regulators); in ccs_power_on()
1563 if (sensor->reset || sensor->xshutdown || sensor->ext_clk) { in ccs_power_on()
1566 rval = clk_prepare_enable(sensor->ext_clk); in ccs_power_on()
1572 gpiod_set_value(sensor->reset, 0); in ccs_power_on()
1573 gpiod_set_value(sensor->xshutdown, 1); in ccs_power_on()
1575 if (ccsdev->flags & CCS_DEVICE_FLAG_IS_SMIA) in ccs_power_on()
1576 sleep = SMIAPP_RESET_DELAY(sensor->hwcfg.ext_clk); in ccs_power_on()
1594 if (!sensor->reset && !sensor->xshutdown) { in ccs_power_on()
1611 } while (--retry); in ccs_power_on()
1615 rval = -EIO; in ccs_power_on()
1620 if (sensor->hwcfg.i2c_addr_alt) { in ccs_power_on()
1636 sensor->hwcfg.ext_clk / (1000000 / (1 << 8))); in ccs_power_on()
1642 rval = ccs_write(sensor, CSI_LANE_MODE, sensor->hwcfg.lanes - 1); in ccs_power_on()
1656 sensor->hwcfg.csi_signalling_mode); in ccs_power_on()
1679 gpiod_set_value(sensor->reset, 1); in ccs_power_on()
1680 gpiod_set_value(sensor->xshutdown, 0); in ccs_power_on()
1681 clk_disable_unprepare(sensor->ext_clk); in ccs_power_on()
1685 sensor->regulators); in ccs_power_on()
1704 if (sensor->hwcfg.i2c_addr_alt) in ccs_power_off()
1707 gpiod_set_value(sensor->reset, 1); in ccs_power_off()
1708 gpiod_set_value(sensor->xshutdown, 0); in ccs_power_off()
1709 clk_disable_unprepare(sensor->ext_clk); in ccs_power_off()
1712 sensor->regulators); in ccs_power_off()
1713 sensor->streaming = false; in ccs_power_off()
1718 /* -----------------------------------------------------------------------------
1724 struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd); in ccs_start_streaming()
1728 mutex_lock(&sensor->mutex); in ccs_start_streaming()
1731 (sensor->csi_format->width << 8) | in ccs_start_streaming()
1732 sensor->csi_format->compressed); in ccs_start_streaming()
1737 if (sensor->binning_horizontal == 1 && in ccs_start_streaming()
1738 sensor->binning_vertical == 1) { in ccs_start_streaming()
1742 (sensor->binning_horizontal << 4) in ccs_start_streaming()
1743 | sensor->binning_vertical; in ccs_start_streaming()
1761 rval = ccs_write(sensor, X_ADDR_START, sensor->pa_src.left); in ccs_start_streaming()
1765 rval = ccs_write(sensor, Y_ADDR_START, sensor->pa_src.top); in ccs_start_streaming()
1771 sensor->pa_src.left + sensor->pa_src.width - 1); in ccs_start_streaming()
1776 sensor->pa_src.top + sensor->pa_src.height - 1); in ccs_start_streaming()
1789 sensor->scaler_sink.left); in ccs_start_streaming()
1794 sensor->scaler_sink.top); in ccs_start_streaming()
1799 sensor->scaler_sink.width); in ccs_start_streaming()
1804 sensor->scaler_sink.height); in ccs_start_streaming()
1812 rval = ccs_write(sensor, SCALING_MODE, sensor->scaling_mode); in ccs_start_streaming()
1816 rval = ccs_write(sensor, SCALE_M, sensor->scale_m); in ccs_start_streaming()
1822 rval = ccs_write(sensor, X_OUTPUT_SIZE, sensor->src_src.width); in ccs_start_streaming()
1825 rval = ccs_write(sensor, Y_OUTPUT_SIZE, sensor->src_src.height); in ccs_start_streaming()
1832 sensor->hwcfg.strobe_setup != NULL && in ccs_start_streaming()
1833 sensor->hwcfg.strobe_setup->trigger != 0) { in ccs_start_streaming()
1841 dev_err(&client->dev, "pre_streamon quirks failed\n"); in ccs_start_streaming()
1848 mutex_unlock(&sensor->mutex); in ccs_start_streaming()
1855 struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd); in ccs_stop_streaming()
1858 mutex_lock(&sensor->mutex); in ccs_stop_streaming()
1865 dev_err(&client->dev, "post_streamoff quirks failed\n"); in ccs_stop_streaming()
1868 mutex_unlock(&sensor->mutex); in ccs_stop_streaming()
1872 /* -----------------------------------------------------------------------------
1878 struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd); in ccs_pm_get_init()
1886 rval = pm_runtime_get_sync(&client->dev); in ccs_pm_get_init()
1891 if (rval == 1 && !sensor->handler_setup_needed) in ccs_pm_get_init()
1894 sensor->handler_setup_needed = false; in ccs_pm_get_init()
1897 rval = v4l2_ctrl_handler_setup(&sensor->pixel_array->ctrl_handler); in ccs_pm_get_init()
1901 rval = v4l2_ctrl_handler_setup(&sensor->src->ctrl_handler); in ccs_pm_get_init()
1908 pm_runtime_put(&client->dev); in ccs_pm_get_init()
1915 struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd); in ccs_set_stream()
1920 sensor->streaming = false; in ccs_set_stream()
1921 pm_runtime_mark_last_busy(&client->dev); in ccs_set_stream()
1922 pm_runtime_put_autosuspend(&client->dev); in ccs_set_stream()
1931 sensor->streaming = true; in ccs_set_stream()
1935 sensor->streaming = false; in ccs_set_stream()
1936 pm_runtime_mark_last_busy(&client->dev); in ccs_set_stream()
1937 pm_runtime_put_autosuspend(&client->dev); in ccs_set_stream()
1946 struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd); in ccs_pre_streamon()
1950 switch (sensor->hwcfg.csi_signalling_mode) { in ccs_pre_streamon()
1954 return -EACCES; in ccs_pre_streamon()
1959 return -EACCES; in ccs_pre_streamon()
1962 return -EACCES; in ccs_pre_streamon()
1974 pm_runtime_put(&client->dev); in ccs_pre_streamon()
1983 struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd); in ccs_post_streamoff()
1985 return pm_runtime_put(&client->dev); in ccs_post_streamoff()
1995 int idx = -1; in ccs_enum_mbus_code()
1996 int rval = -EINVAL; in ccs_enum_mbus_code()
1998 mutex_lock(&sensor->mutex); in ccs_enum_mbus_code()
2000 dev_err(&client->dev, "subdev %s, pad %u, index %u\n", in ccs_enum_mbus_code()
2001 subdev->name, code->pad, code->index); in ccs_enum_mbus_code()
2003 if (subdev != &sensor->src->sd || code->pad != CCS_PAD_SRC) { in ccs_enum_mbus_code()
2004 if (code->index) in ccs_enum_mbus_code()
2007 code->code = sensor->internal_csi_format->code; in ccs_enum_mbus_code()
2013 if (sensor->mbus_frame_fmts & (1 << i)) in ccs_enum_mbus_code()
2016 if (idx == code->index) { in ccs_enum_mbus_code()
2017 code->code = ccs_csi_data_formats[i].code; in ccs_enum_mbus_code()
2018 dev_err(&client->dev, "found index %u, i %u, code %x\n", in ccs_enum_mbus_code()
2019 code->index, i, code->code); in ccs_enum_mbus_code()
2026 mutex_unlock(&sensor->mutex); in ccs_enum_mbus_code()
2035 if (subdev == &sensor->src->sd && pad == CCS_PAD_SRC) in __ccs_get_mbus_code()
2036 return sensor->csi_format->code; in __ccs_get_mbus_code()
2038 return sensor->internal_csi_format->code; in __ccs_get_mbus_code()
2045 fmt->format = *v4l2_subdev_state_get_format(sd_state, fmt->pad); in __ccs_get_format()
2046 fmt->format.code = __ccs_get_mbus_code(subdev, fmt->pad); in __ccs_get_format()
2058 mutex_lock(&sensor->mutex); in ccs_get_format()
2060 mutex_unlock(&sensor->mutex); in ccs_get_format()
2074 for (i = 0; i < subdev->entity.num_pads; i++) in ccs_get_crop_compose()
2079 ssd->sink_pad); in ccs_get_crop_compose()
2096 comp->width = crops[CCS_PAD_SINK]->width; in ccs_propagate()
2097 comp->height = crops[CCS_PAD_SINK]->height; in ccs_propagate()
2099 if (ssd == sensor->scaler) { in ccs_propagate()
2100 sensor->scale_m = CCS_LIM(sensor, SCALER_N_MIN); in ccs_propagate()
2101 sensor->scaling_mode = in ccs_propagate()
2103 sensor->scaler_sink = *comp; in ccs_propagate()
2104 } else if (ssd == sensor->binner) { in ccs_propagate()
2105 sensor->binning_horizontal = 1; in ccs_propagate()
2106 sensor->binning_vertical = 1; in ccs_propagate()
2113 fmt->width = comp->width; in ccs_propagate()
2114 fmt->height = comp->height; in ccs_propagate()
2115 if (which == V4L2_SUBDEV_FORMAT_ACTIVE && ssd == sensor->src) in ccs_propagate()
2116 sensor->src_src = *crops[CCS_PAD_SRC]; in ccs_propagate()
2129 if (sensor->mbus_frame_fmts & (1 << i) && in ccs_validate_csi_data_format()
2134 return sensor->csi_format; in ccs_validate_csi_data_format()
2143 *old_csi_format = sensor->csi_format; in ccs_set_format_source()
2145 u32 code = fmt->format.code; in ccs_set_format_source()
2157 if (subdev != &sensor->src->sd) in ccs_set_format_source()
2162 fmt->format.code = csi_format->code; in ccs_set_format_source()
2164 if (fmt->which != V4L2_SUBDEV_FORMAT_ACTIVE) in ccs_set_format_source()
2167 sensor->csi_format = csi_format; in ccs_set_format_source()
2169 if (csi_format->width != old_csi_format->width) in ccs_set_format_source()
2170 for (i = 0; i < ARRAY_SIZE(sensor->test_data); i++) in ccs_set_format_source()
2172 sensor->test_data[i], 0, in ccs_set_format_source()
2173 (1 << csi_format->width) - 1, 1, 0); in ccs_set_format_source()
2175 if (csi_format->compressed == old_csi_format->compressed) in ccs_set_format_source()
2179 &sensor->valid_link_freqs[sensor->csi_format->compressed in ccs_set_format_source()
2180 - sensor->compressed_min_bpp]; in ccs_set_format_source()
2183 sensor->link_freq, 0, in ccs_set_format_source()
2198 mutex_lock(&sensor->mutex); in ccs_set_format()
2200 if (fmt->pad == ssd->source_pad) { in ccs_set_format()
2205 mutex_unlock(&sensor->mutex); in ccs_set_format()
2211 fmt->format.code = __ccs_get_mbus_code(subdev, fmt->pad); in ccs_set_format()
2212 fmt->format.width &= ~1; in ccs_set_format()
2213 fmt->format.height &= ~1; in ccs_set_format()
2214 fmt->format.field = V4L2_FIELD_NONE; in ccs_set_format()
2216 fmt->format.width = in ccs_set_format()
2217 clamp(fmt->format.width, in ccs_set_format()
2220 fmt->format.height = in ccs_set_format()
2221 clamp(fmt->format.height, in ccs_set_format()
2227 crops[ssd->sink_pad]->left = 0; in ccs_set_format()
2228 crops[ssd->sink_pad]->top = 0; in ccs_set_format()
2229 crops[ssd->sink_pad]->width = fmt->format.width; in ccs_set_format()
2230 crops[ssd->sink_pad]->height = fmt->format.height; in ccs_set_format()
2231 ccs_propagate(subdev, sd_state, fmt->which, V4L2_SEL_TGT_CROP); in ccs_set_format()
2233 mutex_unlock(&sensor->mutex); in ccs_set_format()
2258 val -= SCALING_GOODNESS; in scaling_goodness()
2260 val -= SCALING_GOODNESS; in scaling_goodness()
2265 val -= SCALING_GOODNESS; in scaling_goodness()
2267 val -= SCALING_GOODNESS; in scaling_goodness()
2270 val -= abs(w - ask_w); in scaling_goodness()
2271 val -= abs(h - ask_h); in scaling_goodness()
2274 val -= SCALING_GOODNESS_EXTREME; in scaling_goodness()
2276 dev_dbg(&client->dev, "w %d ask_w %d h %d ask_h %d goodness %d\n", in scaling_goodness()
2293 crops[CCS_PAD_SINK]->width, sel->r.width, in ccs_set_compose_binner()
2294 crops[CCS_PAD_SINK]->height, sel->r.height, sel->flags); in ccs_set_compose_binner()
2296 for (i = 0; i < sensor->nbinning_subtypes; i++) { in ccs_set_compose_binner()
2299 crops[CCS_PAD_SINK]->width in ccs_set_compose_binner()
2300 / sensor->binning_subtypes[i].horizontal, in ccs_set_compose_binner()
2301 sel->r.width, in ccs_set_compose_binner()
2302 crops[CCS_PAD_SINK]->height in ccs_set_compose_binner()
2303 / sensor->binning_subtypes[i].vertical, in ccs_set_compose_binner()
2304 sel->r.height, sel->flags); in ccs_set_compose_binner()
2307 binh = sensor->binning_subtypes[i].horizontal; in ccs_set_compose_binner()
2308 binv = sensor->binning_subtypes[i].vertical; in ccs_set_compose_binner()
2312 if (sel->which == V4L2_SUBDEV_FORMAT_ACTIVE) { in ccs_set_compose_binner()
2313 sensor->binning_vertical = binv; in ccs_set_compose_binner()
2314 sensor->binning_horizontal = binh; in ccs_set_compose_binner()
2317 sel->r.width = (crops[CCS_PAD_SINK]->width / binh) & ~1; in ccs_set_compose_binner()
2318 sel->r.height = (crops[CCS_PAD_SINK]->height / binv) & ~1; in ccs_set_compose_binner()
2346 sel->r.width = min_t(unsigned int, sel->r.width, in ccs_set_compose_scaler()
2347 crops[CCS_PAD_SINK]->width); in ccs_set_compose_scaler()
2348 sel->r.height = min_t(unsigned int, sel->r.height, in ccs_set_compose_scaler()
2349 crops[CCS_PAD_SINK]->height); in ccs_set_compose_scaler()
2351 a = crops[CCS_PAD_SINK]->width in ccs_set_compose_scaler()
2352 * CCS_LIM(sensor, SCALER_N_MIN) / sel->r.width; in ccs_set_compose_scaler()
2353 b = crops[CCS_PAD_SINK]->height in ccs_set_compose_scaler()
2354 * CCS_LIM(sensor, SCALER_N_MIN) / sel->r.height; in ccs_set_compose_scaler()
2355 max_m = crops[CCS_PAD_SINK]->width in ccs_set_compose_scaler()
2366 dev_dbg(&client->dev, "scaling: a %u b %u max_m %u\n", a, b, max_m); in ccs_set_compose_scaler()
2389 crops[CCS_PAD_SINK]->width in ccs_set_compose_scaler()
2391 sel->r.width, in ccs_set_compose_scaler()
2392 crops[CCS_PAD_SINK]->height, in ccs_set_compose_scaler()
2393 sel->r.height, in ccs_set_compose_scaler()
2394 sel->flags); in ccs_set_compose_scaler()
2396 dev_dbg(&client->dev, "trying factor %u (%u)\n", try[i], i); in ccs_set_compose_scaler()
2409 subdev, crops[CCS_PAD_SINK]->width in ccs_set_compose_scaler()
2412 sel->r.width, in ccs_set_compose_scaler()
2413 crops[CCS_PAD_SINK]->height in ccs_set_compose_scaler()
2416 sel->r.height, in ccs_set_compose_scaler()
2417 sel->flags); in ccs_set_compose_scaler()
2426 sel->r.width = in ccs_set_compose_scaler()
2427 (crops[CCS_PAD_SINK]->width in ccs_set_compose_scaler()
2431 sel->r.height = in ccs_set_compose_scaler()
2432 (crops[CCS_PAD_SINK]->height in ccs_set_compose_scaler()
2437 sel->r.height = crops[CCS_PAD_SINK]->height; in ccs_set_compose_scaler()
2439 if (sel->which == V4L2_SUBDEV_FORMAT_ACTIVE) { in ccs_set_compose_scaler()
2440 sensor->scale_m = scale_m; in ccs_set_compose_scaler()
2441 sensor->scaling_mode = mode; in ccs_set_compose_scaler()
2455 sel->r.top = 0; in ccs_set_compose()
2456 sel->r.left = 0; in ccs_set_compose()
2458 if (ssd == sensor->binner) in ccs_set_compose()
2463 *comp = sel->r; in ccs_set_compose()
2464 ccs_propagate(subdev, sd_state, sel->which, V4L2_SEL_TGT_COMPOSE); in ccs_set_compose()
2466 if (sel->which == V4L2_SUBDEV_FORMAT_ACTIVE) in ccs_set_compose()
2479 switch (sel->target) { in ccs_sel_supported()
2482 if (ssd == sensor->pixel_array && sel->pad == CCS_PA_PAD_SRC) in ccs_sel_supported()
2484 if (ssd == sensor->src && sel->pad == CCS_PAD_SRC) in ccs_sel_supported()
2486 if (ssd == sensor->scaler && sel->pad == CCS_PAD_SINK && in ccs_sel_supported()
2490 return -EINVAL; in ccs_sel_supported()
2492 if (ssd == sensor->pixel_array && sel->pad == CCS_PA_PAD_SRC) in ccs_sel_supported()
2494 return -EINVAL; in ccs_sel_supported()
2497 if (sel->pad == ssd->source_pad) in ccs_sel_supported()
2498 return -EINVAL; in ccs_sel_supported()
2499 if (ssd == sensor->binner) in ccs_sel_supported()
2501 if (ssd == sensor->scaler && CCS_LIM(sensor, SCALING_CAPABILITY) in ccs_sel_supported()
2506 return -EINVAL; in ccs_sel_supported()
2520 if (sel->pad == ssd->sink_pad) { in ccs_set_crop()
2522 v4l2_subdev_state_get_format(sd_state, sel->pad); in ccs_set_crop()
2524 src_size.width = mfmt->width; in ccs_set_crop()
2525 src_size.height = mfmt->height; in ccs_set_crop()
2530 if (ssd == sensor->src && sel->pad == CCS_PAD_SRC) { in ccs_set_crop()
2531 sel->r.left = 0; in ccs_set_crop()
2532 sel->r.top = 0; in ccs_set_crop()
2535 sel->r.width = min(sel->r.width, src_size.width); in ccs_set_crop()
2536 sel->r.height = min(sel->r.height, src_size.height); in ccs_set_crop()
2538 sel->r.left = min_t(int, sel->r.left, src_size.width - sel->r.width); in ccs_set_crop()
2539 sel->r.top = min_t(int, sel->r.top, src_size.height - sel->r.height); in ccs_set_crop()
2541 *crops[sel->pad] = sel->r; in ccs_set_crop()
2543 if (ssd != sensor->pixel_array && sel->pad == CCS_PAD_SINK) in ccs_set_crop()
2544 ccs_propagate(subdev, sd_state, sel->which, V4L2_SEL_TGT_CROP); in ccs_set_crop()
2545 else if (sel->which == V4L2_SUBDEV_FORMAT_ACTIVE && in ccs_set_crop()
2546 ssd == sensor->pixel_array) in ccs_set_crop()
2547 sensor->pa_src = sel->r; in ccs_set_crop()
2554 r->top = 0; in ccs_get_native_size()
2555 r->left = 0; in ccs_get_native_size()
2556 r->width = CCS_LIM(ssd->sensor, X_ADDR_MAX) + 1; in ccs_get_native_size()
2557 r->height = CCS_LIM(ssd->sensor, Y_ADDR_MAX) + 1; in ccs_get_native_size()
2575 switch (sel->target) { in ccs_get_selection()
2578 if (ssd == sensor->pixel_array) { in ccs_get_selection()
2579 ccs_get_native_size(ssd, &sel->r); in ccs_get_selection()
2580 } else if (sel->pad == ssd->sink_pad) { in ccs_get_selection()
2583 ssd->sink_pad); in ccs_get_selection()
2584 sel->r.top = sel->r.left = 0; in ccs_get_selection()
2585 sel->r.width = sink_fmt->width; in ccs_get_selection()
2586 sel->r.height = sink_fmt->height; in ccs_get_selection()
2588 sel->r = *comp; in ccs_get_selection()
2593 sel->r = *crops[sel->pad]; in ccs_get_selection()
2596 sel->r = *comp; in ccs_get_selection()
2614 mutex_lock(&sensor->mutex); in ccs_set_selection()
2616 sel->r.left = max(0, sel->r.left & ~1); in ccs_set_selection()
2617 sel->r.top = max(0, sel->r.top & ~1); in ccs_set_selection()
2618 sel->r.width = CCS_ALIGN_DIM(sel->r.width, sel->flags); in ccs_set_selection()
2619 sel->r.height = CCS_ALIGN_DIM(sel->r.height, sel->flags); in ccs_set_selection()
2621 sel->r.width = max_t(unsigned int, CCS_LIM(sensor, MIN_X_OUTPUT_SIZE), in ccs_set_selection()
2622 sel->r.width); in ccs_set_selection()
2623 sel->r.height = max_t(unsigned int, CCS_LIM(sensor, MIN_Y_OUTPUT_SIZE), in ccs_set_selection()
2624 sel->r.height); in ccs_set_selection()
2626 switch (sel->target) { in ccs_set_selection()
2634 ret = -EINVAL; in ccs_set_selection()
2637 mutex_unlock(&sensor->mutex); in ccs_set_selection()
2645 *frames = sensor->frame_skip; in ccs_get_skip_frames()
2653 *lines = sensor->image_start; in ccs_get_skip_top_lines()
2658 /* -----------------------------------------------------------------------------
2670 if (!sensor->dev_init_done) in nvm_show()
2671 return -EBUSY; in nvm_show()
2675 return -ENODEV; in nvm_show()
2679 pm_runtime_put(&client->dev); in nvm_show()
2680 dev_err(&client->dev, "nvm read failed\n"); in nvm_show()
2681 return -ENODEV; in nvm_show()
2684 pm_runtime_mark_last_busy(&client->dev); in nvm_show()
2685 pm_runtime_put_autosuspend(&client->dev); in nvm_show()
2700 struct ccs_module_info *minfo = &sensor->minfo; in ident_show()
2702 if (minfo->mipi_manufacturer_id) in ident_show()
2704 minfo->mipi_manufacturer_id, minfo->model_id, in ident_show()
2705 minfo->revision_number) + 1; in ident_show()
2708 minfo->smia_manufacturer_id, minfo->model_id, in ident_show()
2709 minfo->revision_number) + 1; in ident_show()
2713 /* -----------------------------------------------------------------------------
2719 struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd); in ccs_identify_module()
2720 struct ccs_module_info *minfo = &sensor->minfo; in ccs_identify_module()
2727 &minfo->mipi_manufacturer_id); in ccs_identify_module()
2728 if (!rval && !minfo->mipi_manufacturer_id) in ccs_identify_module()
2730 &minfo->smia_manufacturer_id); in ccs_identify_module()
2732 rval = ccs_read(sensor, MODULE_MODEL_ID, &minfo->model_id); in ccs_identify_module()
2737 &minfo->revision_number); in ccs_identify_module()
2738 minfo->revision_number |= rev << 8; in ccs_identify_module()
2741 rval = ccs_read(sensor, MODULE_DATE_YEAR, &minfo->module_year); in ccs_identify_module()
2744 &minfo->module_month); in ccs_identify_module()
2746 rval = ccs_read(sensor, MODULE_DATE_DAY, &minfo->module_day); in ccs_identify_module()
2751 &minfo->sensor_mipi_manufacturer_id); in ccs_identify_module()
2752 if (!rval && !minfo->sensor_mipi_manufacturer_id) in ccs_identify_module()
2754 &minfo->sensor_smia_manufacturer_id); in ccs_identify_module()
2757 &minfo->sensor_model_id); in ccs_identify_module()
2760 &minfo->sensor_revision_number); in ccs_identify_module()
2761 if (!rval && !minfo->sensor_revision_number) in ccs_identify_module()
2763 &minfo->sensor_revision_number); in ccs_identify_module()
2766 &minfo->sensor_firmware_version); in ccs_identify_module()
2770 rval = ccs_read(sensor, MIPI_CCS_VERSION, &minfo->ccs_version); in ccs_identify_module()
2771 if (!rval && !minfo->ccs_version) in ccs_identify_module()
2773 &minfo->smia_version); in ccs_identify_module()
2774 if (!rval && !minfo->ccs_version) in ccs_identify_module()
2776 &minfo->smiapp_version); in ccs_identify_module()
2779 dev_err(&client->dev, "sensor detection failed\n"); in ccs_identify_module()
2780 return -ENODEV; in ccs_identify_module()
2783 if (minfo->mipi_manufacturer_id) in ccs_identify_module()
2784 dev_dbg(&client->dev, "MIPI CCS module 0x%4.4x-0x%4.4x\n", in ccs_identify_module()
2785 minfo->mipi_manufacturer_id, minfo->model_id); in ccs_identify_module()
2787 dev_dbg(&client->dev, "SMIA module 0x%2.2x-0x%4.4x\n", in ccs_identify_module()
2788 minfo->smia_manufacturer_id, minfo->model_id); in ccs_identify_module()
2790 dev_dbg(&client->dev, in ccs_identify_module()
2791 "module revision 0x%4.4x date %2.2d-%2.2d-%2.2d\n", in ccs_identify_module()
2792 minfo->revision_number, minfo->module_year, minfo->module_month, in ccs_identify_module()
2793 minfo->module_day); in ccs_identify_module()
2795 if (minfo->sensor_mipi_manufacturer_id) in ccs_identify_module()
2796 dev_dbg(&client->dev, "MIPI CCS sensor 0x%4.4x-0x%4.4x\n", in ccs_identify_module()
2797 minfo->sensor_mipi_manufacturer_id, in ccs_identify_module()
2798 minfo->sensor_model_id); in ccs_identify_module()
2800 dev_dbg(&client->dev, "SMIA sensor 0x%2.2x-0x%4.4x\n", in ccs_identify_module()
2801 minfo->sensor_smia_manufacturer_id, in ccs_identify_module()
2802 minfo->sensor_model_id); in ccs_identify_module()
2804 dev_dbg(&client->dev, in ccs_identify_module()
2806 minfo->sensor_revision_number, minfo->sensor_firmware_version); in ccs_identify_module()
2808 if (minfo->ccs_version) { in ccs_identify_module()
2809 dev_dbg(&client->dev, "MIPI CCS version %u.%u", in ccs_identify_module()
2810 (minfo->ccs_version & CCS_MIPI_CCS_VERSION_MAJOR_MASK) in ccs_identify_module()
2812 (minfo->ccs_version & CCS_MIPI_CCS_VERSION_MINOR_MASK)); in ccs_identify_module()
2813 minfo->name = CCS_NAME; in ccs_identify_module()
2815 dev_dbg(&client->dev, in ccs_identify_module()
2817 minfo->smia_version, minfo->smiapp_version); in ccs_identify_module()
2818 minfo->name = SMIAPP_NAME; in ccs_identify_module()
2824 if (minfo->sensor_smia_manufacturer_id && in ccs_identify_module()
2825 !minfo->smia_manufacturer_id && !minfo->model_id) { in ccs_identify_module()
2826 minfo->smia_manufacturer_id = in ccs_identify_module()
2827 minfo->sensor_smia_manufacturer_id; in ccs_identify_module()
2828 minfo->model_id = minfo->sensor_model_id; in ccs_identify_module()
2829 minfo->revision_number = minfo->sensor_revision_number; in ccs_identify_module()
2836 != minfo->mipi_manufacturer_id) in ccs_identify_module()
2840 != minfo->smia_manufacturer_id) in ccs_identify_module()
2842 if (ccs_module_idents[i].model_id != minfo->model_id) in ccs_identify_module()
2847 < (minfo->revision_number >> 8)) in ccs_identify_module()
2851 != (minfo->revision_number >> 8)) in ccs_identify_module()
2855 minfo->name = ccs_module_idents[i].name; in ccs_identify_module()
2856 minfo->quirk = ccs_module_idents[i].quirk; in ccs_identify_module()
2861 dev_warn(&client->dev, in ccs_identify_module()
2864 dev_dbg(&client->dev, "the sensor is called %s\n", minfo->name); in ccs_identify_module()
2877 struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd); in ccs_register_subdev()
2883 rval = v4l2_device_register_subdev(sensor->src->sd.v4l2_dev, &ssd->sd); in ccs_register_subdev()
2885 dev_err(&client->dev, "v4l2_device_register_subdev failed\n"); in ccs_register_subdev()
2889 rval = media_create_pad_link(&ssd->sd.entity, source_pad, in ccs_register_subdev()
2890 &sink_ssd->sd.entity, sink_pad, in ccs_register_subdev()
2893 dev_err(&client->dev, "media_create_pad_link failed\n"); in ccs_register_subdev()
2894 v4l2_device_unregister_subdev(&ssd->sd); in ccs_register_subdev()
2906 for (i = 1; i < sensor->ssds_used; i++) in ccs_unregistered()
2907 v4l2_device_unregister_subdev(&sensor->ssds[i].sd); in ccs_unregistered()
2915 if (sensor->scaler) { in ccs_registered()
2916 rval = ccs_register_subdev(sensor, sensor->binner, in ccs_registered()
2917 sensor->scaler, in ccs_registered()
2925 rval = ccs_register_subdev(sensor, sensor->pixel_array, sensor->binner, in ccs_registered()
2942 struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd); in ccs_cleanup()
2945 for (i = 0; i < sensor->ssds_used; i++) { in ccs_cleanup()
2946 v4l2_subdev_cleanup(&sensor->ssds[2].sd); in ccs_cleanup()
2947 media_entity_cleanup(&sensor->ssds[i].sd.entity); in ccs_cleanup()
2950 device_remove_file(&client->dev, &dev_attr_nvm); in ccs_cleanup()
2951 device_remove_file(&client->dev, &dev_attr_ident); in ccs_cleanup()
2962 struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd); in ccs_init_subdev()
2968 if (ssd != sensor->src) in ccs_init_subdev()
2969 v4l2_subdev_init(&ssd->sd, &ccs_ops); in ccs_init_subdev()
2971 ssd->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; in ccs_init_subdev()
2972 ssd->sd.entity.function = function; in ccs_init_subdev()
2973 ssd->sensor = sensor; in ccs_init_subdev()
2975 ssd->npads = num_pads; in ccs_init_subdev()
2976 ssd->source_pad = num_pads - 1; in ccs_init_subdev()
2978 v4l2_i2c_subdev_set_name(&ssd->sd, client, sensor->minfo.name, name); in ccs_init_subdev()
2980 ssd->pads[ssd->source_pad].flags = MEDIA_PAD_FL_SOURCE; in ccs_init_subdev()
2981 if (ssd != sensor->pixel_array) in ccs_init_subdev()
2982 ssd->pads[ssd->sink_pad].flags = MEDIA_PAD_FL_SINK; in ccs_init_subdev()
2984 ssd->sd.entity.ops = &ccs_entity_ops; in ccs_init_subdev()
2986 if (ssd != sensor->src) { in ccs_init_subdev()
2987 ssd->sd.owner = THIS_MODULE; in ccs_init_subdev()
2988 ssd->sd.dev = &client->dev; in ccs_init_subdev()
2989 v4l2_set_subdevdata(&ssd->sd, client); in ccs_init_subdev()
2992 rval = media_entity_pads_init(&ssd->sd.entity, ssd->npads, ssd->pads); in ccs_init_subdev()
2994 dev_err(&client->dev, "media_entity_pads_init failed\n"); in ccs_init_subdev()
2998 rval = __v4l2_subdev_init_finalize(&ssd->sd, lock_name, lock_key); in ccs_init_subdev()
3000 media_entity_cleanup(&ssd->sd.entity); in ccs_init_subdev()
3011 struct ccs_sensor *sensor = ssd->sensor; in ccs_init_state()
3012 unsigned int pad = ssd == sensor->pixel_array ? in ccs_init_state()
3018 bool is_active = !sd->active_state || sd->active_state == sd_state; in ccs_init_state()
3020 mutex_lock(&sensor->mutex); in ccs_init_state()
3024 fmt->width = crop->width; in ccs_init_state()
3025 fmt->height = crop->height; in ccs_init_state()
3026 fmt->code = sensor->internal_csi_format->code; in ccs_init_state()
3027 fmt->field = V4L2_FIELD_NONE; in ccs_init_state()
3029 if (ssd == sensor->pixel_array) { in ccs_init_state()
3031 sensor->pa_src = *crop; in ccs_init_state()
3033 mutex_unlock(&sensor->mutex); in ccs_init_state()
3038 fmt->code = ssd == sensor->src ? in ccs_init_state()
3039 sensor->csi_format->code : sensor->internal_csi_format->code; in ccs_init_state()
3040 fmt->field = V4L2_FIELD_NONE; in ccs_init_state()
3044 mutex_unlock(&sensor->mutex); in ccs_init_state()
3084 /* -----------------------------------------------------------------------------
3090 struct ccs_hwconfig *hwcfg = &sensor->hwcfg; in ccs_get_hwconfig()
3100 return -ENODEV; in ccs_get_hwconfig()
3103 * Note that we do need to rely on detecting the bus type between CSI-2 in ccs_get_hwconfig()
3104 * D-PHY and CCP2 as the old bindings did not require it. in ccs_get_hwconfig()
3112 hwcfg->csi_signalling_mode = CCS_CSI_SIGNALING_MODE_CSI_2_DPHY; in ccs_get_hwconfig()
3113 hwcfg->lanes = bus_cfg.bus.mipi_csi2.num_data_lanes; in ccs_get_hwconfig()
3116 hwcfg->csi_signalling_mode = CCS_CSI_SIGNALING_MODE_CSI_2_CPHY; in ccs_get_hwconfig()
3117 hwcfg->lanes = bus_cfg.bus.mipi_csi2.num_data_lanes; in ccs_get_hwconfig()
3121 hwcfg->csi_signalling_mode = (bus_cfg.bus.mipi_csi1.strobe) ? in ccs_get_hwconfig()
3124 hwcfg->lanes = 1; in ccs_get_hwconfig()
3128 rval = -EINVAL; in ccs_get_hwconfig()
3132 rval = fwnode_property_read_u32(dev_fwnode(dev), "clock-frequency", in ccs_get_hwconfig()
3133 &hwcfg->ext_clk); in ccs_get_hwconfig()
3135 dev_info(dev, "can't get clock-frequency\n"); in ccs_get_hwconfig()
3137 dev_dbg(dev, "clk %u, mode %u\n", hwcfg->ext_clk, in ccs_get_hwconfig()
3138 hwcfg->csi_signalling_mode); in ccs_get_hwconfig()
3142 rval = -EINVAL; in ccs_get_hwconfig()
3146 hwcfg->op_sys_clock = devm_kcalloc( in ccs_get_hwconfig()
3148 sizeof(*hwcfg->op_sys_clock), GFP_KERNEL); in ccs_get_hwconfig()
3149 if (!hwcfg->op_sys_clock) { in ccs_get_hwconfig()
3150 rval = -ENOMEM; in ccs_get_hwconfig()
3155 hwcfg->op_sys_clock[i] = bus_cfg.link_frequencies[i]; in ccs_get_hwconfig()
3156 dev_dbg(dev, "freq %u: %lld\n", i, hwcfg->op_sys_clock[i]); in ccs_get_hwconfig()
3175 const struct ccs_device *ccsdev = device_get_match_data(&client->dev); in ccs_firmware_name()
3176 bool is_ccs = !(ccsdev->flags & CCS_DEVICE_FLAG_IS_SMIA); in ccs_firmware_name()
3177 bool is_smiapp = sensor->minfo.smiapp_version; in ccs_firmware_name()
3183 * Old SMIA is module-agnostic. Its sensor identification is based on in ccs_firmware_name()
3188 sensor->minfo.mipi_manufacturer_id : in ccs_firmware_name()
3189 sensor->minfo.smia_manufacturer_id; in ccs_firmware_name()
3190 model_id = sensor->minfo.model_id; in ccs_firmware_name()
3191 revision_number = sensor->minfo.revision_number; in ccs_firmware_name()
3194 sensor->minfo.sensor_mipi_manufacturer_id : in ccs_firmware_name()
3195 sensor->minfo.sensor_smia_manufacturer_id; in ccs_firmware_name()
3196 model_id = sensor->minfo.sensor_model_id; in ccs_firmware_name()
3197 revision_number = sensor->minfo.sensor_revision_number; in ccs_firmware_name()
3201 "ccs/%s-%s-%0*x-%4.4x-%0*x.fw", in ccs_firmware_name()
3213 const struct ccs_device *ccsdev = device_get_match_data(&client->dev); in ccs_probe()
3220 sensor = devm_kzalloc(&client->dev, sizeof(*sensor), GFP_KERNEL); in ccs_probe()
3222 return -ENOMEM; in ccs_probe()
3224 rval = ccs_get_hwconfig(sensor, &client->dev); in ccs_probe()
3228 sensor->src = &sensor->ssds[sensor->ssds_used]; in ccs_probe()
3230 v4l2_i2c_subdev_init(&sensor->src->sd, client, &ccs_ops); in ccs_probe()
3231 sensor->src->sd.internal_ops = &ccs_internal_src_ops; in ccs_probe()
3233 sensor->regulators = devm_kcalloc(&client->dev, in ccs_probe()
3235 sizeof(*sensor->regulators), in ccs_probe()
3237 if (!sensor->regulators) in ccs_probe()
3238 return -ENOMEM; in ccs_probe()
3241 sensor->regulators[i].supply = ccs_regulators[i]; in ccs_probe()
3243 rval = devm_regulator_bulk_get(&client->dev, ARRAY_SIZE(ccs_regulators), in ccs_probe()
3244 sensor->regulators); in ccs_probe()
3246 dev_err(&client->dev, "could not get regulators\n"); in ccs_probe()
3250 sensor->ext_clk = devm_clk_get(&client->dev, NULL); in ccs_probe()
3251 if (PTR_ERR(sensor->ext_clk) == -ENOENT) { in ccs_probe()
3252 dev_info(&client->dev, "no clock defined, continuing...\n"); in ccs_probe()
3253 sensor->ext_clk = NULL; in ccs_probe()
3254 } else if (IS_ERR(sensor->ext_clk)) { in ccs_probe()
3255 dev_err(&client->dev, "could not get clock (%ld)\n", in ccs_probe()
3256 PTR_ERR(sensor->ext_clk)); in ccs_probe()
3257 return -EPROBE_DEFER; in ccs_probe()
3260 if (sensor->ext_clk) { in ccs_probe()
3261 if (sensor->hwcfg.ext_clk) { in ccs_probe()
3264 rval = clk_set_rate(sensor->ext_clk, in ccs_probe()
3265 sensor->hwcfg.ext_clk); in ccs_probe()
3267 dev_err(&client->dev, in ccs_probe()
3269 sensor->hwcfg.ext_clk); in ccs_probe()
3273 rate = clk_get_rate(sensor->ext_clk); in ccs_probe()
3274 if (rate != sensor->hwcfg.ext_clk) { in ccs_probe()
3275 dev_err(&client->dev, in ccs_probe()
3277 sensor->hwcfg.ext_clk, rate); in ccs_probe()
3278 return -EINVAL; in ccs_probe()
3281 sensor->hwcfg.ext_clk = clk_get_rate(sensor->ext_clk); in ccs_probe()
3282 dev_dbg(&client->dev, "obtained clock freq %u\n", in ccs_probe()
3283 sensor->hwcfg.ext_clk); in ccs_probe()
3285 } else if (sensor->hwcfg.ext_clk) { in ccs_probe()
3286 dev_dbg(&client->dev, "assuming clock freq %u\n", in ccs_probe()
3287 sensor->hwcfg.ext_clk); in ccs_probe()
3289 dev_err(&client->dev, "unable to obtain clock freq\n"); in ccs_probe()
3290 return -EINVAL; in ccs_probe()
3293 if (!sensor->hwcfg.ext_clk) { in ccs_probe()
3294 dev_err(&client->dev, "cannot work with xclk frequency 0\n"); in ccs_probe()
3295 return -EINVAL; in ccs_probe()
3298 sensor->reset = devm_gpiod_get_optional(&client->dev, "reset", in ccs_probe()
3300 if (IS_ERR(sensor->reset)) in ccs_probe()
3301 return PTR_ERR(sensor->reset); in ccs_probe()
3303 if (!sensor->reset) in ccs_probe()
3304 sensor->xshutdown = devm_gpiod_get_optional(&client->dev, in ccs_probe()
3307 if (IS_ERR(sensor->xshutdown)) in ccs_probe()
3308 return PTR_ERR(sensor->xshutdown); in ccs_probe()
3310 sensor->regmap = devm_cci_regmap_init_i2c(client, 16); in ccs_probe()
3311 if (IS_ERR(sensor->regmap)) { in ccs_probe()
3312 dev_err(&client->dev, "can't initialise CCI (%ld)\n", in ccs_probe()
3313 PTR_ERR(sensor->regmap)); in ccs_probe()
3314 return PTR_ERR(sensor->regmap); in ccs_probe()
3317 rval = ccs_power_on(&client->dev); in ccs_probe()
3321 mutex_init(&sensor->mutex); in ccs_probe()
3325 rval = -ENODEV; in ccs_probe()
3332 rval = -ENOMEM; in ccs_probe()
3336 rval = request_firmware(&fw, filename, &client->dev); in ccs_probe()
3338 ccs_data_parse(&sensor->sdata, fw->data, fw->size, &client->dev, in ccs_probe()
3343 if (!(ccsdev->flags & CCS_DEVICE_FLAG_IS_SMIA) || in ccs_probe()
3344 sensor->minfo.smiapp_version) { in ccs_probe()
3348 rval = -ENOMEM; in ccs_probe()
3352 rval = request_firmware(&fw, filename, &client->dev); in ccs_probe()
3354 ccs_data_parse(&sensor->mdata, fw->data, fw->size, in ccs_probe()
3355 &client->dev, true); in ccs_probe()
3366 rval = -ENODEV; in ccs_probe()
3376 dev_err(&client->dev, "limits quirks failed\n"); in ccs_probe()
3381 sensor->nbinning_subtypes = in ccs_probe()
3385 for (i = 0; i < sensor->nbinning_subtypes; i++) { in ccs_probe()
3386 sensor->binning_subtypes[i].horizontal = in ccs_probe()
3389 sensor->binning_subtypes[i].vertical = in ccs_probe()
3393 dev_dbg(&client->dev, "binning %xx%x\n", in ccs_probe()
3394 sensor->binning_subtypes[i].horizontal, in ccs_probe()
3395 sensor->binning_subtypes[i].vertical); in ccs_probe()
3398 sensor->binning_horizontal = 1; in ccs_probe()
3399 sensor->binning_vertical = 1; in ccs_probe()
3401 if (device_create_file(&client->dev, &dev_attr_ident) != 0) { in ccs_probe()
3402 dev_err(&client->dev, "sysfs ident entry creation failed\n"); in ccs_probe()
3403 rval = -ENOENT; in ccs_probe()
3407 if (sensor->minfo.smiapp_version && in ccs_probe()
3410 if (device_create_file(&client->dev, &dev_attr_nvm) != 0) { in ccs_probe()
3411 dev_err(&client->dev, "sysfs nvm entry failed\n"); in ccs_probe()
3412 rval = -EBUSY; in ccs_probe()
3422 sensor->pll.flags |= CCS_PLL_FLAG_NO_OP_CLOCKS; in ccs_probe()
3428 sensor->scaler = &sensor->ssds[sensor->ssds_used]; in ccs_probe()
3429 sensor->ssds_used++; in ccs_probe()
3431 sensor->binner = &sensor->ssds[sensor->ssds_used]; in ccs_probe()
3432 sensor->ssds_used++; in ccs_probe()
3433 sensor->pixel_array = &sensor->ssds[sensor->ssds_used]; in ccs_probe()
3434 sensor->ssds_used++; in ccs_probe()
3436 sensor->scale_m = CCS_LIM(sensor, SCALER_N_MIN); in ccs_probe()
3439 sensor->pll.bus_type = CCS_PLL_BUS_TYPE_CSI2_DPHY; in ccs_probe()
3440 sensor->pll.csi2.lanes = sensor->hwcfg.lanes; in ccs_probe()
3443 sensor->pll.flags |= CCS_PLL_FLAG_LANE_SPEED_MODEL; in ccs_probe()
3446 sensor->pll.vt_lanes = in ccs_probe()
3448 sensor->pll.op_lanes = in ccs_probe()
3450 sensor->pll.flags |= CCS_PLL_FLAG_LINK_DECOUPLED; in ccs_probe()
3452 sensor->pll.vt_lanes = sensor->pll.csi2.lanes; in ccs_probe()
3453 sensor->pll.op_lanes = sensor->pll.csi2.lanes; in ccs_probe()
3458 sensor->pll.flags |= CCS_PLL_FLAG_EXT_IP_PLL_DIVIDER; in ccs_probe()
3461 sensor->pll.flags |= CCS_PLL_FLAG_FLEXIBLE_OP_PIX_CLK_DIV; in ccs_probe()
3464 sensor->pll.flags |= CCS_PLL_FLAG_FIFO_DERATING; in ccs_probe()
3467 sensor->pll.flags |= CCS_PLL_FLAG_FIFO_DERATING | in ccs_probe()
3481 sensor->pll.flags |= CCS_PLL_FLAG_DUAL_PLL; in ccs_probe()
3483 sensor->pll.flags |= CCS_PLL_FLAG_DUAL_PLL; in ccs_probe()
3487 sensor->pll.flags |= CCS_PLL_FLAG_OP_SYS_DDR; in ccs_probe()
3490 sensor->pll.flags |= CCS_PLL_FLAG_OP_PIX_DDR; in ccs_probe()
3492 sensor->pll.op_bits_per_lane = CCS_LIM(sensor, OP_BITS_PER_LANE); in ccs_probe()
3493 sensor->pll.ext_clk_freq_hz = sensor->hwcfg.ext_clk; in ccs_probe()
3494 sensor->pll.scale_n = CCS_LIM(sensor, SCALER_N_MIN); in ccs_probe()
3498 rval = -ENODEV; in ccs_probe()
3502 rval = ccs_init_subdev(sensor, sensor->scaler, " scaler", 2, in ccs_probe()
3507 rval = ccs_init_subdev(sensor, sensor->binner, " binner", 2, in ccs_probe()
3512 rval = ccs_init_subdev(sensor, sensor->pixel_array, " pixel_array", 1, in ccs_probe()
3528 rval = -ENODEV; in ccs_probe()
3532 mutex_lock(&sensor->mutex); in ccs_probe()
3534 mutex_unlock(&sensor->mutex); in ccs_probe()
3536 dev_err(&client->dev, "update mode failed\n"); in ccs_probe()
3540 sensor->streaming = false; in ccs_probe()
3541 sensor->dev_init_done = true; in ccs_probe()
3542 sensor->handler_setup_needed = true; in ccs_probe()
3548 pm_runtime_set_active(&client->dev); in ccs_probe()
3549 pm_runtime_get_noresume(&client->dev); in ccs_probe()
3550 pm_runtime_enable(&client->dev); in ccs_probe()
3552 rval = v4l2_async_register_subdev_sensor(&sensor->src->sd); in ccs_probe()
3556 pm_runtime_set_autosuspend_delay(&client->dev, 1000); in ccs_probe()
3557 pm_runtime_use_autosuspend(&client->dev); in ccs_probe()
3558 pm_runtime_put_autosuspend(&client->dev); in ccs_probe()
3563 pm_runtime_put_noidle(&client->dev); in ccs_probe()
3564 pm_runtime_disable(&client->dev); in ccs_probe()
3570 kvfree(sensor->mdata.backing); in ccs_probe()
3573 kvfree(sensor->sdata.backing); in ccs_probe()
3576 kfree(sensor->ccs_limits); in ccs_probe()
3579 ccs_power_off(&client->dev); in ccs_probe()
3580 mutex_destroy(&sensor->mutex); in ccs_probe()
3593 pm_runtime_disable(&client->dev); in ccs_remove()
3594 if (!pm_runtime_status_suspended(&client->dev)) in ccs_remove()
3595 ccs_power_off(&client->dev); in ccs_remove()
3596 pm_runtime_set_suspended(&client->dev); in ccs_remove()
3598 for (i = 0; i < sensor->ssds_used; i++) in ccs_remove()
3599 v4l2_device_unregister_subdev(&sensor->ssds[i].sd); in ccs_remove()
3601 mutex_destroy(&sensor->mutex); in ccs_remove()
3602 kfree(sensor->ccs_limits); in ccs_remove()
3603 kvfree(sensor->sdata.backing); in ccs_remove()
3604 kvfree(sensor->mdata.backing); in ccs_remove()
3620 { .compatible = "mipi-ccs-1.1", .data = &ccs_device },
3621 { .compatible = "mipi-ccs-1.0", .data = &ccs_device },
3622 { .compatible = "mipi-ccs", .data = &ccs_device },
3665 return -EINVAL; in ccs_module_init()
3668 return -EINVAL; in ccs_module_init()