Lines Matching +full:1 +full:- +full:sd
1 // SPDX-License-Identifier: GPL-2.0-or-later
10 * Copyright (C) 2002-2004 by Luca Risolia <luca.risolia@studio.unibo.it>
24 #define Y_QUANTABLE (&sd->jpeg_hdr[JPEG_QT0_OFFSET])
25 #define UV_QUANTABLE (&sd->jpeg_hdr[JPEG_QT1_OFFSET])
50 static void reg_w(struct sd *sd, u16 index, u16 value);
52 /*--------------------------------------------------------------------------
53 Write 64-bit data to the fast serial bus registers.
54 Return 0 on success, -1 otherwise.
55 --------------------------------------------------------------------------*/
56 static void w9968cf_write_fsb(struct sd *sd, u16* data) in w9968cf_write_fsb() argument
58 struct usb_device *udev = sd->gspca_dev.dev; in w9968cf_write_fsb()
62 if (sd->gspca_dev.usb_err < 0) in w9968cf_write_fsb()
66 memcpy(sd->gspca_dev.usb_buf, data, 6); in w9968cf_write_fsb()
72 value, 0x06, sd->gspca_dev.usb_buf, 6, 500); in w9968cf_write_fsb()
75 sd->gspca_dev.usb_err = ret; in w9968cf_write_fsb()
79 /*--------------------------------------------------------------------------
82 --------------------------------------------------------------------------*/
83 static void w9968cf_write_sb(struct sd *sd, u16 value) in w9968cf_write_sb() argument
87 if (sd->gspca_dev.usb_err < 0) in w9968cf_write_sb()
95 ret = usb_control_msg(sd->gspca_dev.dev, in w9968cf_write_sb()
96 usb_sndctrlpipe(sd->gspca_dev.dev, 0), in w9968cf_write_sb()
105 sd->gspca_dev.usb_err = ret; in w9968cf_write_sb()
109 /*--------------------------------------------------------------------------
112 --------------------------------------------------------------------------*/
113 static int w9968cf_read_sb(struct sd *sd) in w9968cf_read_sb() argument
117 if (sd->gspca_dev.usb_err < 0) in w9968cf_read_sb()
118 return -1; in w9968cf_read_sb()
125 ret = usb_control_msg(sd->gspca_dev.dev, in w9968cf_read_sb()
126 usb_rcvctrlpipe(sd->gspca_dev.dev, 0), in w9968cf_read_sb()
127 1, in w9968cf_read_sb()
129 0, 0x01, sd->gspca_dev.usb_buf, 2, 500); in w9968cf_read_sb()
131 ret = sd->gspca_dev.usb_buf[0] | in w9968cf_read_sb()
132 (sd->gspca_dev.usb_buf[1] << 8); in w9968cf_read_sb()
135 sd->gspca_dev.usb_err = ret; in w9968cf_read_sb()
140 memset(sd->gspca_dev.usb_buf, 0, 2); in w9968cf_read_sb()
148 /*--------------------------------------------------------------------------
152 --------------------------------------------------------------------------*/
153 static void w9968cf_upload_quantizationtables(struct sd *sd) in w9968cf_upload_quantizationtables() argument
158 reg_w(sd, 0x39, 0x0010); /* JPEG clock enable */ in w9968cf_upload_quantizationtables()
161 a = Y_QUANTABLE[j] | ((unsigned)(Y_QUANTABLE[j + 1]) << 8); in w9968cf_upload_quantizationtables()
162 b = UV_QUANTABLE[j] | ((unsigned)(UV_QUANTABLE[j + 1]) << 8); in w9968cf_upload_quantizationtables()
163 reg_w(sd, 0x40 + i, a); in w9968cf_upload_quantizationtables()
164 reg_w(sd, 0x60 + i, b); in w9968cf_upload_quantizationtables()
166 reg_w(sd, 0x39, 0x0012); /* JPEG encoder enable */ in w9968cf_upload_quantizationtables()
170 * Low-level I2C I/O functions. *
177 static void w9968cf_smbus_start(struct sd *sd) in w9968cf_smbus_start() argument
179 w9968cf_write_sb(sd, 0x0011); /* SDE=1, SDA=0, SCL=1 */ in w9968cf_smbus_start()
180 w9968cf_write_sb(sd, 0x0010); /* SDE=1, SDA=0, SCL=0 */ in w9968cf_smbus_start()
183 static void w9968cf_smbus_stop(struct sd *sd) in w9968cf_smbus_stop() argument
185 w9968cf_write_sb(sd, 0x0010); /* SDE=1, SDA=0, SCL=0 */ in w9968cf_smbus_stop()
186 w9968cf_write_sb(sd, 0x0011); /* SDE=1, SDA=0, SCL=1 */ in w9968cf_smbus_stop()
187 w9968cf_write_sb(sd, 0x0013); /* SDE=1, SDA=1, SCL=1 */ in w9968cf_smbus_stop()
190 static void w9968cf_smbus_write_byte(struct sd *sd, u8 v) in w9968cf_smbus_write_byte() argument
197 v <<= 1; in w9968cf_smbus_write_byte()
198 /* SDE=1, SDA=sda, SCL=0 */ in w9968cf_smbus_write_byte()
199 w9968cf_write_sb(sd, 0x10 | sda); in w9968cf_smbus_write_byte()
200 /* SDE=1, SDA=sda, SCL=1 */ in w9968cf_smbus_write_byte()
201 w9968cf_write_sb(sd, 0x11 | sda); in w9968cf_smbus_write_byte()
202 /* SDE=1, SDA=sda, SCL=0 */ in w9968cf_smbus_write_byte()
203 w9968cf_write_sb(sd, 0x10 | sda); in w9968cf_smbus_write_byte()
207 static void w9968cf_smbus_read_byte(struct sd *sd, u8 *v) in w9968cf_smbus_read_byte() argument
215 *v <<= 1; in w9968cf_smbus_read_byte()
216 /* SDE=1, SDA=1, SCL=1 */ in w9968cf_smbus_read_byte()
217 w9968cf_write_sb(sd, 0x0013); in w9968cf_smbus_read_byte()
218 *v |= (w9968cf_read_sb(sd) & 0x0008) ? 1 : 0; in w9968cf_smbus_read_byte()
219 /* SDE=1, SDA=1, SCL=0 */ in w9968cf_smbus_read_byte()
220 w9968cf_write_sb(sd, 0x0012); in w9968cf_smbus_read_byte()
224 static void w9968cf_smbus_write_nack(struct sd *sd) in w9968cf_smbus_write_nack() argument
228 w9968cf_write_sb(sd, 0x0013); /* SDE=1, SDA=1, SCL=1 */ in w9968cf_smbus_write_nack()
229 w9968cf_write_sb(sd, 0x0012); /* SDE=1, SDA=1, SCL=0 */ in w9968cf_smbus_write_nack()
232 static void w9968cf_smbus_read_ack(struct sd *sd) in w9968cf_smbus_read_ack() argument
234 struct gspca_dev *gspca_dev = (struct gspca_dev *)sd; in w9968cf_smbus_read_ack()
238 w9968cf_write_sb(sd, 0x0012); /* SDE=1, SDA=1, SCL=0 */ in w9968cf_smbus_read_ack()
239 w9968cf_write_sb(sd, 0x0013); /* SDE=1, SDA=1, SCL=1 */ in w9968cf_smbus_read_ack()
240 sda = w9968cf_read_sb(sd); in w9968cf_smbus_read_ack()
241 w9968cf_write_sb(sd, 0x0012); /* SDE=1, SDA=1, SCL=0 */ in w9968cf_smbus_read_ack()
244 sd->gspca_dev.usb_err = -EIO; in w9968cf_smbus_read_ack()
249 static void w9968cf_i2c_w(struct sd *sd, u8 reg, u8 value) in w9968cf_i2c_w() argument
251 struct gspca_dev *gspca_dev = (struct gspca_dev *)sd; in w9968cf_i2c_w()
252 u16* data = (u16 *)sd->gspca_dev.usb_buf; in w9968cf_i2c_w()
254 data[0] = 0x082f | ((sd->sensor_addr & 0x80) ? 0x1500 : 0x0); in w9968cf_i2c_w()
255 data[0] |= (sd->sensor_addr & 0x40) ? 0x4000 : 0x0; in w9968cf_i2c_w()
256 data[1] = 0x2082 | ((sd->sensor_addr & 0x40) ? 0x0005 : 0x0); in w9968cf_i2c_w()
257 data[1] |= (sd->sensor_addr & 0x20) ? 0x0150 : 0x0; in w9968cf_i2c_w()
258 data[1] |= (sd->sensor_addr & 0x10) ? 0x5400 : 0x0; in w9968cf_i2c_w()
259 data[2] = 0x8208 | ((sd->sensor_addr & 0x08) ? 0x0015 : 0x0); in w9968cf_i2c_w()
260 data[2] |= (sd->sensor_addr & 0x04) ? 0x0540 : 0x0; in w9968cf_i2c_w()
261 data[2] |= (sd->sensor_addr & 0x02) ? 0x5000 : 0x0; in w9968cf_i2c_w()
262 data[3] = 0x1d20 | ((sd->sensor_addr & 0x02) ? 0x0001 : 0x0); in w9968cf_i2c_w()
263 data[3] |= (sd->sensor_addr & 0x01) ? 0x0054 : 0x0; in w9968cf_i2c_w()
265 w9968cf_write_fsb(sd, data); in w9968cf_i2c_w()
270 data[1] = 0x0820 | ((reg & 0x20) ? 0x0001 : 0x0); in w9968cf_i2c_w()
271 data[1] |= (reg & 0x10) ? 0x0054 : 0x0; in w9968cf_i2c_w()
272 data[1] |= (reg & 0x08) ? 0x1500 : 0x0; in w9968cf_i2c_w()
273 data[1] |= (reg & 0x04) ? 0x4000 : 0x0; in w9968cf_i2c_w()
279 w9968cf_write_fsb(sd, data); in w9968cf_i2c_w()
284 data[1] = 0x0820 | ((value & 0x20) ? 0x0001 : 0x0); in w9968cf_i2c_w()
285 data[1] |= (value & 0x10) ? 0x0054 : 0x0; in w9968cf_i2c_w()
286 data[1] |= (value & 0x08) ? 0x1500 : 0x0; in w9968cf_i2c_w()
287 data[1] |= (value & 0x04) ? 0x4000 : 0x0; in w9968cf_i2c_w()
293 w9968cf_write_fsb(sd, data); in w9968cf_i2c_w()
295 gspca_dbg(gspca_dev, D_USBO, "i2c 0x%02x -> [0x%02x]\n", value, reg); in w9968cf_i2c_w()
298 /* SMBus protocol: S Addr Wr [A] Subaddr [A] P S Addr+1 Rd [A] [Value] NA P */
299 static int w9968cf_i2c_r(struct sd *sd, u8 reg) in w9968cf_i2c_r() argument
301 struct gspca_dev *gspca_dev = (struct gspca_dev *)sd; in w9968cf_i2c_r()
306 w9968cf_write_sb(sd, 0x0013); /* don't change ! */ in w9968cf_i2c_r()
308 w9968cf_smbus_start(sd); in w9968cf_i2c_r()
309 w9968cf_smbus_write_byte(sd, sd->sensor_addr); in w9968cf_i2c_r()
310 w9968cf_smbus_read_ack(sd); in w9968cf_i2c_r()
311 w9968cf_smbus_write_byte(sd, reg); in w9968cf_i2c_r()
312 w9968cf_smbus_read_ack(sd); in w9968cf_i2c_r()
313 w9968cf_smbus_stop(sd); in w9968cf_i2c_r()
314 w9968cf_smbus_start(sd); in w9968cf_i2c_r()
315 w9968cf_smbus_write_byte(sd, sd->sensor_addr + 1); in w9968cf_i2c_r()
316 w9968cf_smbus_read_ack(sd); in w9968cf_i2c_r()
317 w9968cf_smbus_read_byte(sd, &value); in w9968cf_i2c_r()
321 w9968cf_smbus_write_nack(sd); in w9968cf_i2c_r()
322 w9968cf_smbus_stop(sd); in w9968cf_i2c_r()
324 /* Fast serial bus data control re-enable */ in w9968cf_i2c_r()
325 w9968cf_write_sb(sd, 0x0030); in w9968cf_i2c_r()
327 if (sd->gspca_dev.usb_err >= 0) { in w9968cf_i2c_r()
329 gspca_dbg(gspca_dev, D_USBI, "i2c [0x%02X] -> 0x%02X\n", in w9968cf_i2c_r()
337 /*--------------------------------------------------------------------------
340 --------------------------------------------------------------------------*/
341 static void w9968cf_configure(struct sd *sd) in w9968cf_configure() argument
343 reg_w(sd, 0x00, 0xff00); /* power-down */ in w9968cf_configure()
344 reg_w(sd, 0x00, 0xbf17); /* reset everything */ in w9968cf_configure()
345 reg_w(sd, 0x00, 0xbf10); /* normal operation */ in w9968cf_configure()
346 reg_w(sd, 0x01, 0x0010); /* serial bus, SDS high */ in w9968cf_configure()
347 reg_w(sd, 0x01, 0x0000); /* serial bus, SDS low */ in w9968cf_configure()
348 reg_w(sd, 0x01, 0x0010); /* ..high 'beep-beep' */ in w9968cf_configure()
349 reg_w(sd, 0x01, 0x0030); /* Set sda scl to FSB mode */ in w9968cf_configure()
351 sd->stopped = 1; in w9968cf_configure()
354 static void w9968cf_init(struct sd *sd) in w9968cf_init() argument
356 unsigned long hw_bufsize = sd->sif ? (352 * 288 * 2) : (640 * 480 * 2), in w9968cf_init()
364 reg_w(sd, 0x00, 0xff00); /* power off */ in w9968cf_init()
365 reg_w(sd, 0x00, 0xbf10); /* power on */ in w9968cf_init()
367 reg_w(sd, 0x03, 0x405d); /* DRAM timings */ in w9968cf_init()
368 reg_w(sd, 0x04, 0x0030); /* SDRAM timings */ in w9968cf_init()
370 reg_w(sd, 0x20, y0 & 0xffff); /* Y buf.0, low */ in w9968cf_init()
371 reg_w(sd, 0x21, y0 >> 16); /* Y buf.0, high */ in w9968cf_init()
372 reg_w(sd, 0x24, u0 & 0xffff); /* U buf.0, low */ in w9968cf_init()
373 reg_w(sd, 0x25, u0 >> 16); /* U buf.0, high */ in w9968cf_init()
374 reg_w(sd, 0x28, v0 & 0xffff); /* V buf.0, low */ in w9968cf_init()
375 reg_w(sd, 0x29, v0 >> 16); /* V buf.0, high */ in w9968cf_init()
377 reg_w(sd, 0x22, y1 & 0xffff); /* Y buf.1, low */ in w9968cf_init()
378 reg_w(sd, 0x23, y1 >> 16); /* Y buf.1, high */ in w9968cf_init()
379 reg_w(sd, 0x26, u1 & 0xffff); /* U buf.1, low */ in w9968cf_init()
380 reg_w(sd, 0x27, u1 >> 16); /* U buf.1, high */ in w9968cf_init()
381 reg_w(sd, 0x2a, v1 & 0xffff); /* V buf.1, low */ in w9968cf_init()
382 reg_w(sd, 0x2b, v1 >> 16); /* V buf.1, high */ in w9968cf_init()
384 reg_w(sd, 0x32, y1 & 0xffff); /* JPEG buf 0 low */ in w9968cf_init()
385 reg_w(sd, 0x33, y1 >> 16); /* JPEG buf 0 high */ in w9968cf_init()
387 reg_w(sd, 0x34, y1 & 0xffff); /* JPEG buf 1 low */ in w9968cf_init()
388 reg_w(sd, 0x35, y1 >> 16); /* JPEG bug 1 high */ in w9968cf_init()
390 reg_w(sd, 0x36, 0x0000);/* JPEG restart interval */ in w9968cf_init()
391 reg_w(sd, 0x37, 0x0804);/*JPEG VLE FIFO threshold*/ in w9968cf_init()
392 reg_w(sd, 0x38, 0x0000);/* disable hw up-scaling */ in w9968cf_init()
393 reg_w(sd, 0x3f, 0x0000); /* JPEG/MCTL test data */ in w9968cf_init()
396 static void w9968cf_set_crop_window(struct sd *sd) in w9968cf_set_crop_window() argument
401 if (sd->sif) { in w9968cf_set_crop_window()
409 if (sd->sensor == SEN_OV7620) { in w9968cf_set_crop_window()
417 if (sd->freq->val == 1) { in w9968cf_set_crop_window()
433 fw = SC(sd->gspca_dev.pixfmt.width) / max_width; in w9968cf_set_crop_window()
434 fh = SC(sd->gspca_dev.pixfmt.height) / max_height; in w9968cf_set_crop_window()
436 cw = (fw >= fh) ? max_width : SC(sd->gspca_dev.pixfmt.width) / fh; in w9968cf_set_crop_window()
437 ch = (fw >= fh) ? SC(sd->gspca_dev.pixfmt.height) / fw : max_height; in w9968cf_set_crop_window()
439 sd->sensor_width = max_width; in w9968cf_set_crop_window()
440 sd->sensor_height = max_height; in w9968cf_set_crop_window()
442 x = (max_width - cw) / 2; in w9968cf_set_crop_window()
443 y = (max_height - ch) / 2; in w9968cf_set_crop_window()
445 reg_w(sd, 0x10, start_cropx + x); in w9968cf_set_crop_window()
446 reg_w(sd, 0x11, start_cropy + y); in w9968cf_set_crop_window()
447 reg_w(sd, 0x12, start_cropx + x + cw); in w9968cf_set_crop_window()
448 reg_w(sd, 0x13, start_cropy + y + ch); in w9968cf_set_crop_window()
451 static void w9968cf_mode_init_regs(struct sd *sd) in w9968cf_mode_init_regs() argument
455 w9968cf_set_crop_window(sd); in w9968cf_mode_init_regs()
457 reg_w(sd, 0x14, sd->gspca_dev.pixfmt.width); in w9968cf_mode_init_regs()
458 reg_w(sd, 0x15, sd->gspca_dev.pixfmt.height); in w9968cf_mode_init_regs()
461 reg_w(sd, 0x30, sd->gspca_dev.pixfmt.width); in w9968cf_mode_init_regs()
462 reg_w(sd, 0x31, sd->gspca_dev.pixfmt.height); in w9968cf_mode_init_regs()
465 if (w9968cf_vga_mode[sd->gspca_dev.curr_mode].pixelformat == in w9968cf_mode_init_regs()
467 reg_w(sd, 0x2c, sd->gspca_dev.pixfmt.width / 2); in w9968cf_mode_init_regs()
468 reg_w(sd, 0x2d, sd->gspca_dev.pixfmt.width / 4); in w9968cf_mode_init_regs()
470 reg_w(sd, 0x2c, sd->gspca_dev.pixfmt.width); in w9968cf_mode_init_regs()
472 reg_w(sd, 0x00, 0xbf17); /* reset everything */ in w9968cf_mode_init_regs()
473 reg_w(sd, 0x00, 0xbf10); /* normal operation */ in w9968cf_mode_init_regs()
476 val = sd->gspca_dev.pixfmt.width * sd->gspca_dev.pixfmt.height; in w9968cf_mode_init_regs()
477 reg_w(sd, 0x3d, val & 0xffff); /* low bits */ in w9968cf_mode_init_regs()
478 reg_w(sd, 0x3e, val >> 16); /* high bits */ in w9968cf_mode_init_regs()
480 if (w9968cf_vga_mode[sd->gspca_dev.curr_mode].pixelformat == in w9968cf_mode_init_regs()
483 jpeg_define(sd->jpeg_hdr, sd->gspca_dev.pixfmt.height, in w9968cf_mode_init_regs()
484 sd->gspca_dev.pixfmt.width, 0x22); /* JPEG 420 */ in w9968cf_mode_init_regs()
485 jpeg_set_qual(sd->jpeg_hdr, v4l2_ctrl_g_ctrl(sd->jpegqual)); in w9968cf_mode_init_regs()
486 w9968cf_upload_quantizationtables(sd); in w9968cf_mode_init_regs()
487 v4l2_ctrl_grab(sd->jpegqual, true); in w9968cf_mode_init_regs()
491 if (sd->sensor == SEN_OV7620) { in w9968cf_mode_init_regs()
493 vs_polarity = 1; in w9968cf_mode_init_regs()
494 hs_polarity = 1; in w9968cf_mode_init_regs()
496 vs_polarity = 1; in w9968cf_mode_init_regs()
506 if (w9968cf_vga_mode[sd->gspca_dev.curr_mode].pixelformat == in w9968cf_mode_init_regs()
514 /* val |= 0x0008; enable (1-2-1) filter */ in w9968cf_mode_init_regs()
515 /* val |= 0x000c; enable (2-3-6-3-2) filter */ in w9968cf_mode_init_regs()
519 reg_w(sd, 0x16, val); in w9968cf_mode_init_regs()
521 sd->gspca_dev.empty_packet = 0; in w9968cf_mode_init_regs()
524 static void w9968cf_stop0(struct sd *sd) in w9968cf_stop0() argument
526 v4l2_ctrl_grab(sd->jpegqual, false); in w9968cf_stop0()
527 reg_w(sd, 0x39, 0x0000); /* disable JPEG encoder */ in w9968cf_stop0()
528 reg_w(sd, 0x16, 0x0000); /* stop video capture */ in w9968cf_stop0()
537 to be precise it sends: SOI, SOF, DRI, SOS, Y-data, SOS, U-data, SOS,
538 V-data, EOI. */
543 struct sd *sd = (struct sd *) gspca_dev; in w9968cf_pkt_scan() local
545 if (w9968cf_vga_mode[gspca_dev->curr_mode].pixelformat == in w9968cf_pkt_scan()
549 data[1] == 0xd8) { in w9968cf_pkt_scan()
553 sd->jpeg_hdr, JPEG_HDR_SZ); in w9968cf_pkt_scan()
556 len -= 2; in w9968cf_pkt_scan()
561 if (gspca_dev->empty_packet) { in w9968cf_pkt_scan()
566 gspca_dev->empty_packet = 0; in w9968cf_pkt_scan()