Add a new sdhci interface method, get_card_present().
Many embedded SoC controllers that are (more or less) sdhci-compatible don't implement card detect, and the related values in the PRESENT_STATE register aren't useful. A bridge driver can now implement get_card_present() to read a gpio pin or whatever else is necessary for that system. The default implementation reads the CARD_PRESENT bit from the PRESENT_STATE register, so existing drivers will keep working (or keep not-fully-working, since many drivers right now can't detect card insert/remove).
This commit is contained in:
parent
0922cf8d32
commit
6e37fb2b62
@ -164,8 +164,7 @@ sdhci_reset(struct sdhci_slot *slot, uint8_t mask)
|
||||
int timeout;
|
||||
|
||||
if (slot->quirks & SDHCI_QUIRK_NO_CARD_NO_RESET) {
|
||||
if (!(RD4(slot, SDHCI_PRESENT_STATE) &
|
||||
SDHCI_CARD_PRESENT))
|
||||
if (!SDHCI_GET_CARD_PRESENT(slot->bus, slot))
|
||||
return;
|
||||
}
|
||||
|
||||
@ -489,7 +488,7 @@ sdhci_card_task(void *arg, int pending)
|
||||
struct sdhci_slot *slot = arg;
|
||||
|
||||
SDHCI_LOCK(slot);
|
||||
if (RD4(slot, SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT) {
|
||||
if (SDHCI_GET_CARD_PRESENT(slot->bus, slot)) {
|
||||
if (slot->dev == NULL) {
|
||||
/* If card is present - attach mmc bus. */
|
||||
slot->dev = device_add_child(slot->bus, "mmc", -1);
|
||||
@ -718,6 +717,13 @@ sdhci_generic_min_freq(device_t brdev, struct sdhci_slot *slot)
|
||||
return (slot->max_clk / SDHCI_200_MAX_DIVIDER);
|
||||
}
|
||||
|
||||
bool
|
||||
sdhci_generic_get_card_present(device_t brdev, struct sdhci_slot *slot)
|
||||
{
|
||||
|
||||
return (RD4(slot, SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT);
|
||||
}
|
||||
|
||||
int
|
||||
sdhci_generic_update_ios(device_t brdev, device_t reqdev)
|
||||
{
|
||||
@ -834,7 +840,7 @@ sdhci_start_command(struct sdhci_slot *slot, struct mmc_command *cmd)
|
||||
state = RD4(slot, SDHCI_PRESENT_STATE);
|
||||
/* Do not issue command if there is no card, clock or power.
|
||||
* Controller will not detect timeout without clock active. */
|
||||
if ((state & SDHCI_CARD_PRESENT) == 0 ||
|
||||
if (!SDHCI_GET_CARD_PRESENT(slot->bus, slot) ||
|
||||
slot->power == 0 ||
|
||||
slot->clock == 0) {
|
||||
cmd->error = MMC_ERR_FAILED;
|
||||
@ -1323,7 +1329,7 @@ sdhci_generic_intr(struct sdhci_slot *slot)
|
||||
|
||||
/* Handle card presence interrupts. */
|
||||
if (intmask & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE)) {
|
||||
present = RD4(slot, SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT;
|
||||
present = SDHCI_GET_CARD_PRESENT(slot->bus, slot);
|
||||
slot->intmask &=
|
||||
~(SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE);
|
||||
slot->intmask |= present ? SDHCI_INT_CARD_REMOVE :
|
||||
|
@ -322,5 +322,6 @@ int sdhci_generic_acquire_host(device_t brdev, device_t reqdev);
|
||||
int sdhci_generic_release_host(device_t brdev, device_t reqdev);
|
||||
void sdhci_generic_intr(struct sdhci_slot *slot);
|
||||
uint32_t sdhci_generic_min_freq(device_t brdev, struct sdhci_slot *slot);
|
||||
bool sdhci_generic_get_card_present(device_t brdev, struct sdhci_slot *slot);
|
||||
|
||||
#endif /* __SDHCI_H__ */
|
||||
|
@ -152,3 +152,9 @@ METHOD uint32_t min_freq {
|
||||
device_t brdev;
|
||||
struct sdhci_slot *slot;
|
||||
} DEFAULT sdhci_generic_min_freq;
|
||||
|
||||
METHOD bool get_card_present {
|
||||
device_t brdev;
|
||||
struct sdhci_slot *slot;
|
||||
} DEFAULT sdhci_generic_get_card_present;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user