示例#1
0
/*
 * process all items in the profilelist
 * NOTE an error return during processing will leave the device muted
 */
int tfaContWriteProfile(struct tfa98xx *tfa98xx, int profile, int vstep)
{
    struct nxpTfaProfile *prof = tfaContProfile(tfa98xx, profile);
    struct nxpTfaFileDsc *file;
    u8 *base = tfa98xx->fw.base;
    int i, pwdn=-1;

    if (!prof) {
        return -EINVAL;
    }

    if (tfa98xx->profile_current != profile ) {
        /* profile switch so mute first */
        tfa98xx_mute(tfa98xx);
    }

    tfa98xx->profile_current = profile;
    tfa98xx->vstep = tfa98xx->profiles[profile].vstep;

    /*
     * process the list and write all registers,
     * if a file is encountered then see if we need to poweron first
     */
    for(i = 0; i < prof->length; i++) {
        if (prof->list[i].type == dscFile) {
            if (pwdn < 0)
                pwdn = tfa98xx_is_pwdn(tfa98xx) ;

            if (pwdn) {
                tfa98xx_dsp_power_up(tfa98xx);
                pwdn=0;
            }

            file = (struct nxpTfaFileDsc *)(prof->list[i].offset + base);
            if (tfaContWriteFile(tfa98xx, file) ) {
                return -EINVAL;
            }
        } else {
            /* process and write all non-file items */
            if (tfaContWriteItem(tfa98xx, &prof->list[i]))
                return -EINVAL;
        }
    }

    tfa98xx_unmute(tfa98xx);
    return 0;
}
static ssize_t tfa98xx_state_show(struct device *dev, struct device_attribute *attr,
		char *buf)
{
    struct snd_soc_codec *codec;
    struct tfa98xx *tfa98xx;
    unsigned short mtp;
	unsigned short status;
    int done = 0;
    u32 re25 = 0;
    int try = 0;
    u16 mtp0;

    if(g_tfa98xx == NULL)
    {
        pr_err("%s g_tfa98xx = NULL\n",__func__);
        return 0;
    }

    tfa98xx = g_tfa98xx;
    codec = tfa98xx->codec;

    mutex_lock(&tfa98xx->dsp_init_lock);

#ifdef VENDOR_EDIT
/*[email protected], 2015-08-11, Modify for MTP recovery*/
        /*
	     * check the contents of  MTP register for non-zero,
	     * this indicates that the subsys is ready
	     */
	    mtp0 = (u16)snd_soc_read(codec, 0x84);

        /* NXP: if 0x84 is wrong, restore the correct mtp settings */
        if (!mtp0 || recoverMtp0)
        {
		    pr_err("%s mtp0 error,now recovery mtp.\n",__func__);
            if(recoverMtp0)
            {
                pr_err("%s mtp0 error detect in cold start up.\n",__func__);
                recoverMtp0 = false;
            }
            tfa98xx_restore_mtp(tfa98xx);
        }
#endif

	if (!tfa98xx_is_pwdn(tfa98xx)) {
		tfa98xx_dsp_stop(tfa98xx);
	}
    tfaRunColdStartup(tfa98xx);
    msleep(5);

    mtp = snd_soc_read(codec, TFA98XX_MTP);
	/* reset MTPEX bit if needed */
	if ( (mtp & TFA98XX_KEY2_PROTECTED_SPKR_CAL_MTP_MTPOTC) && (mtp & TFA98XX_KEY2_PROTECTED_SPKR_CAL_MTP_MTPEX))
	{
	    snd_soc_write(codec, 0x0B, 0x5A); /* unlock key2 */
        snd_soc_write(codec, TFA98XX_MTP, 1); /* MTPOTC=1, MTPEX=0 */
        snd_soc_write(codec, 0x62, 1<<11); /* CIMTP=1 */
    }

	do {
        try ++;
		msleep(10);
        status = snd_soc_read(codec, TFA98XX_STATUSREG);
	} while (((status & TFA98XX_STATUSREG_MTPB) == TFA98XX_STATUSREG_MTPB) && (try < 100));

    if(try == 100)
    {
        pr_err("%s try read TFA98XX_STATUSREG_MTPB time out\n",__func__);
        goto err;
    }

	if (!tfa98xx_is_pwdn(tfa98xx)) {
		tfa98xx_dsp_stop(tfa98xx);
	}
    msleep(10);
    tfa98xx->dsp_init = TFA98XX_DSP_INIT_RECOVER;
	/* start the DSP using the latest profile / vstep */
	if (!tfa98xx_dsp_start(tfa98xx, tfa98xx->profile, tfa98xx->vstep))
		tfa98xx->dsp_init = TFA98XX_DSP_INIT_DONE;

#ifdef VENDOR_EDIT
/*[email protected], 2015-08-11, Modify for MTP recovery*/
        /*
	     * check the contents of  MTP register for non-zero,
	     * this indicates that the subsys is ready
	     */
	    mtp0 = (u16)snd_soc_read(codec, 0x84);

        /* NXP: if 0x84 is wrong, restore the correct mtp settings */
        if (!mtp0 )
        {
		    pr_err("%s mtp0 error,now recovery mtp.\n",__func__);
            tfa98xx_restore_mtp(tfa98xx);
        }
#endif

    mtp = snd_soc_read(codec, TFA98XX_MTP);
	done = (mtp & TFA98XX_MTP_MTPEX);
    tfa98xx_dsp_get_calibration_impedance(tfa98xx, &re25);

    pr_debug("%s done =%d re=%d\n",__func__,done,re25);
    mutex_unlock(&tfa98xx->dsp_init_lock);
    return sprintf(buf,"%d:%d",done,re25);

err:
    pr_err("%s calibrate fail\n",__func__);
    mutex_unlock(&tfa98xx->dsp_init_lock);
    return sprintf(buf,"%d:%d",0,0);

}



static struct device_attribute tfa98xx_state_attr =
     __ATTR(calibra, 0444, tfa98xx_state_show, tfa98xx_state_store);

/*[email protected], 2015-11-05, add for debug*/
static ssize_t tfa98xx_Log_state_store(struct device *dev, struct device_attribute *attr,
		const char *buf, size_t count)
{
    pr_err("%s",__func__);

    if (sysfs_streq(buf, "LogOn"))
    {
        testLogOn = 1;
    }
    else if(sysfs_streq(buf, "LogOff"))
    {
        testLogOn = 0;
    }
    else
    {
        testLogOn = 0;
        count = -EINVAL;
    }
    return count;
}