mirror of
https://github.com/torvalds/linux.git
synced 2025-12-07 20:06:24 +00:00
Move the gpib drivers out of staging and into the "real" part of the kernel. This entails: - Remove the gpib Kconfig menu and Makefile build rule from staging. - Remove gpib/uapi from the header file search path in subdir-ccflags of the gpib Makefile - move the gpib/uapi files to include/uapi/linux - Move the gpib tree out of staging to drivers. - Remove the word "Linux" from the gpib Kconfig file. - Add the gpib Kconfig menu and Makefile build rule to drivers Signed-off-by: Dave Penkler <dpenkler@gmail.com> Link: https://patch.msgid.link/20251117144021.23569-5-dpenkler@gmail.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
281 lines
11 KiB
C
281 lines
11 KiB
C
/* 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 {
|
|
#ifdef CONFIG_HAS_IOPORT
|
|
u32 iobase;
|
|
#endif
|
|
void __iomem *mmiobase;
|
|
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(struct gpib_board *board, struct tms9914_priv *priv, u8 *buffer,
|
|
size_t length, int *end, size_t *bytes_read);
|
|
int tms9914_write(struct gpib_board *board, struct tms9914_priv *priv, u8 *buffer,
|
|
size_t length, int send_eoi, size_t *bytes_written);
|
|
int tms9914_command(struct gpib_board *board, struct tms9914_priv *priv, u8 *buffer,
|
|
size_t length, size_t *bytes_written);
|
|
int tms9914_take_control(struct gpib_board *board, struct tms9914_priv *priv, int syncronous);
|
|
/*
|
|
* alternate version of tms9914_take_control which works around buggy tcs
|
|
* implementation.
|
|
*/
|
|
int tms9914_take_control_workaround(struct gpib_board *board, struct tms9914_priv *priv,
|
|
int syncronous);
|
|
int tms9914_go_to_standby(struct gpib_board *board, struct tms9914_priv *priv);
|
|
int tms9914_request_system_control(struct gpib_board *board, struct tms9914_priv *priv,
|
|
int request_control);
|
|
void tms9914_interface_clear(struct gpib_board *board, struct tms9914_priv *priv, int assert);
|
|
void tms9914_remote_enable(struct gpib_board *board, struct tms9914_priv *priv, int enable);
|
|
int tms9914_enable_eos(struct gpib_board *board, struct tms9914_priv *priv, u8 eos_bytes,
|
|
int compare_8_bits);
|
|
void tms9914_disable_eos(struct gpib_board *board, struct tms9914_priv *priv);
|
|
unsigned int tms9914_update_status(struct gpib_board *board, struct tms9914_priv *priv,
|
|
unsigned int clear_mask);
|
|
int tms9914_primary_address(struct gpib_board *board,
|
|
struct tms9914_priv *priv, unsigned int address);
|
|
int tms9914_secondary_address(struct gpib_board *board, struct tms9914_priv *priv,
|
|
unsigned int address, int enable);
|
|
int tms9914_parallel_poll(struct gpib_board *board, struct tms9914_priv *priv, u8 *result);
|
|
void tms9914_parallel_poll_configure(struct gpib_board *board,
|
|
struct tms9914_priv *priv, u8 config);
|
|
void tms9914_parallel_poll_response(struct gpib_board *board,
|
|
struct tms9914_priv *priv, int ist);
|
|
void tms9914_serial_poll_response(struct gpib_board *board,
|
|
struct tms9914_priv *priv, u8 status);
|
|
u8 tms9914_serial_poll_status(struct gpib_board *board, struct tms9914_priv *priv);
|
|
int tms9914_line_status(const struct gpib_board *board, struct tms9914_priv *priv);
|
|
unsigned int tms9914_t1_delay(struct gpib_board *board, struct tms9914_priv *priv,
|
|
unsigned int nano_sec);
|
|
void tms9914_return_to_local(const struct gpib_board *board, struct tms9914_priv *priv);
|
|
|
|
// utility functions
|
|
void tms9914_board_reset(struct tms9914_priv *priv);
|
|
void tms9914_online(struct gpib_board *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
|
|
u8 tms9914_ioport_read_byte(struct tms9914_priv *priv, unsigned int register_num);
|
|
void tms9914_ioport_write_byte(struct tms9914_priv *priv, u8 data, unsigned int register_num);
|
|
u8 tms9914_iomem_read_byte(struct tms9914_priv *priv, unsigned int register_num);
|
|
void tms9914_iomem_write_byte(struct tms9914_priv *priv, u8 data, unsigned int register_num);
|
|
|
|
// interrupt service routine
|
|
irqreturn_t tms9914_interrupt(struct gpib_board *board, struct tms9914_priv *priv);
|
|
irqreturn_t tms9914_interrupt_have_status(struct gpib_board *board, struct tms9914_priv *priv,
|
|
int status1, int status2);
|
|
|
|
// tms9914 has 8 registers
|
|
enum {
|
|
ms9914_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
|