您的位置:首页 > 其它

基于高通MSM 8x60的I2C驱动终极讲解(1)

2014-01-16 19:48 363 查看
网上的I2C驱动讲解已经很多啦,我不想画蛇添足,我想写一个完整的I2C驱动,包括系统启动,总线注册,驱动注册,设备注册,里面会贯穿Linux设备驱动模型,platform机制等等,基于高通MSM 8x60,I2C控制器为qup,下面开始进入正题:
首先是平台设备的注册:源码位置:(msm/arch/arm/mach-msm/devices-msm8x60.c)
首先说下平台设备,因为Linux所有的设备都是通过总线控制器连接到CPU的,但是还有一些设备不是通过总线控制器连接到CPU,所以就有了platform总线虚拟总线,把那些不是真正通过总线控制器相连的设备,比如:SOC的片内设备,片内控制器,这些都归为平台设备.把这些平台设备通过虚拟总线连接到cpu上,以便维护Linux设备模型中的,总线,设备,驱动之间的关系。
首先注册BSP的平台设备驱动,其中I2C控制器的平台设备如下:
先看下高通的8x60,靠,有6个控制器,所有接下来的事情就是淡定。

下面的是6个控制器在I2C控制器的ID编号
#define MSM_GSBI3_QUP_I2C_BUS_ID 0

#define MSM_GSBI4_QUP_I2C_BUS_ID 1

#define MSM_GSBI9_QUP_I2C_BUS_ID 2

#define MSM_GSBI8_QUP_I2C_BUS_ID 3

#define MSM_GSBI7_QUP_I2C_BUS_ID 4

#define MSM_GSBI12_QUP_I2C_BUS_ID 5

下面是六个控制器所用到的资源
static struct resource gsbi3_qup_i2c_resources[] = {

{

.name = "qup_phys_addr",

.start = MSM_GSBI3_QUP_PHYS,

.end = MSM_GSBI3_QUP_PHYS + SZ_4K - 1,

.flags = IORESOURCE_MEM,

},

{

.name = "gsbi_qup_i2c_addr",

.start = MSM_GSBI3_PHYS,

.end = MSM_GSBI3_PHYS + 4 - 1,

.flags = IORESOURCE_MEM,

},

{

.name = "qup_err_intr",

.start = GSBI3_QUP_IRQ,

.end = GSBI3_QUP_IRQ,

.flags = IORESOURCE_IRQ,

},

};
static struct resource gsbi4_qup_i2c_resources[] = {

{

.name = "qup_phys_addr",

.start = MSM_GSBI4_QUP_PHYS,

.end = MSM_GSBI4_QUP_PHYS + SZ_4K - 1,

.flags = IORESOURCE_MEM,

},

{

.name = "gsbi_qup_i2c_addr",

.start = MSM_GSBI4_PHYS,

.end = MSM_GSBI4_PHYS + 4 - 1,

.flags = IORESOURCE_MEM,

},

{

.name = "qup_err_intr",

.start = GSBI4_QUP_IRQ,

.end = GSBI4_QUP_IRQ,

.flags = IORESOURCE_IRQ,

},

};
static struct resource gsbi7_qup_i2c_resources[] = {

{

.name = "qup_phys_addr",

.start = MSM_GSBI7_QUP_PHYS,

.end = MSM_GSBI7_QUP_PHYS + SZ_4K - 1,

.flags = IORESOURCE_MEM,

},

{

.name = "gsbi_qup_i2c_addr",

.start = MSM_GSBI7_PHYS,

.end = MSM_GSBI7_PHYS + 4 - 1,

.flags = IORESOURCE_MEM,

},

{

.name = "qup_err_intr",

.start = GSBI7_QUP_IRQ,

.end = GSBI7_QUP_IRQ,

.flags = IORESOURCE_IRQ,

},

};
static struct resource gsbi8_qup_i2c_resources[] = {

{

.name = "qup_phys_addr",

.start = MSM_GSBI8_QUP_PHYS,

.end = MSM_GSBI8_QUP_PHYS + SZ_4K - 1,

.flags = IORESOURCE_MEM,

},

{

.name = "gsbi_qup_i2c_addr",

.start = MSM_GSBI8_PHYS,

.end = MSM_GSBI8_PHYS + 4 - 1,

.flags = IORESOURCE_MEM,

},

{

.name = "qup_err_intr",

.start = GSBI8_QUP_IRQ,

.end = GSBI8_QUP_IRQ,

.flags = IORESOURCE_IRQ,

},

};
static struct resource gsbi9_qup_i2c_resources[] = {

{

.name = "qup_phys_addr",

.start = MSM_GSBI9_QUP_PHYS,

.end = MSM_GSBI9_QUP_PHYS + SZ_4K - 1,

.flags = IORESOURCE_MEM,

},

{

.name = "gsbi_qup_i2c_addr",

.start = MSM_GSBI9_PHYS,

.end = MSM_GSBI9_PHYS + 4 - 1,

.flags = IORESOURCE_MEM,

},

{

.name = "qup_err_intr",

.start = GSBI9_QUP_IRQ,

.end = GSBI9_QUP_IRQ,

.flags = IORESOURCE_IRQ,

},

};
static struct resource gsbi12_qup_i2c_resources[] = {

{

.name = "qup_phys_addr",

.start = MSM_GSBI12_QUP_PHYS,

.end = MSM_GSBI12_QUP_PHYS + SZ_4K - 1,

.flags = IORESOURCE_MEM,

},

{

.name = "gsbi_qup_i2c_addr",

.start = MSM_GSBI12_PHYS,

.end = MSM_GSBI12_PHYS + 4 - 1,

.flags = IORESOURCE_MEM,

},

{

.name = "qup_err_intr",

.start = GSBI12_QUP_IRQ,

.end = GSBI12_QUP_IRQ,

.flags = IORESOURCE_IRQ,

},

};

