简介

项目中需要加入光感检测功能,需求一到,就打算自己写驱动,意外的发现最新内核中已经支持该驱动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;
}
Logo

更多推荐