Modifying USB DAC settings (select SPDIF)

Sorry for the very cryptic subject and plase feel free to redirect me if this question does not fit in here. So here it is: I have a LogiLink USB 5.1/7.1 sound card. It is based on the CM6206 chip. It has an S/PDIF output that can be set to output the full signal or any of frontlr/center-sub/surroundlr etc. I would like it to output the surround left/right signal.

To do this you need to set some values in REG5:

Now, the Linux kernel already has some stuff for that very chipset in a file called “quirks.c” so I guess I could add whatever I want to that file and recompile the kernel, but I guess there must be an easier way? Write a small program that does the same? Ie something along the lines of:

/*
 * Muck with CM6206 internal registers
 * Based on Set LED - program to control a USB LED device
 * from user space using libusb
 * and code from: https://github.com/torvalds/linux/blob/master/sound/usb/quirks.c
 * Copyright (C) 2004
 *     Greg Kroah-Hartman (greg@kroah.com)
 *
 * This program is free software; you can
 * redistribute it and/or modify it under the terms
 * of the GNU General Public License as published by
 * the Free Software Foundation, version 2 of the
 * License.
 *
 */

// https://www.linuxjournal.com/article/7466

#include <stdio.h>
#include <string.h>
//#include "/usr/include/linux/usb/ch9.h"
#include <linux/types.h>
#include <usb.h>

#define NONE    0x00
#define BLUE    0x04
#define RED     0x02
#define GREEN   0x01

// 046d:c044 
//#define LED_VENDOR_ID   0x0fc5
//#define LED_PRODUCT_ID  0x1223
//#define LED_VENDOR_ID   0x046d
//#define LED_PRODUCT_ID  0xc044 
// 0d8c:0102 
#define LED_VENDOR_ID   0x0d8c
#define LED_PRODUCT_ID  0x0102  

#define BIT(nr) (1UL << (nr))
/*
 * CM6206 registers from the CM6206 datasheet rev 2.1
 */
#define CM6206_REG0_DMA_MASTER BIT(15)
#define CM6206_REG0_SPDIFO_RATE_48K (2 << 12)
#define CM6206_REG0_SPDIFO_RATE_96K (7 << 12)
/* Bit 4 thru 11 is the S/PDIF category code */
#define CM6206_REG0_SPDIFO_CAT_CODE_GENERAL (0 << 4)
#define CM6206_REG0_SPDIFO_EMPHASIS_CD BIT(3)
#define CM6206_REG0_SPDIFO_COPYRIGHT_NA BIT(2)
#define CM6206_REG0_SPDIFO_NON_AUDIO BIT(1)
#define CM6206_REG0_SPDIFO_PRO_FORMAT BIT(0)

#define CM6206_REG1_TEST_SEL_CLK BIT(14)
#define CM6206_REG1_PLLBIN_EN BIT(13)
#define CM6206_REG1_SOFT_MUTE_EN BIT(12)
#define CM6206_REG1_GPIO4_OUT BIT(11)
#define CM6206_REG1_GPIO4_OE BIT(10)
#define CM6206_REG1_GPIO3_OUT BIT(9)
#define CM6206_REG1_GPIO3_OE BIT(8)
#define CM6206_REG1_GPIO2_OUT BIT(7)
#define CM6206_REG1_GPIO2_OE BIT(6)
#define CM6206_REG1_GPIO1_OUT BIT(5)
#define CM6206_REG1_GPIO1_OE BIT(4)
#define CM6206_REG1_SPDIFO_INVALID BIT(3)
#define CM6206_REG1_SPDIF_LOOP_EN BIT(2)
#define CM6206_REG1_SPDIFO_DIS BIT(1)
#define CM6206_REG1_SPDIFI_MIX BIT(0)

