V4L/DVB (8687): soc-camera: Move .power and .reset from soc_camera host to sensor...
authorStefan Herbrechtsmeier <hbmeier@hni.uni-paderborn.de>
Thu, 14 Aug 2008 15:04:11 +0000 (12:04 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Sun, 12 Oct 2008 11:36:50 +0000 (09:36 -0200)
Make .power and .reset callbacks per camera instead of per host, also move
their invocation to camera drivers.

.arch/arm/mach-pxa/include/mach/camera.h    |    2 -

Signed-off-by: Stefan Herbrechtsmeier <hbmeier@hni.uni-paderborn.de>
Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
arch/arm/mach-pxa/include/mach/camera.h
drivers/media/video/mt9m001.c
drivers/media/video/mt9m111.c
drivers/media/video/mt9v022.c
drivers/media/video/pxa_camera.c
drivers/media/video/sh_mobile_ceu_camera.c
include/media/sh_mobile_ceu.h
include/media/soc_camera.h

index 39516ce..31abe6d 100644 (file)
@@ -36,8 +36,6 @@
 
 struct pxacamera_platform_data {
        int (*init)(struct device *);
-       int (*power)(struct device *, int);
-       int (*reset)(struct device *, int);
 
        unsigned long flags;
        unsigned long mclk_10khz;
index 3531f93..0c52437 100644 (file)
@@ -117,13 +117,33 @@ static int reg_clear(struct soc_camera_device *icd, const u8 reg,
 
 static int mt9m001_init(struct soc_camera_device *icd)
 {
+       struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd);
+       struct soc_camera_link *icl = mt9m001->client->dev.platform_data;
        int ret;
 
        dev_dbg(icd->vdev->parent, "%s\n", __func__);
 
-       ret = reg_write(icd, MT9M001_RESET, 1);
-       if (!ret)
-               ret = reg_write(icd, MT9M001_RESET, 0);
+       if (icl->power) {
+               ret = icl->power(&mt9m001->client->dev, 1);
+               if (ret < 0) {
+                       dev_err(icd->vdev->parent,
+                               "Platform failed to power-on the camera.\n");
+                       return ret;
+               }
+       }
+
+       /* The camera could have been already on, we reset it additionally */
+       if (icl->reset)
+               ret = icl->reset(&mt9m001->client->dev);
+       else
+               ret = -ENODEV;
+
+       if (ret < 0) {
+               /* Either no platform reset, or platform reset failed */
+               ret = reg_write(icd, MT9M001_RESET, 1);
+               if (!ret)
+                       ret = reg_write(icd, MT9M001_RESET, 0);
+       }
        /* Disable chip, synchronous option update */
        if (!ret)
                ret = reg_write(icd, MT9M001_OUTPUT_CONTROL, 0);
@@ -133,8 +153,15 @@ static int mt9m001_init(struct soc_camera_device *icd)
 
 static int mt9m001_release(struct soc_camera_device *icd)
 {
+       struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd);
+       struct soc_camera_link *icl = mt9m001->client->dev.platform_data;
+
        /* Disable the chip */
        reg_write(icd, MT9M001_OUTPUT_CONTROL, 0);
+
+       if (icl->power)
+               icl->power(&mt9m001->client->dev, 0);
+
        return 0;
 }
 
index d999326..4844486 100644 (file)
@@ -351,8 +351,18 @@ static int mt9m111_setfmt_yuv(struct soc_camera_device *icd)
 static int mt9m111_enable(struct soc_camera_device *icd)
 {
        struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
+       struct soc_camera_link *icl = mt9m111->client->dev.platform_data;
        int ret;
 
+       if (icl->power) {
+               ret = icl->power(&mt9m111->client->dev, 1);
+               if (ret < 0) {
+                       dev_err(icd->vdev->parent,
+                               "Platform failed to power-on the camera.\n");
+                       return ret;
+               }
+       }
+
        ret = reg_set(RESET, MT9M111_RESET_CHIP_ENABLE);
        if (!ret)
                mt9m111->powered = 1;
@@ -362,11 +372,16 @@ static int mt9m111_enable(struct soc_camera_device *icd)
 static int mt9m111_disable(struct soc_camera_device *icd)
 {
        struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
+       struct soc_camera_link *icl = mt9m111->client->dev.platform_data;
        int ret;
 
        ret = reg_clear(RESET, MT9M111_RESET_CHIP_ENABLE);
        if (!ret)
                mt9m111->powered = 0;
+
+       if (icl->power)
+               icl->power(&mt9m111->client->dev, 0);
+
        return ret;
 }
 
index 0f4b204..2584201 100644 (file)
@@ -134,8 +134,25 @@ static int reg_clear(struct soc_camera_device *icd, const u8 reg,
 static int mt9v022_init(struct soc_camera_device *icd)
 {
        struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd);
+       struct soc_camera_link *icl = mt9v022->client->dev.platform_data;
        int ret;
 
+       if (icl->power) {
+               ret = icl->power(&mt9v022->client->dev, 1);
+               if (ret < 0) {
+                       dev_err(icd->vdev->parent,
+                               "Platform failed to power-on the camera.\n");
+                       return ret;
+               }
+       }
+
+       /*
+        * The camera could have been already on, we hard-reset it additionally,
+        * if available. Soft reset is done in video_probe().
+        */
+       if (icl->reset)
+               icl->reset(&mt9v022->client->dev);
+
        /* Almost the default mode: master, parallel, simultaneous, and an
         * undocumented bit 0x200, which is present in table 7, but not in 8,
         * plus snapshot mode to disable scan for now */
@@ -161,7 +178,12 @@ static int mt9v022_init(struct soc_camera_device *icd)
 
 static int mt9v022_release(struct soc_camera_device *icd)
 {
-       /* Nothing? */
+       struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd);
+       struct soc_camera_link *icl = mt9v022->client->dev.platform_data;
+
+       if (icl->power)
+               icl->power(&mt9v022->client->dev, 0);
+
        return 0;
 }
 
index cf96b2c..14569b5 100644 (file)
@@ -629,17 +629,6 @@ static void pxa_camera_activate(struct pxa_camera_dev *pcdev)
                pdata->init(pcdev->dev);
        }
 
-       if (pdata && pdata->power) {
-               dev_dbg(pcdev->dev, "%s: Power on camera\n", __func__);
-               pdata->power(pcdev->dev, 1);
-       }
-
-       if (pdata && pdata->reset) {
-               dev_dbg(pcdev->dev, "%s: Releasing camera reset\n",
-                       __func__);
-               pdata->reset(pcdev->dev, 1);
-       }
-
        CICR0 = 0x3FF;   /* disable all interrupts */
 
        if (pcdev->platform_flags & PXA_CAMERA_PCLK_EN)
@@ -660,20 +649,7 @@ static void pxa_camera_activate(struct pxa_camera_dev *pcdev)
 
 static void pxa_camera_deactivate(struct pxa_camera_dev *pcdev)
 {
-       struct pxacamera_platform_data *board = pcdev->pdata;
-
        clk_disable(pcdev->clk);
-
-       if (board && board->reset) {
-               dev_dbg(pcdev->dev, "%s: Asserting camera reset\n",
-                       __func__);
-               board->reset(pcdev->dev, 0);
-       }
-
-       if (board && board->power) {
-               dev_dbg(pcdev->dev, "%s: Power off camera\n", __func__);
-               board->power(pcdev->dev, 0);
-       }
 }
 
 static irqreturn_t pxa_camera_irq(int irq, void *data)
index 318754e..7683809 100644 (file)
@@ -304,9 +304,6 @@ static int sh_mobile_ceu_add_device(struct soc_camera_device *icd)
                 "SuperH Mobile CEU driver attached to camera %d\n",
                 icd->devnum);
 
-       if (pcdev->pdata->enable_camera)
-               pcdev->pdata->enable_camera();
-
        ret = icd->ops->init(icd);
        if (ret)
                goto err;
@@ -333,8 +330,6 @@ static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd)
        ceu_write(pcdev, CEIER, 0);
        ceu_write(pcdev, CAPSR, 1 << 16); /* reset */
        icd->ops->release(icd);
-       if (pcdev->pdata->disable_camera)
-               pcdev->pdata->disable_camera();
 
        dev_info(&icd->dev,
                 "SuperH Mobile CEU driver detached from camera %d\n",
index 234a471..b5dbefe 100644 (file)
@@ -5,8 +5,6 @@
 
 struct sh_mobile_ceu_info {
        unsigned long flags; /* SOCAM_... */
-       void (*enable_camera)(void);
-       void (*disable_camera)(void);
 };
 
 #endif /* __ASM_SH_MOBILE_CEU_H__ */
index d548de3..c5de7bb 100644 (file)
@@ -83,6 +83,9 @@ struct soc_camera_link {
        int bus_id;
        /* GPIO number to switch between 8 and 10 bit modes */
        unsigned int gpio;
+       /* Optional callbacks to power on or off and reset the sensor */
+       int (*power)(struct device *, int);
+       int (*reset)(struct device *);
 };
 
 static inline struct soc_camera_device *to_soc_camera_dev(struct device *dev)