--- sys/soundcard.h.orig	2025-06-06 09:04:26.000000000 +0900
+++ sys/soundcard.h	2025-10-22 19:06:12.833551000 +0900
@@ -170,6 +170,7 @@
 #define AFMT_U16_BE	0x00000100	/* Big endian unsigned 16-bit */
 #define AFMT_MPEG	0x00000200	/* MPEG MP2/MP3 audio */
 #define AFMT_AC3	0x00000400	/* Dolby Digital AC3 */
+#define AFMT_DSD	0x00000800	/* 1-bit DSD */
 
 /*
  * 32-bit formats below used for 24-bit audio data where the data is stored
@@ -186,6 +187,8 @@
 #define AFMT_U24_BE	0x00080000	/* Big endian unsigned 24-bit */
 #define AFMT_F32_LE	0x10000000	/* Little endian 32-bit floating point */
 #define AFMT_F32_BE	0x20000000	/* Big endian 32-bit floating point */
+#define AFMT_S64_LE	0x40000000	/* Little endian 64-bit */
+#define AFMT_S96_LE	0x80000000	/* Little endian 96-bit */
 
 /* Machine dependent AFMT_* definitions. */
 #if BYTE_ORDER == LITTLE_ENDIAN
diff -u -r dev/sound.orig/pcm/channel.c dev/sound/pcm/channel.c
--- dev/sound.orig/pcm/channel.c	2025-06-06 09:04:25.000000000 +0900
+++ dev/sound/pcm/channel.c	2025-10-22 16:09:15.585163000 +0900
@@ -964,6 +964,7 @@
 	{    "u8",   "8", NULL, AFMT_U8     },
 	{    "s8",  NULL, NULL, AFMT_S8     },
 	{   "ac3",  NULL, NULL, AFMT_AC3    },
+	{   "dsd",  NULL, NULL, AFMT_DSD    },
 #if BYTE_ORDER == LITTLE_ENDIAN
 	{ "s16le", "s16", "16", AFMT_S16_LE },
 	{ "s16be",  NULL, NULL, AFMT_S16_BE },
