/* * composite.h -- framework for usb gadgets which are composite devices * * Copyright (C) 2006-2008 David Brownell * * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __LINUX_USB_COMPOSITE_H #define __LINUX_USB_COMPOSITE_H #include #include #include #define USB_GADGET_DELAYED_STATUS 0x7fff struct usb_configuration; struct usb_function { const char *name; struct usb_gadget_strings **strings; struct usb_descriptor_header **descriptors; struct usb_descriptor_header **hs_descriptors; struct usb_descriptor_header **ss_descriptors; struct usb_configuration *config; int (*bind)(struct usb_configuration *, struct usb_function *); void (*unbind)(struct usb_configuration *, struct usb_function *); int (*set_alt)(struct usb_function *, unsigned interface, unsigned alt); int (*get_alt)(struct usb_function *, unsigned interface); void (*disable)(struct usb_function *); int (*setup)(struct usb_function *, const struct usb_ctrlrequest *); void (*suspend)(struct usb_function *); void (*resume)(struct usb_function *); int (*get_status)(struct usb_function *); int (*func_suspend)(struct usb_function *, u8 suspend_opt); struct list_head list; DECLARE_BITMAP(endpoints, 32); }; int usb_add_function(struct usb_configuration *, struct usb_function *); int usb_function_deactivate(struct usb_function *); int usb_function_activate(struct usb_function *); int usb_interface_id(struct usb_configuration *, struct usb_function *); int config_ep_by_speed(struct usb_gadget *g, struct usb_function *f, struct usb_ep *_ep); #define MAX_CONFIG_INTERFACES 16 struct usb_configuration { const char *label; struct usb_gadget_strings **strings; const struct usb_descriptor_header **descriptors; void (*unbind)(struct usb_configuration *); int (*setup)(struct usb_configuration *, const struct usb_ctrlrequest *); u8 bConfigurationValue; u8 iConfiguration; u8 bmAttributes; u8 bMaxPower; struct usb_composite_dev *cdev; struct list_head list; struct list_head functions; u8 next_interface_id; unsigned superspeed:1; unsigned highspeed:1; unsigned fullspeed:1; struct usb_function *interface[MAX_CONFIG_INTERFACES]; }; int usb_add_config(struct usb_composite_dev *, struct usb_configuration *, int (*)(struct usb_configuration *)); int usb_remove_config(struct usb_composite_dev *, struct usb_configuration *); struct usb_composite_driver { const char *name; const char *iProduct; const char *iManufacturer; const struct usb_device_descriptor *dev; struct usb_gadget_strings **strings; enum usb_device_speed max_speed; unsigned needs_serial:1; int (*unbind)(struct usb_composite_dev *); void (*disconnect)(struct usb_composite_dev *); void (*suspend)(struct usb_composite_dev *); void (*resume)(struct usb_composite_dev *); }; extern int usb_composite_probe(struct usb_composite_driver *driver, int (*bind)(struct usb_composite_dev *cdev)); extern void usb_composite_unregister(struct usb_composite_driver *driver); extern void usb_composite_setup_continue(struct usb_composite_dev *cdev); struct usb_composite_dev { struct usb_gadget *gadget; struct usb_request *req; unsigned bufsiz; struct usb_configuration *config; unsigned int suspended:1; struct usb_device_descriptor desc; struct list_head configs; struct usb_composite_driver *driver; u8 next_string_id; u8 manufacturer_override; u8 product_override; u8 serial_override; unsigned deactivations; int delayed_status; spinlock_t lock; struct switch_dev sw_connect2pc; bool connected; struct work_struct switch_work; struct delayed_work request_reset; }; extern int usb_string_id(struct usb_composite_dev *c); extern int usb_string_ids_tab(struct usb_composite_dev *c, struct usb_string *str); extern int usb_string_ids_n(struct usb_composite_dev *c, unsigned n); #define DBG(d, fmt, args...) \ dev_dbg(&(d)->gadget->dev , fmt , ## args) #define VDBG(d, fmt, args...) \ dev_vdbg(&(d)->gadget->dev , fmt , ## args) #define ERROR(d, fmt, args...) \ dev_err(&(d)->gadget->dev , fmt , ## args) #define WARNING(d, fmt, args...) \ dev_warn(&(d)->gadget->dev , fmt , ## args) #define INFO(d, fmt, args...) \ dev_info(&(d)->gadget->dev , fmt , ## args) #endif