Erik Andren | 4c98834 | 2008-12-29 07:35:23 -0300 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (c) 2001 Jean-Fredric Clere, Nikolas Zimmermann, Georg Acher |
| 3 | * Mark Cave-Ayland, Carlo E Prelz, Dick Streefland |
| 4 | * Copyright (c) 2002, 2003 Tuukka Toivonen |
| 5 | * Copyright (c) 2008 Erik Andrén |
| 6 | * |
| 7 | * This program is free software; you can redistribute it and/or modify |
| 8 | * it under the terms of the GNU General Public License as published by |
| 9 | * the Free Software Foundation; either version 2 of the License, or |
| 10 | * (at your option) any later version. |
| 11 | * |
| 12 | * This program is distributed in the hope that it will be useful, |
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 15 | * GNU General Public License for more details. |
| 16 | * |
| 17 | * You should have received a copy of the GNU General Public License |
| 18 | * along with this program; if not, write to the Free Software |
| 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| 20 | * |
| 21 | * P/N 861037: Sensor HDCS1000 ASIC STV0600 |
| 22 | * P/N 861050-0010: Sensor HDCS1000 ASIC STV0600 |
| 23 | * P/N 861050-0020: Sensor Photobit PB100 ASIC STV0600-1 - QuickCam Express |
| 24 | * P/N 861055: Sensor ST VV6410 ASIC STV0610 - LEGO cam |
| 25 | * P/N 861075-0040: Sensor HDCS1000 ASIC |
| 26 | * P/N 961179-0700: Sensor ST VV6410 ASIC STV0602 - Dexxa WebCam USB |
| 27 | * P/N 861040-0000: Sensor ST VV6410 ASIC STV0610 - QuickCam Web |
| 28 | */ |
| 29 | |
| 30 | #ifndef STV06XX_VV6410_H_ |
| 31 | #define STV06XX_VV6410_H_ |
| 32 | |
| 33 | #include "stv06xx_sensor.h" |
| 34 | |
| 35 | #define VV6410_COLS 416 |
| 36 | #define VV6410_ROWS 320 |
| 37 | |
| 38 | /* Status registers */ |
| 39 | /* Chip identification number including revision indicator */ |
| 40 | #define VV6410_DEVICEH 0x00 |
| 41 | #define VV6410_DEVICEL 0x01 |
| 42 | |
| 43 | /* User can determine whether timed I2C data |
| 44 | has been consumed by interrogating flag states */ |
| 45 | #define VV6410_STATUS0 0x02 |
| 46 | |
| 47 | /* Current line counter value */ |
| 48 | #define VV6410_LINECOUNTH 0x03 |
| 49 | #define VV6410_LINECOUNTL 0x04 |
| 50 | |
| 51 | /* End x coordinate of image size */ |
| 52 | #define VV6410_XENDH 0x05 |
| 53 | #define VV6410_XENDL 0x06 |
| 54 | |
| 55 | /* End y coordinate of image size */ |
| 56 | #define VV6410_YENDH 0x07 |
| 57 | #define VV6410_YENDL 0x08 |
| 58 | |
| 59 | /* This is the average pixel value returned from the |
| 60 | dark line offset cancellation algorithm */ |
| 61 | #define VV6410_DARKAVGH 0x09 |
| 62 | #define VV6410_DARKAVGL 0x0a |
| 63 | |
| 64 | /* This is the average pixel value returned from the |
| 65 | black line offset cancellation algorithm */ |
| 66 | #define VV6410_BLACKAVGH 0x0b |
| 67 | #define VV6410_BLACKAVGL 0x0c |
| 68 | |
| 69 | /* Flags to indicate whether the x or y image coordinates have been clipped */ |
| 70 | #define VV6410_STATUS1 0x0d |
| 71 | |
| 72 | /* Setup registers */ |
| 73 | |
| 74 | /* Low-power/sleep modes & video timing */ |
| 75 | #define VV6410_SETUP0 0x10 |
| 76 | |
| 77 | /* Various parameters */ |
| 78 | #define VV6410_SETUP1 0x11 |
| 79 | |
| 80 | /* Contains pixel counter reset value used by external sync */ |
| 81 | #define VV6410_SYNCVALUE 0x12 |
| 82 | |
| 83 | /* Frame grabbing modes (FST, LST and QCK) */ |
| 84 | #define VV6410_FGMODES 0x14 |
| 85 | |
| 86 | /* FST and QCK mapping modes. */ |
| 87 | #define VV6410_PINMAPPING 0x15 |
| 88 | |
| 89 | /* Data resolution */ |
| 90 | #define VV6410_DATAFORMAT 0x16 |
| 91 | |
| 92 | /* Output coding formats */ |
| 93 | #define VV6410_OPFORMAT 0x17 |
| 94 | |
| 95 | /* Various mode select bits */ |
| 96 | #define VV6410_MODESELECT 0x18 |
| 97 | |
| 98 | /* Exposure registers */ |
| 99 | /* Fine exposure. */ |
| 100 | #define VV6410_FINEH 0x20 |
| 101 | #define VV6410_FINEL 0x21 |
| 102 | |
| 103 | /* Coarse exposure */ |
| 104 | #define VV6410_COARSEH 0x22 |
| 105 | #define VV6410_COARSEL 0x23 |
| 106 | |
| 107 | /* Analog gain setting */ |
| 108 | #define VV6410_ANALOGGAIN 0x24 |
| 109 | |
| 110 | /* Clock division */ |
| 111 | #define VV6410_CLKDIV 0x25 |
| 112 | |
| 113 | /* Dark line offset cancellation value */ |
| 114 | #define VV6410_DARKOFFSETH 0x2c |
| 115 | #define VV6410_DARKOFFSETL 0x2d |
| 116 | |
| 117 | /* Dark line offset cancellation enable */ |
| 118 | #define VV6410_DARKOFFSETSETUP 0x2e |
| 119 | |
| 120 | /* Video timing registers */ |
| 121 | /* Line Length (Pixel Clocks) */ |
| 122 | #define VV6410_LINELENGTHH 0x52 |
| 123 | #define VV6410_LINELENGTHL 0x53 |
| 124 | |
| 125 | /* X-co-ordinate of top left corner of region of interest (x-offset) */ |
| 126 | #define VV6410_XOFFSETH 0x57 |
| 127 | #define VV6410_XOFFSETL 0x58 |
| 128 | |
| 129 | /* Y-coordinate of top left corner of region of interest (y-offset) */ |
| 130 | #define VV6410_YOFFSETH 0x59 |
| 131 | #define VV6410_YOFFSETL 0x5a |
| 132 | |
| 133 | /* Field length (Lines) */ |
| 134 | #define VV6410_FIELDLENGTHH 0x61 |
| 135 | #define VV6410_FIELDLENGTHL 0x62 |
| 136 | |
| 137 | /* System registers */ |
| 138 | /* Black offset cancellation default value */ |
| 139 | #define VV6410_BLACKOFFSETH 0x70 |
| 140 | #define VV6410_BLACKOFFSETL 0x71 |
| 141 | |
| 142 | /* Black offset cancellation setup */ |
| 143 | #define VV6410_BLACKOFFSETSETUP 0x72 |
| 144 | |
| 145 | /* Analog Control Register 0 */ |
| 146 | #define VV6410_CR0 0x75 |
| 147 | |
| 148 | /* Analog Control Register 1 */ |
| 149 | #define VV6410_CR1 0x76 |
| 150 | |
| 151 | /* ADC Setup Register */ |
| 152 | #define VV6410_AS0 0x77 |
| 153 | |
| 154 | /* Analog Test Register */ |
| 155 | #define VV6410_AT0 0x78 |
| 156 | |
| 157 | /* Audio Amplifier Setup Register */ |
| 158 | #define VV6410_AT1 0x79 |
| 159 | |
| 160 | #define VV6410_HFLIP (1 << 3) |
| 161 | #define VV6410_VFLIP (1 << 4) |
| 162 | |
| 163 | #define VV6410_LOW_POWER_MODE (1 << 0) |
| 164 | #define VV6410_SOFT_RESET (1 << 2) |
| 165 | #define VV6410_PAL_25_FPS (0 << 3) |
| 166 | |
| 167 | #define VV6410_CLK_DIV_2 (1 << 1) |
| 168 | |
| 169 | #define VV6410_FINE_EXPOSURE 320 |
| 170 | #define VV6410_COARSE_EXPOSURE 192 |
| 171 | #define VV6410_DEFAULT_GAIN 5 |
| 172 | |
| 173 | #define VV6410_SUBSAMPLE 0x01 |
| 174 | #define VV6410_CROP_TO_QVGA 0x02 |
| 175 | |
Erik Andrén | 1906d8d | 2009-05-03 15:45:48 -0300 | [diff] [blame] | 176 | #define VV6410_CIF_LINELENGTH 415 |
| 177 | |
Erik Andren | 4c98834 | 2008-12-29 07:35:23 -0300 | [diff] [blame] | 178 | static int vv6410_probe(struct sd *sd); |
| 179 | static int vv6410_start(struct sd *sd); |
| 180 | static int vv6410_init(struct sd *sd); |
| 181 | static int vv6410_stop(struct sd *sd); |
| 182 | static int vv6410_dump(struct sd *sd); |
Erik Andren | 5658ae9 | 2009-01-07 06:11:50 -0300 | [diff] [blame] | 183 | static void vv6410_disconnect(struct sd *sd); |
Erik Andren | 4c98834 | 2008-12-29 07:35:23 -0300 | [diff] [blame] | 184 | |
| 185 | /* V4L2 controls supported by the driver */ |
| 186 | static int vv6410_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); |
| 187 | static int vv6410_set_hflip(struct gspca_dev *gspca_dev, __s32 val); |
| 188 | static int vv6410_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); |
| 189 | static int vv6410_set_vflip(struct gspca_dev *gspca_dev, __s32 val); |
| 190 | static int vv6410_get_analog_gain(struct gspca_dev *gspca_dev, __s32 *val); |
| 191 | static int vv6410_set_analog_gain(struct gspca_dev *gspca_dev, __s32 val); |
Erik Andrén | 1906d8d | 2009-05-03 15:45:48 -0300 | [diff] [blame] | 192 | static int vv6410_get_exposure(struct gspca_dev *gspca_dev, __s32 *val); |
| 193 | static int vv6410_set_exposure(struct gspca_dev *gspca_dev, __s32 val); |
Erik Andren | 4c98834 | 2008-12-29 07:35:23 -0300 | [diff] [blame] | 194 | |
| 195 | const struct stv06xx_sensor stv06xx_sensor_vv6410 = { |
| 196 | .name = "ST VV6410", |
| 197 | .i2c_flush = 5, |
| 198 | .i2c_addr = 0x20, |
| 199 | .i2c_len = 1, |
| 200 | .init = vv6410_init, |
| 201 | .probe = vv6410_probe, |
| 202 | .start = vv6410_start, |
| 203 | .stop = vv6410_stop, |
| 204 | .dump = vv6410_dump, |
Erik Andren | 5658ae9 | 2009-01-07 06:11:50 -0300 | [diff] [blame] | 205 | .disconnect = vv6410_disconnect, |
Erik Andren | 4c98834 | 2008-12-29 07:35:23 -0300 | [diff] [blame] | 206 | }; |
| 207 | |
| 208 | /* If NULL, only single value to write, stored in len */ |
| 209 | struct stv_init { |
| 210 | const u8 *data; |
| 211 | u16 start; |
| 212 | u8 len; |
| 213 | }; |
| 214 | |
| 215 | static const u8 x1500[] = { /* 0x1500 - 0x150f */ |
| 216 | 0x0b, 0xa7, 0xb7, 0x00, 0x00 |
| 217 | }; |
| 218 | |
| 219 | static const u8 x1536[] = { /* 0x1536 - 0x153b */ |
| 220 | 0x02, 0x00, 0x60, 0x01, 0x20, 0x01 |
| 221 | }; |
| 222 | |
| 223 | static const u8 x15c1[] = { /* 0x15c1 - 0x15c2 */ |
| 224 | 0xff, 0x03 /* Output word 0x03ff = 1023 (ISO size) */ |
| 225 | }; |
| 226 | |
| 227 | static const struct stv_init stv_bridge_init[] = { |
| 228 | /* This reg is written twice. Some kind of reset? */ |
| 229 | {NULL, 0x1620, 0x80}, |
| 230 | {NULL, 0x1620, 0x00}, |
| 231 | {NULL, 0x1423, 0x04}, |
| 232 | {x1500, 0x1500, ARRAY_SIZE(x1500)}, |
| 233 | {x1536, 0x1536, ARRAY_SIZE(x1536)}, |
| 234 | {x15c1, 0x15c1, ARRAY_SIZE(x15c1)} |
| 235 | }; |
| 236 | |
| 237 | static const u8 vv6410_sensor_init[][2] = { |
| 238 | /* Setup registers */ |
| 239 | {VV6410_SETUP0, VV6410_SOFT_RESET}, |
| 240 | {VV6410_SETUP0, VV6410_LOW_POWER_MODE}, |
| 241 | /* Use shuffled read-out mode */ |
| 242 | {VV6410_SETUP1, BIT(6)}, |
| 243 | /* All modes to 1 */ |
| 244 | {VV6410_FGMODES, BIT(6) | BIT(4) | BIT(2) | BIT(0)}, |
| 245 | {VV6410_PINMAPPING, 0x00}, |
| 246 | /* Pre-clock generator divide off */ |
| 247 | {VV6410_DATAFORMAT, BIT(7) | BIT(0)}, |
| 248 | |
Erik Andren | 4c98834 | 2008-12-29 07:35:23 -0300 | [diff] [blame] | 249 | {VV6410_CLKDIV, VV6410_CLK_DIV_2}, |
| 250 | |
| 251 | /* System registers */ |
| 252 | /* Enable voltage doubler */ |
| 253 | {VV6410_AS0, BIT(6) | BIT(4) | BIT(3) | BIT(2) | BIT(1)}, |
| 254 | {VV6410_AT0, 0x00}, |
| 255 | /* Power up audio, differential */ |
| 256 | {VV6410_AT1, BIT(4)|BIT(0)}, |
| 257 | }; |
| 258 | |
| 259 | #endif |