@@ -2372,8 +2373,10 @@
 {
 	struct pcm_channel *ch;
 	struct pcmchan_caps *caps;
+	struct snddev_info *d;
 	uint32_t bestformat, bestspeed, besthwformat, *vchanformat, *vchanrate;
 	uint32_t vpflags;
+	uint32_t oldformat;
 	int dirty, err, run, nrun;
 
 	CHN_LOCKASSERT(c);
@@ -2432,6 +2435,8 @@
 	}
 
 	if (flags & CHN_N_TRIGGER) {
+		oldformat = c->format;
+		d = c->parentsnddev;
 		if (c->direction == PCMDIR_PLAY) {
 			vchanformat = &c->parentsnddev->pvchanformat;
 			vchanrate = &c->parentsnddev->pvchanrate;
@@ -2459,8 +2464,16 @@
 			CHN_LOCK(ch);
 			if ((ch->format & AFMT_PASSTHROUGH) &&
 			    snd_fmtvalid(ch->format, caps->fmtlist)) {
-				bestformat = ch->format;
-				bestspeed = ch->speed;
+				if (ch->format & AFMT_DSD
+				    && d->flags & SD_F_DSD_TO_DOP) {
+				    oldformat = ch->format;
+				    bestspeed = ch->speed * 2;
+				    bestformat = SND_FORMAT(AFMT_S24_LE,2,0);
+				}
+				else {
+				    bestformat = ch->format;
+				    bestspeed = ch->speed;
+				}
 				CHN_UNLOCK(ch);
 				vpflags = CHN_F_PASSTHROUGH;
 				nrun++;
@@ -2561,6 +2574,7 @@
 		}
 
 		if (err == 0 && !(bestformat & AFMT_PASSTHROUGH) &&
+		    !(oldformat & AFMT_DSD && d->flags & SD_F_DSD_TO_DOP) &&
 		    (bestformat & AFMT_VCHAN)) {
 			*vchanformat = bestformat;
 			*vchanrate = bestspeed;
diff -u -r dev/sound.orig/pcm/dsp.c dev/sound/pcm/dsp.c
--- dev/sound.orig/pcm/dsp.c	2025-06-06 09:04:25.000000000 +0900
+++ dev/sound/pcm/dsp.c	2025-10-22 19:06:36.418999000 +0900
@@ -1351,8 +1351,12 @@
 				*arg_i = 16;
 			else if (chn->format & AFMT_24BIT)
 				*arg_i = 24;
-			else if (chn->format & AFMT_32BIT)
+			else if (chn->format & (AFMT_32BIT|AFMT_DSD))
 				*arg_i = 32;
+			else if (chn->format & AFMT_S64_LE)
+				*arg_i = 64;
+			else if (chn->format & AFMT_S96_LE)
+				*arg_i = 96;
 			else
 				ret = EINVAL;
 			CHN_UNLOCK(chn);
diff -u -r dev/sound.orig/pcm/feeder.c dev/sound/pcm/feeder.c
--- dev/sound.orig/pcm/feeder.c	2025-06-06 09:04:25.000000000 +0900
+++ dev/sound/pcm/feeder.c	2025-10-22 19:55:19.840467000 +0900
@@ -261,7 +261,7 @@
 #define score_cheq(s1, s2)	(((s1) & 0xfc) == ((s2) & 0xfc))
 #define score_chgt(s1, s2)	(((s1) & 0xfc) > ((s2) & 0xfc))
 #define score_chlt(s1, s2)	(((s1) & 0xfc) < ((s2) & 0xfc))
-#define score_val(s1)		((s1) & 0x3f00)
+#define score_val(s1)		((s1) & 0xff00)
 #define score_cse(s1)		((s1) & 0x7f)
 
 u_int32_t
@@ -291,6 +291,10 @@
 		ret |= 1 << 12;
 	else if (fmt & AFMT_32BIT)
 		ret |= 1 << 13;
+	else if (fmt & (AFMT_S64_LE|AFMT_S96_LE))
+		ret |= 1 << 14;
+	else if (fmt & AFMT_DSD)
+		ret |= 1 << 15;
 
 	return ret;
 }
@@ -318,13 +322,15 @@
 				continue;
 		if (oldscore == 0 ||
 			    (score_val(score2) == score_val(score)) ||
-			    (score_val(score2) == score_val(oldscore)) ||
-			    (score_val(score2) > score_val(oldscore) &&
+//			    (score_val(score2) == score_val(oldscore)) ||
+			    (AFMT_ENCODING(fmt) != AFMT_DSD &&
+			     AFMT_ENCODING(fmts[i]) != AFMT_DSD &&
+			     ((score_val(score2) > score_val(oldscore) &&
 			    score_val(score2) < score_val(score)) ||
 			    (score_val(score2) < score_val(oldscore) &&
 			    score_val(score2) > score_val(score)) ||
 			    (score_val(oldscore) < score_val(score) &&
-			    score_val(score2) > score_val(oldscore))) {
+			    score_val(score2) > score_val(oldscore))))) {
 			if (score_val(oldscore) != score_val(score2) ||
 				    score_cse(score) == score_cse(score2) ||
 				    ((score_cse(oldscore) != score_cse(score) &&
diff -u -r dev/sound.orig/pcm/feeder_chain.c dev/sound/pcm/feeder_chain.c
--- dev/sound.orig/pcm/feeder_chain.c	2025-06-06 09:04:25.000000000 +0900
+++ dev/sound/pcm/feeder_chain.c	2025-10-22 22:07:18.244986000 +0900
@@ -530,25 +530,33 @@
 /* Macrosses to ease our job doing stuffs later. */
 #define FEEDER_BW(c, t)		((c)->t.matrix->channels * (c)->t.rate)
 
-#define FEEDRATE_UP(c)		((c)->target.rate > (c)->current.rate)
-#define FEEDRATE_DOWN(c)	((c)->target.rate < (c)->current.rate)
+#define FEEDRATE_UP(c)		(AFMT_ENCODING((c)->origin.afmt)!=AFMT_DSD && \
+				(c)->target.rate > (c)->current.rate)
+#define FEEDRATE_DOWN(c)	(AFMT_ENCODING((c)->origin.afmt)!=AFMT_DSD && \
+				(c)->target.rate < (c)->current.rate)
 #define FEEDRATE_REQUIRED(c)	(FEEDRATE_UP(c) || FEEDRATE_DOWN(c))
 
-#define FEEDMATRIX_UP(c)	((c)->target.matrix->channels >		\
+#define FEEDMATRIX_UP(c)	(AFMT_ENCODING((c)->origin.afmt)!=AFMT_DSD && \
+				 (c)->target.matrix->channels >		\
 				 (c)->current.matrix->channels)
-#define FEEDMATRIX_DOWN(c)	((c)->target.matrix->channels <		\
+#define FEEDMATRIX_DOWN(c)	(AFMT_ENCODING((c)->origin.afmt)!=AFMT_DSD && \
+				 (c)->target.matrix->channels <		\
 				 (c)->current.matrix->channels)
 #define FEEDMATRIX_REQUIRED(c)	(FEEDMATRIX_UP(c) ||			\
-				 FEEDMATRIX_DOWN(c) || (c)->use_matrix != 0)
+				 FEEDMATRIX_DOWN(c) ||			\
+				 (AFMT_ENCODING((c)->origin.afmt)!=AFMT_DSD && \
+				  (c)->use_matrix != 0))
 
 #define FEEDFORMAT_REQUIRED(c)	(AFMT_ENCODING((c)->current.afmt) !=	\
 				 AFMT_ENCODING((c)->target.afmt))
 
-#define FEEDVOLUME_REQUIRED(c)	((c)->use_volume != 0)
+#define FEEDVOLUME_REQUIRED(c)	(AFMT_ENCODING((c)->origin.afmt)!=AFMT_DSD && \
+				 (c)->use_volume != 0)
 
 #define FEEDEQ_VALIDRATE(c, t)	(feeder_eq_validrate((c)->t.rate) != 0)
 #define FEEDEQ_ECONOMY(c)	(FEEDER_BW(c, current) < FEEDER_BW(c, target))
-#define FEEDEQ_REQUIRED(c)	((c)->use_eq != 0 &&			\
+#define FEEDEQ_REQUIRED(c)	(AFMT_ENCODING((c)->origin.afmt)!=AFMT_DSD && \
+				 (c)->use_eq != 0 &&			\
 				 FEEDEQ_VALIDRATE(c, current))
 
 #define FEEDFORMAT_NE_REQUIRED(c)					\
@@ -585,6 +593,7 @@
 	struct feeder_chain_desc cdesc;
 	struct pcmchan_matrix *hwmatrix, *softmatrix;
 	uint32_t hwfmt, softfmt;
