diff options
| -rw-r--r-- | sound/core/pcm_lib.c | 13 | ||||
| -rw-r--r-- | sound/core/pcm_native.c | 39 | ||||
| -rw-r--r-- | sound/pci/aw2/aw2-alsa.c | 11 | ||||
| -rw-r--r-- | sound/pci/emu10k1/emufx.c | 36 | ||||
| -rw-r--r-- | sound/pci/hda/hda_intel.c | 9 | ||||
| -rw-r--r-- | sound/pci/hda/patch_realtek.c | 84 | ||||
| -rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 2 | ||||
| -rw-r--r-- | sound/usb/caiaq/input.c | 2 | ||||
| -rw-r--r-- | sound/usb/midi.c | 110 | ||||
| -rw-r--r-- | sound/usb/midi.h | 2 | ||||
| -rw-r--r-- | sound/usb/quirks-table.h | 11 | ||||
| -rw-r--r-- | sound/usb/quirks.c | 1 | ||||
| -rw-r--r-- | sound/usb/usbaudio.h | 1 |
13 files changed, 219 insertions, 102 deletions
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index a2ff86189d2a..e9d98be190c5 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c | |||
| @@ -345,7 +345,9 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream, | |||
| 345 | new_hw_ptr = hw_base + pos; | 345 | new_hw_ptr = hw_base + pos; |
| 346 | } | 346 | } |
| 347 | __delta: | 347 | __delta: |
| 348 | delta = (new_hw_ptr - old_hw_ptr) % runtime->boundary; | 348 | delta = new_hw_ptr - old_hw_ptr; |
| 349 | if (delta < 0) | ||
| 350 | delta += runtime->boundary; | ||
| 349 | if (xrun_debug(substream, in_interrupt ? | 351 | if (xrun_debug(substream, in_interrupt ? |
| 350 | XRUN_DEBUG_PERIODUPDATE : XRUN_DEBUG_HWPTRUPDATE)) { | 352 | XRUN_DEBUG_PERIODUPDATE : XRUN_DEBUG_HWPTRUPDATE)) { |
| 351 | char name[16]; | 353 | char name[16]; |
| @@ -439,8 +441,13 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream, | |||
| 439 | snd_pcm_playback_silence(substream, new_hw_ptr); | 441 | snd_pcm_playback_silence(substream, new_hw_ptr); |
| 440 | 442 | ||
| 441 | if (in_interrupt) { | 443 | if (in_interrupt) { |
| 442 | runtime->hw_ptr_interrupt = new_hw_ptr - | 444 | delta = new_hw_ptr - runtime->hw_ptr_interrupt; |
| 443 | (new_hw_ptr % runtime->period_size); | 445 | if (delta < 0) |
| 446 | delta += runtime->boundary; | ||
| 447 | delta -= (snd_pcm_uframes_t)delta % runtime->period_size; | ||
| 448 | runtime->hw_ptr_interrupt += delta; | ||
| 449 | if (runtime->hw_ptr_interrupt >= runtime->boundary) | ||
| 450 | runtime->hw_ptr_interrupt -= runtime->boundary; | ||
| 444 | } | 451 | } |
| 445 | runtime->hw_ptr_base = hw_base; | 452 | runtime->hw_ptr_base = hw_base; |
| 446 | runtime->status->hw_ptr = new_hw_ptr; | 453 | runtime->status->hw_ptr = new_hw_ptr; |
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 644c2bb17b86..303ac04ff6e4 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c | |||
| @@ -27,7 +27,6 @@ | |||
| 27 | #include <linux/pm_qos_params.h> | 27 | #include <linux/pm_qos_params.h> |
| 28 | #include <linux/uio.h> | 28 | #include <linux/uio.h> |
| 29 | #include <linux/dma-mapping.h> | 29 | #include <linux/dma-mapping.h> |
| 30 | #include <linux/math64.h> | ||
| 31 | #include <sound/core.h> | 30 | #include <sound/core.h> |
| 32 | #include <sound/control.h> | 31 | #include <sound/control.h> |
| 33 | #include <sound/info.h> | 32 | #include <sound/info.h> |
| @@ -370,38 +369,6 @@ static int period_to_usecs(struct snd_pcm_runtime *runtime) | |||
| 370 | return usecs; | 369 | return usecs; |
| 371 | } | 370 | } |
| 372 | 371 | ||
| 373 | static int calc_boundary(struct snd_pcm_runtime *runtime) | ||
| 374 | { | ||
| 375 | u_int64_t boundary; | ||
| 376 | |||
| 377 | boundary = (u_int64_t)runtime->buffer_size * | ||
| 378 | (u_int64_t)runtime->period_size; | ||
| 379 | #if BITS_PER_LONG < 64 | ||
| 380 | /* try to find lowest common multiple for buffer and period */ | ||
| 381 | if (boundary > LONG_MAX - runtime->buffer_size) { | ||
| 382 | u_int32_t remainder = -1; | ||
| 383 | u_int32_t divident = runtime->buffer_size; | ||
| 384 | u_int32_t divisor = runtime->period_size; | ||
| 385 | while (remainder) { | ||
| 386 | remainder = divident % divisor; | ||
| 387 | if (remainder) { | ||
| 388 | divident = divisor; | ||
| 389 | divisor = remainder; | ||
| 390 | } | ||
| 391 | } | ||
| 392 | boundary = div_u64(boundary, divisor); | ||
| 393 | if (boundary > LONG_MAX - runtime->buffer_size) | ||
| 394 | return -ERANGE; | ||
| 395 | } | ||
| 396 | #endif | ||
| 397 | if (boundary == 0) | ||
| 398 | return -ERANGE; | ||
| 399 | runtime->boundary = boundary; | ||
| 400 | while (runtime->boundary * 2 <= LONG_MAX - runtime->buffer_size) | ||
| 401 | runtime->boundary *= 2; | ||
| 402 | return 0; | ||
| 403 | } | ||
| 404 | |||
| 405 | static int snd_pcm_hw_params(struct snd_pcm_substream *substream, | 372 | static int snd_pcm_hw_params(struct snd_pcm_substream *substream, |
| 406 | struct snd_pcm_hw_params *params) | 373 | struct snd_pcm_hw_params *params) |
| 407 | { | 374 | { |
| @@ -477,9 +444,9 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream, | |||
| 477 | runtime->stop_threshold = runtime->buffer_size; | 444 | runtime->stop_threshold = runtime->buffer_size; |
| 478 | runtime->silence_threshold = 0; | 445 | runtime->silence_threshold = 0; |
| 479 | runtime->silence_size = 0; | 446 | runtime->silence_size = 0; |
| 480 | err = calc_boundary(runtime); | 447 | runtime->boundary = runtime->buffer_size; |
| 481 | if (err < 0) | 448 | while (runtime->boundary * 2 <= LONG_MAX - runtime->buffer_size) |
| 482 | goto _error; | 449 | runtime->boundary *= 2; |
| 483 | 450 | ||
| 484 | snd_pcm_timer_resolution_change(substream); | 451 | snd_pcm_timer_resolution_change(substream); |
| 485 | runtime->status->state = SNDRV_PCM_STATE_SETUP; | 452 | runtime->status->state = SNDRV_PCM_STATE_SETUP; |
diff --git a/sound/pci/aw2/aw2-alsa.c b/sound/pci/aw2/aw2-alsa.c index 67921f93a41e..c15002242d98 100644 --- a/sound/pci/aw2/aw2-alsa.c +++ b/sound/pci/aw2/aw2-alsa.c | |||
| @@ -26,7 +26,7 @@ | |||
| 26 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
| 27 | #include <linux/interrupt.h> | 27 | #include <linux/interrupt.h> |
| 28 | #include <linux/delay.h> | 28 | #include <linux/delay.h> |
| 29 | #include <asm/io.h> | 29 | #include <linux/io.h> |
| 30 | #include <sound/core.h> | 30 | #include <sound/core.h> |
| 31 | #include <sound/initval.h> | 31 | #include <sound/initval.h> |
| 32 | #include <sound/pcm.h> | 32 | #include <sound/pcm.h> |
| @@ -44,9 +44,6 @@ MODULE_LICENSE("GPL"); | |||
| 44 | /********************************* | 44 | /********************************* |
| 45 | * DEFINES | 45 | * DEFINES |
| 46 | ********************************/ | 46 | ********************************/ |
| 47 | #define PCI_VENDOR_ID_SAA7146 0x1131 | ||
| 48 | #define PCI_DEVICE_ID_SAA7146 0x7146 | ||
| 49 | |||
| 50 | #define CTL_ROUTE_ANALOG 0 | 47 | #define CTL_ROUTE_ANALOG 0 |
| 51 | #define CTL_ROUTE_DIGITAL 1 | 48 | #define CTL_ROUTE_DIGITAL 1 |
| 52 | 49 | ||
| @@ -165,7 +162,7 @@ module_param_array(enable, bool, NULL, 0444); | |||
| 165 | MODULE_PARM_DESC(enable, "Enable Audiowerk2 soundcard."); | 162 | MODULE_PARM_DESC(enable, "Enable Audiowerk2 soundcard."); |
| 166 | 163 | ||
| 167 | static DEFINE_PCI_DEVICE_TABLE(snd_aw2_ids) = { | 164 | static DEFINE_PCI_DEVICE_TABLE(snd_aw2_ids) = { |
| 168 | {PCI_VENDOR_ID_SAA7146, PCI_DEVICE_ID_SAA7146, 0, 0, | 165 | {PCI_VENDOR_ID_PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7146, 0, 0, |
| 169 | 0, 0, 0}, | 166 | 0, 0, 0}, |
| 170 | {0} | 167 | {0} |
| 171 | }; | 168 | }; |
| @@ -419,7 +416,7 @@ static int snd_aw2_pcm_playback_open(struct snd_pcm_substream *substream) | |||
| 419 | { | 416 | { |
| 420 | struct snd_pcm_runtime *runtime = substream->runtime; | 417 | struct snd_pcm_runtime *runtime = substream->runtime; |
| 421 | 418 | ||
| 422 | snd_printdd(KERN_DEBUG "aw2: Playback_open \n"); | 419 | snd_printdd(KERN_DEBUG "aw2: Playback_open\n"); |
| 423 | runtime->hw = snd_aw2_playback_hw; | 420 | runtime->hw = snd_aw2_playback_hw; |
| 424 | return 0; | 421 | return 0; |
| 425 | } | 422 | } |
| @@ -435,7 +432,7 @@ static int snd_aw2_pcm_capture_open(struct snd_pcm_substream *substream) | |||
| 435 | { | 432 | { |
| 436 | struct snd_pcm_runtime *runtime = substream->runtime; | 433 | struct snd_pcm_runtime *runtime = substream->runtime; |
| 437 | 434 | ||
| 438 | snd_printdd(KERN_DEBUG "aw2: Capture_open \n"); | 435 | snd_printdd(KERN_DEBUG "aw2: Capture_open\n"); |
| 439 | runtime->hw = snd_aw2_capture_hw; | 436 | runtime->hw = snd_aw2_capture_hw; |
| 440 | return 0; | 437 | return 0; |
| 441 | } | 438 | } |
diff --git a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c index 4b302d86f5f2..7a9401462c1c 100644 --- a/sound/pci/emu10k1/emufx.c +++ b/sound/pci/emu10k1/emufx.c | |||
| @@ -35,6 +35,7 @@ | |||
| 35 | #include <linux/vmalloc.h> | 35 | #include <linux/vmalloc.h> |
| 36 | #include <linux/init.h> | 36 | #include <linux/init.h> |
| 37 | #include <linux/mutex.h> | 37 | #include <linux/mutex.h> |
| 38 | #include <linux/moduleparam.h> | ||
| 38 | 39 | ||
| 39 | #include <sound/core.h> | 40 | #include <sound/core.h> |
| 40 | #include <sound/tlv.h> | 41 | #include <sound/tlv.h> |
| @@ -50,6 +51,10 @@ | |||
| 50 | #define EMU10K1_CENTER_LFE_FROM_FRONT | 51 | #define EMU10K1_CENTER_LFE_FROM_FRONT |
| 51 | #endif | 52 | #endif |
| 52 | 53 | ||
| 54 | static bool high_res_gpr_volume; | ||
| 55 | module_param(high_res_gpr_volume, bool, 0444); | ||
| 56 | MODULE_PARM_DESC(high_res_gpr_volume, "GPR mixer controls use 31-bit range."); | ||
| 57 | |||
| 53 | /* | 58 | /* |
| 54 | * Tables | 59 | * Tables |
| 55 | */ | 60 | */ |
| @@ -296,6 +301,7 @@ static const u32 db_table[101] = { | |||
| 296 | 301 | ||
| 297 | /* EMU10k1/EMU10k2 DSP control db gain */ | 302 | /* EMU10k1/EMU10k2 DSP control db gain */ |
| 298 | static const DECLARE_TLV_DB_SCALE(snd_emu10k1_db_scale1, -4000, 40, 1); | 303 | static const DECLARE_TLV_DB_SCALE(snd_emu10k1_db_scale1, -4000, 40, 1); |
| 304 | static const DECLARE_TLV_DB_LINEAR(snd_emu10k1_db_linear, TLV_DB_GAIN_MUTE, 0); | ||
| 299 | 305 | ||
| 300 | static const u32 onoff_table[2] = { | 306 | static const u32 onoff_table[2] = { |
| 301 | 0x00000000, 0x00000001 | 307 | 0x00000000, 0x00000001 |
| @@ -1072,10 +1078,17 @@ snd_emu10k1_init_mono_control(struct snd_emu10k1_fx8010_control_gpr *ctl, | |||
| 1072 | strcpy(ctl->id.name, name); | 1078 | strcpy(ctl->id.name, name); |
| 1073 | ctl->vcount = ctl->count = 1; | 1079 | ctl->vcount = ctl->count = 1; |
| 1074 | ctl->gpr[0] = gpr + 0; ctl->value[0] = defval; | 1080 | ctl->gpr[0] = gpr + 0; ctl->value[0] = defval; |
| 1075 | ctl->min = 0; | 1081 | if (high_res_gpr_volume) { |
| 1076 | ctl->max = 100; | 1082 | ctl->min = 0; |
| 1077 | ctl->tlv = snd_emu10k1_db_scale1; | 1083 | ctl->max = 0x7fffffff; |
| 1078 | ctl->translation = EMU10K1_GPR_TRANSLATION_TABLE100; | 1084 | ctl->tlv = snd_emu10k1_db_linear; |
| 1085 | ctl->translation = EMU10K1_GPR_TRANSLATION_NONE; | ||
| 1086 | } else { | ||
| 1087 | ctl->min = 0; | ||
| 1088 | ctl->max = 100; | ||
| 1089 | ctl->tlv = snd_emu10k1_db_scale1; | ||
| 1090 | ctl->translation = EMU10K1_GPR_TRANSLATION_TABLE100; | ||
| 1091 | } | ||
| 1079 | } | 1092 | } |
| 1080 | 1093 | ||
| 1081 | static void __devinit | 1094 | static void __devinit |
| @@ -1087,10 +1100,17 @@ snd_emu10k1_init_stereo_control(struct snd_emu10k1_fx8010_control_gpr *ctl, | |||
| 1087 | ctl->vcount = ctl->count = 2; | 1100 | ctl->vcount = ctl->count = 2; |
| 1088 | ctl->gpr[0] = gpr + 0; ctl->value[0] = defval; | 1101 | ctl->gpr[0] = gpr + 0; ctl->value[0] = defval; |
| 1089 | ctl->gpr[1] = gpr + 1; ctl->value[1] = defval; | 1102 | ctl->gpr[1] = gpr + 1; ctl->value[1] = defval; |
| 1090 | ctl->min = 0; | 1103 | if (high_res_gpr_volume) { |
| 1091 | ctl->max = 100; | 1104 | ctl->min = 0; |
| 1092 | ctl->tlv = snd_emu10k1_db_scale1; | 1105 | ctl->max = 0x7fffffff; |
| 1093 | ctl->translation = EMU10K1_GPR_TRANSLATION_TABLE100; | 1106 | ctl->tlv = snd_emu10k1_db_linear; |
| 1107 | ctl->translation = EMU10K1_GPR_TRANSLATION_NONE; | ||
| 1108 | } else { | ||
| 1109 | ctl->min = 0; | ||
| 1110 | ctl->max = 100; | ||
| 1111 | ctl->tlv = snd_emu10k1_db_scale1; | ||
| 1112 | ctl->translation = EMU10K1_GPR_TRANSLATION_TABLE100; | ||
| 1113 | } | ||
| 1094 | } | 1114 | } |
| 1095 | 1115 | ||
| 1096 | static void __devinit | 1116 | static void __devinit |
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 170610e1d7da..77e22c2a8caa 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
| @@ -1097,6 +1097,7 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id) | |||
| 1097 | struct azx *chip = dev_id; | 1097 | struct azx *chip = dev_id; |
| 1098 | struct azx_dev *azx_dev; | 1098 | struct azx_dev *azx_dev; |
| 1099 | u32 status; | 1099 | u32 status; |
| 1100 | u8 sd_status; | ||
| 1100 | int i, ok; | 1101 | int i, ok; |
| 1101 | 1102 | ||
| 1102 | spin_lock(&chip->reg_lock); | 1103 | spin_lock(&chip->reg_lock); |
| @@ -1110,8 +1111,10 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id) | |||
| 1110 | for (i = 0; i < chip->num_streams; i++) { | 1111 | for (i = 0; i < chip->num_streams; i++) { |
| 1111 | azx_dev = &chip->azx_dev[i]; | 1112 | azx_dev = &chip->azx_dev[i]; |
| 1112 | if (status & azx_dev->sd_int_sta_mask) { | 1113 | if (status & azx_dev->sd_int_sta_mask) { |
| 1114 | sd_status = azx_sd_readb(azx_dev, SD_STS); | ||
| 1113 | azx_sd_writeb(azx_dev, SD_STS, SD_INT_MASK); | 1115 | azx_sd_writeb(azx_dev, SD_STS, SD_INT_MASK); |
| 1114 | if (!azx_dev->substream || !azx_dev->running) | 1116 | if (!azx_dev->substream || !azx_dev->running || |
| 1117 | !(sd_status & SD_INT_COMPLETE)) | ||
| 1115 | continue; | 1118 | continue; |
| 1116 | /* check whether this IRQ is really acceptable */ | 1119 | /* check whether this IRQ is really acceptable */ |
| 1117 | ok = azx_position_ok(chip, azx_dev); | 1120 | ok = azx_position_ok(chip, azx_dev); |
| @@ -2279,12 +2282,14 @@ static int azx_dev_free(struct snd_device *device) | |||
| 2279 | * white/black-listing for position_fix | 2282 | * white/black-listing for position_fix |
| 2280 | */ | 2283 | */ |
| 2281 | static struct snd_pci_quirk position_fix_list[] __devinitdata = { | 2284 | static struct snd_pci_quirk position_fix_list[] __devinitdata = { |
| 2285 | SND_PCI_QUIRK(0x1025, 0x009f, "Acer Aspire 5110", POS_FIX_LPIB), | ||
| 2282 | SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB), | 2286 | SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB), |
| 2283 | SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB), | 2287 | SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB), |
| 2284 | SND_PCI_QUIRK(0x1028, 0x01f6, "Dell Latitude 131L", POS_FIX_LPIB), | 2288 | SND_PCI_QUIRK(0x1028, 0x01f6, "Dell Latitude 131L", POS_FIX_LPIB), |
| 2285 | SND_PCI_QUIRK(0x103c, 0x306d, "HP dv3", POS_FIX_LPIB), | 2289 | SND_PCI_QUIRK(0x103c, 0x306d, "HP dv3", POS_FIX_LPIB), |
| 2286 | SND_PCI_QUIRK(0x1106, 0x3288, "ASUS M2V-MX SE", POS_FIX_LPIB), | ||
| 2287 | SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB), | 2290 | SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB), |
| 2291 | SND_PCI_QUIRK(0x1106, 0x3288, "ASUS M2V-MX SE", POS_FIX_LPIB), | ||
| 2292 | SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba A100-259", POS_FIX_LPIB), | ||
| 2288 | SND_PCI_QUIRK(0x1458, 0xa022, "ga-ma770-ud3", POS_FIX_LPIB), | 2293 | SND_PCI_QUIRK(0x1458, 0xa022, "ga-ma770-ud3", POS_FIX_LPIB), |
| 2289 | SND_PCI_QUIRK(0x1462, 0x1002, "MSI Wind U115", POS_FIX_LPIB), | 2294 | SND_PCI_QUIRK(0x1462, 0x1002, "MSI Wind U115", POS_FIX_LPIB), |
| 2290 | SND_PCI_QUIRK(0x1565, 0x820f, "Biostar Microtech", POS_FIX_LPIB), | 2295 | SND_PCI_QUIRK(0x1565, 0x820f, "Biostar Microtech", POS_FIX_LPIB), |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 53538b0f9991..17d4548cc353 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
| @@ -7025,6 +7025,14 @@ static struct hda_input_mux alc889A_mb31_capture_source = { | |||
| 7025 | }, | 7025 | }, |
| 7026 | }; | 7026 | }; |
| 7027 | 7027 | ||
| 7028 | static struct hda_input_mux alc889A_imac91_capture_source = { | ||
| 7029 | .num_items = 2, | ||
| 7030 | .items = { | ||
| 7031 | { "Mic", 0x01 }, | ||
| 7032 | { "Line", 0x2 }, /* Not sure! */ | ||
| 7033 | }, | ||
| 7034 | }; | ||
| 7035 | |||
| 7028 | /* | 7036 | /* |
| 7029 | * 2ch mode | 7037 | * 2ch mode |
| 7030 | */ | 7038 | */ |
| @@ -7486,15 +7494,8 @@ static struct snd_kcontrol_new alc885_macmini3_mixer[] = { | |||
| 7486 | }; | 7494 | }; |
| 7487 | 7495 | ||
| 7488 | static struct snd_kcontrol_new alc885_imac91_mixer[] = { | 7496 | static struct snd_kcontrol_new alc885_imac91_mixer[] = { |
| 7489 | HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0c, 0x00, HDA_OUTPUT), | 7497 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT), |
| 7490 | HDA_BIND_MUTE ("Line-Out Playback Switch", 0x0c, 0x02, HDA_INPUT), | 7498 | HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT), |
| 7491 | HDA_CODEC_MUTE ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT), | ||
| 7492 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x00, HDA_OUTPUT), | ||
| 7493 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | ||
| 7494 | HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | ||
| 7495 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT), | ||
| 7496 | HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT), | ||
| 7497 | HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT), | ||
| 7498 | { } /* end */ | 7499 | { } /* end */ |
| 7499 | }; | 7500 | }; |
| 7500 | 7501 | ||
| @@ -7995,61 +7996,56 @@ static struct hda_verb alc885_mbp3_init_verbs[] = { | |||
| 7995 | 7996 | ||
| 7996 | /* iMac 9,1 */ | 7997 | /* iMac 9,1 */ |
| 7997 | static struct hda_verb alc885_imac91_init_verbs[] = { | 7998 | static struct hda_verb alc885_imac91_init_verbs[] = { |
| 7998 | /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */ | 7999 | /* Internal Speaker Pin (0x0c) */ |
| 7999 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | 8000 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) }, |
| 8000 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | 8001 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
| 8001 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | 8002 | {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, |
| 8002 | /* Rear mixer */ | 8003 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) }, |
| 8003 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | 8004 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
| 8004 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | 8005 | {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, |
| 8005 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | 8006 | /* HP Pin: Rear */ |
| 8006 | /* HP Pin: output 0 (0x0c) */ | ||
| 8007 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | 8007 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, |
| 8008 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 8008 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
| 8009 | {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, | 8009 | {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, |
| 8010 | {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, | 8010 | {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)}, |
| 8011 | /* Internal Speakers: output 0 (0x0d) */ | 8011 | /* Line in Rear */ |
| 8012 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | 8012 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50}, |
| 8013 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | 8013 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, |
| 8014 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
| 8015 | /* Mic (rear) pin: input vref at 80% */ | ||
| 8016 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
| 8017 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
| 8018 | /* Front Mic pin: input vref at 80% */ | 8014 | /* Front Mic pin: input vref at 80% */ |
| 8019 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | 8015 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, |
| 8020 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | 8016 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, |
| 8021 | /* Line In pin: use output 1 when in LineOut mode */ | 8017 | /* Rear mixer */ |
| 8022 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | 8018 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, |
| 8023 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | 8019 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, |
| 8024 | {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, | 8020 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, |
| 8025 | 8021 | /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */ | |
| 8026 | /* FIXME: use matrix-type input source selection */ | 8022 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, |
| 8027 | /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ | 8023 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, |
| 8028 | /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ | 8024 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, |
| 8025 | /* 0x24 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */ | ||
| 8029 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 8026 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
| 8030 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | 8027 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, |
| 8031 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, | 8028 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, |
| 8032 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, | 8029 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, |
| 8033 | /* Input mixer2 */ | 8030 | /* 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */ |
| 8034 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 8031 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
| 8035 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | 8032 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, |
| 8036 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, | 8033 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, |
| 8037 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, | 8034 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, |
| 8038 | /* Input mixer3 */ | 8035 | /* 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */ |
| 8039 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 8036 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
| 8040 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | 8037 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, |
| 8041 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, | 8038 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, |
| 8042 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, | 8039 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, |
| 8043 | /* ADC1: mute amp left and right */ | 8040 | /* 0x07 [Audio Input] wcaps 0x10011b: Stereo Amp-In */ |
| 8044 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | 8041 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, |
| 8045 | {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, | 8042 | {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, |
| 8046 | /* ADC2: mute amp left and right */ | 8043 | /* 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In */ |
| 8047 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | 8044 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, |
| 8048 | {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, | 8045 | {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, |
| 8049 | /* ADC3: mute amp left and right */ | 8046 | /* 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In */ |
| 8050 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | 8047 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, |
| 8051 | {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, | 8048 | {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, |
| 8052 | |||
| 8053 | { } | 8049 | { } |
| 8054 | }; | 8050 | }; |
| 8055 | 8051 | ||
| @@ -8118,7 +8114,7 @@ static void alc885_imac91_setup(struct hda_codec *codec) | |||
| 8118 | struct alc_spec *spec = codec->spec; | 8114 | struct alc_spec *spec = codec->spec; |
| 8119 | 8115 | ||
| 8120 | spec->autocfg.hp_pins[0] = 0x14; | 8116 | spec->autocfg.hp_pins[0] = 0x14; |
| 8121 | spec->autocfg.speaker_pins[0] = 0x15; | 8117 | spec->autocfg.speaker_pins[0] = 0x18; |
| 8122 | spec->autocfg.speaker_pins[1] = 0x1a; | 8118 | spec->autocfg.speaker_pins[1] = 0x1a; |
| 8123 | } | 8119 | } |
| 8124 | 8120 | ||
| @@ -9627,14 +9623,14 @@ static struct alc_config_preset alc882_presets[] = { | |||
| 9627 | .init_hook = alc885_imac24_init_hook, | 9623 | .init_hook = alc885_imac24_init_hook, |
| 9628 | }, | 9624 | }, |
| 9629 | [ALC885_IMAC91] = { | 9625 | [ALC885_IMAC91] = { |
| 9630 | .mixers = { alc885_imac91_mixer, alc882_chmode_mixer }, | 9626 | .mixers = {alc885_imac91_mixer}, |
| 9631 | .init_verbs = { alc885_imac91_init_verbs, | 9627 | .init_verbs = { alc885_imac91_init_verbs, |
| 9632 | alc880_gpio1_init_verbs }, | 9628 | alc880_gpio1_init_verbs }, |
| 9633 | .num_dacs = ARRAY_SIZE(alc882_dac_nids), | 9629 | .num_dacs = ARRAY_SIZE(alc882_dac_nids), |
| 9634 | .dac_nids = alc882_dac_nids, | 9630 | .dac_nids = alc882_dac_nids, |
| 9635 | .channel_mode = alc885_mbp_4ch_modes, | 9631 | .channel_mode = alc885_mba21_ch_modes, |
| 9636 | .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes), | 9632 | .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes), |
| 9637 | .input_mux = &alc882_capture_source, | 9633 | .input_mux = &alc889A_imac91_capture_source, |
| 9638 | .dig_out_nid = ALC882_DIGOUT_NID, | 9634 | .dig_out_nid = ALC882_DIGOUT_NID, |
| 9639 | .dig_in_nid = ALC882_DIGIN_NID, | 9635 | .dig_in_nid = ALC882_DIGIN_NID, |
| 9640 | .unsol_event = alc_automute_amp_unsol_event, | 9636 | .unsol_event = alc_automute_amp_unsol_event, |
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index a0e06d82da1f..f1e7babd6920 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
| @@ -2078,12 +2078,12 @@ static struct snd_pci_quirk stac927x_cfg_tbl[] = { | |||
| 2078 | SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2000, | 2078 | SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2000, |
| 2079 | "Intel D965", STAC_D965_3ST), | 2079 | "Intel D965", STAC_D965_3ST), |
| 2080 | /* Dell 3 stack systems */ | 2080 | /* Dell 3 stack systems */ |
| 2081 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f7, "Dell XPS M1730", STAC_DELL_3ST), | ||
| 2082 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01dd, "Dell Dimension E520", STAC_DELL_3ST), | 2081 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01dd, "Dell Dimension E520", STAC_DELL_3ST), |
| 2083 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ed, "Dell ", STAC_DELL_3ST), | 2082 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ed, "Dell ", STAC_DELL_3ST), |
| 2084 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f4, "Dell ", STAC_DELL_3ST), | 2083 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f4, "Dell ", STAC_DELL_3ST), |
| 2085 | /* Dell 3 stack systems with verb table in BIOS */ | 2084 | /* Dell 3 stack systems with verb table in BIOS */ |
| 2086 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f3, "Dell Inspiron 1420", STAC_DELL_BIOS), | 2085 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f3, "Dell Inspiron 1420", STAC_DELL_BIOS), |
| 2086 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f7, "Dell XPS M1730", STAC_DELL_BIOS), | ||
| 2087 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0227, "Dell Vostro 1400 ", STAC_DELL_BIOS), | 2087 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0227, "Dell Vostro 1400 ", STAC_DELL_BIOS), |
| 2088 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022e, "Dell ", STAC_DELL_BIOS), | 2088 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022e, "Dell ", STAC_DELL_BIOS), |
| 2089 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022f, "Dell Inspiron 1525", STAC_DELL_BIOS), | 2089 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022f, "Dell Inspiron 1525", STAC_DELL_BIOS), |
diff --git a/sound/usb/caiaq/input.c b/sound/usb/caiaq/input.c index 8bbfbfd4c658..dcb620796d9e 100644 --- a/sound/usb/caiaq/input.c +++ b/sound/usb/caiaq/input.c | |||
| @@ -171,7 +171,7 @@ static void snd_caiaq_input_read_analog(struct snd_usb_caiaqdev *dev, | |||
| 171 | input_report_abs(input_dev, ABS_HAT0Y, (buf[4] << 8) | buf[5]); | 171 | input_report_abs(input_dev, ABS_HAT0Y, (buf[4] << 8) | buf[5]); |
| 172 | input_report_abs(input_dev, ABS_HAT1X, (buf[12] << 8) | buf[13]); | 172 | input_report_abs(input_dev, ABS_HAT1X, (buf[12] << 8) | buf[13]); |
| 173 | input_report_abs(input_dev, ABS_HAT1Y, (buf[2] << 8) | buf[3]); | 173 | input_report_abs(input_dev, ABS_HAT1Y, (buf[2] << 8) | buf[3]); |
| 174 | input_report_abs(input_dev, ABS_HAT2X, (buf[15] << 8) | buf[15]); | 174 | input_report_abs(input_dev, ABS_HAT2X, (buf[14] << 8) | buf[15]); |
| 175 | input_report_abs(input_dev, ABS_HAT2Y, (buf[0] << 8) | buf[1]); | 175 | input_report_abs(input_dev, ABS_HAT2Y, (buf[0] << 8) | buf[1]); |
| 176 | input_report_abs(input_dev, ABS_HAT3X, (buf[10] << 8) | buf[11]); | 176 | input_report_abs(input_dev, ABS_HAT3X, (buf[10] << 8) | buf[11]); |
| 177 | input_report_abs(input_dev, ABS_HAT3Y, (buf[6] << 8) | buf[7]); | 177 | input_report_abs(input_dev, ABS_HAT3Y, (buf[6] << 8) | buf[7]); |
diff --git a/sound/usb/midi.c b/sound/usb/midi.c index 8b1e4b124a9f..46785643c66d 100644 --- a/sound/usb/midi.c +++ b/sound/usb/midi.c | |||
| @@ -645,6 +645,105 @@ static struct usb_protocol_ops snd_usbmidi_cme_ops = { | |||
| 645 | }; | 645 | }; |
| 646 | 646 | ||
| 647 | /* | 647 | /* |
| 648 | * AKAI MPD16 protocol: | ||
| 649 | * | ||
| 650 | * For control port (endpoint 1): | ||
| 651 | * ============================== | ||
| 652 | * One or more chunks consisting of first byte of (0x10 | msg_len) and then a | ||
| 653 | * SysEx message (msg_len=9 bytes long). | ||
| 654 | * | ||
| 655 | * For data port (endpoint 2): | ||
| 656 | * =========================== | ||
| 657 | * One or more chunks consisting of first byte of (0x20 | msg_len) and then a | ||
| 658 | * MIDI message (msg_len bytes long) | ||
| 659 | * | ||
| 660 | * Messages sent: Active Sense, Note On, Poly Pressure, Control Change. | ||
| 661 | */ | ||
| 662 | static void snd_usbmidi_akai_input(struct snd_usb_midi_in_endpoint *ep, | ||
| 663 | uint8_t *buffer, int buffer_length) | ||
| 664 | { | ||
| 665 | unsigned int pos = 0; | ||
| 666 | unsigned int len = (unsigned int)buffer_length; | ||
| 667 | while (pos < len) { | ||
| 668 | unsigned int port = (buffer[pos] >> 4) - 1; | ||
| 669 | unsigned int msg_len = buffer[pos] & 0x0f; | ||
| 670 | pos++; | ||
| 671 | if (pos + msg_len <= len && port < 2) | ||
| 672 | snd_usbmidi_input_data(ep, 0, &buffer[pos], msg_len); | ||
| 673 | pos += msg_len; | ||
| 674 | } | ||
| 675 | } | ||
| 676 | |||
| 677 | #define MAX_AKAI_SYSEX_LEN 9 | ||
| 678 | |||
| 679 | static void snd_usbmidi_akai_output(struct snd_usb_midi_out_endpoint *ep, | ||
| 680 | struct urb *urb) | ||
| 681 | { | ||
| 682 | uint8_t *msg; | ||
| 683 | int pos, end, count, buf_end; | ||
| 684 | uint8_t tmp[MAX_AKAI_SYSEX_LEN]; | ||
| 685 | struct snd_rawmidi_substream *substream = ep->ports[0].substream; | ||
| 686 | |||
| 687 | if (!ep->ports[0].active) | ||
| 688 | return; | ||
| 689 | |||
| 690 | msg = urb->transfer_buffer + urb->transfer_buffer_length; | ||
| 691 | buf_end = ep->max_transfer - MAX_AKAI_SYSEX_LEN - 1; | ||
| 692 | |||
| 693 | /* only try adding more data when there's space for at least 1 SysEx */ | ||
| 694 | while (urb->transfer_buffer_length < buf_end) { | ||
| 695 | count = snd_rawmidi_transmit_peek(substream, | ||
| 696 | tmp, MAX_AKAI_SYSEX_LEN); | ||
| 697 | if (!count) { | ||
| 698 | ep->ports[0].active = 0; | ||
| 699 | return; | ||
| 700 | } | ||
| 701 | /* try to skip non-SysEx data */ | ||
| 702 | for (pos = 0; pos < count && tmp[pos] != 0xF0; pos++) | ||
| 703 | ; | ||
| 704 | |||
| 705 | if (pos > 0) { | ||
| 706 | snd_rawmidi_transmit_ack(substream, pos); | ||
| 707 | continue; | ||
| 708 | } | ||
| 709 | |||
| 710 | /* look for the start or end marker */ | ||
| 711 | for (end = 1; end < count && tmp[end] < 0xF0; end++) | ||
| 712 | ; | ||
| 713 | |||
| 714 | /* next SysEx started before the end of current one */ | ||
| 715 | if (end < count && tmp[end] == 0xF0) { | ||
| 716 | /* it's incomplete - drop it */ | ||
| 717 | snd_rawmidi_transmit_ack(substream, end); | ||
| 718 | continue; | ||
| 719 | } | ||
| 720 | /* SysEx complete */ | ||
| 721 | if (end < count && tmp[end] == 0xF7) { | ||
| 722 | /* queue it, ack it, and get the next one */ | ||
| 723 | count = end + 1; | ||
| 724 | msg[0] = 0x10 | count; | ||
| 725 | memcpy(&msg[1], tmp, count); | ||
| 726 | snd_rawmidi_transmit_ack(substream, count); | ||
| 727 | urb->transfer_buffer_length += count + 1; | ||
| 728 | msg += count + 1; | ||
| 729 | continue; | ||
| 730 | } | ||
| 731 | /* less than 9 bytes and no end byte - wait for more */ | ||
| 732 | if (count < MAX_AKAI_SYSEX_LEN) { | ||
| 733 | ep->ports[0].active = 0; | ||
| 734 | return; | ||
| 735 | } | ||
| 736 | /* 9 bytes and no end marker in sight - malformed, skip it */ | ||
| 737 | snd_rawmidi_transmit_ack(substream, count); | ||
| 738 | } | ||
| 739 | } | ||
| 740 | |||
| 741 | static struct usb_protocol_ops snd_usbmidi_akai_ops = { | ||
| 742 | .input = snd_usbmidi_akai_input, | ||
| 743 | .output = snd_usbmidi_akai_output, | ||
| 744 | }; | ||
| 745 | |||
| 746 | /* | ||
| 648 | * Novation USB MIDI protocol: number of data bytes is in the first byte | 747 | * Novation USB MIDI protocol: number of data bytes is in the first byte |
| 649 | * (when receiving) (+1!) or in the second byte (when sending); data begins | 748 | * (when receiving) (+1!) or in the second byte (when sending); data begins |
| 650 | * at the third byte. | 749 | * at the third byte. |
| @@ -1434,6 +1533,11 @@ static struct port_info { | |||
| 1434 | EXTERNAL_PORT(0x086a, 0x0001, 8, "%s Broadcast"), | 1533 | EXTERNAL_PORT(0x086a, 0x0001, 8, "%s Broadcast"), |
| 1435 | EXTERNAL_PORT(0x086a, 0x0002, 8, "%s Broadcast"), | 1534 | EXTERNAL_PORT(0x086a, 0x0002, 8, "%s Broadcast"), |
| 1436 | EXTERNAL_PORT(0x086a, 0x0003, 4, "%s Broadcast"), | 1535 | EXTERNAL_PORT(0x086a, 0x0003, 4, "%s Broadcast"), |
| 1536 | /* Akai MPD16 */ | ||
| 1537 | CONTROL_PORT(0x09e8, 0x0062, 0, "%s Control"), | ||
| 1538 | PORT_INFO(0x09e8, 0x0062, 1, "%s MIDI", 0, | ||
| 1539 | SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC | | ||
| 1540 | SNDRV_SEQ_PORT_TYPE_HARDWARE), | ||
| 1437 | /* Access Music Virus TI */ | 1541 | /* Access Music Virus TI */ |
| 1438 | EXTERNAL_PORT(0x133e, 0x0815, 0, "%s MIDI"), | 1542 | EXTERNAL_PORT(0x133e, 0x0815, 0, "%s MIDI"), |
| 1439 | PORT_INFO(0x133e, 0x0815, 1, "%s Synth", 0, | 1543 | PORT_INFO(0x133e, 0x0815, 1, "%s Synth", 0, |
| @@ -2035,6 +2139,12 @@ int snd_usbmidi_create(struct snd_card *card, | |||
| 2035 | umidi->usb_protocol_ops = &snd_usbmidi_cme_ops; | 2139 | umidi->usb_protocol_ops = &snd_usbmidi_cme_ops; |
| 2036 | err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints); | 2140 | err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints); |
| 2037 | break; | 2141 | break; |
| 2142 | case QUIRK_MIDI_AKAI: | ||
| 2143 | umidi->usb_protocol_ops = &snd_usbmidi_akai_ops; | ||
| 2144 | err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints); | ||
| 2145 | /* endpoint 1 is input-only */ | ||
| 2146 | endpoints[1].out_cables = 0; | ||
| 2147 | break; | ||
| 2038 | default: | 2148 | default: |
| 2039 | snd_printd(KERN_ERR "invalid quirk type %d\n", quirk->type); | 2149 | snd_printd(KERN_ERR "invalid quirk type %d\n", quirk->type); |
| 2040 | err = -ENXIO; | 2150 | err = -ENXIO; |
diff --git a/sound/usb/midi.h b/sound/usb/midi.h index 2089ec987c66..2fca80b744c0 100644 --- a/sound/usb/midi.h +++ b/sound/usb/midi.h | |||
| @@ -37,6 +37,8 @@ struct snd_usb_midi_endpoint_info { | |||
| 37 | 37 | ||
| 38 | /* for QUIRK_MIDI_CME, data is NULL */ | 38 | /* for QUIRK_MIDI_CME, data is NULL */ |
| 39 | 39 | ||
| 40 | /* for QUIRK_MIDI_AKAI, data is NULL */ | ||
| 41 | |||
| 40 | int snd_usbmidi_create(struct snd_card *card, | 42 | int snd_usbmidi_create(struct snd_card *card, |
| 41 | struct usb_interface *iface, | 43 | struct usb_interface *iface, |
| 42 | struct list_head *midi_list, | 44 | struct list_head *midi_list, |
diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h index 91ddef31bcbd..f8797f61a24b 100644 --- a/sound/usb/quirks-table.h +++ b/sound/usb/quirks-table.h | |||
| @@ -1973,6 +1973,17 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
| 1973 | } | 1973 | } |
| 1974 | }, | 1974 | }, |
| 1975 | 1975 | ||
| 1976 | /* AKAI devices */ | ||
| 1977 | { | ||
| 1978 | USB_DEVICE(0x09e8, 0x0062), | ||
| 1979 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { | ||
| 1980 | .vendor_name = "AKAI", | ||
| 1981 | .product_name = "MPD16", | ||
| 1982 | .ifnum = 0, | ||
| 1983 | .type = QUIRK_MIDI_AKAI, | ||
| 1984 | } | ||
| 1985 | }, | ||
| 1986 | |||
| 1976 | /* TerraTec devices */ | 1987 | /* TerraTec devices */ |
| 1977 | { | 1988 | { |
| 1978 | USB_DEVICE_VENDOR_SPEC(0x0ccd, 0x0012), | 1989 | USB_DEVICE_VENDOR_SPEC(0x0ccd, 0x0012), |
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index 136e5b4cf6de..b45e54c09ba2 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c | |||
| @@ -289,6 +289,7 @@ int snd_usb_create_quirk(struct snd_usb_audio *chip, | |||
| 289 | [QUIRK_MIDI_FASTLANE] = create_any_midi_quirk, | 289 | [QUIRK_MIDI_FASTLANE] = create_any_midi_quirk, |
| 290 | [QUIRK_MIDI_EMAGIC] = create_any_midi_quirk, | 290 | [QUIRK_MIDI_EMAGIC] = create_any_midi_quirk, |
| 291 | [QUIRK_MIDI_CME] = create_any_midi_quirk, | 291 | [QUIRK_MIDI_CME] = create_any_midi_quirk, |
| 292 | [QUIRK_MIDI_AKAI] = create_any_midi_quirk, | ||
| 292 | [QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_audio_quirk, | 293 | [QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_audio_quirk, |
| 293 | [QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk, | 294 | [QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk, |
| 294 | [QUIRK_AUDIO_EDIROL_UAXX] = create_uaxx_quirk, | 295 | [QUIRK_AUDIO_EDIROL_UAXX] = create_uaxx_quirk, |
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h index d679e72a3e5c..06ebf24d3a4d 100644 --- a/sound/usb/usbaudio.h +++ b/sound/usb/usbaudio.h | |||
| @@ -74,6 +74,7 @@ enum quirk_type { | |||
| 74 | QUIRK_MIDI_FASTLANE, | 74 | QUIRK_MIDI_FASTLANE, |
| 75 | QUIRK_MIDI_EMAGIC, | 75 | QUIRK_MIDI_EMAGIC, |
| 76 | QUIRK_MIDI_CME, | 76 | QUIRK_MIDI_CME, |
| 77 | QUIRK_MIDI_AKAI, | ||
| 77 | QUIRK_MIDI_US122L, | 78 | QUIRK_MIDI_US122L, |
| 78 | QUIRK_AUDIO_STANDARD_INTERFACE, | 79 | QUIRK_AUDIO_STANDARD_INTERFACE, |
| 79 | QUIRK_AUDIO_FIXED_ENDPOINT, | 80 | QUIRK_AUDIO_FIXED_ENDPOINT, |
