Ack: [Saucy][PATCH 2/2] mmc: sdhci-pci: add support of O2Micro/BayHubTech SD hosts
Brad Figg
brad.figg at canonical.com
Mon Jan 27 15:31:17 UTC 2014
On 01/27/2014 04:42 AM, Adam Lee wrote:
> BugLink: http://bugs.launchpad.net/bugs/1239938
>
> Add O2Micro/BayHubTech SD Host DeviceId 8520 support.
> Add O2Micro/BayHubTech SD Host DeviceId 8420 & 8421 support.
> Add O2Micro/BayHubTech SD Host DeviceId 8620 & 8621 support.
>
> These card readers are used in laptops like Lenovo ThinkPad W540,
> Dell Latitude E5440, Dell Latitude E6540.
>
> Signed-off-by: Peter Guo <peter.guo at bayhubtech.com>
> Signed-off-by: Adam Lee <adam.lee at canonical.com>
> Signed-off-by: Chris Ball <chris at printf.net>
> (cherry picked from commit 01acf6917aed934388609177605d54ad1463b252)
> Signed-off-by: Adam Lee <adam.lee at canonical.com>
> ---
> drivers/mmc/host/Makefile | 1 +
> drivers/mmc/host/sdhci-pci-o2micro.c | 321 +++++++++++++++++++++++++++++++++++
> drivers/mmc/host/sdhci-pci-o2micro.h | 72 ++++++++
> drivers/mmc/host/sdhci-pci.c | 105 +++++-------
> 4 files changed, 439 insertions(+), 60 deletions(-)
> create mode 100644 drivers/mmc/host/sdhci-pci-o2micro.c
> create mode 100644 drivers/mmc/host/sdhci-pci-o2micro.h
>
> diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
> index d422e21..b07dca9 100644
> --- a/drivers/mmc/host/Makefile
> +++ b/drivers/mmc/host/Makefile
> @@ -9,6 +9,7 @@ obj-$(CONFIG_MMC_MXS) += mxs-mmc.o
> obj-$(CONFIG_MMC_SDHCI) += sdhci.o
> obj-$(CONFIG_MMC_SDHCI_PCI) += sdhci-pci.o
> obj-$(subst m,y,$(CONFIG_MMC_SDHCI_PCI)) += sdhci-pci-data.o
> +obj-$(subst m,y,$(CONFIG_MMC_SDHCI_PCI)) += sdhci-pci-o2micro.o
> obj-$(CONFIG_MMC_SDHCI_ACPI) += sdhci-acpi.o
> obj-$(CONFIG_MMC_SDHCI_PXAV3) += sdhci-pxav3.o
> obj-$(CONFIG_MMC_SDHCI_PXAV2) += sdhci-pxav2.o
> diff --git a/drivers/mmc/host/sdhci-pci-o2micro.c b/drivers/mmc/host/sdhci-pci-o2micro.c
> new file mode 100644
> index 0000000..f49666b
> --- /dev/null
> +++ b/drivers/mmc/host/sdhci-pci-o2micro.c
> @@ -0,0 +1,321 @@
> +/*
> + * Copyright (C) 2013 BayHub Technology Ltd.
> + *
> + * Authors: Peter Guo <peter.guo at bayhubtech.com>
> + * Adam Lee <adam.lee at canonical.com>
> + *
> + * This software is licensed under the terms of the GNU General Public
> + * License version 2, as published by the Free Software Foundation, and
> + * may be copied, distributed, and modified under those terms.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + */
> +
> +#include <linux/pci.h>
> +
> +#include "sdhci.h"
> +#include "sdhci-pci.h"
> +#include "sdhci-pci-o2micro.h"
> +
> +void sdhci_pci_o2_fujin2_pci_init(struct sdhci_pci_chip *chip)
> +{
> + u32 scratch_32;
> + int ret;
> + /* Improve write performance for SD3.0 */
> + ret = pci_read_config_dword(chip->pdev, O2_SD_DEV_CTRL, &scratch_32);
> + if (ret)
> + return;
> + scratch_32 &= ~((1 << 12) | (1 << 13) | (1 << 14));
> + pci_write_config_dword(chip->pdev, O2_SD_DEV_CTRL, scratch_32);
> +
> + /* Enable Link abnormal reset generating Reset */
> + ret = pci_read_config_dword(chip->pdev, O2_SD_MISC_REG5, &scratch_32);
> + if (ret)
> + return;
> + scratch_32 &= ~((1 << 19) | (1 << 11));
> + scratch_32 |= (1 << 10);
> + pci_write_config_dword(chip->pdev, O2_SD_MISC_REG5, scratch_32);
> +
> + /* set card power over current protection */
> + ret = pci_read_config_dword(chip->pdev, O2_SD_TEST_REG, &scratch_32);
> + if (ret)
> + return;
> + scratch_32 |= (1 << 4);
> + pci_write_config_dword(chip->pdev, O2_SD_TEST_REG, scratch_32);
> +
> + /* adjust the output delay for SD mode */
> + pci_write_config_dword(chip->pdev, O2_SD_DELAY_CTRL, 0x00002492);
> +
> + /* Set the output voltage setting of Aux 1.2v LDO */
> + ret = pci_read_config_dword(chip->pdev, O2_SD_LD0_CTRL, &scratch_32);
> + if (ret)
> + return;
> + scratch_32 &= ~(3 << 12);
> + pci_write_config_dword(chip->pdev, O2_SD_LD0_CTRL, scratch_32);
> +
> + /* Set Max power supply capability of SD host */
> + ret = pci_read_config_dword(chip->pdev, O2_SD_CAP_REG0, &scratch_32);
> + if (ret)
> + return;
> + scratch_32 &= ~(0x01FE);
> + scratch_32 |= 0x00CC;
> + pci_write_config_dword(chip->pdev, O2_SD_CAP_REG0, scratch_32);
> + /* Set DLL Tuning Window */
> + ret = pci_read_config_dword(chip->pdev,
> + O2_SD_TUNING_CTRL, &scratch_32);
> + if (ret)
> + return;
> + scratch_32 &= ~(0x000000FF);
> + scratch_32 |= 0x00000066;
> + pci_write_config_dword(chip->pdev, O2_SD_TUNING_CTRL, scratch_32);
> +
> + /* Set UHS2 T_EIDLE */
> + ret = pci_read_config_dword(chip->pdev,
> + O2_SD_UHS2_L1_CTRL, &scratch_32);
> + if (ret)
> + return;
> + scratch_32 &= ~(0x000000FC);
> + scratch_32 |= 0x00000084;
> + pci_write_config_dword(chip->pdev, O2_SD_UHS2_L1_CTRL, scratch_32);
> +
> + /* Set UHS2 Termination */
> + ret = pci_read_config_dword(chip->pdev, O2_SD_FUNC_REG3, &scratch_32);
> + if (ret)
> + return;
> + scratch_32 &= ~((1 << 21) | (1 << 30));
> +
> + /* Set RTD3 function disabled */
> + scratch_32 |= ((1 << 29) | (1 << 28));
> + pci_write_config_dword(chip->pdev, O2_SD_FUNC_REG3, scratch_32);
> +
> + /* Set L1 Entrance Timer */
> + ret = pci_read_config_dword(chip->pdev, O2_SD_CAPS, &scratch_32);
> + if (ret)
> + return;
> + scratch_32 &= ~(0xf0000000);
> + scratch_32 |= 0x30000000;
> + pci_write_config_dword(chip->pdev, O2_SD_CAPS, scratch_32);
> +
> + ret = pci_read_config_dword(chip->pdev,
> + O2_SD_MISC_CTRL4, &scratch_32);
> + if (ret)
> + return;
> + scratch_32 &= ~(0x000f0000);
> + scratch_32 |= 0x00080000;
> + pci_write_config_dword(chip->pdev, O2_SD_MISC_CTRL4, scratch_32);
> +}
> +EXPORT_SYMBOL_GPL(sdhci_pci_o2_fujin2_pci_init);
> +
> +int sdhci_pci_o2_probe_slot(struct sdhci_pci_slot *slot)
> +{
> + struct sdhci_pci_chip *chip;
> + struct sdhci_host *host;
> + u32 reg;
> +
> + chip = slot->chip;
> + host = slot->host;
> + switch (chip->pdev->device) {
> + case PCI_DEVICE_ID_O2_SDS0:
> + case PCI_DEVICE_ID_O2_SEABIRD0:
> + case PCI_DEVICE_ID_O2_SEABIRD1:
> + case PCI_DEVICE_ID_O2_SDS1:
> + case PCI_DEVICE_ID_O2_FUJIN2:
> + reg = sdhci_readl(host, O2_SD_VENDOR_SETTING);
> + if (reg & 0x1)
> + host->quirks |= SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12;
> +
> + if (chip->pdev->device != PCI_DEVICE_ID_O2_FUJIN2)
> + break;
> + /* set dll watch dog timer */
> + reg = sdhci_readl(host, O2_SD_VENDOR_SETTING2);
> + reg |= (1 << 12);
> + sdhci_writel(host, reg, O2_SD_VENDOR_SETTING2);
> +
> + break;
> + default:
> + break;
> + }
> +
> + return 0;
> +}
> +EXPORT_SYMBOL_GPL(sdhci_pci_o2_probe_slot);
> +
> +int sdhci_pci_o2_probe(struct sdhci_pci_chip *chip)
> +{
> + int ret;
> + u8 scratch;
> + u32 scratch_32;
> +
> + switch (chip->pdev->device) {
> + case PCI_DEVICE_ID_O2_8220:
> + case PCI_DEVICE_ID_O2_8221:
> + case PCI_DEVICE_ID_O2_8320:
> + case PCI_DEVICE_ID_O2_8321:
> + /* This extra setup is required due to broken ADMA. */
> + ret = pci_read_config_byte(chip->pdev,
> + O2_SD_LOCK_WP, &scratch);
> + if (ret)
> + return ret;
> + scratch &= 0x7f;
> + pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch);
> +
> + /* Set Multi 3 to VCC3V# */
> + pci_write_config_byte(chip->pdev, O2_SD_MULTI_VCC3V, 0x08);
> +
> + /* Disable CLK_REQ# support after media DET */
> + ret = pci_read_config_byte(chip->pdev,
> + O2_SD_CLKREQ, &scratch);
> + if (ret)
> + return ret;
> + scratch |= 0x20;
> + pci_write_config_byte(chip->pdev, O2_SD_CLKREQ, scratch);
> +
> + /* Choose capabilities, enable SDMA. We have to write 0x01
> + * to the capabilities register first to unlock it.
> + */
> + ret = pci_read_config_byte(chip->pdev, O2_SD_CAPS, &scratch);
> + if (ret)
> + return ret;
> + scratch |= 0x01;
> + pci_write_config_byte(chip->pdev, O2_SD_CAPS, scratch);
> + pci_write_config_byte(chip->pdev, O2_SD_CAPS, 0x73);
> +
> + /* Disable ADMA1/2 */
> + pci_write_config_byte(chip->pdev, O2_SD_ADMA1, 0x39);
> + pci_write_config_byte(chip->pdev, O2_SD_ADMA2, 0x08);
> +
> + /* Disable the infinite transfer mode */
> + ret = pci_read_config_byte(chip->pdev,
> + O2_SD_INF_MOD, &scratch);
> + if (ret)
> + return ret;
> + scratch |= 0x08;
> + pci_write_config_byte(chip->pdev, O2_SD_INF_MOD, scratch);
> +
> + /* Lock WP */
> + ret = pci_read_config_byte(chip->pdev,
> + O2_SD_LOCK_WP, &scratch);
> + if (ret)
> + return ret;
> + scratch |= 0x80;
> + pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch);
> + break;
> + case PCI_DEVICE_ID_O2_SDS0:
> + case PCI_DEVICE_ID_O2_SDS1:
> + case PCI_DEVICE_ID_O2_FUJIN2:
> + /* UnLock WP */
> + ret = pci_read_config_byte(chip->pdev,
> + O2_SD_LOCK_WP, &scratch);
> + if (ret)
> + return ret;
> +
> + scratch &= 0x7f;
> + pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch);
> +
> + /* Set timeout CLK */
> + ret = pci_read_config_dword(chip->pdev,
> + O2_SD_CLK_SETTING, &scratch_32);
> + if (ret)
> + return ret;
> +
> + scratch_32 &= ~(0xFF00);
> + scratch_32 |= 0x07E0C800;
> + pci_write_config_dword(chip->pdev,
> + O2_SD_CLK_SETTING, scratch_32);
> +
> + ret = pci_read_config_dword(chip->pdev,
> + O2_SD_CLKREQ, &scratch_32);
> + if (ret)
> + return ret;
> + scratch_32 |= 0x3;
> + pci_write_config_dword(chip->pdev, O2_SD_CLKREQ, scratch_32);
> +
> + ret = pci_read_config_dword(chip->pdev,
> + O2_SD_PLL_SETTING, &scratch_32);
> + if (ret)
> + return ret;
> +
> + scratch_32 &= ~(0x1F3F070E);
> + scratch_32 |= 0x18270106;
> + pci_write_config_dword(chip->pdev,
> + O2_SD_PLL_SETTING, scratch_32);
> +
> + /* Disable UHS1 funciton */
> + ret = pci_read_config_dword(chip->pdev,
> + O2_SD_CAP_REG2, &scratch_32);
> + if (ret)
> + return ret;
> + scratch_32 &= ~(0xE0);
> + pci_write_config_dword(chip->pdev,
> + O2_SD_CAP_REG2, scratch_32);
> +
> + if (chip->pdev->device == PCI_DEVICE_ID_O2_FUJIN2)
> + sdhci_pci_o2_fujin2_pci_init(chip);
> +
> + /* Lock WP */
> + ret = pci_read_config_byte(chip->pdev,
> + O2_SD_LOCK_WP, &scratch);
> + if (ret)
> + return ret;
> + scratch |= 0x80;
> + pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch);
> + break;
> + case PCI_DEVICE_ID_O2_SEABIRD0:
> + case PCI_DEVICE_ID_O2_SEABIRD1:
> + /* UnLock WP */
> + ret = pci_read_config_byte(chip->pdev,
> + O2_SD_LOCK_WP, &scratch);
> + if (ret)
> + return ret;
> +
> + scratch &= 0x7f;
> + pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch);
> +
> + ret = pci_read_config_dword(chip->pdev,
> + O2_SD_FUNC_REG0, &scratch_32);
> +
> + if ((scratch_32 & 0xff000000) == 0x01000000) {
> + scratch_32 &= 0x0000FFFF;
> + scratch_32 |= 0x1F340000;
> +
> + pci_write_config_dword(chip->pdev,
> + O2_SD_PLL_SETTING, scratch_32);
> + } else {
> + scratch_32 &= 0x0000FFFF;
> + scratch_32 |= 0x2c280000;
> +
> + pci_write_config_dword(chip->pdev,
> + O2_SD_PLL_SETTING, scratch_32);
> +
> + ret = pci_read_config_dword(chip->pdev,
> + O2_SD_FUNC_REG4,
> + &scratch_32);
> + scratch_32 |= (1 << 22);
> + pci_write_config_dword(chip->pdev,
> + O2_SD_FUNC_REG4, scratch_32);
> + }
> +
> + /* Lock WP */
> + ret = pci_read_config_byte(chip->pdev,
> + O2_SD_LOCK_WP, &scratch);
> + if (ret)
> + return ret;
> + scratch |= 0x80;
> + pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch);
> + break;
> + }
> +
> + return 0;
> +}
> +EXPORT_SYMBOL_GPL(sdhci_pci_o2_probe);
> +
> +int sdhci_pci_o2_resume(struct sdhci_pci_chip *chip)
> +{
> + sdhci_pci_o2_probe(chip);
> + return 0;
> +}
> +EXPORT_SYMBOL_GPL(sdhci_pci_o2_resume);
> diff --git a/drivers/mmc/host/sdhci-pci-o2micro.h b/drivers/mmc/host/sdhci-pci-o2micro.h
> new file mode 100644
> index 0000000..dbec4c9
> --- /dev/null
> +++ b/drivers/mmc/host/sdhci-pci-o2micro.h
> @@ -0,0 +1,72 @@
> +/*
> + * Copyright (C) 2013 BayHub Technology Ltd.
> + *
> + * Authors: Peter Guo <peter.guo at bayhubtech.com>
> + * Adam Lee <adam.lee at canonical.com>
> + *
> + * This software is licensed under the terms of the GNU General Public
> + * License version 2, as published by the Free Software Foundation, and
> + * may be copied, distributed, and modified under those terms.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + */
> +
> +#ifndef __SDHCI_PCI_O2MICRO_H
> +#define __SDHCI_PCI_O2MICRO_H
> +
> +#include "sdhci-pci.h"
> +
> +/*
> + * O2Micro device IDs
> + */
> +
> +#define PCI_DEVICE_ID_O2_SDS0 0x8420
> +#define PCI_DEVICE_ID_O2_SDS1 0x8421
> +#define PCI_DEVICE_ID_O2_FUJIN2 0x8520
> +#define PCI_DEVICE_ID_O2_SEABIRD0 0x8620
> +#define PCI_DEVICE_ID_O2_SEABIRD1 0x8621
> +
> +/*
> + * O2Micro device registers
> + */
> +
> +#define O2_SD_MISC_REG5 0x64
> +#define O2_SD_LD0_CTRL 0x68
> +#define O2_SD_DEV_CTRL 0x88
> +#define O2_SD_LOCK_WP 0xD3
> +#define O2_SD_TEST_REG 0xD4
> +#define O2_SD_FUNC_REG0 0xDC
> +#define O2_SD_MULTI_VCC3V 0xEE
> +#define O2_SD_CLKREQ 0xEC
> +#define O2_SD_CAPS 0xE0
> +#define O2_SD_ADMA1 0xE2
> +#define O2_SD_ADMA2 0xE7
> +#define O2_SD_INF_MOD 0xF1
> +#define O2_SD_MISC_CTRL4 0xFC
> +#define O2_SD_TUNING_CTRL 0x300
> +#define O2_SD_PLL_SETTING 0x304
> +#define O2_SD_CLK_SETTING 0x328
> +#define O2_SD_CAP_REG2 0x330
> +#define O2_SD_CAP_REG0 0x334
> +#define O2_SD_UHS1_CAP_SETTING 0x33C
> +#define O2_SD_DELAY_CTRL 0x350
> +#define O2_SD_UHS2_L1_CTRL 0x35C
> +#define O2_SD_FUNC_REG3 0x3E0
> +#define O2_SD_FUNC_REG4 0x3E4
> +
> +#define O2_SD_VENDOR_SETTING 0x110
> +#define O2_SD_VENDOR_SETTING2 0x1C8
> +
> +extern void sdhci_pci_o2_fujin2_pci_init(struct sdhci_pci_chip *chip);
> +
> +extern int sdhci_pci_o2_probe_slot(struct sdhci_pci_slot *slot);
> +
> +extern int sdhci_pci_o2_probe(struct sdhci_pci_chip *chip);
> +
> +extern int sdhci_pci_o2_resume(struct sdhci_pci_chip *chip);
> +
> +#endif /* __SDHCI_PCI_O2MICRO_H */
> diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c
> index da54529..6e62f5e 100644
> --- a/drivers/mmc/host/sdhci-pci.c
> +++ b/drivers/mmc/host/sdhci-pci.c
> @@ -28,6 +28,7 @@
>
> #include "sdhci.h"
> #include "sdhci-pci.h"
> +#include "sdhci-pci-o2micro.h"
>
> /*****************************************************************************\
> * *
> @@ -299,65 +300,6 @@ static const struct sdhci_pci_fixes sdhci_intel_byt_sd = {
> #define O2_SD_ADMA2 0xE7
> #define O2_SD_INF_MOD 0xF1
>
> -static int o2_probe(struct sdhci_pci_chip *chip)
> -{
> - int ret;
> - u8 scratch;
> -
> - switch (chip->pdev->device) {
> - case PCI_DEVICE_ID_O2_8220:
> - case PCI_DEVICE_ID_O2_8221:
> - case PCI_DEVICE_ID_O2_8320:
> - case PCI_DEVICE_ID_O2_8321:
> - /* This extra setup is required due to broken ADMA. */
> - ret = pci_read_config_byte(chip->pdev, O2_SD_LOCK_WP, &scratch);
> - if (ret)
> - return ret;
> - scratch &= 0x7f;
> - pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch);
> -
> - /* Set Multi 3 to VCC3V# */
> - pci_write_config_byte(chip->pdev, O2_SD_MULTI_VCC3V, 0x08);
> -
> - /* Disable CLK_REQ# support after media DET */
> - ret = pci_read_config_byte(chip->pdev, O2_SD_CLKREQ, &scratch);
> - if (ret)
> - return ret;
> - scratch |= 0x20;
> - pci_write_config_byte(chip->pdev, O2_SD_CLKREQ, scratch);
> -
> - /* Choose capabilities, enable SDMA. We have to write 0x01
> - * to the capabilities register first to unlock it.
> - */
> - ret = pci_read_config_byte(chip->pdev, O2_SD_CAPS, &scratch);
> - if (ret)
> - return ret;
> - scratch |= 0x01;
> - pci_write_config_byte(chip->pdev, O2_SD_CAPS, scratch);
> - pci_write_config_byte(chip->pdev, O2_SD_CAPS, 0x73);
> -
> - /* Disable ADMA1/2 */
> - pci_write_config_byte(chip->pdev, O2_SD_ADMA1, 0x39);
> - pci_write_config_byte(chip->pdev, O2_SD_ADMA2, 0x08);
> -
> - /* Disable the infinite transfer mode */
> - ret = pci_read_config_byte(chip->pdev, O2_SD_INF_MOD, &scratch);
> - if (ret)
> - return ret;
> - scratch |= 0x08;
> - pci_write_config_byte(chip->pdev, O2_SD_INF_MOD, scratch);
> -
> - /* Lock WP */
> - ret = pci_read_config_byte(chip->pdev, O2_SD_LOCK_WP, &scratch);
> - if (ret)
> - return ret;
> - scratch |= 0x80;
> - pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch);
> - }
> -
> - return 0;
> -}
> -
> static int jmicron_pmos(struct sdhci_pci_chip *chip, int on)
> {
> u8 scratch;
> @@ -548,7 +490,10 @@ static int jmicron_resume(struct sdhci_pci_chip *chip)
> }
>
> static const struct sdhci_pci_fixes sdhci_o2 = {
> - .probe = o2_probe,
> + .probe = sdhci_pci_o2_probe,
> + .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC,
> + .probe_slot = sdhci_pci_o2_probe_slot,
> + .resume = sdhci_pci_o2_resume,
> };
>
> static const struct sdhci_pci_fixes sdhci_jmicron = {
> @@ -913,6 +858,46 @@ static const struct pci_device_id pci_ids[] = {
> .driver_data = (kernel_ulong_t)&sdhci_o2,
> },
>
> + {
> + .vendor = PCI_VENDOR_ID_O2,
> + .device = PCI_DEVICE_ID_O2_FUJIN2,
> + .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_SDS0,
> + .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_SDS1,
> + .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_SEABIRD0,
> + .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_SEABIRD1,
> + .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)
> },
>
--
Brad Figg brad.figg at canonical.com http://www.canonical.com
More information about the kernel-team
mailing list