Skip to content

Commit

Permalink
V4L/DVB (8687): soc-camera: Move .power and .reset from soc_camera ho…
Browse files Browse the repository at this point in the history
…st 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>
  • Loading branch information
Stefan Herbrechtsmeier authored and Mauro Carvalho Chehab committed Oct 12, 2008
1 parent 506c629 commit 8103466
Show file tree
Hide file tree
Showing 8 changed files with 71 additions and 37 deletions.
2 changes: 0 additions & 2 deletions arch/arm/mach-pxa/include/mach/camera.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,6 @@

struct pxacamera_platform_data {
int (*init)(struct device *);
int (*power)(struct device *, int);
int (*reset)(struct device *, int);

unsigned long flags;
unsigned long mclk_10khz;
Expand Down
33 changes: 30 additions & 3 deletions drivers/media/video/mt9m001.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd);
struct soc_camera_link *icl = mt9m001->client->dev.platform_data;
int ret;

dev_dbg(icd->vdev->parent, "%s\n", __func__);

ret = reg_write(icd, MT9M001_RESET, 1);
if (!ret)
ret = reg_write(icd, MT9M001_RESET, 0);
if (icl->power) {
ret = icl->power(&mt9m001->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 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 */
if (!ret)
ret = reg_write(icd, MT9M001_OUTPUT_CONTROL, 0);
Expand All @@ -133,8 +153,15 @@ static int mt9m001_init(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 */
reg_write(icd, MT9M001_OUTPUT_CONTROL, 0);

if (icl->power)
icl->power(&mt9m001->client->dev, 0);

return 0;
}

Expand Down
15 changes: 15 additions & 0 deletions drivers/media/video/mt9m111.c
Original file line number Diff line number Diff line change
Expand Up @@ -351,8 +351,18 @@ static int mt9m111_setfmt_yuv(struct soc_camera_device *icd)
static int mt9m111_enable(struct soc_camera_device *icd)
{
struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
struct soc_camera_link *icl = mt9m111->client->dev.platform_data;
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);
if (!ret)
mt9m111->powered = 1;
Expand All @@ -362,11 +372,16 @@ static int mt9m111_enable(struct soc_camera_device *icd)
static int mt9m111_disable(struct soc_camera_device *icd)
{
struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
struct soc_camera_link *icl = mt9m111->client->dev.platform_data;
int ret;

ret = reg_clear(RESET, MT9M111_RESET_CHIP_ENABLE);
if (!ret)
mt9m111->powered = 0;

if (icl->power)
icl->power(&mt9m111->client->dev, 0);

return ret;
}

Expand Down
24 changes: 23 additions & 1 deletion drivers/media/video/mt9v022.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd);
struct soc_camera_link *icl = mt9v022->client->dev.platform_data;
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
* undocumented bit 0x200, which is present in table 7, but not in 8,
* plus snapshot mode to disable scan for now */
Expand All @@ -161,7 +178,12 @@ static int mt9v022_init(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;
}

Expand Down
24 changes: 0 additions & 24 deletions drivers/media/video/pxa_camera.c
Original file line number Diff line number Diff line change
Expand Up @@ -629,17 +629,6 @@ static void pxa_camera_activate(struct pxa_camera_dev *pcdev)
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 */

if (pcdev->platform_flags & PXA_CAMERA_PCLK_EN)
Expand All @@ -660,20 +649,7 @@ static void pxa_camera_activate(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);

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)
Expand Down
5 changes: 0 additions & 5 deletions drivers/media/video/sh_mobile_ceu_camera.c
Original file line number Diff line number Diff line change
Expand Up @@ -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",
icd->devnum);

if (pcdev->pdata->enable_camera)
pcdev->pdata->enable_camera();

ret = icd->ops->init(icd);
if (ret)
goto err;
Expand All @@ -333,8 +330,6 @@ static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd)
ceu_write(pcdev, CEIER, 0);
ceu_write(pcdev, CAPSR, 1 << 16); /* reset */
icd->ops->release(icd);
if (pcdev->pdata->disable_camera)
pcdev->pdata->disable_camera();

dev_info(&icd->dev,
"SuperH Mobile CEU driver detached from camera %d\n",
Expand Down
2 changes: 0 additions & 2 deletions include/media/sh_mobile_ceu.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@

struct sh_mobile_ceu_info {
unsigned long flags; /* SOCAM_... */
void (*enable_camera)(void);
void (*disable_camera)(void);
};

#endif /* __ASM_SH_MOBILE_CEU_H__ */
3 changes: 3 additions & 0 deletions include/media/soc_camera.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@ struct soc_camera_link {
int bus_id;
/* GPIO number to switch between 8 and 10 bit modes */
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)
Expand Down

0 comments on commit 8103466

Please sign in to comment.