From: Dave Penkler Date: Wed, 18 Sep 2024 12:18:50 +0000 (+0200) Subject: staging: gpib: Add common include files for GPIB drivers X-Git-Tag: v6.13-rc1~30^2~148 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6c52d5e3cde2c1ca9b63ca2255c2d7c6f95e7afc;p=thirdparty%2Flinux.git staging: gpib: Add common include files for GPIB drivers Common include files used only by the drivers. Signed-off-by: Dave Penkler Link: https://lore.kernel.org/r/20240918121908.19366-4-dpenkler@gmail.com Signed-off-by: Greg Kroah-Hartman --- diff --git a/drivers/staging/gpib/include/amcc5920.h b/drivers/staging/gpib/include/amcc5920.h new file mode 100644 index 0000000000000..766b3799223f1 --- /dev/null +++ b/drivers/staging/gpib/include/amcc5920.h @@ -0,0 +1,49 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/*************************************************************************** + * Header for amcc5920 pci chip + * + * copyright : (C) 2002 by Frank Mori Hess + ***************************************************************************/ + +// plx pci chip registers and bits +enum amcc_registers { + AMCC_INTCS_REG = 0x38, + AMCC_PASS_THRU_REG = 0x60, +}; + +enum amcc_incsr_bits { + AMCC_ADDON_INTR_ENABLE_BIT = 0x2000, + AMCC_ADDON_INTR_ACTIVE_BIT = 0x400000, + AMCC_INTR_ACTIVE_BIT = 0x800000, +}; + +static const int bits_per_region = 8; + +static inline uint32_t amcc_wait_state_bits(unsigned int region, unsigned int num_wait_states) +{ + return (num_wait_states & 0x7) << (-region * bits_per_region); +}; + +enum amcc_prefetch_bits { + PREFETCH_DISABLED = 0x0, + PREFETCH_SMALL = 0x8, + PREFETCH_MEDIUM = 0x10, + PREFETCH_LARGE = 0x18, +}; + +static inline uint32_t amcc_prefetch_bits(unsigned int region, enum amcc_prefetch_bits prefetch) +{ + return prefetch << (--region * bits_per_region); +}; + +static inline uint32_t amcc_PTADR_mode_bit(unsigned int region) +{ + return 0x80 << (--region * bits_per_region); +}; + +static inline uint32_t amcc_disable_write_fifo_bit(unsigned int region) +{ + return 0x20 << (--region * bits_per_region); +}; + diff --git a/drivers/staging/gpib/include/amccs5933.h b/drivers/staging/gpib/include/amccs5933.h new file mode 100644 index 0000000000000..4de0f67974584 --- /dev/null +++ b/drivers/staging/gpib/include/amccs5933.h @@ -0,0 +1,59 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/*************************************************************************** + * Registers and bits for amccs5933 pci chip + * copyright : (C) 2002 by Frank Mori Hess + ***************************************************************************/ + +// register offsets +enum { + MBEF_REG = 0x34, // mailbux empty/full + INTCSR_REG = 0x38, // interrupt control and status + BMCSR_REG = 0x3c, // bus master control and status +}; + +// incoming mailbox 0-3 register offsets +extern inline int INCOMING_MAILBOX_REG(unsigned int mailbox) +{ + return (0x10 + 4 * mailbox); +}; + +// bit definitions + +// INTCSR bits +enum { + OUTBOX_EMPTY_INTR_BIT = 0x10, // enable outbox empty interrupt + INBOX_FULL_INTR_BIT = 0x1000, // enable inbox full interrupt + INBOX_INTR_CS_BIT = 0x20000, // read, or write clear inbox full interrupt + INTR_ASSERTED_BIT = 0x800000, // read only, interrupt asserted +}; + +// select byte 0 to 3 of incoming mailbox +extern inline int INBOX_BYTE_BITS(unsigned int byte) +{ + return (byte & 0x3) << 8; +}; + +// select incoming mailbox 0 to 3 +extern inline int INBOX_SELECT_BITS(unsigned int mailbox) +{ + return (mailbox & 0x3) << 10; +}; + +// select byte 0 to 3 of outgoing mailbox +extern inline int OUTBOX_BYTE_BITS(unsigned int byte) +{ + return (byte & 0x3); +}; + +// select outgoing mailbox 0 to 3 +extern inline int OUTBOX_SELECT_BITS(unsigned int mailbox) +{ + return (mailbox & 0x3) << 2; +}; + +//BMCSR bits +enum { + MBOX_FLAGS_RESET_BIT = 0x08000000, // resets mailbox empty/full flags +}; + diff --git a/drivers/staging/gpib/include/gpibP.h b/drivers/staging/gpib/include/gpibP.h new file mode 100644 index 0000000000000..0129fd29e7041 --- /dev/null +++ b/drivers/staging/gpib/include/gpibP.h @@ -0,0 +1,56 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/*************************************************************************** + * copyright : (C) 2002,2003 by Frank Mori Hess + ***************************************************************************/ + +#ifndef _GPIB_P_H +#define _GPIB_P_H + +#include + +#include "gpib_types.h" +#include "gpib_proto.h" +#include "gpib_user.h" +#include "gpib_ioctl.h" + +#include +#include + +void gpib_register_driver(gpib_interface_t *interface, struct module *mod); +void gpib_unregister_driver(gpib_interface_t *interface); +struct pci_dev *gpib_pci_get_device(const gpib_board_config_t *config, unsigned int vendor_id, + unsigned int device_id, struct pci_dev *from); +struct pci_dev *gpib_pci_get_subsys(const gpib_board_config_t *config, unsigned int vendor_id, + unsigned int device_id, unsigned int ss_vendor, + unsigned int ss_device, struct pci_dev *from); +unsigned int num_gpib_events(const gpib_event_queue_t *queue); +int push_gpib_event(gpib_board_t *board, short event_type); +int pop_gpib_event(gpib_event_queue_t *queue, short *event_type); +int gpib_request_pseudo_irq(gpib_board_t *board, irqreturn_t (*handler)(int, void *)); +void gpib_free_pseudo_irq(gpib_board_t *board); +int gpib_match_device_path(struct device *dev, const char *device_path_in); + +extern gpib_board_t board_array[GPIB_MAX_NUM_BOARDS]; + +extern struct list_head registered_drivers; + +#ifdef GPIB_DEBUG +#define GPIB_DPRINTK(format, args...) pr_info("gpib debug: " format, ## args) +#else +#define GPIB_DPRINTK(arg...) +#endif + +#include + +void writeb_wrapper(unsigned int value, void *address); +unsigned int readb_wrapper(void *address); +void outb_wrapper(unsigned int value, void *address); +unsigned int inb_wrapper(void *address); +void writew_wrapper(unsigned int value, void *address); +unsigned int readw_wrapper(void *address); +void outw_wrapper(unsigned int value, void *address); +unsigned int inw_wrapper(void *address); + +#endif // _GPIB_P_H + diff --git a/drivers/staging/gpib/include/gpib_pci_ids.h b/drivers/staging/gpib/include/gpib_pci_ids.h new file mode 100644 index 0000000000000..162b02deb0ade --- /dev/null +++ b/drivers/staging/gpib/include/gpib_pci_ids.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef __GPIB_PCI_IDS_H +#define __GPIB_LINUX_PCI_IDS_H + +#ifndef PCI_VENDOR_ID_AMCC +#define PCI_VENDOR_ID_AMCC 0x10e8 +#endif + +#ifndef PCI_VENDOR_ID_CBOARDS +#define PCI_VENDOR_ID_CBOARDS 0x1307 +#endif + +#ifndef PCI_VENDOR_ID_QUANCOM +#define PCI_VENDOR_ID_QUANCOM 0x8008 +#endif + +#ifndef PCI_DEVICE_ID_QUANCOM_GPIB +#define PCI_DEVICE_ID_QUANCOM_GPIB 0x3302 +#endif + +#endif // __GPIB_PCI_IDS_H + diff --git a/drivers/staging/gpib/include/gpib_proto.h b/drivers/staging/gpib/include/gpib_proto.h new file mode 100644 index 0000000000000..1499f954210b8 --- /dev/null +++ b/drivers/staging/gpib/include/gpib_proto.h @@ -0,0 +1,56 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef GPIB_PROTO_INCLUDED +#define GPIB_PROTO_INCLUDED + +#include + +int ibopen(struct inode *inode, struct file *filep); +int ibclose(struct inode *inode, struct file *file); +long ibioctl(struct file *filep, unsigned int cmd, unsigned long arg); +int osInit(void); +void osReset(void); +void os_start_timer(gpib_board_t *board, unsigned int usec_timeout); +void os_remove_timer(gpib_board_t *board); +void osSendEOI(void); +void osSendEOI(void); +void init_gpib_board(gpib_board_t *board); +static inline unsigned long usec_to_jiffies(unsigned int usec) +{ + unsigned long usec_per_jiffy = 1000000 / HZ; + + return 1 + (usec + usec_per_jiffy - 1) / usec_per_jiffy; +}; + +int serial_poll_all(gpib_board_t *board, unsigned int usec_timeout); +void init_gpib_descriptor(gpib_descriptor_t *desc); +int dvrsp(gpib_board_t *board, unsigned int pad, int sad, + unsigned int usec_timeout, uint8_t *result); +int ibAPWait(gpib_board_t *board, int pad); +int ibAPrsp(gpib_board_t *board, int padsad, char *spb); +void ibAPE(gpib_board_t *board, int pad, int v); +int ibcac(gpib_board_t *board, int sync, int fallback_to_async); +int ibcmd(gpib_board_t *board, uint8_t *buf, size_t length, size_t *bytes_written); +int ibgts(gpib_board_t *board); +int ibonline(gpib_board_t *board); +int iboffline(gpib_board_t *board); +int iblines(const gpib_board_t *board, short *lines); +int ibrd(gpib_board_t *board, uint8_t *buf, size_t length, int *end_flag, size_t *bytes_read); +int ibrpp(gpib_board_t *board, uint8_t *buf); +int ibrsv2(gpib_board_t *board, uint8_t status_byte, int new_reason_for_service); +void ibrsc(gpib_board_t *board, int request_control); +int ibsic(gpib_board_t *board, unsigned int usec_duration); +int ibsre(gpib_board_t *board, int enable); +int ibpad(gpib_board_t *board, unsigned int addr); +int ibsad(gpib_board_t *board, int addr); +int ibeos(gpib_board_t *board, int eos, int eosflags); +int ibwait(gpib_board_t *board, int wait_mask, int clear_mask, int set_mask, + int *status, unsigned long usec_timeout, gpib_descriptor_t *desc); +int ibwrt(gpib_board_t *board, uint8_t *buf, size_t cnt, int send_eoi, size_t *bytes_written); +int ibstatus(gpib_board_t *board); +int general_ibstatus(gpib_board_t *board, const gpib_status_queue_t *device, + int clear_mask, int set_mask, gpib_descriptor_t *desc); +int io_timed_out(gpib_board_t *board); +int ibppc(gpib_board_t *board, uint8_t configuration); + +#endif /* GPIB_PROTO_INCLUDED */ diff --git a/drivers/staging/gpib/include/gpib_state_machines.h b/drivers/staging/gpib/include/gpib_state_machines.h new file mode 100644 index 0000000000000..7488c00f191e8 --- /dev/null +++ b/drivers/staging/gpib/include/gpib_state_machines.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/*************************************************************************** + * copyright : (C) 2006 by Frank Mori Hess + ***************************************************************************/ + +#ifndef _GPIB_STATE_MACHINES_H +#define _GPIB_STATE_MACHINES_H + +enum talker_function_state { + talker_idle, + talker_addressed, + talker_active, + serial_poll_active +}; + +enum listener_function_state { + listener_idle, + listener_addressed, + listener_active +}; + +#endif // _GPIB_STATE_MACHINES_H diff --git a/drivers/staging/gpib/include/gpib_types.h b/drivers/staging/gpib/include/gpib_types.h new file mode 100644 index 0000000000000..ee2643da6d710 --- /dev/null +++ b/drivers/staging/gpib/include/gpib_types.h @@ -0,0 +1,353 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/*************************************************************************** + * copyright : (C) 2002 by Frank Mori Hess + ***************************************************************************/ + +#ifndef _GPIB_TYPES_H +#define _GPIB_TYPES_H + +#ifdef __KERNEL__ +/* gpib_interface_t defines the interface + * between the board-specific details dealt with in the drivers + * and generic interface provided by gpib-common. + * This really should be in a different header file. + */ +#include "gpib_user.h" +#include +#include +#include +#include +#include +#include +#include + +typedef struct gpib_interface_struct gpib_interface_t; +typedef struct gpib_board_struct gpib_board_t; + +/* config parameters that are only used by driver attach functions */ +typedef struct { + /* firmware blob */ + void *init_data; + int init_data_length; + /* IO base address to use for non-pnp cards (set by core, driver should make local copy) */ + void *ibbase; + /* IRQ to use for non-pnp cards (set by core, driver should make local copy) */ + unsigned int ibirq; + /* dma channel to use for non-pnp cards (set by core, driver should make local copy) */ + unsigned int ibdma; + /* pci bus of card, useful for distinguishing multiple identical pci cards + * (negative means don't care) + */ + int pci_bus; + /* pci slot of card, useful for distinguishing multiple identical pci cards + * (negative means don't care) + */ + int pci_slot; + /* sysfs device path of hardware to attach */ + char *device_path; + /* serial number of hardware to attach */ + char *serial_number; +} gpib_board_config_t; + +struct gpib_interface_struct { + /* name of board */ + char *name; + /* attach() initializes board and allocates resources */ + int (*attach)(gpib_board_t *board, const gpib_board_config_t *config); + /* detach() shuts down board and frees resources */ + void (*detach)(gpib_board_t *board); + /* read() should read at most 'length' bytes from the bus into + * 'buffer'. It should return when it fills the buffer or + * encounters an END (EOI and or EOS if appropriate). It should set 'end' + * to be nonzero if the read was terminated by an END, otherwise 'end' + * should be zero. + * Ultimately, this will be changed into or replaced by an asynchronous + * read. Zero return value for success, negative + * return indicates error. + * nbytes returns number of bytes read + */ + int (*read)(gpib_board_t *board, uint8_t *buffer, size_t length, int *end, + size_t *bytes_read); + /* write() should write 'length' bytes from buffer to the bus. + * If the boolean value send_eoi is nonzero, then EOI should + * be sent along with the last byte. Returns number of bytes + * written or negative value on error. + */ + int (*write)(gpib_board_t *board, uint8_t *buffer, size_t length, int send_eoi, + size_t *bytes_written); + /* command() writes the command bytes in 'buffer' to the bus + * Returns zero on success or negative value on error. + */ + int (*command)(gpib_board_t *board, uint8_t *buffer, size_t length, + size_t *bytes_written); + /* Take control (assert ATN). If 'asyncronous' is nonzero, take + * control asyncronously (assert ATN immediately without waiting + * for other processes to complete first). Should not return + * until board becomes controller in charge. Returns zero no success, + * nonzero on error. + */ + int (*take_control)(gpib_board_t *board, int asyncronous); + /* De-assert ATN. Returns zero on success, nonzer on error. + */ + int (*go_to_standby)(gpib_board_t *board); + /* request/release control of the IFC and REN lines (system controller) */ + void (*request_system_control)(gpib_board_t *board, int request_control); + /* Asserts or de-asserts 'interface clear' (IFC) depending on + * boolean value of 'assert' + */ + void (*interface_clear)(gpib_board_t *board, int assert); + /* Sends remote enable command if 'enable' is nonzero, disables remote mode + * if 'enable' is zero + */ + void (*remote_enable)(gpib_board_t *board, int enable); + /* enable END for reads, when byte 'eos' is received. If + * 'compare_8_bits' is nonzero, then all 8 bits are compared + * with the eos bytes. Otherwise only the 7 least significant + * bits are compared. + */ + int (*enable_eos)(gpib_board_t *board, uint8_t eos, int compare_8_bits); + /* disable END on eos byte (END on EOI only)*/ + void (*disable_eos)(gpib_board_t *board); + /* configure parallel poll */ + void (*parallel_poll_configure)(gpib_board_t *board, uint8_t configuration); + /* conduct parallel poll */ + int (*parallel_poll)(gpib_board_t *board, uint8_t *result); + /* set/clear ist (individual status bit) */ + void (*parallel_poll_response)(gpib_board_t *board, int ist); + /* select local parallel poll configuration mode PP2 versus remote PP1 */ + void (*local_parallel_poll_mode)(gpib_board_t *board, int local); + /* Returns current status of the bus lines. Should be set to + * NULL if your board does not have the ability to query the + * state of the bus lines. + */ + int (*line_status)(const gpib_board_t *board); + /* updates and returns the board's current status. + * The meaning of the bits are specified in gpib_user.h + * in the IBSTA section. The driver does not need to + * worry about setting the CMPL, END, TIMO, or ERR bits. + */ + unsigned int (*update_status)(gpib_board_t *board, unsigned int clear_mask); + /* Sets primary address 0-30 for gpib interface card. + */ + int (*primary_address)(gpib_board_t *board, unsigned int address); + /* Sets and enables, or disables secondary address 0-30 + * for gpib interface card. + */ + int (*secondary_address)(gpib_board_t *board, unsigned int address, + int enable); + /* Sets the byte the board should send in response to a serial poll. + * This function should also start or stop requests for service via + * IEEE 488.2 reqt/reqf, based on MSS (bit 6 of the status_byte). + * If the more flexible serial_poll_response2 is implemented by the + * driver, then this method should be left NULL since it will not + * be used. This method can generate spurious service requests + * which are allowed by IEEE 488.2, but not ideal. + * + * This method should implement the serial poll response method described + * by IEEE 488.2 section 11.3.3.4.3 "Allowed Coupled Control of + * STB, reqt, and reqf". + */ + void (*serial_poll_response)(gpib_board_t *board, uint8_t status_byte); + /* Sets the byte the board should send in response to a serial poll. + * This function should also request service via IEEE 488.2 reqt/reqf + * based on MSS (bit 6 of the status_byte) and new_reason_for_service. + * reqt should be set true if new_reason_for_service is true, + * and reqf should be set true if MSS is false. This function + * will never be called with MSS false and new_reason_for_service + * true simultaneously, so don't worry about that case. + * + * This method implements the serial poll response method described + * by IEEE 488.2 section 11.3.3.4.1 "Preferred Implementation". + * + * If this method is left NULL by the driver, then the user library + * function ibrsv2 will not work. + */ + void (*serial_poll_response2)(gpib_board_t *board, uint8_t status_byte, + int new_reason_for_service); + /* returns the byte the board will send in response to a serial poll. + */ + uint8_t (*serial_poll_status)(gpib_board_t *board); + /* adjust T1 delay */ + unsigned int (*t1_delay)(gpib_board_t *board, unsigned int nano_sec); + /* go to local mode */ + void (*return_to_local)(gpib_board_t *board); + /* board does not support 7 bit eos comparisons */ + unsigned no_7_bit_eos : 1; + /* skip check for listeners before trying to send command bytes */ + unsigned skip_check_for_command_acceptors : 1; +}; + +typedef struct { + struct list_head event_head; + spinlock_t lock; // for access to event list + unsigned int num_events; + unsigned dropped_event : 1; +} gpib_event_queue_t; + +static inline void init_event_queue(gpib_event_queue_t *queue) +{ + INIT_LIST_HEAD(&queue->event_head); + queue->num_events = 0; + queue->dropped_event = 0; + spin_lock_init(&queue->lock); +} + +/* struct for supporting polling operation when irq is not available */ +struct gpib_pseudo_irq { + struct timer_list timer; + irqreturn_t (*handler)(int irq, void *arg); + gpib_board_t *board; + atomic_t active; +}; + +static inline void init_gpib_pseudo_irq(struct gpib_pseudo_irq *pseudo_irq) +{ + pseudo_irq->handler = NULL; + timer_setup(&pseudo_irq->timer, NULL, 0); + atomic_set(&pseudo_irq->active, 0); +} + +/* list so we can make a linked list of drivers */ +typedef struct gpib_interface_list_struct { + struct list_head list; + gpib_interface_t *interface; + struct module *module; +} gpib_interface_list_t; + +/* One gpib_board_t is allocated for each physical board in the computer. + * It provides storage for variables local to each board, and interface + * functions for performing operations on the board + */ +struct gpib_board_struct { + /* functions used by this board */ + gpib_interface_t *interface; + /* Pointer to module whose use count we should increment when + * interface is in use + */ + struct module *provider_module; + /* buffer used to store read/write data for this board */ + u8 *buffer; + /* length of buffer */ + unsigned int buffer_length; + /* Used to hold the board's current status (see update_status() above) + */ + unsigned long status; + /* Driver should only sleep on this wait queue. It is special in that the + * core will wake this queue and set the TIMO bit in 'status' when the + * watchdog timer times out. + */ + wait_queue_head_t wait; + /* Lock that only allows one process to access this board at a time. + * Has to be first in any locking order, since it can be locked over + * multiple ioctls. + */ + struct mutex user_mutex; + /* Mutex which compensates for removal of "big kernel lock" from kernel. + * Should not be held for extended waits. + */ + struct mutex big_gpib_mutex; + /* pid of last process to lock the board mutex */ + pid_t locking_pid; + spinlock_t locking_pid_spinlock; // lock for setting locking pid + /* Spin lock for dealing with races with the interrupt handler */ + spinlock_t spinlock; + /* Watchdog timer to enable timeouts */ + struct timer_list timer; + /* device of attached driver if any */ + struct device *dev; + /* gpib_common device gpibN */ + struct device *gpib_dev; + /* 'private_data' can be used as seen fit by the driver to + * store additional variables for this board + */ + void *private_data; + /* Number of open file descriptors using this board */ + unsigned int use_count; + /* list of open devices connected to this board */ + struct list_head device_list; + /* primary address */ + unsigned int pad; + /* secondary address */ + int sad; + /* timeout for io operations, in microseconds */ + unsigned int usec_timeout; + /* board's parallel poll configuration byte */ + u8 parallel_poll_configuration; + /* t1 delay we are using */ + unsigned int t1_nano_sec; + /* Count that keeps track of whether board is up and running or not */ + unsigned int online; + /* number of processes trying to autopoll */ + int autospollers; + /* autospoll kernel thread */ + struct task_struct *autospoll_task; + /* queue for recording received trigger/clear/ifc events */ + gpib_event_queue_t event_queue; + /* minor number for this board's device file */ + int minor; + /* struct to deal with polling mode*/ + struct gpib_pseudo_irq pseudo_irq; + /* error dong autopoll */ + atomic_t stuck_srq; + gpib_board_config_t config; + /* Flag that indicates whether board is system controller of the bus */ + unsigned master : 1; + /* individual status bit */ + unsigned ist : 1; + /* one means local parallel poll mode ieee 488.1 PP2 (or no parallel poll PP0), + * zero means remote parallel poll configuration mode ieee 488.1 PP1 + */ + unsigned local_ppoll_mode : 1; +}; + +/* element of event queue */ +typedef struct { + struct list_head list; + short event_type; +} gpib_event_t; + +/* Each board has a list of gpib_status_queue_t to keep track of all open devices + * on the bus, so we know what address to poll when we get a service request + */ +typedef struct { + /* list_head so we can make a linked list of devices */ + struct list_head list; + unsigned int pad; /* primary gpib address */ + int sad; /* secondary gpib address (negative means disabled) */ + /* stores serial poll bytes for this device */ + struct list_head status_bytes; + unsigned int num_status_bytes; + /* number of times this address is opened */ + unsigned int reference_count; + /* flags loss of status byte error due to limit on size of queue */ + unsigned dropped_byte : 1; +} gpib_status_queue_t; + +typedef struct { + struct list_head list; + u8 poll_byte; +} status_byte_t; + +void init_gpib_status_queue(gpib_status_queue_t *device); + +/* Used to store device-descriptor-specific information */ +typedef struct { + unsigned int pad; /* primary gpib address */ + int sad; /* secondary gpib address (negative means disabled) */ + atomic_t io_in_progress; + unsigned is_board : 1; + unsigned autopoll_enabled : 1; +} gpib_descriptor_t; + +typedef struct { + atomic_t holding_mutex; + gpib_descriptor_t *descriptors[GPIB_MAX_NUM_DESCRIPTORS]; + /* locked while descriptors are being allocated/deallocated */ + struct mutex descriptors_mutex; + unsigned got_module : 1; +} gpib_file_private_t; + +#endif /* __KERNEL__ */ + +#endif /* _GPIB_TYPES_H */ diff --git a/drivers/staging/gpib/include/nec7210.h b/drivers/staging/gpib/include/nec7210.h new file mode 100644 index 0000000000000..c00aba4ce846d --- /dev/null +++ b/drivers/staging/gpib/include/nec7210.h @@ -0,0 +1,138 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/*************************************************************************** + * copyright : (C) 2002 by Frank Mori Hess + ***************************************************************************/ + +#ifndef _NEC7210_H +#define _NEC7210_H + +#include "gpib_state_machines.h" +#include +#include +#include +#include + +#include "gpib_types.h" +#include "nec7210_registers.h" + +/* struct used to provide variables local to a nec7210 chip */ +struct nec7210_priv { + void *iobase; + unsigned int offset; // offset between successive nec7210 io addresses + unsigned int dma_channel; + u8 *dma_buffer; + unsigned int dma_buffer_length; // length of dma buffer + dma_addr_t dma_buffer_addr; // bus address of board->buffer for use with dma + // software copy of bits written to registers + u8 reg_bits[8]; + u8 auxa_bits; // bits written to auxiliary register A + u8 auxb_bits; // bits written to auxiliary register B + // used to keep track of board's state, bit definitions given below + unsigned long state; + /* lock for chips that extend the nec7210 registers by paging in alternate regs */ + spinlock_t register_page_lock; + // wrappers for outb, inb, readb, or writeb + u8 (*read_byte)(struct nec7210_priv *priv, unsigned int register_number); + void (*write_byte)(struct nec7210_priv *priv, u8 byte, unsigned int register_number); + enum nec7210_chipset type; + enum talker_function_state talker_state; + enum listener_function_state listener_state; + void *private; + unsigned srq_pending : 1; +}; + +static inline void init_nec7210_private(struct nec7210_priv *priv) +{ + memset(priv, 0, sizeof(struct nec7210_priv)); + spin_lock_init(&priv->register_page_lock); +} + +// slightly shorter way to access read_byte and write_byte +static inline u8 read_byte(struct nec7210_priv *priv, unsigned int register_number) +{ + return priv->read_byte(priv, register_number); +} + +static inline void write_byte(struct nec7210_priv *priv, u8 byte, unsigned int register_number) +{ + priv->write_byte(priv, byte, register_number); +} + +// struct nec7210_priv.state bit numbers +enum { + PIO_IN_PROGRESS_BN, // pio transfer in progress + DMA_READ_IN_PROGRESS_BN, // dma read transfer in progress + DMA_WRITE_IN_PROGRESS_BN, // dma write transfer in progress + READ_READY_BN, // board has data byte available to read + WRITE_READY_BN, // board is ready to send a data byte + COMMAND_READY_BN, // board is ready to send a command byte + RECEIVED_END_BN, // received END + BUS_ERROR_BN, // output error has occurred + RFD_HOLDOFF_BN, // rfd holdoff in effect + DEV_CLEAR_BN, // device clear received + ADR_CHANGE_BN, // address state change occurred +}; + +// interface functions +int nec7210_read(gpib_board_t *board, struct nec7210_priv *priv, uint8_t *buffer, + size_t length, int *end, size_t *bytes_read); +int nec7210_write(gpib_board_t *board, struct nec7210_priv *priv, uint8_t *buffer, + size_t length, int send_eoi, size_t *bytes_written); +int nec7210_command(gpib_board_t *board, struct nec7210_priv *priv, uint8_t *buffer, + size_t length, size_t *bytes_written); +int nec7210_take_control(gpib_board_t *board, struct nec7210_priv *priv, int syncronous); +int nec7210_go_to_standby(gpib_board_t *board, struct nec7210_priv *priv); +void nec7210_request_system_control(gpib_board_t *board, + struct nec7210_priv *priv, int request_control); +void nec7210_interface_clear(gpib_board_t *board, struct nec7210_priv *priv, int assert); +void nec7210_remote_enable(gpib_board_t *board, struct nec7210_priv *priv, int enable); +int nec7210_enable_eos(gpib_board_t *board, struct nec7210_priv *priv, uint8_t eos_bytes, + int compare_8_bits); +void nec7210_disable_eos(gpib_board_t *board, struct nec7210_priv *priv); +unsigned int nec7210_update_status(gpib_board_t *board, struct nec7210_priv *priv, + unsigned int clear_mask); +unsigned int nec7210_update_status_nolock(gpib_board_t *board, struct nec7210_priv *priv); +int nec7210_primary_address(const gpib_board_t *board, + struct nec7210_priv *priv, unsigned int address); +int nec7210_secondary_address(const gpib_board_t *board, struct nec7210_priv *priv, + unsigned int address, int enable); +int nec7210_parallel_poll(gpib_board_t *board, struct nec7210_priv *priv, uint8_t *result); +void nec7210_serial_poll_response(gpib_board_t *board, struct nec7210_priv *priv, uint8_t status); +void nec7210_parallel_poll_configure(gpib_board_t *board, + struct nec7210_priv *priv, unsigned int configuration); +void nec7210_parallel_poll_response(gpib_board_t *board, + struct nec7210_priv *priv, int ist); +uint8_t nec7210_serial_poll_status(gpib_board_t *board, + struct nec7210_priv *priv); +unsigned int nec7210_t1_delay(gpib_board_t *board, + struct nec7210_priv *priv, unsigned int nano_sec); +void nec7210_return_to_local(const gpib_board_t *board, struct nec7210_priv *priv); + +// utility functions +void nec7210_board_reset(struct nec7210_priv *priv, const gpib_board_t *board); +void nec7210_board_online(struct nec7210_priv *priv, const gpib_board_t *board); +unsigned int nec7210_set_reg_bits(struct nec7210_priv *priv, unsigned int reg, + unsigned int mask, unsigned int bits); +void nec7210_set_handshake_mode(gpib_board_t *board, struct nec7210_priv *priv, int mode); +void nec7210_release_rfd_holdoff(gpib_board_t *board, struct nec7210_priv *priv); +uint8_t nec7210_read_data_in(gpib_board_t *board, struct nec7210_priv *priv, int *end); + +// wrappers for io functions +uint8_t nec7210_ioport_read_byte(struct nec7210_priv *priv, unsigned int register_num); +void nec7210_ioport_write_byte(struct nec7210_priv *priv, uint8_t data, unsigned int register_num); +uint8_t nec7210_iomem_read_byte(struct nec7210_priv *priv, unsigned int register_num); +void nec7210_iomem_write_byte(struct nec7210_priv *priv, uint8_t data, unsigned int register_num); +uint8_t nec7210_locking_ioport_read_byte(struct nec7210_priv *priv, unsigned int register_num); +void nec7210_locking_ioport_write_byte(struct nec7210_priv *priv, uint8_t data, + unsigned int register_num); +uint8_t nec7210_locking_iomem_read_byte(struct nec7210_priv *priv, unsigned int register_num); +void nec7210_locking_iomem_write_byte(struct nec7210_priv *priv, uint8_t data, + unsigned int register_num); + +// interrupt service routine +irqreturn_t nec7210_interrupt(gpib_board_t *board, struct nec7210_priv *priv); +irqreturn_t nec7210_interrupt_have_status(gpib_board_t *board, + struct nec7210_priv *priv, int status1, int status2); + +#endif //_NEC7210_H diff --git a/drivers/staging/gpib/include/nec7210_registers.h b/drivers/staging/gpib/include/nec7210_registers.h new file mode 100644 index 0000000000000..2ad512c372c4d --- /dev/null +++ b/drivers/staging/gpib/include/nec7210_registers.h @@ -0,0 +1,217 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/*************************************************************************** + * copyright : (C) 2002 by Frank Mori Hess + ***************************************************************************/ + +#ifndef _NEC7210_REGISTERS_H +#define _NEC7210_REGISTERS_H + +enum nec7210_chipset { + NEC7210, // The original + TNT4882, // NI + NAT4882, // NI + CB7210, // measurement computing + IOT7210, // iotech + IGPIB7210, // Ines + TNT5004, // NI (minor differences to TNT4882) +}; + +// nec7210 has 8 registers +static const int nec7210_num_registers = 8; + +/* nec7210 register numbers (might need to be multiplied by + * a board-dependent offset to get actually io address offset) + */ +// write registers +enum nec7210_write_regs { + CDOR, // command/data out + IMR1, // interrupt mask 1 + IMR2, // interrupt mask 2 + SPMR, // serial poll mode + ADMR, // address mode + AUXMR, // auxiliary mode + ADR, // address + EOSR, // end-of-string +}; + +// read registers +enum nec7210_read_regs { + DIR, // data in + ISR1, // interrupt status 1 + ISR2, // interrupt status 2 + SPSR, // serial poll status + ADSR, // address status + CPTR, // command pass though + ADR0, // address 1 + ADR1, // address 2 +}; + +//bit definitions common to nec-7210 compatible registers + +// ISR1: interrupt status register 1 +enum isr1_bits { + HR_DI = (1 << 0), + HR_DO = (1 << 1), + HR_ERR = (1 << 2), + HR_DEC = (1 << 3), + HR_END = (1 << 4), + HR_DET = (1 << 5), + HR_APT = (1 << 6), + HR_CPT = (1 << 7), +}; + +// IMR1: interrupt mask register 1 +enum imr1_bits { + HR_DIIE = (1 << 0), + HR_DOIE = (1 << 1), + HR_ERRIE = (1 << 2), + HR_DECIE = (1 << 3), + HR_ENDIE = (1 << 4), + HR_DETIE = (1 << 5), + HR_APTIE = (1 << 6), + HR_CPTIE = (1 << 7), +}; + +// ISR2, interrupt status register 2 +enum isr2_bits { + HR_ADSC = (1 << 0), + HR_REMC = (1 << 1), + HR_LOKC = (1 << 2), + HR_CO = (1 << 3), + HR_REM = (1 << 4), + HR_LOK = (1 << 5), + HR_SRQI = (1 << 6), + HR_INT = (1 << 7), +}; + +// IMR2, interrupt mask register 2 +enum imr2_bits { + // all the bits in this register that enable interrupts + IMR2_ENABLE_INTR_MASK = 0x4f, + HR_ACIE = (1 << 0), + HR_REMIE = (1 << 1), + HR_LOKIE = (1 << 2), + HR_COIE = (1 << 3), + HR_DMAI = (1 << 4), + HR_DMAO = (1 << 5), + HR_SRQIE = (1 << 6), +}; + +// SPSR, serial poll status register +enum spsr_bits { + HR_PEND = (1 << 6), +}; + +// SPMR, serial poll mode register +enum spmr_bits { + HR_RSV = (1 << 6), +}; + +// ADSR, address status register +enum adsr_bits { + HR_MJMN = (1 << 0), + HR_TA = (1 << 1), + HR_LA = (1 << 2), + HR_TPAS = (1 << 3), + HR_LPAS = (1 << 4), + HR_SPMS = (1 << 5), + HR_NATN = (1 << 6), + HR_CIC = (1 << 7), +}; + +// ADMR, address mode register +enum admr_bits { + HR_ADM0 = (1 << 0), + HR_ADM1 = (1 << 1), + HR_TRM0 = (1 << 4), + HR_TRM1 = (1 << 5), + HR_TRM_EOIOE_TRIG = 0, + HR_TRM_CIC_TRIG = HR_TRM0, + HR_TRM_CIC_EOIOE = HR_TRM1, + HR_TRM_CIC_PE = HR_TRM0 | HR_TRM1, + HR_LON = (1 << 6), + HR_TON = (1 << 7), +}; + +// ADR, bits used in address0, address1 and address0/1 registers +enum adr_bits { + ADDRESS_MASK = 0x1f, /* mask to specify lower 5 bits */ + HR_DL = (1 << 5), + HR_DT = (1 << 6), + HR_ARS = (1 << 7), +}; + +// ADR1, address1 register +enum adr1_bits { + HR_EOI = (1 << 7), +}; + +// AUXMR, auxiliary mode register +enum auxmr_bits { + ICR = 0x20, + PPR = 0x60, + AUXRA = 0x80, + AUXRB = 0xa0, + AUXRE = 0xc0, +}; + +// auxra, auxiliary register A +enum auxra_bits { + HR_HANDSHAKE_MASK = 0x3, + HR_HLDA = 0x1, + HR_HLDE = 0x2, + HR_LCM = 0x3, /* auxra listen continuous */ + HR_REOS = 0x4, + HR_XEOS = 0x8, + HR_BIN = 0x10, +}; + +// auxrb, auxiliary register B +enum auxrb_bits { + HR_CPTE = (1 << 0), + HR_SPEOI = (1 << 1), + HR_TRI = (1 << 2), + HR_INV = (1 << 3), + HR_ISS = (1 << 4), +}; + +enum auxre_bits { + HR_DAC_HLD_DCAS = 0x1, /* perform DAC holdoff on receiving clear */ + HR_DAC_HLD_DTAS = 0x2, /* perform DAC holdoff on receiving trigger */ +}; + +// parallel poll register +enum ppr_bits { + HR_PPS = (1 << 3), + HR_PPU = (1 << 4), +}; + +/* 7210 Auxiliary Commands */ +enum aux_cmds { + AUX_PON = 0x0, /* Immediate Execute pon */ + AUX_CPPF = 0x1, /* Clear Parallel Poll Flag */ + AUX_CR = 0x2, /* Chip Reset */ + AUX_FH = 0x3, /* Finish Handshake */ + AUX_TRIG = 0x4, /* Trigger */ + AUX_RTL = 0x5, /* Return to local */ + AUX_SEOI = 0x6, /* Send EOI */ + AUX_NVAL = 0x7, /* Non-Valid Secondary Command or Address */ + AUX_SPPF = 0x9, /* Set Parallel Poll Flag */ + AUX_VAL = 0xf, /* Valid Secondary Command or Address */ + AUX_GTS = 0x10, /* Go To Standby */ + AUX_TCA = 0x11, /* Take Control Asynchronously */ + AUX_TCS = 0x12, /* Take Control Synchronously */ + AUX_LTN = 0x13, /* Listen */ + AUX_DSC = 0x14, /* Disable System Control */ + AUX_CIFC = 0x16, /* Clear IFC */ + AUX_CREN = 0x17, /* Clear REN */ + AUX_TCSE = 0x1a, /* Take Control Synchronously on End */ + AUX_LTNC = 0x1b, /* Listen in Continuous Mode */ + AUX_LUN = 0x1c, /* Local Unlisten */ + AUX_EPP = 0x1d, /* Execute Parallel Poll */ + AUX_SIFC = 0x1e, /* Set IFC */ + AUX_SREN = 0x1f, /* Set REN */ +}; + +#endif //_NEC7210_REGISTERS_H diff --git a/drivers/staging/gpib/include/plx9050.h b/drivers/staging/gpib/include/plx9050.h new file mode 100644 index 0000000000000..66c56335f5c0b --- /dev/null +++ b/drivers/staging/gpib/include/plx9050.h @@ -0,0 +1,72 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/*************************************************************************** + * Header for plx9050 pci chip + * copyright : (C) 2002 by Frank Mori Hess + ***************************************************************************/ + +#ifndef _PLX9050_GPIB_H +#define _PLX9050_GPIB_H + +// plx pci chip registers and bits +enum { + PLX9050_INTCSR_REG = 0x4c, + PLX9050_CNTRL_REG = 0x50 +}; + +enum plx9050_intcsr_bits { + PLX9050_LINTR1_EN_BIT = 0x1, + PLX9050_LINTR1_POLARITY_BIT = 0x2, + PLX9050_LINTR1_STATUS_BIT = 0x4, + PLX9050_LINTR2_EN_BIT = 0x8, + PLX9050_LINTR2_POLARITY_BIT = 0x10, + PLX9050_LINTR2_STATUS_BIT = 0x20, + PLX9050_PCI_INTR_EN_BIT = 0x40, + PLX9050_SOFT_INTR_BIT = 0x80, + PLX9050_LINTR1_SELECT_ENABLE_BIT = 0x100, //9052 extension + PLX9050_LINTR2_SELECT_ENABLE_BIT = 0x200, //9052 extension + PLX9050_LINTR1_EDGE_CLEAR_BIT = 0x400, //9052 extension + PLX9050_LINTR2_EDGE_CLEAR_BIT = 0x800, //9052 extension +}; + +enum plx9050_cntrl_bits { + PLX9050_WAITO_NOT_USER0_SELECT_BIT = 0x1, + PLX9050_USER0_OUTPUT_BIT = 0x2, + PLX9050_USER0_DATA_BIT = 0x4, + PLX9050_LLOCK_NOT_USER1_SELECT_BIT = 0x8, + PLX9050_USER1_OUTPUT_BIT = 0x10, + PLX9050_USER1_DATA_BIT = 0x20, + PLX9050_CS2_NOT_USER2_SELECT_BIT = 0x40, + PLX9050_USER2_OUTPUT_BIT = 0x80, + PLX9050_USER2_DATA_BIT = 0x100, + PLX9050_CS3_NOT_USER3_SELECT_BIT = 0x200, + PLX9050_USER3_OUTPUT_BIT = 0x400, + PLX9050_USER3_DATA_BIT = 0x800, + PLX9050_PCIBAR_ENABLE_MASK = 0x3000, + PLX9050_PCIBAR_MEMORY_AND_IO_ENABLE_BITS = 0x0, + PLX9050_PCIBAR_MEMORY_NO_IO_ENABLE_BITS = 0x1000, + PLX9050_PCIBAR_IO_NO_MEMORY_ENABLE_BITS = 0x2000, + PLX9050_PCIBAR_MEMORY_AND_IO_TOO_ENABLE_BITS = 0x3000, + PLX9050_PCI_READ_MODE_BIT = 0x4000, + PLX9050_PCI_READ_WITH_WRITE_FLUSH_MODE_BIT = 0x8000, + PLX9050_PCI_READ_NO_FLUSH_MODE_BIT = 0x10000, + PLX9050_PCI_READ_NO_WRITE_MODE_BIT = 0x20000, + PLX9050_PCI_WRITE_MODE_BIT = 0x40000, + PLX9050_PCI_RETRY_DELAY_MASK = 0x780000, + PLX9050_DIRECT_SLAVE_LOCK_ENABLE_BIT = 0x800000, + PLX9050_EEPROM_CLOCK_BIT = 0x1000000, + PLX9050_EEPROM_CHIP_SELECT_BIT = 0x2000000, + PLX9050_WRITE_TO_EEPROM_BIT = 0x4000000, + PLX9050_READ_EEPROM_DATA_BIT = 0x8000000, + PLX9050_EEPROM_VALID_BIT = 0x10000000, + PLX9050_RELOAD_CONFIG_REGISTERS_BIT = 0x20000000, + PLX9050_PCI_SOFTWARE_RESET_BIT = 0x40000000, + PLX9050_MASK_REVISION_BIT = 0x80000000 +}; + +static inline unsigned int PLX9050_PCI_RETRY_DELAY_BITS(unsigned int clocks) +{ + return ((clocks / 8) << 19) & PLX9050_PCI_RETRY_DELAY_MASK; +} + +#endif // _PLX9050_GPIB_H diff --git a/drivers/staging/gpib/include/quancom_pci.h b/drivers/staging/gpib/include/quancom_pci.h new file mode 100644 index 0000000000000..cdaf0d056be9e --- /dev/null +++ b/drivers/staging/gpib/include/quancom_pci.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/*************************************************************************** + * Quancom pci stuff + * copyright (C) 2005 by Frank Mori Hess + ***************************************************************************/ + +#ifndef _QUANCOM_PCI_H +#define _QUANCOM_PCI_H + +/* quancom registers */ +enum quancom_regs { + QUANCOM_IRQ_CONTROL_STATUS_REG = 0xfc, +}; + +enum quancom_irq_control_status_bits { + QUANCOM_IRQ_ASSERTED_BIT = 0x1, /* readable */ + /* (any write to the register clears the interrupt)*/ + QUANCOM_IRQ_ENABLE_BIT = 0x4, /* writeable */ +}; + +#endif // _QUANCOM_PCI_H diff --git a/drivers/staging/gpib/include/tms9914.h b/drivers/staging/gpib/include/tms9914.h new file mode 100644 index 0000000000000..1cbba02c35815 --- /dev/null +++ b/drivers/staging/gpib/include/tms9914.h @@ -0,0 +1,272 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/*************************************************************************** + * copyright : (C) 2002 by Frank Mori Hess + ***************************************************************************/ + +#ifndef _TMS9914_H +#define _TMS9914_H + +#include +#include +#include "gpib_state_machines.h" +#include "gpib_types.h" + +enum tms9914_holdoff_mode { + TMS9914_HOLDOFF_NONE, + TMS9914_HOLDOFF_EOI, + TMS9914_HOLDOFF_ALL, +}; + +/* struct used to provide variables local to a tms9914 chip */ +struct tms9914_priv { + void *iobase; + unsigned int offset; // offset between successive tms9914 io addresses + unsigned int dma_channel; + // software copy of bits written to interrupt mask registers + u8 imr0_bits, imr1_bits; + // bits written to address mode register + u8 admr_bits; + u8 auxa_bits; // bits written to auxiliary register A + // used to keep track of board's state, bit definitions given below + unsigned long state; + u8 eos; // eos character + short eos_flags; + u8 spoll_status; + enum tms9914_holdoff_mode holdoff_mode; + unsigned int ppoll_line; + enum talker_function_state talker_state; + enum listener_function_state listener_state; + unsigned ppoll_sense : 1; + unsigned ppoll_enable : 1; + unsigned ppoll_configure_state : 1; + unsigned primary_listen_addressed : 1; + unsigned primary_talk_addressed : 1; + unsigned holdoff_on_end : 1; + unsigned holdoff_on_all : 1; + unsigned holdoff_active : 1; + // wrappers for outb, inb, readb, or writeb + u8 (*read_byte)(struct tms9914_priv *priv, unsigned int register_number); + void (*write_byte)(struct tms9914_priv *priv, u8 byte, unsigned int + register_number); +}; + +// slightly shorter way to access read_byte and write_byte +static inline u8 read_byte(struct tms9914_priv *priv, unsigned int register_number) +{ + return priv->read_byte(priv, register_number); +} + +static inline void write_byte(struct tms9914_priv *priv, u8 byte, unsigned int register_number) +{ + priv->write_byte(priv, byte, register_number); +} + +// struct tms9914_priv.state bit numbers +enum { + PIO_IN_PROGRESS_BN, // pio transfer in progress + DMA_READ_IN_PROGRESS_BN, // dma read transfer in progress + DMA_WRITE_IN_PROGRESS_BN, // dma write transfer in progress + READ_READY_BN, // board has data byte available to read + WRITE_READY_BN, // board is ready to send a data byte + COMMAND_READY_BN, // board is ready to send a command byte + RECEIVED_END_BN, // received END + BUS_ERROR_BN, // bus error + DEV_CLEAR_BN, // device clear received +}; + +// interface functions +int tms9914_read(gpib_board_t *board, struct tms9914_priv *priv, uint8_t *buffer, + size_t length, int *end, size_t *bytes_read); +int tms9914_write(gpib_board_t *board, struct tms9914_priv *priv, uint8_t *buffer, + size_t length, int send_eoi, size_t *bytes_written); +int tms9914_command(gpib_board_t *board, struct tms9914_priv *priv, uint8_t *buffer, + size_t length, size_t *bytes_written); +int tms9914_take_control(gpib_board_t *board, struct tms9914_priv *priv, int syncronous); +/* alternate version of tms9914_take_control which works around buggy tcs + * implementation. + */ +int tms9914_take_control_workaround(gpib_board_t *board, struct tms9914_priv *priv, + int syncronous); +int tms9914_go_to_standby(gpib_board_t *board, struct tms9914_priv *priv); +void tms9914_request_system_control(gpib_board_t *board, struct tms9914_priv *priv, + int request_control); +void tms9914_interface_clear(gpib_board_t *board, struct tms9914_priv *priv, int assert); +void tms9914_remote_enable(gpib_board_t *board, struct tms9914_priv *priv, int enable); +int tms9914_enable_eos(gpib_board_t *board, struct tms9914_priv *priv, uint8_t eos_bytes, + int compare_8_bits); +void tms9914_disable_eos(gpib_board_t *board, struct tms9914_priv *priv); +unsigned int tms9914_update_status(gpib_board_t *board, struct tms9914_priv *priv, + unsigned int clear_mask); +int tms9914_primary_address(gpib_board_t *board, + struct tms9914_priv *priv, unsigned int address); +int tms9914_secondary_address(gpib_board_t *board, struct tms9914_priv *priv, + unsigned int address, int enable); +int tms9914_parallel_poll(gpib_board_t *board, struct tms9914_priv *priv, uint8_t *result); +void tms9914_parallel_poll_configure(gpib_board_t *board, + struct tms9914_priv *priv, uint8_t config); +void tms9914_parallel_poll_response(gpib_board_t *board, + struct tms9914_priv *priv, int ist); +void tms9914_serial_poll_response(gpib_board_t *board, struct tms9914_priv *priv, uint8_t status); +uint8_t tms9914_serial_poll_status(gpib_board_t *board, struct tms9914_priv *priv); +int tms9914_line_status(const gpib_board_t *board, struct tms9914_priv *priv); +unsigned int tms9914_t1_delay(gpib_board_t *board, struct tms9914_priv *priv, + unsigned int nano_sec); +void tms9914_return_to_local(const gpib_board_t *board, struct tms9914_priv *priv); + +// utility functions +void tms9914_board_reset(struct tms9914_priv *priv); +void tms9914_online(gpib_board_t *board, struct tms9914_priv *priv); +void tms9914_release_holdoff(struct tms9914_priv *priv); +void tms9914_set_holdoff_mode(struct tms9914_priv *priv, enum tms9914_holdoff_mode mode); + +// wrappers for io functions +uint8_t tms9914_ioport_read_byte(struct tms9914_priv *priv, unsigned int register_num); +void tms9914_ioport_write_byte(struct tms9914_priv *priv, uint8_t data, unsigned int register_num); +uint8_t tms9914_iomem_read_byte(struct tms9914_priv *priv, unsigned int register_num); +void tms9914_iomem_write_byte(struct tms9914_priv *priv, uint8_t data, unsigned int register_num); + +// interrupt service routine +irqreturn_t tms9914_interrupt(gpib_board_t *board, struct tms9914_priv *priv); +irqreturn_t tms9914_interrupt_have_status(gpib_board_t *board, struct tms9914_priv *priv, + int status1, int status2); + +// tms9914 has 8 registers +static const int tms9914_num_registers = 8; + +/* tms9914 register numbers (might need to be multiplied by + * a board-dependent offset to get actually io address offset) + */ +// write registers +enum { + IMR0 = 0, /* interrupt mask 0 */ + IMR1 = 1, /* interrupt mask 1 */ + AUXCR = 3, /* auxiliary command */ + ADR = 4, // address register + SPMR = 5, // serial poll mode register + PPR = 6, /* parallel poll */ + CDOR = 7, /* data out register */ +}; + +// read registers +enum { + ISR0 = 0, /* interrupt status 0 */ + ISR1 = 1, /* interrupt status 1 */ + ADSR = 2, /* address status */ + BSR = 3, /* bus status */ + CPTR = 6, /* command pass thru */ + DIR = 7, /* data in register */ +}; + +//bit definitions common to tms9914 compatible registers + +/* ISR0 - Register bits */ +enum isr0_bits { + HR_MAC = (1 << 0), /* My Address Change */ + HR_RLC = (1 << 1), /* Remote/Local change */ + HR_SPAS = (1 << 2), /* Serial Poll active State */ + HR_END = (1 << 3), /* END (EOI or EOS) */ + HR_BO = (1 << 4), /* Byte Out */ + HR_BI = (1 << 5), /* Byte In */ +}; + +/* IMR0 - Register bits */ +enum imr0_bits { + HR_MACIE = (1 << 0), /* */ + HR_RLCIE = (1 << 1), /* */ + HR_SPASIE = (1 << 2), /* */ + HR_ENDIE = (1 << 3), /* */ + HR_BOIE = (1 << 4), /* */ + HR_BIIE = (1 << 5), /* */ +}; + +/* ISR1 - Register bits */ +enum isr1_bits { + HR_IFC = (1 << 0), /* IFC asserted */ + HR_SRQ = (1 << 1), /* SRQ asserted */ + HR_MA = (1 << 2), /* My Address */ + HR_DCAS = (1 << 3), /* Device Clear active State */ + HR_APT = (1 << 4), /* Address pass Through */ + HR_UNC = (1 << 5), /* Unrecognized Command */ + HR_ERR = (1 << 6), /* Data Transmission Error */ + HR_GET = (1 << 7), /* Group execute Trigger */ +}; + +/* IMR1 - Register bits */ +enum imr1_bits { + HR_IFCIE = (1 << 0), /* */ + HR_SRQIE = (1 << 1), /* */ + HR_MAIE = (1 << 2), /* */ + HR_DCASIE = (1 << 3), /* */ + HR_APTIE = (1 << 4), /* */ + HR_UNCIE = (1 << 5), /* */ + HR_ERRIE = (1 << 6), /* */ + HR_GETIE = (1 << 7), /* */ +}; + +/* ADSR - Register bits */ +enum adsr_bits { + HR_ULPA = (1 << 0), /* Store last address LSB */ + HR_TA = (1 << 1), /* Talker Adressed */ + HR_LA = (1 << 2), /* Listener adressed */ + HR_TPAS = (1 << 3), /* talker primary address state */ + HR_LPAS = (1 << 4), /* listener " */ + HR_ATN = (1 << 5), /* ATN active */ + HR_LLO = (1 << 6), /* LLO active */ + HR_REM = (1 << 7), /* REM active */ +}; + +/* ADR - Register bits */ +enum adr_bits { + ADDRESS_MASK = 0x1f, /* mask to specify lower 5 bits for ADR */ + HR_DAT = (1 << 5), /* disable talker */ + HR_DAL = (1 << 6), /* disable listener */ + HR_EDPA = (1 << 7), /* enable dual primary addressing */ +}; + +enum bus_status_bits { + BSR_REN_BIT = 0x1, + BSR_IFC_BIT = 0x2, + BSR_SRQ_BIT = 0x4, + BSR_EOI_BIT = 0x8, + BSR_NRFD_BIT = 0x10, + BSR_NDAC_BIT = 0x20, + BSR_DAV_BIT = 0x40, + BSR_ATN_BIT = 0x80, +}; + +/*---------------------------------------------------------*/ +/* TMS 9914 Auxiliary Commands */ +/*---------------------------------------------------------*/ + +enum aux_cmd_bits { + AUX_CS = 0x80, /* set bit instead of clearing it, used with commands marked 'd' below */ + AUX_CHIP_RESET = 0x0, /* d Chip reset */ + AUX_INVAL = 0x1, // release dac holdoff, invalid command byte + AUX_VAL = (AUX_INVAL | AUX_CS), // release dac holdoff, valid command byte + AUX_RHDF = 0x2, /* X Release RFD holdoff */ + AUX_HLDA = 0x3, /* d holdoff on all data */ + AUX_HLDE = 0x4, /* d holdoff on EOI only */ + AUX_NBAF = 0x5, /* X Set new byte available false */ + AUX_FGET = 0x6, /* d force GET */ + AUX_RTL = 0x7, /* d return to local */ + AUX_SEOI = 0x8, /* X send EOI with next byte */ + AUX_LON = 0x9, /* d Listen only */ + AUX_TON = 0xa, /* d Talk only */ + AUX_GTS = 0xb, /* X goto standby */ + AUX_TCA = 0xc, /* X take control asynchronously */ + AUX_TCS = 0xd, /* X take " synchronously */ + AUX_RPP = 0xe, /* d Request parallel poll */ + AUX_SIC = 0xf, /* d send interface clear */ + AUX_SRE = 0x10, /* d send remote enable */ + AUX_RQC = 0x11, /* X request control */ + AUX_RLC = 0x12, /* X release control */ + AUX_DAI = 0x13, /* d disable all interrupts */ + AUX_PTS = 0x14, /* X pass through next secondary */ + AUX_STDL = 0x15, /* d short T1 delay */ + AUX_SHDW = 0x16, /* d shadow handshake */ + AUX_VSTDL = 0x17, /* d very short T1 delay (smj9914 extension) */ + AUX_RSV2 = 0x18, /* d request service bit 2 (smj9914 extension) */ +}; + +#endif //_TMS9914_H diff --git a/drivers/staging/gpib/include/tnt4882_registers.h b/drivers/staging/gpib/include/tnt4882_registers.h new file mode 100644 index 0000000000000..f0a719772f413 --- /dev/null +++ b/drivers/staging/gpib/include/tnt4882_registers.h @@ -0,0 +1,190 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/*************************************************************************** + * copyright : (C) 2002, 2004 by Frank Mori Hess + ***************************************************************************/ + +#ifndef _TNT4882_REGISTERS_H +#define _TNT4882_REGISTERS_H + +// tnt4882 register offsets +enum { + ACCWR = 0x5, + // offset of auxiliary command register in 9914 mode + AUXCR = 0x6, + INTRT = 0x7, + // register number for auxiliary command register when swap bit is set (9914 mode) + SWAPPED_AUXCR = 0xa, + HSSEL = 0xd, // handshake select register + CNT2 = 0x9, + CNT3 = 0xb, + CFG = 0x10, + SASR = 0x1b, + IMR0 = 0x1d, + IMR3 = 0x12, + CNT0 = 0x14, + CNT1 = 0x16, + KEYREG = 0x17, // key control register (7210 mode only) + CSR = KEYREG, + FIFOB = 0x18, + FIFOA = 0x19, + CCR = 0x1a, // carry cycle register + CMDR = 0x1c, // command register + TIMER = 0x1e, // timer register + + STS1 = 0x10, /* T488 Status Register 1 */ + STS2 = 0x1c, /* T488 Status Register 2 */ + ISR0 = IMR0, + ISR3 = 0x1a, /* T488 Interrupt Status Register 3 */ + BCR = 0x1f, /* bus control/status register */ + BSR = BCR, +}; + +static const int tnt_pagein_offset = 0x11; + +/*============================================================*/ + +/* TURBO-488 registers bit definitions */ + +enum bus_control_status_bits { + BCSR_REN_BIT = 0x1, + BCSR_IFC_BIT = 0x2, + BCSR_SRQ_BIT = 0x4, + BCSR_EOI_BIT = 0x8, + BCSR_NRFD_BIT = 0x10, + BCSR_NDAC_BIT = 0x20, + BCSR_DAV_BIT = 0x40, + BCSR_ATN_BIT = 0x80, +}; + +/* CFG -- Configuration Register (write only) */ +enum cfg_bits { + TNT_COMMAND = 0x80, /* bytes are command bytes instead of data bytes + * (tnt4882 one-chip and newer only?) + */ + TNT_TLCHE = (1 << 6), /* halt transfer on imr0, imr1, or imr2 interrupt */ + TNT_IN = (1 << 5), /* transfer is GPIB read */ + TNT_A_B = (1 << 4), /* order to use fifos 1=fifo A first(big endian), + * 0=fifo b first(little endian) + */ + TNT_CCEN = (1 << 3), /* enable carry cycle */ + TNT_TMOE = (1 << 2), /* enable CPU bus time limit */ + TNT_TIM_BYTN = (1 << 1), /* tmot reg is: 1=125ns clocks, 0=num bytes */ + TNT_B_16BIT = (1 << 0), /* 1=FIFO is 16-bit register, 0=8-bit */ +}; + +/* CMDR -- Command Register */ +enum cmdr_bits { + CLRSC = 0x2, /* clear the system controller bit */ + SETSC = 0x3, /* set the system controller bit */ + GO = 0x4, /* start fifos */ + STOP = 0x8, /* stop fifos */ + RESET_FIFO = 0x10, /* reset the FIFOs */ + SOFT_RESET = 0x22, /* issue a software reset */ + HARD_RESET = 0x40 /* 500x only? */ +}; + +/* HSSEL -- handshake select register (write only) */ +enum hssel_bits { + TNT_ONE_CHIP_BIT = 0x1, + NODMA = 0x10, + TNT_GO2SIDS_BIT = 0x20, +}; + +/* IMR0 -- Interrupt Mode Register 0 */ +enum imr0_bits { + TNT_SYNCIE_BIT = 0x1, /* handshake sync */ + TNT_TOIE_BIT = 0x2, /* timeout */ + TNT_ATNIE_BIT = 0x4, /* ATN interrupt */ + TNT_IFCIE_BIT = 0x8, /* interface clear interrupt */ + TNT_BTO_BIT = 0x10, /* byte timeout */ + TNT_NLEN_BIT = 0x20, /* treat new line as EOS char */ + TNT_STBOIE_BIT = 0x40, /* status byte out */ + TNT_IMR0_ALWAYS_BITS = 0x80, /* always set this bit on write */ +}; + +/* ISR0 -- Interrupt Status Register 0 */ +enum isr0_bits { + TNT_SYNC_BIT = 0x1, /* handshake sync */ + TNT_TO_BIT = 0x2, /* timeout */ + TNT_ATNI_BIT = 0x4, /* ATN interrupt */ + TNT_IFCI_BIT = 0x8, /* interface clear interrupt */ + TNT_EOS_BIT = 0x10, /* end of string */ + TNT_NL_BIT = 0x20, /* new line receive */ + TNT_STBO_BIT = 0x40, /* status byte out */ + TNT_NBA_BIT = 0x80, /* new byte available */ +}; + +/* ISR3 -- Interrupt Status Register 3 (read only) */ +enum isr3_bits { + HR_DONE = (1 << 0), /* transfer done */ + HR_TLCI = (1 << 1), /* isr0, isr1, or isr2 interrupt asserted */ + HR_NEF = (1 << 2), /* NOT empty fifo */ + HR_NFF = (1 << 3), /* NOT full fifo */ + HR_STOP = (1 << 4), /* fifo empty or STOP command issued */ + HR_SRQI_CIC = (1 << 5), /* SRQ asserted and we are CIC (500x only?)*/ + HR_INTR = (1 << 7), /* isr3 interrupt active */ +}; + +enum keyreg_bits { + MSTD = 0x20, // enable 350ns T1 delay +}; + +/* STS1 -- Status Register 1 (read only) */ +enum sts1_bits { + S_DONE = 0x80, /* DMA done */ + S_SC = 0x40, /* is system controller */ + S_IN = 0x20, /* DMA in (to memory) */ + S_DRQ = 0x10, /* DRQ line (for diagnostics) */ + S_STOP = 0x08, /* DMA stopped */ + S_NDAV = 0x04, /* inverse of DAV */ + S_HALT = 0x02, /* status of transfer machine */ + S_GSYNC = 0x01, /* indicates if GPIB is in sync w I/O */ +}; + +/* STS2 -- Status Register 2 */ +enum sts2_bits { + AFFN = (1 << 3), /* "A full FIFO NOT" (0=FIFO full) */ + AEFN = (1 << 2), /* "A empty FIFO NOT" (0=FIFO empty) */ + BFFN = (1 << 1), /* "B full FIFO NOT" (0=FIFO full) */ + BEFN = (1 << 0), /* "B empty FIFO NOT" (0=FIFO empty) */ +}; + +// Auxiliary commands +enum tnt4882_aux_cmds { + AUX_9914 = 0x15, // switch to 9914 mode + AUX_REQT = 0x18, + AUX_REQF = 0x19, + AUX_PAGEIN = 0x50, /* page in alternate registers */ + AUX_HLDI = 0x51, // rfd holdoff immediately + AUX_CLEAR_END = 0x55, + AUX_7210 = 0x99, // switch to 7210 mode +}; + +enum tnt4882_aux_regs { + AUXRG = 0x40, + AUXRI = 0xe0, +}; + +enum auxg_bits { + /* no talking when no listeners bit (prevents bus errors when data written at wrong time) */ + NTNL_BIT = 0x8, + RPP2_BIT = 0x4, /* set/clear local rpp message */ + CHES_BIT = 0x1, /*clear holdoff on end select bit*/ +}; + +enum auxi_bits { + SISB = 0x1, // static interrupt bits (don't clear isr1, isr2 on read) + PP2 = 0x4, // ignore remote parallel poll configuration + USTD = 0x8, // ultra short (1100 nanosec) T1 delay +}; + +enum sasr_bits { + ACRDY_BIT = 0x4, /* acceptor ready state */ + ADHS_BIT = 0x8, /* acceptor data holdoff state */ + ANHS2_BIT = 0x10, /* acceptor not ready holdoff immediately state */ + ANHS1_BIT = 0x20, /* acceptor not ready holdoff state */ + AEHS_BIT = 0x40, /* acceptor end holdoff state */ +}; + +#endif // _TNT4882_REGISTERS_H