linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / drivers / usb / media / sn9c102_sensor.h
index ebafc28..7d953b2 100644 (file)
@@ -1,7 +1,7 @@
 /***************************************************************************
  * API for image sensors connected to the SN9C10x PC Camera Controllers    *
  *                                                                         *
- * Copyright (C) 2004 by Luca Risolia <luca.risolia@studio.unibo.it>       *
+ * Copyright (C) 2004-2006 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    *
@@ -62,6 +62,9 @@ struct sn9c102_sensor;
    ahead.
    Functions must return 0 on success, the appropriate error otherwise.
 */
+extern int sn9c102_probe_hv7131d(struct sn9c102_device* cam);
+extern int sn9c102_probe_mi0343(struct sn9c102_device* cam);
+extern int sn9c102_probe_ov7630(struct sn9c102_device* cam);
 extern int sn9c102_probe_pas106b(struct sn9c102_device* cam);
 extern int sn9c102_probe_pas202bcb(struct sn9c102_device* cam);
 extern int sn9c102_probe_tas5110c1b(struct sn9c102_device* cam);
@@ -74,8 +77,11 @@ extern int sn9c102_probe_tas5130d1b(struct sn9c102_device* cam);
 */
 #define SN9C102_SENSOR_TABLE                                                  \
 static int (*sn9c102_sensor_table[])(struct sn9c102_device*) = {              \
+       &sn9c102_probe_mi0343, /* strong detection based on SENSOR ids */     \
        &sn9c102_probe_pas106b, /* strong detection based on SENSOR ids */    \
        &sn9c102_probe_pas202bcb, /* strong detection based on SENSOR ids */  \
+       &sn9c102_probe_hv7131d, /* strong detection based on SENSOR ids */    \
+       &sn9c102_probe_ov7630, /* detection mostly based on USB pid/vid */    \
        &sn9c102_probe_tas5110c1b, /* detection based on USB pid/vid */       \
        &sn9c102_probe_tas5130d1b, /* detection based on USB pid/vid */       \
        NULL,                                                                 \
@@ -86,7 +92,18 @@ extern void
 sn9c102_attach_sensor(struct sn9c102_device* cam,
                       struct sn9c102_sensor* sensor);
 
-/* Each SN9C10X camera has proper PID/VID identifiers. Add them here in case.*/
+/*
+   Each SN9C10x camera has proper PID/VID identifiers.
+   SN9C103 supports multiple interfaces, but we only handle the video class
+   interface.
+*/
+#define SN9C102_USB_DEVICE(vend, prod, intclass)                              \
+       .match_flags = USB_DEVICE_ID_MATCH_DEVICE |                           \
+                      USB_DEVICE_ID_MATCH_INT_CLASS,                         \
+       .idVendor = (vend),                                                   \
+       .idProduct = (prod),                                                  \
+       .bInterfaceClass = (intclass)
+
 #define SN9C102_ID_TABLE                                                      \
 static const struct usb_device_id sn9c102_id_table[] = {                      \
        { USB_DEVICE(0x0c45, 0x6001), }, /* TAS5110C1B */                     \
@@ -97,36 +114,38 @@ static const struct usb_device_id sn9c102_id_table[] = {                      \
        { USB_DEVICE(0x0c45, 0x6025), }, /* TAS5130D1B and TAS5110C1B */      \
        { USB_DEVICE(0x0c45, 0x6028), }, /* PAS202BCB */                      \
        { USB_DEVICE(0x0c45, 0x6029), }, /* PAS106B */                        \
-       { USB_DEVICE(0x0c45, 0x602a), }, /* HV7131[D|E1] */                   \
+       { USB_DEVICE(0x0c45, 0x602a), }, /* HV7131D */                        \
        { USB_DEVICE(0x0c45, 0x602b), }, /* MI-0343 */                        \
-       { USB_DEVICE(0x0c45, 0x602c), }, /* OV7620 */                         \
+       { USB_DEVICE(0x0c45, 0x602c), }, /* OV7630 */                         \
+       { USB_DEVICE(0x0c45, 0x602d), },                                      \
+       { USB_DEVICE(0x0c45, 0x602e), }, /* OV7630 */                         \
        { USB_DEVICE(0x0c45, 0x6030), }, /* MI03x */                          \
-       { USB_DEVICE(0x0c45, 0x6080), },                                      \
-       { USB_DEVICE(0x0c45, 0x6082), }, /* MI0343 and MI0360 */              \
-       { USB_DEVICE(0x0c45, 0x6083), }, /* HV7131[D|E1] */                   \
-       { USB_DEVICE(0x0c45, 0x6088), },                                      \
-       { USB_DEVICE(0x0c45, 0x608a), },                                      \
-       { USB_DEVICE(0x0c45, 0x608b), },                                      \
-       { USB_DEVICE(0x0c45, 0x608c), }, /* HV7131x */                        \
-       { USB_DEVICE(0x0c45, 0x608e), }, /* CIS-VF10 */                       \
-       { USB_DEVICE(0x0c45, 0x608f), }, /* OV7630 */                         \
-       { USB_DEVICE(0x0c45, 0x60a0), },                                      \
-       { USB_DEVICE(0x0c45, 0x60a2), },                                      \
-       { USB_DEVICE(0x0c45, 0x60a3), },                                      \
-       { USB_DEVICE(0x0c45, 0x60a8), }, /* PAS106B */                        \
-       { USB_DEVICE(0x0c45, 0x60aa), }, /* TAS5130D1B */                     \
-       { USB_DEVICE(0x0c45, 0x60ab), }, /* TAS5110C1B */                     \
-       { USB_DEVICE(0x0c45, 0x60ac), },                                      \
-       { USB_DEVICE(0x0c45, 0x60ae), },                                      \
-       { USB_DEVICE(0x0c45, 0x60af), }, /* PAS202BCB */                      \
-       { USB_DEVICE(0x0c45, 0x60b0), },                                      \
-       { USB_DEVICE(0x0c45, 0x60b2), },                                      \
-       { USB_DEVICE(0x0c45, 0x60b3), },                                      \
-       { USB_DEVICE(0x0c45, 0x60b8), },                                      \
-       { USB_DEVICE(0x0c45, 0x60ba), },                                      \
-       { USB_DEVICE(0x0c45, 0x60bb), },                                      \
-       { USB_DEVICE(0x0c45, 0x60bc), },                                      \
-       { USB_DEVICE(0x0c45, 0x60be), },                                      \
+       { SN9C102_USB_DEVICE(0x0c45, 0x6080, 0xff), },                        \
+       { SN9C102_USB_DEVICE(0x0c45, 0x6082, 0xff), }, /* MI0343 & MI0360 */  \
+       { SN9C102_USB_DEVICE(0x0c45, 0x6083, 0xff), }, /* HV7131[D|E1] */     \
+       { SN9C102_USB_DEVICE(0x0c45, 0x6088, 0xff), },                        \
+       { SN9C102_USB_DEVICE(0x0c45, 0x608a, 0xff), },                        \
+       { SN9C102_USB_DEVICE(0x0c45, 0x608b, 0xff), },                        \
+       { SN9C102_USB_DEVICE(0x0c45, 0x608c, 0xff), }, /* HV7131x */          \
+       { SN9C102_USB_DEVICE(0x0c45, 0x608e, 0xff), }, /* CIS-VF10 */         \
+       { SN9C102_USB_DEVICE(0x0c45, 0x608f, 0xff), }, /* OV7630 */           \
+       { SN9C102_USB_DEVICE(0x0c45, 0x60a0, 0xff), },                        \
+       { SN9C102_USB_DEVICE(0x0c45, 0x60a2, 0xff), },                        \
+       { SN9C102_USB_DEVICE(0x0c45, 0x60a3, 0xff), },                        \
+       { SN9C102_USB_DEVICE(0x0c45, 0x60a8, 0xff), }, /* PAS106B */          \
+       { SN9C102_USB_DEVICE(0x0c45, 0x60aa, 0xff), }, /* TAS5130D1B */       \
+       { SN9C102_USB_DEVICE(0x0c45, 0x60ab, 0xff), }, /* TAS5110C1B */       \
+       { SN9C102_USB_DEVICE(0x0c45, 0x60ac, 0xff), },                        \
+       { SN9C102_USB_DEVICE(0x0c45, 0x60ae, 0xff), },                        \
+       { SN9C102_USB_DEVICE(0x0c45, 0x60af, 0xff), }, /* PAS202BCB */        \
+       { SN9C102_USB_DEVICE(0x0c45, 0x60b0, 0xff), }, /* OV7630 (?) */       \
+       { SN9C102_USB_DEVICE(0x0c45, 0x60b2, 0xff), },                        \
+       { SN9C102_USB_DEVICE(0x0c45, 0x60b3, 0xff), },                        \
+       { SN9C102_USB_DEVICE(0x0c45, 0x60b8, 0xff), },                        \
+       { SN9C102_USB_DEVICE(0x0c45, 0x60ba, 0xff), },                        \
+       { SN9C102_USB_DEVICE(0x0c45, 0x60bb, 0xff), },                        \
+       { SN9C102_USB_DEVICE(0x0c45, 0x60bc, 0xff), },                        \
+       { SN9C102_USB_DEVICE(0x0c45, 0x60be, 0xff), },                        \
        { }                                                                   \
 };
 
@@ -147,35 +166,50 @@ extern int sn9c102_i2c_try_read(struct sn9c102_device*,struct sn9c102_sensor*,
                                 u8 address);
 
 /*
-   This must be used if and only if the sensor doesn't implement the standard
-   I2C protocol. There a number of good reasons why you must use the 
-   single-byte versions of this function: do not abuse. It writes n bytes, 
-   from data0 to datan, (registers 0x09 - 0x09+n of SN9C10X chip).
+   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 SN9C10X
+   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,
                                      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,
+                                    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_write_regs(struct sn9c102_device*, u8* buff, u16 index);
 extern int sn9c102_write_reg(struct sn9c102_device*, u8 value, u16 index);
 extern int sn9c102_pread_reg(struct sn9c102_device*, u16 index);
 
 /*
-   NOTE: there are no debugging functions here. To uniform the output you must
-   use the dev_info()/dev_warn()/dev_err() macros defined in device.h, already
-   included here, the argument being the struct device 'dev' of the sensor
-   structure. Do NOT use these macros before the sensor is attached or the
-   kernel will crash! However you should not need to notify the user about
-   common errors or other messages, since this is done by the master module.
+   NOTE: there are no exported debugging functions. To uniform the output you
+   must use the dev_info()/dev_warn()/dev_err() macros defined in device.h,
+   already included here, the argument being the struct device '&usbdev->dev'
+   of the sensor structure. Do NOT use these macros before the sensor is
+   attached or the kernel will crash! However, you should not need to notify
+   the user about common errors or other messages, since this is done by the
+   master module.
 */
 
 /*****************************************************************************/
 
+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,
@@ -186,13 +220,15 @@ enum sn9c102_i2c_interface {
        SN9C102_I2C_3WIRES,
 };
 
-#define SN9C102_I2C_SLAVEID_FICTITIOUS 0xff
-#define SN9C102_I2C_SLAVEID_UNAVAILABLE 0x00
+#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> */
 
+       /* Supported operations through the 'sysfs' interface */
+       enum sn9c102_i2c_sysfs_ops sysfs_ops;
+
        /*
           These sensor capabilities must be provided if the SN9C10X controller
           needs to communicate through the sensor serial interface by using
@@ -202,10 +238,10 @@ struct sn9c102_sensor {
        enum sn9c102_i2c_interface interface;
 
        /*
-          These identifiers must be provided if the image sensor implements
+          This identifier must be provided if the image sensor implements
           the standard I2C protocol.
        */
-       u8 slave_read_id, slave_write_id; /* reg. 0x09 */
+       u8 i2c_slave_id; /* reg. 0x09 */
 
        /*
           NOTE: Where not noted,most of the functions below are not mandatory.
@@ -215,7 +251,7 @@ struct sn9c102_sensor {
 
        int (*init)(struct sn9c102_device* cam);
        /*
-          This function is called after the sensor has been attached. 
+          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 SN9C10X chip if necessary. You don't need to
           setup picture settings like brightness, contrast, etc.. here, if
@@ -228,7 +264,7 @@ struct sn9c102_sensor {
           sensor according to the default configuration structures below.
        */
 
-       struct v4l2_queryctrl qctrl[V4L2_CID_LASTP1-V4L2_CID_BASE];
+       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.
@@ -315,11 +351,12 @@ struct sn9c102_sensor {
                   matches the RGB bayer sequence (i.e. BGBGBG...GRGRGR).
        */
 
-       const struct device* dev;
+       int (*set_pix_format)(struct sn9c102_device* cam,
+                             const struct v4l2_pix_format* pix);
        /*
-          This is the argument for dev_err(), dev_info() and dev_warn(). It
-          is used for debugging purposes. You must not access the struct
-          before the sensor is attached.
+          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.
        */
 
        const struct usb_device* usbdev;
@@ -333,7 +370,7 @@ struct sn9c102_sensor {
           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[V4L2_CID_LASTP1-V4L2_CID_BASE];
+       struct v4l2_queryctrl _qctrl[SN9C102_MAX_CTRLS];
        struct v4l2_rect _rect;
 };
 
@@ -341,7 +378,11 @@ struct sn9c102_sensor {
 
 /* Private ioctl's for control settings supported by some image sensors */
 #define SN9C102_V4L2_CID_DAC_MAGNITUDE V4L2_CID_PRIVATE_BASE
-#define SN9C102_V4L2_CID_DAC_SIGN V4L2_CID_PRIVATE_BASE + 1
-#define SN9C102_V4L2_CID_GREEN_BALANCE V4L2_CID_PRIVATE_BASE + 2
+#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_ */