#define CM6206_REG2_DRIVER_ON BIT(15)
#define CM6206_REG2_HEADP_SEL_SIDE_CHANNELS (0 << 13)
#define CM6206_REG2_HEADP_SEL_SURROUND_CHANNELS (1 << 13)
#define CM6206_REG2_HEADP_SEL_CENTER_SUBW (2 << 13)
#define CM6206_REG2_HEADP_SEL_FRONT_CHANNELS (3 << 13)
#define CM6206_REG2_MUTE_HEADPHONE_RIGHT BIT(12)
#define CM6206_REG2_MUTE_HEADPHONE_LEFT BIT(11)
#define CM6206_REG2_MUTE_REAR_SURROUND_RIGHT BIT(10)
#define CM6206_REG2_MUTE_REAR_SURROUND_LEFT BIT(9)
#define CM6206_REG2_MUTE_SIDE_SURROUND_RIGHT BIT(8)
#define CM6206_REG2_MUTE_SIDE_SURROUND_LEFT BIT(7)
#define CM6206_REG2_MUTE_SUBWOOFER BIT(6)
#define CM6206_REG2_MUTE_CENTER BIT(5)
#define CM6206_REG2_MUTE_RIGHT_FRONT BIT(3)
#define CM6206_REG2_MUTE_LEFT_FRONT BIT(3)
#define CM6206_REG2_EN_BTL BIT(2)
#define CM6206_REG2_MCUCLKSEL_1_5_MHZ (0)
#define CM6206_REG2_MCUCLKSEL_3_MHZ (1)
#define CM6206_REG2_MCUCLKSEL_6_MHZ (2)
#define CM6206_REG2_MCUCLKSEL_12_MHZ (3)

/* Bit 11..13 sets the sensitivity to FLY tuner volume control VP/VD signal */
#define CM6206_REG3_FLYSPEED_DEFAULT (2 << 11)
#define CM6206_REG3_VRAP25EN BIT(10)
#define CM6206_REG3_MSEL1 BIT(9)
#define CM6206_REG3_SPDIFI_RATE_44_1K BIT(0 << 7)
#define CM6206_REG3_SPDIFI_RATE_48K BIT(2 << 7)
#define CM6206_REG3_SPDIFI_RATE_32K BIT(3 << 7)
#define CM6206_REG3_PINSEL BIT(6)
#define CM6206_REG3_FOE BIT(5)
#define CM6206_REG3_ROE BIT(4)
#define CM6206_REG3_CBOE BIT(3)
#define CM6206_REG3_LOSE BIT(2)
#define CM6206_REG3_HPOE BIT(1)
#define CM6206_REG3_SPDIFI_CANREC BIT(0)

#define CM6206_REG5_DA_RSTN BIT(13)
#define CM6206_REG5_AD_RSTN BIT(12)
#define CM6206_REG5_SPDIFO_AD2SPDO BIT(12)
#define CM6206_REG5_SPDIFO_SEL_FRONT (0 << 9)
#define CM6206_REG5_SPDIFO_SEL_SIDE_SUR (1 << 9)
#define CM6206_REG5_SPDIFO_SEL_CEN_LFE (2 << 9)
#define CM6206_REG5_SPDIFO_SEL_REAR_SUR (3 << 9)
#define CM6206_REG5_CODECM BIT(8)
#define CM6206_REG5_EN_HPF BIT(7)
#define CM6206_REG5_T_SEL_DSDA4 BIT(6)
#define CM6206_REG5_T_SEL_DSDA3 BIT(5)
#define CM6206_REG5_T_SEL_DSDA2 BIT(4)
#define CM6206_REG5_T_SEL_DSDA1 BIT(3)
#define CM6206_REG5_T_SEL_DSDAD_NORMAL 0
#define CM6206_REG5_T_SEL_DSDAD_FRONT 4
#define CM6206_REG5_T_SEL_DSDAD_S_SURROUND 5
#define CM6206_REG5_T_SEL_DSDAD_CEN_LFE 6
#define CM6206_REG5_T_SEL_DSDAD_R_SURROUND 7

#define USB_DIR_OUT			0		/* to device */
#define USB_REQ_SET_CONFIGURATION	0x09
#define USB_TYPE_CLASS			(0x01 << 5)
#define USB_RECIP_ENDPOINT		0x02

static void change_color
        (struct usb_dev_handle *handle,
         unsigned char color)
{
    char *dummy;

    usb_control_msg(handle,
                    0x000000c8,
                    0x00000012,
                    (0x02 * 0x100) + 0x0a,
                    0xff & (~color),
                    dummy,
                    0x00000008,
                    5000);
}

static struct usb_device *device_init(void)
{
    struct usb_bus *usb_bus;
    struct usb_device *dev;

    usb_init();
    usb_find_busses();
    usb_find_devices();

