/* set wled to a level of brightness */
static int qpnp_wled_set_level(struct qpnp_wled *wled, int level)
{
	int i, rc;
	u8 reg;

	if (wled->calc_curr &&
		wled->curr_scale != QPNP_WLED_CURR_SCALE_MAX)
		level = (level * wled->curr_scale) / QPNP_WLED_CURR_SCALE_MAX;

	if (wled->bl_scale_enabled && (wled->bl_scale > 0) &&
		(wled->bl_scale < QPNP_WLED_BL_SCALE_MAX))
		level = (level * wled->bl_scale) / QPNP_WLED_BL_SCALE_MAX;

	pr_debug("%s: brightness=%d level=%d\n",
			__func__, wled->cdev.brightness, level);
	/* set brightness registers */
	for (i = 0; i < wled->num_strings; i++) {
		reg = level & QPNP_WLED_BRIGHT_LSB_MASK;
		rc = qpnp_wled_write_reg(wled, &reg,
			QPNP_WLED_BRIGHT_LSB_REG(wled->sink_base,
						wled->strings[i]));
		if (rc < 0)
			return rc;

		reg = level >> QPNP_WLED_BRIGHT_MSB_SHIFT;
		reg = reg & QPNP_WLED_BRIGHT_MSB_MASK;
		rc = qpnp_wled_write_reg(wled, &reg,
			QPNP_WLED_BRIGHT_MSB_REG(wled->sink_base,
						wled->strings[i]));
		if (rc < 0)
			return rc;
	}

	/* sync */
	reg = QPNP_WLED_SYNC;
	rc = qpnp_wled_write_reg(wled, &reg,
		QPNP_WLED_SYNC_REG(wled->sink_base));
	if (rc < 0)
		return rc;

	reg = QPNP_WLED_SYNC_RESET;
	rc = qpnp_wled_write_reg(wled, &reg,
		QPNP_WLED_SYNC_REG(wled->sink_base));
	if (rc < 0)
		return rc;

	return 0;
}
예제 #2
0
파일: leds-qpnp-wled.c 프로젝트: qriozum/M9
/* sysfs store function for full scale current in ua*/
static ssize_t qpnp_wled_fs_curr_ua_store(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t count)
{
	struct qpnp_wled *wled = dev_get_drvdata(dev);
	int data, i, rc, temp;
	u8 reg;

	if (sscanf(buf, "%d", &data) != 1)
		return -EINVAL;

	for (i = 0; i < wled->num_strings; i++) {
		if (data < QPNP_WLED_FS_CURR_MIN_UA)
			data = QPNP_WLED_FS_CURR_MIN_UA;
		else if (data > QPNP_WLED_FS_CURR_MAX_UA)
			data = QPNP_WLED_FS_CURR_MAX_UA;

		rc = qpnp_wled_read_reg(wled, &reg,
				QPNP_WLED_FS_CURR_REG(wled->sink_base,
							wled->strings[i]));
		if (rc < 0)
			return rc;
		reg &= QPNP_WLED_FS_CURR_MASK;
		temp = data / QPNP_WLED_FS_CURR_STEP_UA;
		reg |= temp;
		rc = qpnp_wled_write_reg(wled, &reg,
				QPNP_WLED_FS_CURR_REG(wled->sink_base,
							wled->strings[i]));
		if (rc)
			return rc;
	}

	wled->fs_curr_ua = data;

	return count;
}
예제 #3
0
파일: leds-qpnp-wled.c 프로젝트: qriozum/M9
static int qpnp_wled_sec_access(struct qpnp_wled *wled, u16 base_addr)
{
	int rc;
	u8 reg = QPNP_WLED_SEC_UNLOCK;

	rc = qpnp_wled_write_reg(wled, &reg,
		QPNP_WLED_SEC_ACCESS_REG(base_addr));
	if (rc)
		return rc;

	return 0;
}
예제 #4
0
파일: leds-qpnp-wled.c 프로젝트: qriozum/M9
/* set wled to a level of brightness */
static int qpnp_wled_set_level(struct qpnp_wled *wled, int level)
{
	int i, rc;
	u8 reg;

	/* set brightness registers */
	for (i = 0; i < wled->num_strings; i++) {
		reg = level & QPNP_WLED_BRIGHT_LSB_MASK;
		rc = qpnp_wled_write_reg(wled, &reg,
			QPNP_WLED_BRIGHT_LSB_REG(wled->sink_base,
						wled->strings[i]));
		if (rc < 0)
			return rc;

		reg = level >> QPNP_WLED_BRIGHT_MSB_SHIFT;
		reg = reg & QPNP_WLED_BRIGHT_MSB_MASK;
		rc = qpnp_wled_write_reg(wled, &reg,
			QPNP_WLED_BRIGHT_MSB_REG(wled->sink_base,
						wled->strings[i]));
		if (rc < 0)
			return rc;
	}

	/* sync */
	reg = QPNP_WLED_SYNC;
	rc = qpnp_wled_write_reg(wled, &reg,
		QPNP_WLED_SYNC_REG(wled->sink_base));
	if (rc < 0)
		return rc;

	reg = QPNP_WLED_SYNC_RESET;
	rc = qpnp_wled_write_reg(wled, &reg,
		QPNP_WLED_SYNC_REG(wled->sink_base));
	if (rc < 0)
		return rc;

	return 0;
}
예제 #5
0
파일: leds-qpnp-wled.c 프로젝트: qriozum/M9
/* sysfs store function for dim mode*/
static ssize_t qpnp_wled_dim_mode_store(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t count)
{
	struct qpnp_wled *wled = dev_get_drvdata(dev);
	char str[QPNP_WLED_STR_SIZE + 1];
	int rc, temp;
	u8 reg;

	if (snprintf(str, QPNP_WLED_STR_SIZE, "%s", buf) > QPNP_WLED_STR_SIZE)
		return -EINVAL;

	if (strcmp(str, "analog") == 0)
		temp = QPNP_WLED_DIM_ANALOG;
	else if (strcmp(str, "digital") == 0)
		temp = QPNP_WLED_DIM_DIGITAL;
	else
		temp = QPNP_WLED_DIM_HYBRID;

	if (temp == wled->dim_mode)
		return count;

	rc = qpnp_wled_read_reg(wled, &reg,
			QPNP_WLED_MOD_REG(wled->sink_base));
	if (rc < 0)
		return rc;

	if (temp == QPNP_WLED_DIM_HYBRID) {
		reg &= QPNP_WLED_DIM_HYB_MASK;
		reg |= (1 << QPNP_WLED_DIM_HYB_SHIFT);
	} else {
		reg &= QPNP_WLED_DIM_HYB_MASK;
		reg |= (0 << QPNP_WLED_DIM_HYB_SHIFT);
		reg &= QPNP_WLED_DIM_ANA_MASK;
		reg |= temp;
	}

	rc = qpnp_wled_write_reg(wled, &reg,
			QPNP_WLED_MOD_REG(wled->sink_base));
	if (rc)
		return rc;

	wled->dim_mode = temp;

	return count;
}
예제 #6
0
파일: leds-qpnp-wled.c 프로젝트: qriozum/M9
static int qpnp_wled_mod_rdy(struct qpnp_wled *wled, u16 base_addr, bool state)
{
	int rc;
	u8 reg;

	rc = qpnp_wled_read_reg(wled, &reg,
			QPNP_WLED_MODULE_RDY_REG(base_addr));
	if (rc < 0)
		return rc;
	reg &= QPNP_WLED_MODULE_RDY_MASK;
	reg |= (state << QPNP_WLED_MODULE_RDY_SHIFT);
	rc = qpnp_wled_write_reg(wled, &reg,
			QPNP_WLED_MODULE_RDY_REG(base_addr));
	if (rc)
		return rc;

	return 0;
}
예제 #7
0
파일: leds-qpnp-wled.c 프로젝트: qriozum/M9
static int qpnp_wled_set_disp(struct qpnp_wled *wled, u16 base_addr)
{
	int rc;
	u8 reg;

	/* display type */
	rc = qpnp_wled_read_reg(wled, &reg,
			QPNP_WLED_DISP_SEL_REG(base_addr));
	if (rc < 0)
		return rc;

	reg &= QPNP_WLED_DISP_SEL_MASK;
	reg |= (wled->disp_type_amoled << QPNP_WLED_DISP_SEL_SHIFT);
	rc = qpnp_wled_write_reg(wled, &reg,
			QPNP_WLED_DISP_SEL_REG(base_addr));
	if (rc)
		return rc;

	return 0;
}
예제 #8
0
파일: leds-qpnp-wled.c 프로젝트: qriozum/M9
int qpnp_ibb_enable(bool state)
{
	int rc;
	u8 reg;

	if (!gwled) {
		pr_err("%s: wled is not initialized yet\n", __func__);
		return -EAGAIN;
	}

	/* enable lab */
	if (gwled->ibb_bias_active) {
		rc = qpnp_wled_module_en(gwled, gwled->lab_base, state);
		if (rc < 0)
			return rc;
		usleep_range(QPNP_WLED_LAB_START_DLY_US,
				QPNP_WLED_LAB_START_DLY_US + 1);
	} else {
		rc = qpnp_wled_read_reg(gwled, &reg,
				QPNP_WLED_LAB_IBB_RDY_REG(gwled->lab_base));
		if (rc < 0)
			return rc;
		reg &= QPNP_WLED_MODULE_EN_MASK;
		reg |= (state << QPNP_WLED_MODULE_EN_SHIFT);
		rc = qpnp_wled_write_reg(gwled, &reg,
				QPNP_WLED_LAB_IBB_RDY_REG(gwled->lab_base));
		if (rc)
			return rc;
	}

	rc = qpnp_wled_module_en(gwled, gwled->ibb_base, state);
	if (rc < 0)
		return rc;

	return 0;
}
예제 #9
0
파일: leds-qpnp-wled.c 프로젝트: qriozum/M9
/* Configure WLED registers */
static int qpnp_wled_config(struct qpnp_wled *wled)
{
	int rc, i, temp;
	u8 reg = 0;

	/* Configure display type */
	rc = qpnp_wled_set_disp(wled, wled->ctrl_base);
	if (rc < 0)
		return rc;

	/* Configure the FEEDBACK OUTPUT register */
	rc = qpnp_wled_read_reg(wled, &reg,
			QPNP_WLED_FDBK_OP_REG(wled->ctrl_base));
	if (rc < 0)
		return rc;
	reg &= QPNP_WLED_FDBK_OP_MASK;
	reg |= wled->fdbk_op;
	rc = qpnp_wled_write_reg(wled, &reg,
			QPNP_WLED_FDBK_OP_REG(wled->ctrl_base));
	if (rc)
		return rc;

	/* Configure the VREF register */
	if (wled->vref_mv < QPNP_WLED_VREF_MIN_MV)
		wled->vref_mv = QPNP_WLED_VREF_MIN_MV;
	else if (wled->vref_mv > QPNP_WLED_VREF_MAX_MV)
		wled->vref_mv = QPNP_WLED_VREF_MAX_MV;

	rc = qpnp_wled_read_reg(wled, &reg,
			QPNP_WLED_VREF_REG(wled->ctrl_base));
	if (rc < 0)
		return rc;
	reg &= QPNP_WLED_VREF_MASK;
	temp = wled->vref_mv - QPNP_WLED_VREF_MIN_MV;
	reg |= (temp / QPNP_WLED_VREF_STEP_MV);
	rc = qpnp_wled_write_reg(wled, &reg,
			QPNP_WLED_VREF_REG(wled->ctrl_base));
	if (rc)
		return rc;

	/* Configure the ILIM register */
	if (wled->ilim_ma < QPNP_WLED_ILIM_MIN_MA)
		wled->ilim_ma = QPNP_WLED_ILIM_MIN_MA;
	else if (wled->ilim_ma > QPNP_WLED_ILIM_MAX_MA)
		wled->ilim_ma = QPNP_WLED_ILIM_MAX_MA;

	rc = qpnp_wled_read_reg(wled, &reg,
			QPNP_WLED_ILIM_REG(wled->ctrl_base));
	if (rc < 0)
		return rc;
	reg &= QPNP_WLED_ILIM_MASK;
	reg |= (wled->ilim_ma / QPNP_WLED_ILIM_STEP_MA);
	rc = qpnp_wled_write_reg(wled, &reg,
			QPNP_WLED_ILIM_REG(wled->ctrl_base));
	if (rc)
		return rc;

	/* Configure the MAX BOOST DUTY register */
	if (wled->boost_duty_ns < QPNP_WLED_BOOST_DUTY_MIN_NS)
		wled->boost_duty_ns = QPNP_WLED_BOOST_DUTY_MIN_NS;
	else if (wled->boost_duty_ns > QPNP_WLED_BOOST_DUTY_MAX_NS)
		wled->boost_duty_ns = QPNP_WLED_BOOST_DUTY_MAX_NS;

	rc = qpnp_wled_read_reg(wled, &reg,
			QPNP_WLED_BOOST_DUTY_REG(wled->ctrl_base));
	if (rc < 0)
		return rc;
	reg &= QPNP_WLED_BOOST_DUTY_MASK;
	reg |= (wled->boost_duty_ns / QPNP_WLED_BOOST_DUTY_STEP_NS);
	rc = qpnp_wled_write_reg(wled, &reg,
			QPNP_WLED_BOOST_DUTY_REG(wled->ctrl_base));
	if (rc)
		return rc;

	/* Configure the SWITCHING FREQ register */
	if (wled->switch_freq_khz == QPNP_WLED_SWITCH_FREQ_1600_KHZ)
		temp = QPNP_WLED_SWITCH_FREQ_1600_KHZ_CODE;
	else
		temp = QPNP_WLED_SWITCH_FREQ_800_KHZ_CODE;

	rc = qpnp_wled_read_reg(wled, &reg,
			QPNP_WLED_SWITCH_FREQ_REG(wled->ctrl_base));
	if (rc < 0)
		return rc;
	reg &= QPNP_WLED_SWITCH_FREQ_MASK;
	reg |= temp;
	rc = qpnp_wled_write_reg(wled, &reg,
			QPNP_WLED_SWITCH_FREQ_REG(wled->ctrl_base));
	if (rc)
		return rc;

	/* Configure the OVP register */
	if (wled->ovp_mv <= QPNP_WLED_OVP_17800_MV) {
		wled->ovp_mv = QPNP_WLED_OVP_17800_MV;
		temp = 3;
	} else if (wled->ovp_mv <= QPNP_WLED_OVP_19400_MV) {
		wled->ovp_mv = QPNP_WLED_OVP_19400_MV;
		temp = 2;
	} else if (wled->ovp_mv <= QPNP_WLED_OVP_29500_MV) {
		wled->ovp_mv = QPNP_WLED_OVP_29500_MV;
		temp = 1;
	} else {
		wled->ovp_mv = QPNP_WLED_OVP_31000_MV;
		temp = 0;
	}

	rc = qpnp_wled_read_reg(wled, &reg,
			QPNP_WLED_OVP_REG(wled->ctrl_base));
	if (rc < 0)
		return rc;
	reg &= QPNP_WLED_OVP_MASK;
	reg |= temp;
	rc = qpnp_wled_write_reg(wled, &reg,
			QPNP_WLED_OVP_REG(wled->ctrl_base));
	if (rc)
		return rc;

	/* Configure the MODULATION register */
	if (wled->mod_freq_khz <= QPNP_WLED_MOD_FREQ_1200_KHZ) {
		wled->mod_freq_khz = QPNP_WLED_MOD_FREQ_1200_KHZ;
		temp = 3;
	} else if (wled->mod_freq_khz <= QPNP_WLED_MOD_FREQ_2400_KHZ) {
		wled->mod_freq_khz = QPNP_WLED_MOD_FREQ_2400_KHZ;
		temp = 2;
	} else if (wled->mod_freq_khz <= QPNP_WLED_MOD_FREQ_9600_KHZ) {
		wled->mod_freq_khz = QPNP_WLED_MOD_FREQ_9600_KHZ;
		temp = 1;
	} else if (wled->mod_freq_khz <= QPNP_WLED_MOD_FREQ_19200_KHZ) {
		wled->mod_freq_khz = QPNP_WLED_MOD_FREQ_19200_KHZ;
		temp = 0;
	} else {
		wled->mod_freq_khz = QPNP_WLED_MOD_FREQ_9600_KHZ;
		temp = 1;
	}

	rc = qpnp_wled_read_reg(wled, &reg,
			QPNP_WLED_MOD_REG(wled->sink_base));
	if (rc < 0)
		return rc;
	reg &= QPNP_WLED_MOD_FREQ_MASK;
	reg |= (temp << QPNP_WLED_MOD_FREQ_SHIFT);

	reg &= QPNP_WLED_PHASE_STAG_MASK;
	reg |= (wled->en_phase_stag << QPNP_WLED_PHASE_STAG_SHIFT);

	reg &= QPNP_WLED_ACC_CLK_FREQ_MASK;
	reg |= (temp << QPNP_WLED_ACC_CLK_FREQ_SHIFT);

	reg &= QPNP_WLED_DIM_RES_MASK;
	reg |= (wled->en_9b_dim_res << QPNP_WLED_DIM_RES_SHIFT);

	if (wled->dim_mode == QPNP_WLED_DIM_HYBRID) {
		reg &= QPNP_WLED_DIM_HYB_MASK;
		reg |= (1 << QPNP_WLED_DIM_HYB_SHIFT);
	} else {
		reg &= QPNP_WLED_DIM_HYB_MASK;
		reg |= (0 << QPNP_WLED_DIM_HYB_SHIFT);
		reg &= QPNP_WLED_DIM_ANA_MASK;
		reg |= wled->dim_mode;
	}

	rc = qpnp_wled_write_reg(wled, &reg,
			QPNP_WLED_MOD_REG(wled->sink_base));
	if (rc)
		return rc;

	/* Configure the HYBRID THRESHOLD register */
	if (wled->hyb_thres < QPNP_WLED_HYB_THRES_MIN)
		wled->hyb_thres = QPNP_WLED_HYB_THRES_MIN;
	else if (wled->hyb_thres > QPNP_WLED_HYB_THRES_MAX)
		wled->hyb_thres = QPNP_WLED_HYB_THRES_MAX;

	rc = qpnp_wled_read_reg(wled, &reg,
			QPNP_WLED_HYB_THRES_REG(wled->sink_base));
	if (rc < 0)
		return rc;
	reg &= QPNP_WLED_HYB_THRES_MASK;
	temp = fls(wled->hyb_thres / QPNP_WLED_HYB_THRES_MIN) - 1;
	reg |= temp;
	rc = qpnp_wled_write_reg(wled, &reg,
			QPNP_WLED_HYB_THRES_REG(wled->sink_base));
	if (rc)
		return rc;

	/* Configure TEST5 register */
	if (wled->dim_mode == QPNP_WLED_DIM_DIGITAL)
		reg = QPNP_WLED_SINK_TEST5_DIG;
	else
		reg = QPNP_WLED_SINK_TEST5_HYB;

	rc = qpnp_wled_sec_access(wled, wled->sink_base);
	if (rc)
		return rc;
	rc = qpnp_wled_write_reg(wled, &reg,
			QPNP_WLED_SINK_TEST5_REG(wled->sink_base));
	if (rc)
		return rc;

	/* disable all current sinks and enable selected strings */
	reg = 0x00;
	rc = qpnp_wled_write_reg(wled, &reg,
			QPNP_WLED_CURR_SINK_REG(wled->sink_base));

	for (i = 0; i < wled->num_strings; i++) {
		if (wled->strings[i] >= QPNP_WLED_MAX_STRINGS) {
			dev_err(&wled->spmi->dev, "Invalid string number\n");
			return -EINVAL;
		}

		/* MODULATOR */
		rc = qpnp_wled_read_reg(wled, &reg,
				QPNP_WLED_MOD_EN_REG(wled->sink_base,
						wled->strings[i]));
		if (rc < 0)
			return rc;
		reg &= QPNP_WLED_MOD_EN_MASK;
		reg |= (QPNP_WLED_MOD_EN << QPNP_WLED_MOD_EN_SHFT);

		if (wled->dim_mode == QPNP_WLED_DIM_HYBRID)
			reg &= QPNP_WLED_GATE_DRV_MASK;
		else
			reg |= ~QPNP_WLED_GATE_DRV_MASK;

		rc = qpnp_wled_write_reg(wled, &reg,
				QPNP_WLED_MOD_EN_REG(wled->sink_base,
						wled->strings[i]));
		if (rc)
			return rc;

		/* SYNC DELAY */
		if (wled->sync_dly_us < QPNP_WLED_SYNC_DLY_MIN_US)
			wled->sync_dly_us = QPNP_WLED_SYNC_DLY_MIN_US;
		else if (wled->sync_dly_us > QPNP_WLED_SYNC_DLY_MAX_US)
			wled->sync_dly_us = QPNP_WLED_SYNC_DLY_MAX_US;

		rc = qpnp_wled_read_reg(wled, &reg,
				QPNP_WLED_SYNC_DLY_REG(wled->sink_base,
						wled->strings[i]));
		if (rc < 0)
			return rc;
		reg &= QPNP_WLED_SYNC_DLY_MASK;
		temp = wled->sync_dly_us / QPNP_WLED_SYNC_DLY_STEP_US;
		reg |= temp;
		rc = qpnp_wled_write_reg(wled, &reg,
				QPNP_WLED_SYNC_DLY_REG(wled->sink_base,
						wled->strings[i]));
		if (rc)
			return rc;

		/* FULL SCALE CURRENT */
		if (wled->fs_curr_ua < QPNP_WLED_FS_CURR_MIN_UA)
			wled->fs_curr_ua = QPNP_WLED_FS_CURR_MIN_UA;
		else if (wled->fs_curr_ua > QPNP_WLED_FS_CURR_MAX_UA)
			wled->fs_curr_ua = QPNP_WLED_FS_CURR_MAX_UA;

		rc = qpnp_wled_read_reg(wled, &reg,
				QPNP_WLED_FS_CURR_REG(wled->sink_base,
						wled->strings[i]));
		if (rc < 0)
			return rc;
		reg &= QPNP_WLED_FS_CURR_MASK;
		temp = wled->fs_curr_ua / QPNP_WLED_FS_CURR_STEP_UA;
		reg |= temp;
		rc = qpnp_wled_write_reg(wled, &reg,
				QPNP_WLED_FS_CURR_REG(wled->sink_base,
						wled->strings[i]));
		if (rc)
			return rc;

		/* CABC */
		rc = qpnp_wled_read_reg(wled, &reg,
				QPNP_WLED_CABC_REG(wled->sink_base,
						wled->strings[i]));
		if (rc < 0)
			return rc;
		reg &= QPNP_WLED_CABC_MASK;
		reg |= (wled->en_cabc << QPNP_WLED_CABC_SHIFT);
		rc = qpnp_wled_write_reg(wled, &reg,
				QPNP_WLED_CABC_REG(wled->sink_base,
						wled->strings[i]));
		if (rc)
			return rc;

		/* Enable CURRENT SINK */
		rc = qpnp_wled_read_reg(wled, &reg,
				QPNP_WLED_CURR_SINK_REG(wled->sink_base));
		if (rc < 0)
			return rc;
		temp = wled->strings[i] + QPNP_WLED_CURR_SINK_SHIFT;
		reg |= (1 << temp);
		rc = qpnp_wled_write_reg(wled, &reg,
				QPNP_WLED_CURR_SINK_REG(wled->sink_base));
		if (rc)
			return rc;
	}

	/* LAB fast precharge */
	rc = qpnp_wled_read_reg(wled, &reg,
			QPNP_WLED_LAB_FAST_PC_REG(wled->lab_base));
	if (rc < 0)
		return rc;
	reg &= QPNP_WLED_LAB_FAST_PC_MASK;
	reg |= (wled->lab_fast_precharge << QPNP_WLED_LAB_FAST_PC_SHIFT);
	rc = qpnp_wled_write_reg(wled, &reg,
			QPNP_WLED_LAB_FAST_PC_REG(wled->lab_base));
	if (rc)
		return rc;

	/* Configure lab display type */
	rc = qpnp_wled_set_disp(wled, wled->lab_base);
	if (rc < 0)
		return rc;

	/* make LAB module ready */
	rc = qpnp_wled_mod_rdy(wled, wled->lab_base, true);
	if (rc < 0)
		return rc;

	/* IBB active bias */
	if (wled->ibb_pwrup_dly_ms < QPNP_WLED_IBB_PWRUP_DLY_MIN_MS)
		wled->ibb_pwrup_dly_ms = QPNP_WLED_IBB_PWRUP_DLY_MIN_MS;
	else if (wled->ibb_pwrup_dly_ms > QPNP_WLED_IBB_PWRUP_DLY_MAX_MS)
		wled->ibb_pwrup_dly_ms = QPNP_WLED_IBB_PWRUP_DLY_MAX_MS;

	rc = qpnp_wled_read_reg(wled, &reg,
			QPNP_WLED_IBB_BIAS_REG(wled->ibb_base));
	if (rc < 0)
		return rc;
	reg &= QPNP_WLED_IBB_BIAS_MASK;
	reg |= (!wled->ibb_bias_active << QPNP_WLED_IBB_BIAS_SHIFT);

	temp = fls(wled->ibb_pwrup_dly_ms) - 1;
	reg &= QPNP_WLED_IBB_PWRUP_DLY_MASK;
	reg |= (temp << QPNP_WLED_IBB_PWRUP_DLY_SHIFT);

	rc = qpnp_wled_sec_access(wled, wled->ibb_base);
	if (rc)
		return rc;

	rc = qpnp_wled_write_reg(wled, &reg,
			QPNP_WLED_IBB_BIAS_REG(wled->ibb_base));
	if (rc)
		return rc;

	/* Configure ibb display type */
	rc = qpnp_wled_set_disp(wled, wled->ibb_base);
	if (rc < 0)
		return rc;

	/* make IBB module ready */
	rc = qpnp_wled_mod_rdy(wled, wled->ibb_base, true);
	if (rc < 0)
		return rc;

	/* setup ovp and sc irqs */
	if (wled->ovp_irq >= 0) {
		rc = devm_request_threaded_irq(&wled->spmi->dev, wled->ovp_irq,
			NULL, qpnp_wled_ovp_irq,
			QPNP_IRQ_FLAGS,
			"qpnp_wled_ovp_irq", wled);
		if (rc < 0) {
			dev_err(&wled->spmi->dev,
				"Unable to request ovp(%d) IRQ(err:%d)\n",
				wled->ovp_irq, rc);
			return rc;
		}
	}

	if (wled->sc_irq >= 0) {
		wled->sc_cnt = 0;
		rc = devm_request_threaded_irq(&wled->spmi->dev, wled->sc_irq,
			NULL, qpnp_wled_sc_irq,
			QPNP_IRQ_FLAGS,
			"qpnp_wled_sc_irq", wled);
		if (rc < 0) {
			dev_err(&wled->spmi->dev,
				"Unable to request sc(%d) IRQ(err:%d)\n",
				wled->sc_irq, rc);
			return rc;
		}

		rc = qpnp_wled_read_reg(wled, &reg,
				QPNP_WLED_SC_PRO_REG(wled->ctrl_base));
		if (rc < 0)
			return rc;
		reg &= QPNP_WLED_EN_SC_MASK;
		reg |= 1 << QPNP_WLED_EN_SC_SHIFT;
		rc = qpnp_wled_write_reg(wled, &reg,
				QPNP_WLED_SC_PRO_REG(wled->ctrl_base));
		if (rc)
			return rc;

		if (wled->en_ext_pfet_sc_pro) {
			rc = qpnp_wled_sec_access(wled, wled->ctrl_base);
			if (rc)
				return rc;

			reg = QPNP_WLED_EXT_FET_DTEST2;
			rc = qpnp_wled_write_reg(wled, &reg,
					QPNP_WLED_TEST_REG(wled->ctrl_base));
			if (rc)
				return rc;
		}
	}

	return 0;
}