+	uint32_t hwspd;
 	int ret;
 
 	CHN_LOCKASSERT(c);
@@ -620,10 +629,6 @@
 				 CHN_F_PASSTHROUGH)) ==			\
 				 (CHN_F_VIRTUAL | CHN_F_PASSTHROUGH))
 
-	/* Get the best possible hardware format. */
-	if (VCHAN_PASSTHROUGH(c))
-		hwfmt = c->parentchannel->format;
-	else {
 		caps = chn_getcaps(c);
 		if (caps == NULL || caps->fmtlist == NULL) {
 			device_printf(c->dev,
@@ -631,10 +636,19 @@
 			return (ENODEV);
 		}
 
+	/* Get the best possible hardware format. */
+	if (VCHAN_PASSTHROUGH(c)) {
+		hwfmt = c->parentchannel->format;
+		hwspd = c->parentchannel->speed;
+		if (!hwspd)
+			hwspd = sndbuf_getspd(c->bufhard);
+	}
+	else {
 		if ((c->format & AFMT_PASSTHROUGH) &&
 		    !snd_fmtvalid(c->format, caps->fmtlist))
 			return (ENODEV);
 
+		hwspd = sndbuf_getspd(c->bufhard);
 		hwfmt = snd_fmtbest(c->format, caps->fmtlist);
 		if (hwfmt == 0 || !snd_fmtvalid(hwfmt, caps->fmtlist)) {
 			device_printf(c->dev,
@@ -686,16 +700,34 @@
 		    "%s(): WARNING: %s Soft format 0x%08x -> 0x%08x\n",
 		    __func__, CHN_DIRSTR(c), c->format, softfmt);
 
+	d = c->parentsnddev;
+
 	/*
 	 * PLAY and REC are opposite.
 	 */
 	if (c->direction == PCMDIR_PLAY) {
-		cdesc.origin.afmt    = softfmt;
-		cdesc.origin.matrix  = softmatrix;
-		cdesc.origin.rate    = c->speed;
-		cdesc.target.afmt    = hwfmt;
-		cdesc.target.matrix  = hwmatrix;
-		cdesc.target.rate    = sndbuf_getspd(c->bufhard);
+		if (d->flags & SD_F_DSD_TO_DOP
+		    && AFMT_ENCODING(c->format) == AFMT_DSD) {
+			cdesc.origin.afmt    = c->format;
+			cdesc.origin.matrix  = softmatrix;
+			cdesc.origin.rate    = c->speed;
+			hwfmt	= SND_FORMAT(AFMT_S24_LE,2,0);
+			if (c->speed)
+				hwspd	= c->speed * 2;
+			RANGE(hwspd, caps->minspeed, caps->maxspeed);
+			cdesc.target.afmt    = hwfmt;
+			cdesc.target.matrix  = hwmatrix;
+			cdesc.target.rate    = hwspd;
+		}
+		else {
+			cdesc.origin.afmt    = softfmt;
+			cdesc.origin.matrix  = softmatrix;
+			cdesc.origin.rate    = c->speed;
+			RANGE(hwspd, caps->minspeed, caps->maxspeed);
+			cdesc.target.afmt    = hwfmt;
+			cdesc.target.matrix  = hwmatrix;
+			cdesc.target.rate    = hwspd;//sndbuf_getspd(c->bufhard);
+		}
 	} else {
 		cdesc.origin.afmt    = hwfmt;
 		cdesc.origin.matrix  = hwmatrix;
@@ -705,20 +737,27 @@
 		cdesc.target.rate    = c->speed;
 	}
 
-	d = c->parentsnddev;
-
 	/*
 	 * If channel is in bitperfect or passthrough mode, make it appear
 	 * that 'origin' and 'target' identical, skipping mostly chain
 	 * procedures.
 	 */
-	if (CHN_BITPERFECT(c) || (c->format & AFMT_PASSTHROUGH)) {
+	if (CHN_BITPERFECT(c) || (c->format & AFMT_AC3) ||
+	    (c->format & AFMT_DSD && !(d->flags & SD_F_DSD_TO_DOP))) {
 		if (c->direction == PCMDIR_PLAY)
 			cdesc.origin = cdesc.target;
 		else
 			cdesc.target = cdesc.origin;
 		c->format = cdesc.target.afmt;
 		c->speed  = cdesc.target.rate;
+	} else if (c->format & AFMT_DSD) {
+		if (c->direction == PCMDIR_PLAY) {
+			c->format = cdesc.origin.afmt;
+			c->speed  = cdesc.origin.rate;
+		} else {
+			c->format = cdesc.target.afmt;
+			c->speed  = cdesc.target.rate;
+		}
 	} else {
 		/*
 		 * Bail out early if we do not support either of those formats.
@@ -766,7 +805,7 @@
 				cdesc.afmt_ne =
 				    (((cdesc.dummy != 0) ? softfmt :
 				    cdesc.target.afmt) &
-				    (AFMT_24BIT | AFMT_32BIT)) ?
+				    (AFMT_24BIT | AFMT_32BIT | AFMT_DSD)) ?
 				    AFMT_S32_NE : AFMT_S16_NE;
 			}
 		}
@@ -862,6 +901,7 @@
 	sndbuf_setspd(c->bufsoft, c->speed);
 
 	sndbuf_setfmt(c->bufhard, hwfmt);
+	sndbuf_setspd(c->bufhard, hwspd);
 
 	chn_syncstate(c);
 
diff -u -r dev/sound.orig/pcm/feeder_format.c dev/sound/pcm/feeder_format.c
--- dev/sound.orig/pcm/feeder_format.c	2025-06-06 09:04:25.000000000 +0900
+++ dev/sound/pcm/feeder_format.c	2025-10-22 19:10:50.690833000 +0900
@@ -69,6 +69,16 @@
 	if (info == NULL)
 		return (ENOMEM);
 
+	if (AFMT_ENCODING(f->desc->in) == AFMT_DSD) {
+		info->channels = 1;
+		info->ibps = 8;//AFMT_BPS(f->desc->in) * info->channels;
+		info->ialign = info->ibps;
+		info->rdfmt = AFMT_S64_LE;
+		info->obps = 12;
+		info->oalign = info->obps;
+		info->wrfmt = AFMT_S96_LE; /* 96bits */
+	}
+	else {
 	info->channels = AFMT_CHANNEL(f->desc->in);
 
 	info->ibps = AFMT_BPS(f->desc->in);
@@ -78,6 +88,7 @@
 	info->obps = AFMT_BPS(f->desc->out);
 	info->oalign = info->obps * info->channels;
 	info->wrfmt = AFMT_ENCODING(f->desc->out);
+	}
 
 	f->data = info;
 
diff -u -r dev/sound.orig/pcm/pcm.h dev/sound/pcm/pcm.h
--- dev/sound.orig/pcm/pcm.h	2025-06-06 09:04:25.000000000 +0900
+++ dev/sound/pcm/pcm.h	2025-10-22 19:31:55.700888000 +0900
@@ -50,7 +50,7 @@
 #define SND_PCM_64	1
 #endif
 
-typedef int32_t intpcm_t;
+typedef int64_t intpcm_t;
 
 typedef int32_t intpcm8_t;
 typedef int32_t intpcm16_t;
@@ -100,6 +100,7 @@
 #define PCM_16_BPS	2
 #define PCM_24_BPS	3
 #define PCM_32_BPS	4
+#define PCM_48_BPS	6
 
 #define INTPCM_T(v)	((intpcm_t)(v))
 #define INTPCM8_T(v)	((intpcm8_t)(v))
@@ -191,6 +192,12 @@
 		v = INTPCM_T(src[3] | src[2] << 8 | src[1] << 16 |
 		    (int8_t)(src[0] ^ 0x80) << 24);
 		break;
+	case AFMT_S64_LE: {
+		const intpcm_t *src64 = (const intpcm_t*)src;
+		v = INTPCM_T(src64[0] | (src64[1] << 8) | (src64[2] << 16) |
+			(src64[3] << 24) | (src64[4] << 32) | (src64[5] << 40) |
+			(src64[6] << 48) | (src64[7] << 56));
+	}	break;
 	case AFMT_F32_LE:	/* FALLTHROUGH */
 	case AFMT_F32_BE:
 		if (fmt == AFMT_F32_LE) {
@@ -234,7 +241,8 @@
 static __always_inline __unused intpcm_t
 pcm_sample_read_norm(const uint8_t *src, uint32_t fmt)
 {
-	return (pcm_sample_read(src, fmt) << (32 - AFMT_BIT(fmt)));
+	return (pcm_sample_read(src, fmt) <<
+		((32 >= AFMT_BIT(fmt)) ? (32 - AFMT_BIT(fmt)) : 0));
 }
 
 /*
@@ -380,6 +388,20 @@
 		dst[1] = v >> 16;
 		dst[0] = (v >> 24) ^ 0x80;
 		break;
+	case AFMT_S96_LE:
+		dst[0] = v;
+		dst[1] = v >> 8;
+		dst[2] = 0x05;
+		dst[3] = v >> 16;
+		dst[4] = v >> 24;
+		dst[5] = 0x05;
+		dst[6] = v >> 32;
+		dst[7] = v >> 40;
+		dst[8] = 0xfa;
+		dst[9] = v >> 48;
+		dst[10] = v >> 56;
+		dst[11] = 0xfa;
+		break;
 	default:
 		printf("%s(): unknown format: 0x%08x\n", __func__, fmt);
 		__assert_unreachable();
@@ -392,7 +414,10 @@
 static __always_inline __unused void
 pcm_sample_write_norm(uint8_t *dst, intpcm_t v, uint32_t fmt)
 {
-	pcm_sample_write(dst, v >> (32 - AFMT_BIT(fmt)), fmt);
+	pcm_sample_write(
+		dst,
+		v >> ((32 >= AFMT_BIT(fmt)) ? (32 - AFMT_BIT(fmt)) : 0),
+		fmt);
 }
 
 /*
diff -u -r dev/sound.orig/pcm/sound.c dev/sound/pcm/sound.c
--- dev/sound.orig/pcm/sound.c	2025-06-06 09:04:25.000000000 +0900
+++ dev/sound/pcm/sound.c	2025-10-22 15:39:34.387636000 +0900
@@ -390,6 +390,43 @@
 	return (sysctl_handle_int(oidp, &mode, 0, req));
 }
 
+static int
+sysctl_dev_pcm_dsd_to_dop(SYSCTL_HANDLER_ARGS)
+{
+	struct snddev_info *d;
+	int err, val;
+
+	d = oidp->oid_arg1;
+	if (!PCM_REGISTERED(d))
+		return (ENODEV);
+
+	PCM_LOCK(d);
+	PCM_WAIT(d);
+	val = (d->flags & SD_F_DSD_TO_DOP) ? 1 : 0;
+	PCM_ACQUIRE(d);
+	PCM_UNLOCK(d);
+
+	err = sysctl_handle_int(oidp, &val, 0, req);
+
+	if (err == 0 && req->newptr != NULL) {
+		if (!(val == 0 || val == 1)) {
+			PCM_RELEASE_QUICK(d);
+			return (EINVAL);
+		}
+
+		PCM_LOCK(d);
+
+		d->flags &= ~SD_F_DSD_TO_DOP;
+		d->flags |= (val != 0) ? SD_F_DSD_TO_DOP : 0;
+
+		PCM_RELEASE(d);
+		PCM_UNLOCK(d);
+	} else
+		PCM_RELEASE_QUICK(d);
+
+	return (err);
+}
+
 static void
 pcm_sysinit(device_t dev)
 {
@@ -414,6 +451,11 @@
 	    "bitperfect", CTLTYPE_INT | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, d,
 	    sizeof(d), sysctl_dev_pcm_bitperfect, "I",
 	    "bit-perfect playback/recording (0=disable, 1=enable)");
+	SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
+	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
+	    "dsd_to_dop", CTLTYPE_INT | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, d,
+	    sizeof(d), sysctl_dev_pcm_dsd_to_dop, "I",
+	    "playback dsd as dop (0=disable, 1=enable)");
 	SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
 	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
 	    "mode", CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_MPSAFE, d, sizeof(d),
--- dev/sound.orig/pcm/sound.h	2025-06-06 09:04:25.000000000 +0900
+++ dev/sound/pcm/sound.h	2025-10-22 19:46:04.473206000 +0900
@@ -116,6 +116,7 @@
 #define SD_F_EQ_PC		0x00000800	/* EQ per-channel */
 #define SD_F_PVCHANS		0x00001000	/* Playback vchans enabled */
 #define SD_F_RVCHANS		0x00002000	/* Recording vchans enabled */
+#define SD_F_DSD_TO_DOP		0x00004000	/* convert DSD to DoP */
 
 #define SD_F_EQ_DEFAULT		(SD_F_EQ | SD_F_EQ_ENABLED)
 #define SD_F_EQ_MASK		(SD_F_EQ | SD_F_EQ_ENABLED |		\
@@ -139,6 +140,7 @@
 				"\014EQ_PC"				\
 				"\015PVCHANS"				\
 				"\016RVCHANS"				\
+				"\017DSD_TO_DOP"			\
 				"\035PRIO_RD"				\
 				"\036PRIO_WR"
 
@@ -469,7 +471,7 @@
 /* Supported vchan mixing formats */
 #define AFMT_VCHAN		(AFMT_CONVERTIBLE & ~AFMT_G711)
 
-#define AFMT_PASSTHROUGH		AFMT_AC3
+#define AFMT_PASSTHROUGH		(AFMT_AC3|AFMT_DSD)
 #define AFMT_PASSTHROUGH_RATE		48000
 #define AFMT_PASSTHROUGH_CHANNEL	2
 #define AFMT_PASSTHROUGH_EXTCHANNEL	0
@@ -494,10 +496,12 @@
 #define AFMT_CHANNEL(v)		(((v) & AFMT_CHANNEL_MASK) >>		\
 				AFMT_CHANNEL_SHIFT)
 
-#define AFMT_BIT(v)		(((v) & AFMT_32BIT) ? 32 :		\
+#define AFMT_BIT(v)		(((v) & AFMT_S96_LE) ? 96 :	\
+				(((v) & AFMT_S64_LE) ? 64 :		\
+				(((v) & (AFMT_32BIT|AFMT_DSD)) ? 32 :	\
 				(((v) & AFMT_24BIT) ? 24 :		\
 				((((v) & AFMT_16BIT) ||			\
-				((v) & AFMT_PASSTHROUGH)) ? 16 : 8)))
+				((v) & AFMT_AC3)) ? 16 : 8)))))
 
 #define AFMT_BPS(v)		(AFMT_BIT(v) >> 3)
 #define AFMT_ALIGN(v)		(AFMT_BPS(v) * AFMT_CHANNEL(v))
