Lines Matching +full:dw9807 +full:- +full:vcm
1 // SPDX-License-Identifier: GPL-2.0
10 #include <media/v4l2-ctrls.h>
11 #include <media/v4l2-device.h>
30 * DW9807 separates two registers to control the VCM position.
61 dev_err(&client->dev, "I2C write STATUS address fail ret = %d\n", in dw9807_i2c_check()
68 dev_err(&client->dev, "I2C read STATUS value fail ret = %d\n", in dw9807_i2c_check()
85 * write VCM position. This ensure that we really write the value in dw9807_set_dac()
93 dev_warn(&client->dev, in dw9807_set_dac()
94 "Cannot do the write operation because VCM is busy\n"); in dw9807_set_dac()
97 return ret ? -EBUSY : val; in dw9807_set_dac()
100 /* Write VCM position to registers */ in dw9807_set_dac()
103 dev_err(&client->dev, in dw9807_set_dac()
114 struct dw9807_device *dev_vcm = container_of(ctrl->handler, in dw9807_set_ctrl()
117 if (ctrl->id == V4L2_CID_FOCUS_ABSOLUTE) { in dw9807_set_ctrl()
118 struct i2c_client *client = v4l2_get_subdevdata(&dev_vcm->sd); in dw9807_set_ctrl()
120 dev_vcm->current_val = ctrl->val; in dw9807_set_ctrl()
121 return dw9807_set_dac(client, ctrl->val); in dw9807_set_ctrl()
124 return -EINVAL; in dw9807_set_ctrl()
133 return pm_runtime_resume_and_get(sd->dev); in dw9807_open()
138 pm_runtime_put(sd->dev); in dw9807_close()
152 v4l2_async_unregister_subdev(&dw9807_dev->sd); in dw9807_subdev_cleanup()
153 v4l2_ctrl_handler_free(&dw9807_dev->ctrls_vcm); in dw9807_subdev_cleanup()
154 media_entity_cleanup(&dw9807_dev->sd.entity); in dw9807_subdev_cleanup()
159 struct v4l2_ctrl_handler *hdl = &dev_vcm->ctrls_vcm; in dw9807_init_controls()
161 struct i2c_client *client = v4l2_get_subdevdata(&dev_vcm->sd); in dw9807_init_controls()
168 dev_vcm->sd.ctrl_handler = hdl; in dw9807_init_controls()
169 if (hdl->error) { in dw9807_init_controls()
170 dev_err(&client->dev, "%s fail error: 0x%x\n", in dw9807_init_controls()
171 __func__, hdl->error); in dw9807_init_controls()
172 return hdl->error; in dw9807_init_controls()
183 dw9807_dev = devm_kzalloc(&client->dev, sizeof(*dw9807_dev), in dw9807_probe()
186 return -ENOMEM; in dw9807_probe()
188 v4l2_i2c_subdev_init(&dw9807_dev->sd, client, &dw9807_ops); in dw9807_probe()
189 dw9807_dev->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; in dw9807_probe()
190 dw9807_dev->sd.internal_ops = &dw9807_int_ops; in dw9807_probe()
196 rval = media_entity_pads_init(&dw9807_dev->sd.entity, 0, NULL); in dw9807_probe()
200 dw9807_dev->sd.entity.function = MEDIA_ENT_F_LENS; in dw9807_probe()
202 rval = v4l2_async_register_subdev(&dw9807_dev->sd); in dw9807_probe()
206 pm_runtime_set_active(&client->dev); in dw9807_probe()
207 pm_runtime_enable(&client->dev); in dw9807_probe()
208 pm_runtime_idle(&client->dev); in dw9807_probe()
213 v4l2_ctrl_handler_free(&dw9807_dev->ctrls_vcm); in dw9807_probe()
214 media_entity_cleanup(&dw9807_dev->sd.entity); in dw9807_probe()
224 pm_runtime_disable(&client->dev); in dw9807_remove()
230 * This function sets the vcm position, so it consumes least current
242 for (val = dw9807_dev->current_val & ~(DW9807_CTRL_STEPS - 1); in dw9807_vcm_suspend()
243 val >= 0; val -= DW9807_CTRL_STEPS) { in dw9807_vcm_suspend()
253 dev_err(&client->dev, "I2C write CTL fail ret = %d\n", ret); in dw9807_vcm_suspend()
261 * This function sets the vcm position to the value set by the user
277 dev_err(&client->dev, "I2C write CTL fail ret = %d\n", ret); in dw9807_vcm_resume()
281 for (val = dw9807_dev->current_val % DW9807_CTRL_STEPS; in dw9807_vcm_resume()
282 val < dw9807_dev->current_val + DW9807_CTRL_STEPS - 1; in dw9807_vcm_resume()
295 { .compatible = "dongwoon,dw9807-vcm" },
297 { .compatible = "dongwoon,dw9807" },
309 .name = "dw9807",
320 MODULE_DESCRIPTION("DW9807 VCM driver");