static void ath9k_hw_adc_dccal_calibrate(struct ath_hal *ah, u8 numChains) { struct ath_hal_5416 *ahp = AH5416(ah); u32 iOddMeasOffset, iEvenMeasOffset, val, i; int32_t qOddMeasOffset, qEvenMeasOffset, qDcMismatch, iDcMismatch; const struct hal_percal_data *calData = ahp->ah_cal_list_curr->calData; u32 numSamples = (1 << (calData->calCountMax + 5)) * calData->calNumSamples; for (i = 0; i < numChains; i++) { iOddMeasOffset = ahp->ah_totalAdcDcOffsetIOddPhase[i]; iEvenMeasOffset = ahp->ah_totalAdcDcOffsetIEvenPhase[i]; qOddMeasOffset = ahp->ah_totalAdcDcOffsetQOddPhase[i]; qEvenMeasOffset = ahp->ah_totalAdcDcOffsetQEvenPhase[i]; DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "Starting ADC DC Offset Cal for Chain %d\n", i); DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "Chn %d pwr_meas_odd_i = %d\n", i, iOddMeasOffset); DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "Chn %d pwr_meas_even_i = %d\n", i, iEvenMeasOffset); DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "Chn %d pwr_meas_odd_q = %d\n", i, qOddMeasOffset); DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "Chn %d pwr_meas_even_q = %d\n", i, qEvenMeasOffset); iDcMismatch = (((iEvenMeasOffset - iOddMeasOffset) * 2) / numSamples) & 0x1ff; qDcMismatch = (((qOddMeasOffset - qEvenMeasOffset) * 2) / numSamples) & 0x1ff; DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "Chn %d dc_offset_mismatch_i = 0x%08x\n", i, iDcMismatch); DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "Chn %d dc_offset_mismatch_q = 0x%08x\n", i, qDcMismatch); val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i)); val &= 0xc0000fff; val |= (qDcMismatch << 12) | (iDcMismatch << 21); REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val); DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "ADC DC Offset Cal done for Chain %d\n", i); } REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0), REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) | AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE); }
static void ath9k_hw_adc_gaincal_calibrate(struct ath_hal *ah, u8 numChains) { struct ath_hal_5416 *ahp = AH5416(ah); u32 iOddMeasOffset, iEvenMeasOffset, qOddMeasOffset, qEvenMeasOffset; u32 qGainMismatch, iGainMismatch, val, i; for (i = 0; i < numChains; i++) { iOddMeasOffset = ahp->ah_totalAdcIOddPhase[i]; iEvenMeasOffset = ahp->ah_totalAdcIEvenPhase[i]; qOddMeasOffset = ahp->ah_totalAdcQOddPhase[i]; qEvenMeasOffset = ahp->ah_totalAdcQEvenPhase[i]; DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "Starting ADC Gain Cal for Chain %d\n", i); DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "Chn %d pwr_meas_odd_i = 0x%08x\n", i, iOddMeasOffset); DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "Chn %d pwr_meas_even_i = 0x%08x\n", i, iEvenMeasOffset); DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "Chn %d pwr_meas_odd_q = 0x%08x\n", i, qOddMeasOffset); DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "Chn %d pwr_meas_even_q = 0x%08x\n", i, qEvenMeasOffset); if (iOddMeasOffset != 0 && qEvenMeasOffset != 0) { iGainMismatch = ((iEvenMeasOffset * 32) / iOddMeasOffset) & 0x3f; qGainMismatch = ((qOddMeasOffset * 32) / qEvenMeasOffset) & 0x3f; DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "Chn %d gain_mismatch_i = 0x%08x\n", i, iGainMismatch); DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "Chn %d gain_mismatch_q = 0x%08x\n", i, qGainMismatch); val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i)); val &= 0xfffff000; val |= (qGainMismatch) | (iGainMismatch << 6); REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val); DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "ADC Gain Cal done for Chain %d\n", i); } } REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0), REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) | AR_PHY_NEW_ADC_GAIN_CORR_ENABLE); }
void ar5416AdcDcCalibration(struct ath_hal *ah, uint8_t numChains) { struct ar5416PerCal *cal = &AH5416(ah)->ah_cal; const HAL_PERCAL_DATA *calData = cal->cal_curr->calData; uint32_t numSamples; int i; numSamples = (1 << (calData->calCountMax + 5)) * calData->calNumSamples; for (i = 0; i < numChains; i++) { uint32_t iOddMeasOffset = cal->totalAdcDcOffsetIOddPhase(i); uint32_t iEvenMeasOffset = cal->totalAdcDcOffsetIEvenPhase(i); int32_t qOddMeasOffset = cal->totalAdcDcOffsetQOddPhase(i); int32_t qEvenMeasOffset = cal->totalAdcDcOffsetQEvenPhase(i); int32_t qDcMismatch, iDcMismatch; uint32_t val; HALDEBUG(ah, HAL_DEBUG_PERCAL, "Starting ADC DC Offset Cal for Chain %d\n", i); HALDEBUG(ah, HAL_DEBUG_PERCAL, " pwr_meas_odd_i = %d\n", iOddMeasOffset); HALDEBUG(ah, HAL_DEBUG_PERCAL, " pwr_meas_even_i = %d\n", iEvenMeasOffset); HALDEBUG(ah, HAL_DEBUG_PERCAL, " pwr_meas_odd_q = %d\n", qOddMeasOffset); HALDEBUG(ah, HAL_DEBUG_PERCAL, " pwr_meas_even_q = %d\n", qEvenMeasOffset); HALASSERT(numSamples); iDcMismatch = (((iEvenMeasOffset - iOddMeasOffset) * 2) / numSamples) & 0x1ff; qDcMismatch = (((qOddMeasOffset - qEvenMeasOffset) * 2) / numSamples) & 0x1ff; HALDEBUG(ah, HAL_DEBUG_PERCAL, " dc_offset_mismatch_i = 0x%08x\n", iDcMismatch); HALDEBUG(ah, HAL_DEBUG_PERCAL, " dc_offset_mismatch_q = 0x%08x\n", qDcMismatch); val = OS_REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i)); val &= 0xc0000fff; val |= (qDcMismatch << 12) | (iDcMismatch << 21); OS_REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val); HALDEBUG(ah, HAL_DEBUG_PERCAL, "ADC DC Offset Cal done for Chain %d\n", i); } OS_REG_SET_BIT(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0), AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE); }
/* * Use HW data to do ADC Gain Calibration */ void ar5416AdcGainCalibration(struct ath_hal *ah, uint8_t numChains) { struct ar5416PerCal *cal = &AH5416(ah)->ah_cal; uint32_t i; for (i = 0; i < numChains; i++) { uint32_t iOddMeasOffset = cal->totalAdcIOddPhase(i); uint32_t iEvenMeasOffset = cal->totalAdcIEvenPhase(i); uint32_t qOddMeasOffset = cal->totalAdcQOddPhase(i); uint32_t qEvenMeasOffset = cal->totalAdcQEvenPhase(i); HALDEBUG(ah, HAL_DEBUG_PERCAL, "Start ADC Gain Cal for Chain %d\n", i); HALDEBUG(ah, HAL_DEBUG_PERCAL, " pwr_meas_odd_i = 0x%08x\n", iOddMeasOffset); HALDEBUG(ah, HAL_DEBUG_PERCAL, " pwr_meas_even_i = 0x%08x\n", iEvenMeasOffset); HALDEBUG(ah, HAL_DEBUG_PERCAL, " pwr_meas_odd_q = 0x%08x\n", qOddMeasOffset); HALDEBUG(ah, HAL_DEBUG_PERCAL, " pwr_meas_even_q = 0x%08x\n", qEvenMeasOffset); if (iOddMeasOffset != 0 && qEvenMeasOffset != 0) { uint32_t iGainMismatch = ((iEvenMeasOffset*32)/iOddMeasOffset) & 0x3f; uint32_t qGainMismatch = ((qOddMeasOffset*32)/qEvenMeasOffset) & 0x3f; uint32_t val; HALDEBUG(ah, HAL_DEBUG_PERCAL, " gain_mismatch_i = 0x%08x\n", iGainMismatch); HALDEBUG(ah, HAL_DEBUG_PERCAL, " gain_mismatch_q = 0x%08x\n", qGainMismatch); val = OS_REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i)); val &= 0xfffff000; val |= (qGainMismatch) | (iGainMismatch << 6); OS_REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val); HALDEBUG(ah, HAL_DEBUG_PERCAL, "ADC Gain Cal done for Chain %d\n", i); } } OS_REG_SET_BIT(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0), AR_PHY_NEW_ADC_GAIN_CORR_ENABLE); }