• I.MX6 driver goto 使用


    /**************************************************************************
     *                     I.MX6 driver goto 使用
     * 说明:
     *     在绝大多数地方,我们都被告诉尽可能不要用goto,甚至都没学过goto,但
     * 这种语法却在内核驱动中普遍使用。
     *
     *                                        2016-4-13 深圳 南山平山村 曾剑锋
     *************************************************************************/
    
    
    #include <linux/module.h>
    #include <linux/fs.h>
    #include <linux/gpio.h>
    #include <linux/miscdevice.h>
    #include <linux/delay.h>
    
    #define SABRESD_VO_PIN            IMX_GPIO_NR(1, 4)
    #define SABRESD_AMPE_PIN          IMX_GPIO_NR(1, 5)
    #define SABRESD_SD_PIN            IMX_GPIO_NR(1, 19)
    #define SABRESD_DT_PIN            IMX_GPIO_NR(3, 20)
    
    #define SPK_HEIGHT              66
    #define SPK_LOW                 67
    #define AMP_HEIGHT              68
    #define AMP_LOW                 69
    #define SD_HEIGHT               70
    #define SD_LOW                  71
    #define DETECT                  72
    
    #define GPIO_CTRL_DEBUG
    #ifdef GPIO_CTRL_DEBUG
        #define mDebug(format, ...) printk("File:%s, Function:%s, Line:%d  "format, __FILE__, __FUNCTION__, __LINE__, ##__VA_ARGS__);
    #else
        #define mDebug(format, ...)
    #endif
    
    static int gpioCtrl_open(struct inode *inode, struct file *file)
    {
        mDebug("Dev open.
    ");
    
        return 0;
    }
    
    static int gpioCtrl_close(struct inode *inode, struct file *file)
    {
        mDebug("Dev close.
    ");
    
        return 0;
    }
    
    static ssize_t gpioCtrl_read(struct file *file,
                            char __user *buf,
                            size_t count,
                            loff_t *pos)
    {
        mDebug("Read data.
    ");
    
        return 0;
    }
    
    static long gpioCtrl_ioctl(struct file * file, unsigned int cmd, unsigned long arg) {
    
        int ret = 0;
    
        switch ( cmd ) {
        case SPK_HEIGHT :
            gpio_set_value(SABRESD_VO_PIN, 1);
            mDebug("SPK_HEIGHT.
    ");
            break;
        case SPK_LOW :
            gpio_set_value(SABRESD_VO_PIN, 0);
            mDebug("SPK_LOW.
    ");
            break;
        case AMP_HEIGHT :
            gpio_set_value(SABRESD_AMPE_PIN, 1);
            mDebug("AMP_HEIGHT.
    ");
            break;
        case AMP_LOW :
            gpio_set_value(SABRESD_AMPE_PIN, 0);
            mDebug("AMP_LOW.
    ");
            break;
        case SD_HEIGHT :
            gpio_set_value(SABRESD_SD_PIN, 1);
            mDebug("SD_HEIGHT.
    ");
            break;
        case SD_LOW :
            gpio_set_value(SABRESD_SD_PIN, 0);
            mDebug("SD_LOW.
    ");
            break;
        case DETECT :
            ret = gpio_get_value(SABRESD_DT_PIN);
            (*(int *)arg) = ret;
            mDebug("DETECT ret = %d.
    ", ret);
    
            ret = 0;
            break;
        default :
            mDebug("gpioCtrl control error.
    ");
            ret =  -1;
            break;
        }
        return ret;
    }
    
    
    struct file_operations fops = {
        .owner      = THIS_MODULE,
        .open       = gpioCtrl_open,
        .release    = gpioCtrl_close,
        .read       = gpioCtrl_read,
        .unlocked_ioctl = gpioCtrl_ioctl,
    };
    
    struct miscdevice misc = {
        .minor  = MISC_DYNAMIC_MINOR,
        .name   = "gpioCtrl",
        .fops   = &fops,
    };
    
    int __init gpioCtrl_init(void)
    {
        int ret;
    
        ret = gpio_request(SABRESD_VO_PIN, "SABRESD_VO_PIN");
        if ( ret ) {
            mDebug("get SABRESD_VO_PIN gpio FAILED!
    ");
            return ret;
        }
    
        ret = gpio_request(SABRESD_AMPE_PIN, "SABRESD_AMPE_PIN");
        if ( ret ) {
            mDebug("get SABRESD_AMPE_PIN gpio FAILED!
    ");
            goto fail1;
        }
    
        ret = gpio_request(SABRESD_SD_PIN, "SABRESD_SD_PIN");
        if ( ret ) {
            mDebug("get SABRESD_SD_PIN gpio FAILED!
    ");
            goto fail2;
        }
    
        ret = gpio_request(SABRESD_DT_PIN, "SABRESD_DT_PIN");
        if ( ret ) {
            mDebug("get SABRESD_DETECT gpio FAILED!
    ");
            goto fail3;
        }
    
        gpio_direction_output(SABRESD_VO_PIN, 0);
        gpio_direction_output(SABRESD_AMPE_PIN, 1);
        gpio_direction_output(SABRESD_SD_PIN, 1);
        gpio_direction_input(SABRESD_DT_PIN);
    
        ret = misc_register(&misc);
        if(ret) {
            mDebug("gpioCtrl_misc_register FAILED!
    ");
            goto fail4;
        }
    
        mDebug("gpioCtrl_misc_register over!
    ");
        return ret;
    
    fail4:
        gpio_free(SABRESD_DT_PIN);
    fail3:
        gpio_free(SABRESD_SD_PIN);
    fail2:
        gpio_free(SABRESD_AMPE_PIN);
    fail1:
        gpio_free(SABRESD_VO_PIN);
        
        return ret;
    }
    
    void __exit gpioCtrl_exit(void)
    {
        gpio_set_value(SABRESD_VO_PIN, 0);
        gpio_set_value(SABRESD_AMPE_PIN, 0);
        gpio_set_value(SABRESD_SD_PIN, 0);
    
        gpio_free(SABRESD_VO_PIN);
        gpio_free(SABRESD_AMPE_PIN);
        gpio_free(SABRESD_SD_PIN);
        gpio_free(SABRESD_DT_PIN);
    
        misc_deregister(&misc);
    }
    
    module_init(gpioCtrl_init);
    module_exit(gpioCtrl_exit);
    
    MODULE_LICENSE("GPL");
  • 相关阅读:
    一款基于jQuery制作的焦点图片局部场景图片切换的特效
    一款基于jQuery打造的滤镜百叶窗幻灯片特效
    css3实现多种颜色的底部阴影按钮特效
    一款简单的css3打造的一面五星红旗特效
    一款jQuery打造的具有多功能切换的幻灯片特效
    一款jquery打造的特炫酷的全屏上下滚动的jquery焦点图特效
    一款基于jquery打造的全屏切换的焦点图切换特效
    一款运用纯CSS编写的android图标
    datagrid删除确认对话框
    好站好文滙集
  • 原文地址:https://www.cnblogs.com/zengjfgit/p/5386849.html
Copyright © 2020-2023  润新知