查看: 1820|回复: 0

linux下如何修改gpio驱动

[复制链接]
  • TA的每日心情

    2014-4-10 13:56
  • 签到天数: 5 天

    连续签到: 1 天

    [LV.2]偶尔看看I

    发表于 2014-1-15 09:56:39 | 显示全部楼层 |阅读模式
    分享到:
    今天我们大家讨论下关于GPIO驱动的一些东西,首先我们来看下针对飞凌嵌入式OK210开发板LED驱动的源码,这也是一个比较简单的gpio驱动程序。
    #include <linux/kernel.h>
    #include <linux/module.h>
    #include <linux/miscdevice.h>
    #include <linux/fs.h>
    #include <linux/types.h>
    #include <linux/moduleparam.h>
    #include <linux/slab.h>
    #include <linux/ioctl.h>
    #include <linux/cdev.h>
    #include <linux/delay.h>
    #include <mach/gpio.h>
    #include <mach/regs-gpio.h>
    #include <plat/gpio-cfg.h>
    #define DEVICE_NAME "leds"
    static int led_gpios[] = {
    #ifdef CONFIG_OK210_BOARD_V2
            S5PV210_MP04(4),  //在gpio-herring.h中对gpio寄存器有定义;
            S5PV210_MP04(5),
            S5PV210_MP04(6),
            S5PV210_MP04(7),
    #else
            S5PV210_GPH2(0),
            S5PV210_GPH2(1),
            S5PV210_GPH2(2),
            S5PV210_GPH2(3),
    #endif
    };
    上面这段代码主要是根据配置文件的不同调用不同寄存器来实现不同的功能;
    #define LED_NUM                ARRAY_SIZE(led_gpios)
    static long fl210_leds_ioctl(struct file *filp, unsigned int cmd,
                    unsigned long arg)
    {
            switch(cmd) {
                    case 0:
                    case 1:
                            if (arg > LED_NUM) {
                                    return -EINVAL;
                            }
                            gpio_set_value(led_gpios[arg], !cmd); //对指定的GPIO寄存器写上一个值
                            printk(DEVICE_NAME": %ld %d\n", arg, cmd);
                            break;
                    default:
                            return -EINVAL;
            }
            return 0;
    }
    static struct file_operations fl210_led_dev_fops = {
            .owner                        = THIS_MODULE,
            .unlocked_ioctl        = fl210_leds_ioctl,
    };
    static struct miscdevice fl210_led_dev = {
            .minor                        = MISC_DYNAMIC_MINOR,
            .name                        = DEVICE_NAME,
            .fops                        = &fl210_led_dev_fops,
    };
    static int __init fl210_led_dev_init(void) {
            int ret;
            int i;
            for (i = 0; i < LED_NUM; i++) {
                    ret = gpio_request(led_gpios, "LED");
                    if (ret) {
                            printk("%s: request GPIO %d for LED failed, ret = %d\n", DEVICE_NAME,
                                            led_gpios, ret);
                            return ret;
                    }
                    s3c_gpio_cfgpin(led_gpios, S3C_GPIO_OUTPUT);  //设置数组中的 这个gpio为输出模式
                    gpio_set_value(led_gpios, 1);
            }
            ret = misc_register(&fl210_led_dev);// 注册杂项设备
            printk(DEVICE_NAME"\tinitialized\n");
            return ret;
    }
    这里我们看下 gpio_request(unsigned gpio, const char *label) 这个函数的参数,gpio则为你要申请的哪一个管脚,label则是为其取一个名字。
    static void __exit fl210_led_dev_exit(void) {
            int i;
            for (i = 0; i < LED_NUM; i++) {
                    gpio_free(led_gpios);  //释放io
            }
            misc_deregister(&fl210_led_dev); //释放杂项设备
    }
    module_init(fl210_led_dev_init);
    module_exit(fl210_led_dev_exit);
    MODULE_LICENSE("GPL");
    MODULE_AUTHOR("Forlinx Inc.");
    我们通过对这段代码的分析可以看出对GPIO的操作主要用到了gpio_set_value (),gpio_request(),s3c_gpio_cfgpin(),这三个函数和led_gpios[]数组,我们可以通过对这个数组里面的成员的修改来实现对其他管脚控制,同时运行上面三个函数可以实现对gpio的赋值控制

    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /4 下一条



    手机版|小黑屋|与非网

    GMT+8, 2024-12-12 10:54 , Processed in 0.116415 second(s), 15 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.