1 // SPDX-License-Identifier: GPL-2.0-only
2 //
3 // Copyright (C) 2021-2022 Samuel Holland <samuel@sholland.org>
4
5 #include <linux/crc8.h>
6 #include <linux/delay.h>
7 #include <linux/err.h>
8 #include <linux/i2c.h>
9 #include <linux/input.h>
10 #include <linux/input/matrix_keypad.h>
11 #include <linux/interrupt.h>
12 #include <linux/module.h>
13 #include <linux/of.h>
14 #include <linux/regulator/consumer.h>
15 #include <linux/types.h>
16
17 #define DRV_NAME "pinephone-keyboard"
18
19 #define PPKB_CRC8_POLYNOMIAL 0x07
20
21 #define PPKB_DEVICE_ID_HI 0x00
22 #define PPKB_DEVICE_ID_HI_VALUE 'K'
23 #define PPKB_DEVICE_ID_LO 0x01
24 #define PPKB_DEVICE_ID_LO_VALUE 'B'
25 #define PPKB_FW_REVISION 0x02
26 #define PPKB_FW_FEATURES 0x03
27 #define PPKB_MATRIX_SIZE 0x06
28 #define PPKB_SCAN_CRC 0x07
29 #define PPKB_SCAN_DATA 0x08
30 #define PPKB_SYS_CONFIG 0x20
31 #define PPKB_SYS_CONFIG_DISABLE_SCAN BIT(0)
32 #define PPKB_SYS_SMBUS_COMMAND 0x21
33 #define PPKB_SYS_SMBUS_DATA 0x22
34 #define PPKB_SYS_COMMAND 0x23
35 #define PPKB_SYS_COMMAND_SMBUS_READ 0x91
36 #define PPKB_SYS_COMMAND_SMBUS_WRITE 0xa1
37
38 #define PPKB_ROWS 6
39 #define PPKB_COLS 12
40
41 /* Size of the scan buffer, including the CRC byte at the beginning. */
42 #define PPKB_BUF_LEN (1 + PPKB_COLS)
43
44 static const uint32_t ppkb_keymap[] = {
45 KEY(0, 0, KEY_ESC),
46 KEY(0, 1, KEY_1),
47 KEY(0, 2, KEY_2),
48 KEY(0, 3, KEY_3),
49 KEY(0, 4, KEY_4),
50 KEY(0, 5, KEY_5),
51 KEY(0, 6, KEY_6),
52 KEY(0, 7, KEY_7),
53 KEY(0, 8, KEY_8),
54 KEY(0, 9, KEY_9),
55 KEY(0, 10, KEY_0),
56 KEY(0, 11, KEY_BACKSPACE),
57
58 KEY(1, 0, KEY_TAB),
59 KEY(1, 1, KEY_Q),
60 KEY(1, 2, KEY_W),
61 KEY(1, 3, KEY_E),
62 KEY(1, 4, KEY_R),
63 KEY(1, 5, KEY_T),
64 KEY(1, 6, KEY_Y),
65 KEY(1, 7, KEY_U),
66 KEY(1, 8, KEY_I),
67 KEY(1, 9, KEY_O),
68 KEY(1, 10, KEY_P),
69 KEY(1, 11, KEY_ENTER),
70
71 KEY(2, 0, KEY_LEFTMETA),
72 KEY(2, 1, KEY_A),
73 KEY(2, 2, KEY_S),
74 KEY(2, 3, KEY_D),
75 KEY(2, 4, KEY_F),
76 KEY(2, 5, KEY_G),
77 KEY(2, 6, KEY_H),
78 KEY(2, 7, KEY_J),
79 KEY(2, 8, KEY_K),
80 KEY(2, 9, KEY_L),
81 KEY(2, 10, KEY_SEMICOLON),
82
83 KEY(3, 0, KEY_LEFTSHIFT),
84 KEY(3, 1, KEY_Z),
85 KEY(3, 2, KEY_X),
86 KEY(3, 3, KEY_C),
87 KEY(3, 4, KEY_V),
88 KEY(3, 5, KEY_B),
89 KEY(3, 6, KEY_N),
90 KEY(3, 7, KEY_M),
91 KEY(3, 8, KEY_COMMA),
92 KEY(3, 9, KEY_DOT),
93 KEY(3, 10, KEY_SLASH),
94
95 KEY(4, 1, KEY_LEFTCTRL),
96 KEY(4, 4, KEY_SPACE),
97 KEY(4, 6, KEY_APOSTROPHE),
98 KEY(4, 8, KEY_RIGHTBRACE),
99 KEY(4, 9, KEY_LEFTBRACE),
100
101 KEY(5, 2, KEY_FN),
102 KEY(5, 3, KEY_LEFTALT),
103 KEY(5, 5, KEY_RIGHTALT),
104
105 /* FN layer */
106 KEY(PPKB_ROWS + 0, 0, KEY_FN_ESC),
107 KEY(PPKB_ROWS + 0, 1, KEY_F1),
108 KEY(PPKB_ROWS + 0, 2, KEY_F2),
109 KEY(PPKB_ROWS + 0, 3, KEY_F3),
110 KEY(PPKB_ROWS + 0, 4, KEY_F4),
111 KEY(PPKB_ROWS + 0, 5, KEY_F5),
112 KEY(PPKB_ROWS + 0, 6, KEY_F6),
113 KEY(PPKB_ROWS + 0, 7, KEY_F7),
114 KEY(PPKB_ROWS + 0, 8, KEY_F8),
115 KEY(PPKB_ROWS + 0, 9, KEY_F9),
116 KEY(PPKB_ROWS + 0, 10, KEY_F10),
117 KEY(PPKB_ROWS + 0, 11, KEY_DELETE),
118
119 KEY(PPKB_ROWS + 1, 10, KEY_PAGEUP),
120
121 KEY(PPKB_ROWS + 2, 0, KEY_SYSRQ),
122 KEY(PPKB_ROWS + 2, 9, KEY_PAGEDOWN),
123 KEY(PPKB_ROWS + 2, 10, KEY_INSERT),
124
125 KEY(PPKB_ROWS + 3, 0, KEY_LEFTSHIFT),
126 KEY(PPKB_ROWS + 3, 8, KEY_HOME),
127 KEY(PPKB_ROWS + 3, 9, KEY_UP),
128 KEY(PPKB_ROWS + 3, 10, KEY_END),
129
130 KEY(PPKB_ROWS + 4, 1, KEY_LEFTCTRL),
131 KEY(PPKB_ROWS + 4, 6, KEY_LEFT),
132 KEY(PPKB_ROWS + 4, 8, KEY_RIGHT),
133 KEY(PPKB_ROWS + 4, 9, KEY_DOWN),
134
135 KEY(PPKB_ROWS + 5, 3, KEY_LEFTALT),
136 KEY(PPKB_ROWS + 5, 5, KEY_RIGHTALT),
137 };
138
139 static const struct matrix_keymap_data ppkb_keymap_data = {
140 .keymap = ppkb_keymap,
141 .keymap_size = ARRAY_SIZE(ppkb_keymap),
142 };
143
144 struct pinephone_keyboard {
145 struct i2c_adapter adapter;
146 struct input_dev *input;
147 u8 buf[2][PPKB_BUF_LEN];
148 u8 crc_table[CRC8_TABLE_SIZE];
149 u8 fn_state[PPKB_COLS];
150 bool buf_swap;
151 bool fn_pressed;
152 };
153
ppkb_adap_smbus_xfer(struct i2c_adapter * adap,u16 addr,unsigned short flags,char read_write,u8 command,int size,union i2c_smbus_data * data)154 static int ppkb_adap_smbus_xfer(struct i2c_adapter *adap, u16 addr,
155 unsigned short flags, char read_write,
156 u8 command, int size,
157 union i2c_smbus_data *data)
158 {
159 struct i2c_client *client = adap->algo_data;
160 u8 buf[3];
161 int ret;
162
163 buf[0] = command;
164 buf[1] = data->byte;
165 buf[2] = read_write == I2C_SMBUS_READ ? PPKB_SYS_COMMAND_SMBUS_READ
166 : PPKB_SYS_COMMAND_SMBUS_WRITE;
167
168 ret = i2c_smbus_write_i2c_block_data(client, PPKB_SYS_SMBUS_COMMAND,
169 sizeof(buf), buf);
170 if (ret)
171 return ret;
172
173 /* Read back the command status until it passes or fails. */
174 do {
175 usleep_range(300, 500);
176 ret = i2c_smbus_read_byte_data(client, PPKB_SYS_COMMAND);
177 } while (ret == buf[2]);
178 if (ret < 0)
179 return ret;
180 /* Commands return 0x00 on success and 0xff on failure. */
181 if (ret)
182 return -EIO;
183
184 if (read_write == I2C_SMBUS_READ) {
185 ret = i2c_smbus_read_byte_data(client, PPKB_SYS_SMBUS_DATA);
186 if (ret < 0)
187 return ret;
188
189 data->byte = ret;
190 }
191
192 return 0;
193 }
194
ppkg_adap_functionality(struct i2c_adapter * adap)195 static u32 ppkg_adap_functionality(struct i2c_adapter *adap)
196 {
197 return I2C_FUNC_SMBUS_BYTE_DATA;
198 }
199
200 static const struct i2c_algorithm ppkb_adap_algo = {
201 .smbus_xfer = ppkb_adap_smbus_xfer,
202 .functionality = ppkg_adap_functionality,
203 };
204
ppkb_update(struct i2c_client * client)205 static void ppkb_update(struct i2c_client *client)
206 {
207 struct pinephone_keyboard *ppkb = i2c_get_clientdata(client);
208 unsigned short *keymap = ppkb->input->keycode;
209 int row_shift = get_count_order(PPKB_COLS);
210 u8 *old_buf = ppkb->buf[!ppkb->buf_swap];
211 u8 *new_buf = ppkb->buf[ppkb->buf_swap];
212 int col, crc, ret, row;
213 struct device *dev = &client->dev;
214
215 ret = i2c_smbus_read_i2c_block_data(client, PPKB_SCAN_CRC,
216 PPKB_BUF_LEN, new_buf);
217 if (ret != PPKB_BUF_LEN) {
218 dev_err(dev, "Failed to read scan data: %d\n", ret);
219 return;
220 }
221
222 crc = crc8(ppkb->crc_table, &new_buf[1], PPKB_COLS, CRC8_INIT_VALUE);
223 if (crc != new_buf[0]) {
224 dev_err(dev, "Bad scan data (%02x != %02x)\n", crc, new_buf[0]);
225 return;
226 }
227
228 ppkb->buf_swap = !ppkb->buf_swap;
229
230 for (col = 0; col < PPKB_COLS; ++col) {
231 u8 old = old_buf[1 + col];
232 u8 new = new_buf[1 + col];
233 u8 changed = old ^ new;
234
235 if (!changed)
236 continue;
237
238 for (row = 0; row < PPKB_ROWS; ++row) {
239 u8 mask = BIT(row);
240 u8 value = new & mask;
241 unsigned short code;
242 bool fn_state;
243
244 if (!(changed & mask))
245 continue;
246
247 /*
248 * Save off the FN key state when the key was pressed,
249 * and use that to determine the code during a release.
250 */
251 fn_state = value ? ppkb->fn_pressed : ppkb->fn_state[col] & mask;
252 if (fn_state)
253 ppkb->fn_state[col] ^= mask;
254
255 /* The FN layer is a second set of rows. */
256 code = MATRIX_SCAN_CODE(fn_state ? PPKB_ROWS + row : row,
257 col, row_shift);
258 input_event(ppkb->input, EV_MSC, MSC_SCAN, code);
259 input_report_key(ppkb->input, keymap[code], value);
260 if (keymap[code] == KEY_FN)
261 ppkb->fn_pressed = value;
262 }
263 }
264 input_sync(ppkb->input);
265 }
266
ppkb_irq_thread(int irq,void * data)267 static irqreturn_t ppkb_irq_thread(int irq, void *data)
268 {
269 struct i2c_client *client = data;
270
271 ppkb_update(client);
272
273 return IRQ_HANDLED;
274 }
275
ppkb_set_scan(struct i2c_client * client,bool enable)276 static int ppkb_set_scan(struct i2c_client *client, bool enable)
277 {
278 struct device *dev = &client->dev;
279 int ret, val;
280
281 ret = i2c_smbus_read_byte_data(client, PPKB_SYS_CONFIG);
282 if (ret < 0) {
283 dev_err(dev, "Failed to read config: %d\n", ret);
284 return ret;
285 }
286
287 if (enable)
288 val = ret & ~PPKB_SYS_CONFIG_DISABLE_SCAN;
289 else
290 val = ret | PPKB_SYS_CONFIG_DISABLE_SCAN;
291
292 ret = i2c_smbus_write_byte_data(client, PPKB_SYS_CONFIG, val);
293 if (ret) {
294 dev_err(dev, "Failed to write config: %d\n", ret);
295 return ret;
296 }
297
298 return 0;
299 }
300
ppkb_open(struct input_dev * input)301 static int ppkb_open(struct input_dev *input)
302 {
303 struct i2c_client *client = input_get_drvdata(input);
304 int error;
305
306 error = ppkb_set_scan(client, true);
307 if (error)
308 return error;
309
310 return 0;
311 }
312
ppkb_close(struct input_dev * input)313 static void ppkb_close(struct input_dev *input)
314 {
315 struct i2c_client *client = input_get_drvdata(input);
316
317 ppkb_set_scan(client, false);
318 }
319
ppkb_probe(struct i2c_client * client)320 static int ppkb_probe(struct i2c_client *client)
321 {
322 struct device *dev = &client->dev;
323 unsigned int phys_rows, phys_cols;
324 struct pinephone_keyboard *ppkb;
325 u8 info[PPKB_MATRIX_SIZE + 1];
326 struct device_node *i2c_bus;
327 int ret;
328 int error;
329
330 error = devm_regulator_get_enable(dev, "vbat");
331 if (error) {
332 dev_err(dev, "Failed to get VBAT supply: %d\n", error);
333 return error;
334 }
335
336 ret = i2c_smbus_read_i2c_block_data(client, 0, sizeof(info), info);
337 if (ret != sizeof(info)) {
338 error = ret < 0 ? ret : -EIO;
339 dev_err(dev, "Failed to read device ID: %d\n", error);
340 return error;
341 }
342
343 if (info[PPKB_DEVICE_ID_HI] != PPKB_DEVICE_ID_HI_VALUE ||
344 info[PPKB_DEVICE_ID_LO] != PPKB_DEVICE_ID_LO_VALUE) {
345 dev_warn(dev, "Unexpected device ID: %#02x %#02x\n",
346 info[PPKB_DEVICE_ID_HI], info[PPKB_DEVICE_ID_LO]);
347 return -ENODEV;
348 }
349
350 dev_info(dev, "Found firmware version %d.%d features %#x\n",
351 info[PPKB_FW_REVISION] >> 4,
352 info[PPKB_FW_REVISION] & 0xf,
353 info[PPKB_FW_FEATURES]);
354
355 phys_rows = info[PPKB_MATRIX_SIZE] & 0xf;
356 phys_cols = info[PPKB_MATRIX_SIZE] >> 4;
357 if (phys_rows != PPKB_ROWS || phys_cols != PPKB_COLS) {
358 dev_err(dev, "Unexpected keyboard size %ux%u\n",
359 phys_rows, phys_cols);
360 return -EINVAL;
361 }
362
363 /* Disable scan by default to save power. */
364 error = ppkb_set_scan(client, false);
365 if (error)
366 return error;
367
368 ppkb = devm_kzalloc(dev, sizeof(*ppkb), GFP_KERNEL);
369 if (!ppkb)
370 return -ENOMEM;
371
372 i2c_set_clientdata(client, ppkb);
373
374 i2c_bus = of_get_child_by_name(dev->of_node, "i2c");
375 if (i2c_bus) {
376 ppkb->adapter.owner = THIS_MODULE;
377 ppkb->adapter.algo = &ppkb_adap_algo;
378 ppkb->adapter.algo_data = client;
379 ppkb->adapter.dev.parent = dev;
380 ppkb->adapter.dev.of_node = i2c_bus;
381 strscpy(ppkb->adapter.name, DRV_NAME, sizeof(ppkb->adapter.name));
382
383 error = devm_i2c_add_adapter(dev, &ppkb->adapter);
384 if (error) {
385 dev_err(dev, "Failed to add I2C adapter: %d\n", error);
386 return error;
387 }
388 }
389
390 crc8_populate_msb(ppkb->crc_table, PPKB_CRC8_POLYNOMIAL);
391
392 ppkb->input = devm_input_allocate_device(dev);
393 if (!ppkb->input)
394 return -ENOMEM;
395
396 input_set_drvdata(ppkb->input, client);
397
398 ppkb->input->name = "PinePhone Keyboard";
399 ppkb->input->phys = DRV_NAME "/input0";
400 ppkb->input->id.bustype = BUS_I2C;
401 ppkb->input->open = ppkb_open;
402 ppkb->input->close = ppkb_close;
403
404 input_set_capability(ppkb->input, EV_MSC, MSC_SCAN);
405 __set_bit(EV_REP, ppkb->input->evbit);
406
407 error = matrix_keypad_build_keymap(&ppkb_keymap_data, NULL,
408 2 * PPKB_ROWS, PPKB_COLS, NULL,
409 ppkb->input);
410 if (error) {
411 dev_err(dev, "Failed to build keymap: %d\n", error);
412 return error;
413 }
414
415 error = input_register_device(ppkb->input);
416 if (error) {
417 dev_err(dev, "Failed to register input: %d\n", error);
418 return error;
419 }
420
421 error = devm_request_threaded_irq(dev, client->irq,
422 NULL, ppkb_irq_thread,
423 IRQF_ONESHOT, client->name, client);
424 if (error) {
425 dev_err(dev, "Failed to request IRQ: %d\n", error);
426 return error;
427 }
428
429 return 0;
430 }
431
432 static const struct of_device_id ppkb_of_match[] = {
433 { .compatible = "pine64,pinephone-keyboard" },
434 { }
435 };
436 MODULE_DEVICE_TABLE(of, ppkb_of_match);
437
438 static struct i2c_driver ppkb_driver = {
439 .probe = ppkb_probe,
440 .driver = {
441 .name = DRV_NAME,
442 .of_match_table = ppkb_of_match,
443 },
444 };
445 module_i2c_driver(ppkb_driver);
446
447 MODULE_AUTHOR("Samuel Holland <samuel@sholland.org>");
448 MODULE_DESCRIPTION("Pine64 PinePhone keyboard driver");
449 MODULE_LICENSE("GPL");
450