简体   繁体   English

如何在Linux中写入CM108芯片的GPIO引脚?

[英]Howto Write to the GPIO Pin of the CM108 Chip in Linux?

The CM108 from C-Media has 4 GPIO pin that you can access via a hid interface. C-Media的CM108具有4个GPIO引脚,您可以通过hid接口访问该引脚。

Using the generic write function in Windows I was able to write to the gpio pins. 使用Windows中的通用写入功能,我能够写入gpio引脚。

However I'm trying to do the same thing in Linux without success. 但是我试图在Linux中做同样的事情而没有成功。

The linux kernel detect the device as a hidraw device. linux内核将设备检测为Hidraw设备。

Note: I was able to read from the device, just not write. 注意:我能够从设备读取,但不能写入。 (I've run the app as root just to make sure it wasn't a permission issue). (我已以root用户身份运行该应用程序,只是为了确保它不是权限问题)。

I got this working, here's how. 我得到了这个工作,这是怎么做的。

I needed to create a new linux hid kernel mod. 我需要创建一个新的Linux隐藏内核mod。 (it wasn't that hard)/* (并不难)/ *

/*
 * Driver for the C-Media 108 chips
 *
 * Copyright (C) 2009 Steve Beaulac <steve@sagacity.ca>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation, version 2.
 */

/*
 * This driver is based on the cm109.c driver
 */

#include <linux/device.h>
#include <linux/hid.h>
#include <linux/module.h>

#define DRIVER_VERSION "20090526"
#define DRIVER_AUTHOR "Steve Beaulac"
#define DRIVER_DESC "C-Media 108 chip"

#define CM108_VENDOR_ID 0x0d8c
#define CM108_PRODUCT_ID 0x000c

#ifdef CONFIG_USB_DYNAMIC_MINORS
#define CM108_MINOR_BASE 0
#else
#define CM108_MINOR_BASE 96
#endif

/*
 * Linux interface and usb initialisation
 */

static int cm108_hid_probe(struct hid_device *hdev, const struct hid_device_id *id)
{
    int ret;

    ret = hid_parse(hdev);
    if (ret) {
        dev_err(&hdev->dev, "parse failed\n");
        goto error;
    }

    ret = hid_hw_start(hdev, HID_CONNECT_HIDRAW);
    if (ret) {
        dev_err(&hdev->dev, "hw start failed\n");
        goto error;
    }
    return 0;

error:
    return ret;
}

static struct hid_device_id cm108_device_table[] = {
    { HID_USB_DEVICE (CM108_VENDOR_ID, CM108_PRODUCT_ID) },
    /* you can add more devices here with product ID 0x0008 - 0x000f */
    { }
};
MODULE_DEVICE_TABLE (hid, cm108_device_table);

static struct hid_driver hid_cm108_driver = {
    .name = "cm108",
    .id_table = cm108_device_table, 
    .probe = cm108_hid_probe,
};

static int hid_cm108_init(void)
{
    return hid_register_driver(&hid_cm108_driver);
}

static void hid_cm108_exit(void)
{
    hid_unregister_driver(&hid_cm108_driver);   
}

module_init(hid_cm108_init);
module_exit(hid_cm108_exit);

MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");

used This makefile 用过的这个makefile

obj-m += cm108.o

and compile the module 并编译模块

make -C /lib/modules/`uname -r`/build/ M=`pwd` EXTRAVERSION="-generic" modules

sudo make -C /lib/modules/`uname -r`/build/ M=`pwd` EXTRAVERSION="-generic" modules_install

depmod -a

I had to modify the modules.order file so that my module would get queried before the generic hid linux module. 我必须修改modules.order文件,以便在通用hid linux模块之前可以查询我的模块。

This modules make sure that the hidraw uses Interface 2. 该模块确保hidraw使用接口2。

Then I can use fopen to read and write to the GPIO pin of the CM108 chip. 然后,我可以使用fopen读取和写入CM108芯片的GPIO引脚。

BTW: when writing you need to write 5byte the 1st byte is used for the HID_OUTPUT_REPORT 顺便说一句:写入时需要写入5个字节,第一个字节用于HID_OUTPUT_REPORT

Most hardware in Linux is accessible as a file. Linux中的大多数硬件都可以作为文件访问。 If the driver created a hardware node for it on the file-system, you're in luck. 如果驱动程序在文件系统上为其创建了硬件节点,那么您很幸运。 You will be able to write to it using regular file routines. 您将能够使用常规文件例程对其进行写入。 Otherwise, you may need to do some assembly magic, which may require you to write a kernel module to do it. 否则,您可能需要做一些组装魔术,这可能需要您编写内核模块才能完成。

Here is a complete example of how to write to the CM108/CM119 GPIO pins on Linux. 这是如何在Linux上写入CM108 / CM119 GPIO引脚的完整示例。

https://github.com/wb2osz/direwolf/blob/dev/cm108.c https://github.com/wb2osz/direwolf/blob/dev/cm108.c

You don't need to run as root or write your own device driver. 您无需以root用户身份运行或编写自己的设备驱动程序。

I have the opposite problem. 我有相反的问题。 I'm trying to figure out how to do the same thing on Windows. 我试图弄清楚如何在Windows上执行相同的操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM