]> git.karo-electronics.de Git - mv-sheeva.git/blob - drivers/media/video/ov7670.c
V4L/DVB (4798): OmniVision OV7670 driver
[mv-sheeva.git] / drivers / media / video / ov7670.c
1 /*
2  * A V4L2 driver for OmniVision OV7670 cameras.
3  *
4  * Copyright 2006 One Laptop Per Child Association, Inc.  Written
5  * by Jonathan Corbet with substantial inspiration from Mark
6  * McClelland's ovcamchip code.
7  *
8  * This file may be distributed under the terms of the GNU General
9  * Public License, version 2.
10  */
11 #include <linux/init.h>
12 #include <linux/module.h>
13 #include <linux/moduleparam.h>
14 #include <linux/slab.h>
15 #include <linux/delay.h>
16 #include <linux/videodev.h>
17 #include <media/v4l2-common.h>
18 #include <linux/i2c.h>
19
20
21 MODULE_AUTHOR("Jonathan Corbet <corbet@lwn.net.");
22 MODULE_DESCRIPTION("A low-level driver for OmniVision ov7670 sensors");
23 MODULE_LICENSE("GPL");
24
25 /*
26  * Basic window sizes.  These probably belong somewhere more globally
27  * useful.
28  */
29 #define VGA_WIDTH       640
30 #define VGA_HEIGHT      480
31 #define QVGA_WIDTH      320
32 #define QVGA_HEIGHT     240
33 #define CIF_WIDTH       352
34 #define CIF_HEIGHT      288
35 #define QCIF_WIDTH      176
36 #define QCIF_HEIGHT     144
37
38 /*
39  * The 7670 sits on i2c with ID 0x42
40  */
41 #define OV7670_I2C_ADDR 0x42
42
43 /* Registers */
44 #define REG_GAIN        0x00    /* Gain lower 8 bits (rest in vref) */
45 #define REG_BLUE        0x01    /* blue gain */
46 #define REG_RED         0x02    /* red gain */
47 #define REG_VREF        0x03    /* Pieces of GAIN, VSTART, VSTOP */
48 #define REG_COM1        0x04    /* Control 1 */
49 #define  COM1_CCIR656     0x40  /* CCIR656 enable */
50 #define REG_BAVE        0x05    /* U/B Average level */
51 #define REG_GbAVE       0x06    /* Y/Gb Average level */
52 #define REG_AECHH       0x07    /* AEC MS 5 bits */
53 #define REG_RAVE        0x08    /* V/R Average level */
54 #define REG_COM2        0x09    /* Control 2 */
55 #define  COM2_SSLEEP      0x10  /* Soft sleep mode */
56 #define REG_PID         0x0a    /* Product ID MSB */
57 #define REG_VER         0x0b    /* Product ID LSB */
58 #define REG_COM3        0x0c    /* Control 3 */
59 #define  COM3_SWAP        0x40    /* Byte swap */
60 #define  COM3_SCALEEN     0x08    /* Enable scaling */
61 #define  COM3_DCWEN       0x04    /* Enable downsamp/crop/window */
62 #define REG_COM4        0x0d    /* Control 4 */
63 #define REG_COM5        0x0e    /* All "reserved" */
64 #define REG_COM6        0x0f    /* Control 6 */
65 #define REG_AECH        0x10    /* More bits of AEC value */
66 #define REG_CLKRC       0x11    /* Clocl control */
67 #define   CLK_EXT         0x40    /* Use external clock directly */
68 #define   CLK_SCALE       0x3f    /* Mask for internal clock scale */
69 #define REG_COM7        0x12    /* Control 7 */
70 #define   COM7_RESET      0x80    /* Register reset */
71 #define   COM7_FMT_MASK   0x38
72 #define   COM7_FMT_VGA    0x00
73 #define   COM7_FMT_CIF    0x20    /* CIF format */
74 #define   COM7_FMT_QVGA   0x10    /* QVGA format */
75 #define   COM7_FMT_QCIF   0x08    /* QCIF format */
76 #define   COM7_RGB        0x04    /* bits 0 and 2 - RGB format */
77 #define   COM7_YUV        0x00    /* YUV */
78 #define   COM7_BAYER      0x01    /* Bayer format */
79 #define   COM7_PBAYER     0x05    /* "Processed bayer" */
80 #define REG_COM8        0x13    /* Control 8 */
81 #define   COM8_FASTAEC    0x80    /* Enable fast AGC/AEC */
82 #define   COM8_AECSTEP    0x40    /* Unlimited AEC step size */
83 #define   COM8_BFILT      0x20    /* Band filter enable */
84 #define   COM8_AGC        0x04    /* Auto gain enable */
85 #define   COM8_AWB        0x02    /* White balance enable */
86 #define   COM8_AEC        0x01    /* Auto exposure enable */
87 #define REG_COM9        0x14    /* Control 9  - gain ceiling */
88 #define REG_COM10       0x15    /* Control 10 */
89 #define   COM10_HSYNC     0x40    /* HSYNC instead of HREF */
90 #define   COM10_PCLK_HB   0x20    /* Suppress PCLK on horiz blank */
91 #define   COM10_HREF_REV  0x08    /* Reverse HREF */
92 #define   COM10_VS_LEAD   0x04    /* VSYNC on clock leading edge */
93 #define   COM10_VS_NEG    0x02    /* VSYNC negative */
94 #define   COM10_HS_NEG    0x01    /* HSYNC negative */
95 #define REG_HSTART      0x17    /* Horiz start high bits */
96 #define REG_HSTOP       0x18    /* Horiz stop high bits */
97 #define REG_VSTART      0x19    /* Vert start high bits */
98 #define REG_VSTOP       0x1a    /* Vert stop high bits */
99 #define REG_PSHFT       0x1b    /* Pixel delay after HREF */
100 #define REG_MIDH        0x1c    /* Manuf. ID high */
101 #define REG_MIDL        0x1d    /* Manuf. ID low */
102 #define REG_MVFP        0x1e    /* Mirror / vflip */
103 #define   MVFP_MIRROR     0x20    /* Mirror image */
104 #define   MVFP_FLIP       0x10    /* Vertical flip */
105
106 #define REG_AEW         0x24    /* AGC upper limit */
107 #define REG_AEB         0x25    /* AGC lower limit */
108 #define REG_VPT         0x26    /* AGC/AEC fast mode op region */
109 #define REG_HSYST       0x30    /* HSYNC rising edge delay */
110 #define REG_HSYEN       0x31    /* HSYNC falling edge delay */
111 #define REG_HREF        0x32    /* HREF pieces */
112 #define REG_TSLB        0x3a    /* lots of stuff */
113 #define   TSLB_YLAST      0x04    /* UYVY or VYUY - see com13 */
114 #define REG_COM11       0x3b    /* Control 11 */
115 #define   COM11_NIGHT     0x80    /* NIght mode enable */
116 #define   COM11_NMFR      0x60    /* Two bit NM frame rate */
117 #define   COM11_HZAUTO    0x10    /* Auto detect 50/60 Hz */
118 #define   COM11_50HZ      0x08    /* Manual 50Hz select */
119 #define   COM11_EXP       0x02
120 #define REG_COM12       0x3c    /* Control 12 */
121 #define   COM12_HREF      0x80    /* HREF always */
122 #define REG_COM13       0x3d    /* Control 13 */
123 #define   COM13_GAMMA     0x80    /* Gamma enable */
124 #define   COM13_UVSAT     0x40    /* UV saturation auto adjustment */
125 #define   COM13_UVSWAP    0x01    /* V before U - w/TSLB */
126 #define REG_COM14       0x3e    /* Control 14 */
127 #define   COM14_DCWEN     0x10    /* DCW/PCLK-scale enable */
128 #define REG_EDGE        0x3f    /* Edge enhancement factor */
129 #define REG_COM15       0x40    /* Control 15 */
130 #define   COM15_R10F0     0x00    /* Data range 10 to F0 */
131 #define   COM15_R01FE     0x80    /*            01 to FE */
132 #define   COM15_R00FF     0xc0    /*            00 to FF */
133 #define   COM15_RGB565    0x10    /* RGB565 output */
134 #define   COM15_RGB555    0x30    /* RGB555 output */
135 #define REG_COM16       0x41    /* Control 16 */
136 #define   COM16_AWBGAIN   0x08    /* AWB gain enable */
137 #define REG_COM17       0x42    /* Control 17 */
138 #define   COM17_AECWIN    0xc0    /* AEC window - must match COM4 */
139 #define   COM17_CBAR      0x08    /* DSP Color bar */
140
141 #define REG_BRIGHT      0x55    /* Brightness */
142 #define REG_CONTRAS     0x56    /* Contrast control */
143
144 #define REG_GFIX        0x69    /* Fix gain control */
145
146 #define REG_RGB444      0x8c    /* RGB 444 control */
147 #define   R444_ENABLE     0x02    /* Turn on RGB444, overrides 5x5 */
148 #define   R444_RGBX       0x01    /* Empty nibble at end */
149
150 #define REG_HAECC1      0x9f    /* Hist AEC/AGC control 1 */
151 #define REG_HAECC2      0xa0    /* Hist AEC/AGC control 2 */
152
153 #define REG_BD50MAX     0xa5    /* 50hz banding step limit */
154 #define REG_HAECC3      0xa6    /* Hist AEC/AGC control 3 */
155 #define REG_HAECC4      0xa7    /* Hist AEC/AGC control 4 */
156 #define REG_HAECC5      0xa8    /* Hist AEC/AGC control 5 */
157 #define REG_HAECC6      0xa9    /* Hist AEC/AGC control 6 */
158 #define REG_HAECC7      0xaa    /* Hist AEC/AGC control 7 */
159 #define REG_BD60MAX     0xab    /* 60hz banding step limit */
160
161
162 /*
163  * The default register settings, as obtained from OmniVision.  There
164  * is really no making sense of most of these - lots of "reserved" values
165  * and such.
166  *
167  * These settings give VGA YUYV.
168  */
169
170 struct regval_list {
171         unsigned char reg_num;
172         unsigned char value;
173 };
174
175 static struct regval_list ov7670_default_regs[] = {
176         { REG_COM7, COM7_RESET },
177 /*
178  * Clock scale: 3 = 15fps
179  *              2 = 20fps
180  *              1 = 30fps
181  */
182         { REG_CLKRC, 0x1 },     /* OV: clock scale (15 fps) */
183         { REG_TSLB,  0x04 },    /* OV */
184         { REG_COM7, 0 },        /* VGA */
185         /*
186          * Set the hardware window.  These values from OV don't entirely
187          * make sense - hstop is less than hstart.  But they work...
188          */
189         { REG_HSTART, 0x13 },   { REG_HSTOP, 0x01 },
190         { REG_HREF, 0xb6 },     { REG_VSTART, 0x02 },
191         { REG_VSTOP, 0x7a },    { REG_VREF, 0x0a },
192
193         { REG_COM3, 0 },        { REG_COM14, 0 },
194         /* Mystery scaling numbers */
195         { 0x70, 0x3a },         { 0x71, 0x35 },
196         { 0x72, 0x11 },         { 0x73, 0xf0 },
197         { 0xa2, 0x02 },         { REG_COM10, 0x0 },
198
199         /* Gamma curve values */
200         { 0x7a, 0x20 },         { 0x7b, 0x10 },
201         { 0x7c, 0x1e },         { 0x7d, 0x35 },
202         { 0x7e, 0x5a },         { 0x7f, 0x69 },
203         { 0x80, 0x76 },         { 0x81, 0x80 },
204         { 0x82, 0x88 },         { 0x83, 0x8f },
205         { 0x84, 0x96 },         { 0x85, 0xa3 },
206         { 0x86, 0xaf },         { 0x87, 0xc4 },
207         { 0x88, 0xd7 },         { 0x89, 0xe8 },
208
209         /* AGC and AEC parameters.  Note we start by disabling those features,
210            then turn them only after tweaking the values. */
211         { REG_COM8, COM8_FASTAEC | COM8_AECSTEP | COM8_BFILT },
212         { REG_GAIN, 0 },        { REG_AECH, 0 },
213         { REG_COM4, 0x40 }, /* magic reserved bit */
214         { REG_COM9, 0x18 }, /* 4x gain + magic rsvd bit */
215         { REG_BD50MAX, 0x05 },  { REG_BD60MAX, 0x07 },
216         { REG_AEW, 0x95 },      { REG_AEB, 0x33 },
217         { REG_VPT, 0xe3 },      { REG_HAECC1, 0x78 },
218         { REG_HAECC2, 0x68 },   { 0xa1, 0x03 }, /* magic */
219         { REG_HAECC3, 0xd8 },   { REG_HAECC4, 0xd8 },
220         { REG_HAECC5, 0xf0 },   { REG_HAECC6, 0x90 },
221         { REG_HAECC7, 0x94 },
222         { REG_COM8, COM8_FASTAEC|COM8_AECSTEP|COM8_BFILT|COM8_AGC|COM8_AEC },
223
224         /* Almost all of these are magic "reserved" values.  */
225         { REG_COM5, 0x61 },     { REG_COM6, 0x4b },
226         { 0x16, 0x02 },         { REG_MVFP, 0x07|MVFP_MIRROR },
227         { 0x21, 0x02 },         { 0x22, 0x91 },
228         { 0x29, 0x07 },         { 0x33, 0x0b },
229         { 0x35, 0x0b },         { 0x37, 0x1d },
230         { 0x38, 0x71 },         { 0x39, 0x2a },
231         { REG_COM12, 0x78 },    { 0x4d, 0x40 },
232         { 0x4e, 0x20 },         { REG_GFIX, 0 },
233         { 0x6b, 0x4a },         { 0x74, 0x10 },
234         { 0x8d, 0x4f },         { 0x8e, 0 },
235         { 0x8f, 0 },            { 0x90, 0 },
236         { 0x91, 0 },            { 0x96, 0 },
237         { 0x9a, 0 },            { 0xb0, 0x84 },
238         { 0xb1, 0x0c },         { 0xb2, 0x0e },
239         { 0xb3, 0x82 },         { 0xb8, 0x0a },
240
241         /* More reserved magic, some of which tweaks white balance */
242         { 0x43, 0x0a },         { 0x44, 0xf0 },
243         { 0x45, 0x34 },         { 0x46, 0x58 },
244         { 0x47, 0x28 },         { 0x48, 0x3a },
245         { 0x59, 0x88 },         { 0x5a, 0x88 },
246         { 0x5b, 0x44 },         { 0x5c, 0x67 },
247         { 0x5d, 0x49 },         { 0x5e, 0x0e },
248         { 0x6c, 0x0a },         { 0x6d, 0x55 },
249         { 0x6e, 0x11 },         { 0x6f, 0x9f }, /* "9e for advance AWB" */
250         { 0x6a, 0x40 },         { REG_BLUE, 0x40 },
251         { REG_RED, 0x60 },
252         { REG_COM8, COM8_FASTAEC|COM8_AECSTEP|COM8_BFILT|COM8_AGC|COM8_AEC|COM8_AWB },
253
254         /* Matrix coefficients */
255         { 0x4f, 0x80 },         { 0x50, 0x80 },
256         { 0x51, 0 },            { 0x52, 0x22 },
257         { 0x53, 0x5e },         { 0x54, 0x80 },
258         { 0x58, 0x9e },
259
260         { REG_COM16, COM16_AWBGAIN },   { REG_EDGE, 0 },
261         { 0x75, 0x05 },         { 0x76, 0xe1 },
262         { 0x4c, 0 },            { 0x77, 0x01 },
263         { REG_COM13, 0xc3 },    { 0x4b, 0x09 },
264         { 0xc9, 0x60 },         { REG_COM16, 0x38 },
265         { 0x56, 0x40 },
266
267         { 0x34, 0x11 },         { REG_COM11, COM11_EXP },
268         { 0xa4, 0x88 },         { 0x96, 0 },
269         { 0x97, 0x30 },         { 0x98, 0x20 },
270         { 0x99, 0x30 },         { 0x9a, 0x84 },
271         { 0x9b, 0x29 },         { 0x9c, 0x03 },
272         { 0x9d, 0x4c },         { 0x9e, 0x3f },
273         { 0x78, 0x04 },
274
275         /* Extra-weird stuff.  Some sort of multiplexor register */
276         { 0x79, 0x01 },         { 0xc8, 0xf0 },
277         { 0x79, 0x0f },         { 0xc8, 0x00 },
278         { 0x79, 0x10 },         { 0xc8, 0x7e },
279         { 0x79, 0x0a },         { 0xc8, 0x80 },
280         { 0x79, 0x0b },         { 0xc8, 0x01 },
281         { 0x79, 0x0c },         { 0xc8, 0x0f },
282         { 0x79, 0x0d },         { 0xc8, 0x20 },
283         { 0x79, 0x09 },         { 0xc8, 0x80 },
284         { 0x79, 0x02 },         { 0xc8, 0xc0 },
285         { 0x79, 0x03 },         { 0xc8, 0x40 },
286         { 0x79, 0x05 },         { 0xc8, 0x30 },
287         { 0x79, 0x26 },
288
289         /* Not sure if these should be here */
290         { 0xf1, 0x10 },         { 0x0f, 0x1d },
291         { 0x0f, 0x1f },
292
293         { 0xff, 0xff }, /* END MARKER */
294 };
295
296
297 /*
298  * Here we'll try to encapsulate the changes for just the output
299  * video format.
300  *
301  * RGB656 and YUV422 come from OV; RGB444 is homebrewed.
302  *
303  * IMPORTANT RULE: the first entry must be for COM7, see ov7670_s_fmt for why.
304  */
305
306
307 static struct regval_list ov7670_fmt_yuv422[] = {
308         { REG_COM7, 0x0 },  /* Selects YUV mode */
309         { REG_RGB444, 0 },      /* No RGB444 please */
310         { REG_COM1, 0 },
311         { REG_COM15, COM15_R00FF },
312         { REG_COM9, 0x18 }, /* 4x gain ceiling; 0x8 is reserved bit */
313         { 0x4f, 0x80 },         /* "matrix coefficient 1" */
314         { 0x50, 0x80 },         /* "matrix coefficient 2" */
315         { 0x52, 0x22 },         /* "matrix coefficient 4" */
316         { 0x53, 0x5e },         /* "matrix coefficient 5" */
317         { 0x54, 0x80 },         /* "matrix coefficient 6" */
318         { REG_COM13, COM13_GAMMA|COM13_UVSAT },
319         { 0xff, 0xff },
320 };
321
322 static struct regval_list ov7670_fmt_rgb565[] = {
323         { REG_COM7, COM7_RGB }, /* Selects RGB mode */
324         { REG_RGB444, 0 },      /* No RGB444 please */
325         { REG_COM1, 0x0 },
326         { REG_COM15, COM15_RGB565 },
327         { REG_COM9, 0x38 },     /* 16x gain ceiling; 0x8 is reserved bit */
328         { 0x4f, 0xb3 },         /* "matrix coefficient 1" */
329         { 0x50, 0xb3 },         /* "matrix coefficient 2" */
330         { 0x52, 0x3d },         /* "matrix coefficient 4" */
331         { 0x53, 0xa7 },         /* "matrix coefficient 5" */
332         { 0x54, 0xe4 },         /* "matrix coefficient 6" */
333         { REG_COM13, COM13_GAMMA|COM13_UVSAT },
334         { 0xff, 0xff },
335 };
336
337 static struct regval_list ov7670_fmt_rgb444[] = {
338         { REG_COM7, COM7_RGB }, /* Selects RGB mode */
339         { REG_RGB444, R444_ENABLE },    /* Enable xxxxrrrr ggggbbbb */
340         { REG_COM1, 0x40 },     /* Magic reserved bit */
341         { REG_COM15, COM15_R01FE|COM15_RGB565 }, /* Data range needed? */
342         { REG_COM9, 0x38 },     /* 16x gain ceiling; 0x8 is reserved bit */
343         { 0x4f, 0xb3 },         /* "matrix coefficient 1" */
344         { 0x50, 0xb3 },         /* "matrix coefficient 2" */
345         { 0x52, 0x3d },         /* "matrix coefficient 4" */
346         { 0x53, 0xa7 },         /* "matrix coefficient 5" */
347         { 0x54, 0xe4 },         /* "matrix coefficient 6" */
348         { REG_COM13, COM13_GAMMA|COM13_UVSAT|0x2 },  /* Magic rsvd bit */
349         { 0xff, 0xff },
350 };
351
352
353
354
355 /*
356  * Low-level register I/O.
357  */
358
359 static int ov7670_read(struct i2c_client *c, unsigned char reg,
360                 unsigned char *value)
361 {
362         int ret;
363
364         ret = i2c_smbus_read_byte_data(c, reg);
365         if (ret > 0)
366                 *value = (unsigned char) ret;
367         return ret;
368 }
369
370
371 static int ov7670_write(struct i2c_client *c, unsigned char reg,
372                 unsigned char value)
373 {
374         return i2c_smbus_write_byte_data(c, reg, value);
375 }
376
377
378 /*
379  * Write a list of register settings; ff/ff stops the process.
380  */
381 static int ov7670_write_array(struct i2c_client *c, struct regval_list *vals)
382 {
383         while (vals->reg_num != 0xff || vals->value != 0xff) {
384                 int ret = ov7670_write(c, vals->reg_num, vals->value);
385                 if (ret < 0)
386                         return ret;
387                 vals++;
388         }
389         return 0;
390 }
391
392
393 /*
394  * Stuff that knows about the sensor.
395  */
396 static void ov7670_reset(struct i2c_client *client)
397 {
398         ov7670_write(client, REG_COM7, COM7_RESET);
399         msleep(1);
400 }
401
402
403 static int ov7670_init(struct i2c_client *client)
404 {
405         return ov7670_write_array(client, ov7670_default_regs);
406 }
407
408
409
410 static int ov7670_detect(struct i2c_client *client)
411 {
412         unsigned char v;
413         int ret;
414
415         ret = ov7670_init(client);
416         if (ret < 0)
417                 return ret;
418         ret = ov7670_read(client, REG_MIDH, &v);
419         if (ret < 0)
420                 return ret;
421         if (v != 0x7f) /* OV manuf. id. */
422                 return -ENODEV;
423         ret = ov7670_read(client, REG_MIDL, &v);
424         if (ret < 0)
425                 return ret;
426         if (v != 0xa2)
427                 return -ENODEV;
428         /*
429          * OK, we know we have an OmniVision chip...but which one?
430          */
431         ret = ov7670_read(client, REG_PID, &v);
432         if (ret < 0)
433                 return ret;
434         if (v != 0x76)  /* PID + VER = 0x76 / 0x73 */
435                 return -ENODEV;
436         ret = ov7670_read(client, REG_VER, &v);
437         if (ret < 0)
438                 return ret;
439         if (v != 0x73)  /* PID + VER = 0x76 / 0x73 */
440                 return -ENODEV;
441         return 0;
442 }
443
444
445
446
447
448 static struct ov7670_format_struct {
449         __u8 *desc;
450         __u32 pixelformat;
451         struct regval_list *regs;
452 } ov7670_formats[] = {
453         {
454                 .desc           = "YUYV 4:2:2",
455                 .pixelformat    = V4L2_PIX_FMT_YUYV,
456                 .regs           = ov7670_fmt_yuv422,
457         },
458         {
459                 .desc           = "RGB 444",
460                 .pixelformat    = V4L2_PIX_FMT_RGB444,
461                 .regs           = ov7670_fmt_rgb444,
462         },
463         {
464                 .desc           = "RGB 565",
465                 .pixelformat    = V4L2_PIX_FMT_RGB565,
466                 .regs           = ov7670_fmt_rgb565,
467         },
468         /*
469          * Pretend we do RGB32.  This is here on the assumption that the
470          * upper layer will reformat RGB444 appropriately.
471          *
472          * The entire purpose for this thing's existence is to enable easy
473          * display of RGB444 for debugging purposes.  It will come out soon.
474          */
475         {
476                 .desc           = "RGB32 (faked)",
477                 .pixelformat    = V4L2_PIX_FMT_RGB32,
478                 .regs           = ov7670_fmt_rgb444,
479         },
480 };
481 #define N_OV7670_FMTS (sizeof(ov7670_formats)/sizeof(ov7670_formats[0]))
482
483 /*
484  * All formats we support are 2 bytes/pixel.
485  */
486 #define BYTES_PER_PIXEL 2
487
488 /*
489  * Then there is the issue of window sizes.  Try to capture the info here.
490  */
491 static struct ov7670_win_size {
492         int     width;
493         int     height;
494         unsigned char com7_bit;
495         int     hstart;         /* Start/stop values for the camera.  Note */
496         int     hstop;          /* that they do not always make complete */
497         int     vstart;         /* sense to humans, but evidently the sensor */
498         int     vstop;          /* will do the right thing... */
499 /* h/vref stuff */
500 } ov7670_win_sizes[] = {
501         /* VGA */
502         {
503                 .width          = VGA_WIDTH,
504                 .height         = VGA_HEIGHT,
505                 .com7_bit       = COM7_FMT_VGA,
506                 .hstart         = 158,          /* These values from */
507                 .hstop          =  14,          /* Omnivision */
508                 .vstart         =  10,
509                 .vstop          = 490,
510         },
511         /* CIF */
512         {
513                 .width          = CIF_WIDTH,
514                 .height         = CIF_HEIGHT,
515                 .com7_bit       = COM7_FMT_CIF,
516                 .hstart         = 170,          /* Empirically determined */
517                 .hstop          =  90,
518                 .vstart         =  14,
519                 .vstop          = 494,
520         },
521         /* QVGA */
522         {
523                 .width          = QVGA_WIDTH,
524                 .height         = QVGA_HEIGHT,
525                 .com7_bit       = COM7_FMT_QVGA,
526                 .hstart         = 164,          /* Empirically determined */
527                 .hstop          =  20,
528                 .vstart         =  14,
529                 .vstop          = 494,
530         },
531 };
532
533 #define N_WIN_SIZES (sizeof(ov7670_win_sizes)/sizeof(ov7670_win_sizes[0]))
534
535
536 /*
537  * Store a set of start/stop values into the camera.
538  */
539 static int ov7670_set_hw(struct i2c_client *client, int hstart, int hstop,
540                 int vstart, int vstop)
541 {
542         int ret;
543         unsigned char v;
544 /*
545  * Horizontal: 11 bits, top 8 live in hstart and hstop.  Bottom 3 of
546  * hstart are in href[2:0], bottom 3 of hstop in href[5:3].  There is
547  * a mystery "edge offset" value in the top two bits of href.
548  */
549         ret =  ov7670_write(client, REG_HSTART, (hstart >> 3) & 0xff);
550         ret += ov7670_write(client, REG_HSTOP, (hstop >> 3) & 0xff);
551         ret += ov7670_read(client, REG_HREF, &v);
552         v = (v & 0xc0) | ((hstop & 0x7) << 3) | (hstart & 0x7);
553         msleep(10);
554         ret += ov7670_write(client, REG_HREF, v);
555 /*
556  * Vertical: similar arrangement, but only 10 bits.
557  */
558         ret += ov7670_write(client, REG_VSTART, (vstart >> 2) & 0xff);
559         ret += ov7670_write(client, REG_VSTOP, (vstop >> 2) & 0xff);
560         ret += ov7670_read(client, REG_VREF, &v);
561         v = (v & 0xf0) | ((vstop & 0x3) << 2) | (vstart & 0x3);
562         msleep(10);
563         ret += ov7670_write(client, REG_VREF, v);
564         return ret;
565 }
566
567
568 static int ov7670_enum_fmt(struct i2c_client *c, struct v4l2_fmtdesc *fmt)
569 {
570         struct ov7670_format_struct *ofmt;
571
572         if (fmt->index >= N_OV7670_FMTS)
573                 return -EINVAL;
574
575         ofmt = ov7670_formats + fmt->index;
576         fmt->flags = 0;
577         strcpy(fmt->description, ofmt->desc);
578         fmt->pixelformat = ofmt->pixelformat;
579         return 0;
580 }
581
582
583 static int ov7670_try_fmt(struct i2c_client *c, struct v4l2_format *fmt,
584                 struct ov7670_format_struct **ret_fmt,
585                 struct ov7670_win_size **ret_wsize)
586 {
587         int index;
588         struct ov7670_win_size *wsize;
589         struct v4l2_pix_format *pix = &fmt->fmt.pix;
590
591         for (index = 0; index < N_OV7670_FMTS; index++)
592                 if (ov7670_formats[index].pixelformat == pix->pixelformat)
593                         break;
594         if (index >= N_OV7670_FMTS)
595                 return -EINVAL;
596         if (ret_fmt != NULL)
597                 *ret_fmt = ov7670_formats + index;
598         /*
599          * Fields: the OV devices claim to be progressive.
600          */
601         if (pix->field == V4L2_FIELD_ANY)
602                 pix->field = V4L2_FIELD_NONE;
603         else if (pix->field != V4L2_FIELD_NONE)
604                 return -EINVAL;
605         /*
606          * Round requested image size down to the nearest
607          * we support, but not below the smallest.
608          */
609         for (wsize = ov7670_win_sizes; wsize < ov7670_win_sizes + N_WIN_SIZES;
610              wsize++)
611                 if (pix->width >= wsize->width && pix->height >= wsize->height)
612                         break;
613         if (wsize > ov7670_win_sizes + N_WIN_SIZES)
614                 wsize--;   /* Take the smallest one */
615         if (ret_wsize != NULL)
616                 *ret_wsize = wsize;
617         /*
618          * Note the size we'll actually handle.
619          */
620         pix->width = wsize->width;
621         pix->height = wsize->height;
622         pix->bytesperline = pix->width*BYTES_PER_PIXEL;
623         if (pix->pixelformat == V4L2_PIX_FMT_RGB32)
624                 pix->bytesperline *= 2;
625         pix->sizeimage = pix->height*pix->bytesperline;
626         return 0;
627
628 }
629
630 /*
631  * Set a format.
632  */
633 static int ov7670_s_fmt(struct i2c_client *c, struct v4l2_format *fmt)
634 {
635         int ret;
636         struct ov7670_format_struct *ovfmt;
637         struct ov7670_win_size *wsize;
638         unsigned char com7;
639
640         ret = ov7670_try_fmt(c, fmt, &ovfmt, &wsize);
641         if (ret)
642                 return ret;
643         /*
644          * COM7 is a pain in the ass, it doesn't like to be read then
645          * quickly written afterward.  But we have everything we need
646          * to set it absolutely here, as long as the format-specific
647          * register sets list it first.
648          */
649         com7 = ovfmt->regs[0].value;
650         com7 |= wsize->com7_bit;
651         ov7670_write(c, REG_COM7, com7);
652         /*
653          * Now write the rest of the array.  Also store start/stops
654          */
655         ov7670_write_array(c, ovfmt->regs + 1);
656         ov7670_set_hw(c, wsize->hstart, wsize->hstop, wsize->vstart,
657                         wsize->vstop);
658         return 0;
659 }
660
661 /*
662  * Code for dealing with controls.
663  */
664
665 /*
666  * Some weird registers seem to store values in a sign/magnitude format!
667  */
668 static unsigned char ov7670_sm_to_abs(unsigned char v)
669 {
670         if ((v & 0x80) == 0)
671                 return v + 128;
672         else
673                 return 128 - (v & 0x7f);
674 }
675
676
677 static unsigned char ov7670_abs_to_sm(unsigned char v)
678 {
679         if (v > 127)
680                 return v & 0x7f;
681         else
682                 return (128 - v) | 0x80;
683 }
684
685 static int ov7670_t_brightness(struct i2c_client *client, unsigned char value)
686 {
687         unsigned char com8;
688         int ret;
689
690         ov7670_read(client, REG_COM8, &com8);
691         com8 &= ~COM8_AEC;
692         ov7670_write(client, REG_COM8, com8);
693         value = ov7670_abs_to_sm(value);
694         ret = ov7670_write(client, REG_BRIGHT, value);
695         return ret;
696 }
697
698 static int ov7670_q_brightness(struct i2c_client *client, unsigned char *value)
699 {
700         int ret;
701         ret = ov7670_read(client, REG_BRIGHT, value);
702         *value = ov7670_sm_to_abs(*value);
703         return ret;
704 }
705
706 static int ov7670_t_contrast(struct i2c_client *client, unsigned char value)
707 {
708         return ov7670_write(client, REG_CONTRAS, value);
709 }
710
711 static int ov7670_q_contrast(struct i2c_client *client, unsigned char *value)
712 {
713         return ov7670_read(client, REG_CONTRAS, value);
714 }
715
716 static int ov7670_q_hflip(struct i2c_client *client, unsigned char *value)
717 {
718         int ret;
719         unsigned char v;
720
721         ret = ov7670_read(client, REG_MVFP, &v);
722         *value = (v & MVFP_MIRROR) == MVFP_MIRROR;
723         return ret;
724 }
725
726
727 static int ov7670_t_hflip(struct i2c_client *client, unsigned char value)
728 {
729         unsigned char v;
730         int ret;
731
732         ret = ov7670_read(client, REG_MVFP, &v);
733         if (value)
734                 v |= MVFP_MIRROR;
735         else
736                 v &= ~MVFP_MIRROR;
737         msleep(10);  /* FIXME */
738         ret += ov7670_write(client, REG_MVFP, v);
739         return ret;
740 }
741
742
743
744 static int ov7670_q_vflip(struct i2c_client *client, unsigned char *value)
745 {
746         int ret;
747         unsigned char v;
748
749         ret = ov7670_read(client, REG_MVFP, &v);
750         *value = (v & MVFP_FLIP) == MVFP_FLIP;
751         return ret;
752 }
753
754
755 static int ov7670_t_vflip(struct i2c_client *client, unsigned char value)
756 {
757         unsigned char v;
758         int ret;
759
760         ret = ov7670_read(client, REG_MVFP, &v);
761         if (value)
762                 v |= MVFP_FLIP;
763         else
764                 v &= ~MVFP_FLIP;
765         msleep(10);  /* FIXME */
766         ret += ov7670_write(client, REG_MVFP, v);
767         return ret;
768 }
769
770
771 static struct ov7670_control {
772         struct v4l2_queryctrl qc;
773         int (*query)(struct i2c_client *c, unsigned char *value);
774         int (*tweak)(struct i2c_client *c, unsigned char value);
775 } ov7670_controls[] =
776 {
777         {
778                 .qc = {
779                         .id = V4L2_CID_BRIGHTNESS,
780                         .type = V4L2_CTRL_TYPE_INTEGER,
781                         .name = "Brightness",
782                         .minimum = 0,
783                         .maximum = 255,
784                         .step = 1,
785                         .default_value = 0x80,
786                         .flags = V4L2_CTRL_FLAG_SLIDER
787                 },
788                 .tweak = ov7670_t_brightness,
789                 .query = ov7670_q_brightness,
790         },
791         {
792                 .qc = {
793                         .id = V4L2_CID_CONTRAST,
794                         .type = V4L2_CTRL_TYPE_INTEGER,
795                         .name = "Contrast",
796                         .minimum = 0,
797                         .maximum = 127,
798                         .step = 1,
799                         .default_value = 0x40,   /* XXX ov7670 spec */
800                         .flags = V4L2_CTRL_FLAG_SLIDER
801                 },
802                 .tweak = ov7670_t_contrast,
803                 .query = ov7670_q_contrast,
804         },
805         {
806                 .qc = {
807                         .id = V4L2_CID_VFLIP,
808                         .type = V4L2_CTRL_TYPE_BOOLEAN,
809                         .name = "Vertical flip",
810                         .minimum = 0,
811                         .maximum = 1,
812                         .step = 1,
813                         .default_value = 0,
814                 },
815                 .tweak = ov7670_t_vflip,
816                 .query = ov7670_q_vflip,
817         },
818         {
819                 .qc = {
820                         .id = V4L2_CID_HFLIP,
821                         .type = V4L2_CTRL_TYPE_BOOLEAN,
822                         .name = "Horizontal mirror",
823                         .minimum = 0,
824                         .maximum = 1,
825                         .step = 1,
826                         .default_value = 0,
827                 },
828                 .tweak = ov7670_t_hflip,
829                 .query = ov7670_q_hflip,
830         },
831 };
832 #define N_CONTROLS (sizeof(ov7670_controls)/sizeof(ov7670_controls[0]))
833
834 static struct ov7670_control *ov7670_find_control(__u32 id)
835 {
836         int i;
837
838         for (i = 0; i < N_CONTROLS; i++)
839                 if (ov7670_controls[i].qc.id == id)
840                         return ov7670_controls + i;
841         return NULL;
842 }
843
844
845 static int ov7670_queryctrl(struct i2c_client *client,
846                 struct v4l2_queryctrl *qc)
847 {
848         struct ov7670_control *ctrl = ov7670_find_control(qc->id);
849
850         if (ctrl == NULL)
851                 return -EINVAL;
852         *qc = ctrl->qc;
853         return 0;
854 }
855
856 static int ov7670_g_ctrl(struct i2c_client *client, struct v4l2_control *ctrl)
857 {
858         struct ov7670_control *octrl = ov7670_find_control(ctrl->id);
859         int ret;
860         unsigned char v;
861
862         if (octrl == NULL)
863                 return -EINVAL;
864         ret = octrl->query(client, &v);
865         if (ret >= 0) {
866                 ctrl->value = v;
867                 return 0;
868         }
869         return ret;
870 }
871
872 static int ov7670_s_ctrl(struct i2c_client *client, struct v4l2_control *ctrl)
873 {
874         struct ov7670_control *octrl = ov7670_find_control(ctrl->id);
875
876         if (octrl == NULL)
877                 return -EINVAL;
878         return octrl->tweak(client, ctrl->value);
879 }
880
881
882
883
884
885
886
887 /*
888  * Basic i2c stuff.
889  */
890 static struct i2c_driver ov7670_driver;
891
892 static int ov7670_attach(struct i2c_adapter *adapter)
893 {
894         int ret;
895         struct i2c_client *client;
896
897         printk(KERN_ERR "ov7670 attach, id = %d\n", adapter->id);
898         /*
899          * For now: only deal with adapters we recognize.
900          */
901         if (adapter->id != I2C_HW_SMBUS_CAFE)
902                 return -ENODEV;
903
904         printk(KERN_ERR "ov7670 accepting\n");
905         client = kzalloc(sizeof (struct i2c_client), GFP_KERNEL);
906         if (! client)
907                 return -ENOMEM;
908         client->adapter = adapter;
909         client->addr = OV7670_I2C_ADDR;
910         client->driver = &ov7670_driver,
911         strcpy(client->name, "OV7670");
912         /* Do we need clientdata? */
913
914         /*
915          * Make sure it's an ov7670
916          */
917         ret = ov7670_detect(client);
918         printk(KERN_ERR "detect result is %d\n", ret);
919         if (ret)
920                 goto out_free;
921         i2c_attach_client(client);
922         return 0;
923
924   out_free:
925         kfree(client);
926         return ret;
927 }
928
929
930 static int ov7670_detach(struct i2c_client *client)
931 {
932         i2c_detach_client(client);
933         kfree(client);
934         return 0;
935 }
936
937
938 static int ov7670_command(struct i2c_client *client, unsigned int cmd,
939                 void *arg)
940 {
941         switch (cmd) {
942         case VIDIOC_INT_G_CHIP_IDENT:
943                 * (enum v4l2_chip_ident *) arg = V4L2_IDENT_OV7670;
944                 return 0;
945
946         case VIDIOC_INT_RESET:
947                 ov7670_reset(client);
948                 return 0;
949
950         case VIDIOC_INT_INIT:
951                 return ov7670_init(client);
952
953         case VIDIOC_ENUM_FMT:
954                 return ov7670_enum_fmt(client, (struct v4l2_fmtdesc *) arg);
955         case VIDIOC_TRY_FMT:
956                 return ov7670_try_fmt(client, (struct v4l2_format *) arg, NULL, NULL);
957         case VIDIOC_S_FMT:
958                 return ov7670_s_fmt(client, (struct v4l2_format *) arg);
959         case VIDIOC_QUERYCTRL:
960                 return ov7670_queryctrl(client, (struct v4l2_queryctrl *) arg);
961         case VIDIOC_S_CTRL:
962                 return ov7670_s_ctrl(client, (struct v4l2_control *) arg);
963         case VIDIOC_G_CTRL:
964                 return ov7670_g_ctrl(client, (struct v4l2_control *) arg);
965         /* Todo:
966            g/s_parm
967            initialization
968         */
969         }
970         return -EINVAL;
971 }
972
973
974
975 static struct i2c_driver ov7670_driver = {
976         .driver = {
977                 .name = "ov7670",
978         },
979         .id             = I2C_DRIVERID_OV7670,
980         .class          = I2C_CLASS_CAM_DIGITAL,
981         .attach_adapter = ov7670_attach,
982         .detach_client  = ov7670_detach,
983         .command        = ov7670_command,
984 };
985
986
987 /*
988  * Module initialization
989  */
990 static int __init ov7670_mod_init(void)
991 {
992         printk(KERN_NOTICE "OmniVision ov7670 sensor driver, at your service\n");
993         return i2c_add_driver(&ov7670_driver);
994 }
995
996 static void __exit ov7670_mod_exit(void)
997 {
998         i2c_del_driver(&ov7670_driver);
999 }
1000
1001 module_init(ov7670_mod_init);
1002 module_exit(ov7670_mod_exit);