aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host/sdhci-pci.c
diff options
context:
space:
mode:
authorPierre Ossman <drzeus@drzeus.cx>2008-03-24 08:09:09 -0400
committerPierre Ossman <drzeus@drzeus.cx>2008-07-15 08:14:40 -0400
commit45211e21598441a32e53cf5032b7faeac143df6d (patch)
tree66a2d252c81160ad3284a695a50b73a1e260bfaf /drivers/mmc/host/sdhci-pci.c
parentee53ab5d73998e502801c024a08de2c39a92c52a (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/host/sdhci-pci.c')
-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 856bb2b2837e..ef77ed1bd114 100644
--- a/drivers/mmc/host/sdhci-pci.c
+++ b/drivers/mmc/host/sdhci-pci.c
@@ -44,6 +44,8 @@ struct sdhci_pci_fixes {
44 unsigned int quirks; 44 unsigned int quirks;
45 45
46 int (*probe)(struct sdhci_pci_chip*); 46 int (*probe)(struct sdhci_pci_chip*);
47
48 int (*resume)(struct sdhci_pci_chip*);
47}; 49};
48 50
49struct sdhci_pci_slot { 51struct sdhci_pci_slot {
@@ -101,10 +103,69 @@ static const struct sdhci_pci_fixes sdhci_cafe = {
101 SDHCI_QUIRK_BROKEN_TIMEOUT_VAL, 103 SDHCI_QUIRK_BROKEN_TIMEOUT_VAL,
102}; 104};
103 105
106static int jmicron_pmos(struct sdhci_pci_chip *chip, int on)
107{
108 u8 scratch;
109 int ret;
110
111 ret = pci_read_config_byte(chip->pdev, 0xAE, &scratch);
112 if (ret)
113 return ret;
114
115 /*
116 * Turn PMOS on [bit 0], set over current detection to 2.4 V
117 * [bit 1:2] and enable over current debouncing [bit 6].
118 */
119 if (on)
120 scratch |= 0x47;
121 else
122 scratch &= ~0x47;
123
124 ret = pci_write_config_byte(chip->pdev, 0xAE, scratch);
125 if (ret)
126 return ret;
127
128 return 0;
129}
130
131static int jmicron_probe(struct sdhci_pci_chip *chip)
132{
133 int ret;
134
135 /*
136 * JMicron chips need a bit of a nudge to enable the power
137 * output pins.
138 */
139 ret = jmicron_pmos(chip, 1);
140 if (ret) {
141 dev_err(&chip->pdev->dev, "Failure enabling card power\n");
142 return ret;
143 }
144
145 return 0;
146}
147
148static int jmicron_resume(struct sdhci_pci_chip *chip)
149{
150 int ret;
151
152 ret = jmicron_pmos(chip, 1);
153 if (ret) {
154 dev_err(&chip->pdev->dev, "Failure enabling card power\n");
155 return ret;
156 }
157
158 return 0;
159}
160
104static const struct sdhci_pci_fixes sdhci_jmicron = { 161static const struct sdhci_pci_fixes sdhci_jmicron = {
105 .quirks = SDHCI_QUIRK_32BIT_DMA_ADDR | 162 .quirks = SDHCI_QUIRK_32BIT_DMA_ADDR |
106 SDHCI_QUIRK_32BIT_DMA_SIZE | 163 SDHCI_QUIRK_32BIT_DMA_SIZE |
107 SDHCI_QUIRK_RESET_AFTER_REQUEST, 164 SDHCI_QUIRK_RESET_AFTER_REQUEST,
165
166 .probe = jmicron_probe,
167
168 .resume = jmicron_resume,
108}; 169};
109 170
110static const struct pci_device_id pci_ids[] __devinitdata = { 171static const struct pci_device_id pci_ids[] __devinitdata = {
@@ -264,6 +325,12 @@ static int sdhci_pci_resume (struct pci_dev *pdev)
264 if (ret) 325 if (ret)
265 return ret; 326 return ret;
266 327
328 if (chip->fixes && chip->fixes->resume) {
329 ret = chip->fixes->resume(chip);
330 if (ret)
331 return ret;
332 }
333
267 for (i = 0;i < chip->num_slots;i++) { 334 for (i = 0;i < chip->num_slots;i++) {
268 slot = chip->slots[i]; 335 slot = chip->slots[i];
269 if (!slot) 336 if (!slot)