sdhc.c revision 1.7.2.6 1 /* $NetBSD: sdhc.c,v 1.7.2.6 2014/02/15 03:33:40 matt Exp $ */
2 /* $OpenBSD: sdhc.c,v 1.25 2009/01/13 19:44:20 grange Exp $ */
3
4 /*
5 * Copyright (c) 2006 Uwe Stuehler <uwe (at) openbsd.org>
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20 /*
21 * SD Host Controller driver based on the SD Host Controller Standard
22 * Simplified Specification Version 1.00 (www.sdcard.com).
23 */
24
25 #include <sys/cdefs.h>
26 __KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.7.2.6 2014/02/15 03:33:40 matt Exp $");
27
28 #include <sys/param.h>
29 #include <sys/device.h>
30 #include <sys/kernel.h>
31 #include <sys/kthread.h>
32 #include <sys/malloc.h>
33 #include <sys/systm.h>
34 #include <sys/mutex.h>
35 #include <sys/condvar.h>
36
37 #include <dev/sdmmc/sdhcreg.h>
38 #include <dev/sdmmc/sdhcvar.h>
39 #include <dev/sdmmc/sdmmcchip.h>
40 #include <dev/sdmmc/sdmmcreg.h>
41 #include <dev/sdmmc/sdmmcvar.h>
42
43 #ifdef SDHC_DEBUG
44 int sdhcdebug = 0;
45 #define DPRINTF(n,s) do { if ((n) <= sdhcdebug) printf s; } while (0)
46 void sdhc_dump_regs(struct sdhc_host *);
47 #else
48 #define DPRINTF(n,s) do {} while (0)
49 #endif
50
51 #define SDHC_COMMAND_TIMEOUT hz
52 #define SDHC_BUFFER_TIMEOUT hz
53 #define SDHC_TRANSFER_TIMEOUT hz
54 #define SDHC_DMA_TIMEOUT hz
55
56 struct sdhc_host {
57 struct sdhc_softc *sc; /* host controller device */
58
59 bus_space_tag_t iot; /* host register set tag */
60 bus_space_handle_t ioh; /* host register set handle */
61 bus_dma_tag_t dmat; /* host DMA tag */
62
63 device_t sdmmc; /* generic SD/MMC device */
64
65 struct kmutex host_mtx;
66
67 u_int clkbase; /* base clock frequency in KHz */
68 int maxblklen; /* maximum block length */
69 uint32_t ocr; /* OCR value from capabilities */
70
71 uint8_t regs[14]; /* host controller state */
72
73 uint16_t intr_status; /* soft interrupt status */
74 uint16_t intr_error_status; /* soft error status */
75 struct kmutex intr_mtx;
76 struct kcondvar intr_cv;
77
78 uint32_t flags; /* flags for this host */
79 #define SHF_USE_DMA 0x0001
80 #define SHF_USE_4BIT_MODE 0x0002
81 };
82
83 #define HDEVNAME(hp) (device_xname((hp)->sc->sc_dev))
84
85 #define HREAD1(hp, reg) \
86 (bus_space_read_1((hp)->iot, (hp)->ioh, (reg)))
87 #define HREAD2(hp, reg) \
88 (bus_space_read_2((hp)->iot, (hp)->ioh, (reg)))
89 #define HREAD4(hp, reg) \
90 (bus_space_read_4((hp)->iot, (hp)->ioh, (reg)))
91 #define HWRITE1(hp, reg, val) \
92 bus_space_write_1((hp)->iot, (hp)->ioh, (reg), (val))
93 #define HWRITE2(hp, reg, val) \
94 bus_space_write_2((hp)->iot, (hp)->ioh, (reg), (val))
95 #define HWRITE4(hp, reg, val) \
96 bus_space_write_4((hp)->iot, (hp)->ioh, (reg), (val))
97 #define HCLR1(hp, reg, bits) \
98 HWRITE1((hp), (reg), HREAD1((hp), (reg)) & ~(bits))
99 #define HCLR2(hp, reg, bits) \
100 HWRITE2((hp), (reg), HREAD2((hp), (reg)) & ~(bits))
101 #define HSET1(hp, reg, bits) \
102 HWRITE1((hp), (reg), HREAD1((hp), (reg)) | (bits))
103 #define HSET2(hp, reg, bits) \
104 HWRITE2((hp), (reg), HREAD2((hp), (reg)) | (bits))
105
106 static int sdhc_host_reset(sdmmc_chipset_handle_t);
107 static int sdhc_host_reset1(sdmmc_chipset_handle_t);
108 static uint32_t sdhc_host_ocr(sdmmc_chipset_handle_t);
109 static int sdhc_host_maxblklen(sdmmc_chipset_handle_t);
110 static int sdhc_card_detect(sdmmc_chipset_handle_t);
111 static int sdhc_write_protect(sdmmc_chipset_handle_t);
112 static int sdhc_bus_power(sdmmc_chipset_handle_t, uint32_t);
113 static int sdhc_bus_clock(sdmmc_chipset_handle_t, int);
114 static int sdhc_bus_width(sdmmc_chipset_handle_t, int);
115 static void sdhc_card_enable_intr(sdmmc_chipset_handle_t, int);
116 static void sdhc_card_intr_ack(sdmmc_chipset_handle_t);
117 static void sdhc_exec_command(sdmmc_chipset_handle_t,
118 struct sdmmc_command *);
119 static int sdhc_start_command(struct sdhc_host *, struct sdmmc_command *);
120 static int sdhc_wait_state(struct sdhc_host *, uint32_t, uint32_t);
121 static int sdhc_soft_reset(struct sdhc_host *, int);
122 static int sdhc_wait_intr(struct sdhc_host *, int, int);
123 static void sdhc_transfer_data(struct sdhc_host *, struct sdmmc_command *);
124 static int sdhc_transfer_data_pio(struct sdhc_host *, struct sdmmc_command *);
125 static void sdhc_read_data_pio(struct sdhc_host *, uint8_t *, int);
126 static void sdhc_write_data_pio(struct sdhc_host *, uint8_t *, int);
127
128 static struct sdmmc_chip_functions sdhc_functions = {
129 /* host controller reset */
130 sdhc_host_reset,
131
132 /* host controller capabilities */
133 sdhc_host_ocr,
134 sdhc_host_maxblklen,
135
136 /* card detection */
137 sdhc_card_detect,
138
139 /* write protect */
140 sdhc_write_protect,
141
142 /* bus power, clock frequency and width */
143 sdhc_bus_power,
144 sdhc_bus_clock,
145 sdhc_bus_width,
146
147 /* command execution */
148 sdhc_exec_command,
149
150 /* card interrupt */
151 sdhc_card_enable_intr,
152 sdhc_card_intr_ack
153 };
154
155 /*
156 * Called by attachment driver. For each SD card slot there is one SD
157 * host controller standard register set. (1.3)
158 */
159 int
160 sdhc_host_found(struct sdhc_softc *sc, bus_space_tag_t iot,
161 bus_space_handle_t ioh, bus_size_t iosize)
162 {
163 struct sdmmcbus_attach_args saa;
164 struct sdhc_host *hp;
165 uint32_t caps;
166 #ifdef SDHC_DEBUG
167 uint16_t sdhcver;
168
169 sdhcver = bus_space_read_2(iot, ioh, SDHC_HOST_CTL_VERSION);
170 aprint_normal_dev(sc->sc_dev, "SD Host Specification/Vendor Version ");
171 switch (SDHC_SPEC_VERSION(sdhcver)) {
172 case 0x00:
173 aprint_normal("1.0/%u\n", SDHC_VENDOR_VERSION(sdhcver));
174 break;
175
176 default:
177 aprint_normal(">1.0/%u\n", SDHC_VENDOR_VERSION(sdhcver));
178 break;
179 }
180 #endif
181
182 /* Allocate one more host structure. */
183 hp = malloc(sizeof(struct sdhc_host), M_DEVBUF, M_WAITOK|M_ZERO);
184 if (hp == NULL) {
185 aprint_error_dev(sc->sc_dev,
186 "couldn't alloc memory (sdhc host)\n");
187 goto err1;
188 }
189 sc->sc_host[sc->sc_nhosts++] = hp;
190
191 /* Fill in the new host structure. */
192 hp->sc = sc;
193 hp->iot = iot;
194 hp->ioh = ioh;
195 hp->dmat = sc->sc_dmat;
196
197 mutex_init(&hp->host_mtx, MUTEX_DEFAULT, IPL_SDMMC);
198 mutex_init(&hp->intr_mtx, MUTEX_DEFAULT, IPL_SDMMC);
199 cv_init(&hp->intr_cv, "sdhcintr");
200
201 /*
202 * Reset the host controller and enable interrupts.
203 */
204 (void)sdhc_host_reset(hp);
205
206 /* Determine host capabilities. */
207 mutex_enter(&hp->host_mtx);
208 caps = HREAD4(hp, SDHC_CAPABILITIES);
209 mutex_exit(&hp->host_mtx);
210
211 DPRINTF(1,("%s: caps=0x%08x\n", device_xname(sc->sc_dev), caps));
212
213 #if notyet
214 /* Use DMA if the host system and the controller support it. */
215 if (ISSET(sc->sc_flags, SDHC_FLAG_FORCE_DMA)
216 || ((ISSET(sc->sc_flags, SDHC_FLAG_USE_DMA)
217 && ISSET(caps, SDHC_DMA_SUPPORT)))) {
218 SET(hp->flags, SHF_USE_DMA);
219 aprint_normal_dev(sc->sc_dev, "using DMA transfer\n");
220 }
221 #endif
222
223 /*
224 * Determine the base clock frequency. (2.2.24)
225 */
226 if (SDHC_BASE_FREQ_KHZ(caps) != 0)
227 hp->clkbase = SDHC_BASE_FREQ_KHZ(caps);
228 if (hp->clkbase == 0) {
229 if (sc->sc_clkbase == 0) {
230 /* The attachment driver must tell us. */
231 aprint_error_dev(sc->sc_dev,"unknown base clock frequency\n");
232 goto err;
233 }
234 hp->clkbase = sc->sc_clkbase;
235 }
236 if (hp->clkbase < 10000 || hp->clkbase > 10000 * 256) {
237 /* SDHC 1.0 supports only 10-63 MHz. */
238 /* SDHC 1.0 supports only 10-255 MHz. */
239 aprint_error_dev(sc->sc_dev,
240 "base clock frequency out of range: %u MHz\n",
241 hp->clkbase / 1000);
242 goto err;
243 }
244 DPRINTF(1,("%s: base clock frequency %u MHz\n",
245 device_xname(sc->sc_dev), hp->clkbase / 1000));
246
247 /*
248 * XXX Set the data timeout counter value according to
249 * capabilities. (2.2.15)
250 */
251 HWRITE1(hp, SDHC_TIMEOUT_CTL, SDHC_TIMEOUT_MAX);
252
253 /*
254 * Determine SD bus voltage levels supported by the controller.
255 */
256 if (ISSET(caps, SDHC_VOLTAGE_SUPP_1_8V))
257 SET(hp->ocr, MMC_OCR_1_7V_1_8V | MMC_OCR_1_8V_1_9V);
258 if (ISSET(caps, SDHC_VOLTAGE_SUPP_3_0V))
259 SET(hp->ocr, MMC_OCR_2_9V_3_0V | MMC_OCR_3_0V_3_1V);
260 if (ISSET(caps, SDHC_VOLTAGE_SUPP_3_3V))
261 SET(hp->ocr, MMC_OCR_3_2V_3_3V | MMC_OCR_3_3V_3_4V);
262
263 /*
264 * Determine the maximum block length supported by the host
265 * controller. (2.2.24)
266 */
267 switch((caps >> SDHC_MAX_BLK_LEN_SHIFT) & SDHC_MAX_BLK_LEN_MASK) {
268 case SDHC_MAX_BLK_LEN_512:
269 hp->maxblklen = 512;
270 break;
271
272 case SDHC_MAX_BLK_LEN_1024:
273 hp->maxblklen = 1024;
274 break;
275
276 case SDHC_MAX_BLK_LEN_2048:
277 hp->maxblklen = 2048;
278 break;
279
280 case SDHC_MAX_BLK_LEN_4096:
281 hp->maxblklen = 4096;
282 break;
283
284 default:
285 aprint_error_dev(sc->sc_dev, "max block length unknown\n");
286 goto err;
287 }
288 DPRINTF(1, ("%s: max block length %u byte%s\n",
289 device_xname(sc->sc_dev), hp->maxblklen,
290 hp->maxblklen > 1 ? "s" : ""));
291
292 #if 0
293 if (sc->sc_flags & SDHC_FLAG_HAVE_CGM) {
294 uint16_t clk = HREAD2(hp, SDHC_CLOCK_CTL);
295 clk |= SDHC_SDCLK_CGM;
296 HWRITE2(hp, SDHC_CLOCK_CTL, clk);
297 clk = HREAD2(hp, SDHC_CLOCK_CTL);
298 if ((clk & SDHC_SDCLK_CGM) == 0) {
299 sc->sc_flags &= ~SDHC_FLAG_HAS_CGM;
300 DPRINTF(1, ("%s: CGM indicated but not supported\n",
301 device_xname(sc->sc_dev)));
302 }
303 }
304 #endif
305
306 /*
307 * Attach the generic SD/MMC bus driver. (The bus driver must
308 * not invoke any chipset functions before it is attached.)
309 */
310 memset(&saa, 0, sizeof(saa));
311 saa.saa_busname = "sdmmc";
312 saa.saa_sct = &sdhc_functions;
313 saa.saa_sch = hp;
314 saa.saa_dmat = hp->dmat;
315 if (sc->sc_flags & SDHC_FLAG_HAVE_CGM) {
316 saa.saa_clkmin = hp->clkbase / 2046;
317 } else {
318 saa.saa_clkmin = hp->clkbase / 256;
319 }
320 saa.saa_clkmax = hp->clkbase;
321 if (ISSET(sc->sc_flags, SDHC_FLAG_HAVE_DVS))
322 saa.saa_clkmin /= 16;
323 saa.saa_caps = SMC_CAPS_4BIT_MODE|SMC_CAPS_AUTO_STOP;
324 DPRINTF(1, ("%s: clkmin=%d clkmax=%d\n",
325 device_xname(sc->sc_dev), saa.saa_clkmin, saa.saa_clkmax));
326 #if notyet
327 if (ISSET(hp->flags, SHF_USE_DMA))
328 saa.saa_caps |= SMC_CAPS_DMA;
329 #endif
330
331 hp->sdmmc = config_found(sc->sc_dev, &saa, NULL);
332
333 return 0;
334
335 err:
336 cv_destroy(&hp->intr_cv);
337 mutex_destroy(&hp->intr_mtx);
338 mutex_destroy(&hp->host_mtx);
339 free(hp, M_DEVBUF);
340 sc->sc_host[--sc->sc_nhosts] = NULL;
341 err1:
342 return 1;
343 }
344
345 bool
346 sdhc_suspend(device_t dev PMF_FN_ARGS)
347 {
348 struct sdhc_softc *sc = device_private(dev);
349 struct sdhc_host *hp;
350 int n, i;
351
352 /* XXX poll for command completion or suspend command
353 * in progress */
354
355 /* Save the host controller state. */
356 for (n = 0; n < sc->sc_nhosts; n++) {
357 hp = sc->sc_host[n];
358 for (i = 0; i < sizeof hp->regs; i++)
359 hp->regs[i] = HREAD1(hp, i);
360 }
361 return true;
362 }
363
364 bool
365 sdhc_resume(device_t dev PMF_FN_ARGS)
366 {
367 struct sdhc_softc *sc = device_private(dev);
368 struct sdhc_host *hp;
369 int n, i;
370
371 /* Restore the host controller state. */
372 for (n = 0; n < sc->sc_nhosts; n++) {
373 hp = sc->sc_host[n];
374 (void)sdhc_host_reset(hp);
375 for (i = 0; i < sizeof hp->regs; i++)
376 HWRITE1(hp, i, hp->regs[i]);
377 }
378 return true;
379 }
380
381 bool
382 sdhc_shutdown(device_t dev, int flags)
383 {
384 struct sdhc_softc *sc = device_private(dev);
385 struct sdhc_host *hp;
386 int i;
387
388 /* XXX chip locks up if we don't disable it before reboot. */
389 for (i = 0; i < sc->sc_nhosts; i++) {
390 hp = sc->sc_host[i];
391 (void)sdhc_host_reset(hp);
392 }
393 return true;
394 }
395
396 /*
397 * Reset the host controller. Called during initialization, when
398 * cards are removed, upon resume, and during error recovery.
399 */
400 static int
401 sdhc_host_reset1(sdmmc_chipset_handle_t sch)
402 {
403 struct sdhc_host *hp = (struct sdhc_host *)sch;
404 uint16_t sdhcimask;
405 int error;
406
407 /* Don't lock. */
408
409 /* Disable all interrupts. */
410 HWRITE2(hp, SDHC_NINTR_SIGNAL_EN, 0);
411
412 /*
413 * Reset the entire host controller and wait up to 100ms for
414 * the controller to clear the reset bit.
415 */
416 error = sdhc_soft_reset(hp, SDHC_RESET_ALL);
417 if (error)
418 goto out;
419
420 /* Set data timeout counter value to max for now. */
421 HWRITE1(hp, SDHC_TIMEOUT_CTL, SDHC_TIMEOUT_MAX);
422
423 /* Enable interrupts. */
424 sdhcimask = SDHC_CARD_REMOVAL | SDHC_CARD_INSERTION |
425 SDHC_BUFFER_READ_READY | SDHC_BUFFER_WRITE_READY |
426 SDHC_DMA_INTERRUPT | SDHC_BLOCK_GAP_EVENT |
427 SDHC_TRANSFER_COMPLETE | SDHC_COMMAND_COMPLETE;
428 HWRITE2(hp, SDHC_NINTR_STATUS_EN, sdhcimask);
429 HWRITE2(hp, SDHC_EINTR_STATUS_EN, SDHC_EINTR_STATUS_MASK);
430 HWRITE2(hp, SDHC_NINTR_SIGNAL_EN, sdhcimask);
431 HWRITE2(hp, SDHC_EINTR_SIGNAL_EN, SDHC_EINTR_SIGNAL_MASK);
432
433 out:
434 return error;
435 }
436
437 static int
438 sdhc_host_reset(sdmmc_chipset_handle_t sch)
439 {
440 struct sdhc_host *hp = (struct sdhc_host *)sch;
441 int error;
442
443 mutex_enter(&hp->host_mtx);
444 error = sdhc_host_reset1(sch);
445 mutex_exit(&hp->host_mtx);
446
447 return error;
448 }
449
450 static uint32_t
451 sdhc_host_ocr(sdmmc_chipset_handle_t sch)
452 {
453 struct sdhc_host *hp = (struct sdhc_host *)sch;
454
455 return hp->ocr;
456 }
457
458 static int
459 sdhc_host_maxblklen(sdmmc_chipset_handle_t sch)
460 {
461 struct sdhc_host *hp = (struct sdhc_host *)sch;
462
463 return hp->maxblklen;
464 }
465
466 /*
467 * Return non-zero if the card is currently inserted.
468 */
469 static int
470 sdhc_card_detect(sdmmc_chipset_handle_t sch)
471 {
472 struct sdhc_host *hp = (struct sdhc_host *)sch;
473 int r;
474
475 mutex_enter(&hp->host_mtx);
476 r = ISSET(HREAD4(hp, SDHC_PRESENT_STATE), SDHC_CARD_INSERTED);
477 mutex_exit(&hp->host_mtx);
478
479 if (r)
480 return 1;
481 return 0;
482 }
483
484 /*
485 * Return non-zero if the card is currently write-protected.
486 */
487 static int
488 sdhc_write_protect(sdmmc_chipset_handle_t sch)
489 {
490 struct sdhc_host *hp = (struct sdhc_host *)sch;
491 int r;
492
493 mutex_enter(&hp->host_mtx);
494 r = ISSET(HREAD4(hp, SDHC_PRESENT_STATE), SDHC_WRITE_PROTECT_SWITCH);
495 mutex_exit(&hp->host_mtx);
496
497 if (!r)
498 return 1;
499 return 0;
500 }
501
502 /*
503 * Set or change SD bus voltage and enable or disable SD bus power.
504 * Return zero on success.
505 */
506 static int
507 sdhc_bus_power(sdmmc_chipset_handle_t sch, uint32_t ocr)
508 {
509 struct sdhc_host *hp = (struct sdhc_host *)sch;
510 uint8_t vdd;
511 int error = 0;
512
513 mutex_enter(&hp->host_mtx);
514
515 /*
516 * Disable bus power before voltage change.
517 */
518 if (!(hp->sc->sc_flags & SDHC_FLAG_NO_PWR0))
519 HWRITE1(hp, SDHC_POWER_CTL, 0);
520
521 /* If power is disabled, reset the host and return now. */
522 if (ocr == 0) {
523 (void)sdhc_host_reset1(hp);
524 goto out;
525 }
526
527 /*
528 * Select the lowest voltage according to capabilities.
529 */
530 ocr &= hp->ocr;
531 if (ISSET(ocr, MMC_OCR_1_7V_1_8V|MMC_OCR_1_8V_1_9V))
532 vdd = SDHC_VOLTAGE_1_8V;
533 else if (ISSET(ocr, MMC_OCR_2_9V_3_0V|MMC_OCR_3_0V_3_1V))
534 vdd = SDHC_VOLTAGE_3_0V;
535 else if (ISSET(ocr, MMC_OCR_3_2V_3_3V|MMC_OCR_3_3V_3_4V))
536 vdd = SDHC_VOLTAGE_3_3V;
537 else {
538 /* Unsupported voltage level requested. */
539 error = EINVAL;
540 goto out;
541 }
542
543 /*
544 * Enable bus power. Wait at least 1 ms (or 74 clocks) plus
545 * voltage ramp until power rises.
546 */
547 HWRITE1(hp, SDHC_POWER_CTL,
548 (vdd << SDHC_VOLTAGE_SHIFT) | SDHC_BUS_POWER);
549 sdmmc_delay(10000);
550
551 /*
552 * The host system may not power the bus due to battery low,
553 * etc. In that case, the host controller should clear the
554 * bus power bit.
555 */
556 if (!ISSET(HREAD1(hp, SDHC_POWER_CTL), SDHC_BUS_POWER)) {
557 error = ENXIO;
558 goto out;
559 }
560
561 out:
562 mutex_exit(&hp->host_mtx);
563
564 return error;
565 }
566
567 /*
568 * Return the smallest possible base clock frequency divisor value
569 * for the CLOCK_CTL register to produce `freq' (KHz).
570 */
571 static int
572 sdhc_clock_divisor(struct sdhc_host *hp, u_int freq, int *divp)
573 {
574 int div;
575
576 if (hp->sc->sc_flags & SDHC_FLAG_HAVE_CGM) {
577 for (div = hp->clkbase / freq; div <= 0x3ff; div++) {
578 if ((hp->clkbase / div) <= freq) {
579 *divp = SDHC_SDCLK_CGM
580 | ((div & 0x300) << SDHC_SDCLK_XDIV_SHIFT)
581 | ((div & 0x0ff) << SDHC_SDCLK_DIV_SHIFT);
582 return false;
583 }
584 }
585 /* No divisor found. */
586 return true;
587 }
588 if (hp->sc->sc_flags & SDHC_FLAG_HAVE_DVS) {
589 int dvs = (hp->clkbase + freq - 1) / freq;
590 div = 1;
591 for (div = 1; div <= 256; div <<= 1, dvs >>= 1) {
592 if (dvs <= 16) {
593 div <<= SDHC_SDCLK_DIV_SHIFT;
594 div |= (dvs - 1) << SDHC_SDCLK_DVS_SHIFT;
595 *divp = div;
596 return false;
597 }
598 }
599 /* No divisor found. */
600 return true;
601 }
602 for (div = 1; div <= 256; div *= 2) {
603 if ((hp->clkbase / div) <= freq) {
604 *divp = (div / 2) << SDHC_SDCLK_DIV_SHIFT;
605 return false;
606 }
607 }
608
609 /* No divisor found. */
610 return true;
611 }
612
613 /*
614 * Set or change SDCLK frequency or disable the SD clock.
615 * Return zero on success.
616 */
617 static int
618 sdhc_bus_clock(sdmmc_chipset_handle_t sch, int freq)
619 {
620 struct sdhc_host *hp = (struct sdhc_host *)sch;
621 int div;
622 int timo;
623 int error = 0;
624 #ifdef DIAGNOSTIC
625 int ispresent;
626 #endif
627
628 #ifdef DIAGNOSTIC
629 mutex_enter(&hp->host_mtx);
630 ispresent = ISSET(HREAD4(hp, SDHC_PRESENT_STATE), SDHC_CMD_INHIBIT_MASK);
631 mutex_exit(&hp->host_mtx);
632
633 /* Must not stop the clock if commands are in progress. */
634 if (ispresent && sdhc_card_detect(hp))
635 printf("%s: sdhc_sdclk_frequency_select: command in progress\n",
636 device_xname(hp->sc->sc_dev));
637 #endif
638
639 mutex_enter(&hp->host_mtx);
640
641 /*
642 * Stop SD clock before changing the frequency.
643 */
644 HWRITE2(hp, SDHC_CLOCK_CTL, 0);
645 if (freq == SDMMC_SDCLK_OFF)
646 goto out;
647
648 /*
649 * Set the minimum base clock frequency divisor.
650 */
651 if (sdhc_clock_divisor(hp, freq, &div)) {
652 /* Invalid base clock frequency or `freq' value. */
653 error = EINVAL;
654 goto out;
655 }
656 HWRITE2(hp, SDHC_CLOCK_CTL, div);
657
658 /*
659 * Start internal clock. Wait 10ms for stabilization.
660 */
661 HSET2(hp, SDHC_CLOCK_CTL, SDHC_INTCLK_ENABLE);
662 for (timo = 1000; timo > 0; timo--) {
663 if (ISSET(HREAD2(hp, SDHC_CLOCK_CTL), SDHC_INTCLK_STABLE))
664 break;
665 sdmmc_delay(10);
666 }
667 if (timo == 0) {
668 error = ETIMEDOUT;
669 goto out;
670 }
671
672 /*
673 * Enable SD clock.
674 */
675 HSET2(hp, SDHC_CLOCK_CTL, SDHC_SDCLK_ENABLE);
676
677 out:
678 mutex_exit(&hp->host_mtx);
679
680 return error;
681 }
682
683 static int
684 sdhc_bus_width(sdmmc_chipset_handle_t sch, int width)
685 {
686 struct sdhc_host *hp = (struct sdhc_host *)sch;
687 int reg;
688
689 switch (width) {
690 case 1:
691 case 4:
692 break;
693
694 default:
695 DPRINTF(0,("%s: unsupported bus width (%d)\n",
696 HDEVNAME(hp), width));
697 return 1;
698 }
699
700 mutex_enter(&hp->host_mtx);
701 reg = HREAD1(hp, SDHC_POWER_CTL);
702 reg &= ~SDHC_4BIT_MODE;
703 if (width == 4)
704 reg |= SDHC_4BIT_MODE;
705 HWRITE1(hp, SDHC_POWER_CTL, reg);
706 mutex_exit(&hp->host_mtx);
707
708 return 0;
709 }
710
711 static void
712 sdhc_card_enable_intr(sdmmc_chipset_handle_t sch, int enable)
713 {
714 struct sdhc_host *hp = (struct sdhc_host *)sch;
715
716 mutex_enter(&hp->host_mtx);
717 if (enable) {
718 HSET2(hp, SDHC_NINTR_STATUS_EN, SDHC_CARD_INTERRUPT);
719 HSET2(hp, SDHC_NINTR_SIGNAL_EN, SDHC_CARD_INTERRUPT);
720 } else {
721 HCLR2(hp, SDHC_NINTR_SIGNAL_EN, SDHC_CARD_INTERRUPT);
722 HCLR2(hp, SDHC_NINTR_STATUS_EN, SDHC_CARD_INTERRUPT);
723 }
724 mutex_exit(&hp->host_mtx);
725 }
726
727 static void
728 sdhc_card_intr_ack(sdmmc_chipset_handle_t sch)
729 {
730 struct sdhc_host *hp = (struct sdhc_host *)sch;
731
732 mutex_enter(&hp->host_mtx);
733 HSET2(hp, SDHC_NINTR_STATUS_EN, SDHC_CARD_INTERRUPT);
734 mutex_exit(&hp->host_mtx);
735 }
736
737 static int
738 sdhc_wait_state(struct sdhc_host *hp, uint32_t mask, uint32_t value)
739 {
740 uint32_t state;
741 int timeout;
742
743 for (timeout = 10; timeout > 0; timeout--) {
744 if (((state = HREAD4(hp, SDHC_PRESENT_STATE)) & mask) == value)
745 return 0;
746 sdmmc_delay(10000);
747 }
748 DPRINTF(0,("%s: timeout waiting for %x (state=%x)\n", HDEVNAME(hp),
749 value, state));
750 return ETIMEDOUT;
751 }
752
753 static void
754 sdhc_exec_command(sdmmc_chipset_handle_t sch, struct sdmmc_command *cmd)
755 {
756 struct sdhc_host *hp = (struct sdhc_host *)sch;
757 int error;
758
759 /*
760 * Start the MMC command, or mark `cmd' as failed and return.
761 */
762 error = sdhc_start_command(hp, cmd);
763 if (error) {
764 cmd->c_error = error;
765 goto out;
766 }
767
768 /*
769 * Wait until the command phase is done, or until the command
770 * is marked done for any other reason.
771 */
772 if (!sdhc_wait_intr(hp, SDHC_COMMAND_COMPLETE, SDHC_COMMAND_TIMEOUT)) {
773 cmd->c_error = ETIMEDOUT;
774 goto out;
775 }
776
777 /*
778 * The host controller removes bits [0:7] from the response
779 * data (CRC) and we pass the data up unchanged to the bus
780 * driver (without padding).
781 */
782 mutex_enter(&hp->host_mtx);
783 if (cmd->c_error == 0 && ISSET(cmd->c_flags, SCF_RSP_PRESENT)) {
784 if (ISSET(cmd->c_flags, SCF_RSP_136)) {
785 uint8_t *p = (uint8_t *)cmd->c_resp;
786 int i;
787
788 for (i = 0; i < 15; i++)
789 *p++ = HREAD1(hp, SDHC_RESPONSE + i);
790 } else {
791 cmd->c_resp[0] = HREAD4(hp, SDHC_RESPONSE);
792 }
793 }
794 mutex_exit(&hp->host_mtx);
795 DPRINTF(1,("%s: resp = %08x\n", HDEVNAME(hp), cmd->c_resp[0]));
796
797 /*
798 * If the command has data to transfer in any direction,
799 * execute the transfer now.
800 */
801 if (cmd->c_error == 0 && cmd->c_data != NULL)
802 sdhc_transfer_data(hp, cmd);
803
804 out:
805 mutex_enter(&hp->host_mtx);
806 /* Turn off the LED. */
807 HCLR1(hp, SDHC_HOST_CTL, SDHC_LED_ON);
808 mutex_exit(&hp->host_mtx);
809 SET(cmd->c_flags, SCF_ITSDONE);
810
811 DPRINTF(1,("%s: cmd %d %s (flags=%08x error=%d)\n", HDEVNAME(hp),
812 cmd->c_opcode, (cmd->c_error == 0) ? "done" : "abort",
813 cmd->c_flags, cmd->c_error));
814 }
815
816 static int
817 sdhc_start_command(struct sdhc_host *hp, struct sdmmc_command *cmd)
818 {
819 uint16_t blksize = 0;
820 uint16_t blkcount = 0;
821 uint16_t mode;
822 uint16_t command;
823 int error;
824
825 DPRINTF(1,("%s: start cmd %d arg=%08x data=%p dlen=%d flags=%08x "
826 "proc=%p \"%s\"\n", HDEVNAME(hp), cmd->c_opcode, cmd->c_arg,
827 cmd->c_data, cmd->c_datalen, cmd->c_flags, curproc,
828 curproc ? curproc->p_comm : ""));
829
830 /*
831 * The maximum block length for commands should be the minimum
832 * of the host buffer size and the card buffer size. (1.7.2)
833 */
834
835 /* Fragment the data into proper blocks. */
836 if (cmd->c_datalen > 0) {
837 blksize = MIN(cmd->c_datalen, cmd->c_blklen);
838 blkcount = cmd->c_datalen / blksize;
839 if (cmd->c_datalen % blksize > 0) {
840 /* XXX: Split this command. (1.7.4) */
841 aprint_error_dev(hp->sc->sc_dev,
842 "data not a multiple of %u bytes\n", blksize);
843 return EINVAL;
844 }
845 }
846
847 /* Check limit imposed by 9-bit block count. (1.7.2) */
848 if (blkcount > SDHC_BLOCK_COUNT_MAX) {
849 aprint_error_dev(hp->sc->sc_dev, "too much data\n");
850 return EINVAL;
851 }
852
853 /* Prepare transfer mode register value. (2.2.5) */
854 mode = 0;
855 if (ISSET(cmd->c_flags, SCF_CMD_READ))
856 mode |= SDHC_READ_MODE;
857 if (blkcount > 0) {
858 mode |= SDHC_BLOCK_COUNT_ENABLE;
859 if (blkcount > 1) {
860 mode |= SDHC_MULTI_BLOCK_MODE;
861 /* XXX only for memory commands? */
862 mode |= SDHC_AUTO_CMD12_ENABLE;
863 }
864 }
865 #if notyet
866 if (cmd->c_dmap != NULL && cmd->c_datalen > 0)
867 mode |= SDHC_DMA_ENABLE;
868 #endif
869
870 /*
871 * Prepare command register value. (2.2.6)
872 */
873 command =
874 (cmd->c_opcode & SDHC_COMMAND_INDEX_MASK) << SDHC_COMMAND_INDEX_SHIFT;
875
876 if (ISSET(cmd->c_flags, SCF_RSP_CRC))
877 command |= SDHC_CRC_CHECK_ENABLE;
878 if (ISSET(cmd->c_flags, SCF_RSP_IDX))
879 command |= SDHC_INDEX_CHECK_ENABLE;
880 if (cmd->c_data != NULL)
881 command |= SDHC_DATA_PRESENT_SELECT;
882
883 if (!ISSET(cmd->c_flags, SCF_RSP_PRESENT))
884 command |= SDHC_NO_RESPONSE;
885 else if (ISSET(cmd->c_flags, SCF_RSP_136))
886 command |= SDHC_RESP_LEN_136;
887 else if (ISSET(cmd->c_flags, SCF_RSP_BSY))
888 command |= SDHC_RESP_LEN_48_CHK_BUSY;
889 else
890 command |= SDHC_RESP_LEN_48;
891
892 /* Wait until command and data inhibit bits are clear. (1.5) */
893 error = sdhc_wait_state(hp, SDHC_CMD_INHIBIT_MASK, 0);
894 if (error)
895 return error;
896
897 DPRINTF(1,("%s: writing cmd: blksize=%d blkcnt=%d mode=%04x cmd=%04x\n",
898 HDEVNAME(hp), blksize, blkcount, mode, command));
899
900 mutex_enter(&hp->host_mtx);
901
902 /* Alert the user not to remove the card. */
903 HSET1(hp, SDHC_HOST_CTL, SDHC_LED_ON);
904
905 /*
906 * Start a CPU data transfer. Writing to the high order byte
907 * of the SDHC_COMMAND register triggers the SD command. (1.5)
908 */
909 HWRITE2(hp, SDHC_TRANSFER_MODE, mode);
910 HWRITE2(hp, SDHC_BLOCK_SIZE, blksize);
911 if (blkcount > 1)
912 HWRITE2(hp, SDHC_BLOCK_COUNT, blkcount);
913 HWRITE4(hp, SDHC_ARGUMENT, cmd->c_arg);
914 HWRITE2(hp, SDHC_COMMAND, command);
915
916 mutex_exit(&hp->host_mtx);
917
918 return 0;
919 }
920
921 static void
922 sdhc_transfer_data(struct sdhc_host *hp, struct sdmmc_command *cmd)
923 {
924 int error;
925
926 DPRINTF(1,("%s: data transfer: resp=%08x datalen=%u\n", HDEVNAME(hp),
927 MMC_R1(cmd->c_resp), cmd->c_datalen));
928
929 #ifdef SDHC_DEBUG
930 /* XXX I forgot why I wanted to know when this happens :-( */
931 if ((cmd->c_opcode == 52 || cmd->c_opcode == 53) &&
932 ISSET(MMC_R1(cmd->c_resp), 0xcb00)) {
933 aprint_error_dev(hp->sc->sc_dev,
934 "CMD52/53 error response flags %#x\n",
935 MMC_R1(cmd->c_resp) & 0xff00);
936 }
937 #endif
938
939 error = sdhc_transfer_data_pio(hp, cmd);
940 if (error)
941 cmd->c_error = error;
942 SET(cmd->c_flags, SCF_ITSDONE);
943
944 DPRINTF(1,("%s: data transfer done (error=%d)\n",
945 HDEVNAME(hp), cmd->c_error));
946 }
947
948 static int
949 sdhc_transfer_data_pio(struct sdhc_host *hp, struct sdmmc_command *cmd)
950 {
951 uint8_t *data = cmd->c_data;
952 int len, datalen;
953 int mask;
954 int error = 0;
955
956 mask = ISSET(cmd->c_flags, SCF_CMD_READ) ?
957 SDHC_BUFFER_READ_ENABLE : SDHC_BUFFER_WRITE_ENABLE;
958 datalen = cmd->c_datalen;
959
960 while (datalen > 0) {
961 if (!sdhc_wait_intr(hp,
962 SDHC_BUFFER_READ_READY|SDHC_BUFFER_WRITE_READY,
963 SDHC_BUFFER_TIMEOUT)) {
964 error = ETIMEDOUT;
965 break;
966 }
967
968 error = sdhc_wait_state(hp, mask, mask);
969 if (error)
970 break;
971
972 len = MIN(datalen, cmd->c_blklen);
973 if (ISSET(cmd->c_flags, SCF_CMD_READ))
974 sdhc_read_data_pio(hp, data, len);
975 else
976 sdhc_write_data_pio(hp, data, len);
977
978 data += len;
979 datalen -= len;
980 }
981
982 if (error == 0 && !sdhc_wait_intr(hp, SDHC_TRANSFER_COMPLETE,
983 SDHC_TRANSFER_TIMEOUT))
984 error = ETIMEDOUT;
985
986 return error;
987 }
988
989 static void
990 sdhc_read_data_pio(struct sdhc_host *hp, uint8_t *data, int datalen)
991 {
992
993 if (((__uintptr_t)data & 3) == 0) {
994 while (datalen > 3) {
995 *(uint32_t *)data = HREAD4(hp, SDHC_DATA);
996 data += 4;
997 datalen -= 4;
998 }
999 if (datalen > 1) {
1000 *(uint16_t *)data = HREAD2(hp, SDHC_DATA);
1001 data += 2;
1002 datalen -= 2;
1003 }
1004 if (datalen > 0) {
1005 *data = HREAD1(hp, SDHC_DATA);
1006 data += 1;
1007 datalen -= 1;
1008 }
1009 } else if (((__uintptr_t)data & 1) == 0) {
1010 while (datalen > 1) {
1011 *(uint16_t *)data = HREAD2(hp, SDHC_DATA);
1012 data += 2;
1013 datalen -= 2;
1014 }
1015 if (datalen > 0) {
1016 *data = HREAD1(hp, SDHC_DATA);
1017 data += 1;
1018 datalen -= 1;
1019 }
1020 } else {
1021 while (datalen > 0) {
1022 *data = HREAD1(hp, SDHC_DATA);
1023 data += 1;
1024 datalen -= 1;
1025 }
1026 }
1027 }
1028
1029 static void
1030 sdhc_write_data_pio(struct sdhc_host *hp, uint8_t *data, int datalen)
1031 {
1032
1033 if (((__uintptr_t)data & 3) == 0) {
1034 while (datalen > 3) {
1035 HWRITE4(hp, SDHC_DATA, *(uint32_t *)data);
1036 data += 4;
1037 datalen -= 4;
1038 }
1039 if (datalen > 1) {
1040 HWRITE2(hp, SDHC_DATA, *(uint16_t *)data);
1041 data += 2;
1042 datalen -= 2;
1043 }
1044 if (datalen > 0) {
1045 HWRITE1(hp, SDHC_DATA, *data);
1046 data += 1;
1047 datalen -= 1;
1048 }
1049 } else if (((__uintptr_t)data & 1) == 0) {
1050 while (datalen > 1) {
1051 HWRITE2(hp, SDHC_DATA, *(uint16_t *)data);
1052 data += 2;
1053 datalen -= 2;
1054 }
1055 if (datalen > 0) {
1056 HWRITE1(hp, SDHC_DATA, *data);
1057 data += 1;
1058 datalen -= 1;
1059 }
1060 } else {
1061 while (datalen > 0) {
1062 HWRITE1(hp, SDHC_DATA, *data);
1063 data += 1;
1064 datalen -= 1;
1065 }
1066 }
1067 }
1068
1069 /* Prepare for another command. */
1070 static int
1071 sdhc_soft_reset(struct sdhc_host *hp, int mask)
1072 {
1073 int timo;
1074
1075 DPRINTF(1,("%s: software reset reg=%08x\n", HDEVNAME(hp), mask));
1076
1077 HWRITE1(hp, SDHC_SOFTWARE_RESET, mask);
1078 for (timo = 10; timo > 0; timo--) {
1079 if (!ISSET(HREAD1(hp, SDHC_SOFTWARE_RESET), mask))
1080 break;
1081 sdmmc_delay(10000);
1082 HWRITE1(hp, SDHC_SOFTWARE_RESET, 0);
1083 }
1084 if (timo == 0) {
1085 DPRINTF(1,("%s: timeout reg=%08x\n", HDEVNAME(hp),
1086 HREAD1(hp, SDHC_SOFTWARE_RESET)));
1087 HWRITE1(hp, SDHC_SOFTWARE_RESET, 0);
1088 return ETIMEDOUT;
1089 }
1090
1091 return 0;
1092 }
1093
1094 static int
1095 sdhc_wait_intr(struct sdhc_host *hp, int mask, int timo)
1096 {
1097 int status;
1098
1099 mask |= SDHC_ERROR_INTERRUPT;
1100
1101 mutex_enter(&hp->intr_mtx);
1102 status = hp->intr_status & mask;
1103 while (status == 0) {
1104 if (cv_timedwait(&hp->intr_cv, &hp->intr_mtx, timo)
1105 == EWOULDBLOCK) {
1106 status |= SDHC_ERROR_INTERRUPT;
1107 break;
1108 }
1109 status = hp->intr_status & mask;
1110 }
1111 hp->intr_status &= ~status;
1112
1113 DPRINTF(2,("%s: intr status %#x error %#x\n", HDEVNAME(hp), status,
1114 hp->intr_error_status));
1115
1116 /* Command timeout has higher priority than command complete. */
1117 if (ISSET(status, SDHC_ERROR_INTERRUPT)) {
1118 hp->intr_error_status = 0;
1119 (void)sdhc_soft_reset(hp, SDHC_RESET_DAT|SDHC_RESET_CMD);
1120 status = 0;
1121 }
1122 mutex_exit(&hp->intr_mtx);
1123
1124 return status;
1125 }
1126
1127 /*
1128 * Established by attachment driver at interrupt priority IPL_SDMMC.
1129 */
1130 int
1131 sdhc_intr(void *arg)
1132 {
1133 struct sdhc_softc *sc = (struct sdhc_softc *)arg;
1134 struct sdhc_host *hp;
1135 int host;
1136 int done = 0;
1137 uint16_t status;
1138 uint16_t error;
1139
1140 /* We got an interrupt, but we don't know from which slot. */
1141 for (host = 0; host < sc->sc_nhosts; host++) {
1142 hp = sc->sc_host[host];
1143 if (hp == NULL)
1144 continue;
1145
1146 /* Find out which interrupts are pending. */
1147 status = HREAD2(hp, SDHC_NINTR_STATUS);
1148 if (!ISSET(status, SDHC_NINTR_STATUS_MASK))
1149 continue; /* no interrupt for us */
1150
1151 /* Acknowledge the interrupts we are about to handle. */
1152 HWRITE2(hp, SDHC_NINTR_STATUS, status);
1153 DPRINTF(2,("%s: interrupt status=%x\n", HDEVNAME(hp),
1154 status));
1155
1156 if (!ISSET(status, SDHC_NINTR_STATUS_MASK))
1157 continue;
1158
1159 /* Claim this interrupt. */
1160 done = 1;
1161
1162 /*
1163 * Service error interrupts.
1164 */
1165 if (ISSET(status, SDHC_ERROR_INTERRUPT)) {
1166 /* Acknowledge error interrupts. */
1167 error = HREAD2(hp, SDHC_EINTR_STATUS);
1168 HWRITE2(hp, SDHC_EINTR_STATUS, error);
1169 DPRINTF(2,("%s: error interrupt, status=%x\n",
1170 HDEVNAME(hp), error));
1171
1172 if (ISSET(error, SDHC_CMD_TIMEOUT_ERROR|
1173 SDHC_DATA_TIMEOUT_ERROR)) {
1174 hp->intr_error_status |= error;
1175 hp->intr_status |= status;
1176 cv_broadcast(&hp->intr_cv);
1177 }
1178 }
1179
1180 /*
1181 * Wake up the sdmmc event thread to scan for cards.
1182 */
1183 if (ISSET(status, SDHC_CARD_REMOVAL|SDHC_CARD_INSERTION))
1184 sdmmc_needs_discover(hp->sdmmc);
1185
1186 /*
1187 * Wake up the blocking process to service command
1188 * related interrupt(s).
1189 */
1190 if (ISSET(status, SDHC_BUFFER_READ_READY|
1191 SDHC_BUFFER_WRITE_READY|SDHC_COMMAND_COMPLETE|
1192 SDHC_TRANSFER_COMPLETE|SDHC_DMA_INTERRUPT)) {
1193 hp->intr_status |= status;
1194 cv_broadcast(&hp->intr_cv);
1195 }
1196
1197 /*
1198 * Service SD card interrupts.
1199 */
1200 if (ISSET(status, SDHC_CARD_INTERRUPT)) {
1201 DPRINTF(0,("%s: card interrupt\n", HDEVNAME(hp)));
1202 HCLR2(hp, SDHC_NINTR_STATUS_EN, SDHC_CARD_INTERRUPT);
1203 sdmmc_card_intr(hp->sdmmc);
1204 }
1205 }
1206
1207 return done;
1208 }
1209
1210 #ifdef SDHC_DEBUG
1211 void
1212 sdhc_dump_regs(struct sdhc_host *hp)
1213 {
1214
1215 printf("0x%02x PRESENT_STATE: %x\n", SDHC_PRESENT_STATE,
1216 HREAD4(hp, SDHC_PRESENT_STATE));
1217 printf("0x%02x POWER_CTL: %x\n", SDHC_POWER_CTL,
1218 HREAD1(hp, SDHC_POWER_CTL));
1219 printf("0x%02x NINTR_STATUS: %x\n", SDHC_NINTR_STATUS,
1220 HREAD2(hp, SDHC_NINTR_STATUS));
1221 printf("0x%02x EINTR_STATUS: %x\n", SDHC_EINTR_STATUS,
1222 HREAD2(hp, SDHC_EINTR_STATUS));
1223 printf("0x%02x NINTR_STATUS_EN: %x\n", SDHC_NINTR_STATUS_EN,
1224 HREAD2(hp, SDHC_NINTR_STATUS_EN));
1225 printf("0x%02x EINTR_STATUS_EN: %x\n", SDHC_EINTR_STATUS_EN,
1226 HREAD2(hp, SDHC_EINTR_STATUS_EN));
1227 printf("0x%02x NINTR_SIGNAL_EN: %x\n", SDHC_NINTR_SIGNAL_EN,
1228 HREAD2(hp, SDHC_NINTR_SIGNAL_EN));
1229 printf("0x%02x EINTR_SIGNAL_EN: %x\n", SDHC_EINTR_SIGNAL_EN,
1230 HREAD2(hp, SDHC_EINTR_SIGNAL_EN));
1231 printf("0x%02x CAPABILITIES: %x\n", SDHC_CAPABILITIES,
1232 HREAD4(hp, SDHC_CAPABILITIES));
1233 printf("0x%02x MAX_CAPABILITIES: %x\n", SDHC_MAX_CAPABILITIES,
1234 HREAD4(hp, SDHC_MAX_CAPABILITIES));
1235 }
1236 #endif
1237