嵌入式Linux系统之I.MX6触摸屏驱动程序TSC2007.C的分析、移植与校准
學(xué)習(xí)交流加
- 個(gè)人qq:
1126137994 - 個(gè)人微信:
liu1126137994 - 學(xué)習(xí)交流資源分享qq群:
962535112
今天來記錄一下I.MX6開發(fā)板移植觸摸屏驅(qū)動程序的過程分析。在移植驅(qū)動程序之前,為了學(xué)習(xí),先去分析一下觸摸屏驅(qū)動程序的框架。加qq1126137994 一起學(xué)習(xí)更多技術(shù)。
文章目錄
- 1、tsc2007.c觸摸屏驅(qū)動程序的分析
- 2、tsc2007.c觸摸屏驅(qū)動程序的移植
- 3、觸摸屏的校準(zhǔn)
1、tsc2007.c觸摸屏驅(qū)動程序的分析
I.MX6的觸摸屏驅(qū)動程序的文件名為:TSC2007.C。
在tsc2007.c文件中初始化tsc2007_init函數(shù)注冊tsc2007_driver結(jié)構(gòu)體,當(dāng)tsc2007_driver結(jié)構(gòu)體成員驅(qū)動name與平臺設(shè)備層中name匹配相同時(shí)調(diào)用tsc2007_probe初始化函數(shù),該函數(shù)是tsc2007設(shè)備驅(qū)動函數(shù)的入口。imx6的具體tsc2007設(shè)備驅(qū)動的實(shí)現(xiàn)的主要工作在tsc2007_probe里完成。
下面是分析tsc2007_probe函數(shù)的調(diào)用關(guān)系(并非程序源碼,只是列舉出關(guān)鍵的函數(shù)調(diào)用):
tsc2007_probeinput_dev = input_allocate_device();//(向input核心層申請)分配一個(gè)input_dev結(jié)構(gòu)體。INIT_DELAYED_WORK;//初始化工作隊(duì)列,把tsc2007工作任務(wù)注冊到工作隊(duì)列中,為下面執(zhí)行隊(duì)列的任務(wù)作好準(zhǔn)備。tsc2007_work;//通過input_report_abs函數(shù)向上層上報(bào)觸摸屏屏的X、Y坐標(biāo)和壓力值,執(zhí)行tsc2007_calculate_pressure函數(shù)進(jìn)行壓力校準(zhǔn),init_platform_hw;//?input_set_abs_params;//通過input_dev結(jié)構(gòu)體設(shè)置按鍵和絕對位置事件以及事件下需要處理的ABS_X、ABS_Y、ABS_PRESSURE的具體事件內(nèi)容request_irq(ts->irq, tsc2007_irq, 0,client->dev.driver->name, ts);//為tsc2007中斷引腳申請一個(gè)中斷處理函數(shù),schedule_delayed_work;//中斷的上半部分tsc2007_work; //中斷的下半部分,tsc2007_read_values;//讀取xy坐標(biāo) 以及獲取壓力值tc->y = tsc2007_xfer(tsc, READ_Y);tc->x = tsc2007_xfer(tsc, READ_X);tsc2007_xfer(tsc, PWRDOWN);//另一次循環(huán)測量rt = tsc2007_calculate_pressure // 計(jì)算壓力 input_report_abs(input, ABS_X, tc.x);input_report_abs(input, ABS_Y, tc.y);input_report_abs(input, ABS_PRESSURE, rt);//上報(bào)獲取到的值tsc2007_xfer; data = i2c_smbus_read_word_data; //檢測IIC總線的讀寫操作val = swab16(data) >> 4; //去掉低4位無效數(shù)據(jù)(#define MAX_12BIT 由定義知最大為12bit,所以需要去掉低4位)return val;//tsc2007_xfer返回一個(gè)val值,就是xy坐標(biāo)的值input_register_device; //像input核心層注冊input_dev結(jié)構(gòu)體arch\mips\boot\Elf2ecoff.c中有如下定義 #define swab16(x) \(( \(((x) & 0x00ffU) << 8) | \(((x) & 0xff00U) >> 8) )) //將x的值的高8位和低8位互換當(dāng)按下觸摸板后產(chǎn)生中斷,中斷里面調(diào)用延時(shí)函數(shù)進(jìn)入底半部程序。在調(diào)度函數(shù)里面,先讀取坐標(biāo),計(jì)算壓力,然后根據(jù)壓力大小上報(bào)坐標(biāo)。若觸摸板一直按下,那么就重新調(diào)用,并通過壓力值來看觸摸板是否釋放。
2、tsc2007.c觸摸屏驅(qū)動程序的移植
觸摸屏驅(qū)動程序的核心部分分析完了,下面就開始移植觸摸屏驅(qū)動程序,其實(shí),內(nèi)核自帶的驅(qū)動程序移植起來非常簡單,在理解驅(qū)動程序的前提下,在平臺設(shè)備文件中添加一些私有數(shù)據(jù)信息,以及配置中斷引腳等即可。
IMX6的板級初始化函數(shù):Board-mx6q_sabresd.c
由與tsc2007與imx6之間的通信是通過IIC總線進(jìn)行的,因此在imx6的平臺設(shè)備層(platform_device)的mx6_sabresd_board_init函數(shù)里就需要配置與tsc2007有關(guān)的IIC總線。由于是TSC2007所掛的IIC總線是第二根,在平臺初始化函數(shù)里將會調(diào)用i2c_register_board_info函數(shù)注冊mxc_i2c2_board_info結(jié)構(gòu)體數(shù)組。
向mxc_i2c2_board_info結(jié)構(gòu)體數(shù)組里添加如下成員:
{I2C_BOARD_INFO("tsc2007",0x48),.platform_data = (void *)& tsc2007_data_lyy,.irq = gpio_io_irq(SABRESD_TS_INT), }其中由于TSC2007的A0、A1兩個(gè)引腳下拉,通過I2C_BOARD_INFO函數(shù)注冊的從機(jī)設(shè)備地址是0x48;通過gpio_to_irq函數(shù)獲取TSC2007中斷號,之后會傳給平臺驅(qū)動層,當(dāng)申請中斷會用到;
再構(gòu)建tsc2007_data_lyy結(jié)構(gòu)體,并添加4個(gè)成員:init_platform_hw函數(shù)、get_pendown_state函數(shù)、irq_pin中斷引腳的選擇、觸摸屏驅(qū)動相關(guān)參數(shù)。
/* * 注意:一下添加的函數(shù),位置沒有固定要求,但是為了整齊統(tǒng)一,還是把它放到與其它設(shè)備定義的相通的位置,方便以后查看*/ #ifdef CONFIG_TOUCHSCREEN_TSC2007 #include <linux/i2c/tsc2007.h>(在頭文件里也添加一下)static int tsc2007_hw_init(void){int err;err = gpio_request(SABRESD_TS_INT,"tsc2007 irq");if(err<0){pr_err("tsc2007 irq gpio request err\n");return err;}err = gpio_direction_input(SABRESD_TS_INT);if(err<0){pr_err("tsc2007 irq gpio init input err %d\n",err);gpio_free(SABRESD_TS_INT);return err;}printk("tsc2007 irq gpio init success!\n");return 0;}static void tsc2007_hw_remove(void){gpio_free(SABRESD_TS_INT);}static int tsc2007_get_pendown_state(void){int state;state = gpio_get_value(SABRESD_TS_INT);//printk("tsc2007 get state = %x\n",state);return (state == 0)? 1:0;}static struct tsc2007_platform_data tsc2007_data_lyy= {.model = 2007,.x_plate_ohms =180,.init_platform_hw = tsc2007_hw_init,.exit_platform_hw = tsc2007_hw_remove,.get_pendown_state = tsc2007_get_pendown_state,}; #endif更改中斷引腳號:
將宏SABRESD_TS_INT改為:(之前是3,26) #define SABRESD_TS_INT IMX_GPIO_NR(6, 7) //lyy (申請中斷引腳)注:在Linux啟動的時(shí)候會將信息進(jìn)行收集,i2c適配器會掃描已經(jīng)靜態(tài)注冊的i2c_board_info,通過調(diào)用i2c_register_board_info函數(shù)將包含所有I2C設(shè)備的i2c_board_info信息的i2c_devinfo變量加入到__i2c_board_list鏈表中,并調(diào)用i2c_new_device為其實(shí)例化一個(gè)i2c_client。在驅(qū)動加載的時(shí)候遇到同名的i2c_board_info就會將i2c_client和driver綁定,并且執(zhí)行driver的probe函數(shù)。這種方式一般放在平臺的代碼中。
i2c_register_board_info(2, mxc_i2c2_board_info,ARRAY_SIZE(mxc_i2c2_board_info));注釋:
上面的工作,基本完成了驅(qū)動程序的移植,但是后來經(jīng)過測試,發(fā)現(xiàn)顯示有錯(cuò)誤:
Failed to register i2c client tsc2007 at 0x48 (-16)
Can’t create device at 0x48
一開始以為是i2c總線沒有識別到,但是經(jīng)過調(diào)試,發(fā)現(xiàn)是中斷引腳的復(fù)用了。
OK!到此,程序添加成功,下一步就是校準(zhǔn)觸摸屏了!!!
3、觸摸屏的校準(zhǔn)
校準(zhǔn)的目的:為了與顯示屏的坐標(biāo)一一對應(yīng)。我們一般采用軟件校準(zhǔn),使用Tslib庫里的校準(zhǔn)軟件進(jìn)行校準(zhǔn)們首先需要移植Tslib庫。
編譯tslib(放到rootfs/tslib/tslib): tar xzf tslib-1.4.tar.gz cd tslib ./autogen.sh mkdir tmp echo "ac_cv_func_malloc_0_nonnull=yes" >arm-linux.cache ./configure --host=arm-linux --cache-file=arm-linux.cache --prefix=$(pwd)/tmp make make install我的這一部分是放到開發(fā)的環(huán)境中做的,其實(shí)可以直接在單板上搞,如果單板上是有編譯器的話。
然后將系統(tǒng)燒寫的單板,在單板上操作:
cd /tslib/tslib/tmp cp * / -rfd1. 修改 /etc/ts.conf第1行(去掉#號和第一個(gè)空格): # module_raw input 改為: module_raw input2. export TSLIB_TSDEVICE=/dev/input/event1 export TSLIB_CALIBFILE=/etc/pointercal export TSLIB_CONFFILE=/etc/ts.conf export TSLIB_PLUGINDIR=/lib/ts export TSLIB_CONSOLEDEVICE=none export TSLIB_FBDEVICE=/dev/fb0測試:
ts_calibrate
ts_test
備注:如果出現(xiàn)段錯(cuò)誤,解決辦法如下:
1、ts.conf文件中的各個(gè)設(shè)置選項(xiàng)之前不能有空格,否則會出現(xiàn): Segmentation fault 錯(cuò)誤,
我就不小心在module…之前多了個(gè)空格,害我查了好久。
2、不要在pointercal對應(yīng)的目錄下,建立一個(gè)空的pointercal文件,否則在運(yùn)行ts_calibrate時(shí),
也可能會出現(xiàn)Segmentation fault
想一起探討以及獲得各種學(xué)習(xí)資源加我(有我博客中寫的代碼的原稿):
qq:1126137994
微信:liu1126137994
可以共同交流關(guān)于嵌入式,操作系統(tǒng),C++語言,C語言,數(shù)據(jù)結(jié)構(gòu)等技術(shù)問題。
總結(jié)
以上是生活随笔為你收集整理的嵌入式Linux系统之I.MX6触摸屏驱动程序TSC2007.C的分析、移植与校准的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SQLyog详细使用教程
- 下一篇: 嵌入式Linux操作系统移植IMX6开发