aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/s2255drv.c
diff options
context:
space:
mode:
authorDean Anderson <dean@sensoray.com>2010-03-05 17:59:48 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-05-17 23:46:36 -0400
commit5a34d9dfaf3cb690c448fac67923effac08c902d (patch)
tree1eb2f41ea3ad5f73c77480a9fe8406d7f5ef69a2 /drivers/media/video/s2255drv.c
parent2e70db9a4553e0f79cb4db05c0552d33932cca80 (diff)
V4L/DVB: s2255drv: Add support for 2257 device
2257 is 2255 with 2 svideo inputs Signed-off-by: Dean Anderson <dean@sensoray.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/s2255drv.c')
-rw-r--r--drivers/media/video/s2255drv.c154
1 files changed, 129 insertions, 25 deletions
diff --git a/drivers/media/video/s2255drv.c b/drivers/media/video/s2255drv.c
index 631a84eea1ae..745f557200aa 100644
--- a/drivers/media/video/s2255drv.c
+++ b/drivers/media/video/s2255drv.c
@@ -120,9 +120,10 @@
120#define COLOR_YUVPK 2 /* YUV packed */ 120#define COLOR_YUVPK 2 /* YUV packed */
121#define COLOR_Y8 4 /* monochrome */ 121#define COLOR_Y8 4 /* monochrome */
122#define COLOR_JPG 5 /* JPEG */ 122#define COLOR_JPG 5 /* JPEG */
123#define MASK_COLOR 0xff
124#define MASK_JPG_QUALITY 0xff00
125 123
124#define MASK_COLOR 0x000000ff
125#define MASK_JPG_QUALITY 0x0000ff00
126#define MASK_INPUT_TYPE 0x000f0000
126/* frame decimation. Not implemented by V4L yet(experimental in V4L) */ 127/* frame decimation. Not implemented by V4L yet(experimental in V4L) */
127#define FDEC_1 1 /* capture every frame. default */ 128#define FDEC_1 1 /* capture every frame. default */
128#define FDEC_2 2 /* capture every 2nd frame */ 129#define FDEC_2 2 /* capture every 2nd frame */
@@ -196,7 +197,6 @@ struct s2255_dmaqueue {
196#define S2255_FW_SUCCESS 2 197#define S2255_FW_SUCCESS 2
197#define S2255_FW_FAILED 3 198#define S2255_FW_FAILED 3
198#define S2255_FW_DISCONNECTING 4 199#define S2255_FW_DISCONNECTING 4
199
200#define S2255_FW_MARKER cpu_to_le32(0x22552f2f) 200#define S2255_FW_MARKER cpu_to_le32(0x22552f2f)
201/* 2255 read states */ 201/* 2255 read states */
202#define S2255_READ_IDLE 0 202#define S2255_READ_IDLE 0
@@ -267,12 +267,12 @@ struct s2255_dev {
267 int vidstatus[MAX_CHANNELS]; 267 int vidstatus[MAX_CHANNELS];
268 wait_queue_head_t wait_vidstatus[MAX_CHANNELS]; 268 wait_queue_head_t wait_vidstatus[MAX_CHANNELS];
269 int vidstatus_ready[MAX_CHANNELS]; 269 int vidstatus_ready[MAX_CHANNELS];
270
271 int chn_ready; 270 int chn_ready;
272 struct kref kref;
273 spinlock_t slock; 271 spinlock_t slock;
274 /* dsp firmware version (f2255usb.bin) */ 272 /* dsp firmware version (f2255usb.bin) */
275 int dsp_fw_ver; 273 int dsp_fw_ver;
274 u16 pid; /* product id */
275 struct kref kref;
276}; 276};
277#define to_s2255_dev(d) container_of(d, struct s2255_dev, kref) 277#define to_s2255_dev(d) container_of(d, struct s2255_dev, kref)
278 278
@@ -306,20 +306,49 @@ struct s2255_fh {
306/* current cypress EEPROM firmware version */ 306/* current cypress EEPROM firmware version */
307#define S2255_CUR_USB_FWVER ((3 << 8) | 6) 307#define S2255_CUR_USB_FWVER ((3 << 8) | 6)
308/* current DSP FW version */ 308/* current DSP FW version */
309#define S2255_CUR_DSP_FWVER 5 309#define S2255_CUR_DSP_FWVER 8
310/* Need DSP version 5+ for video status feature */ 310/* Need DSP version 5+ for video status feature */
311#define S2255_MIN_DSP_STATUS 5 311#define S2255_MIN_DSP_STATUS 5
312#define S2255_MIN_DSP_COLORFILTER 8
312#define S2255_MAJOR_VERSION 1 313#define S2255_MAJOR_VERSION 1
313#define S2255_MINOR_VERSION 17 314#define S2255_MINOR_VERSION 18
314#define S2255_RELEASE 0 315#define S2255_RELEASE 0
315#define S2255_VERSION KERNEL_VERSION(S2255_MAJOR_VERSION, \ 316#define S2255_VERSION KERNEL_VERSION(S2255_MAJOR_VERSION, \
316 S2255_MINOR_VERSION, \ 317 S2255_MINOR_VERSION, \
317 S2255_RELEASE) 318 S2255_RELEASE)
318 319
319/* vendor ids */
320#define USB_S2255_VENDOR_ID 0x1943
321#define USB_S2255_PRODUCT_ID 0x2255
322#define S2255_NORMS (V4L2_STD_PAL | V4L2_STD_NTSC) 320#define S2255_NORMS (V4L2_STD_PAL | V4L2_STD_NTSC)
321
322/* private V4L2 controls */
323
324/*
325 * The following chart displays how COLORFILTER should be set
326 * =========================================================
327 * = fourcc = COLORFILTER =
328 * = ===============================
329 * = = 0 = 1 =
330 * =========================================================
331 * = V4L2_PIX_FMT_GREY(Y8) = monochrome from = monochrome=
332 * = = s-video or = composite =
333 * = = B/W camera = input =
334 * =========================================================
335 * = other = color, svideo = color, =
336 * = = = composite =
337 * =========================================================
338 *
339 * Notes:
340 * channels 0-3 on 2255 are composite
341 * channels 0-1 on 2257 are composite, 2-3 are s-video
342 * If COLORFILTER is 0 with a composite color camera connected,
343 * the output will appear monochrome but hatching
344 * will occur.
345 * COLORFILTER is different from "color killer" and "color effects"
346 * for reasons above.
347 */
348#define S2255_V4L2_YC_ON 1
349#define S2255_V4L2_YC_OFF 0
350#define V4L2_CID_PRIVATE_COLORFILTER (V4L2_CID_PRIVATE_BASE + 0)
351
323/* frame prefix size (sent once every frame) */ 352/* frame prefix size (sent once every frame) */
324#define PREFIX_SIZE 512 353#define PREFIX_SIZE 512
325 354
@@ -360,7 +389,6 @@ static long s2255_vendor_req(struct s2255_dev *dev, unsigned char req,
360 389
361static struct usb_driver s2255_driver; 390static struct usb_driver s2255_driver;
362 391
363
364/* Declare static vars that will be used as parameters */ 392/* Declare static vars that will be used as parameters */
365static unsigned int vid_limit = 16; /* Video memory limit, in Mb */ 393static unsigned int vid_limit = 16; /* Video memory limit, in Mb */
366 394
@@ -375,13 +403,14 @@ module_param(video_nr, int, 0644);
375MODULE_PARM_DESC(video_nr, "start video minor(-1 default autodetect)"); 403MODULE_PARM_DESC(video_nr, "start video minor(-1 default autodetect)");
376 404
377/* USB device table */ 405/* USB device table */
406#define USB_SENSORAY_VID 0x1943
378static struct usb_device_id s2255_table[] = { 407static struct usb_device_id s2255_table[] = {
379 {USB_DEVICE(USB_S2255_VENDOR_ID, USB_S2255_PRODUCT_ID)}, 408 {USB_DEVICE(USB_SENSORAY_VID, 0x2255)},
409 {USB_DEVICE(USB_SENSORAY_VID, 0x2257)}, /*same family as 2255*/
380 { } /* Terminating entry */ 410 { } /* Terminating entry */
381}; 411};
382MODULE_DEVICE_TABLE(usb, s2255_table); 412MODULE_DEVICE_TABLE(usb, s2255_table);
383 413
384
385#define BUFFER_TIMEOUT msecs_to_jiffies(400) 414#define BUFFER_TIMEOUT msecs_to_jiffies(400)
386 415
387/* image formats. */ 416/* image formats. */
@@ -798,6 +827,28 @@ static void res_free(struct s2255_dev *dev, struct s2255_fh *fh)
798 dprintk(1, "res: put\n"); 827 dprintk(1, "res: put\n");
799} 828}
800 829
830static int vidioc_querymenu(struct file *file, void *priv,
831 struct v4l2_querymenu *qmenu)
832{
833 static const char *colorfilter[] = {
834 "Off",
835 "On",
836 NULL
837 };
838 if (qmenu->id == V4L2_CID_PRIVATE_COLORFILTER) {
839 int i;
840 const char **menu_items = colorfilter;
841 for (i = 0; i < qmenu->index && menu_items[i]; i++)
842 ; /* do nothing (from v4l2-common.c) */
843 if (menu_items[i] == NULL || menu_items[i][0] == '\0')
844 return -EINVAL;
845 strlcpy(qmenu->name, menu_items[qmenu->index],
846 sizeof(qmenu->name));
847 return 0;
848 }
849 return v4l2_ctrl_query_menu(qmenu, NULL, NULL);
850}
851
801 852
802static int vidioc_querycap(struct file *file, void *priv, 853static int vidioc_querycap(struct file *file, void *priv,
803 struct v4l2_capability *cap) 854 struct v4l2_capability *cap)
@@ -1007,19 +1058,23 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
1007 /* color mode */ 1058 /* color mode */
1008 switch (fh->fmt->fourcc) { 1059 switch (fh->fmt->fourcc) {
1009 case V4L2_PIX_FMT_GREY: 1060 case V4L2_PIX_FMT_GREY:
1010 fh->mode.color = COLOR_Y8; 1061 fh->mode.color &= ~MASK_COLOR;
1062 fh->mode.color |= COLOR_Y8;
1011 break; 1063 break;
1012 case V4L2_PIX_FMT_JPEG: 1064 case V4L2_PIX_FMT_JPEG:
1013 fh->mode.color = COLOR_JPG | 1065 fh->mode.color &= ~MASK_COLOR;
1014 (fh->dev->jc[fh->channel].quality << 8); 1066 fh->mode.color |= COLOR_JPG;
1067 fh->mode.color |= (fh->dev->jc[fh->channel].quality << 8);
1015 break; 1068 break;
1016 case V4L2_PIX_FMT_YUV422P: 1069 case V4L2_PIX_FMT_YUV422P:
1017 fh->mode.color = COLOR_YUVPL; 1070 fh->mode.color &= ~MASK_COLOR;
1071 fh->mode.color |= COLOR_YUVPL;
1018 break; 1072 break;
1019 case V4L2_PIX_FMT_YUYV: 1073 case V4L2_PIX_FMT_YUYV:
1020 case V4L2_PIX_FMT_UYVY: 1074 case V4L2_PIX_FMT_UYVY:
1021 default: 1075 default:
1022 fh->mode.color = COLOR_YUVPK; 1076 fh->mode.color &= ~MASK_COLOR;
1077 fh->mode.color |= COLOR_YUVPK;
1023 break; 1078 break;
1024 } 1079 }
1025 ret = 0; 1080 ret = 0;
@@ -1186,8 +1241,12 @@ static int s2255_set_mode(struct s2255_dev *dev, unsigned long chn,
1186 dprintk(2, "mode contrast %x\n", mode->contrast); 1241 dprintk(2, "mode contrast %x\n", mode->contrast);
1187 1242
1188 /* if JPEG, set the quality */ 1243 /* if JPEG, set the quality */
1189 if ((mode->color & MASK_COLOR) == COLOR_JPG) 1244 if ((mode->color & MASK_COLOR) == COLOR_JPG) {
1190 mode->color = (dev->jc[chn].quality << 8) | COLOR_JPG; 1245 mode->color &= ~MASK_COLOR;
1246 mode->color |= COLOR_JPG;
1247 mode->color &= ~MASK_JPG_QUALITY;
1248 mode->color |= (dev->jc[chn].quality << 8);
1249 }
1191 1250
1192 /* save the mode */ 1251 /* save the mode */
1193 dev->mode[chn] = *mode; 1252 dev->mode[chn] = *mode;
@@ -1296,7 +1355,7 @@ static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
1296 new_mode = &fh->mode; 1355 new_mode = &fh->mode;
1297 old_mode = &fh->dev->mode[chn]; 1356 old_mode = &fh->dev->mode[chn];
1298 1357
1299 if (new_mode->color != old_mode->color) 1358 if ((new_mode->color & MASK_COLOR) != (old_mode->color & MASK_COLOR))
1300 new_mode->restart = 1; 1359 new_mode->restart = 1;
1301 else if (new_mode->scale != old_mode->scale) 1360 else if (new_mode->scale != old_mode->scale)
1302 new_mode->restart = 1; 1361 new_mode->restart = 1;
@@ -1354,6 +1413,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *i)
1354 int ret = 0; 1413 int ret = 0;
1355 1414
1356 mutex_lock(&q->vb_lock); 1415 mutex_lock(&q->vb_lock);
1416
1357 if (videobuf_queue_is_busy(q)) { 1417 if (videobuf_queue_is_busy(q)) {
1358 dprintk(1, "queue busy\n"); 1418 dprintk(1, "queue busy\n");
1359 ret = -EBUSY; 1419 ret = -EBUSY;
@@ -1366,7 +1426,6 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *i)
1366 goto out_s_std; 1426 goto out_s_std;
1367 } 1427 }
1368 mode = &fh->mode; 1428 mode = &fh->mode;
1369
1370 if (*i & V4L2_STD_NTSC) { 1429 if (*i & V4L2_STD_NTSC) {
1371 dprintk(4, "vidioc_s_std NTSC\n"); 1430 dprintk(4, "vidioc_s_std NTSC\n");
1372 mode->format = FORMAT_NTSC; 1431 mode->format = FORMAT_NTSC;
@@ -1409,7 +1468,16 @@ static int vidioc_enum_input(struct file *file, void *priv,
1409 inp->status = (status & 0x01) ? 0 1468 inp->status = (status & 0x01) ? 0
1410 : V4L2_IN_ST_NO_SIGNAL; 1469 : V4L2_IN_ST_NO_SIGNAL;
1411 } 1470 }
1412 strlcpy(inp->name, "Camera", sizeof(inp->name)); 1471 switch (dev->pid) {
1472 case 0x2255:
1473 default:
1474 strlcpy(inp->name, "Composite", sizeof(inp->name));
1475 break;
1476 case 0x2257:
1477 strlcpy(inp->name, (fh->channel < 2) ? "Composite" : "S-Video",
1478 sizeof(inp->name));
1479 break;
1480 }
1413 return 0; 1481 return 0;
1414} 1482}
1415 1483
@@ -1429,6 +1497,8 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
1429static int vidioc_queryctrl(struct file *file, void *priv, 1497static int vidioc_queryctrl(struct file *file, void *priv,
1430 struct v4l2_queryctrl *qc) 1498 struct v4l2_queryctrl *qc)
1431{ 1499{
1500 struct s2255_fh *fh = priv;
1501 struct s2255_dev *dev = fh->dev;
1432 switch (qc->id) { 1502 switch (qc->id) {
1433 case V4L2_CID_BRIGHTNESS: 1503 case V4L2_CID_BRIGHTNESS:
1434 v4l2_ctrl_query_fill(qc, -127, 127, 1, DEF_BRIGHT); 1504 v4l2_ctrl_query_fill(qc, -127, 127, 1, DEF_BRIGHT);
@@ -1442,6 +1512,19 @@ static int vidioc_queryctrl(struct file *file, void *priv,
1442 case V4L2_CID_HUE: 1512 case V4L2_CID_HUE:
1443 v4l2_ctrl_query_fill(qc, 0, 255, 1, DEF_HUE); 1513 v4l2_ctrl_query_fill(qc, 0, 255, 1, DEF_HUE);
1444 break; 1514 break;
1515 case V4L2_CID_PRIVATE_COLORFILTER:
1516 if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
1517 return -EINVAL;
1518 if ((dev->pid == 0x2257) && (fh->channel > 1))
1519 return -EINVAL;
1520 strlcpy(qc->name, "Color Filter", sizeof(qc->name));
1521 qc->type = V4L2_CTRL_TYPE_MENU;
1522 qc->minimum = 0;
1523 qc->maximum = 1;
1524 qc->step = 1;
1525 qc->default_value = 1;
1526 qc->flags = 0;
1527 break;
1445 default: 1528 default:
1446 return -EINVAL; 1529 return -EINVAL;
1447 } 1530 }
@@ -1453,6 +1536,7 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
1453 struct v4l2_control *ctrl) 1536 struct v4l2_control *ctrl)
1454{ 1537{
1455 struct s2255_fh *fh = priv; 1538 struct s2255_fh *fh = priv;
1539 struct s2255_dev *dev = fh->dev;
1456 switch (ctrl->id) { 1540 switch (ctrl->id) {
1457 case V4L2_CID_BRIGHTNESS: 1541 case V4L2_CID_BRIGHTNESS:
1458 ctrl->value = fh->mode.bright; 1542 ctrl->value = fh->mode.bright;
@@ -1466,6 +1550,13 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
1466 case V4L2_CID_HUE: 1550 case V4L2_CID_HUE:
1467 ctrl->value = fh->mode.hue; 1551 ctrl->value = fh->mode.hue;
1468 break; 1552 break;
1553 case V4L2_CID_PRIVATE_COLORFILTER:
1554 if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
1555 return -EINVAL;
1556 if ((dev->pid == 0x2257) && (fh->channel > 1))
1557 return -EINVAL;
1558 ctrl->value = !((fh->mode.color & MASK_INPUT_TYPE) >> 16);
1559 break;
1469 default: 1560 default:
1470 return -EINVAL; 1561 return -EINVAL;
1471 } 1562 }
@@ -1495,6 +1586,14 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
1495 case V4L2_CID_SATURATION: 1586 case V4L2_CID_SATURATION:
1496 mode->saturation = ctrl->value; 1587 mode->saturation = ctrl->value;
1497 break; 1588 break;
1589 case V4L2_CID_PRIVATE_COLORFILTER:
1590 if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
1591 return -EINVAL;
1592 if ((dev->pid == 0x2257) && (fh->channel > 1))
1593 return -EINVAL;
1594 mode->color &= ~MASK_INPUT_TYPE;
1595 mode->color |= ((ctrl->value ? 0 : 1) << 16);
1596 break;
1498 default: 1597 default:
1499 return -EINVAL; 1598 return -EINVAL;
1500 } 1599 }
@@ -1807,6 +1906,7 @@ static const struct v4l2_file_operations s2255_fops_v4l = {
1807}; 1906};
1808 1907
1809static const struct v4l2_ioctl_ops s2255_ioctl_ops = { 1908static const struct v4l2_ioctl_ops s2255_ioctl_ops = {
1909 .vidioc_querymenu = vidioc_querymenu,
1810 .vidioc_querycap = vidioc_querycap, 1910 .vidioc_querycap = vidioc_querycap,
1811 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, 1911 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
1812 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, 1912 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
@@ -2230,6 +2330,8 @@ static int s2255_board_init(struct s2255_dev *dev)
2230 for (j = 0; j < MAX_CHANNELS; j++) { 2330 for (j = 0; j < MAX_CHANNELS; j++) {
2231 dev->b_acquire[j] = 0; 2331 dev->b_acquire[j] = 0;
2232 dev->mode[j] = mode_def; 2332 dev->mode[j] = mode_def;
2333 if (dev->pid == 0x2257 && j > 1)
2334 dev->mode[j].color |= (1 << 16);
2233 dev->jc[j].quality = S2255_DEF_JPEG_QUAL; 2335 dev->jc[j].quality = S2255_DEF_JPEG_QUAL;
2234 dev->cur_fmt[j] = &formats[0]; 2336 dev->cur_fmt[j] = &formats[0];
2235 dev->mode[j].restart = 1; 2337 dev->mode[j].restart = 1;
@@ -2506,7 +2608,7 @@ static int s2255_probe(struct usb_interface *interface,
2506 s2255_dev_err(&interface->dev, "out of memory\n"); 2608 s2255_dev_err(&interface->dev, "out of memory\n");
2507 goto error; 2609 goto error;
2508 } 2610 }
2509 2611 dev->pid = id->idProduct;
2510 dev->fw_data = kzalloc(sizeof(struct s2255_fw), GFP_KERNEL); 2612 dev->fw_data = kzalloc(sizeof(struct s2255_fw), GFP_KERNEL);
2511 if (!dev->fw_data) 2613 if (!dev->fw_data)
2512 goto error; 2614 goto error;
@@ -2589,6 +2691,8 @@ static int s2255_probe(struct usb_interface *interface,
2589 dev->dsp_fw_ver = *pRel; 2691 dev->dsp_fw_ver = *pRel;
2590 if (*pRel < S2255_CUR_DSP_FWVER) 2692 if (*pRel < S2255_CUR_DSP_FWVER)
2591 printk(KERN_INFO "s2255: f2255usb.bin out of date.\n"); 2693 printk(KERN_INFO "s2255: f2255usb.bin out of date.\n");
2694 if (dev->pid == 0x2257 && *pRel < S2255_MIN_DSP_COLORFILTER)
2695 printk(KERN_WARNING "s2255: 2257 requires firmware 8 or above.\n");
2592 } 2696 }
2593 /* loads v4l specific */ 2697 /* loads v4l specific */
2594 s2255_probe_v4l(dev); 2698 s2255_probe_v4l(dev);