Commit 8327d41b19af08a331c62954fafd685426e617f4
1 parent
2dd57f5e47
Exists in
smarc_8mq_lf_v2020.04
and in
19 other branches
cros_ec: Update the cros_ec keyboard driver to livetree
Update this driver and key_matrix to support a live device tree. Signed-off-by: Simon Glass <sjg@chromium.org>
Showing 4 changed files with 23 additions and 26 deletions Inline Diff
drivers/input/cros_ec_keyb.c
1 | /* | 1 | /* |
2 | * Chromium OS Matrix Keyboard | 2 | * Chromium OS Matrix Keyboard |
3 | * | 3 | * |
4 | * Copyright (c) 2012 The Chromium OS Authors. | 4 | * Copyright (c) 2012 The Chromium OS Authors. |
5 | * | 5 | * |
6 | * SPDX-License-Identifier: GPL-2.0+ | 6 | * SPDX-License-Identifier: GPL-2.0+ |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <common.h> | 9 | #include <common.h> |
10 | #include <cros_ec.h> | 10 | #include <cros_ec.h> |
11 | #include <dm.h> | 11 | #include <dm.h> |
12 | #include <errno.h> | 12 | #include <errno.h> |
13 | #include <fdtdec.h> | ||
14 | #include <input.h> | 13 | #include <input.h> |
15 | #include <keyboard.h> | 14 | #include <keyboard.h> |
16 | #include <key_matrix.h> | 15 | #include <key_matrix.h> |
17 | #include <stdio_dev.h> | 16 | #include <stdio_dev.h> |
18 | 17 | ||
19 | DECLARE_GLOBAL_DATA_PTR; | 18 | DECLARE_GLOBAL_DATA_PTR; |
20 | 19 | ||
21 | enum { | 20 | enum { |
22 | KBC_MAX_KEYS = 8, /* Maximum keys held down at once */ | 21 | KBC_MAX_KEYS = 8, /* Maximum keys held down at once */ |
23 | KBC_REPEAT_RATE_MS = 30, | 22 | KBC_REPEAT_RATE_MS = 30, |
24 | KBC_REPEAT_DELAY_MS = 240, | 23 | KBC_REPEAT_DELAY_MS = 240, |
25 | }; | 24 | }; |
26 | 25 | ||
27 | struct cros_ec_keyb_priv { | 26 | struct cros_ec_keyb_priv { |
28 | struct input_config *input; /* The input layer */ | 27 | struct input_config *input; /* The input layer */ |
29 | struct key_matrix matrix; /* The key matrix layer */ | 28 | struct key_matrix matrix; /* The key matrix layer */ |
30 | int key_rows; /* Number of keyboard rows */ | 29 | int key_rows; /* Number of keyboard rows */ |
31 | int key_cols; /* Number of keyboard columns */ | 30 | int key_cols; /* Number of keyboard columns */ |
32 | int ghost_filter; /* 1 to enable ghost filter, else 0 */ | 31 | int ghost_filter; /* 1 to enable ghost filter, else 0 */ |
33 | }; | 32 | }; |
34 | 33 | ||
35 | 34 | ||
36 | /** | 35 | /** |
37 | * Check the keyboard controller and return a list of key matrix positions | 36 | * Check the keyboard controller and return a list of key matrix positions |
38 | * for which a key is pressed | 37 | * for which a key is pressed |
39 | * | 38 | * |
40 | * @param dev Keyboard device | 39 | * @param dev Keyboard device |
41 | * @param keys List of keys that we have detected | 40 | * @param keys List of keys that we have detected |
42 | * @param max_count Maximum number of keys to return | 41 | * @param max_count Maximum number of keys to return |
43 | * @param samep Set to true if this scan repeats the last, else false | 42 | * @param samep Set to true if this scan repeats the last, else false |
44 | * @return number of pressed keys, 0 for none, -EIO on error | 43 | * @return number of pressed keys, 0 for none, -EIO on error |
45 | */ | 44 | */ |
46 | static int check_for_keys(struct udevice *dev, struct key_matrix_key *keys, | 45 | static int check_for_keys(struct udevice *dev, struct key_matrix_key *keys, |
47 | int max_count, bool *samep) | 46 | int max_count, bool *samep) |
48 | { | 47 | { |
49 | struct cros_ec_keyb_priv *priv = dev_get_priv(dev); | 48 | struct cros_ec_keyb_priv *priv = dev_get_priv(dev); |
50 | struct key_matrix_key *key; | 49 | struct key_matrix_key *key; |
51 | static struct mbkp_keyscan last_scan; | 50 | static struct mbkp_keyscan last_scan; |
52 | static bool last_scan_valid; | 51 | static bool last_scan_valid; |
53 | struct mbkp_keyscan scan; | 52 | struct mbkp_keyscan scan; |
54 | unsigned int row, col, bit, data; | 53 | unsigned int row, col, bit, data; |
55 | int num_keys; | 54 | int num_keys; |
56 | 55 | ||
57 | if (cros_ec_scan_keyboard(dev->parent, &scan)) { | 56 | if (cros_ec_scan_keyboard(dev->parent, &scan)) { |
58 | debug("%s: keyboard scan failed\n", __func__); | 57 | debug("%s: keyboard scan failed\n", __func__); |
59 | return -EIO; | 58 | return -EIO; |
60 | } | 59 | } |
61 | *samep = last_scan_valid && !memcmp(&last_scan, &scan, sizeof(scan)); | 60 | *samep = last_scan_valid && !memcmp(&last_scan, &scan, sizeof(scan)); |
62 | 61 | ||
63 | /* | 62 | /* |
64 | * This is a bit odd. The EC has no way to tell us that it has run | 63 | * This is a bit odd. The EC has no way to tell us that it has run |
65 | * out of key scans. It just returns the same scan over and over | 64 | * out of key scans. It just returns the same scan over and over |
66 | * again. So the only way to detect that we have run out is to detect | 65 | * again. So the only way to detect that we have run out is to detect |
67 | * that this scan is the same as the last. | 66 | * that this scan is the same as the last. |
68 | */ | 67 | */ |
69 | last_scan_valid = true; | 68 | last_scan_valid = true; |
70 | memcpy(&last_scan, &scan, sizeof(last_scan)); | 69 | memcpy(&last_scan, &scan, sizeof(last_scan)); |
71 | 70 | ||
72 | for (col = num_keys = bit = 0; col < priv->matrix.num_cols; | 71 | for (col = num_keys = bit = 0; col < priv->matrix.num_cols; |
73 | col++) { | 72 | col++) { |
74 | for (row = 0; row < priv->matrix.num_rows; row++) { | 73 | for (row = 0; row < priv->matrix.num_rows; row++) { |
75 | unsigned int mask = 1 << (bit & 7); | 74 | unsigned int mask = 1 << (bit & 7); |
76 | 75 | ||
77 | data = scan.data[bit / 8]; | 76 | data = scan.data[bit / 8]; |
78 | if ((data & mask) && num_keys < max_count) { | 77 | if ((data & mask) && num_keys < max_count) { |
79 | key = keys + num_keys++; | 78 | key = keys + num_keys++; |
80 | key->row = row; | 79 | key->row = row; |
81 | key->col = col; | 80 | key->col = col; |
82 | key->valid = 1; | 81 | key->valid = 1; |
83 | } | 82 | } |
84 | bit++; | 83 | bit++; |
85 | } | 84 | } |
86 | } | 85 | } |
87 | 86 | ||
88 | return num_keys; | 87 | return num_keys; |
89 | } | 88 | } |
90 | 89 | ||
91 | /** | 90 | /** |
92 | * Check the keyboard, and send any keys that are pressed. | 91 | * Check the keyboard, and send any keys that are pressed. |
93 | * | 92 | * |
94 | * This is called by input_tstc() and input_getc() when they need more | 93 | * This is called by input_tstc() and input_getc() when they need more |
95 | * characters | 94 | * characters |
96 | * | 95 | * |
97 | * @param input Input configuration | 96 | * @param input Input configuration |
98 | * @return 1, to indicate that we have something to look at | 97 | * @return 1, to indicate that we have something to look at |
99 | */ | 98 | */ |
100 | int cros_ec_kbc_check(struct input_config *input) | 99 | int cros_ec_kbc_check(struct input_config *input) |
101 | { | 100 | { |
102 | struct udevice *dev = input->dev; | 101 | struct udevice *dev = input->dev; |
103 | struct cros_ec_keyb_priv *priv = dev_get_priv(dev); | 102 | struct cros_ec_keyb_priv *priv = dev_get_priv(dev); |
104 | static struct key_matrix_key last_keys[KBC_MAX_KEYS]; | 103 | static struct key_matrix_key last_keys[KBC_MAX_KEYS]; |
105 | static int last_num_keys; | 104 | static int last_num_keys; |
106 | struct key_matrix_key keys[KBC_MAX_KEYS]; | 105 | struct key_matrix_key keys[KBC_MAX_KEYS]; |
107 | int keycodes[KBC_MAX_KEYS]; | 106 | int keycodes[KBC_MAX_KEYS]; |
108 | int num_keys, num_keycodes; | 107 | int num_keys, num_keycodes; |
109 | int irq_pending, sent; | 108 | int irq_pending, sent; |
110 | bool same = false; | 109 | bool same = false; |
111 | 110 | ||
112 | /* | 111 | /* |
113 | * Loop until the EC has no more keyscan records, or we have | 112 | * Loop until the EC has no more keyscan records, or we have |
114 | * received at least one character. This means we know that tstc() | 113 | * received at least one character. This means we know that tstc() |
115 | * will always return non-zero if keys have been pressed. | 114 | * will always return non-zero if keys have been pressed. |
116 | * | 115 | * |
117 | * Without this loop, a key release (which generates no new ascii | 116 | * Without this loop, a key release (which generates no new ascii |
118 | * characters) will cause us to exit this function, and just tstc() | 117 | * characters) will cause us to exit this function, and just tstc() |
119 | * may return 0 before all keys have been read from the EC. | 118 | * may return 0 before all keys have been read from the EC. |
120 | */ | 119 | */ |
121 | do { | 120 | do { |
122 | irq_pending = cros_ec_interrupt_pending(dev->parent); | 121 | irq_pending = cros_ec_interrupt_pending(dev->parent); |
123 | if (irq_pending) { | 122 | if (irq_pending) { |
124 | num_keys = check_for_keys(dev, keys, KBC_MAX_KEYS, | 123 | num_keys = check_for_keys(dev, keys, KBC_MAX_KEYS, |
125 | &same); | 124 | &same); |
126 | if (num_keys < 0) | 125 | if (num_keys < 0) |
127 | return 0; | 126 | return 0; |
128 | last_num_keys = num_keys; | 127 | last_num_keys = num_keys; |
129 | memcpy(last_keys, keys, sizeof(keys)); | 128 | memcpy(last_keys, keys, sizeof(keys)); |
130 | } else { | 129 | } else { |
131 | /* | 130 | /* |
132 | * EC doesn't want to be asked, so use keys from last | 131 | * EC doesn't want to be asked, so use keys from last |
133 | * time. | 132 | * time. |
134 | */ | 133 | */ |
135 | num_keys = last_num_keys; | 134 | num_keys = last_num_keys; |
136 | memcpy(keys, last_keys, sizeof(keys)); | 135 | memcpy(keys, last_keys, sizeof(keys)); |
137 | } | 136 | } |
138 | 137 | ||
139 | if (num_keys < 0) | 138 | if (num_keys < 0) |
140 | return -1; | 139 | return -1; |
141 | num_keycodes = key_matrix_decode(&priv->matrix, keys, | 140 | num_keycodes = key_matrix_decode(&priv->matrix, keys, |
142 | num_keys, keycodes, KBC_MAX_KEYS); | 141 | num_keys, keycodes, KBC_MAX_KEYS); |
143 | sent = input_send_keycodes(input, keycodes, num_keycodes); | 142 | sent = input_send_keycodes(input, keycodes, num_keycodes); |
144 | 143 | ||
145 | /* | 144 | /* |
146 | * For those ECs without an interrupt, stop scanning when we | 145 | * For those ECs without an interrupt, stop scanning when we |
147 | * see that the scan is the same as last time. | 146 | * see that the scan is the same as last time. |
148 | */ | 147 | */ |
149 | if ((irq_pending < 0) && same) | 148 | if ((irq_pending < 0) && same) |
150 | break; | 149 | break; |
151 | } while (irq_pending && !sent); | 150 | } while (irq_pending && !sent); |
152 | 151 | ||
153 | return 1; | 152 | return 1; |
154 | } | 153 | } |
155 | 154 | ||
156 | /** | 155 | /** |
157 | * Decode MBKP keyboard details from the device tree | 156 | * Decode MBKP keyboard details from the device tree |
158 | * | 157 | * |
159 | * @param blob Device tree blob | 158 | * @param blob Device tree blob |
160 | * @param node Node to decode from | 159 | * @param node Node to decode from |
161 | * @param config Configuration data read from fdt | 160 | * @param config Configuration data read from fdt |
162 | * @return 0 if ok, -1 on error | 161 | * @return 0 if ok, -1 on error |
163 | */ | 162 | */ |
164 | static int cros_ec_keyb_decode_fdt(const void *blob, int node, | 163 | static int cros_ec_keyb_decode_fdt(struct udevice *dev, |
165 | struct cros_ec_keyb_priv *config) | 164 | struct cros_ec_keyb_priv *config) |
166 | { | 165 | { |
167 | /* | 166 | /* |
168 | * Get keyboard rows and columns - at present we are limited to | 167 | * Get keyboard rows and columns - at present we are limited to |
169 | * 8 columns by the protocol (one byte per row scan) | 168 | * 8 columns by the protocol (one byte per row scan) |
170 | */ | 169 | */ |
171 | config->key_rows = fdtdec_get_int(blob, node, "keypad,num-rows", 0); | 170 | config->key_rows = dev_read_u32_default(dev, "keypad,num-rows", 0); |
172 | config->key_cols = fdtdec_get_int(blob, node, "keypad,num-columns", 0); | 171 | config->key_cols = dev_read_u32_default(dev, "keypad,num-columns", 0); |
173 | if (!config->key_rows || !config->key_cols || | 172 | if (!config->key_rows || !config->key_cols || |
174 | config->key_rows * config->key_cols / 8 | 173 | config->key_rows * config->key_cols / 8 |
175 | > CROS_EC_KEYSCAN_COLS) { | 174 | > CROS_EC_KEYSCAN_COLS) { |
176 | debug("%s: Invalid key matrix size %d x %d\n", __func__, | 175 | debug("%s: Invalid key matrix size %d x %d\n", __func__, |
177 | config->key_rows, config->key_cols); | 176 | config->key_rows, config->key_cols); |
178 | return -1; | 177 | return -1; |
179 | } | 178 | } |
180 | config->ghost_filter = fdtdec_get_bool(blob, node, | 179 | config->ghost_filter = dev_read_bool(dev, "google,needs-ghost-filter"); |
181 | "google,needs-ghost-filter"); | 180 | |
182 | return 0; | 181 | return 0; |
183 | } | 182 | } |
184 | 183 | ||
185 | static int cros_ec_kbd_probe(struct udevice *dev) | 184 | static int cros_ec_kbd_probe(struct udevice *dev) |
186 | { | 185 | { |
187 | struct cros_ec_keyb_priv *priv = dev_get_priv(dev); | 186 | struct cros_ec_keyb_priv *priv = dev_get_priv(dev); |
188 | struct keyboard_priv *uc_priv = dev_get_uclass_priv(dev); | 187 | struct keyboard_priv *uc_priv = dev_get_uclass_priv(dev); |
189 | struct stdio_dev *sdev = &uc_priv->sdev; | 188 | struct stdio_dev *sdev = &uc_priv->sdev; |
190 | struct input_config *input = &uc_priv->input; | 189 | struct input_config *input = &uc_priv->input; |
191 | const void *blob = gd->fdt_blob; | ||
192 | int node = dev_of_offset(dev); | ||
193 | int ret; | 190 | int ret; |
194 | 191 | ||
195 | if (cros_ec_keyb_decode_fdt(blob, node, priv)) | 192 | ret = cros_ec_keyb_decode_fdt(dev, priv); |
196 | return -1; | 193 | if (ret) { |
194 | debug("%s: Cannot decode node (ret=%d)\n", __func__, ret); | ||
195 | return -EINVAL; | ||
196 | } | ||
197 | input_set_delays(input, KBC_REPEAT_DELAY_MS, KBC_REPEAT_RATE_MS); | 197 | input_set_delays(input, KBC_REPEAT_DELAY_MS, KBC_REPEAT_RATE_MS); |
198 | ret = key_matrix_init(&priv->matrix, priv->key_rows, priv->key_cols, | 198 | ret = key_matrix_init(&priv->matrix, priv->key_rows, priv->key_cols, |
199 | priv->ghost_filter); | 199 | priv->ghost_filter); |
200 | if (ret) { | 200 | if (ret) { |
201 | debug("%s: cannot init key matrix\n", __func__); | 201 | debug("%s: cannot init key matrix\n", __func__); |
202 | return ret; | 202 | return ret; |
203 | } | 203 | } |
204 | ret = key_matrix_decode_fdt(&priv->matrix, gd->fdt_blob, node); | 204 | ret = key_matrix_decode_fdt(dev, &priv->matrix); |
205 | if (ret) { | 205 | if (ret) { |
206 | debug("%s: Could not decode key matrix from fdt\n", __func__); | 206 | debug("%s: Could not decode key matrix from fdt\n", __func__); |
207 | return ret; | 207 | return ret; |
208 | } | 208 | } |
209 | debug("%s: Matrix keyboard %dx%d ready\n", __func__, priv->key_rows, | 209 | debug("%s: Matrix keyboard %dx%d ready\n", __func__, priv->key_rows, |
210 | priv->key_cols); | 210 | priv->key_cols); |
211 | 211 | ||
212 | priv->input = input; | 212 | priv->input = input; |
213 | input->dev = dev; | 213 | input->dev = dev; |
214 | input_add_tables(input, false); | 214 | input_add_tables(input, false); |
215 | input->read_keys = cros_ec_kbc_check; | 215 | input->read_keys = cros_ec_kbc_check; |
216 | strcpy(sdev->name, "cros-ec-keyb"); | 216 | strcpy(sdev->name, "cros-ec-keyb"); |
217 | 217 | ||
218 | /* Register the device. cros_ec_init_keyboard() will be called soon */ | 218 | /* Register the device. cros_ec_init_keyboard() will be called soon */ |
219 | return input_stdio_register(sdev); | 219 | return input_stdio_register(sdev); |
220 | } | 220 | } |
221 | 221 | ||
222 | static const struct keyboard_ops cros_ec_kbd_ops = { | 222 | static const struct keyboard_ops cros_ec_kbd_ops = { |
223 | }; | 223 | }; |
224 | 224 | ||
225 | static const struct udevice_id cros_ec_kbd_ids[] = { | 225 | static const struct udevice_id cros_ec_kbd_ids[] = { |
226 | { .compatible = "google,cros-ec-keyb" }, | 226 | { .compatible = "google,cros-ec-keyb" }, |
227 | { } | 227 | { } |
228 | }; | 228 | }; |
229 | 229 | ||
230 | U_BOOT_DRIVER(cros_ec_kbd) = { | 230 | U_BOOT_DRIVER(cros_ec_kbd) = { |
231 | .name = "cros_ec_kbd", | 231 | .name = "cros_ec_kbd", |
232 | .id = UCLASS_KEYBOARD, | 232 | .id = UCLASS_KEYBOARD, |
233 | .of_match = cros_ec_kbd_ids, | 233 | .of_match = cros_ec_kbd_ids, |
234 | .probe = cros_ec_kbd_probe, | 234 | .probe = cros_ec_kbd_probe, |
235 | .ops = &cros_ec_kbd_ops, | 235 | .ops = &cros_ec_kbd_ops, |
drivers/input/key_matrix.c
1 | /* | 1 | /* |
2 | * Manage Keyboard Matrices | 2 | * Manage Keyboard Matrices |
3 | * | 3 | * |
4 | * Copyright (c) 2012 The Chromium OS Authors. | 4 | * Copyright (c) 2012 The Chromium OS Authors. |
5 | * (C) Copyright 2004 DENX Software Engineering, Wolfgang Denk, wd@denx.de | 5 | * (C) Copyright 2004 DENX Software Engineering, Wolfgang Denk, wd@denx.de |
6 | * | 6 | * |
7 | * SPDX-License-Identifier: GPL-2.0+ | 7 | * SPDX-License-Identifier: GPL-2.0+ |
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include <common.h> | 10 | #include <common.h> |
11 | #include <fdtdec.h> | 11 | #include <dm.h> |
12 | #include <key_matrix.h> | 12 | #include <key_matrix.h> |
13 | #include <malloc.h> | 13 | #include <malloc.h> |
14 | #include <linux/input.h> | 14 | #include <linux/input.h> |
15 | 15 | ||
16 | /** | 16 | /** |
17 | * Determine if the current keypress configuration can cause key ghosting | 17 | * Determine if the current keypress configuration can cause key ghosting |
18 | * | 18 | * |
19 | * We figure this out by seeing if we have two or more keys in the same | 19 | * We figure this out by seeing if we have two or more keys in the same |
20 | * column, as well as two or more keys in the same row. | 20 | * column, as well as two or more keys in the same row. |
21 | * | 21 | * |
22 | * @param config Keyboard matrix config | 22 | * @param config Keyboard matrix config |
23 | * @param keys List of keys to check | 23 | * @param keys List of keys to check |
24 | * @param valid Number of valid keypresses to check | 24 | * @param valid Number of valid keypresses to check |
25 | * @return 0 if no ghosting is possible, 1 if it is | 25 | * @return 0 if no ghosting is possible, 1 if it is |
26 | */ | 26 | */ |
27 | static int has_ghosting(struct key_matrix *config, struct key_matrix_key *keys, | 27 | static int has_ghosting(struct key_matrix *config, struct key_matrix_key *keys, |
28 | int valid) | 28 | int valid) |
29 | { | 29 | { |
30 | int key_in_same_col = 0, key_in_same_row = 0; | 30 | int key_in_same_col = 0, key_in_same_row = 0; |
31 | int i, j; | 31 | int i, j; |
32 | 32 | ||
33 | if (!config->ghost_filter || valid < 3) | 33 | if (!config->ghost_filter || valid < 3) |
34 | return 0; | 34 | return 0; |
35 | 35 | ||
36 | for (i = 0; i < valid; i++) { | 36 | for (i = 0; i < valid; i++) { |
37 | /* | 37 | /* |
38 | * Find 2 keys such that one key is in the same row | 38 | * Find 2 keys such that one key is in the same row |
39 | * and the other is in the same column as the i-th key. | 39 | * and the other is in the same column as the i-th key. |
40 | */ | 40 | */ |
41 | for (j = i + 1; j < valid; j++) { | 41 | for (j = i + 1; j < valid; j++) { |
42 | if (keys[j].col == keys[i].col) | 42 | if (keys[j].col == keys[i].col) |
43 | key_in_same_col = 1; | 43 | key_in_same_col = 1; |
44 | if (keys[j].row == keys[i].row) | 44 | if (keys[j].row == keys[i].row) |
45 | key_in_same_row = 1; | 45 | key_in_same_row = 1; |
46 | } | 46 | } |
47 | } | 47 | } |
48 | 48 | ||
49 | if (key_in_same_col && key_in_same_row) | 49 | if (key_in_same_col && key_in_same_row) |
50 | return 1; | 50 | return 1; |
51 | else | 51 | else |
52 | return 0; | 52 | return 0; |
53 | } | 53 | } |
54 | 54 | ||
55 | int key_matrix_decode(struct key_matrix *config, struct key_matrix_key keys[], | 55 | int key_matrix_decode(struct key_matrix *config, struct key_matrix_key keys[], |
56 | int num_keys, int keycode[], int max_keycodes) | 56 | int num_keys, int keycode[], int max_keycodes) |
57 | { | 57 | { |
58 | const u8 *keymap; | 58 | const u8 *keymap; |
59 | int valid, upto; | 59 | int valid, upto; |
60 | int pos; | 60 | int pos; |
61 | 61 | ||
62 | debug("%s: num_keys = %d\n", __func__, num_keys); | 62 | debug("%s: num_keys = %d\n", __func__, num_keys); |
63 | keymap = config->plain_keycode; | 63 | keymap = config->plain_keycode; |
64 | for (valid = upto = 0; upto < num_keys; upto++) { | 64 | for (valid = upto = 0; upto < num_keys; upto++) { |
65 | struct key_matrix_key *key = &keys[upto]; | 65 | struct key_matrix_key *key = &keys[upto]; |
66 | 66 | ||
67 | debug(" valid=%d, row=%d, col=%d\n", key->valid, key->row, | 67 | debug(" valid=%d, row=%d, col=%d\n", key->valid, key->row, |
68 | key->col); | 68 | key->col); |
69 | if (!key->valid) | 69 | if (!key->valid) |
70 | continue; | 70 | continue; |
71 | pos = key->row * config->num_cols + key->col; | 71 | pos = key->row * config->num_cols + key->col; |
72 | if (config->fn_keycode && pos == config->fn_pos) | 72 | if (config->fn_keycode && pos == config->fn_pos) |
73 | keymap = config->fn_keycode; | 73 | keymap = config->fn_keycode; |
74 | 74 | ||
75 | /* Convert the (row, col) values into a keycode */ | 75 | /* Convert the (row, col) values into a keycode */ |
76 | if (valid < max_keycodes) | 76 | if (valid < max_keycodes) |
77 | keycode[valid++] = keymap[pos]; | 77 | keycode[valid++] = keymap[pos]; |
78 | debug(" keycode=%d\n", keymap[pos]); | 78 | debug(" keycode=%d\n", keymap[pos]); |
79 | } | 79 | } |
80 | 80 | ||
81 | /* For a ghost key config, ignore the keypresses for this iteration. */ | 81 | /* For a ghost key config, ignore the keypresses for this iteration. */ |
82 | if (has_ghosting(config, keys, valid)) { | 82 | if (has_ghosting(config, keys, valid)) { |
83 | valid = 0; | 83 | valid = 0; |
84 | debug(" ghosting detected!\n"); | 84 | debug(" ghosting detected!\n"); |
85 | } | 85 | } |
86 | debug(" %d valid keycodes found\n", valid); | 86 | debug(" %d valid keycodes found\n", valid); |
87 | 87 | ||
88 | return valid; | 88 | return valid; |
89 | } | 89 | } |
90 | 90 | ||
91 | /** | 91 | /** |
92 | * Create a new keycode map from some provided data | 92 | * Create a new keycode map from some provided data |
93 | * | 93 | * |
94 | * This decodes a keycode map in the format used by the fdt, which is one | 94 | * This decodes a keycode map in the format used by the fdt, which is one |
95 | * word per entry, with the row, col and keycode encoded in that word. | 95 | * word per entry, with the row, col and keycode encoded in that word. |
96 | * | 96 | * |
97 | * We create a (row x col) size byte array with each entry containing the | 97 | * We create a (row x col) size byte array with each entry containing the |
98 | * keycode for that (row, col). We also search for map_keycode and return | 98 | * keycode for that (row, col). We also search for map_keycode and return |
99 | * its position if found (this is used for finding the Fn key). | 99 | * its position if found (this is used for finding the Fn key). |
100 | * | 100 | * |
101 | * @param config Key matrix dimensions structure | 101 | * @param config Key matrix dimensions structure |
102 | * @param data Keycode data | 102 | * @param data Keycode data |
103 | * @param len Number of entries in keycode table | 103 | * @param len Number of entries in keycode table |
104 | * @param map_keycode Key code to find in the map | 104 | * @param map_keycode Key code to find in the map |
105 | * @param pos Returns position of map_keycode, if found, else -1 | 105 | * @param pos Returns position of map_keycode, if found, else -1 |
106 | * @return map Pointer to allocated map | 106 | * @return map Pointer to allocated map |
107 | */ | 107 | */ |
108 | static uchar *create_keymap(struct key_matrix *config, u32 *data, int len, | 108 | static uchar *create_keymap(struct key_matrix *config, const u32 *data, int len, |
109 | int map_keycode, int *pos) | 109 | int map_keycode, int *pos) |
110 | { | 110 | { |
111 | uchar *map; | 111 | uchar *map; |
112 | 112 | ||
113 | if (pos) | 113 | if (pos) |
114 | *pos = -1; | 114 | *pos = -1; |
115 | map = (uchar *)calloc(1, config->key_count); | 115 | map = (uchar *)calloc(1, config->key_count); |
116 | if (!map) { | 116 | if (!map) { |
117 | debug("%s: failed to malloc %d bytes\n", __func__, | 117 | debug("%s: failed to malloc %d bytes\n", __func__, |
118 | config->key_count); | 118 | config->key_count); |
119 | return NULL; | 119 | return NULL; |
120 | } | 120 | } |
121 | 121 | ||
122 | for (; len >= sizeof(u32); data++, len -= 4) { | 122 | for (; len >= sizeof(u32); data++, len -= 4) { |
123 | u32 tmp = fdt32_to_cpu(*data); | 123 | u32 tmp = fdt32_to_cpu(*data); |
124 | int key_code, row, col; | 124 | int key_code, row, col; |
125 | int entry; | 125 | int entry; |
126 | 126 | ||
127 | row = (tmp >> 24) & 0xff; | 127 | row = (tmp >> 24) & 0xff; |
128 | col = (tmp >> 16) & 0xff; | 128 | col = (tmp >> 16) & 0xff; |
129 | key_code = tmp & 0xffff; | 129 | key_code = tmp & 0xffff; |
130 | entry = row * config->num_cols + col; | 130 | entry = row * config->num_cols + col; |
131 | map[entry] = key_code; | 131 | map[entry] = key_code; |
132 | debug(" map %d, %d: pos=%d, keycode=%d\n", row, col, | 132 | debug(" map %d, %d: pos=%d, keycode=%d\n", row, col, |
133 | entry, key_code); | 133 | entry, key_code); |
134 | if (pos && map_keycode == key_code) | 134 | if (pos && map_keycode == key_code) |
135 | *pos = entry; | 135 | *pos = entry; |
136 | } | 136 | } |
137 | 137 | ||
138 | return map; | 138 | return map; |
139 | } | 139 | } |
140 | 140 | ||
141 | int key_matrix_decode_fdt(struct key_matrix *config, const void *blob, int node) | 141 | int key_matrix_decode_fdt(struct udevice *dev, struct key_matrix *config) |
142 | { | 142 | { |
143 | const struct fdt_property *prop; | 143 | const u32 *prop; |
144 | int proplen; | 144 | int proplen; |
145 | uchar *plain_keycode; | 145 | uchar *plain_keycode; |
146 | 146 | ||
147 | prop = fdt_get_property(blob, node, "linux,keymap", &proplen); | 147 | prop = dev_read_prop(dev, "linux,keymap", &proplen); |
148 | /* Basic keymap is required */ | 148 | /* Basic keymap is required */ |
149 | if (!prop) { | 149 | if (!prop) { |
150 | debug("%s: cannot find keycode-plain map\n", __func__); | 150 | debug("%s: cannot find keycode-plain map\n", __func__); |
151 | return -1; | 151 | return -1; |
152 | } | 152 | } |
153 | 153 | ||
154 | plain_keycode = create_keymap(config, (u32 *)prop->data, | 154 | plain_keycode = create_keymap(config, prop, proplen, KEY_FN, |
155 | proplen, KEY_FN, &config->fn_pos); | 155 | &config->fn_pos); |
156 | config->plain_keycode = plain_keycode; | 156 | config->plain_keycode = plain_keycode; |
157 | /* Conversion error -> fail */ | 157 | /* Conversion error -> fail */ |
158 | if (!config->plain_keycode) | 158 | if (!config->plain_keycode) |
159 | return -1; | 159 | return -1; |
160 | 160 | ||
161 | prop = fdt_get_property(blob, node, "linux,fn-keymap", &proplen); | 161 | prop = dev_read_prop(dev, "linux,fn-keymap", &proplen); |
162 | /* fn keymap is optional */ | 162 | /* fn keymap is optional */ |
163 | if (!prop) | 163 | if (!prop) |
164 | goto done; | 164 | goto done; |
165 | 165 | ||
166 | config->fn_keycode = create_keymap(config, (u32 *)prop->data, | 166 | config->fn_keycode = create_keymap(config, prop, proplen, -1, NULL); |
167 | proplen, -1, NULL); | ||
168 | /* Conversion error -> fail */ | 167 | /* Conversion error -> fail */ |
169 | if (!config->fn_keycode) { | 168 | if (!config->fn_keycode) { |
170 | free(plain_keycode); | 169 | free(plain_keycode); |
171 | return -1; | 170 | return -1; |
172 | } | 171 | } |
173 | 172 | ||
174 | done: | 173 | done: |
175 | debug("%s: Decoded key maps %p, %p from fdt\n", __func__, | 174 | debug("%s: Decoded key maps %p, %p from fdt\n", __func__, |
176 | config->plain_keycode, config->fn_keycode); | 175 | config->plain_keycode, config->fn_keycode); |
177 | return 0; | 176 | return 0; |
178 | } | 177 | } |
179 | 178 | ||
180 | int key_matrix_init(struct key_matrix *config, int rows, int cols, | 179 | int key_matrix_init(struct key_matrix *config, int rows, int cols, |
181 | int ghost_filter) | 180 | int ghost_filter) |
182 | { | 181 | { |
183 | memset(config, '\0', sizeof(*config)); | 182 | memset(config, '\0', sizeof(*config)); |
184 | config->num_rows = rows; | 183 | config->num_rows = rows; |
185 | config->num_cols = cols; | 184 | config->num_cols = cols; |
186 | config->key_count = rows * cols; | 185 | config->key_count = rows * cols; |
187 | config->ghost_filter = ghost_filter; | 186 | config->ghost_filter = ghost_filter; |
188 | assert(config->key_count > 0); | 187 | assert(config->key_count > 0); |
189 | 188 | ||
190 | return 0; | 189 | return 0; |
191 | } | 190 | } |
192 | 191 |
drivers/input/tegra-kbc.c
1 | /* | 1 | /* |
2 | * (C) Copyright 2011 | 2 | * (C) Copyright 2011 |
3 | * NVIDIA Corporation <www.nvidia.com> | 3 | * NVIDIA Corporation <www.nvidia.com> |
4 | * | 4 | * |
5 | * SPDX-License-Identifier: GPL-2.0+ | 5 | * SPDX-License-Identifier: GPL-2.0+ |
6 | */ | 6 | */ |
7 | 7 | ||
8 | #include <common.h> | 8 | #include <common.h> |
9 | #include <dm.h> | 9 | #include <dm.h> |
10 | #include <fdtdec.h> | 10 | #include <fdtdec.h> |
11 | #include <input.h> | 11 | #include <input.h> |
12 | #include <keyboard.h> | 12 | #include <keyboard.h> |
13 | #include <key_matrix.h> | 13 | #include <key_matrix.h> |
14 | #include <stdio_dev.h> | 14 | #include <stdio_dev.h> |
15 | #include <tegra-kbc.h> | 15 | #include <tegra-kbc.h> |
16 | #include <asm/io.h> | 16 | #include <asm/io.h> |
17 | #include <asm/arch/clock.h> | 17 | #include <asm/arch/clock.h> |
18 | #include <asm/arch/funcmux.h> | 18 | #include <asm/arch/funcmux.h> |
19 | #include <asm/arch-tegra/timer.h> | 19 | #include <asm/arch-tegra/timer.h> |
20 | #include <linux/input.h> | 20 | #include <linux/input.h> |
21 | 21 | ||
22 | DECLARE_GLOBAL_DATA_PTR; | 22 | DECLARE_GLOBAL_DATA_PTR; |
23 | 23 | ||
24 | enum { | 24 | enum { |
25 | KBC_MAX_GPIO = 24, | 25 | KBC_MAX_GPIO = 24, |
26 | KBC_MAX_KPENT = 8, /* size of keypress entry queue */ | 26 | KBC_MAX_KPENT = 8, /* size of keypress entry queue */ |
27 | }; | 27 | }; |
28 | 28 | ||
29 | #define KBC_FIFO_TH_CNT_SHIFT 14 | 29 | #define KBC_FIFO_TH_CNT_SHIFT 14 |
30 | #define KBC_DEBOUNCE_CNT_SHIFT 4 | 30 | #define KBC_DEBOUNCE_CNT_SHIFT 4 |
31 | #define KBC_CONTROL_FIFO_CNT_INT_EN (1 << 3) | 31 | #define KBC_CONTROL_FIFO_CNT_INT_EN (1 << 3) |
32 | #define KBC_CONTROL_KBC_EN (1 << 0) | 32 | #define KBC_CONTROL_KBC_EN (1 << 0) |
33 | #define KBC_INT_FIFO_CNT_INT_STATUS (1 << 2) | 33 | #define KBC_INT_FIFO_CNT_INT_STATUS (1 << 2) |
34 | #define KBC_KPENT_VALID (1 << 7) | 34 | #define KBC_KPENT_VALID (1 << 7) |
35 | #define KBC_ST_STATUS (1 << 3) | 35 | #define KBC_ST_STATUS (1 << 3) |
36 | 36 | ||
37 | enum { | 37 | enum { |
38 | KBC_DEBOUNCE_COUNT = 2, | 38 | KBC_DEBOUNCE_COUNT = 2, |
39 | KBC_REPEAT_RATE_MS = 30, | 39 | KBC_REPEAT_RATE_MS = 30, |
40 | KBC_REPEAT_DELAY_MS = 240, | 40 | KBC_REPEAT_DELAY_MS = 240, |
41 | KBC_CLOCK_KHZ = 32, /* Keyboard uses a 32KHz clock */ | 41 | KBC_CLOCK_KHZ = 32, /* Keyboard uses a 32KHz clock */ |
42 | }; | 42 | }; |
43 | 43 | ||
44 | /* keyboard controller config and state */ | 44 | /* keyboard controller config and state */ |
45 | struct tegra_kbd_priv { | 45 | struct tegra_kbd_priv { |
46 | struct input_config *input; /* The input layer */ | 46 | struct input_config *input; /* The input layer */ |
47 | struct key_matrix matrix; /* The key matrix layer */ | 47 | struct key_matrix matrix; /* The key matrix layer */ |
48 | 48 | ||
49 | struct kbc_tegra *kbc; /* tegra keyboard controller */ | 49 | struct kbc_tegra *kbc; /* tegra keyboard controller */ |
50 | unsigned char inited; /* 1 if keyboard has been inited */ | 50 | unsigned char inited; /* 1 if keyboard has been inited */ |
51 | unsigned char first_scan; /* 1 if this is our first key scan */ | 51 | unsigned char first_scan; /* 1 if this is our first key scan */ |
52 | 52 | ||
53 | /* | 53 | /* |
54 | * After init we must wait a short time before polling the keyboard. | 54 | * After init we must wait a short time before polling the keyboard. |
55 | * This gives the tegra keyboard controller time to react after reset | 55 | * This gives the tegra keyboard controller time to react after reset |
56 | * and lets us grab keys pressed during reset. | 56 | * and lets us grab keys pressed during reset. |
57 | */ | 57 | */ |
58 | unsigned int init_dly_ms; /* Delay before we can read keyboard */ | 58 | unsigned int init_dly_ms; /* Delay before we can read keyboard */ |
59 | unsigned int start_time_ms; /* Time that we inited (in ms) */ | 59 | unsigned int start_time_ms; /* Time that we inited (in ms) */ |
60 | unsigned int last_poll_ms; /* Time we should last polled */ | 60 | unsigned int last_poll_ms; /* Time we should last polled */ |
61 | unsigned int next_repeat_ms; /* Next time we repeat a key */ | 61 | unsigned int next_repeat_ms; /* Next time we repeat a key */ |
62 | }; | 62 | }; |
63 | 63 | ||
64 | /** | 64 | /** |
65 | * reads the keyboard fifo for current keypresses | 65 | * reads the keyboard fifo for current keypresses |
66 | * | 66 | * |
67 | * @param priv Keyboard private data | 67 | * @param priv Keyboard private data |
68 | * @param fifo Place to put fifo results | 68 | * @param fifo Place to put fifo results |
69 | * @param max_keycodes Maximum number of key codes to put in the fifo | 69 | * @param max_keycodes Maximum number of key codes to put in the fifo |
70 | * @return number of items put into fifo | 70 | * @return number of items put into fifo |
71 | */ | 71 | */ |
72 | static int tegra_kbc_find_keys(struct tegra_kbd_priv *priv, int *fifo, | 72 | static int tegra_kbc_find_keys(struct tegra_kbd_priv *priv, int *fifo, |
73 | int max_keycodes) | 73 | int max_keycodes) |
74 | { | 74 | { |
75 | struct key_matrix_key keys[KBC_MAX_KPENT], *key; | 75 | struct key_matrix_key keys[KBC_MAX_KPENT], *key; |
76 | u32 kp_ent = 0; | 76 | u32 kp_ent = 0; |
77 | int i; | 77 | int i; |
78 | 78 | ||
79 | for (key = keys, i = 0; i < KBC_MAX_KPENT; i++, key++) { | 79 | for (key = keys, i = 0; i < KBC_MAX_KPENT; i++, key++) { |
80 | /* Get next word */ | 80 | /* Get next word */ |
81 | if (!(i & 3)) | 81 | if (!(i & 3)) |
82 | kp_ent = readl(&priv->kbc->kp_ent[i / 4]); | 82 | kp_ent = readl(&priv->kbc->kp_ent[i / 4]); |
83 | 83 | ||
84 | key->valid = (kp_ent & KBC_KPENT_VALID) != 0; | 84 | key->valid = (kp_ent & KBC_KPENT_VALID) != 0; |
85 | key->row = (kp_ent >> 3) & 0xf; | 85 | key->row = (kp_ent >> 3) & 0xf; |
86 | key->col = kp_ent & 0x7; | 86 | key->col = kp_ent & 0x7; |
87 | 87 | ||
88 | /* Shift to get next entry */ | 88 | /* Shift to get next entry */ |
89 | kp_ent >>= 8; | 89 | kp_ent >>= 8; |
90 | } | 90 | } |
91 | return key_matrix_decode(&priv->matrix, keys, KBC_MAX_KPENT, fifo, | 91 | return key_matrix_decode(&priv->matrix, keys, KBC_MAX_KPENT, fifo, |
92 | max_keycodes); | 92 | max_keycodes); |
93 | } | 93 | } |
94 | 94 | ||
95 | /** | 95 | /** |
96 | * Process all the keypress sequences in fifo and send key codes | 96 | * Process all the keypress sequences in fifo and send key codes |
97 | * | 97 | * |
98 | * The fifo contains zero or more keypress sets. Each set | 98 | * The fifo contains zero or more keypress sets. Each set |
99 | * consists of from 1-8 keycodes, representing the keycodes which | 99 | * consists of from 1-8 keycodes, representing the keycodes which |
100 | * were simultaneously pressed during that scan. | 100 | * were simultaneously pressed during that scan. |
101 | * | 101 | * |
102 | * This function works through each set and generates ASCII characters | 102 | * This function works through each set and generates ASCII characters |
103 | * for each. Not that one set may produce more than one ASCII characters - | 103 | * for each. Not that one set may produce more than one ASCII characters - |
104 | * for example holding down 'd' and 'f' at the same time will generate | 104 | * for example holding down 'd' and 'f' at the same time will generate |
105 | * two ASCII characters. | 105 | * two ASCII characters. |
106 | * | 106 | * |
107 | * Note: if fifo_cnt is 0, we will tell the input layer that no keys are | 107 | * Note: if fifo_cnt is 0, we will tell the input layer that no keys are |
108 | * pressed. | 108 | * pressed. |
109 | * | 109 | * |
110 | * @param priv Keyboard private data | 110 | * @param priv Keyboard private data |
111 | * @param fifo_cnt Number of entries in the keyboard fifo | 111 | * @param fifo_cnt Number of entries in the keyboard fifo |
112 | */ | 112 | */ |
113 | static void process_fifo(struct tegra_kbd_priv *priv, int fifo_cnt) | 113 | static void process_fifo(struct tegra_kbd_priv *priv, int fifo_cnt) |
114 | { | 114 | { |
115 | int fifo[KBC_MAX_KPENT]; | 115 | int fifo[KBC_MAX_KPENT]; |
116 | int cnt = 0; | 116 | int cnt = 0; |
117 | 117 | ||
118 | /* Always call input_send_keycodes() at least once */ | 118 | /* Always call input_send_keycodes() at least once */ |
119 | do { | 119 | do { |
120 | if (fifo_cnt) | 120 | if (fifo_cnt) |
121 | cnt = tegra_kbc_find_keys(priv, fifo, KBC_MAX_KPENT); | 121 | cnt = tegra_kbc_find_keys(priv, fifo, KBC_MAX_KPENT); |
122 | 122 | ||
123 | input_send_keycodes(priv->input, fifo, cnt); | 123 | input_send_keycodes(priv->input, fifo, cnt); |
124 | } while (--fifo_cnt > 0); | 124 | } while (--fifo_cnt > 0); |
125 | } | 125 | } |
126 | 126 | ||
127 | /** | 127 | /** |
128 | * Check the keyboard controller and emit ASCII characters for any keys that | 128 | * Check the keyboard controller and emit ASCII characters for any keys that |
129 | * are pressed. | 129 | * are pressed. |
130 | * | 130 | * |
131 | * @param priv Keyboard private data | 131 | * @param priv Keyboard private data |
132 | */ | 132 | */ |
133 | static void check_for_keys(struct tegra_kbd_priv *priv) | 133 | static void check_for_keys(struct tegra_kbd_priv *priv) |
134 | { | 134 | { |
135 | int fifo_cnt; | 135 | int fifo_cnt; |
136 | 136 | ||
137 | if (!priv->first_scan && | 137 | if (!priv->first_scan && |
138 | get_timer(priv->last_poll_ms) < KBC_REPEAT_RATE_MS) | 138 | get_timer(priv->last_poll_ms) < KBC_REPEAT_RATE_MS) |
139 | return; | 139 | return; |
140 | priv->last_poll_ms = get_timer(0); | 140 | priv->last_poll_ms = get_timer(0); |
141 | priv->first_scan = 0; | 141 | priv->first_scan = 0; |
142 | 142 | ||
143 | /* | 143 | /* |
144 | * Once we get here we know the keyboard has been scanned. So if there | 144 | * Once we get here we know the keyboard has been scanned. So if there |
145 | * scan waiting for us, we know that nothing is held down. | 145 | * scan waiting for us, we know that nothing is held down. |
146 | */ | 146 | */ |
147 | fifo_cnt = (readl(&priv->kbc->interrupt) >> 4) & 0xf; | 147 | fifo_cnt = (readl(&priv->kbc->interrupt) >> 4) & 0xf; |
148 | process_fifo(priv, fifo_cnt); | 148 | process_fifo(priv, fifo_cnt); |
149 | } | 149 | } |
150 | 150 | ||
151 | /** | 151 | /** |
152 | * In order to detect keys pressed on boot, wait for the hardware to | 152 | * In order to detect keys pressed on boot, wait for the hardware to |
153 | * complete scanning the keys. This includes time to transition from | 153 | * complete scanning the keys. This includes time to transition from |
154 | * Wkup mode to Continous polling mode and the repoll time. We can | 154 | * Wkup mode to Continous polling mode and the repoll time. We can |
155 | * deduct the time that's already elapsed. | 155 | * deduct the time that's already elapsed. |
156 | * | 156 | * |
157 | * @param priv Keyboard private data | 157 | * @param priv Keyboard private data |
158 | */ | 158 | */ |
159 | static void kbd_wait_for_fifo_init(struct tegra_kbd_priv *priv) | 159 | static void kbd_wait_for_fifo_init(struct tegra_kbd_priv *priv) |
160 | { | 160 | { |
161 | if (!priv->inited) { | 161 | if (!priv->inited) { |
162 | unsigned long elapsed_time; | 162 | unsigned long elapsed_time; |
163 | long delay_ms; | 163 | long delay_ms; |
164 | 164 | ||
165 | elapsed_time = get_timer(priv->start_time_ms); | 165 | elapsed_time = get_timer(priv->start_time_ms); |
166 | delay_ms = priv->init_dly_ms - elapsed_time; | 166 | delay_ms = priv->init_dly_ms - elapsed_time; |
167 | if (delay_ms > 0) { | 167 | if (delay_ms > 0) { |
168 | udelay(delay_ms * 1000); | 168 | udelay(delay_ms * 1000); |
169 | debug("%s: delay %ldms\n", __func__, delay_ms); | 169 | debug("%s: delay %ldms\n", __func__, delay_ms); |
170 | } | 170 | } |
171 | 171 | ||
172 | priv->inited = 1; | 172 | priv->inited = 1; |
173 | } | 173 | } |
174 | } | 174 | } |
175 | 175 | ||
176 | /** | 176 | /** |
177 | * Check the tegra keyboard, and send any keys that are pressed. | 177 | * Check the tegra keyboard, and send any keys that are pressed. |
178 | * | 178 | * |
179 | * This is called by input_tstc() and input_getc() when they need more | 179 | * This is called by input_tstc() and input_getc() when they need more |
180 | * characters | 180 | * characters |
181 | * | 181 | * |
182 | * @param input Input configuration | 182 | * @param input Input configuration |
183 | * @return 1, to indicate that we have something to look at | 183 | * @return 1, to indicate that we have something to look at |
184 | */ | 184 | */ |
185 | static int tegra_kbc_check(struct input_config *input) | 185 | static int tegra_kbc_check(struct input_config *input) |
186 | { | 186 | { |
187 | struct tegra_kbd_priv *priv = dev_get_priv(input->dev); | 187 | struct tegra_kbd_priv *priv = dev_get_priv(input->dev); |
188 | 188 | ||
189 | kbd_wait_for_fifo_init(priv); | 189 | kbd_wait_for_fifo_init(priv); |
190 | check_for_keys(priv); | 190 | check_for_keys(priv); |
191 | 191 | ||
192 | return 1; | 192 | return 1; |
193 | } | 193 | } |
194 | 194 | ||
195 | /* configures keyboard GPIO registers to use the rows and columns */ | 195 | /* configures keyboard GPIO registers to use the rows and columns */ |
196 | static void config_kbc_gpio(struct tegra_kbd_priv *priv, struct kbc_tegra *kbc) | 196 | static void config_kbc_gpio(struct tegra_kbd_priv *priv, struct kbc_tegra *kbc) |
197 | { | 197 | { |
198 | int i; | 198 | int i; |
199 | 199 | ||
200 | for (i = 0; i < KBC_MAX_GPIO; i++) { | 200 | for (i = 0; i < KBC_MAX_GPIO; i++) { |
201 | u32 row_cfg, col_cfg; | 201 | u32 row_cfg, col_cfg; |
202 | u32 r_shift = 5 * (i % 6); | 202 | u32 r_shift = 5 * (i % 6); |
203 | u32 c_shift = 4 * (i % 8); | 203 | u32 c_shift = 4 * (i % 8); |
204 | u32 r_mask = 0x1f << r_shift; | 204 | u32 r_mask = 0x1f << r_shift; |
205 | u32 c_mask = 0xf << c_shift; | 205 | u32 c_mask = 0xf << c_shift; |
206 | u32 r_offs = i / 6; | 206 | u32 r_offs = i / 6; |
207 | u32 c_offs = i / 8; | 207 | u32 c_offs = i / 8; |
208 | 208 | ||
209 | row_cfg = readl(&kbc->row_cfg[r_offs]); | 209 | row_cfg = readl(&kbc->row_cfg[r_offs]); |
210 | col_cfg = readl(&kbc->col_cfg[c_offs]); | 210 | col_cfg = readl(&kbc->col_cfg[c_offs]); |
211 | 211 | ||
212 | row_cfg &= ~r_mask; | 212 | row_cfg &= ~r_mask; |
213 | col_cfg &= ~c_mask; | 213 | col_cfg &= ~c_mask; |
214 | 214 | ||
215 | if (i < priv->matrix.num_rows) { | 215 | if (i < priv->matrix.num_rows) { |
216 | row_cfg |= ((i << 1) | 1) << r_shift; | 216 | row_cfg |= ((i << 1) | 1) << r_shift; |
217 | } else { | 217 | } else { |
218 | col_cfg |= (((i - priv->matrix.num_rows) << 1) | 1) | 218 | col_cfg |= (((i - priv->matrix.num_rows) << 1) | 1) |
219 | << c_shift; | 219 | << c_shift; |
220 | } | 220 | } |
221 | 221 | ||
222 | writel(row_cfg, &kbc->row_cfg[r_offs]); | 222 | writel(row_cfg, &kbc->row_cfg[r_offs]); |
223 | writel(col_cfg, &kbc->col_cfg[c_offs]); | 223 | writel(col_cfg, &kbc->col_cfg[c_offs]); |
224 | } | 224 | } |
225 | } | 225 | } |
226 | 226 | ||
227 | /** | 227 | /** |
228 | * Start up the keyboard device | 228 | * Start up the keyboard device |
229 | */ | 229 | */ |
230 | static void tegra_kbc_open(struct tegra_kbd_priv *priv) | 230 | static void tegra_kbc_open(struct tegra_kbd_priv *priv) |
231 | { | 231 | { |
232 | struct kbc_tegra *kbc = priv->kbc; | 232 | struct kbc_tegra *kbc = priv->kbc; |
233 | unsigned int scan_period; | 233 | unsigned int scan_period; |
234 | u32 val; | 234 | u32 val; |
235 | 235 | ||
236 | /* | 236 | /* |
237 | * We will scan at twice the keyboard repeat rate, so that there is | 237 | * We will scan at twice the keyboard repeat rate, so that there is |
238 | * always a scan ready when we check it in check_for_keys(). | 238 | * always a scan ready when we check it in check_for_keys(). |
239 | */ | 239 | */ |
240 | scan_period = KBC_REPEAT_RATE_MS / 2; | 240 | scan_period = KBC_REPEAT_RATE_MS / 2; |
241 | writel(scan_period * KBC_CLOCK_KHZ, &kbc->rpt_dly); | 241 | writel(scan_period * KBC_CLOCK_KHZ, &kbc->rpt_dly); |
242 | writel(scan_period * KBC_CLOCK_KHZ, &kbc->init_dly); | 242 | writel(scan_period * KBC_CLOCK_KHZ, &kbc->init_dly); |
243 | /* | 243 | /* |
244 | * Before reading from the keyboard we must wait for the init_dly | 244 | * Before reading from the keyboard we must wait for the init_dly |
245 | * plus the rpt_delay, plus 2ms for the row scan time. | 245 | * plus the rpt_delay, plus 2ms for the row scan time. |
246 | */ | 246 | */ |
247 | priv->init_dly_ms = scan_period * 2 + 2; | 247 | priv->init_dly_ms = scan_period * 2 + 2; |
248 | 248 | ||
249 | val = KBC_DEBOUNCE_COUNT << KBC_DEBOUNCE_CNT_SHIFT; | 249 | val = KBC_DEBOUNCE_COUNT << KBC_DEBOUNCE_CNT_SHIFT; |
250 | val |= 1 << KBC_FIFO_TH_CNT_SHIFT; /* fifo interrupt threshold */ | 250 | val |= 1 << KBC_FIFO_TH_CNT_SHIFT; /* fifo interrupt threshold */ |
251 | val |= KBC_CONTROL_KBC_EN; /* enable */ | 251 | val |= KBC_CONTROL_KBC_EN; /* enable */ |
252 | writel(val, &kbc->control); | 252 | writel(val, &kbc->control); |
253 | 253 | ||
254 | priv->start_time_ms = get_timer(0); | 254 | priv->start_time_ms = get_timer(0); |
255 | priv->last_poll_ms = get_timer(0); | 255 | priv->last_poll_ms = get_timer(0); |
256 | priv->next_repeat_ms = priv->last_poll_ms; | 256 | priv->next_repeat_ms = priv->last_poll_ms; |
257 | priv->first_scan = 1; | 257 | priv->first_scan = 1; |
258 | } | 258 | } |
259 | 259 | ||
260 | static int tegra_kbd_start(struct udevice *dev) | 260 | static int tegra_kbd_start(struct udevice *dev) |
261 | { | 261 | { |
262 | struct tegra_kbd_priv *priv = dev_get_priv(dev); | 262 | struct tegra_kbd_priv *priv = dev_get_priv(dev); |
263 | 263 | ||
264 | /* Set up pin mux and enable the clock */ | 264 | /* Set up pin mux and enable the clock */ |
265 | funcmux_select(PERIPH_ID_KBC, FUNCMUX_DEFAULT); | 265 | funcmux_select(PERIPH_ID_KBC, FUNCMUX_DEFAULT); |
266 | clock_enable(PERIPH_ID_KBC); | 266 | clock_enable(PERIPH_ID_KBC); |
267 | config_kbc_gpio(priv, priv->kbc); | 267 | config_kbc_gpio(priv, priv->kbc); |
268 | 268 | ||
269 | tegra_kbc_open(priv); | 269 | tegra_kbc_open(priv); |
270 | debug("%s: Tegra keyboard ready\n", __func__); | 270 | debug("%s: Tegra keyboard ready\n", __func__); |
271 | 271 | ||
272 | return 0; | 272 | return 0; |
273 | } | 273 | } |
274 | 274 | ||
275 | /** | 275 | /** |
276 | * Set up the tegra keyboard. This is called by the stdio device handler | 276 | * Set up the tegra keyboard. This is called by the stdio device handler |
277 | * | 277 | * |
278 | * We want to do this init when the keyboard is actually used rather than | 278 | * We want to do this init when the keyboard is actually used rather than |
279 | * at start-up, since keyboard input may not currently be selected. | 279 | * at start-up, since keyboard input may not currently be selected. |
280 | * | 280 | * |
281 | * Once the keyboard starts there will be a period during which we must | 281 | * Once the keyboard starts there will be a period during which we must |
282 | * wait for the keyboard to init. We do this only when a key is first | 282 | * wait for the keyboard to init. We do this only when a key is first |
283 | * read - see kbd_wait_for_fifo_init(). | 283 | * read - see kbd_wait_for_fifo_init(). |
284 | * | 284 | * |
285 | * @return 0 if ok, -ve on error | 285 | * @return 0 if ok, -ve on error |
286 | */ | 286 | */ |
287 | static int tegra_kbd_probe(struct udevice *dev) | 287 | static int tegra_kbd_probe(struct udevice *dev) |
288 | { | 288 | { |
289 | struct tegra_kbd_priv *priv = dev_get_priv(dev); | 289 | struct tegra_kbd_priv *priv = dev_get_priv(dev); |
290 | struct keyboard_priv *uc_priv = dev_get_uclass_priv(dev); | 290 | struct keyboard_priv *uc_priv = dev_get_uclass_priv(dev); |
291 | struct stdio_dev *sdev = &uc_priv->sdev; | 291 | struct stdio_dev *sdev = &uc_priv->sdev; |
292 | struct input_config *input = &uc_priv->input; | 292 | struct input_config *input = &uc_priv->input; |
293 | int node = dev_of_offset(dev); | ||
294 | int ret; | 293 | int ret; |
295 | 294 | ||
296 | priv->kbc = (struct kbc_tegra *)devfdt_get_addr(dev); | 295 | priv->kbc = (struct kbc_tegra *)devfdt_get_addr(dev); |
297 | if ((fdt_addr_t)priv->kbc == FDT_ADDR_T_NONE) { | 296 | if ((fdt_addr_t)priv->kbc == FDT_ADDR_T_NONE) { |
298 | debug("%s: No keyboard register found\n", __func__); | 297 | debug("%s: No keyboard register found\n", __func__); |
299 | return -EINVAL; | 298 | return -EINVAL; |
300 | } | 299 | } |
301 | input_set_delays(input, KBC_REPEAT_DELAY_MS, KBC_REPEAT_RATE_MS); | 300 | input_set_delays(input, KBC_REPEAT_DELAY_MS, KBC_REPEAT_RATE_MS); |
302 | 301 | ||
303 | /* Decode the keyboard matrix information (16 rows, 8 columns) */ | 302 | /* Decode the keyboard matrix information (16 rows, 8 columns) */ |
304 | ret = key_matrix_init(&priv->matrix, 16, 8, 1); | 303 | ret = key_matrix_init(&priv->matrix, 16, 8, 1); |
305 | if (ret) { | 304 | if (ret) { |
306 | debug("%s: Could not init key matrix: %d\n", __func__, ret); | 305 | debug("%s: Could not init key matrix: %d\n", __func__, ret); |
307 | return ret; | 306 | return ret; |
308 | } | 307 | } |
309 | ret = key_matrix_decode_fdt(&priv->matrix, gd->fdt_blob, node); | 308 | ret = key_matrix_decode_fdt(dev, &priv->matrix); |
310 | if (ret) { | 309 | if (ret) { |
311 | debug("%s: Could not decode key matrix from fdt: %d\n", | 310 | debug("%s: Could not decode key matrix from fdt: %d\n", |
312 | __func__, ret); | 311 | __func__, ret); |
313 | return ret; | 312 | return ret; |
314 | } | 313 | } |
315 | input_add_tables(input, false); | 314 | input_add_tables(input, false); |
316 | if (priv->matrix.fn_keycode) { | 315 | if (priv->matrix.fn_keycode) { |
317 | ret = input_add_table(input, KEY_FN, -1, | 316 | ret = input_add_table(input, KEY_FN, -1, |
318 | priv->matrix.fn_keycode, | 317 | priv->matrix.fn_keycode, |
319 | priv->matrix.key_count); | 318 | priv->matrix.key_count); |
320 | if (ret) { | 319 | if (ret) { |
321 | debug("%s: input_add_table() failed\n", __func__); | 320 | debug("%s: input_add_table() failed\n", __func__); |
322 | return ret; | 321 | return ret; |
323 | } | 322 | } |
324 | } | 323 | } |
325 | 324 | ||
326 | /* Register the device. init_tegra_keyboard() will be called soon */ | 325 | /* Register the device. init_tegra_keyboard() will be called soon */ |
327 | priv->input = input; | 326 | priv->input = input; |
328 | input->dev = dev; | 327 | input->dev = dev; |
329 | input->read_keys = tegra_kbc_check; | 328 | input->read_keys = tegra_kbc_check; |
330 | strcpy(sdev->name, "tegra-kbc"); | 329 | strcpy(sdev->name, "tegra-kbc"); |
331 | ret = input_stdio_register(sdev); | 330 | ret = input_stdio_register(sdev); |
332 | if (ret) { | 331 | if (ret) { |
333 | debug("%s: input_stdio_register() failed\n", __func__); | 332 | debug("%s: input_stdio_register() failed\n", __func__); |
334 | return ret; | 333 | return ret; |
335 | } | 334 | } |
336 | 335 | ||
337 | return 0; | 336 | return 0; |
338 | } | 337 | } |
339 | 338 | ||
340 | static const struct keyboard_ops tegra_kbd_ops = { | 339 | static const struct keyboard_ops tegra_kbd_ops = { |
341 | .start = tegra_kbd_start, | 340 | .start = tegra_kbd_start, |
342 | }; | 341 | }; |
343 | 342 | ||
344 | static const struct udevice_id tegra_kbd_ids[] = { | 343 | static const struct udevice_id tegra_kbd_ids[] = { |
345 | { .compatible = "nvidia,tegra20-kbc" }, | 344 | { .compatible = "nvidia,tegra20-kbc" }, |
346 | { } | 345 | { } |
347 | }; | 346 | }; |
348 | 347 | ||
349 | U_BOOT_DRIVER(tegra_kbd) = { | 348 | U_BOOT_DRIVER(tegra_kbd) = { |
350 | .name = "tegra_kbd", | 349 | .name = "tegra_kbd", |
351 | .id = UCLASS_KEYBOARD, | 350 | .id = UCLASS_KEYBOARD, |
352 | .of_match = tegra_kbd_ids, | 351 | .of_match = tegra_kbd_ids, |
353 | .probe = tegra_kbd_probe, | 352 | .probe = tegra_kbd_probe, |
354 | .ops = &tegra_kbd_ops, | 353 | .ops = &tegra_kbd_ops, |
355 | .priv_auto_alloc_size = sizeof(struct tegra_kbd_priv), | 354 | .priv_auto_alloc_size = sizeof(struct tegra_kbd_priv), |
356 | }; | 355 | }; |
357 | 356 |
include/key_matrix.h
1 | /* | 1 | /* |
2 | * Keyboard matrix helper functions | 2 | * Keyboard matrix helper functions |
3 | * | 3 | * |
4 | * Copyright (c) 2012 The Chromium OS Authors. | 4 | * Copyright (c) 2012 The Chromium OS Authors. |
5 | * | 5 | * |
6 | * SPDX-License-Identifier: GPL-2.0+ | 6 | * SPDX-License-Identifier: GPL-2.0+ |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #ifndef _KEY_MATRIX_H | 9 | #ifndef _KEY_MATRIX_H |
10 | #define _KEY_MATRIX_H | 10 | #define _KEY_MATRIX_H |
11 | 11 | ||
12 | #include <common.h> | 12 | #include <common.h> |
13 | 13 | ||
14 | /* Information about a matrix keyboard */ | 14 | /* Information about a matrix keyboard */ |
15 | struct key_matrix { | 15 | struct key_matrix { |
16 | /* Dimensions of the keyboard matrix, in rows and columns */ | 16 | /* Dimensions of the keyboard matrix, in rows and columns */ |
17 | int num_rows; | 17 | int num_rows; |
18 | int num_cols; | 18 | int num_cols; |
19 | int key_count; /* number of keys in the matrix (= rows * cols) */ | 19 | int key_count; /* number of keys in the matrix (= rows * cols) */ |
20 | 20 | ||
21 | /* | 21 | /* |
22 | * Information about keycode mappings. The plain_keycode array must | 22 | * Information about keycode mappings. The plain_keycode array must |
23 | * exist but fn may be NULL in which case it is not decoded. | 23 | * exist but fn may be NULL in which case it is not decoded. |
24 | */ | 24 | */ |
25 | const u8 *plain_keycode; /* key code for each row / column */ | 25 | const u8 *plain_keycode; /* key code for each row / column */ |
26 | const u8 *fn_keycode; /* ...when Fn held down */ | 26 | const u8 *fn_keycode; /* ...when Fn held down */ |
27 | int fn_pos; /* position of Fn key in key (or -1) */ | 27 | int fn_pos; /* position of Fn key in key (or -1) */ |
28 | int ghost_filter; /* non-zero to enable ghost filter */ | 28 | int ghost_filter; /* non-zero to enable ghost filter */ |
29 | }; | 29 | }; |
30 | 30 | ||
31 | /* Information about a particular key (row, column pair) in the matrix */ | 31 | /* Information about a particular key (row, column pair) in the matrix */ |
32 | struct key_matrix_key { | 32 | struct key_matrix_key { |
33 | uint8_t row; /* row number (0 = first) */ | 33 | uint8_t row; /* row number (0 = first) */ |
34 | uint8_t col; /* column number (0 = first) */ | 34 | uint8_t col; /* column number (0 = first) */ |
35 | uint8_t valid; /* 1 if valid, 0 to ignore this */ | 35 | uint8_t valid; /* 1 if valid, 0 to ignore this */ |
36 | }; | 36 | }; |
37 | 37 | ||
38 | /** | 38 | /** |
39 | * Decode a set of pressed keys into key codes | 39 | * Decode a set of pressed keys into key codes |
40 | * | 40 | * |
41 | * Given a list of keys that are pressed, this converts this list into | 41 | * Given a list of keys that are pressed, this converts this list into |
42 | * a list of key codes. Each of the keys has a valid flag, which can be | 42 | * a list of key codes. Each of the keys has a valid flag, which can be |
43 | * used to mark a particular key as invalid (so that it is ignored). | 43 | * used to mark a particular key as invalid (so that it is ignored). |
44 | * | 44 | * |
45 | * The plain keymap is used, unless the Fn key is detected along the way, | 45 | * The plain keymap is used, unless the Fn key is detected along the way, |
46 | * at which point we switch to the Fn key map. | 46 | * at which point we switch to the Fn key map. |
47 | * | 47 | * |
48 | * If key ghosting is detected, we simply ignore the keys and return 0. | 48 | * If key ghosting is detected, we simply ignore the keys and return 0. |
49 | * | 49 | * |
50 | * @param config Keyboard matrix config | 50 | * @param config Keyboard matrix config |
51 | * @param keys List of keys to process (each is row, col) | 51 | * @param keys List of keys to process (each is row, col) |
52 | * @param num_keys Number of keys to process | 52 | * @param num_keys Number of keys to process |
53 | * @param keycode Returns a list of key codes, decoded from input | 53 | * @param keycode Returns a list of key codes, decoded from input |
54 | * @param max_keycodes Size of key codes array (suggest 8) | 54 | * @param max_keycodes Size of key codes array (suggest 8) |
55 | * | 55 | * |
56 | */ | 56 | */ |
57 | int key_matrix_decode(struct key_matrix *config, struct key_matrix_key *keys, | 57 | int key_matrix_decode(struct key_matrix *config, struct key_matrix_key *keys, |
58 | int num_keys, int keycode[], int max_keycodes); | 58 | int num_keys, int keycode[], int max_keycodes); |
59 | 59 | ||
60 | /** | 60 | /** |
61 | * Read the keyboard configuration out of the fdt. | 61 | * Read the keyboard configuration out of the fdt. |
62 | * | 62 | * |
63 | * Decode properties of named "linux,<type>keymap" where <type> is either | 63 | * Decode properties of named "linux,<type>keymap" where <type> is either |
64 | * empty, or "fn-". Then set up the plain key map (and the FN keymap if | 64 | * empty, or "fn-". Then set up the plain key map (and the FN keymap if |
65 | * present). | 65 | * present). |
66 | * | 66 | * |
67 | * @param config Keyboard matrix config | 67 | * @param config Keyboard matrix config |
68 | * @param blob FDT blob | 68 | * @param blob FDT blob |
69 | * @param node Node containing compatible data | 69 | * @param node Node containing compatible data |
70 | * @return 0 if ok, -1 on error | 70 | * @return 0 if ok, -1 on error |
71 | */ | 71 | */ |
72 | int key_matrix_decode_fdt(struct key_matrix *config, const void *blob, | 72 | int key_matrix_decode_fdt(struct udevice *dev, struct key_matrix *config); |
73 | int node); | ||
74 | 73 | ||
75 | /** | 74 | /** |
76 | * Set up a new key matrix. | 75 | * Set up a new key matrix. |
77 | * | 76 | * |
78 | * @param config Keyboard matrix config | 77 | * @param config Keyboard matrix config |
79 | * @param rows Number of rows in key matrix | 78 | * @param rows Number of rows in key matrix |
80 | * @param cols Number of columns in key matrix | 79 | * @param cols Number of columns in key matrix |
81 | * @param ghost_filter Non-zero to enable ghost filtering | 80 | * @param ghost_filter Non-zero to enable ghost filtering |
82 | * @return 0 if ok, -1 on error | 81 | * @return 0 if ok, -1 on error |
83 | */ | 82 | */ |
84 | int key_matrix_init(struct key_matrix *config, int rows, int cols, | 83 | int key_matrix_init(struct key_matrix *config, int rows, int cols, |
85 | int ghost_filter); | 84 | int ghost_filter); |
86 | 85 | ||
87 | #endif | 86 | #endif |
88 | 87 |