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

📄 codec_dev.c

📁 基于UClinux系统下
💻 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 + -