開發(fā)環(huán)境
BootLoader:u-boot-1.1.6
kernel:linux-2.6.30.4
CPU:s3c2440
開發(fā)板:TQ2440
參考資料:《天嵌科技Linux移植手冊》
移植步驟
1、觸摸驅(qū)動編寫
此處直接用天嵌提供的源碼,從天嵌科技提供的 2.6.30.4 的源碼中的“drivers/input/touchsreen/”拷貝“tq2440_ts.c”文件到我的內(nèi)核的“drivers/input/touchsreen/”目錄下,然后修改驅(qū)動源碼的 41 行為如下內(nèi)容:
//extern struct semaphore ADC_LOCK; //這個原來的內(nèi)容
DECLARE_MUTEX(ADC_LOCK); //這是修改后的內(nèi)容
說明:修改原因,因為天嵌科技提供的觸摸驅(qū)動中使用了 ADC 驅(qū)動中的 ADC_LOCK,而這里并沒有移植 ADC 驅(qū)動,所以這里做一下簡單的改變。
源代碼如下:
#include #include #include #include #include #include #include #include #include #include #include #include #include #include /* For ts.dev.id.version */ #define S3C2410TSVERSION 0x0101 #define WAIT4INT(x) (((x)<<8) | S3C2410_ADCTSC_YM_SEN | S3C2410_ADCTSC_YP_SEN | S3C2410_ADCTSC_XP_SEN | S3C2410_ADCTSC_XY_PST(3)) #define AUTOPST (S3C2410_ADCTSC_YM_SEN | S3C2410_ADCTSC_YP_SEN | S3C2410_ADCTSC_XP_SEN | S3C2410_ADCTSC_AUTO_PST | S3C2410_ADCTSC_XY_PST(0)) static char *tq2440ts_name = "TQ2440 TouchScreen"; static struct input_dev *dev; static long xp; static long yp; static int count; extern struct semaphore ADC_LOCK; static int OwnADC = 0; static void __iomem *base_addr; /* static inline void tq2440_ts_connect(void) { s3c2410_gpio_cfgpin(S3C2410_GPG12, S3C2410_GPG12_XMON); s3c2410_gpio_cfgpin(S3C2410_GPG13, S3C2410_GPG13_nXPON); s3c2410_gpio_cfgpin(S3C2410_GPG14, S3C2410_GPG14_YMON); s3c2410_gpio_cfgpin(S3C2410_GPG15, S3C2410_GPG15_nYPON); } */ static void touch_timer_fire(unsigned long data) { unsigned long data0; unsigned long data1; int updown; data0 = ioread32(base_addr+S3C2410_ADCDAT0); data1 = ioread32(base_addr+S3C2410_ADCDAT1); updown = (!(data0 & S3C2410_ADCDAT0_UPDOWN)) && (!(data1 & S3C2410_ADCDAT0_UPDOWN)); if (updown) { if (count != 0) { long tmp; tmp = xp; xp = yp; yp = tmp; xp >>= 2; yp >>= 2; input_report_abs(dev, ABS_X, xp); input_report_abs(dev, ABS_Y, yp); input_report_key(dev, BTN_TOUCH, 1); input_report_abs(dev, ABS_PRESSURE, 1); input_sync(dev); } xp = 0; yp = 0; count = 0; iowrite32(S3C2410_ADCTSC_PULL_UP_DISABLE | AUTOPST, base_addr+S3C2410_ADCTSC); iowrite32(ioread32(base_addr+S3C2410_ADCCON) | S3C2410_ADCCON_ENABLE_START, base_addr+S3C2410_ADCCON); } else { count = 0; input_report_key(dev, BTN_TOUCH, 0); input_report_abs(dev, ABS_PRESSURE, 0); input_sync(dev); iowrite32(WAIT4INT(0), base_addr+S3C2410_ADCTSC); if (OwnADC) { OwnADC = 0; up(&ADC_LOCK); } } } static struct timer_list touch_timer = TIMER_INITIALIZER(touch_timer_fire, 0, 0); static irqreturn_t stylus_updown(int irq, void *dev_id) { unsigned long data0; unsigned long data1; int updown; if (down_trylock(&ADC_LOCK) == 0) { OwnADC = 1; data0 = ioread32(base_addr+S3C2410_ADCDAT0); data1 = ioread32(base_addr+S3C2410_ADCDAT1); updown = (!(data0 & S3C2410_ADCDAT0_UPDOWN)) && (!(data1 & S3C2410_ADCDAT0_UPDOWN)); if (updown) { touch_timer_fire(0); } else { OwnADC = 0; up(&ADC_LOCK); } } return IRQ_HANDLED; } static irqreturn_t stylus_action(int irq, void *dev_id) { unsigned long data0; unsigned long data1; if (OwnADC) { data0 = ioread32(base_addr+S3C2410_ADCDAT0); data1 = ioread32(base_addr+S3C2410_ADCDAT1); xp += data0 & S3C2410_ADCDAT0_XPDATA_MASK; yp += data1 & S3C2410_ADCDAT1_YPDATA_MASK; count++; if (count < (1<<2)) { iowrite32(S3C2410_ADCTSC_PULL_UP_DISABLE | AUTOPST, base_addr+S3C2410_ADCTSC); iowrite32(ioread32(base_addr+S3C2410_ADCCON) | S3C2410_ADCCON_ENABLE_START, base_addr+S3C2410_ADCCON); } else { mod_timer(&touch_timer, jiffies+1); iowrite32(WAIT4INT(1), base_addr+S3C2410_ADCTSC); } } return IRQ_HANDLED; } static struct clk *adc_clock; static int __init tq2440ts_init(void) { struct input_dev *input_dev; adc_clock = clk_get(NULL, "adc"); if (!adc_clock) { printk(KERN_ERR "failed to get adc clock sourcen"); return -ENOENT; } clk_enable(adc_clock); base_addr=ioremap(S3C2410_PA_ADC,0x20); if (base_addr == NULL) { printk(KERN_ERR "Failed to remap register blockn"); return -ENOMEM; } /* Configure GPIOs */ // tq2440_ts_connect(); iowrite32(S3C2410_ADCCON_PRSCEN | S3C2410_ADCCON_PRSCVL(0xFF),base_addr+S3C2410_ADCCON); iowrite32(0xffff, base_addr+S3C2410_ADCDLY); iowrite32(WAIT4INT(0), base_addr+S3C2410_ADCTSC); /* Initialise input stuff */ input_dev = input_allocate_device(); if (!input_dev) { printk(KERN_ERR "Unable to allocate the input device !!n"); return -ENOMEM; } dev = input_dev; dev->evbit[0] = BIT(EV_SYN) | BIT(EV_KEY) | BIT(EV_ABS); dev->keybit[BITS_TO_LONGS(BTN_TOUCH)] = BIT(BTN_TOUCH); input_set_abs_params(dev, ABS_X, 0, 0x3FF, 0, 0); input_set_abs_params(dev, ABS_Y, 0, 0x3FF, 0, 0); input_set_abs_params(dev, ABS_PRESSURE, 0, 1, 0, 0); dev->name = tq2440ts_name; dev->id.bustype = BUS_RS232; dev->id.vendor = 0xDEAD; dev->id.product = 0xBEEF; dev->id.version = S3C2410TSVERSION; if (request_irq(IRQ_ADC, stylus_action, IRQF_SHARED|IRQF_SAMPLE_RANDOM, tq2440ts_name, dev)) { printk(KERN_ERR "tq2440_ts.c: Could not allocate ts IRQ_ADC !n"); iounmap(base_addr); return -EIO; } if (request_irq(IRQ_TC, stylus_updown, IRQF_SAMPLE_RANDOM, tq2440ts_name, dev)) { printk(KERN_ERR "tq2440_ts.c: Could not allocate ts IRQ_ADC !n"); iounmap(base_addr); return -EIO; } printk(KERN_INFO "%s successfully loadedn", tq2440ts_name); input_register_device(dev); return 0; } static void __exit tq2440ts_exit(void) { disable_irq(IRQ_ADC); disable_irq(IRQ_TC); free_irq(IRQ_TC,dev); free_irq(IRQ_ADC,dev); if (adc_clock) { clk_disable(adc_clock); clk_put(adc_clock); adc_clock = NULL; } input_unregister_device(dev); iounmap(base_addr); } module_init(tq2440ts_init); module_exit(tq2440ts_exit); 其實就是將此驅(qū)動程序編譯進內(nèi)核中,使內(nèi)核支持觸摸功能,可以采用編譯成模塊,加載進內(nèi)核的方式,也可以直接編譯進內(nèi)核。此處采用第二種方式。 修改同目錄下的“Kconfig”和“Makefile”文件。 在 Kconfig 文件的 468 行添加如下內(nèi)容: config TOUCHSCREEN_TQ2440 tristate "EmbedSky TQ2440 TouchScreen input driver" depends on ARCH_S3C2410 && INPUT && INPUT_TOUCHSCREEN help Say Y here if you have the TQ2440 TouchScreen. and depends on TQ2440_ADC If unsure, say N. To compile this driver as a module, choose M here: the module will be called tq2440_ts. 在 Makefile 文件的最后添加如下內(nèi)容: obj-$(CONFIG_TOUCHSCREEN_TQ2440) += tq2440_ts.o 2、配置內(nèi)核 System Type —> [ ] ADC common driver support Device Drivers —> Input device support —> [* ] Touchscreens —> <*> EmbedSky TQ2440 TouchScreen input driver 配置完畢后,保存配置,然后編譯內(nèi)核,燒寫鏡像到開發(fā)板中,內(nèi)核就能夠支持觸摸功能了。但是現(xiàn)在還沒有移植QT,所以無法使用觸摸功能,接下來配置一下QT。 3、文件系統(tǒng)中添加Qte 首先要制作帶有Qte的文件系統(tǒng),此處直接從天嵌科技提供的文件系統(tǒng)(rootfs_2.6.30.4 的文件系統(tǒng))源碼里面復(fù)制:“/opt/”目錄和“/root/”目錄到自己建立的文件系統(tǒng)里面,替換掉以前的目錄。使用的qtopia 是 2.2.0 版本的。 然后再在文件系統(tǒng)的“/bin/”目錄下面新建一個名為:“qtopia”的可執(zhí)行文件,內(nèi)容如下: #!/bin/sh echo Start Qtopia-2.2.0 > /dev/tq2440_serial0 if [ -f /etc/pointercal ] ; then $QPEDIR/bin/qpe > /dev/null 2>/dev/null else ts_calibrate $QPEDIR/bin/qpe > /dev/null 2>/dev/null fi 添加可執(zhí)行權(quán)限: chmod u+x qtopia 修改“/etc/init.d/rcS”文件,下面列出新添加的內(nèi)容: PATH=/sbin:/bin:/usr/sbin:/usr/bin runlevel=S prevlevel=N umask 022 export PATH runlevel prevlevel # #Trap CTRL-C &c only in this shell so we can interrupt subprocesses. # mount -a mkdir /dev/pts mount -t devpts devpts /dev/pts echo /sbin/mdev > /proc/sys/kernel/hotplug mdev -s mkdir -p /var/lock mkdir /dev/fb /dev/v4l ln -s /dev/fb0 /dev/fb/0 ln -s /dev/video0 /dev/v4l/video0 ln -s /dev/ts0 /dev/h3600_tsraw #建立一個觸摸設(shè)備的鏈接 export set TSLIB_TSDEVICE=/dev/event0 export set TSLIB_CONFFILE=/etc/ts.conf export set TSLIB_PLUGINDIR=/lib/ts export set TSLIB_CALIBFILE=/etc/pointercal export set HOME=/root export set QTDIR=/opt/Qtopia export set QPEDIR=/opt/Qtopia export set KDEDIR=/opt/kde export set QWS_KEYBOARD="TTY:/dev/tty1" export set QWS_MOUSE_PROTO="TPanel:/dev/event0 USB:/dev/mouse0" export set PATH=$QPEDIR/bin: $PATH export set LD_LIBRARY_PATH= $QTDIR/lib: $QPEDIR/lib qtopia & #啟動 Qte 的腳本,上面幾行是設(shè)置 QT 的環(huán)境變量 /bin/hostname -F /etc/sysconfig/HOSTNAME 然后復(fù)制 tslib 的相關(guān)文件到新建的文件系統(tǒng)中: 復(fù)制“ts.conf”文件到新建的文件系統(tǒng)的“etc/”目錄下,“ts.conf”文件的內(nèi)容如下: #Uncomment if you wish to use the linux input layer event interface module_raw input #Uncomment if you’re using a Sharp Zaurus SL-5500/SL-5000d #module_raw collie #Uncomment if you’re using a Sharp Zaurus SL-C700/C750/C760/C860 #module_raw corgi #Uncomment if you’re using a device with a UCB1200/1300/1400 TS interface #module_raw ucb1x00 #Uncomment if you’re using an HP iPaq h3600 or similar #module_raw h3600 #Uncomment if you’re using a Hitachi Webpad #module_raw mk712 #Uncomment if you’re using an IBM Arctic II #module_raw arctic2 module pthres pmin=1 module variance delta=30 module dejitter delta=100 module linear 復(fù)制可執(zhí)行程序“ts_calibrate”到新建的文件系統(tǒng)的“sbin/”目錄下,這是觸摸校正程序;
上一篇:嵌入式驅(qū)動移植之聲卡驅(qū)動移植
下一篇:LCD驅(qū)動移植之背光控制
推薦閱讀最新更新時間:2025-06-16 12:58




