I attached it as as a standalone file. Does anyone have the new AsiaRF module with support for the second chip select? Or any other hardware that supports the second chip select? This code is a mechanical change that just creates a path through the SPI code for passing the CS number around.
This is how to use it in a DTS file spi@b00 { status = "okay"; m25p80@0 { compatible = "mx25l6405d"; linux,modalias = "m25p80", "mx25l6405d"; reg = <0>; spi-max-frequency = <10000000>; }; codec: le89156@1 { compatible = "zarlink,le89156"; reg = <1>; spi-max-frequency = <10000000>; }; }; That commit on git hub was generated with this procedure. http://wiki.openwrt.org/doc/devel/patches -- Jon Smirl jonsm...@gmail.com
--- a/drivers/spi/spi-rt2880.c +++ b/drivers/spi/spi-rt2880.c @@ -27,16 +27,17 @@ #include <ralink_regs.h> #define DRIVER_NAME "spi-rt2880" -/* only one slave is supported*/ -#define RALINK_NUM_CHIPSELECTS 1 /* in usec */ #define RALINK_SPI_WAIT_MAX_LOOP 2000 -#define RAMIPS_SPI_STAT 0x00 -#define RAMIPS_SPI_CFG 0x10 -#define RAMIPS_SPI_CTL 0x14 -#define RAMIPS_SPI_DATA 0x20 -#define RAMIPS_SPI_FIFO_STAT 0x38 +#define RAMIPS_SPI_DEV_OFFSET 0x40 + +#define RAMIPS_SPI_STAT(cs) (0x00 + (cs * RAMIPS_SPI_DEV_OFFSET)) +#define RAMIPS_SPI_CFG(cs) (0x10 + (cs * RAMIPS_SPI_DEV_OFFSET)) +#define RAMIPS_SPI_CTL(cs) (0x14 + (cs * RAMIPS_SPI_DEV_OFFSET)) +#define RAMIPS_SPI_DATA(cs) (0x20 + (cs * RAMIPS_SPI_DEV_OFFSET)) +#define RAMIPS_SPI_FIFO_STAT(cs) (0x38 + (cs * RAMIPS_SPI_DEV_OFFSET)) +#define RAMIPS_SPI_ARBITER 0xF0 /* SPISTAT register bit field */ #define SPISTAT_BUSY BIT(0) @@ -66,6 +67,10 @@ /* SPIFIFOSTAT register bit field */ #define SPIFIFOSTAT_TXFULL BIT(17) +#define SPICTL_ARB_EN BIT(31) +#define SPI1_POR BIT(1) +#define SPI0_POR BIT(0) + #define MT7621_SPI_TRANS 0x00 #define SPITRANS_BUSY BIT(16) #define MT7621_SPI_OPCODE 0x04 @@ -80,9 +85,10 @@ struct rt2880_spi; struct rt2880_spi_ops { void (*init_hw)(struct rt2880_spi *rs); - void (*set_cs)(struct rt2880_spi *rs, int enable); + void (*set_cs)(struct spi_device *spi, int enable); int (*baudrate_set)(struct spi_device *spi, unsigned int speed); unsigned int (*write_read)(struct spi_device *spi, struct list_head *list, struct spi_transfer *xfer); + int num_cs; }; struct rt2880_spi { @@ -139,6 +145,7 @@ static inline void rt2880_spi_clrbits(st static int rt2880_spi_baudrate_set(struct spi_device *spi, unsigned int speed) { + int cs = spi->chip_select; struct rt2880_spi *rs = spidev_to_rt2880_spi(spi); u32 rate; u32 prescale; @@ -166,9 +173,9 @@ static int rt2880_spi_baudrate_set(struc prescale = ilog2(rate / 2); dev_dbg(&spi->dev, "prescale:%u\n", prescale); - reg = rt2880_spi_read(rs, RAMIPS_SPI_CFG); + reg = rt2880_spi_read(rs, RAMIPS_SPI_CFG(cs)); reg = ((reg & ~SPICFG_SPICLK_PRESCALE_MASK) | prescale); - rt2880_spi_write(rs, RAMIPS_SPI_CFG, reg); + rt2880_spi_write(rs, RAMIPS_SPI_CFG(cs), reg); rs->speed = speed; return 0; } @@ -207,16 +214,20 @@ rt2880_spi_setup_transfer(struct spi_dev return 0; } -static void rt2880_spi_set_cs(struct rt2880_spi *rs, int enable) +static void rt2880_spi_set_cs(struct spi_device *spi, int enable) { + struct rt2880_spi *rs = spidev_to_rt2880_spi(spi); + int cs = spi->chip_select; + if (enable) - rt2880_spi_clrbits(rs, RAMIPS_SPI_CTL, SPICTL_SPIENA); + rt2880_spi_clrbits(rs, RAMIPS_SPI_CTL(cs), SPICTL_SPIENA); else - rt2880_spi_setbits(rs, RAMIPS_SPI_CTL, SPICTL_SPIENA); + rt2880_spi_setbits(rs, RAMIPS_SPI_CTL(cs), SPICTL_SPIENA); } -static void mt7621_spi_set_cs(struct rt2880_spi *rs, int enable) +static void mt7621_spi_set_cs(struct spi_device *spi, int enable) { + struct rt2880_spi *rs = spidev_to_rt2880_spi(spi); u32 polar = rt2880_spi_read(rs, MT7621_SPI_POLAR); if (enable) @@ -226,14 +237,16 @@ static void mt7621_spi_set_cs(struct rt2 rt2880_spi_write(rs, MT7621_SPI_POLAR, polar); } -static inline int rt2880_spi_wait_till_ready(struct rt2880_spi *rs) +static inline int rt2880_spi_wait_till_ready(struct spi_device *spi) { + struct rt2880_spi *rs = spidev_to_rt2880_spi(spi); + int cs = spi->chip_select; int i; for (i = 0; i < RALINK_SPI_WAIT_MAX_LOOP; i++) { u32 status; - status = rt2880_spi_read(rs, RAMIPS_SPI_STAT); + status = rt2880_spi_read(rs, RAMIPS_SPI_STAT(cs)); if ((status & SPISTAT_BUSY) == 0) return 0; @@ -244,8 +257,9 @@ static inline int rt2880_spi_wait_till_r return -ETIMEDOUT; } -static inline int mt7621_spi_wait_till_ready(struct rt2880_spi *rs) +static inline int mt7621_spi_wait_till_ready(struct spi_device *spi) { + struct rt2880_spi *rs = spidev_to_rt2880_spi(spi); int i; for (i = 0; i < RALINK_SPI_WAIT_MAX_LOOP; i++) { @@ -266,6 +280,7 @@ static unsigned int rt2880_spi_write_read(struct spi_device *spi, struct list_head *list, struct spi_transfer *xfer) { struct rt2880_spi *rs = spidev_to_rt2880_spi(spi); + int cs = spi->chip_select; unsigned count = 0; u8 *rx = xfer->rx_buf; const u8 *tx = xfer->tx_buf; @@ -277,9 +292,9 @@ rt2880_spi_write_read(struct spi_device if (tx) { for (count = 0; count < xfer->len; count++) { - rt2880_spi_write(rs, RAMIPS_SPI_DATA, tx[count]); - rt2880_spi_setbits(rs, RAMIPS_SPI_CTL, SPICTL_STARTWR); - err = rt2880_spi_wait_till_ready(rs); + rt2880_spi_write(rs, RAMIPS_SPI_DATA(cs), tx[count]); + rt2880_spi_setbits(rs, RAMIPS_SPI_CTL(cs), SPICTL_STARTWR); + err = rt2880_spi_wait_till_ready(spi); if (err) { dev_err(&spi->dev, "TX failed, err=%d\n", err); goto out; @@ -289,13 +304,13 @@ rt2880_spi_write_read(struct spi_device if (rx) { for (count = 0; count < xfer->len; count++) { - rt2880_spi_setbits(rs, RAMIPS_SPI_CTL, SPICTL_STARTRD); - err = rt2880_spi_wait_till_ready(rs); + rt2880_spi_setbits(rs, RAMIPS_SPI_CTL(cs), SPICTL_STARTRD); + err = rt2880_spi_wait_till_ready(spi); if (err) { dev_err(&spi->dev, "RX failed, err=%d\n", err); goto out; } - rx[count] = (u8) rt2880_spi_read(rs, RAMIPS_SPI_DATA); + rx[count] = (u8) rt2880_spi_read(rs, RAMIPS_SPI_DATA(cs)); } } @@ -362,7 +377,7 @@ mt7621_spi_write_read(struct spi_device trans |= SPI_CTL_START; rt2880_spi_write(rs, MT7621_SPI_TRANS, trans); - mt7621_spi_wait_till_ready(rs); + mt7621_spi_wait_till_ready(spi); if (rx) { u32 data0 = rt2880_spi_read(rs, MT7621_SPI_DATA0); @@ -438,7 +453,7 @@ static int rt2880_spi_transfer_one_messa } if (!cs_active) { - rs->ops->set_cs(rs, 1); + rs->ops->set_cs(spi, 1); cs_active = 1; } @@ -449,14 +464,14 @@ static int rt2880_spi_transfer_one_messa udelay(t->delay_usecs); if (t->cs_change) { - rs->ops->set_cs(rs, 0); + rs->ops->set_cs(spi, 0); cs_active = 0; } } msg_done: if (cs_active) - rs->ops->set_cs(rs, 0); + rs->ops->set_cs(spi, 0); m->status = status; spi_finalize_current_message(master); @@ -486,10 +501,25 @@ static int rt2880_spi_setup(struct spi_d static void rt2880_spi_reset(struct rt2880_spi *rs) { - rt2880_spi_write(rs, RAMIPS_SPI_CFG, + rt2880_spi_write(rs, RAMIPS_SPI_CFG(0), SPICFG_MSBFIRST | SPICFG_TXCLKEDGE_FALLING | SPICFG_SPICLK_DIV16 | SPICFG_SPICLKPOL); - rt2880_spi_write(rs, RAMIPS_SPI_CTL, SPICTL_HIZSDO | SPICTL_SPIENA); + rt2880_spi_write(rs, RAMIPS_SPI_CTL(0), SPICTL_HIZSDO | SPICTL_SPIENA); +} + +static void rt5350_spi_reset(struct rt2880_spi *rs) +{ + int cs; + + rt2880_spi_write(rs, RAMIPS_SPI_ARBITER, + SPICTL_ARB_EN | SPI1_POR | SPI0_POR); + + for (cs = 0; cs < rs->ops->num_cs; cs++) { + rt2880_spi_write(rs, RAMIPS_SPI_CFG(cs), + SPICFG_MSBFIRST | SPICFG_TXCLKEDGE_FALLING | + SPICFG_SPICLK_DIV16 | SPICFG_SPICLKPOL); + rt2880_spi_write(rs, RAMIPS_SPI_CTL(cs), SPICTL_HIZSDO | SPICTL_SPIENA); + } } static void mt7621_spi_reset(struct rt2880_spi *rs) @@ -509,17 +539,26 @@ static struct rt2880_spi_ops spi_ops[] = .set_cs = rt2880_spi_set_cs, .baudrate_set = rt2880_spi_baudrate_set, .write_read = rt2880_spi_write_read, + .num_cs = 1, + }, { + .init_hw = rt5350_spi_reset, + .set_cs = rt2880_spi_set_cs, + .baudrate_set = rt2880_spi_baudrate_set, + .write_read = rt2880_spi_write_read, + .num_cs = 2, }, { .init_hw = mt7621_spi_reset, .set_cs = mt7621_spi_set_cs, .baudrate_set = mt7621_spi_baudrate_set, .write_read = mt7621_spi_write_read, + .num_cs = 1, }, }; static const struct of_device_id rt2880_spi_match[] = { { .compatible = "ralink,rt2880-spi", .data = &spi_ops[0]}, - { .compatible = "ralink,mt7621-spi", .data = &spi_ops[1] }, + { .compatible = "ralink,rt5350-spi", .data = &spi_ops[1]}, + { .compatible = "ralink,mt7621-spi", .data = &spi_ops[2] }, {}, }; MODULE_DEVICE_TABLE(of, rt2880_spi_match); @@ -534,10 +573,12 @@ static int rt2880_spi_probe(struct platf struct resource *r; int status = 0; struct clk *clk; + struct rt2880_spi_ops *ops; match = of_match_device(rt2880_spi_match, &pdev->dev); if (!match) return -EINVAL; + ops = (struct rt2880_spi_ops *)match->data; r = platform_get_resource(pdev, IORESOURCE_MEM, 0); base = devm_ioremap_resource(&pdev->dev, r); @@ -566,9 +607,9 @@ static int rt2880_spi_probe(struct platf master->setup = rt2880_spi_setup; master->transfer_one_message = rt2880_spi_transfer_one_message; - master->num_chipselect = RALINK_NUM_CHIPSELECTS; master->bits_per_word_mask = SPI_BPW_MASK(8); master->dev.of_node = pdev->dev.of_node; + master->num_chipselect = ops->num_cs; dev_set_drvdata(&pdev->dev, master); @@ -577,7 +618,7 @@ static int rt2880_spi_probe(struct platf rs->clk = clk; rs->master = master; rs->sys_freq = clk_get_rate(rs->clk); - rs->ops = (struct rt2880_spi_ops *) match->data; + rs->ops = ops; dev_dbg(&pdev->dev, "sys_freq: %u\n", rs->sys_freq); spin_lock_irqsave(&rs->lock, flags);
_______________________________________________ openwrt-devel mailing list openwrt-devel@lists.openwrt.org https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel