From owner-freebsd-multimedia@FreeBSD.ORG Sun Feb 8 04:00:30 2004 Return-Path: Delivered-To: freebsd-multimedia@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 1434416A4CF for ; Sun, 8 Feb 2004 04:00:28 -0800 (PST) Received: from cmsrelay01.mx.net (cmsrelay01.mx.net [165.212.11.110]) by mx1.FreeBSD.org (Postfix) with SMTP id 81CE143D1D for ; Sun, 8 Feb 2004 04:00:28 -0800 (PST) (envelope-from noackjr@alumni.rice.edu) Received: from uadvg130.cms.usa.net (165.212.11.130) by cmsoutbound.mx.net with SMTP; 8 Feb 2004 12:00:27 -0000 Received: from optimator.noacks.org [65.71.32.141] by uadvg130.cms.usa.net (ASMTP/noackjr@usa.net) via mtad (C8.MAIN.3.13N) with ESMTP id 300iBHmaZ0243M30; Sun, 08 Feb 2004 12:00:25 GMT X-USANET-Auth: 65.71.32.141 AUTH noackjr@usa.net optimator.noacks.org Received: from localhost (localhost [127.0.0.1]) by optimator.noacks.org (Postfix) with ESMTP id 71C1B60ED; Sun, 8 Feb 2004 06:00:24 -0600 (CST) 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 09573-04; Sun, 8 Feb 2004 06:00:23 -0600 (CST) Received: from alumni.rice.edu (compgeek [192.168.1.10]) by optimator.noacks.org (Postfix) with ESMTP id 4326E60E7; Sun, 8 Feb 2004 06:00:23 -0600 (CST) Message-ID: <402624D7.4060009@alumni.rice.edu> Date: Sun, 08 Feb 2004 06:00:23 -0600 From: Jon Noack User-Agent: Mozilla/5.0 (X11; U; FreeBSD i386; en-US; rv:1.6b) Gecko/20040204 Thunderbird/0.4 X-Accept-Language: en-us, en MIME-Version: 1.0 To: freebsd-multimedia@freebsd.org Content-Type: multipart/mixed; boundary="------------020505060907040208040104" X-Virus-Scanned: by amavisd-new at noacks.org Subject: [PATCH] es137x s/pdif output X-BeenThere: freebsd-multimedia@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list Reply-To: noackjr@alumni.rice.edu List-Id: Multimedia discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 08 Feb 2004 12:00:30 -0000 This is a multi-part message in MIME format. --------------020505060907040208040104 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit The discussion last month about 4-channel output prompted me to get off my butt and enable S/PDIF output on the CT5880-E. I found this white paper (http://www.corbac.com/Data/Misc/es1373.ps.gz) to be invaluable. I also need to credit the sysctl stuff from /sys/dev/sound/pci/via8233.c as most of my patch was taken verbatim from there. Setting hw.snd.pcmX.spdif_enabled=1: 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) Setting it back to 0 just reverts these 3 steps. Several things: 1) This is currently only enabled for the CT5880-E. Other es137x-based cards support S/PDIF and this should be enabled for them also -- I just didn't know which ones. 2) It's probably not necessary to toggle SPDIF_OUT/SPDIF_THRU every time. 3) Enabling this causes a degradation in the sound coming over the analog outputs. I don't see anything to help clean this up. Perhaps we should just mute these (how would one do this?). 4) Master volume control has no effect (although individual pcm stream volume is properly handled). 5) I have no idea if my coding style or the functions used were correct. A review by someone in the know would be much appreciated. I've been using this for over an hour with several toggles of the spdif_enabled sysctl; S/PDIF output was correctly enabled and disabled each time. It sounds *sooo* much better over my surround system :). I feel rather silly for having bought the 4Front drivers a couple years ago because the FreeBSD driver lacked this very functionality -- such a simple change... Jon Noack --------------020505060907040208040104 Content-Type: text/plain; name="es137x.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="es137x.diff" diff -ruN es137x.c.orig es137x.c --- es137x.c.orig Sun Feb 8 04:23:36 2004 +++ es137x.c Sun Feb 8 04:56:25 2004 @@ -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,11 @@ if (pcm_register(dev, es, 1, 1)) goto bad; pcm_addchan(dev, PCMDIR_REC, ct, es); pcm_addchan(dev, PCMDIR_PLAY, ct, es); + + /* Only initialize for the CT5880-E */ + if (pci_get_devid(dev) == CT5880_PCI_ID || pci_get_revid(dev) == CT5880REV_CT5880_E) + es_init_sysctls(dev); + pcm_setstatus(dev, status); return 0; diff -ruN es137x.h.orig es137x.h --- es137x.h.orig Sun Feb 8 04:23:40 2004 +++ es137x.h Sun Feb 8 04:50:19 2004 @@ -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 */ --------------020505060907040208040104--