51 #include <linux/module.h>
52 #include <linux/errno.h>
53 #include <linux/signal.h>
54 #include <linux/sched.h>
58 #include <linux/kernel.h>
60 #include <linux/time.h>
61 #include <linux/string.h>
62 #include <linux/types.h>
63 #include <linux/wait.h>
66 #include <linux/poll.h>
71 #include <linux/fcntl.h>
74 #ifdef CONFIG_LIRC_SERIAL_NSLU2
79 #define UART_IE_IXP42X_UUE 0x40
80 #define UART_IE_IXP42X_RTOIE 0x10
85 #define LIRC_DRIVER_NAME "lirc_serial"
98 #define LIRC_HOMEBREW 0
100 #define LIRC_IRDEO_REMOTE 2
101 #define LIRC_ANIMAX 3
111 static bool softcarrier = 1;
112 static bool share_irq;
114 static int sense = -1;
117 #define dprintk(fmt, args...) \
120 printk(KERN_DEBUG LIRC_DRIVER_NAME ": " \
125 static long send_pulse_irdeo(
unsigned long length);
126 static long send_pulse_homebrew(
unsigned long length);
127 static void send_space_irdeo(
long length);
128 static void send_space_homebrew(
long length);
137 .send_pulse = send_pulse_homebrew,
138 .send_space = send_space_homebrew,
139 #ifdef CONFIG_LIRC_SERIAL_TRANSMITTER
166 .send_pulse = send_pulse_irdeo,
167 .send_space = send_space_irdeo,
189 .send_pulse = send_pulse_homebrew,
190 .send_space = send_space_homebrew,
191 #ifdef CONFIG_LIRC_SERIAL_TRANSMITTER
200 #ifdef CONFIG_LIRC_SERIAL_NSLU2
214 .send_pulse = send_pulse_homebrew,
215 .send_space = send_space_homebrew,
216 #ifdef CONFIG_LIRC_SERIAL_TRANSMITTER
228 #define RS_ISR_PASS_LIMIT 256
243 static struct timeval lasttv = {0, 0};
247 static unsigned int freq = 38000;
248 static unsigned int duty_cycle = 50;
251 static unsigned long period;
252 static unsigned long pulse_width;
253 static unsigned long space_width;
255 #if defined(__i386__)
280 #define LIRC_SERIAL_TRANSMITTER_LATENCY 450
286 #define LIRC_SERIAL_TRANSMITTER_LATENCY 256
301 return inb(
io + offset);
316 #ifdef CONFIG_LIRC_SERIAL_NSLU2
332 static void off(
void)
334 #ifdef CONFIG_LIRC_SERIAL_NSLU2
346 #ifndef MAX_UDELAY_MS
347 #define MAX_UDELAY_US 5000
349 #define MAX_UDELAY_US (MAX_UDELAY_MS*1000)
352 static void safe_udelay(
unsigned long usecs)
375 static unsigned long conv_us_to_clocks;
377 static int init_timing_params(
unsigned int new_duty_cycle,
378 unsigned int new_freq)
382 duty_cycle = new_duty_cycle;
389 work = loops_per_sec;
391 conv_us_to_clocks = (work >> 32);
397 period = loops_per_sec >> 3;
398 period /= (freq >> 3);
401 pulse_width = period * duty_cycle / 100;
402 space_width = period - pulse_width;
403 dprintk(
"in init_timing_params, freq=%d, duty_cycle=%d, "
404 "clk/jiffy=%ld, pulse=%ld, space=%ld, "
405 "conv_us_to_clocks=%ld\n",
407 pulse_width, space_width, conv_us_to_clocks);
411 static int init_timing_params(
unsigned int new_duty_cycle,
412 unsigned int new_freq)
418 if (256 * 1000000L / new_freq * new_duty_cycle / 100 <=
421 if (256 * 1000000L / new_freq * (100 - new_duty_cycle) / 100 <=
424 duty_cycle = new_duty_cycle;
426 period = 256 * 1000000
L /
freq;
427 pulse_width = period * duty_cycle / 100;
428 space_width = period - pulse_width;
429 dprintk(
"in init_timing_params, freq=%d pulse=%ld, "
430 "space=%ld\n", freq, pulse_width, space_width);
438 static long send_pulse_irdeo(
unsigned long length)
443 unsigned char chunk, shifted;
446 rawbits = length * 1152 / 10000;
451 for (i = 0, output = 0x7f; rawbits > 0; rawbits -= 3) {
452 shifted = chunk << (i * 3);
454 output &= (~shifted);
471 ret = (-rawbits) * 10000 / 1152;
473 ret = (3 -
i) * 3 * 10000 / 1152 + (-rawbits) * 10000 / 1152;
487 static long send_pulse_homebrew_softcarrier(
unsigned long length)
496 length *= conv_us_to_clocks;
499 target = pulse_width;
508 while ((now - start) < length) {
512 }
while ((now - start) < target);
518 target += space_width;
521 target += pulse_width;
526 return ((now - start) - length) / conv_us_to_clocks;
539 static long send_pulse_homebrew_softcarrier(
unsigned long length)
542 unsigned long actual,
target,
d;
545 actual = 0; target = 0; flag = 0;
546 while (actual < length) {
549 target += space_width;
552 target += pulse_width;
554 d = (target - actual -
564 return (actual-length) >> 8;
568 static long send_pulse_homebrew(
unsigned long length)
574 return send_pulse_homebrew_softcarrier(length);
582 static void send_space_irdeo(
long length)
590 static void send_space_homebrew(
long length)
598 static void rbwrite(
int l)
600 if (lirc_buffer_full(&rbuf)) {
605 lirc_buffer_write(&rbuf, (
void *)&l);
608 static void frbwrite(
int l)
611 static int pulse, space;
612 static unsigned int ptr;
618 rbwrite(pulse | PULSE_BIT);
624 if (!(l & PULSE_BIT)) {
634 if (space > PULSE_MASK)
637 if (space > PULSE_MASK)
643 rbwrite(pulse | PULSE_BIT);
658 static int last_dcd = -1;
674 if ((status & hardware[
type].signal_pin_change)
705 if (dcd == last_dcd) {
707 ": ignoring spike: %d %d %lx %lx %lx %lx\n",
714 deltv = tv.tv_sec-lasttv.
tv_sec;
715 if (tv.tv_sec < lasttv.
tv_sec ||
716 (tv.tv_sec == lasttv.
tv_sec &&
717 tv.tv_usec < lasttv.
tv_usec)) {
719 ": AIEEEE: your clock just jumped "
722 ": %d %d %lx %lx %lx %lx\n",
727 }
else if (deltv > 15) {
733 "%d %d %lx %lx %lx %lx\n",
741 sense = sense ? 0 : 1;
744 data = (
int) (deltv*1000000 +
747 frbwrite(dcd^
sense ? data : (data|PULSE_BIT));
752 }
while (!(sinp(
UART_IIR) & UART_IIR_NO_INT));
757 static int hardware_init_port(
void)
777 if (scratch2 != 0 || scratch3 != 0x0f) {
780 "failed, cannot continue\n");
799 #ifdef CONFIG_LIRC_SERIAL_NSLU2
852 if (result == -
EBUSY)
855 else if (result == -
EINVAL)
857 ": Bad irq number or handler\n");
873 ": port %04x already in use\n",
io);
875 ": use 'setserial /dev/ttySX uart none'\n");
877 ": or compile the serial port driver as module and\n");
879 ": make sure this module is loaded first\n");
884 result = hardware_init_port();
886 goto exit_release_region;
889 init_timing_params(duty_cycle, freq);
902 for (i = 0; i < 9; i++) {
909 sense = (nlow >= nhigh ? 1 : 0);
911 "%s receiver\n",
sense ?
"low" :
"high");
914 "%s receiver\n",
sense ?
"low" :
"high");
916 dprintk(
"Interrupt %d, port %04x obtained\n", irq,
io);
942 static int set_use_inc(
void *data)
956 spin_unlock_irqrestore(&hardware[
type].lock, flags);
961 static void set_use_dec(
void *data)
962 {
unsigned long flags;
972 spin_unlock_irqrestore(&hardware[
type].lock, flags);
976 size_t n, loff_t *ppos)
986 count = n /
sizeof(
int);
987 if (n %
sizeof(
int) || count % 2 == 0)
991 return PTR_ERR(wbuf);
997 for (i = 0; i <
count; i++) {
1004 spin_unlock_irqrestore(&hardware[
type].lock, flags);
1009 static long lirc_ioctl(
struct file *filep,
unsigned int cmd,
unsigned long arg)
1043 dprintk(
"SET_SEND_DUTY_CYCLE\n");
1050 if (value <= 0 || value > 100)
1052 return init_timing_params(value, freq);
1056 dprintk(
"SET_SEND_CARRIER\n");
1063 if (value > 500000 || value < 20000)
1065 return init_timing_params(duty_cycle, value);
1076 .write = lirc_write,
1077 .unlocked_ioctl = lirc_ioctl,
1078 #ifdef CONFIG_COMPAT
1079 .compat_ioctl = lirc_ioctl,
1125 static void lirc_serial_exit(
void);
1129 unsigned long flags;
1132 result = hardware_init_port();
1142 lirc_buffer_clear(&rbuf);
1144 spin_unlock_irqrestore(&hardware[
type].lock, flags);
1150 .probe = lirc_serial_probe,
1152 .suspend = lirc_serial_suspend,
1153 .resume = lirc_serial_resume,
1155 .name =
"lirc_serial",
1160 static int __init lirc_serial_init(
void)
1165 result = lirc_buffer_init(&rbuf,
sizeof(
int),
RBUF_LEN);
1171 printk(
"lirc register returned %d\n", result);
1172 goto exit_buffer_free;
1176 if (!lirc_serial_dev) {
1178 goto exit_driver_unregister;
1183 goto exit_device_put;
1189 exit_driver_unregister:
1192 lirc_buffer_free(&rbuf);
1196 static void lirc_serial_exit(
void)
1200 lirc_buffer_free(&rbuf);
1203 static int __init lirc_serial_init_module(
void)
1217 #ifdef CONFIG_LIRC_SERIAL_NSLU2
1222 ioshift = ioshift ? ioshift : 2;
1232 #ifdef CONFIG_LIRC_SERIAL_NSLU2
1236 ~(LIRC_CAN_SET_SEND_DUTY_CYCLE|
1242 result = lirc_serial_init();
1247 driver.
dev = &lirc_serial_dev->
dev;
1249 if (driver.
minor < 0) {
1251 ": register_chrdev failed!\n");
1253 return driver.
minor;
1258 static void __exit lirc_serial_exit_module(
void)
1262 dprintk(
"cleaned up module\n");
1271 "Christoph Bartelmus, Andrei Tanas");
1276 " 2 = IRdeo Remote, 3 = AnimaX, 4 = IgorPlug,"
1277 " 5 = NSLU2 RX:CTS2/TX:GreenLED)");
1285 " (0 = no memory mapped io)");
1303 " (0 = active high, 1 = active low )");
1305 #ifdef CONFIG_LIRC_SERIAL_TRANSMITTER
1308 " (0 = active high, 1 = active low )");
1312 MODULE_PARM_DESC(softcarrier,
"Software carrier (0 = off, 1 = on, default on)");