/* $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 *);