| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142 | # -*- perl -*-## Invoked from usbdescgen.pl#require '../../iodevs.conf';require 'hconst.ph';my %usbparam     = header_const('usbparam.vh');usb_languages('en_US', 'sv_SE');my $vendor_id    = word(0x4680); # was: word(0x1d50); [OpenMoko]my $device_id    = word(0x0881); # was: word(0x6149); [free public allocations]my $version_id   = word(0x0100);my $serial       = usb_serial('XXXXXX-XXXXXX'); # 12 charactersmy $manufacturer = usb_string(''   => 'Peter & Per');my $product      = usb_string(''   => 'MAX80 I/O card for ABC');my $maxpacket    = 1 << ($usbparam{'USB_PACKET_BITS'} || 6);sub acm_channels($$@) {    my($channel_count,$ep_base,@names) = @_;    my @d;    for (my $c = 0; $c < $channel_count; $c++) {	my $ep_data = $ep_base + ($c << 1);	my $ep_intr = $ep_data + 1;	my $mgmt_if;	my $data_if;	my $name = defined($names[$c]) ? $names[$c] : usb_string();	push(@d,		# Interface association descriptor		usb_desc('interface_association',			 byte(\$mgmt_if), # First interface index			 byte(2),	  # Interface count			 # USB spec says to copy the first interface class			 usb_class('cdc','acm','none'),			 $name),		# Management interface		usb_dset {		    usb_desc('interface',			     byte($mgmt_if = usb_index),			     byte(0),	# No alternate settings			     byte(1),	# Endpoint count			     usb_class('cdc','acm','none'),			     $name),			usb_desc('cs_interface.header',				 word(0x120)), # CDC spec version 1.20			usb_desc('cs_interface.call_management',				 byte(0x03), # AT commands over setup or data				 byte(\$data_if)), # Which data interface			usb_desc('cs_interface.acm',				 # Supports SET_CONTROL_LINE_STATE and				 # SEND_BREAK. This also means				 # GET|SET_LINE_CODING has to be handled,				 # at least vacuously.				 byte(0x06)),			usb_desc('cs_interface.union',				 byte(\$mgmt_if),	# Controlling interface				 byte(\$data_if)),	# Data interface			# Notification endpoint (input)			usb_desc('endpoint',				 ep_i($ep_intr),				 byte(3),	# Interrupt, data				 word($maxpacket),				 byte(2)),	# Interval	    },		# Data interface		usb_dset {		    usb_desc('interface',			     byte($data_if = usb_index),			     byte(0),	# No alternate settings			     byte(2),	# Endpoint count			     usb_class('cdc_data'),			     usb_string()),			# Data endpoint (input)			usb_desc('endpoint',				 ep_i($ep_data),				 byte(2),      # Bulk, data				 word($maxpacket),				 byte(0)),     # Interval			# Data endpoint (output)			usb_desc('endpoint',				 ep_o($ep_data),				 byte(2),	# Bulk, data				 word($maxpacket),				 byte(0))       # Interval	     });    }    return @d;}usb_device {    usb_desc('device',	     word(0x101),		# USB version	     usb_class('multi'),	# Device with multiple interfaces	     byte(8),			# Max packet size on endpoint 0	     $vendor_id, $device_id, $version_id,	     $manufacturer, $product, $serial,	     byte(usb_children)		# Number of configurations	),	usb_dset {	    usb_desc('configuration',		     word(usb_totallen), # Total length for this dset		     byte(usb_children), # Number of interfaces		     byte(usb_index,1),	 # This configuration index		     usb_string(),	 # Text description (empty)		     byte(0xc0),	 # Self or bus powered		     byte(500 >> 1)),	 # Up to 500 mA		# Descriptors for each ACM channel, starting at endpoint 1		acm_channels($consts{'TTY_CHANNELS'}, 1,			     # Names of ACM channels			     usb_string('' => 'MAX80 console'),			     usb_string('' => 'PUN80 network'))    },};usb_additional_data {    # Line state structure    dword(38400),		# Baud rate (largest POSIX required value)	byte(0),		# 1 stop bit	byte(0),		# No parity	byte(8)			# 8 data bits};
 |