Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/arm/ti/ti_spi.c
39481 views
1
/*-
2
* Copyright (c) 2016 Rubicon Communications, LLC (Netgate)
3
* All rights reserved.
4
*
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted provided that the following conditions
7
* are met:
8
* 1. Redistributions of source code must retain the above copyright
9
* notice, this list of conditions and the following disclaimer.
10
* 2. Redistributions in binary form must reproduce the above copyright
11
* notice, this list of conditions and the following disclaimer in the
12
* documentation and/or other materials provided with the distribution.
13
*
14
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24
* SUCH DAMAGE.
25
*
26
*/
27
28
#include <sys/param.h>
29
#include <sys/systm.h>
30
#include <sys/bus.h>
31
32
#include <sys/kernel.h>
33
#include <sys/module.h>
34
#include <sys/rman.h>
35
#include <sys/lock.h>
36
#include <sys/mutex.h>
37
#include <sys/sysctl.h>
38
39
#include <machine/bus.h>
40
#include <machine/resource.h>
41
#include <machine/intr.h>
42
43
#include <dev/ofw/ofw_bus.h>
44
#include <dev/ofw/ofw_bus_subr.h>
45
46
#include <dev/spibus/spi.h>
47
#include <dev/spibus/spibusvar.h>
48
49
#include <arm/ti/ti_sysc.h>
50
#include <arm/ti/ti_spireg.h>
51
#include <arm/ti/ti_spivar.h>
52
53
#include "spibus_if.h"
54
55
static void ti_spi_intr(void *);
56
static int ti_spi_detach(device_t);
57
58
#undef TI_SPI_DEBUG
59
#ifdef TI_SPI_DEBUG
60
#define IRQSTATUSBITS \
61
"\020\1TX0_EMPTY\2TX0_UNDERFLOW\3RX0_FULL\4RX0_OVERFLOW" \
62
"\5TX1_EMPTY\6TX1_UNDERFLOW\7RX1_FULL\11TX2_EMPTY" \
63
"\12TX1_UNDERFLOW\13RX2_FULL\15TX3_EMPTY\16TX3_UNDERFLOW" \
64
"\17RX3_FULL\22EOW"
65
#define CONFBITS \
66
"\020\1PHA\2POL\7EPOL\17DMAW\20DMAR\21DPE0\22DPE1\23IS" \
67
"\24TURBO\25FORCE\30SBE\31SBPOL\34FFEW\35FFER\36CLKG"
68
#define STATBITS \
69
"\020\1RXS\2TXS\3EOT\4TXFFE\5TXFFF\6RXFFE\7RXFFFF"
70
#define MODULCTRLBITS \
71
"\020\1SINGLE\2NOSPIEN\3SLAVE\4SYST\10MOA\11FDAA"
72
#define CTRLBITS \
73
"\020\1ENABLED"
74
75
static void
76
ti_spi_printr(device_t dev)
77
{
78
int clk, conf, ctrl, div, i, j, wl;
79
struct ti_spi_softc *sc;
80
uint32_t reg;
81
82
sc = device_get_softc(dev);
83
reg = TI_SPI_READ(sc, MCSPI_SYSCONFIG);
84
device_printf(dev, "SYSCONFIG: %#x\n", reg);
85
reg = TI_SPI_READ(sc, MCSPI_SYSSTATUS);
86
device_printf(dev, "SYSSTATUS: %#x\n", reg);
87
reg = TI_SPI_READ(sc, MCSPI_IRQSTATUS);
88
device_printf(dev, "IRQSTATUS: 0x%b\n", reg, IRQSTATUSBITS);
89
reg = TI_SPI_READ(sc, MCSPI_IRQENABLE);
90
device_printf(dev, "IRQENABLE: 0x%b\n", reg, IRQSTATUSBITS);
91
reg = TI_SPI_READ(sc, MCSPI_MODULCTRL);
92
device_printf(dev, "MODULCTRL: 0x%b\n", reg, MODULCTRLBITS);
93
for (i = 0; i < sc->sc_numcs; i++) {
94
ctrl = TI_SPI_READ(sc, MCSPI_CTRL_CH(i));
95
conf = TI_SPI_READ(sc, MCSPI_CONF_CH(i));
96
device_printf(dev, "CH%dCONF: 0x%b\n", i, conf, CONFBITS);
97
if (conf & MCSPI_CONF_CLKG) {
98
div = (conf >> MCSPI_CONF_CLK_SHIFT) & MCSPI_CONF_CLK_MSK;
99
div |= ((ctrl >> MCSPI_CTRL_EXTCLK_SHIFT) & MCSPI_CTRL_EXTCLK_MSK) << 4;
100
} else {
101
div = 1;
102
j = (conf >> MCSPI_CONF_CLK_SHIFT) & MCSPI_CONF_CLK_MSK;
103
while (j-- > 0)
104
div <<= 1;
105
}
106
clk = TI_SPI_GCLK / div;
107
wl = ((conf >> MCSPI_CONF_WL_SHIFT) & MCSPI_CONF_WL_MSK) + 1;
108
device_printf(dev, "wordlen: %-2d clock: %d\n", wl, clk);
109
reg = TI_SPI_READ(sc, MCSPI_STAT_CH(i));
110
device_printf(dev, "CH%dSTAT: 0x%b\n", i, reg, STATBITS);
111
device_printf(dev, "CH%dCTRL: 0x%b\n", i, ctrl, CTRLBITS);
112
}
113
reg = TI_SPI_READ(sc, MCSPI_XFERLEVEL);
114
device_printf(dev, "XFERLEVEL: %#x\n", reg);
115
}
116
#endif
117
118
static void
119
ti_spi_set_clock(struct ti_spi_softc *sc, int ch, int freq)
120
{
121
uint32_t clkdiv, conf, div, extclk, reg;
122
123
clkdiv = TI_SPI_GCLK / freq;
124
if (clkdiv > MCSPI_EXTCLK_MSK) {
125
extclk = 0;
126
clkdiv = 0;
127
div = 1;
128
while (TI_SPI_GCLK / div > freq && clkdiv <= 0xf) {
129
clkdiv++;
130
div <<= 1;
131
}
132
conf = clkdiv << MCSPI_CONF_CLK_SHIFT;
133
} else {
134
extclk = clkdiv >> 4;
135
clkdiv &= MCSPI_CONF_CLK_MSK;
136
conf = MCSPI_CONF_CLKG | clkdiv << MCSPI_CONF_CLK_SHIFT;
137
}
138
139
reg = TI_SPI_READ(sc, MCSPI_CTRL_CH(ch));
140
reg &= ~(MCSPI_CTRL_EXTCLK_MSK << MCSPI_CTRL_EXTCLK_SHIFT);
141
reg |= extclk << MCSPI_CTRL_EXTCLK_SHIFT;
142
TI_SPI_WRITE(sc, MCSPI_CTRL_CH(ch), reg);
143
144
reg = TI_SPI_READ(sc, MCSPI_CONF_CH(ch));
145
reg &= ~(MCSPI_CONF_CLKG | MCSPI_CONF_CLK_MSK << MCSPI_CONF_CLK_SHIFT);
146
TI_SPI_WRITE(sc, MCSPI_CONF_CH(ch), reg | conf);
147
}
148
149
static int
150
ti_spi_probe(device_t dev)
151
{
152
153
if (!ofw_bus_status_okay(dev))
154
return (ENXIO);
155
if (!ofw_bus_is_compatible(dev, "ti,omap4-mcspi"))
156
return (ENXIO);
157
158
device_set_desc(dev, "TI McSPI controller");
159
160
return (BUS_PROBE_DEFAULT);
161
}
162
163
static int
164
ti_spi_attach(device_t dev)
165
{
166
int err, i, rid, timeout;
167
struct ti_spi_softc *sc;
168
uint32_t rev;
169
170
sc = device_get_softc(dev);
171
sc->sc_dev = dev;
172
173
/* Activate the McSPI module. */
174
err = ti_sysc_clock_enable(device_get_parent(dev));
175
if (err) {
176
device_printf(dev, "Error: failed to activate source clock\n");
177
return (err);
178
}
179
180
/* Get the number of available channels. */
181
if ((OF_getencprop(ofw_bus_get_node(dev), "ti,spi-num-cs",
182
&sc->sc_numcs, sizeof(sc->sc_numcs))) <= 0) {
183
sc->sc_numcs = 2;
184
}
185
186
rid = 0;
187
sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
188
RF_ACTIVE);
189
if (!sc->sc_mem_res) {
190
device_printf(dev, "cannot allocate memory window\n");
191
return (ENXIO);
192
}
193
194
sc->sc_bst = rman_get_bustag(sc->sc_mem_res);
195
sc->sc_bsh = rman_get_bushandle(sc->sc_mem_res);
196
197
rid = 0;
198
sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
199
RF_ACTIVE);
200
if (!sc->sc_irq_res) {
201
bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
202
device_printf(dev, "cannot allocate interrupt\n");
203
return (ENXIO);
204
}
205
206
/* Hook up our interrupt handler. */
207
if (bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_MISC | INTR_MPSAFE,
208
NULL, ti_spi_intr, sc, &sc->sc_intrhand)) {
209
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res);
210
bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
211
device_printf(dev, "cannot setup the interrupt handler\n");
212
return (ENXIO);
213
}
214
215
mtx_init(&sc->sc_mtx, "ti_spi", NULL, MTX_DEF);
216
217
/* Issue a softreset to the controller */
218
TI_SPI_WRITE(sc, MCSPI_SYSCONFIG, MCSPI_SYSCONFIG_SOFTRESET);
219
timeout = 1000;
220
while (!(TI_SPI_READ(sc, MCSPI_SYSSTATUS) &
221
MCSPI_SYSSTATUS_RESETDONE)) {
222
if (--timeout == 0) {
223
device_printf(dev,
224
"Error: Controller reset operation timed out\n");
225
ti_spi_detach(dev);
226
return (ENXIO);
227
}
228
DELAY(100);
229
}
230
231
/* Print the McSPI module revision. */
232
rev = TI_SPI_READ(sc,
233
ti_sysc_get_rev_address_offset_host(device_get_parent(dev)));
234
device_printf(dev,
235
"scheme: %#x func: %#x rtl: %d rev: %d.%d custom rev: %d\n",
236
(rev >> MCSPI_REVISION_SCHEME_SHIFT) & MCSPI_REVISION_SCHEME_MSK,
237
(rev >> MCSPI_REVISION_FUNC_SHIFT) & MCSPI_REVISION_FUNC_MSK,
238
(rev >> MCSPI_REVISION_RTL_SHIFT) & MCSPI_REVISION_RTL_MSK,
239
(rev >> MCSPI_REVISION_MAJOR_SHIFT) & MCSPI_REVISION_MAJOR_MSK,
240
(rev >> MCSPI_REVISION_MINOR_SHIFT) & MCSPI_REVISION_MINOR_MSK,
241
(rev >> MCSPI_REVISION_CUSTOM_SHIFT) & MCSPI_REVISION_CUSTOM_MSK);
242
243
/* Set Master mode, single channel. */
244
TI_SPI_WRITE(sc, MCSPI_MODULCTRL, MCSPI_MODULCTRL_SINGLE);
245
246
/* Clear pending interrupts and disable interrupts. */
247
TI_SPI_WRITE(sc, MCSPI_IRQENABLE, 0x0);
248
TI_SPI_WRITE(sc, MCSPI_IRQSTATUS, 0xffff);
249
250
for (i = 0; i < sc->sc_numcs; i++) {
251
/*
252
* Default to SPI mode 0, CS active low, 8 bits word length and
253
* 500kHz clock.
254
*/
255
TI_SPI_WRITE(sc, MCSPI_CONF_CH(i),
256
MCSPI_CONF_DPE0 | MCSPI_CONF_EPOL |
257
(8 - 1) << MCSPI_CONF_WL_SHIFT);
258
/* Set initial clock - 500kHz. */
259
ti_spi_set_clock(sc, i, 500000);
260
}
261
262
#ifdef TI_SPI_DEBUG
263
ti_spi_printr(dev);
264
#endif
265
266
device_add_child(dev, "spibus", DEVICE_UNIT_ANY);
267
bus_attach_children(dev);
268
269
return (0);
270
}
271
272
static int
273
ti_spi_detach(device_t dev)
274
{
275
struct ti_spi_softc *sc;
276
int error;
277
278
error = bus_generic_detach(dev);
279
if (error != 0)
280
return (error);
281
282
sc = device_get_softc(dev);
283
284
/* Clear pending interrupts and disable interrupts. */
285
TI_SPI_WRITE(sc, MCSPI_IRQENABLE, 0);
286
TI_SPI_WRITE(sc, MCSPI_IRQSTATUS, 0xffff);
287
288
/* Reset controller. */
289
TI_SPI_WRITE(sc, MCSPI_SYSCONFIG, MCSPI_SYSCONFIG_SOFTRESET);
290
291
mtx_destroy(&sc->sc_mtx);
292
if (sc->sc_intrhand)
293
bus_teardown_intr(dev, sc->sc_irq_res, sc->sc_intrhand);
294
if (sc->sc_irq_res)
295
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res);
296
if (sc->sc_mem_res)
297
bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
298
299
return (0);
300
}
301
302
static int
303
ti_spi_fill_fifo(struct ti_spi_softc *sc)
304
{
305
int bytes, timeout;
306
struct spi_command *cmd;
307
uint32_t written;
308
uint8_t *data;
309
310
cmd = sc->sc_cmd;
311
bytes = min(sc->sc_len - sc->sc_written, sc->sc_fifolvl);
312
while (bytes-- > 0) {
313
data = (uint8_t *)cmd->tx_cmd;
314
written = sc->sc_written++;
315
if (written >= cmd->tx_cmd_sz) {
316
data = (uint8_t *)cmd->tx_data;
317
written -= cmd->tx_cmd_sz;
318
}
319
if (sc->sc_fifolvl == 1) {
320
/* FIFO disabled. */
321
timeout = 1000;
322
while (--timeout > 0 && (TI_SPI_READ(sc,
323
MCSPI_STAT_CH(sc->sc_cs)) & MCSPI_STAT_TXS) == 0) {
324
DELAY(100);
325
}
326
if (timeout == 0)
327
return (-1);
328
}
329
TI_SPI_WRITE(sc, MCSPI_TX_CH(sc->sc_cs), data[written]);
330
}
331
332
return (0);
333
}
334
335
static int
336
ti_spi_drain_fifo(struct ti_spi_softc *sc)
337
{
338
int bytes, timeout;
339
struct spi_command *cmd;
340
uint32_t read;
341
uint8_t *data;
342
343
cmd = sc->sc_cmd;
344
bytes = min(sc->sc_len - sc->sc_read, sc->sc_fifolvl);
345
while (bytes-- > 0) {
346
data = (uint8_t *)cmd->rx_cmd;
347
read = sc->sc_read++;
348
if (read >= cmd->rx_cmd_sz) {
349
data = (uint8_t *)cmd->rx_data;
350
read -= cmd->rx_cmd_sz;
351
}
352
if (sc->sc_fifolvl == 1) {
353
/* FIFO disabled. */
354
timeout = 1000;
355
while (--timeout > 0 && (TI_SPI_READ(sc,
356
MCSPI_STAT_CH(sc->sc_cs)) & MCSPI_STAT_RXS) == 0) {
357
DELAY(100);
358
}
359
if (timeout == 0)
360
return (-1);
361
}
362
data[read] = TI_SPI_READ(sc, MCSPI_RX_CH(sc->sc_cs));
363
}
364
365
return (0);
366
}
367
368
static void
369
ti_spi_intr(void *arg)
370
{
371
struct ti_spi_softc *sc;
372
uint32_t status;
373
374
sc = (struct ti_spi_softc *)arg;
375
TI_SPI_LOCK(sc);
376
status = TI_SPI_READ(sc, MCSPI_IRQSTATUS);
377
378
/*
379
* No new TX_empty or RX_full event will be asserted while the CPU has
380
* not performed the number of writes or reads defined by
381
* MCSPI_XFERLEVEL[AEL] and MCSPI_XFERLEVEL[AFL]. It is responsibility
382
* of CPU perform the right number of writes and reads.
383
*/
384
if (status & MCSPI_IRQ_TX0_EMPTY)
385
ti_spi_fill_fifo(sc);
386
if (status & MCSPI_IRQ_RX0_FULL)
387
ti_spi_drain_fifo(sc);
388
389
/* Clear interrupt status. */
390
TI_SPI_WRITE(sc, MCSPI_IRQSTATUS, status);
391
392
/* Check for end of transfer. */
393
if (sc->sc_written == sc->sc_len && sc->sc_read == sc->sc_len) {
394
sc->sc_flags |= TI_SPI_DONE;
395
wakeup(sc->sc_dev);
396
}
397
398
TI_SPI_UNLOCK(sc);
399
}
400
401
static int
402
ti_spi_pio_transfer(struct ti_spi_softc *sc)
403
{
404
405
while (sc->sc_len - sc->sc_written > 0) {
406
if (ti_spi_fill_fifo(sc) == -1)
407
return (EIO);
408
if (ti_spi_drain_fifo(sc) == -1)
409
return (EIO);
410
}
411
412
return (0);
413
}
414
415
static int
416
ti_spi_gcd(int a, int b)
417
{
418
int m;
419
420
while ((m = a % b) != 0) {
421
a = b;
422
b = m;
423
}
424
425
return (b);
426
}
427
428
static int
429
ti_spi_transfer(device_t dev, device_t child, struct spi_command *cmd)
430
{
431
int err;
432
struct ti_spi_softc *sc;
433
uint32_t clockhz, cs, mode, reg;
434
435
sc = device_get_softc(dev);
436
437
KASSERT(cmd->tx_cmd_sz == cmd->rx_cmd_sz,
438
("TX/RX command sizes should be equal"));
439
KASSERT(cmd->tx_data_sz == cmd->rx_data_sz,
440
("TX/RX data sizes should be equal"));
441
442
/* Get the proper chip select for this child. */
443
spibus_get_cs(child, &cs);
444
spibus_get_clock(child, &clockhz);
445
spibus_get_mode(child, &mode);
446
447
cs &= ~SPIBUS_CS_HIGH;
448
449
if (cs > sc->sc_numcs) {
450
device_printf(dev, "Invalid chip select %d requested by %s\n",
451
cs, device_get_nameunit(child));
452
return (EINVAL);
453
}
454
455
if (mode > 3)
456
{
457
device_printf(dev, "Invalid mode %d requested by %s\n", mode,
458
device_get_nameunit(child));
459
return (EINVAL);
460
}
461
462
TI_SPI_LOCK(sc);
463
464
/* If the controller is in use wait until it is available. */
465
while (sc->sc_flags & TI_SPI_BUSY)
466
mtx_sleep(dev, &sc->sc_mtx, 0, "ti_spi", 0);
467
468
/* Now we have control over SPI controller. */
469
sc->sc_flags = TI_SPI_BUSY;
470
471
/* Save the SPI command data. */
472
sc->sc_cs = cs;
473
sc->sc_cmd = cmd;
474
sc->sc_read = 0;
475
sc->sc_written = 0;
476
sc->sc_len = cmd->tx_cmd_sz + cmd->tx_data_sz;
477
sc->sc_fifolvl = ti_spi_gcd(sc->sc_len, TI_SPI_FIFOSZ);
478
if (sc->sc_fifolvl < 2 || sc->sc_len > 0xffff)
479
sc->sc_fifolvl = 1; /* FIFO disabled. */
480
/* Disable FIFO for now. */
481
sc->sc_fifolvl = 1;
482
483
/* Set the bus frequency. */
484
ti_spi_set_clock(sc, sc->sc_cs, clockhz);
485
486
/* Disable the FIFO. */
487
TI_SPI_WRITE(sc, MCSPI_XFERLEVEL, 0);
488
489
/* 8 bits word, d0 miso, d1 mosi, mode 0 and CS active low. */
490
reg = TI_SPI_READ(sc, MCSPI_CONF_CH(sc->sc_cs));
491
reg &= ~(MCSPI_CONF_FFER | MCSPI_CONF_FFEW | MCSPI_CONF_SBPOL |
492
MCSPI_CONF_SBE | MCSPI_CONF_TURBO | MCSPI_CONF_IS |
493
MCSPI_CONF_DPE1 | MCSPI_CONF_DPE0 | MCSPI_CONF_DMAR |
494
MCSPI_CONF_DMAW | MCSPI_CONF_EPOL);
495
reg |= MCSPI_CONF_DPE0 | MCSPI_CONF_EPOL | MCSPI_CONF_WL8BITS;
496
reg |= mode; /* POL and PHA are the low bits, we can just OR-in mode */
497
TI_SPI_WRITE(sc, MCSPI_CONF_CH(sc->sc_cs), reg);
498
499
#if 0
500
/* Enable channel interrupts. */
501
reg = TI_SPI_READ(sc, MCSPI_IRQENABLE);
502
reg |= 0xf;
503
TI_SPI_WRITE(sc, MCSPI_IRQENABLE, reg);
504
#endif
505
506
/* Start the transfer. */
507
reg = TI_SPI_READ(sc, MCSPI_CTRL_CH(sc->sc_cs));
508
TI_SPI_WRITE(sc, MCSPI_CTRL_CH(sc->sc_cs), reg | MCSPI_CTRL_ENABLE);
509
510
/* Force CS on. */
511
reg = TI_SPI_READ(sc, MCSPI_CONF_CH(sc->sc_cs));
512
TI_SPI_WRITE(sc, MCSPI_CONF_CH(sc->sc_cs), reg |= MCSPI_CONF_FORCE);
513
514
err = 0;
515
if (sc->sc_fifolvl == 1)
516
err = ti_spi_pio_transfer(sc);
517
518
/* Force CS off. */
519
reg = TI_SPI_READ(sc, MCSPI_CONF_CH(sc->sc_cs));
520
reg &= ~MCSPI_CONF_FORCE;
521
TI_SPI_WRITE(sc, MCSPI_CONF_CH(sc->sc_cs), reg);
522
523
/* Disable IRQs. */
524
reg = TI_SPI_READ(sc, MCSPI_IRQENABLE);
525
reg &= ~0xf;
526
TI_SPI_WRITE(sc, MCSPI_IRQENABLE, reg);
527
TI_SPI_WRITE(sc, MCSPI_IRQSTATUS, 0xf);
528
529
/* Disable the SPI channel. */
530
reg = TI_SPI_READ(sc, MCSPI_CTRL_CH(sc->sc_cs));
531
reg &= ~MCSPI_CTRL_ENABLE;
532
TI_SPI_WRITE(sc, MCSPI_CTRL_CH(sc->sc_cs), reg);
533
534
/* Disable FIFO. */
535
reg = TI_SPI_READ(sc, MCSPI_CONF_CH(sc->sc_cs));
536
reg &= ~(MCSPI_CONF_FFER | MCSPI_CONF_FFEW);
537
TI_SPI_WRITE(sc, MCSPI_CONF_CH(sc->sc_cs), reg);
538
539
/* Release the controller and wakeup the next thread waiting for it. */
540
sc->sc_flags = 0;
541
wakeup_one(dev);
542
TI_SPI_UNLOCK(sc);
543
544
return (err);
545
}
546
547
static phandle_t
548
ti_spi_get_node(device_t bus, device_t dev)
549
{
550
551
/* Share controller node with spibus. */
552
return (ofw_bus_get_node(bus));
553
}
554
555
static device_method_t ti_spi_methods[] = {
556
/* Device interface */
557
DEVMETHOD(device_probe, ti_spi_probe),
558
DEVMETHOD(device_attach, ti_spi_attach),
559
DEVMETHOD(device_detach, ti_spi_detach),
560
561
/* SPI interface */
562
DEVMETHOD(spibus_transfer, ti_spi_transfer),
563
564
/* ofw_bus interface */
565
DEVMETHOD(ofw_bus_get_node, ti_spi_get_node),
566
567
DEVMETHOD_END
568
};
569
570
static driver_t ti_spi_driver = {
571
"spi",
572
ti_spi_methods,
573
sizeof(struct ti_spi_softc),
574
};
575
576
DRIVER_MODULE(ti_spi, simplebus, ti_spi_driver, 0, 0);
577
MODULE_DEPEND(ti_spi, ti_sysc, 1, 1, 1);
578
579