drivers: spi: Change to use software controlled cs in default

Added support for software controlled cs in Ambiq SPI drivers

Signed-off-by: Hao Luo <hluo@ambiq.com>
This commit is contained in:
Hao Luo 2024-06-26 10:12:46 +08:00 committed by Anas Nashif
commit 3faaaaba59
9 changed files with 30 additions and 181 deletions

View file

@ -69,67 +69,31 @@
group1 {
pinmux = <M0SCK_P5>, <M0MISO_P6>, <M0MOSI_P7>;
};
group2 {
pinmux = <NCE11_P11>;
drive-push-pull;
ambiq,iom-nce-module = <0>;
ambiq,iom-num = <0>;
};
};
spi1_default: spi1_default {
group1 {
pinmux = <M1SCK_P8>, <M1MISO_P9>, <M1MOSI_P10>;
};
group2 {
pinmux = <NCE14_P14>;
drive-push-pull;
ambiq,iom-nce-module = <1>;
ambiq,iom-num = <1>;
};
};
spi2_default: spi2_default {
group1 {
pinmux = <M2SCK_P27>, <M2MISO_P25>, <M2MOSI_P28>;
};
group2 {
pinmux = <NCE15_P15>;
drive-push-pull;
ambiq,iom-nce-module = <3>;
ambiq,iom-num = <2>;
};
};
spi3_default: spi3_default {
group1 {
pinmux = <M3SCK_P42>, <M3MISO_P43>, <M3MOSI_P38>;
};
group2 {
pinmux = <NCE12_P12>;
drive-push-pull;
ambiq,iom-nce-module = <0>;
ambiq,iom-num = <3>;
};
};
spi4_default: spi4_default {
group1 {
pinmux = <M4SCK_P39>, <M4MISO_P40>, <M4MOSI_P44>;
};
group2 {
pinmux = <NCE13_P13>;
drive-push-pull;
ambiq,iom-nce-module = <1>;
ambiq,iom-num = <4>;
};
};
spi5_default: spi5_default {
group1 {
pinmux = <M5SCK_P48>, <M5MISO_P49>, <M5MOSI_P47>;
};
group2 {
pinmux = <NCE16_P16>;
drive-push-pull;
ambiq,iom-nce-module = <0>;
ambiq,iom-num = <5>;
};
};
mspi0_default: mspi0_default{

View file

@ -106,6 +106,7 @@
compatible = "ambiq,spi";
pinctrl-0 = <&spi0_default>;
pinctrl-names = "default";
cs-gpios = <&gpio0_31 11 GPIO_ACTIVE_LOW>;
clock-frequency = <DT_FREQ_M(1)>;
status = "okay";
};

View file

