aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
commitfcc9d2e5a6c89d22b8b773a64fb4ad21ac318446 (patch)
treea57612d1888735a2ec7972891b68c1ac5ec8faea /drivers/spi
parent8dea78da5cee153b8af9c07a2745f6c55057fe12 (diff)
Added missing tegra files.HEADmaster
Diffstat (limited to 'drivers/spi')
-rw-r--r--drivers/spi/spi-stmp.c679
-rw-r--r--drivers/spi/spi-tegra.c1666
-rw-r--r--drivers/spi/spi_slave_tegra.c1401
3 files changed, 3746 insertions, 0 deletions
diff --git a/drivers/spi/spi-stmp.c b/drivers/spi/spi-stmp.c
new file mode 100644
index 00000000000..fadff76eb7e
--- /dev/null
+++ b/drivers/spi/spi-stmp.c
@@ -0,0 +1,679 @@
1/*
2 * Freescale STMP378X SPI master driver
3 *
4 * Author: dmitry pervushin <dimka@embeddedalley.com>
5 *
6 * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
7 * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
8 */
9
10/*
11 * The code contained herein is licensed under the GNU General Public
12 * License. You may obtain a copy of the GNU General Public License
13 * Version 2 or later at the following locations:
14 *
15 * http://www.opensource.org/licenses/gpl-license.html
16 * http://www.gnu.org/copyleft/gpl.html
17 */
18#include <linux/module.h>
19#include <linux/init.h>
20#include <linux/interrupt.h>
21#include <linux/platform_device.h>
22#include <linux/spi/spi.h>
23#include <linux/err.h>
24#include <linux/clk.h>
25#include <linux/io.h>
26#include <linux/dma-mapping.h>
27#include <linux/delay.h>
28
29#include <mach/platform.h>
30#include <mach/stmp3xxx.h>
31#include <mach/dma.h>
32#include <mach/regs-ssp.h>
33#include <mach/regs-apbh.h>
34
35
36/* 0 means DMA mode(recommended, default), !0 - PIO mode */
37static int pio;
38static int clock;
39
40/* default timeout for busy waits is 2 seconds */
41#define STMP_SPI_TIMEOUT (2 * HZ)
42
43struct stmp_spi {
44 int id;
45
46 void * __iomem regs; /* vaddr of the control registers */
47
48 int irq, err_irq;
49 u32 dma;
50 struct stmp3xxx_dma_descriptor d;
51
52 u32 speed_khz;
53 u32 saved_timings;
54 u32 divider;
55
56 struct clk *clk;
57 struct device *master_dev;
58
59 struct work_struct work;
60 struct workqueue_struct *workqueue;
61
62 /* lock protects queue access */
63 spinlock_t lock;
64 struct list_head queue;
65
66 struct completion done;
67};
68
69#define busy_wait(cond) \
70 ({ \
71 unsigned long end_jiffies = jiffies + STMP_SPI_TIMEOUT; \
72 bool succeeded = false; \
73 do { \
74 if (cond) { \
75 succeeded = true; \
76 break; \
77 } \
78 cpu_relax(); \
79 } while (time_before(jiffies, end_jiffies)); \
80 succeeded; \
81 })
82
83/**
84 * stmp_spi_init_hw
85 * Initialize the SSP port
86 */
87static int stmp_spi_init_hw(struct stmp_spi *ss)
88{
89 int err = 0;
90 void *pins = ss->master_dev->platform_data;
91
92 err = stmp3xxx_request_pin_group(pins, dev_name(ss->master_dev));
93 if (err)
94 goto out;
95
96 ss->clk = clk_get(NULL, "ssp");
97 if (IS_ERR(ss->clk)) {
98 err = PTR_ERR(ss->clk);
99 goto out_free_pins;
100 }
101 clk_enable(ss->clk);
102
103 stmp3xxx_reset_block(ss->regs, false);
104 stmp3xxx_dma_reset_channel(ss->dma);
105
106 return 0;
107
108out_free_pins:
109 stmp3xxx_release_pin_group(pins, dev_name(ss->master_dev));
110out:
111 return err;
112}
113
114static void stmp_spi_release_hw(struct stmp_spi *ss)
115{
116 void *pins = ss->master_dev->platform_data;
117
118 if (ss->clk && !IS_ERR(ss->clk)) {
119 clk_disable(ss->clk);
120 clk_put(ss->clk);
121 }
122 stmp3xxx_release_pin_group(pins, dev_name(ss->master_dev));
123}
124
125static int stmp_spi_setup_transfer(struct spi_device *spi,
126 struct spi_transfer *t)
127{
128 u8 bits_per_word;
129 u32 hz;
130 struct stmp_spi *ss = spi_master_get_devdata(spi->master);
131 u16 rate;
132
133 bits_per_word = spi->bits_per_word;
134 if (t && t->bits_per_word)
135 bits_per_word = t->bits_per_word;
136
137 /*
138 * Calculate speed:
139 * - by default, use maximum speed from ssp clk
140 * - if device overrides it, use it
141 * - if transfer specifies other speed, use transfer's one
142 */
143 hz = 1000 * ss->speed_khz / ss->divider;
144 if (spi->max_speed_hz)
145 hz = min(hz, spi->max_speed_hz);
146 if (t && t->speed_hz)
147 hz = min(hz, t->speed_hz);
148
149 if (hz == 0) {
150 dev_err(&spi->dev, "Cannot continue with zero clock\n");
151 return -EINVAL;
152 }
153
154 if (bits_per_word != 8) {
155 dev_err(&spi->dev, "%s, unsupported bits_per_word=%d\n",
156 __func__, bits_per_word);
157 return -EINVAL;
158 }
159
160 dev_dbg(&spi->dev, "Requested clk rate = %uHz, max = %uHz/%d = %uHz\n",
161 hz, ss->speed_khz, ss->divider,
162 ss->speed_khz * 1000 / ss->divider);
163
164 if (ss->speed_khz * 1000 / ss->divider < hz) {
165 dev_err(&spi->dev, "%s, unsupported clock rate %uHz\n",
166 __func__, hz);
167 return -EINVAL;
168 }
169
170 rate = 1000 * ss->speed_khz/ss->divider/hz;
171
172 writel(BF(ss->divider, SSP_TIMING_CLOCK_DIVIDE) |
173 BF(rate - 1, SSP_TIMING_CLOCK_RATE),
174 HW_SSP_TIMING + ss->regs);
175
176 writel(BF(1 /* mode SPI */, SSP_CTRL1_SSP_MODE) |
177 BF(4 /* 8 bits */, SSP_CTRL1_WORD_LENGTH) |
178 ((spi->mode & SPI_CPOL) ? BM_SSP_CTRL1_POLARITY : 0) |
179 ((spi->mode & SPI_CPHA) ? BM_SSP_CTRL1_PHASE : 0) |
180 (pio ? 0 : BM_SSP_CTRL1_DMA_ENABLE),
181 ss->regs + HW_SSP_CTRL1);
182
183 return 0;
184}
185
186static int stmp_spi_setup(struct spi_device *spi)
187{
188 /* spi_setup() does basic checks,
189 * stmp_spi_setup_transfer() does more later
190 */
191 if (spi->bits_per_word != 8) {
192 dev_err(&spi->dev, "%s, unsupported bits_per_word=%d\n",
193 __func__, spi->bits_per_word);
194 return -EINVAL;
195 }
196 return 0;
197}
198
199static inline u32 stmp_spi_cs(unsigned cs)
200{
201 return ((cs & 1) ? BM_SSP_CTRL0_WAIT_FOR_CMD : 0) |
202 ((cs & 2) ? BM_SSP_CTRL0_WAIT_FOR_IRQ : 0);
203}
204
205static int stmp_spi_txrx_dma(struct stmp_spi *ss, int cs,
206 unsigned char *buf, dma_addr_t dma_buf, int len,
207 int first, int last, bool write)
208{
209 u32 c0 = 0;
210 dma_addr_t spi_buf_dma = dma_buf;
211 int status = 0;
212 enum dma_data_direction dir = write ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
213
214 c0 |= (first ? BM_SSP_CTRL0_LOCK_CS : 0);
215 c0 |= (last ? BM_SSP_CTRL0_IGNORE_CRC : 0);
216 c0 |= (write ? 0 : BM_SSP_CTRL0_READ);
217 c0 |= BM_SSP_CTRL0_DATA_XFER;