Как записать на вывод GPIO чипа CM108 в Linux? - PullRequest
2 голосов
/ 22 мая 2009

CM108 от C-Media имеет 4 контакта GPIO, к которым вы можете получить доступ через скрытый интерфейс.

Используя стандартную функцию записи в Windows, я смог записать на контакты gpio.

Однако я пытаюсь сделать то же самое в Linux без успеха.

Ядро Linux определяет устройство как устройство hidraw.

Примечание: я мог читать с устройства, только не писать. (Я запустил приложение от имени пользователя root, чтобы убедиться, что это не проблема с правами доступа).

Ответы [ 3 ]

2 голосов
/ 16 июня 2009

У меня это работает, вот как.

Мне нужно было создать новый мод linux hid kernel. (это было не так сложно) / *

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

используется этот makefile

obj-m += cm108.o

и скомпилируйте модуль

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

Мне пришлось изменить файл modules.order, чтобы мой модуль запрашивался перед общим модулем hid linux.

Этот модуль гарантирует, что hidraw использует интерфейс 2.

Затем я могу использовать fopen для чтения и записи на вывод GPIO чипа CM108.

Кстати: при записи необходимо записать 5 байтов, 1-й байт используется для HID_OUTPUT_REPORT

0 голосов
/ 29 марта 2018

Вот полный пример того, как записать на контакты GP10 CM108 / CM119 в Linux.

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

Вам не нужно запускаться от имени пользователя root или писать свой собственный драйвер устройства.

У меня противоположная проблема. Я пытаюсь понять, как сделать то же самое в Windows.

0 голосов
/ 25 мая 2009

Большая часть оборудования в Linux доступна в виде файла. Если драйвер создал для него аппаратный узел в файловой системе, вам повезло. Вы сможете писать в него, используя обычные файловые процедуры. В противном случае вам может потребоваться выполнить сборку, которая может потребовать от вас написания модуля ядра.

...