xilinx_ps2.c 10.9 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
/*
 * Xilinx XPS PS/2 device driver
 *
 * (c) 2005 MontaVista Software, Inc.
 * (c) 2008 Xilinx, Inc.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2 of the License, or (at your
 * option) any later version.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 675 Mass Ave, Cambridge, MA 02139, USA.
 */


#include <linux/module.h>
#include <linux/serio.h>
#include <linux/interrupt.h>
#include <linux/errno.h>
22
#include <linux/slab.h>
23 24 25
#include <linux/init.h>
#include <linux/list.h>
#include <linux/io.h>
26
#include <linux/of_address.h>
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
#include <linux/of_device.h>
#include <linux/of_platform.h>

#define DRIVER_NAME		"xilinx_ps2"

/* Register offsets for the xps2 device */
#define XPS2_SRST_OFFSET	0x00000000 /* Software Reset register */
#define XPS2_STATUS_OFFSET	0x00000004 /* Status register */
#define XPS2_RX_DATA_OFFSET	0x00000008 /* Receive Data register */
#define XPS2_TX_DATA_OFFSET	0x0000000C /* Transmit Data register */
#define XPS2_GIER_OFFSET	0x0000002C /* Global Interrupt Enable reg */
#define XPS2_IPISR_OFFSET	0x00000030 /* Interrupt Status register */
#define XPS2_IPIER_OFFSET	0x00000038 /* Interrupt Enable register */

/* Reset Register Bit Definitions */
#define XPS2_SRST_RESET		0x0000000A /* Software Reset  */

/* Status Register Bit Positions */
#define XPS2_STATUS_RX_FULL	0x00000001 /* Receive Full  */
#define XPS2_STATUS_TX_FULL	0x00000002 /* Transmit Full  */

/* Bit definitions for ISR/IER registers. Both the registers have the same bit
 * definitions and are only defined once. */
#define XPS2_IPIXR_WDT_TOUT	0x00000001 /* Watchdog Timeout Interrupt */
#define XPS2_IPIXR_TX_NOACK	0x00000002 /* Transmit No ACK Interrupt */
#define XPS2_IPIXR_TX_ACK	0x00000004 /* Transmit ACK (Data) Interrupt */
#define XPS2_IPIXR_RX_OVF	0x00000008 /* Receive Overflow Interrupt */
#define XPS2_IPIXR_RX_ERR	0x00000010 /* Receive Error Interrupt */
#define XPS2_IPIXR_RX_FULL	0x00000020 /* Receive Data Interrupt */

/* Mask for all the Transmit Interrupts */
#define XPS2_IPIXR_TX_ALL	(XPS2_IPIXR_TX_NOACK | XPS2_IPIXR_TX_ACK)

/* Mask for all the Receive Interrupts */
#define XPS2_IPIXR_RX_ALL	(XPS2_IPIXR_RX_OVF | XPS2_IPIXR_RX_ERR |  \
62
				 XPS2_IPIXR_RX_FULL)
63 64 65

/* Mask for all the Interrupts */
#define XPS2_IPIXR_ALL		(XPS2_IPIXR_TX_ALL | XPS2_IPIXR_RX_ALL |  \
66
				 XPS2_IPIXR_WDT_TOUT)
67 68 69 70 71 72 73 74

/* Global Interrupt Enable mask */
#define XPS2_GIER_GIE_MASK	0x80000000

struct xps2data {
	int irq;
	spinlock_t lock;
	void __iomem *base_address;	/* virt. address of control registers */
75
	unsigned int flags;
76 77
	struct serio *serio;		/* serio */
	struct device *dev;
78 79 80 81 82 83
};

/************************************/
/* XPS PS/2 data transmission calls */
/************************************/

84 85 86 87 88 89 90
/**
 * xps2_recv() - attempts to receive a byte from the PS/2 port.
 * @drvdata:	pointer to ps2 device private data structure
 * @byte:	address where the read data will be copied
 *
 * If there is any data available in the PS/2 receiver, this functions reads
 * the data, otherwise it returns error.
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
 */
static int xps2_recv(struct xps2data *drvdata, u8 *byte)
{
	u32 sr;
	int status = -1;

	/* 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;
	}

	return status;
}

/*********************/
/* Interrupt handler */
/*********************/
static irqreturn_t xps2_interrupt(int irq, void *dev_id)
{
	struct xps2data *drvdata = dev_id;
	u32 intr_sr;
	u8 c;
	int status;

	/* 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)
123
		dev_warn(drvdata->dev, "receive overrun error\n");
124 125

	if (intr_sr & XPS2_IPIXR_RX_ERR)
126
		drvdata->flags |= SERIO_PARITY;
127 128

	if (intr_sr & (XPS2_IPIXR_TX_NOACK | XPS2_IPIXR_WDT_TOUT))
129
		drvdata->flags |= SERIO_TIMEOUT;
130 131

	if (intr_sr & XPS2_IPIXR_RX_FULL) {
132
		status = xps2_recv(drvdata, &c);
133 134 135

		/* Error, if a byte is not received */
		if (status) {
136
			dev_err(drvdata->dev,
137
				"wrong rcvd byte count (%d)\n", status);
138
		} else {
139
			serio_interrupt(drvdata->serio, c, drvdata->flags);
140
			drvdata->flags = 0;
141 142 143 144 145 146 147 148 149 150
		}
	}

	return IRQ_HANDLED;
}

