1 /*
2 * A V4L2 driver for imx274 Raw cameras.
3 *
4 * Copyright (c) 2017 by Allwinnertech Co., Ltd. http://www.allwinnertech.com
5 *
6 * Authors: Zhao Wei <zhaowei@allwinnertech.com>
7 * Liang WeiJie <liangweijie@allwinnertech.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 */
19
20 #include <linux/init.h>
21 #include <linux/module.h>
22 #include <linux/slab.h>
23 #include <linux/i2c.h>
24 #include <linux/delay.h>
25 #include <linux/videodev2.h>
26 #include <linux/clk.h>
27 #include <media/v4l2-device.h>
28 #include <media/v4l2-mediabus.h>
29 #include <linux/io.h>
30 #include <linux/gpio.h>
31 #include <sunxi-gpio.h>
32 #include <linux/spi/spi.h>
33
34 #include "actuator.h"
35
36 MODULE_AUTHOR("lwj");
37 MODULE_DESCRIPTION("A low-level driver for AN41908A");
38 MODULE_LICENSE("GPL");
39
40
41 #define LENS_SUNNY 1
42 #if 0
43 #define LENSDRV_FOCUS_STEPS_REG 0x24 /* define AB motor to Focus */
44 #define LENSDRV_ZOOM_STEPS_REG 0x29 /* define CD motor to Zoom */
45 #else
46 #define LENSDRV_FOCUS_STEPS_REG 0x29 /* define AB motor to Focus */
47 #define LENSDRV_ZOOM_STEPS_REG 0x24 /* define CD motor to Zoom */
48 #endif
49
50
51 #define SUNXI_ACT_NAME "an41908a_act"
52
53 extern void v4l2_spi_subdev_init(struct v4l2_subdev *sd, struct spi_device *spi,
54 const struct v4l2_subdev_ops *ops);
55
act_spi_read_byte(struct spi_device * spi,loff_t from,size_t len,unsigned short * buf)56 static int act_spi_read_byte(struct spi_device *spi, loff_t from,
57 size_t len, unsigned short *buf)
58 {
59 struct spi_transfer t[2];
60 struct spi_message m;
61 unsigned char command[1] = {0};
62 unsigned char data[2];
63
64 spi_message_init(&m);
65 memset(t, 0, sizeof(t));
66 command[0] = from | 0x40;
67 t[0].tx_buf = command;
68 t[0].len = 1;
69 spi_message_add_tail(&t[0], &m);
70
71 t[1].rx_buf = data;
72 t[1].len = len;
73 spi_message_add_tail(&t[1], &m);
74
75 spi_sync(spi, &m);
76
77 *buf = data[1] * 256 + data[0];
78
79 return 0;
80 }
81
act_spi_write_byte(struct spi_device * spi,loff_t to,size_t len,const unsigned short buf)82 static int act_spi_write_byte(struct spi_device *spi, loff_t to,
83 size_t len, const unsigned short buf)
84 {
85 struct spi_transfer t;
86 struct spi_message m;
87 unsigned char command[3] = {0};
88
89 spi_message_init(&m);
90 memset(&t, 0, sizeof(t));
91 command[0] = to & 0x3F;
92 command[1] = buf & 0xff;
93 command[2] = (buf >> 8) & 0xff;
94
95 t.tx_buf = command;
96 t.len = 3;
97 spi_message_add_tail(&t, &m);
98
99 spi_sync(spi, &m);
100
101 return 0;
102 }
103
act_spi_read(struct v4l2_subdev * sd,unsigned char reg,unsigned short * val)104 static int act_spi_read(struct v4l2_subdev *sd, unsigned char reg,
105 unsigned short *val)
106 {
107 struct spi_device *spi = v4l2_get_subdevdata(sd);
108 loff_t from = reg;
109
110 return act_spi_read_byte(spi, from, 2, val);
111 }
112
act_spi_write(struct v4l2_subdev * sd,unsigned char reg,unsigned short val)113 static int act_spi_write(struct v4l2_subdev *sd, unsigned char reg,
114 unsigned short val)
115 {
116 struct spi_device *spi = v4l2_get_subdevdata(sd);
117 loff_t to = reg;
118
119 return act_spi_write_byte(spi, to, 3, val);
120 }
121
122 /*
123 * Code for dealing with controls.
124 * fill with different sensor module
125 * different sensor module has different settings here
126 * if not support the follow function ,retrun -EINVAL
127 */
128
129 #define VD_IS GPIOH(9)
130 #define VD_FZ GPIOH(10)
131
lens_set_pulse(int gpio)132 int lens_set_pulse(int gpio)
133 {
134 if (gpio_direction_output(gpio, 0)) {
135 act_err("gpio%d set 0 err!", gpio);
136 return -1;
137 }
138 usleep_range(1000, 1200);
139 if (gpio_direction_output(gpio, 1)) {
140 act_err("gpio%d set 1 err!", gpio);
141 return -1;
142 }
143 usleep_range(1000, 1200);
144 if (gpio_direction_output(gpio, 0)) {
145 act_err("gpio%d set 0 err!", gpio);
146 return -1;
147 }
148 usleep_range(1000, 1200);
149 return 0;
150 }
151
lens_iris_move(struct v4l2_subdev * sd,uint iris_tgt)152 void lens_iris_move(struct v4l2_subdev *sd, uint iris_tgt)
153 {
154 /* iris_tgt range:0x0000~0x03FF */
155 if (iris_tgt > 0x03ff)
156 return;
157
158 act_spi_write(sd, 0x00, iris_tgt);
159
160 lens_set_pulse(VD_IS);
161
162 act_dbg("%s target 0x%x\n", __func__, iris_tgt);
163 }
164
lens_focus_move(struct v4l2_subdev * sd,bool dir,uint fc_step)165 void lens_focus_move(struct v4l2_subdev *sd, bool dir, uint fc_step)
166 {
167 unsigned short backup_data = 0;
168
169 /* more than 255step */
170 if (fc_step > 0x00FF)
171 return;
172
173 act_spi_read(sd, LENSDRV_FOCUS_STEPS_REG, &backup_data);
174 backup_data &= 0xFE00;
175 backup_data |= fc_step;
176 if (dir == 1) {
177 /* Add directiion bit (CCWCWAB) to registor:0x24 */
178 backup_data |= 0x0100;
179 act_spi_write(sd, LENSDRV_FOCUS_STEPS_REG, backup_data);
180 } else {
181 act_spi_write(sd, LENSDRV_FOCUS_STEPS_REG, backup_data);
182 }
183
184 lens_set_pulse(VD_FZ);
185
186 act_dbg("%s dir %d, step 0x%x\n", __func__, dir, fc_step);
187 }
188
lens_zoom_move(struct v4l2_subdev * sd,bool dir,uint zoom_step)189 void lens_zoom_move(struct v4l2_subdev *sd, bool dir, uint zoom_step)
190 {
191 unsigned short backup_data = 0;
192
193 /* more than 255step */
194 if (zoom_step > 0x00FF)
195 return;
196
197 act_spi_read(sd, LENSDRV_ZOOM_STEPS_REG, &backup_data);
198 backup_data &= 0xFE00;
199 backup_data |= zoom_step;
200 if (dir == 1) {
201 /* Add directiion bit (CCWCWAB) to registor:0x29 */
202 backup_data |= 0x0100;
203 act_spi_write(sd, LENSDRV_ZOOM_STEPS_REG, backup_data);
204 } else {
205 act_spi_write(sd, LENSDRV_ZOOM_STEPS_REG, backup_data);
206 }
207
208 lens_set_pulse(VD_FZ);
209
210 act_dbg("%s dir %d, step 0x%x\n", __func__, dir, zoom_step);
211 }
212
act_power(struct v4l2_subdev * sd,int on)213 static int act_power(struct v4l2_subdev *sd, int on)
214 {
215 return 0;
216 }
217
act_reset(struct v4l2_subdev * sd,u32 val)218 static int act_reset(struct v4l2_subdev *sd, u32 val)
219 {
220 return 0;
221 }
222
act_detect(struct v4l2_subdev * sd)223 static int act_detect(struct v4l2_subdev *sd)
224 {
225 unsigned short rd_val;
226
227 act_spi_write(sd, 0x0E, 0x0C00);
228 act_spi_read(sd, 0x0E, &rd_val);
229 act_dbg("%s 0x%x!!!\n", __func__, rd_val);
230
231 act_spi_write(sd, 0x0E, 0x0D00);
232 act_spi_read(sd, 0x0E, &rd_val);
233 act_dbg("%s 0x%x!!!\n", __func__, rd_val);
234
235 return 0;
236 }
237
act_init(struct v4l2_subdev * sd,u32 val)238 static int act_init(struct v4l2_subdev *sd, u32 val)
239 {
240 int ret;
241
242 act_dbg("act_init\n");
243
244 /*Make sure it is a target sensor */
245 ret = act_detect(sd);
246 if (ret) {
247 act_err("chip found is not an target chip.\n");
248 return ret;
249 }
250
251 #if LENS_SUNNY /* Zoom use AB chanel */
252 act_spi_write(sd, 0x20, 0x5c0a);
253 act_spi_write(sd, 0x21, 0x0005);
254 act_spi_write(sd, 0x22, 0x0003);
255 act_spi_write(sd, 0x23, 0xC8C8);
256 act_spi_write(sd, 0x24, 0x0400);
257 act_spi_write(sd, 0x25, 0x0502);
258 #else
259 act_spi_write(sd, 0x20, 0x5c0a);
260 act_spi_write(sd, 0x21, 0x0000);
261 act_spi_write(sd, 0x22, 0x1603);
262 act_spi_write(sd, 0x23, 0xC8C8);
263 act_spi_write(sd, 0x24, 0x0400);
264 act_spi_write(sd, 0x25, 0x0160);
265 #endif
266
267 act_spi_write(sd, 0x27, 0x1603);
268 act_spi_write(sd, 0x28, 0xC8C8);
269 act_spi_write(sd, 0x29, 0x0400);
270 act_spi_write(sd, 0x2A, 0x0400);
271
272 #if LENS_SUNNY
273 act_spi_write(sd, 0x00, 0x0000); /* Set Iris Target */
274 act_spi_write(sd, 0x01, 0x808A);
275 act_spi_write(sd, 0x02, 0x66F0);
276 act_spi_write(sd, 0x03, 0x0E10);
277 act_spi_write(sd, 0x04, 0x7E20);
278 act_spi_write(sd, 0x05, 0x0A04);
279 act_spi_write(sd, 0x0A, 0x0000);
280 act_spi_write(sd, 0x0B, 0x0400);
281 act_spi_write(sd, 0x0E, 0x0C00);
282 #else
283 act_spi_write(sd, 0x00, 0x0000);
284 act_spi_write(sd, 0x01, 0x6600);
285 act_spi_write(sd, 0x02, 0x5400);
286 act_spi_write(sd, 0x03, 0x0E10);
287 act_spi_write(sd, 0x04, 0x8437);
288 act_spi_write(sd, 0x05, 0x0104);
289 act_spi_write(sd, 0x0A, 0x0042);
290 act_spi_write(sd, 0x0B, 0x0400);
291 act_spi_write(sd, 0x0E, 0x0D00);
292 #endif
293
294 lens_iris_move(sd, 0x02ff);
295
296 lens_focus_move(sd, 0, 128);
297
298 lens_zoom_move(sd, 0, 32);
299
300 return 0;
301 }
302
act_ioctl(struct v4l2_subdev * sd,unsigned int cmd,void * arg)303 static long act_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
304 {
305 int ret = 0;
306
307 switch (cmd) {
308 default:
309 return -EINVAL;
310 }
311 return ret;
312 }
313
314 /* ----------------------------------------------------------------------- */
315
316 static const struct v4l2_subdev_core_ops act_core_ops = {
317 .reset = act_reset,
318 .init = act_init,
319 .s_power = act_power,
320 .ioctl = act_ioctl,
321 };
322
323 static const struct v4l2_subdev_ops act_ops = {
324 .core = &act_core_ops,
325 };
326
327 /* ----------------------------------------------------------------------- */
act_registered(struct v4l2_subdev * sd)328 static int act_registered(struct v4l2_subdev *sd)
329 {
330 return act_init(sd, 0);
331 }
332
333 static const struct v4l2_subdev_internal_ops act_internal_ops = {
334 .registered = act_registered,
335 };
336
act_probe(struct spi_device * spi)337 static int act_probe(struct spi_device *spi)
338 {
339 struct v4l2_subdev *sd;
340
341 sd = kzalloc(sizeof(struct v4l2_subdev), GFP_KERNEL);
342 if (sd == NULL)
343 return -ENOMEM;
344
345 v4l2_spi_subdev_init(sd, spi, &act_ops);
346
347 snprintf(sd->name, sizeof(sd->name), "%s", SUNXI_ACT_NAME);
348 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
349 sd->internal_ops = &act_internal_ops;
350
351 sd->entity.function = MEDIA_ENT_F_LENS;
352 media_entity_pads_init(&sd->entity, 0, NULL);
353
354 if (gpio_request(VD_IS, NULL)) {
355 act_err("request gpio%d is failed\n", VD_IS);
356 return -1;
357 }
358 if (gpio_request(VD_FZ, NULL)) {
359 act_err("request gpio%d is failed\n", VD_FZ);
360 return -1;
361 }
362 if (gpio_direction_output(VD_IS, 1)) {
363 act_err("gpio%d set 0 err!", VD_IS);
364 return -1;
365 }
366 if (gpio_direction_output(VD_FZ, 1)) {
367 act_err("gpio%d set 0 err!", VD_FZ);
368 return -1;
369 }
370
371 lens_set_pulse(VD_IS);
372 lens_set_pulse(VD_FZ);
373
374 return 0;
375 }
act_remove(struct spi_device * spi)376 static int act_remove(struct spi_device *spi)
377 {
378 struct v4l2_subdev *sd;
379
380 gpio_free(VD_IS);
381 gpio_free(VD_FZ);
382
383 sd = spi_get_drvdata(spi);
384 v4l2_device_unregister_subdev(sd);
385 kfree(sd);
386 return 0;
387 }
388
389 static const struct spi_device_id act_id[] = {
390 {SUNXI_ACT_NAME, 0},
391 {}
392 };
393
394 MODULE_DEVICE_TABLE(spi, act_id);
395
396 static struct spi_driver act_driver = {
397 .driver = {
398 .owner = THIS_MODULE,
399 .name = SUNXI_ACT_NAME,
400 },
401 .probe = act_probe,
402 .remove = act_remove,
403 .id_table = act_id,
404 };
init_sensor(void)405 static __init int init_sensor(void)
406 {
407 return spi_register_driver(&act_driver);
408 }
409
exit_sensor(void)410 static __exit void exit_sensor(void)
411 {
412 spi_unregister_driver(&act_driver);
413 }
414
415 module_init(init_sensor);
416 module_exit(exit_sensor);
417