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 void parport_sunbpp_disable_irq(struct parport *p) 50 { 51 struct bpp_regs __iomem *regs = (struct bpp_regs __iomem *)p->base; 52 u32 tmp; 53 54 tmp = sbus_readl(®s->p_csr); 55 tmp &= ~DMA_INT_ENAB; 56 sbus_writel(tmp, ®s->p_csr); 57 } 58 59 static void parport_sunbpp_enable_irq(struct parport *p) 60 { 61 struct bpp_regs __iomem *regs = (struct bpp_regs __iomem *)p->base; 62 u32 tmp; 63 64 tmp = sbus_readl(®s->p_csr); 65 tmp |= DMA_INT_ENAB; 66 sbus_writel(tmp, ®s->p_csr); 67 } 68 69 static void parport_sunbpp_write_data(struct parport *p, unsigned char d) 70 { 71 struct bpp_regs __iomem *regs = (struct bpp_regs __iomem *)p->base; 72 73 sbus_writeb(d, ®s->p_dr); 74 dprintk((KERN_DEBUG "wrote 0x%x\n", d)); 75 } 76 77 static unsigned char parport_sunbpp_read_data(struct parport *p) 78 { 79 struct bpp_regs __iomem *regs = (struct bpp_regs __iomem *)p->base; 80 81 return sbus_readb(®s->p_dr); 82 } 83 84 #if 0 85 static void control_pc_to_sunbpp(struct parport *p, unsigned char status) 86 { 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); 90 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; 99 100 sbus_writeb(value_or, ®s->p_or); 101 sbus_writeb(value_tcr, ®s->p_tcr); 102 } 103 #endif 104 105 static unsigned char status_sunbpp_to_pc(struct parport *p) 106 { 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); 111 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; 122 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)); 125 return bits; 126 } 127 128 static unsigned char control_sunbpp_to_pc(struct parport *p) 129 { 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); 134 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; 143 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)); 146 return bits; 147 } 148 149 static unsigned char parport_sunbpp_read_control(struct parport *p) 150 { 151 return control_sunbpp_to_pc(p); 152 } 153 154 static unsigned char parport_sunbpp_frob_control(struct parport *p, 155 unsigned char mask, 156 unsigned char val) 157 { 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); 161 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; 167 } else { 168 value_tcr |= P_TCR_DS; 169 } 170 } 171 if (mask & PARPORT_CONTROL_AUTOFD) { 172 if (val & PARPORT_CONTROL_AUTOFD) { 173 value_or &= ~P_OR_AFXN; 174 } else { 175 value_or |= P_OR_AFXN; 176 } 177 } 178 if (mask & PARPORT_CONTROL_INIT) { 179 if (val & PARPORT_CONTROL_INIT) { 180 value_or &= ~P_OR_INIT; 181 } else { 182 value_or |= P_OR_INIT; 183 } 184 } 185 if (mask & PARPORT_CONTROL_SELECT) { 186 if (val & PARPORT_CONTROL_SELECT) { 187 value_or |= P_OR_SLCT_IN; 188 } else { 189 value_or &= ~P_OR_SLCT_IN; 190 } 191 } 192 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); 198 } 199 200 static void parport_sunbpp_write_control(struct parport *p, unsigned char d) 201 { 202 const unsigned char wm = (PARPORT_CONTROL_STROBE | 203 PARPORT_CONTROL_AUTOFD | 204 PARPORT_CONTROL_INIT | 205 PARPORT_CONTROL_SELECT); 206 207 parport_sunbpp_frob_control (p, wm, d & wm); 208 } 209 210 static unsigned char parport_sunbpp_read_status(struct parport *p) 211 { 212 return status_sunbpp_to_pc(p); 213 } 214 215 static void parport_sunbpp_data_forward (struct parport *p) 216 { 217 struct bpp_regs __iomem *regs = (struct bpp_regs __iomem *)p->base; 218 unsigned char value_tcr = sbus_readb(®s->p_tcr); 219 220 dprintk((KERN_DEBUG "forward\n")); 221 value_tcr &= ~P_TCR_DIR; 222 sbus_writeb(value_tcr, ®s->p_tcr); 223 } 224 225 static void parport_sunbpp_data_reverse (struct parport *p) 226 { 227 struct bpp_regs __iomem *regs = (struct bpp_regs __iomem *)p->base; 228 u8 val = sbus_readb(®s->p_tcr); 229 230 dprintk((KERN_DEBUG "reverse\n")); 231 val |= P_TCR_DIR; 232 sbus_writeb(val, ®s->p_tcr); 233 } 234 235 static void parport_sunbpp_init_state(struct pardevice *dev, struct parport_state *s) 236 { 237 s->u.pc.ctr = 0xc; 238 s->u.pc.ecr = 0x0; 239 } 240 241 static void parport_sunbpp_save_state(struct parport *p, struct parport_state *s) 242 { 243 s->u.pc.ctr = parport_sunbpp_read_control(p); 244 } 245 246 static void parport_sunbpp_restore_state(struct parport *p, struct parport_state *s) 247 { 248 parport_sunbpp_write_control(p, s->u.pc.ctr); 249 } 250 251 static struct parport_operations parport_sunbpp_ops = 252 { 253 .write_data = parport_sunbpp_write_data, 254 .read_data = parport_sunbpp_read_data, 255 256 .write_control = parport_sunbpp_write_control, 257 .read_control = parport_sunbpp_read_control, 258 .frob_control = parport_sunbpp_frob_control, 259 260 .read_status = parport_sunbpp_read_status, 261 262 .enable_irq = parport_sunbpp_enable_irq, 263 .disable_irq = parport_sunbpp_disable_irq, 264 265 .data_forward = parport_sunbpp_data_forward, 266 .data_reverse = parport_sunbpp_data_reverse, 267 268 .init_state = parport_sunbpp_init_state, 269 .save_state = parport_sunbpp_save_state, 270 .restore_state = parport_sunbpp_restore_state, 271 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, 276 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, 280 281 .compat_write_data = parport_ieee1284_write_compat, 282 .nibble_read_data = parport_ieee1284_read_nibble, 283 .byte_read_data = parport_ieee1284_read_byte, 284 285 .owner = THIS_MODULE, 286 }; 287 288 static int __devinit init_one_port(struct sbus_dev *sdev) 289 { 290 struct parport *p; 291 /* at least in theory there may be a "we don't dma" case */ 292 struct parport_operations *ops; 293 void __iomem *base; 294 int irq, dma, err = 0, size; 295 struct bpp_regs __iomem *regs; 296 unsigned char value_tcr; 297 298 irq = sdev->irqs[0]; 299 base = sbus_ioremap(&sdev->resource[0], 0, 300 sdev->reg_addrs[0].reg_size, 301 "sunbpp"); 302 if (!base) 303 return -ENODEV; 304 305 size = sdev->reg_addrs[0].reg_size; 306 dma = PARPORT_DMA_NONE; 307 308 ops = kmalloc(sizeof(struct parport_operations), GFP_KERNEL); 309 if (!ops) 310 goto out_unmap; 311 312 memcpy (ops, &parport_sunbpp_ops, sizeof (struct parport_operations)); 313 314 dprintk(("register_port\n")); 315 if (!(p = parport_register_port((unsigned long)base, irq, dma, ops))) 316 goto out_free_ops; 317 318 p->size = size; 319 p->dev = &sdev->ofdev.dev; 320 321 if ((err = request_irq(p->irq, parport_irq_handler, 322 IRQF_SHARED, p->name, p)) != 0) { 323 goto out_put_port; 324 } 325 326 parport_sunbpp_enable_irq(p); 327 328 regs = (struct bpp_regs __iomem *)p->base; 329 330 value_tcr = sbus_readb(®s->p_tcr); 331 value_tcr &= ~P_TCR_DIR; 332 sbus_writeb(value_tcr, ®s->p_tcr); 333 334 printk(KERN_INFO "%s: sunbpp at 0x%lx\n", p->name, p->base); 335 336 dev_set_drvdata(&sdev->ofdev.dev, p); 337 338 parport_announce_port(p); 339 340 return 0; 341 342 out_put_port: 343 parport_put_port(p); 344 345 out_free_ops: 346 kfree(ops); 347 348 out_unmap: 349 sbus_iounmap(base, size); 350 351 return err; 352 } 353 354 static int __devinit bpp_probe(struct of_device *dev, const struct of_device_id *match) 355 { 356 struct sbus_dev *sdev = to_sbus_device(&dev->dev); 357 358 return init_one_port(sdev); 359 } 360 361 static int __devexit bpp_remove(struct of_device *dev) 362 { 363 struct parport *p = dev_get_drvdata(&dev->dev); 364 struct parport_operations *ops = p->ops; 365 366 parport_remove_port(p); 367 368 if (p->irq != PARPORT_IRQ_NONE) { 369 parport_sunbpp_disable_irq(p); 370 free_irq(p->irq, p); 371 } 372 373 sbus_iounmap((void __iomem *) p->base, p->size); 374 parport_put_port(p); 375 kfree(ops); 376 377 dev_set_drvdata(&dev->dev, NULL); 378 379 return 0; 380 } 381 382 static struct of_device_id bpp_match[] = { 383 { 384 .name = "SUNW,bpp", 385 }, 386 {}, 387 }; 388 389 MODULE_DEVICE_TABLE(of, bpp_match); 390 391 static struct of_platform_driver bpp_sbus_driver = { 392 .name = "bpp", 393 .match_table = bpp_match, 394 .probe = bpp_probe, 395 .remove = __devexit_p(bpp_remove), 396 }; 397 398 static int __init parport_sunbpp_init(void) 399 { 400 return of_register_driver(&bpp_sbus_driver, &sbus_bus_type); 401 } 402 403 static void __exit parport_sunbpp_exit(void) 404 { 405 of_unregister_driver(&bpp_sbus_driver); 406 } 407 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"); 413 414 module_init(parport_sunbpp_init) 415 module_exit(parport_sunbpp_exit) 416