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);
    }
}
Beispiel #2
0
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);
}
Beispiel #3
0
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;
}