@ -69,73 +69,31 @@
group1 {
pinmux = <M0SCK_P5>, <M0MISO_P6>, <M0MOSI_P7>;
};
group2 {
pinmux = <NCE11_P11>;
drive-push-pull;
ambiq,iom-mspi = <1>;
ambiq,iom-nce-module = <0>;
ambiq,iom-num = <0>;
};
};
spi1_default: spi1_default {
group1 {
pinmux = <M1SCK_P8>, <M1MISO_P9>, <M1MOSI_P10>;
};
group2 {
pinmux = <NCE34_P34>;
drive-push-pull;
ambiq,iom-mspi = <1>;
ambiq,iom-nce-module = <1>;
ambiq,iom-num = <1>;
};
};
spi2_default: spi2_default {
group1 {
pinmux = <M2SCK_P27>, <M2MISO_P25>, <M2MOSI_P28>;
};
group2 {
pinmux = <NCE15_P15>;
drive-push-pull;
ambiq,iom-mspi = <1>;
ambiq,iom-nce-module = <3>;
ambiq,iom-num = <2>;
};
};
spi3_default: spi3_default {
group1 {
pinmux = <M3SCK_P42>, <M3MISO_P43>, <M3MOSI_P38>;
};
group2 {
pinmux = <NCE29_P29>;
drive-push-pull;
ambiq,iom-mspi = <1>;
ambiq,iom-nce-module = <0>;
ambiq,iom-num = <3>;
};
};
spi4_default: spi4_default {
group1 {
pinmux = <M4SCK_P39>, <M4MISO_P40>, <M4MOSI_P44>;
};
group2 {
pinmux = <NCE13_P13>;
drive-push-pull;
ambiq,iom-mspi = <1>;
ambiq,iom-nce-module = <1>;
ambiq,iom-num = <4>;
};
};
spi5_default: spi5_default {
group1 {
pinmux = <M5SCK_P48>, <M5MISO_P49>, <M5MOSI_P47>;
};
group2 {
pinmux = <NCE16_P16>;
drive-push-pull;
ambiq,iom-mspi = <1>;
ambiq,iom-nce-module = <0>;
ambiq,iom-num = <5>;
};
};
mspi0_default: mspi0_default{

View file

@ -106,6 +106,7 @@
compatible = "ambiq,spi";
pinctrl-0 = <&spi0_default>;
pinctrl-names = "default";
cs-gpios = <&gpio0_31 11 GPIO_ACTIVE_LOW>;
clock-frequency = <DT_FREQ_M(1)>;
status = "okay";
};

View file

@ -77,81 +77,41 @@
group1 {
pinmux = <M0SCK_P5>, <M0MISO_P7>, <M0MOSI_P6>;
};
group2 {
pinmux = <NCE72_P72>;
drive-push-pull;
ambiq,iom-nce-module = <0>;
};
};
spi1_default: spi1_default {
group1 {
pinmux = <M1SCK_P8>, <M1MISO_P10>, <M1MOSI_P9>;
};
group2 {
pinmux = <NCE11_P11>;
drive-push-pull;
ambiq,iom-nce-module = <4>;
};
};
spi2_default: spi2_default {
group1 {
pinmux = <M2SCK_P25>, <M2MISO_P27>, <M2MOSI_P26>;
};
group2 {
pinmux = <NCE37_P37>;
drive-push-pull;
ambiq,iom-nce-module = <8>;
};
};
spi3_default: spi3_default {
group1 {
pinmux = <M3SCK_P31>, <M3MISO_P33>, <M3MOSI_P32>;
};
group2 {
pinmux = <NCE85_P85>;
drive-push-pull;
ambiq,iom-nce-module = <12>;
};
};
spi4_default: spi4_default {
group1 {
pinmux = <M4SCK_P34>, <M4MISO_P36>, <M4MOSI_P35>;
};
group2 {
pinmux = <NCE54_P54>;
drive-push-pull;
ambiq,iom-nce-module = <16>;
};
};
spi5_default: spi5_default {
group1 {
pinmux = <M5SCK_P47>, <M5MISO_P49>, <M5MOSI_P48>;
};
group2 {
pinmux = <NCE60_P60>;
drive-push-pull;
ambiq,iom-nce-module = <20>;
};
};
spi6_default: spi6_default {
group1 {
pinmux = <M6SCK_P61>, <M6MISO_P63>, <M6MOSI_P62>;
};
group2 {
pinmux = <NCE30_P30>;
drive-push-pull;
ambiq,iom-nce-module = <24>;
};
};
spi7_default: spi7_default {
group1 {
pinmux = <M7SCK_P22>, <M7MISO_P24>, <M7MOSI_P23>;
};
group2 {
pinmux = <NCE88_P88>;
drive-push-pull;
ambiq,iom-nce-module = <28>;
};
};
mspi0_default: mspi0_default{
group1 {

View file

@ -83,6 +83,7 @@
compatible = "ambiq,spi";
pinctrl-0 = <&spi1_default>;
pinctrl-names = "default";
cs-gpios = <&gpio0_31 11 GPIO_ACTIVE_LOW>;
clock-frequency = <DT_FREQ_M(1)>;
status = "okay";
};

View file

@ -86,82 +86,41 @@
group1 {
pinmux = <M0SCK_P5>, <M0MISO_P7>, <M0MOSI_P6>;
};
group2 {
pinmux = <NCE72_P72>;
drive-push-pull;
ambiq,iom-nce-module = <0>;
};
};
spi1_default: spi1_default {
group1 {
pinmux = <M1SCK_P8>, <M1MISO_P10>, <M1MOSI_P9>;
};
group2 {
pinmux = <NCE11_P11>;
drive-strength = "0.5";
drive-push-pull;
ambiq,iom-nce-module = <4>;
};
};
spi2_default: spi2_default {
group1 {
pinmux = <M2SCK_P25>, <M2MISO_P27>, <M2MOSI_P26>;
};
group2 {
pinmux = <NCE37_P37>;
drive-push-pull;
ambiq,iom-nce-module = <8>;
};
};
spi3_default: spi3_default {
group1 {
pinmux = <M3SCK_P31>, <M3MISO_P33>, <M3MOSI_P32>;
};
group2 {
pinmux = <NCE85_P85>;
drive-push-pull;
ambiq,iom-nce-module = <12>;
};
};
spi4_default: spi4_default {
group1 {
pinmux = <M4SCK_P34>, <M4MISO_P36>, <M4MOSI_P35>;
};
group2 {
pinmux = <NCE79_P79>;
drive-push-pull;
ambiq,iom-nce-module = <16>;
};
};
spi5_default: spi5_default {
group1 {
pinmux = <M5SCK_P47>, <M5MISO_P49>, <M5MOSI_P48>;
};
group2 {
pinmux = <NCE60_P60>;
drive-push-pull;
ambiq,iom-nce-module = <20>;
};
};
spi6_default: spi6_default {
group1 {
pinmux = <M6SCK_P61>, <M6MISO_P63>, <M6MOSI_P62>;
};
group2 {
pinmux = <NCE30_P30>;
drive-push-pull;
ambiq,iom-nce-module = <24>;
};
};
spi7_default: spi7_default {
group1 {
pinmux = <M7SCK_P22>, <M7MISO_P24>, <M7MOSI_P23>;
};
group2 {
pinmux = <NCE88_P88>;
drive-push-pull;
ambiq,iom-nce-module = <28>;
};
};
mspi0_default: mspi0_default{
group1 {

View file

@ -82,6 +82,7 @@
compatible = "ambiq,spi";
pinctrl-0 = <&spi1_default>;
pinctrl-names = "default";
cs-gpios = <&gpio0_31 11 GPIO_ACTIVE_LOW>;
clock-frequency = <1000000>;
status = "okay";
};

View file

@ -36,6 +36,7 @@ struct spi_ambiq_data {
am_hal_iom_config_t iom_cfg;
void *iom_handler;
int inst_idx;
bool cont;
};
typedef void (*spi_context_update_trx)(struct spi_context *ctx, uint8_t dfs, uint32_t len);
@ -55,6 +56,10 @@ static void spi_ambiq_callback(void *callback_ctxt, uint32_t status)
struct spi_ambiq_data *data = dev->data;
struct spi_context *ctx = &data->ctx;
/* de-assert cs until transfer finished and no need to hold cs */
if ((!data->cont) && (!spi_context_tx_buf_on(ctx)) && (!spi_context_rx_buf_on(ctx))) {
spi_context_cs_control(ctx, false);
}
spi_context_complete(ctx, dev, (status == AM_HAL_STATUS_SUCCESS) ? 0 : -EIO);
}
@ -67,6 +72,7 @@ static void spi_ambiq_reset(const struct device *dev)
am_hal_iom_disable(data->iom_handler);
/* NULL config to trigger reconfigure on next xfer */
ctx->config = NULL;
spi_context_cs_control(ctx, false);
/* signal any thread waiting on sync semaphore */
spi_context_complete(ctx, dev, -ETIMEDOUT);
/* clean up for next xfer */
@ -168,7 +174,7 @@ static int spi_config(const struct device *dev, const struct spi_config *config)
}
static int spi_ambiq_xfer_half_duplex(const struct device *dev, am_hal_iom_dir_e dir,
am_hal_iom_transfer_t trans, bool cont)
am_hal_iom_transfer_t trans)
{
struct spi_ambiq_data *data = dev->data;
struct spi_context *ctx = &data->ctx;
@ -217,10 +223,10 @@ static int spi_ambiq_xfer_half_duplex(const struct device *dev, am_hal_iom_dir_e
if ((i == (count - 1)) && (cur_num == rem_num)) {
is_last = true;
}
trans.bContinue = (is_last == true) ? cont : true;
trans.ui32NumBytes = cur_num;
trans.pui32TxBuffer = (uint32_t *)ctx->tx_buf;
trans.pui32RxBuffer = (uint32_t *)ctx->rx_buf;
ctx_update(ctx, 1, cur_num);
#ifdef CONFIG_SPI_AMBIQ_DMA
if (AM_HAL_STATUS_SUCCESS !=
am_hal_iom_nonblocking_transfer(
@ -237,7 +243,6 @@ static int spi_ambiq_xfer_half_duplex(const struct device *dev, am_hal_iom_dir_e
ret = am_hal_iom_blocking_transfer(data->iom_handler, &trans);
#endif
rem_num -= cur_num;
ctx_update(ctx, 1, cur_num);
}
}
}
@ -246,7 +251,7 @@ static int spi_ambiq_xfer_half_duplex(const struct device *dev, am_hal_iom_dir_e
}
static int spi_ambiq_xfer_full_duplex(const struct device *dev, am_hal_iom_dir_e dir,
am_hal_iom_transfer_t trans, bool cont)
am_hal_iom_transfer_t trans)
{
struct spi_ambiq_data *data = dev->data;
struct spi_context *ctx = &data->ctx;
@ -261,7 +266,6 @@ static int spi_ambiq_xfer_full_duplex(const struct device *dev, am_hal_iom_dir_e
trans.ui32NumBytes = MIN(ctx->rx_len, ctx->tx_len);
trans.pui32RxBuffer = (uint32_t *)ctx->rx_buf;
trans.pui32TxBuffer = (uint32_t *)ctx->tx_buf;
trans.bContinue = (trx_once) ? cont : true;
spi_context_update_tx(ctx, 1, trans.ui32NumBytes);
spi_context_update_rx(ctx, 1, trans.ui32NumBytes);
@ -278,7 +282,6 @@ static int spi_ambiq_xfer_full_duplex(const struct device *dev, am_hal_iom_dir_e
trans.ui32NumBytes = ctx->rx_len;
trans.pui32RxBuffer = (uint32_t *)ctx->rx_buf;
}
trans.bContinue = cont;
ret = am_hal_iom_blocking_transfer(data->iom_handler, &trans);
}
@ -299,6 +302,12 @@ static int spi_ambiq_fill_instruction(const struct device *dev, am_hal_iom_trans
*/
if (trans->ui32InstrLen + len > AM_HAL_IOM_MAX_OFFSETSIZE) {
ret = spi_ambiq_xfer_half_duplex(dev, AM_HAL_IOM_TX, *trans, true);
#if defined(CONFIG_SOC_SERIES_APOLLO3X)
trans->ui32Instr = 0;
#else
trans->ui64Instr = 0;
#endif
trans->ui32InstrLen = 0;
} else {
trans->ui32InstrLen += len;
for (int i = 0; i < len; i++) {
@ -316,19 +325,13 @@ static int spi_ambiq_fill_instruction(const struct device *dev, am_hal_iom_trans
static int spi_ambiq_xfer(const struct device *dev, const struct spi_config *config)
{
struct spi_ambiq_data *data = dev->data;
const struct spi_ambiq_config *cfg = dev->config;
struct spi_context *ctx = &data->ctx;
int ret = 0;
bool cont = (config->operation & SPI_HOLD_ON_CS) ? true : false;
data->cont = (config->operation & SPI_HOLD_ON_CS) ? true : false;
am_hal_iom_transfer_t trans = {0};
/* TODO Need to get iom_nce from different nodes of spi */
#if defined(CONFIG_SOC_SERIES_APOLLO3X)
trans.uPeerInfo.ui32SpiChipSelect = cfg->pcfg->states->pins[SPI_CS_INDEX].iom_nce;
#else
trans.uPeerInfo.ui32SpiChipSelect = cfg->pcfg->states->pins[SPI_CS_INDEX].iom_nce % 4;
#endif
spi_context_cs_control(ctx, true);
/* There's data to send */
if (spi_context_tx_on(ctx)) {
@ -343,25 +346,24 @@ static int spi_ambiq_xfer(const struct device *dev, const struct spi_config *con
spi_context_update_rx(ctx, 1, ctx->rx_len);
}
if ((!(config->operation & SPI_HALF_DUPLEX)) && (spi_context_tx_on(ctx))) {
ret = spi_ambiq_xfer_full_duplex(dev, AM_HAL_IOM_FULLDUPLEX, trans,
cont);
ret = spi_ambiq_xfer_full_duplex(dev, AM_HAL_IOM_FULLDUPLEX, trans);
} else {
ret = spi_ambiq_xfer_half_duplex(dev, AM_HAL_IOM_RX, trans,
cont);
ret = spi_ambiq_xfer_half_duplex(dev, AM_HAL_IOM_RX, trans);
}
} else { /* There's no data to Receive */
/* Regard the first tx_buf as cmd if there are more than one buffer */
if (ctx->tx_count > 1) {
ret = spi_ambiq_fill_instruction(dev, &trans, ctx->tx_len);
}
ret = spi_ambiq_xfer_half_duplex(dev, AM_HAL_IOM_TX, trans, cont);
ret = spi_ambiq_xfer_half_duplex(dev, AM_HAL_IOM_TX, trans);
}
} else { /* There's no data to send */
ret = spi_ambiq_xfer_half_duplex(dev, AM_HAL_IOM_RX, trans, cont);
ret = spi_ambiq_xfer_half_duplex(dev, AM_HAL_IOM_RX, trans);
}
#ifndef CONFIG_SPI_AMBIQ_DMA
if (!cont) {
if (!data->cont) {
spi_context_cs_control(ctx, false);
spi_context_complete(ctx, dev, ret);
}
#endif
@ -436,6 +438,7 @@ static int spi_ambiq_init(const struct device *dev)
ret = cfg->pwr_func();
ret |= pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT);
ret |= spi_context_cs_configure_all(&data->ctx);
if (ret < 0) {
LOG_ERR("Fail to config SPI pins\n");
goto end;
@ -473,7 +476,8 @@ end:
}; \
static struct spi_ambiq_data spi_ambiq_data##n = { \
SPI_CONTEXT_INIT_LOCK(spi_ambiq_data##n, ctx), \
SPI_CONTEXT_INIT_SYNC(spi_ambiq_data##n, ctx), .inst_idx = n}; \
SPI_CONTEXT_INIT_SYNC(spi_ambiq_data##n, ctx), \
SPI_CONTEXT_CS_GPIOS_INITIALIZE(DT_DRV_INST(n), ctx).inst_idx = n}; \
static const struct spi_ambiq_config spi_ambiq_config##n = { \
.base = DT_INST_REG_ADDR(n), \
.size = DT_INST_REG_SIZE(n), \