Lines Matching +full:lens +full:- +full:focus

1 // SPDX-License-Identifier: GPL-2.0
10 #include <media/v4l2-ctrls.h>
11 #include <media/v4l2-device.h>
22 * This sets the minimum granularity for the focus positions.
23 * A value of 1 gives maximum accuracy for a desired focus position
27 * This acts as the minimum granularity of lens movement.
29 * uniformly adjusted for gradual lens movement, with desired
78 struct v4l2_ctrl *focus; member
87 return container_of(ctrl->handler, struct ak7375_device, ctrls_vcm); in to_ak7375_vcm()
98 struct i2c_client *client = v4l2_get_subdevdata(&ak7375->sd); in ak7375_i2c_write()
103 return -EINVAL; in ak7375_i2c_write()
112 return -EIO; in ak7375_i2c_write()
120 const struct ak73xx_chipdef *cdef = dev_vcm->cdef; in ak7375_set_ctrl()
122 if (ctrl->id == V4L2_CID_FOCUS_ABSOLUTE) in ak7375_set_ctrl()
123 return ak7375_i2c_write(dev_vcm, cdef->reg_position, in ak7375_set_ctrl()
124 ctrl->val << cdef->shift_pos, 2); in ak7375_set_ctrl()
126 return -EINVAL; in ak7375_set_ctrl()
135 return pm_runtime_resume_and_get(sd->dev); in ak7375_open()
140 pm_runtime_put(sd->dev); in ak7375_close()
154 v4l2_async_unregister_subdev(&ak7375_dev->sd); in ak7375_subdev_cleanup()
155 v4l2_ctrl_handler_free(&ak7375_dev->ctrls_vcm); in ak7375_subdev_cleanup()
156 media_entity_cleanup(&ak7375_dev->sd.entity); in ak7375_subdev_cleanup()
161 struct v4l2_ctrl_handler *hdl = &dev_vcm->ctrls_vcm; in ak7375_init_controls()
163 const struct ak73xx_chipdef *cdef = dev_vcm->cdef; in ak7375_init_controls()
167 dev_vcm->focus = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FOCUS_ABSOLUTE, in ak7375_init_controls()
168 0, cdef->focus_pos_max, cdef->focus_steps, 0); in ak7375_init_controls()
170 if (hdl->error) in ak7375_init_controls()
171 dev_err(dev_vcm->sd.dev, "%s fail error: 0x%x\n", in ak7375_init_controls()
172 __func__, hdl->error); in ak7375_init_controls()
173 dev_vcm->sd.ctrl_handler = hdl; in ak7375_init_controls()
175 return hdl->error; in ak7375_init_controls()
184 ak7375_dev = devm_kzalloc(&client->dev, sizeof(*ak7375_dev), in ak7375_probe()
187 return -ENOMEM; in ak7375_probe()
189 ak7375_dev->cdef = device_get_match_data(&client->dev); in ak7375_probe()
192 ak7375_dev->supplies[i].supply = ak7375_supply_names[i]; in ak7375_probe()
194 ret = devm_regulator_bulk_get(&client->dev, in ak7375_probe()
196 ak7375_dev->supplies); in ak7375_probe()
198 dev_err_probe(&client->dev, ret, "Failed to get regulators\n"); in ak7375_probe()
202 v4l2_i2c_subdev_init(&ak7375_dev->sd, client, &ak7375_ops); in ak7375_probe()
203 ak7375_dev->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; in ak7375_probe()
204 ak7375_dev->sd.internal_ops = &ak7375_int_ops; in ak7375_probe()
205 ak7375_dev->sd.entity.function = MEDIA_ENT_F_LENS; in ak7375_probe()
211 ret = media_entity_pads_init(&ak7375_dev->sd.entity, 0, NULL); in ak7375_probe()
215 ret = v4l2_async_register_subdev(&ak7375_dev->sd); in ak7375_probe()
219 pm_runtime_set_active(&client->dev); in ak7375_probe()
220 pm_runtime_enable(&client->dev); in ak7375_probe()
221 pm_runtime_idle(&client->dev); in ak7375_probe()
226 v4l2_ctrl_handler_free(&ak7375_dev->ctrls_vcm); in ak7375_probe()
227 media_entity_cleanup(&ak7375_dev->sd.entity); in ak7375_probe()
238 pm_runtime_disable(&client->dev); in ak7375_remove()
239 pm_runtime_set_suspended(&client->dev); in ak7375_remove()
244 * The lens position is gradually moved in units of ctrl_steps,
251 const struct ak73xx_chipdef *cdef = ak7375_dev->cdef; in ak7375_vcm_suspend()
254 if (!ak7375_dev->active) in ak7375_vcm_suspend()
257 for (val = ak7375_dev->focus->val & ~(cdef->ctrl_steps - 1); in ak7375_vcm_suspend()
258 val >= 0; val -= cdef->ctrl_steps) { in ak7375_vcm_suspend()
259 ret = ak7375_i2c_write(ak7375_dev, cdef->reg_position, in ak7375_vcm_suspend()
260 val << cdef->shift_pos, 2); in ak7375_vcm_suspend()
264 usleep_range(cdef->ctrl_delay_us, cdef->ctrl_delay_us + 10); in ak7375_vcm_suspend()
267 if (cdef->has_standby) { in ak7375_vcm_suspend()
268 ret = ak7375_i2c_write(ak7375_dev, cdef->reg_cont, in ak7375_vcm_suspend()
269 cdef->mode_standby, 1); in ak7375_vcm_suspend()
275 ak7375_dev->supplies); in ak7375_vcm_suspend()
279 ak7375_dev->active = false; in ak7375_vcm_suspend()
287 * The lens position is gradually moved in units of ctrl_steps,
294 const struct ak73xx_chipdef *cdef = ak7375_dev->cdef; in ak7375_vcm_resume()
297 if (ak7375_dev->active) in ak7375_vcm_resume()
301 ak7375_dev->supplies); in ak7375_vcm_resume()
306 usleep_range(cdef->power_delay_us, cdef->power_delay_us + 500); in ak7375_vcm_resume()
308 ret = ak7375_i2c_write(ak7375_dev, cdef->reg_cont, in ak7375_vcm_resume()
309 cdef->mode_active, 1); in ak7375_vcm_resume()
315 for (val = ak7375_dev->focus->val % cdef->ctrl_steps; in ak7375_vcm_resume()
316 val <= ak7375_dev->focus->val; in ak7375_vcm_resume()
317 val += cdef->ctrl_steps) { in ak7375_vcm_resume()
318 ret = ak7375_i2c_write(ak7375_dev, cdef->reg_position, in ak7375_vcm_resume()
319 val << cdef->shift_pos, 2); in ak7375_vcm_resume()
323 usleep_range(cdef->ctrl_delay_us, cdef->ctrl_delay_us + 10); in ak7375_vcm_resume()
326 ak7375_dev->active = true; in ak7375_vcm_resume()
332 { .compatible = "asahi-kasei,ak7345", .data = &ak7345_cdef, },
333 { .compatible = "asahi-kasei,ak7375", .data = &ak7375_cdef, },