/* * Copyright (c) 2009 NVIDIA Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of the NVIDIA Corporation nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * */ /** * @file * NVIDIA APX ODM Kit:: * Implementation of the ODM Peripheral Discovery API * * @b Description: The peripheral connectivity database implementation. */ #include "nvcommon.h" #include "nvodm_query_gpio.h" #include "nvodm_modules.h" #include "nvodm_query_discovery.h" #include "nvodm_keylist_reserved.h" #include "tegra_devkit_custopt.h" #include "nvodm_query.h" #include "nvrm_drf.h" #include "subboards/nvodm_query_discovery_e888_addresses.h" #include "subboards/nvodm_query_discovery_e906_addresses.h" #include "subboards/nvodm_query_discovery_e911_addresses.h" #include "subboards/nvodm_query_discovery_e936_addresses.h" #include "subboards/nvodm_query_discovery_e951_addresses.h" #include "subboards/nvodm_query_discovery_e1109_addresses.h" #include "subboards/nvodm_query_discovery_e1116_addresses.h" #include "subboards/nvodm_query_discovery_e1120_addresses.h" #include "subboards/nvodm_query_discovery_e1129_addresses.h" //#include "subboards/nvodm_query_discovery_e1215_addresses.h" // enable with accelerometer bring-up (Voyager) static NvOdmPeripheralConnectivity s_Peripherals_Default[] = { #include "subboards/nvodm_query_discovery_e888_peripherals.h" #include "subboards/nvodm_query_discovery_e906_peripherals.h" #include "subboards/nvodm_query_discovery_e911_peripherals.h" #include "subboards/nvodm_query_discovery_e936_peripherals.h" #include "subboards/nvodm_query_discovery_e951_peripherals.h" #include "subboards/nvodm_query_discovery_e1109_peripherals.h" #include "subboards/nvodm_query_discovery_e1116_peripherals.h" #include "subboards/nvodm_query_discovery_e1120_peripherals.h" #include "subboards/nvodm_query_discovery_e1129_peripherals.h" //#include "subboards/nvodm_query_discovery_e1215_peripherals.h" // enable with accelerometer bring-up (Voyager) }; // Function to auto-detect boards with external CPU power supply // defined in nvodm_query.c extern NvBool NvOdmIsCpuExtSupply(void); #define NVODM_QUERY_BOARD_ID_UNKNOWN 0xFFFF #define NVODM_QUERY_MAX_PERIPHERALS 0x400 #define NVODM_QUERY_MAX_IO_ADDRESSES 0x400 #define NVODM_QUERY_MAX_BUS_SEGMENTS 4 // # of Bus Segments defined by I2C extender #define NVODM_QUERY_MAX_EEPROMS 8 // Maximum number of EEPROMs per bus segment #define NVODM_QUERY_ERASED_EEPROM_VALUE 0xFF #define PROCESSOR_BOARD_ID_I2C_ADDRESS ((0x56)<<1) #define PROCESSOR_BOARD_ID_I2C_SEGMENT (0x00) // The following are used to store entries read from EEPROMs at runtime. static NvOdmPeripheralConnectivity s_Peripherals[NVODM_QUERY_MAX_PERIPHERALS]; static NvOdmIoAddress s_Peripheral_IoAddresses[NVODM_QUERY_MAX_IO_ADDRESSES]; static NvOdmBoardInfo s_BoardModuleTable[NVODM_QUERY_MAX_BUS_SEGMENTS * NVODM_QUERY_MAX_EEPROMS]; #define NVODM_QUERY_I2C_CLOCK_SPEED 100 // kHz #define NVODM_QUERY_ENTRY_HEADER_SIZE 0x30 // Size of EERPOM "Entry Header" #define NVODM_QUERY_BOARD_HEADER_START 0x04 // Offset to Part Number in EERPOM #define NVODM_QUERY_I2C_EEPROM_ADDRESS 0xA0 // I2C device base address for EEPROM (7'h50) #define NVODM_QUERY_I2C_EXTENDER_ADDRESS 0x42 // I2C bus extender address (7'h21) #define NVODM_QUERY_PERIPH_CONN_STRUCT_COMPRESSED 10 // See EEPROM_format.txt #define NVODM_PERIPH_IO_ADDR_STRUCT_SZ_COMPRESSED 2 // See EEPROM_format.txt // The following board IDs are used to auto-configure the thermal rail (VOUT15) #define BOARD_ID_E1107 0x0B07 #define BOARD_ID_E1108 0x0B08 #define BOARD_ID_E1109 0x0B09 #define BOARD_ID_E1117 0x0B11 #define BOARD_ID_E951 0x0933 #define PROCESSOR_MODULE_REV_A 0 // A list of the Whistler processor boards static NvU32 gs_WhistlerProcessorBoards[] = { BOARD_ID_E1107, BOARD_ID_E1108, BOARD_ID_E1109 }; // A list of Whistler DDR2 processor boards static NvU32 s_WhistlerDDR2Boards[] = { BOARD_ID_E1107, BOARD_ID_E1109, BOARD_ID_E1117 }; static NvOdmI2cStatus NvOdmPeripheralI2cRead8( NvOdmServicesI2cHandle hOdmI2c, NvU8 I2cAddr, NvU8 Offset, NvU8 *pData) { NvU8 ReadBuffer[1]; NvOdmI2cStatus Error; NvOdmI2cTransactionInfo TransactionInfo; ReadBuffer[0] = Offset; TransactionInfo.Address = I2cAddr; TransactionInfo.Buf = ReadBuffer; TransactionInfo.Flags = NVODM_I2C_IS_WRITE; TransactionInfo.NumBytes = 1; Error = NvOdmI2cTransaction( hOdmI2c, &TransactionInfo, 1, NVODM_QUERY_I2C_CLOCK_SPEED, NV_WAIT_INFINITE); if (Error != NvOdmI2cStatus_Success) { return Error; } NvOdmOsMemset(ReadBuffer, 0, sizeof(ReadBuffer)); TransactionInfo.Address = (I2cAddr | 0x1); TransactionInfo.Buf = ReadBuffer; TransactionInfo.Flags = 0; TransactionInfo.NumBytes = 1; // Read data from ROM at the specified offset Error = NvOdmI2cTransaction( hOdmI2c, &TransactionInfo, 1, NVODM_QUERY_I2C_CLOCK_SPEED, NV_WAIT_INFINITE); if (Error != NvOdmI2cStatus_Success) { return Error; } *pData = ReadBuffer[0]; return Error; } static NvBool NvOdmPeripheralSetBusSegment( NvOdmServicesI2cHandle hOdmI2c, NvU16 BusSegment) { NvU8 WriteBuffer[2]; NvOdmI2cStatus Error; NvOdmI2cTransactionInfo TransactionInfo; NvU8 Data; Data = (NvU8)(BusSegment & 0xF); WriteBuffer[0] = 0x03; // Register (0x03) WriteBuffer[1] = 0x00; // Data TransactionInfo.Address = NVODM_QUERY_I2C_EXTENDER_ADDRESS; TransactionInfo.Buf = WriteBuffer; TransactionInfo.Flags = NVODM_I2C_IS_WRITE; TransactionInfo.NumBytes = 2; Error = NvOdmI2cTransaction( hOdmI2c, &TransactionInfo, 1, NVODM_QUERY_I2C_CLOCK_SPEED, NV_WAIT_INFINITE); if (Error != NvOdmI2cStatus_Success) { return NV_FALSE; } WriteBuffer[0] = 0x01; // Register (0x01) WriteBuffer[1] = Data; // Data (bus segment 0 thru 3) Error = NvOdmI2cTransaction( hOdmI2c, &TransactionInfo, 1, NVODM_QUERY_I2C_CLOCK_SPEED, NV_WAIT_INFINITE); if (Error != NvOdmI2cStatus_Success) { return NV_FALSE; } return NV_TRUE; } static NvBool NvOdmPeripheralReadNumPeripherals( NvOdmServicesI2cHandle hOdmI2c, NvU8 EepromInst, NvU8 *pNumModulePeripherals) { NvOdmI2cStatus Error; NvU8 I2cAddr, Offset; // EepromInst*2, since 7-bit addressing I2cAddr = NVODM_QUERY_I2C_EEPROM_ADDRESS + (EepromInst << 1); /** * Offset to numPeripherals in NvOdmPeripheralConnectivity Structure. * It's the first parameter after the "Entry Header." */ Offset = NVODM_QUERY_ENTRY_HEADER_SIZE; Error = NvOdmPeripheralI2cRead8( hOdmI2c, I2cAddr, Offset, pNumModulePeripherals); if (Error != NvOdmI2cStatus_Success) { return NV_FALSE; } return NV_TRUE; } static NvBool NvOdmPeripheralReadPeripheral( NvOdmServicesI2cHandle hOdmI2c, NvU8 EepromInst, NvU8 Peripheral, NvU64 *pGuid, NvU8 *pEepromAddressListOffset, NvU32 *pNumAddress, NvOdmPeripheralClass *pClass) { NvOdmI2cStatus Error; NvU32 i; NvU8 ConnMemberIndex=0; // Offset to members in NvOdmPeripheralConnectivity NvU8 I2cAddr, Offset; NvU8 ReadBuffer[NVODM_QUERY_PERIPH_CONN_STRUCT_COMPRESSED]; NvU8 NumAddrAndClass; // EepromInst*2, since 7-bit addressing I2cAddr = NVODM_QUERY_I2C_EEPROM_ADDRESS + (EepromInst << 1); /** * Calculate offset to pGuid in NvOdmPeripheralConnectivity Structure * * Offset = sizeof(eeprom Entry Header) + * sizeof(NvOdmPeripheralConnectivity)*peripheral + * pGuid offset <-- First field, so this is 0 */ Offset = NVODM_QUERY_ENTRY_HEADER_SIZE + sizeof(NvOdmPeripheralConnectivity)*Peripheral; for (i=0; i> 3) & 0x0000001F); *pClass = (NvOdmPeripheralClass)(NumAddrAndClass & 0x00000007); return NV_TRUE; } static NvBool NvOdmPeripheralReadIoAddressData( NvOdmServicesI2cHandle hOdmI2c, NvU8 EepromInst, NvU8 EepromAddressListOffset, NvOdmIoAddress *pIoAddressEntry) { NvOdmI2cStatus Error; NvU32 i; NvU8 I2cAddr; NvU8 ReadBuffer[NVODM_PERIPH_IO_ADDR_STRUCT_SZ_COMPRESSED]; NvU16 CompressedIoAddressEntry; // EepromInst*2, since 7-bit addressing I2cAddr = NVODM_QUERY_I2C_EEPROM_ADDRESS + (EepromInst << 1); for (i=0; iInterface = (NvOdmIoModule)((CompressedIoAddressEntry >> 11) & 0x1F); if (pIoAddressEntry->Interface != NvOdmIoModule_Gpio) { pIoAddressEntry->Instance = (NvU32)((CompressedIoAddressEntry >> 7) & 0xF); pIoAddressEntry->Address = (NvU32)(CompressedIoAddressEntry & 0x7F); } else { pIoAddressEntry->Address = (NvU32)((CompressedIoAddressEntry >> 6) & 0x3F); pIoAddressEntry->Instance = (NvU32)(CompressedIoAddressEntry & 0x3F); } return NV_TRUE; } static NvBool NvOdmPeripheralGetEntries(NvU32 *pNum) { NvBool RetVal; NvBool IsMatch = NV_FALSE; NvOdmServicesI2cHandle hOdmI2c = NULL; NvU8 BusSegment, EepromInst; // Peripheral counters NvU8 NumPeripherals = 0; NvU8 CurrentPeripheral = 0; NvU32 TotalPeripherals = 0; NvU32 StaticPeripherals; NvU32 CurrentIoAddressNum = 0; NvU32 TotalIoAddressEntries = 0; NvU32 i,j; NvU8 EepromAddressListOffset; if (!pNum) { return NV_FALSE; } // Auto-detect -- Read I2C-EEPROMs on each sub-board hOdmI2c = NvOdmI2cOpen(NvOdmIoModule_I2c_Pmu, 0); if (!hOdmI2c) return NV_FALSE; for (BusSegment=0; BusSegment < NVODM_QUERY_MAX_BUS_SEGMENTS; BusSegment++) { RetVal = NvOdmPeripheralSetBusSegment(hOdmI2c, BusSegment); if (RetVal == NV_FALSE) { /** * Bus segment not found. Set BusSegment to MAX and try reading * any ID EEPROMS which might be available without the bus * expander. */ BusSegment = NVODM_QUERY_MAX_BUS_SEGMENTS; } for (EepromInst=0; EepromInst < NVODM_QUERY_MAX_EEPROMS; EepromInst++) { RetVal = NvOdmPeripheralReadNumPeripherals( hOdmI2c, EepromInst, &NumPeripherals); if ( (RetVal == NV_TRUE) && (NumPeripherals != NVODM_QUERY_ERASED_EEPROM_VALUE) ) { if (NumPeripherals > 0) { if ((NumPeripherals + TotalPeripherals) > NVODM_QUERY_MAX_PERIPHERALS) { NV_ASSERT( !"ERROR: s_Peripherals[] is too small to accommodate entries!" ); // Break out of loop and use static/default configuration break; } for (CurrentPeripheral=0; \ CurrentPeripheral < NumPeripherals; \ CurrentPeripheral++) { RetVal = NvOdmPeripheralReadPeripheral( hOdmI2c, EepromInst, CurrentPeripheral, &s_Peripherals[TotalPeripherals+CurrentPeripheral].Guid, &EepromAddressListOffset, &s_Peripherals[TotalPeripherals+CurrentPeripheral].NumAddress, &s_Peripherals[TotalPeripherals+CurrentPeripheral].Class); if (RetVal == NV_FALSE) { NV_ASSERT(!"Unable to read EEPROM peripheral entry!"); break; // Go to next EEPROM } else // Process peripheral entry { /** * Process NvOdmIoAddress arrays -- * * These are separate data structures. The addressList value * read from the EEPROM (EepromAddressListOffset) represents * an offset address within the I2C-EEPROM. This offset value * identifies where to find the first instance of the * NvOdmIoAddress data. * * The total number of NvOdmIoAddress entries is identified * by the numAddress variable following the addressList entry * in EEPROM. * * Once the offset and number of entries are determined (from * above NvOdmPeripheralReadPeripheral function call), a loop * fills in entries within the fixed storage area * (e.g., s_Peripheral_IoAddresses) and the actual * addressList pointer is assigned a value that corresponds * to the first entry of the current class within this array. * In other words, there might be prior entries in the * s_Peripheral_IoAddresses array, but the first entry * corresponding to the current class might be the third * element in this array. Therefore, the actual addressList * pointer for the current NvOdmPeripheralConnectivity.addressList * parameter would be the address of the third entry, which is * &s_Peripheral_IoAddresses[2] in this example. */ // Read all of the entries and save them in s_Peripheral_IoAddresses for (CurrentIoAddressNum=0; \ CurrentIoAddressNum < s_Peripherals[TotalPeripherals+CurrentPeripheral].NumAddress; \ CurrentIoAddressNum++) { if (TotalIoAddressEntries > NVODM_QUERY_MAX_IO_ADDRESSES) { NV_ASSERT( !"ERROR: s_Peripheral_IoAddresses[] is too small to accommodate entries!" ); // Cannot recover from this error. NvOdmI2cClose(hOdmI2c); return NV_FALSE; } RetVal = NvOdmPeripheralReadIoAddressData( hOdmI2c, EepromInst, EepromAddressListOffset, &s_Peripheral_IoAddresses[TotalIoAddressEntries+CurrentIoAddressNum]); if (RetVal == NV_FALSE) { NV_ASSERT(!"Unable to read EEPROM (IoAddresses)!"); // Cannot recover from this error. NvOdmI2cClose(hOdmI2c); return NV_FALSE; } else // Process IoAddresses entry { /** * Save the addressList pointer. This points to the first * IoAddresses entry of this class. Then update the overall * IoAddresses array counter (TotalIoAddressEntries). */ s_Peripherals[TotalPeripherals+CurrentPeripheral].AddressList = &s_Peripheral_IoAddresses[TotalIoAddressEntries]; TotalIoAddressEntries += CurrentIoAddressNum; // >-- End of NvOdmIoAddress array processing --< } } } } } TotalPeripherals += NumPeripherals; } } } // Done reading I2C-EEPROM; close it. NvOdmI2cClose(hOdmI2c); /** * Append static peripheral entries (if any) to dynamic list * read from EEPROMs (this list may also be empty), except for * duplicate GUIDs. The dynamic list takes precedence when * duplicate entries are found in the static list. */ StaticPeripherals = NV_ARRAY_SIZE(s_Peripherals_Default); for (i=0; iBoardID = s_BoardModuleTable[CurrentBoard].BoardID; pBoardInfo->SKU = s_BoardModuleTable[CurrentBoard].SKU; pBoardInfo->Fab = s_BoardModuleTable[CurrentBoard].Fab; pBoardInfo->Revision = s_BoardModuleTable[CurrentBoard].Revision; return NV_TRUE; } } } // Match not found pBoardInfo = NULL; return NV_FALSE; } // This will compare the peripheral GUID against a list of known-bad GUIDs // for certain development kit personalities, and return NV_TRUE if it is // known to be unsupported (filtered) on the current configuration static NvBool NvIsFilteredPeripheral(const NvOdmPeripheralConnectivity* pConnectivity) { NvOdmServicesKeyListHandle hKeyList; NvU32 CustOpt = 0; NvU32 Personality = 0; NvU32 opt = 0; NvU32 ril = 0; NvOdmIoModule OdmModule; const NvU32 *OdmConfigs=NULL; NvU32 NumOdmConfigs = 0; const NvOdmPeripheralConnectivity* pFilteredPeriph = pConnectivity; NvOdmBoardInfo BoardInfo; NvU32 i, TotalBoards; NvBool status = NV_FALSE; if((!pConnectivity) || (!pConnectivity->NumAddress)) return NV_TRUE; if (pConnectivity->Guid == NV_ODM_GUID('a','d','t','7','4','6','1',' ')) { /** * The following board detection is used to keep thermal rail * (VOUT15) disabled for certain board SKUs where the board ID * ROMs cannot be read when the thermal rail is enabled. */ TotalBoards = NV_ARRAY_SIZE(gs_WhistlerProcessorBoards); // Scan for processor boards for (i=0; iGuid == NV_ODM_GUID('b','l','u','t','o','o','t','h')) { /** * The following board detection is used to detect presence of Bluetooth Chip. * In case of whistler only ossibility is having E951 board. */ status = NvOdmPeripheralGetBoardInfo((BOARD_ID_E951), &BoardInfo); if(NV_TRUE == status) { return NV_FALSE; // BT module found; don't filter it. }else { return NV_TRUE; // BT module not found; filter the BT peripheral. } } hKeyList = NvOdmServicesKeyListOpen(); if (hKeyList) { CustOpt = NvOdmServicesGetKeyValue(hKeyList, NvOdmKeyListId_ReservedBctCustomerOption); NvOdmServicesKeyListClose(hKeyList); Personality = NV_DRF_VAL(TEGRA_DEVKIT, BCT_CUSTOPT, PERSONALITY, CustOpt); opt = NV_DRF_VAL(TEGRA_DEVKIT, BCT_CUSTOPT, DISPLAY_OPTION, CustOpt); ril = NV_DRF_VAL(TEGRA_DEVKIT, BCT_CUSTOPT, RIL, CustOpt); } if (pConnectivity->Guid == NV_ODM_GUID('e','m','p',' ','_','m','d','m')) { if (ril == TEGRA_DEVKIT_BCT_CUSTOPT_0_RIL_EMP_RAINBOW) { return NV_FALSE; // EMP RAINBOW supported - don't filter it } else { return NV_TRUE; // EMP RAINBOW not supported - filter it } } if (pConnectivity->Guid == NV_ODM_GUID('e','m','p',' ','M','5','7','0')) { if (ril == TEGRA_DEVKIT_BCT_CUSTOPT_0_RIL_EMP_RAINBOW_ULPI) { return NV_FALSE; // EMP RAINBOW ULPI supported - don't filter it } else { return NV_TRUE; // EMP RAINBOW ULPI not supported - filter it } } if (pConnectivity->Guid == NV_ODM_GUID('s','p','i',' ','_','i','p','c')) { if (ril == TEGRA_DEVKIT_BCT_CUSTOPT_0_RIL_IFX) { return NV_FALSE; // IFX supported - don't filter it } else { return NV_TRUE; // IFX not supported - filter it } } if (!Personality) Personality = TEGRA_DEVKIT_DEFAULT_PERSONALITY; OdmModule = pFilteredPeriph->AddressList[0].Interface; if(OdmModule != NvOdmIoModule_Gpio) NvOdmQueryPinMux(OdmModule, &OdmConfigs, &NumOdmConfigs); switch (OdmModule) { case NvOdmIoModule_Gpio: // Filter scroll wheel when trace is enabled if ( (pConnectivity->Guid == NV_ODM_GUID('s','c','r','o','l','w','h','l')) && ((Personality == TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_11) || (Personality == TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_15) || (Personality == TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_C1)) ) return NV_TRUE; else return NV_FALSE; default: return NV_FALSE; } } static const NvOdmPeripheralConnectivity* NvApGetAllPeripherals (NvU32 *pNum) { static NvBool s_AutoDetectDone = NV_FALSE; NvBool RetVal = NV_TRUE; static NvU32 s_TotalPeripherals; NvOdmBoardInfo BoardInfo; if (!pNum) return NULL; if (!s_AutoDetectDone) { /** * Read & cache the board ID info from the I2C-EEPROMs. This * is necessary because once Whistler's thermal power rail is * enabled, the ID ROMs cannot be read. NvApGetAllPeripherals() * is called before that rail is enabled. */ NvOdmPeripheralGetBoardInfo(NVODM_QUERY_BOARD_ID_UNKNOWN, &BoardInfo); RetVal = NvOdmPeripheralGetEntries(&s_TotalPeripherals); if (RetVal == NV_FALSE) { *pNum = 0; return NULL; } s_AutoDetectDone = NV_TRUE; } *pNum = s_TotalPeripherals; return (const NvOdmPeripheralConnectivity *)s_Peripherals; } // This implements a simple linear search across the entire set of currently- // connected peripherals to find the set of GUIDs that Match the search // criteria. More clever implementations are possible, but given the // relatively small search space (max dozens of peripherals) and the relative // infrequency of enumerating peripherals, this is the easiest implementation. const NvOdmPeripheralConnectivity * NvOdmPeripheralGetGuid(NvU64 SearchGuid) { const NvOdmPeripheralConnectivity *pAllPeripherals; NvU32 NumPeripherals; NvU32 i; pAllPeripherals = NvApGetAllPeripherals(&NumPeripherals); if (!pAllPeripherals || !NumPeripherals) return NULL; for (i=0; iNumAddress; i++) { j = offset; do { switch (pSearchAttrs[j]) { case NvOdmPeripheralSearch_IoModule: IsMatch = (pSearchVals[j] == (NvU32)(pPeriph->AddressList[i].Interface)); break; case NvOdmPeripheralSearch_Address: IsMatch = (pSearchVals[j] == pPeriph->AddressList[i].Address); break; case NvOdmPeripheralSearch_Instance: IsMatch = (pSearchVals[j] == pPeriph->AddressList[i].Instance); break; case NvOdmPeripheralSearch_PeripheralClass: default: NV_ASSERT(!"Bad Query!"); break; } j++; } while (IsMatch && jClass)); break; case NvOdmPeripheralSearch_IoModule: IsMatch = IsBusMatch(pPeriph, pSearchAttrs, pSearchVals, i, NumAttrs); break; case NvOdmPeripheralSearch_Address: case NvOdmPeripheralSearch_Instance: // In correctly-formed searches, these parameters will be parsed by // IsBusMatch, so we ignore them here. break; default: NV_ASSERT(!"Bad search attribute!"); break; } } return IsMatch; } NvU32 NvOdmPeripheralEnumerate( const NvOdmPeripheralSearch *pSearchAttrs, const NvU32 *pSearchVals, NvU32 NumAttrs, NvU64 *pGuidList, NvU32 NumGuids) { const NvOdmPeripheralConnectivity *pAllPeripherals; NvU32 NumPeripherals; NvU32 Matches; NvU32 i; pAllPeripherals = NvApGetAllPeripherals(&NumPeripherals); if (!pAllPeripherals || !NumPeripherals) { return 0; } if (!pSearchAttrs || !pSearchVals) { NumAttrs = 0; } for (i=0, Matches=0; i