S3C6410 PWM驱动(三) --- 源代码

/***********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)};

你可能感兴趣的:(S3C6410 PWM驱动(三) --- 源代码)