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

Reply via email to