1 // SPDX-License-Identifier: GPL-2.0
2
3 /***************************************************************************
4 * copyright : (C) 2002 by Frank Mori Hess *
5 ***************************************************************************/
6
7 /*
8 * should enable ATN interrupts (and update board->status on occurrence),
9 * implement recovery from bus errors (if necessary)
10 */
11
12 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
13 #define dev_fmt pr_fmt
14 #define DRV_NAME KBUILD_MODNAME
15
16 #include "hp82335.h"
17 #include <linux/io.h>
18 #include <linux/ioport.h>
19 #include <linux/sched.h>
20 #include <linux/module.h>
21 #include <linux/slab.h>
22 #include <linux/string.h>
23 #include <linux/init.h>
24
25 MODULE_LICENSE("GPL");
26 MODULE_DESCRIPTION("GPIB driver for HP 82335 interface cards");
27
28 static int hp82335_attach(struct gpib_board *board, const struct gpib_board_config *config);
29 static void hp82335_detach(struct gpib_board *board);
30 static irqreturn_t hp82335_interrupt(int irq, void *arg);
31
32 // wrappers for interface functions
hp82335_read(struct gpib_board * board,u8 * buffer,size_t length,int * end,size_t * bytes_read)33 static int hp82335_read(struct gpib_board *board, u8 *buffer, size_t length,
34 int *end, size_t *bytes_read)
35 {
36 struct hp82335_priv *priv = board->private_data;
37
38 return tms9914_read(board, &priv->tms9914_priv, buffer, length, end, bytes_read);
39 }
40
hp82335_write(struct gpib_board * board,u8 * buffer,size_t length,int send_eoi,size_t * bytes_written)41 static int hp82335_write(struct gpib_board *board, u8 *buffer, size_t length, int send_eoi,
42 size_t *bytes_written)
43 {
44 struct hp82335_priv *priv = board->private_data;
45
46 return tms9914_write(board, &priv->tms9914_priv, buffer, length, send_eoi, bytes_written);
47 }
48
hp82335_command(struct gpib_board * board,u8 * buffer,size_t length,size_t * bytes_written)49 static int hp82335_command(struct gpib_board *board, u8 *buffer, size_t length,
50 size_t *bytes_written)
51 {
52 struct hp82335_priv *priv = board->private_data;
53
54 return tms9914_command(board, &priv->tms9914_priv, buffer, length, bytes_written);
55 }
56
hp82335_take_control(struct gpib_board * board,int synchronous)57 static int hp82335_take_control(struct gpib_board *board, int synchronous)
58 {
59 struct hp82335_priv *priv = board->private_data;
60
61 return tms9914_take_control(board, &priv->tms9914_priv, synchronous);
62 }
63
hp82335_go_to_standby(struct gpib_board * board)64 static int hp82335_go_to_standby(struct gpib_board *board)
65 {
66 struct hp82335_priv *priv = board->private_data;
67
68 return tms9914_go_to_standby(board, &priv->tms9914_priv);
69 }
70
hp82335_request_system_control(struct gpib_board * board,int request_control)71 static int hp82335_request_system_control(struct gpib_board *board, int request_control)
72 {
73 struct hp82335_priv *priv = board->private_data;
74
75 return tms9914_request_system_control(board, &priv->tms9914_priv, request_control);
76 }
77
hp82335_interface_clear(struct gpib_board * board,int assert)78 static void hp82335_interface_clear(struct gpib_board *board, int assert)
79 {
80 struct hp82335_priv *priv = board->private_data;
81
82 tms9914_interface_clear(board, &priv->tms9914_priv, assert);
83 }
84
hp82335_remote_enable(struct gpib_board * board,int enable)85 static void hp82335_remote_enable(struct gpib_board *board, int enable)
86 {
87 struct hp82335_priv *priv = board->private_data;
88
89 tms9914_remote_enable(board, &priv->tms9914_priv, enable);
90 }
91
hp82335_enable_eos(struct gpib_board * board,u8 eos_byte,int compare_8_bits)92 static int hp82335_enable_eos(struct gpib_board *board, u8 eos_byte, int compare_8_bits)
93 {
94 struct hp82335_priv *priv = board->private_data;
95
96 return tms9914_enable_eos(board, &priv->tms9914_priv, eos_byte, compare_8_bits);
97 }
98
hp82335_disable_eos(struct gpib_board * board)99 static void hp82335_disable_eos(struct gpib_board *board)
100 {
101 struct hp82335_priv *priv = board->private_data;
102
103 tms9914_disable_eos(board, &priv->tms9914_priv);
104 }
105
hp82335_update_status(struct gpib_board * board,unsigned int clear_mask)106 static unsigned int hp82335_update_status(struct gpib_board *board, unsigned int clear_mask)
107 {
108 struct hp82335_priv *priv = board->private_data;
109
110 return tms9914_update_status(board, &priv->tms9914_priv, clear_mask);
111 }
112
hp82335_primary_address(struct gpib_board * board,unsigned int address)113 static int hp82335_primary_address(struct gpib_board *board, unsigned int address)
114 {
115 struct hp82335_priv *priv = board->private_data;
116
117 return tms9914_primary_address(board, &priv->tms9914_priv, address);
118 }
119
hp82335_secondary_address(struct gpib_board * board,unsigned int address,int enable)120 static int hp82335_secondary_address(struct gpib_board *board, unsigned int address, int enable)
121 {
122 struct hp82335_priv *priv = board->private_data;
123
124 return tms9914_secondary_address(board, &priv->tms9914_priv, address, enable);
125 }
126
hp82335_parallel_poll(struct gpib_board * board,u8 * result)127 static int hp82335_parallel_poll(struct gpib_board *board, u8 *result)
128 {
129 struct hp82335_priv *priv = board->private_data;
130
131 return tms9914_parallel_poll(board, &priv->tms9914_priv, result);
132 }
133
hp82335_parallel_poll_configure(struct gpib_board * board,u8 config)134 static void hp82335_parallel_poll_configure(struct gpib_board *board, u8 config)
135 {
136 struct hp82335_priv *priv = board->private_data;
137
138 tms9914_parallel_poll_configure(board, &priv->tms9914_priv, config);
139 }
140
hp82335_parallel_poll_response(struct gpib_board * board,int ist)141 static void hp82335_parallel_poll_response(struct gpib_board *board, int ist)
142 {
143 struct hp82335_priv *priv = board->private_data;
144
145 tms9914_parallel_poll_response(board, &priv->tms9914_priv, ist);
146 }
147
hp82335_serial_poll_response(struct gpib_board * board,u8 status)148 static void hp82335_serial_poll_response(struct gpib_board *board, u8 status)
149 {
150 struct hp82335_priv *priv = board->private_data;
151
152 tms9914_serial_poll_response(board, &priv->tms9914_priv, status);
153 }
154
hp82335_serial_poll_status(struct gpib_board * board)155 static u8 hp82335_serial_poll_status(struct gpib_board *board)
156 {
157 struct hp82335_priv *priv = board->private_data;
158
159 return tms9914_serial_poll_status(board, &priv->tms9914_priv);
160 }
161
hp82335_line_status(const struct gpib_board * board)162 static int hp82335_line_status(const struct gpib_board *board)
163 {
164 struct hp82335_priv *priv = board->private_data;
165
166 return tms9914_line_status(board, &priv->tms9914_priv);
167 }
168
hp82335_t1_delay(struct gpib_board * board,unsigned int nano_sec)169 static int hp82335_t1_delay(struct gpib_board *board, unsigned int nano_sec)
170 {
171 struct hp82335_priv *priv = board->private_data;
172
173 return tms9914_t1_delay(board, &priv->tms9914_priv, nano_sec);
174 }
175
hp82335_return_to_local(struct gpib_board * board)176 static void hp82335_return_to_local(struct gpib_board *board)
177 {
178 struct hp82335_priv *priv = board->private_data;
179
180 tms9914_return_to_local(board, &priv->tms9914_priv);
181 }
182
183 static struct gpib_interface hp82335_interface = {
184 .name = "hp82335",
185 .attach = hp82335_attach,
186 .detach = hp82335_detach,
187 .read = hp82335_read,
188 .write = hp82335_write,
189 .command = hp82335_command,
190 .request_system_control = hp82335_request_system_control,
191 .take_control = hp82335_take_control,
192 .go_to_standby = hp82335_go_to_standby,
193 .interface_clear = hp82335_interface_clear,
194 .remote_enable = hp82335_remote_enable,
195 .enable_eos = hp82335_enable_eos,
196 .disable_eos = hp82335_disable_eos,
197 .parallel_poll = hp82335_parallel_poll,
198 .parallel_poll_configure = hp82335_parallel_poll_configure,
199 .parallel_poll_response = hp82335_parallel_poll_response,
200 .local_parallel_poll_mode = NULL, // XXX
201 .line_status = hp82335_line_status,
202 .update_status = hp82335_update_status,
203 .primary_address = hp82335_primary_address,
204 .secondary_address = hp82335_secondary_address,
205 .serial_poll_response = hp82335_serial_poll_response,
206 .serial_poll_status = hp82335_serial_poll_status,
207 .t1_delay = hp82335_t1_delay,
208 .return_to_local = hp82335_return_to_local,
209 };
210
hp82335_allocate_private(struct gpib_board * board)211 static int hp82335_allocate_private(struct gpib_board *board)
212 {
213 board->private_data = kzalloc(sizeof(struct hp82335_priv), GFP_KERNEL);
214 if (!board->private_data)
215 return -1;
216 return 0;
217 }
218
hp82335_free_private(struct gpib_board * board)219 static void hp82335_free_private(struct gpib_board *board)
220 {
221 kfree(board->private_data);
222 board->private_data = NULL;
223 }
224
tms9914_to_hp82335_offset(unsigned int register_num)225 static inline unsigned int tms9914_to_hp82335_offset(unsigned int register_num)
226 {
227 return 0x1ff8 + register_num;
228 }
229
hp82335_read_byte(struct tms9914_priv * priv,unsigned int register_num)230 static u8 hp82335_read_byte(struct tms9914_priv *priv, unsigned int register_num)
231 {
232 return tms9914_iomem_read_byte(priv, tms9914_to_hp82335_offset(register_num));
233 }
234
hp82335_write_byte(struct tms9914_priv * priv,u8 data,unsigned int register_num)235 static void hp82335_write_byte(struct tms9914_priv *priv, u8 data, unsigned int register_num)
236 {
237 tms9914_iomem_write_byte(priv, data, tms9914_to_hp82335_offset(register_num));
238 }
239
hp82335_clear_interrupt(struct hp82335_priv * hp_priv)240 static void hp82335_clear_interrupt(struct hp82335_priv *hp_priv)
241 {
242 struct tms9914_priv *tms_priv = &hp_priv->tms9914_priv;
243
244 writeb(0, tms_priv->mmiobase + HPREG_INTR_CLEAR);
245 }
246
hp82335_attach(struct gpib_board * board,const struct gpib_board_config * config)247 static int hp82335_attach(struct gpib_board *board, const struct gpib_board_config *config)
248 {
249 struct hp82335_priv *hp_priv;
250 struct tms9914_priv *tms_priv;
251 int retval;
252 const unsigned long upper_iomem_base = config->ibbase + hp82335_rom_size;
253
254 board->status = 0;
255
256 if (hp82335_allocate_private(board))
257 return -ENOMEM;
258 hp_priv = board->private_data;
259 tms_priv = &hp_priv->tms9914_priv;
260 tms_priv->read_byte = hp82335_read_byte;
261 tms_priv->write_byte = hp82335_write_byte;
262 tms_priv->offset = 1;
263
264 switch (config->ibbase) {
265 case 0xc4000:
266 case 0xc8000:
267 case 0xcc000:
268 case 0xd0000:
269 case 0xd4000:
270 case 0xd8000:
271 case 0xdc000:
272 case 0xe0000:
273 case 0xe4000:
274 case 0xe8000:
275 case 0xec000:
276 case 0xf0000:
277 case 0xf4000:
278 case 0xf8000:
279 case 0xfc000:
280 break;
281 default:
282 dev_err(board->gpib_dev, "invalid base io address 0x%x\n", config->ibbase);
283 return -EINVAL;
284 }
285 if (!request_mem_region(upper_iomem_base, hp82335_upper_iomem_size, "hp82335")) {
286 dev_err(board->gpib_dev, "failed to allocate io memory region 0x%lx-0x%lx\n",
287 upper_iomem_base, upper_iomem_base + hp82335_upper_iomem_size - 1);
288 return -EBUSY;
289 }
290 hp_priv->raw_iobase = upper_iomem_base;
291 tms_priv->mmiobase = ioremap(upper_iomem_base, hp82335_upper_iomem_size);
292
293 retval = request_irq(config->ibirq, hp82335_interrupt, 0, DRV_NAME, board);
294 if (retval) {
295 dev_err(board->gpib_dev, "can't request IRQ %d\n", config->ibirq);
296 return retval;
297 }
298 hp_priv->irq = config->ibirq;
299
300 tms9914_board_reset(tms_priv);
301
302 hp82335_clear_interrupt(hp_priv);
303
304 writeb(INTR_ENABLE, tms_priv->mmiobase + HPREG_CCR);
305
306 tms9914_online(board, tms_priv);
307
308 return 0;
309 }
310
hp82335_detach(struct gpib_board * board)311 static void hp82335_detach(struct gpib_board *board)
312 {
313 struct hp82335_priv *hp_priv = board->private_data;
314 struct tms9914_priv *tms_priv;
315
316 if (hp_priv) {
317 tms_priv = &hp_priv->tms9914_priv;
318 if (hp_priv->irq)
319 free_irq(hp_priv->irq, board);
320 if (tms_priv->mmiobase) {
321 writeb(0, tms_priv->mmiobase + HPREG_CCR);
322 tms9914_board_reset(tms_priv);
323 iounmap(tms_priv->mmiobase);
324 }
325 if (hp_priv->raw_iobase)
326 release_mem_region(hp_priv->raw_iobase, hp82335_upper_iomem_size);
327 }
328 hp82335_free_private(board);
329 }
330
hp82335_init_module(void)331 static int __init hp82335_init_module(void)
332 {
333 int result = gpib_register_driver(&hp82335_interface, THIS_MODULE);
334
335 if (result) {
336 pr_err("gpib_register_driver failed: error = %d\n", result);
337 return result;
338 }
339
340 return 0;
341 }
342
hp82335_exit_module(void)343 static void __exit hp82335_exit_module(void)
344 {
345 gpib_unregister_driver(&hp82335_interface);
346 }
347
348 module_init(hp82335_init_module);
349 module_exit(hp82335_exit_module);
350
351 /*
352 * GPIB interrupt service routines
353 */
354
hp82335_interrupt(int irq,void * arg)355 static irqreturn_t hp82335_interrupt(int irq, void *arg)
356 {
357 int status1, status2;
358 struct gpib_board *board = arg;
359 struct hp82335_priv *priv = board->private_data;
360 unsigned long flags;
361 irqreturn_t retval;
362
363 spin_lock_irqsave(&board->spinlock, flags);
364 status1 = read_byte(&priv->tms9914_priv, ISR0);
365 status2 = read_byte(&priv->tms9914_priv, ISR1);
366 hp82335_clear_interrupt(priv);
367 retval = tms9914_interrupt_have_status(board, &priv->tms9914_priv, status1, status2);
368 spin_unlock_irqrestore(&board->spinlock, flags);
369 return retval;
370 }
371
372