shithub: riscv

Download patch

ref: f9279fa422413a9570c49b766f41a2d2be1f7320
parent: 88fe1837f4e85028a0e1125677fd39d0257d77b1
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Thu Aug 18 18:58:16 EDT 2022

aux/wm8960: support 48kHz via "speed" verb

--- a/sys/src/cmd/aux/wm8960.c
+++ b/sys/src/cmd/aux/wm8960.c
@@ -35,6 +35,7 @@
 static char *uid = "audio";
 static int data;
 static int reg1a;
+static int rate = 44100;
 
 static void
 wr(int a, int v)
@@ -91,11 +92,14 @@
 	wr(o->volreg+1, 1<<8 | zc<<7 | r);
 }
 
-static void
-reset(void)
+static int
+setrate(int s)
 {
 	u32int k;
 
+	if(s != 44100 && s != 48000)
+		return -1;
+
 	/*
 	 * getting DAC ready for s16c2r44100:
 	 *
@@ -118,13 +122,8 @@
 	 *  → sysclk/768000 = 14
 	 *  → dclkdiv = /16 → dclk = 705.6kHz
 	 */
+	wr(0x1a, reg1a = reg1a & ~(1<<0)); /* disable pll */
 
-	toggle(out+Dac, 0);
-	wr(0x1c, 1<<7 | 1<<4 | 1<<3 | 1<<2); /* Vmid/r bias; Vgs/r on; Vmid soft start */
-	wr(0x19, 0<<7); /* Vmid off, Vref off */
-	sleep(500);
-	wr(0x0f, 0); /* reset registers to default */
-
 	wr(0x04,
 		0<<3 | /* dacdiv → sysclk/(1*256) = 44100 */
 		2<<1 | /* sysclkdiv → /2 */
@@ -137,15 +136,32 @@
 		7<<0 | /* N */
 		0
 	);
-	k = 3780645; /* K */
-	wr(0x35, (k>>16) & 0x3f);
+	k = s == 44100 ? 3780645 : 14500883; /* K */
+	wr(0x35, (k>>16) & 0xff);
 	wr(0x36, (k>>8) & 0xff);
 	wr(0x37, k & 0xff);
 
-	wr(0x07, 1<<6 | 2); /* master mode; i²s, 16-bit words, slave mode */
 	wr(0x08, 7<<6 | 7<<0); /* dclkdiv → sysclk/16; bclkdiv → sysclk/8 */
-
 	wr(0x1a, reg1a = reg1a | 1<<0); /* enable pll */
+
+	rate = s;
+
+	return 0;
+}
+
+static void
+reset(void)
+{
+	toggle(out+Dac, 0);
+	wr(0x1c, 1<<7 | 1<<4 | 1<<3 | 1<<2); /* Vmid/r bias; Vgs/r on; Vmid soft start */
+	wr(0x19, 0<<7); /* Vmid off, Vref off */
+	sleep(500);
+	wr(0x0f, 0); /* reset registers to default */
+
+	setrate(rate);
+
+	wr(0x07, 1<<6 | 2); /* master mode; i²s, 16-bit words */
+
 	wr(0x17, 1<<8 | 3<<6 | 1<<1); /* thermal shutdown on; avdd=3.3v; slow clock on */
 
 	wr(0x06, 1<<3 | 1<<2); /* ramp up DAC volume slowly */
@@ -193,7 +209,7 @@
 	}else if(r->fid->file->aux == (void*)Vol){
 		for(i = 0, o = out; i < Nout; i++, o++)
 			s = seprint(s, e, "%s %d %d\n", o->name, o->vol[0], o->vol[1]);
-		seprint(s, e, "speed 44100\n");
+		seprint(s, e, "speed %d\n", rate);
 	}
 
 	readstr(r, msg);
@@ -209,7 +225,8 @@
 
 	snprint(msg, sizeof(msg), "%.*s",
 		utfnlen((char*)r->ifcall.data, r->ifcall.count), (char*)r->ifcall.data);
-	if((nf = tokenize(msg, f, nelem(f))) < 2){
+	nf = tokenize(msg, f, nelem(f));
+	if(nf < 2){
 		if(nf == 1 && strcmp(f[0], "reset") == 0){
 			reset();
 			goto Done;
@@ -218,6 +235,14 @@
 		respond(r, "invalid ctl message");
 		return;
 	}
+	if(nf == 2 && strcmp(f[0], "speed") == 0){
+		if(setrate(atoi(f[1])) != 0){
+			respond(r, "not supported");
+			return;
+		}
+		goto Done;
+	}
+
 	for(i = 0, o = out; i < Nout && strcmp(f[0], o->name) != 0; i++, o++)
 		;
 	if(i >= Nout)