Lines Matching +full:pwm +full:- +full:off +full:- +full:delay +full:- +full:ms
1 // SPDX-License-Identifier: GPL-2.0-only
5 * Copyright (C) 2007-2009 Nokia Corporation
18 #include <linux/delay.h>
46 #define LM8323_CMD_PWM_WRITE 0x95 /* Write PWM script. */
47 #define LM8323_CMD_START_PWM 0x96 /* Start PWM engine. */
48 #define LM8323_CMD_STOP_PWM 0x97 /* Stop PWM engine. */
88 /* Commands for PWM engine; feed in with PWM_WRITE. */
89 /* Load ramp counter from duty cycle field (range 0 - 0xff). */
127 /* pwm lock */
148 struct lm8323_pwm pwm[LM8323_NUM_PWMS]; member
152 #define dev_to_lm8323(d) container_of(d, struct lm8323_chip, client->dev)
172 dev_err(&lm->client->dev, "tried to send %d bytes\n", len); in lm8323_write()
186 ret = i2c_master_send(lm->client, data, len); in lm8323_write()
187 if (unlikely(ret == -EREMOTEIO)) in lm8323_write()
188 ret = i2c_master_send(lm->client, data, len); in lm8323_write()
190 dev_err(&lm->client->dev, "sent %d bytes of %d total\n", in lm8323_write()
208 ret = i2c_master_send(lm->client, &cmd, 1); in lm8323_read()
209 if (unlikely(ret == -EREMOTEIO)) in lm8323_read()
210 ret = i2c_master_send(lm->client, &cmd, 1); in lm8323_read()
212 dev_err(&lm->client->dev, "sending read cmd 0x%02x failed\n", in lm8323_read()
217 ret = i2c_master_recv(lm->client, buf, len); in lm8323_read()
219 dev_err(&lm->client->dev, "wanted %d bytes, got %d\n", in lm8323_read()
234 * The signals are AT-style: the low 7 bits are the keycode, and the top
251 int old_keys_down = lm->keys_down; in process_keys()
262 dev_err(&lm->client->dev, "Failed reading fifo \n"); in process_keys()
270 unsigned short keycode = lm->keymap[key]; in process_keys()
272 dev_vdbg(&lm->client->dev, "key 0x%02x %s\n", in process_keys()
275 if (lm->kp_enabled) { in process_keys()
276 input_event(lm->idev, EV_MSC, MSC_SCAN, key); in process_keys()
277 input_report_key(lm->idev, keycode, isdown); in process_keys()
278 input_sync(lm->idev); in process_keys()
282 lm->keys_down++; in process_keys()
284 lm->keys_down--; in process_keys()
292 if (!old_keys_down && lm->keys_down) in process_keys()
294 if (old_keys_down && !lm->keys_down) in process_keys()
295 lm8323_set_active_time(lm, lm->active_time); in process_keys()
304 dev_vdbg(&lm->client->dev, "fifo overflow!\n"); in lm8323_process_error()
306 dev_vdbg(&lm->client->dev, in lm8323_process_error()
309 dev_vdbg(&lm->client->dev, in lm8323_process_error()
312 dev_vdbg(&lm->client->dev, "bad command parameter\n"); in lm8323_process_error()
324 int keysize = (lm->size_x << 4) | lm->size_y; in lm8323_configure()
326 int debounce = lm->debounce_time >> 2; in lm8323_configure()
327 int active = lm->active_time >> 2; in lm8323_configure()
331 * a close-run thing, give ourselves a 12ms buffer. in lm8323_configure()
339 lm8323_set_active_time(lm, lm->active_time); in lm8323_configure()
352 static void pwm_done(struct lm8323_pwm *pwm) in pwm_done() argument
354 guard(mutex)(&pwm->lock); in pwm_done()
356 pwm->running = false; in pwm_done()
357 if (pwm->desired_brightness != pwm->brightness) in pwm_done()
358 schedule_work(&pwm->work); in pwm_done()
371 guard(mutex)(&lm->lock); in lm8323_irq()
378 dev_vdbg(&lm->client->dev, "rotator fired\n"); in lm8323_irq()
381 dev_vdbg(&lm->client->dev, "error!\n"); in lm8323_irq()
385 dev_err(&lm->client->dev, "chip lost config; " in lm8323_irq()
391 dev_vdbg(&lm->client->dev, in lm8323_irq()
392 "pwm%d engine completed\n", i); in lm8323_irq()
393 pwm_done(&lm->pwm[i]); in lm8323_irq()
410 return -EIO; in lm8323_read_id()
415 static void lm8323_write_pwm_one(struct lm8323_pwm *pwm, int pos, u16 cmd) in lm8323_write_pwm_one() argument
417 lm8323_write(pwm->chip, 4, LM8323_CMD_PWM_WRITE, (pos << 2) | pwm->id, in lm8323_write_pwm_one()
422 * Write a script into a given PWM engine, concluding with PWM_END.
425 * will be kept running at the final PWM level indefinitely.
427 static void lm8323_write_pwm(struct lm8323_pwm *pwm, int kill, in lm8323_write_pwm() argument
433 lm8323_write_pwm_one(pwm, i, cmds[i]); in lm8323_write_pwm()
435 lm8323_write_pwm_one(pwm, i++, PWM_END(kill)); in lm8323_write_pwm()
436 lm8323_write(pwm->chip, 2, LM8323_CMD_START_PWM, pwm->id); in lm8323_write_pwm()
437 pwm->running = true; in lm8323_write_pwm()
442 struct lm8323_pwm *pwm = work_to_pwm(work); in lm8323_pwm_work() local
447 guard(mutex)(&pwm->lock); in lm8323_pwm_work()
452 * case we will be called again when the previous PWM script in lm8323_pwm_work()
455 if (pwm->running || pwm->desired_brightness == pwm->brightness) in lm8323_pwm_work()
458 kill = (pwm->desired_brightness == 0); in lm8323_pwm_work()
459 up = (pwm->desired_brightness > pwm->brightness); in lm8323_pwm_work()
460 steps = abs(pwm->desired_brightness - pwm->brightness); in lm8323_pwm_work()
463 * Convert time (in ms) into a divisor (512 or 16 on a refclk of in lm8323_pwm_work()
466 if ((pwm->fade_time / steps) > (32768 / 512)) { in lm8323_pwm_work()
474 perstep = (hz * pwm->fade_time) / (steps * 1000); in lm8323_pwm_work()
486 steps -= s; in lm8323_pwm_work()
489 lm8323_write_pwm(pwm, kill, num_cmds, pwm_cmds); in lm8323_pwm_work()
490 pwm->brightness = pwm->desired_brightness; in lm8323_pwm_work()
496 struct lm8323_pwm *pwm = cdev_to_pwm(led_cdev); in lm8323_pwm_set_brightness() local
497 struct lm8323_chip *lm = pwm->chip; in lm8323_pwm_set_brightness()
499 scoped_guard(mutex, &pwm->lock) { in lm8323_pwm_set_brightness()
500 pwm->desired_brightness = brightness; in lm8323_pwm_set_brightness()
504 schedule_work(&pwm->work); in lm8323_pwm_set_brightness()
507 * Schedule PWM work as usual unless we are going into suspend in lm8323_pwm_set_brightness()
509 scoped_guard(mutex, &lm->lock) { in lm8323_pwm_set_brightness()
510 if (likely(!lm->pm_suspend)) in lm8323_pwm_set_brightness()
511 schedule_work(&pwm->work); in lm8323_pwm_set_brightness()
513 lm8323_pwm_work(&pwm->work); in lm8323_pwm_set_brightness()
522 struct lm8323_pwm *pwm = cdev_to_pwm(led_cdev); in lm8323_pwm_show_time() local
524 return sprintf(buf, "%d\n", pwm->fade_time); in lm8323_pwm_show_time()
531 struct lm8323_pwm *pwm = cdev_to_pwm(led_cdev); in lm8323_pwm_store_time() local
539 pwm->fade_time = time; in lm8323_pwm_store_time()
554 struct lm8323_pwm *pwm; in init_pwm() local
559 pwm = &lm->pwm[id - 1]; in init_pwm()
561 pwm->id = id; in init_pwm()
562 pwm->fade_time = 0; in init_pwm()
563 pwm->brightness = 0; in init_pwm()
564 pwm->desired_brightness = 0; in init_pwm()
565 pwm->running = false; in init_pwm()
566 pwm->enabled = false; in init_pwm()
567 INIT_WORK(&pwm->work, lm8323_pwm_work); in init_pwm()
568 mutex_init(&pwm->lock); in init_pwm()
569 pwm->chip = lm; in init_pwm()
572 pwm->cdev.name = name; in init_pwm()
573 pwm->cdev.brightness_set = lm8323_pwm_set_brightness; in init_pwm()
574 pwm->cdev.groups = lm8323_pwm_groups; in init_pwm()
576 err = devm_led_classdev_register(dev, &pwm->cdev); in init_pwm()
578 dev_err(dev, "couldn't register PWM %d: %d\n", id, err); in init_pwm()
581 pwm->enabled = true; in init_pwm()
592 return sprintf(buf, "%u\n", !lm->kp_enabled); in lm8323_show_disable()
607 guard(mutex)(&lm->lock); in lm8323_set_disable()
609 lm->kp_enabled = !i; in lm8323_set_disable()
623 struct lm8323_platform_data *pdata = dev_get_platdata(&client->dev); in lm8323_probe()
626 int pwm; in lm8323_probe() local
631 if (!pdata || !pdata->size_x || !pdata->size_y) { in lm8323_probe()
632 dev_err(&client->dev, "missing platform_data\n"); in lm8323_probe()
633 return -EINVAL; in lm8323_probe()
636 if (pdata->size_x > 8) { in lm8323_probe()
637 dev_err(&client->dev, "invalid x size %d specified\n", in lm8323_probe()
638 pdata->size_x); in lm8323_probe()
639 return -EINVAL; in lm8323_probe()
642 if (pdata->size_y > 12) { in lm8323_probe()
643 dev_err(&client->dev, "invalid y size %d specified\n", in lm8323_probe()
644 pdata->size_y); in lm8323_probe()
645 return -EINVAL; in lm8323_probe()
648 lm = devm_kzalloc(&client->dev, sizeof(*lm), GFP_KERNEL); in lm8323_probe()
650 return -ENOMEM; in lm8323_probe()
652 idev = devm_input_allocate_device(&client->dev); in lm8323_probe()
654 return -ENOMEM; in lm8323_probe()
656 lm->client = client; in lm8323_probe()
657 lm->idev = idev; in lm8323_probe()
658 mutex_init(&lm->lock); in lm8323_probe()
660 lm->size_x = pdata->size_x; in lm8323_probe()
661 lm->size_y = pdata->size_y; in lm8323_probe()
662 dev_vdbg(&client->dev, "Keypad size: %d x %d\n", in lm8323_probe()
663 lm->size_x, lm->size_y); in lm8323_probe()
665 lm->debounce_time = pdata->debounce_time; in lm8323_probe()
666 lm->active_time = pdata->active_time; in lm8323_probe()
672 * 100ms until we can configure. in lm8323_probe()
680 dev_err(&client->dev, in lm8323_probe()
692 dev_err(&client->dev, "device not found\n"); in lm8323_probe()
693 return -ENODEV; in lm8323_probe()
696 for (pwm = 0; pwm < LM8323_NUM_PWMS; pwm++) { in lm8323_probe()
697 err = init_pwm(lm, pwm + 1, &client->dev, in lm8323_probe()
698 pdata->pwm_names[pwm]); in lm8323_probe()
703 lm->kp_enabled = true; in lm8323_probe()
705 idev->name = pdata->name ? : "LM8323 keypad"; in lm8323_probe()
706 snprintf(lm->phys, sizeof(lm->phys), in lm8323_probe()
707 "%s/input-kp", dev_name(&client->dev)); in lm8323_probe()
708 idev->phys = lm->phys; in lm8323_probe()
710 idev->evbit[0] = BIT(EV_KEY) | BIT(EV_MSC); in lm8323_probe()
711 __set_bit(MSC_SCAN, idev->mscbit); in lm8323_probe()
713 __set_bit(pdata->keymap[i], idev->keybit); in lm8323_probe()
714 lm->keymap[i] = pdata->keymap[i]; in lm8323_probe()
716 __clear_bit(KEY_RESERVED, idev->keybit); in lm8323_probe()
718 if (pdata->repeat) in lm8323_probe()
719 __set_bit(EV_REP, idev->evbit); in lm8323_probe()
723 dev_dbg(&client->dev, "error registering input device\n"); in lm8323_probe()
727 err = devm_request_threaded_irq(&client->dev, client->irq, in lm8323_probe()
732 dev_err(&client->dev, "could not get IRQ %d\n", client->irq); in lm8323_probe()
738 device_init_wakeup(&client->dev, 1); in lm8323_probe()
739 enable_irq_wake(client->irq); in lm8323_probe()
745 * We don't need to explicitly suspend the chip, as it already switches off
754 irq_set_irq_wake(client->irq, 0); in lm8323_suspend()
755 disable_irq(client->irq); in lm8323_suspend()
757 scoped_guard(mutex, &lm->lock) { in lm8323_suspend()
758 lm->pm_suspend = true; in lm8323_suspend()
762 if (lm->pwm[i].enabled) in lm8323_suspend()
763 led_classdev_suspend(&lm->pwm[i].cdev); in lm8323_suspend()
774 scoped_guard(mutex, &lm->lock) { in lm8323_resume()
775 lm->pm_suspend = false; in lm8323_resume()
779 if (lm->pwm[i].enabled) in lm8323_resume()
780 led_classdev_resume(&lm->pwm[i].cdev); in lm8323_resume()
782 enable_irq(client->irq); in lm8323_resume()
783 irq_set_irq_wake(client->irq, 1); in lm8323_resume()