跟踪G-Sensor有时不起作用的问题

来源:互联网 发布:最新手游服务端源码 编辑:程序博客网 时间:2024/05/22 18:27

跟踪G-Sensor有时不起作用的问题

       最近在生产反馈中,有提到批量机器中有大约2%的机器遇到不转屏的问题。笔者通过反复跟踪,重现了这个问题,通过分析lsmod,看到驱动又已经加载,但是就是不起作用,再通过getevent看信息,发现没有数据报上来,这说明有问题,G-sensor没有报数据肯定就不转屏了,那怎么解决呢?

      仔细分析了G-sensor的驱动,流程上也没看出什么问题来,当然如果流程有问题就不可能是小概率出问题了, 那应该是大面积有问题了。层层分析,还是觉得在detect处理上有疑点,全志平台提供的驱动,读一遍chip ID后,就判断是不是BMA250,或者BMA250E,如果都不是就返回了,上层也就认为没有找到G-sensor,就不会去读数据。通过加了一些打印后,通过大量的测试跟踪,发现G-sensor没有的时候,在detect的时候都没有读成功,于是笔者又从硬件原理图上分析了一下,原来在同一组IIC上,不止它一个,而它就是相对比较晚加载的一个,因此在加载它驱动的时候,前一个驱动使用iic可能有忙的问题,这样就可能造成超时,最终读不出chip ID。那么,我们可以在读chip ID的时候,可以尝试多读几次,一次不行,休息一会再去读,这样就尽了最多限度的努力去读chip ID了,当然极端一点的还可以在读不出chip ID的时候,也强制认为读到了,这样有一个不好地方就是,不能做多种G-sensor的兼容,如果你只有一种G-sensor,这样做也没什么。笔者通过这样一修改后,通过专项测试,以及近段时间的批量生产,没有复现了这个问题。

      因此,在靠读外设的chip ID来判断是否存在这个硬件的时候,我们可以尝试多读几次,这样软件的兼容性会好一点,有一个不好的地方就是,系统的启动时间会稍微增加一点。下面就是对G-sensor detect改造的代码:

[plain] view plaincopy
  1. int gsensor_detect(struct i2c_client *client, struct i2c_board_info *info)  
  2. {  
  3.     struct i2c_adapter *adapter = client->adapter;  
  4.     int ret;  
  5.     int retrytimes = 5;  
  6.       
  7.     if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))  
  8.             return -ENODEV;  
  9.               
  10.     if(twi_id == adapter->nr){  
  11.         for(i2c_num = 0; i2c_num < (sizeof(i2c_address)/sizeof(i2c_address[0]));i2c_num++)  
  12.         {       client->addr = i2c_address[i2c_num];  
  13.                pr_info("%s:addr= 0x%x,i2c_num:%d\n",__func__,client->addr,i2c_num);  
  14.                  
  15.                do {  
  16.             ret = i2c_smbus_read_byte_data(client,BMA250_CHIP_ID_REG);  
  17.             if (ret < 0) {  
  18.                       printk("FAIL read value is 0x%x, retrytimes =%d\n", ret, retrytimes);  
  19.                       
  20.                       retrytimes--;  
  21.                       msleep(5);/*5ms*/  
  22.                     }  
  23.                } while((retrytimes > 0) && (ret < 0));  
  24.                  
  25.                pr_info("Read ID value is :0x%x\n",ret);  
  26.                if ((ret &0x00FF) == BMA250_CHIP_ID){  
  27.                     pr_info("Bosch Sensortec Device detected!\n" );  
  28.                     strlcpy(info->type, SENSOR_NAME, I2C_NAME_SIZE);  
  29.                     return 0;   
  30.       
  31.                }else if((ret &0x00FF) == BMA150_CHIP_ID){  
  32.                       
  33.                    pr_info("Bosch Sensortec Device detected!\n" \  
  34.                 "BMA150 registered I2C driver!\n");    
  35.                  strlcpy(info->type, SENSOR_NAME, I2C_NAME_SIZE);  
  36.                      return 0;   
  37.           } else if((ret &0x00FF) == BMA250E_CHIP_ID) {   
  38.         strlcpy(info->type, SENSOR_NAME, I2C_NAME_SIZE);  
  39.         return 0;     
  40.           }  else {   
  41.         /*worearound we just one gsensor*/  
  42.         pr_info("set force!!!\n");  
  43.         strlcpy(info->type, SENSOR_NAME, I2C_NAME_SIZE);  
  44.         return 0;     
  45.                     }                                                                                                                                  
  46.         }  
  47.           
  48.         pr_info("%s:Bosch Sensortec Device not found, \  
  49.                  maybe the other gsensor equipment! \n",__func__);  
  50.         return -ENODEV;  
  51.     }else{  
  52.         return -ENODEV;  
  53.          }  
  54. }  
from: http://blog.csdn.net/edsam49/article/details/9934763
原创粉丝点击