2 * Copyright (c) 2009 Nuvoton technology.
3 * Wan ZongShun <mcuos.com@gmail.com>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
11 #include <linux/module.h>
12 #include <linux/spinlock.h>
13 #include <linux/workqueue.h>
14 #include <linux/interrupt.h>
15 #include <linux/delay.h>
16 #include <linux/errno.h>
17 #include <linux/err.h>
18 #include <linux/clk.h>
19 #include <linux/device.h>
20 #include <linux/platform_device.h>
21 #include <linux/gpio.h>
23 #include <linux/slab.h>
25 #include <linux/spi/spi.h>
26 #include <linux/spi/spi_bitbang.h>
28 #include <linux/platform_data/spi-nuc900.h>
30 /* usi registers offset */
37 /* usi register bit */
38 #define ENINT (0x01 << 17)
39 #define ENFLG (0x01 << 16)
40 #define TXNUM (0x03 << 8)
41 #define TXNEG (0x01 << 2)
42 #define RXNEG (0x01 << 1)
43 #define LSB (0x01 << 10)
44 #define SELECTLEV (0x01 << 2)
45 #define SELECTPOL (0x01 << 31)
46 #define SELECTSLAVE 0x01
50 struct spi_bitbang bitbang;
51 struct completion done;
56 const unsigned char *tx;
59 struct spi_master *master;
60 struct spi_device *curdev;
62 struct nuc900_spi_info *pdata;
67 static inline struct nuc900_spi *to_hw(struct spi_device *sdev)
69 return spi_master_get_devdata(sdev->master);
72 static void nuc900_slave_select(struct spi_device *spi, unsigned int ssr)
74 struct nuc900_spi *hw = to_hw(spi);
76 unsigned int cs = spi->mode & SPI_CS_HIGH ? 1 : 0;
77 unsigned int cpol = spi->mode & SPI_CPOL ? 1 : 0;
80 spin_lock_irqsave(&hw->lock, flags);
82 val = __raw_readl(hw->regs + USI_SSR);
94 __raw_writel(val, hw->regs + USI_SSR);
96 val = __raw_readl(hw->regs + USI_CNT);
103 __raw_writel(val, hw->regs + USI_CNT);
105 spin_unlock_irqrestore(&hw->lock, flags);
108 static void nuc900_spi_chipsel(struct spi_device *spi, int value)
111 case BITBANG_CS_INACTIVE:
112 nuc900_slave_select(spi, 0);
115 case BITBANG_CS_ACTIVE:
116 nuc900_slave_select(spi, 1);
121 static void nuc900_spi_setup_txnum(struct nuc900_spi *hw,
127 spin_lock_irqsave(&hw->lock, flags);
129 val = __raw_readl(hw->regs + USI_CNT);
134 val |= txnum << 0x08;
136 __raw_writel(val, hw->regs + USI_CNT);
138 spin_unlock_irqrestore(&hw->lock, flags);
142 static void nuc900_spi_setup_txbitlen(struct nuc900_spi *hw,
143 unsigned int txbitlen)
148 spin_lock_irqsave(&hw->lock, flags);
150 val = __raw_readl(hw->regs + USI_CNT);
152 val |= (txbitlen << 0x03);
154 __raw_writel(val, hw->regs + USI_CNT);
156 spin_unlock_irqrestore(&hw->lock, flags);
159 static void nuc900_spi_gobusy(struct nuc900_spi *hw)
164 spin_lock_irqsave(&hw->lock, flags);
166 val = __raw_readl(hw->regs + USI_CNT);
170 __raw_writel(val, hw->regs + USI_CNT);
172 spin_unlock_irqrestore(&hw->lock, flags);
175 static inline unsigned int hw_txbyte(struct nuc900_spi *hw, int count)
177 return hw->tx ? hw->tx[count] : 0;
180 static int nuc900_spi_txrx(struct spi_device *spi, struct spi_transfer *t)
182 struct nuc900_spi *hw = to_hw(spi);
189 __raw_writel(hw_txbyte(hw, 0x0), hw->regs + USI_TX0);
191 nuc900_spi_gobusy(hw);
193 wait_for_completion(&hw->done);
198 static irqreturn_t nuc900_spi_irq(int irq, void *dev)
200 struct nuc900_spi *hw = dev;
202 unsigned int count = hw->count;
204 status = __raw_readl(hw->regs + USI_CNT);
205 __raw_writel(status, hw->regs + USI_CNT);
207 if (status & ENFLG) {
211 hw->rx[count] = __raw_readl(hw->regs + USI_RX0);
214 if (count < hw->len) {
215 __raw_writel(hw_txbyte(hw, count), hw->regs + USI_TX0);
216 nuc900_spi_gobusy(hw);
228 static void nuc900_tx_edge(struct nuc900_spi *hw, unsigned int edge)
233 spin_lock_irqsave(&hw->lock, flags);
235 val = __raw_readl(hw->regs + USI_CNT);
241 __raw_writel(val, hw->regs + USI_CNT);
243 spin_unlock_irqrestore(&hw->lock, flags);
246 static void nuc900_rx_edge(struct nuc900_spi *hw, unsigned int edge)
251 spin_lock_irqsave(&hw->lock, flags);
253 val = __raw_readl(hw->regs + USI_CNT);
259 __raw_writel(val, hw->regs + USI_CNT);
261 spin_unlock_irqrestore(&hw->lock, flags);
264 static void nuc900_send_first(struct nuc900_spi *hw, unsigned int lsb)
269 spin_lock_irqsave(&hw->lock, flags);
271 val = __raw_readl(hw->regs + USI_CNT);
277 __raw_writel(val, hw->regs + USI_CNT);
279 spin_unlock_irqrestore(&hw->lock, flags);
282 static void nuc900_set_sleep(struct nuc900_spi *hw, unsigned int sleep)
287 spin_lock_irqsave(&hw->lock, flags);
289 val = __raw_readl(hw->regs + USI_CNT);
292 val |= (sleep << 12);
294 val &= ~(0x0f << 12);
295 __raw_writel(val, hw->regs + USI_CNT);
297 spin_unlock_irqrestore(&hw->lock, flags);
300 static void nuc900_enable_int(struct nuc900_spi *hw)
305 spin_lock_irqsave(&hw->lock, flags);
307 val = __raw_readl(hw->regs + USI_CNT);
311 __raw_writel(val, hw->regs + USI_CNT);
313 spin_unlock_irqrestore(&hw->lock, flags);
316 static void nuc900_set_divider(struct nuc900_spi *hw)
318 __raw_writel(hw->pdata->divider, hw->regs + USI_DIV);
321 static void nuc900_init_spi(struct nuc900_spi *hw)
324 spin_lock_init(&hw->lock);
326 nuc900_tx_edge(hw, hw->pdata->txneg);
327 nuc900_rx_edge(hw, hw->pdata->rxneg);
328 nuc900_send_first(hw, hw->pdata->lsb);
329 nuc900_set_sleep(hw, hw->pdata->sleep);
330 nuc900_spi_setup_txbitlen(hw, hw->pdata->txbitlen);
331 nuc900_spi_setup_txnum(hw, hw->pdata->txnum);
332 nuc900_set_divider(hw);
333 nuc900_enable_int(hw);
336 static int nuc900_spi_probe(struct platform_device *pdev)
338 struct nuc900_spi *hw;
339 struct spi_master *master;
342 master = spi_alloc_master(&pdev->dev, sizeof(struct nuc900_spi));
343 if (master == NULL) {
344 dev_err(&pdev->dev, "No memory for spi_master\n");
348 hw = spi_master_get_devdata(master);
350 hw->pdata = dev_get_platdata(&pdev->dev);
351 hw->dev = &pdev->dev;
353 if (hw->pdata == NULL) {
354 dev_err(&pdev->dev, "No platform data supplied\n");
359 platform_set_drvdata(pdev, hw);
360 init_completion(&hw->done);
362 master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
363 master->num_chipselect = hw->pdata->num_cs;
364 master->bus_num = hw->pdata->bus_num;
365 hw->bitbang.master = hw->master;
366 hw->bitbang.chipselect = nuc900_spi_chipsel;
367 hw->bitbang.txrx_bufs = nuc900_spi_txrx;
369 hw->res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
370 hw->regs = devm_ioremap_resource(&pdev->dev, hw->res);
371 if (IS_ERR(hw->regs)) {
372 err = PTR_ERR(hw->regs);
376 hw->irq = platform_get_irq(pdev, 0);
378 dev_err(&pdev->dev, "No IRQ specified\n");
383 err = devm_request_irq(&pdev->dev, hw->irq, nuc900_spi_irq, 0,
386 dev_err(&pdev->dev, "Cannot claim IRQ\n");
390 hw->clk = devm_clk_get(&pdev->dev, "spi");
391 if (IS_ERR(hw->clk)) {
392 dev_err(&pdev->dev, "No clock for device\n");
393 err = PTR_ERR(hw->clk);
397 mfp_set_groupg(&pdev->dev, NULL);
400 err = spi_bitbang_start(&hw->bitbang);
402 dev_err(&pdev->dev, "Failed to register SPI master\n");
409 clk_disable(hw->clk);
411 spi_master_put(hw->master);
415 static int nuc900_spi_remove(struct platform_device *dev)
417 struct nuc900_spi *hw = platform_get_drvdata(dev);
419 spi_bitbang_stop(&hw->bitbang);
420 clk_disable(hw->clk);
421 spi_master_put(hw->master);
425 static struct platform_driver nuc900_spi_driver = {
426 .probe = nuc900_spi_probe,
427 .remove = nuc900_spi_remove,
429 .name = "nuc900-spi",
430 .owner = THIS_MODULE,
433 module_platform_driver(nuc900_spi_driver);
435 MODULE_AUTHOR("Wan ZongShun <mcuos.com@gmail.com>");
436 MODULE_DESCRIPTION("nuc900 spi driver!");
437 MODULE_LICENSE("GPL");
438 MODULE_ALIAS("platform:nuc900-spi");