diff -u -r dev/sound.orig/pcm/vchan.c dev/sound/pcm/vchan.c
--- dev/sound.orig/pcm/vchan.c	2025-06-06 09:04:25.000000000 +0900
+++ dev/sound/pcm/vchan.c	2025-10-22 19:43:37.329988000 +0900
@@ -41,10 +41,11 @@
 #include <dev/sound/pcm/vchan.h>
 
 /*
- * [ac3 , dts , linear , 0, linear, 0]
+ * [ac3 , dts , linear , linear, linear, 0, linear, 0]
  */
-#define FMTLIST_MAX		6
-#define FMTLIST_OFFSET		4
+#define FMTLIST_MAX		9
+#define FMTLIST_OFFSET		7
+#define LINEARFMTS_MAX		6
 #define DIGFMTS_MAX		2
 
 #ifdef SND_DEBUG
@@ -88,6 +89,10 @@
 		if (fmtlist[i] & AFMT_PASSTHROUGH)
 			info->fmtlist[j++] = fmtlist[i];
 	}
+	for (i = 0; fmtlist[i] != 0 && j < LINEARFMTS_MAX; i++) {
+		if (!(fmtlist[i] & AFMT_PASSTHROUGH))
+			info->fmtlist[j++] = fmtlist[i];
+	}
 	if (p->format & AFMT_VCHAN)
 		info->fmtlist[j] = p->format;
 	else
