aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-s3c2442/Kconfig2
-rw-r--r--arch/arm/mach-s3c2442/Makefile4
-rw-r--r--arch/arm/mach-s3c2442/gta02-pm-bt.c1
-rw-r--r--arch/arm/mach-s3c2442/gta02-pm-gsm.c24
-rw-r--r--arch/arm/mach-s3c2442/include/mach/gta02.h3
-rw-r--r--arch/arm/mach-s3c2442/mach-gta02.c137
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 = &gta02_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[] = {
+ &gta02_gsm_supply_device,
+};
+
+static struct platform_device* gta02_gsm_supply_children[] = {
+ &gta02_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 */