Пример #1
0
static int __devinit qpnp_flash_init(struct qpnp_led_data *led)
{
	int rc;

	rc = qpnp_led_masked_write(led,
		FLASH_LED_STROBE_CTRL(led->base),
		FLASH_STROBE_MASK, FLASH_DISABLE_ALL);
	if (rc) {
		dev_err(&led->spmi_dev->dev,
			"LED %d flash write failed(%d)\n", led->id, rc);
		return rc;
	}
	rc = qpnp_led_masked_write(led, FLASH_ENABLE_CONTROL(led->base),
		FLASH_INIT_MASK, FLASH_ENABLE_MODULE);
	if (rc) {
		dev_err(&led->spmi_dev->dev,
			"Enable reg write failed(%d)\n", rc);
		return rc;
	}

	/* Set flash safety timer */
	rc = qpnp_led_masked_write(led, FLASH_SAFETY_TIMER(led->base),
		FLASH_SAFETY_TIMER_MASK, led->flash_cfg->duration);
	if (rc) {
		dev_err(&led->spmi_dev->dev,
			"Safety timer reg write failed(%d)\n", rc);
		return rc;
	}

	/* Set max current */
	rc = qpnp_led_masked_write(led, FLASH_MAX_CURR(led->base),
		FLASH_CURRENT_MASK, FLASH_MAX_LEVEL);
	if (rc) {
		dev_err(&led->spmi_dev->dev,
			"Max current reg write failed(%d)\n", rc);
		return rc;
	}
	/* Set clamp current */
	rc = qpnp_led_masked_write(led, FLASH_CLAMP_CURR(led->base),
		FLASH_CURRENT_MASK, led->flash_cfg->clamp_curr);
	if (rc) {
		dev_err(&led->spmi_dev->dev,
			"Clamp current reg write failed(%d)\n", rc);
		return rc;
	}

	/* Set timer control - safety or watchdog */
	if (led->flash_cfg->safety_timer)
		rc = qpnp_led_masked_write(led, FLASH_LED_TMR_CTRL(led->base),
			FLASH_TMR_MASK, FLASH_TMR_SAFETY);
	else
		rc = qpnp_led_masked_write(led, FLASH_LED_TMR_CTRL(led->base),
			FLASH_TMR_MASK, FLASH_TMR_WATCHDOG);
	if (rc) {
		dev_err(&led->spmi_dev->dev,
			"LED timer ctrl reg write failed(%d)\n", rc);
		return rc;
	}
	/* Set headroom */
	rc = qpnp_led_masked_write(led, FLASH_HEADROOM(led->base),
		FLASH_HEADROOM_MASK, led->flash_cfg->headroom);
	if (rc) {
		dev_err(&led->spmi_dev->dev,
			"Headroom reg write failed(%d)\n", rc);
		return rc;
	}

	/* Set mask enable */
	rc = qpnp_led_masked_write(led, FLASH_MASK_ENABLE(led->base),
		FLASH_MASK_REG_MASK, FLASH_MASK_1);
	if (rc) {
		dev_err(&led->spmi_dev->dev,
			"Mask enable reg write failed(%d)\n", rc);
		return rc;
	}

	/* Set startup delay */
	rc = qpnp_led_masked_write(led, FLASH_STARTUP_DELAY(led->base),
		FLASH_STARTUP_DLY_MASK, led->flash_cfg->startup_dly);
	if (rc) {
		dev_err(&led->spmi_dev->dev,
			"Startup delay reg write failed(%d)\n", rc);
		return rc;
	}

	rc = qpnp_led_masked_write(led, FLASH_VREG_OK_FORCE(led->base),
		FLASH_VREG_MASK, FLASH_HW_VREG_OK);
	if (rc) {
		dev_err(&led->spmi_dev->dev,
			"Vreg OK reg write failed(%d)\n", rc);
		return rc;
	}

	/* Set led current and enable module */
	rc = qpnp_led_masked_write(led, led->flash_cfg->current_addr,
		FLASH_CURRENT_MASK, led->flash_cfg->current_prgm);
	if (rc) {
		dev_err(&led->spmi_dev->dev,
			"Current reg write failed(%d)\n", rc);
		return rc;
	}

	rc = qpnp_led_masked_write(led, FLASH_ENABLE_CONTROL(led->base),
		FLASH_ENABLE_MODULE_MASK, FLASH_ENABLE_MODULE);
	if (rc) {
		dev_err(&led->spmi_dev->dev,
			"Enable reg write failed(%d)\n", rc);
		return rc;
	}
	/* dump flash registers */
	qpnp_dump_regs(led, flash_debug_regs, ARRAY_SIZE(flash_debug_regs));

	return 0;
}
static int qpnp_flash_led_init_settings(struct qpnp_flash_led *led)
{
    int rc;
    u8 val, temp_val;

    rc = qpnp_led_masked_write(led->spmi_dev,
                               FLASH_MODULE_ENABLE_CTRL(led->base),
                               FLASH_MODULE_ENABLE_MASK, FLASH_LED_DISABLE);
    if (rc) {
        dev_err(&led->spmi_dev->dev, "Module disable failed\n");
        return rc;
    }

    rc = qpnp_led_masked_write(led->spmi_dev,
                               FLASH_LED_STROBE_CTRL(led->base),
                               FLASH_STROBE_MASK, FLASH_LED_DISABLE);
    if (rc) {
        dev_err(&led->spmi_dev->dev, "Strobe disable failed\n");
        return rc;
    }

    rc = qpnp_led_masked_write(led->spmi_dev,
                               FLASH_LED_TMR_CTRL(led->base),
                               FLASH_TMR_MASK, FLASH_TMR_SAFETY);
    if (rc) {
        dev_err(&led->spmi_dev->dev,
                "LED timer ctrl reg write failed(%d)\n", rc);
        return rc;
    }

    val = (u8)(led->pdata->headroom / FLASH_LED_HEADROOM_DIVIDER -
               FLASH_LED_HEADROOM_OFFSET);
    rc = qpnp_led_masked_write(led->spmi_dev,
                               FLASH_HEADROOM(led->base),
                               FLASH_HEADROOM_MASK, val);
    if (rc) {
        dev_err(&led->spmi_dev->dev, "Headroom reg write failed\n");
        return rc;
    }

    val = qpnp_flash_led_get_startup_dly(led->pdata->startup_dly);

    rc = qpnp_led_masked_write(led->spmi_dev,
                               FLASH_STARTUP_DELAY(led->base),
                               FLASH_STARTUP_DLY_MASK, val);
    if (rc) {
        dev_err(&led->spmi_dev->dev,
                "Startup delay reg write failed\n");
        return rc;
    }

    val = (u8)(led->pdata->clamp_current * FLASH_MAX_LEVEL /
               FLASH_LED_MAX_CURRENT_MA);
    rc = qpnp_led_masked_write(led->spmi_dev,
                               FLASH_CLAMP_CURRENT(led->base),
                               FLASH_CURRENT_MASK, val);
    if (rc) {
        dev_err(&led->spmi_dev->dev,
                "Clamp current reg write failed\n");
        return rc;
    }

    if (led->pdata->pmic_charger_support)
        val = FLASH_LED_FLASH_HW_VREG_OK;
    else
        val = FLASH_LED_FLASH_SW_VREG_OK;
    rc = qpnp_led_masked_write(led->spmi_dev,
                               FLASH_VREG_OK_FORCE(led->base),
                               FLASH_VREG_OK_FORCE_MASK, val);
    if (rc) {
        dev_err(&led->spmi_dev->dev,
                "VREG OK force reg write failed\n");
        return rc;
    }

    if (led->pdata->self_check_en)
        val = FLASH_MODULE_ENABLE;
    else
        val = FLASH_LED_DISABLE;
    rc = qpnp_led_masked_write(led->spmi_dev,
                               FLASH_FAULT_DETECT(led->base),
                               FLASH_FAULT_DETECT_MASK, val);
    if (rc) {
        dev_err(&led->spmi_dev->dev,
                "Fault detect reg write failed\n");
        return rc;
    }

    rc = qpnp_led_masked_write(led->spmi_dev, FLASH_MASK_ENABLE(led->base),
                               FLASH_MASK_MODULE_CONTRL_MASK,
                               FLASH_LED_MASK_MODULE_MASK2_ENABLE);
    if (rc) {
        dev_err(&led->spmi_dev->dev, "Mask module enable failed\n");
        return rc;
    }

    if (!led->pdata->thermal_derate_en)
        val = 0x0;
    else {
        val = led->pdata->thermal_derate_en << 7;
        val |= led->pdata->thermal_derate_rate << 3;
        val |= (led->pdata->thermal_derate_threshold -
                FLASH_LED_THERMAL_THRESHOLD_MIN) /
               FLASH_LED_THERMAL_DEVIDER;
    }
    rc = qpnp_led_masked_write(led->spmi_dev,
                               FLASH_THERMAL_DRATE(led->base),
                               FLASH_THERMAL_DERATE_MASK, val);
    if (rc) {
        dev_err(&led->spmi_dev->dev, "Thermal derate reg write failed\n");
        return rc;
    }

    if (!led->pdata->current_ramp_en)
        val = 0x0;
    else {
        val = led->pdata->current_ramp_en << 7;
        val |= led->pdata->ramp_up_step << 3;
        val |= led->pdata->ramp_dn_step;
    }
    rc = qpnp_led_masked_write(led->spmi_dev,
                               FLASH_CURRENT_RAMP(led->base),
                               FLASH_CURRENT_RAMP_MASK, val);
    if (rc) {
        dev_err(&led->spmi_dev->dev, "Current ramp reg write failed\n");
        return rc;
    }

    if (!led->pdata->vph_pwr_droop_en)
        val = 0x0;
    else {
        val = led->pdata->vph_pwr_droop_en << 7;
        val |= ((led->pdata->vph_pwr_droop_threshold -
                 FLASH_LED_VPH_DROOP_THRESHOLD_MIN_MV) /
                FLASH_LED_VPH_DROOP_THRESHOLD_DIVIDER) << 4;
        temp_val =
            qpnp_flash_led_get_droop_debounce_time(
                led->pdata->vph_pwr_droop_debounce_time);
        if (temp_val == 0xFF) {
            dev_err(&led->spmi_dev->dev, "Invalid debounce time\n");
            return temp_val;
        }

        val |= temp_val;
    }
    rc = qpnp_led_masked_write(led->spmi_dev,
                               FLASH_VPH_PWR_DROOP(led->base),
                               FLASH_VPH_PWR_DROOP_MASK, val);
    if (rc) {
        dev_err(&led->spmi_dev->dev, "VPH PWR droop reg write failed\n");
        return rc;
    }

    if (led->pdata->hdrm_sns_ch0_en) {
        rc = qpnp_led_masked_write(led->spmi_dev,
                                   FLASH_HDRM_SNS_ENABLE_CTRL0(led->base),
                                   FLASH_LED_HDRM_SNS_ENABLE_MASK,
                                   FLASH_LED_HDRM_SNS_ENABLE);
        if (rc) {
            dev_err(&led->spmi_dev->dev,
                    "Headroom sense enable failed\n");
            return rc;
        }
    }

    if (led->pdata->hdrm_sns_ch1_en) {
        rc = qpnp_led_masked_write(led->spmi_dev,
                                   FLASH_HDRM_SNS_ENABLE_CTRL1(led->base),
                                   FLASH_LED_HDRM_SNS_ENABLE_MASK,
                                   FLASH_LED_HDRM_SNS_ENABLE);
        if (rc) {
            dev_err(&led->spmi_dev->dev,
                    "Headroom sense enable failed\n");
            return rc;
        }
    }

    return 0;
}