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) 50 { 51 parport_generic_irq(irq, (struct parport *) dev_id); 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", value_tcr, value_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", value_tcr, value_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", 169 value_tcr, value_or)); 170 if (mask & PARPORT_CONTROL_STROBE) { 171 if (val & PARPORT_CONTROL_STROBE) { 172 value_tcr &= ~P_TCR_DS; 173 } else { 174 value_tcr |= P_TCR_DS; 175 } 176 } 177 if (mask & PARPORT_CONTROL_AUTOFD) { 178 if (val & PARPORT_CONTROL_AUTOFD) { 179 value_or &= ~P_OR_AFXN; 180 } else { 181 value_or |= P_OR_AFXN; 182 } 183 } 184 if (mask & PARPORT_CONTROL_INIT) { 185 if (val & PARPORT_CONTROL_INIT) { 186 value_or &= ~P_OR_INIT; 187 } else { 188 value_or |= P_OR_INIT; 189 } 190 } 191 if (mask & PARPORT_CONTROL_SELECT) { 192 if (val & PARPORT_CONTROL_SELECT) { 193 value_or |= P_OR_SLCT_IN; 194 } else { 195 value_or &= ~P_OR_SLCT_IN; 196 } 197 } 198 199 sbus_writeb(value_or, ®s->p_or); 200 sbus_writeb(value_tcr, ®s->p_tcr); 201 dprintk((KERN_DEBUG "frob2: tcr 0x%x or 0x%x\n", 202 value_tcr, value_or)); 203 return parport_sunbpp_read_control(p); 204 } 205 206 static void parport_sunbpp_write_control(struct parport *p, unsigned char d) 207 { 208 const unsigned char wm = (PARPORT_CONTROL_STROBE | 209 PARPORT_CONTROL_AUTOFD | 210 PARPORT_CONTROL_INIT | 211 PARPORT_CONTROL_SELECT); 212 213 parport_sunbpp_frob_control (p, wm, d & wm); 214 } 215 216 static unsigned char parport_sunbpp_read_status(struct parport *p) 217 { 218 return status_sunbpp_to_pc(p); 219 } 220 221 static void parport_sunbpp_data_forward (struct parport *p) 222 { 223 struct bpp_regs __iomem *regs = (struct bpp_regs __iomem *)p->base; 224 unsigned char value_tcr = sbus_readb(®s->p_tcr); 225 226 dprintk((KERN_DEBUG "forward\n")); 227 value_tcr &= ~P_TCR_DIR; 228 sbus_writeb(value_tcr, ®s->p_tcr); 229 } 230 231 static void parport_sunbpp_data_reverse (struct parport *p) 232 { 233 struct bpp_regs __iomem *regs = (struct bpp_regs __iomem *)p->base; 234 u8 val = sbus_readb(®s->p_tcr); 235 236 dprintk((KERN_DEBUG "reverse\n")); 237 val |= P_TCR_DIR; 238 sbus_writeb(val, ®s->p_tcr); 239 } 240 241 static void parport_sunbpp_init_state(struct pardevice *dev, struct parport_state *s) 242 { 243 s->u.pc.ctr = 0xc; 244 s->u.pc.ecr = 0x0; 245 } 246 247 static void parport_sunbpp_save_state(struct parport *p, struct parport_state *s) 248 { 249 s->u.pc.ctr = parport_sunbpp_read_control(p); 250 } 251 252 static void parport_sunbpp_restore_state(struct parport *p, struct parport_state *s) 253 { 254 parport_sunbpp_write_control(p, s->u.pc.ctr); 255 } 256 257 static struct parport_operations parport_sunbpp_ops = 258 { 259 .write_data = parport_sunbpp_write_data, 260 .read_data = parport_sunbpp_read_data, 261 262 .write_control = parport_sunbpp_write_control, 263 .read_control = parport_sunbpp_read_control, 264 .frob_control = parport_sunbpp_frob_control, 265 266 .read_status = parport_sunbpp_read_status, 267 268 .enable_irq = parport_sunbpp_enable_irq, 269 .disable_irq = parport_sunbpp_disable_irq, 270 271 .data_forward = parport_sunbpp_data_forward, 272 .data_reverse = parport_sunbpp_data_reverse, 273 274 .init_state = parport_sunbpp_init_state, 275 .save_state = parport_sunbpp_save_state, 276 .restore_state = parport_sunbpp_restore_state, 277 278 .epp_write_data = parport_ieee1284_epp_write_data, 279 .epp_read_data = parport_ieee1284_epp_read_data, 280 .epp_write_addr = parport_ieee1284_epp_write_addr, 281 .epp_read_addr = parport_ieee1284_epp_read_addr, 282 283 .ecp_write_data = parport_ieee1284_ecp_write_data, 284 .ecp_read_data = parport_ieee1284_ecp_read_data, 285 .ecp_write_addr = parport_ieee1284_ecp_write_addr, 286 287 .compat_write_data = parport_ieee1284_write_compat, 288 .nibble_read_data = parport_ieee1284_read_nibble, 289 .byte_read_data = parport_ieee1284_read_byte, 290 291 .owner = THIS_MODULE, 292 }; 293 294 static int __devinit init_one_port(struct sbus_dev *sdev) 295 { 296 struct parport *p; 297 /* at least in theory there may be a "we don't dma" case */ 298 struct parport_operations *ops; 299 void __iomem *base; 300 int irq, dma, err = 0, size; 301 struct bpp_regs __iomem *regs; 302 unsigned char value_tcr; 303 304 irq = sdev->irqs[0]; 305 base = sbus_ioremap(&sdev->resource[0], 0, 306 sdev->reg_addrs[0].reg_size, 307 "sunbpp"); 308 if (!base) 309 return -ENODEV; 310 311 size = sdev->reg_addrs[0].reg_size; 312 dma = PARPORT_DMA_NONE; 313 314 ops = kmalloc(sizeof(struct parport_operations), GFP_KERNEL); 315 if (!ops) 316 goto out_unmap; 317 318 memcpy (ops, &parport_sunbpp_ops, sizeof (struct parport_operations)); 319 320 dprintk(("register_port\n")); 321 if (!(p = parport_register_port((unsigned long)base, irq, dma, ops))) 322 goto out_free_ops; 323 324 p->size = size; 325 p->dev = &sdev->ofdev.dev; 326 327 if ((err = request_irq(p->irq, parport_sunbpp_interrupt, 328 IRQF_SHARED, p->name, p)) != 0) { 329 goto out_put_port; 330 } 331 332 parport_sunbpp_enable_irq(p); 333 334 regs = (struct bpp_regs __iomem *)p->base; 335 336 value_tcr = sbus_readb(®s->p_tcr); 337 value_tcr &= ~P_TCR_DIR; 338 sbus_writeb(value_tcr, ®s->p_tcr); 339 340 printk(KERN_INFO "%s: sunbpp at 0x%lx\n", p->name, p->base); 341 342 dev_set_drvdata(&sdev->ofdev.dev, p); 343 344 parport_announce_port(p); 345 346 return 0; 347 348 out_put_port: 349 parport_put_port(p); 350 351 out_free_ops: 352 kfree(ops); 353 354 out_unmap: 355 sbus_iounmap(base, size); 356 357 return err; 358 } 359 360 static int __devinit bpp_probe(struct of_device *dev, const struct of_device_id *match) 361 { 362 struct sbus_dev *sdev = to_sbus_device(&dev->dev); 363 364 return init_one_port(sdev); 365 } 366 367 static int __devexit bpp_remove(struct of_device *dev) 368 { 369 struct parport *p = dev_get_drvdata(&dev->dev); 370 struct parport_operations *ops = p->ops; 371 372 parport_remove_port(p); 373 374 if (p->irq != PARPORT_IRQ_NONE) { 375 parport_sunbpp_disable_irq(p); 376 free_irq(p->irq, p); 377 } 378 379 sbus_iounmap((void __iomem *) p->base, p->size); 380 parport_put_port(p); 381 kfree(ops); 382 383 dev_set_drvdata(&dev->dev, NULL); 384 385 return 0; 386 } 387 388 static struct of_device_id bpp_match[] = { 389 { 390 .name = "SUNW,bpp", 391 }, 392 {}, 393 }; 394 395 MODULE_DEVICE_TABLE(of, bpp_match); 396 397 static struct of_platform_driver bpp_sbus_driver = { 398 .name = "bpp", 399 .match_table = bpp_match, 400 .probe = bpp_probe, 401 .remove = __devexit_p(bpp_remove), 402 }; 403 404 static int __init parport_sunbpp_init(void) 405 { 406 return of_register_driver(&bpp_sbus_driver, &sbus_bus_type); 407 } 408 409 static void __exit parport_sunbpp_exit(void) 410 { 411 of_unregister_driver(&bpp_sbus_driver); 412 } 413 414 MODULE_AUTHOR("Derrick J Brashear"); 415 MODULE_DESCRIPTION("Parport Driver for Sparc bidirectional Port"); 416 MODULE_SUPPORTED_DEVICE("Sparc Bidirectional Parallel Port"); 417 MODULE_VERSION("2.0"); 418 MODULE_LICENSE("GPL"); 419 420 module_init(parport_sunbpp_init) 421 module_exit(parport_sunbpp_exit) 422