From aea41520a95b61491620e5702c8322a8fcfbf12e Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Tue, 25 Aug 2009 16:06:21 +0200 Subject: soc-camera: prepare soc_camera_platform.c and its users for conversion From: Guennadi Liakhovetski 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. Signed-off-by: Guennadi Liakhovetski Cc: Paul Mundt Acked-by: Paul Mundt Priority: low --- arch/sh/boards/board-ap325rxa.c | 43 ++++++++++++++++++------ drivers/media/video/soc_camera.c | 61 ++++++++++++++++++++++++++-------- include/media/soc_camera.h | 6 +++ include/media/soc_camera_platform.h | 2 + 4 files changed, 86 insertions(+), 26 deletions(-) --- linux/drivers/media/video/soc_camera.c | 61 +++++++++++++++++++++++++--------- 1 file changed, 46 insertions(+), 15 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/soc_camera.c b/linux/drivers/media/video/soc_camera.c index 4f315c1b7..8de620b78 100644 --- a/linux/drivers/media/video/soc_camera.c +++ b/linux/drivers/media/video/soc_camera.c @@ -1166,45 +1166,76 @@ void soc_camera_video_stop(struct soc_camera_device *icd) } EXPORT_SYMBOL(soc_camera_video_stop); -static int __devinit soc_camera_pdrv_probe(struct platform_device *pdev) +#ifdef CONFIG_I2C_BOARDINFO +static int soc_camera_init_i2c(struct platform_device *pdev, + struct soc_camera_link *icl) { - struct soc_camera_link *icl = pdev->dev.platform_data; - struct i2c_adapter *adap; struct i2c_client *client; + struct i2c_adapter *adap = i2c_get_adapter(icl->i2c_adapter_id); + int ret; - if (!icl) - return -EINVAL; - - adap = i2c_get_adapter(icl->i2c_adapter_id); if (!adap) { - dev_warn(&pdev->dev, "Cannot get adapter #%d. No driver?\n", - icl->i2c_adapter_id); - /* -ENODEV and -ENXIO do not produce an error on probe()... */ - return -ENOENT; + ret = -ENODEV; + dev_err(&pdev->dev, "Cannot get adapter #%d. No driver?\n", + icl->i2c_adapter_id); + goto ei2cga; } icl->board_info->platform_data = icl; client = i2c_new_device(adap, icl->board_info); if (!client) { - i2c_put_adapter(adap); - return -ENOMEM; + ret = -ENOMEM; + goto ei2cnd; } platform_set_drvdata(pdev, client); return 0; +ei2cnd: + i2c_put_adapter(adap); +ei2cga: + return ret; } -static int __devexit soc_camera_pdrv_remove(struct platform_device *pdev) +static void soc_camera_free_i2c(struct platform_device *pdev) { struct i2c_client *client = platform_get_drvdata(pdev); if (!client) - return -ENODEV; + return; i2c_unregister_device(client); i2c_put_adapter(client->adapter); +} +#else +#define soc_camera_init_i2c(d, icl) (-ENODEV) +#define soc_camera_free_i2c(d) do {} while (0) +#endif +static int __devinit soc_camera_pdrv_probe(struct platform_device *pdev) +{ + struct soc_camera_link *icl = pdev->dev.platform_data; + + if (!icl) + return -EINVAL; + + if (icl->board_info) + return soc_camera_init_i2c(pdev, icl); + else if (!icl->add_device || !icl->del_device) + return -EINVAL; + + /* &pdev->dev will become &icd->dev */ + return icl->add_device(icl, &pdev->dev); +} + +static int __devexit soc_camera_pdrv_remove(struct platform_device *pdev) +{ + struct soc_camera_link *icl = pdev->dev.platform_data; + + if (icl->board_info) + soc_camera_free_i2c(pdev); + else + icl->del_device(icl); return 0; } -- cgit v1.2.3