diff options
author | David Herrmann <dh.herrmann@googlemail.com> | 2011-11-17 08:12:12 -0500 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2011-11-22 17:11:10 -0500 |
commit | 43d782ae80b82667d66010d0d82aa80893a48d12 (patch) | |
tree | d757170b529aed0068bd987522b5c3e1aa32babe | |
parent | 1d3452c63d4b62329d34d7634f67a3dbec21ca87 (diff) |
HID: wiimote: Allow direct DRM debug access
Keep track of current drm and add new debugfs file which reads or writes the
current DRM.
Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
-rw-r--r-- | drivers/hid/hid-wiimote-core.c | 2 | ||||
-rw-r--r-- | drivers/hid/hid-wiimote-debug.c | 107 | ||||
-rw-r--r-- | drivers/hid/hid-wiimote.h | 2 |
3 files changed, 107 insertions, 4 deletions
diff --git a/drivers/hid/hid-wiimote-core.c b/drivers/hid/hid-wiimote-core.c index 2fd2f0337b8..745667e8b61 100644 --- a/drivers/hid/hid-wiimote-core.c +++ b/drivers/hid/hid-wiimote-core.c | |||
@@ -238,6 +238,7 @@ void wiiproto_req_drm(struct wiimote_data *wdata, __u8 drm) | |||
238 | cmd[1] = 0; | 238 | cmd[1] = 0; |
239 | cmd[2] = drm; | 239 | cmd[2] = drm; |
240 | 240 | ||
241 | wdata->state.drm = drm; | ||
241 | wiiproto_keep_rumble(wdata, &cmd[1]); | 242 | wiiproto_keep_rumble(wdata, &cmd[1]); |
242 | wiimote_queue(wdata, cmd, sizeof(cmd)); | 243 | wiimote_queue(wdata, cmd, sizeof(cmd)); |
243 | } | 244 | } |
@@ -1141,6 +1142,7 @@ static struct wiimote_data *wiimote_create(struct hid_device *hdev) | |||
1141 | spin_lock_init(&wdata->state.lock); | 1142 | spin_lock_init(&wdata->state.lock); |
1142 | init_completion(&wdata->state.ready); | 1143 | init_completion(&wdata->state.ready); |
1143 | mutex_init(&wdata->state.sync); | 1144 | mutex_init(&wdata->state.sync); |
1145 | wdata->state.drm = WIIPROTO_REQ_DRM_K; | ||
1144 | 1146 | ||
1145 | return wdata; | 1147 | return wdata; |
1146 | 1148 | ||
diff --git a/drivers/hid/hid-wiimote-debug.c b/drivers/hid/hid-wiimote-debug.c index f81243c8679..17dabc1f339 100644 --- a/drivers/hid/hid-wiimote-debug.c +++ b/drivers/hid/hid-wiimote-debug.c | |||
@@ -12,6 +12,7 @@ | |||
12 | 12 | ||
13 | #include <linux/debugfs.h> | 13 | #include <linux/debugfs.h> |
14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
15 | #include <linux/seq_file.h> | ||
15 | #include <linux/spinlock.h> | 16 | #include <linux/spinlock.h> |
16 | #include <linux/uaccess.h> | 17 | #include <linux/uaccess.h> |
17 | #include "hid-wiimote.h" | 18 | #include "hid-wiimote.h" |
@@ -19,6 +20,7 @@ | |||
19 | struct wiimote_debug { | 20 | struct wiimote_debug { |
20 | struct wiimote_data *wdata; | 21 | struct wiimote_data *wdata; |
21 | struct dentry *eeprom; | 22 | struct dentry *eeprom; |
23 | struct dentry *drm; | ||
22 | }; | 24 | }; |
23 | 25 | ||
24 | static int wiidebug_eeprom_open(struct inode *i, struct file *f) | 26 | static int wiidebug_eeprom_open(struct inode *i, struct file *f) |
@@ -86,10 +88,97 @@ static const struct file_operations wiidebug_eeprom_fops = { | |||
86 | .llseek = generic_file_llseek, | 88 | .llseek = generic_file_llseek, |
87 | }; | 89 | }; |
88 | 90 | ||
91 | static const char *wiidebug_drmmap[] = { | ||
92 | [WIIPROTO_REQ_NULL] = "NULL", | ||
93 | [WIIPROTO_REQ_DRM_K] = "K", | ||
94 | [WIIPROTO_REQ_DRM_KA] = "KA", | ||
95 | [WIIPROTO_REQ_DRM_KE] = "KE", | ||
96 | [WIIPROTO_REQ_DRM_KAI] = "KAI", | ||
97 | [WIIPROTO_REQ_DRM_KEE] = "KEE", | ||
98 | [WIIPROTO_REQ_DRM_KAE] = "KAE", | ||
99 | [WIIPROTO_REQ_DRM_KIE] = "KIE", | ||
100 | [WIIPROTO_REQ_DRM_KAIE] = "KAIE", | ||
101 | [WIIPROTO_REQ_DRM_E] = "E", | ||
102 | [WIIPROTO_REQ_DRM_SKAI1] = "SKAI1", | ||
103 | [WIIPROTO_REQ_DRM_SKAI2] = "SKAI2", | ||
104 | [WIIPROTO_REQ_MAX] = NULL | ||
105 | }; | ||
106 | |||
107 | static int wiidebug_drm_show(struct seq_file *f, void *p) | ||
108 | { | ||
109 | struct wiimote_debug *dbg = f->private; | ||
110 | const char *str = NULL; | ||
111 | unsigned long flags; | ||
112 | __u8 drm; | ||
113 | |||
114 | spin_lock_irqsave(&dbg->wdata->state.lock, flags); | ||
115 | drm = dbg->wdata->state.drm; | ||
116 | spin_unlock_irqrestore(&dbg->wdata->state.lock, flags); | ||
117 | |||
118 | if (drm < WIIPROTO_REQ_MAX) | ||
119 | str = wiidebug_drmmap[drm]; | ||
120 | if (!str) | ||
121 | str = "unknown"; | ||
122 | |||
123 | seq_printf(f, "%s\n", str); | ||
124 | |||
125 | return 0; | ||
126 | } | ||
127 | |||
128 | static int wiidebug_drm_open(struct inode *i, struct file *f) | ||
129 | { | ||
130 | return single_open(f, wiidebug_drm_show, i->i_private); | ||
131 | } | ||
132 | |||
133 | static ssize_t wiidebug_drm_write(struct file *f, const char __user *u, | ||
134 | size_t s, loff_t *off) | ||
135 | { | ||
136 | struct wiimote_debug *dbg = f->private_data; | ||
137 | unsigned long flags; | ||
138 | char buf[16]; | ||
139 | ssize_t len; | ||
140 | int i; | ||
141 | |||
142 | if (s == 0) | ||
143 | return -EINVAL; | ||
144 | |||
145 | len = min((size_t) 15, s); | ||
146 | if (copy_from_user(buf, u, len)) | ||
147 | return -EFAULT; | ||
148 | |||
149 | buf[15] = 0; | ||
150 | |||
151 | for (i = 0; i < WIIPROTO_REQ_MAX; ++i) { | ||
152 | if (!wiidebug_drmmap[i]) | ||
153 | continue; | ||
154 | if (!strcasecmp(buf, wiidebug_drmmap[i])) | ||
155 | break; | ||
156 | } | ||
157 | |||
158 | if (i == WIIPROTO_REQ_MAX) | ||
159 | i = simple_strtoul(buf, NULL, 10); | ||
160 | |||
161 | spin_lock_irqsave(&dbg->wdata->state.lock, flags); | ||
162 | wiiproto_req_drm(dbg->wdata, (__u8) i); | ||
163 | spin_unlock_irqrestore(&dbg->wdata->state.lock, flags); | ||
164 | |||
165 | return len; | ||
166 | } | ||
167 | |||
168 | static const struct file_operations wiidebug_drm_fops = { | ||
169 | .owner = THIS_MODULE, | ||
170 | .open = wiidebug_drm_open, | ||
171 | .read = seq_read, | ||
172 | .llseek = seq_lseek, | ||
173 | .write = wiidebug_drm_write, | ||
174 | .release = single_release, | ||
175 | }; | ||
176 | |||
89 | int wiidebug_init(struct wiimote_data *wdata) | 177 | int wiidebug_init(struct wiimote_data *wdata) |
90 | { | 178 | { |
91 | struct wiimote_debug *dbg; | 179 | struct wiimote_debug *dbg; |
92 | unsigned long flags; | 180 | unsigned long flags; |
181 | int ret = -ENOMEM; | ||
93 | 182 | ||
94 | dbg = kzalloc(sizeof(*dbg), GFP_KERNEL); | 183 | dbg = kzalloc(sizeof(*dbg), GFP_KERNEL); |
95 | if (!dbg) | 184 | if (!dbg) |
@@ -99,16 +188,25 @@ int wiidebug_init(struct wiimote_data *wdata) | |||
99 | 188 | ||
100 | dbg->eeprom = debugfs_create_file("eeprom", S_IRUSR, | 189 | dbg->eeprom = debugfs_create_file("eeprom", S_IRUSR, |
101 | dbg->wdata->hdev->debug_dir, dbg, &wiidebug_eeprom_fops); | 190 | dbg->wdata->hdev->debug_dir, dbg, &wiidebug_eeprom_fops); |
102 | if (!dbg->eeprom) { | 191 | if (!dbg->eeprom) |
103 | kfree(dbg); | 192 | goto err; |
104 | return -ENOMEM; | 193 | |
105 | } | 194 | dbg->drm = debugfs_create_file("drm", S_IRUSR, |
195 | dbg->wdata->hdev->debug_dir, dbg, &wiidebug_drm_fops); | ||
196 | if (!dbg->drm) | ||
197 | goto err_drm; | ||
106 | 198 | ||
107 | spin_lock_irqsave(&wdata->state.lock, flags); | 199 | spin_lock_irqsave(&wdata->state.lock, flags); |
108 | wdata->debug = dbg; | 200 | wdata->debug = dbg; |
109 | spin_unlock_irqrestore(&wdata->state.lock, flags); | 201 | spin_unlock_irqrestore(&wdata->state.lock, flags); |
110 | 202 | ||
111 | return 0; | 203 | return 0; |
204 | |||
205 | err_drm: | ||
206 | debugfs_remove(dbg->eeprom); | ||
207 | err: | ||
208 | kfree(dbg); | ||
209 | return ret; | ||
112 | } | 210 | } |
113 | 211 | ||
114 | void wiidebug_deinit(struct wiimote_data *wdata) | 212 | void wiidebug_deinit(struct wiimote_data *wdata) |
@@ -123,6 +221,7 @@ void wiidebug_deinit(struct wiimote_data *wdata) | |||
123 | wdata->debug = NULL; | 221 | wdata->debug = NULL; |
124 | spin_unlock_irqrestore(&wdata->state.lock, flags); | 222 | spin_unlock_irqrestore(&wdata->state.lock, flags); |
125 | 223 | ||
224 | debugfs_remove(dbg->drm); | ||
126 | debugfs_remove(dbg->eeprom); | 225 | debugfs_remove(dbg->eeprom); |
127 | kfree(dbg); | 226 | kfree(dbg); |
128 | } | 227 | } |
diff --git a/drivers/hid/hid-wiimote.h b/drivers/hid/hid-wiimote.h index 7b6765797f8..c81dbeb086c 100644 --- a/drivers/hid/hid-wiimote.h +++ b/drivers/hid/hid-wiimote.h | |||
@@ -52,6 +52,7 @@ struct wiimote_state { | |||
52 | spinlock_t lock; | 52 | spinlock_t lock; |
53 | __u8 flags; | 53 | __u8 flags; |
54 | __u8 accel_split[2]; | 54 | __u8 accel_split[2]; |
55 | __u8 drm; | ||
55 | 56 | ||
56 | /* synchronous cmd requests */ | 57 | /* synchronous cmd requests */ |
57 | struct mutex sync; | 58 | struct mutex sync; |
@@ -109,6 +110,7 @@ enum wiiproto_reqs { | |||
109 | WIIPROTO_REQ_DRM_E = 0x3d, | 110 | WIIPROTO_REQ_DRM_E = 0x3d, |
110 | WIIPROTO_REQ_DRM_SKAI1 = 0x3e, | 111 | WIIPROTO_REQ_DRM_SKAI1 = 0x3e, |
111 | WIIPROTO_REQ_DRM_SKAI2 = 0x3f, | 112 | WIIPROTO_REQ_DRM_SKAI2 = 0x3f, |
113 | WIIPROTO_REQ_MAX | ||
112 | }; | 114 | }; |
113 | 115 | ||
114 | #define dev_to_wii(pdev) hid_get_drvdata(container_of(pdev, struct hid_device, \ | 116 | #define dev_to_wii(pdev) hid_get_drvdata(container_of(pdev, struct hid_device, \ |