@@ -192,10 +197,12 @@
 {
 	struct vchan_info *info;
 	struct pcm_channel *c;
+	struct snddev_info *d;
 	uint32_t pformat, pspeed, pflags, i;
 
 	info = data;
 	c = info->channel;
+	d = c->parentsnddev;
 	pformat = c->parentchannel->format;
 	pspeed = c->parentchannel->speed;
 	pflags = c->parentchannel->flags;
@@ -213,10 +220,18 @@
 			info->caps.fmtlist[i] = pformat;
 		}
 		if (c->format & AFMT_PASSTHROUGH)
+		    if (c->format & AFMT_DSD && d->flags & SD_F_DSD_TO_DOP) {
 			info->caps.minspeed = c->speed;
-		else 
+			info->caps.maxspeed = info->caps.minspeed * 2;
+		    }
+		    else {
+			info->caps.minspeed = c->speed;
+			info->caps.maxspeed = info->caps.minspeed;
+		    }
+		else  {
 			info->caps.minspeed = pspeed;
-		info->caps.maxspeed = info->caps.minspeed;
+			info->caps.maxspeed = info->caps.minspeed;
+		}
 	} else {
 		info->caps.fmtlist = info->fmtlist + FMTLIST_OFFSET;
 		if (pformat & AFMT_VCHAN)
diff -u -r dev/sound.orig/usb/uaudio.c dev/sound/usb/uaudio.c
--- dev/sound.orig/usb/uaudio.c	2025-06-06 09:04:25.000000000 +0900
+++ dev/sound/usb/uaudio.c	2025-08-30 15:46:40.926119000 +0900
@@ -213,7 +213,7 @@
 	struct uaudio_softc *sc;
 };
 
