aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/s2255drv.c
diff options
context:
space:
mode:
authorDean Anderson <dean@sensoray.com>2010-03-03 17:39:19 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-05-17 23:46:33 -0400
commit4de39f5d6f8267a0b062cba70eaa84fb161007e4 (patch)
treefa6dd392a37c12bdfcfb336bc546b1845d2380ab /drivers/media/video/s2255drv.c
parent723fb9b79b5a2279ed8ea8adfa6f6c92d73deaa2 (diff)
V4L/DVB: s2255drv: adding video input status capability
Video status capability for inputs on Sensoray 2255 driver. 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.c85
1 files changed, 81 insertions, 4 deletions
diff --git a/drivers/media/video/s2255drv.c b/drivers/media/video/s2255drv.c
index 3de914deb8ee..a9c53335fd8f 100644
--- a/drivers/media/video/s2255drv.c
+++ b/drivers/media/video/s2255drv.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * s2255drv.c - a driver for the Sensoray 2255 USB video capture device 2 * s2255drv.c - a driver for the Sensoray 2255 USB video capture device
3 * 3 *
4 * Copyright (C) 2007-2008 by Sensoray Company Inc. 4 * Copyright (C) 2007-2010 by Sensoray Company Inc.
5 * Dean Anderson 5 * Dean Anderson
6 * 6 *
7 * Some video buffer code based on vivi driver: 7 * Some video buffer code based on vivi driver:
@@ -76,11 +76,13 @@
76#define S2255_LOAD_TIMEOUT (5000 + S2255_DSP_BOOTTIME) 76#define S2255_LOAD_TIMEOUT (5000 + S2255_DSP_BOOTTIME)
77#define S2255_DEF_BUFS 16 77#define S2255_DEF_BUFS 16
78#define S2255_SETMODE_TIMEOUT 500 78#define S2255_SETMODE_TIMEOUT 500
79#define S2255_VIDSTATUS_TIMEOUT 350
79#define MAX_CHANNELS 4 80#define MAX_CHANNELS 4
80#define S2255_MARKER_FRAME 0x2255DA4AL 81#define S2255_MARKER_FRAME 0x2255DA4AL
81#define S2255_MARKER_RESPONSE 0x2255ACACL 82#define S2255_MARKER_RESPONSE 0x2255ACACL
82#define S2255_RESPONSE_SETMODE 0x01 83#define S2255_RESPONSE_SETMODE 0x01
83#define S2255_RESPONSE_FW 0x10 84#define S2255_RESPONSE_FW 0x10
85#define S2255_RESPONSE_STATUS 0x20
84#define S2255_USB_XFER_SIZE (16 * 1024) 86#define S2255_USB_XFER_SIZE (16 * 1024)
85#define MAX_CHANNELS 4 87#define MAX_CHANNELS 4
86#define MAX_PIPE_BUFFERS 1 88#define MAX_PIPE_BUFFERS 1
@@ -261,9 +263,16 @@ struct s2255_dev {
261 int chn_configured[MAX_CHANNELS]; 263 int chn_configured[MAX_CHANNELS];
262 wait_queue_head_t wait_setmode[MAX_CHANNELS]; 264 wait_queue_head_t wait_setmode[MAX_CHANNELS];
263 int setmode_ready[MAX_CHANNELS]; 265 int setmode_ready[MAX_CHANNELS];
266 /* video status items */
267 int vidstatus[MAX_CHANNELS];
268 wait_queue_head_t wait_vidstatus[MAX_CHANNELS];
269 int vidstatus_ready[MAX_CHANNELS];
270
264 int chn_ready; 271 int chn_ready;
265 struct kref kref; 272 struct kref kref;
266 spinlock_t slock; 273 spinlock_t slock;
274 /* dsp firmware version (f2255usb.bin) */
275 int dsp_fw_ver;
267}; 276};
268#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)
269 278
@@ -296,8 +305,12 @@ struct s2255_fh {
296 305
297/* current cypress EEPROM firmware version */ 306/* current cypress EEPROM firmware version */
298#define S2255_CUR_USB_FWVER ((3 << 8) | 6) 307#define S2255_CUR_USB_FWVER ((3 << 8) | 6)
308/* current DSP FW version */
309#define S2255_CUR_DSP_FWVER 5
310/* Need DSP version 5+ for video status feature */
311#define S2255_MIN_DSP_STATUS 5
299#define S2255_MAJOR_VERSION 1 312#define S2255_MAJOR_VERSION 1
300#define S2255_MINOR_VERSION 14 313#define S2255_MINOR_VERSION 15
301#define S2255_RELEASE 0 314#define S2255_RELEASE 0
302#define S2255_VERSION KERNEL_VERSION(S2255_MAJOR_VERSION, \ 315#define S2255_VERSION KERNEL_VERSION(S2255_MAJOR_VERSION, \
303 S2255_MINOR_VERSION, \ 316 S2255_MINOR_VERSION, \
@@ -1261,6 +1274,42 @@ static int s2255_set_mode(struct s2255_dev *dev, unsigned long chn,
1261 return res; 1274 return res;
1262} 1275}
1263 1276
1277static int s2255_cmd_status(struct s2255_dev *dev, unsigned long chn,
1278 u32 *pstatus)
1279{
1280 int res;
1281 u32 *buffer;
1282 u32 chn_rev;
1283 mutex_lock(&dev->lock);
1284 chn_rev = G_chnmap[chn];
1285 dprintk(4, "%s chan %d\n", __func__, chn_rev);
1286 buffer = kzalloc(512, GFP_KERNEL);
1287 if (buffer == NULL) {
1288 dev_err(&dev->udev->dev, "out of mem\n");
1289 mutex_unlock(&dev->lock);
1290 return -ENOMEM;
1291 }
1292 /* form the get vid status command */
1293 buffer[0] = IN_DATA_TOKEN;
1294 buffer[1] = chn_rev;
1295 buffer[2] = CMD_STATUS;
1296 *pstatus = 0;
1297 dev->vidstatus_ready[chn] = 0;
1298 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
1299 kfree(buffer);
1300 wait_event_timeout(dev->wait_vidstatus[chn],
1301 (dev->vidstatus_ready[chn] != 0),
1302 msecs_to_jiffies(S2255_VIDSTATUS_TIMEOUT));
1303 if (dev->vidstatus_ready[chn] != 1) {
1304 printk(KERN_DEBUG "s2255: no vidstatus response\n");
1305 res = -EFAULT;
1306 }
1307 *pstatus = dev->vidstatus[chn];
1308 dprintk(4, "%s, vid status %d\n", __func__, *pstatus);
1309 mutex_unlock(&dev->lock);
1310 return res;
1311}
1312
1264static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i) 1313static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
1265{ 1314{
1266 int res; 1315 int res;
@@ -1386,11 +1435,24 @@ out_s_std:
1386static int vidioc_enum_input(struct file *file, void *priv, 1435static int vidioc_enum_input(struct file *file, void *priv,
1387 struct v4l2_input *inp) 1436 struct v4l2_input *inp)
1388{ 1437{
1438 struct s2255_fh *fh = priv;
1439 struct s2255_dev *dev = fh->dev;
1440 u32 status = 0;
1441
1389 if (inp->index != 0) 1442 if (inp->index != 0)
1390 return -EINVAL; 1443 return -EINVAL;
1391 1444
1392 inp->type = V4L2_INPUT_TYPE_CAMERA; 1445 inp->type = V4L2_INPUT_TYPE_CAMERA;
1393 inp->std = S2255_NORMS; 1446 inp->std = S2255_NORMS;
1447 inp->status = 0;
1448 if (dev->dsp_fw_ver >= S2255_MIN_DSP_STATUS) {
1449 int rc;
1450 rc = s2255_cmd_status(dev, fh->channel, &status);
1451 dprintk(4, "s2255_cmd_status rc: %d status %x\n", rc, status);
1452 if (rc == 0)
1453 inp->status = (status & 0x01) ? 0
1454 : V4L2_IN_ST_NO_SIGNAL;
1455 }
1394 strlcpy(inp->name, "Camera", sizeof(inp->name)); 1456 strlcpy(inp->name, "Camera", sizeof(inp->name));
1395 return 0; 1457 return 0;
1396} 1458}
@@ -1700,6 +1762,8 @@ static void s2255_destroy(struct kref *kref)
1700 for (i = 0; i < MAX_CHANNELS; i++) { 1762 for (i = 0; i < MAX_CHANNELS; i++) {
1701 dev->setmode_ready[i] = 1; 1763 dev->setmode_ready[i] = 1;
1702 wake_up(&dev->wait_setmode[i]); 1764 wake_up(&dev->wait_setmode[i]);
1765 dev->vidstatus_ready[i] = 1;
1766 wake_up(&dev->wait_vidstatus[i]);
1703 } 1767 }
1704 mutex_lock(&dev->open_lock); 1768 mutex_lock(&dev->open_lock);
1705 /* reset the DSP so firmware can be reload next time */ 1769 /* reset the DSP so firmware can be reload next time */
@@ -1965,6 +2029,13 @@ static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info)
1965 S2255_FW_SUCCESS); 2029 S2255_FW_SUCCESS);
1966 wake_up(&dev->fw_data->wait_fw); 2030 wake_up(&dev->fw_data->wait_fw);
1967 break; 2031 break;
2032 case S2255_RESPONSE_STATUS:
2033 dev->vidstatus[cc] = pdword[3];
2034 dev->vidstatus_ready[cc] = 1;
2035 wake_up(&dev->wait_vidstatus[cc]);
2036 dprintk(5, "got vidstatus %x chan %d\n",
2037 pdword[3], cc);
2038 break;
1968 default: 2039 default:
1969 printk(KERN_INFO "s2255 unknown resp\n"); 2040 printk(KERN_INFO "s2255 unknown resp\n");
1970 } 2041 }
@@ -2527,9 +2598,10 @@ static int s2255_probe(struct usb_interface *interface,
2527 dev->timer.data = (unsigned long)dev->fw_data; 2598 dev->timer.data = (unsigned long)dev->fw_data;
2528 2599
2529 init_waitqueue_head(&dev->fw_data->wait_fw); 2600 init_waitqueue_head(&dev->fw_data->wait_fw);
2530 for (i = 0; i < MAX_CHANNELS; i++) 2601 for (i = 0; i < MAX_CHANNELS; i++) {
2531 init_waitqueue_head(&dev->wait_setmode[i]); 2602 init_waitqueue_head(&dev->wait_setmode[i]);
2532 2603 init_waitqueue_head(&dev->wait_vidstatus[i]);
2604 }
2533 2605
2534 dev->fw_data->fw_urb = usb_alloc_urb(0, GFP_KERNEL); 2606 dev->fw_data->fw_urb = usb_alloc_urb(0, GFP_KERNEL);
2535 2607
@@ -2561,6 +2633,9 @@ static int s2255_probe(struct usb_interface *interface,
2561 __le32 *pRel; 2633 __le32 *pRel;
2562 pRel = (__le32 *) &dev->fw_data->fw->data[fw_size - 4]; 2634 pRel = (__le32 *) &dev->fw_data->fw->data[fw_size - 4];
2563 printk(KERN_INFO "s2255 dsp fw version %x\n", *pRel); 2635 printk(KERN_INFO "s2255 dsp fw version %x\n", *pRel);
2636 dev->dsp_fw_ver = *pRel;
2637 if (*pRel < S2255_CUR_DSP_FWVER)
2638 printk(KERN_INFO "s2255: f2255usb.bin out of date.\n");
2564 } 2639 }
2565 /* loads v4l specific */ 2640 /* loads v4l specific */
2566 s2255_probe_v4l(dev); 2641 s2255_probe_v4l(dev);
@@ -2597,6 +2672,8 @@ static void s2255_disconnect(struct usb_interface *interface)
2597 for (i = 0; i < MAX_CHANNELS; i++) { 2672 for (i = 0; i < MAX_CHANNELS; i++) {
2598 dev->setmode_ready[i] = 1; 2673 dev->setmode_ready[i] = 1;
2599 wake_up(&dev->wait_setmode[i]); 2674 wake_up(&dev->wait_setmode[i]);
2675 dev->vidstatus_ready[i] = 1;
2676 wake_up(&dev->wait_vidstatus[i]);
2600 } 2677 }
2601 2678
2602 mutex_lock(&dev->open_lock); 2679 mutex_lock(&dev->open_lock);