跟蹤G-Sensor有時不起作用的問題

跟蹤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. }  
發佈了45 篇原創文章 · 獲贊 6 · 訪問量 21萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章