作者:XiaoLin.Peng

欢迎交流 196568501

#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 <linux/interrupt.h>
#include <linux/gpio.h>

#include <asm/irq.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <mach/regs-gpio.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>

#define DEVICE_NAME     "pwm"

#define PWM_IOCTL_SET_FREQ        1
#define PWM_IOCTL_STOP            0

static struct semaphore lock;

/* freq:  pclk/50/16/65536 ~ pclk/50/16
  * if pclk = 50MHz, freq is 1Hz to 62500Hz
  * human ear : 20Hz~ 20000Hz
  */
static void PWM_Set_Freq_Duty( unsigned long freq,unsigned long duty)
{
    unsigned long tcon;
    unsigned long tcnt;
    unsigned long tcfg1;
    unsigned long tcfg0;

//for test added byXiaolin.Peng
    unsigned long TCNTB_saver = 0;
    unsigned long TCMPB_saver = 0;
    
    struct clk *clk_p;
    unsigned long pclk;

//for test  added by Xiaolin.Peng
    printk("freq: %ld\n", freq);

//set GPB0 as tout0, pwm output
    s3c2410_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPB0_TOUT0);

tcon = __raw_readl(S3C2410_TCON);
    tcfg1 = __raw_readl(S3C2410_TCFG1);
    tcfg0 = __raw_readl(S3C2410_TCFG0);

//prescaler = 50
    tcfg0 &= ~S3C2410_TCFG_PRESCALER0_MASK;
    tcfg0 |= (50 - 1);

//mux = 1/16
    tcfg1 &= ~S3C2410_TCFG1_MUX0_MASK;
    tcfg1 |= S3C2410_TCFG1_MUX0_DIV16;

__raw_writel(tcfg1, S3C2410_TCFG1);
    __raw_writel(tcfg0, S3C2410_TCFG0);

clk_p = clk_get(NULL, "pclk");
    pclk  = clk_get_rate(clk_p);
    tcnt  = (pclk/(tcfg0+1)/16)/freq;
    
    __raw_writel(tcnt, S3C2410_TCNTB(0));
    __raw_writel((tcnt*duty)/100, S3C2410_TCMPB(0));

//for test add by Xiaolin.Peng
    TCNTB_saver = __raw_readl(S3C2410_TCNTB(0));
    TCMPB_saver = __raw_readl(S3C2410_TCMPB(0));
    printk("TCNTB: %ld\n", TCNTB_saver);
    printk("TCMPB: %ld\n", TCMPB_saver);    
    
    tcon &= ~0x1f;
    tcon |= 0xb;        //disable deadzone, auto-reload, inv-off, update TCNTB0&TCMPB0, start timer 0
    __raw_writel(tcon, S3C2410_TCON);
    
    tcon &= ~2;            //clear manual update bit
    __raw_writel(tcon, S3C2410_TCON);
}

static void PWM_Stop(void)
{
    s3c2410_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPIO_OUTPUT);
    s3c2410_gpio_setpin(S3C2410_GPB(0), 0);
}

static int s3c24xx_pwm_open(struct inode *inode, struct file *file)
{
    if (!down_trylock(&lock))
    {
        return 0;
    }
    else
        return -EBUSY;
}

static int s3c24xx_pwm_close(struct inode *inode, struct file *file)
{
    PWM_Stop();
    up(&lock);
    return 0;
}
//cmd =1,open pwm function. =  0, close pwm function
//pwm frquency = (arg & 0xff00)>>8,
//pwm duty = (arm & 0x00ff)
//
static int s3c24xx_pwm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
    printk("ioctl pwm: %d %ld\n", cmd, arg);
    switch (cmd) {
    case PWM_IOCTL_SET_FREQ:
        if (arg == 0)
            return -EINVAL;
        PWM_Set_Freq_Duty((arg>>8),(arg&0xff));
        break;

case PWM_IOCTL_STOP:
        PWM_Stop();
        break;
    }

return 0;
}

static struct file_operations dev_fops = {
    .owner   =   THIS_MODULE,
    .open    =   s3c24xx_pwm_open,
    .release =   s3c24xx_pwm_close,
    .ioctl   =   s3c24xx_pwm_ioctl,
};

static struct miscdevice misc = {
    .minor = MISC_DYNAMIC_MINOR,
    .name = DEVICE_NAME,
    .fops = &dev_fops,
};

static int __init dev_init(void)
{
    int ret;

init_MUTEX(&lock);//init semaphore
    ret = misc_register(&misc);

printk (DEVICE_NAME"\tinitialized\n");

return ret;
}

static void __exit dev_exit(void)
{
    misc_deregister(&misc);
}

