热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

linux安装触摸版驱动程序,添加触摸屏驱动程序linux2.6.32在mini2440开发板上移植_Linux编程_Linux公社Linux系统门户网站...

在内核中添加触摸屏驱动程序编者:linux2.6.32并没有带S3C2440触摸屏驱动程序,需要自己实现。而在此的触摸屏驱动程序时作为一个输入设备来实现

在内核中添加触摸屏驱动程序

编者:linux2.6.32并没有带S3C2440触摸屏驱动程序,需要自己实现。而在此的触摸屏驱动程序时作为一个输入设备来实现的。在linux中,对于输入设备而言,内核专为其设计了输入子系统,由核心层处理公共的工作。因为对于输入设备而言,只是中断、读键值/坐标值是与设备相关的,其余的如输入事件的缓冲区的管理以及字符设备驱动的file_operations接口则是输入设备通用的。所以在此是在输入子系统的框架下进行编写触摸屏驱动程序。对于这个驱动的移植以及讲解,参考了网上的一些文章,一部分摒弃了手册。

1 在内核中添加触摸屏驱动程序

Linux-2.6.32.2 内核也没有包含支持S3C2440 的触摸屏驱动,因此我们自行设计了一个s3c2410_ts.c,它位于linux-src/drivers/input/touchscreen 目录下,你可以自己增加一个s3c2410_ts.c 文件,并复制如下内容:

#include

#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 *s3c2410ts_name &#61; "s3c2410 TouchScreen";

static struct input_dev *dev;

static long xp;

static long yp;

static int count;

extern struct semaphore ADC_LOCK;

static int OwnADC &#61; 0;

static void __iomem *base_addr;

static inline void s3c2410_ts_connect(void)

{

s3c2410_gpio_cfgpin(S3C2410_GPG(12), S3C2410_GPG12_XMON);

s3c2410_gpio_cfgpin(S3C2410_GPG(13), S3C2410_GPG13_nXPON);

s3c2410_gpio_cfgpin(S3C2410_GPG(14), S3C2410_GPG14_YMON);

s3c2410_gpio_cfgpin(S3C2410_GPG(15), S3C2410_GPG15_nYPON);

}

static void touch_timer_fire(unsigned long data)

