Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion drivers/hid/hid-oxp.c
Original file line number Diff line number Diff line change
Expand Up @@ -1386,7 +1386,7 @@ static struct mc_subled oxp_rgb_subled_info[] = {

static struct led_classdev_mc oxp_cdev_rgb = {
.led_cdev = {
.name = "oxp:rgb:joystick_rings",
.name = "go:rgb:joystick_rings",
.color = LED_COLOR_ID_RGB,
.brightness = 0x64,
.max_brightness = 0x64,
Expand Down
2 changes: 2 additions & 0 deletions drivers/platform/x86/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -1056,6 +1056,8 @@ config OXP_EC
depends on ACPI_BATTERY
depends on HWMON
depends on X86
depends on INPUT
depends on USB
help
Enables support for the platform EC of OneXPlayer and AOKZOE
handheld devices. This includes fan speed, fan controls, and
Expand Down
134 changes: 133 additions & 1 deletion drivers/platform/x86/oxpec.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@
#include <linux/dmi.h>
#include <linux/hwmon.h>
#include <linux/init.h>
#include <linux/input.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/processor.h>
#include <linux/usb.h>
#include <acpi/battery.h>

/* Handle ACPI lock mechanism */
Expand All @@ -43,17 +45,21 @@ enum oxp_board {
aok_zoe_a1 = 1,
orange_pi_neo,
oxp_2,
oxp_3,
oxp_fly,
oxp_mini_amd,
oxp_mini_amd_a07,
oxp_mini_amd_pro,
oxp_x1,
oxp_g1_i,
oxp_g1_a,
oxp_super_x,
};

static enum oxp_board board;
static struct device *oxp_dev;
static struct input_dev *oxp_tablet_mode_input;
static struct notifier_block oxp_usb_notifier;

/* Fan reading and PWM */
#define OXP_SENSOR_FAN_REG 0x76 /* Fan reading is 2 registers long */
Expand Down Expand Up @@ -149,6 +155,13 @@ static const struct dmi_system_id dmi_table[] = {
},
.driver_data = (void *)oxp_2,
},
{
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "ONE-NETBOOK"),
DMI_EXACT_MATCH(DMI_BOARD_NAME, "ONEXPLAYER 3"),
},
.driver_data = (void *)oxp_3,
},
{
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "ONE-NETBOOK"),
Expand Down Expand Up @@ -210,7 +223,7 @@ static const struct dmi_system_id dmi_table[] = {
DMI_MATCH(DMI_BOARD_VENDOR, "ONE-NETBOOK"),
DMI_EXACT_MATCH(DMI_BOARD_NAME, "ONEXPLAYER SUPER X"),
},
.driver_data = (void *)oxp_g1_a,
.driver_data = (void *)oxp_super_x,
},
{
.matches = {
Expand Down Expand Up @@ -289,9 +302,84 @@ static const struct dmi_system_id dmi_table[] = {
},
.driver_data = (void *)oxp_x1,
},
{
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "ONE-NETBOOK"),
DMI_EXACT_MATCH(DMI_BOARD_NAME, "ONEXPLAYER X2Mini PRO"),
},
.driver_data = (void *)oxp_fly,
},
{},
};

#define OXP_KEYBOARD_VID_QINHENG 0x1a86
#define OXP_KEYBOARD_PID_K2445 0x1305
#define OXP_KEYBOARD_VID_HAILUCK 0x258a
#define OXP_KEYBOARD_PID_HAILUCK 0x001e

static int oxp_find_keyboard(struct usb_device *udev, void *data)
{
bool *keyboard_attached = data;
u16 vid = le16_to_cpu(udev->descriptor.idVendor);
u16 pid = le16_to_cpu(udev->descriptor.idProduct);

switch (board) {
case oxp_x1:
if (vid == OXP_KEYBOARD_VID_HAILUCK &&
pid == OXP_KEYBOARD_PID_HAILUCK)
*keyboard_attached = true;
break;
case oxp_super_x:
if (vid == OXP_KEYBOARD_VID_QINHENG &&
pid == OXP_KEYBOARD_PID_K2445)
*keyboard_attached = true;
break;
default:
break;
}

return 0;
}

static int oxp_usb_notify(struct notifier_block *nb,
unsigned long action, void *data)
{
struct usb_device *udev = data;
u16 vid = le16_to_cpu(udev->descriptor.idVendor);
u16 pid = le16_to_cpu(udev->descriptor.idProduct);
bool keyboard = false;

switch (board) {
case oxp_x1:
keyboard = vid == OXP_KEYBOARD_VID_HAILUCK &&
pid == OXP_KEYBOARD_PID_HAILUCK;
break;
case oxp_super_x:
keyboard = vid == OXP_KEYBOARD_VID_QINHENG &&
pid == OXP_KEYBOARD_PID_K2445;
break;
default:
break;
}

if (!keyboard)
return NOTIFY_DONE;

switch (action) {
case USB_DEVICE_ADD:
input_report_switch(oxp_tablet_mode_input, SW_TABLET_MODE, false);
break;
case USB_DEVICE_REMOVE:
input_report_switch(oxp_tablet_mode_input, SW_TABLET_MODE, true);
break;
default:
return NOTIFY_DONE;
}

input_sync(oxp_tablet_mode_input);
return NOTIFY_OK;
}

