Lines Matching full:ov5645

3  * Driver for the OV5645 camera sensor.
10 * - the OV5645 driver from QC msm-3.10 kernel on codeaurora.org:
12 * media/platform/msm/camera_v2/sensor/ov5645.c?h=LA.BR.1.2.4_rb1.41
85 struct ov5645 { struct
114 static inline struct ov5645 *to_ov5645(struct v4l2_subdev *sd) in to_ov5645() argument
116 return container_of(sd, struct ov5645, sd); in to_ov5645()
540 static int ov5645_write_reg(struct ov5645 *ov5645, u16 reg, u8 val) in ov5645_write_reg() argument
549 ret = i2c_master_send(ov5645->i2c_client, regbuf, 3); in ov5645_write_reg()
551 dev_err(ov5645->dev, "%s: write reg error %d: reg=%x, val=%x\n", in ov5645_write_reg()
559 static int ov5645_read_reg(struct ov5645 *ov5645, u16 reg, u8 *val) in ov5645_read_reg() argument
567 ret = i2c_master_send(ov5645->i2c_client, regbuf, 2); in ov5645_read_reg()
569 dev_err(ov5645->dev, "%s: write reg error %d: reg=%x\n", in ov5645_read_reg()
574 ret = i2c_master_recv(ov5645->i2c_client, val, 1); in ov5645_read_reg()
576 dev_err(ov5645->dev, "%s: read reg error %d: reg=%x\n", in ov5645_read_reg()
584 static int ov5645_set_aec_mode(struct ov5645 *ov5645, u32 mode) in ov5645_set_aec_mode() argument
586 u8 val = ov5645->aec_pk_manual; in ov5645_set_aec_mode()
594 ret = ov5645_write_reg(ov5645, OV5645_AEC_PK_MANUAL, val); in ov5645_set_aec_mode()
596 ov5645->aec_pk_manual = val; in ov5645_set_aec_mode()
601 static int ov5645_set_agc_mode(struct ov5645 *ov5645, u32 enable) in ov5645_set_agc_mode() argument
603 u8 val = ov5645->aec_pk_manual; in ov5645_set_agc_mode()
611 ret = ov5645_write_reg(ov5645, OV5645_AEC_PK_MANUAL, val); in ov5645_set_agc_mode()
613 ov5645->aec_pk_manual = val; in ov5645_set_agc_mode()
618 static int ov5645_set_register_array(struct ov5645 *ov5645, in ov5645_set_register_array() argument
626 ret = ov5645_write_reg(ov5645, settings->reg, settings->val); in ov5645_set_register_array()
641 struct ov5645 *ov5645 = to_ov5645(sd); in __ov5645_set_power_off() local
643 ov5645_write_reg(ov5645, OV5645_IO_MIPI_CTRL00, 0x58); in __ov5645_set_power_off()
644 gpiod_set_value_cansleep(ov5645->rst_gpio, 1); in __ov5645_set_power_off()
645 gpiod_set_value_cansleep(ov5645->enable_gpio, 0); in __ov5645_set_power_off()
646 regulator_bulk_disable(OV5645_NUM_SUPPLIES, ov5645->supplies); in __ov5645_set_power_off()
652 struct ov5645 *ov5645 = to_ov5645(sd); in ov5645_set_power_off() local
655 clk_disable_unprepare(ov5645->xclk); in ov5645_set_power_off()
663 struct ov5645 *ov5645 = to_ov5645(sd); in ov5645_set_power_on() local
666 ret = regulator_bulk_enable(OV5645_NUM_SUPPLIES, ov5645->supplies); in ov5645_set_power_on()
670 ret = clk_prepare_enable(ov5645->xclk); in ov5645_set_power_on()
672 dev_err(ov5645->dev, "clk prepare enable failed\n"); in ov5645_set_power_on()
673 regulator_bulk_disable(OV5645_NUM_SUPPLIES, ov5645->supplies); in ov5645_set_power_on()
678 gpiod_set_value_cansleep(ov5645->enable_gpio, 1); in ov5645_set_power_on()
681 gpiod_set_value_cansleep(ov5645->rst_gpio, 0); in ov5645_set_power_on()
685 ret = ov5645_set_register_array(ov5645, ov5645_global_init_setting, in ov5645_set_power_on()
688 dev_err(ov5645->dev, "could not set init registers\n"); in ov5645_set_power_on()
698 clk_disable_unprepare(ov5645->xclk); in ov5645_set_power_on()
702 static int ov5645_set_saturation(struct ov5645 *ov5645, s32 value) in ov5645_set_saturation() argument
707 ret = ov5645_write_reg(ov5645, OV5645_SDE_SAT_U, reg_value); in ov5645_set_saturation()
711 return ov5645_write_reg(ov5645, OV5645_SDE_SAT_V, reg_value); in ov5645_set_saturation()
714 static int ov5645_set_hflip(struct ov5645 *ov5645, s32 value) in ov5645_set_hflip() argument
716 u8 val = ov5645->timing_tc_reg21; in ov5645_set_hflip()
724 ret = ov5645_write_reg(ov5645, OV5645_TIMING_TC_REG21, val); in ov5645_set_hflip()
726 ov5645->timing_tc_reg21 = val; in ov5645_set_hflip()
731 static int ov5645_set_vflip(struct ov5645 *ov5645, s32 value) in ov5645_set_vflip() argument
733 u8 val = ov5645->timing_tc_reg20; in ov5645_set_vflip()
741 ret = ov5645_write_reg(ov5645, OV5645_TIMING_TC_REG20, val); in ov5645_set_vflip()
743 ov5645->timing_tc_reg20 = val; in ov5645_set_vflip()
748 static int ov5645_set_test_pattern(struct ov5645 *ov5645, s32 value) in ov5645_set_test_pattern() argument
757 return ov5645_write_reg(ov5645, OV5645_PRE_ISP_TEST_SETTING_1, val); in ov5645_set_test_pattern()
768 static int ov5645_set_awb(struct ov5645 *ov5645, s32 enable_auto) in ov5645_set_awb() argument
775 return ov5645_write_reg(ov5645, OV5645_AWB_MANUAL_CONTROL, val); in ov5645_set_awb()
780 struct ov5645 *ov5645 = container_of(ctrl->handler, in ov5645_s_ctrl() local
781 struct ov5645, ctrls); in ov5645_s_ctrl()
784 mutex_lock(&ov5645->power_lock); in ov5645_s_ctrl()
785 if (!pm_runtime_get_if_in_use(ov5645->dev)) { in ov5645_s_ctrl()
786 mutex_unlock(&ov5645->power_lock); in ov5645_s_ctrl()
792 ret = ov5645_set_saturation(ov5645, ctrl->val); in ov5645_s_ctrl()
795 ret = ov5645_set_awb(ov5645, ctrl->val); in ov5645_s_ctrl()
798 ret = ov5645_set_agc_mode(ov5645, ctrl->val); in ov5645_s_ctrl()
801 ret = ov5645_set_aec_mode(ov5645, ctrl->val); in ov5645_s_ctrl()
804 ret = ov5645_set_test_pattern(ov5645, ctrl->val); in ov5645_s_ctrl()
807 ret = ov5645_set_hflip(ov5645, ctrl->val); in ov5645_s_ctrl()
810 ret = ov5645_set_vflip(ov5645, ctrl->val); in ov5645_s_ctrl()
817 pm_runtime_mark_last_busy(ov5645->dev); in ov5645_s_ctrl()
818 pm_runtime_put_autosuspend(ov5645->dev); in ov5645_s_ctrl()
819 mutex_unlock(&ov5645->power_lock); in ov5645_s_ctrl()
859 __ov5645_get_pad_format(struct ov5645 *ov5645, in __ov5645_get_pad_format() argument
868 return &ov5645->fmt; in __ov5645_get_pad_format()
878 struct ov5645 *ov5645 = to_ov5645(sd); in ov5645_get_format() local
880 format->format = *__ov5645_get_pad_format(ov5645, sd_state, in ov5645_get_format()
887 __ov5645_get_pad_crop(struct ov5645 *ov5645, in __ov5645_get_pad_crop() argument
895 return &ov5645->crop; in __ov5645_get_pad_crop()
905 struct ov5645 *ov5645 = to_ov5645(sd); in ov5645_set_format() local
911 __crop = __ov5645_get_pad_crop(ov5645, sd_state, format->pad, in ov5645_set_format()
923 ret = v4l2_ctrl_s_ctrl_int64(ov5645->pixel_clock, in ov5645_set_format()
928 ret = v4l2_ctrl_s_ctrl(ov5645->link_freq, in ov5645_set_format()
933 ov5645->current_mode = new_mode; in ov5645_set_format()
936 __format = __ov5645_get_pad_format(ov5645, sd_state, format->pad, in ov5645_set_format()
967 struct ov5645 *ov5645 = to_ov5645(sd); in ov5645_get_selection() local
972 sel->r = *__ov5645_get_pad_crop(ov5645, sd_state, sel->pad, in ov5645_get_selection()
979 struct ov5645 *ov5645 = to_ov5645(subdev); in ov5645_s_stream() local
983 ret = pm_runtime_resume_and_get(ov5645->dev); in ov5645_s_stream()
987 ret = ov5645_set_register_array(ov5645, in ov5645_s_stream()
988 ov5645->current_mode->data, in ov5645_s_stream()
989 ov5645->current_mode->data_size); in ov5645_s_stream()
991 dev_err(ov5645->dev, "could not set mode %dx%d\n", in ov5645_s_stream()
992 ov5645->current_mode->width, in ov5645_s_stream()
993 ov5645->current_mode->height); in ov5645_s_stream()
996 ret = v4l2_ctrl_handler_setup(&ov5645->ctrls); in ov5645_s_stream()
998 dev_err(ov5645->dev, "could not sync v4l2 controls\n"); in ov5645_s_stream()
1002 ret = ov5645_write_reg(ov5645, OV5645_IO_MIPI_CTRL00, 0x45); in ov5645_s_stream()
1006 ret = ov5645_write_reg(ov5645, OV5645_SYSTEM_CTRL0, in ov5645_s_stream()
1011 ret = ov5645_write_reg(ov5645, OV5645_IO_MIPI_CTRL00, 0x40); in ov5645_s_stream()
1015 ret = ov5645_write_reg(ov5645, OV5645_SYSTEM_CTRL0, in ov5645_s_stream()
1024 pm_runtime_put_sync(ov5645->dev); in ov5645_s_stream()
1028 pm_runtime_mark_last_busy(ov5645->dev); in ov5645_s_stream()
1029 pm_runtime_put_autosuspend(ov5645->dev); in ov5645_s_stream()
1058 struct ov5645 *ov5645; in ov5645_probe() local
1064 ov5645 = devm_kzalloc(dev, sizeof(struct ov5645), GFP_KERNEL); in ov5645_probe()
1065 if (!ov5645) in ov5645_probe()
1068 ov5645->i2c_client = client; in ov5645_probe()
1069 ov5645->dev = dev; in ov5645_probe()
1078 &ov5645->ep); in ov5645_probe()
1087 if (ov5645->ep.bus_type != V4L2_MBUS_CSI2_DPHY) { in ov5645_probe()
1093 ov5645->xclk = devm_clk_get(dev, NULL); in ov5645_probe()
1094 if (IS_ERR(ov5645->xclk)) { in ov5645_probe()
1096 return PTR_ERR(ov5645->xclk); in ov5645_probe()
1112 ret = clk_set_rate(ov5645->xclk, xclk_freq); in ov5645_probe()
1119 ov5645->supplies[i].supply = ov5645_supply_name[i]; in ov5645_probe()
1122 ov5645->supplies); in ov5645_probe()
1126 ov5645->enable_gpio = devm_gpiod_get(dev, "enable", GPIOD_OUT_HIGH); in ov5645_probe()
1127 if (IS_ERR(ov5645->enable_gpio)) { in ov5645_probe()
1129 return PTR_ERR(ov5645->enable_gpio); in ov5645_probe()
1132 ov5645->rst_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); in ov5645_probe()
1133 if (IS_ERR(ov5645->rst_gpio)) { in ov5645_probe()
1135 return PTR_ERR(ov5645->rst_gpio); in ov5645_probe()
1138 mutex_init(&ov5645->power_lock); in ov5645_probe()
1140 v4l2_ctrl_handler_init(&ov5645->ctrls, 9); in ov5645_probe()
1141 v4l2_ctrl_new_std(&ov5645->ctrls, &ov5645_ctrl_ops, in ov5645_probe()
1143 v4l2_ctrl_new_std(&ov5645->ctrls, &ov5645_ctrl_ops, in ov5645_probe()
1145 v4l2_ctrl_new_std(&ov5645->ctrls, &ov5645_ctrl_ops, in ov5645_probe()
1147 v4l2_ctrl_new_std(&ov5645->ctrls, &ov5645_ctrl_ops, in ov5645_probe()
1149 v4l2_ctrl_new_std(&ov5645->ctrls, &ov5645_ctrl_ops, in ov5645_probe()
1151 v4l2_ctrl_new_std_menu(&ov5645->ctrls, &ov5645_ctrl_ops, in ov5645_probe()
1154 v4l2_ctrl_new_std_menu_items(&ov5645->ctrls, &ov5645_ctrl_ops, in ov5645_probe()
1158 ov5645->pixel_clock = v4l2_ctrl_new_std(&ov5645->ctrls, in ov5645_probe()
1162 ov5645->link_freq = v4l2_ctrl_new_int_menu(&ov5645->ctrls, in ov5645_probe()
1167 if (ov5645->link_freq) in ov5645_probe()
1168 ov5645->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY; in ov5645_probe()
1170 ov5645->sd.ctrl_handler = &ov5645->ctrls; in ov5645_probe()
1172 if (ov5645->ctrls.error) { in ov5645_probe()
1174 __func__, ov5645->ctrls.error); in ov5645_probe()
1175 ret = ov5645->ctrls.error; in ov5645_probe()
1179 v4l2_i2c_subdev_init(&ov5645->sd, client, &ov5645_subdev_ops); in ov5645_probe()
1180 ov5645->sd.internal_ops = &ov5645_internal_ops; in ov5645_probe()
1181 ov5645->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; in ov5645_probe()
1182 ov5645->pad.flags = MEDIA_PAD_FL_SOURCE; in ov5645_probe()
1183 ov5645->sd.dev = &client->dev; in ov5645_probe()
1184 ov5645->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; in ov5645_probe()
1186 ret = media_entity_pads_init(&ov5645->sd.entity, 1, &ov5645->pad); in ov5645_probe()
1196 ret = ov5645_read_reg(ov5645, OV5645_CHIP_ID_HIGH, &chip_id_high); in ov5645_probe()
1202 ret = ov5645_read_reg(ov5645, OV5645_CHIP_ID_LOW, &chip_id_low); in ov5645_probe()
1209 dev_info(dev, "OV5645 detected at address 0x%02x\n", client->addr); in ov5645_probe()
1211 ret = ov5645_read_reg(ov5645, OV5645_AEC_PK_MANUAL, in ov5645_probe()
1212 &ov5645->aec_pk_manual); in ov5645_probe()
1219 ret = ov5645_read_reg(ov5645, OV5645_TIMING_TC_REG20, in ov5645_probe()
1220 &ov5645->timing_tc_reg20); in ov5645_probe()
1227 ret = ov5645_read_reg(ov5645, OV5645_TIMING_TC_REG21, in ov5645_probe()
1228 &ov5645->timing_tc_reg21); in ov5645_probe()
1239 ov5645_init_state(&ov5645->sd, NULL); in ov5645_probe()
1241 ret = v4l2_async_register_subdev(&ov5645->sd); in ov5645_probe()
1260 media_entity_cleanup(&ov5645->sd.entity); in ov5645_probe()
1262 v4l2_ctrl_handler_free(&ov5645->ctrls); in ov5645_probe()
1263 mutex_destroy(&ov5645->power_lock); in ov5645_probe()
1271 struct ov5645 *ov5645 = to_ov5645(sd); in ov5645_remove() local
1273 v4l2_async_unregister_subdev(&ov5645->sd); in ov5645_remove()
1274 media_entity_cleanup(&ov5645->sd.entity); in ov5645_remove()
1275 v4l2_ctrl_handler_free(&ov5645->ctrls); in ov5645_remove()
1276 pm_runtime_disable(ov5645->dev); in ov5645_remove()
1277 if (!pm_runtime_status_suspended(ov5645->dev)) in ov5645_remove()
1278 ov5645_set_power_off(ov5645->dev); in ov5645_remove()
1279 pm_runtime_set_suspended(ov5645->dev); in ov5645_remove()
1280 mutex_destroy(&ov5645->power_lock); in ov5645_remove()
1284 { "ov5645" },
1290 { .compatible = "ovti,ov5645" },
1302 .name = "ov5645",
1312 MODULE_DESCRIPTION("Omnivision OV5645 Camera Driver");