1 /* SPDX-License-Identifier: GPL-2.0 */
2
3 /***************************************************************************
4 * Author: Frank Mori Hess <fmh6jj@gmail.com>
5 * copyright: (C) 2006, 2010, 2015 Fluke Corporation
6 ***************************************************************************/
7
8 #include <linux/compiler.h>
9 #include <linux/dmaengine.h>
10 #include <linux/io.h>
11 #include <linux/delay.h>
12 #include <linux/interrupt.h>
13 #include "nec7210.h"
14
15 struct fluke_priv {
16 struct nec7210_priv nec7210_priv;
17 struct resource *gpib_iomem_res;
18 struct resource *write_transfer_counter_res;
19 struct resource *dma_port_res;
20 int irq;
21 struct dma_chan *dma_channel;
22 u8 *dma_buffer;
23 int dma_buffer_size;
24 void __iomem *write_transfer_counter;
25 };
26
27 // cb7210 specific registers and bits
28 enum cb7210_regs {
29 STATE1_REG = 0x4,
30 ISR0_IMR0 = 0x6,
31 BUS_STATUS = 0x7
32 };
33
34 enum cb7210_page_in {
35 ISR0_IMR0_PAGE = 1,
36 BUS_STATUS_PAGE = 1,
37 STATE1_PAGE = 1
38 };
39
40 /* IMR0 -- Interrupt Mode Register 0 */
41 enum imr0_bits {
42 FLUKE_IFCIE_BIT = 0x8, /* interface clear interrupt */
43 };
44
45 /* ISR0 -- Interrupt Status Register 0 */
46 enum isr0_bits {
47 FLUKE_IFCI_BIT = 0x8, /* interface clear interrupt */
48 };
49
50 enum state1_bits {
51 SOURCE_HANDSHAKE_SIDS_BITS = 0x0, /* source idle state */
52 SOURCE_HANDSHAKE_SGNS_BITS = 0x1, /* source generate state */
53 SOURCE_HANDSHAKE_SDYS_BITS = 0x2, /* source delay state */
54 SOURCE_HANDSHAKE_STRS_BITS = 0x5, /* source transfer state */
55 SOURCE_HANDSHAKE_MASK = 0x7
56 };
57
58 // we customized the cb7210 vhdl to give the "data in" status
59 // on the unused bit 7 of the address0 register.
60 enum cb7210_address0 {
61 DATA_IN_STATUS = 0x80
62 };
63
cb7210_page_in_bits(unsigned int page)64 static inline int cb7210_page_in_bits(unsigned int page)
65 {
66 return 0x50 | (page & 0xf);
67 }
68
69 // don't use without locking nec_priv->register_page_lock
fluke_read_byte_nolock(struct nec7210_priv * nec_priv,int register_num)70 static inline uint8_t fluke_read_byte_nolock(struct nec7210_priv *nec_priv,
71 int register_num)
72 {
73 u8 retval;
74
75 retval = readl(nec_priv->mmiobase + register_num * nec_priv->offset);
76 return retval;
77 }
78
79 // don't use without locking nec_priv->register_page_lock
fluke_write_byte_nolock(struct nec7210_priv * nec_priv,uint8_t data,int register_num)80 static inline void fluke_write_byte_nolock(struct nec7210_priv *nec_priv, uint8_t data,
81 int register_num)
82 {
83 writel(data, nec_priv->mmiobase + register_num * nec_priv->offset);
84 }
85
fluke_paged_read_byte(struct fluke_priv * e_priv,unsigned int register_num,unsigned int page)86 static inline uint8_t fluke_paged_read_byte(struct fluke_priv *e_priv,
87 unsigned int register_num, unsigned int page)
88 {
89 struct nec7210_priv *nec_priv = &e_priv->nec7210_priv;
90 u8 retval;
91 unsigned long flags;
92
93 spin_lock_irqsave(&nec_priv->register_page_lock, flags);
94 fluke_write_byte_nolock(nec_priv, cb7210_page_in_bits(page), AUXMR);
95 udelay(1);
96 /* chip auto clears the page after a read */
97 retval = fluke_read_byte_nolock(nec_priv, register_num);
98 spin_unlock_irqrestore(&nec_priv->register_page_lock, flags);
99 return retval;
100 }
101
fluke_paged_write_byte(struct fluke_priv * e_priv,uint8_t data,unsigned int register_num,unsigned int page)102 static inline void fluke_paged_write_byte(struct fluke_priv *e_priv, uint8_t data,
103 unsigned int register_num, unsigned int page)
104 {
105 struct nec7210_priv *nec_priv = &e_priv->nec7210_priv;
106 unsigned long flags;
107
108 spin_lock_irqsave(&nec_priv->register_page_lock, flags);
109 fluke_write_byte_nolock(nec_priv, cb7210_page_in_bits(page), AUXMR);
110 udelay(1);
111 fluke_write_byte_nolock(nec_priv, data, register_num);
112 spin_unlock_irqrestore(&nec_priv->register_page_lock, flags);
113 }
114
115 enum bus_status_bits {
116 BSR_ATN_BIT = 0x1,
117 BSR_EOI_BIT = 0x2,
118 BSR_SRQ_BIT = 0x4,
119 BSR_IFC_BIT = 0x8,
120 BSR_REN_BIT = 0x10,
121 BSR_DAV_BIT = 0x20,
122 BSR_NRFD_BIT = 0x40,
123 BSR_NDAC_BIT = 0x80,
124 };
125
126 enum cb7210_aux_cmds {
127 /* AUX_RTL2 is an undocumented aux command which causes cb7210 to assert
128 * (and keep asserted) local rtl message. This is used in conjunction
129 * with the (stupid) cb7210 implementation
130 * of the normal nec7210 AUX_RTL aux command, which
131 * causes the rtl message to toggle between on and off.
132 */
133 AUX_RTL2 = 0xd,
134 AUX_NBAF = 0xe, // new byte available false (also clears seoi)
135 AUX_LO_SPEED = 0x40,
136 AUX_HI_SPEED = 0x41,
137 };
138
139 enum {
140 fluke_reg_offset = 4,
141 fluke_num_regs = 8,
142 write_transfer_counter_mask = 0x7ff,
143 };
144