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
コメント