Skip to content

Commit fdf0fe2

Browse files
djcampelloEnric Balletbo i Serra
authored andcommitted
platform/chrome: wilco_ec: Add Dell's USB PowerShare Policy control
USB PowerShare is a policy which affects charging via the special USB PowerShare port (marked with a small lightning bolt or battery icon) when in low power states: - In S0, the port will always provide power. - In S0ix, if usb_charge is enabled, then power will be supplied to the port when on AC or if battery is > 50%. Else no power is supplied. - In S5, if usb_charge is enabled, then power will be supplied to the port when on AC. Else no power is supplied. Signed-off-by: Daniel Campello <[email protected]> Signed-off-by: Nick Crews <[email protected]> Signed-off-by: Enric Balletbo i Serra <[email protected]>
1 parent e6679fd commit fdf0fe2

File tree

2 files changed

+108
-0
lines changed

2 files changed

+108
-0
lines changed

Documentation/ABI/testing/sysfs-platform-wilco-ec

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,23 @@ Description:
3131
Output will a version string be similar to the example below:
3232
08B6
3333

34+
What: /sys/bus/platform/devices/GOOG000C\:00/usb_charge
35+
Date: October 2019
36+
KernelVersion: 5.5
37+
Description:
38+
Control the USB PowerShare Policy. USB PowerShare is a policy
39+
which affects charging via the special USB PowerShare port
40+
(marked with a small lightning bolt or battery icon) when in
41+
low power states:
42+
- In S0, the port will always provide power.
43+
- In S0ix, if usb_charge is enabled, then power will be
44+
supplied to the port when on AC or if battery is > 50%.
45+
Else no power is supplied.
46+
- In S5, if usb_charge is enabled, then power will be supplied
47+
to the port when on AC. Else no power is supplied.
48+
49+
Input should be either "0" or "1".
50+
3451
What: /sys/bus/platform/devices/GOOG000C\:00/version
3552
Date: May 2019
3653
KernelVersion: 5.3

drivers/platform/chrome/wilco_ec/sysfs.c

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,26 @@ struct boot_on_ac_request {
2323
u8 reserved7;
2424
} __packed;
2525

26+
#define CMD_USB_CHARGE 0x39
27+
28+
enum usb_charge_op {
29+
USB_CHARGE_GET = 0,
30+
USB_CHARGE_SET = 1,
31+
};
32+
33+
struct usb_charge_request {
34+
u8 cmd; /* Always CMD_USB_CHARGE */
35+
u8 reserved;
36+
u8 op; /* One of enum usb_charge_op */
37+
u8 val; /* When setting, either 0 or 1 */
38+
} __packed;
39+
40+
struct usb_charge_response {
41+
u8 reserved;
42+
u8 status; /* Set by EC to 0 on success, other value on failure */
43+
u8 val; /* When getting, set by EC to either 0 or 1 */
44+
} __packed;
45+
2646
#define CMD_EC_INFO 0x38
2747
enum get_ec_info_op {
2848
CMD_GET_EC_LABEL = 0,
@@ -131,12 +151,83 @@ static ssize_t model_number_show(struct device *dev,
131151

132152
static DEVICE_ATTR_RO(model_number);
133153

154+
static int send_usb_charge(struct wilco_ec_device *ec,
155+
struct usb_charge_request *rq,
156+
struct usb_charge_response *rs)
157+
{
158+
struct wilco_ec_message msg;
159+
int ret;
160+
161+
memset(&msg, 0, sizeof(msg));
162+
msg.type = WILCO_EC_MSG_LEGACY;
163+
msg.request_data = rq;
164+
msg.request_size = sizeof(*rq);
165+
msg.response_data = rs;
166+
msg.response_size = sizeof(*rs);
167+
ret = wilco_ec_mailbox(ec, &msg);
168+
if (ret < 0)
169+
return ret;
170+
if (rs->status)
171+
return -EIO;
172+
173+
return 0;
174+
}
175+
176+
static ssize_t usb_charge_show(struct device *dev,
177+
struct device_attribute *attr, char *buf)
178+
{
179+
struct wilco_ec_device *ec = dev_get_drvdata(dev);
180+
struct usb_charge_request rq;
181+
struct usb_charge_response rs;
182+
int ret;
183+
184+
memset(&rq, 0, sizeof(rq));
185+
rq.cmd = CMD_USB_CHARGE;
186+
rq.op = USB_CHARGE_GET;
187+
188+
ret = send_usb_charge(ec, &rq, &rs);
189+
if (ret < 0)
190+
return ret;
191+
192+
return sprintf(buf, "%d\n", rs.val);
193+
}
194+
195+
static ssize_t usb_charge_store(struct device *dev,
196+
struct device_attribute *attr,
197+
const char *buf, size_t count)
198+
{
199+
struct wilco_ec_device *ec = dev_get_drvdata(dev);
200+
struct usb_charge_request rq;
201+
struct usb_charge_response rs;
202+
int ret;
203+
u8 val;
204+
205+
ret = kstrtou8(buf, 10, &val);
206+
if (ret < 0)
207+
return ret;
208+
if (val > 1)
209+
return -EINVAL;
210+
211+
memset(&rq, 0, sizeof(rq));
212+
rq.cmd = CMD_USB_CHARGE;
213+
rq.op = USB_CHARGE_SET;
214+
rq.val = val;
215+
216+
ret = send_usb_charge(ec, &rq, &rs);
217+
if (ret < 0)
218+
return ret;
219+
220+
return count;
221+
}
222+
223+
static DEVICE_ATTR_RW(usb_charge);
134224

135225
static struct attribute *wilco_dev_attrs[] = {
136226
&dev_attr_boot_on_ac.attr,
137227
&dev_attr_build_date.attr,
138228
&dev_attr_build_revision.attr,
139229
&dev_attr_model_number.attr,
230+
&dev_attr_usb_charge.attr,
140231
&dev_attr_version.attr,
141232
NULL,
142233
};

0 commit comments

Comments
 (0)