aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/sbus/char
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2008-08-27 01:25:03 -0400
committerDavid S. Miller <davem@davemloft.net>2008-08-29 05:13:08 -0400
commit902663f6ea4a2603bee0d88450aae2d653a46f5d (patch)
treed085c52ce6569c08c90ebfcf23871eed7bcedc3d /drivers/sbus/char
parent51e0f004a9ab9104acbe323c0b20e0279bf9be85 (diff)
sparc: Delete bare sbus char bpp driver, obsoleted by parport_sunbpp
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/sbus/char')
-rw-r--r--drivers/sbus/char/Kconfig8
-rw-r--r--drivers/sbus/char/Makefile1
-rw-r--r--drivers/sbus/char/bpp.c1055
3 files changed, 0 insertions, 1064 deletions
diff --git a/drivers/sbus/char/Kconfig b/drivers/sbus/char/Kconfig
index 400c65bfb8c7..9cd54ec63aef 100644
--- a/drivers/sbus/char/Kconfig
+++ b/drivers/sbus/char/Kconfig
@@ -30,14 +30,6 @@ config OBP_FLASH
30 The OpenBoot PROM on Ultra systems is flashable. If you want to be 30 The OpenBoot PROM on Ultra systems is flashable. If you want to be
31 able to upgrade the OBP firmware, say Y here. 31 able to upgrade the OBP firmware, say Y here.
32 32
33config SUN_BPP
34 tristate "Bidirectional parallel port support (OBSOLETE)"
35 depends on EXPERIMENTAL
36 help
37 Say Y here to support Sun's obsolete variant of IEEE1284
38 bidirectional parallel port protocol as /dev/bppX. Can be built on
39 x86 machines.
40
41config SUN_VIDEOPIX 33config SUN_VIDEOPIX
42 tristate "Videopix Frame Grabber (EXPERIMENTAL)" 34 tristate "Videopix Frame Grabber (EXPERIMENTAL)"
43 depends on EXPERIMENTAL && (BROKEN || !64BIT) 35 depends on EXPERIMENTAL && (BROKEN || !64BIT)
diff --git a/drivers/sbus/char/Makefile b/drivers/sbus/char/Makefile
index 7ab060e9a5fe..d8b2d0c0ebd5 100644
--- a/drivers/sbus/char/Makefile
+++ b/drivers/sbus/char/Makefile
@@ -17,7 +17,6 @@ obj-$(CONFIG_WATCHDOG_RIO) += riowatchdog.o
17obj-$(CONFIG_OBP_FLASH) += flash.o 17obj-$(CONFIG_OBP_FLASH) += flash.o
18obj-$(CONFIG_SUN_OPENPROMIO) += openprom.o 18obj-$(CONFIG_SUN_OPENPROMIO) += openprom.o
19obj-$(CONFIG_SUN_MOSTEK_RTC) += rtc.o 19obj-$(CONFIG_SUN_MOSTEK_RTC) += rtc.o
20obj-$(CONFIG_SUN_BPP) += bpp.o
21obj-$(CONFIG_SUN_VIDEOPIX) += vfc.o 20obj-$(CONFIG_SUN_VIDEOPIX) += vfc.o
22obj-$(CONFIG_TADPOLE_TS102_UCTRL) += uctrl.o 21obj-$(CONFIG_TADPOLE_TS102_UCTRL) += uctrl.o
23obj-$(CONFIG_SUN_JSFLASH) += jsflash.o 22obj-$(CONFIG_SUN_JSFLASH) += jsflash.o
diff --git a/drivers/sbus/char/bpp.c b/drivers/sbus/char/bpp.c
deleted file mode 100644
index bba21e053a1b..000000000000
--- a/drivers/sbus/char/bpp.c
+++ /dev/null
@@ -1,1055 +0,0 @@
1/*
2 * drivers/sbus/char/bpp.c
3 *
4 * Copyright (c) 1995 Picture Elements
5 * Stephen Williams (steve@icarus.com)
6 * Gus Baldauf (gbaldauf@ix.netcom.com)
7 *
8 * Linux/SPARC port by Peter Zaitcev.
9 * Integration into SPARC tree by Tom Dyas.
10 */
11
12
13#include <linux/kernel.h>
14#include <linux/module.h>
15#include <linux/fs.h>
16#include <linux/errno.h>
17#include <linux/sched.h>
18#include <linux/spinlock.h>
19#include <linux/timer.h>
20#include <linux/ioport.h>
21#include <linux/major.h>
22#include <linux/smp_lock.h>
23
24#include <asm/uaccess.h>
25#include <asm/io.h>
26
27#if defined(__i386__)
28# include <asm/system.h>
29#endif
30
31#if defined(__sparc__)
32# include <linux/init.h>
33# include <linux/delay.h> /* udelay() */
34
35# include <asm/oplib.h> /* OpenProm Library */
36# include <asm/sbus.h>
37#endif
38
39#include <asm/bpp.h>
40
41#define BPP_PROBE_CODE 0x55
42#define BPP_DELAY 100
43
44static const unsigned BPP_MAJOR = LP_MAJOR;
45static const char *bpp_dev_name = "bpp";
46
47/* When switching from compatibility to a mode where I can read, try
48 the following mode first. */
49
50/* const unsigned char DEFAULT_ECP = 0x10; */
51static const unsigned char DEFAULT_ECP = 0x30;
52static const unsigned char DEFAULT_NIBBLE = 0x00;
53
54/*
55 * These are 1284 time constraints, in units of jiffies.
56 */
57
58static const unsigned long TIME_PSetup = 1;
59static const unsigned long TIME_PResponse = 6;
60static const unsigned long TIME_IDLE_LIMIT = 2000;
61
62/*
63 * One instance per supported subdevice...
64 */
65# define BPP_NO 3
66
67enum IEEE_Mode { COMPATIBILITY, NIBBLE, ECP, ECP_RLE, EPP };
68
69struct inst {
70 unsigned present : 1; /* True if the hardware exists */
71 unsigned enhanced : 1; /* True if the hardware in "enhanced" */
72 unsigned opened : 1; /* True if the device is opened already */
73 unsigned run_flag : 1; /* True if waiting for a repeate byte */
74
75 unsigned char direction; /* 0 --> out, 0x20 --> IN */
76 unsigned char pp_state; /* State of host controlled pins. */
77 enum IEEE_Mode mode;
78
79 unsigned char run_length;
80 unsigned char repeat_byte;
81};
82
83static struct inst instances[BPP_NO];
84
85#if defined(__i386__)
86
87static const unsigned short base_addrs[BPP_NO] = { 0x278, 0x378, 0x3bc };
88
89/*
90 * These are for data access.
91 * Control lines accesses are hidden in set_bits() and get_bits().
92 * The exception is the probe procedure, which is system-dependent.
93 */
94#define bpp_outb_p(data, base) outb_p((data), (base))
95#define bpp_inb(base) inb(base)
96#define bpp_inb_p(base) inb_p(base)
97
98/*
99 * This method takes the pin values mask and sets the hardware pins to
100 * the requested value: 1 == high voltage, 0 == low voltage. This
101 * burries the annoying PC bit inversion and preserves the direction
102 * flag.
103 */
104static void set_pins(unsigned short pins, unsigned minor)
105{
106 unsigned char bits = instances[minor].direction; /* == 0x20 */
107
108 if (! (pins & BPP_PP_nStrobe)) bits |= 1;
109 if (! (pins & BPP_PP_nAutoFd)) bits |= 2;
110 if ( pins & BPP_PP_nInit) bits |= 4;
111 if (! (pins & BPP_PP_nSelectIn)) bits |= 8;
112
113 instances[minor].pp_state = bits;
114
115 outb_p(bits, base_addrs[minor]+2);
116}
117
118static unsigned short get_pins(unsigned minor)
119{
120 unsigned short bits = 0;
121
122 unsigned value = instances[minor].pp_state;
123 if (! (value & 0x01)) bits |= BPP_PP_nStrobe;
124 if (! (value & 0x02)) bits |= BPP_PP_nAutoFd;
125 if (value & 0x04) bits |= BPP_PP_nInit;
126 if (! (value & 0x08)) bits |= BPP_PP_nSelectIn;
127
128 value = inb_p(base_addrs[minor]+1);
129 if (value & 0x08) bits |= BPP_GP_nFault;
130 if (value & 0x10) bits |= BPP_GP_Select;
131 if (value & 0x20) bits |= BPP_GP_PError;
132 if (value & 0x40) bits |= BPP_GP_nAck;
133 if (! (value & 0x80)) bits |= BPP_GP_Busy;
134
135 return bits;
136}
137
138#endif /* __i386__ */
139
140#if defined(__sparc__)
141
142/*
143 * Register block
144 */
145 /* DMA registers */
146#define BPP_CSR 0x00
147#define BPP_ADDR 0x04
148#define BPP_BCNT 0x08
149#define BPP_TST_CSR 0x0C
150 /* Parallel Port registers */
151#define BPP_HCR 0x10
152#define BPP_OCR 0x12
153#define BPP_DR 0x14
154#define BPP_TCR 0x15
155#define BPP_OR 0x16
156#define BPP_IR 0x17
157#define BPP_ICR 0x18
158#define BPP_SIZE 0x1A
159
160/* BPP_CSR. Bits of type RW1 are cleared with writing '1'. */
161#define P_DEV_ID_MASK 0xf0000000 /* R */
162#define P_DEV_ID_ZEBRA 0x40000000
163#define P_DEV_ID_L64854 0xa0000000 /* == NCR 89C100+89C105. Pity. */
164#define P_NA_LOADED 0x08000000 /* R NA wirtten but was not used */
165#define P_A_LOADED 0x04000000 /* R */
166#define P_DMA_ON 0x02000000 /* R DMA is not disabled */
167#define P_EN_NEXT 0x01000000 /* RW */
168#define P_TCI_DIS 0x00800000 /* RW TCI forbidden from interrupts */
169#define P_DIAG 0x00100000 /* RW Disables draining and resetting
170 of P-FIFO on loading of P_ADDR*/
171#define P_BURST_SIZE 0x000c0000 /* RW SBus burst size */
172#define P_BURST_8 0x00000000
173#define P_BURST_4 0x00040000
174#define P_BURST_1 0x00080000 /* "No burst" write */
175#define P_TC 0x00004000 /* RW1 Term Count, can be cleared when
176 P_EN_NEXT=1 */
177#define P_EN_CNT 0x00002000 /* RW */
178#define P_EN_DMA 0x00000200 /* RW */
179#define P_WRITE 0x00000100 /* R DMA dir, 1=to ram, 0=to port */
180#define P_RESET 0x00000080 /* RW */
181#define P_SLAVE_ERR 0x00000040 /* RW1 Access size error */
182#define P_INVALIDATE 0x00000020 /* W Drop P-FIFO */
183#define P_INT_EN 0x00000010 /* RW OK to P_INT_PEND||P_ERR_PEND */
184#define P_DRAINING 0x0000000c /* R P-FIFO is draining to memory */
185#define P_ERR_PEND 0x00000002 /* R */
186#define P_INT_PEND 0x00000001 /* R */
187
188/* BPP_HCR. Time is in increments of SBus clock. */
189#define P_HCR_TEST 0x8000 /* Allows buried counters to be read */
190#define P_HCR_DSW 0x7f00 /* Data strobe width (in ticks) */
191#define P_HCR_DDS 0x007f /* Data setup before strobe (in ticks) */
192
193/* BPP_OCR. */
194#define P_OCR_MEM_CLR 0x8000
195#define P_OCR_DATA_SRC 0x4000 /* ) */
196#define P_OCR_DS_DSEL 0x2000 /* ) Bidirectional */
197#define P_OCR_BUSY_DSEL 0x1000 /* ) selects */
198#define P_OCR_ACK_DSEL 0x0800 /* ) */
199#define P_OCR_EN_DIAG 0x0400
200#define P_OCR_BUSY_OP 0x0200 /* Busy operation */
201#define P_OCR_ACK_OP 0x0100 /* Ack operation */
202#define P_OCR_SRST 0x0080 /* Reset state machines. Not selfcleaning. */
203#define P_OCR_IDLE 0x0008 /* PP data transfer state machine is idle */
204#define P_OCR_V_ILCK 0x0002 /* Versatec faded. Zebra only. */
205#define P_OCR_EN_VER 0x0001 /* Enable Versatec (0 - enable). Zebra only. */
206
207/* BPP_TCR */
208#define P_TCR_DIR 0x08
209#define P_TCR_BUSY 0x04
210#define P_TCR_ACK 0x02
211#define P_TCR_DS 0x01 /* Strobe */
212
213/* BPP_OR */
214#define P_OR_V3 0x20 /* ) */
215#define P_OR_V2 0x10 /* ) on Zebra only */
216#define P_OR_V1 0x08 /* ) */
217#define P_OR_INIT 0x04
218#define P_OR_AFXN 0x02 /* Auto Feed */
219#define P_OR_SLCT_IN 0x01
220
221/* BPP_IR */
222#define P_IR_PE 0x04
223#define P_IR_SLCT 0x02
224#define P_IR_ERR 0x01
225
226/* BPP_ICR */
227#define P_DS_IRQ 0x8000 /* RW1 */
228#define P_ACK_IRQ 0x4000 /* RW1 */
229#define P_BUSY_IRQ 0x2000 /* RW1 */
230#define P_PE_IRQ 0x1000 /* RW1 */
231#define P_SLCT_IRQ 0x0800 /* RW1 */
232#define P_ERR_IRQ 0x0400 /* RW1 */
233#define P_DS_IRQ_EN 0x0200 /* RW Always on rising edge */
234#define P_ACK_IRQ_EN 0x0100 /* RW Always on rising edge */
235#define P_BUSY_IRP 0x0080 /* RW 1= rising edge */
236#define P_BUSY_IRQ_EN 0x0040 /* RW */
237#define P_PE_IRP 0x0020 /* RW 1= rising edge */
238#define P_PE_IRQ_EN 0x0010 /* RW */
239#define P_SLCT_IRP 0x0008 /* RW 1= rising edge */
240#define P_SLCT_IRQ_EN 0x0004 /* RW */
241#define P_ERR_IRP 0x0002 /* RW1 1= rising edge */
242#define P_ERR_IRQ_EN 0x0001 /* RW */
243
244static void __iomem *base_addrs[BPP_NO];
245
246#define bpp_outb_p(data, base) sbus_writeb(data, (base) + BPP_DR)
247#define bpp_inb_p(base) sbus_readb((base) + BPP_DR)
248#define bpp_inb(base) sbus_readb((base) + BPP_DR)
249
250static void set_pins(unsigned short pins, unsigned minor)
251{
252 void __iomem *base = base_addrs[minor];
253 unsigned char bits_tcr = 0, bits_or = 0;
254
255 if (instances[minor].direction & 0x20) bits_tcr |= P_TCR_DIR;
256 if ( pins & BPP_PP_nStrobe) bits_tcr |= P_TCR_DS;
257
258 if ( pins & BPP_PP_nAutoFd) bits_or |= P_OR_AFXN;
259 if (! (pins & BPP_PP_nInit)) bits_or |= P_OR_INIT;
260 if (! (pins & BPP_PP_nSelectIn)) bits_or |= P_OR_SLCT_IN;
261
262 sbus_writeb(bits_or, base + BPP_OR);
263 sbus_writeb(bits_tcr, base + BPP_TCR);
264}
265
266/*
267 * i386 people read output pins from a software image.
268 * We may get them back from hardware.
269 * Again, inversion of pins must he buried here.
270 */
271static unsigned short get_pins(unsigned minor)
272{
273 void __iomem *base = base_addrs[minor];
274 unsigned short bits = 0;
275 unsigned value_tcr = sbus_readb(base + BPP_TCR);
276 unsigned value_ir = sbus_readb(base + BPP_IR);
277 unsigned value_or = sbus_readb(base + BPP_OR);
278
279 if (value_tcr & P_TCR_DS) bits |= BPP_PP_nStrobe;
280 if (value_or & P_OR_AFXN) bits |= BPP_PP_nAutoFd;
281 if (! (value_or & P_OR_INIT)) bits |= BPP_PP_nInit;
282 if (! (value_or & P_OR_SLCT_IN)) bits |= BPP_PP_nSelectIn;
283
284 if (value_ir & P_IR_ERR) bits |= BPP_GP_nFault;
285 if (! (value_ir & P_IR_SLCT)) bits |= BPP_GP_Select;
286 if (! (value_ir & P_IR_PE)) bits |= BPP_GP_PError;
287 if (! (value_tcr & P_TCR_ACK)) bits |= BPP_GP_nAck;
288 if (value_tcr & P_TCR_BUSY) bits |= BPP_GP_Busy;
289
290 return bits;
291}
292
293#endif /* __sparc__ */
294
295static void snooze(unsigned long snooze_time, unsigned minor)
296{
297 schedule_timeout_uninterruptible(snooze_time + 1);
298}
299
300static int wait_for(unsigned short set, unsigned short clr,
301 unsigned long delay, unsigned minor)
302{
303 unsigned short pins = get_pins(minor);
304
305 unsigned long extime = 0;
306
307 /*
308 * Try a real fast scan for the first jiffy, in case the device
309 * responds real good. The first while loop guesses an expire
310 * time accounting for possible wraparound of jiffies.
311 */
312 while (time_after_eq(jiffies, extime)) extime = jiffies + 1;
313 while ( (time_before(jiffies, extime))
314 && (((pins & set) != set) || ((pins & clr) != 0)) ) {
315 pins = get_pins(minor);
316 }
317
318 delay -= 1;
319
320 /*
321 * If my delay expired or the pins are still not where I want
322 * them, then resort to using the timer and greatly reduce my
323 * sample rate. If the peripheral is going to be slow, this will
324 * give the CPU up to some more worthy process.
325 */
326 while ( delay && (((pins & set) != set) || ((pins & clr) != 0)) ) {
327
328 snooze(1, minor);
329 pins = get_pins(minor);
330 delay -= 1;
331 }
332
333 if (delay == 0) return -1;
334 else return pins;
335}
336
337/*
338 * Return ZERO(0) If the negotiation succeeds, an errno otherwise. An
339 * errno means something broke, and I do not yet know how to fix it.
340 */
341static int negotiate(unsigned char mode, unsigned minor)
342{
343 int rc;
344 unsigned short pins = get_pins(minor);
345 if (pins & BPP_PP_nSelectIn) return -EIO;
346
347
348 /* Event 0: Write the mode to the data lines */
349 bpp_outb_p(mode, base_addrs[minor]);
350
351 snooze(TIME_PSetup, minor);
352
353 /* Event 1: Strobe the mode code into the peripheral */
354 set_pins(BPP_PP_nSelectIn|BPP_PP_nStrobe|BPP_PP_nInit, minor);
355
356 /* Wait for Event 2: Peripheral responds as a 1284 device. */
357 rc = wait_for(BPP_GP_PError|BPP_GP_Select|BPP_GP_nFault,
358 BPP_GP_nAck,
359 TIME_PResponse,
360 minor);
361
362 if (rc == -1) return -ETIMEDOUT;
363
364 /* Event 3: latch extensibility request */
365 set_pins(BPP_PP_nSelectIn|BPP_PP_nInit, minor);
366
367 /* ... quick nap while peripheral ponders the byte i'm sending...*/
368 snooze(1, minor);
369
370 /* Event 4: restore strobe, to ACK peripheral's response. */
371 set_pins(BPP_PP_nSelectIn|BPP_PP_nAutoFd|BPP_PP_nStrobe|BPP_PP_nInit, minor);
372
373 /* Wait for Event 6: Peripheral latches response bits */
374 rc = wait_for(BPP_GP_nAck, 0, TIME_PSetup+TIME_PResponse, minor);
375 if (rc == -1) return -EIO;
376
377 /* A 1284 device cannot refuse nibble mode */
378 if (mode == DEFAULT_NIBBLE) return 0;
379
380 if (pins & BPP_GP_Select) return 0;
381
382 return -EPROTONOSUPPORT;
383}
384
385static int terminate(unsigned minor)
386{
387 int rc;
388
389 /* Event 22: Request termination of 1284 mode */
390 set_pins(BPP_PP_nAutoFd|BPP_PP_nStrobe|BPP_PP_nInit, minor);
391
392 /* Wait for Events 23 and 24: ACK termination request. */
393 rc = wait_for(BPP_GP_Busy|BPP_GP_nFault,
394 BPP_GP_nAck,
395 TIME_PSetup+TIME_PResponse,
396 minor);
397
398 instances[minor].direction = 0;
399 instances[minor].mode = COMPATIBILITY;
400
401 if (rc == -1) {
402 return -EIO;
403 }
404
405 /* Event 25: Handshake by lowering nAutoFd */
406 set_pins(BPP_PP_nStrobe|BPP_PP_nInit, minor);
407
408 /* Event 26: Peripheral wiggles lines... */
409
410 /* Event 27: Peripheral sets nAck HIGH to ack handshake */
411 rc = wait_for(BPP_GP_nAck, 0, TIME_PResponse, minor);
412 if (rc == -1) {
413 set_pins(BPP_PP_nAutoFd|BPP_PP_nStrobe|BPP_PP_nInit, minor);
414 return -EIO;
415 }
416
417 /* Event 28: Finish phase by raising nAutoFd */
418 set_pins(BPP_PP_nAutoFd|BPP_PP_nStrobe|BPP_PP_nInit, minor);
419
420 return 0;
421}
422
423static DEFINE_SPINLOCK(bpp_open_lock);
424
425/*
426 * Allow only one process to open the device at a time.
427 */
428static int bpp_open(struct inode *inode, struct file *f)
429{
430 unsigned minor = iminor(inode);
431 int ret;
432
433 lock_kernel();
434 spin_lock(&bpp_open_lock);
435 ret = 0;
436 if (minor >= BPP_NO) {
437 ret = -ENODEV;
438 } else {
439 if (! instances[minor].present) {
440 ret = -ENODEV;
441 } else {
442 if (instances[minor].opened)
443 ret = -EBUSY;
444 else
445 instances[minor].opened = 1;
446 }
447 }
448 spin_unlock(&bpp_open_lock);
449 unlock_kernel();
450
451 return ret;
452}
453
454/*
455 * When the process closes the device, this method is called to clean
456 * up and reset the hardware. Always leave the device in compatibility
457 * mode as this is a reasonable place to clean up from messes made by
458 * ioctls, or other mayhem.
459 */
460static int bpp_release(struct inode *inode, struct file *f)
461{
462 unsigned minor = iminor(inode);
463
464 spin_lock(&bpp_open_lock);
465 instances[minor].opened = 0;
466
467 if (instances[minor].mode != COMPATIBILITY)
468 terminate(minor);
469
470 spin_unlock(&bpp_open_lock);
471
472 return 0;
473}
474
475static long read_nibble(unsigned minor, char __user *c, unsigned long cnt)
476{
477 unsigned long remaining = cnt;
478 long rc;
479
480 while (remaining > 0) {
481 unsigned char byte = 0;
482 int pins;
483
484 /* Event 7: request nibble */
485 set_pins(BPP_PP_nSelectIn|BPP_PP_nStrobe, minor);
486
487 /* Wait for event 9: Peripher strobes first nibble */
488 pins = wait_for(0, BPP_GP_nAck, TIME_IDLE_LIMIT, minor);
489 if (pins == -1) return -ETIMEDOUT;
490
491 /* Event 10: I handshake nibble */
492 set_pins(BPP_PP_nSelectIn|BPP_PP_nStrobe|BPP_PP_nAutoFd, minor);
493 if (pins & BPP_GP_nFault) byte |= 0x01;
494 if (pins & BPP_GP_Select) byte |= 0x02;
495 if (pins & BPP_GP_PError) byte |= 0x04;
496 if (pins & BPP_GP_Busy) byte |= 0x08;
497
498 /* Wait for event 11: Peripheral handshakes nibble */
499 rc = wait_for(BPP_GP_nAck, 0, TIME_PResponse, minor);
500
501 /* Event 7: request nibble */
502 set_pins(BPP_PP_nSelectIn|BPP_PP_nStrobe, minor);
503
504 /* Wait for event 9: Peripher strobes first nibble */
505 pins = wait_for(0, BPP_GP_nAck, TIME_PResponse, minor);
506 if (rc == -1) return -ETIMEDOUT;
507
508 /* Event 10: I handshake nibble */
509 set_pins(BPP_PP_nSelectIn|BPP_PP_nStrobe|BPP_PP_nAutoFd, minor);
510 if (pins & BPP_GP_nFault) byte |= 0x10;
511 if (pins & BPP_GP_Select) byte |= 0x20;
512 if (pins & BPP_GP_PError) byte |= 0x40;
513 if (pins & BPP_GP_Busy) byte |= 0x80;
514
515 if (put_user(byte, c))
516 return -EFAULT;
517 c += 1;
518 remaining -= 1;
519
520 /* Wait for event 11: Peripheral handshakes nibble */
521 rc = wait_for(BPP_GP_nAck, 0, TIME_PResponse, minor);
522 if (rc == -1) return -EIO;
523 }
524
525 return cnt - remaining;
526}
527
528static long read_ecp(unsigned minor, char __user *c, unsigned long cnt)
529{
530 unsigned long remaining;
531 long rc;
532
533 /* Turn ECP mode from forward to reverse if needed. */
534 if (! instances[minor].direction) {
535 unsigned short pins = get_pins(minor);
536
537 /* Event 38: Turn the bus around */
538 instances[minor].direction = 0x20;
539 pins &= ~BPP_PP_nAutoFd;
540 set_pins(pins, minor);
541
542 /* Event 39: Set pins for reverse mode. */
543 snooze(TIME_PSetup, minor);
544 set_pins(BPP_PP_nStrobe|BPP_PP_nSelectIn, minor);
545
546 /* Wait for event 40: Peripheral ready to be strobed */
547 rc = wait_for(0, BPP_GP_PError, TIME_PResponse, minor);
548 if (rc == -1) return -ETIMEDOUT;
549 }
550
551 remaining = cnt;
552
553 while (remaining > 0) {
554
555 /* If there is a run length for a repeated byte, repeat */
556 /* that byte a few times. */
557 if (instances[minor].run_length && !instances[minor].run_flag) {
558
559 char buffer[128];
560 unsigned idx;
561 unsigned repeat = remaining < instances[minor].run_length
562 ? remaining
563 : instances[minor].run_length;
564
565 for (idx = 0 ; idx < repeat ; idx += 1)
566 buffer[idx] = instances[minor].repeat_byte;
567
568 if (copy_to_user(c, buffer, repeat))
569 return -EFAULT;
570 remaining -= repeat;
571 c += repeat;
572 instances[minor].run_length -= repeat;
573 }
574
575 if (remaining == 0) break;
576
577
578 /* Wait for Event 43: Data active on the bus. */
579 rc = wait_for(0, BPP_GP_nAck, TIME_IDLE_LIMIT, minor);
580 if (rc == -1) break;
581
582 if (rc & BPP_GP_Busy) {
583 /* OK, this is data. read it in. */
584 unsigned char byte = bpp_inb(base_addrs[minor]);
585 if (put_user(byte, c))
586 return -EFAULT;
587 c += 1;
588 remaining -= 1;
589
590 if (instances[minor].run_flag) {
591 instances[minor].repeat_byte = byte;
592 instances[minor].run_flag = 0;
593 }
594
595 } else {
596 unsigned char byte = bpp_inb(base_addrs[minor]);
597 if (byte & 0x80) {
598 printk("bpp%d: "
599 "Ignoring ECP channel %u from device.\n",
600 minor, byte & 0x7f);
601 } else {
602 instances[minor].run_length = byte;
603 instances[minor].run_flag = 1;
604 }
605 }
606
607 /* Event 44: I got it. */
608 set_pins(BPP_PP_nStrobe|BPP_PP_nAutoFd|BPP_PP_nSelectIn, minor);
609
610 /* Wait for event 45: peripheral handshake */
611 rc = wait_for(BPP_GP_nAck, 0, TIME_PResponse, minor);
612 if (rc == -1) return -ETIMEDOUT;
613
614 /* Event 46: Finish handshake */
615 set_pins(BPP_PP_nStrobe|BPP_PP_nSelectIn, minor);
616
617 }
618
619
620 return cnt - remaining;
621}
622
623static ssize_t bpp_read(struct file *f, char __user *c, size_t cnt, loff_t * ppos)
624{
625 long rc;
626 unsigned minor = iminor(f->f_path.dentry->d_inode);
627 if (minor >= BPP_NO) return -ENODEV;
628 if (!instances[minor].present) return -ENODEV;
629
630 switch (instances[minor].mode) {
631
632 default:
633 if (instances[minor].mode != COMPATIBILITY)
634 terminate(minor);
635
636 if (instances[minor].enhanced) {
637 /* For now, do all reads with ECP-RLE mode */
638 unsigned short pins;
639
640 rc = negotiate(DEFAULT_ECP, minor);
641 if (rc < 0) break;
642
643 instances[minor].mode = ECP_RLE;
644
645 /* Event 30: set nAutoFd low to setup for ECP mode */
646 pins = get_pins(minor);
647 pins &= ~BPP_PP_nAutoFd;
648 set_pins(pins, minor);
649
650 /* Wait for Event 31: peripheral ready */
651 rc = wait_for(BPP_GP_PError, 0, TIME_PResponse, minor);
652 if (rc == -1) return -ETIMEDOUT;
653
654 rc = read_ecp(minor, c, cnt);
655
656 } else {
657 rc = negotiate(DEFAULT_NIBBLE, minor);
658 if (rc < 0) break;
659
660 instances[minor].mode = NIBBLE;
661
662 rc = read_nibble(minor, c, cnt);
663 }
664 break;
665
666 case NIBBLE:
667 rc = read_nibble(minor, c, cnt);
668 break;
669
670 case ECP:
671 case ECP_RLE:
672 rc = read_ecp(minor, c, cnt);
673 break;
674
675 }
676
677
678 return rc;
679}
680
681/*
682 * Compatibility mode handshaking is a matter of writing data,
683 * strobing it, and waiting for the printer to stop being busy.
684 */
685static long write_compat(unsigned minor, const char __user *c, unsigned long cnt)
686{
687 long rc;
688 unsigned short pins = get_pins(minor);
689
690 unsigned long remaining = cnt;
691
692
693 while (remaining > 0) {
694 unsigned char byte;
695
696 if (get_user(byte, c))
697 return -EFAULT;
698 c += 1;
699
700 rc = wait_for(BPP_GP_nAck, BPP_GP_Busy, TIME_IDLE_LIMIT, minor);
701 if (rc == -1) return -ETIMEDOUT;
702
703 bpp_outb_p(byte, base_addrs[minor]);
704 remaining -= 1;
705 /* snooze(1, minor); */
706
707 pins &= ~BPP_PP_nStrobe;
708 set_pins(pins, minor);
709
710 rc = wait_for(BPP_GP_Busy, 0, TIME_PResponse, minor);
711
712 pins |= BPP_PP_nStrobe;
713 set_pins(pins, minor);
714 }
715
716 return cnt - remaining;
717}
718
719/*
720 * Write data using ECP mode. Watch out that the port may be set up
721 * for reading. If so, turn the port around.
722 */
723static long write_ecp(unsigned minor, const char __user *c, unsigned long cnt)
724{
725 unsigned short pins = get_pins(minor);
726 unsigned long remaining = cnt;
727
728 if (instances[minor].direction) {
729 int rc;
730
731 /* Event 47 Request bus be turned around */
732 pins |= BPP_PP_nInit;
733 set_pins(pins, minor);
734
735 /* Wait for Event 49: Peripheral relinquished bus */
736 rc = wait_for(BPP_GP_PError, 0, TIME_PResponse, minor);
737
738 pins |= BPP_PP_nAutoFd;
739 instances[minor].direction = 0;
740 set_pins(pins, minor);
741 }
742
743 while (remaining > 0) {
744 unsigned char byte;
745 int rc;
746
747 if (get_user(byte, c))
748 return -EFAULT;
749
750 rc = wait_for(0, BPP_GP_Busy, TIME_PResponse, minor);
751 if (rc == -1) return -ETIMEDOUT;
752
753 c += 1;
754
755 bpp_outb_p(byte, base_addrs[minor]);
756
757 pins &= ~BPP_PP_nStrobe;
758 set_pins(pins, minor);
759
760 pins |= BPP_PP_nStrobe;
761 rc = wait_for(BPP_GP_Busy, 0, TIME_PResponse, minor);
762 if (rc == -1) return -EIO;
763
764 set_pins(pins, minor);
765 }
766
767 return cnt - remaining;
768}
769
770/*
771 * Write to the peripheral. Be sensitive of the current mode. If I'm
772 * in a mode that can be turned around (ECP) then just do
773 * that. Otherwise, terminate and do my writing in compat mode. This
774 * is the safest course as any device can handle it.
775 */
776static ssize_t bpp_write(struct file *f, const char __user *c, size_t cnt, loff_t * ppos)
777{
778 long errno = 0;
779 unsigned minor = iminor(f->f_path.dentry->d_inode);
780 if (minor >= BPP_NO) return -ENODEV;
781 if (!instances[minor].present) return -ENODEV;
782
783 switch (instances[minor].mode) {
784
785 case ECP:
786 case ECP_RLE:
787 errno = write_ecp(minor, c, cnt);
788 break;
789 case COMPATIBILITY:
790 errno = write_compat(minor, c, cnt);
791 break;
792 default:
793 terminate(minor);
794 errno = write_compat(minor, c, cnt);
795 }
796
797 return errno;
798}
799
800static int bpp_ioctl(struct inode *inode, struct file *f, unsigned int cmd,
801 unsigned long arg)
802{
803 int errno = 0;
804
805 unsigned minor = iminor(inode);
806 if (minor >= BPP_NO) return -ENODEV;
807 if (!instances[minor].present) return -ENODEV;
808
809
810 switch (cmd) {
811
812 case BPP_PUT_PINS:
813 set_pins(arg, minor);
814 break;
815
816 case BPP_GET_PINS:
817 errno = get_pins(minor);
818 break;
819
820 case BPP_PUT_DATA:
821 bpp_outb_p(arg, base_addrs[minor]);
822 break;
823
824 case BPP_GET_DATA:
825 errno = bpp_inb_p(base_addrs[minor]);
826 break;
827
828 case BPP_SET_INPUT:
829 if (arg)
830 if (instances[minor].enhanced) {
831 unsigned short bits = get_pins(minor);
832 instances[minor].direction = 0x20;
833 set_pins(bits, minor);
834 } else {
835 errno = -ENOTTY;
836 }
837 else {
838 unsigned short bits = get_pins(minor);
839 instances[minor].direction = 0x00;
840 set_pins(bits, minor);
841 }
842 break;
843
844 default:
845 errno = -EINVAL;
846 }
847
848 return errno;
849}
850
851static const struct file_operations bpp_fops = {
852 .owner = THIS_MODULE,
853 .read = bpp_read,
854 .write = bpp_write,
855 .ioctl = bpp_ioctl,
856 .open = bpp_open,
857 .release = bpp_release,
858};
859
860#if defined(__i386__)
861
862#define collectLptPorts() {}
863
864static void probeLptPort(unsigned idx)
865{
866 unsigned int testvalue;
867 const unsigned short lpAddr = base_addrs[idx];
868
869 instances[idx].present = 0;
870 instances[idx].enhanced = 0;
871 instances[idx].direction = 0;
872 instances[idx].mode = COMPATIBILITY;
873 instances[idx].run_length = 0;
874 instances[idx].run_flag = 0;
875 if (!request_region(lpAddr,3, bpp_dev_name)) return;
876
877 /*
878 * First, make sure the instance exists. Do this by writing to
879 * the data latch and reading the value back. If the port *is*
880 * present, test to see if it supports extended-mode
881 * operation. This will be required for IEEE1284 reverse
882 * transfers.
883 */
884
885 outb_p(BPP_PROBE_CODE, lpAddr);
886 for (testvalue=0; testvalue<BPP_DELAY; testvalue++)
887 ;
888 testvalue = inb_p(lpAddr);
889 if (testvalue == BPP_PROBE_CODE) {
890 unsigned save;
891 instances[idx].present = 1;
892
893 save = inb_p(lpAddr+2);
894 for (testvalue=0; testvalue<BPP_DELAY; testvalue++)
895 ;
896 outb_p(save|0x20, lpAddr+2);
897 for (testvalue=0; testvalue<BPP_DELAY; testvalue++)
898 ;
899 outb_p(~BPP_PROBE_CODE, lpAddr);
900 for (testvalue=0; testvalue<BPP_DELAY; testvalue++)
901 ;
902 testvalue = inb_p(lpAddr);
903 if ((testvalue&0xff) == (0xff&~BPP_PROBE_CODE))
904 instances[idx].enhanced = 0;
905 else
906 instances[idx].enhanced = 1;
907 outb_p(save, lpAddr+2);
908 }
909 else {
910 release_region(lpAddr,3);
911 }
912 /*
913 * Leave the port in compat idle mode.
914 */
915 set_pins(BPP_PP_nAutoFd|BPP_PP_nStrobe|BPP_PP_nInit, idx);
916
917 printk("bpp%d: Port at 0x%03x: Enhanced mode %s\n", idx, base_addrs[idx],
918 instances[idx].enhanced? "SUPPORTED" : "UNAVAILABLE");
919}
920
921static inline void freeLptPort(int idx)
922{
923 release_region(base_addrs[idx], 3);
924}
925
926#endif
927
928#if defined(__sparc__)
929
930static void __iomem *map_bpp(struct sbus_dev *dev, int idx)
931{
932 return sbus_ioremap(&dev->resource[0], 0, BPP_SIZE, "bpp");
933}
934
935static int collectLptPorts(void)
936{
937 struct sbus_bus *bus;
938 struct sbus_dev *dev;
939 int count;
940
941 count = 0;
942 for_all_sbusdev(dev, bus) {
943 if (strcmp(dev->prom_name, "SUNW,bpp") == 0) {
944 if (count >= BPP_NO) {
945 printk(KERN_NOTICE
946 "bpp: More than %d bpp ports,"
947 " rest is ignored\n", BPP_NO);
948 return count;
949 }
950 base_addrs[count] = map_bpp(dev, count);
951 count++;
952 }
953 }
954 return count;
955}
956
957static void probeLptPort(unsigned idx)
958{
959 void __iomem *rp = base_addrs[idx];
960 __u32 csr;
961 char *brand;
962
963 instances[idx].present = 0;
964 instances[idx].enhanced = 0;
965 instances[idx].direction = 0;
966 instances[idx].mode = COMPATIBILITY;
967 instances[idx].run_length = 0;
968 instances[idx].run_flag = 0;
969
970 if (!rp) return;
971
972 instances[idx].present = 1;
973 instances[idx].enhanced = 1; /* Sure */
974
975 csr = sbus_readl(rp + BPP_CSR);
976 if ((csr & P_DRAINING) != 0 && (csr & P_ERR_PEND) == 0) {
977 udelay(20);
978 csr = sbus_readl(rp + BPP_CSR);
979 if ((csr & P_DRAINING) != 0 && (csr & P_ERR_PEND) == 0) {
980 printk("bpp%d: DRAINING still active (0x%08x)\n", idx, csr);
981 }
982 }
983 printk("bpp%d: reset with 0x%08x ..", idx, csr);
984 sbus_writel((csr | P_RESET) & ~P_INT_EN, rp + BPP_CSR);
985 udelay(500);
986 sbus_writel(sbus_readl(rp + BPP_CSR) & ~P_RESET, rp + BPP_CSR);
987 csr = sbus_readl(rp + BPP_CSR);
988 printk(" done with csr=0x%08x ocr=0x%04x\n",
989 csr, sbus_readw(rp + BPP_OCR));
990
991 switch (csr & P_DEV_ID_MASK) {
992 case P_DEV_ID_ZEBRA:
993 brand = "Zebra";
994 break;
995 case P_DEV_ID_L64854:
996 brand = "DMA2";
997 break;
998 default:
999 brand = "Unknown";
1000 }
1001 printk("bpp%d: %s at %p\n", idx, brand, rp);
1002
1003 /*
1004 * Leave the port in compat idle mode.
1005 */
1006 set_pins(BPP_PP_nAutoFd|BPP_PP_nStrobe|BPP_PP_nInit, idx);
1007
1008 return;
1009}
1010
1011static inline void freeLptPort(int idx)
1012{
1013 sbus_iounmap(base_addrs[idx], BPP_SIZE);
1014}
1015
1016#endif
1017
1018static int __init bpp_init(void)
1019{
1020 int rc;
1021 unsigned idx;
1022
1023 rc = collectLptPorts();
1024 if (rc == 0)
1025 return -ENODEV;
1026
1027 rc = register_chrdev(BPP_MAJOR, bpp_dev_name, &bpp_fops);
1028 if (rc < 0)
1029 return rc;
1030
1031 for (idx = 0; idx < BPP_NO; idx++) {
1032 instances[idx].opened = 0;
1033 probeLptPort(idx);
1034 }
1035
1036 return 0;
1037}
1038
1039static void __exit bpp_cleanup(void)
1040{
1041 unsigned idx;
1042
1043 unregister_chrdev(BPP_MAJOR, bpp_dev_name);
1044
1045 for (idx = 0; idx < BPP_NO; idx++) {
1046 if (instances[idx].present)
1047 freeLptPort(idx);
1048 }
1049}
1050
1051module_init(bpp_init);
1052module_exit(bpp_cleanup);
1053
1054MODULE_LICENSE("GPL");
1055