Commit 2a8626a9e2d86d114a2d9f813a1acebf9d53dd10

Authored by Sebastian Andrzej Siewior
1 parent d0777f2c3e

spi/pxa2xx: Add chipselect support for Sodaville

The SPI core on Sodaville supports chip selects. Its configuration
moved into the SSSR register at bit 0 and 1. Thus Sodaville can be hooked
up with up to 4 devices.
This patch ensures that the bits which are otherwiese reserved are only
touched on Sodaville and not on any other PXAs. Also it makes sure that
the status register does not lose the CS information while clearing the
ROR bit.

Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Dirk Brandewie <dirk.brandewie@gmail.com>

Showing 2 changed files with 70 additions and 25 deletions Side-by-side Diff

drivers/spi/pxa2xx_spi.c
... ... @@ -163,7 +163,10 @@
163 163 u8 enable_dma;
164 164 u8 bits_per_word;
165 165 u32 speed_hz;
166   - int gpio_cs;
  166 + union {
  167 + int gpio_cs;
  168 + unsigned int frm;
  169 + };
167 170 int gpio_cs_inverted;
168 171 int (*write)(struct driver_data *drv_data);
169 172 int (*read)(struct driver_data *drv_data);
... ... @@ -176,6 +179,11 @@
176 179 {
177 180 struct chip_data *chip = drv_data->cur_chip;
178 181  
  182 + if (drv_data->ssp_type == CE4100_SSP) {
  183 + write_SSSR(drv_data->cur_chip->frm, drv_data->ioaddr);
  184 + return;
  185 + }
  186 +
179 187 if (chip->cs_control) {
180 188 chip->cs_control(PXA2XX_CS_ASSERT);
181 189 return;
... ... @@ -189,6 +197,9 @@
189 197 {
190 198 struct chip_data *chip = drv_data->cur_chip;
191 199  
  200 + if (drv_data->ssp_type == CE4100_SSP)
  201 + return;
  202 +
192 203 if (chip->cs_control) {
193 204 chip->cs_control(PXA2XX_CS_DEASSERT);
194 205 return;
... ... @@ -198,6 +209,25 @@
198 209 gpio_set_value(chip->gpio_cs, !chip->gpio_cs_inverted);
199 210 }
200 211  
  212 +static void write_SSSR_CS(struct driver_data *drv_data, u32 val)
  213 +{
  214 + void __iomem *reg = drv_data->ioaddr;
  215 +
  216 + if (drv_data->ssp_type == CE4100_SSP)
  217 + val |= read_SSSR(reg) & SSSR_ALT_FRM_MASK;
  218 +
  219 + write_SSSR(val, reg);
  220 +}
  221 +
  222 +static int pxa25x_ssp_comp(struct driver_data *drv_data)
  223 +{
  224 + if (drv_data->ssp_type == PXA25x_SSP)
  225 + return 1;
  226 + if (drv_data->ssp_type == CE4100_SSP)
  227 + return 1;
  228 + return 0;
  229 +}
  230 +
201 231 static int flush(struct driver_data *drv_data)
202 232 {
203 233 unsigned long limit = loops_per_jiffy << 1;
... ... @@ -209,7 +239,7 @@
209 239 read_SSDR(reg);
210 240 }
211 241 } while ((read_SSSR(reg) & SSSR_BSY) && --limit);
212   - write_SSSR(SSSR_ROR, reg);
  242 + write_SSSR_CS(drv_data, SSSR_ROR);
213 243  
214 244 return limit;
215 245 }
216 246  
... ... @@ -502,9 +532,9 @@
502 532 /* Stop and reset */
503 533 DCSR(drv_data->rx_channel) = RESET_DMA_CHANNEL;
504 534 DCSR(drv_data->tx_channel) = RESET_DMA_CHANNEL;
505   - write_SSSR(drv_data->clear_sr, reg);
  535 + write_SSSR_CS(drv_data, drv_data->clear_sr);
506 536 write_SSCR1(read_SSCR1(reg) & ~drv_data->dma_cr1, reg);
507   - if (drv_data->ssp_type != PXA25x_SSP)
  537 + if (!pxa25x_ssp_comp(drv_data))
508 538 write_SSTO(0, reg);
509 539 flush(drv_data);
510 540 write_SSCR0(read_SSCR0(reg) & ~SSCR0_SSE, reg);
... ... @@ -524,7 +554,7 @@
524 554  
525 555 /* Clear and disable interrupts on SSP and DMA channels*/
526 556 write_SSCR1(read_SSCR1(reg) & ~drv_data->dma_cr1, reg);
527   - write_SSSR(drv_data->clear_sr, reg);
  557 + write_SSSR_CS(drv_data, drv_data->clear_sr);
528 558 DCSR(drv_data->tx_channel) = RESET_DMA_CHANNEL;
529 559 DCSR(drv_data->rx_channel) = RESET_DMA_CHANNEL;
530 560  
... ... @@ -617,7 +647,7 @@
617 647  
618 648 /* Clear and disable timeout interrupt, do the rest in
619 649 * dma_transfer_complete */
620   - if (drv_data->ssp_type != PXA25x_SSP)
  650 + if (!pxa25x_ssp_comp(drv_data))
621 651 write_SSTO(0, reg);
622 652  
623 653 /* finish this transfer, start the next */
624 654  
... ... @@ -635,9 +665,9 @@
635 665 void __iomem *reg = drv_data->ioaddr;
636 666  
637 667 /* Stop and reset SSP */
638   - write_SSSR(drv_data->clear_sr, reg);
  668 + write_SSSR_CS(drv_data, drv_data->clear_sr);
639 669 write_SSCR1(read_SSCR1(reg) & ~drv_data->int_cr1, reg);
640   - if (drv_data->ssp_type != PXA25x_SSP)
  670 + if (!pxa25x_ssp_comp(drv_data))
641 671 write_SSTO(0, reg);
642 672 flush(drv_data);
643 673 write_SSCR0(read_SSCR0(reg) & ~SSCR0_SSE, reg);
644 674  
... ... @@ -653,9 +683,9 @@
653 683 void __iomem *reg = drv_data->ioaddr;
654 684  
655 685 /* Stop SSP */
656   - write_SSSR(drv_data->clear_sr, reg);
  686 + write_SSSR_CS(drv_data, drv_data->clear_sr);
657 687 write_SSCR1(read_SSCR1(reg) & ~drv_data->int_cr1, reg);
658   - if (drv_data->ssp_type != PXA25x_SSP)
  688 + if (!pxa25x_ssp_comp(drv_data))
659 689 write_SSTO(0, reg);
660 690  
661 691 /* Update total byte transfered return count actual bytes read */
... ... @@ -711,7 +741,7 @@
711 741 if (drv_data->tx == drv_data->tx_end) {
712 742 write_SSCR1(read_SSCR1(reg) & ~SSCR1_TIE, reg);
713 743 /* PXA25x_SSP has no timeout, read trailing bytes */
714   - if (drv_data->ssp_type == PXA25x_SSP) {
  744 + if (pxa25x_ssp_comp(drv_data)) {
715 745 if (!wait_ssp_rx_stall(reg))
716 746 {
717 747 int_error_stop(drv_data, "interrupt_transfer: "
718 748  
... ... @@ -754,9 +784,9 @@
754 784  
755 785 write_SSCR0(read_SSCR0(reg) & ~SSCR0_SSE, reg);
756 786 write_SSCR1(read_SSCR1(reg) & ~drv_data->int_cr1, reg);
757   - if (drv_data->ssp_type != PXA25x_SSP)
  787 + if (!pxa25x_ssp_comp(drv_data))
758 788 write_SSTO(0, reg);
759   - write_SSSR(drv_data->clear_sr, reg);
  789 + write_SSSR_CS(drv_data, drv_data->clear_sr);
760 790  
761 791 dev_err(&drv_data->pdev->dev, "bad message state "
762 792 "in interrupt handler\n");
... ... @@ -869,7 +899,7 @@
869 899 {
870 900 unsigned long ssp_clk = clk_get_rate(ssp->clk);
871 901  
872   - if (ssp->type == PXA25x_SSP)
  902 + if (ssp->type == PXA25x_SSP || ssp->type == CE4100_SSP)
873 903 return ((ssp_clk / (2 * rate) - 1) & 0xff) << 8;
874 904 else
875 905 return ((ssp_clk / rate - 1) & 0xfff) << 8;
... ... @@ -1095,7 +1125,7 @@
1095 1125  
1096 1126 /* Clear status */
1097 1127 cr1 = chip->cr1 | chip->threshold | drv_data->int_cr1;
1098   - write_SSSR(drv_data->clear_sr, reg);
  1128 + write_SSSR_CS(drv_data, drv_data->clear_sr);
1099 1129 }
1100 1130  
1101 1131 /* see if we need to reload the config registers */
... ... @@ -1105,7 +1135,7 @@
1105 1135  
1106 1136 /* stop the SSP, and update the other bits */
1107 1137 write_SSCR0(cr0 & ~SSCR0_SSE, reg);
1108   - if (drv_data->ssp_type != PXA25x_SSP)
  1138 + if (!pxa25x_ssp_comp(drv_data))
1109 1139 write_SSTO(chip->timeout, reg);
1110 1140 /* first set CR1 without interrupt and service enables */
1111 1141 write_SSCR1(cr1 & SSCR1_CHANGE_MASK, reg);
... ... @@ -1113,7 +1143,7 @@
1113 1143 write_SSCR0(cr0, reg);
1114 1144  
1115 1145 } else {
1116   - if (drv_data->ssp_type != PXA25x_SSP)
  1146 + if (!pxa25x_ssp_comp(drv_data))
1117 1147 write_SSTO(chip->timeout, reg);
1118 1148 }
1119 1149  
1120 1150  
... ... @@ -1240,14 +1270,13 @@
1240 1270 uint tx_thres = TX_THRESH_DFLT;
1241 1271 uint rx_thres = RX_THRESH_DFLT;
1242 1272  
1243   - if (drv_data->ssp_type != PXA25x_SSP
  1273 + if (!pxa25x_ssp_comp(drv_data)
1244 1274 && (spi->bits_per_word < 4 || spi->bits_per_word > 32)) {
1245 1275 dev_err(&spi->dev, "failed setup: ssp_type=%d, bits/wrd=%d "
1246 1276 "b/w not 4-32 for type non-PXA25x_SSP\n",
1247 1277 drv_data->ssp_type, spi->bits_per_word);
1248 1278 return -EINVAL;
1249   - }
1250   - else if (drv_data->ssp_type == PXA25x_SSP
  1279 + } else if (pxa25x_ssp_comp(drv_data)
1251 1280 && (spi->bits_per_word < 4
1252 1281 || spi->bits_per_word > 16)) {
1253 1282 dev_err(&spi->dev, "failed setup: ssp_type=%d, bits/wrd=%d "
... ... @@ -1266,7 +1295,17 @@
1266 1295 return -ENOMEM;
1267 1296 }
1268 1297  
1269   - chip->gpio_cs = -1;
  1298 + if (drv_data->ssp_type == CE4100_SSP) {
  1299 + if (spi->chip_select > 4) {
  1300 + dev_err(&spi->dev, "failed setup: "
  1301 + "cs number must not be > 4.\n");
  1302 + kfree(chip);
  1303 + return -EINVAL;
  1304 + }
  1305 +
  1306 + chip->frm = spi->chip_select;
  1307 + } else
  1308 + chip->gpio_cs = -1;
1270 1309 chip->enable_dma = 0;
1271 1310 chip->timeout = TIMOUT_DFLT;
1272 1311 chip->dma_burst_size = drv_data->master_info->enable_dma ?
... ... @@ -1322,7 +1361,7 @@
1322 1361 | (((spi->mode & SPI_CPOL) != 0) ? SSCR1_SPO : 0);
1323 1362  
1324 1363 /* NOTE: PXA25x_SSP _could_ use external clocking ... */
1325   - if (drv_data->ssp_type != PXA25x_SSP)
  1364 + if (!pxa25x_ssp_comp(drv_data))
1326 1365 dev_dbg(&spi->dev, "%ld Hz actual, %s\n",
1327 1366 clk_get_rate(ssp->clk)
1328 1367 / (1 + ((chip->cr0 & SSCR0_SCR(0xfff)) >> 8)),
1329 1368  
1330 1369  
... ... @@ -1357,17 +1396,21 @@
1357 1396  
1358 1397 spi_set_ctldata(spi, chip);
1359 1398  
  1399 + if (drv_data->ssp_type == CE4100_SSP)
  1400 + return 0;
  1401 +
1360 1402 return setup_cs(spi, chip, chip_info);
1361 1403 }
1362 1404  
1363 1405 static void cleanup(struct spi_device *spi)
1364 1406 {
1365 1407 struct chip_data *chip = spi_get_ctldata(spi);
  1408 + struct driver_data *drv_data = spi_master_get_devdata(spi->master);
1366 1409  
1367 1410 if (!chip)
1368 1411 return;
1369 1412  
1370   - if (gpio_is_valid(chip->gpio_cs))
  1413 + if (drv_data->ssp_type != CE4100_SSP && gpio_is_valid(chip->gpio_cs))
1371 1414 gpio_free(chip->gpio_cs);
1372 1415  
1373 1416 kfree(chip);
... ... @@ -1507,7 +1550,7 @@
1507 1550  
1508 1551 drv_data->ioaddr = ssp->mmio_base;
1509 1552 drv_data->ssdr_physical = ssp->phys_base + SSDR;
1510   - if (ssp->type == PXA25x_SSP) {
  1553 + if (pxa25x_ssp_comp(drv_data)) {
1511 1554 drv_data->int_cr1 = SSCR1_TIE | SSCR1_RIE;
1512 1555 drv_data->dma_cr1 = 0;
1513 1556 drv_data->clear_sr = SSSR_ROR;
... ... @@ -1569,7 +1612,7 @@
1569 1612 | SSCR0_Motorola
1570 1613 | SSCR0_DataSize(8),
1571 1614 drv_data->ioaddr);
1572   - if (drv_data->ssp_type != PXA25x_SSP)
  1615 + if (!pxa25x_ssp_comp(drv_data))
1573 1616 write_SSTO(0, drv_data->ioaddr);
1574 1617 write_SSPSP(0, drv_data->ioaddr);
1575 1618  
include/linux/pxa2xx_ssp.h
... ... @@ -72,6 +72,7 @@
72 72 #define SSCR1_SPH (1 << 4) /* Motorola SPI SSPSCLK phase setting */
73 73 #define SSCR1_MWDS (1 << 5) /* Microwire Transmit Data Size */
74 74  
  75 +#define SSSR_ALT_FRM_MASK 3 /* Masks the SFRM signal number */
75 76 #define SSSR_TNF (1 << 2) /* Transmit FIFO Not Full */
76 77 #define SSSR_RNE (1 << 3) /* Receive FIFO Not Empty */
77 78 #define SSSR_BSY (1 << 4) /* SSP Busy */
... ... @@ -160,6 +161,7 @@
160 161 PXA25x_NSSP, /* pxa 255, 26x (including ASSP) */
161 162 PXA27x_SSP,
162 163 PXA168_SSP,
  164 + CE4100_SSP,
163 165 };
164 166  
165 167 struct ssp_device {