From patchwork Sat Oct 20 21:44:34 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 192951 X-Patchwork-Delegate: sjg@chromium.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id BABA42C0082 for ; Sun, 21 Oct 2012 08:45:07 +1100 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id BCEEC4A36C; Sat, 20 Oct 2012 23:45:03 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Y9rDJ1re7vn4; Sat, 20 Oct 2012 23:45:02 +0200 (CEST) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 3A3FE4A371; Sat, 20 Oct 2012 23:45:00 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 0FC414A371 for ; Sat, 20 Oct 2012 23:44:58 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id fCiaG2lcSb+e for ; Sat, 20 Oct 2012 23:44:56 +0200 (CEST) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from mail-lb0-f202.google.com (mail-lb0-f202.google.com [209.85.217.202]) by theia.denx.de (Postfix) with ESMTPS id 9668E4A36C for ; Sat, 20 Oct 2012 23:44:54 +0200 (CEST) Received: by mail-lb0-f202.google.com with SMTP id l12so85919lbo.3 for ; Sat, 20 Oct 2012 14:44:54 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer:x-gm-message-state; bh=b/Th2UALj8BT5inBn0ST3hr089u21Eb5RdpxYH0nvVU=; b=SoNluLrjPeehFjhHBmh49Yus0L0kFtqtfFRVMsaXOZbFbhnp8Z6HpLYL2Xe7EYv4UQ Lfy4hDvbopnjs6eSgn60QpMPXbP7BsN+vwcZw5yzzsGbrzQOhwtGBKa9+maq/QgBbSTV 0Oejk3dJ9aLLk6J7HFAk5AEnG9gSPmspbz4DpuzC+xi0f5CrP0QUF8YUt2h44512ctXu vpAhWvaCECUvQIBZPJeWWsucmuRKalYXJ99ypC0QBI12UqYAf71bxweh1wLxZuLUvG7t +1fq+GzmoanM7jOTYIj4oLzcPCOwiXrfGNF9TKMrxiT8tKxIiUJYV4sU74hd6y6y8+J9 h0uw== Received: by 10.180.101.9 with SMTP id fc9mr1584784wib.3.1350769494179; Sat, 20 Oct 2012 14:44:54 -0700 (PDT) Received: from hpza9.eem.corp.google.com ([74.125.121.33]) by gmr-mx.google.com with ESMTPS id b5si2469001wie.2.2012.10.20.14.44.54 (version=TLSv1/SSLv3 cipher=AES128-SHA); Sat, 20 Oct 2012 14:44:54 -0700 (PDT) Received: from kaka.mtv.corp.google.com (kaka.mtv.corp.google.com [172.22.73.79]) by hpza9.eem.corp.google.com (Postfix) with ESMTP id 775F25C0050; Sat, 20 Oct 2012 14:44:53 -0700 (PDT) Received: by kaka.mtv.corp.google.com (Postfix, from userid 121222) id C52DA160534; Sat, 20 Oct 2012 14:44:52 -0700 (PDT) From: Simon Glass To: U-Boot Mailing List Date: Sat, 20 Oct 2012 14:44:34 -0700 Message-Id: <1350769476-32163-1-git-send-email-sjg@chromium.org> X-Mailer: git-send-email 1.7.7.3 X-Gm-Message-State: ALoCoQk4hU3jdjo7E5gk73qzzP30q2rT+xwiS6sVE41zhH3yP0ivi0iwleapUBsiloE+4ULZX+VfWwhTMkma0bxkb0plV5IGr1MRYfZ7mBSVwtUhvMiUDOjDmDcTyfM247/l3SdmBl9gap5ngT+wD77HXSANaxFst1/TW+5XO+qAlrzOQ9DpSLfLWp3BocOhJ74XqKTtaj+4 Cc: Tom Rini , Bill Richardson Subject: [U-Boot] [PATCH 1/3] x86: gpio: Add GPIO driver for Intel ICH6 and later. X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.11 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de From: Bill Richardson Implement functions for Intel ICH6 and later. Only GPIOs 0-31 are handled by this code. Signed-off-by: Bill Richardson Signed-off-by: Simon Glass --- arch/x86/include/asm/gpio.h | 27 +++++ drivers/gpio/Makefile | 1 + drivers/gpio/intel_ich6_gpio.c | 242 ++++++++++++++++++++++++++++++++++++++++ include/pci.h | 123 ++++++++++++++++++++ 4 files changed, 393 insertions(+), 0 deletions(-) create mode 100644 arch/x86/include/asm/gpio.h create mode 100644 drivers/gpio/intel_ich6_gpio.c diff --git a/arch/x86/include/asm/gpio.h b/arch/x86/include/asm/gpio.h new file mode 100644 index 0000000..0a37a85 --- /dev/null +++ b/arch/x86/include/asm/gpio.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2012, Google Inc. All rights reserved. + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _X86_GPIO_H_ +#define _X86_GPIO_H_ + +#include + +#endif /* _X86_GPIO_H_ */ diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index d50ac3b..2d97b4f 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -26,6 +26,7 @@ include $(TOPDIR)/config.mk LIB := $(obj)libgpio.o COBJS-$(CONFIG_AT91_GPIO) += at91_gpio.o +COBJS-$(CONFIG_INTEL_ICH6_GPIO) += intel_ich6_gpio.o COBJS-$(CONFIG_KIRKWOOD_GPIO) += kw_gpio.o COBJS-$(CONFIG_MARVELL_GPIO) += mvgpio.o COBJS-$(CONFIG_MARVELL_MFP) += mvmfp.o diff --git a/drivers/gpio/intel_ich6_gpio.c b/drivers/gpio/intel_ich6_gpio.c new file mode 100644 index 0000000..1ccb641 --- /dev/null +++ b/drivers/gpio/intel_ich6_gpio.c @@ -0,0 +1,242 @@ +/* + * Copyright (c) 2012 The Chromium OS Authors. + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * This is a GPIO driver for Intel ICH6 and later. The x86 GPIOs are accessed + * through the PCI bus. Each PCI device has 256 bytes of configuration space, + * consisting of a standard header and a device-specific set of registers. PCI + * bus 0, device 31, function 0 gives us access to the chipset GPIOs (among + * other things). Within the PCI configuration space, the GPIOBASE register + * tells us where in the device's I/O region we can find more registers to + * actually access the GPIOs. + * + * PCI bus/device/function 0:1f:0 => PCI config registers + * PCI config register "GPIOBASE" + * PCI I/O space + [GPIOBASE] => start of GPIO registers + * GPIO registers => gpio pin function, direction, value + */ + +#include +#include +#include +#include + +/* Where in config space is the register that points to the GPIO registers? */ +#define PCI_CFG_GPIOBASE 0x48 + +/* + * There are often more than 32 GPIOs, depending on the ICH version. + * For now, we just support bank 0 because it's the same for all. + */ +#define GPIO_MAX 31 + +/* Within the I/O space, where are the registers to control the GPIOs? */ +#define OFS_GPIO_USE_SEL 0x00 +#define OFS_GPIO_IO_SEL 0x04 +#define OFS_GP_LVL 0x0C + +static pci_dev_t dev; /* handle for 0:1f:0 */ +static u32 gpiobase; /* offset into I/O space */ +static int found_it_once; /* valid GPIO device? */ +static int in_use[GPIO_MAX]; /* "lock" for access to pins */ + +static int gpio_init(void) +{ + u8 tmpbyte; + u16 tmpword; + u32 tmplong; + + /* Have we already done this? */ + if (found_it_once) + return 0; + + /* Where should it be? */ + dev = PCI_BDF(0, 0x1f, 0); + + /* Is the device present? */ + pci_read_config_word(dev, PCI_VENDOR_ID, &tmpword); + if (tmpword != PCI_VENDOR_ID_INTEL) { + debug("%s: wrong VendorID\n", __func__); + return -1; + } + /* + * We'd like to check the Device ID too, but pretty much any + * value is either a) correct with slight differences, or b) + * correct but undocumented. We'll have to check other things + * instead... + */ + + /* I/O should already be enabled (it's a RO bit). */ + pci_read_config_word(dev, PCI_COMMAND, &tmpword); + if (!(tmpword & PCI_COMMAND_IO)) { + debug("%s: device IO not enabled\n", __func__); + return -1; + } + + /* Header Type must be normal (bits 6-0 only; see spec.) */ + pci_read_config_byte(dev, PCI_HEADER_TYPE, &tmpbyte); + if ((tmpbyte & 0x7f) != PCI_HEADER_TYPE_NORMAL) { + debug("%s: invalid Header type\n", __func__); + return -1; + } + + /* Base Class must be a bridge device */ + pci_read_config_byte(dev, PCI_CLASS_CODE, &tmpbyte); + if (tmpbyte != PCI_CLASS_CODE_BRIDGE) { + debug("%s: invalid class\n", __func__); + return -1; + } + /* Sub Class must be ISA */ + pci_read_config_byte(dev, PCI_CLASS_SUB_CODE, &tmpbyte); + if (tmpbyte != PCI_CLASS_SUB_CODE_BRIDGE_ISA) { + debug("%s: invalid subclass\n", __func__); + return -1; + } + + /* Programming Interface must be 0x00 (no others exist) */ + pci_read_config_byte(dev, PCI_CLASS_PROG, &tmpbyte); + if (tmpbyte != 0x00) { + debug("%s: invalid interface type\n", __func__); + return -1; + } + + /* + * GPIOBASE moved to its current offset with ICH6, but prior to + * that it was unused (or undocumented). Check that it looks + * okay: not all ones or zeros, and mapped to I/O space (bit 0). + */ + pci_read_config_dword(dev, PCI_CFG_GPIOBASE, &tmplong); + if (tmplong == 0x00000000 || tmplong == 0xffffffff || + !(tmplong & 0x00000001)) { + debug("%s: unexpected GPIOBASE value\n", __func__); + return -1; + } + + /* + * Okay, I guess we're looking at the right device. The actual + * GPIO registers are in the PCI device's I/O space, starting + * at the offset that we just read. Bit 0 indicates that it's + * an I/O address, not a memory address, so mask that off. + */ + gpiobase = tmplong & 0xfffffffe; + + /* Finally. These are the droids we're looking for. */ + found_it_once = 1; + return 0; +} + +int gpio_request(unsigned gpio, const char *label /* UNUSED */) +{ + u32 tmplong; + + /* Are we doing it wrong? */ + if (gpio > GPIO_MAX || in_use[gpio]) { + debug("%s: gpio unavailable\n", __func__); + return -1; + } + + /* Is the hardware ready? */ + if (gpio_init()) { + debug("%s: gpio_init failed\n", __func__); + return -1; + } + + /* + * Make sure that the GPIO pin we want isn't already in use for some + * built-in hardware function. We have to check this for every + * requested pin. + */ + tmplong = inl(gpiobase + OFS_GPIO_USE_SEL); + if (!(tmplong & (1UL << gpio))) { + debug("%s: reserved for internal use\n", __func__); + return -1; + } + + in_use[gpio] = 1; + return 0; +} + +int gpio_free(unsigned gpio) +{ + if (gpio > GPIO_MAX || !in_use[gpio]) { + debug("%s: gpio unavailable\n", __func__); + return -1; + } + in_use[gpio] = 0; + return 0; +} + +int gpio_direction_input(unsigned gpio) +{ + u32 tmplong; + + if (gpio > GPIO_MAX || !in_use[gpio]) { + debug("%s: gpio unavailable\n", __func__); + return -1; + } + tmplong = inl(gpiobase + OFS_GPIO_IO_SEL); + tmplong |= (1UL << gpio); + outl(gpiobase + OFS_GPIO_IO_SEL, tmplong); + return 0; +} + +int gpio_direction_output(unsigned gpio, int value) +{ + u32 tmplong; + + if (gpio > GPIO_MAX || !in_use[gpio]) { + debug("%s: gpio unavailable\n", __func__); + return -1; + } + tmplong = inl(gpiobase + OFS_GPIO_IO_SEL); + tmplong &= ~(1UL << gpio); + outl(gpiobase + OFS_GPIO_IO_SEL, tmplong); + return 0; +} + +int gpio_get_value(unsigned gpio) +{ + u32 tmplong; + + if (gpio > GPIO_MAX || !in_use[gpio]) { + debug("%s: gpio unavailable\n", __func__); + return -1; + } + tmplong = inl(gpiobase + OFS_GP_LVL); + return (tmplong & (1UL << gpio)) ? 1 : 0; +} + +int gpio_set_value(unsigned gpio, int value) +{ + u32 tmplong; + + if (gpio > GPIO_MAX || !in_use[gpio]) { + debug("%s: gpio unavailable\n", __func__); + return -1; + } + tmplong = inl(gpiobase + OFS_GP_LVL); + if (value) + tmplong |= (1UL << gpio); + else + tmplong &= ~(1UL << gpio); + outl(gpiobase + OFS_GP_LVL, tmplong); + return 0; +} diff --git a/include/pci.h b/include/pci.h index eba122f..15f583f 100644 --- a/include/pci.h +++ b/include/pci.h @@ -67,7 +67,130 @@ #define PCI_CLASS_PROG 0x09 /* Reg. Level Programming Interface */ #define PCI_CLASS_DEVICE 0x0a /* Device class */ #define PCI_CLASS_CODE 0x0b /* Device class code */ +#define PCI_CLASS_CODE_TOO_OLD 0x00 +#define PCI_CLASS_CODE_STORAGE 0x01 +#define PCI_CLASS_CODE_NETWORK 0x02 +#define PCI_CLASS_CODE_DISPLAY 0x03 +#define PCI_CLASS_CODE_MULTIMEDIA 0x04 +#define PCI_CLASS_CODE_MEMORY 0x05 +#define PCI_CLASS_CODE_BRIDGE 0x06 +#define PCI_CLASS_CODE_COMM 0x07 +#define PCI_CLASS_CODE_PERIPHERAL 0x08 +#define PCI_CLASS_CODE_INPUT 0x09 +#define PCI_CLASS_CODE_DOCKING 0x0A +#define PCI_CLASS_CODE_PROCESSOR 0x0B +#define PCI_CLASS_CODE_SERIAL 0x0C +#define PCI_CLASS_CODE_WIRELESS 0x0D +#define PCI_CLASS_CODE_I2O 0x0E +#define PCI_CLASS_CODE_SATELLITE 0x0F +#define PCI_CLASS_CODE_CRYPTO 0x10 +#define PCI_CLASS_CODE_DATA 0x11 +/* Base Class 0x12 - 0xFE is reserved */ +#define PCI_CLASS_CODE_OTHER 0xFF + #define PCI_CLASS_SUB_CODE 0x0a /* Device sub-class code */ +#define PCI_CLASS_SUB_CODE_TOO_OLD_NOTVGA 0x00 +#define PCI_CLASS_SUB_CODE_TOO_OLD_VGA 0x01 +#define PCI_CLASS_SUB_CODE_STORAGE_SCSI 0x00 +#define PCI_CLASS_SUB_CODE_STORAGE_IDE 0x01 +#define PCI_CLASS_SUB_CODE_STORAGE_FLOPPY 0x02 +#define PCI_CLASS_SUB_CODE_STORAGE_IPIBUS 0x03 +#define PCI_CLASS_SUB_CODE_STORAGE_RAID 0x04 +#define PCI_CLASS_SUB_CODE_STORAGE_ATA 0x05 +#define PCI_CLASS_SUB_CODE_STORAGE_SATA 0x06 +#define PCI_CLASS_SUB_CODE_STORAGE_SAS 0x07 +#define PCI_CLASS_SUB_CODE_STORAGE_OTHER 0x80 +#define PCI_CLASS_SUB_CODE_NETWORK_ETHERNET 0x00 +#define PCI_CLASS_SUB_CODE_NETWORK_TOKENRING 0x01 +#define PCI_CLASS_SUB_CODE_NETWORK_FDDI 0x02 +#define PCI_CLASS_SUB_CODE_NETWORK_ATM 0x03 +#define PCI_CLASS_SUB_CODE_NETWORK_ISDN 0x04 +#define PCI_CLASS_SUB_CODE_NETWORK_WORLDFIP 0x05 +#define PCI_CLASS_SUB_CODE_NETWORK_PICMG 0x06 +#define PCI_CLASS_SUB_CODE_NETWORK_OTHER 0x80 +#define PCI_CLASS_SUB_CODE_DISPLAY_VGA 0x00 +#define PCI_CLASS_SUB_CODE_DISPLAY_XGA 0x01 +#define PCI_CLASS_SUB_CODE_DISPLAY_3D 0x02 +#define PCI_CLASS_SUB_CODE_DISPLAY_OTHER 0x80 +#define PCI_CLASS_SUB_CODE_MULTIMEDIA_VIDEO 0x00 +#define PCI_CLASS_SUB_CODE_MULTIMEDIA_AUDIO 0x01 +#define PCI_CLASS_SUB_CODE_MULTIMEDIA_PHONE 0x02 +#define PCI_CLASS_SUB_CODE_MULTIMEDIA_OTHER 0x80 +#define PCI_CLASS_SUB_CODE_MEMORY_RAM 0x00 +#define PCI_CLASS_SUB_CODE_MEMORY_FLASH 0x01 +#define PCI_CLASS_SUB_CODE_MEMORY_OTHER 0x80 +#define PCI_CLASS_SUB_CODE_BRIDGE_HOST 0x00 +#define PCI_CLASS_SUB_CODE_BRIDGE_ISA 0x01 +#define PCI_CLASS_SUB_CODE_BRIDGE_EISA 0x02 +#define PCI_CLASS_SUB_CODE_BRIDGE_MCA 0x03 +#define PCI_CLASS_SUB_CODE_BRIDGE_PCI 0x04 +#define PCI_CLASS_SUB_CODE_BRIDGE_PCMCIA 0x05 +#define PCI_CLASS_SUB_CODE_BRIDGE_NUBUS 0x06 +#define PCI_CLASS_SUB_CODE_BRIDGE_CARDBUS 0x07 +#define PCI_CLASS_SUB_CODE_BRIDGE_RACEWAY 0x08 +#define PCI_CLASS_SUB_CODE_BRIDGE_SEMI_PCI 0x09 +#define PCI_CLASS_SUB_CODE_BRIDGE_INFINIBAND 0x0A +#define PCI_CLASS_SUB_CODE_BRIDGE_OTHER 0x80 +#define PCI_CLASS_SUB_CODE_COMM_SERIAL 0x00 +#define PCI_CLASS_SUB_CODE_COMM_PARALLEL 0x01 +#define PCI_CLASS_SUB_CODE_COMM_MULTIPORT 0x02 +#define PCI_CLASS_SUB_CODE_COMM_MODEM 0x03 +#define PCI_CLASS_SUB_CODE_COMM_GPIB 0x04 +#define PCI_CLASS_SUB_CODE_COMM_SMARTCARD 0x05 +#define PCI_CLASS_SUB_CODE_COMM_OTHER 0x80 +#define PCI_CLASS_SUB_CODE_PERIPHERAL_PIC 0x00 +#define PCI_CLASS_SUB_CODE_PERIPHERAL_DMA 0x01 +#define PCI_CLASS_SUB_CODE_PERIPHERAL_TIMER 0x02 +#define PCI_CLASS_SUB_CODE_PERIPHERAL_RTC 0x03 +#define PCI_CLASS_SUB_CODE_PERIPHERAL_HOTPLUG 0x04 +#define PCI_CLASS_SUB_CODE_PERIPHERAL_SD 0x05 +#define PCI_CLASS_SUB_CODE_PERIPHERAL_OTHER 0x80 +#define PCI_CLASS_SUB_CODE_INPUT_KEYBOARD 0x00 +#define PCI_CLASS_SUB_CODE_INPUT_DIGITIZER 0x01 +#define PCI_CLASS_SUB_CODE_INPUT_MOUSE 0x02 +#define PCI_CLASS_SUB_CODE_INPUT_SCANNER 0x03 +#define PCI_CLASS_SUB_CODE_INPUT_GAMEPORT 0x04 +#define PCI_CLASS_SUB_CODE_INPUT_OTHER 0x80 +#define PCI_CLASS_SUB_CODE_DOCKING_GENERIC 0x00 +#define PCI_CLASS_SUB_CODE_DOCKING_OTHER 0x80 +#define PCI_CLASS_SUB_CODE_PROCESSOR_386 0x00 +#define PCI_CLASS_SUB_CODE_PROCESSOR_486 0x01 +#define PCI_CLASS_SUB_CODE_PROCESSOR_PENTIUM 0x02 +#define PCI_CLASS_SUB_CODE_PROCESSOR_ALPHA 0x10 +#define PCI_CLASS_SUB_CODE_PROCESSOR_POWERPC 0x20 +#define PCI_CLASS_SUB_CODE_PROCESSOR_MIPS 0x30 +#define PCI_CLASS_SUB_CODE_PROCESSOR_COPROC 0x40 +#define PCI_CLASS_SUB_CODE_SERIAL_1394 0x00 +#define PCI_CLASS_SUB_CODE_SERIAL_ACCESSBUS 0x01 +#define PCI_CLASS_SUB_CODE_SERIAL_SSA 0x02 +#define PCI_CLASS_SUB_CODE_SERIAL_USB 0x03 +#define PCI_CLASS_SUB_CODE_SERIAL_FIBRECHAN 0x04 +#define PCI_CLASS_SUB_CODE_SERIAL_SMBUS 0x05 +#define PCI_CLASS_SUB_CODE_SERIAL_INFINIBAND 0x06 +#define PCI_CLASS_SUB_CODE_SERIAL_IPMI 0x07 +#define PCI_CLASS_SUB_CODE_SERIAL_SERCOS 0x08 +#define PCI_CLASS_SUB_CODE_SERIAL_CANBUS 0x09 +#define PCI_CLASS_SUB_CODE_WIRELESS_IRDA 0x00 +#define PCI_CLASS_SUB_CODE_WIRELESS_IR 0x01 +#define PCI_CLASS_SUB_CODE_WIRELESS_RF 0x10 +#define PCI_CLASS_SUB_CODE_WIRELESS_BLUETOOTH 0x11 +#define PCI_CLASS_SUB_CODE_WIRELESS_BROADBAND 0x12 +#define PCI_CLASS_SUB_CODE_WIRELESS_80211A 0x20 +#define PCI_CLASS_SUB_CODE_WIRELESS_80211B 0x21 +#define PCI_CLASS_SUB_CODE_WIRELESS_OTHER 0x80 +#define PCI_CLASS_SUB_CODE_I2O_V1_0 0x00 +#define PCI_CLASS_SUB_CODE_SATELLITE_TV 0x01 +#define PCI_CLASS_SUB_CODE_SATELLITE_AUDIO 0x02 +#define PCI_CLASS_SUB_CODE_SATELLITE_VOICE 0x03 +#define PCI_CLASS_SUB_CODE_SATELLITE_DATA 0x04 +#define PCI_CLASS_SUB_CODE_CRYPTO_NETWORK 0x00 +#define PCI_CLASS_SUB_CODE_CRYPTO_ENTERTAINMENT 0x10 +#define PCI_CLASS_SUB_CODE_CRYPTO_OTHER 0x80 +#define PCI_CLASS_SUB_CODE_DATA_DPIO 0x00 +#define PCI_CLASS_SUB_CODE_DATA_PERFCNTR 0x01 +#define PCI_CLASS_SUB_CODE_DATA_COMMSYNC 0x10 +#define PCI_CLASS_SUB_CODE_DATA_MGMT 0x20 +#define PCI_CLASS_SUB_CODE_DATA_OTHER 0x80 #define PCI_CACHE_LINE_SIZE 0x0c /* 8 bits */ #define PCI_LATENCY_TIMER 0x0d /* 8 bits */