1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280
|
/* 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
|