From b42a81ca0fa7b3b442a0731ffc4e7db44464b5f2 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Wed, 29 Sep 2010 17:31:33 +0900 Subject: spi/s3c64xx: Consider the clk_from_cmu flag Newer SoCs have the SPI clock scaling control in platform's clock management unit. Inorder for such SoCs to work, we need to check the flag clk_from_cmu before making any clock changes. Signed-off-by: Jassi Brar Signed-off-by: Grant Likely --- arch/arm/plat-samsung/include/plat/s3c64xx-spi.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch') diff --git a/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h b/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h index e5aba8f95b7..b226f7405e6 100644 --- a/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h +++ b/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h @@ -32,6 +32,8 @@ struct s3c64xx_spi_csinfo { * struct s3c64xx_spi_info - SPI Controller defining structure * @src_clk_nr: Clock source index for the CLK_CFG[SPI_CLKSEL] field. * @src_clk_name: Platform name of the corresponding clock. + * @clk_from_cmu: If the SPI clock/prescalar control block is present + * by the platform's clock-management-unit and not in SPI controller. * @num_cs: Number of CS this controller emulates. * @cfg_gpio: Configure pins for this SPI controller. * @fifo_lvl_mask: All tx fifo_lvl fields start at offset-6 @@ -41,6 +43,7 @@ struct s3c64xx_spi_csinfo { struct s3c64xx_spi_info { int src_clk_nr; char *src_clk_name; + bool clk_from_cmu; int num_cs; -- cgit v1.2.3-70-g09d2 From bde435a9ca376d0b7809768ca803dbf14416b9c1 Mon Sep 17 00:00:00 2001 From: Kevin Wells Date: Thu, 16 Sep 2010 06:18:50 -0700 Subject: spi/pl022: Add spi->mode support to AMBA SPI driver This patch adds spi->mode support for the AMBA pl022 driver and allows spidev to correctly alter SPI modes. Unused fields used in the pl022 header file for the pl022_config_chip have been removed. The ab8500 client driver selects the data transfer size instead of the platform data. For platforms that use the amba pl022 driver, the unused fields in the controller data structure have been removed and the .mode field in the SPI board info structure is used instead. Signed-off-by: Kevin Wells Tested-by: Linus Walleij Acked-by: Linus Walleij Signed-off-by: Grant Likely --- arch/arm/mach-lpc32xx/phy3250.c | 7 +-- arch/arm/mach-u300/dummyspichip.c | 5 +- arch/arm/mach-u300/spi.c | 10 +-- arch/arm/mach-ux500/board-mop500.c | 8 +-- drivers/mfd/ab8500-spi.c | 5 ++ drivers/spi/amba-pl022.c | 121 ++++++++++++++++--------------------- include/linux/amba/pl022.h | 6 -- 7 files changed, 63 insertions(+), 99 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-lpc32xx/phy3250.c b/arch/arm/mach-lpc32xx/phy3250.c index bc9a42da214..0c936cf5675 100644 --- a/arch/arm/mach-lpc32xx/phy3250.c +++ b/arch/arm/mach-lpc32xx/phy3250.c @@ -172,18 +172,12 @@ static void phy3250_spi_cs_set(u32 control) } static struct pl022_config_chip spi0_chip_info = { - .lbm = LOOPBACK_DISABLED, .com_mode = INTERRUPT_TRANSFER, .iface = SSP_INTERFACE_MOTOROLA_SPI, .hierarchy = SSP_MASTER, .slave_tx_disable = 0, - .endian_tx = SSP_TX_LSB, - .endian_rx = SSP_RX_LSB, - .data_size = SSP_DATA_BITS_8, .rx_lev_trig = SSP_RX_4_OR_MORE_ELEM, .tx_lev_trig = SSP_TX_4_OR_MORE_EMPTY_LOC, - .clk_phase = SSP_CLK_FIRST_EDGE, - .clk_pol = SSP_CLK_POL_IDLE_LOW, .ctrl_len = SSP_BITS_8, .wait_state = SSP_MWIRE_WAIT_ZERO, .duplex = SSP_MICROWIRE_CHANNEL_FULL_DUPLEX, @@ -239,6 +233,7 @@ static int __init phy3250_spi_board_register(void) .max_speed_hz = 5000000, .bus_num = 0, .chip_select = 0, + .mode = SPI_MODE_0, .platform_data = &eeprom, .controller_data = &spi0_chip_info, }, diff --git a/arch/arm/mach-u300/dummyspichip.c b/arch/arm/mach-u300/dummyspichip.c index 5f55012b7c9..03f79361259 100644 --- a/arch/arm/mach-u300/dummyspichip.c +++ b/arch/arm/mach-u300/dummyspichip.c @@ -46,7 +46,6 @@ static ssize_t dummy_looptest(struct device *dev, * struct, this is just used here to alter the behaviour of the chip * in order to perform tests. */ - struct pl022_config_chip *chip_info = spi->controller_data; int status; u8 txbuf[14] = {0xDE, 0xAD, 0xBE, 0xEF, 0x2B, 0xAD, 0xCA, 0xFE, 0xBA, 0xBE, 0xB1, 0x05, @@ -72,7 +71,7 @@ static ssize_t dummy_looptest(struct device *dev, * Force chip to 8 bit mode * WARNING: NEVER DO THIS IN REAL DRIVER CODE, THIS SHOULD BE STATIC! */ - chip_info->data_size = SSP_DATA_BITS_8; + spi->bits_per_word = 8; /* You should NOT DO THIS EITHER */ spi->master->setup(spi); @@ -159,7 +158,7 @@ static ssize_t dummy_looptest(struct device *dev, * Force chip to 16 bit mode * WARNING: NEVER DO THIS IN REAL DRIVER CODE, THIS SHOULD BE STATIC! */ - chip_info->data_size = SSP_DATA_BITS_16; + spi->bits_per_word = 16; /* You should NOT DO THIS EITHER */ spi->master->setup(spi); diff --git a/arch/arm/mach-u300/spi.c b/arch/arm/mach-u300/spi.c index f0e887bea30..edb2c0d255c 100644 --- a/arch/arm/mach-u300/spi.c +++ b/arch/arm/mach-u300/spi.c @@ -30,8 +30,6 @@ static void select_dummy_chip(u32 chipselect) } struct pl022_config_chip dummy_chip_info = { - /* Nominally this is LOOPBACK_DISABLED, but this is our dummy chip! */ - .lbm = LOOPBACK_ENABLED, /* * available POLLING_TRANSFER and INTERRUPT_TRANSFER, * DMA_TRANSFER does not work @@ -42,14 +40,8 @@ struct pl022_config_chip dummy_chip_info = { .hierarchy = SSP_MASTER, /* 0 = drive TX even as slave, 1 = do not drive TX as slave */ .slave_tx_disable = 0, - /* LSB first */ - .endian_tx = SSP_TX_LSB, - .endian_rx = SSP_RX_LSB, - .data_size = SSP_DATA_BITS_8, /* used to be 12 in some default */ .rx_lev_trig = SSP_RX_1_OR_MORE_ELEM, .tx_lev_trig = SSP_TX_1_OR_MORE_EMPTY_LOC, - .clk_phase = SSP_CLK_SECOND_EDGE, - .clk_pol = SSP_CLK_POL_IDLE_LOW, .ctrl_len = SSP_BITS_12, .wait_state = SSP_MWIRE_WAIT_ZERO, .duplex = SSP_MICROWIRE_CHANNEL_FULL_DUPLEX, @@ -75,7 +67,7 @@ static struct spi_board_info u300_spi_devices[] = { .bus_num = 0, /* Only one bus on this chip */ .chip_select = 0, /* Means SPI_CS_HIGH, change if e.g low CS */ - .mode = 0, + .mode = SPI_MODE_1 | SPI_LSB_FIRST | SPI_LOOP, }, #endif }; diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c index 0e8fd135a57..219ae0ca4ee 100644 --- a/arch/arm/mach-ux500/board-mop500.c +++ b/arch/arm/mach-ux500/board-mop500.c @@ -55,19 +55,13 @@ static void ab4500_spi_cs_control(u32 command) } struct pl022_config_chip ab4500_chip_info = { - .lbm = LOOPBACK_DISABLED, .com_mode = INTERRUPT_TRANSFER, .iface = SSP_INTERFACE_MOTOROLA_SPI, /* we can act as master only */ .hierarchy = SSP_MASTER, .slave_tx_disable = 0, - .endian_rx = SSP_RX_MSB, - .endian_tx = SSP_TX_MSB, - .data_size = SSP_DATA_BITS_24, .rx_lev_trig = SSP_RX_1_OR_MORE_ELEM, .tx_lev_trig = SSP_TX_1_OR_MORE_EMPTY_LOC, - .clk_phase = SSP_CLK_SECOND_EDGE, - .clk_pol = SSP_CLK_POL_IDLE_HIGH, .cs_control = ab4500_spi_cs_control, }; @@ -83,7 +77,7 @@ static struct spi_board_info u8500_spi_devices[] = { .max_speed_hz = 12000000, .bus_num = 0, .chip_select = 0, - .mode = SPI_MODE_0, + .mode = SPI_MODE_3, .irq = IRQ_DB8500_AB8500, }, }; diff --git a/drivers/mfd/ab8500-spi.c b/drivers/mfd/ab8500-spi.c index e1c8b62b086..01b6d584442 100644 --- a/drivers/mfd/ab8500-spi.c +++ b/drivers/mfd/ab8500-spi.c @@ -83,6 +83,11 @@ static int __devinit ab8500_spi_probe(struct spi_device *spi) struct ab8500 *ab8500; int ret; + spi->bits_per_word = 24; + ret = spi_setup(spi); + if (ret < 0) + return ret; + ab8500 = kzalloc(sizeof *ab8500, GFP_KERNEL); if (!ab8500) return -ENOMEM; diff --git a/drivers/spi/amba-pl022.c b/drivers/spi/amba-pl022.c index db0c67908d2..59c90f3ccc2 100644 --- a/drivers/spi/amba-pl022.c +++ b/drivers/spi/amba-pl022.c @@ -1595,12 +1595,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, @@ -1626,24 +1620,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)) { @@ -1663,20 +1639,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)) { @@ -1825,23 +1787,14 @@ static int calculate_effective_freq(struct pl022 *pl022, * 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; @@ -1884,18 +1837,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; @@ -1933,12 +1880,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; @@ -1955,6 +1906,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; } } @@ -1987,6 +1939,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, @@ -2002,29 +1956,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, 7); + 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); @@ -2033,6 +2009,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; @@ -2095,6 +2072,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); diff --git a/include/linux/amba/pl022.h b/include/linux/amba/pl022.h index db6a191ddcf..bf143663df8 100644 --- a/include/linux/amba/pl022.h +++ b/include/linux/amba/pl022.h @@ -277,19 +277,13 @@ struct pl022_ssp_controller { */ struct pl022_config_chip { struct device *dev; - enum ssp_loopback lbm; enum ssp_interface iface; enum ssp_hierarchy hierarchy; bool slave_tx_disable; struct ssp_clock_params clk_freq; - enum ssp_rx_endian endian_rx; - enum ssp_tx_endian endian_tx; - enum ssp_data_size data_size; enum ssp_mode com_mode; enum ssp_rx_level_trig rx_lev_trig; enum ssp_tx_level_trig tx_lev_trig; - enum ssp_spi_clk_phase clk_phase; - enum ssp_spi_clk_pol clk_pol; enum ssp_microwire_ctrl_len ctrl_len; enum ssp_microwire_wait_state wait_state; enum ssp_duplex duplex; -- cgit v1.2.3-70-g09d2 From f3016fa591c788d6d545ef7907e24c8b5d788759 Mon Sep 17 00:00:00 2001 From: Mingkai Hu Date: Tue, 12 Oct 2010 18:18:33 +0800 Subject: powerpc/of: add eSPI controller dts bindings and DTS modification Also modifiy the document of cell-index in SPI controller. Add the SPI flash(s25fl128p01) support on p4080ds and mpc8536ds board. Signed-off-by: Mingkai Hu Signed-off-by: Grant Likely --- Documentation/powerpc/dts-bindings/fsl/spi.txt | 24 +++++++++++- arch/powerpc/boot/dts/mpc8536ds.dts | 52 ++++++++++++++++++++++++++ arch/powerpc/boot/dts/p4080ds.dts | 11 ++---- 3 files changed, 79 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/Documentation/powerpc/dts-bindings/fsl/spi.txt b/Documentation/powerpc/dts-bindings/fsl/spi.txt index 80510c018ee..777abd7399d 100644 --- a/Documentation/powerpc/dts-bindings/fsl/spi.txt +++ b/Documentation/powerpc/dts-bindings/fsl/spi.txt @@ -1,7 +1,9 @@ * SPI (Serial Peripheral Interface) Required properties: -- cell-index : SPI controller index. +- cell-index : QE SPI subblock index. + 0: QE subblock SPI1 + 1: QE subblock SPI2 - compatible : should be "fsl,spi". - mode : the SPI operation mode, it can be "cpu" or "cpu-qe". - reg : Offset and length of the register set for the device @@ -29,3 +31,23 @@ Example: gpios = <&gpio 18 1 // device reg=<0> &gpio 19 1>; // device reg=<1> }; + + +* eSPI (Enhanced Serial Peripheral Interface) + +Required properties: +- compatible : should be "fsl,mpc8536-espi". +- reg : Offset and length of the register set for the device. +- interrupts : should contain eSPI interrupt, the device has one interrupt. +- fsl,espi-num-chipselects : the number of the chipselect signals. + +Example: + spi@110000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,mpc8536-espi"; + reg = <0x110000 0x1000>; + interrupts = <53 0x2>; + interrupt-parent = <&mpic>; + fsl,espi-num-chipselects = <4>; + }; diff --git a/arch/powerpc/boot/dts/mpc8536ds.dts b/arch/powerpc/boot/dts/mpc8536ds.dts index 815cebb2e3e..a75c10eed26 100644 --- a/arch/powerpc/boot/dts/mpc8536ds.dts +++ b/arch/powerpc/boot/dts/mpc8536ds.dts @@ -108,6 +108,58 @@ }; }; + spi@7000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,mpc8536-espi"; + reg = <0x7000 0x1000>; + interrupts = <59 0x2>; + interrupt-parent = <&mpic>; + fsl,espi-num-chipselects = <4>; + + flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "spansion,s25sl12801"; + reg = <0>; + spi-max-frequency = <40000000>; + partition@u-boot { + label = "u-boot"; + reg = <0x00000000 0x00100000>; + read-only; + }; + partition@kernel { + label = "kernel"; + reg = <0x00100000 0x00500000>; + read-only; + }; + partition@dtb { + label = "dtb"; + reg = <0x00600000 0x00100000>; + read-only; + }; + partition@fs { + label = "file system"; + reg = <0x00700000 0x00900000>; + }; + }; + flash@1 { + compatible = "spansion,s25sl12801"; + reg = <1>; + spi-max-frequency = <40000000>; + }; + flash@2 { + compatible = "spansion,s25sl12801"; + reg = <2>; + spi-max-frequency = <40000000>; + }; + flash@3 { + compatible = "spansion,s25sl12801"; + reg = <3>; + spi-max-frequency = <40000000>; + }; + }; + dma@21300 { #address-cells = <1>; #size-cells = <1>; diff --git a/arch/powerpc/boot/dts/p4080ds.dts b/arch/powerpc/boot/dts/p4080ds.dts index 2f0de24e382..5b7fc29dd6c 100644 --- a/arch/powerpc/boot/dts/p4080ds.dts +++ b/arch/powerpc/boot/dts/p4080ds.dts @@ -236,22 +236,19 @@ }; spi@110000 { - cell-index = <0>; #address-cells = <1>; #size-cells = <0>; - compatible = "fsl,espi"; + compatible = "fsl,p4080-espi", "fsl,mpc8536-espi"; reg = <0x110000 0x1000>; interrupts = <53 0x2>; interrupt-parent = <&mpic>; - espi,num-ss-bits = <4>; - mode = "cpu"; + fsl,espi-num-chipselects = <4>; - fsl_m25p80@0 { + flash@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "fsl,espi-flash"; + compatible = "spansion,s25sl12801"; reg = <0>; - linux,modalias = "fsl_m25p80"; spi-max-frequency = <40000000>; /* input clock */ partition@u-boot { label = "u-boot"; -- cgit v1.2.3-70-g09d2 From 201bbc6fd84c67b4021f454d3e4c30d5cd77f702 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Wed, 23 Sep 2009 20:56:10 +0000 Subject: spi/bfin_spi: drop custom cs_change_per_word support As David points out, the cs_change_per_word option isn't standard, nor is anyone actually using it. So punt all of the dead code considering it makes up ~10% of the code size. Reported-by: David Brownell Signed-off-by: Mike Frysinger --- arch/blackfin/include/asm/bfin5xx_spi.h | 1 - drivers/spi/spi_bfin5xx.c | 148 +++----------------------------- 2 files changed, 12 insertions(+), 137 deletions(-) (limited to 'arch') diff --git a/arch/blackfin/include/asm/bfin5xx_spi.h b/arch/blackfin/include/asm/bfin5xx_spi.h index ed4f8c6db0c..ee3ecb96aa1 100644 --- a/arch/blackfin/include/asm/bfin5xx_spi.h +++ b/arch/blackfin/include/asm/bfin5xx_spi.h @@ -120,7 +120,6 @@ struct bfin5xx_spi_chip { u16 ctl_reg; u8 enable_dma; u8 bits_per_word; - u8 cs_change_per_word; u16 cs_chg_udelay; /* Some devices require 16-bit delays */ u32 cs_gpio; /* Value to send if no TX value is supplied, usually 0x0 or 0xFFFF */ diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c index 6150a8cfb82..f4023a78c87 100644 --- a/drivers/spi/spi_bfin5xx.c +++ b/drivers/spi/spi_bfin5xx.c @@ -114,7 +114,6 @@ struct chip_data { u8 width; /* 0 or 1 */ u8 enable_dma; u8 bits_per_word; /* 8 or 16 */ - u8 cs_change_per_word; u16 cs_chg_udelay; /* Some devices require > 255usec delay */ u32 cs_gpio; u16 idle_tx_val; @@ -309,24 +308,6 @@ static void bfin_spi_u8_writer(struct driver_data *drv_data) } } -static void bfin_spi_u8_cs_chg_writer(struct driver_data *drv_data) -{ - struct chip_data *chip = drv_data->cur_chip; - - /* clear RXS (we check for RXS inside the loop) */ - bfin_spi_dummy_read(drv_data); - - while (drv_data->tx < drv_data->tx_end) { - bfin_spi_cs_active(drv_data, chip); - write_TDBR(drv_data, (*(u8 *) (drv_data->tx++))); - /* make sure transfer finished before deactiving CS */ - while (!(read_STAT(drv_data) & BIT_STAT_RXS)) - cpu_relax(); - bfin_spi_dummy_read(drv_data); - bfin_spi_cs_deactive(drv_data, chip); - } -} - static void bfin_spi_u8_reader(struct driver_data *drv_data) { u16 tx_val = drv_data->cur_chip->idle_tx_val; @@ -342,24 +323,6 @@ static void bfin_spi_u8_reader(struct driver_data *drv_data) } } -static void bfin_spi_u8_cs_chg_reader(struct driver_data *drv_data) -{ - struct chip_data *chip = drv_data->cur_chip; - u16 tx_val = chip->idle_tx_val; - - /* discard old RX data and clear RXS */ - bfin_spi_dummy_read(drv_data); - - while (drv_data->rx < drv_data->rx_end) { - bfin_spi_cs_active(drv_data, chip); - write_TDBR(drv_data, tx_val); - while (!(read_STAT(drv_data) & BIT_STAT_RXS)) - cpu_relax(); - *(u8 *) (drv_data->rx++) = read_RDBR(drv_data); - bfin_spi_cs_deactive(drv_data, chip); - } -} - static void bfin_spi_u8_duplex(struct driver_data *drv_data) { /* discard old RX data and clear RXS */ @@ -373,23 +336,6 @@ static void bfin_spi_u8_duplex(struct driver_data *drv_data) } } -static void bfin_spi_u8_cs_chg_duplex(struct driver_data *drv_data) -{ - struct chip_data *chip = drv_data->cur_chip; - - /* discard old RX data and clear RXS */ - bfin_spi_dummy_read(drv_data); - - while (drv_data->rx < drv_data->rx_end) { - bfin_spi_cs_active(drv_data, chip); - write_TDBR(drv_data, (*(u8 *) (drv_data->tx++))); - while (!(read_STAT(drv_data) & BIT_STAT_RXS)) - cpu_relax(); - *(u8 *) (drv_data->rx++) = read_RDBR(drv_data); - bfin_spi_cs_deactive(drv_data, chip); - } -} - static void bfin_spi_u16_writer(struct driver_data *drv_data) { /* clear RXS (we check for RXS inside the loop) */ @@ -407,25 +353,6 @@ static void bfin_spi_u16_writer(struct driver_data *drv_data) } } -static void bfin_spi_u16_cs_chg_writer(struct driver_data *drv_data) -{ - struct chip_data *chip = drv_data->cur_chip; - - /* clear RXS (we check for RXS inside the loop) */ - bfin_spi_dummy_read(drv_data); - - while (drv_data->tx < drv_data->tx_end) { - bfin_spi_cs_active(drv_data, chip); - write_TDBR(drv_data, (*(u16 *) (drv_data->tx))); - drv_data->tx += 2; - /* make sure transfer finished before deactiving CS */ - while (!(read_STAT(drv_data) & BIT_STAT_RXS)) - cpu_relax(); - bfin_spi_dummy_read(drv_data); - bfin_spi_cs_deactive(drv_data, chip); - } -} - static void bfin_spi_u16_reader(struct driver_data *drv_data) { u16 tx_val = drv_data->cur_chip->idle_tx_val; @@ -442,25 +369,6 @@ static void bfin_spi_u16_reader(struct driver_data *drv_data) } } -static void bfin_spi_u16_cs_chg_reader(struct driver_data *drv_data) -{ - struct chip_data *chip = drv_data->cur_chip; - u16 tx_val = chip->idle_tx_val; - - /* discard old RX data and clear RXS */ - bfin_spi_dummy_read(drv_data); - - while (drv_data->rx < drv_data->rx_end) { - bfin_spi_cs_active(drv_data, chip); - write_TDBR(drv_data, tx_val); - while (!(read_STAT(drv_data) & BIT_STAT_RXS)) - cpu_relax(); - *(u16 *) (drv_data->rx) = read_RDBR(drv_data); - drv_data->rx += 2; - bfin_spi_cs_deactive(drv_data, chip); - } -} - static void bfin_spi_u16_duplex(struct driver_data *drv_data) { /* discard old RX data and clear RXS */ @@ -476,25 +384,6 @@ static void bfin_spi_u16_duplex(struct driver_data *drv_data) } } -static void bfin_spi_u16_cs_chg_duplex(struct driver_data *drv_data) -{ - struct chip_data *chip = drv_data->cur_chip; - - /* discard old RX data and clear RXS */ - bfin_spi_dummy_read(drv_data); - - while (drv_data->rx < drv_data->rx_end) { - bfin_spi_cs_active(drv_data, chip); - write_TDBR(drv_data, (*(u16 *) (drv_data->tx))); - drv_data->tx += 2; - while (!(read_STAT(drv_data) & BIT_STAT_RXS)) - cpu_relax(); - *(u16 *) (drv_data->rx) = read_RDBR(drv_data); - drv_data->rx += 2; - bfin_spi_cs_deactive(drv_data, chip); - } -} - /* test if ther is more transfer to be done */ static void *bfin_spi_next_transfer(struct driver_data *drv_data) { @@ -773,23 +662,17 @@ static void bfin_spi_pump_transfers(unsigned long data) case 8: drv_data->n_bytes = 1; width = CFG_SPI_WORDSIZE8; - drv_data->read = chip->cs_change_per_word ? - bfin_spi_u8_cs_chg_reader : bfin_spi_u8_reader; - drv_data->write = chip->cs_change_per_word ? - bfin_spi_u8_cs_chg_writer : bfin_spi_u8_writer; - drv_data->duplex = chip->cs_change_per_word ? - bfin_spi_u8_cs_chg_duplex : bfin_spi_u8_duplex; + drv_data->read = bfin_spi_u8_reader; + drv_data->write = bfin_spi_u8_writer; + drv_data->duplex = bfin_spi_u8_duplex; break; case 16: drv_data->n_bytes = 2; width = CFG_SPI_WORDSIZE16; - drv_data->read = chip->cs_change_per_word ? - bfin_spi_u16_cs_chg_reader : bfin_spi_u16_reader; - drv_data->write = chip->cs_change_per_word ? - bfin_spi_u16_cs_chg_writer : bfin_spi_u16_writer; - drv_data->duplex = chip->cs_change_per_word ? - bfin_spi_u16_cs_chg_duplex : bfin_spi_u16_duplex; + drv_data->read = bfin_spi_u16_reader; + drv_data->write = bfin_spi_u16_writer; + drv_data->duplex = bfin_spi_u16_duplex; break; default: @@ -1164,7 +1047,6 @@ static int bfin_spi_setup(struct spi_device *spi) && drv_data->master_info->enable_dma; chip->ctl_reg = chip_info->ctl_reg; chip->bits_per_word = chip_info->bits_per_word; - chip->cs_change_per_word = chip_info->cs_change_per_word; chip->cs_chg_udelay = chip_info->cs_chg_udelay; chip->cs_gpio = chip_info->cs_gpio; chip->idle_tx_val = chip_info->idle_tx_val; @@ -1193,23 +1075,17 @@ static int bfin_spi_setup(struct spi_device *spi) case 8: chip->n_bytes = 1; chip->width = CFG_SPI_WORDSIZE8; - chip->read = chip->cs_change_per_word ? - bfin_spi_u8_cs_chg_reader : bfin_spi_u8_reader; - chip->write = chip->cs_change_per_word ? - bfin_spi_u8_cs_chg_writer : bfin_spi_u8_writer; - chip->duplex = chip->cs_change_per_word ? - bfin_spi_u8_cs_chg_duplex : bfin_spi_u8_duplex; + chip->read = bfin_spi_u8_reader; + chip->write = bfin_spi_u8_writer; + chip->duplex = bfin_spi_u8_duplex; break; case 16: chip->n_bytes = 2; chip->width = CFG_SPI_WORDSIZE16; - chip->read = chip->cs_change_per_word ? - bfin_spi_u16_cs_chg_reader : bfin_spi_u16_reader; - chip->write = chip->cs_change_per_word ? - bfin_spi_u16_cs_chg_writer : bfin_spi_u16_writer; - chip->duplex = chip->cs_change_per_word ? - bfin_spi_u16_cs_chg_duplex : bfin_spi_u16_duplex; + chip->read = bfin_spi_u16_reader; + chip->write = bfin_spi_u16_writer; + chip->duplex = bfin_spi_u16_duplex; break; default: -- cgit v1.2.3-70-g09d2 From 0d2c6de2255cb299fdd77d4543738adee45f4f3f Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Thu, 15 Oct 2009 04:13:29 +0000 Subject: Blackfin: SPI: expand SPI bitmasks Expand the BIT_CTL defines to use the naming convention of the hardware, and expand the masks to cover all documented bits. Signed-off-by: Mike Frysinger --- arch/blackfin/include/asm/bfin5xx_spi.h | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/blackfin/include/asm/bfin5xx_spi.h b/arch/blackfin/include/asm/bfin5xx_spi.h index ee3ecb96aa1..126d25e2afa 100644 --- a/arch/blackfin/include/asm/bfin5xx_spi.h +++ b/arch/blackfin/include/asm/bfin5xx_spi.h @@ -26,11 +26,14 @@ #define BIT_CTL_ENABLE 0x4000 #define BIT_CTL_OPENDRAIN 0x2000 #define BIT_CTL_MASTER 0x1000 -#define BIT_CTL_POLAR 0x0800 -#define BIT_CTL_PHASE 0x0400 -#define BIT_CTL_BITORDER 0x0200 +#define BIT_CTL_CPOL 0x0800 +#define BIT_CTL_CPHA 0x0400 +#define BIT_CTL_LSBF 0x0200 #define BIT_CTL_WORDSIZE 0x0100 -#define BIT_CTL_MISOENABLE 0x0020 +#define BIT_CTL_EMISO 0x0020 +#define BIT_CTL_PSSE 0x0010 +#define BIT_CTL_GM 0x0008 +#define BIT_CTL_SZ 0x0004 #define BIT_CTL_RXMOD 0x0000 #define BIT_CTL_TXMOD 0x0001 #define BIT_CTL_TIMOD_DMA_TX 0x0003 -- cgit v1.2.3-70-g09d2 From d3cc71f71ae13596cb988e16bfa2b15f09fb7347 Mon Sep 17 00:00:00 2001 From: Barry Song Date: Tue, 17 Nov 2009 09:45:59 +0000 Subject: spi/bfin_spi: redo GPIO CS handling The common SPI layers take care of detecting CS conflicts and preventing two devices from claiming the same CS. This causes problems for the GPIO CS support we currently have as we are using CS0 to mean "GPIO CS". But if we have multiple devices using a GPIO CS, the common SPI layers see multiple devices using the virtual "CS0" and reject any such attempts. To make both work, we introduce an offset define. This represents the max number of hardware CS values that the SPI peripheral supports. If the CS is below this limit, we know we can use the hardware CS. If it's above, we treat it as a GPIO CS. This keeps the CS unique as seen by the common code and prevents conflicts. Signed-off-by: Barry Song Signed-off-by: Mike Frysinger --- arch/blackfin/include/asm/bfin5xx_spi.h | 3 ++- drivers/spi/spi_bfin5xx.c | 40 +++++++++++++++++---------------- 2 files changed, 23 insertions(+), 20 deletions(-) (limited to 'arch') diff --git a/arch/blackfin/include/asm/bfin5xx_spi.h b/arch/blackfin/include/asm/bfin5xx_spi.h index 126d25e2afa..6f011dac378 100644 --- a/arch/blackfin/include/asm/bfin5xx_spi.h +++ b/arch/blackfin/include/asm/bfin5xx_spi.h @@ -109,6 +109,8 @@ #define CMD_SPI_GET_SYSTEMCLOCK 25 #define CMD_SPI_SET_WRITECONTINUOUS 26 +#define MAX_CTRL_CS 8 /* cs in spi controller */ + /* device.platform_data for SSP controller devices */ struct bfin5xx_spi_master { u16 num_chipselect; @@ -124,7 +126,6 @@ struct bfin5xx_spi_chip { u8 enable_dma; u8 bits_per_word; u16 cs_chg_udelay; /* Some devices require 16-bit delays */ - u32 cs_gpio; /* Value to send if no TX value is supplied, usually 0x0 or 0xFFFF */ u16 idle_tx_val; u8 pio_interrupt; /* Enable spi data irq */ diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c index 07044d7db9a..278fe0a612c 100644 --- a/drivers/spi/spi_bfin5xx.c +++ b/drivers/spi/spi_bfin5xx.c @@ -183,7 +183,7 @@ static int bfin_spi_flush(struct master_data *drv_data) /* Chip select operation functions for cs_change flag */ static void bfin_spi_cs_active(struct master_data *drv_data, struct slave_data *chip) { - if (likely(chip->chip_select_num)) { + if (likely(chip->chip_select_num < MAX_CTRL_CS)) { u16 flag = read_FLAG(drv_data); flag &= ~chip->flag; @@ -196,7 +196,7 @@ static void bfin_spi_cs_active(struct master_data *drv_data, struct slave_data * static void bfin_spi_cs_deactive(struct master_data *drv_data, struct slave_data *chip) { - if (likely(chip->chip_select_num)) { + if (likely(chip->chip_select_num < MAX_CTRL_CS)) { u16 flag = read_FLAG(drv_data); flag |= chip->flag; @@ -214,20 +214,24 @@ static void bfin_spi_cs_deactive(struct master_data *drv_data, struct slave_data /* enable or disable the pin muxed by GPIO and SPI CS to work as SPI CS */ static inline void bfin_spi_cs_enable(struct master_data *drv_data, struct slave_data *chip) { - u16 flag = read_FLAG(drv_data); + if (chip->chip_select_num < MAX_CTRL_CS) { + u16 flag = read_FLAG(drv_data); - flag |= (chip->flag >> 8); + flag |= (chip->flag >> 8); - write_FLAG(drv_data, flag); + write_FLAG(drv_data, flag); + } } static inline void bfin_spi_cs_disable(struct master_data *drv_data, struct slave_data *chip) { - u16 flag = read_FLAG(drv_data); + if (chip->chip_select_num < MAX_CTRL_CS) { + u16 flag = read_FLAG(drv_data); - flag &= ~(chip->flag >> 8); + flag &= ~(chip->flag >> 8); - write_FLAG(drv_data, flag); + write_FLAG(drv_data, flag); + } } /* stop controller and re-config current chip*/ @@ -1016,7 +1020,6 @@ static int bfin_spi_setup(struct spi_device *spi) chip->ctl_reg = chip_info->ctl_reg; chip->bits_per_word = chip_info->bits_per_word; chip->cs_chg_udelay = chip_info->cs_chg_udelay; - chip->cs_gpio = chip_info->cs_gpio; chip->idle_tx_val = chip_info->idle_tx_val; chip->pio_interrupt = chip_info->pio_interrupt; } @@ -1036,8 +1039,11 @@ static int bfin_spi_setup(struct spi_device *spi) * SPI_BAUD, not the real baudrate */ chip->baud = hz_to_spi_baud(spi->max_speed_hz); - chip->flag = (1 << (spi->chip_select)) << 8; chip->chip_select_num = spi->chip_select; + if (chip->chip_select_num < MAX_CTRL_CS) + chip->flag = (1 << spi->chip_select) << 8; + else + chip->cs_gpio = chip->chip_select_num - MAX_CTRL_CS; switch (chip->bits_per_word) { case 8: @@ -1098,7 +1104,7 @@ static int bfin_spi_setup(struct spi_device *spi) disable_irq(drv_data->spi_irq); } - if (chip->chip_select_num == 0) { + if (chip->chip_select_num >= MAX_CTRL_CS) { ret = gpio_request(chip->cs_gpio, spi->modalias); if (ret) { dev_err(&spi->dev, "gpio_request() error\n"); @@ -1115,8 +1121,7 @@ static int bfin_spi_setup(struct spi_device *spi) spi_set_ctldata(spi, chip); dev_dbg(&spi->dev, "chip select number is %d\n", chip->chip_select_num); - if (chip->chip_select_num > 0 && - chip->chip_select_num <= spi->master->num_chipselect) { + if (chip->chip_select_num < MAX_CTRL_CS) { ret = peripheral_request(ssel[spi->master->bus_num] [chip->chip_select_num-1], spi->modalias); if (ret) { @@ -1131,7 +1136,7 @@ static int bfin_spi_setup(struct spi_device *spi) return 0; pin_error: - if (chip->chip_select_num == 0) + if (chip->chip_select_num >= MAX_CTRL_CS) gpio_free(chip->cs_gpio); else peripheral_free(ssel[spi->master->bus_num] @@ -1162,14 +1167,11 @@ static void bfin_spi_cleanup(struct spi_device *spi) if (!chip) return; - if ((chip->chip_select_num > 0) - && (chip->chip_select_num <= spi->master->num_chipselect)) { + if (chip->chip_select_num < MAX_CTRL_CS) { peripheral_free(ssel[spi->master->bus_num] [chip->chip_select_num-1]); bfin_spi_cs_disable(drv_data, chip); - } - - if (chip->chip_select_num == 0) + } else gpio_free(chip->cs_gpio); kfree(chip); -- cgit v1.2.3-70-g09d2 From 5e8592dca303fb429d1641c205fe509f4b781ca2 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Fri, 18 Dec 2009 18:00:10 +0000 Subject: spi/bfin_spi: combine duplicate SPI_CTL read/write logic While combining things, also switch to the proper SPI bit define names. This lets us punt the rarely used SPI defines. Signed-off-by: Mike Frysinger --- arch/blackfin/include/asm/bfin5xx_spi.h | 68 --------------------------------- drivers/spi/spi_bfin5xx.c | 40 +++++++++---------- 2 files changed, 18 insertions(+), 90 deletions(-) (limited to 'arch') diff --git a/arch/blackfin/include/asm/bfin5xx_spi.h b/arch/blackfin/include/asm/bfin5xx_spi.h index 6f011dac378..4223cf08ce8 100644 --- a/arch/blackfin/include/asm/bfin5xx_spi.h +++ b/arch/blackfin/include/asm/bfin5xx_spi.h @@ -11,18 +11,6 @@ #define MIN_SPI_BAUD_VAL 2 -#define SPI_READ 0 -#define SPI_WRITE 1 - -#define SPI_CTRL_OFF 0x0 -#define SPI_FLAG_OFF 0x4 -#define SPI_STAT_OFF 0x8 -#define SPI_TXBUFF_OFF 0xc -#define SPI_RXBUFF_OFF 0x10 -#define SPI_BAUD_OFF 0x14 -#define SPI_SHAW_OFF 0x18 - - #define BIT_CTL_ENABLE 0x4000 #define BIT_CTL_OPENDRAIN 0x2000 #define BIT_CTL_MASTER 0x1000 @@ -53,62 +41,6 @@ #define BIT_STU_SENDOVER 0x0001 #define BIT_STU_RECVFULL 0x0020 -#define CFG_SPI_ENABLE 1 -#define CFG_SPI_DISABLE 0 - -#define CFG_SPI_OUTENABLE 1 -#define CFG_SPI_OUTDISABLE 0 - -#define CFG_SPI_ACTLOW 1 -#define CFG_SPI_ACTHIGH 0 - -#define CFG_SPI_PHASESTART 1 -#define CFG_SPI_PHASEMID 0 - -#define CFG_SPI_MASTER 1 -#define CFG_SPI_SLAVE 0 - -#define CFG_SPI_SENELAST 0 -#define CFG_SPI_SENDZERO 1 - -#define CFG_SPI_RCVFLUSH 1 -#define CFG_SPI_RCVDISCARD 0 - -#define CFG_SPI_LSBFIRST 1 -#define CFG_SPI_MSBFIRST 0 - -#define CFG_SPI_WORDSIZE16 1 -#define CFG_SPI_WORDSIZE8 0 - -#define CFG_SPI_MISOENABLE 1 -#define CFG_SPI_MISODISABLE 0 - -#define CFG_SPI_READ 0x00 -#define CFG_SPI_WRITE 0x01 -#define CFG_SPI_DMAREAD 0x02 -#define CFG_SPI_DMAWRITE 0x03 - -#define CFG_SPI_CSCLEARALL 0 -#define CFG_SPI_CHIPSEL1 1 -#define CFG_SPI_CHIPSEL2 2 -#define CFG_SPI_CHIPSEL3 3 -#define CFG_SPI_CHIPSEL4 4 -#define CFG_SPI_CHIPSEL5 5 -#define CFG_SPI_CHIPSEL6 6 -#define CFG_SPI_CHIPSEL7 7 - -#define CFG_SPI_CS1VALUE 1 -#define CFG_SPI_CS2VALUE 2 -#define CFG_SPI_CS3VALUE 3 -#define CFG_SPI_CS4VALUE 4 -#define CFG_SPI_CS5VALUE 5 -#define CFG_SPI_CS6VALUE 6 -#define CFG_SPI_CS7VALUE 7 - -#define CMD_SPI_SET_BAUDRATE 2 -#define CMD_SPI_GET_SYSTEMCLOCK 25 -#define CMD_SPI_SET_WRITECONTINUOUS 26 - #define MAX_CTRL_CS 8 /* cs in spi controller */ /* device.platform_data for SSP controller devices */ diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c index 376f2f09e34..b3450b78cc5 100644 --- a/drivers/spi/spi_bfin5xx.c +++ b/drivers/spi/spi_bfin5xx.c @@ -560,8 +560,7 @@ static void bfin_spi_pump_transfers(unsigned long data) struct spi_transfer *previous = NULL; struct slave_data *chip = NULL; unsigned int bits_per_word; - u8 width; - u16 cr, dma_width, dma_config; + u16 cr, cr_width, dma_width, dma_config; u32 tranf_success = 1; u8 full_duplex = 0; @@ -642,22 +641,19 @@ static void bfin_spi_pump_transfers(unsigned long data) bits_per_word = transfer->bits_per_word ? : message->spi->bits_per_word; if (bits_per_word == 8) { drv_data->n_bytes = 1; - width = CFG_SPI_WORDSIZE8; + drv_data->len = transfer->len; + cr_width = 0; drv_data->ops = &bfin_transfer_ops_u8; } else { drv_data->n_bytes = 2; - width = CFG_SPI_WORDSIZE16; + drv_data->len = (transfer->len) >> 1; + cr_width = BIT_CTL_WORDSIZE; drv_data->ops = &bfin_transfer_ops_u16; } - cr = (read_CTRL(drv_data) & (~BIT_CTL_TIMOD)); - cr |= (width << 8); + cr = read_CTRL(drv_data) & ~(BIT_CTL_TIMOD | BIT_CTL_WORDSIZE); + cr |= cr_width; write_CTRL(drv_data, cr); - if (width == CFG_SPI_WORDSIZE16) { - drv_data->len = (transfer->len) >> 1; - } else { - drv_data->len = transfer->len; - } dev_dbg(&drv_data->pdev->dev, "transfer: drv_data->ops is %p, chip->ops is %p, u8_ops is %p\n", drv_data->ops, chip->ops, &bfin_transfer_ops_u8); @@ -672,13 +668,12 @@ static void bfin_spi_pump_transfers(unsigned long data) write_BAUD(drv_data, chip->baud); write_STAT(drv_data, BIT_STAT_CLR); - cr = (read_CTRL(drv_data) & (~BIT_CTL_TIMOD)); if (drv_data->cs_change) bfin_spi_cs_active(drv_data, chip); dev_dbg(&drv_data->pdev->dev, "now pumping a transfer: width is %d, len is %d\n", - width, transfer->len); + cr_width, transfer->len); /* * Try to map dma buffer and do a dma transfer. If successful use, @@ -697,7 +692,7 @@ static void bfin_spi_pump_transfers(unsigned long data) /* config dma channel */ dev_dbg(&drv_data->pdev->dev, "doing dma transfer\n"); set_dma_x_count(drv_data->dma_channel, drv_data->len); - if (width == CFG_SPI_WORDSIZE16) { + if (cr_width == BIT_CTL_WORDSIZE) { set_dma_x_modify(drv_data->dma_channel, 2); dma_width = WDSIZE_16; } else { @@ -786,10 +781,16 @@ static void bfin_spi_pump_transfers(unsigned long data) return; } + /* + * We always use SPI_WRITE mode (transfer starts with TDBR write). + * SPI_READ mode (transfer starts with RDBR read) seems to have + * problems with setting up the output value in TDBR prior to the + * start of the transfer. + */ + write_CTRL(drv_data, cr | BIT_CTL_TXMOD); + if (chip->pio_interrupt) { - /* use write mode. spi irq should have been disabled */ - cr = (read_CTRL(drv_data) & (~BIT_CTL_TIMOD)); - write_CTRL(drv_data, (cr | CFG_SPI_WRITE)); + /* SPI irq should have been disabled by now */ /* discard old RX data and clear RXS */ bfin_spi_dummy_read(drv_data); @@ -813,11 +814,6 @@ static void bfin_spi_pump_transfers(unsigned long data) /* IO mode */ dev_dbg(&drv_data->pdev->dev, "doing IO transfer\n"); - /* we always use SPI_WRITE mode. SPI_READ mode - seems to have problems with setting up the - output value in TDBR prior to the transfer. */ - write_CTRL(drv_data, (cr | CFG_SPI_WRITE)); - if (full_duplex) { /* full duplex mode */ BUG_ON((drv_data->tx_end - drv_data->tx) != -- cgit v1.2.3-70-g09d2