這個驅動使能了幾個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...