]> nv-tegra.nvidia Code Review - linux-3.10.git/blobdiff - drivers/media/video/davinci/vpfe_capture.c
Merge branch 'linus' into sched/core
[linux-3.10.git] / drivers / media / video / davinci / vpfe_capture.c
index c704a26376833a67af71b8e1605a4cea428e9e03..7cf042f9b3775b025a4e405aa09a404310db7578 100644 (file)
  *             - Support for control ioctls
  */
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
-#include <linux/version.h>
 #include <media/v4l2-common.h>
 #include <linux/io.h>
 #include <media/davinci/vpfe_capture.h>
@@ -108,9 +108,6 @@ struct ccdc_config {
        int vpfe_probed;
        /* name of ccdc device */
        char name[32];
-       /* for storing mem maps for CCDC */
-       int ccdc_addr_size;
-       void *__iomem ccdc_addr;
 };
 
 /* data structures */
@@ -230,7 +227,6 @@ int vpfe_register_ccdc_device(struct ccdc_hw_device *dev)
        BUG_ON(!dev->hw_ops.set_image_window);
        BUG_ON(!dev->hw_ops.get_image_window);
        BUG_ON(!dev->hw_ops.get_line_length);
-       BUG_ON(!dev->hw_ops.setfbaddr);
        BUG_ON(!dev->hw_ops.getfid);
 
        mutex_lock(&ccdc_lock);
@@ -241,25 +237,23 @@ int vpfe_register_ccdc_device(struct ccdc_hw_device *dev)
                 * walk through it during vpfe probe
                 */
                printk(KERN_ERR "vpfe capture not initialized\n");
-               ret = -1;
+               ret = -EFAULT;
                goto unlock;
        }
 
        if (strcmp(dev->name, ccdc_cfg->name)) {
                /* ignore this ccdc */
-               ret = -1;
+               ret = -EINVAL;
                goto unlock;
        }
 
        if (ccdc_dev) {
                printk(KERN_ERR "ccdc already registered\n");
-               ret = -1;
+               ret = -EINVAL;
                goto unlock;
        }
 
        ccdc_dev = dev;
-       dev->hw_ops.set_ccdc_base(ccdc_cfg->ccdc_addr,
-                                 ccdc_cfg->ccdc_addr_size);
 unlock:
        mutex_unlock(&ccdc_lock);
        return ret;
@@ -660,7 +654,7 @@ static void vpfe_detach_irq(struct vpfe_device *vpfe_dev)
 
        frame_format = ccdc_dev->hw_ops.get_frame_format();
        if (frame_format == CCDC_FRMFMT_PROGRESSIVE)
-               free_irq(IRQ_VDINT1, vpfe_dev);
+               free_irq(vpfe_dev->ccdc_irq1, vpfe_dev);
 }
 
 static int vpfe_attach_irq(struct vpfe_device *vpfe_dev)
@@ -1413,6 +1407,41 @@ static int vpfe_dqbuf(struct file *file, void *priv,
                                      buf, file->f_flags & O_NONBLOCK);
 }
 
+static int vpfe_queryctrl(struct file *file, void *priv,
+               struct v4l2_queryctrl *qctrl)
+{
+       struct vpfe_device *vpfe_dev = video_drvdata(file);
+       struct vpfe_subdev_info *sdinfo;
+
+       sdinfo = vpfe_dev->current_subdev;
+
+       return v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id,
+                                        core, queryctrl, qctrl);
+
+}
+
+static int vpfe_g_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl)
+{
+       struct vpfe_device *vpfe_dev = video_drvdata(file);
+       struct vpfe_subdev_info *sdinfo;
+
+       sdinfo = vpfe_dev->current_subdev;
+
+       return v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id,
+                                        core, g_ctrl, ctrl);
+}
+
+static int vpfe_s_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl)
+{
+       struct vpfe_device *vpfe_dev = video_drvdata(file);
+       struct vpfe_subdev_info *sdinfo;
+
+       sdinfo = vpfe_dev->current_subdev;
+
+       return v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id,
+                                        core, s_ctrl, ctrl);
+}
+
 /*
  * vpfe_calculate_offsets : This function calculates buffers offset
  * for top and bottom field
@@ -1710,6 +1739,9 @@ static const struct v4l2_ioctl_ops vpfe_ioctl_ops = {
        .vidioc_querystd         = vpfe_querystd,
        .vidioc_s_std            = vpfe_s_std,
        .vidioc_g_std            = vpfe_g_std,
+       .vidioc_queryctrl        = vpfe_queryctrl,
+       .vidioc_g_ctrl           = vpfe_g_ctrl,
+       .vidioc_s_ctrl           = vpfe_s_ctrl,
        .vidioc_reqbufs          = vpfe_reqbufs,
        .vidioc_querybuf         = vpfe_querybuf,
        .vidioc_qbuf             = vpfe_qbuf,
@@ -1749,61 +1781,6 @@ static struct vpfe_device *vpfe_initialize(void)
        return vpfe_dev;
 }
 
-static void vpfe_disable_clock(struct vpfe_device *vpfe_dev)
-{
-       struct vpfe_config *vpfe_cfg = vpfe_dev->cfg;
-
-       clk_disable(vpfe_cfg->vpssclk);
-       clk_put(vpfe_cfg->vpssclk);
-       clk_disable(vpfe_cfg->slaveclk);
-       clk_put(vpfe_cfg->slaveclk);
-       v4l2_info(vpfe_dev->pdev->driver,
-                "vpfe vpss master & slave clocks disabled\n");
-}
-
-static int vpfe_enable_clock(struct vpfe_device *vpfe_dev)
-{
-       struct vpfe_config *vpfe_cfg = vpfe_dev->cfg;
-       int ret = -ENOENT;
-
-       vpfe_cfg->vpssclk = clk_get(vpfe_dev->pdev, "vpss_master");
-       if (NULL == vpfe_cfg->vpssclk) {
-               v4l2_err(vpfe_dev->pdev->driver, "No clock defined for"
-                        "vpss_master\n");
-               return ret;
-       }
-
-       if (clk_enable(vpfe_cfg->vpssclk)) {
-               v4l2_err(vpfe_dev->pdev->driver,
-                       "vpfe vpss master clock not enabled\n");
-               goto out;
-       }
-       v4l2_info(vpfe_dev->pdev->driver,
-                "vpfe vpss master clock enabled\n");
-
-       vpfe_cfg->slaveclk = clk_get(vpfe_dev->pdev, "vpss_slave");
-       if (NULL == vpfe_cfg->slaveclk) {
-               v4l2_err(vpfe_dev->pdev->driver,
-                       "No clock defined for vpss slave\n");
-               goto out;
-       }
-
-       if (clk_enable(vpfe_cfg->slaveclk)) {
-               v4l2_err(vpfe_dev->pdev->driver,
-                        "vpfe vpss slave clock not enabled\n");
-               goto out;
-       }
-       v4l2_info(vpfe_dev->pdev->driver, "vpfe vpss slave clock enabled\n");
-       return 0;
-out:
-       if (vpfe_cfg->vpssclk)
-               clk_put(vpfe_cfg->vpssclk);
-       if (vpfe_cfg->slaveclk)
-               clk_put(vpfe_cfg->slaveclk);
-
-       return -1;
-}
-
 /*
  * vpfe_probe : This function creates device entries by register
  * itself to the V4L2 driver and initializes fields of each
@@ -1833,7 +1810,7 @@ static __init int vpfe_probe(struct platform_device *pdev)
 
        if (NULL == pdev->dev.platform_data) {
                v4l2_err(pdev->dev.driver, "Unable to get vpfe config\n");
-               ret = -ENOENT;
+               ret = -ENODEV;
                goto probe_free_dev_mem;
        }
 
@@ -1847,18 +1824,13 @@ static __init int vpfe_probe(struct platform_device *pdev)
                goto probe_free_dev_mem;
        }
 
-       /* enable vpss clocks */
-       ret = vpfe_enable_clock(vpfe_dev);
-       if (ret)
-               goto probe_free_dev_mem;
-
        mutex_lock(&ccdc_lock);
        /* Allocate memory for ccdc configuration */
        ccdc_cfg = kmalloc(sizeof(struct ccdc_config), GFP_KERNEL);
        if (NULL == ccdc_cfg) {
                v4l2_err(pdev->dev.driver,
                         "Memory allocation failed for ccdc_cfg\n");
-               goto probe_disable_clock;
+               goto probe_free_dev_mem;
        }
 
        strncpy(ccdc_cfg->name, vpfe_cfg->ccdc, 32);
@@ -1867,61 +1839,34 @@ static __init int vpfe_probe(struct platform_device *pdev)
        if (!res1) {
                v4l2_err(pdev->dev.driver,
                         "Unable to get interrupt for VINT0\n");
-               ret = -ENOENT;
-               goto probe_disable_clock;
+               ret = -ENODEV;
+               goto probe_free_ccdc_cfg_mem;
        }
        vpfe_dev->ccdc_irq0 = res1->start;
 
        /* Get VINT1 irq resource */
-       res1 = platform_get_resource(pdev,
-                               IORESOURCE_IRQ, 1);
+       res1 = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
        if (!res1) {
                v4l2_err(pdev->dev.driver,
                         "Unable to get interrupt for VINT1\n");
-               ret = -ENOENT;
-               goto probe_disable_clock;
+               ret = -ENODEV;
+               goto probe_free_ccdc_cfg_mem;
        }
        vpfe_dev->ccdc_irq1 = res1->start;
 
-       /* Get address base of CCDC */
-       res1 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!res1) {
-               v4l2_err(pdev->dev.driver,
-                       "Unable to get register address map\n");
-               ret = -ENOENT;
-               goto probe_disable_clock;
-       }
-
-       ccdc_cfg->ccdc_addr_size = res1->end - res1->start + 1;
-       if (!request_mem_region(res1->start, ccdc_cfg->ccdc_addr_size,
-                               pdev->dev.driver->name)) {
-               v4l2_err(pdev->dev.driver,
-                       "Failed request_mem_region for ccdc base\n");
-               ret = -ENXIO;
-               goto probe_disable_clock;
-       }
-       ccdc_cfg->ccdc_addr = ioremap_nocache(res1->start,
-                                            ccdc_cfg->ccdc_addr_size);
-       if (!ccdc_cfg->ccdc_addr) {
-               v4l2_err(pdev->dev.driver, "Unable to ioremap ccdc addr\n");
-               ret = -ENXIO;
-               goto probe_out_release_mem1;
-       }
-
        ret = request_irq(vpfe_dev->ccdc_irq0, vpfe_isr, IRQF_DISABLED,
                          "vpfe_capture0", vpfe_dev);
 
        if (0 != ret) {
                v4l2_err(pdev->dev.driver, "Unable to request interrupt\n");
-               goto probe_out_unmap1;
+               goto probe_free_ccdc_cfg_mem;
        }
 
        /* Allocate memory for video device */
        vfd = video_device_alloc();
        if (NULL == vfd) {
                ret = -ENOMEM;
-               v4l2_err(pdev->dev.driver,
-                       "Unable to alloc video device\n");
+               v4l2_err(pdev->dev.driver, "Unable to alloc video device\n");
                goto probe_out_release_irq;
        }
 
@@ -1929,7 +1874,6 @@ static __init int vpfe_probe(struct platform_device *pdev)
        vfd->release            = video_device_release;
        vfd->fops               = &vpfe_fops;
        vfd->ioctl_ops          = &vpfe_ioctl_ops;
-       vfd->minor              = -1;
        vfd->tvnorms            = 0;
        vfd->current_norm       = V4L2_STD_PAL;
        vfd->v4l2_dev           = &vpfe_dev->v4l2_dev;
@@ -1978,8 +1922,7 @@ static __init int vpfe_probe(struct platform_device *pdev)
        platform_set_drvdata(pdev, vpfe_dev);
        /* set driver private data */
        video_set_drvdata(vpfe_dev->video_dev, vpfe_dev);
-       i2c_adap = i2c_get_adapter(1);
-       vpfe_cfg = pdev->dev.platform_data;
+       i2c_adap = i2c_get_adapter(vpfe_cfg->i2c_adapter_id);
        num_subdevs = vpfe_cfg->num_subdevs;
        vpfe_dev->sd = kmalloc(sizeof(struct v4l2_subdev *) * num_subdevs,
                                GFP_KERNEL);
@@ -2034,16 +1977,11 @@ probe_out_video_unregister:
 probe_out_v4l2_unregister:
        v4l2_device_unregister(&vpfe_dev->v4l2_dev);
 probe_out_video_release:
-       if (vpfe_dev->video_dev->minor == -1)
+       if (!video_is_registered(vpfe_dev->video_dev))
                video_device_release(vpfe_dev->video_dev);
 probe_out_release_irq:
        free_irq(vpfe_dev->ccdc_irq0, vpfe_dev);
-probe_out_unmap1:
-       iounmap(ccdc_cfg->ccdc_addr);
-probe_out_release_mem1:
-       release_mem_region(res1->start, res1->end - res1->start + 1);
-probe_disable_clock:
-       vpfe_disable_clock(vpfe_dev);
+probe_free_ccdc_cfg_mem:
        mutex_unlock(&ccdc_lock);
        kfree(ccdc_cfg);
 probe_free_dev_mem:
@@ -2054,10 +1992,9 @@ probe_free_dev_mem:
 /*
  * vpfe_remove : It un-register device from V4L2 driver
  */
-static int vpfe_remove(struct platform_device *pdev)
+static int __devexit vpfe_remove(struct platform_device *pdev)
 {
        struct vpfe_device *vpfe_dev = platform_get_drvdata(pdev);
-       struct resource *res;
 
        v4l2_info(pdev->dev.driver, "vpfe_remove\n");
 
@@ -2065,12 +2002,6 @@ static int vpfe_remove(struct platform_device *pdev)
        kfree(vpfe_dev->sd);
        v4l2_device_unregister(&vpfe_dev->v4l2_dev);
        video_unregister_device(vpfe_dev->video_dev);
-       mutex_lock(&ccdc_lock);
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       release_mem_region(res->start, res->end - res->start + 1);
-       iounmap(ccdc_cfg->ccdc_addr);
-       mutex_unlock(&ccdc_lock);
-       vpfe_disable_clock(vpfe_dev);
        kfree(vpfe_dev);
        kfree(ccdc_cfg);
        return 0;
@@ -2090,7 +2021,7 @@ vpfe_resume(struct device *dev)
        return -1;
 }
 
-static struct dev_pm_ops vpfe_dev_pm_ops = {
+static const struct dev_pm_ops vpfe_dev_pm_ops = {
        .suspend = vpfe_suspend,
        .resume = vpfe_resume,
 };