?? tw2834.c
字號:
*/
static void tw2834_initpage0(int norm)
{
int t1;
if(norm == VIDEO_NORM_NTSC){
for (t1=0; t1<4; t1++){
tw2834_write_table(PAGE0,0x00+0x40*t1,tbl_ntsc_page0_common,36);
tw2834_write_byte(PAGE0,0x22+0x40*t1,t1);
}
tw2834_write_table(PAGE0,0x38,tbl_ntsc_page0_sfr1,8);
tw2834_write_table(PAGE0,0x78,tbl_ntsc_page0_sfr2,8);
tw2834_write_table(PAGE0,0xb8,tbl_ntsc_page0_sfr3,8);
tw2834_write_table(PAGE0,0xf8,tbl_ntsc_page0_sfr4,8);
}
else{
for(t1=0; t1<4; t1++){
tw2834_write_table(PAGE0,0x00+0x40*t1,tbl_pal_page0_common,36);
tw2834_write_byte(PAGE0,0x22+0x40*t1,t1);
}
tw2834_write_table(PAGE0,0x38,tbl_pal_page0_sfr1,8);
tw2834_write_table(PAGE0,0x78,tbl_pal_page0_sfr2,8);
tw2834_write_table(PAGE0,0xb8,tbl_pal_page0_sfr3,8);
tw2834_write_table(PAGE0,0xf8,tbl_pal_page0_sfr4,8);
}
}
/*
* initialize the page1's register
* return value: nothing
*/
static void tw2834_initpage1(int norm)
{
unsigned char t1;
tw2834_write_table(PAGE1,0x01,tbl_page1_x_com,15);
tw2834_write_table(PAGE1,0x10,tbl_page1_x_ch_nrml,32);
tw2834_write_table(PAGE1,0x50,tbl_page1_y_com,16);
tw2834_write_table(PAGE1,0x60,tbl_page1_y_ch_nrml_pic_quad,16);
tw2834_write_table(PAGE1,0x70,tbl_page1_cas_popup,14);
if(norm==VIDEO_NORM_NTSC){
tw2834_write_table(PAGE1,0x30,tbl_ntsc_page1_x_pic_quad,16);
tw2834_write_table(PAGE1,0x40,tbl_ntsc_page1_dumy,16);
tw2834_write_table(PAGE1,0x80,tbl_ntsc_page1_enc,15);
tw2834_write_byte(PAGE1,0x00,0x00);
}
else{
tw2834_write_table(PAGE1,0x30,tbl_pal_page1_x_pic_quad,16);
tw2834_write_table(PAGE1,0x40,tbl_pal_page1_dumy,16);
tw2834_write_table(PAGE1,0x80,tbl_pal_page1_enc,15);
tw2834_write_byte(PAGE1,0x00,0x80);
}
tw2834_write_table(PAGE1,0xc0,tbl_page1_channel_id_ctrl,16);
tw2834_write_byte(PAGE1,REG_CLK_CTL,0x41); /*... DAC clock control*/
tw2834_write_byte(PAGE1,REG_MPP_SET,0xbb);
for (t1 = 0; t1 < 4; t1++) {
tw2834_write_byte(PAGE1,REG_QUE_DATA,t1);
tw2834_write_byte(PAGE1,REG_QUE_ADDR,QUE_WR|t1);
}
tw2834_write_byte(PAGE1,0x8d,0x60); /*... when cascade*/
tw2834_write_byte(PAGE1,0x80,0x22); /*... when cascade*/
}
/*
* initialize the page2's register
* return value: nothing
*/
static void tw2834_initpage2(int norm)
{
unsigned char t1;
unsigned char reg_curctl;
tw2834_write_table(PAGE2,0x00,tbl_page2_cur_3d_box,96);
if (norm == VIDEO_NORM_NTSC)
tw2834_write_table(PAGE2,0x60,tbl_ntsc_page2_ary_box,32);
else
tw2834_write_table(PAGE2,0x60,tbl_pal_page2_ary_box,32);
for (t1 = 0; t1 < 4; t1++) {
tw2834_write_table(PAGE2,0x80+0x20*t1,tbl_page2_motn_sens,6);
tw2834_write_table(PAGE2,0x86+0x20*t1,tbl_page2_motn_mask,24);
}
reg_curctl = tw2834_read_byte(PAGE2,REG_CURCTL);
}
/*
* first initialize tw2834 routine
* return value: nothing
*/
static void tw2834_init_0(void)
{
unsigned char reg;
reg = tw2834_read_byte(PAGE0,0xFE);
if(reg==0x10)
setmemclock(0x99); /*rev version B*/
else if(reg==0x11)
setmemclock(0x77); /*rev version C*/
udelay(1000); /*delay 1ms */
}
/*
* second initialize tw2834 routine
* return value: nothing
*/
static void tw2834_init_1(void)
{
tw2834_initpage0(norm_mode);
tw2834_initpage1(norm_mode);
tw2834_initpage2(norm_mode);
/*set the digital channel ID offset default 10*/
tw2834_ch_id_config(10);
set_display_d1(0);
if (mchannel == 0)
{
if (videosize == 0)
{
set1cif(0);
}
else if (videosize == 1)
{
setd1(0);
}
}
else
{
if (videosize == 0)
{
set4cif();
}
else if (videosize == 1)
{
set_2halfd1();
}
else if (videosize == 2)
{
set4d1();
return;
}
else if (videosize == 3)
{
set4qcif();
return;
}
else if (videosize == 4)
{
set2cif();
return;
}
else
{
setd1(0);
return;
}
}
}
/*
* tw2834 read routine.
* do nothing.
*/
ssize_t tw2834_read(struct file * file, char __user * buf, size_t count, loff_t * offset)
{
return 0;
}
/*
* tw2834 write routine.
* do nothing.
*/
ssize_t tw2834_write(struct file * file, const char __user * buf, size_t count, loff_t * offset)
{
return 0;
}
/*
* tw2834 open routine.
* do nothing.
*/
int tw2834_open(struct inode * inode, struct file * file)
{
return 0;
}
/*
* tw2834 close routine.
* do nothing.
*/
int tw2834_close(struct inode * inode, struct file * file)
{
return 0;
}
/******************************************************************************/
/*
* tw2834 io control routine
* @param inode: pointer of the node;
* @param file: pointer of the file;
* @param cmd: command from the app:
* @param arg:arg from app layer.
*/
int tw2834_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
int ret = 0;
void __user *argp = (void __user *)arg;
unsigned long val;
if (copy_from_user(&val, argp, sizeof(val)))
{
printk("\tTW2834_ERROR: WRONG cpy val is %lu\n",val);
return -EFAULT;
}
switch (cmd)
{
/*read register */
case TW2834_READ_REG:
{
val = tw2834_read_byte((val>>8) & 0xff, val & 0xff);
return copy_to_user(argp, &val, sizeof(val)) ? -EFAULT : 0;
}
/*write register*/
case TW2834_SET_REG:
{
tw2834_write_byte((val>>16) & 0xff, (val>>8) & 0xff, val & 0xff);
return 0;
}
case TW2834_GETNORM:
{
//int chn;
//unsigned char byte_tmp;
int norm_read;
/*
chn = (unsigned char)(val & 0xff);
byte_tmp = tw2834_read_byte(PAGE0, (0x40 * chn));
if(((byte_tmp & 0xe0) >> 5) < 4)
norm_read = VIDEO_NORM_PAL;
else
norm_read = VIDEO_NORM_NTSC;
*/
norm_read = norm_mode;
printk ("norm: %d\n", norm_mode);
return copy_to_user(argp, &norm_read, sizeof(norm_read)) ? -EFAULT : 0;
}
/*set the value of bright*/
case TW2834_SET_BRIGHT:
{
int chn;
unsigned char bright;
chn = (unsigned char)(val & 0xff);
bright = (unsigned char)((val & 0xff00) >> 8);
if(chn<0 || chn>3)
return -EINVAL;
tw2834_write_byte(PAGE0,0x12+0x40*chn,bright);
return 0;
}
/*set the value of contrast*/
case TW2834_SET_CONTRAST:
{
int chn;
unsigned char cont;
chn = (unsigned char)(val & 0xff);
cont = (unsigned char)((val & 0xff00) >> 8);
if(chn<0 || chn>3)
return -EINVAL;
tw2834_write_byte(PAGE0,0x11+0x40*chn,cont);
return 0;
}
/*set the value of hue*/
case TW2834_SET_HUE:
{
int chn;
unsigned char hue;
chn = (unsigned char)(val & 0xff);
hue = (unsigned char)((val & 0xff00) >> 8);
if(chn<0 || chn>3)
return -EINVAL;
tw2834_write_byte(PAGE0,0x0f+0x40*chn,hue);
return 0;
}
/*set the value of sat*/
case TW2834_SET_SAT:
{
int chn;
unsigned char sat;
chn = (unsigned char)(val & 0xff);
sat = (unsigned char)((val & 0xff00) >> 8);
if(chn<0 || chn>3)
return -EINVAL;
tw2834_write_byte(PAGE0,0x10+0x40*chn,sat);
return 0;
}
/*initialize register and set norm */
case TW2834_SETNORM: /*initialize all the register*/
{
mchannel = 0;
videosize = 0;
if(val == VIDEO_NORM_NTSC){
norm_mode = VIDEO_NORM_NTSC;
tw2834_init_1();
}
else if(val == VIDEO_NORM_PAL){
norm_mode = VIDEO_NORM_PAL;
tw2834_init_1();
}
else
return -EINVAL;
return 0;
}
/*set record path mod to 4qcif*/
case TW2834_SET_4QCIF:
{
set4qcif();
return 0;
}
/*set record path mod to 4 cif*/
case TW2834_SET_4CIF:
{
set4cif();
return 0;
}
/*set record path mod to 1 cif*/
case TW2834_SET_1CIF:
{
int chn = val;
if(chn<0 || chn>3)
return -EINVAL;
set1cif(chn);
return 0;
}
/*set record path mod to 1 d1*/
case TW2834_SET_1D1:
{
int chn = val;
if(chn<0 || chn>3)
return -EINVAL;
setd1(chn);
return 0;
}
/*set record path mod to 4 d1*/
case TW2834_SET_4D1:
{
set4d1();
return 0;
}
/*set record path mod to switch*/
case TW2834_SET_Y_SWITCH:
{
if (val>1023)
{
printk("\tTW2834_ERROR: period more than 1023, is %lu\n",val);
return -EINVAL;
}
set_record_switch(val);
return 0;
}
/*set record path mod to half d1*/
case TW2834_SET_2HALF_D1:
{
set_2halfd1();
return 0;
}
/*set record path mod to 2 cif*/
case TW2834_SET_2CIF:
{
set2cif();
return 0;
}
/*set display path mod to 1 d1*/
case TW2834_SET_X_D1:
{
set_display_d1(0);
return 0;
}
/*set display path mod to quad*/
case TW2834_SET_X_QUAD:
{
set_display_quad();
return 0;
}
/* Set the digital id offset of vbi*/
case TW2834_SET_VBI_OFFSET_V:
{
if(val>20 || val<1)
{
printk("\tTW2834_ERROR: offset more than 20,or less than 1 : %lu\n",val);
return -EINVAL;
}
tw2834_ch_id_config(val&0xff);
return 0;
}
/* Get the digital id vertical offset of vbi*/
case TW2834_GET_VBI_OFFSET_V:
{
val = tw2834_get_chid_offsetv();
return copy_to_user(argp, &val, sizeof(val)) ? -EFAULT : 0;
}
/* Get the digital id horizontal offset of vbi*/
case TW2834_GET_VBI_OFFSET_H:
{
val = 2;
return copy_to_user(argp, &val, sizeof(val)) ? -EFAULT : 0;
}
/*cmd wrong, do nothing*/
default:
{
return -EINVAL;
}
}
return ret;
}
/*
* The various file operations we support.
*/
static struct file_operations tw2834_fops = {
.owner = THIS_MODULE,
.read = tw2834_read,
.write = tw2834_write,
.ioctl = tw2834_ioctl,
.open = tw2834_open,
.release = tw2834_close
};
static struct miscdevice tw2834_dev = {
MISC_DYNAMIC_MINOR,
"tw2834dev",
&tw2834_fops,
};
/******************************************************************************/
/*
* tw2834 device initializing routine
*/
static int tw2834_device_init(void)
{
init_gpio_control();
tw2834_init_0();
tw2834_init_1();
return 0;
}
static int __init tw2834_init(void)
{
int ret = 0;
printk("TW2834 driver init start ... \n");
ret = misc_register(&tw2834_dev);
if (ret)
{
printk("\tTW2834_ERROR: could not register tw2834 devices. \n");
return ret;
}
if (tw2834_device_init() < 0)
{
misc_deregister(&tw2834_dev);
printk("\tTW2834_ERROR: tw2834 driver init fail for device init error!\n");
return -1;
}
printk("TW2834 driver init successful!\n");
return ret;
}
static void __exit tw2834_exit(void)
{
release_gpio_control();
misc_deregister(&tw2834_dev);
}
/******************************************************************************/
module_init(tw2834_init);
module_exit(tw2834_exit);
module_param(mchannel, int, S_IRUGO);
module_param(videosize, int, S_IRUGO);
module_param(norm_mode, int, S_IRUGO);
#ifdef MODULE
#include <linux/compile.h>
#endif
MODULE_INFO(build, UTS_VERSION);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("hisilicon");
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -