File Index
Files and directories
Sign in
FILE

tms9914.c

File preview with syntax highlighting.

linux-6.19.14/drivers/gpib/tms9914/tms9914.c C
  1// SPDX-License-Identifier: GPL-2.0
  2
  3/***************************************************************************
  4 *   copyright		  : (C) 2001, 2002 by Frank Mori Hess
  5 ***************************************************************************/
  6
  7#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  8#define dev_fmt pr_fmt
  9
 10#include <linux/ioport.h>
 11#include <linux/sched.h>
 12#include <linux/module.h>
 13#include <linux/slab.h>
 14#include <asm/dma.h>
 15#include <linux/io.h>
 16#include <linux/bitops.h>
 17#include <linux/pci.h>
 18#include <linux/pci_ids.h>
 19#include <linux/string.h>
 20#include <linux/init.h>
 21#include <linux/spinlock.h>
 22#include <linux/delay.h>
 23
 24#include "gpibP.h"
 25#include "tms9914.h"
 26
 27MODULE_LICENSE("GPL");
 28MODULE_DESCRIPTION("GPIB library for tms9914");
 29
 30static unsigned int update_status_nolock(struct gpib_board *board, struct tms9914_priv *priv);
 31
 32int tms9914_take_control(struct gpib_board *board, struct tms9914_priv *priv, int synchronous)
 33{
 34	int i;
 35	const int timeout = 100;
 36
 37	if (synchronous)
 38		write_byte(priv, AUX_TCS, AUXCR);
 39	else
 40		write_byte(priv, AUX_TCA, AUXCR);
 41	// busy wait until ATN is asserted
 42	for (i = 0; i < timeout; i++) {
 43		if ((read_byte(priv, ADSR) & HR_ATN))
 44			break;
 45		udelay(1);
 46	}
 47	if (i == timeout)
 48		return -ETIMEDOUT;
 49
 50	clear_bit(WRITE_READY_BN, &priv->state);
 51
 52	return 0;
 53}
 54EXPORT_SYMBOL_GPL(tms9914_take_control);
 55
 56/*
 57 * The agilent 82350B has a buggy implementation of tcs which interferes with the
 58 * operation of tca.  It appears to be based on the controller state machine
 59 * described in the TI 9900 TMS9914A data manual published in 1982.  This
 60 * manual describes tcs as putting the controller into a CWAS
 61 * state where it waits indefinitely for ANRS and ignores tca.	Since a
 62 * functioning tca is far more important than tcs, we work around the
 63 * problem by never issuing tcs.
 64 *
 65 * I don't know if this problem exists in the real tms9914a or just in the fpga
 66 * of the 82350B.  For now, only the agilent_82350b uses this workaround.
 67 * The rest of the tms9914 based drivers still use tms9914_take_control
 68 * directly (which does issue tcs).
 69 */
 70int tms9914_take_control_workaround(struct gpib_board *board,
 71				    struct tms9914_priv *priv, int synchronous)
 72{
 73	if (synchronous)
 74		return -ETIMEDOUT;
 75	return tms9914_take_control(board, priv, synchronous);
 76}
 77EXPORT_SYMBOL_GPL(tms9914_take_control_workaround);
 78
 79int tms9914_go_to_standby(struct gpib_board *board, struct tms9914_priv *priv)
 80{
 81	int i;
 82	const int timeout = 1000;
 83
 84	write_byte(priv, AUX_GTS, AUXCR);
 85	// busy wait until ATN is released
 86	for (i = 0; i < timeout; i++) {
 87		if ((read_byte(priv, ADSR) & HR_ATN) == 0)
 88			break;
 89		udelay(1);
 90	}
 91	if (i == timeout)
 92		return -ETIMEDOUT;
 93
 94	clear_bit(COMMAND_READY_BN, &priv->state);
 95
 96	return 0;
 97}
 98EXPORT_SYMBOL_GPL(tms9914_go_to_standby);
 99
