Tfa98xx_Error_t Tfa9890_DspReset(Tfa98xx_handle_t handle, int state) { Tfa98xx_Error_t error; unsigned short value49, value; /* for TFA9890 temporarily disable clock gating when dsp reset is used */ error = Tfa98xx_ReadRegister16(handle, TFA98XX_CURRENTSENSE4, &value49); if (error) return error; if (Tfa98xx_Error_Ok == error) { /* clock gating off */ value = value49 | TFA98XX_CURRENTSENSE4_CTRL_CLKGATECFOFF; // set the bit error = Tfa98xx_WriteRegister16(handle, TFA98XX_CURRENTSENSE4, value); if (error) return error; } error = Tfa98xx_ReadRegister16(handle, TFA98XX_CF_CONTROLS, &value); if (error) return error; /* set requested the DSP reset signal state */ value = state ? (value | TFA98XX_CF_CONTROLS_RST_MSK) : (value & ~TFA98XX_CF_CONTROLS_RST_MSK); error = Tfa98xx_WriteRegister16(handle, TFA98XX_CF_CONTROLS, value); /* clock gating restore */ error = Tfa98xx_WriteRegister16(handle, 0x49, value49);/* clock gating restore */ return error; }
/* * 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; }
/* * 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; }
/* * 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; } }
/* * Unbypassed the DSP */ static int tfa98xx_unbypass_dsp(Tfa98xx_handle_t handleIn) { enum Tfa98xx_Error err = Tfa98xx_Error_Other; unsigned short i2SRead = 0; unsigned short sysRead = 0; unsigned short sysCtrlRead = 0; unsigned short batProtRead = 0; if (handleIn == -1) return err; /* basic settings for quickset */ err = Tfa98xx_ReadRegister16(handleIn, TFA98XX_I2SREG, &i2SRead); err = Tfa98xx_ReadRegister16(handleIn, TFA98XX_I2S_SEL_REG, &sysRead); err = Tfa98xx_ReadRegister16(handleIn, TFA98XX_SYS_CTRL, &sysCtrlRead); err = Tfa98xx_ReadRegister16(handleIn, TFA98XX_BAT_PROT, &batProtRead); i2SRead |= TFA98XX_I2SREG_CHSA; /* Set CHSA to Unbypass DSP */ sysRead |= TFA9890_I2S_SEL_REG_POR;/* Set I2S SEL REG to set DCDC compensation to default 100%*/ sysRead &= ~(TFA98XX_I2S_SEL_REG_SPKR_MSK);/*Set impedance to be defined by DSP */ sysCtrlRead |= TFA98XX_SYS_CTRL_DCA_MSK;/* Set DCDC to active mode*/ sysCtrlRead |= TFA98XX_SYS_CTRL_CFE_MSK;/* Enable Coolflux */ batProtRead &= ~(TFA989X_BAT_PROT_BSSBY_MSK);/*Set clipper active */ /* Set CHSA to Unbypass DSP */ err = Tfa98xx_WriteRegister16(handleIn, TFA98XX_I2SREG, i2SRead); /* Set I2S SEL REG to set DCDC compensation to default 100% and Set impedance to be defined by DSP */ err = Tfa98xx_WriteRegister16(handleIn, TFA98XX_I2S_SEL_REG, sysRead); /* Set DCDC to active mode and enable Coolflux */ err = Tfa98xx_WriteRegister16(handleIn, TFA98XX_SYS_CTRL, sysCtrlRead); /* Set bypass clipper battery protection */ err = Tfa98xx_WriteRegister16(handleIn, TFA98XX_BAT_PROT, batProtRead); return err; }
/* * Bypass DSP handling */ static int tfa98xx_bypass_dsp(Tfa98xx_handle_t handleIn) { enum Tfa98xx_Error err = Tfa98xx_Error_Other; unsigned short i2SRead = 0; unsigned short sysRead = 0; unsigned short sysCtrlRead = 0; unsigned short batProtRead = 0; if (handleIn == -1) return err; err = Tfa98xx_ReadRegister16(handleIn, TFA98XX_I2SREG, &i2SRead); err = Tfa98xx_ReadRegister16(handleIn, TFA98XX_I2S_SEL_REG, &sysRead); err = Tfa98xx_ReadRegister16(handleIn, TFA98XX_SYS_CTRL, &sysCtrlRead); err = Tfa98xx_ReadRegister16(handleIn, TFA98XX_BAT_PROT, &batProtRead); i2SRead &= ~(TFA98XX_I2SREG_CHSA_MSK); /* Set CHSA to bypass DSP */ sysRead &= ~(TFA98XX_I2S_SEL_REG_DCFG_MSK);/* Set DCDC compensation to off */ sysRead |= TFA98XX_I2S_SEL_REG_SPKR_MSK; /* Set impedance as 8ohm */ sysCtrlRead &= ~(TFA98XX_SYS_CTRL_DCA_MSK);/* Set DCDC to follower mode */ sysCtrlRead &= ~(TFA98XX_SYS_CTRL_CFE_MSK);/* Disable coolflux */ batProtRead |= TFA989X_BAT_PROT_BSSBY_MSK;/* Set clipper bypassed */ /* Set CHSA to bypass DSP */ err = Tfa98xx_WriteRegister16(handleIn, TFA98XX_I2SREG, i2SRead); /* Set DCDC compensation to off and set impedance as 8ohm */ err = Tfa98xx_WriteRegister16(handleIn, TFA98XX_I2S_SEL_REG, sysRead); /* Set DCDC to follower mode and disable coolflux */ err = Tfa98xx_WriteRegister16(handleIn, TFA98XX_SYS_CTRL, sysCtrlRead); /* Set bypass clipper battery protection */ err = Tfa98xx_WriteRegister16(handleIn, TFA98XX_BAT_PROT, batProtRead); return err; }
static void waitCalibration(Tfa98xx_handle_t handle, int *calibrateDone) { enum Tfa98xx_Error err; int tries = 0; unsigned short mtp; unsigned short spkrCalibration; #define WAIT_TRIES 1000 err = Tfa98xx_ReadRegister16(handle, TFA98XX_MTP, &mtp); /* in case of calibrate once wait for MTPEX */ if (mtp & TFA98XX_MTP_MTPOTC) { while ((*calibrateDone == 0) && (tries < WAIT_TRIES)) { err = Tfa98xx_ReadRegister16(handle, TFA98XX_MTP, &mtp); /* check MTP bit1 (MTPEX) */ *calibrateDone = (mtp & TFA98XX_MTP_MTPEX); tries++; } } else { /* poll xmem for calibrate always */ while ((*calibrateDone == 0) && (tries < WAIT_TRIES)) { /* TODO optimise with wait estimation */ err = Tfa98xx_DspReadMem(handle, 231, 1, calibrateDone); tries++; } if (tries == WAIT_TRIES) pr_err("%s: calibrateDone 231 timedout\n", __func__); } err = Tfa98xx_ReadRegister16(handle, TFA98XX_SPKR_CALIBRATION, &spkrCalibration); if (err != Tfa98xx_Error_Ok) { pr_err("%s: Tfa98xx_ReadRegister16 failed %d\n", __func__, err); return; } spkrCalibration &= ~(TFA98XX_SPKR_CALIBRATION_TROS_MSK); err = Tfa98xx_WriteRegister16(handle, TFA98XX_SPKR_CALIBRATION, spkrCalibration); if (err != Tfa98xx_Error_Ok) { pr_err("%s: Tfa98xx_WriteRegister16 failed %d\n", __func__, err); return; } }
/* * 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; }
Tfa98xx_Error_t Tfa9890_specific(Tfa98xx_handle_t handle) { Tfa98xx_Error_t error = Tfa98xx_Error_Ok; unsigned short value; ALOGD("[%s][%s] 2", __FILE__, __func__); if (!handle_is_open(handle)) return Tfa98xx_Error_NotOpen; /* reset all i2C registers to default */ error = Tfa98xx_WriteRegister16(handle, 0x09, 0x0002); if (Tfa98xx_Error_Ok == error) { error = Tfa98xx_ReadRegister16(handle, 0x09, &value); } if (Tfa98xx_Error_Ok == error) { /* DSP must be in control of the amplifier to avoid plops */ value |= TFA98XX_SYS_CTRL_AMPE_POS; error = Tfa98xx_WriteRegister16(handle, 0x09, value); } /* some other registers must be set for optimal amplifier behaviour */ if (Tfa98xx_Error_Ok == error) { error = Tfa98xx_WriteRegister16(handle, 0x06, 0x000F); // not for n1c } if (Tfa98xx_Error_Ok == error) { error = Tfa98xx_WriteRegister16(handle, 0x07, 0x8FFF); // not for n1c } if (Tfa98xx_Error_Ok == error) { error = Tfa98xx_WriteRegister16(handle, 0x08, 0x7832); // change for n1c } if (Tfa98xx_Error_Ok == error) { error = Tfa98xx_WriteRegister16(handle, 0x09, 0x824D); } if (Tfa98xx_Error_Ok == error) { error = Tfa98xx_WriteRegister16(handle, 0x0A, 0x38E5); // not for n1c } if (Tfa98xx_Error_Ok == error) { error = Tfa98xx_WriteRegister16(handle, 0x0E, 0x0F01);// not for n1c } if (Tfa98xx_Error_Ok == error) { error = Tfa98xx_WriteRegister16(handle, 0x46, 0x4000);// not for n1c } if (Tfa98xx_Error_Ok == error) { error = Tfa98xx_WriteRegister16(handle, 0x47, 0x5901); } if (Tfa98xx_Error_Ok == error) { error = Tfa98xx_WriteRegister16(handle, 0x48, 0x06C0); } if (Tfa98xx_Error_Ok == error) { error = Tfa98xx_WriteRegister16(handle, 0x49, 0xAD93); } return error; }
static void setOtc(Tfa98xx_handle_t handle, int otcOn) { enum Tfa98xx_Error err; unsigned short mtp; unsigned short status; unsigned short spkrCalibration; int mtpChanged = 0; int timeout; err = Tfa98xx_ReadRegister16(handle, TFA98XX_SPKR_CALIBRATION, &spkrCalibration); if (err != Tfa98xx_Error_Ok) { pr_err("%s: Tfa98xx_ReadRegister16 failed %d\n", __func__, err); return; } spkrCalibration |= TFA98XX_SPKR_CALIBRATION_TROS_MSK; spkrCalibration &= ~(TFA98XX_SPKR_CALIBRATION_EXTTS_MSK); spkrCalibration |= (SPKR_CALIBRATION_EXTTS_VALUE << TFA98XX_SPKR_CALIBRATION_EXTTS_POS); err = Tfa98xx_WriteRegister16(handle, TFA98XX_SPKR_CALIBRATION, spkrCalibration); if (err != Tfa98xx_Error_Ok) { pr_err("%s: Tfa98xx_WriteRegister16 failed %d\n", __func__, err); return; } err = Tfa98xx_ReadRegister16(handle, TFA98XX_MTP, &mtp); if (err != Tfa98xx_Error_Ok) { pr_err("%s: Tfa98xx_DspReset failed %d\n", __func__, err); return; } if ((otcOn != 0) && (otcOn != 1)) { pr_err("%s: Tfa98xx_ReadRegister16 failed %d\n", __func__, err); return; } /* set reset MTPEX bit if needed */ if ((mtp & TFA98XX_MTP_MTPOTC) != otcOn) { /* need to change the OTC bit, set MTPEX=0 in any case */ /* unlock key2 */ err = Tfa98xx_WriteRegister16(handle, 0x0B, 0x5A); if (err != Tfa98xx_Error_Ok) { pr_err("%s: Tfa98xx_DspReset failed %d\n", __func__, err); return; } /* MTPOTC=otcOn, MTPEX=0 */ err = Tfa98xx_WriteRegister16(handle, TFA98XX_MTP, (unsigned short)otcOn); if (err != Tfa98xx_Error_Ok) { pr_err("%s: Tfa98xx_DspReset failed %d\n", __func__, err); return; } /* CIMTP=1 */ err = Tfa98xx_WriteRegister16(handle, 0x62, 1<<11); if (err != Tfa98xx_Error_Ok) { pr_err("%s: Tfa98xx_DspReset failed %d\n", __func__, err); return; } mtpChanged = 1; } timeout = 0; do { msleep(20); err = Tfa98xx_ReadRegister16(handle, TFA98XX_STATUSREG, &status); pr_info("%s %04x\n", __func__, status); if (err != Tfa98xx_Error_Ok) { pr_err("%s: Tfa98xx_DspReset failed %d\n", __func__, err); return; } timeout++; if (timeout > 50) { pr_info("%s timeout\n", __func__); break; } } while ((status & TFA98XX_STATUSREG_MTPB_MSK) == TFA98XX_STATUSREG_MTPB_MSK); }
static void coldStartup(Tfa98xx_handle_t handle) { enum Tfa98xx_Error err; unsigned short status; int ready = 0; int timeout; unsigned short dcdcRead = 0; unsigned short dcdcBoost = 0; /* load the optimal TFA98xx in HW settings */ err = Tfa98xx_Init(handle); if (err != Tfa98xx_Error_Ok) { pr_err("%s: Tfa98xx_Init failed %d\n", __func__, err); return; } /* NXP SL: Sample rate should be set before power up */ /* Set sample rate to example 48000*/ err = Tfa98xx_SetSampleRate(handle, SAMPLE_RATE); if (err != Tfa98xx_Error_Ok) pr_err("%s: Tfa98xx_SetSampleRate failed %d\n", __func__, err); /* Power On the device by setting bit 0 to 0 of register 9*/ err = Tfa98xx_Powerdown(handle, 0); if (err != Tfa98xx_Error_Ok) { pr_err("%s: Tfa98xx_Powerdown failed %d\n", __func__, err); return; } /* set Max boost coil current 1.92 A */ err = Tfa98xx_ReadRegister16(handle, TFA98XX_DCDCBOOST, &dcdcRead); dcdcRead &= ~(TFA98XX_DCDCBOOST_DCMCC_MSK); dcdcRead |= (3 << TFA98XX_DCDCBOOST_DCMCC_POS); err = Tfa98xx_WriteRegister16(handle, TFA98XX_DCDCBOOST, dcdcRead); /* set Max boost voltage 7.5 V */ err = Tfa98xx_ReadRegister16(handle, TFA98XX_DCDCBOOST, &dcdcBoost); dcdcBoost &= ~(TFA98XX_DCDCBOOST_DCVO_MSK); dcdcBoost |= 3; err = Tfa98xx_WriteRegister16(handle, TFA98XX_DCDCBOOST, dcdcBoost); /* Check the PLL is powered up from status register 0*/ err = Tfa98xx_ReadRegister16(handle, TFA98XX_STATUSREG, &status); if (err != Tfa98xx_Error_Ok) { pr_err("%s: Tfa98xx_ReadRegister16 failed %d\n", __func__, err); return; } timeout = 0; while ((status & TFA98XX_STATUSREG_AREFS_MSK) == 0) { /* not ok yet */ err = Tfa98xx_ReadRegister16(handle, TFA98XX_STATUSREG, &status); if (err != Tfa98xx_Error_Ok) { pr_err("%s: Tfa98xx_ReadRegister16 failed %d\n", __func__, err); return; } msleep(20); timeout++; if (timeout > 50) { pr_info("%s timeout status:%x\n", __func__, status); break; } } /* powered on * - now it is allowed to access DSP specifics * - stall DSP by setting reset * */ err = Tfa98xx_DspReset(handle, 1); if (err != Tfa98xx_Error_Ok) { pr_err("%s: Tfa98xx_DspReset failed %d\n", __func__, err); return; } /* wait until the DSP subsystem hardware is ready * note that the DSP CPU is not running yet (RST=1) * */ timeout = 0; while (ready == 0) { /* are we ready? */ err = Tfa98xx_DspSystemStable(handle, &ready); if (err != Tfa98xx_Error_Ok) { pr_err("%s: Tfa98xx_DspSystemStable failed %d\n", __func__, err); return; } msleep(20); timeout++; if (timeout > 50) { pr_info("%s timeout ready:%d\n", __func__, ready); break; } } /* Load cold-boot patch for the first time to force cold start-up. * use the patchload only to write the internal register * */ dspPatch(handle, &patch_data[PATCH_COLDBOOT]); err = Tfa98xx_ReadRegister16(handle, TFA98XX_STATUSREG, &status); if (err != Tfa98xx_Error_Ok) { pr_err("%s: Tfa98xx_ReadRegister16 failed %d\n", __func__, err); return; } if ((status & TFA98XX_STATUSREG_ACS_MSK) == 0) { pr_err("%s: status & TFA98XX_STATUSREG_ACS_MSK == 0\n", __func__); return; } /* cold boot, need to load all parameters and patches */ /* patch the ROM code */ dspPatch(handle, &patch_data[PATCH_DSP]); }