/*
 * initTfa9888.c
 *
 *  Created on: Jun 26, 2014
 *      Author: wim
 */

#include "tfa_dsp_fw.h"
#include "tfa_service.h"
#include "tfa_internal.h"

#include "tfa98xx_tfafieldnames.h"


static enum Tfa98xx_Error tfa9888_specific(Tfa98xx_handle_t handle) {
	enum Tfa98xx_Error error = Tfa98xx_Error_Ok;
	unsigned short value, xor;

	if (!tfa98xx_handle_is_open(handle))
		return Tfa98xx_Error_NotOpen;

	if ((handles_local[handle].rev & 0xff) != 0x88) {
		pr_err("This code is not for this device type: %x\n", handles_local[handle].rev);
		return Tfa98xx_Error_Bad_Parameter;
	}

	/* Unlock keys to write settings */
	error = tfa98xx_write_register16(handle, 0x0F, 0x5A6B);
	error = tfa98xx_read_register16(handle, 0xFB, &value);
	xor = value ^ 0x005A;
	error = tfa98xx_write_register16(handle, 0xA0, xor);

	/* The optimal settings are different for 1c, 2c, 3b and 2b/1b */
	if (handles_local[handle].rev == 0x2c88) {	
		/* ----- generated code start ----- */
		/* --------- Version v1 ---------- */
		tfa98xx_write_register16(handle, 0x00, 0x164d); //POR=0x064d
		tfa98xx_write_register16(handle, 0x01, 0x828b); //POR=0x92cb
		tfa98xx_write_register16(handle, 0x02, 0x1dc8); //POR=0x1828
		tfa98xx_write_register16(handle, 0x0e, 0x0080); //POR=0x0000
		tfa98xx_write_register16(handle, 0x20, 0x089e); //POR=0x0890
		tfa98xx_write_register16(handle, 0x22, 0x543c); //POR=0x545c
		tfa98xx_write_register16(handle, 0x23, 0x0006); //POR=0x0000
		tfa98xx_write_register16(handle, 0x24, 0x0014); //POR=0x0000
		tfa98xx_write_register16(handle, 0x25, 0x000a); //POR=0x0000
		tfa98xx_write_register16(handle, 0x26, 0x0100); //POR=0x0000
		tfa98xx_write_register16(handle, 0x28, 0x1000); //POR=0x0000
		tfa98xx_write_register16(handle, 0x51, 0x0000); //POR=0x00c0
		tfa98xx_write_register16(handle, 0x52, 0xfafe); //POR=0xbaf6
		tfa98xx_write_register16(handle, 0x70, 0x3ee4); //POR=0x3ee6
		tfa98xx_write_register16(handle, 0x71, 0x1074); //POR=0x3074
		tfa98xx_write_register16(handle, 0x83, 0x0014); //POR=0x0013
		/* ----- generated code end   ----- */
	} else if (handles_local[handle].rev == 0x1c88) {
		/* ----- generated code start ----- */
		/* --------- Version v6 ---------- */
		tfa98xx_write_register16(handle, 0x00, 0x164d); //POR=0x064d
		tfa98xx_write_register16(handle, 0x01, 0x828b); //POR=0x92cb
		tfa98xx_write_register16(handle, 0x02, 0x1dc8); //POR=0x1828
		tfa98xx_write_register16(handle, 0x0e, 0x0080); //POR=0x0000
		tfa98xx_write_register16(handle, 0x20, 0x089e); //POR=0x0890
		tfa98xx_write_register16(handle, 0x22, 0x543c); //POR=0x545c
		tfa98xx_write_register16(handle, 0x23, 0x0006); //POR=0x0000
		tfa98xx_write_register16(handle, 0x24, 0x0014); //POR=0x0000
		tfa98xx_write_register16(handle, 0x25, 0x000a); //POR=0x0000
		tfa98xx_write_register16(handle, 0x26, 0x0100); //POR=0x0000
		tfa98xx_write_register16(handle, 0x28, 0x1000); //POR=0x0000
		tfa98xx_write_register16(handle, 0x51, 0x0000); //POR=0x00c0
		tfa98xx_write_register16(handle, 0x52, 0xfafe); //POR=0xbaf6
		tfa98xx_write_register16(handle, 0x70, 0x3ee4); //POR=0x3ee6
		tfa98xx_write_register16(handle, 0x71, 0x1074); //POR=0x3074
		tfa98xx_write_register16(handle, 0x83, 0x0014); //POR=0x0013
		/* ----- generated code end   ----- */
	} else if (handles_local[handle].rev == 0x3b88) {
		/* ----- generated code start ----- */
		/* --------- Version v20 ---------- */
		tfa98xx_write_register16(handle, 0x01, 0x828b); //POR=0x92cb
		tfa98xx_write_register16(handle, 0x02, 0x1dc8); //POR=0x1828
		tfa98xx_write_register16(handle, 0x20, 0x089e); //POR=0x0890
		tfa98xx_write_register16(handle, 0x22, 0x543c); //POR=0x545c
		tfa98xx_write_register16(handle, 0x23, 0x0c06); //POR=0x0000
		tfa98xx_write_register16(handle, 0x24, 0x0014); //POR=0x0000
		tfa98xx_write_register16(handle, 0x25, 0x000a); //POR=0x0000
		tfa98xx_write_register16(handle, 0x26, 0x0100); //POR=0x0000
		tfa98xx_write_register16(handle, 0x28, 0x1000); //POR=0x0000
		tfa98xx_write_register16(handle, 0x51, 0x0000); //POR=0x00c0
		tfa98xx_write_register16(handle, 0x52, 0xfafe); //POR=0xbaf6
		tfa98xx_write_register16(handle, 0x58, 0x1e1c); //POR=0x161c
		tfa98xx_write_register16(handle, 0x70, 0x3ee4); //POR=0x3ee6
		tfa98xx_write_register16(handle, 0x71, 0x1074); //POR=0x3074
		tfa98xx_write_register16(handle, 0x83, 0x0014); //POR=0x0013
		/* ----- generated code end   ----- */
	} else {
		/* If not 1c or 3b assume older version */
		/* ----- generated code start ----- */
		/* --------- Version v19 ---------- */
		tfa98xx_write_register16(handle, 0x00, 0x1e5d); //POR=0x064d
		tfa98xx_write_register16(handle, 0x01, 0x828b); //POR=0x92cb
		tfa98xx_write_register16(handle, 0x20, 0x089e); //POR=0x0890
		tfa98xx_write_register16(handle, 0x23, 0x0c06); //POR=0x0000
		tfa98xx_write_register16(handle, 0x24, 0x0014); //POR=0x0000
		tfa98xx_write_register16(handle, 0x25, 0x000a); //POR=0x0000
		tfa98xx_write_register16(handle, 0x26, 0x0100); //POR=0x0000
		tfa98xx_write_register16(handle, 0x28, 0x1000); //POR=0x0000
		tfa98xx_write_register16(handle, 0x51, 0x0000); //POR=0x00c0
		tfa98xx_write_register16(handle, 0x52, 0x9ae2); //POR=0xbaf6
		tfa98xx_write_register16(handle, 0x58, 0x1e1c); //POR=0x161c
		tfa98xx_write_register16(handle, 0x70, 0x3ce6); //POR=0x3ee6
		tfa98xx_write_register16(handle, 0x71, 0x1074); //POR=0x3074
		tfa98xx_write_register16(handle, 0x83, 0x0014); //POR=0x0013
		/* ----- generated code end   ----- */
	}

