diff options
author | David Herrmann <dh.herrmann@gmail.com> | 2013-05-05 17:12:53 -0400 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2013-06-03 05:07:01 -0400 |
commit | dcf392313817efb4f318ebbf21f607dbdaf5ea56 (patch) | |
tree | edf299dd868642038d52714ddcd553b532f2511d /drivers/hid/hid-wiimote-modules.c | |
parent | 20cef813b4791ba55b2f3c4258414b6ded21e8ff (diff) |
HID: wiimote: convert BATTERY to module
This introduces a new sub-device module for the BATTERY handlers. It
moves the whole power_supply battery handling over to wiimote-modules.
This doesn't change any semantics or ABI but only converts the battery
handling into a sub-device module.
Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid/hid-wiimote-modules.c')
-rw-r--r-- | drivers/hid/hid-wiimote-modules.c | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/drivers/hid/hid-wiimote-modules.c b/drivers/hid/hid-wiimote-modules.c index 616f24024f77..4cbbbe651ba5 100644 --- a/drivers/hid/hid-wiimote-modules.c +++ b/drivers/hid/hid-wiimote-modules.c | |||
@@ -171,9 +171,107 @@ static const struct wiimod_ops wiimod_rumble = { | |||
171 | .remove = wiimod_rumble_remove, | 171 | .remove = wiimod_rumble_remove, |
172 | }; | 172 | }; |
173 | 173 | ||
174 | /* | ||
175 | * Battery | ||
176 | * 1 byte of battery capacity information is sent along every protocol status | ||
177 | * report. The wiimote core caches it but we try to update it on every | ||
178 | * user-space request. | ||
179 | * This is supported by nearly every device so it's almost always enabled. | ||
180 | */ | ||
181 | |||
182 | static enum power_supply_property wiimod_battery_props[] = { | ||
183 | POWER_SUPPLY_PROP_CAPACITY, | ||
184 | POWER_SUPPLY_PROP_SCOPE, | ||
185 | }; | ||
186 | |||
187 | static int wiimod_battery_get_property(struct power_supply *psy, | ||
188 | enum power_supply_property psp, | ||
189 | union power_supply_propval *val) | ||
190 | { | ||
191 | struct wiimote_data *wdata = container_of(psy, struct wiimote_data, | ||
192 | battery); | ||
193 | int ret = 0, state; | ||
194 | unsigned long flags; | ||
195 | |||
196 | if (psp == POWER_SUPPLY_PROP_SCOPE) { | ||
197 | val->intval = POWER_SUPPLY_SCOPE_DEVICE; | ||
198 | return 0; | ||
199 | } else if (psp != POWER_SUPPLY_PROP_CAPACITY) { | ||
200 | return -EINVAL; | ||
201 | } | ||
202 | |||
203 | ret = wiimote_cmd_acquire(wdata); | ||
204 | if (ret) | ||
205 | return ret; | ||
206 | |||
207 | spin_lock_irqsave(&wdata->state.lock, flags); | ||
208 | wiimote_cmd_set(wdata, WIIPROTO_REQ_SREQ, 0); | ||
209 | wiiproto_req_status(wdata); | ||
210 | spin_unlock_irqrestore(&wdata->state.lock, flags); | ||
211 | |||
212 | wiimote_cmd_wait(wdata); | ||
213 | wiimote_cmd_release(wdata); | ||
214 | |||
215 | spin_lock_irqsave(&wdata->state.lock, flags); | ||
216 | state = wdata->state.cmd_battery; | ||
217 | spin_unlock_irqrestore(&wdata->state.lock, flags); | ||
218 | |||
219 | val->intval = state * 100 / 255; | ||
220 | return ret; | ||
221 | } | ||
222 | |||
223 | static int wiimod_battery_probe(const struct wiimod_ops *ops, | ||
224 | struct wiimote_data *wdata) | ||
225 | { | ||
226 | int ret; | ||
227 | |||
228 | wdata->battery.properties = wiimod_battery_props; | ||
229 | wdata->battery.num_properties = ARRAY_SIZE(wiimod_battery_props); | ||
230 | wdata->battery.get_property = wiimod_battery_get_property; | ||
231 | wdata->battery.type = POWER_SUPPLY_TYPE_BATTERY; | ||
232 | wdata->battery.use_for_apm = 0; | ||
233 | wdata->battery.name = kasprintf(GFP_KERNEL, "wiimote_battery_%s", | ||
234 | wdata->hdev->uniq); | ||
235 | if (!wdata->battery.name) | ||
236 | return -ENOMEM; | ||
237 | |||
238 | ret = power_supply_register(&wdata->hdev->dev, &wdata->battery); | ||
239 | if (ret) { | ||
240 | hid_err(wdata->hdev, "cannot register battery device\n"); | ||
241 | goto err_free; | ||
242 | } | ||
243 | |||
244 | power_supply_powers(&wdata->battery, &wdata->hdev->dev); | ||
245 | return 0; | ||
246 | |||
247 | err_free: | ||
248 | kfree(wdata->battery.name); | ||
249 | wdata->battery.name = NULL; | ||
250 | return ret; | ||
251 | } | ||
252 | |||
253 | static void wiimod_battery_remove(const struct wiimod_ops *ops, | ||
254 | struct wiimote_data *wdata) | ||
255 | { | ||
256 | if (!wdata->battery.name) | ||
257 | return; | ||
258 | |||
259 | power_supply_unregister(&wdata->battery); | ||
260 | kfree(wdata->battery.name); | ||
261 | wdata->battery.name = NULL; | ||
262 | } | ||
263 | |||
264 | static const struct wiimod_ops wiimod_battery = { | ||
265 | .flags = 0, | ||
266 | .arg = 0, | ||
267 | .probe = wiimod_battery_probe, | ||
268 | .remove = wiimod_battery_remove, | ||
269 | }; | ||
270 | |||
174 | /* module table */ | 271 | /* module table */ |
175 | 272 | ||
176 | const struct wiimod_ops *wiimod_table[WIIMOD_NUM] = { | 273 | const struct wiimod_ops *wiimod_table[WIIMOD_NUM] = { |
177 | [WIIMOD_KEYS] = &wiimod_keys, | 274 | [WIIMOD_KEYS] = &wiimod_keys, |
178 | [WIIMOD_RUMBLE] = &wiimod_rumble, | 275 | [WIIMOD_RUMBLE] = &wiimod_rumble, |
276 | [WIIMOD_BATTERY] = &wiimod_battery, | ||
179 | }; | 277 | }; |