module_init(dev_init);
module_exit(dev_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("FriendlyARM Inc.");
MODULE_DESCRIPTION("S3C2410/S3C2440 PWM Driver");

下面是用于测试驱动的代码:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>

int main(int argc, char **argv)
{
    int on = 1;
        unsigned long frq_duty = 0;;
    int fd;

fprintf(stderr, "PWM APP starting...\n");

fd = open("/dev/pwm", 0);
    if (fd < 0) {
        fprintf(stderr, "error:open device pwm failed\n    ");
        exit(1);
    }
    else {
        fprintf(stderr, "PWM devie open success\n");
    }
        frq_duty = ((200<<8)|80);
    ioctl(fd, on, frq_duty);
        while(1);
    close(fd);
    return 0;
}

Mni2440 linux PWM 驱动代码修改支持 频率,占空比修改--XiaoLin.Peng相关推荐

  1. linux网卡驱动对XDP支持情况

    各个网卡厂商对应的Linux内核驱动如下 Mellanox: mlx4 (4.8) and mlx5 (4.9) QLogic/Cavium: qede (4.10) Virtio_net: (4.1 ...

  2. linux PWM驱动屏幕亮度及pwm子系统框架(Linux驱动开发篇)

    1.对象 imx6ull单片机,控制其下面的pwm3的外设.关于对象的详细介绍看裸机pwm控制屏幕亮度 在dtsi中的位置 /soc/aips1/pwm3 pwm3: pwm@02088000 { c ...

  3. linux 按键驱动代码分析

    原文地址:http://blog.csdn.NET/woshidahuaidan2011/article/details/51695147 二.按键驱动 1.对按键驱动添加设备信息 linux-3.1 ...

  4. Linux PWM驱动框架 (二)

    Linux内核提供看PWM的驱动框架,让驱动开发人员可以更好地进行PWM驱动的编写. 1.PWM结构体 struct pwm_chip {struct device *dev;struct list_ ...

  5. 友善之臂 mini2440 linux led 驱动代码,[转]mini2440的LEDS驱动程序和测试程序详解

    转自:http://blog.csdn.net/garby2004/article/details/4603996 一 leds的驱动程序 位置:linux 2.6.29/drivers/char/m ...

  6. 友善之臂 mini2440 linux led 驱动代码,友善之臂mini2440的LEDdriver驱动分析及测试程序...

    一,前言:因为友善尚未公布mini2440开发板上的测试程序,所以我自己就写了一个.还好不是太难. (WINCE6.0+mini2440) 二,首先来分析一下LEDDriver. 2.1,入口函数:( ...

  7. linux SPI驱动代码追踪

    一.Linux SPI 框架概述 linux系统下的spi驱动程序从逻辑上可以分为3个部分: SPI Core:SPI Core 是 Linux 内核用来维护和管理 spi 的核心部分,SPI Cor ...

  8. 友善之臂 mini2440 linux led 驱动代码,mini2440 led驱动程序

    这个led驱动程序只在linux-2.6.32.2内核中测试通过,至于其他的内核可能头文件有一些改动就不能 编译成功了.下面给出源程序: 这是友善之臂提供的源码: #include #include ...

  9. linux查看蓝牙驱动版本号,linux蓝牙驱动代码阅读笔记

    昨天看了一下介绍蓝牙协议文档,今天索性对照看了看kernel里的代码(bluez),这里记点笔记,还是继承了老毛病,只关注整体流程而忽略细节,先了解个大概,等真正需要时再仔细分析. net/hci_c ...

最新文章

  1. 有雄心的男人才有出息
  2. (一)MVC5干货篇,目录和路由
  3. Linux下的命令总结笔记(二)
  4. 34、Power Query-中国式排名
  5. 玩转GIT系列之【如何配置GIT的用户名/密码/密钥】
  6. Centos7安装图形桌面
  7. 安凯无人驾驶_完美运行零失误 安凯无人驾驶巴士挑战“世界第一玻璃桥”
  8. 编码的奥秘txt_编码的奥秘(Charles Petzold著) PDF扫描版[9MB]
  9. 解压文件时,系统找不到指定路径
  10. 【游戏建模】将Ciri转为守望先锋的角色
  11. vibe算法的另外一种实现
  12. CruiseControl.Net学习记录
  13. final修饰的变量就是常量?
  14. php中row是什么意思,row是什么意思
  15. RF SeleniumLibrary 关键字分类解读
  16. iQOO Z6和iQOOZ6x的区别 选哪个好
  17. 异常Required request body is missing。
  18. 利用JavaAPI访问HDFS的文件
  19. すぬけ君の塗り絵 2 イージー / Snuke's Coloring 2 (ABC Edit) AtCoder - 2145
  20. 如何给PDF文件设置和取消打开密码

热门文章

  1. Jenkins从svn获取代码报”E170001“异常问题解决
  2. 数据库设计-学生管理系统数据库系统
  3. ips细胞最新发现:科学家开发出了一套评估干细胞的全能性的新标准
  4. PhotoShop实现文字人物海报效果
  5. linux 触摸屏驱动介绍
  6. FreeCAD-0.19源码编译教程
  7. 正点原子STM32-串口中断服务函数USART1_IRQHandler关于USART_RX_STA的学习笔记
  8. 甲骨文业绩超预期股价大涨近11% 市值首超2000亿美元
  9. cad打印去掉边框_CAD如何去掉图纸空白边框真正按1:1打印出图
  10. 数字经济时代,数据中心供电系统如何助力实现双碳目标