2008年9月23日星期二

添加自己的i2c adapter (gpio转i2c)

用的这一款CPU没有i2c host,所以gpio模拟i2c,本来一个设备不用做i2c adapter,直接模拟就是了,但是接了3个i2c设备,ts,radio,touchpad,所以要用i2c总线。driver/i2c/下已经有比较成熟的代码了,所以添加我们这款CPU的adapter,然后做设备driver。
i2c通讯方式中有包含bit方式通讯,driver/i2c/algos/i2c-algo-bit.c
需要添加的是i2c-algo-bit.c里的setsda,setscl,getsda,getscl 4个函数

/* --- setting states on the bus with the right timing: --------------- */
#define setsda(adap,val) adap->setsda(adap->data, val)
#define setscl(adap,val) adap->setscl(adap->data, val)
#define getsda(adap) adap->getsda(adap->data)
#define getscl(adap) adap->getscl(adap->data)

做adapter数据结构
struct t30x_gpio_i2c_pins
{
unsigned int scl_gpio;
unsigned int scl_inout;
unsigned int scl_altfunc;
unsigned int sda_gpio;
unsigned int sda_inout;
unsigned int sda_altfunc;
};

struct t30x_gpio_i2c_data
{
struct t30x_gpio_i2c_pins gpio_pins;
struct i2c_adapter adapter;
struct i2c_algo_bit_data algo_data;
};

static struct t30x_gpio_i2c_data t30x_gpio_i2cd =
{
.gpio_pins =
{
.scl_gpio = 0x4,
.scl_inout = 0xff,
.sda_gpio = 0x8,
.sda_inout = 0xff,
},
.adapter =
{
.name = "t302b-gpio-i2c",
.owner = THIS_MODULE,
.id = I2C_HW_B_T30XGPIO,
.retries = 2,
.class = I2C_CLASS_ALL,
},
.algo_data =
{
.setsda = t30x_gpio_bit_setsda,
.setscl = t30x_gpio_bit_setscl,
.getsda = t30x_gpio_bit_getsda,
.getscl = NULL,
.udelay = 10,
.mdelay = 10,
.timeout = 100,
},
};

完成3个函数
static void t30x_gpio_bit_setscl(void *data, int val)
{
struct t30x_gpio_i2c_pins* gdata = (struct t30x_gpio_i2c_pins*)data;
//set output
if(T30X_GPIO_OUTPUT != gdata->scl_inout)
{
writel(readl(GPIO_OE)(gdata->sda_gpio), GPIO_OE);
gdata->scl_inout = T30X_GPIO_OUTPUT;
}
if (val)
writel(gdata->scl_gpio, GPIO_SET);
else
writel(gdata->scl_gpio, GPIO_CLEAR);
}

static void t30x_gpio_bit_setsda(void *data, int val)
{
struct t30x_gpio_i2c_pins* gdata = (struct t30x_gpio_i2c_pins*)data;
//set output
if(T30X_GPIO_OUTPUT != gdata->sda_inout)
{
writel(readl(GPIO_OE)(gdata->sda_gpio), GPIO_OE);
gdata->sda_inout = T30X_GPIO_OUTPUT;
}

if (val)
writel(gdata->sda_gpio, GPIO_SET);
else
writel(gdata->sda_gpio, GPIO_CLEAR);
}

static int t30x_gpio_bit_getsda(void *data)
{
int sda;
struct t30x_gpio_i2c_pins* gdata = (struct t30x_gpio_i2c_pins*)data;
//set input
if(T30X_GPIO_INPUT != gdata->sda_inout)
{
writel(readl(GPIO_OE)&(~(gdata->sda_gpio)), GPIO_OE);
gdata->sda_inout = T30X_GPIO_INPUT;
}
sda = readl(GPIO_LEVEL)&(gdata->sda_gpio);
return sda? 1 : 0;
}

完成gpio初始化函数
static int t30x_gpio_hw_init(void *data)
{
struct t30x_gpio_i2c_pins* gdata = (struct t30x_gpio_i2c_pins*)data;
//altfunc select
writel(readl(GPIO_ALTFUNC_SEL)&(~((gdata->scl_altfunc)(gdata->sda_altfunc))), GPIO_ALTFUNC_SEL);

//disable gpio interrupt mask
writel(readl(GPIO_INT_MASK)((gdata->scl_gpio)(gdata->sda_gpio)), GPIO_INT_MASK);

//set output
writel(readl(GPIO_OE)((gdata->scl_gpio)(gdata->sda_gpio)), GPIO_OE);

//set level high
writel(((gdata->scl_gpio)(gdata->sda_gpio)), GPIO_SET);
return 0;
}

模块初始化
static int __init t30x_gpio_i2c_init(void)
{
int err;
struct t30x_gpio_i2c_data *drv_data = &t30x_gpio_i2cd;
drv_data->adapter.algo_data = &(drv_data->algo_data);

//private data = gpio pins, set sda/scl will use it
drv_data->algo_data.data = &(drv_data->gpio_pins);

//gpio config
t30x_gpio_hw_init(&(drv_data->gpio_pins));

//add to i2c bit algos
if ((err = i2c_bit_add_bus(&drv_data->adapter) != 0))
{
printk(KERN_ERR "\033[0;40;36mERROR: Could not add %s to i2c bit algos\033[0m\r\n", drv_data->adapter.name); return err;
}

printk("t30x gpio i2c bus initialized\r\n");
return 0;
}

static void __exit t30x_gpio_i2c_exit(void)
{
struct t30x_gpio_i2c_data *drv_data = &t30x_gpio_i2cd;
i2c_bit_del_bus(&drv_data->adapter);
return;
}

module_init(t30x_gpio_i2c_init);
module_exit(t30x_gpio_i2c_exit);
MODULE_DESCRIPTION("GPIO-based I2C adapter for t30x systems");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("zhourr");

3 条评论:

匿名 说...

哥们,您好~我最近也在用GPIO转I2C做TSC2007的驱动,遇到点问题,想请教您,又没有您的联系方式,如果您有时间帮助我一下的话,请发邮件到我的邮箱dan20031@126.com,THANKS

yanmaneee 说...

hermes belt
yeezy boost 350 v2
cheap jordans
kobe 11
off white shoes
air max 97
yeezy
yeezy boost 350 v2
kyrie 4 shoes
golden goose

匿名 说...

off white outlet
a bathing ape
yeezy
goyard outlet
kd shoes
air jordan
jordan 12
bape clothing
fear of god hoodie
hermes bag