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