虫虫2003 发表于 2013-08-05 15:36

请问Linux下I2C设备驱动该如何写?

我想写一个Linux下的I2C设备驱动,基于系统中现有的I2C子系统,采用probe的方式来实现,请问此类代码是采用什么样的一种固定框架?我看了内核中一些设备的代码,觉得很复杂,而我只是想实现很简单的功能;网上也查了一些资料,但并没有找到详细叙述。
目前我的代码如下:static const struct i2c_device_id dm2016_ids[] =
{
    {"dm2016", 0},
    {/* END OF LIST */}
};
MODULE_DEVICE_TABLE(i2c, dm2016_ids);


struct dm2016_data {
    struct i2c_client *client;
};

static int __devinit dm2016_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
    struct dm2016_data *pstDM2016Data = NULL;
    struct device *pstDev = &client->dev;
    int s32Ret = 0;

    pstDM2016Data = kzalloc(sizeof(*pstDev), GFP_KERNEL);
    if (NULL == pstDM2016Data)
    {
      dev_err(pstDev, "alloc dm2016 data memory fail!\n");
      return -ENOMEM;
    }

    pstDM2016Data->client = client;
    i2c_set_clientdata(client, pstDM2016Data);


    dev_info(pstDev, "create dm2016 client OK!\n");
    return 0;
}

static int __devexit dm2016_remove(struct i2c_client *client)
{
    struct dm2016_data *pstDM2016Data = i2c_get_clientdata(client);

    kfree(pstDM2016Data);

    return 0;
}


static struct i2c_driver dm2016_driver = {
    .driver = {
      .name = "dm2016",
      .owner = THIS_MODULE,
    },
    .probe = dm2016_probe,
    .remove = __devexit_p(dm2016_remove),
    .id_table = dm2016_ids,
};

static int __init dm2016_init(void)
{
    return i2c_add_driver(&dm2016_driver);
}

static void __exit dm2016_exit(void)
{
    i2c_del_driver(&dm2016_driver);
}我想为设备定义自己的读写函数以及类似ioctl这样的操作,请问我在dm2016_probe函数中要做哪些操作?还有结构体dm2016_data需要哪些成员?
谢谢!

wwxxxxll 发表于 2013-08-06 17:20

要简单的就不用i2c框架,用misc或一般的udev就可以了
qq: 2379374402
群:163617970

虫虫2003 发表于 2013-08-06 22:56

wwxxxxll 发表于 2013-08-06 17:20 static/image/common/back.gif
要简单的就不用i2c框架,用misc或一般的udev就可以了
qq: 2379374402
群:163617970
我本来也是想用misc的,可是发现内核中现有的i2c读写接口函数参数都是struct i2c_client *client,这如果不用i2c子系统就不好搞吧。

wwxxxxll 发表于 2013-08-07 10:39

本帖最后由 wwxxxxll 于 2013-08-07 10:41 编辑

回复 3# 虫虫2003


我就是用misc写的i2c和spi和加速度传感器通讯,也用misc写过1-wire与ds18b20通讯
没有什么不好搞的
写usb或网卡的话就必须用系统提供的模型了
有兴趣加入我们的群。欢迎每一位linux驱动同好加入!

虫虫2003 发表于 2013-08-07 14:19

wwxxxxll 发表于 2013-08-07 10:39 static/image/common/back.gif
回复 3# 虫虫2003




能否给一个简单的示例代码或框架?

wwxxxxll 发表于 2013-08-08 10:01

这是用i2c和spi与重力加速度模块通信,i2c和spi是用gpio模拟的,在hi3515平台上
我把i2c和spi写成模块不是设备驱动,
然后用cdev写个重力加速度模块的设备驱动模块,然后用一个宏选择调用i2c或spi。
若想深入交流,请加我!

虫虫2003 发表于 2013-08-09 22:12

wwxxxxll 发表于 2013-08-08 10:01 static/image/common/back.gif
这是用i2c和spi与重力加速度模块通信,i2c和spi是用gpio模拟的,在hi3515平台上
我把i2c和spi写成模块不是 ...

谢谢你提供的代码,海思的平台我也搞过几个,包括3515,上面的i2c设备驱动我也做过,它的i2c驱动接口还是比较简单的,像i2c_write(unsigned char devaddress, unsigned char address, unsigned char data)这样,直接提供设备地址、寄存器地址、数据就行了,最终就是利用读写接口函数完成结构体file_operations中的一系列函数。但是我现在做的这个是Linux标准内核下的i2c设备驱动,而内核i2c提供的读写接口都是这样的s32 i2c_smbus_write_i2c_block_data(struct i2c_client *client, u8 command, u8 length, const u8 *values)我要想调用这些函数就得先得到*client,而这就必须使用probe方式,也就是我问题中那种代码框架。可是我现在既不知道probe函数里面要做什么事情,也不知道在哪里实现像file_operations中read、write、ioctl这类设备读写函数。不知你是否明白我的意思。

heyangya 发表于 2013-08-10 22:53

可以在probe里注册一个字符设备,然后实现read,write 等操作

虫虫2003 发表于 2013-08-11 02:26

heyangya 发表于 2013-08-10 22:53 static/image/common/back.gif
可以在probe里注册一个字符设备,然后实现read,write 等操作

我想要实现复杂点的操作,就是类似ioctl,通过应用层传递的参数来实现一个基于读写的复杂操作,不知有没有。否则如果只有最简单的读写操作,那不是得把ioctl的工作放到应用层去做?

heyangya 发表于 2013-08-11 09:25

字符设备的操作函数集包括open,close,read,write,ioctl......你想干什么都可以
页: [1] 2
查看完整版本: 请问Linux下I2C设备驱动该如何写?