aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video
diff options
context:
space:
mode:
authorJean-Francois Moine <moinejf@free.fr>2009-06-12 02:49:39 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-09-12 11:17:33 -0400
commitc4d363ccd75e1bf6a32f10df7ceb789a86f9291a (patch)
tree31fcc0368cdcf10b5d2b28e48c71929457aa2de3 /drivers/media/video
parent43b786677eb15edf7e8a2440878e5fa912bcccc6 (diff)
V4L/DVB (12226): gspca - spca508: Extend the write_vector routine.
Signed-off-by: Jean-Francois Moine <moinejf@free.fr> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video')
-rw-r--r--drivers/media/video/gspca/spca508.c59
1 files changed, 55 insertions, 4 deletions
diff --git a/drivers/media/video/gspca/spca508.c b/drivers/media/video/gspca/spca508.c
index 2ed2669bac3e..9696c4caf5c9 100644
--- a/drivers/media/video/gspca/spca508.c
+++ b/drivers/media/video/gspca/spca508.c
@@ -1304,19 +1304,70 @@ static int reg_read(struct gspca_dev *gspca_dev,
1304 return gspca_dev->usb_buf[0]; 1304 return gspca_dev->usb_buf[0];
1305} 1305}
1306 1306
1307/* send 1 or 2 bytes to the sensor via the Synchronous Serial Interface */
1308static int ssi_w(struct gspca_dev *gspca_dev,
1309 u16 reg, u16 val)
1310{
1311 struct usb_device *dev = gspca_dev->dev;
1312 int ret, retry;
1313
1314 ret = reg_write(dev, 0x8802, reg >> 8);
1315 if (ret < 0)
1316 goto out;
1317 ret = reg_write(dev, 0x8801, reg & 0x00ff);
1318 if (ret < 0)
1319 goto out;
1320 if ((reg & 0xff00) == 0x1000) { /* if 2 bytes */
1321 ret = reg_write(dev, 0x8805, val & 0x00ff);
1322 if (ret < 0)
1323 goto out;
1324 val >>= 8;
1325 }
1326 ret = reg_write(dev, 0x8800, val);
1327 if (ret < 0)
1328 goto out;
1329
1330 /* poll until not busy */
1331 retry = 10;
1332 for (;;) {
1333 ret = reg_read(gspca_dev, 0x8803);
1334 if (ret < 0)
1335 break;
1336 if (gspca_dev->usb_buf[0] == 0)
1337 break;
1338 if (--retry <= 0) {
1339 PDEBUG(D_ERR, "ssi_w busy %02x",
1340 gspca_dev->usb_buf[0]);
1341 ret = -1;
1342 break;
1343 }
1344 msleep(8);
1345 }
1346
1347out:
1348 return ret;
1349}
1350
1307static int write_vector(struct gspca_dev *gspca_dev, 1351static int write_vector(struct gspca_dev *gspca_dev,
1308 const u16 (*data)[2]) 1352 const u16 (*data)[2])
1309{ 1353{
1310 struct usb_device *dev = gspca_dev->dev; 1354 struct usb_device *dev = gspca_dev->dev;
1311 int ret; 1355 int ret = 0;
1312 1356
1313 while ((*data)[1] != 0) { 1357 while ((*data)[1] != 0) {
1314 ret = reg_write(dev, (*data)[1], (*data)[0]); 1358 if ((*data)[1] & 0x8000) {
1359 if ((*data)[1] == 0xdd00) /* delay */
1360 msleep((*data)[0]);
1361 else
1362 ret = reg_write(dev, (*data)[1], (*data)[0]);
1363 } else {
1364 ret = ssi_w(gspca_dev, (*data)[1], (*data)[0]);
1365 }
1315 if (ret < 0) 1366 if (ret < 0)
1316 return ret; 1367 break;
1317 data++; 1368 data++;
1318 } 1369 }
1319 return 0; 1370 return ret;
1320} 1371}
1321 1372
1322/* this function is called at probe time */ 1373/* this function is called at probe time */