{

unsigned long data0;

unsigned long data1;

int updown;

data0 &#61; ioread32(base_addr&#43;S3C2410_ADCDAT0);

data1 &#61; ioread32(base_addr&#43;S3C2410_ADCDAT1);

updown &#61; (!(data0 & S3C2410_ADCDAT0_UPDOWN)) && (!(data1 & S3C2410_ADCDAT0_UPDOWN));

if (updown) {

if (count !&#61; 0) {

long tmp;

tmp &#61; xp;

xp &#61; yp;

yp &#61; tmp;

xp >>&#61; 2;

yp >>&#61; 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 &#61; 0;

yp &#61; 0;

count &#61; 0;

iowrite32(S3C2410_ADCTSC_PULL_UP_DISABLE | AUTOPST, base_addr&#43;S3C2410_ADCTSC);

iowrite32(ioread32(base_addr&#43;S3C2410_ADCCON) | S3C2410_ADCCON_ENABLE_START,

base_addr&#43;S3C2410_ADCCON);

} else {

count &#61; 0;

input_report_key(dev, BTN_TOUCH, 0);

input_report_abs(dev, ABS_PRESSURE, 0);

input_sync(dev);

iowrite32(WAIT4INT(0), base_addr&#43;S3C2410_ADCTSC);

if (OwnADC) {

OwnADC &#61; 0;

up(&ADC_LOCK);

}

}

}

static struct timer_list touch_timer &#61;

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) &#61;&#61; 0) {

OwnADC &#61; 1;

data0 &#61; ioread32(base_addr&#43;S3C2410_ADCDAT0);

data1 &#61; ioread32(base_addr&#43;S3C2410_ADCDAT1);

updown &#61; (!(data0 & S3C2410_ADCDAT0_UPDOWN)) && (!(data1 &

S3C2410_ADCDAT0_UPDOWN));

if (updown) {

touch_timer_fire(0);

} else {

OwnADC &#61; 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 &#61; ioread32(base_addr&#43;S3C2410_ADCDAT0);

data1 &#61; ioread32(base_addr&#43;S3C2410_ADCDAT1);

xp &#43;&#61; data0 & S3C2410_ADCDAT0_XPDATA_MASK;

yp &#43;&#61; data1 & S3C2410_ADCDAT1_YPDATA_MASK;

count&#43;&#43;;

if (count <(1<<2)) {

iowrite32(S3C2410_ADCTSC_PULL_UP_DISABLE | AUTOPST,

base_addr&#43;S3C2410_ADCTSC);

iowrite32(ioread32(base_addr&#43;S3C2410_ADCCON) | S3C2410_ADCCON_ENABLE_START,

base_addr&#43;S3C2410_ADCCON);

} else {

mod_timer(&touch_timer, jiffies&#43;1);

iowrite32(WAIT4INT(1), base_addr&#43;S3C2410_ADCTSC);

}

}

return IRQ_HANDLED;

}

static struct clk *adc_clock;

static int __init s3c2410ts_init(void)

{

struct input_dev *input_dev;

adc_clock &#61; clk_get(NULL, "adc");

if (!adc_clock) {

printk(KERN_ERR "failed to get adc clock source\n");

return -ENOENT;

}

clk_enable(adc_clock);

base_addr&#61;ioremap(S3C2410_PA_ADC,0x20);

if (base_addr &#61;&#61; NULL) {

printk(KERN_ERR "Failed to remap register block\n");

return -ENOMEM;

}

/* Configure GPIOs */

s3c2410_ts_connect();

iowrite32(S3C2410_ADCCON_PRSCEN | S3C2410_ADCCON_PRSCVL(0xFF),\

base_addr&#43;S3C2410_ADCCON);

iowrite32(0xffff, base_addr&#43;S3C2410_ADCDLY);

iowrite32(WAIT4INT(0), base_addr&#43;S3C2410_ADCTSC);

/* Initialise input stuff */

input_dev &#61; input_allocate_device();

if (!input_dev) {

printk(KERN_ERR "Unable to allocate the input device !!\n");

return -ENOMEM;

}

dev &#61; input_dev;

dev->evbit[0] &#61; BIT(EV_SYN) | BIT(EV_KEY) | BIT(EV_ABS);

dev->keybit[BITS_TO_LONGS(BTN_TOUCH)] &#61; 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 &#61; s3c2410ts_name;

dev->id.bustype &#61; BUS_RS232;

dev->id.vendor &#61; 0xDEAD;

dev->id.product &#61; 0xBEEF;

dev->id.version &#61; S3C2410TSVERSION;

/* Get irqs */

if (request_irq(IRQ_ADC, stylus_action, IRQF_SHARED|IRQF_SAMPLE_RANDOM,

"s3c2410_action", dev)) {

printk(KERN_ERR "s3c2410_ts.c: Could not allocate ts IRQ_ADC !\n");

iounmap(base_addr);

return -EIO;

}

if (request_irq(IRQ_TC, stylus_updown, IRQF_SAMPLE_RANDOM,

"s3c2410_action", dev)) {

printk(KERN_ERR "s3c2410_ts.c: Could not allocate ts IRQ_TC !\n");

iounmap(base_addr);

return -EIO;

}

printk(KERN_INFO "%s successfully loaded\n", s3c2410ts_name);

/* All went ok, so register to the input system */

input_register_device(dev);

return 0;

}

static void __exit s3c2410ts_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 &#61; NULL;

}

input_unregister_device(dev);

iounmap(base_addr);

}

module_init(s3c2410ts_init);

module_exit(s3c2410ts_exit);

然后在linux-2.6.32.2/drivers/input/touchscreen/Makefile 文件中添加该源代码的目标模块&#xff0c;如图红色部分&#xff1a;

obj-$(CONFIG_TOUCHSCREEN_WM97XX_ZYLONITE) &#43;&#61; zylonite-wm97xx.o

obj-$(CONFIG_TOUCHSCREEN_W90X900) &#43;&#61; w90p910_ts.o

obj-$(CONFIG_TOUCHSCREEN_PCAP) &#43;&#61; pcap_ts.o

obj-$(CONFIG_TOUCHSCREEN_S3C2410) &#43;&#61; s3c2410_ts.o

再打开linux-2.6.32.2/drivers/input/touchscreen/Kconfig 文件&#xff0c;加入如下红色部分&#xff0c;这样就在内核配置中添加了mini2440 的触摸屏驱动选项&#xff1a;

menuconfig INPUT_TOUCHSCREEN

bool "Touchscreens"

help

Say Y here, and a list of supported touchscreens will be displayed.

This option doesn&#39;t affect the kernel.

If unsure, say Y.

if INPUT_TOUCHSCREEN

config TOUCHSCREEN_S3C2410

tristate "Samsung S3C2410 touchscreen input driver"

depends on MACH_MINI2440 && INPUT && INPUT_TOUCHSCREEN && MINI2440_ADC

help

Say Y here if you have the s3c2410 touchscreen.

If unsure, say N.

To compile this driver as a module, choose M here: the

module will be called s3c2410_ts.config TOUCHSCREEN_ADS7846

tristate "ADS7846/TSC2046 and ADS7843 based touchscreens"

depends on SPI_MASTER

depends on HWMON &#61; n || HWMON

help

至此&#xff0c;我们就已经在内核中添加完了触摸屏驱动。

2 配置编译内核并测试触摸屏驱动

在命令行执行&#xff1a;make menuconfig&#xff0c;然后依次选择如下子菜单&#xff0c;找到刚刚添加的触摸屏驱动选项&#xff1a;

Device Drivers --->

Input device support --->

[*] Touchscreens --->

按空格键选中触摸屏驱动配置选项&#xff1a;退出并保存以上内核配置&#xff0c;在命令行输入&#xff1a;make zImage&#xff0c;将生成arch/arm/boot/zImage文件&#xff0c;使用supervivi 的“k”命令把它烧写到开发板。在此我们还是使用缺省的文件系统root_qtopia&#xff0c;可以看到屏幕上出现校正界面&#xff1a;依照屏幕提示&#xff0c;使用触摸笔逐步点击“十”型交叉点&#xff0c;即可进入qtopia 系统。

3、触摸屏驱动程序的详细分析。

这个内容由于较多&#xff0c;放在下一个文章里&#xff0c;见下链接。

linux-2.6.32在mini2440开发板上移植(10)之触摸屏工作原理以及驱动程序详细分析。 http://www.linuxidc.com/Linux/2013-04/82383p10.htm0b1331709591d260c1c78e86d0c51c18.png



推荐阅读
  • 如何自行分析定位SAP BSP错误
    The“BSPtag”Imentionedintheblogtitlemeansforexamplethetagchtmlb:configCelleratorbelowwhichi ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • 本文介绍了一种划分和计数油田地块的方法。根据给定的条件,通过遍历和DFS算法,将符合条件的地块标记为不符合条件的地块,并进行计数。同时,还介绍了如何判断点是否在给定范围内的方法。 ... [详细]
  • 本文介绍了为什么要使用多进程处理TCP服务端,多进程的好处包括可靠性高和处理大量数据时速度快。然而,多进程不能共享进程空间,因此有一些变量不能共享。文章还提供了使用多进程实现TCP服务端的代码,并对代码进行了详细注释。 ... [详细]
  • 本文介绍了解决二叉树层序创建问题的方法。通过使用队列结构体和二叉树结构体,实现了入队和出队操作,并提供了判断队列是否为空的函数。详细介绍了解决该问题的步骤和流程。 ... [详细]
  • 动态规划算法的基本步骤及最长递增子序列问题详解
    本文详细介绍了动态规划算法的基本步骤,包括划分阶段、选择状态、决策和状态转移方程,并以最长递增子序列问题为例进行了详细解析。动态规划算法的有效性依赖于问题本身所具有的最优子结构性质和子问题重叠性质。通过将子问题的解保存在一个表中,在以后尽可能多地利用这些子问题的解,从而提高算法的效率。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • 本文介绍了PE文件结构中的导出表的解析方法,包括获取区段头表、遍历查找所在的区段等步骤。通过该方法可以准确地解析PE文件中的导出表信息。 ... [详细]
  • 本文介绍了一个题目的解法,通过二分答案来解决问题,但困难在于如何进行检查。文章提供了一种逃逸方式,通过移动最慢的宿管来锁门时跑到更居中的位置,从而使所有合格的寝室都居中。文章还提到可以分开判断两边的情况,并使用前缀和的方式来求出在任意时刻能够到达宿管即将锁门的寝室的人数。最后,文章提到可以改成O(n)的直接枚举来解决问题。 ... [详细]
  • Linux服务器密码过期策略、登录次数限制、私钥登录等配置方法
    本文介绍了在Linux服务器上进行密码过期策略、登录次数限制、私钥登录等配置的方法。通过修改配置文件中的参数,可以设置密码的有效期、最小间隔时间、最小长度,并在密码过期前进行提示。同时还介绍了如何进行公钥登录和修改默认账户用户名的操作。详细步骤和注意事项可参考本文内容。 ... [详细]
  • SpringBoot uri统一权限管理的实现方法及步骤详解
    本文详细介绍了SpringBoot中实现uri统一权限管理的方法,包括表结构定义、自动统计URI并自动删除脏数据、程序启动加载等步骤。通过该方法可以提高系统的安全性,实现对系统任意接口的权限拦截验证。 ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 本文介绍了多因子选股模型在实际中的构建步骤,包括风险源分析、因子筛选和体系构建,并进行了模拟实证回测。在风险源分析中,从宏观、行业、公司和特殊因素四个角度分析了影响资产价格的因素。具体包括宏观经济运行和宏经济政策对证券市场的影响,以及行业类型、行业生命周期和行业政策对股票价格的影响。 ... [详细]
  • 1,关于死锁的理解死锁,我们可以简单的理解为是两个线程同时使用同一资源,两个线程又得不到相应的资源而造成永无相互等待的情况。 2,模拟死锁背景介绍:我们创建一个朋友 ... [详细]
author-avatar
双木子婷_893
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有