2005-04-16 15:20:36 -07:00
/*
* Copyright ( C ) 2003 David Brownell
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation ; either version 2.1 of the License , or
* ( at your option ) any later version .
*/
# include <linux/errno.h>
# include <linux/kernel.h>
2012-09-06 20:11:09 +02:00
# include <linux/module.h>
2005-04-16 15:20:36 -07:00
# include <linux/list.h>
# include <linux/string.h>
# include <linux/device.h>
# include <linux/init.h>
2011-11-17 16:42:24 -05:00
# include <linux/nls.h>
2005-04-16 15:20:36 -07:00
2006-12-16 15:34:53 -08:00
# include <linux/usb/ch9.h>
2007-10-04 18:05:17 -07:00
# include <linux/usb/gadget.h>
2005-04-16 15:20:36 -07:00
/**
* usb_gadget_get_string - fill out a string descriptor
* @ table : of c strings encoded using UTF - 8
* @ id : string id , from low byte of wValue in get string descriptor
2011-11-17 16:42:24 -05:00
* @ buf : at least 256 bytes , must be 16 - bit aligned
2005-04-16 15:20:36 -07:00
*
* Finds the UTF - 8 string matching the ID , and converts it into a
* string descriptor in utf16 - le .
* Returns length of descriptor ( always even ) or negative errno
*
* If your driver needs stings in multiple languages , you ' ll probably
* " switch (wIndex) { ... } " in your ep0 string descriptor logic ,
* using this routine after choosing which set of UTF - 8 strings to use .
* Note that US - ASCII is a strict subset of UTF - 8 ; any string bytes with
* the eighth bit set will be multibyte UTF - 8 characters , not ISO - 8859 / 1
* characters ( which are also widely used in C strings ) .
*/
int
usb_gadget_get_string ( struct usb_gadget_strings * table , int id , u8 * buf )
{
struct usb_string * s ;
int len ;
/* descriptor 0 has the language id */
if ( id = = 0 ) {
buf [ 0 ] = 4 ;
buf [ 1 ] = USB_DT_STRING ;
buf [ 2 ] = ( u8 ) table - > language ;
buf [ 3 ] = ( u8 ) ( table - > language > > 8 ) ;
return 4 ;
}
for ( s = table - > strings ; s & & s - > s ; s + + )
if ( s - > id = = id )
break ;
/* unrecognized: stall. */
if ( ! s | | ! s - > s )
return - EINVAL ;
/* string descriptors have length, tag, then UTF16-LE text */
len = min ( ( size_t ) 126 , strlen ( s - > s ) ) ;
2011-11-17 16:42:24 -05:00
len = utf8s_to_utf16s ( s - > s , len , UTF16_LITTLE_ENDIAN ,
( wchar_t * ) & buf [ 2 ] , 126 ) ;
2005-04-16 15:20:36 -07:00
if ( len < 0 )
return - EINVAL ;
buf [ 0 ] = ( len + 1 ) * 2 ;
buf [ 1 ] = USB_DT_STRING ;
return buf [ 0 ] ;
}
2012-09-06 20:11:09 +02:00
EXPORT_SYMBOL_GPL ( usb_gadget_get_string ) ;