Hi, This can make MMC/SD driver work on O2 chip. Best regards, Jennifer --- /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) }, Unless otherwise stated, this e-mail message does not constitute a solicitation to buy or sell any products or services, or to participate in any particular trading strategy. This e-mail message and any attachments are intended solely for the use of the individual or entity to which it is addressed and may contain information that is confidential or legally privileged. If you are not the intended recipient, you are hereby notified that any dissemination, distribution, copying or other use of this message or its attachments is strictly prohibited. If you have received this message in error, please notify the sender immediately and permanently delete this message and any attachments. O2Micro International Ltd., and its subsidiaries and affiliates, are neither liable for the proper and complete transmission of the information contained in this communication, the accuracy of the information contained therein, nor for any delay in its receipt.
Attachment:
patch
Description: patch