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

jeilinj.c (13361B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * Jeilinj subdriver
      4 *
      5 * Supports some Jeilin dual-mode cameras which use bulk transport and
      6 * download raw JPEG data.
      7 *
      8 * Copyright (C) 2009 Theodore Kilgore
      9 *
     10 * Sportscam DV15 support and control settings are
     11 * Copyright (C) 2011 Patrice Chotard
     12 */
     13
     14#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
     15
     16#define MODULE_NAME "jeilinj"
     17
     18#include <linux/slab.h>
     19#include "gspca.h"
     20#include "jpeg.h"
     21
     22MODULE_AUTHOR("Theodore Kilgore <kilgota@auburn.edu>");
     23MODULE_DESCRIPTION("GSPCA/JEILINJ USB Camera Driver");
     24MODULE_LICENSE("GPL");
     25
     26/* Default timeouts, in ms */
     27#define JEILINJ_CMD_TIMEOUT 500
     28#define JEILINJ_CMD_DELAY 160
     29#define JEILINJ_DATA_TIMEOUT 1000
     30
     31/* Maximum transfer size to use. */
     32#define JEILINJ_MAX_TRANSFER 0x200
     33#define FRAME_HEADER_LEN 0x10
     34#define FRAME_START 0xFFFFFFFF
     35
     36enum {
     37	SAKAR_57379,
     38	SPORTSCAM_DV15,
     39};
     40
     41#define CAMQUALITY_MIN 0	/* highest cam quality */
     42#define CAMQUALITY_MAX 97	/* lowest cam quality  */
     43
     44/* Structure to hold all of our device specific stuff */
     45struct sd {
     46	struct gspca_dev gspca_dev;	/* !! must be the first item */
     47	int blocks_left;
     48	const struct v4l2_pix_format *cap_mode;
     49	struct v4l2_ctrl *freq;
     50	struct v4l2_ctrl *jpegqual;
     51	/* Driver stuff */
     52	u8 type;
     53	u8 quality;				 /* image quality */
     54#define QUALITY_MIN 35
     55#define QUALITY_MAX 85
     56#define QUALITY_DEF 85
     57	u8 jpeg_hdr[JPEG_HDR_SZ];
     58};
     59
     60struct jlj_command {
     61	unsigned char instruction[2];
     62	unsigned char ack_wanted;
     63	unsigned char delay;
     64};
     65
     66/* AFAICT these cameras will only do 320x240. */
     67static struct v4l2_pix_format jlj_mode[] = {
     68	{ 320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
     69		.bytesperline = 320,
     70		.sizeimage = 320 * 240,
     71		.colorspace = V4L2_COLORSPACE_JPEG,
     72		.priv = 0},
     73	{ 640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
     74		.bytesperline = 640,
     75		.sizeimage = 640 * 480,
     76		.colorspace = V4L2_COLORSPACE_JPEG,
     77		.priv = 0}
     78};
     79
     80/*
     81 * cam uses endpoint 0x03 to send commands, 0x84 for read commands,
     82 * and 0x82 for bulk transfer.
     83 */
     84
     85/* All commands are two bytes only */
     86static void jlj_write2(struct gspca_dev *gspca_dev, unsigned char *command)
     87{
     88	int retval;
     89
     90	if (gspca_dev->usb_err < 0)
     91		return;
     92	memcpy(gspca_dev->usb_buf, command, 2);
     93	retval = usb_bulk_msg(gspca_dev->dev,
     94			usb_sndbulkpipe(gspca_dev->dev, 3),
     95			gspca_dev->usb_buf, 2, NULL, 500);
     96	if (retval < 0) {
     97		pr_err("command write [%02x] error %d\n",
     98		       gspca_dev->usb_buf[0], retval);
     99		gspca_dev->usb_err = retval;
    100	}
    101}
    102
    103/* Responses are one byte only */
    104static void jlj_read1(struct gspca_dev *gspca_dev, unsigned char *response)
    105{
    106	int retval;
    107
    108	if (gspca_dev->usb_err < 0)
    109		return;
    110	retval = usb_bulk_msg(gspca_dev->dev,
    111	usb_rcvbulkpipe(gspca_dev->dev, 0x84),
    112				gspca_dev->usb_buf, 1, NULL, 500);
    113	*response = gspca_dev->usb_buf[0];
    114	if (retval < 0) {
    115		pr_err("read command [%02x] error %d\n",
    116		       gspca_dev->usb_buf[0], retval);
    117		gspca_dev->usb_err = retval;
    118	}
    119}
    120
    121static void setfreq(struct gspca_dev *gspca_dev, s32 val)
    122{
    123	u8 freq_commands[][2] = {
    124		{0x71, 0x80},
    125		{0x70, 0x07}
    126	};
    127
    128	freq_commands[0][1] |= val >> 1;
    129
    130	jlj_write2(gspca_dev, freq_commands[0]);
    131	jlj_write2(gspca_dev, freq_commands[1]);
    132}
    133
    134static void setcamquality(struct gspca_dev *gspca_dev, s32 val)
    135{
    136	u8 quality_commands[][2] = {
    137		{0x71, 0x1E},
    138		{0x70, 0x06}
    139	};
    140	u8 camquality;
    141
    142	/* adapt camera quality from jpeg quality */
    143	camquality = ((QUALITY_MAX - val) * CAMQUALITY_MAX)
    144		/ (QUALITY_MAX - QUALITY_MIN);
    145	quality_commands[0][1] += camquality;
    146
    147	jlj_write2(gspca_dev, quality_commands[0]);
    148	jlj_write2(gspca_dev, quality_commands[1]);
    149}
    150
    151static void setautogain(struct gspca_dev *gspca_dev, s32 val)
    152{
    153	u8 autogain_commands[][2] = {
    154		{0x94, 0x02},
    155		{0xcf, 0x00}
    156	};
    157
    158	autogain_commands[1][1] = val << 4;
    159
    160	jlj_write2(gspca_dev, autogain_commands[0]);
    161	jlj_write2(gspca_dev, autogain_commands[1]);
    162}
    163
    164static void setred(struct gspca_dev *gspca_dev, s32 val)
    165{
    166	u8 setred_commands[][2] = {
    167		{0x94, 0x02},
    168		{0xe6, 0x00}
    169	};
    170
    171	setred_commands[1][1] = val;
    172
    173	jlj_write2(gspca_dev, setred_commands[0]);
    174	jlj_write2(gspca_dev, setred_commands[1]);
    175}
    176
    177static void setgreen(struct gspca_dev *gspca_dev, s32 val)
    178{
    179	u8 setgreen_commands[][2] = {
    180		{0x94, 0x02},
    181		{0xe7, 0x00}
    182	};
    183
    184	setgreen_commands[1][1] = val;
    185
    186	jlj_write2(gspca_dev, setgreen_commands[0]);
    187	jlj_write2(gspca_dev, setgreen_commands[1]);
    188}
    189
    190static void setblue(struct gspca_dev *gspca_dev, s32 val)
    191{
    192	u8 setblue_commands[][2] = {
    193		{0x94, 0x02},
    194		{0xe9, 0x00}
    195	};
    196
    197	setblue_commands[1][1] = val;
    198
    199	jlj_write2(gspca_dev, setblue_commands[0]);
    200	jlj_write2(gspca_dev, setblue_commands[1]);
    201}
    202
    203static int jlj_start(struct gspca_dev *gspca_dev)
    204{
    205	int i;
    206	int start_commands_size;
    207	u8 response = 0xff;
    208	struct sd *sd = (struct sd *) gspca_dev;
    209	struct jlj_command start_commands[] = {
    210		{{0x71, 0x81}, 0, 0},
    211		{{0x70, 0x05}, 0, JEILINJ_CMD_DELAY},
    212		{{0x95, 0x70}, 1, 0},
    213		{{0x71, 0x81 - gspca_dev->curr_mode}, 0, 0},
    214		{{0x70, 0x04}, 0, JEILINJ_CMD_DELAY},
    215		{{0x95, 0x70}, 1, 0},
    216		{{0x71, 0x00}, 0, 0},   /* start streaming ??*/
    217		{{0x70, 0x08}, 0, JEILINJ_CMD_DELAY},
    218		{{0x95, 0x70}, 1, 0},
    219#define SPORTSCAM_DV15_CMD_SIZE 9
    220		{{0x94, 0x02}, 0, 0},
    221		{{0xde, 0x24}, 0, 0},
    222		{{0x94, 0x02}, 0, 0},
    223		{{0xdd, 0xf0}, 0, 0},
    224		{{0x94, 0x02}, 0, 0},
    225		{{0xe3, 0x2c}, 0, 0},
    226		{{0x94, 0x02}, 0, 0},
    227		{{0xe4, 0x00}, 0, 0},
    228		{{0x94, 0x02}, 0, 0},
    229		{{0xe5, 0x00}, 0, 0},
    230		{{0x94, 0x02}, 0, 0},
    231		{{0xe6, 0x2c}, 0, 0},
    232		{{0x94, 0x03}, 0, 0},
    233		{{0xaa, 0x00}, 0, 0}
    234	};
    235
    236	sd->blocks_left = 0;
    237	/* Under Windows, USB spy shows that only the 9 first start
    238	 * commands are used for SPORTSCAM_DV15 webcam
    239	 */
    240	if (sd->type == SPORTSCAM_DV15)
    241		start_commands_size = SPORTSCAM_DV15_CMD_SIZE;
    242	else
    243		start_commands_size = ARRAY_SIZE(start_commands);
    244
    245	for (i = 0; i < start_commands_size; i++) {
    246		jlj_write2(gspca_dev, start_commands[i].instruction);
    247		if (start_commands[i].delay)
    248			msleep(start_commands[i].delay);
    249		if (start_commands[i].ack_wanted)
    250			jlj_read1(gspca_dev, &response);
    251	}
    252	setcamquality(gspca_dev, v4l2_ctrl_g_ctrl(sd->jpegqual));
    253	msleep(2);
    254	setfreq(gspca_dev, v4l2_ctrl_g_ctrl(sd->freq));
    255	if (gspca_dev->usb_err < 0)
    256		gspca_err(gspca_dev, "Start streaming command failed\n");
    257	return gspca_dev->usb_err;
    258}
    259
    260static void sd_pkt_scan(struct gspca_dev *gspca_dev,
    261			u8 *data, int len)
    262{
    263	struct sd *sd = (struct sd *) gspca_dev;
    264	int packet_type;
    265	u32 header_marker;
    266
    267	gspca_dbg(gspca_dev, D_STREAM, "Got %d bytes out of %d for Block 0\n",
    268		  len, JEILINJ_MAX_TRANSFER);
    269	if (len != JEILINJ_MAX_TRANSFER) {
    270		gspca_dbg(gspca_dev, D_PACK, "bad length\n");
    271		goto discard;
    272	}
    273	/* check if it's start of frame */
    274	header_marker = ((u32 *)data)[0];
    275	if (header_marker == FRAME_START) {
    276		sd->blocks_left = data[0x0a] - 1;
    277		gspca_dbg(gspca_dev, D_STREAM, "blocks_left = 0x%x\n",
    278			  sd->blocks_left);
    279		/* Start a new frame, and add the JPEG header, first thing */
    280		gspca_frame_add(gspca_dev, FIRST_PACKET,
    281				sd->jpeg_hdr, JPEG_HDR_SZ);
    282		/* Toss line 0 of data block 0, keep the rest. */
    283		gspca_frame_add(gspca_dev, INTER_PACKET,
    284				data + FRAME_HEADER_LEN,
    285				JEILINJ_MAX_TRANSFER - FRAME_HEADER_LEN);
    286	} else if (sd->blocks_left > 0) {
    287		gspca_dbg(gspca_dev, D_STREAM, "%d blocks remaining for frame\n",
    288			  sd->blocks_left);
    289		sd->blocks_left -= 1;
    290		if (sd->blocks_left == 0)
    291			packet_type = LAST_PACKET;
    292		else
    293			packet_type = INTER_PACKET;
    294		gspca_frame_add(gspca_dev, packet_type,
    295				data, JEILINJ_MAX_TRANSFER);
    296	} else
    297		goto discard;
    298	return;
    299discard:
    300	/* Discard data until a new frame starts. */
    301	gspca_dev->last_packet_type = DISCARD_PACKET;
    302}
    303
    304/* This function is called at probe time just before sd_init */
    305static int sd_config(struct gspca_dev *gspca_dev,
    306		const struct usb_device_id *id)
    307{
    308	struct cam *cam = &gspca_dev->cam;
    309	struct sd *dev  = (struct sd *) gspca_dev;
    310
    311	dev->type = id->driver_info;
    312	dev->quality = QUALITY_DEF;
    313
    314	cam->cam_mode = jlj_mode;
    315	cam->nmodes = ARRAY_SIZE(jlj_mode);
    316	cam->bulk = 1;
    317	cam->bulk_nurbs = 1;
    318	cam->bulk_size = JEILINJ_MAX_TRANSFER;
    319	return 0;
    320}
    321
    322static void sd_stopN(struct gspca_dev *gspca_dev)
    323{
    324	int i;
    325	u8 *buf;
    326	static u8 stop_commands[][2] = {
    327		{0x71, 0x00},
    328		{0x70, 0x09},
    329		{0x71, 0x80},
    330		{0x70, 0x05}
    331	};
    332
    333	for (;;) {
    334		/* get the image remaining blocks */
    335		usb_bulk_msg(gspca_dev->dev,
    336				gspca_dev->urb[0]->pipe,
    337				gspca_dev->urb[0]->transfer_buffer,
    338				JEILINJ_MAX_TRANSFER, NULL,
    339				JEILINJ_DATA_TIMEOUT);
    340
    341		/* search for 0xff 0xd9  (EOF for JPEG) */
    342		i = 0;
    343		buf = gspca_dev->urb[0]->transfer_buffer;
    344		while ((i < (JEILINJ_MAX_TRANSFER - 1)) &&
    345			((buf[i] != 0xff) || (buf[i+1] != 0xd9)))
    346			i++;
    347
    348		if (i != (JEILINJ_MAX_TRANSFER - 1))
    349			/* last remaining block found */
    350			break;
    351		}
    352
    353	for (i = 0; i < ARRAY_SIZE(stop_commands); i++)
    354		jlj_write2(gspca_dev, stop_commands[i]);
    355}
    356
    357/* this function is called at probe and resume time */
    358static int sd_init(struct gspca_dev *gspca_dev)
    359{
    360	return gspca_dev->usb_err;
    361}
    362
    363/* Set up for getting frames. */
    364static int sd_start(struct gspca_dev *gspca_dev)
    365{
    366	struct sd *dev = (struct sd *) gspca_dev;
    367
    368	/* create the JPEG header */
    369	jpeg_define(dev->jpeg_hdr, gspca_dev->pixfmt.height,
    370			gspca_dev->pixfmt.width,
    371			0x21);          /* JPEG 422 */
    372	jpeg_set_qual(dev->jpeg_hdr, dev->quality);
    373	gspca_dbg(gspca_dev, D_STREAM, "Start streaming at %dx%d\n",
    374		  gspca_dev->pixfmt.height, gspca_dev->pixfmt.width);
    375	jlj_start(gspca_dev);
    376	return gspca_dev->usb_err;
    377}
    378
    379/* Table of supported USB devices */
    380static const struct usb_device_id device_table[] = {
    381	{USB_DEVICE(0x0979, 0x0280), .driver_info = SAKAR_57379},
    382	{USB_DEVICE(0x0979, 0x0270), .driver_info = SPORTSCAM_DV15},
    383	{}
    384};
    385
    386MODULE_DEVICE_TABLE(usb, device_table);
    387
    388static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
    389{
    390	struct gspca_dev *gspca_dev =
    391		container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
    392	struct sd *sd = (struct sd *)gspca_dev;
    393
    394	gspca_dev->usb_err = 0;
    395
    396	if (!gspca_dev->streaming)
    397		return 0;
    398
    399	switch (ctrl->id) {
    400	case V4L2_CID_POWER_LINE_FREQUENCY:
    401		setfreq(gspca_dev, ctrl->val);
    402		break;
    403	case V4L2_CID_RED_BALANCE:
    404		setred(gspca_dev, ctrl->val);
    405		break;
    406	case V4L2_CID_GAIN:
    407		setgreen(gspca_dev, ctrl->val);
    408		break;
    409	case V4L2_CID_BLUE_BALANCE:
    410		setblue(gspca_dev, ctrl->val);
    411		break;
    412	case V4L2_CID_AUTOGAIN:
    413		setautogain(gspca_dev, ctrl->val);
    414		break;
    415	case V4L2_CID_JPEG_COMPRESSION_QUALITY:
    416		jpeg_set_qual(sd->jpeg_hdr, ctrl->val);
    417		setcamquality(gspca_dev, ctrl->val);
    418		break;
    419	}
    420	return gspca_dev->usb_err;
    421}
    422
    423static const struct v4l2_ctrl_ops sd_ctrl_ops = {
    424	.s_ctrl = sd_s_ctrl,
    425};
    426
    427static int sd_init_controls(struct gspca_dev *gspca_dev)
    428{
    429	struct sd *sd = (struct sd *)gspca_dev;
    430	struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
    431	static const struct v4l2_ctrl_config custom_autogain = {
    432		.ops = &sd_ctrl_ops,
    433		.id = V4L2_CID_AUTOGAIN,
    434		.type = V4L2_CTRL_TYPE_INTEGER,
    435		.name = "Automatic Gain (and Exposure)",
    436		.max = 3,
    437		.step = 1,
    438		.def = 0,
    439	};
    440
    441	gspca_dev->vdev.ctrl_handler = hdl;
    442	v4l2_ctrl_handler_init(hdl, 6);
    443	sd->freq = v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops,
    444			V4L2_CID_POWER_LINE_FREQUENCY,
    445			V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 1,
    446			V4L2_CID_POWER_LINE_FREQUENCY_60HZ);
    447	v4l2_ctrl_new_custom(hdl, &custom_autogain, NULL);
    448	v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
    449			V4L2_CID_RED_BALANCE, 0, 3, 1, 2);
    450	v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
    451			V4L2_CID_GAIN, 0, 3, 1, 2);
    452	v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
    453			V4L2_CID_BLUE_BALANCE, 0, 3, 1, 2);
    454	sd->jpegqual = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
    455			V4L2_CID_JPEG_COMPRESSION_QUALITY,
    456			QUALITY_MIN, QUALITY_MAX, 1, QUALITY_DEF);
    457
    458	if (hdl->error) {
    459		pr_err("Could not initialize controls\n");
    460		return hdl->error;
    461	}
    462	return 0;
    463}
    464
    465static int sd_set_jcomp(struct gspca_dev *gspca_dev,
    466			const struct v4l2_jpegcompression *jcomp)
    467{
    468	struct sd *sd = (struct sd *) gspca_dev;
    469
    470	v4l2_ctrl_s_ctrl(sd->jpegqual, jcomp->quality);
    471	return 0;
    472}
    473
    474static int sd_get_jcomp(struct gspca_dev *gspca_dev,
    475			struct v4l2_jpegcompression *jcomp)
    476{
    477	struct sd *sd = (struct sd *) gspca_dev;
    478
    479	memset(jcomp, 0, sizeof *jcomp);
    480	jcomp->quality = v4l2_ctrl_g_ctrl(sd->jpegqual);
    481	jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
    482			| V4L2_JPEG_MARKER_DQT;
    483	return 0;
    484}
    485
    486
    487/* sub-driver description */
    488static const struct sd_desc sd_desc_sakar_57379 = {
    489	.name   = MODULE_NAME,
    490	.config = sd_config,
    491	.init   = sd_init,
    492	.start  = sd_start,
    493	.stopN  = sd_stopN,
    494	.pkt_scan = sd_pkt_scan,
    495};
    496
    497/* sub-driver description */
    498static const struct sd_desc sd_desc_sportscam_dv15 = {
    499	.name   = MODULE_NAME,
    500	.config = sd_config,
    501	.init   = sd_init,
    502	.init_controls = sd_init_controls,
    503	.start  = sd_start,
    504	.stopN  = sd_stopN,
    505	.pkt_scan = sd_pkt_scan,
    506	.get_jcomp = sd_get_jcomp,
    507	.set_jcomp = sd_set_jcomp,
    508};
    509
    510static const struct sd_desc *sd_desc[2] = {
    511	&sd_desc_sakar_57379,
    512	&sd_desc_sportscam_dv15
    513};
    514
    515/* -- device connect -- */
    516static int sd_probe(struct usb_interface *intf,
    517		const struct usb_device_id *id)
    518{
    519	return gspca_dev_probe(intf, id,
    520			sd_desc[id->driver_info],
    521			sizeof(struct sd),
    522			THIS_MODULE);
    523}
    524
    525static struct usb_driver sd_driver = {
    526	.name       = MODULE_NAME,
    527	.id_table   = device_table,
    528	.probe      = sd_probe,
    529	.disconnect = gspca_disconnect,
    530#ifdef CONFIG_PM
    531	.suspend = gspca_suspend,
    532	.resume  = gspca_resume,
    533	.reset_resume = gspca_resume,
    534#endif
    535};
    536
    537module_usb_driver(sd_driver);