【Linux driver】----TP driver

1. Input subsystem

Core layer: Linux_Dir/drivers/input/input.c (provides the core functions)
Device event layer: Linux_Dir/drivers/input/evdev.c (provides handler)
provides raw data generated by the input device and reports it to the application. This is applicable For
all input devices, the touch screen is no exception.
When writing a driver based on the input subsystem, you only need to:
1. Allocate input_dev
2. Set what events can be generated and which events of this type
3. input_register_device registration
4. Hardware operation
Insert image description here

The input subsystem needs to provide functions such as file reading and writing. In the File_operations structure in "input.c" in the input subsystem, it is found that only the ".open" function exists

static const struct file_operations input_fops = {
    
    
    .owner = THIS_MODULE,
    .open = input_open_file,
};

In the "input_open_file" function, you will find that it relies on the "input_handler" structure registered by other files such as "evdev.c, keyboard.c" and other files (these structures provide functions such as read and write).

static int input_open_file(struct inode *inode, struct file *file)
{
    
    
    struct input_handler *handler = input_table[iminor(inode) >> 5];
    const struct file_operations *old_fops, *new_fops = NULL;
    int err;

       .....
    old_fops = file->f_op;
    file->f_op = new_fops;

    err = new_fops->open(inode, file);

    if (err) {
    
    
        fops_put(file->f_op);
        file->f_op = fops_get(old_fops);
    }
    fops_put(old_fops);
    return err;
}

Insert image description here
The touch screen is also operated using the above framework. You need an "evdev.c" file on the right. An "input_dev" structure is allocated on the left
. Then look at the process on the left side of the hardware device in the picture above:
allocate an "input_dev" structure --> set the "input_dev" structure --> register the "input_dev"
structure --> hardware-related operations.

2. Touch screen hardware principle

Insert image description here

Insert image description here

3. s3c2440 AD controller

  • A/D converter freq. = 50MHz/(49+1) = 1MHz
  • Conversion time = 1/(1MHz / 5cycles) = 1/200KHz = 5 us You
    need to set the appropriate clock to the touch screen module. In the experiment, it is set to 1MHz. The
    driver needs to enable the ADC module through clk_get and clk_enable and set the bit6 of adccon to 49. Make the touch screen clock 1MHZ
	clk = clk_get(NULL, "adc");
	clk_enable(clk);

In the automatic X/Y coordinate conversion mode, the X coordinate is stored in the register ADCDAT0 and the Y coordinate is stored in ADCDAT1. The driver can read
BIT15 of ADCDAT0/1 to obtain the converted X/Y coordinate.

Waiting for the touch pen to be pressed or released. You can know whether to wait for the release or press by judging whether BIT8 of ADCTSC is set.

4. Touch screen usage process

1. What types of events can occur?

	set_bit(EV_KEY, s3c_ts_dev->evbit); //设置input_dev的evdev数组中的EV_KEY位
    set_bit(EV_ABS, s3c_ts_dev->evbit);//设置input_dev的evdev数组中的EV_ABS位

2. Set the components that generate such events

    set_bit(BTN_TOUCH, s3c_ts_dev->keybit);

    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);

BIN_TOUCH: Touch "button" event
ABS_X/ABS_Y: X/Y absolute displacement
ABS_PRESSURE: Absolute displacement pressure event

3.Hardware operation

    s3c_ts_regs = ioremap(0x58000000, sizeof(struct s3c_ts_regs));//ioremap寄存器
    
    s3c_ts_regs->adcdly = 0xffff;//设置ADCDLY为最大值, 这使得电压稳定后再发出IRQ_TC中断
    
    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);

5. Code Reference

https://gitee.com/change-ly/linux_drv

Guess you like

Origin blog.csdn.net/weixin_45281868/article/details/127129766
Recommended