📄 codec_dev.c
字号:
/*************************************************
Copyright (C), 1997-2006, Centnet Tech. Co., Ltd.
File name: adspdev.c
Author:Zhoujh Version: 1.0 Date: April 11 2006
Description:
Others:
Function List:
1. ....
History:
1. Date:
Author:
Modification:
2. ...
*************************************************/
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/smp_lock.h>
#include <linux/devfs_fs_kernel.h>
#include <linux/init.h>
#include <asm/uaccess.h>
#include <linux/delay.h>
#include "common.h"
#include "cncodec.h"
#include "codec_dev.h"
struct codecdev codeccfg;
char g_timer = 0;
/**********************************************
unsigned char get_line_type(unsigned char chan)
ch:the logic channel
**********************************************/
unsigned char get_line_type(unsigned char chan)
{
unsigned char Line_type;
if(chan==0)
{
Line_type=CD_FXS;
}
if(chan==1)
{
switch(codeccfg.module_type)
{
case TWO_FXS:
case TWO_FXS_TWO_FXOYE:
case FOUR_FXS:
case THREE_FXS_ONE_FXOH:
case TWO_FXS_TWO_FXO:
case FOUR_FXS_FOUR_FXOYE:
Line_type=CD_FXS;
break;
case ONE_FXS_ONE_FXO:
Line_type=CD_FXO;
break;
default:
break;
}
}
if(chan==2)
{
switch(codeccfg.module_type)
{
case FOUR_FXS:
case THREE_FXS_ONE_FXOH:
case FOUR_FXS_FOUR_FXOYE:
Line_type=CD_FXS;
break;
case TWO_FXS_TWO_FXO:
Line_type=CD_FXO;
break;
default:
break;
}
}
if(chan==3)
{
switch(codeccfg.module_type)
{
case FOUR_FXS:
case FOUR_FXS_FOUR_FXOYE:
Line_type=CD_FXS;
break;
case TWO_FXS_TWO_FXO:
Line_type=CD_FXO;
break;
default:
break;
}
}
return Line_type;
}
static void active_lamp_timer(unsigned long data)
{
struct codecdev *codeccfg_ptr = (struct codecdev *)data;
if(0 == codeccfg_ptr->invert)
{
codeccfg_ptr->invert = 1;
set_led(-1, 1);
}
else
{
codeccfg_ptr->invert = 0;
set_led(-1, 0);
}
if(g_timer == 0)
{
codeccfg_ptr->timer.expires = ACTIVE_LAMP_TIMER;
}
else
{
codeccfg_ptr->timer.expires = jiffies+(HZ*1/5);
}
add_timer(&codeccfg_ptr->timer);
}
void start_active_lamp(struct codecdev *codeccfg_ptr)
{
codeccfg_ptr->invert = 0;
init_timer(&codeccfg_ptr->timer);
codeccfg_ptr->timer.expires = ACTIVE_LAMP_TIMER;
codeccfg_ptr->timer.data = (unsigned long) codeccfg_ptr;
codeccfg_ptr->timer.function = &active_lamp_timer;
add_timer(&codeccfg_ptr->timer);
}
static ssize_t codecdev_read (struct file *file, char __user *buf, size_t count,
loff_t *offset)
{
return 0;
}
static ssize_t codecdev_write (struct file *file, const char __user *buf, size_t count,
loff_t *offset)
{
return 0;
}
static int codecdev_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
unsigned int i;
unsigned char data = 1,data_3050=0;
unsigned char chan = 0;
unsigned char lcr=0; //add by gao fc
unsigned char *str = NULL;
unsigned int v1 = 0;
unsigned int v2 = 0;
unsigned int v3 = 0;
unsigned int v4 = 0;
unsigned int ret = 0;
switch(cmd)
{
case HANDUP_DETECTION:
{
chan = *((unsigned char *)arg);
if(CD_FXS == get_line_type(chan))
{
for(i=0;i<100;i++) //add by gaofc
{
cpld_rw_sync(1);
}
Write_cpld(1<<(chan));
Write_cpld(0xc4);
lcr=Read_cpld();
lcr =lcr&0x01; //edit by gaofc
if(lcr) //add by gaofc
{
data=0;
}
}
else
{
data_3050=ReadDr3050(5); //changed by liubing on Oct 10,06
if(data_3050>>2&0x01)
data=0; //Ring Detected
else
{
if(data_3050==0)
data=2; // handdown state
else
data=3; //empty
}
}
*((unsigned char *)arg) = data;
}
break;
case FXO_CONNECTION_DETECTION:
{
chan = *((unsigned char *)arg);
data = fxo_connection_status(chan);
*((unsigned char *)arg) = data;
}
break;
case SETSLIC_OPEN:
{
chan = *((unsigned char *)arg);
SetSlic(chan, 1);
}
break;
case SETSLIC_CLOSE:
{
chan = *((unsigned char *)arg);
SetSlic(chan, 0);
}
break;
case SETSLIC_RING:
{
chan = *((unsigned char *)arg);
SetSlic(chan, 4);
}
break;
case SETSLIC_INVERTOPEN:
{
chan = *((unsigned char *)arg);
SetSlic(chan, 5);
}
break;
case SETSLIC_ONHOOK:
{
chan = *((unsigned char *)arg);
SetSlic(chan, 2);
}
break;
case SET_TRUNK_CLOSE:
{
chan = *((unsigned char *)arg);
set_trunk(chan, 0);
}
break;
case SET_TRUNK_OPEN:
{
chan = *((unsigned char *)arg);
set_trunk(chan, 1);
}
break;
case GET_LINE_TYPE:
{
chan = *((unsigned char *)arg);
data = get_line_type(chan);
*((unsigned char *)arg) = data;
}
break;
case SET_LED_ON:
{
chan = *((unsigned char *)arg);
set_led(chan,1);
}
break;
case SET_LED_OFF:
{
chan = *((unsigned char *)arg);
set_led(chan,0);
}
break;
case SET_LED_TIMER_FAST:
g_timer = 1;
break;
case SET_LED_TIMER_SLOW:
g_timer = 0;
break;
case SET_CID_ON:
{
chan = *((unsigned char *)arg);
CID_enable(chan, 1);
}
break;
case SET_CID_OFF:
{
chan = *((unsigned char *)arg);
CID_enable(chan, 0);
}
break;
case GET_GATEWAY_TYPE:
{
data = ReadType(Gateway_type_addr);
*((unsigned char *)arg) = data;
}
break;
case GET_CODEC_TYPE:
{
data = ReadType(Codec_type_addr);
*((unsigned char *)arg) = data;
}
break;
case GET_MODULE_TYPE:
{
data = ReadType(Module_type_addr);
*((unsigned char *)arg) = data;
}
break;
case SET_PCM_ENABLE:
{
chan = *((unsigned char *)arg);
PCM_enable(chan, 1);
}
break;
case SET_PCM_DISABLE:
{
chan = *((unsigned char *)arg);
PCM_enable(chan, 0);
}
break;
case GET_SPORT_CLOCK:
{
data = ReadType(Sport_type_addr);
*((unsigned char *)arg) = data;
}
break;
case GET_NIC_TYPE:
{
data = ReadType(Nic_type_addr);
*((unsigned char *)arg) = data;
}
break;
case SET_IVA_0:
{
chan = *((unsigned char *)arg);
iva_si3215_set(chan, -1);
}
break;
case SET_IVA_1:
{
chan = *((unsigned char *)arg);
iva_si3215_set(chan, 0);
}
break;
case SET_IVA_2:
{
chan = *((unsigned char *)arg);
iva_si3215_set(chan, 1);
}
break;
case SET_OVA_0:
{
chan = *((unsigned char *)arg);
ova_si3215_set(chan, -1);
}
break;
case SET_OVA_1:
{
chan = *((unsigned char *)arg);
ova_si3215_set(chan, 0);
}
break;
case SET_OVA_2:
{
chan = *((unsigned char *)arg);
ova_si3215_set(chan, 1);
}
break;
case SET_IMPEDANCE_0:
{
chan = *((unsigned char *)arg);
Set_Two_wire_impedance_control(chan, 0);
}
break;
case SET_IMPEDANCE_1:
{
chan = *((unsigned char *)arg);
Set_Two_wire_impedance_control(chan, 1);
}
break;
case SET_IMPEDANCE_2:
{
chan = *((unsigned char *)arg);
Set_Two_wire_impedance_control(chan, 2);
}
break;
case SET_IMPEDANCE_3:
{
chan = *((unsigned char *)arg);
Set_Two_wire_impedance_control(chan, 3);
}
break;
case SET_IMPEDANCE_4:
{
chan = *((unsigned char *)arg);
Set_Two_wire_impedance_control(chan, 4);
}
break;
case SET_IMPEDANCE_5:
{
chan = *((unsigned char *)arg);
Set_Two_wire_impedance_control(chan, 5);
}
break;
case SET_IMPEDANCE_6:
{
chan = *((unsigned char *)arg);
Set_Two_wire_impedance_control(chan, 6);
}
break;
case SET_IMPEDANCE_7:
{
chan = *((unsigned char *)arg);
Set_Two_wire_impedance_control(chan, 7);
}
break;
case SET_SI3050_IMPEDANCE:
str = (unsigned char *)arg;
chan = str[0];
Si3050_Country_Set(str[1]);
break;
case DEBUG_READDRPROSLIC:
sscanf(arg, "%d|%d", &v1, &v2);
ret = ReadDrProSLIC((unsigned char)v1, (unsigned char)v2);
printk ("ReadDrProSLIC(%d, %d) = 0x%x\n\r", v1, v2, ret);
break;
case DEBUG_WRITEDRPROSLIC:
sscanf(arg, "%d|%d|%d", &v1, &v2, &v3);
WriteDrProSLIC((unsigned char)v1, (unsigned char)v2, (unsigned char)v3);
printk ("WriteDrProSLIC(%d, %d, %d) = 0\n\r", v1, v2, v3);
break;
case DEBUG_READINDRPROSLIC:
sscanf(arg, "%d|%d", &v1, &v2);
ret = ReadInDrProSLIC((unsigned char)v1, (unsigned char)v2);
printk ("ReadInDrProSLIC(%d, %d) = 0x%x\n\r", v1, v2, ret);
break;
case DEBUG_WRITEINDRPROSLIC:
sscanf(arg, "%d|%d|%d", &v1, &v2, &v3);
WriteInDrProSLIC((unsigned char)v1, (unsigned char)v2, (unsigned char)v3);
printk ("WriteInDrProSLIC(%d, %d,%d) = 0\n\r", v1, v2, v3);
break;
case DEBUG_READCPLD3050:
ret = (unsigned int)Read_cpld_3050();
printk ("Read_cpld_3050(void) = 0x%x\n\r", ret);
break;
case DEBUG_WRITECPLD3050:
sscanf(arg, "%d", &v1);
Write_cpld_3050((unsigned short)v1);
printk ("Write_cpld_3050(%d)= 0\n\r", v1);
break;
default:
break;
}
return 0;
}
static int codecdev_open(struct inode *inode, struct file *file)
{
return 0;
}
static int codecdev_release(struct inode *inode, struct file *file)
{
return 0;
}
static struct file_operations codecdev_fops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
.read = codecdev_read,
.write = codecdev_write,
.ioctl = codecdev_ioctl,
.open = codecdev_open,
.release = codecdev_release,
};
static int __init codec_dev_init()
{
int res = 0;
*pFIO_DIR = 0xF370; //det PF INPUT OR OUTPUT
codeccfg.module_type = ReadType(Module_type_addr);
switch (codeccfg.module_type)
{
case ONE_FXS:
case ONE_FXS_ONE_FXOY:
if(initProSLIC(0) != CODEC_OK) goto codec_out;
break;
case TWO_FXS:
case TWO_FXS_TWO_FXOYE:
if(initProSLIC(0) != CODEC_OK) goto codec_out;
if(initProSLIC(1) != CODEC_OK) goto codec_out;
break;
case THREE_FXS_ONE_FXOH:
if(initProSLIC(0) != CODEC_OK) goto codec_out;
if(initProSLIC(1) != CODEC_OK) goto codec_out;
if(initProSLIC(2) != CODEC_OK) goto codec_out;
break;
case FOUR_FXS:
case FOUR_FXS_FOUR_FXOYE:
if(initProSLIC(0) != CODEC_OK) goto codec_out;
if(initProSLIC(1) != CODEC_OK) goto codec_out;
if(initProSLIC(2) != CODEC_OK) goto codec_out;
if(initProSLIC(3) != CODEC_OK) goto codec_out;
break;
case ONE_FXS_ONE_FXO:
if(initProSLIC(0) != CODEC_OK) goto codec_out;
if(init3050() != CODEC_OK) goto codec_out;
break;
default:
break;
}
start_active_lamp(&codeccfg);
res = register_chrdev(CODEC_MAJOR, "codec", &codecdev_fops);
if(res)
{
goto codec_out;
}
devfs_mk_dir("codec");
return 0;
codec_out_unreg_chrdev:
unregister_chrdev(CODEC_MAJOR, "codec");
codec_out:
CODEC_ASSERT(0);
return res;
}
static void __exit codec_dev_exit(void)
{
devfs_remove("codec");
unregister_chrdev(CODEC_MAJOR,"codec");
}
MODULE_AUTHOR("Centnet Inc.");
MODULE_DESCRIPTION("codec /dev entries driver");
MODULE_LICENSE("Copyright (c) Centnet Inc.");
module_init(codec_dev_init);
module_exit(codec_dev_exit);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -