From noackjr@compgeek.noacks.org  Fri Jul  2 08:18:02 2004
Return-Path: <noackjr@compgeek.noacks.org>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id 1705816A4CE
	for <FreeBSD-gnats-submit@freebsd.org>; Fri,  2 Jul 2004 08:18:02 +0000 (GMT)
Received: from smtp004.bizmail.sc5.yahoo.com (smtp004.bizmail.sc5.yahoo.com [66.163.175.81])
	by mx1.FreeBSD.org (Postfix) with SMTP id E76FB43D58
	for <FreeBSD-gnats-submit@freebsd.org>; Fri,  2 Jul 2004 08:18:01 +0000 (GMT)
	(envelope-from noackjr@compgeek.noacks.org)
Received: from unknown (HELO optimator.noacks.org) (noackjr@supercrime.org@70.240.179.20 with login)
  by smtp004.bizmail.sc5.yahoo.com with SMTP; 2 Jul 2004 08:17:03 -0000
Received: from localhost (localhost [127.0.0.1])
	by optimator.noacks.org (Postfix) with ESMTP id ADA5461D2;
	Fri,  2 Jul 2004 03:17:01 -0500 (CDT)
Received: from optimator.noacks.org ([127.0.0.1])
 by localhost (optimator.noacks.org [127.0.0.1]) (amavisd-new, port 10024)
 with LMTP id 19173-02; Fri,  2 Jul 2004 03:16:58 -0500 (CDT)
Received: from compgeek.noacks.org (compgeek [192.168.1.10])
	by optimator.noacks.org (Postfix) with ESMTP id DB8FE6131;
	Fri,  2 Jul 2004 03:16:57 -0500 (CDT)
Received: (from noackjr@localhost)
	by compgeek.noacks.org (8.12.11/8.12.11/Submit) id i628Gvxa001684;
	Fri, 2 Jul 2004 03:16:57 -0500 (CDT)
	(envelope-from noackjr)
Message-Id: <200407020816.i628Gvxa001684@compgeek.noacks.org>
Date: Fri, 2 Jul 2004 03:16:57 -0500 (CDT)
From: Jonathan Noack <noackj@concordiacrusaders.org>
Reply-To: Jonathan Noack <noackj@concordiacrusaders.org>
To: FreeBSD-gnats-submit@freebsd.org
Cc: Mathew Kanner <mat@cnd.mcgill.ca>
Subject: [PATCH] enable S/PDIF output for es137x sound cards
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         68594
>Category:       kern
>Synopsis:       [sound] [patch] enable S/PDIF output for es137x sound cards
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    sound
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Fri Jul 02 08:20:22 GMT 2004
>Closed-Date:    Sun Jul 31 14:15:10 GMT 2005
>Last-Modified:  Sun Jul 31 14:15:10 GMT 2005
>Originator:     Jonathan Noack
>Release:        FreeBSD 5.2-CURRENT i386
>Organization:
Concordia Lutheran High School
>Environment:
System: FreeBSD compgeek.noacks.org 5.2-CURRENT FreeBSD 5.2-CURRENT #11: Wed Jun 30 19:53:45 CDT 2004 noackjr@compgeek.noacks.org:/usr/obj/usr/src/sys/COMPGEEK i386
>Description:
	Filing PR so this doesn't get lost.  I have been using this patch
	for four months now with no problems (other than generic pcm
	issues such as the locking...).  See freebsd-multimedia archive
	for original discussion:
	http://docs.freebsd.org/cgi/mid.cgi?402624D7.4060009

	This code was adapted from the via8233 driver.  The es1373 white
	paper at http://www.corbac.com/Data/Misc/es1373.ps.gz was also
	invaluable.

	I added a hw.snd.pcmX.spdif_enabled sysctl to enable/disable the
	S/PDIF support.  Enabling this sysctl does three things:
	1) ENABLE_SPDIF output
	2) Set to SPDIF_OUT instead of SPDIF_THRU
	3) Mute analog input to get clean digital out (with RECEN_B)

	Disabling the sysctl just reverts these three steps.

	Things to ponder/shake_your_fist_at_the_world_over:
	1) Mathew Kanner said he was working on revamping the pcm(4) man
	   page.  As a result, there is no man page update with this PR.
	2) This may not work for all es137x sound cards.  I do not know
	   what will happen if S/PDIF is enabled on a card that doesn't
	   support it.  Most sources say only revision 4+ cards support
	   S/PDIF, but some disagree with this.  *shrug*
	3) Enabling S/PDIF causes a degradation in the quality of the
	   analog sound outputs.  I believe this degradation is caused by
	   the sound card outputting both the analog and digital signals
	   to the same analog output plug.  This may be due to some
	   versions of the card not having a separate digital out plug
	   (the line out serves as both the analog and digital out).  If
	   so, it may be necessary to mute the analog portion in order to
	   get a clean digital signal on these cards.
	4) Master volume control has no effect (although individual pcm
	   stream volume is properly handled.
>How-To-Repeat:
	N/A
>Fix:
	See patch below.

--- es137x.diff begins here ---
Index: es137x.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/sound/pci/es137x.c,v
retrieving revision 1.50
diff -u -r1.50 es137x.c
--- es137x.c	17 Mar 2004 17:50:44 -0000	1.50
+++ es137x.c	25 May 2004 12:35:15 -0000
@@ -831,6 +831,59 @@
 	}
 }
 
