1、IIO设备
IIO是 Industrial I/O 的缩写,是Linux下为工业输入输出所设计的子系统。主要用于传感器设备,ADC/DAC设备。
2、基本框架
struct foobar_i2c_device_data {
struct i2c_client *client;
struct i2c_adapter *adap;
struct iio_dev *indio;
};
static ssize_t type_show(struct device *dev, struct device_attribute *attr, char *buf)
{
int ret;
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
const struct iio_chan_spec *chan = indio_dev->channels;
ret = sprintf(buf, "%d\n", chan->type);
return ret;
}
static int i2c_foobar_iio_device_read_raw(struct iio_dev *indio_dev,
const struct iio_chan_spec *chan, int *val1, int *val2, long mask)
{
struct foobar_i2c_device_data *i2c = iio_device_get_drvdata(indio_dev);
dev_info(&i2c->adap->dev, "%d\n", chan->channel2);
*val1 = chan->type;
*val2 = chan->channel2;
return 1;
}
static IIO_DEVICE_ATTR_RO(type, 0);
static struct attribute *i2c_foobar_attributes[] = {
&iio_dev_attr_type.dev_attr.attr,
NULL
};
static const struct attribute_group i2c_foobar_iio_device_attrs = {
.attrs = i2c_foobar_attributes
};
static const struct iio_info foobar_iio_info = {
.attrs = &i2c_foobar_iio_device_attrs,
.read_raw = i2c_foobar_iio_device_read_raw,
};
static const struct iio_chan_spec i2c_iio_channels[] = {
{
.type = IIO_LIGHT,
.modified = 1,
.channel2 = IIO_MOD_LIGHT_IR,
.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
},
{
.type = IIO_PROXIMITY,
.modified = 1,
.channel2 = IIO_MOD_LIGHT_CLEAR,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
}
};
static int iio_device_init(struct foobar_i2c_device_data *device)
{
struct iio_dev *indio;
int ret;
indio = iio_device_alloc(&device->client->dev, sizeof(*indio));
if (!indio) {
ret = -ENOMEM;
goto out;
}
indio->info = &foobar_iio_info;
indio->channels = i2c_iio_channels;
indio->num_channels = ARRAY_SIZE(i2c_iio_channels);
indio->dev.parent = &device->client->dev;
indio->name = "sensor name";
ret = iio_device_register(indio);
if (ret) {
dev_err(&device->client->dev, "register iio device FAIL:%d\n", ret);
iio_device_free(indio);
goto out;
}
iio_device_set_drvdata(indio, device);
out:
return ret;
}
static int foobar_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
struct i2c_adapter *adap = client->adapter;
struct foobar_i2c_device_data *device;
int ret;
device = kzalloc(sizeof(*device), GFP_KERNEL);
if (!device)
return -ENOMEM;
device->client = client;
device->adap = adap;
ret = iio_device_init(device);
if (ret) {
dev_err(&adap->dev, "device init FAIL:%d\n", ret);
kfree(device);
return ret;
}
i2c_set_clientdata(client, device);
return 0;
}
IIO设备的重点是iio_info,这里有那么点绕,在iio_info中需要填充attrs和read_raw,attr是用于提供自定义属性,
read_raw用于读取框架提供的属性读取。IIO设备默认有一个name属性,这个属性的值为iio_dev的name,其它
的属性可以自己添加。
3、read_raw注意事项
这个参数函数的返回值比较特别,
0:没有任何返回,即使填充了val1和val2,也不会有任何显示。
1:不带小数点,只使用val1的值。
>= 2:6位以上小数点,val1为整数部分。2为小数点后6位,3为小数点8位。