18
18
#include <linux/module.h>
19
19
#include <linux/platform_device.h>
20
20
#include <linux/spi/spi.h>
21
- #include <linux/spi/spi_bitbang.h>
22
21
#include <linux/io.h>
23
22
#include <linux/of.h>
24
23
45
44
#define ALTERA_SPI_CONTROL_SSO_MSK 0x400
46
45
47
46
struct altera_spi {
48
- /* bitbang has to be first */
49
- struct spi_bitbang bitbang ;
50
- struct completion done ;
51
-
52
47
void __iomem * base ;
53
48
int irq ;
54
49
int len ;
@@ -66,59 +61,64 @@ static inline struct altera_spi *altera_spi_to_hw(struct spi_device *sdev)
66
61
return spi_master_get_devdata (sdev -> master );
67
62
}
68
63
69
- static void altera_spi_chipsel (struct spi_device * spi , int value )
64
+ static void altera_spi_set_cs (struct spi_device * spi , bool is_high )
70
65
{
71
66
struct altera_spi * hw = altera_spi_to_hw (spi );
72
67
73
- if (spi -> mode & SPI_CS_HIGH ) {
74
- switch (value ) {
75
- case BITBANG_CS_INACTIVE :
76
- writel (1 << spi -> chip_select ,
77
- hw -> base + ALTERA_SPI_SLAVE_SEL );
78
- hw -> imr |= ALTERA_SPI_CONTROL_SSO_MSK ;
79
- writel (hw -> imr , hw -> base + ALTERA_SPI_CONTROL );
80
- break ;
81
-
82
- case BITBANG_CS_ACTIVE :
83
- hw -> imr &= ~ALTERA_SPI_CONTROL_SSO_MSK ;
84
- writel (hw -> imr , hw -> base + ALTERA_SPI_CONTROL );
85
- writel (0 , hw -> base + ALTERA_SPI_SLAVE_SEL );
86
- break ;
87
- }
68
+ if (is_high ) {
69
+ hw -> imr &= ~ALTERA_SPI_CONTROL_SSO_MSK ;
70
+ writel (hw -> imr , hw -> base + ALTERA_SPI_CONTROL );
71
+ writel (0 , hw -> base + ALTERA_SPI_SLAVE_SEL );
88
72
} else {
89
- switch (value ) {
90
- case BITBANG_CS_INACTIVE :
91
- hw -> imr &= ~ALTERA_SPI_CONTROL_SSO_MSK ;
92
- writel (hw -> imr , hw -> base + ALTERA_SPI_CONTROL );
93
- break ;
73
+ writel (BIT (spi -> chip_select ), hw -> base + ALTERA_SPI_SLAVE_SEL );
74
+ hw -> imr |= ALTERA_SPI_CONTROL_SSO_MSK ;
75
+ writel (hw -> imr , hw -> base + ALTERA_SPI_CONTROL );
76
+ }
77
+ }
78
+
79
+ static void altera_spi_tx_word (struct altera_spi * hw )
80
+ {
81
+ unsigned int txd = 0 ;
94
82
95
- case BITBANG_CS_ACTIVE :
96
- writel (1 << spi -> chip_select ,
97
- hw -> base + ALTERA_SPI_SLAVE_SEL );
98
- hw -> imr |= ALTERA_SPI_CONTROL_SSO_MSK ;
99
- writel (hw -> imr , hw -> base + ALTERA_SPI_CONTROL );
83
+ if (hw -> tx ) {
84
+ switch (hw -> bytes_per_word ) {
85
+ case 1 :
86
+ txd = hw -> tx [hw -> count ];
87
+ break ;
88
+ case 2 :
89
+ txd = (hw -> tx [hw -> count * 2 ]
90
+ | (hw -> tx [hw -> count * 2 + 1 ] << 8 ));
100
91
break ;
101
92
}
102
93
}
94
+
95
+ writel (txd , hw -> base + ALTERA_SPI_TXDATA );
103
96
}
104
97
105
- static inline unsigned int hw_txbyte (struct altera_spi * hw , int count )
98
+ static void altera_spi_rx_word (struct altera_spi * hw )
106
99
{
107
- if (hw -> tx ) {
100
+ unsigned int rxd ;
101
+
102
+ rxd = readl (hw -> base + ALTERA_SPI_RXDATA );
103
+ if (hw -> rx ) {
108
104
switch (hw -> bytes_per_word ) {
109
105
case 1 :
110
- return hw -> tx [count ];
106
+ hw -> rx [hw -> count ] = rxd ;
107
+ break ;
111
108
case 2 :
112
- return (hw -> tx [count * 2 ]
113
- | (hw -> tx [count * 2 + 1 ] << 8 ));
109
+ hw -> rx [hw -> count * 2 ] = rxd ;
110
+ hw -> rx [hw -> count * 2 + 1 ] = rxd >> 8 ;
111
+ break ;
114
112
}
115
113
}
116
- return 0 ;
114
+
115
+ hw -> count ++ ;
117
116
}
118
117
119
- static int altera_spi_txrx (struct spi_device * spi , struct spi_transfer * t )
118
+ static int altera_spi_txrx (struct spi_master * master ,
119
+ struct spi_device * spi , struct spi_transfer * t )
120
120
{
121
- struct altera_spi * hw = altera_spi_to_hw ( spi );
121
+ struct altera_spi * hw = spi_master_get_devdata ( master );
122
122
123
123
hw -> tx = t -> tx_buf ;
124
124
hw -> rx = t -> rx_buf ;
@@ -132,67 +132,39 @@ static int altera_spi_txrx(struct spi_device *spi, struct spi_transfer *t)
132
132
writel (hw -> imr , hw -> base + ALTERA_SPI_CONTROL );
133
133
134
134
/* send the first byte */
135
- writel (hw_txbyte (hw , 0 ), hw -> base + ALTERA_SPI_TXDATA );
136
-
137
- wait_for_completion (& hw -> done );
138
- /* disable receive interrupt */
139
- hw -> imr &= ~ALTERA_SPI_CONTROL_IRRDY_MSK ;
140
- writel (hw -> imr , hw -> base + ALTERA_SPI_CONTROL );
135
+ altera_spi_tx_word (hw );
141
136
} else {
142
137
while (hw -> count < hw -> len ) {
143
- unsigned int rxd ;
144
-
145
- writel (hw_txbyte (hw , hw -> count ),
146
- hw -> base + ALTERA_SPI_TXDATA );
138
+ altera_spi_tx_word (hw );
147
139
148
140
while (!(readl (hw -> base + ALTERA_SPI_STATUS ) &
149
141
ALTERA_SPI_STATUS_RRDY_MSK ))
150
142
cpu_relax ();
151
143
152
- rxd = readl (hw -> base + ALTERA_SPI_RXDATA );
153
- if (hw -> rx ) {
154
- switch (hw -> bytes_per_word ) {
155
- case 1 :
156
- hw -> rx [hw -> count ] = rxd ;
157
- break ;
158
- case 2 :
159
- hw -> rx [hw -> count * 2 ] = rxd ;
160
- hw -> rx [hw -> count * 2 + 1 ] = rxd >> 8 ;
161
- break ;
162
- }
163
- }
164
-
165
- hw -> count ++ ;
144
+ altera_spi_rx_word (hw );
166
145
}
146
+ spi_finalize_current_transfer (master );
167
147
}
168
148
169
- return hw -> count * hw -> bytes_per_word ;
149
+ return t -> len ;
170
150
}
171
151
172
152
static irqreturn_t altera_spi_irq (int irq , void * dev )
173
153
{
174
- struct altera_spi * hw = dev ;
175
- unsigned int rxd ;
154
+ struct spi_master * master = dev ;
155
+ struct altera_spi * hw = spi_master_get_devdata ( master ) ;
176
156
177
- rxd = readl (hw -> base + ALTERA_SPI_RXDATA );
178
- if (hw -> rx ) {
179
- switch (hw -> bytes_per_word ) {
180
- case 1 :
181
- hw -> rx [hw -> count ] = rxd ;
182
- break ;
183
- case 2 :
184
- hw -> rx [hw -> count * 2 ] = rxd ;
185
- hw -> rx [hw -> count * 2 + 1 ] = rxd >> 8 ;
186
- break ;
187
- }
188
- }
157
+ altera_spi_rx_word (hw );
189
158
190
- hw -> count ++ ;
159
+ if (hw -> count < hw -> len ) {
160
+ altera_spi_tx_word (hw );
161
+ } else {
162
+ /* disable receive interrupt */
163
+ hw -> imr &= ~ALTERA_SPI_CONTROL_IRRDY_MSK ;
164
+ writel (hw -> imr , hw -> base + ALTERA_SPI_CONTROL );
191
165
192
- if (hw -> count < hw -> len )
193
- writel (hw_txbyte (hw , hw -> count ), hw -> base + ALTERA_SPI_TXDATA );
194
- else
195
- complete (& hw -> done );
166
+ spi_finalize_current_transfer (master );
167
+ }
196
168
197
169
return IRQ_HANDLED ;
198
170
}
@@ -214,14 +186,10 @@ static int altera_spi_probe(struct platform_device *pdev)
214
186
master -> mode_bits = SPI_CS_HIGH ;
215
187
master -> bits_per_word_mask = SPI_BPW_RANGE_MASK (1 , 16 );
216
188
master -> dev .of_node = pdev -> dev .of_node ;
189
+ master -> transfer_one = altera_spi_txrx ;
190
+ master -> set_cs = altera_spi_set_cs ;
217
191
218
192
hw = spi_master_get_devdata (master );
219
- platform_set_drvdata (pdev , hw );
220
-
221
- /* setup the state for the bitbang driver */
222
- hw -> bitbang .master = master ;
223
- hw -> bitbang .chipselect = altera_spi_chipsel ;
224
- hw -> bitbang .txrx_bufs = altera_spi_txrx ;
225
193
226
194
/* find and map our resources */
227
195
res = platform_get_resource (pdev , IORESOURCE_MEM , 0 );
@@ -239,15 +207,13 @@ static int altera_spi_probe(struct platform_device *pdev)
239
207
/* irq is optional */
240
208
hw -> irq = platform_get_irq (pdev , 0 );
241
209
if (hw -> irq >= 0 ) {
242
- init_completion (& hw -> done );
243
210
err = devm_request_irq (& pdev -> dev , hw -> irq , altera_spi_irq , 0 ,
244
- pdev -> name , hw );
211
+ pdev -> name , master );
245
212
if (err )
246
213
goto exit ;
247
214
}
248
215
249
- /* register our spi controller */
250
- err = spi_bitbang_start (& hw -> bitbang );
216
+ err = devm_spi_register_master (& pdev -> dev , master );
251
217
if (err )
252
218
goto exit ;
253
219
dev_info (& pdev -> dev , "base %p, irq %d\n" , hw -> base , hw -> irq );
@@ -258,16 +224,6 @@ static int altera_spi_probe(struct platform_device *pdev)
258
224
return err ;
259
225
}
260
226
261
- static int altera_spi_remove (struct platform_device * dev )
262
- {
263
- struct altera_spi * hw = platform_get_drvdata (dev );
264
- struct spi_master * master = hw -> bitbang .master ;
265
-
266
- spi_bitbang_stop (& hw -> bitbang );
267
- spi_master_put (master );
268
- return 0 ;
269
- }
270
-
271
227
#ifdef CONFIG_OF
272
228
static const struct of_device_id altera_spi_match [] = {
273
229
{ .compatible = "ALTR,spi-1.0" , },
@@ -279,7 +235,6 @@ MODULE_DEVICE_TABLE(of, altera_spi_match);
279
235
280
236
static struct platform_driver altera_spi_driver = {
281
237
.probe = altera_spi_probe ,
282
- .remove = altera_spi_remove ,
283
238
.driver = {
284
239
.name = DRV_NAME ,
285
240
.pm = NULL ,
0 commit comments