summaryrefslogtreecommitdiff
path: root/drivers/mmc
diff options
context:
space:
mode:
authorPierre Ossman <drzeus@drzeus.cx>2008-03-24 13:09:09 +0100
committerPierre Ossman <drzeus@drzeus.cx>2008-05-28 09:24:30 +0200
commit81e51afdcd7c3cc93e42e4aceb7529f90105d8a7 (patch)
tree2bbe8446b5fa11b78584bc4a5cbff6571110ecf8 /drivers/mmc
parenta94896c52a6e08596d37a07cda644d31c12aa10a (diff)
sdhci: toggle JMicron PMOS setting
Some of the JMicron chips requires us to manually enable the power output stages of the chip. Add the necessary hooks and functions to manage this. Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/host/sdhci-pci.c67
1 files changed, 67 insertions, 0 deletions
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c
index ff9ece28d6fa..51c76e6ffa3e 100644
--- a/drivers/mmc/host/sdhci-pci.c
+++ b/drivers/mmc/host/sdhci-pci.c
@@ -44,6 +44,8 @@ struct sdhci_pci_fixes {
unsigned int quirks;
int (*probe)(struct sdhci_pci_chip*);
+
+ int (*resume)(struct sdhci_pci_chip*);
};
struct sdhci_pci_slot {
@@ -95,10 +97,69 @@ static const struct sdhci_pci_fixes sdhci_ene_714 = {
SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS,
};
+static int jmicron_pmos(struct sdhci_pci_chip *chip, int on)
+{
+ u8 scratch;
+ int ret;
+
+ ret = pci_read_config_byte(chip->pdev, 0xAE, &scratch);
+ if (ret)
+ return ret;
+
+ /*
+ * Turn PMOS on [bit 0], set over current detection to 2.4 V
+ * [bit 1:2] and enable over current debouncing [bit 6].
+ */
+ if (on)
+ scratch |= 0x47;
+ else
+ scratch &= ~0x47;
+
+ ret = pci_write_config_byte(chip->pdev, 0xAE, scratch);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int jmicron_probe(struct sdhci_pci_chip *chip)
+{
+ int ret;
+
+ /*
+ * JMicron chips need a bit of a nudge to enable the power
+ * output pins.
+ */
+ ret = jmicron_pmos(chip, 1);
+ if (ret) {
+ dev_err(&chip->pdev->dev, "Failure enabling card power\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static int jmicron_resume(struct sdhci_pci_chip *chip)
+{
+ int ret;
+
+ ret = jmicron_pmos(chip, 1);
+ if (ret) {
+ dev_err(&chip->pdev->dev, "Failure enabling card power\n");
+ return ret;
+ }
+
+ return 0;
+}
+
static const struct sdhci_pci_fixes sdhci_jmicron = {
.quirks = SDHCI_QUIRK_32BIT_DMA_ADDR |
SDHCI_QUIRK_32BIT_DMA_SIZE |
SDHCI_QUIRK_RESET_AFTER_REQUEST,
+
+ .probe = jmicron_probe,
+
+ .resume = jmicron_resume,
};
static const struct pci_device_id pci_ids[] __devinitdata = {
@@ -250,6 +311,12 @@ static int sdhci_pci_resume (struct pci_dev *pdev)
if (ret)
return ret;
+ if (chip->fixes && chip->fixes->resume) {
+ ret = chip->fixes->resume(chip);
+ if (ret)
+ return ret;
+ }
+
for (i = 0;i < chip->num_slots;i++) {
slot = chip->slots[i];
if (!slot)