aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTaeyoung Kim <ktyrun@insignal.co.kr>2013-02-22 16:50:13 +0900
committerTaeyoung Kim <ktyrun@insignal.co.kr>2013-02-22 16:50:13 +0900
commit08b54ab48c7002ceba7429c012c4f4cf0513b472 (patch)
tree1e07b0d2eec6e2e0bdc6af4b621711c04293597d
parent0771c8ad8dbecc4e930100242c7afff695bf8873 (diff)
ARM: EXYNOS: ARNDALE: Added CSR GPS power control device.arndale-jb_mr1-es4arndale-jb_mr1-20130308
Signed-off-by: Taeyoung Kim <ktyrun@insignal.co.kr>
-rw-r--r--arch/arm/configs/arndale_android_defconfig1
-rw-r--r--arch/arm/mach-exynos/Makefile3
-rw-r--r--arch/arm/mach-exynos/board-arndale-gps.c36
-rw-r--r--arch/arm/mach-exynos/board-arndale.h3
-rw-r--r--arch/arm/mach-exynos/include/mach/gcontrol.h10
-rw-r--r--arch/arm/mach-exynos/mach-arndale.c3
-rw-r--r--drivers/misc/Kconfig7
-rw-r--r--drivers/misc/Makefile1
-rw-r--r--drivers/misc/gcontrol.c271
9 files changed, 335 insertions, 0 deletions
diff --git a/arch/arm/configs/arndale_android_defconfig b/arch/arm/configs/arndale_android_defconfig
index 1bf9f9fb10b..295f8f4bda8 100644
--- a/arch/arm/configs/arndale_android_defconfig
+++ b/arch/arm/configs/arndale_android_defconfig
@@ -177,6 +177,7 @@ CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=8192
CONFIG_UID_STAT=y
+CONFIG_GPS_POWER=y
CONFIG_SCSI=y
CONFIG_BLK_DEV_SD=y
CONFIG_CHR_DEV_SG=y
diff --git a/arch/arm/mach-exynos/Makefile b/arch/arm/mach-exynos/Makefile
index 526e78cb102..0d234c17e79 100644
--- a/arch/arm/mach-exynos/Makefile
+++ b/arch/arm/mach-exynos/Makefile
@@ -103,6 +103,9 @@ obj-$(CONFIG_MACH_ARNDALE) += board-arndale-tvout.o
obj-$(CONFIG_MACH_ARNDALE) += board-arndale-camera.o
obj-$(CONFIG_MACH_ARNDALE) += board-arndale-wifi.o
obj-$(CONFIG_MACH_ARNDALE) += board-arndale-sensors.o
+ifeq ($(CONFIG_GPS_POWER),y)
+obj-$(CONFIG_MACH_ARNDALE) += board-arndale-gps.o
+endif
# device support
diff --git a/arch/arm/mach-exynos/board-arndale-gps.c b/arch/arm/mach-exynos/board-arndale-gps.c
new file mode 100644
index 00000000000..6555453c41d
--- /dev/null
+++ b/arch/arm/mach-exynos/board-arndale-gps.c
@@ -0,0 +1,36 @@
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/module.h>
+#include <mach/gpio.h>
+#include <plat/gpio-cfg.h>
+
+#include <mach/gcontrol.h>
+
+#define CUSTOM_GPIO_GPS_POWER_EN EXYNOS5_GPX0(7)
+#define CUSTOM_GPIO_GPS_RESET EXYNOS5_GPB1(2)
+
+struct csr_platform_data csr_platdata = {
+ .power = CUSTOM_GPIO_GPS_POWER_EN,
+ .reset = CUSTOM_GPIO_GPS_RESET,
+};
+
+static struct platform_device csr_gps = {
+ .name = "csrgps",
+ .id = -1,
+ .dev = {
+ .platform_data = &csr_platdata,
+ },
+};
+
+static struct platform_device *arndale_gps_devs[] __initdata = {
+ &csr_gps,
+};
+
+void __init exynos5_arndale_gps_init(void)
+{
+ platform_add_devices(arndale_gps_devs, ARRAY_SIZE(arndale_gps_devs));
+}
+
diff --git a/arch/arm/mach-exynos/board-arndale.h b/arch/arm/mach-exynos/board-arndale.h
index 127166cd2d9..e3633e4ab67 100644
--- a/arch/arm/mach-exynos/board-arndale.h
+++ b/arch/arm/mach-exynos/board-arndale.h
@@ -51,5 +51,8 @@ void exynos5_smdk5250_tvout_init(void);
void exynos5_smdk5250_camera_init(void);
void exynos5_arndale_wifi_init(void);
void exynos5_arndale_sensors_init(void);
+#ifdef CONFIG_GPS_POWER
+void exynos5_arndale_gps_init(void);
+#endif
#endif
diff --git a/arch/arm/mach-exynos/include/mach/gcontrol.h b/arch/arm/mach-exynos/include/mach/gcontrol.h
new file mode 100644
index 00000000000..83b825dd302
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/gcontrol.h
@@ -0,0 +1,10 @@
+#ifndef __MACH_GCONTROL_H__
+#define __MACH_GCONTROL_H__
+
+
+struct csr_platform_data {
+ unsigned int power;
+ unsigned int reset;
+};
+
+#endif
diff --git a/arch/arm/mach-exynos/mach-arndale.c b/arch/arm/mach-exynos/mach-arndale.c
index 6d38e1c3e24..3be94672bea 100644
--- a/arch/arm/mach-exynos/mach-arndale.c
+++ b/arch/arm/mach-exynos/mach-arndale.c
@@ -491,6 +491,9 @@ static void __init smdk5250_machine_init(void)
exynos5_smdk5250_sysfs_soc_init();
exynos5_arndale_wifi_init();
exynos5_arndale_sensors_init();
+#ifdef CONFIG_GPS_POWER
+ exynos5_arndale_gps_init();
+#endif
}
MACHINE_START(ARNDALE, "ARNDALE")
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 86074226b2d..52a6e9eb8f7 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -554,6 +554,13 @@ config AUDIENCE_ES305
The ES305 is a Voice Processor with integrated DSP that processes
i2s audio data to provide noise suppression and echo cancellation.
+config GPS_POWER
+ tristate "GPS Power Driver"
+ depends on MACH_ARNDALE
+ default n
+ help
+ Say Y here to enable support for gps power control
+
source "drivers/misc/c2port/Kconfig"
source "drivers/misc/eeprom/Kconfig"
source "drivers/misc/cb710/Kconfig"
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index f42af7abc20..f745db7a5a1 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -56,3 +56,4 @@ obj-$(CONFIG_WL127X_RFKILL) += wl127x-rfkill.o
obj-$(CONFIG_SENSORS_AK8975) += akm8975.o
obj-$(CONFIG_STMPE811_ADC) += stmpe811-adc.o
obj-$(CONFIG_AUDIENCE_ES305) += es305.o
+obj-$(CONFIG_GPS_POWER) += gcontrol.o
diff --git a/drivers/misc/gcontrol.c b/drivers/misc/gcontrol.c
new file mode 100644
index 00000000000..8ee328d8f34
--- /dev/null
+++ b/drivers/misc/gcontrol.c
@@ -0,0 +1,271 @@
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/miscdevice.h>
+#include <linux/platform_device.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/fs.h>
+#include <linux/gpio.h>
+
+#include <plat/gpio-cfg.h>
+#include <mach/gcontrol.h>
+
+unsigned int gps_gpio=0;
+unsigned int gps_reset_gpio=0;
+
+int gps_power_control(unsigned int pw, int onoff);
+int gps_reset_control(unsigned int rst, int onoff);
+
+
+static int __devinit csr_gps_drv_probe(struct platform_device *pdev)
+{
+ int ret;
+ struct csr_platform_data *p = (struct csr_platform_data *)pdev->dev.platform_data;
+
+ gps_gpio = p->power;
+ gps_reset_gpio = p->reset;
+
+ ret = gps_power_control( gps_gpio, 0 );
+
+ if(ret)
+ {
+ printk("============ not gps power probe !!!!! ===============\n");
+ return ret;
+ }
+ printk("============ gps power probe !!!!! ===============\n");
+
+ ret = gps_reset_control( gps_reset_gpio, 1 );
+
+ if(ret == 0)
+ {
+ printk("============ not gps reset probe !!!!! ===============\n");
+ return ret;
+ }
+ printk("============ gps reset probe !!!!! ===============\n");
+
+ return 0;
+}
+
+int gps_power_control(unsigned int pw, int onoff)
+{
+ s3c_gpio_cfgpin(pw, S3C_GPIO_SFN(1));
+ s3c_gpio_setpull(pw, S3C_GPIO_PULL_NONE);
+ gpio_set_value(pw, !!(onoff));
+ return gpio_get_value(pw);
+}
+
+int gps_reset_control(unsigned int rst, int onoff)
+{
+ s3c_gpio_cfgpin(rst, S3C_GPIO_SFN(1));
+ s3c_gpio_setpull(rst, S3C_GPIO_PULL_UP);
+ gpio_set_value(rst, !!(onoff));
+ return gpio_get_value(rst);
+}
+
+static int __devexit csr_gps_drv_remove(struct platform_device *pdev)
+{
+ return 0;
+}
+
+static int gps_power = 0;
+static int gps_reset = 1;
+
+long
+gps_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ int err = 0;
+ switch (cmd)
+ {
+ case 0:
+ if (gps_power != 0)
+ gps_power = gps_power_control(gps_gpio,0);
+ if (gps_power != 0)
+ err = -1;
+ break;
+ default:
+ case 1:
+ if (gps_power == 0)
+ gps_power = gps_power_control(gps_gpio,1);
+ if (gps_power == 0)
+ err = -1;
+ break;
+ }
+ return err;
+}
+
+ssize_t
+gps_read(struct file *filp, char *userbuf, size_t count, loff_t *f_pos)
+{
+ char buf[2] = { '0' + gps_power, 0 };
+ return simple_read_from_buffer(userbuf, count, f_pos, buf, sizeof(buf));
+}
+
+ssize_t
+gps_write(struct file *filp, const char *userbuf, size_t count, loff_t *f_pos)
+{
+ if (count > 0)
+ {
+ int state = simple_strtoul(userbuf, NULL, 10) ? 1 : 0;
+ if (gps_power != state)
+ gps_power = gps_power_control(gps_gpio, state);
+ }
+ return count;
+}
+
+int
+gps_open(struct inode *inode, struct file *filp)
+{
+ if( !try_module_get(THIS_MODULE) )
+ return -ENODEV;
+ return 0;
+}
+
+int
+gps_release(struct inode *inode, struct file *filp)
+{
+ module_put(THIS_MODULE);
+ return 0;
+}
+
+struct file_operations gps_fops =
+{
+ .owner = THIS_MODULE,
+ .read = gps_read,
+ .write = gps_write,
+ .unlocked_ioctl = gps_ioctl,
+ .open = gps_open,
+ .release = gps_release,
+};
+
+struct miscdevice gps_miscdev =
+{
+ MISC_DYNAMIC_MINOR,
+ "gcontrol",
+ &gps_fops
+};
+
+long
+gps_reset_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ int err = 0;
+ switch (cmd)
+ {
+ case 0:
+ if (gps_reset != 0)
+ gps_reset = gps_reset_control(gps_reset_gpio,0);
+ if (gps_reset != 0)
+ err = -1;
+ break;
+ default:
+ case 1:
+ if (gps_reset == 0)
+ gps_reset = gps_reset_control(gps_reset_gpio,1);
+ if (gps_reset == 0)
+ err = -1;
+ break;
+ }
+ return err;
+}
+
+ssize_t
+gps_reset_read(struct file *filp, char *userbuf, size_t count, loff_t *f_pos)
+{
+ char buf[2] = { '0' + gps_reset, 0 };
+ return simple_read_from_buffer(userbuf, count, f_pos, buf, sizeof(buf));
+}
+
+ssize_t
+gps_reset_write(struct file *filp, const char *userbuf, size_t count, loff_t *f_pos)
+{
+ if (count > 0)
+ {
+ int state = simple_strtoul(userbuf, NULL, 10) ? 1 : 0;
+ if (gps_reset != state)
+ gps_reset = gps_reset_control(gps_reset_gpio, state);
+ }
+ return count;
+}
+
+int
+gps_reset_open(struct inode *inode, struct file *filp)
+{
+ if( !try_module_get(THIS_MODULE) )
+ return -ENODEV;
+ return 0;
+}
+
+int
+gps_reset_release(struct inode *inode, struct file *filp)
+{
+ module_put(THIS_MODULE);
+ return 0;
+}
+
+struct file_operations gps_reset_fops =
+{
+ .owner = THIS_MODULE,
+ .read = gps_reset_read,
+ .write = gps_reset_write,
+ .unlocked_ioctl = gps_reset_ioctl,
+ .open = gps_reset_open,
+ .release = gps_reset_release,
+};
+
+struct miscdevice gps_reset_miscdev =
+{
+ MISC_DYNAMIC_MINOR,
+ "gpsreset",
+ &gps_reset_fops
+};
+
+static struct platform_driver csr_gps_driver = {
+ .probe = csr_gps_drv_probe,
+ .remove = __devexit_p(csr_gps_drv_remove),
+ .driver = {
+ .name = "csrgps",
+ .owner = THIS_MODULE,
+ },
+ .suspend = NULL,
+ .resume = NULL,
+};
+
+static int __init
+gps_init(void)
+{
+ int ret;
+
+ ret = platform_driver_register(&csr_gps_driver);
+ if(ret)
+ return ret;
+
+ gps_power_control(gps_gpio,0);
+
+ ret = misc_register(&gps_miscdev);
+ if(ret)
+ return ret;
+
+ ret = misc_register(&gps_reset_miscdev);
+ if(ret)
+ return ret;
+
+ return 0;
+}
+
+static void __exit
+gps_exit(void)
+{
+ gps_power_control(gps_gpio,0);
+ gps_reset_control(gps_reset_gpio,0);
+ platform_driver_unregister(&csr_gps_driver);
+ misc_deregister(&gps_miscdev);
+ misc_deregister(&gps_reset_miscdev);
+}
+
+module_init(gps_init);
+module_exit(gps_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("GPS Power Driver");
+