sdhci_xenon.c (8a8166e5bcfb50e2b7280581b600d098fa6c9fc7) | sdhci_xenon.c (d78e464d23304084be17cb8db8981558f2829d6c) |
---|---|
1/*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 2018 Rubicon Communications, LLC (Netgate) 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions --- 34 unchanged lines hidden (view full) --- 43#include <sys/rman.h> 44#include <sys/sysctl.h> 45#include <sys/taskqueue.h> 46 47#include <machine/bus.h> 48#include <machine/resource.h> 49 50#include <dev/extres/regulator/regulator.h> | 1/*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 2018 Rubicon Communications, LLC (Netgate) 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions --- 34 unchanged lines hidden (view full) --- 43#include <sys/rman.h> 44#include <sys/sysctl.h> 45#include <sys/taskqueue.h> 46 47#include <machine/bus.h> 48#include <machine/resource.h> 49 50#include <dev/extres/regulator/regulator.h> |
51#include <dev/fdt/fdt_common.h> 52#include <dev/ofw/ofw_bus.h> 53#include <dev/ofw/ofw_bus_subr.h> | |
54 55#include <dev/mmc/bridge.h> | 51 52#include <dev/mmc/bridge.h> |
56#include <dev/mmc/mmc_fdt_helpers.h> | |
57#include <dev/mmc/mmcbrvar.h> 58#include <dev/mmc/mmcreg.h> 59 60#include <dev/sdhci/sdhci.h> | 53#include <dev/mmc/mmcbrvar.h> 54#include <dev/mmc/mmcreg.h> 55 56#include <dev/sdhci/sdhci.h> |
61#include <dev/sdhci/sdhci_fdt_gpio.h> | |
62#include <dev/sdhci/sdhci_xenon.h> 63 64#include "mmcbr_if.h" 65#include "sdhci_if.h" 66 67#include "opt_mmccam.h" 68#include "opt_soc.h" 69 70#define MAX_SLOTS 6 71 | 57#include <dev/sdhci/sdhci_xenon.h> 58 59#include "mmcbr_if.h" 60#include "sdhci_if.h" 61 62#include "opt_mmccam.h" 63#include "opt_soc.h" 64 65#define MAX_SLOTS 6 66 |
72static struct ofw_compat_data compat_data[] = { 73 { "marvell,armada-3700-sdhci", 1 }, 74#ifdef SOC_MARVELL_8K 75 { "marvell,armada-cp110-sdhci", 1 }, 76 { "marvell,armada-ap806-sdhci", 1 }, 77 { "marvell,armada-ap807-sdhci", 1 }, 78#endif 79 { NULL, 0 } 80}; 81 82struct sdhci_xenon_softc { 83 device_t dev; /* Controller device */ 84 int slot_id; /* Controller ID */ 85 phandle_t node; /* FDT node */ 86 struct resource *irq_res; /* IRQ resource */ 87 void *intrhand; /* Interrupt handle */ 88 struct sdhci_fdt_gpio *gpio; /* GPIO pins for CD detection. */ 89 90 struct sdhci_slot *slot; /* SDHCI internal data */ 91 struct resource *mem_res; /* Memory resource */ 92 93 uint8_t znr; /* PHY ZNR */ 94 uint8_t zpr; /* PHY ZPR */ 95 bool slow_mode; /* PHY slow mode */ 96 97 struct mmc_helper mmc_helper; /* MMC helper for parsing FDT */ 98}; 99 | |
100static uint8_t 101sdhci_xenon_read_1(device_t dev, struct sdhci_slot *slot __unused, 102 bus_size_t off) 103{ 104 struct sdhci_xenon_softc *sc = device_get_softc(dev); 105 106 return (bus_read_1(sc->mem_res, off)); 107} --- 69 unchanged lines hidden (view full) --- 177 sdhci_generic_intr(sc->slot); 178} 179 180static int 181sdhci_xenon_get_ro(device_t bus, device_t dev) 182{ 183 struct sdhci_xenon_softc *sc = device_get_softc(bus); 184 | 67static uint8_t 68sdhci_xenon_read_1(device_t dev, struct sdhci_slot *slot __unused, 69 bus_size_t off) 70{ 71 struct sdhci_xenon_softc *sc = device_get_softc(dev); 72 73 return (bus_read_1(sc->mem_res, off)); 74} --- 69 unchanged lines hidden (view full) --- 144 sdhci_generic_intr(sc->slot); 145} 146 147static int 148sdhci_xenon_get_ro(device_t bus, device_t dev) 149{ 150 struct sdhci_xenon_softc *sc = device_get_softc(bus); 151 |
185 return (sdhci_generic_get_ro(bus, dev) ^ 186 (sc->mmc_helper.props & MMC_PROP_WP_INVERTED)); | 152 return (sdhci_generic_get_ro(bus, dev) ^ sc->wp_inverted); |
187} 188 | 153} 154 |
189static bool 190sdhci_xenon_get_card_present(device_t dev, struct sdhci_slot *slot) 191{ 192 struct sdhci_xenon_softc *sc = device_get_softc(dev); 193 194 return (sdhci_fdt_gpio_get_present(sc->gpio)); 195} 196 | |
197static void 198sdhci_xenon_set_uhs_timing(device_t brdev, struct sdhci_slot *slot) 199{ 200 const struct mmc_ios *ios; 201 uint16_t hostctrl2; 202 203 if (slot->version < SDHCI_SPEC_300) 204 return; --- 177 unchanged lines hidden (view full) --- 382 383 switch (ios->power_mode) { 384 case power_on: 385 break; 386 case power_off: 387 if (bootverbose) 388 device_printf(sc->dev, "Powering down sd/mmc\n"); 389 | 155static void 156sdhci_xenon_set_uhs_timing(device_t brdev, struct sdhci_slot *slot) 157{ 158 const struct mmc_ios *ios; 159 uint16_t hostctrl2; 160 161 if (slot->version < SDHCI_SPEC_300) 162 return; --- 177 unchanged lines hidden (view full) --- 340 341 switch (ios->power_mode) { 342 case power_on: 343 break; 344 case power_off: 345 if (bootverbose) 346 device_printf(sc->dev, "Powering down sd/mmc\n"); 347 |
390 if (sc->mmc_helper.vmmc_supply) 391 regulator_disable(sc->mmc_helper.vmmc_supply); 392 if (sc->mmc_helper.vqmmc_supply) 393 regulator_disable(sc->mmc_helper.vqmmc_supply); | 348 if (sc->vmmc_supply) 349 regulator_disable(sc->vmmc_supply); 350 if (sc->vqmmc_supply) 351 regulator_disable(sc->vqmmc_supply); |
394 break; 395 case power_up: 396 if (bootverbose) 397 device_printf(sc->dev, "Powering up sd/mmc\n"); 398 | 352 break; 353 case power_up: 354 if (bootverbose) 355 device_printf(sc->dev, "Powering up sd/mmc\n"); 356 |
399 if (sc->mmc_helper.vmmc_supply) 400 regulator_enable(sc->mmc_helper.vmmc_supply); 401 if (sc->mmc_helper.vqmmc_supply) 402 regulator_enable(sc->mmc_helper.vqmmc_supply); | 357 if (sc->vmmc_supply) 358 regulator_enable(sc->vmmc_supply); 359 if (sc->vqmmc_supply) 360 regulator_enable(sc->vqmmc_supply); |
403 break; 404 }; 405 406 /* Update the PHY settings. */ 407 if (ios->clock != 0) 408 sdhci_xenon_phy_set(brdev, ios); 409 410 if (ios->clock > SD_MMC_CARD_ID_FREQUENCY) { --- 16 unchanged lines hidden (view full) --- 427 428 slot = device_get_ivars(reqdev); 429 430 if (slot->version < SDHCI_SPEC_300) 431 return (0); 432 433 sc = device_get_softc(brdev); 434 | 361 break; 362 }; 363 364 /* Update the PHY settings. */ 365 if (ios->clock != 0) 366 sdhci_xenon_phy_set(brdev, ios); 367 368 if (ios->clock > SD_MMC_CARD_ID_FREQUENCY) { --- 16 unchanged lines hidden (view full) --- 385 386 slot = device_get_ivars(reqdev); 387 388 if (slot->version < SDHCI_SPEC_300) 389 return (0); 390 391 sc = device_get_softc(brdev); 392 |
435 if (sc->mmc_helper.vqmmc_supply == NULL) 436 return EOPNOTSUPP; | 393 if (sc->vqmmc_supply == NULL && !sc->skip_regulators) 394 return (EOPNOTSUPP); |
437 438 err = 0; 439 440 hostctrl2 = bus_read_2(sc->mem_res, SDHCI_HOST_CONTROL2); 441 switch (slot->host.ios.vccq) { 442 case vccq_330: 443 if (!(hostctrl2 & SDHCI_CTRL2_S18_ENABLE)) 444 return (0); 445 hostctrl2 &= ~SDHCI_CTRL2_S18_ENABLE; 446 bus_write_2(sc->mem_res, SDHCI_HOST_CONTROL2, hostctrl2); 447 | 395 396 err = 0; 397 398 hostctrl2 = bus_read_2(sc->mem_res, SDHCI_HOST_CONTROL2); 399 switch (slot->host.ios.vccq) { 400 case vccq_330: 401 if (!(hostctrl2 & SDHCI_CTRL2_S18_ENABLE)) 402 return (0); 403 hostctrl2 &= ~SDHCI_CTRL2_S18_ENABLE; 404 bus_write_2(sc->mem_res, SDHCI_HOST_CONTROL2, hostctrl2); 405 |
448 uvolt = 3300000; 449 err = regulator_set_voltage(sc->mmc_helper.vqmmc_supply, 450 uvolt, uvolt); 451 if (err != 0) { 452 device_printf(sc->dev, 453 "Cannot set vqmmc to %d<->%d\n", 454 uvolt, 455 uvolt); 456 return (err); | 406 if (!sc->skip_regulators) { 407 uvolt = 3300000; 408 err = regulator_set_voltage(sc->vqmmc_supply, 409 uvolt, uvolt); 410 if (err != 0) { 411 device_printf(sc->dev, 412 "Cannot set vqmmc to %d<->%d\n", 413 uvolt, 414 uvolt); 415 return (err); 416 } |
457 } 458 459 /* 460 * According to the 'SD Host Controller Simplified 461 * Specification 4.20 the host driver should take more 462 * than 5ms for stable time of host voltage regulator 463 * from changing 1.8V Signaling Enable. 464 */ 465 DELAY(5000); 466 hostctrl2 = bus_read_2(sc->mem_res, SDHCI_HOST_CONTROL2); 467 if (!(hostctrl2 & SDHCI_CTRL2_S18_ENABLE)) 468 return (0); | 417 } 418 419 /* 420 * According to the 'SD Host Controller Simplified 421 * Specification 4.20 the host driver should take more 422 * than 5ms for stable time of host voltage regulator 423 * from changing 1.8V Signaling Enable. 424 */ 425 DELAY(5000); 426 hostctrl2 = bus_read_2(sc->mem_res, SDHCI_HOST_CONTROL2); 427 if (!(hostctrl2 & SDHCI_CTRL2_S18_ENABLE)) 428 return (0); |
469 return EAGAIN; | 429 return (EAGAIN); |
470 case vccq_180: 471 if (!(slot->host.caps & MMC_CAP_SIGNALING_180)) { | 430 case vccq_180: 431 if (!(slot->host.caps & MMC_CAP_SIGNALING_180)) { |
472 return EINVAL; | 432 return (EINVAL); |
473 } 474 if (hostctrl2 & SDHCI_CTRL2_S18_ENABLE) 475 return (0); 476 hostctrl2 |= SDHCI_CTRL2_S18_ENABLE; 477 bus_write_2(sc->mem_res, SDHCI_HOST_CONTROL2, hostctrl2); 478 | 433 } 434 if (hostctrl2 & SDHCI_CTRL2_S18_ENABLE) 435 return (0); 436 hostctrl2 |= SDHCI_CTRL2_S18_ENABLE; 437 bus_write_2(sc->mem_res, SDHCI_HOST_CONTROL2, hostctrl2); 438 |
479 uvolt = 1800000; 480 err = regulator_set_voltage(sc->mmc_helper.vqmmc_supply, 481 uvolt, uvolt); 482 if (err != 0) { 483 device_printf(sc->dev, 484 "Cannot set vqmmc to %d<->%d\n", 485 uvolt, 486 uvolt); 487 return (err); | 439 if (!sc->skip_regulators) { 440 uvolt = 1800000; 441 err = regulator_set_voltage(sc->vqmmc_supply, 442 uvolt, uvolt); 443 if (err != 0) { 444 device_printf(sc->dev, 445 "Cannot set vqmmc to %d<->%d\n", 446 uvolt, 447 uvolt); 448 return (err); 449 } |
488 } 489 490 /* 491 * According to the 'SD Host Controller Simplified 492 * Specification 4.20 the host driver should take more 493 * than 5ms for stable time of host voltage regulator 494 * from changing 1.8V Signaling Enable. 495 */ 496 DELAY(5000); 497 hostctrl2 = bus_read_2(sc->mem_res, SDHCI_HOST_CONTROL2); 498 if (hostctrl2 & SDHCI_CTRL2_S18_ENABLE) 499 return (0); | 450 } 451 452 /* 453 * According to the 'SD Host Controller Simplified 454 * Specification 4.20 the host driver should take more 455 * than 5ms for stable time of host voltage regulator 456 * from changing 1.8V Signaling Enable. 457 */ 458 DELAY(5000); 459 hostctrl2 = bus_read_2(sc->mem_res, SDHCI_HOST_CONTROL2); 460 if (hostctrl2 & SDHCI_CTRL2_S18_ENABLE) 461 return (0); |
500 return EAGAIN; | 462 return (EAGAIN); |
501 default: 502 device_printf(brdev, 503 "Attempt to set unsupported signaling voltage\n"); | 463 default: 464 device_printf(brdev, 465 "Attempt to set unsupported signaling voltage\n"); |
504 return EINVAL; | 466 return (EINVAL); |
505 } 506} 507 508static void | 467 } 468} 469 470static void |
509sdhci_xenon_fdt_parse(device_t dev, struct sdhci_slot *slot) | 471sdhci_xenon_parse_prop(device_t dev) |
510{ | 472{ |
511 struct sdhci_xenon_softc *sc = device_get_softc(dev); 512 pcell_t cid; | 473 struct sdhci_xenon_softc *sc; 474 uint64_t val; |
513 | 475 |
514 mmc_fdt_parse(dev, 0, &sc->mmc_helper, &slot->host); | 476 sc = device_get_softc(dev); 477 val = 0; |
515 | 478 |
516 /* Allow dts to patch quirks, slots, and max-frequency. */ 517 if ((OF_getencprop(sc->node, "quirks", &cid, sizeof(cid))) > 0) 518 slot->quirks = cid; 519 if (OF_hasprop(sc->node, "marvell,xenon-phy-slow-mode")) 520 sc->slow_mode = true; | 479 if (device_get_property(dev, "quirks", &val, sizeof(val)) > 0) 480 sc->slot->quirks = val; |
521 sc->znr = XENON_ZNR_DEF_VALUE; | 481 sc->znr = XENON_ZNR_DEF_VALUE; |
522 if ((OF_getencprop(sc->node, "marvell,xenon-phy-znr", &cid, 523 sizeof(cid))) > 0) 524 sc->znr = cid & XENON_ZNR_MASK; | 482 if (device_get_property(dev, "marvell,xenon-phy-znr", 483 &val, sizeof(val)) > 0) 484 sc->znr = val & XENON_ZNR_MASK; |
525 sc->zpr = XENON_ZPR_DEF_VALUE; | 485 sc->zpr = XENON_ZPR_DEF_VALUE; |
526 if ((OF_getencprop(sc->node, "marvell,xenon-phy-zpr", &cid, 527 sizeof(cid))) > 0) 528 sc->zpr = cid & XENON_ZPR_MASK; | 486 if (device_get_property(dev, "marvell,xenon-phy-zpr", 487 &val, sizeof(val)) > 0) 488 sc->zpr = val & XENON_ZPR_MASK; 489 if (device_has_property(dev, "marvell,xenon-phy-slow-mode")) 490 sc->slow_mode = true; |
529} 530 | 491} 492 |
531static int 532sdhci_xenon_probe(device_t dev) 533{ 534 if (!ofw_bus_status_okay(dev)) 535 return (ENXIO); 536 537 if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) 538 return (ENXIO); 539 540 device_set_desc(dev, "Armada Xenon SDHCI controller"); 541 542 return (0); 543} 544 545static int | 493int |
546sdhci_xenon_attach(device_t dev) 547{ 548 struct sdhci_xenon_softc *sc = device_get_softc(dev); | 494sdhci_xenon_attach(device_t dev) 495{ 496 struct sdhci_xenon_softc *sc = device_get_softc(dev); |
549 struct sdhci_slot *slot; | |
550 int err, rid; 551 uint32_t reg; 552 553 sc->dev = dev; 554 sc->slot_id = 0; | 497 int err, rid; 498 uint32_t reg; 499 500 sc->dev = dev; 501 sc->slot_id = 0; |
555 sc->node = ofw_bus_get_node(dev); | |
556 557 /* Allocate IRQ. */ 558 rid = 0; 559 sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, 560 RF_ACTIVE); 561 if (sc->irq_res == NULL) { 562 device_printf(dev, "Can't allocate IRQ\n"); 563 return (ENOMEM); --- 5 unchanged lines hidden (view full) --- 569 &rid, RF_ACTIVE); 570 if (sc->mem_res == NULL) { 571 bus_release_resource(dev, SYS_RES_IRQ, 572 rman_get_rid(sc->irq_res), sc->irq_res); 573 device_printf(dev, "Can't allocate memory for slot\n"); 574 return (ENOMEM); 575 } 576 | 502 503 /* Allocate IRQ. */ 504 rid = 0; 505 sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, 506 RF_ACTIVE); 507 if (sc->irq_res == NULL) { 508 device_printf(dev, "Can't allocate IRQ\n"); 509 return (ENOMEM); --- 5 unchanged lines hidden (view full) --- 515 &rid, RF_ACTIVE); 516 if (sc->mem_res == NULL) { 517 bus_release_resource(dev, SYS_RES_IRQ, 518 rman_get_rid(sc->irq_res), sc->irq_res); 519 device_printf(dev, "Can't allocate memory for slot\n"); 520 return (ENOMEM); 521 } 522 |
577 slot = malloc(sizeof(*slot), M_DEVBUF, M_ZERO | M_WAITOK); | 523 sdhci_xenon_parse_prop(dev); |
578 | 524 |
579 /* 580 * Set up any gpio pin handling described in the FDT data. This cannot 581 * fail; see comments in sdhci_fdt_gpio.h for details. 582 */ 583 sc->gpio = sdhci_fdt_gpio_setup(dev, slot); | 525 sc->slot->max_clk = XENON_MMC_MAX_CLK; 526 if (sc->slot->host.f_max > 0) 527 sc->slot->max_clk = sc->slot->host.f_max; |
584 | 528 |
585 sdhci_xenon_fdt_parse(dev, slot); 586 587 slot->max_clk = XENON_MMC_MAX_CLK; 588 if (slot->host.f_max > 0) 589 slot->max_clk = slot->host.f_max; 590 /* Check if the device is flagged as non-removable. */ 591 if (sc->mmc_helper.props & MMC_PROP_NON_REMOVABLE) { 592 slot->opt |= SDHCI_NON_REMOVABLE; 593 if (bootverbose) 594 device_printf(dev, "Non-removable media\n"); 595 } 596 597 sc->slot = slot; 598 | |
599 if (sdhci_init_slot(dev, sc->slot, 0)) 600 goto fail; 601 602 /* 1.2V signaling is not supported. */ 603 sc->slot->host.caps &= ~MMC_CAP_SIGNALING_120; 604 605 /* Disable UHS in case of the PHY slow mode. */ 606 if (sc->slow_mode) --- 46 unchanged lines hidden (view full) --- 653 bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(sc->mem_res), 654 sc->mem_res); 655 free(sc->slot, M_DEVBUF); 656 sc->slot = NULL; 657 658 return (ENXIO); 659} 660 | 529 if (sdhci_init_slot(dev, sc->slot, 0)) 530 goto fail; 531 532 /* 1.2V signaling is not supported. */ 533 sc->slot->host.caps &= ~MMC_CAP_SIGNALING_120; 534 535 /* Disable UHS in case of the PHY slow mode. */ 536 if (sc->slow_mode) --- 46 unchanged lines hidden (view full) --- 583 bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(sc->mem_res), 584 sc->mem_res); 585 free(sc->slot, M_DEVBUF); 586 sc->slot = NULL; 587 588 return (ENXIO); 589} 590 |
661static int | 591int |
662sdhci_xenon_detach(device_t dev) 663{ 664 struct sdhci_xenon_softc *sc = device_get_softc(dev); 665 | 592sdhci_xenon_detach(device_t dev) 593{ 594 struct sdhci_xenon_softc *sc = device_get_softc(dev); 595 |
666 if (sc->gpio != NULL) 667 sdhci_fdt_gpio_teardown(sc->gpio); 668 | |
669 bus_generic_detach(dev); 670 bus_teardown_intr(dev, sc->irq_res, sc->intrhand); 671 bus_release_resource(dev, SYS_RES_IRQ, rman_get_rid(sc->irq_res), 672 sc->irq_res); 673 sdhci_cleanup_slot(sc->slot); 674 bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(sc->mem_res), 675 sc->mem_res); 676 free(sc->slot, M_DEVBUF); 677 sc->slot = NULL; 678 679 return (0); 680} 681 682static device_method_t sdhci_xenon_methods[] = { | 596 bus_generic_detach(dev); 597 bus_teardown_intr(dev, sc->irq_res, sc->intrhand); 598 bus_release_resource(dev, SYS_RES_IRQ, rman_get_rid(sc->irq_res), 599 sc->irq_res); 600 sdhci_cleanup_slot(sc->slot); 601 bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(sc->mem_res), 602 sc->mem_res); 603 free(sc->slot, M_DEVBUF); 604 sc->slot = NULL; 605 606 return (0); 607} 608 609static device_method_t sdhci_xenon_methods[] = { |
683 /* device_if */ 684 DEVMETHOD(device_probe, sdhci_xenon_probe), 685 DEVMETHOD(device_attach, sdhci_xenon_attach), 686 DEVMETHOD(device_detach, sdhci_xenon_detach), 687 | |
688 /* Bus interface */ 689 DEVMETHOD(bus_read_ivar, sdhci_generic_read_ivar), 690 DEVMETHOD(bus_write_ivar, sdhci_generic_write_ivar), 691 692 /* mmcbr_if */ 693 DEVMETHOD(mmcbr_update_ios, sdhci_xenon_update_ios), 694 DEVMETHOD(mmcbr_request, sdhci_generic_request), 695 DEVMETHOD(mmcbr_get_ro, sdhci_xenon_get_ro), --- 7 unchanged lines hidden (view full) --- 703 DEVMETHOD(sdhci_read_1, sdhci_xenon_read_1), 704 DEVMETHOD(sdhci_read_2, sdhci_xenon_read_2), 705 DEVMETHOD(sdhci_read_4, sdhci_xenon_read_4), 706 DEVMETHOD(sdhci_read_multi_4, sdhci_xenon_read_multi_4), 707 DEVMETHOD(sdhci_write_1, sdhci_xenon_write_1), 708 DEVMETHOD(sdhci_write_2, sdhci_xenon_write_2), 709 DEVMETHOD(sdhci_write_4, sdhci_xenon_write_4), 710 DEVMETHOD(sdhci_write_multi_4, sdhci_xenon_write_multi_4), | 610 /* Bus interface */ 611 DEVMETHOD(bus_read_ivar, sdhci_generic_read_ivar), 612 DEVMETHOD(bus_write_ivar, sdhci_generic_write_ivar), 613 614 /* mmcbr_if */ 615 DEVMETHOD(mmcbr_update_ios, sdhci_xenon_update_ios), 616 DEVMETHOD(mmcbr_request, sdhci_generic_request), 617 DEVMETHOD(mmcbr_get_ro, sdhci_xenon_get_ro), --- 7 unchanged lines hidden (view full) --- 625 DEVMETHOD(sdhci_read_1, sdhci_xenon_read_1), 626 DEVMETHOD(sdhci_read_2, sdhci_xenon_read_2), 627 DEVMETHOD(sdhci_read_4, sdhci_xenon_read_4), 628 DEVMETHOD(sdhci_read_multi_4, sdhci_xenon_read_multi_4), 629 DEVMETHOD(sdhci_write_1, sdhci_xenon_write_1), 630 DEVMETHOD(sdhci_write_2, sdhci_xenon_write_2), 631 DEVMETHOD(sdhci_write_4, sdhci_xenon_write_4), 632 DEVMETHOD(sdhci_write_multi_4, sdhci_xenon_write_multi_4), |
711 DEVMETHOD(sdhci_get_card_present, sdhci_xenon_get_card_present), | |
712 DEVMETHOD(sdhci_set_uhs_timing, sdhci_xenon_set_uhs_timing), 713 714 DEVMETHOD_END 715}; 716 | 633 DEVMETHOD(sdhci_set_uhs_timing, sdhci_xenon_set_uhs_timing), 634 635 DEVMETHOD_END 636}; 637 |
717static driver_t sdhci_xenon_driver = { 718 "sdhci_xenon", 719 sdhci_xenon_methods, 720 sizeof(struct sdhci_xenon_softc), 721}; 722static devclass_t sdhci_xenon_devclass; | 638DEFINE_CLASS_0(sdhci_xenon, sdhci_xenon_driver, sdhci_xenon_methods, 639 sizeof(struct sdhci_xenon_softc)); |
723 | 640 |
724DRIVER_MODULE(sdhci_xenon, simplebus, sdhci_xenon_driver, sdhci_xenon_devclass, 725 NULL, NULL); 726 | |
727SDHCI_DEPEND(sdhci_xenon); 728#ifndef MMCCAM 729MMC_DECLARE_BRIDGE(sdhci_xenon); 730#endif | 641SDHCI_DEPEND(sdhci_xenon); 642#ifndef MMCCAM 643MMC_DECLARE_BRIDGE(sdhci_xenon); 644#endif |