Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 9 Feb 2012 10:20:42 +0000 (UTC)
From:      Gleb Smirnoff <glebius@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r231266 - in head: share/man/man4 sys/dev/sdhci
Message-ID:  <201202091020.q19AKgi0093783@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: glebius
Date: Thu Feb  9 10:20:41 2012
New Revision: 231266
URL: http://svn.freebsd.org/changeset/base/231266

Log:
  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:
  head/share/man/man4/sdhci.4
  head/sys/dev/sdhci/sdhci.c
  head/sys/dev/sdhci/sdhci.h

Modified: head/share/man/man4/sdhci.4
==============================================================================
--- head/share/man/man4/sdhci.4	Thu Feb  9 10:09:12 2012	(r231265)
+++ head/share/man/man4/sdhci.4	Thu Feb  9 10:20:41 2012	(r231266)
@@ -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

Modified: head/sys/dev/sdhci/sdhci.c
==============================================================================
--- head/sys/dev/sdhci/sdhci.c	Thu Feb  9 10:09:12 2012	(r231265)
+++ head/sys/dev/sdhci/sdhci.c	Thu Feb  9 10:20:41 2012	(r231266)
@@ -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: head/sys/dev/sdhci/sdhci.h
==============================================================================
--- head/sys/dev/sdhci/sdhci.h	Thu Feb  9 10:09:12 2012	(r231265)
+++ head/sys/dev/sdhci/sdhci.h	Thu Feb  9 10:20:41 2012	(r231266)
@@ -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?201202091020.q19AKgi0093783>