// SPDX-License-Identifier: GPL-2.0-or-later /*****************************************************************************/ /* * baycom_par.c -- baycom par96 and picpar 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 * * par96: This is a modem for 9600 baud FSK compatible to the G3RUH standard. * The modem does all the filtering and regenerates the receiver clock. * Data is transferred from and to the PC via a shift register. * The shift register is filled with 16 bits and an interrupt is * signalled. The PC then empties the shift register in a burst. This * modem connects to the parallel port, hence the name. The modem * leaves the implementation of the HDLC protocol and the scrambler * polynomial to the PC. This modem is no longer available (at least * from Baycom) and has been replaced by the PICPAR modem (see below). * You may however still build one from the schematics published in * cq-DL :-). * * picpar: This is a redesign of the par96 modem by Henning Rech, DF9IC. The * modem is protocol compatible to par96, but uses only three low * power ICs and can therefore be fed from the parallel port and * does not require an additional power supply. It features * built in DCD circuitry. The driver should therefore be configured * for hardware DCD. * * Command line options (insmod command line) * * mode driver mode string. Valid choices are par96 and picpar. * iobase base address of the port; common values are 0x378, 0x278, 0x3bc * * 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 split into separate files for ser12/par96 * 0.6 03.08.1999 adapt to Linus' new __setup/__initcall * removed some pre-2.2 kernel compatibility cruft * 0.7 10.08.1999 Check if parport can do SPP and is safe to access during interrupt contexts * 0.8 12.02.2000 adapted to softnet driver interface * removed direct parport access, uses parport driver methods * 0.9 03.07.2000 fix interface name handling */ /*****************************************************************************/ #include <linux/module.h> #include <linux/kernel.h> #include <linux/types.h> #include <linux/fcntl.h> #include <linux/interrupt.h> #include <linux/ioport.h> #include <linux/in.h> #include <linux/string.h> #include <linux/init.h> #include <linux/delay.h> #include <linux/errno.h> #include <linux/netdevice.h> #include <linux/hdlcdrv.h> #include <linux/baycom.h> #include <linux/parport.h> #include <linux/bitops.h> #include <linux/jiffies.h> #include <linux/uaccess.h> /* --------------------------------------------------------------------- */ #define BAYCOM_DEBUG /* * modem options; bit mask */ #define BAYCOM_OPTIONS_SOFTDCD … /* --------------------------------------------------------------------- */ static const char bc_drvname[] = …; static const char bc_drvinfo[] = …; /* --------------------------------------------------------------------- */ #define NR_PORTS … static struct net_device *baycom_device[NR_PORTS]; /* --------------------------------------------------------------------- */ #define PAR96_BURSTBITS … #define PAR96_BURST … #define PAR96_PTT … #define PAR96_TXBIT … #define PAR96_ACK … #define PAR96_RXBIT … #define PAR96_DCD … #define PAR97_POWER … /* ---------------------------------------------------------------------- */ /* * Information that need to be kept for each board. */ struct baycom_state { … }; /* --------------------------------------------------------------------- */ static inline void baycom_int_freq(struct baycom_state *bc) { … } /* --------------------------------------------------------------------- */ /* * ===================== PAR96 specific routines ========================= */ #define PAR96_DESCRAM_TAP1 … #define PAR96_DESCRAM_TAP2 … #define PAR96_DESCRAM_TAP3 … #define PAR96_DESCRAM_TAPSH1 … #define PAR96_DESCRAM_TAPSH2 … #define PAR96_DESCRAM_TAPSH3 … #define PAR96_SCRAM_TAP1 … #define PAR96_SCRAM_TAPN … /* --------------------------------------------------------------------- */ static inline void par96_tx(struct net_device *dev, struct baycom_state *bc) { … } /* --------------------------------------------------------------------- */ static inline void par96_rx(struct net_device *dev, struct baycom_state *bc) { … } /* --------------------------------------------------------------------- */ static void par96_interrupt(void *dev_id) { … } /* --------------------------------------------------------------------- */ static void par96_wakeup(void *handle) { … } /* --------------------------------------------------------------------- */ static int par96_open(struct net_device *dev) { … } /* --------------------------------------------------------------------- */ static int par96_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 par96_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] = …; module_param_array(…); MODULE_PARM_DESC(…) …; module_param_hw_array(iobase, int, ioport, NULL, 0); MODULE_PARM_DESC(…) …; MODULE_AUTHOR(…) …; MODULE_DESCRIPTION(…) …; MODULE_LICENSE(…) …; /* --------------------------------------------------------------------- */ static int baycom_par_probe(struct pardevice *par_dev) { … } static struct parport_driver baycom_par_driver = …; static int __init init_baycompar(void) { … } static void __exit cleanup_baycompar(void) { … } module_init(…) …; module_exit(cleanup_baycompar); /* --------------------------------------------------------------------- */ #ifndef MODULE /* * format: baycom_par=io,mode * mode: par96,picpar */ static int __init baycom_par_setup(char *str) { … } __setup(…); #endif /* MODULE */ /* --------------------------------------------------------------------- */