xref: /netbsd-src/sys/dev/ic/ssdfbvar.h (revision f3cfa6f6ce31685c6c4a758bc430e69eb99f50a4)
1 /* $NetBSD: ssdfbvar.h,v 1.2 2019/03/17 04:03:17 tnn Exp $ */
2 
3 /*
4  * Copyright (c) 2019 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Tobias Nygren.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 /*
33  * cfdata attachment flags
34  */
35 #define SSDFB_ATTACH_FLAG_PRODUCT_MASK		0x000000ff
36 #define SSDFB_ATTACH_FLAG_UPSIDEDOWN		0x00000100
37 #define SSDFB_ATTACH_FLAG_INVERSE		0x00000200
38 #define SSDFB_ATTACH_FLAG_CONSOLE		0x00000400
39 
40 /*
41  * Fundamental commands
42  * SSD1306 Rev 1.1 p.28
43  * SH1106 Rev 0.1 p.19,20,22
44  */
45 #define SSDFB_CMD_SET_CONTRAST_CONTROL		0x81
46 #define SSDFB_CMD_ENTIRE_DISPLAY_OFF		0xa4
47 #define SSDFB_CMD_ENTIRE_DISPLAY_ON		0xa5
48 #define SSDFB_CMD_SET_NORMAL_DISPLAY		0xa6
49 #define SSDFB_CMD_SET_INVERSE_DISPLAY		0xa7
50 #define SSDFB_CMD_SET_DISPLAY_OFF		0xae
51 #define SSDFB_CMD_SET_DISPLAY_ON		0xaf
52 
53 /*
54  * Scrolling commands; SSD1306 Rev 1.1 p. 28
55  */
56 #define SSDFB_CMD_VERTICAL_AND_RIGHT_SCROLL	0x29
57 #define SSDFB_CMD_VERTICAL_AND_LEFT_SCROLL	0x2a
58 #define SSDFB_CMD_DEACTIVATE_SCROLL		0x2e
59 #define SSDFB_CMD_ACTIVATE_SCROLL		0x2f
60 #define SSDFB_CMD_SET_VERTICAL_SCROLL_AREA	0xa3
61 
62 /*
63  * Addressing commands
64  * SSD1306 Rev 1.1 p.30
65  * SH1106 Rev 0.1 p.18,22
66  */
67 #define SSDFB_CMD_SET_LOWER_COLUMN_START_ADDRESS_BASE	0x00
68 #define SSDFB_CMD_SET_LOWER_COLUMN_START_ADDRESS_MAX	0x0f
69 #define SSDFB_CMD_SET_HIGHER_COLUMN_START_ADDRESS_BASE	0x10
70 #define SSDFB_CMD_SET_HIGHER_COLUMN_START_ADDRESS_MAX	0x1f
71 #define SSD1306_CMD_SET_MEMORY_ADDRESSING_MODE		0x20
72 	#define SSD1306_MEMORY_ADDRESSING_MODE_HORIZONTAL 0x00
73 	#define SSD1306_MEMORY_ADDRESSING_MODE_VERTICAL	0x01
74 	#define SSD1306_MEMORY_ADDRESSING_MODE_PAGE	0x02
75 #define SSD1306_CMD_SET_COLUMN_ADDRESS			0x21
76 #define SSD1306_CMD_SET_PAGE_ADDRESS			0x22
77 #define SSDFB_CMD_SET_PAGE_START_ADDRESS_BASE		0xb0
78 #define SSDFB_CMD_SET_PAGE_START_ADDRESS_MAX		0xb7
79 
80 /*
81  * Resolution & hardware layout commands
82  * SSD1306 Rev 1.1 p.31
83  * SH1106 Rev 0.1 p.19,20,21,23
84  */
85 #define SSDFB_CMD_SET_DISPLAY_START_LINE_BASE		0x40
86 #define SSDFB_CMD_SET_DISPLAY_START_LINE_MAX		0x7f
87 #define SSDFB_CMD_SET_SEGMENT_REMAP_NORMAL		0xa0
88 #define SSDFB_CMD_SET_SEGMENT_REMAP_REVERSE		0xa1
89 #define SSDFB_CMD_SET_MULTIPLEX_RATIO			0xa8
90 #define SSDFB_CMD_SET_COM_OUTPUT_DIRECTION_NORMAL	0xc0
91 #define SSDFB_CMD_SET_COM_OUTPUT_DIRECTION_REMAP	0xc8
92 #define SSDFB_CMD_SET_DISPLAY_OFFSET			0xd3
93 #define SSDFB_CMD_SET_COM_PINS_HARDWARE_CFG		0xda
94 	#define SSDFB_COM_PINS_A1_MASK			0x02
95 	#define SSDFB_COM_PINS_ALTERNATIVE_MASK		0x10
96 	#define SSDFB_COM_PINS_REMAP_MASK		0x20
97 
98 /*
99  * Timing & driving commands
100  * SSD1306 Rev 1.1 p.32
101  * SH1106 Rev 0.1 p.24,25,26
102  */
103 #define SSDFB_CMD_SET_DISPLAY_CLOCK_RATIO		0xd5
104 	#define SSDFB_DISPLAY_CLOCK_DIVIDER_MASK	0x0f
105 	#define SSDFB_DISPLAY_CLOCK_DIVIDER_SHIFT	0
106 	#define SSDFB_DISPLAY_CLOCK_OSCILLATOR_MASK	0xf0
107 	#define SSDFB_DISPLAY_CLOCK_OSCILLATOR_SHIFT	4
108 #define SSDFB_CMD_SET_PRECHARGE_PERIOD			0xd9
109 	#define SSDFB_PRECHARGE_MASK			0x0f
110 	#define SSDFB_PRECHARGE_SHIFT			0
111 	#define SSDFB_DISCHARGE_MASK			0xf0
112 	#define SSDFB_DISCHARGE_SHIFT			4
113 #define SSDFB_CMD_SET_VCOMH_DESELECT_LEVEL		0xdb
114 	#define SSD1306_VCOMH_DESELECT_LEVEL_0_65_VCC	0x00
115 	#define SSD1306_VCOMH_DESELECT_LEVEL_0_77_VCC	0x20
116 	#define SSD1306_VCOMH_DESELECT_LEVEL_0_83_VCC	0x30
117 	#define SH1106_VCOMH_DESELECT_LEVEL_DEFAULT	0x35
118 
119 /*
120  * Misc commands
121  * SSD1306 Rev 1.1 p.32
122  * SH1106 Rev 0.1 p.27,28
123  */
124 #define SSDFB_CMD_NOP					0xe3
125 #define SH1106_CMD_READ_MODIFY_WRITE			0xe0
126 #define SH1106_CMD_READ_MODIFY_WRITE_CANCEL		0xee
127 
128 /*
129  * Charge pump commands
130  * SSD1306 App Note Rev 0.4 p.3
131  * SH1106 V0.1 p.18
132  */
133 #define SSD1306_CMD_SET_CHARGE_PUMP			0x8d
134 	#define SSD1306_CHARGE_PUMP_ENABLE		0x14
135 	#define SSD1306_CHARGE_PUMP_DISABE		0x10
136 #define SH1106_CMD_SET_CHARGE_PUMP_7V4			0x30
137 #define SH1106_CMD_SET_CHARGE_PUMP_8V0			0x31
138 #define SH1106_CMD_SET_CHARGE_PUMP_8V4			0x32
139 #define SH1106_CMD_SET_CHARGE_PUMP_9V0			0x33
140 
141 /*
142  * DC-DC commands
143  * SH1106 V0.1 p.18
144  */
145 #define SH1106_CMD_SET_DC_DC				0xad
146 	#define SH1106_DC_DC_OFF			0x8a
147 	#define SH1106_DC_DC_ON				0x8b
148 
149 typedef enum {
150 	SSDFB_CONTROLLER_UNKNOWN=0,
151 	SSDFB_CONTROLLER_SSD1306=1,
152 	SSDFB_CONTROLLER_SH1106=2,
153 } ssdfb_controller_id_t;
154 
155 typedef enum {
156 	SSDFB_PRODUCT_UNKNOWN=0,
157 	SSDFB_PRODUCT_SSD1306_GENERIC=1,
158 	SSDFB_PRODUCT_SH1106_GENERIC=2,
159 	SSDFB_PRODUCT_ADAFRUIT_931=3,
160 	SSDFB_PRODUCT_ADAFRUIT_938=4,
161 } ssdfb_product_id_t;
162 
163 #define SSDFB_I2C_DEFAULT_ADDR		0x3c
164 #define SSDFB_I2C_ALTERNATIVE_ADDR	0x3d
165 
166 /* Co bit has different behaviour in SSD1306 and SH1106 */
167 #define SSDFB_I2C_CTRL_BYTE_CONTINUATION_MASK	__BIT(7)
168 #define SSDFB_I2C_CTRL_BYTE_DATA_MASK		__BIT(6)
169 
170 union ssdfb_block {
171 	uint8_t		col[8];
172 	uint64_t	raw;
173 };
174 
175 struct ssdfb_product {
176 	ssdfb_product_id_t		p_product_id;
177 	ssdfb_controller_id_t		p_controller_id;
178 	const char			*p_name;
179 	int				p_width;
180 	int				p_height;
181 	int				p_panel_shift;
182 	uint8_t				p_fosc;
183 	uint8_t				p_fosc_div;
184 	uint8_t				p_precharge;
185 	uint8_t				p_discharge;
186 	uint8_t				p_compin_cfg;
187 	uint8_t				p_vcomh_deselect_level;
188 	uint8_t				p_default_contrast;
189 	uint8_t				p_multiplex_ratio;
190 	uint8_t				p_chargepump_cmd;
191 	uint8_t				p_chargepump_arg;
192 };
193 
194 struct ssdfb_softc {
195 	device_t			sc_dev;
196 	const struct ssdfb_product	*sc_p;
197 
198 	/* wscons & rasops state */
199 	u_int				sc_mode;
200 	int				sc_fontcookie;
201 	struct wsdisplay_font		*sc_font;
202 	struct wsscreen_descr		sc_screen_descr;
203 	const struct wsscreen_descr	*sc_screens[1];
204 	struct wsscreen_list		sc_screenlist;
205 	struct rasops_info		sc_ri;
206 	size_t				sc_ri_bits_len;
207 	struct wsdisplay_emulops	sc_orig_riops;
208 	int				sc_nscreens;
209 	device_t			sc_wsdisplay;
210 	bool				sc_is_console;
211 	bool				sc_usepoll;
212 
213 	/* hardware state */
214 	bool				sc_upsidedown;
215 	bool				sc_inverse;
216 	uint8_t				sc_contrast;
217 	bool				sc_display_on;
218 	union ssdfb_block		*sc_gddram;
219 	size_t				sc_gddram_len;
220 
221 	/* damage tracking */
222 	lwp_t				*sc_thread;
223 	kcondvar_t			sc_cond;
224 	kmutex_t			sc_cond_mtx;
225 	bool				sc_detaching;
226 	int				sc_backoff;
227 	bool				sc_modified;
228 	struct uvm_object		*sc_uobj;
229 
230 	/* reference to bus-specific code */
231 	void	*sc_cookie;
232 	int	(*sc_cmd)(void *, uint8_t *, size_t, bool);
233 	int	(*sc_transfer_rect)(void *, uint8_t, uint8_t, uint8_t, uint8_t,
234 				    uint8_t *, size_t, bool);
235 };
236 
237 void	ssdfb_attach(struct ssdfb_softc *, int flags);
238 int	ssdfb_detach(struct ssdfb_softc *);
239