Root/
1 | /* |
2 | * Roccat Lua driver for Linux |
3 | * |
4 | * Copyright (c) 2012 Stefan Achatz <erazor_de@users.sourceforge.net> |
5 | */ |
6 | |
7 | /* |
8 | * This program is free software; you can redistribute it and/or modify it |
9 | * under the terms of the GNU General Public License as published by the Free |
10 | * Software Foundation; either version 2 of the License, or (at your option) |
11 | * any later version. |
12 | */ |
13 | |
14 | /* |
15 | * Roccat Lua is a gamer mouse which cpi, button and light settings can be |
16 | * configured. |
17 | */ |
18 | |
19 | #include <linux/device.h> |
20 | #include <linux/input.h> |
21 | #include <linux/hid.h> |
22 | #include <linux/module.h> |
23 | #include <linux/slab.h> |
24 | #include <linux/hid-roccat.h> |
25 | #include "hid-ids.h" |
26 | #include "hid-roccat-common.h" |
27 | #include "hid-roccat-lua.h" |
28 | |
29 | static ssize_t lua_sysfs_read(struct file *fp, struct kobject *kobj, |
30 | char *buf, loff_t off, size_t count, |
31 | size_t real_size, uint command) |
32 | { |
33 | struct device *dev = container_of(kobj, struct device, kobj); |
34 | struct lua_device *lua = hid_get_drvdata(dev_get_drvdata(dev)); |
35 | struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); |
36 | int retval; |
37 | |
38 | if (off >= real_size) |
39 | return 0; |
40 | |
41 | if (off != 0 || count != real_size) |
42 | return -EINVAL; |
43 | |
44 | mutex_lock(&lua->lua_lock); |
45 | retval = roccat_common2_receive(usb_dev, command, buf, real_size); |
46 | mutex_unlock(&lua->lua_lock); |
47 | |
48 | return retval ? retval : real_size; |
49 | } |
50 | |
51 | static ssize_t lua_sysfs_write(struct file *fp, struct kobject *kobj, |
52 | void const *buf, loff_t off, size_t count, |
53 | size_t real_size, uint command) |
54 | { |
55 | struct device *dev = container_of(kobj, struct device, kobj); |
56 | struct lua_device *lua = hid_get_drvdata(dev_get_drvdata(dev)); |
57 | struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); |
58 | int retval; |
59 | |
60 | if (off != 0 || count != real_size) |
61 | return -EINVAL; |
62 | |
63 | mutex_lock(&lua->lua_lock); |
64 | retval = roccat_common2_send(usb_dev, command, (void *)buf, real_size); |
65 | mutex_unlock(&lua->lua_lock); |
66 | |
67 | return retval ? retval : real_size; |
68 | } |
69 | |
70 | #define LUA_SYSFS_W(thingy, THINGY) \ |
71 | static ssize_t lua_sysfs_write_ ## thingy(struct file *fp, \ |
72 | struct kobject *kobj, struct bin_attribute *attr, \ |
73 | char *buf, loff_t off, size_t count) \ |
74 | { \ |
75 | return lua_sysfs_write(fp, kobj, buf, off, count, \ |
76 | LUA_SIZE_ ## THINGY, LUA_COMMAND_ ## THINGY); \ |
77 | } |
78 | |
79 | #define LUA_SYSFS_R(thingy, THINGY) \ |
80 | static ssize_t lua_sysfs_read_ ## thingy(struct file *fp, \ |
81 | struct kobject *kobj, struct bin_attribute *attr, \ |
82 | char *buf, loff_t off, size_t count) \ |
83 | { \ |
84 | return lua_sysfs_read(fp, kobj, buf, off, count, \ |
85 | LUA_SIZE_ ## THINGY, LUA_COMMAND_ ## THINGY); \ |
86 | } |
87 | |
88 | #define LUA_BIN_ATTRIBUTE_RW(thingy, THINGY) \ |
89 | LUA_SYSFS_W(thingy, THINGY) \ |
90 | LUA_SYSFS_R(thingy, THINGY) \ |
91 | static struct bin_attribute lua_ ## thingy ## _attr = { \ |
92 | .attr = { .name = #thingy, .mode = 0660 }, \ |
93 | .size = LUA_SIZE_ ## THINGY, \ |
94 | .read = lua_sysfs_read_ ## thingy, \ |
95 | .write = lua_sysfs_write_ ## thingy \ |
96 | }; |
97 | |
98 | LUA_BIN_ATTRIBUTE_RW(control, CONTROL) |
99 | |
100 | static int lua_create_sysfs_attributes(struct usb_interface *intf) |
101 | { |
102 | return sysfs_create_bin_file(&intf->dev.kobj, &lua_control_attr); |
103 | } |
104 | |
105 | static void lua_remove_sysfs_attributes(struct usb_interface *intf) |
106 | { |
107 | sysfs_remove_bin_file(&intf->dev.kobj, &lua_control_attr); |
108 | } |
109 | |
110 | static int lua_init_lua_device_struct(struct usb_device *usb_dev, |
111 | struct lua_device *lua) |
112 | { |
113 | mutex_init(&lua->lua_lock); |
114 | |
115 | return 0; |
116 | } |
117 | |
118 | static int lua_init_specials(struct hid_device *hdev) |
119 | { |
120 | struct usb_interface *intf = to_usb_interface(hdev->dev.parent); |
121 | struct usb_device *usb_dev = interface_to_usbdev(intf); |
122 | struct lua_device *lua; |
123 | int retval; |
124 | |
125 | lua = kzalloc(sizeof(*lua), GFP_KERNEL); |
126 | if (!lua) { |
127 | hid_err(hdev, "can't alloc device descriptor\n"); |
128 | return -ENOMEM; |
129 | } |
130 | hid_set_drvdata(hdev, lua); |
131 | |
132 | retval = lua_init_lua_device_struct(usb_dev, lua); |
133 | if (retval) { |
134 | hid_err(hdev, "couldn't init struct lua_device\n"); |
135 | goto exit; |
136 | } |
137 | |
138 | retval = lua_create_sysfs_attributes(intf); |
139 | if (retval) { |
140 | hid_err(hdev, "cannot create sysfs files\n"); |
141 | goto exit; |
142 | } |
143 | |
144 | return 0; |
145 | exit: |
146 | kfree(lua); |
147 | return retval; |
148 | } |
149 | |
150 | static void lua_remove_specials(struct hid_device *hdev) |
151 | { |
152 | struct usb_interface *intf = to_usb_interface(hdev->dev.parent); |
153 | struct lua_device *lua; |
154 | |
155 | lua_remove_sysfs_attributes(intf); |
156 | |
157 | lua = hid_get_drvdata(hdev); |
158 | kfree(lua); |
159 | } |
160 | |
161 | static int lua_probe(struct hid_device *hdev, |
162 | const struct hid_device_id *id) |
163 | { |
164 | int retval; |
165 | |
166 | retval = hid_parse(hdev); |
167 | if (retval) { |
168 | hid_err(hdev, "parse failed\n"); |
169 | goto exit; |
170 | } |
171 | |
172 | retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT); |
173 | if (retval) { |
174 | hid_err(hdev, "hw start failed\n"); |
175 | goto exit; |
176 | } |
177 | |
178 | retval = lua_init_specials(hdev); |
179 | if (retval) { |
180 | hid_err(hdev, "couldn't install mouse\n"); |
181 | goto exit_stop; |
182 | } |
183 | |
184 | return 0; |
185 | |
186 | exit_stop: |
187 | hid_hw_stop(hdev); |
188 | exit: |
189 | return retval; |
190 | } |
191 | |
192 | static void lua_remove(struct hid_device *hdev) |
193 | { |
194 | lua_remove_specials(hdev); |
195 | hid_hw_stop(hdev); |
196 | } |
197 | |
198 | static const struct hid_device_id lua_devices[] = { |
199 | { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_LUA) }, |
200 | { } |
201 | }; |
202 | |
203 | MODULE_DEVICE_TABLE(hid, lua_devices); |
204 | |
205 | static struct hid_driver lua_driver = { |
206 | .name = "lua", |
207 | .id_table = lua_devices, |
208 | .probe = lua_probe, |
209 | .remove = lua_remove |
210 | }; |
211 | module_hid_driver(lua_driver); |
212 | |
213 | MODULE_AUTHOR("Stefan Achatz"); |
214 | MODULE_DESCRIPTION("USB Roccat Lua driver"); |
215 | MODULE_LICENSE("GPL v2"); |
216 |
Branches:
ben-wpan
ben-wpan-stefan
javiroman/ks7010
jz-2.6.34
jz-2.6.34-rc5
jz-2.6.34-rc6
jz-2.6.34-rc7
jz-2.6.35
jz-2.6.36
jz-2.6.37
jz-2.6.38
jz-2.6.39
jz-3.0
jz-3.1
jz-3.11
jz-3.12
jz-3.13
jz-3.15
jz-3.16
jz-3.18-dt
jz-3.2
jz-3.3
jz-3.4
jz-3.5
jz-3.6
jz-3.6-rc2-pwm
jz-3.9
jz-3.9-clk
jz-3.9-rc8
jz47xx
jz47xx-2.6.38
master
Tags:
od-2011-09-04
od-2011-09-18
v2.6.34-rc5
v2.6.34-rc6
v2.6.34-rc7
v3.9