天天看點

Linux字元裝置驅動總結程式(二)

前面我們講解了字元裝置驅動的一些寫法,但是那樣寫出來的程式隻能我們自己用或者自己公司用。因為你沒有統一接口,别人不知道你的裝置接口是什麼,現在我們講解幾種常用的設裝置模型。

第一:input輸入子系統(鍵盤,滑鼠,觸摸屏等等)

static struct input_dev *s3c_ts_dev;//定義一個 input_dev結構體

s3c_ts_dev = input_allocate_device();//配置設定input_dev結構體

input_register_device(s3c_ts_dev);//注冊 input_dev類型結構體

input_unregister_device(s3c_ts_dev);//解除安裝 input_dev類型結構體

input_free_device(s3c_ts_dev);//釋放配置設定的input_dev結構體

其中用到的一設定事件的函數

/* 2.1 能産生哪類事件 */

set_bit(ev_key, s3c_ts_dev->evbit);

set_bit(ev_abs, s3c_ts_dev->evbit);

/* 2.2 能産生這類事件裡的哪些事件 */

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

 unsigned long evbit[nbits(ev_max)];   // 表示能産生哪類事件

unsigned long keybit[nbits(key_max)]; // 表示能産生哪些按鍵

unsigned long relbit[nbits(rel_max)]; // 表示能産生哪些相對位移事件, x,y,滾輪

unsigned long absbit[nbits(abs_max)]; // 表示能産生哪些絕對位移事件, x,y

第二:分離的概念,平台總線的引入。

dev:(屬于不穩定的部分)

platform_device_register(&led_dev);

static struct resource led_resource[] = {

platform_device_unregister(&led_dev);

    [0] = {

        .start = 0x56000010,           //gpio_con gpio_dat兩個寄存器占八個位元組

        .end   = 0x56000010 + 8 - 1,//是以需要映射長八個位元組

        .flags = ioresource_mem,

    },

    [1] = {

        .start  = 8,

        .end   = 8,

        .flags = ioresource_irq,

    }

};

static void led_release(struct device * dev)

{

}

static struct platform_device led_dev = {

.name         = "myled",

.id       = -1,

.num_resources    = array_size(led_resource),

.resource     = led_resource,

.dev = { 

.release = led_release, 

},

drv:(穩定的部分)

struct platform_driver led_drv = {

.probe

= led_probe,

.remove

= led_remove,

.driver

= {

.name = "myled",

platform_driver_register(&led_drv);

platform_driver_unregister(&led_drv);

res = platform_get_resource(pdev, ioresource_mem, 0);

res = platform_get_resource(pdev, ioresource_irq, 0);//這兩個函數用開擷取資源

tips:在這裡這個結構體裡面的name必須和dev裡面的name一緻,隻有相同的時候才會調用led_probe其他的跟寫普通的字元裝置驅動是不變的

第三:framebuffer結構

static struct fb_info *s3c_lcd;

s3c_lcd = framebuffer_alloc(0, null);

register_framebuffer(s3c_lcd);

unregister_framebuffer(s3c_lcd);

framebuffer_release(s3c_lcd);

第四:usb

//這裡還是用了分離的概念,隻是裡面的一些函數接口不一樣,其他的模型可以前的還是一樣的。

static struct usb_driver usbmouse_as_key_driver = {

.name = "usbmouse_as_key_",

= usbmouse_as_key_probe,

.disconnect

= usbmouse_as_key_disconnect,

.id_table

      = usbmouse_as_key_id_table,

struct usb_device *dev = interface_to_usbdev(intf);

struct usb_host_interface *interface;

struct usb_endpoint_descriptor *endpoint;

input_allocate_device();

input_register_device(uk_dev);

usb_buf = usb_buffer_alloc(dev, len, gfp_atomic, &usb_buf_phys);

usb_alloc_urb(0, gfp_kernel);

usb_submit_urb(uk_urb, gfp_kernel);

usb_kill_urb(uk_urb);

usb_free_urb(uk_urb);

usb_buffer_free(dev, len, usb_buf, usb_buf_phys);

input_unregister_device(uk_dev);

input_free_device(uk_dev);

繼續閱讀