Example #1
0
/**
 * @brief           Initialize dedicated HW (GPIO, ADC) and configure averaging
 *                  to enable current measurement of a given spring.
 * @warning         Shall be called prior to any other spwrm_* call.
 * warning          'spring' index starts at 1, not 0.
 * @return          0 on success, standard error codes otherwise.
 * @param[in]       spring: selected spring ([1..SPRING_COUNT])
 * @param[in]       count: averaging sample count
 *                  ([1..ADC_MAX_AVG_SAMPLE_COUNT])
 */
int spwrm_init(uint8_t spring, uint8_t count)
{
    uint8_t adc, chan;
    uint32_t spin;
    int ret;

    CHECK_SPRING(spring);
    CHECK_ARG_AVG_COUNT(count);

    adc = spwrm_get_adc_device(spring);
    chan = spwrm_get_adc_channel(spring);
    spin = spwrm_get_sign_pin(spring);

    dbg_verbose("%s(): Configuring %s... (adc=%u, spin=0x%08X)\n",
                __func__, spwrm_get_name(spring), adc, spin);

    /* Configure SIGN pin as input */
    stm32_configgpio(spin);

    ret = adc_init(adc, chan, count);
    if (ret) {
        dbg_error("%s(): %s initialization failed!!! (%d).\n", __func__,
                    spwrm_get_name(spring), ret);
    } else {
        dbg_verbose("%s(): %s initialization done.\n", __func__,
                    spwrm_get_name(spring));
    }

    return ret;
}
Example #2
0
/**
 * @brief           Return sampled data of a given power rail.
 * @return          0 on success, standard error codes otherwise.
 * @param[in]       bdbpm_r: power rail device structure
 * @param[out]      m: power measurement data (voltage, current, power)
 */
int bdbpm_measure_rail(bdbpm_rail *bdbpm_r, pwr_measure *m)
{
    int ret;

    if ((!bdbpm_r) || (!m)) {
        dbg_error("%s(): NULL pointer!\n", __func__);
        return -EINVAL;
    }
    dbg_verbose("%s(): measuring %s rail...\n", __func__, bdbpm_r->rail_name);

    /* Configure I2C Mux */
    ret = bdbpm_ina230_select(bdbpm_r->dev);
    if (ret) {
        dbg_error("%s(): failed to configure i2c mux! (%d)\n",
                  __func__, ret);
        return ret;
    }
    /* Get measurement data */
    ret = ina230_get_data(bdbpm_r->ina230_dev, m);
    if (ret) {
        dbg_error("%s(): failed to retrieve measurement data! (%d)\n",
                  __func__, ret);
    } else {
        dbg_verbose("%s(): %s measurement: %duV %duA %duW\n", __func__,
                    bdbpm_r->rail_name, m->uV, m->uA, m->uW);
    }

    return ret;
}
Example #3
0
/**
 * @brief           Measure the current consumption of a given spring.
 * @return          current consumption of a given spring (in microamps)
 * warning          'spring' index starts at 1, not 0.
 * @param[in]       spring: selected spring ([1..SPRING_COUNT])
 * @param[out]      uA: selected spring current measurement, in microamps)
 */
int spwrm_get_current(uint8_t spring, int32_t *uA)
{
    int ret;
    uint8_t adc, chan;
    uint32_t spin, uV;

    CHECK_SPRING(spring);
    CHECK_NULL_ARG(uA);

    adc = spwrm_get_adc_device(spring);
    chan = spwrm_get_adc_channel(spring);
    spin = spwrm_get_sign_pin(spring);
    *uA = 0;

    ret = adc_get_data(adc, chan, &uV);
    if (ret) {
        dbg_error("%s(): failed to get %s data! (%d)\n", __func__,
                  spwrm_get_name(spring), ret);
        return ret;
    }
    /* Convert to uV */
    uV = adc_get_uV(uV);
    /* Get data sign */
    if (stm32_gpioread(spin) == 0) {
        dbg_verbose("%s(): pin=0 => sign=-\n", __func__);
        *uA = -((int32_t) max9929f_get_Iload(uV));
    } else {
        dbg_verbose("%s(): pin=1 => sign=+\n", __func__);
        *uA = (int32_t) max9929f_get_Iload(uV);
    }
    dbg_verbose("%s(): measured voltage=%uuV => current=%duA\n",
                __func__, uV, *uA);

    return 0;
}
Example #4
0
/**
 * @brief           Deinitialize dedicated current measurement HW
 *                  (GPIO, ADC) of a given spring.
 * warning          'spring' index starts at 1, not 0.
 * @return          0 on success, standard error otherwise.
 * @param[in]       spring: selected spring ([1..SPRING_COUNT])
 */
int spwrm_deinit(uint8_t spring)
{
    int ret;
    uint8_t adc, chan;
    uint32_t spin;

    CHECK_SPRING(spring);

    dbg_verbose("%s(): De-initializing %s...\n", __func__,
                spwrm_get_name(spring));

    adc = spwrm_get_adc_device(spring);
    chan = spwrm_get_adc_channel(spring);
    spin = spwrm_get_sign_pin(spring);

    /* Unconfigure GPIO ADC channel pin */
    stm32_unconfiggpio(spin);
    /* Shutdown ADC */
    ret = adc_deinit(adc, chan);
    if (ret) {
        dbg_error("%s(): %s de-initialization failed!!! (%d)\n", __func__,
                  spwrm_get_name(spring), ret);
    } else {
        dbg_verbose("%s(): %s de-initialization done.\n", __func__,
                    spwrm_get_name(spring));
    }
    return ret;
}
Example #5
0
static bool
rexec_remote( char *host, int port, char *c )
{
    int     ret, sockfd;
    char    *cmd=NULL;

    cmd = (char*)malloc( strlen(c) + 10);
    sockfd = sock_connectTo( host, port );
    if(sockfd==-1)
        return false;
    sprintf( cmd, "EXECUTE %s", c );
    dbg_verbose( "%s\n", cmd );
    sock_sendLine( sockfd, cmd );
    ret = sock_getStatus( sockfd );
    if( ret < 0 )
    {   dbg_error( "rexec: No remote confirmation!\n");
        free(cmd);
        return false;
    }

    if( ret > 0 )
    {   dbg_error("rexec: Error: '%s'\n", strerror( ret ) );
        dbg_error("rexec: Can't execute [%s].\n", c );
        free(cmd);
        shutdown( sockfd, 2);
        close( sockfd );
        return false;
    }
    free(cmd);
    shutdown( sockfd, 2);
    close( sockfd );
    return true;
}
Example #6
0
/**
 * @brief           Collect power measurements of all user-selected rails.
 * @return          0 on success, standard error codes otherwise
 */
static int bdbpm_main_collect_measurements(void)
{
    int ret = 0;
    uint8_t d_start, d_end;
    uint8_t r_start, r_end;
    uint8_t d, r;

    bdbpm_main_get_device_list(&d_start, &d_end);
    for (d = d_start; d < d_end; d++) {
        bdbpm_main_get_rail_list(d, &r_start, &r_end);
        for (r = r_start; r < r_end; r++) {
            ret = bdbpm_measure_rail(bdbpm_rails[d][r], &measurements[d][r]);
            if (ret) {
                fprintf(stderr, "failed to collect %s measurements!!! (%d)\n",
                    bdbpm_rail_name(d, r), ret);
                return ret;
            } else {
                dbg_verbose("%s(): %s: %uuV %uuA %uuW\n", __func__,
                    bdbpm_rail_name(d, r),
                    measurements[d][r].uV, measurements[d][r].uA,
                    measurements[d][r].uW);
            }
        }
    }

    return 0;
}
Example #7
0
/* Control RGB LED */
void debug_rgb_led(uint8_t r, uint8_t g, uint8_t b)
{
    dbg_verbose("%s(): rgb=%d%d%d\n", __func__, r, g, b);
    stm32_gpiowrite(GPIO_R_LED_EN, !r);
    stm32_gpiowrite(GPIO_G_LED_EN, !g);
    stm32_gpiowrite(GPIO_B_LED_EN, !b);
}
Example #8
0
/**
 * @brief Take ownership of WDx pins prior to issuing timesync strobe signals
 *        ensuring a known initial state on WDM lines before APB/GPB get
 *        transitioned to monitor incoming timesync strobe signals
 */
