V4L/DVB (11717): gspca - sonixj: Webcams with bridge sn9c128 added
[pandora-kernel.git] / drivers / media / video / gspca / sonixj.c
index 882d5e9..77be80d 100644 (file)
@@ -22,7 +22,6 @@
 #define MODULE_NAME "sonixj"
 
 #include "gspca.h"
-#define QUANT_VAL 4            /* quantization table */
 #include "jpeg.h"
 
 #define V4L2_CID_INFRARED (V4L2_CID_PRIVATE_BASE + 0)
@@ -45,8 +44,15 @@ struct sd {
        u8 blue;
        u8 red;
        u8 gamma;
-       u8 vflip;                       /* ov7630 only */
+       u8 vflip;                       /* ov7630/ov7648 only */
        u8 infrared;                    /* mt9v111 only */
+       u8 quality;                     /* image quality */
+#define QUALITY_MIN 60
+#define QUALITY_MAX 95
+#define QUALITY_DEF 80
+       u8 jpegqual;                    /* webcam quality */
+
+       u8 reg18;
 
        s8 ag_cnt;
 #define AG_CNT_START 13
@@ -56,7 +62,6 @@ struct sd {
 #define BRIDGE_SN9C105 1
 #define BRIDGE_SN9C110 2
 #define BRIDGE_SN9C120 3
-#define BRIDGE_SN9C325 4
        u8 sensor;                      /* Type of image sensor chip */
 #define SENSOR_HV7131R 0
 #define SENSOR_MI0360 1
@@ -68,6 +73,8 @@ struct sd {
 #define SENSOR_OV7660 7
 #define SENSOR_SP80708 8
        u8 i2c_base;
+
+       u8 *jpeg_hdr;
 };
 
 /* V4L2 controls supported by the driver */
@@ -192,7 +199,7 @@ static struct ctrl sd_ctrls[] = {
            .set = sd_setautogain,
            .get = sd_getautogain,
        },
-/* ov7630 only */
+/* ov7630/ov7648 only */
 #define VFLIP_IDX 6
        {
            {
@@ -202,7 +209,7 @@ static struct ctrl sd_ctrls[] = {
                .minimum = 0,
                .maximum = 1,
                .step    = 1,
-#define VFLIP_DEF 1
+#define VFLIP_DEF 0                    /* vflip def = 1 for ov7630 */
                .default_value = VFLIP_DEF,
            },
            .set = sd_setvflip,
@@ -234,13 +241,13 @@ static __u32 ctrl_dis[] = {
                                                /* SENSOR_MI0360 1 */
        (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
                                                /* SENSOR_MO4000 2 */
-       0,
+       (1 << VFLIP_IDX),
                                                /* SENSOR_MT9V111 3 */
        (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
                                                /* SENSOR_OM6802 4 */
        (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX),
                                                /* SENSOR_OV7630 5 */
-       (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
+       (1 << INFRARED_IDX),
                                                /* SENSOR_OV7648 6 */
        (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
                                                /* SENSOR_OV7660 7 */
@@ -346,9 +353,9 @@ static const u8 sn_ov7648[0x1c] = {
 
 static const u8 sn_ov7660[0x1c] = {
 /*     reg0    reg1    reg2    reg3    reg4    reg5    reg6    reg7 */
-       0x00,   0x61,   0x40,   0x00,   0x1a,   0x20,   0x20,   0x20,
+       0x00,   0x61,   0x40,   0x00,   0x1a,   0x00,   0x00,   0x00,
 /*     reg8    reg9    rega    regb    regc    regd    rege    regf */
-       0x81,   0x21,   0x07,   0x00,   0x00,   0x00,   0x00,   0x10,
+       0x81,   0x21,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,
 /*     reg10   reg11   reg12   reg13   reg14   reg15   reg16   reg17 */
        0x03,   0x00,   0x01,   0x01,   0x08,   0x28,   0x1e,   0x20,
 /*     reg18   reg19   reg1a   reg1b */
@@ -669,7 +676,8 @@ static const u8 ov7648_sensor_init[][8] = {
        {0xb1, 0x21, 0x2d, 0x85, 0x00, 0x00, 0x00, 0x10},
 /*...*/
 /*     {0xa1, 0x21, 0x12, 0x08, 0x00, 0x00, 0x00, 0x10}, jfm done */
-/*     {0xa1, 0x21, 0x75, 0x06, 0x00, 0x00, 0x00, 0x10}, jfm done */
+/*     {0xa1, 0x21, 0x75, 0x06, 0x00, 0x00, 0x00, 0x10},   * COMN
+                                                        * set by setvflip */
        {0xa1, 0x21, 0x19, 0x02, 0x00, 0x00, 0x00, 0x10},
        {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
 /*     {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
@@ -748,6 +756,7 @@ static const u8 ov7660_sensor_init[][8] = {
        {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */
        {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */
        {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */
+       {0xb1, 0x21, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x10},
 /****** (some exchanges in the win trace) ******/
        {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */
                                                /* bits[3..0]reserved */
@@ -858,25 +867,6 @@ static const u8 sp80708_sensor_init[][8] = {
        {}
 };
 
-static const u8 qtable4[] = {
-       0x06, 0x04, 0x04, 0x06, 0x04, 0x04, 0x06, 0x06,
-       0x06, 0x06, 0x08, 0x06, 0x06, 0x08, 0x0a, 0x11,
-       0x0a, 0x0a, 0x08, 0x08, 0x0a, 0x15, 0x0f, 0x0f,
-       0x0c, 0x11, 0x19, 0x15, 0x19, 0x19, 0x17, 0x15,
-       0x17, 0x17, 0x1b, 0x1d, 0x25, 0x21, 0x1b, 0x1d,
-       0x23, 0x1d, 0x17, 0x17, 0x21, 0x2e, 0x21, 0x23,
-       0x27, 0x29, 0x2c, 0x2c, 0x2c, 0x19, 0x1f, 0x30,
-       0x32, 0x2e, 0x29, 0x32, 0x25, 0x29, 0x2c, 0x29,
-       0x06, 0x08, 0x08, 0x0a, 0x08, 0x0a, 0x13, 0x0a,
-       0x0a, 0x13, 0x29, 0x1b, 0x17, 0x1b, 0x29, 0x29,
-       0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
-       0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
-       0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
-       0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
-       0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
-       0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29
-};
-
 /* read <len> bytes to gspca_dev->usb_buf */
 static void reg_r(struct gspca_dev *gspca_dev,
                  u16 value, int len)
@@ -1075,9 +1065,9 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
        struct sd *sd = (struct sd *) gspca_dev;
        const u8 *reg9a;
        static const u8 reg9a_def[] =
-               {0x08, 0x40, 0x20, 0x10, 0x00, 0x04};
-       static const u8 reg9a_sn9c325[] =
-               {0x0a, 0x40, 0x38, 0x30, 0x00, 0x20};
+               {0x00, 0x40, 0x20, 0x00, 0x00, 0x00};
+       static const u8 reg9a_spec[] =
+               {0x00, 0x40, 0x38, 0x30, 0x00, 0x20};
        static const u8 regd4[] = {0x60, 0x00, 0x00};
 
        reg_w1(gspca_dev, 0xf1, 0x00);
@@ -1087,9 +1077,10 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
        reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2);
        reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2);
        reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5);      /* jfm len was 3 */
-       switch (sd->bridge) {
-       case BRIDGE_SN9C325:
-               reg9a = reg9a_sn9c325;
+       switch (sd->sensor) {
+       case SENSOR_OV7660:
+       case SENSOR_SP80708:
+               reg9a = reg9a_spec;
                break;
        default:
                reg9a = reg9a_def;
@@ -1114,7 +1105,6 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
                reg_w1(gspca_dev, 0x17, 0x64);
                reg_w1(gspca_dev, 0x01, 0x42);
                break;
-/*jfm: from win trace */
        case SENSOR_OV7630:
                reg_w1(gspca_dev, 0x01, 0x61);
                reg_w1(gspca_dev, 0x17, 0xe2);
@@ -1124,18 +1114,15 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
        case SENSOR_OV7648:
                reg_w1(gspca_dev, 0x01, 0x63);
                reg_w1(gspca_dev, 0x17, 0x20);
+               reg_w1(gspca_dev, 0x01, 0x62);
                reg_w1(gspca_dev, 0x01, 0x42);
                break;
-/*jfm: from win trace */
        case SENSOR_OV7660:
-               if (sd->bridge == BRIDGE_SN9C120) {
-                       reg_w1(gspca_dev, 0x01, 0x61);
-                       reg_w1(gspca_dev, 0x17, 0x20);
-                       reg_w1(gspca_dev, 0x01, 0x60);
-                       reg_w1(gspca_dev, 0x01, 0x40);
-                       break;
-               }
-               /* fall thru */
+               reg_w1(gspca_dev, 0x01, 0x61);
+               reg_w1(gspca_dev, 0x17, 0x20);
+               reg_w1(gspca_dev, 0x01, 0x60);
+               reg_w1(gspca_dev, 0x01, 0x40);
+               break;
        case SENSOR_SP80708:
                reg_w1(gspca_dev, 0x01, 0x63);
                reg_w1(gspca_dev, 0x17, 0x20);
@@ -1144,6 +1131,9 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
                mdelay(100);
                reg_w1(gspca_dev, 0x02, 0x62);
                break;
+/*     case SENSOR_HV7131R: */
+/*     case SENSOR_MI0360: */
+/*     case SENSOR_MO4000: */
        default:
                reg_w1(gspca_dev, 0x01, 0x43);
                reg_w1(gspca_dev, 0x17, 0x61);
@@ -1290,6 +1280,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
        cam = &gspca_dev->cam;
        cam->cam_mode = vga_mode;
        cam->nmodes = ARRAY_SIZE(vga_mode);
+       cam->npkt = 24;                 /* 24 packets per ISOC message */
 
        sd->bridge = id->driver_info >> 16;
        sd->sensor = id->driver_info >> 8;
@@ -1303,8 +1294,13 @@ static int sd_config(struct gspca_dev *gspca_dev,
        sd->gamma = GAMMA_DEF;
        sd->autogain = AUTOGAIN_DEF;
        sd->ag_cnt = -1;
-       sd->vflip = VFLIP_DEF;
+       if (sd->sensor != SENSOR_OV7630)
+               sd->vflip = 0;
+       else
+               sd->vflip = 1;
        sd->infrared = INFRARED_DEF;
+       sd->quality = QUALITY_DEF;
+       sd->jpegqual = 80;
 
        gspca_dev->ctrl_dis = ctrl_dis[sd->sensor];
        return 0;
@@ -1563,16 +1559,39 @@ static void setautogain(struct gspca_dev *gspca_dev)
 
        if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX))
                return;
+       switch (sd->sensor) {
+       case SENSOR_OV7630:
+       case SENSOR_OV7648: {
+               u8 comb;
+
+               if (sd->sensor == SENSOR_OV7630)
+                       comb = 0xc0;
+               else
+                       comb = 0xa0;
+               if (sd->autogain)
+                       comb |= 0x02;
+               i2c_w1(&sd->gspca_dev, 0x13, comb);
+               return;
+           }
+       }
        if (sd->autogain)
                sd->ag_cnt = AG_CNT_START;
        else
                sd->ag_cnt = -1;
 }
 
+/* ov7630/ov7648 only */
 static void setvflip(struct sd *sd)
 {
-       i2c_w1(&sd->gspca_dev, 0x75,                    /* COMN */
-               sd->vflip ? 0x82 : 0x02);
+       u8 comn;
+
+       if (sd->sensor == SENSOR_OV7630)
+               comn = 0x02;
+       else
+               comn = 0x06;
+       if (sd->vflip)
+               comn |= 0x80;
+       i2c_w1(&sd->gspca_dev, 0x75, comn);
 }
 
 static void setinfrared(struct sd *sd)
@@ -1583,12 +1602,49 @@ static void setinfrared(struct sd *sd)
                sd->infrared ? 0x66 : 0x64);
 }
 
+static void setjpegqual(struct gspca_dev *gspca_dev)
+{
+       struct sd *sd = (struct sd *) gspca_dev;
+       int i, sc;
+
+       if (sd->jpegqual < 50)
+               sc = 5000 / sd->jpegqual;
+       else
+               sc = 200 - sd->jpegqual * 2;
+#if USB_BUF_SZ < 64
+#error "No room enough in usb_buf for quantization table"
+#endif
+       for (i = 0; i < 64; i++)
+               gspca_dev->usb_buf[i] =
+                       (jpeg_head[JPEG_QT0_OFFSET + i] * sc + 50) / 100;
+       usb_control_msg(gspca_dev->dev,
+                       usb_sndctrlpipe(gspca_dev->dev, 0),
+                       0x08,
+                       USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
+                       0x0100, 0,
+                       gspca_dev->usb_buf, 64,
+                       500);
+       for (i = 0; i < 64; i++)
+               gspca_dev->usb_buf[i] =
+                       (jpeg_head[JPEG_QT1_OFFSET + i] * sc + 50) / 100;
+       usb_control_msg(gspca_dev->dev,
+                       usb_sndctrlpipe(gspca_dev->dev, 0),
+                       0x08,
+                       USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
+                       0x0140, 0,
+                       gspca_dev->usb_buf, 64,
+                       500);
+
+       sd->reg18 ^= 0x40;
+       reg_w1(gspca_dev, 0x18, sd->reg18);
+}
+
 /* -- start the camera -- */
 static int sd_start(struct gspca_dev *gspca_dev)
 {
        struct sd *sd = (struct sd *) gspca_dev;
        int i;
-       u8 reg1, reg17, reg18;
+       u8 reg1, reg17;
        const u8 *sn9c1xx;
        int mode;
        static const u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
@@ -1597,6 +1653,12 @@ static int sd_start(struct gspca_dev *gspca_dev)
        static const u8 CE_ov76xx[] =
                                { 0x32, 0xdd, 0x32, 0xdd };
 
+       /* create the JPEG header */
+       sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
+       jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
+                       0x21);          /* JPEG 422 */
+       jpeg_set_qual(sd->jpeg_hdr, sd->quality);
+
        sn9c1xx = sn_tb[(int) sd->sensor];
        configure_gpio(gspca_dev, sn9c1xx);
 
@@ -1622,13 +1684,9 @@ static int sd_start(struct gspca_dev *gspca_dev)
        case SENSOR_OV7648:
                reg17 = 0x20;
                break;
-/*jfm: from win trace */
        case SENSOR_OV7660:
-               if (sd->bridge == BRIDGE_SN9C120) {
-                       reg17 = 0xa0;
-                       break;
-               }
-               /* fall thru */
+               reg17 = 0xa0;
+               break;
        default:
                reg17 = 0x60;
                break;
@@ -1653,16 +1711,17 @@ static int sd_start(struct gspca_dev *gspca_dev)
                reg_w1(gspca_dev, 0x9a, 0x0a);
                reg_w1(gspca_dev, 0x99, 0x60);
                break;
+       case SENSOR_OV7660:
+               reg_w1(gspca_dev, 0x9a, 0x05);
+               if (sd->bridge == BRIDGE_SN9C105)
+                       reg_w1(gspca_dev, 0x99, 0xff);
+               else
+                       reg_w1(gspca_dev, 0x99, 0x5b);
+               break;
        case SENSOR_SP80708:
                reg_w1(gspca_dev, 0x9a, 0x05);
                reg_w1(gspca_dev, 0x99, 0x59);
                break;
-       case SENSOR_OV7660:
-               if (sd->bridge == BRIDGE_SN9C120) {
-                       reg_w1(gspca_dev, 0x9a, 0x05);
-                       break;
-               }
-               /* fall thru */
        default:
                reg_w1(gspca_dev, 0x9a, 0x08);
                reg_w1(gspca_dev, 0x99, 0x59);
@@ -1755,13 +1814,9 @@ static int sd_start(struct gspca_dev *gspca_dev)
        }
 
        /* here change size mode 0 -> VGA; 1 -> CIF */
-       reg18 = sn9c1xx[0x18] | (mode << 4);
-       reg_w1(gspca_dev, 0x18, reg18 | 0x40);
-
-       reg_w(gspca_dev, 0x0100, qtable4, 0x40);
-       reg_w(gspca_dev, 0x0140, qtable4 + 0x40, 0x40);
-
-       reg_w1(gspca_dev, 0x18, reg18);
+       sd->reg18 = sn9c1xx[0x18] | (mode << 4) | 0x40;
+       reg_w1(gspca_dev, 0x18, sd->reg18);
+       setjpegqual(gspca_dev);
 
        reg_w1(gspca_dev, 0x17, reg17);
        reg_w1(gspca_dev, 0x01, reg1);
@@ -1818,6 +1873,13 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
        reg_w1(gspca_dev, 0xf1, 0x00);
 }
 
+static void sd_stop0(struct gspca_dev *gspca_dev)
+{
+       struct sd *sd = (struct sd *) gspca_dev;
+
+       kfree(sd->jpeg_hdr);
+}
+
 static void do_autogain(struct gspca_dev *gspca_dev)
 {
        struct sd *sd = (struct sd *) gspca_dev;
@@ -1901,7 +1963,8 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
        if (gspca_dev->last_packet_type == LAST_PACKET) {
 
                /* put the JPEG 422 header */
-               jpeg_put_header(gspca_dev, frame, 0x21);
+               gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+                       sd->jpeg_hdr, JPEG_HDR_SZ);
        }
        gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
 }
@@ -2068,6 +2131,34 @@ static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val)
        return 0;
 }
 
+static int sd_set_jcomp(struct gspca_dev *gspca_dev,
+                       struct v4l2_jpegcompression *jcomp)
+{
+       struct sd *sd = (struct sd *) gspca_dev;
+
+       if (jcomp->quality < QUALITY_MIN)
+               sd->quality = QUALITY_MIN;
+       else if (jcomp->quality > QUALITY_MAX)
+               sd->quality = QUALITY_MAX;
+       else
+               sd->quality = jcomp->quality;
+       if (gspca_dev->streaming)
+               jpeg_set_qual(sd->jpeg_hdr, sd->quality);
+       return 0;
+}
+
+static int sd_get_jcomp(struct gspca_dev *gspca_dev,
+                       struct v4l2_jpegcompression *jcomp)
+{
+       struct sd *sd = (struct sd *) gspca_dev;
+
+       memset(jcomp, 0, sizeof *jcomp);
+       jcomp->quality = sd->quality;
+       jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
+                       | V4L2_JPEG_MARKER_DQT;
+       return 0;
+}
+
 /* sub-driver description */
 static const struct sd_desc sd_desc = {
        .name = MODULE_NAME,
@@ -2077,8 +2168,11 @@ static const struct sd_desc sd_desc = {
        .init = sd_init,
        .start = sd_start,
        .stopN = sd_stopN,
+       .stop0 = sd_stop0,
        .pkt_scan = sd_pkt_scan,
        .dq_callback = do_autogain,
+       .get_jcomp = sd_get_jcomp,
+       .set_jcomp = sd_set_jcomp,
 };
 
 /* -- module initialisation -- */
@@ -2093,9 +2187,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
 #endif
        {USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)},
        {USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)},
-#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
        {USB_DEVICE(0x0471, 0x0327), BSI(SN9C105, MI0360, 0x5d)},
-#endif
        {USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)},
        {USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)},
        {USB_DEVICE(0x06f8, 0x3004), BSI(SN9C105, OV7660, 0x21)},
@@ -2117,7 +2209,12 @@ static const __devinitdata struct usb_device_id device_table[] = {
 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
        {USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x21)},
 #endif
+       {USB_DEVICE(0x0c45, 0x6100), BSI(SN9C120, MI0360, 0x5d)}, /*sn9c128*/
 /*     {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */
+       {USB_DEVICE(0x0c45, 0x610a), BSI(SN9C120, OV7648, 0x21)}, /*sn9c128*/
+       {USB_DEVICE(0x0c45, 0x610b), BSI(SN9C120, OV7660, 0x21)}, /*sn9c128*/
+       {USB_DEVICE(0x0c45, 0x610c), BSI(SN9C120, HV7131R, 0x11)}, /*sn9c128*/
+       {USB_DEVICE(0x0c45, 0x610e), BSI(SN9C120, OV7630, 0x21)}, /*sn9c128*/
 /*     {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */
 /*     {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */
        {USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/
@@ -2133,9 +2230,9 @@ static const __devinitdata struct usb_device_id device_table[] = {
        {USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x21)},
 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
        {USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)},
+#endif
        {USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)},
 /*     {USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x??)}, */
-#endif
        {USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, SP80708, 0x18)},
        {}
 };