1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * OpenCores tiny SPI master driver 4 * 5 * http://opencores.org/project,tiny_spi 6 * 7 * Copyright (C) 2011 Thomas Chou <thomas@wytron.com.tw> 8 * 9 * Based on spi_s3c24xx.c, which is: 10 * Copyright (c) 2006 Ben Dooks 11 * Copyright (c) 2006 Simtec Electronics 12 * Ben Dooks <ben@simtec.co.uk> 13 */ 14 15 #include <linux/interrupt.h> 16 #include <linux/errno.h> 17 #include <linux/module.h> 18 #include <linux/platform_device.h> 19 #include <linux/spi/spi.h> 20 #include <linux/spi/spi_bitbang.h> 21 #include <linux/spi/spi_oc_tiny.h> 22 #include <linux/io.h> 23 #include <linux/gpio.h> 24 #include <linux/of.h> 25 26 #define DRV_NAME "spi_oc_tiny" 27 28 #define TINY_SPI_RXDATA 0 29 #define TINY_SPI_TXDATA 4 30 #define TINY_SPI_STATUS 8 31 #define TINY_SPI_CONTROL 12 32 #define TINY_SPI_BAUD 16 33 34 #define TINY_SPI_STATUS_TXE 0x1 35 #define TINY_SPI_STATUS_TXR 0x2 36 37 struct tiny_spi { 38 /* bitbang has to be first */ 39 struct spi_bitbang bitbang; 40 struct completion done; 41 42 void __iomem *base; 43 int irq; 44 unsigned int freq; 45 unsigned int baudwidth; 46 unsigned int baud; 47 unsigned int speed_hz; 48 unsigned int mode; 49 unsigned int len; 50 unsigned int txc, rxc; 51 const u8 *txp; 52 u8 *rxp; 53 int gpio_cs_count; 54 int *gpio_cs; 55 }; 56 57 static inline struct tiny_spi *tiny_spi_to_hw(struct spi_device *sdev) 58 { 59 return spi_master_get_devdata(sdev->master); 60 } 61 62 static unsigned int tiny_spi_baud(struct spi_device *spi, unsigned int hz) 63 { 64 struct tiny_spi *hw = tiny_spi_to_hw(spi); 65 66 return min(DIV_ROUND_UP(hw->freq, hz * 2), (1U << hw->baudwidth)) - 1; 67 } 68 69 static void tiny_spi_chipselect(struct spi_device *spi, int is_active) 70 { 71 struct tiny_spi *hw = tiny_spi_to_hw(spi); 72 73 if (hw->gpio_cs_count > 0) { 74 gpio_set_value(hw->gpio_cs[spi->chip_select], 75 (spi->mode & SPI_CS_HIGH) ? is_active : !is_active); 76 } 77 } 78 79 static int tiny_spi_setup_transfer(struct spi_device *spi, 80 struct spi_transfer *t) 81 { 82 struct tiny_spi *hw = tiny_spi_to_hw(spi); 83 unsigned int baud = hw->baud; 84 85 if (t) { 86 if (t->speed_hz && t->speed_hz != hw->speed_hz) 87 baud = tiny_spi_baud(spi, t->speed_hz); 88 } 89 writel(baud, hw->base + TINY_SPI_BAUD); 90 writel(hw->mode, hw->base + TINY_SPI_CONTROL); 91 return 0; 92 } 93 94 static int tiny_spi_setup(struct spi_device *spi) 95 { 96 struct tiny_spi *hw = tiny_spi_to_hw(spi); 97 98 if (spi->max_speed_hz != hw->speed_hz) { 99 hw->speed_hz = spi->max_speed_hz; 100 hw->baud = tiny_spi_baud(spi, hw->speed_hz); 101 } 102 hw->mode = spi->mode & (SPI_CPOL | SPI_CPHA); 103 return 0; 104 } 105 106 static inline void tiny_spi_wait_txr(struct tiny_spi *hw) 107 { 108 while (!(readb(hw->base + TINY_SPI_STATUS) & 109 TINY_SPI_STATUS_TXR)) 110 cpu_relax(); 111 } 112 113 static inline void tiny_spi_wait_txe(struct tiny_spi *hw) 114 { 115 while (!(readb(hw->base + TINY_SPI_STATUS) & 116 TINY_SPI_STATUS_TXE)) 117 cpu_relax(); 118 } 119 120 static int tiny_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t) 121 { 122 struct tiny_spi *hw = tiny_spi_to_hw(spi); 123 const u8 *txp = t->tx_buf; 124 u8 *rxp = t->rx_buf; 125 unsigned int i; 126 127 if (hw->irq >= 0) { 128 /* use interrupt driven data transfer */ 129 hw->len = t->len; 130 hw->txp = t->tx_buf; 131 hw->rxp = t->rx_buf; 132 hw->txc = 0; 133 hw->rxc = 0; 134 135 /* send the first byte */ 136 if (t->len > 1) { 137 writeb(hw->txp ? *hw->txp++ : 0, 138 hw->base + TINY_SPI_TXDATA); 139 hw->txc++; 140 writeb(hw->txp ? *hw->txp++ : 0, 141 hw->base + TINY_SPI_TXDATA); 142 hw->txc++; 143 writeb(TINY_SPI_STATUS_TXR, hw->base + TINY_SPI_STATUS); 144 } else { 145 writeb(hw->txp ? *hw->txp++ : 0, 146 hw->base + TINY_SPI_TXDATA); 147 hw->txc++; 148 writeb(TINY_SPI_STATUS_TXE, hw->base + TINY_SPI_STATUS); 149 } 150 151 wait_for_completion(&hw->done); 152 } else { 153 /* we need to tighten the transfer loop */ 154 writeb(txp ? *txp++ : 0, hw->base + TINY_SPI_TXDATA); 155 for (i = 1; i < t->len; i++) { 156 writeb(txp ? *txp++ : 0, hw->base + TINY_SPI_TXDATA); 157 158 if (rxp || (i != t->len - 1)) 159 tiny_spi_wait_txr(hw); 160 if (rxp) 161 *rxp++ = readb(hw->base + TINY_SPI_TXDATA); 162 } 163 tiny_spi_wait_txe(hw); 164 if (rxp) 165 *rxp++ = readb(hw->base + TINY_SPI_RXDATA); 166 } 167 168 return t->len; 169 } 170 171 static irqreturn_t tiny_spi_irq(int irq, void *dev) 172 { 173 struct tiny_spi *hw = dev; 174 175 writeb(0, hw->base + TINY_SPI_STATUS); 176 if (hw->rxc + 1 == hw->len) { 177 if (hw->rxp) 178 *hw->rxp++ = readb(hw->base + TINY_SPI_RXDATA); 179 hw->rxc++; 180 complete(&hw->done); 181 } else { 182 if (hw->rxp) 183 *hw->rxp++ = readb(hw->base + TINY_SPI_TXDATA); 184 hw->rxc++; 185 if (hw->txc < hw->len) { 186 writeb(hw->txp ? *hw->txp++ : 0, 187 hw->base + TINY_SPI_TXDATA); 188 hw->txc++; 189 writeb(TINY_SPI_STATUS_TXR, 190 hw->base + TINY_SPI_STATUS); 191 } else { 192 writeb(TINY_SPI_STATUS_TXE, 193 hw->base + TINY_SPI_STATUS); 194 } 195 } 196 return IRQ_HANDLED; 197 } 198 199 #ifdef CONFIG_OF 200 #include <linux/of_gpio.h> 201 202 static int tiny_spi_of_probe(struct platform_device *pdev) 203 { 204 struct tiny_spi *hw = platform_get_drvdata(pdev); 205 struct device_node *np = pdev->dev.of_node; 206 unsigned int i; 207 u32 val; 208 209 if (!np) 210 return 0; 211 hw->gpio_cs_count = of_gpio_count(np); 212 if (hw->gpio_cs_count > 0) { 213 hw->gpio_cs = devm_kcalloc(&pdev->dev, 214 hw->gpio_cs_count, sizeof(unsigned int), 215 GFP_KERNEL); 216 if (!hw->gpio_cs) 217 return -ENOMEM; 218 } 219 for (i = 0; i < hw->gpio_cs_count; i++) { 220 hw->gpio_cs[i] = of_get_gpio_flags(np, i, NULL); 221 if (hw->gpio_cs[i] < 0) 222 return -ENODEV; 223 } 224 hw->bitbang.master->dev.of_node = pdev->dev.of_node; 225 if (!of_property_read_u32(np, "clock-frequency", &val)) 226 hw->freq = val; 227 if (!of_property_read_u32(np, "baud-width", &val)) 228 hw->baudwidth = val; 229 return 0; 230 } 231 #else /* !CONFIG_OF */ 232 static int tiny_spi_of_probe(struct platform_device *pdev) 233 { 234 return 0; 235 } 236 #endif /* CONFIG_OF */ 237 238 static int tiny_spi_probe(struct platform_device *pdev) 239 { 240 struct tiny_spi_platform_data *platp = dev_get_platdata(&pdev->dev); 241 struct tiny_spi *hw; 242 struct spi_master *master; 243 struct resource *res; 244 unsigned int i; 245 int err = -ENODEV; 246 247 master = spi_alloc_master(&pdev->dev, sizeof(struct tiny_spi)); 248 if (!master) 249 return err; 250 251 /* setup the master state. */ 252 master->bus_num = pdev->id; 253 master->num_chipselect = 255; 254 master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; 255 master->setup = tiny_spi_setup; 256 257 hw = spi_master_get_devdata(master); 258 platform_set_drvdata(pdev, hw); 259 260 /* setup the state for the bitbang driver */ 261 hw->bitbang.master = master; 262 hw->bitbang.setup_transfer = tiny_spi_setup_transfer; 263 hw->bitbang.chipselect = tiny_spi_chipselect; 264 hw->bitbang.txrx_bufs = tiny_spi_txrx_bufs; 265 266 /* find and map our resources */ 267 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 268 hw->base = devm_ioremap_resource(&pdev->dev, res); 269 if (IS_ERR(hw->base)) { 270 err = PTR_ERR(hw->base); 271 goto exit; 272 } 273 /* irq is optional */ 274 hw->irq = platform_get_irq(pdev, 0); 275 if (hw->irq >= 0) { 276 init_completion(&hw->done); 277 err = devm_request_irq(&pdev->dev, hw->irq, tiny_spi_irq, 0, 278 pdev->name, hw); 279 if (err) 280 goto exit; 281 } 282 /* find platform data */ 283 if (platp) { 284 hw->gpio_cs_count = platp->gpio_cs_count; 285 hw->gpio_cs = platp->gpio_cs; 286 if (platp->gpio_cs_count && !platp->gpio_cs) { 287 err = -EBUSY; 288 goto exit; 289 } 290 hw->freq = platp->freq; 291 hw->baudwidth = platp->baudwidth; 292 } else { 293 err = tiny_spi_of_probe(pdev); 294 if (err) 295 goto exit; 296 } 297 for (i = 0; i < hw->gpio_cs_count; i++) { 298 err = gpio_request(hw->gpio_cs[i], dev_name(&pdev->dev)); 299 if (err) 300 goto exit_gpio; 301 gpio_direction_output(hw->gpio_cs[i], 1); 302 } 303 hw->bitbang.master->num_chipselect = max(1, hw->gpio_cs_count); 304 305 /* register our spi controller */ 306 err = spi_bitbang_start(&hw->bitbang); 307 if (err) 308 goto exit; 309 dev_info(&pdev->dev, "base %p, irq %d\n", hw->base, hw->irq); 310 311 return 0; 312 313 exit_gpio: 314 while (i-- > 0) 315 gpio_free(hw->gpio_cs[i]); 316 exit: 317 spi_master_put(master); 318 return err; 319 } 320 321 static int tiny_spi_remove(struct platform_device *pdev) 322 { 323 struct tiny_spi *hw = platform_get_drvdata(pdev); 324 struct spi_master *master = hw->bitbang.master; 325 unsigned int i; 326 327 spi_bitbang_stop(&hw->bitbang); 328 for (i = 0; i < hw->gpio_cs_count; i++) 329 gpio_free(hw->gpio_cs[i]); 330 spi_master_put(master); 331 return 0; 332 } 333 334 #ifdef CONFIG_OF 335 static const struct of_device_id tiny_spi_match[] = { 336 { .compatible = "opencores,tiny-spi-rtlsvn2", }, 337 {}, 338 }; 339 MODULE_DEVICE_TABLE(of, tiny_spi_match); 340 #endif /* CONFIG_OF */ 341 342 static struct platform_driver tiny_spi_driver = { 343 .probe = tiny_spi_probe, 344 .remove = tiny_spi_remove, 345 .driver = { 346 .name = DRV_NAME, 347 .pm = NULL, 348 .of_match_table = of_match_ptr(tiny_spi_match), 349 }, 350 }; 351 module_platform_driver(tiny_spi_driver); 352 353 MODULE_DESCRIPTION("OpenCores tiny SPI driver"); 354 MODULE_AUTHOR("Thomas Chou <thomas@wytron.com.tw>"); 355 MODULE_LICENSE("GPL"); 356 MODULE_ALIAS("platform:" DRV_NAME); 357