tracking-2.6.27-rc2-include-path-changes.patch
[kernel.git] / arch / arm / plat-s3c24xx / neo1973_pm_gps.c
1 /*
2  * GPS Power Management code for the FIC Neo1973 GSM Phone
3  *
4  * (C) 2007 by Openmoko Inc.
5  * Author: Harald Welte <laforge@openmoko.org>
6  * All rights reserved.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 as
10  * published by the Free Software Foundation
11  *
12  */
13
14 #include <linux/module.h>
15 #include <linux/init.h>
16 #include <linux/kernel.h>
17 #include <linux/delay.h>
18 #include <linux/platform_device.h>
19
20 #include <mach/hardware.h>
21
22 #include <asm/mach-types.h>
23
24 #include <asm/plat-s3c24xx/neo1973.h>
25
26 #ifdef CONFIG_MACH_NEO1973_GTA01
27 #include <asm/arch/gta01.h>
28 #include <linux/pcf50606.h>
29 #endif
30
31 #ifdef CONFIG_MACH_NEO1973_GTA02
32 #include <asm/arch/gta02.h>
33 #include <linux/pcf50633.h>
34 #endif
35
36 struct neo1973_pm_gps_data {
37         int power_was_on;
38 };
39
40 static struct neo1973_pm_gps_data neo1973_gps;
41
42 int neo1973_pm_gps_is_on(void)
43 {
44         return neo1973_gps.power_was_on;
45 }
46 EXPORT_SYMBOL_GPL(neo1973_pm_gps_is_on);
47
48 /* This is the 2.8V supply for the RTC crystal, the mail clock crystal and
49  * the input to VDD_RF */
50 static void gps_power_2v8_set(int on)
51 {
52         switch (system_rev) {
53         case GTA01v3_SYSTEM_REV:
54         case GTA01v4_SYSTEM_REV:
55                 if (on)
56                         pcf50606_voltage_set(pcf50606_global,
57                                              PCF50606_REGULATOR_IOREG, 2800);
58                 pcf50606_onoff_set(pcf50606_global,
59                                    PCF50606_REGULATOR_IOREG, on);
60                 break;
61         case GTA01Bv2_SYSTEM_REV:
62                 s3c2410_gpio_setpin(GTA01_GPIO_GPS_EN_2V8, on);
63                         break;
64         case GTA01Bv3_SYSTEM_REV:
65         case GTA01Bv4_SYSTEM_REV:
66                 break;
67         }
68 }
69
70 static int gps_power_2v8_get(void)
71 {
72         int ret = 0;
73
74         switch (system_rev) {
75         case GTA01v3_SYSTEM_REV:
76         case GTA01v4_SYSTEM_REV:
77                 if (pcf50606_onoff_get(pcf50606_global,
78                                         PCF50606_REGULATOR_IOREG) &&
79                     pcf50606_voltage_get(pcf50606_global,
80                                          PCF50606_REGULATOR_IOREG) == 2800)
81                         ret = 1;
82                 break;
83         case GTA01Bv2_SYSTEM_REV:
84                 if (s3c2410_gpio_getpin(GTA01_GPIO_GPS_EN_2V8))
85                         ret = 1;
86                 break;
87         case GTA01Bv3_SYSTEM_REV:
88         case GTA01Bv4_SYSTEM_REV:
89                 break;
90         }
91
92         return ret;
93 }
94
95 /* This is the 3V supply (AVDD) for the external RF frontend (LNA bias) */
96 static void gps_power_3v_set(int on)
97 {
98         switch (system_rev) {
99         case GTA01v3_SYSTEM_REV:
100         case GTA01v4_SYSTEM_REV:
101                 if (on)
102                         pcf50606_voltage_set(pcf50606_global,
103                                              PCF50606_REGULATOR_D1REG, 3000);
104                 pcf50606_onoff_set(pcf50606_global,
105                                    PCF50606_REGULATOR_D1REG, on);
106                 break;
107         case GTA01Bv2_SYSTEM_REV:
108         case GTA01Bv3_SYSTEM_REV:
109         case GTA01Bv4_SYSTEM_REV:
110                 s3c2410_gpio_setpin(GTA01_GPIO_GPS_EN_3V, on);
111                 break;
112         }
113 }
114
115 static int gps_power_3v_get(void)
116 {
117         int ret = 0;
118
119         switch (system_rev) {
120         case GTA01v3_SYSTEM_REV:
121         case GTA01v4_SYSTEM_REV:
122                 if (pcf50606_onoff_get(pcf50606_global,
123                                        PCF50606_REGULATOR_D1REG) &&
124                     pcf50606_voltage_get(pcf50606_global,
125                                          PCF50606_REGULATOR_D1REG) == 3000)
126                         ret = 1;
127                 break;
128         case GTA01Bv2_SYSTEM_REV:
129         case GTA01Bv3_SYSTEM_REV:
130         case GTA01Bv4_SYSTEM_REV:
131                 if (s3c2410_gpio_getpin(GTA01_GPIO_GPS_EN_3V))
132                         ret = 1;
133                 break;
134         }
135
136         return ret;
137 }
138
139 /* This is the 3.3V supply for VDD_IO and VDD_LPREG input */
140 static void gps_power_3v3_set(int on)
141 {
142         switch (system_rev) {
143         case GTA01v3_SYSTEM_REV:
144         case GTA01v4_SYSTEM_REV:
145         case GTA01Bv2_SYSTEM_REV:
146                 if (on)
147                         pcf50606_voltage_set(pcf50606_global,
148                                              PCF50606_REGULATOR_DCD, 3300);
149                 pcf50606_onoff_set(pcf50606_global,
150                                    PCF50606_REGULATOR_DCD, on);
151                 break;
152         case GTA01Bv3_SYSTEM_REV:
153         case GTA01Bv4_SYSTEM_REV:
154                 s3c2410_gpio_setpin(GTA01_GPIO_GPS_EN_3V3, on);
155                 break;
156         }
157 }
158
159 static int gps_power_3v3_get(void)
160 {
161         int ret = 0;
162
163         switch (system_rev) {
164         case GTA01v3_SYSTEM_REV:
165         case GTA01v4_SYSTEM_REV:
166         case GTA01Bv2_SYSTEM_REV:
167                 if (pcf50606_onoff_get(pcf50606_global,
168                                        PCF50606_REGULATOR_DCD) &&
169                     pcf50606_voltage_get(pcf50606_global,
170                                          PCF50606_REGULATOR_DCD) == 3300)
171                         ret = 1;
172                 break;
173         case GTA01Bv3_SYSTEM_REV:
174         case GTA01Bv4_SYSTEM_REV:
175                 if (s3c2410_gpio_getpin(GTA01_GPIO_GPS_EN_3V3))
176                         ret = 1;
177                 break;
178         }
179
180         return ret;
181 }
182
183 /* This is the 2.5V supply for VDD_PLLREG and VDD_COREREG input */
184 static void gps_power_2v5_set(int on)
185 {
186         switch (system_rev) {
187         case GTA01v3_SYSTEM_REV:
188                 /* This is CORE_1V8 and cannot be disabled */
189                 break;
190         case GTA01v4_SYSTEM_REV:
191         case GTA01Bv2_SYSTEM_REV:
192         case GTA01Bv3_SYSTEM_REV:
193         case GTA01Bv4_SYSTEM_REV:
194                 if (on)
195                         pcf50606_voltage_set(pcf50606_global,
196                                              PCF50606_REGULATOR_D2REG, 2500);
197                 pcf50606_onoff_set(pcf50606_global,
198                                    PCF50606_REGULATOR_D2REG, on);
199                 break;
200         }
201 }
202
203 static int gps_power_2v5_get(void)
204 {
205         int ret = 0;
206
207         switch (system_rev) {
208         case GTA01v3_SYSTEM_REV:
209                 /* This is CORE_1V8 and cannot be disabled */
210                 ret = 1;
211                 break;
212         case GTA01v4_SYSTEM_REV:
213         case GTA01Bv2_SYSTEM_REV:
214         case GTA01Bv3_SYSTEM_REV:
215         case GTA01Bv4_SYSTEM_REV:
216                 if (pcf50606_onoff_get(pcf50606_global,
217                                        PCF50606_REGULATOR_D2REG) &&
218                     pcf50606_voltage_get(pcf50606_global,
219                                          PCF50606_REGULATOR_D2REG) == 2500)
220                         ret = 1;
221                 break;
222         }
223
224         return ret;
225 }
226
227 /* This is the 1.5V supply for VDD_CORE */
228 static void gps_power_1v5_set(int on)
229 {
230         switch (system_rev) {
231         case GTA01v3_SYSTEM_REV:
232         case GTA01v4_SYSTEM_REV:
233         case GTA01Bv2_SYSTEM_REV:
234                 /* This is switched via 2v5 */
235                 break;
236         case GTA01Bv3_SYSTEM_REV:
237         case GTA01Bv4_SYSTEM_REV:
238                 if (on)
239                         pcf50606_voltage_set(pcf50606_global,
240                                              PCF50606_REGULATOR_DCD, 1500);
241                 pcf50606_onoff_set(pcf50606_global,
242                                    PCF50606_REGULATOR_DCD, on);
243                 break;
244         }
245 }
246
247 static int gps_power_1v5_get(void)
248 {
249         int ret = 0;
250
251         switch (system_rev) {
252         case GTA01v3_SYSTEM_REV:
253         case GTA01v4_SYSTEM_REV:
254         case GTA01Bv2_SYSTEM_REV:
255                 /* This is switched via 2v5 */
256                 ret = 1;
257                 break;
258         case GTA01Bv3_SYSTEM_REV:
259         case GTA01Bv4_SYSTEM_REV:
260                 if (pcf50606_onoff_get(pcf50606_global,
261                                        PCF50606_REGULATOR_DCD) &&
262                     pcf50606_voltage_get(pcf50606_global,
263                                          PCF50606_REGULATOR_DCD) == 1500)
264                         ret = 1;
265                 break;
266         }
267
268         return ret;
269 }
270
271 /* This is the POWERON pin */
272 static void gps_pwron_set(int on)
273 {
274
275         neo1973_gps.power_was_on = !!on;
276
277 #ifdef CONFIG_MACH_NEO1973_GTA01
278         if (machine_is_neo1973_gta01())
279                 neo1973_gpb_setpin(GTA01_GPIO_GPS_PWRON, on);
280 #endif /* CONFIG_MACH_NEO1973_GTA01 */
281
282 #ifdef CONFIG_MACH_NEO1973_GTA02
283         if (machine_is_neo1973_gta02()) {
284                 if (on) {
285                         pcf50633_voltage_set(pcf50633_global,
286                                 PCF50633_REGULATOR_LDO5, 3000);
287                         /* return UART pins to being UART pins */
288                         s3c2410_gpio_cfgpin(S3C2410_GPH4, S3C2410_GPH4_TXD1);
289                         /* remove pulldown now it won't be floating any more */
290                         s3c2410_gpio_pullup(S3C2410_GPH5, 0);
291                 } else {
292                         /*
293                          * take care not to power unpowered GPS from UART TX
294                          * return them to GPIO and force low
295                          */
296                         s3c2410_gpio_cfgpin(S3C2410_GPH4, S3C2410_GPH4_OUTP);
297                         s3c2410_gpio_setpin(S3C2410_GPH4, 0);
298                         /* don't let RX from unpowered GPS float */
299                         s3c2410_gpio_pullup(S3C2410_GPH5, 1);
300                 }
301                 pcf50633_onoff_set(pcf50633_global,
302                         PCF50633_REGULATOR_LDO5, on);
303         }
304 #endif /* CONFIG_MACH_NEO1973_GTA02 */
305 }
306
307 static int gps_pwron_get(void)
308 {
309 #ifdef CONFIG_MACH_NEO1973_GTA01
310         if (machine_is_neo1973_gta01())
311                 return !!s3c2410_gpio_getpin(GTA01_GPIO_GPS_PWRON);
312 #endif /* CONFIG_MACH_NEO1973_GTA01 */
313
314 #ifdef CONFIG_MACH_NEO1973_GTA02
315         if (machine_is_neo1973_gta02())
316                 return !!pcf50633_onoff_get(pcf50633_global,
317                                                        PCF50633_REGULATOR_LDO5);
318 #endif /* CONFIG_MACH_NEO1973_GTA02 */
319         return -1;
320 }
321
322 /* This is the nRESET pin */
323 static void gps_rst_set(int on)
324 {
325         switch (system_rev) {
326         case GTA01v3_SYSTEM_REV:
327                 pcf50606_gpo0_set(pcf50606_global, on);
328                 break;
329         case GTA01v4_SYSTEM_REV:
330         case GTA01Bv2_SYSTEM_REV:
331         case GTA01Bv3_SYSTEM_REV:
332         case GTA01Bv4_SYSTEM_REV:
333                 s3c2410_gpio_setpin(GTA01_GPIO_GPS_RESET, on);
334                 break;
335         }
336 }
337
338 static int gps_rst_get(void)
339 {
340         switch (system_rev) {
341         case GTA01v3_SYSTEM_REV:
342                 if (pcf50606_gpo0_get(pcf50606_global))
343                         return 1;
344                 break;
345         case GTA01v4_SYSTEM_REV:
346         case GTA01Bv2_SYSTEM_REV:
347         case GTA01Bv3_SYSTEM_REV:
348         case GTA01Bv4_SYSTEM_REV:
349                 if (s3c2410_gpio_getpin(GTA01_GPIO_GPS_RESET))
350                         return 1;
351                 break;
352         }
353
354         return 0;
355 }
356
357 static ssize_t power_gps_read(struct device *dev,
358                               struct device_attribute *attr, char *buf)
359 {
360         int ret = 0;
361
362         if (!strcmp(attr->attr.name, "power_tcxo_2v8")) {
363                 ret = gps_power_2v8_get();
364         } else if (!strcmp(attr->attr.name, "power_avdd_3v")) {
365                 ret = gps_power_3v_get();
366         } else if (!strcmp(attr->attr.name, "pwron")) {
367                 ret = gps_pwron_get();
368         } else if (!strcmp(attr->attr.name, "reset")) {
369                 ret = gps_rst_get();
370         } else if (!strcmp(attr->attr.name, "power_lp_io_3v3")) {
371                 ret = gps_power_3v3_get();
372         } else if (!strcmp(attr->attr.name, "power_pll_core_2v5")) {
373                 ret = gps_power_2v5_get();
374         } else if (!strcmp(attr->attr.name, "power_core_1v5") ||
375                    !strcmp(attr->attr.name, "power_vdd_core_1v5")) {
376                 ret = gps_power_1v5_get();
377         }
378
379         if (ret)
380                 return strlcpy(buf, "1\n", 3);
381         else
382                 return strlcpy(buf, "0\n", 3);
383 }
384
385 static ssize_t power_gps_write(struct device *dev,
386                                struct device_attribute *attr, const char *buf,
387                                size_t count)
388 {
389         unsigned long on = simple_strtoul(buf, NULL, 10);
390
391         if (!strcmp(attr->attr.name, "power_tcxo_2v8")) {
392                 gps_power_2v8_set(on);
393         } else if (!strcmp(attr->attr.name, "power_avdd_3v")) {
394                 gps_power_3v_set(on);
395         } else if (!strcmp(attr->attr.name, "pwron")) {
396                 gps_pwron_set(on);
397         } else if (!strcmp(attr->attr.name, "reset")) {
398                 gps_rst_set(on);
399         } else if (!strcmp(attr->attr.name, "power_lp_io_3v3")) {
400                 gps_power_3v3_set(on);
401         } else if (!strcmp(attr->attr.name, "power_pll_core_2v5")) {
402                 gps_power_2v5_set(on);
403         } else if (!strcmp(attr->attr.name, "power_core_1v5") ||
404                    !strcmp(attr->attr.name, "power_vdd_core_1v5")) {
405                 gps_power_1v5_set(on);
406         }
407
408         return count;
409 }
410
411 static void gps_power_sequence_up(void)
412 {
413         /* According to PMB2520 Data Sheet, Rev. 2006-06-05,
414          * Chapter 4.2.2 */
415
416         /* nRESET must be asserted low */
417         gps_rst_set(0);
418
419         /* POWERON must be de-asserted (low) */
420         gps_pwron_set(0);
421
422         /* Apply VDD_IO and VDD_LPREG_IN */
423         gps_power_3v3_set(1);
424
425         /* VDD_COREREG_IN, VDD_PLLREG_IN */
426         gps_power_1v5_set(1);
427         gps_power_2v5_set(1);
428
429         /* and VDD_RF may be applied */
430         gps_power_2v8_set(1);
431
432         /* We need to enable AVDD, since in GTA01Bv3 it is
433          * shared with RFREG_IN */
434         gps_power_3v_set(1);
435
436         msleep(3);      /* Is 3ms enough? */
437
438         /* De-asert nRESET */
439         gps_rst_set(1);
440
441         /* Switch power on */
442         gps_pwron_set(1);
443
444 }
445
446 static void gps_power_sequence_down(void)
447 {
448         /* According to PMB2520 Data Sheet, Rev. 2006-06-05,
449          * Chapter 4.2.3.1 */
450         gps_pwron_set(0);
451
452         /* Don't disable AVDD before PWRON is cleared, since
453          * in GTA01Bv3, AVDD and RFREG_IN are shared */
454         gps_power_3v_set(0);
455
456         /* Remove VDD_COREREG_IN, VDD_PLLREG_IN and VDD_REFREG_IN */
457         gps_power_1v5_set(0);
458         gps_power_2v5_set(0);
459         gps_power_2v8_set(0);
460
461         /* Remove VDD_LPREG_IN and VDD_IO */
462         gps_power_3v3_set(0);
463 }
464
465
466 static ssize_t power_sequence_read(struct device *dev,
467                                    struct device_attribute *attr,
468                                    char *buf)
469 {
470         return strlcpy(buf, "power_up power_down\n", PAGE_SIZE);
471 }
472
473 static ssize_t power_sequence_write(struct device *dev,
474                                     struct device_attribute *attr,
475                                     const char *buf, size_t count)
476 {
477         dev_dbg(dev, "wrote: '%s'\n", buf);
478
479         if (!strncmp(buf, "power_up", 8))
480                 gps_power_sequence_up();
481         else if (!strncmp(buf, "power_down", 10))
482                 gps_power_sequence_down();
483         else
484                 return -EINVAL;
485
486         return count;
487 }
488
489 static DEVICE_ATTR(power_tcxo_2v8, 0644, power_gps_read, power_gps_write);
490 static DEVICE_ATTR(power_avdd_3v, 0644, power_gps_read, power_gps_write);
491 static DEVICE_ATTR(pwron, 0644, power_gps_read, power_gps_write);
492 static DEVICE_ATTR(reset, 0644, power_gps_read, power_gps_write);
493 static DEVICE_ATTR(power_lp_io_3v3, 0644, power_gps_read, power_gps_write);
494 static DEVICE_ATTR(power_pll_core_2v5, 0644, power_gps_read, power_gps_write);
495 static DEVICE_ATTR(power_core_1v5, 0644, power_gps_read, power_gps_write);
496 static DEVICE_ATTR(power_vdd_core_1v5, 0644, power_gps_read, power_gps_write);
497 static DEVICE_ATTR(power_sequence, 0644, power_sequence_read,
498                    power_sequence_write);
499
500 #ifdef CONFIG_PM
501 static int gta01_pm_gps_suspend(struct platform_device *pdev,
502                                 pm_message_t state)
503 {
504 #ifdef CONFIG_MACH_NEO1973_GTA01
505         if (machine_is_neo1973_gta01()) {
506                 /* FIXME */
507                 gps_power_sequence_down();
508         }
509 #endif /* CONFIG_MACH_NEO1973_GTA01 */
510
511 #ifdef CONFIG_MACH_NEO1973_GTA02
512         if (machine_is_neo1973_gta02())
513                 gps_pwron_set(0);
514 #endif /* CONFIG_MACH_NEO1973_GTA02 */
515
516         return 0;
517 }
518
519 static int gta01_pm_gps_resume(struct platform_device *pdev)
520 {
521 #ifdef CONFIG_MACH_NEO1973_GTA01
522         if (machine_is_neo1973_gta01())
523                 if (neo1973_gps.power_was_on)
524                         gps_power_sequence_up();
525 #endif /* CONFIG_MACH_NEO1973_GTA01 */
526
527 #ifdef CONFIG_MACH_NEO1973_GTA02
528         if (machine_is_neo1973_gta02())
529                 if (neo1973_gps.power_was_on)
530                     gps_pwron_set(1);
531 #endif /* CONFIG_MACH_NEO1973_GTA02 */
532
533         return 0;
534 }
535 #else
536 #define gta01_pm_gps_suspend    NULL
537 #define gta01_pm_gps_resume     NULL
538 #endif
539
540 static struct attribute *gta01_gps_sysfs_entries[] = {
541         &dev_attr_power_avdd_3v.attr,
542         &dev_attr_pwron.attr,
543         &dev_attr_reset.attr,
544         &dev_attr_power_lp_io_3v3.attr,
545         &dev_attr_power_pll_core_2v5.attr,
546         &dev_attr_power_sequence.attr,
547         NULL,   /* power_core_1v5 */
548         NULL,   /* power_vdd_core_1v5 */
549         NULL    /* terminating entry */
550 };
551
552 static struct attribute_group gta01_gps_attr_group = {
553         .name   = NULL,
554         .attrs  = gta01_gps_sysfs_entries,
555 };
556
557 static struct attribute *gta02_gps_sysfs_entries[] = {
558         &dev_attr_pwron.attr,
559         NULL
560 };
561
562 static struct attribute_group gta02_gps_attr_group = {
563         .name   = NULL,
564         .attrs  = gta02_gps_sysfs_entries,
565 };
566
567 static int __init gta01_pm_gps_probe(struct platform_device *pdev)
568 {
569 #ifdef CONFIG_MACH_NEO1973_GTA01
570         if (machine_is_neo1973_gta01()) {
571                 s3c2410_gpio_cfgpin(GTA01_GPIO_GPS_PWRON, S3C2410_GPIO_OUTPUT);
572
573                 switch (system_rev) {
574                 case GTA01v3_SYSTEM_REV:
575                         break;
576                 case GTA01v4_SYSTEM_REV:
577                         s3c2410_gpio_cfgpin(GTA01_GPIO_GPS_RESET, S3C2410_GPIO_OUTPUT);
578                         break;
579                 case GTA01Bv3_SYSTEM_REV:
580                 case GTA01Bv4_SYSTEM_REV:
581                         s3c2410_gpio_cfgpin(GTA01_GPIO_GPS_EN_3V3, S3C2410_GPIO_OUTPUT);
582                         /* fallthrough */
583                 case GTA01Bv2_SYSTEM_REV:
584                         s3c2410_gpio_cfgpin(GTA01_GPIO_GPS_EN_2V8, S3C2410_GPIO_OUTPUT);
585                         s3c2410_gpio_cfgpin(GTA01_GPIO_GPS_EN_3V, S3C2410_GPIO_OUTPUT);
586                         s3c2410_gpio_cfgpin(GTA01_GPIO_GPS_RESET, S3C2410_GPIO_OUTPUT);
587                         break;
588                 default:
589                         dev_warn(&pdev->dev, "Unknown GTA01 Revision 0x%x, "
590                                 "AGPS PM features not available!!!\n",
591                                 system_rev);
592                         return -1;
593                         break;
594                 }
595
596                 gps_power_sequence_down();
597
598                 switch (system_rev) {
599                 case GTA01v3_SYSTEM_REV:
600                 case GTA01v4_SYSTEM_REV:
601                 case GTA01Bv2_SYSTEM_REV:
602                         gta01_gps_sysfs_entries[ARRAY_SIZE(gta01_gps_sysfs_entries)-3] =
603                                                 &dev_attr_power_tcxo_2v8.attr;
604                         break;
605                 case GTA01Bv3_SYSTEM_REV:
606                 case GTA01Bv4_SYSTEM_REV:
607                         gta01_gps_sysfs_entries[ARRAY_SIZE(gta01_gps_sysfs_entries)-3] =
608                                                 &dev_attr_power_core_1v5.attr;
609                         gta01_gps_sysfs_entries[ARRAY_SIZE(gta01_gps_sysfs_entries)-2] =
610                                                 &dev_attr_power_vdd_core_1v5.attr;
611                         break;
612                 }
613
614                 return sysfs_create_group(&pdev->dev.kobj, &gta01_gps_attr_group);
615         }
616 #endif /* CONFIG_MACH_NEO1973_GTA01 */
617
618 #ifdef CONFIG_MACH_NEO1973_GTA02
619         if (machine_is_neo1973_gta02()) {
620                 switch (system_rev) {
621                 case GTA02v2_SYSTEM_REV:
622                 case GTA02v3_SYSTEM_REV:
623                 case GTA02v4_SYSTEM_REV:
624                 case GTA02v5_SYSTEM_REV:
625                 case GTA02v6_SYSTEM_REV:
626                         pcf50633_voltage_set(pcf50633_global,
627                                 PCF50633_REGULATOR_LDO5, 3000);
628                         pcf50633_onoff_set(pcf50633_global,
629                                 PCF50633_REGULATOR_LDO5, 0);
630                         dev_info(&pdev->dev, "FIC Neo1973 GPS Power Managerment:"
631                                  "starting\n");
632                         break;
633                 default:
634                         dev_warn(&pdev->dev, "Unknown GTA02 Revision 0x%x, "
635                                 "AGPS PM features not available!!!\n",
636                                 system_rev);
637                         return -1;
638                         break;
639                 }
640                 return sysfs_create_group(&pdev->dev.kobj, &gta02_gps_attr_group);
641         }
642 #endif /* CONFIG_MACH_NEO1973_GTA02 */
643         return -1;
644 }
645
646 static int gta01_pm_gps_remove(struct platform_device *pdev)
647 {
648 #ifdef CONFIG_MACH_NEO1973_GTA01
649         if (machine_is_neo1973_gta01()) {
650                 gps_power_sequence_down();
651                 sysfs_remove_group(&pdev->dev.kobj, &gta01_gps_attr_group);
652         }
653 #endif /* CONFIG_MACH_NEO1973_GTA01 */
654
655 #ifdef CONFIG_MACH_NEO1973_GTA02
656         if (machine_is_neo1973_gta02()) {
657                 pcf50633_onoff_set(pcf50633_global, PCF50633_REGULATOR_LDO5, 0);
658                 sysfs_remove_group(&pdev->dev.kobj, &gta02_gps_attr_group);
659         }
660 #endif /* CONFIG_MACH_NEO1973_GTA02 */
661         return 0;
662 }
663
664 static struct platform_driver gta01_pm_gps_driver = {
665         .probe          = gta01_pm_gps_probe,
666         .remove         = gta01_pm_gps_remove,
667         .suspend        = gta01_pm_gps_suspend,
668         .resume         = gta01_pm_gps_resume,
669         .driver         = {
670                 .name           = "neo1973-pm-gps",
671         },
672 };
673
674 static int __devinit gta01_pm_gps_init(void)
675 {
676         return platform_driver_register(&gta01_pm_gps_driver);
677 }
678
679 static void gta01_pm_gps_exit(void)
680 {
681         platform_driver_unregister(&gta01_pm_gps_driver);
682 }
683
684 module_init(gta01_pm_gps_init);
685 module_exit(gta01_pm_gps_exit);
686
687 MODULE_LICENSE("GPL");
688 MODULE_AUTHOR("Harald Welte <laforge@openmoko.org>");
689 MODULE_DESCRIPTION("FIC Neo1973 GPS Power Management");