Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c4d363cc authored by Jean-Francois Moine's avatar Jean-Francois Moine Committed by Mauro Carvalho Chehab
Browse files

V4L/DVB (12226): gspca - spca508: Extend the write_vector routine.

parent 43b78667
Loading
Loading
Loading
Loading
+55 −4
Original line number Diff line number Diff line
@@ -1304,19 +1304,70 @@ static int reg_read(struct gspca_dev *gspca_dev,
	return gspca_dev->usb_buf[0];
}

/* send 1 or 2 bytes to the sensor via the Synchronous Serial Interface */
static int ssi_w(struct gspca_dev *gspca_dev,
		u16 reg, u16 val)
{
	struct usb_device *dev = gspca_dev->dev;
	int ret, retry;

	ret = reg_write(dev, 0x8802, reg >> 8);
	if (ret < 0)
		goto out;
	ret = reg_write(dev, 0x8801, reg & 0x00ff);
	if (ret < 0)
		goto out;
	if ((reg & 0xff00) == 0x1000) {		/* if 2 bytes */
		ret = reg_write(dev, 0x8805, val & 0x00ff);
		if (ret < 0)
			goto out;
		val >>= 8;
	}
	ret = reg_write(dev, 0x8800, val);
	if (ret < 0)
		goto out;

	/* poll until not busy */
	retry = 10;
	for (;;) {
		ret = reg_read(gspca_dev, 0x8803);
		if (ret < 0)
			break;
		if (gspca_dev->usb_buf[0] == 0)
			break;
		if (--retry <= 0) {
			PDEBUG(D_ERR, "ssi_w busy %02x",
					gspca_dev->usb_buf[0]);
			ret = -1;
			break;
		}
		msleep(8);
	}

out:
	return ret;
}

static int write_vector(struct gspca_dev *gspca_dev,
			const u16 (*data)[2])
{
	struct usb_device *dev = gspca_dev->dev;
	int ret;
	int ret = 0;

	while ((*data)[1] != 0) {
		if ((*data)[1] & 0x8000) {
			if ((*data)[1] == 0xdd00)	/* delay */
				msleep((*data)[0]);
			else
				ret = reg_write(dev, (*data)[1], (*data)[0]);
		} else {
			ret = ssi_w(gspca_dev, (*data)[1], (*data)[0]);
		}
		if (ret < 0)
			return ret;
			break;
		data++;
	}
	return 0;
	return ret;
}

/* this function is called at probe time */