0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #include <linux/errno.h>
0018 #include <linux/i2c.h>
0019 #include <linux/kernel.h>
0020 #include <linux/module.h>
0021 #include <linux/regulator/consumer.h>
0022 #include <linux/gpio/consumer.h>
0023
0024 #include <media/v4l2-ctrls.h>
0025 #include <media/v4l2-device.h>
0026 #include <media/v4l2-subdev.h>
0027
0028
0029 #define AD5820_POWER_DOWN (1 << 15)
0030 #define AD5820_DAC_SHIFT 4
0031 #define AD5820_RAMP_MODE_LINEAR (0 << 3)
0032 #define AD5820_RAMP_MODE_64_16 (1 << 3)
0033
0034 #define CODE_TO_RAMP_US(s) ((s) == 0 ? 0 : (1 << ((s) - 1)) * 50)
0035 #define RAMP_US_TO_CODE(c) fls(((c) + ((c)>>1)) / 50)
0036
0037 #define to_ad5820_device(sd) container_of(sd, struct ad5820_device, subdev)
0038
0039 struct ad5820_device {
0040 struct v4l2_subdev subdev;
0041 struct ad5820_platform_data *platform_data;
0042 struct regulator *vana;
0043
0044 struct v4l2_ctrl_handler ctrls;
0045 u32 focus_absolute;
0046 u32 focus_ramp_time;
0047 u32 focus_ramp_mode;
0048
0049 struct gpio_desc *enable_gpio;
0050
0051 struct mutex power_lock;
0052 int power_count;
0053
0054 bool standby;
0055 };
0056
0057 static int ad5820_write(struct ad5820_device *coil, u16 data)
0058 {
0059 struct i2c_client *client = v4l2_get_subdevdata(&coil->subdev);
0060 struct i2c_msg msg;
0061 __be16 be_data;
0062 int r;
0063
0064 if (!client->adapter)
0065 return -ENODEV;
0066
0067 be_data = cpu_to_be16(data);
0068 msg.addr = client->addr;
0069 msg.flags = 0;
0070 msg.len = 2;
0071 msg.buf = (u8 *)&be_data;
0072
0073 r = i2c_transfer(client->adapter, &msg, 1);
0074 if (r < 0) {
0075 dev_err(&client->dev, "write failed, error %d\n", r);
0076 return r;
0077 }
0078
0079 return 0;
0080 }
0081
0082
0083
0084
0085
0086
0087 static int ad5820_update_hw(struct ad5820_device *coil)
0088 {
0089 u16 status;
0090
0091 status = RAMP_US_TO_CODE(coil->focus_ramp_time);
0092 status |= coil->focus_ramp_mode
0093 ? AD5820_RAMP_MODE_64_16 : AD5820_RAMP_MODE_LINEAR;
0094 status |= coil->focus_absolute << AD5820_DAC_SHIFT;
0095
0096 if (coil->standby)
0097 status |= AD5820_POWER_DOWN;
0098
0099 return ad5820_write(coil, status);
0100 }
0101
0102
0103
0104
0105 static int ad5820_power_off(struct ad5820_device *coil, bool standby)
0106 {
0107 int ret = 0, ret2;
0108
0109
0110
0111
0112
0113 if (standby) {
0114 coil->standby = true;
0115 ret = ad5820_update_hw(coil);
0116 }
0117
0118 gpiod_set_value_cansleep(coil->enable_gpio, 0);
0119
0120 ret2 = regulator_disable(coil->vana);
0121 if (ret)
0122 return ret;
0123 return ret2;
0124 }
0125
0126 static int ad5820_power_on(struct ad5820_device *coil, bool restore)
0127 {
0128 int ret;
0129
0130 ret = regulator_enable(coil->vana);
0131 if (ret < 0)
0132 return ret;
0133
0134 gpiod_set_value_cansleep(coil->enable_gpio, 1);
0135
0136 if (restore) {
0137
0138 coil->standby = false;
0139 ret = ad5820_update_hw(coil);
0140 if (ret)
0141 goto fail;
0142 }
0143 return 0;
0144
0145 fail:
0146 gpiod_set_value_cansleep(coil->enable_gpio, 0);
0147 coil->standby = true;
0148 regulator_disable(coil->vana);
0149
0150 return ret;
0151 }
0152
0153
0154
0155
0156 static int ad5820_set_ctrl(struct v4l2_ctrl *ctrl)
0157 {
0158 struct ad5820_device *coil =
0159 container_of(ctrl->handler, struct ad5820_device, ctrls);
0160
0161 switch (ctrl->id) {
0162 case V4L2_CID_FOCUS_ABSOLUTE:
0163 coil->focus_absolute = ctrl->val;
0164 return ad5820_update_hw(coil);
0165 }
0166
0167 return 0;
0168 }
0169
0170 static const struct v4l2_ctrl_ops ad5820_ctrl_ops = {
0171 .s_ctrl = ad5820_set_ctrl,
0172 };
0173
0174
0175 static int ad5820_init_controls(struct ad5820_device *coil)
0176 {
0177 v4l2_ctrl_handler_init(&coil->ctrls, 1);
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191 v4l2_ctrl_new_std(&coil->ctrls, &ad5820_ctrl_ops,
0192 V4L2_CID_FOCUS_ABSOLUTE, 0, 1023, 1, 0);
0193
0194 if (coil->ctrls.error)
0195 return coil->ctrls.error;
0196
0197 coil->focus_absolute = 0;
0198 coil->focus_ramp_time = 0;
0199 coil->focus_ramp_mode = 0;
0200
0201 coil->subdev.ctrl_handler = &coil->ctrls;
0202
0203 return 0;
0204 }
0205
0206
0207
0208
0209 static int ad5820_registered(struct v4l2_subdev *subdev)
0210 {
0211 struct ad5820_device *coil = to_ad5820_device(subdev);
0212
0213 return ad5820_init_controls(coil);
0214 }
0215
0216 static int
0217 ad5820_set_power(struct v4l2_subdev *subdev, int on)
0218 {
0219 struct ad5820_device *coil = to_ad5820_device(subdev);
0220 int ret = 0;
0221
0222 mutex_lock(&coil->power_lock);
0223
0224
0225
0226
0227
0228 if (coil->power_count == !on) {
0229 ret = on ? ad5820_power_on(coil, true) :
0230 ad5820_power_off(coil, true);
0231 if (ret < 0)
0232 goto done;
0233 }
0234
0235
0236 coil->power_count += on ? 1 : -1;
0237 WARN_ON(coil->power_count < 0);
0238
0239 done:
0240 mutex_unlock(&coil->power_lock);
0241 return ret;
0242 }
0243
0244 static int ad5820_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
0245 {
0246 return ad5820_set_power(sd, 1);
0247 }
0248
0249 static int ad5820_close(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
0250 {
0251 return ad5820_set_power(sd, 0);
0252 }
0253
0254 static const struct v4l2_subdev_core_ops ad5820_core_ops = {
0255 .s_power = ad5820_set_power,
0256 };
0257
0258 static const struct v4l2_subdev_ops ad5820_ops = {
0259 .core = &ad5820_core_ops,
0260 };
0261
0262 static const struct v4l2_subdev_internal_ops ad5820_internal_ops = {
0263 .registered = ad5820_registered,
0264 .open = ad5820_open,
0265 .close = ad5820_close,
0266 };
0267
0268
0269
0270
0271 static int __maybe_unused ad5820_suspend(struct device *dev)
0272 {
0273 struct v4l2_subdev *subdev = dev_get_drvdata(dev);
0274 struct ad5820_device *coil = to_ad5820_device(subdev);
0275
0276 if (!coil->power_count)
0277 return 0;
0278
0279 return ad5820_power_off(coil, false);
0280 }
0281
0282 static int __maybe_unused ad5820_resume(struct device *dev)
0283 {
0284 struct v4l2_subdev *subdev = dev_get_drvdata(dev);
0285 struct ad5820_device *coil = to_ad5820_device(subdev);
0286
0287 if (!coil->power_count)
0288 return 0;
0289
0290 return ad5820_power_on(coil, true);
0291 }
0292
0293 static int ad5820_probe(struct i2c_client *client,
0294 const struct i2c_device_id *devid)
0295 {
0296 struct ad5820_device *coil;
0297 int ret;
0298
0299 coil = devm_kzalloc(&client->dev, sizeof(*coil), GFP_KERNEL);
0300 if (!coil)
0301 return -ENOMEM;
0302
0303 coil->vana = devm_regulator_get(&client->dev, "VANA");
0304 if (IS_ERR(coil->vana)) {
0305 ret = PTR_ERR(coil->vana);
0306 if (ret != -EPROBE_DEFER)
0307 dev_err(&client->dev, "could not get regulator for vana\n");
0308 return ret;
0309 }
0310
0311 coil->enable_gpio = devm_gpiod_get_optional(&client->dev, "enable",
0312 GPIOD_OUT_LOW);
0313 if (IS_ERR(coil->enable_gpio)) {
0314 ret = PTR_ERR(coil->enable_gpio);
0315 if (ret != -EPROBE_DEFER)
0316 dev_err(&client->dev, "could not get enable gpio\n");
0317 return ret;
0318 }
0319
0320 mutex_init(&coil->power_lock);
0321
0322 v4l2_i2c_subdev_init(&coil->subdev, client, &ad5820_ops);
0323 coil->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
0324 coil->subdev.internal_ops = &ad5820_internal_ops;
0325 coil->subdev.entity.function = MEDIA_ENT_F_LENS;
0326 strscpy(coil->subdev.name, "ad5820 focus", sizeof(coil->subdev.name));
0327
0328 ret = media_entity_pads_init(&coil->subdev.entity, 0, NULL);
0329 if (ret < 0)
0330 goto cleanup2;
0331
0332 ret = v4l2_async_register_subdev(&coil->subdev);
0333 if (ret < 0)
0334 goto cleanup;
0335
0336 return ret;
0337
0338 cleanup2:
0339 mutex_destroy(&coil->power_lock);
0340 cleanup:
0341 media_entity_cleanup(&coil->subdev.entity);
0342 return ret;
0343 }
0344
0345 static int ad5820_remove(struct i2c_client *client)
0346 {
0347 struct v4l2_subdev *subdev = i2c_get_clientdata(client);
0348 struct ad5820_device *coil = to_ad5820_device(subdev);
0349
0350 v4l2_async_unregister_subdev(&coil->subdev);
0351 v4l2_ctrl_handler_free(&coil->ctrls);
0352 media_entity_cleanup(&coil->subdev.entity);
0353 mutex_destroy(&coil->power_lock);
0354 return 0;
0355 }
0356
0357 static const struct i2c_device_id ad5820_id_table[] = {
0358 { "ad5820", 0 },
0359 { "ad5821", 0 },
0360 { "ad5823", 0 },
0361 { }
0362 };
0363 MODULE_DEVICE_TABLE(i2c, ad5820_id_table);
0364
0365 static const struct of_device_id ad5820_of_table[] = {
0366 { .compatible = "adi,ad5820" },
0367 { .compatible = "adi,ad5821" },
0368 { .compatible = "adi,ad5823" },
0369 { }
0370 };
0371 MODULE_DEVICE_TABLE(of, ad5820_of_table);
0372
0373 static SIMPLE_DEV_PM_OPS(ad5820_pm, ad5820_suspend, ad5820_resume);
0374
0375 static struct i2c_driver ad5820_i2c_driver = {
0376 .driver = {
0377 .name = "ad5820",
0378 .pm = &ad5820_pm,
0379 .of_match_table = ad5820_of_table,
0380 },
0381 .probe = ad5820_probe,
0382 .remove = ad5820_remove,
0383 .id_table = ad5820_id_table,
0384 };
0385
0386 module_i2c_driver(ad5820_i2c_driver);
0387
0388 MODULE_AUTHOR("Tuukka Toivonen");
0389 MODULE_DESCRIPTION("AD5820 camera lens driver");
0390 MODULE_LICENSE("GPL");