/* * PlayStation 2 Trance Vibrator driver * * Copyright (C) 2006 Sam Hocevar * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* Standard include files */ #include #include #include #include #include /* Version Information */ #define DRIVER_VERSION "v1.1" #define DRIVER_AUTHOR "Sam Hocevar, sam@zoy.org" #define DRIVER_DESC "PlayStation 2 Trance Vibrator driver" #define TRANCEVIBRATOR_VENDOR_ID 0x0b49 /* ASCII Corporation */ #define TRANCEVIBRATOR_PRODUCT_ID 0x064f /* Trance Vibrator */ static const struct usb_device_id id_table[] = { { USB_DEVICE(TRANCEVIBRATOR_VENDOR_ID, TRANCEVIBRATOR_PRODUCT_ID) }, { }, }; MODULE_DEVICE_TABLE (usb, id_table); /* Driver-local specific stuff */ struct trancevibrator { struct usb_device *udev; unsigned int speed; }; static ssize_t show_speed(struct device *dev, struct device_attribute *attr, char *buf) { struct usb_interface *intf = to_usb_interface(dev); struct trancevibrator *tv = usb_get_intfdata(intf); return sprintf(buf, "%d\n", tv->speed); } static ssize_t set_speed(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct usb_interface *intf = to_usb_interface(dev); struct trancevibrator *tv = usb_get_intfdata(intf); int temp, retval, old; temp = simple_strtoul(buf, NULL, 10); if (temp > 255) temp = 255; else if (temp < 0) temp = 0; old = tv->speed; tv->speed = temp; dev_dbg(&tv->udev->dev, "speed = %d\n", tv->speed); /* Set speed */ retval = usb_control_msg(tv->udev, usb_sndctrlpipe(tv->udev, 0), 0x01, /* vendor request: set speed */ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_OTHER, tv->speed, /* speed value */ 0, NULL, 0, USB_CTRL_GET_TIMEOUT); if (retval) { tv->speed = old; dev_dbg(&tv->udev->dev, "retval = %d\n", retval); return retval; } return count; } static DEVICE_ATTR(speed, S_IRUGO | S_IWUSR, show_speed, set_speed); static int tv_probe(struct usb_interface *interface, const struct usb_device_id *id) { struct usb_device *udev = interface_to_usbdev(interface); struct trancevibrator *dev; int retval; dev = kzalloc(sizeof(struct trancevibrator), GFP_KERNEL); if (!dev) { retval = -ENOMEM; goto error; } dev->udev = usb_get_dev(udev); usb_set_intfdata(interface, dev); retval = device_create_file(&interface->dev, &dev_attr_speed); if (retval) goto error_create_file; return 0; error_create_file: usb_put_dev(udev); usb_set_intfdata(interface, NULL); error: kfree(dev); return retval; } static void tv_disconnect(struct usb_interface *interface) { struct trancevibrator *dev; dev = usb_get_intfdata (interface); device_remove_file(&interface->dev, &dev_attr_speed); usb_set_intfdata(interface, NULL); usb_put_dev(dev->udev); kfree(dev); } /* USB subsystem object */ static struct usb_driver tv_driver = { .name = "trancevibrator", .probe = tv_probe, .disconnect = tv_disconnect, .id_table = id_table, }; module_usb_driver(tv_driver); MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); 500'>2017-02-07udp: properly cope with csum errorsEric Dumazet1-1/+3 2017-02-04netlabel: out of bound access in cipso_v4_validate()Eric Dumazet1-0/+4 2017-02-04Merge branch 'irq-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/ker...Linus Torvalds1-0/+17 2017-02-04Merge tag 'char-misc-4.10-rc7' of git://git.kernel.org/pub/scm/linux/kernel/g...Linus Torvalds1-2/+30 2017-02-03base/memory, hotplug: fix a kernel oops in show_valid_zones()Toshi Kani1-1/+2 2017-02-03Merge tag 'drm-fixes-for-v4.10-rc7' of git://people.freedesktop.org/~airlied/...Linus Torvalds2-1/+16 2017-02-03Merge branch 'modversions' (modversions fixes for powerpc from Ard)Linus Torvalds3-17/+25 2017-02-03log2: make order_base_2() behave correctly on const input value zeroArd Biesheuvel1-1/+12 2017-02-03module: unify absolute krctab definitions for 32-bit and 64-bitArd Biesheuvel1-7/+0 2017-02-03modversions: treat symbol CRCs as 32 bit quantitiesArd Biesheuvel3-12/+27 2017-02-03ipv6: sr: remove cleanup flag and fix HMAC computationDavid Lebrun1-6/+3 2017-02-02Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/ke...Linus Torvalds1-3/+0 2017-02-01Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/netLinus Torvalds4-19/+26 2017-02-01Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/vir...Linus Torvalds1-0/+1 2017-02-01net: fix ndo_features_check/ndo_fix_features comment orderingDimitris Michailidis1-14/+15 2017-02-01perf/x86/intel/uncore: Make package handling more robustThomas Gleixner1-2/+0