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 671ea29b39SMartin Sperl #define BCM2835_AUX_SPI_CNTL0_CPHA_IN 0x00000400 681ea29b39SMartin Sperl #define BCM2835_AUX_SPI_CNTL0_CLEARFIFO 0x00000200 691ea29b39SMartin Sperl #define BCM2835_AUX_SPI_CNTL0_CPHA_OUT 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 761ea29b39SMartin Sperl #define BCM2835_AUX_SPI_CNTL1_IDLE 0x00000080 771ea29b39SMartin Sperl #define BCM2835_AUX_SPI_CNTL1_TXEMPTY 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 #define BCM2835_AUX_SPI_MODE_BITS (SPI_CPOL | SPI_CPHA | SPI_CS_HIGH \ 961ea29b39SMartin Sperl | SPI_NO_CS) 971ea29b39SMartin Sperl 981ea29b39SMartin Sperl struct bcm2835aux_spi { 991ea29b39SMartin Sperl void __iomem *regs; 1001ea29b39SMartin Sperl struct clk *clk; 1011ea29b39SMartin Sperl int irq; 1021ea29b39SMartin Sperl u32 cntl[2]; 1031ea29b39SMartin Sperl const u8 *tx_buf; 1041ea29b39SMartin Sperl u8 *rx_buf; 1051ea29b39SMartin Sperl int tx_len; 1061ea29b39SMartin Sperl int rx_len; 10772aac02bSMartin Sperl int pending; 1081ea29b39SMartin Sperl }; 1091ea29b39SMartin Sperl 1101ea29b39SMartin Sperl static inline u32 bcm2835aux_rd(struct bcm2835aux_spi *bs, unsigned reg) 1111ea29b39SMartin Sperl { 1121ea29b39SMartin Sperl return readl(bs->regs + reg); 1131ea29b39SMartin Sperl } 1141ea29b39SMartin Sperl 1151ea29b39SMartin Sperl static inline void bcm2835aux_wr(struct bcm2835aux_spi *bs, unsigned reg, 1161ea29b39SMartin Sperl u32 val) 1171ea29b39SMartin Sperl { 1181ea29b39SMartin Sperl writel(val, bs->regs + reg); 1191ea29b39SMartin Sperl } 1201ea29b39SMartin Sperl 1211ea29b39SMartin Sperl static inline void bcm2835aux_rd_fifo(struct bcm2835aux_spi *bs) 1221ea29b39SMartin Sperl { 1231ea29b39SMartin Sperl u32 data; 1241ea29b39SMartin Sperl int count = min(bs->rx_len, 3); 1251ea29b39SMartin Sperl 1261ea29b39SMartin Sperl data = bcm2835aux_rd(bs, BCM2835_AUX_SPI_IO); 1271ea29b39SMartin Sperl if (bs->rx_buf) { 12872aac02bSMartin Sperl switch (count) { 12972aac02bSMartin Sperl case 4: 13072aac02bSMartin Sperl *bs->rx_buf++ = (data >> 24) & 0xff; 13172aac02bSMartin Sperl /* fallthrough */ 13272aac02bSMartin Sperl case 3: 13372aac02bSMartin Sperl *bs->rx_buf++ = (data >> 16) & 0xff; 13472aac02bSMartin Sperl /* fallthrough */ 13572aac02bSMartin Sperl case 2: 13672aac02bSMartin Sperl *bs->rx_buf++ = (data >> 8) & 0xff; 13772aac02bSMartin Sperl /* fallthrough */ 13872aac02bSMartin Sperl case 1: 13972aac02bSMartin Sperl *bs->rx_buf++ = (data >> 0) & 0xff; 14072aac02bSMartin Sperl /* fallthrough - no default */ 14172aac02bSMartin Sperl } 1421ea29b39SMartin Sperl } 1431ea29b39SMartin Sperl bs->rx_len -= count; 14472aac02bSMartin Sperl bs->pending -= count; 1451ea29b39SMartin Sperl } 1461ea29b39SMartin Sperl 1471ea29b39SMartin Sperl static inline void bcm2835aux_wr_fifo(struct bcm2835aux_spi *bs) 1481ea29b39SMartin Sperl { 1491ea29b39SMartin Sperl u32 data; 1501ea29b39SMartin Sperl u8 byte; 1511ea29b39SMartin Sperl int count; 1521ea29b39SMartin Sperl int i; 1531ea29b39SMartin Sperl 1541ea29b39SMartin Sperl /* gather up to 3 bytes to write to the FIFO */ 1551ea29b39SMartin Sperl count = min(bs->tx_len, 3); 1561ea29b39SMartin Sperl data = 0; 1571ea29b39SMartin Sperl for (i = 0; i < count; i++) { 1581ea29b39SMartin Sperl byte = bs->tx_buf ? *bs->tx_buf++ : 0; 1591ea29b39SMartin Sperl data |= byte << (8 * (2 - i)); 1601ea29b39SMartin Sperl } 1611ea29b39SMartin Sperl 1621ea29b39SMartin Sperl /* and set the variable bit-length */ 1631ea29b39SMartin Sperl data |= (count * 8) << 24; 1641ea29b39SMartin Sperl 1651ea29b39SMartin Sperl /* and decrement length */ 1661ea29b39SMartin Sperl bs->tx_len -= count; 16772aac02bSMartin Sperl bs->pending += count; 1681ea29b39SMartin Sperl 1691ea29b39SMartin Sperl /* write to the correct TX-register */ 1701ea29b39SMartin Sperl if (bs->tx_len) 1711ea29b39SMartin Sperl bcm2835aux_wr(bs, BCM2835_AUX_SPI_TXHOLD, data); 1721ea29b39SMartin Sperl else 1731ea29b39SMartin Sperl bcm2835aux_wr(bs, BCM2835_AUX_SPI_IO, data); 1741ea29b39SMartin Sperl } 1751ea29b39SMartin Sperl 1761ea29b39SMartin Sperl static void bcm2835aux_spi_reset_hw(struct bcm2835aux_spi *bs) 1771ea29b39SMartin Sperl { 1781ea29b39SMartin Sperl /* disable spi clearing fifo and interrupts */ 1791ea29b39SMartin Sperl bcm2835aux_wr(bs, BCM2835_AUX_SPI_CNTL1, 0); 1801ea29b39SMartin Sperl bcm2835aux_wr(bs, BCM2835_AUX_SPI_CNTL0, 1811ea29b39SMartin Sperl BCM2835_AUX_SPI_CNTL0_CLEARFIFO); 1821ea29b39SMartin Sperl } 1831ea29b39SMartin Sperl 1841ea29b39SMartin Sperl static irqreturn_t bcm2835aux_spi_interrupt(int irq, void *dev_id) 1851ea29b39SMartin Sperl { 1861ea29b39SMartin Sperl struct spi_master *master = dev_id; 1871ea29b39SMartin Sperl struct bcm2835aux_spi *bs = spi_master_get_devdata(master); 1881ea29b39SMartin Sperl irqreturn_t ret = IRQ_NONE; 1891ea29b39SMartin Sperl 1901ea29b39SMartin Sperl /* check if we have data to read */ 1911ea29b39SMartin Sperl while (bs->rx_len && 1921ea29b39SMartin Sperl (!(bcm2835aux_rd(bs, BCM2835_AUX_SPI_STAT) & 1931ea29b39SMartin Sperl BCM2835_AUX_SPI_STAT_RX_EMPTY))) { 1941ea29b39SMartin Sperl bcm2835aux_rd_fifo(bs); 1951ea29b39SMartin Sperl ret = IRQ_HANDLED; 1961ea29b39SMartin Sperl } 1971ea29b39SMartin Sperl 1981ea29b39SMartin Sperl /* check if we have data to write */ 1991ea29b39SMartin Sperl while (bs->tx_len && 20072aac02bSMartin Sperl (bs->pending < 12) && 2011ea29b39SMartin Sperl (!(bcm2835aux_rd(bs, BCM2835_AUX_SPI_STAT) & 2021ea29b39SMartin Sperl BCM2835_AUX_SPI_STAT_TX_FULL))) { 2031ea29b39SMartin Sperl bcm2835aux_wr_fifo(bs); 2041ea29b39SMartin Sperl ret = IRQ_HANDLED; 2051ea29b39SMartin Sperl } 2061ea29b39SMartin Sperl 2071ea29b39SMartin Sperl /* and check if we have reached "done" */ 2081ea29b39SMartin Sperl while (bs->rx_len && 2091ea29b39SMartin Sperl (!(bcm2835aux_rd(bs, BCM2835_AUX_SPI_STAT) & 2101ea29b39SMartin Sperl BCM2835_AUX_SPI_STAT_BUSY))) { 2111ea29b39SMartin Sperl bcm2835aux_rd_fifo(bs); 2121ea29b39SMartin Sperl ret = IRQ_HANDLED; 2131ea29b39SMartin Sperl } 2141ea29b39SMartin Sperl 2151ea29b39SMartin Sperl /* and if rx_len is 0 then wake up completion and disable spi */ 2161ea29b39SMartin Sperl if (!bs->rx_len) { 2171ea29b39SMartin Sperl bcm2835aux_spi_reset_hw(bs); 2181ea29b39SMartin Sperl complete(&master->xfer_completion); 2191ea29b39SMartin Sperl } 2201ea29b39SMartin Sperl 2211ea29b39SMartin Sperl /* and return */ 2221ea29b39SMartin Sperl return ret; 2231ea29b39SMartin Sperl } 2241ea29b39SMartin Sperl 2251ea29b39SMartin Sperl static int __bcm2835aux_spi_transfer_one_irq(struct spi_master *master, 2261ea29b39SMartin Sperl struct spi_device *spi, 2271ea29b39SMartin Sperl struct spi_transfer *tfr) 2281ea29b39SMartin Sperl { 2291ea29b39SMartin Sperl struct bcm2835aux_spi *bs = spi_master_get_devdata(master); 2301ea29b39SMartin Sperl 2311ea29b39SMartin Sperl /* enable interrupts */ 2321ea29b39SMartin Sperl bcm2835aux_wr(bs, BCM2835_AUX_SPI_CNTL1, bs->cntl[1] | 2331ea29b39SMartin Sperl BCM2835_AUX_SPI_CNTL1_TXEMPTY | 2341ea29b39SMartin Sperl BCM2835_AUX_SPI_CNTL1_IDLE); 2351ea29b39SMartin Sperl 2361ea29b39SMartin Sperl /* and wait for finish... */ 2371ea29b39SMartin Sperl return 1; 2381ea29b39SMartin Sperl } 2391ea29b39SMartin Sperl 2401ea29b39SMartin Sperl static int bcm2835aux_spi_transfer_one_irq(struct spi_master *master, 2411ea29b39SMartin Sperl struct spi_device *spi, 2421ea29b39SMartin Sperl struct spi_transfer *tfr) 2431ea29b39SMartin Sperl { 2441ea29b39SMartin Sperl struct bcm2835aux_spi *bs = spi_master_get_devdata(master); 2451ea29b39SMartin Sperl 2461ea29b39SMartin Sperl /* fill in registers and fifos before enabling interrupts */ 2471ea29b39SMartin Sperl bcm2835aux_wr(bs, BCM2835_AUX_SPI_CNTL1, bs->cntl[1]); 2481ea29b39SMartin Sperl bcm2835aux_wr(bs, BCM2835_AUX_SPI_CNTL0, bs->cntl[0]); 2491ea29b39SMartin Sperl 2501ea29b39SMartin Sperl /* fill in tx fifo with data before enabling interrupts */ 2511ea29b39SMartin Sperl while ((bs->tx_len) && 25272aac02bSMartin Sperl (bs->pending < 12) && 2531ea29b39SMartin Sperl (!(bcm2835aux_rd(bs, BCM2835_AUX_SPI_STAT) & 2541ea29b39SMartin Sperl BCM2835_AUX_SPI_STAT_TX_FULL))) { 2551ea29b39SMartin Sperl bcm2835aux_wr_fifo(bs); 2561ea29b39SMartin Sperl } 2571ea29b39SMartin Sperl 2581ea29b39SMartin Sperl /* now run the interrupt mode */ 2591ea29b39SMartin Sperl return __bcm2835aux_spi_transfer_one_irq(master, spi, tfr); 2601ea29b39SMartin Sperl } 2611ea29b39SMartin Sperl 2621ea29b39SMartin Sperl static int bcm2835aux_spi_transfer_one_poll(struct spi_master *master, 2631ea29b39SMartin Sperl struct spi_device *spi, 26472aac02bSMartin Sperl struct spi_transfer *tfr) 2651ea29b39SMartin Sperl { 2661ea29b39SMartin Sperl struct bcm2835aux_spi *bs = spi_master_get_devdata(master); 2671ea29b39SMartin Sperl unsigned long timeout; 2681ea29b39SMartin Sperl u32 stat; 2691ea29b39SMartin Sperl 2701ea29b39SMartin Sperl /* configure spi */ 2711ea29b39SMartin Sperl bcm2835aux_wr(bs, BCM2835_AUX_SPI_CNTL1, bs->cntl[1]); 2721ea29b39SMartin Sperl bcm2835aux_wr(bs, BCM2835_AUX_SPI_CNTL0, bs->cntl[0]); 2731ea29b39SMartin Sperl 2741ea29b39SMartin Sperl /* set the timeout */ 2751ea29b39SMartin Sperl timeout = jiffies + BCM2835_AUX_SPI_POLLING_JIFFIES; 2761ea29b39SMartin Sperl 2771ea29b39SMartin Sperl /* loop until finished the transfer */ 2781ea29b39SMartin Sperl while (bs->rx_len) { 2791ea29b39SMartin Sperl /* read status */ 2801ea29b39SMartin Sperl stat = bcm2835aux_rd(bs, BCM2835_AUX_SPI_STAT); 2811ea29b39SMartin Sperl 2821ea29b39SMartin Sperl /* fill in tx fifo with remaining data */ 2831ea29b39SMartin Sperl if ((bs->tx_len) && (!(stat & BCM2835_AUX_SPI_STAT_TX_FULL))) { 2841ea29b39SMartin Sperl bcm2835aux_wr_fifo(bs); 2851ea29b39SMartin Sperl continue; 2861ea29b39SMartin Sperl } 2871ea29b39SMartin Sperl 2881ea29b39SMartin Sperl /* read data from fifo for both cases */ 2891ea29b39SMartin Sperl if (!(stat & BCM2835_AUX_SPI_STAT_RX_EMPTY)) { 2901ea29b39SMartin Sperl bcm2835aux_rd_fifo(bs); 2911ea29b39SMartin Sperl continue; 2921ea29b39SMartin Sperl } 2931ea29b39SMartin Sperl if (!(stat & BCM2835_AUX_SPI_STAT_BUSY)) { 2941ea29b39SMartin Sperl bcm2835aux_rd_fifo(bs); 2951ea29b39SMartin Sperl continue; 2961ea29b39SMartin Sperl } 2971ea29b39SMartin Sperl 2981ea29b39SMartin Sperl /* there is still data pending to read check the timeout */ 2991ea29b39SMartin Sperl if (bs->rx_len && time_after(jiffies, timeout)) { 3001ea29b39SMartin Sperl dev_dbg_ratelimited(&spi->dev, 3011ea29b39SMartin Sperl "timeout period reached: jiffies: %lu remaining tx/rx: %d/%d - falling back to interrupt mode\n", 3021ea29b39SMartin Sperl jiffies - timeout, 3031ea29b39SMartin Sperl bs->tx_len, bs->rx_len); 3041ea29b39SMartin Sperl /* forward to interrupt handler */ 3051ea29b39SMartin Sperl return __bcm2835aux_spi_transfer_one_irq(master, 3061ea29b39SMartin Sperl spi, tfr); 3071ea29b39SMartin Sperl } 3081ea29b39SMartin Sperl } 3091ea29b39SMartin Sperl 3101ea29b39SMartin Sperl /* Transfer complete - reset SPI HW */ 3111ea29b39SMartin Sperl bcm2835aux_spi_reset_hw(bs); 3121ea29b39SMartin Sperl 3131ea29b39SMartin Sperl /* and return without waiting for completion */ 3141ea29b39SMartin Sperl return 0; 3151ea29b39SMartin Sperl } 3161ea29b39SMartin Sperl 3171ea29b39SMartin Sperl static int bcm2835aux_spi_transfer_one(struct spi_master *master, 3181ea29b39SMartin Sperl struct spi_device *spi, 3191ea29b39SMartin Sperl struct spi_transfer *tfr) 3201ea29b39SMartin Sperl { 3211ea29b39SMartin Sperl struct bcm2835aux_spi *bs = spi_master_get_devdata(master); 3221ea29b39SMartin Sperl unsigned long spi_hz, clk_hz, speed; 32372aac02bSMartin Sperl unsigned long spi_used_hz; 32472aac02bSMartin Sperl unsigned long long xfer_time_us; 3251ea29b39SMartin Sperl 3261ea29b39SMartin Sperl /* calculate the registers to handle 3271ea29b39SMartin Sperl * 3281ea29b39SMartin Sperl * note that we use the variable data mode, which 3291ea29b39SMartin Sperl * is not optimal for longer transfers as we waste registers 3301ea29b39SMartin Sperl * resulting (potentially) in more interrupts when transferring 3311ea29b39SMartin Sperl * more than 12 bytes 3321ea29b39SMartin Sperl */ 3331ea29b39SMartin Sperl bs->cntl[0] = BCM2835_AUX_SPI_CNTL0_ENABLE | 3341ea29b39SMartin Sperl BCM2835_AUX_SPI_CNTL0_VAR_WIDTH | 3351ea29b39SMartin Sperl BCM2835_AUX_SPI_CNTL0_MSBF_OUT; 3361ea29b39SMartin Sperl bs->cntl[1] = BCM2835_AUX_SPI_CNTL1_MSBF_IN; 3371ea29b39SMartin Sperl 3381ea29b39SMartin Sperl /* set clock */ 3391ea29b39SMartin Sperl spi_hz = tfr->speed_hz; 3401ea29b39SMartin Sperl clk_hz = clk_get_rate(bs->clk); 3411ea29b39SMartin Sperl 3421ea29b39SMartin Sperl if (spi_hz >= clk_hz / 2) { 3431ea29b39SMartin Sperl speed = 0; 3441ea29b39SMartin Sperl } else if (spi_hz) { 3451ea29b39SMartin Sperl speed = DIV_ROUND_UP(clk_hz, 2 * spi_hz) - 1; 3461ea29b39SMartin Sperl if (speed > BCM2835_AUX_SPI_CNTL0_SPEED_MAX) 3471ea29b39SMartin Sperl speed = BCM2835_AUX_SPI_CNTL0_SPEED_MAX; 3481ea29b39SMartin Sperl } else { /* the slowest we can go */ 3491ea29b39SMartin Sperl speed = BCM2835_AUX_SPI_CNTL0_SPEED_MAX; 3501ea29b39SMartin Sperl } 3511ea29b39SMartin Sperl bs->cntl[0] |= speed << BCM2835_AUX_SPI_CNTL0_SPEED_SHIFT; 3521ea29b39SMartin Sperl 3531ea29b39SMartin Sperl spi_used_hz = clk_hz / (2 * (speed + 1)); 3541ea29b39SMartin Sperl 3551ea29b39SMartin Sperl /* handle all the modes */ 3561ea29b39SMartin Sperl if (spi->mode & SPI_CPOL) 3571ea29b39SMartin Sperl bs->cntl[0] |= BCM2835_AUX_SPI_CNTL0_CPOL; 3581ea29b39SMartin Sperl if (spi->mode & SPI_CPHA) 3591ea29b39SMartin Sperl bs->cntl[0] |= BCM2835_AUX_SPI_CNTL0_CPHA_OUT | 3601ea29b39SMartin Sperl BCM2835_AUX_SPI_CNTL0_CPHA_IN; 3611ea29b39SMartin Sperl 3621ea29b39SMartin Sperl /* set transmit buffers and length */ 3631ea29b39SMartin Sperl bs->tx_buf = tfr->tx_buf; 3641ea29b39SMartin Sperl bs->rx_buf = tfr->rx_buf; 3651ea29b39SMartin Sperl bs->tx_len = tfr->len; 3661ea29b39SMartin Sperl bs->rx_len = tfr->len; 36772aac02bSMartin Sperl bs->pending = 0; 3681ea29b39SMartin Sperl 36972aac02bSMartin Sperl /* calculate the estimated time in us the transfer runs 37072aac02bSMartin Sperl * note that there are are 2 idle clocks after each 37172aac02bSMartin Sperl * chunk getting transferred - in our case the chunk size 37272aac02bSMartin Sperl * is 3 bytes, so we approximate this by 9 bits/byte 37372aac02bSMartin Sperl */ 37472aac02bSMartin Sperl xfer_time_us = tfr->len * 9 * 1000000; 37572aac02bSMartin Sperl do_div(xfer_time_us, spi_used_hz); 3761ea29b39SMartin Sperl 3771ea29b39SMartin Sperl /* run in polling mode for short transfers */ 3781ea29b39SMartin Sperl if (xfer_time_us < BCM2835_AUX_SPI_POLLING_LIMIT_US) 37972aac02bSMartin Sperl return bcm2835aux_spi_transfer_one_poll(master, spi, tfr); 3801ea29b39SMartin Sperl 3811ea29b39SMartin Sperl /* run in interrupt mode for all others */ 3821ea29b39SMartin Sperl return bcm2835aux_spi_transfer_one_irq(master, spi, tfr); 3831ea29b39SMartin Sperl } 3841ea29b39SMartin Sperl 3851ea29b39SMartin Sperl static void bcm2835aux_spi_handle_err(struct spi_master *master, 3861ea29b39SMartin Sperl struct spi_message *msg) 3871ea29b39SMartin Sperl { 3881ea29b39SMartin Sperl struct bcm2835aux_spi *bs = spi_master_get_devdata(master); 3891ea29b39SMartin Sperl 3901ea29b39SMartin Sperl bcm2835aux_spi_reset_hw(bs); 3911ea29b39SMartin Sperl } 3921ea29b39SMartin Sperl 3931ea29b39SMartin Sperl static int bcm2835aux_spi_probe(struct platform_device *pdev) 3941ea29b39SMartin Sperl { 3951ea29b39SMartin Sperl struct spi_master *master; 3961ea29b39SMartin Sperl struct bcm2835aux_spi *bs; 3971ea29b39SMartin Sperl struct resource *res; 3981ea29b39SMartin Sperl unsigned long clk_hz; 3991ea29b39SMartin Sperl int err; 4001ea29b39SMartin Sperl 4011ea29b39SMartin Sperl master = spi_alloc_master(&pdev->dev, sizeof(*bs)); 4021ea29b39SMartin Sperl if (!master) { 4031ea29b39SMartin Sperl dev_err(&pdev->dev, "spi_alloc_master() failed\n"); 4041ea29b39SMartin Sperl return -ENOMEM; 4051ea29b39SMartin Sperl } 4061ea29b39SMartin Sperl 4071ea29b39SMartin Sperl platform_set_drvdata(pdev, master); 4081ea29b39SMartin Sperl master->mode_bits = BCM2835_AUX_SPI_MODE_BITS; 4091ea29b39SMartin Sperl master->bits_per_word_mask = SPI_BPW_MASK(8); 4101ea29b39SMartin Sperl master->num_chipselect = -1; 4111ea29b39SMartin Sperl master->transfer_one = bcm2835aux_spi_transfer_one; 4121ea29b39SMartin Sperl master->handle_err = bcm2835aux_spi_handle_err; 4131ea29b39SMartin Sperl master->dev.of_node = pdev->dev.of_node; 4141ea29b39SMartin Sperl 4151ea29b39SMartin Sperl bs = spi_master_get_devdata(master); 4161ea29b39SMartin Sperl 4171ea29b39SMartin Sperl /* the main area */ 4181ea29b39SMartin Sperl res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 4191ea29b39SMartin Sperl bs->regs = devm_ioremap_resource(&pdev->dev, res); 4201ea29b39SMartin Sperl if (IS_ERR(bs->regs)) { 4211ea29b39SMartin Sperl err = PTR_ERR(bs->regs); 4221ea29b39SMartin Sperl goto out_master_put; 4231ea29b39SMartin Sperl } 4241ea29b39SMartin Sperl 4251ea29b39SMartin Sperl bs->clk = devm_clk_get(&pdev->dev, NULL); 4261ea29b39SMartin Sperl if ((!bs->clk) || (IS_ERR(bs->clk))) { 4271ea29b39SMartin Sperl err = PTR_ERR(bs->clk); 4281ea29b39SMartin Sperl dev_err(&pdev->dev, "could not get clk: %d\n", err); 4291ea29b39SMartin Sperl goto out_master_put; 4301ea29b39SMartin Sperl } 4311ea29b39SMartin Sperl 43207bce09eSMartin Sperl bs->irq = platform_get_irq(pdev, 0); 4331ea29b39SMartin Sperl if (bs->irq <= 0) { 4341ea29b39SMartin Sperl dev_err(&pdev->dev, "could not get IRQ: %d\n", bs->irq); 4351ea29b39SMartin Sperl err = bs->irq ? bs->irq : -ENODEV; 4361ea29b39SMartin Sperl goto out_master_put; 4371ea29b39SMartin Sperl } 4381ea29b39SMartin Sperl 4391ea29b39SMartin Sperl /* this also enables the HW block */ 4401ea29b39SMartin Sperl err = clk_prepare_enable(bs->clk); 4411ea29b39SMartin Sperl if (err) { 4421ea29b39SMartin Sperl dev_err(&pdev->dev, "could not prepare clock: %d\n", err); 4431ea29b39SMartin Sperl goto out_master_put; 4441ea29b39SMartin Sperl } 4451ea29b39SMartin Sperl 4461ea29b39SMartin Sperl /* just checking if the clock returns a sane value */ 4471ea29b39SMartin Sperl clk_hz = clk_get_rate(bs->clk); 4481ea29b39SMartin Sperl if (!clk_hz) { 4491ea29b39SMartin Sperl dev_err(&pdev->dev, "clock returns 0 Hz\n"); 4501ea29b39SMartin Sperl err = -ENODEV; 4511ea29b39SMartin Sperl goto out_clk_disable; 4521ea29b39SMartin Sperl } 4531ea29b39SMartin Sperl 45407bce09eSMartin Sperl /* reset SPI-HW block */ 45507bce09eSMartin Sperl bcm2835aux_spi_reset_hw(bs); 45607bce09eSMartin Sperl 4571ea29b39SMartin Sperl err = devm_request_irq(&pdev->dev, bs->irq, 4581ea29b39SMartin Sperl bcm2835aux_spi_interrupt, 4591ea29b39SMartin Sperl IRQF_SHARED, 4601ea29b39SMartin Sperl dev_name(&pdev->dev), master); 4611ea29b39SMartin Sperl if (err) { 4621ea29b39SMartin Sperl dev_err(&pdev->dev, "could not request IRQ: %d\n", err); 4631ea29b39SMartin Sperl goto out_clk_disable; 4641ea29b39SMartin Sperl } 4651ea29b39SMartin Sperl 4661ea29b39SMartin Sperl err = devm_spi_register_master(&pdev->dev, master); 4671ea29b39SMartin Sperl if (err) { 4681ea29b39SMartin Sperl dev_err(&pdev->dev, "could not register SPI master: %d\n", err); 4691ea29b39SMartin Sperl goto out_clk_disable; 4701ea29b39SMartin Sperl } 4711ea29b39SMartin Sperl 4721ea29b39SMartin Sperl return 0; 4731ea29b39SMartin Sperl 4741ea29b39SMartin Sperl out_clk_disable: 4751ea29b39SMartin Sperl clk_disable_unprepare(bs->clk); 4761ea29b39SMartin Sperl out_master_put: 4771ea29b39SMartin Sperl spi_master_put(master); 4781ea29b39SMartin Sperl return err; 4791ea29b39SMartin Sperl } 4801ea29b39SMartin Sperl 4811ea29b39SMartin Sperl static int bcm2835aux_spi_remove(struct platform_device *pdev) 4821ea29b39SMartin Sperl { 4831ea29b39SMartin Sperl struct spi_master *master = platform_get_drvdata(pdev); 4841ea29b39SMartin Sperl struct bcm2835aux_spi *bs = spi_master_get_devdata(master); 4851ea29b39SMartin Sperl 4861ea29b39SMartin Sperl bcm2835aux_spi_reset_hw(bs); 4871ea29b39SMartin Sperl 4881ea29b39SMartin Sperl /* disable the HW block by releasing the clock */ 4891ea29b39SMartin Sperl clk_disable_unprepare(bs->clk); 4901ea29b39SMartin Sperl 4911ea29b39SMartin Sperl return 0; 4921ea29b39SMartin Sperl } 4931ea29b39SMartin Sperl 4941ea29b39SMartin Sperl static const struct of_device_id bcm2835aux_spi_match[] = { 4951ea29b39SMartin Sperl { .compatible = "brcm,bcm2835-aux-spi", }, 4961ea29b39SMartin Sperl {} 4971ea29b39SMartin Sperl }; 4981ea29b39SMartin Sperl MODULE_DEVICE_TABLE(of, bcm2835aux_spi_match); 4991ea29b39SMartin Sperl 5001ea29b39SMartin Sperl static struct platform_driver bcm2835aux_spi_driver = { 5011ea29b39SMartin Sperl .driver = { 5021ea29b39SMartin Sperl .name = "spi-bcm2835aux", 5031ea29b39SMartin Sperl .of_match_table = bcm2835aux_spi_match, 5041ea29b39SMartin Sperl }, 5051ea29b39SMartin Sperl .probe = bcm2835aux_spi_probe, 5061ea29b39SMartin Sperl .remove = bcm2835aux_spi_remove, 5071ea29b39SMartin Sperl }; 5081ea29b39SMartin Sperl module_platform_driver(bcm2835aux_spi_driver); 5091ea29b39SMartin Sperl 5101ea29b39SMartin Sperl MODULE_DESCRIPTION("SPI controller driver for Broadcom BCM2835 aux"); 5111ea29b39SMartin Sperl MODULE_AUTHOR("Martin Sperl <kernel@martin.sperl.org>"); 5121ea29b39SMartin Sperl MODULE_LICENSE("GPL v2"); 513