staging: gpib: Add common include files for GPIB drivers

Common include files used only by the drivers.

Signed-off-by: Dave Penkler <dpenkler@gmail.com>
Link: https://lore.kernel.org/r/20240918121908.19366-4-dpenkler@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Dave Penkler
2024-09-18 14:18:50 +02:00
committed by Greg Kroah-Hartman
parent f11192a246
commit 6c52d5e3cd
13 changed files with 1530 additions and 0 deletions

View File

@@ -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);
};

View File

@@ -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
};

View File

@@ -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 <linux/types.h>
#include "gpib_types.h"
#include "gpib_proto.h"
#include "gpib_user.h"
#include "gpib_ioctl.h"
#include <linux/fs.h>
#include <linux/interrupt.h>
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 <linux/io.h>
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

View File

@@ -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

View File

@@ -0,0 +1,56 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef GPIB_PROTO_INCLUDED
#define GPIB_PROTO_INCLUDED
#include <linux/fs.h>
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 */

View File

@@ -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

View File

@@ -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 <linux/atomic.h>
#include <linux/device.h>
#include <linux/mutex.h>
#include <linux/wait.h>
#include <linux/sched.h>
#include <linux/timer.h>
#include <linux/interrupt.h>
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 */

View File

@@ -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 <linux/types.h>
#include <linux/spinlock.h>
#include <linux/string.h>
#include <linux/interrupt.h>
#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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -0,0 +1,272 @@
/* SPDX-License-Identifier: GPL-2.0 */
/***************************************************************************
* copyright : (C) 2002 by Frank Mori Hess
***************************************************************************/
#ifndef _TMS9914_H
#define _TMS9914_H
#include <linux/types.h>
#include <linux/interrupt.h>
#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

View File

@@ -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