/*******************/
/* serio callbacks */
/*******************/

151 152 153 154 155 156 157 158 159
/**
 * sxps2_write() - sends a byte out through the PS/2 port.
 * @pserio:	pointer to the serio structure of the PS/2 port
 * @c:		data that needs to be written to the PS/2 port
 *
 * This function checks if the PS/2 transmitter is empty and sends a byte.
 * Otherwise it returns error. Transmission fails only when nothing is connected
 * to the PS/2 port. Thats why, we do not try to resend the data in case of a
 * failure.
160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181
 */
static int sxps2_write(struct serio *pserio, unsigned char c)
{
	struct xps2data *drvdata = pserio->port_data;
	unsigned long flags;
	u32 sr;
	int status = -1;

	spin_lock_irqsave(&drvdata->lock, flags);

	/* 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)) {
		out_be32(drvdata->base_address + XPS2_TX_DATA_OFFSET, c);
		status = 0;
	}

	spin_unlock_irqrestore(&drvdata->lock, flags);

	return status;
}

182 183 184 185 186
/**
 * sxps2_open() - called when a port is opened by the higher layer.
 * @pserio:	pointer to the serio structure of the PS/2 device
 *
 * This function requests irq and enables interrupts for the PS/2 device.
187 188 189 190
 */
static int sxps2_open(struct serio *pserio)
{
	struct xps2data *drvdata = pserio->port_data;
191 192
	int error;
	u8 c;
193

194
	error = request_irq(drvdata->irq, &xps2_interrupt, 0,
195
				DRIVER_NAME, drvdata);
196
	if (error) {
197
		dev_err(drvdata->dev,
198 199
			"Couldn't allocate interrupt %d\n", drvdata->irq);
		return error;
200 201 202 203 204
	}

	/* start reception by enabling the interrupts */
	out_be32(drvdata->base_address + XPS2_GIER_OFFSET, XPS2_GIER_GIE_MASK);
	out_be32(drvdata->base_address + XPS2_IPIER_OFFSET, XPS2_IPIXR_RX_ALL);
205
	(void)xps2_recv(drvdata, &c);
206 207 208 209

	return 0;		/* success */
}

210 211 212 213 214
/**
 * sxps2_close() - frees the interrupt.
 * @pserio:	pointer to the serio structure of the PS/2 device
 *
 * This function frees the irq and disables interrupts for the PS/2 device.
215 216 217 218 219 220 221 222 223 224 225
 */
static void sxps2_close(struct serio *pserio)
{
	struct xps2data *drvdata = pserio->port_data;

	/* Disable the PS2 interrupts */
	out_be32(drvdata->base_address + XPS2_GIER_OFFSET, 0x00);
	out_be32(drvdata->base_address + XPS2_IPIER_OFFSET, 0x00);
	free_irq(drvdata->irq, drvdata);
}

226 227 228
/**
 * xps2_of_probe - probe method for the PS/2 device.
 * @of_dev:	pointer to OF device structure
L
Lucas De Marchi 已提交
229
 * @match:	pointer to the structure used for matching a device
230 231 232 233 234 235
 *
 * This function probes the PS/2 device in the device tree.
 * It initializes the driver data structure and the hardware.
 * It returns 0, if the driver is bound to the PS/2 device, or a negative
 * value if there is an error.
 */
236
static int __devinit xps2_of_probe(struct platform_device *ofdev)
237
{
238 239
	struct resource r_irq; /* Interrupt resources */
	struct resource r_mem; /* IO mem resources */
240 241
	struct xps2data *drvdata;
	struct serio *serio;
242 243 244 245 246
	struct device *dev = &ofdev->dev;
	resource_size_t remap_size, phys_addr;
	int error;

	dev_info(dev, "Device Tree Probing \'%s\'\n",
247
			ofdev->dev.of_node->name);
248

249
	/* Get iospace for the device */
250
	error = of_address_to_resource(ofdev->dev.of_node, 0, &r_mem);
251 252 253 254
	if (error) {
		dev_err(dev, "invalid address\n");
		return error;
	}
255

256
	/* Get IRQ for the device */
257
	if (!of_irq_to_resource(ofdev->dev.of_node, 0, &r_irq)) {
258 259
		dev_err(dev, "no IRQ found\n");
		return -ENODEV;
260 261 262
	}

	drvdata = kzalloc(sizeof(struct xps2data), GFP_KERNEL);
263 264 265 266
	serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
	if (!drvdata || !serio) {
		error = -ENOMEM;
		goto failed1;
267 268 269
	}

	spin_lock_init(&drvdata->lock);
270
	drvdata->irq = r_irq.start;
271 272
	drvdata->serio = serio;
	drvdata->dev = dev;
273 274

	phys_addr = r_mem.start;
275
	remap_size = resource_size(&r_mem);
276 277 278 279
	if (!request_mem_region(phys_addr, remap_size, DRIVER_NAME)) {
		dev_err(dev, "Couldn't lock memory region at 0x%08llX\n",
			(unsigned long long)phys_addr);
		error = -EBUSY;
280 281 282 283
		goto failed1;
	}

	/* Fill in configuration data and add them to the list */
284
	drvdata->base_address = ioremap(phys_addr, remap_size);
285
	if (drvdata->base_address == NULL) {
286 287 288
		dev_err(dev, "Couldn't ioremap memory at 0x%08llX\n",
			(unsigned long long)phys_addr);
		error = -EFAULT;
289 290 291 292 293 294 295 296 297 298
		goto failed2;
	}

	/* Disable all the interrupts, just in case */
	out_be32(drvdata->base_address + XPS2_IPIER_OFFSET, 0);

	/* Reset the PS2 device and abort any current transaction, to make sure
	 * we have the PS2 in a good state */
	out_be32(drvdata->base_address + XPS2_SRST_OFFSET, XPS2_SRST_RESET);

299 300 301
	dev_info(dev, "Xilinx PS2 at 0x%08llX mapped to 0x%p, irq=%d\n",
		 (unsigned long long)phys_addr, drvdata->base_address,
		 drvdata->irq);
302 303 304 305 306 307 308 309

	serio->id.type = SERIO_8042;
	serio->write = sxps2_write;
	serio->open = sxps2_open;
	serio->close = sxps2_close;
	serio->port_data = drvdata;
	serio->dev.parent = dev;
	snprintf(serio->name, sizeof(serio->name),
310
		 "Xilinx XPS PS/2 at %08llX", (unsigned long long)phys_addr);
311
	snprintf(serio->phys, sizeof(serio->phys),
312 313
		 "xilinxps2/serio at %08llX", (unsigned long long)phys_addr);

314 315
	serio_register_port(serio);

316
	platform_set_drvdata(ofdev, drvdata);
317 318 319
	return 0;		/* success */

failed2:
320
	release_mem_region(phys_addr, remap_size);
321
failed1:
322
	kfree(serio);
323 324
	kfree(drvdata);

325
	return error;
326 327
}

328 329 330 331 332 333 334 335
/**
 * xps2_of_remove - unbinds the driver from the PS/2 device.
 * @of_dev:	pointer to OF device structure
 *
 * This function is called if a device is physically removed from the system or
 * if the driver module is being unloaded. It frees any resources allocated to
 * the device.
 */
336
static int __devexit xps2_of_remove(struct platform_device *of_dev)
337
{
338
	struct xps2data *drvdata = platform_get_drvdata(of_dev);
339
	struct resource r_mem; /* IO mem resources */
340

341
	serio_unregister_port(drvdata->serio);
342
	iounmap(drvdata->base_address);
343 344

	/* Get iospace of the device */
345
	if (of_address_to_resource(of_dev->dev.of_node, 0, &r_mem))
346
		dev_err(drvdata->dev, "invalid address\n");
347
	else
348
		release_mem_region(r_mem.start, resource_size(&r_mem));
349

350 351
	kfree(drvdata);

352
	platform_set_drvdata(of_dev, NULL);
353

354
	return 0;
355 356 357
}

/* Match table for of_platform binding */
358
static const struct of_device_id xps2_of_match[] __devinitconst = {
359 360 361 362 363
	{ .compatible = "xlnx,xps-ps2-1.00.a", },
	{ /* end of list */ },
};
MODULE_DEVICE_TABLE(of, xps2_of_match);

364
static struct platform_driver xps2_of_driver = {
365 366 367 368 369
	.driver = {
		.name = DRIVER_NAME,
		.owner = THIS_MODULE,
		.of_match_table = xps2_of_match,
	},
370 371 372
	.probe		= xps2_of_probe,
	.remove		= __devexit_p(xps2_of_remove),
};
373
module_platform_driver(xps2_of_driver);
374 375 376 377 378

MODULE_AUTHOR("Xilinx, Inc.");
MODULE_DESCRIPTION("Xilinx XPS PS/2 driver");
MODULE_LICENSE("GPL");