Lines Matching +full:lens +full:- +full:focus
1 // SPDX-License-Identifier: GPL-2.0
7 * latte-l-oss/drivers/external_drivers/camera/drivers/media/i2c/micam/dw9761.c
17 #include <media/v4l2-cci.h>
18 #include <media/v4l2-common.h>
19 #include <media/v4l2-ctrls.h>
20 #include <media/v4l2-subdev.h>
72 struct v4l2_ctrl *focus; member
78 return regulator_disable(dw9719->regulator); in dw9719_power_down()
86 ret = regulator_enable(dw9719->regulator); in dw9719_power_up()
91 cci_write(dw9719->regmap, DW9719_CONTROL, DW9719_SHUTDOWN, &ret); in dw9719_power_up()
93 cci_write(dw9719->regmap, DW9719_CONTROL, DW9719_STANDBY, &ret); in dw9719_power_up()
98 ret = cci_read(dw9719->regmap, DW9719_INFO, &val, NULL); in dw9719_power_up()
104 dw9719->model = DW9719; in dw9719_power_up()
105 dw9719->mode_low_bits = 0x00; in dw9719_power_up()
106 dw9719->sac_mode = DW9719_DEFAULT_SAC; in dw9719_power_up()
107 dw9719->vcm_freq = DW9719_DEFAULT_VCM_FREQ; in dw9719_power_up()
110 dw9719->model = DW9761; in dw9719_power_up()
111 dw9719->mode_low_bits = 0x01; in dw9719_power_up()
112 dw9719->sac_mode = DW9761_DEFAULT_SAC; in dw9719_power_up()
113 dw9719->vcm_freq = DW9761_DEFAULT_VCM_FREQ; in dw9719_power_up()
116 dev_err(dw9719->dev, in dw9719_power_up()
118 return -ENXIO; in dw9719_power_up()
122 device_property_read_u32(dw9719->dev, "dongwoon,sac-mode", in dw9719_power_up()
123 &dw9719->sac_mode); in dw9719_power_up()
126 device_property_read_u32(dw9719->dev, "dongwoon,vcm-freq", in dw9719_power_up()
127 &dw9719->vcm_freq); in dw9719_power_up()
130 cci_write(dw9719->regmap, DW9719_CONTROL, DW9719_ENABLE_RINGING, &ret); in dw9719_power_up()
131 cci_write(dw9719->regmap, DW9719_MODE, dw9719->mode_low_bits | in dw9719_power_up()
132 (dw9719->sac_mode << DW9719_MODE_SAC_SHIFT), &ret); in dw9719_power_up()
133 cci_write(dw9719->regmap, DW9719_VCM_FREQ, dw9719->vcm_freq, &ret); in dw9719_power_up()
135 if (dw9719->model == DW9761) in dw9719_power_up()
136 cci_write(dw9719->regmap, DW9761_VCM_PRELOAD, in dw9719_power_up()
147 return cci_write(dw9719->regmap, DW9719_VCM_CURRENT, value, NULL); in dw9719_t_focus_abs()
152 struct dw9719_device *dw9719 = container_of(ctrl->handler, in dw9719_set_ctrl()
158 if (!pm_runtime_get_if_in_use(dw9719->dev)) in dw9719_set_ctrl()
161 switch (ctrl->id) { in dw9719_set_ctrl()
163 ret = dw9719_t_focus_abs(dw9719, ctrl->val); in dw9719_set_ctrl()
166 ret = -EINVAL; in dw9719_set_ctrl()
169 pm_runtime_put(dw9719->dev); in dw9719_set_ctrl()
185 for (val = dw9719->ctrls.focus->val; val >= 0; in dw9719_suspend()
186 val -= DW9719_CTRL_STEPS) { in dw9719_suspend()
201 int current_focus = dw9719->ctrls.focus->val; in dw9719_resume()
227 return pm_runtime_resume_and_get(sd->dev); in dw9719_open()
232 pm_runtime_put(sd->dev); in dw9719_close()
247 v4l2_ctrl_handler_init(&dw9719->ctrls.handler, 1); in dw9719_init_controls()
249 dw9719->ctrls.focus = v4l2_ctrl_new_std(&dw9719->ctrls.handler, ops, in dw9719_init_controls()
253 if (dw9719->ctrls.handler.error) { in dw9719_init_controls()
254 dev_err(dw9719->dev, "Error initialising v4l2 ctrls\n"); in dw9719_init_controls()
255 ret = dw9719->ctrls.handler.error; in dw9719_init_controls()
259 dw9719->sd.ctrl_handler = &dw9719->ctrls.handler; in dw9719_init_controls()
263 v4l2_ctrl_handler_free(&dw9719->ctrls.handler); in dw9719_init_controls()
274 dw9719 = devm_kzalloc(&client->dev, sizeof(*dw9719), GFP_KERNEL); in dw9719_probe()
276 return -ENOMEM; in dw9719_probe()
278 dw9719->regmap = devm_cci_regmap_init_i2c(client, 8); in dw9719_probe()
279 if (IS_ERR(dw9719->regmap)) in dw9719_probe()
280 return PTR_ERR(dw9719->regmap); in dw9719_probe()
282 dw9719->dev = &client->dev; in dw9719_probe()
284 dw9719->regulator = devm_regulator_get(&client->dev, "vdd"); in dw9719_probe()
285 if (IS_ERR(dw9719->regulator)) in dw9719_probe()
286 return dev_err_probe(&client->dev, PTR_ERR(dw9719->regulator), in dw9719_probe()
289 v4l2_i2c_subdev_init(&dw9719->sd, client, &dw9719_ops); in dw9719_probe()
290 dw9719->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; in dw9719_probe()
291 dw9719->sd.internal_ops = &dw9719_internal_ops; in dw9719_probe()
297 ret = media_entity_pads_init(&dw9719->sd.entity, 0, NULL); in dw9719_probe()
301 dw9719->sd.entity.function = MEDIA_ENT_F_LENS; in dw9719_probe()
306 * runtime pm is disabled this will leave the chip on, so that the lens in dw9719_probe()
314 pm_runtime_set_active(&client->dev); in dw9719_probe()
315 pm_runtime_get_noresume(&client->dev); in dw9719_probe()
316 pm_runtime_enable(&client->dev); in dw9719_probe()
318 ret = v4l2_async_register_subdev(&dw9719->sd); in dw9719_probe()
322 pm_runtime_set_autosuspend_delay(&client->dev, 1000); in dw9719_probe()
323 pm_runtime_use_autosuspend(&client->dev); in dw9719_probe()
324 pm_runtime_put_autosuspend(&client->dev); in dw9719_probe()
329 pm_runtime_disable(&client->dev); in dw9719_probe()
330 pm_runtime_put_noidle(&client->dev); in dw9719_probe()
333 media_entity_cleanup(&dw9719->sd.entity); in dw9719_probe()
335 v4l2_ctrl_handler_free(&dw9719->ctrls.handler); in dw9719_probe()
347 v4l2_ctrl_handler_free(&dw9719->ctrls.handler); in dw9719_remove()
348 media_entity_cleanup(&dw9719->sd.entity); in dw9719_remove()
350 pm_runtime_disable(&client->dev); in dw9719_remove()
351 if (!pm_runtime_status_suspended(&client->dev)) in dw9719_remove()
353 pm_runtime_set_suspended(&client->dev); in dw9719_remove()