一、前言
产品上有一个声控开关的需求,需要用到ADC,调试过程遇到了很多问题,特此记录下。(都可以写个小故事了)
二、过程
1.修改设备树
板子上ADC功能默认是没有打开的,所以先改设备树。
1.1
BUG1:从doc文档直接复制代码,格式错误,编译和运行不会报错。
描述:我直接从doc文档把ADC设备树代码复制过来,然后格式不对,就是ADC驱动文件显示不出,一直没发现,最后拿着FAE的设备树文件直接替换,才正常。
解决办法:照着文档敲,或者从源文件copy。
1.2
BUG2:驱动代码的匹配名和设备树不一致。
描述:vf610_adc.c文件的vf610_adc_probe函数下,查找的regular设备名字和设备名字有差异,代码如下。
点击查看代码
//vf610_adc_probe函数
printk("iio_adc_probe444\n");
info->vref = devm_regulator_get(&pdev->dev, "vref");
if (IS_ERR(info->vref))
return PTR_ERR(info->vref);
//设备树regulator节点
reg_verf_3V3: regulator@2 {
compatible = "regulator-fixed";
regulator-name ="verf";//就是这里,然后导致设备驱动注册失败
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
};
解决办法: 改设备regulator的名字。
1.3
BUG3: 使用menuconfig配置".config"文件不生效,配置完成,重新编译之后,再次打卡menuconfig文件发现刚才使能adc模块,标记消失了。
原因: ".config"被"arch/arm/configs/imx_v7_deconfig"覆盖了。通过分析脚本和查阅资料发现,imx_v7_deconfig文件是板子的出厂默认配置,不使能adc驱动,编译开始会把imx_v7_deconfig的配置合并到.config,若冲突,.config文件会被 imx_v7_deconfig覆盖掉,然后内核会使用.config文件配置。
方法: 配置完menuconfig时将配置路径改为"arch/arm/configs/imx_v7_deconfig",这样编译就不会被覆盖了
1.4
BUG4:读取到adc的原始数据正确,但是分辨率错误。
原因:设备树问题,设备树里最小设为0,最大电压设为3.3,造成了驱动程序的分辨错误。不清楚驱动程序为什么这么设计。
点击查看代码
reg_verf_3V3: regulator@2 {
compatible = "regulator-fixed";
regulator-name ="vref";
regulator-min-microvolt = <0000000>;
regulator-max-microvolt = <3300000>;
};
方法:修改设备树,电压最小最大都设为3.3v。
点击查看代码
reg_verf_3V3: regulator@2 {
compatible = "regulator-fixed";
regulator-name ="vref";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
};
四、详细设备树代码
点击查看代码
//file name: imx6ull.dtsi
adc1: adc@02198000 {
compatible = "fsl,imx6ul-adc", "fsl,vf610-adc";
reg = <0x02198000 0x4000>;
interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6UL_CLK_ADC1>;
num-channels = <2>;
clock-names = "adc";
status = "disabled";
};
//file name: imx6ull-14x14-evk.dts。在iomuxc节点下添加引脚复用信息
pinctrl_adc1: adc1grp {
fsl,pins = <
MX6UL_PAD_GPIO1_IO01__GPIO1_IO01 0xb0
>;
};
//file name: imx6ull-14x14-evk.dts。追加节点信息,把状态设置为使能。
&adc1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_adc1>;
num-channels = <2>;
verf-supply = <®_verf_3V3>;
status = "okay";
};
//