• Home
  • Raw
  • Download

Lines Matching +full:reference +full:- +full:div +full:- +full:factor

1 // SPDX-License-Identifier: GPL-2.0
12 * Copyright 2006-7 Jonathan Corbet <corbet@lwn.net>
26 #include <linux/v4l2-mediabus.h>
31 #include <media/v4l2-ctrls.h>
32 #include <media/v4l2-device.h>
33 #include <media/v4l2-event.h>
34 #include <media/v4l2-image-sizes.h>
35 #include <media/v4l2-subdev.h>
40 #define GAIN 0x00 /* AGC - Gain control gain setting */
41 #define BLUE 0x01 /* AWB - Blue channel gain setting */
42 #define RED 0x02 /* AWB - Red channel gain setting */
43 #define GREEN 0x03 /* AWB - Green channel gain setting */
48 #define AECH 0x08 /* Exposure Value - AEC MSBs */
64 #define HSIZE 0x18 /* Horizontal frame (HREF column) end high 8-bit */
65 #define VSTART 0x19 /* Vertical frame (row) start high 8-bit */
67 #define PSHFT 0x1B /* Data format - pixel delay select */
68 #define MIDH 0x1C /* Manufacturer ID byte - high */
69 #define MIDL 0x1D /* Manufacturer ID byte - low */
74 #define AEW 0x24 /* AGC/AEC - Stable operating region (upper limit) */
75 #define AEB 0x25 /* AGC/AEC - Stable operating region (lower limit) */
109 #define LCC1 0x47 /* Lens correction option 1 - X coordinate */
110 #define LCC2 0x48 /* Lens correction option 2 - Y coordinate */
112 #define LCC4 0x4A /* Lens correction option 4 - radius of the circular */
125 #define AREF0 0x4E /* Sensor reference control */
126 #define AREF1 0x4F /* Sensor reference current control */
127 #define AREF2 0x50 /* Analog reference control */
128 #define AREF3 0x51 /* ADC reference control */
129 #define AREF4 0x52 /* ADC reference control */
130 #define AREF5 0x53 /* ADC reference control */
131 #define AREF6 0x54 /* Analog reference control */
132 #define AREF7 0x55 /* Analog reference control */
179 #define DNSTH 0x8E /* De-noise threshold */
182 #define DNSOFF 0x91 /* Auto De-noise threshold control */
236 /* Tri-state option for output clock */
237 #define NOTRI_CLOCK 0x04 /* 0: Tri-state at this period */
238 /* 1: No tri-state at this period */
239 /* Tri-state option for output data */
240 #define NOTRI_DATA 0x02 /* 0: Tri-state at this period */
241 /* 1: No tri-state at this period */
276 #define CLKRC_DIV(n) ((n) - 1)
315 /* Automatic gain ceiling - maximum AGC value */
366 #define DENOISE_ACTRL 0x40 /* De-noise auto threshold control */
369 #define SCAL0_ACTRL 0x08 /* Auto scaling factor control */
370 #define SCAL1_2_ACTRL 0x04 /* Auto scaling factor control */
427 /* band_filter = COM8[5] ? 256 - BDBASE : 0 */
500 /* Setting DSP4 to DSP_OFMT_RAW8 still gives 10-bit output,
501 * regardless of the COM7 value. We can thus only support 10-bit
559 ret = regmap_write(priv->regmap, COM7, SCCB_RESET); in ov772x_reset()
565 return regmap_update_bits(priv->regmap, COM2, SOFT_SLEEP_MODE, in ov772x_reset()
579 mutex_lock(&priv->lock); in ov772x_s_stream()
581 if (priv->streaming == enable) in ov772x_s_stream()
584 ret = regmap_update_bits(priv->regmap, COM2, SOFT_SLEEP_MODE, in ov772x_s_stream()
590 dev_dbg(&client->dev, "format %d, win %s\n", in ov772x_s_stream()
591 priv->cfmt->code, priv->win->name); in ov772x_s_stream()
593 priv->streaming = enable; in ov772x_s_stream()
596 mutex_unlock(&priv->lock); in ov772x_s_stream()
604 unsigned int fps = tpf->numerator ? in ov772x_select_fps()
605 tpf->denominator / tpf->numerator : in ov772x_select_fps()
606 tpf->denominator; in ov772x_select_fps()
615 diff = abs(fps - ov772x_frame_intervals[i]); in ov772x_select_fps()
630 unsigned long fin = clk_get_rate(priv->clk); in ov772x_set_frame_rate()
641 switch (cfmt->com7 & OFMT_MASK) { in ov772x_set_frame_rate()
643 fsize = win->sizeimage; in ov772x_set_frame_rate()
648 fsize = win->sizeimage * 2; in ov772x_set_frame_rate()
657 * Fin -> [ / CLKRC_div] -> [ * PLL_mult] -> pclk in ov772x_set_frame_rate()
663 * div = PLL_mult * Fin / pclk in ov772x_set_frame_rate()
665 * and re-calculate the pixel clock using it: in ov772x_set_frame_rate()
680 unsigned int div; in ov772x_set_frame_rate() local
685 div = DIV_ROUND_CLOSEST(pll_out, pclk); in ov772x_set_frame_rate()
686 t_pclk = DIV_ROUND_CLOSEST(fin * pll_mult, div); in ov772x_set_frame_rate()
687 diff = abs(pclk - t_pclk); in ov772x_set_frame_rate()
690 clkrc = CLKRC_DIV(div); in ov772x_set_frame_rate()
695 ret = regmap_write(priv->regmap, COM4, com4 | COM4_RESERVED); in ov772x_set_frame_rate()
699 ret = regmap_write(priv->regmap, CLKRC, clkrc | CLKRC_RESERVED); in ov772x_set_frame_rate()
710 struct v4l2_fract *tpf = &ival->interval; in ov772x_g_frame_interval()
712 tpf->numerator = 1; in ov772x_g_frame_interval()
713 tpf->denominator = priv->fps; in ov772x_g_frame_interval()
722 struct v4l2_fract *tpf = &ival->interval; in ov772x_s_frame_interval()
726 mutex_lock(&priv->lock); in ov772x_s_frame_interval()
728 if (priv->streaming) { in ov772x_s_frame_interval()
729 ret = -EBUSY; in ov772x_s_frame_interval()
738 * the frame rate will be restored right after power-up. in ov772x_s_frame_interval()
740 if (priv->power_count > 0) { in ov772x_s_frame_interval()
741 ret = ov772x_set_frame_rate(priv, fps, priv->cfmt, priv->win); in ov772x_s_frame_interval()
746 tpf->numerator = 1; in ov772x_s_frame_interval()
747 tpf->denominator = fps; in ov772x_s_frame_interval()
748 priv->fps = fps; in ov772x_s_frame_interval()
751 mutex_unlock(&priv->lock); in ov772x_s_frame_interval()
758 struct ov772x_priv *priv = container_of(ctrl->handler, in ov772x_s_ctrl()
760 struct regmap *regmap = priv->regmap; in ov772x_s_ctrl()
769 * the controls will be restored right after power-up. in ov772x_s_ctrl()
771 if (priv->power_count == 0) in ov772x_s_ctrl()
774 switch (ctrl->id) { in ov772x_s_ctrl()
776 val = ctrl->val ? VFLIP_IMG : 0x00; in ov772x_s_ctrl()
777 if (priv->info && (priv->info->flags & OV772X_FLAG_VFLIP)) in ov772x_s_ctrl()
781 val = ctrl->val ? HFLIP_IMG : 0x00; in ov772x_s_ctrl()
782 if (priv->info && (priv->info->flags & OV772X_FLAG_HFLIP)) in ov772x_s_ctrl()
786 if (!ctrl->val) { in ov772x_s_ctrl()
794 val = 256 - ctrl->val; in ov772x_s_ctrl()
805 return -EINVAL; in ov772x_s_ctrl()
816 reg->size = 1; in ov772x_g_register()
817 if (reg->reg > 0xff) in ov772x_g_register()
818 return -EINVAL; in ov772x_g_register()
820 ret = regmap_read(priv->regmap, reg->reg, &val); in ov772x_g_register()
824 reg->val = (__u64)val; in ov772x_g_register()
834 if (reg->reg > 0xff || in ov772x_s_register()
835 reg->val > 0xff) in ov772x_s_register()
836 return -EINVAL; in ov772x_s_register()
838 return regmap_write(priv->regmap, reg->reg, reg->val); in ov772x_s_register()
844 struct i2c_client *client = v4l2_get_subdevdata(&priv->subdev); in ov772x_power_on()
847 if (priv->clk) { in ov772x_power_on()
848 ret = clk_prepare_enable(priv->clk); in ov772x_power_on()
853 if (priv->pwdn_gpio) { in ov772x_power_on()
854 gpiod_set_value(priv->pwdn_gpio, 1); in ov772x_power_on()
860 * platforms (namely the SuperH Migo-R). Until a framework becomes in ov772x_power_on()
864 priv->rstb_gpio = gpiod_get_optional(&client->dev, "reset", in ov772x_power_on()
866 if (IS_ERR(priv->rstb_gpio)) { in ov772x_power_on()
867 dev_info(&client->dev, "Unable to get GPIO \"reset\""); in ov772x_power_on()
868 clk_disable_unprepare(priv->clk); in ov772x_power_on()
869 return PTR_ERR(priv->rstb_gpio); in ov772x_power_on()
872 if (priv->rstb_gpio) { in ov772x_power_on()
873 gpiod_set_value(priv->rstb_gpio, 1); in ov772x_power_on()
875 gpiod_set_value(priv->rstb_gpio, 0); in ov772x_power_on()
878 gpiod_put(priv->rstb_gpio); in ov772x_power_on()
886 clk_disable_unprepare(priv->clk); in ov772x_power_off()
888 if (priv->pwdn_gpio) { in ov772x_power_off()
889 gpiod_set_value(priv->pwdn_gpio, 0); in ov772x_power_off()
905 mutex_lock(&priv->lock); in ov772x_s_power()
910 if (priv->power_count == !on) { in ov772x_s_power()
918 ret = ov772x_set_params(priv, priv->cfmt, in ov772x_s_power()
919 priv->win); in ov772x_s_power()
927 priv->power_count += on ? 1 : -1; in ov772x_s_power()
928 WARN(priv->power_count < 0, "Unbalanced power count\n"); in ov772x_s_power()
929 WARN(priv->power_count > 1, "Duplicated s_power call\n"); in ov772x_s_power()
932 mutex_unlock(&priv->lock); in ov772x_s_power()
944 u32 diff = abs(width - ov772x_win_sizes[i].rect.width) in ov772x_select_win()
945 + abs(height - ov772x_win_sizes[i].rect.height); in ov772x_select_win()
965 if (mf->code == ov772x_cfmts[i].code) { in ov772x_select_params()
972 *win = ov772x_select_win(mf->width, mf->height); in ov772x_select_params()
977 struct regmap *regmap = priv->regmap; in ov772x_edgectrl()
980 if (!priv->info) in ov772x_edgectrl()
983 if (priv->info->edgectrl.strength & OV772X_MANUAL_EDGE_CTRL) { in ov772x_edgectrl()
997 priv->info->edgectrl.threshold); in ov772x_edgectrl()
1003 priv->info->edgectrl.strength); in ov772x_edgectrl()
1007 } else if (priv->info->edgectrl.upper > priv->info->edgectrl.lower) { in ov772x_edgectrl()
1015 priv->info->edgectrl.upper); in ov772x_edgectrl()
1021 priv->info->edgectrl.lower); in ov772x_edgectrl()
1045 ret = regmap_write(priv->regmap, HSTART, win->rect.left >> 2); in ov772x_set_params()
1048 ret = regmap_write(priv->regmap, HSIZE, win->rect.width >> 2); in ov772x_set_params()
1051 ret = regmap_write(priv->regmap, VSTART, win->rect.top >> 1); in ov772x_set_params()
1054 ret = regmap_write(priv->regmap, VSIZE, win->rect.height >> 1); in ov772x_set_params()
1057 ret = regmap_write(priv->regmap, HOUTSIZE, win->rect.width >> 2); in ov772x_set_params()
1060 ret = regmap_write(priv->regmap, VOUTSIZE, win->rect.height >> 1); in ov772x_set_params()
1063 ret = regmap_write(priv->regmap, HREF, in ov772x_set_params()
1064 ((win->rect.top & 1) << HREF_VSTART_SHIFT) | in ov772x_set_params()
1065 ((win->rect.left & 3) << HREF_HSTART_SHIFT) | in ov772x_set_params()
1066 ((win->rect.height & 1) << HREF_VSIZE_SHIFT) | in ov772x_set_params()
1067 ((win->rect.width & 3) << HREF_HSIZE_SHIFT)); in ov772x_set_params()
1070 ret = regmap_write(priv->regmap, EXHCH, in ov772x_set_params()
1071 ((win->rect.height & 1) << EXHCH_VSIZE_SHIFT) | in ov772x_set_params()
1072 ((win->rect.width & 3) << EXHCH_HSIZE_SHIFT)); in ov772x_set_params()
1077 val = cfmt->dsp3; in ov772x_set_params()
1079 ret = regmap_update_bits(priv->regmap, DSP_CTRL3, UV_MASK, val); in ov772x_set_params()
1084 /* DSP_CTRL4: AEC reference point and DSP output format. */ in ov772x_set_params()
1085 if (cfmt->dsp4) { in ov772x_set_params()
1086 ret = regmap_write(priv->regmap, DSP_CTRL4, cfmt->dsp4); in ov772x_set_params()
1092 val = cfmt->com3; in ov772x_set_params()
1093 if (priv->info && (priv->info->flags & OV772X_FLAG_VFLIP)) in ov772x_set_params()
1095 if (priv->info && (priv->info->flags & OV772X_FLAG_HFLIP)) in ov772x_set_params()
1097 if (priv->vflip_ctrl->val) in ov772x_set_params()
1099 if (priv->hflip_ctrl->val) in ov772x_set_params()
1102 ret = regmap_update_bits(priv->regmap, COM3, SWAP_MASK | IMG_MASK, val); in ov772x_set_params()
1107 ret = regmap_write(priv->regmap, COM7, win->com7_bit | cfmt->com7); in ov772x_set_params()
1112 ret = ov772x_set_frame_rate(priv, priv->fps, cfmt, win); in ov772x_set_params()
1117 if (priv->band_filter_ctrl->val) { in ov772x_set_params()
1118 unsigned short band_filter = priv->band_filter_ctrl->val; in ov772x_set_params()
1120 ret = regmap_update_bits(priv->regmap, COM8, in ov772x_set_params()
1123 ret = regmap_update_bits(priv->regmap, BDBASE, in ov772x_set_params()
1124 0xff, 256 - band_filter); in ov772x_set_params()
1144 if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) in ov772x_get_selection()
1145 return -EINVAL; in ov772x_get_selection()
1147 sel->r.left = 0; in ov772x_get_selection()
1148 sel->r.top = 0; in ov772x_get_selection()
1149 switch (sel->target) { in ov772x_get_selection()
1152 sel->r.width = priv->win->rect.width; in ov772x_get_selection()
1153 sel->r.height = priv->win->rect.height; in ov772x_get_selection()
1156 return -EINVAL; in ov772x_get_selection()
1164 struct v4l2_mbus_framefmt *mf = &format->format; in ov772x_get_fmt()
1167 if (format->pad) in ov772x_get_fmt()
1168 return -EINVAL; in ov772x_get_fmt()
1170 mf->width = priv->win->rect.width; in ov772x_get_fmt()
1171 mf->height = priv->win->rect.height; in ov772x_get_fmt()
1172 mf->code = priv->cfmt->code; in ov772x_get_fmt()
1173 mf->colorspace = priv->cfmt->colorspace; in ov772x_get_fmt()
1174 mf->field = V4L2_FIELD_NONE; in ov772x_get_fmt()
1184 struct v4l2_mbus_framefmt *mf = &format->format; in ov772x_set_fmt()
1189 if (format->pad) in ov772x_set_fmt()
1190 return -EINVAL; in ov772x_set_fmt()
1194 mf->code = cfmt->code; in ov772x_set_fmt()
1195 mf->width = win->rect.width; in ov772x_set_fmt()
1196 mf->height = win->rect.height; in ov772x_set_fmt()
1197 mf->field = V4L2_FIELD_NONE; in ov772x_set_fmt()
1198 mf->colorspace = cfmt->colorspace; in ov772x_set_fmt()
1199 mf->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; in ov772x_set_fmt()
1200 mf->quantization = V4L2_QUANTIZATION_DEFAULT; in ov772x_set_fmt()
1201 mf->xfer_func = V4L2_XFER_FUNC_DEFAULT; in ov772x_set_fmt()
1203 if (format->which == V4L2_SUBDEV_FORMAT_TRY) { in ov772x_set_fmt()
1204 cfg->try_fmt = *mf; in ov772x_set_fmt()
1208 mutex_lock(&priv->lock); in ov772x_set_fmt()
1210 if (priv->streaming) { in ov772x_set_fmt()
1211 ret = -EBUSY; in ov772x_set_fmt()
1218 * the format will be restored right after power-up. in ov772x_set_fmt()
1220 if (priv->power_count > 0) { in ov772x_set_fmt()
1225 priv->win = win; in ov772x_set_fmt()
1226 priv->cfmt = cfmt; in ov772x_set_fmt()
1229 mutex_unlock(&priv->lock); in ov772x_set_fmt()
1236 struct i2c_client *client = v4l2_get_subdevdata(&priv->subdev); in ov772x_video_probe()
1246 ret = regmap_read(priv->regmap, PID, &pid); in ov772x_video_probe()
1249 ret = regmap_read(priv->regmap, VER, &ver); in ov772x_video_probe()
1261 dev_err(&client->dev, in ov772x_video_probe()
1263 ret = -ENODEV; in ov772x_video_probe()
1267 ret = regmap_read(priv->regmap, MIDH, &midh); in ov772x_video_probe()
1270 ret = regmap_read(priv->regmap, MIDL, &midl); in ov772x_video_probe()
1274 dev_info(&client->dev, in ov772x_video_probe()
1278 ret = v4l2_ctrl_handler_setup(&priv->hdl); in ov772x_video_probe()
1305 if (fie->pad || fie->index >= ARRAY_SIZE(ov772x_frame_intervals)) in ov772x_enum_frame_interval()
1306 return -EINVAL; in ov772x_enum_frame_interval()
1308 if (fie->width != VGA_WIDTH && fie->width != QVGA_WIDTH) in ov772x_enum_frame_interval()
1309 return -EINVAL; in ov772x_enum_frame_interval()
1310 if (fie->height != VGA_HEIGHT && fie->height != QVGA_HEIGHT) in ov772x_enum_frame_interval()
1311 return -EINVAL; in ov772x_enum_frame_interval()
1313 fie->interval.numerator = 1; in ov772x_enum_frame_interval()
1314 fie->interval.denominator = ov772x_frame_intervals[fie->index]; in ov772x_enum_frame_interval()
1323 if (code->pad || code->index >= ARRAY_SIZE(ov772x_cfmts)) in ov772x_enum_mbus_code()
1324 return -EINVAL; in ov772x_enum_mbus_code()
1326 code->code = ov772x_cfmts[code->index].code; in ov772x_enum_mbus_code()
1365 if (!client->dev.of_node && !client->dev.platform_data) { in ov772x_probe()
1366 dev_err(&client->dev, in ov772x_probe()
1367 "Missing ov772x platform data for non-DT device\n"); in ov772x_probe()
1368 return -EINVAL; in ov772x_probe()
1371 priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL); in ov772x_probe()
1373 return -ENOMEM; in ov772x_probe()
1375 priv->regmap = devm_regmap_init_sccb(client, &ov772x_regmap_config); in ov772x_probe()
1376 if (IS_ERR(priv->regmap)) { in ov772x_probe()
1377 dev_err(&client->dev, "Failed to allocate register map\n"); in ov772x_probe()
1378 return PTR_ERR(priv->regmap); in ov772x_probe()
1381 priv->info = client->dev.platform_data; in ov772x_probe()
1382 mutex_init(&priv->lock); in ov772x_probe()
1384 v4l2_i2c_subdev_init(&priv->subdev, client, &ov772x_subdev_ops); in ov772x_probe()
1385 priv->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | in ov772x_probe()
1387 v4l2_ctrl_handler_init(&priv->hdl, 3); in ov772x_probe()
1389 priv->hdl.lock = &priv->lock; in ov772x_probe()
1390 priv->vflip_ctrl = v4l2_ctrl_new_std(&priv->hdl, &ov772x_ctrl_ops, in ov772x_probe()
1392 priv->hflip_ctrl = v4l2_ctrl_new_std(&priv->hdl, &ov772x_ctrl_ops, in ov772x_probe()
1394 priv->band_filter_ctrl = v4l2_ctrl_new_std(&priv->hdl, &ov772x_ctrl_ops, in ov772x_probe()
1397 priv->subdev.ctrl_handler = &priv->hdl; in ov772x_probe()
1398 if (priv->hdl.error) { in ov772x_probe()
1399 ret = priv->hdl.error; in ov772x_probe()
1403 priv->clk = clk_get(&client->dev, NULL); in ov772x_probe()
1404 if (IS_ERR(priv->clk)) { in ov772x_probe()
1405 dev_err(&client->dev, "Unable to get xclk clock\n"); in ov772x_probe()
1406 ret = PTR_ERR(priv->clk); in ov772x_probe()
1410 priv->pwdn_gpio = gpiod_get_optional(&client->dev, "powerdown", in ov772x_probe()
1412 if (IS_ERR(priv->pwdn_gpio)) { in ov772x_probe()
1413 dev_info(&client->dev, "Unable to get GPIO \"powerdown\""); in ov772x_probe()
1414 ret = PTR_ERR(priv->pwdn_gpio); in ov772x_probe()
1423 priv->pad.flags = MEDIA_PAD_FL_SOURCE; in ov772x_probe()
1424 priv->subdev.entity.function = MEDIA_ENT_F_CAM_SENSOR; in ov772x_probe()
1425 ret = media_entity_pads_init(&priv->subdev.entity, 1, &priv->pad); in ov772x_probe()
1430 priv->cfmt = &ov772x_cfmts[0]; in ov772x_probe()
1431 priv->win = &ov772x_win_sizes[0]; in ov772x_probe()
1432 priv->fps = 15; in ov772x_probe()
1434 ret = v4l2_async_register_subdev(&priv->subdev); in ov772x_probe()
1441 media_entity_cleanup(&priv->subdev.entity); in ov772x_probe()
1443 if (priv->pwdn_gpio) in ov772x_probe()
1444 gpiod_put(priv->pwdn_gpio); in ov772x_probe()
1446 clk_put(priv->clk); in ov772x_probe()
1448 v4l2_ctrl_handler_free(&priv->hdl); in ov772x_probe()
1449 mutex_destroy(&priv->lock); in ov772x_probe()
1458 media_entity_cleanup(&priv->subdev.entity); in ov772x_remove()
1459 clk_put(priv->clk); in ov772x_remove()
1460 if (priv->pwdn_gpio) in ov772x_remove()
1461 gpiod_put(priv->pwdn_gpio); in ov772x_remove()
1462 v4l2_async_unregister_subdev(&priv->subdev); in ov772x_remove()
1463 v4l2_ctrl_handler_free(&priv->hdl); in ov772x_remove()
1464 mutex_destroy(&priv->lock); in ov772x_remove()