ofw_spi: Parse property for the SPI mode and CS polarity.

As cs is stored in a uint32_t, use the last bit to store the
active high flag as it's unlikely that we will have that much CS.

Reviewed by:	loos
MFC after:	2 weeks
Differential Revision:	https://reviews.freebsd.org/D8614
This commit is contained in:
Emmanuel Vadot 2016-12-18 14:54:20 +00:00
parent b5120bcd3b
commit 7073d12c4d
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=310229
14 changed files with 48 additions and 0 deletions

View File

@ -301,6 +301,8 @@ at91_spi_transfer(device_t dev, device_t child, struct spi_command *cmd)
/* get the proper chip select */ /* get the proper chip select */
spibus_get_cs(child, &cs); spibus_get_cs(child, &cs);
cs &= ~SPIBUS_CS_HIGH;
sc = device_get_softc(dev); sc = device_get_softc(dev);
i = 0; i = 0;

View File

@ -433,6 +433,9 @@ bcm_spi_transfer(device_t dev, device_t child, struct spi_command *cmd)
/* Get the proper chip select for this child. */ /* Get the proper chip select for this child. */
spibus_get_cs(child, &cs); spibus_get_cs(child, &cs);
cs &= ~SPIBUS_CS_HIGH;
if (cs > 2) { if (cs > 2) {
device_printf(dev, device_printf(dev,
"Invalid chip select %d requested by %s\n", cs, "Invalid chip select %d requested by %s\n", cs,

View File

@ -262,6 +262,8 @@ spi_transfer(device_t dev, device_t child, struct spi_command *cmd)
/* get the proper chip select */ /* get the proper chip select */
spibus_get_cs(child, &cs); spibus_get_cs(child, &cs);
cs &= ~SPIBUS_CS_HIGH;
/* Command */ /* Command */
spi_txrx(sc, cmd->tx_cmd, cmd->rx_cmd, cmd->tx_cmd_sz, cs); spi_txrx(sc, cmd->tx_cmd, cmd->rx_cmd, cmd->tx_cmd_sz, cs);

View File

@ -147,6 +147,8 @@ lpc_spi_transfer(device_t dev, device_t child, struct spi_command *cmd)
spibus_get_cs(child, &cs); spibus_get_cs(child, &cs);
cs &= ~SPIBUS_CS_HIGH;
/* Set CS active */ /* Set CS active */
lpc_gpio_set_state(child, cs, 0); lpc_gpio_set_state(child, cs, 0);

View File

@ -204,6 +204,8 @@ spi_transfer(device_t dev, device_t child, struct spi_command *cmd)
/* get the proper chip select */ /* get the proper chip select */
spibus_get_cs(child, &cs); spibus_get_cs(child, &cs);
cs &= ~SPIBUS_CS_HIGH;
/* Command */ /* Command */
spi_txrx(sc, cmd->tx_cmd, cmd->rx_cmd, cmd->tx_cmd_sz, cs); spi_txrx(sc, cmd->tx_cmd, cmd->rx_cmd, cmd->tx_cmd_sz, cs);

View File

@ -457,6 +457,9 @@ ti_spi_transfer(device_t dev, device_t child, struct spi_command *cmd)
/* Get the proper chip select for this child. */ /* Get the proper chip select for this child. */
spibus_get_cs(child, &cs); spibus_get_cs(child, &cs);
cs &= ~SPIBUS_CS_HIGH;
if (cs > sc->sc_numcs) { if (cs > sc->sc_numcs) {
device_printf(dev, "Invalid chip select %d requested by %s\n", device_printf(dev, "Invalid chip select %d requested by %s\n",
cs, device_get_nameunit(child)); cs, device_get_nameunit(child));

View File

@ -80,6 +80,7 @@ ofw_spibus_attach(device_t dev)
phandle_t child; phandle_t child;
pcell_t clock, paddr; pcell_t clock, paddr;
device_t childdev; device_t childdev;
uint32_t mode = SPIBUS_MODE_NONE;
sc->dev = dev; sc->dev = dev;
@ -102,6 +103,24 @@ ofw_spibus_attach(device_t dev)
continue; continue;
} }
/*
* Try to get the cpol/cpha mode
*/
if (OF_hasprop(child, "spi-cpol"))
mode = SPIBUS_MODE_CPOL;
if (OF_hasprop(child, "spi-cpha")) {
if (mode == SPIBUS_MODE_CPOL)
mode = SPIBUS_MODE_CPOL_CPHA;
else
mode = SPIBUS_MODE_CPHA;
}
/*
* Try to get the CS polarity
*/
if (OF_hasprop(child, "spi-cs-high"))
paddr |= SPIBUS_CS_HIGH;
/* /*
* Get the maximum clock frequency for device, zero means * Get the maximum clock frequency for device, zero means
* use the default bus speed. * use the default bus speed.
@ -120,6 +139,7 @@ ofw_spibus_attach(device_t dev)
continue; continue;
dinfo->opd_dinfo.cs = paddr; dinfo->opd_dinfo.cs = paddr;
dinfo->opd_dinfo.clock = clock; dinfo->opd_dinfo.clock = clock;
dinfo->opd_dinfo.mode = mode;
if (ofw_bus_gen_setup_devinfo(&dinfo->opd_obdinfo, child) != if (ofw_bus_gen_setup_devinfo(&dinfo->opd_obdinfo, child) !=
0) { 0) {
free(dinfo, M_DEVBUF); free(dinfo, M_DEVBUF);

View File

@ -46,6 +46,8 @@ struct spibus_ivar
uint32_t clock; uint32_t clock;
}; };
#define SPIBUS_CS_HIGH (1U << 31)
enum { enum {
SPIBUS_IVAR_CS, /* chip select that we're on */ SPIBUS_IVAR_CS, /* chip select that we're on */
SPIBUS_IVAR_MODE, /* SPI mode (0-3) */ SPIBUS_IVAR_MODE, /* SPI mode (0-3) */

View File

@ -193,6 +193,8 @@ spi_transfer(device_t dev, device_t child, struct spi_command *cmd)
/* get the proper chip select */ /* get the proper chip select */
spibus_get_cs(child, &cs); spibus_get_cs(child, &cs);
cs &= ~SPIBUS_CS_HIGH;
/* Assert CS */ /* Assert CS */
reg = READ4(sc, SPI_SSR); reg = READ4(sc, SPI_SSR);
reg &= ~(1 << cs); reg &= ~(1 << cs);

View File

@ -166,6 +166,8 @@ ar5315_spi_transfer(device_t dev, device_t child, struct spi_command *cmd)
spibus_get_cs(child, &cs); spibus_get_cs(child, &cs);
cs &= ~SPIBUS_CS_HIGH;
/* Open SPI controller interface */ /* Open SPI controller interface */
ar5315_spi_chip_activate(sc, cs); ar5315_spi_chip_activate(sc, cs);

View File

@ -212,6 +212,8 @@ ar71xx_spi_transfer(device_t dev, device_t child, struct spi_command *cmd)
spibus_get_cs(child, &cs); spibus_get_cs(child, &cs);
cs &= ~SPIBUS_CS_HIGH;
ar71xx_spi_chip_activate(sc, cs); ar71xx_spi_chip_activate(sc, cs);
KASSERT(cmd->tx_cmd_sz == cmd->rx_cmd_sz, KASSERT(cmd->tx_cmd_sz == cmd->rx_cmd_sz,

View File

@ -231,6 +231,8 @@ mtk_spi_transfer(device_t dev, device_t child, struct spi_command *cmd)
spibus_get_cs(child, &cs); spibus_get_cs(child, &cs);
cs &= ~SPIBUS_CS_HIGH;
if (cs != 0) if (cs != 0)
/* Only 1 CS */ /* Only 1 CS */
return (ENXIO); return (ENXIO);

View File

@ -236,6 +236,8 @@ mtk_spi_transfer(device_t dev, device_t child, struct spi_command *cmd)
spibus_get_cs(child, &cs); spibus_get_cs(child, &cs);
cs &= ~SPIBUS_CS_HIGH;
if (cs != 0) if (cs != 0)
/* Only 1 CS */ /* Only 1 CS */
return (ENXIO); return (ENXIO);

View File

@ -226,6 +226,8 @@ rt305x_spi_transfer(device_t dev, device_t child, struct spi_command *cmd)
spibus_get_cs(child, &cs); spibus_get_cs(child, &cs);
cs &= ~SPIBUS_CS_HIGH;
if (cs != 0) if (cs != 0)
/* Only 1 CS */ /* Only 1 CS */
return (ENXIO); return (ENXIO);