All of lore.kernel.org
 help / color / mirror / Atom feed
From: klem.dev@gmail.com
To: patch@alsa-project.org
Cc: "Clément Guedez" <klem.dev@gmail.com>, alsa-devel@alsa-project.org
Subject: [PATCH 6/6] ESI W192M : Add sampling rate control of the ADC/DAC
Date: Wed, 18 Mar 2015 02:26:31 +0100	[thread overview]
Message-ID: <5508d462.4160b40a.64fa.44ee@mx.google.com> (raw)
In-Reply-To: <1426641991-3694-1-git-send-email-me>

From: Clément Guedez <klem.dev@gmail.com>

Add sampling rate control for ADC/DAC for ESI W192M.
Allow to switch between 48K/96K/192K sampling rate.
All DAC need to be mute when changing samplerate.

Signed-off-by: Clément Guedez <klem.dev@gmail.com>

diff --git a/sound/pci/ice1712/wtm.c b/sound/pci/ice1712/wtm.c
index 6d3412f..9906119 100644
--- a/sound/pci/ice1712/wtm.c
+++ b/sound/pci/ice1712/wtm.c
@@ -30,12 +30,18 @@
 #include <linux/init.h>
 #include <sound/core.h>
 #include <sound/tlv.h>
+#include <linux/slab.h>
 
 #include "ice1712.h"
 #include "envy24ht.h"
 #include "wtm.h"
 #include "stac946x.h"
 
+struct wtm_spec {
+	/* rate change needs atomic mute/unmute of all dacs*/
+	struct mutex mute_mutex;
+};
+
 
 /*
  *	2*ADC 6*DAC no1 ringbuffer r/w on i2c bus
@@ -69,15 +75,65 @@ static inline unsigned char stac9460_2_get(struct snd_ice1712 *ice, int reg)
 /*
  *	DAC mute control
  */
