Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 18 Jun 2012 10:56:30 +0000 (UTC)
From:      Gleb Smirnoff <glebius@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org
Subject:   svn commit: r237224 - stable/9/sys/dev/sdhci
Message-ID:  <201206181056.q5IAuUwX075136@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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
  */
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201206181056.q5IAuUwX075136>