转自: https://www.ebaina.com/articles/140000004356

声明:因为在开发过程中不同设备会搭载同一芯片,不同设备会有各种不同的硬件设备,因此本文移植的gt911驱动也是以动态加载的方式载入内核的。

gt9xx是一款很常用的触摸屏ic,网上对它在安卓和stm32平台上的使用调试教程较多,但是在海思平台的调试教程较少,下面记录一些我自己移植gt9xx安卓驱动碰到的问题。

开始调试时给到的资料有一份gt9xx的安卓驱动代码,一份移植说明书,一份gt9xx的数据手册(网上都有)。

- 阅读剩余部分 -

转自: https://blog.csdn.net/xubin341719/article/details/7881735

关键词:android 按键 矩阵按键 AD按键

平台信息:

内核:linux2.6/linux3.0

系统:android/android4.0

平台:S5PV310(samsung exynos4210)

作者:xubin341719(欢迎转载,请注明作者)

一、硬件部分:

1、矩阵按键、IO按键、AD按键

这个知识相对来说比较简单,不过上次真有一个网友不太清楚这个。所以这个基础部分我们在这里也说一下。

- 阅读剩余部分 -

转自: https://blog.csdn.net/xubin341719/article/details/7678053

参考:http://blog.chinaunix.net/uid-22174347-id-1786941.html

==========================================================

开发环境

编译系统 :fedora9

编译器 :arm-linux-4.4.3

主控芯片 :S3C2440

开发板 :mini2440

==========================================================

一、电阻式触摸屏工作原理 二、 S3C2440 电阻式触摸屏接口、内部ADC结构 三、Linux输入子系统(InputSubsystem) 四、mini2440触摸屏驱动分析

==========================================================

