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 #include <linux/of.h> 30 #include <linux/of_device.h> 31 32 #include <linux/parport.h> 33 34 #include <asm/ptrace.h> 35 #include <linux/interrupt.h> 36 37 #include <asm/io.h> 38 #include <asm/oplib.h> /* OpenProm Library */ 39 #include <asm/dma.h> /* BPP uses LSI 64854 for DMA */ 40 #include <asm/irq.h> 41 #include <asm/sunbpp.h> 42 43 #undef __SUNBPP_DEBUG 44 #ifdef __SUNBPP_DEBUG 45 #define dprintk(x) printk x 46 #else 47 #define dprintk(x) 48 #endif 49 50 static void parport_sunbpp_disable_irq(struct parport *p) 51 { 52 struct bpp_regs __iomem *regs = (struct bpp_regs __iomem *)p->base; 53 u32 tmp; 54 55 tmp = sbus_readl(®s->p_csr); 56 tmp &= ~DMA_INT_ENAB; 57 sbus_writel(tmp, ®s->p_csr); 58 } 59 60 static void parport_sunbpp_enable_irq(struct parport *p) 61 { 62 struct bpp_regs __iomem *regs = (struct bpp_regs __iomem *)p->base; 63 u32 tmp; 64 65 tmp = sbus_readl(®s->p_csr); 66 tmp |= DMA_INT_ENAB; 67 sbus_writel(tmp, ®s->p_csr); 68 } 69 70 static void parport_sunbpp_write_data(struct parport *p, unsigned char d) 71 { 72 struct bpp_regs __iomem *regs = (struct bpp_regs __iomem *)p->base; 73 74 sbus_writeb(d, ®s->p_dr); 75 dprintk((KERN_DEBUG "wrote 0x%x\n", d)); 76 } 77 78 static unsigned char parport_sunbpp_read_data(struct parport *p) 79 { 80 struct bpp_regs __iomem *regs = (struct bpp_regs __iomem *)p->base; 81 82 return sbus_readb(®s->p_dr); 83 } 84 85 #if 0 86 static void control_pc_to_sunbpp(struct parport *p, unsigned char status) 87 { 88 struct bpp_regs __iomem *regs = (struct bpp_regs __iomem *)p->base; 89 unsigned char value_tcr = sbus_readb(®s->p_tcr); 90 unsigned char value_or = sbus_readb(®s->p_or); 91 92 if (status & PARPORT_CONTROL_STROBE) 93 value_tcr |= P_TCR_DS; 94 if (status & PARPORT_CONTROL_AUTOFD) 95 value_or |= P_OR_AFXN; 96 if (status & PARPORT_CONTROL_INIT) 97 value_or |= P_OR_INIT; 98 if (status & PARPORT_CONTROL_SELECT) 99 value_or |= P_OR_SLCT_IN; 100 101 sbus_writeb(value_or, ®s->p_or); 102 sbus_writeb(value_tcr, ®s->p_tcr); 103 } 104 #endif 105 106 static unsigned char status_sunbpp_to_pc(struct parport *p) 107 { 108 struct bpp_regs __iomem *regs = (struct bpp_regs __iomem *)p->base; 109 unsigned char bits = 0; 110 unsigned char value_tcr = sbus_readb(®s->p_tcr); 111 unsigned char value_ir = sbus_readb(®s->p_ir); 112 113 if (!(value_ir & P_IR_ERR)) 114 bits |= PARPORT_STATUS_ERROR; 115 if (!(value_ir & P_IR_SLCT)) 116 bits |= PARPORT_STATUS_SELECT; 117 if (!(value_ir & P_IR_PE)) 118 bits |= PARPORT_STATUS_PAPEROUT; 119 if (value_tcr & P_TCR_ACK) 120 bits |= PARPORT_STATUS_ACK; 121 if (!(value_tcr & P_TCR_BUSY)) 122 bits |= PARPORT_STATUS_BUSY; 123 124 dprintk((KERN_DEBUG "tcr 0x%x ir 0x%x\n", value_tcr, value_ir)); 125 dprintk((KERN_DEBUG "read status 0x%x\n", bits)); 126 return bits; 127 } 128 129 static unsigned char control_sunbpp_to_pc(struct parport *p) 130 { 131 struct bpp_regs __iomem *regs = (struct bpp_regs __iomem *)p->base; 132 unsigned char bits = 0; 133 unsigned char value_tcr = sbus_readb(®s->p_tcr); 134 unsigned char value_or = sbus_readb(®s->p_or); 135 136 if (!(value_tcr & P_TCR_DS)) 137 bits |= PARPORT_CONTROL_STROBE; 138 if (!(value_or & P_OR_AFXN)) 139 bits |= PARPORT_CONTROL_AUTOFD; 140 if (!(value_or & P_OR_INIT)) 141 bits |= PARPORT_CONTROL_INIT; 142 if (value_or & P_OR_SLCT_IN) 143 bits |= PARPORT_CONTROL_SELECT; 144 145 dprintk((KERN_DEBUG "tcr 0x%x or 0x%x\n", value_tcr, value_or)); 146 dprintk((KERN_DEBUG "read control 0x%x\n", bits)); 147 return bits; 148 } 149 150 static unsigned char parport_sunbpp_read_control(struct parport *p) 151 { 152 return control_sunbpp_to_pc(p); 153 } 154 155 static unsigned char parport_sunbpp_frob_control(struct parport *p, 156 unsigned char mask, 157 unsigned char val) 158 { 159 struct bpp_regs __iomem *regs = (struct bpp_regs __iomem *)p->base; 160 unsigned char value_tcr = sbus_readb(®s->p_tcr); 161 unsigned char value_or = sbus_readb(®s->p_or); 162 163 dprintk((KERN_DEBUG "frob1: tcr 0x%x or 0x%x\n", 164 value_tcr, value_or)); 165 if (mask & PARPORT_CONTROL_STROBE) { 166 if (val & PARPORT_CONTROL_STROBE) { 167 value_tcr &= ~P_TCR_DS; 168 } else { 169 value_tcr |= P_TCR_DS; 170 } 171 } 172 if (mask & PARPORT_CONTROL_AUTOFD) { 173 if (val & PARPORT_CONTROL_AUTOFD) { 174 value_or &= ~P_OR_AFXN; 175 } else { 176 value_or |= P_OR_AFXN; 177 } 178 } 179 if (mask & PARPORT_CONTROL_INIT) { 180 if (val & PARPORT_CONTROL_INIT) { 181 value_or &= ~P_OR_INIT; 182 } else { 183 value_or |= P_OR_INIT; 184 } 185 } 186 if (mask & PARPORT_CONTROL_SELECT) { 187 if (val & PARPORT_CONTROL_SELECT) { 188 value_or |= P_OR_SLCT_IN; 189 } else { 190 value_or &= ~P_OR_SLCT_IN; 191 } 192 } 193 194 sbus_writeb(value_or, ®s->p_or); 195 sbus_writeb(value_tcr, ®s->p_tcr); 196 dprintk((KERN_DEBUG "frob2: tcr 0x%x or 0x%x\n", 197 value_tcr, value_or)); 198 return parport_sunbpp_read_control(p); 199 } 200 201 static void parport_sunbpp_write_control(struct parport *p, unsigned char d) 202 { 203 const unsigned char wm = (PARPORT_CONTROL_STROBE | 204 PARPORT_CONTROL_AUTOFD | 205 PARPORT_CONTROL_INIT | 206 PARPORT_CONTROL_SELECT); 207 208 parport_sunbpp_frob_control (p, wm, d & wm); 209 } 210 211 static unsigned char parport_sunbpp_read_status(struct parport *p) 212 { 213 return status_sunbpp_to_pc(p); 214 } 215 216 static void parport_sunbpp_data_forward (struct parport *p) 217 { 218 struct bpp_regs __iomem *regs = (struct bpp_regs __iomem *)p->base; 219 unsigned char value_tcr = sbus_readb(®s->p_tcr); 220 221 dprintk((KERN_DEBUG "forward\n")); 222 value_tcr &= ~P_TCR_DIR; 223 sbus_writeb(value_tcr, ®s->p_tcr); 224 } 225 226 static void parport_sunbpp_data_reverse (struct parport *p) 227 { 228 struct bpp_regs __iomem *regs = (struct bpp_regs __iomem *)p->base; 229 u8 val = sbus_readb(®s->p_tcr); 230 231 dprintk((KERN_DEBUG "reverse\n")); 232 val |= P_TCR_DIR; 233 sbus_writeb(val, ®s->p_tcr); 234 } 235 236 static void parport_sunbpp_init_state(struct pardevice *dev, struct parport_state *s) 237 { 238 s->u.pc.ctr = 0xc; 239 s->u.pc.ecr = 0x0; 240 } 241 242 static void parport_sunbpp_save_state(struct parport *p, struct parport_state *s) 243 { 244 s->u.pc.ctr = parport_sunbpp_read_control(p); 245 } 246 247 static void parport_sunbpp_restore_state(struct parport *p, struct parport_state *s) 248 { 249 parport_sunbpp_write_control(p, s->u.pc.ctr); 250 } 251 252 static struct parport_operations parport_sunbpp_ops = 253 { 254 .write_data = parport_sunbpp_write_data, 255 .read_data = parport_sunbpp_read_data, 256 257 .write_control = parport_sunbpp_write_control, 258 .read_control = parport_sunbpp_read_control, 259 .frob_control = parport_sunbpp_frob_control, 260 261 .read_status = parport_sunbpp_read_status, 262 263 .enable_irq = parport_sunbpp_enable_irq, 264 .disable_irq = parport_sunbpp_disable_irq, 265 266 .data_forward = parport_sunbpp_data_forward, 267 .data_reverse = parport_sunbpp_data_reverse, 268 269 .init_state = parport_sunbpp_init_state, 270 .save_state = parport_sunbpp_save_state, 271 .restore_state = parport_sunbpp_restore_state, 272 273 .epp_write_data = parport_ieee1284_epp_write_data, 274 .epp_read_data = parport_ieee1284_epp_read_data, 275 .epp_write_addr = parport_ieee1284_epp_write_addr, 276 .epp_read_addr = parport_ieee1284_epp_read_addr, 277 278 .ecp_write_data = parport_ieee1284_ecp_write_data, 279 .ecp_read_data = parport_ieee1284_ecp_read_data, 280 .ecp_write_addr = parport_ieee1284_ecp_write_addr, 281 282 .compat_write_data = parport_ieee1284_write_compat, 283 .nibble_read_data = parport_ieee1284_read_nibble, 284 .byte_read_data = parport_ieee1284_read_byte, 285 286 .owner = THIS_MODULE, 287 }; 288 289 static int __devinit bpp_probe(struct of_device *op, const struct of_device_id *match) 290 { 291 struct parport_operations *ops; 292 struct bpp_regs __iomem *regs; 293 int irq, dma, err = 0, size; 294 unsigned char value_tcr; 295 void __iomem *base; 296 struct parport *p; 297 298 irq = op->irqs[0]; 299 base = of_ioremap(&op->resource[0], 0, 300 resource_size(&op->resource[0]), 301 "sunbpp"); 302 if (!base) 303 return -ENODEV; 304 305 size = resource_size(&op->resource[0]); 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 = &op->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(&op->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 of_iounmap(&op->resource[0], base, size); 350 351 return err; 352 } 353 354 static int __devexit bpp_remove(struct of_device *op) 355 { 356 struct parport *p = dev_get_drvdata(&op->dev); 357 struct parport_operations *ops = p->ops; 358 359 parport_remove_port(p); 360 361 if (p->irq != PARPORT_IRQ_NONE) { 362 parport_sunbpp_disable_irq(p); 363 free_irq(p->irq, p); 364 } 365 366 of_iounmap(&op->resource[0], (void __iomem *) p->base, p->size); 367 parport_put_port(p); 368 kfree(ops); 369 370 dev_set_drvdata(&op->dev, NULL); 371 372 return 0; 373 } 374 375 static const struct of_device_id bpp_match[] = { 376 { 377 .name = "SUNW,bpp", 378 }, 379 {}, 380 }; 381 382 MODULE_DEVICE_TABLE(of, bpp_match); 383 384 static struct of_platform_driver bpp_sbus_driver = { 385 .name = "bpp", 386 .match_table = bpp_match, 387 .probe = bpp_probe, 388 .remove = __devexit_p(bpp_remove), 389 }; 390 391 static int __init parport_sunbpp_init(void) 392 { 393 return of_register_driver(&bpp_sbus_driver, &of_bus_type); 394 } 395 396 static void __exit parport_sunbpp_exit(void) 397 { 398 of_unregister_driver(&bpp_sbus_driver); 399 } 400 401 MODULE_AUTHOR("Derrick J Brashear"); 402 MODULE_DESCRIPTION("Parport Driver for Sparc bidirectional Port"); 403 MODULE_SUPPORTED_DEVICE("Sparc Bidirectional Parallel Port"); 404 MODULE_VERSION("2.0"); 405 MODULE_LICENSE("GPL"); 406 407 module_init(parport_sunbpp_init) 408 module_exit(parport_sunbpp_exit) 409