ssdfbvar.h revision 1.7 1 /* $NetBSD: ssdfbvar.h,v 1.7 2021/08/02 14:00:48 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 __BITS(3, 0)
105 #define SSDFB_DISPLAY_CLOCK_OSCILLATOR_MASK __BITS(7, 4)
106 #define SSDFB_CMD_SET_PRECHARGE_PERIOD 0xd9
107 #define SSDFB_PRECHARGE_MASK __BITS(3, 0)
108 #define SSDFB_DISCHARGE_MASK __BITS(7, 4)
109 #define SSDFB_CMD_SET_VCOMH_DESELECT_LEVEL 0xdb
110 #define SSD1306_VCOMH_DESELECT_LEVEL_0_65_VCC 0x00
111 #define SSD1306_VCOMH_DESELECT_LEVEL_0_77_VCC 0x20
112 #define SSD1306_VCOMH_DESELECT_LEVEL_0_83_VCC 0x30
113 #define SH1106_VCOMH_DESELECT_LEVEL_DEFAULT 0x35
114
115 /*
116 * Misc commands
117 * SSD1306 Rev 1.1 p.32
118 * SH1106 Rev 0.1 p.27,28
119 */
120 #define SSDFB_CMD_NOP 0xe3
121 #define SH1106_CMD_READ_MODIFY_WRITE 0xe0
122 #define SH1106_CMD_READ_MODIFY_WRITE_CANCEL 0xee
123
124 /*
125 * Charge pump commands
126 * SSD1306 App Note Rev 0.4 p.3
127 * SH1106 V0.1 p.18
128 */
129 #define SSD1306_CMD_SET_CHARGE_PUMP 0x8d
130 #define SSD1306_CHARGE_PUMP_ENABLE 0x14
131 #define SSD1306_CHARGE_PUMP_DISABE 0x10
132 #define SH1106_CMD_SET_CHARGE_PUMP_7V4 0x30
133 #define SH1106_CMD_SET_CHARGE_PUMP_8V0 0x31
134 #define SH1106_CMD_SET_CHARGE_PUMP_8V4 0x32
135 #define SH1106_CMD_SET_CHARGE_PUMP_9V0 0x33
136
137 /*
138 * DC-DC commands
139 * SH1106 V0.1 p.18
140 */
141 #define SH1106_CMD_SET_DC_DC 0xad
142 #define SH1106_DC_DC_OFF 0x8a
143 #define SH1106_DC_DC_ON 0x8b
144
145 /*
146 * SSD1322 command set
147 */
148 #define SSD1322_CMD_ENABLE_GRAY_SCALE_TABLE 0x00
149 #define SSD1322_CMD_SET_COLUMN_ADDRESS 0x15
150 #define SSD1322_CMD_WRITE_RAM 0x5c
151 #define SSD1322_CMD_READ_RAM 0x5d
152 #define SSD1322_CMD_SET_ROW_ADDRESS 0x75
153 #define SSD1322_CMD_SET_REMAP_AND_DUAL_COM_LINE_MODE 0xa0
154 #define SSD1322_CMD_SET_DISPLAY_START_LINE 0xa1
155 #define SSD1322_CMD_SET_DISPLAY_OFFSET 0xa2
156
157 #define SSD1322_CMD_ENTIRE_DISPLAY_OFF SSDFB_CMD_ENTIRE_DISPLAY_OFF
158 #define SSD1322_CMD_ENTIRE_DISPLAY_ON SSDFB_CMD_ENTIRE_DISPLAY_ON
159 #define SSD1322_CMD_NORMAL_DISPLAY SSDFB_CMD_SET_NORMAL_DISPLAY
160 #define SSD1322_CMD_INVERSE_DISPLAY SSDFB_CMD_SET_INVERSE_DISPLAY
161 #define SSD1322_CMD_SET_SLEEP_MODE_ON SSDFB_CMD_SET_DISPLAY_OFF
162 #define SSD1322_CMD_SET_SLEEP_MODE_OFF SSDFB_CMD_SET_DISPLAY_ON
163
164 #define SSD1322_CMD_ENABLE_PARTIAL_DISPLAY 0xa8
165 #define SSD1322_CMD_EXIT_PARTIAL_DISPLAY 0xa9
166 #define SSD1322_CMD_FUNCTION_SELECTION 0xab
167 #define SSD1322_FUNCTION_SELECTION_EXTERNAL_VDD 0
168 #define SSD1322_FUNCTION_SELECTION_INTERNAL_VDD __BIT(0)
169 #define SSD1322_CMD_SET_PHASE_LENGTH 0xb1
170 #define SSD1322_PHASE_LENGTH_PHASE_2_MASK __BITS(7, 4)
171 #define SSD1322_DEFAULT_PHASE_2 7
172 #define SSD1322_PHASE_LENGTH_PHASE_1_MASK __BITS(3, 0)
173 #define SSD1322_DEFAULT_PHASE_1 4
174 #define SSD1322_CMD_SET_FRONT_CLOCK_DIVIDER 0xb3
175 #define SSD1322_FREQUENCY_MASK __BITS(7, 4)
176 #define SSD1322_DEFAULT_FREQUENCY 5
177 #define SSD1322_DIVIDER_MASK __BITS(3, 0)
178 #define SSD1322_DEFAULT_DIVIDER 0
179 #define SSD1322_CMD_DISPLAY_ENHANCEMENT_A 0xb4
180 #define SSD1322_DISPLAY_ENHANCEMENT_A_MAGIC1 0xa2
181 #define SSD1322_DISPLAY_ENHANCEMENT_A_MAGIC2 0xb5
182 #define SSD1322_CMD_SET_GPIO 0xb5
183 #define SSD1322_GPIO0_DISABLED 0
184 #define SSD1322_GPIO0_TRISTATE __BIT(0)
185 #define SSD1322_GPIO0_LOW __BIT(1)
186 #define SSD1322_GPIO0_HIGH __BITS(1, 0)
187 #define SSD1322_GPIO1_DISABLED 0
188 #define SSD1322_GPIO1_TRISTATE __BIT(2)
189 #define SSD1322_GPIO1_LOW __BIT(3)
190 #define SSD1322_GPIO1_HIGH __BITS(3, 2)
191 #define SSD1322_CMD_SET_SECOND_PRECHARGE_PERIOD 0xb6
192 #define SSD1322_DEFAULT_SECOND_PRECHARGE_PERIOD 8
193 #define SSD1322_CMD_SET_GRAY_SCALE_TABLE 0xb8
194 #define SSD1322_CMD_SET_DEFAULT_GRAY_SCALE_TABLE 0xb9
195 #define SSD1322_CMD_SET_PRE_CHARGE_VOLTAGE_LEVEL 0xbb
196 #define SSD1322_DEFAULT_PRE_CHARGE_VOLTAGE_LEVEL 0x17
197 #define SSD1322_CMD_SET_VCOMH 0xbe
198 #define SSD1322_DEFAULT_VCOMH 0x04
199 #define SSD1322_CMD_SET_CONTRAST_CURRENT 0xc1
200 #define SSD1322_DEFAULT_CONTRAST_CURRENT 0x7f
201 #define SSD1322_CMD_MASTER_CONTRAST_CURRENT_CONTROL 0xc7
202 #define SSD1322_DEFAULT_MASTER_CONTRAST_CURRENT_CONTROL 0xf
203 #define SSD1322_CMD_SET_MULTIPLEX_RATIO 0xca
204 #define SSD1322_CMD_DISPLAY_ENHANCEMENT_B 0xd1
205 #define SSD1322_DISPLAY_ENHANCEMENT_B_MAGIC1 0xa2
206 #define SSD1322_DISPLAY_ENHANCEMENT_B_MAGIC2 0x20
207 #define SSD1322_CMD_SET_COMMAND_LOCK 0xfd
208 #define SSD1322_COMMAND_UNLOCK_MAGIC 0x12
209 #define SSD1322_COMMAND_LOCK_MAGIC 0x16
210 /* undocumented on this chip, but works in practice */
211 #define SSD1322_CMD_NOP SSDFB_CMD_NOP
212
213 /*
214 * SSD1353 command set
215 */
216 #define SSD1353_CMD_SET_COLUMN_ADDRESS SSD1322_CMD_SET_COLUMN_ADDRESS
217 #define SSD1353_CMD_DRAW_LINE 0x21
218 #define SSD1353_CMD_DRAW_RECTANGLE 0x22
219 #define SSD1353_CMD_COPY 0x23
220 #define SSD1353_CMD_DIM 0x24
221 #define SSD1353_CMD_CLEAR_WINDOW 0x25
222 #define SSD1353_CMD_FILL_ENABLE 0x26
223 #define SSD1353_CMD_SCROLLING_SETUP 0x27
224 #define SSD1353_CMD_DEACTIVATE_SCROLL SSDFB_CMD_DEACTIVATE_SCROLL
225 #define SSD1353_CMD_ACTIVATE_SCROLL SSDFB_CMD_ACTIVATE_SCROLL
226 #define SSD1353_CMD_WRITE_RAM SSD1322_CMD_WRITE_RAM
227 #define SD1353_CMD_READ_RAM SSD1322_CMD_READ_RAM
228 #define SSD1353_CMD_SET_ROW_ADDRESS SSD1322_CMD_SET_ROW_ADDRESS
229 #define SSD1353_CMD_SET_CONTRAST_CONTROL_A 0x81
230 #define SSD1353_CMD_SET_CONTRAST_CONTROL_B 0x82
231 #define SSD1353_CMD_SET_CONTRAST_CONTROL_C 0x83
232 #define SSD1353_DEFAULT_CONTRAST_CONTROL 128
233 #define SSD1353_CMD_MASTER_CURRENT_CONTROL 0x87
234 #define SSD1353_DEFAULT_MASTER_CURRENT_ATTENUATION 15
235 #define SSD1353_CMD_SET_SECOND_PRECHARGE_SPEED 0x8a
236 #define SSD1353_DEFAULT_SECOND_PRECHARGE_SPEED 2
237 #define SSD1353_CMD_REMAP_COLOR_DEPTH 0xa0
238 #define SSD1353_CMD_SET_DISPLAY_START_LINE SSD1322_CMD_SET_DISPLAY_START_LINE
239 #define SSD1353_CMD_SET_DISPLAY_OFFSET SSD1322_CMD_SET_DISPLAY_OFFSET
240 #define SSD1353_CMD_SET_VERTICAL_SCROLL_AREA SSDFB_CMD_SET_VERTICAL_SCROLL_AREA
241 #define SSD1353_CMD_NORMAL_DISPLAY 0xa4
242 #define SSD1353_CMD_ENTIRE_DISPLAY_ON 0xa5
243 #define SSD1353_CMD_ENTIRE_DISPLAY_OFF 0xa6
244 #define SSD1353_CMD_INVERSE_DISPLAY SSDFB_CMD_SET_INVERSE_DISPLAY
245 #define SSD1353_CMD_SET_MULTIPLEX_RATIO SSDFB_CMD_SET_MULTIPLEX_RATIO
246 #define SSD1353_CMD_DIM_MODE_SETTING 0xab
247 #define SSD1353_CMD_SET_DISPLAY_ON_DIM 0xac
248 #define SSD1353_CMD_SET_DISPLAY_OFF SSDFB_CMD_SET_DISPLAY_OFF
249 #define SSD1353_CMD_SET_DISPLAY_ON SSDFB_CMD_SET_DISPLAY_ON
250 #define SSD1353_CMD_SET_PHASE_LENGTH SSD1322_CMD_SET_PHASE_LENGTH
251 #define SSD1353_DEFAULT_PHASE_2 7
252 #define SSD1353_DEFAULT_PHASE_1 4
253 #define SSD1353_CMD_SET_FRONT_CLOCK_DIVIDER SSD1322_CMD_SET_FRONT_CLOCK_DIVIDER
254 #define SSD1353_DEFAULT_DIVIDER 0
255 #define SSD1353_DEFAULT_FREQUENCY 12
256 #define SSD1353_CMD_SET_SECOND_PRECHARGE_PERIOD 0xb4
257 #define SSD1353_DEFAULT_SECOND_PRECHARGE_PERIOD 7
258 #define SSD1353_CMD_SET_GRAY_SCALE_TABLE SSD1322_CMD_SET_GRAY_SCALE_TABLE
259 #define SSD1353_CMD_SET_DEFAULT_GRAY_SCALE_TABLE SSD1322_CMD_SET_DEFAULT_GRAY_SCALE_TABLE
260 #define SSD1353_CMD_SET_PRE_CHARGE_VOLTAGE_LEVEL SSD1322_CMD_SET_PRE_CHARGE_VOLTAGE_LEVEL
261 #define SSD1353_DEFAULT_PRE_CHARGE_VOLTAGE_LEVEL 0x3e
262 #define SSD1353_CMD_SET_VCOMH SSD1322_CMD_SET_VCOMH
263 #define SSD1353_DEFAULT_VCOMH 0x3c
264 #define SSD1353_CMD_OTP_WRITE 0xc0
265 #define SSD1353_CMD_RESET 0xe2
266 #define SSD1353_CMD_NOP SSDFB_CMD_NOP
267 #define SSD1353_CMD_SET_COMMAND_LOCK SSD1322_CMD_SET_COMMAND_LOCK
268 #define SSD1353_COMMAND_UNLOCK_MAGIC SSD1322_COMMAND_UNLOCK_MAGIC
269 #define SSD1353_COMMAND_LOCK_MAGIC SSD1353_COMMAND_LOCK_MAGIC
270
271 struct ssdfb_softc;
272
273 typedef enum {
274 SSDFB_CONTROLLER_UNKNOWN=0,
275 SSDFB_CONTROLLER_SSD1306=1,
276 SSDFB_CONTROLLER_SH1106=2,
277 SSDFB_CONTROLLER_SSD1322=3,
278 } ssdfb_controller_id_t;
279
280 typedef enum {
281 SSDFB_PRODUCT_UNKNOWN=0,
282 SSDFB_PRODUCT_SSD1306_GENERIC=1,
283 SSDFB_PRODUCT_SH1106_GENERIC=2,
284 SSDFB_PRODUCT_ADAFRUIT_931=3,
285 SSDFB_PRODUCT_ADAFRUIT_938=4,
286 SSDFB_PRODUCT_SSD1322_GENERIC=5,
287 } ssdfb_product_id_t;
288
289 #define SSDFB_I2C_DEFAULT_ADDR 0x3c
290 #define SSDFB_I2C_ALTERNATIVE_ADDR 0x3d
291
292 /* Co bit has different behaviour in SSD1306 and SH1106 */
293 #define SSDFB_I2C_CTRL_BYTE_CONTINUATION_MASK __BIT(7)
294 #define SSDFB_I2C_CTRL_BYTE_DATA_MASK __BIT(6)
295
296 union ssdfb_block {
297 uint8_t col[8];
298 uint64_t raw;
299 };
300
301 struct ssdfb_product {
302 ssdfb_product_id_t p_product_id;
303 ssdfb_controller_id_t p_controller_id;
304 const char *p_name;
305 int p_width;
306 int p_height;
307 int p_bits_per_pixel;
308 int p_panel_shift;
309 uint8_t p_fosc;
310 uint8_t p_fosc_div;
311 uint8_t p_precharge;
312 uint8_t p_discharge;
313 uint8_t p_compin_cfg;
314 uint8_t p_vcomh_deselect_level;
315 uint8_t p_default_contrast;
316 uint8_t p_multiplex_ratio;
317 int (*p_init)(struct ssdfb_softc *);
318 int (*p_sync)(struct ssdfb_softc *, bool);
319 };
320
321 struct ssdfb_softc {
322 device_t sc_dev;
323 const struct ssdfb_product *sc_p;
324
325 /* wscons & rasops state */
326 u_int sc_mode;
327 int sc_fontcookie;
328 struct wsdisplay_font *sc_font;
329 struct wsscreen_descr sc_screen_descr;
330 const struct wsscreen_descr *sc_screens[1];
331 struct wsscreen_list sc_screenlist;
332 struct rasops_info sc_ri;
333 size_t sc_ri_bits_len;
334 struct wsdisplay_emulops sc_orig_riops;
335 int sc_nscreens;
336 device_t sc_wsdisplay;
337 bool sc_is_console;
338 bool sc_usepoll;
339
340 /* hardware state */
341 bool sc_upsidedown;
342 bool sc_inverse;
343 uint8_t sc_contrast;
344 bool sc_display_on;
345 union ssdfb_block *sc_gddram;
346 size_t sc_gddram_len;
347
348 /* damage tracking */
349 lwp_t *sc_thread;
350 kcondvar_t sc_cond;
351 kmutex_t sc_cond_mtx;
352 bool sc_detaching;
353 int sc_backoff;
354 bool sc_modified;
355 struct uvm_object *sc_uobj;
356
357 /* reference to bus-specific code */
358 void *sc_cookie;
359 int (*sc_cmd)(void *, uint8_t *, size_t, bool);
360 int (*sc_transfer_rect)(void *, uint8_t, uint8_t, uint8_t, uint8_t,
361 uint8_t *, size_t, bool);
362 };
363
364 void ssdfb_attach(struct ssdfb_softc *, int flags);
365 int ssdfb_detach(struct ssdfb_softc *);
366