static ssize_t led_r_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { struct leds_dev_data *info = dev_get_drvdata(dev); struct pm8xxx_led_config *led_cfg; unsigned int brightness = 0; unsigned int num_digits = size; unsigned int loop_cnt = 0; int temp; printk(KERN_DEBUG "led_r brightness =%s, numdigs=%u\n", buf, num_digits); while ((buf[loop_cnt] >= '0') && (buf[loop_cnt] <= '9') && (loop_cnt < num_digits)) { brightness = brightness*10 + (buf[loop_cnt] - '0'); loop_cnt++; } printk(KERN_DEBUG "led_r brightness =%u\n", brightness); if (brightness < 0 || brightness > 255) { printk(KERN_WARNING "led_r brightness is out of range"); return -1; } temp = pm8xxx_led_get(&info->led[PM8XXX_LED_PAT7_RED].cdev); if (brightness == 0 && temp == 0) return size; if (atomic_read(&info->op_flag)) atomic_set(&info->op_flag, 0); pm8xxx_led_work_pat_led_off(info); mutex_lock(&info->led_work_lock); led_cfg = &info->pdata->configs[PM8XXX_LED_PAT7_RED]; pm8xxx_set_led_mode_and_max_brightness(&info->led[PM8XXX_LED_PAT7_RED], led_cfg->mode, led_cfg->max_current); __pm8xxx_led_work(&info->led[PM8XXX_LED_PAT7_RED], led_cfg->max_current); if (led_cfg->mode != PM8XXX_LED_MODE_MANUAL) pm8xxx_led_pwm_configure(&info->led[PM8XXX_LED_PAT7_RED], 0, 0); if (brightness && (info->pdata->led_power_on)) info->pdata->led_power_on(1); pm8xxx_led_set(&info->led[PM8XXX_LED_PAT7_RED].cdev, brightness); mutex_unlock(&info->led_work_lock); return size; }
static void pm8xxx_led_work(struct work_struct *work) { int rc; struct pm8xxx_led_data *led = container_of(work, struct pm8xxx_led_data, work); if (led->pwm_dev == NULL) { __pm8xxx_led_work(led, led->cdev.brightness); } else { rc = pm8xxx_led_pwm_work(led); if (rc) pr_err("could not configure PWM mode for LED:%d\n", led->id); } }
static void pm8xxx_led_work_pat_led_off(struct leds_dev_data *info) { int loop_cnt; mutex_lock(&info->led_work_lock); if (info->pdata->led_power_on) info->pdata->led_power_on(0); for (loop_cnt = 0 ; loop_cnt < ((info->pdata->led_core->num_leds) - 1) ; loop_cnt++) { __pm8xxx_led_work(&info->led[loop_cnt], 0); if (info->led[loop_cnt].pwm_dev != NULL) pwm_free(info->led[loop_cnt].pwm_dev); } mutex_unlock(&info->led_work_lock); }
static void pm8xxx_led_work_pat_full_chrg(struct work_struct *work) { struct leds_dev_data *info = container_of(work, struct leds_dev_data, work_pat_full_chrg); struct pm8xxx_led_config *led_cfg; if (!atomic_read(&info->op_flag)) { pr_info("LED turns off before turns on, op:%d\n", atomic_read(&info->op_flag)); return; } pm8xxx_led_work_pat_led_off(info); mutex_lock(&info->led_work_lock); led_cfg = &info->pdata->configs[PM8XXX_LED_PAT5_GREEN]; pm8xxx_set_led_mode_and_max_brightness( &info->led[PM8XXX_LED_PAT5_GREEN], led_cfg->mode, led_cfg->max_current); __pm8xxx_led_work(&info->led[PM8XXX_LED_PAT5_GREEN], led_cfg->max_current); if (low_powermode) { led_cfg->pwm_duty_cycles->duty_pcts[0] = 100/LOW_POWERMODE_DIVIDER; led_cfg->pwm_duty_cycles->duty_pcts[1] = 100/LOW_POWERMODE_DIVIDER; } else { led_cfg->pwm_duty_cycles->duty_pcts[0] = 100; led_cfg->pwm_duty_cycles->duty_pcts[1] = 100; } if (led_cfg->mode != PM8XXX_LED_MODE_MANUAL) pm8xxx_led_pwm_configure(&info->led[PM8XXX_LED_PAT5_GREEN], 0, 0); pm8xxx_led_set(&info->led[PM8XXX_LED_PAT5_GREEN].cdev, led_cfg->max_current); mutex_unlock(&info->led_work_lock); }
static void pm8xxx_led_work_pat_powering(struct work_struct *work) { struct leds_dev_data *info = container_of(work, struct leds_dev_data, work_pat_powering); struct pm8xxx_led_config *led_cfg; int loop_cnt; if (!atomic_read(&info->op_flag)) { pr_info("LED turns off before turns on, op:%d\n", atomic_read(&info->op_flag)); return; } pm8xxx_led_work_pat_led_off(info); mutex_lock(&info->led_work_lock); for (loop_cnt = PM8XXX_LED_PAT6_GREEN ; loop_cnt <= PM8XXX_LED_PAT6_BLUE ; loop_cnt++) { led_cfg = &info->pdata->configs[loop_cnt]; pm8xxx_set_led_mode_and_max_brightness(&info->led[loop_cnt], led_cfg->mode, led_cfg->max_current); __pm8xxx_led_work(&info->led[loop_cnt], led_cfg->max_current); if (led_cfg->mode != PM8XXX_LED_MODE_MANUAL) pm8xxx_led_pwm_configure(&info->led[loop_cnt], 200, 200); } pm8xxx_led_set(&info->led[PM8XXX_LED_PAT6_GREEN].cdev, led_cfg->max_current); pm8xxx_led_set(&info->led[PM8XXX_LED_PAT6_BLUE].cdev, led_cfg->max_current); mutex_unlock(&info->led_work_lock); }
static ssize_t led_blink_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { struct leds_dev_data *info = dev_get_drvdata(dev); struct pm8xxx_led_config *led_cfg; unsigned int brightness_r = 0; unsigned int brightness_g = 0; unsigned int brightness_b = 0; unsigned int loop_cnt = 0; unsigned int delayon = 0; unsigned int delayoff = 0; unsigned int argb_count = 0; bool is_blinking; printk(KERN_ALERT "[LED_blink_store] is \"%s\" (pid %i)\n", current->comm, current->pid); printk(KERN_ALERT "led_blink input =%s, size=%d\n", buf, size); if (size < 7) { printk(KERN_DEBUG "led_blink: Invlid input\n"); return size; } if (buf[8] == ' ') { /*case of RGB delay_on delay_off*/ for (loop_cnt = 9; loop_cnt < size-1; loop_cnt++) { delayon = delayon*10 + (buf[loop_cnt] - '0'); if (buf[loop_cnt+1] == ' ') { loop_cnt += 2; break; } } for (; loop_cnt < size-1; loop_cnt++) delayoff = delayoff*10 + (buf[loop_cnt] - '0'); } else if (buf[10] == ' ') { /*case of ARGB delay_on delay_off*/ argb_count = 1; for (loop_cnt = 11; loop_cnt < size-1; loop_cnt++) { delayon = delayon*10 + (buf[loop_cnt] - '0'); if (buf[loop_cnt+1] == ' ') { loop_cnt += 2; break; } } for (; loop_cnt < size-1; loop_cnt++) delayoff = delayoff*10 + (buf[loop_cnt] - '0'); } else if (size > 9) { /*case of ARGB*/ argb_count = 1; } atomic_set(&info->op_flag , 0); /*buf[0], buf[1] contains 0x, so ignore it. case of RGB*/ if (!argb_count) { brightness_r = hex_to_dec(buf[2], buf[3]); brightness_g = hex_to_dec(buf[4], buf[5]); brightness_b = hex_to_dec(buf[6], buf[7]); } /*buf[0], buf[1] contains 0x, so ignore it. buf[2], buf[3] contains A (alpha value), ignore it.case of ARGB*/ else { brightness_r = hex_to_dec(buf[4], buf[5]); brightness_g = hex_to_dec(buf[6], buf[7]); brightness_b = hex_to_dec(buf[8], buf[9]); } is_blinking = delayon > 0 || delayoff > 0; pm8xxx_led_work_pat_led_off(info); mutex_lock(&info->led_work_lock); led_cfg = &info->pdata->configs[PM8XXX_LED_PAT8_BLUE]; brightness_b = brightness_b * 100 / 255; led_cfg->pwm_duty_cycles->duty_pcts[0] = is_blinking ? 0 : brightness_b; led_cfg->pwm_duty_cycles->duty_pcts[1] = brightness_b; pm8xxx_set_led_mode_and_max_brightness(&info->led[PM8XXX_LED_PAT8_BLUE], led_cfg->mode, led_cfg->max_current); __pm8xxx_led_work(&info->led[PM8XXX_LED_PAT8_BLUE], led_cfg->max_current); if (led_cfg->mode != PM8XXX_LED_MODE_MANUAL) pm8xxx_led_pwm_configure(&info->led[PM8XXX_LED_PAT8_BLUE], delayoff, delayon); led_cfg = &info->pdata->configs[PM8XXX_LED_PAT8_GREEN]; brightness_g = brightness_g * 100 / 255; led_cfg->pwm_duty_cycles->duty_pcts[0] = is_blinking ? 0 : brightness_g; led_cfg->pwm_duty_cycles->duty_pcts[1] = brightness_g; pm8xxx_set_led_mode_and_max_brightness( &info->led[PM8XXX_LED_PAT8_GREEN], led_cfg->mode, led_cfg->max_current); __pm8xxx_led_work(&info->led[PM8XXX_LED_PAT8_GREEN], led_cfg->max_current); if (led_cfg->mode != PM8XXX_LED_MODE_MANUAL) pm8xxx_led_pwm_configure(&info->led[PM8XXX_LED_PAT8_GREEN], delayoff, delayon); led_cfg = &info->pdata->configs[PM8XXX_LED_PAT8_RED]; brightness_r = brightness_r * 100 / 255; led_cfg->pwm_duty_cycles->duty_pcts[0] = is_blinking ? 0 : brightness_r; led_cfg->pwm_duty_cycles->duty_pcts[1] = brightness_r; pm8xxx_set_led_mode_and_max_brightness(&info->led[PM8XXX_LED_PAT8_RED], led_cfg->mode, led_cfg->max_current); __pm8xxx_led_work(&info->led[PM8XXX_LED_PAT8_RED], led_cfg->max_current); if (led_cfg->mode != PM8XXX_LED_MODE_MANUAL) pm8xxx_led_pwm_configure(&info->led[PM8XXX_LED_PAT8_RED], delayoff, delayon); if ((brightness_r || brightness_g || brightness_b) && (info->pdata->led_power_on)) info->pdata->led_power_on(1); printk(KERN_DEBUG "[LED] USER : R:%d,G:%d,B:%d\n", brightness_r, brightness_g, brightness_b); pm8xxx_led_set(&info->led[PM8XXX_LED_PAT8_RED].cdev, led_cfg->max_current); pm8xxx_led_set(&info->led[PM8XXX_LED_PAT8_GREEN].cdev, led_cfg->max_current); pm8xxx_led_set(&info->led[PM8XXX_LED_PAT8_BLUE].cdev, led_cfg->max_current); mutex_unlock(&info->led_work_lock); return size; }
static int __devinit pm8xxx_led_probe(struct platform_device *pdev) { const struct led_platform_data *pcore_data; struct led_info *curr_led; struct pm8xxx_led_config *led_cfg; struct pm8xxx_led_data *led, *led_dat; struct leds_dev_data *info; struct pm8xxx_led_platform_data *pdata ; int rc = -1, i = 0; pdata = pdev->dev.platform_data; if (pdata == NULL) { dev_err(&pdev->dev, "platform data not supplied\n"); return -EINVAL; } pcore_data = pdata->led_core; if (pcore_data->num_leds != pdata->num_configs) { dev_err(&pdev->dev, "#no. of led configs and #no. of led" "entries are not equal\n"); return -EINVAL; } led = kcalloc(pcore_data->num_leds, sizeof(*led), GFP_KERNEL); if (led == NULL) { dev_err(&pdev->dev, "failed to alloc memory\n"); return -ENOMEM; } info = kzalloc(sizeof(*info), GFP_KERNEL); if (!info) { dev_err(&pdev->dev, "fail to memory allocation.\n"); rc = -ENOMEM; goto fail_mem_check; } info->pdata = pdata; info->led = led; for (i = 0; i < pcore_data->num_leds; i++) { curr_led = &pcore_data->leds[i]; led_dat = &led[i]; led_cfg = &pdata->configs[i]; led_dat->id = led_cfg->id; led_dat->pwm_channel = led_cfg->pwm_channel; led_dat->pwm_period_us = led_cfg->pwm_period_us; led_dat->pwm_duty_cycles = led_cfg->pwm_duty_cycles; if (!((led_dat->id >= PM8XXX_ID_LED_KB_LIGHT) && (led_dat->id <= PM8XXX_ID_FLASH_LED_1))) { dev_err(&pdev->dev, "invalid LED ID (%d) specified\n", led_dat->id); rc = -EINVAL; goto fail_id_check; } led_dat->cdev.name = curr_led->name; led_dat->cdev.default_trigger = curr_led->default_trigger; led_dat->cdev.brightness_set = pm8xxx_led_set; led_dat->cdev.brightness_get = pm8xxx_led_get; led_dat->cdev.brightness = LED_OFF; led_dat->cdev.flags = curr_led->flags; led_dat->dev = &pdev->dev; rc = get_init_value(led_dat, &led_dat->reg); if (rc < 0) goto fail_id_check; rc = pm8xxx_set_led_mode_and_max_brightness(led_dat, led_cfg->mode, led_cfg->max_current); if (rc < 0) goto fail_id_check; mutex_init(&led_dat->lock); INIT_WORK(&led_dat->work, pm8xxx_led_work); if (led_dat->id == PM8XXX_ID_LED_KB_LIGHT) __pm8xxx_led_work(led_dat, LED_FULL); else __pm8xxx_led_work(led_dat, LED_OFF); } platform_set_drvdata(pdev, info); led_virtual_dev(info); low_powermode = 0; return 0; fail_id_check: if (i > 0) { for (i = i - 1; i >= 0; i--) { mutex_destroy(&led[i].lock); led_classdev_unregister(&led[i].cdev); if (led[i].pwm_dev != NULL) pwm_free(led[i].pwm_dev); } } kfree(info); fail_mem_check: kfree(led); return rc; }
static int __devinit pm8xxx_led_probe(struct platform_device *pdev) { const struct pm8xxx_led_platform_data *pdata = pdev->dev.platform_data; const struct led_platform_data *pcore_data; struct led_info *curr_led; struct pm8xxx_led_data *led, *led_dat; struct pm8xxx_led_config *led_cfg; int rc, i; if (pdata == NULL) { dev_err(&pdev->dev, "platform data not supplied\n"); return -EINVAL; } pcore_data = pdata->led_core; if (pcore_data->num_leds != pdata->num_configs) { dev_err(&pdev->dev, "#no. of led configs and #no. of led" "entries are not equal\n"); return -EINVAL; } led = kcalloc(pcore_data->num_leds, sizeof(*led), GFP_KERNEL); if (led == NULL) { dev_err(&pdev->dev, "failed to alloc memory\n"); return -ENOMEM; } for (i = 0; i < pcore_data->num_leds; i++) { curr_led = &pcore_data->leds[i]; led_dat = &led[i]; led_cfg = &pdata->configs[i]; led_dat->id = led_cfg->id; led_dat->pwm_channel = led_cfg->pwm_channel; led_dat->pwm_period_us = led_cfg->pwm_period_us; led_dat->pwm_duty_cycles = led_cfg->pwm_duty_cycles; #ifdef CONFIG_MACH_MSM8960_MMI led_dat->led_ctrl = led_cfg->led_ctrl; led_dat->do_blink = 0; if (led_dat->pwm_duty_cycles == NULL) led_dat->pwm_duty_cycles = &pm8xxx_default_pwm_duty_cycles; #endif if (!((led_dat->id >= PM8XXX_ID_LED_KB_LIGHT) && (led_dat->id <= PM8XXX_ID_FLASH_LED_1))) { dev_err(&pdev->dev, "invalid LED ID (%d) specified\n", led_dat->id); rc = -EINVAL; goto fail_id_check; } led_dat->cdev.name = curr_led->name; led_dat->cdev.default_trigger = curr_led->default_trigger; led_dat->cdev.brightness_set = pm8xxx_led_set; led_dat->cdev.brightness_get = pm8xxx_led_get; #ifdef CONFIG_MACH_MSM8960_MMI led_dat->cdev.blink_set = pm8xxx_led_blink_set; #endif led_dat->cdev.brightness = LED_OFF; led_dat->cdev.flags = curr_led->flags; led_dat->dev = &pdev->dev; rc = get_init_value(led_dat, &led_dat->reg); if (rc < 0) goto fail_id_check; rc = pm8xxx_set_led_mode_and_max_brightness(led_dat, led_cfg->mode, led_cfg->max_current); if (rc < 0) goto fail_id_check; mutex_init(&led_dat->lock); INIT_WORK(&led_dat->work, pm8xxx_led_work); rc = led_classdev_register(&pdev->dev, &led_dat->cdev); if (rc) { dev_err(&pdev->dev, "unable to register led %d,rc=%d\n", led_dat->id, rc); goto fail_id_check; } if (led_cfg->mode != PM8XXX_LED_MODE_MANUAL) { __pm8xxx_led_work(led_dat, led_dat->cdev.max_brightness); if (led_dat->pwm_channel != -1) { led_dat->cdev.max_brightness = LED_FULL; rc = pm8xxx_led_pwm_configure(led_dat); if (rc) { dev_err(&pdev->dev, "failed to " "configure LED, error: %d\n", rc); goto fail_id_check; } } } else { __pm8xxx_led_work(led_dat, LED_OFF); } } platform_set_drvdata(pdev, led); return 0; fail_id_check: if (i > 0) { for (i = i - 1; i >= 0; i--) { mutex_destroy(&led[i].lock); led_classdev_unregister(&led[i].cdev); if (led[i].pwm_dev != NULL) pwm_free(led[i].pwm_dev); } } kfree(led); return rc; }