    for (usb_bus = usb_busses;
         usb_bus;
         usb_bus = usb_bus->next) {
        for (dev = usb_bus->devices;
             dev;
             dev = dev->next) {
            if ((dev->descriptor.idVendor
                  == LED_VENDOR_ID) &&
                (dev->descriptor.idProduct
                  == LED_PRODUCT_ID))
                return dev;
        }
    }
    return NULL;
}

/*
 * C-Media CM106/CM106+ have four 16-bit internal registers that are nicely
 * documented in the device's data sheet.
 */
static int snd_usb_cm106_write_int_reg(usb_dev_handle *handle, int reg, __u16 value)
{
	char buf[4];
	buf[0] = 0x20;
	buf[1] = value & 0xff;
	buf[2] = (value >> 8) & 0xff;
	buf[3] = reg;
	//https://sourceforge.net/p/libusb-win32/wiki/Documentation/
	return usb_control_msg(handle, 					// handle
		USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_ENDPOINT,	// Request type
		USB_REQ_SET_CONFIGURATION,  				// Request
		0, 								// value
		0, 								// index
		buf,								// payload
		4,
		5000);								// length
}

int main(int argc, char **argv)
{
    struct usb_device *usb_dev;
    struct usb_dev_handle *usb_handle;
    int retval = 1;
    int i, rc;
    unsigned char color = NONE;
    int val;

    usb_set_debug(4);

    usb_dev = device_init();
    if (usb_dev == NULL) {
        fprintf(stderr, "Device not found\n");
        goto exit;
    }

    usb_handle = usb_open(usb_dev);
    if (usb_handle == NULL) {
        fprintf(stderr, "Cannot open\n");
        goto exit;
    }

    usb_handle = usb_open(usb_dev);
    if (usb_handle == NULL) {
        fprintf(stderr,
             "Not able to claim the USB device\n");
        goto exit;
    }

/* REG5: de-assert AD/DA reset signals */
    val = 	CM6206_REG5_DA_RSTN |
		CM6206_REG5_AD_RSTN | CM6206_REG5_SPDIFO_SEL_CEN_LFE;

    rc = snd_usb_cm106_write_int_reg(usb_handle, 5, val);
        fprintf(stderr,
             "Wrote %X to register 5, rc = %d\n", val, rc);

    retval = 0;

exit:
    usb_close(usb_handle);
    return retval;
}

This may be controllable via alsamixer. Did you try this first?

You mean here? I just see the various volumes, not a selection for S/PDIF out?

lqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq AlsaMixer v1.1.3 qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqk
x Card: USB Sound Device                               F1:  Help               x
x Chip: USB Mixer                                      F2:  System information x
x View: F3:[Playback] F4: Capture  F5: All             F6:  Select sound card  x
x Item: Speaker [dB gain: -20.06, -20.06]              Esc: Exit               x
x                                                                              x
x     lqqk     lqqk     lqqk     lqqk     lqqk              lqqk     lqqk      x
x     x  x     x  x     x  x     x  x     x  x              x  x     x  x      x
x     x  x     x  x     x  x     x  x     x  x              x  x     x  x      x
x     x  x     x  x     x  x     x  x     x  x              x  x     x  x      x
x     x  x     x  x     x  x     x  x     x  x              x  x     x  x      x
x     x  x     x  x     x  x     x  x     x  x              xaax     xaax      x
x     x  x     x  x     x  x     x  x     x  x              xaax     xaax      x
x     x  x     x  x     x  x     x  x     x  x              xaax     xaax      x
x     xaax     xaax     xaax     xaax     xaax              xaax     xaax      x
x     xaax     xaax     xaax     xaax     xaax              xaax     xaax      x
x     xaax     xaax     xaax     xaax     xaax              xaax     xaax      x
x     tqqu     tqqu     tqqu     tqqu     tqqu     Mic      tqqu     tqqu      x
x     xOOx     xOOx     xOOx     xOOx     xOOx              xMMx     xMMx      x
x     mqqj     mqqj     mqqj     mqqj     mqqj              mqqj     mqqj      x
x    29<>29   29<>29     29       29     29<>29            64<>64   64<>64     x
x  <Speaker >Speaker  Speaker  Speaker  Speaker  PCM Capt   Line     Mic       x
x    Front     Rear    Center   Woofer    Side                                 x
mqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqj

No. You have the right idea in your OP - you need to get under the skin of the soundcard driver.

