Add support for RICOH R5CE823 card reader, that can be found in
some Lenovo laptops. The conroller needs a quirk to lower its frequency, and after that it operates normally.
This commit is contained in:
parent
27a58a0dde
commit
bdf6c01f6d
@ -24,7 +24,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd January 14, 2009
|
||||
.Dd February 9, 2012
|
||||
.Dt SDHCI 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -69,6 +69,8 @@ ENE CB714
|
||||
.It
|
||||
RICOH R5C822
|
||||
.It
|
||||
RICOH R5CE823
|
||||
.It
|
||||
TI PCIXX21/XX11
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
|
@ -74,6 +74,8 @@ __FBSDID("$FreeBSD$");
|
||||
#define SDHCI_QUIRK_INCR_TIMEOUT_CONTROL (1<<7)
|
||||
/* Controller has broken read timings */
|
||||
#define SDHCI_QUIRK_BROKEN_TIMINGS (1<<8)
|
||||
/* Controller needs lowered frequency */
|
||||
#define SDHCI_QUIRK_LOWER_FREQUENCY (1<<9)
|
||||
|
||||
static const struct sdhci_device {
|
||||
uint32_t model;
|
||||
@ -85,6 +87,8 @@ static const struct sdhci_device {
|
||||
SDHCI_QUIRK_FORCE_DMA },
|
||||
{ 0xe8221180, 0xffff, "RICOH SD",
|
||||
SDHCI_QUIRK_FORCE_DMA },
|
||||
{ 0xe8231180, 0xffff, "RICOH R5CE823 SD",
|
||||
SDHCI_QUIRK_LOWER_FREQUENCY },
|
||||
{ 0x8034104c, 0xffff, "TI XX21/XX11 SD",
|
||||
SDHCI_QUIRK_FORCE_DMA },
|
||||
{ 0x05501524, 0xffff, "ENE CB712 SD",
|
||||
@ -349,6 +353,24 @@ sdhci_init(struct sdhci_slot *slot)
|
||||
WR4(slot, SDHCI_SIGNAL_ENABLE, slot->intmask);
|
||||
}
|
||||
|
||||
static void
|
||||
sdhci_lower_frequency(device_t dev)
|
||||
{
|
||||
|
||||
/* Enable SD2.0 mode. */
|
||||
pci_write_config(dev, SDHC_PCI_MODE_KEY, 0xfc, 1);
|
||||
pci_write_config(dev, SDHC_PCI_MODE, SDHC_PCI_MODE_SD20, 1);
|
||||
pci_write_config(dev, SDHC_PCI_MODE_KEY, 0x00, 1);
|
||||
|
||||
/*
|
||||
* Some SD/MMC cards don't work with the default base
|
||||
* clock frequency of 200MHz. Lower it to 50Hz.
|
||||
*/
|
||||
pci_write_config(dev, SDHC_PCI_BASE_FREQ_KEY, 0x01, 1);
|
||||
pci_write_config(dev, SDHC_PCI_BASE_FREQ, 50, 1);
|
||||
pci_write_config(dev, SDHC_PCI_BASE_FREQ_KEY, 0x00, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
sdhci_set_clock(struct sdhci_slot *slot, uint32_t clock)
|
||||
{
|
||||
@ -631,6 +653,9 @@ sdhci_attach(device_t dev)
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Some controllers need to be bumped into the right mode. */
|
||||
if (sc->quirks & SDHCI_QUIRK_LOWER_FREQUENCY)
|
||||
sdhci_lower_frequency(dev);
|
||||
/* Read slots info from PCI registers. */
|
||||
slots = pci_read_config(dev, PCI_SLOT_INFO, 1);
|
||||
bar = PCI_SLOT_INFO_FIRST_BAR(slots);
|
||||
|
@ -37,6 +37,15 @@
|
||||
#define PCI_SLOT_INFO_SLOTS(x) (((x >> 4) & 7) + 1)
|
||||
#define PCI_SLOT_INFO_FIRST_BAR(x) ((x) & 7)
|
||||
|
||||
/*
|
||||
* RICOH specific PCI registers
|
||||
*/
|
||||
#define SDHC_PCI_MODE_KEY 0xf9
|
||||
#define SDHC_PCI_MODE 0x150
|
||||
#define SDHC_PCI_MODE_SD20 0x10
|
||||
#define SDHC_PCI_BASE_FREQ_KEY 0xfc
|
||||
#define SDHC_PCI_BASE_FREQ 0xe1
|
||||
|
||||
/*
|
||||
* Controller registers
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user