/***********wzk_pwm.c**********/ #include "wzk_pwm.h" //init dev void init_pwm(void) { unsigned int tmp; s3c_gpio_cfgpin(pwm_table[0],S3C_GPIO_SFN(2)); tmp = readl(S3C64XX_GPFCON); printk("%x\n",tmp); return; } void set_pwm_freq(unsigned freq) { unsigned int tmp; //pwm tmp = readl(S3C_TCFG0); tmp = tmp & 0xffffff00; tmp = tmp | 0x00000001; writel(tmp,S3C_TCFG0); //input freq = PCLK/(prescaler + 1)/divider //prescaler = 1; //divider = 16 tmp = readl(S3C_TCFG1); tmp = tmp & 0xfffffff0; tmp = tmp | 0x00000004; writel(tmp,S3C_TCFG1); //TCNTB0 tmp = PCLK/2/16/freq; writel(tmp,S3C_TCNTB(0)); //TCMPB0 tmp = tmp * 2 / 3; writel(tmp,S3C_TCMPB(0)); //tcon tmp = readl(S3C_TCON); tmp = tmp & 0xffffff00; tmp = tmp | 0x0000000f; writel(tmp,S3C_TCON); //clear manual update bit tmp = readl(S3C_TCON); tmp = tmp & 0xfffffffd; writel(tmp,S3C_TCON); return; } //close pwm void close_pwm(void) { unsigned int tmp; tmp = readl(S3C_TCON); tmp = tmp & 0xfffffffe; writel(tmp,S3C_TCON); s3c_gpio_cfgpin(pwm_table[0],S3C_GPIO_SFN(0)); tmp = readl(S3C_TCON); printk("tcon:%x\n",tmp); tmp = readl(S3C64XX_GPFCON); printk("gpfcon:%x\n",tmp); return; } int s3c6410_pwm_open(struct inode *inode,struct file *file) { //init device init_pwm(); return 0; } int s3c6410_pwm_close(struct inode *inode,struct file *file) { close_pwm(); return 0; } static int s3c6410_pwm_read(struct file *filp,char __user *buff,size_t count,loff_t *offp) { return 0; } static unsigned int s3c6410_pwm_poll(struct file *file,struct poll_table_struct *wait) { return 0; } static long s3c6410_pwm_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { //TCNTB0 set_pwm_freq(cmd); return 0; } static struct file_operations s3c6410_pwm_fops = { .owner = THIS_MODULE, .open = s3c6410_pwm_open, .unlocked_ioctl = s3c6410_pwm_ioctl, .release = s3c6410_pwm_close, .read = s3c6410_pwm_read, .poll = s3c6410_pwm_poll }; static struct cdev cdev_pwm; struct class * my_class; dev_t devno; static int __init s3c6410_pwm_init(void) { int ret; // dev_t devno; printk(KERN_NOTICE "enter s3c6410_pwm_init\n"); // devno = MKDEV(KEY_MAJOR,0); ret = alloc_chrdev_region(&devno,0,1,DEVICE_NAME); if(ret) { printk(KERN_NOTICE "can not register led device"); return ret; } cdev_init(&cdev_pwm,&s3c6410_pwm_fops); cdev_pwm.owner = THIS_MODULE; ret =cdev_add(&cdev_pwm,devno,1); if(ret) { printk(KERN_NOTICE "can not add leds device"); return ret; } my_class = class_create(THIS_MODULE,DEVICE_NAME); if(IS_ERR(my_class)) { printk("Err: Failed in creating class\n"); return -1; } device_create(my_class,NULL,devno,NULL,DEVICE_NAME); // init_dev(); printk(DEVICE_NAME " initialized\n"); return 0; } static void __exit s3c6410_pwm_exit(void) { device_destroy(my_class,devno); class_destroy(my_class); cdev_del(&cdev_pwm); unregister_chrdev_region(devno,1); printk(KERN_NOTICE "s3c6410_pwm_exit\n"); } module_init(s3c6410_pwm_init); module_exit(s3c6410_pwm_exit); MODULE_LICENSE("GPL");
/**********wzk_pwm.h **********/ #include <linux/module.h> #include <linux/kernel.h> #include <linux/fs.h> #include <linux/init.h> #include <linux/miscdevice.h> #include <linux/delay.h> #include <linux/device.h> #include <linux/cdev.h> #include <asm/irq.h> #include <mach/gpio.h> #include <mach/regs-gpio.h> #include <mach/gpio-bank-f.h> #include <mach/map.h> //S3C64XX_VA_GPIO #include <plat/gpio-cfg.h> #include <mach/hardware.h> #include <linux/io.h> #include <asm/io.h> #include <plat/regs-timer.h> /* #include <linux/sched.h> #include <linux/poll.h> #include <linux/interrupt.h> #include <linux/semaphore.h> #include <linux/timer.h> #include <asm/irq.h> #include <asm/uaccess.h> #include <mach/irqs.h> #include <linux/timer.h> #include <linux/jiffies.h> */ #define DEVICE_NAME "pwm" #define PCLK 66000000 #define PWM_HZ 1000 static unsigned long pwm_table[] = {S3C64XX_GPF(14)};