1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
|
/* $NetBSD: ssdfbvar.h,v 1.10 2021/08/05 22:31:20 tnn Exp $ */
/*
* Copyright (c) 2019 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Tobias Nygren.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* cfdata attachment flags
*/
#define SSDFB_ATTACH_FLAG_PRODUCT_MASK 0x000000ff
#define SSDFB_ATTACH_FLAG_UPSIDEDOWN 0x00000100
#define SSDFB_ATTACH_FLAG_INVERSE 0x00000200
#define SSDFB_ATTACH_FLAG_CONSOLE 0x00000400
#define SSDFB_ATTACH_FLAG_MPSAFE 0x00000800
/*
* Fundamental commands
* SSD1306 Rev 1.1 p.28
* SH1106 Rev 0.1 p.19,20,22
*/
#define SSDFB_CMD_SET_CONTRAST_CONTROL 0x81
#define SSDFB_CMD_ENTIRE_DISPLAY_OFF 0xa4
#define SSDFB_CMD_ENTIRE_DISPLAY_ON 0xa5
#define SSDFB_CMD_SET_NORMAL_DISPLAY 0xa6
#define SSDFB_CMD_SET_INVERSE_DISPLAY 0xa7
#define SSDFB_CMD_SET_DISPLAY_OFF 0xae
#define SSDFB_CMD_SET_DISPLAY_ON 0xaf
/*
* Scrolling commands; SSD1306 Rev 1.1 p. 28
*/
#define SSDFB_CMD_VERTICAL_AND_RIGHT_SCROLL 0x29
#define SSDFB_CMD_VERTICAL_AND_LEFT_SCROLL 0x2a
#define SSDFB_CMD_DEACTIVATE_SCROLL 0x2e
#define SSDFB_CMD_ACTIVATE_SCROLL 0x2f
#define SSDFB_CMD_SET_VERTICAL_SCROLL_AREA 0xa3
/*
* Addressing commands
* SSD1306 Rev 1.1 p.30
* SH1106 Rev 0.1 p.18,22
*/
#define SSDFB_CMD_SET_LOWER_COLUMN_START_ADDRESS_BASE 0x00
#define SSDFB_CMD_SET_LOWER_COLUMN_START_ADDRESS_MAX 0x0f
#define SSDFB_CMD_SET_HIGHER_COLUMN_START_ADDRESS_BASE 0x10
#define SSDFB_CMD_SET_HIGHER_COLUMN_START_ADDRESS_MAX 0x1f
#define SSD1306_CMD_SET_MEMORY_ADDRESSING_MODE 0x20
#define SSD1306_MEMORY_ADDRESSING_MODE_HORIZONTAL 0x00
#define SSD1306_MEMORY_ADDRESSING_MODE_VERTICAL 0x01
#define SSD1306_MEMORY_ADDRESSING_MODE_PAGE 0x02
#define SSD1306_CMD_SET_COLUMN_ADDRESS 0x21
#define SSD1306_CMD_SET_PAGE_ADDRESS 0x22
#define SSDFB_CMD_SET_PAGE_START_ADDRESS_BASE 0xb0
#define SSDFB_CMD_SET_PAGE_START_ADDRESS_MAX 0xb7
/*
* Resolution & hardware layout commands
* SSD1306 Rev 1.1 p.31
* SH1106 Rev 0.1 p.19,20,21,23
*/
#define SSDFB_CMD_SET_DISPLAY_START_LINE_BASE 0x40
#define SSDFB_CMD_SET_DISPLAY_START_LINE_MAX 0x7f
#define SSDFB_CMD_SET_SEGMENT_REMAP_NORMAL 0xa0
#define SSDFB_CMD_SET_SEGMENT_REMAP_REVERSE 0xa1
#define SSDFB_CMD_SET_MULTIPLEX_RATIO 0xa8
#define SSDFB_CMD_SET_COM_OUTPUT_DIRECTION_NORMAL 0xc0
#define SSDFB_CMD_SET_COM_OUTPUT_DIRECTION_REMAP 0xc8
#define SSDFB_CMD_SET_DISPLAY_OFFSET 0xd3
#define SSDFB_CMD_SET_COM_PINS_HARDWARE_CFG 0xda
#define SSDFB_COM_PINS_A1_MASK 0x02
#define SSDFB_COM_PINS_ALTERNATIVE_MASK 0x10
#define SSDFB_COM_PINS_REMAP_MASK 0x20
/*
* Timing & driving commands
* SSD1306 Rev 1.1 p.32
* SH1106 Rev 0.1 p.24,25,26
*/
#define SSDFB_CMD_SET_DISPLAY_CLOCK_RATIO 0xd5
#define SSDFB_DISPLAY_CLOCK_DIVIDER_MASK __BITS(3, 0)
#define SSDFB_DISPLAY_CLOCK_OSCILLATOR_MASK __BITS(7, 4)
#define SSDFB_CMD_SET_PRECHARGE_PERIOD 0xd9
#define SSDFB_PRECHARGE_MASK __BITS(3, 0)
#define SSDFB_DISCHARGE_MASK __BITS(7, 4)
#define SSDFB_CMD_SET_VCOMH_DESELECT_LEVEL 0xdb
#define SSD1306_VCOMH_DESELECT_LEVEL_0_65_VCC 0x00
#define SSD1306_VCOMH_DESELECT_LEVEL_0_77_VCC 0x20
#define SSD1306_VCOMH_DESELECT_LEVEL_0_83_VCC 0x30
#define SH1106_VCOMH_DESELECT_LEVEL_DEFAULT 0x35
/*
* Misc commands
* SSD1306 Rev 1.1 p.32
* SH1106 Rev 0.1 p.27,28
*/
#define SSDFB_CMD_NOP 0xe3
#define SH1106_CMD_READ_MODIFY_WRITE 0xe0
#define SH1106_CMD_READ_MODIFY_WRITE_CANCEL 0xee
/*
* Charge pump commands
* SSD1306 App Note Rev 0.4 p.3
* SH1106 V0.1 p.18
*/
#define SSD1306_CMD_SET_CHARGE_PUMP 0x8d
#define SSD1306_CHARGE_PUMP_ENABLE 0x14
#define SSD1306_CHARGE_PUMP_DISABE 0x10
#define SH1106_CMD_SET_CHARGE_PUMP_7V4 0x30
#define SH1106_CMD_SET_CHARGE_PUMP_8V0 0x31
#define SH1106_CMD_SET_CHARGE_PUMP_8V4 0x32
#define SH1106_CMD_SET_CHARGE_PUMP_9V0 0x33
/*
* DC-DC commands
* SH1106 V0.1 p.18
*/
#define SH1106_CMD_SET_DC_DC 0xad
#define SH1106_DC_DC_OFF 0x8a
#define SH1106_DC_DC_ON 0x8b
/*
* SSD1322 command set
*/
#define SSD1322_CMD_ENABLE_GRAY_SCALE_TABLE 0x00
#define SSD1322_CMD_SET_COLUMN_ADDRESS 0x15
#define SSD1322_CMD_WRITE_RAM 0x5c
#define SSD1322_CMD_READ_RAM 0x5d
#define SSD1322_CMD_SET_ROW_ADDRESS 0x75
#define SSD1322_CMD_SET_REMAP_AND_DUAL_COM_LINE_MODE 0xa0
#define SSD1322_CMD_SET_DISPLAY_START_LINE 0xa1
#define SSD1322_CMD_SET_DISPLAY_OFFSET 0xa2
#define SSD1322_CMD_ENTIRE_DISPLAY_OFF SSDFB_CMD_ENTIRE_DISPLAY_OFF
#define SSD1322_CMD_ENTIRE_DISPLAY_ON SSDFB_CMD_ENTIRE_DISPLAY_ON
#define SSD1322_CMD_NORMAL_DISPLAY SSDFB_CMD_SET_NORMAL_DISPLAY
#define SSD1322_CMD_INVERSE_DISPLAY SSDFB_CMD_SET_INVERSE_DISPLAY
#define SSD1322_CMD_SET_SLEEP_MODE_ON SSDFB_CMD_SET_DISPLAY_OFF
#define SSD1322_CMD_SET_SLEEP_MODE_OFF SSDFB_CMD_SET_DISPLAY_ON
#define SSD1322_CMD_ENABLE_PARTIAL_DISPLAY 0xa8
#define SSD1322_CMD_EXIT_PARTIAL_DISPLAY 0xa9
#define SSD1322_CMD_FUNCTION_SELECTION 0xab
#define SSD1322_FUNCTION_SELECTION_EXTERNAL_VDD 0
#define SSD1322_FUNCTION_SELECTION_INTERNAL_VDD __BIT(0)
#define SSD1322_CMD_SET_PHASE_LENGTH 0xb1
#define SSD1322_PHASE_LENGTH_PHASE_2_MASK __BITS(7, 4)
#define SSD1322_DEFAULT_PHASE_2 7
#define SSD1322_PHASE_LENGTH_PHASE_1_MASK __BITS(3, 0)
#define SSD1322_DEFAULT_PHASE_1 4
#define SSD1322_CMD_SET_FRONT_CLOCK_DIVIDER 0xb3
#define SSD1322_FREQUENCY_MASK __BITS(7, 4)
#define SSD1322_DEFAULT_FREQUENCY 5
#define SSD1322_DIVIDER_MASK __BITS(3, 0)
#define SSD1322_DEFAULT_DIVIDER 0
#define SSD1322_CMD_DISPLAY_ENHANCEMENT_A 0xb4
#define SSD1322_DISPLAY_ENHANCEMENT_A_MAGIC1 0xa2
#define SSD1322_DISPLAY_ENHANCEMENT_A_MAGIC2 0xb5
#define SSD1322_CMD_SET_GPIO 0xb5
#define SSD1322_GPIO0_DISABLED 0
#define SSD1322_GPIO0_TRISTATE __BIT(0)
#define SSD1322_GPIO0_LOW __BIT(1)
#define SSD1322_GPIO0_HIGH __BITS(1, 0)
#define SSD1322_GPIO1_DISABLED 0
#define SSD1322_GPIO1_TRISTATE __BIT(2)
#define SSD1322_GPIO1_LOW __BIT(3)
#define SSD1322_GPIO1_HIGH __BITS(3, 2)
#define SSD1322_CMD_SET_SECOND_PRECHARGE_PERIOD 0xb6
#define SSD1322_DEFAULT_SECOND_PRECHARGE_PERIOD 8
#define SSD1322_CMD_SET_GRAY_SCALE_TABLE 0xb8
#define SSD1322_CMD_SET_DEFAULT_GRAY_SCALE_TABLE 0xb9
#define SSD1322_CMD_SET_PRE_CHARGE_VOLTAGE_LEVEL 0xbb
#define SSD1322_DEFAULT_PRE_CHARGE_VOLTAGE_LEVEL 0x17
#define SSD1322_CMD_SET_VCOMH 0xbe
#define SSD1322_DEFAULT_VCOMH 0x04
#define SSD1322_CMD_SET_CONTRAST_CURRENT 0xc1
#define SSD1322_DEFAULT_CONTRAST_CURRENT 0x7f
#define SSD1322_CMD_MASTER_CONTRAST_CURRENT_CONTROL 0xc7
#define SSD1322_DEFAULT_MASTER_CONTRAST_CURRENT_CONTROL 0xf
#define SSD1322_CMD_SET_MULTIPLEX_RATIO 0xca
#define SSD1322_CMD_DISPLAY_ENHANCEMENT_B 0xd1
#define SSD1322_DISPLAY_ENHANCEMENT_B_MAGIC1 0xa2
#define SSD1322_DISPLAY_ENHANCEMENT_B_MAGIC2 0x20
#define SSD1322_CMD_SET_COMMAND_LOCK 0xfd
#define SSD1322_COMMAND_UNLOCK_MAGIC 0x12
#define SSD1322_COMMAND_LOCK_MAGIC 0x16
/* undocumented on this chip, but works in practice */
#define SSD1322_CMD_NOP SSDFB_CMD_NOP
/*
* SSD1353 command set
*/
#define SSD1353_CMD_SET_COLUMN_ADDRESS SSD1322_CMD_SET_COLUMN_ADDRESS
#define SSD1353_CMD_DRAW_LINE 0x21
#define SSD1353_CMD_DRAW_RECTANGLE 0x22
#define SSD1353_CMD_COPY 0x23
#define SSD1353_CMD_DIM 0x24
#define SSD1353_CMD_CLEAR_WINDOW 0x25
#define SSD1353_CMD_FILL_ENABLE 0x26
#define SSD1353_CMD_SCROLLING_SETUP 0x27
#define SSD1353_CMD_DEACTIVATE_SCROLL SSDFB_CMD_DEACTIVATE_SCROLL
#define SSD1353_CMD_ACTIVATE_SCROLL SSDFB_CMD_ACTIVATE_SCROLL
#define SSD1353_CMD_WRITE_RAM SSD1322_CMD_WRITE_RAM
#define SD1353_CMD_READ_RAM SSD1322_CMD_READ_RAM
#define SSD1353_CMD_SET_ROW_ADDRESS SSD1322_CMD_SET_ROW_ADDRESS
#define SSD1353_CMD_SET_CONTRAST_CONTROL_A 0x81
#define SSD1353_CMD_SET_CONTRAST_CONTROL_B 0x82
#define SSD1353_CMD_SET_CONTRAST_CONTROL_C 0x83
#define SSD1353_DEFAULT_CONTRAST_CONTROL 128
#define SSD1353_CMD_MASTER_CURRENT_CONTROL 0x87
#define SSD1353_DEFAULT_MASTER_CURRENT_ATTENUATION 15
#define SSD1353_CMD_SET_SECOND_PRECHARGE_SPEED 0x8a
#define SSD1353_DEFAULT_SECOND_PRECHARGE_SPEED 2
#define SSD1353_CMD_REMAP_COLOR_DEPTH 0xa0
#define SSD1353_REMAP_NO_INCREMENT __BIT(0)
#define SSD1353_REMAP_SEG_DIRECTION __BIT(1)
#define SSD1353_REMAP_RGB __BIT(2)
#define SSD1353_REMAP_LR __BIT(3)
#define SSD1353_REMAP_COM_DIRECTION __BIT(4)
#define SSD1353_REMAP_SPLIT_ODD_EVEN __BIT(5)
#define SSD1353_REMAP_PIXEL_FORMAT_MASK __BITS(7, 6)
#define SSD1353_CMD_SET_DISPLAY_START_LINE SSD1322_CMD_SET_DISPLAY_START_LINE
#define SSD1353_CMD_SET_DISPLAY_OFFSET SSD1322_CMD_SET_DISPLAY_OFFSET
#define SSD1353_CMD_SET_VERTICAL_SCROLL_AREA SSDFB_CMD_SET_VERTICAL_SCROLL_AREA
#define SSD1353_CMD_NORMAL_DISPLAY 0xa4
#define SSD1353_CMD_ENTIRE_DISPLAY_ON 0xa5
#define SSD1353_CMD_ENTIRE_DISPLAY_OFF 0xa6
#define SSD1353_CMD_INVERSE_DISPLAY SSDFB_CMD_SET_INVERSE_DISPLAY
#define SSD1353_CMD_SET_MULTIPLEX_RATIO SSDFB_CMD_SET_MULTIPLEX_RATIO
#define SSD1353_CMD_DIM_MODE_SETTING 0xab
#define SSD1353_CMD_SET_DISPLAY_ON_DIM 0xac
#define SSD1353_CMD_SET_DISPLAY_OFF SSDFB_CMD_SET_DISPLAY_OFF
#define SSD1353_CMD_SET_DISPLAY_ON SSDFB_CMD_SET_DISPLAY_ON
#define SSD1353_CMD_SET_PHASE_LENGTH SSD1322_CMD_SET_PHASE_LENGTH
#define SSD1353_DEFAULT_PHASE_2 7
#define SSD1353_DEFAULT_PHASE_1 4
#define SSD1353_CMD_SET_FRONT_CLOCK_DIVIDER SSD1322_CMD_SET_FRONT_CLOCK_DIVIDER
#define SSD1353_DEFAULT_DIVIDER 0
#define SSD1353_DEFAULT_FREQUENCY 12
#define SSD1353_CMD_SET_SECOND_PRECHARGE_PERIOD 0xb4
#define SSD1353_DEFAULT_SECOND_PRECHARGE_PERIOD 7
#define SSD1353_CMD_SET_GRAY_SCALE_TABLE SSD1322_CMD_SET_GRAY_SCALE_TABLE
#define SSD1353_CMD_SET_DEFAULT_GRAY_SCALE_TABLE SSD1322_CMD_SET_DEFAULT_GRAY_SCALE_TABLE
#define SSD1353_CMD_SET_PRE_CHARGE_VOLTAGE_LEVEL SSD1322_CMD_SET_PRE_CHARGE_VOLTAGE_LEVEL
#define SSD1353_DEFAULT_PRE_CHARGE_VOLTAGE_LEVEL 0x3e
#define SSD1353_CMD_SET_VCOMH SSD1322_CMD_SET_VCOMH
#define SSD1353_DEFAULT_VCOMH 0x3c
#define SSD1353_CMD_OTP_WRITE 0xc0
#define SSD1353_CMD_RESET 0xe2
#define SSD1353_CMD_NOP SSDFB_CMD_NOP
#define SSD1353_CMD_SET_COMMAND_LOCK SSD1322_CMD_SET_COMMAND_LOCK
#define SSD1353_COMMAND_UNLOCK_MAGIC SSD1322_COMMAND_UNLOCK_MAGIC
#define SSD1353_COMMAND_LOCK_MAGIC SSD1353_COMMAND_LOCK_MAGIC
struct ssdfb_softc;
typedef enum {
SSDFB_CONTROLLER_UNKNOWN=0,
SSDFB_CONTROLLER_SSD1306=1,
SSDFB_CONTROLLER_SH1106=2,
SSDFB_CONTROLLER_SSD1322=3,
SSDFB_CONTROLLER_SSD1353=4,
} ssdfb_controller_id_t;
typedef enum {
SSDFB_PRODUCT_UNKNOWN=0,
SSDFB_PRODUCT_SSD1306_GENERIC=1,
SSDFB_PRODUCT_SH1106_GENERIC=2,
SSDFB_PRODUCT_ADAFRUIT_931=3,
SSDFB_PRODUCT_ADAFRUIT_938=4,
SSDFB_PRODUCT_SSD1322_GENERIC=5,
SSDFB_PRODUCT_SSD1353_GENERIC=6,
SSDFB_PRODUCT_DEP_160128A_RGB=7,
} ssdfb_product_id_t;
#define SSDFB_I2C_DEFAULT_ADDR 0x3c
#define SSDFB_I2C_ALTERNATIVE_ADDR 0x3d
/* Co bit has different behaviour in SSD1306 and SH1106 */
#define SSDFB_I2C_CTRL_BYTE_CONTINUATION_MASK __BIT(7)
#define SSDFB_I2C_CTRL_BYTE_DATA_MASK __BIT(6)
union ssdfb_block {
uint8_t col[8];
uint64_t raw;
};
struct ssdfb_product {
ssdfb_product_id_t p_product_id;
ssdfb_controller_id_t p_controller_id;
const char *p_name;
int p_width;
int p_height;
int p_bits_per_pixel;
bool p_rgb;
int p_panel_shift;
uint8_t p_fosc;
uint8_t p_fosc_div;
uint8_t p_precharge;
uint8_t p_discharge;
uint8_t p_compin_cfg;
uint8_t p_vcomh_deselect_level;
uint8_t p_default_contrast;
uint8_t p_multiplex_ratio;
int (*p_init)(struct ssdfb_softc *);
int (*p_sync)(struct ssdfb_softc *, bool);
};
struct ssdfb_softc {
device_t sc_dev;
const struct ssdfb_product *sc_p;
/* wscons & rasops state */
u_int sc_mode;
int sc_fontcookie;
struct wsdisplay_font *sc_font;
struct wsscreen_descr sc_screen_descr;
const struct wsscreen_descr *sc_screens[1];
struct wsscreen_list sc_screenlist;
struct rasops_info sc_ri;
size_t sc_ri_bits_len;
struct wsdisplay_emulops sc_orig_riops;
int sc_nscreens;
device_t sc_wsdisplay;
bool sc_is_console;
bool sc_usepoll;
/* hardware state */
bool sc_upsidedown;
bool sc_inverse;
uint8_t sc_contrast;
bool sc_display_on;
union ssdfb_block *sc_gddram;
size_t sc_gddram_len;
/* damage tracking */
lwp_t *sc_thread;
kcondvar_t sc_cond;
kmutex_t sc_cond_mtx;
bool sc_detaching;
int sc_backoff;
bool sc_modified;
struct uvm_object *sc_uobj;
/* reference to bus-specific code */
void *sc_cookie;
int (*sc_cmd)(void *, uint8_t *, size_t, bool);
int (*sc_transfer_rect)(void *, uint8_t, uint8_t, uint8_t, uint8_t,
uint8_t *, size_t, bool);
};
void ssdfb_attach(struct ssdfb_softc *, int flags);
int ssdfb_detach(struct ssdfb_softc *);
|