这是4412的GPD0_1路,itop中被使用为LCD的背光电路的pwm功能。因此如果使用教程中的代码,同样操作GPD0_1是行不通的。

会出现错误,所以需要解除在内核中的占用

修改arch/arm/mach-exynos/mach-itop4412.c,找到并注释

    samsung_bl_set(&smdk4x12_bl_gpio_info, &smdk4x12_bl_data);

在内核中取消相关的模块编译,(不确定)

Device Driver>>Graphics support>>Backlight & LCD device support(取消)

 

然后在平台文件中增加注册设备:

    &s3c_device_timer[1],

然后是测试代码:

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/fb.h>
#include <linux/backlight.h>
#include <linux/err.h>
#include <linux/pwm.h>
#include <linux/slab.h>
#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <linux/gpio.h>
#include <mach/gpio.h>
#include <plat/gpio-cfg.h>
#include <linux/ioctl.h>
#include <asm-generic/uaccess.h>

#define DEVICE_NAME "my_pwm3_dev"
#define DRIVER_NAME "my_pwm3_drv"

#define PWM_MAGIC 'p'
#define PWM_MAX_NR 3

#define PWM_IOCTL_STOP      _IO(PWM_MAGIC, 0)
#define PWM_IOCTL_SET_FREQ  _IO(PWM_MAGIC, 1)
#define PWM_IOCTL_SET_DUTY  _IO(PWM_MAGIC, 2)

#define NS_IN_1HZ                               (1000000000UL)

#define BUZZER_PWM_ID                   0
#define PWM1_ID                                 1
#define PWM2_ID                 2
#define PWM3_ID                 3


#define BUZZER_PMW_GPIO EXYNOS4_GPD0(0)
#define PWM1_GPIO               EXYNOS4_GPD0(1)
#define PWM2_GPIO       EXYNOS4_GPD0(2)
#define PWM3_GPIO       EXYNOS4_GPD0(3)

static struct pwm_device *pwm4buzzer;
static struct semaphore lock;
static int period_ns = 1000;
static unsigned long freq = 50;
static unsigned long duty = 2;

static void pwm_set_freq(void)
{
    //配置周期
    period_ns = NS_IN_1HZ / freq;
    //配置占空比
        if(duty < 1)
                duty = 1;
    pwm_disable(pwm4buzzer);
    pwm_config(pwm4buzzer, period_ns / duty, period_ns);
    pwm_enable(pwm4buzzer);
    //配置相应的GPIO,蜂鸣器IO配置成PWM输出模式
    s3c_gpio_cfgpin(PWM3_GPIO, S3C_GPIO_SFN(2));
}

static void pwm_stop(void)
{
    s3c_gpio_cfgpin(PWM3_GPIO, S3C_GPIO_OUTPUT);

    pwm_config(pwm4buzzer, 0, NS_IN_1HZ / 100);
    pwm_disable(pwm4buzzer);
}

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

static int ops_pwm_close(struct inode *inode, struct file *file)
{
    up(&lock);
    return 0;
}

static long ops_pwm_ioctl(struct file *filep, unsigned int cmd,
                unsigned long arg)
{
    if(_IOC_TYPE(cmd)!=PWM_MAGIC) return -EINVAL;
    if(_IOC_NR(cmd) > PWM_MAX_NR) return -EINVAL;

    switch(cmd) {
    case PWM_IOCTL_SET_FREQ:
        if(arg == 0)
            return -EINVAL;
        get_user(freq, (unsigned long __user *)arg);
        printk(KERN_EMERG "freq is %ld\n", freq);
        pwm_set_freq();
        break;
    case PWM_IOCTL_STOP:
        pwm_stop();
                break;
        case PWM_IOCTL_SET_DUTY:
        get_user(duty, (unsigned long __user *)arg);
        printk(KERN_EMERG "duty is %ld\n", duty);
        pwm_set_freq();
                break;
    default:
        pwm_stop();
        break;
    }
    return 0;
}

static struct file_operations pwm_ops = {
    .owner = THIS_MODULE,
    .open  = ops_pwm_open,
    .release = ops_pwm_close,
    .unlocked_ioctl = ops_pwm_ioctl,
};

static struct miscdevice pwm_misc_dev = {
    .minor = MISC_DYNAMIC_MINOR,
    .name  = DEVICE_NAME,
    .fops  = &pwm_ops,
};

static int __init iTop4412_pwm_dev_init(void)
{
    int ret;
    gpio_free(PWM3_GPIO);

    ret = gpio_request(PWM3_GPIO, DEVICE_NAME);
    if(ret) {
                printk(KERN_EMERG "request GPIO %d for pwm failed\n", PWM3_GPIO);
                return ret;
    }

        gpio_set_value(PWM3_GPIO, 0);
        s3c_gpio_cfgpin(PWM3_GPIO, S3C_GPIO_OUTPUT);

        pwm4buzzer = pwm_request(PWM3_ID, DEVICE_NAME);
        if (IS_ERR(pwm4buzzer)) {
                printk(KERN_EMERG "request pwm %d for %s failed\n", PWM3_ID, DEVICE_NAME);
                return -ENODEV;
        }
    pwm_stop();

    sema_init(&lock, 1);
    ret = misc_register(&pwm_misc_dev);
        if(ret < 0) {
                gpio_free(BUZZER_PMW_GPIO);
                pwm_free(pwm4buzzer);
                misc_deregister(&pwm_misc_dev);
        }

    printk(KERN_EMERG "\tinitialized\n");

    return ret;
}

static void __exit iTop4412_pwm_dev_exit(void)
{
    gpio_free(BUZZER_PMW_GPIO);
        pwm_free(pwm4buzzer);
    misc_deregister(&pwm_misc_dev);

    printk(KERN_EMERG "\texit\n");
    return;
}

module_init(iTop4412_pwm_dev_init);
module_exit(iTop4412_pwm_dev_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Chen Tuo");
MODULE_DESCRIPTION("Exynos4 PWM Driver");
my_pwm3.c

相关文章:

  • 2021-10-06
  • 2021-12-14
  • 2021-09-22
  • 2021-07-23
  • 2021-10-14
  • 2021-09-02
猜你喜欢
  • 2021-12-04
  • 2022-12-23
  • 2021-08-28
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案