MTK 平台下,用GPIO模拟的I2C,MTK不建议这样做,说可能会有些影响;
可是会有什么影响呢?目前还不知道;
转载请注明出处:http://blog.csdn.net/yuanjungogogo
#define XXX_I2C_SLAVE_WRITE_ADDR 0x2A
static struct mutex xxx_mutex;
#define GPIO_SDA_PIN 90
#define GPIO_SCL_PIN 89
#define GPIO_SDA_PIN_M_GPIO GPIO_MODE_00
#define GPIO_SCL_PIN_M_GPIO GPIO_MODE_00
void cust_i2c_scl_set( unsigned char mode)
{
if(mt_set_gpio_mode(GPIO_SCL_PIN, GPIO_SDA_PIN_M_GPIO))
{
printk("XXX cust_i2c_scl_set mode failed \n");
}
if(mt_set_gpio_dir(GPIO_SCL_PIN, GPIO_DIR_OUT))
{
printk("XXX cust_i2c_scl_set dir failed \n");
}
if( mode == 1)
{
if(mt_set_gpio_out(GPIO_SCL_PIN, GPIO_OUT_ONE))
{
printk("XXX cust_i2c_scl_set high failed \n");
}
}
else
{
if(mt_set_gpio_out(GPIO_SCL_PIN, GPIO_OUT_ZERO))
{
printk("XXX cust_i2c_scl_set low failed \n");
}
}
printk("转载请注明出处:http://blog.csdn.net/yuanjungogogo");
}
void cust_i2c_sda_set( unsigned char mode)
{
if(mt_set_gpio_mode(GPIO_SDA_PIN, GPIO_SDA_PIN_M_GPIO))
{
printk("XXX cust_i2c_sda_set mode failed \n");
}
if(mt_set_gpio_dir(GPIO_SDA_PIN, GPIO_DIR_OUT))
{
printk("XXX cust_i2c_sda_set dir failed \n");
}
if( mode == 1)
{
if(mt_set_gpio_out(GPIO_SDA_PIN, GPIO_OUT_ONE))
{
printk("XXX cust_i2c_sda_set high failed \n");
}
}
else
{
if(mt_set_gpio_out(GPIO_SDA_PIN, GPIO_OUT_ZERO))
{
printk("XXX cust_i2c_sda_set low failed \n");
}
}
}
void cust_i2c_sda_dir_set( unsigned char mode)
{
if(mt_set_gpio_mode(GPIO_SDA_PIN, GPIO_SDA_PIN_M_GPIO))
{
printk("XXX cust_i2c_sda_dir_set mode failed \n");
}
if( mode == GPIO_DIR_IN)
{
if(mt_set_gpio_dir(GPIO_SDA_PIN, GPIO_DIR_IN))
{
printk("XXX cust_i2c_sda_dir_set in failed \n");
}
}
else
{
if(mt_set_gpio_dir(GPIO_SDA_PIN, GPIO_DIR_OUT))
{
printk("XXX cust_i2c_sda_dir_set out failed \n");
}
}
}
unsigned char cust_i2c_sda_get(void)
{
if(mt_set_gpio_mode(GPIO_SDA_PIN, GPIO_SDA_PIN_M_GPIO))
{
printk("XXX cust_i2c_sda_get mode failed \n");
}
if(mt_set_gpio_dir(GPIO_SDA_PIN,GPIO_DIR_IN))
{
printk("XXX cust_i2c_sda_get dir failed \n");
}
return mt_get_gpio_in(GPIO_SDA_PIN);
}
void cust_i2c_start(void)
{
//printk("cust_i2c_start \n");
cust_i2c_scl_set(1);
cust_i2c_sda_set(1);
udelay(5);
cust_i2c_sda_set(0);
udelay(5);
cust_i2c_scl_set(0);
}
void cust_i2c_stop(void)
{
//printk("cust_i2c_stop \n");
cust_i2c_scl_set(1);
cust_i2c_sda_set(0);
udelay(5);
cust_i2c_sda_set(1);
udelay(5);
}
char cust_i2c_get_ack(void)
{
unsigned char get_bit;
unsigned char i;
//printk("cust_i2c_get_ack \n");
//cust_i2c_sda_set(1);
//udelay(5);
cust_i2c_sda_dir_set(GPIO_DIR_IN);
cust_i2c_scl_set(1);
udelay(5);
//cust_i2c_sda_get();
for(i=0; i<10; i++)
{
get_bit = mt_get_gpio_in(GPIO_SDA_PIN);
udelay(5);
if(0 == get_bit)
{
break;
}
}
cust_i2c_scl_set(0);
cust_i2c_sda_dir_set(GPIO_DIR_OUT);
if(i == 10)
{
return -1;
}
return 0;
printk("转载请注明出处:http://blog.csdn.net/yuanjungogogo");
}
char cust_i2c_send_ack(void)
{
//printk("cust_i2c_send_ack \n");
cust_i2c_sda_set(0);
udelay(5);
cust_i2c_scl_set(1);
udelay(5);
cust_i2c_scl_set(0);
return 0;
}
void cust_i2c_no_ack(void)
{
//printk("cust_i2c_send_ack \n");
cust_i2c_sda_set(1);
cust_i2c_scl_set(1);
udelay(5);
cust_i2c_scl_set(0);
udelay(5);
}
void cust_i2c_send_byte( unsigned char udata)
{
char i;
//printk("cust_i2c_send_byte \n",udata);
for( i = 0; i<8;i++ )
{
if( ((udata>>(7-i)) & 0x01) == 0x01)
{
cust_i2c_sda_set(1);
}
else
{
cust_i2c_sda_set(0);
}
udelay(2);
cust_i2c_scl_set(1);
udelay(5);
cust_i2c_scl_set(0);
}
udelay(5);
}
unsigned char cust_i2c_get_byte( void )
{
char i;
unsigned char data;
unsigned char get_bit;
data = 0;
//printk("cust_i2c_get_byte \n");
cust_i2c_sda_dir_set(GPIO_DIR_IN);
for( i = 0; i<8; i++ )
{
cust_i2c_scl_set(1);
udelay(5);
//get_bit = cust_i2c_sda_get();
get_bit = mt_get_gpio_in(GPIO_SDA_PIN);
cust_i2c_scl_set(0);
udelay(5);
if( 1 == (get_bit &0x01))
{
data |= get_bit <<(7-i);
}
}
udelay(5);
return data;
}
char cust_i2c_write_byte(unsigned char addr, unsigned char regaddr, unsigned char udata)
{
char res;
cust_i2c_start();
cust_i2c_send_byte(addr);
res = cust_i2c_get_ack();
if(0 != res)
{
printk("XXX cust_i2c_write_byte device addr error \n");
return -1;
}
cust_i2c_send_byte(regaddr);
res = cust_i2c_get_ack();
if( 0 != res )
{
printk("XXX cust_i2c_write_byte reg addr error \n");
return -1;
}
cust_i2c_send_byte(udata);
res = cust_i2c_get_ack();
if( 0 != res )
{
printk("XXX cust_i2c_write_byte reg data error \n");
return -1;
}
cust_i2c_stop();
return 0;
}
char cust_i2c_read_byte(unsigned char addr, unsigned char regaddr, unsigned char *udata)
{
unsigned char data;
char res;
cust_i2c_start();
cust_i2c_send_byte( addr );
res = cust_i2c_get_ack();
if( 0 != res )
{
printk("XXX cust_i2c_read_byte device addr error \n");
return -1;
}
cust_i2c_send_byte( regaddr );
res = cust_i2c_get_ack();
if( 0 != res )
{
printk("XXX cust_i2c_read_byte reg addr error \n");
return -1;
}
cust_i2c_start();
addr |= 0x01;
cust_i2c_send_byte( addr );
res = cust_i2c_get_ack();
if( 0 != res )
{
printk("XXX cust_i2c_read_byte devce addr error \n");
return -1;
}
*udata = cust_i2c_get_byte();
cust_i2c_no_ack();
cust_i2c_stop();
return 0;
printk("转载请注明出处:http://blog.csdn.net/yuanjungogogo");
}
char cust_i2c_write_bytes(unsigned char addr, unsigned char regaddr, unsigned char *udata, unsigned int count)
{
u32 i;
char res;
cust_i2c_start();
cust_i2c_send_byte( addr );
res = cust_i2c_get_ack();
if( 0 != res )
{
printk("XXX cust_i2c_write_bytes device addr error \n");
return -1;
}
cust_i2c_send_byte( regaddr );
res = cust_i2c_get_ack();
if( 0 != res )
{
printk("XXX cust_i2c_write_bytes reg addr error \n");
return -1;
}
for( i = 0; i< count; i++)
{
cust_i2c_send_byte(udata[i]);
res = cust_i2c_get_ack();
if(0 != res)
{
printk("XXX cust_i2c_write_bytes reg data error \n",__FUNCTION__,__LINE__);
return -1;
}
}
cust_i2c_stop();
return 0;
}
char cust_i2c_read_bytes(unsigned char addr, unsigned char regaddr, unsigned char *udata,unsigned int count)
{
unsigned char data;
unsigned int i;
char res;
cust_i2c_start();
cust_i2c_send_byte( addr );
res = cust_i2c_get_ack();
if( 0 != res )
{
printk("XXX cust_i2c_read_bytes device addr error \n");
return -1;
}
cust_i2c_send_byte( regaddr );
res = cust_i2c_get_ack();
if( 0 != res )
{
printk("XXX cust_i2c_read_bytes reg addr error \n");
return -1;
}
cust_i2c_start();
addr |= 0x01;
cust_i2c_send_byte( addr );
res = cust_i2c_get_ack();
if( 0 != res )
{
printk("XXX cust_i2c_read_bytes reg addr error \n");
return -1;
}
for( i = 0; i < count-1; i++)
{
udata[i] = cust_i2c_get_byte();
res = cust_i2c_send_ack();
if(0 != res)
{
printk("XXX cust_i2c_read_bytes reg data error \n");
return -1;
}
}
udata[i] = cust_i2c_get_byte();
cust_i2c_no_ack();
cust_i2c_stop();
return data;
}
int cust_i2c_master_send(struct i2c_client *client, u8 *buf, u8 count)
{
u8 slave_addr;
u8 reg_addr;
mutex_lock(&xxx_mutex);
slave_addr = XXX_I2C_SLAVE_WRITE_ADDR ;
reg_addr = buf[0];
#if defined(XXX_I2C_GPIO_MODE_DEBUG)
printk("XXX cust_i2c_master_send_byte reg_addr=0x x% \n", reg_addr);
#endif
cust_i2c_write_bytes(slave_addr,reg_addr, &buf[1],count-1);
mutex_unlock(&xxx_mutex);
return count;
}
int cust_i2c_master_read(struct i2c_client *client, u8 *buf, u8 count)
{
u8 slave_addr;
u8 reg_addr;
slave_addr = XXX_I2C_SLAVE_WRITE_ADDR ;
reg_addr = buf[0];
#if defined(XXX_I2C_GPIO_MODE_DEBUG)
printk("XXX cust_i2c_master_read_byte reg_addr=0x %x\n", reg_addr);
#endif
cust_i2c_read_bytes(slave_addr,reg_addr, &buf[0],count);
return count;
}
int cust_hwmsen_write_block(struct i2c_client *client, u8 addr, u8 *data, u8 len)
{
u8 slave_addr;
u8 reg_addr;
mutex_lock(&xxx_mutex);
slave_addr = XXX_I2C_SLAVE_WRITE_ADDR;
reg_addr = addr;
#if defined(XXX_I2C_GPIO_MODE_DEBUG)
printk("XXX cust_hwmsen_write_block reg_addr=0x%x\n", reg_addr);
#endif
cust_i2c_write_bytes(slave_addr,reg_addr, data,len);
mutex_unlock(&xxx_mutex);
return 0;
}
int cust_hwmsen_read_block(struct i2c_client *client, u8 addr, u8 *data, u8 len)
{
u8 buf[64] = {0};
mutex_lock(&xxx_mutex);
buf[0] = addr;
cust_i2c_master_read(client, buf, len);
mutex_unlock(&xxx_mutex);
#if defined(XXX_I2C_GPIO_MODE_DEBUG)
printk("XXX cust_hwmsen_read_block addr=0x%x, buf=0x%x\n", addr, buf[0]);
#endif
memcpy(data, buf, len);
return 0;
printk("转载请注明出处:http://blog.csdn.net/yuanjungogogo");
}