/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 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. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. */ #include #include #include /* base addresses */ #define QPNP_WLED_CTRL_BASE 0xd800 #define QPNP_WLED_SINK_BASE 0xd900 #define QPNP_WLED_IBB_BASE 0xdc00 #define QPNP_WLED_LAB_BASE 0xde00 /* ctrl registers */ #define QPNP_WLED_EN_REG(b) (b + 0x46) #define QPNP_WLED_FDBK_OP_REG(b) (b + 0x48) #define QPNP_WLED_VREF_REG(b) (b + 0x49) #define QPNP_WLED_BOOST_DUTY_REG(b) (b + 0x4B) #define QPNP_WLED_SWITCH_FREQ_REG(b) (b + 0x4C) #define QPNP_WLED_OVP_REG(b) (b + 0x4D) #define QPNP_WLED_ILIM_REG(b) (b + 0x4E) #define QPNP_WLED_EN_MASK 0x7F #define QPNP_WLED_EN_SHIFT 7 #define QPNP_WLED_FDBK_OP_MASK 0xF8 #define QPNP_WLED_VREF_MASK 0xF0 #define QPNP_WLED_VREF_STEP_MV 25 #define QPNP_WLED_VREF_MIN_MV 300 #define QPNP_WLED_VREF_MAX_MV 675 #define QPNP_WLED_DFLT_VREF_MV 350 #define QPNP_WLED_ILIM_MASK 0xF8 #define QPNP_WLED_ILIM_MIN_MA 105 #define QPNP_WLED_ILIM_MAX_MA 1980 #define QPNP_WLED_ILIM_STEP_MA 280 #define QPNP_WLED_DFLT_ILIM_MA 980 #define QPNP_WLED_ILIM_OVERWRITE 0x80 #define QPNP_WLED_BOOST_DUTY_MASK 0xFC #define QPNP_WLED_BOOST_DUTY_STEP_NS 52 #define QPNP_WLED_BOOST_DUTY_MIN_NS 26 #define QPNP_WLED_BOOST_DUTY_MAX_NS 156 #define QPNP_WLED_DEF_BOOST_DUTY_NS 104 #define QPNP_WLED_DFLT_HYB_THRES 625 #define QPNP_WLED_SWITCH_FREQ_MASK 0xF0 #define QPNP_WLED_SWITCH_FREQ_800_KHZ 800 #define QPNP_WLED_SWITCH_FREQ_1600_KHZ 1600 #define QPNP_WLED_OVP_MASK 0xFC #define QPNP_WLED_OVP_17800_MV 17800 #define QPNP_WLED_OVP_19400_MV 19400 #define QPNP_WLED_OVP_29500_MV 29500 #define QPNP_WLED_OVP_31000_MV 31000 /* sink registers */ #define QPNP_WLED_CURR_SINK_REG(b) (b + 0x46) #define QPNP_WLED_SYNC_REG(b) (b + 0x47) #define QPNP_WLED_MOD_REG(b) (b + 0x4A) #define QPNP_WLED_HYB_THRES_REG(b) (b + 0x4B) #define QPNP_WLED_MOD_EN_REG(b, n) (b + 0x50 + (n * 0x10)) #define QPNP_WLED_SYNC_DLY_REG(b, n) (QPNP_WLED_MOD_EN_REG(b, n) + 0x01) #define QPNP_WLED_FS_CURR_REG(b, n) (QPNP_WLED_MOD_EN_REG(b, n) + 0x02) #define QPNP_WLED_CABC_REG(b, n) (QPNP_WLED_MOD_EN_REG(b, n) + 0x06) #define QPNP_WLED_BRIGHT_LSB_REG(b, n) (QPNP_WLED_MOD_EN_REG(b, n) + 0x07) #define QPNP_WLED_BRIGHT_MSB_REG(b, n) (QPNP_WLED_MOD_EN_REG(b, n) + 0x08) #define QPNP_WLED_MOD_FREQ_1200_KHZ 1200 #define QPNP_WLED_MOD_FREQ_2400_KHZ 2400 #define QPNP_WLED_MOD_FREQ_9600_KHZ 9600 #define QPNP_WLED_MOD_FREQ_19200_KHZ 19200 #define QPNP_WLED_MOD_FREQ_MASK 0x3F #define QPNP_WLED_MOD_FREQ_SHIFT 6 #define QPNP_WLED_PHASE_STAG_MASK 0xDF #define QPNP_WLED_PHASE_STAG_SHIFT 5 #define QPNP_WLED_DIM_RES_MASK 0xFD #define QPNP_WLED_DIM_RES_SHIFT 1 #define QPNP_WLED_DIM_HYB_MASK 0xFB #define QPNP_WLED_DIM_HYB_SHIFT 2 #define QPNP_WLED_DIM_ANA_MASK 0xFE #define QPNP_WLED_HYB_THRES_MASK 0xF8 #define QPNP_WLED_HYB_THRES_MIN 78 #define QPNP_WLED_DEF_HYB_THRES 625 #define QPNP_WLED_HYB_THRES_MAX 10000 #define QPNP_WLED_MOD_EN_MASK 0x7F #define QPNP_WLED_MOD_EN_SHFT 7 #define QPNP_WLED_MOD_EN 1 #define QPNP_WLED_SYNC_DLY_MASK 0xF8 #define QPNP_WLED_SYNC_DLY_MIN_US 0 #define QPNP_WLED_SYNC_DLY_MAX_US 1400 #define QPNP_WLED_SYNC_DLY_STEP_US 200 #define QPNP_WLED_DEF_SYNC_DLY_US 400 #define QPNP_WLED_FS_CURR_MASK 0xF0 #define QPNP_WLED_FS_CURR_MIN_UA 0 #define QPNP_WLED_FS_CURR_MAX_UA 30000 #define QPNP_WLED_FS_CURR_STEP_UA 2500 #define QPNP_WLED_CABC_MASK 0x7F #define QPNP_WLED_CABC_SHIFT 7 #define QPNP_WLED_CURR_SINK_SHIFT 4 #define QPNP_WLED_BRIGHT_LSB_MASK 0xFF #define QPNP_WLED_BRIGHT_MSB_SHIFT 8 #define QPNP_WLED_BRIGHT_MSB_MASK 0x0F #define QPNP_WLED_SYNC 0x0F #define QPNP_WLED_SYNC_RESET 0x00 #define QPNP_WLED_SWITCH_FREQ_800_KHZ_CODE 0x0B #define QPNP_WLED_SWITCH_FREQ_1600_KHZ_CODE 0x05 #define QPNP_WLED_DISP_SEL_REG(b) (b + 0x44) #define QPNP_WLED_MODULE_RDY_REG(b) (b + 0x45) #define QPNP_WLED_MODULE_EN_REG(b) (b + 0x46) #define QPNP_WLED_MODULE_RDY_MASK 0x7F #define QPNP_WLED_MODULE_RDY_SHIFT 7 #define QPNP_WLED_MODULE_EN_MASK 0x7F #define QPNP_WLED_MODULE_EN_SHIFT 7 #define QPNP_WLED_DISP_SEL_MASK 0x7F #define QPNP_WLED_DISP_SEL_SHIFT 7 #define QPNP_WLED_IBB_BIAS_REG(b) (b + 0x58) #define QPNP_WLED_IBB_BIAS_MASK 0x7F #define QPNP_WLED_IBB_BIAS_SHIFT 7 #define QPNP_WLED_IBB_PWRUP_DLY_MASK 0xCF #define QPNP_WLED_IBB_PWRUP_DLY_SHIFT 4 #define QPNP_WLED_IBB_PWRUP_DLY_MIN_MS 0 #define QPNP_WLED_IBB_PWRUP_DLY_MAX_MS 3 #define QPNP_WLED_IBB_PWRDN_DLY_MIN_MS 0 #define QPNP_WLED_IBB_PWRDN_DLY_MAX_MS 3 #define IBB_LAB_VREG_STEP_SIZE 100000 #define QPNP_LABIBB_OUTPUT_VOLTAGE 0x41 #define QPNP_LAB_OUTPUT_OVERRIDE_EN BIT(7) #define QPNP_LAB_SET_VOLTAGE_MASK (BIT(4) - 1) #define QPNP_IBB_SET_VOLTAGE_MASK (BIT(6) - 1) #define QPNP_WLED_LAB_IBB_RDY_REG(b) (b + 0x49) #define QPNP_WLED_LAB_FAST_PC_REG(b) (b + 0x5E) #define QPNP_WLED_LAB_FAST_PC_MASK 0xFB #define QPNP_WLED_LAB_START_DLY_US 8 #define QPNP_WLED_LAB_FAST_PC_SHIFT 2 #define QPNP_WLED_SEC_ACCESS_REG(b) (b + 0xD0) #define QPNP_WLED_SEC_UNLOCK 0xA5 #define QPNP_WLED_MAX_STRINGS 4 #define WLED_MAX_LEVEL_511 511 #define WLED_MAX_LEVEL_4095 4095 #define QPNP_WLED_RAMP_DLY_MS 20 #define QPNP_WLED_TRIGGER_NONE "none" #define QPNP_WLED_STR_SIZE 20 #define QPNP_WLED_MIN_MSLEEP 20 #define QPNP_WLED_MAX_BR_LEVEL 1638 #define PWRDN_DLY2_MASK 0x3 /* output feedback mode */ enum qpnp_wled_fdbk_op { QPNP_WLED_FDBK_AUTO, QPNP_WLED_FDBK_WLED1, QPNP_WLED_FDBK_WLED2, QPNP_WLED_FDBK_WLED3, QPNP_WLED_FDBK_WLED4, }; /* dimming modes */ enum qpnp_wled_dim_mode { QPNP_WLED_DIM_ANALOG, QPNP_WLED_DIM_DIGITAL, QPNP_WLED_DIM_HYBRID, }; /* dimming curve shapes */ enum qpnp_wled_dim_shape { QPNP_WLED_DIM_SHAPE_LOG, QPNP_WLED_DIM_SHAPE_LINEAR, QPNP_WLED_DIM_SHAPE_SQUARE, }; /** * qpnp_wled - wed data structure * @ fdbk_op - output feedback mode * @ dim_mode - dimming mode * @ dim_shape - dimming curve shape * @ ctrl_base - base address for wled ctrl * @ sink_base - base address for wled sink * @ ibb_base - base address for IBB(Inverting Buck Boost) * @ lab_base - base address for LAB(LCD/AMOLED Boost) * @ mod_freq_khz - modulator frequency in KHZ * @ hyb_thres - threshold for hybrid dimming * @ sync_dly_us - sync delay in us * @ vref_mv - ref voltage in mv * @ switch_freq_khz - switching frequency in KHZ * @ ovp_mv - over voltage protection in mv * @ ilim_ma - current limiter in ma * @ boost_duty_ns - boost duty cycle in ns * @ fs_curr_ua - full scale current in ua * @ ramp_ms - delay between ramp steps in ms * @ ramp_step - ramp step size * @ strings - supported list of strings * @ num_strings - number of strings * @ en_9b_dim_res - enable or disable 9bit dimming * @ en_phase_stag - enable or disable phase staggering * @ en_cabc - enable or disable cabc * @ disp_type_amoled - type of display: LCD/AMOLED * @ ibb_bias_active - activate display bias * @ lab_fast_precharge - fast/slow precharge */ struct qpnp_wled { enum qpnp_wled_fdbk_op fdbk_op; enum qpnp_wled_dim_mode dim_mode; enum qpnp_wled_dim_shape dim_shape; uint16_t ctrl_base; uint16_t sink_base; uint16_t ibb_base; uint16_t lab_base; uint16_t mod_freq_khz; uint16_t hyb_thres; uint16_t sync_dly_us; uint16_t vref_mv; uint16_t switch_freq_khz; uint16_t ovp_mv; uint16_t ilim_ma; uint16_t boost_duty_ns; uint16_t fs_curr_ua; uint16_t ibb_pwrup_dly_ms; uint16_t ibb_pwrdn_dly_ms; uint16_t ibb_discharge_en; uint16_t ramp_ms; uint16_t ramp_step; uint8_t strings[QPNP_WLED_MAX_STRINGS]; uint8_t num_strings; bool en_9b_dim_res; bool en_phase_stag; bool en_cabc; bool disp_type_amoled; bool ibb_bias_active; bool lab_fast_precharge; uint32_t lab_min_volt; uint32_t lab_max_volt; uint32_t ibb_min_volt; uint32_t ibb_max_volt; uint32_t ibb_init_volt; uint32_t lab_init_volt; }; struct qpnp_wled_config_data { bool display_type; char pwr_up_delay; char pwr_down_delay; char ibb_discharge_en; uint32_t lab_min_volt; uint32_t lab_max_volt; uint32_t ibb_min_volt; uint32_t ibb_max_volt; uint32_t ibb_init_volt; uint32_t lab_init_volt; }; /* WLED Initial Setup */ int qpnp_wled_init(struct qpnp_wled_config_data *config); /* Enable IBB */ int qpnp_ibb_enable(bool state); void qpnp_wled_enable_backlight(int enable);