[pkg-fso-commits] [SCM] linux-2.6-openmoko, the Linux 2.6 kernel tree from Openmoko branch, andy-tracking, updated. upstream/20090303.gitb9de904e-140-g23b564c

Andy Green agreen at octopus.localdomain
Mon Jun 8 17:29:46 UTC 2009


The following commit has been merged in the andy-tracking branch:
commit be03383f4a472291bcf747e959ffb208d3fd56ce
Author: Werner Almesberger <werner at openmoko.org>
Date:   Tue Mar 10 14:02:28 2009 +0000

    add primitive camera power control
    
    This dirty hack adds camera activation/deactivation on open/close.
    This code will have to move to a machine/platform area later. The
    general driver is the wrong place for it.
    
    It also removes the unconditional activation and moves the domain
    setting to the rest of the power control code. (Thanks, Andy !)
    
    Note that opening the camera now always takes about 20 seconds
    until the settings are downloaded, not just on the first open.
    
    Signed-off-by: Werner Almesberger <werner at openmoko.org>

diff --git a/arch/arm/mach-s3c6410/mach-om-3d7k.c b/arch/arm/mach-s3c6410/mach-om-3d7k.c
index e54abd8..74a88d6 100644
--- a/arch/arm/mach-s3c6410/mach-om-3d7k.c
+++ b/arch/arm/mach-s3c6410/mach-om-3d7k.c
@@ -69,9 +69,6 @@
 #include <plat/cpu.h>
 #include <plat/tzic-sp890.h>
 #include <plat/usb-control.h>
-/* temp -- move to camera driver along with _NORMAL register setting */
-#include <plat/regs-sys.h>
-#include <plat/regs-syscon-power.h>
 
 /* #include <plat/udc.h> */
 #include <linux/i2c.h>
@@ -1044,17 +1041,6 @@ static void om_3d7k_pcf50633_attach_child_devices(struct pcf50633 *pcf)
 	pcf50633_reg_write(pcf, PCF50633_REG_LEDENA, 0x00);
 	pcf50633_reg_write(pcf, PCF50633_REG_LEDDIM, 0x01);
 	pcf50633_reg_write(pcf, PCF50633_REG_LEDENA, 0x01);
-
-#ifdef CONFIG_S3C_DEV_CAMIF
-	/* @@@ do this properly later - WA */
-	pcf50633_reg_write(om_3d7k_pcf, 0x30, 0x21);
-	pcf50633_reg_write(om_3d7k_pcf, 0x39, 0x13);
-	pcf50633_reg_write(om_3d7k_pcf, 0x3a, 0x21);
-
-	/* so it doesn't get lost */
-	__raw_writel(__raw_readl(S3C64XX_NORMAL_CFG) |
-		     S3C64XX_NORMALCFG_DOMAIN_I_ON, S3C64XX_NORMAL_CFG);
-#endif
 }
 
 static void om_3d7k_l1k002_pwronoff(int level)
diff --git a/drivers/media/video/s3c_camera_driver.c b/drivers/media/video/s3c_camera_driver.c
index 1d3bffa..3be2734 100644
--- a/drivers/media/video/s3c_camera_driver.c
+++ b/drivers/media/video/s3c_camera_driver.c
@@ -51,6 +51,15 @@
 #include "s3c_camif.h"
 #include "videodev2_s3c.h"
 
+#include <linux/mfd/pcf50633/core.h>	/* @@@ hack - WA */
+#include <plat/gpio-bank-f.h>
+#include <plat/gpio-cfg.h>
+#include <mach/gpio.h>
+#include <mach/map.h>
+#include <plat/regs-sys.h>
+#include <plat/regs-syscon-power.h>
+
+
 static struct clk *cam_clock;
 camif_cfg_t s3c_fimc[CAMIF_DEV_NUM];
 extern camif_cis_t msdma_input;
@@ -1311,6 +1320,72 @@ long s3c_camif_ioctl(struct file *file, unsigned int cmd, unsigned long _arg)
 	}
 }
 
