aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/mmc/host/sdhci-pci.c112
-rw-r--r--include/linux/pci_ids.h5
2 files changed, 117 insertions, 0 deletions
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c
index 3d9c2460d437..831cf91b644a 100644
--- a/drivers/mmc/host/sdhci-pci.c
+++ b/drivers/mmc/host/sdhci-pci.c
@@ -176,6 +176,74 @@ static const struct sdhci_pci_fixes sdhci_intel_mfd_emmc_sdio = {
176 .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC, 176 .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC,
177}; 177};
178 178
179/* O2Micro extra registers */
180#define O2_SD_LOCK_WP 0xD3
181#define O2_SD_MULTI_VCC3V 0xEE
182#define O2_SD_CLKREQ 0xEC
183#define O2_SD_CAPS 0xE0
184#define O2_SD_ADMA1 0xE2
185#define O2_SD_ADMA2 0xE7
186#define O2_SD_INF_MOD 0xF1
187
188static int o2_probe(struct sdhci_pci_chip *chip)
189{
190 int ret;
191 u8 scratch;
192
193 switch (chip->pdev->device) {
194 case PCI_DEVICE_ID_O2_8220:
195 case PCI_DEVICE_ID_O2_8221:
196 case PCI_DEVICE_ID_O2_8320:
197 case PCI_DEVICE_ID_O2_8321:
198 /* This extra setup is required due to broken ADMA. */
199 ret = pci_read_config_byte(chip->pdev, O2_SD_LOCK_WP, &scratch);
200 if (ret)
201 return ret;
202 scratch &= 0x7f;
203 pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch);
204
205 /* Set Multi 3 to VCC3V# */
206 pci_write_config_byte(chip->pdev, O2_SD_MULTI_VCC3V, 0x08);
207
208 /* Disable CLK_REQ# support after media DET */
209 ret = pci_read_config_byte(chip->pdev, O2_SD_CLKREQ, &scratch);
210 if (ret)
211 return ret;
212 scratch |= 0x20;
213 pci_write_config_byte(chip->pdev, O2_SD_CLKREQ, scratch);
214
215 /* Choose capabilities, enable SDMA. We have to write 0x01
216 * to the capabilities register first to unlock it.
217 */
218 ret = pci_read_config_byte(chip->pdev, O2_SD_CAPS, &scratch);
219 if (ret)
220 return ret;
221 scratch |= 0x01;
222 pci_write_config_byte(chip->pdev, O2_SD_CAPS, scratch);
223 pci_write_config_byte(chip->pdev, O2_SD_CAPS, 0x73);
224
225 /* Disable ADMA1/2 */
226 pci_write_config_byte(chip->pdev, O2_SD_ADMA1, 0x39);
227 pci_write_config_byte(chip->pdev, O2_SD_ADMA2, 0x08);
228
229 /* Disable the infinite transfer mode */
230 ret = pci_read_config_byte(chip->pdev, O2_SD_INF_MOD, &scratch);
231 if (ret)
232 return ret;
233 scratch |= 0x08;
234 pci_write_config_byte(chip->pdev, O2_SD_INF_MOD, scratch);
235
236 /* Lock WP */
237 ret = pci_read_config_byte(chip->pdev, O2_SD_LOCK_WP, &scratch);
238 if (ret)
239 return ret;
240 scratch |= 0x80;
241 pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch);
242 }
243
244 return 0;
245}
246
179static int jmicron_pmos(struct sdhci_pci_chip *chip, int on) 247static int jmicron_pmos(struct sdhci_pci_chip *chip, int on)
180{ 248{
181 u8 scratch; 249 u8 scratch;
@@ -339,6 +407,10 @@ static int jmicron_resume(struct sdhci_pci_chip *chip)
339 return 0; 407 return 0;
340} 408}
341 409
410static const struct sdhci_pci_fixes sdhci_o2 = {
411 .probe = o2_probe,
412};
413
342static const struct sdhci_pci_fixes sdhci_jmicron = { 414static const struct sdhci_pci_fixes sdhci_jmicron = {
343 .probe = jmicron_probe, 415 .probe = jmicron_probe,
344 416
@@ -589,6 +661,46 @@ static const struct pci_device_id pci_ids[] __devinitdata = {
589 .driver_data = (kernel_ulong_t)&sdhci_intel_mfd_emmc_sdio, 661 .driver_data = (kernel_ulong_t)&sdhci_intel_mfd_emmc_sdio,
590 }, 662 },
591 663
664 {
665 .vendor = PCI_VENDOR_ID_O2,
666 .device = PCI_DEVICE_ID_O2_8120,
667 .subvendor = PCI_ANY_ID,
668 .subdevice = PCI_ANY_ID,
669 .driver_data = (kernel_ulong_t)&sdhci_o2,
670 },
671
672 {
673 .vendor = PCI_VENDOR_ID_O2,
674 .device = PCI_DEVICE_ID_O2_8220,
675 .subvendor = PCI_ANY_ID,
676 .subdevice = PCI_ANY_ID,
677 .driver_data = (kernel_ulong_t)&sdhci_o2,
678 },
679
680 {
681 .vendor = PCI_VENDOR_ID_O2,
682 .device = PCI_DEVICE_ID_O2_8221,
683 .subvendor = PCI_ANY_ID,
684 .subdevice = PCI_ANY_ID,
685 .driver_data = (kernel_ulong_t)&sdhci_o2,
686 },
687
688 {
689 .vendor = PCI_VENDOR_ID_O2,
690 .device = PCI_DEVICE_ID_O2_8320,
691 .subvendor = PCI_ANY_ID,
692 .subdevice = PCI_ANY_ID,
693 .driver_data = (kernel_ulong_t)&sdhci_o2,
694 },
695
696 {
697 .vendor = PCI_VENDOR_ID_O2,
698 .device = PCI_DEVICE_ID_O2_8321,
699 .subvendor = PCI_ANY_ID,
700 .subdevice = PCI_ANY_ID,
701 .driver_data = (kernel_ulong_t)&sdhci_o2,
702 },
703
592 { /* Generic SD host controller */ 704 { /* Generic SD host controller */
593 PCI_DEVICE_CLASS((PCI_CLASS_SYSTEM_SDHCI << 8), 0xFFFF00) 705 PCI_DEVICE_CLASS((PCI_CLASS_SYSTEM_SDHCI << 8), 0xFFFF00)
594 }, 706 },
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index cb845c16ad7d..7a58875cdad5 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -1650,6 +1650,11 @@
1650#define PCI_DEVICE_ID_O2_6836 0x6836 1650#define PCI_DEVICE_ID_O2_6836 0x6836
1651#define PCI_DEVICE_ID_O2_6812 0x6872 1651#define PCI_DEVICE_ID_O2_6812 0x6872
1652#define PCI_DEVICE_ID_O2_6933 0x6933 1652#define PCI_DEVICE_ID_O2_6933 0x6933
1653#define PCI_DEVICE_ID_O2_8120 0x8120
1654#define PCI_DEVICE_ID_O2_8220 0x8220
1655#define PCI_DEVICE_ID_O2_8221 0x8221
1656#define PCI_DEVICE_ID_O2_8320 0x8320
1657#define PCI_DEVICE_ID_O2_8321 0x8321
1653 1658
1654#define PCI_VENDOR_ID_3DFX 0x121a 1659#define PCI_VENDOR_ID_3DFX 0x121a
1655#define PCI_DEVICE_ID_3DFX_VOODOO 0x0001 1660#define PCI_DEVICE_ID_3DFX_VOODOO 0x0001