From: Kevin Wells <wellsk40@gmail.com> To: sameo@linux.intel.com, rabin.vincent@stericsson.com, linus.walleij@stericsson.com, srinidhi.kasagar@stericsson.com, linux-kernel@vger.kernel.org, linux@arm.linux.org.uk, u.kleine-koenig@pengutronix.de, linux-arm-kernel@lists.infradead.org, tj@kernel.org, grant.likely@secretlab.ca, spi-devel-general@lists.sourceforge.net Cc: quentinyang05@gmail.com, Lukasz.Baj@tieto.com, kevin.wells@nxp.com Subject: resend: [PATCH] amba_pl022: Setup SPI configuration based on spi->mode Date: Fri, 10 Sep 2010 15:57:57 -0700 [thread overview] Message-ID: <AANLkTikbKwo9=xLWo1qEcc2E5aa2iN2F_KCokJPpnWOk@mail.gmail.com> (raw) (Re-send with full distribution list) This patch changes the way SPI transfers are setup. The previous method uses the pl022_config_chip data for configuration of loopback mode, edge count, clock polarity, number of data bits, and bit transfer order. This change configures these parameters based on spi->mode passed via master->setup and will allow the drivers use SPI to configure the interface. The fields lbm, clk_phase, clk_pol, and data_size are no longer needed. For the ST/pl023 setup, the first bit transferred for both RX and TX is now selected with the SPI_LSB_FIRST flag in spi->mode. There are also several very minor cleanups in the patch that fix return status on setup failures. This has been tested with the AT25 serial EEPROM driver and spidev modes 0-3 with loopback and varying data sizes. Reported-by: Quentin Yang <quentinyang05@gmail.com> Signed-off-by: Kevin Wells <wellsk40@gmail.com> --- drivers/spi/amba-pl022.c | 121 ++++++++++++++++++++-------------------------- 1 files changed, 53 insertions(+), 68 deletions(-) diff --git a/drivers/spi/amba-pl022.c b/drivers/spi/amba-pl022.c index acd35d1..1be488a 100644 --- a/drivers/spi/amba-pl022.c +++ b/drivers/spi/amba-pl022.c @@ -1248,12 +1248,6 @@ static int destroy_queue(struct pl022 *pl022) static int verify_controller_parameters(struct pl022 *pl022, struct pl022_config_chip *chip_info) { - if ((chip_info->lbm != LOOPBACK_ENABLED) - && (chip_info->lbm != LOOPBACK_DISABLED)) { - dev_err(chip_info->dev, - "loopback Mode is configured incorrectly\n"); - return -EINVAL; - } if ((chip_info->iface < SSP_INTERFACE_MOTOROLA_SPI) || (chip_info->iface > SSP_INTERFACE_UNIDIRECTIONAL)) { dev_err(chip_info->dev, @@ -1279,24 +1273,6 @@ static int verify_controller_parameters(struct pl022 *pl022, "cpsdvsr is configured incorrectly\n"); return -EINVAL; } - if ((chip_info->endian_rx != SSP_RX_MSB) - && (chip_info->endian_rx != SSP_RX_LSB)) { - dev_err(chip_info->dev, - "RX FIFO endianess is configured incorrectly\n"); - return -EINVAL; - } - if ((chip_info->endian_tx != SSP_TX_MSB) - && (chip_info->endian_tx != SSP_TX_LSB)) { - dev_err(chip_info->dev, - "TX FIFO endianess is configured incorrectly\n"); - return -EINVAL; - } - if ((chip_info->data_size < SSP_DATA_BITS_4) - || (chip_info->data_size > SSP_DATA_BITS_32)) { - dev_err(chip_info->dev, - "DATA Size is configured incorrectly\n"); - return -EINVAL; - } if ((chip_info->com_mode != INTERRUPT_TRANSFER) && (chip_info->com_mode != DMA_TRANSFER) && (chip_info->com_mode != POLLING_TRANSFER)) { @@ -1316,20 +1292,6 @@ static int verify_controller_parameters(struct pl022 *pl022, "TX FIFO Trigger Level is configured incorrectly\n"); return -EINVAL; } - if (chip_info->iface == SSP_INTERFACE_MOTOROLA_SPI) { - if ((chip_info->clk_phase != SSP_CLK_FIRST_EDGE) - && (chip_info->clk_phase != SSP_CLK_SECOND_EDGE)) { - dev_err(chip_info->dev, - "Clock Phase is configured incorrectly\n"); - return -EINVAL; - } - if ((chip_info->clk_pol != SSP_CLK_POL_IDLE_LOW) - && (chip_info->clk_pol != SSP_CLK_POL_IDLE_HIGH)) { - dev_err(chip_info->dev, - "Clock Polarity is configured incorrectly\n"); - return -EINVAL; - } - } if (chip_info->iface == SSP_INTERFACE_NATIONAL_MICROWIRE) { if ((chip_info->ctrl_len < SSP_BITS_4) || (chip_info->ctrl_len > SSP_BITS_32)) { @@ -1494,23 +1456,14 @@ static int process_dma_info(struct pl022_config_chip *chip_info, * controller hardware here, that is not done until the actual transfer * commence. */ - -/* FIXME: JUST GUESSING the spi->mode bits understood by this driver */ -#define MODEBITS (SPI_CPOL | SPI_CPHA | SPI_CS_HIGH \ - | SPI_LSB_FIRST | SPI_LOOP) - static int pl022_setup(struct spi_device *spi) { struct pl022_config_chip *chip_info; struct chip_data *chip; int status = 0; struct pl022 *pl022 = spi_master_get_devdata(spi->master); - - if (spi->mode & ~MODEBITS) { - dev_dbg(&spi->dev, "unsupported mode bits %x\n", - spi->mode & ~MODEBITS); - return -EINVAL; - } + unsigned int bits = spi->bits_per_word; + u32 tmp; if (!spi->max_speed_hz) return -EINVAL; @@ -1555,18 +1508,12 @@ static int pl022_setup(struct spi_device *spi) * Set controller data default values: * Polling is supported by default */ - chip_info->lbm = LOOPBACK_DISABLED; chip_info->com_mode = POLLING_TRANSFER; chip_info->iface = SSP_INTERFACE_MOTOROLA_SPI; chip_info->hierarchy = SSP_SLAVE; chip_info->slave_tx_disable = DO_NOT_DRIVE_TX; - chip_info->endian_tx = SSP_TX_LSB; - chip_info->endian_rx = SSP_RX_LSB; - chip_info->data_size = SSP_DATA_BITS_12; chip_info->rx_lev_trig = SSP_RX_1_OR_MORE_ELEM; chip_info->tx_lev_trig = SSP_TX_1_OR_MORE_EMPTY_LOC; - chip_info->clk_phase = SSP_CLK_SECOND_EDGE; - chip_info->clk_pol = SSP_CLK_POL_IDLE_LOW; chip_info->ctrl_len = SSP_BITS_8; chip_info->wait_state = SSP_MWIRE_WAIT_ZERO; chip_info->duplex = SSP_MICROWIRE_CHANNEL_FULL_DUPLEX; @@ -1601,12 +1548,16 @@ static int pl022_setup(struct spi_device *spi) chip->xfer_type = chip_info->com_mode; chip->cs_control = chip_info->cs_control; - if (chip_info->data_size <= 8) { - dev_dbg(&spi->dev, "1 <= n <=8 bits per word\n"); + if (bits <= 3) { + /* PL022 doesn't support less than 4-bits */ + status = -ENOTSUPP; + goto err_config_params; + } else if (bits <= 8) { + dev_dbg(&spi->dev, "4 <= n <=8 bits per word\n"); chip->n_bytes = 1; chip->read = READING_U8; chip->write = WRITING_U8; - } else if (chip_info->data_size <= 16) { + } else if (bits <= 16) { dev_dbg(&spi->dev, "9 <= n <= 16 bits per word\n"); chip->n_bytes = 2; chip->read = READING_U16; @@ -1623,6 +1574,7 @@ static int pl022_setup(struct spi_device *spi) dev_err(&spi->dev, "a standard pl022 can only handle " "1 <= n <= 16 bit words\n"); + status = -ENOTSUPP; goto err_config_params; } } @@ -1656,6 +1608,8 @@ static int pl022_setup(struct spi_device *spi) /* Special setup for the ST micro extended control registers */ if (pl022->vendor->extended_cr) { + u32 etx; + if (pl022->vendor->pl023) { /* These bits are only in the PL023 */ SSP_WRITE_BITS(chip->cr1, chip_info->clkdelay, @@ -1671,29 +1625,51 @@ static int pl022_setup(struct spi_device *spi) SSP_WRITE_BITS(chip->cr1, chip_info->wait_state, SSP_CR1_MASK_MWAIT_ST, 6); } - SSP_WRITE_BITS(chip->cr0, chip_info->data_size, + SSP_WRITE_BITS(chip->cr0, bits - 1, SSP_CR0_MASK_DSS_ST, 0); - SSP_WRITE_BITS(chip->cr1, chip_info->endian_rx, - SSP_CR1_MASK_RENDN_ST, 4); - SSP_WRITE_BITS(chip->cr1, chip_info->endian_tx, - SSP_CR1_MASK_TENDN_ST, 5); + + if (spi->mode & SPI_LSB_FIRST) { + tmp = SSP_RX_LSB; + etx = SSP_TX_LSB; + } else { + tmp = SSP_RX_MSB; + etx = SSP_TX_MSB; + } + SSP_WRITE_BITS(chip->cr1, tmp, SSP_CR1_MASK_RENDN_ST, 4); + SSP_WRITE_BITS(chip->cr1, etx, SSP_CR1_MASK_TENDN_ST, 5); SSP_WRITE_BITS(chip->cr1, chip_info->rx_lev_trig, SSP_CR1_MASK_RXIFLSEL_ST, 7); SSP_WRITE_BITS(chip->cr1, chip_info->tx_lev_trig, SSP_CR1_MASK_TXIFLSEL_ST, 10); } else { - SSP_WRITE_BITS(chip->cr0, chip_info->data_size, + SSP_WRITE_BITS(chip->cr0, bits - 1, SSP_CR0_MASK_DSS, 0); SSP_WRITE_BITS(chip->cr0, chip_info->iface, SSP_CR0_MASK_FRF, 4); } + /* Stuff that is common for all versions */ - SSP_WRITE_BITS(chip->cr0, chip_info->clk_pol, SSP_CR0_MASK_SPO, 6); - SSP_WRITE_BITS(chip->cr0, chip_info->clk_phase, SSP_CR0_MASK_SPH, 7); + if (spi->mode & SPI_CPOL) + tmp = SSP_CLK_POL_IDLE_HIGH; + else + tmp = SSP_CLK_POL_IDLE_LOW; + SSP_WRITE_BITS(chip->cr0, tmp, SSP_CR0_MASK_SPO, 6); + + if (spi->mode & SPI_CPHA) + tmp = SSP_CLK_SECOND_EDGE; + else + tmp = SSP_CLK_FIRST_EDGE; + SSP_WRITE_BITS(chip->cr0, tmp, SSP_CR0_MASK_SPH, 6); + SSP_WRITE_BITS(chip->cr0, chip_info->clk_freq.scr, SSP_CR0_MASK_SCR, 8); /* Loopback is available on all versions except PL023 */ - if (!pl022->vendor->pl023) - SSP_WRITE_BITS(chip->cr1, chip_info->lbm, SSP_CR1_MASK_LBM, 0); + if (!pl022->vendor->pl023) { + if (spi->mode & SPI_LOOP) + tmp = LOOPBACK_ENABLED; + else + tmp = LOOPBACK_DISABLED; + SSP_WRITE_BITS(chip->cr1, tmp, SSP_CR1_MASK_LBM, 0); + } SSP_WRITE_BITS(chip->cr1, SSP_DISABLED, SSP_CR1_MASK_SSE, 1); SSP_WRITE_BITS(chip->cr1, chip_info->hierarchy, SSP_CR1_MASK_MS, 2); SSP_WRITE_BITS(chip->cr1, chip_info->slave_tx_disable, SSP_CR1_MASK_SOD, 3); @@ -1702,6 +1678,7 @@ static int pl022_setup(struct spi_device *spi) spi_set_ctldata(spi, chip); return status; err_config_params: + spi_set_ctldata(spi, NULL); err_first_setup: kfree(chip); return status; @@ -1764,6 +1741,14 @@ pl022_probe(struct amba_device *adev, struct amba_id *id) master->setup = pl022_setup; master->transfer = pl022_transfer; + /* + * Supports mode 0-3, loopback, and active low CS. Transfers are + * always MS bit first on the original pl022. + */ + master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LOOP; + if (pl022->vendor->extended_cr) + master->mode_bits |= SPI_LSB_FIRST; + dev_dbg(&adev->dev, "BUSNO: %d\n", master->bus_num); status = amba_request_regions(adev, NULL); -- 1.7.2.2
WARNING: multiple messages have this Message-ID (diff)
From: wellsk40@gmail.com (Kevin Wells) To: linux-arm-kernel@lists.infradead.org Subject: resend: [PATCH] amba_pl022: Setup SPI configuration based on spi->mode Date: Fri, 10 Sep 2010 15:57:57 -0700 [thread overview] Message-ID: <AANLkTikbKwo9=xLWo1qEcc2E5aa2iN2F_KCokJPpnWOk@mail.gmail.com> (raw) (Re-send with full distribution list) This patch changes the way SPI transfers are setup. The previous method uses the pl022_config_chip data for configuration of loopback mode, edge count, clock polarity, number of data bits, and bit transfer order. This change configures these parameters based on spi->mode passed via master->setup and will allow the drivers use SPI to configure the interface. The fields lbm, clk_phase, clk_pol, and data_size are no longer needed. For the ST/pl023 setup, the first bit transferred for both RX and TX is now selected with the SPI_LSB_FIRST flag in spi->mode. There are also several very minor cleanups in the patch that fix return status on setup failures. This has been tested with the AT25 serial EEPROM driver and spidev modes 0-3 with loopback and varying data sizes. Reported-by: Quentin Yang <quentinyang05@gmail.com> Signed-off-by: Kevin Wells <wellsk40@gmail.com> --- ?drivers/spi/amba-pl022.c | ?121 ++++++++++++++++++++-------------------------- ?1 files changed, 53 insertions(+), 68 deletions(-) diff --git a/drivers/spi/amba-pl022.c b/drivers/spi/amba-pl022.c index acd35d1..1be488a 100644 --- a/drivers/spi/amba-pl022.c +++ b/drivers/spi/amba-pl022.c @@ -1248,12 +1248,6 @@ static int destroy_queue(struct pl022 *pl022) ?static int verify_controller_parameters(struct pl022 *pl022, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?struct pl022_config_chip *chip_info) ?{ - ? ? ? if ((chip_info->lbm != LOOPBACK_ENABLED) - ? ? ? ? ? && (chip_info->lbm != LOOPBACK_DISABLED)) { - ? ? ? ? ? ? ? dev_err(chip_info->dev, - ? ? ? ? ? ? ? ? ? ? ? "loopback Mode is configured incorrectly\n"); - ? ? ? ? ? ? ? return -EINVAL; - ? ? ? } ? ? ? ?if ((chip_info->iface < SSP_INTERFACE_MOTOROLA_SPI) ? ? ? ? ? ?|| (chip_info->iface > SSP_INTERFACE_UNIDIRECTIONAL)) { ? ? ? ? ? ? ? ?dev_err(chip_info->dev, @@ -1279,24 +1273,6 @@ static int verify_controller_parameters(struct pl022 *pl022, ? ? ? ? ? ? ? ? ? ? ? ?"cpsdvsr is configured incorrectly\n"); ? ? ? ? ? ? ? ?return -EINVAL; ? ? ? ?} - ? ? ? if ((chip_info->endian_rx != SSP_RX_MSB) - ? ? ? ? ? && (chip_info->endian_rx != SSP_RX_LSB)) { - ? ? ? ? ? ? ? dev_err(chip_info->dev, - ? ? ? ? ? ? ? ? ? ? ? "RX FIFO endianess is configured incorrectly\n"); - ? ? ? ? ? ? ? return -EINVAL; - ? ? ? } - ? ? ? if ((chip_info->endian_tx != SSP_TX_MSB) - ? ? ? ? ? && (chip_info->endian_tx != SSP_TX_LSB)) { - ? ? ? ? ? ? ? dev_err(chip_info->dev, - ? ? ? ? ? ? ? ? ? ? ? "TX FIFO endianess is configured incorrectly\n"); - ? ? ? ? ? ? ? return -EINVAL; - ? ? ? } - ? ? ? if ((chip_info->data_size < SSP_DATA_BITS_4) - ? ? ? ? ? || (chip_info->data_size > SSP_DATA_BITS_32)) { - ? ? ? ? ? ? ? dev_err(chip_info->dev, - ? ? ? ? ? ? ? ? ? ? ? "DATA Size is configured incorrectly\n"); - ? ? ? ? ? ? ? return -EINVAL; - ? ? ? } ? ? ? ?if ((chip_info->com_mode != INTERRUPT_TRANSFER) ? ? ? ? ? ?&& (chip_info->com_mode != DMA_TRANSFER) ? ? ? ? ? ?&& (chip_info->com_mode != POLLING_TRANSFER)) { @@ -1316,20 +1292,6 @@ static int verify_controller_parameters(struct pl022 *pl022, ? ? ? ? ? ? ? ? ? ? ? ?"TX FIFO Trigger Level is configured incorrectly\n"); ? ? ? ? ? ? ? ?return -EINVAL; ? ? ? ?} - ? ? ? if (chip_info->iface == SSP_INTERFACE_MOTOROLA_SPI) { - ? ? ? ? ? ? ? if ((chip_info->clk_phase != SSP_CLK_FIRST_EDGE) - ? ? ? ? ? ? ? ? ? && (chip_info->clk_phase != SSP_CLK_SECOND_EDGE)) { - ? ? ? ? ? ? ? ? ? ? ? dev_err(chip_info->dev, - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "Clock Phase is configured incorrectly\n"); - ? ? ? ? ? ? ? ? ? ? ? return -EINVAL; - ? ? ? ? ? ? ? } - ? ? ? ? ? ? ? if ((chip_info->clk_pol != SSP_CLK_POL_IDLE_LOW) - ? ? ? ? ? ? ? ? ? && (chip_info->clk_pol != SSP_CLK_POL_IDLE_HIGH)) { - ? ? ? ? ? ? ? ? ? ? ? dev_err(chip_info->dev, - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "Clock Polarity is configured incorrectly\n"); - ? ? ? ? ? ? ? ? ? ? ? return -EINVAL; - ? ? ? ? ? ? ? } - ? ? ? } ? ? ? ?if (chip_info->iface == SSP_INTERFACE_NATIONAL_MICROWIRE) { ? ? ? ? ? ? ? ?if ((chip_info->ctrl_len < SSP_BITS_4) ? ? ? ? ? ? ? ? ? ?|| (chip_info->ctrl_len > SSP_BITS_32)) { @@ -1494,23 +1456,14 @@ static int process_dma_info(struct pl022_config_chip *chip_info, ?* controller hardware here, that is not done until the actual transfer ?* commence. ?*/ - -/* FIXME: JUST GUESSING the spi->mode bits understood by this driver */ -#define MODEBITS ? ? ? (SPI_CPOL | SPI_CPHA | SPI_CS_HIGH \ - ? ? ? ? ? ? ? ? ? ? ? | SPI_LSB_FIRST | SPI_LOOP) - ?static int pl022_setup(struct spi_device *spi) ?{ ? ? ? ?struct pl022_config_chip *chip_info; ? ? ? ?struct chip_data *chip; ? ? ? ?int status = 0; ? ? ? ?struct pl022 *pl022 = spi_master_get_devdata(spi->master); - - ? ? ? if (spi->mode & ~MODEBITS) { - ? ? ? ? ? ? ? dev_dbg(&spi->dev, "unsupported mode bits %x\n", - ? ? ? ? ? ? ? ? ? ? ? spi->mode & ~MODEBITS); - ? ? ? ? ? ? ? return -EINVAL; - ? ? ? } + ? ? ? unsigned int bits = spi->bits_per_word; + ? ? ? u32 tmp; ? ? ? ?if (!spi->max_speed_hz) ? ? ? ? ? ? ? ?return -EINVAL; @@ -1555,18 +1508,12 @@ static int pl022_setup(struct spi_device *spi) ? ? ? ? ? ? ? ? * Set controller data default values: ? ? ? ? ? ? ? ? * Polling is supported by default ? ? ? ? ? ? ? ? */ - ? ? ? ? ? ? ? chip_info->lbm = LOOPBACK_DISABLED; ? ? ? ? ? ? ? ?chip_info->com_mode = POLLING_TRANSFER; ? ? ? ? ? ? ? ?chip_info->iface = SSP_INTERFACE_MOTOROLA_SPI; ? ? ? ? ? ? ? ?chip_info->hierarchy = SSP_SLAVE; ? ? ? ? ? ? ? ?chip_info->slave_tx_disable = DO_NOT_DRIVE_TX; - ? ? ? ? ? ? ? chip_info->endian_tx = SSP_TX_LSB; - ? ? ? ? ? ? ? chip_info->endian_rx = SSP_RX_LSB; - ? ? ? ? ? ? ? chip_info->data_size = SSP_DATA_BITS_12; ? ? ? ? ? ? ? ?chip_info->rx_lev_trig = SSP_RX_1_OR_MORE_ELEM; ? ? ? ? ? ? ? ?chip_info->tx_lev_trig = SSP_TX_1_OR_MORE_EMPTY_LOC; - ? ? ? ? ? ? ? chip_info->clk_phase = SSP_CLK_SECOND_EDGE; - ? ? ? ? ? ? ? chip_info->clk_pol = SSP_CLK_POL_IDLE_LOW; ? ? ? ? ? ? ? ?chip_info->ctrl_len = SSP_BITS_8; ? ? ? ? ? ? ? ?chip_info->wait_state = SSP_MWIRE_WAIT_ZERO; ? ? ? ? ? ? ? ?chip_info->duplex = SSP_MICROWIRE_CHANNEL_FULL_DUPLEX; @@ -1601,12 +1548,16 @@ static int pl022_setup(struct spi_device *spi) ? ? ? ?chip->xfer_type = chip_info->com_mode; ? ? ? ?chip->cs_control = chip_info->cs_control; - ? ? ? if (chip_info->data_size <= 8) { - ? ? ? ? ? ? ? dev_dbg(&spi->dev, "1 <= n <=8 bits per word\n"); + ? ? ? if (bits <= 3) { + ? ? ? ? ? ? ? /* PL022 doesn't support less than 4-bits */ + ? ? ? ? ? ? ? status = -ENOTSUPP; + ? ? ? ? ? ? ? goto err_config_params; + ? ? ? } else if (bits <= 8) { + ? ? ? ? ? ? ? dev_dbg(&spi->dev, "4 <= n <=8 bits per word\n"); ? ? ? ? ? ? ? ?chip->n_bytes = 1; ? ? ? ? ? ? ? ?chip->read = READING_U8; ? ? ? ? ? ? ? ?chip->write = WRITING_U8; - ? ? ? } else if (chip_info->data_size <= 16) { + ? ? ? } else if (bits <= 16) { ? ? ? ? ? ? ? ?dev_dbg(&spi->dev, "9 <= n <= 16 bits per word\n"); ? ? ? ? ? ? ? ?chip->n_bytes = 2; ? ? ? ? ? ? ? ?chip->read = READING_U16; @@ -1623,6 +1574,7 @@ static int pl022_setup(struct spi_device *spi) ? ? ? ? ? ? ? ? ? ? ? ?dev_err(&spi->dev, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?"a standard pl022 can only handle " ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?"1 <= n <= 16 bit words\n"); + ? ? ? ? ? ? ? ? ? ? ? status = -ENOTSUPP; ? ? ? ? ? ? ? ? ? ? ? ?goto err_config_params; ? ? ? ? ? ? ? ?} ? ? ? ?} @@ -1656,6 +1608,8 @@ static int pl022_setup(struct spi_device *spi) ? ? ? ?/* Special setup for the ST micro extended control registers */ ? ? ? ?if (pl022->vendor->extended_cr) { + ? ? ? ? ? ? ? u32 etx; + ? ? ? ? ? ? ? ?if (pl022->vendor->pl023) { ? ? ? ? ? ? ? ? ? ? ? ?/* These bits are only in the PL023 */ ? ? ? ? ? ? ? ? ? ? ? ?SSP_WRITE_BITS(chip->cr1, chip_info->clkdelay, @@ -1671,29 +1625,51 @@ static int pl022_setup(struct spi_device *spi) ? ? ? ? ? ? ? ? ? ? ? ?SSP_WRITE_BITS(chip->cr1, chip_info->wait_state, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? SSP_CR1_MASK_MWAIT_ST, 6); ? ? ? ? ? ? ? ?} - ? ? ? ? ? ? ? SSP_WRITE_BITS(chip->cr0, chip_info->data_size, + ? ? ? ? ? ? ? SSP_WRITE_BITS(chip->cr0, bits - 1, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? SSP_CR0_MASK_DSS_ST, 0); - ? ? ? ? ? ? ? SSP_WRITE_BITS(chip->cr1, chip_info->endian_rx, - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?SSP_CR1_MASK_RENDN_ST, 4); - ? ? ? ? ? ? ? SSP_WRITE_BITS(chip->cr1, chip_info->endian_tx, - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?SSP_CR1_MASK_TENDN_ST, 5); + + ? ? ? ? ? ? ? if (spi->mode & SPI_LSB_FIRST) { + ? ? ? ? ? ? ? ? ? ? ? tmp = SSP_RX_LSB; + ? ? ? ? ? ? ? ? ? ? ? etx = SSP_TX_LSB; + ? ? ? ? ? ? ? } else { + ? ? ? ? ? ? ? ? ? ? ? tmp = SSP_RX_MSB; + ? ? ? ? ? ? ? ? ? ? ? etx = SSP_TX_MSB; + ? ? ? ? ? ? ? } + ? ? ? ? ? ? ? SSP_WRITE_BITS(chip->cr1, tmp, SSP_CR1_MASK_RENDN_ST, 4); + ? ? ? ? ? ? ? SSP_WRITE_BITS(chip->cr1, etx, SSP_CR1_MASK_TENDN_ST, 5); ? ? ? ? ? ? ? ?SSP_WRITE_BITS(chip->cr1, chip_info->rx_lev_trig, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? SSP_CR1_MASK_RXIFLSEL_ST, 7); ? ? ? ? ? ? ? ?SSP_WRITE_BITS(chip->cr1, chip_info->tx_lev_trig, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? SSP_CR1_MASK_TXIFLSEL_ST, 10); ? ? ? ?} else { - ? ? ? ? ? ? ? SSP_WRITE_BITS(chip->cr0, chip_info->data_size, + ? ? ? ? ? ? ? SSP_WRITE_BITS(chip->cr0, bits - 1, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? SSP_CR0_MASK_DSS, 0); ? ? ? ? ? ? ? ?SSP_WRITE_BITS(chip->cr0, chip_info->iface, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? SSP_CR0_MASK_FRF, 4); ? ? ? ?} + ? ? ? ?/* Stuff that is common for all versions */ - ? ? ? SSP_WRITE_BITS(chip->cr0, chip_info->clk_pol, SSP_CR0_MASK_SPO, 6); - ? ? ? SSP_WRITE_BITS(chip->cr0, chip_info->clk_phase, SSP_CR0_MASK_SPH, 7); + ? ? ? if (spi->mode & SPI_CPOL) + ? ? ? ? ? ? ? tmp = SSP_CLK_POL_IDLE_HIGH; + ? ? ? else + ? ? ? ? ? ? ? tmp = SSP_CLK_POL_IDLE_LOW; + ? ? ? SSP_WRITE_BITS(chip->cr0, tmp, SSP_CR0_MASK_SPO, 6); + + ? ? ? if (spi->mode & SPI_CPHA) + ? ? ? ? ? ? ? tmp = SSP_CLK_SECOND_EDGE; + ? ? ? else + ? ? ? ? ? ? ? tmp = SSP_CLK_FIRST_EDGE; + ? ? ? SSP_WRITE_BITS(chip->cr0, tmp, SSP_CR0_MASK_SPH, 6); + ? ? ? ?SSP_WRITE_BITS(chip->cr0, chip_info->clk_freq.scr, SSP_CR0_MASK_SCR, 8); ? ? ? ?/* Loopback is available on all versions except PL023 */ - ? ? ? if (!pl022->vendor->pl023) - ? ? ? ? ? ? ? SSP_WRITE_BITS(chip->cr1, chip_info->lbm, SSP_CR1_MASK_LBM, 0); + ? ? ? if (!pl022->vendor->pl023) { + ? ? ? ? ? ? ? if (spi->mode & SPI_LOOP) + ? ? ? ? ? ? ? ? ? ? ? tmp = LOOPBACK_ENABLED; + ? ? ? ? ? ? ? else + ? ? ? ? ? ? ? ? ? ? ? tmp = LOOPBACK_DISABLED; + ? ? ? ? ? ? ? SSP_WRITE_BITS(chip->cr1, tmp, SSP_CR1_MASK_LBM, 0); + ? ? ? } ? ? ? ?SSP_WRITE_BITS(chip->cr1, SSP_DISABLED, SSP_CR1_MASK_SSE, 1); ? ? ? ?SSP_WRITE_BITS(chip->cr1, chip_info->hierarchy, SSP_CR1_MASK_MS, 2); ? ? ? ?SSP_WRITE_BITS(chip->cr1, chip_info->slave_tx_disable, SSP_CR1_MASK_SOD, 3); @@ -1702,6 +1678,7 @@ static int pl022_setup(struct spi_device *spi) ? ? ? ?spi_set_ctldata(spi, chip); ? ? ? ?return status; ?err_config_params: + ? ? ? spi_set_ctldata(spi, NULL); ?err_first_setup: ? ? ? ?kfree(chip); ? ? ? ?return status; @@ -1764,6 +1741,14 @@ pl022_probe(struct amba_device *adev, struct amba_id *id) ? ? ? ?master->setup = pl022_setup; ? ? ? ?master->transfer = pl022_transfer; + ? ? ? /* + ? ? ? ?* Supports mode 0-3, loopback, and active low CS. Transfers are + ? ? ? ?* always MS bit first on the original pl022. + ? ? ? ?*/ + ? ? ? master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LOOP; + ? ? ? if (pl022->vendor->extended_cr) + ? ? ? ? ? ? ? master->mode_bits |= SPI_LSB_FIRST; + ? ? ? ?dev_dbg(&adev->dev, "BUSNO: %d\n", master->bus_num); ? ? ? ?status = amba_request_regions(adev, NULL); -- 1.7.2.2
next reply other threads:[~2010-09-10 22:57 UTC|newest] Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top 2010-09-10 22:57 Kevin Wells [this message] 2010-09-10 22:57 ` resend: [PATCH] amba_pl022: Setup SPI configuration based on spi->mode Kevin Wells 2010-09-13 16:51 ` Kevin Wells 2010-09-13 16:51 ` Kevin Wells 2010-09-13 16:51 ` Kevin Wells 2010-09-14 14:45 ` Linus Walleij 2010-09-14 14:45 ` Linus Walleij 2010-09-14 14:45 ` Linus Walleij 2010-09-16 19:16 ` Kevin Wells 2010-09-16 19:16 ` Kevin Wells 2010-09-16 19:16 ` Kevin Wells 2010-09-10 22:57 Kevin Wells
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to='AANLkTikbKwo9=xLWo1qEcc2E5aa2iN2F_KCokJPpnWOk@mail.gmail.com' \ --to=wellsk40@gmail.com \ --cc=Lukasz.Baj@tieto.com \ --cc=grant.likely@secretlab.ca \ --cc=kevin.wells@nxp.com \ --cc=linus.walleij@stericsson.com \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=linux-kernel@vger.kernel.org \ --cc=linux@arm.linux.org.uk \ --cc=quentinyang05@gmail.com \ --cc=rabin.vincent@stericsson.com \ --cc=sameo@linux.intel.com \ --cc=spi-devel-general@lists.sourceforge.net \ --cc=srinidhi.kasagar@stericsson.com \ --cc=tj@kernel.org \ --cc=u.kleine-koenig@pengutronix.de \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.