/* Helper functions to handle EC read/write */
static int read_from_ec(u8 reg, int size, long *val)
{
Expand Down Expand Up @@ -345,6 +433,7 @@ static umode_t tt_toggle_is_visible(struct kobject *kobj,
case oxp_x1:
case oxp_g1_i:
case oxp_g1_a:
case oxp_super_x:
return attr->mode;
default:
break;
Expand Down Expand Up @@ -374,6 +463,7 @@ static ssize_t tt_toggle_store(struct device *dev,
case oxp_fly:
case oxp_mini_amd_pro:
case oxp_g1_a:
case oxp_super_x:
reg = OXP_TURBO_SWITCH_REG;
mask = OXP_TURBO_TAKE_VAL;
break;
Expand Down Expand Up @@ -420,6 +510,7 @@ static ssize_t tt_toggle_show(struct device *dev,
case oxp_fly:
case oxp_mini_amd_pro:
case oxp_g1_a:
case oxp_super_x:
reg = OXP_TURBO_SWITCH_REG;
mask = OXP_TURBO_TAKE_VAL;
break;
Expand Down Expand Up @@ -516,6 +607,7 @@ static bool oxp_psy_ext_supported(void)
case oxp_x1:
case oxp_g1_i:
case oxp_g1_a:
case oxp_super_x:
case oxp_fly:
return true;
default:
Expand Down Expand Up @@ -649,6 +741,7 @@ static int oxp_pwm_enable(void)
case oxp_x1:
case oxp_g1_i:
case oxp_g1_a:
case oxp_super_x:
return write_to_ec(OXP_SENSOR_PWM_ENABLE_REG, PWM_MODE_MANUAL);
default:
return -EINVAL;
Expand All @@ -669,6 +762,7 @@ static int oxp_pwm_disable(void)
case oxp_x1:
case oxp_g1_i:
case oxp_g1_a:
case oxp_super_x:
return write_to_ec(OXP_SENSOR_PWM_ENABLE_REG, PWM_MODE_AUTO);
default:
return -EINVAL;
Expand All @@ -689,6 +783,7 @@ static int oxp_pwm_read(long *val)
case oxp_x1:
case oxp_g1_i:
case oxp_g1_a:
case oxp_super_x:
return read_from_ec(OXP_SENSOR_PWM_ENABLE_REG, 1, val);
default:
return -EOPNOTSUPP;
Expand All @@ -703,6 +798,8 @@ static umode_t oxp_ec_hwmon_is_visible(const void *drvdata,
case hwmon_fan:
return 0444;
case hwmon_pwm:
if (board == oxp_3)
return 0;
return 0644;
default:
return 0;
Expand All @@ -716,6 +813,7 @@ static int oxp_pwm_fan_speed(long *val)
case orange_pi_neo:
return read_from_ec(ORANGEPI_SENSOR_FAN_REG, 2, val);
case oxp_2:
case oxp_3:
case oxp_x1:
case oxp_g1_i:
return read_from_ec(OXP_2_SENSOR_FAN_REG, 2, val);
Expand All @@ -725,6 +823,7 @@ static int oxp_pwm_fan_speed(long *val)
case oxp_mini_amd_a07:
case oxp_mini_amd_pro:
case oxp_g1_a:
case oxp_super_x:
return read_from_ec(OXP_SENSOR_FAN_REG, 2, val);
default:
return -EOPNOTSUPP;
Expand Down Expand Up @@ -757,6 +856,7 @@ static int oxp_pwm_input_write(long val)
case oxp_fly:
case oxp_mini_amd_pro:
case oxp_g1_a:
case oxp_super_x:
return write_to_ec(OXP_SENSOR_PWM_REG, val);
default:
return -EOPNOTSUPP;
Expand Down Expand Up @@ -796,6 +896,7 @@ static int oxp_pwm_input_read(long *val)
case oxp_fly:
case oxp_mini_amd_pro:
case oxp_g1_a:
case oxp_super_x:
default:
ret = read_from_ec(OXP_SENSOR_PWM_REG, 1, val);
if (ret)
Expand Down Expand Up @@ -937,6 +1038,7 @@ static const struct hwmon_chip_info oxp_ec_chip_info = {
/* Initialization logic */
static int oxp_platform_probe(struct platform_device *pdev)
{
bool keyboard_attached = false;
struct device *dev = &pdev->dev;
struct device *hwdev;
int ret;
Expand All @@ -954,6 +1056,33 @@ static int oxp_platform_probe(struct platform_device *pdev)
return ret;
}

switch (board) {
case oxp_x1:
case oxp_super_x:
oxp_tablet_mode_input = devm_input_allocate_device(dev);
if (!oxp_tablet_mode_input)
return -ENOMEM;

oxp_tablet_mode_input->name = "OneXPlayer Tablet Mode Switch";
oxp_tablet_mode_input->phys = "oxp-platform/input0";
oxp_tablet_mode_input->id.bustype = BUS_HOST;
input_set_capability(oxp_tablet_mode_input, EV_SW, SW_TABLET_MODE);

ret = input_register_device(oxp_tablet_mode_input);
if (ret)
return ret;

oxp_usb_notifier.notifier_call = oxp_usb_notify;
usb_register_notify(&oxp_usb_notifier);
usb_for_each_dev(&keyboard_attached, oxp_find_keyboard);
input_report_switch(oxp_tablet_mode_input, SW_TABLET_MODE,
!keyboard_attached);
input_sync(oxp_tablet_mode_input);
break;
default:
break;
}

return 0;
}

Expand Down Expand Up @@ -994,6 +1123,9 @@ static int __init oxp_platform_init(void)

static void __exit oxp_platform_exit(void)
{
if (board == oxp_x1 || board == oxp_super_x)
usb_unregister_notify(&oxp_usb_notifier);

platform_device_unregister(oxp_platform_device);
platform_driver_unregister(&oxp_platform_driver);
}
Expand Down