diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-22 16:47:51 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-22 16:47:51 -0700 |
commit | 7992018d979460af59fbae8a48f9641305aea438 (patch) | |
tree | de64367c49aa76606e7ea8354b299d067f1c0bda /drivers/media/video/cafe_ccic.c | |
parent | 5fd52203e1856ad925b1a6adae9a22e533da94e2 (diff) | |
parent | edd75ede2d40eadb98e07d87e88fa970f86ffe9e (diff) |
Merge branch 'master' of ssh://master.kernel.org/pub/scm/linux/kernel/git/mchehab/v4l-dvb
* 'master' of ssh://master.kernel.org/pub/scm/linux/kernel/git/mchehab/v4l-dvb:
V4L/DVB (5691): Ov7670: reset clkrc in rgb565 mode
V4L/DVB (5690): Cafe_ccic: Properly power down the sensor
V4L/DVB (5680): Tuner-simple.c fix suport for SECAM with FI1216MF
V4L/DVB (5630): Dvb-core: Handle failures to create devices
V4L/DVB (5639a): Fix dst usage count
V4L/DVB (5670): Adding new fields to v4l2_pix_format broke the ABI, reverted that change
V4L/DVB (5640): Fix: em28xx shouldn't be selecting VIDEO_BUF
V4L/DVB (5639): Fix Kconfig dependencies for ivtv
Diffstat (limited to 'drivers/media/video/cafe_ccic.c')
-rw-r--r-- | drivers/media/video/cafe_ccic.c | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c index 96254dbaf62..c08f650df42 100644 --- a/drivers/media/video/cafe_ccic.c +++ b/drivers/media/video/cafe_ccic.c @@ -775,6 +775,12 @@ static void cafe_ctlr_power_up(struct cafe_camera *cam) spin_lock_irqsave(&cam->dev_lock, flags); cafe_reg_clear_bit(cam, REG_CTRL1, C1_PWRDWN); /* + * Part one of the sensor dance: turn the global + * GPIO signal on. + */ + cafe_reg_write(cam, REG_GL_FCR, GFCR_GPIO_ON); + cafe_reg_write(cam, REG_GL_GPIOR, GGPIO_OUT|GGPIO_VAL); + /* * Put the sensor into operational mode (assumes OLPC-style * wiring). Control 0 is reset - set to 1 to operate. * Control 1 is power down, set to 0 to operate. @@ -784,6 +790,7 @@ static void cafe_ctlr_power_up(struct cafe_camera *cam) cafe_reg_write(cam, REG_GPR, GPR_C1EN|GPR_C0EN|GPR_C0); // mdelay(1); /* Enough? */ spin_unlock_irqrestore(&cam->dev_lock, flags); + msleep(5); /* Just to be sure */ } static void cafe_ctlr_power_down(struct cafe_camera *cam) @@ -792,6 +799,8 @@ static void cafe_ctlr_power_down(struct cafe_camera *cam) spin_lock_irqsave(&cam->dev_lock, flags); cafe_reg_write(cam, REG_GPR, GPR_C1EN|GPR_C0EN|GPR_C1); + cafe_reg_write(cam, REG_GL_FCR, GFCR_GPIO_ON); + cafe_reg_write(cam, REG_GL_GPIOR, GGPIO_OUT); cafe_reg_set_bit(cam, REG_CTRL1, C1_PWRDWN); spin_unlock_irqrestore(&cam->dev_lock, flags); } @@ -851,6 +860,7 @@ static int cafe_cam_init(struct cafe_camera *cam) ret = 0; cam->state = S_IDLE; out: + cafe_ctlr_power_down(cam); mutex_unlock(&cam->s_mutex); return ret; } @@ -2103,10 +2113,16 @@ static int cafe_pci_probe(struct pci_dev *pdev, ret = request_irq(pdev->irq, cafe_irq, IRQF_SHARED, "cafe-ccic", cam); if (ret) goto out_iounmap; + /* + * Initialize the controller and leave it powered up. It will + * stay that way until the sensor driver shows up. + */ cafe_ctlr_init(cam); cafe_ctlr_power_up(cam); /* - * Set up I2C/SMBUS communications + * Set up I2C/SMBUS communications. We have to drop the mutex here + * because the sensor could attach in this call chain, leading to + * unsightly deadlocks. */ mutex_unlock(&cam->s_mutex); /* attach can deadlock */ ret = cafe_smbus_setup(cam); |