(这部分转自:http://blog.chinaunix.net/uid-22174347-id-1786941.html 文章写得很好)

四、mini2440触摸屏驱动分析

1、硬件原理图分析

S3c2440芯片内部触摸屏接口与ADC接口是集成在一起的,硬件结构原理图请看:S3C2440上ADC驱动实例开发讲解中的图,其中通道7(XP或AIN7)作为触摸屏接口的X坐标输入,通道5(YP或AIN5)作为触摸屏接口的Y坐标输入。在"S3C2440上ADC驱动实例开发讲解"中,AD转换的模拟信号是由开发板上的一个电位器产生并通过通道1(AIN0)输入的,而这里的模拟信号则是由点触触摸屏所产生的X坐标和Y坐标两个模拟信号,并分别通过通道7和通道5输入。S3c2440提供的触摸屏接口有4种处理模式,分别是:正常转换模式、单独的X/Y位置转换模式、自动X/Y位置转换模式和等待中断模式,对于在每种模式下工作的要求,请详细查看数据手册的描述。本驱动实例将采用自动X/Y位置转换模式和等待中断模式。

- 阅读剩余部分 -

转自: https://blog.csdn.net/xubin341719/article/details/7678035

参考:http://blog.chinaunix.net/uid-22174347-id-1786941.html

==========================================================

开发环境

编译系统 :fedora9

编译器 :arm-linux-4.4.3

主控芯片 :S3C2440

开发板 :mini2440

==========================================================

一、电阻式触摸屏工作原理 二、 S3C2440 电阻式触摸屏接口、内部ADC结构 三、Linux输入子系统(InputSubsystem) 四、mini2440触摸屏驱动分析

==========================================================

三、Linux输入子系统(InputSubsystem)

1,linux输入子系统简述

其实驱动这部分大多还是转载别人的,linux输入子系统后面再详细分析。

在Linux中,输入子系统是由输入子系统设备驱动层、输入子系统核心层(InputCore)和输入子系统事件处理层(Event Handler)组成。其中设备驱动层提供对硬件各寄存器的读写访问和将底层硬件对用户输入访问的响应转换为标准的输入事件,再通过核心层提交给事件处理层;而核心层对下提供了设备驱动层的编程接口,对上又提供了事件处理层的编程接口;而事件处理层就为我们用户空间的应用程序提供了统一访问设备的接口和驱动层提交来的事件处理。所以这使得我们输入设备的驱动部分不在用关心对设备文件的操作,而是要关心对各硬件寄存器的操作和提交的输入事件。下面用图形来描述一下这三者的关系吧!

- 阅读剩余部分 -

转自: https://blog.csdn.net/zgkxzx/article/details/56980769

前言

gslx680电容触摸屏是一种目前Android嵌入式设备中比较常用的触摸屏类型。这里我们以Exynos4412为Android bsp平台,移植一款gslx680电容触摸屏。 关于电容触摸屏的原理,这里不进行讲解,不明白的,可以参照一下博客:http://blog.csdn.net/xubin341719/article/details/7820492 这里只从实际工程出发,讲解移植过程。谢谢~~

- 阅读剩余部分 -

转自: https://blog.csdn.net/loongembedded/article/details/72674115

  1. 8937 lk采用8952的。

/device/qcom/msm8937_64/BoardConfig.mk 下面可看出来

BOOTLOADER_PLATFORM := msm8952 # use msm8937LK configuration

2.8937 configs文件用 kernel\msm-3.18\arch\arm64\configs 目录下的

3.user版本用 msm8937-perf_defconfig 文件,userdebug 和 eng 版本用 msm8937_defconfig

    #----------------------------------------------------------------------
    # Compile Linux Kernel
    #----------------------------------------------------------------------
    ifeq ($(KERNEL_DEFCONFIG),)
       ifeq ($(TARGET_BUILD_VARIANT),user)
         KERNEL_DEFCONFIG := msm8937-perf_defconfig
       else
         KERNEL_DEFCONFIG := msm8937_defconfig
       endif
    endif

- 阅读剩余部分 -

转自: https://blog.csdn.net/zhahaobing2017/article/details/52951159

android屏幕启动流程

点亮一个新屏幕,下面以8909-x26的屏幕为例。

启动引导部分:

一、添加对应的.h文件

首先添加一个.h头文件,命名为panel_ili9806e_fwvga_hsd_helitai_x26_video.h,该文件放在路径/bootable/bootloader/lk/dev/gcdb/include/下面。因为这里包含了各种型号的屏幕的头文件,也就是初始化代码,并且放在了启动引导目录。根据命名,知道该屏幕的IC(芯片)是ili9806e,屏幕分辨率是fwvga,玻璃是HSD,模组厂是helitai(合力泰)。

屏幕工作的关键是芯片、玻璃、模组厂!

在头文件里面会对屏幕进行初始化,如backlight(背光),lane(通道),color(颜色),timing_information(定时)等。

/*---------------------------------------------------------------------------*/

/* Backlight setting                                                         */

/*---------------------------------------------------------------------------*/

static struct backlight ili9806e_fwvga_hsd_helitai_x26_video_backlight = {

1, 1, 4095, 100, 1, "PMIC_8941"

};

/*---------------------------------------------------------------------------*/

/* Lane configuration                                                        */

/*---------------------------------------------------------------------------*/

static struct lane_configuration ili9806e_fwvga_hsd_helitai_x26_video_lane_config = {

2, 1, 1, 1, 0, 0, 0

};

/*---------------------------------------------------------------------------*/

/* Panel color information                                                   */

/*---------------------------------------------------------------------------*/

static struct color_info ili9806e_fwvga_hsd_helitai_x26_video_color = {

24, 0, 0xff, 0, 0, 0

};

static char ili9806e_fwvga_hsd_helitai_x26_video_on_cmd0[] = {

0x06, 0x00, 0x39, 0xC0,

0xFF, 0xFF, 0x98, 0x06,

0x04, 0x01, 0xFF, 0xFF,

};

......

二、oem_penel.c文件添加自己的新屏幕(路径:bootable/bootloader/lk/target/msm8909_x26_q1/

(1).首先添加屏幕初始化的头文件”panel_ili9806e_fwvga_hsd_helitai_x26_video.h“,即:

#include “include/panel_ili9806e_fwvga_hsd_helitai_x26_video.h”.

(2).在枚举类型中添加自己的新屏幕:

其中该枚举类型在文件mipi_panel_reg_id.h中(路径:./bootable/bootloader/lk/platform/msm_shared/include/

enum {

......

ILI9806E_FWVGA_HSD_HELITAI_x26_VIDEO_PANEL,//add your panel.

UNKNOWN_PANEL

};

(3).在函数init_panel_data()中,添加自己的板子的case语句,即新屏幕的数据初始化。

case ILI9806E_FWVGA_HSD_HELITAI_x26_VIDEO_PANEL:

panelstruct->paneldata          = &ili9806e_fwvga_hsd_helitai_x26_video_panel_data;

panelstruct->panelres           = &ili9806e_fwvga_hsd_helitai_x26_video_panel_res;

panelstruct->color              = &ili9806e_fwvga_hsd_helitai_x26_video_color;

panelstruct->videopanel         = &ili9806e_fwvga_hsd_helitai_x26_video_video_panel;

panelstruct->commandpanel       = &ili9806e_fwvga_hsd_helitai_x26_video_command_panel;

panelstruct->state              = &ili9806e_fwvga_hsd_helitai_x26_video_state;

panelstruct->laneconfig         = &ili9806e_fwvga_hsd_helitai_x26_video_lane_config;

panelstruct->paneltiminginfo    = &ili9806e_fwvga_hsd_helitai_x26_video_timing_info;

panelstruct->panelresetseq      = &ili9806e_fwvga_hsd_helitai_x26_video_reset_seq;

panelstruct->backlightinfo      = &ili9806e_fwvga_hsd_helitai_x26_video_backlight;

pinfo->mipi.panel_cmds          = ili9806e_fwvga_hsd_helitai_x26_video_on_command;

pinfo->mipi.num_of_panel_cmds   = ARRAY_SIZE(ili9806e_fwvga_hsd_helitai_x26_video_on_command);

memcpy(phy_db->timing,ili9806e_fwvga_hsd_helitai_x26_video_timings, TIMING_SIZE);

pinfo->mipi.signature = ILI9806E_FWVGA_HSD_HELITAI_x26_VIDEO_SIGNATURE;

break;

(4).在函数oem_panel_select()中,必须让控制板的id选择自己新添加的,否则,开机屏幕不亮。

case HW_PLATFORM_QRD:

if (lcm_gpio_id == 1) {

panel_id = ILI9806E_FWVGA_HSD_HUASHI_VIDEO_PANEL;

} else {

panel_id = ILI9806E_FWVGA_HSD_HELITAI_x26_VIDEO_PANEL;//add your panel

}

break;

到此,lk(little kernel)部分,屏幕相关的工作就完成了!

程序执行流程:

(1)当按下开机键,程序自然就是从main函数开始执行,不过main是C 语言的叫法。(具体可以参见BIOS过程)。

(2)程序运行到APP_START(aboot)

.init = aboot_init,

APP_END

就会调用aboot_init()函数。aboot意为“引导”。

(2)引导的时候自然有屏幕的启动和初始化,aboot_init()函数调用target_display_init()函数,条件是DISPLAY_SPLASH_SCREEN为1。

(3)在函数target_display_init()最后,ret = gcdb_display_init();程序自然跳转到函数gcdb_display_init()

(4)在gcdb_display_init中首先调用oem_panel_select()函数,然后又跳转到oem_panel_select函数。

hw_id的值由board_hardware_id()返回,返回了11,然后进入qrd路线。107行知lcm_gpio_id=0,所以在else分支(lcm_gpio_id =0)下添加自己的屏幕,即将panel_id设置为ILI9806E_FWVGA_HSD_HELITAI_x26

_VIDEO_PANEL.(panel_id = ILI9806E_FWVGA_HSD_HELITAI_x26_VIDEO_PANEL)。

(5)oem_panel_select()函数最后return init_panel_data(),程序进入init_panel_data(),

(6)在init_panel_data()中已经添加了自己的case语句,根据第109行,Func:oem_panel_select panel_id = 17 ,说明,已经选择了添加的新屏幕来初始化,因为枚举变量中自己新添加的屏幕(ILI9806E_FWVGA_HSD_HELITAI_x26_VIDEO_PANEL)刚好是第17个。这样panel_ili9806e_fwvga_hsd_helitai_x26_video.h文件参数全部用到。最后返回pan_type.

(7)程序继续在oem_panel_select()中,也返回pan_type,然后退出oem_panel_select()函数。回到gcdb_display_init()中,接收了pan_type,所以日志117行打印出pan_type是PANEL_TYPE_DSI。

(8)在gcdb_display_init中自然初始化DSI下的项目,如:

panel.fb.width,

panel.fb.height,

panel.fb.stride,

panel.fb.bpp

...

(9)第117行,display_enable = 1,ret = 0;gcdb_display_init()返回,说明屏幕bootloader部分完成,新屏幕可用,成功返回0.然后回到函数target_display_init()。

(10)第118行, in function:target_display_init,line:350,ret = 0.说明 target_display_init函数也成功结束。

(11)到此开机中屏幕的点亮结束了。

编译bootloader: make aboot -j6

烧写bootloader: fastboot flash aboot emmc_appsboot.mbn

附log:

......

106 [1450][1450]#mipi_get_lcm_pin_id().pin[8]_status = 0

107 ------ Func:oem_panel_select lcm_gpio_id = 0 ----------

108 hw_id = 11

109 -Func:oem_panel_select    panel_id = 17 -------

110 in function:gcdb_display_init,line:379,panel_type is PANEL_TYPE_DSI

111 in function:gcdb_display_init,line:386,panel init successfully!

112 [1540][1540] Config MIPI_VIDEO_PANEL.

113 [1690][1690] Panic Lut0 la90000 Lut1 ff Robest 0

114 [1700][1700] Turn on MIPI_VIDEO_PANEL.

115 [1720][1720] Video lane tested successfully

116 in function:gcdb_display_init,line:419,panel_type is PANEL_TYPE_DSI

117 display_enable = 1,ret = 0

118 in function:target_display_init,line:350,ret = 0

......

内核部分:

三、 (1)在路径kernel/arch/arm/boot/dts/msm8909_x26_q1下添加内核配置文件: dsi-panel-ili9806e-fwvga-hsd-helitai-x26-video.dtsi.

该文件是屏幕的配置文件,屏幕休眠唤醒时会走此文件。配置项目包括:

mdss-dsi-h-back-porchmdss-dsi-h-front-porchmdss-dsi-h-pulse-widthmdss-dsi-h-sync-skew等。

具体可参考文件:kernel/Documentation/devicetree/bindings/fb

其中在文件开头有一变量 dsi_ili9806e_fwvga_hsd_hlt_x26_vid,其值必须和启动引导部分的结构体ili9806e_fwvga_hsd_helitai_x26_video_panel_data的第一个成员相同。

引导部分和内核相关联就是这个panel_node_id, 这样屏幕待机之后唤醒就会找到引导时候的初始化屏幕路线。引导部分和内核部分的桥梁就是panel_node_id(变量dsi_ili9806e_fwvga_hsd_hlt_x26_vid), 他写进cmd-line,最后传给内核。

(2)在文件msm8909-mdss-panels.dtsi添加头文件:

即添加一行代码:#include "dsi-panel-ili9806e-fwvga-hsd-helitai-x26-video.dtsi"

其中该文件是屏幕的配置文件

(3)添加自己的屏幕(注意语法,不要漏掉分号):

&dsi_ili9806e_fwvga_hsd_hlt_x26_vid {

       qcom,cont-splash-enabled;

};

(4)将id设置为自己的id,这一步很重要,否则,开机屏幕正常,但是一旦休眠,再次唤醒手机,手机就是白屏,因为,唤醒虽然走的是开机的初始化路线,但是在这里却进入了另一种型号的屏幕了!

&mdss_dsi0 {

/*qcom,dsi-pref-prim-pan = <&dsi_ili9806e_fwvga_video>;*/

qcom,dsi-pref-prim-pan = <&dsi_ili9806e_fwvga_hsd_hlt_x26_vid>;//在这一行改为自己的屏幕

pinctrl-names = "mdss_default", "mdss_sleep";

  ......

};

到此,内核部分修改完成!

编译:make bootimage -j6

烧写: sudo fastboot flash boot boot.img

转自: https://blog.csdn.net/liuyingyanhuo/article/details/81294787

RK3288下tp驱动移植

一、修改DTS,添加新的I2C设备

&i2c4 {
    status = "okay";
    clock-frequency = <400000>;

    gslX680@40 {
        compatible = "gslX680";   
        reg = <0x40>;
        touch-gpio = <&gpio7 6 IRQ_TYPE_LEVEL_LOW>;
        reset-gpio = <&gpio7 5 GPIO_ACTIVE_HIGH>;
        i2c_sda_gpios = <&gpio7 17 IRQ_TYPE_LEVEL_LOW>;
        i2c_scl_gpios = <&gpio7 18 IRQ_TYPE_LEVEL_LOW>;
        status = "okay";
    };
};

1.&i2c4表明该设备挂载在i2c4下,我们添加设备节点时可根据硬件原理图看设备挂载在哪个I2C下,然后再到对应的节点上修改; 2.gslX680@40表示此I2C设备是触摸屏,设备名gsl680,设备地址为0x40; 3.compatible = “gslX680” 用于驱动和设备的绑定,表示特定的设备名(此处一定要正确,否则设备不能绑定);compatible优先匹配驱动中的id.table; 4.reg = <0x40> 表示此设备的地址为0x40,可以根据原理图找出设备地址,如果该地址错误,会导致I2C通讯失败; 5.touch-gpio = <&gpio7 6 IRQ_TYPE_LEVEL_LOW>; 表示中断引脚使用的是GPIO7中的GPIO_A6引脚,低电平触发; reset-gpio = <&gpio7 5 GPIO_ACTIVE_HIGH>; 表示复位引脚使用的是GPIO7中的GPIO_A5,高电平有效; 6.i2c_sda_gpios i2c_scl_gpios这两个分别是数据线和时钟线,看具体情况是否需要添加到代码;

二、修改Makefile,Kconfig

1.在drivers/input/touchscreen/Makefile中添加驱动:

obj-$(CONFIG_TOUCHSCREEN_GSLX680)  += GSL1680F/

注:看具体情况是否需要释掉Makefile里面其他GSLX680的编译信息,以及要看自己具体文件夹来配置,只有配置了CONFIG_TOUCHSCREEN_GSLX680选项,才会去编译GSL1680F文件夹下的文件; 2.修改Kconfigt添加驱动配置描述:

config TOUCHSCREEN_GSLX680
    tristate "GSL touch screen GSL1680 support for rockchip based platform"
    default y
    help
        Say Y here if you have a touchscreen interface using the
        two GSL gsl1680 , and your board-specific initialization
        code includes that in its table of IIC devices.
        If unsure, say N.

config后面的参数需要和驱动对应文件夹相匹配;

3.修改makefile以及Kconfig文件后,若发现还是没有编译驱动,可修改驱动配置文件

kernel/arch/arm/rockchip_defconfig

修改rockchip_defconfig文件使驱动强制编译进内核。

三、驱动移植时遇到的问题

1.驱动已经匹配上,但还是出现i2c读取不到address或device,有可能是硬件上接线有问题; 2.tp驱动移植成功后,发现tp反向,需要修改驱动中上报的x、y坐标,参考代码如下:

if (gtp_x_reverse)
            x = ts->abs_x_max - x;
if (gtp_y_reverse)
            y = ts->abs_y_max - y;

3.屏幕比列不匹配,可能需要原厂进行修改;

四、tp调试时的问题排查

1.当我们调试出现问题时,首先检查电压; 2.在porbe 函数里面加一句打印,确认驱动已经正常注册进系统了; 3.确认中断是否注册上了,可以adb shell cat /proc/interrupters,如果没有就查下打印,一般申请中断失败,都是IO 口被其他驱动或虚拟设备占用; 4.如果注册上了,但是触摸没中断.就用示波器勾下中断脚是否有波形,如果没有就代表触摸屏本身有问题,换一个试一下; 5.如果有波形,但是adb shell cat /proc/interrupters,中断号对应的中断数没有增加,一般都是中断脚被复用为其他作用,比如PWM; 6.一般这时候上层都会有点出来,大致分为三种情况:   1)出现鼠标,或者只有一个圆圈出来,这个是属于input 创建时候的有问题,可以参考正 常的驱动;   2)出现上下或左右反了,这个是要改驱动里面的上报函数;   3)如果上下左右正常了,但是会出现无法画到四个边的情况,这个是属于TP 里面的软 件问题,需要联系TP 厂的FAE,进行修改;

