设备树定义
link {
mode = "split";
type = "line-interleaved";
speed = <6>;
sioa {
device = <&gmsl2_red_des_sioa 0x48>;
translators = <&touchscreen_red_cd 0x4a>,<&gmsl2_red_adc_sioa 0x49>;
};
siob {
device = <&gmsl2_red_des_siob 0x48>;
translators = <&touchscreen_red_pd 0x4a>,<&gmsl2_red_adc_siob 0x49>;
};
};
translators {
#address-cells = <1>;
#size-cells = <0>;
gmsl2_red_adc_sioa: adc@0x32 {
reg = <0x32>;
};
gmsl2_red_adc_siob: adc@0x34 {
reg = <0x34>;
};
};
解析函数
这里的np是link的节点
static int of_serdes_get_lane_translators(struct serdes_device *sd,
struct device_node *np,
struct serdes_lane *lane)
{
struct of_phandle_args translator;
int res, count, i;
lane->nb_translators = 0;
lane->translators = NULL;
/* get number of device to translate */
count = of_property_count_u32_elems(np, "translators");
if (count < 0) {
dev_err(&sd->client->dev,
"issue on 'translators' property...\n");
return count;
}
/* divide by 2 (1 phandle + 1 arg) */
count >>= 1;
if (count < 1) {
dev_err(&sd->client->dev,
"'translators' defined number arguments don't match...\n");
return -EINVAL;
}
lane->translators = devm_kzalloc(&sd->client->dev,
sizeof(*lane->translators) * count, GFP_KERNEL);
if (!lane->translators)
return -ENOMEM;
/* parse each device to translate address */
for (i = 0, lane->nb_translators = 0; i < count; i++) {
res = of_parse_phandle_with_fixed_args(np, "translators",
1, i, &translator);
if (res < 0)
continue;
/* remote address is the phandle argument */
lane->translators[lane->nb_translators].remote =
translator.args[0];
/* phandle 'reg' property is the local address */
res = of_property_read_u32(translator.np, "reg",
&lane->translators[lane->nb_translators].local);
lane->nb_translators++;
of_node_put(translator.np); /* decrease node refcount */
}
return 0;
}