Version:  2.0.40 2.2.26 2.4.37 3.0 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15 3.16

Linux/drivers/spi/spi-orion.c

  1 /*
  2  * Marvell Orion SPI controller driver
  3  *
  4  * Author: Shadi Ammouri <shadi@marvell.com>
  5  * Copyright (C) 2007-2008 Marvell Ltd.
  6  *
  7  * This program is free software; you can redistribute it and/or modify
  8  * it under the terms of the GNU General Public License version 2 as
  9  * published by the Free Software Foundation.
 10  */
 11 
 12 #include <linux/interrupt.h>
 13 #include <linux/delay.h>
 14 #include <linux/platform_device.h>
 15 #include <linux/err.h>
 16 #include <linux/io.h>
 17 #include <linux/spi/spi.h>
 18 #include <linux/module.h>
 19 #include <linux/of.h>
 20 #include <linux/clk.h>
 21 #include <linux/sizes.h>
 22 #include <asm/unaligned.h>
 23 
 24 #define DRIVER_NAME                     "orion_spi"
 25 
 26 #define ORION_NUM_CHIPSELECTS           1 /* only one slave is supported*/
 27 #define ORION_SPI_WAIT_RDY_MAX_LOOP     2000 /* in usec */
 28 
 29 #define ORION_SPI_IF_CTRL_REG           0x00
 30 #define ORION_SPI_IF_CONFIG_REG         0x04
 31 #define ORION_SPI_DATA_OUT_REG          0x08
 32 #define ORION_SPI_DATA_IN_REG           0x0c
 33 #define ORION_SPI_INT_CAUSE_REG         0x10
 34 
 35 #define ORION_SPI_MODE_CPOL             (1 << 11)
 36 #define ORION_SPI_MODE_CPHA             (1 << 12)
 37 #define ORION_SPI_IF_8_16_BIT_MODE      (1 << 5)
 38 #define ORION_SPI_CLK_PRESCALE_MASK     0x1F
 39 #define ORION_SPI_MODE_MASK             (ORION_SPI_MODE_CPOL | \
 40                                          ORION_SPI_MODE_CPHA)
 41 
 42 struct orion_spi {
 43         struct spi_master       *master;
 44         void __iomem            *base;
 45         struct clk              *clk;
 46 };
 47 
 48 static inline void __iomem *spi_reg(struct orion_spi *orion_spi, u32 reg)
 49 {
 50         return orion_spi->base + reg;
 51 }
 52 
 53 static inline void
 54 orion_spi_setbits(struct orion_spi *orion_spi, u32 reg, u32 mask)
 55 {
 56         void __iomem *reg_addr = spi_reg(orion_spi, reg);
 57         u32 val;
 58 
 59         val = readl(reg_addr);
 60         val |= mask;
 61         writel(val, reg_addr);
 62 }
 63 
 64 static inline void
 65 orion_spi_clrbits(struct orion_spi *orion_spi, u32 reg, u32 mask)
 66 {
 67         void __iomem *reg_addr = spi_reg(orion_spi, reg);
 68         u32 val;
 69 
 70         val = readl(reg_addr);
 71         val &= ~mask;
 72         writel(val, reg_addr);
 73 }
 74 
 75 static int orion_spi_baudrate_set(struct spi_device *spi, unsigned int speed)
 76 {
 77         u32 tclk_hz;
 78         u32 rate;
 79         u32 prescale;
 80         u32 reg;
 81         struct orion_spi *orion_spi;
 82 
 83         orion_spi = spi_master_get_devdata(spi->master);
 84 
 85         tclk_hz = clk_get_rate(orion_spi->clk);
 86 
 87         /*
 88          * the supported rates are: 4,6,8...30
 89          * round up as we look for equal or less speed
 90          */
 91         rate = DIV_ROUND_UP(tclk_hz, speed);
 92         rate = roundup(rate, 2);
 93 
 94         /* check if requested speed is too small */
 95         if (rate > 30)
 96                 return -EINVAL;
 97 
 98         if (rate < 4)
 99                 rate = 4;
100 
101         /* Convert the rate to SPI clock divisor value. */
102         prescale = 0x10 + rate/2;
103 
104         reg = readl(spi_reg(orion_spi, ORION_SPI_IF_CONFIG_REG));
105         reg = ((reg & ~ORION_SPI_CLK_PRESCALE_MASK) | prescale);
106         writel(reg, spi_reg(orion_spi, ORION_SPI_IF_CONFIG_REG));
107 
108         return 0;
109 }
110 
111 static void
112 orion_spi_mode_set(struct spi_device *spi)
113 {
114         u32 reg;
115         struct orion_spi *orion_spi;
116 
117         orion_spi = spi_master_get_devdata(spi->master);
118 
119         reg = readl(spi_reg(orion_spi, ORION_SPI_IF_CONFIG_REG));
120         reg &= ~ORION_SPI_MODE_MASK;
121         if (spi->mode & SPI_CPOL)
122                 reg |= ORION_SPI_MODE_CPOL;
123         if (spi->mode & SPI_CPHA)
124                 reg |= ORION_SPI_MODE_CPHA;
125         writel(reg, spi_reg(orion_spi, ORION_SPI_IF_CONFIG_REG));
126 }
127 
128 /*
129  * called only when no transfer is active on the bus
130  */
131 static int
132 orion_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
133 {
134         struct orion_spi *orion_spi;
135         unsigned int speed = spi->max_speed_hz;
136         unsigned int bits_per_word = spi->bits_per_word;
137         int     rc;
138 
139         orion_spi = spi_master_get_devdata(spi->master);
140 
141         if ((t != NULL) && t->speed_hz)
142                 speed = t->speed_hz;
143 
144         if ((t != NULL) && t->bits_per_word)
145                 bits_per_word = t->bits_per_word;
146 
147         orion_spi_mode_set(spi);
148 
149         rc = orion_spi_baudrate_set(spi, speed);
150         if (rc)
151                 return rc;
152 
153         if (bits_per_word == 16)
154                 orion_spi_setbits(orion_spi, ORION_SPI_IF_CONFIG_REG,
155                                   ORION_SPI_IF_8_16_BIT_MODE);
156         else
157                 orion_spi_clrbits(orion_spi, ORION_SPI_IF_CONFIG_REG,
158                                   ORION_SPI_IF_8_16_BIT_MODE);
159 
160         return 0;
161 }
162 
163 static void orion_spi_set_cs(struct orion_spi *orion_spi, int enable)
164 {
165         if (enable)
166                 orion_spi_setbits(orion_spi, ORION_SPI_IF_CTRL_REG, 0x1);
167         else
168                 orion_spi_clrbits(orion_spi, ORION_SPI_IF_CTRL_REG, 0x1);
169 }
170 
171 static inline int orion_spi_wait_till_ready(struct orion_spi *orion_spi)
172 {
173         int i;
174 
175         for (i = 0; i < ORION_SPI_WAIT_RDY_MAX_LOOP; i++) {
176                 if (readl(spi_reg(orion_spi, ORION_SPI_INT_CAUSE_REG)))
177                         return 1;
178                 else
179                         udelay(1);
180         }
181 
182         return -1;
183 }
184 
185 static inline int
186 orion_spi_write_read_8bit(struct spi_device *spi,
187                           const u8 **tx_buf, u8 **rx_buf)
188 {
189         void __iomem *tx_reg, *rx_reg, *int_reg;
190         struct orion_spi *orion_spi;
191 
192         orion_spi = spi_master_get_devdata(spi->master);
193         tx_reg = spi_reg(orion_spi, ORION_SPI_DATA_OUT_REG);
194         rx_reg = spi_reg(orion_spi, ORION_SPI_DATA_IN_REG);
195         int_reg = spi_reg(orion_spi, ORION_SPI_INT_CAUSE_REG);
196 
197         /* clear the interrupt cause register */
198         writel(0x0, int_reg);
199 
200         if (tx_buf && *tx_buf)
201                 writel(*(*tx_buf)++, tx_reg);
202         else
203                 writel(0, tx_reg);
204 
205         if (orion_spi_wait_till_ready(orion_spi) < 0) {
206                 dev_err(&spi->dev, "TXS timed out\n");
207                 return -1;
208         }
209 
210         if (rx_buf && *rx_buf)
211                 *(*rx_buf)++ = readl(rx_reg);
212 
213         return 1;
214 }
215 
216 static inline int
217 orion_spi_write_read_16bit(struct spi_device *spi,
218                            const u16 **tx_buf, u16 **rx_buf)
219 {
220         void __iomem *tx_reg, *rx_reg, *int_reg;
221         struct orion_spi *orion_spi;
222 
223         orion_spi = spi_master_get_devdata(spi->master);
224         tx_reg = spi_reg(orion_spi, ORION_SPI_DATA_OUT_REG);
225         rx_reg = spi_reg(orion_spi, ORION_SPI_DATA_IN_REG);
226         int_reg = spi_reg(orion_spi, ORION_SPI_INT_CAUSE_REG);
227 
228         /* clear the interrupt cause register */
229         writel(0x0, int_reg);
230 
231         if (tx_buf && *tx_buf)
232                 writel(__cpu_to_le16(get_unaligned((*tx_buf)++)), tx_reg);
233         else
234                 writel(0, tx_reg);
235 
236         if (orion_spi_wait_till_ready(orion_spi) < 0) {
237                 dev_err(&spi->dev, "TXS timed out\n");
238                 return -1;
239         }
240 
241         if (rx_buf && *rx_buf)
242                 put_unaligned(__le16_to_cpu(readl(rx_reg)), (*rx_buf)++);
243 
244         return 1;
245 }
246 
247 static unsigned int
248 orion_spi_write_read(struct spi_device *spi, struct spi_transfer *xfer)
249 {
250         unsigned int count;
251         int word_len;
252 
253         word_len = spi->bits_per_word;
254         count = xfer->len;
255 
256         if (word_len == 8) {
257                 const u8 *tx = xfer->tx_buf;
258                 u8 *rx = xfer->rx_buf;
259 
260                 do {
261                         if (orion_spi_write_read_8bit(spi, &tx, &rx) < 0)
262                                 goto out;
263                         count--;
264                 } while (count);
265         } else if (word_len == 16) {
266                 const u16 *tx = xfer->tx_buf;
267                 u16 *rx = xfer->rx_buf;
268 
269                 do {
270                         if (orion_spi_write_read_16bit(spi, &tx, &rx) < 0)
271                                 goto out;
272                         count -= 2;
273                 } while (count);
274         }
275 
276 out:
277         return xfer->len - count;
278 }
279 
280 
281 static int orion_spi_transfer_one_message(struct spi_master *master,
282                                            struct spi_message *m)
283 {
284         struct orion_spi *orion_spi = spi_master_get_devdata(master);
285         struct spi_device *spi = m->spi;
286         struct spi_transfer *t = NULL;
287         int par_override = 0;
288         int status = 0;
289         int cs_active = 0;
290 
291         /* Load defaults */
292         status = orion_spi_setup_transfer(spi, NULL);
293 
294         if (status < 0)
295                 goto msg_done;
296 
297         list_for_each_entry(t, &m->transfers, transfer_list) {
298                 if (par_override || t->speed_hz || t->bits_per_word) {
299                         par_override = 1;
300                         status = orion_spi_setup_transfer(spi, t);
301                         if (status < 0)
302                                 break;
303                         if (!t->speed_hz && !t->bits_per_word)
304                                 par_override = 0;
305                 }
306 
307                 if (!cs_active) {
308                         orion_spi_set_cs(orion_spi, 1);
309                         cs_active = 1;
310                 }
311 
312                 if (t->len)
313                         m->actual_length += orion_spi_write_read(spi, t);
314 
315                 if (t->delay_usecs)
316                         udelay(t->delay_usecs);
317 
318                 if (t->cs_change) {
319                         orion_spi_set_cs(orion_spi, 0);
320                         cs_active = 0;
321                 }
322         }
323 
324 msg_done:
325         if (cs_active)
326                 orion_spi_set_cs(orion_spi, 0);
327 
328         m->status = status;
329         spi_finalize_current_message(master);
330 
331         return 0;
332 }
333 
334 static int orion_spi_reset(struct orion_spi *orion_spi)
335 {
336         /* Verify that the CS is deasserted */
337         orion_spi_set_cs(orion_spi, 0);
338 
339         return 0;
340 }
341 
342 static int orion_spi_probe(struct platform_device *pdev)
343 {
344         struct spi_master *master;
345         struct orion_spi *spi;
346         struct resource *r;
347         unsigned long tclk_hz;
348         int status = 0;
349         const u32 *iprop;
350         int size;
351 
352         master = spi_alloc_master(&pdev->dev, sizeof(*spi));
353         if (master == NULL) {
354                 dev_dbg(&pdev->dev, "master allocation failed\n");
355                 return -ENOMEM;
356         }
357 
358         if (pdev->id != -1)
359                 master->bus_num = pdev->id;
360         if (pdev->dev.of_node) {
361                 iprop = of_get_property(pdev->dev.of_node, "cell-index",
362                                         &size);
363                 if (iprop && size == sizeof(*iprop))
364                         master->bus_num = *iprop;
365         }
366 
367         /* we support only mode 0, and no options */
368         master->mode_bits = SPI_CPHA | SPI_CPOL;
369 
370         master->transfer_one_message = orion_spi_transfer_one_message;
371         master->num_chipselect = ORION_NUM_CHIPSELECTS;
372         master->bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(16);
373 
374         platform_set_drvdata(pdev, master);
375 
376         spi = spi_master_get_devdata(master);
377         spi->master = master;
378 
379         spi->clk = devm_clk_get(&pdev->dev, NULL);
380         if (IS_ERR(spi->clk)) {
381                 status = PTR_ERR(spi->clk);
382                 goto out;
383         }
384 
385         clk_prepare(spi->clk);
386         clk_enable(spi->clk);
387         tclk_hz = clk_get_rate(spi->clk);
388         master->max_speed_hz = DIV_ROUND_UP(tclk_hz, 4);
389         master->min_speed_hz = DIV_ROUND_UP(tclk_hz, 30);
390 
391         r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
392         spi->base = devm_ioremap_resource(&pdev->dev, r);
393         if (IS_ERR(spi->base)) {
394                 status = PTR_ERR(spi->base);
395                 goto out_rel_clk;
396         }
397 
398         if (orion_spi_reset(spi) < 0)
399                 goto out_rel_clk;
400 
401         master->dev.of_node = pdev->dev.of_node;
402         status = devm_spi_register_master(&pdev->dev, master);
403         if (status < 0)
404                 goto out_rel_clk;
405 
406         return status;
407 
408 out_rel_clk:
409         clk_disable_unprepare(spi->clk);
410 out:
411         spi_master_put(master);
412         return status;
413 }
414 
415 
416 static int orion_spi_remove(struct platform_device *pdev)
417 {
418         struct spi_master *master;
419         struct orion_spi *spi;
420 
421         master = platform_get_drvdata(pdev);
422         spi = spi_master_get_devdata(master);
423 
424         clk_disable_unprepare(spi->clk);
425 
426         return 0;
427 }
428 
429 MODULE_ALIAS("platform:" DRIVER_NAME);
430 
431 static const struct of_device_id orion_spi_of_match_table[] = {
432         { .compatible = "marvell,orion-spi", },
433         {}
434 };
435 MODULE_DEVICE_TABLE(of, orion_spi_of_match_table);
436 
437 static struct platform_driver orion_spi_driver = {
438         .driver = {
439                 .name   = DRIVER_NAME,
440                 .owner  = THIS_MODULE,
441                 .of_match_table = of_match_ptr(orion_spi_of_match_table),
442         },
443         .probe          = orion_spi_probe,
444         .remove         = orion_spi_remove,
445 };
446 
447 module_platform_driver(orion_spi_driver);
448 
449 MODULE_DESCRIPTION("Orion SPI driver");
450 MODULE_AUTHOR("Shadi Ammouri <shadi@marvell.com>");
451 MODULE_LICENSE("GPL");
452 

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us