int tfa98xxDiagLoadPresetsMultiple(int slave) { Tfa98xx_handle_t hL, hR, handles[2] ; int result = 0; // 1 is failure Tfa98xx_Config_t cfg; unsigned char tstbuf[0x87 + sizeof(cfg)]; TRACEIN; lastApiError = Tfa98xx_Open(slave << 1, &hL); if (lastApiError != Tfa98xx_Error_Ok) return 2; handles[0]=hL; lastApiError = Tfa98xx_Open(slave+1 << 1, &hR); if (lastApiError != Tfa98xx_Error_Ok) return 3; handles[1]=hR; lastApiError = Tfa98xx_DspWritePresetMultiple(2, handles, TFA98XX_PRESET_LENGTH, settings_HQ_KS_13X18_DUMBO_preset); assert(lastApiError == Tfa98xx_Error_Ok); stop: Tfa98xx_Close(hL); Tfa98xx_Close(hR); lastError = result; TRACEOUT; return result; }
int tfa98xxDiagLoadPreset(int slave) { Tfa98xx_handle_t handle; int result = 1; // 1 is failure Tfa98xx_Config_t cfg; unsigned char tstbuf[0x87 + sizeof(cfg)]; TRACEIN; lastApiError = Tfa98xx_Open(slave << 1, &handle); if (lastApiError != Tfa98xx_Error_Ok) return 2; coldStartup(handle); lastApiError = Tfa98xx_DspWritePreset(handle, TFA98XX_PRESET_LENGTH, settings_HQ_KS_13X18_DUMBO_preset); assert(lastApiError == Tfa98xx_Error_Ok); lastApiError = Tfa98xx_DspGetParam(handle, 1 /*MODULE_SPEAKERBOOST */ , 0x80, sizeof(tstbuf), tstbuf); assert(lastApiError == Tfa98xx_Error_Ok); result = 0 != memcmp(settings_HQ_KS_13X18_DUMBO_preset, &tstbuf[sizeof(cfg)], sizeof(Tfa98xx_Preset_t)); if (result) sprintf(lastErrorString, "DSP parameters mismatch"); stop: Tfa98xx_Close(handle); lastError = result; TRACEOUT; return result; }
/* * dump all known registers * returns: * 0 if slave can't be opened * nr of registers displayed */ int tfa98xxDiagRegisterDump(int slave) { Tfa98xx_handle_t handle; int i; unsigned short regval; unsigned char reg; TRACEIN; lastApiError = Tfa98xx_Open(slave << 1, &handle); if (lastApiError != Tfa98xx_Error_Ok) return 0; for (i = 0; i < MAXREGS; i++) { lastApiError = Tfa98xx_ReadRegister16(handle, regdefs[i].offset, ®val); assert(lastApiError == Tfa98xx_Error_Ok); printf("0x%02x: 0x%04x (%s)\n", regdefs[i].offset, regval, regdefs[i].name); } Tfa98xx_Close(handle); TRACEOUT; return i; }
int tfa98xxDiagLoadConfig(int slave) { Tfa98xx_handle_t handle; int result = 1; // 1 is failure Tfa98xx_Config_t cfg; TRACEIN; lastApiError = Tfa98xx_Open(slave << 1, &handle); if (lastApiError != Tfa98xx_Error_Ok) return 2; coldStartup(handle); lastApiError = Tfa98xx_DspWriteConfig(handle, TFA98XX_CONFIG_LENGTH, settings_Setup87_config); assert(lastApiError == Tfa98xx_Error_Ok); lastApiError = Tfa98xx_DspGetParam(handle, 1 /*MODULE_SPEAKERBOOST */ , 0x80, sizeof(cfg), cfg); assert(lastApiError == Tfa98xx_Error_Ok); result = 0 != memcmp(settings_Setup87_config, cfg, sizeof(Tfa98xx_Config_t)); if (result) sprintf(lastErrorString, "DSP parameters mismatch"); stop: Tfa98xx_Close(handle); lastError = result; TRACEOUT; return result; }
/* * check battery level to be above 2Volts * * */ int tfa98xxDiagBattery(int slave) { Tfa98xx_handle_t handle; int result = 0; // 1 is failure unsigned short reg; TRACEIN; lastApiError = Tfa98xx_Open(slave << 1, &handle); if (lastApiError != Tfa98xx_Error_Ok) return 4; // enable the clock in bypass mode // 48 kHz left channel I2S with coolflux in Bypass lastApiError = Tfa98xx_WriteRegister16(handle, TFA98XX_I2SREG, 0x880b); // assert(lastApiError == Tfa98xx_Error_Ok); // PLL=BCK, input 1, power off lastApiError = Tfa98xx_WriteRegister16(handle, TFA98XX_SYS_CTRL, 0x0219); // assert(lastApiError == Tfa98xx_Error_Ok); // 1.0 uF coil, PLL=BCK, input 1, power on lastApiError = Tfa98xx_WriteRegister16(handle, TFA98XX_SYS_CTRL, 0x0618); // assert(lastApiError == Tfa98xx_Error_Ok); // check if clocks are stable and running // give it some time usleep(14000); // 14ms good for all rates // expect: 0x00 : 0xd85f if (tfa98xxDiagStatus (handle, 0, TFA98XX_STATUS_PLLS | TFA98XX_STATUS_CLKS)) { sprintf(lastErrorString, "clock not running"); result = 2; // fail if any of these is clear goto stop; } // check battery level lastApiError = Tfa98xx_ReadRegister16(handle, TFA98XX_BATTERYVOLTAGE, ®); assert(lastApiError == Tfa98xx_Error_Ok); // 2V: 2/(5.5/1024)=372 if (reg < 372) { sprintf(lastErrorString, "battery level too low: exp > 2.0V, rcv=%2.2f", reg * (5.5 / 1024)); result = 1; goto stop; } // any other errors if (tfa98xxDiagStatus (handle, TFA98XX_STATUS_ERRORS_SET_MSK, TFA98XX_STATUS_ERRORS_CLR_MSK)) { sprintf(lastErrorString, "status errorbit active"); result = 3; } stop: Tfa98xx_Close(handle); lastError = result; TRACEOUT; return result; }
/* * write/read test of a register that has no risk of causing damage * return code: * 2 : write value wrong * */ int tfa98xxDiagI2cRw(int slave) { Tfa98xx_handle_t handle; int testregoffset, result = 0; // 1 is failure unsigned short testreg; TRACEIN; lastApiError = Tfa98xx_Open(slave << 1, &handle); if (lastApiError != Tfa98xx_Error_Ok) return 1; // get the index of the testreg for ( testregoffset = 0; testregoffset < MAXREGS; testregoffset++) { if (regdefs[ testregoffset].offset == RWTEST_REG) break; } // powerdown to avoid side effects lastApiError = Tfa98xx_Powerdown(handle, 1); assert(lastApiError == Tfa98xx_Error_Ok); // check pwron default first lastApiError = Tfa98xx_ReadRegister16(handle, RWTEST_REG, &testreg); // assert(lastApiError == Tfa98xx_Error_Ok); if (regdefs[ testregoffset].pwronDefault != (testreg & regdefs[ testregoffset].pwronTestmask)) { sprintf(lastErrorString, "poweron default wrong: %s (0x%02x), exp:0x%04x rcv:0x%04x\n", regdefs[ testregoffset].name, regdefs[ testregoffset].offset, regdefs[ testregoffset].pwronDefault, testreg); result = 2; goto stop; } // write 0x1234 lastApiError = Tfa98xx_WriteRegister16(handle, RWTEST_REG, 0x1234); // assert(lastApiError == Tfa98xx_Error_Ok); lastApiError = Tfa98xx_ReadRegister16(handle, RWTEST_REG, &testreg); // assert(lastApiError == Tfa98xx_Error_Ok); // restore default, else pwrdefault may fail lastApiError = Tfa98xx_WriteRegister16(handle, RWTEST_REG, regdefs[RWTEST_REG].pwronDefault); // assert(lastApiError == Tfa98xx_Error_Ok); if (0x1234 != testreg) { sprintf(lastErrorString, "read back value mismatch: (testreg=0x%02x), exp:0x%04x rcv:0x%04x\n", RWTEST_REG, 0x1234, testreg); result = 1; } stop: Tfa98xx_Close(handle); lastError = result; TRACEOUT; return result; }
static int tfa98xx_codec_remove(struct snd_soc_codec *codec) { enum Tfa98xx_Error err; pr_info("%s\n", __func__); if (handle_is_open(handles[TOP])) { err = Tfa98xx_Close(handles[TOP]); if (err != Tfa98xx_Error_Ok) pr_err("%s: Top Tfa98xx_Close failed\n", __func__); handles[TOP] = -1; } if (handle_is_open(handles[BOTTOM])) { err = Tfa98xx_Close(handles[BOTTOM]); if (err != Tfa98xx_Error_Ok) pr_err("%s: Top Tfa98xx_Close failed\n", __func__); handles[TOP] = -1; } return 0; }
/* * assume I2S input and verify signal activity */ int tfa98xxDiagI2sInput(int slave) { { Tfa98xx_handle_t handle; int result; Tfa98xx_StateInfo_t stateInfo; unsigned short sysctrlReg; TRACEIN; lastApiError = Tfa98xx_Open(slave << 1, &handle); if (lastApiError != Tfa98xx_Error_Ok) return 3; gHandle = handle; // global prevents reopen result = tfa98xxDiagLoadSpeaker(slave); if (result) { result = 2; goto stop; } lastApiError = Tfa98xx_SetConfigured(handle); assert(lastApiError == Tfa98xx_Error_Ok); //select channel lastApiError = Tfa98xx_ReadRegister16(handle, 0x09, &sysctrlReg); assert(lastApiError == Tfa98xx_Error_Ok); lastApiError = Tfa98xx_WriteRegister16(handle, 0x09, sysctrlReg & ~(0x1 << 13)); // input 1 // lastApiError = Tfa98xx_WriteRegister16(handle, 0x09, sysctrlReg | (0x1<<13)); // input 2 assert(lastApiError == Tfa98xx_Error_Ok); lastApiError = Tfa98xx_DspGetStateInfo(handle, &stateInfo); assert(lastApiError == Tfa98xx_Error_Ok); // check for activity if ((stateInfo.statusFlag & (1 << Tfa98xx_SpeakerBoost_Activity)) == 0) { sprintf(lastErrorString, "no audio active on input"); result = 1; } else result = 0; stop: Tfa98xx_Close(handle); lastError = result; gHandle = -1; TRACEOUT; return result; } }
void read_tfa98xx_id(int *id) { Tfa98xx_handle_t handle; int err; /* create handle */ err = Tfa98xx_Open(I2C_ADDRESS, &handle); if(err != Tfa98xx_Error_Ok) { ALOGE("[%s] Tfa98xx_Open failed! err = %d, I2C_ADDRESS = %#x", __func__, err,I2C_ADDRESS); } err = Tfa98xx_ReadRegister16(handle, TFA98XX_REVISIONNUMBER, id); ALOGD("TFA98xx ID=%#x",*id); err = Tfa98xx_Close(handle); }
/* * enable clocks in bypass and verify status */ int tfa98xxDiagClock(int slave) { Tfa98xx_handle_t handle; int result = 0; // 1 is failure TRACEIN; lastApiError = Tfa98xx_Open(slave << 1, &handle); if (lastApiError != Tfa98xx_Error_Ok) return 3; // enable the clock in bypass mode // 48 kHz left channel I2S with coolflux in Bypass lastApiError = Tfa98xx_WriteRegister16(handle, TFA98XX_I2SREG, 0x880b); // assert(lastApiError == Tfa98xx_Error_Ok); // PLL=BCK, input 1, power off lastApiError = Tfa98xx_WriteRegister16(handle, TFA98XX_SYS_CTRL, 0x0219); // assert(lastApiError == Tfa98xx_Error_Ok); // 1.0 uF coil, PLL=BCK, input 1, power on lastApiError = Tfa98xx_WriteRegister16(handle, TFA98XX_SYS_CTRL, 0x0618); // assert(lastApiError == Tfa98xx_Error_Ok); // give it some time usleep(14000); // 14ms good for all rates // check if clocks are stable and running // expect: 0x00 : 0xd85f if (tfa98xxDiagStatus (handle, 0, TFA98XX_STATUS_PLLS | TFA98XX_STATUS_CLKS)) { sprintf(lastErrorString, "clock not running"); result = 1; // fail if any of these is clear goto stop; } // any other errors if (tfa98xxDiagStatus (handle, TFA98XX_STATUS_ERRORS_SET_MSK, TFA98XX_STATUS_ERRORS_CLR_MSK)) { sprintf(lastErrorString, "status errorbit active"); result = 2; } stop: Tfa98xx_Close(handle); lastError = result; TRACEOUT; return result; }
/* * load speaker parameters and verify readback * * note: this function can be called from other tests it uses the global handle */ int tfa98xxDiagLoadSpeaker(int slave) { int result = 1; // 1 is failure int gbl=0; Tfa98xx_SpeakerParameters_t spkr; TRACEIN; if ( gHandle<0 ) { lastApiError = Tfa98xx_Open(slave << 1, &gHandle); if (lastApiError != Tfa98xx_Error_Ok) return 2; } else gbl = 1; coldStartup(gHandle); lastApiError = Tfa98xx_DspWriteSpeakerParameters(gHandle, TFA98XX_SPEAKERPARAMETER_LENGTH, settings_KS_13X18_DUMBO_speaker); assert(lastApiError == Tfa98xx_Error_Ok); lastApiError = Tfa98xx_DspGetParam(gHandle, 1 /*MODULE_SPEAKERBOOST */ , 0x86, sizeof(spkr), spkr); assert(lastApiError == Tfa98xx_Error_Ok); result = 0 != memcmp(settings_KS_13X18_DUMBO_speaker, spkr, sizeof(Tfa98xx_SpeakerParameters_t)); if (result) sprintf(lastErrorString, "DSP parameters mismatch"); stop: if ( !gbl ) { Tfa98xx_Close(gHandle); lastError = result; gHandle=-1; } TRACEOUT; return result; }
int tfa98xxDiagDsp(int slave) { Tfa98xx_handle_t handle; int i, result = 0; // !0 is failure char tag[TFA98XX_MAXTAG], string[TFA98XX_MAXTAG + 1], *ptr; const char *exp = DSP_revstring; TRACEIN; lastApiError = Tfa98xx_Open(slave << 1, &handle); if (lastApiError != Tfa98xx_Error_Ok) return 3; coldStartup(handle); lastApiError = Tfa98xx_DspGetParam(handle, 1 /*MODULE_SPEAKERBOOST */ , 0xFF, TFA98XX_MAXTAG, tag); if (lastApiError != Tfa98xx_Error_Ok) { sprintf(lastErrorString, "DSP failure"); return 1; } ptr = string; // the characters are in every 3rd byte for (i = 2; i < TFA98XX_MAXTAG; i += 3) { if (isprint(tag[i])) { *ptr++ = tag[i]; // only printable chars } } *ptr = '\0'; if (strcmp(exp, string)) { sprintf(lastErrorString, "wrong DSP revtag: exp %s rcv:%s\n", exp, string); return 2; } stop: Tfa98xx_Close(handle); lastError = result; TRACEOUT; return result; }
/* * verify default state of relevant registers */ int tfa98xxDiagRegisterDefaults(int slave) { Tfa98xx_handle_t handle; int i, result = 0; // 1 is failure unsigned short regval; unsigned char reg; TRACEIN; lastApiError = Tfa98xx_Open(slave << 1, &handle); if (lastApiError != Tfa98xx_Error_Ok) return 2; for (i = 0; i < MAXREGS; i++) { if (regdefs[i].pwronTestmask == 0) continue; lastApiError = Tfa98xx_ReadRegister16(handle, regdefs[i].offset, ®val); assert(lastApiError == Tfa98xx_Error_Ok); if (regdefs[i].pwronDefault != (regval & regdefs[i].pwronTestmask)) { sprintf(lastErrorString, "poweron default wrong: %s (0x%02x), exp:0x%04x rcv:0x%04x\n", regdefs[i].name, regdefs[i].offset, regdefs[i].pwronDefault, regval); result++; } } // set DC-DC peak protection bit lastApiError = Tfa98xx_WriteRegister16(handle, TFA98XX_SPKR_CALIBRATION, 0x0c00); // assert(lastApiError == Tfa98xx_Error_Ok); stop: Tfa98xx_Close(handle); lastError = result; TRACEOUT; return result; }
/* * scan of I2C for ID registers and check for expected device * open the expected device */ int tfa98xxDiagI2cScan(int slave) { Tfa98xx_handle_t handle; int result = 0; // 1 is failure TRACEIN; lastApiError = Tfa98xx_Open(slave << 1, &handle); if (lastApiError == Tfa98xx_Error_Ok) { Tfa98xx_Close(handle); } else { result = 1; // non-0 if fail sprintf(lastErrorString, "can't find i2c slave 0x%0x", slave); } lastError = result; TRACEOUT; return result; }
/* * verify speaker presence by checking the resistance */ int tfa98xxDiagSpeakerPresence(int slave) { Tfa98xx_handle_t handle; int result; float re0; TRACEIN; lastApiError = Tfa98xx_Open(slave << 1, &handle); if (lastApiError != Tfa98xx_Error_Ok) return 3; gHandle = handle; result = tfa98xxDiagLoadSpeaker(slave); if (result) { result = 2; goto stop; } lastApiError = Tfa98xx_SetConfigured(handle); assert(lastApiError == Tfa98xx_Error_Ok); waitCalibration(handle, &re0); // check R for non-0 if (re0 == 0) { sprintf(lastErrorString, "Speaker not detected"); result = 1; } else result = 0; stop: Tfa98xx_Close(handle); lastError = result; gHandle = -1; TRACEOUT; return result; }
/* * check status register flags and assume coldstart (or fail) * return code: * 1 : error bit * 2 : not cold powered on * other internal errors */ int tfa98xxDiagStatusCold(int slave) { Tfa98xx_handle_t handle; int result = 0; // 1 is failure unsigned short statusreg; TRACEIN; lastApiError = Tfa98xx_Open(slave << 1, &handle); if (lastApiError != Tfa98xx_Error_Ok) { return 3; } lastApiError = Tfa98xx_ReadRegister16(handle, TFA98XX_STATUSREG, &statusreg); assert(lastApiError == Tfa98xx_Error_Ok); if (!(statusreg & TFA98XX_STATUS_ACS)) { /* ensure cold booted */ sprintf(lastErrorString, "not a cold start"); result = 2; goto stop; } if (tfa98xxDiagStatus (handle, TFA98XX_STATUS_ERRORS_SET_MSK, TFA98XX_STATUS_ERRORS_CLR_MSK)) { sprintf(lastErrorString, "status errorbit active"); result = 1; } stop: Tfa98xx_Close(handle); lastError = result; TRACEOUT; return result; }