📄 uboot-gta02.patch
字号:
+enum pcf50633_reg_mbcs3 {+ PCF50633_MBCS3_USBLIM_PLAY = 0x01,+ PCF50633_MBCS3_USBLIM_CGH = 0x02,+ PCF50633_MBCS3_TLIM_PLAY = 0x04,+ PCF50633_MBCS3_TLIM_CHG = 0x08,+ PCF50633_MBCS3_ILIM = 0x10, /* 1: Ibat > Icutoff */+ PCF50633_MBCS3_VLIM = 0x20, /* 1: Vbat == Vmax */+ PCF50633_MBCS3_VBATSTAT = 0x40, /* 1: Vbat > Vbatcond */+ PCF50633_MBCS3_VRES = 0x80, /* 1: Vbat > Vth(RES) */+};+++/* this is to be provided by the board implementation */+extern const u_int8_t pcf50633_initial_regs[__NUM_PCF50633_REGS];++void pcf50633_reg_write(u_int8_t reg, u_int8_t val);++u_int8_t pcf50633_reg_read(u_int8_t reg);++void pcf50633_reg_set_bit_mask(u_int8_t reg, u_int8_t mask, u_int8_t val);+void pcf50633_reg_clear_bits(u_int8_t reg, u_int8_t bits);++void pcf50633_init(void);+void pcf50633_usb_maxcurrent(unsigned int ma);++const char *pcf50633_charger_state(void);++#endif /* _PCF50633_H */+Index: u-boot/drivers/misc/pcf50633.c===================================================================--- /dev/null+++ u-boot/drivers/misc/pcf50633.c@@ -0,0 +1,278 @@+#include <common.h>++#ifdef CONFIG_DRIVER_PCF50633++#include <i2c.h>+#include <pcf50633.h>+#include <asm/atomic.h>+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))+++#define ADC_NOMINAL_RES_1A 6+#define ADC_NOMINAL_RES_NC_R_USB 43++#define PCF50633_I2C_ADDR 0x73++void __pcf50633_reg_write(u_int8_t reg, u_int8_t val)+{+ i2c_write(PCF50633_I2C_ADDR, reg, 1, &val, 1);+}++u_int8_t __pcf50633_reg_read(u_int8_t reg)+{+ u_int8_t tmp;+ i2c_read(PCF50633_I2C_ADDR, reg, 1, &tmp, 1);+ return tmp;+}++void pcf50633_reg_write(u_int8_t reg, u_int8_t val)+{+ unsigned long flags;++ local_irq_save(flags);+ __pcf50633_reg_write(reg, val);+ local_irq_restore(flags);+}++u_int8_t pcf50633_reg_read(u_int8_t reg)+{+ unsigned long flags;+ u_int8_t tmp;++ local_irq_save(flags);+ tmp = __pcf50633_reg_read(reg);+ local_irq_restore(flags);++ return tmp;+}++void pcf50633_reg_set_bit_mask(u_int8_t reg, u_int8_t mask, u_int8_t val)+{+ unsigned long flags;+ u_int8_t tmp;++ local_irq_save(flags);+ tmp = __pcf50633_reg_read(reg);+ __pcf50633_reg_write(reg, (val & mask) | (tmp & ~mask));+ local_irq_restore(flags);+}++void pcf50633_reg_clear_bits(u_int8_t reg, u_int8_t bits)+{+ unsigned long flags;+ u_int8_t tmp;++ local_irq_save(flags);+ tmp = pcf50633_reg_read(reg);+ pcf50633_reg_write(reg, (tmp & ~bits));+ local_irq_restore(flags);+}++static const u_int8_t regs_invalid[] = {+ PCF50633_REG_VERSION,+ PCF50633_REG_VARIANT,+ PCF50633_REG_OOCSHDWN,+ PCF50633_REG_INT1,+ PCF50633_REG_INT2,+ PCF50633_REG_INT3,+ PCF50633_REG_INT4,+ PCF50633_REG_INT5,+ PCF50633_REG_OOCSTAT,+ 0x2c,+ PCF50633_REG_DCDCSTAT,+ PCF50633_REG_LDOSTAT,+ PCF50633_REG_MBCS1,+ PCF50633_REG_MBCS2,+ PCF50633_REG_MBCS3,+ PCF50633_REG_ALMDATA,+ 0x51,+ /* 0x55 ... 0x6e: don't write */+ /* 0x6f ... 0x83: reserved */+};+#define PCF50633_LAST_REG 0x55++static int reg_is_invalid(u_int8_t reg)+{+ int i;++ /* all registers above 0x55 (ADCS1) except 0x84 */+ if (reg == PCF50633_REG_DCDCPFM)+ return 0;+ if (reg >= 0x55)+ return 1;++ for (i = 0; i < ARRAY_SIZE(regs_invalid); i++) {+ if (regs_invalid[i] > reg)+ return 0;+ if (regs_invalid[i] == reg)+ return 1;+ }++ return 0;+}++/* figure out our charger situation */+int pcf50633_read_charger_type(void)+{+ u_int16_t ret;++ /* kill ratiometric, but enable ACCSW biasing */+ pcf50633_reg_write(PCF50633_REG_ADCC2, 0x00);+ pcf50633_reg_write(PCF50633_REG_ADCC3, 0x01);++ /* start ADC conversion of selected channel */+ pcf50633_reg_write(PCF50633_REG_ADCC1, PCF50633_ADCC1_MUX_ADCIN1 |+ PCF50633_ADCC1_AVERAGE_16 |+ PCF50633_ADCC1_ADCSTART |+ PCF50633_ADCC1_RES_10BIT);++ /* spin until completed */+ while (!(pcf50633_reg_read(PCF50633_REG_ADCS3) & 0x80))+ ;++ /* grab the result */+ ret = (pcf50633_reg_read(PCF50633_REG_ADCS1) << 2) |+ (pcf50633_reg_read(PCF50633_REG_ADCS3) &+ PCF50633_ADCS3_ADCDAT1L_MASK);++ /* well it is nearest to the 1A resistor */+ if (ret < ((ADC_NOMINAL_RES_1A + ADC_NOMINAL_RES_NC_R_USB) / 2))+ return 1000;++ /* ok all we know is there is no resistor, it can be USB pwr or none */+ if ((pcf50633_reg_read(PCF50633_REG_MBCS1) & 0x3) == 0x3)+ return 500; /* USB power then */++ return 0; /* nope, no power, just battery */+}++++/* initialize PCF50633 register set */+void pcf50633_init(void)+{+ unsigned long flags;+ u_int8_t i, limit;++ local_irq_save(flags);+ for (i = 0; i < PCF50633_LAST_REG; i++) {+ if (reg_is_invalid(i))+ continue;+ __pcf50633_reg_write(i, pcf50633_initial_regs[i]);+ }+ local_irq_restore(flags);++ printf("Power: ");+ switch (pcf50633_read_charger_type()) {+ case 0: /* no charger, battery only */+ printf("Battery\n");+ limit = PCF50633_MBCC7_USB_SUSPEND;+ break;+ case 500:+ printf("USB / 500mA\n");+ limit = PCF50633_MBCC7_USB_500mA;+ break;+ default:+ printf("1A\n");+ limit = PCF50633_MBCC7_USB_1000mA;+ break;+ }+ pcf50633_reg_write(PCF50633_REG_MBCC7,+ (pcf50633_reg_read(PCF50633_REG_MBCC7) &+ (~PCF56033_MBCC7_USB_MASK)) | limit);+}++void pcf50633_usb_maxcurrent(unsigned int ma)+{+ u_int8_t val;++ if (ma < 100)+ val = 0x03;+ else if (ma < 500)+ val = 0x00;+ else if (ma < 1000)+ val = 0x01;+ else+ val = 0x02;++ return pcf50633_reg_set_bit_mask(PCF50633_REG_MBCC7, 0x03, val);+}+++static const char *charger_states[] = {+ [0] = "play_only",+ [1] = "usb_precharge",+ [2] = "usb_precharge_wait",+ [3] = "usb_fast_charge",+ [4] = "usb_fast_charge_wait",+ [5] = "usb_suspend",+ [6] = "adapter_precharge",+ [7] = "adapter_precharge_wait",+ [8] = "adapter_fast_charge",+ [9] = "adapter_fast_charge_wait",+ [10] = "battery_full",+ [11] = "halt",+};++const char *pcf50633_charger_state(void)+{+ u_int8_t val = pcf50633_reg_read(PCF50633_REG_MBCS2);++ val &= 0x0f;+ if (val > 11)+ return "error";++ return charger_states[val];+}++#if defined(CONFIG_RTC_PCF50633) && defined(CONFIG_CMD_DATE)++#include <rtc.h>++static unsigned bcd2bin (uchar n)+{+ return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));+}++static unsigned char bin2bcd (unsigned int n)+{+ return (((n / 10) << 4) | (n % 10));+}+++void rtc_get(struct rtc_time *tmp)+{+ tmp->tm_sec = bcd2bin(pcf50633_reg_read(PCF50633_REG_RTCSC));+ tmp->tm_min = bcd2bin(pcf50633_reg_read(PCF50633_REG_RTCMN));+ tmp->tm_hour = bcd2bin(pcf50633_reg_read(PCF50633_REG_RTCHR));+ tmp->tm_wday = bcd2bin(pcf50633_reg_read(PCF50633_REG_RTCWD));+ tmp->tm_mday = bcd2bin(pcf50633_reg_read(PCF50633_REG_RTCDT));+ tmp->tm_mon = bcd2bin(pcf50633_reg_read(PCF50633_REG_RTCMT));+ tmp->tm_year = bcd2bin(pcf50633_reg_read(PCF50633_REG_RTCYR));+ if (tmp->tm_year < 70)+ tmp->tm_year += 2000;+ else+ tmp->tm_year += 1900;+ tmp->tm_yday = 0;+ tmp->tm_isdst = 0;+}++void rtc_set(struct rtc_time *tmp)+{+ pcf50633_reg_write(PCF50633_REG_RTCSC, bin2bcd(tmp->tm_sec));+ pcf50633_reg_write(PCF50633_REG_RTCMN, bin2bcd(tmp->tm_min));+ pcf50633_reg_write(PCF50633_REG_RTCHR, bin2bcd(tmp->tm_hour));+ pcf50633_reg_write(PCF50633_REG_RTCWD, bin2bcd(tmp->tm_wday));+ pcf50633_reg_write(PCF50633_REG_RTCDT, bin2bcd(tmp->tm_mday));+ pcf50633_reg_write(PCF50633_REG_RTCMN, bin2bcd(tmp->tm_mon));+ pcf50633_reg_write(PCF50633_REG_RTCYR, bin2bcd(tmp->tm_year % 100));+}++void rtc_reset(void)+{+ /* FIXME */+}+#endif /* CONFIG_RTC_PCF50633 && CONFIG_CMD_DATE */+++#endif /* CONFIG DRIVER_PCF50633 */Index: u-boot/board/neo1973/common/lowlevel_init.S===================================================================--- u-boot.orig/board/neo1973/common/lowlevel_init.S+++ u-boot/board/neo1973/common/lowlevel_init.S@@ -49,7 +49,7 @@ #define WAIT (0x1<<2) #define UBLB (0x1<<3) -#define B1_BWSCON (DW32)+#define B1_BWSCON (DW16 + WAIT + UBLB) #define B2_BWSCON (DW16) #define B3_BWSCON (DW16 + WAIT + UBLB) #define B4_BWSCON (DW16)@@ -66,11 +66,11 @@ #define B0_Tacp 0x0 #define B0_PMC 0x0 /* normal */ -/* BANK1CON */+/* BANK1CON: Smedia Glamo 3362 (on GTA02) */ #define B1_Tacs 0x0 /* 0clk */-#define B1_Tcos 0x0 /* 0clk */-#define B1_Tacc 0x7 /* 14clk */-#define B1_Tcoh 0x0 /* 0clk */+#define B1_Tcos 0x3 /* 4clk */+#define B1_Tacc 0x3 /* 4clk */+#define B1_Tcoh 0x3 /* 4clk */ #define B1_Tah 0x0 /* 0clk */ #define B1_Tacp 0x0 #define B1_PMC 0x0@@ -109,16 +109,18 @@ #define B6_MT 0x3 /* SDRAM */ #define B6_Trcd 0x1 /* 3clk */-#if defined (CONFIG_ARCH_GTA01_v3) || defined(CONFIG_ARCH_GTA01_v4)+#if defined (CONFIG_ARCH_GTA01_v3) || defined(CONFIG_ARCH_GTA01_v4) || \+ CONFIG_GTA02_REVISION >= 2 #define B6_SCAN 0x1 /* 9bit */+#define B7_SCAN 0x1 /* 9bit */ #elif defined(CONFIG_ARCH_GTA01B_v2) || defined(CONFIG_ARCH_GTA01B_v3) || \- defined(CONFIG_ARCH_GTA01B_v4)+ defined(CONFIG_ARCH_GTA01B_v4) || defined(CONFIG_ARCH_GTA02_v1) #define B6_SCAN 0x2 /* 10bit */+#define B7_SCAN 0x2 /* 10bit */ #endif #define B7_MT 0x3 /* SDRAM */ #define B7_Trcd 0x1 /* 3clk */-#define B7_SCAN 0x2 /* 10bit */ /* REFRESH parameter */ #define REFEN 0x1 /* Refresh enable */@@ -165,6 +167,27 @@ str r1, [r0] #endif +#if defined(CONFIG_ARCH_GTA02_v1)+ /* enable KEEPACT(GPJ3) to make sure PMU keeps us alive */+ ldr r0, =0x56000000 /* GPJ base */+ ldr r1, [r0, #0xd0] /* GPJCON */+ orr r1, r1, #(1 << 6)+ str r1, [r0, #0xd0]++ ldr r1, [r0, #0xd4] /* GPJDAT */+ orr r1, r1, #(1 << 3)+ str r1, [r0, #0xd4]+#elif CONFIG_GTA02_REVISION >= 2+ /* enable KEEPACT(GPJ8) to make sure PMU keeps us alive */+ ldr r0, =0x56000000 /* GPJ base */+ ldr r1, [r0, #0xd0] /* GPJCON */+ orr r1, r1, #(1 << 16)+ str r1, [r0, #0xd0]++ ldr r1, [r0, #0xd4] /* GPJDAT */+ orr r1, r1, #(1 << 8)+ str r1, [r0, #0xd4]+#endif /* everything is fine now */ mov pc, lr @@ -182,6 +205,10 @@ .word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN)) .word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN)) .word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)+#if CONFIG_GTA02_REVISION >= 2+ .word 0xb1+#else .word 0xb2+#endif .word 0x30 .word 0x30Index: u-boot/board/neo1973/gta02/pcf50633.c===================================================================--- /dev/null+++ u-boot/board/neo1973/gta02/pcf50633.c@@ -0,0 +1,116 @@++#include <common.h>+#include <pcf50633.h>++/* initial register set for PCF50633 in Neo1973 GTA02 devices */+const u_int8_t pcf50633_initial_regs[__NUM_PCF50633_REGS] = {+ /* gap */+ [PCF50633_REG_INT1M] = PCF50633_INT1_SECOND,+ [PCF50633_REG_INT2M] = PCF50633_INT2_EXTON3F |+ PCF50633_INT2_EXTON3R |+ PCF50633_INT2_EXTON2F |+ PCF50633_INT2_EXTON2R |+ PCF50633_INT2_EXTON1R |+ PCF50633_INT2_EXTON1F,+ [PCF50633_REG_INT3M] = PCF50633_INT3_ADCRDY,+ [PCF50633_REG_INT4M] = 0x00,+ [PCF50633_REG_INT5M] = 0x00,++ [PCF50633_REG_OOCWAKE] = 0xd3, /* wake from ONKEY,EXTON!,RTC,USB,ADP */+ [PCF50633_REG_OOCTIM1] = 0xaa, /* debounce 14ms everything */+ [PCF50633_REG_OOCTIM2] = 0x4a,+ [PCF50633_REG_OOCMODE] = 0x55,+ [PCF50633_REG_OOCCTL] = 0x44,++ [PCF50633_REG_GPIOCTL] = 0x01, /* only GPIO1 is input */+ [PCF50633_REG_GPIO2CFG] = 0x00,+ [PCF50633_REG_GPIO3CFG] = 0x00,+ [PCF50633_REG_GPOCFG] = 0x00,++ [PCF50633_REG_SVMCTL] = 0x08, /* 3.10V SYS voltage thresh. */+ [PCF50633_REG_BVMCTL] = 0x02, /* 2.80V BAT voltage thresh. */++ [PCF50633_REG_STBYCTL1] = 0x00,+ [PCF50633_REG_STBYCTL2] = 0x00,++ [PCF50633_REG_DEBPF1] = 0xff,+ [PCF50633_REG_DEBPF2] = 0xff,+ [PCF50633_REG_DEBPF2] = 0x3f,++ [PCF50633_REG_AUTOOUT] = 0x6b, /* 3.300V */+ [PCF50633_REG_AUTOENA] = 0x01, /* always on */+ [PCF50633_REG_AUTOCTL] = 0x00, /* automatic up/down operation */+ [PCF50633_REG_AUTOMXC] = 0x0a, /* 400mA at startup FIXME */++ [PCF50633_REG_DOWN1OUT] = 0x1b, /* 1.3V (0x1b * .025V + 0.625V) */+ [PCF50633_REG_DOWN1ENA] = 0x02, /* enabled if GPIO1 = HIGH */+ [PCF50633_REG_DOWN1CTL] = 0x00, /* no DVM */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -