/* Status Register Bit Positions */ #define XPS2_STATUS_RX_FULL 0x00000001 /* Receive Full */ #define XPS2_STATUS_TX_FULL 0x00000002 /* Transmit Full */
/* If there is data available in the PS/2 receiver, read it */
sr = in_be32(drvdata->base_address + XPS2_STATUS_OFFSET); if (sr & XPS2_STATUS_RX_FULL) {
*byte = in_be32(drvdata->base_address + XPS2_RX_DATA_OFFSET);
status = 0;
}
/* Get the PS/2 interrupts and clear them */
intr_sr = in_be32(drvdata->base_address + XPS2_IPISR_OFFSET);
out_be32(drvdata->base_address + XPS2_IPISR_OFFSET, intr_sr);
/* Check which interrupt is active */ if (intr_sr & XPS2_IPIXR_RX_OVF)
dev_warn(drvdata->dev, "receive overrun error\n");
if (intr_sr & XPS2_IPIXR_RX_ERR)
drvdata->flags |= SERIO_PARITY;
if (intr_sr & (XPS2_IPIXR_TX_NOACK | XPS2_IPIXR_WDT_TOUT))
drvdata->flags |= SERIO_TIMEOUT;
if (intr_sr & XPS2_IPIXR_RX_FULL) {
status = xps2_recv(drvdata, &c);
/* Error, if a byte is not received */ if (status) {
dev_err(drvdata->dev, "wrong rcvd byte count (%d)\n", status);
} else {
serio_interrupt(drvdata->serio, c, drvdata->flags);
drvdata->flags = 0;
}
}
/* If the PS/2 transmitter is empty send a byte of data */
sr = in_be32(drvdata->base_address + XPS2_STATUS_OFFSET); if (sr & XPS2_STATUS_TX_FULL) return -EAGAIN;
phys_addr = r_mem.start;
remap_size = resource_size(&r_mem); if (!request_mem_region(phys_addr, remap_size, DRIVER_NAME)) {
dev_err(dev, "Couldn't lock memory region at 0x%08llX\n",
(unsignedlonglong)phys_addr);
error = -EBUSY; goto failed1;
}
/* Fill in configuration data and add them to the list */
drvdata->base_address = ioremap(phys_addr, remap_size); if (drvdata->base_address == NULL) {
dev_err(dev, "Couldn't ioremap memory at 0x%08llX\n",
(unsignedlonglong)phys_addr);
error = -EFAULT; goto failed2;
}
/* Disable all the interrupts, just in case */
out_be32(drvdata->base_address + XPS2_IPIER_OFFSET, 0);
/* Get iospace of the device */ if (of_address_to_resource(of_dev->dev.of_node, 0, &r_mem))
dev_err(drvdata->dev, "invalid address\n"); else
release_mem_region(r_mem.start, resource_size(&r_mem));
kfree(drvdata);
}
/* Match table for of_platform binding */ staticconststruct of_device_id xps2_of_match[] = {
{ .compatible = "xlnx,xps-ps2-1.00.a", },
{ /* end of list */ },
};
MODULE_DEVICE_TABLE(of, xps2_of_match);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.