• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6/drivers/media/video/gspca/m5602/
1/*
2 * Driver for the s5k83a sensor
3 *
4 * Copyright (C) 2008 Erik Andr��n
5 * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
6 * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
7 *
8 * Portions of code to USB interface and ALi driver software,
9 * Copyright (c) 2006 Willem Duinker
10 * v4l2 interface modeled after the V4L2 driver
11 * for SN9C10x PC Camera Controllers
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License as
15 * published by the Free Software Foundation, version 2.
16 *
17 */
18
19#include <linux/kthread.h>
20#include "m5602_s5k83a.h"
21
22static int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val);
23static int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
24static int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val);
25static int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val);
26static int s5k83a_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
27static int s5k83a_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
28static int s5k83a_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
29static int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
30static int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
31static int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
32
33static struct v4l2_pix_format s5k83a_modes[] = {
34	{
35		640,
36		480,
37		V4L2_PIX_FMT_SBGGR8,
38		V4L2_FIELD_NONE,
39		.sizeimage =
40			640 * 480,
41		.bytesperline = 640,
42		.colorspace = V4L2_COLORSPACE_SRGB,
43		.priv = 0
44	}
45};
46
47static const struct ctrl s5k83a_ctrls[] = {
48#define GAIN_IDX 0
49	{
50		{
51			.id = V4L2_CID_GAIN,
52			.type = V4L2_CTRL_TYPE_INTEGER,
53			.name = "gain",
54			.minimum = 0x00,
55			.maximum = 0xff,
56			.step = 0x01,
57			.default_value = S5K83A_DEFAULT_GAIN,
58			.flags = V4L2_CTRL_FLAG_SLIDER
59		},
60			.set = s5k83a_set_gain,
61			.get = s5k83a_get_gain
62
63	},
64#define BRIGHTNESS_IDX 1
65	{
66		{
67			.id = V4L2_CID_BRIGHTNESS,
68			.type = V4L2_CTRL_TYPE_INTEGER,
69			.name = "brightness",
70			.minimum = 0x00,
71			.maximum = 0xff,
72			.step = 0x01,
73			.default_value = S5K83A_DEFAULT_BRIGHTNESS,
74			.flags = V4L2_CTRL_FLAG_SLIDER
75		},
76			.set = s5k83a_set_brightness,
77			.get = s5k83a_get_brightness,
78	},
79#define EXPOSURE_IDX 2
80	{
81		{
82			.id = V4L2_CID_EXPOSURE,
83			.type = V4L2_CTRL_TYPE_INTEGER,
84			.name = "exposure",
85			.minimum = 0x00,
86			.maximum = S5K83A_MAXIMUM_EXPOSURE,
87			.step = 0x01,
88			.default_value = S5K83A_DEFAULT_EXPOSURE,
89			.flags = V4L2_CTRL_FLAG_SLIDER
90		},
91			.set = s5k83a_set_exposure,
92			.get = s5k83a_get_exposure
93	},
94#define HFLIP_IDX 3
95	{
96		{
97			.id = V4L2_CID_HFLIP,
98			.type = V4L2_CTRL_TYPE_BOOLEAN,
99			.name = "horizontal flip",
100			.minimum = 0,
101			.maximum = 1,
102			.step = 1,
103			.default_value = 0
104		},
105			.set = s5k83a_set_hflip,
106			.get = s5k83a_get_hflip
107	},
108#define VFLIP_IDX 4
109	{
110		{
111			.id = V4L2_CID_VFLIP,
112			.type = V4L2_CTRL_TYPE_BOOLEAN,
113			.name = "vertical flip",
114			.minimum = 0,
115			.maximum = 1,
116			.step = 1,
117			.default_value = 0
118		},
119		.set = s5k83a_set_vflip,
120		.get = s5k83a_get_vflip
121	}
122};
123
124static void s5k83a_dump_registers(struct sd *sd);
125static int s5k83a_get_rotation(struct sd *sd, u8 *reg_data);
126static int s5k83a_set_led_indication(struct sd *sd, u8 val);
127static int s5k83a_set_flip_real(struct gspca_dev *gspca_dev,
128				__s32 vflip, __s32 hflip);
129
130int s5k83a_probe(struct sd *sd)
131{
132	struct s5k83a_priv *sens_priv;
133	u8 prod_id = 0, ver_id = 0;
134	int i, err = 0;
135
136	if (force_sensor) {
137		if (force_sensor == S5K83A_SENSOR) {
138			info("Forcing a %s sensor", s5k83a.name);
139			goto sensor_found;
140		}
141		/* If we want to force another sensor, don't try to probe this
142		 * one */
143		return -ENODEV;
144	}
145
146	PDEBUG(D_PROBE, "Probing for a s5k83a sensor");
147
148	/* Preinit the sensor */
149	for (i = 0; i < ARRAY_SIZE(preinit_s5k83a) && !err; i++) {
150		u8 data[2] = {preinit_s5k83a[i][2], preinit_s5k83a[i][3]};
151		if (preinit_s5k83a[i][0] == SENSOR)
152			err = m5602_write_sensor(sd, preinit_s5k83a[i][1],
153				data, 2);
154		else
155			err = m5602_write_bridge(sd, preinit_s5k83a[i][1],
156				data[0]);
157	}
158
159	/* We don't know what register (if any) that contain the product id
160	 * Just pick the first addresses that seem to produce the same results
161	 * on multiple machines */
162	if (m5602_read_sensor(sd, 0x00, &prod_id, 1))
163		return -ENODEV;
164
165	if (m5602_read_sensor(sd, 0x01, &ver_id, 1))
166		return -ENODEV;
167
168	if ((prod_id == 0xff) || (ver_id == 0xff))
169		return -ENODEV;
170	else
171		info("Detected a s5k83a sensor");
172
173sensor_found:
174	sens_priv = kmalloc(
175		sizeof(struct s5k83a_priv), GFP_KERNEL);
176	if (!sens_priv)
177		return -ENOMEM;
178
179	sens_priv->settings =
180	kmalloc(sizeof(s32)*ARRAY_SIZE(s5k83a_ctrls), GFP_KERNEL);
181	if (!sens_priv->settings) {
182		kfree(sens_priv);
183		return -ENOMEM;
184	}
185
186	sd->gspca_dev.cam.cam_mode = s5k83a_modes;
187	sd->gspca_dev.cam.nmodes = ARRAY_SIZE(s5k83a_modes);
188	sd->desc->ctrls = s5k83a_ctrls;
189	sd->desc->nctrls = ARRAY_SIZE(s5k83a_ctrls);
190
191	/* null the pointer! thread is't running now */
192	sens_priv->rotation_thread = NULL;
193
194	for (i = 0; i < ARRAY_SIZE(s5k83a_ctrls); i++)
195		sens_priv->settings[i] = s5k83a_ctrls[i].qctrl.default_value;
196
197	sd->sensor_priv = sens_priv;
198	return 0;
199}
200
201int s5k83a_init(struct sd *sd)
202{
203	int i, err = 0;
204	s32 *sensor_settings =
205			((struct s5k83a_priv *) sd->sensor_priv)->settings;
206
207	for (i = 0; i < ARRAY_SIZE(init_s5k83a) && !err; i++) {
208		u8 data[2] = {0x00, 0x00};
209
210		switch (init_s5k83a[i][0]) {
211		case BRIDGE:
212			err = m5602_write_bridge(sd,
213					init_s5k83a[i][1],
214					init_s5k83a[i][2]);
215			break;
216
217		case SENSOR:
218			data[0] = init_s5k83a[i][2];
219			err = m5602_write_sensor(sd,
220				init_s5k83a[i][1], data, 1);
221			break;
222
223		case SENSOR_LONG:
224			data[0] = init_s5k83a[i][2];
225			data[1] = init_s5k83a[i][3];
226			err = m5602_write_sensor(sd,
227				init_s5k83a[i][1], data, 2);
228			break;
229		default:
230			info("Invalid stream command, exiting init");
231			return -EINVAL;
232		}
233	}
234
235	if (dump_sensor)
236		s5k83a_dump_registers(sd);
237
238	err = s5k83a_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]);
239	if (err < 0)
240		return err;
241
242	err = s5k83a_set_brightness(&sd->gspca_dev,
243				     sensor_settings[BRIGHTNESS_IDX]);
244	if (err < 0)
245		return err;
246
247	err = s5k83a_set_exposure(&sd->gspca_dev,
248				   sensor_settings[EXPOSURE_IDX]);
249	if (err < 0)
250		return err;
251
252	err = s5k83a_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]);
253	if (err < 0)
254		return err;
255
256	err = s5k83a_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]);
257
258	return err;
259}
260
261static int rotation_thread_function(void *data)
262{
263	struct sd *sd = (struct sd *) data;
264	struct s5k83a_priv *sens_priv = sd->sensor_priv;
265	u8 reg, previous_rotation = 0;
266	__s32 vflip, hflip;
267
268	set_current_state(TASK_INTERRUPTIBLE);
269	while (!schedule_timeout(100)) {
270		if (mutex_lock_interruptible(&sd->gspca_dev.usb_lock))
271			break;
272
273		s5k83a_get_rotation(sd, &reg);
274		if (previous_rotation != reg) {
275			previous_rotation = reg;
276			info("Camera was flipped");
277
278			s5k83a_get_vflip((struct gspca_dev *) sd, &vflip);
279			s5k83a_get_hflip((struct gspca_dev *) sd, &hflip);
280
281			if (reg) {
282				vflip = !vflip;
283				hflip = !hflip;
284			}
285			s5k83a_set_flip_real((struct gspca_dev *) sd,
286					      vflip, hflip);
287		}
288
289		mutex_unlock(&sd->gspca_dev.usb_lock);
290		set_current_state(TASK_INTERRUPTIBLE);
291	}
292
293	/* return to "front" flip */
294	if (previous_rotation) {
295		s5k83a_get_vflip((struct gspca_dev *) sd, &vflip);
296		s5k83a_get_hflip((struct gspca_dev *) sd, &hflip);
297		s5k83a_set_flip_real((struct gspca_dev *) sd, vflip, hflip);
298	}
299
300	sens_priv->rotation_thread = NULL;
301	return 0;
302}
303
304int s5k83a_start(struct sd *sd)
305{
306	int i, err = 0;
307	struct s5k83a_priv *sens_priv = sd->sensor_priv;
308
309	/* Create another thread, polling the GPIO ports of the camera to check
310	   if it got rotated. This is how the windows driver does it so we have
311	   to assume that there is no better way of accomplishing this */
312	sens_priv->rotation_thread = kthread_create(rotation_thread_function,
313						    sd, "rotation thread");
314	wake_up_process(sens_priv->rotation_thread);
315
316	/* Preinit the sensor */
317	for (i = 0; i < ARRAY_SIZE(start_s5k83a) && !err; i++) {
318		u8 data[2] = {start_s5k83a[i][2], start_s5k83a[i][3]};
319		if (start_s5k83a[i][0] == SENSOR)
320			err = m5602_write_sensor(sd, start_s5k83a[i][1],
321				data, 2);
322		else
323			err = m5602_write_bridge(sd, start_s5k83a[i][1],
324				data[0]);
325	}
326	if (err < 0)
327		return err;
328
329	return s5k83a_set_led_indication(sd, 1);
330}
331
332int s5k83a_stop(struct sd *sd)
333{
334	struct s5k83a_priv *sens_priv = sd->sensor_priv;
335
336	if (sens_priv->rotation_thread)
337		kthread_stop(sens_priv->rotation_thread);
338
339	return s5k83a_set_led_indication(sd, 0);
340}
341
342void s5k83a_disconnect(struct sd *sd)
343{
344	struct s5k83a_priv *sens_priv = sd->sensor_priv;
345
346	s5k83a_stop(sd);
347
348	sd->sensor = NULL;
349	kfree(sens_priv->settings);
350	kfree(sens_priv);
351}
352
353static int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
354{
355	struct sd *sd = (struct sd *) gspca_dev;
356	struct s5k83a_priv *sens_priv = sd->sensor_priv;
357
358	*val = sens_priv->settings[GAIN_IDX];
359	return 0;
360}
361
362static int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val)
363{
364	int err;
365	u8 data[2];
366	struct sd *sd = (struct sd *) gspca_dev;
367	struct s5k83a_priv *sens_priv = sd->sensor_priv;
368
369	sens_priv->settings[GAIN_IDX] = val;
370
371	data[0] = 0x00;
372	data[1] = 0x20;
373	err = m5602_write_sensor(sd, 0x14, data, 2);
374	if (err < 0)
375		return err;
376
377	data[0] = 0x01;
378	data[1] = 0x00;
379	err = m5602_write_sensor(sd, 0x0d, data, 2);
380	if (err < 0)
381		return err;
382
383	data[0] = val >> 3; /* gain, high 5 bits */
384	data[1] = val >> 1; /* gain, high 7 bits */
385	err = m5602_write_sensor(sd, S5K83A_GAIN, data, 2);
386
387	return err;
388}
389
390static int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val)
391{
392	struct sd *sd = (struct sd *) gspca_dev;
393	struct s5k83a_priv *sens_priv = sd->sensor_priv;
394
395	*val = sens_priv->settings[BRIGHTNESS_IDX];
396	return 0;
397}
398
399static int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val)
400{
401	int err;
402	u8 data[1];
403	struct sd *sd = (struct sd *) gspca_dev;
404	struct s5k83a_priv *sens_priv = sd->sensor_priv;
405
406	sens_priv->settings[BRIGHTNESS_IDX] = val;
407	data[0] = val;
408	err = m5602_write_sensor(sd, S5K83A_BRIGHTNESS, data, 1);
409	return err;
410}
411
412static int s5k83a_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
413{
414	struct sd *sd = (struct sd *) gspca_dev;
415	struct s5k83a_priv *sens_priv = sd->sensor_priv;
416
417	*val = sens_priv->settings[EXPOSURE_IDX];
418	return 0;
419}
420
421static int s5k83a_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
422{
423	int err;
424	u8 data[2];
425	struct sd *sd = (struct sd *) gspca_dev;
426	struct s5k83a_priv *sens_priv = sd->sensor_priv;
427
428	sens_priv->settings[EXPOSURE_IDX] = val;
429	data[0] = 0;
430	data[1] = val;
431	err = m5602_write_sensor(sd, S5K83A_EXPOSURE, data, 2);
432	return err;
433}
434
435static int s5k83a_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
436{
437	struct sd *sd = (struct sd *) gspca_dev;
438	struct s5k83a_priv *sens_priv = sd->sensor_priv;
439
440	*val = sens_priv->settings[VFLIP_IDX];
441	return 0;
442}
443
444static int s5k83a_set_flip_real(struct gspca_dev *gspca_dev,
445				__s32 vflip, __s32 hflip)
446{
447	int err;
448	u8 data[1];
449	struct sd *sd = (struct sd *) gspca_dev;
450
451	data[0] = 0x05;
452	err = m5602_write_sensor(sd, S5K83A_PAGE_MAP, data, 1);
453	if (err < 0)
454		return err;
455
456	/* six bit is vflip, seven is hflip */
457	data[0] = S5K83A_FLIP_MASK;
458	data[0] = (vflip) ? data[0] | 0x40 : data[0];
459	data[0] = (hflip) ? data[0] | 0x80 : data[0];
460
461	err = m5602_write_sensor(sd, S5K83A_FLIP, data, 1);
462	if (err < 0)
463		return err;
464
465	data[0] = (vflip) ? 0x0b : 0x0a;
466	err = m5602_write_sensor(sd, S5K83A_VFLIP_TUNE, data, 1);
467	if (err < 0)
468		return err;
469
470	data[0] = (hflip) ? 0x0a : 0x0b;
471	err = m5602_write_sensor(sd, S5K83A_HFLIP_TUNE, data, 1);
472	return err;
473}
474
475static int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
476{
477	int err;
478	u8 reg;
479	__s32 hflip;
480	struct sd *sd = (struct sd *) gspca_dev;
481	struct s5k83a_priv *sens_priv = sd->sensor_priv;
482
483	sens_priv->settings[VFLIP_IDX] = val;
484
485	s5k83a_get_hflip(gspca_dev, &hflip);
486
487	err = s5k83a_get_rotation(sd, &reg);
488	if (err < 0)
489		return err;
490	if (reg) {
491		val = !val;
492		hflip = !hflip;
493	}
494
495	err = s5k83a_set_flip_real(gspca_dev, val, hflip);
496	return err;
497}
498
499static int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
500{
501	struct sd *sd = (struct sd *) gspca_dev;
502	struct s5k83a_priv *sens_priv = sd->sensor_priv;
503
504	*val = sens_priv->settings[HFLIP_IDX];
505	return 0;
506}
507
508static int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
509{
510	int err;
511	u8 reg;
512	__s32 vflip;
513	struct sd *sd = (struct sd *) gspca_dev;
514	struct s5k83a_priv *sens_priv = sd->sensor_priv;
515
516	sens_priv->settings[HFLIP_IDX] = val;
517
518	s5k83a_get_vflip(gspca_dev, &vflip);
519
520	err = s5k83a_get_rotation(sd, &reg);
521	if (err < 0)
522		return err;
523	if (reg) {
524		val = !val;
525		vflip = !vflip;
526	}
527
528	err = s5k83a_set_flip_real(gspca_dev, vflip, val);
529	return err;
530}
531
532static int s5k83a_set_led_indication(struct sd *sd, u8 val)
533{
534	int err = 0;
535	u8 data[1];
536
537	err = m5602_read_bridge(sd, M5602_XB_GPIO_DAT, data);
538	if (err < 0)
539		return err;
540
541	if (val)
542		data[0] = data[0] | S5K83A_GPIO_LED_MASK;
543	else
544		data[0] = data[0] & ~S5K83A_GPIO_LED_MASK;
545
546	err = m5602_write_bridge(sd, M5602_XB_GPIO_DAT, data[0]);
547
548	return err;
549}
550
551/* Get camera rotation on Acer notebooks */
552static int s5k83a_get_rotation(struct sd *sd, u8 *reg_data)
553{
554	int err = m5602_read_bridge(sd, M5602_XB_GPIO_DAT, reg_data);
555	*reg_data = (*reg_data & S5K83A_GPIO_ROTATION_MASK) ? 0 : 1;
556	return err;
557}
558
559static void s5k83a_dump_registers(struct sd *sd)
560{
561	int address;
562	u8 page, old_page;
563	m5602_read_sensor(sd, S5K83A_PAGE_MAP, &old_page, 1);
564
565	for (page = 0; page < 16; page++) {
566		m5602_write_sensor(sd, S5K83A_PAGE_MAP, &page, 1);
567		info("Dumping the s5k83a register state for page 0x%x", page);
568		for (address = 0; address <= 0xff; address++) {
569			u8 val = 0;
570			m5602_read_sensor(sd, address, &val, 1);
571			info("register 0x%x contains 0x%x",
572			     address, val);
573		}
574	}
575	info("s5k83a register state dump complete");
576
577	for (page = 0; page < 16; page++) {
578		m5602_write_sensor(sd, S5K83A_PAGE_MAP, &page, 1);
579		info("Probing for which registers that are read/write "
580				"for page 0x%x", page);
581		for (address = 0; address <= 0xff; address++) {
582			u8 old_val, ctrl_val, test_val = 0xff;
583
584			m5602_read_sensor(sd, address, &old_val, 1);
585			m5602_write_sensor(sd, address, &test_val, 1);
586			m5602_read_sensor(sd, address, &ctrl_val, 1);
587
588			if (ctrl_val == test_val)
589				info("register 0x%x is writeable", address);
590			else
591				info("register 0x%x is read only", address);
592
593			/* Restore original val */
594			m5602_write_sensor(sd, address, &old_val, 1);
595		}
596	}
597	info("Read/write register probing complete");
598	m5602_write_sensor(sd, S5K83A_PAGE_MAP, &old_page, 1);
599}
600