您的位置:首页 > 运维架构 > Linux

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

2013-11-13 22:38 375 查看
以下是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");
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: