cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

spca500.c (27172B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * SPCA500 chip based cameras initialization data
      4 *
      5 * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
      6 */
      7
      8#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
      9
     10#define MODULE_NAME "spca500"
     11
     12#include "gspca.h"
     13#include "jpeg.h"
     14
     15MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
     16MODULE_DESCRIPTION("GSPCA/SPCA500 USB Camera Driver");
     17MODULE_LICENSE("GPL");
     18
     19#define QUALITY 85
     20
     21/* specific webcam descriptor */
     22struct sd {
     23	struct gspca_dev gspca_dev;		/* !! must be the first item */
     24
     25	char subtype;
     26#define AgfaCl20 0
     27#define AiptekPocketDV 1
     28#define BenqDC1016 2
     29#define CreativePCCam300 3
     30#define DLinkDSC350 4
     31#define Gsmartmini 5
     32#define IntelPocketPCCamera 6
     33#define KodakEZ200 7
     34#define LogitechClickSmart310 8
     35#define LogitechClickSmart510 9
     36#define LogitechTraveler 10
     37#define MustekGsmart300 11
     38#define Optimedia 12
     39#define PalmPixDC85 13
     40#define ToptroIndus 14
     41
     42	u8 jpeg_hdr[JPEG_HDR_SZ];
     43};
     44
     45static const struct v4l2_pix_format vga_mode[] = {
     46	{320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
     47		.bytesperline = 320,
     48		.sizeimage = 320 * 240 * 3 / 8 + 590,
     49		.colorspace = V4L2_COLORSPACE_JPEG,
     50		.priv = 1},
     51	{640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
     52		.bytesperline = 640,
     53		.sizeimage = 640 * 480 * 3 / 8 + 590,
     54		.colorspace = V4L2_COLORSPACE_JPEG,
     55		.priv = 0},
     56};
     57
     58static const struct v4l2_pix_format sif_mode[] = {
     59	{176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
     60		.bytesperline = 176,
     61		.sizeimage = 176 * 144 * 3 / 8 + 590,
     62		.colorspace = V4L2_COLORSPACE_JPEG,
     63		.priv = 1},
     64	{352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
     65		.bytesperline = 352,
     66		.sizeimage = 352 * 288 * 3 / 8 + 590,
     67		.colorspace = V4L2_COLORSPACE_JPEG,
     68		.priv = 0},
     69};
     70
     71/* Frame packet header offsets for the spca500 */
     72#define SPCA500_OFFSET_PADDINGLB 2
     73#define SPCA500_OFFSET_PADDINGHB 3
     74#define SPCA500_OFFSET_MODE      4
     75#define SPCA500_OFFSET_IMGWIDTH  5
     76#define SPCA500_OFFSET_IMGHEIGHT 6
     77#define SPCA500_OFFSET_IMGMODE   7
     78#define SPCA500_OFFSET_QTBLINDEX 8
     79#define SPCA500_OFFSET_FRAMSEQ   9
     80#define SPCA500_OFFSET_CDSPINFO  10
     81#define SPCA500_OFFSET_GPIO      11
     82#define SPCA500_OFFSET_AUGPIO    12
     83#define SPCA500_OFFSET_DATA      16
     84
     85
     86static const __u16 spca500_visual_defaults[][3] = {
     87	{0x00, 0x0003, 0x816b},	/* SSI not active sync with vsync,
     88				 * hue (H byte) = 0,
     89				 * saturation/hue enable,
     90				 * brightness/contrast enable.
     91				 */
     92	{0x00, 0x0000, 0x8167},	/* brightness = 0 */
     93	{0x00, 0x0020, 0x8168},	/* contrast = 0 */
     94	{0x00, 0x0003, 0x816b},	/* SSI not active sync with vsync,
     95				 * hue (H byte) = 0, saturation/hue enable,
     96				 * brightness/contrast enable.
     97				 * was 0x0003, now 0x0000.
     98				 */
     99	{0x00, 0x0000, 0x816a},	/* hue (L byte) = 0 */
    100	{0x00, 0x0020, 0x8169},	/* saturation = 0x20 */
    101	{0x00, 0x0050, 0x8157},	/* edge gain high threshold */
    102	{0x00, 0x0030, 0x8158},	/* edge gain low threshold */
    103	{0x00, 0x0028, 0x8159},	/* edge bandwidth high threshold */
    104	{0x00, 0x000a, 0x815a},	/* edge bandwidth low threshold */
    105	{0x00, 0x0001, 0x8202},	/* clock rate compensation = 1/25 sec/frame */
    106	{0x0c, 0x0004, 0x0000},
    107	/* set interface */
    108	{}
    109};
    110static const __u16 Clicksmart510_defaults[][3] = {
    111	{0x00, 0x00, 0x8211},
    112	{0x00, 0x01, 0x82c0},
    113	{0x00, 0x10, 0x82cb},
    114	{0x00, 0x0f, 0x800d},
    115	{0x00, 0x82, 0x8225},
    116	{0x00, 0x21, 0x8228},
    117	{0x00, 0x00, 0x8203},
    118	{0x00, 0x00, 0x8204},
    119	{0x00, 0x08, 0x8205},
    120	{0x00, 0xf8, 0x8206},
    121	{0x00, 0x28, 0x8207},
    122	{0x00, 0xa0, 0x8208},
    123	{0x00, 0x08, 0x824a},
    124	{0x00, 0x08, 0x8214},
    125	{0x00, 0x80, 0x82c1},
    126	{0x00, 0x00, 0x82c2},
    127	{0x00, 0x00, 0x82ca},
    128	{0x00, 0x80, 0x82c1},
    129	{0x00, 0x04, 0x82c2},
    130	{0x00, 0x00, 0x82ca},
    131	{0x00, 0xfc, 0x8100},
    132	{0x00, 0xfc, 0x8105},
    133	{0x00, 0x30, 0x8101},
    134	{0x00, 0x00, 0x8102},
    135	{0x00, 0x00, 0x8103},
    136	{0x00, 0x66, 0x8107},
    137	{0x00, 0x00, 0x816b},
    138	{0x00, 0x00, 0x8155},
    139	{0x00, 0x01, 0x8156},
    140	{0x00, 0x60, 0x8157},
    141	{0x00, 0x40, 0x8158},
    142	{0x00, 0x0a, 0x8159},
    143	{0x00, 0x06, 0x815a},
    144	{0x00, 0x00, 0x813f},
    145	{0x00, 0x00, 0x8200},
    146	{0x00, 0x19, 0x8201},
    147	{0x00, 0x00, 0x82c1},
    148	{0x00, 0xa0, 0x82c2},
    149	{0x00, 0x00, 0x82ca},
    150	{0x00, 0x00, 0x8117},
    151	{0x00, 0x00, 0x8118},
    152	{0x00, 0x65, 0x8119},
    153	{0x00, 0x00, 0x811a},
    154	{0x00, 0x00, 0x811b},
    155	{0x00, 0x55, 0x811c},
    156	{0x00, 0x65, 0x811d},
    157	{0x00, 0x55, 0x811e},
    158	{0x00, 0x16, 0x811f},
    159	{0x00, 0x19, 0x8120},
    160	{0x00, 0x80, 0x8103},
    161	{0x00, 0x83, 0x816b},
    162	{0x00, 0x25, 0x8168},
    163	{0x00, 0x01, 0x820f},
    164	{0x00, 0xff, 0x8115},
    165	{0x00, 0x48, 0x8116},
    166	{0x00, 0x50, 0x8151},
    167	{0x00, 0x40, 0x8152},
    168	{0x00, 0x78, 0x8153},
    169	{0x00, 0x40, 0x8154},
    170	{0x00, 0x00, 0x8167},
    171	{0x00, 0x20, 0x8168},
    172	{0x00, 0x00, 0x816a},
    173	{0x00, 0x03, 0x816b},
    174	{0x00, 0x20, 0x8169},
    175	{0x00, 0x60, 0x8157},
    176	{0x00, 0x00, 0x8190},
    177	{0x00, 0x00, 0x81a1},
    178	{0x00, 0x00, 0x81b2},
    179	{0x00, 0x27, 0x8191},
    180	{0x00, 0x27, 0x81a2},
    181	{0x00, 0x27, 0x81b3},
    182	{0x00, 0x4b, 0x8192},
    183	{0x00, 0x4b, 0x81a3},
    184	{0x00, 0x4b, 0x81b4},
    185	{0x00, 0x66, 0x8193},
    186	{0x00, 0x66, 0x81a4},
    187	{0x00, 0x66, 0x81b5},
    188	{0x00, 0x79, 0x8194},
    189	{0x00, 0x79, 0x81a5},
    190	{0x00, 0x79, 0x81b6},
    191	{0x00, 0x8a, 0x8195},
    192	{0x00, 0x8a, 0x81a6},
    193	{0x00, 0x8a, 0x81b7},
    194	{0x00, 0x9b, 0x8196},
    195	{0x00, 0x9b, 0x81a7},
    196	{0x00, 0x9b, 0x81b8},
    197	{0x00, 0xa6, 0x8197},
    198	{0x00, 0xa6, 0x81a8},
    199	{0x00, 0xa6, 0x81b9},
    200	{0x00, 0xb2, 0x8198},
    201	{0x00, 0xb2, 0x81a9},
    202	{0x00, 0xb2, 0x81ba},
    203	{0x00, 0xbe, 0x8199},
    204	{0x00, 0xbe, 0x81aa},
    205	{0x00, 0xbe, 0x81bb},
    206	{0x00, 0xc8, 0x819a},
    207	{0x00, 0xc8, 0x81ab},
    208	{0x00, 0xc8, 0x81bc},
    209	{0x00, 0xd2, 0x819b},
    210	{0x00, 0xd2, 0x81ac},
    211	{0x00, 0xd2, 0x81bd},
    212	{0x00, 0xdb, 0x819c},
    213	{0x00, 0xdb, 0x81ad},
    214	{0x00, 0xdb, 0x81be},
    215	{0x00, 0xe4, 0x819d},
    216	{0x00, 0xe4, 0x81ae},
    217	{0x00, 0xe4, 0x81bf},
    218	{0x00, 0xed, 0x819e},
    219	{0x00, 0xed, 0x81af},
    220	{0x00, 0xed, 0x81c0},
    221	{0x00, 0xf7, 0x819f},
    222	{0x00, 0xf7, 0x81b0},
    223	{0x00, 0xf7, 0x81c1},
    224	{0x00, 0xff, 0x81a0},
    225	{0x00, 0xff, 0x81b1},
    226	{0x00, 0xff, 0x81c2},
    227	{0x00, 0x03, 0x8156},
    228	{0x00, 0x00, 0x8211},
    229	{0x00, 0x20, 0x8168},
    230	{0x00, 0x01, 0x8202},
    231	{0x00, 0x30, 0x8101},
    232	{0x00, 0x00, 0x8111},
    233	{0x00, 0x00, 0x8112},
    234	{0x00, 0x00, 0x8113},
    235	{0x00, 0x00, 0x8114},
    236	{}
    237};
    238
    239static const __u8 qtable_creative_pccam[2][64] = {
    240	{				/* Q-table Y-components */
    241	 0x05, 0x03, 0x03, 0x05, 0x07, 0x0c, 0x0f, 0x12,
    242	 0x04, 0x04, 0x04, 0x06, 0x08, 0x11, 0x12, 0x11,
    243	 0x04, 0x04, 0x05, 0x07, 0x0c, 0x11, 0x15, 0x11,
    244	 0x04, 0x05, 0x07, 0x09, 0x0f, 0x1a, 0x18, 0x13,
    245	 0x05, 0x07, 0x0b, 0x11, 0x14, 0x21, 0x1f, 0x17,
    246	 0x07, 0x0b, 0x11, 0x13, 0x18, 0x1f, 0x22, 0x1c,
    247	 0x0f, 0x13, 0x17, 0x1a, 0x1f, 0x24, 0x24, 0x1e,
    248	 0x16, 0x1c, 0x1d, 0x1d, 0x22, 0x1e, 0x1f, 0x1e},
    249	{				/* Q-table C-components */
    250	 0x05, 0x05, 0x07, 0x0e, 0x1e, 0x1e, 0x1e, 0x1e,
    251	 0x05, 0x06, 0x08, 0x14, 0x1e, 0x1e, 0x1e, 0x1e,
    252	 0x07, 0x08, 0x11, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
    253	 0x0e, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
    254	 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
    255	 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
    256	 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
    257	 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e}
    258};
    259
    260static const __u8 qtable_kodak_ez200[2][64] = {
    261	{				/* Q-table Y-components */
    262	 0x02, 0x01, 0x01, 0x02, 0x02, 0x04, 0x05, 0x06,
    263	 0x01, 0x01, 0x01, 0x02, 0x03, 0x06, 0x06, 0x06,
    264	 0x01, 0x01, 0x02, 0x02, 0x04, 0x06, 0x07, 0x06,
    265	 0x01, 0x02, 0x02, 0x03, 0x05, 0x09, 0x08, 0x06,
    266	 0x02, 0x02, 0x04, 0x06, 0x07, 0x0b, 0x0a, 0x08,
    267	 0x02, 0x04, 0x06, 0x06, 0x08, 0x0a, 0x0b, 0x09,
    268	 0x05, 0x06, 0x08, 0x09, 0x0a, 0x0c, 0x0c, 0x0a,
    269	 0x07, 0x09, 0x0a, 0x0a, 0x0b, 0x0a, 0x0a, 0x0a},
    270	{				/* Q-table C-components */
    271	 0x02, 0x02, 0x02, 0x05, 0x0a, 0x0a, 0x0a, 0x0a,
    272	 0x02, 0x02, 0x03, 0x07, 0x0a, 0x0a, 0x0a, 0x0a,
    273	 0x02, 0x03, 0x06, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
    274	 0x05, 0x07, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
    275	 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
    276	 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
    277	 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
    278	 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a}
    279};
    280
    281static const __u8 qtable_pocketdv[2][64] = {
    282	{		/* Q-table Y-components start registers 0x8800 */
    283	 0x06, 0x04, 0x04, 0x06, 0x0a, 0x10, 0x14, 0x18,
    284	 0x05, 0x05, 0x06, 0x08, 0x0a, 0x17, 0x18, 0x16,
    285	 0x06, 0x05, 0x06, 0x0a, 0x10, 0x17, 0x1c, 0x16,
    286	 0x06, 0x07, 0x09, 0x0c, 0x14, 0x23, 0x20, 0x19,
    287	 0x07, 0x09, 0x0f, 0x16, 0x1b, 0x2c, 0x29, 0x1f,
    288	 0x0a, 0x0e, 0x16, 0x1a, 0x20, 0x2a, 0x2d, 0x25,
    289	 0x14, 0x1a, 0x1f, 0x23, 0x29, 0x30, 0x30, 0x28,
    290	 0x1d, 0x25, 0x26, 0x27, 0x2d, 0x28, 0x29, 0x28,
    291	 },
    292	{		/* Q-table C-components start registers 0x8840 */
    293	 0x07, 0x07, 0x0a, 0x13, 0x28, 0x28, 0x28, 0x28,
    294	 0x07, 0x08, 0x0a, 0x1a, 0x28, 0x28, 0x28, 0x28,
    295	 0x0a, 0x0a, 0x16, 0x28, 0x28, 0x28, 0x28, 0x28,
    296	 0x13, 0x1a, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
    297	 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
    298	 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
    299	 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
    300	 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28}
    301};
    302
    303/* read 'len' bytes to gspca_dev->usb_buf */
    304static void reg_r(struct gspca_dev *gspca_dev,
    305		  __u16 index,
    306		  __u16 length)
    307{
    308	usb_control_msg(gspca_dev->dev,
    309			usb_rcvctrlpipe(gspca_dev->dev, 0),
    310			0,
    311			USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
    312			0,		/* value */
    313			index, gspca_dev->usb_buf, length, 500);
    314}
    315
    316static int reg_w(struct gspca_dev *gspca_dev,
    317		     __u16 req, __u16 index, __u16 value)
    318{
    319	int ret;
    320
    321	gspca_dbg(gspca_dev, D_USBO, "reg write: [0x%02x] = 0x%02x\n",
    322		  index, value);
    323	ret = usb_control_msg(gspca_dev->dev,
    324			usb_sndctrlpipe(gspca_dev->dev, 0),
    325			req,
    326			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
    327			value, index, NULL, 0, 500);
    328	if (ret < 0)
    329		pr_err("reg write: error %d\n", ret);
    330	return ret;
    331}
    332
    333/* returns: negative is error, pos or zero is data */
    334static int reg_r_12(struct gspca_dev *gspca_dev,
    335			__u16 req,	/* bRequest */
    336			__u16 index,	/* wIndex */
    337			__u16 length)	/* wLength (1 or 2 only) */
    338{
    339	int ret;
    340
    341	gspca_dev->usb_buf[1] = 0;
    342	ret = usb_control_msg(gspca_dev->dev,
    343			usb_rcvctrlpipe(gspca_dev->dev, 0),
    344			req,
    345			USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
    346			0,		/* value */
    347			index,
    348			gspca_dev->usb_buf, length,
    349			500);		/* timeout */
    350	if (ret < 0) {
    351		pr_err("reg_r_12 err %d\n", ret);
    352		return ret;
    353	}
    354	return (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0];
    355}
    356
    357/*
    358 * Simple function to wait for a given 8-bit value to be returned from
    359 * a reg_read call.
    360 * Returns: negative is error or timeout, zero is success.
    361 */
    362static int reg_r_wait(struct gspca_dev *gspca_dev,
    363			__u16 reg, __u16 index, __u16 value)
    364{
    365	int ret, cnt = 20;
    366
    367	while (--cnt > 0) {
    368		ret = reg_r_12(gspca_dev, reg, index, 1);
    369		if (ret == value)
    370			return 0;
    371		msleep(50);
    372	}
    373	return -EIO;
    374}
    375
    376static int write_vector(struct gspca_dev *gspca_dev,
    377			const __u16 data[][3])
    378{
    379	int ret, i = 0;
    380
    381	while (data[i][0] != 0 || data[i][1] != 0 || data[i][2] != 0) {
    382		ret = reg_w(gspca_dev, data[i][0], data[i][2], data[i][1]);
    383		if (ret < 0)
    384			return ret;
    385		i++;
    386	}
    387	return 0;
    388}
    389
    390static int spca50x_setup_qtable(struct gspca_dev *gspca_dev,
    391				unsigned int request,
    392				unsigned int ybase,
    393				unsigned int cbase,
    394				const __u8 qtable[2][64])
    395{
    396	int i, err;
    397
    398	/* loop over y components */
    399	for (i = 0; i < 64; i++) {
    400		err = reg_w(gspca_dev, request, ybase + i, qtable[0][i]);
    401		if (err < 0)
    402			return err;
    403	}
    404
    405	/* loop over c components */
    406	for (i = 0; i < 64; i++) {
    407		err = reg_w(gspca_dev, request, cbase + i, qtable[1][i]);
    408		if (err < 0)
    409			return err;
    410	}
    411	return 0;
    412}
    413
    414static void spca500_ping310(struct gspca_dev *gspca_dev)
    415{
    416	reg_r(gspca_dev, 0x0d04, 2);
    417	gspca_dbg(gspca_dev, D_STREAM, "ClickSmart310 ping 0x0d04 0x%02x 0x%02x\n",
    418		  gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
    419}
    420
    421static void spca500_clksmart310_init(struct gspca_dev *gspca_dev)
    422{
    423	reg_r(gspca_dev, 0x0d05, 2);
    424	gspca_dbg(gspca_dev, D_STREAM, "ClickSmart310 init 0x0d05 0x%02x 0x%02x\n",
    425		  gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
    426	reg_w(gspca_dev, 0x00, 0x8167, 0x5a);
    427	spca500_ping310(gspca_dev);
    428
    429	reg_w(gspca_dev, 0x00, 0x8168, 0x22);
    430	reg_w(gspca_dev, 0x00, 0x816a, 0xc0);
    431	reg_w(gspca_dev, 0x00, 0x816b, 0x0b);
    432	reg_w(gspca_dev, 0x00, 0x8169, 0x25);
    433	reg_w(gspca_dev, 0x00, 0x8157, 0x5b);
    434	reg_w(gspca_dev, 0x00, 0x8158, 0x5b);
    435	reg_w(gspca_dev, 0x00, 0x813f, 0x03);
    436	reg_w(gspca_dev, 0x00, 0x8151, 0x4a);
    437	reg_w(gspca_dev, 0x00, 0x8153, 0x78);
    438	reg_w(gspca_dev, 0x00, 0x0d01, 0x04);
    439						/* 00 for adjust shutter */
    440	reg_w(gspca_dev, 0x00, 0x0d02, 0x01);
    441	reg_w(gspca_dev, 0x00, 0x8169, 0x25);
    442	reg_w(gspca_dev, 0x00, 0x0d01, 0x02);
    443}
    444
    445static void spca500_setmode(struct gspca_dev *gspca_dev,
    446			__u8 xmult, __u8 ymult)
    447{
    448	int mode;
    449
    450	/* set x multiplier */
    451	reg_w(gspca_dev, 0, 0x8001, xmult);
    452
    453	/* set y multiplier */
    454	reg_w(gspca_dev, 0, 0x8002, ymult);
    455
    456	/* use compressed mode, VGA, with mode specific subsample */
    457	mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
    458	reg_w(gspca_dev, 0, 0x8003, mode << 4);
    459}
    460
    461static int spca500_full_reset(struct gspca_dev *gspca_dev)
    462{
    463	int err;
    464
    465	/* send the reset command */
    466	err = reg_w(gspca_dev, 0xe0, 0x0001, 0x0000);
    467	if (err < 0)
    468		return err;
    469
    470	/* wait for the reset to complete */
    471	err = reg_r_wait(gspca_dev, 0x06, 0x0000, 0x0000);
    472	if (err < 0)
    473		return err;
    474	err = reg_w(gspca_dev, 0xe0, 0x0000, 0x0000);
    475	if (err < 0)
    476		return err;
    477	err = reg_r_wait(gspca_dev, 0x06, 0, 0);
    478	if (err < 0) {
    479		gspca_err(gspca_dev, "reg_r_wait() failed\n");
    480		return err;
    481	}
    482	/* all ok */
    483	return 0;
    484}
    485
    486/* Synchro the Bridge with sensor */
    487/* Maybe that will work on all spca500 chip */
    488/* because i only own a clicksmart310 try for that chip */
    489/* using spca50x_set_packet_size() cause an Ooops here */
    490/* usb_set_interface from kernel 2.6.x clear all the urb stuff */
    491/* up-port the same feature as in 2.4.x kernel */
    492static int spca500_synch310(struct gspca_dev *gspca_dev)
    493{
    494	if (usb_set_interface(gspca_dev->dev, gspca_dev->iface, 0) < 0) {
    495		gspca_err(gspca_dev, "Set packet size: set interface error\n");
    496		goto error;
    497	}
    498	spca500_ping310(gspca_dev);
    499
    500	reg_r(gspca_dev, 0x0d00, 1);
    501
    502	/* need alt setting here */
    503	gspca_dbg(gspca_dev, D_PACK, "ClickSmart310 sync alt: %d\n",
    504		  gspca_dev->alt);
    505
    506	/* Windoze use pipe with altsetting 6 why 7 here */
    507	if (usb_set_interface(gspca_dev->dev,
    508				gspca_dev->iface,
    509				gspca_dev->alt) < 0) {
    510		gspca_err(gspca_dev, "Set packet size: set interface error\n");
    511		goto error;
    512	}
    513	return 0;
    514error:
    515	return -EBUSY;
    516}
    517
    518static void spca500_reinit(struct gspca_dev *gspca_dev)
    519{
    520	int err;
    521	__u8 Data;
    522
    523	/* some unknown command from Aiptek pocket dv and family300 */
    524
    525	reg_w(gspca_dev, 0x00, 0x0d01, 0x01);
    526	reg_w(gspca_dev, 0x00, 0x0d03, 0x00);
    527	reg_w(gspca_dev, 0x00, 0x0d02, 0x01);
    528
    529	/* enable drop packet */
    530	reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
    531
    532	err = spca50x_setup_qtable(gspca_dev, 0x00, 0x8800, 0x8840,
    533				 qtable_pocketdv);
    534	if (err < 0)
    535		gspca_err(gspca_dev, "spca50x_setup_qtable failed on init\n");
    536
    537	/* set qtable index */
    538	reg_w(gspca_dev, 0x00, 0x8880, 2);
    539	/* family cam Quicksmart stuff */
    540	reg_w(gspca_dev, 0x00, 0x800a, 0x00);
    541	/* Set agc transfer: synced between frames */
    542	reg_w(gspca_dev, 0x00, 0x820f, 0x01);
    543	/* Init SDRAM - needed for SDRAM access */
    544	reg_w(gspca_dev, 0x00, 0x870a, 0x04);
    545	/*Start init sequence or stream */
    546	reg_w(gspca_dev, 0, 0x8003, 0x00);
    547	/* switch to video camera mode */
    548	reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
    549	msleep(2000);
    550	if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0) {
    551		reg_r(gspca_dev, 0x816b, 1);
    552		Data = gspca_dev->usb_buf[0];
    553		reg_w(gspca_dev, 0x00, 0x816b, Data);
    554	}
    555}
    556
    557/* this function is called at probe time */
    558static int sd_config(struct gspca_dev *gspca_dev,
    559			const struct usb_device_id *id)
    560{
    561	struct sd *sd = (struct sd *) gspca_dev;
    562	struct cam *cam;
    563
    564	cam = &gspca_dev->cam;
    565	sd->subtype = id->driver_info;
    566	if (sd->subtype != LogitechClickSmart310) {
    567		cam->cam_mode = vga_mode;
    568		cam->nmodes = ARRAY_SIZE(vga_mode);
    569	} else {
    570		cam->cam_mode = sif_mode;
    571		cam->nmodes = ARRAY_SIZE(sif_mode);
    572	}
    573	return 0;
    574}
    575
    576/* this function is called at probe and resume time */
    577static int sd_init(struct gspca_dev *gspca_dev)
    578{
    579	struct sd *sd = (struct sd *) gspca_dev;
    580
    581	/* initialisation of spca500 based cameras is deferred */
    582	gspca_dbg(gspca_dev, D_STREAM, "SPCA500 init\n");
    583	if (sd->subtype == LogitechClickSmart310)
    584		spca500_clksmart310_init(gspca_dev);
    585/*	else
    586		spca500_initialise(gspca_dev); */
    587	gspca_dbg(gspca_dev, D_STREAM, "SPCA500 init done\n");
    588	return 0;
    589}
    590
    591static int sd_start(struct gspca_dev *gspca_dev)
    592{
    593	struct sd *sd = (struct sd *) gspca_dev;
    594	int err;
    595	__u8 Data;
    596	__u8 xmult, ymult;
    597
    598	/* create the JPEG header */
    599	jpeg_define(sd->jpeg_hdr, gspca_dev->pixfmt.height,
    600			gspca_dev->pixfmt.width,
    601			0x22);		/* JPEG 411 */
    602	jpeg_set_qual(sd->jpeg_hdr, QUALITY);
    603
    604	if (sd->subtype == LogitechClickSmart310) {
    605		xmult = 0x16;
    606		ymult = 0x12;
    607	} else {
    608		xmult = 0x28;
    609		ymult = 0x1e;
    610	}
    611
    612	/* is there a sensor here ? */
    613	reg_r(gspca_dev, 0x8a04, 1);
    614	gspca_dbg(gspca_dev, D_STREAM, "Spca500 Sensor Address 0x%02x\n",
    615		  gspca_dev->usb_buf[0]);
    616	gspca_dbg(gspca_dev, D_STREAM, "Spca500 curr_mode: %d Xmult: 0x%02x, Ymult: 0x%02x",
    617		  gspca_dev->curr_mode, xmult, ymult);
    618
    619	/* setup qtable */
    620	switch (sd->subtype) {
    621	case LogitechClickSmart310:
    622		 spca500_setmode(gspca_dev, xmult, ymult);
    623
    624		/* enable drop packet */
    625		reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
    626		reg_w(gspca_dev, 0x00, 0x8880, 3);
    627		err = spca50x_setup_qtable(gspca_dev,
    628					   0x00, 0x8800, 0x8840,
    629					   qtable_creative_pccam);
    630		if (err < 0)
    631			gspca_err(gspca_dev, "spca50x_setup_qtable failed\n");
    632		/* Init SDRAM - needed for SDRAM access */
    633		reg_w(gspca_dev, 0x00, 0x870a, 0x04);
    634
    635		/* switch to video camera mode */
    636		reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
    637		msleep(500);
    638		if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
    639			gspca_err(gspca_dev, "reg_r_wait() failed\n");
    640
    641		reg_r(gspca_dev, 0x816b, 1);
    642		Data = gspca_dev->usb_buf[0];
    643		reg_w(gspca_dev, 0x00, 0x816b, Data);
    644
    645		spca500_synch310(gspca_dev);
    646
    647		write_vector(gspca_dev, spca500_visual_defaults);
    648		spca500_setmode(gspca_dev, xmult, ymult);
    649		/* enable drop packet */
    650		err = reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
    651		if (err < 0)
    652			gspca_err(gspca_dev, "failed to enable drop packet\n");
    653		reg_w(gspca_dev, 0x00, 0x8880, 3);
    654		err = spca50x_setup_qtable(gspca_dev,
    655					   0x00, 0x8800, 0x8840,
    656					   qtable_creative_pccam);
    657		if (err < 0)
    658			gspca_err(gspca_dev, "spca50x_setup_qtable failed\n");
    659
    660		/* Init SDRAM - needed for SDRAM access */
    661		reg_w(gspca_dev, 0x00, 0x870a, 0x04);
    662
    663		/* switch to video camera mode */
    664		reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
    665
    666		if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
    667			gspca_err(gspca_dev, "reg_r_wait() failed\n");
    668
    669		reg_r(gspca_dev, 0x816b, 1);
    670		Data = gspca_dev->usb_buf[0];
    671		reg_w(gspca_dev, 0x00, 0x816b, Data);
    672		break;
    673	case CreativePCCam300:		/* Creative PC-CAM 300 640x480 CCD */
    674	case IntelPocketPCCamera:	/* FIXME: Temporary fix for
    675					 *	Intel Pocket PC Camera
    676					 *	- NWG (Sat 29th March 2003) */
    677
    678		/* do a full reset */
    679		err = spca500_full_reset(gspca_dev);
    680		if (err < 0)
    681			gspca_err(gspca_dev, "spca500_full_reset failed\n");
    682
    683		/* enable drop packet */
    684		err = reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
    685		if (err < 0)
    686			gspca_err(gspca_dev, "failed to enable drop packet\n");
    687		reg_w(gspca_dev, 0x00, 0x8880, 3);
    688		err = spca50x_setup_qtable(gspca_dev,
    689					   0x00, 0x8800, 0x8840,
    690					   qtable_creative_pccam);
    691		if (err < 0)
    692			gspca_err(gspca_dev, "spca50x_setup_qtable failed\n");
    693
    694		spca500_setmode(gspca_dev, xmult, ymult);
    695		reg_w(gspca_dev, 0x20, 0x0001, 0x0004);
    696
    697		/* switch to video camera mode */
    698		reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
    699
    700		if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
    701			gspca_err(gspca_dev, "reg_r_wait() failed\n");
    702
    703		reg_r(gspca_dev, 0x816b, 1);
    704		Data = gspca_dev->usb_buf[0];
    705		reg_w(gspca_dev, 0x00, 0x816b, Data);
    706
    707/*		write_vector(gspca_dev, spca500_visual_defaults); */
    708		break;
    709	case KodakEZ200:		/* Kodak EZ200 */
    710
    711		/* do a full reset */
    712		err = spca500_full_reset(gspca_dev);
    713		if (err < 0)
    714			gspca_err(gspca_dev, "spca500_full_reset failed\n");
    715		/* enable drop packet */
    716		reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
    717		reg_w(gspca_dev, 0x00, 0x8880, 0);
    718		err = spca50x_setup_qtable(gspca_dev,
    719					   0x00, 0x8800, 0x8840,
    720					   qtable_kodak_ez200);
    721		if (err < 0)
    722			gspca_err(gspca_dev, "spca50x_setup_qtable failed\n");
    723		spca500_setmode(gspca_dev, xmult, ymult);
    724
    725		reg_w(gspca_dev, 0x20, 0x0001, 0x0004);
    726
    727		/* switch to video camera mode */
    728		reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
    729
    730		if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
    731			gspca_err(gspca_dev, "reg_r_wait() failed\n");
    732
    733		reg_r(gspca_dev, 0x816b, 1);
    734		Data = gspca_dev->usb_buf[0];
    735		reg_w(gspca_dev, 0x00, 0x816b, Data);
    736
    737/*		write_vector(gspca_dev, spca500_visual_defaults); */
    738		break;
    739
    740	case BenqDC1016:
    741	case DLinkDSC350:		/* FamilyCam 300 */
    742	case AiptekPocketDV:		/* Aiptek PocketDV */
    743	case Gsmartmini:		/*Mustek Gsmart Mini */
    744	case MustekGsmart300:		/* Mustek Gsmart 300 */
    745	case PalmPixDC85:
    746	case Optimedia:
    747	case ToptroIndus:
    748	case AgfaCl20:
    749		spca500_reinit(gspca_dev);
    750		reg_w(gspca_dev, 0x00, 0x0d01, 0x01);
    751		/* enable drop packet */
    752		reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
    753
    754		err = spca50x_setup_qtable(gspca_dev,
    755				   0x00, 0x8800, 0x8840, qtable_pocketdv);
    756		if (err < 0)
    757			gspca_err(gspca_dev, "spca50x_setup_qtable failed\n");
    758		reg_w(gspca_dev, 0x00, 0x8880, 2);
    759
    760		/* familycam Quicksmart pocketDV stuff */
    761		reg_w(gspca_dev, 0x00, 0x800a, 0x00);
    762		/* Set agc transfer: synced between frames */
    763		reg_w(gspca_dev, 0x00, 0x820f, 0x01);
    764		/* Init SDRAM - needed for SDRAM access */
    765		reg_w(gspca_dev, 0x00, 0x870a, 0x04);
    766
    767		spca500_setmode(gspca_dev, xmult, ymult);
    768		/* switch to video camera mode */
    769		reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
    770
    771		reg_r_wait(gspca_dev, 0, 0x8000, 0x44);
    772
    773		reg_r(gspca_dev, 0x816b, 1);
    774		Data = gspca_dev->usb_buf[0];
    775		reg_w(gspca_dev, 0x00, 0x816b, Data);
    776		break;
    777	case LogitechTraveler:
    778	case LogitechClickSmart510:
    779		reg_w(gspca_dev, 0x02, 0x00, 0x00);
    780		/* enable drop packet */
    781		reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
    782
    783		err = spca50x_setup_qtable(gspca_dev,
    784					0x00, 0x8800,
    785					0x8840, qtable_creative_pccam);
    786		if (err < 0)
    787			gspca_err(gspca_dev, "spca50x_setup_qtable failed\n");
    788		reg_w(gspca_dev, 0x00, 0x8880, 3);
    789		reg_w(gspca_dev, 0x00, 0x800a, 0x00);
    790		/* Init SDRAM - needed for SDRAM access */
    791		reg_w(gspca_dev, 0x00, 0x870a, 0x04);
    792
    793		spca500_setmode(gspca_dev, xmult, ymult);
    794
    795		/* switch to video camera mode */
    796		reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
    797		reg_r_wait(gspca_dev, 0, 0x8000, 0x44);
    798
    799		reg_r(gspca_dev, 0x816b, 1);
    800		Data = gspca_dev->usb_buf[0];
    801		reg_w(gspca_dev, 0x00, 0x816b, Data);
    802		write_vector(gspca_dev, Clicksmart510_defaults);
    803		break;
    804	}
    805	return 0;
    806}
    807
    808static void sd_stopN(struct gspca_dev *gspca_dev)
    809{
    810	reg_w(gspca_dev, 0, 0x8003, 0x00);
    811
    812	/* switch to video camera mode */
    813	reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
    814	reg_r(gspca_dev, 0x8000, 1);
    815	gspca_dbg(gspca_dev, D_STREAM, "stop SPCA500 done reg8000: 0x%2x\n",
    816		  gspca_dev->usb_buf[0]);
    817}
    818
    819static void sd_pkt_scan(struct gspca_dev *gspca_dev,
    820			u8 *data,			/* isoc packet */
    821			int len)			/* iso packet length */
    822{
    823	struct sd *sd = (struct sd *) gspca_dev;
    824	int i;
    825	static __u8 ffd9[] = {0xff, 0xd9};
    826
    827/* frames are jpeg 4.1.1 without 0xff escape */
    828	if (data[0] == 0xff) {
    829		if (data[1] != 0x01) {	/* drop packet */
    830/*			gspca_dev->last_packet_type = DISCARD_PACKET; */
    831			return;
    832		}
    833		gspca_frame_add(gspca_dev, LAST_PACKET,
    834					ffd9, 2);
    835
    836		/* put the JPEG header in the new frame */
    837		gspca_frame_add(gspca_dev, FIRST_PACKET,
    838			sd->jpeg_hdr, JPEG_HDR_SZ);
    839
    840		data += SPCA500_OFFSET_DATA;
    841		len -= SPCA500_OFFSET_DATA;
    842	} else {
    843		data += 1;
    844		len -= 1;
    845	}
    846
    847	/* add 0x00 after 0xff */
    848	i = 0;
    849	do {
    850		if (data[i] == 0xff) {
    851			gspca_frame_add(gspca_dev, INTER_PACKET,
    852					data, i + 1);
    853			len -= i;
    854			data += i;
    855			*data = 0x00;
    856			i = 0;
    857		}
    858		i++;
    859	} while (i < len);
    860	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
    861}
    862
    863static void setbrightness(struct gspca_dev *gspca_dev, s32 val)
    864{
    865	reg_w(gspca_dev, 0x00, 0x8167,
    866			(__u8) (val - 128));
    867}
    868
    869static void setcontrast(struct gspca_dev *gspca_dev, s32 val)
    870{
    871	reg_w(gspca_dev, 0x00, 0x8168, val);
    872}
    873
    874static void setcolors(struct gspca_dev *gspca_dev, s32 val)
    875{
    876	reg_w(gspca_dev, 0x00, 0x8169, val);
    877}
    878
    879static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
    880{
    881	struct gspca_dev *gspca_dev =
    882		container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
    883
    884	gspca_dev->usb_err = 0;
    885
    886	if (!gspca_dev->streaming)
    887		return 0;
    888
    889	switch (ctrl->id) {
    890	case V4L2_CID_BRIGHTNESS:
    891		setbrightness(gspca_dev, ctrl->val);
    892		break;
    893	case V4L2_CID_CONTRAST:
    894		setcontrast(gspca_dev, ctrl->val);
    895		break;
    896	case V4L2_CID_SATURATION:
    897		setcolors(gspca_dev, ctrl->val);
    898		break;
    899	}
    900	return gspca_dev->usb_err;
    901}
    902
    903static const struct v4l2_ctrl_ops sd_ctrl_ops = {
    904	.s_ctrl = sd_s_ctrl,
    905};
    906
    907static int sd_init_controls(struct gspca_dev *gspca_dev)
    908{
    909	struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
    910
    911	gspca_dev->vdev.ctrl_handler = hdl;
    912	v4l2_ctrl_handler_init(hdl, 3);
    913	v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
    914			V4L2_CID_BRIGHTNESS, 0, 255, 1, 127);
    915	v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
    916			V4L2_CID_CONTRAST, 0, 63, 1, 31);
    917	v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
    918			V4L2_CID_SATURATION, 0, 63, 1, 31);
    919
    920	if (hdl->error) {
    921		pr_err("Could not initialize controls\n");
    922		return hdl->error;
    923	}
    924	return 0;
    925}
    926
    927/* sub-driver description */
    928static const struct sd_desc sd_desc = {
    929	.name = MODULE_NAME,
    930	.config = sd_config,
    931	.init = sd_init,
    932	.init_controls = sd_init_controls,
    933	.start = sd_start,
    934	.stopN = sd_stopN,
    935	.pkt_scan = sd_pkt_scan,
    936};
    937
    938/* -- module initialisation -- */
    939static const struct usb_device_id device_table[] = {
    940	{USB_DEVICE(0x040a, 0x0300), .driver_info = KodakEZ200},
    941	{USB_DEVICE(0x041e, 0x400a), .driver_info = CreativePCCam300},
    942	{USB_DEVICE(0x046d, 0x0890), .driver_info = LogitechTraveler},
    943	{USB_DEVICE(0x046d, 0x0900), .driver_info = LogitechClickSmart310},
    944	{USB_DEVICE(0x046d, 0x0901), .driver_info = LogitechClickSmart510},
    945	{USB_DEVICE(0x04a5, 0x300c), .driver_info = BenqDC1016},
    946	{USB_DEVICE(0x04fc, 0x7333), .driver_info = PalmPixDC85},
    947	{USB_DEVICE(0x055f, 0xc200), .driver_info = MustekGsmart300},
    948	{USB_DEVICE(0x055f, 0xc220), .driver_info = Gsmartmini},
    949	{USB_DEVICE(0x06bd, 0x0404), .driver_info = AgfaCl20},
    950	{USB_DEVICE(0x06be, 0x0800), .driver_info = Optimedia},
    951	{USB_DEVICE(0x084d, 0x0003), .driver_info = DLinkDSC350},
    952	{USB_DEVICE(0x08ca, 0x0103), .driver_info = AiptekPocketDV},
    953	{USB_DEVICE(0x2899, 0x012c), .driver_info = ToptroIndus},
    954	{USB_DEVICE(0x8086, 0x0630), .driver_info = IntelPocketPCCamera},
    955	{}
    956};
    957MODULE_DEVICE_TABLE(usb, device_table);
    958
    959/* -- device connect -- */
    960static int sd_probe(struct usb_interface *intf,
    961			const struct usb_device_id *id)
    962{
    963	return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
    964				THIS_MODULE);
    965}
    966
    967static struct usb_driver sd_driver = {
    968	.name = MODULE_NAME,
    969	.id_table = device_table,
    970	.probe = sd_probe,
    971	.disconnect = gspca_disconnect,
    972#ifdef CONFIG_PM
    973	.suspend = gspca_suspend,
    974	.resume = gspca_resume,
    975	.reset_resume = gspca_resume,
    976#endif
    977};
    978
    979module_usb_driver(sd_driver);