// SPDX-License-Identifier: GPL-2.0-or-later /* * GSPCA sub driver for W996[78]CF JPEG USB Dual Mode Camera Chip. * * Copyright (C) 2009 Hans de Goede <[email protected]> * * This module is adapted from the in kernel v4l1 w9968cf driver: * * Copyright (C) 2002-2004 by Luca Risolia <[email protected]> */ /* Note this is not a stand alone driver, it gets included in ov519.c, this is a bit of a hack, but it needs the driver code for a lot of different ov sensors which is already present in ov519.c (the old v4l1 driver used the ovchipcam framework). When we have the time we really should move the sensor drivers to v4l2 sub drivers, and properly split of this driver from ov519.c */ #define pr_fmt(fmt) … #define W9968CF_I2C_BUS_DELAY … #define Y_QUANTABLE … #define UV_QUANTABLE … static const struct v4l2_pix_format w9968cf_vga_mode[] = …; static void reg_w(struct sd *sd, u16 index, u16 value); /*-------------------------------------------------------------------------- Write 64-bit data to the fast serial bus registers. Return 0 on success, -1 otherwise. --------------------------------------------------------------------------*/ static void w9968cf_write_fsb(struct sd *sd, u16* data) { … } /*-------------------------------------------------------------------------- Write data to the serial bus control register. Return 0 on success, a negative number otherwise. --------------------------------------------------------------------------*/ static void w9968cf_write_sb(struct sd *sd, u16 value) { … } /*-------------------------------------------------------------------------- Read data from the serial bus control register. Return 0 on success, a negative number otherwise. --------------------------------------------------------------------------*/ static int w9968cf_read_sb(struct sd *sd) { … } /*-------------------------------------------------------------------------- Upload quantization tables for the JPEG compression. This function is called by w9968cf_start_transfer(). Return 0 on success, a negative number otherwise. --------------------------------------------------------------------------*/ static void w9968cf_upload_quantizationtables(struct sd *sd) { … } /**************************************************************************** * Low-level I2C I/O functions. * * The adapter supports the following I2C transfer functions: * * i2c_adap_fastwrite_byte_data() (at 400 kHz bit frequency only) * * i2c_adap_read_byte_data() * * i2c_adap_read_byte() * ****************************************************************************/ static void w9968cf_smbus_start(struct sd *sd) { … } static void w9968cf_smbus_stop(struct sd *sd) { … } static void w9968cf_smbus_write_byte(struct sd *sd, u8 v) { … } static void w9968cf_smbus_read_byte(struct sd *sd, u8 *v) { … } static void w9968cf_smbus_write_nack(struct sd *sd) { … } static void w9968cf_smbus_read_ack(struct sd *sd) { … } /* SMBus protocol: S Addr Wr [A] Subaddr [A] Value [A] P */ static void w9968cf_i2c_w(struct sd *sd, u8 reg, u8 value) { … } /* SMBus protocol: S Addr Wr [A] Subaddr [A] P S Addr+1 Rd [A] [Value] NA P */ static int w9968cf_i2c_r(struct sd *sd, u8 reg) { … } /*-------------------------------------------------------------------------- Turn on the LED on some webcams. A beep should be heard too. Return 0 on success, a negative number otherwise. --------------------------------------------------------------------------*/ static void w9968cf_configure(struct sd *sd) { … } static void w9968cf_init(struct sd *sd) { … } static void w9968cf_set_crop_window(struct sd *sd) { … } static void w9968cf_mode_init_regs(struct sd *sd) { … } static void w9968cf_stop0(struct sd *sd) { … } /* The w9968cf docs say that a 0 sized packet means EOF (and also SOF for the next frame). This seems to simply not be true when operating in JPEG mode, in this case there may be empty packets within the frame. So in JPEG mode use the JPEG SOI marker to detect SOF. Note to make things even more interesting the w9968cf sends *PLANAR* jpeg, to be precise it sends: SOI, SOF, DRI, SOS, Y-data, SOS, U-data, SOS, V-data, EOI. */ static void w9968cf_pkt_scan(struct gspca_dev *gspca_dev, u8 *data, /* isoc packet */ int len) /* iso packet length */ { … }