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

spca1528.c (10294B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * spca1528 subdriver
      4 *
      5 * Copyright (C) 2010-2011 Jean-Francois Moine (http://moinejf.free.fr)
      6 */
      7
      8#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
      9
     10#define MODULE_NAME "spca1528"
     11
     12#include "gspca.h"
     13#include "jpeg.h"
     14
     15MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
     16MODULE_DESCRIPTION("SPCA1528 USB Camera Driver");
     17MODULE_LICENSE("GPL");
     18
     19/* specific webcam descriptor */
     20struct sd {
     21	struct gspca_dev gspca_dev;	/* !! must be the first item */
     22
     23	u8 pkt_seq;
     24
     25	u8 jpeg_hdr[JPEG_HDR_SZ];
     26};
     27
     28static const struct v4l2_pix_format vga_mode[] = {
     29/*		(does not work correctly)
     30	{176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
     31		.bytesperline = 176,
     32		.sizeimage = 176 * 144 * 5 / 8 + 590,
     33		.colorspace = V4L2_COLORSPACE_JPEG,
     34		.priv = 3},
     35*/
     36	{320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
     37		.bytesperline = 320,
     38		.sizeimage = 320 * 240 * 4 / 8 + 590,
     39		.colorspace = V4L2_COLORSPACE_JPEG,
     40		.priv = 2},
     41	{640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
     42		.bytesperline = 640,
     43		.sizeimage = 640 * 480 * 3 / 8 + 590,
     44		.colorspace = V4L2_COLORSPACE_JPEG,
     45		.priv = 1},
     46};
     47
     48/* read <len> bytes to gspca usb_buf */
     49static void reg_r(struct gspca_dev *gspca_dev,
     50			u8 req,
     51			u16 index,
     52			int len)
     53{
     54#if USB_BUF_SZ < 64
     55#error "USB buffer too small"
     56#endif
     57	struct usb_device *dev = gspca_dev->dev;
     58	int ret;
     59
     60	if (gspca_dev->usb_err < 0)
     61		return;
     62	ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
     63			req,
     64			USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
     65			0x0000,			/* value */
     66			index,
     67			gspca_dev->usb_buf, len,
     68			500);
     69	gspca_dbg(gspca_dev, D_USBI, "GET %02x 0000 %04x %02x\n", req, index,
     70		  gspca_dev->usb_buf[0]);
     71	if (ret < 0) {
     72		pr_err("reg_r err %d\n", ret);
     73		gspca_dev->usb_err = ret;
     74		/*
     75		 * Make sure the buffer is zeroed to avoid uninitialized
     76		 * values.
     77		 */
     78		memset(gspca_dev->usb_buf, 0, USB_BUF_SZ);
     79	}
     80}
     81
     82static void reg_w(struct gspca_dev *gspca_dev,
     83			u8 req,
     84			u16 value,
     85			u16 index)
     86{
     87	struct usb_device *dev = gspca_dev->dev;
     88	int ret;
     89
     90	if (gspca_dev->usb_err < 0)
     91		return;
     92	gspca_dbg(gspca_dev, D_USBO, "SET %02x %04x %04x\n", req, value, index);
     93	ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
     94			req,
     95			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
     96			value, index,
     97			NULL, 0, 500);
     98	if (ret < 0) {
     99		pr_err("reg_w err %d\n", ret);
    100		gspca_dev->usb_err = ret;
    101	}
    102}
    103
    104static void reg_wb(struct gspca_dev *gspca_dev,
    105			u8 req,
    106			u16 value,
    107			u16 index,
    108			u8 byte)
    109{
    110	struct usb_device *dev = gspca_dev->dev;
    111	int ret;
    112
    113	if (gspca_dev->usb_err < 0)
    114		return;
    115	gspca_dbg(gspca_dev, D_USBO, "SET %02x %04x %04x %02x\n",
    116		  req, value, index, byte);
    117	gspca_dev->usb_buf[0] = byte;
    118	ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
    119			req,
    120			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
    121			value, index,
    122			gspca_dev->usb_buf, 1, 500);
    123	if (ret < 0) {
    124		pr_err("reg_w err %d\n", ret);
    125		gspca_dev->usb_err = ret;
    126	}
    127}
    128
    129static void wait_status_0(struct gspca_dev *gspca_dev)
    130{
    131	int i, w;
    132
    133	i = 16;
    134	w = 0;
    135	do {
    136		reg_r(gspca_dev, 0x21, 0x0000, 1);
    137		if (gspca_dev->usb_buf[0] == 0)
    138			return;
    139		w += 15;
    140		msleep(w);
    141	} while (--i > 0);
    142	gspca_err(gspca_dev, "wait_status_0 timeout\n");
    143	gspca_dev->usb_err = -ETIME;
    144}
    145
    146static void wait_status_1(struct gspca_dev *gspca_dev)
    147{
    148	int i;
    149
    150	i = 10;
    151	do {
    152		reg_r(gspca_dev, 0x21, 0x0001, 1);
    153		msleep(10);
    154		if (gspca_dev->usb_buf[0] == 1) {
    155			reg_wb(gspca_dev, 0x21, 0x0000, 0x0001, 0x00);
    156			reg_r(gspca_dev, 0x21, 0x0001, 1);
    157			return;
    158		}
    159	} while (--i > 0);
    160	gspca_err(gspca_dev, "wait_status_1 timeout\n");
    161	gspca_dev->usb_err = -ETIME;
    162}
    163
    164static void setbrightness(struct gspca_dev *gspca_dev, s32 val)
    165{
    166	reg_wb(gspca_dev, 0xc0, 0x0000, 0x00c0, val);
    167}
    168
    169static void setcontrast(struct gspca_dev *gspca_dev, s32 val)
    170{
    171	reg_wb(gspca_dev, 0xc1, 0x0000, 0x00c1, val);
    172}
    173
    174static void sethue(struct gspca_dev *gspca_dev, s32 val)
    175{
    176	reg_wb(gspca_dev, 0xc2, 0x0000, 0x0000, val);
    177}
    178
    179static void setcolor(struct gspca_dev *gspca_dev, s32 val)
    180{
    181	reg_wb(gspca_dev, 0xc3, 0x0000, 0x00c3, val);
    182}
    183
    184static void setsharpness(struct gspca_dev *gspca_dev, s32 val)
    185{
    186	reg_wb(gspca_dev, 0xc4, 0x0000, 0x00c4, val);
    187}
    188
    189/* this function is called at probe time */
    190static int sd_config(struct gspca_dev *gspca_dev,
    191			const struct usb_device_id *id)
    192{
    193	gspca_dev->cam.cam_mode = vga_mode;
    194	gspca_dev->cam.nmodes = ARRAY_SIZE(vga_mode);
    195	gspca_dev->cam.npkt = 128; /* number of packets per ISOC message */
    196			/*fixme: 256 in ms-win traces*/
    197
    198	return 0;
    199}
    200
    201/* this function is called at probe and resume time */
    202static int sd_init(struct gspca_dev *gspca_dev)
    203{
    204	reg_w(gspca_dev, 0x00, 0x0001, 0x2067);
    205	reg_w(gspca_dev, 0x00, 0x00d0, 0x206b);
    206	reg_w(gspca_dev, 0x00, 0x0000, 0x206c);
    207	reg_w(gspca_dev, 0x00, 0x0001, 0x2069);
    208	msleep(8);
    209	reg_w(gspca_dev, 0x00, 0x00c0, 0x206b);
    210	reg_w(gspca_dev, 0x00, 0x0000, 0x206c);
    211	reg_w(gspca_dev, 0x00, 0x0001, 0x2069);
    212
    213	reg_r(gspca_dev, 0x20, 0x0000, 1);
    214	reg_r(gspca_dev, 0x20, 0x0000, 5);
    215	reg_r(gspca_dev, 0x23, 0x0000, 64);
    216	gspca_dbg(gspca_dev, D_PROBE, "%s%s\n", &gspca_dev->usb_buf[0x1c],
    217		  &gspca_dev->usb_buf[0x30]);
    218	reg_r(gspca_dev, 0x23, 0x0001, 64);
    219	return gspca_dev->usb_err;
    220}
    221
    222/* function called at start time before URB creation */
    223static int sd_isoc_init(struct gspca_dev *gspca_dev)
    224{
    225	u8 mode;
    226
    227	reg_r(gspca_dev, 0x00, 0x2520, 1);
    228	wait_status_0(gspca_dev);
    229	reg_w(gspca_dev, 0xc5, 0x0003, 0x0000);
    230	wait_status_1(gspca_dev);
    231
    232	wait_status_0(gspca_dev);
    233	mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
    234	reg_wb(gspca_dev, 0x25, 0x0000, 0x0004, mode);
    235	reg_r(gspca_dev, 0x25, 0x0004, 1);
    236	reg_wb(gspca_dev, 0x27, 0x0000, 0x0000, 0x06);	/* 420 */
    237	reg_r(gspca_dev, 0x27, 0x0000, 1);
    238
    239/* not useful..
    240	gspca_dev->alt = 4;		* use alternate setting 3 */
    241
    242	return gspca_dev->usb_err;
    243}
    244
    245/* -- start the camera -- */
    246static int sd_start(struct gspca_dev *gspca_dev)
    247{
    248	struct sd *sd = (struct sd *) gspca_dev;
    249
    250	/* initialize the JPEG header */
    251	jpeg_define(sd->jpeg_hdr, gspca_dev->pixfmt.height,
    252			gspca_dev->pixfmt.width,
    253			0x22);		/* JPEG 411 */
    254
    255	/* the JPEG quality shall be 85% */
    256	jpeg_set_qual(sd->jpeg_hdr, 85);
    257
    258	reg_r(gspca_dev, 0x00, 0x2520, 1);
    259	msleep(8);
    260
    261	/* start the capture */
    262	wait_status_0(gspca_dev);
    263	reg_w(gspca_dev, 0x31, 0x0000, 0x0004);	/* start request */
    264	wait_status_1(gspca_dev);
    265	wait_status_0(gspca_dev);
    266	msleep(200);
    267
    268	sd->pkt_seq = 0;
    269	return gspca_dev->usb_err;
    270}
    271
    272static void sd_stopN(struct gspca_dev *gspca_dev)
    273{
    274	/* stop the capture */
    275	wait_status_0(gspca_dev);
    276	reg_w(gspca_dev, 0x31, 0x0000, 0x0000);	/* stop request */
    277	wait_status_1(gspca_dev);
    278	wait_status_0(gspca_dev);
    279}
    280
    281/* move a packet adding 0x00 after 0xff */
    282static void add_packet(struct gspca_dev *gspca_dev,
    283			u8 *data,
    284			int len)
    285{
    286	int i;
    287
    288	i = 0;
    289	do {
    290		if (data[i] == 0xff) {
    291			gspca_frame_add(gspca_dev, INTER_PACKET,
    292					data, i + 1);
    293			len -= i;
    294			data += i;
    295			*data = 0x00;
    296			i = 0;
    297		}
    298	} while (++i < len);
    299	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
    300}
    301
    302static void sd_pkt_scan(struct gspca_dev *gspca_dev,
    303			u8 *data,			/* isoc packet */
    304			int len)			/* iso packet length */
    305{
    306	struct sd *sd = (struct sd *) gspca_dev;
    307	static const u8 ffd9[] = {0xff, 0xd9};
    308
    309	/* image packets start with:
    310	 *	02 8n
    311	 * with <n> bit:
    312	 *	0x01: even (0) / odd (1) image
    313	 *	0x02: end of image when set
    314	 */
    315	if (len < 3)
    316		return;				/* empty packet */
    317	if (*data == 0x02) {
    318		if (data[1] & 0x02) {
    319			sd->pkt_seq = !(data[1] & 1);
    320			add_packet(gspca_dev, data + 2, len - 2);
    321			gspca_frame_add(gspca_dev, LAST_PACKET,
    322					ffd9, 2);
    323			return;
    324		}
    325		if ((data[1] & 1) != sd->pkt_seq)
    326			goto err;
    327		if (gspca_dev->last_packet_type == LAST_PACKET)
    328			gspca_frame_add(gspca_dev, FIRST_PACKET,
    329					sd->jpeg_hdr, JPEG_HDR_SZ);
    330		add_packet(gspca_dev, data + 2, len - 2);
    331		return;
    332	}
    333err:
    334	gspca_dev->last_packet_type = DISCARD_PACKET;
    335}
    336
    337static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
    338{
    339	struct gspca_dev *gspca_dev =
    340		container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
    341
    342	gspca_dev->usb_err = 0;
    343
    344	if (!gspca_dev->streaming)
    345		return 0;
    346
    347	switch (ctrl->id) {
    348	case V4L2_CID_BRIGHTNESS:
    349		setbrightness(gspca_dev, ctrl->val);
    350		break;
    351	case V4L2_CID_CONTRAST:
    352		setcontrast(gspca_dev, ctrl->val);
    353		break;
    354	case V4L2_CID_HUE:
    355		sethue(gspca_dev, ctrl->val);
    356		break;
    357	case V4L2_CID_SATURATION:
    358		setcolor(gspca_dev, ctrl->val);
    359		break;
    360	case V4L2_CID_SHARPNESS:
    361		setsharpness(gspca_dev, ctrl->val);
    362		break;
    363	}
    364	return gspca_dev->usb_err;
    365}
    366
    367static const struct v4l2_ctrl_ops sd_ctrl_ops = {
    368	.s_ctrl = sd_s_ctrl,
    369};
    370
    371static int sd_init_controls(struct gspca_dev *gspca_dev)
    372{
    373	struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
    374
    375	gspca_dev->vdev.ctrl_handler = hdl;
    376	v4l2_ctrl_handler_init(hdl, 5);
    377	v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
    378			V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
    379	v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
    380			V4L2_CID_CONTRAST, 0, 8, 1, 1);
    381	v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
    382			V4L2_CID_HUE, 0, 255, 1, 0);
    383	v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
    384			V4L2_CID_SATURATION, 0, 8, 1, 1);
    385	v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
    386			V4L2_CID_SHARPNESS, 0, 255, 1, 0);
    387
    388	if (hdl->error) {
    389		pr_err("Could not initialize controls\n");
    390		return hdl->error;
    391	}
    392	return 0;
    393}
    394
    395/* sub-driver description */
    396static const struct sd_desc sd_desc = {
    397	.name = MODULE_NAME,
    398	.config = sd_config,
    399	.init = sd_init,
    400	.init_controls = sd_init_controls,
    401	.isoc_init = sd_isoc_init,
    402	.start = sd_start,
    403	.stopN = sd_stopN,
    404	.pkt_scan = sd_pkt_scan,
    405};
    406
    407/* -- module initialisation -- */
    408static const struct usb_device_id device_table[] = {
    409	{USB_DEVICE(0x04fc, 0x1528)},
    410	{}
    411};
    412MODULE_DEVICE_TABLE(usb, device_table);
    413
    414/* -- device connect -- */
    415static int sd_probe(struct usb_interface *intf,
    416			const struct usb_device_id *id)
    417{
    418	/* the video interface for isochronous transfer is 1 */
    419	if (intf->cur_altsetting->desc.bInterfaceNumber != 1)
    420		return -ENODEV;
    421
    422	return gspca_dev_probe2(intf, id, &sd_desc, sizeof(struct sd),
    423				THIS_MODULE);
    424}
    425
    426static struct usb_driver sd_driver = {
    427	.name = MODULE_NAME,
    428	.id_table = device_table,
    429	.probe = sd_probe,
    430	.disconnect = gspca_disconnect,
    431#ifdef CONFIG_PM
    432	.suspend = gspca_suspend,
    433	.resume = gspca_resume,
    434	.reset_resume = gspca_resume,
    435#endif
    436};
    437
    438module_usb_driver(sd_driver);