예제 #1
0
/*
 * This serves as both the GPIO IRQ handler and the debounce handler. When
 * called as the debounce handler, IRQs are probably not already disabled when
 * entering this function.
 */
static int ara_key_irqhandler(int irq, void *context)
{
    struct ara_key_context *key = &the_ara_key;
    bool value, active;
    irqstate_t flags;

    flags = irqsave();

    value = !!gpio_get_value(key->db.gpio);
    active = (value == key->rising_edge);

    dbg_insane("ara key press value: %u active: %u\n", value, active);

    if (!debounce_gpio(&key->db, active)) {
	goto out;
    }

    dbg_insane("ara key press value: %u active: %u (stable)\n", value, active);

    /* if something is pending, cancel it so we can pass the correct active */
    if (!work_available(&key->irq_work)) {
	work_cancel(HPWORK, &key->irq_work);
    }
    work_queue(HPWORK, &key->irq_work, ara_key_irqworker,
               (void*)(uintptr_t)active, 0);

out:
    irqrestore(flags);

    return OK;
}
예제 #2
0
파일: vreg.c 프로젝트: nklabs/Nuttx
/**
 * @brief Configure all the GPIOs associated with a voltage regulator
 * to their default states.
 * @param vreg regulator to configure
 */
int vreg_config(struct vreg *vreg) {
    unsigned int i;
    int rc = 0;

    if (!vreg) {
        return -ENODEV;
    }

    dbg_verbose("%s %s\n", __func__,  vreg->name ? vreg->name : "unknown");

    for (i = 0; i < vreg->nr_vregs; i++) {
        if (!&vreg->vregs[i]) {
            rc = -EINVAL;
            break;
        }
        dbg_insane("%s: %s vreg, gpio %d\n", __func__,
                   vreg->name ? vreg->name : "unknown",
                   vreg->vregs[i].gpio);
        // First set default value then switch line to output mode
        gpio_set_value(vreg->vregs[i].gpio, vreg->vregs[i].def_val);
        gpio_direction_out(vreg->vregs[i].gpio, vreg->vregs[i].def_val);
    }

    atomic_init(&vreg->use_count, 0);
    vreg->power_state = false;

    return rc;
}
예제 #3
0
파일: vreg.c 프로젝트: nklabs/Nuttx
/**
 * @brief Manage the regulator state; Turn it on when needed
 * @returns: 0 on success, <0 on error
 */
int vreg_get(struct vreg *vreg) {
    unsigned int i, rc = 0;

    if (!vreg) {
        return -ENODEV;
    }

    dbg_verbose("%s %s\n", __func__, vreg->name ? vreg->name : "unknown");

    /* Enable the regulator on the first use; Update use count */
    if (atomic_inc(&vreg->use_count) == 1) {
        for (i = 0; i < vreg->nr_vregs; i++) {
            if (!&vreg->vregs[i]) {
                rc = -EINVAL;
                break;
            }
            dbg_insane("%s: %s vreg, gpio %d to %d, hold %dus\n", __func__,
                       vreg->name ? vreg->name : "unknown",
                       vreg->vregs[i].gpio, !!vreg->vregs[i].active_high,
                       vreg->vregs[i].hold_time);
            gpio_set_value(vreg->vregs[i].gpio, vreg->vregs[i].active_high);
            up_udelay(vreg->vregs[i].hold_time);
        }
    }

    /* Update state */
    vreg->power_state = true;

    return rc;
}
예제 #4
0
파일: vreg.c 프로젝트: nklabs/Nuttx
/**
 * @brief Manage the regulator state; Turn it off when unused
 * @returns: 0 on success, <0 on error
 */
int vreg_put(struct vreg *vreg) {
    unsigned int i, rc = 0;

    if (!vreg) {
        return -ENODEV;
    }

    dbg_verbose("%s %s\n", __func__, vreg->name ? vreg->name : "unknown");

    /* If already disabled, do nothing */
    if (!atomic_get(&vreg->use_count))
        return rc;

    /* Disable the regulator on the last use; Update use count */
    if (!atomic_dec(&vreg->use_count)) {
        for (i = 0; i < vreg->nr_vregs; i++) {
            if (!&vreg->vregs[i]) {
                rc = -EINVAL;
                break;
            }
            dbg_insane("%s: %s vreg, gpio %08x to %d\n", __func__,
                       vreg->name ? vreg->name : "unknown",
                       vreg->vregs[i].gpio, !vreg->vregs[i].active_high);
            gpio_set_value(vreg->vregs[i].gpio, !vreg->vregs[i].active_high);
        }

        /* Update state */
        vreg->power_state = false;
    }

    return rc;
}