关于tp驱动问题会持续更新··········

转自: https://blog.csdn.net/VERBOR/article/details/115128511?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_title~default-0.no_search_link&spm=1001.2101.3001.4242

Qualcomm&MTK平台lcd/tp调试及问题总结

LCD原理结构
        LCD背光板
        下偏光板
        薄膜基板(TFT)
        液晶
        彩色滤光片
        上偏光片
        原理
视图如下
高通平台
    lk启动方式下(主要安卓8之前)
    kernel移植
            .dtsi中
背光的软件流程如下
    1.bootloader部分
    2.kernel部分
    主要背光功耗控制方法

LCD原理结构

目前主要使用的显示屏有TFT-LCD,OLED

LCD背光板

  • 为屏显提供基本光源

下偏光板

  • 使背光传出光线方向一致传向

薄膜基板(TFT)

  • 控制液晶扭转,电压变化控制扭转度数由主要有driver ic控制

液晶

  • 液晶分子受TFT控制,扭转角度影响光线透过率从而控制像素的亮度,影响灰阶(常用8位控制器)256级灰度控制,RGB三原色就是256X256X256 = 1677216种色彩,国际主要10位控制器

彩色滤光片

  • 红蓝绿三基色上色作用

上偏光片

  • 和下偏光片共同配合呈垂直角度

原理

背光发出光源,通过下偏光片进入,我们通过tft基板控制液晶分子扭转电压和扭转角度相关,从而控制单个像素的明暗强度,再透过滤光片从而实现多种色彩,不同强弱产生不同的画面,对待屏幕常见参数有 gamma 值,对比度,饱和度.可以通过高通QDCM 工具进行在线调试.

- 阅读剩余部分 -

需要重复字符串 n 次,如果 java 版本高,可以直接使用 String.repeat()

        String str = "Abc";
        System.out.println( str.repeat(3) );

如果版本低,那就使用 regex

        String str = "Abc";
        String repeated = new String(new char[3]).replace("\0", str);
        System.out.println(repeated);

可以直接创建一个重复字符串的函数:

    private String repeatString(String str, int times) {
        return new String(new char[times]).replace("\0", str);
    }

参考:

https://www.learnfk.com/article-java11-repeat-string-n-times