devicetree

devicetreeとは

 Linuxのデバイスドライバに関連するソースコードは、ロジック部を記載しているドライバのファイルである「*.c」の他に、設定値等のパラメータ部を別のファイルとして持っています。このファイルが「*.dts」「*.dtsi」となり、devicetreeのファイルとなります。

ドライバの初期化時に、devicetreeに記載しているパラメータを読み出し、この値を元に動作させます。パラメータを別のファイルに置くことで、ドライバ本体を修正せずに、異なるSoC、異なる接続ポートに対応する事が可能になります。

使い方

 照度センサデバイスドライバでは、ltr578_i2c_probeから呼ばれるget_alsps_dts_funcに記載ある以下に使用箇所があります。

kernel/mediatek/4.4/drivers/misc/mediatek/sensors-1.0/hwmon/sensor_dts/sensor_dts.c

ret = of_property_read_u32_array(node, "power_id", power_id, ARRAY_SIZE(power_id));

このof_property_read_u32_array関数は以下に定義されています。

kernel/mediatek/4.4/drivers/of/base.c

/**
 * of_property_read_u32_array - Find and read an array of 32 bit integers
 * from a property.
 *
 * @np:		device node from which the property value is to be read.
 * @propname:	name of the property to be searched.
 * @out_values:	pointer to return value, modified only if return value is 0.
 * @sz:		number of array elements to read
 *
 * Search for a property in a device node and read 32-bit value(s) from
 * it. Returns 0 on success, -EINVAL if the property does not exist,
 * -ENODATA if property does not have a value, and -EOVERFLOW if the
 * property data isn't large enough.
 *
 * The out_values is modified only if a valid u32 value can be decoded.
 */
int of_property_read_u32_array(const struct device_node *np,
			       const char *propname, u32 *out_values,
			       size_t sz)

devicetreeから、unsignedな32bit型で配列情報を読み込む関数になります。第1引数には、後述するノードの情報、I2Cクライアントドライバであれば、client->dev.of_nodeを指定します。of_find_node_by_name(NULL, “ノード名“)で探すことも可能です。第2引数には読み出す値の定義名を指定します。第3引数には読み込んだ値の代入先を指定します。第4引数には配列のサイズを指定します。

Kindle Fire HD 10 (9th Generation) においては、devicetreeのファイルとして「kernel/mediatek/4.4/arch/arm64/boot/dts/mediatek/maverick_hvt1p1.dts」が使用されています。

その為、使用例である

of_property_read_u32_array(node, "power_id", power_id, ARRAY_SIZE(power_id));

であれば、以下で”power_id”に定義されている0xffffがpower_id変数に代入される動作となります。

kernel/mediatek/4.4/arch/arm64/boot/dts/mediatek/maverick_hvt1p1.dts

ltr578:ltr578@53 {
	compatible = "mediatek,ltr578";
	i2c_num = <1>;
	reg = <0x53>;
	i2c_addr = <0x53 0x00 0x00 0x00>;
	polling_mode_ps = <1>;
	polling_mode_als = <1>;
	power_id = <0xffff>;
	power_vol = <0>;
	ps_threshold_high = <120>;
	ps_threshold_low = <100>;
	is_batch_supported_ps = <0>;
	is_batch_supported_als = <0>;
};

最初に記載されているltr578@53がノード名になります。of_property_read_u32_array以外にも、読み込む値によって、関数がそれぞれ用意されています。

kernel/mediatek/4.4/include/linux/of.h

static inline bool of_property_read_bool(const struct device_node *np,
					 const char *propname)

static inline int of_property_read_u8(const struct device_node *np,
				       const char *propname,
				       u8 *out_value)

static inline int of_property_read_u16(const struct device_node *np,
				       const char *propname,
				       u16 *out_value)

static inline int of_property_read_u32(const struct device_node *np,
				       const char *propname,
				       u32 *out_value)

static inline int of_property_read_s32(const struct device_node *np,
				       const char *propname,
				       s32 *out_value)

extern int of_property_read_u8_array(const struct device_node *np,
			const char *propname, u8 *out_values, size_t sz);

extern int of_property_read_u16_array(const struct device_node *np,
			const char *propname, u16 *out_values, size_t sz);

extern int of_property_read_u32_array(const struct device_node *np,
				      const char *propname,
				      u32 *out_values,
				      size_t sz);

extern int of_property_read_u64(const struct device_node *np,
				const char *propname, u64 *out_value);

extern int of_property_read_u64_array(const struct device_node *np,
				      const char *propname,
				      u64 *out_values,
				      size_t sz);

extern int of_property_read_string(struct device_node *np,
				   const char *propname,
				   const char **out_string);

最後に

 読み込み可能なdevicetreeの値は、端末内の /sys/firmware/devicetree から確認可能です。使用例であるpower_idの値が入ったファイルは以下に存在します。残念ながら開発者でないので、読み込みはできません。

maverick:/sys/firmware/devicetree/base/i2c@11011000/ltr578@53 $ ls
ls: ./reg: Permission denied
ls: ./name: Permission denied
ls: ./power_vol: Permission denied
ls: ./i2c_addr: Permission denied
ls: ./ps_threshold_low: Permission denied
ls: ./i2c_num: Permission denied
ls: ./compatible: Permission denied
ls: ./ps_threshold_high: Permission denied
ls: ./polling_mode_als: Permission denied
ls: ./is_batch_supported_ps: Permission denied
ls: ./power_id: Permission denied
ls: ./is_batch_supported_als: Permission denied
ls: ./polling_mode_ps: Permission denied
ls: ./phandle: Permission denied
ls: ./linux,phandle: Permission denied

コメント

タイトルとURLをコピーしました