Full support for Ginger Console
[linux-ginger.git] / drivers / media / video / dw9710.c
blobab2966d67c381e29bc2090856fb7199577d84fb3
1 /*
2 * dw9710.c - DW9710 Coil Motor (LENS) driver
4 * Copyright (C) 2009 Texas Instruments.
6 * Contributors:
7 * Sergio Aguirre <saaguirre@ti.com>
8 * Troy Laramy
9 * Mohit Jalori
11 * This file is licensed under the terms of the GNU General Public License
12 * version 2. This program is licensed "as is" without any warranty of any
13 * kind, whether express or implied.
16 #include <linux/mutex.h>
17 #include <linux/i2c.h>
18 #include <linux/delay.h>
20 #include <media/v4l2-int-device.h>
21 #include <media/dw9710.h>
23 #define DW9710_I2C_RETRY_COUNT 5
24 #define DW9710_DISABLE 1
25 #define DW9710_ENABLE 0
26 #define DW9710_POWERDN(ARG) (((ARG) & 0x1) << 15)
27 #define DW9710_POWERDN_R(ARG) (((ARG) >> 15) & 0x1)
28 #define DW9710_DATA(ARG) (((ARG) & 0xFF) << 6)
29 #define DW9710_DATA_R(ARG) (((ARG) >> 6) & 0xFF)
31 /* Focus control values */
32 #define DW9710_DEF_LENS_POSN 0 /* 0x7F */
33 #define DW9710_LENS_POSN_STEP 1
34 #define DW9710_MAX_FOCUS_POS 0xFF
36 struct dw9710_device {
37 struct device *dev;
38 struct dw9710_platform_data *pdata;
39 struct v4l2_int_device *v4l2_int_device;
40 int opened;
41 u16 current_lens_posn;
42 u16 saved_lens_posn;
43 int detected;
44 int power_state;
47 static struct vcontrol {
48 struct v4l2_queryctrl qc;
49 int current_value;
50 } video_control[] = {
53 .id = V4L2_CID_FOCUS_ABSOLUTE,
54 .type = V4L2_CTRL_TYPE_INTEGER,
55 .name = "Focus, Absolute",
56 .minimum = 0,
57 .maximum = DW9710_MAX_FOCUS_POS,
58 .step = DW9710_LENS_POSN_STEP,
59 .default_value = DW9710_DEF_LENS_POSN,
61 .current_value = DW9710_DEF_LENS_POSN,
65 /**
66 * find_vctrl - Finds the requested ID in the video control structure array
67 * @id: ID of control to search the video control array for
69 * Returns the index of the requested ID from the control structure array
71 static int find_vctrl(int id)
73 int i;
75 if (id < V4L2_CID_BASE)
76 return -EDOM;
78 for (i = (ARRAY_SIZE(video_control) - 1); i >= 0; i--) {
79 if (video_control[i].qc.id == id)
80 return i;
83 return -EINVAL;
86 /**
87 * dw9710_reg_read - Reads a value from a register in DW9710 Coil driver device.
88 * @client: Pointer to structure of I2C client.
89 * @value: Pointer to u16 for returning value of register to read.
91 * Returns zero if successful, or non-zero otherwise.
92 **/
93 static int dw9710_reg_read(struct i2c_client *client, u16 *value)
95 int err;
96 struct i2c_msg msg[1];
97 unsigned char data[2];
99 if (!client->adapter)
100 return -ENODEV;
102 msg->addr = client->addr;
103 msg->flags = I2C_M_RD;
104 msg->len = 2;
105 msg->buf = data;
107 data[0] = 0;
108 data[1] = 0;
110 err = i2c_transfer(client->adapter, msg, 1);
112 if (err >= 0) {
113 err = ((data[0] & 0xFF) << 8) | (data[1]);
114 *value = err;
115 return 0;
117 return err;
121 * dw9710_reg_write - Writes a value to a register in DW9710 Coil driver device.
122 * @client: Pointer to structure of I2C client.
123 * @value: Value of register to write.
125 * Returns zero if successful, or non-zero otherwise.
127 static int dw9710_reg_write(struct i2c_client *client, u16 value)
129 int err;
130 struct i2c_msg msg[1];
131 unsigned char data[2];
132 int retry = 0;
134 if (!client->adapter)
135 return -ENODEV;
137 again:
138 msg->addr = client->addr;
139 msg->flags = 0;
140 msg->len = 2;
141 msg->buf = data;
143 data[0] = (u8)(value >> 8);
144 data[1] = (u8)(value & 0xFF);
146 err = i2c_transfer(client->adapter, msg, 1);
148 if (err >= 0)
149 return 0;
151 if (retry <= DW9710_I2C_RETRY_COUNT) {
152 dev_dbg(&client->dev, "retry ... %d", retry);
153 retry++;
154 set_current_state(TASK_UNINTERRUPTIBLE);
155 schedule_timeout(msecs_to_jiffies(20));
156 goto again;
158 return err;
162 * dw9710_detect - Detects DW9710 Coil driver device.
163 * @client: Pointer to structure of I2C client.
165 * Returns 0 if successful, -1 if camera is off or if test register value
166 * wasn't stored properly, or returned errors from either dw9710_reg_write or
167 * dw9710_reg_read functions.
169 static int dw9710_detect(struct i2c_client *client)
171 int err = 0;
172 u16 wposn = 0, rposn = 0;
173 u16 posn = 0x05;
175 wposn = (DW9710_POWERDN(DW9710_ENABLE) | DW9710_DATA(posn));
177 err = dw9710_reg_write(client, wposn);
178 if (err) {
179 dev_err(&client->dev, "Unable to write DW9710 \n");
180 return err;
183 err = dw9710_reg_read(client, &rposn);
184 if (err) {
185 dev_err(&client->dev, "Unable to read DW9710\n");
186 return err;
189 if (wposn != rposn) {
190 dev_err(&client->dev, "W/R MISMATCH!\n");
191 return -1;
193 posn = 0;
194 wposn = (DW9710_POWERDN(DW9710_ENABLE) | DW9710_DATA(posn));
195 err = dw9710_reg_write(client, wposn);
197 return err;
201 * dw9710_af_setfocus - Sets the desired focus.
202 * @posn: Desired focus position, 0 (far) - 100 (close).
204 * Returns 0 on success, -EINVAL if camera is off or focus value is out of
205 * bounds, or returned errors from either dw9710_reg_write or dw9710_reg_read
206 * functions.
208 int dw9710_af_setfocus(struct v4l2_int_device *s, u16 posn)
210 struct dw9710_device *lens = s->priv;
211 struct i2c_client *client = to_i2c_client(lens->dev);
212 u16 cur_focus_value = 0;
213 int ret = -EINVAL;
215 if (posn > DW9710_MAX_FOCUS_POS) {
216 dev_err(&client->dev, "Bad posn params 0x%x \n", posn);
217 return ret;
220 if ((lens->power_state == V4L2_POWER_OFF) ||
221 (lens->power_state == V4L2_POWER_STANDBY)) {
222 lens->current_lens_posn = posn;
223 return 0;
226 ret = dw9710_reg_read(client, &cur_focus_value);
228 if (ret) {
229 dev_err(&client->dev, "Read of current Lens position failed\n");
230 return ret;
233 if (DW9710_DATA_R(cur_focus_value) == posn) {
234 dev_dbg(&client->dev, "Device already in requested focal point\n");
235 return ret;
238 ret = dw9710_reg_write(client, DW9710_POWERDN(DW9710_ENABLE) |
239 DW9710_DATA(posn));
241 if (ret)
242 dev_err(&client->dev, "Setfocus register write failed\n");
243 lens->current_lens_posn = posn;
244 return ret;
246 EXPORT_SYMBOL(dw9710_af_setfocus);
249 * dw9710_af_getfocus - Gets the focus value from device.
250 * @value: Pointer to u16 variable which will contain the focus value.
252 * Returns 0 if successful, -EINVAL if camera is off, or return value of
253 * dw9710_reg_read if fails.
255 int dw9710_af_getfocus(struct v4l2_int_device *s, u16 *value)
257 struct dw9710_device *lens = s->priv;
258 struct i2c_client *client = to_i2c_client(lens->dev);
259 int ret;
260 u16 posn = 0;
262 if ((lens->power_state == V4L2_POWER_OFF) ||
263 (lens->power_state == V4L2_POWER_STANDBY))
264 return -EINVAL;
266 ret = dw9710_reg_read(client, &posn);
268 if (ret) {
269 dev_err(&client->dev, "Read of current Lens position failed\n");
270 return ret;
272 *value = DW9710_DATA_R(posn);
273 lens->current_lens_posn = DW9710_DATA_R(posn);
274 return ret;
276 EXPORT_SYMBOL(dw9710_af_getfocus);
279 * ioctl_queryctrl - V4L2 lens interface handler for VIDIOC_QUERYCTRL ioctl
280 * @s: pointer to standard V4L2 device structure
281 * @qc: standard V4L2 VIDIOC_QUERYCTRL ioctl structure
283 * If the requested control is supported, returns the control information
284 * from the video_control[] array. Otherwise, returns -EINVAL if the
285 * control is not supported.
287 static int ioctl_queryctrl(struct v4l2_int_device *s, struct v4l2_queryctrl *qc)
289 int i;
291 i = find_vctrl(qc->id);
292 if (i == -EINVAL)
293 qc->flags = V4L2_CTRL_FLAG_DISABLED;
295 if (i < 0)
296 return -EINVAL;
298 *qc = video_control[i].qc;
299 return 0;
303 * ioctl_g_ctrl - V4L2 DW9710 lens interface handler for VIDIOC_G_CTRL ioctl
304 * @s: pointer to standard V4L2 device structure
305 * @vc: standard V4L2 VIDIOC_G_CTRL ioctl structure
307 * If the requested control is supported, returns the control's current
308 * value from the video_control[] array. Otherwise, returns -EINVAL
309 * if the control is not supported.
311 static int ioctl_g_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc)
313 struct vcontrol *lvc;
314 int i;
315 u16 curr_posn;
317 i = find_vctrl(vc->id);
318 if (i < 0)
319 return -EINVAL;
320 lvc = &video_control[i];
322 switch (vc->id) {
323 case V4L2_CID_FOCUS_ABSOLUTE:
324 if (dw9710_af_getfocus(s, &curr_posn))
325 return -EFAULT;
326 vc->value = curr_posn;
327 lvc->current_value = curr_posn;
328 break;
331 return 0;
335 * ioctl_s_ctrl - V4L2 DW9710 lens interface handler for VIDIOC_S_CTRL ioctl
336 * @s: pointer to standard V4L2 device structure
337 * @vc: standard V4L2 VIDIOC_S_CTRL ioctl structure
339 * If the requested control is supported, sets the control's current
340 * value in HW (and updates the video_control[] array). Otherwise,
341 * returns -EINVAL if the control is not supported.
343 static int ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc)
345 int retval = -EINVAL;
346 int i;
347 struct vcontrol *lvc;
349 i = find_vctrl(vc->id);
350 if (i < 0)
351 return -EINVAL;
352 lvc = &video_control[i];
354 switch (vc->id) {
355 case V4L2_CID_FOCUS_ABSOLUTE:
356 retval = dw9710_af_setfocus(s, vc->value);
357 if (!retval)
358 lvc->current_value = vc->value;
359 break;
362 return retval;
366 * ioctl_g_priv - V4L2 sensor interface handler for vidioc_int_g_priv_num
367 * @s: pointer to standard V4L2 device structure
368 * @p: void pointer to hold sensor's private data address
370 * Returns device's (sensor's) private data area address in p parameter
372 static int ioctl_g_priv(struct v4l2_int_device *s, void *p)
374 struct dw9710_device *lens = s->priv;
376 return lens->pdata->priv_data_set(p);
381 * ioctl_dev_exit - V4L2 sensor interface handler for vidioc_int_dev_exit_num
382 * @s: pointer to standard V4L2 device structure
384 * Delinitialise the dev. at slave detach. The complement of ioctl_dev_init.
386 static int ioctl_dev_exit(struct v4l2_int_device *s)
388 return 0;
392 * ioctl_dev_init - V4L2 sensor interface handler for vidioc_int_dev_init_num
393 * @s: pointer to standard V4L2 device structure
395 * Initialise the device when slave attaches to the master. Returns 0 if
396 * dw9710 device could be found, otherwise returns appropriate error.
398 static int ioctl_dev_init(struct v4l2_int_device *s)
400 struct dw9710_device *lens = s->priv;
401 struct i2c_client *client = to_i2c_client(lens->dev);
402 int err;
404 err = dw9710_detect(client);
405 if (err < 0) {
406 dev_err(&client->dev, "Unable to detect lens\n");
407 lens->detected = 0;
408 return err;
410 lens->detected = 1;
411 dev_info(&client->dev, "Lens HW detected\n");
413 return 0;
414 }/**
415 * ioctl_s_power - V4L2 sensor interface handler for vidioc_int_s_power_num
416 * @s: pointer to standard V4L2 device structure
417 * @on: power state to which device is to be set
419 * Sets devices power state to requrested state, if possible.
421 static int ioctl_s_power(struct v4l2_int_device *s, enum v4l2_power new_power)
423 struct dw9710_device *lens = s->priv;
424 int rval = 0;
426 switch (new_power) {
427 case V4L2_POWER_ON:
428 rval = lens->pdata->power_set(V4L2_POWER_ON);
429 if (rval)
430 break;
432 if (lens->detected)
433 dw9710_af_setfocus(s, lens->current_lens_posn);
434 else {
435 rval = ioctl_dev_init(s);
436 if (rval)
437 goto err_on;
439 break;
440 case V4L2_POWER_OFF:
441 err_on:
442 lens->pdata->power_set(V4L2_POWER_OFF);
443 break;
444 case V4L2_POWER_STANDBY:
445 rval = lens->pdata->power_set(V4L2_POWER_STANDBY);
446 break;
447 default:
448 return -EINVAL;
451 if (!rval)
452 lens->power_state = new_power;
453 return rval;
456 static struct v4l2_int_ioctl_desc dw9710_ioctl_desc[] = {
457 { .num = vidioc_int_dev_init_num,
458 .func = (v4l2_int_ioctl_func *)ioctl_dev_init },
459 { .num = vidioc_int_dev_exit_num,
460 .func = (v4l2_int_ioctl_func *)ioctl_dev_exit },
461 { .num = vidioc_int_s_power_num,
462 .func = (v4l2_int_ioctl_func *)ioctl_s_power },
463 { .num = vidioc_int_g_priv_num,
464 .func = (v4l2_int_ioctl_func *)ioctl_g_priv },
465 { .num = vidioc_int_queryctrl_num,
466 .func = (v4l2_int_ioctl_func *)ioctl_queryctrl },
467 { .num = vidioc_int_g_ctrl_num,
468 .func = (v4l2_int_ioctl_func *)ioctl_g_ctrl },
469 { .num = vidioc_int_s_ctrl_num,
470 .func = (v4l2_int_ioctl_func *)ioctl_s_ctrl },
473 static struct v4l2_int_slave dw9710_slave = {
474 .ioctls = dw9710_ioctl_desc,
475 .num_ioctls = ARRAY_SIZE(dw9710_ioctl_desc),
478 static struct v4l2_int_device dw9710_int_device = {
479 .module = THIS_MODULE,
480 .name = DW9710_NAME,
481 .type = v4l2_int_type_slave,
482 .u = {
483 .slave = &dw9710_slave,
488 * dw9710_probe - Probes the driver for valid I2C attachment.
489 * @client: Pointer to structure of I2C client.
491 * Returns 0 if successful, or -EBUSY if unable to get client attached data.
493 static int dw9710_probe(struct i2c_client *client,
494 const struct i2c_device_id *id)
496 struct dw9710_device *lens;
497 struct dw9710_platform_data *pdata;
498 int err;
500 if (i2c_get_clientdata(client))
501 return -EBUSY;
503 pdata = client->dev.platform_data;
504 if (!pdata) {
505 dev_err(&client->dev, "no platform data?\n");
506 return -EINVAL;
509 lens = kzalloc(sizeof(*lens), GFP_KERNEL);
510 if (!lens)
511 return -ENOMEM;
513 /* Don't keep pointer to platform data, copy elements instead */
514 lens->pdata = kzalloc(sizeof(*lens->pdata), GFP_KERNEL);
515 if (!lens->pdata) {
516 err = -ENOMEM;
517 goto on_err1;
520 lens->pdata->power_set = pdata->power_set;
521 lens->pdata->priv_data_set = pdata->priv_data_set;
523 lens->detected = 0;
524 lens->current_lens_posn = DW9710_DEF_LENS_POSN;
526 lens->v4l2_int_device = &dw9710_int_device;
527 lens->v4l2_int_device->priv = lens;
528 lens->dev = &client->dev;
530 i2c_set_clientdata(client, lens);
532 err = v4l2_int_device_register(lens->v4l2_int_device);
533 if (err) {
534 dev_err(&client->dev, "Failed to Register as V4L2 device.\n");
535 goto on_err2;
538 return 0;
539 on_err2:
540 i2c_set_clientdata(client, NULL);
541 kfree(lens->pdata);
542 on_err1:
543 kfree(lens);
544 return err;
548 * dw9710_remove - Routine when device its unregistered from I2C
549 * @client: Pointer to structure of I2C client.
551 * Returns 0 if successful, or -ENODEV if the client isn't attached.
553 static int dw9710_remove(struct i2c_client *client)
555 if (!client->adapter)
556 return -ENODEV;
558 i2c_set_clientdata(client, NULL);
559 return 0;
562 static const struct i2c_device_id dw9710_id[] = {
563 { DW9710_NAME, 0 },
566 MODULE_DEVICE_TABLE(i2c, dw9710_id);
568 static struct i2c_driver dw9710_i2c_driver = {
569 .driver = {
570 .name = DW9710_NAME,
571 .owner = THIS_MODULE,
573 .probe = dw9710_probe,
574 .remove = dw9710_remove,
575 .id_table = dw9710_id,
579 * dw9710_init - Module initialisation.
581 * Returns 0 if successful, or -EINVAL if device couldn't be initialized, or
582 * added as a character device.
584 static int __init dw9710_init(void)
586 int err = -EINVAL;
588 err = i2c_add_driver(&dw9710_i2c_driver);
589 if (err)
590 goto fail;
591 return err;
592 fail:
593 printk(KERN_ERR "Failed to register " DW9710_NAME ".\n");
594 return err;
596 module_init(dw9710_init);
599 * dw9710_cleanup - Module cleanup.
601 static void __exit dw9710_cleanup(void)
603 i2c_del_driver(&dw9710_i2c_driver);
605 module_exit(dw9710_cleanup);
607 MODULE_AUTHOR("Texas Instruments");
608 MODULE_LICENSE("GPL");
609 MODULE_DESCRIPTION("DW9710 LENS driver");