Skip to content

Commit

Permalink
sdhc: sdhc_spi: compile-time determine if sdhc_ones needed
Browse files Browse the repository at this point in the history
Use the new `SPI_MOSI_OVERRUN_DT` macro to determine at compile-time
whether the 512 byte array of `sdhc_ones` is required.

(cherry picked from commit 5d87cd6)

Original-Signed-off-by: Jordan Yates <jordan@embeint.com>
GitOrigin-RevId: 5d87cd6
Cr-Build-Id: 8740178774340358353
Cr-Build-Url: https://cr-buildbucket.appspot.com/build/8740178774340358353
Copybot-Job-Name: zephyr-main-copybot-downstream
Change-Id: I334bfe317e86e6943c5b4e1a63f25de5a2c6926c
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/zephyr/+/5773301
Tested-by: ChromeOS Prod (Robot) <chromeos-ci-prod@chromeos-bot.iam.gserviceaccount.com>
Commit-Queue: Jeremy Bettis <jbettis@chromium.org>
Reviewed-by: Jeremy Bettis <jbettis@chromium.org>
Tested-by: Jeremy Bettis <jbettis@chromium.org>
  • Loading branch information
JordanYates authored and Chromeos LUCI committed Aug 8, 2024
1 parent aa4eb85 commit 68a0038
Showing 1 changed file with 32 additions and 13 deletions.
45 changes: 32 additions & 13 deletions drivers/sdhc/sdhc_spi.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,19 @@ LOG_MODULE_REGISTER(sdhc_spi, CONFIG_SDHC_LOG_LEVEL);
#define SPI_R1B_TIMEOUT_MS 3000
#define SD_SPI_SKIP_RETRIES 1000000

/* The SD protocol requires sending ones while reading but Zephyr
* defaults to writing zeros. This block of 512 bytes is used for writing
* 0xff while we read data blocks. Should remain const so this buffer is
* stored in flash.
#define _INST_REQUIRES_EXPLICIT_FF(inst) (SPI_MOSI_OVERRUN_DT(DT_INST_BUS(inst)) != 0xFF) ||

/* The SD protocol requires sending ones while reading but the Zephyr
* SPI API defers the choice of default values to the drivers.
*
* For drivers that we know will send ones we can avoid allocating a
* 512 byte array of ones and remove the limit on the number of bytes
* that can be read in a single transaction.
*/
#define ANY_INST_REQUIRES_EXPLICIT_FF DT_INST_FOREACH_STATUS_OKAY(_INST_REQUIRES_EXPLICIT_FF) 0

#if ANY_INST_REQUIRES_EXPLICIT_FF

static const uint8_t sdhc_ones[] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
Expand Down Expand Up @@ -78,6 +86,8 @@ static const uint8_t sdhc_ones[] = {

BUILD_ASSERT(sizeof(sdhc_ones) == 512, "0xFF array for SDHC must be 512 bytes");

#endif /* ANY_INST_REQUIRES_EXPLICIT_FF */

struct sdhc_spi_config {
const struct device *spi_dev;
const struct gpio_dt_spec pwr_gpio;
Expand All @@ -97,6 +107,7 @@ struct sdhc_spi_data {
static int sdhc_spi_rx(const struct device *spi_dev, struct spi_config *spi_cfg,
uint8_t *buf, int len)
{
#if ANY_INST_REQUIRES_EXPLICIT_FF
struct spi_buf tx_bufs[] = {
{
.buf = (uint8_t *)sdhc_ones,
Expand All @@ -108,6 +119,10 @@ static int sdhc_spi_rx(const struct device *spi_dev, struct spi_config *spi_cfg,
.buffers = tx_bufs,
.count = 1,
};
const struct spi_buf_set *tx_ptr = &tx;
#else
const struct spi_buf_set *tx_ptr = NULL;
#endif /* ANY_INST_REQUIRES_EXPLICIT_FF */

struct spi_buf rx_bufs[] = {
{
Expand All @@ -121,7 +136,7 @@ static int sdhc_spi_rx(const struct device *spi_dev, struct spi_config *spi_cfg,
.count = 1,
};

return spi_transceive(spi_dev, spi_cfg, &tx, &rx);
return spi_transceive(spi_dev, spi_cfg, tx_ptr, &rx);
}

static int sdhc_spi_init_card(const struct device *dev)
Expand Down Expand Up @@ -432,10 +447,14 @@ static int sdhc_spi_read_data(const struct device *dev, struct sdhc_data *data)
int ret;
uint8_t crc[SD_SPI_CRC16_SIZE + 1];

/* The SPI API defaults to sending 0x00 when no TX buffer is
* provided, so we are limited to 512 byte reads
* (unless we increase the size of SDHC buffer)
#if ANY_INST_REQUIRES_EXPLICIT_FF
/* If the driver requires explicit 0xFF bytes on receive, we
* are limited to receiving the size of the sdhc_ones buffer
*/
if (data->block_size > sizeof(sdhc_ones)) {
return -ENOTSUP;
}

const struct spi_buf tx_bufs[] = {
{
.buf = (uint8_t *)sdhc_ones,
Expand All @@ -447,6 +466,10 @@ static int sdhc_spi_read_data(const struct device *dev, struct sdhc_data *data)
.buffers = tx_bufs,
.count = 1,
};
const struct spi_buf_set *tx_ptr = &tx;
#else
const struct spi_buf_set *tx_ptr = NULL;
#endif /* ANY_INST_REQUIRES_EXPLICIT_FF */

struct spi_buf rx_bufs[] = {
{
Expand All @@ -460,10 +483,6 @@ static int sdhc_spi_read_data(const struct device *dev, struct sdhc_data *data)
.count = 1,
};

if (data->block_size > 512) {
/* SPI max BLKLEN is 512 */
return -ENOTSUP;
}

/* Read bytes until data stream starts. SD will send 0xff until
* data is available
Expand All @@ -480,7 +499,7 @@ static int sdhc_spi_read_data(const struct device *dev, struct sdhc_data *data)
/* Read blocks until we are out of data */
while (remaining--) {
ret = spi_transceive(config->spi_dev,
dev_data->spi_cfg, &tx, &rx);
dev_data->spi_cfg, tx_ptr, &rx);
if (ret) {
LOG_ERR("Data write failed");
return ret;
Expand Down

0 comments on commit 68a0038

Please sign in to comment.