xref: /freebsd/sys/dev/atopcase/atopcase_var.h (revision ddfc6f84f24215b418af19260e9156219f6df03e)
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