// SPDX-License-Identifier: GPL-2.0-or-later /*****************************************************************************/ /* * baycom_ser_hdx.c -- baycom ser12 halfduplex radio modem driver. * * Copyright (C) 1996-2000 Thomas Sailer ([email protected]) * * Please note that the GPL allows you to use the driver, NOT the radio. * In order to use the radio, you need a license from the communications * authority of your country. * * Supported modems * * ser12: This is a very simple 1200 baud AFSK modem. The modem consists only * of a modulator/demodulator chip, usually a TI TCM3105. The computer * is responsible for regenerating the receiver bit clock, as well as * for handling the HDLC protocol. The modem connects to a serial port, * hence the name. Since the serial port is not used as an async serial * port, the kernel driver for serial ports cannot be used, and this * driver only supports standard serial hardware (8250, 16450, 16550A) * * Command line options (insmod command line) * * mode ser12 hardware DCD * ser12* software DCD * ser12@ hardware/software DCD, i.e. no explicit DCD signal but hardware * mutes audio input to the modem * ser12+ hardware DCD, inverted signal at DCD pin * iobase base address of the port; common values are 0x3f8, 0x2f8, 0x3e8, 0x2e8 * irq interrupt line of the port; common values are 4,3 * * History: * 0.1 26.06.1996 Adapted from baycom.c and made network driver interface * 18.10.1996 Changed to new user space access routines (copy_{to,from}_user) * 0.3 26.04.1997 init code/data tagged * 0.4 08.07.1997 alternative ser12 decoding algorithm (uses delta CTS ints) * 0.5 11.11.1997 ser12/par96 split into separate files * 0.6 14.04.1998 cleanups * 0.7 03.08.1999 adapt to Linus' new __setup/__initcall * 0.8 10.08.1999 use module_init/module_exit * 0.9 12.02.2000 adapted to softnet driver interface * 0.10 03.07.2000 fix interface name handling */ /*****************************************************************************/ #include <linux/capability.h> #include <linux/module.h> #include <linux/ioport.h> #include <linux/string.h> #include <linux/init.h> #include <linux/interrupt.h> #include <linux/uaccess.h> #include <asm/io.h> #include <linux/hdlcdrv.h> #include <linux/baycom.h> #include <linux/jiffies.h> /* --------------------------------------------------------------------- */ #define BAYCOM_DEBUG /* --------------------------------------------------------------------- */ static const char bc_drvname[] = …; static const char bc_drvinfo[] = …; /* --------------------------------------------------------------------- */ #define NR_PORTS … static struct net_device *baycom_device[NR_PORTS]; /* --------------------------------------------------------------------- */ #define RBR(iobase) … #define THR(iobase) … #define IER(iobase) … #define IIR(iobase) … #define FCR(iobase) … #define LCR(iobase) … #define MCR(iobase) … #define LSR(iobase) … #define MSR(iobase) … #define SCR(iobase) … #define DLL(iobase) … #define DLM(iobase) … #define SER12_EXTENT … /* ---------------------------------------------------------------------- */ /* * Information that need to be kept for each board. */ struct baycom_state { … }; /* --------------------------------------------------------------------- */ static inline void baycom_int_freq(struct baycom_state *bc) { … } /* --------------------------------------------------------------------- */ /* * ===================== SER12 specific routines ========================= */ static inline void ser12_set_divisor(struct net_device *dev, unsigned char divisor) { … } /* --------------------------------------------------------------------- */ /* * must call the TX arbitrator every 10ms */ #define SER12_ARB_DIVIDER(bc) … #define SER12_DCD_INTERVAL(bc) … static inline void ser12_tx(struct net_device *dev, struct baycom_state *bc) { … } /* --------------------------------------------------------------------- */ static inline void ser12_rx(struct net_device *dev, struct baycom_state *bc) { … } /* --------------------------------------------------------------------- */ static irqreturn_t ser12_interrupt(int irq, void *dev_id) { … } /* --------------------------------------------------------------------- */ enum uart { … }; static const char *uart_str[] = …; static enum uart ser12_check_uart(unsigned int iobase) { … } /* --------------------------------------------------------------------- */ static int ser12_open(struct net_device *dev) { … } /* --------------------------------------------------------------------- */ static int ser12_close(struct net_device *dev) { … } /* --------------------------------------------------------------------- */ /* * ===================== hdlcdrv driver interface ========================= */ /* --------------------------------------------------------------------- */ static int baycom_ioctl(struct net_device *dev, void __user *data, struct hdlcdrv_ioctl *hi, int cmd); /* --------------------------------------------------------------------- */ static const struct hdlcdrv_ops ser12_ops = …; /* --------------------------------------------------------------------- */ static int baycom_setmode(struct baycom_state *bc, const char *modestr) { … } /* --------------------------------------------------------------------- */ static int baycom_ioctl(struct net_device *dev, void __user *data, struct hdlcdrv_ioctl *hi, int cmd) { … } /* --------------------------------------------------------------------- */ /* * command line settable parameters */ static char *mode[NR_PORTS] = …; static int iobase[NR_PORTS] = …; static int irq[NR_PORTS] = …; module_param_array(…); MODULE_PARM_DESC(…) …; module_param_hw_array(iobase, int, ioport, NULL, 0); MODULE_PARM_DESC(…) …; module_param_hw_array(irq, int, irq, NULL, 0); MODULE_PARM_DESC(…) …; MODULE_AUTHOR(…) …; MODULE_DESCRIPTION(…) …; MODULE_LICENSE(…) …; /* --------------------------------------------------------------------- */ static int __init init_baycomserhdx(void) { … } static void __exit cleanup_baycomserhdx(void) { … } module_init(…) …; module_exit(cleanup_baycomserhdx); /* --------------------------------------------------------------------- */ #ifndef MODULE /* * format: baycom_ser_hdx=io,irq,mode * mode: ser12 hardware DCD * ser12* software DCD * ser12@ hardware/software DCD, i.e. no explicit DCD signal but hardware * mutes audio input to the modem * ser12+ hardware DCD, inverted signal at DCD pin */ static int __init baycom_ser_hdx_setup(char *str) { … } __setup(…); #endif /* MODULE */ /* --------------------------------------------------------------------- */