乙個簡單的keyboard驅動

2021-06-17 16:36:36 字數 3506 閱讀 7283

這個驅動使能了幾個cpld控制的按鍵,f1, f2,f3,f4, home, up, down,left,right, esc, enter。

1.cpld_kpd_probe()

static int cpld_kpd_probe(struct platform_device *pdev)

cpld_input_dev=input_allocate_device();

if(!cpld_kpd_dev || !cpld_input_dev)

platform_set_drvdata(pdev, cpld_kpd_dev);

cpld_kpd_dev->input = cpld_input_dev;

cpld_input_dev->keycode = (void *)cpldkpd_keycodes;

cpld_input_dev->keycodesize = sizeof(cpldkpd_keycodes[0]);

cpld_input_dev->keycodemax = cpldkpd_keycodes_size;

cpld_input_dev->name = "cpldkpd";

cpld_input_dev->id.bustype = bus_host;

retval = input_register_device(cpld_input_dev);

if(retval < 0)

__set_bit(ev_key, cpld_input_dev->evbit);

for (i = 0; i < cpldkpd_keycodes_size; i++)

__set_bit(cpldkpd_keycodes[i], cpld_input_dev->keybit);

cpld_kpd_dev->poll_timer.expires = jiffies + kscanrate;

cpld_kpd_dev->poll_timer.function = cpld_kpd_handle_timer;

/* initialize the polling timer */

init_timer(&cpld_kpd_dev->poll_timer);

/* map cpld memory */

cpld_kpd_dev->base = ioremap(cpld_base_addr, 64);

if(!cpld_kpd_dev->base)

irq = setup_gpio_irq();

retval = request_irq(irq, cpld_kpd_interrupt, 0, mod_name, mod_name);

if(retval)

key_pad_enabled = 1;

device_init_wakeup(&pdev->dev, 1);

return 0;

err3:

free_irq(irq, mod_name);

err2:

input_unregister_device(cpld_input_dev);

err1:

input_free_device(cpld_input_dev);

kfree(cpld_kpd_dev);

return retval;

}

這算是個標準的keyboard input裝置的probe函式。

cpld_kpd_dev是個全域性變數,原型如下:

/* keypad private data structure */

struct cpld_kpd ;

struct cpld_kpd *cpld_kpd_dev;

input_dev: 表示是個輸入裝置。

poll_timer.:因為整了乙個定時器,所以有乙個timer_list

irq是中斷號,

nkeys:是按鍵的個數

然後分配乙個input_dev, 接著是初始化和註冊輸入裝置。

然後是註冊中斷。

初始化定時器:

cpld_kpd_dev->poll_timer.expires = jiffies + kscanrate;

cpld_kpd_dev->poll_timer.function = cpld_kpd_handle_timer;

/* initialize the polling timer */

init_timer(&cpld_kpd_dev->poll_timer);

remap cpld記憶體空間,訪問cpld暫存器需要:

/* map cpld memory */

cpld_kpd_dev->base = ioremap(cpld_base_addr, 64);

if(!cpld_kpd_dev->base)

設定中斷觸發方式,並註冊中斷:

irq = setup_gpio_irq();

retval = request_irq(irq, cpld_kpd_interrupt, 0, mod_name, mod_name);

if(retval)

2. 中斷服務例程, 發現中斷就報告event:

static irqreturn_t cpld_kpd_interrupt(int irq, void *dev_id)

static void cpld_kpd_handle_timer(unsigned long time)

if (cpld_kpd_scan_matrix() == 0)

}

掃瞄鍵盤,看哪個鍵按下,並傳送event,即input_event()函式,報告按下之後要報告乙個彈起的事件,因為這裡有彈起中斷。

static int cpld_kpd_scan_matrix(void)

if(reg & f2_bitmap)

if(reg & f3_bitmap)

if(reg & f4_bitmap)

if(reg & home_bitmap)

if(reg & up_bitmap)

if(reg & left_bitmap)

if(reg & right_bitmap)

if(reg & down_bitmap)

if(reg & enter_bitmap)

if(reg & esc_bitmap)

dprintk("count = 0x%x\n", count);

return count;

}

具體的按鍵有如下這些:

key_f1, key_home, key_down,

key_f2, key_up, key_enter,

key_f3, key_left, key_esc,

key_f4, key_right, 0

};

驅動篇 乙個簡單的led驅動

1.構造裝置結構體 struct light dev cdev結構體 struct cdev 2.設定裝置資訊 struct light dev light devp 設定裝置結構體變數 int light major light major 設定主裝置號3.設定並填充file operations...

乙個簡單的串列埠過濾驅動

學習驅動開發一段時間了,在嘗試著從最簡單的驅動開發著手學習,我再嘗試著編寫乙個最簡單的串列埠過濾驅動,可是多次嘗試都沒有成功,總是一載入就藍屏。看了網上的例子他們都是採用的ioattachdevicetodevicestack,而我採用的是ioattachdevice,現在把網上的 整理成最簡單的形...

乙個簡單的Linux字元驅動

這個是win驅動課的作業,題目是設計乙個通用的io埠讀寫驅動,因為我的電腦配置太低無法執行虛擬機器,就用linux完成了作業。read和write的處理併發讀寫的部分來自ldd3。1.驅動程式 通用io埠讀寫驅動 include include include include include inc...