Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 212301
b: refs/heads/master
c: bde435a
h: refs/heads/master
i:
  212299: 4cb3c74
v: v3
  • Loading branch information
Kevin Wells authored and Grant Likely committed Oct 13, 2010
1 parent ebbc7e2 commit 99dd6e5
Show file tree
Hide file tree
Showing 8 changed files with 64 additions and 100 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: fadcf49b9bd7ec5fb69befbf477e747d5b6a0328
refs/heads/master: bde435a9ca376d0b7809768ca803dbf14416b9c1
7 changes: 1 addition & 6 deletions trunk/arch/arm/mach-lpc32xx/phy3250.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
},
Expand Down
5 changes: 2 additions & 3 deletions trunk/arch/arm/mach-u300/dummyspichip.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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);

Expand Down Expand Up @@ -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);

Expand Down
10 changes: 1 addition & 9 deletions trunk/arch/arm/mach-u300/spi.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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,
Expand All @@ -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
};
Expand Down
8 changes: 1 addition & 7 deletions trunk/arch/arm/mach-ux500/board-mop500.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};

Expand All @@ -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,
},
};
Expand Down
5 changes: 5 additions & 0 deletions trunk/drivers/mfd/ab8500-spi.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
121 changes: 53 additions & 68 deletions trunk/drivers/spi/amba-pl022.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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)) {
Expand All @@ -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)) {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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;
}
}
Expand Down Expand Up @@ -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,
Expand All @@ -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);
Expand All @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
6 changes: 0 additions & 6 deletions trunk/include/linux/amba/pl022.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 99dd6e5

Please sign in to comment.