blob: cc39d76e5221daed055e5c468dc7fafae667d41f [file] [log] [blame]
Erik Andrenc109f812008-10-01 04:51:53 -03001/*
2 * Driver for the ov9650 sensor
3 *
Erik Andren0c505e682008-10-16 16:43:16 -03004 * Copyright (C) 2008 Erik Andrén
Erik Andrenc109f812008-10-01 04:51:53 -03005 * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
6 * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
7 *
8 * Portions of code to USB interface and ALi driver software,
9 * Copyright (c) 2006 Willem Duinker
10 * v4l2 interface modeled after the V4L2 driver
11 * for SN9C10x PC Camera Controllers
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License as
15 * published by the Free Software Foundation, version 2.
16 *
17 */
18
19#ifndef M5602_OV9650_H_
20#define M5602_OV9650_H_
21
22#include <linux/dmi.h>
Erik Andrenc109f812008-10-01 04:51:53 -030023#include "m5602_sensor.h"
24
25/*****************************************************************************/
26
27#define OV9650_GAIN 0x00
28#define OV9650_BLUE 0x01
29#define OV9650_RED 0x02
30#define OV9650_VREF 0x03
31#define OV9650_COM1 0x04
32#define OV9650_BAVE 0x05
33#define OV9650_GEAVE 0x06
34#define OV9650_RSVD7 0x07
Erik Andr?n3d3ec922008-12-29 12:49:25 -030035#define OV9650_COM2 0x09
Erik Andrenc109f812008-10-01 04:51:53 -030036#define OV9650_PID 0x0a
37#define OV9650_VER 0x0b
38#define OV9650_COM3 0x0c
Erik Andrén1f614f42008-12-23 17:15:19 -030039#define OV9650_COM4 0x0d
Erik Andrenc109f812008-10-01 04:51:53 -030040#define OV9650_COM5 0x0e
41#define OV9650_COM6 0x0f
42#define OV9650_AECH 0x10
43#define OV9650_CLKRC 0x11
44#define OV9650_COM7 0x12
45#define OV9650_COM8 0x13
46#define OV9650_COM9 0x14
47#define OV9650_COM10 0x15
48#define OV9650_RSVD16 0x16
49#define OV9650_HSTART 0x17
50#define OV9650_HSTOP 0x18
51#define OV9650_VSTRT 0x19
52#define OV9650_VSTOP 0x1a
53#define OV9650_PSHFT 0x1b
54#define OV9650_MVFP 0x1e
55#define OV9650_AEW 0x24
56#define OV9650_AEB 0x25
57#define OV9650_VPT 0x26
58#define OV9650_BBIAS 0x27
59#define OV9650_GbBIAS 0x28
60#define OV9650_Gr_COM 0x29
61#define OV9650_RBIAS 0x2c
62#define OV9650_HREF 0x32
63#define OV9650_CHLF 0x33
64#define OV9650_ARBLM 0x34
65#define OV9650_RSVD35 0x35
66#define OV9650_RSVD36 0x36
67#define OV9650_ADC 0x37
68#define OV9650_ACOM38 0x38
69#define OV9650_OFON 0x39
70#define OV9650_TSLB 0x3a
71#define OV9650_COM12 0x3c
72#define OV9650_COM13 0x3d
73#define OV9650_COM15 0x40
74#define OV9650_COM16 0x41
75#define OV9650_LCC1 0x62
76#define OV9650_LCC2 0x63
77#define OV9650_LCC3 0x64
78#define OV9650_LCC4 0x65
79#define OV9650_LCC5 0x66
80#define OV9650_HV 0x69
81#define OV9650_DBLV 0x6b
82#define OV9650_COM21 0x8b
83#define OV9650_COM22 0x8c
84#define OV9650_COM24 0x8e
85#define OV9650_DBLC1 0x8f
86#define OV9650_RSVD94 0x94
87#define OV9650_RSVD95 0x95
88#define OV9650_RSVD96 0x96
89#define OV9650_LCCFB 0x9d
90#define OV9650_LCCFR 0x9e
91#define OV9650_AECHM 0xa1
92#define OV9650_COM26 0xa5
93#define OV9650_ACOMA8 0xa8
94#define OV9650_ACOMA9 0xa9
95
96#define OV9650_REGISTER_RESET (1 << 7)
97#define OV9650_VGA_SELECT (1 << 6)
Erik Andrén03f46de2008-12-23 17:07:58 -030098#define OV9650_CIF_SELECT (1 << 5)
Erik Andrén3b2f3322008-12-22 16:06:29 -030099#define OV9650_QVGA_SELECT (1 << 4)
Erik Andr?ne31f9dd2008-12-27 13:30:10 -0300100#define OV9650_QCIF_SELECT (1 << 3)
Erik Andrenc109f812008-10-01 04:51:53 -0300101#define OV9650_RGB_SELECT (1 << 2)
102#define OV9650_RAW_RGB_SELECT (1 << 0)
103
104#define OV9650_FAST_AGC_AEC (1 << 7)
105#define OV9650_AEC_UNLIM_STEP_SIZE (1 << 6)
106#define OV9650_BANDING (1 << 5)
107#define OV9650_AGC_EN (1 << 2)
108#define OV9650_AWB_EN (1 << 1)
109#define OV9650_AEC_EN (1 << 0)
110
111#define OV9650_VARIOPIXEL (1 << 2)
112#define OV9650_SYSTEM_CLK_SEL (1 << 7)
113#define OV9650_SLAM_MODE (1 << 4)
114
Erik Andrén1f614f42008-12-23 17:15:19 -0300115#define OV9650_QVGA_VARIOPIXEL (1 << 7)
116
Erik Andrenc109f812008-10-01 04:51:53 -0300117#define OV9650_VFLIP (1 << 4)
118#define OV9650_HFLIP (1 << 5)
119
Erik Andr?n3d3ec922008-12-29 12:49:25 -0300120#define OV9650_SOFT_SLEEP (1 << 4)
121#define OV9650_OUTPUT_DRIVE_2X (1 << 0)
122
Erik Andr?nbd99ffb2009-01-03 10:55:52 -0300123#define OV9650_LEFT_OFFSET 0x62
124
Erik Andrenc109f812008-10-01 04:51:53 -0300125#define GAIN_DEFAULT 0x14
126#define RED_GAIN_DEFAULT 0x70
127#define BLUE_GAIN_DEFAULT 0x20
Erik Andr?n7136e702008-12-31 07:25:42 -0300128#define EXPOSURE_DEFAULT 0x1ff
Erik Andrenc109f812008-10-01 04:51:53 -0300129
130/*****************************************************************************/
131
132/* Kernel module parameters */
133extern int force_sensor;
134extern int dump_sensor;
Erik Andrenc109f812008-10-01 04:51:53 -0300135
136int ov9650_probe(struct sd *sd);
137int ov9650_init(struct sd *sd);
Erik Andrén082aa892008-12-21 18:07:59 -0300138int ov9650_start(struct sd *sd);
Erik Andr?n3d3ec922008-12-29 12:49:25 -0300139int ov9650_stop(struct sd *sd);
Erik Andrenc109f812008-10-01 04:51:53 -0300140int ov9650_power_down(struct sd *sd);
141
Erik Andrenc109f812008-10-01 04:51:53 -0300142int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
143int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
144int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
145int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val);
146int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val);
147int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val);
148int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val);
149int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val);
150int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
151int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
152int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
153int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
154int ov9650_get_brightness(struct gspca_dev *gspca_dev, __s32 *val);
155int ov9650_set_brightness(struct gspca_dev *gspca_dev, __s32 val);
156int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev, __s32 *val);
157int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, __s32 val);
158int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val);
159int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val);
160
Erik Andr?ndac136e2008-12-30 17:35:34 -0300161const static struct m5602_sensor ov9650 = {
Erik Andr?ne4cc4fc2008-12-30 15:27:17 -0300162 .name = "OV9650",
163 .i2c_slave_id = 0x60,
164 .i2c_regW = 1,
165 .probe = ov9650_probe,
166 .init = ov9650_init,
167 .start = ov9650_start,
168 .stop = ov9650_stop,
169 .power_down = ov9650_power_down,
Erik Andrenc109f812008-10-01 04:51:53 -0300170};
171
172static const unsigned char preinit_ov9650[][3] =
173{
174 /* [INITCAM] */
175 {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02},
176 {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0},
177 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
178 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
179 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
180 {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00},
181
182 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x08},
183 {BRIDGE, M5602_XB_GPIO_DIR, 0x05},
184 {BRIDGE, M5602_XB_GPIO_DAT, 0x04},
185 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
186 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
187 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00},
188 {BRIDGE, M5602_XB_GPIO_DAT, 0x00},
189 {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a},
190 /* Reset chip */
191 {SENSOR, OV9650_COM7, OV9650_REGISTER_RESET},
192 /* Enable double clock */
193 {SENSOR, OV9650_CLKRC, 0x80},
194 /* Do something out of spec with the power */
195 {SENSOR, OV9650_OFON, 0x40}
196};
197
198static const unsigned char init_ov9650[][3] =
199{
200 /* [INITCAM] */
201 {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02},
202 {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0},
203 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
204 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
205 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
206 {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00},
207
208 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x08},
209 {BRIDGE, M5602_XB_GPIO_DIR, 0x05},
210 {BRIDGE, M5602_XB_GPIO_DAT, 0x04},
211 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
212 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
213 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00},
214 {BRIDGE, M5602_XB_GPIO_DAT, 0x00},
215 {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a},
Erik Andrén1b0b27b2008-12-23 14:08:07 -0300216
Erik Andrenc109f812008-10-01 04:51:53 -0300217 /* Reset chip */
218 {SENSOR, OV9650_COM7, OV9650_REGISTER_RESET},
219 /* Enable double clock */
220 {SENSOR, OV9650_CLKRC, 0x80},
221 /* Do something out of spec with the power */
222 {SENSOR, OV9650_OFON, 0x40},
223
Erik Andrenc109f812008-10-01 04:51:53 -0300224 /* Set fast AGC/AEC algorithm with unlimited step size */
225 {SENSOR, OV9650_COM8, OV9650_FAST_AGC_AEC |
226 OV9650_AEC_UNLIM_STEP_SIZE |
227 OV9650_AWB_EN | OV9650_AGC_EN},
228
229 {SENSOR, OV9650_CHLF, 0x10},
230 {SENSOR, OV9650_ARBLM, 0xbf},
231 {SENSOR, OV9650_ACOM38, 0x81},
232 /* Turn off color matrix coefficient double option */
233 {SENSOR, OV9650_COM16, 0x00},
Erik Andrénd58626c2008-11-25 03:50:05 -0300234 /* Enable color matrix for RGB/YUV, Delay Y channel,
Erik Andrenc109f812008-10-01 04:51:53 -0300235 set output Y/UV delay to 1 */
236 {SENSOR, OV9650_COM13, 0x19},
237 /* Enable digital BLC, Set output mode to U Y V Y */
238 {SENSOR, OV9650_TSLB, 0x0c},
239 /* Limit the AGC/AEC stable upper region */
240 {SENSOR, OV9650_COM24, 0x00},
241 /* Enable HREF and some out of spec things */
242 {SENSOR, OV9650_COM12, 0x73},
Erik Andréncedacfe2008-12-19 13:12:04 -0300243 /* Set all DBLC offset signs to positive and
Erik Andrenc109f812008-10-01 04:51:53 -0300244 do some out of spec stuff */
245 {SENSOR, OV9650_DBLC1, 0xdf},
246 {SENSOR, OV9650_COM21, 0x06},
247 {SENSOR, OV9650_RSVD35, 0x91},
248 /* Necessary, no camera stream without it */
249 {SENSOR, OV9650_RSVD16, 0x06},
250 {SENSOR, OV9650_RSVD94, 0x99},
251 {SENSOR, OV9650_RSVD95, 0x99},
252 {SENSOR, OV9650_RSVD96, 0x04},
253 /* Enable full range output */
254 {SENSOR, OV9650_COM15, 0x0},
Erik Andréncedacfe2008-12-19 13:12:04 -0300255 /* Enable HREF at optical black, enable ADBLC bias,
Erik Andrenc109f812008-10-01 04:51:53 -0300256 enable ADBLC, reset timings at format change */
257 {SENSOR, OV9650_COM6, 0x4b},
258 /* Subtract 32 from the B channel bias */
259 {SENSOR, OV9650_BBIAS, 0xa0},
260 /* Subtract 32 from the Gb channel bias */
261 {SENSOR, OV9650_GbBIAS, 0xa0},
262 /* Do not bypass the analog BLC and to some out of spec stuff */
263 {SENSOR, OV9650_Gr_COM, 0x00},
264 /* Subtract 32 from the R channel bias */
265 {SENSOR, OV9650_RBIAS, 0xa0},
266 /* Subtract 32 from the R channel bias */
267 {SENSOR, OV9650_RBIAS, 0x0},
268 {SENSOR, OV9650_COM26, 0x80},
269 {SENSOR, OV9650_ACOMA9, 0x98},
270 /* Set the AGC/AEC stable region upper limit */
271 {SENSOR, OV9650_AEW, 0x68},
272 /* Set the AGC/AEC stable region lower limit */
273 {SENSOR, OV9650_AEB, 0x5c},
274 /* Set the high and low limit nibbles to 3 */
275 {SENSOR, OV9650_VPT, 0xc3},
Erik Andréncedacfe2008-12-19 13:12:04 -0300276 /* Set the Automatic Gain Ceiling (AGC) to 128x,
Erik Andrenc109f812008-10-01 04:51:53 -0300277 drop VSYNC at frame drop,
278 limit exposure timing,
279 drop frame when the AEC step is larger than the exposure gap */
280 {SENSOR, OV9650_COM9, 0x6e},
281 /* Set VSYNC negative, Set RESET to SLHS (slave mode horizontal sync)
282 and set PWDN to SLVS (slave mode vertical sync) */
283 {SENSOR, OV9650_COM10, 0x42},
284 /* Set horizontal column start high to default value */
Erik Andréncedacfe2008-12-19 13:12:04 -0300285 {SENSOR, OV9650_HSTART, 0x1a}, /* 210 */
Erik Andrenc109f812008-10-01 04:51:53 -0300286 /* Set horizontal column end */
Erik Andréncedacfe2008-12-19 13:12:04 -0300287 {SENSOR, OV9650_HSTOP, 0xbf}, /* 1534 */
Erik Andrenc109f812008-10-01 04:51:53 -0300288 /* Complementing register to the two writes above */
289 {SENSOR, OV9650_HREF, 0xb2},
290 /* Set vertical row start high bits */
291 {SENSOR, OV9650_VSTRT, 0x02},
292 /* Set vertical row end low bits */
293 {SENSOR, OV9650_VSTOP, 0x7e},
294 /* Set complementing vertical frame control */
295 {SENSOR, OV9650_VREF, 0x10},
Erik Andrenc109f812008-10-01 04:51:53 -0300296 {SENSOR, OV9650_ADC, 0x04},
297 {SENSOR, OV9650_HV, 0x40},
298 /* Enable denoise, and white-pixel erase */
299 {SENSOR, OV9650_COM22, 0x23},
300
Erik Andrén1f614f42008-12-23 17:15:19 -0300301 /* Enable VARIOPIXEL */
302 {SENSOR, OV9650_COM3, OV9650_VARIOPIXEL},
303 {SENSOR, OV9650_COM4, OV9650_QVGA_VARIOPIXEL},
304
Erik Andr?n3d3ec922008-12-29 12:49:25 -0300305 /* Put the sensor in soft sleep mode */
306 {SENSOR, OV9650_COM2, OV9650_SOFT_SLEEP | OV9650_OUTPUT_DRIVE_2X},
Erik Andrenc109f812008-10-01 04:51:53 -0300307};
308
309static const unsigned char power_down_ov9650[][3] =
310{
311 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04},
312 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
313 {SENSOR, OV9650_COM7, 0x80},
314 {SENSOR, OV9650_OFON, 0xf4},
315 {SENSOR, OV9650_MVFP, 0x80},
316 {SENSOR, OV9650_DBLV, 0x3f},
317 {SENSOR, OV9650_RSVD36, 0x49},
318 {SENSOR, OV9650_COM7, 0x05},
319
320 {BRIDGE, M5602_XB_GPIO_DIR, 0x05},
321 {BRIDGE, M5602_XB_GPIO_DAT, 0x04},
322 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
323 {BRIDGE, M5602_XB_GPIO_EN_L, 0x06},
324 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02},
325 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04},
Erik Andrén27b1e4c2008-12-23 18:06:37 -0300326 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
327};
328
Erik Andr?n3d3ec922008-12-29 12:49:25 -0300329static const unsigned char res_init_ov9650[][3] =
Erik Andrén27b1e4c2008-12-23 18:06:37 -0300330{
Erik Andr?n3d3ec922008-12-29 12:49:25 -0300331 {SENSOR, OV9650_COM2, (1 << 0)},
332
333 {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x82},
334 {BRIDGE, M5602_XB_LINE_OF_FRAME_L, 0x00},
335 {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82},
336 {BRIDGE, M5602_XB_PIX_OF_LINE_L, 0x00},
337 {BRIDGE, M5602_XB_SIG_INI, 0x01}
Erik Andrenc109f812008-10-01 04:51:53 -0300338};
339
Erik Andrenc109f812008-10-01 04:51:53 -0300340#endif