Linux touch screen (2)

Source: Internet
Author: User

2. Touch Screen Driver Analysis

2.1 Overview

Touch screen drivers do not distinguish between resistance and tolerance, but between single-point touch and multi-point touch. A typical touch screen driver is based on the input subsystem. Here we will analyze the driver file s3c2410_ts.c (in the old kernel, it is a great change. If you are interested, you can check it out. This file is named S3C2410, but it also supports S3C2440 and cloud6410.

2.2 driver analysis (s3c2410_ts.c)

L initialization module

Staticstruct platform_driver initi_ts_driver = {

. Driver = {

. Name = "Samsung-ts ",

. Owner = this_module,

# Ifdefconfig_pm

. PM = & cloud_ts_pmops,

# Endif

},

. Id_table = s3cts_driver_ids,

. Probe = s3c2410ts_probe,

. Remove =__ devexit_p (s3c2410ts_remove ),

};

 

Staticint _ init s3c2410ts_init (void)

{

Returnplatform_driver_register (& initi_ts_driver );

}

It can be seen that the driver is mounted to the platform bus, constructs a platform_driver struct, and then registers

 

L probe function,

Static int _ devinit s3c2410ts_probe (struct platform_device * pdev)

{

/* Obtain the clock resource for the ADC */

TS. Clock = clk_get (Dev, "ADC ");

 

/* Obtain touch screen interrupt resources */

TS. irq_tc = ret = platform_get_irq (pdev, 0 );

 

/* Obtain Io memory resources */

Res = platform_get_resource (pdev, ioresource_mem, 0 );

TS. IO = ioremap (res-> Start, resource_size (RES ));

 

/*

* Construct an ADC customer to request data conversion from the ADC

* S3c24xx_ts_select: This is called when the ADC selects or unprocesses this client.

* S3c24xx_ts_conversion: called when the ADC conversion is complete

*/

TS. Client = maid (pdev, s3c24xx_ts_select,

S3c24xx_ts_conversion, 1 );

 

/* Allocate an input device struct */

Input_dev = input_allocate_device ();

 

TS. Input = input_dev;

/* Set the input device to support ev_key and ev_abs events */

TS. Input-> evbit [0] = bit_mask (ev_key) | bit_mask (ev_abs );

 

/* The btn_touch button is supported */

TS. Input-> keybit [bit_word (btn_touch)] = bit_mask (btn_touch );

 

/* Set the touch screen range (for the range value, refer to the Data Manual) to filter out error events when handling events */

Input_set_abs_params (TS. Input, abs_x, 0, 0x3ff, 0, 0 );

Input_set_abs_params (TS. Input, abs_y, 0, 0x3ff, 0, 0 );

/* Set some attributes */

TS. Input-> name = "s3c24xxtouchscreen ";

TS. Input-> ID. bustype = bus_host;

TS. Input-> ID. Vendor = 0 xdead;

TS. Input-> ID. Product = 0 xbeef;

TS. Input-> ID. Version = 0x0102;

 

/* Set the buffer size. If oversampling_shift = 2, the buffer size is 1 <2 */

TS. Shift = Info-> oversampling_shift;

TS. Features = platform_get_device_id (pdev)-> driver_data;

 

/* Apply for touch screen interruption */

Ret = request_irq (TS. irq_tc, stylus_irq, 0,

"S3c2410_ts_pen", ts. Input );

 

/* All went OK, so register to theinput system */

Ret = input_register_device (TS. Input );

 

Return 0;

}

 

2.3 interrupt Analysis

L The core of the touch screen driver is the interrupt program. When a touch pen is clicked or popped up, interruption occurs (int_tc)

Staticirqreturn_t stylus_irq (int irq, void * dev_id)

{

Data0 = readl (TS. Io + s3c2410_adcdat0);/* Get X value */

Data1 = readl (TS. Io + s3c2410_adcdat1);/* Get y value */

 

Down = get_down (data0, data1 );

If (down)/* determines whether to press and start ADC conversion */

Initi_adc_start (TS. Client, 0, 1 <ts. Shift );

Return irq_handled;

}

 

L start ADC Conversion

Intiniti_adc_start (struct initi_adc_client * client,

Unsigned int channel, unsigned intnr_samples)

{

 

Spin_lock_irqsave (& ADC-> lock, flags );

 

Client-> channel = channel;

Client-> nr_samples = nr_samples;

 

If (client-> is_ts)

ADC-> ts_pend = client;/* "blocking" the client for request conversion */

Else

List_add_tail (& client-> pend, & adc_pending );

 

If (! ADC-> cur)/* if the current request is complete, the ADC performs the next conversion Request */

Initi_adc_try (ADC );/**/

 

Spin_unlock_irqrestore (& ADC-> lock, flags );

Return 0;

}

There may be many customers who want to convert ADC requests, so the queue mechanism is used to accept the customer's conversion requests. However, for a touch screen request conversion, the request will be blocked in ts_pend. Touch screen request conversion takes precedence over others, which I personally think may be the reason for real-time performance.

Static void89c_adc_try (struct adc_device * ADC)

{

Struct initi_adc_client * Next = ADC-> ts_pend;

 

If (! Next &&! List_empty (& adc_pending )){

Next = list_first_entry (& adc_pending,

Structiniti_adc_client, pend );

List_del (& next-> pend );

} Else

ADC-> ts_pend = NULL;

 

If (next ){

Adc_dbg (ADC, "New clientis % P \ n", next );

ADC-> cur = next;

Initi_adc_select (ADC, next);/* select the customer requesting conversion */

Cloud_adc_convert (ADC);/* Start conversion */

Initi_adc_dbgshow (ADC );

}

}

 

L int_adc interruption occurs when the ADC is fully converted. The value of "initi_adc_irq ()-> (client-> select_cb) (client, 0)" indicates that the select_cb function is "initi_adc_register ()" in the touch screen driver () registered callback function: s3c24xx_ts_select ()

Static voids3c24xx_ts_select (struct initi_adc_client * client, unsigned select)

{

If (select) {/* select the ADC conversion request customer item */

Writel (s3c2410_adctsc_pull_up_disable | autopst,

TS. Io + s3c2410_adctsc );

} Else {/**/

Mod_timer (& touch_timer, jiffies + 1 );

Writel (wait4int | int_up, ts. Io + s3c2410_adctsc );

}

}

Touch_timer is a timer. When a time-out occurs, the touch_timer_fire () function is called to report the coordinates. After the event is reported, it is handled by the input subsystem.

Static voidtouch_timer_fire (unsigned long data)

{

Data0 = readl (TS. Io + s3c2410_adcdat0 );

Data1 = readl (TS. Io + s3c2410_adcdat1 );

 

Down = get_down (data0, data1 );

 

If (down) {/* determines whether to press or play? */

If (TS. Count = (1 <ts. Shift) {/* determine whether the buffer is full */

TS. XP >>=ts. shift;

TS. yp> = ts. shift;

 

/* Report event information */

Input_report_abs (TS. Input, abs_x, ts. XP );

Input_report_abs (TS. Input, abs_y, ts. YP );

 

Input_report_key (TS. Input, btn_touch, 1 );

Input_sync (TS. Input );

 

TS. XP = 0;

TS. Yp = 0;

TS. Count = 0;

}

 

Initi_adc_start (TS. Client, 0, 1 <ts. Shift );

} Else {

TS. XP = 0;

TS. Yp = 0;

TS. Count = 0;

 

Input_report_key (TS. Input, btn_touch, 0 );

Input_sync (TS. Input );

 

Writel (wait4int | int_down, ts. Io + s3c2410_adctsc );

}

}

First, we can analyze the key points of the analysis as long as we grasp the time when two interruptions occur, otherwise it will be difficult to analyze them.

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.