Adds AT90USB162 support (#11570)

* at90usb162 support

* fix missing bracket

* Apply suggestions from code review

Co-authored-by: Ryan <fauxpark@gmail.com>

Co-authored-by: Ryan <fauxpark@gmail.com>
This commit is contained in:
Dasky 2021-01-30 03:53:56 +00:00 committed by GitHub
parent 3780ab3fcd
commit d92ffd1157
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 42 additions and 34 deletions

View file

@ -40,7 +40,7 @@
ifeq ($(strip $(BOOTLOADER)), atmel-dfu) ifeq ($(strip $(BOOTLOADER)), atmel-dfu)
OPT_DEFS += -DBOOTLOADER_ATMEL_DFU OPT_DEFS += -DBOOTLOADER_ATMEL_DFU
OPT_DEFS += -DBOOTLOADER_DFU OPT_DEFS += -DBOOTLOADER_DFU
ifneq (,$(filter $(MCU), atmega16u2 atmega32u2 atmega16u4 atmega32u4 at90usb646 at90usb647)) ifneq (,$(filter $(MCU), at90usb162 atmega16u2 atmega32u2 atmega16u4 atmega32u4 at90usb646 at90usb647))
BOOTLOADER_SIZE = 4096 BOOTLOADER_SIZE = 4096
endif endif
ifneq (,$(filter $(MCU), at90usb1286 at90usb1287)) ifneq (,$(filter $(MCU), at90usb1286 at90usb1287))
@ -50,7 +50,7 @@ endif
ifeq ($(strip $(BOOTLOADER)), lufa-dfu) ifeq ($(strip $(BOOTLOADER)), lufa-dfu)
OPT_DEFS += -DBOOTLOADER_LUFA_DFU OPT_DEFS += -DBOOTLOADER_LUFA_DFU
OPT_DEFS += -DBOOTLOADER_DFU OPT_DEFS += -DBOOTLOADER_DFU
ifneq (,$(filter $(MCU), atmega16u2 atmega32u2 atmega16u4 atmega32u4 at90usb646 at90usb647)) ifneq (,$(filter $(MCU), at90usb162 atmega16u2 atmega32u2 atmega16u4 atmega32u4 at90usb646 at90usb647))
BOOTLOADER_SIZE = 4096 BOOTLOADER_SIZE = 4096
endif endif
ifneq (,$(filter $(MCU), at90usb1286 at90usb1287)) ifneq (,$(filter $(MCU), at90usb1286 at90usb1287))
@ -60,7 +60,7 @@ endif
ifeq ($(strip $(BOOTLOADER)), qmk-dfu) ifeq ($(strip $(BOOTLOADER)), qmk-dfu)
OPT_DEFS += -DBOOTLOADER_QMK_DFU OPT_DEFS += -DBOOTLOADER_QMK_DFU
OPT_DEFS += -DBOOTLOADER_DFU OPT_DEFS += -DBOOTLOADER_DFU
ifneq (,$(filter $(MCU), atmega16u2 atmega32u2 atmega16u4 atmega32u4 at90usb646 at90usb647)) ifneq (,$(filter $(MCU), at90usb162 atmega16u2 atmega32u2 atmega16u4 atmega32u4 at90usb646 at90usb647))
BOOTLOADER_SIZE = 4096 BOOTLOADER_SIZE = 4096
endif endif
ifneq (,$(filter $(MCU), at90usb1286 at90usb1287)) ifneq (,$(filter $(MCU), at90usb1286 at90usb1287))

View file

@ -222,7 +222,7 @@ ifeq ($(strip $(RGB_MATRIX_ENABLE)), yes)
$(error "$(RGB_MATRIX_DRIVER)" is not a valid matrix type) $(error "$(RGB_MATRIX_DRIVER)" is not a valid matrix type)
endif endif
OPT_DEFS += -DRGB_MATRIX_ENABLE OPT_DEFS += -DRGB_MATRIX_ENABLE
ifneq (,$(filter $(MCU), atmega16u2 atmega32u2)) ifneq (,$(filter $(MCU), atmega16u2 atmega32u2 at90usb162))
# ATmegaxxU2 does not have hardware MUL instruction - lib8tion must be told to use software multiplication routines # ATmegaxxU2 does not have hardware MUL instruction - lib8tion must be told to use software multiplication routines
OPT_DEFS += -DLIB8_ATTINY OPT_DEFS += -DLIB8_ATTINY
endif endif

View file

@ -25,7 +25,7 @@
}, },
"processor": { "processor": {
"type": "string", "type": "string",
"enum": ["cortex-m0", "cortex-m0plus", "cortex-m3", "cortex-m4", "MKL26Z64", "MK20DX128", "MK20DX256", "STM32F042", "STM32F072", "STM32F103", "STM32F303", "STM32F401", "STM32F411", "atmega16u2", "atmega32u2", "atmega16u4", "atmega32u4", "at90usb646", "at90usb647", "at90usb1286", "at90usb1287", "atmega32a", "atmega328p", "atmega328", "attiny85", "unknown"] "enum": ["cortex-m0", "cortex-m0plus", "cortex-m3", "cortex-m4", "MKL26Z64", "MK20DX128", "MK20DX256", "STM32F042", "STM32F072", "STM32F103", "STM32F303", "STM32F401", "STM32F411", "atmega16u2", "atmega32u2", "atmega16u4", "atmega32u4", "at90usb162", "at90usb646", "at90usb647", "at90usb1286", "at90usb1287", "atmega32a", "atmega328p", "atmega328", "attiny85", "unknown"]
}, },
"board": { "board": {
"type": "string", "type": "string",

View file

@ -9,6 +9,7 @@ The following use [LUFA](https://www.fourwalledcubicle.com/LUFA.php) as the USB
* [ATmega16U2](https://www.microchip.com/wwwproducts/en/ATmega16U2) / [ATmega32U2](https://www.microchip.com/wwwproducts/en/ATmega32U2) * [ATmega16U2](https://www.microchip.com/wwwproducts/en/ATmega16U2) / [ATmega32U2](https://www.microchip.com/wwwproducts/en/ATmega32U2)
* [ATmega16U4](https://www.microchip.com/wwwproducts/en/ATmega16U4) / [ATmega32U4](https://www.microchip.com/wwwproducts/en/ATmega32U4) * [ATmega16U4](https://www.microchip.com/wwwproducts/en/ATmega16U4) / [ATmega32U4](https://www.microchip.com/wwwproducts/en/ATmega32U4)
* [AT90USB64](https://www.microchip.com/wwwproducts/en/AT90USB646) / [AT90USB128](https://www.microchip.com/wwwproducts/en/AT90USB1286) * [AT90USB64](https://www.microchip.com/wwwproducts/en/AT90USB646) / [AT90USB128](https://www.microchip.com/wwwproducts/en/AT90USB1286)
* [AT90USB162](https://www.microchip.com/wwwproducts/en/AT90USB162)
Certain MCUs which do not have native USB will use [V-USB](https://www.obdev.at/products/vusb/index.html) instead: Certain MCUs which do not have native USB will use [V-USB](https://www.obdev.at/products/vusb/index.html) instead:

View file

@ -93,18 +93,18 @@ BACKLIGHT_DRIVER = pwm
On AVR boards, QMK automatically decides which driver to use according to the following table: On AVR boards, QMK automatically decides which driver to use according to the following table:
|Backlight Pin|AT90USB64/128|ATmega16/32U4|ATmega16/32U2|ATmega32A|ATmega328/P| |Backlight Pin|AT90USB64/128|AT90USB162|ATmega16/32U4|ATmega16/32U2|ATmega32A|ATmega328/P|
|-------------|-------------|-------------|-------------|---------|-----------| |-------------|-------------|----------|-------------|-------------|---------|-----------|
|`B1` | | | | |Timer 1 | |`B1` | | | | | |Timer 1 |
|`B2` | | | | |Timer 1 | |`B2` | | | | | |Timer 1 |
|`B5` |Timer 1 |Timer 1 | | | | |`B5` |Timer 1 | |Timer 1 | | | |
|`B6` |Timer 1 |Timer 1 | | | | |`B6` |Timer 1 | |Timer 1 | | | |
|`B7` |Timer 1 |Timer 1 |Timer 1 | | | |`B7` |Timer 1 |Timer 1 |Timer 1 |Timer 1 | | |
|`C4` |Timer 3 | | | | | |`C4` |Timer 3 | | | | | |
|`C5` |Timer 3 | |Timer 1 | | | |`C5` |Timer 3 |Timer 1 | |Timer 1 | | |
|`C6` |Timer 3 |Timer 3 |Timer 1 | | | |`C6` |Timer 3 |Timer 1 |Timer 3 |Timer 1 | | |
|`D4` | | | |Timer 1 | | |`D4` | | | | |Timer 1 | |
|`D5` | | | |Timer 1 | | |`D5` | | | | |Timer 1 | |
All other pins will use timer-assisted software PWM: All other pins will use timer-assisted software PWM:

View file

@ -14,6 +14,7 @@ QMK は十分な容量のフラッシュメモリを備えた USB 対応 AVR ま
* [ATmega16U2](https://www.microchip.com/wwwproducts/en/ATmega16U2) / [ATmega32U2](https://www.microchip.com/wwwproducts/en/ATmega32U2) * [ATmega16U2](https://www.microchip.com/wwwproducts/en/ATmega16U2) / [ATmega32U2](https://www.microchip.com/wwwproducts/en/ATmega32U2)
* [ATmega16U4](https://www.microchip.com/wwwproducts/en/ATmega16U4) / [ATmega32U4](https://www.microchip.com/wwwproducts/en/ATmega32U4) * [ATmega16U4](https://www.microchip.com/wwwproducts/en/ATmega16U4) / [ATmega32U4](https://www.microchip.com/wwwproducts/en/ATmega32U4)
* [AT90USB64](https://www.microchip.com/wwwproducts/en/AT90USB646) / [AT90USB128](https://www.microchip.com/wwwproducts/en/AT90USB1286) * [AT90USB64](https://www.microchip.com/wwwproducts/en/AT90USB646) / [AT90USB128](https://www.microchip.com/wwwproducts/en/AT90USB1286)
* [AT90USB162](https://www.microchip.com/wwwproducts/en/AT90USB162)
組み込みの USB インターフェースを持たない、いくつかの MCU は代わりに [V-USB](https://www.obdev.at/products/vusb/index.html) を使います: 組み込みの USB インターフェースを持たない、いくつかの MCU は代わりに [V-USB](https://www.obdev.at/products/vusb/index.html) を使います:

View file

@ -7,9 +7,9 @@ The SPI Master drivers used in QMK have a set of common functions to allow porta
No special setup is required - just connect the `SS`, `SCK`, `MOSI` and `MISO` pins of your SPI devices to the matching pins on the MCU: No special setup is required - just connect the `SS`, `SCK`, `MOSI` and `MISO` pins of your SPI devices to the matching pins on the MCU:
|MCU |`SS`|`SCK`|`MOSI`|`MISO`| |MCU |`SS`|`SCK`|`MOSI`|`MISO`|
|---------------|----|-----|------|------| |-----------------|----|-----|------|------|
|ATMega16/32U2/4|`B0`|`B1` |`B2` |`B3` | |ATMega16/32U2/4 |`B0`|`B1` |`B2` |`B3` |
|AT90USB64/128 |`B0`|`B1` |`B2` |`B3` | |AT90USB64/128/162|`B0`|`B1` |`B2` |`B3` |
|ATmega32A |`B4`|`B7` |`B5` |`B6` | |ATmega32A |`B4`|`B7` |`B5` |`B6` |
|ATmega328/P |`B2`|`B5` |`B3` |`B4` | |ATmega328/P |`B2`|`B5` |`B3` |`B4` |

View file

@ -20,7 +20,7 @@
#ifdef SOFT_SERIAL_PIN #ifdef SOFT_SERIAL_PIN
# if !(defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__)) # if !(defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__) || defined(__AVR_AT90USB162__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__))
# error serial.c is not supported for the currently selected MCU # error serial.c is not supported for the currently selected MCU
# endif # endif
// if using ATmega32U4/2, AT90USBxxx I2C, can not use PD0 and PD1 in soft serial. // if using ATmega32U4/2, AT90USBxxx I2C, can not use PD0 and PD1 in soft serial.
@ -52,8 +52,8 @@
# define EICRx EICRA # define EICRx EICRA
# endif # endif
// ATmegaxxU2 specific config // ATmegaxxU2/AT90USB162 specific config
# if defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega32U2__) # if defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega32U2__) || defined(__AVR_AT90USB162__)
// PD4(INT5), PD6(INT6), PD7(INT7), PC7(INT4) // PD4(INT5), PD6(INT6), PD7(INT7), PC7(INT4)
# if SOFT_SERIAL_PIN == D4 # if SOFT_SERIAL_PIN == D4
# define EIMSK_BIT _BV(INT5) # define EIMSK_BIT _BV(INT5)

View file

@ -20,7 +20,7 @@
#include "quantum.h" #include "quantum.h"
#include "timer.h" #include "timer.h"
#if defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__) #if defined(__AVR_AT90USB162__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__)
# define SPI_SCK_PIN B1 # define SPI_SCK_PIN B1
# define SPI_MOSI_PIN B2 # define SPI_MOSI_PIN B2
# define SPI_MISO_PIN B3 # define SPI_MISO_PIN B3

View file

@ -21,7 +21,7 @@
typedef int16_t spi_status_t; typedef int16_t spi_status_t;
// Hardware SS pin is defined in the header so that user code can refer to it // Hardware SS pin is defined in the header so that user code can refer to it
#if defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__) #if defined(__AVR_AT90USB162__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__)
# define SPI_SS_PIN B0 # define SPI_SS_PIN B0
#elif defined(__AVR_ATmega32A__) #elif defined(__AVR_ATmega32A__)
# define SPI_SS_PIN B4 # define SPI_SS_PIN B4

View file

@ -29,7 +29,7 @@
#include "uart.h" #include "uart.h"
#if defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__) #if defined(__AVR_AT90USB162__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__)
# define UDRn UDR1 # define UDRn UDR1
# define UBRRnL UBRR1L # define UBRRnL UBRR1L
# define UCSRnA UCSR1A # define UCSRnA UCSR1A

View file

@ -11,7 +11,7 @@ MAX_KEYBOARD_SUBFOLDERS = 5
# Supported processor types # Supported processor types
CHIBIOS_PROCESSORS = 'cortex-m0', 'cortex-m0plus', 'cortex-m3', 'cortex-m4', 'MKL26Z64', 'MK20DX128', 'MK20DX256', 'STM32F042', 'STM32F072', 'STM32F103', 'STM32F303', 'STM32F401', 'STM32F411' CHIBIOS_PROCESSORS = 'cortex-m0', 'cortex-m0plus', 'cortex-m3', 'cortex-m4', 'MKL26Z64', 'MK20DX128', 'MK20DX256', 'STM32F042', 'STM32F072', 'STM32F103', 'STM32F303', 'STM32F401', 'STM32F411'
LUFA_PROCESSORS = 'atmega16u2', 'atmega32u2', 'atmega16u4', 'atmega32u4', 'at90usb646', 'at90usb647', 'at90usb1286', 'at90usb1287', None LUFA_PROCESSORS = 'at90usb162', 'atmega16u2', 'atmega32u2', 'atmega16u4', 'atmega32u4', 'at90usb646', 'at90usb647', 'at90usb1286', 'at90usb1287', None
VUSB_PROCESSORS = 'atmega32a', 'atmega328p', 'atmega328', 'attiny85' VUSB_PROCESSORS = 'atmega32a', 'atmega328p', 'atmega328', 'attiny85'
# Common format strings # Common format strings

View file

@ -48,6 +48,7 @@ def check_udev_rules():
_udev_rule("03eb", "2ff3"), # ATmega16U4 _udev_rule("03eb", "2ff3"), # ATmega16U4
_udev_rule("03eb", "2ff4"), # ATmega32U4 _udev_rule("03eb", "2ff4"), # ATmega32U4
_udev_rule("03eb", "2ff9"), # AT90USB64 _udev_rule("03eb", "2ff9"), # AT90USB64
_udev_rule("03eb", "2ffa"), # AT90USB162
_udev_rule("03eb", "2ffb") # AT90USB128 _udev_rule("03eb", "2ffb") # AT90USB128
}, },
'kiibohd': {_udev_rule("1c11", "b007")}, 'kiibohd': {_udev_rule("1c11", "b007")},

View file

@ -68,7 +68,7 @@
# define COMxx1 COM3A1 # define COMxx1 COM3A1
# define OCRxx OCR3A # define OCRxx OCR3A
# endif # endif
#elif (defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega32U2__)) && (BACKLIGHT_PIN == B7 || BACKLIGHT_PIN == C5 || BACKLIGHT_PIN == C6) #elif (defined(__AVR_AT90USB162__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega32U2__)) && (BACKLIGHT_PIN == B7 || BACKLIGHT_PIN == C5 || BACKLIGHT_PIN == C6)
# define HARDWARE_PWM # define HARDWARE_PWM
# define ICRx ICR1 # define ICRx ICR1
# define TCCRxA TCCR1A # define TCCRxA TCCR1A

View file

@ -39,7 +39,7 @@
# define PIND_ADDRESS 0x9 # define PIND_ADDRESS 0x9
# define PINE_ADDRESS 0xC # define PINE_ADDRESS 0xC
# define PINF_ADDRESS 0xF # define PINF_ADDRESS 0xF
# elif defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega328P__) || defined(__AVR_ATmega328__) # elif defined(__AVR_AT90USB162__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega328P__) || defined(__AVR_ATmega328__)
# define ADDRESS_BASE 0x00 # define ADDRESS_BASE 0x00
# define PINB_ADDRESS 0x3 # define PINB_ADDRESS 0x3
# define PINC_ADDRESS 0x6 # define PINC_ADDRESS 0x6

View file

@ -37,6 +37,8 @@
#ifndef DYNAMIC_KEYMAP_EEPROM_MAX_ADDR #ifndef DYNAMIC_KEYMAP_EEPROM_MAX_ADDR
# if defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__) # if defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__)
# define DYNAMIC_KEYMAP_EEPROM_MAX_ADDR 2047 # define DYNAMIC_KEYMAP_EEPROM_MAX_ADDR 2047
# elif defined(__AVR_AT90USB162__)
# define DYNAMIC_KEYMAP_EEPROM_MAX_ADDR 511
# else # else
# define DYNAMIC_KEYMAP_EEPROM_MAX_ADDR 1023 # define DYNAMIC_KEYMAP_EEPROM_MAX_ADDR 1023
# endif # endif

View file

@ -279,7 +279,7 @@ ifneq ($(findstring STM32F411, $(MCU)),)
DFU_SUFFIX_ARGS ?= -v 0483 -p DF11 DFU_SUFFIX_ARGS ?= -v 0483 -p DF11
endif endif
ifneq (,$(filter $(MCU),atmega16u2 atmega32u2 atmega16u4 atmega32u4 at90usb646 at90usb647 at90usb1286 at90usb1287)) ifneq (,$(filter $(MCU),at90usb162 atmega16u2 atmega32u2 atmega16u4 atmega32u4 at90usb646 at90usb647 at90usb1286 at90usb1287))
PROTOCOL = LUFA PROTOCOL = LUFA
# Processor frequency. # Processor frequency.
@ -317,7 +317,7 @@ ifneq (,$(filter $(MCU),atmega16u2 atmega32u2 atmega16u4 atmega32u4 at90usb646 a
ifeq (,$(filter $(NO_INTERRUPT_CONTROL_ENDPOINT),yes)) ifeq (,$(filter $(NO_INTERRUPT_CONTROL_ENDPOINT),yes))
OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
endif endif
ifneq (,$(filter $(MCU),atmega16u2 atmega32u2)) ifneq (,$(filter $(MCU),at90usb162 atmega16u2 atmega32u2))
NO_I2C = yes NO_I2C = yes
endif endif
endif endif

View file

@ -11,4 +11,5 @@ libusb,ATmega32U2,03EB,2FF0,ddc2c572-cb6e-4f61-a6cc-1a5de941f063
libusb,ATmega16U4,03EB,2FF3,3180d426-bf93-4578-a693-2efbc337da8e libusb,ATmega16U4,03EB,2FF3,3180d426-bf93-4578-a693-2efbc337da8e
libusb,ATmega32U4,03EB,2FF4,5f9726fd-f9de-487a-9fbd-8b3524a7a56a libusb,ATmega32U4,03EB,2FF4,5f9726fd-f9de-487a-9fbd-8b3524a7a56a
libusb,AT90USB64,03EB,2FF9,c6a708ad-e97d-43cd-b04a-3180d737a71b libusb,AT90USB64,03EB,2FF9,c6a708ad-e97d-43cd-b04a-3180d737a71b
libusb,AT90USB162,03EB,2FFA,ef8546f0-ef09-4e7c-8fc2-ffbae1dcd84a
libusb,AT90USB128,03EB,2FFB,fd217df3-59d0-440a-a8f3-4c0c8c84daa3 libusb,AT90USB128,03EB,2FFB,fd217df3-59d0-440a-a8f3-4c0c8c84daa3

View file

@ -9,6 +9,8 @@ SUBSYSTEMS=="usb", ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="2ff3", TAG+="uacc
SUBSYSTEMS=="usb", ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="2ff4", TAG+="uaccess" SUBSYSTEMS=="usb", ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="2ff4", TAG+="uaccess"
### AT90USB64 ### AT90USB64
SUBSYSTEMS=="usb", ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="2ff9", TAG+="uaccess" SUBSYSTEMS=="usb", ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="2ff9", TAG+="uaccess"
### AT90USB162
SUBSYSTEMS=="usb", ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="2ffa", TAG+="uaccess"
### AT90USB128 ### AT90USB128
SUBSYSTEMS=="usb", ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="2ffb", TAG+="uaccess" SUBSYSTEMS=="usb", ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="2ffb", TAG+="uaccess"