diff options
-rw-r--r-- | arch/arm/mach-s3c2442/Kconfig | 2 | ||||
-rw-r--r-- | arch/arm/mach-s3c2442/Makefile | 4 | ||||
-rw-r--r-- | arch/arm/mach-s3c2442/gta02-pm-bt.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-s3c2442/gta02-pm-gsm.c | 24 | ||||
-rw-r--r-- | arch/arm/mach-s3c2442/include/mach/gta02.h | 3 | ||||
-rw-r--r-- | arch/arm/mach-s3c2442/mach-gta02.c | 137 |
6 files changed, 152 insertions, 19 deletions
diff --git a/arch/arm/mach-s3c2442/Kconfig b/arch/arm/mach-s3c2442/Kconfig index bdb37dd567d..194d128c695 100644 --- a/arch/arm/mach-s3c2442/Kconfig +++ b/arch/arm/mach-s3c2442/Kconfig @@ -34,10 +34,10 @@ config MACH_NEO1973_GTA02 select MACH_NEO1973 select S3C2410_PWM select S3C_DEV_USB_HOST - select S3C_DEV_NAND select FIQ select S3C_PWM select S3C24XX_GPIO_EXTRA64 + select S3C_DEV_NAND help Say Y here if you are using the Openmoko GTA02 / Freerunner GSM Phone diff --git a/arch/arm/mach-s3c2442/Makefile b/arch/arm/mach-s3c2442/Makefile index cf39481cb5c..6247ca03eae 100644 --- a/arch/arm/mach-s3c2442/Makefile +++ b/arch/arm/mach-s3c2442/Makefile @@ -13,10 +13,10 @@ obj-$(CONFIG_CPU_S3C2442) += s3c2442.o obj-$(CONFIG_CPU_S3C2442) += clock.o obj-$(CONFIG_MACH_NEO1973_GTA02) += mach-gta02.o \ + gta02-fiq.o \ gta02-pm-bt.o \ gta02-pm-gps.o \ gta02-pm-gsm.o \ - gta02-pm-wlan.o \ - gta02-fiq.o + gta02-pm-wlan.o # Machine support diff --git a/arch/arm/mach-s3c2442/gta02-pm-bt.c b/arch/arm/mach-s3c2442/gta02-pm-bt.c index 76671ce96d0..8bb2a12f7c5 100644 --- a/arch/arm/mach-s3c2442/gta02-pm-bt.c +++ b/arch/arm/mach-s3c2442/gta02-pm-bt.c @@ -23,7 +23,6 @@ #include <asm/mach-types.h> #include <mach/gta02.h> -#include <linux/mfd/pcf50633/gpio.h> #include <linux/regulator/consumer.h> diff --git a/arch/arm/mach-s3c2442/gta02-pm-gsm.c b/arch/arm/mach-s3c2442/gta02-pm-gsm.c index 4b6cad806fe..70a94cb3f24 100644 --- a/arch/arm/mach-s3c2442/gta02-pm-gsm.c +++ b/arch/arm/mach-s3c2442/gta02-pm-gsm.c @@ -19,6 +19,8 @@ #include <linux/errno.h> #include <linux/interrupt.h> #include <linux/delay.h> +#include <linux/err.h> +#include <linux/regulator/consumer.h> #include <mach/gpio.h> #include <asm/mach-types.h> @@ -26,7 +28,6 @@ #include <mach/hardware.h> #include <mach/gta02.h> -#include <linux/mfd/pcf50633/gpio.h> #include <mach/regs-gpio.h> #include <mach/regs-gpioj.h> @@ -38,6 +39,7 @@ extern void s3c24xx_serial_console_set_silence(int); struct gta02pm_priv { int gpio_ndl_gsm; struct console *con; + struct regulator *regulator; }; static struct gta02pm_priv gta02_gsm; @@ -62,7 +64,7 @@ static ssize_t gsm_read(struct device *dev, struct device_attribute *attr, char *buf) { if (!strcmp(attr->attr.name, "power_on")) { - if (pcf50633_gpio_get(gta02_pcf, PCF50633_GPIO2)) + if (regulator_is_enabled(gta02_gsm.regulator)) goto out_1; } else if (!strcmp(attr->attr.name, "download")) { if (!s3c2410_gpio_getpin(GTA02_GPIO_nDL_GSM)) @@ -79,11 +81,17 @@ out_1: static void gsm_on_off(struct device *dev, int on) { + + on = !!on; + + if (on == regulator_is_enabled(gta02_gsm.regulator)) + return; + if (!on) { s3c2410_gpio_cfgpin(S3C2410_GPH(1), S3C2410_GPIO_INPUT); s3c2410_gpio_cfgpin(S3C2410_GPH(2), S3C2410_GPIO_INPUT); - pcf50633_gpio_set(gta02_pcf, PCF50633_GPIO2, 0); + regulator_disable(gta02_gsm.regulator); if (gta02_gsm.con) { s3c24xx_serial_console_set_silence(0); @@ -108,7 +116,7 @@ static void gsm_on_off(struct device *dev, int on) s3c2410_gpio_cfgpin(S3C2410_GPH(1), S3C2410_GPH1_nRTS0); s3c2410_gpio_cfgpin(S3C2410_GPH(2), S3C2410_GPH2_TXD0); - pcf50633_gpio_set(gta02_pcf, PCF50633_GPIO2, 7); + regulator_enable(gta02_gsm.regulator); msleep(100); @@ -264,6 +272,14 @@ static int __init gta02_gsm_probe(struct platform_device *pdev) gta02_gsm.gpio_ndl_gsm = 1; s3c2410_gpio_setpin(GTA02_GPIO_nDL_GSM, 1); + gta02_gsm.regulator = regulator_get_exclusive(&pdev->dev, "GSM"); + + if (IS_ERR(gta02_gsm.regulator)) { + dev_err(&pdev->dev, "Failed to get regulator: %d\n", + PTR_ERR(gta02_gsm.regulator)); + return PTR_ERR(gta02_gsm.regulator); + } + /* GSM is to be initially off (at boot, or if this module inserted) */ gsm_on_off(&pdev->dev, 0); diff --git a/arch/arm/mach-s3c2442/include/mach/gta02.h b/arch/arm/mach-s3c2442/include/mach/gta02.h index b67e5ec2919..6db48d4ff61 100644 --- a/arch/arm/mach-s3c2442/include/mach/gta02.h +++ b/arch/arm/mach-s3c2442/include/mach/gta02.h @@ -83,6 +83,9 @@ #define GTA02_GPIO_GLAMO_BASE S3C_GPIO_END #define GTA02_GPIO_GLAMO(x) (GTA02_GPIO_GLAMO_BASE + (x)) +#define GTA02_GPIO_PCF_BASE (GTA02_GPIO_GLAMO_BASE + 32) +#define GTA02_GPIO_PCF(x) (GTA02_GPIO_PCF_BASE + (x)) + int gta02_get_pcb_revision(void); extern struct pcf50633 *gta02_pcf; diff --git a/arch/arm/mach-s3c2442/mach-gta02.c b/arch/arm/mach-s3c2442/mach-gta02.c index 1480881268c..74bd5564ec8 100644 --- a/arch/arm/mach-s3c2442/mach-gta02.c +++ b/arch/arm/mach-s3c2442/mach-gta02.c @@ -259,7 +259,6 @@ static struct glamo_mmc_platform_data gta02_glamo_mmc_pdata = { static struct glamo_gpio_platform_data gta02_glamo_gpio_pdata = { .base = GTA02_GPIO_GLAMO_BASE, - .registered = gta02_glamo_registered, }; static struct glamo_platform_data gta02_glamo_pdata = { @@ -314,6 +313,39 @@ static struct platform_device gta02_pm_wlan_dev = { .name = "gta02-pm-wlan", }; +static struct regulator_consumer_supply gsm_supply_consumer = { + .dev = >a02_pm_gsm_dev.dev, + .supply = "GSM", +}; + +static struct regulator_init_data gsm_supply_init_data = { + .constraints = { + .min_uV = 3700000, + .max_uV = 3700000, + .valid_modes_mask = REGULATOR_MODE_NORMAL, + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = 1, + .consumer_supplies = &gsm_supply_consumer, +}; + +static struct fixed_voltage_config gsm_supply_config = { + .supply_name = "GSM", + .microvolts = 3700000, + .gpio = GTA02_GPIO_PCF(PCF50633_GPIO2), + .enable_high = 1, + .init_data = &gsm_supply_init_data, +}; + +static struct platform_device gta02_gsm_supply_device = { + .name = "reg-fixed-voltage", + .id = 1, + .dev = { + .platform_data = &gsm_supply_config, + }, +}; + + #ifdef CONFIG_CHARGER_PCF50633 /* * On GTA02 the 1A charger features a 48K resistor to 0V on the ID pin. @@ -352,7 +384,7 @@ gta02_configure_pmu_for_charger(struct pcf50633 *pcf, void *unused, int res) * Sanity - stop GPO driving out now that we have a 1A charger * GPO controls USB Host power generation on GTA02 */ - pcf50633_gpio_set(pcf, PCF50633_GPO, 0); + /*pcf50633_gpio_set(pcf, PCF50633_GPO, 0);*/ ma = 1000; } else @@ -723,7 +755,6 @@ static void gta02_jbt6k74_probe_completed(struct device *dev) } const struct jbt6k74_platform_data jbt6k74_pdata = { - .probe_completed = gta02_jbt6k74_probe_completed, .gpio_reset = GTA02_GPIO_GLAMO(4), }; @@ -871,12 +902,6 @@ struct platform_device gta02_platform_bat = { /* HDQ */ -static void gta02_hdq_attach_child_devices(struct device *parent_device) -{ - bq27000_battery_device.dev.parent = parent_device; - platform_device_register(&bq27000_battery_device); -} - static void gta02_hdq_gpio_direction_out(void) { s3c2410_gpio_cfgpin(GTA02v5_GPIO_HDQ, S3C2410_GPIO_OUTPUT); @@ -1037,7 +1062,6 @@ const static struct s3c2410_ts_mach_info gta02_ts_cfg = { }; struct hdq_platform_data gta02_hdq_platform_data = { - .attach_child_devices = gta02_hdq_attach_child_devices, .gpio_dir_out = gta02_hdq_gpio_direction_out, .gpio_dir_in = gta02_hdq_gpio_direction_in, .gpio_set = gta02_hdq_gpio_set_value, @@ -1046,7 +1070,6 @@ struct hdq_platform_data gta02_hdq_platform_data = { .enable_fiq = gta02_fiq_enable, .disable_fiq = gta02_fiq_disable, .kick_fiq = gta02_fiq_kick, - }; struct platform_device gta02_hdq_device = { @@ -1130,6 +1153,98 @@ static void gta02_poweroff(void) pcf50633_reg_set_bit_mask(gta02_pcf, PCF50633_REG_OOCSHDWN, 1, 1); } + +struct gta02_device_children { + const char *dev_name; + size_t num_children; + struct platform_device **children; + void (*probed_callback)(struct device *dev); +}; + +static struct platform_device* gta02_glamo_gpio_children[] = { + &spigpio_device, +}; + +static struct platform_device* gta02_pcf50633_gpio_children[] = { + >a02_gsm_supply_device, +}; + +static struct platform_device* gta02_gsm_supply_children[] = { + >a02_pm_gsm_dev, +}; + +static struct platform_device* gta02_hdq_children[] = { + &bq27000_battery_device, +}; + +static struct gta02_device_children gta02_device_children[] = { + { + .dev_name = "glamo-gpio.0", + .num_children = 1, + .children = gta02_glamo_gpio_children, + }, + { + .dev_name = "hdq.0", + .num_children = 1, + .children = gta02_hdq_children, + }, + { + .dev_name = "spi2.0", + .probed_callback = gta02_jbt6k74_probe_completed, + }, + { + .dev_name = "pcf50633-gpio", + .num_children = 1, + .children = gta02_pcf50633_gpio_children, + }, + { + .dev_name = "reg-fixed-voltage.1", + .num_children = 1, + .children = gta02_gsm_supply_children, + } +}; + +static int gta02_add_child_devices(struct device *parent, + struct platform_device **children, + size_t num_children) +{ + size_t i; + + for (i = 0; i < num_children; ++i) + children[i]->dev.parent = parent; + + return platform_add_devices(children, num_children); +} + +static int gta02_device_registered(struct notifier_block *block, + unsigned long action, void *data) +{ + struct device *dev = data; + const char *devname = dev_name(dev); + size_t i; + + if (action != BUS_NOTIFY_BOUND_DRIVER) + return 0; + + for (i = 0; i < ARRAY_SIZE(gta02_device_children); ++i) { + if (strcmp(devname, gta02_device_children[i].dev_name) == 0) { + gta02_add_child_devices(dev, gta02_device_children[i].children, + gta02_device_children[i].num_children); + + if (gta02_device_children[i].probed_callback) + gta02_device_children[i].probed_callback(dev); + break; + } + } + + return 0; +} + +static struct notifier_block gta02_device_register_notifier = { + .notifier_call = gta02_device_registered, + .priority = INT_MAX, +}; + /* On hardware rev 5 and earlier the leds are missing a resistor and reading * from their gpio pins will always return 0, so we have to shadow the * led states software */ |