📄 i2c-gm-adap.c
字号:
unsigned char *p;
p=buf ;
if(! (client = kmalloc(sizeof(struct GMi2c_i2c_client),GFP_KERNEL)))
return ;
memcpy(client,&i2cdev_client_template,sizeof(struct i2c_client));
client->adapter = &bit_i2c_adapter;
client->adapter->flags = EEPROM_ID_WRITE; //I2C device address
client->adapter->data = start_addr ; //I2C offset
for (i=0 ; i<size ; i++) {
ret = i2c_master_send(client,p,1);
if (ret != 1){
printk("i2c-GM-adap.o: I2C Write error(ret:0x%x), reg = 0x%x, data = 0x%x!\n",ret,client->adapter->data,*p);
}
client->adapter->data++ ;
p++;
}
//status = bit_eeprom_adapter.algo->master_xfer(&bit_eeprom_adapter,&msg,msg.len);
kfree(client);
}
static unsigned int get_ahb_clk(void)
{
return AHB_CLK_IN;
}
void adjust_timer(void)
{
unsigned int timer_clk;
timer_clk=get_ahb_clk()/2;
printk("Adjust Timer to %d\n",timer_clk);
*(volatile unsigned int *)(TIMER_FTTMR010_VA_BASE+0x4)=(timer_clk/HZ)-1;
}
//#define ADDR_2 // support 16 bit internal address
static unsigned int ken_u32PMU_ReadHCLK(void)
{
return AHB_CLK_IN;
}
static unsigned int ken_u32PMU_ReadPCLK(void)
{
#if defined(CONFIG_PLATFORM_GM8120)
if (inw(PMU_FTPMU010_VA_BASE+0x28) & BIT2)
return (ken_u32PMU_ReadHCLK() >> 1);
else
return (ken_u32PMU_ReadHCLK());
#else
return (AHB_CLK_IN >> 1);
#endif
}
void fLib_I2C_SetClockdiv_i(unsigned int count)
{
//printk("i2c-GM-adap.o:count in fLib_I2C_SetClockdiv_i:%d\n",count);
if ( count < 0 )
return ;
outl(count, I2C_FTI2C010_VA_BASE + I2C_ClockDiv);
}
int GM_fLib_I2C_SetClockdiv(unsigned int i_SCLout) //i_CSCLout means I2C bus clock value , *1024
{
int i;
i_SCLout = i_SCLout *1024 ;
//printk("I2C bus Clock:%d",i_SCLout);
if ( i_SCLout == 0 ){
i_SCLout = I2C_Default_FREQ; // default. clock is 45KHz
}
/*if (i_SCLout > I2C_MAX_FREQ || i_SCLout==0) {
i_SCLout = I2C_MAX_FREQ; // max. clock is 400KHz
}
*/
//printk("i2c-GM-adap.o:Set I2C Bus Clock:0x%x\n",i_SCLout);
i = (((ken_u32PMU_ReadPCLK() + i_SCLout - 1) / i_SCLout) +
((I2C_GSR_Value & (BIT12 | BIT11 | BIT10)) >> 10) -
1 + 1 )/2;
if (i >= BIT10) {
printk("Pclk is to fast to form i2c clock, fail \n");
return -1;
}
fLib_I2C_SetClockdiv_i(i);
return 0;
}
void I2C_freq_init(void) {
int SCLout,i ;
SCLout = ken_u32PMU_ReadPCLK() /10; // PCLK must 10 times of SCLout
if (SCLout > I2C_MAX_FREQ)
SCLout = I2C_MAX_FREQ; // max. clock is 400KHz
i = (((ken_u32PMU_ReadPCLK() + SCLout - 1) / SCLout) +
((I2C_GSR_Value & (BIT12 | BIT11 | BIT10)) >> 10) -
1 + 1 )/2;
if (i >= BIT10) {
printk("Pclk is to fast to form i2c clock, fail \n");
return -1;
}
printk("current Clock div i:0x%x\n",i);
//GM_fLib_I2C_SetClockdiv(0x60);
fLib_I2C_SetClockdiv_i(i);
}
int i2c_dev_init(void)
{
int res;
printk("I2C_GM_ADAP_Version(%s) driver enable!\n",I2C_GM_ADAP_Version);
I2C_freq_init();
i2cdev_initialized = 0;
res = register_chrdev(I2C_MAJOR, "i2c", &i2cdev_fops);
if (res)
goto out;
res = class_register(&i2c_dev_class);
if (res)
goto out_unreg_chrdev;
if (i2c_iic_add_bus(&bit_i2c_adapter) <0) {
printk("i2c_iic_add_bus fail!\n");
return -1;
}
printk("i2c_iic_add_bus in i2c-GM-adap.c successfully!\n");
res = i2c_add_driver(&i2cdev_driver);
if (res)
goto out_unreg_class;
devfs_mk_dir("i2c");
printk("i2c_add_driver successfully!\n");
return 0;
out_unreg_class:
class_unregister(&i2c_dev_class);
out_unreg_chrdev:
unregister_chrdev(I2C_MAJOR, "i2c");
out:
printk(KERN_ERR "%s: Driver Initialisation failed\n", __FILE__);
return res;
}EXPORT_SYMBOL(i2c_dev_init);
void i2c_dev_exit(void)
{
i2c_del_driver(&i2cdev_driver);
i2c_iic_del_bus(&bit_i2c_adapter);
class_unregister(&i2c_dev_class);
devfs_remove("i2c");
unregister_chrdev(I2C_MAJOR,"i2c");
}EXPORT_SYMBOL(i2c_dev_exit);
//Add By Ken.Hsieh for testing
int GM8120_get_mac_eeprom(unsigned char *macp)
{
int i,j;
unsigned char *mac=macp, set[6]={0x10,0x20,0x30,0x40,0x50,0x60};
//unsigned char *mac=macp, set[6]={0x11,0x22,0x33,0x44,0x55,0x66};
//Add By Ken.Hsieh
//if set is "0x11,0x12,0x13,0x14,0x15,0x16, eth0 could ping successfully, but fail in ftp function"
j=i=(unsigned int)&cfg.mac-(unsigned int)&cfg;
//I2C_freq_init();
//GM_fLib_I2C_SetClockdiv(0x60);
//printk("Set ClockDiv !\n");
//seeprom_write(CONFIG_START_ADDR+i,6,set);
//printk("seeprom_write MAC successfully!\n");
seeprom_read(CONFIG_START_ADDR+j,6,mac);
printk(" MAC address[%02x%02x%02x%02x%02x%02x]:",mac[0],mac[1],mac[2],mac[3],mac[4],mac[5]);
if((mac[0]==0)&&(mac[1]==0)&&(mac[2]==0)&&(mac[3]==0)&&(mac[4]==0)&&(mac[5]==0))
return 0;
if((mac[0]==0xff)&&(mac[1]==0xff)&&(mac[2]==0xff)&&(mac[3]==0xff)&&(mac[4]==0xff)&&(mac[5]==0xff))
return 0;
return 1;
}EXPORT_SYMBOL(GM8120_get_mac_eeprom);
int GM8120_tv_init1(char *buf,int length)
{
int i;
for(i=0;i<length;i++)
{
seeprom_write(*(buf+i*2),1,(buf+i*2+1));
}
return 0;
}
int GM8120_tv_init2(char *buf,int length,unsigned char *macp)
{
int i;
for(i=0;i<length;i++)
{
seeprom_write(*(buf+i*2),1,(buf+i*2+1));
}
return 0;
}
static ssize_t i2cdev_read (struct file *file, char __user *buf, size_t count,
loff_t *offset)
{
char *tmp;
int ret;
#ifdef DEBUG
struct inode *inode = file->f_dentry->d_inode;
#endif /* DEBUG */
struct i2c_client *client = (struct i2c_client *)file->private_data;
/* copy user space data to kernel space. */
tmp = kmalloc(count,GFP_KERNEL);
if (tmp==NULL)
return -ENOMEM;
#ifdef DEBUG
printk("i2c-GM-adap.o: i2c-%d reading %d bytes.\n",MINOR(inode->i_rdev),
count);
#endif
//Add By Ken.Hsieh
ret = i2c_master_recv(client,tmp,count);
if (ret >= 0)
ret = copy_to_user(buf,tmp,count)?-EFAULT:ret;
kfree(tmp);
return ret;
}
static ssize_t i2cdev_write (struct file *file, const char __user *buf, size_t count,
loff_t *offset)
{
int ret;
char *tmp;
struct i2c_client *client = (struct i2c_client *)file->private_data;
/* copy user space data to kernel space. */
tmp = kmalloc(count,GFP_KERNEL);
if (tmp==NULL)
return -ENOMEM;
if (copy_from_user(tmp,buf,count)) {
kfree(tmp);
return -EFAULT;
}
#ifdef DEBUG
printk("i2c-GM-adap.o: writing %d bytes:%2x.\n",
count,*buf);
#endif
ret = i2c_master_send(client,tmp,count);
kfree(tmp);
return ret;
}
static int i2cdev_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned *arg)
{
struct GMi2c_i2c_client *client = (struct GMi2c_i2c_client *)file->private_data;
struct i2c_GM_msg *i2c_data ;
int count ;
int ret;
char *tmp,*tmp1;
#ifdef DEBUG
printk("i2c-GM-adap-adap.o: i2c-%d ioctl, cmd: 0x%x, arg: %s.\n",
MINOR(inode->i_rdev),cmd, arg);
#endif /* DEBUG */
switch ( cmd ) {
case I2C_SLAVE:
//Set address
client->adapter->data = arg;
#ifdef DEBUG
printk("i2c-GM-adap-adap.o:Setting adapter address:%2x in i2cdev_ioctl of i2c-GM-adap-adap.o \n",client->adapter->data);
#endif
return 0;
case I2C_SLAVE_FORCE:
client->adapter->flags = arg;
return 0;
case I2C_TENBIT:
printk("i2c-GM-adap.o:Funciton I2C_TENBIT not support!\n");
return 0;
case I2C_PEC:
printk("i2c-GM-adap.o:Funciton I2C_PEC not support!\n");
return 0;
case I2C_FUNCS:
printk("\nClock div:%d\n",arg);
//GM_fLib_I2C_SetClockdiv(arg);
return 0;
case I2C_RDWR:
i2c_data = arg;
//client->adapter->flags = i2c_data->addr; //device address
client->adapter->data = i2c_data->waddr; //offset
client->adapter->client_count = i2c_data->clockdiv ;
client->adapter->adap.retries = i2c_data->multiread_once;
count = i2c_data->len;
if(i2c_data->addr & 0x01)
client->flags = I2C_M_RD;
else
client->flags = 0;
client->adapter->flags = i2c_data->addr >> 1;
#ifdef DEBUG
printk("addr = 0x%x,waddr = 0x%x,len = 0x%x,buf= 0x%x,clockdiv = 0x%x\n",i2c_data->addr,i2c_data->waddr,i2c_data->len,i2c_data->buf,i2c_data->clockdiv);
#endif
tmp = kmalloc(count,GFP_KERNEL);
tmp1 = tmp ;
if (tmp==NULL){
printk("%s:Alloc memory fault!\n",__FUNCTION__);
return -ENOMEM;
}
if (copy_from_user(tmp,i2c_data->buf,count)) {
printk("%s:copy from user fault!\n",__FUNCTION__);
kfree(tmp);
return -EFAULT;
}
if (( client->flags & I2C_M_RD ) !=1 ) {
ret = i2c_master_send(client,tmp,count);
}
else {
ret = i2c_master_recv(client,tmp,count);
copy_to_user(i2c_data->buf,tmp,count);
}
kfree(tmp);
return ret;
case I2C_SMBUS:
printk("i2c-GM-adap.o:Funciton I2C_SMBUS not support!\n");
return 0;
default:
printk("i2c-GM-adap.o:Funciton default not support!\n");
return 0;
}
return 0;
}
static int i2cdev_open (struct inode *inode, struct file *file)
{
unsigned int minor = iminor(inode);
struct i2c_client *client;
struct i2c_adapter *adap;
struct i2c_dev *i2c_dev;
//Add By Ken.Hsieh
*(volatile unsigned int *)(I2C_ADDR+0x14)=1;
*(volatile unsigned int *)(I2C_ADDR+0x8)=0x3e; //0x40
//printk("Init I2C_ADDR..\n");
// adjust_timer();
//I2C_freq_init();
i2c_dev = i2c_dev_get_by_minor(minor);
if (!i2c_dev)
return -ENODEV;
adap = i2c_get_adapter(i2c_dev->adap->nr);
if (!adap)
return -ENODEV;
client = kmalloc(sizeof(*client), GFP_KERNEL);
if (!client) {
i2c_put_adapter(adap);
return -ENOMEM;
}
memcpy(client, &i2cdev_client_template, sizeof(*client));
/* registered with adapter, passed as client to user */
client->adapter = adap;
client->addr = Display_ID;
file->private_data = client;
#ifdef DEBUG
printk("i2c-GM-adap.o: opened i2c-%d\n",minor);
#endif
return 0;
}
static int i2cdev_release (struct inode *inode, struct file *file)
{
struct i2c_client *client = file->private_data;
i2c_put_adapter(client->adapter);
kfree(client);
file->private_data = NULL;
return 0;
}
unsigned int i2c_ready=0;
int GM_i2c_xfer(struct i2c_msg *msgs, int num, int clockdiv)
{
extern int GM_i2c_doxfer(struct i2c_msg *msgs, int num);
int ret = 0;
I2C_LOCK((&bit_i2c_adapter));
#if 0
ret = GM_fLib_I2C_SetClockdiv(clockdiv);
if (ret !=0 ) {
printk("%s:Error in SetClockdiv of GM_i2c_write\n", __FUNCTION__);
*(unsigned int *)(I2C_FTI2C010_0_VA_BASE+0x08) = 0xf9;
*(unsigned int *)(I2C_FTI2C010_0_VA_BASE+0x14) = 0x417;
// return ret;
}
#endif
*(unsigned int *)(I2C_FTI2C010_0_VA_BASE+0x08) = 0xf9;
*(unsigned int *)(I2C_FTI2C010_0_VA_BASE+0x14) = 0x417;
//*(unsigned int *)(I2C_FTI2C010_0_VA_BASE+0x14) = 0x401;
ret = GM_i2c_doxfer(msgs, num);
I2C_UNLOCK((&bit_i2c_adapter));
return ret;
}
EXPORT_SYMBOL(GM_i2c_xfer);
/*
static int i2cdev_close (struct inode *inode, struct file *file){
printk("i2c-GM-adap.o:i2cdev_close..\n");
i2cdev_ioctl(inode,file,I2C_SLAVE_FORCE,Display_ID)
return 0;
}
*/
/*
static int __init tv_init(void){
printk("I2C_GM_ADAP_Version(%s) driver enable!\n",I2C_GM_ADAP_Version);
seeprom_init();
}
*/
//module_init(i2c_dev_init);
MODULE_AUTHOR("GM Corp.");
MODULE_LICENSE("GM License");
EXPORT_SYMBOL(GM_i2c_read);
EXPORT_SYMBOL(GM_i2c_write);
EXPORT_SYMBOL(GM_fLib_I2C_SetClockdiv);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -