?? fipkernel.c
字號(hào):
// FIP + IR kernel module// Copyright (c) Sigma Designs, Inc. 2002#include <linux/kernel.h>#include <linux/module.h>#include <linux/interrupt.h>#include <linux/fs.h>#include <linux/poll.h>#include <linux/ioctl.h>#include <linux/devfs_fs_kernel.h>#include <asm/pgtable.h>#include <asm/irq.h>#include <asm/hardware.h>#include "irstate.h"#include "fip.h"#include "fip_private.h"#include "fipkernel.h"#include "fipioctl.h"MODULE_DESCRIPTION("Remote control and front panel driver module");MODULE_AUTHOR("Vincent Trinh, Fabrice Gautier");#ifdef MODULE_LICENSEMODULE_LICENSE("Proprietary. Copyright (c) 2002 Sigma Designs Inc. All rights reserved.");#endif // MODULE_LICENSE//wait queuewait_queue_head_t fip_wait_queue;// Temp hackextern int fipkeyerrors;// Called by the state machine or fip when a scancode has been completedvoid fiq_handler (void){ unsigned int intno; intno = *(INT_FIQSTAT_REG); if(intno & TIMER1_INT) { // clear timer interrupt *(TIMER_TMRSTAT_REG) = 0x2; if(fip_timer()) { wake_up_interruptible(&fip_wait_queue); } return; } if(intno & PIO0_INT) { // clear pio 0 bit 1 *PIO_0_INT_STATUS_REG = ((1 << 1 ) <<16) | 0xffff; if(ir_pio()) { wake_up_interruptible(&fip_wait_queue); } return; }}void fiq_enable(int int_mask){ int status; // Set type to FIQ status = *INT_TYPE_REG; *INT_TYPE_REG = status | (int_mask); // Enable status = *INT_ENABLE_REG; *INT_ENABLE_REG = status | (int_mask); __sti ();}void fiq_disable(int int_mask){ int status; __cli (); // disable status = *INT_ENABLE_REG; *INT_ENABLE_REG = status & ~(int_mask); // reset type to IRQ status = *INT_TYPE_REG; *INT_TYPE_REG = status & ~(int_mask);}// ... To here// File opsstatic int fip_open(struct inode *inode, struct file *filp){ MOD_INC_USE_COUNT; return 0;}static int fip_release(struct inode *inode, struct file *filp){ MOD_DEC_USE_COUNT; return 0;}static int fip_ioctl(struct inode *i_node, struct file *filp,unsigned int cmd, unsigned long arg){ int rc=0; switch (cmd) { case FIP_IOCTL_FLUSH_FIFO: FIP_FIFO_FLUSH(); break; case FIP_IOCTL_DIMMER: FIP_DIMMER(arg); break; case FIP_IOCTL_DISPLAY: //printk("FIP_IOCTL_DISPLAY(%d,0x%02x)\n", (int)((arg>>16)&0x3F), (int)(arg&0xFF)); FIP_DISPLAY((arg>>16)&0x3F, arg&0xFF); break; case FIP_IOCTL_LED: FIP_LED((arg&0xFFFF),arg>>31); break; case FIP_IOCTL_READ_KEYS: rc = fip_read_scancode(arg); break; default: printk("fip_ioctl: unknow cmd = %d\n",cmd); rc = -EINVAL; } return rc;}#if 1 // XXXstatic unsigned int fip_kernel_poll(struct file *filp, poll_table *wait){ int mask = 0; poll_wait(filp,&fip_wait_queue,wait); //XXX: kinda of hackish: we use POLLIN but we read with an ioctl ?! // Should we use POLLMSG or something else ?? FIP_FIFO_LOCK (); if(!FIP_FIFO_EMPTY()) mask |= POLLIN; FIP_FIFO_UNLOCK (); return mask;}#endifstruct file_operations fip_fops = { open: fip_open, ioctl: fip_ioctl, poll: fip_kernel_poll, release: fip_release};devfs_handle_t fip_register(void){ devfs_handle_t de; unsigned int maj,min; // register char driver. // Try devfs first - if kernel doesnt support devfs, devfs_register // returns NULL#ifdef CONFIG_DEVFS_FS if((de=devfs_register(NULL, RMFIP_DEVICE_NAME, DEVFS_FL_DEFAULT, RMFIP_MAJOR, 0, S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP, &fip_fops, NULL))) { devfs_get_maj_min(de, &maj, &min); printk("init_module: device (%d:%d) registered in devfs\n", maj, min); } #else#error You must enable devfs in your kernel#endif return de;}// use the PIO interrupt to change the state in the state machineint init_module (){ int status; EXPORT_NO_SYMBOLS; printk ("\nfip: init_module\n"); init_waitqueue_head(&fip_wait_queue); install_fiq_handler(&fiq_handler); ir_init(); fip_init(); // Set type to FIQ (Timer irq used for front panel polling) status = *INT_TYPE_REG; *INT_TYPE_REG = status | TIMER1_INT; // Set type to FIQ (pio0 irq used for remote control) status = *INT_TYPE_REG; *INT_TYPE_REG = status | PIO0_INT; if(fip_register()) printk("fip: Device sucessfully registered\n"); else printk("fip: Unable to register device\n"); fip_fifo_first = 0; fip_fifo_last = 0; fiq_enable(TIMER1_INT); fiq_enable(PIO0_INT); printk("fip: init_module done\n"); return 0;}void cleanup_module (void){ printk ("fip: cleanup\n"); install_fiq_handler(NULL);}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -