Lines Matching +full:vaa +full:- +full:supply

1 // SPDX-License-Identifier: GPL-2.0-only
6 * Copyright (C) 2011, Javier Martin <javier.martin@vista-silicon.com>
28 #include <media/v4l2-async.h>
29 #include <media/v4l2-ctrls.h>
30 #include <media/v4l2-device.h>
31 #include <media/v4l2-fwnode.h>
32 #include <media/v4l2-subdev.h>
34 #include "aptina-pll.h"
161 struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev); in mt9p031_set_output_control()
162 u16 value = (mt9p031->output_control & ~clear) | set; in mt9p031_set_output_control()
169 mt9p031->output_control = value; in mt9p031_set_output_control()
175 struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev); in mt9p031_set_mode2()
176 u16 value = (mt9p031->mode2 & ~clear) | set; in mt9p031_set_mode2()
183 mt9p031->mode2 = value; in mt9p031_set_mode2()
189 struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev); in mt9p031_reset()
201 MT9P031_PIXEL_CLOCK_DIVIDE(mt9p031->clk_div)); in mt9p031_reset()
227 struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev); in mt9p031_clk_setup()
228 struct mt9p031_platform_data *pdata = mt9p031->pdata; in mt9p031_clk_setup()
232 mt9p031->clk = devm_clk_get(&client->dev, NULL); in mt9p031_clk_setup()
233 if (IS_ERR(mt9p031->clk)) in mt9p031_clk_setup()
234 return PTR_ERR(mt9p031->clk); in mt9p031_clk_setup()
236 ret = clk_set_rate(mt9p031->clk, pdata->ext_freq); in mt9p031_clk_setup()
240 ext_freq = clk_get_rate(mt9p031->clk); in mt9p031_clk_setup()
248 div = DIV_ROUND_UP(ext_freq, pdata->target_freq); in mt9p031_clk_setup()
251 mt9p031->clk_div = min_t(unsigned int, div, 64); in mt9p031_clk_setup()
252 mt9p031->use_pll = false; in mt9p031_clk_setup()
257 mt9p031->pll.ext_clock = ext_freq; in mt9p031_clk_setup()
258 mt9p031->pll.pix_clock = pdata->target_freq; in mt9p031_clk_setup()
259 mt9p031->use_pll = true; in mt9p031_clk_setup()
261 return aptina_pll_calculate(&client->dev, &limits, &mt9p031->pll); in mt9p031_clk_setup()
266 struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev); in mt9p031_pll_enable()
269 if (!mt9p031->use_pll) in mt9p031_pll_enable()
278 (mt9p031->pll.m << 8) | (mt9p031->pll.n - 1)); in mt9p031_pll_enable()
282 ret = mt9p031_write(client, MT9P031_PLL_CONFIG_2, mt9p031->pll.p1 - 1); in mt9p031_pll_enable()
295 struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev); in mt9p031_pll_disable()
297 if (!mt9p031->use_pll) in mt9p031_pll_disable()
310 if (mt9p031->reset) { in mt9p031_power_on()
311 gpiod_set_value(mt9p031->reset, 1); in mt9p031_power_on()
316 ret = regulator_bulk_enable(ARRAY_SIZE(mt9p031->regulators), in mt9p031_power_on()
317 mt9p031->regulators); in mt9p031_power_on()
322 if (mt9p031->clk) { in mt9p031_power_on()
323 ret = clk_prepare_enable(mt9p031->clk); in mt9p031_power_on()
325 regulator_bulk_disable(ARRAY_SIZE(mt9p031->regulators), in mt9p031_power_on()
326 mt9p031->regulators); in mt9p031_power_on()
332 if (mt9p031->reset) { in mt9p031_power_on()
333 gpiod_set_value(mt9p031->reset, 0); in mt9p031_power_on()
334 /* Wait 850000 EXTCLK cycles before de-asserting reset. */ in mt9p031_power_on()
335 rate = clk_get_rate(mt9p031->clk); in mt9p031_power_on()
347 if (mt9p031->reset) { in mt9p031_power_off()
348 gpiod_set_value(mt9p031->reset, 1); in mt9p031_power_off()
352 regulator_bulk_disable(ARRAY_SIZE(mt9p031->regulators), in mt9p031_power_off()
353 mt9p031->regulators); in mt9p031_power_off()
355 clk_disable_unprepare(mt9p031->clk); in mt9p031_power_off()
360 struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev); in __mt9p031_set_power()
374 dev_err(&client->dev, "Failed to reset the camera\n"); in __mt9p031_set_power()
379 if (mt9p031->pdata && mt9p031->pdata->pixclk_pol) { in __mt9p031_set_power()
386 return v4l2_ctrl_handler_setup(&mt9p031->ctrls); in __mt9p031_set_power()
389 /* -----------------------------------------------------------------------------
395 struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev); in mt9p031_set_params()
396 struct v4l2_mbus_framefmt *format = &mt9p031->format; in mt9p031_set_params()
397 const struct v4l2_rect *crop = &mt9p031->crop; in mt9p031_set_params()
412 ret = mt9p031_write(client, MT9P031_COLUMN_START, crop->left); in mt9p031_set_params()
415 ret = mt9p031_write(client, MT9P031_ROW_START, crop->top); in mt9p031_set_params()
418 ret = mt9p031_write(client, MT9P031_WINDOW_WIDTH, crop->width - 1); in mt9p031_set_params()
421 ret = mt9p031_write(client, MT9P031_WINDOW_HEIGHT, crop->height - 1); in mt9p031_set_params()
428 xskip = DIV_ROUND_CLOSEST(crop->width, format->width); in mt9p031_set_params()
429 yskip = DIV_ROUND_CLOSEST(crop->height, format->height); in mt9p031_set_params()
430 xbin = 1 << (ffs(xskip) - 1); in mt9p031_set_params()
431 ybin = 1 << (ffs(yskip) - 1); in mt9p031_set_params()
434 ((xbin - 1) << 4) | (xskip - 1)); in mt9p031_set_params()
438 ((ybin - 1) << 4) | (yskip - 1)); in mt9p031_set_params()
442 /* Blanking - use minimum value for horizontal blanking and default in mt9p031_set_params()
448 ret = mt9p031_write(client, MT9P031_HORIZONTAL_BLANK, hblank - 1); in mt9p031_set_params()
451 ret = mt9p031_write(client, MT9P031_VERTICAL_BLANK, vblank - 1); in mt9p031_set_params()
498 * - clear pause restart in mt9p031_s_stream()
499 * - don't clear restart as clearing restart manually can cause in mt9p031_s_stream()
516 if (code->pad || code->index) in mt9p031_enum_mbus_code()
517 return -EINVAL; in mt9p031_enum_mbus_code()
519 code->code = mt9p031->format.code; in mt9p031_enum_mbus_code()
529 if (fse->index >= 8 || fse->code != mt9p031->format.code) in mt9p031_enum_frame_size()
530 return -EINVAL; in mt9p031_enum_frame_size()
532 fse->min_width = MT9P031_WINDOW_WIDTH_DEF in mt9p031_enum_frame_size()
533 / min_t(unsigned int, 7, fse->index + 1); in mt9p031_enum_frame_size()
534 fse->max_width = fse->min_width; in mt9p031_enum_frame_size()
535 fse->min_height = MT9P031_WINDOW_HEIGHT_DEF / (fse->index + 1); in mt9p031_enum_frame_size()
536 fse->max_height = fse->min_height; in mt9p031_enum_frame_size()
550 return &mt9p031->format; in __mt9p031_get_pad_format()
565 return &mt9p031->crop; in __mt9p031_get_pad_crop()
577 fmt->format = *__mt9p031_get_pad_format(mt9p031, sd_state, fmt->pad, in mt9p031_get_format()
578 fmt->which); in mt9p031_get_format()
594 __crop = __mt9p031_get_pad_crop(mt9p031, sd_state, format->pad, in mt9p031_set_format()
595 format->which); in mt9p031_set_format()
598 width = clamp_t(unsigned int, ALIGN(format->format.width, 2), in mt9p031_set_format()
599 max_t(unsigned int, __crop->width / 7, in mt9p031_set_format()
601 __crop->width); in mt9p031_set_format()
602 height = clamp_t(unsigned int, ALIGN(format->format.height, 2), in mt9p031_set_format()
603 max_t(unsigned int, __crop->height / 8, in mt9p031_set_format()
605 __crop->height); in mt9p031_set_format()
607 hratio = DIV_ROUND_CLOSEST(__crop->width, width); in mt9p031_set_format()
608 vratio = DIV_ROUND_CLOSEST(__crop->height, height); in mt9p031_set_format()
610 __format = __mt9p031_get_pad_format(mt9p031, sd_state, format->pad, in mt9p031_set_format()
611 format->which); in mt9p031_set_format()
612 __format->width = __crop->width / hratio; in mt9p031_set_format()
613 __format->height = __crop->height / vratio; in mt9p031_set_format()
615 format->format = *__format; in mt9p031_set_format()
626 switch (sel->target) { in mt9p031_get_selection()
628 sel->r.left = MT9P031_COLUMN_START_MIN; in mt9p031_get_selection()
629 sel->r.top = MT9P031_ROW_START_MIN; in mt9p031_get_selection()
630 sel->r.width = MT9P031_WINDOW_WIDTH_MAX; in mt9p031_get_selection()
631 sel->r.height = MT9P031_WINDOW_HEIGHT_MAX; in mt9p031_get_selection()
635 sel->r = *__mt9p031_get_pad_crop(mt9p031, sd_state, in mt9p031_get_selection()
636 sel->pad, sel->which); in mt9p031_get_selection()
640 return -EINVAL; in mt9p031_get_selection()
653 if (sel->target != V4L2_SEL_TGT_CROP) in mt9p031_set_selection()
654 return -EINVAL; in mt9p031_set_selection()
659 rect.left = clamp(ALIGN(sel->r.left, 2), MT9P031_COLUMN_START_MIN, in mt9p031_set_selection()
661 rect.top = clamp(ALIGN(sel->r.top, 2), MT9P031_ROW_START_MIN, in mt9p031_set_selection()
663 rect.width = clamp_t(unsigned int, ALIGN(sel->r.width, 2), in mt9p031_set_selection()
666 rect.height = clamp_t(unsigned int, ALIGN(sel->r.height, 2), in mt9p031_set_selection()
671 MT9P031_PIXEL_ARRAY_WIDTH - rect.left); in mt9p031_set_selection()
673 MT9P031_PIXEL_ARRAY_HEIGHT - rect.top); in mt9p031_set_selection()
675 __crop = __mt9p031_get_pad_crop(mt9p031, sd_state, sel->pad, in mt9p031_set_selection()
676 sel->which); in mt9p031_set_selection()
678 if (rect.width != __crop->width || rect.height != __crop->height) { in mt9p031_set_selection()
683 sel->pad, in mt9p031_set_selection()
684 sel->which); in mt9p031_set_selection()
685 __format->width = rect.width; in mt9p031_set_selection()
686 __format->height = rect.height; in mt9p031_set_selection()
690 sel->r = rect; in mt9p031_set_selection()
705 crop->left = MT9P031_COLUMN_START_DEF; in mt9p031_init_state()
706 crop->top = MT9P031_ROW_START_DEF; in mt9p031_init_state()
707 crop->width = MT9P031_WINDOW_WIDTH_DEF; in mt9p031_init_state()
708 crop->height = MT9P031_WINDOW_HEIGHT_DEF; in mt9p031_init_state()
711 format->code = mt9p031->code; in mt9p031_init_state()
712 format->width = MT9P031_WINDOW_WIDTH_DEF; in mt9p031_init_state()
713 format->height = MT9P031_WINDOW_HEIGHT_DEF; in mt9p031_init_state()
714 format->field = V4L2_FIELD_NONE; in mt9p031_init_state()
715 format->colorspace = V4L2_COLORSPACE_SRGB; in mt9p031_init_state()
720 /* -----------------------------------------------------------------------------
731 struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev); in mt9p031_restore_blc()
734 if (mt9p031->blc_auto->cur.val != 0) { in mt9p031_restore_blc()
741 if (mt9p031->blc_offset->cur.val != 0) { in mt9p031_restore_blc()
743 mt9p031->blc_offset->cur.val); in mt9p031_restore_blc()
754 container_of(ctrl->handler, struct mt9p031, ctrls); in mt9p031_s_ctrl()
755 struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev); in mt9p031_s_ctrl()
759 if (ctrl->flags & V4L2_CTRL_FLAG_INACTIVE) in mt9p031_s_ctrl()
762 switch (ctrl->id) { in mt9p031_s_ctrl()
765 (ctrl->val >> 16) & 0xffff); in mt9p031_s_ctrl()
770 ctrl->val & 0xffff); in mt9p031_s_ctrl()
777 * ------------------------------------------ in mt9p031_s_ctrl()
787 if (ctrl->val <= 32) { in mt9p031_s_ctrl()
788 data = ctrl->val; in mt9p031_s_ctrl()
789 } else if (ctrl->val <= 64) { in mt9p031_s_ctrl()
790 ctrl->val &= ~1; in mt9p031_s_ctrl()
791 data = (1 << 6) | (ctrl->val >> 1); in mt9p031_s_ctrl()
793 ctrl->val &= ~7; in mt9p031_s_ctrl()
794 data = ((ctrl->val - 64) << 5) | (1 << 6) | 32; in mt9p031_s_ctrl()
800 if (ctrl->val) in mt9p031_s_ctrl()
808 if (ctrl->val) in mt9p031_s_ctrl()
818 * in the image. Activate (deactivate) the BLC-related controls in mt9p031_s_ctrl()
821 v4l2_ctrl_activate(mt9p031->blc_auto, ctrl->val == 0); in mt9p031_s_ctrl()
822 v4l2_ctrl_activate(mt9p031->blc_offset, ctrl->val == 0); in mt9p031_s_ctrl()
824 if (!ctrl->val) { in mt9p031_s_ctrl()
854 ((ctrl->val - 1) << MT9P031_TEST_PATTERN_SHIFT) in mt9p031_s_ctrl()
859 ctrl->val ? 0 : MT9P031_READ_MODE_2_ROW_BLC, in mt9p031_s_ctrl()
860 ctrl->val ? MT9P031_READ_MODE_2_ROW_BLC : 0); in mt9p031_s_ctrl()
865 ctrl->val ? 0 : MT9P031_BLC_MANUAL_BLC); in mt9p031_s_ctrl()
869 ctrl->val); in mt9p031_s_ctrl()
872 data = ctrl->val & ((1 << 9) - 1); in mt9p031_s_ctrl()
887 ctrl->val & ((1 << 12) - 1)); in mt9p031_s_ctrl()
936 .min = -255,
946 .min = -2048,
954 /* -----------------------------------------------------------------------------
963 mutex_lock(&mt9p031->power_lock); in mt9p031_set_power()
968 if (mt9p031->power_count == !on) { in mt9p031_set_power()
975 mt9p031->power_count += on ? 1 : -1; in mt9p031_set_power()
976 WARN_ON(mt9p031->power_count < 0); in mt9p031_set_power()
979 mutex_unlock(&mt9p031->power_lock); in mt9p031_set_power()
983 /* -----------------------------------------------------------------------------
996 dev_err(&client->dev, "MT9P031 power up failed\n"); in mt9p031_registered()
1005 dev_err(&client->dev, "MT9P031 not detected, wrong version " in mt9p031_registered()
1007 return -ENODEV; in mt9p031_registered()
1010 dev_info(&client->dev, "MT9P031 detected at address 0x%02x\n", in mt9p031_registered()
1011 client->addr); in mt9p031_registered()
1056 /* -----------------------------------------------------------------------------
1069 if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node) in mt9p031_get_pdata()
1070 return client->dev.platform_data; in mt9p031_get_pdata()
1072 np = of_graph_get_endpoint_by_regs(client->dev.of_node, 0, -1); in mt9p031_get_pdata()
1079 pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL); in mt9p031_get_pdata()
1083 of_property_read_u32(np, "input-clock-frequency", &pdata->ext_freq); in mt9p031_get_pdata()
1084 of_property_read_u32(np, "pixel-clock-frequency", &pdata->target_freq); in mt9p031_get_pdata()
1086 pdata->pixclk_pol = !!(endpoint.bus.parallel.flags & in mt9p031_get_pdata()
1097 struct i2c_adapter *adapter = client->adapter; in mt9p031_probe()
1103 dev_err(&client->dev, "No platform data\n"); in mt9p031_probe()
1104 return -EINVAL; in mt9p031_probe()
1108 dev_warn(&client->dev, in mt9p031_probe()
1109 "I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n"); in mt9p031_probe()
1110 return -EIO; in mt9p031_probe()
1113 mt9p031 = devm_kzalloc(&client->dev, sizeof(*mt9p031), GFP_KERNEL); in mt9p031_probe()
1115 return -ENOMEM; in mt9p031_probe()
1117 mt9p031->pdata = pdata; in mt9p031_probe()
1118 mt9p031->output_control = MT9P031_OUTPUT_CONTROL_DEF; in mt9p031_probe()
1119 mt9p031->mode2 = MT9P031_READ_MODE_2_ROW_BLC; in mt9p031_probe()
1120 mt9p031->code = (uintptr_t)i2c_get_match_data(client); in mt9p031_probe()
1122 mt9p031->regulators[0].supply = "vdd"; in mt9p031_probe()
1123 mt9p031->regulators[1].supply = "vdd_io"; in mt9p031_probe()
1124 mt9p031->regulators[2].supply = "vaa"; in mt9p031_probe()
1126 ret = devm_regulator_bulk_get(&client->dev, 3, mt9p031->regulators); in mt9p031_probe()
1128 dev_err(&client->dev, "Unable to get regulators\n"); in mt9p031_probe()
1132 mutex_init(&mt9p031->power_lock); in mt9p031_probe()
1134 v4l2_ctrl_handler_init(&mt9p031->ctrls, ARRAY_SIZE(mt9p031_ctrls) + 6); in mt9p031_probe()
1136 v4l2_ctrl_new_std(&mt9p031->ctrls, &mt9p031_ctrl_ops, in mt9p031_probe()
1140 v4l2_ctrl_new_std(&mt9p031->ctrls, &mt9p031_ctrl_ops, in mt9p031_probe()
1143 v4l2_ctrl_new_std(&mt9p031->ctrls, &mt9p031_ctrl_ops, in mt9p031_probe()
1145 v4l2_ctrl_new_std(&mt9p031->ctrls, &mt9p031_ctrl_ops, in mt9p031_probe()
1147 v4l2_ctrl_new_std(&mt9p031->ctrls, &mt9p031_ctrl_ops, in mt9p031_probe()
1148 V4L2_CID_PIXEL_RATE, pdata->target_freq, in mt9p031_probe()
1149 pdata->target_freq, 1, pdata->target_freq); in mt9p031_probe()
1150 v4l2_ctrl_new_std_menu_items(&mt9p031->ctrls, &mt9p031_ctrl_ops, in mt9p031_probe()
1152 ARRAY_SIZE(mt9p031_test_pattern_menu) - 1, 0, in mt9p031_probe()
1156 v4l2_ctrl_new_custom(&mt9p031->ctrls, &mt9p031_ctrls[i], NULL); in mt9p031_probe()
1158 mt9p031->subdev.ctrl_handler = &mt9p031->ctrls; in mt9p031_probe()
1160 if (mt9p031->ctrls.error) { in mt9p031_probe()
1162 __func__, mt9p031->ctrls.error); in mt9p031_probe()
1163 ret = mt9p031->ctrls.error; in mt9p031_probe()
1167 mt9p031->blc_auto = v4l2_ctrl_find(&mt9p031->ctrls, V4L2_CID_BLC_AUTO); in mt9p031_probe()
1168 mt9p031->blc_offset = v4l2_ctrl_find(&mt9p031->ctrls, in mt9p031_probe()
1171 v4l2_i2c_subdev_init(&mt9p031->subdev, client, &mt9p031_subdev_ops); in mt9p031_probe()
1172 mt9p031->subdev.internal_ops = &mt9p031_subdev_internal_ops; in mt9p031_probe()
1174 mt9p031->subdev.entity.function = MEDIA_ENT_F_CAM_SENSOR; in mt9p031_probe()
1175 mt9p031->pad.flags = MEDIA_PAD_FL_SOURCE; in mt9p031_probe()
1176 ret = media_entity_pads_init(&mt9p031->subdev.entity, 1, &mt9p031->pad); in mt9p031_probe()
1180 mt9p031->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; in mt9p031_probe()
1182 ret = mt9p031_init_state(&mt9p031->subdev, NULL); in mt9p031_probe()
1186 mt9p031->reset = devm_gpiod_get_optional(&client->dev, "reset", in mt9p031_probe()
1193 ret = v4l2_async_register_subdev(&mt9p031->subdev); in mt9p031_probe()
1197 v4l2_ctrl_handler_free(&mt9p031->ctrls); in mt9p031_probe()
1198 media_entity_cleanup(&mt9p031->subdev.entity); in mt9p031_probe()
1199 mutex_destroy(&mt9p031->power_lock); in mt9p031_probe()
1210 v4l2_ctrl_handler_free(&mt9p031->ctrls); in mt9p031_remove()
1212 media_entity_cleanup(&subdev->entity); in mt9p031_remove()
1213 mutex_destroy(&mt9p031->power_lock); in mt9p031_remove()