I.MX6 driver goto 使用

简介: /************************************************************************** * I.MX6 driver goto 使用 * 说明: * 在绝大多数地方,我们都被告诉尽可能不要用goto,甚至都没学过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.\n");

    return 0;
}

static int gpioCtrl_close(struct inode *inode, struct file *file)
{
    mDebug("Dev close.\n");

    return 0;
}

static ssize_t gpioCtrl_read(struct file *file,
                        char __user *buf,
                        size_t count,
                        loff_t *pos)
{
    mDebug("Read data.\n");

    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.\n");
        break;
    case SPK_LOW :
        gpio_set_value(SABRESD_VO_PIN, 0);
        mDebug("SPK_LOW.\n");
        break;
    case AMP_HEIGHT :
        gpio_set_value(SABRESD_AMPE_PIN, 1);
        mDebug("AMP_HEIGHT.\n");
        break;
    case AMP_LOW :
        gpio_set_value(SABRESD_AMPE_PIN, 0);
        mDebug("AMP_LOW.\n");
        break;
    case SD_HEIGHT :
        gpio_set_value(SABRESD_SD_PIN, 1);
        mDebug("SD_HEIGHT.\n");
        break;
    case SD_LOW :
        gpio_set_value(SABRESD_SD_PIN, 0);
        mDebug("SD_LOW.\n");
        break;
    case DETECT :
        ret = gpio_get_value(SABRESD_DT_PIN);
        (*(int *)arg) = ret;
        mDebug("DETECT ret = %d.\n", ret);

        ret = 0;
        break;
    default :
        mDebug("gpioCtrl control error.\n");
        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!\n");
        return ret;
    }

    ret = gpio_request(SABRESD_AMPE_PIN, "SABRESD_AMPE_PIN");
    if ( ret ) {
        mDebug("get SABRESD_AMPE_PIN gpio FAILED!\n");
        goto fail1;
    }

    ret = gpio_request(SABRESD_SD_PIN, "SABRESD_SD_PIN");
    if ( ret ) {
        mDebug("get SABRESD_SD_PIN gpio FAILED!\n");
        goto fail2;
    }

    ret = gpio_request(SABRESD_DT_PIN, "SABRESD_DT_PIN");
    if ( ret ) {
        mDebug("get SABRESD_DETECT gpio FAILED!\n");
        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!\n");
        goto fail4;
    }

    mDebug("gpioCtrl_misc_register over!\n");
    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");

 

目录
相关文章
打印文档即提示Print driver host for 32bit applications
主机win7 32位系统,打印一切正常,共享打印机后,客户机为win7 64位系统连接该共享打印机,连接成功,驱动安装正常,x64驱动,客户机打印测试页正常,但打印文档即提示Print driver host for 32bit applications。
7634 0
打印文档即提示Print driver host for 32bit applications
|
7月前
|
Android开发
Android JNI 报错(signal 6 (SIGABRT), code -1 (SI_QUEUE), fault addr )
Android JNI 报错(signal 6 (SIGABRT), code -1 (SI_QUEUE), fault addr )
1047 1
|
7月前
|
安全
qt.qpa.xcb: could not connect to display 问题解决
【5月更文挑战第16天】qt.qpa.xcb: could not connect to display qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in "" even though it was found. This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem. 问题解决
3532 1
|
Linux 开发工具 Android开发
[√]leak tracer的stack address始终无法被addr2line识别
[√]leak tracer的stack address始终无法被addr2line识别
148 0
成功解决absl.flags._exceptions.UnrecognizedFlagError: Unknown command line flag 'data_format'
成功解决absl.flags._exceptions.UnrecognizedFlagError: Unknown command line flag 'data_format'
relocation R_X86_64_PC32 against symbol ff_pw_9 can not be used when making a shared object
relocation R_X86_64_PC32 against symbol ff_pw_9 can not be used when making a shared object
292 0
|
Swift iOS开发
Xcode10 NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_END
前言 升级成 Xcode 10 之后每次 New File 看到 .h 基本都能看到 NS_ASSUME_NONNULL_BEGIN 和 NS_ASSUME_NONNULL_END 成对出现在 @interface 与 @end 上下, 包裹住它, 这两对关键字并非新特性, 只是 Xcode 10 之后系统默认实现了, 应该是考虑到与 Swift 混编, 为了更好兼容其 optional 与 non-optional。
1848 0
Unable to handle kernel NULL pointer dereference at virtual address 00000000问题的解决
今天在编译好内核模块后,安装内核模块memdev.ko的时候,出现了Unable to handle kernel NULL pointer dereference at virtual address 00000000等如图所示的问题:     在百度和google找了很多答案,明显就是跟指针有关系。
3216 0
|
C语言 Windows 编译器
完美解决Unknown Pin 和Failed to add class member
相信很多人在使用DXP和AD的时候,都遇到过Unknown Pin 和Failed to add class member 的问题,我也遇到了,经过实验发现新建个PCB就可以解决这些问题,网上的常见做法也是这样的。但是很多时候新建PCB就要放弃前面已经布局布线了一半的样本,实在是费时又劳神。所以我在想既然是报错,肯定有办法解决,于是就研究了下发现了如下解决办法。希望对大家能有帮助。
2837 0