@@ -39,6 +39,26 @@
#define MAX_SLOTS 8
+#ifndef PCI_DEVICE_ID_O2_8120
+#define PCI_DEVICE_ID_O2_8120 0x8120
+#endif
+
+#ifndef PCI_DEVICE_ID_O2_8220
+#define PCI_DEVICE_ID_O2_8220 0x8220
+#endif
+
+#ifndef PCI_DEVICE_ID_O2_8320
+#define PCI_DEVICE_ID_O2_8320 0x8320
+#endif
+
+#ifndef PCI_DEVICE_ID_O2_8321
+#define PCI_DEVICE_ID_O2_8321 0x8321
+#endif
+
+#ifndef PCI_DEVICE_ID_O2_8221
+#define PCI_DEVICE_ID_O2_8221 0x8221
+#endif
+
struct sdhci_pci_chip;
struct sdhci_pci_slot;
@@ -112,6 +132,118 @@ static const struct sdhci_pci_fixes sdhc
SDHCI_QUIRK_BROKEN_TIMEOUT_VAL,
};
+static int o2_probe(struct sdhci_pci_chip *chip)
+{
+ int ret;
+ u8 scratch;
+
+ if ((chip->pdev->device == PCI_DEVICE_ID_O2_8220) ||
+ (chip->pdev->device == PCI_DEVICE_ID_O2_8320) ||
+ (chip->pdev->device == PCI_DEVICE_ID_O2_8321) ||
+ (chip->pdev->device == PCI_DEVICE_ID_O2_8221))
+ {
+ //set D3 to 0x7f
+ ret = pci_read_config_byte(chip->pdev, 0xD3, &scratch);
+ if (ret)
+ return ret;
+
+ scratch &= 0x7f;
+
+ ret = pci_write_config_byte(chip->pdev, 0xD3, scratch);
+ if (ret)
+ return ret;
+
+ // set EE to 08
+ ret = pci_read_config_byte(chip->pdev, 0xEE, &scratch);
+ if (ret)
+ return ret;
+
+ scratch = 0x08;
+
+ ret = pci_write_config_byte(chip->pdev, 0xEE, scratch);
+ if (ret)
+ return ret;
+
+ // set Ec to 0x20
+ ret = pci_read_config_byte(chip->pdev, 0xEC, &scratch);
+ if (ret)
+ return ret;
+
+ scratch |= 0x20;
+
+ ret = pci_write_config_byte(chip->pdev, 0xEC, scratch);
+ if (ret)
+ return ret;
+
+ // set E0 to 0x01
+ ret = pci_read_config_byte(chip->pdev, 0xE0, &scratch);
+ if (ret)
+ return ret;
+
+ scratch |= 0x01;
+
+ ret = pci_write_config_byte(chip->pdev, 0xE0, scratch);
+ if (ret)
+ return ret;
+
+ // set E0 to 0x73
+ ret = pci_read_config_byte(chip->pdev, 0xE0, &scratch);
+ if (ret)
+ return ret;
+
+ scratch = 0x73;
+
+ ret = pci_write_config_byte(chip->pdev, 0xE0, scratch);
+ if (ret)
+ return ret;
+
+ // set E2 to 0x39
+ ret = pci_read_config_byte(chip->pdev, 0xE2, &scratch);
+ if (ret)
+ return ret;
+
+ scratch = 0x39;
+
+ ret = pci_write_config_byte(chip->pdev, 0xE2, scratch);
+ if (ret)
+ return ret;
+
+ // set E7 to 0x08
+ ret = pci_read_config_byte(chip->pdev, 0xE7, &scratch);
+ if (ret)
+ return ret;
+
+ scratch = 0x08;
+
+ ret = pci_write_config_byte(chip->pdev, 0xE7, scratch);
+ if (ret)
+ return ret;
+
+ // set f1 to 0x08
+ ret = pci_read_config_byte(chip->pdev, 0xF1, &scratch);
+ if (ret)
+ return ret;
+
+ scratch |= 0x08;
+
+ ret = pci_write_config_byte(chip->pdev, 0xF1, scratch);
+ if (ret)
+ return ret;
+
+ //set D3 to 80
+ ret = pci_read_config_byte(chip->pdev, 0xD3, &scratch);
+ if (ret)
+ return ret;
+
+ scratch |= 0x80;
+
+ ret = pci_write_config_byte(chip->pdev, 0xD3, scratch);
+ if (ret)
+ return ret;
+ }
+ return 0;
+}
+
static int jmicron_pmos(struct sdhci_pci_chip *chip, int on)
{
u8 scratch;
@@ -275,6 +407,11 @@ static int jmicron_resume(struct sdhci_p
return 0;
}
+static const struct sdhci_pci_fixes sdhci_o2 = {
+ .probe = o2_probe,
+// .quirks = SDHCI_QUICK_ADMA_TABLE_ENTRY,
+};
+
static const struct sdhci_pci_fixes sdhci_jmicron = {
.probe = jmicron_probe,
@@ -445,6 +582,46 @@ static const struct pci_device_id pci_id
.driver_data = (kernel_ulong_t)&sdhci_via,
},
+ {
+ .vendor = PCI_VENDOR_ID_O2,
+ .device = PCI_DEVICE_ID_O2_8120,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .driver_data = (kernel_ulong_t)&sdhci_o2,
+ },
+
+ {
+ .vendor = PCI_VENDOR_ID_O2,
+ .device = PCI_DEVICE_ID_O2_8220,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .driver_data = (kernel_ulong_t)&sdhci_o2,
+ },
+
+ {
+ .vendor = PCI_VENDOR_ID_O2,
+ .device = PCI_DEVICE_ID_O2_8320,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .driver_data = (kernel_ulong_t)&sdhci_o2,
+ },
+
+ {
+ .vendor = PCI_VENDOR_ID_O2,
+ .device = PCI_DEVICE_ID_O2_8221,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .driver_data = (kernel_ulong_t)&sdhci_o2,
+ },
+
+ {
+ .vendor = PCI_VENDOR_ID_O2,
+ .device = PCI_DEVICE_ID_O2_8321,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .driver_data = (kernel_ulong_t)&sdhci_o2,
+ },
+
{ /* Generic SD host controller */
PCI_DEVICE_CLASS((PCI_CLASS_SYSTEM_SDHCI << 8), 0xFFFF00)
},