2 * (C) 2006-2007 by OpenMoko, Inc.
3 * Author: Harald Welte <laforge@openmoko.org>
5 * based on existing S3C2410 startup code in u-boot:
8 * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
9 * Marius Groeger <mgroeger@sysgo.de>
12 * David Mueller, ELSOFT AG, <d.mueller@elsoft.ch>
14 * See file CREDITS for list of people who contributed to this
17 * This program is free software; you can redistribute it and/or
18 * modify it under the terms of the GNU General Public License as
19 * published by the Free Software Foundation; either version 2 of
20 * the License, or (at your option) any later version.
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
27 * You should have received a copy of the GNU General Public License
28 * along with this program; if not, write to the Free Software
29 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
37 #include <asm/atomic.h>
39 #include "../common/neo1973.h"
40 #include "../common/jbt6k74.h"
44 DECLARE_GLOBAL_DATA_PTR;
46 /* That many seconds the power key needs to be pressed to power up */
47 #define POWER_KEY_SECONDS 1
49 /* If the battery voltage is below this, we can't provide stable power */
50 #define SAFE_POWER_MILLIVOLT 3400
52 #if defined(CONFIG_ARCH_GTA02_v1)
53 //#define M_MDIV 0x7f /* Fout = 405.00MHz */
54 #define M_MDIV 0x7d /* Fout = 399.00MHz */
70 extern void smedia3362_lcm_reset(int);
71 extern void glamo_core_init(void);
73 unsigned int neo1973_wakeup_cause;
74 extern unsigned char booted_from_nand;
75 extern unsigned char booted_from_nor;
76 extern int nobootdelay;
77 extern int udc_usb_maxcurrent;
79 char __cfg_prompt[20] = "GTA02vXX # ";
82 * In >GTA02v5, use gta02_revision to test for features, not
83 * CONFIG_GTA02_REVISION or CONFIG_ARCH_GTA02_vX !
87 static uint16_t gpb_shadow = 0; /* to work around GTA02v5 LED bug */
89 int gta02_get_pcb_revision(void);
91 static inline void delay (unsigned long loops)
93 __asm__ volatile ("1:\n"
95 "bne 1b":"=r" (loops):"0" (loops));
99 GTA02_LED_PWR_ORANGE = 0,
100 GTA02_LED_PWR_BLUE = 1,
101 GTA02_LED_AUX_RED = 2,
105 * Miscellaneous platform dependent initialisations
108 static void cpu_speed(int mdiv, int pdiv, int sdiv, int clkdivn)
110 S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
113 clk_power->CLKDIVN = clkdivn;
115 /* to reduce PLL lock time, adjust the LOCKTIME register */
116 clk_power->LOCKTIME = 0xFFFFFF;
119 clk_power->MPLLCON = ((mdiv << 12) + (pdiv << 4) + sdiv);
121 /* some delay between MPLL and UPLL */
125 clk_power->UPLLCON = ((U_M_MDIV << 12) + (U_M_PDIV << 4) + U_M_SDIV);
127 /* some delay between MPLL and UPLL */
133 S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
135 /* FCLK = 200MHz values from cpu/arm920t/start.S */
136 cpu_speed(142, 7, 1, 3); /* 200MHZ, 1:2:4 */
138 /* set up the I/O ports */
139 #if CONFIG_GTA02_REVISION == 1
140 gpio->GPACON = 0x007E1FFF;
141 gpio->GPADAT |= (1 << 16); /* Set GPA16 to high (nNAND_WP) */
143 gpio->GPBCON = 0x00155555;
144 gpio->GPBUP = 0x000007FF;
146 gpio->GPCCON = 0x55551155;
147 gpio->GPCUP = 0x0000FFFF;
149 gpio->GPDCON = 0x55555555;
150 gpio->GPDUP = 0x0000FFFF;
152 gpio->GPECON = 0xAAAAAAAA;
153 gpio->GPEUP = 0x0000FFFF;
155 gpio->GPFCON = 0x0000AAAA;
156 gpio->GPFUP = 0x000000FF;
158 gpio->GPGCON = 0x013DFDFA;
159 gpio->GPGUP = 0x0000FFFF;
161 gpio->GPHCON = 0x0028AAAA;
162 gpio->GPHUP = 0x000007FF;
164 gpio->GPJCON = 0x1545541;
165 #elif CONFIG_GTA02_REVISION == 2
166 gpio->GPACON = 0x007E1FFF;
167 gpio->GPADAT |= (1 << 16); /* Set GPA16 to high (nNAND_WP) */
169 gpio->GPBCON = 0x00155555;
170 gpio->GPBUP = 0x000007FF;
172 gpio->GPCCON = 0x55415155;
173 gpio->GPCUP = 0x0000FFFF;
175 gpio->GPDCON = 0x55555555;
176 gpio->GPDUP = 0x0000FFFF;
178 gpio->GPECON = 0xAAAAAAAA;
179 gpio->GPEUP = 0x0000FFFF;
181 gpio->GPFCON = 0x0000AAAA;
182 gpio->GPFUP = 0x000000FF;
184 gpio->GPGCON = 0x0156FE7A;
185 gpio->GPGUP = 0x0000FFFF;
187 gpio->GPHCON = 0x001AAAAA;
188 gpio->GPHUP = 0x000007FF;
190 gpio->GPJCON = 0x1551544;
191 gpio->GPJUP = 0x1ffff;
192 gpio->GPJDAT |= (1 << 4); /* Set GPJ4 to high (nGSM_EN) */
193 #elif CONFIG_GTA02_REVISION >= 3
194 gpio->GPACON = 0x007E5FFF;
195 gpio->GPADAT |= (1 << 16); /* Set GPA16 to high (nNAND_WP) */
197 gpio->GPBCON = 0x00155555;
198 gpio->GPBUP = 0x000007FF;
201 * PCB rev index found on C13, C15, D0, D3 and D4. These are NC or
202 * pulled up by 10K. Therefore to ensure no current flows when they
203 * are not interrogated, we drive them high. When we interrogate them
204 * we make them pulled them down inputs briefly and set them high op
208 /* pulldown on "PIO_5" BT module to stop float when unpowered
209 * C13 and C15 are b0 and b1 of PCB rev index
211 gpio->GPCCON = 0x55555155;
212 gpio->GPCUP = 0x0000FFFF & ~(1 << 5);
213 gpio->GPCDAT |= (1 << 13) | (1 << 15); /* index detect -> hi */
215 /* D0, D3 and D4 are b2, b3 and b4 of PCB rev index */
216 gpio->GPDCON = 0x55555555;
217 gpio->GPDUP = 0x0000FFFF;
218 gpio->GPDDAT |= (1 << 0) | (1 << 3) | (1 << 4); /* index detect -> hi */
220 /* pulldown on GPE11 / SPIMISO0 - goes to debug board and will float */
221 gpio->GPECON = 0xAAAAAAAA;
222 gpio->GPEUP = 0x0000FFFF & ~(1 << 11);
224 /* pulldown on GPF03: TP-4705+debug - debug conn will float */
225 gpio->GPFCON = 0x0000AAAA;
226 gpio->GPFUP = 0x000000FF & ~(1 << 3);
228 gpio->GPGCON = 0x01AAFE79;
229 gpio->GPGUP = 0x0000FFFF;
231 /* pulldown on GPH08: UEXTCLK, just floats!
232 * pulldown GPH0 -- nCTS0 / RTS_MODEM -- floats when GSM off
233 * pulldown GPH3 -- RXD[0] / TX_MODEM -- floats when GSM off
235 gpio->GPHCON = 0x001AAAAA;
236 gpio->GPHUP = 0x000007FF & ~(1 << 8) & ~(1 << 0) & ~(1 << 3);
238 /* pulldown on GPJ00: input, just floats! */
239 /* pulldown on GPJ07: WLAN module WLAN_GPIO0, no ext pull */
240 gpio->GPJCON = 0x1551544;
241 gpio->GPJUP = 0x1ffff & ~(1 << 0) & ~(1 << 7);
242 gpio->GPJDAT |= (1 << 4) | (1 << 6);
243 /* Set GPJ4 to high (nGSM_EN) */
244 /* Set GPJ6 to high (nDL_GSM) */
245 gpio->GPJDAT &= ~(1 << 5); /* Set GPJ5 to low 3D RST */
246 gpio->GPJDAT &= ~(1 << 5); /* Set GPJ5 to low 3D RST */
248 /* leaving Glamo forced to Reset# active here killed
249 * U-Boot when you touched the memory region
252 gpio->GPJDAT |= (1 << 5); /* Set GPJ5 to high 3D RST */
254 #error Please define GTA02 version
257 /* arch number of SMDK2410-Board */
258 gd->bd->bi_arch_number = MACH_TYPE_NEO1973_GTA02;
260 /* adress of boot parameters */
261 gd->bd->bi_boot_params = 0x30000100;
267 * Since the NOR at address 0 is replaced by SteppingStone when the AUX
268 * button is released, we would crash when an interrupt arrives (e.g.,
271 * We solve this as follows: we copy the vector table to RAM at address
272 * 0x30000000 and then use the PID feature in the 920T MMU to map all
273 * addresses in the range 0x0....... to 0x3....... without actually
274 * setting up page mappings in the MMU. Thus, vectors are then
275 * retrieved from their location in RAM.
277 * Note that the mapping is done in lib_arm/interrupts.c, so that it
278 * automatically tracks whether we allow interrupts or not. This is
279 * particularly necessary when we boot, since the operating system may
280 * not expect to find this sort of mapping to be active.
282 #ifdef CONFIG_GTA02_REVISION
286 memcpy((void *) 0x30000000, &_start, 0x40);
292 static void set_revision(void)
294 int rev = gta02_get_pcb_revision();
297 if (CONFIG_GTA02_REVISION < 5)
298 gta02_revision = CONFIG_GTA02_REVISION;
308 printf("Unrecognized hardware revision 0x%03x. "
309 "Defaulting to GTA02v6.\n", rev);
313 sprintf(__cfg_prompt, "GTA02v%d # ", gta02_revision);
315 #if 1 /* remove these after checking that Andy doesn't need them anymore */
316 printf("PCB rev: 0x%03X\n", rev);
317 /* expose in the env so we can add to kernel commandline */
318 sprintf(buf, "0x%03X", rev);
319 setenv("pcb_rev", buf);
323 static void poll_charger(void)
325 if (pcf50633_read_charger_type() == 1000)
326 pcf50633_usb_maxcurrent(1000);
327 else /* track what the time-critical udc callback allows us */
328 if (pcf50633_usb_last_maxcurrent != udc_usb_maxcurrent)
329 pcf50633_usb_maxcurrent(udc_usb_maxcurrent);
332 static int have_int(uint8_t mask1, uint8_t mask2);
334 static void clear_pmu_int(void)
336 S3C24X0_INTERRUPT * const intr = S3C24X0_GetBase_INTERRUPT();
337 S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
339 /* read the PMU's interrupt register and store what we found for later
343 /* clear EINT9/GPG1 in the MCU's interrupt path */
344 gpio->EINTPEND = 1 << 9;
345 intr->SRCPND = BIT_EINT8_23;
346 intr->INTPND = BIT_EINT8_23;
349 static void cpu_idle(void)
351 S3C24X0_INTERRUPT * const intr = S3C24X0_GetBase_INTERRUPT();
352 S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
353 S3C24X0_CLOCK_POWER * const clk = S3C24X0_GetBase_CLOCK_POWER();
357 * We don't want to execute interrupts throughout all this, since
358 * u-boot's interrupt handling code isn't modular, and getting a "real"
359 * interrupt without clearing it in the interrupt handler would cause
360 * us to loop permanently.
362 local_irq_save(flags);
364 /* enable PMU interrupts */
365 intr->INTMSK &= ~BIT_EINT8_23;
366 gpio->EINTMASK &= ~(1 << 9);
369 clk->CLKCON |= 1 << 2;
371 /* disable PMU interrupts */
372 intr->INTMSK |= BIT_EINT8_23;
373 gpio->EINTMASK |= 1 << 9;
375 /* collect PMU interrupts and clear them */
379 local_irq_restore(flags);
382 static int charger_is_present(void)
384 /* is charger or power adapter present? */
385 return !!(pcf50633_reg_read(PCF50633_REG_MBCS1) & 3);
388 static int battery_is_present(void)
390 /* battery less than bvmlvl -> don't boot */
391 return !(pcf50633_reg_read(PCF50633_REG_BVMCTL) & 1);
394 static int battery_is_good(void)
396 /* battery is absent -> don't boot */
397 if (!battery_is_present())
400 /* we could try to boot, but we'll probably die on the way */
401 if (pcf50633_read_battvolt() < SAFE_POWER_MILLIVOLT)
407 static int wait_for_power(void)
410 * TODO: this function should also check if charger is still attached
411 * it makes no sense to wait otherwise.
421 /* we have plenty of external power but no visible battery ->
422 * don't hang around trying to charge, try to boot */
423 if (!battery_is_present() && (pcf50633_usb_last_maxcurrent >= 500))
426 /* cpu_idle sits with interrupts off destroying USB operation
427 * don't run it unless we are in trouble
429 if (!battery_is_good())
434 if (neo1973_new_second()) {
436 * Probe the battery only if the current LED cycle is
437 * about to end, so that it had time to discharge.
439 if (led_cycle && battery_is_good())
442 /* check if charger is present, otherwise stop start up */
443 if (!charger_is_present()) {
450 led_cycle = !seconds || (seconds & 1);
453 * Blink the AUX LED, unless it's broken (which is the case in
454 * GTA02v5 it is) and draws excessive current, which we just
455 * can't afford in this delicate situation.
457 if (gta02_revision > 5)
458 neo1973_led(GTA02_LED_AUX_RED, led_cycle);
460 /* alternate LED and charger cycles */
461 pcf50633_reg_set_bit_mask(PCF50633_REG_MBCC1, 1, !led_cycle);
463 /* cancel shutdown timer to keep charging
464 * it can get triggered by lowvsys along the way but if it
465 * didn't kill us then don't let it kill us later
467 pcf50633_reg_write(PCF50633_REG_OOCSHDWN, 4);
470 /* switch off the AUX LED */
471 neo1973_led(GTA02_LED_AUX_RED, 0);
473 /* do we have power now? */
477 static void pcf50633_late_init(void)
479 #ifdef CONFIG_ARCH_GTA02_v1
480 uint8_t pwren = 1; /* always on */
481 uint8_t recent = 0; /* antiques don't have that */
483 uint8_t pwren = 2; /* enabled if GPIO1 = HIGH */
484 uint8_t recent = 1; /* always on */
487 pcf50633_reg_write(PCF50633_REG_LDO1ENA, pwren);
488 pcf50633_reg_write(PCF50633_REG_LDO2ENA, 2); /* enabled if GPIO1 = H */
489 pcf50633_reg_write(PCF50633_REG_LDO5ENA, recent);
490 pcf50633_reg_write(PCF50633_REG_LDO6ENA, recent);
492 pcf50633_reg_write(PCF50633_REG_MBCC5, 0xff); /* 1A USB fast charge */
494 pcf50633_reg_set_bit_mask(PCF50633_REG_MBCC1, 1, 1); /* charge ! */
497 int board_late_init(void)
499 S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
502 int menu_vote = 0; /* <= 0: no, > 0: yes */
505 char *env_stop_in_menu;
509 /* Initialize the Power Management Unit with a safe register set */
512 /* obtain wake-up reason */
513 int1 = pcf50633_reg_read(PCF50633_REG_INT1);
514 int2 = pcf50633_reg_read(PCF50633_REG_INT2);
516 /* if there's no other reason, must be regular reset */
517 neo1973_wakeup_cause = NEO1973_WAKEUP_RESET;
519 if (!booted_from_nand && !booted_from_nor)
522 /* save wake-up reason in environment */
523 sprintf(buf, "0x%02x", int1);
524 setenv("pcf50633_int1", buf);
525 sprintf(buf, "0x%02x", int2);
526 setenv("pcf50633_int2", buf);
528 if (int1 & PCF50633_INT1_ALARM) {
529 /* we've been woken up by RTC alarm, boot */
530 neo1973_wakeup_cause = NEO1973_WAKEUP_ALARM;
533 if (int1 & PCF50633_INT1_USBINS) {
534 /* we've been woken up by charger insert */
535 neo1973_wakeup_cause = NEO1973_WAKEUP_CHARGER;
538 if (int2 & PCF50633_INT2_ONKEYF) {
539 /* we've been woken up by a falling edge of the onkey */
540 neo1973_wakeup_cause = NEO1973_WAKEUP_POWER_KEY;
543 if (neo1973_wakeup_cause == NEO1973_WAKEUP_CHARGER) {
544 /* if we still think it was only a charger insert, boot */
550 while (neo1973_wakeup_cause == NEO1973_WAKEUP_RESET ||
551 neo1973_on_key_pressed()) {
553 if (neo1973_aux_key_pressed())
558 if (neo1973_new_second())
560 if (seconds >= POWER_KEY_SECONDS)
563 /* Power off if minimum number of seconds not reached */
567 /* Power off if no battery is present and only 100mA is available */
568 if (!wait_for_power())
571 pcf50633_late_init();
572 cpu_speed(M_MDIV, M_PDIV, M_SDIV, 5); /* 400MHZ, 1:4:8 */
574 /* issue a short pulse with the vibrator */
575 neo1973_led(GTA02_LED_AUX_RED, 1);
578 neo1973_led(GTA02_LED_AUX_RED, 0);
581 #if defined(CONFIG_ARCH_GTA02_v1)
582 /* Glamo3362 reset and power cycle */
583 gpio->GPJDAT &= ~0x000000001; /* GTA02v1_GPIO_3D_RESET */
584 pcf50633_reg_write(PCF50633_REG_DOWN2ENA, 0);
586 pcf50633_reg_write(PCF50633_REG_DOWN2ENA, 0x2);
587 gpio->GPJDAT |= 0x000000001; /* GTA02v1_GPIO_3D_RESET */
590 env_stop_in_menu = getenv("stop_in_menu");
591 /* If the stop_in_menu environment variable is set, enter the
593 if (env_stop_in_menu && strcmp(env_stop_in_menu, "yes") == 0)
596 enter_bootmenu = menu_vote > 0 || booted_from_nor;
598 smedia3362_lcm_reset(1);
599 if (!enter_bootmenu && getenv("splashimage"))
600 run_command(getenv("splashimage"), 0);
602 jbt6k74_enter_state(JBT_STATE_NORMAL);
603 jbt6k74_display_onoff(1);
604 /* switch on the backlight */
605 neo1973_backlight(1);
609 /* check if sd card is inserted, and power-up if it is */
610 S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
611 if (!(gpio->GPFDAT & (1 << 5)))
612 gpio->GPBDAT &= ~(1 << 2);
616 if (enter_bootmenu) {
617 extern struct bootmenu_setup bootmenu_setup;
619 if (booted_from_nand)
620 bootmenu_setup.comment = "NAND";
622 bootmenu_setup.comment = "NOR";
632 gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
633 gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
638 u_int32_t get_board_rev(void)
640 return 0x300+0x10*gta02_revision;
643 void neo1973_poweroff(void)
645 printf("poweroff\n");
647 pcf50633_reg_write(PCF50633_REG_OOCSHDWN, 0x01);
648 /* don't return to caller */
652 void neo1973_backlight(int on)
655 /* pcf50633 manual p60
656 * "led_out should never be set to 000000, as this would result
657 * in a deadlock making it impossible to program another value.
658 * If led_out should be inadvertently set to 000000, the
659 * LEDOUT register can be reset by disabling and enabling the
660 * LED converter via control bit led_on in the LEDENA register"
662 pcf50633_reg_write(PCF50633_REG_LEDENA, 0x00);
663 pcf50633_reg_write(PCF50633_REG_LEDENA, 0x01);
664 pcf50633_reg_write(PCF50633_REG_LEDOUT, 0x3f);
666 pcf50633_reg_write(PCF50633_REG_LEDENA, 0x00);
670 void neo1973_vibrator(int on)
672 S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
674 #if defined(CONFIG_ARCH_GTA01_v3) || defined(CONFIG_ARCH_GTA01_v4)
675 gpio->GPGDAT |= (1 << 11); /* GPG11 */
676 #elif defined(CONFIG_ARCH_GTA01B_v2) || defined(CONFIG_ARCH_GTA01B_v3)
677 gpio->GPBDAT |= (1 << 10); /* GPB10 */
679 gpio->GPBDAT |= (1 << 3); /* GPB3 */
682 #if defined(CONFIG_ARCH_GTA01_v3) || defined(CONFIG_ARCH_GTA01_v4)
683 gpio->GPGDAT &= ~(1 << 11); /* GPG11 */
684 #elif defined(CONFIG_ARCH_GTA01B_v2) || defined(CONFIG_ARCH_GTA01B_v3)
685 gpio->GPBDAT &= ~(1 << 10); /* GPB10 */
687 gpio->GPBDAT &= ~(1 << 3); /* GPB3 */
689 gpio->GPBDAT |= gpb_shadow;
692 void neo1973_gsm(int on)
694 S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
696 /* GPIO2 of PMU, GPB7(MODEM_ON)=1 and GPB5(MODEM_RST)=0 */
698 #if !defined(CONFIG_ARCH_GTA02_v1)
699 pcf50633_reg_write(PCF50633_REG_GPIO2CFG, 0x07);
701 gpio->GPBDAT &= ~(1 << 5); /* GTA02_GPIO_MODEM_RST */
702 gpio->GPBDAT |= (1 << 7); /* GTA02_GPIO_MODEM_ON */
703 gpio->GPJDAT &= ~(1 << 6); /* GTA02_GPIO_nDL_GSM */
705 gpio->GPBDAT &= ~(1 << 7); /* GTA02_GPIO_MODEM_ON */
706 #if !defined(CONFIG_ARCH_GTA02_v1)
707 pcf50633_reg_write(PCF50633_REG_GPIO2CFG, 0x00);
709 gpio->GPJDAT |= (1 << 6); /* GTA02_GPIO_nDL_GSM */
713 void neo1973_gps(int on)
716 pcf50633_reg_write(PCF50633_REG_LDO5ENA, 0x01);
718 pcf50633_reg_write(PCF50633_REG_LDO5ENA, 0x00);
721 static int pwr_int_pending(void)
723 S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
725 return !(gpio->GPGDAT & (1 << 1)); /* EINT9/GPG1 */
728 static int have_int(uint8_t mask1, uint8_t mask2)
730 static uint8_t pending1 = 0, pending2 = 0;
732 if (pwr_int_pending()) {
734 * We retrieve all interupts, so that we clear any stray ones
740 for (i = 0; i != 5; i++)
741 ints[i] = pcf50633_reg_read(PCF50633_REG_INT1+i);
745 if (pending1 & mask1) {
749 if (pending2 & mask2) {
756 int neo1973_new_second(void)
758 return have_int(PCF50633_INT1_SECOND, 0);
761 int neo1973_on_key_pressed(void)
763 static int pressed = -1;
766 have_int(0, PCF50633_INT2_ONKEYF | PCF50633_INT2_ONKEYR))
767 pressed = !(pcf50633_reg_read(PCF50633_REG_OOCSTAT) &
768 PCF50633_OOCSTAT_ONKEY);
772 int neo1973_aux_key_pressed(void)
774 S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
776 return !!(gpio->GPFDAT & (1 << 6));
779 /* The sum of all part_size[]s must equal to or greater than the NAND size,
782 unsigned int dynpart_size[] = {
783 CFG_UBOOT_SIZE, CFG_ENV_SIZE, 0x800000, 0xa0000, 0x40000, 0x10000000, 0 };
784 char *dynpart_names[] = {
785 "u-boot", "u-boot_env", "kernel", "splash", "factory", "rootfs", NULL };
788 const char *neo1973_get_charge_status(void)
791 return pcf50633_charger_state();
794 int neo1973_set_charge_mode(enum neo1973_charger_cmd cmd)
797 puts("not implemented yet\n");
801 void neo1973_led(int led, int on)
803 S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
809 gpb_shadow |= (1 << led);
810 gpio->GPBDAT |= gpb_shadow;
813 gpb_shadow &= ~(1 << led);
814 gpio->GPBDAT = (gpio->GPBDAT | gpb_shadow) & ~(1 << led);
819 * returns PCB revision information in b9,b8 and b2,b1,b0
820 * Pre-GTA02 A6 returns 0x000
821 * GTA02 A6 returns 0x001
824 int gta02_get_pcb_revision(void)
826 S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
830 /* make C13 and C15 pulled-down inputs */
831 gpio->GPCCON &= ~0xcc000000;
832 gpio->GPCUP &= ~((1 << 13) | (1 << 15));
833 /* D0, D3 and D4 pulled-down inputs */
834 gpio->GPDCON &= ~0x000003c3;
835 gpio->GPDUP &= ~((1 << 0) | (1 << 3) | (1 << 4));
837 /* delay after changing pulldowns */
841 /* read the version info */
843 n = (u >> (13 - 0)) & 0x001;
844 n |= (u >> (15 - 1)) & 0x002;
846 n |= (u << (0 + 2)) & 0x004;
848 n |= (u << (8 - 3)) & 0x100;
849 n |= (u << (9 - 4)) & 0x200;
852 * when not being interrogated, all of the revision GPIO
853 * are set to output HIGH without pulldown so no current flows
854 * if they are NC or pulled up.
856 /* make C13 and C15 high ouputs with no pulldowns */
857 gpio->GPCCON |= 0x44000000;
858 gpio->GPCUP |= (1 << 13) | (1 << 15);
859 gpio->GPCDAT |= (1 << 13) | (1 << 15);
860 /* D0, D3 and D4 high ouputs with no pulldowns */
861 gpio->GPDCON |= 0x00000141;
862 gpio->GPDUP |= (1 << 0) | (1 << 3) | (1 << 4);
863 gpio->GPDDAT |= (1 << 0) | (1 << 3) | (1 << 4);