something_i_am_sure
This commit is contained in:
+8
-2
@@ -10,11 +10,11 @@
|
|||||||
#
|
#
|
||||||
# This build does NOT use the WCH EVT SDK, WCH's GCC, libprintf, or IQmath.
|
# This build does NOT use the WCH EVT SDK, WCH's GCC, libprintf, or IQmath.
|
||||||
|
|
||||||
TARGET ?= firmware
|
TARGET ?= ch32v003_GPIO_USB
|
||||||
TARGET_MCU ?= CH32V003
|
TARGET_MCU ?= CH32V003
|
||||||
|
|
||||||
# Root of the ch32fun checkout (the directory containing ch32fun/ and minichlink/).
|
# Root of the ch32fun checkout (the directory containing ch32fun/ and minichlink/).
|
||||||
CH32FUN_ROOT ?= $(HOME)/code/ch32fun
|
CH32FUN_ROOT ?= ./rv003usb/ch32fun
|
||||||
CH32FUN ?= $(CH32FUN_ROOT)/ch32fun
|
CH32FUN ?= $(CH32FUN_ROOT)/ch32fun
|
||||||
MINICHLINK ?= $(CH32FUN_ROOT)/minichlink
|
MINICHLINK ?= $(CH32FUN_ROOT)/minichlink
|
||||||
|
|
||||||
@@ -27,6 +27,12 @@ NEWLIB ?= /usr/riscv64-elf/include
|
|||||||
# make PREFIX=riscv32-unknown-elf
|
# make PREFIX=riscv32-unknown-elf
|
||||||
PREFIX ?= riscv64-elf
|
PREFIX ?= riscv64-elf
|
||||||
|
|
||||||
|
EXTRA_CFLAGS:=-I./rv003usb/lib -I./rv003usb/rv003usb -I../include -O3
|
||||||
|
|
||||||
|
ADDITIONAL_C_FILES+=$(wildcard ./src/*.c)
|
||||||
|
ADDITIONAL_C_FILES+=$(wildcard ./rv003usb/rv003usb/*.c)
|
||||||
|
|
||||||
|
|
||||||
ifeq ($(wildcard $(CH32FUN)/ch32fun.mk),)
|
ifeq ($(wildcard $(CH32FUN)/ch32fun.mk),)
|
||||||
$(error ch32fun not found at $(CH32FUN). Set CH32FUN_ROOT=/path/to/ch32fun)
|
$(error ch32fun not found at $(CH32FUN). Set CH32FUN_ROOT=/path/to/ch32fun)
|
||||||
endif
|
endif
|
||||||
|
|||||||
+2
-10
@@ -1,16 +1,8 @@
|
|||||||
/* SPDX-License-Identifier: MIT */
|
|
||||||
#ifndef _FUNCONFIG_H
|
#ifndef _FUNCONFIG_H
|
||||||
#define _FUNCONFIG_H
|
#define _FUNCONFIG_H
|
||||||
|
|
||||||
/* CH32V003: 48 MHz from the internal HSI + PLL. */
|
|
||||||
#define FUNCONF_USE_HSI 1
|
|
||||||
#define FUNCONF_USE_PLL 1
|
|
||||||
#define FUNCONF_SYSTEM_CORE_CLOCK 48000000
|
|
||||||
|
|
||||||
/*
|
|
||||||
* printf() goes to the SWIO debug channel by default.
|
|
||||||
* Use `make monitor` (minichlink -T) to view it.
|
|
||||||
*/
|
|
||||||
#define FUNCONF_USE_DEBUGPRINTF 1
|
#define FUNCONF_USE_DEBUGPRINTF 1
|
||||||
|
#define FUNCONF_SYSTICK_USE_HCLK 1
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
#include "ch32v003hw.h"
|
||||||
|
#include "rv003usb.h"
|
||||||
|
#include "ch32fun.h"
|
||||||
|
#include "usb.h"
|
||||||
|
|
||||||
|
static uint8_t ctl_buf[4] __attribute__((aligned(4)));
|
||||||
|
|
||||||
|
const uint8_t pin_lookup[] = {PA1,PA2,PC0,PC1,PC2,PC3,PC4,PC5,PC6,PC7,PD0,PD1,PD2,PD7};
|
||||||
|
|
||||||
|
void usb_handle_other_control_message(struct usb_endpoint *e, struct usb_urb *s,
|
||||||
|
struct rv003usb_internal *ist) {
|
||||||
|
uint8_t type = s->wRequestTypeLSBRequestMSB & 0xff;
|
||||||
|
uint8_t req = s->wRequestTypeLSBRequestMSB >> 8;
|
||||||
|
uint16_t wValue = s->lValueLSBIndexMSB & 0xffff; // driver: (op << 8) | pin
|
||||||
|
int len = 0;
|
||||||
|
|
||||||
|
if (type != 0xC0) return; // vendor, device to host
|
||||||
|
if (req == 0 /* GET_INFO */) {
|
||||||
|
struct microcontroller_capabilities* capabs = (struct microcontroller_capabilities*)ctl_buf;
|
||||||
|
capabs->num_gpio = sizeof(pin_lookup) / sizeof(typeof(pin_lookup[0]));
|
||||||
|
capabs->num_uart = 1;
|
||||||
|
capabs->num_spi = 1;
|
||||||
|
capabs->num_adc = 4 ;
|
||||||
|
len = 4;
|
||||||
|
} else if (req == 1 /* CONTROL_PINS */) {
|
||||||
|
switch (ctl_buf[0]) {
|
||||||
|
case (OP_GPIO_GET):
|
||||||
|
ctl_buf[0] = funDigitalRead(pin_lookup[ctl_buf[1]]);
|
||||||
|
len = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
e->opaque = ctl_buf;
|
||||||
|
e->max_len = (s->wLength < len) ? s->wLength : len;
|
||||||
|
}
|
||||||
|
|
||||||
|
void usb_handle_user_data(struct usb_endpoint *e, int ep, uint8_t *data, int len,
|
||||||
|
struct rv003usb_internal *ist) {
|
||||||
|
if (ep != 1 || len < 1) return;
|
||||||
|
/* data[0] = OP_GPIO_SET / OP_GPIO_SET_DIR ... */
|
||||||
|
}
|
||||||
@@ -0,0 +1,102 @@
|
|||||||
|
#ifndef _USB_CONFIG_H
|
||||||
|
#define _USB_CONFIG_H
|
||||||
|
|
||||||
|
#define ENDPOINTS 2
|
||||||
|
|
||||||
|
#define USB_PORT D
|
||||||
|
#define USB_PIN_DP 3
|
||||||
|
#define USB_PIN_DM 4
|
||||||
|
// #define USB_PIN_DPU 2
|
||||||
|
|
||||||
|
#define RV003USB_OPTIMIZE_FLASH 1
|
||||||
|
#define RV003USB_DEBUG_TIMING 0
|
||||||
|
#define RV003USB_EVENT_DEBUGGING 0
|
||||||
|
#define RV003USB_HANDLE_IN_REQUEST 0
|
||||||
|
#define RV003USB_OTHER_CONTROL 1
|
||||||
|
#define RV003USB_HANDLE_USER_DATA 1
|
||||||
|
#define RV003USB_HID_FEATURES 0
|
||||||
|
#define RV003USB_USB_TERMINAL 0
|
||||||
|
#define RV003USB_USE_REBOOT_FEATURE_REPORT 0
|
||||||
|
|
||||||
|
#ifndef __ASSEMBLER__
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifdef INSTANCE_DESCRIPTORS
|
||||||
|
|
||||||
|
static const uint8_t device_descriptor[] = {
|
||||||
|
18, 1,
|
||||||
|
0x10, 0x01, // USB 1.1
|
||||||
|
0x00, 0x00, 0x00,
|
||||||
|
0x08, // EP0 max packet
|
||||||
|
0xd0, 0xfa, // idVendor 0xfad0
|
||||||
|
0x00, 0x90, // idProduct 0x9000
|
||||||
|
0x02, 0x00,
|
||||||
|
1, 2, 3,
|
||||||
|
1,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const uint8_t config_descriptor[] = {
|
||||||
|
9, 2,
|
||||||
|
0x20, 0x00, // wTotalLength = 9 + 9 + 7 + 7
|
||||||
|
0x01, // bNumInterfaces
|
||||||
|
0x01, // bConfigurationValue
|
||||||
|
0x00,
|
||||||
|
0x80,
|
||||||
|
0x64,
|
||||||
|
|
||||||
|
9, 4,
|
||||||
|
0, // bInterfaceNumber
|
||||||
|
0, // bAlternateSetting
|
||||||
|
2, // bNumEndpoints
|
||||||
|
0xff, // vendor specific class
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
0,
|
||||||
|
|
||||||
|
7, 0x05,
|
||||||
|
0x01, // EP1 OUT
|
||||||
|
0x03, // interrupt
|
||||||
|
0x08, 0x00, // max packet 8
|
||||||
|
10, // interval ms
|
||||||
|
|
||||||
|
7, 0x05,
|
||||||
|
0x81, // EP1 IN
|
||||||
|
0x03,
|
||||||
|
0x08, 0x00,
|
||||||
|
10,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define STR_MANUFACTURER u"That real manufacturer"
|
||||||
|
#define STR_PRODUCT u"CH32V003 USB GPIO module"
|
||||||
|
#ifndef STR_SERIAL
|
||||||
|
#define STR_SERIAL u"deadbeef"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct usb_string_descriptor_struct {
|
||||||
|
uint8_t bLength;
|
||||||
|
uint8_t bDescriptorType;
|
||||||
|
uint16_t wString[];
|
||||||
|
};
|
||||||
|
const static struct usb_string_descriptor_struct string0 __attribute__((section(".rodata"))) = { 4, 3, {0x0409} };
|
||||||
|
const static struct usb_string_descriptor_struct string1 __attribute__((section(".rodata"))) = { sizeof(STR_MANUFACTURER), 3, STR_MANUFACTURER };
|
||||||
|
const static struct usb_string_descriptor_struct string2 __attribute__((section(".rodata"))) = { sizeof(STR_PRODUCT), 3, STR_PRODUCT };
|
||||||
|
const static struct usb_string_descriptor_struct string3 __attribute__((section(".rodata"))) = { sizeof(STR_SERIAL), 3, STR_SERIAL };
|
||||||
|
|
||||||
|
const static struct descriptor_list_struct {
|
||||||
|
uint32_t lIndexValue;
|
||||||
|
const uint8_t *addr;
|
||||||
|
uint8_t length;
|
||||||
|
} descriptor_list[] = {
|
||||||
|
{0x00000100, device_descriptor, sizeof(device_descriptor)},
|
||||||
|
{0x00000200, config_descriptor, sizeof(config_descriptor)},
|
||||||
|
{0x00000300, (const uint8_t *)&string0, 4},
|
||||||
|
{0x04090301, (const uint8_t *)&string1, sizeof(STR_MANUFACTURER)},
|
||||||
|
{0x04090302, (const uint8_t *)&string2, sizeof(STR_PRODUCT)},
|
||||||
|
{0x04090303, (const uint8_t *)&string3, sizeof(STR_SERIAL)}
|
||||||
|
};
|
||||||
|
#define DESCRIPTOR_LIST_ENTRIES ((sizeof(descriptor_list))/(sizeof(struct descriptor_list_struct)))
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
#pragma once
|
||||||
|
#if __has_include(<linux/types.h>)
|
||||||
|
#include <linux/types.h>
|
||||||
|
#else
|
||||||
|
#include <stdint.h>
|
||||||
|
typedef uint8_t u8;
|
||||||
|
#endif
|
||||||
|
enum op_type {
|
||||||
|
OP_CAPABILITIES_GET,
|
||||||
|
OP_GPIO_GET,
|
||||||
|
OP_GPIO_SET,
|
||||||
|
OP_GPIO_SET_DIR,
|
||||||
|
OP_SET_ADC_PIN,
|
||||||
|
OP_READ_ADC,
|
||||||
|
OP_GPIO_SET_BAUD,
|
||||||
|
OP_GPIO_WRITE_UART,
|
||||||
|
OP_GPIO_READ_UART,
|
||||||
|
OP_GPIO_SET_CLK,
|
||||||
|
OP_GPIO_WRITE_SPI,
|
||||||
|
OP_GPIO_READ_SPI
|
||||||
|
};
|
||||||
|
enum direction { DIR_IN, DIR_OUT };
|
||||||
|
|
||||||
|
enum vendor_request {
|
||||||
|
GET_INFO,
|
||||||
|
CONTROL_PINS
|
||||||
|
};
|
||||||
|
|
||||||
|
struct __attribute__((packed)) microcontroller_capabilities {
|
||||||
|
u8 num_gpio;
|
||||||
|
u8 num_uart;
|
||||||
|
u8 num_spi;
|
||||||
|
u8 num_adc;
|
||||||
|
};
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1 @@
|
|||||||
|
savedcmd_Module.symvers := /usr/lib/modules/7.2.9-zen1-1-zen/build/scripts/mod/modpost -M -a -N -o Module.symvers -n -T modules.order -i /usr/lib/modules/7.2.9-zen1-1-zen/build/Module.symvers -e
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
savedcmd_main.ko := ld -r -m elf_x86_64 -z noexecstack --no-warn-rwx-segments --build-id=sha1 -T /usr/lib/modules/7.2.9-zen1-1-zen/build/scripts/module.lds -o main.ko main.o main.mod.o .module-common.o
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
savedcmd_main.mod := printf '%s\n' main.o | awk '!x[$$0]++ { print("./"$$0) }' > main.mod
|
||||||
File diff suppressed because it is too large
Load Diff
+1274
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -0,0 +1 @@
|
|||||||
|
savedcmd_modules.order := { echo main.o; :; } > modules.order
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
obj-m += main.o
|
||||||
|
|
||||||
|
KDIR ?= /lib/modules/$(shell uname -r)/build
|
||||||
|
|
||||||
|
all:
|
||||||
|
$(MAKE) -C $(KDIR) M=$(PWD) modules
|
||||||
|
|
||||||
|
clean:
|
||||||
|
$(MAKE) -C $(KDIR) M=$(PWD) clean
|
||||||
@@ -0,0 +1,404 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"file": "main.c",
|
||||||
|
"arguments": [
|
||||||
|
"/usr/bin/gcc",
|
||||||
|
"-Wp,-MMD,./.main.o.d",
|
||||||
|
"-nostdinc",
|
||||||
|
"-I/usr/lib/modules/7.2.9-zen1-1-zen/build/arch/x86/include",
|
||||||
|
"-I/usr/lib/modules/7.2.9-zen1-1-zen/build/arch/x86/include/generated",
|
||||||
|
"-I/usr/lib/modules/7.2.9-zen1-1-zen/build/include",
|
||||||
|
"-I/usr/lib/modules/7.2.9-zen1-1-zen/build/include",
|
||||||
|
"-I/usr/lib/modules/7.2.9-zen1-1-zen/build/arch/x86/include/uapi",
|
||||||
|
"-I/usr/lib/modules/7.2.9-zen1-1-zen/build/arch/x86/include/generated/uapi",
|
||||||
|
"-I/usr/lib/modules/7.2.9-zen1-1-zen/build/include/uapi",
|
||||||
|
"-I/usr/lib/modules/7.2.9-zen1-1-zen/build/include/generated/uapi",
|
||||||
|
"-include",
|
||||||
|
"/usr/lib/modules/7.2.9-zen1-1-zen/build/include/linux/compiler-version.h",
|
||||||
|
"-include",
|
||||||
|
"/usr/lib/modules/7.2.9-zen1-1-zen/build/include/linux/kconfig.h",
|
||||||
|
"-include",
|
||||||
|
"/usr/lib/modules/7.2.9-zen1-1-zen/build/include/linux/compiler_types.h",
|
||||||
|
"-D__KERNEL__",
|
||||||
|
"-fshort-wchar",
|
||||||
|
"-funsigned-char",
|
||||||
|
"-fno-common",
|
||||||
|
"-fno-PIE",
|
||||||
|
"-fno-strict-aliasing",
|
||||||
|
"-std=gnu11",
|
||||||
|
"-fms-extensions",
|
||||||
|
"-mno-sse",
|
||||||
|
"-mno-mmx",
|
||||||
|
"-mno-sse2",
|
||||||
|
"-mno-3dnow",
|
||||||
|
"-mno-avx",
|
||||||
|
"-mno-sse4a",
|
||||||
|
"-mno-avx2",
|
||||||
|
"-fno-tree-vectorize",
|
||||||
|
"-fcf-protection=branch",
|
||||||
|
"-fno-jump-tables",
|
||||||
|
"-m64",
|
||||||
|
"-falign-jumps=1",
|
||||||
|
"-falign-loops=1",
|
||||||
|
"-mno-80387",
|
||||||
|
"-mno-fp-ret-in-387",
|
||||||
|
"-mpreferred-stack-boundary=3",
|
||||||
|
"-mskip-rax-setup",
|
||||||
|
"-march=x86-64",
|
||||||
|
"-mtune=generic",
|
||||||
|
"-mno-red-zone",
|
||||||
|
"-mcmodel=kernel",
|
||||||
|
"-mstack-protector-guard-reg=gs",
|
||||||
|
"-mstack-protector-guard-symbol=__ref_stack_chk_guard",
|
||||||
|
"-Wno-sign-compare",
|
||||||
|
"-fno-asynchronous-unwind-tables",
|
||||||
|
"-mindirect-branch=thunk-extern",
|
||||||
|
"-mindirect-branch-register",
|
||||||
|
"-mindirect-branch-cs-prefix",
|
||||||
|
"-mfunction-return=thunk-extern",
|
||||||
|
"-fno-jump-tables",
|
||||||
|
"-mharden-sls=all",
|
||||||
|
"-fpatchable-function-entry=16,16",
|
||||||
|
"-fno-delete-null-pointer-checks",
|
||||||
|
"-O3",
|
||||||
|
"-fno-allow-store-data-races",
|
||||||
|
"-fstack-protector-strong",
|
||||||
|
"-ftrivial-auto-var-init=zero",
|
||||||
|
"-fzero-init-padding-bits=all",
|
||||||
|
"-fno-stack-clash-protection",
|
||||||
|
"-fdiagnostics-show-context=2",
|
||||||
|
"-pg",
|
||||||
|
"-mrecord-mcount",
|
||||||
|
"-mfentry",
|
||||||
|
"-DCC_USING_FENTRY",
|
||||||
|
"-fmin-function-alignment=16",
|
||||||
|
"-fstrict-flex-arrays=3",
|
||||||
|
"-fno-strict-overflow",
|
||||||
|
"-fno-stack-check",
|
||||||
|
"-fconserve-stack",
|
||||||
|
"-fno-builtin-wcslen",
|
||||||
|
"-Wall",
|
||||||
|
"-Wextra",
|
||||||
|
"-Wundef",
|
||||||
|
"-Werror=implicit-function-declaration",
|
||||||
|
"-Werror=implicit-int",
|
||||||
|
"-Werror=return-type",
|
||||||
|
"-Werror=strict-prototypes",
|
||||||
|
"-Wno-format-security",
|
||||||
|
"-Wno-trigraphs",
|
||||||
|
"-Wno-frame-address",
|
||||||
|
"-Wno-address-of-packed-member",
|
||||||
|
"-Wmissing-declarations",
|
||||||
|
"-Wmissing-prototypes",
|
||||||
|
"-Wframe-larger-than=2048",
|
||||||
|
"-Wno-main",
|
||||||
|
"-Wno-type-limits",
|
||||||
|
"-Wno-dangling-pointer",
|
||||||
|
"-Wvla-larger-than=1",
|
||||||
|
"-Wno-pointer-sign",
|
||||||
|
"-Wcast-function-type",
|
||||||
|
"-Wno-unterminated-string-initialization",
|
||||||
|
"-Wno-array-bounds",
|
||||||
|
"-Wno-stringop-overflow",
|
||||||
|
"-Wno-alloc-size-larger-than",
|
||||||
|
"-Wimplicit-fallthrough=5",
|
||||||
|
"-Werror=date-time",
|
||||||
|
"-Werror=incompatible-pointer-types",
|
||||||
|
"-Werror=designated-init",
|
||||||
|
"-Wenum-conversion",
|
||||||
|
"-Wunused",
|
||||||
|
"-Wno-unused-but-set-variable",
|
||||||
|
"-Wno-unused-const-variable",
|
||||||
|
"-Wno-packed-not-aligned",
|
||||||
|
"-Wno-format-overflow",
|
||||||
|
"-Wno-format-truncation",
|
||||||
|
"-Wno-stringop-truncation",
|
||||||
|
"-Wno-override-init",
|
||||||
|
"-Wno-missing-field-initializers",
|
||||||
|
"-Wno-shift-negative-value",
|
||||||
|
"-Wno-maybe-uninitialized",
|
||||||
|
"-Wno-sign-compare",
|
||||||
|
"-Wno-unused-parameter",
|
||||||
|
"-g",
|
||||||
|
"-gdwarf-5",
|
||||||
|
"-DMODULE",
|
||||||
|
"-DKBUILD_BASENAME=\"main\"",
|
||||||
|
"-DKBUILD_MODNAME=\"main\"",
|
||||||
|
"-D__KBUILD_MODNAME=main",
|
||||||
|
"-c",
|
||||||
|
"-o",
|
||||||
|
"main.o",
|
||||||
|
"main.c"
|
||||||
|
],
|
||||||
|
"directory": "/home/lukas/code/Linux-microcontroller-GPIO/kernel",
|
||||||
|
"output": "main.o"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"file": "main.mod.c",
|
||||||
|
"arguments": [
|
||||||
|
"/usr/bin/gcc",
|
||||||
|
"-Wp,-MMD,./.main.mod.o.d",
|
||||||
|
"-nostdinc",
|
||||||
|
"-I/usr/lib/modules/7.2.9-zen1-1-zen/build/arch/x86/include",
|
||||||
|
"-I/usr/lib/modules/7.2.9-zen1-1-zen/build/arch/x86/include/generated",
|
||||||
|
"-I/usr/lib/modules/7.2.9-zen1-1-zen/build/include",
|
||||||
|
"-I/usr/lib/modules/7.2.9-zen1-1-zen/build/include",
|
||||||
|
"-I/usr/lib/modules/7.2.9-zen1-1-zen/build/arch/x86/include/uapi",
|
||||||
|
"-I/usr/lib/modules/7.2.9-zen1-1-zen/build/arch/x86/include/generated/uapi",
|
||||||
|
"-I/usr/lib/modules/7.2.9-zen1-1-zen/build/include/uapi",
|
||||||
|
"-I/usr/lib/modules/7.2.9-zen1-1-zen/build/include/generated/uapi",
|
||||||
|
"-include",
|
||||||
|
"/usr/lib/modules/7.2.9-zen1-1-zen/build/include/linux/compiler-version.h",
|
||||||
|
"-include",
|
||||||
|
"/usr/lib/modules/7.2.9-zen1-1-zen/build/include/linux/kconfig.h",
|
||||||
|
"-include",
|
||||||
|
"/usr/lib/modules/7.2.9-zen1-1-zen/build/include/linux/compiler_types.h",
|
||||||
|
"-D__KERNEL__",
|
||||||
|
"-fshort-wchar",
|
||||||
|
"-funsigned-char",
|
||||||
|
"-fno-common",
|
||||||
|
"-fno-PIE",
|
||||||
|
"-fno-strict-aliasing",
|
||||||
|
"-std=gnu11",
|
||||||
|
"-fms-extensions",
|
||||||
|
"-mno-sse",
|
||||||
|
"-mno-mmx",
|
||||||
|
"-mno-sse2",
|
||||||
|
"-mno-3dnow",
|
||||||
|
"-mno-avx",
|
||||||
|
"-mno-sse4a",
|
||||||
|
"-mno-avx2",
|
||||||
|
"-fno-tree-vectorize",
|
||||||
|
"-fcf-protection=branch",
|
||||||
|
"-fno-jump-tables",
|
||||||
|
"-m64",
|
||||||
|
"-falign-jumps=1",
|
||||||
|
"-falign-loops=1",
|
||||||
|
"-mno-80387",
|
||||||
|
"-mno-fp-ret-in-387",
|
||||||
|
"-mpreferred-stack-boundary=3",
|
||||||
|
"-mskip-rax-setup",
|
||||||
|
"-march=x86-64",
|
||||||
|
"-mtune=generic",
|
||||||
|
"-mno-red-zone",
|
||||||
|
"-mcmodel=kernel",
|
||||||
|
"-mstack-protector-guard-reg=gs",
|
||||||
|
"-mstack-protector-guard-symbol=__ref_stack_chk_guard",
|
||||||
|
"-Wno-sign-compare",
|
||||||
|
"-fno-asynchronous-unwind-tables",
|
||||||
|
"-mindirect-branch=thunk-extern",
|
||||||
|
"-mindirect-branch-register",
|
||||||
|
"-mindirect-branch-cs-prefix",
|
||||||
|
"-mfunction-return=thunk-extern",
|
||||||
|
"-fno-jump-tables",
|
||||||
|
"-mharden-sls=all",
|
||||||
|
"-fpatchable-function-entry=16,16",
|
||||||
|
"-fno-delete-null-pointer-checks",
|
||||||
|
"-O3",
|
||||||
|
"-fno-allow-store-data-races",
|
||||||
|
"-fstack-protector-strong",
|
||||||
|
"-ftrivial-auto-var-init=zero",
|
||||||
|
"-fzero-init-padding-bits=all",
|
||||||
|
"-fno-stack-clash-protection",
|
||||||
|
"-fdiagnostics-show-context=2",
|
||||||
|
"-pg",
|
||||||
|
"-mrecord-mcount",
|
||||||
|
"-mfentry",
|
||||||
|
"-DCC_USING_FENTRY",
|
||||||
|
"-fmin-function-alignment=16",
|
||||||
|
"-fstrict-flex-arrays=3",
|
||||||
|
"-fno-strict-overflow",
|
||||||
|
"-fno-stack-check",
|
||||||
|
"-fconserve-stack",
|
||||||
|
"-fno-builtin-wcslen",
|
||||||
|
"-Wall",
|
||||||
|
"-Wextra",
|
||||||
|
"-Wundef",
|
||||||
|
"-Werror=implicit-function-declaration",
|
||||||
|
"-Werror=implicit-int",
|
||||||
|
"-Werror=return-type",
|
||||||
|
"-Werror=strict-prototypes",
|
||||||
|
"-Wno-format-security",
|
||||||
|
"-Wno-trigraphs",
|
||||||
|
"-Wno-frame-address",
|
||||||
|
"-Wno-address-of-packed-member",
|
||||||
|
"-Wmissing-declarations",
|
||||||
|
"-Wmissing-prototypes",
|
||||||
|
"-Wframe-larger-than=2048",
|
||||||
|
"-Wno-main",
|
||||||
|
"-Wno-type-limits",
|
||||||
|
"-Wno-dangling-pointer",
|
||||||
|
"-Wvla-larger-than=1",
|
||||||
|
"-Wno-pointer-sign",
|
||||||
|
"-Wcast-function-type",
|
||||||
|
"-Wno-unterminated-string-initialization",
|
||||||
|
"-Wno-array-bounds",
|
||||||
|
"-Wno-stringop-overflow",
|
||||||
|
"-Wno-alloc-size-larger-than",
|
||||||
|
"-Wimplicit-fallthrough=5",
|
||||||
|
"-Werror=date-time",
|
||||||
|
"-Werror=incompatible-pointer-types",
|
||||||
|
"-Werror=designated-init",
|
||||||
|
"-Wenum-conversion",
|
||||||
|
"-Wunused",
|
||||||
|
"-Wno-unused-but-set-variable",
|
||||||
|
"-Wno-unused-const-variable",
|
||||||
|
"-Wno-packed-not-aligned",
|
||||||
|
"-Wno-format-overflow",
|
||||||
|
"-Wno-format-truncation",
|
||||||
|
"-Wno-stringop-truncation",
|
||||||
|
"-Wno-override-init",
|
||||||
|
"-Wno-missing-field-initializers",
|
||||||
|
"-Wno-shift-negative-value",
|
||||||
|
"-Wno-maybe-uninitialized",
|
||||||
|
"-Wno-sign-compare",
|
||||||
|
"-Wno-unused-parameter",
|
||||||
|
"-g",
|
||||||
|
"-gdwarf-5",
|
||||||
|
"-DMODULE",
|
||||||
|
"-DKBUILD_BASENAME=\"main.mod\"",
|
||||||
|
"-DKBUILD_MODNAME=\"main\"",
|
||||||
|
"-D__KBUILD_MODNAME=main",
|
||||||
|
"-c",
|
||||||
|
"-o",
|
||||||
|
"main.mod.o",
|
||||||
|
"main.mod.c"
|
||||||
|
],
|
||||||
|
"directory": "/home/lukas/code/Linux-microcontroller-GPIO/kernel",
|
||||||
|
"output": "main.mod.o"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"file": "/usr/lib/modules/7.2.9-zen1-1-zen/build/scripts/module-common.c",
|
||||||
|
"arguments": [
|
||||||
|
"/usr/bin/gcc",
|
||||||
|
"-Wp,-MMD,./..module-common.o.d",
|
||||||
|
"-nostdinc",
|
||||||
|
"-I/usr/lib/modules/7.2.9-zen1-1-zen/build/arch/x86/include",
|
||||||
|
"-I/usr/lib/modules/7.2.9-zen1-1-zen/build/arch/x86/include/generated",
|
||||||
|
"-I/usr/lib/modules/7.2.9-zen1-1-zen/build/include",
|
||||||
|
"-I/usr/lib/modules/7.2.9-zen1-1-zen/build/include",
|
||||||
|
"-I/usr/lib/modules/7.2.9-zen1-1-zen/build/arch/x86/include/uapi",
|
||||||
|
"-I/usr/lib/modules/7.2.9-zen1-1-zen/build/arch/x86/include/generated/uapi",
|
||||||
|
"-I/usr/lib/modules/7.2.9-zen1-1-zen/build/include/uapi",
|
||||||
|
"-I/usr/lib/modules/7.2.9-zen1-1-zen/build/include/generated/uapi",
|
||||||
|
"-include",
|
||||||
|
"/usr/lib/modules/7.2.9-zen1-1-zen/build/include/linux/compiler-version.h",
|
||||||
|
"-include",
|
||||||
|
"/usr/lib/modules/7.2.9-zen1-1-zen/build/include/linux/kconfig.h",
|
||||||
|
"-include",
|
||||||
|
"/usr/lib/modules/7.2.9-zen1-1-zen/build/include/linux/compiler_types.h",
|
||||||
|
"-D__KERNEL__",
|
||||||
|
"-fshort-wchar",
|
||||||
|
"-funsigned-char",
|
||||||
|
"-fno-common",
|
||||||
|
"-fno-PIE",
|
||||||
|
"-fno-strict-aliasing",
|
||||||
|
"-std=gnu11",
|
||||||
|
"-fms-extensions",
|
||||||
|
"-mno-sse",
|
||||||
|
"-mno-mmx",
|
||||||
|
"-mno-sse2",
|
||||||
|
"-mno-3dnow",
|
||||||
|
"-mno-avx",
|
||||||
|
"-mno-sse4a",
|
||||||
|
"-mno-avx2",
|
||||||
|
"-fno-tree-vectorize",
|
||||||
|
"-fcf-protection=branch",
|
||||||
|
"-fno-jump-tables",
|
||||||
|
"-m64",
|
||||||
|
"-falign-jumps=1",
|
||||||
|
"-falign-loops=1",
|
||||||
|
"-mno-80387",
|
||||||
|
"-mno-fp-ret-in-387",
|
||||||
|
"-mpreferred-stack-boundary=3",
|
||||||
|
"-mskip-rax-setup",
|
||||||
|
"-march=x86-64",
|
||||||
|
"-mtune=generic",
|
||||||
|
"-mno-red-zone",
|
||||||
|
"-mcmodel=kernel",
|
||||||
|
"-mstack-protector-guard-reg=gs",
|
||||||
|
"-mstack-protector-guard-symbol=__ref_stack_chk_guard",
|
||||||
|
"-Wno-sign-compare",
|
||||||
|
"-fno-asynchronous-unwind-tables",
|
||||||
|
"-mindirect-branch=thunk-extern",
|
||||||
|
"-mindirect-branch-register",
|
||||||
|
"-mindirect-branch-cs-prefix",
|
||||||
|
"-mfunction-return=thunk-extern",
|
||||||
|
"-fno-jump-tables",
|
||||||
|
"-mharden-sls=all",
|
||||||
|
"-fpatchable-function-entry=16,16",
|
||||||
|
"-fno-delete-null-pointer-checks",
|
||||||
|
"-O3",
|
||||||
|
"-fno-allow-store-data-races",
|
||||||
|
"-fstack-protector-strong",
|
||||||
|
"-ftrivial-auto-var-init=zero",
|
||||||
|
"-fzero-init-padding-bits=all",
|
||||||
|
"-fno-stack-clash-protection",
|
||||||
|
"-fdiagnostics-show-context=2",
|
||||||
|
"-pg",
|
||||||
|
"-mrecord-mcount",
|
||||||
|
"-mfentry",
|
||||||
|
"-DCC_USING_FENTRY",
|
||||||
|
"-fmin-function-alignment=16",
|
||||||
|
"-fstrict-flex-arrays=3",
|
||||||
|
"-fno-strict-overflow",
|
||||||
|
"-fno-stack-check",
|
||||||
|
"-fconserve-stack",
|
||||||
|
"-fno-builtin-wcslen",
|
||||||
|
"-Wall",
|
||||||
|
"-Wextra",
|
||||||
|
"-Wundef",
|
||||||
|
"-Werror=implicit-function-declaration",
|
||||||
|
"-Werror=implicit-int",
|
||||||
|
"-Werror=return-type",
|
||||||
|
"-Werror=strict-prototypes",
|
||||||
|
"-Wno-format-security",
|
||||||
|
"-Wno-trigraphs",
|
||||||
|
"-Wno-frame-address",
|
||||||
|
"-Wno-address-of-packed-member",
|
||||||
|
"-Wmissing-declarations",
|
||||||
|
"-Wmissing-prototypes",
|
||||||
|
"-Wframe-larger-than=2048",
|
||||||
|
"-Wno-main",
|
||||||
|
"-Wno-type-limits",
|
||||||
|
"-Wno-dangling-pointer",
|
||||||
|
"-Wvla-larger-than=1",
|
||||||
|
"-Wno-pointer-sign",
|
||||||
|
"-Wcast-function-type",
|
||||||
|
"-Wno-unterminated-string-initialization",
|
||||||
|
"-Wno-array-bounds",
|
||||||
|
"-Wno-stringop-overflow",
|
||||||
|
"-Wno-alloc-size-larger-than",
|
||||||
|
"-Wimplicit-fallthrough=5",
|
||||||
|
"-Werror=date-time",
|
||||||
|
"-Werror=incompatible-pointer-types",
|
||||||
|
"-Werror=designated-init",
|
||||||
|
"-Wenum-conversion",
|
||||||
|
"-Wunused",
|
||||||
|
"-Wno-unused-but-set-variable",
|
||||||
|
"-Wno-unused-const-variable",
|
||||||
|
"-Wno-packed-not-aligned",
|
||||||
|
"-Wno-format-overflow",
|
||||||
|
"-Wno-format-truncation",
|
||||||
|
"-Wno-stringop-truncation",
|
||||||
|
"-Wno-override-init",
|
||||||
|
"-Wno-missing-field-initializers",
|
||||||
|
"-Wno-shift-negative-value",
|
||||||
|
"-Wno-maybe-uninitialized",
|
||||||
|
"-Wno-sign-compare",
|
||||||
|
"-Wno-unused-parameter",
|
||||||
|
"-g",
|
||||||
|
"-gdwarf-5",
|
||||||
|
"-DMODULE",
|
||||||
|
"-DKBUILD_BASENAME=\".module_common\"",
|
||||||
|
"-DKBUILD_MODNAME=\".module_common.o\"",
|
||||||
|
"-D__KBUILD_MODNAME=.module_common.o",
|
||||||
|
"-c",
|
||||||
|
"-o",
|
||||||
|
".module-common.o",
|
||||||
|
"/usr/lib/modules/7.2.9-zen1-1-zen/build/scripts/module-common.c"
|
||||||
|
],
|
||||||
|
"directory": "/home/lukas/code/Linux-microcontroller-GPIO/kernel",
|
||||||
|
"output": ".module-common.o"
|
||||||
|
}
|
||||||
|
]
|
||||||
+234
@@ -0,0 +1,234 @@
|
|||||||
|
#include "../include/usb.h"
|
||||||
|
#include "asm-generic/errno-base.h"
|
||||||
|
#include "linux/cleanup.h"
|
||||||
|
#include "linux/device/devres.h"
|
||||||
|
#include "linux/gfp_types.h"
|
||||||
|
#include <linux/gpio/driver.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/usb.h>
|
||||||
|
|
||||||
|
#define GPIO_PIN_COUNT 18
|
||||||
|
|
||||||
|
struct microcontroller_gpio {
|
||||||
|
struct gpio_chip chip; /* kernel GPIO controller object */
|
||||||
|
struct usb_device *udev; /* handle used for all USB transfers */
|
||||||
|
struct usb_interface *intf;
|
||||||
|
unsigned char ep_addr;
|
||||||
|
int interval;
|
||||||
|
};
|
||||||
|
|
||||||
|
#include <linux/slab.h>
|
||||||
|
#include <linux/usb.h>
|
||||||
|
|
||||||
|
static int send_cmd_get_response_control(struct usb_device *udev, u8 *dst,
|
||||||
|
__u16 max_resp_size,
|
||||||
|
enum vendor_request request_type,
|
||||||
|
const u8 cmd[2]) {
|
||||||
|
int retval;
|
||||||
|
u16 wValue;
|
||||||
|
if (cmd == NULL) {
|
||||||
|
wValue = ((u16)cmd[0] << 8) | cmd[1]; /* Pack 2 command bytes into wValue */
|
||||||
|
} else {
|
||||||
|
wValue = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 2. Execute Control IN transfer */
|
||||||
|
retval = usb_control_msg(
|
||||||
|
udev, usb_rcvctrlpipe(udev, 0), /* Control IN pipe */
|
||||||
|
request_type, /* bRequest */
|
||||||
|
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, /* bmRequestType */
|
||||||
|
wValue, /* 2 Command bytes sent in SETUP */
|
||||||
|
0x0000, /* wIndex (unused) */
|
||||||
|
dst, /* Buffer for incoming data */
|
||||||
|
max_resp_size, /* Request up to 256 bytes */
|
||||||
|
2000 /* Timeout (ms) */
|
||||||
|
);
|
||||||
|
|
||||||
|
if (retval < 0) {
|
||||||
|
pr_err("Control transfer failed: %d\n", retval);
|
||||||
|
}
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void usb_data_send_completed(struct urb *urb) {
|
||||||
|
if (urb->status == 0)
|
||||||
|
pr_info("Async transfer successful!\n");
|
||||||
|
else
|
||||||
|
pr_err("Async transfer failed with status: %d\n", urb->status);
|
||||||
|
|
||||||
|
kfree(urb->transfer_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int async_send_usb_data_to_microcontroller(const unsigned char *msg,
|
||||||
|
size_t msg_len,
|
||||||
|
struct usb_device *udev,
|
||||||
|
unsigned char ep_addr,int interval) {
|
||||||
|
struct urb *urb;
|
||||||
|
char *buf_dma;
|
||||||
|
int retval;
|
||||||
|
unsigned int pipe = usb_sndbulkpipe(udev, ep_addr);
|
||||||
|
|
||||||
|
urb = usb_alloc_urb(0, GFP_KERNEL);
|
||||||
|
if (!urb)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
buf_dma = kzalloc(msg_len, GFP_KERNEL);
|
||||||
|
if (!buf_dma) {
|
||||||
|
usb_free_urb(urb);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(buf_dma, msg, msg_len);
|
||||||
|
|
||||||
|
usb_fill_int_urb(urb, udev, pipe, buf_dma, msg_len, usb_data_send_completed, NULL, interval);
|
||||||
|
|
||||||
|
retval = usb_submit_urb(urb, GFP_KERNEL);
|
||||||
|
if (retval) {
|
||||||
|
pr_err("Failed to submit URB: %d\n", retval);
|
||||||
|
kfree(buf_dma);
|
||||||
|
}
|
||||||
|
|
||||||
|
// usb_data_send_completed will free is automaticaly
|
||||||
|
usb_free_urb(urb);
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read the level of line "off" from the device; return 1, 0 or -errno. */
|
||||||
|
static int microcontroller_get(struct gpio_chip *gc, unsigned int off) {
|
||||||
|
if (off>= gc->ngpio) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
struct microcontroller_gpio *dev = gpiochip_get_data(gc);
|
||||||
|
u8 retval;
|
||||||
|
const u8 cmd[] = {OP_GPIO_GET,off};
|
||||||
|
send_cmd_get_response_control(dev->udev, &retval, sizeof(retval), CONTROL_PINS, cmd);
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Drive output line "off" to "val" (0 or 1) on the device; return 0 or -errno.
|
||||||
|
*/
|
||||||
|
static int microcontroller_set(struct gpio_chip *gc, unsigned int off,
|
||||||
|
int val) {
|
||||||
|
struct microcontroller_gpio *dev = gpiochip_get_data(gc);
|
||||||
|
const unsigned char msg[2] = {OP_GPIO_SET, val};
|
||||||
|
return async_send_usb_data_to_microcontroller(msg, sizeof(msg), dev->udev,
|
||||||
|
dev->ep_addr,dev->interval);
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Tell the device to make line "off" an input; return 0 or -errno. */
|
||||||
|
static int microcontroller_dir_in(struct gpio_chip *gc, unsigned int off) {
|
||||||
|
struct microcontroller_gpio *dev = gpiochip_get_data(gc);
|
||||||
|
const unsigned char msg[2] = {OP_GPIO_SET_DIR, DIR_IN};
|
||||||
|
return async_send_usb_data_to_microcontroller(msg, sizeof(msg), dev->udev,
|
||||||
|
dev->ep_addr,dev->interval);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tell the device to make line "off" an output driving "val"; return 0 or
|
||||||
|
* -errno. */
|
||||||
|
static int microcontroller_dir_out(struct gpio_chip *gc, unsigned int off,
|
||||||
|
int val) {
|
||||||
|
struct microcontroller_gpio *dev = gpiochip_get_data(gc);
|
||||||
|
const unsigned char msg[3] = {OP_GPIO_SET_DIR, DIR_OUT, val};
|
||||||
|
return async_send_usb_data_to_microcontroller(msg, sizeof(msg), dev->udev,
|
||||||
|
dev->ep_addr,dev->interval);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_microcontroller_capabilities(struct microcontroller_gpio *dev) {
|
||||||
|
struct microcontroller_capabilities capabs;
|
||||||
|
if (send_cmd_get_response_control(dev->udev, (u8 *)&capabs, sizeof(capabs),
|
||||||
|
GET_INFO, NULL) != sizeof(capabs)) {
|
||||||
|
dev->chip.ngpio = capabs.num_gpio;
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Called when the USB device matches: allocate state, fill gpio_chip, register
|
||||||
|
* it. */
|
||||||
|
static int microcontroller_probe(struct usb_interface *intf,
|
||||||
|
const struct usb_device_id *id) {
|
||||||
|
struct microcontroller_gpio *dev;
|
||||||
|
dev = devm_kzalloc(&intf->dev, sizeof(*dev), GFP_KERNEL);
|
||||||
|
if (!dev) {
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
struct usb_host_interface *iface_desc = intf->cur_altsetting;
|
||||||
|
struct usb_endpoint_descriptor *ep_desc;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) {
|
||||||
|
ep_desc = &iface_desc->endpoint[i].desc;
|
||||||
|
|
||||||
|
if (usb_endpoint_is_int_out(ep_desc)) {
|
||||||
|
pr_info("Found Bulk OUT endpoint address: 0x%02X\n",
|
||||||
|
ep_desc->bEndpointAddress);
|
||||||
|
dev->interval = ep_desc->bInterval;
|
||||||
|
dev->ep_addr = ep_desc->bEndpointAddress;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
usb_set_intfdata(intf, dev);
|
||||||
|
dev_info(&intf->dev, "USB device attached: vendor=0x%04x, product=0x%04x\n",
|
||||||
|
le16_to_cpu(dev->udev->descriptor.idVendor),
|
||||||
|
le16_to_cpu(dev->udev->descriptor.idProduct));
|
||||||
|
|
||||||
|
dev->udev = usb_get_dev(interface_to_usbdev(intf));
|
||||||
|
dev->intf = intf;
|
||||||
|
|
||||||
|
dev->chip.label = "microcontroller-gpio";
|
||||||
|
dev->chip.parent = &intf->dev;
|
||||||
|
dev->chip.owner = THIS_MODULE;
|
||||||
|
dev->chip.base = -1;
|
||||||
|
|
||||||
|
dev->chip.get = microcontroller_get;
|
||||||
|
dev->chip.set = microcontroller_set;
|
||||||
|
dev->chip.direction_input = microcontroller_dir_in;
|
||||||
|
dev->chip.direction_output = microcontroller_dir_out;
|
||||||
|
get_microcontroller_capabilities(dev);
|
||||||
|
int ret = devm_gpiochip_add_data(&intf->dev, &dev->chip, dev);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(&intf->dev, "Failed to add gpio_chip\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Called on unplug or driver unbind: release the USB device reference. */
|
||||||
|
static void microcontroller_disconnect(struct usb_interface *intf) {
|
||||||
|
struct microcontroller_gpio *dev;
|
||||||
|
dev = usb_get_intfdata(intf);
|
||||||
|
|
||||||
|
usb_set_intfdata(intf, NULL);
|
||||||
|
if (dev) {
|
||||||
|
usb_put_dev(dev->udev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* VID/PID pairs this driver binds to. */
|
||||||
|
static const struct usb_device_id microcontroller_table[] = {
|
||||||
|
{USB_DEVICE(0xfad0, 0x9000)}, {}};
|
||||||
|
/* Exports the table so udev can autoload the module when the device appears. */
|
||||||
|
MODULE_DEVICE_TABLE(usb, microcontroller_table);
|
||||||
|
|
||||||
|
/* Ties probe, disconnect and the ID table together for the USB core. */
|
||||||
|
static struct usb_driver microcontroller_driver = {
|
||||||
|
.name = "microcontroller-GPIO",
|
||||||
|
.probe = microcontroller_probe,
|
||||||
|
.disconnect = microcontroller_disconnect,
|
||||||
|
.id_table = microcontroller_table,
|
||||||
|
};
|
||||||
|
/* Generates module init and exit that register and unregister
|
||||||
|
* microcontroller_driver.
|
||||||
|
*/
|
||||||
|
module_usb_driver(microcontroller_driver);
|
||||||
|
|
||||||
|
MODULE_LICENSE("GPL");
|
||||||
Binary file not shown.
@@ -0,0 +1 @@
|
|||||||
|
./main.o
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/export-internal.h>
|
||||||
|
#include <linux/compiler.h>
|
||||||
|
|
||||||
|
MODULE_INFO(name, KBUILD_MODNAME);
|
||||||
|
|
||||||
|
__visible struct module __this_module
|
||||||
|
__section(".gnu.linkonce.this_module") = {
|
||||||
|
.name = KBUILD_MODNAME,
|
||||||
|
.init = init_module,
|
||||||
|
#ifdef CONFIG_MODULE_UNLOAD
|
||||||
|
.exit = cleanup_module,
|
||||||
|
#endif
|
||||||
|
.arch = MODULE_ARCH_INIT,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
MODULE_INFO(depends, "");
|
||||||
|
|
||||||
|
MODULE_ALIAS("usb:v1234p5678d*dc*dsc*dp*ic*isc*ip*in*");
|
||||||
|
|
||||||
|
MODULE_INFO(srcversion, "263CD52FCADD9F48F0ABAB5");
|
||||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
|
|||||||
|
main.o
|
||||||
Reference in New Issue
Block a user