From 9c31fa783cd34bcbfce89f18057f1419ac2e6ec4 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Fri, 12 Jun 2009 03:49:39 -0300 Subject: [PATCH] --- yaml --- r: 161439 b: refs/heads/master c: c4d363ccd75e1bf6a32f10df7ceb789a86f9291a h: refs/heads/master i: 161437: 741ca902de34d7ac0b4b550b47faed9b68f9a2be 161435: 264fff90af4dcce9af4e60820abe594e97f75a4a 161431: 48fc5dd7a224f9a9693f0680a5a13f88fa22f595 161423: 7b3acac79e65f876411b8a8190a818dd585a25ed 161407: b7d802bfcaee934c6a9c2ce31027a00802368b6b v: v3 --- [refs] | 2 +- trunk/drivers/media/video/gspca/spca508.c | 59 +++++++++++++++++++++-- 2 files changed, 56 insertions(+), 5 deletions(-) diff --git a/[refs] b/[refs] index 64fed3800699..a7d025061c5d 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 43b786677eb15edf7e8a2440878e5fa912bcccc6 +refs/heads/master: c4d363ccd75e1bf6a32f10df7ceb789a86f9291a diff --git a/trunk/drivers/media/video/gspca/spca508.c b/trunk/drivers/media/video/gspca/spca508.c index 2ed2669bac3e..9696c4caf5c9 100644 --- a/trunk/drivers/media/video/gspca/spca508.c +++ b/trunk/drivers/media/video/gspca/spca508.c @@ -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) { - ret = reg_write(dev, (*data)[1], (*data)[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 */