Commit 81034663159f39d005316b5c139038459cd16721

Authored by Stefan Herbrechtsmeier
Committed by Mauro Carvalho Chehab
1 parent 506c629a8e

V4L/DVB (8687): soc-camera: Move .power and .reset from soc_camera host to sensor driver

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>

Showing 8 changed files with 71 additions and 37 deletions Side-by-side Diff

arch/arm/mach-pxa/include/mach/camera.h
... ... @@ -36,8 +36,6 @@
36 36  
37 37 struct pxacamera_platform_data {
38 38 int (*init)(struct device *);
39   - int (*power)(struct device *, int);
40   - int (*reset)(struct device *, int);
41 39  
42 40 unsigned long flags;
43 41 unsigned long mclk_10khz;
drivers/media/video/mt9m001.c
... ... @@ -117,13 +117,33 @@
117 117  
118 118 static int mt9m001_init(struct soc_camera_device *icd)
119 119 {
  120 + struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd);
  121 + struct soc_camera_link *icl = mt9m001->client->dev.platform_data;
120 122 int ret;
121 123  
122 124 dev_dbg(icd->vdev->parent, "%s\n", __func__);
123 125  
124   - ret = reg_write(icd, MT9M001_RESET, 1);
125   - if (!ret)
126   - ret = reg_write(icd, MT9M001_RESET, 0);
  126 + if (icl->power) {
  127 + ret = icl->power(&mt9m001->client->dev, 1);
  128 + if (ret < 0) {
  129 + dev_err(icd->vdev->parent,
  130 + "Platform failed to power-on the camera.\n");
  131 + return ret;
  132 + }
  133 + }
  134 +
  135 + /* The camera could have been already on, we reset it additionally */
  136 + if (icl->reset)
  137 + ret = icl->reset(&mt9m001->client->dev);
  138 + else
  139 + ret = -ENODEV;
  140 +
  141 + if (ret < 0) {
  142 + /* Either no platform reset, or platform reset failed */
  143 + ret = reg_write(icd, MT9M001_RESET, 1);
  144 + if (!ret)
  145 + ret = reg_write(icd, MT9M001_RESET, 0);
  146 + }
127 147 /* Disable chip, synchronous option update */
128 148 if (!ret)
129 149 ret = reg_write(icd, MT9M001_OUTPUT_CONTROL, 0);
130 150  
... ... @@ -133,8 +153,15 @@
133 153  
134 154 static int mt9m001_release(struct soc_camera_device *icd)
135 155 {
  156 + struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd);
  157 + struct soc_camera_link *icl = mt9m001->client->dev.platform_data;
  158 +
136 159 /* Disable the chip */
137 160 reg_write(icd, MT9M001_OUTPUT_CONTROL, 0);
  161 +
  162 + if (icl->power)
  163 + icl->power(&mt9m001->client->dev, 0);
  164 +
138 165 return 0;
139 166 }
140 167  
drivers/media/video/mt9m111.c
... ... @@ -351,8 +351,18 @@
351 351 static int mt9m111_enable(struct soc_camera_device *icd)
352 352 {
353 353 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
  354 + struct soc_camera_link *icl = mt9m111->client->dev.platform_data;
354 355 int ret;
355 356  
  357 + if (icl->power) {
  358 + ret = icl->power(&mt9m111->client->dev, 1);
  359 + if (ret < 0) {
  360 + dev_err(icd->vdev->parent,
  361 + "Platform failed to power-on the camera.\n");
  362 + return ret;
  363 + }
  364 + }
  365 +
356 366 ret = reg_set(RESET, MT9M111_RESET_CHIP_ENABLE);
357 367 if (!ret)
358 368 mt9m111->powered = 1;
359 369  
... ... @@ -362,11 +372,16 @@
362 372 static int mt9m111_disable(struct soc_camera_device *icd)
363 373 {
364 374 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
  375 + struct soc_camera_link *icl = mt9m111->client->dev.platform_data;
365 376 int ret;
366 377  
367 378 ret = reg_clear(RESET, MT9M111_RESET_CHIP_ENABLE);
368 379 if (!ret)
369 380 mt9m111->powered = 0;
  381 +
  382 + if (icl->power)
  383 + icl->power(&mt9m111->client->dev, 0);
  384 +
370 385 return ret;
371 386 }
372 387  
drivers/media/video/mt9v022.c
... ... @@ -134,8 +134,25 @@
134 134 static int mt9v022_init(struct soc_camera_device *icd)
135 135 {
136 136 struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd);
  137 + struct soc_camera_link *icl = mt9v022->client->dev.platform_data;
137 138 int ret;
138 139  
  140 + if (icl->power) {
  141 + ret = icl->power(&mt9v022->client->dev, 1);
  142 + if (ret < 0) {
  143 + dev_err(icd->vdev->parent,
  144 + "Platform failed to power-on the camera.\n");
  145 + return ret;
  146 + }
  147 + }
  148 +
  149 + /*
  150 + * The camera could have been already on, we hard-reset it additionally,
  151 + * if available. Soft reset is done in video_probe().
  152 + */
  153 + if (icl->reset)
  154 + icl->reset(&mt9v022->client->dev);
  155 +
139 156 /* Almost the default mode: master, parallel, simultaneous, and an
140 157 * undocumented bit 0x200, which is present in table 7, but not in 8,
141 158 * plus snapshot mode to disable scan for now */
... ... @@ -161,7 +178,12 @@
161 178  
162 179 static int mt9v022_release(struct soc_camera_device *icd)
163 180 {
164   - /* Nothing? */
  181 + struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd);
  182 + struct soc_camera_link *icl = mt9v022->client->dev.platform_data;
  183 +
  184 + if (icl->power)
  185 + icl->power(&mt9v022->client->dev, 0);
  186 +
165 187 return 0;
166 188 }
167 189  
drivers/media/video/pxa_camera.c
... ... @@ -629,17 +629,6 @@
629 629 pdata->init(pcdev->dev);
630 630 }
631 631  
632   - if (pdata && pdata->power) {
633   - dev_dbg(pcdev->dev, "%s: Power on camera\n", __func__);
634   - pdata->power(pcdev->dev, 1);
635   - }
636   -
637   - if (pdata && pdata->reset) {
638   - dev_dbg(pcdev->dev, "%s: Releasing camera reset\n",
639   - __func__);
640   - pdata->reset(pcdev->dev, 1);
641   - }
642   -
643 632 CICR0 = 0x3FF; /* disable all interrupts */
644 633  
645 634 if (pcdev->platform_flags & PXA_CAMERA_PCLK_EN)
646 635  
... ... @@ -660,20 +649,7 @@
660 649  
661 650 static void pxa_camera_deactivate(struct pxa_camera_dev *pcdev)
662 651 {
663   - struct pxacamera_platform_data *board = pcdev->pdata;
664   -
665 652 clk_disable(pcdev->clk);
666   -
667   - if (board && board->reset) {
668   - dev_dbg(pcdev->dev, "%s: Asserting camera reset\n",
669   - __func__);
670   - board->reset(pcdev->dev, 0);
671   - }
672   -
673   - if (board && board->power) {
674   - dev_dbg(pcdev->dev, "%s: Power off camera\n", __func__);
675   - board->power(pcdev->dev, 0);
676   - }
677 653 }
678 654  
679 655 static irqreturn_t pxa_camera_irq(int irq, void *data)
drivers/media/video/sh_mobile_ceu_camera.c
... ... @@ -304,9 +304,6 @@
304 304 "SuperH Mobile CEU driver attached to camera %d\n",
305 305 icd->devnum);
306 306  
307   - if (pcdev->pdata->enable_camera)
308   - pcdev->pdata->enable_camera();
309   -
310 307 ret = icd->ops->init(icd);
311 308 if (ret)
312 309 goto err;
... ... @@ -333,8 +330,6 @@
333 330 ceu_write(pcdev, CEIER, 0);
334 331 ceu_write(pcdev, CAPSR, 1 << 16); /* reset */
335 332 icd->ops->release(icd);
336   - if (pcdev->pdata->disable_camera)
337   - pcdev->pdata->disable_camera();
338 333  
339 334 dev_info(&icd->dev,
340 335 "SuperH Mobile CEU driver detached from camera %d\n",
include/media/sh_mobile_ceu.h
... ... @@ -5,8 +5,6 @@
5 5  
6 6 struct sh_mobile_ceu_info {
7 7 unsigned long flags; /* SOCAM_... */
8   - void (*enable_camera)(void);
9   - void (*disable_camera)(void);
10 8 };
11 9  
12 10 #endif /* __ASM_SH_MOBILE_CEU_H__ */
include/media/soc_camera.h
... ... @@ -83,6 +83,9 @@
83 83 int bus_id;
84 84 /* GPIO number to switch between 8 and 10 bit modes */
85 85 unsigned int gpio;
  86 + /* Optional callbacks to power on or off and reset the sensor */
  87 + int (*power)(struct device *, int);
  88 + int (*reset)(struct device *);
86 89 };
87 90  
88 91 static inline struct soc_camera_device *to_soc_camera_dev(struct device *dev)