aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/vivi.c
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil@xs4all.nl>2009-02-14 11:23:12 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-03-30 11:42:50 -0400
commit5ab6c9af375e27c48bd2e86f4d9f6d68c9ab98fd (patch)
treebc6dae0d02ee6169149a67f93a089b091a6ce06c /drivers/media/video/vivi.c
parentb01676005446ad51a32bb00577647c7aae7d2624 (diff)
V4L/DVB (10645): vivi: introduce v4l2_device and do several cleanups
- add v4l2_device - remove BKL - make the debug parameter settable on the fly - set bus_info in querycap Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/vivi.c')
-rw-r--r--drivers/media/video/vivi.c258
1 files changed, 130 insertions, 128 deletions
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c
index 0f25d686ca20..625e9662c7ad 100644
--- a/drivers/media/video/vivi.c
+++ b/drivers/media/video/vivi.c
@@ -33,12 +33,13 @@
33#include <linux/videodev.h> 33#include <linux/videodev.h>
34#endif 34#endif
35#include <linux/interrupt.h> 35#include <linux/interrupt.h>
36#include <media/videobuf-vmalloc.h>
37#include <media/v4l2-common.h>
38#include <media/v4l2-ioctl.h>
39#include <linux/kthread.h> 36#include <linux/kthread.h>
40#include <linux/highmem.h> 37#include <linux/highmem.h>
41#include <linux/freezer.h> 38#include <linux/freezer.h>
39#include <media/videobuf-vmalloc.h>
40#include <media/v4l2-device.h>
41#include <media/v4l2-ioctl.h>
42#include "font.h"
42 43
43#define VIVI_MODULE_NAME "vivi" 44#define VIVI_MODULE_NAME "vivi"
44 45
@@ -47,18 +48,32 @@
47#define WAKE_DENOMINATOR 1001 48#define WAKE_DENOMINATOR 1001
48#define BUFFER_TIMEOUT msecs_to_jiffies(500) /* 0.5 seconds */ 49#define BUFFER_TIMEOUT msecs_to_jiffies(500) /* 0.5 seconds */
49 50
50#include "font.h"
51
52#define VIVI_MAJOR_VERSION 0 51#define VIVI_MAJOR_VERSION 0
53#define VIVI_MINOR_VERSION 5 52#define VIVI_MINOR_VERSION 6
54#define VIVI_RELEASE 0 53#define VIVI_RELEASE 0
55#define VIVI_VERSION \ 54#define VIVI_VERSION \
56 KERNEL_VERSION(VIVI_MAJOR_VERSION, VIVI_MINOR_VERSION, VIVI_RELEASE) 55 KERNEL_VERSION(VIVI_MAJOR_VERSION, VIVI_MINOR_VERSION, VIVI_RELEASE)
57 56
58/* Declare static vars that will be used as parameters */ 57MODULE_DESCRIPTION("Video Technology Magazine Virtual Video Capture Board");
59static unsigned int vid_limit = 16; /* Video memory limit, in Mb */ 58MODULE_AUTHOR("Mauro Carvalho Chehab, Ted Walther and John Sokol");
60static int video_nr = -1; /* /dev/videoN, -1 for autodetect */ 59MODULE_LICENSE("Dual BSD/GPL");
61static int n_devs = 1; /* Number of virtual devices */ 60
61static unsigned video_nr = -1;
62module_param(video_nr, uint, 0644);
63MODULE_PARM_DESC(video_nr, "videoX start number, -1 is autodetect");
64
65static unsigned n_devs = 1;
66module_param(n_devs, uint, 0644);
67MODULE_PARM_DESC(n_devs, "number of video devices to create");
68
69static unsigned debug;
70module_param(debug, uint, 0644);
71MODULE_PARM_DESC(debug, "activates debug info");
72
73static unsigned int vid_limit = 16;
74module_param(vid_limit, uint, 0644);
75MODULE_PARM_DESC(vid_limit, "capture memory limit in megabytes");
76
62 77
63/* supported controls */ 78/* supported controls */
64static struct v4l2_queryctrl vivi_qctrl[] = { 79static struct v4l2_queryctrl vivi_qctrl[] = {
@@ -112,11 +127,8 @@ static struct v4l2_queryctrl vivi_qctrl[] = {
112 127
113static int qctl_regs[ARRAY_SIZE(vivi_qctrl)]; 128static int qctl_regs[ARRAY_SIZE(vivi_qctrl)];
114 129
115#define dprintk(dev, level, fmt, arg...) \ 130#define dprintk(dev, level, fmt, arg...) \
116 do { \ 131 v4l2_dbg(level, debug, &dev->v4l2_dev, fmt, ## arg)
117 if (dev->vfd->debug >= (level)) \
118 printk(KERN_DEBUG "vivi: " fmt , ## arg); \
119 } while (0)
120 132
121/* ------------------------------------------------------------------ 133/* ------------------------------------------------------------------
122 Basic structures 134 Basic structures
@@ -206,6 +218,7 @@ static LIST_HEAD(vivi_devlist);
206 218
207struct vivi_dev { 219struct vivi_dev {
208 struct list_head vivi_devlist; 220 struct list_head vivi_devlist;
221 struct v4l2_device v4l2_dev;
209 222
210 spinlock_t slock; 223 spinlock_t slock;
211 struct mutex mutex; 224 struct mutex mutex;
@@ -656,7 +669,7 @@ static int vivi_start_thread(struct vivi_fh *fh)
656 dma_q->kthread = kthread_run(vivi_thread, fh, "vivi"); 669 dma_q->kthread = kthread_run(vivi_thread, fh, "vivi");
657 670
658 if (IS_ERR(dma_q->kthread)) { 671 if (IS_ERR(dma_q->kthread)) {
659 printk(KERN_ERR "vivi: kernel_thread() failed\n"); 672 v4l2_err(&dev->v4l2_dev, "kernel_thread() failed\n");
660 return PTR_ERR(dma_q->kthread); 673 return PTR_ERR(dma_q->kthread);
661 } 674 }
662 /* Wakes thread */ 675 /* Wakes thread */
@@ -799,8 +812,12 @@ static struct videobuf_queue_ops vivi_video_qops = {
799static int vidioc_querycap(struct file *file, void *priv, 812static int vidioc_querycap(struct file *file, void *priv,
800 struct v4l2_capability *cap) 813 struct v4l2_capability *cap)
801{ 814{
815 struct vivi_fh *fh = priv;
816 struct vivi_dev *dev = fh->dev;
817
802 strcpy(cap->driver, "vivi"); 818 strcpy(cap->driver, "vivi");
803 strcpy(cap->card, "vivi"); 819 strcpy(cap->card, "vivi");
820 strlcpy(cap->bus_info, dev->v4l2_dev.name, sizeof(cap->bus_info));
804 cap->version = VIVI_VERSION; 821 cap->version = VIVI_VERSION;
805 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | 822 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
806 V4L2_CAP_STREAMING | 823 V4L2_CAP_STREAMING |
@@ -1124,32 +1141,21 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
1124 1141
1125static int vivi_open(struct file *file) 1142static int vivi_open(struct file *file)
1126{ 1143{
1127 int minor = video_devdata(file)->minor; 1144 struct vivi_dev *dev = video_drvdata(file);
1128 struct vivi_dev *dev;
1129 struct vivi_fh *fh = NULL; 1145 struct vivi_fh *fh = NULL;
1130 int i; 1146 int i;
1131 int retval = 0; 1147 int retval = 0;
1132 1148
1133 printk(KERN_DEBUG "vivi: open called (minor=%d)\n", minor);
1134
1135 lock_kernel();
1136 list_for_each_entry(dev, &vivi_devlist, vivi_devlist)
1137 if (dev->vfd->minor == minor)
1138 goto found;
1139 unlock_kernel();
1140 return -ENODEV;
1141
1142found:
1143 mutex_lock(&dev->mutex); 1149 mutex_lock(&dev->mutex);
1144 dev->users++; 1150 dev->users++;
1145 1151
1146 if (dev->users > 1) { 1152 if (dev->users > 1) {
1147 dev->users--; 1153 dev->users--;
1148 retval = -EBUSY; 1154 mutex_unlock(&dev->mutex);
1149 goto unlock; 1155 return -EBUSY;
1150 } 1156 }
1151 1157
1152 dprintk(dev, 1, "open minor=%d type=%s users=%d\n", minor, 1158 dprintk(dev, 1, "open /dev/video%d type=%s users=%d\n", dev->vfd->num,
1153 v4l2_type_names[V4L2_BUF_TYPE_VIDEO_CAPTURE], dev->users); 1159 v4l2_type_names[V4L2_BUF_TYPE_VIDEO_CAPTURE], dev->users);
1154 1160
1155 /* allocate + initialize per filehandle data */ 1161 /* allocate + initialize per filehandle data */
@@ -1157,14 +1163,11 @@ found:
1157 if (NULL == fh) { 1163 if (NULL == fh) {
1158 dev->users--; 1164 dev->users--;
1159 retval = -ENOMEM; 1165 retval = -ENOMEM;
1160 goto unlock;
1161 } 1166 }
1162unlock:
1163 mutex_unlock(&dev->mutex); 1167 mutex_unlock(&dev->mutex);
1164 if (retval) { 1168
1165 unlock_kernel(); 1169 if (retval)
1166 return retval; 1170 return retval;
1167 }
1168 1171
1169 file->private_data = fh; 1172 file->private_data = fh;
1170 fh->dev = dev; 1173 fh->dev = dev;
@@ -1193,7 +1196,6 @@ unlock:
1193 sizeof(struct vivi_buffer), fh); 1196 sizeof(struct vivi_buffer), fh);
1194 1197
1195 vivi_start_thread(fh); 1198 vivi_start_thread(fh);
1196 unlock_kernel();
1197 1199
1198 return 0; 1200 return 0;
1199} 1201}
@@ -1249,32 +1251,6 @@ static int vivi_close(struct file *file)
1249 return 0; 1251 return 0;
1250} 1252}
1251 1253
1252static int vivi_release(void)
1253{
1254 struct vivi_dev *dev;
1255 struct list_head *list;
1256
1257 while (!list_empty(&vivi_devlist)) {
1258 list = vivi_devlist.next;
1259 list_del(list);
1260 dev = list_entry(list, struct vivi_dev, vivi_devlist);
1261
1262 if (-1 != dev->vfd->minor) {
1263 printk(KERN_INFO "%s: unregistering /dev/video%d\n",
1264 VIVI_MODULE_NAME, dev->vfd->num);
1265 video_unregister_device(dev->vfd);
1266 } else {
1267 printk(KERN_INFO "%s: releasing /dev/video%d\n",
1268 VIVI_MODULE_NAME, dev->vfd->num);
1269 video_device_release(dev->vfd);
1270 }
1271
1272 kfree(dev);
1273 }
1274
1275 return 0;
1276}
1277
1278static int vivi_mmap(struct file *file, struct vm_area_struct *vma) 1254static int vivi_mmap(struct file *file, struct vm_area_struct *vma)
1279{ 1255{
1280 struct vivi_fh *fh = file->private_data; 1256 struct vivi_fh *fh = file->private_data;
@@ -1337,84 +1313,126 @@ static struct video_device vivi_template = {
1337 .tvnorms = V4L2_STD_525_60, 1313 .tvnorms = V4L2_STD_525_60,
1338 .current_norm = V4L2_STD_NTSC_M, 1314 .current_norm = V4L2_STD_NTSC_M,
1339}; 1315};
1316
1340/* ----------------------------------------------------------------- 1317/* -----------------------------------------------------------------
1341 Initialization and module stuff 1318 Initialization and module stuff
1342 ------------------------------------------------------------------*/ 1319 ------------------------------------------------------------------*/
1343 1320
1344/* This routine allocates from 1 to n_devs virtual drivers. 1321static int vivi_release(void)
1322{
1323 struct vivi_dev *dev;
1324 struct list_head *list;
1345 1325
1346 The real maximum number of virtual drivers will depend on how many drivers 1326 while (!list_empty(&vivi_devlist)) {
1347 will succeed. This is limited to the maximum number of devices that 1327 list = vivi_devlist.next;
1348 videodev supports, which is equal to VIDEO_NUM_DEVICES. 1328 list_del(list);
1349 */ 1329 dev = list_entry(list, struct vivi_dev, vivi_devlist);
1350static int __init vivi_init(void) 1330
1331 v4l2_info(&dev->v4l2_dev, "unregistering /dev/video%d\n",
1332 dev->vfd->num);
1333 video_unregister_device(dev->vfd);
1334 v4l2_device_unregister(&dev->v4l2_dev);
1335 kfree(dev);
1336 }
1337
1338 return 0;
1339}
1340
1341static int __init vivi_create_instance(int i)
1351{ 1342{
1352 int ret = -ENOMEM, i;
1353 struct vivi_dev *dev; 1343 struct vivi_dev *dev;
1354 struct video_device *vfd; 1344 struct video_device *vfd;
1345 int ret;
1355 1346
1356 if (n_devs <= 0) 1347 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
1357 n_devs = 1; 1348 if (!dev)
1349 return -ENOMEM;
1358 1350
1359 for (i = 0; i < n_devs; i++) { 1351 snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name),
1360 dev = kzalloc(sizeof(*dev), GFP_KERNEL); 1352 "%s-%03d", VIVI_MODULE_NAME, i);
1361 if (!dev) 1353 ret = v4l2_device_register(NULL, &dev->v4l2_dev);
1362 break; 1354 if (ret)
1355 goto free_dev;
1363 1356
1364 /* init video dma queues */ 1357 /* init video dma queues */
1365 INIT_LIST_HEAD(&dev->vidq.active); 1358 INIT_LIST_HEAD(&dev->vidq.active);
1366 init_waitqueue_head(&dev->vidq.wq); 1359 init_waitqueue_head(&dev->vidq.wq);
1367 1360
1368 /* initialize locks */ 1361 /* initialize locks */
1369 spin_lock_init(&dev->slock); 1362 spin_lock_init(&dev->slock);
1370 mutex_init(&dev->mutex); 1363 mutex_init(&dev->mutex);
1371 1364
1372 vfd = video_device_alloc(); 1365 ret = -ENOMEM;
1373 if (!vfd) { 1366 vfd = video_device_alloc();
1374 kfree(dev); 1367 if (!vfd)
1375 break; 1368 goto unreg_dev;
1376 }
1377 1369
1378 *vfd = vivi_template; 1370 *vfd = vivi_template;
1379 1371
1380 ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr); 1372 ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr);
1381 if (ret < 0) { 1373 if (ret < 0)
1382 video_device_release(vfd); 1374 goto rel_vdev;
1383 kfree(dev);
1384 1375
1385 /* If some registers succeeded, keep driver */ 1376 video_set_drvdata(vfd, dev);
1386 if (i)
1387 ret = 0;
1388 1377
1389 break; 1378 /* Now that everything is fine, let's add it to device list */
1390 } 1379 list_add_tail(&dev->vivi_devlist, &vivi_devlist);
1391 1380
1392 /* Now that everything is fine, let's add it to device list */ 1381 snprintf(vfd->name, sizeof(vfd->name), "%s (%i)",
1393 list_add_tail(&dev->vivi_devlist, &vivi_devlist); 1382 vivi_template.name, vfd->num);
1394 1383
1395 snprintf(vfd->name, sizeof(vfd->name), "%s (%i)", 1384 if (video_nr >= 0)
1396 vivi_template.name, vfd->minor); 1385 video_nr++;
1397 1386
1398 if (video_nr >= 0) 1387 dev->vfd = vfd;
1399 video_nr++; 1388 v4l2_info(&dev->v4l2_dev, "V4L2 device registered as /dev/video%d\n",
1389 vfd->num);
1390 return 0;
1391
1392rel_vdev:
1393 video_device_release(vfd);
1394unreg_dev:
1395 v4l2_device_unregister(&dev->v4l2_dev);
1396free_dev:
1397 kfree(dev);
1398 return ret;
1399}
1400 1400
1401 dev->vfd = vfd; 1401/* This routine allocates from 1 to n_devs virtual drivers.
1402 printk(KERN_INFO "%s: V4L2 device registered as /dev/video%d\n", 1402
1403 VIVI_MODULE_NAME, vfd->num); 1403 The real maximum number of virtual drivers will depend on how many drivers
1404 will succeed. This is limited to the maximum number of devices that
1405 videodev supports, which is equal to VIDEO_NUM_DEVICES.
1406 */
1407static int __init vivi_init(void)
1408{
1409 int ret, i;
1410
1411 if (n_devs <= 0)
1412 n_devs = 1;
1413
1414 for (i = 0; i < n_devs; i++) {
1415 ret = vivi_create_instance(i);
1416 if (ret) {
1417 /* If some instantiations succeeded, keep driver */
1418 if (i)
1419 ret = 0;
1420 break;
1421 }
1404 } 1422 }
1405 1423
1406 if (ret < 0) { 1424 if (ret < 0) {
1407 vivi_release();
1408 printk(KERN_INFO "Error %d while loading vivi driver\n", ret); 1425 printk(KERN_INFO "Error %d while loading vivi driver\n", ret);
1409 } else { 1426 return ret;
1410 printk(KERN_INFO "Video Technology Magazine Virtual Video " 1427 }
1428
1429 printk(KERN_INFO "Video Technology Magazine Virtual Video "
1411 "Capture Board ver %u.%u.%u successfully loaded.\n", 1430 "Capture Board ver %u.%u.%u successfully loaded.\n",
1412 (VIVI_VERSION >> 16) & 0xFF, (VIVI_VERSION >> 8) & 0xFF, 1431 (VIVI_VERSION >> 16) & 0xFF, (VIVI_VERSION >> 8) & 0xFF,
1413 VIVI_VERSION & 0xFF); 1432 VIVI_VERSION & 0xFF);
1414 1433
1415 /* n_devs will reflect the actual number of allocated devices */ 1434 /* n_devs will reflect the actual number of allocated devices */
1416 n_devs = i; 1435 n_devs = i;
1417 }
1418 1436
1419 return ret; 1437 return ret;
1420} 1438}
@@ -1426,19 +1444,3 @@ static void __exit vivi_exit(void)
1426 1444
1427module_init(vivi_init); 1445module_init(vivi_init);
1428module_exit(vivi_exit); 1446module_exit(vivi_exit);
1429
1430MODULE_DESCRIPTION("Video Technology Magazine Virtual Video Capture Board");
1431MODULE_AUTHOR("Mauro Carvalho Chehab, Ted Walther and John Sokol");
1432MODULE_LICENSE("Dual BSD/GPL");
1433
1434module_param(video_nr, uint, 0444);
1435MODULE_PARM_DESC(video_nr, "video iminor start number");
1436
1437module_param(n_devs, uint, 0444);
1438MODULE_PARM_DESC(n_devs, "number of video devices to create");
1439
1440module_param_named(debug, vivi_template.debug, int, 0444);
1441MODULE_PARM_DESC(debug, "activates debug info");
1442
1443module_param(vid_limit, int, 0644);
1444MODULE_PARM_DESC(vid_limit, "capture memory limit in megabytes");