Commit 048d6992 authored by Guennadi Liakhovetski's avatar Guennadi Liakhovetski Committed by Mauro Carvalho Chehab

V4L/DVB (12506): soc-camera: convert to platform device

Convert soc-camera core and all drivers to platform device API. We already
converted platforms to register a platform device for each soc-camera client,
now we remove the compatibility code and switch completely to the new scheme.
This is a preparatory step for the v4l2-subdev conversion.
Signed-off-by: default avatarGuennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 92455d2a
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -503,18 +503,19 @@ static int mx3_camera_add_device(struct soc_camera_device *icd) ...@@ -503,18 +503,19 @@ static int mx3_camera_add_device(struct soc_camera_device *icd)
mx3_camera_activate(mx3_cam, icd); mx3_camera_activate(mx3_cam, icd);
ret = icd->ops->init(icd); ret = icd->ops->init(icd);
if (ret < 0) { if (ret < 0)
clk_disable(mx3_cam->clk);
goto einit; goto einit;
}
mx3_cam->icd = icd; mx3_cam->icd = icd;
dev_info(&icd->dev, "MX3 Camera driver attached to camera %d\n",
icd->devnum);
return 0;
einit: einit:
clk_disable(mx3_cam->clk);
ebusy: ebusy:
if (!ret)
dev_info(&icd->dev, "MX3 Camera driver attached to camera %d\n",
icd->devnum);
return ret; return ret;
} }
...@@ -947,9 +948,10 @@ static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt) ...@@ -947,9 +948,10 @@ static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
camera_flags = icd->ops->query_bus_param(icd); camera_flags = icd->ops->query_bus_param(icd);
common_flags = soc_camera_bus_param_compatible(camera_flags, bus_flags); common_flags = soc_camera_bus_param_compatible(camera_flags, bus_flags);
dev_dbg(ici->dev, "Flags cam: 0x%lx host: 0x%lx common: 0x%lx\n",
camera_flags, bus_flags, common_flags);
if (!common_flags) { if (!common_flags) {
dev_dbg(ici->dev, "no common flags: camera %lx, host %lx\n", dev_dbg(ici->dev, "no common flags");
camera_flags, bus_flags);
return -EINVAL; return -EINVAL;
} }
...@@ -1002,8 +1004,11 @@ static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt) ...@@ -1002,8 +1004,11 @@ static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
SOCAM_DATAWIDTH_4; SOCAM_DATAWIDTH_4;
ret = icd->ops->set_bus_param(icd, common_flags); ret = icd->ops->set_bus_param(icd, common_flags);
if (ret < 0) if (ret < 0) {
dev_dbg(ici->dev, "camera set_bus_param(%lx) returned %d\n",
common_flags, ret);
return ret; return ret;
}
/* /*
* So far only gated clock mode is supported. Add a line * So far only gated clock mode is supported. Add a line
...@@ -1127,8 +1132,9 @@ static int __devinit mx3_camera_probe(struct platform_device *pdev) ...@@ -1127,8 +1132,9 @@ static int __devinit mx3_camera_probe(struct platform_device *pdev)
INIT_LIST_HEAD(&mx3_cam->capture); INIT_LIST_HEAD(&mx3_cam->capture);
spin_lock_init(&mx3_cam->lock); spin_lock_init(&mx3_cam->lock);
base = ioremap(res->start, res->end - res->start + 1); base = ioremap(res->start, resource_size(res));
if (!base) { if (!base) {
pr_err("Couldn't map %x@%x\n", resource_size(res), res->start);
err = -ENOMEM; err = -ENOMEM;
goto eioremap; goto eioremap;
} }
...@@ -1215,3 +1221,4 @@ module_exit(mx3_camera_exit); ...@@ -1215,3 +1221,4 @@ module_exit(mx3_camera_exit);
MODULE_DESCRIPTION("i.MX3x SoC Camera Host driver"); MODULE_DESCRIPTION("i.MX3x SoC Camera Host driver");
MODULE_AUTHOR("Guennadi Liakhovetski <lg@denx.de>"); MODULE_AUTHOR("Guennadi Liakhovetski <lg@denx.de>");
MODULE_LICENSE("GPL v2"); MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:" MX3_CAM_DRV_NAME);
This diff is collapsed.
...@@ -830,7 +830,8 @@ static void pxa_camera_init_videobuf(struct videobuf_queue *q, ...@@ -830,7 +830,8 @@ static void pxa_camera_init_videobuf(struct videobuf_queue *q,
sizeof(struct pxa_buffer), icd); sizeof(struct pxa_buffer), icd);
} }
static u32 mclk_get_divisor(struct pxa_camera_dev *pcdev) static u32 mclk_get_divisor(struct platform_device *pdev,
struct pxa_camera_dev *pcdev)
{ {
unsigned long mclk = pcdev->mclk; unsigned long mclk = pcdev->mclk;
u32 div; u32 div;
...@@ -842,7 +843,7 @@ static u32 mclk_get_divisor(struct pxa_camera_dev *pcdev) ...@@ -842,7 +843,7 @@ static u32 mclk_get_divisor(struct pxa_camera_dev *pcdev)
/* mclk <= ciclk / 4 (27.4.2) */ /* mclk <= ciclk / 4 (27.4.2) */
if (mclk > lcdclk / 4) { if (mclk > lcdclk / 4) {
mclk = lcdclk / 4; mclk = lcdclk / 4;
dev_warn(pcdev->soc_host.dev, "Limiting master clock to %lu\n", mclk); dev_warn(&pdev->dev, "Limiting master clock to %lu\n", mclk);
} }
/* We verify mclk != 0, so if anyone breaks it, here comes their Oops */ /* We verify mclk != 0, so if anyone breaks it, here comes their Oops */
...@@ -852,8 +853,8 @@ static u32 mclk_get_divisor(struct pxa_camera_dev *pcdev) ...@@ -852,8 +853,8 @@ static u32 mclk_get_divisor(struct pxa_camera_dev *pcdev)
if (pcdev->platform_flags & PXA_CAMERA_MCLK_EN) if (pcdev->platform_flags & PXA_CAMERA_MCLK_EN)
pcdev->mclk = lcdclk / (2 * (div + 1)); pcdev->mclk = lcdclk / (2 * (div + 1));
dev_dbg(pcdev->soc_host.dev, "LCD clock %luHz, target freq %luHz, " dev_dbg(&pdev->dev, "LCD clock %luHz, target freq %luHz, divisor %u\n",
"divisor %u\n", lcdclk, mclk, div); lcdclk, mclk, div);
return div; return div;
} }
...@@ -958,15 +959,20 @@ static int pxa_camera_add_device(struct soc_camera_device *icd) ...@@ -958,15 +959,20 @@ static int pxa_camera_add_device(struct soc_camera_device *icd)
goto ebusy; goto ebusy;
} }
dev_info(&icd->dev, "PXA Camera driver attached to camera %d\n",
icd->devnum);
pxa_camera_activate(pcdev); pxa_camera_activate(pcdev);
ret = icd->ops->init(icd); ret = icd->ops->init(icd);
if (ret < 0)
goto einit;
pcdev->icd = icd;
if (!ret) dev_info(&icd->dev, "PXA Camera driver attached to camera %d\n",
pcdev->icd = icd; icd->devnum);
return 0;
einit:
pxa_camera_deactivate(pcdev);
ebusy: ebusy:
return ret; return ret;
} }
...@@ -1575,8 +1581,7 @@ static int __devinit pxa_camera_probe(struct platform_device *pdev) ...@@ -1575,8 +1581,7 @@ static int __devinit pxa_camera_probe(struct platform_device *pdev)
pcdev->mclk = 20000000; pcdev->mclk = 20000000;
} }
pcdev->soc_host.dev = &pdev->dev; pcdev->mclk_divisor = mclk_get_divisor(pdev, pcdev);
pcdev->mclk_divisor = mclk_get_divisor(pcdev);
INIT_LIST_HEAD(&pcdev->capture); INIT_LIST_HEAD(&pcdev->capture);
spin_lock_init(&pcdev->lock); spin_lock_init(&pcdev->lock);
...@@ -1641,6 +1646,7 @@ static int __devinit pxa_camera_probe(struct platform_device *pdev) ...@@ -1641,6 +1646,7 @@ static int __devinit pxa_camera_probe(struct platform_device *pdev)
pcdev->soc_host.drv_name = PXA_CAM_DRV_NAME; pcdev->soc_host.drv_name = PXA_CAM_DRV_NAME;
pcdev->soc_host.ops = &pxa_soc_camera_host_ops; pcdev->soc_host.ops = &pxa_soc_camera_host_ops;
pcdev->soc_host.priv = pcdev; pcdev->soc_host.priv = pcdev;
pcdev->soc_host.dev = &pdev->dev;
pcdev->soc_host.nr = pdev->id; pcdev->soc_host.nr = pdev->id;
err = soc_camera_host_register(&pcdev->soc_host); err = soc_camera_host_register(&pcdev->soc_host);
...@@ -1722,3 +1728,4 @@ module_exit(pxa_camera_exit); ...@@ -1722,3 +1728,4 @@ module_exit(pxa_camera_exit);
MODULE_DESCRIPTION("PXA27x SoC Camera Host driver"); MODULE_DESCRIPTION("PXA27x SoC Camera Host driver");
MODULE_AUTHOR("Guennadi Liakhovetski <kernel@pengutronix.de>"); MODULE_AUTHOR("Guennadi Liakhovetski <kernel@pengutronix.de>");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:" PXA_CAM_DRV_NAME);
...@@ -357,11 +357,13 @@ static int sh_mobile_ceu_add_device(struct soc_camera_device *icd) ...@@ -357,11 +357,13 @@ static int sh_mobile_ceu_add_device(struct soc_camera_device *icd)
"SuperH Mobile CEU driver attached to camera %d\n", "SuperH Mobile CEU driver attached to camera %d\n",
icd->devnum); icd->devnum);
clk_enable(pcdev->clk);
ret = icd->ops->init(icd); ret = icd->ops->init(icd);
if (ret) if (ret) {
clk_disable(pcdev->clk);
goto err; goto err;
}
clk_enable(pcdev->clk);
ceu_write(pcdev, CAPSR, 1 << 16); /* reset */ ceu_write(pcdev, CAPSR, 1 << 16); /* reset */
while (ceu_read(pcdev, CSTSR) & 1) while (ceu_read(pcdev, CSTSR) & 1)
...@@ -395,10 +397,10 @@ static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd) ...@@ -395,10 +397,10 @@ static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd)
} }
spin_unlock_irqrestore(&pcdev->lock, flags); spin_unlock_irqrestore(&pcdev->lock, flags);
clk_disable(pcdev->clk);
icd->ops->release(icd); icd->ops->release(icd);
clk_disable(pcdev->clk);
dev_info(&icd->dev, dev_info(&icd->dev,
"SuperH Mobile CEU driver detached from camera %d\n", "SuperH Mobile CEU driver detached from camera %d\n",
icd->devnum); icd->devnum);
...@@ -937,3 +939,4 @@ module_exit(sh_mobile_ceu_exit); ...@@ -937,3 +939,4 @@ module_exit(sh_mobile_ceu_exit);
MODULE_DESCRIPTION("SuperH Mobile CEU driver"); MODULE_DESCRIPTION("SuperH Mobile CEU driver");
MODULE_AUTHOR("Magnus Damm"); MODULE_AUTHOR("Magnus Damm");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:sh_mobile_ceu");
This diff is collapsed.
...@@ -21,35 +21,32 @@ ...@@ -21,35 +21,32 @@
#include <media/soc_camera_platform.h> #include <media/soc_camera_platform.h>
struct soc_camera_platform_priv { struct soc_camera_platform_priv {
struct soc_camera_platform_info *info;
struct soc_camera_device icd;
struct soc_camera_data_format format; struct soc_camera_data_format format;
}; };
static struct soc_camera_platform_info * static struct soc_camera_platform_info *
soc_camera_platform_get_info(struct soc_camera_device *icd) soc_camera_platform_get_info(struct soc_camera_device *icd)
{ {
struct soc_camera_platform_priv *priv; struct platform_device *pdev = to_platform_device(dev_get_drvdata(&icd->dev));
priv = container_of(icd, struct soc_camera_platform_priv, icd); return pdev->dev.platform_data;
return priv->info;
} }
static int soc_camera_platform_init(struct soc_camera_device *icd) static int soc_camera_platform_init(struct soc_camera_device *icd)
{ {
struct soc_camera_platform_info *p = soc_camera_platform_get_info(icd); struct soc_camera_link *icl = to_soc_camera_link(icd);
if (p->power) if (icl->power)
p->power(1); icl->power(dev_get_drvdata(&icd->dev), 1);
return 0; return 0;
} }
static int soc_camera_platform_release(struct soc_camera_device *icd) static int soc_camera_platform_release(struct soc_camera_device *icd)
{ {
struct soc_camera_platform_info *p = soc_camera_platform_get_info(icd); struct soc_camera_link *icl = to_soc_camera_link(icd);
if (p->power) if (icl->power)
p->power(0); icl->power(dev_get_drvdata(&icd->dev), 0);
return 0; return 0;
} }
...@@ -102,31 +99,29 @@ static int soc_camera_platform_try_fmt(struct soc_camera_device *icd, ...@@ -102,31 +99,29 @@ static int soc_camera_platform_try_fmt(struct soc_camera_device *icd,
return 0; return 0;
} }
static int soc_camera_platform_video_probe(struct soc_camera_device *icd) static int soc_camera_platform_video_probe(struct soc_camera_device *icd,
struct platform_device *pdev)
{ {
struct soc_camera_platform_priv *priv; struct soc_camera_platform_priv *priv = platform_get_drvdata(pdev);
priv = container_of(icd, struct soc_camera_platform_priv, icd); struct soc_camera_platform_info *p = pdev->dev.platform_data;
int ret;
priv->format.name = priv->info->format_name; priv->format.name = p->format_name;
priv->format.depth = priv->info->format_depth; priv->format.depth = p->format_depth;
priv->format.fourcc = priv->info->format.pixelformat; priv->format.fourcc = p->format.pixelformat;
priv->format.colorspace = priv->info->format.colorspace; priv->format.colorspace = p->format.colorspace;
icd->formats = &priv->format; icd->formats = &priv->format;
icd->num_formats = 1; icd->num_formats = 1;
return soc_camera_video_start(icd); /* ..._video_start() does dev_set_drvdata(&icd->dev, &pdev->dev) */
} ret = soc_camera_video_start(icd, &pdev->dev);
static void soc_camera_platform_video_remove(struct soc_camera_device *icd)
{
soc_camera_video_stop(icd); soc_camera_video_stop(icd);
return ret;
} }
static struct soc_camera_ops soc_camera_platform_ops = { static struct soc_camera_ops soc_camera_platform_ops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.probe = soc_camera_platform_video_probe,
.remove = soc_camera_platform_video_remove,
.init = soc_camera_platform_init, .init = soc_camera_platform_init,
.release = soc_camera_platform_release, .release = soc_camera_platform_release,
.start_capture = soc_camera_platform_start_capture, .start_capture = soc_camera_platform_start_capture,
...@@ -141,11 +136,10 @@ static struct soc_camera_ops soc_camera_platform_ops = { ...@@ -141,11 +136,10 @@ static struct soc_camera_ops soc_camera_platform_ops = {
static int soc_camera_platform_probe(struct platform_device *pdev) static int soc_camera_platform_probe(struct platform_device *pdev)
{ {
struct soc_camera_platform_priv *priv; struct soc_camera_platform_priv *priv;
struct soc_camera_platform_info *p; struct soc_camera_platform_info *p = pdev->dev.platform_data;
struct soc_camera_device *icd; struct soc_camera_device *icd;
int ret; int ret;
p = pdev->dev.platform_data;
if (!p) if (!p)
return -EINVAL; return -EINVAL;
...@@ -153,31 +147,40 @@ static int soc_camera_platform_probe(struct platform_device *pdev) ...@@ -153,31 +147,40 @@ static int soc_camera_platform_probe(struct platform_device *pdev)
if (!priv) if (!priv)
return -ENOMEM; return -ENOMEM;
priv->info = p;
platform_set_drvdata(pdev, priv); platform_set_drvdata(pdev, priv);
icd = &priv->icd; icd = to_soc_camera_dev(p->dev);
if (!icd)
goto enoicd;
icd->ops = &soc_camera_platform_ops; icd->ops = &soc_camera_platform_ops;
icd->control = &pdev->dev; dev_set_drvdata(&icd->dev, &pdev->dev);
icd->width_min = 0; icd->width_min = 0;
icd->width_max = priv->info->format.width; icd->width_max = p->format.width;
icd->height_min = 0; icd->height_min = 0;
icd->height_max = priv->info->format.height; icd->height_max = p->format.height;
icd->y_skip_top = 0; icd->y_skip_top = 0;
icd->iface = priv->info->iface;
ret = soc_camera_device_register(icd); ret = soc_camera_platform_video_probe(icd, pdev);
if (ret) if (ret) {
icd->ops = NULL;
kfree(priv); kfree(priv);
}
return ret; return ret;
enoicd:
kfree(priv);
return -EINVAL;
} }
static int soc_camera_platform_remove(struct platform_device *pdev) static int soc_camera_platform_remove(struct platform_device *pdev)
{ {
struct soc_camera_platform_priv *priv = platform_get_drvdata(pdev); struct soc_camera_platform_priv *priv = platform_get_drvdata(pdev);
struct soc_camera_platform_info *p = pdev->dev.platform_data;
struct soc_camera_device *icd = to_soc_camera_dev(p->dev);
soc_camera_device_unregister(&priv->icd); icd->ops = NULL;
kfree(priv); kfree(priv);
return 0; return 0;
} }
...@@ -206,3 +209,4 @@ module_exit(soc_camera_platform_module_exit); ...@@ -206,3 +209,4 @@ module_exit(soc_camera_platform_module_exit);
MODULE_DESCRIPTION("SoC Camera Platform driver"); MODULE_DESCRIPTION("SoC Camera Platform driver");
MODULE_AUTHOR("Magnus Damm"); MODULE_AUTHOR("Magnus Damm");
MODULE_LICENSE("GPL v2"); MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:soc_camera_platform");
...@@ -224,8 +224,6 @@ struct tw9910_hsync_ctrl { ...@@ -224,8 +224,6 @@ struct tw9910_hsync_ctrl {
struct tw9910_priv { struct tw9910_priv {
struct tw9910_video_info *info; struct tw9910_video_info *info;
struct i2c_client *client;
struct soc_camera_device icd;
const struct tw9910_scale_ctrl *scale; const struct tw9910_scale_ctrl *scale;
}; };
...@@ -511,35 +509,38 @@ tw9910_select_norm(struct soc_camera_device *icd, u32 width, u32 height) ...@@ -511,35 +509,38 @@ tw9910_select_norm(struct soc_camera_device *icd, u32 width, u32 height)
*/ */
static int tw9910_init(struct soc_camera_device *icd) static int tw9910_init(struct soc_camera_device *icd)
{ {
struct tw9910_priv *priv = container_of(icd, struct tw9910_priv, icd); struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
struct soc_camera_link *icl = to_soc_camera_link(icd);
int ret = 0; int ret = 0;
if (priv->info->link.power) { if (icl->power) {
ret = priv->info->link.power(&priv->client->dev, 1); ret = icl->power(&client->dev, 1);
if (ret < 0) if (ret < 0)
return ret; return ret;
} }
if (priv->info->link.reset) if (icl->reset)
ret = priv->info->link.reset(&priv->client->dev); ret = icl->reset(&client->dev);
return ret; return ret;
} }
static int tw9910_release(struct soc_camera_device *icd) static int tw9910_release(struct soc_camera_device *icd)
{ {
struct tw9910_priv *priv = container_of(icd, struct tw9910_priv, icd); struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
struct soc_camera_link *icl = to_soc_camera_link(icd);
int ret = 0; int ret = 0;
if (priv->info->link.power) if (icl->power)
ret = priv->info->link.power(&priv->client->dev, 0); ret = icl->power(&client->dev, 0);
return ret; return ret;
} }
static int tw9910_start_capture(struct soc_camera_device *icd) static int tw9910_start_capture(struct soc_camera_device *icd)
{ {
struct tw9910_priv *priv = container_of(icd, struct tw9910_priv, icd); struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
struct tw9910_priv *priv = i2c_get_clientdata(client);
if (!priv->scale) { if (!priv->scale) {
dev_err(&icd->dev, "norm select error\n"); dev_err(&icd->dev, "norm select error\n");
...@@ -567,8 +568,9 @@ static int tw9910_set_bus_param(struct soc_camera_device *icd, ...@@ -567,8 +568,9 @@ static int tw9910_set_bus_param(struct soc_camera_device *icd,
static unsigned long tw9910_query_bus_param(struct soc_camera_device *icd) static unsigned long tw9910_query_bus_param(struct soc_camera_device *icd)
{ {
struct tw9910_priv *priv = container_of(icd, struct tw9910_priv, icd); struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
struct soc_camera_link *icl = priv->client->dev.platform_data; struct tw9910_priv *priv = i2c_get_clientdata(client);
struct soc_camera_link *icl = to_soc_camera_link(icd);
unsigned long flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_MASTER | unsigned long flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_MASTER |
SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_HIGH |
SOCAM_DATA_ACTIVE_HIGH | priv->info->buswidth; SOCAM_DATA_ACTIVE_HIGH | priv->info->buswidth;
...@@ -610,13 +612,13 @@ static int tw9910_enum_input(struct soc_camera_device *icd, ...@@ -610,13 +612,13 @@ static int tw9910_enum_input(struct soc_camera_device *icd,
static int tw9910_get_register(struct soc_camera_device *icd, static int tw9910_get_register(struct soc_camera_device *icd,
struct v4l2_dbg_register *reg) struct v4l2_dbg_register *reg)
{ {
struct tw9910_priv *priv = container_of(icd, struct tw9910_priv, icd); struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
int ret; int ret;
if (reg->reg > 0xff) if (reg->reg > 0xff)
return -EINVAL; return -EINVAL;
ret = i2c_smbus_read_byte_data(priv->client, reg->reg); ret = i2c_smbus_read_byte_data(client, reg->reg);
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -631,20 +633,21 @@ static int tw9910_get_register(struct soc_camera_device *icd, ...@@ -631,20 +633,21 @@ static int tw9910_get_register(struct soc_camera_device *icd,
static int tw9910_set_register(struct soc_camera_device *icd, static int tw9910_set_register(struct soc_camera_device *icd,
struct v4l2_dbg_register *reg) struct v4l2_dbg_register *reg)
{ {
struct tw9910_priv *priv = container_of(icd, struct tw9910_priv, icd); struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
if (reg->reg > 0xff || if (reg->reg > 0xff ||
reg->val > 0xff) reg->val > 0xff)
return -EINVAL; return -EINVAL;
return i2c_smbus_write_byte_data(priv->client, reg->reg, reg->val); return i2c_smbus_write_byte_data(client, reg->reg, reg->val);
} }
#endif #endif
static int tw9910_set_crop(struct soc_camera_device *icd, static int tw9910_set_crop(struct soc_camera_device *icd,
struct v4l2_rect *rect) struct v4l2_rect *rect)
{ {
struct tw9910_priv *priv = container_of(icd, struct tw9910_priv, icd); struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
struct tw9910_priv *priv = i2c_get_clientdata(client);
int ret = -EINVAL; int ret = -EINVAL;
u8 val; u8 val;
...@@ -658,8 +661,8 @@ static int tw9910_set_crop(struct soc_camera_device *icd, ...@@ -658,8 +661,8 @@ static int tw9910_set_crop(struct soc_camera_device *icd,
/* /*
* reset hardware * reset hardware
*/ */
tw9910_reset(priv->client); tw9910_reset(client);
ret = tw9910_write_array(priv->client, tw9910_default_regs); ret = tw9910_write_array(client, tw9910_default_regs);
if (ret < 0) if (ret < 0)
goto tw9910_set_fmt_error; goto tw9910_set_fmt_error;
...@@ -670,7 +673,7 @@ static int tw9910_set_crop(struct soc_camera_device *icd, ...@@ -670,7 +673,7 @@ static int tw9910_set_crop(struct soc_camera_device *icd,
if (SOCAM_DATAWIDTH_16 == priv->info->buswidth) if (SOCAM_DATAWIDTH_16 == priv->info->buswidth)
val = LEN; val = LEN;
ret = tw9910_mask_set(priv->client, OPFORM, LEN, val); ret = tw9910_mask_set(client, OPFORM, LEN, val);
if (ret < 0) if (ret < 0)
goto tw9910_set_fmt_error; goto tw9910_set_fmt_error;
...@@ -698,28 +701,28 @@ static int tw9910_set_crop(struct soc_camera_device *icd, ...@@ -698,28 +701,28 @@ static int tw9910_set_crop(struct soc_camera_device *icd,
val = 0; val = 0;
} }
ret = tw9910_mask_set(priv->client, VBICNTL, RTSEL_MASK, val); ret = tw9910_mask_set(client, VBICNTL, RTSEL_MASK, val);
if (ret < 0) if (ret < 0)
goto tw9910_set_fmt_error; goto tw9910_set_fmt_error;
/* /*
* set scale * set scale
*/ */
ret = tw9910_set_scale(priv->client, priv->scale); ret = tw9910_set_scale(client, priv->scale);
if (ret < 0) if (ret < 0)
goto tw9910_set_fmt_error; goto tw9910_set_fmt_error;
/* /*
* set cropping * set cropping
*/ */
ret = tw9910_set_cropping(priv->client, &tw9910_cropping_ctrl); ret = tw9910_set_cropping(client, &tw9910_cropping_ctrl);
if (ret < 0) if (ret < 0)
goto tw9910_set_fmt_error; goto tw9910_set_fmt_error;
/* /*
* set hsync * set hsync
*/ */
ret = tw9910_set_hsync(priv->client, &tw9910_hsync_ctrl); ret = tw9910_set_hsync(client, &tw9910_hsync_ctrl);
if (ret < 0) if (ret < 0)
goto tw9910_set_fmt_error; goto tw9910_set_fmt_error;
...@@ -727,7 +730,7 @@ static int tw9910_set_crop(struct soc_camera_device *icd, ...@@ -727,7 +730,7 @@ static int tw9910_set_crop(struct soc_camera_device *icd,
tw9910_set_fmt_error: tw9910_set_fmt_error:
tw9910_reset(priv->client); tw9910_reset(client);
priv->scale = NULL; priv->scale = NULL;
return ret; return ret;
...@@ -784,9 +787,10 @@ static int tw9910_try_fmt(struct soc_camera_device *icd, ...@@ -784,9 +787,10 @@ static int tw9910_try_fmt(struct soc_camera_device *icd,
return 0; return 0;
} }
static int tw9910_video_probe(struct soc_camera_device *icd) static int tw9910_video_probe(struct soc_camera_device *icd,
struct i2c_client *client)
{ {
struct tw9910_priv *priv = container_of(icd, struct tw9910_priv, icd); struct tw9910_priv *priv = i2c_get_clientdata(client);
s32 val; s32 val;
int ret; int ret;
...@@ -810,10 +814,18 @@ static int tw9910_video_probe(struct soc_camera_device *icd) ...@@ -810,10 +814,18 @@ static int tw9910_video_probe(struct soc_camera_device *icd)
icd->formats = tw9910_color_fmt; icd->formats = tw9910_color_fmt;
icd->num_formats = ARRAY_SIZE(tw9910_color_fmt); icd->num_formats = ARRAY_SIZE(tw9910_color_fmt);
/* Switch master clock on */
ret = soc_camera_video_start(icd, &client->dev);
if (ret)
return ret;
/* /*
* check and show Product ID * check and show Product ID
*/ */
val = i2c_smbus_read_byte_data(priv->client, ID); val = i2c_smbus_read_byte_data(client, ID);
soc_camera_video_stop(icd);
if (0x0B != GET_ID(val) || if (0x0B != GET_ID(val) ||
0x00 != GET_ReV(val)) { 0x00 != GET_ReV(val)) {
dev_err(&icd->dev, dev_err(&icd->dev,
...@@ -824,25 +836,14 @@ static int tw9910_video_probe(struct soc_camera_device *icd) ...@@ -824,25 +836,14 @@ static int tw9910_video_probe(struct soc_camera_device *icd)
dev_info(&icd->dev, dev_info(&icd->dev,
"tw9910 Product ID %0x:%0x\n", GET_ID(val), GET_ReV(val)); "tw9910 Product ID %0x:%0x\n", GET_ID(val), GET_ReV(val));
ret = soc_camera_video_start(icd);
if (ret < 0)
return ret;
icd->vdev->tvnorms = V4L2_STD_NTSC | V4L2_STD_PAL; icd->vdev->tvnorms = V4L2_STD_NTSC | V4L2_STD_PAL;
icd->vdev->current_norm = V4L2_STD_NTSC; icd->vdev->current_norm = V4L2_STD_NTSC;
return ret; return ret;
} }
static void tw9910_video_remove(struct soc_camera_device *icd)
{
soc_camera_video_stop(icd);
}
static struct soc_camera_ops tw9910_ops = { static struct soc_camera_ops tw9910_ops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.probe = tw9910_video_probe,
.remove = tw9910_video_remove,
.init = tw9910_init, .init = tw9910_init,
.release = tw9910_release, .release = tw9910_release,
.start_capture = tw9910_start_capture, .start_capture = tw9910_start_capture,
...@@ -871,18 +872,25 @@ static int tw9910_probe(struct i2c_client *client, ...@@ -871,18 +872,25 @@ static int tw9910_probe(struct i2c_client *client,
{ {
struct tw9910_priv *priv; struct tw9910_priv *priv;
struct tw9910_video_info *info; struct tw9910_video_info *info;
struct soc_camera_device *icd; struct soc_camera_device *icd = client->dev.platform_data;
struct i2c_adapter *adapter =
to_i2c_adapter(client->dev.parent);
struct soc_camera_link *icl;
const struct tw9910_scale_ctrl *scale; const struct tw9910_scale_ctrl *scale;
int i, ret; int i, ret;
if (!client->dev.platform_data) if (!icd) {
dev_err(&client->dev, "TW9910: missing soc-camera data!\n");
return -EINVAL; return -EINVAL;
}
info = container_of(client->dev.platform_data, icl = to_soc_camera_link(icd);
struct tw9910_video_info, link); if (!icl)
return -EINVAL;
if (!i2c_check_functionality(to_i2c_adapter(client->dev.parent), info = container_of(icl, struct tw9910_video_info, link);
I2C_FUNC_SMBUS_BYTE_DATA)) {
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
dev_err(&client->dev, dev_err(&client->dev,
"I2C-Adapter doesn't support " "I2C-Adapter doesn't support "
"I2C_FUNC_SMBUS_BYTE_DATA\n"); "I2C_FUNC_SMBUS_BYTE_DATA\n");
...@@ -894,12 +902,9 @@ static int tw9910_probe(struct i2c_client *client, ...@@ -894,12 +902,9 @@ static int tw9910_probe(struct i2c_client *client,
return -ENOMEM; return -ENOMEM;
priv->info = info; priv->info = info;
priv->client = client;
i2c_set_clientdata(client, priv); i2c_set_clientdata(client, priv);
icd = &priv->icd;
icd->ops = &tw9910_ops; icd->ops = &tw9910_ops;
icd->control = &client->dev;
icd->iface = info->link.bus_id; icd->iface = info->link.bus_id;
/* /*
...@@ -925,9 +930,9 @@ static int tw9910_probe(struct i2c_client *client, ...@@ -925,9 +930,9 @@ static int tw9910_probe(struct i2c_client *client,
icd->height_min = min(scale[i].height, icd->height_min); icd->height_min = min(scale[i].height, icd->height_min);
} }
ret = soc_camera_device_register(icd); ret = tw9910_video_probe(icd, client);
if (ret) { if (ret) {
icd->ops = NULL;
i2c_set_clientdata(client, NULL); i2c_set_clientdata(client, NULL);
kfree(priv); kfree(priv);
} }
...@@ -938,8 +943,9 @@ static int tw9910_probe(struct i2c_client *client, ...@@ -938,8 +943,9 @@ static int tw9910_probe(struct i2c_client *client,
static int tw9910_remove(struct i2c_client *client) static int tw9910_remove(struct i2c_client *client)
{ {
struct tw9910_priv *priv = i2c_get_clientdata(client); struct tw9910_priv *priv = i2c_get_clientdata(client);
struct soc_camera_device *icd = client->dev.platform_data;
soc_camera_device_unregister(&priv->icd); icd->ops = NULL;
i2c_set_clientdata(client, NULL); i2c_set_clientdata(client, NULL);
kfree(priv); kfree(priv);
return 0; return 0;
......
...@@ -20,7 +20,6 @@ ...@@ -20,7 +20,6 @@
struct soc_camera_device { struct soc_camera_device {
struct list_head list; struct list_head list;
struct device dev; struct device dev;
struct device *control;
unsigned short width; /* Current window */ unsigned short width; /* Current window */
unsigned short height; /* sizes */ unsigned short height; /* sizes */
unsigned short x_min; /* Camera capabilities */ unsigned short x_min; /* Camera capabilities */
...@@ -131,17 +130,25 @@ static inline struct soc_camera_host *to_soc_camera_host(struct device *dev) ...@@ -131,17 +130,25 @@ static inline struct soc_camera_host *to_soc_camera_host(struct device *dev)
return dev_get_drvdata(dev); return dev_get_drvdata(dev);
} }
extern int soc_camera_host_register(struct soc_camera_host *ici); static inline struct soc_camera_link *to_soc_camera_link(struct soc_camera_device *icd)
extern void soc_camera_host_unregister(struct soc_camera_host *ici); {
extern int soc_camera_device_register(struct soc_camera_device *icd); return icd->dev.platform_data;
extern void soc_camera_device_unregister(struct soc_camera_device *icd); }
extern int soc_camera_video_start(struct soc_camera_device *icd); static inline struct device *to_soc_camera_control(struct soc_camera_device *icd)
extern void soc_camera_video_stop(struct soc_camera_device *icd); {
return dev_get_drvdata(&icd->dev);
}
extern const struct soc_camera_data_format *soc_camera_format_by_fourcc( int soc_camera_host_register(struct soc_camera_host *ici);
void soc_camera_host_unregister(struct soc_camera_host *ici);
int soc_camera_video_start(struct soc_camera_device *icd, struct device *dev);
void soc_camera_video_stop(struct soc_camera_device *icd);
const struct soc_camera_data_format *soc_camera_format_by_fourcc(
struct soc_camera_device *icd, unsigned int fourcc); struct soc_camera_device *icd, unsigned int fourcc);
extern const struct soc_camera_format_xlate *soc_camera_xlate_by_fourcc( const struct soc_camera_format_xlate *soc_camera_xlate_by_fourcc(
struct soc_camera_device *icd, unsigned int fourcc); struct soc_camera_device *icd, unsigned int fourcc);
struct soc_camera_data_format { struct soc_camera_data_format {
...@@ -170,8 +177,6 @@ struct soc_camera_format_xlate { ...@@ -170,8 +177,6 @@ struct soc_camera_format_xlate {
struct soc_camera_ops { struct soc_camera_ops {
struct module *owner; struct module *owner;
int (*probe)(struct soc_camera_device *);
void (*remove)(struct soc_camera_device *);
int (*suspend)(struct soc_camera_device *, pm_message_t state); int (*suspend)(struct soc_camera_device *, pm_message_t state);
int (*resume)(struct soc_camera_device *); int (*resume)(struct soc_camera_device *);
int (*init)(struct soc_camera_device *); int (*init)(struct soc_camera_device *);
......
...@@ -18,11 +18,10 @@ struct device; ...@@ -18,11 +18,10 @@ struct device;
struct soc_camera_platform_info { struct soc_camera_platform_info {
int iface; int iface;
char *format_name; const char *format_name;
unsigned long format_depth; unsigned long format_depth;
struct v4l2_pix_format format; struct v4l2_pix_format format;
unsigned long bus_param; unsigned long bus_param;
void (*power)(int);
struct device *dev; struct device *dev;
int (*set_capture)(struct soc_camera_platform_info *info, int enable); int (*set_capture)(struct soc_camera_platform_info *info, int enable);
struct soc_camera_link link; struct soc_camera_link link;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment