# -*- perl -*- # # Invoked from usbdescgen.pl # require '../../common/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 characters my $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 };