include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit...
[safe/jmp/linux-2.6] / drivers / media / video / pvrusb2 / pvrusb2-v4l2.c
index c53037a..bf1e0fe 100644 (file)
@@ -20,6 +20,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/version.h>
 #include "pvrusb2-context.h"
 #include "pvrusb2-hdw.h"
@@ -90,8 +91,8 @@ static struct v4l2_capability pvr_capability ={
        .driver         = "pvrusb2",
        .card           = "Hauppauge WinTV pvr-usb2",
        .bus_info       = "usb",
-       .version        = KERNEL_VERSION(0,8,0),
-       .capabilities   = (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VBI_CAPTURE |
+       .version        = KERNEL_VERSION(0, 9, 0),
+       .capabilities   = (V4L2_CAP_VIDEO_CAPTURE |
                           V4L2_CAP_TUNER | V4L2_CAP_AUDIO | V4L2_CAP_RADIO |
                           V4L2_CAP_READWRITE),
        .reserved       = {0,0,0,0}
@@ -151,31 +152,19 @@ static struct v4l2_format pvr_format [] = {
 };
 
 
-static const char *get_v4l_name(int v4l_type)
-{
-       switch (v4l_type) {
-       case VFL_TYPE_GRABBER: return "video";
-       case VFL_TYPE_RADIO: return "radio";
-       case VFL_TYPE_VBI: return "vbi";
-       default: return "?";
-       }
-}
-
-
 /*
  * pvr_ioctl()
  *
  * This is part of Video 4 Linux API. The procedure handles ioctl() calls.
  *
  */
-static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
-                             unsigned int cmd, void *arg)
+static long pvr2_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
 {
        struct pvr2_v4l2_fh *fh = file->private_data;
        struct pvr2_v4l2 *vp = fh->vhead;
        struct pvr2_v4l2_dev *dev_info = fh->dev_info;
        struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
-       int ret = -EINVAL;
+       long ret = -EINVAL;
 
        if (pvrusb2_debug & PVR2_TRACE_V4LIOCTL) {
                v4l_print_ioctl(pvr2_hdw_get_driver_name(hdw),cmd);
@@ -268,7 +257,7 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
                memset(&tmp,0,sizeof(tmp));
                tmp.index = vi->index;
                ret = 0;
-               if ((vi->index < 0) || (vi->index >= fh->input_cnt)) {
+               if (vi->index >= fh->input_cnt) {
                        ret = -EINVAL;
                        break;
                }
@@ -332,7 +321,7 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
        case VIDIOC_S_INPUT:
        {
                struct v4l2_input *vi = (struct v4l2_input *)arg;
-               if ((vi->index < 0) || (vi->index >= fh->input_cnt)) {
+               if (vi->index >= fh->input_cnt) {
                        ret = -ERANGE;
                        break;
                }
@@ -755,6 +744,92 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
                break;
        }
 
+       case VIDIOC_CROPCAP:
+       {
+               struct v4l2_cropcap *cap = (struct v4l2_cropcap *)arg;
+               if (cap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+                       ret = -EINVAL;
+                       break;
+               }
+               ret = pvr2_hdw_get_cropcap(hdw, cap);
+               cap->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; /* paranoia */
+               break;
+       }
+       case VIDIOC_G_CROP:
+       {
+               struct v4l2_crop *crop = (struct v4l2_crop *)arg;
+               int val = 0;
+               if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+                       ret = -EINVAL;
+                       break;
+               }
+               ret = pvr2_ctrl_get_value(
+                       pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPL), &val);
+               if (ret != 0) {
+                       ret = -EINVAL;
+                       break;
+               }
+               crop->c.left = val;
+               ret = pvr2_ctrl_get_value(
+                       pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPT), &val);
+               if (ret != 0) {
+                       ret = -EINVAL;
+                       break;
+               }
+               crop->c.top = val;
+               ret = pvr2_ctrl_get_value(
+                       pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPW), &val);
+               if (ret != 0) {
+                       ret = -EINVAL;
+                       break;
+               }
+               crop->c.width = val;
+               ret = pvr2_ctrl_get_value(
+                       pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPH), &val);
+               if (ret != 0) {
+                       ret = -EINVAL;
+                       break;
+               }
+               crop->c.height = val;
+       }
+       case VIDIOC_S_CROP:
+       {
+               struct v4l2_crop *crop = (struct v4l2_crop *)arg;
+               struct v4l2_cropcap cap;
+               if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+                       ret = -EINVAL;
+                       break;
+               }
+               cap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+               ret = pvr2_ctrl_set_value(
+                       pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPL),
+                       crop->c.left);
+               if (ret != 0) {
+                       ret = -EINVAL;
+                       break;
+               }
+               ret = pvr2_ctrl_set_value(
+                       pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPT),
+                       crop->c.top);
+               if (ret != 0) {
+                       ret = -EINVAL;
+                       break;
+               }
+               ret = pvr2_ctrl_set_value(
+                       pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPW),
+                       crop->c.width);
+               if (ret != 0) {
+                       ret = -EINVAL;
+                       break;
+               }
+               ret = pvr2_ctrl_set_value(
+                       pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPH),
+                       crop->c.height);
+               if (ret != 0) {
+                       ret = -EINVAL;
+                       break;
+               }
+       }
        case VIDIOC_LOG_STATUS:
        {
                pvr2_hdw_trigger_module_log(hdw);
@@ -766,19 +841,19 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
        case VIDIOC_DBG_G_REGISTER:
        {
                u64 val;
-               struct v4l2_register *req = (struct v4l2_register *)arg;
+               struct v4l2_dbg_register *req = (struct v4l2_dbg_register *)arg;
                if (cmd == VIDIOC_DBG_S_REGISTER) val = req->val;
                ret = pvr2_hdw_register_access(
-                       hdw,req->match_type,req->match_chip,req->reg,
-                       cmd == VIDIOC_DBG_S_REGISTER,&val);
+                       hdw, &req->match, req->reg,
+                       cmd == VIDIOC_DBG_S_REGISTER, &val);
                if (cmd == VIDIOC_DBG_G_REGISTER) req->val = val;
                break;
        }
 #endif
 
        default :
-               ret = v4l_compat_translate_ioctl(inode,file,cmd,
-                                                arg,pvr2_v4l2_do_ioctl);
+               ret = v4l_compat_translate_ioctl(file, cmd,
+                                                arg, pvr2_v4l2_do_ioctl);
        }
 
        pvr2_hdw_commit_ctl(hdw);
@@ -786,31 +861,28 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
        if (ret < 0) {
                if (pvrusb2_debug & PVR2_TRACE_V4LIOCTL) {
                        pvr2_trace(PVR2_TRACE_V4LIOCTL,
-                                  "pvr2_v4l2_do_ioctl failure, ret=%d",ret);
+                                  "pvr2_v4l2_do_ioctl failure, ret=%ld", ret);
                } else {
                        if (pvrusb2_debug & PVR2_TRACE_V4LIOCTL) {
                                pvr2_trace(PVR2_TRACE_V4LIOCTL,
-                                          "pvr2_v4l2_do_ioctl failure, ret=%d"
-                                          " command was:",ret);
+                                          "pvr2_v4l2_do_ioctl failure, ret=%ld"
+                                          " command was:", ret);
                                v4l_print_ioctl(pvr2_hdw_get_driver_name(hdw),
                                                cmd);
                        }
                }
        } else {
                pvr2_trace(PVR2_TRACE_V4LIOCTL,
-                          "pvr2_v4l2_do_ioctl complete, ret=%d (0x%x)",
-                          ret,ret);
+                          "pvr2_v4l2_do_ioctl complete, ret=%ld (0x%lx)",
+                          ret, ret);
        }
        return ret;
 }
 
