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

📄 clm_dspdrv.c

📁 这个才是朗讯的内置猫驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
/* *  CLModem v0.3.0 - Low level DSP routines * *  Copyright (C) 2000  Mikhail Moreyra * *  This file may be redistributed under the terms of the GNU Public *  License. */#define __NO_VERSION__#include <linux/kernel.h>#include <linux/module.h>#include <linux/wrapper.h>#include <asm/io.h>#include <asm/irq.h>#include "clm_config.h"#include "clm_data.h"#include "clm_dspdrv.h"#include "clm_modem.h"#define BUF_SIZE	4096extern int BaseIOAddress;extern int modem_irq;unsigned char current_command[40];unsigned char dsp_response_data[16];unsigned char Cdata[64];int hook = 1;int spkr_volume_level = 0;int spkr_on = 0;int _dsp_timer;volatile int dsp_done;int mt_x2_connection;int mt_v90_connection;int ack_or_response;int mt_v90_configured;volatile int v8_configured = 0;unsigned char line_mode = 0;unsigned short mt_RateSeq1;unsigned short mt_RateSeq2;unsigned short mt_RateSeq3;unsigned short mt_rate_seq_map, mt_set_rate_seq_param3;int mt_conn_orig = 1;int line_bit_rate;int call_progress_state = 0;int PcmEnabled = 0;int mt_IdleSendPwron = 0;volatile int mt_RingState = 0;char mt_call_progress;volatile char line_io_enabled = 0;volatile char dce_length_semaphore = 0;volatile char dce_status_semaphore = 0;volatile int dce_tx_count = 0;volatile int dce_rx_count = 0;volatile int dce_tx_interrupt_expected = 0;volatile unsigned char dce_tx_buffer[BUF_SIZE];volatile unsigned char dce_rx_buffer[BUF_SIZE];volatile int dce_tx_remove = 0;volatile int dce_rx_insert = 0;volatile int dte_rx_remove = 0;volatile int dte_tx_insert = 0;volatile int stat_tx_count = 0;volatile int stat_rx_count = 0;int dce_rx_errors = 0;unsigned char v8_tx_buffer[32];int sending_CM, sending_JM;int JM_received, CM_received;int CM_count, JM_count;unsigned char v8_tx_msg_size;volatile int jm_seq_match;int v8_status, length, old_length;int ci_count, v8_rx_msg_size;int RX_stat[32];int TX_stat[32];volatile int critical = 0;/* ************************************************ */void cmd_packet_callback(unsigned char x);void mt_CallProgressCallback(void);void line_int(void);void line_rx_int(void);void line_tx_int(void);void sync_rx_int(void);void sync_tx_int(void);void v8_rx_int(void);void v8_tx_int(void);/* ************************************************ */voidset_register(int reg, unsigned char val){    outb (val, BaseIOAddress + reg);}unsigned charget_register(int reg){    return inb (BaseIOAddress + reg);}/*************************************************//*		INTERRUPT HANDLER		 *//*************************************************/voiddspdrv_CommRamHandler(void){    unsigned char x, rv;    rv = get_register (0x0);    if (rv) {	x = dspdrv_GetCRAM (Cdata);	cmd_packet_callback (x);    }}voiddspdrv_CommRamISR(void){    critical = 1;    get_register (0xff);    dspdrv_CommRamHandler();    line_int();    critical = 0;}voidcmd_packet_callback (unsigned char x){    if (x == 0xd1)	mt_CallProgressCallback();    else	dsp_done = 1;}voidmt_CallProgressCallback(void){    static short LastTimeStamp = 0;    short nt, xt, dt;    int x;    if (Cdata[4] != 1) return;    nt = (Cdata[7] << 8) | Cdata[6];    xt = (Cdata[9] << 8) | Cdata[8];    if (nt > LastTimeStamp)	dt = nt - LastTimeStamp;    else {	dt = nt - LastTimeStamp;	dt += 0x1aab;    }    /* Dbg("Ring time: %2d - dtime: %4d -- ", xt, dt); */    if (xt) {	if (dt)	    x = (xt * 0x3e8) / dt;	else	    x = 0;	if ((x >= 0xf) && (x <= 0x44))	    mt_RingState = 7;	else	    mt_RingState = 0;	/* Dbg("Ring length= %d -- ", x); */    } else {	if (mt_RingState == 2)	    mt_RingState = 0;	else	    mt_RingState = 2;    }    Msg("RingState = %d\n", mt_RingState);    LastTimeStamp = nt;}/* CRAM_CallBack */voidline_int(void){    if (line_io_enabled == 0) return;    dspdrv_ReadCram(0x34, &dce_length_semaphore, 1);    dspdrv_ReadCram(0x35, &dce_status_semaphore, 1);    if (dce_status_semaphore)	dspdrv_ReadCram(0x34, &dce_length_semaphore, 1);#if 1    if (dce_status_semaphore>1) Dbg("RX StSem: %#x\n", dce_status_semaphore);#endif    if (dce_length_semaphore || dce_status_semaphore)	line_rx_int();    dspdrv_ReadCram(0x74, &dce_length_semaphore, 1);    dspdrv_ReadCram(0x75, &dce_status_semaphore, 1);#if 1    if (dce_status_semaphore>1) Dbg("TX StSem: %#x\n", dce_status_semaphore);#endif    if ((dce_length_semaphore == 0) && (dce_status_semaphore == 0))	line_tx_int();}voidline_rx_int(void){    if (v8_configured) v8_rx_int();    else sync_rx_int();}voidline_tx_int(void){    if (v8_configured) v8_tx_int();    else sync_tx_int();}voidsync_rx_int(void){    char reg = 0x14;    if (dce_status_semaphore == 6) {	/* Msg("RX Error\n"); */	dce_rx_errors++;    }        RX_stat[(int)dce_length_semaphore-1]++;    if (dce_length_semaphore > 32) Dbg("ERROR: dce_length_semaphore > 32\n");    while (dce_length_semaphore) {	dspdrv_ReadCram(reg++, &dce_rx_buffer[dce_rx_insert], 1);	if (dce_rx_count < BUF_SIZE) {	    dce_rx_insert++;	    dce_rx_count++;	    stat_rx_count++;	    if (dce_rx_insert == BUF_SIZE) dce_rx_insert = 0;	} else Dbg("ERROR: RX buffer full\n");	dce_length_semaphore--;    }    dce_status_semaphore = 0;    dspdrv_WriteCram(0x34, &dce_length_semaphore, 1);    dspdrv_WriteCram(0x35, &dce_status_semaphore, 1);}voidsync_tx_int(void){    char reg, xs, tcnt;    if (dce_tx_count == 0) {	dce_tx_interrupt_expected = 0;	return;    }    reg = 0x54;    tcnt = 0;    while (tcnt < 0x20) {	/* 32 Tx bytes Max */	dspdrv_WriteCram(reg++, &dce_tx_buffer[dce_tx_remove++], 1);	dce_tx_count--;	tcnt++;	stat_tx_count++;	if (dce_tx_remove == BUF_SIZE) dce_tx_remove = 0;	if (dce_tx_count == 0) break;    }    TX_stat[(int)tcnt-1]++;        xs = 0;    dspdrv_WriteCram(0x75, &xs, 1);    dspdrv_WriteCram(0x74, &tcnt, 1);}voidv8_rx_int(void){    unsigned char c, reg = 0x14;    while (dce_length_semaphore) {	dspdrv_ReadCram(reg++, &c, 1);	dce_length_semaphore--;	/* Dbg("%4x ", c); */	if (v8_status == 0) {	    if (c == 0xe0) {		v8_status = 1;		old_length = 0;		dce_rx_buffer[0] = 0xe0;		length = 1;	    }	} else if (v8_status == 1) {	    if (c != 0xe0)		dce_rx_buffer[length++] = c;	    else if (length < 3)		length = 1;	    else {		v8_status = 2;		old_length = length - 1;		length = 1;	    }	} else if (v8_status == 2) {	    if (dce_rx_buffer[length] == c) {		length++;		old_length--;	    } else if (c != 0xe0) {		v8_status = 1;		dce_rx_buffer[length++] = c;	    } else {		if (old_length == 0) {		    /* Dbg("JM Match\n"); */		    v8_rx_msg_size = length;		    jm_seq_match = 1;		    dce_length_semaphore = 0;		    v8_status = 3;		} else {		    Dbg("Old lenght not 0...\n");		    if (length < 3) {			length = 1;			v8_status = 1;		    } else {			old_length = length - 1;			length = 1;		    }		}	    }	} else {	    dce_length_semaphore = 0;	}    }    dspdrv_WriteCram(0x34, &dce_length_semaphore, 1);    dce_status_semaphore = 0;    dspdrv_WriteCram(0x35, &dce_status_semaphore, 1);}voidv8_tx_int(void){    char xs = 0;    if (!sending_CM && !sending_JM) return;    dspdrv_WriteCram(0x54, v8_tx_buffer, v8_tx_msg_size);    dspdrv_WriteCram(0x75, &xs, 1);    dspdrv_WriteCram(0x74, &v8_tx_msg_size, 1);    if (sending_CM) CM_count++;    else JM_count++;}voidline_enable_interrupts(void){    enable_irq(modem_irq);}voidline_disable_interrupts(void){    disable_irq(modem_irq);}/* ************************************************ */voiddelay(int milliseconds){    /* mdelay(milliseconds);     This doesn't work well */        current->state = TASK_INTERRUPTIBLE;    schedule_timeout((milliseconds * HZ + 1000 - HZ) / 1000); /* 100ths sec */}/* ************************************************ */voiddspdrv_clear_dsp_interrupt(void){    get_register (0xff);}voiddspdrv_ping_cram_intr(void){    set_register (0xfe, 0);}voidSetDspCfg (int p1){    unsigned char rv;        rv = get_register (0xf6);    if (p1 == 0) rv &= 0xfe;    else rv |= 0x1;    set_register (0xf6, rv);}voidWaitForDspReady(void){    /* delay(1000); */    delay(500);   /* How much should this be ? */}voidResetDspInternal(void){    set_register (0xfc, 2);    set_register (0xf7, 0);    SetDspCfg (1);    set_register (0xfc, 1);    WaitForDspReady();}#define LO_B(x) ((unsigned short)x & 0xff)#define HI_B(x) (((unsigned short)x >> 8) & 0xff)intDnldViaHw(unsigned short *data){    unsigned short xc, wc, w;    unsigned char xl=0, xh=0;    int i, rv=1;        xc = data[0];    i = 1;    set_register(0xfc, 0xa);    while (xc) {	wc = data[i++];	set_register(0xf9, HI_B(data[i]));	set_register(0xf8, LO_B(data[i]));	i++;	while (wc) {	    set_register(0xfa, LO_B(data[i]));	    set_register(0xfa, HI_B(data[i]));	    i++;	    wc--;	}	xc--;    }    i = 1;    xc = data[0];    while (xc) {	wc = data[i++];	xl = LO_B(data[i]);	xh = HI_B(data[i]);	set_register(0xf8, xl);	set_register(0xf9, xh);	i++;	rv = 1;	while (wc) {	    w = get_register(0xfa) | (get_register(0xfa) << 8);	    if (data[i] != w) rv = 0;	    i++;	    wc--;	}	xc--;    }    set_register(0xf9, 0x8);    set_register(0xf8, 0);    set_register(0xfa, xl);    set_register(0xfa, xh);    set_register(0xfc, 0x9);    return rv;}intDnldBootx(void) {    /* return DnldViaHw(bootx_array); */    return 0;}intDnldPcmPage(void){    return 0;	/* No PCM modes supported yet. (x2 & V.90) */}voidDnldPoweronPatch(void){    DnldViaHw(pwr_on_patch);    WaitForDspReady();    DspPatch(1);}voidResetDspPoweron(void){    int al;    set_register (0xf7, 0x2);    SetDspCfg (1);    if (DnldBootx() && DnldPcmPage()) {	if (mt_v90_configured == 0)	    al = 0;	else	    al = 1;	PcmEnabled = al+1;    }    DnldPoweronPatch();}voidDnldPatch(unsigned char *patch){    int i, ps, pcnt, j, wx, b;        ps = (patch[2] | (patch[3] << 8))*2 + 1;    i = 2;    ack_or_response = 2;    current_command[0] = 0xc;    current_command[1] = 0;    current_command[3] = 0;    current_command[6] = 0;    current_command[7] = 0;    while (i != ps) {	pcnt = 4;	j = 8;	current_command[4] = patch[i*2];	current_command[5] = patch[i*2+1];	wx = patch[i*2] | (patch[i*2+1] << 8);	for (b=1; b<4; b++) {	    i++;	    pcnt+=2;	    current_command[j++] = patch[i*2];	    current_command[j++] = patch[i*2+1];	    if (i == ps) break;	    i++;

⌨️ 快捷键说明

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