static int spi_dw_release(struct device *dev, const struct spi_config *config) { struct spi_dw_data *spi = dev->driver_data; if (!spi_context_configured(&spi->ctx, config)) { return -EINVAL; } spi_context_unlock_unconditionally(&spi->ctx); return 0; }
static int spi_nrfx_release(struct device *dev, const struct spi_config *spi_cfg) { struct spi_nrfx_data *dev_data = get_dev_data(dev); if (!spi_context_configured(&dev_data->ctx, spi_cfg)) { return -EINVAL; } spi_context_unlock_unconditionally(&dev_data->ctx); return 0; }
static int configure(struct device *dev, const struct spi_config *spi_cfg) { struct spi_context *ctx = &get_dev_data(dev)->ctx; if (spi_context_configured(ctx, spi_cfg)) { /* Already configured. No need to do it again. */ return 0; } if (SPI_OP_MODE_GET(spi_cfg->operation) == SPI_OP_MODE_MASTER) { LOG_ERR("Master mode is not supported on %s", dev->config->name); return -EINVAL; } if (spi_cfg->operation & SPI_MODE_LOOP) { LOG_ERR("Loopback mode is not supported"); return -EINVAL; } if ((spi_cfg->operation & SPI_LINES_MASK) != SPI_LINES_SINGLE) { LOG_ERR("Only single line mode is supported"); return -EINVAL; } if (SPI_WORD_SIZE_GET(spi_cfg->operation) != 8) { LOG_ERR("Word sizes other than 8 bits" " are not supported"); return -EINVAL; } if (spi_cfg->cs) { LOG_ERR("CS control via GPIO is not supported"); return -EINVAL; } ctx->config = spi_cfg; nrf_spis_configure(get_dev_config(dev)->spis.p_reg, get_nrf_spis_mode(spi_cfg->operation), get_nrf_spis_bit_order(spi_cfg->operation)); return 0; }
static int spi_stm32_configure(struct spi_config *config) { const struct spi_stm32_config *cfg = CONFIG_CFG(config); struct spi_stm32_data *data = CONFIG_DATA(config); const u32_t scaler[] = { LL_SPI_BAUDRATEPRESCALER_DIV2, LL_SPI_BAUDRATEPRESCALER_DIV4, LL_SPI_BAUDRATEPRESCALER_DIV8, LL_SPI_BAUDRATEPRESCALER_DIV16, LL_SPI_BAUDRATEPRESCALER_DIV32, LL_SPI_BAUDRATEPRESCALER_DIV64, LL_SPI_BAUDRATEPRESCALER_DIV128, LL_SPI_BAUDRATEPRESCALER_DIV256 }; SPI_TypeDef *spi = cfg->spi; u32_t clock; int br; if (spi_context_configured(&data->ctx, config)) { /* Nothing to do */ return 0; } if (SPI_WORD_SIZE_GET(config->operation) != 8) { return -ENOTSUP; } clock_control_get_rate(device_get_binding(STM32_CLOCK_CONTROL_NAME), (clock_control_subsys_t) &cfg->pclken, &clock); for (br = 1 ; br <= ARRAY_SIZE(scaler) ; ++br) { u32_t clk = clock >> br; if (clk < config->frequency) { break; } } if (br > ARRAY_SIZE(scaler)) { SYS_LOG_ERR("Unsupported frequency %uHz, max %uHz, min %uHz", config->frequency, clock >> 1, clock >> ARRAY_SIZE(scaler)); return -EINVAL; }
static int spi_dw_configure(const struct spi_dw_config *info, struct spi_dw_data *spi, const struct spi_config *config) { u32_t ctrlr0 = 0U; LOG_DBG("%p (prev %p)", config, spi->ctx.config); if (spi_context_configured(&spi->ctx, config)) { /* Nothing to do */ return 0; } /* Verify if requested op mode is relevant to this controller */ if (config->operation & SPI_OP_MODE_SLAVE) { if (!(info->op_modes & SPI_CTX_RUNTIME_OP_MODE_SLAVE)) { LOG_ERR("Slave mode not supported"); return -ENOTSUP; } } else { if (!(info->op_modes & SPI_CTX_RUNTIME_OP_MODE_MASTER)) { LOG_ERR("Master mode not supported"); return -ENOTSUP; } } if (config->operation & (SPI_TRANSFER_LSB | SPI_LINES_DUAL | SPI_LINES_QUAD)) { LOG_ERR("Unsupported configuration"); return -EINVAL; } /* Word size */ ctrlr0 |= DW_SPI_CTRLR0_DFS(SPI_WORD_SIZE_GET(config->operation)); /* Determine how many bytes are required per-frame */ spi->dfs = SPI_WS_TO_DFS(SPI_WORD_SIZE_GET(config->operation)); /* SPI mode */ if (SPI_MODE_GET(config->operation) & SPI_MODE_CPOL) { ctrlr0 |= DW_SPI_CTRLR0_SCPOL; } if (SPI_MODE_GET(config->operation) & SPI_MODE_CPHA) { ctrlr0 |= DW_SPI_CTRLR0_SCPH; } if (SPI_MODE_GET(config->operation) & SPI_MODE_LOOP) { ctrlr0 |= DW_SPI_CTRLR0_SRL; } /* Installing the configuration */ write_ctrlr0(ctrlr0, info->regs); /* At this point, it's mandatory to set this on the context! */ spi->ctx.config = config; if (!spi_dw_is_slave(spi)) { /* Baud rate and Slave select, for master only */ write_baudr(SPI_DW_CLK_DIVIDER(config->frequency), info->regs); write_ser(1 << config->slave, info->regs); } spi_context_cs_configure(&spi->ctx); if (spi_dw_is_slave(spi)) { LOG_DBG("Installed slave config %p:" " ws/dfs %u/%u, mode %u/%u/%u", config, SPI_WORD_SIZE_GET(config->operation), spi->dfs, (SPI_MODE_GET(config->operation) & SPI_MODE_CPOL) ? 1 : 0, (SPI_MODE_GET(config->operation) & SPI_MODE_CPHA) ? 1 : 0, (SPI_MODE_GET(config->operation) & SPI_MODE_LOOP) ? 1 : 0); } else { LOG_DBG("Installed master config %p: freq %uHz (div = %u)," " ws/dfs %u/%u, mode %u/%u/%u, slave %u", config, config->frequency, SPI_DW_CLK_DIVIDER(config->frequency), SPI_WORD_SIZE_GET(config->operation), spi->dfs, (SPI_MODE_GET(config->operation) & SPI_MODE_CPOL) ? 1 : 0, (SPI_MODE_GET(config->operation) & SPI_MODE_CPHA) ? 1 : 0, (SPI_MODE_GET(config->operation) & SPI_MODE_LOOP) ? 1 : 0, config->slave); } return 0; }