下面是为6个I2C控制器所注册平台设备驱动需要的结构体

/* Use GSBI3 QUP for /dev/i2c-0 */

struct platform_device msm_gsbi3_qup_i2c_device = {

.name = "qup_i2c",

.id = MSM_GSBI3_QUP_I2C_BUS_ID,

.num_resources = ARRAY_SIZE(gsbi3_qup_i2c_resources),

.resource = gsbi3_qup_i2c_resources,

};
/* Use GSBI4 QUP for /dev/i2c-1 */

struct platform_device msm_gsbi4_qup_i2c_device = {

.name = "qup_i2c",

.id = MSM_GSBI4_QUP_I2C_BUS_ID,

.num_resources = ARRAY_SIZE(gsbi4_qup_i2c_resources),

.resource = gsbi4_qup_i2c_resources,

};
/* Use GSBI8 QUP for /dev/i2c-3 */

struct platform_device msm_gsbi8_qup_i2c_device = {

.name = "qup_i2c",

.id = MSM_GSBI8_QUP_I2C_BUS_ID,

.num_resources = ARRAY_SIZE(gsbi8_qup_i2c_resources),

.resource = gsbi8_qup_i2c_resources,

};
/* Use GSBI9 QUP for /dev/i2c-2 */

struct platform_device msm_gsbi9_qup_i2c_device = {

.name = "qup_i2c",

.id = MSM_GSBI9_QUP_I2C_BUS_ID,

.num_resources = ARRAY_SIZE(gsbi9_qup_i2c_resources),

.resource = gsbi9_qup_i2c_resources,

};
/* Use GSBI7 QUP for /dev/i2c-4 (Marimba) */

struct platform_device msm_gsbi7_qup_i2c_device = {

.name = "qup_i2c",

.id = MSM_GSBI7_QUP_I2C_BUS_ID,

.num_resources = ARRAY_SIZE(gsbi7_qup_i2c_resources),

.resource = gsbi7_qup_i2c_resources,

};
/* Use GSBI12 QUP for /dev/i2c-5 (Sensors) */

struct platform_device msm_gsbi12_qup_i2c_device = {

.name = "qup_i2c",

.id = MSM_GSBI12_QUP_I2C_BUS_ID,

.num_resources = ARRAY_SIZE(gsbi12_qup_i2c_resources),

.resource = gsbi12_qup_i2c_resources,

};
注意该6个平台设备结构体的name都是"qup_i2c",下面这些平台设备将在BSP资源注册的时候给添加到系统。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: