aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuennadi Liakhovetski <g.liakhovetski@gmx.de>2009-08-25 10:06:21 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-09-18 23:18:24 -0400
commitc41debafc6e396a8e15f1f017aec7c0cf67e1b54 (patch)
tree4f128d3acb39deab3eb9f8ab1a9681fc07148432
parent2639ead140aa7063188b6599a1a7398d60db2712 (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.c43
-rw-r--r--drivers/media/video/soc_camera.c61
-rw-r--r--include/media/soc_camera.h6
-rw-r--r--include/media/soc_camera_platform.h2
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
313static int ap325rxa_camera_add(struct soc_camera_link *icl, struct device *dev);
314static void ap325rxa_camera_del(struct soc_camera_link *icl);
315
313static struct soc_camera_platform_info camera_info = { 316static 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
328static struct platform_device camera_device = { 335static struct platform_device camera_device = {
@@ -332,15 +339,20 @@ static struct platform_device camera_device = {
332 }, 339 },
333}; 340};
334 341
335static int __init camera_setup(void) 342static 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}
342late_initcall(camera_setup);
343 350
351static 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
346static int ov7725_power(struct device *dev, int mode) 358static 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
426static struct platform_device ap325rxa_camera = { 438static 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
444static struct spi_board_info ap325rxa_spi_devices[] = { 465static 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}
1166EXPORT_SYMBOL(soc_camera_video_stop); 1166EXPORT_SYMBOL(soc_camera_video_stop);
1167 1167
1168static int __devinit soc_camera_pdrv_probe(struct platform_device *pdev) 1168#ifdef CONFIG_I2C_BOARDINFO
1169static 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;
1193ei2cnd:
1194 i2c_put_adapter(adap);
1195ei2cga:
1196 return ret;
1195} 1197}
1196 1198
1197static int __devexit soc_camera_pdrv_remove(struct platform_device *pdev) 1199static 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
1214static 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
1230static 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
16struct soc_camera_platform_info { 17struct 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__ */