void Adt7461ParameterCapsGet( NvOdmTmonDeviceHandle hTmon, NvOdmTmonZoneID ZoneId, NvOdmTmonConfigParam ParamId, NvOdmTmonParameterCaps* pCaps) { NvBool ExtRange; ADT7461PrivData* pPrivData; const ADT7461ChannelInfo* pChannel; NV_ASSERT(hTmon && hTmon->pPrivate && pCaps); pPrivData = hTmon->pPrivate; #if PRE_ER_GMT_THERMALSENSOR ExtRange = 0; /* not support ADT thermal sensor*/ #else ExtRange = ((pPrivData->ShadowConfig & ADT7461ConfigBits_ExtendedRange) != 0); #endif pChannel = &pPrivData->pDeviceInfo->Channels[( pPrivData->ConnectivityMap[ZoneId])]; switch (ParamId) { case NvOdmTmonConfigParam_IntrLimitHigh: case NvOdmTmonConfigParam_IntrLimitLow: pCaps->OdmProtected = pChannel->ChannelPolicy.IntrLimitsOdmProtected; break; case NvOdmTmonConfigParam_HwLimitCrit: pCaps->OdmProtected = pChannel->ChannelPolicy.HwLimitCritOdmProtected; break; case NvOdmTmonConfigParam_SampleMs: // smaple intervals in descending order pCaps->MaxValue = s_Adt7461SampleIntervalsMS[0]; pCaps->MinValue = s_Adt7461SampleIntervalsMS[( NV_ARRAY_SIZE(s_Adt7461SampleIntervalsMS) - 1)]; pCaps->OdmProtected = pChannel->ChannelPolicy.RateOdmProtected; return; default: // unsupported parameter pCaps->MaxValue = ODM_TMON_PARAMETER_UNSPECIFIED; pCaps->MinValue = ODM_TMON_PARAMETER_UNSPECIFIED; pCaps->OdmProtected = NV_TRUE; return; } // Common range for limits pCaps->MaxValue = ADT7461_T_RANGE_LIMIT_HIGH(ExtRange); pCaps->MinValue = ADT7461_T_RANGE_LIMIT_LOW(ExtRange); }
void Adt7461CapabilitiesGet( NvOdmTmonDeviceHandle hTmon, NvOdmTmonZoneID ZoneId, NvOdmTmonCapabilities* pCaps) { NvBool ExtRange; ADT7461PrivData* pPrivData; NV_ASSERT(hTmon && hTmon->pPrivate && pCaps); pPrivData = hTmon->pPrivate; ExtRange = ((pPrivData->ShadowConfig & ADT7461ConfigBits_ExtendedRange) != 0); pCaps->Tmax = ADT7461_T_RANGE_LIMIT_HIGH(ExtRange); pCaps->Tmin = ADT7461_T_RANGE_LIMIT_LOW(ExtRange); pCaps->IntrSupported = NV_TRUE; pCaps->HwCriticalSupported = NV_TRUE; pCaps->HwCoolingSupported = NV_FALSE; }
void Adt7461CapabilitiesGet( NvOdmTmonDeviceHandle hTmon, NvOdmTmonZoneID ZoneId, NvOdmTmonCapabilities* pCaps) { NvBool ExtRange; ADT7461PrivData* pPrivData; NV_ASSERT(hTmon && hTmon->pPrivate && pCaps); pPrivData = hTmon->pPrivate; #if PRE_ER_GMT_THERMALSENSOR ExtRange = 0; /* not support ADT thermal sensor*/ #else ExtRange = ((pPrivData->ShadowConfig & ADT7461ConfigBits_ExtendedRange) != 0); #endif pCaps->Tmax = ADT7461_T_RANGE_LIMIT_HIGH(ExtRange); pCaps->Tmin = ADT7461_T_RANGE_LIMIT_LOW(ExtRange); pCaps->IntrSupported = NV_TRUE; pCaps->HwCriticalSupported = NV_TRUE; pCaps->HwCoolingSupported = NV_FALSE; }
NvBool Adt7461ParameterConfig( NvOdmTmonDeviceHandle hTmon, NvOdmTmonZoneID ZoneId, NvOdmTmonConfigParam ParamId, NvS32* pSetting) { NvU8 Data; NvBool ExtRange, OdmProtected; ADT7461PrivData* pPrivData; const ADT7461RegisterInfo* pReg; const ADT7461ChannelInfo* pChannel; NV_ASSERT(hTmon && hTmon->pPrivate && pSetting); pPrivData = hTmon->pPrivate; #if PRE_ER_GMT_THERMALSENSOR ExtRange = 0; /* not support ADT thermal sensor*/ #else ExtRange = ((pPrivData->ShadowConfig & ADT7461ConfigBits_ExtendedRange) != 0); #endif pChannel = &pPrivData->pDeviceInfo->Channels[( pPrivData->ConnectivityMap[ZoneId])]; switch (ParamId) { case NvOdmTmonConfigParam_IntrLimitHigh: #if PRE_ER_WORKAROUND return NV_TRUE; #endif pReg = &pChannel->IntrLimitHigh; OdmProtected = pChannel->ChannelPolicy.IntrLimitsOdmProtected; break; case NvOdmTmonConfigParam_IntrLimitLow: #if PRE_ER_WORKAROUND return NV_TRUE; #endif pReg = &pChannel->IntrLimitLow; OdmProtected = pChannel->ChannelPolicy.IntrLimitsOdmProtected; break; case NvOdmTmonConfigParam_HwLimitCrit: #if PRE_ER_WORKAROUND return NV_TRUE; #endif pReg = &pChannel->ComparatorLimit; OdmProtected = pChannel->ChannelPolicy.HwLimitCritOdmProtected; break; case NvOdmTmonConfigParam_SampleMs: OdmProtected = pChannel->ChannelPolicy.RateOdmProtected; return Adt7461ConfigureSampleInterval( pPrivData, OdmProtected, pSetting); default: // unsupported parameter *pSetting = ODM_TMON_PARAMETER_UNSPECIFIED; return NV_TRUE; } // Common processing for temperature limits configuration if ((OdmProtected) || ((*pSetting) == ODM_TMON_PARAMETER_UNSPECIFIED)) { // Read ADT7461 register and convert data to current parameter value if(!Adt7461ReadReg(pPrivData, pReg, &Data)) return NV_FALSE; *pSetting = ADT7461_T_DATA_TO_VALUE(ExtRange, Data); } else { // Clip target setting to temperature range if ((*pSetting) > ADT7461_T_RANGE_LIMIT_HIGH(ExtRange)) *pSetting = ADT7461_T_RANGE_LIMIT_HIGH(ExtRange); else if ((*pSetting) < ADT7461_T_RANGE_LIMIT_LOW(ExtRange)) *pSetting = ADT7461_T_RANGE_LIMIT_LOW(ExtRange); // Convert new configuration setting and write to ADT7461 register Data = ADT7461_T_VALUE_TO_DATA(ExtRange, *pSetting); if(!Adt7461WriteReg(pPrivData, pReg, Data)) return NV_FALSE; } return NV_TRUE; }
NvBool Adt7461Init(NvOdmTmonDeviceHandle hTmon) { NvU8 Data; NvBool ExtRange; NvU32 i = 0; NvU32 I2cInstance = 0; NvOdmIoModule I2cModule = NvOdmIoModule_Num; // Inavlid module const ADT7461RegisterInfo* pReg = NULL; ADT7461PrivData* pPrivData = NULL; NV_ASSERT(hTmon && hTmon->pConn && hTmon->pConn->AddressList); // Allocate and clear priavte data pPrivData = (ADT7461PrivData*) NvOdmOsAlloc(sizeof(ADT7461PrivData)); if (pPrivData == NULL) { NVODM_ADT7461_PRINTF(("ADT7461: Error Allocating PrivData. \n")); return NV_FALSE; } NvOdmOsMemset(pPrivData, 0, sizeof(ADT7461PrivData)); hTmon->pPrivate = pPrivData; // Register for PMU services pPrivData->hOdmPmuSevice = NvOdmServicesPmuOpen(); if (pPrivData->hOdmPmuSevice == NULL) { NVODM_ADT7461_PRINTF(("ADT7461: Error Open PMU service. \n")); goto fail; } // Register for GPIO services pPrivData->hGpio = NvOdmGpioOpen(); if (pPrivData->hOdmPmuSevice == NULL) { NVODM_ADT7461_PRINTF(("ADT7461: Error Open GPIO service. \n")); goto fail; } /* * Parse connectivity data: turn On power to the device, acquire I2C * interface and GPIO interrupt (optional); map device channels to * thermal zones */ for (i = 0; i < hTmon->pConn->NumAddress; i ++) { const NvOdmIoAddress* pIoAddress = &hTmon->pConn->AddressList[i]; if (pIoAddress->Interface == NvOdmIoModule_I2c_Pmu) { I2cModule = NvOdmIoModule_I2c_Pmu; I2cInstance = pIoAddress->Instance; NV_ASSERT(pIoAddress->Address != 0); pPrivData->DeviceI2cAddr = pIoAddress->Address; } else if (pIoAddress->Interface == NvOdmIoModule_Tsense) { NV_ASSERT(pIoAddress->Instance < NvOdmTmonZoneID_Num); NV_ASSERT(pIoAddress->Address < ADT7461ChannelID_Num); pPrivData->ConnectivityMap[pIoAddress->Instance] = pIoAddress->Address; } else if (pIoAddress->Interface == NvOdmIoModule_Vdd) { NvU32 usec = 0; NvU32 RailAddress = pIoAddress->Address; NvOdmServicesPmuVddRailCapabilities RailCapabilities; NvOdmServicesPmuGetCapabilities( pPrivData->hOdmPmuSevice, RailAddress, &RailCapabilities); NvOdmServicesPmuSetVoltage(pPrivData->hOdmPmuSevice, RailAddress, RailCapabilities.requestMilliVolts, &usec); NvOdmOsWaitUS(usec + (ADT7461_POWERUP_DELAY_MS * 1000)); } else if (pIoAddress->Interface == NvOdmIoModule_Gpio) { NvU32 port = pIoAddress->Instance; NvU32 pin = pIoAddress->Address; pPrivData->hGpioPin = NvOdmGpioAcquirePinHandle( pPrivData->hGpio, port, pin); } } NV_ASSERT(I2cModule == NvOdmIoModule_I2c_Pmu); pPrivData->hOdmI2C = NvOdmI2cOpen(I2cModule, I2cInstance); if (pPrivData->hOdmI2C == NULL) { NVODM_ADT7461_PRINTF(("ADT7461: Error Open I2C device. \n")); goto fail; } /* * Initialize device info and configuration. Force standby mode to avoid * glitch on shutdown comparator output when temperature range and/or * comparator limit is changing during initialization. The Adt7461Run() * call from the hal that follows initialization will switch device to * run mode and re-start temperature monitoring (note that out of limit * interrupt is always masked during and after initialization) */ pPrivData->pDeviceInfo = &s_Adt7461Info; pPrivData->ShadowRegPtr = ADT7461_INVALID_ADDR; pReg = &pPrivData->pDeviceInfo->Config; if (!Adt7461ReadReg(pPrivData, pReg, &Data)) goto fail; if ((Data & ADT7461ConfigBits_ExtendedRange) != (ADT7461_INITIAL_CONFIG & ADT7461ConfigBits_ExtendedRange)) { // Only switch from standard to extended range is supported NV_ASSERT((Data & ADT7461ConfigBits_ExtendedRange) == 0); Data |= ADT7461ConfigBits_Standby; if(!Adt7461WriteReg(pPrivData, pReg, Data)) goto fail; } Data = ADT7461_INITIAL_CONFIG | ADT7461ConfigBits_Standby; if(!Adt7461WriteReg(pPrivData, pReg, Data)) goto fail; pPrivData->ShadowConfig = Data; #if PRE_ER_GMT_THERMALSENSOR ExtRange = 0; /* not support ADT thermal sensor*/ #else ExtRange = ((Data & ADT7461ConfigBits_ExtendedRange) != 0); #endif // Program shutdown comparators settings Data = ADT7461_T_VALUE_TO_DATA( ExtRange, ADT7461_ODM_LOCAL_COMPARATOR_LIMIT_VALUE); pReg = &pPrivData->pDeviceInfo->Channels[ ADT7461ChannelID_Local].ComparatorLimit; if(!Adt7461WriteReg(pPrivData, pReg, Data)) goto fail; Data = ADT7461_T_VALUE_TO_DATA( ExtRange, ADT7461_ODM_REMOTE_COMPARATOR_LIMIT_VALUE); pReg = &pPrivData->pDeviceInfo->Channels[ ADT7461ChannelID_Remote].ComparatorLimit; if(!Adt7461WriteReg(pPrivData, pReg, Data)) goto fail; // Set interrupt limits to the range boundaries to prevent out of limit // interrupt Data = ADT7461_T_VALUE_TO_DATA( ExtRange, ADT7461_T_RANGE_LIMIT_HIGH(ExtRange)); pReg = &pPrivData->pDeviceInfo->Channels[ ADT7461ChannelID_Local].IntrLimitHigh; if(!Adt7461WriteReg(pPrivData, pReg, Data)) goto fail; pReg = &pPrivData->pDeviceInfo->Channels[ ADT7461ChannelID_Remote].IntrLimitHigh; if(!Adt7461WriteReg(pPrivData, pReg, Data)) goto fail; Data = ADT7461_T_VALUE_TO_DATA( ExtRange, ADT7461_T_RANGE_LIMIT_LOW(ExtRange)); pReg = &pPrivData->pDeviceInfo->Channels[ ADT7461ChannelID_Local].IntrLimitLow; if(!Adt7461WriteReg(pPrivData, pReg, Data)) goto fail; pReg = &pPrivData->pDeviceInfo->Channels[ ADT7461ChannelID_Remote].IntrLimitLow; if(!Adt7461WriteReg(pPrivData, pReg, Data)) goto fail; // Set initial rate Data = ADT7461_INITIAL_RATE_SETTING; pReg = &pPrivData->pDeviceInfo->Rate; if(!Adt7461WriteReg(pPrivData, pReg, Data)) goto fail; pPrivData->ShadowRate = Data; // Set remote channel offset (8-bit 2's complement value for any range) Data = ((NvU8)ADT7461_ODM_REMOTE_OFFSET_VALUE); pReg = &pPrivData->pDeviceInfo->Channels[ ADT7461ChannelID_Remote].Toffset; if(!Adt7461WriteReg(pPrivData, pReg, Data)) goto fail; // Read ADT7461 status and ARA (clear pending Alert interrupt, if any) pReg = &pPrivData->pDeviceInfo->Status; if (!Adt7461ReadReg(pPrivData, pReg, &Data)) goto fail; // TODO: check open remote circuit error Adt7461ReadAra(pPrivData); return NV_TRUE; fail: Adt7461FreePrivData(pPrivData); hTmon->pPrivate = NULL; return NV_FALSE; }