Lines Matching +full:timer +full:- +full:pwm

1 // SPDX-License-Identifier: GPL-2.0-or-later
8 #include <linux/pwm.h>
15 #include <media/rc-core.h>
17 #define DRIVER_NAME "pwm-ir-tx"
18 #define DEVICE_NAME "PWM IR Transmitter"
21 struct pwm_device *pwm; member
22 struct hrtimer timer; member
33 { .compatible = "pwm-ir-tx", },
34 { .compatible = "nokia,n900-ir" },
41 struct pwm_ir *pwm_ir = dev->priv; in pwm_ir_set_duty_cycle()
43 pwm_ir->duty_cycle = duty_cycle; in pwm_ir_set_duty_cycle()
50 struct pwm_ir *pwm_ir = dev->priv; in pwm_ir_set_carrier()
53 return -EINVAL; in pwm_ir_set_carrier()
55 pwm_ir->carrier = carrier; in pwm_ir_set_carrier()
63 struct pwm_ir *pwm_ir = dev->priv; in pwm_ir_tx_sleep()
64 struct pwm_device *pwm = pwm_ir->pwm; in pwm_ir_tx_sleep() local
70 pwm_init_state(pwm, &state); in pwm_ir_tx_sleep()
72 state.period = DIV_ROUND_CLOSEST(NSEC_PER_SEC, pwm_ir->carrier); in pwm_ir_tx_sleep()
73 pwm_set_relative_duty_cycle(&state, pwm_ir->duty_cycle, 100); in pwm_ir_tx_sleep()
79 pwm_apply_might_sleep(pwm, &state); in pwm_ir_tx_sleep()
88 pwm_apply_might_sleep(pwm, &state); in pwm_ir_tx_sleep()
96 struct pwm_ir *pwm_ir = dev->priv; in pwm_ir_tx_atomic()
97 struct pwm_device *pwm = pwm_ir->pwm; in pwm_ir_tx_atomic() local
100 pwm_init_state(pwm, &state); in pwm_ir_tx_atomic()
102 state.period = DIV_ROUND_CLOSEST(NSEC_PER_SEC, pwm_ir->carrier); in pwm_ir_tx_atomic()
103 pwm_set_relative_duty_cycle(&state, pwm_ir->duty_cycle, 100); in pwm_ir_tx_atomic()
105 pwm_ir->txbuf = txbuf; in pwm_ir_tx_atomic()
106 pwm_ir->txbuf_len = count; in pwm_ir_tx_atomic()
107 pwm_ir->txbuf_index = 0; in pwm_ir_tx_atomic()
108 pwm_ir->state = &state; in pwm_ir_tx_atomic()
110 hrtimer_start(&pwm_ir->timer, 0, HRTIMER_MODE_REL); in pwm_ir_tx_atomic()
112 wait_for_completion(&pwm_ir->tx_done); in pwm_ir_tx_atomic()
117 static enum hrtimer_restart pwm_ir_timer(struct hrtimer *timer) in pwm_ir_timer() argument
119 struct pwm_ir *pwm_ir = container_of(timer, struct pwm_ir, timer); in pwm_ir_timer()
129 pwm_ir->state->enabled = !(pwm_ir->txbuf_index % 2); in pwm_ir_timer()
130 pwm_apply_atomic(pwm_ir->pwm, pwm_ir->state); in pwm_ir_timer()
132 if (pwm_ir->txbuf_index >= pwm_ir->txbuf_len) { in pwm_ir_timer()
133 complete(&pwm_ir->tx_done); in pwm_ir_timer()
138 ns = US_TO_NS(pwm_ir->txbuf[pwm_ir->txbuf_index]); in pwm_ir_timer()
139 hrtimer_add_expires_ns(timer, ns); in pwm_ir_timer()
141 pwm_ir->txbuf_index++; in pwm_ir_timer()
143 now = timer->base->get_time(); in pwm_ir_timer()
144 } while (hrtimer_get_expires_tv64(timer) < now); in pwm_ir_timer()
155 pwm_ir = devm_kmalloc(&pdev->dev, sizeof(*pwm_ir), GFP_KERNEL); in pwm_ir_probe()
157 return -ENOMEM; in pwm_ir_probe()
159 pwm_ir->pwm = devm_pwm_get(&pdev->dev, NULL); in pwm_ir_probe()
160 if (IS_ERR(pwm_ir->pwm)) in pwm_ir_probe()
161 return PTR_ERR(pwm_ir->pwm); in pwm_ir_probe()
163 pwm_ir->carrier = 38000; in pwm_ir_probe()
164 pwm_ir->duty_cycle = 50; in pwm_ir_probe()
166 rcdev = devm_rc_allocate_device(&pdev->dev, RC_DRIVER_IR_RAW_TX); in pwm_ir_probe()
168 return -ENOMEM; in pwm_ir_probe()
170 if (pwm_might_sleep(pwm_ir->pwm)) { in pwm_ir_probe()
171 dev_info(&pdev->dev, "TX will not be accurate as PWM device might sleep\n"); in pwm_ir_probe()
172 rcdev->tx_ir = pwm_ir_tx_sleep; in pwm_ir_probe()
174 init_completion(&pwm_ir->tx_done); in pwm_ir_probe()
175 hrtimer_init(&pwm_ir->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); in pwm_ir_probe()
176 pwm_ir->timer.function = pwm_ir_timer; in pwm_ir_probe()
177 rcdev->tx_ir = pwm_ir_tx_atomic; in pwm_ir_probe()
180 rcdev->priv = pwm_ir; in pwm_ir_probe()
181 rcdev->driver_name = DRIVER_NAME; in pwm_ir_probe()
182 rcdev->device_name = DEVICE_NAME; in pwm_ir_probe()
183 rcdev->s_tx_duty_cycle = pwm_ir_set_duty_cycle; in pwm_ir_probe()
184 rcdev->s_tx_carrier = pwm_ir_set_carrier; in pwm_ir_probe()
186 rc = devm_rc_register_device(&pdev->dev, rcdev); in pwm_ir_probe()
188 dev_err(&pdev->dev, "failed to register rc device\n"); in pwm_ir_probe()
202 MODULE_DESCRIPTION("PWM IR Transmitter");