diff options
author | Mike Lockwood <lockwood@android.com> | 2010-02-06 21:53:51 -0500 |
---|---|---|
committer | Colin Cross <ccross@android.com> | 2011-06-14 09:08:55 -0700 |
commit | f041ac69036f1e3a7ce62ef3391801cbe0c6630c (patch) | |
tree | 7eae32d7c875c7473d2d88ae483a3423712c4c19 /drivers/usb | |
parent | 789ef237b38a79f988738ff18ae6d756551afb92 (diff) | |
download | kernel_samsung_aries-f041ac69036f1e3a7ce62ef3391801cbe0c6630c.zip kernel_samsung_aries-f041ac69036f1e3a7ce62ef3391801cbe0c6630c.tar.gz kernel_samsung_aries-f041ac69036f1e3a7ce62ef3391801cbe0c6630c.tar.bz2 |
USB: composite: Add class driver for enabling and disabling USB functions.
Signed-off-by: Mike Lockwood <lockwood@android.com>
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/gadget/composite.c | 50 |
1 files changed, 48 insertions, 2 deletions
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 3b210de..11944bd 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -75,6 +75,33 @@ static char composite_manufacturer[50]; /*-------------------------------------------------------------------------*/ +static ssize_t enable_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct usb_function *f = dev_get_drvdata(dev); + return sprintf(buf, "%d\n", !f->hidden); +} + +static ssize_t enable_store( + struct device *dev, struct device_attribute *attr, + const char *buf, size_t size) +{ + struct usb_function *f = dev_get_drvdata(dev); + struct usb_composite_driver *driver = f->config->cdev->driver; + int value; + + sscanf(buf, "%d", &value); + if (driver->enable_function) + driver->enable_function(f, value); + else + f->hidden = !value; + + return size; +} + +static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR, enable_show, enable_store); + + /** * usb_add_function() - add a function to a configuration * @config: the configuration @@ -92,15 +119,30 @@ static char composite_manufacturer[50]; int usb_add_function(struct usb_configuration *config, struct usb_function *function) { + struct usb_composite_dev *cdev = config->cdev; int value = -EINVAL; + int index; - DBG(config->cdev, "adding '%s'/%p to config '%s'/%p\n", + DBG(cdev, "adding '%s'/%p to config '%s'/%p\n", function->name, function, config->label, config); if (!function->set_alt || !function->disable) goto done; + index = atomic_inc_return(&cdev->driver->function_count); + function->dev = device_create(cdev->driver->class, NULL, + MKDEV(0, index), NULL, function->name); + if (IS_ERR(function->dev)) + return PTR_ERR(function->dev); + + value = device_create_file(function->dev, &dev_attr_enable); + if (value < 0) { + device_destroy(cdev->driver->class, MKDEV(0, index)); + return value; + } + dev_set_drvdata(function->dev, function); + function->config = config; list_add_tail(&function->list, &config->functions); @@ -126,7 +168,7 @@ int usb_add_function(struct usb_configuration *config, done: if (value) - DBG(config->cdev, "adding '%s'/%p --> %d\n", + DBG(cdev, "adding '%s'/%p --> %d\n", function->name, function, value); return value; } @@ -1325,6 +1367,10 @@ int usb_composite_probe(struct usb_composite_driver *driver, composite = driver; composite_gadget_bind = bind; + driver->class = class_create(THIS_MODULE, "usb_composite"); + if (IS_ERR(driver->class)) + return PTR_ERR(driver->class); + return usb_gadget_probe_driver(&composite_driver, composite_bind); } |