#define LEDEN_LEDAPWM BIT(4)
#define LEDEN_LEDBPWM BIT(5)
+#define LED_UNKNOWN -1
+
enum twl4030_led {
TWL4030_LEDA = 0,
TWL4030_LEDB,
struct work_struct work;
};
-static int twl4030_clear_set(u8 mod_no, u8 clear, u8 set, u8 reg)
-{
- u8 val = 0;
- int ret;
-
- ret = twl_i2c_read_u8(mod_no, &val, reg);
- if (ret)
- return ret;
-
- val &= ~clear;
- val |= set;
-
- return twl_i2c_write_u8(mod_no, val, reg);
-}
-
static void twl4030_enable_ledab(enum twl4030_led led, bool enable)
{
u8 bits;
bits = LEDEN_LEDBON | LEDEN_LEDBPWM;
if (enable)
- twl4030_clear_set(TWL4030_MODULE_LED, 0, bits, TWL4030_LED_LEDEN);
+ twl_i2c_rmw_u8(TWL4030_MODULE_LED, 0, bits, TWL4030_LED_LEDEN);
else
- twl4030_clear_set(TWL4030_MODULE_LED, bits, 0, TWL4030_LED_LEDEN);
+ twl_i2c_rmw_u8(TWL4030_MODULE_LED, bits, 0, TWL4030_LED_LEDEN);
}
static void twl4030_enable_pwm01(enum twl4030_led led, bool enable)
{
- u8 r, enbit, clkbit;
+ u8 enbit, clkbit;
if (led == TWL4030_PWM0) {
enbit = GPBR1_PWM0_ENABLE;
clkbit = GPBR1_PWM1_CLK_ENABLE;
}
- twl_i2c_read_u8(TWL4030_MODULE_INTBR, &r, TWL_INTBR_GPBR1);
-
if (enable) {
/* first enable clock, then PWM out */
- r &= ~enbit;
- r |= clkbit;
- twl_i2c_write_u8(TWL4030_MODULE_INTBR, r, TWL_INTBR_GPBR1);
- r |= enbit;
+ twl_i2c_rmw_u8(TWL4030_MODULE_INTBR,
+ enbit, clkbit, TWL_INTBR_GPBR1);
+ twl_i2c_rmw_u8(TWL4030_MODULE_INTBR,
+ 0, enbit, TWL_INTBR_GPBR1);
} else {
/* first disable PWM output, then clock */
- r &= ~enbit;
- twl_i2c_write_u8(TWL4030_MODULE_INTBR, r, TWL_INTBR_GPBR1);
- r &= ~clkbit;
+ twl_i2c_rmw_u8(TWL4030_MODULE_INTBR,
+ enbit, 0, TWL_INTBR_GPBR1);
+ twl_i2c_rmw_u8(TWL4030_MODULE_INTBR,
+ clkbit, 0, TWL_INTBR_GPBR1);
}
-
- twl_i2c_write_u8(TWL4030_MODULE_INTBR, r, TWL_INTBR_GPBR1);
}
static void twl4030_pwmled_work(struct work_struct *work)
twl_i2c_write_u8(led->module, val, TWL4030_PWMx_PWMxOFF);
- if (led->old_brightness == LED_OFF)
+ if (led->old_brightness == LED_OFF || led->old_brightness == LED_UNKNOWN)
led->enable(led->id, 1);
out:
led->cdev.brightness_set = twl4030_pwmled_brightness;
led->cdev.default_trigger = pdata->leds[i].default_trigger;
led->id = pdata->leds[i].pwm_id;
- led->old_brightness = -1; /* unknown */
+ led->old_brightness = LED_UNKNOWN;
switch (pdata->leds[i].pwm_id) {
case TWL4030_LEDA:
led->module = TWL4030_MODULE_PWM0;
led->enable = twl4030_enable_pwm01;
/* enable PWM0 in pin mux */
- twl4030_clear_set(TWL4030_MODULE_INTBR,
+ twl_i2c_rmw_u8(TWL4030_MODULE_INTBR,
0x0c, 0x04, TWL_INTBR_PMBR1);
+ /* enable PWM clock for initial write */
+ twl_i2c_rmw_u8(TWL4030_MODULE_INTBR,
+ 0, GPBR1_PWM0_CLK_ENABLE, TWL_INTBR_GPBR1);
break;
case TWL4030_PWM1:
led->module = TWL4030_MODULE_PWM1;
led->enable = twl4030_enable_pwm01;
- twl4030_clear_set(TWL4030_MODULE_INTBR,
+ twl_i2c_rmw_u8(TWL4030_MODULE_INTBR,
0, 0x30, TWL_INTBR_PMBR1);
+ twl_i2c_rmw_u8(TWL4030_MODULE_INTBR,
+ 0, GPBR1_PWM1_CLK_ENABLE, TWL_INTBR_GPBR1);
break;
default:
dev_err(&pdev->dev, "invalid pwm_id: %d\n",
INIT_WORK(&led->work, twl4030_pwmled_work);
twl_i2c_write_u8(led->module, 0, TWL4030_PWMx_PWMxON);
+ led->new_brightness = LED_OFF;
+ twl4030_pwmled_work(&led->work);
/* Hand it over to the LED framework */
ret = led_classdev_register(&pdev->dev, &led->cdev);