+static void stac9460_dac_mute_all(struct snd_ice1712 *ice, unsigned char mute,
+				unsigned short int *change_mask)
+{
+	unsigned char new, old;
+	int id, idx, change;
+
+	/*stac9460 1*/
+	for (id = 0; id < 7; id++) {
+		if (*change_mask & (0x01 << id)) {
+			if (id == 0)
+				idx = STAC946X_MASTER_VOLUME;
+			else
+				idx = STAC946X_LF_VOLUME - 1 + id;
+			old = stac9460_get(ice, idx);
+			new = (~mute << 7 & 0x80) | (old & ~0x80);
+			change = (new != old);
+			if (change) {
+				stac9460_put(ice, idx, new);
+				*change_mask = *change_mask | (0x01 << id);
+			} else {
+				*change_mask = *change_mask & ~(0x01 << id);
+			}
+		}
+	}
+
+	/*stac9460 2*/
+	for (id = 0; id < 3; id++) {
+		if (*change_mask & (0x01 << (id + 7))) {
+			if (id == 0)
+				idx = STAC946X_MASTER_VOLUME;
+			else
+				idx = STAC946X_LF_VOLUME - 1 + id;
+			old = stac9460_2_get(ice, idx);
+			new = (~mute << 7 & 0x80) | (old & ~0x80);
+			change = (new != old);
+			if (change) {
+				stac9460_2_put(ice, idx, new);
+				*change_mask = *change_mask | (0x01 << id);
+			} else {
+				*change_mask = *change_mask & ~(0x01 << id);
+			}
+		}
+	}
+}
+
+
+
 #define stac9460_dac_mute_info		snd_ctl_boolean_mono_info
 
 static int stac9460_dac_mute_get(struct snd_kcontrol *kcontrol,
 				struct snd_ctl_elem_value *ucontrol)
 {
 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
+	struct wtm_spec *spec = ice->spec;
 	unsigned char val;
 	int idx, id;
 
+	mutex_lock(&spec->mute_mutex);
+
 	if (kcontrol->private_value) {
 		idx = STAC946X_MASTER_VOLUME;
 		id = 0;
@@ -90,6 +146,8 @@ static int stac9460_dac_mute_get(struct snd_kcontrol *kcontrol,
 	else
 		val = stac9460_2_get(ice, idx - 6);
 	ucontrol->value.integer.value[0] = (~val >> 7) & 0x1;
+
+	mutex_unlock(&spec->mute_mutex);
 	return 0;
 }
 
@@ -388,6 +446,44 @@ static int stac9460_mic_sw_put(struct snd_kcontrol *kcontrol,
 }
 
 
+/*
+ * Handler for setting correct codec rate - called when rate change is detected
+ */
+static void stac9460_set_rate_val(struct snd_ice1712 *ice, unsigned int rate)
+{
+	unsigned char old, new;
+	unsigned short int changed;
+	struct wtm_spec *spec = ice->spec;
+
+	if (rate == 0)  /* no hint - S/PDIF input is master, simply return */
+		return;
+	else if (rate <= 48000)
+		new = 0x08;     /* 256x, base rate mode */
+	else if (rate <= 96000)
+		new = 0x11;     /* 256x, mid rate mode */
+	else
+		new = 0x12;     /* 128x, high rate mode */
+
+	old = stac9460_get(ice, STAC946X_MASTER_CLOCKING);
+	if (old == new)
+		return;
+	/* change detected, setting master clock, muting first */
+	/* due to possible conflicts with mute controls - mutexing */
+	mutex_lock(&spec->mute_mutex);
+	/* we have to remember current mute status for each DAC */
+	changed = 0xFFFF;
+	stac9460_dac_mute_all(ice, 0, &changed);
+	/*printk(KERN_DEBUG "Rate change: %d, new MC: 0x%02x\n", rate, new);*/
+	stac9460_put(ice, STAC946X_MASTER_CLOCKING, new);
+	stac9460_2_put(ice, STAC946X_MASTER_CLOCKING, new);
+	udelay(10);
+	/* unmuting - only originally unmuted dacs -
+	* i.e. those changed when muting */
+	stac9460_dac_mute_all(ice, 1, &changed);
+	mutex_unlock(&spec->mute_mutex);
+}
+
+
 /*Limits value in dB for fader*/
 static const DECLARE_TLV_DB_SCALE(db_scale_dac, -19125, 75, 0);
 static const DECLARE_TLV_DB_SCALE(db_scale_adc, 0, 150, 0);
@@ -487,21 +583,32 @@ static int wtm_init(struct snd_ice1712 *ice)
 {
 	static unsigned short stac_inits_wtm[] = {
 		STAC946X_RESET, 0,
+		STAC946X_MASTER_CLOCKING, 0x11,
 		(unsigned short)-1
 	};
 	unsigned short *p;
+	struct wtm_spec *spec;
 
 	/*WTM 192M*/
 	ice->num_total_dacs = 8;
 	ice->num_total_adcs = 4;
 	ice->force_rdma1 = 1;
 
+	/*init mutex for dac mute conflict*/
+	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
+	if (!spec)
+		return -ENOMEM;
+	ice->spec = spec;
+	mutex_init(&spec->mute_mutex);
+
+
 	/*initialize codec*/
 	p = stac_inits_wtm;
 	for (; *p != (unsigned short)-1; p += 2) {
 		stac9460_put(ice, p[0], p[1]);
 		stac9460_2_put(ice, p[0], p[1]);
 	}
+	ice->gpio.set_pro_rate = stac9460_set_rate_val;
 	return 0;
 }
 
-- 
2.1.4

_______________________________________________
Alsa-devel mailing list
Alsa-devel@alsa-project.org
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

  parent reply	other threads:[~2015-03-18  1:26 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <1426641991-3694-1-git-send-email-me>
2015-03-18  1:26 ` [PATCH 2/6] ESI W192M : Update eeprom structure to C99 standard klem.dev
2015-03-18  1:26 ` [PATCH 3/6] ESI W192M : Enable midi i/o of port envy24 chip as available klem.dev
2015-03-18  1:26 ` [PATCH 4/6] ESI W192M : Add TLV support for control value in dB scale klem.dev
2015-03-18  1:26 ` [PATCH 5/6] ESI W192M : Add text Line in/Mic for selecting input gain state klem.dev
2015-03-18  1:26 ` klem.dev [this message]
     [not found] <1426465255-19005-1-git-send-email-me>
2015-03-16  0:20 ` [PATCH 6/6] ESI W192M : Add sampling rate control of the ADC/DAC klem.dev
2015-03-14  4:04 klem.dev
     [not found] <1426300302-20542-1-git-send-email-me>
2015-03-14  2:31 ` klem.dev
2015-03-14  4:02   ` Clément Guedez

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5508d462.4160b40a.64fa.44ee@mx.google.com \
    --to=klem.dev@gmail.com \
    --cc=alsa-devel@alsa-project.org \
    --cc=patch@alsa-project.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.