-#define	CHAN_MAX_ALT 24
+#define	CHAN_MAX_ALT 128
 
 struct uaudio_chan_alt {
 	union uaudio_asf1d p_asf1d;
@@ -253,7 +253,8 @@
 
 	int feedback_rate;
 
-	uint32_t pcm_format[2];
+	uint32_t pcm_format_count;
+	uint32_t pcm_format[CHAN_MAX_ALT+1];
 
 	uint16_t bytes_per_frame[2];
 
@@ -426,7 +427,7 @@
 };
 
 struct uaudio_format {
-	uint16_t wFormat;
+	uint32_t wFormat;
 	uint8_t	bPrecision;
 	uint32_t freebsd_fmt;
 	const char *description;
@@ -461,6 +462,8 @@
 
 	{UA20_FMT_ALAW, 8, AFMT_A_LAW, "8-bit A-Law"},
 	{UA20_FMT_MULAW, 8, AFMT_MU_LAW, "8-bit mu-Law"},
+
+	{UA20_FMT_RAW, 32, AFMT_DSD, "1-bit DSD"},
 	{0, 0, 0, NULL}
 };
 
@@ -511,6 +514,8 @@
 static void	uaudio_mixer_find_inputs_sub(struct uaudio_terminal_node *,
 		    const uint8_t *, uint8_t, struct uaudio_search_result *);
 static const void *uaudio_mixer_verify_desc(const void *, uint32_t);
+static usb_error_t uaudio_set_format(struct usb_device *, uint8_t,
+		    uint8_t, uint32_t);
 static usb_error_t uaudio_set_speed(struct usb_device *, uint8_t, uint32_t);
 static int	uaudio_mixer_get(struct usb_device *, uint16_t, uint8_t,
 		    struct uaudio_mixer_node *);
@@ -531,6 +536,9 @@
 static const void *uaudio20_mixer_verify_desc(const void *, uint32_t);
 static usb_error_t uaudio20_set_speed(struct usb_device *, uint8_t,
 		    uint8_t, uint32_t);
+static usb_error_t
+uaudio20_set_format(struct usb_device *udev, uint8_t iface_no,
+    uint8_t clockid, uint32_t format);
 
 /* USB audio v1.0 and v2.0 */
 
@@ -1467,6 +1475,11 @@
 				DPRINTF("setting of sample rate failed! "
 				    "(continuing anyway)\n");
 			}
