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: Ib7177aafc63c4c33b8c144d665a11d5aaf0ef584
Signed-off-by: Prasad Sodagudi <psodagud@codeaurora.org>
This commit is contained in:
Prasad Sodagudi
2013-06-06 11:35:57 +05:30
parent 4fcb5c97be
commit 5af8792bd5
3 changed files with 71 additions and 15 deletions
+23 -2
View File
@@ -133,6 +133,11 @@
_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
@@ -795,7 +800,7 @@ static int __devinit get_init_value(struct pm8xxx_led_data *led, u8 *val)
static int pm8xxx_led_pwm_configure(struct pm8xxx_led_data *led)
{
int start_idx, idx_len, duty_us, rc;
int start_idx, idx_len, duty_us, rc, flags;
led->pwm_dev = pwm_request(led->pwm_channel,
led->cdev.name);
@@ -808,6 +813,22 @@ static int pm8xxx_led_pwm_configure(struct pm8xxx_led_data *led)
return -ENODEV;
}
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;
}
if (led->pwm_duty_cycles != NULL) {
start_idx = led->pwm_duty_cycles->start_idx;
idx_len = led->pwm_duty_cycles->num_duty_pcts;
@@ -825,7 +846,7 @@ static int pm8xxx_led_pwm_configure(struct pm8xxx_led_data *led)
led->pwm_duty_cycles->duty_pcts,
led->pwm_duty_cycles->duty_ms,
start_idx, idx_len, 0, 0,
PM8XXX_LED_PWM_FLAGS);
flags);
} else {
duty_us = led->pwm_period_us;
rc = pwm_config(led->pwm_dev, duty_us, led->pwm_period_us);
+44 -12
View File
@@ -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 pwm_device {
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;
@@ -259,18 +262,37 @@ static int pm8xxx_pwm_bank_enable(struct pwm_device *pwm, int enable)
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;
}
@@ -1010,6 +1032,16 @@ int pm8xxx_pwm_lut_config(struct pwm_device *pwm, int period_us,
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;
+4 -1
View File
@@ -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
*