summaryrefslogtreecommitdiff
path: root/common/mkbp_info.c
blob: b3835367cf5bc6394935ac8ef9b54261c5e36b70 (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
/* Copyright 2021 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

/* MKBP info host command */

#include "common.h"
#include "console.h"
#include "ec_commands.h"
#include "host_command.h"
#include "keyboard_config.h"
#include "keyboard_mkbp.h"
#include "keyboard_scan.h"
#include "mkbp_input_devices.h"
#include "util.h"

static uint32_t get_supported_buttons(void)
{
	uint32_t val = 0;

#ifdef CONFIG_VOLUME_BUTTONS
	val |= BIT(EC_MKBP_VOL_UP) | BIT(EC_MKBP_VOL_DOWN);
#endif /* defined(CONFIG_VOLUME_BUTTONS) */

#ifdef CONFIG_DEDICATED_RECOVERY_BUTTON
	val |= BIT(EC_MKBP_RECOVERY);
#endif /* defined(CONFIG_DEDICATED_RECOVERY_BUTTON) */

#ifdef CONFIG_POWER_BUTTON
	val |= BIT(EC_MKBP_POWER_BUTTON);
#endif /* defined(CONFIG_POWER_BUTTON) */

	return val;
}

static uint32_t get_supported_switches(void)
{
	uint32_t val = 0;

#ifdef CONFIG_LID_SWITCH
	val |= BIT(EC_MKBP_LID_OPEN);
#endif
#ifdef CONFIG_TABLET_MODE_SWITCH
	val |= BIT(EC_MKBP_TABLET_MODE);
#endif
#ifdef CONFIG_BASE_ATTACHED_SWITCH
	val |= BIT(EC_MKBP_BASE_ATTACHED);
#endif
#ifdef CONFIG_FRONT_PROXIMITY_SWITCH
	val |= BIT(EC_MKBP_FRONT_PROXIMITY);
#endif
	return val;
}

static enum ec_status mkbp_get_info(struct host_cmd_handler_args *args)
{
	const struct ec_params_mkbp_info *p = args->params;

	if (args->params_size == 0 || p->info_type == EC_MKBP_INFO_KBD) {
		struct ec_response_mkbp_info *r = args->response;

#ifdef CONFIG_KEYBOARD_PROTOCOL_MKBP
		/* Version 0 just returns info about the keyboard. */
		r->rows = KEYBOARD_ROWS;
		r->cols = KEYBOARD_COLS_MAX;
#else
		r->rows = 0;
		r->cols = 0;
#endif /* CONFIG_KEYBOARD_PROTOCOL_MKBP */

		/* This used to be "switches" which was previously 0. */
		r->reserved = 0;

		args->response_size = sizeof(struct ec_response_mkbp_info);
	} else {
		union ec_response_get_next_data *r = args->response;

		/* Version 1 (other than EC_MKBP_INFO_KBD) */
		switch (p->info_type) {
		case EC_MKBP_INFO_SUPPORTED:
			switch (p->event_type) {
			case EC_MKBP_EVENT_BUTTON:
				r->buttons = get_supported_buttons();
				args->response_size = sizeof(r->buttons);
				break;

			case EC_MKBP_EVENT_SWITCH:
				r->switches = get_supported_switches();
				args->response_size = sizeof(r->switches);
				break;

			default:
				/* Don't care for now for other types. */
				return EC_RES_INVALID_PARAM;
			}
			break;

		case EC_MKBP_INFO_CURRENT:
			switch (p->event_type) {
#ifdef HAS_TASK_KEYSCAN
			case EC_MKBP_EVENT_KEY_MATRIX:
				memcpy(r->key_matrix, keyboard_scan_get_state(),
				       sizeof(r->key_matrix));
				args->response_size = sizeof(r->key_matrix);
				break;
#endif
			case EC_MKBP_EVENT_HOST_EVENT:
				r->host_event = (uint32_t)host_get_events();
				args->response_size = sizeof(r->host_event);
				break;

#ifdef CONFIG_HOST_EVENT64
			case EC_MKBP_EVENT_HOST_EVENT64:
				r->host_event64 = host_get_events();
				args->response_size = sizeof(r->host_event64);
				break;
#endif

#ifdef CONFIG_MKBP_INPUT_DEVICES
			case EC_MKBP_EVENT_BUTTON:
				r->buttons = mkbp_get_button_state();
				args->response_size = sizeof(r->buttons);
				break;

			case EC_MKBP_EVENT_SWITCH:
				r->switches = mkbp_get_switch_state();
				args->response_size = sizeof(r->switches);
				break;
#endif /* CONFIG_MKBP_INPUT_DEVICES */

			default:
				/* Doesn't make sense for other event types. */
				return EC_RES_INVALID_PARAM;
			}
			break;

		default:
			/* Unsupported query. */
			return EC_RES_ERROR;
		}
	}
	return EC_RES_SUCCESS;
}

DECLARE_HOST_COMMAND(EC_CMD_MKBP_INFO, mkbp_get_info,
		     EC_VER_MASK(0) | EC_VER_MASK(1));