Example #1
0
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, &reg);
        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, &regval);
                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;
}
Example #10
0
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]);
}