From 4388eceec011c570cf49adc6e36d70095949b615 Mon Sep 17 00:00:00 2001 From: nirenjan Date: Thu, 13 Aug 2020 03:17:35 -0700 Subject: [PATCH] Create workflow to build kernel module This workflow runs only if there is a change to the kernel_module path. Consequently, commits that only impact the kernel_module will be ignored for the standard userspace driver build. This commit also updates the CodeQL workflow to only run on a scheduled basis and on pull requests, but not on every push, since this is a fairly slow script. Finally, this commit also removes the obsolete kernel module sources, since they are no longer maintained, and it also provides a hook for Github actions to pick up and execute the kernel workflow. --- .../scripts/install-kernel-dependencies.sh | 4 + .github/workflows/build.yml | 2 + .github/workflows/codeql-analysis.yml | 5 +- .github/workflows/kernel.yml | 31 + README.md | 1 + kernel_module/x52joy.c | 600 ------------------ kernel_module/x52joy_commands.c | 266 -------- kernel_module/x52joy_commands.h | 76 --- kernel_module/x52joy_common.h | 80 --- kernel_module/x52joy_input.c | 243 ------- kernel_module/x52joy_map.h | 190 ------ 11 files changed, 39 insertions(+), 1459 deletions(-) create mode 100755 .github/scripts/install-kernel-dependencies.sh create mode 100644 .github/workflows/kernel.yml delete mode 100644 kernel_module/x52joy.c delete mode 100644 kernel_module/x52joy_commands.c delete mode 100644 kernel_module/x52joy_commands.h delete mode 100644 kernel_module/x52joy_common.h delete mode 100644 kernel_module/x52joy_input.c delete mode 100644 kernel_module/x52joy_map.h diff --git a/.github/scripts/install-kernel-dependencies.sh b/.github/scripts/install-kernel-dependencies.sh new file mode 100755 index 0000000..03a04c9 --- /dev/null +++ b/.github/scripts/install-kernel-dependencies.sh @@ -0,0 +1,4 @@ +#!/bin/bash +# Install dependencies to build kernel modules on Ubuntu runners +sudo apt-get update +sudo apt-get install -y linux-headers-$(uname -r) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ff065dd..e171c59 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -5,6 +5,8 @@ on: branches: - '*' - '!gh-pages' + paths-ignore: + - 'kernel_module/**' pull_request: branches: [ master ] diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 8e73e6d..ebd3648 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -1,17 +1,14 @@ name: "CodeQL" on: - push: - branches: ['*', '!gh-pages'] pull_request: # The branches below must be a subset of the branches above branches: [master] schedule: - - cron: '0 7 * * 1' + - cron: '30 7 * * 1,3,5' jobs: analyse: - if: "!(contains(github.event.head_commit.message, '[ci skip]') || contains(github.event.head_commit.message, '[skip ci]'))" name: Analyse runs-on: ubuntu-latest diff --git a/.github/workflows/kernel.yml b/.github/workflows/kernel.yml new file mode 100644 index 0000000..2a41262 --- /dev/null +++ b/.github/workflows/kernel.yml @@ -0,0 +1,31 @@ +name: Kernel Module + +on: + push: + branches: [ '*' ] + paths: + - 'kernel_module/**' + pull_request: + branches: [ master ] + +jobs: + build: + if: "!(contains(github.event.head_commit.message, '[ci skip]') || contains(github.event.head_commit.message, '[skip ci]'))" + name: ${{ matrix.os }} + runs-on: ${{ matrix.os }} + + strategy: + matrix: + os: ['ubuntu-16.04', 'ubuntu-18.04', 'ubuntu-20.04'] + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Install kernel dependencies + run: ./.github/scripts/install-kernel-dependencies.sh + + - name: Build kernel module + run: | + cd kernel_module + make diff --git a/README.md b/README.md index 17a69ce..c72cadc 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ Saitek X52Pro joystick driver for Linux ======================================= ![Build/Test](https://github.com/nirenjan/x52pro-linux/workflows/Build/Test/badge.svg) +![Kernel Module](https://github.com/nirenjan/x52pro-linux/workflows/Kernel%20Module/badge.svg) ![CodeQL](https://github.com/nirenjan/x52pro-linux/workflows/CodeQL/badge.svg) [![Join the chat at https://gitter.im/x52pro-linux/community](https://badges.gitter.im/x52pro-linux/community.svg)](https://gitter.im/x52pro-linux/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) diff --git a/kernel_module/x52joy.c b/kernel_module/x52joy.c deleted file mode 100644 index e470698..0000000 --- a/kernel_module/x52joy.c +++ /dev/null @@ -1,600 +0,0 @@ -/* - * Saitek X52 Pro HOTAS driver - * - * Copyright (C) 2012 Nirenjan Krishnan (nirenjan@nirenjan.org) - * - * 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. - * - * SPDX-License-Identifier: GPL-2.0-only - */ - -#ifdef CONFIG_USB_DEBUG - #define DEBUG 1 -#endif - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "x52joy_commands.h" -#include "x52joy_common.h" - -#define DRIVER_AUTHOR "Nirenjan Krishnan, nirenjan@gmail.com" -#define DRIVER_DESC "Saitek X52Pro HOTAS Driver" -#define DRIVER_VERSION "1.0" - -static const struct x52_device { - u16 idVendor; - u16 idProduct; - char *name; - u8 type; - u8 flags; -} x52_devices[] = { - { - VENDOR_ID_SAITEK, PRODUCT_ID_X52_PRO, - "Saitek X52 Pro Flight Control System", X52TYPE_X52PRO, - X52FLAGS_SUPPORTS_MFD | X52FLAGS_SUPPORTS_LED - }, - { /* Terminating entry */ - 0x0000, 0x0000, "Unknown X52", X52TYPE_UNKNOWN, 0 - }, -}; - -/* list of devices that work with this driver */ -static struct usb_device_id id_table[] = { - { USB_DEVICE(VENDOR_ID_SAITEK, PRODUCT_ID_X52_PRO) }, - /* - * Future versions of this driver may support the original - * X52 HOTAS joystick, but for now, only the X52 Pro is - * supported. - */ - { }, -}; -MODULE_DEVICE_TABLE (usb, id_table); - -#define CHECK_RETURN(ret, cnt) do { \ - if (ret) {\ - return ret;\ - } else {\ - return cnt;\ - }\ -} while(0) - -/********************************************************************** - * MFD Line manipulation functions - *********************************************************************/ -static ssize_t show_text_line(struct device *dev, char *buf, u8 line) -{ - struct usb_interface *intf = to_usb_interface(dev); - struct x52_joy *joy = usb_get_intfdata(intf); - - line--; /* Convert to 0-based line number */ - - if (joy->feat_mfd) { - return sprintf(buf, "%s\n", joy->line[line].text); - } else { - sprintf(buf, "\n"); - return -EOPNOTSUPP; - } - return 0; -} - -static ssize_t set_text_line(struct device *dev, const char *buf, - size_t count, u8 line) -{ - struct usb_interface *intf = to_usb_interface(dev); - struct x52_joy *joy = usb_get_intfdata(intf); - u16 i; - u16 length; - int retval; - - if (!joy->feat_mfd) { - return -EOPNOTSUPP; - } - - line--; /* Convert to 0-based line number */ - - /* Copy the string from src to dst, upto 16 characters max */ - for (i = 0, length = 0; i < X52_MFD_LINE_SIZE && i < count; i++, length++) { - joy->line[line].text[i] = buf[i]; - } - joy->line[line].length = length; - - /* Append empty bytes until the destination is full */ - for ( ; i < X52_MFD_LINE_SIZE; i++) { - /* The X52 pro MFD uses space characters as empty characters */ - joy->line[line].text[i] = 32; - } - - retval = set_text(joy, line); - - CHECK_RETURN(retval, count); -} - - -#define show_set_text(no) \ -static ssize_t show_text_line##no(struct device *dev, struct device_attribute *attr, char *buf) \ -{ \ - return show_text_line(dev, buf, no); \ -} \ -static ssize_t set_text_line##no(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \ -{ \ - return set_text_line(dev, buf, count, no); \ -} \ -static DEVICE_ATTR(mfd_line##no, S_IWUSR | S_IWGRP | S_IRUGO, show_text_line##no, set_text_line##no); - -show_set_text(1); -show_set_text(2); -show_set_text(3); - -/********************************************************************** - * Brightness manipulation functions - *********************************************************************/ -#define mfd 0 -#define led 1 - -static int to_hex(const char c) -{ - /* Converts a single character to hex */ - if (c >= '0' && c <= '9') { - return (c - '0'); - } else if (c >= 'A' && c <= 'F') { - return (c - 'A' + 10); - } else if (c >= 'a' && c <= 'f') { - return (c - 'a' + 10); - } - return -1; -} - -static ssize_t set_x52_brightness(struct device *dev, const char *buf, - size_t count, u8 target) -{ - u16 bri; - u16 ch; - int retval; - struct usb_interface *intf = to_usb_interface(dev); - struct x52_joy *joy = usb_get_intfdata(intf); - - if (target >= 2 || count != 4 || buf[0] != '0' || - ((buf[1] | 0x20) != 'x')) { - /* Just some sanity checking */ - return -EOPNOTSUPP; - } - - bri = 0; - ch = to_hex(buf[2]); - if (ch >= 0) { - bri |= ch; - bri <<= 4; - } else { - return -EOPNOTSUPP; - } - ch = to_hex(buf[3]); - if (ch >= 0) { - bri |= ch; - } else { - return -EOPNOTSUPP; - } - - if (bri > 0x80) { - return -EOPNOTSUPP; - } - - if (target == mfd) { - ch = X52_MFD_BRIGHTNESS; - joy->bri_mfd = bri; - } else { - ch = X52_LED_BRIGHTNESS; - joy->bri_led = bri; - } - - retval = set_brightness(joy, target); - - CHECK_RETURN(retval, count); -} - -static ssize_t show_brightness(struct device *dev, char *buf, u8 target) -{ - struct usb_interface *intf = to_usb_interface(dev); - struct x52_joy *joy = usb_get_intfdata(intf); - - if (target == mfd) { - if (joy->feat_mfd) { - return sprintf(buf, "0x%02x\n", joy->bri_mfd); - } - } else if (target == led) { - if (joy->feat_led) { - return sprintf(buf, "0x%02x\n", joy->bri_led); - } - } - - sprintf(buf, "\n"); - return -EOPNOTSUPP; -} - -static ssize_t show_bri_mfd (struct device *dev, struct device_attribute *attr, char *buf) -{ - return show_brightness(dev, buf, mfd); -} -static ssize_t set_bri_mfd (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) -{ - return set_x52_brightness(dev, buf, count, mfd); -} -static ssize_t show_bri_led (struct device *dev, struct device_attribute *attr, char *buf) -{ - return show_brightness(dev, buf, led); -} -static ssize_t set_bri_led (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) -{ - return set_x52_brightness(dev, buf, count, led); -} -static DEVICE_ATTR(bri_mfd, S_IWUSR | S_IWGRP | S_IRUGO, show_bri_mfd, set_bri_mfd); -static DEVICE_ATTR(bri_led, S_IWUSR | S_IWGRP | S_IRUGO, show_bri_led, set_bri_led); - -#undef mfd -#undef led - -/********************************************************************** - * LED manipulation functions - *********************************************************************/ - -#define fire X52_LED_FIRE -#define a_red X52_LED_A_RED -#define a_green X52_LED_A_GREEN -#define b_red X52_LED_B_RED -#define b_green X52_LED_B_GREEN -#define d_red X52_LED_D_RED -#define d_green X52_LED_D_GREEN -#define e_red X52_LED_E_RED -#define e_green X52_LED_E_GREEN -#define t1_red X52_LED_T1_RED -#define t1_green X52_LED_T1_GREEN -#define t2_red X52_LED_T2_RED -#define t2_green X52_LED_T2_GREEN -#define t3_red X52_LED_T3_RED -#define t3_green X52_LED_T3_GREEN -#define pov_red X52_LED_POV_RED -#define pov_green X52_LED_POV_GREEN -#define i_red X52_LED_I_RED -#define i_green X52_LED_I_GREEN -#define throttle X52_LED_THROTTLE - -static ssize_t set_x52_led(struct device *dev, const char *buf, - size_t count, u8 target) -{ - u8 status; - int retval; - struct usb_interface *intf = to_usb_interface(dev); - struct x52_joy *joy = usb_get_intfdata(intf); - - if (target > X52_LED_THROTTLE || count < 1 || buf[0] < '0' || - buf[0] > '1') { - /* Just some sanity checking */ - return -EOPNOTSUPP; - } - - status = buf[0] - '0'; - - if (status) { - joy->led_status |= (1 << target); - } else { - joy->led_status &= ~(1 << target); - } - - retval = set_led(joy, target); - - CHECK_RETURN(retval, count); -} - -static ssize_t show_led(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct usb_interface *intf = to_usb_interface(dev); - struct x52_joy *joy = usb_get_intfdata(intf); - - if (joy->feat_led) { - return sprintf(buf, "0x%08x\n", joy->led_status); - } - - sprintf(buf, "\n"); - return -EOPNOTSUPP; -} - -#define show_set_led(no) \ -static ssize_t set_led_##no(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \ -{ \ - return set_x52_led(dev, buf, count, no); \ -} \ -static DEVICE_ATTR(led_##no, S_IWUSR | S_IWGRP | S_IRUGO, show_led, set_led_##no); - -show_set_led(fire); -show_set_led(a_red); -show_set_led(a_green); -show_set_led(b_red); -show_set_led(b_green); -show_set_led(d_red); -show_set_led(d_green); -show_set_led(e_red); -show_set_led(e_green); -show_set_led(t1_red); -show_set_led(t1_green); -show_set_led(t2_red); -show_set_led(t2_green); -show_set_led(t3_red); -show_set_led(t3_green); -show_set_led(pov_red); -show_set_led(pov_green); -show_set_led(i_red); -show_set_led(i_green); -show_set_led(throttle); - -/********************************************************************** - * Blink manipulation functions - *********************************************************************/ -static ssize_t show_blink(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct usb_interface *intf = to_usb_interface(dev); - struct x52_joy *joy = usb_get_intfdata(intf); - - if (joy->feat_led) { - return sprintf(buf, "%d\n", joy->blink_led); - } else { - sprintf(buf, "\n"); - return -EOPNOTSUPP; - } - return 0; -} - -static ssize_t set_x52_blink(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct usb_interface *intf = to_usb_interface(dev); - struct x52_joy *joy = usb_get_intfdata(intf); - int retval; - - if (!joy->feat_led) { - return -EOPNOTSUPP; - } - - if (count < 1 || buf[0] < '0' || buf[1] > '1') { - return -EINVAL; - } - - joy->blink_led = buf[0] - '0'; - - retval = set_blink(joy); - - CHECK_RETURN(retval, count); -} - - -static DEVICE_ATTR(led_blink, S_IWUSR | S_IWGRP | S_IRUGO, show_blink, set_x52_blink); - -/********************************************************************** - * X52 driver functions - *********************************************************************/ -static int x52_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - struct usb_device *udev = interface_to_usbdev(intf); - struct x52_joy *joy = NULL; - struct input_dev *idev = NULL; - struct usb_endpoint_descriptor *ep_irq_in; - int retval = -ENOMEM; - int i; - - for (i = 0; x52_devices[i].idVendor; i++) { - if ((le16_to_cpu(udev->descriptor.idVendor) == x52_devices[i].idVendor) && - (le16_to_cpu(udev->descriptor.idProduct) == x52_devices[i].idProduct)) { - break; - } - } - - joy = kzalloc(sizeof(*joy), GFP_KERNEL); - if (joy == NULL) { - dev_err(&intf->dev, "Out of memory: Cannot create joystick\n"); - goto error; - } - joy->type = x52_devices[i].type; - - idev = input_allocate_device(); - if (idev == NULL) { - dev_err(&intf->dev, "Out of memory: Cannot create input\n"); - goto error; - } - - joy->idata = usb_alloc_coherent(udev, X52_PACKET_LEN, GFP_KERNEL, - &joy->idata_dma); - if (!joy->idata) { - dev_err(&intf->dev, "Out of memory: Cannot alloc coherent buffer\n"); - goto error; - } - - joy->irq_in = usb_alloc_urb(0, GFP_KERNEL); - if (!joy->irq_in) { - dev_err(&intf->dev, "Out of memory: Cannot alloc IRQ URB\n"); - goto error1; - } - - joy->udev = usb_get_dev(udev); - - joy->idev = idev; - usb_make_path(udev, joy->phys, sizeof(joy->phys)); - strlcat(joy->phys, "/input0", sizeof(joy->phys)); - - idev->name = x52_devices[i].name; - idev->phys = joy->phys; - usb_to_input_id(udev, &idev->id); - idev->dev.parent = &intf->dev; - - input_set_drvdata(idev, joy); - - idev->open = x52_open; - idev->close = x52_close; - - x52_setup_input(idev); - - ep_irq_in = &intf->cur_altsetting->endpoint[0].desc; - usb_fill_int_urb(joy->irq_in, udev, - usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress), - joy->idata, X52_PACKET_LEN, x52_irq_handler, - joy, ep_irq_in->bInterval); - joy->irq_in->transfer_dma = joy->idata_dma; - joy->irq_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - - retval = input_register_device(joy->idev); - if (retval) { - goto error2; - } - - /* Set the feature bits */ - joy->feat_mfd = !!(x52_devices[i].flags & X52FLAGS_SUPPORTS_MFD); - joy->feat_led = !!(x52_devices[i].flags & X52FLAGS_SUPPORTS_LED); - - usb_set_intfdata(intf, joy); - - if (joy->feat_mfd) { - device_create_file(&intf->dev, &dev_attr_mfd_line1); - device_create_file(&intf->dev, &dev_attr_mfd_line2); - device_create_file(&intf->dev, &dev_attr_mfd_line3); - - device_create_file(&intf->dev, &dev_attr_bri_mfd); - } - - if (joy->feat_led) { - device_create_file(&intf->dev, &dev_attr_bri_led); - - device_create_file(&intf->dev, &dev_attr_led_fire); - device_create_file(&intf->dev, &dev_attr_led_a_red); - device_create_file(&intf->dev, &dev_attr_led_a_green); - device_create_file(&intf->dev, &dev_attr_led_b_red); - device_create_file(&intf->dev, &dev_attr_led_b_green); - device_create_file(&intf->dev, &dev_attr_led_d_red); - device_create_file(&intf->dev, &dev_attr_led_d_green); - device_create_file(&intf->dev, &dev_attr_led_e_red); - device_create_file(&intf->dev, &dev_attr_led_e_green); - device_create_file(&intf->dev, &dev_attr_led_t1_red); - device_create_file(&intf->dev, &dev_attr_led_t1_green); - device_create_file(&intf->dev, &dev_attr_led_t2_red); - device_create_file(&intf->dev, &dev_attr_led_t2_green); - device_create_file(&intf->dev, &dev_attr_led_t3_red); - device_create_file(&intf->dev, &dev_attr_led_t3_green); - device_create_file(&intf->dev, &dev_attr_led_pov_red); - device_create_file(&intf->dev, &dev_attr_led_pov_green); - device_create_file(&intf->dev, &dev_attr_led_i_red); - device_create_file(&intf->dev, &dev_attr_led_i_green); - device_create_file(&intf->dev, &dev_attr_led_throttle); - - device_create_file(&intf->dev, &dev_attr_led_blink); - } - - try_module_get(THIS_MODULE); - - dev_info(&intf->dev, "X52 device now attached\n"); - return 0; - -error2: - usb_free_urb(joy->irq_in); -error1: - usb_free_coherent(udev, X52_PACKET_LEN, joy->idata, joy->idata_dma); -error: - input_free_device(idev); - kfree(joy); - return retval; -} - -static void x52_disconnect(struct usb_interface *intf) -{ - struct x52_joy *joy; - - joy = usb_get_intfdata(intf); - usb_set_intfdata(intf, NULL); - - usb_kill_urb(joy->irq_in); - usb_free_urb(joy->irq_in); - usb_free_coherent(joy->udev, X52_PACKET_LEN, joy->idata, joy->idata_dma); - input_free_device(joy->idev); - - if (joy->feat_mfd) { - device_remove_file(&intf->dev, &dev_attr_mfd_line1); - device_remove_file(&intf->dev, &dev_attr_mfd_line2); - device_remove_file(&intf->dev, &dev_attr_mfd_line3); - - device_remove_file(&intf->dev, &dev_attr_bri_mfd); - } - - if (joy->feat_led) { - device_remove_file(&intf->dev, &dev_attr_bri_led); - - device_remove_file(&intf->dev, &dev_attr_led_fire); - device_remove_file(&intf->dev, &dev_attr_led_a_red); - device_remove_file(&intf->dev, &dev_attr_led_a_green); - device_remove_file(&intf->dev, &dev_attr_led_b_red); - device_remove_file(&intf->dev, &dev_attr_led_b_green); - device_remove_file(&intf->dev, &dev_attr_led_d_red); - device_remove_file(&intf->dev, &dev_attr_led_d_green); - device_remove_file(&intf->dev, &dev_attr_led_e_red); - device_remove_file(&intf->dev, &dev_attr_led_e_green); - device_remove_file(&intf->dev, &dev_attr_led_t1_red); - device_remove_file(&intf->dev, &dev_attr_led_t1_green); - device_remove_file(&intf->dev, &dev_attr_led_t2_red); - device_remove_file(&intf->dev, &dev_attr_led_t2_green); - device_remove_file(&intf->dev, &dev_attr_led_t3_red); - device_remove_file(&intf->dev, &dev_attr_led_t3_green); - device_remove_file(&intf->dev, &dev_attr_led_pov_red); - device_remove_file(&intf->dev, &dev_attr_led_pov_green); - device_remove_file(&intf->dev, &dev_attr_led_i_red); - device_remove_file(&intf->dev, &dev_attr_led_i_green); - device_remove_file(&intf->dev, &dev_attr_led_throttle); - - device_remove_file(&intf->dev, &dev_attr_led_blink); - } - - usb_put_dev(joy->udev); - kfree(joy); - - module_put(THIS_MODULE); - - dev_info(&intf->dev, "X52 device now disconnected\n"); -} - -static struct usb_driver x52_driver = { - .name = "saitek_x52", - .probe = x52_probe, - .disconnect = x52_disconnect, - .id_table = id_table, -}; - -static int __init x52_init(void) -{ - int retval = 0; - - retval = usb_register(&x52_driver); - if (retval) { - pr_err("usb_register failed (errno=%d)\n", retval); - } - - return retval; -} - -static void __exit x52_exit(void) -{ - usb_deregister(&x52_driver); -} - -module_init (x52_init); -module_exit (x52_exit); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_VERSION(DRIVER_VERSION); -MODULE_LICENSE("GPL v2"); - diff --git a/kernel_module/x52joy_commands.c b/kernel_module/x52joy_commands.c deleted file mode 100644 index aed2311..0000000 --- a/kernel_module/x52joy_commands.c +++ /dev/null @@ -1,266 +0,0 @@ -/* - * Saitek X52 Pro HOTAS driver - * - * Copyright (C) 2012 Nirenjan Krishnan (nirenjan@nirenjan.org) - * - * 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. - * - * SPDX-License-Identifier: GPL-2.0-only - */ - -#ifdef CONFIG_USB_DEBUG - #define DEBUG 1 -#endif - -#include -#include -#include -#include -#include -#include - -#include "x52joy_commands.h" -#include "x52joy_common.h" - -/********************************************************************** - * MFD Line manipulation functions - *********************************************************************/ -static const u8 line_cmd[X52_MFD_LINES] = { - X52_MFD_LINE1, - X52_MFD_LINE2, - X52_MFD_LINE3, -}; - -int set_text(struct x52_joy *joy, u8 line_no) -{ - u16 i; - u16 ch; - u16 length; - char *text_ptr; - int retval; - - if (!joy || line_no >= X52_MFD_LINES) { - /* Just some sanity checking */ - return -EINVAL; - } - - /* Clear the line first */ - retval = usb_control_msg(joy->udev, - usb_sndctrlpipe(joy->udev, 0), - X52_VENDOR_REQUEST, - USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, - 0x00, - line_cmd[line_no] | X52_MFD_CLEAR_LINE, - NULL, 0, 1000); - if (retval) { - return retval; - } - - length = joy->line[line_no].length; - - for (i = 0; i < X52_MFD_LINE_SIZE && i < length; i+= 2) { - text_ptr = &joy->line[line_no].text[i]; - if (length - i > 1) { - ch = *(u16 *)text_ptr; - } else { - ch = (*text_ptr) + (0x20 << 8); - } - - retval = usb_control_msg(joy->udev, - usb_sndctrlpipe(joy->udev, 0), - X52_VENDOR_REQUEST, - USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, - ch, - line_cmd[line_no] | X52_MFD_WRITE_LINE, - NULL, 0, 1000); - if (retval) { - return retval; - } - } - - return 0; -} - -/********************************************************************** - * Brightness manipulation functions - *********************************************************************/ -int set_brightness(struct x52_joy *joy, u8 target) -{ - u16 bri; - u8 ch; - int retval; - - if (!joy || target > 1) { - /* Just some sanity checking */ - return -EINVAL; - } - - if (target == 0) { // MFD - ch = X52_MFD_BRIGHTNESS; - bri = joy->bri_mfd; - } else { // LED - ch = X52_LED_BRIGHTNESS; - bri = joy->bri_led; - } - - if (bri > 0x80) { - return -EOPNOTSUPP; - } - - retval = usb_control_msg(joy->udev, - usb_sndctrlpipe(joy->udev, 0), - X52_VENDOR_REQUEST, - USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, - bri, ch, - NULL, 0, 1000); - return retval; -} - -/********************************************************************** - * LED manipulation functions - *********************************************************************/ -int set_led(struct x52_joy *joy, u8 target) -{ - int retval; - u8 status; - - if (!joy || target > X52_LED_THROTTLE) { - /* Just some sanity checking */ - return -EINVAL; - } - - status = (u8)((joy->led_status >> target) & 1); - - retval = usb_control_msg(joy->udev, - usb_sndctrlpipe(joy->udev, 0), - X52_VENDOR_REQUEST, - USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, - target << 8 | status, X52_LED, - NULL, 0, 1000); - return retval; -} - -/********************************************************************** - * Date manipulation functions - *********************************************************************/ -int set_date(struct x52_joy *joy) -{ - int retval; - u16 ddmm; - u16 yy; - - if (!joy) { - /* Just some sanity checking */ - return -EINVAL; - } - - /* - * The X52 Pro MFD expects the date to be stored as DD-MM-YY. - * However, by tweaking the USB control messages, we can display - * in any format we choose. - */ - if (joy->date.format >= x52_mfd_format_max) { - return -EOPNOTSUPP; - } - - switch (joy->date.format) { - case x52_mfd_format_yymmdd: - yy = joy->date.day; - ddmm = (joy->date.year << 8) | joy->date.month; - break; - - case x52_mfd_format_mmddyy: - yy = joy->date.year; - ddmm = (joy->date.day << 8) | joy->date.month; - break; - - case x52_mfd_format_ddmmyy: - yy = joy->date.year; - ddmm = (joy->date.month << 8) | joy->date.day; - break; - - default: - return -EOPNOTSUPP; - } - - retval = usb_control_msg(joy->udev, - usb_sndctrlpipe(joy->udev, 0), - X52_VENDOR_REQUEST, - USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, - ddmm, X52_DATE_DDMM, - NULL, 0, 1000); - retval = usb_control_msg(joy->udev, - usb_sndctrlpipe(joy->udev, 0), - X52_VENDOR_REQUEST, - USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, - yy, X52_DATE_YEAR, - NULL, 0, 1000); - return retval; -} - -/********************************************************************** - * Shift manipulation functions - *********************************************************************/ -int set_shift(struct x52_joy *joy) -{ - int retval; - int val; - - if (!joy) { - /* Just some sanity checking */ - return -EINVAL; - } - - if (!joy->feat_mfd) { - return -EOPNOTSUPP; - } - - if (joy->shift_ind) { - val = X52_SHIFT_ON; - } else { - val = X52_SHIFT_OFF; - } - - retval = usb_control_msg(joy->udev, - usb_sndctrlpipe(joy->udev, 0), - X52_VENDOR_REQUEST, - USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, - val, X52_SHIFT_INDICATOR, - NULL, 0, 1000); - return retval; -} - -/********************************************************************** - * Blink manipulation functions - *********************************************************************/ -int set_blink(struct x52_joy *joy) -{ - int retval; - int val; - - if (!joy) { - /* Just some sanity checking */ - return -EINVAL; - } - - if (!joy->feat_led) { - return -EOPNOTSUPP; - } - - if (joy->blink_led) { - val = X52_BLINK_ON; - } else { - val = X52_BLINK_OFF; - } - - retval = usb_control_msg(joy->udev, - usb_sndctrlpipe(joy->udev, 0), - X52_VENDOR_REQUEST, - USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, - val, X52_BLINK_INDICATOR, - NULL, 0, 1000); - return retval; -} - diff --git a/kernel_module/x52joy_commands.h b/kernel_module/x52joy_commands.h deleted file mode 100644 index a6d2395..0000000 --- a/kernel_module/x52joy_commands.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Saitek X52 Pro HOTAS driver - * - * Copyright (C) 2012 Nirenjan Krishnan (nirenjan@nirenjan.org) - * - * 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. - * - * SPDX-License-Identifier: GPL-2.0-only - */ - -#ifndef X52JOY_COMMANDS_H -#define X52JOY_COMMANDS_H - -/* X52 vendor API commands */ -/* Vendor request - all commands must have this request ID */ -#define X52_VENDOR_REQUEST 0x91 - -/* MFD Text commands */ -#define X52_MFD_CLEAR_LINE 0x08 -#define X52_MFD_WRITE_LINE 0x00 - -#define X52_MFD_LINE1 0xd1 -#define X52_MFD_LINE2 0xd2 -#define X52_MFD_LINE3 0xd4 - -/* Brightness commands */ -#define X52_MFD_BRIGHTNESS 0xb1 -#define X52_LED_BRIGHTNESS 0xb2 - -/* LED set commands */ -#define X52_LED 0xb8 - -/* Time commands */ -#define X52_TIME_CLOCK1 0xc0 -#define X52_OFFS_CLOCK2 0xc1 -#define X52_OFFS_CLOCK3 0xc2 - -/* Date commands */ -#define X52_DATE_DDMM 0xc4 -#define X52_DATE_YEAR 0xc8 - -/* Shift indicator on MFD */ -#define X52_SHIFT_INDICATOR 0xfd -#define X52_SHIFT_ON 0x51 -#define X52_SHIFT_OFF 0x50 - -/* Blink throttle & POV LED */ -#define X52_BLINK_INDICATOR 0xb4 -#define X52_BLINK_ON 0x51 -#define X52_BLINK_OFF 0x50 - -/* LED indices */ -#define X52_LED_FIRE 0x01 -#define X52_LED_A_RED 0x02 -#define X52_LED_A_GREEN 0x03 -#define X52_LED_B_RED 0x04 -#define X52_LED_B_GREEN 0x05 -#define X52_LED_D_RED 0x06 -#define X52_LED_D_GREEN 0x07 -#define X52_LED_E_RED 0x08 -#define X52_LED_E_GREEN 0x09 -#define X52_LED_T1_RED 0x0a -#define X52_LED_T1_GREEN 0x0b -#define X52_LED_T2_RED 0x0c -#define X52_LED_T2_GREEN 0x0d -#define X52_LED_T3_RED 0x0e -#define X52_LED_T3_GREEN 0x0f -#define X52_LED_POV_RED 0x10 -#define X52_LED_POV_GREEN 0x11 -#define X52_LED_I_RED 0x12 -#define X52_LED_I_GREEN 0x13 -#define X52_LED_THROTTLE 0x14 - -#endif /* !defined X52JOY_COMMANDS_H */ diff --git a/kernel_module/x52joy_common.h b/kernel_module/x52joy_common.h deleted file mode 100644 index 4d2b018..0000000 --- a/kernel_module/x52joy_common.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Saitek X52 Pro HOTAS driver - * - * Copyright (C) 2012 Nirenjan Krishnan (nirenjan@nirenjan.org) - * - * 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. - * - * SPDX-License-Identifier: GPL-2.0-only - */ - -#ifndef X52JOY_COMMON_H -#define X52JOY_COMMON_H - -#include -#include - -#include "x52joy_map.h" - -struct x52_joy { - struct usb_device *udev; - struct urb *irq_in; - unsigned char *idata; - dma_addr_t idata_dma; - struct input_dev *idev; - char phys[64]; - - u32 led_status; - struct x52_mfd_line line[X52_MFD_LINES]; - struct x52_mfd_date date; - struct x52_mfd_time time; - struct x52_mfd_offs time_offs2; - struct x52_mfd_offs time_offs3; - - u8 type; - u8 bri_mfd; - u8 bri_led; - - u8 shift_ind:1; - u8 blink_led:1; - u8 clutch_mode:1; - - u8 shift_state_enabled:1; - u8 clock_enabled:1; - u8 clutch_enabled:1; - u8 clutch_latched:1; - u8 :1; - - u8 feat_mfd:1; - u8 feat_led:1; - u8 debug:1; - u8 :5; -}; - -#define X52_PACKET_LEN 16 - -#define X52TYPE_X52 1 -#define X52TYPE_X52PRO 2 -#define X52TYPE_UNKNOWN 0 - -#define VENDOR_ID_SAITEK 0x06a3 -#define PRODUCT_ID_X52_PRO 0x0762 - -#define X52FLAGS_SUPPORTS_MFD (1 << 0) -#define X52FLAGS_SUPPORTS_LED (1 << 1) - -int set_text(struct x52_joy *joy, u8 line_no); -int set_brightness(struct x52_joy *joy, u8 target); -int set_led(struct x52_joy *joy, u8 target); -int set_date(struct x52_joy *joy); -int set_shift(struct x52_joy *joy); -int set_blink(struct x52_joy *joy); - -void x52_irq_handler(struct urb *urb); -void x52_setup_input(struct input_dev *idev); -int x52_open (struct input_dev *idev); -void x52_close (struct input_dev *idev); - -#endif /* !defined X52JOY_COMMON_H */ diff --git a/kernel_module/x52joy_input.c b/kernel_module/x52joy_input.c deleted file mode 100644 index 13bfaca..0000000 --- a/kernel_module/x52joy_input.c +++ /dev/null @@ -1,243 +0,0 @@ -/* - * Saitek X52 Pro HOTAS driver - * - * Copyright (C) 2012 Nirenjan Krishnan (nirenjan@nirenjan.org) - * - * 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. - * - * SPDX-License-Identifier: GPL-2.0-only - */ - -#ifdef CONFIG_USB_DEBUG - #define DEBUG 1 -#endif - -#include -#include - -#include "x52joy_commands.h" -#include "x52joy_common.h" - -#define X52PRO_X_SHIFT 0 -#define X52PRO_X_MASK 0x3ff -#define X52PRO_Y_SHIFT 10 -#define X52PRO_Y_MASK 0x3ff -#define X52PRO_RZ_SHIFT 20 -#define X52PRO_RZ_MASK 0x3ff - -static void x52pro_decode_urb(struct x52_joy *joy, unsigned char *data) -{ - struct input_dev *idev = joy->idev; - u32 stick_axis = data[3]; - stick_axis = (stick_axis << 8) | data[2]; - stick_axis = (stick_axis << 8) | data[1]; - stick_axis = (stick_axis << 8) | data[0]; - - input_report_key(idev, BTN_TRIGGER_HAPPY1, data[8] & 0x01); - input_report_key(idev, BTN_TRIGGER_HAPPY2, data[8] & 0x02); - input_report_key(idev, BTN_TRIGGER_HAPPY3, data[8] & 0x04); - input_report_key(idev, BTN_TRIGGER_HAPPY4, data[8] & 0x08); - input_report_key(idev, BTN_TRIGGER_HAPPY5, data[8] & 0x10); - input_report_key(idev, BTN_TRIGGER_HAPPY6, data[8] & 0x20); - input_report_key(idev, BTN_TRIGGER_HAPPY7, data[8] & 0x40); - input_report_key(idev, BTN_TRIGGER_HAPPY8, data[8] & 0x80); - - input_report_key(idev, BTN_TRIGGER_HAPPY9, data[9] & 0x01); - input_report_key(idev, BTN_TRIGGER_HAPPY10, data[9] & 0x02); - input_report_key(idev, BTN_TRIGGER_HAPPY11, data[9] & 0x04); - input_report_key(idev, BTN_TRIGGER_HAPPY12, data[9] & 0x08); - input_report_key(idev, BTN_TRIGGER_HAPPY13, data[9] & 0x10); - input_report_key(idev, BTN_TRIGGER_HAPPY14, data[9] & 0x20); - input_report_key(idev, BTN_TRIGGER_HAPPY15, data[9] & 0x40); - input_report_key(idev, BTN_TRIGGER_HAPPY16, data[9] & 0x80); - - input_report_key(idev, BTN_TRIGGER_HAPPY17, data[10] & 0x01); - input_report_key(idev, BTN_TRIGGER_HAPPY18, data[10] & 0x02); - input_report_key(idev, BTN_TRIGGER_HAPPY19, data[10] & 0x04); - input_report_key(idev, BTN_TRIGGER_HAPPY20, data[10] & 0x08); - input_report_key(idev, BTN_TRIGGER_HAPPY21, data[10] & 0x10); - input_report_key(idev, BTN_TRIGGER_HAPPY22, data[10] & 0x20); - input_report_key(idev, BTN_TRIGGER_HAPPY23, data[10] & 0x40); - input_report_key(idev, BTN_TRIGGER_HAPPY24, data[10] & 0x80); - - input_report_key(idev, BTN_TRIGGER_HAPPY25, data[11] & 0x01); - input_report_key(idev, BTN_TRIGGER_HAPPY26, data[11] & 0x02); - input_report_key(idev, BTN_TRIGGER_HAPPY27, data[11] & 0x04); - input_report_key(idev, BTN_TRIGGER_HAPPY28, data[11] & 0x08); - input_report_key(idev, BTN_TRIGGER_HAPPY29, data[11] & 0x10); - input_report_key(idev, BTN_TRIGGER_HAPPY30, data[11] & 0x20); - input_report_key(idev, BTN_TRIGGER_HAPPY31, data[11] & 0x40); - input_report_key(idev, BTN_TRIGGER_HAPPY32, data[11] & 0x80); - - input_report_key(idev, BTN_TRIGGER_HAPPY33, data[12] & 0x01); - input_report_key(idev, BTN_TRIGGER_HAPPY34, data[12] & 0x02); - input_report_key(idev, BTN_TRIGGER_HAPPY35, data[12] & 0x04); - input_report_key(idev, BTN_TRIGGER_HAPPY36, data[12] & 0x08); - input_report_key(idev, BTN_TRIGGER_HAPPY37, data[12] & 0x10); - input_report_key(idev, BTN_TRIGGER_HAPPY38, data[12] & 0x20); - input_report_key(idev, BTN_TRIGGER_HAPPY39, data[12] & 0x40); - - input_report_abs(idev, ABS_X, - (stick_axis >> X52PRO_X_SHIFT) & X52PRO_X_MASK); - input_report_abs(idev, ABS_Y, - (stick_axis >> X52PRO_Y_SHIFT) & X52PRO_Y_MASK); - input_report_abs(idev, ABS_RZ, - (stick_axis >> X52PRO_RZ_SHIFT) & X52PRO_RZ_MASK); - - input_report_abs(idev, ABS_THROTTLE, data[4]); - input_report_abs(idev, ABS_RX, data[5]); - input_report_abs(idev, ABS_RY, data[6]); - input_report_abs(idev, ABS_Z, data[7]); - - input_report_abs(idev, ABS_TILT_X, data[14] & 0xF); - input_report_abs(idev, ABS_TILT_Y, data[14] >> 4); - - switch(data[13]) { - case 0x00: - input_report_abs(idev, ABS_HAT0X, 0); - input_report_abs(idev, ABS_HAT0Y, 0); - break; - case 0x10: - input_report_abs(idev, ABS_HAT0X, 0); - input_report_abs(idev, ABS_HAT0Y, -1); - break; - case 0x20: - input_report_abs(idev, ABS_HAT0X, 1); - input_report_abs(idev, ABS_HAT0Y, -1); - break; - case 0x30: - input_report_abs(idev, ABS_HAT0X, 1); - input_report_abs(idev, ABS_HAT0Y, 0); - break; - case 0x40: - input_report_abs(idev, ABS_HAT0X, 1); - input_report_abs(idev, ABS_HAT0Y, 1); - break; - case 0x50: - input_report_abs(idev, ABS_HAT0X, 0); - input_report_abs(idev, ABS_HAT0Y, 1); - break; - case 0x60: - input_report_abs(idev, ABS_HAT0X, -1); - input_report_abs(idev, ABS_HAT0Y, 1); - break; - case 0x70: - input_report_abs(idev, ABS_HAT0X, -1); - input_report_abs(idev, ABS_HAT0Y, 0); - break; - case 0x80: - input_report_abs(idev, ABS_HAT0X, -1); - input_report_abs(idev, ABS_HAT0Y, -1); - break; - } - - input_sync(idev); -} - -void x52_irq_handler(struct urb *urb) -{ - struct x52_joy *joy = urb->context; - int retval, status; - - status = urb->status; - - switch (status) { - case 0: - /* success */ - break; - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - /* This URB is terminated, clean up */ - dev_dbg(joy->idev->dev.parent, - "%s - URB shutting down with status: %d", - __func__, status); - return; - default: - dev_dbg(joy->idev->dev.parent, - "%s - nonzero URB status received: %d", - __func__, status); - goto error; - } - - switch (joy->type) { - case X52TYPE_X52PRO: - x52pro_decode_urb(joy, joy->idata); - break; - case X52TYPE_X52: - break; - default: - break; - } - -error: - retval = usb_submit_urb(urb, GFP_ATOMIC); - if (retval) - dev_err(joy->idev->dev.parent, - "%s - usb_submit_urb failed with result %d", - __func__, retval); - -} - -void x52_setup_input(struct input_dev *idev) -{ - int i; - - if (!idev) { - return; - } - - /* - * Enable event inputs. - * - * EV_KEY for buttons (and keyboard events in the future) - * EV_ABS for the axis - * EV_REL for future mouse support by the mouse stick - */ - idev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); - - /* For now, map the buttons directly */ - for (i = BTN_TRIGGER_HAPPY1; i <= BTN_TRIGGER_HAPPY39; i++) { - __set_bit(i, idev->keybit); - } - - /* Map the axes */ - input_set_abs_params(idev, ABS_X, 0, 1023, 0, 0); - input_set_abs_params(idev, ABS_Y, 0, 1023, 0, 0); - input_set_abs_params(idev, ABS_RZ, 0, 1023, 0, 0); - - input_set_abs_params(idev, ABS_THROTTLE, 0, 255, 0, 0); - input_set_abs_params(idev, ABS_RX, 0, 255, 0, 0); - input_set_abs_params(idev, ABS_RY, 0, 255, 0, 0); - input_set_abs_params(idev, ABS_Z, 0, 255, 0, 0); - - /* Mouse stick */ - input_set_abs_params(idev, ABS_TILT_X, 0, 15, 0, 0); - input_set_abs_params(idev, ABS_TILT_Y, 0, 15, 0, 0); - - /* Hat switch */ - input_set_abs_params(idev, ABS_HAT0X, -1, 1, 0, 0); - input_set_abs_params(idev, ABS_HAT0Y, -1, 1, 0, 0); -} - -int x52_open (struct input_dev *idev) -{ - struct x52_joy *joy = input_get_drvdata(idev); - - joy->irq_in->dev = joy->udev; - if (usb_submit_urb(joy->irq_in, GFP_KERNEL)) { - return -EIO; - } - - return 0; -} - -void x52_close (struct input_dev *idev) -{ - struct x52_joy *joy = input_get_drvdata(idev); - - usb_kill_urb(joy->irq_in); -} - diff --git a/kernel_module/x52joy_map.h b/kernel_module/x52joy_map.h deleted file mode 100644 index 18204a3..0000000 --- a/kernel_module/x52joy_map.h +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Saitek X52 Pro HOTAS driver - * - * Copyright (C) 2012 Nirenjan Krishnan (nirenjan@nirenjan.org) - * - * 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. - * - * SPDX-License-Identifier: GPL-2.0-only - */ - -#ifndef X52JOY_MAP_H -#define X52JOY_MAP_H - -#include - -/********************************************************************** - * X52 enumerations - *********************************************************************/ -enum x52_button { - x52_button_trigger1, /* Trigger primary */ - x52_button_launch, /* Launch/Fire */ - x52_button_a, - x52_button_b, - x52_button_c, - x52_button_pinkie, /* Pinkie shift switch */ - - x52_button_d, /* D and E buttons are */ - x52_button_e, /* on the throttle */ - - x52_button_t1_up, /* Toggle 1 up/down */ - x52_button_t1_dn, - x52_button_t2_up, /* Toggle 2 up/down */ - x52_button_t2_dn, - x52_button_t3_up, /* Toggle 3 up/down */ - x52_button_t3_dn, - x52_button_trigger2, /* Trigger secondary */ - - x52_button_mouse_left, - x52_button_mouse_scroll_dn, // Down & up are from the POV of - x52_button_mouse_scroll_up, // the user - x52_button_mouse_right, - - x52_button_stick_pov_N, // These two POVs should really - x52_button_stick_pov_E, // be represented by hats, but - x52_button_stick_pov_S, // the joystick reports them as - x52_button_stick_pov_W, // button presses. - - x52_button_throttle_pov_N, // For the throttle, N, E, S, W - x52_button_throttle_pov_E, // are taken if you look at it - x52_button_throttle_pov_S, // from the position of the user - x52_button_throttle_pov_W, // NOT from the rear of the throttle - - x52_button_mode_select_1, // The mode selection switch is not - x52_button_mode_select_2, // a push button but a selector - - x52_button_mode_select_3, // only one can be active at a time - - x52_button_clutch, - x52_button_function, - x52_button_start_stop, - x52_button_reset, - x52_button_pg_up, - x52_button_pg_dn, - x52_button_up, - x52_button_dn, - x52_button_select, - - x52_button_max -}; - -enum x52_axis { - x52_axis_x, /* Stick X axis */ - x52_axis_y, /* Stick Y axis */ - x52_axis_rz, /* Stick twist axis */ - - x52_axis_z, /* Throttle axis */ - x52_axis_rx, /* Rotary X axis */ - x52_axis_ry, /* Rotary Y axis */ - x52_axis_slider, /* Slider axis */ - - x52_axis_mouse_x, /* Mouse stick X axis */ - x52_axis_mouse_y, /* Mouse stick Y axis */ - - x52_axis_max -}; - -/********************************************************************** - * X52 joystick settings - *********************************************************************/ -/* Deadzone settings - no response if value ... */ -struct x52_axis_deadzone { - u16 dead_lo; /* value < dead_lo */ - u16 dead_hi; /* value > dead_hi */ - - u16 dead_fuzz; /* dead_fuzz > 0 && */ - u16 dead_flat; /* flat - fuzz < value < flat + fuzz */ -}; - -/* - * The X52 MFD supports the following: - * - 3 lines of 16 characters each - * - Clock with HH:MM - * - Date with YYMMDD (IIRC) - */ -#define X52_MFD_LINE_SIZE 16 -#define X52_MFD_LINES 3 - -struct x52_mfd_line { - u8 text[X52_MFD_LINE_SIZE]; - u8 length; -}; - -enum x52_mfd_date_format { - x52_mfd_format_yymmdd, /* YY-MM-DD */ - x52_mfd_format_mmddyy, /* MM-DD-YY */ - x52_mfd_format_ddmmyy, /* DD-MM-YY */ - x52_mfd_format_max, -}; - -struct x52_mfd_date { - u8 year; - u8 month; - u8 day; - u8 format; /* See format enum */ -}; - -struct x52_mfd_time { - u8 hour; - u8 minute; - u8 h24; /* 24 hour format if 1 */ -}; - -struct x52_mfd_offs { - u8 min_off; /* Minute offset from clock 0 */ - u8 neg_off; /* Negative offset if 1 */ - u8 h24; /* 24 hour format if 1 */ -}; - -/********************************************************************** - * X52 mappings - *********************************************************************/ -/* - * Modes to map - * - * Right now, the module supports only 6 modes, listed as follows: - * - Mode 1 - * - Mode 2 - * - Mode 3 - * - Mode 1 + Pinkie - * - Mode 2 + Pinkie - * - Mode 3 + Pinkie - * The last 3 modes use the pinkie switch as a shift selector. - */ -enum x52_map_modes { - x52_map_mode1, - x52_map_mode2, - x52_map_mode3, - x52_map_mode1shift, - x52_map_mode2shift, - x52_map_mode3shift, - x52_map_max -}; - -/* Structure to map joystick button input to a keyboard or mouse event */ -struct x52_event { - u16 type; - u16 code; - s32 value; -}; - -/* - * This defines the maximum number of keyboard or mouse events that can - * be programmed. - */ -#define X52_MAP_MAX_EVENTS 64 - -struct x52_map_event { - u8 mode_selector; - u8 flags; - u8 button_or_axis; - u8 fallback; - - u16 range_low; - u16 range_high; - - struct x52_event events[X52_MAP_MAX_EVENTS]; -}; - -#endif /* !defined X52JOY_MAP_H */