OK. The snippet of code above seems to work, but has an unfortunate side-effect: The normal left/right sound goes away unless SPDIFOUT is 0. If I play a DTS test stream all works normally, even though I have not been able to verify that S/PDIF now holds the surround channels. Will do so as soon as I get my hands on a TOSLINK receiver.

Cleaned up code:

/ *
* Set SPDIFOUT - program to control the SPDIF-output on a CM6206 chip
*
* Based on: Set LED - program to control a USB LED device
* from user space using libusb (Writing a Real Driver&mdash;In User Space | Linux Journal)
*
* Copyright (C) 2004
* Greg Kroah-Hartman (greg@kroah.com)
*
* This program is free software; you can
* redistribute it and/or modify it under the terms
* of the GNU General Public License as published by
* the Free Software Foundation, version 2 of the
* License.
*
*/

// https://www.linuxjournal.com/article/7466

#include <stdio.h>
#include <string.h>
#include <linux/types.h>
#include <usb.h>


//Id's for the  C-Media Electronics, Inc. CM106 Like Sound Device

// 0d8c:0102 
#define LED_VENDOR_ID   0x0d8c
#define LED_PRODUCT_ID  0x0102  

#define BIT(nr) (1UL << (nr))
/*
 * CM6206 registers from the CM6206 datasheet rev 2.1
 */
#define CM6206_REG0_DMA_MASTER BIT(15)
#define CM6206_REG0_SPDIFO_RATE_48K (2 << 12)
#define CM6206_REG0_SPDIFO_RATE_96K (7 << 12)
/* Bit 4 thru 11 is the S/PDIF category code */
#define CM6206_REG0_SPDIFO_CAT_CODE_GENERAL (0 << 4)
#define CM6206_REG0_SPDIFO_EMPHASIS_CD BIT(3)
#define CM6206_REG0_SPDIFO_COPYRIGHT_NA BIT(2)
#define CM6206_REG0_SPDIFO_NON_AUDIO BIT(1)
#define CM6206_REG0_SPDIFO_PRO_FORMAT BIT(0)

#define CM6206_REG1_TEST_SEL_CLK BIT(14)
#define CM6206_REG1_PLLBIN_EN BIT(13)
#define CM6206_REG1_SOFT_MUTE_EN BIT(12)
#define CM6206_REG1_GPIO4_OUT BIT(11)
#define CM6206_REG1_GPIO4_OE BIT(10)
#define CM6206_REG1_GPIO3_OUT BIT(9)
#define CM6206_REG1_GPIO3_OE BIT(8)
#define CM6206_REG1_GPIO2_OUT BIT(7)
#define CM6206_REG1_GPIO2_OE BIT(6)
#define CM6206_REG1_GPIO1_OUT BIT(5)
#define CM6206_REG1_GPIO1_OE BIT(4)
#define CM6206_REG1_SPDIFO_INVALID BIT(3)
#define CM6206_REG1_SPDIF_LOOP_EN BIT(2)
#define CM6206_REG1_SPDIFO_DIS BIT(1)
#define CM6206_REG1_SPDIFI_MIX BIT(0)

#define CM6206_REG2_DRIVER_ON BIT(15)
#define CM6206_REG2_HEADP_SEL_SIDE_CHANNELS (0 << 13)
#define CM6206_REG2_HEADP_SEL_SURROUND_CHANNELS (1 << 13)
#define CM6206_REG2_HEADP_SEL_CENTER_SUBW (2 << 13)
#define CM6206_REG2_HEADP_SEL_FRONT_CHANNELS (3 << 13)
#define CM6206_REG2_MUTE_HEADPHONE_RIGHT BIT(12)
#define CM6206_REG2_MUTE_HEADPHONE_LEFT BIT(11)
#define CM6206_REG2_MUTE_REAR_SURROUND_RIGHT BIT(10)
#define CM6206_REG2_MUTE_REAR_SURROUND_LEFT BIT(9)
#define CM6206_REG2_MUTE_SIDE_SURROUND_RIGHT BIT(8)
#define CM6206_REG2_MUTE_SIDE_SURROUND_LEFT BIT(7)
#define CM6206_REG2_MUTE_SUBWOOFER BIT(6)
#define CM6206_REG2_MUTE_CENTER BIT(5)
#define CM6206_REG2_MUTE_RIGHT_FRONT BIT(4)
#define CM6206_REG2_MUTE_LEFT_FRONT BIT(3)
#define CM6206_REG2_EN_BTL BIT(2)
#define CM6206_REG2_MCUCLKSEL_1_5_MHZ (0)
#define CM6206_REG2_MCUCLKSEL_3_MHZ (1)
#define CM6206_REG2_MCUCLKSEL_6_MHZ (2)
#define CM6206_REG2_MCUCLKSEL_12_MHZ (3)

