aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/sn9c102/sn9c102_pas202bcb.c
diff options
context:
space:
mode:
authorLuca Risolia <luca.risolia@studio.unibo.it>2007-01-08 08:43:56 -0500
committerMauro Carvalho Chehab <mchehab@infradead.org>2007-02-21 10:34:19 -0500
commitf327ebbd004fb2f08291ca4c6637f5f27319683c (patch)
tree9f8ea1a6ae5554a7137e9c8e1c92adda8d06eab4 /drivers/media/video/sn9c102/sn9c102_pas202bcb.c
parent19790db00bb7ff4d6621b82933afb3423586644e (diff)
V4L/DVB (5062): SN9C102 driver updates
- Add support for SN9C105 and SN9C120 - Add some more USB device identifiers - Add support for OV7660 - Implement audio ioctl's and VIDIOC_ENUM_FRAMESIZES - Add preliminary support for 0x0c45/0x6007 - Documentation updates - Generic improvements Signed-off-by: Luca Risolia <luca.risolia@studio.unibo.it> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video/sn9c102/sn9c102_pas202bcb.c')
-rw-r--r--drivers/media/video/sn9c102/sn9c102_pas202bcb.c97
1 files changed, 81 insertions, 16 deletions
diff --git a/drivers/media/video/sn9c102/sn9c102_pas202bcb.c b/drivers/media/video/sn9c102/sn9c102_pas202bcb.c
index e3c1178e339c..7894f01b56e8 100644
--- a/drivers/media/video/sn9c102/sn9c102_pas202bcb.c
+++ b/drivers/media/video/sn9c102/sn9c102_pas202bcb.c
@@ -1,13 +1,13 @@
1/*************************************************************************** 1/***************************************************************************
2 * Plug-in for PAS202BCB image sensor connected to the SN9C10x PC Camera * 2 * Plug-in for PAS202BCB image sensor connected to the SN9C1xx PC Camera *
3 * Controllers * 3 * Controllers *
4 * * 4 * *
5 * Copyright (C) 2004 by Carlos Eduardo Medaglia Dyonisio * 5 * Copyright (C) 2004 by Carlos Eduardo Medaglia Dyonisio *
6 * <medaglia@undl.org.br> * 6 * <medaglia@undl.org.br> *
7 * http://cadu.homelinux.com:8080/ * 7 * http://cadu.homelinux.com:8080/ *
8 * * 8 * *
9 * DAC Magnitude, exposure and green gain controls added by * 9 * Support for SN9C103, DAC Magnitude, exposure and green gain controls *
10 * Luca Risolia <luca.risolia@studio.unibo.it> * 10 * added by Luca Risolia <luca.risolia@studio.unibo.it> *
11 * * 11 * *
12 * This program is free software; you can redistribute it and/or modify * 12 * This program is free software; you can redistribute it and/or modify *
13 * it under the terms of the GNU General Public License as published by * 13 * it under the terms of the GNU General Public License as published by *
@@ -35,12 +35,54 @@ static int pas202bcb_init(struct sn9c102_device* cam)
35{ 35{
36 int err = 0; 36 int err = 0;
37 37
38 switch (sn9c102_get_bridge(cam)) {
39 case BRIDGE_SN9C101:
40 case BRIDGE_SN9C102:
38 err += sn9c102_write_reg(cam, 0x00, 0x10); 41 err += sn9c102_write_reg(cam, 0x00, 0x10);
39 err += sn9c102_write_reg(cam, 0x00, 0x11); 42 err += sn9c102_write_reg(cam, 0x00, 0x11);
40 err += sn9c102_write_reg(cam, 0x00, 0x14); 43 err += sn9c102_write_reg(cam, 0x00, 0x14);
41 err += sn9c102_write_reg(cam, 0x20, 0x17); 44 err += sn9c102_write_reg(cam, 0x20, 0x17);
42 err += sn9c102_write_reg(cam, 0x30, 0x19); 45 err += sn9c102_write_reg(cam, 0x30, 0x19);
43 err += sn9c102_write_reg(cam, 0x09, 0x18); 46 err += sn9c102_write_reg(cam, 0x09, 0x18);
47 break;
48 case BRIDGE_SN9C103:
49 err += sn9c102_write_reg(cam, 0x00, 0x02);
50 err += sn9c102_write_reg(cam, 0x00, 0x03);
51 err += sn9c102_write_reg(cam, 0x1a, 0x04);
52 err += sn9c102_write_reg(cam, 0x20, 0x05);
53 err += sn9c102_write_reg(cam, 0x20, 0x06);
54 err += sn9c102_write_reg(cam, 0x20, 0x07);
55 err += sn9c102_write_reg(cam, 0x00, 0x10);
56 err += sn9c102_write_reg(cam, 0x00, 0x11);
57 err += sn9c102_write_reg(cam, 0x00, 0x14);
58 err += sn9c102_write_reg(cam, 0x20, 0x17);
59 err += sn9c102_write_reg(cam, 0x30, 0x19);
60 err += sn9c102_write_reg(cam, 0x09, 0x18);
61 err += sn9c102_write_reg(cam, 0x02, 0x1c);
62 err += sn9c102_write_reg(cam, 0x03, 0x1d);
63 err += sn9c102_write_reg(cam, 0x0f, 0x1e);
64 err += sn9c102_write_reg(cam, 0x0c, 0x1f);
65 err += sn9c102_write_reg(cam, 0x00, 0x20);
66 err += sn9c102_write_reg(cam, 0x10, 0x21);
67 err += sn9c102_write_reg(cam, 0x20, 0x22);
68 err += sn9c102_write_reg(cam, 0x30, 0x23);
69 err += sn9c102_write_reg(cam, 0x40, 0x24);
70 err += sn9c102_write_reg(cam, 0x50, 0x25);
71 err += sn9c102_write_reg(cam, 0x60, 0x26);
72 err += sn9c102_write_reg(cam, 0x70, 0x27);
73 err += sn9c102_write_reg(cam, 0x80, 0x28);
74 err += sn9c102_write_reg(cam, 0x90, 0x29);
75 err += sn9c102_write_reg(cam, 0xa0, 0x2a);
76 err += sn9c102_write_reg(cam, 0xb0, 0x2b);
77 err += sn9c102_write_reg(cam, 0xc0, 0x2c);
78 err += sn9c102_write_reg(cam, 0xd0, 0x2d);
79 err += sn9c102_write_reg(cam, 0xe0, 0x2e);
80 err += sn9c102_write_reg(cam, 0xf0, 0x2f);
81 err += sn9c102_write_reg(cam, 0xff, 0x30);
82 break;
83 default:
84 break;
85 }
44 86
45 err += sn9c102_i2c_write(cam, 0x02, 0x14); 87 err += sn9c102_i2c_write(cam, 0x02, 0x14);
46 err += sn9c102_i2c_write(cam, 0x03, 0x40); 88 err += sn9c102_i2c_write(cam, 0x03, 0x40);
@@ -107,7 +149,7 @@ static int pas202bcb_set_pix_format(struct sn9c102_device* cam,
107 int err = 0; 149 int err = 0;
108 150
109 if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X) 151 if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X)
110 err += sn9c102_write_reg(cam, 0x24, 0x17); 152 err += sn9c102_write_reg(cam, 0x28, 0x17);
111 else 153 else
112 err += sn9c102_write_reg(cam, 0x20, 0x17); 154 err += sn9c102_write_reg(cam, 0x20, 0x17);
113 155
@@ -152,11 +194,23 @@ static int pas202bcb_set_ctrl(struct sn9c102_device* cam,
152static int pas202bcb_set_crop(struct sn9c102_device* cam, 194static int pas202bcb_set_crop(struct sn9c102_device* cam,
153 const struct v4l2_rect* rect) 195 const struct v4l2_rect* rect)
154{ 196{
155 struct sn9c102_sensor* s = &pas202bcb; 197 struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
156 int err = 0; 198 int err = 0;
157 u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 4, 199 u8 h_start = 0,
158 v_start = (u8)(rect->top - s->cropcap.bounds.top) + 3; 200 v_start = (u8)(rect->top - s->cropcap.bounds.top) + 3;
159 201
202 switch (sn9c102_get_bridge(cam)) {
203 case BRIDGE_SN9C101:
204 case BRIDGE_SN9C102:
205 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 4;
206 break;
207 case BRIDGE_SN9C103:
208 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 3;
209 break;
210 default:
211 break;
212 }
213
160 err += sn9c102_write_reg(cam, h_start, 0x12); 214 err += sn9c102_write_reg(cam, h_start, 0x12);
161 err += sn9c102_write_reg(cam, v_start, 0x13); 215 err += sn9c102_write_reg(cam, v_start, 0x13);
162 216
@@ -166,8 +220,8 @@ static int pas202bcb_set_crop(struct sn9c102_device* cam,
166 220
167static struct sn9c102_sensor pas202bcb = { 221static struct sn9c102_sensor pas202bcb = {
168 .name = "PAS202BCB", 222 .name = "PAS202BCB",
169 .maintainer = "Carlos Eduardo Medaglia Dyonisio " 223 .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
170 "<medaglia@undl.org.br>", 224 .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102 | BRIDGE_SN9C103,
171 .sysfs_ops = SN9C102_I2C_READ | SN9C102_I2C_WRITE, 225 .sysfs_ops = SN9C102_I2C_READ | SN9C102_I2C_WRITE,
172 .frequency = SN9C102_I2C_400KHZ | SN9C102_I2C_100KHZ, 226 .frequency = SN9C102_I2C_400KHZ | SN9C102_I2C_100KHZ,
173 .interface = SN9C102_I2C_2WIRES, 227 .interface = SN9C102_I2C_2WIRES,
@@ -191,7 +245,7 @@ static struct sn9c102_sensor pas202bcb = {
191 .minimum = 0x00, 245 .minimum = 0x00,
192 .maximum = 0x1f, 246 .maximum = 0x1f,
193 .step = 0x01, 247 .step = 0x01,
194 .default_value = 0x0c, 248 .default_value = 0x0b,
195 .flags = 0, 249 .flags = 0,
196 }, 250 },
197 { 251 {
@@ -201,7 +255,7 @@ static struct sn9c102_sensor pas202bcb = {
201 .minimum = 0x00, 255 .minimum = 0x00,
202 .maximum = 0x0f, 256 .maximum = 0x0f,
203 .step = 0x01, 257 .step = 0x01,
204 .default_value = 0x01, 258 .default_value = 0x00,
205 .flags = 0, 259 .flags = 0,
206 }, 260 },
207 { 261 {
@@ -271,16 +325,27 @@ int sn9c102_probe_pas202bcb(struct sn9c102_device* cam)
271 * Minimal initialization to enable the I2C communication 325 * Minimal initialization to enable the I2C communication
272 * NOTE: do NOT change the values! 326 * NOTE: do NOT change the values!
273 */ 327 */
274 err += sn9c102_write_reg(cam, 0x01, 0x01); /* sensor power down */ 328 switch (sn9c102_get_bridge(cam)) {
275 err += sn9c102_write_reg(cam, 0x40, 0x01); /* sensor power on */ 329 case BRIDGE_SN9C101:
276 err += sn9c102_write_reg(cam, 0x28, 0x17); /* sensor clock at 24 MHz */ 330 case BRIDGE_SN9C102:
277 if (err) 331 err += sn9c102_write_reg(cam, 0x01, 0x01); /* power down */
278 return -EIO; 332 err += sn9c102_write_reg(cam, 0x40, 0x01); /* power on */
333 err += sn9c102_write_reg(cam, 0x28, 0x17); /* clock 24 MHz */
334 break;
335 case BRIDGE_SN9C103: /* do _not_ change anything! */
336 err += sn9c102_write_reg(cam, 0x09, 0x01);
337 err += sn9c102_write_reg(cam, 0x44, 0x01);
338 err += sn9c102_write_reg(cam, 0x44, 0x02);
339 err += sn9c102_write_reg(cam, 0x29, 0x17);
340 break;
341 default:
342 break;
343 }
279 344
280 r0 = sn9c102_i2c_try_read(cam, &pas202bcb, 0x00); 345 r0 = sn9c102_i2c_try_read(cam, &pas202bcb, 0x00);
281 r1 = sn9c102_i2c_try_read(cam, &pas202bcb, 0x01); 346 r1 = sn9c102_i2c_try_read(cam, &pas202bcb, 0x01);
282 347
283 if (r0 < 0 || r1 < 0) 348 if (err || r0 < 0 || r1 < 0)
284 return -EIO; 349 return -EIO;
285 350
286 pid = (r0 << 4) | ((r1 & 0xf0) >> 4); 351 pid = (r0 << 4) | ((r1 & 0xf0) >> 4);