Loading drivers/video/backlight/qcom-spmi-wled.c +111 −2 Original line number Diff line number Diff line Loading @@ -180,6 +180,21 @@ #define WLED5_SINK_FLASH_SHDN_CLR_REG 0xb6 #define WLED5_SINK_BRIGHTNESS_SLEW_RATE_CTL_REG 0xb8 #define WLED5_EN_SLEW_CTL BIT(7) #define WLED5_EN_EXP_LUT BIT(6) #define WLED5_SINK_DIMMING_EXP_LUT0_LSB_REG 0xc0 #define WLED5_SINK_DIMMING_EXP_LUT0_MSB_REG 0xc1 #define WLED5_SINK_DIMMING_EXP_LUT1_LSB_REG 0xc2 #define WLED5_SINK_DIMMING_EXP_LUT1_MSB_REG 0xc3 #define WLED5_SINK_DIMMING_EXP_LUT_LSB_MASK GENMASK(7, 0) #define WLED5_SINK_DIMMING_EXP_LUT_MSB_MASK GENMASK(6, 0) #define WLED5_SINK_EXP_LUT_INDEX_REG 0xc9 #define EXP_DIMMING_TABLE_SIZE 256 enum wled_version { WLED_PMI8998 = 4, WLED_PM660L, Loading Loading @@ -211,6 +226,7 @@ struct wled_config { bool en_cabc; bool ext_pfet_sc_pro_en; bool auto_calib_enabled; bool use_exp_dimming; }; struct wled_flash_config { Loading Loading @@ -258,6 +274,7 @@ struct wled { enum wled_flash_mode flash_mode; u8 num_strings; u32 leds_per_string; u32 exp_map[EXP_DIMMING_TABLE_SIZE]; }; enum wled5_mod_sel { Loading Loading @@ -320,7 +337,7 @@ static int wled_module_enable(struct wled *wled, int val) return 0; /* Force HFRC off */ if (is_wled5(wled)) { if (*wled->version == WLED_PM8150L) { reg = val ? 0 : 3; rc = regmap_write(wled->regmap, wled->ctrl_addr + WLED5_CTRL_PBUS_WRITE_SYNC_CTL, reg); Loading @@ -335,7 +352,7 @@ static int wled_module_enable(struct wled *wled, int val) return rc; /* Force HFRC off */ if (is_wled5(wled) && val) { if ((*wled->version == WLED_PM8150L) && val) { rc = regmap_write(wled->regmap, wled->sink_addr + WLED5_SINK_FLASH_SHDN_CLR_REG, 0); if (rc < 0) Loading Loading @@ -1116,6 +1133,78 @@ static inline u8 get_wled_safety_time(int time_ms) return 0; } static int wled_read_exp_dimming_map(struct device_node *node, struct wled *wled) { int rc = 0, len; if (*wled->version != WLED_PM7325B) { pr_err("Exponential dimming not supported for WLED version %d\n", *wled->version); return 0; } len = of_property_count_elems_of_size(node, "qcom,exp-dimming-map", sizeof(u32)); if (len != EXP_DIMMING_TABLE_SIZE) { pr_err("Invalid exponential map length: %d, must be 256 bytes length\n", len); return -EINVAL; } rc = of_property_read_u32_array(node, "qcom,exp-dimming-map", wled->exp_map, EXP_DIMMING_TABLE_SIZE); if (rc < 0) pr_err("Error in reading qcom,exp-dimming-map, rc=%d\n", rc); return rc; } static int wled_program_exp_dimming(struct wled *wled) { int rc = 0, i; u8 val[4]; if (*wled->version != WLED_PM7325B) { pr_err("Exponential dimming not supported for WLED version %d\n", *wled->version); return 0; } wled_module_enable(wled, 0); rc = regmap_update_bits(wled->regmap, wled->sink_addr + WLED5_SINK_BRIGHTNESS_SLEW_RATE_CTL_REG, WLED5_EN_EXP_LUT, WLED5_EN_EXP_LUT); if (rc < 0) { wled_module_enable(wled, 1); return rc; } for (i = 0; i < EXP_DIMMING_TABLE_SIZE / 2; i++) { val[0] = wled->exp_map[2 * i] & WLED5_SINK_DIMMING_EXP_LUT_LSB_MASK; val[1] = (wled->exp_map[2 * i] >> 8) & WLED5_SINK_DIMMING_EXP_LUT_MSB_MASK; val[2] = wled->exp_map[2 * i + 1] & WLED5_SINK_DIMMING_EXP_LUT_LSB_MASK; val[3] = (wled->exp_map[2 * i + 1] >> 8) & WLED5_SINK_DIMMING_EXP_LUT_MSB_MASK; rc = regmap_write(wled->regmap, wled->sink_addr + WLED5_SINK_EXP_LUT_INDEX_REG, i); if (rc < 0) goto exp_dimm_fail; rc = regmap_bulk_write(wled->regmap, wled->sink_addr + WLED5_SINK_DIMMING_EXP_LUT0_LSB_REG, val, sizeof(val)); if (rc < 0) goto exp_dimm_fail; } wled_module_enable(wled, 1); return rc; exp_dimm_fail: regmap_update_bits(wled->regmap, wled->sink_addr + WLED5_SINK_BRIGHTNESS_SLEW_RATE_CTL_REG, WLED5_EN_EXP_LUT, 0); wled_module_enable(wled, 1); return rc; } static int wled5_setup(struct wled *wled) { int rc, temp, i; Loading Loading @@ -1216,6 +1305,14 @@ static int wled5_setup(struct wled *wled) if (rc < 0) return rc; if (wled->cfg.use_exp_dimming) { rc = wled_program_exp_dimming(wled); if (rc < 0) { pr_err("Programming exponential dimming map failed, rc=%d\n", rc); return rc; } } if (wled->ovp_irq >= 0) { rc = devm_request_threaded_irq(&wled->pdev->dev, wled->ovp_irq, NULL, wled_ovp_irq_handler, IRQF_ONESHOT, Loading Loading @@ -1391,6 +1488,7 @@ static const struct wled_config wled4_config_defaults = { .en_cabc = 0, .ext_pfet_sc_pro_en = 0, .auto_calib_enabled = 0, .use_exp_dimming = 0, }; static const struct wled_config wled5_config_defaults = { Loading @@ -1404,6 +1502,7 @@ static const struct wled_config wled5_config_defaults = { .en_cabc = 0, .ext_pfet_sc_pro_en = 0, .auto_calib_enabled = 0, .use_exp_dimming = 0, }; struct wled_var_cfg { Loading Loading @@ -2269,6 +2368,7 @@ static int wled_configure(struct wled *wled, struct device *dev) { "qcom,en-cabc", &cfg->en_cabc, }, { "qcom,ext-pfet-sc-pro", &cfg->ext_pfet_sc_pro_en, }, { "qcom,auto-calibration", &cfg->auto_calib_enabled, }, { "qcom,use-exp-dimming", &cfg->use_exp_dimming, }, }; prop_addr = of_get_address(dev->of_node, 0, NULL, NULL); Loading Loading @@ -2341,6 +2441,15 @@ static int wled_configure(struct wled *wled, struct device *dev) *bool_opts[i].val_ptr = true; } if (wled->cfg.use_exp_dimming) { rc = wled_read_exp_dimming_map(dev->of_node, wled); if (rc < 0) { dev_err(&wled->pdev->dev, "Reading exponential dimming map failed, rc=%d\n", rc); return rc; } } wled->sc_irq = platform_get_irq_byname(wled->pdev, "sc-irq"); if (wled->sc_irq < 0) dev_dbg(&wled->pdev->dev, "sc irq is not used\n"); Loading Loading
drivers/video/backlight/qcom-spmi-wled.c +111 −2 Original line number Diff line number Diff line Loading @@ -180,6 +180,21 @@ #define WLED5_SINK_FLASH_SHDN_CLR_REG 0xb6 #define WLED5_SINK_BRIGHTNESS_SLEW_RATE_CTL_REG 0xb8 #define WLED5_EN_SLEW_CTL BIT(7) #define WLED5_EN_EXP_LUT BIT(6) #define WLED5_SINK_DIMMING_EXP_LUT0_LSB_REG 0xc0 #define WLED5_SINK_DIMMING_EXP_LUT0_MSB_REG 0xc1 #define WLED5_SINK_DIMMING_EXP_LUT1_LSB_REG 0xc2 #define WLED5_SINK_DIMMING_EXP_LUT1_MSB_REG 0xc3 #define WLED5_SINK_DIMMING_EXP_LUT_LSB_MASK GENMASK(7, 0) #define WLED5_SINK_DIMMING_EXP_LUT_MSB_MASK GENMASK(6, 0) #define WLED5_SINK_EXP_LUT_INDEX_REG 0xc9 #define EXP_DIMMING_TABLE_SIZE 256 enum wled_version { WLED_PMI8998 = 4, WLED_PM660L, Loading Loading @@ -211,6 +226,7 @@ struct wled_config { bool en_cabc; bool ext_pfet_sc_pro_en; bool auto_calib_enabled; bool use_exp_dimming; }; struct wled_flash_config { Loading Loading @@ -258,6 +274,7 @@ struct wled { enum wled_flash_mode flash_mode; u8 num_strings; u32 leds_per_string; u32 exp_map[EXP_DIMMING_TABLE_SIZE]; }; enum wled5_mod_sel { Loading Loading @@ -320,7 +337,7 @@ static int wled_module_enable(struct wled *wled, int val) return 0; /* Force HFRC off */ if (is_wled5(wled)) { if (*wled->version == WLED_PM8150L) { reg = val ? 0 : 3; rc = regmap_write(wled->regmap, wled->ctrl_addr + WLED5_CTRL_PBUS_WRITE_SYNC_CTL, reg); Loading @@ -335,7 +352,7 @@ static int wled_module_enable(struct wled *wled, int val) return rc; /* Force HFRC off */ if (is_wled5(wled) && val) { if ((*wled->version == WLED_PM8150L) && val) { rc = regmap_write(wled->regmap, wled->sink_addr + WLED5_SINK_FLASH_SHDN_CLR_REG, 0); if (rc < 0) Loading Loading @@ -1116,6 +1133,78 @@ static inline u8 get_wled_safety_time(int time_ms) return 0; } static int wled_read_exp_dimming_map(struct device_node *node, struct wled *wled) { int rc = 0, len; if (*wled->version != WLED_PM7325B) { pr_err("Exponential dimming not supported for WLED version %d\n", *wled->version); return 0; } len = of_property_count_elems_of_size(node, "qcom,exp-dimming-map", sizeof(u32)); if (len != EXP_DIMMING_TABLE_SIZE) { pr_err("Invalid exponential map length: %d, must be 256 bytes length\n", len); return -EINVAL; } rc = of_property_read_u32_array(node, "qcom,exp-dimming-map", wled->exp_map, EXP_DIMMING_TABLE_SIZE); if (rc < 0) pr_err("Error in reading qcom,exp-dimming-map, rc=%d\n", rc); return rc; } static int wled_program_exp_dimming(struct wled *wled) { int rc = 0, i; u8 val[4]; if (*wled->version != WLED_PM7325B) { pr_err("Exponential dimming not supported for WLED version %d\n", *wled->version); return 0; } wled_module_enable(wled, 0); rc = regmap_update_bits(wled->regmap, wled->sink_addr + WLED5_SINK_BRIGHTNESS_SLEW_RATE_CTL_REG, WLED5_EN_EXP_LUT, WLED5_EN_EXP_LUT); if (rc < 0) { wled_module_enable(wled, 1); return rc; } for (i = 0; i < EXP_DIMMING_TABLE_SIZE / 2; i++) { val[0] = wled->exp_map[2 * i] & WLED5_SINK_DIMMING_EXP_LUT_LSB_MASK; val[1] = (wled->exp_map[2 * i] >> 8) & WLED5_SINK_DIMMING_EXP_LUT_MSB_MASK; val[2] = wled->exp_map[2 * i + 1] & WLED5_SINK_DIMMING_EXP_LUT_LSB_MASK; val[3] = (wled->exp_map[2 * i + 1] >> 8) & WLED5_SINK_DIMMING_EXP_LUT_MSB_MASK; rc = regmap_write(wled->regmap, wled->sink_addr + WLED5_SINK_EXP_LUT_INDEX_REG, i); if (rc < 0) goto exp_dimm_fail; rc = regmap_bulk_write(wled->regmap, wled->sink_addr + WLED5_SINK_DIMMING_EXP_LUT0_LSB_REG, val, sizeof(val)); if (rc < 0) goto exp_dimm_fail; } wled_module_enable(wled, 1); return rc; exp_dimm_fail: regmap_update_bits(wled->regmap, wled->sink_addr + WLED5_SINK_BRIGHTNESS_SLEW_RATE_CTL_REG, WLED5_EN_EXP_LUT, 0); wled_module_enable(wled, 1); return rc; } static int wled5_setup(struct wled *wled) { int rc, temp, i; Loading Loading @@ -1216,6 +1305,14 @@ static int wled5_setup(struct wled *wled) if (rc < 0) return rc; if (wled->cfg.use_exp_dimming) { rc = wled_program_exp_dimming(wled); if (rc < 0) { pr_err("Programming exponential dimming map failed, rc=%d\n", rc); return rc; } } if (wled->ovp_irq >= 0) { rc = devm_request_threaded_irq(&wled->pdev->dev, wled->ovp_irq, NULL, wled_ovp_irq_handler, IRQF_ONESHOT, Loading Loading @@ -1391,6 +1488,7 @@ static const struct wled_config wled4_config_defaults = { .en_cabc = 0, .ext_pfet_sc_pro_en = 0, .auto_calib_enabled = 0, .use_exp_dimming = 0, }; static const struct wled_config wled5_config_defaults = { Loading @@ -1404,6 +1502,7 @@ static const struct wled_config wled5_config_defaults = { .en_cabc = 0, .ext_pfet_sc_pro_en = 0, .auto_calib_enabled = 0, .use_exp_dimming = 0, }; struct wled_var_cfg { Loading Loading @@ -2269,6 +2368,7 @@ static int wled_configure(struct wled *wled, struct device *dev) { "qcom,en-cabc", &cfg->en_cabc, }, { "qcom,ext-pfet-sc-pro", &cfg->ext_pfet_sc_pro_en, }, { "qcom,auto-calibration", &cfg->auto_calib_enabled, }, { "qcom,use-exp-dimming", &cfg->use_exp_dimming, }, }; prop_addr = of_get_address(dev->of_node, 0, NULL, NULL); Loading Loading @@ -2341,6 +2441,15 @@ static int wled_configure(struct wled *wled, struct device *dev) *bool_opts[i].val_ptr = true; } if (wled->cfg.use_exp_dimming) { rc = wled_read_exp_dimming_map(dev->of_node, wled); if (rc < 0) { dev_err(&wled->pdev->dev, "Reading exponential dimming map failed, rc=%d\n", rc); return rc; } } wled->sc_irq = platform_get_irq_byname(wled->pdev, "sc-irq"); if (wled->sc_irq < 0) dev_dbg(&wled->pdev->dev, "sc irq is not used\n"); Loading