module初始化顺序导致的AKM8963C 磁传感器probe失败

时间:2022-03-06 22:24:05

今天调试AKM8963C,代码以前平台用过,确认可以正常工作!拿过来直接用,理论上没问题。但是事实却不到who am I 的值。

问题确认步骤:

1.检查供电。(VDD 和 VID 均正确)

2.检查RSTN引脚配置是否有效。(正常工作时RSTN引脚应为高电平。为了确保工作正常,首先将该引脚拉低保持5us,而后再拉高,100us后芯片应该已经进入正常工作模式,可以读取数据了)

if(pdata->gpio_RST != 0) {
gpio_request(pdata->gpio_RST, "akm8963_rstn");
gpio_direction_output( pdata->gpio_RST, 0);
udelay(5);
gpio_direction_output( pdata->gpio_RST, 1);
/* Device will be accessible 50-100 us after */
udelay(100);
}

3. DRDY引脚在调试过程可以先不关心,因为这只是为了触发外部中断。

用示波器确认上述两步都正确后,依然读不到数据。

为了排除问题。在probe中添加了一个死循环,不断的将RSTN引脚拉低然后再拉高,并且将间隔时间调整大一些,以确保reset有效果。然后再读取数据。奇迹出现了,发现这样reset两次后就可以读到数据了。

因为以前的板子同样用这个芯片,同样用这个reset的时间间隔,都能正常工作,这个现在不正常是没道理的。仔细看了下log输出发现了一个异常:

[    2.954930] i2c timeout intraw =0x0, intMak =0x0, intenable =0x5a04d40,i2c_trl =0x6e, i2c_cmd=0x30c0

[    2.964016] [I2C:xxxxx_i2c_init:i2c clk=100000]

在AKM8963的probe过程中间夹杂了一个关于i2c控制器初始化的log。

这下明白了。可见8963的probe执行太早了,竟然在i2c驱动初始化还没有完成的时候调用了i2c操作,这当然是不行的。这也就是上面的测试过程中经过两次reset后又能读出数据的原因。因为在这两次reset的时间中,i2c控制器已经可用了。

因此解决的这个问题的办法就是让AKM8963的驱动加载的晚一点。这个用late_initcall替换掉以前的module_init即可。顺便我也把LIS3DH加速度传感器的init加载也改为late_initcal了,这样更保险。

 -module_init(akm8963_init);
+late_initcall(akm8963_init);