root/drivers/parport/parport_sunbpp.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. parport_sunbpp_disable_irq
  2. parport_sunbpp_enable_irq
  3. parport_sunbpp_write_data
  4. parport_sunbpp_read_data
  5. status_sunbpp_to_pc
  6. control_sunbpp_to_pc
  7. parport_sunbpp_read_control
  8. parport_sunbpp_frob_control
  9. parport_sunbpp_write_control
  10. parport_sunbpp_read_status
  11. parport_sunbpp_data_forward
  12. parport_sunbpp_data_reverse
  13. parport_sunbpp_init_state
  14. parport_sunbpp_save_state
  15. parport_sunbpp_restore_state
  16. bpp_probe
  17. bpp_remove

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /* parport_sunbpp.c: Parallel-port routines for SBUS
   3  * 
   4  * Author: Derrick J. Brashear <shadow@dementia.org>
   5  *
   6  * based on work by:
   7  *          Phil Blundell <philb@gnu.org>
   8  *          Tim Waugh <tim@cyberelk.demon.co.uk>
   9  *          Jose Renau <renau@acm.org>
  10  *          David Campbell <campbell@tirian.che.curtin.edu.au>
  11  *          Grant Guenther <grant@torque.net>
  12  *          Eddie C. Dost <ecd@skynet.be>
  13  *          Stephen Williams (steve@icarus.com)
  14  *          Gus Baldauf (gbaldauf@ix.netcom.com)
  15  *          Peter Zaitcev
  16  *          Tom Dyas
  17  *
  18  * Updated to new SBUS device framework: David S. Miller <davem@davemloft.net>
  19  * 
  20  */
  21 
  22 #include <linux/string.h>
  23 #include <linux/module.h>
  24 #include <linux/delay.h>
  25 #include <linux/errno.h>
  26 #include <linux/ioport.h>
  27 #include <linux/kernel.h>
  28 #include <linux/slab.h>
  29 #include <linux/init.h>
  30 #include <linux/of.h>
  31 #include <linux/of_device.h>
  32 
  33 #include <linux/parport.h>
  34 
  35 #include <asm/ptrace.h>
  36 #include <linux/interrupt.h>
  37 
  38 #include <asm/io.h>
  39 #include <asm/oplib.h>           /* OpenProm Library */
  40 #include <asm/dma.h>             /* BPP uses LSI 64854 for DMA */
  41 #include <asm/irq.h>
  42 #include <asm/sunbpp.h>
  43 
  44 #undef __SUNBPP_DEBUG
  45 #ifdef __SUNBPP_DEBUG
  46 #define dprintk(x) printk x
  47 #else
  48 #define dprintk(x)
  49 #endif
  50 
  51 static void parport_sunbpp_disable_irq(struct parport *p)
  52 {
  53         struct bpp_regs __iomem *regs = (struct bpp_regs __iomem *)p->base;
  54         u32 tmp;
  55 
  56         tmp = sbus_readl(&regs->p_csr);
  57         tmp &= ~DMA_INT_ENAB;
  58         sbus_writel(tmp, &regs->p_csr);
  59 }
  60 
  61 static void parport_sunbpp_enable_irq(struct parport *p)
  62 {
  63         struct bpp_regs __iomem *regs = (struct bpp_regs __iomem *)p->base;
  64         u32 tmp;
  65 
  66         tmp = sbus_readl(&regs->p_csr);
  67         tmp |= DMA_INT_ENAB;
  68         sbus_writel(tmp, &regs->p_csr);
  69 }
  70 
  71 static void parport_sunbpp_write_data(struct parport *p, unsigned char d)
  72 {
  73         struct bpp_regs __iomem *regs = (struct bpp_regs __iomem *)p->base;
  74 
  75         sbus_writeb(d, &regs->p_dr);
  76         dprintk((KERN_DEBUG "wrote 0x%x\n", d));
  77 }
  78 
  79 static unsigned char parport_sunbpp_read_data(struct parport *p)
  80 {
  81         struct bpp_regs __iomem *regs = (struct bpp_regs __iomem *)p->base;
  82 
  83         return sbus_readb(&regs->p_dr);
  84 }
  85 
  86 static unsigned char status_sunbpp_to_pc(struct parport *p)
  87 {
  88         struct bpp_regs __iomem *regs = (struct bpp_regs __iomem *)p->base;
  89         unsigned char bits = 0;
  90         unsigned char value_tcr = sbus_readb(&regs->p_tcr);
  91         unsigned char value_ir = sbus_readb(&regs->p_ir);
  92 
  93         if (!(value_ir & P_IR_ERR))
  94                 bits |= PARPORT_STATUS_ERROR;
  95         if (!(value_ir & P_IR_SLCT))
  96                 bits |= PARPORT_STATUS_SELECT;
  97         if (!(value_ir & P_IR_PE))
  98                 bits |= PARPORT_STATUS_PAPEROUT;
  99         if (value_tcr & P_TCR_ACK)
 100                 bits |= PARPORT_STATUS_ACK;
 101         if (!(value_tcr & P_TCR_BUSY))
 102                 bits |= PARPORT_STATUS_BUSY;
 103 
 104         dprintk((KERN_DEBUG "tcr 0x%x ir 0x%x\n", value_tcr, value_ir));
 105         dprintk((KERN_DEBUG "read status 0x%x\n", bits));
 106         return bits;
 107 }
 108 
 109 static unsigned char control_sunbpp_to_pc(struct parport *p)
 110 {
 111         struct bpp_regs __iomem *regs = (struct bpp_regs __iomem *)p->base;
 112         unsigned char bits = 0;
 113         unsigned char value_tcr = sbus_readb(&regs->p_tcr);
 114         unsigned char value_or = sbus_readb(&regs->p_or);
 115 
 116         if (!(value_tcr & P_TCR_DS))
 117                 bits |= PARPORT_CONTROL_STROBE;
 118         if (!(value_or & P_OR_AFXN))
 119                 bits |= PARPORT_CONTROL_AUTOFD;
 120         if (!(value_or & P_OR_INIT))
 121                 bits |= PARPORT_CONTROL_INIT;
 122         if (value_or & P_OR_SLCT_IN)
 123                 bits |= PARPORT_CONTROL_SELECT;
 124 
 125         dprintk((KERN_DEBUG "tcr 0x%x or 0x%x\n", value_tcr, value_or));
 126         dprintk((KERN_DEBUG "read control 0x%x\n", bits));
 127         return bits;
 128 }
 129 
 130 static unsigned char parport_sunbpp_read_control(struct parport *p)
 131 {
 132         return control_sunbpp_to_pc(p);
 133 }
 134 
 135 static unsigned char parport_sunbpp_frob_control(struct parport *p,
 136                                                  unsigned char mask,
 137                                                  unsigned char val)
 138 {
 139         struct bpp_regs __iomem *regs = (struct bpp_regs __iomem *)p->base;
 140         unsigned char value_tcr = sbus_readb(&regs->p_tcr);
 141         unsigned char value_or = sbus_readb(&regs->p_or);
 142 
 143         dprintk((KERN_DEBUG "frob1: tcr 0x%x or 0x%x\n",
 144                  value_tcr, value_or));
 145         if (mask & PARPORT_CONTROL_STROBE) {
 146                 if (val & PARPORT_CONTROL_STROBE) {
 147                         value_tcr &= ~P_TCR_DS;
 148                 } else {
 149                         value_tcr |= P_TCR_DS;
 150                 }
 151         }
 152         if (mask & PARPORT_CONTROL_AUTOFD) {
 153                 if (val & PARPORT_CONTROL_AUTOFD) {
 154                         value_or &= ~P_OR_AFXN;
 155                 } else {
 156                         value_or |= P_OR_AFXN;
 157                 }
 158         }
 159         if (mask & PARPORT_CONTROL_INIT) {
 160                 if (val & PARPORT_CONTROL_INIT) {
 161                         value_or &= ~P_OR_INIT;
 162                 } else {
 163                         value_or |= P_OR_INIT;
 164                 }
 165         }
 166         if (mask & PARPORT_CONTROL_SELECT) {
 167                 if (val & PARPORT_CONTROL_SELECT) {
 168                         value_or |= P_OR_SLCT_IN;
 169                 } else {
 170                         value_or &= ~P_OR_SLCT_IN;
 171                 }
 172         }
 173 
 174         sbus_writeb(value_or, &regs->p_or);
 175         sbus_writeb(value_tcr, &regs->p_tcr);
 176         dprintk((KERN_DEBUG "frob2: tcr 0x%x or 0x%x\n",
 177                  value_tcr, value_or));
 178         return parport_sunbpp_read_control(p);
 179 }
 180 
 181 static void parport_sunbpp_write_control(struct parport *p, unsigned char d)
 182 {
 183         const unsigned char wm = (PARPORT_CONTROL_STROBE |
 184                                   PARPORT_CONTROL_AUTOFD |
 185                                   PARPORT_CONTROL_INIT |
 186                                   PARPORT_CONTROL_SELECT);
 187 
 188         parport_sunbpp_frob_control (p, wm, d & wm);
 189 }
 190 
 191 static unsigned char parport_sunbpp_read_status(struct parport *p)
 192 {
 193         return status_sunbpp_to_pc(p);
 194 }
 195 
 196 static void parport_sunbpp_data_forward (struct parport *p)
 197 {
 198         struct bpp_regs __iomem *regs = (struct bpp_regs __iomem *)p->base;
 199         unsigned char value_tcr = sbus_readb(&regs->p_tcr);
 200 
 201         dprintk((KERN_DEBUG "forward\n"));
 202         value_tcr &= ~P_TCR_DIR;
 203         sbus_writeb(value_tcr, &regs->p_tcr);
 204 }
 205 
 206 static void parport_sunbpp_data_reverse (struct parport *p)
 207 {
 208         struct bpp_regs __iomem *regs = (struct bpp_regs __iomem *)p->base;
 209         u8 val = sbus_readb(&regs->p_tcr);
 210 
 211         dprintk((KERN_DEBUG "reverse\n"));
 212         val |= P_TCR_DIR;
 213         sbus_writeb(val, &regs->p_tcr);
 214 }
 215 
 216 static void parport_sunbpp_init_state(struct pardevice *dev, struct parport_state *s)
 217 {
 218         s->u.pc.ctr = 0xc;
 219         s->u.pc.ecr = 0x0;
 220 }
 221 
 222 static void parport_sunbpp_save_state(struct parport *p, struct parport_state *s)
 223 {
 224         s->u.pc.ctr = parport_sunbpp_read_control(p);
 225 }
 226 
 227 static void parport_sunbpp_restore_state(struct parport *p, struct parport_state *s)
 228 {
 229         parport_sunbpp_write_control(p, s->u.pc.ctr);
 230 }
 231 
 232 static struct parport_operations parport_sunbpp_ops = 
 233 {
 234         .write_data     = parport_sunbpp_write_data,
 235         .read_data      = parport_sunbpp_read_data,
 236 
 237         .write_control  = parport_sunbpp_write_control,
 238         .read_control   = parport_sunbpp_read_control,
 239         .frob_control   = parport_sunbpp_frob_control,
 240 
 241         .read_status    = parport_sunbpp_read_status,
 242 
 243         .enable_irq     = parport_sunbpp_enable_irq,
 244         .disable_irq    = parport_sunbpp_disable_irq,
 245 
 246         .data_forward   = parport_sunbpp_data_forward,
 247         .data_reverse   = parport_sunbpp_data_reverse,
 248 
 249         .init_state     = parport_sunbpp_init_state,
 250         .save_state     = parport_sunbpp_save_state,
 251         .restore_state  = parport_sunbpp_restore_state,
 252 
 253         .epp_write_data = parport_ieee1284_epp_write_data,
 254         .epp_read_data  = parport_ieee1284_epp_read_data,
 255         .epp_write_addr = parport_ieee1284_epp_write_addr,
 256         .epp_read_addr  = parport_ieee1284_epp_read_addr,
 257 
 258         .ecp_write_data = parport_ieee1284_ecp_write_data,
 259         .ecp_read_data  = parport_ieee1284_ecp_read_data,
 260         .ecp_write_addr = parport_ieee1284_ecp_write_addr,
 261 
 262         .compat_write_data      = parport_ieee1284_write_compat,
 263         .nibble_read_data       = parport_ieee1284_read_nibble,
 264         .byte_read_data         = parport_ieee1284_read_byte,
 265 
 266         .owner          = THIS_MODULE,
 267 };
 268 
 269 static int bpp_probe(struct platform_device *op)
 270 {
 271         struct parport_operations *ops;
 272         struct bpp_regs __iomem *regs;
 273         int irq, dma, err = 0, size;
 274         unsigned char value_tcr;
 275         void __iomem *base;
 276         struct parport *p;
 277 
 278         irq = op->archdata.irqs[0];
 279         base = of_ioremap(&op->resource[0], 0,
 280                           resource_size(&op->resource[0]),
 281                           "sunbpp");
 282         if (!base)
 283                 return -ENODEV;
 284 
 285         size = resource_size(&op->resource[0]);
 286         dma = PARPORT_DMA_NONE;
 287 
 288         ops = kmemdup(&parport_sunbpp_ops, sizeof(struct parport_operations),
 289                       GFP_KERNEL);
 290         if (!ops) {
 291                 err = -ENOMEM;
 292                 goto out_unmap;
 293         }
 294 
 295         dprintk(("register_port\n"));
 296         if (!(p = parport_register_port((unsigned long)base, irq, dma, ops))) {
 297                 err = -ENOMEM;
 298                 goto out_free_ops;
 299         }
 300 
 301         p->size = size;
 302         p->dev = &op->dev;
 303 
 304         if ((err = request_irq(p->irq, parport_irq_handler,
 305                                IRQF_SHARED, p->name, p)) != 0) {
 306                 goto out_put_port;
 307         }
 308 
 309         parport_sunbpp_enable_irq(p);
 310 
 311         regs = (struct bpp_regs __iomem *)p->base;
 312 
 313         value_tcr = sbus_readb(&regs->p_tcr);
 314         value_tcr &= ~P_TCR_DIR;
 315         sbus_writeb(value_tcr, &regs->p_tcr);
 316 
 317         printk(KERN_INFO "%s: sunbpp at 0x%lx\n", p->name, p->base);
 318 
 319         dev_set_drvdata(&op->dev, p);
 320 
 321         parport_announce_port(p);
 322 
 323         return 0;
 324 
 325 out_put_port:
 326         parport_put_port(p);
 327 
 328 out_free_ops:
 329         kfree(ops);
 330 
 331 out_unmap:
 332         of_iounmap(&op->resource[0], base, size);
 333 
 334         return err;
 335 }
 336 
 337 static int bpp_remove(struct platform_device *op)
 338 {
 339         struct parport *p = dev_get_drvdata(&op->dev);
 340         struct parport_operations *ops = p->ops;
 341 
 342         parport_remove_port(p);
 343 
 344         if (p->irq != PARPORT_IRQ_NONE) {
 345                 parport_sunbpp_disable_irq(p);
 346                 free_irq(p->irq, p);
 347         }
 348 
 349         of_iounmap(&op->resource[0], (void __iomem *) p->base, p->size);
 350         parport_put_port(p);
 351         kfree(ops);
 352 
 353         dev_set_drvdata(&op->dev, NULL);
 354 
 355         return 0;
 356 }
 357 
 358 static const struct of_device_id bpp_match[] = {
 359         {
 360                 .name = "SUNW,bpp",
 361         },
 362         {},
 363 };
 364 
 365 MODULE_DEVICE_TABLE(of, bpp_match);
 366 
 367 static struct platform_driver bpp_sbus_driver = {
 368         .driver = {
 369                 .name = "bpp",
 370                 .of_match_table = bpp_match,
 371         },
 372         .probe          = bpp_probe,
 373         .remove         = bpp_remove,
 374 };
 375 
 376 module_platform_driver(bpp_sbus_driver);
 377 
 378 MODULE_AUTHOR("Derrick J Brashear");
 379 MODULE_DESCRIPTION("Parport Driver for Sparc bidirectional Port");
 380 MODULE_SUPPORTED_DEVICE("Sparc Bidirectional Parallel Port");
 381 MODULE_VERSION("2.0");
 382 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */