diff options
| author | Ingo Molnar <mingo@kernel.org> | 2012-04-14 13:18:27 +0200 |
|---|---|---|
| committer | Ingo Molnar <mingo@kernel.org> | 2012-04-14 13:19:04 +0200 |
| commit | 6ac1ef482d7ae0c690f1640bf6eb818ff9a2d91e (patch) | |
| tree | 021cc9f6b477146fcebe6f3be4752abfa2ba18a9 /drivers/leds/leds-lm3530.c | |
| parent | 682968e0c425c60f0dde37977e5beb2b12ddc4cc (diff) | |
| parent | a385ec4f11bdcf81af094c03e2444ee9b7fad2e5 (diff) | |
Merge branch 'perf/core' into perf/uprobes
Merge in latest upstream (and the latest perf development tree),
to prepare for tooling changes, and also to pick up v3.4 MM
changes that the uprobes code needs to take care of.
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'drivers/leds/leds-lm3530.c')
| -rw-r--r-- | drivers/leds/leds-lm3530.c | 135 |
1 files changed, 78 insertions, 57 deletions
diff --git a/drivers/leds/leds-lm3530.c b/drivers/leds/leds-lm3530.c index e59c166a0ce2..968fd5fef4fc 100644 --- a/drivers/leds/leds-lm3530.c +++ b/drivers/leds/leds-lm3530.c @@ -26,7 +26,6 @@ #define LM3530_GEN_CONFIG 0x10 #define LM3530_ALS_CONFIG 0x20 #define LM3530_BRT_RAMP_RATE 0x30 -#define LM3530_ALS_ZONE_REG 0x40 #define LM3530_ALS_IMP_SELECT 0x41 #define LM3530_BRT_CTRL_REG 0xA0 #define LM3530_ALS_ZB0_REG 0x60 @@ -38,7 +37,7 @@ #define LM3530_ALS_Z2T_REG 0x72 #define LM3530_ALS_Z3T_REG 0x73 #define LM3530_ALS_Z4T_REG 0x74 -#define LM3530_REG_MAX 15 +#define LM3530_REG_MAX 14 /* General Control Register */ #define LM3530_EN_I2C_SHIFT (0) @@ -80,6 +79,9 @@ #define LM3530_DEF_ZT_3 (0x33) #define LM3530_DEF_ZT_4 (0x19) +/* 7 bits are used for the brightness : LM3530_BRT_CTRL_REG */ +#define MAX_BRIGHTNESS (127) + struct lm3530_mode_map { const char *mode; enum lm3530_mode mode_val; @@ -115,7 +117,6 @@ static const u8 lm3530_reg[LM3530_REG_MAX] = { LM3530_GEN_CONFIG, LM3530_ALS_CONFIG, LM3530_BRT_RAMP_RATE, - LM3530_ALS_ZONE_REG, LM3530_ALS_IMP_SELECT, LM3530_BRT_CTRL_REG, LM3530_ALS_ZB0_REG, @@ -152,27 +153,35 @@ static int lm3530_init_registers(struct lm3530_data *drvdata) u8 reg_val[LM3530_REG_MAX]; u8 zones[LM3530_ALS_ZB_MAX]; u32 als_vmin, als_vmax, als_vstep; - struct lm3530_platform_data *pltfm = drvdata->pdata; + struct lm3530_platform_data *pdata = drvdata->pdata; struct i2c_client *client = drvdata->client; + struct lm3530_pwm_data *pwm = &pdata->pwm_data; - gen_config = (pltfm->brt_ramp_law << LM3530_RAMP_LAW_SHIFT) | - ((pltfm->max_current & 7) << LM3530_MAX_CURR_SHIFT); + gen_config = (pdata->brt_ramp_law << LM3530_RAMP_LAW_SHIFT) | + ((pdata->max_current & 7) << LM3530_MAX_CURR_SHIFT); - if (drvdata->mode == LM3530_BL_MODE_MANUAL || - drvdata->mode == LM3530_BL_MODE_ALS) - gen_config |= (LM3530_ENABLE_I2C); + switch (drvdata->mode) { + case LM3530_BL_MODE_MANUAL: + case LM3530_BL_MODE_ALS: + gen_config |= LM3530_ENABLE_I2C; + break; + case LM3530_BL_MODE_PWM: + gen_config |= LM3530_ENABLE_PWM | LM3530_ENABLE_PWM_SIMPLE | + (pdata->pwm_pol_hi << LM3530_PWM_POL_SHIFT); + break; + } if (drvdata->mode == LM3530_BL_MODE_ALS) { - if (pltfm->als_vmax == 0) { - pltfm->als_vmin = 0; - pltfm->als_vmax = LM3530_ALS_WINDOW_mV; + if (pdata->als_vmax == 0) { + pdata->als_vmin = 0; + pdata->als_vmax = LM3530_ALS_WINDOW_mV; } - als_vmin = pltfm->als_vmin; - als_vmax = pltfm->als_vmax; + als_vmin = pdata->als_vmin; + als_vmax = pdata->als_vmax; if ((als_vmax - als_vmin) > LM3530_ALS_WINDOW_mV) - pltfm->als_vmax = als_vmax = + pdata->als_vmax = als_vmax = als_vmin + LM3530_ALS_WINDOW_mV; /* n zone boundary makes n+1 zones */ @@ -184,44 +193,41 @@ static int lm3530_init_registers(struct lm3530_data *drvdata) / 1000; als_config = - (pltfm->als_avrg_time << LM3530_ALS_AVG_TIME_SHIFT) | + (pdata->als_avrg_time << LM3530_ALS_AVG_TIME_SHIFT) | (LM3530_ENABLE_ALS) | - (pltfm->als_input_mode << LM3530_ALS_SEL_SHIFT); + (pdata->als_input_mode << LM3530_ALS_SEL_SHIFT); als_imp_sel = - (pltfm->als1_resistor_sel << LM3530_ALS1_IMP_SHIFT) | - (pltfm->als2_resistor_sel << LM3530_ALS2_IMP_SHIFT); + (pdata->als1_resistor_sel << LM3530_ALS1_IMP_SHIFT) | + (pdata->als2_resistor_sel << LM3530_ALS2_IMP_SHIFT); } - if (drvdata->mode == LM3530_BL_MODE_PWM) - gen_config |= (LM3530_ENABLE_PWM) | - (pltfm->pwm_pol_hi << LM3530_PWM_POL_SHIFT) | - (LM3530_ENABLE_PWM_SIMPLE); - - brt_ramp = (pltfm->brt_ramp_fall << LM3530_BRT_RAMP_FALL_SHIFT) | - (pltfm->brt_ramp_rise << LM3530_BRT_RAMP_RISE_SHIFT); + brt_ramp = (pdata->brt_ramp_fall << LM3530_BRT_RAMP_FALL_SHIFT) | + (pdata->brt_ramp_rise << LM3530_BRT_RAMP_RISE_SHIFT); if (drvdata->brightness) brightness = drvdata->brightness; else - brightness = drvdata->brightness = pltfm->brt_val; + brightness = drvdata->brightness = pdata->brt_val; + + if (brightness > drvdata->led_dev.max_brightness) + brightness = drvdata->led_dev.max_brightness; reg_val[0] = gen_config; /* LM3530_GEN_CONFIG */ reg_val[1] = als_config; /* LM3530_ALS_CONFIG */ reg_val[2] = brt_ramp; /* LM3530_BRT_RAMP_RATE */ - reg_val[3] = 0x00; /* LM3530_ALS_ZONE_REG */ - reg_val[4] = als_imp_sel; /* LM3530_ALS_IMP_SELECT */ - reg_val[5] = brightness; /* LM3530_BRT_CTRL_REG */ - reg_val[6] = zones[0]; /* LM3530_ALS_ZB0_REG */ - reg_val[7] = zones[1]; /* LM3530_ALS_ZB1_REG */ - reg_val[8] = zones[2]; /* LM3530_ALS_ZB2_REG */ - reg_val[9] = zones[3]; /* LM3530_ALS_ZB3_REG */ - reg_val[10] = LM3530_DEF_ZT_0; /* LM3530_ALS_Z0T_REG */ - reg_val[11] = LM3530_DEF_ZT_1; /* LM3530_ALS_Z1T_REG */ - reg_val[12] = LM3530_DEF_ZT_2; /* LM3530_ALS_Z2T_REG */ - reg_val[13] = LM3530_DEF_ZT_3; /* LM3530_ALS_Z3T_REG */ - reg_val[14] = LM3530_DEF_ZT_4; /* LM3530_ALS_Z4T_REG */ + reg_val[3] = als_imp_sel; /* LM3530_ALS_IMP_SELECT */ + reg_val[4] = brightness; /* LM3530_BRT_CTRL_REG */ + reg_val[5] = zones[0]; /* LM3530_ALS_ZB0_REG */ + reg_val[6] = zones[1]; /* LM3530_ALS_ZB1_REG */ + reg_val[7] = zones[2]; /* LM3530_ALS_ZB2_REG */ + reg_val[8] = zones[3]; /* LM3530_ALS_ZB3_REG */ + reg_val[9] = LM3530_DEF_ZT_0; /* LM3530_ALS_Z0T_REG */ + reg_val[10] = LM3530_DEF_ZT_1; /* LM3530_ALS_Z1T_REG */ + reg_val[11] = LM3530_DEF_ZT_2; /* LM3530_ALS_Z2T_REG */ + reg_val[12] = LM3530_DEF_ZT_3; /* LM3530_ALS_Z3T_REG */ + reg_val[13] = LM3530_DEF_ZT_4; /* LM3530_ALS_Z4T_REG */ if (!drvdata->enable) { ret = regulator_enable(drvdata->regulator); @@ -234,6 +240,15 @@ static int lm3530_init_registers(struct lm3530_data *drvdata) } for (i = 0; i < LM3530_REG_MAX; i++) { + /* do not update brightness register when pwm mode */ + if (lm3530_reg[i] == LM3530_BRT_CTRL_REG && + drvdata->mode == LM3530_BL_MODE_PWM) { + if (pwm->pwm_set_intensity) + pwm->pwm_set_intensity(reg_val[i], + drvdata->led_dev.max_brightness); + continue; + } + ret = i2c_smbus_write_byte_data(client, lm3530_reg[i], reg_val[i]); if (ret) @@ -249,6 +264,9 @@ static void lm3530_brightness_set(struct led_classdev *led_cdev, int err; struct lm3530_data *drvdata = container_of(led_cdev, struct lm3530_data, led_dev); + struct lm3530_platform_data *pdata = drvdata->pdata; + struct lm3530_pwm_data *pwm = &pdata->pwm_data; + u8 max_brightness = led_cdev->max_brightness; switch (drvdata->mode) { case LM3530_BL_MODE_MANUAL: @@ -264,12 +282,12 @@ static void lm3530_brightness_set(struct led_classdev *led_cdev, /* set the brightness in brightness control register*/ err = i2c_smbus_write_byte_data(drvdata->client, - LM3530_BRT_CTRL_REG, brt_val / 2); + LM3530_BRT_CTRL_REG, brt_val); if (err) dev_err(&drvdata->client->dev, "Unable to set brightness: %d\n", err); else - drvdata->brightness = brt_val / 2; + drvdata->brightness = brt_val; if (brt_val == 0) { err = regulator_disable(drvdata->regulator); @@ -282,6 +300,8 @@ static void lm3530_brightness_set(struct led_classdev *led_cdev, case LM3530_BL_MODE_ALS: break; case LM3530_BL_MODE_PWM: + if (pwm->pwm_set_intensity) + pwm->pwm_set_intensity(brt_val, max_brightness); break; default: break; @@ -291,11 +311,11 @@ static void lm3530_brightness_set(struct led_classdev *led_cdev, static ssize_t lm3530_mode_get(struct device *dev, struct device_attribute *attr, char *buf) { - struct i2c_client *client = container_of( - dev->parent, struct i2c_client, dev); - struct lm3530_data *drvdata = i2c_get_clientdata(client); + struct led_classdev *led_cdev = dev_get_drvdata(dev); + struct lm3530_data *drvdata; int i, len = 0; + drvdata = container_of(led_cdev, struct lm3530_data, led_dev); for (i = 0; i < ARRAY_SIZE(mode_map); i++) if (drvdata->mode == mode_map[i].mode_val) len += sprintf(buf + len, "[%s] ", mode_map[i].mode); @@ -310,26 +330,26 @@ static ssize_t lm3530_mode_get(struct device *dev, static ssize_t lm3530_mode_set(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { - int err; - struct i2c_client *client = container_of( - dev->parent, struct i2c_client, dev); - struct lm3530_data *drvdata = i2c_get_clientdata(client); - int mode; + struct led_classdev *led_cdev = dev_get_drvdata(dev); + struct lm3530_data *drvdata; + struct lm3530_pwm_data *pwm; + u8 max_brightness; + int mode, err; + drvdata = container_of(led_cdev, struct lm3530_data, led_dev); + pwm = &drvdata->pdata->pwm_data; + max_brightness = led_cdev->max_brightness; mode = lm3530_get_mode_from_str(buf); if (mode < 0) { dev_err(dev, "Invalid mode\n"); return -EINVAL; } - if (mode == LM3530_BL_MODE_MANUAL) - drvdata->mode = LM3530_BL_MODE_MANUAL; - else if (mode == LM3530_BL_MODE_ALS) - drvdata->mode = LM3530_BL_MODE_ALS; - else if (mode == LM3530_BL_MODE_PWM) { - dev_err(dev, "PWM mode not supported\n"); - return -EINVAL; - } + drvdata->mode = mode; + + /* set pwm to low if unnecessary */ + if (mode != LM3530_BL_MODE_PWM && pwm->pwm_set_intensity) + pwm->pwm_set_intensity(0, max_brightness); err = lm3530_init_registers(drvdata); if (err) { @@ -380,6 +400,7 @@ static int __devinit lm3530_probe(struct i2c_client *client, drvdata->enable = false; drvdata->led_dev.name = LM3530_LED_DEV; drvdata->led_dev.brightness_set = lm3530_brightness_set; + drvdata->led_dev.max_brightness = MAX_BRIGHTNESS; i2c_set_clientdata(client, drvdata); |
