目錄
- 背景
- 一、芯片介紹
- 二、手冊
- 三、內核驅動配置
- 3.1 設備樹配置
- 3.2 修改內核配置文件
- 3.3 編譯
- 四、內核驅動分析
- 1、初始化流程
- 2、屬性文件/解釋
- 五、調試和計算
背景
最近調試了一款德州儀器的帶有I2C控制接口的可以實現電壓、電流、功率監測,并可以進行報警設置的芯片INA226;
本文主要總結在linux 5.10下怎么配置內核將此芯片用起來,并總結內核中此芯片的驅動實現;
一、芯片介紹
INA226 是具有 I2C? 或 SMBUS 兼容接口的電流分流
器和功率監測器。該器件同時監控分流壓降和總線電源
電壓。可編程校準值、轉換時間、和均值計算,與一個
內部乘法器相組合,實現電流值(安培)和功率值
(瓦)的直接讀取。
INA226 可在 0V 至 36V 的共模總線電壓范圍內感測電
流,與電源電壓無關。 該器件由一個 2.7V 至 5.5V 的
單電源供電,汲取 330μA 的典型電源電流。該器件的
額定工作溫度范圍為 –40°C 至 125°C,I2C 兼容接口
上具有多達 16 個可編程地址。
二、手冊
https://www.ti.com.cn/product/cn/INA226/part-details/INA226AIDGST
詳細描述和硬件參考設計等見手冊;
三、內核驅動配置
3.1 設備樹配置
&i2cXXX {
status = “okay”;
ina226@xx {
compatible = “ti,ina226”;
reg = <0xXX>; //器件地址結合手冊和硬件配置定義
shunt-resistor = <1000>; //采樣電阻值單位是: micro-ohm 微歐姆,如果是1毫歐就乘以1000
};
};
3.2 修改內核配置文件
修改內核源碼/arch/arm64/configs/xxxxxxx_defconfg配置文件,添加編譯選項
CONFIG_SENSORS_INA2XX=y 編譯到內核 或者
CONFIG_SENSORS_INA2XX=m 編譯成模塊
3.3 編譯
配置成模塊時,查看是否生成ina2xx.o 和 ina2xx.ko;
配置編譯到內核時,查看是否生成ina2xx.o;
四、內核驅動分析
1、初始化流程
驅動和設備樹表示的設備match后 -> ina2xx_probe 執行
static int ina2xx_probe(struct i2c_client *client)
{struct device *dev = &client->dev;struct ina2xx_data *data;struct device *hwmon_dev;u32 val;int ret, group = 0;enum ina2xx_ids chip;if (client->dev.of_node)chip = (enum ina2xx_ids)of_device_get_match_data(&client->dev);//獲取設備與驅動匹配后的of_device_id 結構里的數據,這的data為驅動不同芯片自定義的索引 ina219 為0 ,ina226為1elsechip = i2c_match_id(ina2xx_id, client)->driver_data;data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); //分配data結構的內存if (!data)return -ENOMEM;/* set the device type */data->config = &ina2xx_config[chip]; //結構ina2xx_config 的結構體賦值mutex_init(&data->config_lock);if (of_property_read_u32(dev->of_node, "shunt-resistor", &val) < 0) {struct ina2xx_platform_data *pdata = dev_get_platdata(dev); //讀取設備樹中定義的采樣電阻值if (pdata)val = pdata->shunt_uohms; //得到采樣電阻的阻值微歐姆elseval = INA2XX_RSHUNT_DEFAULT;}ina2xx_set_shunt(data, val);// struct ina2xx_data結構成員初始化ina2xx_regmap_config.max_register = data->config->registers; //芯片寄存器的個數data->regmap = devm_regmap_init_i2c(client, &ina2xx_regmap_config);//寄存器地址和值的位寬定義if (IS_ERR(data->regmap)) {dev_err(dev, "failed to allocate register map\n");return PTR_ERR(data->regmap);}ret = ina2xx_init(data);//初始化將默認值配置給配置寄存器,校準值配置給校準寄存器if (ret < 0) {dev_err(dev, "error configuring the device: %d\n", ret);return -ENODEV;}data->groups[group++] = &ina2xx_group;//通用屬性組if (chip == ina226)data->groups[group++] = &ina226_group; //ina226 屬性組hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,data, data->groups); //注冊成硬件監控設備類if (IS_ERR(hwmon_dev))return PTR_ERR(hwmon_dev);dev_info(dev, "power monitor %s (Rshunt = %li uOhm)\n",client->name, data->rshunt);return 0;
}
2、屬性文件/解釋
1、會生成如下屬性文件和目錄
2、舉例解釋
//屬性文件in0_input ,ina2xx_value 屬性只讀對應 ina2xx_value_show 函數,INA2XX_SHUNT_VOLTAGE 采樣電阻分壓寄存器
static SENSOR_DEVICE_ATTR_RO(in0_input, ina2xx_value, INA2XX_SHUNT_VOLTAGE);//屬性文件in1_input ,ina2xx_value 屬性只讀對應ina2xx_value_show 函數,INA2XX_BUS_VOLTAGE總線電壓寄存器
static SENSOR_DEVICE_ATTR_RO(in1_input, ina2xx_value, INA2XX_BUS_VOLTAGE);
五、調試和計算
1、安裝模塊 或者編譯進內核啟動;
2、查看板卡/設備內屬性目錄
ls /sys/class/hwmon/hwmonX
3、以上屬性文件內的數據為數字值,根據表示的數據內容的含義乘以分辨率,并結合具體的單位即可計算測量值,也可以與一期測量結果進行對比;