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; }