Lines Matching +full:media +full:- +full:blk +full:- +full:ctrl
1 // SPDX-License-Identifier: GPL-2.0
18 #include <media/v4l2-cci.h>
19 #include <media/v4l2-ctrls.h>
20 #include <media/v4l2-device.h>
21 #include <media/v4l2-fwnode.h>
22 #include <media/v4l2-subdev.h>
74 /* BLK */
121 /* ASDE - Auto Saturation De-noise and Edge-Enhancement */
132 /* INTPEE - Interpolation and Edge-Enhancement */
145 /* ABB - Auto Black Balance */
158 /* LSC - Lens Shading Correction */
168 /* CC - Channel Coefficient */
228 /* AEC - Automatic Exposure Control */
283 /* AWB (P1) - Auto White Balance */
322 * BT = EXP_TIME - height - 8 - VS_START_TIME + VS_END_TIME
347 -4, -3, -2, -1, 0, 1, 2, 3, 4
774 ret = regulator_enable(gc0308->vdd); in gc0308_power_on()
778 ret = clk_prepare_enable(gc0308->clk); in gc0308_power_on()
782 gpiod_set_value_cansleep(gc0308->pwdn_gpio, 0); in gc0308_power_on()
785 gpiod_set_value_cansleep(gc0308->reset_gpio, 1); in gc0308_power_on()
787 gpiod_set_value_cansleep(gc0308->reset_gpio, 0); in gc0308_power_on()
793 regulator_disable(gc0308->vdd); in gc0308_power_on()
801 gpiod_set_value_cansleep(gc0308->pwdn_gpio, 1); in gc0308_power_off()
802 clk_disable_unprepare(gc0308->clk); in gc0308_power_off()
803 regulator_disable(gc0308->vdd); in gc0308_power_off()
814 return cci_read(gc0308->regmap, CCI_REG8(reg->reg), ®->val, NULL); in gc0308_g_register()
822 return cci_write(gc0308->regmap, CCI_REG8(reg->reg), reg->val, NULL); in gc0308_s_register()
830 {GC0308_LUMA_OFFSET, regs->luma_offset}, in gc0308_set_exposure()
831 {GC0308_AEC_TARGET_Y, regs->aec_target_y}, in gc0308_set_exposure()
834 return cci_multi_reg_write(gc0308->regmap, exposure_reg_seq, in gc0308_set_exposure()
843 {GC0308_AWB_R_GAIN, regs->r}, in gc0308_set_awb_mode()
844 {GC0308_AWB_G_GAIN, regs->g}, in gc0308_set_awb_mode()
845 {GC0308_AWB_B_GAIN, regs->b}, in gc0308_set_awb_mode()
849 ret = cci_update_bits(gc0308->regmap, GC0308_AAAA_EN, in gc0308_set_awb_mode()
851 ret = cci_multi_reg_write(gc0308->regmap, awb_reg_seq, in gc0308_set_awb_mode()
861 {GC0308_SPECIAL_EFFECT, regs->special_effect}, in gc0308_set_colormode()
862 {GC0308_DEBUG_MODE1, regs->dbg_mode1}, in gc0308_set_colormode()
863 {GC0308_BLOCK_EN1, regs->block_en1}, in gc0308_set_colormode()
864 {GC0308_AEC_MODE3, regs->aec_mode3}, in gc0308_set_colormode()
865 {GC0308_EEINTP_MODE_2, regs->eeintp_mode_2}, in gc0308_set_colormode()
866 {GC0308_EDGE12_EFFECT, regs->edge12_effect}, in gc0308_set_colormode()
867 {GC0308_LUMA_CONTRAST, regs->luma_contrast}, in gc0308_set_colormode()
868 {GC0308_CONTRAST_CENTER, regs->contrast_center}, in gc0308_set_colormode()
869 {GC0308_FIXED_CB, regs->fixed_cb}, in gc0308_set_colormode()
870 {GC0308_FIXED_CR, regs->fixed_cr}, in gc0308_set_colormode()
873 return cci_multi_reg_write(gc0308->regmap, colormode_reg_seq, in gc0308_set_colormode()
896 return cci_multi_reg_write(gc0308->regmap, pwr_line_60hz, in gc0308_set_power_line_freq()
899 return cci_multi_reg_write(gc0308->regmap, pwr_line_50hz, in gc0308_set_power_line_freq()
903 return -EINVAL; in gc0308_set_power_line_freq()
910 if (gc0308->vflip->val) in gc0308_update_mirror()
913 if (gc0308->hflip->val) in gc0308_update_mirror()
916 return cci_update_bits(gc0308->regmap, GC0308_CISCTL_MODE1, in gc0308_update_mirror()
922 u16 vblank = gc0308->vblank->val; in gc0308_update_blanking()
923 u16 hblank = gc0308->hblank->val; in gc0308_update_blanking()
927 cci_write(gc0308->regmap, GC0308_VB_HB, vbhb, &ret); in gc0308_update_blanking()
928 cci_write(gc0308->regmap, GC0308_HBLANK, hblank & 0xff, &ret); in gc0308_update_blanking()
929 cci_write(gc0308->regmap, GC0308_VBLANK, vblank & 0xff, &ret); in gc0308_update_blanking()
934 static int _gc0308_s_ctrl(struct v4l2_ctrl *ctrl) in _gc0308_s_ctrl() argument
936 struct gc0308 *gc0308 = container_of(ctrl->handler, struct gc0308, hdl); in _gc0308_s_ctrl()
937 u8 flipval = ctrl->val ? 0xff : 0x00; in _gc0308_s_ctrl()
939 switch (ctrl->id) { in _gc0308_s_ctrl()
947 return cci_update_bits(gc0308->regmap, GC0308_AAAA_EN, in _gc0308_s_ctrl()
950 return gc0308_set_awb_mode(gc0308, ctrl->val); in _gc0308_s_ctrl()
952 return gc0308_set_power_line_freq(gc0308, ctrl->val); in _gc0308_s_ctrl()
954 return gc0308_set_colormode(gc0308, ctrl->val); in _gc0308_s_ctrl()
956 return cci_update_bits(gc0308->regmap, GC0308_DEBUG_MODE2, in _gc0308_s_ctrl()
957 GENMASK(1, 0), ctrl->val, NULL); in _gc0308_s_ctrl()
959 return gc0308_set_exposure(gc0308, ctrl->val); in _gc0308_s_ctrl()
962 return -EINVAL; in _gc0308_s_ctrl()
965 static int gc0308_s_ctrl(struct v4l2_ctrl *ctrl) in gc0308_s_ctrl() argument
967 struct gc0308 *gc0308 = container_of(ctrl->handler, struct gc0308, hdl); in gc0308_s_ctrl()
970 if (!pm_runtime_get_if_in_use(gc0308->dev)) in gc0308_s_ctrl()
973 ret = _gc0308_s_ctrl(ctrl); in gc0308_s_ctrl()
975 dev_err(gc0308->dev, "failed to set control: %d\n", ret); in gc0308_s_ctrl()
977 pm_runtime_mark_last_busy(gc0308->dev); in gc0308_s_ctrl()
978 pm_runtime_put_autosuspend(gc0308->dev); in gc0308_s_ctrl()
999 if (code->index >= ARRAY_SIZE(gc0308_formats)) in gc0308_enum_mbus_code()
1000 return -EINVAL; in gc0308_enum_mbus_code()
1002 code->code = gc0308_formats[code->index].code; in gc0308_enum_mbus_code()
1016 return -1; in gc0308_get_format_idx()
1023 if (fse->index >= ARRAY_SIZE(gc0308_frame_sizes)) in gc0308_enum_frame_size()
1024 return -EINVAL; in gc0308_enum_frame_size()
1026 if (gc0308_get_format_idx(fse->code) < 0) in gc0308_enum_frame_size()
1027 return -EINVAL; in gc0308_enum_frame_size()
1029 fse->min_width = gc0308_frame_sizes[fse->index].width; in gc0308_enum_frame_size()
1030 fse->max_width = gc0308_frame_sizes[fse->index].width; in gc0308_enum_frame_size()
1031 fse->min_height = gc0308_frame_sizes[fse->index].height; in gc0308_enum_frame_size()
1032 fse->max_height = gc0308_frame_sizes[fse->index].height; in gc0308_enum_frame_size()
1040 fmt->width = mode->width; in gc0308_update_pad_format()
1041 fmt->height = mode->height; in gc0308_update_pad_format()
1042 fmt->code = code; in gc0308_update_pad_format()
1043 fmt->field = V4L2_FIELD_NONE; in gc0308_update_pad_format()
1044 fmt->colorspace = V4L2_COLORSPACE_SRGB; in gc0308_update_pad_format()
1053 int i = gc0308_get_format_idx(fmt->format.code); in gc0308_set_format()
1060 height, fmt->format.width, in gc0308_set_format()
1061 fmt->format.height); in gc0308_set_format()
1063 gc0308_update_pad_format(mode, &fmt->format, gc0308_formats[i].code); in gc0308_set_format()
1064 *v4l2_subdev_state_get_format(sd_state, 0) = fmt->format; in gc0308_set_format()
1066 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) in gc0308_set_format()
1069 gc0308->mode.out_format = gc0308_formats[i].regval; in gc0308_set_format()
1070 gc0308->mode.subsample = mode->subsample; in gc0308_set_format()
1071 gc0308->mode.width = mode->width; in gc0308_set_format()
1072 gc0308->mode.height = mode->height; in gc0308_set_format()
1083 format->width = 640; in gc0308_init_state()
1084 format->height = 480; in gc0308_init_state()
1085 format->code = gc0308_formats[0].code; in gc0308_init_state()
1086 format->colorspace = V4L2_COLORSPACE_SRGB; in gc0308_init_state()
1087 format->field = V4L2_FIELD_NONE; in gc0308_init_state()
1088 format->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; in gc0308_init_state()
1089 format->quantization = V4L2_QUANTIZATION_DEFAULT; in gc0308_init_state()
1090 format->xfer_func = V4L2_XFER_FUNC_DEFAULT; in gc0308_init_state()
1105 {GC0308_SUBSAMPLE, gc0308->mode.subsample}, in gc0308_set_resolution()
1114 {GC0308_CROP_WIN_HEIGHT, gc0308->mode.height}, in gc0308_set_resolution()
1115 {GC0308_CROP_WIN_WIDTH, gc0308->mode.width}, in gc0308_set_resolution()
1118 return cci_multi_reg_write(gc0308->regmap, resolution_regs, in gc0308_set_resolution()
1126 ret = pm_runtime_resume_and_get(gc0308->dev); in gc0308_start_stream()
1130 cci_multi_reg_write(gc0308->regmap, sensor_default_regs, in gc0308_start_stream()
1132 cci_update_bits(gc0308->regmap, GC0308_OUT_FORMAT, in gc0308_start_stream()
1133 GENMASK(4, 0), gc0308->mode.out_format, &ret); in gc0308_start_stream()
1137 dev_err(gc0308->dev, "failed to update registers: %d\n", ret); in gc0308_start_stream()
1141 ret = __v4l2_ctrl_handler_setup(&gc0308->hdl); in gc0308_start_stream()
1143 dev_err(gc0308->dev, "failed to setup controls\n"); in gc0308_start_stream()
1149 if (gc0308->mbus_config & V4L2_MBUS_VSYNC_ACTIVE_LOW) in gc0308_start_stream()
1151 if (gc0308->mbus_config & V4L2_MBUS_HSYNC_ACTIVE_LOW) in gc0308_start_stream()
1153 ret = cci_write(gc0308->regmap, GC0308_SYNC_MODE, sync_mode, NULL); in gc0308_start_stream()
1160 pm_runtime_mark_last_busy(gc0308->dev); in gc0308_start_stream()
1161 pm_runtime_put_autosuspend(gc0308->dev); in gc0308_start_stream()
1167 pm_runtime_mark_last_busy(gc0308->dev); in gc0308_stop_stream()
1168 pm_runtime_put_autosuspend(gc0308->dev); in gc0308_stop_stream()
1205 struct device *dev = gc0308->dev; in gc0308_bus_config()
1214 return -EINVAL; in gc0308_bus_config()
1221 gc0308->mbus_config = bus_cfg.bus.parallel.flags; in gc0308_bus_config()
1236 v4l2_ctrl_handler_init(&gc0308->hdl, 11); in gc0308_init_controls()
1237 gc0308->hblank = v4l2_ctrl_new_std(&gc0308->hdl, &gc0308_ctrl_ops, in gc0308_init_controls()
1241 gc0308->vblank = v4l2_ctrl_new_std(&gc0308->hdl, &gc0308_ctrl_ops, in gc0308_init_controls()
1245 gc0308->hflip = v4l2_ctrl_new_std(&gc0308->hdl, &gc0308_ctrl_ops, in gc0308_init_controls()
1247 gc0308->vflip = v4l2_ctrl_new_std(&gc0308->hdl, &gc0308_ctrl_ops, in gc0308_init_controls()
1249 v4l2_ctrl_new_std(&gc0308->hdl, &gc0308_ctrl_ops, V4L2_CID_PIXEL_RATE, in gc0308_init_controls()
1252 v4l2_ctrl_new_std(&gc0308->hdl, &gc0308_ctrl_ops, in gc0308_init_controls()
1254 v4l2_ctrl_new_std_menu_items(&gc0308->hdl, &gc0308_ctrl_ops, in gc0308_init_controls()
1256 ARRAY_SIZE(gc0308_test_pattern_menu) - 1, in gc0308_init_controls()
1258 v4l2_ctrl_new_std_menu(&gc0308->hdl, &gc0308_ctrl_ops, in gc0308_init_controls()
1261 v4l2_ctrl_new_std_menu(&gc0308->hdl, &gc0308_ctrl_ops, in gc0308_init_controls()
1263 v4l2_ctrl_new_std_menu(&gc0308->hdl, &gc0308_ctrl_ops, in gc0308_init_controls()
1267 v4l2_ctrl_new_int_menu(&gc0308->hdl, &gc0308_ctrl_ops, in gc0308_init_controls()
1269 ARRAY_SIZE(gc0308_exposure_menu) - 1, in gc0308_init_controls()
1273 gc0308->sd.ctrl_handler = &gc0308->hdl; in gc0308_init_controls()
1274 if (gc0308->hdl.error) { in gc0308_init_controls()
1275 ret = gc0308->hdl.error; in gc0308_init_controls()
1276 v4l2_ctrl_handler_free(&gc0308->hdl); in gc0308_init_controls()
1280 v4l2_ctrl_cluster(2, &gc0308->hflip); in gc0308_init_controls()
1281 v4l2_ctrl_cluster(2, &gc0308->hblank); in gc0308_init_controls()
1288 struct device *dev = &client->dev; in gc0308_probe()
1296 return -ENOMEM; in gc0308_probe()
1298 gc0308->dev = dev; in gc0308_probe()
1305 gc0308->clk = devm_clk_get_optional(dev, NULL); in gc0308_probe()
1306 if (IS_ERR(gc0308->clk)) in gc0308_probe()
1307 return dev_err_probe(dev, PTR_ERR(gc0308->clk), in gc0308_probe()
1310 gc0308->vdd = devm_regulator_get(dev, "vdd28"); in gc0308_probe()
1311 if (IS_ERR(gc0308->vdd)) in gc0308_probe()
1312 return dev_err_probe(dev, PTR_ERR(gc0308->vdd), in gc0308_probe()
1315 gc0308->pwdn_gpio = devm_gpiod_get(dev, "powerdown", GPIOD_OUT_LOW); in gc0308_probe()
1316 if (IS_ERR(gc0308->pwdn_gpio)) in gc0308_probe()
1317 return dev_err_probe(dev, PTR_ERR(gc0308->pwdn_gpio), in gc0308_probe()
1320 gc0308->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); in gc0308_probe()
1321 if (IS_ERR(gc0308->reset_gpio)) in gc0308_probe()
1322 return dev_err_probe(dev, PTR_ERR(gc0308->reset_gpio), in gc0308_probe()
1330 gc0308->regmap = devm_regmap_init_i2c(client, &gc0308_regmap_config); in gc0308_probe()
1331 if (IS_ERR(gc0308->regmap)) in gc0308_probe()
1332 return dev_err_probe(dev, PTR_ERR(gc0308->regmap), in gc0308_probe()
1335 v4l2_i2c_subdev_init(&gc0308->sd, client, &gc0308_subdev_ops); in gc0308_probe()
1336 gc0308->sd.internal_ops = &gc0308_internal_ops; in gc0308_probe()
1337 gc0308->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; in gc0308_probe()
1343 gc0308->sd.state_lock = gc0308->hdl.lock; in gc0308_probe()
1344 gc0308->pad.flags = MEDIA_PAD_FL_SOURCE; in gc0308_probe()
1345 gc0308->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; in gc0308_probe()
1346 ret = media_entity_pads_init(&gc0308->sd.entity, 1, &gc0308->pad); in gc0308_probe()
1350 ret = v4l2_subdev_init_finalize(&gc0308->sd); in gc0308_probe()
1358 if (gc0308->clk) { in gc0308_probe()
1359 clkrate = clk_get_rate(gc0308->clk); in gc0308_probe()
1364 ret = cci_read(gc0308->regmap, GC0308_CHIP_ID, ®val, NULL); in gc0308_probe()
1371 ret = -EINVAL; in gc0308_probe()
1387 ret = v4l2_async_register_subdev(&gc0308->sd); in gc0308_probe()
1401 v4l2_subdev_cleanup(&gc0308->sd); in gc0308_probe()
1403 media_entity_cleanup(&gc0308->sd.entity); in gc0308_probe()
1405 v4l2_ctrl_handler_free(&gc0308->hdl); in gc0308_probe()
1412 struct device *dev = &client->dev; in gc0308_remove()
1414 v4l2_async_unregister_subdev(&gc0308->sd); in gc0308_remove()
1415 v4l2_ctrl_handler_free(&gc0308->hdl); in gc0308_remove()
1416 media_entity_cleanup(&gc0308->sd.entity); in gc0308_remove()