/*
* tp2802.c
*/
#include <linux/kernel.h>
#include <linux/version.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/fcntl.h>
#include <linux/mm.h>
#ifndef CONFIG_HISI_SNAPSHOT_BOOT
#include <linux/miscdevice.h>
#endif
#include <linux/proc_fs.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/system.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/string.h>
#include <linux/list.h>
#include <asm/delay.h>
#include <linux/timer.h>
#include <linux/delay.h>
#include <linux/poll.h>
#include <linux/kthread.h>
#include <linux/sched.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#include "tp2823_def.h"
#include "tp2823.h"
#ifdef CONFIG_HISI_SNAPSHOT_BOOT
#include "himedia.h"
#define DEV_NAME "tp2823"
static struct himedia_device s_stTp2823Device;
#endif
static struct i2c_board_info hi_info =
{
I2C_BOARD_INFO("tp2823", 0x88),
};
static struct i2c_client* tp2823_client;
#define MUXCTRL_BASE 0x200F0000
#define HW_REG(reg) *((volatile unsigned int *)(reg))
#define MUXCTRL_REG(offset) IO_ADDRESS(MUXCTRL_BASE + (offset))
MODULE_AUTHOR("Jay Guillory <
[email protected]>");
MODULE_DESCRIPTION("TechPoint TP2802 Linux Module");
MODULE_LICENSE("GPL");
enum
{
TP2802C = 0x0200,
TP2802D = 0x0201,
TP2804 = 0x0400,
TP2806 = 0x0401,
TP2822 = 0x2200,
TP2823 = 0x2300
};
//TP2823 audio
//both record and playback are master, 16ch,I2S mode.
//#define SAMPLE_16K //if no define, default 8K
#define DATA_16BIT //if no define, default 8BIT
//TP2802D EQ for short cable option
#define TP2802D_EQ_SHORT 0x0d
#define TP2802D_CGAIN_SHORT 0x74
//#define TP2802D_EQ_SHORT 0x01
//#define TP2802D_CGAIN_SHORT 0x70
#define BT1120_HEADER_8BIT 0x00 //reg0x02 bit3 0=BT1120,
#define BT656_HEADER_8BIT 0x08 //reg0x02 bit3 1=656,
#define SAV_HEADER BT1120_HEADER_8BIT
static int mode = TP2802_720P25;
static int chips = 4;
static int output = MUX_1CH;
static int id[MAX_CHIPS];
#define TP2802A_I2C_ADDR 0x88
#define TP2802B_I2C_ADDR 0x8A
#define TP2802C_I2C_ADDR 0x8C
#define TP2802D_I2C_ADDR 0x8E
void tp28xx_byte_write(unsigned char chip_addr, unsigned char reg_addr, unsigned char value)
{
int ret;
unsigned char buf[2];
struct i2c_client* client = tp2823_client;
tp2823_client->addr = chip_addr;
buf[0] = reg_addr;
buf[1] = value;
ret = i2c_master_send(client, buf, 2);
//return ret;
}
unsigned char tp28xx_byte_read(unsigned char chip_addr, unsigned char reg_addr)
{
int ret_data = 0xFF;
int ret;
struct i2c_client* client = tp2823_client;
unsigned char buf[2];
tp2823_client->addr = chip_addr;
buf[0] = reg_addr;
ret = i2c_master_recv(client, buf, 1);
if (ret >= 0)
{
ret_data = buf[0];
}
return ret_data;
}
unsigned char tp2802_i2c_addr[] = { TP2802A_I2C_ADDR,
TP2802B_I2C_ADDR,
TP2802C_I2C_ADDR,
TP2802D_I2C_ADDR
};
#define TP2802_I2C_ADDR(chip_id) (tp2802_i2c_addr[chip_id])
#define SCAN_ENABLE 1
#define SCAN_DISABLE 0
#define MAX_COUNT 0xffff
typedef struct
{
unsigned int count[CHANNELS_PER_CHIP];
unsigned int mode[CHANNELS_PER_CHIP];
unsigned int scan[CHANNELS_PER_CHIP];
unsigned int gain[CHANNELS_PER_CHIP][4];
//unsigned int std[CHANNELS_PER_CHIP];
unsigned int state[CHANNELS_PER_CHIP];
unsigned int force[CHANNELS_PER_CHIP];
unsigned char addr;
} tp2802wd_info;
static const unsigned char SYS_MODE[4] = {0x01, 0x02, 0x04, 0x08};
static const unsigned char SYS_AND[4] = {0xfe, 0xfd, 0xfb, 0xf7};
static const unsigned char CLK_MODE[4] = {0x01, 0x10, 0x01, 0x10};
static const unsigned char CLK_ADDR[4] = {0xfa, 0xfa, 0xfb, 0xfb};
static const unsigned char CLK_AND[4] = {0xf8, 0x8f, 0xf8, 0x8f};
static tp2802wd_info watchdog_info[MAX_CHIPS];
volatile static unsigned int watchdog_state = 0;
struct task_struct* task_watchdog_deamon = NULL;
static DEFINE_SPINLOCK(watchdog_lock);
#define WATCHDOG_EXIT 0
#define WATCHDOG_RUNNING 1
#define WDT 1
int TP2802_watchdog_init(void);
void TP2802_watchdog_exit(void);
static void TP2822_PTZ_mode(unsigned char, unsigned char);
#if 0
unsigned char tp28xx_byte_write(unsigned char chip_addr,
unsigned char addr ,
unsigned char data )
{
#ifndef HI_FPGA
#ifdef HI_GPIO_I2C
gpio_i2c_write(chip_addr, addr, data);
#else
HI_I2C_Write(chip_addr, addr, 1, data, 1);
udelay(1000); //HI_I2C_Write足??足
#endif
#else
if (TW2865A_I2C_ADDR == chip_addr || TW2865B_I2C_ADDR == chip_addr)
{
gpio_i2c_write(chip_addr,addr,data);
}
else
{
gpio_i2c1_write(chip_addr,addr,data);
}
#endif
return 0;
}
unsigned char tp28xx_byte_read(unsigned char chip_addr, unsigned char addr)
{
#ifndef HI_FPGA
#ifdef HI_GPIO_I2C
return gpio_i2c_read(chip_addr, addr);
#else
return (HI_I2C_Read(chip_addr, addr, 1, 1) & 0xff);
#endif
#else
if (TW2865A_I2C_ADDR == chip_addr || TW2865B_I2C_ADDR == chip_addr)
{
return gpio_i2c_read(chip_addr,addr);
}
else
{
return gpio_i2c1_read(chip_addr,addr);
}
#endif
}
#endif
EXPORT_SYMBOL(tp28xx_byte_write);
EXPORT_SYMBOL(tp28xx_byte_read);
static void tp2802_write_table(unsigned char chip_addr,
unsigned char addr, unsigned char* tbl_ptr, unsigned char tbl_cnt)
{
unsigned char i = 0;
for (i = 0; i < tbl_cnt; i ++)
{
tp28xx_byte_write(chip_addr, (addr + i), *(tbl_ptr + i));
}
}
#if 0
static void tp2802_read_table(unsigned char chip_addr,
unsigned char addr, unsigned char reg_num)
{
unsigned char i = 0, temp = 0;
for (i = 0; i < reg_num; i++ )
{
temp = tp28xx_byte_read(chip_addr, addr + i);
printk("reg 0x%02x=0x%02x,", addr + i, temp);
if (((i + 1) % 4) == 0)
{
printk("\n");
}
}
}
#endif
int tp2802_open(struct inode* inode, struct file* file)
{
return SUCCESS;
}
int tp2802_close(struct inode* inode, struct file* file)
{
return SUCCESS;
}
static void tp2802_set_work_mode_1080p25(unsigned chip_addr)
{
// Start address 0x15, Size = 9B
tp2802_write_table(chip_addr, 0x15, tbl_tp2802_1080p25_raster, 9);
}
static void tp2802_set_work_mode_1080p30(unsigned chip_addr)
{
// Start address 0x15, Size = 9B
tp2802_write_table(chip_addr, 0x15, tbl_tp2802_1080p30_raster, 9);
}
static void tp2802_set_work_mode_720p25(unsigned chip_addr)
{
// Start address 0x15, Size = 9B
tp2802_write_table(chip_addr, 0x15, tbl_tp2802_720p25_raster, 9);
}
static void tp2802_set_work_mode_720p30(unsigned chip_addr)
{
// Start address 0x15, Size = 9B
tp2802_write_table(chip_addr, 0x15, tbl_tp2802_720p30_raster, 9);
}
static void tp2802_set_work_mode_720p50(unsigned chip_addr)
{
// Start address 0x15, Size = 9B
tp2802_write_table(chip_addr, 0x15, tbl_tp2802_720p50_raster, 9);
}
static void tp2802_set_work_mode_720p60(unsigned chip_addr)
{
// Start address 0x15, Size = 9B
tp2802_write_table(chip_addr, 0x15, tbl_tp2802_720p60_raster, 9);
}
static int tp2823_audio_config_rmpos(unsigned i2c_addr, unsigned format, unsigned chn_num)
{
int i = 0;
//clear first
for (i=0; i<20; i++)
{
tp28xx_byte_write(i2c_addr, i, 0);
}
switch(chn_num)
{
case 2:
if (format)
{
tp28xx_byte_write(i2c_addr, 0x0, 1);
tp28xx_byte_write(i2c_addr, 0x1, 2);
}
else
{
tp28xx_byte_write(i2c_addr, 0x0, 1);
tp28xx_byte_write(i2c_addr, 0x8, 2);
}
break;
case 4:
if (format)
{
tp28xx
评论0