一、综述
目前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,如下

因此通过在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

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

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

直接调用strstr(saved_command_line, "lcm="),
不需要定义saved_command_line。
到此,就写完了,收工练琴!
Stay hungry,Stay foolish!
荆轲刺秦王