1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2021-2023 Val Packett <val@packett.cool> 5 * Copyright (c) 2023 Vladimir Kondratyev <wulf@FreeBSD.org> 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 #ifndef _ATOPCASE_VAR_H_ 30 #define _ATOPCASE_VAR_H_ 31 32 #include "opt_hid.h" 33 34 #include <sys/types.h> 35 #include <sys/bus.h> 36 #include <sys/taskqueue.h> 37 38 #include <contrib/dev/acpica/include/acpi.h> 39 #include <dev/acpica/acpivar.h> 40 41 #include <dev/backlight/backlight.h> 42 43 #include <dev/hid/hid.h> 44 45 struct atopcase_child { 46 device_t hidbus; 47 48 struct hid_device_info hw; 49 50 uint8_t device; 51 uint8_t name[80]; 52 53 uint8_t rdesc[ATOPCASE_MSG_SIZE]; 54 size_t rdesc_len; 55 56 hid_intr_t *intr_handler; 57 void *intr_ctx; 58 59 bool open; 60 }; 61 62 struct atopcase_softc { 63 device_t sc_dev; 64 65 ACPI_HANDLE sc_handle; 66 int sc_gpe_bit; 67 68 int sc_irq_rid; 69 struct resource *sc_irq_res; 70 void *sc_irq_ih; 71 volatile unsigned int sc_intr_cnt; 72 73 struct timeout_task sc_task; 74 struct taskqueue *sc_tq; 75 76 bool sc_booted; 77 bool sc_wait_for_status; 78 79 uint8_t sc_hid[HID_PNP_ID_SIZE]; 80 uint8_t sc_vendor[80]; 81 uint8_t sc_product[80]; 82 uint8_t sc_serial[80]; 83 uint16_t sc_vid; 84 uint16_t sc_pid; 85 uint16_t sc_ver; 86 87 /* 88 * Writes are complex and async (i.e. 2 responses arrive via interrupt) 89 * and cannot be interleaved (no new writes until responses arrive). 90 * they are serialized with sc_write_sx lock. 91 */ 92 struct sx sc_write_sx; 93 /* 94 * SPI transfers must be separated by a small pause. As they can be 95 * initiated by both interrupts and users, do ATOPCASE_SPI_PAUSE() 96 * after each transfer and serialize them with sc_sx or sc_mtx locks 97 * depending on interupt source (GPE or PIC). Still use sc_write_sx 98 * lock while polling. 99 */ 100 struct sx sc_sx; 101 struct mtx sc_mtx; 102 103 struct atopcase_child sc_kb; 104 struct atopcase_child sc_tp; 105 106 struct cdev *sc_backlight; 107 uint32_t sc_backlight_level; 108 109 uint16_t sc_msg_len; 110 uint8_t sc_msg[ATOPCASE_MSG_SIZE]; 111 struct atopcase_packet sc_buf; 112 struct atopcase_packet sc_junk; 113 }; 114 115 #ifdef HID_DEBUG 116 enum atopcase_log_level { 117 ATOPCASE_LLEVEL_DISABLED = 0, 118 ATOPCASE_LLEVEL_INFO, 119 ATOPCASE_LLEVEL_DEBUG, /* for troubleshooting */ 120 ATOPCASE_LLEVEL_TRACE, /* log every packet */ 121 }; 122 extern enum atopcase_log_level atopcase_debug; 123 #endif 124 125 int atopcase_receive_packet(struct atopcase_softc *); 126 int atopcase_init(struct atopcase_softc *); 127 int atopcase_destroy(struct atopcase_softc *sc); 128 int atopcase_intr(struct atopcase_softc *); 129 void atopcase_intr_setup(device_t, device_t, hid_intr_t, void *, 130 struct hid_rdesc_info *); 131 void atopcase_intr_unsetup(device_t, device_t); 132 int atopcase_intr_start(device_t, device_t); 133 int atopcase_intr_stop(device_t, device_t); 134 void atopcase_intr_poll(device_t, device_t); 135 int atopcase_get_rdesc(device_t, device_t, void *, hid_size_t); 136 int atopcase_set_report(device_t, device_t, const void *, hid_size_t, uint8_t, 137 uint8_t); 138 int atopcase_backlight_update_status(device_t, struct backlight_props *); 139 int atopcase_backlight_get_status(device_t, struct backlight_props *); 140 int atopcase_backlight_get_info(device_t, struct backlight_info *); 141 142 #endif /* _ATOPCASE_VAR_H_ */ 143