aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiri Slaby <jirislaby@gmail.com>2007-05-08 03:31:45 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-08 14:15:14 -0400
commitcef2cf07273d12ac3453d2baff096423f17b7403 (patch)
tree807ce95b91d1a09f449d61301f1148c85d7818db
parent6f7f02e78a75a09195d963e0392b195bc2d55c5c (diff)
Misc: add sensable phantom driver
Add sensable phantom driver Signed-off-by: Jiri Slaby <jirislaby@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--Documentation/ioctl-number.txt3
-rw-r--r--MAINTAINERS5
-rw-r--r--drivers/misc/Kconfig9
-rw-r--r--drivers/misc/Makefile1
-rw-r--r--drivers/misc/phantom.c463
-rw-r--r--include/linux/Kbuild1
-rw-r--r--include/linux/phantom.h42
7 files changed, 523 insertions, 1 deletions
diff --git a/Documentation/ioctl-number.txt b/Documentation/ioctl-number.txt
index 8f750c0efe..3de7d379cf 100644
--- a/Documentation/ioctl-number.txt
+++ b/Documentation/ioctl-number.txt
@@ -138,7 +138,8 @@ Code Seq# Include File Comments
138'm' 00-1F net/irda/irmod.h conflict! 138'm' 00-1F net/irda/irmod.h conflict!
139'n' 00-7F linux/ncp_fs.h 139'n' 00-7F linux/ncp_fs.h
140'n' E0-FF video/matrox.h matroxfb 140'n' E0-FF video/matrox.h matroxfb
141'p' 00-3F linux/mc146818rtc.h 141'p' 00-0F linux/phantom.h conflict! (OpenHaptics needs this)
142'p' 00-3F linux/mc146818rtc.h conflict!
142'p' 40-7F linux/nvram.h 143'p' 40-7F linux/nvram.h
143'p' 80-9F user-space parport 144'p' 80-9F user-space parport
144 <mailto:tim@cyberelk.net> 145 <mailto:tim@cyberelk.net>
diff --git a/MAINTAINERS b/MAINTAINERS
index 36e48a4e29..69f3f66091 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3108,6 +3108,11 @@ L: selinux@tycho.nsa.gov (subscribers-only, general discussion)
3108W: http://www.nsa.gov/selinux 3108W: http://www.nsa.gov/selinux
3109S: Supported 3109S: Supported
3110 3110
3111SENSABLE PHANTOM
3112P: Jiri Slaby
3113M: jirislaby@gmail.com
3114S: Maintained
3115
3111SERIAL ATA (SATA) SUBSYSTEM: 3116SERIAL ATA (SATA) SUBSYSTEM:
3112P: Jeff Garzik 3117P: Jeff Garzik
3113M: jgarzik@pobox.com 3118M: jgarzik@pobox.com
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index bfb02c1a45..877e7909a0 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -25,6 +25,15 @@ config IBM_ASM
25 information on the specific driver level and support statement 25 information on the specific driver level and support statement
26 for your IBM server. 26 for your IBM server.
27 27
28config PHANTOM
29 tristate "Sensable PHANToM"
30 depends on PCI
31 help
32 Say Y here if you want to build a driver for Sensable PHANToM device.
33
34 If you choose to build module, its name will be phantom. If unsure,
35 say N here.
36
28 37
29 If unsure, say N. 38 If unsure, say N.
30 39
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index ece6baf76b..5b6d46de00 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_BLINK) += blink.o
11obj-$(CONFIG_LKDTM) += lkdtm.o 11obj-$(CONFIG_LKDTM) += lkdtm.o
12obj-$(CONFIG_TIFM_CORE) += tifm_core.o 12obj-$(CONFIG_TIFM_CORE) += tifm_core.o
13obj-$(CONFIG_TIFM_7XX1) += tifm_7xx1.o 13obj-$(CONFIG_TIFM_7XX1) += tifm_7xx1.o
14obj-$(CONFIG_PHANTOM) += phantom.o
14obj-$(CONFIG_SGI_IOC4) += ioc4.o 15obj-$(CONFIG_SGI_IOC4) += ioc4.o
15obj-$(CONFIG_SONY_LAPTOP) += sony-laptop.o 16obj-$(CONFIG_SONY_LAPTOP) += sony-laptop.o
16obj-$(CONFIG_THINKPAD_ACPI) += thinkpad_acpi.o 17obj-$(CONFIG_THINKPAD_ACPI) += thinkpad_acpi.o
diff --git a/drivers/misc/phantom.c b/drivers/misc/phantom.c
new file mode 100644
index 0000000000..35b139b0e5
--- /dev/null
+++ b/drivers/misc/phantom.c
@@ -0,0 +1,463 @@
1/*
2 * Copyright (C) 2005-2007 Jiri Slaby <jirislaby@gmail.com>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * You need an userspace library to cooperate with this driver. It (and other
10 * info) may be obtained here:
11 * http://www.fi.muni.cz/~xslaby/phantom.html
12 */
13
14#include <linux/kernel.h>
15#include <linux/module.h>
16#include <linux/device.h>
17#include <linux/pci.h>
18#include <linux/fs.h>
19#include <linux/poll.h>
20#include <linux/interrupt.h>
21#include <linux/cdev.h>
22#include <linux/phantom.h>
23
24#include <asm/atomic.h>
25#include <asm/io.h>
26
27#define PHANTOM_VERSION "n0.9.5"
28
29#define PHANTOM_MAX_MINORS 8
30
31#define PHN_IRQCTL 0x4c /* irq control in caddr space */
32
33#define PHB_RUNNING 1
34
35static struct class *phantom_class;
36static int phantom_major;
37
38struct phantom_device {
39 unsigned int opened;
40 void __iomem *caddr;
41 u32 __iomem *iaddr;
42 u32 __iomem *oaddr;
43 unsigned long status;
44 atomic_t counter;
45
46 wait_queue_head_t wait;
47 struct cdev cdev;
48
49 struct mutex open_lock;
50};
51
52static unsigned char phantom_devices[PHANTOM_MAX_MINORS];
53
54static int phantom_status(struct phantom_device *dev, unsigned long newstat)
55{
56 pr_debug("phantom_status %lx %lx\n", dev->status, newstat);
57
58 if (!(dev->status & PHB_RUNNING) && (newstat & PHB_RUNNING)) {
59 atomic_set(&dev->counter, 0);
60 iowrite32(PHN_CTL_IRQ, dev->iaddr + PHN_CONTROL);
61 iowrite32(0x43, dev->caddr + PHN_IRQCTL);
62 } else if ((dev->status & PHB_RUNNING) && !(newstat & PHB_RUNNING))
63 iowrite32(0, dev->caddr + PHN_IRQCTL);
64
65 dev->status = newstat;
66
67 return 0;
68}
69
70/*
71 * File ops
72 */
73
74static int phantom_ioctl(struct inode *inode, struct file *file, u_int cmd,
75 u_long arg)
76{
77 struct phantom_device *dev = file->private_data;
78 struct phm_regs rs;
79 struct phm_reg r;
80 void __user *argp = (void __user *)arg;
81 unsigned int i;
82
83 if (_IOC_TYPE(cmd) != PH_IOC_MAGIC ||
84 _IOC_NR(cmd) > PH_IOC_MAXNR)
85 return -ENOTTY;
86
87 switch (cmd) {
88 case PHN_SET_REG:
89 if (copy_from_user(&r, argp, sizeof(r)))
90 return -EFAULT;
91
92 if (r.reg > 7)
93 return -EINVAL;
94
95 if (r.reg == PHN_CONTROL && (r.value & PHN_CTL_IRQ) &&
96 phantom_status(dev, dev->status | PHB_RUNNING))
97 return -ENODEV;
98
99 pr_debug("phantom: writing %x to %u\n", r.value, r.reg);
100 iowrite32(r.value, dev->iaddr + r.reg);
101
102 if (r.reg == PHN_CONTROL && !(r.value & PHN_CTL_IRQ))
103 phantom_status(dev, dev->status & ~PHB_RUNNING);
104 break;
105 case PHN_SET_REGS:
106 if (copy_from_user(&rs, argp, sizeof(rs)))
107 return -EFAULT;
108
109 pr_debug("phantom: SRS %u regs %x\n", rs.count, rs.mask);
110 for (i = 0; i < min(rs.count, 8U); i++)
111 if ((1 << i) & rs.mask)
112 iowrite32(rs.values[i], dev->oaddr + i);
113 break;
114 case PHN_GET_REG:
115 if (copy_from_user(&r, argp, sizeof(r)))
116 return -EFAULT;
117
118 if (r.reg > 7)
119 return -EINVAL;
120
121 r.value = ioread32(dev->iaddr + r.reg);
122
123 if (copy_to_user(argp, &r, sizeof(r)))
124 return -EFAULT;
125 break;
126 case PHN_GET_REGS:
127 if (copy_from_user(&rs, argp, sizeof(rs)))
128 return -EFAULT;
129
130 pr_debug("phantom: GRS %u regs %x\n", rs.count, rs.mask);
131 for (i = 0; i < min(rs.count, 8U); i++)
132 if ((1 << i) & rs.mask)
133 rs.values[i] = ioread32(dev->iaddr + i);
134
135 if (copy_to_user(argp, &rs, sizeof(rs)))
136 return -EFAULT;
137 break;
138 default:
139 return -ENOTTY;
140 }
141
142 return 0;
143}
144
145static int phantom_open(struct inode *inode, struct file *file)
146{
147 struct phantom_device *dev = container_of(inode->i_cdev,
148 struct phantom_device, cdev);
149
150