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
  */
 
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to