+			if (uaudio20_set_format(sc->sc_udev,
+			    sc->sc_mixer_iface_no, x, chan_alt->p_fmt->wFormat)) {
+				DPRINTF("setting of format failed! "
+				    "(continuing anyway)\n");
+			}
 		}
 	} else if (chan_alt->p_sed.v1->bmAttributes & UA_SED_FREQ_CONTROL) {
 		if (uaudio_set_speed(sc->sc_udev,
@@ -1629,7 +1642,7 @@
 {
 	struct usb_device_request req;
 	usb_error_t error;
-#define	UAUDIO20_MAX_RATES 32	/* we support at maximum 32 rates */
+#define	UAUDIO20_MAX_RATES 64	/* we support at maximum 32 rates */
 	uint8_t data[2 + UAUDIO20_MAX_RATES * 12];
 	uint16_t actlen;
 	uint16_t rates;
@@ -1766,6 +1779,7 @@
 	uint8_t audio_if = 0;
 	uint8_t midi_if = 0;
 	uint8_t uma_if_class;
+	uint32_t i;
 
 	while ((desc = usb_desc_foreach(cd, desc))) {
 		if ((desc->bDescriptorType == UDESC_INTERFACE) &&
@@ -1957,13 +1971,17 @@
 
 			if ((bChannels != channels) ||
 			    (bBitResolution != bit_resolution)) {
-				DPRINTF("Wrong number of channels\n");
+				DPRINTF("Wrong number of "
+					"bChannels:%d channels:%d, "
+					"bBitResolution:%d, bit_resolution:%d\n",
+					(int)bChannels, (int)channels,
+					(int)bBitResolution,(int)bit_resolution);
 				goto next_ep;
 			}
 
 			for (p_fmt = uaudio20_formats;
 			    p_fmt->wFormat != 0; p_fmt++) {
-				if ((p_fmt->wFormat & dwFormat) &&
+				if ((p_fmt->wFormat == dwFormat) &&
 				    (p_fmt->bPrecision == bBitResolution))
 					break;
 			}
@@ -1991,8 +2009,8 @@
 				if (uaudio20_check_rate(udev,
 				    sc->sc_mixer_iface_no, x, rate)) {
 					DPRINTF("Unsupported sampling "
-					    "rate, id=%d\n", x);
-					goto next_ep;
+					    "rate=%d, id=%d\n", rate, x);
+					continue;//goto next_ep;
 				}
 			}
 		} else {
@@ -2035,7 +2053,11 @@
 
 			if ((bChannels != channels) ||
 			    (bBitResolution != bit_resolution)) {
-				DPRINTF("Wrong number of channels\n");
+				DPRINTF("Wrong number of "
+					"bChannels:%d channels:%d, "
+					"bBitResolution:%d, bit_resolution:%d\n",
+					(int)bChannels, (int)channels,
+					(int)bBitResolution,(int)bit_resolution);
 				goto next_ep;
 			}
 		}
@@ -2064,8 +2086,10 @@
 		uaudio_chan_dump_ep_desc(ed1);
 #endif
 		DPRINTF("Sample rate = %dHz, channels = %d, "
-		    "bits = %d, format = %s, ep 0x%02x, chan %p\n", rate, channels,
-		    bit_resolution, p_fmt->description, ed1->bEndpointAddress, chan);
+		    "bits = %d, format = %s, ep 0x%02x, alt_idx %d, chan %p\n",
+		    rate, channels,
+		    bit_resolution, p_fmt->description, ed1->bEndpointAddress,
+		    alt_index, chan);
 
 		chan_alt->sample_rate = rate;
 		chan_alt->p_asf1d = asf1d;
@@ -2120,21 +2144,29 @@
 			goto next_ep;
 		}
 		if (chan->num_alt > 1) {
-			/* we only accumulate one format at different sample rates */
-			if (chan->pcm_format[0] != format) {
-				DPRINTF("Multiple formats is not supported\n");
+			/* ignore if duplicate format and sample rate entry */
+			if (format == chan->usb_alt[chan->num_alt - 2].p_fmt->freebsd_fmt &&
+			    rate == chan->usb_alt[chan->num_alt - 2].sample_rate) {
+				DPRINTF("Duplicate format and sample rate detected\n");
 				chan->num_alt--;
 				goto next_ep;
 			}
-			/* ignore if duplicate sample rate entry */
-			if (rate == chan->usb_alt[chan->num_alt - 2].sample_rate) {
-				DPRINTF("Duplicate sample rate detected\n");
-				chan->num_alt--;
-				goto next_ep;
-			}
 		}
 		chan->pcm_cap.fmtlist = chan->pcm_format;
-		chan->pcm_cap.fmtlist[0] = format;
+		for (i = 0; i< chan->pcm_format_count; i++) {
+			if (chan->pcm_format[i] == format) {
+				break;
+			}
+		}
+		if (i == chan->pcm_format_count) {
+			if (chan->pcm_format_count >= CHAN_MAX_ALT) {
+				printf("pcm_format_count over.\n");
+			}
+			else {
+				chan->pcm_cap.fmtlist[chan->pcm_format_count] = format;
+				chan->pcm_format_count++;
+			}
+		}
 
 		/* check if device needs bitperfect */
 		if (chan_alt->channels > UAUDIO_MATRIX_MAX)
@@ -2154,6 +2186,8 @@
 /* This structure defines all the supported rates. */
 
 static const uint32_t uaudio_rate_list[CHAN_MAX_ALT] = {
+	768000,
+	705600,
 	384000,
 	352800,
 	192000,
@@ -2286,7 +2320,7 @@
 
 		temp = UGETDW(buf);
 
-		DPRINTF("Value = 0x%08x\n", (int)temp);
+		DPRINTFN(2,"Value = 0x%08x\n", (int)temp);
 
 		/* auto-detect SYNC format */
 
@@ -2309,7 +2343,7 @@
 		while (temp > (sample_rate + (sample_rate / 2)))
 			temp /= 2;
 
-		DPRINTF("Comparing %d Hz :: %d Hz\n",
+		DPRINTFN(2,"Comparing %d Hz :: %d Hz\n",
 		    (int)temp, (int)sample_rate);
 
 		/*
@@ -2722,6 +2756,13 @@
 }
 
 int
+uaudio_chan_reset(struct uaudio_chan *ch)
+{
+        msleep(ch, ch->pcm_mtx, 0, "reset", 50);
+	return (0);
+}
+
+int
 uaudio_chan_set_param_blocksize(struct uaudio_chan *ch, uint32_t blocksize)
 {
 	uint32_t temp = 2 * uaudio_get_buffer_size(ch, ch->set_alt);
@@ -2822,7 +2863,30 @@
 int
 uaudio_chan_set_param_format(struct uaudio_chan *ch, uint32_t format)
 {
+	struct uaudio_softc *sc;
+	/* struct uaudio_chan_alt *chan_alt; */
+	uint32_t dop_format, dop_speed;
+	uint8_t next_alt;
+
 	DPRINTF("Selecting format 0x%08x\n", (unsigned int)format);
+
+	sc = ch->priv_sc;
+	dop_speed	= sndbuf_getspd(ch->pcm_ch->bufhard);
+	dop_format	= format;
+
+	for (next_alt = 0; next_alt < ch->num_alt; next_alt++) {
+		if (dop_speed == ch->usb_alt[next_alt].sample_rate
+		    && AFMT_ENCODING(dop_format)
+		    == AFMT_ENCODING(ch->usb_alt[next_alt].p_fmt->freebsd_fmt))
+ 			break;
+	}
+	if (next_alt == ch->num_alt)
+		next_alt--;
+
+	usb_proc_explore_lock(sc->sc_udev);
+	ch->set_alt = next_alt;
+	usb_proc_explore_unlock(sc->sc_udev);
+
 	return (0);
 }
 
@@ -5360,6 +5424,34 @@
 	data[1] = speed >> 8;
 	data[2] = speed >> 16;
 	data[3] = speed >> 24;
+
+	return (usbd_do_request(udev, NULL, &req, data));
+}
+
+static usb_error_t
+uaudio20_set_format(struct usb_device *udev, uint8_t iface_no,
+    uint8_t clockid, uint32_t format)
+{
+	struct usb_device_request req;
+	uint8_t data[8];
+
+	DPRINTFN(6, "ifaceno=%d clockid=%d format=0x%08x\n",
+	    iface_no, clockid, format);
+
+	req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
+	req.bRequest = UA20_CS_CUR;
+	USETW2(req.wValue, UA20_CS_AUDIO_FORMAT_CONTROL, 0);
+	USETW2(req.wIndex, clockid, iface_no);
+	USETW(req.wLength, 8);
+	/* USETDW(data,format); */
+	data[0] = format;
+	data[1] = format >> 8;
+	data[2] = format >> 16;
+	data[3] = format >> 24;
+	data[4] = 0;//format >> 24;
+	data[5] = 0;//format >> 16;
+	data[6] = 0;//format >> 8;
+	data[7] = 0;//format;
 
 	return (usbd_do_request(udev, NULL, &req, data));
 }
diff -u -r dev/sound.orig/usb/uaudio.h dev/sound/usb/uaudio.h
--- dev/sound.orig/usb/uaudio.h	2025-06-06 09:04:25.000000000 +0900
+++ dev/sound/usb/uaudio.h	2025-10-22 15:27:06.081273000 +0900
@@ -43,6 +43,7 @@
 extern void	*uaudio_chan_init(struct uaudio_chan *ch, struct snd_dbuf *b,
 		    struct pcm_channel *c, int dir);
 extern int	uaudio_chan_free(struct uaudio_chan *ch);
+extern int	uaudio_chan_reset(struct uaudio_chan *ch);
 extern int	uaudio_chan_set_param_blocksize(struct uaudio_chan *ch,
 		    uint32_t blocksize);
 extern int	uaudio_chan_set_param_fragments(struct uaudio_chan *ch,
diff -u -r dev/sound.orig/usb/uaudio_pcm.c dev/sound/usb/uaudio_pcm.c
--- dev/sound.orig/usb/uaudio_pcm.c	2025-06-06 09:04:25.000000000 +0900
+++ dev/sound/usb/uaudio_pcm.c	2025-05-07 07:09:45.174877000 +0900
@@ -50,6 +50,12 @@
 }
 
 static int
+ua_chan_reset(kobj_t obj, void *data)
+{
+	return (uaudio_chan_reset(data));
+}
+
+static int
 ua_chan_setformat(kobj_t obj, void *data, uint32_t format)
 {
 	/*
@@ -111,6 +117,7 @@
 static kobj_method_t ua_chan_methods[] = {
 	KOBJMETHOD(channel_init, ua_chan_init),
 	KOBJMETHOD(channel_free, ua_chan_free),
+	KOBJMETHOD(channel_reset, ua_chan_reset),
 	KOBJMETHOD(channel_setformat, ua_chan_setformat),
 	KOBJMETHOD(channel_setspeed, ua_chan_setspeed),
 	KOBJMETHOD(channel_setblocksize, ua_chan_setblocksize),
diff -u -r dev/sound.orig/usb/uaudioreg.h dev/sound/usb/uaudioreg.h
--- dev/sound.orig/usb/uaudioreg.h	2025-06-06 09:04:25.000000000 +0900
+++ dev/sound/usb/uaudioreg.h	2024-10-07 06:03:44.450403000 +0900
@@ -782,6 +782,7 @@
 
 #define	UA20_CS_SAM_FREQ_CONTROL	0x01
 #define	UA20_CS_CLOCK_VALID_CONTROL 	0x02
+#define	UA20_CS_AUDIO_FORMAT_CONTROL 	0x03
 
 #define	UA20_TE_COPY_PROTECT_CONTROL	0x01
 #define	UA20_TE_CONNECTOR_CONTROL	0x02
