17b3d4f44SNick Crews /* SPDX-License-Identifier: GPL-2.0 */
27b3d4f44SNick Crews /*
37b3d4f44SNick Crews  * ChromeOS Wilco Embedded Controller
47b3d4f44SNick Crews  *
57b3d4f44SNick Crews  * Copyright 2018 Google LLC
67b3d4f44SNick Crews  */
77b3d4f44SNick Crews 
87b3d4f44SNick Crews #ifndef WILCO_EC_H
97b3d4f44SNick Crews #define WILCO_EC_H
107b3d4f44SNick Crews 
118673e944SAndy Shevchenko #include <linux/mutex.h>
128673e944SAndy Shevchenko #include <linux/types.h>
137b3d4f44SNick Crews 
147b3d4f44SNick Crews /* Message flags for using the mailbox() interface */
157b3d4f44SNick Crews #define WILCO_EC_FLAG_NO_RESPONSE	BIT(0) /* EC does not respond */
167b3d4f44SNick Crews 
177b3d4f44SNick Crews /* Normal commands have a maximum 32 bytes of data */
187b3d4f44SNick Crews #define EC_MAILBOX_DATA_SIZE		32
197b3d4f44SNick Crews 
208673e944SAndy Shevchenko struct device;
218673e944SAndy Shevchenko struct resource;
228673e944SAndy Shevchenko struct platform_device;
238673e944SAndy Shevchenko 
247b3d4f44SNick Crews /**
257b3d4f44SNick Crews  * struct wilco_ec_device - Wilco Embedded Controller handle.
267b3d4f44SNick Crews  * @dev: Device handle.
277b3d4f44SNick Crews  * @mailbox_lock: Mutex to ensure one mailbox command at a time.
287b3d4f44SNick Crews  * @io_command: I/O port for mailbox command.  Provided by ACPI.
297b3d4f44SNick Crews  * @io_data: I/O port for mailbox data.  Provided by ACPI.
307b3d4f44SNick Crews  * @io_packet: I/O port for mailbox packet data.  Provided by ACPI.
317b3d4f44SNick Crews  * @data_buffer: Buffer used for EC communication.  The same buffer
327b3d4f44SNick Crews  *               is used to hold the request and the response.
337b3d4f44SNick Crews  * @data_size: Size of the data buffer used for EC communication.
34b787bb12SNick Crews  * @debugfs_pdev: The child platform_device used by the debugfs sub-driver.
350d2f2a3dSNick Crews  * @rtc_pdev: The child platform_device used by the RTC sub-driver.
363c4d77b6SNick Crews  * @charger_pdev: Child platform_device used by the charger config sub-driver.
371210d1e6SNick Crews  * @telem_pdev: The child platform_device used by the telemetry sub-driver.
387b3d4f44SNick Crews  */
397b3d4f44SNick Crews struct wilco_ec_device {
407b3d4f44SNick Crews 	struct device *dev;
417b3d4f44SNick Crews 	struct mutex mailbox_lock;
427b3d4f44SNick Crews 	struct resource *io_command;
437b3d4f44SNick Crews 	struct resource *io_data;
447b3d4f44SNick Crews 	struct resource *io_packet;
457b3d4f44SNick Crews 	void *data_buffer;
467b3d4f44SNick Crews 	size_t data_size;
47b787bb12SNick Crews 	struct platform_device *debugfs_pdev;
480d2f2a3dSNick Crews 	struct platform_device *rtc_pdev;
493c4d77b6SNick Crews 	struct platform_device *charger_pdev;
501210d1e6SNick Crews 	struct platform_device *telem_pdev;
517b3d4f44SNick Crews };
527b3d4f44SNick Crews 
537b3d4f44SNick Crews /**
547b3d4f44SNick Crews  * struct wilco_ec_request - Mailbox request message format.
557b3d4f44SNick Crews  * @struct_version: Should be %EC_MAILBOX_PROTO_VERSION
567b3d4f44SNick Crews  * @checksum: Sum of all bytes must be 0.
577b3d4f44SNick Crews  * @mailbox_id: Mailbox identifier, specifies the command set.
587b3d4f44SNick Crews  * @mailbox_version: Mailbox interface version %EC_MAILBOX_VERSION
597b3d4f44SNick Crews  * @reserved: Set to zero.
6014e14aafSNick Crews  * @data_size: Length of following data.
617b3d4f44SNick Crews  */
627b3d4f44SNick Crews struct wilco_ec_request {
637b3d4f44SNick Crews 	u8 struct_version;
647b3d4f44SNick Crews 	u8 checksum;
657b3d4f44SNick Crews 	u16 mailbox_id;
667b3d4f44SNick Crews 	u8 mailbox_version;
677b3d4f44SNick Crews 	u8 reserved;
687b3d4f44SNick Crews 	u16 data_size;
697b3d4f44SNick Crews } __packed;
707b3d4f44SNick Crews 
717b3d4f44SNick Crews /**
727b3d4f44SNick Crews  * struct wilco_ec_response - Mailbox response message format.
737b3d4f44SNick Crews  * @struct_version: Should be %EC_MAILBOX_PROTO_VERSION
747b3d4f44SNick Crews  * @checksum: Sum of all bytes must be 0.
757b3d4f44SNick Crews  * @result: Result code from the EC.  Non-zero indicates an error.
767b3d4f44SNick Crews  * @data_size: Length of the response data buffer.
777b3d4f44SNick Crews  * @reserved: Set to zero.
787b3d4f44SNick Crews  * @data: Response data buffer.  Max size is %EC_MAILBOX_DATA_SIZE_EXTENDED.
797b3d4f44SNick Crews  */
807b3d4f44SNick Crews struct wilco_ec_response {
817b3d4f44SNick Crews 	u8 struct_version;
827b3d4f44SNick Crews 	u8 checksum;
837b3d4f44SNick Crews 	u16 result;
847b3d4f44SNick Crews 	u16 data_size;
857b3d4f44SNick Crews 	u8 reserved[2];
86*1223f3dbSGustavo A. R. Silva 	u8 data[];
877b3d4f44SNick Crews } __packed;
887b3d4f44SNick Crews 
897b3d4f44SNick Crews /**
907b3d4f44SNick Crews  * enum wilco_ec_msg_type - Message type to select a set of command codes.
917b3d4f44SNick Crews  * @WILCO_EC_MSG_LEGACY: Legacy EC messages for standard EC behavior.
927b3d4f44SNick Crews  * @WILCO_EC_MSG_PROPERTY: Get/Set/Sync EC controlled NVRAM property.
932ad1f7a9SNick Crews  * @WILCO_EC_MSG_TELEMETRY: Request telemetry data from the EC.
947b3d4f44SNick Crews  */
957b3d4f44SNick Crews enum wilco_ec_msg_type {
967b3d4f44SNick Crews 	WILCO_EC_MSG_LEGACY = 0x00f0,
977b3d4f44SNick Crews 	WILCO_EC_MSG_PROPERTY = 0x00f2,
982ad1f7a9SNick Crews 	WILCO_EC_MSG_TELEMETRY = 0x00f5,
997b3d4f44SNick Crews };
1007b3d4f44SNick Crews 
1017b3d4f44SNick Crews /**
1027b3d4f44SNick Crews  * struct wilco_ec_message - Request and response message.
1037b3d4f44SNick Crews  * @type: Mailbox message type.
1047b3d4f44SNick Crews  * @flags: Message flags, e.g. %WILCO_EC_FLAG_NO_RESPONSE.
1057b3d4f44SNick Crews  * @request_size: Number of bytes to send to the EC.
1067b3d4f44SNick Crews  * @request_data: Buffer containing the request data.
10714e14aafSNick Crews  * @response_size: Number of bytes to read from EC.
1087b3d4f44SNick Crews  * @response_data: Buffer containing the response data, should be
1097b3d4f44SNick Crews  *                 response_size bytes and allocated by caller.
1107b3d4f44SNick Crews  */
1117b3d4f44SNick Crews struct wilco_ec_message {
1127b3d4f44SNick Crews 	enum wilco_ec_msg_type type;
1137b3d4f44SNick Crews 	u8 flags;
1147b3d4f44SNick Crews 	size_t request_size;
1157b3d4f44SNick Crews 	void *request_data;
1167b3d4f44SNick Crews 	size_t response_size;
1177b3d4f44SNick Crews 	void *response_data;
1187b3d4f44SNick Crews };
1197b3d4f44SNick Crews 
1207b3d4f44SNick Crews /**
1217b3d4f44SNick Crews  * wilco_ec_mailbox() - Send request to the EC and receive the response.
1227b3d4f44SNick Crews  * @ec: Wilco EC device.
1237b3d4f44SNick Crews  * @msg: Wilco EC message.
1247b3d4f44SNick Crews  *
1257b3d4f44SNick Crews  * Return: Number of bytes received or negative error code on failure.
1267b3d4f44SNick Crews  */
1277b3d4f44SNick Crews int wilco_ec_mailbox(struct wilco_ec_device *ec, struct wilco_ec_message *msg);
1287b3d4f44SNick Crews 
129119a3cb6SDaniel Campello /**
130119a3cb6SDaniel Campello  * wilco_keyboard_leds_init() - Set up the keyboard backlight LEDs.
131119a3cb6SDaniel Campello  * @ec: EC device to query.
132119a3cb6SDaniel Campello  *
133119a3cb6SDaniel Campello  * After this call, the keyboard backlight will be exposed through a an LED
134119a3cb6SDaniel Campello  * device at /sys/class/leds.
135119a3cb6SDaniel Campello  *
136119a3cb6SDaniel Campello  * This may sleep because it uses wilco_ec_mailbox().
137119a3cb6SDaniel Campello  *
138119a3cb6SDaniel Campello  * Return: 0 on success, negative error code on failure.
139119a3cb6SDaniel Campello  */
140119a3cb6SDaniel Campello int wilco_keyboard_leds_init(struct wilco_ec_device *ec);
141119a3cb6SDaniel Campello 
1420c0b7ea2SNick Crews /*
1430c0b7ea2SNick Crews  * A Property is typically a data item that is stored to NVRAM
1440c0b7ea2SNick Crews  * by the EC. Each of these data items has an index associated
1450c0b7ea2SNick Crews  * with it, known as the Property ID (PID). Properties may have
1460c0b7ea2SNick Crews  * variable lengths, up to a max of WILCO_EC_PROPERTY_MAX_SIZE
1470c0b7ea2SNick Crews  * bytes. Properties can be simple integers, or they may be more
1480c0b7ea2SNick Crews  * complex binary data.
1490c0b7ea2SNick Crews  */
1500c0b7ea2SNick Crews 
1510c0b7ea2SNick Crews #define WILCO_EC_PROPERTY_MAX_SIZE	4
1520c0b7ea2SNick Crews 
1530c0b7ea2SNick Crews /**
1540c0b7ea2SNick Crews  * struct ec_property_set_msg - Message to get or set a property.
1550c0b7ea2SNick Crews  * @property_id: Which property to get or set.
1560c0b7ea2SNick Crews  * @length: Number of bytes of |data| that are used.
1570c0b7ea2SNick Crews  * @data: Actual property data.
1580c0b7ea2SNick Crews  */
1590c0b7ea2SNick Crews struct wilco_ec_property_msg {
1600c0b7ea2SNick Crews 	u32 property_id;
1610c0b7ea2SNick Crews 	int length;
1620c0b7ea2SNick Crews 	u8 data[WILCO_EC_PROPERTY_MAX_SIZE];
1630c0b7ea2SNick Crews };
1640c0b7ea2SNick Crews 
1650c0b7ea2SNick Crews /**
1660c0b7ea2SNick Crews  * wilco_ec_get_property() - Retrieve a property from the EC.
1670c0b7ea2SNick Crews  * @ec: Embedded Controller device.
1680c0b7ea2SNick Crews  * @prop_msg: Message for request and response.
1690c0b7ea2SNick Crews  *
1700c0b7ea2SNick Crews  * The property_id field of |prop_msg| should be filled before calling this
1710c0b7ea2SNick Crews  * function. The result will be stored in the data and length fields.
1720c0b7ea2SNick Crews  *
1730c0b7ea2SNick Crews  * Return: 0 on success, negative error code on failure.
1740c0b7ea2SNick Crews  */
1750c0b7ea2SNick Crews int wilco_ec_get_property(struct wilco_ec_device *ec,
1760c0b7ea2SNick Crews 			  struct wilco_ec_property_msg *prop_msg);
1770c0b7ea2SNick Crews 
1780c0b7ea2SNick Crews /**
1790c0b7ea2SNick Crews  * wilco_ec_set_property() - Store a property on the EC.
1800c0b7ea2SNick Crews  * @ec: Embedded Controller device.
1810c0b7ea2SNick Crews  * @prop_msg: Message for request and response.
1820c0b7ea2SNick Crews  *
1830c0b7ea2SNick Crews  * The property_id, length, and data fields of |prop_msg| should be
1840c0b7ea2SNick Crews  * filled before calling this function.
1850c0b7ea2SNick Crews  *
1860c0b7ea2SNick Crews  * Return: 0 on success, negative error code on failure.
1870c0b7ea2SNick Crews  */
1880c0b7ea2SNick Crews int wilco_ec_set_property(struct wilco_ec_device *ec,
1890c0b7ea2SNick Crews 			  struct wilco_ec_property_msg *prop_msg);
1900c0b7ea2SNick Crews 
1910c0b7ea2SNick Crews /**
1920c0b7ea2SNick Crews  * wilco_ec_get_byte_property() - Retrieve a byte-size property from the EC.
1930c0b7ea2SNick Crews  * @ec: Embedded Controller device.
1940c0b7ea2SNick Crews  * @property_id: Which property to retrieve.
1950c0b7ea2SNick Crews  * @val: The result value, will be filled by this function.
1960c0b7ea2SNick Crews  *
1970c0b7ea2SNick Crews  * Return: 0 on success, negative error code on failure.
1980c0b7ea2SNick Crews  */
1990c0b7ea2SNick Crews int wilco_ec_get_byte_property(struct wilco_ec_device *ec, u32 property_id,
2000c0b7ea2SNick Crews 			       u8 *val);
2010c0b7ea2SNick Crews 
2020c0b7ea2SNick Crews /**
2030c0b7ea2SNick Crews  * wilco_ec_get_byte_property() - Store a byte-size property on the EC.
2040c0b7ea2SNick Crews  * @ec: Embedded Controller device.
2050c0b7ea2SNick Crews  * @property_id: Which property to store.
2060c0b7ea2SNick Crews  * @val: Value to store.
2070c0b7ea2SNick Crews  *
2080c0b7ea2SNick Crews  * Return: 0 on success, negative error code on failure.
2090c0b7ea2SNick Crews  */
2100c0b7ea2SNick Crews int wilco_ec_set_byte_property(struct wilco_ec_device *ec, u32 property_id,
2110c0b7ea2SNick Crews 			       u8 val);
2120c0b7ea2SNick Crews 
2134c1ca625SNick Crews /**
2144c1ca625SNick Crews  * wilco_ec_add_sysfs() - Create sysfs entries
2154c1ca625SNick Crews  * @ec: Wilco EC device
2164c1ca625SNick Crews  *
2174c1ca625SNick Crews  * wilco_ec_remove_sysfs() needs to be called afterwards
2184c1ca625SNick Crews  * to perform the necessary cleanup.
2194c1ca625SNick Crews  *
2204c1ca625SNick Crews  * Return: 0 on success or negative error code on failure.
2214c1ca625SNick Crews  */
2224c1ca625SNick Crews int wilco_ec_add_sysfs(struct wilco_ec_device *ec);
2234c1ca625SNick Crews void wilco_ec_remove_sysfs(struct wilco_ec_device *ec);
2244c1ca625SNick Crews 
2257b3d4f44SNick Crews #endif /* WILCO_EC_H */
226