⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 codec.c

📁 u-boot-1.1.6 源码包
💻 C
📖 第 1 页 / 共 3 页
字号:
	codsp_write_sop_short(duslic_id, channel, OFR1_ADDR, 0x0000);	codsp_set_slic(duslic_id, channel, SS_RING_PAUSE); /* Start Ringing */	/* select source for the levelmeter to be IO4-IO3 */	codsp_write_sop_char(duslic_id, channel, LMCR2_ADDR, LMCR2_LM_SEL_IO4_MINUS_IO3);	udelay(40000);	/* Before Enabling Level Meter Programm the apropriate shift factor K_INTDC=(4 if Rectifier Enabled and 2 if Rectifier Disabled) */	codsp_write_cop_char(duslic_id, channel, RING_PARAMS_START_ADDR + 7, K_INTDC_RECT_OFF);	udelay(10000);	/* Enable LevelMeter to Integrate only once (Rectifier Disabled) */	codsp_write_sop_char(duslic_id, channel,			LMCR1_ADDR, LMCR1_LM_THM | LMCR1_LM_MASK | LMCR1_LM_EN | LMCR1_LM_ONCE);	udelay(40000); /* Integration Period == Ring Period = 40ms (for 25Hz Ring) */	if (wait_level_metering_finish(duslic_id, channel)) {		udelay(10000); /* To be sure that Integration Results are Valid wait at least 500us !!! */		/* Now Read the LM Result Registers (Will be valid until LM_EN becomes zero again( after that the Result is updated every 500us) ) */		Offset_Compensation = codsp_read_sop_short(duslic_id, channel, LMRES1_ADDR);		Offset_Compensation = (-1) * ((Offset_Compensation * (1 << K_INTDC_RECT_OFF)) / N_SAMPLES);		/* Disable LevelMeter ==> In order to be able to restart Integrator again (for the next integration) */		codsp_write_sop_char(duslic_id, channel, LMCR1_ADDR, LMCR1_LM_THM | LMCR1_LM_MASK | LMCR1_LM_ONCE);		/* Now programm Integrator Offset Registers !!! */		codsp_write_sop_short(duslic_id, channel, OFR1_ADDR, Offset_Compensation);		codsp_set_slic(duslic_id, channel, SS_RINGING); /* Start Ringing */		udelay(40000);		/* Reenable Level Meter Integrator (The Result will be valid after Integration Period=Ring Period and until LN_EN become zero again) */		codsp_write_sop_char(duslic_id, channel,				LMCR1_ADDR, LMCR1_LM_THM | LMCR1_LM_MASK | LMCR1_LM_EN | LMCR1_LM_ONCE);		udelay(40000); /* Integration Period == Ring Period = 40ms (for 25Hz Ring) */		/* Poll the LM_OK bit to see when Integration Result is Ready */		if (wait_level_metering_finish(duslic_id, channel)) {			udelay(10000); /* wait at least 500us to be sure that the Integration Result are valid !!! */			/* Now Read the LM Result Registers (They will hold their value until LM_EN become zero again */			/*				    ==>After that Result Regs will be updated every 500us !!!) */			LM_Result = codsp_read_sop_short(duslic_id, channel, LMRES1_ADDR);			V_in = (-1) * ( ( (((long int)LM_Result) * V_AD_x10000) / N_SAMPLES) >> (15 - K_INTDC_RECT_OFF)) ;  /* Vin x 10000*/			V_out = (V_in * Divider_Ratio) / 10000L ;	/* Vout x100 */			if (V_out < 0)				V_out= -V_out;			if (V_out > MAX_V_RING_MEANx100)				err_mask |= 8;			*ring_mean_v = V_out;		} else {			err_mask |= 8;			*ring_mean_v = 0;		}	} else {		err_mask |= 8;		*ring_mean_v = 0;	}	/* Disable LevelMeter ==> In order to be able to restart Integrator again (for the next integration) */	codsp_write_sop_char(duslic_id, channel, LMCR1_ADDR,		LMCR1_LM_THM | LMCR1_LM_MASK | LMCR1_LM_ONCE);	codsp_write_sop_short(duslic_id, channel, OFR1_ADDR, 0x0000);	codsp_set_slic(duslic_id, channel, SS_RING_PAUSE); /* Start Ringing */	/* Now Enable Rectifier */	/* select source for the levelmeter to be IO4-IO3 */	codsp_write_sop_char(duslic_id, channel, LMCR2_ADDR,		LMCR2_LM_SEL_IO4_MINUS_IO3 | LMCR2_LM_RECT);	/* Program the apropriate shift factor K_INTDC (in order to avoid Overflow at Integtation Result !!!) */	codsp_write_cop_char(duslic_id, channel, RING_PARAMS_START_ADDR + 7, K_INTDC_RECT_ON);	udelay(40000);	/* Reenable Level Meter Integrator (The Result will be valid after Integration Period=Ring Period and until LN_EN become zero again) */	codsp_write_sop_char(duslic_id, channel, LMCR1_ADDR,			LMCR1_LM_THM | LMCR1_LM_MASK | LMCR1_LM_EN | LMCR1_LM_ONCE);	udelay(40000);	/* Poll the LM_OK bit to see when Integration Result is Ready */	if (wait_level_metering_finish(duslic_id, channel)) {		udelay(10000);		/* Now Read the LM Result Registers (They will hold their value until LM_EN become zero again */		/*				    ==>After that Result Regs will be updated every 500us !!!) */		Offset_Compensation = codsp_read_sop_short(duslic_id, channel, LMRES1_ADDR);		Offset_Compensation = (-1) * ((Offset_Compensation * (1 << K_INTDC_RECT_ON)) / N_SAMPLES);		/* Disable LevelMeter ==> In order to be able to restart Integrator again (for the next integration) */		codsp_write_sop_char(duslic_id, channel, LMCR1_ADDR, LMCR1_LM_THM | LMCR1_LM_MASK | LMCR1_LM_ONCE);		/* Now programm Integrator Offset Registers !!! */		codsp_write_sop_short(duslic_id, channel, OFR1_ADDR, Offset_Compensation);		/* Be sure that a Ring is generated !!!! */		codsp_set_slic(duslic_id, channel, SS_RINGING); /* Start Ringing again */		udelay(40000);		/* Reenable Level Meter Integrator (The Result will be valid after Integration Period=Ring Period and until LN_EN become zero again) */		codsp_write_sop_char(duslic_id, channel, LMCR1_ADDR,				LMCR1_LM_THM | LMCR1_LM_MASK | LMCR1_LM_EN | LMCR1_LM_ONCE);		udelay(40000);		/* Poll the LM_OK bit to see when Integration Result is Ready */		if (wait_level_metering_finish(duslic_id, channel)) {			udelay(10000);			/* Now Read the LM Result Registers (They will hold their value until LM_EN become zero again */			/*				    ==>After that Result Regs will be updated every 500us !!!) */			LM_Result = codsp_read_sop_short(duslic_id, channel, LMRES1_ADDR);			V_in = (-1) *  ( ( (((long int)LM_Result) * V_AD_x10000) / N_SAMPLES) >> (15 - K_INTDC_RECT_ON) ) ;  /* Vin x 10000*/			V_out = (((V_in * Divider_Ratio) / 10000L) * RMS_MULTIPLIERx100) / 100 ;	/* Vout_RMS x100 */			if (V_out < 0)				V_out = -V_out;			Vout_diff = (V_out - TARGET_V_RING_RMSx100);			if (Vout_diff < 0)				Vout_diff = -Vout_diff;			if (Vout_diff > V_RMS_RING_MAX_DIFFx100)				err_mask |= 16;			*ring_rms_v = V_out;		} else {			err_mask |= 16;			*ring_rms_v = 0;		}	} else {		err_mask |= 16;		*ring_rms_v = 0;	}	/* Disable LevelMeter ==> In order to be able to restart Integrator again (for the next integration) */	codsp_write_sop_char(duslic_id, channel, LMCR1_ADDR, LMCR1_LM_THM | LMCR1_LM_MASK);	retrieve_slic_state(slic_id);	return(err_mask);}int test_dtmf(int slic_id){	unsigned char code;	unsigned char b;	unsigned int intreg;	int duslic_id = slic_id >> 1;	int channel = slic_id & 1;	for (code = 0; code < 16; code++) {		b = codsp_read_sop_char(duslic_id, channel, DSCR_ADDR);		codsp_write_sop_char(duslic_id, channel, DSCR_ADDR,			(b & ~(DSCR_PTG | DSCR_DG_KEY(15))) | DSCR_DG_KEY(code) | DSCR_TG1_EN | DSCR_TG2_EN);		udelay(80000);		intreg = codsp_read_sop_int(duslic_id, channel, INTREG1_ADDR);		if ((intreg & CODSP_INTREG_INT_CH) == 0)			break;		if ((intreg & CODSP_INTREG_DTMF_OK) == 0 ||				codsp_dtmf_map[(intreg >> 10) & 15] != codsp_dtmf_map[code])			break;		b = codsp_read_sop_char(duslic_id, channel, DSCR_ADDR);		codsp_write_sop_char(duslic_id, channel, DSCR_ADDR,				b & ~(DSCR_COR8 | DSCR_TG1_EN | DSCR_TG2_EN));		udelay(80000);		intreg = codsp_read_sop_int(duslic_id, channel, INTREG1_ADDR); /* for dtmf_pause irq */	}	if (code != 16) {		b = codsp_read_sop_char(duslic_id, channel, DSCR_ADDR); /* stop dtmf */		codsp_write_sop_char(duslic_id, channel, DSCR_ADDR,				b & ~(DSCR_COR8 | DSCR_TG1_EN | DSCR_TG2_EN));		return(1);	}	return(0);}void data_up_persist_time(int duslic_id, int channel, int time_ms){	unsigned char b;	b = codsp_read_sop_char(duslic_id, channel, IOCTL3_ADDR);	b = (b & 0x0F) | ((time_ms & 0x0F) << 4);	codsp_write_sop_char(duslic_id, channel, IOCTL3_ADDR, b);}static void program_dtmf_params(int duslic_id, int channel){	unsigned char b;	codsp_write_pop_char(duslic_id, channel, DTMF_LEV_ADDR, 0x10);	codsp_write_pop_char(duslic_id, channel, DTMF_TWI_ADDR, 0x0C);	codsp_write_pop_char(duslic_id, channel, DTMF_NCF_H_ADDR, 0x79);	codsp_write_pop_char(duslic_id, channel, DTMF_NCF_L_ADDR, 0x10);	codsp_write_pop_char(duslic_id, channel, DTMF_NBW_H_ADDR, 0x02);	codsp_write_pop_char(duslic_id, channel, DTMF_NBW_L_ADDR, 0xFB);	codsp_write_pop_char(duslic_id, channel, DTMF_GAIN_ADDR, 0x91);	codsp_write_pop_char(duslic_id, channel, DTMF_RES1_ADDR, 0x00);	codsp_write_pop_char(duslic_id, channel, DTMF_RES2_ADDR, 0x00);	codsp_write_pop_char(duslic_id, channel, DTMF_RES3_ADDR, 0x00);	b = codsp_read_sop_char(duslic_id, channel, BCR5_ADDR);	codsp_write_sop_char(duslic_id, channel, BCR5_ADDR, b | BCR5_DTMF_EN);}static void codsp_channel_full_reset(int duslic_id, int channel){	program_coeffs(duslic_id, channel, ac_coeffs, sizeof(ac_coeffs) / sizeof(struct _coeffs));	program_coeffs(duslic_id, channel, dc_coeffs, sizeof(dc_coeffs) / sizeof(struct _coeffs));	/* program basic configuration registers */	codsp_write_sop_char(duslic_id, channel, BCR1_ADDR, 0x01);	codsp_write_sop_char(duslic_id, channel, BCR2_ADDR, 0x41);	codsp_write_sop_char(duslic_id, channel, BCR3_ADDR, 0x43);	codsp_write_sop_char(duslic_id, channel, BCR4_ADDR, 0x00);	codsp_write_sop_char(duslic_id, channel, BCR5_ADDR, 0x00);	codsp_write_sop_char(duslic_id, channel, DSCR_ADDR, 0x04);		/* PG */	program_dtmf_params(duslic_id, channel);	codsp_write_sop_char(duslic_id, channel, LMCR3_ADDR, 0x40);	/* RingTRip_SEL */	data_up_persist_time(duslic_id, channel, 4);	codsp_write_sop_char(duslic_id, channel, MASK_ADDR, 0xFF);     /* All interrupts masked */	codsp_set_slic(duslic_id, channel, SS_ACTIVE_HIGH);}static int codsp_chip_full_reset(int duslic_id){	int i, cnt;	int intreg[NUM_CHANNELS];	unsigned char pcm_resync;	unsigned char revision;	codsp_reset_chip(duslic_id);	udelay(2000);	for (i = 0; i < NUM_CHANNELS; i++)		intreg[i] = codsp_read_sop_int(duslic_id, i, INTREG1_ADDR);	udelay(1500);	if (_PORTC_GET(com_hook_mask_tab[duslic_id]) == 0) {		printf("_HOOK(%d) stayed low\n", duslic_id);		return -1;	}	for (pcm_resync = 0, i = 0; i < NUM_CHANNELS; i++) {		if (intreg[i] & CODSP_INTREG_SYNC_FAIL)			pcm_resync |= 1 << i;	}	for (cnt = 0; cnt < 5 && pcm_resync; cnt++) {		for (i = 0; i < NUM_CHANNELS; i++)			codsp_resync_channel(duslic_id, i);		udelay(2000);		pcm_resync = 0;		for (i = 0; i < NUM_CHANNELS; i++) {			if (codsp_read_sop_int(duslic_id, i, INTREG1_ADDR) & CODSP_INTREG_SYNC_FAIL)				pcm_resync |= 1 << i;		}	}	if (cnt == 5) {		printf("PCM_Resync(%u) not completed\n", duslic_id);		return -2;	}	revision = codsp_read_sop_char(duslic_id, 0, REVISION_ADDR);	printf("DuSLIC#%d hardware version %d.%d\r\n", duslic_id, (revision & 0xF0) >> 4, revision & 0x0F);	codsp_write_sop_char(duslic_id, 0, XCR_ADDR, 0x80);	/* EDSP_EN */	for (i = 0; i < NUM_CHANNELS; i++) {		codsp_write_sop_char(duslic_id, i, PCMC1_ADDR, 0x01);		codsp_channel_full_reset(duslic_id, i);	}	return 0;}int slic_self_test(int duslic_mask){	int slic;	int i;	int r;	long vdd, v_oh_H, v_oh_L, ring_mean_v, ring_rms_v;	const char *err_txt[] = { "VDD", "V_OH_H", "V_OH_L", "V_RING_MEAN", "V_RING_RMS" };	int error = 0;	for (slic = 0; slic < MAX_SLICS; slic++) { /* voltages self test */		if (duslic_mask & (1 << (slic >> 1))) {			r = measure_on_hook_voltages(slic, &vdd,				&v_oh_H, &v_oh_L, &ring_mean_v, &ring_rms_v);			printf("SLIC %u measured voltages (x100):\n\t"				    "VDD = %ld\tV_OH_H = %ld\tV_OH_L = %ld\tV_RING_MEAN = %ld\tV_RING_RMS = %ld\n",				    slic, vdd, v_oh_H, v_oh_L, ring_mean_v, ring_rms_v);			if (r != 0)				error |= 1 << slic;			for (i = 0; i < 5; i++)				if (r & (1 << i))					printf("\t%s out of range\n", err_txt[i]);		}	}	for (slic = 0; slic < MAX_SLICS; slic++) { /* voice path self test */		if (duslic_mask & (1 << (slic >> 1))) {			printf("SLIC %u VOICE PATH...CHECKING", slic);			printf("\rSLIC %u VOICE PATH...%s\n", slic,				(r = test_dtmf(slic)) != 0 ? "FAILED  " : "PASSED  ");			if (r != 0)				error |= 1 << slic;		}	}	return(error);}#if defined(CONFIG_NETTA_ISDN)#define SPIENS1		(1 << (31 - 15))#define SPIENS2		(1 << (31 - 19))static const int spiens_mask_tab[2] = { SPIENS1, SPIENS2 };int s_initialized = 0;static inline unsigned int s_transfer_internal(int s_id, unsigned int address, unsigned int value){	unsigned int rx, v;	_PORTB_SET(spiens_mask_tab[s_id], 0);	rx = __SPI_Transfer(address);	switch (address & 0xF0) {	case 0x60:	/* write byte register */	case 0x70:		rx = __SPI_Transfer(value);		break;	case 0xE0:	/* read R6 register */		v = __SPI_Transfer(0);		rx = (rx << 8) | v;		break;	case 0xF0:	/* read byte register */		rx = __SPI_Transfer(0);		break;	}	_PORTB_SET(spiens_mask_tab[s_id], 1);	return rx;}static void s_write_BR(int s_id, unsigned int regno, unsigned int val){	unsigned int address;	unsigned int v;	address = 0x70 | (regno & 15);	val &= 0xff;	v = s_transfer_internal(s_id, address, val);}static void s_write_OR(int s_id, unsigned int regno, unsigned int val){	unsigned int address;	unsigned int v;	address = 0x70 | (regno & 15);	val &= 0xff;	v = s_transfer_internal(s_id, address, val);}static void s_write_NR(int s_id, unsigned int regno, unsigned int val){	unsigned int address;	unsigned int v;	address = (regno & 7) << 4;	val &= 0xf;	v = s_transfer_internal(s_id, address | val, 0x00);}#define BR7_IFR			0x08	/* IDL2 free run */#define BR7_ICSLSB		0x04	/* IDL2 clock speed LSB */#define BR15_OVRL_REG_EN	0x80#define OR7_D3VR		0x80	/* disable 3V regulator */#define OR8_TEME		0x10	/* TE mode enable */#define OR8_MME			0x08	/* master mode enable */void s_initialize(void){	int s_id;	for (s_id = 0; s_id < 2; s_id++) {		s_write_BR(s_id, 7, BR7_IFR | BR7_ICSLSB);		s_write_BR(s_id, 15, BR15_OVRL_REG_EN);		s_write_OR(s_id, 8, OR8_TEME | OR8_MME);		s_write_OR(s_id, 7, OR7_D3VR);		s_write_OR(s_id, 6, 0);		s_write_BR(s_id, 15, 0);		s_write_NR(s_id, 3, 0);	}}#endifint board_post_codec(int flags){	int j;	int r;	int duslic_mask;	printf("board_post_dsp\n");#if defined(CONFIG_NETTA_ISDN)	if (s_initialized == 0) {		s_initialize();		s_initialized = 1;		printf("s_initialized\n");		udelay(20000);	}#endif	duslic_mask = 0;	for (j = 0; j < MAX_DUSLIC; j++) {		if (codsp_chip_full_reset(j) < 0)			printf("Error initializing DuSLIC#%d\n", j);		else			duslic_mask |= 1 << j;	}	if (duslic_mask != 0) {		printf("Testing SLICs...\n");		r = slic_self_test(duslic_mask);		for (j = 0; j < MAX_SLICS; j++) {			if (duslic_mask & (1 << (j >> 1)))				printf("SLIC %u...%s\n", j, r & (1 << j) ? "FAULTY" : "OK");		}	}	printf("DuSLIC self test finished\n");	return 0;	/* return -1 on error */}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -