• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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