在一个驱动程序模块中处理多个i2c_clients(使用sysfs)

时间:2017-09-18 15:31:57

标签: linux linux-kernel linux-device-driver kernel-module i2c

我想为tmp102温度传感器创建一个内核驱动程序。 在一个项目中,我只有一个传感器,另一个 - 2个传感器。我希望我的内核模块能够支持N个传感器,而不是固定数量。我在管理多个struct i2c_client并为每个结构创建sysfs条目时遇到问题。以下是我的表现:

  1. probe()函数中,我为struct i2c_client*提供的每个设备获得I2C_BOARD_INFO()

  2. 然后我kobject_create_and_add("tmp102", kernel_kobj)获取 sysfs 中模块的主目录。

  3. 对于每个设备,我创建sysfs_create_group(),获取指向静态创建属性的指针。属性将(*show)()(*store)()指针设置为静态函数,例如

    static ssize_t tmp102_sysfs_thigh_get_one(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
    
  4. 在此功能中,我想通过I2C读取。问题是......我不知道如何获取设备的struct i2c_client *,该设备应以某种方式链接到此 sysfs 条目,并且I2C地址就在那里! / p>

    我应该如何正确地"链接"带有 sysfs 条目的i2c_client,以便我可以在函数内部获取I2C地址?

    理想情况下,我想只有一组函数(每个属性一个)。 sysfs 树应如下所示:

      /sysfs/kernel/tmp102
      |
      |-> <hex i2c address, e.g. /48>
      |   |
      |   |-> temperature   
      |
      |   
      |-> /49
          |
          |-> temperature
    

    我想要两个温度&#39;属性使用相同的函数,它能够确定应该写入的I2C地址。

    或者我的架构可能是错误的?如果是这样,对于需要处理多个i2c_client s的驱动程序应该如何?

    编辑:

    我决定使用struct device_attribute代替常规attribute。据我所知,使用常规属性时获取struct device指针并不容易,与struct i2c_client相同。他们不容易和他们联系在一起。来自kobject的{​​{1}},我需要拥有此项目的属性。可以在/sys/kernel中找到device_attribute - 我使用/sys/devices并将我的设备sysfs_create_groupkobject组相关联。我使用device_attribute,并将我的设备sysfs_create_linkkobject相关联。这样我就可以为每个设备创建一个文件夹(链接),指向/sys/kernel/tmp102中的原始属性文件夹。

1 个答案:

答案 0 :(得分:2)

首先,您应该知道tmp102已经有一个具有sysfs接口的内核驱动程序。看看drivers/hwmon/tmp102.c

现在,对于您的问题,您有一个struct kobject传递给您的sysfs回调。您可以调用kobj_to_dev()来获取指向设备的指针。然后,例如,您可以使用dev_get_drvdata()获取指向您自己的私有结构的指针,该结构将包含指向i2c客户端的指针。不要忘记在探针中首先使用dev_set_drvdata()进行设置。

您可以在drivers/rtc/rtc-ds1343.c中找到一个示例,但它正在使用spi_driver。