diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S index 30c102978..1d8b8de34 100644 --- a/arch/arm64/kernel/vmlinux.lds.S +++ b/arch/arm64/kernel/vmlinux.lds.S @@ -201,6 +201,15 @@ SECTIONS INIT_RAM_FS *(.init.rodata.* .init.bss) /* from the EFI stub */ } + +#ifdef CONFIG_DRIVERS_HDF + .init.hdf_table : { + _hdf_drivers_start = .; + *(.hdf.driver) + _hdf_drivers_end = .; + } +#endif + .exit.data : { EXIT_DATA } diff --git a/drivers/Kconfig b/drivers/Kconfig index 826b2b19d..9a887e91b 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -236,6 +236,8 @@ source "drivers/interconnect/Kconfig" source "drivers/counter/Kconfig" +source "drivers/hdf/khdf/Kconfig" + source "drivers/most/Kconfig" source "drivers/accesstokenid/Kconfig" diff --git a/drivers/Makefile b/drivers/Makefile index ecc494918..79507aef0 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -191,5 +191,6 @@ obj-$(CONFIG_SIOX) += siox/ obj-$(CONFIG_GNSS) += gnss/ obj-$(CONFIG_INTERCONNECT) += interconnect/ obj-$(CONFIG_COUNTER) += counter/ +obj-$(CONFIG_DRIVERS_HDF) += hdf/ obj-$(CONFIG_MOST) += most/ obj-$(CONFIG_ACCESS_TOKENID) += accesstokenid/ diff --git a/drivers/hdf/Makefile b/drivers/hdf/Makefile new file mode 100644 index 000000000..5c5e1911c --- /dev/null +++ b/drivers/hdf/Makefile @@ -0,0 +1,2 @@ +export PROJECT_ROOT := ../../../../../ +obj-$(CONFIG_DRIVERS_HDF) += khdf/ diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index 4acb583c9..ddcaf4cdc 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile @@ -2,6 +2,19 @@ # # Makefile for the HID driver # +HDF_ROOT_DIR = -I$(srctree)/drivers/hdf +ccflags-$(CONFIG_DRIVERS_HDF_INPUT) += $(HDF_ROOT_DIR)/framework/model/input/driver \ + $(HDF_ROOT_DIR)/framework/include/core \ + $(HDF_ROOT_DIR)/framework/core/common/include/host \ + $(HDF_ROOT_DIR)/framework/include/utils \ + $(HDF_ROOT_DIR)/framework/include/osal \ + $(HDF_ROOT_DIR)/framework/ability/sbuf/include \ + $(HDF_ROOT_DIR)/inner_api/utils \ + $(HDF_ROOT_DIR)/inner_api/osal/shared \ + $(HDF_ROOT_DIR)/inner_api/host/shared \ + $(HDF_ROOT_DIR)/inner_api/core \ + $(HDF_ROOT_DIR)/khdf/osal/include \ + $(HDF_ROOT_DIR)/evdev hid-y := hid-core.o hid-input.o hid-quirks.o hid-$(CONFIG_DEBUG_FS) += hid-debug.o diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 5550c943f..f0503e232 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -33,6 +33,9 @@ #include #include +#if defined(CONFIG_DRIVERS_HDF_INPUT) +#include "hdf_hid_adapter.h" +#endif #include "hid-ids.h" /* @@ -1522,6 +1525,11 @@ static void hid_process_event(struct hid_device *hid, struct hid_field *field, hidinput_hid_event(hid, field, usage, value); if (hid->claimed & HID_CLAIMED_HIDDEV && interrupt && hid->hiddev_hid_event) hid->hiddev_hid_event(hid, field, usage, value); +#if defined(CONFIG_DRIVERS_HDF_INPUT) + if (hid->input_dev) { + HidReportEvent(hid->input_dev, usage->type, usage->code, value); + } +#endif } /* @@ -1928,6 +1936,85 @@ static const struct device_attribute dev_attr_country = { .show = show_country, }; +#if defined(CONFIG_DRIVERS_HDF_INPUT) +static bool check_mouse(char *name) +{ + int i; + static char *option[]={"Mouse", "mouse", "MOUSE", "Razer"}; + for (i = 0; i < 4; i++) { + if (strstr(name, option[i])) + return true; + } + return false; +} +static bool check_kbd(char *name) +{ + int i; + static char *option[]={"Keyboard", "keyboard"}; + for (i = 0; i < 2; i++) { + if (strstr(name, option[i])) + return true; + } + return false; +} +static bool check_rocker(char *name) +{ + int i; + static char *option[]={"Thrustmaster"}; + for (i = 0; i < 1; i++) { + if (strstr(name, option[i])) + return true; + } + return false; +} +static bool check_encoder(char *name) +{ + if (strcmp(name, "Wired KeyBoard") == 0) { + return true; + } + return false; +} +static bool check_trackball(char *name) +{ + int i; + static char *option[]={"Trackball"}; + for (i = 0; i < 1; i++) { + if (strstr(name, option[i])) + return true; + } + return false; +} +static void notify_connect_event(struct hid_device *hdev) +{ + bool check; + int type = -1; + HidInfo *dev = (HidInfo *)kmalloc(sizeof(HidInfo), GFP_KERNEL); + if (dev == NULL) { + printk("%s: malloc failed", __func__); + return; + } + type = check_mouse(hdev->name)?HID_TYPE_MOUSE:type; + type = check_kbd(hdev->name)?HID_TYPE_KEYBOARD:type; + type = check_rocker(hdev->name)?HID_TYPE_ROCKER:type; + type = check_encoder(hdev->name)?HID_TYPE_ENCODER:type; + type = check_trackball(hdev->name)?HID_TYPE_TRACKBALL:type; + if ( type < 0) { + kfree(dev); + dev = NULL; + return; + } + + dev->devType = type; + dev->devName = hdev->name; + hdev->input_dev = HidRegisterHdfInputDev(dev); + if (hdev->input_dev == NULL) { + printk("%s: RegisterInputDevice failed\n", __func__); + } + kfree(dev); + dev = NULL; +} +#endif + int hid_connect(struct hid_device *hdev, unsigned int connect_mask) { static const char *types[] = { "Device", "Pointer", "Mouse", "Device", @@ -2020,6 +2107,9 @@ int hid_connect(struct hid_device *hdev, unsigned int connect_mask) hid_info(hdev, "%s: %s HID v%x.%02x %s [%s] on %s\n", buf, bus, hdev->version >> 8, hdev->version & 0xff, type, hdev->name, hdev->phys); +#if defined(CONFIG_DRIVERS_HDF_INPUT) + notify_connect_event(hdev); +#endif return 0; } @@ -2035,6 +2125,10 @@ void hid_disconnect(struct hid_device *hdev) if (hdev->claimed & HID_CLAIMED_HIDRAW) hidraw_disconnect(hdev); hdev->claimed = 0; +#if defined(CONFIG_DRIVERS_HDF_INPUT) + if (hdev->input_dev) + HidUnregisterHdfInputDev(hdev->input_dev); +#endif } EXPORT_SYMBOL_GPL(hid_disconnect); @@ -2119,6 +2213,11 @@ EXPORT_SYMBOL_GPL(hid_hw_open); */ void hid_hw_close(struct hid_device *hdev) { +#if defined(CONFIG_DRIVERS_HDF_INPUT) + if (hdev->input_dev) { + return; + } +#endif mutex_lock(&hdev->ll_open_lock); if (!--hdev->ll_open_count) hdev->ll_driver->close(hdev); diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 580d37834..fb945f4ce 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -20,6 +20,10 @@ #include #include +#if defined(CONFIG_DRIVERS_HDF_INPUT) +#include "hdf_hid_adapter.h" +#endif + #include "hid-ids.h" #define unk KEY_UNKNOWN @@ -1416,7 +1420,15 @@ void hidinput_report_event(struct hid_device *hid, struct hid_report *report) return; list_for_each_entry(hidinput, &hid->inputs, list) +#if defined(CONFIG_DRIVERS_HDF_INPUT) + { +#endif input_sync(hidinput->input); +#if defined(CONFIG_DRIVERS_HDF_INPUT) + if(hid->input_dev) + HidReportEvent(hid->input_dev, EV_SYN, SYN_REPORT, 0); + } +#endif } EXPORT_SYMBOL_GPL(hidinput_report_event); @@ -1867,6 +1879,42 @@ static inline void hidinput_configure_usages(struct hid_input *hidinput, report->field[i]->usage + j); } +#if defined(CONFIG_DRIVERS_HDF_INPUT) +static void transfer_info(struct input_dev *dev) +{ + int i; + HidInfo *info = (HidInfo *)kmalloc(sizeof(HidInfo),GFP_KERNEL); + if (info == NULL) { + printk("%s: malloc failed\n",__func__); + return; + } + info->devName = dev->name; + memcpy(info->devProp, dev->propbit, sizeof(unsigned long) * BITS_TO_LONGS(INPUT_PROP_CNT)); + memcpy(info->eventType, dev->evbit, sizeof(unsigned long) * BITS_TO_LONGS(EV_CNT)); + memcpy(info->keyCode, dev->keybit, sizeof(unsigned long) * BITS_TO_LONGS(KEY_CNT)); + memcpy(info->relCode, dev->relbit, sizeof(unsigned long) * BITS_TO_LONGS(REL_CNT)); + memcpy(info->absCode, dev->absbit, sizeof(unsigned long) * BITS_TO_LONGS(ABS_CNT)); + memcpy(info->miscCode, dev->mscbit, sizeof(unsigned long) * BITS_TO_LONGS(MSC_CNT)); + memcpy(info->ledCode, dev->ledbit, sizeof(unsigned long) * BITS_TO_LONGS(LED_CNT)); + memcpy(info->soundCode, dev->sndbit, sizeof(unsigned long) * BITS_TO_LONGS(SND_CNT)); + memcpy(info->forceCode, dev->ffbit, sizeof(unsigned long) * BITS_TO_LONGS(FF_CNT)); + memcpy(info->switchCode, dev->swbit, sizeof(unsigned long) * BITS_TO_LONGS(SW_CNT)); + for (i = 0; i < BITS_TO_LONGS(ABS_CNT); i++) { + if (dev->absbit[i] != 0) { + memcpy(info->axisInfo, dev->absinfo, sizeof(struct input_absinfo) * ABS_CNT); + break; + } + } + info->bustype = dev->id.bustype; + info->vendor = dev->id.vendor; + info->product = dev->id.product; + info->version = dev->id.version; + SendInfoToHdf(info); + kfree(info); + info = NULL; +} +#endif + /* * Register the input device; print a message. * Configure the input layer interface @@ -1952,6 +2000,9 @@ int hidinput_connect(struct hid_device *hid, unsigned int force) continue; } +#if defined(CONFIG_DRIVERS_HDF_INPUT) + transfer_info(hidinput->input); +#endif if (input_register_device(hidinput->input)) goto out_unwind; hidinput->registered = true; diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile index a48e5f2d8..90d25f224 100644 --- a/drivers/input/misc/Makefile +++ b/drivers/input/misc/Makefile @@ -85,3 +85,21 @@ obj-$(CONFIG_INPUT_XEN_KBDDEV_FRONTEND) += xen-kbdfront.o obj-$(CONFIG_INPUT_YEALINK) += yealink.o obj-$(CONFIG_INPUT_IDEAPAD_SLIDEBAR) += ideapad_slidebar.o +ccflags-y +=-I$(srctree)/drivers/hdf/framework/model/input/driver \ + -I$(srctree)/drivers/hdf/framework/model/input/driver/input_bus_ops \ + -I$(srctree)/drivers/hdf/framework/include/core \ + -I$(srctree)/drivers/hdf/framework/core/common/include/host \ + -I$(srctree)/drivers/hdf/framework/include/utils \ + -I$(srctree)/drivers/hdf/framework/include/osal \ + -I$(srctree)/drivers/hdf/framework/include/platform \ + -I$(srctree)/drivers/hdf/framework/include/config \ + -I$(srctree)/drivers/hdf/framework/core/host/include \ + -I$(srctree)/drivers/hdf/framework/core/shared/include \ + -I$(srctree)/drivers/hdf/framework/utils/include \ + -I$(srctree)/drivers/hdf/inner_api/osal/shared \ + -I$(srctree)/drivers/hdf/inner_api/host/shared \ + -I$(srctree)/drivers/hdf/inner_api/utils \ + -I$(srctree)/drivers/hdf/inner_api/core \ + -I$(srctree)/drivers/hdf/khdf/osal/include +ccflags-y +=-I$(srctree)/bounds_checking_function/include \ + -I$(srctree)/drivers/hdf/evdev diff --git a/drivers/input/misc/rk805-pwrkey.c b/drivers/input/misc/rk805-pwrkey.c index 3fb64dbda..394cd5912 100644 --- a/drivers/input/misc/rk805-pwrkey.c +++ b/drivers/input/misc/rk805-pwrkey.c @@ -14,6 +14,9 @@ #include #include #include +#include "hdf_hid_adapter.h" + +InputDevice *HidinputDev=NULL; static irqreturn_t pwrkey_fall_irq(int irq, void *_pwr) { @@ -22,6 +25,8 @@ static irqreturn_t pwrkey_fall_irq(int irq, void *_pwr) input_report_key(pwr, KEY_POWER, 1); input_sync(pwr); + HidReportEvent(HidinputDev, EV_KEY, KEY_POWER, 1); + HidReportEvent(HidinputDev, EV_SYN, SYN_REPORT, 0); return IRQ_HANDLED; } @@ -32,9 +37,24 @@ static irqreturn_t pwrkey_rise_irq(int irq, void *_pwr) input_report_key(pwr, KEY_POWER, 0); input_sync(pwr); + HidReportEvent(HidinputDev, EV_KEY, KEY_POWER, 0); + HidReportEvent(HidinputDev, EV_SYN, SYN_REPORT, 0); return IRQ_HANDLED; } +static InputDevice* HidRegisterHdfPowerKeyDev(void) +{ + InputDevice* inputDev = NULL; + HidInfo Hid_keyInfo; + + Hid_keyInfo.devType = HID_TYPE_KEY; + Hid_keyInfo.eventType[0] = SET_BIT(EV_KEY); + Hid_keyInfo.keyCode[3] = SET_BIT(KEY_POWER); + Hid_keyInfo.devName = "hid-powerkey"; + inputDev = HidRegisterHdfInputDev(&Hid_keyInfo); + return inputDev; +} + static int rk805_pwrkey_probe(struct platform_device *pdev) { struct input_dev *pwr; @@ -87,6 +107,11 @@ static int rk805_pwrkey_probe(struct platform_device *pdev) platform_set_drvdata(pdev, pwr); device_init_wakeup(&pdev->dev, true); + HidinputDev = HidRegisterHdfPowerKeyDev(); + if (NULL == HidinputDev) { + pr_err("HidRegisterHdfInputDev error\n"); + return -EINVAL; + } return 0; } diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c index 505c562a5..67d451beb 100644 --- a/drivers/input/mousedev.c +++ b/drivers/input/mousedev.c @@ -869,7 +869,7 @@ static struct mousedev *mousedev_create(struct input_dev *dev, if (mixdev) { dev_set_name(&mousedev->dev, "mice"); - + mousedev->open = 1; mousedev->open_device = mixdev_open_devices; mousedev->close_device = mixdev_close_devices; } else { diff --git a/drivers/usb/core/notify.c b/drivers/usb/core/notify.c index e61436637..8256d576c 100644 --- a/drivers/usb/core/notify.c +++ b/drivers/usb/core/notify.c @@ -66,3 +66,12 @@ void usb_notify_remove_bus(struct usb_bus *ubus) { blocking_notifier_call_chain(&usb_notifier_list, USB_BUS_REMOVE, ubus); } + +void usb_notify_online_status(bool online) +{ + if (online) { + blocking_notifier_call_chain(&usb_notifier_list, USB_GADGET_ADD, NULL); + } else { + blocking_notifier_call_chain(&usb_notifier_list, USB_GADGET_REMOVE, NULL); + } +} diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index b75fe5680..8b236394a 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -3633,6 +3633,7 @@ static void dwc3_gadget_interrupt(struct dwc3 *dwc, { switch (event->type) { case DWC3_DEVICE_EVENT_DISCONNECT: + usb_notify_online_status(false); dwc3_gadget_disconnect_interrupt(dwc); break; case DWC3_DEVICE_EVENT_RESET: @@ -3640,6 +3641,7 @@ static void dwc3_gadget_interrupt(struct dwc3 *dwc, break; case DWC3_DEVICE_EVENT_CONNECT_DONE: dwc3_gadget_conndone_interrupt(dwc); + usb_notify_online_status(true); break; case DWC3_DEVICE_EVENT_WAKEUP: dwc3_gadget_wakeup_interrupt(dwc); diff --git a/include/linux/hid.h b/include/linux/hid.h index 6ed2a97eb..1d1445a23 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -622,6 +622,7 @@ struct hid_device { /* device report descriptor */ struct list_head debug_list; spinlock_t debug_list_lock; wait_queue_head_t debug_wait; + void *input_dev; }; #define to_hid_device(pdev) \ diff --git a/include/linux/usb.h b/include/linux/usb.h index d6a41841b..de3232ee5 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -2019,8 +2019,11 @@ static inline int usb_translate_errors(int error_code) #define USB_DEVICE_REMOVE 0x0002 #define USB_BUS_ADD 0x0003 #define USB_BUS_REMOVE 0x0004 +#define USB_GADGET_ADD 0x0005 +#define USB_GADGET_REMOVE 0x0006 extern void usb_register_notify(struct notifier_block *nb); extern void usb_unregister_notify(struct notifier_block *nb); +extern void usb_notify_online_status(bool online); /* debugfs stuff */ extern struct dentry *usb_debug_root;