linux/drivers/media/usb/gspca/ov519.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * OV519 driver
 *
 * Copyright (C) 2008-2011 Jean-François Moine <[email protected]>
 * Copyright (C) 2009 Hans de Goede <[email protected]>
 *
 * This module is adapted from the ov51x-jpeg package, which itself
 * was adapted from the ov511 driver.
 *
 * Original copyright for the ov511 driver is:
 *
 * Copyright (c) 1999-2006 Mark W. McClelland
 * Support for OV519, OV8610 Copyright (c) 2003 Joerg Heckenbach
 * Many improvements by Bret Wallach <[email protected]>
 * Color fixes by by Orion Sky Lawlor <[email protected]> (2/26/2000)
 * OV7620 fixes by Charl P. Botha <[email protected]>
 * Changes by Claudio Matsuoka <[email protected]>
 *
 * ov51x-jpeg original copyright is:
 *
 * Copyright (c) 2004-2007 Romain Beauxis <[email protected]>
 * Support for OV7670 sensors was contributed by Sam Skipsey <[email protected]>
 */

#define pr_fmt(fmt)

#define MODULE_NAME

#include <linux/input.h>
#include "gspca.h"

/* The jpeg_hdr is used by w996Xcf only */
/* The CONEX_CAM define for jpeg.h needs renaming, now its used here too */
#define CONEX_CAM
#include "jpeg.h"

MODULE_AUTHOR();
MODULE_DESCRIPTION();
MODULE_LICENSE();

/* global parameters */
static int frame_rate;

/* Number of times to retry a failed I2C transaction. Increase this if you
 * are getting "Failed to read sensor ID..." */
static int i2c_detect_tries =;

/* ov519 device descriptor */
struct sd {};
enum sensors {};

/* Note this is a bit of a hack, but the w9968cf driver needs the code for all
   the ov sensors which is already present here. When we have the time we
   really should move the sensor drivers to v4l2 sub drivers. */
#include "w996Xcf.c"

/* table of the disabled controls */
struct ctrl_valid {};

static const struct ctrl_valid valid_controls[] =;

static const struct v4l2_pix_format ov519_vga_mode[] =;
static const struct v4l2_pix_format ov519_sif_mode[] =;

/* Note some of the sizeimage values for the ov511 / ov518 may seem
   larger then necessary, however they need to be this big as the ov511 /
   ov518 always fills the entire isoc frame, using 0 padding bytes when
   it doesn't have any data. So with low framerates the amount of data
   transferred can become quite large (libv4l will remove all the 0 padding
   in userspace). */
static const struct v4l2_pix_format ov518_vga_mode[] =;
static const struct v4l2_pix_format ov518_sif_mode[] =;

static const struct v4l2_pix_format ov511_vga_mode[] =;
static const struct v4l2_pix_format ov511_sif_mode[] =;

static const struct v4l2_pix_format ovfx2_ov2610_mode[] =;
static const struct v4l2_pix_format ovfx2_ov3610_mode[] =;
static const struct v4l2_pix_format ovfx2_ov9600_mode[] =;

/* Registers common to OV511 / OV518 */
#define R51x_FIFO_PSIZE
#define R51x_SYS_RESET
	/* Reset type flags */
	#define OV511_RESET_OMNICE
#define R51x_SYS_INIT
#define R51x_SYS_SNAP
#define R51x_SYS_CUST_ID
#define R51x_COMP_LUT_BEGIN

/* OV511 Camera interface register numbers */
#define R511_CAM_DELAY
#define R511_CAM_EDGE
#define R511_CAM_PXCNT
#define R511_CAM_LNCNT
#define R511_CAM_PXDIV
#define R511_CAM_LNDIV
#define R511_CAM_UV_EN
#define R511_CAM_LINE_MODE
#define R511_CAM_OPTS

#define R511_SNAP_FRAME
#define R511_SNAP_PXCNT
#define R511_SNAP_LNCNT
#define R511_SNAP_PXDIV
#define R511_SNAP_LNDIV
#define R511_SNAP_UV_EN
#define R511_SNAP_OPTS

#define R511_DRAM_FLOW_CTL
#define R511_FIFO_OPTS
#define R511_I2C_CTL
#define R511_SYS_LED_CTL
#define R511_COMP_EN
#define R511_COMP_LUT_EN

/* OV518 Camera interface register numbers */
#define R518_GPIO_OUT
#define R518_GPIO_CTL

/* OV519 Camera interface register numbers */
#define OV519_R10_H_SIZE
#define OV519_R11_V_SIZE
#define OV519_R12_X_OFFSETL
#define OV519_R13_X_OFFSETH
#define OV519_R14_Y_OFFSETL
#define OV519_R15_Y_OFFSETH
#define OV519_R16_DIVIDER
#define OV519_R20_DFR
#define OV519_R25_FORMAT

/* OV519 System Controller register numbers */
#define OV519_R51_RESET1
#define OV519_R54_EN_CLK1
#define OV519_R57_SNAPSHOT

#define OV519_GPIO_DATA_OUT0
#define OV519_GPIO_IO_CTRL0

/*#define OV511_ENDPOINT_ADDRESS 1	 * Isoc endpoint number */

/*
 * The FX2 chip does not give us a zero length read at end of frame.
 * It does, however, give a short read at the end of a frame, if
 * necessary, rather than run two frames together.
 *
 * By choosing the right bulk transfer size, we are guaranteed to always
 * get a short read for the last read of each frame.  Frame sizes are
 * always a composite number (width * height, or a multiple) so if we
 * choose a prime number, we are guaranteed that the last read of a
 * frame will be short.
 *
 * But it isn't that easy: the 2.6 kernel requires a multiple of 4KB,
 * otherwise EOVERFLOW "babbling" errors occur.  I have not been able
 * to figure out why.  [PMiller]
 *
 * The constant (13 * 4096) is the largest "prime enough" number less than 64KB.
 *
 * It isn't enough to know the number of bytes per frame, in case we
 * have data dropouts or buffer overruns (even though the FX2 double
 * buffers, there are some pretty strict real time constraints for
 * isochronous transfer for larger frame sizes).
 */
/*jfm: this value does not work for 800x600 - see isoc_init */
#define OVFX2_BULK_SIZE

/* I2C registers */
#define R51x_I2C_W_SID
#define R51x_I2C_SADDR_3
#define R51x_I2C_SADDR_2
#define R51x_I2C_R_SID
#define R51x_I2C_DATA
#define R518_I2C_CTL
#define OVFX2_I2C_ADDR

/* I2C ADDRESSES */
#define OV7xx0_SID
#define OV_HIRES_SID
#define OV8xx0_SID
#define OV6xx0_SID

/* OV7610 registers */
#define OV7610_REG_GAIN
#define OV7610_REG_BLUE
#define OV7610_REG_RED
#define OV7610_REG_SAT
#define OV8610_REG_HUE
#define OV7610_REG_CNT
#define OV7610_REG_BRT
#define OV7610_REG_COM_C
#define OV7610_REG_ID_HIGH
#define OV7610_REG_ID_LOW
#define OV7610_REG_COM_I

/* OV7660 and OV7670 registers */
#define OV7670_R00_GAIN
#define OV7670_R01_BLUE
#define OV7670_R02_RED
#define OV7670_R03_VREF
#define OV7670_R04_COM1
/*#define OV7670_R07_AECHH	0x07	 * AEC MS 5 bits */
#define OV7670_R0C_COM3
#define OV7670_R0D_COM4
#define OV7670_R0E_COM5
#define OV7670_R0F_COM6
#define OV7670_R10_AECH
#define OV7670_R11_CLKRC
#define OV7670_R12_COM7
#define OV7670_COM7_FMT_VGA
/*#define   OV7670_COM7_YUV	 0x00	 * YUV */
#define OV7670_COM7_FMT_QVGA
#define OV7670_COM7_FMT_MASK
#define OV7670_COM7_RESET
#define OV7670_R13_COM8
#define OV7670_COM8_AEC
#define OV7670_COM8_AWB
#define OV7670_COM8_AGC
#define OV7670_COM8_BFILT
#define OV7670_COM8_AECSTEP
#define OV7670_COM8_FASTAEC
#define OV7670_R14_COM9
#define OV7670_R15_COM10
#define OV7670_R17_HSTART
#define OV7670_R18_HSTOP
#define OV7670_R19_VSTART
#define OV7670_R1A_VSTOP
#define OV7670_R1E_MVFP
#define OV7670_MVFP_VFLIP
#define OV7670_MVFP_MIRROR
#define OV7670_R24_AEW
#define OV7670_R25_AEB
#define OV7670_R26_VPT
#define OV7670_R32_HREF
#define OV7670_R3A_TSLB
#define OV7670_R3B_COM11
#define OV7670_COM11_EXP
#define OV7670_COM11_HZAUTO
#define OV7670_R3C_COM12
#define OV7670_R3D_COM13
#define OV7670_COM13_GAMMA
#define OV7670_COM13_UVSAT
#define OV7670_R3E_COM14
#define OV7670_R3F_EDGE
#define OV7670_R40_COM15
/*#define   OV7670_COM15_R00FF	 0xc0	 *	00 to FF */
#define OV7670_R41_COM16
#define OV7670_COM16_AWBGAIN
/* end of ov7660 common registers */
#define OV7670_R55_BRIGHT
#define OV7670_R56_CONTRAS
#define OV7670_R69_GFIX
/*#define OV7670_R8C_RGB444	0x8c	 * RGB 444 control */
#define OV7670_R9F_HAECC1
#define OV7670_RA0_HAECC2
#define OV7670_RA5_BD50MAX
#define OV7670_RA6_HAECC3
#define OV7670_RA7_HAECC4
#define OV7670_RA8_HAECC5
#define OV7670_RA9_HAECC6
#define OV7670_RAA_HAECC7
#define OV7670_RAB_BD60MAX

struct ov_regvals {};
struct ov_i2c_regvals {};

/* Settings for OV2610 camera chip */
static const struct ov_i2c_regvals norm_2610[] =;

static const struct ov_i2c_regvals norm_2610ae[] =;

static const struct ov_i2c_regvals norm_3620b[] =;

static const struct ov_i2c_regvals norm_6x20[] =;

static const struct ov_i2c_regvals norm_6x30[] =;

/* Lawrence Glaister <[email protected]> reports:
 *
 * Register 0x0f in the 7610 has the following effects:
 *
 * 0x85 (AEC method 1): Best overall, good contrast range
 * 0x45 (AEC method 2): Very overexposed
 * 0xa5 (spec sheet default): Ok, but the black level is
 *	shifted resulting in loss of contrast
 * 0x05 (old driver setting): very overexposed, too much
 *	contrast
 */
static const struct ov_i2c_regvals norm_7610[] =;

static const struct ov_i2c_regvals norm_7620[] =;

/* 7640 and 7648. The defaults should be OK for most registers. */
static const struct ov_i2c_regvals norm_7640[] =;

static const struct ov_regvals init_519_ov7660[] =;
static const struct ov_i2c_regvals norm_7660[] =;
static const struct ov_i2c_regvals norm_9600[] =;

/* 7670. Defaults taken from OmniVision provided data,
*  as provided by Jonathan Corbet of OLPC		*/
static const struct ov_i2c_regvals norm_7670[] =;

static const struct ov_i2c_regvals norm_8610[] =;

static unsigned char ov7670_abs_to_sm(unsigned char v)
{}

/* Write a OV519 register */
static void reg_w(struct sd *sd, u16 index, u16 value)
{}

/* Read from a OV519 register, note not valid for the w9968cf!! */
/* returns: negative is error, pos or zero is data */
static int reg_r(struct sd *sd, u16 index)
{}

/* Read 8 values from a OV519 register */
static int reg_r8(struct sd *sd,
		  u16 index)
{}

/*
 * Writes bits at positions specified by mask to an OV51x reg. Bits that are in
 * the same position as 1's in "mask" are cleared and set to "value". Bits
 * that are in the same position as 0's in "mask" are preserved, regardless
 * of their respective state in "value".
 */
static void reg_w_mask(struct sd *sd,
			u16 index,
			u8 value,
			u8 mask)
{}

/*
 * Writes multiple (n) byte value to a single register. Only valid with certain
 * registers (0x30 and 0xc4 - 0xce).
 */
static void ov518_reg_w32(struct sd *sd, u16 index, u32 value, int n)
{}

static void ov511_i2c_w(struct sd *sd, u8 reg, u8 value)
{}

static int ov511_i2c_r(struct sd *sd, u8 reg)
{}

/*
 * The OV518 I2C I/O procedure is different, hence, this function.
 * This is normally only called from i2c_w(). Note that this function
 * always succeeds regardless of whether the sensor is present and working.
 */
static void ov518_i2c_w(struct sd *sd,
		u8 reg,
		u8 value)
{}

/*
 * returns: negative is error, pos or zero is data
 *
 * The OV518 I2C I/O procedure is different, hence, this function.
 * This is normally only called from i2c_r(). Note that this function
 * always succeeds regardless of whether the sensor is present and working.
 */
static int ov518_i2c_r(struct sd *sd, u8 reg)
{}

static void ovfx2_i2c_w(struct sd *sd, u8 reg, u8 value)
{}

static int ovfx2_i2c_r(struct sd *sd, u8 reg)
{}

static void i2c_w(struct sd *sd, u8 reg, u8 value)
{}

static int i2c_r(struct sd *sd, u8 reg)
{}

/* Writes bits at positions specified by mask to an I2C reg. Bits that are in
 * the same position as 1's in "mask" are cleared and set to "value". Bits
 * that are in the same position as 0's in "mask" are preserved, regardless
 * of their respective state in "value".
 */
static void i2c_w_mask(struct sd *sd,
			u8 reg,
			u8 value,
			u8 mask)
{}

/* Temporarily stops OV511 from functioning. Must do this before changing
 * registers while the camera is streaming */
static inline void ov51x_stop(struct sd *sd)
{}

/* Restarts OV511 after ov511_stop() is called. Has no effect if it is not
 * actually stopped (for performance). */
static inline void ov51x_restart(struct sd *sd)
{}

static void ov51x_set_slave_ids(struct sd *sd, u8 slave);

/* This does an initial reset of an OmniVision sensor and ensures that I2C
 * is synchronized. Returns <0 on failure.
 */
static int init_ov_sensor(struct sd *sd, u8 slave)
{}

/* Set the read and write slave IDs. The "slave" argument is the write slave,
 * and the read slave will be set to (slave + 1).
 * This should not be called from outside the i2c I/O functions.
 * Sets I2C read and write slave IDs. Returns <0 for error
 */
static void ov51x_set_slave_ids(struct sd *sd,
				u8 slave)
{}

static void write_regvals(struct sd *sd,
			 const struct ov_regvals *regvals,
			 int n)
{}

static void write_i2c_regvals(struct sd *sd,
			const struct ov_i2c_regvals *regvals,
			int n)
{}

/****************************************************************************
 *
 * OV511 and sensor configuration
 *
 ***************************************************************************/

/* This initializes the OV2x10 / OV3610 / OV3620 / OV9600 */
static void ov_hires_configure(struct sd *sd)
{}

/* This initializes the OV8110, OV8610 sensor. The OV8110 uses
 * the same register settings as the OV8610, since they are very similar.
 */
static void ov8xx0_configure(struct sd *sd)
{}

/* This initializes the OV7610, OV7620, or OV76BE sensor. The OV76BE uses
 * the same register settings as the OV7610, since they are very similar.
 */
static void ov7xx0_configure(struct sd *sd)
{}

/* This initializes the OV6620, OV6630, OV6630AE, or OV6630AF sensor. */
static void ov6xx0_configure(struct sd *sd)
{}

/* Turns on or off the LED. Only has an effect with OV511+/OV518(+)/OV519 */
static void ov51x_led_control(struct sd *sd, int on)
{}

static void sd_reset_snapshot(struct gspca_dev *gspca_dev)
{}

static void ov51x_upload_quan_tables(struct sd *sd)
{}

/* This initializes the OV511/OV511+ and the sensor */
static void ov511_configure(struct gspca_dev *gspca_dev)
{}

/* This initializes the OV518/OV518+ and the sensor */
static void ov518_configure(struct gspca_dev *gspca_dev)
{}

static void ov519_configure(struct sd *sd)
{}

static void ovfx2_configure(struct sd *sd)
{}

/* set the mode */
/* This function works for ov7660 only */
static void ov519_set_mode(struct sd *sd)
{}

/* set the frame rate */
/* This function works for sensors ov7640, ov7648 ov7660 and ov7670 only */
static void ov519_set_fr(struct sd *sd)
{}

static void setautogain(struct gspca_dev *gspca_dev, s32 val)
{}

/* this function is called at probe time */
static int sd_config(struct gspca_dev *gspca_dev,
			const struct usb_device_id *id)
{}

/* this function is called at probe and resume time */
static int sd_init(struct gspca_dev *gspca_dev)
{}

/* function called at start time before URB creation */
static int sd_isoc_init(struct gspca_dev *gspca_dev)
{}

/* Set up the OV511/OV511+ with the given image parameters.
 *
 * Do not put any sensor-specific code in here (including I2C I/O functions)
 */
static void ov511_mode_init_regs(struct sd *sd)
{}

/* Sets up the OV518/OV518+ with the given image parameters
 *
 * OV518 needs a completely different approach, until we can figure out what
 * the individual registers do. Also, only 15 FPS is supported now.
 *
 * Do not put any sensor-specific code in here (including I2C I/O functions)
 */
static void ov518_mode_init_regs(struct sd *sd)
{}

/* Sets up the OV519 with the given image parameters
 *
 * OV519 needs a completely different approach, until we can figure out what
 * the individual registers do.
 *
 * Do not put any sensor-specific code in here (including I2C I/O functions)
 */
static void ov519_mode_init_regs(struct sd *sd)
{}

static void mode_init_ov_sensor_regs(struct sd *sd)
{}

/* this function works for bridge ov519 and sensors ov7660 and ov7670 only */
static void sethvflip(struct gspca_dev *gspca_dev, s32 hflip, s32 vflip)
{}

static void set_ov_sensor_window(struct sd *sd)
{}

/* -- start the camera -- */
static int sd_start(struct gspca_dev *gspca_dev)
{}

static void sd_stopN(struct gspca_dev *gspca_dev)
{}

static void sd_stop0(struct gspca_dev *gspca_dev)
{}

static void ov51x_handle_button(struct gspca_dev *gspca_dev, u8 state)
{}

static void ov511_pkt_scan(struct gspca_dev *gspca_dev,
			u8 *in,			/* isoc packet */
			int len)		/* iso packet length */
{}

static void ov518_pkt_scan(struct gspca_dev *gspca_dev,
			u8 *data,			/* isoc packet */
			int len)			/* iso packet length */
{}

static void ov519_pkt_scan(struct gspca_dev *gspca_dev,
			u8 *data,			/* isoc packet */
			int len)			/* iso packet length */
{}

static void ovfx2_pkt_scan(struct gspca_dev *gspca_dev,
			u8 *data,			/* isoc packet */
			int len)			/* iso packet length */
{}

static void sd_pkt_scan(struct gspca_dev *gspca_dev,
			u8 *data,			/* isoc packet */
			int len)			/* iso packet length */
{}

/* -- management routines -- */

static void setbrightness(struct gspca_dev *gspca_dev, s32 val)
{}

static void setcontrast(struct gspca_dev *gspca_dev, s32 val)
{}

static void setexposure(struct gspca_dev *gspca_dev, s32 val)
{}

static void setcolors(struct gspca_dev *gspca_dev, s32 val)
{}

static void setautobright(struct gspca_dev *gspca_dev, s32 val)
{}

static void setfreq_i(struct sd *sd, s32 val)
{}

static void setfreq(struct gspca_dev *gspca_dev, s32 val)
{}

static int sd_get_jcomp(struct gspca_dev *gspca_dev,
			struct v4l2_jpegcompression *jcomp)
{}

static int sd_set_jcomp(struct gspca_dev *gspca_dev,
			const struct v4l2_jpegcompression *jcomp)
{}

static int sd_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
{}

static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
{}

static const struct v4l2_ctrl_ops sd_ctrl_ops =;

static int sd_init_controls(struct gspca_dev *gspca_dev)
{}

/* sub-driver description */
static const struct sd_desc sd_desc =;

/* -- module initialisation -- */
static const struct usb_device_id device_table[] =;

MODULE_DEVICE_TABLE(usb, device_table);

/* -- device connect -- */
static int sd_probe(struct usb_interface *intf,
			const struct usb_device_id *id)
{}

static struct usb_driver sd_driver =;

module_usb_driver();

module_param(frame_rate, int, 0644);
MODULE_PARM_DESC();