leds: pm8xxx: Enable PWM LPG banks based on max current
The current design enables PWM LPG high bank with out
checking the max current. So enable PWM LPG low bank when max
current configured as 4mA and enable PWM LPG high bank when
the max current configured as 8mA. Enabled both PWM LPG low bank
and PWM LPG high bank when max current configure as 12mA.
CRs-Fixed: 486318
Change-Id: I6686ed85d78fa55f08491a47c10581407e0cd70e
Signed-off-by: Prasad Sodagudi <psodagud@codeaurora.org>
diff --git a/drivers/leds/leds-pm8xxx.c b/drivers/leds/leds-pm8xxx.c
index 938ca01..ecba6a6 100644
--- a/drivers/leds/leds-pm8xxx.c
+++ b/drivers/leds/leds-pm8xxx.c
@@ -144,6 +144,10 @@
_rgb_led_blue << PM8XXX_ID_RGB_LED_BLUE, \
}
+#define PM8XXX_PWM_CURRENT_4MA 4
+#define PM8XXX_PWM_CURRENT_8MA 8
+#define PM8XXX_PWM_CURRENT_12MA 12
+
/**
* supported_leds - leds supported for each PMIC version
* @version - version of PMIC
@@ -445,6 +449,7 @@
int temp = 0;
int pwm_max = 0;
int total_ms, on_ms;
+ int flags;
if (!led->pwm_duty_cycles || !led->pwm_duty_cycles->duty_pcts) {
dev_err(led->cdev.dev, "duty_cycles and duty_pcts is not exist\n");
@@ -498,11 +503,27 @@
return -EINVAL;
}
+ flags = PM8XXX_LED_PWM_FLAGS;
+ switch (led->max_current) {
+ case PM8XXX_PWM_CURRENT_4MA:
+ flags |= PM_PWM_BANK_LO;
+ break;
+ case PM8XXX_PWM_CURRENT_8MA:
+ flags |= PM_PWM_BANK_HI;
+ break;
+ case PM8XXX_PWM_CURRENT_12MA:
+ flags |= (PM_PWM_BANK_LO | PM_PWM_BANK_HI);
+ break;
+ default:
+ flags |= (PM_PWM_BANK_LO | PM_PWM_BANK_HI);
+ break;
+ }
+
rc = pm8xxx_pwm_lut_config(led->pwm_dev, led->pwm_period_us,
led->pwm_duty_cycles->duty_pcts,
led->pwm_duty_cycles->duty_ms,
start_idx, idx_len, led->pwm_pause_lo, led->pwm_pause_hi,
- PM8XXX_LED_PWM_FLAGS);
+ flags);
return rc;
}
diff --git a/drivers/mfd/pm8xxx-pwm.c b/drivers/mfd/pm8xxx-pwm.c
index 6f6369b..f57ff8a 100644
--- a/drivers/mfd/pm8xxx-pwm.c
+++ b/drivers/mfd/pm8xxx-pwm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
*
* 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
@@ -58,10 +58,11 @@
#define PM8XXX_PWM_DISABLE 0x3F
/* PM8XXX LPG PWM */
+#define SSBI_REG_ADDR_LPG_BANK_LOW_EN 0x130
#define SSBI_REG_ADDR_LPG_CTL_BASE 0x13C
#define SSBI_REG_ADDR_LPG_CTL(n) (SSBI_REG_ADDR_LPG_CTL_BASE + (n))
#define SSBI_REG_ADDR_LPG_BANK_SEL 0x143
-#define SSBI_REG_ADDR_LPG_BANK_EN 0x144
+#define SSBI_REG_ADDR_LPG_BANK_HIGH_EN 0x144
#define SSBI_REG_ADDR_LPG_LUT_CFG0 0x145
#define SSBI_REG_ADDR_LPG_LUT_CFG1 0x146
#define SSBI_REG_ADDR_LPG_TEST 0x147
@@ -206,13 +207,15 @@
struct pm8xxx_pwm_chip *chip;
int bypass_lut;
int dtest_mode_supported;
+ int banks;
};
struct pm8xxx_pwm_chip {
struct pwm_device *pwm_dev;
u8 pwm_channels;
u8 pwm_total_pre_divs;
- u8 bank_mask;
+ u8 lo_bank_mask;
+ u8 hi_bank_mask;
struct mutex pwm_mutex;
struct device *dev;
bool is_lpg_supported;
@@ -258,17 +261,39 @@
chip = pwm->chip;
- if (enable)
- reg = chip->bank_mask | (1 << pwm->pwm_id);
- else
- reg = chip->bank_mask & ~(1 << pwm->pwm_id);
+ if (pwm->banks & PM_PWM_BANK_LO) {
+ if (enable)
+ reg = chip->lo_bank_mask | (1 << pwm->pwm_id);
+ else
+ reg = chip->lo_bank_mask & ~(1 << pwm->pwm_id);
- rc = pm8xxx_writeb(chip->dev->parent, SSBI_REG_ADDR_LPG_BANK_EN, reg);
- if (rc) {
- pr_err("pm8xxx_writeb(): rc=%d (Enable LPG Bank)\n", rc);
- return rc;
+ rc = pm8xxx_writeb(chip->dev->parent,
+ SSBI_REG_ADDR_LPG_BANK_LOW_EN, reg);
+
+ if (rc) {
+ pr_err("pm8xxx_writeb(): Enable Bank Low =%d\n", rc);
+ return rc;
+ }
+
+ chip->lo_bank_mask = reg;
}
- chip->bank_mask = reg;
+
+ if (pwm->banks & PM_PWM_BANK_HI) {
+ if (enable)
+ reg = chip->hi_bank_mask | (1 << pwm->pwm_id);
+ else
+ reg = chip->hi_bank_mask & ~(1 << pwm->pwm_id);
+
+ rc = pm8xxx_writeb(chip->dev->parent,
+ SSBI_REG_ADDR_LPG_BANK_HIGH_EN, reg);
+
+ if (rc) {
+ pr_err("pm8xxx_writeb(): Enable Bank High =%d\n", rc);
+ return rc;
+ }
+
+ chip->hi_bank_mask = reg;
+ }
return 0;
}
@@ -1000,6 +1025,16 @@
period = &pwm->period;
mutex_lock(&pwm->chip->pwm_mutex);
+ if (flags & PM_PWM_BANK_HI)
+ pwm->banks = PM_PWM_BANK_HI;
+
+ if (flags & PM_PWM_BANK_LO)
+ pwm->banks |= PM_PWM_BANK_LO;
+
+ /*Enable both banks if banks information is not shared.*/
+ if (!pwm->banks)
+ pwm->banks |= (PM_PWM_BANK_LO | PM_PWM_BANK_HI);
+
if (!pwm->in_use) {
pr_err("pwm_id: %d: stale handle?\n", pwm->pwm_id);
rc = -EINVAL;
diff --git a/include/linux/mfd/pm8xxx/pwm.h b/include/linux/mfd/pm8xxx/pwm.h
index 6d95e3a..47ebe06 100644
--- a/include/linux/mfd/pm8xxx/pwm.h
+++ b/include/linux/mfd/pm8xxx/pwm.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
*
* 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
@@ -32,6 +32,9 @@
#define PM_PWM_LUT_NO_TABLE 0x100
+#define PM_PWM_BANK_LO 0x1000
+#define PM_PWM_BANK_HI 0x2000
+
/**
* PWM frequency/period control
*