diff options
author | Jean-Francois Moine <moinejf@free.fr> | 2009-06-12 02:49:39 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-09-12 11:17:33 -0400 |
commit | c4d363ccd75e1bf6a32f10df7ceb789a86f9291a (patch) | |
tree | 31fcc0368cdcf10b5d2b28e48c71929457aa2de3 /drivers/media/video | |
parent | 43b786677eb15edf7e8a2440878e5fa912bcccc6 (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.c | 59 |
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 */ | ||
1308 | static 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 | |||
1347 | out: | ||
1348 | return ret; | ||
1349 | } | ||
1350 | |||
1307 | static int write_vector(struct gspca_dev *gspca_dev, | 1351 | static 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 */ |