Our ath5k IQ calibration computation seems to differ from the HALs. Below is a userspace program which illustrates this better.
The regdump was from an AR5212. I have to test against more values. Let me know if you see similar mismatches. You can also wget this from: http://ruslug.rutgers.edu/~mcgrof/tmp/iq.c --- #include <stdio.h> #include <sys/types.h> #define AR5K_PHY_IQ_CORR_Q_I_COFF 0x000007e0 #define AR5K_PHY_IQ_CORR_Q_I_COFF_S 5 #define AR5K_PHY_IQ_CORR_Q_Q_COFF 0x0000001f #define AR5K_PHY_IQ_CORR_ENABLE 0x00000800 /* This is what the AR5K_PHY_IQ register looks like to which we write * some final I and Q values to: * * 0000 0000 0000 0000 0000 0 000 000 0 0000 * |---------------------| |----| | |------------| |------| * ? L E I Q * * ? = Unknown * E = AR5K_PHY_IQ_CORR_ENABLE bit * L = AR5K_PHY_IQ_CAL_NUM_LOG_MAX (???) * I = Inphase, range seems to be 1 - 63 * Q = Quadrature, range seems to be 1 - 31 * * */ /* Implementation of I and Q calibration currently done in ath5k, this * doesn't seem to be right... */ int main(void) { u_int32_t i_pwr, q_pwr, val, final; int iq_corr, i_coff, i_coffd, q_coff, q_coffd; /* Current iq register value. This is just read to later append * our new I and Q values we want to write. */ final = 0x7510ff08; /* Read from a register, the 'I power' */ i_pwr = 0xf1366154; /* Read from a register, the 'Q power' */ q_pwr = 0xe6f4851f; /* Read from a register, seem to be, 'I/Q Correlation' */ iq_corr = 0x0f64d935; i_coffd = ((i_pwr >> 1) + (q_pwr >> 1)) >> 7; q_coffd = q_pwr >> 6; /* The AR5K_PHY_IQ_CORR_Q_I_COFF >> AR5K_PHY_IQ_CORR_Q_I_COFF_S is * done just to accomodate the values to be written to the right * place in the register for the I value */ i_coff = ((-iq_corr) / i_coffd) & (AR5K_PHY_IQ_CORR_Q_I_COFF >> AR5K_PHY_IQ_CORR_Q_I_COFF_S); q_coff = (((int)i_pwr / q_coffd) - 64) & AR5K_PHY_IQ_CORR_Q_Q_COFF; /* Hex print, without the shift, these are the real values then * these seem to be negative values... */ printf("Hex of actual values:\n"); printf("i:\t0x%08x\n", ((-iq_corr) / i_coffd)); printf("q:\t0x%08x\n", ((int)i_pwr / q_coffd) - 64); printf("Digit of actual values:\n"); /* Digit print, of real values */ printf("i:\t%d\n", ((-iq_corr) / i_coffd)); printf("q:\t%d\n", ((int)i_pwr / q_coffd) - 64); /* Here's what -1 looks like in hex */ printf("\n-1:\t0x%08x\n\n", -1); /* The actual currently computed value */ printf("Currently computed values:\n"); printf("i_coff:\t0x%08x\n", i_coff); printf("q_coff:\t0x%08x\n\n", q_coff); /* Final value we use to write to the AR5K_PHY_IQ register */ val = AR5K_PHY_IQ_CORR_ENABLE | ((u_int32_t)q_coff) | ((u_int32_t)i_coff << AR5K_PHY_IQ_CORR_Q_I_COFF_S); final |= val; printf("Final val we OR to the last read from AR5K_PHY_IQ:\n"); printf("val:\t0x%08x\n\n", val); printf("Final val we write to AR5K_PHY_IQ\n"); printf("final:\t0x%08x\n", final); #if 0 Just so you get an idea, this is a regdump of what the HAL actually does: R: Read W: Write This is the current value of AR5K_PHY_IQ R:0x09920 = 0x7510ff08 - ath_hal_calibrate AR5K_PHY_IQ This is where where i_pwr and q_pwr are obtained from R:0x09c10 = 0xf1366154 - ath_hal_calibrate AR5K_PHY_IQRES_CAL_PWR_I R:0x09c14 = 0xe6f4851f - ath_hal_calibrate AR5K_PHY_IQRES_CAL_PWR_Q This is where iq_corr is obtained from R:0x09c18 = 0x0f64d935 - ath_hal_calibrate AR5K_PHY_IQRES_CAL_CORR R:0x09920 = 0x7510ff08 - ath_hal_calibrate AR5K_PHY_IQ This is what we end up writing to AR5K_PHY_IQ, note the values are different from what we currently compute. W:0x09920 = 0x7510f808 - ath_hal_calibrate AR5K_PHY_IQ Now this is what this program prints out. We're probably doing something wrong... Hex of actual values: i: 0xfffffff8 q: 0xffffffbc Digit of actual values: i: -8 q: -68 -1: 0xffffffff Currently computed values: i_coff: 0x00000038 q_coff: 0x0000001c Final val we OR to the last read from AR5K_PHY_IQ: val: 0x00000f1c Final val we write to AR5K_PHY_IQ final: 0x7510ff1c #endif return 0; } _______________________________________________ ath5k-devel mailing list ath5k-devel@lists.ath5k.org https://lists.ath5k.org/mailman/listinfo/ath5k-devel