void rk808_configure_ldo(int ldo, int millivolts) { uint8_t vsel; if (!millivolts) { rk808_clrsetbits(LDO_EN, 1 << (ldo - 1), 0); return; } switch (ldo) { case 1: case 2: case 4: case 5: case 8: vsel = div_round_up(millivolts, 100) - 18; assert(vsel <= 0x10); break; case 3: case 6: case 7: vsel = div_round_up(millivolts, 100) - 8; assert(vsel <= 0x11); break; default: die("Unknown LDO index!"); } rk808_clrsetbits(LDO_ONSEL(ldo), 0x1f, vsel); rk808_clrsetbits(LDO_EN, 0, 1 << (ldo - 1)); }
int rtc_get(struct rtc_time *time) { uint8_t value; int ret = 0; /* * Set RTC_READSEL to cause reads to access shadow registers and * transition GET_TIME from 0 to 1 to cause dynamic register content * to be copied into shadow registers. This ensures a coherent reading * of time values as we access each register using slow I2C transfers. */ rk808_clrsetbits(RTC_CTRL, RTC_CTRL_GET_TIME, 0); rk808_clrsetbits(RTC_CTRL, 0, RTC_CTRL_GET_TIME | RTC_CTRL_RTC_READSEL); ret |= rk808_read(RTC_SECOND, &value); time->sec = bcd2bin(value & 0x7f); ret |= rk808_read(RTC_MINUTE, &value); time->min = bcd2bin(value & 0x7f); ret |= rk808_read(RTC_HOUR, &value); time->hour = bcd2bin(value & 0x3f); ret |= rk808_read(RTC_DAY, &value); time->mday = bcd2bin(value & 0x3f); ret |= rk808_read(RTC_MONTH, &value); time->mon = bcd2bin(value & 0x1f); ret |= rk808_read(RTC_YEAR, &value); time->year = bcd2bin(value); return ret; }
void rk808_configure_buck(int buck, int millivolts) { uint8_t vsel; uint8_t buck_reg; switch (buck) { case 1: case 2: /* 25mV steps. base = 29 * 25mV = 725 */ vsel = (div_round_up(millivolts, 25) - 29) * 2 + 1; assert(vsel <= 0x3f); buck_reg = BUCK1SEL + 4 * (buck - 1); break; case 4: vsel = div_round_up(millivolts, 100) - 18; assert(vsel <= 0xf); buck_reg = BUCK4SEL; break; default: die("Unknown buck index!"); } rk808_clrsetbits(DCDC_ILMAX, 0, 3 << ((buck - 1) * 2)); /* undervoltage detection may be wrong, disable it */ rk808_clrsetbits(DCDC_UV_ACT, 1 << (buck - 1), 0); rk808_clrsetbits(buck_reg, 0x3f, vsel); rk808_clrsetbits(DCDC_EN, 0, 1 << (buck - 1)); }
int rtc_get(struct rtc_time *time) { uint8_t value; int ret = 0; /* * Set RTC_READSEL to cause reads to access shadow registers and * transition GET_TIME from 0 to 1 to cause dynamic register content * to be copied into shadow registers. This ensures a coherent reading * of time values as we access each register using slow I2C transfers. */ rk808_clrsetbits(RTC_CTRL, RTC_CTRL_GET_TIME, 0); rk808_clrsetbits(RTC_CTRL, 0, RTC_CTRL_GET_TIME | RTC_CTRL_RTC_READSEL); /* * After we set the GET_TIME bit, the rtc time can't be read * immediately. So we should wait up to 31.25 us. */ udelay(32); ret |= rk808_read(RTC_SECOND, &value); time->sec = bcd2bin(value & 0x7f); ret |= rk808_read(RTC_MINUTE, &value); time->min = bcd2bin(value & 0x7f); ret |= rk808_read(RTC_HOUR, &value); time->hour = bcd2bin(value & 0x3f); ret |= rk808_read(RTC_DAY, &value); time->mday = bcd2bin(value & 0x3f); ret |= rk808_read(RTC_MONTH, &value); time->mon = bcd2bin(value & 0x1f); ret |= rk808_read(RTC_YEAR, &value); time->year = bcd2bin(value); time->wday = -1; /* unknown */ return ret; }
void rk808_configure_buck(uint8_t bus, int buck, int millivolts) { uint8_t vsel; uint8_t buck_reg; switch (buck) { case 1: case 2: /*base on 725mv, use 25mv step */ vsel = (div_round_up(millivolts, 25) - 29) * 2 + 1; assert(vsel <= 0x3f); buck_reg = BUCK1SEL + 4 * (buck - 1); break; case 4: vsel = div_round_up(millivolts, 100) - 18; assert(vsel <= 0xf); buck_reg = BUCK4SEL; break; default: die("fault buck index!"); } rk808_clrsetbits(bus, buck_reg, 0x3f, vsel); rk808_clrsetbits(bus, DCDC_EN, 0, 1 << (buck - 1)); }
void rk808_configure_switch(int sw, int enabled) { assert(sw == 1 || sw == 2); rk808_clrsetbits(DCDC_EN, 1 << (sw + 4), !!enabled << (sw + 4)); }
static void rk808rtc_start(void) { rk808_clrsetbits(RTC_CTRL, 0, RTC_CTRL_STOP_RTC); }
static void rk808rtc_stop(void) { rk808_clrsetbits(RTC_CTRL, RTC_CTRL_STOP_RTC, 0); }