Linux Driver之总线设备驱动bus-dev-drv模型

来源:互联网 发布:sql高阶 编辑:程序博客网 时间:2024/05/16 10:30

以下是led_platform_dev文件内容:

#include <linux/module.h>

#include <linux/init.h>
#include <linux/kernel.h>

#include <linux/platform_device.h>

static struct resource res[] =
{
    [0] =
    {
        .start = 5,
        .end   = 8,
        .name  = "nled",
        .flags = IORESOURCE_IRQ,
    },
};

static void led_release(struct device *dev)
{
    return;
}

static struct platform_device led_dev =
{
    .name = "myled",
    .id   = 0,
    .num_resources = ARRAY_SIZE(res),
    .resource = res,
    .dev =
    {
        .release = led_release,
    },
};

static int __init led_dev_init(void)
{
    return platform_device_register(&led_dev);
}

static void __exit led_dev_exit(void)
{
    return platform_device_unregister(&led_dev);
}

module_init(led_dev_init);
module_exit(led_dev_exit);

MODULE_LICENSE("GPL");

以下是led_platform_drv文件内容:

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/fs.h>
#include <asm/gpio.h>
#include <plat/gpio-cfg.h>
#include <linux/uaccess.h>
#include <mach/regs-gpio.h>

static unsigned int major;
static struct class * led_cls;
static struct device * led_dev;
static unsigned int pin_start;
static unsigned int pin_end;

static int led_open(struct inode *inode, struct file * file)
{
    int i;
    for(i = pin_start;i <= pin_end;++i)
    {
        s3c_gpio_cfgpin(S3C2410_GPB(i), S3C2410_GPIO_OUTPUT);//配置GPIO引脚为输出功能
    }
    return 0;
}

static ssize_t led_write(struct file *file, const char __user *buf, size_t size, loff_t *off)
{
    int i;
    unsigned char nled = -1;
    if(size != 1)
        return -EINVAL;
    copy_from_user(&nled, buf, size);
    printk("nled = %d\n", nled);
    if(nled == 0)
    {
        for(i = pin_start;i <= pin_end;++i) 
        {
            gpio_set_value(S3C2410_GPB(i), 1); /* 关闭led灯 */
        }
    }
    else
    {
        gpio_set_value(S3C2410_GPB(nled + 4), 0); /* 开启led灯 */
    }
    return 0;
}

static struct file_operations f_ops =
{
    .owner = THIS_MODULE,
    .open  = led_open,
    .write = led_write,
};

static int led_probe(struct platform_device *pdev)
{
    struct resource *res;
    res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
    if(res == NULL)
        return -EINVAL;
    major = register_chrdev(0, "led", &f_ops);
    led_cls = class_create(THIS_MODULE, "led");
    led_dev = device_create(led_cls, NULL, MKDEV(major, 0), NULL, "myled");
    pin_start = res->start; /* TQ2440 GPB5~8 -- LED1~4 */
    pin_end = res->end;     /* pin_start=5 pin_end=8 */
    return 0;
}

static int led_remove(struct platform_device *pdev)
{
    device_destroy(led_cls, MKDEV(major, 0));
    class_destroy(led_cls);
    unregister_chrdev(major, "led");
    return 0;
}

static struct platform_driver led_drv =
{
    .probe = led_probe,
    .remove = led_remove,
    .driver = {
        .name = "myled",
        .owner = THIS_MODULE,
    },
};

static int __init led_drv_init(void)
{
    return platform_driver_register(&led_drv);
}

static void __exit led_drv_exit(void)
{
    return platform_driver_unregister(&led_drv);
}

module_init(led_drv_init);
module_exit(led_drv_exit);

MODULE_LICENSE("GPL");



原创粉丝点击