int timesync_wd_pins_init(uint32_t interface_strobe_mask) {
    struct interface *intf_apb1, *intf_apb2;

    if (timesync_state == TIMESYNC_STATE_SYNCING ||
        timesync_state == TIMESYNC_STATE_INVALID) {
        return -EBUSY;
    }

    intf_apb1 = interface_get_by_name(INTF_APB1);
    intf_apb2 = interface_get_by_name(INTF_APB2);

    if (intf_apb1) {
        interface_strobe_mask |= 1 << intf_apb1->dev_id;
    } else {
        lldbg("Couldn't find APB1 interface!\n");
    }
    if (intf_apb2) {
        interface_strobe_mask |= 1 << intf_apb2->dev_id;
    } else {
        lldbg("Couldn't find APB2 interface!\n");
    }

    timesync_pin_strobe_mask = interfaces_timesync_init(interface_strobe_mask);
    dbg_verbose("interface-mask 0x%08lx strobe-mask 0x%08lx\n",
                interface_strobe_mask, timesync_pin_strobe_mask);
    return 0;
}
Example #9
0
/**
 * @brief           Return the device ID given a device name.
 * @return          device ID (>= 0) on success, standard error codes otherwise.
 *                  -ENODEV if not found
 * @param[in]       name: power rail name
 * @param[out]      dev: device ID
 */
int bdbpm_device_id(const char *name, uint8_t *dev)
{
    int ret = 0;

    if ((!name) || (!dev)) {
        ret = -ENODEV;
    } else {
        *dev = DEV_COUNT;
    }

    if (strcmp(name, "SW") == 0) {
        *dev = DEV_SW;
    } else if (strcmp(name, "APB1") == 0) {
        *dev = DEV_APB1;
    } else if (strcmp(name, "APB2") == 0) {
        *dev = DEV_APB2;
    } else if (strcmp(name, "APB3") == 0) {
        *dev = DEV_APB3;
    } else if (strcmp(name, "GPB1") == 0) {
        *dev = DEV_GPB1;
    } else if (strcmp(name, "GPB2") == 0) {
        *dev = DEV_GPB2;
#ifdef CONFIG_ARCH_BOARD_ARA_SDB_SVC
    } else if (strcmp(name, "SVC") == 0) {
        *dev = DEV_SVC;
#endif
    } else {
        *dev = DEV_COUNT;
        ret = -ENODEV;
    }

    dbg_verbose("%s(): name=%s => device=%u\n", __func__, name, *dev);

    return ret;
}
Example #10
0
/* Main request processing thread */
static int r592_process_thread(void *data)
{
    int error;
    struct r592_device *dev = (struct r592_device *)data;
    unsigned long flags;

    while (!kthread_should_stop()) {
        spin_lock_irqsave(&dev->io_thread_lock, flags);
        set_current_state(TASK_INTERRUPTIBLE);
        error = memstick_next_req(dev->host, &dev->req);
        spin_unlock_irqrestore(&dev->io_thread_lock, flags);

        if (error) {
            if (error == -ENXIO || error == -EAGAIN) {
                dbg_verbose("IO: done IO, sleeping");
            } else {
                dbg("IO: unknown error from "
                    "memstick_next_req %d", error);
            }

            if (kthread_should_stop())
                set_current_state(TASK_RUNNING);

            schedule();
        } else {
            set_current_state(TASK_RUNNING);
            r592_execute_tpc(dev);
        }
    }
    return 0;
}
Example #11
0
File: vreg.c Project: 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;
}
Example #12
0
File: vreg.c Project: 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;
}
Example #13
0
File: vreg.c Project: 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;
}
Example #14
0
/**
 * @brief Configure all the voltage regulators associated with an interface
 * to their default states.
 * @param iface interface to configure
 */