+static int es1371x_spdif_en;
+
+static int
+sysctl_es1371x_spdif_enable(SYSCTL_HANDLER_ARGS)
+{
+	struct es_info *es;
+	device_t dev;
+	int err, new_en, r;
+
+	new_en = es1371x_spdif_en;
+	err = sysctl_handle_int(oidp, &new_en, sizeof(new_en), req);
+	if (err || req->newptr == NULL)
+		return err;
+
+	if (new_en < 0 || new_en > 1)
+		return EINVAL;
+	es1371x_spdif_en = new_en;
+
+	dev = oidp->oid_arg1;
+	es = pcm_getdevinfo(dev);
+	r = bus_space_read_4(es->st, es->sh, ES1370_REG_STATUS);
+	if (new_en) {
+		r |= ENABLE_SPDIF;
+		es->ctrl |= SPDIFEN_B;
+		es->ctrl |= RECEN_B;
+	} else {
+		r &= ~ENABLE_SPDIF;
+		es->ctrl &= ~SPDIFEN_B;
+		es->ctrl &= ~RECEN_B;
+	}
+	bus_space_write_4(es->st, es->sh, ES1370_REG_CONTROL, es->ctrl);
+	bus_space_write_4(es->st, es->sh, ES1370_REG_STATUS, r);
+	return 0;
+}
+
+static void
+es_init_sysctls(device_t dev)
+{
+	struct es_info *es;
+	int r;
+
+	es = pcm_getdevinfo(dev);
+	r = bus_space_read_4(es->st, es->sh, ES1370_REG_STATUS);
+	es1371x_spdif_en = (r & ENABLE_SPDIF) ? 1 : 0;
+
+	SYSCTL_ADD_PROC(snd_sysctl_tree(dev),
+			SYSCTL_CHILDREN(snd_sysctl_tree_top(dev)),
+			OID_AUTO, "spdif_enabled",
+			CTLTYPE_INT | CTLFLAG_RW, dev, sizeof(dev),
+			sysctl_es1371x_spdif_enable, "I",
+			"Enable S/PDIF output on primary playback channel");
+}
+
 static int
 es_pci_attach(device_t dev)
 {
@@ -931,6 +984,9 @@
 	if (pcm_register(dev, es, 1, 1)) goto bad;
 	pcm_addchan(dev, PCMDIR_REC, ct, es);
 	pcm_addchan(dev, PCMDIR_PLAY, ct, es);
+
+	es_init_sysctls(dev);
+
 	pcm_setstatus(dev, status);
 
 	return 0;
Index: es137x.h
===================================================================
RCS file: /home/ncvs/src/sys/dev/sound/pci/es137x.h,v
retrieving revision 1.4
diff -u -r1.4 es137x.h
--- es137x.h	5 Apr 2000 00:38:00 -0000	1.4
+++ es137x.h	25 May 2004 12:35:15 -0000
@@ -167,6 +167,17 @@
 #define ES1371_SRC_RAM_DATAI(i) (((i)>>0)&0xffff)	/* current value of the sample rate converter */
 
 /*
+ * S/PDIF specific
+ */
+
+/* Use ES1370_REG_CONTROL */
+#define RECEN_B			0x08000000	/* Used to control mixing of analog with digital data */
+#define SPDIFEN_B		0x04000000	/* Reset to switch digital output mux to "THRU" mode */
+/* Use ES1370_REG_STATUS */
+#define ENABLE_SPDIF		0x00040000	/* Used to enable the S/PDIF circuitry */
+#define TEST_SPDIF		0x00020000	/* Used to put the S/PDIF module in "test mode" */
+
+/*
  *  Sample rate converter addresses
  */
 
--- es137x.diff ends here ---


>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->sound 
Responsible-Changed-By: arved 
Responsible-Changed-When: Fri Jul 23 13:19:15 GMT 2004 
Responsible-Changed-Why:  
over to sound maintainers 

http://www.freebsd.org/cgi/query-pr.cgi?pr=68594 

From: Jon Noack <noackjr@alumni.rice.edu>
To: freebsd-gnats-submit@FreeBSD.org, noackj@concordiacrusaders.org,
	julian@elischer.org
Cc:  
Subject: Re: kern/68594: [PATCH] enable S/PDIF output for es137x sound cards
Date: Sun, 22 Aug 2004 01:14:17 -0500

 The patch in the PR is still current.  The only change to these files 
 since the original PR was filed was during the renaming of snd_pcm to 
 sound mega-commit.  As the change was an in-place single-line change, 
 the line numbers of the patch didn't change.
 
 I was originally told the style was OK, but a quick glance at it would 
 be appreciated.
 
 This has been used continuously since February and is working now 
 (currently listening to a .flac of "Changes" by 3 Doors Down).
 
 Jon

From: Jon Noack <noackjr@alumni.rice.edu>
To: freebsd-gnats-submit@FreeBSD.org, noackj@concordiacrusaders.org,
	julian@elischer.org
Cc:  
Subject: Re: kern/68594: [PATCH] enable S/PDIF output for es137x sound cards
Date: Sun, 22 Aug 2004 03:22:36 -0500

 This is a multi-part message in MIME format.
 --------------000909070301010200080501
 Content-Type: text/plain; charset=us-ascii; format=flowed
 Content-Transfer-Encoding: 7bit
 
 The updated patch attached adds some 4.x compatibility #ifdefs that I 
 forgot about.
 
 --------------000909070301010200080501
 Content-Type: text/plain;
  name="es137x.diff"
 Content-Transfer-Encoding: 7bit
 Content-Disposition: inline;
  filename="es137x.diff"
 
 Index: es137x.c
 ===================================================================
 RCS file: /home/ncvs/src/sys/dev/sound/pci/es137x.c,v
 retrieving revision 1.51
 diff -u -r1.51 es137x.c
 --- es137x.c	16 Jul 2004 03:59:27 -0000	1.51
 +++ es137x.c	22 Aug 2004 08:21:05 -0000
 @@ -831,6 +831,63 @@
  	}
  }
  
 +#ifdef SND_DYNSYSCTL
 +static int es1371x_spdif_en;
 +
 +static int
 +sysctl_es1371x_spdif_enable(SYSCTL_HANDLER_ARGS)
 +{
 +	struct es_info *es;
 +	device_t dev;
 +	int err, new_en, r;
 +
 +	new_en = es1371x_spdif_en;
 +	err = sysctl_handle_int(oidp, &new_en, sizeof(new_en), req);
 +	if (err || req->newptr == NULL)
 +		return err;
 +
 +	if (new_en < 0 || new_en > 1)
 +		return EINVAL;
 +	es1371x_spdif_en = new_en;
 +
 +	dev = oidp->oid_arg1;
 +	es = pcm_getdevinfo(dev);
 +	r = bus_space_read_4(es->st, es->sh, ES1370_REG_STATUS);
 +	if (new_en) {
 +		r |= ENABLE_SPDIF;
 +		es->ctrl |= SPDIFEN_B;
 +		es->ctrl |= RECEN_B;
 +	} else {
 +		r &= ~ENABLE_SPDIF;
 +		es->ctrl &= ~SPDIFEN_B;
 +		es->ctrl &= ~RECEN_B;
 +	}
 +	bus_space_write_4(es->st, es->sh, ES1370_REG_CONTROL, es->ctrl);
 +	bus_space_write_4(es->st, es->sh, ES1370_REG_STATUS, r);
 +	return 0;
 +}
 +#endif /* SND_DYNSYSCTL */
 +
 +static void
 +es_init_sysctls(device_t dev)
 +{
 +#ifdef SND_DYNSYSCTL
 +	struct es_info *es;
 +	int r;
 +
 +	es = pcm_getdevinfo(dev);
 +	r = bus_space_read_4(es->st, es->sh, ES1370_REG_STATUS);
 +	es1371x_spdif_en = (r & ENABLE_SPDIF) ? 1 : 0;
 +
 +	SYSCTL_ADD_PROC(snd_sysctl_tree(dev),
 +			SYSCTL_CHILDREN(snd_sysctl_tree_top(dev)),
 +			OID_AUTO, "spdif_enabled",
 +			CTLTYPE_INT | CTLFLAG_RW, dev, sizeof(dev),
 +			sysctl_es1371x_spdif_enable, "I",
 +			"Enable S/PDIF output on primary playback channel");
 +#endif /* SND_DYNSYSCTL */
 +}
 +
  static int
  es_pci_attach(device_t dev)
  {
 @@ -931,6 +988,9 @@
  	if (pcm_register(dev, es, 1, 1)) goto bad;
  	pcm_addchan(dev, PCMDIR_REC, ct, es);
  	pcm_addchan(dev, PCMDIR_PLAY, ct, es);
 +
 +	es_init_sysctls(dev);
 +
  	pcm_setstatus(dev, status);
  
  	return 0;
 Index: es137x.h
 ===================================================================
 RCS file: /home/ncvs/src/sys/dev/sound/pci/es137x.h,v
 retrieving revision 1.4
 diff -u -r1.4 es137x.h
 --- es137x.h	5 Apr 2000 00:38:00 -0000	1.4
 +++ es137x.h	25 May 2004 12:35:15 -0000
 @@ -167,6 +167,17 @@
  #define ES1371_SRC_RAM_DATAI(i) (((i)>>0)&0xffff)	/* current value of the sample rate converter */
  
  /*
 + * S/PDIF specific
 + */
 +
 +/* Use ES1370_REG_CONTROL */
 +#define RECEN_B			0x08000000	/* Used to control mixing of analog with digital data */
 +#define SPDIFEN_B		0x04000000	/* Reset to switch digital output mux to "THRU" mode */
 +/* Use ES1370_REG_STATUS */
 +#define ENABLE_SPDIF		0x00040000	/* Used to enable the S/PDIF circuitry */
 +#define TEST_SPDIF		0x00020000	/* Used to put the S/PDIF module in "test mode" */
 +
 +/*
   *  Sample rate converter addresses
   */
  
 
 --------------000909070301010200080501--
State-Changed-From-To: open->closed 
State-Changed-By: netchild 
State-Changed-When: Sun Jul 31 14:14:40 GMT 2005 
State-Changed-Why:  
Most recent version is committed now. Thanks! 

http://www.freebsd.org/cgi/query-pr.cgi?pr=59349 
State-Changed-From-To: open->closed 
State-Changed-By: netchild 
State-Changed-When: Sun Jul 31 14:14:40 GMT 2005 
State-Changed-Why:  
Most recent version is committed now. Thanks! 

http://www.freebsd.org/cgi/query-pr.cgi?pr=73498 
State-Changed-From-To: open->closed 
State-Changed-By: netchild 
State-Changed-When: Sun Jul 31 14:14:40 GMT 2005 
State-Changed-Why:  
Most recent version is committed now. Thanks! 

http://www.freebsd.org/cgi/query-pr.cgi?pr=68594 
>Unformatted:
