diff options
author | Taeyoung Kim <ktyrun@insignal.co.kr> | 2013-02-22 16:50:13 +0900 |
---|---|---|
committer | Taeyoung Kim <ktyrun@insignal.co.kr> | 2013-02-22 16:50:13 +0900 |
commit | 08b54ab48c7002ceba7429c012c4f4cf0513b472 (patch) | |
tree | 1e07b0d2eec6e2e0bdc6af4b621711c04293597d | |
parent | 0771c8ad8dbecc4e930100242c7afff695bf8873 (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_defconfig | 1 | ||||
-rw-r--r-- | arch/arm/mach-exynos/Makefile | 3 | ||||
-rw-r--r-- | arch/arm/mach-exynos/board-arndale-gps.c | 36 | ||||
-rw-r--r-- | arch/arm/mach-exynos/board-arndale.h | 3 | ||||
-rw-r--r-- | arch/arm/mach-exynos/include/mach/gcontrol.h | 10 | ||||
-rw-r--r-- | arch/arm/mach-exynos/mach-arndale.c | 3 | ||||
-rw-r--r-- | drivers/misc/Kconfig | 7 | ||||
-rw-r--r-- | drivers/misc/Makefile | 1 | ||||
-rw-r--r-- | drivers/misc/gcontrol.c | 271 |
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"); + |