Merge branch 'for_linus' of git://cavan.codon.org.uk/platform-drivers-x86
[pandora-kernel.git] / drivers / spi / spi-nuc900.c
1 /*
2  * Copyright (c) 2009 Nuvoton technology.
3  * Wan ZongShun <mcuos.com@gmail.com>
4  *
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.
8  *
9  */
10
11 #include <linux/init.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>
22 #include <linux/io.h>
23 #include <linux/slab.h>
24
25 #include <linux/spi/spi.h>
26 #include <linux/spi/spi_bitbang.h>
27
28 #include <mach/nuc900_spi.h>
29
30 /* usi registers offset */
31 #define USI_CNT         0x00
32 #define USI_DIV         0x04
33 #define USI_SSR         0x08
34 #define USI_RX0         0x10
35 #define USI_TX0         0x10
36
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
47 #define GOBUSY          0x01
48
49 struct nuc900_spi {
50         struct spi_bitbang       bitbang;
51         struct completion        done;
52         void __iomem            *regs;
53         int                      irq;
54         int                      len;
55         int                      count;
56         const unsigned char     *tx;
57         unsigned char           *rx;
58         struct clk              *clk;
59         struct resource         *ioarea;
60         struct spi_master       *master;
61         struct spi_device       *curdev;
62         struct device           *dev;
63         struct nuc900_spi_info *pdata;
64         spinlock_t              lock;
65         struct resource         *res;
66 };
67
68 static inline struct nuc900_spi *to_hw(struct spi_device *sdev)
69 {
70         return spi_master_get_devdata(sdev->master);
71 }
72
73 static void nuc900_slave_select(struct spi_device *spi, unsigned int ssr)
74 {
75         struct nuc900_spi *hw = to_hw(spi);
76         unsigned int val;
77         unsigned int cs = spi->mode & SPI_CS_HIGH ? 1 : 0;
78         unsigned int cpol = spi->mode & SPI_CPOL ? 1 : 0;
79         unsigned long flags;
80
81         spin_lock_irqsave(&hw->lock, flags);
82
83         val = __raw_readl(hw->regs + USI_SSR);
84
85         if (!cs)
86                 val &= ~SELECTLEV;
87         else
88                 val |= SELECTLEV;
89
90         if (!ssr)
91                 val &= ~SELECTSLAVE;
92         else
93                 val |= SELECTSLAVE;
94
95         __raw_writel(val, hw->regs + USI_SSR);
96
97         val = __raw_readl(hw->regs + USI_CNT);
98
99         if (!cpol)
100                 val &= ~SELECTPOL;
101         else
102                 val |= SELECTPOL;
103
104         __raw_writel(val, hw->regs + USI_CNT);
105
106         spin_unlock_irqrestore(&hw->lock, flags);
107 }
108
109 static void nuc900_spi_chipsel(struct spi_device *spi, int value)
110 {
111         switch (value) {
112         case BITBANG_CS_INACTIVE:
113                 nuc900_slave_select(spi, 0);
114                 break;
115
116         case BITBANG_CS_ACTIVE:
117                 nuc900_slave_select(spi, 1);
118                 break;
119         }
120 }
121
122 static void nuc900_spi_setup_txnum(struct nuc900_spi *hw,
123                                                         unsigned int txnum)
124 {
125         unsigned int val;
126         unsigned long flags;
127
128         spin_lock_irqsave(&hw->lock, flags);
129
130         val = __raw_readl(hw->regs + USI_CNT);
131
132         if (!txnum)
133                 val &= ~TXNUM;
134         else
135                 val |= txnum << 0x08;
136
137         __raw_writel(val, hw->regs + USI_CNT);
138
139         spin_unlock_irqrestore(&hw->lock, flags);
140
141 }
142
143 static void nuc900_spi_setup_txbitlen(struct nuc900_spi *hw,
144                                                         unsigned int txbitlen)
145 {
146         unsigned int val;
147         unsigned long flags;
148
149         spin_lock_irqsave(&hw->lock, flags);
150
151         val = __raw_readl(hw->regs + USI_CNT);
152
153         val |= (txbitlen << 0x03);
154
155         __raw_writel(val, hw->regs + USI_CNT);
156
157         spin_unlock_irqrestore(&hw->lock, flags);
158 }
159
160 static void nuc900_spi_gobusy(struct nuc900_spi *hw)
161 {
162         unsigned int val;
163         unsigned long flags;
164
165         spin_lock_irqsave(&hw->lock, flags);
166
167         val = __raw_readl(hw->regs + USI_CNT);
168
169         val |= GOBUSY;
170
171         __raw_writel(val, hw->regs + USI_CNT);
172
173         spin_unlock_irqrestore(&hw->lock, flags);
174 }
175
176 static int nuc900_spi_setupxfer(struct spi_device *spi,
177                                  struct spi_transfer *t)
178 {
179         return 0;
180 }
181
182 static int nuc900_spi_setup(struct spi_device *spi)
183 {
184         return 0;
185 }
186
187 static inline unsigned int hw_txbyte(struct nuc900_spi *hw, int count)
188 {
189         return hw->tx ? hw->tx[count] : 0;
190 }
191
192 static int nuc900_spi_txrx(struct spi_device *spi, struct spi_transfer *t)
193 {
194         struct nuc900_spi *hw = to_hw(spi);
195
196         hw->tx = t->tx_buf;
197         hw->rx = t->rx_buf;
198         hw->len = t->len;
199         hw->count = 0;
200
201         __raw_writel(hw_txbyte(hw, 0x0), hw->regs + USI_TX0);
202
203         nuc900_spi_gobusy(hw);
204
205         wait_for_completion(&hw->done);
206
207         return hw->count;
208 }
209
210 static irqreturn_t nuc900_spi_irq(int irq, void *dev)
211 {
212         struct nuc900_spi *hw = dev;
213         unsigned int status;
214         unsigned int count = hw->count;
215
216         status = __raw_readl(hw->regs + USI_CNT);
217         __raw_writel(status, hw->regs + USI_CNT);
218
219         if (status & ENFLG) {
220                 hw->count++;
221
222                 if (hw->rx)
223                         hw->rx[count] = __raw_readl(hw->regs + USI_RX0);
224                 count++;
225
226                 if (count < hw->len) {
227                         __raw_writel(hw_txbyte(hw, count), hw->regs + USI_TX0);
228                         nuc900_spi_gobusy(hw);
229                 } else {
230                         complete(&hw->done);
231                 }
232
233                 return IRQ_HANDLED;
234         }
235
236         complete(&hw->done);
237         return IRQ_HANDLED;
238 }
239
240 static void nuc900_tx_edge(struct nuc900_spi *hw, unsigned int edge)
241 {
242         unsigned int val;
243         unsigned long flags;
244
245         spin_lock_irqsave(&hw->lock, flags);
246
247         val = __raw_readl(hw->regs + USI_CNT);
248
249         if (edge)
250                 val |= TXNEG;
251         else
252                 val &= ~TXNEG;
253         __raw_writel(val, hw->regs + USI_CNT);
254
255         spin_unlock_irqrestore(&hw->lock, flags);
256 }
257
258 static void nuc900_rx_edge(struct nuc900_spi *hw, unsigned int edge)
259 {
260         unsigned int val;
261         unsigned long flags;
262
263         spin_lock_irqsave(&hw->lock, flags);
264
265         val = __raw_readl(hw->regs + USI_CNT);
266
267         if (edge)
268                 val |= RXNEG;
269         else
270                 val &= ~RXNEG;
271         __raw_writel(val, hw->regs + USI_CNT);
272
273         spin_unlock_irqrestore(&hw->lock, flags);
274 }
275
276 static void nuc900_send_first(struct nuc900_spi *hw, unsigned int lsb)
277 {
278         unsigned int val;
279         unsigned long flags;
280
281         spin_lock_irqsave(&hw->lock, flags);
282
283         val = __raw_readl(hw->regs + USI_CNT);
284
285         if (lsb)
286                 val |= LSB;
287         else
288                 val &= ~LSB;
289         __raw_writel(val, hw->regs + USI_CNT);
290
291         spin_unlock_irqrestore(&hw->lock, flags);
292 }
293
294 static void nuc900_set_sleep(struct nuc900_spi *hw, unsigned int sleep)
295 {
296         unsigned int val;
297         unsigned long flags;
298
299         spin_lock_irqsave(&hw->lock, flags);
300
301         val = __raw_readl(hw->regs + USI_CNT);
302
303         if (sleep)
304                 val |= (sleep << 12);
305         else
306                 val &= ~(0x0f << 12);
307         __raw_writel(val, hw->regs + USI_CNT);
308
309         spin_unlock_irqrestore(&hw->lock, flags);
310 }
311
312 static void nuc900_enable_int(struct nuc900_spi *hw)
313 {
314         unsigned int val;
315         unsigned long flags;
316
317         spin_lock_irqsave(&hw->lock, flags);
318
319         val = __raw_readl(hw->regs + USI_CNT);
320
321         val |= ENINT;
322
323         __raw_writel(val, hw->regs + USI_CNT);
324
325         spin_unlock_irqrestore(&hw->lock, flags);
326 }
327
328 static void nuc900_set_divider(struct nuc900_spi *hw)
329 {
330         __raw_writel(hw->pdata->divider, hw->regs + USI_DIV);
331 }
332
333 static void nuc900_init_spi(struct nuc900_spi *hw)
334 {
335         clk_enable(hw->clk);
336         spin_lock_init(&hw->lock);
337
338         nuc900_tx_edge(hw, hw->pdata->txneg);
339         nuc900_rx_edge(hw, hw->pdata->rxneg);
340         nuc900_send_first(hw, hw->pdata->lsb);
341         nuc900_set_sleep(hw, hw->pdata->sleep);
342         nuc900_spi_setup_txbitlen(hw, hw->pdata->txbitlen);
343         nuc900_spi_setup_txnum(hw, hw->pdata->txnum);
344         nuc900_set_divider(hw);
345         nuc900_enable_int(hw);
346 }
347
348 static int __devinit nuc900_spi_probe(struct platform_device *pdev)
349 {
350         struct nuc900_spi *hw;
351         struct spi_master *master;
352         int err = 0;
353
354         master = spi_alloc_master(&pdev->dev, sizeof(struct nuc900_spi));
355         if (master == NULL) {
356                 dev_err(&pdev->dev, "No memory for spi_master\n");
357                 err = -ENOMEM;
358                 goto err_nomem;
359         }
360
361         hw = spi_master_get_devdata(master);
362         memset(hw, 0, sizeof(struct nuc900_spi));
363
364         hw->master = spi_master_get(master);
365         hw->pdata  = pdev->dev.platform_data;
366         hw->dev = &pdev->dev;
367
368         if (hw->pdata == NULL) {
369                 dev_err(&pdev->dev, "No platform data supplied\n");
370                 err = -ENOENT;
371                 goto err_pdata;
372         }
373
374         platform_set_drvdata(pdev, hw);
375         init_completion(&hw->done);
376
377         master->mode_bits          = SPI_MODE_0;
378         master->num_chipselect     = hw->pdata->num_cs;
379         master->bus_num            = hw->pdata->bus_num;
380         hw->bitbang.master         = hw->master;
381         hw->bitbang.setup_transfer = nuc900_spi_setupxfer;
382         hw->bitbang.chipselect     = nuc900_spi_chipsel;
383         hw->bitbang.txrx_bufs      = nuc900_spi_txrx;
384         hw->bitbang.master->setup  = nuc900_spi_setup;
385
386         hw->res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
387         if (hw->res == NULL) {
388                 dev_err(&pdev->dev, "Cannot get IORESOURCE_MEM\n");
389                 err = -ENOENT;
390                 goto err_pdata;
391         }
392
393         hw->ioarea = request_mem_region(hw->res->start,
394                                         resource_size(hw->res), pdev->name);
395
396         if (hw->ioarea == NULL) {
397                 dev_err(&pdev->dev, "Cannot reserve region\n");
398                 err = -ENXIO;
399                 goto err_pdata;
400         }
401
402         hw->regs = ioremap(hw->res->start, resource_size(hw->res));
403         if (hw->regs == NULL) {
404                 dev_err(&pdev->dev, "Cannot map IO\n");
405                 err = -ENXIO;
406                 goto err_iomap;
407         }
408
409         hw->irq = platform_get_irq(pdev, 0);
410         if (hw->irq < 0) {
411                 dev_err(&pdev->dev, "No IRQ specified\n");
412                 err = -ENOENT;
413                 goto err_irq;
414         }
415
416         err = request_irq(hw->irq, nuc900_spi_irq, 0, pdev->name, hw);
417         if (err) {
418                 dev_err(&pdev->dev, "Cannot claim IRQ\n");
419                 goto err_irq;
420         }
421
422         hw->clk = clk_get(&pdev->dev, "spi");
423         if (IS_ERR(hw->clk)) {
424                 dev_err(&pdev->dev, "No clock for device\n");
425                 err = PTR_ERR(hw->clk);
426                 goto err_clk;
427         }
428
429         mfp_set_groupg(&pdev->dev);
430         nuc900_init_spi(hw);
431
432         err = spi_bitbang_start(&hw->bitbang);
433         if (err) {
434                 dev_err(&pdev->dev, "Failed to register SPI master\n");
435                 goto err_register;
436         }
437
438         return 0;
439
440 err_register:
441         clk_disable(hw->clk);
442         clk_put(hw->clk);
443 err_clk:
444         free_irq(hw->irq, hw);
445 err_irq:
446         iounmap(hw->regs);
447 err_iomap:
448         release_mem_region(hw->res->start, resource_size(hw->res));
449         kfree(hw->ioarea);
450 err_pdata:
451         spi_master_put(hw->master);
452
453 err_nomem:
454         return err;
455 }
456
457 static int __devexit nuc900_spi_remove(struct platform_device *dev)
458 {
459         struct nuc900_spi *hw = platform_get_drvdata(dev);
460
461         free_irq(hw->irq, hw);
462
463         platform_set_drvdata(dev, NULL);
464
465         spi_bitbang_stop(&hw->bitbang);
466
467         clk_disable(hw->clk);
468         clk_put(hw->clk);
469
470         iounmap(hw->regs);
471
472         release_mem_region(hw->res->start, resource_size(hw->res));
473         kfree(hw->ioarea);
474
475         spi_master_put(hw->master);
476         return 0;
477 }
478
479 static struct platform_driver nuc900_spi_driver = {
480         .probe          = nuc900_spi_probe,
481         .remove         = __devexit_p(nuc900_spi_remove),
482         .driver         = {
483                 .name   = "nuc900-spi",
484                 .owner  = THIS_MODULE,
485         },
486 };
487 module_platform_driver(nuc900_spi_driver);
488
489 MODULE_AUTHOR("Wan ZongShun <mcuos.com@gmail.com>");
490 MODULE_DESCRIPTION("nuc900 spi driver!");
491 MODULE_LICENSE("GPL");
492 MODULE_ALIAS("platform:nuc900-spi");