diff options
author | Guennadi Liakhovetski <g.liakhovetski@gmx.de> | 2009-08-25 10:06:21 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-09-18 23:18:24 -0400 |
commit | c41debafc6e396a8e15f1f017aec7c0cf67e1b54 (patch) | |
tree | 4f128d3acb39deab3eb9f8ab1a9681fc07148432 | |
parent | 2639ead140aa7063188b6599a1a7398d60db2712 (diff) |
V4L/DVB (12504): soc-camera: prepare soc_camera_platform.c and its users for conversion
soc_camera_platform.c is only used by y SuperH ap325rxa board. This patch
converts soc_camera_platform.c and its users for the soc-camera platform-
device conversion and also extends soc-camera core to handle non-I2C cameras.
Cc: Paul Mundt <lethal@linux-sh.org>
Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Acked-by: Paul Mundt <lethal@linux-sh.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r-- | arch/sh/boards/board-ap325rxa.c | 43 | ||||
-rw-r--r-- | drivers/media/video/soc_camera.c | 61 | ||||
-rw-r--r-- | include/media/soc_camera.h | 6 | ||||
-rw-r--r-- | include/media/soc_camera_platform.h | 2 |
4 files changed, 86 insertions, 26 deletions
diff --git a/arch/sh/boards/board-ap325rxa.c b/arch/sh/boards/board-ap325rxa.c index 327d47c25a57..7e2d2de0384d 100644 --- a/arch/sh/boards/board-ap325rxa.c +++ b/arch/sh/boards/board-ap325rxa.c | |||
@@ -310,6 +310,9 @@ static int camera_set_capture(struct soc_camera_platform_info *info, | |||
310 | return ret; | 310 | return ret; |
311 | } | 311 | } |
312 | 312 | ||
313 | static int ap325rxa_camera_add(struct soc_camera_link *icl, struct device *dev); | ||
314 | static void ap325rxa_camera_del(struct soc_camera_link *icl); | ||
315 | |||
313 | static struct soc_camera_platform_info camera_info = { | 316 | static struct soc_camera_platform_info camera_info = { |
314 | .iface = 0, | 317 | .iface = 0, |
315 | .format_name = "UYVY", | 318 | .format_name = "UYVY", |
@@ -323,6 +326,10 @@ static struct soc_camera_platform_info camera_info = { | |||
323 | .bus_param = SOCAM_PCLK_SAMPLE_RISING | SOCAM_HSYNC_ACTIVE_HIGH | | 326 | .bus_param = SOCAM_PCLK_SAMPLE_RISING | SOCAM_HSYNC_ACTIVE_HIGH | |
324 | SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_MASTER | SOCAM_DATAWIDTH_8, | 327 | SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_MASTER | SOCAM_DATAWIDTH_8, |
325 | .set_capture = camera_set_capture, | 328 | .set_capture = camera_set_capture, |
329 | .link = { | ||
330 | .add_device = ap325rxa_camera_add, | ||
331 | .del_device = ap325rxa_camera_del, | ||
332 | }, | ||
326 | }; | 333 | }; |
327 | 334 | ||
328 | static struct platform_device camera_device = { | 335 | static struct platform_device camera_device = { |
@@ -332,15 +339,20 @@ static struct platform_device camera_device = { | |||
332 | }, | 339 | }, |
333 | }; | 340 | }; |
334 | 341 | ||
335 | static int __init camera_setup(void) | 342 | static int ap325rxa_camera_add(struct soc_camera_link *icl, |
343 | struct device *dev) | ||
336 | { | 344 | { |
337 | if (camera_probe() > 0) | 345 | if (icl != &camera_info.link || camera_probe() <= 0) |
338 | platform_device_register(&camera_device); | 346 | return -ENODEV; |
339 | 347 | ||
340 | return 0; | 348 | return platform_device_register(&camera_device); |
341 | } | 349 | } |
342 | late_initcall(camera_setup); | ||
343 | 350 | ||
351 | static void ap325rxa_camera_del(struct soc_camera_link *icl) | ||
352 | { | ||
353 | if (icl == &camera_info.link) | ||
354 | platform_device_unregister(&camera_device); | ||
355 | } | ||
344 | #endif /* CONFIG_I2C */ | 356 | #endif /* CONFIG_I2C */ |
345 | 357 | ||
346 | static int ov7725_power(struct device *dev, int mode) | 358 | static int ov7725_power(struct device *dev, int mode) |
@@ -423,11 +435,19 @@ static struct ov772x_camera_info ov7725_info = { | |||
423 | }, | 435 | }, |
424 | }; | 436 | }; |
425 | 437 | ||
426 | static struct platform_device ap325rxa_camera = { | 438 | static struct platform_device ap325rxa_camera[] = { |
427 | .name = "soc-camera-pdrv", | 439 | { |
428 | .id = 0, | 440 | .name = "soc-camera-pdrv", |
429 | .dev = { | 441 | .id = 0, |
430 | .platform_data = &ov7725_info.link, | 442 | .dev = { |
443 | .platform_data = &ov7725_info.link, | ||
444 | }, | ||
445 | }, { | ||
446 | .name = "soc-camera-pdrv", | ||
447 | .id = 1, | ||
448 | .dev = { | ||
449 | .platform_data = &camera_info.link, | ||
450 | }, | ||
431 | }, | 451 | }, |
432 | }; | 452 | }; |
433 | 453 | ||
@@ -438,7 +458,8 @@ static struct platform_device *ap325rxa_devices[] __initdata = { | |||
438 | &ceu_device, | 458 | &ceu_device, |
439 | &nand_flash_device, | 459 | &nand_flash_device, |
440 | &sdcard_cn3_device, | 460 | &sdcard_cn3_device, |
441 | &ap325rxa_camera, | 461 | &ap325rxa_camera[0], |
462 | &ap325rxa_camera[1], | ||
442 | }; | 463 | }; |
443 | 464 | ||
444 | static struct spi_board_info ap325rxa_spi_devices[] = { | 465 | static struct spi_board_info ap325rxa_spi_devices[] = { |
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c index 9f5ae8167855..0340754e5406 100644 --- a/drivers/media/video/soc_camera.c +++ b/drivers/media/video/soc_camera.c | |||
@@ -1165,45 +1165,76 @@ void soc_camera_video_stop(struct soc_camera_device *icd) | |||
1165 | } | 1165 | } |
1166 | EXPORT_SYMBOL(soc_camera_video_stop); | 1166 | EXPORT_SYMBOL(soc_camera_video_stop); |
1167 | 1167 | ||
1168 | static int __devinit soc_camera_pdrv_probe(struct platform_device *pdev) | 1168 | #ifdef CONFIG_I2C_BOARDINFO |
1169 | static int soc_camera_init_i2c(struct platform_device *pdev, | ||
1170 | struct soc_camera_link *icl) | ||
1169 | { | 1171 | { |
1170 | struct soc_camera_link *icl = pdev->dev.platform_data; | ||
1171 | struct i2c_adapter *adap; | ||
1172 | struct i2c_client *client; | 1172 | struct i2c_client *client; |
1173 | struct i2c_adapter *adap = i2c_get_adapter(icl->i2c_adapter_id); | ||
1174 | int ret; | ||
1173 | 1175 | ||
1174 | if (!icl) | ||
1175 | return -EINVAL; | ||
1176 | |||
1177 | adap = i2c_get_adapter(icl->i2c_adapter_id); | ||
1178 | if (!adap) { | 1176 | if (!adap) { |
1179 | dev_warn(&pdev->dev, "Cannot get adapter #%d. No driver?\n", | 1177 | ret = -ENODEV; |
1180 | icl->i2c_adapter_id); | 1178 | dev_err(&pdev->dev, "Cannot get adapter #%d. No driver?\n", |
1181 | /* -ENODEV and -ENXIO do not produce an error on probe()... */ | 1179 | icl->i2c_adapter_id); |
1182 | return -ENOENT; | 1180 | goto ei2cga; |
1183 | } | 1181 | } |
1184 | 1182 | ||
1185 | icl->board_info->platform_data = icl; | 1183 | icl->board_info->platform_data = icl; |
1186 | client = i2c_new_device(adap, icl->board_info); | 1184 | client = i2c_new_device(adap, icl->board_info); |
1187 | if (!client) { | 1185 | if (!client) { |
1188 | i2c_put_adapter(adap); | 1186 | ret = -ENOMEM; |
1189 | return -ENOMEM; | 1187 | goto ei2cnd; |
1190 | } | 1188 | } |
1191 | 1189 | ||
1192 | platform_set_drvdata(pdev, client); | 1190 | platform_set_drvdata(pdev, client); |
1193 | 1191 | ||
1194 | return 0; | 1192 | return 0; |
1193 | ei2cnd: | ||
1194 | i2c_put_adapter(adap); | ||
1195 | ei2cga: | ||
1196 | return ret; | ||
1195 | } | 1197 | } |
1196 | 1198 | ||
1197 | static int __devexit soc_camera_pdrv_remove(struct platform_device *pdev) | 1199 | static void soc_camera_free_i2c(struct platform_device *pdev) |
1198 | { | 1200 | { |
1199 | struct i2c_client *client = platform_get_drvdata(pdev); | 1201 | struct i2c_client *client = platform_get_drvdata(pdev); |
1200 | 1202 | ||
1201 | if (!client) | 1203 | if (!client) |
1202 | return -ENODEV; | 1204 | return; |
1203 | 1205 | ||
1204 | i2c_unregister_device(client); | 1206 | i2c_unregister_device(client); |
1205 | i2c_put_adapter(client->adapter); | 1207 | i2c_put_adapter(client->adapter); |
1208 | } | ||
1209 | #else | ||
1210 | #define soc_camera_init_i2c(d, icl) (-ENODEV) | ||
1211 | #define soc_camera_free_i2c(d) do {} while (0) | ||
1212 | #endif | ||
1206 | 1213 | ||
1214 | static int __devinit soc_camera_pdrv_probe(struct platform_device *pdev) | ||
1215 | { | ||
1216 | struct soc_camera_link *icl = pdev->dev.platform_data; | ||
1217 | |||
1218 | if (!icl) | ||
1219 | return -EINVAL; | ||
1220 | |||
1221 | if (icl->board_info) | ||
1222 | return soc_camera_init_i2c(pdev, icl); | ||
1223 | else if (!icl->add_device || !icl->del_device) | ||
1224 | return -EINVAL; | ||
1225 | |||
1226 | /* &pdev->dev will become &icd->dev */ | ||
1227 | return icl->add_device(icl, &pdev->dev); | ||
1228 | } | ||
1229 | |||
1230 | static int __devexit soc_camera_pdrv_remove(struct platform_device *pdev) | ||
1231 | { | ||
1232 | struct soc_camera_link *icl = pdev->dev.platform_data; | ||
1233 | |||
1234 | if (icl->board_info) | ||
1235 | soc_camera_free_i2c(pdev); | ||
1236 | else | ||
1237 | icl->del_device(icl); | ||
1207 | return 0; | 1238 | return 0; |
1208 | } | 1239 | } |
1209 | 1240 | ||
diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h index 23ecead35e7a..813e12061daa 100644 --- a/include/media/soc_camera.h +++ b/include/media/soc_camera.h | |||
@@ -102,6 +102,12 @@ struct soc_camera_link { | |||
102 | int i2c_adapter_id; | 102 | int i2c_adapter_id; |
103 | struct i2c_board_info *board_info; | 103 | struct i2c_board_info *board_info; |
104 | const char *module_name; | 104 | const char *module_name; |
105 | /* | ||
106 | * For non-I2C devices platform platform has to provide methods to | ||
107 | * add a device to the system and to remove | ||
108 | */ | ||
109 | int (*add_device)(struct soc_camera_link *, struct device *); | ||
110 | void (*del_device)(struct soc_camera_link *); | ||
105 | /* Optional callbacks to power on or off and reset the sensor */ | 111 | /* Optional callbacks to power on or off and reset the sensor */ |
106 | int (*power)(struct device *, int); | 112 | int (*power)(struct device *, int); |
107 | int (*reset)(struct device *); | 113 | int (*reset)(struct device *); |
diff --git a/include/media/soc_camera_platform.h b/include/media/soc_camera_platform.h index 1d092b4678aa..af224deadb43 100644 --- a/include/media/soc_camera_platform.h +++ b/include/media/soc_camera_platform.h | |||
@@ -12,6 +12,7 @@ | |||
12 | #define __SOC_CAMERA_H__ | 12 | #define __SOC_CAMERA_H__ |
13 | 13 | ||
14 | #include <linux/videodev2.h> | 14 | #include <linux/videodev2.h> |
15 | #include <media/soc_camera.h> | ||
15 | 16 | ||
16 | struct soc_camera_platform_info { | 17 | struct soc_camera_platform_info { |
17 | int iface; | 18 | int iface; |
@@ -21,6 +22,7 @@ struct soc_camera_platform_info { | |||
21 | unsigned long bus_param; | 22 | unsigned long bus_param; |
22 | void (*power)(int); | 23 | void (*power)(int); |
23 | int (*set_capture)(struct soc_camera_platform_info *info, int enable); | 24 | int (*set_capture)(struct soc_camera_platform_info *info, int enable); |
25 | struct soc_camera_link link; | ||
24 | }; | 26 | }; |
25 | 27 | ||
26 | #endif /* __SOC_CAMERA_H__ */ | 28 | #endif /* __SOC_CAMERA_H__ */ |