	return error;
}

static enum Tfa98xx_Error tfa9888_tfa_dsp_write_tables(Tfa98xx_handle_t handle, int sample_rate) 
{
	unsigned char buffer[15] = {0};
	int size = 15 * sizeof(char);

	/* Write the fractional delay in the hardware register 'cs_frac_delay' */
	switch(sample_rate) {
		case 0:	/* 8kHz */
			TFA_SET_BF(handle, FRACTDEL, 40);
			break;
		case 1:	/* 11.025KHz */
			TFA_SET_BF(handle, FRACTDEL, 38);
			break;
		case 2:	/* 12kHz */
			TFA_SET_BF(handle, FRACTDEL, 37);
			break;
		case 3:	/* 16kHz */
			TFA_SET_BF(handle, FRACTDEL, 59);
			break;
		case 4:	/* 22.05KHz */
			TFA_SET_BF(handle, FRACTDEL, 56);
			break;
		case 5:	/* 24kHz */
			TFA_SET_BF(handle, FRACTDEL, 56);
			break;
		case 6:	/* 32kHz */
			TFA_SET_BF(handle, FRACTDEL, 52);
			break;
		case 7:	/* 44.1kHz */
			TFA_SET_BF(handle, FRACTDEL, 48);
			break;
		case 8:
		default:/* 48kHz */
			TFA_SET_BF(handle, FRACTDEL, 46);
			break;
	}

	/* First copy the msg_id to the buffer */
        buffer[0] = (uint8_t) 0;
        buffer[1] = (uint8_t) MODULE_FRAMEWORK + 128;
        buffer[2] = (uint8_t) FW_PAR_ID_SET_SENSES_DELAY;

        /* Required for all FS exept 8kHz (8kHz is all zero) */
	if(sample_rate != 0) {
		buffer[5] = 1;	/* Vdelay_P */
		buffer[8] = 0;	/* Idelay_P */
		buffer[11] = 1; /* Vdelay_S */
		buffer[14] = 0; /* Idelay_S */
	}

	/* send SetSensesDelay msg */
	return tfa_dsp_msg(handle, size, (char *)buffer);
}

/*
 * register device specifics functions
 */
void tfa9888_ops(struct tfa_device_ops *ops) {
	ops->tfa_init = tfa9888_specific;
	ops->tfa_dsp_write_tables=tfa9888_tfa_dsp_write_tables;
}
