0001
0002
0003
0004 #include <linux/delay.h>
0005 #include <linux/i2c.h>
0006 #include <linux/module.h>
0007 #include <linux/pm_runtime.h>
0008 #include <linux/regulator/consumer.h>
0009 #include <media/v4l2-ctrls.h>
0010 #include <media/v4l2-device.h>
0011 #include <media/v4l2-event.h>
0012
0013 #define DW9714_NAME "dw9714"
0014 #define DW9714_MAX_FOCUS_POS 1023
0015
0016
0017
0018
0019 #define DW9714_FOCUS_STEPS 1
0020
0021
0022
0023
0024
0025
0026 #define DW9714_CTRL_STEPS 16
0027 #define DW9714_CTRL_DELAY_US 1000
0028
0029
0030
0031
0032 #define DW9714_DEFAULT_S 0x0
0033 #define DW9714_VAL(data, s) ((data) << 4 | (s))
0034
0035
0036 struct dw9714_device {
0037 struct v4l2_ctrl_handler ctrls_vcm;
0038 struct v4l2_subdev sd;
0039 u16 current_val;
0040 struct regulator *vcc;
0041 };
0042
0043 static inline struct dw9714_device *to_dw9714_vcm(struct v4l2_ctrl *ctrl)
0044 {
0045 return container_of(ctrl->handler, struct dw9714_device, ctrls_vcm);
0046 }
0047
0048 static inline struct dw9714_device *sd_to_dw9714_vcm(struct v4l2_subdev *subdev)
0049 {
0050 return container_of(subdev, struct dw9714_device, sd);
0051 }
0052
0053 static int dw9714_i2c_write(struct i2c_client *client, u16 data)
0054 {
0055 int ret;
0056 __be16 val = cpu_to_be16(data);
0057
0058 ret = i2c_master_send(client, (const char *)&val, sizeof(val));
0059 if (ret != sizeof(val)) {
0060 dev_err(&client->dev, "I2C write fail\n");
0061 return -EIO;
0062 }
0063 return 0;
0064 }
0065
0066 static int dw9714_t_focus_vcm(struct dw9714_device *dw9714_dev, u16 val)
0067 {
0068 struct i2c_client *client = v4l2_get_subdevdata(&dw9714_dev->sd);
0069
0070 dw9714_dev->current_val = val;
0071
0072 return dw9714_i2c_write(client, DW9714_VAL(val, DW9714_DEFAULT_S));
0073 }
0074
0075 static int dw9714_set_ctrl(struct v4l2_ctrl *ctrl)
0076 {
0077 struct dw9714_device *dev_vcm = to_dw9714_vcm(ctrl);
0078
0079 if (ctrl->id == V4L2_CID_FOCUS_ABSOLUTE)
0080 return dw9714_t_focus_vcm(dev_vcm, ctrl->val);
0081
0082 return -EINVAL;
0083 }
0084
0085 static const struct v4l2_ctrl_ops dw9714_vcm_ctrl_ops = {
0086 .s_ctrl = dw9714_set_ctrl,
0087 };
0088
0089 static int dw9714_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
0090 {
0091 return pm_runtime_resume_and_get(sd->dev);
0092 }
0093
0094 static int dw9714_close(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
0095 {
0096 pm_runtime_put(sd->dev);
0097
0098 return 0;
0099 }
0100
0101 static const struct v4l2_subdev_internal_ops dw9714_int_ops = {
0102 .open = dw9714_open,
0103 .close = dw9714_close,
0104 };
0105
0106 static const struct v4l2_subdev_core_ops dw9714_core_ops = {
0107 .log_status = v4l2_ctrl_subdev_log_status,
0108 .subscribe_event = v4l2_ctrl_subdev_subscribe_event,
0109 .unsubscribe_event = v4l2_event_subdev_unsubscribe,
0110 };
0111
0112 static const struct v4l2_subdev_ops dw9714_ops = {
0113 .core = &dw9714_core_ops,
0114 };
0115
0116 static void dw9714_subdev_cleanup(struct dw9714_device *dw9714_dev)
0117 {
0118 v4l2_async_unregister_subdev(&dw9714_dev->sd);
0119 v4l2_ctrl_handler_free(&dw9714_dev->ctrls_vcm);
0120 media_entity_cleanup(&dw9714_dev->sd.entity);
0121 }
0122
0123 static int dw9714_init_controls(struct dw9714_device *dev_vcm)
0124 {
0125 struct v4l2_ctrl_handler *hdl = &dev_vcm->ctrls_vcm;
0126 const struct v4l2_ctrl_ops *ops = &dw9714_vcm_ctrl_ops;
0127
0128 v4l2_ctrl_handler_init(hdl, 1);
0129
0130 v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FOCUS_ABSOLUTE,
0131 0, DW9714_MAX_FOCUS_POS, DW9714_FOCUS_STEPS, 0);
0132
0133 if (hdl->error)
0134 dev_err(dev_vcm->sd.dev, "%s fail error: 0x%x\n",
0135 __func__, hdl->error);
0136 dev_vcm->sd.ctrl_handler = hdl;
0137 return hdl->error;
0138 }
0139
0140 static int dw9714_probe(struct i2c_client *client)
0141 {
0142 struct dw9714_device *dw9714_dev;
0143 int rval;
0144
0145 dw9714_dev = devm_kzalloc(&client->dev, sizeof(*dw9714_dev),
0146 GFP_KERNEL);
0147 if (dw9714_dev == NULL)
0148 return -ENOMEM;
0149
0150 dw9714_dev->vcc = devm_regulator_get(&client->dev, "vcc");
0151 if (IS_ERR(dw9714_dev->vcc))
0152 return PTR_ERR(dw9714_dev->vcc);
0153
0154 rval = regulator_enable(dw9714_dev->vcc);
0155 if (rval < 0) {
0156 dev_err(&client->dev, "failed to enable vcc: %d\n", rval);
0157 return rval;
0158 }
0159
0160 v4l2_i2c_subdev_init(&dw9714_dev->sd, client, &dw9714_ops);
0161 dw9714_dev->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
0162 V4L2_SUBDEV_FL_HAS_EVENTS;
0163 dw9714_dev->sd.internal_ops = &dw9714_int_ops;
0164
0165 rval = dw9714_init_controls(dw9714_dev);
0166 if (rval)
0167 goto err_cleanup;
0168
0169 rval = media_entity_pads_init(&dw9714_dev->sd.entity, 0, NULL);
0170 if (rval < 0)
0171 goto err_cleanup;
0172
0173 dw9714_dev->sd.entity.function = MEDIA_ENT_F_LENS;
0174
0175 rval = v4l2_async_register_subdev(&dw9714_dev->sd);
0176 if (rval < 0)
0177 goto err_cleanup;
0178
0179 pm_runtime_set_active(&client->dev);
0180 pm_runtime_enable(&client->dev);
0181 pm_runtime_idle(&client->dev);
0182
0183 return 0;
0184
0185 err_cleanup:
0186 regulator_disable(dw9714_dev->vcc);
0187 v4l2_ctrl_handler_free(&dw9714_dev->ctrls_vcm);
0188 media_entity_cleanup(&dw9714_dev->sd.entity);
0189
0190 return rval;
0191 }
0192
0193 static int dw9714_remove(struct i2c_client *client)
0194 {
0195 struct v4l2_subdev *sd = i2c_get_clientdata(client);
0196 struct dw9714_device *dw9714_dev = sd_to_dw9714_vcm(sd);
0197 int ret;
0198
0199 pm_runtime_disable(&client->dev);
0200 if (!pm_runtime_status_suspended(&client->dev)) {
0201 ret = regulator_disable(dw9714_dev->vcc);
0202 if (ret) {
0203 dev_err(&client->dev,
0204 "Failed to disable vcc: %d\n", ret);
0205 }
0206 }
0207 pm_runtime_set_suspended(&client->dev);
0208 dw9714_subdev_cleanup(dw9714_dev);
0209
0210 return 0;
0211 }
0212
0213
0214
0215
0216
0217
0218 static int __maybe_unused dw9714_vcm_suspend(struct device *dev)
0219 {
0220 struct i2c_client *client = to_i2c_client(dev);
0221 struct v4l2_subdev *sd = i2c_get_clientdata(client);
0222 struct dw9714_device *dw9714_dev = sd_to_dw9714_vcm(sd);
0223 int ret, val;
0224
0225 if (pm_runtime_suspended(&client->dev))
0226 return 0;
0227
0228 for (val = dw9714_dev->current_val & ~(DW9714_CTRL_STEPS - 1);
0229 val >= 0; val -= DW9714_CTRL_STEPS) {
0230 ret = dw9714_i2c_write(client,
0231 DW9714_VAL(val, DW9714_DEFAULT_S));
0232 if (ret)
0233 dev_err_once(dev, "%s I2C failure: %d", __func__, ret);
0234 usleep_range(DW9714_CTRL_DELAY_US, DW9714_CTRL_DELAY_US + 10);
0235 }
0236
0237 ret = regulator_disable(dw9714_dev->vcc);
0238 if (ret)
0239 dev_err(dev, "Failed to disable vcc: %d\n", ret);
0240
0241 return ret;
0242 }
0243
0244
0245
0246
0247
0248
0249
0250 static int __maybe_unused dw9714_vcm_resume(struct device *dev)
0251 {
0252 struct i2c_client *client = to_i2c_client(dev);
0253 struct v4l2_subdev *sd = i2c_get_clientdata(client);
0254 struct dw9714_device *dw9714_dev = sd_to_dw9714_vcm(sd);
0255 int ret, val;
0256
0257 if (pm_runtime_suspended(&client->dev))
0258 return 0;
0259
0260 ret = regulator_enable(dw9714_dev->vcc);
0261 if (ret) {
0262 dev_err(dev, "Failed to enable vcc: %d\n", ret);
0263 return ret;
0264 }
0265 usleep_range(1000, 2000);
0266
0267 for (val = dw9714_dev->current_val % DW9714_CTRL_STEPS;
0268 val < dw9714_dev->current_val + DW9714_CTRL_STEPS - 1;
0269 val += DW9714_CTRL_STEPS) {
0270 ret = dw9714_i2c_write(client,
0271 DW9714_VAL(val, DW9714_DEFAULT_S));
0272 if (ret)
0273 dev_err_ratelimited(dev, "%s I2C failure: %d",
0274 __func__, ret);
0275 usleep_range(DW9714_CTRL_DELAY_US, DW9714_CTRL_DELAY_US + 10);
0276 }
0277
0278 return 0;
0279 }
0280
0281 static const struct i2c_device_id dw9714_id_table[] = {
0282 { DW9714_NAME, 0 },
0283 { { 0 } }
0284 };
0285 MODULE_DEVICE_TABLE(i2c, dw9714_id_table);
0286
0287 static const struct of_device_id dw9714_of_table[] = {
0288 { .compatible = "dongwoon,dw9714" },
0289 { { 0 } }
0290 };
0291 MODULE_DEVICE_TABLE(of, dw9714_of_table);
0292
0293 static const struct dev_pm_ops dw9714_pm_ops = {
0294 SET_SYSTEM_SLEEP_PM_OPS(dw9714_vcm_suspend, dw9714_vcm_resume)
0295 SET_RUNTIME_PM_OPS(dw9714_vcm_suspend, dw9714_vcm_resume, NULL)
0296 };
0297
0298 static struct i2c_driver dw9714_i2c_driver = {
0299 .driver = {
0300 .name = DW9714_NAME,
0301 .pm = &dw9714_pm_ops,
0302 .of_match_table = dw9714_of_table,
0303 },
0304 .probe_new = dw9714_probe,
0305 .remove = dw9714_remove,
0306 .id_table = dw9714_id_table,
0307 };
0308
0309 module_i2c_driver(dw9714_i2c_driver);
0310
0311 MODULE_AUTHOR("Tianshu Qiu <tian.shu.qiu@intel.com>");
0312 MODULE_AUTHOR("Jian Xu Zheng");
0313 MODULE_AUTHOR("Yuning Pu <yuning.pu@intel.com>");
0314 MODULE_AUTHOR("Jouni Ukkonen <jouni.ukkonen@intel.com>");
0315 MODULE_AUTHOR("Tommi Franttila <tommi.franttila@intel.com>");
0316 MODULE_DESCRIPTION("DW9714 VCM driver");
0317 MODULE_LICENSE("GPL v2");