11ea29b39SMartin Sperl /* 21ea29b39SMartin Sperl * Driver for Broadcom BCM2835 auxiliary SPI Controllers 31ea29b39SMartin Sperl * 41ea29b39SMartin Sperl * the driver does not rely on the native chipselects at all 51ea29b39SMartin Sperl * but only uses the gpio type chipselects 61ea29b39SMartin Sperl * 71ea29b39SMartin Sperl * Based on: spi-bcm2835.c 81ea29b39SMartin Sperl * 91ea29b39SMartin Sperl * Copyright (C) 2015 Martin Sperl 101ea29b39SMartin Sperl * 111ea29b39SMartin Sperl * This program is free software; you can redistribute it and/or modify 121ea29b39SMartin Sperl * it under the terms of the GNU General Public License as published by 131ea29b39SMartin Sperl * the Free Software Foundation; either version 2 of the License, or 141ea29b39SMartin Sperl * (at your option) any later version. 151ea29b39SMartin Sperl * 161ea29b39SMartin Sperl * This program is distributed in the hope that it will be useful, 171ea29b39SMartin Sperl * but WITHOUT ANY WARRANTY; without even the implied warranty of 181ea29b39SMartin Sperl * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 191ea29b39SMartin Sperl * GNU General Public License for more details. 201ea29b39SMartin Sperl */ 211ea29b39SMartin Sperl 221ea29b39SMartin Sperl #include <linux/clk.h> 231ea29b39SMartin Sperl #include <linux/completion.h> 241ea29b39SMartin Sperl #include <linux/delay.h> 251ea29b39SMartin Sperl #include <linux/err.h> 261ea29b39SMartin Sperl #include <linux/interrupt.h> 271ea29b39SMartin Sperl #include <linux/io.h> 281ea29b39SMartin Sperl #include <linux/kernel.h> 291ea29b39SMartin Sperl #include <linux/module.h> 301ea29b39SMartin Sperl #include <linux/of.h> 311ea29b39SMartin Sperl #include <linux/of_address.h> 321ea29b39SMartin Sperl #include <linux/of_device.h> 331ea29b39SMartin Sperl #include <linux/of_gpio.h> 341ea29b39SMartin Sperl #include <linux/of_irq.h> 351ea29b39SMartin Sperl #include <linux/regmap.h> 361ea29b39SMartin Sperl #include <linux/spi/spi.h> 371ea29b39SMartin Sperl #include <linux/spinlock.h> 381ea29b39SMartin Sperl 391ea29b39SMartin Sperl /* 401ea29b39SMartin Sperl * spi register defines 411ea29b39SMartin Sperl * 421ea29b39SMartin Sperl * note there is garbage in the "official" documentation, 431ea29b39SMartin Sperl * so some data is taken from the file: 441ea29b39SMartin Sperl * brcm_usrlib/dag/vmcsx/vcinclude/bcm2708_chip/aux_io.h 451ea29b39SMartin Sperl * inside of: 461ea29b39SMartin Sperl * http://www.broadcom.com/docs/support/videocore/Brcm_Android_ICS_Graphics_Stack.tar.gz 471ea29b39SMartin Sperl */ 481ea29b39SMartin Sperl 491ea29b39SMartin Sperl /* SPI register offsets */ 501ea29b39SMartin Sperl #define BCM2835_AUX_SPI_CNTL0 0x00 511ea29b39SMartin Sperl #define BCM2835_AUX_SPI_CNTL1 0x04 521ea29b39SMartin Sperl #define BCM2835_AUX_SPI_STAT 0x08 531ea29b39SMartin Sperl #define BCM2835_AUX_SPI_PEEK 0x0C 541ea29b39SMartin Sperl #define BCM2835_AUX_SPI_IO 0x20 551ea29b39SMartin Sperl #define BCM2835_AUX_SPI_TXHOLD 0x30 561ea29b39SMartin Sperl 571ea29b39SMartin Sperl /* Bitfields in CNTL0 */ 581ea29b39SMartin Sperl #define BCM2835_AUX_SPI_CNTL0_SPEED 0xFFF00000 591ea29b39SMartin Sperl #define BCM2835_AUX_SPI_CNTL0_SPEED_MAX 0xFFF 601ea29b39SMartin Sperl #define BCM2835_AUX_SPI_CNTL0_SPEED_SHIFT 20 611ea29b39SMartin Sperl #define BCM2835_AUX_SPI_CNTL0_CS 0x000E0000 621ea29b39SMartin Sperl #define BCM2835_AUX_SPI_CNTL0_POSTINPUT 0x00010000 631ea29b39SMartin Sperl #define BCM2835_AUX_SPI_CNTL0_VAR_CS 0x00008000 641ea29b39SMartin Sperl #define BCM2835_AUX_SPI_CNTL0_VAR_WIDTH 0x00004000 651ea29b39SMartin Sperl #define BCM2835_AUX_SPI_CNTL0_DOUTHOLD 0x00003000 661ea29b39SMartin Sperl #define BCM2835_AUX_SPI_CNTL0_ENABLE 0x00000800 67e9dd4edcSStephan Olbrich #define BCM2835_AUX_SPI_CNTL0_IN_RISING 0x00000400 681ea29b39SMartin Sperl #define BCM2835_AUX_SPI_CNTL0_CLEARFIFO 0x00000200 69e9dd4edcSStephan Olbrich #define BCM2835_AUX_SPI_CNTL0_OUT_RISING 0x00000100 701ea29b39SMartin Sperl #define BCM2835_AUX_SPI_CNTL0_CPOL 0x00000080 711ea29b39SMartin Sperl #define BCM2835_AUX_SPI_CNTL0_MSBF_OUT 0x00000040 721ea29b39SMartin Sperl #define BCM2835_AUX_SPI_CNTL0_SHIFTLEN 0x0000003F 731ea29b39SMartin Sperl 741ea29b39SMartin Sperl /* Bitfields in CNTL1 */ 751ea29b39SMartin Sperl #define BCM2835_AUX_SPI_CNTL1_CSHIGH 0x00000700 76fe0e2304SStephan Olbrich #define BCM2835_AUX_SPI_CNTL1_TXEMPTY 0x00000080 77fe0e2304SStephan Olbrich #define BCM2835_AUX_SPI_CNTL1_IDLE 0x00000040 781ea29b39SMartin Sperl #define BCM2835_AUX_SPI_CNTL1_MSBF_IN 0x00000002 791ea29b39SMartin Sperl #define BCM2835_AUX_SPI_CNTL1_KEEP_IN 0x00000001 801ea29b39SMartin Sperl 811ea29b39SMartin Sperl /* Bitfields in STAT */ 821ea29b39SMartin Sperl #define BCM2835_AUX_SPI_STAT_TX_LVL 0xFF000000 831ea29b39SMartin Sperl #define BCM2835_AUX_SPI_STAT_RX_LVL 0x00FF0000 841ea29b39SMartin Sperl #define BCM2835_AUX_SPI_STAT_TX_FULL 0x00000400 851ea29b39SMartin Sperl #define BCM2835_AUX_SPI_STAT_TX_EMPTY 0x00000200 861ea29b39SMartin Sperl #define BCM2835_AUX_SPI_STAT_RX_FULL 0x00000100 871ea29b39SMartin Sperl #define BCM2835_AUX_SPI_STAT_RX_EMPTY 0x00000080 881ea29b39SMartin Sperl #define BCM2835_AUX_SPI_STAT_BUSY 0x00000040 891ea29b39SMartin Sperl #define BCM2835_AUX_SPI_STAT_BITCOUNT 0x0000003F 901ea29b39SMartin Sperl 911ea29b39SMartin Sperl /* timeout values */ 921ea29b39SMartin Sperl #define BCM2835_AUX_SPI_POLLING_LIMIT_US 30 931ea29b39SMartin Sperl #define BCM2835_AUX_SPI_POLLING_JIFFIES 2 941ea29b39SMartin Sperl 951ea29b39SMartin Sperl struct bcm2835aux_spi { 961ea29b39SMartin Sperl void __iomem *regs; 971ea29b39SMartin Sperl struct clk *clk; 981ea29b39SMartin Sperl int irq; 991ea29b39SMartin Sperl u32 cntl[2]; 1001ea29b39SMartin Sperl const u8 *tx_buf; 1011ea29b39SMartin Sperl u8 *rx_buf; 1021ea29b39SMartin Sperl int tx_len; 1031ea29b39SMartin Sperl int rx_len; 10472aac02bSMartin Sperl int pending; 1051ea29b39SMartin Sperl }; 1061ea29b39SMartin Sperl 1071ea29b39SMartin Sperl static inline u32 bcm2835aux_rd(struct bcm2835aux_spi *bs, unsigned reg) 1081ea29b39SMartin Sperl { 1091ea29b39SMartin Sperl return readl(bs->regs + reg); 1101ea29b39SMartin Sperl } 1111ea29b39SMartin Sperl 1121ea29b39SMartin Sperl static inline void bcm2835aux_wr(struct bcm2835aux_spi *bs, unsigned reg, 1131ea29b39SMartin Sperl u32 val) 1141ea29b39SMartin Sperl { 1151ea29b39SMartin Sperl writel(val, bs->regs + reg); 1161ea29b39SMartin Sperl } 1171ea29b39SMartin Sperl 1181ea29b39SMartin Sperl static inline void bcm2835aux_rd_fifo(struct bcm2835aux_spi *bs) 1191ea29b39SMartin Sperl { 1201ea29b39SMartin Sperl u32 data; 1211ea29b39SMartin Sperl int count = min(bs->rx_len, 3); 1221ea29b39SMartin Sperl 1231ea29b39SMartin Sperl data = bcm2835aux_rd(bs, BCM2835_AUX_SPI_IO); 1241ea29b39SMartin Sperl if (bs->rx_buf) { 12572aac02bSMartin Sperl switch (count) { 12672aac02bSMartin Sperl case 3: 12772aac02bSMartin Sperl *bs->rx_buf++ = (data >> 16) & 0xff; 12872aac02bSMartin Sperl /* fallthrough */ 12972aac02bSMartin Sperl case 2: 13072aac02bSMartin Sperl *bs->rx_buf++ = (data >> 8) & 0xff; 13172aac02bSMartin Sperl /* fallthrough */ 13272aac02bSMartin Sperl case 1: 13372aac02bSMartin Sperl *bs->rx_buf++ = (data >> 0) & 0xff; 13472aac02bSMartin Sperl /* fallthrough - no default */ 13572aac02bSMartin Sperl } 1361ea29b39SMartin Sperl } 1371ea29b39SMartin Sperl bs->rx_len -= count; 13872aac02bSMartin Sperl bs->pending -= count; 1391ea29b39SMartin Sperl } 1401ea29b39SMartin Sperl 1411ea29b39SMartin Sperl static inline void bcm2835aux_wr_fifo(struct bcm2835aux_spi *bs) 1421ea29b39SMartin Sperl { 1431ea29b39SMartin Sperl u32 data; 1441ea29b39SMartin Sperl u8 byte; 1451ea29b39SMartin Sperl int count; 1461ea29b39SMartin Sperl int i; 1471ea29b39SMartin Sperl 1481ea29b39SMartin Sperl /* gather up to 3 bytes to write to the FIFO */ 1491ea29b39SMartin Sperl count = min(bs->tx_len, 3); 1501ea29b39SMartin Sperl data = 0; 1511ea29b39SMartin Sperl for (i = 0; i < count; i++) { 1521ea29b39SMartin Sperl byte = bs->tx_buf ? *bs->tx_buf++ : 0; 1531ea29b39SMartin Sperl data |= byte << (8 * (2 - i)); 1541ea29b39SMartin Sperl } 1551ea29b39SMartin Sperl 1561ea29b39SMartin Sperl /* and set the variable bit-length */ 1571ea29b39SMartin Sperl data |= (count * 8) << 24; 1581ea29b39SMartin Sperl 1591ea29b39SMartin Sperl /* and decrement length */ 1601ea29b39SMartin Sperl bs->tx_len -= count; 16172aac02bSMartin Sperl bs->pending += count; 1621ea29b39SMartin Sperl 1631ea29b39SMartin Sperl /* write to the correct TX-register */ 1641ea29b39SMartin Sperl if (bs->tx_len) 1651ea29b39SMartin Sperl bcm2835aux_wr(bs, BCM2835_AUX_SPI_TXHOLD, data); 1661ea29b39SMartin Sperl else 1671ea29b39SMartin Sperl bcm2835aux_wr(bs, BCM2835_AUX_SPI_IO, data); 1681ea29b39SMartin Sperl } 1691ea29b39SMartin Sperl 1701ea29b39SMartin Sperl static void bcm2835aux_spi_reset_hw(struct bcm2835aux_spi *bs) 1711ea29b39SMartin Sperl { 1721ea29b39SMartin Sperl /* disable spi clearing fifo and interrupts */ 1731ea29b39SMartin Sperl bcm2835aux_wr(bs, BCM2835_AUX_SPI_CNTL1, 0); 1741ea29b39SMartin Sperl bcm2835aux_wr(bs, BCM2835_AUX_SPI_CNTL0, 1751ea29b39SMartin Sperl BCM2835_AUX_SPI_CNTL0_CLEARFIFO); 1761ea29b39SMartin Sperl } 1771ea29b39SMartin Sperl 1787188a6f0SMartin Sperl static void bcm2835aux_spi_transfer_helper(struct bcm2835aux_spi *bs) 1791ea29b39SMartin Sperl { 18073b114eeSMartin Sperl u32 stat = bcm2835aux_rd(bs, BCM2835_AUX_SPI_STAT); 18173b114eeSMartin Sperl 1821ea29b39SMartin Sperl /* check if we have data to read */ 18373b114eeSMartin Sperl for (; bs->rx_len && (stat & BCM2835_AUX_SPI_STAT_RX_LVL); 18473b114eeSMartin Sperl stat = bcm2835aux_rd(bs, BCM2835_AUX_SPI_STAT)) 1851ea29b39SMartin Sperl bcm2835aux_rd_fifo(bs); 1861ea29b39SMartin Sperl 1871ea29b39SMartin Sperl /* check if we have data to write */ 1881ea29b39SMartin Sperl while (bs->tx_len && 18972aac02bSMartin Sperl (bs->pending < 12) && 1901ea29b39SMartin Sperl (!(bcm2835aux_rd(bs, BCM2835_AUX_SPI_STAT) & 1911ea29b39SMartin Sperl BCM2835_AUX_SPI_STAT_TX_FULL))) { 1921ea29b39SMartin Sperl bcm2835aux_wr_fifo(bs); 1931ea29b39SMartin Sperl } 1947188a6f0SMartin Sperl } 1957188a6f0SMartin Sperl 1967188a6f0SMartin Sperl static irqreturn_t bcm2835aux_spi_interrupt(int irq, void *dev_id) 1977188a6f0SMartin Sperl { 1987188a6f0SMartin Sperl struct spi_master *master = dev_id; 1997188a6f0SMartin Sperl struct bcm2835aux_spi *bs = spi_master_get_devdata(master); 2007188a6f0SMartin Sperl 2017188a6f0SMartin Sperl /* IRQ may be shared, so return if our interrupts are disabled */ 2027188a6f0SMartin Sperl if (!(bcm2835aux_rd(bs, BCM2835_AUX_SPI_CNTL1) & 2037188a6f0SMartin Sperl (BCM2835_AUX_SPI_CNTL1_TXEMPTY | BCM2835_AUX_SPI_CNTL1_IDLE))) 2047188a6f0SMartin Sperl return IRQ_NONE; 2057188a6f0SMartin Sperl 2067188a6f0SMartin Sperl /* do common fifo handling */ 2077188a6f0SMartin Sperl bcm2835aux_spi_transfer_helper(bs); 2081ea29b39SMartin Sperl 209f29ab184SStephan Olbrich if (!bs->tx_len) { 210f29ab184SStephan Olbrich /* disable tx fifo empty interrupt */ 211f29ab184SStephan Olbrich bcm2835aux_wr(bs, BCM2835_AUX_SPI_CNTL1, bs->cntl[1] | 212f29ab184SStephan Olbrich BCM2835_AUX_SPI_CNTL1_IDLE); 213f29ab184SStephan Olbrich } 214f29ab184SStephan Olbrich 215b4e2adefSStephan Olbrich /* and if rx_len is 0 then disable interrupts and wake up completion */ 2161ea29b39SMartin Sperl if (!bs->rx_len) { 217b4e2adefSStephan Olbrich bcm2835aux_wr(bs, BCM2835_AUX_SPI_CNTL1, bs->cntl[1]); 2181ea29b39SMartin Sperl complete(&master->xfer_completion); 2191ea29b39SMartin Sperl } 2201ea29b39SMartin Sperl 2217188a6f0SMartin Sperl return IRQ_HANDLED; 2221ea29b39SMartin Sperl } 2231ea29b39SMartin Sperl 2241ea29b39SMartin Sperl static int __bcm2835aux_spi_transfer_one_irq(struct spi_master *master, 2251ea29b39SMartin Sperl struct spi_device *spi, 2261ea29b39SMartin Sperl struct spi_transfer *tfr) 2271ea29b39SMartin Sperl { 2281ea29b39SMartin Sperl struct bcm2835aux_spi *bs = spi_master_get_devdata(master); 2291ea29b39SMartin Sperl 2301ea29b39SMartin Sperl /* enable interrupts */ 2311ea29b39SMartin Sperl bcm2835aux_wr(bs, BCM2835_AUX_SPI_CNTL1, bs->cntl[1] | 2321ea29b39SMartin Sperl BCM2835_AUX_SPI_CNTL1_TXEMPTY | 2331ea29b39SMartin Sperl BCM2835_AUX_SPI_CNTL1_IDLE); 2341ea29b39SMartin Sperl 2351ea29b39SMartin Sperl /* and wait for finish... */ 2361ea29b39SMartin Sperl return 1; 2371ea29b39SMartin Sperl } 2381ea29b39SMartin Sperl 2391ea29b39SMartin Sperl static int bcm2835aux_spi_transfer_one_irq(struct spi_master *master, 2401ea29b39SMartin Sperl struct spi_device *spi, 2411ea29b39SMartin Sperl struct spi_transfer *tfr) 2421ea29b39SMartin Sperl { 2431ea29b39SMartin Sperl struct bcm2835aux_spi *bs = spi_master_get_devdata(master); 2441ea29b39SMartin Sperl 2451ea29b39SMartin Sperl /* fill in registers and fifos before enabling interrupts */ 2461ea29b39SMartin Sperl bcm2835aux_wr(bs, BCM2835_AUX_SPI_CNTL1, bs->cntl[1]); 2471ea29b39SMartin Sperl bcm2835aux_wr(bs, BCM2835_AUX_SPI_CNTL0, bs->cntl[0]); 2481ea29b39SMartin Sperl 2491ea29b39SMartin Sperl /* fill in tx fifo with data before enabling interrupts */ 2501ea29b39SMartin Sperl while ((bs->tx_len) && 25172aac02bSMartin Sperl (bs->pending < 12) && 2521ea29b39SMartin Sperl (!(bcm2835aux_rd(bs, BCM2835_AUX_SPI_STAT) & 2531ea29b39SMartin Sperl BCM2835_AUX_SPI_STAT_TX_FULL))) { 2541ea29b39SMartin Sperl bcm2835aux_wr_fifo(bs); 2551ea29b39SMartin Sperl } 2561ea29b39SMartin Sperl 2571ea29b39SMartin Sperl /* now run the interrupt mode */ 2581ea29b39SMartin Sperl return __bcm2835aux_spi_transfer_one_irq(master, spi, tfr); 2591ea29b39SMartin Sperl } 2601ea29b39SMartin Sperl 2611ea29b39SMartin Sperl static int bcm2835aux_spi_transfer_one_poll(struct spi_master *master, 2621ea29b39SMartin Sperl struct spi_device *spi, 26372aac02bSMartin Sperl struct spi_transfer *tfr) 2641ea29b39SMartin Sperl { 2651ea29b39SMartin Sperl struct bcm2835aux_spi *bs = spi_master_get_devdata(master); 2661ea29b39SMartin Sperl unsigned long timeout; 2671ea29b39SMartin Sperl 2681ea29b39SMartin Sperl /* configure spi */ 2691ea29b39SMartin Sperl bcm2835aux_wr(bs, BCM2835_AUX_SPI_CNTL1, bs->cntl[1]); 2701ea29b39SMartin Sperl bcm2835aux_wr(bs, BCM2835_AUX_SPI_CNTL0, bs->cntl[0]); 2711ea29b39SMartin Sperl 2721ea29b39SMartin Sperl /* set the timeout */ 2731ea29b39SMartin Sperl timeout = jiffies + BCM2835_AUX_SPI_POLLING_JIFFIES; 2741ea29b39SMartin Sperl 2751ea29b39SMartin Sperl /* loop until finished the transfer */ 2761ea29b39SMartin Sperl while (bs->rx_len) { 2771ea29b39SMartin Sperl 2787188a6f0SMartin Sperl /* do common fifo handling */ 2797188a6f0SMartin Sperl bcm2835aux_spi_transfer_helper(bs); 2801ea29b39SMartin Sperl 2811ea29b39SMartin Sperl /* there is still data pending to read check the timeout */ 2821ea29b39SMartin Sperl if (bs->rx_len && time_after(jiffies, timeout)) { 2831ea29b39SMartin Sperl dev_dbg_ratelimited(&spi->dev, 2841ea29b39SMartin Sperl "timeout period reached: jiffies: %lu remaining tx/rx: %d/%d - falling back to interrupt mode\n", 2851ea29b39SMartin Sperl jiffies - timeout, 2861ea29b39SMartin Sperl bs->tx_len, bs->rx_len); 2871ea29b39SMartin Sperl /* forward to interrupt handler */ 2881ea29b39SMartin Sperl return __bcm2835aux_spi_transfer_one_irq(master, 2891ea29b39SMartin Sperl spi, tfr); 2901ea29b39SMartin Sperl } 2911ea29b39SMartin Sperl } 2921ea29b39SMartin Sperl 2931ea29b39SMartin Sperl /* and return without waiting for completion */ 2941ea29b39SMartin Sperl return 0; 2951ea29b39SMartin Sperl } 2961ea29b39SMartin Sperl 2971ea29b39SMartin Sperl static int bcm2835aux_spi_transfer_one(struct spi_master *master, 2981ea29b39SMartin Sperl struct spi_device *spi, 2991ea29b39SMartin Sperl struct spi_transfer *tfr) 3001ea29b39SMartin Sperl { 3011ea29b39SMartin Sperl struct bcm2835aux_spi *bs = spi_master_get_devdata(master); 3021ea29b39SMartin Sperl unsigned long spi_hz, clk_hz, speed; 30372aac02bSMartin Sperl unsigned long spi_used_hz; 3041ea29b39SMartin Sperl 3051ea29b39SMartin Sperl /* calculate the registers to handle 3061ea29b39SMartin Sperl * 3071ea29b39SMartin Sperl * note that we use the variable data mode, which 3081ea29b39SMartin Sperl * is not optimal for longer transfers as we waste registers 3091ea29b39SMartin Sperl * resulting (potentially) in more interrupts when transferring 3101ea29b39SMartin Sperl * more than 12 bytes 3111ea29b39SMartin Sperl */ 3121ea29b39SMartin Sperl 3131ea29b39SMartin Sperl /* set clock */ 3141ea29b39SMartin Sperl spi_hz = tfr->speed_hz; 3151ea29b39SMartin Sperl clk_hz = clk_get_rate(bs->clk); 3161ea29b39SMartin Sperl 3171ea29b39SMartin Sperl if (spi_hz >= clk_hz / 2) { 3181ea29b39SMartin Sperl speed = 0; 3191ea29b39SMartin Sperl } else if (spi_hz) { 3201ea29b39SMartin Sperl speed = DIV_ROUND_UP(clk_hz, 2 * spi_hz) - 1; 3211ea29b39SMartin Sperl if (speed > BCM2835_AUX_SPI_CNTL0_SPEED_MAX) 3221ea29b39SMartin Sperl speed = BCM2835_AUX_SPI_CNTL0_SPEED_MAX; 3231ea29b39SMartin Sperl } else { /* the slowest we can go */ 3241ea29b39SMartin Sperl speed = BCM2835_AUX_SPI_CNTL0_SPEED_MAX; 3251ea29b39SMartin Sperl } 326b4e2adefSStephan Olbrich /* mask out old speed from previous spi_transfer */ 327b4e2adefSStephan Olbrich bs->cntl[0] &= ~(BCM2835_AUX_SPI_CNTL0_SPEED); 328b4e2adefSStephan Olbrich /* set the new speed */ 3291ea29b39SMartin Sperl bs->cntl[0] |= speed << BCM2835_AUX_SPI_CNTL0_SPEED_SHIFT; 3301ea29b39SMartin Sperl 3311ea29b39SMartin Sperl spi_used_hz = clk_hz / (2 * (speed + 1)); 3321ea29b39SMartin Sperl 3331ea29b39SMartin Sperl /* set transmit buffers and length */ 3341ea29b39SMartin Sperl bs->tx_buf = tfr->tx_buf; 3351ea29b39SMartin Sperl bs->rx_buf = tfr->rx_buf; 3361ea29b39SMartin Sperl bs->tx_len = tfr->len; 3371ea29b39SMartin Sperl bs->rx_len = tfr->len; 33872aac02bSMartin Sperl bs->pending = 0; 3391ea29b39SMartin Sperl 340d704afffSTrent Piepho /* Calculate the estimated time in us the transfer runs. Note that 341d704afffSTrent Piepho * there are are 2 idle clocks cycles after each chunk getting 342d704afffSTrent Piepho * transferred - in our case the chunk size is 3 bytes, so we 343d704afffSTrent Piepho * approximate this by 9 cycles/byte. This is used to find the number 344d704afffSTrent Piepho * of Hz per byte per polling limit. E.g., we can transfer 1 byte in 345d704afffSTrent Piepho * 30 µs per 300,000 Hz of bus clock. 34672aac02bSMartin Sperl */ 347d704afffSTrent Piepho #define HZ_PER_BYTE ((9 * 1000000) / BCM2835_AUX_SPI_POLLING_LIMIT_US) 3481ea29b39SMartin Sperl /* run in polling mode for short transfers */ 349d704afffSTrent Piepho if (tfr->len < spi_used_hz / HZ_PER_BYTE) 35072aac02bSMartin Sperl return bcm2835aux_spi_transfer_one_poll(master, spi, tfr); 3511ea29b39SMartin Sperl 3521ea29b39SMartin Sperl /* run in interrupt mode for all others */ 3531ea29b39SMartin Sperl return bcm2835aux_spi_transfer_one_irq(master, spi, tfr); 354d704afffSTrent Piepho #undef HZ_PER_BYTE 3551ea29b39SMartin Sperl } 3561ea29b39SMartin Sperl 357b4e2adefSStephan Olbrich static int bcm2835aux_spi_prepare_message(struct spi_master *master, 358b4e2adefSStephan Olbrich struct spi_message *msg) 359b4e2adefSStephan Olbrich { 360b4e2adefSStephan Olbrich struct spi_device *spi = msg->spi; 361b4e2adefSStephan Olbrich struct bcm2835aux_spi *bs = spi_master_get_devdata(master); 362b4e2adefSStephan Olbrich 363b4e2adefSStephan Olbrich bs->cntl[0] = BCM2835_AUX_SPI_CNTL0_ENABLE | 364b4e2adefSStephan Olbrich BCM2835_AUX_SPI_CNTL0_VAR_WIDTH | 365b4e2adefSStephan Olbrich BCM2835_AUX_SPI_CNTL0_MSBF_OUT; 366b4e2adefSStephan Olbrich bs->cntl[1] = BCM2835_AUX_SPI_CNTL1_MSBF_IN; 367b4e2adefSStephan Olbrich 368b4e2adefSStephan Olbrich /* handle all the modes */ 369e9dd4edcSStephan Olbrich if (spi->mode & SPI_CPOL) { 370b4e2adefSStephan Olbrich bs->cntl[0] |= BCM2835_AUX_SPI_CNTL0_CPOL; 371e9dd4edcSStephan Olbrich bs->cntl[0] |= BCM2835_AUX_SPI_CNTL0_OUT_RISING; 372e9dd4edcSStephan Olbrich } else { 373e9dd4edcSStephan Olbrich bs->cntl[0] |= BCM2835_AUX_SPI_CNTL0_IN_RISING; 374e9dd4edcSStephan Olbrich } 375b4e2adefSStephan Olbrich bcm2835aux_wr(bs, BCM2835_AUX_SPI_CNTL1, bs->cntl[1]); 376b4e2adefSStephan Olbrich bcm2835aux_wr(bs, BCM2835_AUX_SPI_CNTL0, bs->cntl[0]); 377b4e2adefSStephan Olbrich 378b4e2adefSStephan Olbrich return 0; 379b4e2adefSStephan Olbrich } 380b4e2adefSStephan Olbrich 381b4e2adefSStephan Olbrich static int bcm2835aux_spi_unprepare_message(struct spi_master *master, 382b4e2adefSStephan Olbrich struct spi_message *msg) 383b4e2adefSStephan Olbrich { 384b4e2adefSStephan Olbrich struct bcm2835aux_spi *bs = spi_master_get_devdata(master); 385b4e2adefSStephan Olbrich 386b4e2adefSStephan Olbrich bcm2835aux_spi_reset_hw(bs); 387b4e2adefSStephan Olbrich 388b4e2adefSStephan Olbrich return 0; 389b4e2adefSStephan Olbrich } 390b4e2adefSStephan Olbrich 3911ea29b39SMartin Sperl static void bcm2835aux_spi_handle_err(struct spi_master *master, 3921ea29b39SMartin Sperl struct spi_message *msg) 3931ea29b39SMartin Sperl { 3941ea29b39SMartin Sperl struct bcm2835aux_spi *bs = spi_master_get_devdata(master); 3951ea29b39SMartin Sperl 3961ea29b39SMartin Sperl bcm2835aux_spi_reset_hw(bs); 3971ea29b39SMartin Sperl } 3981ea29b39SMartin Sperl 399519f2c22SMartin Sperl static int bcm2835aux_spi_setup(struct spi_device *spi) 400519f2c22SMartin Sperl { 401519f2c22SMartin Sperl int ret; 402519f2c22SMartin Sperl 403519f2c22SMartin Sperl /* sanity check for native cs */ 404519f2c22SMartin Sperl if (spi->mode & SPI_NO_CS) 405519f2c22SMartin Sperl return 0; 406ccd978b7SMartin Sperl if (gpio_is_valid(spi->cs_gpio)) { 407ccd978b7SMartin Sperl /* with gpio-cs set the GPIO to the correct level 408ccd978b7SMartin Sperl * and as output (in case the dt has the gpio not configured 409ccd978b7SMartin Sperl * as output but native cs) 410ccd978b7SMartin Sperl */ 411ccd978b7SMartin Sperl ret = gpio_direction_output(spi->cs_gpio, 412ccd978b7SMartin Sperl (spi->mode & SPI_CS_HIGH) ? 0 : 1); 413ccd978b7SMartin Sperl if (ret) 414ccd978b7SMartin Sperl dev_err(&spi->dev, 415ccd978b7SMartin Sperl "could not set gpio %i as output: %i\n", 416ccd978b7SMartin Sperl spi->cs_gpio, ret); 417ccd978b7SMartin Sperl 418ccd978b7SMartin Sperl return ret; 419ccd978b7SMartin Sperl } 420519f2c22SMartin Sperl 421519f2c22SMartin Sperl /* for dt-backwards compatibility: only support native on CS0 422519f2c22SMartin Sperl * known things not supported with broken native CS: 423519f2c22SMartin Sperl * * multiple chip-selects: cs0-cs2 are all 424519f2c22SMartin Sperl * simultaniously asserted whenever there is a transfer 425519f2c22SMartin Sperl * this even includes SPI_NO_CS 426519f2c22SMartin Sperl * * SPI_CS_HIGH: cs are always asserted low 427519f2c22SMartin Sperl * * cs_change: cs is deasserted after each spi_transfer 428519f2c22SMartin Sperl * * cs_delay_usec: cs is always deasserted one SCK cycle 429519f2c22SMartin Sperl * after the last transfer 430519f2c22SMartin Sperl * probably more... 431519f2c22SMartin Sperl */ 432519f2c22SMartin Sperl dev_warn(&spi->dev, 433519f2c22SMartin Sperl "Native CS is not supported - please configure cs-gpio in device-tree\n"); 434519f2c22SMartin Sperl 435519f2c22SMartin Sperl if (spi->chip_select == 0) 436519f2c22SMartin Sperl return 0; 437519f2c22SMartin Sperl 438519f2c22SMartin Sperl dev_warn(&spi->dev, "Native CS is not working for cs > 0\n"); 439519f2c22SMartin Sperl 440519f2c22SMartin Sperl return -EINVAL; 441519f2c22SMartin Sperl } 442519f2c22SMartin Sperl 4431ea29b39SMartin Sperl static int bcm2835aux_spi_probe(struct platform_device *pdev) 4441ea29b39SMartin Sperl { 4451ea29b39SMartin Sperl struct spi_master *master; 4461ea29b39SMartin Sperl struct bcm2835aux_spi *bs; 4471ea29b39SMartin Sperl struct resource *res; 4481ea29b39SMartin Sperl unsigned long clk_hz; 4491ea29b39SMartin Sperl int err; 4501ea29b39SMartin Sperl 4511ea29b39SMartin Sperl master = spi_alloc_master(&pdev->dev, sizeof(*bs)); 4521ea29b39SMartin Sperl if (!master) { 4531ea29b39SMartin Sperl dev_err(&pdev->dev, "spi_alloc_master() failed\n"); 4541ea29b39SMartin Sperl return -ENOMEM; 4551ea29b39SMartin Sperl } 4561ea29b39SMartin Sperl 4571ea29b39SMartin Sperl platform_set_drvdata(pdev, master); 458e9dd4edcSStephan Olbrich master->mode_bits = (SPI_CPOL | SPI_CS_HIGH | SPI_NO_CS); 4591ea29b39SMartin Sperl master->bits_per_word_mask = SPI_BPW_MASK(8); 460509c5836SMartin Sperl /* even though the driver never officially supported native CS 461509c5836SMartin Sperl * allow a single native CS for legacy DT support purposes when 462509c5836SMartin Sperl * no cs-gpio is configured. 463509c5836SMartin Sperl * Known limitations for native cs are: 464509c5836SMartin Sperl * * multiple chip-selects: cs0-cs2 are all simultaniously asserted 465509c5836SMartin Sperl * whenever there is a transfer - this even includes SPI_NO_CS 466509c5836SMartin Sperl * * SPI_CS_HIGH: is ignores - cs are always asserted low 467509c5836SMartin Sperl * * cs_change: cs is deasserted after each spi_transfer 468509c5836SMartin Sperl * * cs_delay_usec: cs is always deasserted one SCK cycle after 469509c5836SMartin Sperl * a spi_transfer 470509c5836SMartin Sperl */ 471509c5836SMartin Sperl master->num_chipselect = 1; 472519f2c22SMartin Sperl master->setup = bcm2835aux_spi_setup; 4731ea29b39SMartin Sperl master->transfer_one = bcm2835aux_spi_transfer_one; 4741ea29b39SMartin Sperl master->handle_err = bcm2835aux_spi_handle_err; 475b4e2adefSStephan Olbrich master->prepare_message = bcm2835aux_spi_prepare_message; 476b4e2adefSStephan Olbrich master->unprepare_message = bcm2835aux_spi_unprepare_message; 4771ea29b39SMartin Sperl master->dev.of_node = pdev->dev.of_node; 4781ea29b39SMartin Sperl 4791ea29b39SMartin Sperl bs = spi_master_get_devdata(master); 4801ea29b39SMartin Sperl 4811ea29b39SMartin Sperl /* the main area */ 4821ea29b39SMartin Sperl res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 4831ea29b39SMartin Sperl bs->regs = devm_ioremap_resource(&pdev->dev, res); 4841ea29b39SMartin Sperl if (IS_ERR(bs->regs)) { 4851ea29b39SMartin Sperl err = PTR_ERR(bs->regs); 4861ea29b39SMartin Sperl goto out_master_put; 4871ea29b39SMartin Sperl } 4881ea29b39SMartin Sperl 4891ea29b39SMartin Sperl bs->clk = devm_clk_get(&pdev->dev, NULL); 490bfc7af6dSYueHaibing if (IS_ERR(bs->clk)) { 4911ea29b39SMartin Sperl err = PTR_ERR(bs->clk); 4921ea29b39SMartin Sperl dev_err(&pdev->dev, "could not get clk: %d\n", err); 4931ea29b39SMartin Sperl goto out_master_put; 4941ea29b39SMartin Sperl } 4951ea29b39SMartin Sperl 49607bce09eSMartin Sperl bs->irq = platform_get_irq(pdev, 0); 4971ea29b39SMartin Sperl if (bs->irq <= 0) { 4981ea29b39SMartin Sperl dev_err(&pdev->dev, "could not get IRQ: %d\n", bs->irq); 4991ea29b39SMartin Sperl err = bs->irq ? bs->irq : -ENODEV; 5001ea29b39SMartin Sperl goto out_master_put; 5011ea29b39SMartin Sperl } 5021ea29b39SMartin Sperl 5031ea29b39SMartin Sperl /* this also enables the HW block */ 5041ea29b39SMartin Sperl err = clk_prepare_enable(bs->clk); 5051ea29b39SMartin Sperl if (err) { 5061ea29b39SMartin Sperl dev_err(&pdev->dev, "could not prepare clock: %d\n", err); 5071ea29b39SMartin Sperl goto out_master_put; 5081ea29b39SMartin Sperl } 5091ea29b39SMartin Sperl 5101ea29b39SMartin Sperl /* just checking if the clock returns a sane value */ 5111ea29b39SMartin Sperl clk_hz = clk_get_rate(bs->clk); 5121ea29b39SMartin Sperl if (!clk_hz) { 5131ea29b39SMartin Sperl dev_err(&pdev->dev, "clock returns 0 Hz\n"); 5141ea29b39SMartin Sperl err = -ENODEV; 5151ea29b39SMartin Sperl goto out_clk_disable; 5161ea29b39SMartin Sperl } 5171ea29b39SMartin Sperl 51807bce09eSMartin Sperl /* reset SPI-HW block */ 51907bce09eSMartin Sperl bcm2835aux_spi_reset_hw(bs); 52007bce09eSMartin Sperl 5211ea29b39SMartin Sperl err = devm_request_irq(&pdev->dev, bs->irq, 5221ea29b39SMartin Sperl bcm2835aux_spi_interrupt, 5231ea29b39SMartin Sperl IRQF_SHARED, 5241ea29b39SMartin Sperl dev_name(&pdev->dev), master); 5251ea29b39SMartin Sperl if (err) { 5261ea29b39SMartin Sperl dev_err(&pdev->dev, "could not request IRQ: %d\n", err); 5271ea29b39SMartin Sperl goto out_clk_disable; 5281ea29b39SMartin Sperl } 5291ea29b39SMartin Sperl 5301ea29b39SMartin Sperl err = devm_spi_register_master(&pdev->dev, master); 5311ea29b39SMartin Sperl if (err) { 5321ea29b39SMartin Sperl dev_err(&pdev->dev, "could not register SPI master: %d\n", err); 5331ea29b39SMartin Sperl goto out_clk_disable; 5341ea29b39SMartin Sperl } 5351ea29b39SMartin Sperl 5361ea29b39SMartin Sperl return 0; 5371ea29b39SMartin Sperl 5381ea29b39SMartin Sperl out_clk_disable: 5391ea29b39SMartin Sperl clk_disable_unprepare(bs->clk); 5401ea29b39SMartin Sperl out_master_put: 5411ea29b39SMartin Sperl spi_master_put(master); 5421ea29b39SMartin Sperl return err; 5431ea29b39SMartin Sperl } 5441ea29b39SMartin Sperl 5451ea29b39SMartin Sperl static int bcm2835aux_spi_remove(struct platform_device *pdev) 5461ea29b39SMartin Sperl { 5471ea29b39SMartin Sperl struct spi_master *master = platform_get_drvdata(pdev); 5481ea29b39SMartin Sperl struct bcm2835aux_spi *bs = spi_master_get_devdata(master); 5491ea29b39SMartin Sperl 5501ea29b39SMartin Sperl bcm2835aux_spi_reset_hw(bs); 5511ea29b39SMartin Sperl 5521ea29b39SMartin Sperl /* disable the HW block by releasing the clock */ 5531ea29b39SMartin Sperl clk_disable_unprepare(bs->clk); 5541ea29b39SMartin Sperl 5551ea29b39SMartin Sperl return 0; 5561ea29b39SMartin Sperl } 5571ea29b39SMartin Sperl 5581ea29b39SMartin Sperl static const struct of_device_id bcm2835aux_spi_match[] = { 5591ea29b39SMartin Sperl { .compatible = "brcm,bcm2835-aux-spi", }, 5601ea29b39SMartin Sperl {} 5611ea29b39SMartin Sperl }; 5621ea29b39SMartin Sperl MODULE_DEVICE_TABLE(of, bcm2835aux_spi_match); 5631ea29b39SMartin Sperl 5641ea29b39SMartin Sperl static struct platform_driver bcm2835aux_spi_driver = { 5651ea29b39SMartin Sperl .driver = { 5661ea29b39SMartin Sperl .name = "spi-bcm2835aux", 5671ea29b39SMartin Sperl .of_match_table = bcm2835aux_spi_match, 5681ea29b39SMartin Sperl }, 5691ea29b39SMartin Sperl .probe = bcm2835aux_spi_probe, 5701ea29b39SMartin Sperl .remove = bcm2835aux_spi_remove, 5711ea29b39SMartin Sperl }; 5721ea29b39SMartin Sperl module_platform_driver(bcm2835aux_spi_driver); 5731ea29b39SMartin Sperl 5741ea29b39SMartin Sperl MODULE_DESCRIPTION("SPI controller driver for Broadcom BCM2835 aux"); 5751ea29b39SMartin Sperl MODULE_AUTHOR("Martin Sperl <kernel@martin.sperl.org>"); 57622bf6cd2SStefan Wahren MODULE_LICENSE("GPL"); 577