[Linux驱动炼成记] 10 -光感ISL29035调试/IIO子系统
简介项目中需要加入光感检测功能,需求一到,就打算自己写驱动,意外的发现最新内核中已经支持该驱动ISL29035。配置好DTS应该初步可以使用。看代码过程中发现isl29035的实现主要是采用IIO子系统实现的。芯片有一个中断引脚INT,低电平有效,相当于超过预定的亮度阀值,该引脚为低电平,应用层完全可以当做一个input来处理看芯片手册主要找到芯片的IIC从机地址 ,Device Addr...
·
简介
项目中需要加入光感检测功能,需求一到,就打算自己写驱动,意外的发现最新内核中已经支持该驱动ISL29035。配置好DTS应该初步可以使用。看代码过程中发现isl29035的实现主要是采用IIO子系统实现的。
- 芯片有一个中断引脚INT,低电平有效,相当于超过预定的亮度阀值,该引脚为低电平,应用层完全可以当做一个input来处理
- 看芯片手册主要找到芯片的IIC从机地址 ,Device Addressiong : 0100 0100 : 0x44
- 芯片相关寄存器说明
其中COMMAND-1中的 B2/INT为中断使能引脚
0 : interrupt is cleared or not triggered yet
1 : interrupt is triggered
DATA寄存器获取亮度的数据
INT_LT/INT_HT 为最低/最高阀值设定
寄存器详细设置可以参考芯片技术手册,这里不一一介绍
内核配置/编译
- 内核默认配置选项开启
内核版本: 4.9.68
内核Documentation/iio/iio_configfs.txt
这句话说明了支持IIO必须开启CONFIG_IIO_CONFIGFS选项
In order to use configfs support in IIO we need to select it at compile
time via CONFIG_IIO_CONFIGFS config option.
arch/arm64/configs/xxx_defconfig
....
CONFIG_IIO_SYSFS_TRIGGER=y
CONFIG_IIO_CONFIGFS=y
CONFIG_SENSORS_ISL29018=y
对应的源码目录
drivers/staging/iio/light/isl29018.c
...
static const struct i2c_device_id isl29018_id[] = {
{"isl29018", isl29018},
{"isl29023", isl29023},
{"isl29035", isl29035},
{}
};
- DTS配置
isl29025的配置可以参考内核4.19中的
Documentation/devicetree/bindings/iio/light/isl29018.txt
isl29018@44 {
compatible = "isil,isl29035";
reg = <0x44>;
interrupt-parent = <&gpio>;
interrupts = <TEGRA_GPIO(Z, 2) IRQ_TYPE_LEVEL_HIGH>;
};
调试
配置完成时候,开始编译烧录,进入系统中会发现:
// 设备节点如下
# cat /sys/bus/iio/devices/iio\:device0/
dev
in_illuminance0_calibscale
//读取亮度值:0~1000
in_illuminance0_input
in_illuminance0_integration_time
in_illuminance0_scale
in_illuminance_integration_time_available
in_illuminance_scale_available
in_intensity_ir_raw
name
of_node/
power/
subsystem/
uevent
//对应代码中亮度API
static int isl29018_read_lux(struct isl29018_chip *chip, int *lux)
{
int lux_data;
unsigned int data_x_range;
lux_data = isl29018_read_sensor_input(chip,
ISL29018_CMD1_OPMODE_ALS_ONCE);
if (lux_data < 0)
return lux_data;
data_x_range = lux_data * chip->scale.scale +
lux_data * chip->scale.uscale / 1000000;
*lux = data_x_range * chip->calibscale +
data_x_range * chip->ucalibscale / 1000000;
return 0;
}
更多推荐
已为社区贡献4条内容
所有评论(0)