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