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