aboutsummaryrefslogtreecommitdiffstats
path: root/sound/usb/usbmixer.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/usb/usbmixer.c')
-rw-r--r--sound/usb/usbmixer.c70
1 files changed, 41 insertions, 29 deletions
diff --git a/sound/usb/usbmixer.c b/sound/usb/usbmixer.c
index ce86283ee0fa..491e975a0c87 100644
--- a/sound/usb/usbmixer.c
+++ b/sound/usb/usbmixer.c
@@ -46,6 +46,27 @@
46/* ignore error from controls - for debugging */ 46/* ignore error from controls - for debugging */
47/* #define IGNORE_CTL_ERROR */ 47/* #define IGNORE_CTL_ERROR */
48 48
49/*
50 * Sound Blaster remote control configuration
51 *
52 * format of remote control data:
53 * Extigy: xx 00
54 * Audigy 2 NX: 06 80 xx 00 00 00
55 * Live! 24-bit: 06 80 xx yy 22 83
56 */
57static const struct rc_config {
58 u32 usb_id;
59 u8 offset;
60 u8 length;
61 u8 packet_length;
62 u8 mute_mixer_id;
63 u32 mute_code;
64} rc_configs[] = {
65 { USB_ID(0x041e, 0x3000), 0, 1, 2, 18, 0x0013 }, /* Extigy */
66 { USB_ID(0x041e, 0x3020), 2, 1, 6, 18, 0x0013 }, /* Audigy 2 NX */
67 { USB_ID(0x041e, 0x3040), 2, 2, 6, 2, 0x6e91 }, /* Live! 24-bit */
68};
69
49struct usb_mixer_interface { 70struct usb_mixer_interface {
50 struct snd_usb_audio *chip; 71 struct snd_usb_audio *chip;
51 unsigned int ctrlif; 72 unsigned int ctrlif;
@@ -55,11 +76,7 @@ struct usb_mixer_interface {
55 struct usb_mixer_elem_info **id_elems; /* array[256], indexed by unit id */ 76 struct usb_mixer_elem_info **id_elems; /* array[256], indexed by unit id */
56 77
57 /* Sound Blaster remote control stuff */ 78 /* Sound Blaster remote control stuff */
58 enum { 79 const struct rc_config *rc_cfg;
59 RC_NONE,
60 RC_EXTIGY,
61 RC_AUDIGY2NX,
62 } rc_type;
63 unsigned long rc_hwdep_open; 80 unsigned long rc_hwdep_open;
64 u32 rc_code; 81 u32 rc_code;
65 wait_queue_head_t rc_waitq; 82 wait_queue_head_t rc_waitq;
@@ -1647,7 +1664,7 @@ static void snd_usb_mixer_notify_id(struct usb_mixer_interface *mixer,
1647static void snd_usb_mixer_memory_change(struct usb_mixer_interface *mixer, 1664static void snd_usb_mixer_memory_change(struct usb_mixer_interface *mixer,
1648 int unitid) 1665 int unitid)
1649{ 1666{
1650 if (mixer->rc_type == RC_NONE) 1667 if (!mixer->rc_cfg)
1651 return; 1668 return;
1652 /* unit ids specific to Extigy/Audigy 2 NX: */ 1669 /* unit ids specific to Extigy/Audigy 2 NX: */
1653 switch (unitid) { 1670 switch (unitid) {
@@ -1732,20 +1749,19 @@ static void snd_usb_soundblaster_remote_complete(struct urb *urb,
1732 struct pt_regs *regs) 1749 struct pt_regs *regs)
1733{ 1750{
1734 struct usb_mixer_interface *mixer = urb->context; 1751 struct usb_mixer_interface *mixer = urb->context;
1735 /* 1752 const struct rc_config *rc = mixer->rc_cfg;
1736 * format of remote control data:
1737 * Extigy: xx 00
1738 * Audigy 2 NX: 06 80 xx 00 00 00
1739 */
1740 int offset = mixer->rc_type == RC_EXTIGY ? 0 : 2;
1741 u32 code; 1753 u32 code;
1742 1754
1743 if (urb->status < 0 || urb->actual_length <= offset) 1755 if (urb->status < 0 || urb->actual_length < rc->packet_length)
1744 return; 1756 return;
1745 code = mixer->rc_buffer[offset]; 1757
1758 code = mixer->rc_buffer[rc->offset];
1759 if (rc->length == 2)
1760 code |= mixer->rc_buffer[rc->offset + 1] << 8;
1761
1746 /* the Mute button actually changes the mixer control */ 1762 /* the Mute button actually changes the mixer control */
1747 if (code == 13) 1763 if (code == rc->mute_code)
1748 snd_usb_mixer_notify_id(mixer, 18); 1764 snd_usb_mixer_notify_id(mixer, rc->mute_mixer_id);
1749 mixer->rc_code = code; 1765 mixer->rc_code = code;
1750 wmb(); 1766 wmb();
1751 wake_up(&mixer->rc_waitq); 1767 wake_up(&mixer->rc_waitq);
@@ -1801,21 +1817,17 @@ static unsigned int snd_usb_sbrc_hwdep_poll(struct snd_hwdep *hw, struct file *f
1801static int snd_usb_soundblaster_remote_init(struct usb_mixer_interface *mixer) 1817static int snd_usb_soundblaster_remote_init(struct usb_mixer_interface *mixer)
1802{ 1818{
1803 struct snd_hwdep *hwdep; 1819 struct snd_hwdep *hwdep;
1804 int err, len; 1820 int err, len, i;
1805 1821
1806 switch (mixer->chip->usb_id) { 1822 for (i = 0; i < ARRAY_SIZE(rc_configs); ++i)
1807 case USB_ID(0x041e, 0x3000): 1823 if (rc_configs[i].usb_id == mixer->chip->usb_id)
1808 mixer->rc_type = RC_EXTIGY; 1824 break;
1809 len = 2; 1825 if (i >= ARRAY_SIZE(rc_configs))
1810 break;
1811 case USB_ID(0x041e, 0x3020):
1812 mixer->rc_type = RC_AUDIGY2NX;
1813 len = 6;
1814 break;
1815 default:
1816 return 0; 1826 return 0;
1817 } 1827 mixer->rc_cfg = &rc_configs[i];
1818 1828
1829 len = mixer->rc_cfg->packet_length;
1830
1819 init_waitqueue_head(&mixer->rc_waitq); 1831 init_waitqueue_head(&mixer->rc_waitq);
1820 err = snd_hwdep_new(mixer->chip->card, "SB remote control", 0, &hwdep); 1832 err = snd_hwdep_new(mixer->chip->card, "SB remote control", 0, &hwdep);
1821 if (err < 0) 1833 if (err < 0)
@@ -1998,7 +2010,7 @@ int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif)
1998 if ((err = snd_audigy2nx_controls_create(mixer)) < 0) 2010 if ((err = snd_audigy2nx_controls_create(mixer)) < 0)
1999 goto _error; 2011 goto _error;
2000 if (!snd_card_proc_new(chip->card, "audigy2nx", &entry)) 2012 if (!snd_card_proc_new(chip->card, "audigy2nx", &entry))
2001 snd_info_set_text_ops(entry, mixer, 1024, 2013 snd_info_set_text_ops(entry, mixer,
2002 snd_audigy2nx_proc_read); 2014 snd_audigy2nx_proc_read);
2003 } 2015 }
2004 2016