#include <linux/module.h>/*__init, __exit, module_init*/ #include <linux/platform_device.h>/*platform_driver*/ #include <linux/miscdevice.h>/*struct miscdevice*/ #include <linux/fs.h>/*file_operations*/
#include <asm/arch/hardware.h>/*GPCR2*/ #include <asm/arch/pxa-regs.h>
#include <asm/uaccess.h>/*copy_from_user()*/ #include <linux/delay.h>/*mdelay()*/
spinlock_t lock;/*声明一个自旋锁*/ static char ctrl[3]; static int mgc270_stepmotor_ctrl[] = { 81, //---A 82, //---B 83, //---C 84, //---D }; static int mgc270_stepmotor_open(struct inode *inode, struct file *file) { unsigned int i; /* Set ALl pins GPO Low */ for( i = 0; i < 4; i++) pxa_gpio_mode(mgc270_stepmotor_ctrl[i] | GPIO_OUT | GPIO_DFLT_LOW); printk("mgc270-stepmotor opened!\n"); return 0; } static ssize_t mgc270_stepmotor_write(struct file *file, const char __user *buffer, size_t len, loff_t *ppos) { unsigned char n, i; unsigned long flags;
printk("mgc270-stepmotor write!\n"); spin_lock_irqsave(&lock, flags) ; if (copy_from_user(&ctrl, buffer, sizeof(ctrl)) ) return -EFAULT; printk("ctrl data is %d %d %d \n", ctrl[0]-0x30, ctrl[1]-0x30, ctrl[2]-0x30); for( n = 0; n < ctrl[2]-0x30; n++ ) { if(!(ctrl[0]-0x30)) //anticlockwise {//步进电机顺时针转 // printk("ANTI CLOCKWISE!!\n"); for( i = 0; i < 4; i++ ) { GPCR2 |= 0x0F << 17;/*GPCRx:Pin置高*/ GPSR2 |= 3 << ( 17 + i );/*GPSRx:Pin置低*/ if( i == 3 ) GPSR2 |= 1 << 17; mdelay((ctrl[1]-0x30)*100); } } else { //clockwise /*逆时针*/ // printk("CLOCK WISE!!\n"); for( i = 0; i < 4; i++ ) { GPSR2 |= 0x0F << 17; GPCR2 |= 3 << ( 20 - i ); if( i == 3 ) GPCR2 |= 1 << 20; mdelay((ctrl[1]-0x30)*100); } } } spin_unlock_irqrestore(&lock, flags); return sizeof(ctrl); } static int mgc270_stepmotor_release(struct inode *inode, struct file *file) { unsigned int i; /* Set ALl pins GPO Low */ for( i = 0; i < 4; i++) //设置GPIO模式 pxa_gpio_mode(mgc270_stepmotor_ctrl[i] | GPIO_OUT | GPIO_DFLT_LOW); printk("mgc270-stepmotor released!\n"); return 0; } static int mgc270_stepmotor_ioctl(struct inode *inode, struct file *file,unsigned int cmd, unsigned long arg) { printk("mgc270-stepmotor ioctl\n"); /* you can write code for ioctl() here */ return 0; } static const struct file_operations mgc270_stepmotor_fops = { .owner = THIS_MODULE, .write = mgc270_stepmotor_write, .ioctl = mgc270_stepmotor_ioctl, .open = mgc270_stepmotor_open, .release = mgc270_stepmotor_release, }; static struct miscdevice mgc270_stepmotor_miscdev = { .minor = MISC_DYNAMIC_MINOR, .name = "mgc270-stepmotor", .fops = &mgc270_stepmotor_fops/*miscdevice设备的file_operations,参考字符设备中的*/ }; static int mgc270_stepmotor_probe(struct platform_device *dev) { int ret; printk("probing mgc270-stepmotor!\n"); ret = misc_register(&mgc270_stepmotor_miscdev); /*注册misc设备,miscdevice结构体提供操作函数入口*/ if (ret) printk("Failed to register miscdev for MagicARM270 stepmotor.\n"); return ret; } static int mgc270_stepmotor_remove(struct platform_device *dev) {/*卸载misc设备函数,在platform_driver_unregister()中被调用*/ printk(KERN_ALERT"remove!\n"); misc_deregister(&mgc270_stepmotor_miscdev); printk("mgc270-stepmotor removed!\n"); return 0; } struct platform_device *mgc270_stepmotor_device; static struct platform_driver mgc270_stepmotor_driver = { .driver = { .name = "mgc270-stepmotor", .owner = THIS_MODULE, }, .probe = mgc270_stepmotor_probe,/*第二级初始化入口,注册misc设备*/ .remove = mgc270_stepmotor_remove,/*移出函数入口,__exit调用*/ }; static int __init mgc270_stepmotor_init(void) {//平台设备初始化,第一级初始化 int rc; printk("mgc270-stepmotor init......\n"); mgc270_stepmotor_device = platform_device_alloc("mgc270-stepmotor", -1); /*申请设备空间*/ if (!mgc270_stepmotor_device) return -ENOMEM; rc = platform_device_add(mgc270_stepmotor_device); /*在platform_device总线上添加stepmotor设备[添加device]*/ if (rc < 0) { platform_device_put(mgc270_stepmotor_device); /*失败了则释放设备空间*/ return rc; } rc = platform_driver_register(&mgc270_stepmotor_driver); /*在driver总线上注册驱动*/ if (rc < 0) platform_device_unregister(mgc270_stepmotor_device); /*失败了则删除device*/ spin_lock_init(&lock);/*初始化自旋锁*/ return rc; } static void __exit mgc270_stepmotor_exit(void) { printk(KERN_ALERT"exit!\n"); platform_driver_unregister(&mgc270_stepmotor_driver);
/*这里面调用*remove*/ printk(KERN_ALERT"driver_unregiste!\n"); platform_device_unregister(mgc270_stepmotor_device); printk("mgc270-stepmotor exit!\n"); }
module_init(mgc270_stepmotor_init); module_exit(mgc270_stepmotor_exit);
MODULE_AUTHOR("Abing "); MODULE_DESCRIPTION("ZHIYUAN MagicARM270 stepmotor Driver"); MODULE_LICENSE("GPL");
|