刷入谷歌system.img,导致TP和Gsensor方向异常解决方案

一、综述

目前Android 8.1 项目会过一个新GSI测试项,
需要刷入谷歌提供的system.img文件,其中默认的LCD旋转角度为0度,
若是在平板项目中,正式软件的LCD旋转角度可能为270度。
因此会造成TP和Gsensor方向功能异常问题。
(ps:后来谷歌爸爸终于把关于平板项目的旋转角度调回来了,也就是白改了)

二、实现思路

当前解决思路如下:
刷入谷歌提供的system.img软件时,开机系统状态:androidboot.verifiedbootstate=orange
软件正式开机系统状态:
androidboot.verifiedbootstate=green

此状态会在lk->kernel的过程中,通过cmdline的参数传给kernel层,
从log中搜索cmdline,如下


开机串口log

因此通过在kernel层判断此状态来改变TP和Gsensor方向

三、解决方案(代码实现)

1.TP修改

kernel-3.18/drivers/input/touchscreen/mediatek/gslX68X_9709

#include <linux/string.h>//add by zcf 2018.04.24

static bool used_defautl_tp_rotation = false;//add by zcf 2018.04.24

static int __init tpd_driver_init(void) {
    char * sub = "androidboot.verifiedbootstate=orange";//add by zcf 2018.04.24
    print_info("Sileadinc gslX680 touch panel driver init\n");
    
    //add by zcf 2018.04.24
    if(strstr(saved_command_line,sub)){
      //if boot state == orange ,change tp rotation to 0
        used_defautl_tp_rotation = true;        
    }
    //end add by zcf 2018.04.24

#ifdef ADD_I2C_DEVICE_ANDROID_4_0
    //i2c_register_board_info(1, &gslX680_i2c_tpd, 1);  
#endif
    tpd_get_dts_info();
    if(tpd_driver_add(&tpd_device_driver) < 0)
        print_err("add gslX680 driver failed\n");
    return 0;
}


void tpd_down( int id, int x, int y, int p) 
{
    print_info("+++tpd_down++++ x =%d  y=%d    ++++++++++++++++ \n", x, y);
    if(!used_defautl_tp_rotation){ //add by zcf 2018.04.24
#if defined(TPD_ROTATE_90)
    tpd_rotate_90(&x,&y);
#elif  defined(TPD_ROTATE_270)||defined(TPD_ROTATE_270_2)
    tpd_rotate_270(&x,&y);
#endif
    }  //add by zcf 2018.04.24
    //省略部分代码
}

不同的项目TP驱动不同个,但修改思路是相同的,在tpd_driver_init()函数里,
char * sub = "androidboot.verifiedbootstate=orange";
if(strstr(saved_command_line,sub)){
//if boot state == orange ,change tp rotation to 0
used_defautl_tp_rotation = true;
}
解析saved_command_line是否包含"androidboot.verifiedbootstate=orange"
如果是的话,我们就需要改变TP的方向,使用默认旋转度为0的方向。
在tpd_down(),禁止旋转90度或者270度,也就是使用默认0度方向。
同样道理
kernel-3.18/drivers/input/touchscreen/mediatek

static int tpd_probe(struct platform_device *pdev)
{
    int touch_type = 1; /* 0:R-touch, 1: Cap-touch */
    int i = 0;
    char * sub = "androidboot.verifiedbootstate=orange";//add by zcf 2018.04.24
     //省略....代码

    //add by zcf 2018.04.24
    if(strstr(saved_command_line,sub)){
    //if boot state == orange ,change tp rotation to 0
        goto tp_rotate_to_zero;    
    }
    // end add by zcf 2018.04.24
    #ifdef CONFIG_MTK_LCM_PHYSICAL_ROTATION
    if (0 == strncmp(CONFIG_MTK_LCM_PHYSICAL_ROTATION, "90", 2)
        || 0 == strncmp(CONFIG_MTK_LCM_PHYSICAL_ROTATION, "270", 3)) {
#ifdef CONFIG_MTK_FB    
/*Fix build errors,as some projects  cannot support these apis while bring up*/
        TPD_RES_Y = DISP_GetScreenWidth();
        TPD_RES_X = DISP_GetScreenHeight();
#endif
    } else
    #endif
    {
       tp_rotate_to_zero://add by zcf 2018.04.24
#ifdef CONFIG_CUSTOM_LCM_X
#ifndef CONFIG_MTK_FPGA
#ifdef CONFIG_MTK_FB

如果f boot state == orange ,就调过CONFIG_MTK_LCM_PHYSICAL_ROTATION宏所定义的代码,即不旋转
直接goto -> tp_rotate_to_zero:后面的代码

2.Gsensor方向的修改

kernel-3.18/arch/arm/boot/dts

&i2c2 {
    gsensor@18 {
        i2c_num = <2>;
        i2c_addr = <0x18 0 0 0>;
        direction = <7>;
        direction_for_gsi = <6>;/*add by zcf 2018.04.24*/
        power_id = <0xffff>;
        power_vol = <0>;
        firlen = <0>;
        is_batch_supported = <0>;
    };
}

在dts里面添加direction_for_gsi ,如果刷了gsi的system.img,就使用这个方向,否则使用默认的direction
kernel-3.18/drivers/misc/mediatek/sensors-1.0/hwmon/sensor_dts

int get_accel_dts_func(struct device_node *node, struct acc_hw *hw)
{
    char * sub = "androidboot.verifiedbootstate=orange";//add by zcf 2018.04.24
    int i, ret;
    u32 i2c_num[] = {0};
    u32 i2c_addr[G_CUST_I2C_ADDR_NUM] = {0};
    u32 direction[] = {0};
    u32 direction_for_gsi[] = {0};// add by zcf 2018.04.24
    u32 power_id[] = {0};
    u32 power_vol[] = {0};
      //省略...代码

    ret = of_property_read_u32_array(node, "direction", direction, 
                                ARRAY_SIZE(direction));
    if (ret == 0)
      hw->direction = direction[0];
      //add by zcf 2018.04.24 
       if(strstr(saved_command_line,sub)){
      //if boot state == orange ,used the direction_for_gsi for gsi test
       if(of_find_property(node,"direction_for_gsi",NULL)) {
         ret = of_property_read_u32_array(node, "direction_for_gsi", 
                      direction_for_gsi, ARRAY_SIZE(direction_for_gsi));
         hw->direction = direction_for_gsi[0];      
      }
     }
 //end add by zcf 2018.04.24
}

如果saved_command_line包含androidboot.verifiedbootstate=orange;
判断direction_for_gsi节点是否为空
不为空就获取direction_for_gsi的值赋给hw->direction
hw->direction = direction_for_gsi[0];

saved_command_line在内核中的定义和使用

saved_command_line是全局变量,该变量通过EXPOER_SYMBOL(saved_command_line)宏,使得全局可用。

这个变量定义在main.c


main.c

在sparc_ksyms_32.c或者sparc_ksyms_64.c里export为全局变量


sparc_ksyms_32.c

我们可以看一下内核中试如何使用的,模仿即可


mtkfb.c

直接调用strstr(saved_command_line, "lcm="),
不需要定义saved_command_line。

到此,就写完了,收工练琴!

Stay hungry,Stay foolish!
荆轲刺秦王

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容