#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/i2c.h>
#include <linux/io.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/of_device.h>
#include <linux/module.h>
#include <linux/reset.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/of_platform.h>
#include <linux/clk-provider.h>
#include <linux/pinctrl/consumer.h>
#include <asm/unaligned.h>
#include "8619c.h"
#define SDTV 0x00 // 480P 576P
#define SDPC 0x10 // 640x480 800x600 1024x768 etc
#define HDTV 0x20 // 720P 1080P
#define HDPC 0x30 // 1366x768 1600x900 etc
//如果有接外部参考电阻(Pin 16 - REXT, 2K 电阻),优先使用外部参考电阻
#define _Internal_ 0x88 // internal resistance
#define _External_ 0x80 // external resistance(Pin 16 - REXT, 2K resistance)
//*********************RGB Config*****************************//
#define _Output_3x8bit_ 0x00 // RGB888 24 bit
#define _Output_3x6bit_High_ 0x80 // High 18 bit active
#define _Output_3x6bit_Low_ 0xa0 // Low 18 bit active
#define _Output_3x565_High_ 0xc0 // High 16 bit active
#define _Output_3x565_Low_ 0xe0 // Low 16 bit active
#define RST_GPIO_ACTIVE_LOW 0
#define RST_GPIO_ACTIVE_HIGH 1
#define Delay_ms msleep
#define GPIO_NUM (256)
#define _6bit_Dither_En 0x38
#define _6bit_Dither_Dis 0x00
//================================//
#define _Bit_Swap_En 0x10 // bit24 ~ bit0 high/low bit swap enable.
#define _Bit_Swap_Dis 0x00
//================================//
#define _OutPut_RGB_ 0x07
#define _OutPut_RBG_ 0x06
#define _OutPut_GRB_ 0x05
#define _OutPut_GBR_ 0x04
#define _OutPut_BRG_ 0x03
#define _OutPut_BGR_ 0x00
//================================//
#define _Red_Bit_Swap_En 0x20 // Red bit7 ~ bit0 swap enable
#define _Red_Bit_Swap_Dis 0x00
#define _Green_Bit_Swap_En 0x40 // Green bit7 ~ bit0 swap enable
#define _Green_Bit_Swap_Dis 0x00
#define _Blue_Bit_Swap_En 0x80 // Blue bit7 ~ bit0 swap enable
#define _Blue_Bit_Swap_Dis 0x00
#define HD8619C_CHIP_ID_0X0 (0x16)
#define HD8619C_CHIP_ID_0X1 (0x04)
static void __iomem *aon_pin_mux_base;
static void __iomem *pmm_base;
#define ZX_LB_AON_IO_58 (aon_pin_mux_base + 0x80)
#define ZX_LB_PMM_IO_58 (pmm_base + 0x80)
#define ZX_LB_AON_IO_59 (aon_pin_mux_base + 0x84)
#define ZX_LB_PMM_IO_59 (pmm_base + 0x84)
//**********************************************//
// u8 LT8619C_Output_Mode ;// = _TTL_Output_;
u8 Refer_Resistance ;
bool Load_HDCPKey_En ;
bool CLK_DDRMODE_EN ;
u8 CP_Convert_Mode ;
// when LT8619C_Output_Mode == _RGB_Output_
u8 TTL_Color_Mode ;
u8 TTL_Bit_Swap ;
u8 TTL_Output_RGB_Swap ;
u8 Red_Bit_Swap ;
u8 Green_Bit_Swap;
u8 Blue_Bit_Swap;
#define ISP_REG_END 0xff
#define INVALID_VAL 0x0
struct regval_list {
unsigned short reg_num;
unsigned char value;
};
struct i2c_reglist
{
unsigned char addr;
unsigned char data;
};
struct i2c_reg
{
unsigned char addr;
unsigned char data;
};
struct i2c_8619c_dev{
dev_t devno;
struct cdev *cdev;
struct device *dev;
int reset_gpio_8619c;
};
struct i2c_client *HD8619c_i2c_client =NULL;
struct i2c_8619c_dev *i2c_8619c_info;
void LT8619C_Config(void)
{
printk("itachi:++++++LT8619C_Config+++++++\n");
// LT8619C_Output_Mode = _TTL_Output_;;
// 如果有接外部参考电阻(Pin 16 - REXT, 2K 电阻),优先使用外部参考电阻
Refer_Resistance = _External_;// _Internal_ 0x88 // internal resistance
// _External_ 0x80 // external resistance(Pin 16 - REXT, 2K resistance)
Load_HDCPKey_En = 0;// 1:外接 HDCP key; 0:不使用 HDCP Key
CLK_DDRMODE_EN = 0; // 1: CLK divided by 2 ; 0 : Normal
CP_Convert_Mode = HDTV;
//******************************************//
// when LT8619C_Output_Mode == _RGB_Output_
TTL_Color_Mode = _Output_3x8bit_;
TTL_Bit_Swap = _Bit_Swap_Dis; // 0x10: bit24 ~ bit0 high/low bit swap enable. 0x00: Normal
TTL_Output_RGB_Swap = _OutPut_RGB_;
Red_Bit_Swap = _Red_Bit_Swap_Dis;// 0x20: Red bit7 ~ bit0 swap enable; 0x00 : Normal
Green_Bit_Swap = _Green_Bit_Swap_Dis;// 0x40: Red bit7 ~ bit0 swap enable; 0x00 : Normal
Blue_Bit_Swap = _Blue_Bit_Swap_Dis;// 0x80: Red bit7 ~ bit0 swap enable; 0x00 : Normal
return;
}
//switch to 0x60bank.
static const struct i2c_reglist i2c_8619c_register_table[] = {
{0xff,0x60},
};
//read 0x00 id.
static const struct i2c_reglist i2c_8619c_id_0x0_table[] = {
{0x0,INVALID_VAL},
};
//read 0x01 id.
static const struct i2c_reglist i2c_8619c_id_0x1_table[] = {
{0x1,INVALID_VAL},
};
//switch to 0x80bank.
static const struct i2c_reglist i2c_8619c_reg_0x80_table[] = {
{0xff,0x80},
};
//read 0x2c id.
static const struct i2c_reglist i2c_8619c_id_0x2c_table[] = {
{0x2c,INVALID_VAL},
};
//read rx signal
static const struct i2c_reglist i2c_8619c_id_0x43_table[] = {
{0x43,INVALID_VAL},
};
struct class HD8619c_class={
.name = "8619c_class",
};
static int HD8619c_open(struct inode * inode, struct file * file)
{
return 0;
}
static int HD8619c_close(struct inode *inode, struct file * filp)
{
return 0;
}
static int HD8619c_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
return 0;
}
ssize_t HD8619c_write(struct file *filp, const char __user *buf, size_t count, loff_t *fpos)
{
return 0;
}
ssize_t HD8619c_read(struct file * file, char __user * buf, size_t nbytes, loff_t * ppos)
{
return 0;
}
static struct file_operations HD8619c_fops = {
.open = HD8619c_open,
.release = HD8619c_close,
.unlocked_ioctl = HD8619c_ioctl,
.write = HD8619c_write,
.read = HD8619c_read,
};
static int zx_hd8619_i2c_write(struct i2c_client *i2c_client, const void *data, size_t count)
{
int xfer;
xfer = i2c_master_send(i2c_client, data, count);
if (xfer == count)
return 0;
else if (xfer < 0)
return xfer;
else
return -EIO;
}
static int zx_hd8619c_i2c_read(struct i2c_client *i2c_client, unsigned char addr)
{
int xfer;
// struct i2c_client *i2c_client =HD8619c_i2c_client;
xfer =i2c_smbus_read_byte_data(HD8619c_i2c_client, addr);
if (xfer < 0)
{
printk(KERN_ERR "%s: I2C smbus transfer error\n", __func__);
}
return xfer;
}
static int zx_hd8619_i2c_read_regs(const struct i2c_reg *tbl, unsigned int tbl_size)
{
int xfer = 0;
unsigned int i = 0;
unsigned char buf[2];
//struct i2c_client *i2c_client =HD8619c_i2c_client;
for (; tbl_size--; i++)
{
buf[0] = tbl[i].addr;
buf[1] = tbl[i].data;
xfer = zx_hd8619c_i2c_read(HD8619c_i2c_client, buf[0]);
if (xfer < 0) {
printk(KERN_ERR "%s: I2C device 0 read error: read 0x%x and data is 0x%x \n", __func__,tbl[i].addr,xfer);
return -EIO;
}
else
{
printk("%s:I2C device 0 read success: read 0x%x and data is 0x%x \n", __func__, tbl[i].addr,xfer);
}
}
return xfer;
}
static int zx_hd8619_i2c_update(struct i2c_client *i2c_client, const struct i2c_reg *tbl, unsigned int tbl_size)
{
int xfer = 0;
unsigned int i = 0;
unsigned char buf[2];
for (; tbl_size--; i++)
{
buf[0] = tbl[i].addr;
buf[1] = tbl[i].data;
xfer = zx_hd8619_i2c_write(i2c_client, buf, ARRAY_SIZE(buf));
if (xfer < 0){
printk(KERN_ERR "%s: I2C device 0 write error: xfer is %d \n", __func__, xfer);
return -EIO;
}
msleep(1);
#ifdef ZX_PCM3168_DEBUG
xfer = zx_hd8619_i2c_read(i2c_client, buf[0] );
if (xfer < 0) {
printk(KERN_ERR "%s: I2C device 0 read error: read 0x%x and data is 0x%x \n", __func__,buf[0],xfer);
return -EIO;
}
else{
评论2