-
 static void pvr2_v4l2_dev_destroy(struct pvr2_v4l2_dev *dip)
 {
-       int minor_id = dip->devbase.minor;
        struct pvr2_hdw *hdw = dip->v4lp->channel.mc_head->hdw;
        enum pvr2_config cfg = dip->config;
-       int v4l_type = dip->v4l_type;
 
        pvr2_hdw_v4l_store_minor_number(hdw,dip->minor_type,-1);
 
@@ -822,13 +894,22 @@ static void pvr2_v4l2_dev_destroy(struct pvr2_v4l2_dev *dip)
           are gone. */
        video_unregister_device(&dip->devbase);
 
-       printk(KERN_INFO "pvrusb2: unregistered device %s%u [%s]\n",
-              get_v4l_name(v4l_type),minor_id & 0x1f,
+       printk(KERN_INFO "pvrusb2: unregistered device %s [%s]\n",
+              video_device_node_name(&dip->devbase),
               pvr2_config_get_name(cfg));
 
 }
 
 
+static void pvr2_v4l2_dev_disassociate_parent(struct pvr2_v4l2_dev *dip)
+{
+       if (!dip) return;
+       if (!dip->devbase.parent) return;
+       dip->devbase.parent = NULL;
+       device_move(&dip->devbase.dev, NULL, DPM_ORDER_NONE);
+}
+
+
 static void pvr2_v4l2_destroy_no_lock(struct pvr2_v4l2 *vp)
 {
        if (vp->dev_video) {
@@ -859,24 +940,22 @@ static void pvr2_v4l2_internal_check(struct pvr2_channel *chp)
        struct pvr2_v4l2 *vp;
        vp = container_of(chp,struct pvr2_v4l2,channel);
        if (!vp->channel.mc_head->disconnect_flag) return;
+       pvr2_v4l2_dev_disassociate_parent(vp->dev_video);
+       pvr2_v4l2_dev_disassociate_parent(vp->dev_radio);
        if (vp->vfirst) return;
        pvr2_v4l2_destroy_no_lock(vp);
 }
 
 
-static int pvr2_v4l2_ioctl(struct inode *inode, struct file *file,
+static long pvr2_v4l2_ioctl(struct file *file,
                           unsigned int cmd, unsigned long arg)
 {
 
-/* Temporary hack : use ivtv api until a v4l2 one is available. */
-#define IVTV_IOC_G_CODEC        0xFFEE7703
-#define IVTV_IOC_S_CODEC        0xFFEE7704
-       if (cmd == IVTV_IOC_G_CODEC || cmd == IVTV_IOC_S_CODEC) return 0;
-       return video_usercopy(inode, file, cmd, arg, pvr2_v4l2_do_ioctl);
+       return video_usercopy(file, cmd, arg, pvr2_v4l2_do_ioctl);
 }
 
 
-static int pvr2_v4l2_release(struct inode *inode, struct file *file)
+static int pvr2_v4l2_release(struct file *file)
 {
        struct pvr2_v4l2_fh *fhp = file->private_data;
        struct pvr2_v4l2 *vp = fhp->vhead;
@@ -924,7 +1003,7 @@ static int pvr2_v4l2_release(struct inode *inode, struct file *file)
 }
 
 
-static int pvr2_v4l2_open(struct inode *inode, struct file *file)
+static int pvr2_v4l2_open(struct file *file)
 {
        struct pvr2_v4l2_dev *dip; /* Our own context pointer */
        struct pvr2_v4l2_fh *fhp;
@@ -1151,13 +1230,12 @@ static unsigned int pvr2_v4l2_poll(struct file *file, poll_table *wait)
 }
 
 
-static const struct file_operations vdev_fops = {
+static const struct v4l2_file_operations vdev_fops = {
        .owner      = THIS_MODULE,
        .open       = pvr2_v4l2_open,
        .release    = pvr2_v4l2_release,
        .read       = pvr2_v4l2_read,
        .ioctl      = pvr2_v4l2_ioctl,
-       .llseek     = no_llseek,
        .poll       = pvr2_v4l2_poll,
 };
 
@@ -1171,12 +1249,13 @@ static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip,
                               struct pvr2_v4l2 *vp,
                               int v4l_type)
 {
+       struct usb_device *usbdev;
        int mindevnum;
        int unit_number;
        int *nr_ptr = NULL;
        dip->v4lp = vp;
 
-
+       usbdev = pvr2_hdw_get_dev(vp->channel.mc_head->hdw);
        dip->v4l_type = v4l_type;
        switch (v4l_type) {
        case VFL_TYPE_GRABBER:
@@ -1185,8 +1264,9 @@ static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip,
                dip->minor_type = pvr2_v4l_type_video;
                nr_ptr = video_nr;
                if (!dip->stream) {
-                       err("Failed to set up pvrusb2 v4l video dev"
-                           " due to missing stream instance");
+                       pr_err(KBUILD_MODNAME
+                               ": Failed to set up pvrusb2 v4l video dev"
+                               " due to missing stream instance\n");
                        return;
                }
                break;
@@ -1203,8 +1283,8 @@ static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip,
                break;
        default:
                /* Bail out (this should be impossible) */
-               err("Failed to set up pvrusb2 v4l dev"
-                   " due to unrecognized config");
+               pr_err(KBUILD_MODNAME ": Failed to set up pvrusb2 v4l dev"
+                   " due to unrecognized config\n");
                return;
        }
 
@@ -1216,15 +1296,17 @@ static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip,
        if (nr_ptr && (unit_number >= 0) && (unit_number < PVR_NUM)) {
                mindevnum = nr_ptr[unit_number];
        }
+       dip->devbase.parent = &usbdev->dev;
        if ((video_register_device(&dip->devbase,
                                   dip->v4l_type, mindevnum) < 0) &&
            (video_register_device(&dip->devbase,
                                   dip->v4l_type, -1) < 0)) {
-               err("Failed to register pvrusb2 v4l device");
+               pr_err(KBUILD_MODNAME
+                       ": Failed to register pvrusb2 v4l device\n");
        }
 
-       printk(KERN_INFO "pvrusb2: registered device %s%u [%s]\n",
-              get_v4l_name(dip->v4l_type),dip->devbase.minor & 0x1f,
+       printk(KERN_INFO "pvrusb2: registered device %s [%s]\n",
+              video_device_node_name(&dip->devbase),
               pvr2_config_get_name(dip->config));
 
        pvr2_hdw_v4l_store_minor_number(vp->channel.mc_head->hdw,