Touch screen driver

Source: Internet
Author: User

The Touch Screen driver framework is similar to the input subsystem in the previous article, but the underlying driver is changed from buttons to touch screens.

ADC registers of S3C2440:

struct s3c_ts_regs {  unsigned long adccon;  unsigned long adctsc;  unsigned long adcdly;  unsigned long adcdat0;  unsigned long adcdat1;  unsigned long adcupdn;};

1. Allocate the input_dev struct

struct input_dev *s3c_ts_dev = input_allocate_device();
2. Set 2.1 to set the Event Type
set_bit(EV_KEY, s3c_ts_dev->evbit);set_bit(EV_ABS, s3c_ts_dev->evbit);
2.2 events that can generate such events
set_bit(BTN_TOUCH, s3c_ts_dev->keybit);
// Supports absolute value X coordinates, and sets the maximum and minimum values in the coordinate system, as well as interference values and welding positions.
input_set_abs_params(s3c_ts_dev, ABS_X,              0, 0x3FF, 0, 0);input_set_abs_params(s3c_ts_dev, ABS_Y,              0, 0x3FF, 0, 0);input_set_abs_params(s3c_ts_dev, ABS_PRESSURE, 0, 1, 0, 0);
3. Registration
inpute_register_device(s3c_ts_dev);
4. Hardware-related operations 4.1 enable ADC clock
struct clk *clk = clk_get(NULL, "adc");clk_enable(clk);
4.2 set the relevant registers of the ADC
Initi_ts_regs = ioremap (0x58000000, sizeof (struct initi_ts_regs);/* converter prescaler enable, adcclk = pclk/(49 + 1) = 50 MHz/(49 + 1) = 1 MHz */initi_ts_regs-> adccon = (1 <14) | (49 <6); initi_ts_regs-> adcdly = 0 xFFFF; // set this register to the maximum value to ensure the accuracy of the ADC conversion.
4.3 request interruption, ADC conversion completed interruption and touch screen press or lift interruption
request_irq(IRQ_TC, pen_down_up_irq, IRQF_SAMPLE_RANDOM, "ts_pen", NULL);request_irq(IRQ_ADC, adc_irq, IRQF_SAMPLE_RANDOM, "adc", NULL);
4.4 initialize the timer to handle sliding on the touch screen
init_timer(&ts_timer);ts_timer.function = s3c_ts_timer_function;add_timer(&ts_timer);
4.5 let the touch screen wait for the pen tip to press
enter_wait_pen_dowm_mode();
5. Touch Screen mode settings
void enter_wait_pen_down_mode(void){     s3c_ts_regs->adctsc = 0xd3;}void enter_wait_pen_up_mode(void){     s3c_ts_regs->adctsc = 0x1d3;}void enter_measure_xy_mode(void){     s3c_ts_regs->adctsc = (1<<3) | (1<<2);}void start_adc(void){     s3c_ts_regs->adccon |= (1<<0);}
6. The timer processing function reports events.
Void Merge (void) {If (initi_ts_regs-> adcdat0 & (1 <15) {/* release */input_report_abs (initi_ts_dev, abs_pressure, 0); input_report_key (initi_ts_dev, btn_touch, 0); input_sync (initi_ts_dev); enter_wait_pen_down_mode () ;}else {/* press */enter_measure_xy_mode (); start_adc ();}}
7. interrupt handling functions
Irqreturn_t release (int irq, void * dev_id) {If (initi_ts_regs-> adcdat0 & (1 <15) {/* release */input_report_abs (initi_ts_dev, abs_pressure, 0 ); input_report_key (cloud_ts_dev, btn_touch, 0); input_sync (cloud_ts_dev); reset () ;}else {/* press */RESET (); start_adc () ;}return irq_handled ;} irqreturn_t adc_irq (int irq, void * dev_id) {static int CNT = 0; static int X [4], Y [4]; int adcdat0, adcdat1; adcdat0 = cloud_ts_regs-> adcdat0; adcdat1 = cloud_ts_regs-> adcdat1; If (cloud_ts_regs-> adcdat0 & (1 <15) {/* release */CNT = 0; values (maid, abs_pressure, 0); values (maid, btn_touch, 0); input_sync (FIG); values () ;}else {x [CNT] = adcdat0 & 0x3fff; Y [CNT] = adcdat1 & 0x3fff; ++ CNT; If (CNT = 4) {If (initi_filter_ts (x, y) {input_report_abs (initi_ts_dev, abs_x, (X [1] + X [2] + X [3] + X [4])/4); input_report_abs (initi_ts_dev, abs_y, (Y [1] + Y [2] + Y [3] + Y [4])/4); input_report_abs (initi_ts_dev, abs_pressure, 1); input_report_key (initi_ts_dev, btn_touch, 1); input_sync (initi_ts_dev) ;}cnt = 0; enter_wait_pen_up_mode (); mod_timer (& ts_timer, jiffies + Hz/100);} else {enter_measure_xy_mode (); start_adc () ;}return irq_handled ;}
8. filter the data converted by the ADC.
static int s3c_filter_ts(int x[], int y[]){#define ERR_LIMIT 10     int avr_x, avr_y;     int det_x, det_y;     avr_x = (x[0] + x[1])/2;     avr_y = (y[0] + y[1])/2;     det_x = (x[2] > avr_x) ? (x[2] - avr_x) : (avr_x - x[2]);     det_y = (y[2] > avr_y) ? (y[2] - avr_y) : (avr_y - y[2]);     if ((det_x > ERR_LIMIT) || (det_y > ERR_LIMIT))          return 0;     avr_x = (x[1] + x[2])/2;     avr_y = (y[1] + y[2])/2;     det_x = (x[3] > avr_x) ? (x[3] - avr_x) : (avr_x - x[3]);     det_y = (y[3] > avr_y) ? (y[3] - avr_y) : (avr_y - y[3]);     if ((det_x > ERR_LIMIT) || (det_y > ERR_LIMIT))          return 0;     return 1;}
 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.