📄 parport_2410_16c552.c
字号:
/* S3C2410 开发板扩展并口16C552的low-level驱动 * * Author: Allen He<wingwind@sina.com> * * * * The extended parallel port provides one port at a fixed address * with 8 output data lines (D0 - D7), 1 output control line (STROBE) * and 1 input status line (BUSY) able to cause an interrupt. *///#define MODULE //HYL Add #include <linux/module.h>#include <linux/kernel.h>#include <linux/init.h>#include <linux/parport.h>#include <linux/slab.h>#include <linux/ioport.h>#include <asm/irq.h>#include <asm/hardware.h>#include <asm/arch/cpu_s3c2410.h>#include <asm/arch/parport_2410_16c552.h>static struct parport *this_port = NULL; unsigned charparport_16c552_read_data(struct parport *p){ unsigned long flags; unsigned char data; save_flags(flags); cli(); data=*((unsigned char *)(p->base+0x0)) ; restore_flags(flags); return data;}static voidparport_16c552_write_data(struct parport *p, unsigned char data){ unsigned long flags; save_flags(flags); cli(); *((unsigned char *)(p->base+0x0))=data; restore_flags(flags); return;}unsigned char parport_16c552_read_control(struct parport *p){ unsigned long flags; unsigned char control = 0; save_flags(flags); cli(); control=*((unsigned char *)(p->base+0x2)); restore_flags(flags); return control;}void parport_16c552_write_control(struct parport *p, unsigned char d){ unsigned long flags; save_flags(flags); cli(); *((unsigned char *)(p->base+0x2))=d; restore_flags(flags); return;}static unsigned charparport_16c552_frob_control(struct parport *p, unsigned char mask, unsigned char val){ unsigned char old = parport_16c552_read_control(p); parport_16c552_write_control(p, (old & ~mask) ^ val); return old;}static unsigned charparport_16c552_read_status(struct parport *p){ return (*((unsigned char *)(p->base+0x1)));}static voidparport_16c552_init_state(struct pardevice *d, struct parport_state *s){}static voidparport_16c552_save_state(struct parport *p, struct parport_state *s){}static voidparport_16c552_restore_state(struct parport *p, struct parport_state *s){}static voidparport_16c552_interrupt(int irq, void *dev_id, struct pt_regs *regs){ parport_generic_irq(irq, (struct parport *) dev_id, regs);}static voidparport_16c552_enable_irq(struct parport *p){ enable_irq(INT_EINT8_23);}static voidparport_16c552_disable_irq(struct parport *p){ disable_irq(INT_EINT8_23);}static voidparport_16c552_data_forward(struct parport *p){ unsigned long flags; save_flags(flags); cli(); parport_16c552_frob_control(p,0x20,0x0); restore_flags(flags);}static voidparport_16c552_data_reverse(struct parport *p){ unsigned long flags; save_flags(flags); cli(); parport_16c552_frob_control(p,0x20,0x20); restore_flags(flags);}static voidparport_16c552_inc_use_count(void){ MOD_INC_USE_COUNT;}static voidparport_16c552_dec_use_count(void){ MOD_DEC_USE_COUNT;}static struct parport_operations parport_16c552_ops = { parport_16c552_write_data, parport_16c552_read_data, parport_16c552_write_control, parport_16c552_read_control, parport_16c552_frob_control, parport_16c552_read_status, parport_16c552_enable_irq, parport_16c552_disable_irq, parport_16c552_data_forward, parport_16c552_data_reverse, parport_16c552_init_state, parport_16c552_save_state, parport_16c552_restore_state, parport_16c552_inc_use_count, parport_16c552_dec_use_count, parport_ieee1284_epp_write_data, parport_ieee1284_epp_read_data, parport_ieee1284_epp_write_addr, parport_ieee1284_epp_read_addr, parport_ieee1284_ecp_write_data, parport_ieee1284_ecp_read_data, parport_ieee1284_ecp_write_addr, parport_ieee1284_write_compat, parport_ieee1284_read_nibble, parport_ieee1284_read_byte,};int __initparport_16c552_init(void){ struct parport *p; unsigned long flags; /*分配内存区域*/ if(check_mem_region(brd_16c552_parportbase,0x800))//0x800 is a number defined as will. { printk("16c552 driver:memory already in use\n"); return -EBUSY; } request_mem_region(brd_16c552_parportbase,0x800,"parport_16c552"); p = parport_register_port(brd_16c552_parportbase,INT_EINT8_23, PARPORT_DMA_NONE, &parport_16c552_ops); if (!p) return 0; if (request_irq(INT_EINT8_23, parport_16c552_interrupt, SA_SHIRQ, p->name, p)) { parport_unregister_port (p); return 0; } /* // initialize the parport as a input device with disabling irq. save_flags(flags); cli(); parport_16c552_frob_control(p,0x3f,0x24); restore_flags(flags);*/ this_port = p; printk(KERN_INFO "%s: s3c2410 brd extended with 16c552, port using irq\n", p->name); parport_proc_register(p); parport_announce_port (p); return 1; }#ifdef MODULEMODULE_AUTHOR("Wingwind");MODULE_DESCRIPTION("Parport Driver for 16c552 parellel Port");MODULE_SUPPORTED_DEVICE("S3c2410 extending 16c552 Parallel Port");MODULE_LICENSE("GPL");intinit_module(void){ return parport_16c552_init() ? 0 : -ENODEV;}voidcleanup_module(void){ if (this_port->irq != PARPORT_IRQ_NONE) free_irq(IRQ_MFP_BUSY, this_port); parport_proc_unregister(this_port); parport_unregister_port(this_port); release_mem_region(brd_16c552_parportbase,0x800,); }#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -