The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/ath/ath_hal/ar5416/ar5416_cal_iq.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * SPDX-License-Identifier: ISC
    3  *
    4  * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
    5  * Copyright (c) 2002-2008 Atheros Communications, Inc.
    6  *
    7  * Permission to use, copy, modify, and/or distribute this software for any
    8  * purpose with or without fee is hereby granted, provided that the above
    9  * copyright notice and this permission notice appear in all copies.
   10  *
   11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
   13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
   14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
   15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
   16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
   17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   18  *
   19  * $FreeBSD$
   20  */
   21 #include "opt_ah.h"
   22 
   23 #include "ah.h"
   24 #include "ah_internal.h"
   25 #include "ah_devid.h"
   26 
   27 #include "ar5416/ar5416.h"
   28 #include "ar5416/ar5416reg.h"
   29 #include "ar5416/ar5416phy.h"
   30 
   31 /* IQ Cal aliases */
   32 #define totalPowerMeasI(i)      caldata[0][i].u
   33 #define totalPowerMeasQ(i)      caldata[1][i].u
   34 #define totalIqCorrMeas(i)      caldata[2][i].s
   35 
   36 /*
   37  * Collect data from HW to later perform IQ Mismatch Calibration
   38  */
   39 void
   40 ar5416IQCalCollect(struct ath_hal *ah)
   41 {
   42         struct ar5416PerCal *cal = &AH5416(ah)->ah_cal;
   43         int i;
   44 
   45         /* 
   46          * Accumulate IQ cal measures for active chains
   47          */
   48         for (i = 0; i < AR5416_MAX_CHAINS; i++) {
   49                 cal->totalPowerMeasI(i) +=
   50                     OS_REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
   51                 cal->totalPowerMeasQ(i) +=
   52                     OS_REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
   53                 cal->totalIqCorrMeas(i) += (int32_t)
   54                     OS_REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
   55                 HALDEBUG(ah, HAL_DEBUG_PERCAL,
   56                     "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n",
   57                     cal->calSamples, i, cal->totalPowerMeasI(i),
   58                     cal->totalPowerMeasQ(i), cal->totalIqCorrMeas(i));
   59         }
   60 }
   61 
   62 /*
   63  * Use HW data to do IQ Mismatch Calibration
   64  */
   65 void
   66 ar5416IQCalibration(struct ath_hal *ah, uint8_t numChains)
   67 {
   68         struct ar5416PerCal *cal = &AH5416(ah)->ah_cal;
   69         int i;
   70 
   71         for (i = 0; i < numChains; i++) {
   72                 uint32_t powerMeasI = cal->totalPowerMeasI(i);
   73                 uint32_t powerMeasQ = cal->totalPowerMeasQ(i);
   74                 uint32_t iqCorrMeas = cal->totalIqCorrMeas(i);
   75                 uint32_t qCoffDenom, iCoffDenom;
   76                 int iqCorrNeg;
   77 
   78                 HALDEBUG(ah, HAL_DEBUG_PERCAL,
   79                     "Start IQ Cal and Correction for Chain %d\n", i);
   80                 HALDEBUG(ah, HAL_DEBUG_PERCAL,
   81                     "Orignal: iq_corr_meas = 0x%08x\n", iqCorrMeas);
   82 
   83                 iqCorrNeg = 0;
   84                 /* iqCorrMeas is always negative. */ 
   85                 if (iqCorrMeas > 0x80000000)  {
   86                         iqCorrMeas = (0xffffffff - iqCorrMeas) + 1;
   87                         iqCorrNeg = 1;
   88                 }
   89 
   90                 HALDEBUG(ah, HAL_DEBUG_PERCAL, " pwr_meas_i = 0x%08x\n",
   91                     powerMeasI);
   92                 HALDEBUG(ah, HAL_DEBUG_PERCAL, " pwr_meas_q = 0x%08x\n",
   93                     powerMeasQ);
   94                 HALDEBUG(ah, HAL_DEBUG_PERCAL, " iqCorrNeg is 0x%08x\n",
   95                     iqCorrNeg);
   96 
   97                 iCoffDenom = (powerMeasI/2 + powerMeasQ/2)/ 128;
   98                 qCoffDenom = powerMeasQ / 64;
   99                 /* Protect against divide-by-0 */
  100                 if (powerMeasQ != 0) {
  101                         /* IQ corr_meas is already negated if iqcorr_neg == 1 */
  102                         int32_t iCoff = iqCorrMeas/iCoffDenom;
  103                         int32_t qCoff = powerMeasI/qCoffDenom - 64;
  104 
  105                         HALDEBUG(ah, HAL_DEBUG_PERCAL, " iCoff = 0x%08x\n",
  106                             iCoff);
  107                         HALDEBUG(ah, HAL_DEBUG_PERCAL, " qCoff = 0x%08x\n",
  108                             qCoff);
  109          
  110                         /* Negate iCoff if iqCorrNeg == 0 */
  111                         iCoff = iCoff & 0x3f;
  112                         HALDEBUG(ah, HAL_DEBUG_PERCAL,
  113                             "New:  iCoff = 0x%08x\n", iCoff);
  114 
  115                         if (iqCorrNeg == 0x0)
  116                                 iCoff = 0x40 - iCoff;
  117                         if (qCoff > 15)
  118                                 qCoff = 15;
  119                         else if (qCoff <= -16)
  120                                 qCoff = -16;
  121                         HALDEBUG(ah, HAL_DEBUG_PERCAL,
  122                             " : iCoff = 0x%x  qCoff = 0x%x\n", iCoff, qCoff);
  123 
  124                         OS_REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4_CHAIN(i),
  125                             AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF, iCoff);
  126                         OS_REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4_CHAIN(i),
  127                             AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF, qCoff);
  128                         HALDEBUG(ah, HAL_DEBUG_PERCAL,
  129                             "IQ Cal and Correction done for Chain %d\n", i);
  130                 }
  131         }
  132         OS_REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4,
  133             AR_PHY_TIMING_CTRL4_IQCORR_ENABLE);
  134 }

Cache object: ed6a00ce982c0a045a108f01a3ff192f


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.