1010#include <linux/slab.h>
1111#include <linux/of.h>
1212#include <linux/platform_device.h>
13+ #include <linux/hrtimer.h>
14+ #include <linux/completion.h>
1315#include <media/rc-core.h>
1416
1517#define DRIVER_NAME "pwm-ir-tx"
1618#define DEVICE_NAME "PWM IR Transmitter"
1719
1820struct pwm_ir {
1921 struct pwm_device * pwm ;
20- unsigned int carrier ;
21- unsigned int duty_cycle ;
22+ struct hrtimer timer ;
23+ struct completion tx_done ;
24+ struct pwm_state * state ;
25+ u32 carrier ;
26+ u32 duty_cycle ;
27+ const unsigned int * txbuf ;
28+ unsigned int txbuf_len ;
29+ unsigned int txbuf_index ;
2230};
2331
2432static const struct of_device_id pwm_ir_of_match [] = {
@@ -49,8 +57,8 @@ static int pwm_ir_set_carrier(struct rc_dev *dev, u32 carrier)
4957 return 0 ;
5058}
5159
52- static int pwm_ir_tx (struct rc_dev * dev , unsigned int * txbuf ,
53- unsigned int count )
60+ static int pwm_ir_tx_sleep (struct rc_dev * dev , unsigned int * txbuf ,
61+ unsigned int count )
5462{
5563 struct pwm_ir * pwm_ir = dev -> priv ;
5664 struct pwm_device * pwm = pwm_ir -> pwm ;
@@ -82,6 +90,62 @@ static int pwm_ir_tx(struct rc_dev *dev, unsigned int *txbuf,
8290 return count ;
8391}
8492
93+ static int pwm_ir_tx_atomic (struct rc_dev * dev , unsigned int * txbuf ,
94+ unsigned int count )
95+ {
96+ struct pwm_ir * pwm_ir = dev -> priv ;
97+ struct pwm_device * pwm = pwm_ir -> pwm ;
98+ struct pwm_state state ;
99+
100+ pwm_init_state (pwm , & state );
101+
102+ state .period = DIV_ROUND_CLOSEST (NSEC_PER_SEC , pwm_ir -> carrier );
103+ pwm_set_relative_duty_cycle (& state , pwm_ir -> duty_cycle , 100 );
104+
105+ pwm_ir -> txbuf = txbuf ;
106+ pwm_ir -> txbuf_len = count ;
107+ pwm_ir -> txbuf_index = 0 ;
108+ pwm_ir -> state = & state ;
109+
110+ hrtimer_start (& pwm_ir -> timer , 0 , HRTIMER_MODE_REL );
111+
112+ wait_for_completion (& pwm_ir -> tx_done );
113+
114+ return count ;
115+ }
116+
117+ static enum hrtimer_restart pwm_ir_timer (struct hrtimer * timer )
118+ {
119+ struct pwm_ir * pwm_ir = container_of (timer , struct pwm_ir , timer );
120+ ktime_t now ;
121+
122+ /*
123+ * If we happen to hit an odd latency spike, loop through the
124+ * pulses until we catch up.
125+ */
126+ do {
127+ u64 ns ;
128+
129+ pwm_ir -> state -> enabled = !(pwm_ir -> txbuf_index % 2 );
130+ pwm_apply_atomic (pwm_ir -> pwm , pwm_ir -> state );
131+
132+ if (pwm_ir -> txbuf_index >= pwm_ir -> txbuf_len ) {
133+ complete (& pwm_ir -> tx_done );
134+
135+ return HRTIMER_NORESTART ;
136+ }
137+
138+ ns = US_TO_NS (pwm_ir -> txbuf [pwm_ir -> txbuf_index ]);
139+ hrtimer_add_expires_ns (timer , ns );
140+
141+ pwm_ir -> txbuf_index ++ ;
142+
143+ now = timer -> base -> get_time ();
144+ } while (hrtimer_get_expires_tv64 (timer ) < now );
145+
146+ return HRTIMER_RESTART ;
147+ }
148+
85149static int pwm_ir_probe (struct platform_device * pdev )
86150{
87151 struct pwm_ir * pwm_ir ;
@@ -103,10 +167,19 @@ static int pwm_ir_probe(struct platform_device *pdev)
103167 if (!rcdev )
104168 return - ENOMEM ;
105169
170+ if (pwm_might_sleep (pwm_ir -> pwm )) {
171+ dev_info (& pdev -> dev , "TX will not be accurate as PWM device might sleep\n" );
172+ rcdev -> tx_ir = pwm_ir_tx_sleep ;
173+ } else {
174+ init_completion (& pwm_ir -> tx_done );
175+ hrtimer_init (& pwm_ir -> timer , CLOCK_MONOTONIC , HRTIMER_MODE_REL );
176+ pwm_ir -> timer .function = pwm_ir_timer ;
177+ rcdev -> tx_ir = pwm_ir_tx_atomic ;
178+ }
179+
106180 rcdev -> priv = pwm_ir ;
107181 rcdev -> driver_name = DRIVER_NAME ;
108182 rcdev -> device_name = DEVICE_NAME ;
109- rcdev -> tx_ir = pwm_ir_tx ;
110183 rcdev -> s_tx_duty_cycle = pwm_ir_set_duty_cycle ;
111184 rcdev -> s_tx_carrier = pwm_ir_set_carrier ;
112185
0 commit comments