Skip to content
This repository was archived by the owner on Oct 31, 2024. It is now read-only.

Commit 4b7eb04

Browse files
authored
Merge pull request #418 from guylamar2006/6.7-mod1
Added Steam Deck ACPI Functionality (extcon, hwmon, leds, mfd)
2 parents defd16d + ce51560 commit 4b7eb04

13 files changed

Lines changed: 740 additions & 0 deletions

File tree

CONFIGS/xanmod/gcc/config_x86-64-v3

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5547,6 +5547,7 @@ CONFIG_SENSORS_SMSC47B397=m
55475547
CONFIG_SENSORS_SCH56XX_COMMON=m
55485548
CONFIG_SENSORS_SCH5627=m
55495549
CONFIG_SENSORS_SCH5636=m
5550+
CONFIG_SENSORS_STEAMDECK=m
55505551
CONFIG_SENSORS_STTS751=m
55515552
CONFIG_SENSORS_ADC128D818=m
55525553
CONFIG_SENSORS_ADS7828=m
@@ -5893,6 +5894,7 @@ CONFIG_RAVE_SP_CORE=m
58935894
CONFIG_MFD_INTEL_M10_BMC_CORE=m
58945895
CONFIG_MFD_INTEL_M10_BMC_SPI=m
58955896
CONFIG_MFD_INTEL_M10_BMC_PMCI=m
5897+
CONFIG_MFD_STEAMDECK=m
58965898
# end of Multifunction device drivers
58975899

58985900
CONFIG_REGULATOR=y
@@ -8852,6 +8854,7 @@ CONFIG_LEDS_NIC78BX=m
88528854
CONFIG_LEDS_TI_LMU_COMMON=m
88538855
CONFIG_LEDS_LM36274=m
88548856
CONFIG_LEDS_TPS6105X=m
8857+
CONFIG_LEDS_STEAMDECK=m
88558858

88568859
#
88578860
# Flash and Torch LED drivers
@@ -9943,6 +9946,7 @@ CONFIG_EXTCON_SM5502=m
99439946
CONFIG_EXTCON_USB_GPIO=m
99449947
CONFIG_EXTCON_USBC_CROS_EC=m
99459948
CONFIG_EXTCON_USBC_TUSB320=m
9949+
CONFIG_EXTCON_STEAMDECK=m
99469950
CONFIG_MEMORY=y
99479951
CONFIG_FPGA_DFL_EMIF=m
99489952
CONFIG_IIO=m

drivers/extcon/Kconfig

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,4 +202,11 @@ config EXTCON_RTK_TYPE_C
202202
The DHC (Digital Home Hub) RTD series SoC contains a type c module.
203203
This driver will detect the status of the type-c port.
204204

205+
config EXTCON_STEAMDECK
206+
tristate "Steam Deck extcon support"
207+
depends on MFD_STEAMDECK
208+
help
209+
Say Y here to enable support of USB Type C cable detection extcon
210+
support on Steam Deck devices
211+
205212
endif

drivers/extcon/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,4 @@ obj-$(CONFIG_EXTCON_USB_GPIO) += extcon-usb-gpio.o
2626
obj-$(CONFIG_EXTCON_USBC_CROS_EC) += extcon-usbc-cros-ec.o
2727
obj-$(CONFIG_EXTCON_USBC_TUSB320) += extcon-usbc-tusb320.o
2828
obj-$(CONFIG_EXTCON_RTK_TYPE_C) += extcon-rtk-type-c.o
29+
obj-$(CONFIG_EXTCON_STEAMDECK) += extcon-steamdeck.o

drivers/extcon/extcon-steamdeck.c

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
2+
#include <linux/acpi.h>
3+
#include <linux/platform_device.h>
4+
#include <linux/extcon-provider.h>
5+
6+
#define ACPI_STEAMDECK_NOTIFY_STATUS 0x80
7+
8+
/* 0 - port connected, 1 -port disconnected */
9+
#define ACPI_STEAMDECK_PORT_CONNECT BIT(0)
10+
/* 0 - Upstream Facing Port, 1 - Downdstream Facing Port */
11+
#define ACPI_STEAMDECK_CUR_DATA_ROLE BIT(3)
12+
/*
13+
* Debouncing delay to allow negotiation process to settle. 2s value
14+
* was arrived at via trial and error.
15+
*/
16+
#define STEAMDECK_ROLE_SWITCH_DELAY (msecs_to_jiffies(2000))
17+
18+
struct steamdeck_extcon {
19+
struct acpi_device *adev;
20+
struct delayed_work role_work;
21+
struct extcon_dev *edev;
22+
struct device *dev;
23+
};
24+
25+
static int steamdeck_read_pdcs(struct steamdeck_extcon *sd, unsigned long long *pdcs)
26+
{
27+
acpi_status status;
28+
29+
status = acpi_evaluate_integer(sd->adev->handle, "PDCS", NULL, pdcs);
30+
if (ACPI_FAILURE(status)) {
31+
dev_err(sd->dev, "PDCS evaluation failed: %s\n",
32+
acpi_format_exception(status));
33+
return -EIO;
34+
}
35+
36+
return 0;
37+
}
38+
39+
static void steamdeck_usb_role_work(struct work_struct *work)
40+
{
41+
struct steamdeck_extcon *sd =
42+
container_of(work, struct steamdeck_extcon, role_work.work);
43+
unsigned long long pdcs;
44+
bool usb_host;
45+
46+
if (steamdeck_read_pdcs(sd, &pdcs))
47+
return;
48+
49+
/*
50+
* We only care about these two
51+
*/
52+
pdcs &= ACPI_STEAMDECK_PORT_CONNECT | ACPI_STEAMDECK_CUR_DATA_ROLE;
53+
54+
/*
55+
* For "connect" events our role is determined by a bit in
56+
* PDCS, for "disconnect" we switch to being a gadget
57+
* unconditionally. The thinking for the latter is we don't
58+
* want to start acting as a USB host until we get
59+
* confirmation from the firmware that we are a USB host
60+
*/
61+
usb_host = (pdcs & ACPI_STEAMDECK_PORT_CONNECT) ?
62+
pdcs & ACPI_STEAMDECK_CUR_DATA_ROLE : false;
63+
64+
dev_dbg(sd->dev, "USB role is %s\n", usb_host ? "host" : "device");
65+
WARN_ON(extcon_set_state_sync(sd->edev, EXTCON_USB_HOST,
66+
usb_host));
67+
68+
}
69+
70+
static void steamdeck_notify(acpi_handle handle, u32 event, void *context)
71+
{
72+
struct device *dev = context;
73+
struct steamdeck_extcon *sd = dev_get_drvdata(dev);
74+
unsigned long long pdcs;
75+
unsigned long delay;
76+
77+
switch (event) {
78+
case ACPI_STEAMDECK_NOTIFY_STATUS:
79+
if (steamdeck_read_pdcs(sd, &pdcs))
80+
return;
81+
/*
82+
* We process "disconnect" events immediately and
83+
* "connect" events with a delay to give the HW time
84+
* to settle. For example attaching USB hub (at least
85+
* for HW used for testing) will generate intermediary
86+
* event with "host" bit not set, followed by the one
87+
* that does have it set.
88+
*/
89+
delay = (pdcs & ACPI_STEAMDECK_PORT_CONNECT) ?
90+
STEAMDECK_ROLE_SWITCH_DELAY : 0;
91+
92+
queue_delayed_work(system_long_wq, &sd->role_work, delay);
93+
break;
94+
default:
95+
dev_warn(dev, "Unsupported event [0x%x]\n", event);
96+
}
97+
}
98+
99+
static void steamdeck_remove_notify_handler(void *data)
100+
{
101+
struct steamdeck_extcon *sd = data;
102+
103+
acpi_remove_notify_handler(sd->adev->handle, ACPI_DEVICE_NOTIFY,
104+
steamdeck_notify);
105+
cancel_delayed_work_sync(&sd->role_work);
106+
}
107+
108+
static const unsigned int steamdeck_extcon_cable[] = {
109+
EXTCON_USB,
110+
EXTCON_USB_HOST,
111+
EXTCON_CHG_USB_SDP,
112+
EXTCON_CHG_USB_CDP,
113+
EXTCON_CHG_USB_DCP,
114+
EXTCON_CHG_USB_ACA,
115+
EXTCON_NONE,
116+
};
117+
118+
static int steamdeck_extcon_probe(struct platform_device *pdev)
119+
{
120+
struct device *dev = &pdev->dev;
121+
struct steamdeck_extcon *sd;
122+
acpi_status status;
123+
int ret;
124+
125+
sd = devm_kzalloc(dev, sizeof(*sd), GFP_KERNEL);
126+
if (!sd)
127+
return -ENOMEM;
128+
129+
INIT_DELAYED_WORK(&sd->role_work, steamdeck_usb_role_work);
130+
platform_set_drvdata(pdev, sd);
131+
sd->adev = ACPI_COMPANION(dev->parent);
132+
sd->dev = dev;
133+
sd->edev = devm_extcon_dev_allocate(dev, steamdeck_extcon_cable);
134+
if (IS_ERR(sd->edev))
135+
return PTR_ERR(sd->edev);
136+
137+
ret = devm_extcon_dev_register(dev, sd->edev);
138+
if (ret < 0) {
139+
dev_err(dev, "Failed to register extcon device: %d\n", ret);
140+
return ret;
141+
}
142+
143+
/*
144+
* Set initial role value
145+
*/
146+
queue_delayed_work(system_long_wq, &sd->role_work, 0);
147+
flush_delayed_work(&sd->role_work);
148+
149+
status = acpi_install_notify_handler(sd->adev->handle,
150+
ACPI_DEVICE_NOTIFY,
151+
steamdeck_notify,
152+
dev);
153+
if (ACPI_FAILURE(status)) {
154+
dev_err(dev, "Error installing ACPI notify handler\n");
155+
return -EIO;
156+
}
157+
158+
ret = devm_add_action_or_reset(dev, steamdeck_remove_notify_handler,
159+
sd);
160+
return ret;
161+
}
162+
163+
static const struct platform_device_id steamdeck_extcon_id_table[] = {
164+
{ .name = "steamdeck-extcon" },
165+
{}
166+
};
167+
MODULE_DEVICE_TABLE(platform, steamdeck_extcon_id_table);
168+
169+
static struct platform_driver steamdeck_extcon_driver = {
170+
.probe = steamdeck_extcon_probe,
171+
.driver = {
172+
.name = "steamdeck-extcon",
173+
},
174+
.id_table = steamdeck_extcon_id_table,
175+
};
176+
module_platform_driver(steamdeck_extcon_driver);
177+
178+
MODULE_AUTHOR("Andrey Smirnov <andrew.smirnov@gmail.com>");
179+
MODULE_DESCRIPTION("Steam Deck extcon driver");
180+
MODULE_LICENSE("GPL");