/* Bit 11..13 sets the sensitivity to FLY tuner volume control VP/VD signal */
#define CM6206_REG3_FLYSPEED_DEFAULT (2 << 11)
#define CM6206_REG3_VRAP25EN BIT(10)
#define CM6206_REG3_MSEL1 BIT(9)
#define CM6206_REG3_SPDIFI_RATE_44_1K BIT(0 << 7)
#define CM6206_REG3_SPDIFI_RATE_48K BIT(2 << 7)
#define CM6206_REG3_SPDIFI_RATE_32K BIT(3 << 7)
#define CM6206_REG3_PINSEL BIT(6)
#define CM6206_REG3_FOE BIT(5)
#define CM6206_REG3_ROE BIT(4)
#define CM6206_REG3_CBOE BIT(3)
#define CM6206_REG3_LOSE BIT(2)
#define CM6206_REG3_HPOE BIT(1)
#define CM6206_REG3_SPDIFI_CANREC BIT(0)

#define CM6206_REG5_DA_RSTN BIT(13)
#define CM6206_REG5_AD_RSTN BIT(12)
#define CM6206_REG5_SPDIFO_AD2SPDO BIT(12)
#define CM6206_REG5_SPDIFO_SEL_FRONT (0 << 9)
#define CM6206_REG5_SPDIFO_SEL_SIDE_SUR (1 << 9)
#define CM6206_REG5_SPDIFO_SEL_CEN_LFE (2 << 9)
#define CM6206_REG5_SPDIFO_SEL_REAR_SUR (3 << 9)
#define CM6206_REG5_CODECM BIT(8)
#define CM6206_REG5_EN_HPF BIT(7)
#define CM6206_REG5_T_SEL_DSDA4 BIT(6)
#define CM6206_REG5_T_SEL_DSDA3 BIT(5)
#define CM6206_REG5_T_SEL_DSDA2 BIT(4)
#define CM6206_REG5_T_SEL_DSDA1 BIT(3)
#define CM6206_REG5_T_SEL_DSDAD_NORMAL 0
#define CM6206_REG5_T_SEL_DSDAD_FRONT 4
#define CM6206_REG5_T_SEL_DSDAD_S_SURROUND 5
#define CM6206_REG5_T_SEL_DSDAD_CEN_LFE 6
#define CM6206_REG5_T_SEL_DSDAD_R_SURROUND 7
// Sundry USB defines
#define USB_DIR_OUT			0		/* to device */
#define USB_REQ_SET_CONFIGURATION	0x09
#define USB_TYPE_CLASS			(0x01 << 5)
#define USB_RECIP_ENDPOINT		0x02

static struct usb_device *device_init(void)
{
    struct usb_bus *usb_bus;
    struct usb_device *dev;

    usb_init();
    usb_find_busses();
    usb_find_devices();

    for (usb_bus = usb_busses;
         usb_bus;
         usb_bus = usb_bus->next) {
        for (dev = usb_bus->devices;
             dev;
             dev = dev->next) {
            if ((dev->descriptor.idVendor
                  == LED_VENDOR_ID) &&
                (dev->descriptor.idProduct
                  == LED_PRODUCT_ID))
                return dev;
        }
    }
    return NULL;
}

/*
 * C-Media CM106/CM106+ have four 16-bit internal registers that are nicely
 * documented in the device's data sheet.
 */
static int snd_usb_cm106_write_int_reg(usb_dev_handle *handle, int reg, __u16 value)
{
	char buf[4];
	buf[0] = 0x20;
	buf[1] = value & 0xff;
	buf[2] = (value >> 8) & 0xff;
	buf[3] = reg;
	//https://sourceforge.net/p/libusb-win32/wiki/Documentation/
	return usb_control_msg(handle, 					// handle
		USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_ENDPOINT,	// Request type
		USB_REQ_SET_CONFIGURATION,  				// Request
		0, 								// value
		0, 								// index
		buf,								// payload
		4,
		5000);								// length
}

