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");

 

目录
相关文章
|
Java
Java“解析时到达文件末尾”解决
在Java编程中,“解析时到达文件末尾”通常指在读取或处理文件时提前遇到了文件结尾,导致程序无法继续读取所需数据。解决方法包括:确保文件路径正确,检查文件是否完整,使用正确的文件读取模式(如文本或二进制),以及确保读取位置正确。合理设置缓冲区大小和循环条件也能避免此类问题。
1217 2
|
12月前
|
Dart 索引
鸿蒙应用开发从入门到入行 - 篇8:Tabs选项卡页签视图切换
在本篇文章里,您将掌握使用Tabs选项卡做栏目分类,这是未来应用开发中极为常用的组件
485 7
鸿蒙应用开发从入门到入行 - 篇8:Tabs选项卡页签视图切换
|
12月前
|
存储 API
鸿蒙元服务项目实战:终结篇之备忘录搜索功能实现
开发元服务,有很多的限制性因素,比如包的大小限制,相关API限制,所以,我们在实际开发的时候,具体Api能否使用,还需要去官网查看一下,目前,针对当前这个小项目,总结了几个小问题,大家在开发的过程中可以作为参考。
236 2
鸿蒙元服务项目实战:终结篇之备忘录搜索功能实现
|
存储 分布式计算 负载均衡
|
网络架构
小区搜索过程
小区搜索是终端通过同步信号块SSB与小区建立联系的过程,包括取得小区下行频率、时间同步、检测小区识别号CellID、通过解码广播信道BCH上的系统信息。下行同步包括频率、符号和帧同步。
459 0
小区搜索过程
|
数据采集 搜索推荐 前端开发
VuePress 博客优化之开启 Algolia 全文搜索
由于 VuePress 的内置搜索只会为页面的标题、h2 、 h3 以及 tags 构建搜索索引。 如果你需要全文搜索,可则以使用 Algolia 搜索,本篇讲讲如何申请以及配置 Algolia 搜索。
954 0
VuePress 博客优化之开启 Algolia 全文搜索
|
存储 安全 Java
Dremio: 将 Minio 配置为分布式存储
Dremio: 将 Minio 配置为分布式存储
Dremio: 将 Minio 配置为分布式存储
|
消息中间件 Java 开发工具
DataHub Flink Connector
我们在阿里云上使用DataHub作为Flink程序输入输出的消息队列,使用成本比较低,但由于是阿里云的云产品,周边生态做的不是很好,Flink Stream的Connector并没有开源出来。因此本人参照RocketMQ Flink Connector写了DataHub的Flink Connector。
1993 3
|
弹性计算 安全 网络安全
云桌面远程办公
员工通过公网直接登录到云桌面实例(有公网访问权限)进行远程办公,云桌面客户端具有一定加密和安全传输能力。
云桌面远程办公