aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/gspca/w996Xcf.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/gspca/w996Xcf.c')
-rw-r--r--drivers/media/video/gspca/w996Xcf.c325
1 files changed, 143 insertions, 182 deletions
diff --git a/drivers/media/video/gspca/w996Xcf.c b/drivers/media/video/gspca/w996Xcf.c
index 4066ac8c45a0..4a9e622e5e1b 100644
--- a/drivers/media/video/gspca/w996Xcf.c
+++ b/drivers/media/video/gspca/w996Xcf.c
@@ -59,18 +59,21 @@ static const struct v4l2_pix_format w9968cf_vga_mode[] = {
59 .colorspace = V4L2_COLORSPACE_JPEG}, 59 .colorspace = V4L2_COLORSPACE_JPEG},
60}; 60};
61 61
62static int reg_w(struct sd *sd, __u16 index, __u16 value); 62static void reg_w(struct sd *sd, u16 index, u16 value);
63 63
64/*-------------------------------------------------------------------------- 64/*--------------------------------------------------------------------------
65 Write 64-bit data to the fast serial bus registers. 65 Write 64-bit data to the fast serial bus registers.
66 Return 0 on success, -1 otherwise. 66 Return 0 on success, -1 otherwise.
67 --------------------------------------------------------------------------*/ 67 --------------------------------------------------------------------------*/
68static int w9968cf_write_fsb(struct sd *sd, u16* data) 68static void w9968cf_write_fsb(struct sd *sd, u16* data)
69{ 69{
70 struct usb_device *udev = sd->gspca_dev.dev; 70 struct usb_device *udev = sd->gspca_dev.dev;
71 u16 value; 71 u16 value;
72 int ret; 72 int ret;
73 73
74 if (sd->gspca_dev.usb_err < 0)
75 return;
76
74 value = *data++; 77 value = *data++;
75 memcpy(sd->gspca_dev.usb_buf, data, 6); 78 memcpy(sd->gspca_dev.usb_buf, data, 6);
76 79
@@ -79,20 +82,21 @@ static int w9968cf_write_fsb(struct sd *sd, u16* data)
79 value, 0x06, sd->gspca_dev.usb_buf, 6, 500); 82 value, 0x06, sd->gspca_dev.usb_buf, 6, 500);
80 if (ret < 0) { 83 if (ret < 0) {
81 err("Write FSB registers failed (%d)", ret); 84 err("Write FSB registers failed (%d)", ret);
82 return ret; 85 sd->gspca_dev.usb_err = ret;
83 } 86 }
84
85 return 0;
86} 87}
87 88
88/*-------------------------------------------------------------------------- 89/*--------------------------------------------------------------------------
89 Write data to the serial bus control register. 90 Write data to the serial bus control register.
90 Return 0 on success, a negative number otherwise. 91 Return 0 on success, a negative number otherwise.
91 --------------------------------------------------------------------------*/ 92 --------------------------------------------------------------------------*/
92static int w9968cf_write_sb(struct sd *sd, u16 value) 93static void w9968cf_write_sb(struct sd *sd, u16 value)
93{ 94{
94 int ret; 95 int ret;
95 96
97 if (sd->gspca_dev.usb_err < 0)
98 return;
99
96 /* We don't use reg_w here, as that would cause all writes when 100 /* We don't use reg_w here, as that would cause all writes when
97 bitbanging i2c to be logged, making the logs impossible to read */ 101 bitbanging i2c to be logged, making the logs impossible to read */
98 ret = usb_control_msg(sd->gspca_dev.dev, 102 ret = usb_control_msg(sd->gspca_dev.dev,
@@ -105,10 +109,8 @@ static int w9968cf_write_sb(struct sd *sd, u16 value)
105 109
106 if (ret < 0) { 110 if (ret < 0) {
107 err("Write SB reg [01] %04x failed", value); 111 err("Write SB reg [01] %04x failed", value);
108 return ret; 112 sd->gspca_dev.usb_err = ret;
109 } 113 }
110
111 return 0;
112} 114}
113 115
114/*-------------------------------------------------------------------------- 116/*--------------------------------------------------------------------------
@@ -119,6 +121,9 @@ static int w9968cf_read_sb(struct sd *sd)
119{ 121{
120 int ret; 122 int ret;
121 123
124 if (sd->gspca_dev.usb_err < 0)
125 return -1;
126
122 /* We don't use reg_r here, as the w9968cf is special and has 16 127 /* We don't use reg_r here, as the w9968cf is special and has 16
123 bit registers instead of 8 bit */ 128 bit registers instead of 8 bit */
124 ret = usb_control_msg(sd->gspca_dev.dev, 129 ret = usb_control_msg(sd->gspca_dev.dev,
@@ -126,11 +131,13 @@ static int w9968cf_read_sb(struct sd *sd)
126 1, 131 1,
127 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 132 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
128 0, 0x01, sd->gspca_dev.usb_buf, 2, 500); 133 0, 0x01, sd->gspca_dev.usb_buf, 2, 500);
129 if (ret >= 0) 134 if (ret >= 0) {
130 ret = sd->gspca_dev.usb_buf[0] | 135 ret = sd->gspca_dev.usb_buf[0] |
131 (sd->gspca_dev.usb_buf[1] << 8); 136 (sd->gspca_dev.usb_buf[1] << 8);
132 else 137 } else {
133 err("Read SB reg [01] failed"); 138 err("Read SB reg [01] failed");
139 sd->gspca_dev.usb_err = ret;
140 }
134 141
135 udelay(W9968CF_I2C_BUS_DELAY); 142 udelay(W9968CF_I2C_BUS_DELAY);
136 143
@@ -142,22 +149,20 @@ static int w9968cf_read_sb(struct sd *sd)
142 This function is called by w9968cf_start_transfer(). 149 This function is called by w9968cf_start_transfer().
143 Return 0 on success, a negative number otherwise. 150 Return 0 on success, a negative number otherwise.
144 --------------------------------------------------------------------------*/ 151 --------------------------------------------------------------------------*/
145static int w9968cf_upload_quantizationtables(struct sd *sd) 152static void w9968cf_upload_quantizationtables(struct sd *sd)
146{ 153{
147 u16 a, b; 154 u16 a, b;
148 int ret = 0, i, j; 155 int i, j;
149 156
150 ret += reg_w(sd, 0x39, 0x0010); /* JPEG clock enable */ 157 reg_w(sd, 0x39, 0x0010); /* JPEG clock enable */
151 158
152 for (i = 0, j = 0; i < 32; i++, j += 2) { 159 for (i = 0, j = 0; i < 32; i++, j += 2) {
153 a = Y_QUANTABLE[j] | ((unsigned)(Y_QUANTABLE[j+1]) << 8); 160 a = Y_QUANTABLE[j] | ((unsigned)(Y_QUANTABLE[j + 1]) << 8);
154 b = UV_QUANTABLE[j] | ((unsigned)(UV_QUANTABLE[j+1]) << 8); 161 b = UV_QUANTABLE[j] | ((unsigned)(UV_QUANTABLE[j + 1]) << 8);
155 ret += reg_w(sd, 0x40+i, a); 162 reg_w(sd, 0x40 + i, a);
156 ret += reg_w(sd, 0x60+i, b); 163 reg_w(sd, 0x60 + i, b);
157 } 164 }
158 ret += reg_w(sd, 0x39, 0x0012); /* JPEG encoder enable */ 165 reg_w(sd, 0x39, 0x0012); /* JPEG encoder enable */
159
160 return ret;
161} 166}
162 167
163/**************************************************************************** 168/****************************************************************************
@@ -168,50 +173,39 @@ static int w9968cf_upload_quantizationtables(struct sd *sd)
168 * i2c_adap_read_byte() * 173 * i2c_adap_read_byte() *
169 ****************************************************************************/ 174 ****************************************************************************/
170 175
171static int w9968cf_smbus_start(struct sd *sd) 176static void w9968cf_smbus_start(struct sd *sd)
172{ 177{
173 int ret = 0; 178 w9968cf_write_sb(sd, 0x0011); /* SDE=1, SDA=0, SCL=1 */
174 179 w9968cf_write_sb(sd, 0x0010); /* SDE=1, SDA=0, SCL=0 */
175 ret += w9968cf_write_sb(sd, 0x0011); /* SDE=1, SDA=0, SCL=1 */
176 ret += w9968cf_write_sb(sd, 0x0010); /* SDE=1, SDA=0, SCL=0 */
177
178 return ret;
179} 180}
180 181
181static int w9968cf_smbus_stop(struct sd *sd) 182static void w9968cf_smbus_stop(struct sd *sd)
182{ 183{
183 int ret = 0; 184 w9968cf_write_sb(sd, 0x0010); /* SDE=1, SDA=0, SCL=0 */
184 185 w9968cf_write_sb(sd, 0x0011); /* SDE=1, SDA=0, SCL=1 */
185 ret += w9968cf_write_sb(sd, 0x0010); /* SDE=1, SDA=0, SCL=0 */ 186 w9968cf_write_sb(sd, 0x0013); /* SDE=1, SDA=1, SCL=1 */
186 ret += w9968cf_write_sb(sd, 0x0011); /* SDE=1, SDA=0, SCL=1 */
187 ret += w9968cf_write_sb(sd, 0x0013); /* SDE=1, SDA=1, SCL=1 */
188
189 return ret;
190} 187}
191 188
192static int w9968cf_smbus_write_byte(struct sd *sd, u8 v) 189static void w9968cf_smbus_write_byte(struct sd *sd, u8 v)
193{ 190{
194 u8 bit; 191 u8 bit;
195 int ret = 0, sda; 192 int sda;
196 193
197 for (bit = 0 ; bit < 8 ; bit++) { 194 for (bit = 0 ; bit < 8 ; bit++) {
198 sda = (v & 0x80) ? 2 : 0; 195 sda = (v & 0x80) ? 2 : 0;
199 v <<= 1; 196 v <<= 1;
200 /* SDE=1, SDA=sda, SCL=0 */ 197 /* SDE=1, SDA=sda, SCL=0 */
201 ret += w9968cf_write_sb(sd, 0x10 | sda); 198 w9968cf_write_sb(sd, 0x10 | sda);
202 /* SDE=1, SDA=sda, SCL=1 */ 199 /* SDE=1, SDA=sda, SCL=1 */
203 ret += w9968cf_write_sb(sd, 0x11 | sda); 200 w9968cf_write_sb(sd, 0x11 | sda);
204 /* SDE=1, SDA=sda, SCL=0 */ 201 /* SDE=1, SDA=sda, SCL=0 */
205 ret += w9968cf_write_sb(sd, 0x10 | sda); 202 w9968cf_write_sb(sd, 0x10 | sda);
206 } 203 }
207
208 return ret;
209} 204}
210 205
211static int w9968cf_smbus_read_byte(struct sd *sd, u8* v) 206static void w9968cf_smbus_read_byte(struct sd *sd, u8 *v)
212{ 207{
213 u8 bit; 208 u8 bit;
214 int ret = 0;
215 209
216 /* No need to ensure SDA is high as we are always called after 210 /* No need to ensure SDA is high as we are always called after
217 read_ack which ends with SDA high */ 211 read_ack which ends with SDA high */
@@ -219,51 +213,40 @@ static int w9968cf_smbus_read_byte(struct sd *sd, u8* v)
219 for (bit = 0 ; bit < 8 ; bit++) { 213 for (bit = 0 ; bit < 8 ; bit++) {
220 *v <<= 1; 214 *v <<= 1;
221 /* SDE=1, SDA=1, SCL=1 */ 215 /* SDE=1, SDA=1, SCL=1 */
222 ret += w9968cf_write_sb(sd, 0x0013); 216 w9968cf_write_sb(sd, 0x0013);
223 *v |= (w9968cf_read_sb(sd) & 0x0008) ? 1 : 0; 217 *v |= (w9968cf_read_sb(sd) & 0x0008) ? 1 : 0;
224 /* SDE=1, SDA=1, SCL=0 */ 218 /* SDE=1, SDA=1, SCL=0 */
225 ret += w9968cf_write_sb(sd, 0x0012); 219 w9968cf_write_sb(sd, 0x0012);
226 } 220 }
227
228 return ret;
229} 221}
230 222
231static int w9968cf_smbus_write_nack(struct sd *sd) 223static void w9968cf_smbus_write_nack(struct sd *sd)
232{ 224{
233 int ret = 0;
234
235 /* No need to ensure SDA is high as we are always called after 225 /* No need to ensure SDA is high as we are always called after
236 read_byte which ends with SDA high */ 226 read_byte which ends with SDA high */
237 ret += w9968cf_write_sb(sd, 0x0013); /* SDE=1, SDA=1, SCL=1 */ 227 w9968cf_write_sb(sd, 0x0013); /* SDE=1, SDA=1, SCL=1 */
238 ret += w9968cf_write_sb(sd, 0x0012); /* SDE=1, SDA=1, SCL=0 */ 228 w9968cf_write_sb(sd, 0x0012); /* SDE=1, SDA=1, SCL=0 */
239
240 return ret;
241} 229}
242 230
243static int w9968cf_smbus_read_ack(struct sd *sd) 231static void w9968cf_smbus_read_ack(struct sd *sd)
244{ 232{
245 int ret = 0, sda; 233 int sda;
246 234
247 /* Ensure SDA is high before raising clock to avoid a spurious stop */ 235 /* Ensure SDA is high before raising clock to avoid a spurious stop */
248 ret += w9968cf_write_sb(sd, 0x0012); /* SDE=1, SDA=1, SCL=0 */ 236 w9968cf_write_sb(sd, 0x0012); /* SDE=1, SDA=1, SCL=0 */
249 ret += w9968cf_write_sb(sd, 0x0013); /* SDE=1, SDA=1, SCL=1 */ 237 w9968cf_write_sb(sd, 0x0013); /* SDE=1, SDA=1, SCL=1 */
250 sda = w9968cf_read_sb(sd); 238 sda = w9968cf_read_sb(sd);
251 ret += w9968cf_write_sb(sd, 0x0012); /* SDE=1, SDA=1, SCL=0 */ 239 w9968cf_write_sb(sd, 0x0012); /* SDE=1, SDA=1, SCL=0 */
252 if (sda < 0) 240 if (sda >= 0 && (sda & 0x08)) {
253 ret += sda;
254 else if (sda & 0x08) {
255 PDEBUG(D_USBI, "Did not receive i2c ACK"); 241 PDEBUG(D_USBI, "Did not receive i2c ACK");
256 ret += -1; 242 sd->gspca_dev.usb_err = -EIO;
257 } 243 }
258
259 return ret;
260} 244}
261 245
262/* SMBus protocol: S Addr Wr [A] Subaddr [A] Value [A] P */ 246/* SMBus protocol: S Addr Wr [A] Subaddr [A] Value [A] P */
263static int w9968cf_i2c_w(struct sd *sd, u8 reg, u8 value) 247static void w9968cf_i2c_w(struct sd *sd, u8 reg, u8 value)
264{ 248{
265 u16* data = (u16 *)sd->gspca_dev.usb_buf; 249 u16* data = (u16 *)sd->gspca_dev.usb_buf;
266 int ret = 0;
267 250
268 data[0] = 0x082f | ((sd->sensor_addr & 0x80) ? 0x1500 : 0x0); 251 data[0] = 0x082f | ((sd->sensor_addr & 0x80) ? 0x1500 : 0x0);
269 data[0] |= (sd->sensor_addr & 0x40) ? 0x4000 : 0x0; 252 data[0] |= (sd->sensor_addr & 0x40) ? 0x4000 : 0x0;
@@ -276,7 +259,7 @@ static int w9968cf_i2c_w(struct sd *sd, u8 reg, u8 value)
276 data[3] = 0x1d20 | ((sd->sensor_addr & 0x02) ? 0x0001 : 0x0); 259 data[3] = 0x1d20 | ((sd->sensor_addr & 0x02) ? 0x0001 : 0x0);
277 data[3] |= (sd->sensor_addr & 0x01) ? 0x0054 : 0x0; 260 data[3] |= (sd->sensor_addr & 0x01) ? 0x0054 : 0x0;
278 261
279 ret += w9968cf_write_fsb(sd, data); 262 w9968cf_write_fsb(sd, data);
280 263
281 data[0] = 0x8208 | ((reg & 0x80) ? 0x0015 : 0x0); 264 data[0] = 0x8208 | ((reg & 0x80) ? 0x0015 : 0x0);
282 data[0] |= (reg & 0x40) ? 0x0540 : 0x0; 265 data[0] |= (reg & 0x40) ? 0x0540 : 0x0;
@@ -290,7 +273,7 @@ static int w9968cf_i2c_w(struct sd *sd, u8 reg, u8 value)
290 data[2] |= (reg & 0x01) ? 0x5400 : 0x0; 273 data[2] |= (reg & 0x01) ? 0x5400 : 0x0;
291 data[3] = 0x001d; 274 data[3] = 0x001d;
292 275
293 ret += w9968cf_write_fsb(sd, data); 276 w9968cf_write_fsb(sd, data);
294 277
295 data[0] = 0x8208 | ((value & 0x80) ? 0x0015 : 0x0); 278 data[0] = 0x8208 | ((value & 0x80) ? 0x0015 : 0x0);
296 data[0] |= (value & 0x40) ? 0x0540 : 0x0; 279 data[0] |= (value & 0x40) ? 0x0540 : 0x0;
@@ -304,14 +287,9 @@ static int w9968cf_i2c_w(struct sd *sd, u8 reg, u8 value)
304 data[2] |= (value & 0x01) ? 0x5400 : 0x0; 287 data[2] |= (value & 0x01) ? 0x5400 : 0x0;
305 data[3] = 0xfe1d; 288 data[3] = 0xfe1d;
306 289
307 ret += w9968cf_write_fsb(sd, data); 290 w9968cf_write_fsb(sd, data);
308 291
309 if (!ret) 292 PDEBUG(D_USBO, "i2c 0x%02x -> [0x%02x]", value, reg);
310 PDEBUG(D_USBO, "i2c 0x%02x -> [0x%02x]", value, reg);
311 else
312 PDEBUG(D_ERR, "i2c 0x%02x -> [0x%02x] failed", value, reg);
313
314 return ret;
315} 293}
316 294
317/* SMBus protocol: S Addr Wr [A] Subaddr [A] P S Addr+1 Rd [A] [Value] NA P */ 295/* SMBus protocol: S Addr Wr [A] Subaddr [A] P S Addr+1 Rd [A] [Value] NA P */
@@ -321,28 +299,28 @@ static int w9968cf_i2c_r(struct sd *sd, u8 reg)
321 u8 value; 299 u8 value;
322 300
323 /* Fast serial bus data control disable */ 301 /* Fast serial bus data control disable */
324 ret += w9968cf_write_sb(sd, 0x0013); /* don't change ! */ 302 w9968cf_write_sb(sd, 0x0013); /* don't change ! */
325 303
326 ret += w9968cf_smbus_start(sd); 304 w9968cf_smbus_start(sd);
327 ret += w9968cf_smbus_write_byte(sd, sd->sensor_addr); 305 w9968cf_smbus_write_byte(sd, sd->sensor_addr);
328 ret += w9968cf_smbus_read_ack(sd); 306 w9968cf_smbus_read_ack(sd);
329 ret += w9968cf_smbus_write_byte(sd, reg); 307 w9968cf_smbus_write_byte(sd, reg);
330 ret += w9968cf_smbus_read_ack(sd); 308 w9968cf_smbus_read_ack(sd);
331 ret += w9968cf_smbus_stop(sd); 309 w9968cf_smbus_stop(sd);
332 ret += w9968cf_smbus_start(sd); 310 w9968cf_smbus_start(sd);
333 ret += w9968cf_smbus_write_byte(sd, sd->sensor_addr + 1); 311 w9968cf_smbus_write_byte(sd, sd->sensor_addr + 1);
334 ret += w9968cf_smbus_read_ack(sd); 312 w9968cf_smbus_read_ack(sd);
335 ret += w9968cf_smbus_read_byte(sd, &value); 313 w9968cf_smbus_read_byte(sd, &value);
336 /* signal we don't want to read anymore, the v4l1 driver used to 314 /* signal we don't want to read anymore, the v4l1 driver used to
337 send an ack here which is very wrong! (and then fixed 315 send an ack here which is very wrong! (and then fixed
338 the issues this gave by retrying reads) */ 316 the issues this gave by retrying reads) */
339 ret += w9968cf_smbus_write_nack(sd); 317 w9968cf_smbus_write_nack(sd);
340 ret += w9968cf_smbus_stop(sd); 318 w9968cf_smbus_stop(sd);
341 319
342 /* Fast serial bus data control re-enable */ 320 /* Fast serial bus data control re-enable */
343 ret += w9968cf_write_sb(sd, 0x0030); 321 w9968cf_write_sb(sd, 0x0030);
344 322
345 if (!ret) { 323 if (sd->gspca_dev.usb_err >= 0) {
346 ret = value; 324 ret = value;
347 PDEBUG(D_USBI, "i2c [0x%02X] -> 0x%02X", reg, value); 325 PDEBUG(D_USBI, "i2c [0x%02X] -> 0x%02X", reg, value);
348 } else 326 } else
@@ -351,79 +329,68 @@ static int w9968cf_i2c_r(struct sd *sd, u8 reg)
351 return ret; 329 return ret;
352} 330}
353 331
354
355/*-------------------------------------------------------------------------- 332/*--------------------------------------------------------------------------
356 Turn on the LED on some webcams. A beep should be heard too. 333 Turn on the LED on some webcams. A beep should be heard too.
357 Return 0 on success, a negative number otherwise. 334 Return 0 on success, a negative number otherwise.
358 --------------------------------------------------------------------------*/ 335 --------------------------------------------------------------------------*/
359static int w9968cf_configure(struct sd *sd) 336static void w9968cf_configure(struct sd *sd)
360{ 337{
361 int ret = 0; 338 reg_w(sd, 0x00, 0xff00); /* power-down */
362 339 reg_w(sd, 0x00, 0xbf17); /* reset everything */
363 ret += reg_w(sd, 0x00, 0xff00); /* power-down */ 340 reg_w(sd, 0x00, 0xbf10); /* normal operation */
364 ret += reg_w(sd, 0x00, 0xbf17); /* reset everything */ 341 reg_w(sd, 0x01, 0x0010); /* serial bus, SDS high */
365 ret += reg_w(sd, 0x00, 0xbf10); /* normal operation */ 342 reg_w(sd, 0x01, 0x0000); /* serial bus, SDS low */
366 ret += reg_w(sd, 0x01, 0x0010); /* serial bus, SDS high */ 343 reg_w(sd, 0x01, 0x0010); /* ..high 'beep-beep' */
367 ret += reg_w(sd, 0x01, 0x0000); /* serial bus, SDS low */ 344 reg_w(sd, 0x01, 0x0030); /* Set sda scl to FSB mode */
368 ret += reg_w(sd, 0x01, 0x0010); /* ..high 'beep-beep' */
369 ret += reg_w(sd, 0x01, 0x0030); /* Set sda scl to FSB mode */
370
371 if (ret)
372 PDEBUG(D_ERR, "Couldn't turn on the LED");
373 345
374 sd->stopped = 1; 346 sd->stopped = 1;
375
376 return ret;
377} 347}
378 348
379static int w9968cf_init(struct sd *sd) 349static void w9968cf_init(struct sd *sd)
380{ 350{
381 int ret = 0;
382 unsigned long hw_bufsize = sd->sif ? (352 * 288 * 2) : (640 * 480 * 2), 351 unsigned long hw_bufsize = sd->sif ? (352 * 288 * 2) : (640 * 480 * 2),
383 y0 = 0x0000, 352 y0 = 0x0000,
384 u0 = y0 + hw_bufsize/2, 353 u0 = y0 + hw_bufsize / 2,
385 v0 = u0 + hw_bufsize/4, 354 v0 = u0 + hw_bufsize / 4,
386 y1 = v0 + hw_bufsize/4, 355 y1 = v0 + hw_bufsize / 4,
387 u1 = y1 + hw_bufsize/2, 356 u1 = y1 + hw_bufsize / 2,
388 v1 = u1 + hw_bufsize/4; 357 v1 = u1 + hw_bufsize / 4;
389 358
390 ret += reg_w(sd, 0x00, 0xff00); /* power off */ 359 reg_w(sd, 0x00, 0xff00); /* power off */
391 ret += reg_w(sd, 0x00, 0xbf10); /* power on */ 360 reg_w(sd, 0x00, 0xbf10); /* power on */
392 361
393 ret += reg_w(sd, 0x03, 0x405d); /* DRAM timings */ 362 reg_w(sd, 0x03, 0x405d); /* DRAM timings */
394 ret += reg_w(sd, 0x04, 0x0030); /* SDRAM timings */ 363 reg_w(sd, 0x04, 0x0030); /* SDRAM timings */
395 364
396 ret += reg_w(sd, 0x20, y0 & 0xffff); /* Y buf.0, low */ 365 reg_w(sd, 0x20, y0 & 0xffff); /* Y buf.0, low */
397 ret += reg_w(sd, 0x21, y0 >> 16); /* Y buf.0, high */ 366 reg_w(sd, 0x21, y0 >> 16); /* Y buf.0, high */
398 ret += reg_w(sd, 0x24, u0 & 0xffff); /* U buf.0, low */ 367 reg_w(sd, 0x24, u0 & 0xffff); /* U buf.0, low */
399 ret += reg_w(sd, 0x25, u0 >> 16); /* U buf.0, high */ 368 reg_w(sd, 0x25, u0 >> 16); /* U buf.0, high */
400 ret += reg_w(sd, 0x28, v0 & 0xffff); /* V buf.0, low */ 369 reg_w(sd, 0x28, v0 & 0xffff); /* V buf.0, low */
401 ret += reg_w(sd, 0x29, v0 >> 16); /* V buf.0, high */ 370 reg_w(sd, 0x29, v0 >> 16); /* V buf.0, high */
402 371
403 ret += reg_w(sd, 0x22, y1 & 0xffff); /* Y buf.1, low */ 372 reg_w(sd, 0x22, y1 & 0xffff); /* Y buf.1, low */
404 ret += reg_w(sd, 0x23, y1 >> 16); /* Y buf.1, high */ 373 reg_w(sd, 0x23, y1 >> 16); /* Y buf.1, high */
405 ret += reg_w(sd, 0x26, u1 & 0xffff); /* U buf.1, low */ 374 reg_w(sd, 0x26, u1 & 0xffff); /* U buf.1, low */
406 ret += reg_w(sd, 0x27, u1 >> 16); /* U buf.1, high */ 375 reg_w(sd, 0x27, u1 >> 16); /* U buf.1, high */
407 ret += reg_w(sd, 0x2a, v1 & 0xffff); /* V buf.1, low */ 376 reg_w(sd, 0x2a, v1 & 0xffff); /* V buf.1, low */
408 ret += reg_w(sd, 0x2b, v1 >> 16); /* V buf.1, high */ 377 reg_w(sd, 0x2b, v1 >> 16); /* V buf.1, high */
409 378
410 ret += reg_w(sd, 0x32, y1 & 0xffff); /* JPEG buf 0 low */ 379 reg_w(sd, 0x32, y1 & 0xffff); /* JPEG buf 0 low */
411 ret += reg_w(sd, 0x33, y1 >> 16); /* JPEG buf 0 high */ 380 reg_w(sd, 0x33, y1 >> 16); /* JPEG buf 0 high */
412 381
413 ret += reg_w(sd, 0x34, y1 & 0xffff); /* JPEG buf 1 low */ 382 reg_w(sd, 0x34, y1 & 0xffff); /* JPEG buf 1 low */
414 ret += reg_w(sd, 0x35, y1 >> 16); /* JPEG bug 1 high */ 383 reg_w(sd, 0x35, y1 >> 16); /* JPEG bug 1 high */
415 384
416 ret += reg_w(sd, 0x36, 0x0000);/* JPEG restart interval */ 385 reg_w(sd, 0x36, 0x0000);/* JPEG restart interval */
417 ret += reg_w(sd, 0x37, 0x0804);/*JPEG VLE FIFO threshold*/ 386 reg_w(sd, 0x37, 0x0804);/*JPEG VLE FIFO threshold*/
418 ret += reg_w(sd, 0x38, 0x0000);/* disable hw up-scaling */ 387 reg_w(sd, 0x38, 0x0000);/* disable hw up-scaling */
419 ret += reg_w(sd, 0x3f, 0x0000); /* JPEG/MCTL test data */ 388 reg_w(sd, 0x3f, 0x0000); /* JPEG/MCTL test data */
420
421 return ret;
422} 389}
423 390
424static int w9968cf_set_crop_window(struct sd *sd) 391static void w9968cf_set_crop_window(struct sd *sd)
425{ 392{
426 int ret = 0, start_cropx, start_cropy, x, y, fw, fh, cw, ch, 393 int start_cropx, start_cropy, x, y, fw, fh, cw, ch,
427 max_width, max_height; 394 max_width, max_height;
428 395
429 if (sd->sif) { 396 if (sd->sif) {
@@ -456,8 +423,8 @@ static int w9968cf_set_crop_window(struct sd *sd)
456 fw = SC(sd->gspca_dev.width) / max_width; 423 fw = SC(sd->gspca_dev.width) / max_width;
457 fh = SC(sd->gspca_dev.height) / max_height; 424 fh = SC(sd->gspca_dev.height) / max_height;
458 425
459 cw = (fw >= fh) ? max_width : SC(sd->gspca_dev.width)/fh; 426 cw = (fw >= fh) ? max_width : SC(sd->gspca_dev.width) / fh;
460 ch = (fw >= fh) ? SC(sd->gspca_dev.height)/fw : max_height; 427 ch = (fw >= fh) ? SC(sd->gspca_dev.height) / fw : max_height;
461 428
462 sd->sensor_width = max_width; 429 sd->sensor_width = max_width;
463 sd->sensor_height = max_height; 430 sd->sensor_height = max_height;
@@ -465,42 +432,40 @@ static int w9968cf_set_crop_window(struct sd *sd)
465 x = (max_width - cw) / 2; 432 x = (max_width - cw) / 2;
466 y = (max_height - ch) / 2; 433 y = (max_height - ch) / 2;
467 434
468 ret += reg_w(sd, 0x10, start_cropx + x); 435 reg_w(sd, 0x10, start_cropx + x);
469 ret += reg_w(sd, 0x11, start_cropy + y); 436 reg_w(sd, 0x11, start_cropy + y);
470 ret += reg_w(sd, 0x12, start_cropx + x + cw); 437 reg_w(sd, 0x12, start_cropx + x + cw);
471 ret += reg_w(sd, 0x13, start_cropy + y + ch); 438 reg_w(sd, 0x13, start_cropy + y + ch);
472
473 return ret;
474} 439}
475 440
476static int w9968cf_mode_init_regs(struct sd *sd) 441static void w9968cf_mode_init_regs(struct sd *sd)
477{ 442{
478 int ret = 0, val, vs_polarity, hs_polarity; 443 int val, vs_polarity, hs_polarity;
479 444
480 ret += w9968cf_set_crop_window(sd); 445 w9968cf_set_crop_window(sd);
481 446
482 ret += reg_w(sd, 0x14, sd->gspca_dev.width); 447 reg_w(sd, 0x14, sd->gspca_dev.width);
483 ret += reg_w(sd, 0x15, sd->gspca_dev.height); 448 reg_w(sd, 0x15, sd->gspca_dev.height);
484 449
485 /* JPEG width & height */ 450 /* JPEG width & height */
486 ret += reg_w(sd, 0x30, sd->gspca_dev.width); 451 reg_w(sd, 0x30, sd->gspca_dev.width);
487 ret += reg_w(sd, 0x31, sd->gspca_dev.height); 452 reg_w(sd, 0x31, sd->gspca_dev.height);
488 453
489 /* Y & UV frame buffer strides (in WORD) */ 454 /* Y & UV frame buffer strides (in WORD) */
490 if (w9968cf_vga_mode[sd->gspca_dev.curr_mode].pixelformat == 455 if (w9968cf_vga_mode[sd->gspca_dev.curr_mode].pixelformat ==
491 V4L2_PIX_FMT_JPEG) { 456 V4L2_PIX_FMT_JPEG) {
492 ret += reg_w(sd, 0x2c, sd->gspca_dev.width/2); 457 reg_w(sd, 0x2c, sd->gspca_dev.width / 2);
493 ret += reg_w(sd, 0x2d, sd->gspca_dev.width/4); 458 reg_w(sd, 0x2d, sd->gspca_dev.width / 4);
494 } else 459 } else
495 ret += reg_w(sd, 0x2c, sd->gspca_dev.width); 460 reg_w(sd, 0x2c, sd->gspca_dev.width);
496 461
497 ret += reg_w(sd, 0x00, 0xbf17); /* reset everything */ 462 reg_w(sd, 0x00, 0xbf17); /* reset everything */
498 ret += reg_w(sd, 0x00, 0xbf10); /* normal operation */ 463 reg_w(sd, 0x00, 0xbf10); /* normal operation */
499 464
500 /* Transfer size in WORDS (for UYVY format only) */ 465 /* Transfer size in WORDS (for UYVY format only) */
501 val = sd->gspca_dev.width * sd->gspca_dev.height; 466 val = sd->gspca_dev.width * sd->gspca_dev.height;
502 ret += reg_w(sd, 0x3d, val & 0xffff); /* low bits */ 467 reg_w(sd, 0x3d, val & 0xffff); /* low bits */
503 ret += reg_w(sd, 0x3e, val >> 16); /* high bits */ 468 reg_w(sd, 0x3e, val >> 16); /* high bits */
504 469
505 if (w9968cf_vga_mode[sd->gspca_dev.curr_mode].pixelformat == 470 if (w9968cf_vga_mode[sd->gspca_dev.curr_mode].pixelformat ==
506 V4L2_PIX_FMT_JPEG) { 471 V4L2_PIX_FMT_JPEG) {
@@ -508,7 +473,7 @@ static int w9968cf_mode_init_regs(struct sd *sd)
508 jpeg_define(sd->jpeg_hdr, sd->gspca_dev.height, 473 jpeg_define(sd->jpeg_hdr, sd->gspca_dev.height,
509 sd->gspca_dev.width, 0x22); /* JPEG 420 */ 474 sd->gspca_dev.width, 0x22); /* JPEG 420 */
510 jpeg_set_qual(sd->jpeg_hdr, sd->quality); 475 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
511 ret += w9968cf_upload_quantizationtables(sd); 476 w9968cf_upload_quantizationtables(sd);
512 } 477 }
513 478
514 /* Video Capture Control Register */ 479 /* Video Capture Control Register */
@@ -540,19 +505,15 @@ static int w9968cf_mode_init_regs(struct sd *sd)
540 505
541 val |= 0x8000; /* capt. enable */ 506 val |= 0x8000; /* capt. enable */
542 507
543 ret += reg_w(sd, 0x16, val); 508 reg_w(sd, 0x16, val);
544 509
545 sd->gspca_dev.empty_packet = 0; 510 sd->gspca_dev.empty_packet = 0;
546
547 return ret;
548} 511}
549 512
550static void w9968cf_stop0(struct sd *sd) 513static void w9968cf_stop0(struct sd *sd)
551{ 514{
552 if (sd->gspca_dev.present) { 515 reg_w(sd, 0x39, 0x0000); /* disable JPEG encoder */
553 reg_w(sd, 0x39, 0x0000); /* disable JPEG encoder */ 516 reg_w(sd, 0x16, 0x0000); /* stop video capture */
554 reg_w(sd, 0x16, 0x0000); /* stop video capture */
555 }
556} 517}
557 518
558/* The w9968cf docs say that a 0 sized packet means EOF (and also SOF 519/* The w9968cf docs say that a 0 sized packet means EOF (and also SOF