Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /*
0003  * PlayStation 2 Trance Vibrator driver
0004  *
0005  * Copyright (C) 2006 Sam Hocevar <sam@zoy.org>
0006  */
0007 
0008 /* Standard include files */
0009 #include <linux/kernel.h>
0010 #include <linux/errno.h>
0011 #include <linux/slab.h>
0012 #include <linux/module.h>
0013 #include <linux/usb.h>
0014 
0015 #define DRIVER_AUTHOR "Sam Hocevar, sam@zoy.org"
0016 #define DRIVER_DESC "PlayStation 2 Trance Vibrator driver"
0017 
0018 #define TRANCEVIBRATOR_VENDOR_ID    0x0b49  /* ASCII Corporation */
0019 #define TRANCEVIBRATOR_PRODUCT_ID   0x064f  /* Trance Vibrator */
0020 
0021 static const struct usb_device_id id_table[] = {
0022     { USB_DEVICE(TRANCEVIBRATOR_VENDOR_ID, TRANCEVIBRATOR_PRODUCT_ID) },
0023     { },
0024 };
0025 MODULE_DEVICE_TABLE (usb, id_table);
0026 
0027 /* Driver-local specific stuff */
0028 struct trancevibrator {
0029     struct usb_device *udev;
0030     unsigned int speed;
0031 };
0032 
0033 static ssize_t speed_show(struct device *dev, struct device_attribute *attr,
0034               char *buf)
0035 {
0036     struct usb_interface *intf = to_usb_interface(dev);
0037     struct trancevibrator *tv = usb_get_intfdata(intf);
0038 
0039     return sprintf(buf, "%d\n", tv->speed);
0040 }
0041 
0042 static ssize_t speed_store(struct device *dev, struct device_attribute *attr,
0043              const char *buf, size_t count)
0044 {
0045     struct usb_interface *intf = to_usb_interface(dev);
0046     struct trancevibrator *tv = usb_get_intfdata(intf);
0047     int temp, retval, old;
0048 
0049     retval = kstrtoint(buf, 10, &temp);
0050     if (retval)
0051         return retval;
0052     if (temp > 255)
0053         temp = 255;
0054     else if (temp < 0)
0055         temp = 0;
0056     old = tv->speed;
0057     tv->speed = temp;
0058 
0059     dev_dbg(&tv->udev->dev, "speed = %d\n", tv->speed);
0060 
0061     /* Set speed */
0062     retval = usb_control_msg(tv->udev, usb_sndctrlpipe(tv->udev, 0),
0063                  0x01, /* vendor request: set speed */
0064                  USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
0065                  tv->speed, /* speed value */
0066                  0, NULL, 0, USB_CTRL_SET_TIMEOUT);
0067     if (retval) {
0068         tv->speed = old;
0069         dev_dbg(&tv->udev->dev, "retval = %d\n", retval);
0070         return retval;
0071     }
0072     return count;
0073 }
0074 static DEVICE_ATTR_RW(speed);
0075 
0076 static struct attribute *tv_attrs[] = {
0077     &dev_attr_speed.attr,
0078     NULL,
0079 };
0080 ATTRIBUTE_GROUPS(tv);
0081 
0082 static int tv_probe(struct usb_interface *interface,
0083             const struct usb_device_id *id)
0084 {
0085     struct usb_device *udev = interface_to_usbdev(interface);
0086     struct trancevibrator *dev;
0087     int retval;
0088 
0089     dev = kzalloc(sizeof(struct trancevibrator), GFP_KERNEL);
0090     if (!dev) {
0091         retval = -ENOMEM;
0092         goto error;
0093     }
0094 
0095     dev->udev = usb_get_dev(udev);
0096     usb_set_intfdata(interface, dev);
0097 
0098     return 0;
0099 
0100 error:
0101     kfree(dev);
0102     return retval;
0103 }
0104 
0105 static void tv_disconnect(struct usb_interface *interface)
0106 {
0107     struct trancevibrator *dev;
0108 
0109     dev = usb_get_intfdata (interface);
0110     usb_set_intfdata(interface, NULL);
0111     usb_put_dev(dev->udev);
0112     kfree(dev);
0113 }
0114 
0115 /* USB subsystem object */
0116 static struct usb_driver tv_driver = {
0117     .name =     "trancevibrator",
0118     .probe =    tv_probe,
0119     .disconnect =   tv_disconnect,
0120     .id_table = id_table,
0121     .dev_groups =   tv_groups,
0122 };
0123 
0124 module_usb_driver(tv_driver);
0125 
0126 MODULE_AUTHOR(DRIVER_AUTHOR);
0127 MODULE_DESCRIPTION(DRIVER_DESC);
0128 MODULE_LICENSE("GPL");