diff options
author | Luca Risolia <luca.risolia@studio.unibo.it> | 2007-01-08 08:43:56 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2007-02-21 10:34:19 -0500 |
commit | f327ebbd004fb2f08291ca4c6637f5f27319683c (patch) | |
tree | 9f8ea1a6ae5554a7137e9c8e1c92adda8d06eab4 /drivers/media/video/sn9c102/sn9c102_pas202bcb.c | |
parent | 19790db00bb7ff4d6621b82933afb3423586644e (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.c | 97 |
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, | |||
152 | static int pas202bcb_set_crop(struct sn9c102_device* cam, | 194 | static 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 | ||
167 | static struct sn9c102_sensor pas202bcb = { | 221 | static 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); |