void rtc_set_alarm(int h, int m) { int day = mc13783_read(MC13783_RTC_DAY); int tod = mc13783_read(MC13783_RTC_TIME); if (h*3600 + m*60 < tod) day++; mc13783_write(MC13783_RTC_DAY_ALARM, day); mc13783_write(MC13783_RTC_ALARM, h*3600 + m*60); }
void _backlight_on(void) { static const char regs[2] = { MC13783_LED_CONTROL0, MC13783_LED_CONTROL2 }; uint32_t data[2]; #ifdef HAVE_LCD_ENABLE lcd_enable(true); #endif /* Set/clear LEDRAMPUP bit, clear LEDRAMPDOWN bit, * Ensure LED supply is on. */ data[0] = MC13783_LED_CONTROL0_BITS | MC13783_LEDEN; if (!backlight_on_status) data[0] |= led_ramp_mask & MC13783_LEDMDRAMPUP; backlight_on_status = true; /* Specify final PWM setting */ data[1] = mc13783_read(MC13783_LED_CONTROL2); if (data[1] != MC13783_DATA_ERROR) { data[1] &= ~MC13783_LEDMDDC; data[1] |= backlight_pwm_bits; /* Write regs within 30us of each other (requires single xfer) */ mc13783_write_regs(regs, data, 2); } }
/** Public APIs **/ void rtc_init(void) { /* only needs to be polled on startup */ if (mc13783_read(MC13783_INTERRUPT_STATUS1) & MC13783_TODAI) { alarm_start = true; mc13783_write(MC13783_INTERRUPT_STATUS1, MC13783_TODAI); } }
uint32_t mc13783_clear(unsigned address, uint32_t bits) { uint32_t data; mutex_lock(&mc13783_spi_mutex); data = mc13783_read(address); if (data != MC13783_DATA_ERROR) mc13783_write(address, data & ~bits); mutex_unlock(&mc13783_spi_mutex); return data; }
bool _backlight_init(void) { /* Set default LED register value */ mc13783_write(MC13783_LED_CONTROL0, MC13783_LED_CONTROL0_BITS | MC13783_LEDEN); #ifdef HAVE_BACKLIGHT_BRIGHTNESS /* Our PWM and I-Level is different than retailos (but same apparent * brightness), so init to our default. */ _backlight_set_brightness(DEFAULT_BRIGHTNESS_SETTING); #else /* Use default PWM */ backlight_pwm_bits = mc13783_read(MC13783_LED_CONTROL2) & MC13783_LEDMDDC; #endif return true; }
/* This is called from the mc13783 interrupt thread */ void button_power_event(void) { bool pressed = (mc13783_read(MC13783_INTERRUPT_SENSE1) & MC13783_ONOFD1S) == 0; int oldlevel = disable_irq_save(); if (pressed) { ext_btn |= BUTTON_POWER; } else { ext_btn &= ~BUTTON_POWER; } restore_irq(oldlevel); }
uint32_t mc13783_write_masked(unsigned address, uint32_t data, uint32_t mask) { uint32_t old; mutex_lock(&mc13783_spi_mutex); old = mc13783_read(address); if (old != MC13783_DATA_ERROR) { data = (old & ~mask) | (data & mask); if (mc13783_write(address, data) != 1) old = MC13783_DATA_ERROR; } mutex_unlock(&mc13783_spi_mutex); return old; }
void button_init_device(void) { #ifdef BOOTLOADER /* Can be called more than once in the bootloader */ if (initialized) return; initialized = true; #endif /* Enable keypad clock */ ccm_module_clock_gating(CG_KPP, CGM_ON_RUN_WAIT); /* 1. Enable number of rows in keypad (KPCR[4:0]) * * Configure the rows/cols in KPP * LSB nybble in KPP is for 5 rows * MSB nybble in KPP is for 3 cols */ KPP_KPCR |= 0x1f; /* 2. Write 0's to KPDR[10:8] */ KPP_KPDR &= ~(0x7 << 8); /* 3. Configure the keypad columns as open-drain (KPCR[10:8]). */ KPP_KPCR |= (0x7 << 8); /* 4. Configure columns as output, rows as input (KDDR[10:8,4:0]) */ KPP_KDDR = (KPP_KDDR | (0x7 << 8)) & ~0x1f; /* 5. Clear the KPKD Status Flag and Synchronizer chain. * 6. Set the KDIE control bit bit. */ KPP_KPSR = KPP_KPSR_KRSS | KPP_KPSR_KDSC | KPP_KPSR_KPKD; power_button_update(!(mc13783_read(MC13783_INTERRUPT_SENSE1) & MC13783_ONOFD1S)); mc13783_enable_event(MC13783_ONOFD1_EVENT, true); #ifdef HAVE_HEADPHONE_DETECTION headphone_init(); #endif }
/* Read the immediate state of the cable from the PMIC */ bool usb_plugged(void) { return mc13783_read(MC13783_INTERRUPT_SENSE0) & MC13783_USB4V4S; }
void rtc_get_alarm(int *h, int *m) { int tod = mc13783_read(MC13783_RTC_ALARM); *h = tod / 3600; *m = tod % 3600 / 60; }