1. 程式人生 > >[Linux驅動煉成記] 10 -光感ISL29035除錯/IIO子系統

[Linux驅動煉成記] 10 -光感ISL29035除錯/IIO子系統

簡介

專案中需要加入光感檢測功能,需求一到,就打算自己寫驅動,意外的發現最新核心中已經支援該驅動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

[email protected]
{ 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;
}