Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
linux-davinci
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
linux
linux-davinci
Commits
156366d3
Commit
156366d3
authored
Mar 02, 2010
by
Takashi Iwai
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote branch 'alsa/devel' into topic/misc
Conflicts: sound/usb/usbaudio.c
parents
7f9320d4
0a566ec2
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
38 additions
and
156 deletions
+38
-156
Documentation/sound/alsa/ALSA-Configuration.txt
Documentation/sound/alsa/ALSA-Configuration.txt
+1
-1
sound/usb/Kconfig
sound/usb/Kconfig
+3
-3
sound/usb/ua101.c
sound/usb/ua101.c
+33
-67
sound/usb/usbaudio.c
sound/usb/usbaudio.c
+0
-53
sound/usb/usbaudio.h
sound/usb/usbaudio.h
+1
-2
sound/usb/usbquirks.h
sound/usb/usbquirks.h
+0
-30
No files found.
Documentation/sound/alsa/ALSA-Configuration.txt
View file @
156366d3
...
@@ -1812,7 +1812,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
...
@@ -1812,7 +1812,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
Module snd-ua101
Module snd-ua101
----------------
----------------
Module for the Edirol UA-101
audio/MIDI interface
.
Module for the Edirol UA-101
/UA-1000 audio/MIDI interfaces
.
This module supports multiple devices, autoprobe and hotplugging.
This module supports multiple devices, autoprobe and hotplugging.
...
...
sound/usb/Kconfig
View file @
156366d3
...
@@ -22,13 +22,13 @@ config SND_USB_AUDIO
...
@@ -22,13 +22,13 @@ config SND_USB_AUDIO
will be called snd-usb-audio.
will be called snd-usb-audio.
config SND_USB_UA101
config SND_USB_UA101
tristate "Edirol UA-101 driver (EXPERIMENTAL)"
tristate "Edirol UA-101
/UA-1000
driver (EXPERIMENTAL)"
depends on EXPERIMENTAL
depends on EXPERIMENTAL
select SND_PCM
select SND_PCM
select SND_RAWMIDI
select SND_RAWMIDI
help
help
Say Y here to include support for the Edirol UA-101 a
udio/MIDI
Say Y here to include support for the Edirol UA-101 a
nd UA-1000
interface
.
audio/MIDI interfaces
.
To compile this driver as a module, choose M here: the module
To compile this driver as a module, choose M here: the module
will be called snd-ua101.
will be called snd-ua101.
...
...
sound/usb/ua101.c
View file @
156366d3
/*
/*
* Edirol UA-101 driver
* Edirol UA-101
/UA-1000
driver
* Copyright (c) Clemens Ladisch <clemens@ladisch.de>
* Copyright (c) Clemens Ladisch <clemens@ladisch.de>
*
*
* This driver is free software: you can redistribute it and/or modify
* This driver is free software: you can redistribute it and/or modify
...
@@ -25,13 +25,10 @@
...
@@ -25,13 +25,10 @@
#include <sound/pcm_params.h>
#include <sound/pcm_params.h>
#include "usbaudio.h"
#include "usbaudio.h"
MODULE_DESCRIPTION
(
"Edirol UA-101 driver"
);
MODULE_DESCRIPTION
(
"Edirol UA-101
/1000
driver"
);
MODULE_AUTHOR
(
"Clemens Ladisch <clemens@ladisch.de>"
);
MODULE_AUTHOR
(
"Clemens Ladisch <clemens@ladisch.de>"
);
MODULE_LICENSE
(
"GPL v2"
);
MODULE_LICENSE
(
"GPL v2"
);
MODULE_SUPPORTED_DEVICE
(
"{{Edirol,UA-101}}"
);
MODULE_SUPPORTED_DEVICE
(
"{{Edirol,UA-101},{Edirol,UA-1000}}"
);
/* I use my UA-1A for testing because I don't have a UA-101 ... */
#define UA1A_HACK
/*
/*
* Should not be lower than the minimum scheduling delay of the host
* Should not be lower than the minimum scheduling delay of the host
...
@@ -132,9 +129,6 @@ struct ua101 {
...
@@ -132,9 +129,6 @@ struct ua101 {
dma_addr_t
dma
;
dma_addr_t
dma
;
}
buffers
[
MAX_MEMORY_BUFFERS
];
}
buffers
[
MAX_MEMORY_BUFFERS
];
}
capture
,
playback
;
}
capture
,
playback
;
unsigned
int
fps
[
10
];
unsigned
int
frame_counter
;
};
};
static
DEFINE_MUTEX
(
devices_mutex
);
static
DEFINE_MUTEX
(
devices_mutex
);
...
@@ -424,16 +418,6 @@ static void capture_urb_complete(struct urb *urb)
...
@@ -424,16 +418,6 @@ static void capture_urb_complete(struct urb *urb)
if
(
do_period_elapsed
)
if
(
do_period_elapsed
)
snd_pcm_period_elapsed
(
stream
->
substream
);
snd_pcm_period_elapsed
(
stream
->
substream
);
/* for debugging: measure the sample rate relative to the USB clock */
ua
->
fps
[
ua
->
frame_counter
++
/
ua
->
packets_per_second
]
+=
frames
;
if
(
ua
->
frame_counter
>=
ARRAY_SIZE
(
ua
->
fps
)
*
ua
->
packets_per_second
)
{
printk
(
KERN_DEBUG
"capture rate:"
);
for
(
frames
=
0
;
frames
<
ARRAY_SIZE
(
ua
->
fps
);
++
frames
)
printk
(
KERN_CONT
" %u"
,
ua
->
fps
[
frames
]);
printk
(
KERN_CONT
"
\n
"
);
memset
(
ua
->
fps
,
0
,
sizeof
(
ua
->
fps
));
ua
->
frame_counter
=
0
;
}
return
;
return
;
stream_stopped:
stream_stopped:
...
@@ -1200,13 +1184,30 @@ static int ua101_probe(struct usb_interface *interface,
...
@@ -1200,13 +1184,30 @@ static int ua101_probe(struct usb_interface *interface,
.
type
=
QUIRK_MIDI_FIXED_ENDPOINT
,
.
type
=
QUIRK_MIDI_FIXED_ENDPOINT
,
.
data
=
&
midi_ep
.
data
=
&
midi_ep
};
};
static
const
int
intf_numbers
[
2
][
3
]
=
{
{
/* UA-101 */
[
INTF_PLAYBACK
]
=
0
,
[
INTF_CAPTURE
]
=
1
,
[
INTF_MIDI
]
=
2
,
},
{
/* UA-1000 */
[
INTF_CAPTURE
]
=
1
,
[
INTF_PLAYBACK
]
=
2
,
[
INTF_MIDI
]
=
3
,
},
};
struct
snd_card
*
card
;
struct
snd_card
*
card
;
struct
ua101
*
ua
;
struct
ua101
*
ua
;
unsigned
int
card_index
,
i
;
unsigned
int
card_index
,
i
;
int
is_ua1000
;
const
char
*
name
;
char
usb_path
[
32
];
char
usb_path
[
32
];
int
err
;
int
err
;
if
(
interface
->
altsetting
->
desc
.
bInterfaceNumber
!=
0
)
is_ua1000
=
usb_id
->
idProduct
==
0x0044
;
if
(
interface
->
altsetting
->
desc
.
bInterfaceNumber
!=
intf_numbers
[
is_ua1000
][
0
])
return
-
ENODEV
;
return
-
ENODEV
;
mutex_lock
(
&
devices_mutex
);
mutex_lock
(
&
devices_mutex
);
...
@@ -1239,20 +1240,13 @@ static int ua101_probe(struct usb_interface *interface,
...
@@ -1239,20 +1240,13 @@ static int ua101_probe(struct usb_interface *interface,
init_waitqueue_head
(
&
ua
->
rate_feedback_wait
);
init_waitqueue_head
(
&
ua
->
rate_feedback_wait
);
init_waitqueue_head
(
&
ua
->
alsa_playback_wait
);
init_waitqueue_head
(
&
ua
->
alsa_playback_wait
);
#ifdef UA1A_HACK
if
(
ua
->
dev
->
descriptor
.
idProduct
==
cpu_to_le16
(
0x0018
))
{
ua
->
intf
[
2
]
=
interface
;
ua
->
intf
[
0
]
=
usb_ifnum_to_if
(
ua
->
dev
,
1
);
ua
->
intf
[
1
]
=
usb_ifnum_to_if
(
ua
->
dev
,
2
);
usb_driver_claim_interface
(
&
ua101_driver
,
ua
->
intf
[
0
],
ua
);
usb_driver_claim_interface
(
&
ua101_driver
,
ua
->
intf
[
1
],
ua
);
}
else
{
#endif
ua
->
intf
[
0
]
=
interface
;
ua
->
intf
[
0
]
=
interface
;
for
(
i
=
1
;
i
<
ARRAY_SIZE
(
ua
->
intf
);
++
i
)
{
for
(
i
=
1
;
i
<
ARRAY_SIZE
(
ua
->
intf
);
++
i
)
{
ua
->
intf
[
i
]
=
usb_ifnum_to_if
(
ua
->
dev
,
i
);
ua
->
intf
[
i
]
=
usb_ifnum_to_if
(
ua
->
dev
,
intf_numbers
[
is_ua1000
][
i
]);
if
(
!
ua
->
intf
[
i
])
{
if
(
!
ua
->
intf
[
i
])
{
dev_err
(
&
ua
->
dev
->
dev
,
"interface %u not found
\n
"
,
i
);
dev_err
(
&
ua
->
dev
->
dev
,
"interface %u not found
\n
"
,
intf_numbers
[
is_ua1000
][
i
]);
err
=
-
ENXIO
;
err
=
-
ENXIO
;
goto
probe_error
;
goto
probe_error
;
}
}
...
@@ -1264,39 +1258,19 @@ static int ua101_probe(struct usb_interface *interface,
...
@@ -1264,39 +1258,19 @@ static int ua101_probe(struct usb_interface *interface,
goto
probe_error
;
goto
probe_error
;
}
}
}
}
#ifdef UA1A_HACK
}
#endif
snd_card_set_dev
(
card
,
&
interface
->
dev
);
snd_card_set_dev
(
card
,
&
interface
->
dev
);
#ifdef UA1A_HACK
if
(
ua
->
dev
->
descriptor
.
idProduct
==
cpu_to_le16
(
0x0018
))
{
ua
->
format_bit
=
SNDRV_PCM_FMTBIT_S16_LE
;
ua
->
rate
=
44100
;
ua
->
packets_per_second
=
1000
;
ua
->
capture
.
channels
=
2
;
ua
->
playback
.
channels
=
2
;
ua
->
capture
.
frame_bytes
=
4
;
ua
->
playback
.
frame_bytes
=
4
;
ua
->
capture
.
usb_pipe
=
usb_rcvisocpipe
(
ua
->
dev
,
2
);
ua
->
playback
.
usb_pipe
=
usb_sndisocpipe
(
ua
->
dev
,
1
);
ua
->
capture
.
max_packet_bytes
=
192
;
ua
->
playback
.
max_packet_bytes
=
192
;
}
else
{
#endif
err
=
detect_usb_format
(
ua
);
err
=
detect_usb_format
(
ua
);
if
(
err
<
0
)
if
(
err
<
0
)
goto
probe_error
;
goto
probe_error
;
#ifdef UA1A_HACK
}
#endif
name
=
usb_id
->
idProduct
==
0x0044
?
"UA-1000"
:
"UA-101"
;
strcpy
(
card
->
driver
,
"UA-101"
);
strcpy
(
card
->
driver
,
"UA-101"
);
strcpy
(
card
->
shortname
,
"UA-101"
);
strcpy
(
card
->
shortname
,
name
);
usb_make_path
(
ua
->
dev
,
usb_path
,
sizeof
(
usb_path
));
usb_make_path
(
ua
->
dev
,
usb_path
,
sizeof
(
usb_path
));
snprintf
(
ua
->
card
->
longname
,
sizeof
(
ua
->
card
->
longname
),
snprintf
(
ua
->
card
->
longname
,
sizeof
(
ua
->
card
->
longname
),
"EDIROL
UA-101 (serial %s), %u Hz at %s, %s speed"
,
"EDIROL
%s (serial %s), %u Hz at %s, %s speed"
,
name
,
ua
->
dev
->
serial
?
ua
->
dev
->
serial
:
"?"
,
ua
->
rate
,
usb_path
,
ua
->
dev
->
serial
?
ua
->
dev
->
serial
:
"?"
,
ua
->
rate
,
usb_path
,
ua
->
dev
->
speed
==
USB_SPEED_HIGH
?
"high"
:
"full"
);
ua
->
dev
->
speed
==
USB_SPEED_HIGH
?
"high"
:
"full"
);
...
@@ -1314,24 +1288,18 @@ static int ua101_probe(struct usb_interface *interface,
...
@@ -1314,24 +1288,18 @@ static int ua101_probe(struct usb_interface *interface,
if
(
err
<
0
)
if
(
err
<
0
)
goto
probe_error
;
goto
probe_error
;
err
=
snd_pcm_new
(
card
,
"UA-101"
,
0
,
1
,
1
,
&
ua
->
pcm
);
err
=
snd_pcm_new
(
card
,
name
,
0
,
1
,
1
,
&
ua
->
pcm
);
if
(
err
<
0
)
if
(
err
<
0
)
goto
probe_error
;
goto
probe_error
;
ua
->
pcm
->
private_data
=
ua
;
ua
->
pcm
->
private_data
=
ua
;
strcpy
(
ua
->
pcm
->
name
,
"UA-101"
);
strcpy
(
ua
->
pcm
->
name
,
name
);
snd_pcm_set_ops
(
ua
->
pcm
,
SNDRV_PCM_STREAM_PLAYBACK
,
&
playback_pcm_ops
);
snd_pcm_set_ops
(
ua
->
pcm
,
SNDRV_PCM_STREAM_PLAYBACK
,
&
playback_pcm_ops
);
snd_pcm_set_ops
(
ua
->
pcm
,
SNDRV_PCM_STREAM_CAPTURE
,
&
capture_pcm_ops
);
snd_pcm_set_ops
(
ua
->
pcm
,
SNDRV_PCM_STREAM_CAPTURE
,
&
capture_pcm_ops
);
#ifdef UA1A_HACK
if
(
ua
->
dev
->
descriptor
.
idProduct
!=
cpu_to_le16
(
0x0018
))
{
#endif
err
=
snd_usbmidi_create
(
card
,
ua
->
intf
[
INTF_MIDI
],
err
=
snd_usbmidi_create
(
card
,
ua
->
intf
[
INTF_MIDI
],
&
ua
->
midi_list
,
&
midi_quirk
);
&
ua
->
midi_list
,
&
midi_quirk
);
if
(
err
<
0
)
if
(
err
<
0
)
goto
probe_error
;
goto
probe_error
;
#ifdef UA1A_HACK
}
#endif
err
=
snd_card_register
(
card
);
err
=
snd_card_register
(
card
);
if
(
err
<
0
)
if
(
err
<
0
)
...
@@ -1386,11 +1354,9 @@ static void ua101_disconnect(struct usb_interface *interface)
...
@@ -1386,11 +1354,9 @@ static void ua101_disconnect(struct usb_interface *interface)
}
}
static
struct
usb_device_id
ua101_ids
[]
=
{
static
struct
usb_device_id
ua101_ids
[]
=
{
#ifdef UA1A_HACK
{
USB_DEVICE
(
0x0582
,
0x0044
)
},
/* UA-1000 high speed */
{
USB_DEVICE
(
0x0582
,
0x0018
)
},
{
USB_DEVICE
(
0x0582
,
0x007d
)
},
/* UA-101 high speed */
#endif
{
USB_DEVICE
(
0x0582
,
0x008d
)
},
/* UA-101 full speed */
{
USB_DEVICE
(
0x0582
,
0x007d
)
},
{
USB_DEVICE
(
0x0582
,
0x008d
)
},
{
}
{
}
};
};
MODULE_DEVICE_TABLE
(
usb
,
ua101_ids
);
MODULE_DEVICE_TABLE
(
usb
,
ua101_ids
);
...
...
sound/usb/usbaudio.c
View file @
156366d3
...
@@ -3386,58 +3386,6 @@ static int create_uaxx_quirk(struct snd_usb_audio *chip,
...
@@ -3386,58 +3386,6 @@ static int create_uaxx_quirk(struct snd_usb_audio *chip,
return
0
;
return
0
;
}
}
/*
* Create a stream for an Edirol UA-1000 interface.
*/
static
int
create_ua1000_quirk
(
struct
snd_usb_audio
*
chip
,
struct
usb_interface
*
iface
,
const
struct
snd_usb_audio_quirk
*
quirk
)
{
static
const
struct
audioformat
ua1000_format
=
{
.
format
=
SNDRV_PCM_FORMAT_S32_LE
,
.
fmt_type
=
UAC_FORMAT_TYPE_I
,
.
altsetting
=
1
,
.
altset_idx
=
1
,
.
attributes
=
0
,
.
rates
=
SNDRV_PCM_RATE_CONTINUOUS
,
};
struct
usb_host_interface
*
alts
;
struct
usb_interface_descriptor
*
altsd
;
struct
audioformat
*
fp
;
int
stream
,
err
;
if
(
iface
->
num_altsetting
!=
2
)
return
-
ENXIO
;
alts
=
&
iface
->
altsetting
[
1
];
altsd
=
get_iface_desc
(
alts
);
if
(
alts
->
extralen
!=
11
||
alts
->
extra
[
1
]
!=
USB_DT_CS_INTERFACE
||
altsd
->
bNumEndpoints
!=
1
)
return
-
ENXIO
;
fp
=
kmemdup
(
&
ua1000_format
,
sizeof
(
*
fp
),
GFP_KERNEL
);
if
(
!
fp
)
return
-
ENOMEM
;
fp
->
channels
=
alts
->
extra
[
4
];
fp
->
iface
=
altsd
->
bInterfaceNumber
;
fp
->
endpoint
=
get_endpoint
(
alts
,
0
)
->
bEndpointAddress
;
fp
->
ep_attr
=
get_endpoint
(
alts
,
0
)
->
bmAttributes
;
fp
->
datainterval
=
parse_datainterval
(
chip
,
alts
);
fp
->
maxpacksize
=
le16_to_cpu
(
get_endpoint
(
alts
,
0
)
->
wMaxPacketSize
);
fp
->
rate_max
=
fp
->
rate_min
=
combine_triple
(
&
alts
->
extra
[
8
]);
stream
=
(
fp
->
endpoint
&
USB_DIR_IN
)
?
SNDRV_PCM_STREAM_CAPTURE
:
SNDRV_PCM_STREAM_PLAYBACK
;
err
=
add_audio_endpoint
(
chip
,
stream
,
fp
);
if
(
err
<
0
)
{
kfree
(
fp
);
return
err
;
}
/* FIXME: playback must be synchronized to capture */
usb_set_interface
(
chip
->
dev
,
fp
->
iface
,
0
);
return
0
;
}
static
int
snd_usb_create_quirk
(
struct
snd_usb_audio
*
chip
,
static
int
snd_usb_create_quirk
(
struct
snd_usb_audio
*
chip
,
struct
usb_interface
*
iface
,
struct
usb_interface
*
iface
,
const
struct
snd_usb_audio_quirk
*
quirk
);
const
struct
snd_usb_audio_quirk
*
quirk
);
...
@@ -3686,7 +3634,6 @@ static int snd_usb_create_quirk(struct snd_usb_audio *chip,
...
@@ -3686,7 +3634,6 @@ static int snd_usb_create_quirk(struct snd_usb_audio *chip,
[
QUIRK_MIDI_CME
]
=
create_any_midi_quirk
,
[
QUIRK_MIDI_CME
]
=
create_any_midi_quirk
,
[
QUIRK_AUDIO_STANDARD_INTERFACE
]
=
create_standard_audio_quirk
,
[
QUIRK_AUDIO_STANDARD_INTERFACE
]
=
create_standard_audio_quirk
,
[
QUIRK_AUDIO_FIXED_ENDPOINT
]
=
create_fixed_stream_quirk
,
[
QUIRK_AUDIO_FIXED_ENDPOINT
]
=
create_fixed_stream_quirk
,
[
QUIRK_AUDIO_EDIROL_UA1000
]
=
create_ua1000_quirk
,
[
QUIRK_AUDIO_EDIROL_UAXX
]
=
create_uaxx_quirk
,
[
QUIRK_AUDIO_EDIROL_UAXX
]
=
create_uaxx_quirk
,
[
QUIRK_AUDIO_ALIGN_TRANSFER
]
=
create_align_transfer_quirk
[
QUIRK_AUDIO_ALIGN_TRANSFER
]
=
create_align_transfer_quirk
};
};
...
...
sound/usb/usbaudio.h
View file @
156366d3
...
@@ -75,7 +75,6 @@ enum quirk_type {
...
@@ -75,7 +75,6 @@ enum quirk_type {
QUIRK_MIDI_US122L
,
QUIRK_MIDI_US122L
,
QUIRK_AUDIO_STANDARD_INTERFACE
,
QUIRK_AUDIO_STANDARD_INTERFACE
,
QUIRK_AUDIO_FIXED_ENDPOINT
,
QUIRK_AUDIO_FIXED_ENDPOINT
,
QUIRK_AUDIO_EDIROL_UA1000
,
QUIRK_AUDIO_EDIROL_UAXX
,
QUIRK_AUDIO_EDIROL_UAXX
,
QUIRK_AUDIO_ALIGN_TRANSFER
,
QUIRK_AUDIO_ALIGN_TRANSFER
,
...
@@ -112,7 +111,7 @@ struct snd_usb_midi_endpoint_info {
...
@@ -112,7 +111,7 @@ struct snd_usb_midi_endpoint_info {
/* for QUIRK_AUDIO/MIDI_STANDARD_INTERFACE, data is NULL */
/* for QUIRK_AUDIO/MIDI_STANDARD_INTERFACE, data is NULL */
/* for QUIRK_AUDIO_EDIROL_UA
700_UA25/UA1000
, data is NULL */
/* for QUIRK_AUDIO_EDIROL_UA
XX
, data is NULL */
/* for QUIRK_IGNORE_INTERFACE, data is NULL */
/* for QUIRK_IGNORE_INTERFACE, data is NULL */
...
...
sound/usb/usbquirks.h
View file @
156366d3
...
@@ -1015,36 +1015,6 @@ YAMAHA_DEVICE(0x7010, "UB99"),
...
@@ -1015,36 +1015,6 @@ YAMAHA_DEVICE(0x7010, "UB99"),
}
}
}
}
},
},
{
USB_DEVICE
(
0x0582
,
0x0044
),
.
driver_info
=
(
unsigned
long
)
&
(
const
struct
snd_usb_audio_quirk
)
{
.
vendor_name
=
"Roland"
,
.
product_name
=
"UA-1000"
,
.
ifnum
=
QUIRK_ANY_INTERFACE
,
.
type
=
QUIRK_COMPOSITE
,
.
data
=
(
const
struct
snd_usb_audio_quirk
[])
{
{
.
ifnum
=
1
,
.
type
=
QUIRK_AUDIO_EDIROL_UA1000
},
{
.
ifnum
=
2
,
.
type
=
QUIRK_AUDIO_EDIROL_UA1000
},
{
.
ifnum
=
3
,
.
type
=
QUIRK_MIDI_FIXED_ENDPOINT
,
.
data
=
&
(
const
struct
snd_usb_midi_endpoint_info
)
{
.
out_cables
=
0x0003
,
.
in_cables
=
0x0003
}
},
{
.
ifnum
=
-
1
}
}
}
},
{
{
/* has ID 0x0049 when not in "Advanced Driver" mode */
/* has ID 0x0049 when not in "Advanced Driver" mode */
USB_DEVICE
(
0x0582
,
0x0047
),
USB_DEVICE
(
0x0582
,
0x0047
),
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment