308 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			308 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/***************************************************************************
 | 
						|
 * API for image sensors connected to the SN9C1xx PC Camera Controllers    *
 | 
						|
 *                                                                         *
 | 
						|
 * Copyright (C) 2004-2007 by Luca Risolia <luca.risolia@studio.unibo.it>  *
 | 
						|
 *                                                                         *
 | 
						|
 * This program is free software; you can redistribute it and/or modify    *
 | 
						|
 * it under the terms of the GNU General Public License as published by    *
 | 
						|
 * the Free Software Foundation; either version 2 of the License, or       *
 | 
						|
 * (at your option) any later version.                                     *
 | 
						|
 *                                                                         *
 | 
						|
 * This program is distributed in the hope that it will be useful,         *
 | 
						|
 * but WITHOUT ANY WARRANTY; without even the implied warranty of          *
 | 
						|
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           *
 | 
						|
 * GNU General Public License for more details.                            *
 | 
						|
 *                                                                         *
 | 
						|
 * You should have received a copy of the GNU General Public License       *
 | 
						|
 * along with this program; if not, write to the Free Software             *
 | 
						|
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.               *
 | 
						|
 ***************************************************************************/
 | 
						|
 | 
						|
#ifndef _SN9C102_SENSOR_H_
 | 
						|
#define _SN9C102_SENSOR_H_
 | 
						|
 | 
						|
#include <linux/usb.h>
 | 
						|
#include <linux/videodev2.h>
 | 
						|
#include <linux/device.h>
 | 
						|
#include <linux/stddef.h>
 | 
						|
#include <linux/errno.h>
 | 
						|
#include <asm/types.h>
 | 
						|
 | 
						|
struct sn9c102_device;
 | 
						|
struct sn9c102_sensor;
 | 
						|
 | 
						|
/*****************************************************************************/
 | 
						|
 | 
						|
/*
 | 
						|
   OVERVIEW.
 | 
						|
   This is a small interface that allows you to add support for any CCD/CMOS
 | 
						|
   image sensors connected to the SN9C1XX bridges. The entire API is documented
 | 
						|
   below. In the most general case, to support a sensor there are three steps
 | 
						|
   you have to follow:
 | 
						|
   1) define the main "sn9c102_sensor" structure by setting the basic fields;
 | 
						|
   2) write a probing function to be called by the core module when the USB
 | 
						|
      camera is recognized, then add both the USB ids and the name of that
 | 
						|
      function to the two corresponding tables in sn9c102_devtable.h;
 | 
						|
   3) implement the methods that you want/need (and fill the rest of the main
 | 
						|
      structure accordingly).
 | 
						|
   "sn9c102_pas106b.c" is an example of all this stuff. Remember that you do
 | 
						|
   NOT need to touch the source code of the core module for the things to work
 | 
						|
   properly, unless you find bugs or flaws in it. Finally, do not forget to
 | 
						|
   read the V4L2 API for completeness.
 | 
						|
*/
 | 
						|
 | 
						|
/*****************************************************************************/
 | 
						|
 | 
						|
enum sn9c102_bridge {
 | 
						|
	BRIDGE_SN9C101 = 0x01,
 | 
						|
	BRIDGE_SN9C102 = 0x02,
 | 
						|
	BRIDGE_SN9C103 = 0x04,
 | 
						|
	BRIDGE_SN9C105 = 0x08,
 | 
						|
	BRIDGE_SN9C120 = 0x10,
 | 
						|
};
 | 
						|
 | 
						|
/* Return the bridge name */
 | 
						|
enum sn9c102_bridge sn9c102_get_bridge(struct sn9c102_device* cam);
 | 
						|
 | 
						|
/* Return a pointer the sensor struct attached to the camera */
 | 
						|
struct sn9c102_sensor* sn9c102_get_sensor(struct sn9c102_device* cam);
 | 
						|
 | 
						|
/* Identify a device */
 | 
						|
extern struct sn9c102_device*
 | 
						|
sn9c102_match_id(struct sn9c102_device* cam, const struct usb_device_id *id);
 | 
						|
 | 
						|
/* Attach a probed sensor to the camera. */
 | 
						|
extern void
 | 
						|
sn9c102_attach_sensor(struct sn9c102_device* cam,
 | 
						|
		      const struct sn9c102_sensor* sensor);
 | 
						|
 | 
						|
/*
 | 
						|
   Read/write routines: they always return -1 on error, 0 or the read value
 | 
						|
   otherwise. NOTE that a real read operation is not supported by the SN9C1XX
 | 
						|
   chip for some of its registers. To work around this problem, a pseudo-read
 | 
						|
   call is provided instead: it returns the last successfully written value
 | 
						|
   on the register (0 if it has never been written), the usual -1 on error.
 | 
						|
*/
 | 
						|
 | 
						|
/* The "try" I2C I/O versions are used when probing the sensor */
 | 
						|
extern int sn9c102_i2c_try_read(struct sn9c102_device*,
 | 
						|
				const struct sn9c102_sensor*, u8 address);
 | 
						|
 | 
						|
/*
 | 
						|
   These must be used if and only if the sensor doesn't implement the standard
 | 
						|
   I2C protocol. There are a number of good reasons why you must use the
 | 
						|
   single-byte versions of these functions: do not abuse. The first function
 | 
						|
   writes n bytes, from data0 to datan, to registers 0x09 - 0x09+n of SN9C1XX
 | 
						|
   chip. The second one programs the registers 0x09 and 0x10 with data0 and
 | 
						|
   data1, and places the n bytes read from the sensor register table in the
 | 
						|
   buffer pointed by 'buffer'. Both the functions return -1 on error; the write
 | 
						|
   version returns 0 on success, while the read version returns the first read
 | 
						|
   byte.
 | 
						|
*/
 | 
						|
extern int sn9c102_i2c_try_raw_write(struct sn9c102_device* cam,
 | 
						|
				     const struct sn9c102_sensor* sensor, u8 n,
 | 
						|
				     u8 data0, u8 data1, u8 data2, u8 data3,
 | 
						|
				     u8 data4, u8 data5);
 | 
						|
extern int sn9c102_i2c_try_raw_read(struct sn9c102_device* cam,
 | 
						|
				    const struct sn9c102_sensor* sensor,
 | 
						|
				    u8 data0, u8 data1, u8 n, u8 buffer[]);
 | 
						|
 | 
						|
/* To be used after the sensor struct has been attached to the camera struct */
 | 
						|
extern int sn9c102_i2c_write(struct sn9c102_device*, u8 address, u8 value);
 | 
						|
extern int sn9c102_i2c_read(struct sn9c102_device*, u8 address);
 | 
						|
 | 
						|
/* I/O on registers in the bridge. Could be used by the sensor methods too */
 | 
						|
extern int sn9c102_read_reg(struct sn9c102_device*, u16 index);
 | 
						|
extern int sn9c102_pread_reg(struct sn9c102_device*, u16 index);
 | 
						|
extern int sn9c102_write_reg(struct sn9c102_device*, u8 value, u16 index);
 | 
						|
extern int sn9c102_write_regs(struct sn9c102_device*, const u8 valreg[][2],
 | 
						|
			      int count);
 | 
						|
/*
 | 
						|
   Write multiple registers with constant values. For example:
 | 
						|
   sn9c102_write_const_regs(cam, {0x00, 0x14}, {0x60, 0x17}, {0x0f, 0x18});
 | 
						|
   Register adresses must be < 256.
 | 
						|
*/
 | 
						|
#define sn9c102_write_const_regs(sn9c102_device, data...)                     \
 | 
						|
	({ static const u8 _valreg[][2] = {data};                             \
 | 
						|
	sn9c102_write_regs(sn9c102_device, _valreg, ARRAY_SIZE(_valreg)); })
 | 
						|
 | 
						|
/*****************************************************************************/
 | 
						|
 | 
						|
enum sn9c102_i2c_sysfs_ops {
 | 
						|
	SN9C102_I2C_READ = 0x01,
 | 
						|
	SN9C102_I2C_WRITE = 0x02,
 | 
						|
};
 | 
						|
 | 
						|
enum sn9c102_i2c_frequency { /* sensors may support both the frequencies */
 | 
						|
	SN9C102_I2C_100KHZ = 0x01,
 | 
						|
	SN9C102_I2C_400KHZ = 0x02,
 | 
						|
};
 | 
						|
 | 
						|
enum sn9c102_i2c_interface {
 | 
						|
	SN9C102_I2C_2WIRES,
 | 
						|
	SN9C102_I2C_3WIRES,
 | 
						|
};
 | 
						|
 | 
						|
#define SN9C102_MAX_CTRLS (V4L2_CID_LASTP1-V4L2_CID_BASE+10)
 | 
						|
 | 
						|
struct sn9c102_sensor {
 | 
						|
	char name[32], /* sensor name */
 | 
						|
	     maintainer[64]; /* name of the mantainer <email> */
 | 
						|
 | 
						|
	enum sn9c102_bridge supported_bridge; /* supported SN9C1xx bridges */
 | 
						|
 | 
						|
	/* Supported operations through the 'sysfs' interface */
 | 
						|
	enum sn9c102_i2c_sysfs_ops sysfs_ops;
 | 
						|
 | 
						|
	/*
 | 
						|
	   These sensor capabilities must be provided if the SN9C1XX controller
 | 
						|
	   needs to communicate through the sensor serial interface by using
 | 
						|
	   at least one of the i2c functions available.
 | 
						|
	*/
 | 
						|
	enum sn9c102_i2c_frequency frequency;
 | 
						|
	enum sn9c102_i2c_interface interface;
 | 
						|
 | 
						|
	/*
 | 
						|
	   This identifier must be provided if the image sensor implements
 | 
						|
	   the standard I2C protocol.
 | 
						|
	*/
 | 
						|
	u8 i2c_slave_id; /* reg. 0x09 */
 | 
						|
 | 
						|
	/*
 | 
						|
	   NOTE: Where not noted,most of the functions below are not mandatory.
 | 
						|
		 Set to null if you do not implement them. If implemented,
 | 
						|
		 they must return 0 on success, the proper error otherwise.
 | 
						|
	*/
 | 
						|
 | 
						|
	int (*init)(struct sn9c102_device* cam);
 | 
						|
	/*
 | 
						|
	   This function will be called after the sensor has been attached.
 | 
						|
	   It should be used to initialize the sensor only, but may also
 | 
						|
	   configure part of the SN9C1XX chip if necessary. You don't need to
 | 
						|
	   setup picture settings like brightness, contrast, etc.. here, if
 | 
						|
	   the corrisponding controls are implemented (see below), since
 | 
						|
	   they are adjusted in the core driver by calling the set_ctrl()
 | 
						|
	   method after init(), where the arguments are the default values
 | 
						|
	   specified in the v4l2_queryctrl list of supported controls;
 | 
						|
	   Same suggestions apply for other settings, _if_ the corresponding
 | 
						|
	   methods are present; if not, the initialization must configure the
 | 
						|
	   sensor according to the default configuration structures below.
 | 
						|
	*/
 | 
						|
 | 
						|
	struct v4l2_queryctrl qctrl[SN9C102_MAX_CTRLS];
 | 
						|
	/*
 | 
						|
	   Optional list of default controls, defined as indicated in the
 | 
						|
	   V4L2 API. Menu type controls are not handled by this interface.
 | 
						|
	*/
 | 
						|
 | 
						|
	int (*get_ctrl)(struct sn9c102_device* cam, struct v4l2_control* ctrl);
 | 
						|
	int (*set_ctrl)(struct sn9c102_device* cam,
 | 
						|
			const struct v4l2_control* ctrl);
 | 
						|
	/*
 | 
						|
	   You must implement at least the set_ctrl method if you have defined
 | 
						|
	   the list above. The returned value must follow the V4L2
 | 
						|
	   specifications for the VIDIOC_G|C_CTRL ioctls. V4L2_CID_H|VCENTER
 | 
						|
	   are not supported by this driver, so do not implement them. Also,
 | 
						|
	   you don't have to check whether the passed values are out of bounds,
 | 
						|
	   given that this is done by the core module.
 | 
						|
	*/
 | 
						|
 | 
						|
	struct v4l2_cropcap cropcap;
 | 
						|
	/*
 | 
						|
	   Think the image sensor as a grid of R,G,B monochromatic pixels
 | 
						|
	   disposed according to a particular Bayer pattern, which describes
 | 
						|
	   the complete array of pixels, from (0,0) to (xmax, ymax). We will
 | 
						|
	   use this coordinate system from now on. It is assumed the sensor
 | 
						|
	   chip can be programmed to capture/transmit a subsection of that
 | 
						|
	   array of pixels: we will call this subsection "active window".
 | 
						|
	   It is not always true that the largest achievable active window can
 | 
						|
	   cover the whole array of pixels. The V4L2 API defines another
 | 
						|
	   area called "source rectangle", which, in turn, is a subrectangle of
 | 
						|
	   the active window. The SN9C1XX chip is always programmed to read the
 | 
						|
	   source rectangle.
 | 
						|
	   The bounds of both the active window and the source rectangle are
 | 
						|
	   specified in the cropcap substructures 'bounds' and 'defrect'.
 | 
						|
	   By default, the source rectangle should cover the largest possible
 | 
						|
	   area. Again, it is not always true that the largest source rectangle
 | 
						|
	   can cover the entire active window, although it is a rare case for
 | 
						|
	   the hardware we have. The bounds of the source rectangle _must_ be
 | 
						|
	   multiple of 16 and must use the same coordinate system as indicated
 | 
						|
	   before; their centers shall align initially.
 | 
						|
	   If necessary, the sensor chip must be initialized during init() to
 | 
						|
	   set the bounds of the active sensor window; however, by default, it
 | 
						|
	   usually covers the largest achievable area (maxwidth x maxheight)
 | 
						|
	   of pixels, so no particular initialization is needed, if you have
 | 
						|
	   defined the correct default bounds in the structures.
 | 
						|
	   See the V4L2 API for further details.
 | 
						|
	   NOTE: once you have defined the bounds of the active window
 | 
						|
		 (struct cropcap.bounds) you must not change them.anymore.
 | 
						|
	   Only 'bounds' and 'defrect' fields are mandatory, other fields
 | 
						|
	   will be ignored.
 | 
						|
	*/
 | 
						|
 | 
						|
	int (*set_crop)(struct sn9c102_device* cam,
 | 
						|
			const struct v4l2_rect* rect);
 | 
						|
	/*
 | 
						|
	   To be called on VIDIOC_C_SETCROP. The core module always calls a
 | 
						|
	   default routine which configures the appropriate SN9C1XX regs (also
 | 
						|
	   scaling), but you may need to override/adjust specific stuff.
 | 
						|
	   'rect' contains width and height values that are multiple of 16: in
 | 
						|
	   case you override the default function, you always have to program
 | 
						|
	   the chip to match those values; on error return the corresponding
 | 
						|
	   error code without rolling back.
 | 
						|
	   NOTE: in case, you must program the SN9C1XX chip to get rid of
 | 
						|
		 blank pixels or blank lines at the _start_ of each line or
 | 
						|
		 frame after each HSYNC or VSYNC, so that the image starts with
 | 
						|
		 real RGB data (see regs 0x12, 0x13) (having set H_SIZE and,
 | 
						|
		 V_SIZE you don't have to care about blank pixels or blank
 | 
						|
		 lines at the end of each line or frame).
 | 
						|
	*/
 | 
						|
 | 
						|
	struct v4l2_pix_format pix_format;
 | 
						|
	/*
 | 
						|
	   What you have to define here are: 1) initial 'width' and 'height' of
 | 
						|
	   the target rectangle 2) the initial 'pixelformat', which can be
 | 
						|
	   either V4L2_PIX_FMT_SN9C10X, V4L2_PIX_FMT_JPEG (for ompressed video)
 | 
						|
	   or V4L2_PIX_FMT_SBGGR8 3) 'priv', which we'll be used to indicate
 | 
						|
	   the number of bits per pixel for uncompressed video, 8 or 9 (despite
 | 
						|
	   the current value of 'pixelformat').
 | 
						|
	   NOTE 1: both 'width' and 'height' _must_ be either 1/1 or 1/2 or 1/4
 | 
						|
		   of cropcap.defrect.width and cropcap.defrect.height. I
 | 
						|
		   suggest 1/1.
 | 
						|
	   NOTE 2: The initial compression quality is defined by the first bit
 | 
						|
		   of reg 0x17 during the initialization of the image sensor.
 | 
						|
	   NOTE 3: as said above, you have to program the SN9C1XX chip to get
 | 
						|
		   rid of any blank pixels, so that the output of the sensor
 | 
						|
		   matches the RGB bayer sequence (i.e. BGBGBG...GRGRGR).
 | 
						|
	*/
 | 
						|
 | 
						|
	int (*set_pix_format)(struct sn9c102_device* cam,
 | 
						|
			      const struct v4l2_pix_format* pix);
 | 
						|
	/*
 | 
						|
	   To be called on VIDIOC_S_FMT, when switching from the SBGGR8 to
 | 
						|
	   SN9C10X pixel format or viceversa. On error return the corresponding
 | 
						|
	   error code without rolling back.
 | 
						|
	*/
 | 
						|
 | 
						|
	/*
 | 
						|
	   Do NOT write to the data below, it's READ ONLY. It is used by the
 | 
						|
	   core module to store successfully updated values of the above
 | 
						|
	   settings, for rollbacks..etc..in case of errors during atomic I/O
 | 
						|
	*/
 | 
						|
	struct v4l2_queryctrl _qctrl[SN9C102_MAX_CTRLS];
 | 
						|
	struct v4l2_rect _rect;
 | 
						|
};
 | 
						|
 | 
						|
/*****************************************************************************/
 | 
						|
 | 
						|
/* Private ioctl's for control settings supported by some image sensors */
 | 
						|
#define SN9C102_V4L2_CID_DAC_MAGNITUDE (V4L2_CID_PRIVATE_BASE + 0)
 | 
						|
#define SN9C102_V4L2_CID_GREEN_BALANCE (V4L2_CID_PRIVATE_BASE + 1)
 | 
						|
#define SN9C102_V4L2_CID_RESET_LEVEL (V4L2_CID_PRIVATE_BASE + 2)
 | 
						|
#define SN9C102_V4L2_CID_PIXEL_BIAS_VOLTAGE (V4L2_CID_PRIVATE_BASE + 3)
 | 
						|
#define SN9C102_V4L2_CID_GAMMA (V4L2_CID_PRIVATE_BASE + 4)
 | 
						|
#define SN9C102_V4L2_CID_BAND_FILTER (V4L2_CID_PRIVATE_BASE + 5)
 | 
						|
#define SN9C102_V4L2_CID_BRIGHT_LEVEL (V4L2_CID_PRIVATE_BASE + 6)
 | 
						|
 | 
						|
#endif /* _SN9C102_SENSOR_H_ */
 |