summaryrefslogtreecommitdiff
path: root/drivers/gpib/cb7210/cb7210.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpib/cb7210/cb7210.h')
-rw-r--r--drivers/gpib/cb7210/cb7210.h203
1 files changed, 203 insertions, 0 deletions
diff --git a/drivers/gpib/cb7210/cb7210.h b/drivers/gpib/cb7210/cb7210.h
new file mode 100644
index 000000000000..ddc841ff87ae
--- /dev/null
+++ b/drivers/gpib/cb7210/cb7210.h
@@ -0,0 +1,203 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+/***************************************************************************
+ * copyright : (C) 2002 by Frank Mori Hess
+ ***************************************************************************/
+
+#include "nec7210.h"
+#include "gpibP.h"
+#include "amccs5933.h"
+
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+
+enum {
+ PCI_DEVICE_ID_CBOARDS_PCI_GPIB = 0x6,
+ PCI_DEVICE_ID_CBOARDS_CPCI_GPIB = 0xe,
+};
+
+enum pci_chip {
+ PCI_CHIP_NONE = 0,
+ PCI_CHIP_AMCC_S5933,
+ PCI_CHIP_QUANCOM
+};
+
+// struct which defines private_data for cb7210 boards
+struct cb7210_priv {
+ struct nec7210_priv nec7210_priv;
+ struct pci_dev *pci_device;
+ // base address of amccs5933 pci chip
+ unsigned long amcc_iobase;
+ unsigned long fifo_iobase;
+ unsigned int irq;
+ enum pci_chip pci_chip;
+ u8 hs_mode_bits;
+ unsigned out_fifo_half_empty : 1;
+ unsigned in_fifo_half_full : 1;
+};
+
+// pci-gpib register offset
+static const int cb7210_reg_offset = 1;
+
+// uses 10 ioports
+static const int cb7210_iosize = 10;
+
+// fifo size in bytes
+static const int cb7210_fifo_size = 2048;
+static const int cb7210_fifo_width = 2;
+
+// cb7210 specific registers and bits
+enum cb7210_regs {
+ BUS_STATUS = 0x7,
+};
+
+enum cb7210_page_in {
+ BUS_STATUS_PAGE = 1,
+};
+
+enum hs_regs {
+ // write registers
+ HS_MODE = 0x8, /* HS_MODE register */
+ HS_INT_LEVEL = 0x9, /* HS_INT_LEVEL register */
+ // read registers
+ HS_STATUS = 0x8, /* HS_STATUS register */
+};
+
+static inline u32 nec7210_iobase(const struct cb7210_priv *cb_priv)
+{
+ return cb_priv->nec7210_priv.iobase;
+}
+
+static inline int cb7210_page_in_bits(unsigned int page)
+{
+ return 0x50 | (page & 0xf);
+}
+
+static inline u8 cb7210_paged_read_byte(struct cb7210_priv *cb_priv,
+ unsigned int register_num, unsigned int page)
+{
+ struct nec7210_priv *nec_priv = &cb_priv->nec7210_priv;
+ u8 retval;
+ unsigned long flags;
+
+ spin_lock_irqsave(&nec_priv->register_page_lock, flags);
+ outb(cb7210_page_in_bits(page), nec7210_iobase(cb_priv) + AUXMR * nec_priv->offset);
+ udelay(1);
+ retval = inb(nec7210_iobase(cb_priv) + register_num * nec_priv->offset);
+ spin_unlock_irqrestore(&nec_priv->register_page_lock, flags);
+ return retval;
+}
+
+// don't use for register_num < 8, since it doesn't lock
+static inline u8 cb7210_read_byte(const struct cb7210_priv *cb_priv,
+ enum hs_regs register_num)
+{
+ const struct nec7210_priv *nec_priv = &cb_priv->nec7210_priv;
+ u8 retval;
+
+ retval = inb(nec7210_iobase(cb_priv) + register_num * nec_priv->offset);
+ return retval;
+}
+
+static inline void cb7210_paged_write_byte(struct cb7210_priv *cb_priv, u8 data,
+ unsigned int register_num, unsigned int page)
+{
+ struct nec7210_priv *nec_priv = &cb_priv->nec7210_priv;
+ unsigned long flags;
+
+ spin_lock_irqsave(&nec_priv->register_page_lock, flags);
+ outb(cb7210_page_in_bits(page), nec7210_iobase(cb_priv) + AUXMR * nec_priv->offset);
+ udelay(1);
+ outb(data, nec7210_iobase(cb_priv) + register_num * nec_priv->offset);
+ spin_unlock_irqrestore(&nec_priv->register_page_lock, flags);
+}
+
+// don't use for register_num < 8, since it doesn't lock
+static inline void cb7210_write_byte(const struct cb7210_priv *cb_priv, u8 data,
+ enum hs_regs register_num)
+{
+ const struct nec7210_priv *nec_priv = &cb_priv->nec7210_priv;
+
+ outb(data, nec7210_iobase(cb_priv) + register_num * nec_priv->offset);
+}
+
+enum bus_status_bits {
+ BSR_ATN_BIT = 0x1,
+ BSR_EOI_BIT = 0x2,
+ BSR_SRQ_BIT = 0x4,
+ BSR_IFC_BIT = 0x8,
+ BSR_REN_BIT = 0x10,
+ BSR_DAV_BIT = 0x20,
+ BSR_NRFD_BIT = 0x40,
+ BSR_NDAC_BIT = 0x80,
+};
+
+/* CBI 488.2 HS control */
+
+/*
+ * when both bit 0 and 1 are set, it
+ * 1 clears the transmit state machine to an initial condition
+ * 2 clears any residual interrupts left latched on cbi488.2
+ * 3 resets all control bits in HS_MODE to zero
+ * 4 enables TX empty interrupts
+ * when both bit 0 and 1 are zero, then the high speed mode is disabled
+ */
+enum hs_mode_bits {
+ HS_ENABLE_MASK = 0x3,
+ HS_TX_ENABLE = (1 << 0),
+ HS_RX_ENABLE = (1 << 1),
+ HS_HF_INT_EN = (1 << 3),
+ HS_CLR_SRQ_INT = (1 << 4),
+ HS_CLR_EOI_EMPTY_INT = (1 << 5),
+ HS_CLR_HF_INT = (1 << 6),
+ HS_SYS_CONTROL = (1 << 7),
+};
+
+/* CBI 488.2 status */
+enum hs_status_bits {
+ HS_FIFO_FULL = (1 << 0),
+ HS_HALF_FULL = (1 << 1),
+ HS_SRQ_INT = (1 << 2),
+ HS_EOI_INT = (1 << 3),
+ HS_TX_MSB_NOT_EMPTY = (1 << 4),
+ HS_RX_MSB_NOT_EMPTY = (1 << 5),
+ HS_TX_LSB_NOT_EMPTY = (1 << 6),
+ HS_RX_LSB_NOT_EMPTY = (1 << 7),
+};
+
+/* CBI488.2 hs_int_level register */
+enum hs_int_level_bits {
+ HS_RESET7210 = (1 << 7),
+};
+
+static inline unsigned int irq_bits(unsigned int irq)
+{
+ switch (irq) {
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ return irq - 1;
+ case 7:
+ return 0x5;
+ case 10:
+ return 0x6;
+ case 11:
+ return 0x7;
+ default:
+ return 0;
+ }
+}
+
+enum cb7210_aux_cmds {
+/*
+ * AUX_RTL2 is an undocumented aux command which causes cb7210 to assert
+ * (and keep asserted) local rtl message. This is used in conjunction
+ * with the (stupid) cb7210 implementation
+ * of the normal nec7210 AUX_RTL aux command, which
+ * causes the rtl message to toggle between on and off.
+ */
+ AUX_RTL2 = 0xd,
+ AUX_LO_SPEED = 0x40,
+ AUX_HI_SPEED = 0x41,
+};