static int interface_config(struct interface *iface)
{
    int rc = 0;

    dbg_verbose("Configuring interface %s.\n",
            iface->name ? iface->name : "unknown");

    /* Configure default state for the regulator pins */
    rc = vreg_config(iface->vreg);

    /*
     * Configure WAKEOUT as input, floating so that it does not interfere
     * with the wake and detect input pin
     */
    if (iface->wake_out) {
        if (stm32_configgpio(iface->wake_out | GPIO_INPUT) < 0) {
            dbg_error("%s: Failed to configure WAKEOUT pin for interface %s\n",
                      __func__, iface->name ? iface->name : "unknown");
            rc = -1;
        }
    }

    iface->power_state = false;

    return rc;
}
Example #15
0
/**
 * @brief           Initialize the power measurement HW and SW library.
 *                  To be called once, before any other call to the library.
 * @return          0 on success, standard error codes otherwise.
 * @param[in]       current_lsb_uA: current measurement precision (LSB) in uA
 * @param[in]       ct: sampling conversion time to be used
 * @param[in]       avg_count: averaging sample count (>0)
 */
int bdbpm_init(uint32_t current_lsb_uA,
               ina230_conversion_time ct,
               ina230_avg_count avg_count)
{
    dbg_verbose("%s(): Initializing with options lsb=%uuA, ct=%u, avg_count=%u...\n",
                __func__, current_lsb_uA, ct, avg_count);
    /* Initialize I2C internal structs */
    i2c_dev = up_i2cinitialize(PWRM_I2C_BUS);
    if (!i2c_dev) {
        dbg_error("%s(): Failed to get I2C bus %u\n", __func__, PWRM_I2C_BUS);
        return -ENXIO;
    }

    bdbpm_current_lsb = current_lsb_uA;
    if (ct >= ina230_ct_count) {
        dbg_error("%s(): invalid conversion time! (%u)\n", __func__, ct);
        up_i2cuninitialize(i2c_dev);
        return -EINVAL;
    }
    if (avg_count >= ina230_avg_count_max) {
        dbg_error("%s(): invalid average count! (%u)\n", __func__, avg_count);
        up_i2cuninitialize(i2c_dev);
        return -EINVAL;
    }
    bdbpm_ct = ct;
    bdbpm_avg_count = avg_count;

    current_dev = -1;

    /*
     * Setup I/O selection pins on U135
     *
     * Note: U135 is registered to gpio_chip from the board code
     */
    gpio_direction_out(I2C_INA230_SEL1_A, 1);
    gpio_direction_out(I2C_INA230_SEL1_B, 1);
    gpio_direction_out(I2C_INA230_SEL1_INH, 1);
    gpio_direction_out(I2C_INA230_SEL2_A, 1);
    gpio_direction_out(I2C_INA230_SEL2_B, 1);
    gpio_direction_out(I2C_INA230_SEL2_INH, 1);

    dbg_verbose("%s(): done.\n", __func__);

    return OK;
}
Example #16
0
/**
 * @brief           Convert voltage into current, following MAX9929F device
 *                  specifications.
 * @return          Current (microamps)
 * @param[in]       uV: voltage (in microvolts)
 */
static inline uint32_t max9929f_get_Iload(uint32_t uV)
{
    uint32_t uA;

    uA = (uV / MAX9929F_AV_GAIN) * MAX9929F_RSENSE_RECIPROCAL;
    dbg_verbose("%s(): uV=%uuV, Rs=100 mohms, gain=%u uA=%u\n", __func__,
                uV, MAX9929F_AV_GAIN, uA);
    return uA;
}
Example #17
0
/**
 * @brief           Convert sampled 12-bit data into voltage (microvolts),
 *                  considering ADC reference voltage and voltage LSB.
 * @return          Voltage (microvolts)
 * @param[in]       data: ADC sampled data
 */
