static int parport_ECPPS2_supported(struct parport *pb) { int mode; unsigned char oecr = pb->ops->read_econtrol(pb); if (!(pb->modes & PARPORT_MODE_PCECR)) return 0; pb->ops->write_econtrol(pb, 0x20); mode = parport_PS2_supported(pb); pb->ops->write_econtrol(pb, oecr); return mode ? PARPORT_MODE_PCECPPS2 : 0; }
int init_one_port(struct linux_ebus_device *dev) { struct parport tmpport, *p; unsigned long base; unsigned long config; int irq, dma; /* Pointer to NS87303 Configuration Registers */ config = dev->base_address[1]; /* Setup temporary access to Device operations */ tmpport.base = dev->base_address[0]; tmpport.ops = &parport_ax_ops; /* Configure IRQ to Push Pull, Level Low */ /* Enable ECP mode, set bit 2 of the CTR first */ tmpport.ops->write_control(&tmpport, 0x04); ns87303_modify(config, PCR, PCR_EPP_ENABLE | PCR_IRQ_ODRAIN, PCR_ECP_ENABLE | PCR_ECP_CLK_ENA | PCR_IRQ_POLAR); /* LPT CTR bit 5 controls direction of parallel port */ ns87303_modify(config, PTR, 0, PTR_LPT_REG_DIR); /* * Now continue initializing the port */ base = dev->base_address[0]; irq = dev->irqs[0]; dma = PARPORT_DMA_AUTO; if (!(p = parport_register_port(base, irq, dma, &parport_ax_ops))) return 0; /* Save away pointer to our EBus DMA */ p->private_data = (void *)dev->base_address[2]; p->modes = PARPORT_MODE_PCSPP | parport_PS2_supported(p); if (!check_region(p->base + 0x400, 3)) { p->modes |= parport_ECR_present(p); p->modes |= parport_ECP_supported(p); p->modes |= parport_ECPPS2_supported(p); } p->size = 3; if (p->dma == PARPORT_DMA_AUTO) p->dma = (p->modes & PARPORT_MODE_PCECP) ? 0 : PARPORT_DMA_NONE; printk(KERN_INFO "%s: PC-style at 0x%lx", p->name, p->base); if (p->irq != PARPORT_IRQ_NONE) printk(", irq %s", __irq_itoa(p->irq)); if (p->dma != PARPORT_DMA_NONE) printk(", dma %d", p->dma); printk(" ["); { int f = 0; printmode(SPP); printmode(PS2); printmode(ECP); printmode(ECPPS2); } printk("]\n"); parport_proc_register(p); p->flags |= PARPORT_FLAG_COMA; p->ops->write_control(p, 0x0c); p->ops->write_data(p, 0); if (parport_probe_hook) (*parport_probe_hook)(p); return 1; }
struct parport *__devinit parport_gsc_probe_port (unsigned long base, unsigned long base_hi, int irq, int dma, struct pci_dev *dev) { struct parport_gsc_private *priv; struct parport_operations *ops; struct parport tmp; struct parport *p = &tmp; priv = kmalloc (sizeof (struct parport_gsc_private), GFP_KERNEL); if (!priv) { printk (KERN_DEBUG "parport (0x%lx): no memory!\n", base); return NULL; } ops = kmalloc (sizeof (struct parport_operations), GFP_KERNEL); if (!ops) { printk (KERN_DEBUG "parport (0x%lx): no memory for ops!\n", base); kfree (priv); return NULL; } memcpy (ops, &parport_gsc_ops, sizeof (struct parport_operations)); priv->ctr = 0xc; priv->ctr_writable = 0xff; priv->dma_buf = 0; priv->dma_handle = 0; priv->dev = dev; p->base = base; p->base_hi = base_hi; p->irq = irq; p->dma = dma; p->modes = PARPORT_MODE_PCSPP | PARPORT_MODE_SAFEININT; p->ops = ops; p->private_data = priv; p->physport = p; if (!parport_SPP_supported (p)) { /* No port. */ kfree (priv); return NULL; } parport_PS2_supported (p); if (!(p = parport_register_port(base, PARPORT_IRQ_NONE, PARPORT_DMA_NONE, ops))) { kfree (priv); kfree (ops); return NULL; } p->base_hi = base_hi; p->modes = tmp.modes; p->size = (p->modes & PARPORT_MODE_EPP)?8:3; p->private_data = priv; printk(KERN_INFO "%s: PC-style at 0x%lx", p->name, p->base); p->irq = irq; if (p->irq == PARPORT_IRQ_AUTO) { p->irq = PARPORT_IRQ_NONE; } if (p->irq != PARPORT_IRQ_NONE) { printk(", irq %d", p->irq); if (p->dma == PARPORT_DMA_AUTO) { p->dma = PARPORT_DMA_NONE; } } if (p->dma == PARPORT_DMA_AUTO) /* To use DMA, giving the irq is mandatory (see above) */ p->dma = PARPORT_DMA_NONE; printk(" ["); #define printmode(x) {if(p->modes&PARPORT_MODE_##x){printk("%s%s",f?",":"",#x);f++;}} { int f = 0; printmode(PCSPP); printmode(TRISTATE); printmode(COMPAT) printmode(EPP); // printmode(ECP); // printmode(DMA); } #undef printmode printk("]\n"); if (p->irq != PARPORT_IRQ_NONE) { if (request_irq (p->irq, parport_gsc_interrupt, 0, p->name, p)) { printk (KERN_WARNING "%s: irq %d in use, " "resorting to polled operation\n", p->name, p->irq); p->irq = PARPORT_IRQ_NONE; p->dma = PARPORT_DMA_NONE; } } /* Done probing. Now put the port into a sensible start-up state. */ parport_gsc_write_data(p, 0); parport_gsc_data_forward (p); /* Now that we've told the sharing engine about the port, and found out its characteristics, let the high-level drivers know about it. */ parport_announce_port (p); return p; }