📄 tw2815.c
字号:
#include <linux/module.h>#include <linux/init.h>#include <linux/delay.h>#include <linux/errno.h>#include <linux/fs.h>#include <linux/kernel.h>#include <linux/major.h>#include <linux/slab.h>#include <linux/mm.h>#include <linux/pci.h>#include <linux/signal.h>#include <asm/io.h>#include <asm/pgtable.h>#include <asm/page.h>#include <linux/sched.h>#include <linux/types.h>#include <linux/videodev.h>#include <asm/uaccess.h>#include <asm/arch/regs-gpio.h>#include <asm/arch/regs-iic.h>#include <asm/arch/regs-irq.h>#include <linux/i2c.h>#define I2C_NAME(x) (x)->name#include <linux/video_encoder.h>#include "tw2815.h"static char tw2815_name[] = "tw2815";static unsigned short normal_i2c[] ={ TW2815_SADDR_W >> 1, I2C_CLIENT_END};static unsigned short ignore = I2C_CLIENT_END;static struct i2c_client_address_data addr_data ={ .normal_i2c = normal_i2c, .probe = &ignore, .ignore = &ignore, };static unsigned char tbl_pal_tw2815_common[] = { // CH1 CH2 CH3 CH4 0x00,0x88,0x20,0xd0, //... 0x00~0x03 0x10~0x13 0x20~0x23 0x30~0x33 0x05,0x20,0x28,0x80, //... 0x04~0x07 0x14~0x17 0x24~0x27 0x34~0x37 0x80,0xa0,0x80,0x82, //... 0x08~0x0b 0x18~0x1b 0x28~0x2b 0x38~0x3b 0x00,0x00,0x11 //... 0x0c~0x0e 0x1c~0x1e 0x2c~0x2e 0x3c~0x3e };static unsigned char tbl_pal_tw2815_sfr1[] = { 0x00,0x00,0x00,0xe0, //... 0x40~0x43 0x45,0xa0,0xd0,0x2f, //... 0x44~0x47 0x64,0x80,0x80,0x82, //... 0x48~0x4b 0x82,0x03,0x00,0x00 //... 0x4c~0x4f };static unsigned char tbl_pal_tw2815_sfr2[] = { 0x00,0x0f,0x05,0x00, //... 0x50~0x53 0x00,0x80,0x06,0x00, //... 0x54~0x57 0x00,0x00 //... 0x58~0x59 };//=================================================================================//=================================================================================static unsigned char tbl_ntsc_tw2815_common[] = { // CH1 CH2 CH3 CH4 0x00,0xc8,0x20,0xd0, //... 0x00~0x03 0x10~0x13 0x20~0x23 0x30~0x33 0x06,0xf0,0x08,0x80, //... 0x04~0x07 0x14~0x17 0x24~0x27 0x34~0x37 0x80,0x80,0x80,0x02, //... 0x08~0x0b 0x18~0x1b 0x28~0x2b 0x38~0x3b 0x06,0x00,0x11 //... 0x0c~0x0e 0x1c~0x1e 0x2c~0x2e 0x3c~0x3e };static unsigned char tbl_ntsc_tw2815_sfr1[] = { 0x00,0x00,0x00,0xc0, //... 0x40~0x43 0x45,0xa0,0xd0,0x2f, //... 0x44~0x47 0x64,0x80,0x80,0x82, //... 0x48~0x4b 0x82,0x00,0x00,0x00 //... 0x4c~0x4f };static unsigned char tbl_ntsc_tw2815_sfr2[] = { 0x00,0x0f,0x05,0x00, //... 0x50~0x53 0x00,0x80,0x06,0x00, //... 0x54~0x57 0x00,0x00 //... 0x58~0x59 };struct tw2815 { struct i2c_client *client; int norm; int enable; int bright; int contrast; int hue; int sat;};struct i2c_reg_value { u8 reg; u8 value;};static int tw2815_single_read(struct i2c_client *client, u8 addr){ struct i2c_reg_value reg; u8 value; int rc; value = addr; if (1 != (rc = i2c_master_send(client, &value, 1))) printk("i2c i/o error: rc == %d (should be 1)\n", rc); msleep(10); if (1 != (rc = i2c_master_recv(client, &value, 1))) printk("i2c i/o error: rc == %d (should be 1)\n", rc); printk("Tw2815: read 0x%02x = 0x%02x\n", addr, value); return(value);}static void tw2815_block_read(struct i2c_client *client, u8 start_addr, u8 *tbl_ptr, u8 length){ u8 count,value; for(count=0;count<length;count++) { value = tw2815_single_read(client, start_addr); *tbl_ptr = value; tbl_ptr++; start_addr++; } return ;}static void tw2815_single_write(struct i2c_client *client, u8 addr, u8 value){ struct i2c_reg_value reg; int rc; reg.reg = addr; reg.value = value; if (2 != (rc = i2c_master_send(client, ®.reg, 2))) printk("i2c i/o error: rc == %d (should be 2)\n", rc);}static void tw2815_block_write(struct i2c_client *client, u8 start_addr, u8 *tbl_ptr, u8 length){ u8 count,value; for(count=0;count<length;count++) { value =*tbl_ptr; tw2815_single_write(client,start_addr,value); start_addr++; tbl_ptr++; } return;}static void tw2815_mPAL_vedio_write(struct i2c_client *client){ u8 tc; u8 *buf; for(tc=0;tc<4;tc++) { buf = tbl_pal_tw2815_common; tw2815_block_write(client, COMMOM_REG_ADDR+0x10*tc, buf, COMMOM_REG_LENGTH); } buf = tbl_pal_tw2815_sfr1; tw2815_block_write(client, SFR1_REG_ADDR, buf, SFR1_REG_LENGTH); buf = tbl_pal_tw2815_sfr2; tw2815_block_write(client, SFR2_REG_ADDR, buf, SFR2_REG_LENGTH); tw2815_single_write(client,0x0d,0x05); tw2815_single_write(client,0x1d,0x04); tw2815_single_write(client,0x2d,0x07); tw2815_single_write(client,0x3d,0x06);}static void tw2815_mNTSC_vedio_write(struct i2c_client *client){ u8 tc; u8 *buf; for(tc=0;tc<4;tc++) { buf = tbl_ntsc_tw2815_common; tw2815_block_write(client, COMMOM_REG_ADDR+0x10*tc, buf, COMMOM_REG_LENGTH); } buf = tbl_ntsc_tw2815_sfr1; tw2815_block_write(client, SFR1_REG_ADDR, buf, SFR1_REG_LENGTH); buf = tbl_ntsc_tw2815_sfr2; tw2815_block_write(client, SFR2_REG_ADDR, buf, SFR2_REG_LENGTH); tw2815_single_write(client,0x0d,0x05); tw2815_single_write(client,0x1d,0x04); tw2815_single_write(client,0x2d,0x07); tw2815_single_write(client,0x3d,0x06);}static void tw2815_default_vedio_write(struct i2c_client *client,u8 telecast_mode){ switch(telecast_mode) { case TELECAST_PAL_MODE: tw2815_mPAL_vedio_write(client); break; case TELECAST_NTSC_MODE: tw2815_mNTSC_vedio_write(client); break; } return;}/**************************************************************************** I2C Command ****************************************************************************/static int tw2815_command(struct i2c_client *client, u32 cmd, void *arg){ switch ( cmd ) { case GET_TW2815_REG_VALUE: { char *tmp; char start_addr,length; int ret; tmp = kmalloc(2,GFP_KERNEL); if (tmp==NULL) return -ENOMEM; if (copy_from_user(tmp,(char _user *)arg,2)) { kfree(tmp); return -EFAULT; } start_addr = *tmp++; length = *tmp; kfree(tmp); tmp = kmalloc(length,GFP_KERNEL); if (tmp==NULL) return -ENOMEM; tw2815_block_read(client,start_addr,tmp,length); ret = copy_to_user((char _user *)arg,tmp,length)?-EFAULT:ret; kfree(tmp); } break; case SET_TW2815_REG_VALUE: { char *tmp; char start_addr,value; int ret; tmp = kmalloc(2,GFP_KERNEL); if (tmp==NULL) return -ENOMEM; if (copy_from_user(tmp,(char _user *)arg,2)) { kfree(tmp); return -EFAULT; } start_addr = *tmp++; value = *tmp; kfree(tmp); tw2815_single_write(client,start_addr,value); } break; case TW2815_DEFAULT_CONFIG_PAL: tw2815_mPAL_vedio_write(client); break; case TW2815_DEFAULT_CONFIG_NTSC: tw2815_mNTSC_vedio_write(client); break; case TW2815_HUE_CONFIG: { char value,ch_num; char *tmp; tmp = kmalloc(2,GFP_KERNEL); if (tmp==NULL) return -ENOMEM; if (copy_from_user(tmp,(char _user *)arg,2)) { kfree(tmp); return -EFAULT; } value = *tmp++; ch_num = *tmp; kfree(tmp); switch(ch_num) { case ALL_CH: tw2815_single_write(client,CH1_HUE_REG,value); tw2815_single_write(client,CH2_HUE_REG,value); tw2815_single_write(client,CH3_HUE_REG,value); tw2815_single_write(client,CH4_HUE_REG,value); break; case CH_NUM1: tw2815_single_write(client,CH1_HUE_REG,value); break; case CH_NUM2: tw2815_single_write(client,CH2_HUE_REG,value); break; case CH_NUM3: tw2815_single_write(client,CH3_HUE_REG,value); break; case CH_NUM4: tw2815_single_write(client,CH4_HUE_REG,value); break; } } break; case TW2815_SAT_CONFIG: { char value,ch_num; char *tmp; tmp = kmalloc(2,GFP_KERNEL); if (tmp==NULL) return -ENOMEM; if (copy_from_user(tmp,(char _user *)arg,2)) { kfree(tmp); return -EFAULT; } value = *tmp++; ch_num = *tmp; kfree(tmp); switch(ch_num) { case ALL_CH: tw2815_single_write(client,CH1_SAT_REG,value); tw2815_single_write(client,CH2_SAT_REG,value); tw2815_single_write(client,CH3_SAT_REG,value); tw2815_single_write(client,CH4_SAT_REG,value); break; case CH_NUM1: tw2815_single_write(client,CH1_SAT_REG,value); break; case CH_NUM2: tw2815_single_write(client,CH2_SAT_REG,value); break; case CH_NUM3: tw2815_single_write(client,CH3_SAT_REG,value); break; case CH_NUM4: tw2815_single_write(client,CH4_SAT_REG,value); break; } } break; case TW2815_CONT_CONFIG: { char value,ch_num; char *tmp; tmp = kmalloc(2,GFP_KERNEL); if (tmp==NULL) return -ENOMEM; if (copy_from_user(tmp,(char _user *)arg,2)) { kfree(tmp); return -EFAULT; } value = *tmp++; ch_num = *tmp; kfree(tmp); switch(ch_num) { case ALL_CH: tw2815_single_write(client,CH1_CONT_REG,value); tw2815_single_write(client,CH2_CONT_REG,value); tw2815_single_write(client,CH3_CONT_REG,value); tw2815_single_write(client,CH4_CONT_REG,value); break; case CH_NUM1: tw2815_single_write(client,CH1_CONT_REG,value); break; case CH_NUM2: tw2815_single_write(client,CH2_CONT_REG,value); break; case CH_NUM3: tw2815_single_write(client,CH3_CONT_REG,value); break; case CH_NUM4: tw2815_single_write(client,CH4_CONT_REG,value); break; } } break; case TW2815_BRT_CONFIG: { char value,ch_num; char *tmp; tmp = kmalloc(2,GFP_KERNEL); if (tmp==NULL) return -ENOMEM; if (copy_from_user(tmp,(char _user *)arg,2)) { kfree(tmp); return -EFAULT; } value = *tmp++; ch_num = *tmp; kfree(tmp); switch(ch_num) { case ALL_CH: tw2815_single_write(client,CH1_BRT_REG,value); tw2815_single_write(client,CH2_BRT_REG,value); tw2815_single_write(client,CH3_BRT_REG,value); tw2815_single_write(client,CH4_BRT_REG,value); break; case CH_NUM1: tw2815_single_write(client,CH1_BRT_REG,value); break; case CH_NUM2: tw2815_single_write(client,CH2_BRT_REG,value); break; case CH_NUM3: tw2815_single_write(client,CH3_BRT_REG,value); break; case CH_NUM4: tw2815_single_write(client,CH4_BRT_REG,value); break; } } break; case TW2815_UGAIN_CONFIG: char value; __get_user(value, (char __user *)arg); tw2815_single_write(client,VGAIN_REG,value); break; case TW2815_VGAIN_CONFIG: char value; __get_user(value, (char __user *)arg); tw2815_single_write(client,VGAIN_REG,value); break; default : return -1; } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -