1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (C) 2017 Sean Young <sean@mess.org>
6 #include <linux/kernel.h>
7 #include <linux/module.h>
8 #include <linux/gpio/consumer.h>
9 #include <linux/delay.h>
10 #include <linux/slab.h>
12 #include <linux/platform_device.h>
13 #include <media/rc-core.h>
15 #define DRIVER_NAME "gpio-ir-tx"
16 #define DEVICE_NAME "GPIO IR Bit Banging Transmitter"
19 struct gpio_desc
*gpio
;
21 unsigned int duty_cycle
;
24 static const struct of_device_id gpio_ir_tx_of_match
[] = {
25 { .compatible
= "gpio-ir-tx", },
28 MODULE_DEVICE_TABLE(of
, gpio_ir_tx_of_match
);
30 static int gpio_ir_tx_set_duty_cycle(struct rc_dev
*dev
, u32 duty_cycle
)
32 struct gpio_ir
*gpio_ir
= dev
->priv
;
34 gpio_ir
->duty_cycle
= duty_cycle
;
39 static int gpio_ir_tx_set_carrier(struct rc_dev
*dev
, u32 carrier
)
41 struct gpio_ir
*gpio_ir
= dev
->priv
;
46 gpio_ir
->carrier
= carrier
;
51 static void gpio_ir_tx_unmodulated(struct gpio_ir
*gpio_ir
, uint
*txbuf
,
62 for (i
= 0; i
< count
; i
++) {
63 gpiod_set_value(gpio_ir
->gpio
, !(i
% 2));
65 edge
= ktime_add_us(edge
, txbuf
[i
]);
66 delta
= ktime_us_delta(edge
, ktime_get());
71 gpiod_set_value(gpio_ir
->gpio
, 0);
74 static void gpio_ir_tx_modulated(struct gpio_ir
*gpio_ir
, uint
*txbuf
,
79 * delta should never exceed 0.5 seconds (IR_MAX_DURATION) and on
80 * m68k ndelay(s64) does not compile; so use s32 rather than s64.
84 unsigned int pulse
, space
;
86 /* Ensure the dividend fits into 32 bit */
87 pulse
= DIV_ROUND_CLOSEST(gpio_ir
->duty_cycle
* (NSEC_PER_SEC
/ 100),
89 space
= DIV_ROUND_CLOSEST((100 - gpio_ir
->duty_cycle
) *
90 (NSEC_PER_SEC
/ 100), gpio_ir
->carrier
);
96 for (i
= 0; i
< count
; i
++) {
99 edge
= ktime_add_us(edge
, txbuf
[i
]);
100 delta
= ktime_us_delta(edge
, ktime_get());
105 ktime_t last
= ktime_add_us(edge
, txbuf
[i
]);
107 while (ktime_before(ktime_get(), last
)) {
108 gpiod_set_value(gpio_ir
->gpio
, 1);
109 edge
= ktime_add_ns(edge
, pulse
);
110 delta
= ktime_to_ns(ktime_sub(edge
,
114 gpiod_set_value(gpio_ir
->gpio
, 0);
115 edge
= ktime_add_ns(edge
, space
);
116 delta
= ktime_to_ns(ktime_sub(edge
,
127 static int gpio_ir_tx(struct rc_dev
*dev
, unsigned int *txbuf
,
130 struct gpio_ir
*gpio_ir
= dev
->priv
;
133 local_irq_save(flags
);
134 if (gpio_ir
->carrier
)
135 gpio_ir_tx_modulated(gpio_ir
, txbuf
, count
);
137 gpio_ir_tx_unmodulated(gpio_ir
, txbuf
, count
);
138 local_irq_restore(flags
);
143 static int gpio_ir_tx_probe(struct platform_device
*pdev
)
145 struct gpio_ir
*gpio_ir
;
146 struct rc_dev
*rcdev
;
149 gpio_ir
= devm_kmalloc(&pdev
->dev
, sizeof(*gpio_ir
), GFP_KERNEL
);
153 rcdev
= devm_rc_allocate_device(&pdev
->dev
, RC_DRIVER_IR_RAW_TX
);
157 gpio_ir
->gpio
= devm_gpiod_get(&pdev
->dev
, NULL
, GPIOD_OUT_LOW
);
158 if (IS_ERR(gpio_ir
->gpio
)) {
159 if (PTR_ERR(gpio_ir
->gpio
) != -EPROBE_DEFER
)
160 dev_err(&pdev
->dev
, "Failed to get gpio (%ld)\n",
161 PTR_ERR(gpio_ir
->gpio
));
162 return PTR_ERR(gpio_ir
->gpio
);
165 rcdev
->priv
= gpio_ir
;
166 rcdev
->driver_name
= DRIVER_NAME
;
167 rcdev
->device_name
= DEVICE_NAME
;
168 rcdev
->tx_ir
= gpio_ir_tx
;
169 rcdev
->s_tx_duty_cycle
= gpio_ir_tx_set_duty_cycle
;
170 rcdev
->s_tx_carrier
= gpio_ir_tx_set_carrier
;
172 gpio_ir
->carrier
= 38000;
173 gpio_ir
->duty_cycle
= 50;
175 rc
= devm_rc_register_device(&pdev
->dev
, rcdev
);
177 dev_err(&pdev
->dev
, "failed to register rc device\n");
182 static struct platform_driver gpio_ir_tx_driver
= {
183 .probe
= gpio_ir_tx_probe
,
186 .of_match_table
= of_match_ptr(gpio_ir_tx_of_match
),
189 module_platform_driver(gpio_ir_tx_driver
);
191 MODULE_DESCRIPTION("GPIO IR Bit Banging Transmitter");
192 MODULE_AUTHOR("Sean Young <sean@mess.org>");
193 MODULE_LICENSE("GPL");