Lines Matching +full:bootloader +full:- +full:key

1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2010-2012 by Bruno Prémont <bonbons@linux-vserver.org> *
11 #include <linux/hid-debug.h>
13 #include "hid-ids.h"
23 #include "hid-picolcd.h"
28 * The PicoLCD has an IR receiver header, a built-in keypad with 5 keys
29 * and header for 4x4 key matrix. The built-in keys are part of the matrix.
55 struct list_head *feature_report_list = &hdev->report_enum[dir].report_list; in picolcd_report()
59 if (report->id == id) in picolcd_report()
66 /* Submit a report and wait for a reply from device - if device fades away
79 if (data->status & PICOLCD_FAILED) in picolcd_send_and_wait()
85 init_completion(&work->ready); in picolcd_send_and_wait()
86 work->out_report = report; in picolcd_send_and_wait()
87 work->in_report = NULL; in picolcd_send_and_wait()
88 work->raw_size = 0; in picolcd_send_and_wait()
90 mutex_lock(&data->mutex); in picolcd_send_and_wait()
91 spin_lock_irqsave(&data->lock, flags); in picolcd_send_and_wait()
92 for (i = k = 0; i < report->maxfield; i++) in picolcd_send_and_wait()
93 for (j = 0; j < report->field[i]->report_count; j++) { in picolcd_send_and_wait()
94 hid_set_field(report->field[i], j, k < size ? raw_data[k] : 0); in picolcd_send_and_wait()
97 if (data->status & PICOLCD_FAILED) { in picolcd_send_and_wait()
101 data->pending = work; in picolcd_send_and_wait()
102 hid_hw_request(data->hdev, report, HID_REQ_SET_REPORT); in picolcd_send_and_wait()
103 spin_unlock_irqrestore(&data->lock, flags); in picolcd_send_and_wait()
104 wait_for_completion_interruptible_timeout(&work->ready, HZ*2); in picolcd_send_and_wait()
105 spin_lock_irqsave(&data->lock, flags); in picolcd_send_and_wait()
106 data->pending = NULL; in picolcd_send_and_wait()
108 spin_unlock_irqrestore(&data->lock, flags); in picolcd_send_and_wait()
109 mutex_unlock(&data->mutex); in picolcd_send_and_wait()
122 * 0x00 means no key and at most 2 keys may be pressed at same time in picolcd_raw_keypad()
131 for (j = 0; j < sizeof(data->pressed_keys); j++) in picolcd_raw_keypad()
132 if (data->pressed_keys[j] == raw_data[i]) in picolcd_raw_keypad()
134 for (j = 0; j < sizeof(data->pressed_keys); j++) in picolcd_raw_keypad()
135 if (data->pressed_keys[j] == 0) { in picolcd_raw_keypad()
136 data->pressed_keys[j] = raw_data[i]; in picolcd_raw_keypad()
139 input_event(data->input_keys, EV_MSC, MSC_SCAN, raw_data[i]); in picolcd_raw_keypad()
141 key_code = data->keycode[raw_data[i]]; in picolcd_raw_keypad()
145 dbg_hid(PICOLCD_NAME " got key press for %u:%d", in picolcd_raw_keypad()
147 input_report_key(data->input_keys, key_code, 1); in picolcd_raw_keypad()
149 input_sync(data->input_keys); in picolcd_raw_keypad()
155 for (j = 0; j < sizeof(data->pressed_keys); j++) { in picolcd_raw_keypad()
157 if (data->pressed_keys[j] == 0) in picolcd_raw_keypad()
160 if (data->pressed_keys[j] == raw_data[i]) in picolcd_raw_keypad()
162 input_event(data->input_keys, EV_MSC, MSC_SCAN, data->pressed_keys[j]); in picolcd_raw_keypad()
163 if (data->pressed_keys[j] < PICOLCD_KEYS) in picolcd_raw_keypad()
164 key_code = data->keycode[data->pressed_keys[j]]; in picolcd_raw_keypad()
168 dbg_hid(PICOLCD_NAME " got key release for %u:%d", in picolcd_raw_keypad()
169 data->pressed_keys[j], key_code); in picolcd_raw_keypad()
170 input_report_key(data->input_keys, key_code, 0); in picolcd_raw_keypad()
172 input_sync(data->input_keys); in picolcd_raw_keypad()
173 data->pressed_keys[j] = 0; in picolcd_raw_keypad()
187 return -ENODEV; in picolcd_check_version()
192 return -ENODEV; in picolcd_check_version()
195 if (verinfo->raw_size == 2) { in picolcd_check_version()
196 data->version[0] = verinfo->raw_data[1]; in picolcd_check_version()
197 data->version[1] = verinfo->raw_data[0]; in picolcd_check_version()
198 if (data->status & PICOLCD_BOOTLOADER) { in picolcd_check_version()
199 hid_info(hdev, "PicoLCD, bootloader version %d.%d\n", in picolcd_check_version()
200 verinfo->raw_data[1], verinfo->raw_data[0]); in picolcd_check_version()
203 verinfo->raw_data[1], verinfo->raw_data[0]); in picolcd_check_version()
207 ret = -EINVAL; in picolcd_check_version()
223 if (!data || !report || report->maxfield != 1) in picolcd_reset()
224 return -ENODEV; in picolcd_reset()
226 spin_lock_irqsave(&data->lock, flags); in picolcd_reset()
227 if (hdev->product == USB_DEVICE_ID_PICOLCD_BOOTLOADER) in picolcd_reset()
228 data->status |= PICOLCD_BOOTLOADER; in picolcd_reset()
231 hid_set_field(report->field[0], 0, 1); in picolcd_reset()
232 if (data->status & PICOLCD_FAILED) { in picolcd_reset()
233 spin_unlock_irqrestore(&data->lock, flags); in picolcd_reset()
234 return -ENODEV; in picolcd_reset()
237 spin_unlock_irqrestore(&data->lock, flags); in picolcd_reset()
258 if (data->status & PICOLCD_BOOTLOADER) in picolcd_operation_mode_show()
259 return sysfs_emit(buf, "[bootloader] lcd\n"); in picolcd_operation_mode_show()
261 return sysfs_emit(buf, "bootloader [lcd]\n"); in picolcd_operation_mode_show()
269 int timeout = data->opmode_delay; in picolcd_operation_mode_store()
273 if (data->status & PICOLCD_BOOTLOADER) in picolcd_operation_mode_store()
274 report = picolcd_out_report(REPORT_EXIT_FLASHER, data->hdev); in picolcd_operation_mode_store()
275 } else if (sysfs_streq(buf, "bootloader")) { in picolcd_operation_mode_store()
276 if (!(data->status & PICOLCD_BOOTLOADER)) in picolcd_operation_mode_store()
277 report = picolcd_out_report(REPORT_EXIT_KEYBOARD, data->hdev); in picolcd_operation_mode_store()
279 return -EINVAL; in picolcd_operation_mode_store()
282 if (!report || report->maxfield != 1) in picolcd_operation_mode_store()
283 return -EINVAL; in picolcd_operation_mode_store()
285 spin_lock_irqsave(&data->lock, flags); in picolcd_operation_mode_store()
286 hid_set_field(report->field[0], 0, timeout & 0xff); in picolcd_operation_mode_store()
287 hid_set_field(report->field[0], 1, (timeout >> 8) & 0xff); in picolcd_operation_mode_store()
288 hid_hw_request(data->hdev, report, HID_REQ_SET_REPORT); in picolcd_operation_mode_store()
289 spin_unlock_irqrestore(&data->lock, flags); in picolcd_operation_mode_store()
304 return sysfs_emit(buf, "%hu\n", data->opmode_delay); in picolcd_operation_mode_delay_show()
313 return -EINVAL; in picolcd_operation_mode_delay_store()
315 return -EINVAL; in picolcd_operation_mode_delay_store()
317 data->opmode_delay = u; in picolcd_operation_mode_delay_store()
338 size, report->id); in picolcd_raw_event()
342 if (report->id == REPORT_KEY_STATE) { in picolcd_raw_event()
343 if (data->input_keys) in picolcd_raw_event()
344 picolcd_raw_keypad(data, report, raw_data+1, size-1); in picolcd_raw_event()
345 } else if (report->id == REPORT_IR_DATA) { in picolcd_raw_event()
346 picolcd_raw_cir(data, report, raw_data+1, size-1); in picolcd_raw_event()
348 spin_lock_irqsave(&data->lock, flags); in picolcd_raw_event()
353 if (data->pending) { in picolcd_raw_event()
354 memcpy(data->pending->raw_data, raw_data+1, size-1); in picolcd_raw_event()
355 data->pending->raw_size = size-1; in picolcd_raw_event()
356 data->pending->in_report = report; in picolcd_raw_event()
357 complete(&data->pending->ready); in picolcd_raw_event()
359 spin_unlock_irqrestore(&data->lock, flags); in picolcd_raw_event()
410 struct hid_device *hdev = data->hdev; in picolcd_init_keys()
415 return -ENODEV; in picolcd_init_keys()
416 if (report->maxfield != 1 || report->field[0]->report_count != 2 || in picolcd_init_keys()
417 report->field[0]->report_size != 8) { in picolcd_init_keys()
419 return -EINVAL; in picolcd_init_keys()
425 return -ENOMEM; in picolcd_init_keys()
428 memcpy(data->keycode, def_keymap, sizeof(def_keymap)); in picolcd_init_keys()
429 idev->name = hdev->name; in picolcd_init_keys()
430 idev->phys = hdev->phys; in picolcd_init_keys()
431 idev->uniq = hdev->uniq; in picolcd_init_keys()
432 idev->id.bustype = hdev->bus; in picolcd_init_keys()
433 idev->id.vendor = hdev->vendor; in picolcd_init_keys()
434 idev->id.product = hdev->product; in picolcd_init_keys()
435 idev->id.version = hdev->version; in picolcd_init_keys()
436 idev->dev.parent = &hdev->dev; in picolcd_init_keys()
437 idev->keycode = &data->keycode; in picolcd_init_keys()
438 idev->keycodemax = PICOLCD_KEYS; in picolcd_init_keys()
439 idev->keycodesize = sizeof(data->keycode[0]); in picolcd_init_keys()
441 set_bit(EV_REP, idev->evbit); in picolcd_init_keys()
443 input_set_capability(idev, EV_KEY, data->keycode[i]); in picolcd_init_keys()
450 data->input_keys = idev; in picolcd_init_keys()
456 struct input_dev *idev = data->input_keys; in picolcd_exit_keys()
458 data->input_keys = NULL; in picolcd_exit_keys()
525 int error = -ENOMEM; in picolcd_probe()
536 return -ENOMEM; in picolcd_probe()
539 spin_lock_init(&data->lock); in picolcd_probe()
540 mutex_init(&data->mutex); in picolcd_probe()
541 data->hdev = hdev; in picolcd_probe()
542 data->opmode_delay = 5000; in picolcd_probe()
543 if (hdev->product == USB_DEVICE_ID_PICOLCD_BOOTLOADER) in picolcd_probe()
544 data->status |= PICOLCD_BOOTLOADER; in picolcd_probe()
562 hid_err(hdev, "failed to open input interrupt pipe for key and IR events\n"); in picolcd_probe()
566 error = device_create_file(&hdev->dev, &dev_attr_operation_mode_delay); in picolcd_probe()
572 error = device_create_file(&hdev->dev, &dev_attr_operation_mode); in picolcd_probe()
578 if (data->status & PICOLCD_BOOTLOADER) in picolcd_probe()
589 device_remove_file(&hdev->dev, &dev_attr_operation_mode); in picolcd_probe()
591 device_remove_file(&hdev->dev, &dev_attr_operation_mode_delay); in picolcd_probe()
607 spin_lock_irqsave(&data->lock, flags); in picolcd_remove()
608 data->status |= PICOLCD_FAILED; in picolcd_remove()
609 spin_unlock_irqrestore(&data->lock, flags); in picolcd_remove()
612 device_remove_file(&hdev->dev, &dev_attr_operation_mode); in picolcd_remove()
613 device_remove_file(&hdev->dev, &dev_attr_operation_mode_delay); in picolcd_remove()
618 spin_lock_irqsave(&data->lock, flags); in picolcd_remove()
619 if (data->pending) in picolcd_remove()
620 complete(&data->pending->ready); in picolcd_remove()
621 spin_unlock_irqrestore(&data->lock, flags); in picolcd_remove()
633 mutex_destroy(&data->mutex); in picolcd_remove()
646 .name = "hid-picolcd",