static inline uint32_t adc_get_uV(uint32_t data)
{
    uint32_t uV;

    uV = data * ADC_VOLTAGE_LSB;
    dbg_verbose("%s(): data=%u, lsb=%uuV, uV=%uuV\n", __func__,
                data, ADC_VOLTAGE_LSB, uV);

    return uV;
}
Example #18
0
/**
 * @brief           Return time required to sample spring current consumption
 * warning          'spring' index starts at 1, not 0.
 * @return          spring current consumption sampling time (in microseconds),
 *                  standard error codes otherwise (<0)
 * @param[in]       spring: selected spring ([1..SPRING_COUNT])
 */
int32_t spwrm_get_sampling_time(uint8_t spring)
{
    uint8_t adc;

    CHECK_SPRING(spring);

    adc = spwrm_get_adc_device(spring);
    dbg_verbose("%s(): %s sampling time = %dus\n",
                __func__, spwrm_get_name(spring), adc_get_sampling_time(adc));
    return adc_get_sampling_time(adc);
}
Example #19
0
/* Interrupt handler */
static irqreturn_t r592_irq(int irq, void *data)
{
    struct r592_device *dev = (struct r592_device *)data;
    irqreturn_t ret = IRQ_NONE;
    u32 reg;
    u16 irq_enable, irq_status;
    unsigned long flags;
    int error;

    spin_lock_irqsave(&dev->irq_lock, flags);

    reg = r592_read_reg(dev, R592_REG_MSC);
    irq_enable = reg >> 16;
    irq_status = reg & 0xFFFF;

    /* Ack the interrupts */
    reg &= ~irq_status;
    r592_write_reg(dev, R592_REG_MSC, reg);

    /* Get the IRQ status minus bits that aren't enabled */
    irq_status &= (irq_enable);

    /* Due to limitation of memstick core, we don't look at bits that
    	indicate that card was removed/inserted and/or present */
    if (irq_status & (R592_REG_MSC_IRQ_INSERT | R592_REG_MSC_IRQ_REMOVE)) {

        bool card_was_added = irq_status & R592_REG_MSC_IRQ_INSERT;
        ret = IRQ_HANDLED;

        message("IRQ: card %s", card_was_added ? "added" : "removed");

        mod_timer(&dev->detect_timer,
                  jiffies + msecs_to_jiffies(card_was_added ? 500 : 50));
    }

    if (irq_status &
            (R592_REG_MSC_FIFO_DMA_DONE | R592_REG_MSC_FIFO_DMA_ERR)) {
        ret = IRQ_HANDLED;

        if (irq_status & R592_REG_MSC_FIFO_DMA_ERR) {
            message("IRQ: DMA error");
            error = -EIO;
        } else {
            dbg_verbose("IRQ: dma done");
            error = 0;
        }

        r592_stop_dma(dev, error);
        complete(&dev->dma_done);
    }

    spin_unlock_irqrestore(&dev->irq_lock, flags);
    return ret;
}
Example #20
0
/**
 * @brief           Return device start and end IDs depending on user options.
 * @return          device start and end IDs
 * @param[out]      d_start: device start ID
 * @param[out]      d_end: device end ID
 */
static void bdbpm_main_get_device_list(uint8_t *d_start, uint8_t *d_end)
{
    if (user_dev_id == DEV_COUNT) {
        *d_start = 0;
        *d_end = DEV_COUNT;
    } else {
        *d_start = user_dev_id;
        *d_end = user_dev_id + 1;
    }
    dbg_verbose("%s(): user_dev_id=%u => d_start=%u d_end=%u\n",
                __func__, user_dev_id, *d_start, *d_end);
}
Example #21
0
/**
 * @brief           Return rail start and end IDs depending on user options.
 * @return          rail start and end IDs
 * @param[in]       dev: device ID
 * @param[out]      r_start: power rail start ID
 * @param[out]      r_end: power rail end ID
 */
