diff options
author | Stefan Herbrechtsmeier <hbmeier@hni.uni-paderborn.de> | 2008-08-14 11:04:11 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2008-10-12 07:36:50 -0400 |
commit | 81034663159f39d005316b5c139038459cd16721 (patch) | |
tree | 8a86bc69b553bb2cb7656465b7449565427b197d | |
parent | 506c629a8eb95a3232a0aafa3b80903224ccc461 (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.h | 2 | ||||
-rw-r--r-- | drivers/media/video/mt9m001.c | 33 | ||||
-rw-r--r-- | drivers/media/video/mt9m111.c | 15 | ||||
-rw-r--r-- | drivers/media/video/mt9v022.c | 24 | ||||
-rw-r--r-- | drivers/media/video/pxa_camera.c | 24 | ||||
-rw-r--r-- | drivers/media/video/sh_mobile_ceu_camera.c | 5 | ||||
-rw-r--r-- | include/media/sh_mobile_ceu.h | 2 | ||||
-rw-r--r-- | include/media/soc_camera.h | 3 |
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 | ||
37 | struct pxacamera_platform_data { | 37 | struct 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 | ||
118 | static int mt9m001_init(struct soc_camera_device *icd) | 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 | 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 | ||
134 | static int mt9m001_release(struct soc_camera_device *icd) | 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 | /* 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) | |||
351 | static int mt9m111_enable(struct soc_camera_device *icd) | 351 | static 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) | |||
362 | static int mt9m111_disable(struct soc_camera_device *icd) | 372 | static 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, | |||
134 | static int mt9v022_init(struct soc_camera_device *icd) | 134 | static 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 | ||
162 | static int mt9v022_release(struct soc_camera_device *icd) | 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 | 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 | ||
661 | static void pxa_camera_deactivate(struct pxa_camera_dev *pcdev) | 650 | static 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 | ||
679 | static irqreturn_t pxa_camera_irq(int irq, void *data) | 655 | static 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 | ||
6 | struct sh_mobile_ceu_info { | 6 | struct 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 | ||
88 | static inline struct soc_camera_device *to_soc_camera_dev(struct device *dev) | 91 | static inline struct soc_camera_device *to_soc_camera_dev(struct device *dev) |