Esempio n. 1
0
/**
 * @brief Close SPI device
 *
 * This function is called when the caller is no longer using this driver. It
 * should release or close all resources that were allocated by the open()
 * function. This function should be called after the open() function. If the
 * device is not opened yet, this function should return without any operations.
 *
 * @param dev pointer to structure of device data
 */
static void tsb_spi_dev_close(struct device *dev)
{
    int i;
    struct tsb_spi_dev_info *info = NULL;

    /* check input parameter */
    if (!dev || !device_get_private(dev)) {
        return;
    }

    info = device_get_private(dev);

    sem_wait(&info->lock);

    up_disable_irq(TSB_IRQ_SPI);
    irq_detach(TSB_IRQ_SPI);

    tsb_spi_hw_deinit(info);

    for (i = 0; i < info->num_boards; i++) {
        device_close(info->dev_spi_board[i]);
        info->dev_spi_board[i] = NULL;
    }
    info->state = TSB_SPI_STATE_CLOSED;
    sem_post(&info->lock);
}
Esempio n. 2
0
/**
 * @brief Remove SPI device
 *
 * This function is called by the system to unregister the driver. It should
 * release the hardware resource and interrupt setting, and then free memory
 * that allocated by the probe() function.
 * This function should be called after probe() function. If driver was opened,
 * this function should call close() function before releasing resources.
 *
 * @param dev pointer to structure of device data
 */
static void tsb_spi_dev_remove(struct device *dev)
{
    struct tsb_spi_info *info = NULL;

    /* check input parameter */
    if (!dev || !device_get_private(dev)) {
        return;
    }
    info = device_get_private(dev);

    info->state = TSB_SPI_STATE_INVALID;
    sem_destroy(&info->lock);
    sem_destroy(&info->bus);

    /* deinitialize gpio pins */
    tsb_spi_hw_deinit(dev);
    device_set_private(dev, NULL);
    free(info);
}
Esempio n. 3
0
/**
 * @brief Open SPI device
 *
 * This function is called when the caller is preparing to use this device
 * driver. This function should be called after probe() function and needs to
 * check whether the driver is already open. If driver was opened, it needs
 * to return an error code to the caller.
 *
 * @param dev pointer to structure of device data
 * @return 0 on success, negative errno on error
 */
static int tsb_spi_dev_open(struct device *dev)
{
    struct tsb_spi_dev_info *info = NULL;
    struct device *spi_board;
    int i;
    int ret = 0;

    /* check input parameter */
    if (!dev || !device_get_private(dev)) {
        return -EINVAL;
    }

    info = device_get_private(dev);

    sem_wait(&info->lock);

    if (info->state != TSB_SPI_STATE_CLOSED) {
        ret = -EBUSY;
        goto err_open;
    }

    /* open all the consecutive slaves we can find */
    info->num_boards = 0;
    for (i = 0; i < SPI_MAX_SLAVES; i++) {
        spi_board = device_open(DEVICE_TYPE_SPI_BOARD_HW, i);
        if (spi_board) {
            info->num_boards++;
            info->dev_spi_board[i] = spi_board;
        } else
            break;
    }

    info->curr_xfer.cs_high = 0;
    info->curr_xfer.bpw = 8;

    ret = tsb_spi_hw_init(info);
    if (ret) {
        goto err_hwinit;
    }
    /* register SPI IRQ number */
    ret = irq_attach(TSB_IRQ_SPI, tsb_spi_irq_handler, NULL);
    if (ret != OK) {
        ret = -EIO;
        goto err_irq;
    }

    up_enable_irq(TSB_IRQ_SPI);

    info->state = TSB_SPI_STATE_OPEN;
    sem_post(&info->lock);
    return ret;

err_irq:
    tsb_spi_hw_deinit(info);
err_hwinit:
    for (i = 0; i < info->num_boards; i++) {
        device_close(info->dev_spi_board[i]);
        info->dev_spi_board[i] = NULL;
    }
err_open:
    sem_post(&info->lock);
    return ret;
}