11da177e4SLinus Torvalds #ifndef _SERIO_H 21da177e4SLinus Torvalds #define _SERIO_H 31da177e4SLinus Torvalds 41da177e4SLinus Torvalds /* 51da177e4SLinus Torvalds * Copyright (C) 1999-2002 Vojtech Pavlik 61da177e4SLinus Torvalds * 71da177e4SLinus Torvalds * This program is free software; you can redistribute it and/or modify it 81da177e4SLinus Torvalds * under the terms of the GNU General Public License version 2 as published by 91da177e4SLinus Torvalds * the Free Software Foundation. 101da177e4SLinus Torvalds */ 111da177e4SLinus Torvalds 121da177e4SLinus Torvalds #include <linux/ioctl.h> 131da177e4SLinus Torvalds 141da177e4SLinus Torvalds #define SPIOCSTYPE _IOW('q', 0x01, unsigned long) 151da177e4SLinus Torvalds 161da177e4SLinus Torvalds #ifdef __KERNEL__ 171da177e4SLinus Torvalds 181da177e4SLinus Torvalds #include <linux/interrupt.h> 191da177e4SLinus Torvalds #include <linux/list.h> 201da177e4SLinus Torvalds #include <linux/spinlock.h> 211da177e4SLinus Torvalds #include <linux/device.h> 221da177e4SLinus Torvalds #include <linux/mod_devicetable.h> 231da177e4SLinus Torvalds 241da177e4SLinus Torvalds struct serio { 251da177e4SLinus Torvalds void *port_data; 261da177e4SLinus Torvalds 271da177e4SLinus Torvalds char name[32]; 281da177e4SLinus Torvalds char phys[32]; 291da177e4SLinus Torvalds 301da177e4SLinus Torvalds unsigned int manual_bind; 311da177e4SLinus Torvalds 321da177e4SLinus Torvalds struct serio_device_id id; 331da177e4SLinus Torvalds 341da177e4SLinus Torvalds spinlock_t lock; /* protects critical sections from port's interrupt handler */ 351da177e4SLinus Torvalds 361da177e4SLinus Torvalds int (*write)(struct serio *, unsigned char); 371da177e4SLinus Torvalds int (*open)(struct serio *); 381da177e4SLinus Torvalds void (*close)(struct serio *); 391da177e4SLinus Torvalds int (*start)(struct serio *); 401da177e4SLinus Torvalds void (*stop)(struct serio *); 411da177e4SLinus Torvalds 421da177e4SLinus Torvalds struct serio *parent, *child; 431da177e4SLinus Torvalds 441da177e4SLinus Torvalds struct serio_driver *drv; /* accessed from interrupt, must be protected by serio->lock and serio->sem */ 451da177e4SLinus Torvalds struct semaphore drv_sem; /* protects serio->drv so attributes can pin driver */ 461da177e4SLinus Torvalds 471da177e4SLinus Torvalds struct device dev; 481da177e4SLinus Torvalds unsigned int registered; /* port has been fully registered with driver core */ 491da177e4SLinus Torvalds 501da177e4SLinus Torvalds struct list_head node; 511da177e4SLinus Torvalds }; 521da177e4SLinus Torvalds #define to_serio_port(d) container_of(d, struct serio, dev) 531da177e4SLinus Torvalds 541da177e4SLinus Torvalds struct serio_driver { 551da177e4SLinus Torvalds void *private; 561da177e4SLinus Torvalds char *description; 571da177e4SLinus Torvalds 581da177e4SLinus Torvalds struct serio_device_id *id_table; 591da177e4SLinus Torvalds unsigned int manual_bind; 601da177e4SLinus Torvalds 611da177e4SLinus Torvalds void (*write_wakeup)(struct serio *); 621da177e4SLinus Torvalds irqreturn_t (*interrupt)(struct serio *, unsigned char, 631da177e4SLinus Torvalds unsigned int, struct pt_regs *); 641da177e4SLinus Torvalds int (*connect)(struct serio *, struct serio_driver *drv); 651da177e4SLinus Torvalds int (*reconnect)(struct serio *); 661da177e4SLinus Torvalds void (*disconnect)(struct serio *); 671da177e4SLinus Torvalds void (*cleanup)(struct serio *); 681da177e4SLinus Torvalds 691da177e4SLinus Torvalds struct device_driver driver; 701da177e4SLinus Torvalds }; 711da177e4SLinus Torvalds #define to_serio_driver(d) container_of(d, struct serio_driver, driver) 721da177e4SLinus Torvalds 731da177e4SLinus Torvalds int serio_open(struct serio *serio, struct serio_driver *drv); 741da177e4SLinus Torvalds void serio_close(struct serio *serio); 751da177e4SLinus Torvalds void serio_rescan(struct serio *serio); 761da177e4SLinus Torvalds void serio_reconnect(struct serio *serio); 771da177e4SLinus Torvalds irqreturn_t serio_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs); 781da177e4SLinus Torvalds 791da177e4SLinus Torvalds void __serio_register_port(struct serio *serio, struct module *owner); 801da177e4SLinus Torvalds static inline void serio_register_port(struct serio *serio) 811da177e4SLinus Torvalds { 821da177e4SLinus Torvalds __serio_register_port(serio, THIS_MODULE); 831da177e4SLinus Torvalds } 841da177e4SLinus Torvalds 851da177e4SLinus Torvalds void serio_unregister_port(struct serio *serio); 86*dbf4ccd6SDmitry Torokhov void serio_unregister_child_port(struct serio *serio); 871da177e4SLinus Torvalds void __serio_unregister_port_delayed(struct serio *serio, struct module *owner); 881da177e4SLinus Torvalds static inline void serio_unregister_port_delayed(struct serio *serio) 891da177e4SLinus Torvalds { 901da177e4SLinus Torvalds __serio_unregister_port_delayed(serio, THIS_MODULE); 911da177e4SLinus Torvalds } 921da177e4SLinus Torvalds 931da177e4SLinus Torvalds void __serio_register_driver(struct serio_driver *drv, struct module *owner); 941da177e4SLinus Torvalds static inline void serio_register_driver(struct serio_driver *drv) 951da177e4SLinus Torvalds { 961da177e4SLinus Torvalds __serio_register_driver(drv, THIS_MODULE); 971da177e4SLinus Torvalds } 981da177e4SLinus Torvalds 991da177e4SLinus Torvalds void serio_unregister_driver(struct serio_driver *drv); 1001da177e4SLinus Torvalds 1011da177e4SLinus Torvalds static inline int serio_write(struct serio *serio, unsigned char data) 1021da177e4SLinus Torvalds { 1031da177e4SLinus Torvalds if (serio->write) 1041da177e4SLinus Torvalds return serio->write(serio, data); 1051da177e4SLinus Torvalds else 1061da177e4SLinus Torvalds return -1; 1071da177e4SLinus Torvalds } 1081da177e4SLinus Torvalds 1091da177e4SLinus Torvalds static inline void serio_drv_write_wakeup(struct serio *serio) 1101da177e4SLinus Torvalds { 1111da177e4SLinus Torvalds if (serio->drv && serio->drv->write_wakeup) 1121da177e4SLinus Torvalds serio->drv->write_wakeup(serio); 1131da177e4SLinus Torvalds } 1141da177e4SLinus Torvalds 1151da177e4SLinus Torvalds static inline void serio_cleanup(struct serio *serio) 1161da177e4SLinus Torvalds { 1171da177e4SLinus Torvalds if (serio->drv && serio->drv->cleanup) 1181da177e4SLinus Torvalds serio->drv->cleanup(serio); 1191da177e4SLinus Torvalds } 1201da177e4SLinus Torvalds 1211da177e4SLinus Torvalds /* 1221da177e4SLinus Torvalds * Use the following fucntions to manipulate serio's per-port 1231da177e4SLinus Torvalds * driver-specific data. 1241da177e4SLinus Torvalds */ 1251da177e4SLinus Torvalds static inline void *serio_get_drvdata(struct serio *serio) 1261da177e4SLinus Torvalds { 1271da177e4SLinus Torvalds return dev_get_drvdata(&serio->dev); 1281da177e4SLinus Torvalds } 1291da177e4SLinus Torvalds 1301da177e4SLinus Torvalds static inline void serio_set_drvdata(struct serio *serio, void *data) 1311da177e4SLinus Torvalds { 1321da177e4SLinus Torvalds dev_set_drvdata(&serio->dev, data); 1331da177e4SLinus Torvalds } 1341da177e4SLinus Torvalds 1351da177e4SLinus Torvalds /* 1361da177e4SLinus Torvalds * Use the following fucntions to protect critical sections in 1371da177e4SLinus Torvalds * driver code from port's interrupt handler 1381da177e4SLinus Torvalds */ 1391da177e4SLinus Torvalds static inline void serio_pause_rx(struct serio *serio) 1401da177e4SLinus Torvalds { 1411da177e4SLinus Torvalds spin_lock_irq(&serio->lock); 1421da177e4SLinus Torvalds } 1431da177e4SLinus Torvalds 1441da177e4SLinus Torvalds static inline void serio_continue_rx(struct serio *serio) 1451da177e4SLinus Torvalds { 1461da177e4SLinus Torvalds spin_unlock_irq(&serio->lock); 1471da177e4SLinus Torvalds } 1481da177e4SLinus Torvalds 1491da177e4SLinus Torvalds /* 1501da177e4SLinus Torvalds * Use the following fucntions to pin serio's driver in process context 1511da177e4SLinus Torvalds */ 1521da177e4SLinus Torvalds static inline int serio_pin_driver(struct serio *serio) 1531da177e4SLinus Torvalds { 1541da177e4SLinus Torvalds return down_interruptible(&serio->drv_sem); 1551da177e4SLinus Torvalds } 1561da177e4SLinus Torvalds 157*dbf4ccd6SDmitry Torokhov static inline void serio_pin_driver_uninterruptible(struct serio *serio) 158*dbf4ccd6SDmitry Torokhov { 159*dbf4ccd6SDmitry Torokhov down(&serio->drv_sem); 160*dbf4ccd6SDmitry Torokhov } 161*dbf4ccd6SDmitry Torokhov 1621da177e4SLinus Torvalds static inline void serio_unpin_driver(struct serio *serio) 1631da177e4SLinus Torvalds { 1641da177e4SLinus Torvalds up(&serio->drv_sem); 1651da177e4SLinus Torvalds } 1661da177e4SLinus Torvalds 1671da177e4SLinus Torvalds 1681da177e4SLinus Torvalds #endif 1691da177e4SLinus Torvalds 1701da177e4SLinus Torvalds /* 1711da177e4SLinus Torvalds * bit masks for use in "interrupt" flags (3rd argument) 1721da177e4SLinus Torvalds */ 1731da177e4SLinus Torvalds #define SERIO_TIMEOUT 1 1741da177e4SLinus Torvalds #define SERIO_PARITY 2 1751da177e4SLinus Torvalds #define SERIO_FRAME 4 1761da177e4SLinus Torvalds 1771da177e4SLinus Torvalds /* 1781da177e4SLinus Torvalds * Serio types 1791da177e4SLinus Torvalds */ 1801da177e4SLinus Torvalds #define SERIO_XT 0x00 1811da177e4SLinus Torvalds #define SERIO_8042 0x01 1821da177e4SLinus Torvalds #define SERIO_RS232 0x02 1831da177e4SLinus Torvalds #define SERIO_HIL_MLC 0x03 1841da177e4SLinus Torvalds #define SERIO_PS_PSTHRU 0x05 1851da177e4SLinus Torvalds #define SERIO_8042_XL 0x06 1861da177e4SLinus Torvalds 1871da177e4SLinus Torvalds /* 1881da177e4SLinus Torvalds * Serio types 1891da177e4SLinus Torvalds */ 1901da177e4SLinus Torvalds #define SERIO_UNKNOWN 0x00 1911da177e4SLinus Torvalds #define SERIO_MSC 0x01 1921da177e4SLinus Torvalds #define SERIO_SUN 0x02 1931da177e4SLinus Torvalds #define SERIO_MS 0x03 1941da177e4SLinus Torvalds #define SERIO_MP 0x04 1951da177e4SLinus Torvalds #define SERIO_MZ 0x05 1961da177e4SLinus Torvalds #define SERIO_MZP 0x06 1971da177e4SLinus Torvalds #define SERIO_MZPP 0x07 1981da177e4SLinus Torvalds #define SERIO_VSXXXAA 0x08 1991da177e4SLinus Torvalds #define SERIO_SUNKBD 0x10 2001da177e4SLinus Torvalds #define SERIO_WARRIOR 0x18 2011da177e4SLinus Torvalds #define SERIO_SPACEORB 0x19 2021da177e4SLinus Torvalds #define SERIO_MAGELLAN 0x1a 2031da177e4SLinus Torvalds #define SERIO_SPACEBALL 0x1b 2041da177e4SLinus Torvalds #define SERIO_GUNZE 0x1c 2051da177e4SLinus Torvalds #define SERIO_IFORCE 0x1d 2061da177e4SLinus Torvalds #define SERIO_STINGER 0x1e 2071da177e4SLinus Torvalds #define SERIO_NEWTON 0x1f 2081da177e4SLinus Torvalds #define SERIO_STOWAWAY 0x20 2091da177e4SLinus Torvalds #define SERIO_H3600 0x21 2101da177e4SLinus Torvalds #define SERIO_PS2SER 0x22 2111da177e4SLinus Torvalds #define SERIO_TWIDKBD 0x23 2121da177e4SLinus Torvalds #define SERIO_TWIDJOY 0x24 2131da177e4SLinus Torvalds #define SERIO_HIL 0x25 2141da177e4SLinus Torvalds #define SERIO_SNES232 0x26 2151da177e4SLinus Torvalds #define SERIO_SEMTECH 0x27 2161da177e4SLinus Torvalds #define SERIO_LKKBD 0x28 2171da177e4SLinus Torvalds #define SERIO_ELO 0x29 2181da177e4SLinus Torvalds #define SERIO_MICROTOUCH 0x30 2191da177e4SLinus Torvalds 2201da177e4SLinus Torvalds #endif 221