⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 apb_i2c_module.c

📁 这个代码是基于JADE X90+ wm8976 的 ALSA标准接口的驱动
💻 C
字号:
/********************************************//* I2CFunc.c: implementation of the I2C API.*//* Author   : DQ							*//* Time     : 2005-12-15					*//********************************************/#include <linux/major.h>#include <linux/vmalloc.h>#include <linux/init.h>#include <linux/interrupt.h>#include <linux/module.h>#include <linux/blkdev.h>#include <linux/bitops.h>#include <linux/delay.h>#include <asm/uaccess.h>#include <asm/io.h>#include <asm/arch-x900/apb_i2c_module.h>#include <asm/arch-x900/apb_i2c_tvin.h>#ifdef CONFIG_ARCH_X900	 #define PHY_SYS_BASE    0x20031000	 #define PHY_I2C_BASE    0x20026000#else	#define PHY_SYS_BASE	0x20020000	#define	PHY_I2C_BASE	     0x20036000#endif#define SZ_4K           0x1000unsigned int *g_i2c_base = 0;unsigned int *g_sysctrl_base = 0;/* This struct aims at translate parameters.** Para : addr , the slave's address** Para : control, the control register's value** Para : mask, the mask for interrupt** Para : rx , the recive FIFO's depth** Para : tx , the transmit FIFO's depth **/typedef struct {	unsigned short addr;	unsigned short control;	unsigned short mask;	unsigned short rx;	unsigned short tx;}i2cConfig;/* This struct describe the SCL Paramter ** mode : this is the I2C translate mode , such as SS = SlowSpeed, FS = Full Speed , HS = High Speed** hcnt : this is the High period for the SCL** lcnt : this is the Low period for the SCL**/typedef struct {	I2CMODE mode;	unsigned short hcnt;	unsigned short lcnt;}i2cSpeedMode;void i2cSetConfig(i2cConfig* Init_data, i2cSpeedMode* m ){	I2C_DISABLE;	if(Init_data)	{		I2C_SAR(Init_data->addr);//Set the address of the i2c device		I2C_CON(Init_data->control);//Set the control register for the transfer	    I2C_INTR_MASK(Init_data->mask);//Enable interrupts		I2C_RX_TL(Init_data->rx);//Set Rx FIFO Threshold 	    I2C_TX_TL(Init_data->tx);//Set Tx FIFO Threshold    }	if(m)	{		switch(m->mode)		{		case I2C_SS:			I2C_SS_HCNT(m->hcnt);			I2C_SS_LCNT(m->lcnt);			break;		case I2C_FS:			I2C_FS_HCNT(m->hcnt);			I2C_FS_LCNT(m->lcnt);			break;		case I2C_HS:			I2C_HS_HCNT(m->hcnt);			I2C_HS_LCNT(m->lcnt);			break;			default:			{				I2C_ERROR("There is no such I2C mode.");				break;			}		}	}		I2C_ENABLE;//Enable the I2C MASTER}void i2cSetTarget( char target_addr){	//Disable the I2C MASTER, all the config should be set when the i2c master is disabled    if (target_addr)    {    	I2C_DISABLE;	    I2C_TAR(target_addr/2);//Set the address for the target slave		I2C_ENABLE;//Enable the I2C MASTER	}}/* brief : Initialize the I2C module */i2cInst* init_i2c(){	int error = 0;	i2cInst* t = 0;		i2cConfig* g_initData = 0;	i2cSpeedMode* spemode = 0;	// Define the Initialize parameters 		t = (i2cInst*)vmalloc( sizeof(i2cInst));	if( t )	{		t->config = (void*)vmalloc( sizeof(i2cConfig) );		t->speed = (void*)vmalloc( sizeof(i2cSpeedMode) );	}	else		error = 1;		g_initData = (i2cConfig*)t->config;	spemode = (i2cSpeedMode*)t->speed;	g_initData->addr = 0x0045;//slave address	g_initData->control = 0x0023;//change from 0x0003    /* Ruskee: Why change from 0x03?*/	g_initData->mask = 0x0000;	g_initData->rx = 0x0008;  /*Ruskee: Why change from 0x0*/	g_initData->tx = 0x0000;	spemode->mode = I2C_SS;	spemode->hcnt = 0x0028;//0x88; 	spemode->lcnt = 0x002f;//0x8f;	g_i2c_base = (u32 *)(ioremap(PHY_I2C_BASE, SZ_4K));		i2cSetConfig(g_initData,spemode);	return t;}/* brief : Delete the I2C module from the system */void dele_i2c(i2cInst* t){	if(t)	{		if(t->config)			vfree(t->config);		if(t->speed)			vfree(t->speed);		vfree(t);	}	iounmap(g_i2c_base);}// wait for Receive FIFO Not Emptyint waitRFNE(unsigned int timeout){	timeout = timeout*10000;	while(!(I2C_STATUS & RFNE)&&timeout)	{		timeout --;	}	if( timeout > 0 )		return 0;	else		return -1;}// Transmit FIFO Not Fullbool isTFNF(void){	if (I2C_STATUS & TFNF)	   return true;	else	   return false;}// wait for Transmit FIFO Completely Emptyint waitTFE(unsigned int timeout){	timeout = timeout*10000;	while(!(I2C_STATUS & TFE)&&timeout)	{		timeout --;	}	if( timeout > 0 )		return 0;	else		return -1;}/* brief: This API is used to transmit data ** para : threhold -- the  threhold of the FIFO** para : buffer -- the pointer of data** para : target -- the address of the target*/ int transmitData(const int threhold, const unsigned char buffer[], const unsigned short target){	int error = 0 ,i;		if(!g_i2c_base)		return -1;		if(threhold < 0 || threhold >255){		error = 1;		return error;	}		I2C_DISABLE;		I2C_TX_TL((threhold-1));	I2C_TAR(target);				I2C_ENABLE;	error = waitTFE(100);		i=0;	while(i < threhold)	{	   while (!isTFNF());		I2C_WRITE (buffer[i++]);		{			int k = 4;			while( k -- );		}	}		error = waitTFE(100);	udelay(100);	//hw_delay(1);	return error;}int ReadData(const int threhold, const unsigned char buffer[], const unsigned short target , unsigned char buffer2[]){	int i, error = 0,tx_num = threhold;	if(!g_i2c_base)	{		return -1;	}	I2C_DISABLE;	I2C_TX_TL((1));	I2C_TAR(target);			   I2C_CON(I2CR_CON | 0x20);	I2C_ENABLE;		error = waitTFE(100);	i=0;	while(i < threhold)	{		I2C_WRITE (buffer[i++]);		{			int k = 4;			while( k -- );		}	}	i = 0;	while( i < threhold && !error)	{			while(((I2C_STATUS)&(TFNF))&&tx_num)		{			I2C_WRITE(0x100);				tx_num--;		}		error = waitRFNE(100);		buffer2[ i ] = I2C_READ;		i++;	}	return error;}int i2cWrite( i2cInst* inst , const unsigned short target , const unsigned char* address , int acount , unsigned char* value , int vcount ){	int error = 0 ,i = 0;	if(target != inst->target)	{		inst->target = target;		i2cSetTarget(target);	}	error = waitTFE(100);	while( i < acount && !error)	{		I2C_WRITE (address[i++]);		{			int k = 4;			while( k -- );		}	}	i = 0;	while( i < vcount && !error)	{		I2C_WRITE (value[i++]);		{			int k = 4;//33000/4;			while( k -- );		}	}	error = waitTFE(100);	return error;}int i2cRead( i2cInst* inst , const unsigned short target , const unsigned char* address , int acount , unsigned char* value , int vcount ){	int error = 0 ,i = 0, tx_num = vcount;   if (!g_i2c_base)      return -1;	if(target != inst->target)	{		inst->target = target;		i2cSetTarget(target);	}   I2C_CON(I2CR_CON | 0x20);  /* Ruskee: Is it necessary to have this?*/	error = waitTFE(100);	while( i < acount && !error)	{		I2C_WRITE (address[i++]);		{			int k = 4;			while( k -- );		}	}	i = 0;	error = waitTFE(1000);	while( i < vcount && !error)	{			while(((I2C_STATUS)&(TFNF))&&tx_num)		{			I2C_WRITE(0x100);				tx_num--;		}		error = waitRFNE(100);		value[ i ] = I2C_READ;		i++;	}	return error;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -