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); } }
static void mc13783_interrupt_thread(void) { uint32_t pending[2]; /* Enable mc13783 GPIO event */ gpio_enable_event(MC13783_EVENT_ID); while (1) { const struct mc13783_event *event, *event_last; wakeup_wait(&mc13783_svc_wake, TIMEOUT_BLOCK); if (mc13783_thread_id == 0) break; mc13783_read_regs(pmic_ints_regs, pending, 2); /* Only clear interrupts being dispatched */ pending[0] &= pmic_int_enabled[0]; pending[1] &= pmic_int_enabled[1]; mc13783_write_regs(pmic_ints_regs, pending, 2); /* Whatever is going to be serviced in this loop has been * acknowledged. Reenable interrupt and if anything was still * pending or became pending again, another signal will be * generated. */ imx31_regset32(&MC13783_GPIO_IMR, 1ul << MC13783_GPIO_LINE); event = mc13783_events; event_last = event + MC13783_NUM_EVENTS; /* .count is surely expected to be > 0 */ do { enum mc13783_event_sets set = event->set; uint32_t pnd = pending[set]; uint32_t mask = event->mask; if (pnd & mask) { event->callback(); pnd &= ~mask; pending[set] = pnd; } if ((pending[0] | pending[1]) == 0) break; /* Terminate early if nothing more to service */ } while (++event < event_last); } gpio_disable_event(MC13783_EVENT_ID); }
int rtc_write_datetime(const struct tm *tm) { uint32_t regs[2]; int year, leap, month, day, i, base_yearday; regs[RTC_REG_TIME] = tm->tm_sec + tm->tm_min*60 + tm->tm_hour*3600; year = tm->tm_year - 100; if (year < RTC_BASE_YEAR - 1900) year += 2000; else year += 1900; /* Get number of leaps for day before base */ leap = get_leap_count(RTC_BASE_DAY_COUNT - 1); /* Get day number for base year 0-364|365 */ base_yearday = RTC_BASE_DAY_COUNT - leap - (RTC_BASE_YEAR - 1601) * 365; /* Get the number of days elapsed from reference */ for (i = RTC_BASE_YEAR, day = 0; i < year; i++) { day += is_leap_year(i) ? 366 : 365; } /* Find the number of days passed this year up to the 1st of the * month. */ leap = is_leap_year(year); month = tm->tm_mon; for (i = 0; i < month; i++) { day += month_table[leap][i]; } regs[RTC_REG_DAY] = day + tm->tm_mday - 1 - base_yearday; if (mc13783_write_regs(rtc_registers, regs, 2) == 2) { return 7; } return 0; }