aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video
diff options
context:
space:
mode:
authorAmerigo Wang <amwang@redhat.com>2010-05-28 05:45:38 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-08-02 14:26:43 -0400
commit3b23bc5731d476b0913c437626d6a6f51687d1d6 (patch)
tree3181b82af5d5ff99ebf550bb8f9abb54c54f34e9 /drivers/media/video
parent51c555690d16d1d1354ee9b5a3c9098766702094 (diff)
V4L/DVB: Remove obsolete ovcamchip sensor framework
Only used by obsoleted v4l1 driver Signed-off-by: Amerigo Wang <amwang@redhat.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video')
-rw-r--r--drivers/media/video/Kconfig17
-rw-r--r--drivers/media/video/Makefile1
-rw-r--r--drivers/media/video/ovcamchip/Makefile4
-rw-r--r--drivers/media/video/ovcamchip/ov6x20.c414
-rw-r--r--drivers/media/video/ovcamchip/ov6x30.c373
-rw-r--r--drivers/media/video/ovcamchip/ov76be.c302
-rw-r--r--drivers/media/video/ovcamchip/ov7x10.c334
-rw-r--r--drivers/media/video/ovcamchip/ov7x20.c454
-rw-r--r--drivers/media/video/ovcamchip/ovcamchip_core.c395
-rw-r--r--drivers/media/video/ovcamchip/ovcamchip_priv.h101
10 files changed, 0 insertions, 2395 deletions
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index 60889593785c..bf47cdc95a71 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -1001,23 +1001,6 @@ source "drivers/media/video/usbvideo/Kconfig"
1001 1001
1002source "drivers/media/video/et61x251/Kconfig" 1002source "drivers/media/video/et61x251/Kconfig"
1003 1003
1004config VIDEO_OVCAMCHIP
1005 tristate "OmniVision Camera Chip support (DEPRECATED)"
1006 depends on I2C && VIDEO_V4L1
1007 default n
1008 ---help---
1009 This driver is DEPRECATED please use the gspca ov519 module
1010 instead. Note that for the ov511 / ov518 support of the gspca module
1011 you need atleast version 0.6.0 of libv4l and for the w9968cf
1012 atleast version 0.6.3 of libv4l.
1013
1014 Support for the OmniVision OV6xxx and OV7xxx series of camera chips.
1015 This driver is intended to be used with the ov511 and w9968cf USB
1016 camera drivers.
1017
1018 To compile this driver as a module, choose M here: the
1019 module will be called ovcamchip.
1020
1021config USB_SE401 1004config USB_SE401
1022 tristate "USB SE401 Camera support" 1005 tristate "USB SE401 Camera support"
1023 depends on VIDEO_V4L1 1006 depends on VIDEO_V4L1
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index bb702c921c7a..e3603b4ceeaa 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -105,7 +105,6 @@ obj-$(CONFIG_VIDEO_TLG2300) += tlg2300/
105obj-$(CONFIG_VIDEO_CX231XX) += cx231xx/ 105obj-$(CONFIG_VIDEO_CX231XX) += cx231xx/
106obj-$(CONFIG_VIDEO_USBVISION) += usbvision/ 106obj-$(CONFIG_VIDEO_USBVISION) += usbvision/
107obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2/ 107obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2/
108obj-$(CONFIG_VIDEO_OVCAMCHIP) += ovcamchip/
109obj-$(CONFIG_VIDEO_CPIA2) += cpia2/ 108obj-$(CONFIG_VIDEO_CPIA2) += cpia2/
110obj-$(CONFIG_VIDEO_MXB) += mxb.o 109obj-$(CONFIG_VIDEO_MXB) += mxb.o
111obj-$(CONFIG_VIDEO_HEXIUM_ORION) += hexium_orion.o 110obj-$(CONFIG_VIDEO_HEXIUM_ORION) += hexium_orion.o
diff --git a/drivers/media/video/ovcamchip/Makefile b/drivers/media/video/ovcamchip/Makefile
deleted file mode 100644
index cba4cdf20f49..000000000000
--- a/drivers/media/video/ovcamchip/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
1ovcamchip-objs := ovcamchip_core.o ov6x20.o ov6x30.o ov7x10.o ov7x20.o \
2 ov76be.o
3
4obj-$(CONFIG_VIDEO_OVCAMCHIP) += ovcamchip.o
diff --git a/drivers/media/video/ovcamchip/ov6x20.c b/drivers/media/video/ovcamchip/ov6x20.c
deleted file mode 100644
index c04130dab127..000000000000
--- a/drivers/media/video/ovcamchip/ov6x20.c
+++ /dev/null
@@ -1,414 +0,0 @@
1/* OmniVision OV6620/OV6120 Camera Chip Support Code
2 *
3 * Copyright (c) 1999-2004 Mark McClelland <mark@alpha.dyndns.org>
4 * http://alpha.dyndns.org/ov511/
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. NO WARRANTY OF ANY KIND is expressed or implied.
10 */
11
12#define DEBUG
13
14#include <linux/slab.h>
15#include "ovcamchip_priv.h"
16
17/* Registers */
18#define REG_GAIN 0x00 /* gain [5:0] */
19#define REG_BLUE 0x01 /* blue gain */
20#define REG_RED 0x02 /* red gain */
21#define REG_SAT 0x03 /* saturation */
22#define REG_CNT 0x05 /* Y contrast */
23#define REG_BRT 0x06 /* Y brightness */
24#define REG_WB_BLUE 0x0C /* WB blue ratio [5:0] */
25#define REG_WB_RED 0x0D /* WB red ratio [5:0] */
26#define REG_EXP 0x10 /* exposure */
27
28/* Window parameters */
29#define HWSBASE 0x38
30#define HWEBASE 0x3A
31#define VWSBASE 0x05
32#define VWEBASE 0x06
33
34struct ov6x20 {
35 int auto_brt;
36 int auto_exp;
37 int backlight;
38 int bandfilt;
39 int mirror;
40};
41
42/* Initial values for use with OV511/OV511+ cameras */
43static struct ovcamchip_regvals regvals_init_6x20_511[] = {
44 { 0x12, 0x80 }, /* reset */
45 { 0x11, 0x01 },
46 { 0x03, 0x60 },
47 { 0x05, 0x7f }, /* For when autoadjust is off */
48 { 0x07, 0xa8 },
49 { 0x0c, 0x24 },
50 { 0x0d, 0x24 },
51 { 0x0f, 0x15 }, /* COMS */
52 { 0x10, 0x75 }, /* AEC Exposure time */
53 { 0x12, 0x24 }, /* Enable AGC and AWB */
54 { 0x14, 0x04 },
55 { 0x16, 0x03 },
56 { 0x26, 0xb2 }, /* BLC enable */
57 /* 0x28: 0x05 Selects RGB format if RGB on */
58 { 0x28, 0x05 },
59 { 0x2a, 0x04 }, /* Disable framerate adjust */
60 { 0x2d, 0x99 },
61 { 0x33, 0xa0 }, /* Color Processing Parameter */
62 { 0x34, 0xd2 }, /* Max A/D range */
63 { 0x38, 0x8b },
64 { 0x39, 0x40 },
65
66 { 0x3c, 0x39 }, /* Enable AEC mode changing */
67 { 0x3c, 0x3c }, /* Change AEC mode */
68 { 0x3c, 0x24 }, /* Disable AEC mode changing */
69
70 { 0x3d, 0x80 },
71 /* These next two registers (0x4a, 0x4b) are undocumented. They
72 * control the color balance */
73 { 0x4a, 0x80 },
74 { 0x4b, 0x80 },
75 { 0x4d, 0xd2 }, /* This reduces noise a bit */
76 { 0x4e, 0xc1 },
77 { 0x4f, 0x04 },
78 { 0xff, 0xff }, /* END MARKER */
79};
80
81/* Initial values for use with OV518 cameras */
82static struct ovcamchip_regvals regvals_init_6x20_518[] = {
83 { 0x12, 0x80 }, /* Do a reset */
84 { 0x03, 0xc0 }, /* Saturation */
85 { 0x05, 0x8a }, /* Contrast */
86 { 0x0c, 0x24 }, /* AWB blue */
87 { 0x0d, 0x24 }, /* AWB red */
88 { 0x0e, 0x8d }, /* Additional 2x gain */
89 { 0x0f, 0x25 }, /* Black expanding level = 1.3V */
90 { 0x11, 0x01 }, /* Clock div. */
91 { 0x12, 0x24 }, /* Enable AGC and AWB */
92 { 0x13, 0x01 }, /* (default) */
93 { 0x14, 0x80 }, /* Set reserved bit 7 */
94 { 0x15, 0x01 }, /* (default) */
95 { 0x16, 0x03 }, /* (default) */
96 { 0x17, 0x38 }, /* (default) */
97 { 0x18, 0xea }, /* (default) */
98 { 0x19, 0x04 },
99 { 0x1a, 0x93 },
100 { 0x1b, 0x00 }, /* (default) */
101 { 0x1e, 0xc4 }, /* (default) */
102 { 0x1f, 0x04 }, /* (default) */
103 { 0x20, 0x20 }, /* Enable 1st stage aperture correction */
104 { 0x21, 0x10 }, /* Y offset */
105 { 0x22, 0x88 }, /* U offset */
106 { 0x23, 0xc0 }, /* Set XTAL power level */
107 { 0x24, 0x53 }, /* AEC bright ratio */
108 { 0x25, 0x7a }, /* AEC black ratio */
109 { 0x26, 0xb2 }, /* BLC enable */
110 { 0x27, 0xa2 }, /* Full output range */
111 { 0x28, 0x01 }, /* (default) */
112 { 0x29, 0x00 }, /* (default) */
113 { 0x2a, 0x84 }, /* (default) */
114 { 0x2b, 0xa8 }, /* Set custom frame rate */
115 { 0x2c, 0xa0 }, /* (reserved) */
116 { 0x2d, 0x95 }, /* Enable banding filter */
117 { 0x2e, 0x88 }, /* V offset */
118 { 0x33, 0x22 }, /* Luminance gamma on */
119 { 0x34, 0xc7 }, /* A/D bias */
120 { 0x36, 0x12 }, /* (reserved) */
121 { 0x37, 0x63 }, /* (reserved) */
122 { 0x38, 0x8b }, /* Quick AEC/AEB */
123 { 0x39, 0x00 }, /* (default) */
124 { 0x3a, 0x0f }, /* (default) */
125 { 0x3b, 0x3c }, /* (default) */
126 { 0x3c, 0x5c }, /* AEC controls */
127 { 0x3d, 0x80 }, /* Drop 1 (bad) frame when AEC change */
128 { 0x3e, 0x80 }, /* (default) */
129 { 0x3f, 0x02 }, /* (default) */
130 { 0x40, 0x10 }, /* (reserved) */
131 { 0x41, 0x10 }, /* (reserved) */
132 { 0x42, 0x00 }, /* (reserved) */
133 { 0x43, 0x7f }, /* (reserved) */
134 { 0x44, 0x80 }, /* (reserved) */
135 { 0x45, 0x1c }, /* (reserved) */
136 { 0x46, 0x1c }, /* (reserved) */
137 { 0x47, 0x80 }, /* (reserved) */
138 { 0x48, 0x5f }, /* (reserved) */
139 { 0x49, 0x00 }, /* (reserved) */
140 { 0x4a, 0x00 }, /* Color balance (undocumented) */
141 { 0x4b, 0x80 }, /* Color balance (undocumented) */
142 { 0x4c, 0x58 }, /* (reserved) */
143 { 0x4d, 0xd2 }, /* U *= .938, V *= .838 */
144 { 0x4e, 0xa0 }, /* (default) */
145 { 0x4f, 0x04 }, /* UV 3-point average */
146 { 0x50, 0xff }, /* (reserved) */
147 { 0x51, 0x58 }, /* (reserved) */
148 { 0x52, 0xc0 }, /* (reserved) */
149 { 0x53, 0x42 }, /* (reserved) */
150 { 0x27, 0xa6 }, /* Enable manual offset adj. (reg 21 & 22) */
151 { 0x12, 0x20 },
152 { 0x12, 0x24 },
153
154 { 0xff, 0xff }, /* END MARKER */
155};
156
157/* This initializes the OV6x20 camera chip and relevant variables. */
158static int ov6x20_init(struct i2c_client *c)
159{
160 struct ovcamchip *ov = i2c_get_clientdata(c);
161 struct ov6x20 *s;
162 int rc;
163
164 DDEBUG(4, &c->dev, "entered");
165
166 switch (c->adapter->id) {
167 case I2C_HW_SMBUS_OV511:
168 rc = ov_write_regvals(c, regvals_init_6x20_511);
169 break;
170 case I2C_HW_SMBUS_OV518:
171 rc = ov_write_regvals(c, regvals_init_6x20_518);
172 break;
173 default:
174 dev_err(&c->dev, "ov6x20: Unsupported adapter\n");
175 rc = -ENODEV;
176 }
177
178 if (rc < 0)
179 return rc;
180
181 ov->spriv = s = kzalloc(sizeof *s, GFP_KERNEL);
182 if (!s)
183 return -ENOMEM;
184
185 s->auto_brt = 1;
186 s->auto_exp = 1;
187
188 return rc;
189}
190
191static int ov6x20_free(struct i2c_client *c)
192{
193 struct ovcamchip *ov = i2c_get_clientdata(c);
194
195 kfree(ov->spriv);
196 return 0;
197}
198
199static int ov6x20_set_control(struct i2c_client *c,
200 struct ovcamchip_control *ctl)
201{
202 struct ovcamchip *ov = i2c_get_clientdata(c);
203 struct ov6x20 *s = ov->spriv;
204 int rc;
205 int v = ctl->value;
206
207 switch (ctl->id) {
208 case OVCAMCHIP_CID_CONT:
209 rc = ov_write(c, REG_CNT, v >> 8);
210 break;
211 case OVCAMCHIP_CID_BRIGHT:
212 rc = ov_write(c, REG_BRT, v >> 8);
213 break;
214 case OVCAMCHIP_CID_SAT:
215 rc = ov_write(c, REG_SAT, v >> 8);
216 break;
217 case OVCAMCHIP_CID_HUE:
218 rc = ov_write(c, REG_RED, 0xFF - (v >> 8));
219 if (rc < 0)
220 goto out;
221
222 rc = ov_write(c, REG_BLUE, v >> 8);
223 break;
224 case OVCAMCHIP_CID_EXP:
225 rc = ov_write(c, REG_EXP, v);
226 break;
227 case OVCAMCHIP_CID_FREQ:
228 {
229 int sixty = (v == 60);
230
231 rc = ov_write(c, 0x2b, sixty?0xa8:0x28);
232 if (rc < 0)
233 goto out;
234
235 rc = ov_write(c, 0x2a, sixty?0x84:0xa4);
236 break;
237 }
238 case OVCAMCHIP_CID_BANDFILT:
239 rc = ov_write_mask(c, 0x2d, v?0x04:0x00, 0x04);
240 s->bandfilt = v;
241 break;
242 case OVCAMCHIP_CID_AUTOBRIGHT:
243 rc = ov_write_mask(c, 0x2d, v?0x10:0x00, 0x10);
244 s->auto_brt = v;
245 break;
246 case OVCAMCHIP_CID_AUTOEXP:
247 rc = ov_write_mask(c, 0x13, v?0x01:0x00, 0x01);
248 s->auto_exp = v;
249 break;
250 case OVCAMCHIP_CID_BACKLIGHT:
251 {
252 rc = ov_write_mask(c, 0x4e, v?0xe0:0xc0, 0xe0);
253 if (rc < 0)
254 goto out;
255
256 rc = ov_write_mask(c, 0x29, v?0x08:0x00, 0x08);
257 if (rc < 0)
258 goto out;
259
260 rc = ov_write_mask(c, 0x0e, v?0x80:0x00, 0x80);
261 s->backlight = v;
262 break;
263 }
264 case OVCAMCHIP_CID_MIRROR:
265 rc = ov_write_mask(c, 0x12, v?0x40:0x00, 0x40);
266 s->mirror = v;
267 break;
268 default:
269 DDEBUG(2, &c->dev, "control not supported: %d", ctl->id);
270 return -EPERM;
271 }
272
273out:
274 DDEBUG(3, &c->dev, "id=%d, arg=%d, rc=%d", ctl->id, v, rc);
275 return rc;
276}
277
278static int ov6x20_get_control(struct i2c_client *c,
279 struct ovcamchip_control *ctl)
280{
281 struct ovcamchip *ov = i2c_get_clientdata(c);
282 struct ov6x20 *s = ov->spriv;
283 int rc = 0;
284 unsigned char val = 0;
285
286 switch (ctl->id) {
287 case OVCAMCHIP_CID_CONT:
288 rc = ov_read(c, REG_CNT, &val);
289 ctl->value = val << 8;
290 break;
291 case OVCAMCHIP_CID_BRIGHT:
292 rc = ov_read(c, REG_BRT, &val);
293 ctl->value = val << 8;
294 break;
295 case OVCAMCHIP_CID_SAT:
296 rc = ov_read(c, REG_SAT, &val);
297 ctl->value = val << 8;
298 break;
299 case OVCAMCHIP_CID_HUE:
300 rc = ov_read(c, REG_BLUE, &val);
301 ctl->value = val << 8;
302 break;
303 case OVCAMCHIP_CID_EXP:
304 rc = ov_read(c, REG_EXP, &val);
305 ctl->value = val;
306 break;
307 case OVCAMCHIP_CID_BANDFILT:
308 ctl->value = s->bandfilt;
309 break;
310 case OVCAMCHIP_CID_AUTOBRIGHT:
311 ctl->value = s->auto_brt;
312 break;
313 case OVCAMCHIP_CID_AUTOEXP:
314 ctl->value = s->auto_exp;
315 break;
316 case OVCAMCHIP_CID_BACKLIGHT:
317 ctl->value = s->backlight;
318 break;
319 case OVCAMCHIP_CID_MIRROR:
320 ctl->value = s->mirror;
321 break;
322 default:
323 DDEBUG(2, &c->dev, "control not supported: %d", ctl->id);
324 return -EPERM;
325 }
326
327 DDEBUG(3, &c->dev, "id=%d, arg=%d, rc=%d", ctl->id, ctl->value, rc);
328 return rc;
329}
330
331static int ov6x20_mode_init(struct i2c_client *c, struct ovcamchip_window *win)
332{
333 /******** QCIF-specific regs ********/
334
335 ov_write(c, 0x14, win->quarter?0x24:0x04);
336
337 /******** Palette-specific regs ********/
338
339 /* OV518 needs 8 bit multiplexed in color mode, and 16 bit in B&W */
340 if (c->adapter->id == I2C_HW_SMBUS_OV518) {
341 if (win->format == VIDEO_PALETTE_GREY)
342 ov_write_mask(c, 0x13, 0x00, 0x20);
343 else
344 ov_write_mask(c, 0x13, 0x20, 0x20);
345 } else {
346 if (win->format == VIDEO_PALETTE_GREY)
347 ov_write_mask(c, 0x13, 0x20, 0x20);
348 else
349 ov_write_mask(c, 0x13, 0x00, 0x20);
350 }
351
352 /******** Clock programming ********/
353
354 /* The OV6620 needs special handling. This prevents the
355 * severe banding that normally occurs */
356
357 /* Clock down */
358 ov_write(c, 0x2a, 0x04);
359
360 ov_write(c, 0x11, win->clockdiv);
361
362 ov_write(c, 0x2a, 0x84);
363 /* This next setting is critical. It seems to improve
364 * the gain or the contrast. The "reserved" bits seem
365 * to have some effect in this case. */
366 ov_write(c, 0x2d, 0x85); /* FIXME: This messes up banding filter */
367
368 return 0;
369}
370
371static int ov6x20_set_window(struct i2c_client *c, struct ovcamchip_window *win)
372{
373 int ret, hwscale, vwscale;
374
375 ret = ov6x20_mode_init(c, win);
376 if (ret < 0)
377 return ret;
378
379 if (win->quarter) {
380 hwscale = 0;
381 vwscale = 0;
382 } else {
383 hwscale = 1;
384 vwscale = 1; /* The datasheet says 0; it's wrong */
385 }
386
387 ov_write(c, 0x17, HWSBASE + (win->x >> hwscale));
388 ov_write(c, 0x18, HWEBASE + ((win->x + win->width) >> hwscale));
389 ov_write(c, 0x19, VWSBASE + (win->y >> vwscale));
390 ov_write(c, 0x1a, VWEBASE + ((win->y + win->height) >> vwscale));
391
392 return 0;
393}
394
395static int ov6x20_command(struct i2c_client *c, unsigned int cmd, void *arg)
396{
397 switch (cmd) {
398 case OVCAMCHIP_CMD_S_CTRL:
399 return ov6x20_set_control(c, arg);
400 case OVCAMCHIP_CMD_G_CTRL:
401 return ov6x20_get_control(c, arg);
402 case OVCAMCHIP_CMD_S_MODE:
403 return ov6x20_set_window(c, arg);
404 default:
405 DDEBUG(2, &c->dev, "command not supported: %d", cmd);
406 return -ENOIOCTLCMD;
407 }
408}
409
410struct ovcamchip_ops ov6x20_ops = {
411 .init = ov6x20_init,
412 .free = ov6x20_free,
413 .command = ov6x20_command,
414};
diff --git a/drivers/media/video/ovcamchip/ov6x30.c b/drivers/media/video/ovcamchip/ov6x30.c
deleted file mode 100644
index 73b94f51a85a..000000000000
--- a/drivers/media/video/ovcamchip/ov6x30.c
+++ /dev/null
@@ -1,373 +0,0 @@
1/* OmniVision OV6630/OV6130 Camera Chip Support Code
2 *
3 * Copyright (c) 1999-2004 Mark McClelland <mark@alpha.dyndns.org>
4 * http://alpha.dyndns.org/ov511/
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. NO WARRANTY OF ANY KIND is expressed or implied.
10 */
11
12#define DEBUG
13
14#include <linux/slab.h>
15#include "ovcamchip_priv.h"
16
17/* Registers */
18#define REG_GAIN 0x00 /* gain [5:0] */
19#define REG_BLUE 0x01 /* blue gain */
20#define REG_RED 0x02 /* red gain */
21#define REG_SAT 0x03 /* saturation [7:3] */
22#define REG_CNT 0x05 /* Y contrast [3:0] */
23#define REG_BRT 0x06 /* Y brightness */
24#define REG_SHARP 0x07 /* sharpness */
25#define REG_WB_BLUE 0x0C /* WB blue ratio [5:0] */
26#define REG_WB_RED 0x0D /* WB red ratio [5:0] */
27#define REG_EXP 0x10 /* exposure */
28
29/* Window parameters */
30#define HWSBASE 0x38
31#define HWEBASE 0x3A
32#define VWSBASE 0x05
33#define VWEBASE 0x06
34
35struct ov6x30 {
36 int auto_brt;
37 int auto_exp;
38 int backlight;
39 int bandfilt;
40 int mirror;
41};
42
43static struct ovcamchip_regvals regvals_init_6x30[] = {
44 { 0x12, 0x80 }, /* reset */
45 { 0x00, 0x1f }, /* Gain */
46 { 0x01, 0x99 }, /* Blue gain */
47 { 0x02, 0x7c }, /* Red gain */
48 { 0x03, 0xc0 }, /* Saturation */
49 { 0x05, 0x0a }, /* Contrast */
50 { 0x06, 0x95 }, /* Brightness */
51 { 0x07, 0x2d }, /* Sharpness */
52 { 0x0c, 0x20 },
53 { 0x0d, 0x20 },
54 { 0x0e, 0x20 },
55 { 0x0f, 0x05 },
56 { 0x10, 0x9a }, /* "exposure check" */
57 { 0x11, 0x00 }, /* Pixel clock = fastest */
58 { 0x12, 0x24 }, /* Enable AGC and AWB */
59 { 0x13, 0x21 },
60 { 0x14, 0x80 },
61 { 0x15, 0x01 },
62 { 0x16, 0x03 },
63 { 0x17, 0x38 },
64 { 0x18, 0xea },
65 { 0x19, 0x04 },
66 { 0x1a, 0x93 },
67 { 0x1b, 0x00 },
68 { 0x1e, 0xc4 },
69 { 0x1f, 0x04 },
70 { 0x20, 0x20 },
71 { 0x21, 0x10 },
72 { 0x22, 0x88 },
73 { 0x23, 0xc0 }, /* Crystal circuit power level */
74 { 0x25, 0x9a }, /* Increase AEC black pixel ratio */
75 { 0x26, 0xb2 }, /* BLC enable */
76 { 0x27, 0xa2 },
77 { 0x28, 0x00 },
78 { 0x29, 0x00 },
79 { 0x2a, 0x84 }, /* (keep) */
80 { 0x2b, 0xa8 }, /* (keep) */
81 { 0x2c, 0xa0 },
82 { 0x2d, 0x95 }, /* Enable auto-brightness */
83 { 0x2e, 0x88 },
84 { 0x33, 0x26 },
85 { 0x34, 0x03 },
86 { 0x36, 0x8f },
87 { 0x37, 0x80 },
88 { 0x38, 0x83 },
89 { 0x39, 0x80 },
90 { 0x3a, 0x0f },
91 { 0x3b, 0x3c },
92 { 0x3c, 0x1a },
93 { 0x3d, 0x80 },
94 { 0x3e, 0x80 },
95 { 0x3f, 0x0e },
96 { 0x40, 0x00 }, /* White bal */
97 { 0x41, 0x00 }, /* White bal */
98 { 0x42, 0x80 },
99 { 0x43, 0x3f }, /* White bal */
100 { 0x44, 0x80 },
101 { 0x45, 0x20 },
102 { 0x46, 0x20 },
103 { 0x47, 0x80 },
104 { 0x48, 0x7f },
105 { 0x49, 0x00 },
106 { 0x4a, 0x00 },
107 { 0x4b, 0x80 },
108 { 0x4c, 0xd0 },
109 { 0x4d, 0x10 }, /* U = 0.563u, V = 0.714v */
110 { 0x4e, 0x40 },
111 { 0x4f, 0x07 }, /* UV average mode, color killer: strongest */
112 { 0x50, 0xff },
113 { 0x54, 0x23 }, /* Max AGC gain: 18dB */
114 { 0x55, 0xff },
115 { 0x56, 0x12 },
116 { 0x57, 0x81 }, /* (default) */
117 { 0x58, 0x75 },
118 { 0x59, 0x01 }, /* AGC dark current compensation: +1 */
119 { 0x5a, 0x2c },
120 { 0x5b, 0x0f }, /* AWB chrominance levels */
121 { 0x5c, 0x10 },
122 { 0x3d, 0x80 },
123 { 0x27, 0xa6 },
124 /* Toggle AWB off and on */
125 { 0x12, 0x20 },
126 { 0x12, 0x24 },
127
128 { 0xff, 0xff }, /* END MARKER */
129};
130
131/* This initializes the OV6x30 camera chip and relevant variables. */
132static int ov6x30_init(struct i2c_client *c)
133{
134 struct ovcamchip *ov = i2c_get_clientdata(c);
135 struct ov6x30 *s;
136 int rc;
137
138 DDEBUG(4, &c->dev, "entered");
139
140 rc = ov_write_regvals(c, regvals_init_6x30);
141 if (rc < 0)
142 return rc;
143
144 ov->spriv = s = kzalloc(sizeof *s, GFP_KERNEL);
145 if (!s)
146 return -ENOMEM;
147
148 s->auto_brt = 1;
149 s->auto_exp = 1;
150
151 return rc;
152}
153
154static int ov6x30_free(struct i2c_client *c)
155{
156 struct ovcamchip *ov = i2c_get_clientdata(c);
157
158 kfree(ov->spriv);
159 return 0;
160}
161
162static int ov6x30_set_control(struct i2c_client *c,
163 struct ovcamchip_control *ctl)
164{
165 struct ovcamchip *ov = i2c_get_clientdata(c);
166 struct ov6x30 *s = ov->spriv;
167 int rc;
168 int v = ctl->value;
169
170 switch (ctl->id) {
171 case OVCAMCHIP_CID_CONT:
172 rc = ov_write_mask(c, REG_CNT, v >> 12, 0x0f);
173 break;
174 case OVCAMCHIP_CID_BRIGHT:
175 rc = ov_write(c, REG_BRT, v >> 8);
176 break;
177 case OVCAMCHIP_CID_SAT:
178 rc = ov_write(c, REG_SAT, v >> 8);
179 break;
180 case OVCAMCHIP_CID_HUE:
181 rc = ov_write(c, REG_RED, 0xFF - (v >> 8));
182 if (rc < 0)
183 goto out;
184
185 rc = ov_write(c, REG_BLUE, v >> 8);
186 break;
187 case OVCAMCHIP_CID_EXP:
188 rc = ov_write(c, REG_EXP, v);
189 break;
190 case OVCAMCHIP_CID_FREQ:
191 {
192 int sixty = (v == 60);
193
194 rc = ov_write(c, 0x2b, sixty?0xa8:0x28);
195 if (rc < 0)
196 goto out;
197
198 rc = ov_write(c, 0x2a, sixty?0x84:0xa4);
199 break;
200 }
201 case OVCAMCHIP_CID_BANDFILT:
202 rc = ov_write_mask(c, 0x2d, v?0x04:0x00, 0x04);
203 s->bandfilt = v;
204 break;
205 case OVCAMCHIP_CID_AUTOBRIGHT:
206 rc = ov_write_mask(c, 0x2d, v?0x10:0x00, 0x10);
207 s->auto_brt = v;
208 break;
209 case OVCAMCHIP_CID_AUTOEXP:
210 rc = ov_write_mask(c, 0x28, v?0x00:0x10, 0x10);
211 s->auto_exp = v;
212 break;
213 case OVCAMCHIP_CID_BACKLIGHT:
214 {
215 rc = ov_write_mask(c, 0x4e, v?0x80:0x60, 0xe0);
216 if (rc < 0)
217 goto out;
218
219 rc = ov_write_mask(c, 0x29, v?0x08:0x00, 0x08);
220 if (rc < 0)
221 goto out;
222
223 rc = ov_write_mask(c, 0x28, v?0x02:0x00, 0x02);
224 s->backlight = v;
225 break;
226 }
227 case OVCAMCHIP_CID_MIRROR:
228 rc = ov_write_mask(c, 0x12, v?0x40:0x00, 0x40);
229 s->mirror = v;
230 break;
231 default:
232 DDEBUG(2, &c->dev, "control not supported: %d", ctl->id);
233 return -EPERM;
234 }
235
236out:
237 DDEBUG(3, &c->dev, "id=%d, arg=%d, rc=%d", ctl->id, v, rc);
238 return rc;
239}
240
241static int ov6x30_get_control(struct i2c_client *c,
242 struct ovcamchip_control *ctl)
243{
244 struct ovcamchip *ov = i2c_get_clientdata(c);
245 struct ov6x30 *s = ov->spriv;
246 int rc = 0;
247 unsigned char val = 0;
248
249 switch (ctl->id) {
250 case OVCAMCHIP_CID_CONT:
251 rc = ov_read(c, REG_CNT, &val);
252 ctl->value = (val & 0x0f) << 12;
253 break;
254 case OVCAMCHIP_CID_BRIGHT:
255 rc = ov_read(c, REG_BRT, &val);
256 ctl->value = val << 8;
257 break;
258 case OVCAMCHIP_CID_SAT:
259 rc = ov_read(c, REG_SAT, &val);
260 ctl->value = val << 8;
261 break;
262 case OVCAMCHIP_CID_HUE:
263 rc = ov_read(c, REG_BLUE, &val);
264 ctl->value = val << 8;
265 break;
266 case OVCAMCHIP_CID_EXP:
267 rc = ov_read(c, REG_EXP, &val);
268 ctl->value = val;
269 break;
270 case OVCAMCHIP_CID_BANDFILT:
271 ctl->value = s->bandfilt;
272 break;
273 case OVCAMCHIP_CID_AUTOBRIGHT:
274 ctl->value = s->auto_brt;
275 break;
276 case OVCAMCHIP_CID_AUTOEXP:
277 ctl->value = s->auto_exp;
278 break;
279 case OVCAMCHIP_CID_BACKLIGHT:
280 ctl->value = s->backlight;
281 break;
282 case OVCAMCHIP_CID_MIRROR:
283 ctl->value = s->mirror;
284 break;
285 default:
286 DDEBUG(2, &c->dev, "control not supported: %d", ctl->id);
287 return -EPERM;
288 }
289
290 DDEBUG(3, &c->dev, "id=%d, arg=%d, rc=%d", ctl->id, ctl->value, rc);
291 return rc;
292}
293
294static int ov6x30_mode_init(struct i2c_client *c, struct ovcamchip_window *win)
295{
296 /******** QCIF-specific regs ********/
297
298 ov_write_mask(c, 0x14, win->quarter?0x20:0x00, 0x20);
299
300 /******** Palette-specific regs ********/
301
302 if (win->format == VIDEO_PALETTE_GREY) {
303 if (c->adapter->id == I2C_HW_SMBUS_OV518) {
304 /* Do nothing - we're already in 8-bit mode */
305 } else {
306 ov_write_mask(c, 0x13, 0x20, 0x20);
307 }
308 } else {
309 /* The OV518 needs special treatment. Although both the OV518
310 * and the OV6630 support a 16-bit video bus, only the 8 bit Y
311 * bus is actually used. The UV bus is tied to ground.
312 * Therefore, the OV6630 needs to be in 8-bit multiplexed
313 * output mode */
314
315 if (c->adapter->id == I2C_HW_SMBUS_OV518) {
316 /* Do nothing - we want to stay in 8-bit mode */
317 /* Warning: Messing with reg 0x13 breaks OV518 color */
318 } else {
319 ov_write_mask(c, 0x13, 0x00, 0x20);
320 }
321 }
322
323 /******** Clock programming ********/
324
325 ov_write(c, 0x11, win->clockdiv);
326
327 return 0;
328}
329
330static int ov6x30_set_window(struct i2c_client *c, struct ovcamchip_window *win)
331{
332 int ret, hwscale, vwscale;
333
334 ret = ov6x30_mode_init(c, win);
335 if (ret < 0)
336 return ret;
337
338 if (win->quarter) {
339 hwscale = 0;
340 vwscale = 0;
341 } else {
342 hwscale = 1;
343 vwscale = 1; /* The datasheet says 0; it's wrong */
344 }
345
346 ov_write(c, 0x17, HWSBASE + (win->x >> hwscale));
347 ov_write(c, 0x18, HWEBASE + ((win->x + win->width) >> hwscale));
348 ov_write(c, 0x19, VWSBASE + (win->y >> vwscale));
349 ov_write(c, 0x1a, VWEBASE + ((win->y + win->height) >> vwscale));
350
351 return 0;
352}
353
354static int ov6x30_command(struct i2c_client *c, unsigned int cmd, void *arg)
355{
356 switch (cmd) {
357 case OVCAMCHIP_CMD_S_CTRL:
358 return ov6x30_set_control(c, arg);
359 case OVCAMCHIP_CMD_G_CTRL:
360 return ov6x30_get_control(c, arg);
361 case OVCAMCHIP_CMD_S_MODE:
362 return ov6x30_set_window(c, arg);
363 default:
364 DDEBUG(2, &c->dev, "command not supported: %d", cmd);
365 return -ENOIOCTLCMD;
366 }
367}
368
369struct ovcamchip_ops ov6x30_ops = {
370 .init = ov6x30_init,
371 .free = ov6x30_free,
372 .command = ov6x30_command,
373};
diff --git a/drivers/media/video/ovcamchip/ov76be.c b/drivers/media/video/ovcamchip/ov76be.c
deleted file mode 100644
index 11f6be924d8b..000000000000
--- a/drivers/media/video/ovcamchip/ov76be.c
+++ /dev/null
@@ -1,302 +0,0 @@
1/* OmniVision OV76BE Camera Chip Support Code
2 *
3 * Copyright (c) 1999-2004 Mark McClelland <mark@alpha.dyndns.org>
4 * http://alpha.dyndns.org/ov511/
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. NO WARRANTY OF ANY KIND is expressed or implied.
10 */
11
12#define DEBUG
13
14#include <linux/slab.h>
15#include "ovcamchip_priv.h"
16
17/* OV7610 registers: Since the OV76BE is undocumented, we'll settle for these
18 * for now. */
19#define REG_GAIN 0x00 /* gain [5:0] */
20#define REG_BLUE 0x01 /* blue channel balance */
21#define REG_RED 0x02 /* red channel balance */
22#define REG_SAT 0x03 /* saturation */
23#define REG_CNT 0x05 /* Y contrast */
24#define REG_BRT 0x06 /* Y brightness */
25#define REG_BLUE_BIAS 0x0C /* blue channel bias [5:0] */
26#define REG_RED_BIAS 0x0D /* red channel bias [5:0] */
27#define REG_GAMMA_COEFF 0x0E /* gamma settings */
28#define REG_WB_RANGE 0x0F /* AEC/ALC/S-AWB settings */
29#define REG_EXP 0x10 /* manual exposure setting */
30#define REG_CLOCK 0x11 /* polarity/clock prescaler */
31#define REG_FIELD_DIVIDE 0x16 /* field interval/mode settings */
32#define REG_HWIN_START 0x17 /* horizontal window start */
33#define REG_HWIN_END 0x18 /* horizontal window end */
34#define REG_VWIN_START 0x19 /* vertical window start */
35#define REG_VWIN_END 0x1A /* vertical window end */
36#define REG_PIXEL_SHIFT 0x1B /* pixel shift */
37#define REG_YOFFSET 0x21 /* Y channel offset */
38#define REG_UOFFSET 0x22 /* U channel offset */
39#define REG_ECW 0x24 /* exposure white level for AEC */
40#define REG_ECB 0x25 /* exposure black level for AEC */
41#define REG_FRAMERATE_H 0x2A /* frame rate MSB + misc */
42#define REG_FRAMERATE_L 0x2B /* frame rate LSB */
43#define REG_ALC 0x2C /* Auto Level Control settings */
44#define REG_VOFFSET 0x2E /* V channel offset adjustment */
45#define REG_ARRAY_BIAS 0x2F /* array bias -- don't change */
46#define REG_YGAMMA 0x33 /* misc gamma settings [7:6] */
47#define REG_BIAS_ADJUST 0x34 /* misc bias settings */
48
49/* Window parameters */
50#define HWSBASE 0x38
51#define HWEBASE 0x3a
52#define VWSBASE 0x05
53#define VWEBASE 0x05
54
55struct ov76be {
56 int auto_brt;
57 int auto_exp;
58 int bandfilt;
59 int mirror;
60};
61
62/* NOTE: These are the same as the 7x10 settings, but should eventually be
63 * optimized for the OV76BE */
64static struct ovcamchip_regvals regvals_init_76be[] = {
65 { 0x10, 0xff },
66 { 0x16, 0x03 },
67 { 0x28, 0x24 },
68 { 0x2b, 0xac },
69 { 0x12, 0x00 },
70 { 0x38, 0x81 },
71 { 0x28, 0x24 }, /* 0c */
72 { 0x0f, 0x85 }, /* lg's setting */
73 { 0x15, 0x01 },
74 { 0x20, 0x1c },
75 { 0x23, 0x2a },
76 { 0x24, 0x10 },
77 { 0x25, 0x8a },
78 { 0x26, 0xa2 },
79 { 0x27, 0xc2 },
80 { 0x2a, 0x04 },
81 { 0x2c, 0xfe },
82 { 0x2d, 0x93 },
83 { 0x30, 0x71 },
84 { 0x31, 0x60 },
85 { 0x32, 0x26 },
86 { 0x33, 0x20 },
87 { 0x34, 0x48 },
88 { 0x12, 0x24 },
89 { 0x11, 0x01 },
90 { 0x0c, 0x24 },
91 { 0x0d, 0x24 },
92 { 0xff, 0xff }, /* END MARKER */
93};
94
95/* This initializes the OV76be camera chip and relevant variables. */
96static int ov76be_init(struct i2c_client *c)
97{
98 struct ovcamchip *ov = i2c_get_clientdata(c);
99 struct ov76be *s;
100 int rc;
101
102 DDEBUG(4, &c->dev, "entered");
103
104 rc = ov_write_regvals(c, regvals_init_76be);
105 if (rc < 0)
106 return rc;
107
108 ov->spriv = s = kzalloc(sizeof *s, GFP_KERNEL);
109 if (!s)
110 return -ENOMEM;
111
112 s->auto_brt = 1;
113 s->auto_exp = 1;
114
115 return rc;
116}
117
118static int ov76be_free(struct i2c_client *c)
119{
120 struct ovcamchip *ov = i2c_get_clientdata(c);
121
122 kfree(ov->spriv);
123 return 0;
124}
125
126static int ov76be_set_control(struct i2c_client *c,
127 struct ovcamchip_control *ctl)
128{
129 struct ovcamchip *ov = i2c_get_clientdata(c);
130 struct ov76be *s = ov->spriv;
131 int rc;
132 int v = ctl->value;
133
134 switch (ctl->id) {
135 case OVCAMCHIP_CID_BRIGHT:
136 rc = ov_write(c, REG_BRT, v >> 8);
137 break;
138 case OVCAMCHIP_CID_SAT:
139 rc = ov_write(c, REG_SAT, v >> 8);
140 break;
141 case OVCAMCHIP_CID_EXP:
142 rc = ov_write(c, REG_EXP, v);
143 break;
144 case OVCAMCHIP_CID_FREQ:
145 {
146 int sixty = (v == 60);
147
148 rc = ov_write_mask(c, 0x2a, sixty?0x00:0x80, 0x80);
149 if (rc < 0)
150 goto out;
151
152 rc = ov_write(c, 0x2b, sixty?0x00:0xac);
153 if (rc < 0)
154 goto out;
155
156 rc = ov_write_mask(c, 0x76, 0x01, 0x01);
157 break;
158 }
159 case OVCAMCHIP_CID_BANDFILT:
160 rc = ov_write_mask(c, 0x2d, v?0x04:0x00, 0x04);
161 s->bandfilt = v;
162 break;
163 case OVCAMCHIP_CID_AUTOBRIGHT:
164 rc = ov_write_mask(c, 0x2d, v?0x10:0x00, 0x10);
165 s->auto_brt = v;
166 break;
167 case OVCAMCHIP_CID_AUTOEXP:
168 rc = ov_write_mask(c, 0x13, v?0x01:0x00, 0x01);
169 s->auto_exp = v;
170 break;
171 case OVCAMCHIP_CID_MIRROR:
172 rc = ov_write_mask(c, 0x12, v?0x40:0x00, 0x40);
173 s->mirror = v;
174 break;
175 default:
176 DDEBUG(2, &c->dev, "control not supported: %d", ctl->id);
177 return -EPERM;
178 }
179
180out:
181 DDEBUG(3, &c->dev, "id=%d, arg=%d, rc=%d", ctl->id, v, rc);
182 return rc;
183}
184
185static int ov76be_get_control(struct i2c_client *c,
186 struct ovcamchip_control *ctl)
187{
188 struct ovcamchip *ov = i2c_get_clientdata(c);
189 struct ov76be *s = ov->spriv;
190 int rc = 0;
191 unsigned char val = 0;
192
193 switch (ctl->id) {
194 case OVCAMCHIP_CID_BRIGHT:
195 rc = ov_read(c, REG_BRT, &val);
196 ctl->value = val << 8;
197 break;
198 case OVCAMCHIP_CID_SAT:
199 rc = ov_read(c, REG_SAT, &val);
200 ctl->value = val << 8;
201 break;
202 case OVCAMCHIP_CID_EXP:
203 rc = ov_read(c, REG_EXP, &val);
204 ctl->value = val;
205 break;
206 case OVCAMCHIP_CID_BANDFILT:
207 ctl->value = s->bandfilt;
208 break;
209 case OVCAMCHIP_CID_AUTOBRIGHT:
210 ctl->value = s->auto_brt;
211 break;
212 case OVCAMCHIP_CID_AUTOEXP:
213 ctl->value = s->auto_exp;
214 break;
215 case OVCAMCHIP_CID_MIRROR:
216 ctl->value = s->mirror;
217 break;
218 default:
219 DDEBUG(2, &c->dev, "control not supported: %d", ctl->id);
220 return -EPERM;
221 }
222
223 DDEBUG(3, &c->dev, "id=%d, arg=%d, rc=%d", ctl->id, ctl->value, rc);
224 return rc;
225}
226
227static int ov76be_mode_init(struct i2c_client *c, struct ovcamchip_window *win)
228{
229 int qvga = win->quarter;
230
231 /******** QVGA-specific regs ********/
232
233 ov_write(c, 0x14, qvga?0xa4:0x84);
234
235 /******** Palette-specific regs ********/
236
237 if (win->format == VIDEO_PALETTE_GREY) {
238 ov_write_mask(c, 0x0e, 0x40, 0x40);
239 ov_write_mask(c, 0x13, 0x20, 0x20);
240 } else {
241 ov_write_mask(c, 0x0e, 0x00, 0x40);
242 ov_write_mask(c, 0x13, 0x00, 0x20);
243 }
244
245 /******** Clock programming ********/
246
247 ov_write(c, 0x11, win->clockdiv);
248
249 /******** Resolution-specific ********/
250
251 if (win->width == 640 && win->height == 480)
252 ov_write(c, 0x35, 0x9e);
253 else
254 ov_write(c, 0x35, 0x1e);
255
256 return 0;
257}
258
259static int ov76be_set_window(struct i2c_client *c, struct ovcamchip_window *win)
260{
261 int ret, hwscale, vwscale;
262
263 ret = ov76be_mode_init(c, win);
264 if (ret < 0)
265 return ret;
266
267 if (win->quarter) {
268 hwscale = 1;
269 vwscale = 0;
270 } else {
271 hwscale = 2;
272 vwscale = 1;
273 }
274
275 ov_write(c, 0x17, HWSBASE + (win->x >> hwscale));
276 ov_write(c, 0x18, HWEBASE + ((win->x + win->width) >> hwscale));
277 ov_write(c, 0x19, VWSBASE + (win->y >> vwscale));
278 ov_write(c, 0x1a, VWEBASE + ((win->y + win->height) >> vwscale));
279
280 return 0;
281}
282
283static int ov76be_command(struct i2c_client *c, unsigned int cmd, void *arg)
284{
285 switch (cmd) {
286 case OVCAMCHIP_CMD_S_CTRL:
287 return ov76be_set_control(c, arg);
288 case OVCAMCHIP_CMD_G_CTRL:
289 return ov76be_get_control(c, arg);
290 case OVCAMCHIP_CMD_S_MODE:
291 return ov76be_set_window(c, arg);
292 default:
293 DDEBUG(2, &c->dev, "command not supported: %d", cmd);
294 return -ENOIOCTLCMD;
295 }
296}
297
298struct ovcamchip_ops ov76be_ops = {
299 .init = ov76be_init,
300 .free = ov76be_free,
301 .command = ov76be_command,
302};
diff --git a/drivers/media/video/ovcamchip/ov7x10.c b/drivers/media/video/ovcamchip/ov7x10.c
deleted file mode 100644
index 5206e7913924..000000000000
--- a/drivers/media/video/ovcamchip/ov7x10.c
+++ /dev/null
@@ -1,334 +0,0 @@
1/* OmniVision OV7610/OV7110 Camera Chip Support Code
2 *
3 * Copyright (c) 1999-2004 Mark McClelland <mark@alpha.dyndns.org>
4 * http://alpha.dyndns.org/ov511/
5 *
6 * Color fixes by by Orion Sky Lawlor <olawlor@acm.org> (2/26/2000)
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version. NO WARRANTY OF ANY KIND is expressed or implied.
12 */
13
14#define DEBUG
15
16#include <linux/slab.h>
17#include "ovcamchip_priv.h"
18
19/* Registers */
20#define REG_GAIN 0x00 /* gain [5:0] */
21#define REG_BLUE 0x01 /* blue channel balance */
22#define REG_RED 0x02 /* red channel balance */
23#define REG_SAT 0x03 /* saturation */
24#define REG_CNT 0x05 /* Y contrast */
25#define REG_BRT 0x06 /* Y brightness */
26#define REG_BLUE_BIAS 0x0C /* blue channel bias [5:0] */
27#define REG_RED_BIAS 0x0D /* red channel bias [5:0] */
28#define REG_GAMMA_COEFF 0x0E /* gamma settings */
29#define REG_WB_RANGE 0x0F /* AEC/ALC/S-AWB settings */
30#define REG_EXP 0x10 /* manual exposure setting */
31#define REG_CLOCK 0x11 /* polarity/clock prescaler */
32#define REG_FIELD_DIVIDE 0x16 /* field interval/mode settings */
33#define REG_HWIN_START 0x17 /* horizontal window start */
34#define REG_HWIN_END 0x18 /* horizontal window end */
35#define REG_VWIN_START 0x19 /* vertical window start */
36#define REG_VWIN_END 0x1A /* vertical window end */
37#define REG_PIXEL_SHIFT 0x1B /* pixel shift */
38#define REG_YOFFSET 0x21 /* Y channel offset */
39#define REG_UOFFSET 0x22 /* U channel offset */
40#define REG_ECW 0x24 /* exposure white level for AEC */
41#define REG_ECB 0x25 /* exposure black level for AEC */
42#define REG_FRAMERATE_H 0x2A /* frame rate MSB + misc */
43#define REG_FRAMERATE_L 0x2B /* frame rate LSB */
44#define REG_ALC 0x2C /* Auto Level Control settings */
45#define REG_VOFFSET 0x2E /* V channel offset adjustment */
46#define REG_ARRAY_BIAS 0x2F /* array bias -- don't change */
47#define REG_YGAMMA 0x33 /* misc gamma settings [7:6] */
48#define REG_BIAS_ADJUST 0x34 /* misc bias settings */
49
50/* Window parameters */
51#define HWSBASE 0x38
52#define HWEBASE 0x3a
53#define VWSBASE 0x05
54#define VWEBASE 0x05
55
56struct ov7x10 {
57 int auto_brt;
58 int auto_exp;
59 int bandfilt;
60 int mirror;
61};
62
63/* Lawrence Glaister <lg@jfm.bc.ca> reports:
64 *
65 * Register 0x0f in the 7610 has the following effects:
66 *
67 * 0x85 (AEC method 1): Best overall, good contrast range
68 * 0x45 (AEC method 2): Very overexposed
69 * 0xa5 (spec sheet default): Ok, but the black level is
70 * shifted resulting in loss of contrast
71 * 0x05 (old driver setting): very overexposed, too much
72 * contrast
73 */
74static struct ovcamchip_regvals regvals_init_7x10[] = {
75 { 0x10, 0xff },
76 { 0x16, 0x03 },
77 { 0x28, 0x24 },
78 { 0x2b, 0xac },
79 { 0x12, 0x00 },
80 { 0x38, 0x81 },
81 { 0x28, 0x24 }, /* 0c */
82 { 0x0f, 0x85 }, /* lg's setting */
83 { 0x15, 0x01 },
84 { 0x20, 0x1c },
85 { 0x23, 0x2a },
86 { 0x24, 0x10 },
87 { 0x25, 0x8a },
88 { 0x26, 0xa2 },
89 { 0x27, 0xc2 },
90 { 0x2a, 0x04 },
91 { 0x2c, 0xfe },
92 { 0x2d, 0x93 },
93 { 0x30, 0x71 },
94 { 0x31, 0x60 },
95 { 0x32, 0x26 },
96 { 0x33, 0x20 },
97 { 0x34, 0x48 },
98 { 0x12, 0x24 },
99 { 0x11, 0x01 },
100 { 0x0c, 0x24 },
101 { 0x0d, 0x24 },
102 { 0xff, 0xff }, /* END MARKER */
103};
104
105/* This initializes the OV7x10 camera chip and relevant variables. */
106static int ov7x10_init(struct i2c_client *c)
107{
108 struct ovcamchip *ov = i2c_get_clientdata(c);
109 struct ov7x10 *s;
110 int rc;
111
112 DDEBUG(4, &c->dev, "entered");
113
114 rc = ov_write_regvals(c, regvals_init_7x10);
115 if (rc < 0)
116 return rc;
117
118 ov->spriv = s = kzalloc(sizeof *s, GFP_KERNEL);
119 if (!s)
120 return -ENOMEM;
121
122 s->auto_brt = 1;
123 s->auto_exp = 1;
124
125 return rc;
126}
127
128static int ov7x10_free(struct i2c_client *c)
129{
130 struct ovcamchip *ov = i2c_get_clientdata(c);
131
132 kfree(ov->spriv);
133 return 0;
134}
135
136static int ov7x10_set_control(struct i2c_client *c,
137 struct ovcamchip_control *ctl)
138{
139 struct ovcamchip *ov = i2c_get_clientdata(c);
140 struct ov7x10 *s = ov->spriv;
141 int rc;
142 int v = ctl->value;
143
144 switch (ctl->id) {
145 case OVCAMCHIP_CID_CONT:
146 rc = ov_write(c, REG_CNT, v >> 8);
147 break;
148 case OVCAMCHIP_CID_BRIGHT:
149 rc = ov_write(c, REG_BRT, v >> 8);
150 break;
151 case OVCAMCHIP_CID_SAT:
152 rc = ov_write(c, REG_SAT, v >> 8);
153 break;
154 case OVCAMCHIP_CID_HUE:
155 rc = ov_write(c, REG_RED, 0xFF - (v >> 8));
156 if (rc < 0)
157 goto out;
158
159 rc = ov_write(c, REG_BLUE, v >> 8);
160 break;
161 case OVCAMCHIP_CID_EXP:
162 rc = ov_write(c, REG_EXP, v);
163 break;
164 case OVCAMCHIP_CID_FREQ:
165 {
166 int sixty = (v == 60);
167
168 rc = ov_write_mask(c, 0x2a, sixty?0x00:0x80, 0x80);
169 if (rc < 0)
170 goto out;
171
172 rc = ov_write(c, 0x2b, sixty?0x00:0xac);
173 if (rc < 0)
174 goto out;
175
176 rc = ov_write_mask(c, 0x13, 0x10, 0x10);
177 if (rc < 0)
178 goto out;
179
180 rc = ov_write_mask(c, 0x13, 0x00, 0x10);
181 break;
182 }
183 case OVCAMCHIP_CID_BANDFILT:
184 rc = ov_write_mask(c, 0x2d, v?0x04:0x00, 0x04);
185 s->bandfilt = v;
186 break;
187 case OVCAMCHIP_CID_AUTOBRIGHT:
188 rc = ov_write_mask(c, 0x2d, v?0x10:0x00, 0x10);
189 s->auto_brt = v;
190 break;
191 case OVCAMCHIP_CID_AUTOEXP:
192 rc = ov_write_mask(c, 0x29, v?0x00:0x80, 0x80);
193 s->auto_exp = v;
194 break;
195 case OVCAMCHIP_CID_MIRROR:
196 rc = ov_write_mask(c, 0x12, v?0x40:0x00, 0x40);
197 s->mirror = v;
198 break;
199 default:
200 DDEBUG(2, &c->dev, "control not supported: %d", ctl->id);
201 return -EPERM;
202 }
203
204out:
205 DDEBUG(3, &c->dev, "id=%d, arg=%d, rc=%d", ctl->id, v, rc);
206 return rc;
207}
208
209static int ov7x10_get_control(struct i2c_client *c,
210 struct ovcamchip_control *ctl)
211{
212 struct ovcamchip *ov = i2c_get_clientdata(c);
213 struct ov7x10 *s = ov->spriv;
214 int rc = 0;
215 unsigned char val = 0;
216
217 switch (ctl->id) {
218 case OVCAMCHIP_CID_CONT:
219 rc = ov_read(c, REG_CNT, &val);
220 ctl->value = val << 8;
221 break;
222 case OVCAMCHIP_CID_BRIGHT:
223 rc = ov_read(c, REG_BRT, &val);
224 ctl->value = val << 8;
225 break;
226 case OVCAMCHIP_CID_SAT:
227 rc = ov_read(c, REG_SAT, &val);
228 ctl->value = val << 8;
229 break;
230 case OVCAMCHIP_CID_HUE:
231 rc = ov_read(c, REG_BLUE, &val);
232 ctl->value = val << 8;
233 break;
234 case OVCAMCHIP_CID_EXP:
235 rc = ov_read(c, REG_EXP, &val);
236 ctl->value = val;
237 break;
238 case OVCAMCHIP_CID_BANDFILT:
239 ctl->value = s->bandfilt;
240 break;
241 case OVCAMCHIP_CID_AUTOBRIGHT:
242 ctl->value = s->auto_brt;
243 break;
244 case OVCAMCHIP_CID_AUTOEXP:
245 ctl->value = s->auto_exp;
246 break;
247 case OVCAMCHIP_CID_MIRROR:
248 ctl->value = s->mirror;
249 break;
250 default:
251 DDEBUG(2, &c->dev, "control not supported: %d", ctl->id);
252 return -EPERM;
253 }
254
255 DDEBUG(3, &c->dev, "id=%d, arg=%d, rc=%d", ctl->id, ctl->value, rc);
256 return rc;
257}
258
259static int ov7x10_mode_init(struct i2c_client *c, struct ovcamchip_window *win)
260{
261 int qvga = win->quarter;
262
263 /******** QVGA-specific regs ********/
264
265 ov_write(c, 0x14, qvga?0x24:0x04);
266
267 /******** Palette-specific regs ********/
268
269 if (win->format == VIDEO_PALETTE_GREY) {
270 ov_write_mask(c, 0x0e, 0x40, 0x40);
271 ov_write_mask(c, 0x13, 0x20, 0x20);
272 } else {
273 ov_write_mask(c, 0x0e, 0x00, 0x40);
274 ov_write_mask(c, 0x13, 0x00, 0x20);
275 }
276
277 /******** Clock programming ********/
278
279 ov_write(c, 0x11, win->clockdiv);
280
281 /******** Resolution-specific ********/
282
283 if (win->width == 640 && win->height == 480)
284 ov_write(c, 0x35, 0x9e);
285 else
286 ov_write(c, 0x35, 0x1e);
287
288 return 0;
289}
290
291static int ov7x10_set_window(struct i2c_client *c, struct ovcamchip_window *win)
292{
293 int ret, hwscale, vwscale;
294
295 ret = ov7x10_mode_init(c, win);
296 if (ret < 0)
297 return ret;
298
299 if (win->quarter) {
300 hwscale = 1;
301 vwscale = 0;
302 } else {
303 hwscale = 2;
304 vwscale = 1;
305 }
306
307 ov_write(c, 0x17, HWSBASE + (win->x >> hwscale));
308 ov_write(c, 0x18, HWEBASE + ((win->x + win->width) >> hwscale));
309 ov_write(c, 0x19, VWSBASE + (win->y >> vwscale));
310 ov_write(c, 0x1a, VWEBASE + ((win->y + win->height) >> vwscale));
311
312 return 0;
313}
314
315static int ov7x10_command(struct i2c_client *c, unsigned int cmd, void *arg)
316{
317 switch (cmd) {
318 case OVCAMCHIP_CMD_S_CTRL:
319 return ov7x10_set_control(c, arg);
320 case OVCAMCHIP_CMD_G_CTRL:
321 return ov7x10_get_control(c, arg);
322 case OVCAMCHIP_CMD_S_MODE:
323 return ov7x10_set_window(c, arg);
324 default:
325 DDEBUG(2, &c->dev, "command not supported: %d", cmd);
326 return -ENOIOCTLCMD;
327 }
328}
329
330struct ovcamchip_ops ov7x10_ops = {
331 .init = ov7x10_init,
332 .free = ov7x10_free,
333 .command = ov7x10_command,
334};
diff --git a/drivers/media/video/ovcamchip/ov7x20.c b/drivers/media/video/ovcamchip/ov7x20.c
deleted file mode 100644
index 8e26ae338f31..000000000000
--- a/drivers/media/video/ovcamchip/ov7x20.c
+++ /dev/null
@@ -1,454 +0,0 @@
1/* OmniVision OV7620/OV7120 Camera Chip Support Code
2 *
3 * Copyright (c) 1999-2004 Mark McClelland <mark@alpha.dyndns.org>
4 * http://alpha.dyndns.org/ov511/
5 *
6 * OV7620 fixes by Charl P. Botha <cpbotha@ieee.org>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version. NO WARRANTY OF ANY KIND is expressed or implied.
12 */
13
14#define DEBUG
15
16#include <linux/slab.h>
17#include "ovcamchip_priv.h"
18
19/* Registers */
20#define REG_GAIN 0x00 /* gain [5:0] */
21#define REG_BLUE 0x01 /* blue gain */
22#define REG_RED 0x02 /* red gain */
23#define REG_SAT 0x03 /* saturation */
24#define REG_BRT 0x06 /* Y brightness */
25#define REG_SHARP 0x07 /* analog sharpness */
26#define REG_BLUE_BIAS 0x0C /* WB blue ratio [5:0] */
27#define REG_RED_BIAS 0x0D /* WB red ratio [5:0] */
28#define REG_EXP 0x10 /* exposure */
29
30/* Default control settings. Values are in terms of V4L2 controls. */
31#define OV7120_DFL_BRIGHT 0x60
32#define OV7620_DFL_BRIGHT 0x60
33#define OV7120_DFL_SAT 0xb0
34#define OV7620_DFL_SAT 0xc0
35#define DFL_AUTO_EXP 1
36#define DFL_AUTO_GAIN 1
37#define OV7120_DFL_GAIN 0x00
38#define OV7620_DFL_GAIN 0x00
39/* NOTE: Since autoexposure is the default, these aren't programmed into the
40 * OV7x20 chip. They are just here because V4L2 expects a default */
41#define OV7120_DFL_EXP 0x7f
42#define OV7620_DFL_EXP 0x7f
43
44/* Window parameters */
45#define HWSBASE 0x2F /* From 7620.SET (spec is wrong) */
46#define HWEBASE 0x2F
47#define VWSBASE 0x05
48#define VWEBASE 0x05
49
50struct ov7x20 {
51 int auto_brt;
52 int auto_exp;
53 int auto_gain;
54 int backlight;
55 int bandfilt;
56 int mirror;
57};
58
59/* Contrast look-up table */
60static unsigned char ctab[] = {
61 0x01, 0x05, 0x09, 0x11, 0x15, 0x35, 0x37, 0x57,
62 0x5b, 0xa5, 0xa7, 0xc7, 0xc9, 0xcf, 0xef, 0xff
63};
64
65/* Settings for (Black & White) OV7120 camera chip */
66static struct ovcamchip_regvals regvals_init_7120[] = {
67 { 0x12, 0x80 }, /* reset */
68 { 0x13, 0x00 }, /* Autoadjust off */
69 { 0x12, 0x20 }, /* Disable AWB */
70 { 0x13, DFL_AUTO_GAIN?0x01:0x00 }, /* Autoadjust on (if desired) */
71 { 0x00, OV7120_DFL_GAIN },
72 { 0x01, 0x80 },
73 { 0x02, 0x80 },
74 { 0x03, OV7120_DFL_SAT },
75 { 0x06, OV7120_DFL_BRIGHT },
76 { 0x07, 0x00 },
77 { 0x0c, 0x20 },
78 { 0x0d, 0x20 },
79 { 0x11, 0x01 },
80 { 0x14, 0x84 },
81 { 0x15, 0x01 },
82 { 0x16, 0x03 },
83 { 0x17, 0x2f },
84 { 0x18, 0xcf },
85 { 0x19, 0x06 },
86 { 0x1a, 0xf5 },
87 { 0x1b, 0x00 },
88 { 0x20, 0x08 },
89 { 0x21, 0x80 },
90 { 0x22, 0x80 },
91 { 0x23, 0x00 },
92 { 0x26, 0xa0 },
93 { 0x27, 0xfa },
94 { 0x28, 0x20 }, /* DON'T set bit 6. It is for the OV7620 only */
95 { 0x29, DFL_AUTO_EXP?0x00:0x80 },
96 { 0x2a, 0x10 },
97 { 0x2b, 0x00 },
98 { 0x2c, 0x88 },
99 { 0x2d, 0x95 },
100 { 0x2e, 0x80 },
101 { 0x2f, 0x44 },
102 { 0x60, 0x20 },
103 { 0x61, 0x02 },
104 { 0x62, 0x5f },
105 { 0x63, 0xd5 },
106 { 0x64, 0x57 },
107 { 0x65, 0x83 }, /* OV says "don't change this value" */
108 { 0x66, 0x55 },
109 { 0x67, 0x92 },
110 { 0x68, 0xcf },
111 { 0x69, 0x76 },
112 { 0x6a, 0x22 },
113 { 0x6b, 0xe2 },
114 { 0x6c, 0x40 },
115 { 0x6d, 0x48 },
116 { 0x6e, 0x80 },
117 { 0x6f, 0x0d },
118 { 0x70, 0x89 },
119 { 0x71, 0x00 },
120 { 0x72, 0x14 },
121 { 0x73, 0x54 },
122 { 0x74, 0xa0 },
123 { 0x75, 0x8e },
124 { 0x76, 0x00 },
125 { 0x77, 0xff },
126 { 0x78, 0x80 },
127 { 0x79, 0x80 },
128 { 0x7a, 0x80 },
129 { 0x7b, 0xe6 },
130 { 0x7c, 0x00 },
131 { 0x24, 0x3a },
132 { 0x25, 0x60 },
133 { 0xff, 0xff }, /* END MARKER */
134};
135
136/* Settings for (color) OV7620 camera chip */
137static struct ovcamchip_regvals regvals_init_7620[] = {
138 { 0x12, 0x80 }, /* reset */
139 { 0x00, OV7620_DFL_GAIN },
140 { 0x01, 0x80 },
141 { 0x02, 0x80 },
142 { 0x03, OV7620_DFL_SAT },
143 { 0x06, OV7620_DFL_BRIGHT },
144 { 0x07, 0x00 },
145 { 0x0c, 0x24 },
146 { 0x0c, 0x24 },
147 { 0x0d, 0x24 },
148 { 0x11, 0x01 },
149 { 0x12, 0x24 },
150 { 0x13, DFL_AUTO_GAIN?0x01:0x00 },
151 { 0x14, 0x84 },
152 { 0x15, 0x01 },
153 { 0x16, 0x03 },
154 { 0x17, 0x2f },
155 { 0x18, 0xcf },
156 { 0x19, 0x06 },
157 { 0x1a, 0xf5 },
158 { 0x1b, 0x00 },
159 { 0x20, 0x18 },
160 { 0x21, 0x80 },
161 { 0x22, 0x80 },
162 { 0x23, 0x00 },
163 { 0x26, 0xa2 },
164 { 0x27, 0xea },
165 { 0x28, 0x20 },
166 { 0x29, DFL_AUTO_EXP?0x00:0x80 },
167 { 0x2a, 0x10 },
168 { 0x2b, 0x00 },
169 { 0x2c, 0x88 },
170 { 0x2d, 0x91 },
171 { 0x2e, 0x80 },
172 { 0x2f, 0x44 },
173 { 0x60, 0x27 },
174 { 0x61, 0x02 },
175 { 0x62, 0x5f },
176 { 0x63, 0xd5 },
177 { 0x64, 0x57 },
178 { 0x65, 0x83 },
179 { 0x66, 0x55 },
180 { 0x67, 0x92 },
181 { 0x68, 0xcf },
182 { 0x69, 0x76 },
183 { 0x6a, 0x22 },
184 { 0x6b, 0x00 },
185 { 0x6c, 0x02 },
186 { 0x6d, 0x44 },
187 { 0x6e, 0x80 },
188 { 0x6f, 0x1d },
189 { 0x70, 0x8b },
190 { 0x71, 0x00 },
191 { 0x72, 0x14 },
192 { 0x73, 0x54 },
193 { 0x74, 0x00 },
194 { 0x75, 0x8e },
195 { 0x76, 0x00 },
196 { 0x77, 0xff },
197 { 0x78, 0x80 },
198 { 0x79, 0x80 },
199 { 0x7a, 0x80 },
200 { 0x7b, 0xe2 },
201 { 0x7c, 0x00 },
202 { 0xff, 0xff }, /* END MARKER */
203};
204
205/* Returns index into the specified look-up table, with 'n' elements, for which
206 * the value is greater than or equal to "val". If a match isn't found, (n-1)
207 * is returned. The entries in the table must be in ascending order. */
208static inline int ov7x20_lut_find(unsigned char lut[], int n, unsigned char val)
209{
210 int i = 0;
211
212 while (lut[i] < val && i < n)
213 i++;
214
215 return i;
216}
217
218/* This initializes the OV7x20 camera chip and relevant variables. */
219static int ov7x20_init(struct i2c_client *c)
220{
221 struct ovcamchip *ov = i2c_get_clientdata(c);
222 struct ov7x20 *s;
223 int rc;
224
225 DDEBUG(4, &c->dev, "entered");
226
227 if (ov->mono)
228 rc = ov_write_regvals(c, regvals_init_7120);
229 else
230 rc = ov_write_regvals(c, regvals_init_7620);
231
232 if (rc < 0)
233 return rc;
234
235 ov->spriv = s = kzalloc(sizeof *s, GFP_KERNEL);
236 if (!s)
237 return -ENOMEM;
238
239 s->auto_brt = 1;
240 s->auto_exp = DFL_AUTO_EXP;
241 s->auto_gain = DFL_AUTO_GAIN;
242
243 return 0;
244}
245
246static int ov7x20_free(struct i2c_client *c)
247{
248 struct ovcamchip *ov = i2c_get_clientdata(c);
249
250 kfree(ov->spriv);
251 return 0;
252}
253
254static int ov7x20_set_v4l1_control(struct i2c_client *c,
255 struct ovcamchip_control *ctl)
256{
257 struct ovcamchip *ov = i2c_get_clientdata(c);
258 struct ov7x20 *s = ov->spriv;
259 int rc;
260 int v = ctl->value;
261
262 switch (ctl->id) {
263 case OVCAMCHIP_CID_CONT:
264 {
265 /* Use Y gamma control instead. Bit 0 enables it. */
266 rc = ov_write(c, 0x64, ctab[v >> 12]);
267 break;
268 }
269 case OVCAMCHIP_CID_BRIGHT:
270 /* 7620 doesn't like manual changes when in auto mode */
271 if (!s->auto_brt)
272 rc = ov_write(c, REG_BRT, v >> 8);
273 else
274 rc = 0;
275 break;
276 case OVCAMCHIP_CID_SAT:
277 rc = ov_write(c, REG_SAT, v >> 8);
278 break;
279 case OVCAMCHIP_CID_EXP:
280 if (!s->auto_exp)
281 rc = ov_write(c, REG_EXP, v);
282 else
283 rc = -EBUSY;
284 break;
285 case OVCAMCHIP_CID_FREQ:
286 {
287 int sixty = (v == 60);
288
289 rc = ov_write_mask(c, 0x2a, sixty?0x00:0x80, 0x80);
290 if (rc < 0)
291 goto out;
292
293 rc = ov_write(c, 0x2b, sixty?0x00:0xac);
294 if (rc < 0)
295 goto out;
296
297 rc = ov_write_mask(c, 0x76, 0x01, 0x01);
298 break;
299 }
300 case OVCAMCHIP_CID_BANDFILT:
301 rc = ov_write_mask(c, 0x2d, v?0x04:0x00, 0x04);
302 s->bandfilt = v;
303 break;
304 case OVCAMCHIP_CID_AUTOBRIGHT:
305 rc = ov_write_mask(c, 0x2d, v?0x10:0x00, 0x10);
306 s->auto_brt = v;
307 break;
308 case OVCAMCHIP_CID_AUTOEXP:
309 rc = ov_write_mask(c, 0x13, v?0x01:0x00, 0x01);
310 s->auto_exp = v;
311 break;
312 case OVCAMCHIP_CID_BACKLIGHT:
313 {
314 rc = ov_write_mask(c, 0x68, v?0xe0:0xc0, 0xe0);
315 if (rc < 0)
316 goto out;
317
318 rc = ov_write_mask(c, 0x29, v?0x08:0x00, 0x08);
319 if (rc < 0)
320 goto out;
321
322 rc = ov_write_mask(c, 0x28, v?0x02:0x00, 0x02);
323 s->backlight = v;
324 break;
325 }
326 case OVCAMCHIP_CID_MIRROR:
327 rc = ov_write_mask(c, 0x12, v?0x40:0x00, 0x40);
328 s->mirror = v;
329 break;
330 default:
331 DDEBUG(2, &c->dev, "control not supported: %d", ctl->id);
332 return -EPERM;
333 }
334
335out:
336 DDEBUG(3, &c->dev, "id=%d, arg=%d, rc=%d", ctl->id, v, rc);
337 return rc;
338}
339
340static int ov7x20_get_v4l1_control(struct i2c_client *c,
341 struct ovcamchip_control *ctl)
342{
343 struct ovcamchip *ov = i2c_get_clientdata(c);
344 struct ov7x20 *s = ov->spriv;
345 int rc = 0;
346 unsigned char val = 0;
347
348 switch (ctl->id) {
349 case OVCAMCHIP_CID_CONT:
350 rc = ov_read(c, 0x64, &val);
351 ctl->value = ov7x20_lut_find(ctab, 16, val) << 12;
352 break;
353 case OVCAMCHIP_CID_BRIGHT:
354 rc = ov_read(c, REG_BRT, &val);
355 ctl->value = val << 8;
356 break;
357 case OVCAMCHIP_CID_SAT:
358 rc = ov_read(c, REG_SAT, &val);
359 ctl->value = val << 8;
360 break;
361 case OVCAMCHIP_CID_EXP:
362 rc = ov_read(c, REG_EXP, &val);
363 ctl->value = val;
364 break;
365 case OVCAMCHIP_CID_BANDFILT:
366 ctl->value = s->bandfilt;
367 break;
368 case OVCAMCHIP_CID_AUTOBRIGHT:
369 ctl->value = s->auto_brt;
370 break;
371 case OVCAMCHIP_CID_AUTOEXP:
372 ctl->value = s->auto_exp;
373 break;
374 case OVCAMCHIP_CID_BACKLIGHT:
375 ctl->value = s->backlight;
376 break;
377 case OVCAMCHIP_CID_MIRROR:
378 ctl->value = s->mirror;
379 break;
380 default:
381 DDEBUG(2, &c->dev, "control not supported: %d", ctl->id);
382 return -EPERM;
383 }
384
385 DDEBUG(3, &c->dev, "id=%d, arg=%d, rc=%d", ctl->id, ctl->value, rc);
386 return rc;
387}
388
389static int ov7x20_mode_init(struct i2c_client *c, struct ovcamchip_window *win)
390{
391 struct ovcamchip *ov = i2c_get_clientdata(c);
392 int qvga = win->quarter;
393
394 /******** QVGA-specific regs ********/
395 ov_write_mask(c, 0x14, qvga?0x20:0x00, 0x20);
396 ov_write_mask(c, 0x28, qvga?0x00:0x20, 0x20);
397 ov_write(c, 0x24, qvga?0x20:0x3a);
398 ov_write(c, 0x25, qvga?0x30:0x60);
399 ov_write_mask(c, 0x2d, qvga?0x40:0x00, 0x40);
400 if (!ov->mono)
401 ov_write_mask(c, 0x67, qvga?0xf0:0x90, 0xf0);
402 ov_write_mask(c, 0x74, qvga?0x20:0x00, 0x20);
403
404 /******** Clock programming ********/
405
406 ov_write(c, 0x11, win->clockdiv);
407
408 return 0;
409}
410
411static int ov7x20_set_window(struct i2c_client *c, struct ovcamchip_window *win)
412{
413 int ret, hwscale, vwscale;
414
415 ret = ov7x20_mode_init(c, win);
416 if (ret < 0)
417 return ret;
418
419 if (win->quarter) {
420 hwscale = 1;
421 vwscale = 0;
422 } else {
423 hwscale = 2;
424 vwscale = 1;
425 }
426
427 ov_write(c, 0x17, HWSBASE + (win->x >> hwscale));
428 ov_write(c, 0x18, HWEBASE + ((win->x + win->width) >> hwscale));
429 ov_write(c, 0x19, VWSBASE + (win->y >> vwscale));
430 ov_write(c, 0x1a, VWEBASE + ((win->y + win->height) >> vwscale));
431
432 return 0;
433}
434
435static int ov7x20_command(struct i2c_client *c, unsigned int cmd, void *arg)
436{
437 switch (cmd) {
438 case OVCAMCHIP_CMD_S_CTRL:
439 return ov7x20_set_v4l1_control(c, arg);
440 case OVCAMCHIP_CMD_G_CTRL:
441 return ov7x20_get_v4l1_control(c, arg);
442 case OVCAMCHIP_CMD_S_MODE:
443 return ov7x20_set_window(c, arg);
444 default:
445 DDEBUG(2, &c->dev, "command not supported: %d", cmd);
446 return -ENOIOCTLCMD;
447 }
448}
449
450struct ovcamchip_ops ov7x20_ops = {
451 .init = ov7x20_init,
452 .free = ov7x20_free,
453 .command = ov7x20_command,
454};
diff --git a/drivers/media/video/ovcamchip/ovcamchip_core.c b/drivers/media/video/ovcamchip/ovcamchip_core.c
deleted file mode 100644
index d573d8428998..000000000000
--- a/drivers/media/video/ovcamchip/ovcamchip_core.c
+++ /dev/null
@@ -1,395 +0,0 @@
1/* Shared Code for OmniVision Camera Chip Drivers
2 *
3 * Copyright (c) 2004 Mark McClelland <mark@alpha.dyndns.org>
4 * http://alpha.dyndns.org/ov511/
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. NO WARRANTY OF ANY KIND is expressed or implied.
10 */
11
12#define DEBUG
13
14#include <linux/init.h>
15#include <linux/module.h>
16#include <linux/slab.h>
17#include <linux/delay.h>
18#include <linux/i2c.h>
19#include <media/v4l2-device.h>
20#include <media/v4l2-i2c-drv.h>
21#include "ovcamchip_priv.h"
22
23#define DRIVER_VERSION "v2.27 for Linux 2.6"
24#define DRIVER_AUTHOR "Mark McClelland <mark@alpha.dyndns.org>"
25#define DRIVER_DESC "OV camera chip I2C driver"
26
27#define PINFO(fmt, args...) printk(KERN_INFO "ovcamchip: " fmt "\n" , ## args);
28#define PERROR(fmt, args...) printk(KERN_ERR "ovcamchip: " fmt "\n" , ## args);
29
30#ifdef DEBUG
31int ovcamchip_debug = 0;
32static int debug;
33module_param(debug, int, 0);
34MODULE_PARM_DESC(debug,
35 "Debug level: 0=none, 1=inits, 2=warning, 3=config, 4=functions, 5=all");
36#endif
37
38/* By default, let bridge driver tell us if chip is monochrome. mono=0
39 * will ignore that and always treat chips as color. mono=1 will force
40 * monochrome mode for all chips. */
41static int mono = -1;
42module_param(mono, int, 0);
43MODULE_PARM_DESC(mono,
44 "1=chips are monochrome (OVx1xx), 0=force color, -1=autodetect (default)");
45
46MODULE_AUTHOR(DRIVER_AUTHOR);
47MODULE_DESCRIPTION(DRIVER_DESC);
48MODULE_LICENSE("GPL");
49
50
51/* Registers common to all chips, that are needed for detection */
52#define GENERIC_REG_ID_HIGH 0x1C /* manufacturer ID MSB */
53#define GENERIC_REG_ID_LOW 0x1D /* manufacturer ID LSB */
54#define GENERIC_REG_COM_I 0x29 /* misc ID bits */
55
56static char *chip_names[NUM_CC_TYPES] = {
57 [CC_UNKNOWN] = "Unknown chip",
58 [CC_OV76BE] = "OV76BE",
59 [CC_OV7610] = "OV7610",
60 [CC_OV7620] = "OV7620",
61 [CC_OV7620AE] = "OV7620AE",
62 [CC_OV6620] = "OV6620",
63 [CC_OV6630] = "OV6630",
64 [CC_OV6630AE] = "OV6630AE",
65 [CC_OV6630AF] = "OV6630AF",
66};
67
68/* ----------------------------------------------------------------------- */
69
70int ov_write_regvals(struct i2c_client *c, struct ovcamchip_regvals *rvals)
71{
72 int rc;
73
74 while (rvals->reg != 0xff) {
75 rc = ov_write(c, rvals->reg, rvals->val);
76 if (rc < 0)
77 return rc;
78 rvals++;
79 }
80
81 return 0;
82}
83
84/* Writes bits at positions specified by mask to an I2C reg. Bits that are in
85 * the same position as 1's in "mask" are cleared and set to "value". Bits
86 * that are in the same position as 0's in "mask" are preserved, regardless
87 * of their respective state in "value".
88 */
89int ov_write_mask(struct i2c_client *c,
90 unsigned char reg,
91 unsigned char value,
92 unsigned char mask)
93{
94 int rc;
95 unsigned char oldval, newval;
96
97 if (mask == 0xff) {
98 newval = value;
99 } else {
100 rc = ov_read(c, reg, &oldval);
101 if (rc < 0)
102 return rc;
103
104 oldval &= (~mask); /* Clear the masked bits */
105 value &= mask; /* Enforce mask on value */
106 newval = oldval | value; /* Set the desired bits */
107 }
108
109 return ov_write(c, reg, newval);
110}
111
112/* ----------------------------------------------------------------------- */
113
114/* Reset the chip and ensure that I2C is synchronized. Returns <0 if failure.
115 */
116static int init_camchip(struct i2c_client *c)
117{
118 int i, success;
119 unsigned char high, low;
120
121 /* Reset the chip */
122 ov_write(c, 0x12, 0x80);
123
124 /* Wait for it to initialize */
125 msleep(150);
126
127 for (i = 0, success = 0; i < I2C_DETECT_RETRIES && !success; i++) {
128 if (ov_read(c, GENERIC_REG_ID_HIGH, &high) >= 0) {
129 if (ov_read(c, GENERIC_REG_ID_LOW, &low) >= 0) {
130 if (high == 0x7F && low == 0xA2) {
131 success = 1;
132 continue;
133 }
134 }
135 }
136
137 /* Reset the chip */
138 ov_write(c, 0x12, 0x80);
139
140 /* Wait for it to initialize */
141 msleep(150);
142
143 /* Dummy read to sync I2C */
144 ov_read(c, 0x00, &low);
145 }
146
147 if (!success)
148 return -EIO;
149
150 PDEBUG(1, "I2C synced in %d attempt(s)", i);
151
152 return 0;
153}
154
155/* This detects the OV7610, OV7620, or OV76BE chip. */
156static int ov7xx0_detect(struct i2c_client *c)
157{
158 struct ovcamchip *ov = i2c_get_clientdata(c);
159 int rc;
160 unsigned char val;
161
162 PDEBUG(4, "");
163
164 /* Detect chip (sub)type */
165 rc = ov_read(c, GENERIC_REG_COM_I, &val);
166 if (rc < 0) {
167 PERROR("Error detecting ov7xx0 type");
168 return rc;
169 }
170
171 if ((val & 3) == 3) {
172 PINFO("Camera chip is an OV7610");
173 ov->subtype = CC_OV7610;
174 } else if ((val & 3) == 1) {
175 rc = ov_read(c, 0x15, &val);
176 if (rc < 0) {
177 PERROR("Error detecting ov7xx0 type");
178 return rc;
179 }
180
181 if (val & 1) {
182 PINFO("Camera chip is an OV7620AE");
183 /* OV7620 is a close enough match for now. There are
184 * some definite differences though, so this should be
185 * fixed */
186 ov->subtype = CC_OV7620;
187 } else {
188 PINFO("Camera chip is an OV76BE");
189 ov->subtype = CC_OV76BE;
190 }
191 } else if ((val & 3) == 0) {
192 PINFO("Camera chip is an OV7620");
193 ov->subtype = CC_OV7620;
194 } else {
195 PERROR("Unknown camera chip version: %d", val & 3);
196 return -ENOSYS;
197 }
198
199 if (ov->subtype == CC_OV76BE)
200 ov->sops = &ov76be_ops;
201 else if (ov->subtype == CC_OV7620)
202 ov->sops = &ov7x20_ops;
203 else
204 ov->sops = &ov7x10_ops;
205
206 return 0;
207}
208
209/* This detects the OV6620, OV6630, OV6630AE, or OV6630AF chip. */
210static int ov6xx0_detect(struct i2c_client *c)
211{
212 struct ovcamchip *ov = i2c_get_clientdata(c);
213 int rc;
214 unsigned char val;
215
216 PDEBUG(4, "");
217
218 /* Detect chip (sub)type */
219 rc = ov_read(c, GENERIC_REG_COM_I, &val);
220 if (rc < 0) {
221 PERROR("Error detecting ov6xx0 type");
222 return -1;
223 }
224
225 if ((val & 3) == 0) {
226 ov->subtype = CC_OV6630;
227 PINFO("Camera chip is an OV6630");
228 } else if ((val & 3) == 1) {
229 ov->subtype = CC_OV6620;
230 PINFO("Camera chip is an OV6620");
231 } else if ((val & 3) == 2) {
232 ov->subtype = CC_OV6630;
233 PINFO("Camera chip is an OV6630AE");
234 } else if ((val & 3) == 3) {
235 ov->subtype = CC_OV6630;
236 PINFO("Camera chip is an OV6630AF");
237 }
238
239 if (ov->subtype == CC_OV6620)
240 ov->sops = &ov6x20_ops;
241 else
242 ov->sops = &ov6x30_ops;
243
244 return 0;
245}
246
247static int ovcamchip_detect(struct i2c_client *c)
248{
249 /* Ideally we would just try a single register write and see if it NAKs.
250 * That isn't possible since the OV518 can't report I2C transaction
251 * failures. So, we have to try to initialize the chip (i.e. reset it
252 * and check the ID registers) to detect its presence. */
253
254 /* Test for 7xx0 */
255 PDEBUG(3, "Testing for 0V7xx0");
256 if (init_camchip(c) < 0)
257 return -ENODEV;
258 /* 7-bit addresses with bit 0 set are for the OV7xx0 */
259 if (c->addr & 1) {
260 if (ov7xx0_detect(c) < 0) {
261 PERROR("Failed to init OV7xx0");
262 return -EIO;
263 }
264 return 0;
265 }
266 /* Test for 6xx0 */
267 PDEBUG(3, "Testing for 0V6xx0");
268 if (ov6xx0_detect(c) < 0) {
269 PERROR("Failed to init OV6xx0");
270 return -EIO;
271 }
272 return 0;
273}
274
275/* ----------------------------------------------------------------------- */
276
277static long ovcamchip_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
278{
279 struct ovcamchip *ov = to_ovcamchip(sd);
280 struct i2c_client *c = v4l2_get_subdevdata(sd);
281
282 if (!ov->initialized &&
283 cmd != OVCAMCHIP_CMD_Q_SUBTYPE &&
284 cmd != OVCAMCHIP_CMD_INITIALIZE) {
285 v4l2_err(sd, "Camera chip not initialized yet!\n");
286 return -EPERM;
287 }
288
289 switch (cmd) {
290 case OVCAMCHIP_CMD_Q_SUBTYPE:
291 {
292 *(int *)arg = ov->subtype;
293 return 0;
294 }
295 case OVCAMCHIP_CMD_INITIALIZE:
296 {
297 int rc;
298
299 if (mono == -1)
300 ov->mono = *(int *)arg;
301 else
302 ov->mono = mono;
303
304 if (ov->mono) {
305 if (ov->subtype != CC_OV7620)
306 v4l2_warn(sd, "Monochrome not "
307 "implemented for this chip\n");
308 else
309 v4l2_info(sd, "Initializing chip as "
310 "monochrome\n");
311 }
312
313 rc = ov->sops->init(c);
314 if (rc < 0)
315 return rc;
316
317 ov->initialized = 1;
318 return 0;
319 }
320 default:
321 return ov->sops->command(c, cmd, arg);
322 }
323}
324
325/* ----------------------------------------------------------------------- */
326
327static const struct v4l2_subdev_core_ops ovcamchip_core_ops = {
328 .ioctl = ovcamchip_ioctl,
329};
330
331static const struct v4l2_subdev_ops ovcamchip_ops = {
332 .core = &ovcamchip_core_ops,
333};
334
335static int ovcamchip_probe(struct i2c_client *client,
336 const struct i2c_device_id *id)
337{
338 struct ovcamchip *ov;
339 struct v4l2_subdev *sd;
340 int rc = 0;
341
342 ov = kzalloc(sizeof *ov, GFP_KERNEL);
343 if (!ov) {
344 rc = -ENOMEM;
345 goto no_ov;
346 }
347 sd = &ov->sd;
348 v4l2_i2c_subdev_init(sd, client, &ovcamchip_ops);
349
350 rc = ovcamchip_detect(client);
351 if (rc < 0)
352 goto error;
353
354 v4l_info(client, "%s found @ 0x%02x (%s)\n",
355 chip_names[ov->subtype], client->addr << 1, client->adapter->name);
356
357 PDEBUG(1, "Camera chip detection complete");
358
359 return rc;
360error:
361 kfree(ov);
362no_ov:
363 PDEBUG(1, "returning %d", rc);
364 return rc;
365}
366
367static int ovcamchip_remove(struct i2c_client *client)
368{
369 struct v4l2_subdev *sd = i2c_get_clientdata(client);
370 struct ovcamchip *ov = to_ovcamchip(sd);
371 int rc;
372
373 v4l2_device_unregister_subdev(sd);
374 rc = ov->sops->free(client);
375 if (rc < 0)
376 return rc;
377
378 kfree(ov);
379 return 0;
380}
381
382/* ----------------------------------------------------------------------- */
383
384static const struct i2c_device_id ovcamchip_id[] = {
385 { "ovcamchip", 0 },
386 { }
387};
388MODULE_DEVICE_TABLE(i2c, ovcamchip_id);
389
390static struct v4l2_i2c_driver_data v4l2_i2c_data = {
391 .name = "ovcamchip",
392 .probe = ovcamchip_probe,
393 .remove = ovcamchip_remove,
394 .id_table = ovcamchip_id,
395};
diff --git a/drivers/media/video/ovcamchip/ovcamchip_priv.h b/drivers/media/video/ovcamchip/ovcamchip_priv.h
deleted file mode 100644
index 4f07b78c88bc..000000000000
--- a/drivers/media/video/ovcamchip/ovcamchip_priv.h
+++ /dev/null
@@ -1,101 +0,0 @@
1/* OmniVision* camera chip driver private definitions for core code and
2 * chip-specific code
3 *
4 * Copyright (c) 1999-2004 Mark McClelland
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. NO WARRANTY OF ANY KIND is expressed or implied.
10 *
11 * * OmniVision is a trademark of OmniVision Technologies, Inc. This driver
12 * is not sponsored or developed by them.
13 */
14
15#ifndef __LINUX_OVCAMCHIP_PRIV_H
16#define __LINUX_OVCAMCHIP_PRIV_H
17
18#include <linux/i2c.h>
19#include <media/v4l2-subdev.h>
20#include <media/ovcamchip.h>
21
22#ifdef DEBUG
23extern int ovcamchip_debug;
24#endif
25
26#define PDEBUG(level, fmt, args...) \
27 if (ovcamchip_debug >= (level)) pr_debug("[%s:%d] " fmt "\n", \
28 __func__, __LINE__ , ## args)
29
30#define DDEBUG(level, dev, fmt, args...) \
31 if (ovcamchip_debug >= (level)) dev_dbg(dev, "[%s:%d] " fmt "\n", \
32 __func__, __LINE__ , ## args)
33
34/* Number of times to retry chip detection. Increase this if you are getting
35 * "Failed to init camera chip" */
36#define I2C_DETECT_RETRIES 10
37
38struct ovcamchip_regvals {
39 unsigned char reg;
40 unsigned char val;
41};
42
43struct ovcamchip_ops {
44 int (*init)(struct i2c_client *);
45 int (*free)(struct i2c_client *);
46 int (*command)(struct i2c_client *, unsigned int, void *);
47};
48
49struct ovcamchip {
50 struct v4l2_subdev sd;
51 struct ovcamchip_ops *sops;
52 void *spriv; /* Private data for OV7x10.c etc... */
53 int subtype; /* = SEN_OV7610 etc... */
54 int mono; /* Monochrome chip? (invalid until init) */
55 int initialized; /* OVCAMCHIP_CMD_INITIALIZE was successful */
56};
57
58static inline struct ovcamchip *to_ovcamchip(struct v4l2_subdev *sd)
59{
60 return container_of(sd, struct ovcamchip, sd);
61}
62
63extern struct ovcamchip_ops ov6x20_ops;
64extern struct ovcamchip_ops ov6x30_ops;
65extern struct ovcamchip_ops ov7x10_ops;
66extern struct ovcamchip_ops ov7x20_ops;
67extern struct ovcamchip_ops ov76be_ops;
68
69/* --------------------------------- */
70/* I2C I/O */
71/* --------------------------------- */
72
73static inline int ov_read(struct i2c_client *c, unsigned char reg,
74 unsigned char *value)
75{
76 int rc;
77
78 rc = i2c_smbus_read_byte_data(c, reg);
79 *value = (unsigned char) rc;
80 return rc;
81}
82
83static inline int ov_write(struct i2c_client *c, unsigned char reg,
84 unsigned char value )
85{
86 return i2c_smbus_write_byte_data(c, reg, value);
87}
88
89/* --------------------------------- */
90/* FUNCTION PROTOTYPES */
91/* --------------------------------- */
92
93/* Functions in ovcamchip_core.c */
94
95extern int ov_write_regvals(struct i2c_client *c,
96 struct ovcamchip_regvals *rvals);
97
98extern int ov_write_mask(struct i2c_client *c, unsigned char reg,
99 unsigned char value, unsigned char mask);
100
101#endif