ref: f351c9fc472c247d1f46c27bd76ac6a8deccfd59
parent: 7c6dac30cba19b18fd82026a4a32ceb5f5f36ffa
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Wed Aug 17 23:06:22 EDT 2022
aux/wm8960: run as master and provide more precise clock; add oneshot mode (no fs)
--- a/sys/src/cmd/aux/wm8960.c
+++ b/sys/src/cmd/aux/wm8960.c
@@ -32,7 +32,8 @@
};
static char *uid = "audio";
-static int data, reg1a;
+static int data;
+static int reg1a = 1<<0; /* pll enable */
static void
wr(int a, int v)
@@ -39,7 +40,7 @@
{
u8int c;
- //fprint(2, "[0x%x] ← 0x%ux = ", a, v & 0x1ff);
+ //fprint(2, "[0x%x] ← 0x%ux\n", a, v & 0x1ff);
c = v & 0xff;
pwrite(data, &c, 1, a<<1 | ((v>>8)&1));
}
@@ -104,15 +105,32 @@
static void
reset(void)
{
+ u32int k;
Out *o;
int i;
wr(0x0f, 0); /* reset registers to default */
- wr(0x04, 0); /* sysclk (div 1) derived from mclk; dacdiv=sysclk/256 */
+ wr(0x04,
+ 1<<0 | /* sysclk derived from pll */
+ 2<<1 | /* sysclk div by 2 */
+ 1<<3 | /* dacdiv = sysclk/(1.5*256) */
+ 0
+ );
+ wr(0x34,
+ 1<<5 | /* enable fractional mode */
+ 1<<4 | /* pllprescale (divide mclk by 2 before) */
+ 10<<0 | /* plln = int(f1/f2) */
+ 0
+ );
+ k = 0x7654321; /* fractional part */
+ wr(0x35, k>>18);
+ wr(0x36, k>>9);
+ wr(0x37, k);
+
wr(0x05, 0<<3); /* unmute DAC */
wr(0x06, 1<<3 | 1<<2); /* ramp up DAC volume slowly */
- wr(0x07, 2); /* i²s, 16-bit words, slave mode */
- wr(0x08, 7<<6); /* class D divider: sysclk/16 */
+ wr(0x07, 1<<6 | 2); /* master mode; i²s, 16-bit words, slave mode */
+ wr(0x08, 5<<6 | 9<<0); /* class D divider: sysclk/8; bclk = sysclk/12 */
wr(0x19, 1<<7 | 1<<6); /* Vmid = playback, VREF on */
wr(0x22, 1<<8); /* L DAC to mixer */
wr(0x25, 1<<8); /* R DAC to mixer */
@@ -207,7 +225,7 @@
static void
usage(void)
{
- fprint(2, "usage: aux/wm8960\n");
+ fprint(2, "usage: aux/wm8960 [-1] [-D] [-m /mnt/pm] [-s service]\n");
exits("usage");
}
@@ -215,11 +233,15 @@
main(int argc, char **argv)
{
char *mtpt, *srv;
- int ctl;
+ int ctl, oneshot;
mtpt = "/mnt/wm8960";
srv = nil;
+ oneshot = 0;
ARGBEGIN{
+ case '1':
+ oneshot = 1;
+ break;
case 'D':
chatty9p = 1;
break;
@@ -242,6 +264,9 @@
close(ctl);
reset();
+
+ if(oneshot)
+ exits(nil);
fs.tree = alloctree(uid, uid, DMDIR|0555, nil);
createfile(fs.tree->root, "audioctl", uid, 0666, (void*)Ctl);