設(shè)計資源 培訓(xùn) 開發(fā)板 精華推薦
- LDK120M33R 3.3V低壓降穩(wěn)壓器典型應(yīng)用(可調(diào)版)電路
- STM32功率屏蔽,用于功耗測量的Nucleo擴展板(UM2243)
- AD9444-LVDS/PCBZ、LVDS 模式評估板,用于評估 AD9444 14 位、80 MSPS 模數(shù)轉(zhuǎn)換器
- nuedc2020_lmt70
- Wi-Fi?微控制器平臺
- 華為hdmi 多USB版本
- 使用 Analog Devices 的 ADR3530 的參考設(shè)計
- tcrt5000
- LT4276BUFD LTPoE++ 70W 電源在正向模式下的典型應(yīng)用電路
- 【PCB求糾錯】無刷驅(qū)動模塊/17屆極速越野組
- 頭部終端廠商自研ISP芯片背后:手機市場競爭不變的賽點
- 配置arm-linux虛擬機開發(fā)環(huán)境
- 存儲器寒冬說頻遭打臉?業(yè)內(nèi):僅是短期修正 需求穩(wěn)定
- 【STM32】CubeMX+HAL 點亮LED
- plc編程入門_如何學(xué)習(xí)PLC編程
- stm32 6 step pwm信號生成
- ChargePoint和Gatik將合作開發(fā)自動駕駛電動中型卡車的電動生態(tài)系統(tǒng)
- STM32比較常見的BUG總結(jié)
- 是德科技發(fā)布調(diào)查報告——軟件測試自動化是衛(wèi)星行業(yè)面臨的首要技術(shù)挑戰(zhàn)
- 蜂巢能源2025年試產(chǎn)半固態(tài)電池,2027年大批量供貨
- 激光雷達進化論:RoboSense如何持續(xù)領(lǐng)跑?
- 法雷奧-全景顯示技術(shù) Panovision | 申報2025第七屆金輯獎中國汽車新供應(yīng)鏈百強
- 公安部:目前我國市售汽車搭載的“智駕”系統(tǒng),都不具備“自動駕駛”功能
- 德賽西威-旗艦級AI智能座艙域控制器 | 申報2025第七屆金輯獎中國汽車新供應(yīng)鏈百強
- Mobileye推出駕駛員監(jiān)測系統(tǒng)(DMS)技術(shù) ,實現(xiàn)人與車輛協(xié)同駕駛
- 第三屆安富利汽車生態(tài)圈峰會盛大啟幕,雙城聯(lián)動激發(fā)智慧出行產(chǎn)業(yè)新動能
- Vicor Corporation 2025年第二季度財報:專利訴訟和解推動強勁增長
- 智能底盤2.0競賽,這家外資巨頭按下加速鍵
- GaN技術(shù)如何應(yīng)用到人形機器人執(zhí)行關(guān)節(jié)?
- 機器人逐漸代替我們工作,當失業(yè)大潮席卷而來的時候,你準備好了嗎
- 我國工業(yè)機器人高速發(fā)展,但關(guān)鍵技術(shù)較弱,產(chǎn)業(yè)應(yīng)用集中在中低端
- 韓國研發(fā)電池電極活性材料單粒子的3D觀測模型 提升電池能效
- 全球首例:博世與戴姆勒合作推出的無人泊車技術(shù)獲批
- 佛吉亞合作微軟 利用微軟互聯(lián)汽車/云平臺打造未來座艙
- 基于C8051F系列單片機的數(shù)據(jù)采集系統(tǒng)USB接口設(shè)計
- 單片機學(xué)習(xí)心得1:89c51單片機定時器應(yīng)用!
- 單片機按鍵掃描程序和顯示程序及延時程序解析
- 一文掌握全部單片機硬件抗干擾技術(shù)
- ATMEGA8單片機對步進電機的驅(qū)動