From 347efa5f896173cd420cec1f960bf7c989f0cf61 Mon Sep 17 00:00:00 2001 From: TheStrix Date: Thu, 1 Mar 2018 15:54:54 +0530 Subject: [PATCH] drivers: leds: Import Xiaomi changes Change-Id: I8c0f049ee8c4898f9d2931ee392bcbc39fc55826 --- drivers/leds/leds-qpnp-flash-v2.c | 16 ++++++++++++---- drivers/leds/leds-qpnp-wled.c | 36 +++++++++++++++++++++++++++++++++++- drivers/leds/leds-qpnp.c | 30 ++++++++++++++++++++++++++++++ include/linux/leds.h | 2 ++ 4 files changed, 79 insertions(+), 5 deletions(-) diff --git a/drivers/leds/leds-qpnp-flash-v2.c b/drivers/leds/leds-qpnp-flash-v2.c index 86e70689ce2d..01681e70d87e 100644 --- a/drivers/leds/leds-qpnp-flash-v2.c +++ b/drivers/leds/leds-qpnp-flash-v2.c @@ -1,4 +1,5 @@ /* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. + * Copyright (C) 2018 XiaoMi, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -139,7 +140,7 @@ #define FLASH_LED_IRES_BASE 3 #define FLASH_LED_IRES_DIVISOR 2500 #define FLASH_LED_IRES_MIN_UA 5000 -#define FLASH_LED_IRES_DEFAULT_UA 12500 +#define FLASH_LED_IRES_DEFAULT_UA 13000 #define FLASH_LED_IRES_DEFAULT_VAL 0x00 #define FLASH_LED_HDRM_VOL_SHIFT 4 #define FLASH_LED_HDRM_VOL_DEFAULT_MV 0x80 @@ -1129,9 +1130,12 @@ static int qpnp_flash_led_switch_set(struct flash_switch_data *snode, bool on) int rc, i, addr_offset; u8 val, mask; + pr_err("snode->enabled = %d, on = %d", snode->enabled, on); if (snode->enabled == on) { - pr_debug("Switch node is already %s!\n", + pr_err("Switch node is already %s!\n", on ? "enabled" : "disabled"); + if (on) + qpnp_flash_led_switch_disable(snode); return 0; } @@ -1209,8 +1213,10 @@ static int qpnp_flash_led_switch_set(struct flash_switch_data *snode, bool on) rc = qpnp_flash_led_masked_write(led, FLASH_LED_REG_MOD_CTRL(led->base), FLASH_LED_MOD_CTRL_MASK, FLASH_LED_MOD_ENABLE); - if (rc < 0) + if (rc < 0) { + pr_err("qpnp_flash_led_masked_write fail\n"); return rc; + } } led->enable++; @@ -1241,8 +1247,10 @@ static int qpnp_flash_led_switch_set(struct flash_switch_data *snode, bool on) rc = qpnp_flash_led_masked_write(led, FLASH_LED_EN_LED_CTRL(led->base), snode->led_mask, val); - if (rc < 0) + if (rc < 0) { + pr_err("qpnp_flash_led_masked_write fail\n"); return rc; + } snode->enabled = true; return 0; diff --git a/drivers/leds/leds-qpnp-wled.c b/drivers/leds/leds-qpnp-wled.c index 54e147cca1a5..7407cb8ec957 100644 --- a/drivers/leds/leds-qpnp-wled.c +++ b/drivers/leds/leds-qpnp-wled.c @@ -1,4 +1,5 @@ /* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. + * Copyright (C) 2018 XiaoMi, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1965,7 +1966,7 @@ static int qpnp_wled_config(struct qpnp_wled *wled) if (wled->switch_freq_khz == 1600) reg = QPNP_WLED_SWITCH_FREQ_1600_KHZ_CODE; else if (wled->switch_freq_khz == 600) - temp = QPNP_WLED_SWITCH_FREQ_600_KHZ_CODE; + reg = QPNP_WLED_SWITCH_FREQ_600_KHZ_CODE; else reg = QPNP_WLED_SWITCH_FREQ_800_KHZ_CODE; @@ -2251,6 +2252,39 @@ static int qpnp_wled_config(struct qpnp_wled *wled) return 0; } +int qpnp_wled_cabc(struct led_classdev *led_cdev, bool enable) +{ + struct qpnp_wled *wled; + int rc = 0, i; + u8 reg = 0; + + wled = container_of(led_cdev, struct qpnp_wled, cdev); + if (wled == NULL) { + pr_err("wled is null\n"); + return -EPERM; + } + wled->en_cabc = enable; + for (i = 0; i < wled->num_strings; i++) { + /* CABC */ + rc = qpnp_wled_read_reg(wled, + 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, + QPNP_WLED_CABC_REG(wled->sink_base, + wled->strings[i]), reg); + if (rc) + return rc; + pr_debug("%d en_cabc %d\n", i, wled->en_cabc); + } + return rc; +} + +EXPORT_SYMBOL_GPL(qpnp_wled_cabc); + /* parse wled dtsi parameters */ static int qpnp_wled_parse_dt(struct qpnp_wled *wled) { diff --git a/drivers/leds/leds-qpnp.c b/drivers/leds/leds-qpnp.c index e3cfffb5c563..66e62a6d2b62 100644 --- a/drivers/leds/leds-qpnp.c +++ b/drivers/leds/leds-qpnp.c @@ -1,4 +1,5 @@ /* Copyright (c) 2012-2015, 2017, The Linux Foundation. All rights reserved. + * Copyright (C) 2018 XiaoMi, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1787,6 +1788,7 @@ static void qpnp_led_set(struct led_classdev *led_cdev, enum led_brightness value) { struct qpnp_led_data *led; + int rc; led = container_of(led_cdev, struct qpnp_led_data, cdev); if (value < LED_OFF) { @@ -1798,6 +1800,34 @@ static void qpnp_led_set(struct led_classdev *led_cdev, value = led->cdev.max_brightness; led->cdev.brightness = value; + + if (led->id == QPNP_ID_RGB_RED || led->id == QPNP_ID_RGB_GREEN + || led->id == QPNP_ID_RGB_BLUE) { + mutex_lock(&led->lock); + rc = qpnp_rgb_set(led); + if (rc < 0) + dev_err(&led->pdev->dev, + "RGB set brightness failed (%d)\n", rc); + mutex_unlock(&led->lock); + return; + } else if (led->id == QPNP_ID_LED_MPP) { + mutex_lock(&led->lock); + rc = qpnp_mpp_set(led); + if (rc < 0) + dev_err(&led->pdev->dev, + "MPP set brightness failed (%d)\n", rc); + mutex_unlock(&led->lock); + return; + } else if (led->id == QPNP_ID_KPDBL) { + mutex_lock(&led->lock); + rc = qpnp_kpdbl_set(led); + if (rc < 0) + dev_err(&led->pdev->dev, + "KPDBL set brightness failed (%d)\n", rc); + mutex_unlock(&led->lock); + return; + } + if (led->in_order_command_processing) queue_work(led->workqueue, &led->work); else diff --git a/include/linux/leds.h b/include/linux/leds.h index 197b61500ab7..ffb3226c0e3e 100644 --- a/include/linux/leds.h +++ b/include/linux/leds.h @@ -3,6 +3,7 @@ * * Copyright (C) 2005 John Lenz * Copyright (C) 2005 Richard Purdie + * Copyright (C) 2018 XiaoMi, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -114,6 +115,7 @@ extern void devm_led_classdev_unregister(struct device *parent, struct led_classdev *led_cdev); extern void led_classdev_suspend(struct led_classdev *led_cdev); extern void led_classdev_resume(struct led_classdev *led_cdev); +extern int qpnp_wled_cabc(struct led_classdev *led_cdev, bool enable); /** * led_blink_set - set blinking with software fallback -- 2.11.0