static void bdbpm_main_get_rail_list(uint8_t dev,
                                    uint8_t *r_start, uint8_t *r_end)
{
    if (user_rail_id == DEV_MAX_RAIL_COUNT) {
        *r_start = 0;
        *r_end = bdbpm_dev_rail_count(dev);
    } else {
        *r_start = user_rail_id;
        *r_end = user_rail_id + 1;
    }
    dbg_verbose("%s(): dev=%u => r_start=%u r_end=%u\n",
                __func__, dev, *r_start, *r_end);
}
Example #22
0
/* External interface: submit requests */
static void r592_submit_req(struct memstick_host *host)
{
    struct r592_device *dev = memstick_priv(host);
    unsigned long flags;

    if (dev->req)
        return;

    spin_lock_irqsave(&dev->io_thread_lock, flags);
    if (wake_up_process(dev->io_thread))
        dbg_verbose("IO thread woken to process requests");
    spin_unlock_irqrestore(&dev->io_thread_lock, flags);
}
Example #23
0
/**
 * @brief           Deinitialize HW & SW structure of a given power rail.
 * @param[in]       bdbpm_r: power rail device structure
 */
void bdbpm_deinit_rail(bdbpm_rail *bdbpm_r)
{
    int ret;

    if (!bdbpm_r) {
        dbg_error("%s(): invalid bdbpm_r!\n", __func__);
        return;
    }

    dbg_verbose("%s(): deinitializing %s device...\n",
                __func__, bdbpm_r->rail_name);
    /* Configure I2C Mux */
    ret = bdbpm_ina230_select(bdbpm_r->dev);
    if (ret) {
        dbg_error("%s(): failed to configure i2c mux! (%d)\n",
                  __func__, ret);
        return;
    }
    /* Deinit device */
    ina230_deinit(bdbpm_r->ina230_dev);
    /* Free memory */
    free(bdbpm_r);
    dbg_verbose("%s(): device deinit done.\n", __func__);
}
Example #24
0
/**
 * @brief Turn on the power to this interface
 * @returns: 0 on success, <0 on error
 */
int interface_pwr_enable(struct interface *iface)
{
    if (!iface) {
        return -ENODEV;
    }

    dbg_verbose("Enabling interface %s.\n",
                iface->name ? iface->name : "unknown");
    vreg_get(iface->vreg);

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

    return 0;
}
Example #25
0
/**
 * @brief           Return maximum rail count depending on user options.
 * @return          maximum rail count
 */
