summaryrefslogtreecommitdiff
path: root/include/linux/wmi.h
blob: 75cb0c7cfe57135ef9b0589d71be89a2d55e407b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * wmi.h - ACPI WMI interface
 *
 * Copyright (c) 2015 Andrew Lutomirski
 */

#ifndef _LINUX_WMI_H
#define _LINUX_WMI_H

#include <linux/compiler_attributes.h>
#include <linux/device.h>
#include <linux/acpi.h>
#include <linux/mod_devicetable.h>
#include <linux/types.h>

/**
 * struct wmi_device - WMI device structure
 * @dev: Device associated with this WMI device
 * @setable: True for devices implementing the Set Control Method
 * @driver_override: Driver name to force a match; do not set directly,
 *		     because core frees it; use driver_set_override() to
 *		     set or clear it.
 *
 * This represents WMI devices discovered by the WMI driver core.
 */
struct wmi_device {
	struct device dev;
	bool setable;
	const char *driver_override;
};

/**
 * to_wmi_device() - Helper macro to cast a device to a wmi_device
 * @device: device struct
 *
 * Cast a struct device to a struct wmi_device.
 */
#define to_wmi_device(device)	container_of_const(device, struct wmi_device, dev)

/**
 * struct wmi_buffer - WMI data buffer
 * @length: Buffer length in bytes
 * @data: Pointer to the buffer content
 *
 * This structure is used to exchange data with the WMI driver core.
 */
struct wmi_buffer {
	size_t length;
	void *data;
};

/**
 * struct wmi_string - WMI string representation
 * @length: Size of @chars in bytes
 * @chars: UTF16-LE characters with optional nul termination and padding
 *
 * This structure is used when exchanging string data over the WMI interface.
 */
struct wmi_string {
	__le16 length;
	__le16 chars[];
} __packed;

ssize_t wmi_string_to_utf8s(const struct wmi_string *str, u8 *dst, size_t length);

ssize_t wmi_string_from_utf8s(struct wmi_string *str, size_t max_chars, const u8 *src,
			      size_t src_length);

int wmidev_invoke_method(struct wmi_device *wdev, u8 instance, u32 method_id,
			 const struct wmi_buffer *in, struct wmi_buffer *out);

int wmidev_query_block(struct wmi_device *wdev, u8 instance, struct wmi_buffer *out);

int wmidev_set_block(struct wmi_device *wdev, u8 instance, const struct wmi_buffer *in);

acpi_status wmidev_evaluate_method(struct wmi_device *wdev, u8 instance, u32 method_id,
				   const struct acpi_buffer *in, struct acpi_buffer *out);

union acpi_object *wmidev_block_query(struct wmi_device *wdev, u8 instance);

acpi_status wmidev_block_set(struct wmi_device *wdev, u8 instance, const struct acpi_buffer *in);

u8 wmidev_instance_count(struct wmi_device *wdev);

/**
 * struct wmi_driver - WMI driver structure
 * @driver: Driver model structure
 * @id_table: List of WMI GUIDs supported by this driver
 * @no_notify_data: Driver supports WMI events which provide no event data
 * @no_singleton: Driver can be instantiated multiple times
 * @probe: Callback for device binding
 * @remove: Callback for device unbinding
 * @shutdown: Callback for device shutdown
 * @notify: Callback for receiving WMI events (deprecated)
 * @notify_new: Callback for receiving WMI events
 *
 * This represents WMI drivers which handle WMI devices. The data inside the buffer
 * passed to the @notify_new callback is guaranteed to be aligned on a 8-byte boundary.
 */
struct wmi_driver {
	struct device_driver driver;
	const struct wmi_device_id *id_table;
	bool no_notify_data;
	bool no_singleton;

	int (*probe)(struct wmi_device *wdev, const void *context);
	void (*remove)(struct wmi_device *wdev);
	void (*shutdown)(struct wmi_device *wdev);
	void (*notify)(struct wmi_device *device, union acpi_object *data);
	void (*notify_new)(struct wmi_device *device, const struct wmi_buffer *data);
};

/**
 * to_wmi_driver() - Helper macro to cast a driver to a wmi_driver
 * @drv: driver struct
 *
 * Cast a struct device_driver to a struct wmi_driver.
 */
#define to_wmi_driver(drv)	container_of_const(drv, struct wmi_driver, driver)

int __must_check __wmi_driver_register(struct wmi_driver *driver, struct module *owner);

void wmi_driver_unregister(struct wmi_driver *driver);

/**
 * wmi_driver_register() - Helper macro to register a WMI driver
 * @driver: wmi_driver struct
 *
 * Helper macro for registering a WMI driver. It automatically passes
 * THIS_MODULE to the underlying function.
 */
#define wmi_driver_register(driver) __wmi_driver_register((driver), THIS_MODULE)

/**
 * module_wmi_driver() - Helper macro to register/unregister a WMI driver
 * @__wmi_driver: wmi_driver struct
 *
 * Helper macro for WMI drivers which do not do anything special in module
 * init/exit. This eliminates a lot of boilerplate. Each module may only
 * use this macro once, and calling it replaces module_init() and module_exit().
 */
#define module_wmi_driver(__wmi_driver) \
	module_driver(__wmi_driver, wmi_driver_register, \
		      wmi_driver_unregister)

#endif