aboutsummaryrefslogtreecommitdiff
path: root/arch/arm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/mach-s3c2440/mach-gta02.c396
-rw-r--r--arch/arm/plat-s3c24xx/neo1973_pm_gps.c173
2 files changed, 281 insertions, 288 deletions
diff --git a/arch/arm/mach-s3c2440/mach-gta02.c b/arch/arm/mach-s3c2440/mach-gta02.c
index 5b537f70d56..b8811169743 100644
--- a/arch/arm/mach-s3c2440/mach-gta02.c
+++ b/arch/arm/mach-s3c2440/mach-gta02.c
@@ -45,6 +45,16 @@
#include <linux/mtd/partitions.h>
#include <linux/mtd/physmap.h>
+#include <linux/i2c.h>
+#include <linux/backlight.h>
+#include <linux/regulator/machine.h>
+
+#include <linux/mfd/pcf50633/core.h>
+#include <linux/mfd/pcf50633/mbc.h>
+#include <linux/mfd/pcf50633/adc.h>
+#include <linux/mfd/pcf50633/gpio.h>
+#include <linux/mfd/pcf50633/pmic.h>
+
#include <linux/lis302dl.h>
#include <asm/mach/arch.h>
@@ -98,17 +108,9 @@
#include <../drivers/input/touchscreen/ts_filter_median.h>
#include <../drivers/input/touchscreen/ts_filter_group.h>
-#include <linux/mfd/pcf50633/core.h>
-#include <linux/mfd/pcf50633/gpio.h>
-#include <linux/mfd/pcf50633/mbc.h>
-#include <linux/pcf506xx.h>
-
/* arbitrates which sensor IRQ owns the shared SPI bus */
static spinlock_t motion_irq_lock;
-static int gta02_charger_online_status;
-static int gta02_charger_active_status;
-
/* define FIQ IPC struct */
/*
* contains stuff FIQ ISR modifies and normal kernel code can see and use
@@ -473,14 +475,20 @@ static struct s3c2410_uartcfg gta02_uartcfgs[] = {
/* BQ27000 Battery */
+struct pcf50633 *gta02_pcf;
+
static int gta02_get_charger_online_status(void)
{
- return gta02_charger_online_status;
+ struct pcf50633 *pcf = gta02_pcf;
+
+ return pcf50633_mbc_get_status(pcf) & PCF50633_MBC_USB_ONLINE;
}
static int gta02_get_charger_active_status(void)
{
- return gta02_charger_active_status;
+ struct pcf50633 *pcf = gta02_pcf;
+
+ return pcf50633_mbc_get_status(pcf) & PCF50633_MBC_USB_ACTIVE;
}
@@ -522,10 +530,10 @@ gta02_configure_pmu_for_charger(struct pcf50633 *pcf, void *unused, int res)
pcf50633_mbc_usb_curlim_set(pcf, ma);
}
-/* PMU driver info */
+static struct delayed_work gta02_charger_work;
+static int gta02_usb_vbus_draw;
-static int pmu_callback(struct device *dev, unsigned int feature,
- enum pmu_event event)
+static void gta02_charger_worker(struct work_struct *work)
{
struct pcf50633 *pcf = gta02_pcf;
@@ -539,9 +547,19 @@ static int pmu_callback(struct device *dev, unsigned int feature,
gta02_configure_pmu_for_charger, NULL);
return;
}
+}
- bq27000_charging_state_change(&bq27000_battery_device);
- return 0;
+#define GTA02_CHARGER_CONFIGURE_TIMEOUT ((3000 * HZ) / 1000)
+static void gta02_pmu_event_callback(struct pcf50633 *pcf, int irq)
+{
+ if (irq == PCF50633_IRQ_USBINS) {
+ schedule_delayed_work(&gta02_charger_work,
+ GTA02_CHARGER_CONFIGURE_TIMEOUT);
+ return;
+ } else if (irq == PCF50633_IRQ_USBREM) {
+ cancel_delayed_work_sync(&gta02_charger_work);
+ gta02_usb_vbus_draw = 0;
+ }
}
static struct platform_device gta01_pm_gps_dev = {
@@ -566,7 +584,8 @@ static struct platform_device gta02_pm_gsm_dev = {
static struct platform_device gta02_glamo_dev;
static void mangle_glamo_res_by_system_rev(void);
-static void gta02_pcf50633_attach_child_devices(struct device *parent_device);
+static void gta02_pmu_attach_child_devices(struct pcf50633 *pcf);
+static void gta02_pmu_regulator_registered(struct pcf50633 *pcf, int id);
static struct platform_device gta02_pm_wlan_dev = {
.name = "gta02-pm-wlan",
@@ -606,22 +625,21 @@ static char *gta02_batteries[] = {
struct pcf50633_platform_data gta02_pcf_pdata = {
.resumers = {
- [0] = PCF50633_INT1_USBINS |
- PCF50633_INT1_USBREM |
- PCF50633_INT1_ALARM,
- [1] = PCF50633_INT2_ONKEYF,
- [2] = PCF50633_INT3_ONKEY1S
+ [0] = PCF50633_INT1_USBINS |
+ PCF50633_INT1_USBREM |
+ PCF50633_INT1_ALARM,
+ [1] = PCF50633_INT2_ONKEYF,
+ [2] = PCF50633_INT3_ONKEY1S,
+ [3] = PCF50633_INT4_LOWSYS |
+ PCF50633_INT4_LOWBAT |
+ PCF50633_INT4_HIGHTMP,
},
- /* warning: these get rewritten during machine init below
- * depending on pcb variant
- */
- .rails = {
+
+ .batteries = gta02_batteries,
+ .num_batteries = ARRAY_SIZE(gta02_batteries),
+
+ .reg_init_data = {
[PCF50633_REGULATOR_AUTO] = {
- .name = "io_3v3",
- .flags = PMU_VRAIL_F_SUSPEND_ON,
- .voltage = {
- .init = 3300,
- .max = 3300,
.constraints = {
.min_uV = 3300000,
.max_uV = 3300000,
@@ -632,17 +650,9 @@ struct pcf50633_platform_data gta02_pcf_pdata = {
.enabled = 1,
},
},
+ .num_consumer_supplies = 0,
},
[PCF50633_REGULATOR_DOWN1] = {
- .name = "core_1v3",
- /* Wow, when we are going into suspend, after pcf50633
- * runs its suspend (which happens real early since it
- * is an i2c device) we are running out of the 22uF cap
- * on core_1v3 rail !!!!
- */
- .voltage = {
- .init = 1300,
- .max = 1600,
.constraints = {
.min_uV = 1300000,
.max_uV = 1600000,
@@ -650,13 +660,9 @@ struct pcf50633_platform_data gta02_pcf_pdata = {
.boot_on = 1,
.apply_uV = 1,
},
+ .num_consumer_supplies = 0,
},
[PCF50633_REGULATOR_DOWN2] = {
- .name = "core_1v8",
- .flags = PMU_VRAIL_F_SUSPEND_ON,
- .voltage = {
- .init = 1800,
- .max = 1800,
.constraints = {
.min_uV = 1800000,
.max_uV = 1800000,
@@ -667,12 +673,9 @@ struct pcf50633_platform_data gta02_pcf_pdata = {
.enabled = 1,
},
},
+ .num_consumer_supplies = 0,
},
[PCF50633_REGULATOR_HCLDO] = {
- .name = "sd_3v3",
- .voltage = {
- .init = 2000,
- .max = 3300,
.constraints = {
.min_uV = 2000000,
.max_uV = 3300000,
@@ -680,40 +683,47 @@ struct pcf50633_platform_data gta02_pcf_pdata = {
.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
.boot_on = 1,
},
+ .num_consumer_supplies = 1,
+ .consumer_supplies = hcldo_consumers,
},
[PCF50633_REGULATOR_LDO1] = {
- .name = "gsensor_3v3",
- .voltage = {
- .init = 1300,
- .max = 1330,
+ .constraints = {
+ .min_uV = 1300000,
+ .max_uV = 1300000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .apply_uV = 1,
},
+ .num_consumer_supplies = 0,
},
[PCF50633_REGULATOR_LDO2] = {
- .name = "codec_3v3",
- .voltage = {
- .init = 3300,
- .max = 3300,
+ .constraints = {
+ .min_uV = 3300000,
+ .max_uV = 3300000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .apply_uV = 1,
},
+ .num_consumer_supplies = 0,
},
[PCF50633_REGULATOR_LDO3] = {
- .name = "unused3",
- .voltage = {
- .init = 3000,
- .max = 3000,
+ .constraints = {
+ .min_uV = 3000000,
+ .max_uV = 3000000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .apply_uV = 1,
},
+ .num_consumer_supplies = 0,
},
[PCF50633_REGULATOR_LDO4] = {
- .name = "bt_3v2",
- .voltage = {
- .init = 2500,
- .max = 3300,
+ .constraints = {
+ .min_uV = 3200000,
+ .max_uV = 3200000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .apply_uV = 1,
},
+ .num_consumer_supplies = 1,
+ .consumer_supplies = ldo4_consumers,
},
[PCF50633_REGULATOR_LDO5] = {
- .name = "rf3v",
- .voltage = {
- .init = 1500,
- .max = 1500,
.constraints = {
.min_uV = 1500000,
.max_uV = 1500000,
@@ -723,115 +733,76 @@ struct pcf50633_platform_data gta02_pcf_pdata = {
.enabled = 1,
},
},
+ .num_consumer_supplies = 1,
+ .consumer_supplies = ldo5_consumers,
},
[PCF50633_REGULATOR_LDO6] = {
- .name = "lcm_3v",
- .flags = PMU_VRAIL_F_SUSPEND_ON,
- .voltage = {
- .init = 0,
- .max = 3300,
.constraints = {
.min_uV = 0,
.max_uV = 3300000,
.valid_modes_mask = REGULATOR_MODE_NORMAL,
},
+ .num_consumer_supplies = 0,
},
[PCF50633_REGULATOR_MEMLDO] = {
- .name = "memldo",
- .flags = PMU_VRAIL_F_SUSPEND_ON,
- .voltage = {
- .init = 1800,
- .max = 1800,
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .state_mem = {
+ .enabled = 1,
+ },
},
+ .num_consumer_supplies = 0,
},
- },
- .defer_resume_backlight = 1,
- .resume_backlight_ramp_speed = 5,
- .attach_child_devices = gta02_pcf50633_attach_child_devices
+ },
+ .probe_done = gta02_pmu_attach_child_devices,
+ .regulator_registered = gta02_pmu_regulator_registered,
+ .mbc_event_callback = gta02_pmu_event_callback,
};
-#if 0 /* currently unused */
-static void cfg_pmu_vrail(struct pmu_voltage_rail *vrail, char *name,
- unsigned int flags, unsigned int init,
- unsigned int max)
-{
- vrail->name = name;
- vrail->flags = flags;
- vrail->voltage.init = init;
- vrail->voltage.max = max;
-}
-#endif
-
static void mangle_pmu_pdata_by_system_rev(void)
{
+ struct regulator_init_data *reg_init_data;
+
+ reg_init_data = gta02_pcf_pdata.reg_init_data;
+
switch (system_rev) {
case GTA02v1_SYSTEM_REV:
/* FIXME: this is only in v1 due to wrong PMU variant */
- gta02_pcf_pdata.rails[PCF50633_REGULATOR_DOWN2].flags =
- PMU_VRAIL_F_SUSPEND_ON;
+ reg_init_data[PCF50633_REGULATOR_DOWN2]
+ .constraints.state_mem.enabled = 1;
break;
case GTA02v2_SYSTEM_REV:
case GTA02v3_SYSTEM_REV:
case GTA02v4_SYSTEM_REV:
case GTA02v5_SYSTEM_REV:
case GTA02v6_SYSTEM_REV:
- /* we need to keep the 1.8V going since this is the SDRAM
- * self-refresh voltage */
- gta02_pcf_pdata.rails[PCF50633_REGULATOR_DOWN2].flags =
- PMU_VRAIL_F_SUSPEND_ON;
- gta02_pcf_pdata.rails[PCF50633_REGULATOR_DOWN2].name =
- "io_1v8",
- gta02_pcf_pdata.rails[PCF50633_REGULATOR_LDO1].name =
- "gsensor_3v3",
- gta02_pcf_pdata.rails[PCF50633_REGULATOR_LDO1].voltage.init =
- 3300;
- gta02_pcf_pdata.rails[PCF50633_REGULATOR_LDO1].voltage.max =
- 3300;
- gta02_pcf_pdata.rails[PCF50633_REGULATOR_LDO1].flags &=
- ~PMU_VRAIL_F_SUSPEND_ON;
- gta02_pcf_pdata.rails[PCF50633_REGULATOR_LDO3].flags =
- PMU_VRAIL_F_UNUSED;
- gta02_pcf_pdata.rails[PCF50633_REGULATOR_LDO5] = ((struct pmu_voltage_rail) {
- .name = "rf_3v",
- .voltage = {
- .init = 0,
- .max = 3000,
- }
- });
- gta02_pcf_pdata.rails[PCF50633_REGULATOR_LDO6] =
- ((struct pmu_voltage_rail) {
- .name = "lcm_3v",
- .flags = PMU_VRAIL_F_SUSPEND_ON,
- .voltage = {
- .init = 3000,
- .max = 3000,
- }
- });
+ reg_init_data[PCF50633_REGULATOR_LDO1]
+ .constraints.min_uV = 3300000;
+ reg_init_data[PCF50633_REGULATOR_LDO1]
+ .constraints.min_uV = 3300000;
+ reg_init_data[PCF50633_REGULATOR_LDO1]
+ .constraints.state_mem.enabled = 0;
+
+ reg_init_data[PCF50633_REGULATOR_LDO5]
+ .constraints.min_uV = 3000000;
+ reg_init_data[PCF50633_REGULATOR_LDO5]
+ .constraints.max_uV = 3000000;
+
+ reg_init_data[PCF50633_REGULATOR_LDO6]
+ .constraints.min_uV = 3000000;
+ reg_init_data[PCF50633_REGULATOR_LDO6]
+ .constraints.max_uV = 3000000;
+ reg_init_data[PCF50633_REGULATOR_LDO6]
+ .constraints.apply_uV = 1;
break;
default:
break;
}
}
-static struct resource gta02_pmu_resources[] = {
- [0] = {
- .flags = IORESOURCE_IRQ,
- .start = GTA02_IRQ_PCF50633,
- .end = GTA02_IRQ_PCF50633,
- },
-};
-
-struct platform_device gta02_pmu_dev = {
- .name = "pcf50633",
- .num_resources = ARRAY_SIZE(gta02_pmu_resources),
- .resource = gta02_pmu_resources,
- .dev = {
- .platform_data = &gta02_pcf_pdata,
- },
-};
-
-
#ifdef CONFIG_GTA02_HDQ
/* HDQ */
@@ -956,6 +927,14 @@ struct platform_device s3c24xx_pwm_device = {
.num_resources = 0,
};
+static struct i2c_board_info gta02_i2c_devs[] __initdata = {
+ {
+ I2C_BOARD_INFO("pcf50633", 0x73),
+ .irq = GTA02_IRQ_PCF50633,
+ .platform_data = &gta02_pcf_pdata,
+ },
+};
+
static struct s3c2410_nand_set gta02_nand_sets[] = {
[0] = {
.name = "neo1973-nand",
@@ -1078,10 +1057,11 @@ static struct s3c2410_ts_mach_info gta02_ts_cfg = {
},
};
+
static void gta02_bl_set_intensity(int intensity)
{
- struct pcf50633 *pcf = gta02_pcf_pdata.pcf;
- int old_intensity;
+ struct pcf50633 *pcf = gta02_pcf;
+ int old_intensity = pcf50633_reg_read(pcf, PCF50633_REG_LEDOUT);
int ret;
intensity >>= 2;
@@ -1149,19 +1129,25 @@ static struct platform_device gta02_bl_dev = {
static void gta02_jbt6k74_reset(int devidx, int level)
{
glamo_lcm_reset(level);
-}
+}
-/* finally bring up deferred backlight resume now LCM is resumed itself */
-
-static void gta02_jbt6k74_resuming(int devidx)
+static void gta02_jbt6k74_probe_completed(struct device *dev)
{
- pcf50633_backlight_resume(pcf50633_global);
-}
+ struct pcf50633 *pcf = gta02_pcf;
+ /* Switch on backlight. Qi does not do it for us */
+ pcf50633_reg_write(pcf, PCF50633_REG_LEDOUT, 0x01);
+ pcf50633_reg_write(pcf, PCF50633_REG_LEDENA, 0x00);
+ pcf50633_reg_write(pcf, PCF50633_REG_LEDDIM, 0x01);
+ pcf50633_reg_write(pcf, PCF50633_REG_LEDENA, 0x01);
+
+ gta02_bl_dev.dev.parent = dev;
+ platform_device_register(&gta02_bl_dev);
+}
const struct jbt6k74_platform_data jbt6k74_pdata = {
.reset = gta02_jbt6k74_reset,
- .resuming = gta02_jbt6k74_resuming,
+ .probe_completed = gta02_jbt6k74_probe_completed,
};
static struct spi_board_info gta02_spi_board_info[] = {
@@ -1487,61 +1473,18 @@ static int glamo_irq_is_wired(void)
return -ENODEV;
}
-
-static void
-gta02_glamo_mmc_set_power(unsigned char power_mode, unsigned short vdd)
+static int gta02_glamo_can_set_mmc_power(void)
{
- int mv = 1650;
- int timeout = 500;
-
- printk(KERN_DEBUG "mmc_set_power(power_mode=%u, vdd=%u)\n",
- power_mode, vdd);
-
switch (system_rev) {
- case GTA02v1_SYSTEM_REV:
- case GTA02v2_SYSTEM_REV:
- break;
- case GTA02v3_SYSTEM_REV:
- case GTA02v4_SYSTEM_REV:
- case GTA02v5_SYSTEM_REV:
- case GTA02v6_SYSTEM_REV:
- switch (power_mode) {
- case MMC_POWER_ON:
- case MMC_POWER_UP:
- /* depend on pcf50633 driver init + not suspended */
- while (pcf50633_ready(pcf50633_global) && (timeout--))
- msleep(5);
-
- if (timeout < 0) {
- printk(KERN_ERR"gta02_glamo_mmc_set_power "
- "BAILING on timeout\n");
- return;
- }
- /* select and set the voltage */
- if (vdd > 7)
- mv += 350 + 100 * (vdd - 8);
- printk(KERN_INFO "SD power -> %dmV\n", mv);
- pcf50633_voltage_set(pcf50633_global,
- PCF50633_REGULATOR_HCLDO, mv);
- pcf50633_onoff_set(pcf50633_global,
- PCF50633_REGULATOR_HCLDO, 1);
- break;
- case MMC_POWER_OFF:
- /* power off happens during suspend, when pcf50633 can
- * be already gone and not coming back... just forget
- * the action then because pcf50633 suspend already
- * dealt with it, otherwise we spin forever
- */
- if (pcf50633_ready(pcf50633_global))
- return;
- pcf50633_onoff_set(pcf50633_global,
- PCF50633_REGULATOR_HCLDO, 0);
- break;
- }
- break;
+ case GTA02v3_SYSTEM_REV:
+ case GTA02v4_SYSTEM_REV:
+ case GTA02v5_SYSTEM_REV:
+ case GTA02v6_SYSTEM_REV:
+ return 1;
}
-}
+ return 0;
+}
/* Smedia Glamo 3362 */
@@ -1591,7 +1534,8 @@ static struct glamofb_platform_data gta02_glamo_pdata = {
.spigpio_info = &glamo_spigpio_cfg,
/* glamo MMC function platform data */
- .glamo_set_mci_power = gta02_glamo_mmc_set_power,
+ .mmc_dev = &gta02_mmc_dev,
+ .glamo_can_set_mci_power = gta02_glamo_can_set_mmc_power,
.glamo_mci_use_slow = gta02_glamo_mci_use_slow,
.glamo_irq_is_wired = glamo_irq_is_wired,
.glamo_external_reset = gta02_glamo_external_reset
@@ -1697,7 +1641,6 @@ static struct platform_device *gta02_devices[] __initdata = {
&s3c24xx_pwm_device,
&gta02_led_dev,
&gta02_pm_wlan_dev, /* not dependent on PMU */
- &gta02_pmu_dev,
&s3c_device_iis,
&s3c_device_i2c0,
@@ -1706,10 +1649,7 @@ static struct platform_device *gta02_devices[] __initdata = {
/* these guys DO need to be children of PMU */
static struct platform_device *gta02_devices_pmu_children[] = {
- &gta02_glamo_dev, /* glamo-mci power handling depends on PMU */
&s3c_device_ts, /* input 1 */
- &gta01_pm_gps_dev,
- &gta01_pm_bt_dev,
&gta02_pm_gsm_dev,
&gta02_pm_usbhost_dev,
&s3c_device_spi_acc1, /* input 2 */
@@ -1718,6 +1658,30 @@ static struct platform_device *gta02_devices_pmu_children[] = {
&gta02_resume_reason_device,
};
+static void gta02_pmu_regulator_registered(struct pcf50633 *pcf, int id)
+{
+ struct platform_device *regulator, *pdev;
+
+ regulator = pcf->regulator_pdev[id];
+
+ switch(id) {
+ case PCF50633_REGULATOR_LDO4:
+ pdev = &gta01_pm_bt_dev;
+ break;
+ case PCF50633_REGULATOR_LDO5:
+ pdev = &gta01_pm_gps_dev;
+ break;
+ case PCF50633_REGULATOR_HCLDO:
+ pdev = &gta02_glamo_dev;
+ break;
+ default:
+ return;
+ }
+
+ pdev->dev.parent = &regulator->dev;
+ platform_device_register(pdev);
+}
+
/* this is called when pc50633 is probed, unfortunately quite late in the
* day since it is an I2C bus device. Here we can belatedly define some
* platform devices with the advantage that we can mark the pcf50633 as the
@@ -1725,18 +1689,14 @@ static struct platform_device *gta02_devices_pmu_children[] = {
* the pcf50633 still around.
*/
-static void gta02_pcf50633_attach_child_devices(struct device *parent_device)
+static void gta02_pmu_attach_child_devices(struct pcf50633 *pcf)
{
int n;
gta02_pcf = pcf;
- gta02_pcf = pcf;
-
- gta02_pcf = pcf;
-
for (n = 0; n < ARRAY_SIZE(gta02_devices_pmu_children); n++)
- gta02_devices_pmu_children[n]->dev.parent = parent_device;
+ gta02_devices_pmu_children[n]->dev.parent = pcf->dev;
mangle_glamo_res_by_system_rev();
platform_add_devices(gta02_devices_pmu_children,
@@ -1792,6 +1752,8 @@ static void __init gta02_machine_init(void)
mangle_glamo_res_by_system_rev();
+ i2c_register_board_info(0, gta02_i2c_devs, ARRAY_SIZE(gta02_i2c_devs));
+
mangle_pmu_pdata_by_system_rev();
platform_add_devices(gta02_devices, ARRAY_SIZE(gta02_devices));
diff --git a/arch/arm/plat-s3c24xx/neo1973_pm_gps.c b/arch/arm/plat-s3c24xx/neo1973_pm_gps.c
index 3db733c86f4..9b455229e6d 100644
--- a/arch/arm/plat-s3c24xx/neo1973_pm_gps.c
+++ b/arch/arm/plat-s3c24xx/neo1973_pm_gps.c
@@ -25,22 +25,40 @@
/* For GTA01 */
#include <mach/gta01.h>
-#include <linux/pcf50606.h>
+#include <linux/mfd/pcf50606/core.h>
+#include <linux/mfd/pcf50606/gpo.h>
/* For GTA02 */
#include <mach/gta02.h>
#include <linux/mfd/pcf50633/core.h>
+#include <linux/mfd/pcf50633/pmic.h>
#include <linux/regulator/consumer.h>
-
#include <linux/err.h>
+enum gta01_pm_gps_supplies {
+
+ /* GTA01 */
+ GTA01_GPS_REG_2V8,
+ GTA01_GPS_REG_3V,
+ GTA01_GPS_REG_3V3,
+ GTA01_GPS_REG_1V5,
+ GTA01_GPS_REG_2V5,
+
+ /* GTA02 */
+ GTA02_GPS_REG_RF_3V,
+
+ /* Always last */
+ GTA01_GPS_NUM_REG
+};
+
struct neo1973_pm_gps_data {
- int power_was_on;
- struct regulator *regulator;
#ifdef CONFIG_PM
int keep_on_in_suspend;
#endif
+ int power_was_on; /* For GTA02 only */
+ int regulator_state[GTA01_GPS_NUM_REG];
+ struct regulator *regulator[GTA01_GPS_NUM_REG];
};
static struct neo1973_pm_gps_data neo1973_gps;
@@ -57,14 +75,16 @@ EXPORT_SYMBOL_GPL(neo1973_pm_gps_is_on);
* the input to VDD_RF */
static void gps_power_2v8_set(int on)
{
+ struct regulator *regulator = neo1973_gps.regulator[GTA01_GPS_REG_2V8];
+
switch (system_rev) {
case GTA01v3_SYSTEM_REV:
case GTA01v4_SYSTEM_REV:
if (on)
- pcf50606_voltage_set(pcf50606_global,
- PCF50606_REGULATOR_IOREG, 2800);
- pcf50606_onoff_set(pcf50606_global,
- PCF50606_REGULATOR_IOREG, on);
+ regulator_enable(regulator);
+ else
+ regulator_disable(regulator);
+ neo1973_gps.regulator_state[GTA01_GPS_REG_2V8] = on;
break;
case GTA01Bv2_SYSTEM_REV:
s3c2410_gpio_setpin(GTA01_GPIO_GPS_EN_2V8, on);
@@ -78,15 +98,12 @@ static void gps_power_2v8_set(int on)
static int gps_power_2v8_get(void)
{
int ret = 0;
+ struct regulator *regulator = neo1973_gps.regulator[GTA01_GPS_REG_2V8];
switch (system_rev) {
case GTA01v3_SYSTEM_REV:
case GTA01v4_SYSTEM_REV:
- if (pcf50606_onoff_get(pcf50606_global,
- PCF50606_REGULATOR_IOREG) &&
- pcf50606_voltage_get(pcf50606_global,
- PCF50606_REGULATOR_IOREG) == 2800)
- ret = 1;
+ ret = regulator_is_enabled(regulator);
break;
case GTA01Bv2_SYSTEM_REV:
if (s3c2410_gpio_getpin(GTA01_GPIO_GPS_EN_2V8))
@@ -103,14 +120,16 @@ static int gps_power_2v8_get(void)
/* This is the 3V supply (AVDD) for the external RF frontend (LNA bias) */
static void gps_power_3v_set(int on)
{
+ struct regulator *regulator = neo1973_gps.regulator[GTA01_GPS_REG_3V];
+
switch (system_rev) {
case GTA01v3_SYSTEM_REV:
case GTA01v4_SYSTEM_REV:
if (on)
- pcf50606_voltage_set(pcf50606_global,
- PCF50606_REGULATOR_D1REG, 3000);
- pcf50606_onoff_set(pcf50606_global,
- PCF50606_REGULATOR_D1REG, on);
+ regulator_enable(regulator);
+ else
+ regulator_disable(regulator);
+ neo1973_gps.regulator_state[GTA01_GPS_REG_3V3] = on;
break;
case GTA01Bv2_SYSTEM_REV:
case GTA01Bv3_SYSTEM_REV:
@@ -123,15 +142,12 @@ static void gps_power_3v_set(int on)
static int gps_power_3v_get(void)
{
int ret = 0;
+ struct regulator *regulator = neo1973_gps.regulator[GTA01_GPS_REG_3V];
switch (system_rev) {
case GTA01v3_SYSTEM_REV:
case GTA01v4_SYSTEM_REV:
- if (pcf50606_onoff_get(pcf50606_global,
- PCF50606_REGULATOR_D1REG) &&
- pcf50606_voltage_get(pcf50606_global,
- PCF50606_REGULATOR_D1REG) == 3000)
- ret = 1;
+ ret = regulator_is_enabled(regulator);
break;
case GTA01Bv2_SYSTEM_REV:
case GTA01Bv3_SYSTEM_REV:
@@ -147,15 +163,17 @@ static int gps_power_3v_get(void)
/* This is the 3.3V supply for VDD_IO and VDD_LPREG input */
static void gps_power_3v3_set(int on)
{
+ struct regulator *regulator = neo1973_gps.regulator[GTA01_GPS_REG_3V3];
+
switch (system_rev) {
case GTA01v3_SYSTEM_REV:
case GTA01v4_SYSTEM_REV:
case GTA01Bv2_SYSTEM_REV:
if (on)
- pcf50606_voltage_set(pcf50606_global,
- PCF50606_REGULATOR_DCD, 3300);
- pcf50606_onoff_set(pcf50606_global,
- PCF50606_REGULATOR_DCD, on);
+ regulator_enable(regulator);
+ else
+ regulator_disable(regulator);
+ neo1973_gps.regulator_state[GTA01_GPS_REG_3V3] = on;
break;
case GTA01Bv3_SYSTEM_REV:
case GTA01Bv4_SYSTEM_REV:
@@ -167,16 +185,13 @@ static void gps_power_3v3_set(int on)
static int gps_power_3v3_get(void)
{
int ret = 0;
+ struct regulator *regulator = neo1973_gps.regulator[GTA01_GPS_REG_3V3];
switch (system_rev) {
case GTA01v3_SYSTEM_REV:
case GTA01v4_SYSTEM_REV:
case GTA01Bv2_SYSTEM_REV:
- if (pcf50606_onoff_get(pcf50606_global,
- PCF50606_REGULATOR_DCD) &&
- pcf50606_voltage_get(pcf50606_global,
- PCF50606_REGULATOR_DCD) == 3300)
- ret = 1;
+ ret = regulator_is_enabled(regulator);
break;
case GTA01Bv3_SYSTEM_REV:
case GTA01Bv4_SYSTEM_REV:
@@ -191,6 +206,8 @@ static int gps_power_3v3_get(void)
/* This is the 2.5V supply for VDD_PLLREG and VDD_COREREG input */
static void gps_power_2v5_set(int on)
{
+ struct regulator *regulator = neo1973_gps.regulator[GTA01_GPS_REG_2V5];
+
switch (system_rev) {
case GTA01v3_SYSTEM_REV:
/* This is CORE_1V8 and cannot be disabled */
@@ -200,10 +217,10 @@ static void gps_power_2v5_set(int on)
case GTA01Bv3_SYSTEM_REV:
case GTA01Bv4_SYSTEM_REV:
if (on)
- pcf50606_voltage_set(pcf50606_global,
- PCF50606_REGULATOR_D2REG, 2500);
- pcf50606_onoff_set(pcf50606_global,
- PCF50606_REGULATOR_D2REG, on);
+ regulator_enable(regulator);
+ else
+ regulator_disable(regulator);
+ neo1973_gps.regulator_state[GTA01_GPS_REG_2V5] = on;
break;
}
}
@@ -211,6 +228,7 @@ static void gps_power_2v5_set(int on)
static int gps_power_2v5_get(void)
{
int ret = 0;
+ struct regulator *regulator = neo1973_gps.regulator[GTA01_GPS_REG_2V5];
switch (system_rev) {
case GTA01v3_SYSTEM_REV:
@@ -221,11 +239,7 @@ static int gps_power_2v5_get(void)
case GTA01Bv2_SYSTEM_REV:
case GTA01Bv3_SYSTEM_REV:
case GTA01Bv4_SYSTEM_REV:
- if (pcf50606_onoff_get(pcf50606_global,
- PCF50606_REGULATOR_D2REG) &&
- pcf50606_voltage_get(pcf50606_global,
- PCF50606_REGULATOR_D2REG) == 2500)
- ret = 1;
+ ret = regulator_is_enabled(regulator);
break;
}
@@ -235,6 +249,8 @@ static int gps_power_2v5_get(void)
/* This is the 1.5V supply for VDD_CORE */
static void gps_power_1v5_set(int on)
{
+ struct regulator *regulator = neo1973_gps.regulator[GTA01_GPS_REG_1V5];
+
switch (system_rev) {
case GTA01v3_SYSTEM_REV:
case GTA01v4_SYSTEM_REV:
@@ -244,10 +260,10 @@ static void gps_power_1v5_set(int on)
case GTA01Bv3_SYSTEM_REV:
case GTA01Bv4_SYSTEM_REV:
if (on)
- pcf50606_voltage_set(pcf50606_global,
- PCF50606_REGULATOR_DCD, 1500);
- pcf50606_onoff_set(pcf50606_global,
- PCF50606_REGULATOR_DCD, on);
+ regulator_enable(regulator);
+ else
+ regulator_disable(regulator);
+ neo1973_gps.regulator_state[GTA01_GPS_REG_1V5] = on;
break;
}
}
@@ -255,6 +271,7 @@ static void gps_power_1v5_set(int on)
static int gps_power_1v5_get(void)
{
int ret = 0;
+ struct regulator *regulator = neo1973_gps.regulator[GTA01_GPS_REG_1V5];
switch (system_rev) {
case GTA01v3_SYSTEM_REV:
@@ -265,11 +282,7 @@ static int gps_power_1v5_get(void)
break;
case GTA01Bv3_SYSTEM_REV:
case GTA01Bv4_SYSTEM_REV:
- if (pcf50606_onoff_get(pcf50606_global,
- PCF50606_REGULATOR_DCD) &&
- pcf50606_voltage_get(pcf50606_global,
- PCF50606_REGULATOR_DCD) == 1500)
- ret = 1;
+ ret = regulator_is_enabled(regulator);
break;
}
@@ -286,8 +299,6 @@ static void gps_pwron_set(int on)
if (machine_is_neo1973_gta02()) {
if (on) {
- pcf50633_voltage_set(pcf50633_global,
- PCF50633_REGULATOR_LDO5, 3000);
/* return UART pins to being UART pins */
s3c2410_gpio_cfgpin(S3C2410_GPH4, S3C2410_GPH4_TXD1);
/* remove pulldown now it won't be floating any more */
@@ -302,11 +313,10 @@ static void gps_pwron_set(int on)
/* don't let RX from unpowered GPS float */
s3c2410_gpio_pullup(S3C2410_GPH5, 1);
}
- if (on && !regulator_is_enabled(neo1973_gps.regulator))
- regulator_enable(neo1973_gps.regulator);
-
- if (!on && regulator_is_enabled(neo1973_gps.regulator))
- regulator_disable(neo1973_gps.regulator);
+ if (on && !neo1973_gps.power_was_on)
+ regulator_enable(neo1973_gps.regulator[GTA02_GPS_REG_RF_3V]);
+ else if (!on && neo1973_gps.power_was_on)
+ regulator_disable(neo1973_gps.regulator[GTA02_GPS_REG_RF_3V]);
}
}
@@ -316,8 +326,7 @@ static int gps_pwron_get(void)
return !!s3c2410_gpio_getpin(GTA01_GPIO_GPS_PWRON);
if (machine_is_neo1973_gta02())
- return !!pcf50633_onoff_get(pcf50633_global,
- PCF50633_REGULATOR_LDO5);
+ return regulator_is_enabled(neo1973_gps.regulator[GTA02_GPS_REG_RF_3V]);
return -1;
}
@@ -413,7 +422,7 @@ static void gps_rst_set(int on)
{
switch (system_rev) {
case GTA01v3_SYSTEM_REV:
- pcf50606_gpo0_set(pcf50606_global, on);
+ pcf50606_gpo_set_active(gta01_pcf, PCF50606_GPO1, on);
break;
case GTA01v4_SYSTEM_REV:
case GTA01Bv2_SYSTEM_REV:
@@ -428,8 +437,7 @@ static int gps_rst_get(void)
{
switch (system_rev) {
case GTA01v3_SYSTEM_REV:
- if (pcf50606_gpo0_get(pcf50606_global))
- return 1;
+ return pcf50606_gpo_get_active(gta01_pcf, PCF50606_GPO1);
break;
case GTA01v4_SYSTEM_REV:
case GTA01Bv2_SYSTEM_REV:
@@ -487,17 +495,22 @@ static void gps_power_sequence_down(void)
/* Don't disable AVDD before PWRON is cleared, since
* in GTA01Bv3, AVDD and RFREG_IN are shared */
- gps_power_3v_set(0);
+ if (neo1973_gps.regulator_state[GTA01_GPS_REG_3V])
+ gps_power_3v_set(0);
/* Remove VDD_COREREG_IN, VDD_PLLREG_IN and VDD_REFREG_IN */
- gps_power_1v5_set(0);
- gps_power_2v5_set(0);
- gps_power_2v8_set(0);
+ if (neo1973_gps.regulator_state[GTA01_GPS_REG_1V5])
+ gps_power_1v5_set(0);
+ if (neo1973_gps.regulator_state[GTA01_GPS_REG_2V5])
+ gps_power_2v5_set(0);
+ if (neo1973_gps.regulator_state[GTA01_GPS_REG_2V8])
+ gps_power_2v8_set(0);
/* Remove VDD_LPREG_IN and VDD_IO */
- gps_power_3v3_set(0);
-}
+ if (neo1973_gps.regulator_state[GTA01_GPS_REG_3V3])
+ gps_power_3v3_set(0);
+}
static ssize_t power_sequence_read(struct device *dev,
struct device_attribute *attr,
@@ -643,6 +656,18 @@ static int __init gta01_pm_gps_probe(struct platform_device *pdev)
}
#ifdef CONFIG_MACH_NEO1973_GTA01
+
+ neo1973_gps.regulator[GTA01_GPS_REG_2V8] =
+ regulator_get(&pdev->dev, "GPS_2V8");
+ neo1973_gps.regulator[GTA01_GPS_REG_3V] =
+ regulator_get(&pdev->dev, "GPS_3V");
+ neo1973_gps.regulator[GTA01_GPS_REG_3V3] =
+ regulator_get(&pdev->dev, "GPS_3V3");
+ neo1973_gps.regulator[GTA01_GPS_REG_1V5] =
+ regulator_get(&pdev->dev, "GPS_1V5");
+ neo1973_gps.regulator[GTA01_GPS_REG_2V5] =
+ regulator_get(&pdev->dev, "GPS_2V5");
+
gps_power_sequence_down();
switch (system_rev) {
@@ -673,7 +698,7 @@ static int __init gta01_pm_gps_probe(struct platform_device *pdev)
case GTA02v4_SYSTEM_REV:
case GTA02v5_SYSTEM_REV:
case GTA02v6_SYSTEM_REV:
- neo1973_gps.regulator = regulator_get(
+ neo1973_gps.regulator[GTA02_GPS_REG_RF_3V] = regulator_get(
&pdev->dev, "RF_3V");
if (IS_ERR(neo1973_gps.regulator)) {
dev_err(&pdev->dev, "probe failed %ld\n",
@@ -681,7 +706,7 @@ static int __init gta01_pm_gps_probe(struct platform_device *pdev)
return PTR_ERR(neo1973_gps.regulator);
}
- dev_info(&pdev->dev, "FIC Neo1973 GPS Power Management:"
+ dev_info(&pdev->dev, "FIC Neo1973 GPS Power Managerment:"
"starting\n");
break;
default:
@@ -699,7 +724,7 @@ static int __init gta01_pm_gps_probe(struct platform_device *pdev)
* to second-guess some of its internal logic and make it do
* something that isn't really part of its design.
*/
- pcf50633_reg_write(gta02_pcf_pdata.pcf,
+ pcf50633_reg_write(gta02_pcf,
PCF50633_REG_LDO5ENA, 0);
return sysfs_create_group(&pdev->dev.kobj,
@@ -712,13 +737,19 @@ static int gta01_pm_gps_remove(struct platform_device *pdev)
{
if (machine_is_neo1973_gta01()) {
#ifdef CONFIG_MACH_NEO1973_GTA01
+ int i;
+
gps_power_sequence_down();
+ /* Now disable all regulators */
+ for (i = 0; i < GTA01_GPS_NUM_REG; i++) {
+ regulator_put(neo1973_gps.regulator[i]);
+ }
#endif
sysfs_remove_group(&pdev->dev.kobj, &gta01_gps_attr_group);
}
if (machine_is_neo1973_gta02()) {
- pcf50633_onoff_set(pcf50633_global, PCF50633_REGULATOR_LDO5, 0);
+ regulator_put(neo1973_gps.regulator[GTA02_GPS_REG_RF_3V]);
sysfs_remove_group(&pdev->dev.kobj, &gta02_gps_attr_group);
}
return 0;