MTK GPIO 模拟I2C

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");
}


你可能感兴趣的:(Android,Linux)