#include <linux/completion.h>
#include <linux/device.h>
#include <linux/firmware.h>
#include <linux/ihex.h>
#include <linux/input.h>
#include <linux/kernel.h>
#include <linux/leds.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/usb/input.h>
#include <linux/usb/cdc.h>
#include <linux/unaligned.h>
#define IMS_PCU_KEYMAP_LEN …
struct ims_pcu_buttons { … };
struct ims_pcu_gamepad { … };
struct ims_pcu_backlight { … };
#define IMS_PCU_PART_NUMBER_LEN …
#define IMS_PCU_SERIAL_NUMBER_LEN …
#define IMS_PCU_DOM_LEN …
#define IMS_PCU_FW_VERSION_LEN …
#define IMS_PCU_BL_VERSION_LEN …
#define IMS_PCU_BL_RESET_REASON_LEN …
#define IMS_PCU_PCU_B_DEVICE_ID …
#define IMS_PCU_BUF_SIZE …
struct ims_pcu { … };
static const unsigned short ims_pcu_keymap_1[] = …;
static const unsigned short ims_pcu_keymap_2[] = …;
static const unsigned short ims_pcu_keymap_3[] = …;
static const unsigned short ims_pcu_keymap_4[] = …;
static const unsigned short ims_pcu_keymap_5[] = …;
struct ims_pcu_device_info { … };
#define IMS_PCU_DEVINFO(_n, _gamepad) …
static const struct ims_pcu_device_info ims_pcu_device_info[] = …;
static void ims_pcu_buttons_report(struct ims_pcu *pcu, u32 data)
{ … }
static int ims_pcu_setup_buttons(struct ims_pcu *pcu,
const unsigned short *keymap,
size_t keymap_len)
{ … }
static void ims_pcu_destroy_buttons(struct ims_pcu *pcu)
{ … }
static void ims_pcu_gamepad_report(struct ims_pcu *pcu, u32 data)
{ … }
static int ims_pcu_setup_gamepad(struct ims_pcu *pcu)
{ … }
static void ims_pcu_destroy_gamepad(struct ims_pcu *pcu)
{ … }
#define IMS_PCU_PROTOCOL_STX …
#define IMS_PCU_PROTOCOL_ETX …
#define IMS_PCU_PROTOCOL_DLE …
#define IMS_PCU_CMD_STATUS …
#define IMS_PCU_CMD_PCU_RESET …
#define IMS_PCU_CMD_RESET_REASON …
#define IMS_PCU_CMD_SEND_BUTTONS …
#define IMS_PCU_CMD_JUMP_TO_BTLDR …
#define IMS_PCU_CMD_GET_INFO …
#define IMS_PCU_CMD_SET_BRIGHTNESS …
#define IMS_PCU_CMD_EEPROM …
#define IMS_PCU_CMD_GET_FW_VERSION …
#define IMS_PCU_CMD_GET_BL_VERSION …
#define IMS_PCU_CMD_SET_INFO …
#define IMS_PCU_CMD_GET_BRIGHTNESS …
#define IMS_PCU_CMD_GET_DEVICE_ID …
#define IMS_PCU_CMD_SPECIAL_INFO …
#define IMS_PCU_CMD_BOOTLOADER …
#define IMS_PCU_CMD_OFN_SET_CONFIG …
#define IMS_PCU_CMD_OFN_GET_CONFIG …
#define IMS_PCU_RSP_STATUS …
#define IMS_PCU_RSP_PCU_RESET …
#define IMS_PCU_RSP_RESET_REASON …
#define IMS_PCU_RSP_SEND_BUTTONS …
#define IMS_PCU_RSP_JUMP_TO_BTLDR …
#define IMS_PCU_RSP_GET_INFO …
#define IMS_PCU_RSP_SET_BRIGHTNESS …
#define IMS_PCU_RSP_EEPROM …
#define IMS_PCU_RSP_GET_FW_VERSION …
#define IMS_PCU_RSP_GET_BL_VERSION …
#define IMS_PCU_RSP_SET_INFO …
#define IMS_PCU_RSP_GET_BRIGHTNESS …
#define IMS_PCU_RSP_CMD_INVALID …
#define IMS_PCU_RSP_GET_DEVICE_ID …
#define IMS_PCU_RSP_SPECIAL_INFO …
#define IMS_PCU_RSP_BOOTLOADER …
#define IMS_PCU_RSP_OFN_SET_CONFIG …
#define IMS_PCU_RSP_OFN_GET_CONFIG …
#define IMS_PCU_RSP_EVNT_BUTTONS …
#define IMS_PCU_GAMEPAD_MASK …
#define IMS_PCU_MIN_PACKET_LEN …
#define IMS_PCU_DATA_OFFSET …
#define IMS_PCU_CMD_WRITE_TIMEOUT …
#define IMS_PCU_CMD_RESPONSE_TIMEOUT …
static void ims_pcu_report_events(struct ims_pcu *pcu)
{ … }
static void ims_pcu_handle_response(struct ims_pcu *pcu)
{ … }
static void ims_pcu_process_data(struct ims_pcu *pcu, struct urb *urb)
{ … }
static bool ims_pcu_byte_needs_escape(u8 byte)
{ … }
static int ims_pcu_send_cmd_chunk(struct ims_pcu *pcu,
u8 command, int chunk, int len)
{ … }
static int ims_pcu_send_command(struct ims_pcu *pcu,
u8 command, const u8 *data, int len)
{ … }
static int __ims_pcu_execute_command(struct ims_pcu *pcu,
u8 command, const void *data, size_t len,
u8 expected_response, int response_time)
{ … }
#define ims_pcu_execute_command(pcu, code, data, len) …
#define ims_pcu_execute_query(pcu, code) …
#define IMS_PCU_BL_CMD_QUERY_DEVICE …
#define IMS_PCU_BL_CMD_UNLOCK_CONFIG …
#define IMS_PCU_BL_CMD_ERASE_APP …
#define IMS_PCU_BL_CMD_PROGRAM_DEVICE …
#define IMS_PCU_BL_CMD_PROGRAM_COMPLETE …
#define IMS_PCU_BL_CMD_READ_APP …
#define IMS_PCU_BL_CMD_RESET_DEVICE …
#define IMS_PCU_BL_CMD_LAUNCH_APP …
#define IMS_PCU_BL_RSP_QUERY_DEVICE …
#define IMS_PCU_BL_RSP_UNLOCK_CONFIG …
#define IMS_PCU_BL_RSP_ERASE_APP …
#define IMS_PCU_BL_RSP_PROGRAM_DEVICE …
#define IMS_PCU_BL_RSP_PROGRAM_COMPLETE …
#define IMS_PCU_BL_RSP_READ_APP …
#define IMS_PCU_BL_RSP_RESET_DEVICE …
#define IMS_PCU_BL_RSP_LAUNCH_APP …
#define IMS_PCU_BL_DATA_OFFSET …
static int __ims_pcu_execute_bl_command(struct ims_pcu *pcu,
u8 command, const void *data, size_t len,
u8 expected_response, int response_time)
{ … }
#define ims_pcu_execute_bl_command(pcu, code, data, len, timeout) … \
#define IMS_PCU_INFO_PART_OFFSET …
#define IMS_PCU_INFO_DOM_OFFSET …
#define IMS_PCU_INFO_SERIAL_OFFSET …
#define IMS_PCU_SET_INFO_SIZE …
static int ims_pcu_get_info(struct ims_pcu *pcu)
{ … }
static int ims_pcu_set_info(struct ims_pcu *pcu)
{ … }
static int ims_pcu_switch_to_bootloader(struct ims_pcu *pcu)
{ … }
#define IMS_PCU_FIRMWARE_NAME …
struct ims_pcu_flash_fmt { … };
static unsigned int ims_pcu_count_fw_records(const struct firmware *fw)
{ … }
static int ims_pcu_verify_block(struct ims_pcu *pcu,
u32 addr, u8 len, const u8 *data)
{ … }
static int ims_pcu_flash_firmware(struct ims_pcu *pcu,
const struct firmware *fw,
unsigned int n_fw_records)
{ … }
static int ims_pcu_handle_firmware_update(struct ims_pcu *pcu,
const struct firmware *fw)
{ … }
static void ims_pcu_process_async_firmware(const struct firmware *fw,
void *context)
{ … }
#define IMS_PCU_MAX_BRIGHTNESS …
static int ims_pcu_backlight_set_brightness(struct led_classdev *cdev,
enum led_brightness value)
{ … }
static enum led_brightness
ims_pcu_backlight_get_brightness(struct led_classdev *cdev)
{ … }
static int ims_pcu_setup_backlight(struct ims_pcu *pcu)
{ … }
static void ims_pcu_destroy_backlight(struct ims_pcu *pcu)
{ … }
struct ims_pcu_attribute { … };
static ssize_t ims_pcu_attribute_show(struct device *dev,
struct device_attribute *dattr,
char *buf)
{ … }
static ssize_t ims_pcu_attribute_store(struct device *dev,
struct device_attribute *dattr,
const char *buf, size_t count)
{ … }
#define IMS_PCU_ATTR(_field, _mode) …
#define IMS_PCU_RO_ATTR(_field) …
#define IMS_PCU_RW_ATTR(_field) …
static IMS_PCU_RW_ATTR(part_number);
static IMS_PCU_RW_ATTR(serial_number);
static IMS_PCU_RW_ATTR(date_of_manufacturing);
static IMS_PCU_RO_ATTR(fw_version);
static IMS_PCU_RO_ATTR(bl_version);
static IMS_PCU_RO_ATTR(reset_reason);
static ssize_t ims_pcu_reset_device(struct device *dev,
struct device_attribute *dattr,
const char *buf, size_t count)
{ … }
static DEVICE_ATTR(reset_device, S_IWUSR, NULL, ims_pcu_reset_device);
static ssize_t ims_pcu_update_firmware_store(struct device *dev,
struct device_attribute *dattr,
const char *buf, size_t count)
{ … }
static DEVICE_ATTR(update_firmware, S_IWUSR,
NULL, ims_pcu_update_firmware_store);
static ssize_t
ims_pcu_update_firmware_status_show(struct device *dev,
struct device_attribute *dattr,
char *buf)
{ … }
static DEVICE_ATTR(update_firmware_status, S_IRUGO,
ims_pcu_update_firmware_status_show, NULL);
static struct attribute *ims_pcu_attrs[] = …;
static umode_t ims_pcu_is_attr_visible(struct kobject *kobj,
struct attribute *attr, int n)
{ … }
static const struct attribute_group ims_pcu_attr_group = …;
#define OFN_REG_RESULT_OFFSET …
static int ims_pcu_read_ofn_config(struct ims_pcu *pcu, u8 addr, u8 *data)
{ … }
static int ims_pcu_write_ofn_config(struct ims_pcu *pcu, u8 addr, u8 data)
{ … }
static ssize_t ims_pcu_ofn_reg_data_show(struct device *dev,
struct device_attribute *dattr,
char *buf)
{ … }
static ssize_t ims_pcu_ofn_reg_data_store(struct device *dev,
struct device_attribute *dattr,
const char *buf, size_t count)
{ … }
static DEVICE_ATTR(reg_data, S_IRUGO | S_IWUSR,
ims_pcu_ofn_reg_data_show, ims_pcu_ofn_reg_data_store);
static ssize_t ims_pcu_ofn_reg_addr_show(struct device *dev,
struct device_attribute *dattr,
char *buf)
{ … }
static ssize_t ims_pcu_ofn_reg_addr_store(struct device *dev,
struct device_attribute *dattr,
const char *buf, size_t count)
{ … }
static DEVICE_ATTR(reg_addr, S_IRUGO | S_IWUSR,
ims_pcu_ofn_reg_addr_show, ims_pcu_ofn_reg_addr_store);
struct ims_pcu_ofn_bit_attribute { … };
static ssize_t ims_pcu_ofn_bit_show(struct device *dev,
struct device_attribute *dattr,
char *buf)
{ … }
static ssize_t ims_pcu_ofn_bit_store(struct device *dev,
struct device_attribute *dattr,
const char *buf, size_t count)
{ … }
#define IMS_PCU_OFN_BIT_ATTR(_field, _addr, _nr) …
static IMS_PCU_OFN_BIT_ATTR(engine_enable, 0x60, 7);
static IMS_PCU_OFN_BIT_ATTR(speed_enable, 0x60, 6);
static IMS_PCU_OFN_BIT_ATTR(assert_enable, 0x60, 5);
static IMS_PCU_OFN_BIT_ATTR(xyquant_enable, 0x60, 4);
static IMS_PCU_OFN_BIT_ATTR(xyscale_enable, 0x60, 1);
static IMS_PCU_OFN_BIT_ATTR(scale_x2, 0x63, 6);
static IMS_PCU_OFN_BIT_ATTR(scale_y2, 0x63, 7);
static struct attribute *ims_pcu_ofn_attrs[] = …;
static umode_t ims_pcu_ofn_is_attr_visible(struct kobject *kobj,
struct attribute *attr, int n)
{ … }
static const struct attribute_group ims_pcu_ofn_attr_group = …;
static void ims_pcu_irq(struct urb *urb)
{ … }
static int ims_pcu_buffers_alloc(struct ims_pcu *pcu)
{ … }
static void ims_pcu_buffers_free(struct ims_pcu *pcu)
{ … }
static const struct usb_cdc_union_desc *
ims_pcu_get_cdc_union_desc(struct usb_interface *intf)
{ … }
static int ims_pcu_parse_cdc_data(struct usb_interface *intf, struct ims_pcu *pcu)
{ … }
static int ims_pcu_start_io(struct ims_pcu *pcu)
{ … }
static void ims_pcu_stop_io(struct ims_pcu *pcu)
{ … }
static int ims_pcu_line_setup(struct ims_pcu *pcu)
{ … }
static int ims_pcu_get_device_info(struct ims_pcu *pcu)
{ … }
static int ims_pcu_identify_type(struct ims_pcu *pcu, u8 *device_id)
{ … }
static int ims_pcu_init_application_mode(struct ims_pcu *pcu)
{ … }
static void ims_pcu_destroy_application_mode(struct ims_pcu *pcu)
{ … }
static int ims_pcu_init_bootloader_mode(struct ims_pcu *pcu)
{ … }
static void ims_pcu_destroy_bootloader_mode(struct ims_pcu *pcu)
{ … }
#define IMS_PCU_APPLICATION_MODE …
#define IMS_PCU_BOOTLOADER_MODE …
static struct usb_driver ims_pcu_driver;
static int ims_pcu_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{ … }
static void ims_pcu_disconnect(struct usb_interface *intf)
{ … }
#ifdef CONFIG_PM
static int ims_pcu_suspend(struct usb_interface *intf,
pm_message_t message)
{ … }
static int ims_pcu_resume(struct usb_interface *intf)
{ … }
#endif
static const struct usb_device_id ims_pcu_id_table[] = …;
static const struct attribute_group *ims_pcu_sysfs_groups[] = …;
static struct usb_driver ims_pcu_driver = …;
module_usb_driver(…) …;
MODULE_DESCRIPTION(…) …;
MODULE_AUTHOR(…) …;
MODULE_LICENSE(…) …;