1 /* parport_sunbpp.c: Parallel-port routines for SBUS
 
   3  * Author: Derrick J. Brashear <shadow@dementia.org>
 
   6  *          Phil Blundell <philb@gnu.org>
 
   7  *          Tim Waugh <tim@cyberelk.demon.co.uk>
 
   8  *          Jose Renau <renau@acm.org>
 
   9  *          David Campbell <campbell@tirian.che.curtin.edu.au>
 
  10  *          Grant Guenther <grant@torque.net>
 
  11  *          Eddie C. Dost <ecd@skynet.be>
 
  12  *          Stephen Williams (steve@icarus.com)
 
  13  *          Gus Baldauf (gbaldauf@ix.netcom.com)
 
  17  * Updated to new SBUS device framework: David S. Miller <davem@davemloft.net>
 
  21 #include <linux/string.h>
 
  22 #include <linux/module.h>
 
  23 #include <linux/delay.h>
 
  24 #include <linux/errno.h>
 
  25 #include <linux/ioport.h>
 
  26 #include <linux/kernel.h>
 
  27 #include <linux/slab.h>
 
  28 #include <linux/init.h>
 
  30 #include <linux/parport.h>
 
  32 #include <asm/ptrace.h>
 
  33 #include <linux/interrupt.h>
 
  36 #include <asm/oplib.h>           /* OpenProm Library */
 
  38 #include <asm/dma.h>             /* BPP uses LSI 64854 for DMA */
 
  40 #include <asm/sunbpp.h>
 
  44 #define dprintk(x) printk x
 
  49 static void parport_sunbpp_disable_irq(struct parport *p)
 
  51         struct bpp_regs __iomem *regs = (struct bpp_regs __iomem *)p->base;
 
  54         tmp = sbus_readl(®s->p_csr);
 
  56         sbus_writel(tmp, ®s->p_csr);
 
  59 static void parport_sunbpp_enable_irq(struct parport *p)
 
  61         struct bpp_regs __iomem *regs = (struct bpp_regs __iomem *)p->base;
 
  64         tmp = sbus_readl(®s->p_csr);
 
  66         sbus_writel(tmp, ®s->p_csr);
 
  69 static void parport_sunbpp_write_data(struct parport *p, unsigned char d)
 
  71         struct bpp_regs __iomem *regs = (struct bpp_regs __iomem *)p->base;
 
  73         sbus_writeb(d, ®s->p_dr);
 
  74         dprintk((KERN_DEBUG "wrote 0x%x\n", d));
 
  77 static unsigned char parport_sunbpp_read_data(struct parport *p)
 
  79         struct bpp_regs __iomem *regs = (struct bpp_regs __iomem *)p->base;
 
  81         return sbus_readb(®s->p_dr);
 
  85 static void control_pc_to_sunbpp(struct parport *p, unsigned char status)
 
  87         struct bpp_regs __iomem *regs = (struct bpp_regs __iomem *)p->base;
 
  88         unsigned char value_tcr = sbus_readb(®s->p_tcr);
 
  89         unsigned char value_or = sbus_readb(®s->p_or);
 
  91         if (status & PARPORT_CONTROL_STROBE) 
 
  92                 value_tcr |= P_TCR_DS;
 
  93         if (status & PARPORT_CONTROL_AUTOFD) 
 
  94                 value_or |= P_OR_AFXN;
 
  95         if (status & PARPORT_CONTROL_INIT) 
 
  96                 value_or |= P_OR_INIT;
 
  97         if (status & PARPORT_CONTROL_SELECT) 
 
  98                 value_or |= P_OR_SLCT_IN;
 
 100         sbus_writeb(value_or, ®s->p_or);
 
 101         sbus_writeb(value_tcr, ®s->p_tcr);
 
 105 static unsigned char status_sunbpp_to_pc(struct parport *p)
 
 107         struct bpp_regs __iomem *regs = (struct bpp_regs __iomem *)p->base;
 
 108         unsigned char bits = 0;
 
 109         unsigned char value_tcr = sbus_readb(®s->p_tcr);
 
 110         unsigned char value_ir = sbus_readb(®s->p_ir);
 
 112         if (!(value_ir & P_IR_ERR))
 
 113                 bits |= PARPORT_STATUS_ERROR;
 
 114         if (!(value_ir & P_IR_SLCT))
 
 115                 bits |= PARPORT_STATUS_SELECT;
 
 116         if (!(value_ir & P_IR_PE))
 
 117                 bits |= PARPORT_STATUS_PAPEROUT;
 
 118         if (value_tcr & P_TCR_ACK)
 
 119                 bits |= PARPORT_STATUS_ACK;
 
 120         if (!(value_tcr & P_TCR_BUSY))
 
 121                 bits |= PARPORT_STATUS_BUSY;
 
 123         dprintk((KERN_DEBUG "tcr 0x%x ir 0x%x\n", value_tcr, value_ir));
 
 124         dprintk((KERN_DEBUG "read status 0x%x\n", bits));
 
 128 static unsigned char control_sunbpp_to_pc(struct parport *p)
 
 130         struct bpp_regs __iomem *regs = (struct bpp_regs __iomem *)p->base;
 
 131         unsigned char bits = 0;
 
 132         unsigned char value_tcr = sbus_readb(®s->p_tcr);
 
 133         unsigned char value_or = sbus_readb(®s->p_or);
 
 135         if (!(value_tcr & P_TCR_DS))
 
 136                 bits |= PARPORT_CONTROL_STROBE;
 
 137         if (!(value_or & P_OR_AFXN))
 
 138                 bits |= PARPORT_CONTROL_AUTOFD;
 
 139         if (!(value_or & P_OR_INIT))
 
 140                 bits |= PARPORT_CONTROL_INIT;
 
 141         if (value_or & P_OR_SLCT_IN)
 
 142                 bits |= PARPORT_CONTROL_SELECT;
 
 144         dprintk((KERN_DEBUG "tcr 0x%x or 0x%x\n", value_tcr, value_or));
 
 145         dprintk((KERN_DEBUG "read control 0x%x\n", bits));
 
 149 static unsigned char parport_sunbpp_read_control(struct parport *p)
 
 151         return control_sunbpp_to_pc(p);
 
 154 static unsigned char parport_sunbpp_frob_control(struct parport *p,
 
 158         struct bpp_regs __iomem *regs = (struct bpp_regs __iomem *)p->base;
 
 159         unsigned char value_tcr = sbus_readb(®s->p_tcr);
 
 160         unsigned char value_or = sbus_readb(®s->p_or);
 
 162         dprintk((KERN_DEBUG "frob1: tcr 0x%x or 0x%x\n",
 
 163                  value_tcr, value_or));
 
 164         if (mask & PARPORT_CONTROL_STROBE) {
 
 165                 if (val & PARPORT_CONTROL_STROBE) {
 
 166                         value_tcr &= ~P_TCR_DS;
 
 168                         value_tcr |= P_TCR_DS;
 
 171         if (mask & PARPORT_CONTROL_AUTOFD) {
 
 172                 if (val & PARPORT_CONTROL_AUTOFD) {
 
 173                         value_or &= ~P_OR_AFXN;
 
 175                         value_or |= P_OR_AFXN;
 
 178         if (mask & PARPORT_CONTROL_INIT) {
 
 179                 if (val & PARPORT_CONTROL_INIT) {
 
 180                         value_or &= ~P_OR_INIT;
 
 182                         value_or |= P_OR_INIT;
 
 185         if (mask & PARPORT_CONTROL_SELECT) {
 
 186                 if (val & PARPORT_CONTROL_SELECT) {
 
 187                         value_or |= P_OR_SLCT_IN;
 
 189                         value_or &= ~P_OR_SLCT_IN;
 
 193         sbus_writeb(value_or, ®s->p_or);
 
 194         sbus_writeb(value_tcr, ®s->p_tcr);
 
 195         dprintk((KERN_DEBUG "frob2: tcr 0x%x or 0x%x\n",
 
 196                  value_tcr, value_or));
 
 197         return parport_sunbpp_read_control(p);
 
 200 static void parport_sunbpp_write_control(struct parport *p, unsigned char d)
 
 202         const unsigned char wm = (PARPORT_CONTROL_STROBE |
 
 203                                   PARPORT_CONTROL_AUTOFD |
 
 204                                   PARPORT_CONTROL_INIT |
 
 205                                   PARPORT_CONTROL_SELECT);
 
 207         parport_sunbpp_frob_control (p, wm, d & wm);
 
 210 static unsigned char parport_sunbpp_read_status(struct parport *p)
 
 212         return status_sunbpp_to_pc(p);
 
 215 static void parport_sunbpp_data_forward (struct parport *p)
 
 217         struct bpp_regs __iomem *regs = (struct bpp_regs __iomem *)p->base;
 
 218         unsigned char value_tcr = sbus_readb(®s->p_tcr);
 
 220         dprintk((KERN_DEBUG "forward\n"));
 
 221         value_tcr &= ~P_TCR_DIR;
 
 222         sbus_writeb(value_tcr, ®s->p_tcr);
 
 225 static void parport_sunbpp_data_reverse (struct parport *p)
 
 227         struct bpp_regs __iomem *regs = (struct bpp_regs __iomem *)p->base;
 
 228         u8 val = sbus_readb(®s->p_tcr);
 
 230         dprintk((KERN_DEBUG "reverse\n"));
 
 232         sbus_writeb(val, ®s->p_tcr);
 
 235 static void parport_sunbpp_init_state(struct pardevice *dev, struct parport_state *s)
 
 241 static void parport_sunbpp_save_state(struct parport *p, struct parport_state *s)
 
 243         s->u.pc.ctr = parport_sunbpp_read_control(p);
 
 246 static void parport_sunbpp_restore_state(struct parport *p, struct parport_state *s)
 
 248         parport_sunbpp_write_control(p, s->u.pc.ctr);
 
 251 static struct parport_operations parport_sunbpp_ops = 
 
 253         .write_data     = parport_sunbpp_write_data,
 
 254         .read_data      = parport_sunbpp_read_data,
 
 256         .write_control  = parport_sunbpp_write_control,
 
 257         .read_control   = parport_sunbpp_read_control,
 
 258         .frob_control   = parport_sunbpp_frob_control,
 
 260         .read_status    = parport_sunbpp_read_status,
 
 262         .enable_irq     = parport_sunbpp_enable_irq,
 
 263         .disable_irq    = parport_sunbpp_disable_irq,
 
 265         .data_forward   = parport_sunbpp_data_forward,
 
 266         .data_reverse   = parport_sunbpp_data_reverse,
 
 268         .init_state     = parport_sunbpp_init_state,
 
 269         .save_state     = parport_sunbpp_save_state,
 
 270         .restore_state  = parport_sunbpp_restore_state,
 
 272         .epp_write_data = parport_ieee1284_epp_write_data,
 
 273         .epp_read_data  = parport_ieee1284_epp_read_data,
 
 274         .epp_write_addr = parport_ieee1284_epp_write_addr,
 
 275         .epp_read_addr  = parport_ieee1284_epp_read_addr,
 
 277         .ecp_write_data = parport_ieee1284_ecp_write_data,
 
 278         .ecp_read_data  = parport_ieee1284_ecp_read_data,
 
 279         .ecp_write_addr = parport_ieee1284_ecp_write_addr,
 
 281         .compat_write_data      = parport_ieee1284_write_compat,
 
 282         .nibble_read_data       = parport_ieee1284_read_nibble,
 
 283         .byte_read_data         = parport_ieee1284_read_byte,
 
 285         .owner          = THIS_MODULE,
 
 288 static int __devinit init_one_port(struct sbus_dev *sdev)
 
 291         /* at least in theory there may be a "we don't dma" case */
 
 292         struct parport_operations *ops;
 
 294         int irq, dma, err = 0, size;
 
 295         struct bpp_regs __iomem *regs;
 
 296         unsigned char value_tcr;
 
 299         base = sbus_ioremap(&sdev->resource[0], 0,
 
 300                             sdev->reg_addrs[0].reg_size, 
 
 305         size = sdev->reg_addrs[0].reg_size;
 
 306         dma = PARPORT_DMA_NONE;
 
 308         ops = kmalloc(sizeof(struct parport_operations), GFP_KERNEL);
 
 312         memcpy (ops, &parport_sunbpp_ops, sizeof (struct parport_operations));
 
 314         dprintk(("register_port\n"));
 
 315         if (!(p = parport_register_port((unsigned long)base, irq, dma, ops)))
 
 319         p->dev = &sdev->ofdev.dev;
 
 321         if ((err = request_irq(p->irq, parport_irq_handler,
 
 322                                IRQF_SHARED, p->name, p)) != 0) {
 
 326         parport_sunbpp_enable_irq(p);
 
 328         regs = (struct bpp_regs __iomem *)p->base;
 
 330         value_tcr = sbus_readb(®s->p_tcr);
 
 331         value_tcr &= ~P_TCR_DIR;
 
 332         sbus_writeb(value_tcr, ®s->p_tcr);
 
 334         printk(KERN_INFO "%s: sunbpp at 0x%lx\n", p->name, p->base);
 
 336         dev_set_drvdata(&sdev->ofdev.dev, p);
 
 338         parport_announce_port(p);
 
 349         sbus_iounmap(base, size);
 
 354 static int __devinit bpp_probe(struct of_device *dev, const struct of_device_id *match)
 
 356         struct sbus_dev *sdev = to_sbus_device(&dev->dev);
 
 358         return init_one_port(sdev);
 
 361 static int __devexit bpp_remove(struct of_device *dev)
 
 363         struct parport *p = dev_get_drvdata(&dev->dev);
 
 364         struct parport_operations *ops = p->ops;
 
 366         parport_remove_port(p);
 
 368         if (p->irq != PARPORT_IRQ_NONE) {
 
 369                 parport_sunbpp_disable_irq(p);
 
 373         sbus_iounmap((void __iomem *) p->base, p->size);
 
 377         dev_set_drvdata(&dev->dev, NULL);
 
 382 static struct of_device_id bpp_match[] = {
 
 389 MODULE_DEVICE_TABLE(of, bpp_match);
 
 391 static struct of_platform_driver bpp_sbus_driver = {
 
 393         .match_table    = bpp_match,
 
 395         .remove         = __devexit_p(bpp_remove),
 
 398 static int __init parport_sunbpp_init(void)
 
 400         return of_register_driver(&bpp_sbus_driver, &sbus_bus_type);
 
 403 static void __exit parport_sunbpp_exit(void)
 
 405         of_unregister_driver(&bpp_sbus_driver);
 
 408 MODULE_AUTHOR("Derrick J Brashear");
 
 409 MODULE_DESCRIPTION("Parport Driver for Sparc bidirectional Port");
 
 410 MODULE_SUPPORTED_DEVICE("Sparc Bidirectional Parallel Port");
 
 411 MODULE_VERSION("2.0");
 
 412 MODULE_LICENSE("GPL");
 
 414 module_init(parport_sunbpp_init)
 
 415 module_exit(parport_sunbpp_exit)