aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Herbrechtsmeier <hbmeier@hni.uni-paderborn.de>2008-08-14 11:04:11 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2008-10-12 07:36:50 -0400
commit81034663159f39d005316b5c139038459cd16721 (patch)
tree8a86bc69b553bb2cb7656465b7449565427b197d
parent506c629a8eb95a3232a0aafa3b80903224ccc461 (diff)
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>
-rw-r--r--arch/arm/mach-pxa/include/mach/camera.h2
-rw-r--r--drivers/media/video/mt9m001.c33
-rw-r--r--drivers/media/video/mt9m111.c15
-rw-r--r--drivers/media/video/mt9v022.c24
-rw-r--r--drivers/media/video/pxa_camera.c24
-rw-r--r--drivers/media/video/sh_mobile_ceu_camera.c5
-rw-r--r--include/media/sh_mobile_ceu.h2
-rw-r--r--include/media/soc_camera.h3
8 files changed, 71 insertions, 37 deletions
diff --git a/arch/arm/mach-pxa/include/mach/camera.h b/arch/arm/mach-pxa/include/mach/camera.h
index 39516ced8b1f..31abe6d514b8 100644
--- a/arch/arm/mach-pxa/include/mach/camera.h
+++ b/arch/arm/mach-pxa/include/mach/camera.h
@@ -36,8 +36,6 @@
36 36
37struct pxacamera_platform_data { 37struct pxacamera_platform_data {
38 int (*init)(struct device *); 38 int (*init)(struct device *);
39 int (*power)(struct device *, int);
40 int (*reset)(struct device *, int);
41 39
42 unsigned long flags; 40 unsigned long flags;
43 unsigned long mclk_10khz; 41 unsigned long mclk_10khz;
diff --git a/drivers/media/video/mt9m001.c b/drivers/media/video/mt9m001.c
index 3531f9352dff..0c524376b67e 100644
--- a/drivers/media/video/mt9m001.c
+++ b/drivers/media/video/mt9m001.c
@@ -117,13 +117,33 @@ static int reg_clear(struct soc_camera_device *icd, const u8 reg,
117 117
118static int mt9m001_init(struct soc_camera_device *icd) 118static 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 int ret; 122 int ret;
121 123
122 dev_dbg(icd->vdev->parent, "%s\n", __func__); 124 dev_dbg(icd->vdev->parent, "%s\n", __func__);
123 125
124 ret = reg_write(icd, MT9M001_RESET, 1); 126 if (icl->power) {
125 if (!ret) 127 ret = icl->power(&mt9m001->client->dev, 1);
126 ret = reg_write(icd, MT9M001_RESET, 0); 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 /* Disable chip, synchronous option update */ 147 /* Disable chip, synchronous option update */
128 if (!ret) 148 if (!ret)
129 ret = reg_write(icd, MT9M001_OUTPUT_CONTROL, 0); 149 ret = reg_write(icd, MT9M001_OUTPUT_CONTROL, 0);
@@ -133,8 +153,15 @@ static int mt9m001_init(struct soc_camera_device *icd)
133 153
134static int mt9m001_release(struct soc_camera_device *icd) 154static 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 /* Disable the chip */ 159 /* Disable the chip */
137 reg_write(icd, MT9M001_OUTPUT_CONTROL, 0); 160 reg_write(icd, MT9M001_OUTPUT_CONTROL, 0);
161
162 if (icl->power)
163 icl->power(&mt9m001->client->dev, 0);
164
138 return 0; 165 return 0;
139} 166}
140 167
diff --git a/drivers/media/video/mt9m111.c b/drivers/media/video/mt9m111.c
index d99932631050..4844486d72fb 100644
--- a/drivers/media/video/mt9m111.c
+++ b/drivers/media/video/mt9m111.c
@@ -351,8 +351,18 @@ static int mt9m111_setfmt_yuv(struct soc_camera_device *icd)
351static int mt9m111_enable(struct soc_camera_device *icd) 351static int mt9m111_enable(struct soc_camera_device *icd)
352{ 352{
353 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); 353 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
354 struct soc_camera_link *icl = mt9m111->client->dev.platform_data;
354 int ret; 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 ret = reg_set(RESET, MT9M111_RESET_CHIP_ENABLE); 366 ret = reg_set(RESET, MT9M111_RESET_CHIP_ENABLE);
357 if (!ret) 367 if (!ret)
358 mt9m111->powered = 1; 368 mt9m111->powered = 1;
@@ -362,11 +372,16 @@ static int mt9m111_enable(struct soc_camera_device *icd)
362static int mt9m111_disable(struct soc_camera_device *icd) 372static int mt9m111_disable(struct soc_camera_device *icd)
363{ 373{
364 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); 374 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
375 struct soc_camera_link *icl = mt9m111->client->dev.platform_data;
365 int ret; 376 int ret;
366 377
367 ret = reg_clear(RESET, MT9M111_RESET_CHIP_ENABLE); 378 ret = reg_clear(RESET, MT9M111_RESET_CHIP_ENABLE);
368 if (!ret) 379 if (!ret)
369 mt9m111->powered = 0; 380 mt9m111->powered = 0;
381
382 if (icl->power)
383 icl->power(&mt9m111->client->dev, 0);
384
370 return ret; 385 return ret;
371} 386}
372 387
diff --git a/drivers/media/video/mt9v022.c b/drivers/media/video/mt9v022.c
index 0f4b204667e0..2584201059d8 100644
--- a/drivers/media/video/mt9v022.c
+++ b/drivers/media/video/mt9v022.c
@@ -134,8 +134,25 @@ static int reg_clear(struct soc_camera_device *icd, const u8 reg,
134static int mt9v022_init(struct soc_camera_device *icd) 134static int mt9v022_init(struct soc_camera_device *icd)
135{ 135{
136 struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); 136 struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd);
137 struct soc_camera_link *icl = mt9v022->client->dev.platform_data;
137 int ret; 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 /* Almost the default mode: master, parallel, simultaneous, and an 156 /* Almost the default mode: master, parallel, simultaneous, and an
140 * undocumented bit 0x200, which is present in table 7, but not in 8, 157 * undocumented bit 0x200, which is present in table 7, but not in 8,
141 * plus snapshot mode to disable scan for now */ 158 * plus snapshot mode to disable scan for now */
@@ -161,7 +178,12 @@ static int mt9v022_init(struct soc_camera_device *icd)
161 178
162static int mt9v022_release(struct soc_camera_device *icd) 179static 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 return 0; 187 return 0;
166} 188}
167 189
diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c
index cf96b2cc4f1c..14569b591388 100644
--- a/drivers/media/video/pxa_camera.c
+++ b/drivers/media/video/pxa_camera.c
@@ -629,17 +629,6 @@ static void pxa_camera_activate(struct pxa_camera_dev *pcdev)
629 pdata->init(pcdev->dev); 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 CICR0 = 0x3FF; /* disable all interrupts */ 632 CICR0 = 0x3FF; /* disable all interrupts */
644 633
645 if (pcdev->platform_flags & PXA_CAMERA_PCLK_EN) 634 if (pcdev->platform_flags & PXA_CAMERA_PCLK_EN)
@@ -660,20 +649,7 @@ static void pxa_camera_activate(struct pxa_camera_dev *pcdev)
660 649
661static void pxa_camera_deactivate(struct pxa_camera_dev *pcdev) 650static void pxa_camera_deactivate(struct pxa_camera_dev *pcdev)
662{ 651{
663 struct pxacamera_platform_data *board = pcdev->pdata;
664
665 clk_disable(pcdev->clk); 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
679static irqreturn_t pxa_camera_irq(int irq, void *data) 655static irqreturn_t pxa_camera_irq(int irq, void *data)
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c
index 318754e73132..76838091dc66 100644
--- a/drivers/media/video/sh_mobile_ceu_camera.c
+++ b/drivers/media/video/sh_mobile_ceu_camera.c
@@ -304,9 +304,6 @@ static int sh_mobile_ceu_add_device(struct soc_camera_device *icd)
304 "SuperH Mobile CEU driver attached to camera %d\n", 304 "SuperH Mobile CEU driver attached to camera %d\n",
305 icd->devnum); 305 icd->devnum);
306 306
307 if (pcdev->pdata->enable_camera)
308 pcdev->pdata->enable_camera();
309
310 ret = icd->ops->init(icd); 307 ret = icd->ops->init(icd);
311 if (ret) 308 if (ret)
312 goto err; 309 goto err;
@@ -333,8 +330,6 @@ static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd)
333 ceu_write(pcdev, CEIER, 0); 330 ceu_write(pcdev, CEIER, 0);
334 ceu_write(pcdev, CAPSR, 1 << 16); /* reset */ 331 ceu_write(pcdev, CAPSR, 1 << 16); /* reset */
335 icd->ops->release(icd); 332 icd->ops->release(icd);
336 if (pcdev->pdata->disable_camera)
337 pcdev->pdata->disable_camera();
338 333
339 dev_info(&icd->dev, 334 dev_info(&icd->dev,
340 "SuperH Mobile CEU driver detached from camera %d\n", 335 "SuperH Mobile CEU driver detached from camera %d\n",
diff --git a/include/media/sh_mobile_ceu.h b/include/media/sh_mobile_ceu.h
index 234a4711d2ec..b5dbefea3740 100644
--- a/include/media/sh_mobile_ceu.h
+++ b/include/media/sh_mobile_ceu.h
@@ -5,8 +5,6 @@
5 5
6struct sh_mobile_ceu_info { 6struct sh_mobile_ceu_info {
7 unsigned long flags; /* SOCAM_... */ 7 unsigned long flags; /* SOCAM_... */
8 void (*enable_camera)(void);
9 void (*disable_camera)(void);
10}; 8};
11 9
12#endif /* __ASM_SH_MOBILE_CEU_H__ */ 10#endif /* __ASM_SH_MOBILE_CEU_H__ */
diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h
index d548de326722..c5de7bb19fda 100644
--- a/include/media/soc_camera.h
+++ b/include/media/soc_camera.h
@@ -83,6 +83,9 @@ struct soc_camera_link {
83 int bus_id; 83 int bus_id;
84 /* GPIO number to switch between 8 and 10 bit modes */ 84 /* GPIO number to switch between 8 and 10 bit modes */
85 unsigned int gpio; 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
88static inline struct soc_camera_device *to_soc_camera_dev(struct device *dev) 91static inline struct soc_camera_device *to_soc_camera_dev(struct device *dev)