100void tms9914_interface_clear(struct gpib_board *board, struct tms9914_priv *priv, int assert)
101{
102	if (assert) {
103		write_byte(priv, AUX_SIC | AUX_CS, AUXCR);
104
105		set_bit(CIC_NUM, &board->status);
106	} else {
107		write_byte(priv, AUX_SIC, AUXCR);
108	}
109}
110EXPORT_SYMBOL_GPL(tms9914_interface_clear);
111
112void tms9914_remote_enable(struct gpib_board *board, struct tms9914_priv *priv, int enable)
113{
114	if (enable)
115		write_byte(priv, AUX_SRE | AUX_CS, AUXCR);
116	else
117		write_byte(priv, AUX_SRE, AUXCR);
118}
119EXPORT_SYMBOL_GPL(tms9914_remote_enable);
120
121int tms9914_request_system_control(struct gpib_board *board, struct tms9914_priv *priv,
122				   int request_control)
123{
124	if (request_control) {
125		write_byte(priv, AUX_RQC, AUXCR);
126	} else {
127		clear_bit(CIC_NUM, &board->status);
128		write_byte(priv, AUX_RLC, AUXCR);
129	}
130	return 0;
131}
132EXPORT_SYMBOL_GPL(tms9914_request_system_control);
133
134unsigned int tms9914_t1_delay(struct gpib_board *board, struct tms9914_priv *priv,
135			      unsigned int nano_sec)
136{
137	static const int clock_period = 200;	// assuming 5Mhz input clock
138	int num_cycles;
139
140	num_cycles = 12;
141
142	if (nano_sec <= 8 * clock_period) {
143		write_byte(priv, AUX_STDL | AUX_CS, AUXCR);
144		num_cycles = 8;
145	} else {
146		write_byte(priv, AUX_STDL, AUXCR);
147	}
148
149	if (nano_sec <= 4 * clock_period) {
150		write_byte(priv, AUX_VSTDL | AUX_CS, AUXCR);
151		num_cycles = 4;
152	} else {
153		write_byte(priv, AUX_VSTDL, AUXCR);
154	}
155
156	return num_cycles * clock_period;
157}
158EXPORT_SYMBOL_GPL(tms9914_t1_delay);
159
160void tms9914_return_to_local(const struct gpib_board *board, struct tms9914_priv *priv)
161{
162	write_byte(priv, AUX_RTL, AUXCR);
163}
164EXPORT_SYMBOL_GPL(tms9914_return_to_local);
165
166void tms9914_set_holdoff_mode(struct tms9914_priv *priv, enum tms9914_holdoff_mode mode)
167{
168	switch (mode) {
169	case TMS9914_HOLDOFF_NONE:
170		write_byte(priv, AUX_HLDE, AUXCR);
171		write_byte(priv, AUX_HLDA, AUXCR);
172		break;
173	case TMS9914_HOLDOFF_EOI:
174		write_byte(priv, AUX_HLDE | AUX_CS, AUXCR);
175		write_byte(priv, AUX_HLDA, AUXCR);
176		break;
177	case TMS9914_HOLDOFF_ALL:
178		write_byte(priv, AUX_HLDE, AUXCR);
179		write_byte(priv, AUX_HLDA | AUX_CS, AUXCR);
180		break;
181	default:
182		pr_err("bug! bad holdoff mode %i\n", mode);
183		break;
184	}
185	priv->holdoff_mode = mode;
186}
187EXPORT_SYMBOL_GPL(tms9914_set_holdoff_mode);
188
189void tms9914_release_holdoff(struct tms9914_priv *priv)
190{
191	if (priv->holdoff_active) {
192		write_byte(priv, AUX_RHDF, AUXCR);
193		priv->holdoff_active = 0;
194	}
195}
196EXPORT_SYMBOL_GPL(tms9914_release_holdoff);
197
198int tms9914_enable_eos(struct gpib_board *board, struct tms9914_priv *priv, u8 eos_byte,
199		       int compare_8_bits)
200{
201	priv->eos = eos_byte;
202	priv->eos_flags = REOS;
203	if (compare_8_bits)
204		priv->eos_flags |= BIN;
205	return 0;
206}
207EXPORT_SYMBOL(tms9914_enable_eos);
208
209void tms9914_disable_eos(struct gpib_board *board, struct tms9914_priv *priv)
210{
211	priv->eos_flags &= ~REOS;
212}
213EXPORT_SYMBOL(tms9914_disable_eos);
214
215int tms9914_parallel_poll(struct gpib_board *board, struct tms9914_priv *priv, u8 *result)
216{
217	// execute parallel poll
218	write_byte(priv, AUX_CS | AUX_RPP, AUXCR);
219	udelay(2);
220	*result = read_byte(priv, CPTR);
221	// clear parallel poll state
222	write_byte(priv, AUX_RPP, AUXCR);
223	return 0;
224}
225EXPORT_SYMBOL(tms9914_parallel_poll);
226
227static void set_ppoll_reg(struct tms9914_priv *priv, int enable,
228			  unsigned int dio_line, int sense, int ist)
229{
230	u8 dio_byte;
231
232	if (enable && ((sense && ist) || (!sense && !ist))) {
233		dio_byte = 1 << (dio_line - 1);
234		write_byte(priv, dio_byte, PPR);
235	} else {
236		write_byte(priv, 0, PPR);
237	}
238}
239
240void tms9914_parallel_poll_configure(struct gpib_board *board,
241				     struct tms9914_priv *priv, u8 config)
242{
243	priv->ppoll_enable = (config & PPC_DISABLE) == 0;
244	priv->ppoll_line = (config & PPC_DIO_MASK) + 1;
245	priv->ppoll_sense = (config & PPC_SENSE) != 0;
246	set_ppoll_reg(priv, priv->ppoll_enable, priv->ppoll_line, priv->ppoll_sense, board->ist);
247}
248EXPORT_SYMBOL(tms9914_parallel_poll_configure);
249
250void tms9914_parallel_poll_response(struct gpib_board *board,
251				    struct tms9914_priv *priv, int ist)
252{
253	set_ppoll_reg(priv, priv->ppoll_enable, priv->ppoll_line, priv->ppoll_sense, ist);
254}
255EXPORT_SYMBOL(tms9914_parallel_poll_response);
256
257void tms9914_serial_poll_response(struct gpib_board *board,
258				  struct tms9914_priv *priv, u8 status)
259{
260	unsigned long flags;
261
262	spin_lock_irqsave(&board->spinlock, flags);
263	write_byte(priv, status, SPMR);
264	priv->spoll_status = status;
265	if (status & request_service_bit)
266		write_byte(priv, AUX_RSV2 | AUX_CS, AUXCR);
267	else
268		write_byte(priv, AUX_RSV2, AUXCR);
269	spin_unlock_irqrestore(&board->spinlock, flags);
270}
271EXPORT_SYMBOL(tms9914_serial_poll_response);
272
273u8 tms9914_serial_poll_status(struct gpib_board *board, struct tms9914_priv *priv)
274{
275	u8 status;
276	unsigned long flags;
277
278	spin_lock_irqsave(&board->spinlock, flags);
279	status = priv->spoll_status;
280	spin_unlock_irqrestore(&board->spinlock, flags);
281
282	return status;
283}
284EXPORT_SYMBOL(tms9914_serial_poll_status);
285
286int tms9914_primary_address(struct gpib_board *board,
287			    struct tms9914_priv *priv, unsigned int address)
288{
289	// put primary address in address0
290	write_byte(priv, address & ADDRESS_MASK, ADR);
291	return 0;
292}
293EXPORT_SYMBOL(tms9914_primary_address);
294
295int tms9914_secondary_address(struct gpib_board *board, struct tms9914_priv *priv,
296			      unsigned int address, int enable)
297{
298	if (enable)
299		priv->imr1_bits |= HR_APTIE;
300	else
301		priv->imr1_bits &= ~HR_APTIE;
302
303	write_byte(priv, priv->imr1_bits, IMR1);
304	return 0;
305}
306EXPORT_SYMBOL(tms9914_secondary_address);
307
308unsigned int tms9914_update_status(struct gpib_board *board, struct tms9914_priv *priv,
309				   unsigned int clear_mask)
310{
311	unsigned long flags;
312	unsigned int retval;
313
314	spin_lock_irqsave(&board->spinlock, flags);
315	retval = update_status_nolock(board, priv);
316	board->status &= ~clear_mask;
317	spin_unlock_irqrestore(&board->spinlock, flags);
318
319	return retval;
320}
321EXPORT_SYMBOL(tms9914_update_status);
322
323static void update_talker_state(struct tms9914_priv *priv, unsigned int address_status_bits)
324{
325	if (address_status_bits & HR_TA)	{
326		if (address_status_bits & HR_ATN)
327			priv->talker_state = talker_addressed;
328		else
329			/*
330			 * this could also be serial_poll_active, but the tms9914 provides no
331			 * way to distinguish, so we'll assume talker_active
332			 */
333			priv->talker_state = talker_active;
334	} else {
335		priv->talker_state = talker_idle;
336	}
337}
338
339static void update_listener_state(struct tms9914_priv *priv, unsigned int address_status_bits)
340{
341	if (address_status_bits & HR_LA)	{
342		if (address_status_bits & HR_ATN)
343			priv->listener_state = listener_addressed;
344		else
345			priv->listener_state = listener_active;
346	} else {
347		priv->listener_state = listener_idle;
348	}
349}
350
351static unsigned int update_status_nolock(struct gpib_board *board, struct tms9914_priv *priv)
352{
353	int address_status;
354	int bsr_bits;
355
356	address_status = read_byte(priv, ADSR);
357
358	// check for remote/local
359	if (address_status & HR_REM)
360		set_bit(REM_NUM, &board->status);
361	else
362		clear_bit(REM_NUM, &board->status);
363	// check for lockout
364	if (address_status & HR_LLO)
365		set_bit(LOK_NUM, &board->status);
366	else
367		clear_bit(LOK_NUM, &board->status);
368	// check for ATN
369	if (address_status & HR_ATN)
370		set_bit(ATN_NUM, &board->status);
371	else
372		clear_bit(ATN_NUM, &board->status);
373	// check for talker/listener addressed
374	update_talker_state(priv, address_status);
375	if (priv->talker_state == talker_active || priv->talker_state == talker_addressed)
376		set_bit(TACS_NUM, &board->status);
377	else
378		clear_bit(TACS_NUM, &board->status);
379
380	update_listener_state(priv, address_status);
381	if (priv->listener_state == listener_active || priv->listener_state == listener_addressed)
382		set_bit(LACS_NUM, &board->status);
383	else
384		clear_bit(LACS_NUM, &board->status);
385	// Check for SRQI - not reset elsewhere except in autospoll
386	if (board->status & SRQI) {
387		bsr_bits = read_byte(priv, BSR);
388		if (!(bsr_bits & BSR_SRQ_BIT))
389			clear_bit(SRQI_NUM, &board->status);
390	}
391
392	dev_dbg(board->gpib_dev, "status 0x%lx, state 0x%lx\n", board->status, priv->state);
393
394	return board->status;
395}
396
397int tms9914_line_status(const struct gpib_board *board, struct tms9914_priv *priv)
398{
399	int bsr_bits;
400	int status = VALID_ALL;
401
402	bsr_bits = read_byte(priv, BSR);
403
404	if (bsr_bits & BSR_REN_BIT)
405		status |= BUS_REN;
406	if (bsr_bits & BSR_IFC_BIT)
407		status |= BUS_IFC;
408	if (bsr_bits & BSR_SRQ_BIT)
409		status |= BUS_SRQ;
410	if (bsr_bits & BSR_EOI_BIT)
411		status |= BUS_EOI;
412	if (bsr_bits & BSR_NRFD_BIT)
413		status |= BUS_NRFD;
414	if (bsr_bits & BSR_NDAC_BIT)
415		status |= BUS_NDAC;
416	if (bsr_bits & BSR_DAV_BIT)
417		status |= BUS_DAV;
418	if (bsr_bits & BSR_ATN_BIT)
419		status |= BUS_ATN;
420
421	return status;
422}
423EXPORT_SYMBOL(tms9914_line_status);
424
425static int check_for_eos(struct tms9914_priv *priv, u8 byte)
426{
427	static const u8 seven_bit_compare_mask = 0x7f;
428
429	if ((priv->eos_flags & REOS) == 0)
430		return 0;
431
432	if (priv->eos_flags & BIN) {
433		if (priv->eos == byte)
434			return 1;
435	} else	{
436		if ((priv->eos & seven_bit_compare_mask) == (byte & seven_bit_compare_mask))
437			return 1;
438	}
439	return 0;
440}
441
442static int wait_for_read_byte(struct gpib_board *board, struct tms9914_priv *priv)
443{
444	if (wait_event_interruptible(board->wait,
445				     test_bit(READ_READY_BN, &priv->state) ||
446				     test_bit(DEV_CLEAR_BN, &priv->state) ||
447				     test_bit(TIMO_NUM, &board->status)))
448		return -ERESTARTSYS;
449
450	if (test_bit(TIMO_NUM, &board->status))
451		return -ETIMEDOUT;
452
453	if (test_bit(DEV_CLEAR_BN, &priv->state))
454		return -EINTR;
455	return 0;
456}
457
458static inline u8 tms9914_read_data_in(struct gpib_board *board,
459				      struct tms9914_priv *priv, int *end)
460{
461	unsigned long flags;
462	u8 data;
463
464	spin_lock_irqsave(&board->spinlock, flags);
465	clear_bit(READ_READY_BN, &priv->state);
466	data = read_byte(priv, DIR);
467	if (test_and_clear_bit(RECEIVED_END_BN, &priv->state))
468		*end = 1;
469	else
470		*end = 0;
471	switch (priv->holdoff_mode) {
472	case TMS9914_HOLDOFF_EOI:
473		if (*end)
474			priv->holdoff_active = 1;
475		break;
476	case TMS9914_HOLDOFF_ALL:
477		priv->holdoff_active = 1;
478		break;
479	case TMS9914_HOLDOFF_NONE:
480		break;
481	default:
482		dev_err(board->gpib_dev, "bug! bad holdoff mode %i\n", priv->holdoff_mode);
483		break;
484	}
485	spin_unlock_irqrestore(&board->spinlock, flags);
486
487	return data;
488}
489
490static int pio_read(struct gpib_board *board, struct tms9914_priv *priv, u8 *buffer,
491		    size_t length, int *end, size_t *bytes_read)
492{
493	ssize_t retval = 0;
494
495	*bytes_read = 0;
496	*end = 0;
497	while (*bytes_read < length && *end == 0) {
498		tms9914_release_holdoff(priv);
499		retval = wait_for_read_byte(board, priv);
500		if (retval < 0)
501			return retval;
502		buffer[(*bytes_read)++] = tms9914_read_data_in(board, priv, end);
503
504		if (check_for_eos(priv, buffer[*bytes_read - 1]))
505			*end = 1;
506	}
507
508	return retval;
509}
510
511int tms9914_read(struct gpib_board *board, struct tms9914_priv *priv, u8 *buffer,
512		 size_t length, int *end, size_t *bytes_read)
513{
514	ssize_t retval = 0;
515	size_t num_bytes;
516
517	*end = 0;
518	*bytes_read = 0;
519	if (length == 0)
520		return 0;
521
522	clear_bit(DEV_CLEAR_BN, &priv->state);
523
524	// transfer data (except for last byte)
525	if (length > 1)	{
526		if (priv->eos_flags & REOS)
527			tms9914_set_holdoff_mode(priv, TMS9914_HOLDOFF_ALL);
528		else
529			tms9914_set_holdoff_mode(priv, TMS9914_HOLDOFF_EOI);
530		// PIO transfer
531		retval = pio_read(board, priv, buffer, length - 1, end, &num_bytes);
532		*bytes_read += num_bytes;
533		if (retval < 0)
534			return retval;
535		buffer += num_bytes;
536		length -= num_bytes;
537	}
538	// read last bytes if we haven't received an END yet
539	if (*end == 0) {
540		// make sure we holdoff after last byte read
541		tms9914_set_holdoff_mode(priv, TMS9914_HOLDOFF_ALL);
542		retval = pio_read(board, priv, buffer, length, end, &num_bytes);
543		*bytes_read += num_bytes;
544		if (retval < 0)
545			return retval;
546	}
547	return 0;
548}
549EXPORT_SYMBOL(tms9914_read);
550
551static int pio_write_wait(struct gpib_board *board, struct tms9914_priv *priv)
552{
553	// wait until next byte is ready to be sent
554	if (wait_event_interruptible(board->wait,
555				     test_bit(WRITE_READY_BN, &priv->state) ||
556				     test_bit(BUS_ERROR_BN, &priv->state) ||
557				     test_bit(DEV_CLEAR_BN, &priv->state) ||
558				     test_bit(TIMO_NUM, &board->status)))
559		return -ERESTARTSYS;
560
561	if (test_bit(TIMO_NUM, &board->status))
562		return -ETIMEDOUT;
563	if (test_bit(BUS_ERROR_BN, &priv->state))
564		return -EIO;
565	if (test_bit(DEV_CLEAR_BN, &priv->state))
566		return -EINTR;
567
568	return 0;
569}
570
571static int pio_write(struct gpib_board *board, struct tms9914_priv *priv, u8 *buffer,
572		     size_t length, size_t *bytes_written)
573{
574	ssize_t retval = 0;
575	unsigned long flags;
576
577	*bytes_written = 0;
578	while (*bytes_written < length) {
579		retval = pio_write_wait(board, priv);
580		if (retval < 0)
581			break;
582
583		spin_lock_irqsave(&board->spinlock, flags);
584		clear_bit(WRITE_READY_BN, &priv->state);
585		write_byte(priv, buffer[(*bytes_written)++], CDOR);
586		spin_unlock_irqrestore(&board->spinlock, flags);
587	}
588	retval = pio_write_wait(board, priv);
589	if (retval < 0)
590		return retval;
591
592	return length;
593}
594
595int tms9914_write(struct gpib_board *board, struct tms9914_priv *priv,
596		  u8 *buffer, size_t length, int send_eoi, size_t *bytes_written)
597{
598	ssize_t retval = 0;
599
600	*bytes_written = 0;
601	if (length == 0)
602		return 0;
603
604	clear_bit(BUS_ERROR_BN, &priv->state);
605	clear_bit(DEV_CLEAR_BN, &priv->state);
606
607	if (send_eoi)
608		length-- ; /* save the last byte for sending EOI */
609
610	if (length > 0)	{
611		size_t num_bytes;
612		// PIO transfer
613		retval = pio_write(board, priv, buffer, length, &num_bytes);
614		*bytes_written += num_bytes;
615		if (retval < 0)
616			return retval;
617	}
618	if (send_eoi) {
619		size_t num_bytes;
620		/*send EOI */
621		write_byte(priv, AUX_SEOI, AUXCR);
622
623		retval = pio_write(board, priv, &buffer[*bytes_written], 1, &num_bytes);
624		*bytes_written += num_bytes;
625	}
626	return retval;
627}
628EXPORT_SYMBOL(tms9914_write);
629
630static void check_my_address_state(struct gpib_board *board,
631				   struct tms9914_priv *priv, int cmd_byte)
632{
633	if (cmd_byte == MLA(board->pad)) {
634		priv->primary_listen_addressed = 1;
635		// become active listener
636		if (board->sad < 0)
637			write_byte(priv, AUX_LON | AUX_CS, AUXCR);
638	} else if (board->sad >= 0 && priv->primary_listen_addressed &&
639		  cmd_byte == MSA(board->sad)) {
640		// become active listener
641		write_byte(priv, AUX_LON | AUX_CS, AUXCR);
642	} else if (cmd_byte != MLA(board->pad) && (cmd_byte & 0xe0) == LAD) {
643		priv->primary_listen_addressed = 0;
644	} else if (cmd_byte == UNL) {
645		priv->primary_listen_addressed = 0;
646		write_byte(priv, AUX_LON, AUXCR);
647	} else if (cmd_byte == MTA(board->pad))	{
648		priv->primary_talk_addressed = 1;
649		if (board->sad < 0)
650			// make active talker
651			write_byte(priv, AUX_TON | AUX_CS, AUXCR);
652	} else if (board->sad >= 0 && priv->primary_talk_addressed &&
653		   cmd_byte == MSA(board->sad)) {
654		// become active talker
655		write_byte(priv, AUX_TON | AUX_CS, AUXCR);
656	} else if (cmd_byte != MTA(board->pad) && (cmd_byte & 0xe0) == TAD) {
657		// Other Talk Address
658		priv->primary_talk_addressed = 0;
659		write_byte(priv, AUX_TON, AUXCR);
660	} else if (cmd_byte == UNT) {
661		priv->primary_talk_addressed = 0;
662		write_byte(priv, AUX_TON, AUXCR);
663	}
664}
665
666int tms9914_command(struct gpib_board *board, struct tms9914_priv *priv,  u8 *buffer,
667		    size_t length, size_t *bytes_written)
668{
669	int retval = 0;
670	unsigned long flags;
671
672	*bytes_written = 0;
673	while (*bytes_written < length) {
674		if (wait_event_interruptible(board->wait,
675					     test_bit(COMMAND_READY_BN,
676						      &priv->state) ||
677					     test_bit(TIMO_NUM, &board->status)))
678			break;
679		if (test_bit(TIMO_NUM, &board->status))
680			break;
681
682		spin_lock_irqsave(&board->spinlock, flags);
683		clear_bit(COMMAND_READY_BN, &priv->state);
684		write_byte(priv, buffer[*bytes_written], CDOR);
685		spin_unlock_irqrestore(&board->spinlock, flags);
686
687		check_my_address_state(board, priv, buffer[*bytes_written]);
688
689		++(*bytes_written);
690	}
691	// wait until last command byte is written
692	if (wait_event_interruptible(board->wait,
693				     test_bit(COMMAND_READY_BN,
694					      &priv->state) || test_bit(TIMO_NUM, &board->status)))
695		retval = -ERESTARTSYS;
696	if (test_bit(TIMO_NUM, &board->status))
697		retval = -ETIMEDOUT;
698
699	return retval;
700}
701EXPORT_SYMBOL(tms9914_command);
702
703irqreturn_t tms9914_interrupt(struct gpib_board *board, struct tms9914_priv *priv)
704{
705	int status0, status1;
706
707	// read interrupt status (also clears status)
708	status0 = read_byte(priv, ISR0);
709	status1 = read_byte(priv, ISR1);
710	return tms9914_interrupt_have_status(board, priv, status0, status1);
711}
712EXPORT_SYMBOL(tms9914_interrupt);
713
714irqreturn_t tms9914_interrupt_have_status(struct gpib_board *board, struct tms9914_priv *priv,
715					  int status0, int status1)
716{
717	// record reception of END
718	if (status0 & HR_END)
719		set_bit(RECEIVED_END_BN, &priv->state);
720	// get incoming data in PIO mode
721	if ((status0 & HR_BI))
722		set_bit(READ_READY_BN, &priv->state);
723	if ((status0 & HR_BO))	{
724		if (read_byte(priv, ADSR) & HR_ATN)
725			set_bit(COMMAND_READY_BN, &priv->state);
726		else
727			set_bit(WRITE_READY_BN, &priv->state);
728	}
729
730	if (status0 & HR_SPAS) {
731		priv->spoll_status &= ~request_service_bit;
732		write_byte(priv, priv->spoll_status, SPMR);
733		// FIXME: set SPOLL status bit
734	}
735	// record service request in status
736	if (status1 & HR_SRQ)
737		set_bit(SRQI_NUM, &board->status);
738	// have been addressed (with secondary addressing disabled)
739	if (status1 & HR_MA)
740		// clear dac holdoff
741		write_byte(priv, AUX_VAL, AUXCR);
742	// unrecognized command received
743	if (status1 & HR_UNC) {
744		unsigned short command_byte = read_byte(priv, CPTR) & gpib_command_mask;
745
746		switch (command_byte) {
747		case PP_CONFIG:
748			priv->ppoll_configure_state = 1;
749			/*
750			 * AUX_PTS generates another UNC interrupt on the next command byte
751			 * if it is in the secondary address group (such as PPE and PPD).
752			 */
753			write_byte(priv, AUX_PTS, AUXCR);
754			write_byte(priv, AUX_VAL, AUXCR);
755			break;
756		case PPU:
757			tms9914_parallel_poll_configure(board, priv, command_byte);
758			write_byte(priv, AUX_VAL, AUXCR);
759			break;
760		default:
761			if (is_PPE(command_byte) || is_PPD(command_byte)) {
762				if (priv->ppoll_configure_state) {
763					tms9914_parallel_poll_configure(board, priv, command_byte);
764					write_byte(priv, AUX_VAL, AUXCR);
765				} else	{// bad parallel poll configure byte
766					// clear dac holdoff
767					write_byte(priv, AUX_INVAL, AUXCR);
768				}
769			} else	{
770				// clear dac holdoff
771				write_byte(priv, AUX_INVAL, AUXCR);
772			}
773			break;
774		}
775
776		if (in_primary_command_group(command_byte) && command_byte != PP_CONFIG)
777			priv->ppoll_configure_state = 0;
778	}
779
780	if (status1 & HR_ERR) {
781		dev_dbg(board->gpib_dev, "gpib bus error\n");
782		set_bit(BUS_ERROR_BN, &priv->state);
783	}
784
785	if (status1 & HR_IFC) {
786		push_gpib_event(board, EVENT_IFC);
787		clear_bit(CIC_NUM, &board->status);
788	}
789
790	if (status1 & HR_GET) {
791		push_gpib_event(board, EVENT_DEV_TRG);
792		// clear dac holdoff
793		write_byte(priv, AUX_VAL, AUXCR);
794	}
795
796	if (status1 & HR_DCAS) {
797		push_gpib_event(board, EVENT_DEV_CLR);
798		// clear dac holdoff
799		write_byte(priv, AUX_VAL, AUXCR);
800		set_bit(DEV_CLEAR_BN, &priv->state);
801	}
802
803	// check for being addressed with secondary addressing
804	if (status1 & HR_APT) {
805		if (board->sad < 0)
806			dev_err(board->gpib_dev, "bug, APT interrupt without secondary addressing?\n");
807		if ((read_byte(priv, CPTR) & gpib_command_mask) == MSA(board->sad))
808			write_byte(priv, AUX_VAL, AUXCR);
809		else
810			write_byte(priv, AUX_INVAL, AUXCR);
811	}
812
813	if ((status0 & priv->imr0_bits) || (status1 & priv->imr1_bits))	{
814		dev_dbg(board->gpib_dev, "isr0 0x%x, imr0 0x%x, isr1 0x%x, imr1 0x%x\n",
815			status0, priv->imr0_bits, status1, priv->imr1_bits);
816		update_status_nolock(board, priv);
817		wake_up_interruptible(&board->wait);
818	}
819	return IRQ_HANDLED;
820}
821EXPORT_SYMBOL(tms9914_interrupt_have_status);
822
823void tms9914_board_reset(struct tms9914_priv *priv)
824{
825	/* chip reset */
826	write_byte(priv, AUX_CHIP_RESET | AUX_CS, AUXCR);
827
828	/* disable all interrupts */
829	priv->imr0_bits = 0;
830	write_byte(priv, priv->imr0_bits, IMR0);
831	priv->imr1_bits = 0;
832	write_byte(priv, priv->imr1_bits, IMR1);
833	write_byte(priv, AUX_DAI | AUX_CS, AUXCR);
834
835	/* clear registers by reading */
836	read_byte(priv, CPTR);
837	read_byte(priv, ISR0);
838	read_byte(priv, ISR1);
839
840	write_byte(priv, 0, SPMR);
841
842	/* parallel poll unconfigure */
843	write_byte(priv, 0, PPR);
844	/* request for data holdoff */
845	tms9914_set_holdoff_mode(priv, TMS9914_HOLDOFF_ALL);
846}
847EXPORT_SYMBOL_GPL(tms9914_board_reset);
848
849void tms9914_online(struct gpib_board *board, struct tms9914_priv *priv)
850{
851	/* set GPIB address */
852	tms9914_primary_address(board, priv, board->pad);
853	tms9914_secondary_address(board, priv, board->sad, board->sad >= 0);
854
855	/* enable tms9914 interrupts */
856	priv->imr0_bits |= HR_MACIE | HR_RLCIE | HR_ENDIE | HR_BOIE | HR_BIIE |
857		HR_SPASIE;
858	priv->imr1_bits |= HR_MAIE | HR_SRQIE | HR_UNCIE | HR_ERRIE | HR_IFCIE |
859		HR_GETIE | HR_DCASIE;
860	write_byte(priv, priv->imr0_bits, IMR0);
861	write_byte(priv, priv->imr1_bits, IMR1);
862	write_byte(priv, AUX_DAI, AUXCR);
863
864	/* turn off reset state */
865	write_byte(priv, AUX_CHIP_RESET, AUXCR);
866}
867EXPORT_SYMBOL_GPL(tms9914_online);
868
869#ifdef CONFIG_HAS_IOPORT
870// wrapper for inb
871u8 tms9914_ioport_read_byte(struct tms9914_priv *priv, unsigned int register_num)
872{
873	return inb(priv->iobase + register_num * priv->offset);
874}
875EXPORT_SYMBOL_GPL(tms9914_ioport_read_byte);
876
877// wrapper for outb
878void tms9914_ioport_write_byte(struct tms9914_priv *priv, u8 data, unsigned int register_num)
879{
880	outb(data, priv->iobase + register_num * priv->offset);
881	if (register_num == AUXCR)
882		udelay(1);
883}
884EXPORT_SYMBOL_GPL(tms9914_ioport_write_byte);
885#endif
886
887// wrapper for readb
888u8 tms9914_iomem_read_byte(struct tms9914_priv *priv, unsigned int register_num)
889{
890	return readb(priv->mmiobase + register_num * priv->offset);
891}
892EXPORT_SYMBOL_GPL(tms9914_iomem_read_byte);
893
894// wrapper for writeb
895void tms9914_iomem_write_byte(struct tms9914_priv *priv, u8 data, unsigned int register_num)
896{
897	writeb(data, priv->mmiobase + register_num * priv->offset);
898	if (register_num == AUXCR)
899		udelay(1);
900}
901EXPORT_SYMBOL_GPL(tms9914_iomem_write_byte);
902
903static int __init tms9914_init_module(void)
904{
905	return 0;
906}
907
908static void __exit tms9914_exit_module(void)
909{
910}
911
912module_init(tms9914_init_module);
913module_exit(tms9914_exit_module);
914
~/ Read-only file preview.