1 /* $NetBSD: ssdfbvar.h,v 1.5 2019/11/02 14:18:36 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 #define SSDFB_ATTACH_FLAG_MPSAFE 0x00000800 40 41 /* 42 * Fundamental commands 43 * SSD1306 Rev 1.1 p.28 44 * SH1106 Rev 0.1 p.19,20,22 45 */ 46 #define SSDFB_CMD_SET_CONTRAST_CONTROL 0x81 47 #define SSDFB_CMD_ENTIRE_DISPLAY_OFF 0xa4 48 #define SSDFB_CMD_ENTIRE_DISPLAY_ON 0xa5 49 #define SSDFB_CMD_SET_NORMAL_DISPLAY 0xa6 50 #define SSDFB_CMD_SET_INVERSE_DISPLAY 0xa7 51 #define SSDFB_CMD_SET_DISPLAY_OFF 0xae 52 #define SSDFB_CMD_SET_DISPLAY_ON 0xaf 53 54 /* 55 * Scrolling commands; SSD1306 Rev 1.1 p. 28 56 */ 57 #define SSDFB_CMD_VERTICAL_AND_RIGHT_SCROLL 0x29 58 #define SSDFB_CMD_VERTICAL_AND_LEFT_SCROLL 0x2a 59 #define SSDFB_CMD_DEACTIVATE_SCROLL 0x2e 60 #define SSDFB_CMD_ACTIVATE_SCROLL 0x2f 61 #define SSDFB_CMD_SET_VERTICAL_SCROLL_AREA 0xa3 62 63 /* 64 * Addressing commands 65 * SSD1306 Rev 1.1 p.30 66 * SH1106 Rev 0.1 p.18,22 67 */ 68 #define SSDFB_CMD_SET_LOWER_COLUMN_START_ADDRESS_BASE 0x00 69 #define SSDFB_CMD_SET_LOWER_COLUMN_START_ADDRESS_MAX 0x0f 70 #define SSDFB_CMD_SET_HIGHER_COLUMN_START_ADDRESS_BASE 0x10 71 #define SSDFB_CMD_SET_HIGHER_COLUMN_START_ADDRESS_MAX 0x1f 72 #define SSD1306_CMD_SET_MEMORY_ADDRESSING_MODE 0x20 73 #define SSD1306_MEMORY_ADDRESSING_MODE_HORIZONTAL 0x00 74 #define SSD1306_MEMORY_ADDRESSING_MODE_VERTICAL 0x01 75 #define SSD1306_MEMORY_ADDRESSING_MODE_PAGE 0x02 76 #define SSD1306_CMD_SET_COLUMN_ADDRESS 0x21 77 #define SSD1306_CMD_SET_PAGE_ADDRESS 0x22 78 #define SSDFB_CMD_SET_PAGE_START_ADDRESS_BASE 0xb0 79 #define SSDFB_CMD_SET_PAGE_START_ADDRESS_MAX 0xb7 80 81 /* 82 * Resolution & hardware layout commands 83 * SSD1306 Rev 1.1 p.31 84 * SH1106 Rev 0.1 p.19,20,21,23 85 */ 86 #define SSDFB_CMD_SET_DISPLAY_START_LINE_BASE 0x40 87 #define SSDFB_CMD_SET_DISPLAY_START_LINE_MAX 0x7f 88 #define SSDFB_CMD_SET_SEGMENT_REMAP_NORMAL 0xa0 89 #define SSDFB_CMD_SET_SEGMENT_REMAP_REVERSE 0xa1 90 #define SSDFB_CMD_SET_MULTIPLEX_RATIO 0xa8 91 #define SSDFB_CMD_SET_COM_OUTPUT_DIRECTION_NORMAL 0xc0 92 #define SSDFB_CMD_SET_COM_OUTPUT_DIRECTION_REMAP 0xc8 93 #define SSDFB_CMD_SET_DISPLAY_OFFSET 0xd3 94 #define SSDFB_CMD_SET_COM_PINS_HARDWARE_CFG 0xda 95 #define SSDFB_COM_PINS_A1_MASK 0x02 96 #define SSDFB_COM_PINS_ALTERNATIVE_MASK 0x10 97 #define SSDFB_COM_PINS_REMAP_MASK 0x20 98 99 /* 100 * Timing & driving commands 101 * SSD1306 Rev 1.1 p.32 102 * SH1106 Rev 0.1 p.24,25,26 103 */ 104 #define SSDFB_CMD_SET_DISPLAY_CLOCK_RATIO 0xd5 105 #define SSDFB_DISPLAY_CLOCK_DIVIDER_MASK __BITS(3, 0) 106 #define SSDFB_DISPLAY_CLOCK_OSCILLATOR_MASK __BITS(7, 4) 107 #define SSDFB_CMD_SET_PRECHARGE_PERIOD 0xd9 108 #define SSDFB_PRECHARGE_MASK __BITS(3, 0) 109 #define SSDFB_DISCHARGE_MASK __BITS(7, 4) 110 #define SSDFB_CMD_SET_VCOMH_DESELECT_LEVEL 0xdb 111 #define SSD1306_VCOMH_DESELECT_LEVEL_0_65_VCC 0x00 112 #define SSD1306_VCOMH_DESELECT_LEVEL_0_77_VCC 0x20 113 #define SSD1306_VCOMH_DESELECT_LEVEL_0_83_VCC 0x30 114 #define SH1106_VCOMH_DESELECT_LEVEL_DEFAULT 0x35 115 116 /* 117 * Misc commands 118 * SSD1306 Rev 1.1 p.32 119 * SH1106 Rev 0.1 p.27,28 120 */ 121 #define SSDFB_CMD_NOP 0xe3 122 #define SH1106_CMD_READ_MODIFY_WRITE 0xe0 123 #define SH1106_CMD_READ_MODIFY_WRITE_CANCEL 0xee 124 125 /* 126 * Charge pump commands 127 * SSD1306 App Note Rev 0.4 p.3 128 * SH1106 V0.1 p.18 129 */ 130 #define SSD1306_CMD_SET_CHARGE_PUMP 0x8d 131 #define SSD1306_CHARGE_PUMP_ENABLE 0x14 132 #define SSD1306_CHARGE_PUMP_DISABE 0x10 133 #define SH1106_CMD_SET_CHARGE_PUMP_7V4 0x30 134 #define SH1106_CMD_SET_CHARGE_PUMP_8V0 0x31 135 #define SH1106_CMD_SET_CHARGE_PUMP_8V4 0x32 136 #define SH1106_CMD_SET_CHARGE_PUMP_9V0 0x33 137 138 /* 139 * DC-DC commands 140 * SH1106 V0.1 p.18 141 */ 142 #define SH1106_CMD_SET_DC_DC 0xad 143 #define SH1106_DC_DC_OFF 0x8a 144 #define SH1106_DC_DC_ON 0x8b 145 146 /* 147 * SSD1322 command set 148 */ 149 #define SSD1322_CMD_ENABLE_GRAY_SCALE_TABLE 0x00 150 #define SSD1322_CMD_SET_COLUMN_ADDRESS 0x15 151 #define SSD1322_CMD_WRITE_RAM 0x5c 152 #define SSD1322_CMD_READ_RAM 0x5d 153 #define SSD1322_CMD_SET_ROW_ADDRESS 0x75 154 #define SSD1322_CMD_SET_REMAP_AND_DUAL_COM_LINE_MODE 0xa0 155 #define SSD1322_CMD_SET_DISPLAY_START_LINE 0xa1 156 #define SSD1322_CMD_SET_DISPLAY_OFFSET 0xa2 157 158 /* These are the same as SSDFB generic commands */ 159 #define SSD1322_CMD_ENTIRE_DISPLAY_OFF 0xa4 160 #define SSD1322_CMD_ENTIRE_DISPLAY_ON 0xa5 161 #define SSD1322_CMD_NORMAL_DISPLAY 0xa6 162 #define SSD1322_CMD_INVERSE_DISPLAY 0xa7 163 #define SSD1322_CMD_SET_SLEEP_MODE_ON 0xae 164 #define SSD1322_CMD_SET_SLEEP_MODE_OFF 0xaf 165 166 #define SSD1322_CMD_ENABLE_PARTIAL_DISPLAY 0xa8 167 #define SSD1322_CMD_EXIT_PARTIAL_DISPLAY 0xa9 168 #define SSD1322_CMD_FUNCTION_SELECTION 0xab 169 #define SSD1322_FUNCTION_SELECTION_EXTERNAL_VDD 0 170 #define SSD1322_FUNCTION_SELECTION_INTERNAL_VDD __BIT(0) 171 #define SSD1322_CMD_SET_PHASE_LENGTH 0xb1 172 #define SSD1322_PHASE_LENGTH_PHASE_2_MASK __BITS(7, 4) 173 #define SSD1322_DEFAULT_PHASE_2 7 174 #define SSD1322_PHASE_LENGTH_PHASE_1_MASK __BITS(3, 0) 175 #define SSD1322_DEFAULT_PHASE_1 4 176 #define SSD1322_CMD_SET_FRONT_CLOCK_DIVIDER 0xb3 177 #define SSD1322_FREQUENCY_MASK __BITS(7, 4) 178 #define SSD1322_DEFAULT_FREQUENCY 5 179 #define SSD1322_DIVIDER_MASK __BITS(3, 0) 180 #define SSD1322_DEFAULT_DIVIDER 0 181 #define SSD1322_CMD_DISPLAY_ENHANCEMENT_A 0xb4 182 #define SSD1322_DISPLAY_ENHANCEMENT_A_MAGIC1 0xa2 183 #define SSD1322_DISPLAY_ENHANCEMENT_A_MAGIC2 0xb5 184 #define SSD1322_CMD_SET_GPIO 0xb5 185 #define SSD1322_GPIO0_DISABLED 0 186 #define SSD1322_GPIO0_TRISTATE __BIT(0) 187 #define SSD1322_GPIO0_LOW __BIT(1) 188 #define SSD1322_GPIO0_HIGH __BITS(1, 0) 189 #define SSD1322_GPIO1_DISABLED 0 190 #define SSD1322_GPIO1_TRISTATE __BIT(2) 191 #define SSD1322_GPIO1_LOW __BIT(3) 192 #define SSD1322_GPIO1_HIGH __BITS(3, 2) 193 #define SSD1322_CMD_SET_SECOND_PRECHARGE_PERIOD 0xb6 194 #define SSD1322_DEFAULT_SECOND_PRECHARGE 8 195 #define SSD1322_CMD_SET_GRAY_SCALE_TABLE 0xb8 196 #define SSD1322_CMD_SET_DEFAULT_GRAY_SCALE_TABLE 0xb9 197 #define SSD1322_CMD_SET_PRE_CHARGE_VOLTAGE_LEVEL 0xbb 198 #define SSD1322_DEFAULT_PRE_CHARGE_VOLTAGE_LEVEL 0x17 199 #define SSD1322_CMD_SET_VCOMH 0xbe 200 #define SSD1322_DEFAULT_VCOMH 0x04 201 #define SSD1322_CMD_SET_CONTRAST_CURRENT 0xc1 202 #define SSD1322_DEFAULT_CONTRAST_CURRENT 0x7f 203 #define SSD1322_CMD_MASTER_CONTRAST_CURRENT_CONTROL 0xc7 204 #define SSD1322_DEFAULT_MASTER_CONTRAST_CURRENT_CONTROL 0xf 205 #define SSD1322_CMD_SET_MUX_RATIO 0xca 206 #define SSD1322_CMD_DISPLAY_ENHANCEMENT_B 0xd1 207 #define SSD1322_DISPLAY_ENHANCEMENT_B_MAGIC1 0xa2 208 #define SSD1322_DISPLAY_ENHANCEMENT_B_MAGIC2 0x20 209 #define SSD1322_CMD_SET_COMMAND_LOCK 0xfd 210 #define SSD1322_COMMAND_UNLOCK_MAGIC 0x12 211 #define SSD1322_COMMAND_LOCK_MAGIC 0x16 212 213 struct ssdfb_softc; 214 215 typedef enum { 216 SSDFB_CONTROLLER_UNKNOWN=0, 217 SSDFB_CONTROLLER_SSD1306=1, 218 SSDFB_CONTROLLER_SH1106=2, 219 SSDFB_CONTROLLER_SSD1322=3, 220 } ssdfb_controller_id_t; 221 222 typedef enum { 223 SSDFB_PRODUCT_UNKNOWN=0, 224 SSDFB_PRODUCT_SSD1306_GENERIC=1, 225 SSDFB_PRODUCT_SH1106_GENERIC=2, 226 SSDFB_PRODUCT_ADAFRUIT_931=3, 227 SSDFB_PRODUCT_ADAFRUIT_938=4, 228 SSDFB_PRODUCT_SSD1322_GENERIC=5, 229 } ssdfb_product_id_t; 230 231 #define SSDFB_I2C_DEFAULT_ADDR 0x3c 232 #define SSDFB_I2C_ALTERNATIVE_ADDR 0x3d 233 234 /* Co bit has different behaviour in SSD1306 and SH1106 */ 235 #define SSDFB_I2C_CTRL_BYTE_CONTINUATION_MASK __BIT(7) 236 #define SSDFB_I2C_CTRL_BYTE_DATA_MASK __BIT(6) 237 238 union ssdfb_block { 239 uint8_t col[8]; 240 uint64_t raw; 241 }; 242 243 struct ssdfb_product { 244 ssdfb_product_id_t p_product_id; 245 ssdfb_controller_id_t p_controller_id; 246 const char *p_name; 247 int p_width; 248 int p_height; 249 int p_bits_per_pixel; 250 int p_panel_shift; 251 uint8_t p_fosc; 252 uint8_t p_fosc_div; 253 uint8_t p_precharge; 254 uint8_t p_discharge; 255 uint8_t p_compin_cfg; 256 uint8_t p_vcomh_deselect_level; 257 uint8_t p_default_contrast; 258 uint8_t p_multiplex_ratio; 259 int (*p_init)(struct ssdfb_softc *); 260 int (*p_sync)(struct ssdfb_softc *, bool); 261 }; 262 263 struct ssdfb_softc { 264 device_t sc_dev; 265 const struct ssdfb_product *sc_p; 266 267 /* wscons & rasops state */ 268 u_int sc_mode; 269 int sc_fontcookie; 270 struct wsdisplay_font *sc_font; 271 struct wsscreen_descr sc_screen_descr; 272 const struct wsscreen_descr *sc_screens[1]; 273 struct wsscreen_list sc_screenlist; 274 struct rasops_info sc_ri; 275 size_t sc_ri_bits_len; 276 struct wsdisplay_emulops sc_orig_riops; 277 int sc_nscreens; 278 device_t sc_wsdisplay; 279 bool sc_is_console; 280 bool sc_usepoll; 281 282 /* hardware state */ 283 bool sc_upsidedown; 284 bool sc_inverse; 285 uint8_t sc_contrast; 286 bool sc_display_on; 287 union ssdfb_block *sc_gddram; 288 size_t sc_gddram_len; 289 290 /* damage tracking */ 291 lwp_t *sc_thread; 292 kcondvar_t sc_cond; 293 kmutex_t sc_cond_mtx; 294 bool sc_detaching; 295 int sc_backoff; 296 bool sc_modified; 297 struct uvm_object *sc_uobj; 298 299 /* reference to bus-specific code */ 300 void *sc_cookie; 301 int (*sc_cmd)(void *, uint8_t *, size_t, bool); 302 int (*sc_transfer_rect)(void *, uint8_t, uint8_t, uint8_t, uint8_t, 303 uint8_t *, size_t, bool); 304 }; 305 306 void ssdfb_attach(struct ssdfb_softc *, int flags); 307 int ssdfb_detach(struct ssdfb_softc *); 308