--- /home/j/Desktop/kernel_source_1104/linux-2.6.35/drivers/mmc/host/sdhci-pci.c 2010-08-02 06:11:14.000000000 +0800 +++ /home/j/Desktop/SD_ADMAissue_8220_8320/20101020_sdhci_pci_c/sdhci-pci.c 2010-10-20 23:44:50.000000000 +0800 @@ -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) },