drivers/hwmon/Kconfig

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1963,6 +1963,17 @@ config SENSORS_SCH5636
19631963
This driver can also be built as a module. If so, the module
19641964
will be called sch5636.
19651965

1966+
config SENSORS_STEAMDECK
1967+
tristate "Steam Deck EC sensors"
1968+
depends on MFD_STEAMDECK
1969+
help
1970+
If you say yes here you get support for the hardware
1971+
monitoring features exposed by EC firmware on Steam Deck
1972+
devices
1973+
1974+
This driver can also be built as a module. If so, the module
1975+
will be called steamdeck-hwmon.
1976+
19661977
config SENSORS_STTS751
19671978
tristate "ST Microelectronics STTS751"
19681979
depends on I2C

drivers/hwmon/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,7 @@ obj-$(CONFIG_SENSORS_SMSC47B397)+= smsc47b397.o
199199
obj-$(CONFIG_SENSORS_SMSC47M1) += smsc47m1.o
200200
obj-$(CONFIG_SENSORS_SMSC47M192)+= smsc47m192.o
201201
obj-$(CONFIG_SENSORS_SPARX5) += sparx5-temp.o
202+
obj-$(CONFIG_SENSORS_STEAMDECK) += steamdeck-hwmon.o
202203
obj-$(CONFIG_SENSORS_STTS751) += stts751.o
203204
obj-$(CONFIG_SENSORS_SY7636A) += sy7636a-hwmon.o
204205
obj-$(CONFIG_SENSORS_AMC6821) += amc6821.o

0 commit comments

Comments
 (0)