Linux iio驱动学习

最近在做新项目的充电bringup,kernel 内核版本为5.4版本,使用到的充电电荷泵(charger pump)IC具备采样vbus vbat ibat ibus等功能,以往项目都是通过power_supply架构来实现采集adc数据,但是最新的kernel版本由于GKI的限制vendor无法在自行添加自定义的power_supply,所以需要修改原来项目采集adc数据的方法,所以采用linux正统的iio驱动来实现adc读取的功能,顺便学习梳理了一下iio驱动的使用方法。
iio子系统:Industrial I/O
一般用于具备ADC/DAC的器件提供驱动支持,使用范围比较广泛,比如温湿度传感器、陀螺仪、adc采样等等。软件驱动上提供sysfs(/sys/bus/iio/devices/)和dev(dev/iio:deviceX)节点供上层交互,内核空间提供接口给其他驱动使用。

iio子系统主要代码路径:
include/linux/iio/consumer.h
kernel/msm-4.19/drivers/iio/industrialio-core.c industrialio-buffer.c industrialio-trigger.c …

使用示例:
iio注册三部曲,申请、填充、注册

#include <linux/iio/iio.h>
#include <dt-bindings/iio/qti_power_supply_iio.h>

struct charger_pump_iio_channels {
	const char *datasheet_name;
	int channel_num;
	enum iio_chan_type type;
	long info_mask;
};

#define CP_IIO_CHAN(_name, _num, _type, _mask)		\
	{	.datasheet_name = _name,		\
		.channel_num = _num,			\
		.type = _type,				\
		.info_mask = _mask,	},

#define CP_CHAN_VOLT(_name, _num)			\
	CP_IIO_CHAN(_name, _num, IIO_VOLTAGE, BIT(IIO_CHAN_INFO_PROCESSED))
#define CP_CHAN_CUR(_name, _num)			\
	CP_IIO_CHAN(_name, _num, IIO_CURRENT, BIT(IIO_CHAN_INFO_PROCESSED))
#define SC8551_CHAN_TEMP(_name, _num)			\
	CP_IIO_CHAN(_name, _num, IIO_TEMP, BIT(IIO_CHAN_INFO_PROCESSED))

static const struct charger_pump_iio_channels cp_iio_psy_channels[] = {
	SC8551_CHAN_VOLT("sc_battery_voltage", PSY_IIO_SC_BATTERY_VOLTAGE)
	SC8551_CHAN_CUR("sc_battery_current", PSY_IIO_SC_BATTERY_CURRENT)
	SC8551_CHAN_TEMP("sc_battery_temperature", PSY_IIO_SC_BATTERY_TEMPERATURE)
	......
};
提供读写的实际底层函数接口
static const struct iio_info sc_iio_info = {
	.read_raw	= sc_iio_read_raw,
	.write_raw	= sc_iio_write_raw,
	.of_xlate	= sc_iio_of_xlate,
};

struct iio_dev *indio_dev = chip->indio_dev;
struct iio_chan_spec *chan;
int num_iio_channels = ARRAY_SIZE(cp_iio_psy_channels);

1.分配内存
chip->iio_chan = devm_kcalloc(chip->dev, num_iio_channels, sizeof(*chip->iio_chan), GFP_KERNEL);
chip->int_iio_chans = devm_kcalloc(chip->dev, num_iio_channels, sizeof(*chip->int_iio_chans),GFP_KERNEL);

2.填充
indio_dev->name = "cp-standalone";
indio_dev->info = &sc_iio_info;
indio_dev->channels = chip->iio_chan;
indio_dev->num_channels = num_iio_channels;
for (i = 0; i < num_iio_channels; i++) {
	chip->int_iio_chans[i].indio_dev = indio_dev;
	chan = &chip->iio_chan[i];
	chip->int_iio_chans[i].channel = chan;
	chan->address = i;
	chan->channel = sc8551_iio_psy_channels[i].channel_num;
	chan->type = sc8551_iio_psy_channels[i].type;
	chan->datasheet_name =sc8551_iio_psy_channels[i].datasheet_name;
	chan->extend_name =sc8551_iio_psy_channels[i].datasheet_name;
	chan->info_mask_separate =sc8551_iio_psy_channels[i].info_mask;
}

3.注册indio_dev
rc = devm_iio_device_register(chip->dev, indio_dev);

iio使用API:

	ret = usbpd_get_iio_channel(pdpm, CP_MASTER, CHARGE_PUMP_SC_BATTERY_VOLTAGE, &val1);
  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值