1 From 70a0c17968f5151ce4f468785860e04bbc7a9d3c Mon Sep 17 00:00:00 2001
2 From: mokopatches <mokopatches@openmoko.org>
3 Date: Wed, 16 Jul 2008 14:46:56 +0100
4 Subject: [PATCH] gta02-power_control.patch
7 arch/arm/plat-s3c24xx/neo1973_pm_bt.c | 84 +++++++++---
8 arch/arm/plat-s3c24xx/neo1973_pm_gps.c | 217 ++++++++++++++++++++++++--------
9 arch/arm/plat-s3c24xx/neo1973_pm_gsm.c | 97 ++++++++++++--
10 3 files changed, 309 insertions(+), 89 deletions(-)
12 diff --git a/arch/arm/plat-s3c24xx/neo1973_pm_bt.c b/arch/arm/plat-s3c24xx/neo1973_pm_bt.c
13 index b1af441..d685ef7 100644
14 --- a/arch/arm/plat-s3c24xx/neo1973_pm_bt.c
15 +++ b/arch/arm/plat-s3c24xx/neo1973_pm_bt.c
17 #include <linux/pcf50606.h>
19 #include <asm/hardware.h>
20 +#include <asm/mach-types.h>
21 #include <asm/arch/gta01.h>
22 +#include <asm/arch/gta02.h>
24 #define DRVMSG "FIC Neo1973 Bluetooth Power Management"
26 @@ -27,14 +29,30 @@ static ssize_t bt_read(struct device *dev, struct device_attribute *attr,
29 if (!strcmp(attr->attr.name, "power_on")) {
30 - if (pcf50606_onoff_get(pcf50606_global,
31 - PCF50606_REGULATOR_D1REG) &&
32 - pcf50606_voltage_get(pcf50606_global,
33 - PCF50606_REGULATOR_D1REG) == 3100)
35 + switch (machine_arch_type) {
36 + case MACH_TYPE_NEO1973_GTA01:
37 + if (pcf50606_onoff_get(pcf50606_global,
38 + PCF50606_REGULATOR_D1REG) &&
39 + pcf50606_voltage_get(pcf50606_global,
40 + PCF50606_REGULATOR_D1REG) == 3100)
43 + case MACH_TYPE_NEO1973_GTA02:
44 + if (s3c2410_gpio_getpin(GTA02_GPIO_BT_EN))
48 } else if (!strcmp(attr->attr.name, "reset")) {
49 - if (s3c2410_gpio_getpin(GTA01_GPIO_BT_EN) == 0)
51 + switch (machine_arch_type) {
52 + case MACH_TYPE_NEO1973_GTA01:
53 + if (s3c2410_gpio_getpin(GTA01_GPIO_BT_EN) == 0)
56 + case MACH_TYPE_NEO1973_GTA02:
57 + if (s3c2410_gpio_getpin(GTA02_GPIO_BT_EN) == 0)
63 return strlcpy(buf, "0\n", 3);
64 @@ -48,20 +66,37 @@ static ssize_t bt_write(struct device *dev, struct device_attribute *attr,
65 unsigned long on = simple_strtoul(buf, NULL, 10);
67 if (!strcmp(attr->attr.name, "power_on")) {
68 - /* if we are powering up, assert reset, then power, then
71 - s3c2410_gpio_setpin(GTA01_GPIO_BT_EN, 0);
72 - pcf50606_voltage_set(pcf50606_global,
73 - PCF50606_REGULATOR_D1REG,
75 + switch (machine_arch_type) {
76 + case MACH_TYPE_NEO1973_GTA01:
77 + /* if we are powering up, assert reset, then power,
78 + * then release reset */
80 + s3c2410_gpio_setpin(GTA01_GPIO_BT_EN, 0);
81 + pcf50606_voltage_set(pcf50606_global,
82 + PCF50606_REGULATOR_D1REG,
85 + pcf50606_onoff_set(pcf50606_global,
86 + PCF50606_REGULATOR_D1REG, on);
87 + s3c2410_gpio_setpin(GTA01_GPIO_BT_EN, on);
89 + case MACH_TYPE_NEO1973_GTA02:
91 + s3c2410_gpio_setpin(GTA02_GPIO_BT_EN, 0);
93 + s3c2410_gpio_setpin(GTA02_GPIO_BT_EN, 1);
96 - pcf50606_onoff_set(pcf50606_global,
97 - PCF50606_REGULATOR_D1REG, on);
98 - s3c2410_gpio_setpin(GTA01_GPIO_BT_EN, on);
99 } else if (!strcmp(attr->attr.name, "reset")) {
100 /* reset is low-active, so we need to invert */
101 - s3c2410_gpio_setpin(GTA01_GPIO_BT_EN, on ? 0 : 1);
102 + switch (machine_arch_type) {
103 + case MACH_TYPE_NEO1973_GTA01:
104 + s3c2410_gpio_setpin(GTA01_GPIO_BT_EN, on ? 0 : 1);
106 + case MACH_TYPE_NEO1973_GTA02:
107 + s3c2410_gpio_setpin(GTA02_GPIO_BT_EN, on ? 0 : 1);
113 @@ -107,9 +142,16 @@ static int __init gta01_bt_probe(struct platform_device *pdev)
115 dev_info(&pdev->dev, DRVMSG ": starting\n");
117 - /* we make sure that the voltage is off */
118 - pcf50606_onoff_set(pcf50606_global,
119 - PCF50606_REGULATOR_D1REG, 0);
120 + switch (machine_arch_type) {
121 + case MACH_TYPE_NEO1973_GTA01:
122 + /* we make sure that the voltage is off */
123 + pcf50606_onoff_set(pcf50606_global,
124 + PCF50606_REGULATOR_D1REG, 0);
126 + case MACH_TYPE_NEO1973_GTA02:
127 + /* FIXME: implementation */
130 /* we pull reset to low to make sure that the chip doesn't
131 * drain power through the reset line */
132 s3c2410_gpio_setpin(GTA01_GPIO_BT_EN, 0);
133 diff --git a/arch/arm/plat-s3c24xx/neo1973_pm_gps.c b/arch/arm/plat-s3c24xx/neo1973_pm_gps.c
134 index f8cf719..6bd8054 100644
135 --- a/arch/arm/plat-s3c24xx/neo1973_pm_gps.c
136 +++ b/arch/arm/plat-s3c24xx/neo1973_pm_gps.c
138 #include <linux/delay.h>
139 #include <linux/platform_device.h>
141 -#include <linux/pcf50606.h>
143 #include <asm/hardware.h>
145 +#include <asm/mach-types.h>
146 +#ifdef CONFIG_MACH_NEO1973_GTA01
147 #include <asm/arch/gta01.h>
148 +#include <linux/pcf50606.h>
151 +#ifdef CONFIG_MACH_NEO1973_GTA02
152 +#include <asm/arch/gta02.h>
153 +#include <linux/pcf50633.h>
156 /* This is the 2.8V supply for the RTC crystal, the mail clock crystal and
157 * the input to VDD_RF */
158 @@ -248,15 +256,42 @@ static int gps_power_1v5_get(void)
159 /* This is the POWERON pin */
160 static void gps_pwron_set(int on)
162 - s3c2410_gpio_setpin(GTA01_GPIO_GPS_PWRON, on);
163 +#ifdef CONFIG_MACH_NEO1973_GTA01
164 + if (machine_is_neo1973_gta01())
165 + s3c2410_gpio_setpin(GTA01_GPIO_GPS_PWRON, on);
166 +#endif /* CONFIG_MACH_NEO1973_GTA01 */
168 +#ifdef CONFIG_MACH_NEO1973_GTA02
169 + if (machine_is_neo1973_gta02()) {
171 + pcf50633_voltage_set(pcf50633_global,
172 + PCF50633_REGULATOR_LDO5, 3000);
173 + pcf50633_onoff_set(pcf50633_global,
174 + PCF50633_REGULATOR_LDO5, on);
176 +#endif /* CONFIG_MACH_NEO1973_GTA02 */
179 static int gps_pwron_get(void)
181 - if (s3c2410_gpio_getpin(GTA01_GPIO_GPS_PWRON))
185 +#ifdef CONFIG_MACH_NEO1973_GTA01
186 + if (machine_is_neo1973_gta01()) {
187 + if (s3c2410_gpio_getpin(GTA01_GPIO_GPS_PWRON))
192 +#endif /* CONFIG_MACH_NEO1973_GTA01 */
194 +#ifdef CONFIG_MACH_NEO1973_GTA02
195 + if (machine_is_neo1973_gta02()) {
196 + if (pcf50633_onoff_get(pcf50633_global, PCF50633_REGULATOR_LDO5))
201 +#endif /* CONFIG_MACH_NEO1973_GTA02 */
205 /* This is the nRESET pin */
206 @@ -441,17 +476,40 @@ static DEVICE_ATTR(power_sequence, 0644, power_sequence_read,
207 static int gta01_pm_gps_suspend(struct platform_device *pdev,
211 - gps_power_sequence_down();
212 +#ifdef CONFIG_MACH_NEO1973_GTA01
213 + if (machine_is_neo1973_gta01()) {
215 + gps_power_sequence_down();
217 +#endif /* CONFIG_MACH_NEO1973_GTA01 */
219 +#ifdef CONFIG_MACH_NEO1973_GTA02
220 + if (machine_is_neo1973_gta02()) {
222 + pcf50633_onoff_set(pcf50633_global,
223 + PCF50633_REGULATOR_LDO5, 0);
225 +#endif /* CONFIG_MACH_NEO1973_GTA02 */
230 static int gta01_pm_gps_resume(struct platform_device *pdev)
233 - gps_power_sequence_up();
235 +#ifdef CONFIG_MACH_NEO1973_GTA01
236 + if (machine_is_neo1973_gta01()) {
238 + gps_power_sequence_up();
240 +#endif /* CONFIG_MACH_NEO1973_GTA01 */
242 +#ifdef CONFIG_MACH_NEO1973_GTA02
243 + if (machine_is_neo1973_gta02()) {
245 + pcf50633_onoff_set(pcf50633_global,
246 + PCF50633_REGULATOR_LDO5, 1);
247 +#endif /* CONFIG_MACH_NEO1973_GTA02 */
252 @@ -476,59 +534,110 @@ static struct attribute_group gta01_gps_attr_group = {
253 .attrs = gta01_gps_sysfs_entries,
256 +static struct attribute *gta02_gps_sysfs_entries[] = {
257 + &dev_attr_pwron.attr,
261 +static struct attribute_group gta02_gps_attr_group = {
263 + .attrs = gta02_gps_sysfs_entries,
266 static int __init gta01_pm_gps_probe(struct platform_device *pdev)
268 - s3c2410_gpio_cfgpin(GTA01_GPIO_GPS_PWRON, S3C2410_GPIO_OUTPUT);
269 +#ifdef CONFIG_MACH_NEO1973_GTA01
270 + if (machine_is_neo1973_gta01()) {
271 + s3c2410_gpio_cfgpin(GTA01_GPIO_GPS_PWRON, S3C2410_GPIO_OUTPUT);
273 - switch (system_rev) {
274 - case GTA01v3_SYSTEM_REV:
276 - case GTA01v4_SYSTEM_REV:
277 - s3c2410_gpio_cfgpin(GTA01_GPIO_GPS_RESET, S3C2410_GPIO_OUTPUT);
279 - case GTA01Bv3_SYSTEM_REV:
280 - case GTA01Bv4_SYSTEM_REV:
281 - s3c2410_gpio_cfgpin(GTA01_GPIO_GPS_EN_3V3, S3C2410_GPIO_OUTPUT);
283 - case GTA01Bv2_SYSTEM_REV:
284 - s3c2410_gpio_cfgpin(GTA01_GPIO_GPS_EN_2V8, S3C2410_GPIO_OUTPUT);
285 - s3c2410_gpio_cfgpin(GTA01_GPIO_GPS_EN_3V, S3C2410_GPIO_OUTPUT);
286 - s3c2410_gpio_cfgpin(GTA01_GPIO_GPS_RESET, S3C2410_GPIO_OUTPUT);
289 - dev_warn(&pdev->dev, "Unknown GTA01 Revision 0x%x, "
290 - "AGPS PM features not available!!!\n",
295 + switch (system_rev) {
296 + case GTA01v3_SYSTEM_REV:
298 + case GTA01v4_SYSTEM_REV:
299 + s3c2410_gpio_cfgpin(GTA01_GPIO_GPS_RESET, S3C2410_GPIO_OUTPUT);
301 + case GTA01Bv3_SYSTEM_REV:
302 + case GTA01Bv4_SYSTEM_REV:
303 + s3c2410_gpio_cfgpin(GTA01_GPIO_GPS_EN_3V3, S3C2410_GPIO_OUTPUT);
305 + case GTA01Bv2_SYSTEM_REV:
306 + s3c2410_gpio_cfgpin(GTA01_GPIO_GPS_EN_2V8, S3C2410_GPIO_OUTPUT);
307 + s3c2410_gpio_cfgpin(GTA01_GPIO_GPS_EN_3V, S3C2410_GPIO_OUTPUT);
308 + s3c2410_gpio_cfgpin(GTA01_GPIO_GPS_RESET, S3C2410_GPIO_OUTPUT);
311 + dev_warn(&pdev->dev, "Unknown GTA01 Revision 0x%x, "
312 + "AGPS PM features not available!!!\n",
318 - gps_power_sequence_down();
319 + gps_power_sequence_down();
321 - switch (system_rev) {
322 - case GTA01v3_SYSTEM_REV:
323 - case GTA01v4_SYSTEM_REV:
324 - case GTA01Bv2_SYSTEM_REV:
325 - gta01_gps_sysfs_entries[ARRAY_SIZE(gta01_gps_sysfs_entries)-3] =
326 - &dev_attr_power_tcxo_2v8.attr;
328 - case GTA01Bv3_SYSTEM_REV:
329 - case GTA01Bv4_SYSTEM_REV:
330 - gta01_gps_sysfs_entries[ARRAY_SIZE(gta01_gps_sysfs_entries)-3] =
331 - &dev_attr_power_core_1v5.attr;
332 - gta01_gps_sysfs_entries[ARRAY_SIZE(gta01_gps_sysfs_entries)-2] =
333 - &dev_attr_power_vdd_core_1v5.attr;
336 + switch (system_rev) {
337 + case GTA01v3_SYSTEM_REV:
338 + case GTA01v4_SYSTEM_REV:
339 + case GTA01Bv2_SYSTEM_REV:
340 + gta01_gps_sysfs_entries[ARRAY_SIZE(gta01_gps_sysfs_entries)-3] =
341 + &dev_attr_power_tcxo_2v8.attr;
343 + case GTA01Bv3_SYSTEM_REV:
344 + case GTA01Bv4_SYSTEM_REV:
345 + gta01_gps_sysfs_entries[ARRAY_SIZE(gta01_gps_sysfs_entries)-3] =
346 + &dev_attr_power_core_1v5.attr;
347 + gta01_gps_sysfs_entries[ARRAY_SIZE(gta01_gps_sysfs_entries)-2] =
348 + &dev_attr_power_vdd_core_1v5.attr;
352 - return sysfs_create_group(&pdev->dev.kobj, >a01_gps_attr_group);
353 + return sysfs_create_group(&pdev->dev.kobj, >a01_gps_attr_group);
355 +#endif /* CONFIG_MACH_NEO1973_GTA01 */
357 +#ifdef CONFIG_MACH_NEO1973_GTA02
358 + if (machine_is_neo1973_gta02()) {
359 + switch (system_rev) {
360 + case GTA02v2_SYSTEM_REV:
361 + case GTA02v3_SYSTEM_REV:
362 + case GTA02v4_SYSTEM_REV:
363 + case GTA02v5_SYSTEM_REV:
364 + case GTA02v6_SYSTEM_REV:
365 + pcf50633_voltage_set(pcf50633_global,
366 + PCF50633_REGULATOR_LDO5, 3000);
367 + pcf50633_onoff_set(pcf50633_global,
368 + PCF50633_REGULATOR_LDO5, 0);
369 + dev_info(&pdev->dev, "FIC Neo1973 GPS Power Managerment:"
373 + dev_warn(&pdev->dev, "Unknown GTA02 Revision 0x%x, "
374 + "AGPS PM features not available!!!\n",
379 + return sysfs_create_group(&pdev->dev.kobj, >a02_gps_attr_group);
381 +#endif /* CONFIG_MACH_NEO1973_GTA02 */
385 static int gta01_pm_gps_remove(struct platform_device *pdev)
387 - gps_power_sequence_down();
388 - sysfs_remove_group(&pdev->dev.kobj, >a01_gps_attr_group);
389 +#ifdef CONFIG_MACH_NEO1973_GTA01
390 + if (machine_is_neo1973_gta01()) {
391 + gps_power_sequence_down();
392 + sysfs_remove_group(&pdev->dev.kobj, >a01_gps_attr_group);
394 +#endif /* CONFIG_MACH_NEO1973_GTA01 */
396 +#ifdef CONFIG_MACH_NEO1973_GTA02
397 + if (machine_is_neo1973_gta02()) {
398 + pcf50633_onoff_set(pcf50633_global, PCF50633_REGULATOR_LDO5, 0);
399 + sysfs_remove_group(&pdev->dev.kobj, >a02_gps_attr_group);
401 +#endif /* CONFIG_MACH_NEO1973_GTA02 */
405 diff --git a/arch/arm/plat-s3c24xx/neo1973_pm_gsm.c b/arch/arm/plat-s3c24xx/neo1973_pm_gsm.c
406 index a1615f8..13cb45b 100644
407 --- a/arch/arm/plat-s3c24xx/neo1973_pm_gsm.c
408 +++ b/arch/arm/plat-s3c24xx/neo1973_pm_gsm.c
410 #include <linux/errno.h>
412 #include <asm/hardware.h>
413 +#include <asm/mach-types.h>
414 #include <asm/arch/gta01.h>
416 +#ifdef CONFIG_MACH_NEO1973_GTA02
417 +#include <asm/arch/gta02.h>
418 +#include <linux/pcf50633.h>
419 +#include <asm/arch/regs-gpioj.h>
422 struct gta01pm_priv {
425 @@ -54,8 +61,16 @@ static ssize_t gsm_read(struct device *dev, struct device_attribute *attr,
426 if (s3c2410_gpio_getpin(GTA01_GPIO_MODEM_RST))
428 } else if (!strcmp(attr->attr.name, "download")) {
429 - if (s3c2410_gpio_getpin(GTA01_GPIO_MODEM_DNLOAD))
431 +#ifdef CONFIG_MACH_NEO1973_GTA01
432 + if (machine_is_neo1973_gta01())
433 + if (s3c2410_gpio_getpin(GTA01_GPIO_MODEM_DNLOAD))
436 +#ifdef CONFIG_MACH_NEO1973_GTA02
437 + if (machine_is_neo1973_gta02())
438 + if (s3c2410_gpio_getpin(GTA02_GPIO_nDL_GSM))
443 return strlcpy(buf, "0\n", 3);
444 @@ -70,32 +85,67 @@ static ssize_t gsm_write(struct device *dev, struct device_attribute *attr,
446 if (!strcmp(attr->attr.name, "power_on")) {
448 - dev_info(dev, "powering up GSM, thus disconnecting "
449 - "serial console\n");
450 + if (gta01_gsm.con) {
451 + dev_info(dev, "powering up GSM, thus "
452 + "disconnecting serial console\n");
455 console_stop(gta01_gsm.con);
458 if (gta01_gsm.gpio_ngsm_en)
459 s3c2410_gpio_setpin(gta01_gsm.gpio_ngsm_en, 0);
461 + switch (system_rev) {
462 +#ifdef CONFIG_MACH_NEO1973_GTA02
463 + case GTA02v2_SYSTEM_REV:
464 + case GTA02v3_SYSTEM_REV:
465 + case GTA02v4_SYSTEM_REV:
466 + case GTA02v5_SYSTEM_REV:
467 + case GTA02v6_SYSTEM_REV:
468 + pcf50633_gpio_set(pcf50633_global,
469 + PCF50633_GPIO2, 1);
474 s3c2410_gpio_setpin(GTA01_GPIO_MODEM_ON, 1);
476 s3c2410_gpio_setpin(GTA01_GPIO_MODEM_ON, 0);
478 + switch (system_rev) {
479 +#ifdef CONFIG_MACH_NEO1973_GTA02
480 + case GTA02v2_SYSTEM_REV:
481 + case GTA02v3_SYSTEM_REV:
482 + case GTA02v4_SYSTEM_REV:
483 + case GTA02v5_SYSTEM_REV:
484 + case GTA02v6_SYSTEM_REV:
485 + pcf50633_gpio_set(pcf50633_global,
486 + PCF50633_GPIO2, 0);
491 if (gta01_gsm.gpio_ngsm_en)
492 s3c2410_gpio_setpin(gta01_gsm.gpio_ngsm_en, 1);
495 + if (gta01_gsm.con) {
496 console_start(gta01_gsm.con);
498 - dev_info(dev, "powered down GSM, thus enabling "
499 - "serial console\n");
500 + dev_info(dev, "powered down GSM, thus enabling "
501 + "serial console\n");
504 } else if (!strcmp(attr->attr.name, "reset")) {
505 s3c2410_gpio_setpin(GTA01_GPIO_MODEM_RST, on);
506 } else if (!strcmp(attr->attr.name, "download")) {
507 - s3c2410_gpio_setpin(GTA01_GPIO_MODEM_DNLOAD, on);
508 +#ifdef CONFIG_MACH_NEO1973_GTA01
509 + if (machine_is_neo1973_gta01())
510 + s3c2410_gpio_setpin(GTA01_GPIO_MODEM_DNLOAD, on);
512 +#ifdef CONFIG_MACH_NEO1973_GTA02
513 + if (machine_is_neo1973_gta02())
514 + s3c2410_gpio_setpin(GTA02_GPIO_nDL_GSM, on);
519 @@ -111,6 +161,9 @@ static int gta01_gsm_suspend(struct platform_device *pdev, pm_message_t state)
520 /* GPIO state is saved/restored by S3C2410 core GPIO driver, so we
521 * don't need to do anything here */
523 + /* disable DL GSM to prevent jack_insert becoming flaoting */
524 + if (machine_is_neo1973_gta02())
525 + s3c2410_gpio_setpin(GTA02_GPIO_nDL_GSM, 1);
529 @@ -124,6 +177,8 @@ static int gta01_gsm_resume(struct platform_device *pdev)
530 if (s3c2410_gpio_getpin(GTA01_GPIO_MODEM_ON) && gta01_gsm.con)
531 console_stop(gta01_gsm.con);
533 + if (machine_is_neo1973_gta02())
534 + s3c2410_gpio_setpin(GTA02_GPIO_nDL_GSM, 0);
538 @@ -134,7 +189,7 @@ static int gta01_gsm_resume(struct platform_device *pdev)
539 static struct attribute *gta01_gsm_sysfs_entries[] = {
540 &dev_attr_power_on.attr,
541 &dev_attr_reset.attr,
543 + &dev_attr_download.attr,
547 @@ -158,8 +213,18 @@ static int __init gta01_gsm_probe(struct platform_device *pdev)
548 gta01_gsm.gpio_ngsm_en = GTA01Bv2_GPIO_nGSM_EN;
549 s3c2410_gpio_setpin(GTA01v3_GPIO_nGSM_EN, 0);
551 +#ifdef CONFIG_MACH_NEO1973_GTA02
552 + case GTA02v1_SYSTEM_REV:
553 + case GTA02v2_SYSTEM_REV:
554 + case GTA02v3_SYSTEM_REV:
555 + case GTA02v4_SYSTEM_REV:
556 + case GTA02v5_SYSTEM_REV:
557 + case GTA02v6_SYSTEM_REV:
558 + gta01_gsm.gpio_ngsm_en = 0;
562 - dev_warn(&pdev->dev, "Unknown GTA01 Revision 0x%x, "
563 + dev_warn(&pdev->dev, "Unknown Neo1973 Revision 0x%x, "
564 "some PM features not available!!!\n",
567 @@ -175,9 +240,13 @@ static int __init gta01_gsm_probe(struct platform_device *pdev)
571 - gta01_gsm.con = find_s3c24xx_console();
572 - if (!gta01_gsm.con)
573 - dev_warn(&pdev->dev, "cannot find S3C24xx console driver\n");
574 + if (machine_is_neo1973_gta01()) {
575 + gta01_gsm.con = find_s3c24xx_console();
576 + if (!gta01_gsm.con)
577 + dev_warn(&pdev->dev,
578 + "cannot find S3C24xx console driver\n");
580 + gta01_gsm.con = NULL;
582 return sysfs_create_group(&pdev->dev.kobj, >a01_gsm_attr_group);