1 /* parport_sunbpp.c: Parallel-port routines for SBUS 2 * 3 * Author: Derrick J. Brashear <shadow@dementia.org> 4 * 5 * based on work by: 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) 14 * Peter Zaitcev 15 * Tom Dyas 16 * 17 * Updated to new SBUS device framework: David S. Miller <davem@davemloft.net> 18 * 19 */ 20 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> 29 30 #include <linux/parport.h> 31 32 #include <asm/ptrace.h> 33 #include <linux/interrupt.h> 34 35 #include <asm/io.h> 36 #include <asm/oplib.h> /* OpenProm Library */ 37 #include <asm/sbus.h> 38 #include <asm/dma.h> /* BPP uses LSI 64854 for DMA */ 39 #include <asm/irq.h> 40 #include <asm/sunbpp.h> 41 42 #undef __SUNBPP_DEBUG 43 #ifdef __SUNBPP_DEBUG 44 #define dprintk(x) printk x 45 #else 46 #define dprintk(x) 47 #endif 48 49 static irqreturn_t parport_sunbpp_interrupt(int irq, void *dev_id, struct pt_regs *regs) 50 { 51 parport_generic_irq(irq, (struct parport *) dev_id, regs); 52 return IRQ_HANDLED; 53 } 54 55 static void parport_sunbpp_disable_irq(struct parport *p) 56 { 57 struct bpp_regs __iomem *regs = (struct bpp_regs __iomem *)p->base; 58 u32 tmp; 59 60 tmp = sbus_readl(®s->p_csr); 61 tmp &= ~DMA_INT_ENAB; 62 sbus_writel(tmp, ®s->p_csr); 63 } 64 65 static void parport_sunbpp_enable_irq(struct parport *p) 66 { 67 struct bpp_regs __iomem *regs = (struct bpp_regs __iomem *)p->base; 68 u32 tmp; 69 70 tmp = sbus_readl(®s->p_csr); 71 tmp |= DMA_INT_ENAB; 72 sbus_writel(tmp, ®s->p_csr); 73 } 74 75 static void parport_sunbpp_write_data(struct parport *p, unsigned char d) 76 { 77 struct bpp_regs __iomem *regs = (struct bpp_regs __iomem *)p->base; 78 79 sbus_writeb(d, ®s->p_dr); 80 dprintk((KERN_DEBUG "wrote 0x%x\n", d)); 81 } 82 83 static unsigned char parport_sunbpp_read_data(struct parport *p) 84 { 85 struct bpp_regs __iomem *regs = (struct bpp_regs __iomem *)p->base; 86 87 return sbus_readb(®s->p_dr); 88 } 89 90 #if 0 91 static void control_pc_to_sunbpp(struct parport *p, unsigned char status) 92 { 93 struct bpp_regs __iomem *regs = (struct bpp_regs __iomem *)p->base; 94 unsigned char value_tcr = sbus_readb(®s->p_tcr); 95 unsigned char value_or = sbus_readb(®s->p_or); 96 97 if (status & PARPORT_CONTROL_STROBE) 98 value_tcr |= P_TCR_DS; 99 if (status & PARPORT_CONTROL_AUTOFD) 100 value_or |= P_OR_AFXN; 101 if (status & PARPORT_CONTROL_INIT) 102 value_or |= P_OR_INIT; 103 if (status & PARPORT_CONTROL_SELECT) 104 value_or |= P_OR_SLCT_IN; 105 106 sbus_writeb(value_or, ®s->p_or); 107 sbus_writeb(value_tcr, ®s->p_tcr); 108 } 109 #endif 110 111 static unsigned char status_sunbpp_to_pc(struct parport *p) 112 { 113 struct bpp_regs __iomem *regs = (struct bpp_regs __iomem *)p->base; 114 unsigned char bits = 0; 115 unsigned char value_tcr = sbus_readb(®s->p_tcr); 116 unsigned char value_ir = sbus_readb(®s->p_ir); 117 118 if (!(value_ir & P_IR_ERR)) 119 bits |= PARPORT_STATUS_ERROR; 120 if (!(value_ir & P_IR_SLCT)) 121 bits |= PARPORT_STATUS_SELECT; 122 if (!(value_ir & P_IR_PE)) 123 bits |= PARPORT_STATUS_PAPEROUT; 124 if (value_tcr & P_TCR_ACK) 125 bits |= PARPORT_STATUS_ACK; 126 if (!(value_tcr & P_TCR_BUSY)) 127 bits |= PARPORT_STATUS_BUSY; 128 129 dprintk((KERN_DEBUG "tcr 0x%x ir 0x%x\n", regs->p_tcr, regs->p_ir)); 130 dprintk((KERN_DEBUG "read status 0x%x\n", bits)); 131 return bits; 132 } 133 134 static unsigned char control_sunbpp_to_pc(struct parport *p) 135 { 136 struct bpp_regs __iomem *regs = (struct bpp_regs __iomem *)p->base; 137 unsigned char bits = 0; 138 unsigned char value_tcr = sbus_readb(®s->p_tcr); 139 unsigned char value_or = sbus_readb(®s->p_or); 140 141 if (!(value_tcr & P_TCR_DS)) 142 bits |= PARPORT_CONTROL_STROBE; 143 if (!(value_or & P_OR_AFXN)) 144 bits |= PARPORT_CONTROL_AUTOFD; 145 if (!(value_or & P_OR_INIT)) 146 bits |= PARPORT_CONTROL_INIT; 147 if (value_or & P_OR_SLCT_IN) 148 bits |= PARPORT_CONTROL_SELECT; 149 150 dprintk((KERN_DEBUG "tcr 0x%x or 0x%x\n", regs->p_tcr, regs->p_or)); 151 dprintk((KERN_DEBUG "read control 0x%x\n", bits)); 152 return bits; 153 } 154 155 static unsigned char parport_sunbpp_read_control(struct parport *p) 156 { 157 return control_sunbpp_to_pc(p); 158 } 159 160 static unsigned char parport_sunbpp_frob_control(struct parport *p, 161 unsigned char mask, 162 unsigned char val) 163 { 164 struct bpp_regs __iomem *regs = (struct bpp_regs __iomem *)p->base; 165 unsigned char value_tcr = sbus_readb(®s->p_tcr); 166 unsigned char value_or = sbus_readb(®s->p_or); 167 168 dprintk((KERN_DEBUG "frob1: tcr 0x%x or 0x%x\n", regs->p_tcr, regs->p_or)); 169 if (mask & PARPORT_CONTROL_STROBE) { 170 if (val & PARPORT_CONTROL_STROBE) { 171 value_tcr &= ~P_TCR_DS; 172 } else { 173 value_tcr |= P_TCR_DS; 174 } 175 } 176 if (mask & PARPORT_CONTROL_AUTOFD) { 177 if (val & PARPORT_CONTROL_AUTOFD) { 178 value_or &= ~P_OR_AFXN; 179 } else { 180 value_or |= P_OR_AFXN; 181 } 182 } 183 if (mask & PARPORT_CONTROL_INIT) { 184 if (val & PARPORT_CONTROL_INIT) { 185 value_or &= ~P_OR_INIT; 186 } else { 187 value_or |= P_OR_INIT; 188 } 189 } 190 if (mask & PARPORT_CONTROL_SELECT) { 191 if (val & PARPORT_CONTROL_SELECT) { 192 value_or |= P_OR_SLCT_IN; 193 } else { 194 value_or &= ~P_OR_SLCT_IN; 195 } 196 } 197 198 sbus_writeb(value_or, ®s->p_or); 199 sbus_writeb(value_tcr, ®s->p_tcr); 200 dprintk((KERN_DEBUG "frob2: tcr 0x%x or 0x%x\n", regs->p_tcr, regs->p_or)); 201 return parport_sunbpp_read_control(p); 202 } 203 204 static void parport_sunbpp_write_control(struct parport *p, unsigned char d) 205 { 206 const unsigned char wm = (PARPORT_CONTROL_STROBE | 207 PARPORT_CONTROL_AUTOFD | 208 PARPORT_CONTROL_INIT | 209 PARPORT_CONTROL_SELECT); 210 211 parport_sunbpp_frob_control (p, wm, d & wm); 212 } 213 214 static unsigned char parport_sunbpp_read_status(struct parport *p) 215 { 216 return status_sunbpp_to_pc(p); 217 } 218 219 static void parport_sunbpp_data_forward (struct parport *p) 220 { 221 struct bpp_regs __iomem *regs = (struct bpp_regs __iomem *)p->base; 222 unsigned char value_tcr = sbus_readb(®s->p_tcr); 223 224 dprintk((KERN_DEBUG "forward\n")); 225 value_tcr &= ~P_TCR_DIR; 226 sbus_writeb(value_tcr, ®s->p_tcr); 227 } 228 229 static void parport_sunbpp_data_reverse (struct parport *p) 230 { 231 struct bpp_regs __iomem *regs = (struct bpp_regs __iomem *)p->base; 232 u8 val = sbus_readb(®s->p_tcr); 233 234 dprintk((KERN_DEBUG "reverse\n")); 235 val |= P_TCR_DIR; 236 sbus_writeb(val, ®s->p_tcr); 237 } 238 239 static void parport_sunbpp_init_state(struct pardevice *dev, struct parport_state *s) 240 { 241 s->u.pc.ctr = 0xc; 242 s->u.pc.ecr = 0x0; 243 } 244 245 static void parport_sunbpp_save_state(struct parport *p, struct parport_state *s) 246 { 247 s->u.pc.ctr = parport_sunbpp_read_control(p); 248 } 249 250 static void parport_sunbpp_restore_state(struct parport *p, struct parport_state *s) 251 { 252 parport_sunbpp_write_control(p, s->u.pc.ctr); 253 } 254 255 static struct parport_operations parport_sunbpp_ops = 256 { 257 .write_data = parport_sunbpp_write_data, 258 .read_data = parport_sunbpp_read_data, 259 260 .write_control = parport_sunbpp_write_control, 261 .read_control = parport_sunbpp_read_control, 262 .frob_control = parport_sunbpp_frob_control, 263 264 .read_status = parport_sunbpp_read_status, 265 266 .enable_irq = parport_sunbpp_enable_irq, 267 .disable_irq = parport_sunbpp_disable_irq, 268 269 .data_forward = parport_sunbpp_data_forward, 270 .data_reverse = parport_sunbpp_data_reverse, 271 272 .init_state = parport_sunbpp_init_state, 273 .save_state = parport_sunbpp_save_state, 274 .restore_state = parport_sunbpp_restore_state, 275 276 .epp_write_data = parport_ieee1284_epp_write_data, 277 .epp_read_data = parport_ieee1284_epp_read_data, 278 .epp_write_addr = parport_ieee1284_epp_write_addr, 279 .epp_read_addr = parport_ieee1284_epp_read_addr, 280 281 .ecp_write_data = parport_ieee1284_ecp_write_data, 282 .ecp_read_data = parport_ieee1284_ecp_read_data, 283 .ecp_write_addr = parport_ieee1284_ecp_write_addr, 284 285 .compat_write_data = parport_ieee1284_write_compat, 286 .nibble_read_data = parport_ieee1284_read_nibble, 287 .byte_read_data = parport_ieee1284_read_byte, 288 289 .owner = THIS_MODULE, 290 }; 291 292 static int __devinit init_one_port(struct sbus_dev *sdev) 293 { 294 struct parport *p; 295 /* at least in theory there may be a "we don't dma" case */ 296 struct parport_operations *ops; 297 void __iomem *base; 298 int irq, dma, err = 0, size; 299 struct bpp_regs __iomem *regs; 300 unsigned char value_tcr; 301 302 irq = sdev->irqs[0]; 303 base = sbus_ioremap(&sdev->resource[0], 0, 304 sdev->reg_addrs[0].reg_size, 305 "sunbpp"); 306 if (!base) 307 return -ENODEV; 308 309 size = sdev->reg_addrs[0].reg_size; 310 dma = PARPORT_DMA_NONE; 311 312 ops = kmalloc(sizeof(struct parport_operations), GFP_KERNEL); 313 if (!ops) 314 goto out_unmap; 315 316 memcpy (ops, &parport_sunbpp_ops, sizeof (struct parport_operations)); 317 318 dprintk(("register_port\n")); 319 if (!(p = parport_register_port((unsigned long)base, irq, dma, ops))) 320 goto out_free_ops; 321 322 p->size = size; 323 324 if ((err = request_irq(p->irq, parport_sunbpp_interrupt, 325 SA_SHIRQ, p->name, p)) != 0) { 326 goto out_put_port; 327 } 328 329 parport_sunbpp_enable_irq(p); 330 331 regs = (struct bpp_regs __iomem *)p->base; 332 333 value_tcr = sbus_readb(®s->p_tcr); 334 value_tcr &= ~P_TCR_DIR; 335 sbus_writeb(value_tcr, ®s->p_tcr); 336 337 printk(KERN_INFO "%s: sunbpp at 0x%lx\n", p->name, p->base); 338 339 dev_set_drvdata(&sdev->ofdev.dev, p); 340 341 parport_announce_port(p); 342 343 return 0; 344 345 out_put_port: 346 parport_put_port(p); 347 348 out_free_ops: 349 kfree(ops); 350 351 out_unmap: 352 sbus_iounmap(base, size); 353 354 return err; 355 } 356 357 static int __devinit bpp_probe(struct of_device *dev, const struct of_device_id *match) 358 { 359 struct sbus_dev *sdev = to_sbus_device(&dev->dev); 360 361 return init_one_port(sdev); 362 } 363 364 static int __devexit bpp_remove(struct of_device *dev) 365 { 366 struct parport *p = dev_get_drvdata(&dev->dev); 367 struct parport_operations *ops = p->ops; 368 369 parport_remove_port(p); 370 371 if (p->irq != PARPORT_IRQ_NONE) { 372 parport_sunbpp_disable_irq(p); 373 free_irq(p->irq, p); 374 } 375 376 sbus_iounmap((void __iomem *) p->base, p->size); 377 parport_put_port(p); 378 kfree(ops); 379 380 dev_set_drvdata(&dev->dev, NULL); 381 382 return 0; 383 } 384 385 static struct of_device_id bpp_match[] = { 386 { 387 .name = "SUNW,bpp", 388 }, 389 {}, 390 }; 391 392 MODULE_DEVICE_TABLE(of, bpp_match); 393 394 static struct of_platform_driver bpp_sbus_driver = { 395 .name = "bpp", 396 .match_table = bpp_match, 397 .probe = bpp_probe, 398 .remove = __devexit_p(bpp_remove), 399 }; 400 401 static int __init parport_sunbpp_init(void) 402 { 403 return of_register_driver(&bpp_sbus_driver, &sbus_bus_type); 404 } 405 406 static void __exit parport_sunbpp_exit(void) 407 { 408 of_unregister_driver(&bpp_sbus_driver); 409 } 410 411 MODULE_AUTHOR("Derrick J Brashear"); 412 MODULE_DESCRIPTION("Parport Driver for Sparc bidirectional Port"); 413 MODULE_SUPPORTED_DEVICE("Sparc Bidirectional Parallel Port"); 414 MODULE_VERSION("2.0"); 415 MODULE_LICENSE("GPL"); 416 417 module_init(parport_sunbpp_init) 418 module_exit(parport_sunbpp_exit) 419