ok6410使用2.6内核驱动规范重写——pwm

/*************************************************************************
    > File Name: pwm_new.c
    > Author: wangermao
    > Mail: wangermao@gmail.com 
    > Created Time: 2012年05月27日 星期天 23时10分59秒
 ************************************************************************/

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/poll.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <linux/interrupt.h>
#include <asm/uaccess.h>
#include <mach/hardware.h>
#include <plat/regs-timer.h>
#include <mach/regs-irq.h>
#include <asm/mach/time.h>
#include <linux/clk.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/miscdevice.h>

#include <mach/map.h>
#include <mach/regs-clock.h>
#include <mach/regs-gpio.h>

#include <plat/gpio-cfg.h>
#include <mach/gpio-bank-e.h>
#include <mach/gpio-bank-f.h>
#include <mach/gpio-bank-k.h>

//#define PWM_MAGIC 1991

#ifndef PWM_MAGIC
	#define PWM_IOCTL_STOP 0
	#define PWM_IOCTL_SETFREQ 1
#else
	#define PWM_IOCTL_STOP _IO(PWM_MAGIC, 0)
	#define PWM_IOCTL_SETFREQ _(PWM_MAGIC, 1)
#endif

static pwm_new_major = 0;

static struct pwm_new_dev {
	struct cdev cdev;
	struct semaphore lock;
}pwm_new_dev;

static void pwm_set_freq(unsigned long arg)
{
	unsigned int tmp;
	struct clk *clk_p;
	unsigned long pclk, tcnt;

	tmp = ioread32(S3C64XX_GPFCON);
	tmp &= ~(0x03U<<30);
	tmp |= (0x02U<<30);
	iowrite32(tmp, S3C64XX_GPFCON);

	tmp = ioread32(S3C_TCFG0);
	tmp &= ~S3C_TCFG_PRESCALER0_MASK;
	tmp |= (50-1);
	iowrite32(tmp, S3C_TCFG0);

	tmp = ioread32(S3C_TCFG1);
	tmp &= ~S3C_TCFG1_MUX0_MASK;
	tmp |= S3C_TCFG1_MUX0_DIV16;
	iowrite32(tmp, S3C_TCFG1);

	clk_p = clk_get(NULL, "pclk");
	pclk = clk_get_rate(clk_p);
	tcnt = pclk/50/16/arg;
	iowrite32(tcnt, S3C_TCNTB(0));
	iowrite32(tcnt/2, S3C_TCMPB(0));

	tmp = ioread32(S3C_TCON);
	tmp &= ~0x1f;
	tmp |= (0x0b);	
	iowrite32(tmp, S3C_TCON);
	tmp &= ~2;	
	iowrite32(tmp, S3C_TCON);
}

static void pwm_stop()
{
	unsigned int tmp;
	tmp = ioread32(S3C64XX_GPFCON);
	tmp &= ~(0x03U<<30);
	iowrite32(tmp, S3C64XX_GPFCON);
}

static long pwm_new_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
	switch (cmd) {
		case PWM_IOCTL_STOP:
			pwm_stop();
			break;
		case PWM_IOCTL_SETFREQ:
			pwm_set_freq(arg);
			break;
		default:
			break;
	}
}

static int pwm_new_open(struct inode *inode, struct file *filp)
{
	struct pwm_new_dev *dev;
	dev = container_of(inode->i_cdev, struct pwm_new_dev, cdev);
	if (down_trylock(&dev->lock))
		return -EBUSY;

	filp->private_data = dev;

	return 0;
}

static int pwm_new_release(struct inode *inode, struct file *filp)
{
	struct pwm_new_dev *dev;
	dev = filp->private_data;
	up(&dev->lock);
	return 0;
}

static struct file_operations pwm_new_fops = {
	.owner = THIS_MODULE,
	.unlocked_ioctl = pwm_new_ioctl,
	.open = pwm_new_open,
	.release = pwm_new_release,
};

static void pwm_setup_cdev(struct pwm_new_dev *dev, int minor)
{
	int err, devno = MKDEV(pwm_new_major, minor);
	cdev_init(&dev->cdev, &pwm_new_fops);
	dev->cdev.owner = THIS_MODULE;
	dev->cdev.ops = &pwm_new_fops;
	err = cdev_add(&dev->cdev, devno, 1);
	if (err)
		printk(KERN_NOTICE "error:%d adding cdev \n", err);
}

static int __init pwm_new_init(void)
{
	int ret;
	dev_t devno = MKDEV(pwm_new_major, 0);

	if (devno)
		register_chrdev_region(devno, 1, "pwm_new");
	else {
		ret = alloc_chrdev_region(&devno, 0, 1, "pwm_new");
		pwm_new_major = MAJOR(devno);
	}

	if (ret < 0)
		return ret;

	sema_init(&pwm_new_dev.lock, 1);
	pwm_setup_cdev(&pwm_new_dev, 0);
	
	return 0;
}

static void __exit pwm_new_exit(void)
{
	cdev_del(&pwm_new_dev.cdev);
	unregister_chrdev_region(MKDEV(pwm_new_major, 0), 1);
}

MODULE_AUTHOR("WANGERMAO");
MODULE_LICENSE("GPL");
module_init(pwm_new_init);
module_exit(pwm_new_exit);


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值