Lines Matching +full:ctrl +full:- +full:module

1 // SPDX-License-Identifier: GPL-2.0
10 #include <linux/module.h>
12 #include <linux/rk-camera-module.h>
14 #include <media/v4l2-ctrls.h>
15 #include <media/v4l2-device.h>
74 static inline struct dw9763_device *to_dw9763_vcm(struct v4l2_ctrl *ctrl) in to_dw9763_vcm() argument
76 return container_of(ctrl->handler, struct dw9763_device, ctrls_vcm); in to_dw9763_vcm()
93 return -EINVAL; in dw9763_write_reg()
100 val_i = 4 - len; in dw9763_write_reg()
106 dev_err(&client->dev, "Failed to write 0x%04x,0x%x\n", reg, val); in dw9763_write_reg()
107 return -EIO; in dw9763_write_reg()
109 dev_dbg(&client->dev, "succeed to write 0x%04x,0x%x\n", reg, val); in dw9763_write_reg()
125 return -EINVAL; in dw9763_read_reg()
129 msgs[0].addr = client->addr; in dw9763_read_reg()
135 msgs[1].addr = client->addr; in dw9763_read_reg()
138 msgs[1].buf = &data_be_p[4 - len]; in dw9763_read_reg()
140 ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); in dw9763_read_reg()
142 return -EIO; in dw9763_read_reg()
152 struct i2c_client *client = dev_vcm->client; in dw9763_move_time_div()
155 switch (dev_vcm->t_div) { in dw9763_move_time_div()
175 dev_err(&client->dev, "%s: t_div parameter err %d\n", __func__, dev_vcm->t_div); in dw9763_move_time_div()
185 struct i2c_client *client = dev_vcm->client; in dw9763_move_time()
188 switch (dev_vcm->step_mode) { in dw9763_move_time()
194 move_time_us = 6300 + dev_vcm->t_src * 100; in dw9763_move_time()
201 dev_err(&client->dev, in dw9763_move_time()
203 __func__, dev_vcm->step_mode); in dw9763_move_time()
207 dev_dbg(&client->dev, in dw9763_move_time()
217 struct i2c_client *client = v4l2_get_subdevdata(&dev_vcm->sd); in dw9763_set_dac()
231 dev_dbg(&client->dev, in dw9763_set_dac()
236 dev_err(&client->dev, in dw9763_set_dac()
243 struct i2c_client *client = v4l2_get_subdevdata(&dev_vcm->sd); in dw9763_get_dac()
252 dev_dbg(&client->dev, "%s: get dac %d\n", __func__, *cur_dac); in dw9763_get_dac()
257 dev_err(&client->dev, in dw9763_get_dac()
265 struct i2c_client *client = dev_vcm->client; in dw9763_get_pos()
273 if (abs_step <= dev_vcm->start_current) in dw9763_get_pos()
275 else if ((abs_step > dev_vcm->start_current) && in dw9763_get_pos()
276 (abs_step <= dev_vcm->rated_current)) in dw9763_get_pos()
277 abs_step = (dev_vcm->rated_current - abs_step) / dev_vcm->step; in dw9763_get_pos()
282 dev_dbg(&client->dev, "%s: get position %d\n", __func__, *cur_pos); in dw9763_get_pos()
286 dev_err(&client->dev, in dw9763_get_pos()
296 struct i2c_client *client = dev_vcm->client; in dw9763_set_pos()
299 position = dev_vcm->start_current; in dw9763_set_pos()
301 position = dev_vcm->start_current + in dw9763_set_pos()
302 (dev_vcm->step * (VCMDRV_MAX_LOG - dest_pos)); in dw9763_set_pos()
307 dev_vcm->current_lens_pos = position; in dw9763_set_pos()
308 dev_vcm->current_related_pos = dest_pos; in dw9763_set_pos()
311 dev_dbg(&client->dev, "%s: set position %d, dac %d\n", __func__, dest_pos, position); in dw9763_set_pos()
316 static int dw9763_get_ctrl(struct v4l2_ctrl *ctrl) in dw9763_get_ctrl() argument
318 struct dw9763_device *dev_vcm = to_dw9763_vcm(ctrl); in dw9763_get_ctrl()
320 if (ctrl->id == V4L2_CID_FOCUS_ABSOLUTE) in dw9763_get_ctrl()
321 return dw9763_get_pos(dev_vcm, &ctrl->val); in dw9763_get_ctrl()
323 return -EINVAL; in dw9763_get_ctrl()
326 static int dw9763_set_ctrl(struct v4l2_ctrl *ctrl) in dw9763_set_ctrl() argument
328 struct dw9763_device *dev_vcm = to_dw9763_vcm(ctrl); in dw9763_set_ctrl()
329 struct i2c_client *client = dev_vcm->client; in dw9763_set_ctrl()
330 unsigned int dest_pos = ctrl->val; in dw9763_set_ctrl()
334 dev_dbg(&client->dev, "ctrl->id: 0x%x, ctrl->val: 0x%x\n", in dw9763_set_ctrl()
335 ctrl->id, ctrl->val); in dw9763_set_ctrl()
337 if (ctrl->id == V4L2_CID_FOCUS_ABSOLUTE) { in dw9763_set_ctrl()
340 dev_info(&client->dev, in dw9763_set_ctrl()
343 return -EINVAL; in dw9763_set_ctrl()
348 dev_vcm->move_us = dev_vcm->vcm_movefull_t; in dw9763_set_ctrl()
350 dev_dbg(&client->dev, in dw9763_set_ctrl()
352 dest_pos, dev_vcm->move_us); in dw9763_set_ctrl()
354 dev_vcm->start_move_tv = ns_to_kernel_old_timeval(ktime_get_ns()); in dw9763_set_ctrl()
355 mv_us = dev_vcm->start_move_tv.tv_usec + in dw9763_set_ctrl()
356 dev_vcm->move_us; in dw9763_set_ctrl()
358 dev_vcm->end_move_tv.tv_sec = in dw9763_set_ctrl()
359 dev_vcm->start_move_tv.tv_sec + 1; in dw9763_set_ctrl()
360 dev_vcm->end_move_tv.tv_usec = mv_us - 1000000; in dw9763_set_ctrl()
362 dev_vcm->end_move_tv.tv_sec = in dw9763_set_ctrl()
363 dev_vcm->start_move_tv.tv_sec; in dw9763_set_ctrl()
364 dev_vcm->end_move_tv.tv_usec = mv_us; in dw9763_set_ctrl()
380 rval = pm_runtime_get_sync(sd->dev); in dw9763_open()
382 pm_runtime_put_noidle(sd->dev); in dw9763_open()
391 pm_runtime_put(sd->dev); in dw9763_close()
403 struct i2c_client *client = dev_vcm->client; in dw9763_update_vcm_cfg()
406 if (dev_vcm->max_ma == 0) { in dw9763_update_vcm_cfg()
407 dev_err(&client->dev, "max current is zero"); in dw9763_update_vcm_cfg()
411 cur_dist = dev_vcm->vcm_cfg.rated_ma - dev_vcm->vcm_cfg.start_ma; in dw9763_update_vcm_cfg()
412 cur_dist = cur_dist * DW9763_MAX_REG / dev_vcm->max_ma; in dw9763_update_vcm_cfg()
413 dev_vcm->step = (cur_dist + (VCMDRV_MAX_LOG - 1)) / VCMDRV_MAX_LOG; in dw9763_update_vcm_cfg()
414 dev_vcm->start_current = dev_vcm->vcm_cfg.start_ma * in dw9763_update_vcm_cfg()
415 DW9763_MAX_REG / dev_vcm->max_ma; in dw9763_update_vcm_cfg()
416 dev_vcm->rated_current = dev_vcm->vcm_cfg.rated_ma * in dw9763_update_vcm_cfg()
417 DW9763_MAX_REG / dev_vcm->max_ma; in dw9763_update_vcm_cfg()
418 dev_vcm->step_mode = dev_vcm->vcm_cfg.step_mode; in dw9763_update_vcm_cfg()
420 dev_info(&client->dev, in dw9763_update_vcm_cfg()
422 dev_vcm->vcm_cfg.start_ma, in dw9763_update_vcm_cfg()
423 dev_vcm->vcm_cfg.rated_ma, in dw9763_update_vcm_cfg()
424 dev_vcm->vcm_cfg.step_mode, in dw9763_update_vcm_cfg()
425 dev_vcm->max_ma); in dw9763_update_vcm_cfg()
431 struct i2c_client *client = dev_vcm->client; in dw9763_ioctl()
439 vcm_tim->vcm_start_t.tv_sec = dev_vcm->start_move_tv.tv_sec; in dw9763_ioctl()
440 vcm_tim->vcm_start_t.tv_usec = in dw9763_ioctl()
441 dev_vcm->start_move_tv.tv_usec; in dw9763_ioctl()
442 vcm_tim->vcm_end_t.tv_sec = dev_vcm->end_move_tv.tv_sec; in dw9763_ioctl()
443 vcm_tim->vcm_end_t.tv_usec = dev_vcm->end_move_tv.tv_usec; in dw9763_ioctl()
445 dev_dbg(&client->dev, "dw9763_get_move_res 0x%lx, 0x%lx, 0x%lx, 0x%lx\n", in dw9763_ioctl()
446 vcm_tim->vcm_start_t.tv_sec, in dw9763_ioctl()
447 vcm_tim->vcm_start_t.tv_usec, in dw9763_ioctl()
448 vcm_tim->vcm_end_t.tv_sec, in dw9763_ioctl()
449 vcm_tim->vcm_end_t.tv_usec); in dw9763_ioctl()
453 vcm_cfg->start_ma = dev_vcm->vcm_cfg.start_ma; in dw9763_ioctl()
454 vcm_cfg->rated_ma = dev_vcm->vcm_cfg.rated_ma; in dw9763_ioctl()
455 vcm_cfg->step_mode = dev_vcm->vcm_cfg.step_mode; in dw9763_ioctl()
459 if (vcm_cfg->start_ma == 0 && vcm_cfg->rated_ma == 0) { in dw9763_ioctl()
460 dev_err(&client->dev, in dw9763_ioctl()
462 vcm_cfg->start_ma, vcm_cfg->rated_ma); in dw9763_ioctl()
463 return -EINVAL; in dw9763_ioctl()
465 dev_vcm->vcm_cfg.start_ma = vcm_cfg->start_ma; in dw9763_ioctl()
466 dev_vcm->vcm_cfg.rated_ma = vcm_cfg->rated_ma; in dw9763_ioctl()
467 dev_vcm->vcm_cfg.step_mode = vcm_cfg->step_mode; in dw9763_ioctl()
470 dev_err(&client->dev, in dw9763_ioctl()
472 return -EINVAL; in dw9763_ioctl()
483 struct i2c_client *client = dev_vcm->client; in dw9763_compat_ioctl32()
500 &p32->vcm_start_t.tv_sec); in dw9763_compat_ioctl32()
502 &p32->vcm_start_t.tv_usec); in dw9763_compat_ioctl32()
504 &p32->vcm_end_t.tv_sec); in dw9763_compat_ioctl32()
506 &p32->vcm_end_t.tv_usec); in dw9763_compat_ioctl32()
512 ret = -EFAULT; in dw9763_compat_ioctl32()
519 ret = -EFAULT; in dw9763_compat_ioctl32()
521 dev_err(&client->dev, in dw9763_compat_ioctl32()
523 return -EINVAL; in dw9763_compat_ioctl32()
543 v4l2_device_unregister_subdev(&dw9763_dev->sd); in dw9763_subdev_cleanup()
544 v4l2_device_unregister(&dw9763_dev->vdev); in dw9763_subdev_cleanup()
545 v4l2_ctrl_handler_free(&dw9763_dev->ctrls_vcm); in dw9763_subdev_cleanup()
546 media_entity_cleanup(&dw9763_dev->sd.entity); in dw9763_subdev_cleanup()
551 struct v4l2_ctrl_handler *hdl = &dev_vcm->ctrls_vcm; in dw9763_init_controls()
559 if (hdl->error) in dw9763_init_controls()
560 dev_err(dev_vcm->sd.dev, "%s fail error: 0x%x\n", in dw9763_init_controls()
561 __func__, hdl->error); in dw9763_init_controls()
562 dev_vcm->sd.ctrl_handler = hdl; in dw9763_init_controls()
563 return hdl->error; in dw9763_init_controls()
611 for (i--; i >= 0 ; i--) in add_sysfs_interfaces()
614 return -ENODEV; in add_sysfs_interfaces()
639 if (dw9763_dev->power_gpio) in __dw9763_set_power()
640 gpiod_direction_output(dw9763_dev->power_gpio, on); in __dw9763_set_power()
650 struct i2c_client *client = dw9763_dev->client; in dw9763_check_id()
651 struct device *dev = &client->dev; in dw9763_check_id()
658 return -ENODEV; in dw9763_check_id()
661 dev_info(&dw9763_dev->client->dev, in dw9763_check_id()
676 dev_err(&client->dev, "probe init failed with error %d\n", ret); in dw9763_probe_init()
677 return -1; in dw9763_probe_init()
683 struct device_node *np = of_node_get(client->dev.of_node); in dw9763_probe()
691 dev_info(&client->dev, "probing...\n"); in dw9763_probe()
696 dev_info(&client->dev, in dw9763_probe()
697 "could not get module %s from dts!\n", in dw9763_probe()
707 dev_info(&client->dev, in dw9763_probe()
708 "could not get module %s from dts!\n", in dw9763_probe()
715 dev_info(&client->dev, in dw9763_probe()
716 "could not get module %s from dts!\n", in dw9763_probe()
723 dev_info(&client->dev, in dw9763_probe()
724 "could not get module %s from dts!\n", in dw9763_probe()
732 dev_info(&client->dev, in dw9763_probe()
733 "could not get module %s from dts!\n", in dw9763_probe()
741 dev_info(&client->dev, in dw9763_probe()
742 "could not get module %s from dts!\n", in dw9763_probe()
746 dw9763_dev = devm_kzalloc(&client->dev, sizeof(*dw9763_dev), in dw9763_probe()
749 return -ENOMEM; in dw9763_probe()
752 &dw9763_dev->module_index); in dw9763_probe()
754 &dw9763_dev->module_facing); in dw9763_probe()
756 dev_err(&client->dev, in dw9763_probe()
757 "could not get module information!\n"); in dw9763_probe()
758 return -EINVAL; in dw9763_probe()
760 dw9763_dev->client = client; in dw9763_probe()
761 dw9763_dev->power_gpio = devm_gpiod_get(&client->dev, in dw9763_probe()
763 if (IS_ERR(dw9763_dev->power_gpio)) { in dw9763_probe()
764 dw9763_dev->power_gpio = NULL; in dw9763_probe()
765 dev_warn(&client->dev, in dw9763_probe()
766 "Failed to get power-gpios, maybe no use\n"); in dw9763_probe()
772 v4l2_i2c_subdev_init(&dw9763_dev->sd, client, &dw9763_ops); in dw9763_probe()
773 dw9763_dev->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; in dw9763_probe()
774 dw9763_dev->sd.internal_ops = &dw9763_int_ops; in dw9763_probe()
780 ret = media_entity_pads_init(&dw9763_dev->sd.entity, 0, NULL); in dw9763_probe()
784 sd = &dw9763_dev->sd; in dw9763_probe()
785 sd->entity.function = MEDIA_ENT_F_LENS; in dw9763_probe()
788 if (strcmp(dw9763_dev->module_facing, "back") == 0) in dw9763_probe()
793 snprintf(sd->name, sizeof(sd->name), "m%02d_%s_%s %s", in dw9763_probe()
794 dw9763_dev->module_index, facing, in dw9763_probe()
795 DW9763_NAME, dev_name(sd->dev)); in dw9763_probe()
798 dev_err(&client->dev, "v4l2 async register subdev failed\n"); in dw9763_probe()
800 dw9763_dev->max_ma = max_ma; in dw9763_probe()
801 dw9763_dev->vcm_cfg.start_ma = start_ma; in dw9763_probe()
802 dw9763_dev->vcm_cfg.rated_ma = rated_ma; in dw9763_probe()
803 dw9763_dev->vcm_cfg.step_mode = step_mode; in dw9763_probe()
805 dw9763_dev->move_us = 0; in dw9763_probe()
806 dw9763_dev->current_related_pos = VCMDRV_MAX_LOG; in dw9763_probe()
807 dw9763_dev->start_move_tv = ns_to_kernel_old_timeval(ktime_get_ns()); in dw9763_probe()
808 dw9763_dev->end_move_tv = ns_to_kernel_old_timeval(ktime_get_ns()); in dw9763_probe()
810 dw9763_dev->t_src = t_src; in dw9763_probe()
811 dw9763_dev->t_div = t_div; in dw9763_probe()
814 mutex_init(&dw9763_dev->lock); in dw9763_probe()
816 dw9763_dev->vcm_movefull_t = in dw9763_probe()
818 pm_runtime_set_active(&client->dev); in dw9763_probe()
819 pm_runtime_enable(&client->dev); in dw9763_probe()
820 pm_runtime_idle(&client->dev); in dw9763_probe()
822 add_sysfs_interfaces(&client->dev); in dw9763_probe()
823 dev_info(&client->dev, "probing successful\n"); in dw9763_probe()
829 dev_err(&client->dev, "Probe failed: %d\n", ret); in dw9763_probe()
838 remove_sysfs_interfaces(&client->dev); in dw9763_remove()
839 mutex_destroy(&dw9763_dev->lock); in dw9763_remove()
840 pm_runtime_disable(&client->dev); in dw9763_remove()
862 if (dev_vcm->step_mode != DIRECT_MODE) in dw9763_init()
867 switch (dev_vcm->step_mode) { in dw9763_init()
873 mode_val |= dev_vcm->step_mode << 5; in dw9763_init()
879 mode_val |= (dev_vcm->t_div & 0x07); in dw9763_init()
880 algo_time = dev_vcm->t_src; in dw9763_init()
891 dev_err(&client->dev, "init failed with error %d\n", ret); in dw9763_init()
892 return -1; in dw9763_init()
903 dev_err(&client->dev, "failed to set power down mode!\n"); in dw9763_vcm_suspend()
914 dw9763_set_pos(dev_vcm, dev_vcm->current_related_pos); in dw9763_vcm_resume()