svn commit: r237224 - stable/9/sys/dev/sdhci
Gleb Smirnoff
glebius at FreeBSD.org
Mon Jun 18 10:56:30 UTC 2012
Author: glebius
Date: Mon Jun 18 10:56:29 2012
New Revision: 237224
URL: http://svn.freebsd.org/changeset/base/237224
Log:
Merge 231266 from head:
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.
Modified:
stable/9/sys/dev/sdhci/sdhci.c
stable/9/sys/dev/sdhci/sdhci.h
Directory Properties:
stable/9/sys/ (props changed)
stable/9/sys/dev/ (props changed)
Modified: stable/9/sys/dev/sdhci/sdhci.c
==============================================================================
--- stable/9/sys/dev/sdhci/sdhci.c Mon Jun 18 07:54:10 2012 (r237223)
+++ stable/9/sys/dev/sdhci/sdhci.c Mon Jun 18 10:56:29 2012 (r237224)
@@ -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",
@@ -350,6 +354,24 @@ sdhci_init(struct sdhci_slot *slot)
}
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)
{
uint32_t res;
@@ -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);
Modified: stable/9/sys/dev/sdhci/sdhci.h
==============================================================================
--- stable/9/sys/dev/sdhci/sdhci.h Mon Jun 18 07:54:10 2012 (r237223)
+++ stable/9/sys/dev/sdhci/sdhci.h Mon Jun 18 10:56:29 2012 (r237224)
@@ -38,6 +38,15 @@
#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
*/
More information about the svn-src-stable-9
mailing list