📄 weida_printer.c
字号:
/*weida_printer i/o map:data Strobe(pin1)->GPD0ack(pin19)->GPD1BUSY(pin21)->GPD2Paper End(pin23)->CON-GPIO 18pinSELECT(pin25)->GPD3ERROER(pin4)->GPD4data0-data7(pin3,5...17)->GPC8,GPC9,GPC10,GPC11,GPC12,GPC13,GPC14,GPC15*//* * driver/char/weida_printer.c * * Copyright (C) 2006 ccb * * May be freely distributed as part of Linux. */#include <linux/config.h>#include <linux/module.h>#include <linux/init.h>#include <linux/version.h>#include <asm-arm/uaccess.h>#include <linux/miscdevice.h>#include <linux/sched.h>#include <linux/delay.h>#include <linux/poll.h>#include <asm-arm/delay.h>#include <asm/hardware.h>#include <asm-arm/arch-s3c2410/S3C2410.h>#include "weida_printer.h"#if CONFIG_MODVERSIONS==1#define MODVERSIONS#include <linux/modversions.h>#endif#define DEVICE_NAME "weida_printer"#define WEIDA_MAJOR 234static int gpio_data_tab[] = { GPIO_C8, GPIO_C9, GPIO_C10, GPIO_C11, GPIO_C12, GPIO_C13, GPIO_C14, GPIO_C15};#define DATA_NUM ( (sizeof gpio_data_tab) / sizeof (gpio_data_tab[0]) )#define WEIDA_DATA_READY GPIO_D0#define WEIDA_ACK GPIO_D1#define WEIDA_BUSY GPIO_D2#define WEIDA_SELECT GPIO_D3#define WEIDA_ERROR GPIO_D4static DECLARE_WAIT_QUEUE_HEAD(weida_printer_wait);static void weida_printer_io_port_init(void){ int i; for (i = 0; i < DATA_NUM; i ++) { unsigned gpio = gpio_data_tab[i]; set_gpio_ctrl(gpio | GPIO_PULLUP_DIS | GPIO_MODE_OUT); write_gpio_bit(gpio, 0); } set_gpio_ctrl(WEIDA_DATA_READY | GPIO_PULLUP_DIS | GPIO_MODE_OUT); set_gpio_ctrl(WEIDA_ACK | GPIO_PULLUP_DIS | GPIO_MODE_IN); set_gpio_ctrl(WEIDA_BUSY | GPIO_PULLUP_DIS | GPIO_MODE_IN); set_gpio_ctrl(WEIDA_SELECT | GPIO_PULLUP_DIS | GPIO_MODE_IN); set_gpio_ctrl(WEIDA_ERROR | GPIO_PULLUP_DIS | GPIO_MODE_IN); printk("init port!/n");}#define DATA_READY(x) write_gpio_bit(WEIDA_DATA_READY, x)static void type_data(unsigned char data){ int data_bit, j; mdelay(150); for(j=0 ; j<8; j++) { data_bit = ((data & (1 << j)) >> j ); write_gpio_bit(gpio_data_tab[j], data_bit&0x01); udelay(2); } DATA_READY(0); udelay(2); DATA_READY(1); //printk("type!/n");} static void weida_init(void){ printk("init!/n"); INIT_WEIDA; SET_LANDSCAPE; SET_FONT_SPACE(2); SET_LINE_SPACE(2); DELETE_LINE;}static int weida_printer_write(struct file * file, const char * buffer, size_t count, loff_t *ppos){ unsigned char *kbuf; int ready; ready = read_gpio_bit(WEIDA_BUSY); printk("write busy!"); if (ready) return -EBUSY; //ready = read_gpio_bit(WEIDA_SELECT); // printk("write ready!"); // if (!ready) // return -EAGAIN; // ready = read_gpio_bit(WEIDA_ERROR);// printk("write error1!");// if (!ready) // return -EINVAL;// printk("write error2!"); kbuf = kmalloc(count+1, GFP_KERNEL); printk("kbuf!"); memset(kbuf, '\0', count+1); printk("memset!"); if (copy_from_user (kbuf, buffer, count)) { printk("copy form user wrong!"); kfree(kbuf); return -EFAULT; } while(*kbuf != '\0') { type_data(*kbuf); while(read_gpio_bit(WEIDA_ACK)); printk("%c",*kbuf); kbuf++; } kfree(kbuf); return count;}static unsigned int weida_printer_select( struct file *file, struct poll_table_struct *wait){ int ready; ready = read_gpio_bit(WEIDA_BUSY); if (!ready) return 1; poll_wait(file, &weida_printer_wait, wait); printk("select!/n"); return 0;}static int weida_printer_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg){ int num; switch(cmd) { case WEIDA_IOCSFONTSPACE: //get_user(num, &arg); copy_from_user(&num, &arg, sizeof num); SET_FONT_SPACE(num); break; case WEIDA_IOCSLINESPACE: copy_from_user(&num, &arg, sizeof num); SET_LINE_SPACE(num); break; case WEIDA_IOCSUNDERLINE: copy_from_user(&num, &arg, sizeof num); SET_UNDERLINE(num); break; case WEIDA_IOCSUPLINE: copy_from_user(&num, &arg, sizeof num); SET_UPLINE(num); break; case WEIDA_IOCSCHARACTER1: SELECT_CHARACTER1; break; case WEIDA_IOCSCHARACTER2: SELECT_CHARACTER2; break; case WEIDA_IOCSDOT_MATRIX: copy_from_user(&num, &arg, sizeof num); SELECT_DOT_MATRIX(num); break; case WEIDA_IOCIWEIDA: INIT_WEIDA; break; case WEIDA_IOCLAMPLIFY: copy_from_user(&num, &arg, sizeof num); LANDSCAPE_AMPLIFY(num); break; case WEIDA_IOCVAMPLIFY: copy_from_user(&num, &arg, sizeof num); VERTICAL_AMPLIFY(num); break; case WEIDA_IOCSLANDSCAPE: SET_LANDSCAPE; break; case WEIDA_IOCSVERTICAL: SET_VERTICAL; break; case WEIDA_IOCSRIGHTLIMIT: copy_from_user(&num, &arg, sizeof num); SET_RIGHT_LIMIT(num); break; case WEIDA_IOCSLEFTLIMIT: copy_from_user(&num, &arg, sizeof num); SET_LEFT_LIMIT(num); break; case WEIDA_IOCSHEX_PRINT: copy_from_user(&num, &arg, sizeof num); HEX_PRINT(num); break; case WEIDA_IOCS2HANZI: SET_2_HANZI; break; case WEIDA_IOCC2HANZI: CLEAR_2_HANZI; break; default: return -EINVAL; } printk("ioctl!/n"); return 0;}static struct file_operations weida_printer_fops = { owner: THIS_MODULE, ioctl: weida_printer_ioctl, poll: weida_printer_select, write: weida_printer_write,};static int __init weida_printer_init(void){ int ret; ret = register_chrdev(WEIDA_MAJOR, DEVICE_NAME, &weida_printer_fops); if (ret < 0) { printk(DEVICE_NAME " can't register major number\n"); return ret; } weida_printer_io_port_init(); weida_init(); printk("weida_printer_init!/n"); return 0;}static void __exit weida_printer_exit(void){ unregister_chrdev(WEIDA_MAJOR, DEVICE_NAME);}module_init(weida_printer_init);module_exit(weida_printer_exit);MODULE_LICENSE("GPL");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -