@@ -2602,6 +2602,216 @@ static int snd_bbfpro_controls_create(struct usb_mixer_interface *mixer)
2602
2602
return 0 ;
2603
2603
}
2604
2604
2605
+ /*
2606
+ * Pioneer DJ DJM-250MK2 and maybe other DJM models
2607
+ *
2608
+ * For playback, no duplicate mapping should be set.
2609
+ * There are three mixer stereo channels (CH1, CH2, AUX)
2610
+ * and three stereo sources (Playback 1-2, Playback 3-4, Playback 5-6).
2611
+ * Each channel should be mapped just once to one source.
2612
+ * If mapped multiple times, only one source will play on given channel
2613
+ * (sources are not mixed together).
2614
+ *
2615
+ * For recording, duplicate mapping is OK. We will get the same signal multiple times.
2616
+ *
2617
+ * Channels 7-8 are in both directions fixed to FX SEND / FX RETURN.
2618
+ *
2619
+ * See also notes in the quirks-table.h file.
2620
+ */
2621
+
2622
+ struct snd_pioneer_djm_option {
2623
+ const u16 wIndex ;
2624
+ const u16 wValue ;
2625
+ const char * name ;
2626
+ };
2627
+
2628
+ static const struct snd_pioneer_djm_option snd_pioneer_djm_options_capture_level [] = {
2629
+ { .name = "-5 dB" , .wValue = 0x0300 , .wIndex = 0x8003 },
2630
+ { .name = "-10 dB" , .wValue = 0x0200 , .wIndex = 0x8003 },
2631
+ { .name = "-15 dB" , .wValue = 0x0100 , .wIndex = 0x8003 },
2632
+ { .name = "-19 dB" , .wValue = 0x0000 , .wIndex = 0x8003 }
2633
+ };
2634
+
2635
+ static const struct snd_pioneer_djm_option snd_pioneer_djm_options_capture_ch12 [] = {
2636
+ { .name = "CH1 Control Tone PHONO" , .wValue = 0x0103 , .wIndex = 0x8002 },
2637
+ { .name = "CH1 Control Tone LINE" , .wValue = 0x0100 , .wIndex = 0x8002 },
2638
+ { .name = "Post CH1 Fader" , .wValue = 0x0106 , .wIndex = 0x8002 },
2639
+ { .name = "Cross Fader A" , .wValue = 0x0107 , .wIndex = 0x8002 },
2640
+ { .name = "Cross Fader B" , .wValue = 0x0108 , .wIndex = 0x8002 },
2641
+ { .name = "MIC" , .wValue = 0x0109 , .wIndex = 0x8002 },
2642
+ { .name = "AUX" , .wValue = 0x010d , .wIndex = 0x8002 },
2643
+ { .name = "REC OUT" , .wValue = 0x010a , .wIndex = 0x8002 }
2644
+ };
2645
+
2646
+ static const struct snd_pioneer_djm_option snd_pioneer_djm_options_capture_ch34 [] = {
2647
+ { .name = "CH2 Control Tone PHONO" , .wValue = 0x0203 , .wIndex = 0x8002 },
2648
+ { .name = "CH2 Control Tone LINE" , .wValue = 0x0200 , .wIndex = 0x8002 },
2649
+ { .name = "Post CH2 Fader" , .wValue = 0x0206 , .wIndex = 0x8002 },
2650
+ { .name = "Cross Fader A" , .wValue = 0x0207 , .wIndex = 0x8002 },
2651
+ { .name = "Cross Fader B" , .wValue = 0x0208 , .wIndex = 0x8002 },
2652
+ { .name = "MIC" , .wValue = 0x0209 , .wIndex = 0x8002 },
2653
+ { .name = "AUX" , .wValue = 0x020d , .wIndex = 0x8002 },
2654
+ { .name = "REC OUT" , .wValue = 0x020a , .wIndex = 0x8002 }
2655
+ };
2656
+
2657
+ static const struct snd_pioneer_djm_option snd_pioneer_djm_options_capture_ch56 [] = {
2658
+ { .name = "REC OUT" , .wValue = 0x030a , .wIndex = 0x8002 },
2659
+ { .name = "Post CH1 Fader" , .wValue = 0x0311 , .wIndex = 0x8002 },
2660
+ { .name = "Post CH2 Fader" , .wValue = 0x0312 , .wIndex = 0x8002 },
2661
+ { .name = "Cross Fader A" , .wValue = 0x0307 , .wIndex = 0x8002 },
2662
+ { .name = "Cross Fader B" , .wValue = 0x0308 , .wIndex = 0x8002 },
2663
+ { .name = "MIC" , .wValue = 0x0309 , .wIndex = 0x8002 },
2664
+ { .name = "AUX" , .wValue = 0x030d , .wIndex = 0x8002 }
2665
+ };
2666
+
2667
+ static const struct snd_pioneer_djm_option snd_pioneer_djm_options_playback_12 [] = {
2668
+ { .name = "CH1" , .wValue = 0x0100 , .wIndex = 0x8016 },
2669
+ { .name = "CH2" , .wValue = 0x0101 , .wIndex = 0x8016 },
2670
+ { .name = "AUX" , .wValue = 0x0104 , .wIndex = 0x8016 }
2671
+ };
2672
+
2673
+ static const struct snd_pioneer_djm_option snd_pioneer_djm_options_playback_34 [] = {
2674
+ { .name = "CH1" , .wValue = 0x0200 , .wIndex = 0x8016 },
2675
+ { .name = "CH2" , .wValue = 0x0201 , .wIndex = 0x8016 },
2676
+ { .name = "AUX" , .wValue = 0x0204 , .wIndex = 0x8016 }
2677
+ };
2678
+
2679
+ static const struct snd_pioneer_djm_option snd_pioneer_djm_options_playback_56 [] = {
2680
+ { .name = "CH1" , .wValue = 0x0300 , .wIndex = 0x8016 },
2681
+ { .name = "CH2" , .wValue = 0x0301 , .wIndex = 0x8016 },
2682
+ { .name = "AUX" , .wValue = 0x0304 , .wIndex = 0x8016 }
2683
+ };
2684
+
2685
+ struct snd_pioneer_djm_option_group {
2686
+ const char * name ;
2687
+ const struct snd_pioneer_djm_option * options ;
2688
+ const size_t count ;
2689
+ const u16 default_value ;
2690
+ };
2691
+
2692
+ #define snd_pioneer_djm_option_group_item (_name , suffix , _default_value ) { \
2693
+ .name = _name, \
2694
+ .options = snd_pioneer_djm_options_##suffix, \
2695
+ .count = ARRAY_SIZE(snd_pioneer_djm_options_##suffix), \
2696
+ .default_value = _default_value }
2697
+
2698
+ static const struct snd_pioneer_djm_option_group snd_pioneer_djm_option_groups [] = {
2699
+ snd_pioneer_djm_option_group_item ("Master Capture Level Capture Switch" , capture_level , 0 ),
2700
+ snd_pioneer_djm_option_group_item ("Capture 1-2 Capture Switch" , capture_ch12 , 2 ),
2701
+ snd_pioneer_djm_option_group_item ("Capture 3-4 Capture Switch" , capture_ch34 , 2 ),
2702
+ snd_pioneer_djm_option_group_item ("Capture 5-6 Capture Switch" , capture_ch56 , 0 ),
2703
+ snd_pioneer_djm_option_group_item ("Playback 1-2 Playback Switch" , playback_12 , 0 ),
2704
+ snd_pioneer_djm_option_group_item ("Playback 3-4 Playback Switch" , playback_34 , 1 ),
2705
+ snd_pioneer_djm_option_group_item ("Playback 5-6 Playback Switch" , playback_56 , 2 )
2706
+ };
2707
+
2708
+ // layout of the kcontrol->private_value:
2709
+ #define SND_PIONEER_DJM_VALUE_MASK 0x0000ffff
2710
+ #define SND_PIONEER_DJM_GROUP_MASK 0xffff0000
2711
+ #define SND_PIONEER_DJM_GROUP_SHIFT 16
2712
+
2713
+ static int snd_pioneer_djm_controls_info (struct snd_kcontrol * kctl , struct snd_ctl_elem_info * info )
2714
+ {
2715
+ u16 group_index = kctl -> private_value >> SND_PIONEER_DJM_GROUP_SHIFT ;
2716
+ size_t count ;
2717
+ const char * name ;
2718
+ const struct snd_pioneer_djm_option_group * group ;
2719
+
2720
+ if (group_index >= ARRAY_SIZE (snd_pioneer_djm_option_groups ))
2721
+ return - EINVAL ;
2722
+
2723
+ group = & snd_pioneer_djm_option_groups [group_index ];
2724
+ count = group -> count ;
2725
+ if (info -> value .enumerated .item >= count )
2726
+ info -> value .enumerated .item = count - 1 ;
2727
+ name = group -> options [info -> value .enumerated .item ].name ;
2728
+ strlcpy (info -> value .enumerated .name , name , sizeof (info -> value .enumerated .name ));
2729
+ info -> type = SNDRV_CTL_ELEM_TYPE_ENUMERATED ;
2730
+ info -> count = 1 ;
2731
+ info -> value .enumerated .items = count ;
2732
+ return 0 ;
2733
+ }
2734
+
2735
+ static int snd_pioneer_djm_controls_update (struct usb_mixer_interface * mixer , u16 group , u16 value )
2736
+ {
2737
+ int err ;
2738
+
2739
+ if (group >= ARRAY_SIZE (snd_pioneer_djm_option_groups )
2740
+ || value >= snd_pioneer_djm_option_groups [group ].count )
2741
+ return - EINVAL ;
2742
+
2743
+ err = snd_usb_lock_shutdown (mixer -> chip );
2744
+ if (err )
2745
+ return err ;
2746
+
2747
+ err = snd_usb_ctl_msg (
2748
+ mixer -> chip -> dev , usb_sndctrlpipe (mixer -> chip -> dev , 0 ),
2749
+ USB_REQ_SET_FEATURE ,
2750
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE ,
2751
+ snd_pioneer_djm_option_groups [group ].options [value ].wValue ,
2752
+ snd_pioneer_djm_option_groups [group ].options [value ].wIndex ,
2753
+ NULL , 0 );
2754
+
2755
+ snd_usb_unlock_shutdown (mixer -> chip );
2756
+ return err ;
2757
+ }
2758
+
2759
+ static int snd_pioneer_djm_controls_get (struct snd_kcontrol * kctl , struct snd_ctl_elem_value * elem )
2760
+ {
2761
+ elem -> value .enumerated .item [0 ] = kctl -> private_value & SND_PIONEER_DJM_VALUE_MASK ;
2762
+ return 0 ;
2763
+ }
2764
+
2765
+ static int snd_pioneer_djm_controls_put (struct snd_kcontrol * kctl , struct snd_ctl_elem_value * elem )
2766
+ {
2767
+ struct usb_mixer_elem_list * list = snd_kcontrol_chip (kctl );
2768
+ struct usb_mixer_interface * mixer = list -> mixer ;
2769
+ unsigned long private_value = kctl -> private_value ;
2770
+ u16 group = (private_value & SND_PIONEER_DJM_GROUP_MASK ) >> SND_PIONEER_DJM_GROUP_SHIFT ;
2771
+ u16 value = elem -> value .enumerated .item [0 ];
2772
+
2773
+ kctl -> private_value = (group << SND_PIONEER_DJM_GROUP_SHIFT ) | value ;
2774
+
2775
+ return snd_pioneer_djm_controls_update (mixer , group , value );
2776
+ }
2777
+
2778
+ static int snd_pioneer_djm_controls_resume (struct usb_mixer_elem_list * list )
2779
+ {
2780
+ unsigned long private_value = list -> kctl -> private_value ;
2781
+ u16 group = (private_value & SND_PIONEER_DJM_GROUP_MASK ) >> SND_PIONEER_DJM_GROUP_SHIFT ;
2782
+ u16 value = (private_value & SND_PIONEER_DJM_VALUE_MASK );
2783
+
2784
+ return snd_pioneer_djm_controls_update (list -> mixer , group , value );
2785
+ }
2786
+
2787
+ static int snd_pioneer_djm_controls_create (struct usb_mixer_interface * mixer )
2788
+ {
2789
+ int err , i ;
2790
+ const struct snd_pioneer_djm_option_group * group ;
2791
+ struct snd_kcontrol_new knew = {
2792
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER ,
2793
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE ,
2794
+ .index = 0 ,
2795
+ .info = snd_pioneer_djm_controls_info ,
2796
+ .get = snd_pioneer_djm_controls_get ,
2797
+ .put = snd_pioneer_djm_controls_put
2798
+ };
2799
+
2800
+ for (i = 0 ; i < ARRAY_SIZE (snd_pioneer_djm_option_groups ); i ++ ) {
2801
+ group = & snd_pioneer_djm_option_groups [i ];
2802
+ knew .name = group -> name ;
2803
+ knew .private_value = (i << SND_PIONEER_DJM_GROUP_SHIFT ) | group -> default_value ;
2804
+ err = snd_pioneer_djm_controls_update (mixer , i , group -> default_value );
2805
+ if (err )
2806
+ return err ;
2807
+ err = add_single_ctl_with_resume (mixer , 0 , snd_pioneer_djm_controls_resume ,
2808
+ & knew , NULL );
2809
+ if (err )
2810
+ return err ;
2811
+ }
2812
+ return 0 ;
2813
+ }
2814
+
2605
2815
int snd_usb_mixer_apply_create_quirk (struct usb_mixer_interface * mixer )
2606
2816
{
2607
2817
int err = 0 ;
@@ -2706,6 +2916,9 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer)
2706
2916
case USB_ID (0x2a39 , 0x3fb0 ): /* RME Babyface Pro FS */
2707
2917
err = snd_bbfpro_controls_create (mixer );
2708
2918
break ;
2919
+ case USB_ID (0x2b73 , 0x0017 ): /* Pioneer DJ DJM-250MK2 */
2920
+ err = snd_pioneer_djm_controls_create (mixer );
2921
+ break ;
2709
2922
}
2710
2923
2711
2924
return err ;
0 commit comments