static int snd_usb_cm106_read_int_reg(usb_dev_handle *handle, int reg, __u16 value)
{
	char buf[4];
	buf[0] = 0x30;
	buf[1] = value & 0xff;
	buf[2] = (value >> 8) & 0xff;
	buf[3] = reg;
	//https://sourceforge.net/p/libusb-win32/wiki/Documentation/
	return usb_control_msg(handle, 					// handle
		USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_ENDPOINT,	// Request type
		USB_REQ_SET_CONFIGURATION,  				// Request
		0, 								// value
		0, 								// index
		buf,								// payload
		4,
		5000);								// length
}

int main(int argc, char **argv)
{
    struct usb_device *usb_dev;
    struct usb_dev_handle *usb_handle;
    int retval = 1;
    int i, rc, sel = 0;
    int val;
    char b[4];

    usb_set_debug(4);

    if(argc < 2)
    {
        fprintf(stderr, "Set CM6206 SPDIFOUT. Usage: setspdif n, where n is one of 0 - front, 1 - side surround, 2 - center, 3 - rear surround\n");
        return 0;
    }

    usb_dev = device_init();
    if (usb_dev == NULL) {
        fprintf(stderr, "CM6206 Device not found\n");
        goto exit;
    }

    usb_handle = usb_open(usb_dev);
    if (usb_handle == NULL) {
        fprintf(stderr, "Cannot open CM6206\n");
        goto exit;
    }

    usb_handle = usb_open(usb_dev);
    if (usb_handle == NULL) {
        fprintf(stderr,
             "Not able to claim the CM6206 USB device\n");
        goto exit;
    }

    if( argc == 2) sel = atoi(argv[1]);
    sel = sel << 9;
    fprintf(stderr, "Selector is %X\n", sel);
     

/* REG5: de-assert AD/DA reset signals */
    val = CM6206_REG5_DA_RSTN | CM6206_REG5_AD_RSTN | sel;// | CM6206_REG5_SPDIFO_SEL_SIDE_SUR; // | CM6206_REG5_SPDIFO_SEL_CEN_LFE;

    rc = snd_usb_cm106_write_int_reg(usb_handle, 5, val);
        fprintf(stderr,
             "Wrote %X to register 5, rc = %d\n", val, rc);

    retval = 0;

exit:
    usb_close(usb_handle);
    return retval;
}
1 Like

OK. Tested an aplay.conf like this:
defaults.pcm.card 1
defaults.pcm.device 0

pcm.ch40dup {
    type route
    slave.pcm surround40
    slave.channels 4
    ttable.0.0 1
    ttable.1.1 1
    ttable.0.2 1
    ttable.1.3 1
}

pcm.ch51dup {
    type route
    slave.pcm surround51
    slave.channels 6
    ttable.0.0 1
    ttable.1.1 1
    ttable.0.2 1
    ttable.1.3 1
    ttable.0.4 0.5
    ttable.1.4 0.5
}

This gives me L/R on stereo material, but I have to change output device which is a drag.

This seems to fix it: I now have signal on both the Vero4 PCM out and on the USB card:

pcm.both {
    type route;
    slave.pcm {
        type multi;
        slaves.a.pcm "plughw:0,0"
        slaves.b.pcm "plughw:1,0"
        slaves.a.channels 2;
        slaves.b.channels 6;
        bindings.0.slave a;
        bindings.0.channel 0;
        bindings.1.slave a;
        bindings.1.channel 1;
    
        bindings.2.slave b;
        bindings.2.channel 0;
        bindings.3.slave b;
        bindings.3.channel 1;
        bindings.4.slave b;
        bindings.4.channel 4;
        bindings.5.slave b;
        bindings.5.channel 5;
        bindings.6.slave b;
        bindings.6.channel 2;
        bindings.7.slave b;
        bindings.7.channel 3;
    }   
   
    ttable.0.0 1;
    ttable.1.1 1;
   
    ttable.0.2 1;  
    ttable.1.3 1;  
    ttable.2.4 1; 
    ttable.3.5 1; 
    ttable.4.6 1; 
    ttable.5.7 1; 
}

pcm.test {
        type plug
        slave.pcm "both"
}

ctl.test {
        type hw
        card SB
}
1 Like