static uint8_t bdbpm_main_get_max_rail_count(void)
{
    uint8_t max_rcount;

    if (user_dev_id == DEV_COUNT) {
        max_rcount = DEV_MAX_RAIL_COUNT;
    } else {
        if (user_rail_id == DEV_MAX_RAIL_COUNT) {
            max_rcount = bdbpm_dev_rail_count(user_dev_id);
        } else {
            max_rcount = 1;
        }
    }
    dbg_verbose("%s(): max_rcount=%u\n", __func__, max_rcount);
    return max_rcount;
}
Example #26
0
/* Send data from SVC to switch */
inline int i2c_switch_send_msg(uint8_t *buf, unsigned int size)
{
    int ret;

    dbg_verbose("%s()\n", __func__);
    dbg_print_buf(DBG_VERBOSE, buf, size);

    i2c_select_device(I2C_ADDR_SWITCH);

    ret = I2C_WRITE(sw_exp_dev, buf, size);
    if (ret) {
        dbg_error("%s(): Error %d\n", __func__, ret);
        return ERROR;
    }

    return 0;
}
Example #27
0
/* Write data to the IO Expander */
int i2c_ioexp_write(uint8_t *msg, int size, uint8_t addr)
{
    int ret;

    i2c_select_device(addr);

    ret = I2C_WRITE(sw_exp_dev, msg, size);
    if (ret) {
        dbg_error("%s(): Error %d\n", __func__, ret);
        return ERROR;
    }

    dbg_verbose("%s()\n", __func__);
    dbg_print_buf(DBG_VERBOSE, msg, size);

    return ret;
}
Example #28
0
/* Transfers fifo contents in/out using DMA */
static int r592_transfer_fifo_dma(struct r592_device *dev)
{
    int len, sg_count;
    bool is_write;

    if (!dev->dma_capable || !dev->req->long_data)
        return -EINVAL;

    len = dev->req->sg.length;
    is_write = dev->req->data_dir == WRITE;

    if (len != R592_LFIFO_SIZE)
        return -EINVAL;

    dbg_verbose("doing dma transfer");

    dev->dma_error = 0;
    INIT_COMPLETION(dev->dma_done);

    /* TODO: hidden assumption about nenth beeing always 1 */
    sg_count = dma_map_sg(&dev->pci_dev->dev, &dev->req->sg, 1, is_write ?
                          PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE);

    if (sg_count != 1 ||
            (sg_dma_len(&dev->req->sg) < dev->req->sg.length)) {
        message("problem in dma_map_sg");
        return -EIO;
    }

    r592_start_dma(dev, is_write);

    /* Wait for DMA completion */
    if (!wait_for_completion_timeout(
                &dev->dma_done, msecs_to_jiffies(1000))) {
        message("DMA timeout");
        r592_stop_dma(dev, -ETIMEDOUT);
    }

    dma_unmap_sg(&dev->pci_dev->dev, &dev->req->sg, 1, is_write ?
                 PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE);


    return dev->dma_error;
}
Example #29
0
/*
 * @brief Generate a WAKEOUT signal to wake-up/power-up modules.
 * If assert is true, keep the WAKEOUT lines asserted.
 *
 * The corresponding power supplies must already be enabled.
 */
int interface_generate_wakeout(struct interface *iface, bool assert)
{
    int rc;

    if (!iface) {
        return -ENODEV;
    }

   /*
    * Assert the WAKEOUT line on the interfaces in order to power up the
    * modules.
    * When the WAKEOUT signal is de-asserted the bridges have to assert
    * the PS_HOLD signal asap in order to stay powered up.
    */
    dbg_verbose("Generating WAKEOUT on interface %s.\n",
                iface->name ? iface->name : "unknown");

    if (iface->wake_out) {
        rc = stm32_configgpio(iface->wake_out | GPIO_OUTPUT | GPIO_OUTPUT_SET);
        if (rc < 0) {
            dbg_error("%s: Failed to assert WAKEOUT pin for interface %s\n",
                      __func__, iface->name ? iface->name : "unknown");
            return rc;
        }

        if (!assert) {
            /* Wait for the bridges to react */
            usleep(WAKEOUT_PULSE_DURATION_IN_US);

            /* De-assert the lines */
            rc = stm32_configgpio(iface->wake_out | GPIO_INPUT);
            if (rc < 0) {
                dbg_error("%s: Failed to de-assert WAKEOUT pin for interface %s\n",
                          __func__, iface->name ? iface->name : "unknown");
                return rc;
            }
        }
    }

    return 0;
}
Example #30
0
/**
 * @brief Generate a ping to the given bit-mask of interfaces
 *        return authoritative time at the ping.
 *        AP must have already completed a timesync_wd_pins_init() routine
 */
int timesync_ping(uint64_t *frame_time) {

    irqstate_t flags;

    if (!frame_time)
        return -EINVAL;

    if (timesync_state != TIMESYNC_STATE_DEBUG_ACTIVE &&
        timesync_state != TIMESYNC_STATE_ACTIVE) {
        lldbg("timesync invalid state %d cannot ping\n", timesync_state);
        return -ENODEV;
    }

    flags = irqsave();
    timesync_strobe(timesync_pin_strobe_mask, frame_time);
    irqrestore(flags);

    dbg_verbose("Ping pinmask=0x%08lx frame-time=%llu\n", timesync_pin_strobe_mask,
                *frame_time);
    return 0;
}