1 // SPDX-License-Identifier: GPL-2.0-only
3 // Copyright (C) 2021-2022 Samuel Holland <samuel@sholland.org>
5 #include <linux/crc8.h>
6 #include <linux/delay.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/mod_devicetable.h>
15 #include <linux/regulator/consumer.h>
16 #include <linux/types.h>
18 #define DRV_NAME "pinephone-keyboard"
20 #define PPKB_CRC8_POLYNOMIAL 0x07
22 #define PPKB_DEVICE_ID_HI 0x00
23 #define PPKB_DEVICE_ID_HI_VALUE 'K'
24 #define PPKB_DEVICE_ID_LO 0x01
25 #define PPKB_DEVICE_ID_LO_VALUE 'B'
26 #define PPKB_FW_REVISION 0x02
27 #define PPKB_FW_FEATURES 0x03
28 #define PPKB_MATRIX_SIZE 0x06
29 #define PPKB_SCAN_CRC 0x07
30 #define PPKB_SCAN_DATA 0x08
31 #define PPKB_SYS_CONFIG 0x20
32 #define PPKB_SYS_CONFIG_DISABLE_SCAN BIT(0)
33 #define PPKB_SYS_SMBUS_COMMAND 0x21
34 #define PPKB_SYS_SMBUS_DATA 0x22
35 #define PPKB_SYS_COMMAND 0x23
36 #define PPKB_SYS_COMMAND_SMBUS_READ 0x91
37 #define PPKB_SYS_COMMAND_SMBUS_WRITE 0xa1
42 /* Size of the scan buffer, including the CRC byte at the beginning. */
43 #define PPKB_BUF_LEN (1 + PPKB_COLS)
45 static const uint32_t ppkb_keymap
[] = {
57 KEY(0, 11, KEY_BACKSPACE
),
70 KEY(1, 11, KEY_ENTER
),
72 KEY(2, 0, KEY_LEFTMETA
),
82 KEY(2, 10, KEY_SEMICOLON
),
84 KEY(3, 0, KEY_LEFTSHIFT
),
94 KEY(3, 10, KEY_SLASH
),
96 KEY(4, 1, KEY_LEFTCTRL
),
98 KEY(4, 6, KEY_APOSTROPHE
),
99 KEY(4, 8, KEY_RIGHTBRACE
),
100 KEY(4, 9, KEY_LEFTBRACE
),
103 KEY(5, 3, KEY_LEFTALT
),
104 KEY(5, 5, KEY_RIGHTALT
),
107 KEY(PPKB_ROWS
+ 0, 0, KEY_FN_ESC
),
108 KEY(PPKB_ROWS
+ 0, 1, KEY_F1
),
109 KEY(PPKB_ROWS
+ 0, 2, KEY_F2
),
110 KEY(PPKB_ROWS
+ 0, 3, KEY_F3
),
111 KEY(PPKB_ROWS
+ 0, 4, KEY_F4
),
112 KEY(PPKB_ROWS
+ 0, 5, KEY_F5
),
113 KEY(PPKB_ROWS
+ 0, 6, KEY_F6
),
114 KEY(PPKB_ROWS
+ 0, 7, KEY_F7
),
115 KEY(PPKB_ROWS
+ 0, 8, KEY_F8
),
116 KEY(PPKB_ROWS
+ 0, 9, KEY_F9
),
117 KEY(PPKB_ROWS
+ 0, 10, KEY_F10
),
118 KEY(PPKB_ROWS
+ 0, 11, KEY_DELETE
),
120 KEY(PPKB_ROWS
+ 1, 10, KEY_PAGEUP
),
122 KEY(PPKB_ROWS
+ 2, 0, KEY_SYSRQ
),
123 KEY(PPKB_ROWS
+ 2, 9, KEY_PAGEDOWN
),
124 KEY(PPKB_ROWS
+ 2, 10, KEY_INSERT
),
126 KEY(PPKB_ROWS
+ 3, 0, KEY_LEFTSHIFT
),
127 KEY(PPKB_ROWS
+ 3, 8, KEY_HOME
),
128 KEY(PPKB_ROWS
+ 3, 9, KEY_UP
),
129 KEY(PPKB_ROWS
+ 3, 10, KEY_END
),
131 KEY(PPKB_ROWS
+ 4, 1, KEY_LEFTCTRL
),
132 KEY(PPKB_ROWS
+ 4, 6, KEY_LEFT
),
133 KEY(PPKB_ROWS
+ 4, 8, KEY_RIGHT
),
134 KEY(PPKB_ROWS
+ 4, 9, KEY_DOWN
),
136 KEY(PPKB_ROWS
+ 5, 3, KEY_LEFTALT
),
137 KEY(PPKB_ROWS
+ 5, 5, KEY_RIGHTALT
),
140 static const struct matrix_keymap_data ppkb_keymap_data
= {
141 .keymap
= ppkb_keymap
,
142 .keymap_size
= ARRAY_SIZE(ppkb_keymap
),
145 struct pinephone_keyboard
{
146 struct i2c_adapter adapter
;
147 struct input_dev
*input
;
148 u8 buf
[2][PPKB_BUF_LEN
];
149 u8 crc_table
[CRC8_TABLE_SIZE
];
150 u8 fn_state
[PPKB_COLS
];
155 static int ppkb_adap_smbus_xfer(struct i2c_adapter
*adap
, u16 addr
,
156 unsigned short flags
, char read_write
,
157 u8 command
, int size
,
158 union i2c_smbus_data
*data
)
160 struct i2c_client
*client
= adap
->algo_data
;
166 buf
[2] = read_write
== I2C_SMBUS_READ
? PPKB_SYS_COMMAND_SMBUS_READ
167 : PPKB_SYS_COMMAND_SMBUS_WRITE
;
169 ret
= i2c_smbus_write_i2c_block_data(client
, PPKB_SYS_SMBUS_COMMAND
,
174 /* Read back the command status until it passes or fails. */
176 usleep_range(300, 500);
177 ret
= i2c_smbus_read_byte_data(client
, PPKB_SYS_COMMAND
);
178 } while (ret
== buf
[2]);
181 /* Commands return 0x00 on success and 0xff on failure. */
185 if (read_write
== I2C_SMBUS_READ
) {
186 ret
= i2c_smbus_read_byte_data(client
, PPKB_SYS_SMBUS_DATA
);
196 static u32
ppkg_adap_functionality(struct i2c_adapter
*adap
)
198 return I2C_FUNC_SMBUS_BYTE_DATA
;
201 static const struct i2c_algorithm ppkb_adap_algo
= {
202 .smbus_xfer
= ppkb_adap_smbus_xfer
,
203 .functionality
= ppkg_adap_functionality
,
206 static void ppkb_update(struct i2c_client
*client
)
208 struct pinephone_keyboard
*ppkb
= i2c_get_clientdata(client
);
209 unsigned short *keymap
= ppkb
->input
->keycode
;
210 int row_shift
= get_count_order(PPKB_COLS
);
211 u8
*old_buf
= ppkb
->buf
[!ppkb
->buf_swap
];
212 u8
*new_buf
= ppkb
->buf
[ppkb
->buf_swap
];
213 int col
, crc
, ret
, row
;
214 struct device
*dev
= &client
->dev
;
216 ret
= i2c_smbus_read_i2c_block_data(client
, PPKB_SCAN_CRC
,
217 PPKB_BUF_LEN
, new_buf
);
218 if (ret
!= PPKB_BUF_LEN
) {
219 dev_err(dev
, "Failed to read scan data: %d\n", ret
);
223 crc
= crc8(ppkb
->crc_table
, &new_buf
[1], PPKB_COLS
, CRC8_INIT_VALUE
);
224 if (crc
!= new_buf
[0]) {
225 dev_err(dev
, "Bad scan data (%02x != %02x)\n", crc
, new_buf
[0]);
229 ppkb
->buf_swap
= !ppkb
->buf_swap
;
231 for (col
= 0; col
< PPKB_COLS
; ++col
) {
232 u8 old
= old_buf
[1 + col
];
233 u8
new = new_buf
[1 + col
];
234 u8 changed
= old
^ new;
239 for (row
= 0; row
< PPKB_ROWS
; ++row
) {
241 u8 value
= new & mask
;
245 if (!(changed
& mask
))
249 * Save off the FN key state when the key was pressed,
250 * and use that to determine the code during a release.
252 fn_state
= value
? ppkb
->fn_pressed
: ppkb
->fn_state
[col
] & mask
;
254 ppkb
->fn_state
[col
] ^= mask
;
256 /* The FN layer is a second set of rows. */
257 code
= MATRIX_SCAN_CODE(fn_state
? PPKB_ROWS
+ row
: row
,
259 input_event(ppkb
->input
, EV_MSC
, MSC_SCAN
, code
);
260 input_report_key(ppkb
->input
, keymap
[code
], value
);
261 if (keymap
[code
] == KEY_FN
)
262 ppkb
->fn_pressed
= value
;
265 input_sync(ppkb
->input
);
268 static irqreturn_t
ppkb_irq_thread(int irq
, void *data
)
270 struct i2c_client
*client
= data
;
277 static int ppkb_set_scan(struct i2c_client
*client
, bool enable
)
279 struct device
*dev
= &client
->dev
;
282 ret
= i2c_smbus_read_byte_data(client
, PPKB_SYS_CONFIG
);
284 dev_err(dev
, "Failed to read config: %d\n", ret
);
289 val
= ret
& ~PPKB_SYS_CONFIG_DISABLE_SCAN
;
291 val
= ret
| PPKB_SYS_CONFIG_DISABLE_SCAN
;
293 ret
= i2c_smbus_write_byte_data(client
, PPKB_SYS_CONFIG
, val
);
295 dev_err(dev
, "Failed to write config: %d\n", ret
);
302 static int ppkb_open(struct input_dev
*input
)
304 struct i2c_client
*client
= input_get_drvdata(input
);
307 error
= ppkb_set_scan(client
, true);
314 static void ppkb_close(struct input_dev
*input
)
316 struct i2c_client
*client
= input_get_drvdata(input
);
318 ppkb_set_scan(client
, false);
321 static int ppkb_probe(struct i2c_client
*client
)
323 struct device
*dev
= &client
->dev
;
324 unsigned int phys_rows
, phys_cols
;
325 struct pinephone_keyboard
*ppkb
;
326 u8 info
[PPKB_MATRIX_SIZE
+ 1];
327 struct device_node
*i2c_bus
;
331 error
= devm_regulator_get_enable(dev
, "vbat");
333 dev_err(dev
, "Failed to get VBAT supply: %d\n", error
);
337 ret
= i2c_smbus_read_i2c_block_data(client
, 0, sizeof(info
), info
);
338 if (ret
!= sizeof(info
)) {
339 error
= ret
< 0 ? ret
: -EIO
;
340 dev_err(dev
, "Failed to read device ID: %d\n", error
);
344 if (info
[PPKB_DEVICE_ID_HI
] != PPKB_DEVICE_ID_HI_VALUE
||
345 info
[PPKB_DEVICE_ID_LO
] != PPKB_DEVICE_ID_LO_VALUE
) {
346 dev_warn(dev
, "Unexpected device ID: %#02x %#02x\n",
347 info
[PPKB_DEVICE_ID_HI
], info
[PPKB_DEVICE_ID_LO
]);
351 dev_info(dev
, "Found firmware version %d.%d features %#x\n",
352 info
[PPKB_FW_REVISION
] >> 4,
353 info
[PPKB_FW_REVISION
] & 0xf,
354 info
[PPKB_FW_FEATURES
]);
356 phys_rows
= info
[PPKB_MATRIX_SIZE
] & 0xf;
357 phys_cols
= info
[PPKB_MATRIX_SIZE
] >> 4;
358 if (phys_rows
!= PPKB_ROWS
|| phys_cols
!= PPKB_COLS
) {
359 dev_err(dev
, "Unexpected keyboard size %ux%u\n",
360 phys_rows
, phys_cols
);
364 /* Disable scan by default to save power. */
365 error
= ppkb_set_scan(client
, false);
369 ppkb
= devm_kzalloc(dev
, sizeof(*ppkb
), GFP_KERNEL
);
373 i2c_set_clientdata(client
, ppkb
);
375 i2c_bus
= of_get_child_by_name(dev
->of_node
, "i2c");
377 ppkb
->adapter
.owner
= THIS_MODULE
;
378 ppkb
->adapter
.algo
= &ppkb_adap_algo
;
379 ppkb
->adapter
.algo_data
= client
;
380 ppkb
->adapter
.dev
.parent
= dev
;
381 ppkb
->adapter
.dev
.of_node
= i2c_bus
;
382 strscpy(ppkb
->adapter
.name
, DRV_NAME
, sizeof(ppkb
->adapter
.name
));
384 error
= devm_i2c_add_adapter(dev
, &ppkb
->adapter
);
386 dev_err(dev
, "Failed to add I2C adapter: %d\n", error
);
391 crc8_populate_msb(ppkb
->crc_table
, PPKB_CRC8_POLYNOMIAL
);
393 ppkb
->input
= devm_input_allocate_device(dev
);
397 input_set_drvdata(ppkb
->input
, client
);
399 ppkb
->input
->name
= "PinePhone Keyboard";
400 ppkb
->input
->phys
= DRV_NAME
"/input0";
401 ppkb
->input
->id
.bustype
= BUS_I2C
;
402 ppkb
->input
->open
= ppkb_open
;
403 ppkb
->input
->close
= ppkb_close
;
405 input_set_capability(ppkb
->input
, EV_MSC
, MSC_SCAN
);
406 __set_bit(EV_REP
, ppkb
->input
->evbit
);
408 error
= matrix_keypad_build_keymap(&ppkb_keymap_data
, NULL
,
409 2 * PPKB_ROWS
, PPKB_COLS
, NULL
,
412 dev_err(dev
, "Failed to build keymap: %d\n", error
);
416 error
= input_register_device(ppkb
->input
);
418 dev_err(dev
, "Failed to register input: %d\n", error
);
422 error
= devm_request_threaded_irq(dev
, client
->irq
,
423 NULL
, ppkb_irq_thread
,
424 IRQF_ONESHOT
, client
->name
, client
);
426 dev_err(dev
, "Failed to request IRQ: %d\n", error
);
433 static const struct of_device_id ppkb_of_match
[] = {
434 { .compatible
= "pine64,pinephone-keyboard" },
437 MODULE_DEVICE_TABLE(of
, ppkb_of_match
);
439 static struct i2c_driver ppkb_driver
= {
443 .of_match_table
= ppkb_of_match
,
446 module_i2c_driver(ppkb_driver
);
448 MODULE_AUTHOR("Samuel Holland <samuel@sholland.org>");
449 MODULE_DESCRIPTION("Pine64 PinePhone keyboard driver");
450 MODULE_LICENSE("GPL");