+
+void om_3d7k_camera_on(void)
+{
+	extern struct pcf50633 *om_3d7k_pcf;
+	int i;
+
+	gpio_direction_output(S3C64XX_GPF(3), 0);
+
+	/* @@@ hack - WA */
+	pcf50633_reg_write(om_3d7k_pcf, 0x30, 0x21);
+	for (i = 0; !(pcf50633_reg_read(om_3d7k_pcf, 0x42) & 0x02); i++) {
+		if (i == 100) {
+			printk(KERN_ERR "can't bring up LDO2\n");
+			break;
+		}
+		msleep(10);
+	}
+
+	pcf50633_reg_write(om_3d7k_pcf, 0x39, 0x13);
+	pcf50633_reg_write(om_3d7k_pcf, 0x3a, 0x21);
+	for (i = 0; !(pcf50633_reg_read(om_3d7k_pcf, 0x42) & 0x40); i++) {
+		if (i == 100) {
+			printk(KERN_ERR "can't bring up HCLDO\n");
+			break;
+		}
+		msleep(10);
+	}
+
+	msleep(100);	/* > 0 ms */
+
+	if (cam_clock)
+		clk_enable(cam_clock);
+
+	msleep(1);	/* > 100 cycles */
+	gpio_direction_output(S3C64XX_GPF(3), 1);
+	msleep(25);	/* > 1 Mcycles */
+	s3c_gpio_cfgpin(S3C64XX_GPF(3), S3C64XX_GPF3_CAMIF_nRST);
+	msleep(25);	/* just to be sure > 1 Mcycles */
+
+	__raw_writel(__raw_readl(S3C64XX_NORMAL_CFG) |
+	    S3C64XX_NORMALCFG_DOMAIN_I_ON, S3C64XX_NORMAL_CFG);
+}
+
+void om_3d7k_camera_off(void)
+{
+	extern struct pcf50633 *om_3d7k_pcf;
+
+	gpio_direction_output(S3C64XX_GPF(3), 0);
+
+	msleep(1);	/* > 20 cycles */
+
+	if (cam_clock)
+		clk_disable(cam_clock);
+	msleep(1);	/* > 0 ms */
+
+	/* @@@ hack - WA */
+	pcf50633_reg_write(om_3d7k_pcf, 0x3a, 0x20);	/* 2V8, ... */
+	pcf50633_reg_write(om_3d7k_pcf, 0x30, 0x20);	/* ... then 1V5 */
+
+#if 0
+	__raw_writel(__raw_readl(S3C64XX_NORMAL_CFG) &
+	    ~S3C64XX_NORMALCFG_DOMAIN_I_ON, S3C64XX_NORMAL_CFG);
+#endif
+}
+
+
 /* @@@ - WA */
 #define s3c_camif_exclusive_open(inode, file) 0
 #define s3c_camif_exclusive_release(inode, file)
@@ -1339,6 +1414,8 @@ int s3c_camif_open(struct file *file)
 		up(&cfg->cis->lock);
 	}
 
+	om_3d7k_camera_on();
+
 	err = s3c_camif_exclusive_open(inode, file);
 	cfg->cis->user++;
 	cfg->status = CAMIF_STOPPED;
@@ -1384,6 +1461,9 @@ int s3c_camif_release(struct file *file)
 	cfg->cis->user--;
 	cfg->status = CAMIF_STOPPED;
 
+	om_3d7k_camera_off();
+	cfg->cis->init_sensor = 0;
+
 	return 0;
 }
 
@@ -1753,9 +1833,6 @@ static int s3c_camif_probe(struct platform_device *pdev)
 		return PTR_ERR(cam_clock);
 	}
 
-printk("cam_clock %p\n", cam_clock);
-	clk_enable(cam_clock);
-
 	/* Print banner */
 	printk(KERN_INFO "S3C FIMC v%s\n", FIMC_VER);
 
diff --git a/drivers/media/video/samsung/4xa_sensor.c b/drivers/media/video/samsung/4xa_sensor.c
index b7f9061..1e3ca1c 100644
--- a/drivers/media/video/samsung/4xa_sensor.c
+++ b/drivers/media/video/samsung/4xa_sensor.c
@@ -215,8 +215,16 @@ s5k4xa_attach(struct i2c_adapter *adap, int addr, int kind)
 
 static int sensor_attach_adapter(struct i2c_adapter *adap)
 {
+	extern void om_3d7k_camera_on(void);
+	extern void om_3d7k_camera_off(void);
+	int ret;
+
 	s3c_camif_open_sensor(&data);
-	return i2c_probe(adap, &addr_data, s5k4xa_attach);
+
+	om_3d7k_camera_on();
+	ret = i2c_probe(adap, &addr_data, s5k4xa_attach);
+	om_3d7k_camera_off();
+	return ret;
 }
 
 static int sensor_detach(struct i2c_client *client)

-- 
linux-2.6-openmoko, the Linux 2.6 kernel tree from Openmoko



More information about the pkg-fso-commits mailing list