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>
This commit is contained in:
parent
506c629a8e
commit
8103466315
@ -36,8 +36,6 @@
|
|||||||
|
|
||||||
struct pxacamera_platform_data {
|
struct pxacamera_platform_data {
|
||||||
int (*init)(struct device *);
|
int (*init)(struct device *);
|
||||||
int (*power)(struct device *, int);
|
|
||||||
int (*reset)(struct device *, int);
|
|
||||||
|
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
unsigned long mclk_10khz;
|
unsigned long mclk_10khz;
|
||||||
|
@ -117,13 +117,33 @@ static int reg_clear(struct soc_camera_device *icd, const u8 reg,
|
|||||||
|
|
||||||
static int mt9m001_init(struct soc_camera_device *icd)
|
static int mt9m001_init(struct soc_camera_device *icd)
|
||||||
{
|
{
|
||||||
|
struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd);
|
||||||
|
struct soc_camera_link *icl = mt9m001->client->dev.platform_data;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
dev_dbg(icd->vdev->parent, "%s\n", __func__);
|
dev_dbg(icd->vdev->parent, "%s\n", __func__);
|
||||||
|
|
||||||
ret = reg_write(icd, MT9M001_RESET, 1);
|
if (icl->power) {
|
||||||
if (!ret)
|
ret = icl->power(&mt9m001->client->dev, 1);
|
||||||
ret = reg_write(icd, MT9M001_RESET, 0);
|
if (ret < 0) {
|
||||||
|
dev_err(icd->vdev->parent,
|
||||||
|
"Platform failed to power-on the camera.\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The camera could have been already on, we reset it additionally */
|
||||||
|
if (icl->reset)
|
||||||
|
ret = icl->reset(&mt9m001->client->dev);
|
||||||
|
else
|
||||||
|
ret = -ENODEV;
|
||||||
|
|
||||||
|
if (ret < 0) {
|
||||||
|
/* Either no platform reset, or platform reset failed */
|
||||||
|
ret = reg_write(icd, MT9M001_RESET, 1);
|
||||||
|
if (!ret)
|
||||||
|
ret = reg_write(icd, MT9M001_RESET, 0);
|
||||||
|
}
|
||||||
/* Disable chip, synchronous option update */
|
/* Disable chip, synchronous option update */
|
||||||
if (!ret)
|
if (!ret)
|
||||||
ret = reg_write(icd, MT9M001_OUTPUT_CONTROL, 0);
|
ret = reg_write(icd, MT9M001_OUTPUT_CONTROL, 0);
|
||||||
@ -133,8 +153,15 @@ static int mt9m001_init(struct soc_camera_device *icd)
|
|||||||
|
|
||||||
static int mt9m001_release(struct soc_camera_device *icd)
|
static int mt9m001_release(struct soc_camera_device *icd)
|
||||||
{
|
{
|
||||||
|
struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd);
|
||||||
|
struct soc_camera_link *icl = mt9m001->client->dev.platform_data;
|
||||||
|
|
||||||
/* Disable the chip */
|
/* Disable the chip */
|
||||||
reg_write(icd, MT9M001_OUTPUT_CONTROL, 0);
|
reg_write(icd, MT9M001_OUTPUT_CONTROL, 0);
|
||||||
|
|
||||||
|
if (icl->power)
|
||||||
|
icl->power(&mt9m001->client->dev, 0);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -351,8 +351,18 @@ static int mt9m111_setfmt_yuv(struct soc_camera_device *icd)
|
|||||||
static int mt9m111_enable(struct soc_camera_device *icd)
|
static int mt9m111_enable(struct soc_camera_device *icd)
|
||||||
{
|
{
|
||||||
struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
|
struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
|
||||||
|
struct soc_camera_link *icl = mt9m111->client->dev.platform_data;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
if (icl->power) {
|
||||||
|
ret = icl->power(&mt9m111->client->dev, 1);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(icd->vdev->parent,
|
||||||
|
"Platform failed to power-on the camera.\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ret = reg_set(RESET, MT9M111_RESET_CHIP_ENABLE);
|
ret = reg_set(RESET, MT9M111_RESET_CHIP_ENABLE);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
mt9m111->powered = 1;
|
mt9m111->powered = 1;
|
||||||
@ -362,11 +372,16 @@ static int mt9m111_enable(struct soc_camera_device *icd)
|
|||||||
static int mt9m111_disable(struct soc_camera_device *icd)
|
static int mt9m111_disable(struct soc_camera_device *icd)
|
||||||
{
|
{
|
||||||
struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
|
struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
|
||||||
|
struct soc_camera_link *icl = mt9m111->client->dev.platform_data;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = reg_clear(RESET, MT9M111_RESET_CHIP_ENABLE);
|
ret = reg_clear(RESET, MT9M111_RESET_CHIP_ENABLE);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
mt9m111->powered = 0;
|
mt9m111->powered = 0;
|
||||||
|
|
||||||
|
if (icl->power)
|
||||||
|
icl->power(&mt9m111->client->dev, 0);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,8 +134,25 @@ static int reg_clear(struct soc_camera_device *icd, const u8 reg,
|
|||||||
static int mt9v022_init(struct soc_camera_device *icd)
|
static int mt9v022_init(struct soc_camera_device *icd)
|
||||||
{
|
{
|
||||||
struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd);
|
struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd);
|
||||||
|
struct soc_camera_link *icl = mt9v022->client->dev.platform_data;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
if (icl->power) {
|
||||||
|
ret = icl->power(&mt9v022->client->dev, 1);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(icd->vdev->parent,
|
||||||
|
"Platform failed to power-on the camera.\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The camera could have been already on, we hard-reset it additionally,
|
||||||
|
* if available. Soft reset is done in video_probe().
|
||||||
|
*/
|
||||||
|
if (icl->reset)
|
||||||
|
icl->reset(&mt9v022->client->dev);
|
||||||
|
|
||||||
/* Almost the default mode: master, parallel, simultaneous, and an
|
/* Almost the default mode: master, parallel, simultaneous, and an
|
||||||
* undocumented bit 0x200, which is present in table 7, but not in 8,
|
* undocumented bit 0x200, which is present in table 7, but not in 8,
|
||||||
* plus snapshot mode to disable scan for now */
|
* plus snapshot mode to disable scan for now */
|
||||||
@ -161,7 +178,12 @@ static int mt9v022_init(struct soc_camera_device *icd)
|
|||||||
|
|
||||||
static int mt9v022_release(struct soc_camera_device *icd)
|
static int mt9v022_release(struct soc_camera_device *icd)
|
||||||
{
|
{
|
||||||
/* Nothing? */
|
struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd);
|
||||||
|
struct soc_camera_link *icl = mt9v022->client->dev.platform_data;
|
||||||
|
|
||||||
|
if (icl->power)
|
||||||
|
icl->power(&mt9v022->client->dev, 0);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -629,17 +629,6 @@ static void pxa_camera_activate(struct pxa_camera_dev *pcdev)
|
|||||||
pdata->init(pcdev->dev);
|
pdata->init(pcdev->dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pdata && pdata->power) {
|
|
||||||
dev_dbg(pcdev->dev, "%s: Power on camera\n", __func__);
|
|
||||||
pdata->power(pcdev->dev, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pdata && pdata->reset) {
|
|
||||||
dev_dbg(pcdev->dev, "%s: Releasing camera reset\n",
|
|
||||||
__func__);
|
|
||||||
pdata->reset(pcdev->dev, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
CICR0 = 0x3FF; /* disable all interrupts */
|
CICR0 = 0x3FF; /* disable all interrupts */
|
||||||
|
|
||||||
if (pcdev->platform_flags & PXA_CAMERA_PCLK_EN)
|
if (pcdev->platform_flags & PXA_CAMERA_PCLK_EN)
|
||||||
@ -660,20 +649,7 @@ static void pxa_camera_activate(struct pxa_camera_dev *pcdev)
|
|||||||
|
|
||||||
static void pxa_camera_deactivate(struct pxa_camera_dev *pcdev)
|
static void pxa_camera_deactivate(struct pxa_camera_dev *pcdev)
|
||||||
{
|
{
|
||||||
struct pxacamera_platform_data *board = pcdev->pdata;
|
|
||||||
|
|
||||||
clk_disable(pcdev->clk);
|
clk_disable(pcdev->clk);
|
||||||
|
|
||||||
if (board && board->reset) {
|
|
||||||
dev_dbg(pcdev->dev, "%s: Asserting camera reset\n",
|
|
||||||
__func__);
|
|
||||||
board->reset(pcdev->dev, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (board && board->power) {
|
|
||||||
dev_dbg(pcdev->dev, "%s: Power off camera\n", __func__);
|
|
||||||
board->power(pcdev->dev, 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static irqreturn_t pxa_camera_irq(int irq, void *data)
|
static irqreturn_t pxa_camera_irq(int irq, void *data)
|
||||||
|
@ -304,9 +304,6 @@ 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);
|
||||||
|
|
||||||
if (pcdev->pdata->enable_camera)
|
|
||||||
pcdev->pdata->enable_camera();
|
|
||||||
|
|
||||||
ret = icd->ops->init(icd);
|
ret = icd->ops->init(icd);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err;
|
goto err;
|
||||||
@ -333,8 +330,6 @@ static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd)
|
|||||||
ceu_write(pcdev, CEIER, 0);
|
ceu_write(pcdev, CEIER, 0);
|
||||||
ceu_write(pcdev, CAPSR, 1 << 16); /* reset */
|
ceu_write(pcdev, CAPSR, 1 << 16); /* reset */
|
||||||
icd->ops->release(icd);
|
icd->ops->release(icd);
|
||||||
if (pcdev->pdata->disable_camera)
|
|
||||||
pcdev->pdata->disable_camera();
|
|
||||||
|
|
||||||
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",
|
||||||
|
@ -5,8 +5,6 @@
|
|||||||
|
|
||||||
struct sh_mobile_ceu_info {
|
struct sh_mobile_ceu_info {
|
||||||
unsigned long flags; /* SOCAM_... */
|
unsigned long flags; /* SOCAM_... */
|
||||||
void (*enable_camera)(void);
|
|
||||||
void (*disable_camera)(void);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* __ASM_SH_MOBILE_CEU_H__ */
|
#endif /* __ASM_SH_MOBILE_CEU_H__ */
|
||||||
|
@ -83,6 +83,9 @@ struct soc_camera_link {
|
|||||||
int bus_id;
|
int bus_id;
|
||||||
/* GPIO number to switch between 8 and 10 bit modes */
|
/* GPIO number to switch between 8 and 10 bit modes */
|
||||||
unsigned int gpio;
|
unsigned int gpio;
|
||||||
|
/* Optional callbacks to power on or off and reset the sensor */
|
||||||
|
int (*power)(struct device *, int);
|
||||||
|
int (*reset)(struct device *);
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline struct soc_camera_device *to_soc_camera_dev(struct device *dev)
|
static inline struct soc_camera_device *to_soc_camera_dev(struct device *dev)
|
||||||
|
Loading…
Reference in New Issue
Block a user