All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH 0/4] snd-ice1712: Add Philips PSC724 Ultimate Edge
@ 2012-04-16 21:18 Ondrej Zary
  2012-04-16 21:18 ` [PATCH 1/4] snd-ice1712: add chip_exit callback Ondrej Zary
                   ` (3 more replies)
  0 siblings, 4 replies; 37+ messages in thread
From: Ondrej Zary @ 2012-04-16 21:18 UTC (permalink / raw)
  To: alsa-devel; +Cc: linux-kernel

Hello,
this is first attempt to add Philips PSC724 Ultimate Edge sound card
support to snd-ice1712 driver. Unlike other snd-ice1712 subdrivers, the codec
code is splitted into separate modules and thus reusable.

Working: all analog outputs (front, rear, center+lfe, headphone) and inputs
(front mic, rear mic, line, cd, aux), mixer, headphone jack detection

Currently untested: SPDIF, real multichannel sounds, power management

Buggy: switching AGC mode in mixer causes alsamixer to crash - looks like
it does not like notifications about control activating/deactivating



^ permalink raw reply	[flat|nested] 37+ messages in thread

* [PATCH 1/4] snd-ice1712: add chip_exit callback
  2012-04-16 21:18 [RFC PATCH 0/4] snd-ice1712: Add Philips PSC724 Ultimate Edge Ondrej Zary
@ 2012-04-16 21:18 ` Ondrej Zary
  2012-04-16 21:18 ` [PATCH 2/4] Add Wolfson Microelectronics WM8766 codec ALSA driver Ondrej Zary
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 37+ messages in thread
From: Ondrej Zary @ 2012-04-16 21:18 UTC (permalink / raw)
  To: alsa-devel; +Cc: linux-kernel

Add chip_exit callback to allow card subdrivers to do cleanup work on module
removal.

Needed by Philips PSC724 subdriver to cancel delayed work.

Signed-off-by: Ondrej Zary <linux@rainbow-software.org>
---
 sound/pci/ice1712/ice1712.c |    8 +++++++-
 sound/pci/ice1712/ice1712.h |    3 +++
 sound/pci/ice1712/ice1724.c |    8 +++++++-
 3 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c
index 132a86e..e153bdb 100644
--- a/sound/pci/ice1712/ice1712.c
+++ b/sound/pci/ice1712/ice1712.c
@@ -2686,6 +2686,7 @@ static int __devinit snd_ice1712_probe(struct pci_dev *pci,
 	for (tbl = card_tables; *tbl; tbl++) {
 		for (c = *tbl; c->subvendor; c++) {
 			if (c->subvendor == ice->eeprom.subvendor) {
+				ice->card_info = c;
 				strcpy(card->shortname, c->name);
 				if (c->driver) /* specific driver? */
 					strcpy(card->driver, c->driver);
@@ -2799,7 +2800,12 @@ static int __devinit snd_ice1712_probe(struct pci_dev *pci,
 
 static void __devexit snd_ice1712_remove(struct pci_dev *pci)
 {
-	snd_card_free(pci_get_drvdata(pci));
+	struct snd_card *card = pci_get_drvdata(pci);
+	struct snd_ice1712 *ice = card->private_data;
+
+	if (ice->card_info && ice->card_info->chip_exit)
+		ice->card_info->chip_exit(ice);
+	snd_card_free(card);
 	pci_set_drvdata(pci, NULL);
 }
 
diff --git a/sound/pci/ice1712/ice1712.h b/sound/pci/ice1712/ice1712.h
index 0da778a..79f8aeb 100644
--- a/sound/pci/ice1712/ice1712.h
+++ b/sound/pci/ice1712/ice1712.h
@@ -288,6 +288,7 @@ struct snd_ice1712_spdif {
 	} ops;
 };
 
+struct snd_ice1712_card_info;
 
 struct snd_ice1712 {
 	unsigned long conp_dma_size;
@@ -324,6 +325,7 @@ struct snd_ice1712 {
 	struct snd_info_entry *proc_entry;
 
 	struct snd_ice1712_eeprom eeprom;
+	struct snd_ice1712_card_info *card_info;
 
 	unsigned int pro_volumes[20];
 	unsigned int omni:1;		/* Delta Omni I/O */
@@ -517,6 +519,7 @@ struct snd_ice1712_card_info {
 	char *model;
 	char *driver;
 	int (*chip_init)(struct snd_ice1712 *);
+	void (*chip_exit)(struct snd_ice1712 *);
 	int (*build_controls)(struct snd_ice1712 *);
 	unsigned int no_mpu401:1;
 	unsigned int mpu401_1_info_flags;
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c
index 9236297..ea686c4 100644
--- a/sound/pci/ice1712/ice1724.c
+++ b/sound/pci/ice1712/ice1724.c
@@ -2325,6 +2325,7 @@ static int __devinit snd_vt1724_read_eeprom(struct snd_ice1712 *ice,
 				ice->eeprom.subvendor = c->subvendor;
 			} else if (c->subvendor != ice->eeprom.subvendor)
 				continue;
+			ice->card_info = c;
 			if (!c->eeprom_size || !c->eeprom_data)
 				goto found;
 			/* if the EEPROM is given by the driver, use it */
@@ -2765,7 +2766,12 @@ __found:
 
 static void __devexit snd_vt1724_remove(struct pci_dev *pci)
 {
-	snd_card_free(pci_get_drvdata(pci));
+	struct snd_card *card = pci_get_drvdata(pci);
+	struct snd_ice1712 *ice = card->private_data;
+
+	if (ice->card_info && ice->card_info->chip_exit)
+		ice->card_info->chip_exit(ice);
+	snd_card_free(card);
 	pci_set_drvdata(pci, NULL);
 }
 
-- 
Ondrej Zary


^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH 2/4] Add Wolfson Microelectronics WM8766 codec ALSA driver
  2012-04-16 21:18 [RFC PATCH 0/4] snd-ice1712: Add Philips PSC724 Ultimate Edge Ondrej Zary
  2012-04-16 21:18 ` [PATCH 1/4] snd-ice1712: add chip_exit callback Ondrej Zary
@ 2012-04-16 21:18 ` Ondrej Zary
  2012-04-17 14:59   ` Mark Brown
  2012-04-16 21:18 ` [PATCH 3/4] Add Wolfson Microelectronics WM8776 " Ondrej Zary
  2012-04-16 21:18 ` [PATCH 4/4] snd-ice1712: Add Philips PSC724 Ultimate Edge Ondrej Zary
  3 siblings, 1 reply; 37+ messages in thread
From: Ondrej Zary @ 2012-04-16 21:18 UTC (permalink / raw)
  To: alsa-devel; +Cc: linux-kernel

Needed by Philips PSC724 subdriver. The code does not contain any
card-specific bits so it can be used by any other ALSA driver.

Signed-off-by: Ondrej Zary <linux@rainbow-software.org>
---
 include/sound/wm8766.h   |  160 ++++++++++++++++++++
 sound/i2c/other/Makefile |    3 +-
 sound/i2c/other/wm8766.c |  374 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 536 insertions(+), 1 deletions(-)
 create mode 100644 include/sound/wm8766.h
 create mode 100644 sound/i2c/other/wm8766.c

diff --git a/include/sound/wm8766.h b/include/sound/wm8766.h
new file mode 100644
index 0000000..7d1df7f
--- /dev/null
+++ b/include/sound/wm8766.h
@@ -0,0 +1,160 @@
+#ifndef __SOUND_WM8766_H
+#define __SOUND_WM8766_H
+
+/*
+ *   ALSA driver for WM8766 codecs
+ *
+ *	Copyright (c) 2012 Ondrej Zary <linux@rainbow-software.org>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ */
+
+#define WM8766_REG_DACL1	0x00
+#define WM8766_REG_DACR1	0x01
+#define WM8766_VOL_MASK			0x1ff		/* incl. update bit */
+#define WM8766_VOL_UPDATE		(1 << 8)	/* update volume */
+#define WM8766_REG_DACCTRL1	0x02
+#define WM8766_DAC_MUTEALL		(1 << 0)
+#define WM8766_DAC_DEEMPALL		(1 << 1)
+#define WM8766_DAC_PDWN			(1 << 2)
+#define WM8766_DAC_ATC			(1 << 3)
+#define WM8766_DAC_IZD			(1 << 4)
+#define WM8766_DAC_PL_MASK		0x1e0
+#define WM8766_DAC_PL_LL		(1 << 5)	/* L chan: L signal */
+#define WM8766_DAC_PL_LR		(2 << 5)	/* L chan: R signal */
+#define WM8766_DAC_PL_LB		(3 << 5)	/* L chan: both */
+#define WM8766_DAC_PL_RL		(1 << 7)	/* R chan: L signal */
+#define WM8766_DAC_PL_RR		(2 << 7)	/* R chan: R signal */
+#define WM8766_DAC_PL_RB		(3 << 7)	/* R chan: both */
+#define WM8766_REG_IFCTRL	0x03
+#define WM8766_IF_FMT_RIGHTJ		(0 << 0)
+#define WM8766_IF_FMT_LEFTJ		(1 << 0)
+#define WM8766_IF_FMT_I2S		(2 << 0)
+#define WM8766_IF_FMT_DSP		(3 << 0)
+#define WM8766_IF_DSP_LATE		(1 << 2)	/* in DSP mode */
+#define WM8766_IF_LRC_INVERTED		(1 << 2)	/* in other modes */
+#define WM8766_IF_BCLK_INVERTED		(1 << 3)
+#define WM8766_IF_IWL_16BIT		(0 << 4)
+#define WM8766_IF_IWL_20BIT		(1 << 4)
+#define WM8766_IF_IWL_24BIT		(2 << 4)
+#define WM8766_IF_IWL_32BIT		(3 << 4)
+#define WM8766_IF_MASK			0x3f
+#define WM8766_PHASE_INVERT1		(1 << 6)
+#define WM8766_PHASE_INVERT2		(1 << 7)
+#define WM8766_PHASE_INVERT3		(1 << 8)
+#define WM8766_REG_DACL2	0x04
+#define WM8766_REG_DACR2	0x05
+#define WM8766_REG_DACL3	0x06
+#define WM8766_REG_DACR3	0x07
+#define WM8766_REG_MASTDA	0x08
+#define WM8766_REG_DACCTRL2	0x09
+#define WM8766_DAC2_ZCD			(1 << 0)
+#define WM8766_DAC2_ZFLAG_ALL		(0 << 1)
+#define WM8766_DAC2_ZFLAG_1		(1 << 1)
+#define WM8766_DAC2_ZFLAG_2		(2 << 1)
+#define WM8766_DAC2_ZFLAG_3		(3 << 1)
+#define WM8766_DAC2_MUTE1		(1 << 3)
+#define WM8766_DAC2_MUTE2		(1 << 4)
+#define WM8766_DAC2_MUTE3		(1 << 5)
+#define WM8766_DAC2_DEEMP1		(1 << 6)
+#define WM8766_DAC2_DEEMP2		(1 << 7)
+#define WM8766_DAC2_DEEMP3		(1 << 8)
+#define WM8766_REG_DACCTRL3	0x0a
+#define WM8766_DAC3_DACPD1		(1 << 1)
+#define WM8766_DAC3_DACPD2		(1 << 2)
+#define WM8766_DAC3_DACPD3		(1 << 3)
+#define WM8766_DAC3_PWRDNALL		(1 << 4)
+#define WM8766_DAC3_POWER_MASK		0x1e
+#define WM8766_DAC3_MASTER		(1 << 5)
+#define WM8766_DAC3_DAC128FS		(0 << 6)
+#define WM8766_DAC3_DAC192FS		(1 << 6)
+#define WM8766_DAC3_DAC256FS		(2 << 6)
+#define WM8766_DAC3_DAC384FS		(3 << 6)
+#define WM8766_DAC3_DAC512FS		(4 << 6)
+#define WM8766_DAC3_DAC768FS		(5 << 6)
+#define WM8766_DAC3_MSTR_MASK		0x1e0
+#define WM8766_REG_MUTE1	0x0c
+#define WM8766_MUTE1_MPD		(1 << 6)
+#define WM8766_REG_MUTE2	0x0f
+#define WM8766_MUTE2_MPD		(1 << 5)
+#define WM8766_REG_RESET	0x1f
+
+#define WM8766_REG_COUNT	0x10	/* don't cache the RESET register */
+
+struct snd_wm8766;
+
+struct snd_wm8766_ops {
+	void (*write)(struct snd_wm8766 *wm, u16 addr, u16 data);
+};
+
+enum snd_wm8766_ctl_id {
+	WM8766_CTL_CH1_VOL,
+	WM8766_CTL_CH2_VOL,
+	WM8766_CTL_CH3_VOL,
+	WM8766_CTL_CH1_SW,
+	WM8766_CTL_CH2_SW,
+	WM8766_CTL_CH3_SW,
+	WM8766_CTL_PHASE1_SW,
+	WM8766_CTL_PHASE2_SW,
+	WM8766_CTL_PHASE3_SW,
+	WM8766_CTL_DEEMPH1_SW,
+	WM8766_CTL_DEEMPH2_SW,
+	WM8766_CTL_DEEMPH3_SW,
+	WM8766_CTL_IZD_SW,
+	WM8766_CTL_ZC_SW,
+
+	WM8766_CTL_COUNT,
+};
+
+#define WM8766_ENUM_MAX		16
+
+#define WM8766_FLAG_STEREO	(1 << 0)
+#define WM8766_FLAG_VOL_UPDATE	(1 << 1)
+#define WM8766_FLAG_INVERT	(1 << 2)
+#define WM8766_FLAG_LIM		(1 << 3)
+#define WM8766_FLAG_ALC		(1 << 4)
+
+struct snd_wm8766_ctl {
+	struct snd_kcontrol *kctl;
+	char *name;
+	snd_ctl_elem_type_t type;
+	const char *const enum_names[WM8766_ENUM_MAX];
+	const unsigned int *tlv;
+	u16 reg1, reg2, mask1, mask2, min, max, flags;
+	void (*set)(struct snd_wm8766 *wm, u16 ch1, u16 ch2);
+	void (*get)(struct snd_wm8766 *wm, u16 *ch1, u16 *ch2);
+};
+
+enum snd_wm8766_agc_mode { WM8766_AGC_OFF, WM8766_AGC_LIM, WM8766_AGC_ALC };
+
+struct snd_wm8766 {
+	struct snd_card *card;
+	struct snd_wm8766_ctl ctl[WM8766_CTL_COUNT];
+	enum snd_wm8766_agc_mode agc_mode;
+	struct snd_wm8766_ops ops;
+	u16 regs[WM8766_REG_COUNT];	/* 9-bit registers */
+};
+
+
+
+void snd_wm8766_init(struct snd_wm8766 *wm);
+void snd_wm8766_set_if(struct snd_wm8766 *wm, u16 dac);
+void snd_wm8766_set_master_mode(struct snd_wm8766 *wm, u16 mode);
+void snd_wm8766_set_power(struct snd_wm8766 *wm, u16 power);
+void snd_wm8766_volume_restore(struct snd_wm8766 *wm);
+int snd_wm8766_build_controls(struct snd_wm8766 *wm);
+
+#endif /* __SOUND_WM8766_H */
diff --git a/sound/i2c/other/Makefile b/sound/i2c/other/Makefile
index c95d8f1..93406f7 100644
--- a/sound/i2c/other/Makefile
+++ b/sound/i2c/other/Makefile
@@ -9,9 +9,10 @@ snd-ak4113-objs := ak4113.o
 snd-ak4xxx-adda-objs := ak4xxx-adda.o
 snd-pt2258-objs := pt2258.o
 snd-tea575x-tuner-objs := tea575x-tuner.o
+snd-wm8766-objs := wm8766.o
 
 # Module Dependency
 obj-$(CONFIG_SND_PDAUDIOCF) += snd-ak4117.o
 obj-$(CONFIG_SND_ICE1712) += snd-ak4xxx-adda.o
-obj-$(CONFIG_SND_ICE1724) += snd-ak4114.o snd-ak4113.o snd-ak4xxx-adda.o snd-pt2258.o
+obj-$(CONFIG_SND_ICE1724) += snd-ak4114.o snd-ak4113.o snd-ak4xxx-adda.o snd-pt2258.o snd-wm8766.o
 obj-$(CONFIG_SND_TEA575X) += snd-tea575x-tuner.o
diff --git a/sound/i2c/other/wm8766.c b/sound/i2c/other/wm8766.c
new file mode 100644
index 0000000..deed3a3
--- /dev/null
+++ b/sound/i2c/other/wm8766.c
@@ -0,0 +1,374 @@
+/*
+ *   ALSA driver for WM8766 codecs
+ *
+ *	Copyright (c) 2012 Ondrej Zary <linux@rainbow-software.org>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <sound/control.h>
+#include <sound/tlv.h>
+#include <sound/wm8766.h>
+
+MODULE_AUTHOR("Ondrej Zary <linux@rainbow-software.org>");
+MODULE_DESCRIPTION("Routines for control of WM8766 codecs");
+MODULE_LICENSE("GPL");
+
+/* low-level access */
+
+void snd_wm8766_write(struct snd_wm8766 *wm, u16 addr, u16 data)
+{
+	if (addr < WM8766_REG_RESET)
+		wm->regs[addr] = data;
+	wm->ops.write(wm, addr, data);
+}
+
+/* mixer controls */
+
+static const DECLARE_TLV_DB_SCALE(wm8766_tlv, -12750, 50, 1);
+
+static struct snd_wm8766_ctl default_ctl[WM8766_CTL_COUNT] = {
+	[WM8766_CTL_CH1_VOL] = {
+		.name = "Channel 1 Playback Volume",
+		.type = SNDRV_CTL_ELEM_TYPE_INTEGER,
+		.tlv = wm8766_tlv,
+		.reg1 = WM8766_REG_DACL1,
+		.reg2 = WM8766_REG_DACR1,
+		.mask1 = WM8766_VOL_MASK,
+		.mask2 = WM8766_VOL_MASK,
+		.max = 0xff,
+		.flags = WM8766_FLAG_STEREO | WM8766_FLAG_VOL_UPDATE,
+	},
+	[WM8766_CTL_CH2_VOL] = {
+		.name = "Channel 2 Playback Volume",
+		.type = SNDRV_CTL_ELEM_TYPE_INTEGER,
+		.tlv = wm8766_tlv,
+		.reg1 = WM8766_REG_DACL2,
+		.reg2 = WM8766_REG_DACR2,
+		.mask1 = WM8766_VOL_MASK,
+		.mask2 = WM8766_VOL_MASK,
+		.max = 0xff,
+		.flags = WM8766_FLAG_STEREO | WM8766_FLAG_VOL_UPDATE,
+	},
+	[WM8766_CTL_CH3_VOL] = {
+		.name = "Channel 3 Playback Volume",
+		.type = SNDRV_CTL_ELEM_TYPE_INTEGER,
+		.tlv = wm8766_tlv,
+		.reg1 = WM8766_REG_DACL3,
+		.reg2 = WM8766_REG_DACR3,
+		.mask1 = WM8766_VOL_MASK,
+		.mask2 = WM8766_VOL_MASK,
+		.max = 0xff,
+		.flags = WM8766_FLAG_STEREO | WM8766_FLAG_VOL_UPDATE,
+	},
+	[WM8766_CTL_CH1_SW] = {
+		.name = "Channel 1 Playback Switch",
+		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN,
+		.reg1 = WM8766_REG_DACCTRL2,
+		.mask1 = WM8766_DAC2_MUTE1,
+		.flags = WM8766_FLAG_INVERT,
+	},
+	[WM8766_CTL_CH2_SW] = {
+		.name = "Channel 2 Playback Switch",
+		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN,
+		.reg1 = WM8766_REG_DACCTRL2,
+		.mask1 = WM8766_DAC2_MUTE2,
+		.flags = WM8766_FLAG_INVERT,
+	},
+	[WM8766_CTL_CH3_SW] = {
+		.name = "Channel 3 Playback Switch",
+		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN,
+		.reg1 = WM8766_REG_DACCTRL2,
+		.mask1 = WM8766_DAC2_MUTE3,
+		.flags = WM8766_FLAG_INVERT,
+	},
+	[WM8766_CTL_PHASE1_SW] = {
+		.name = "Channel 1 Phase Invert Playback Switch",
+		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN,
+		.reg1 = WM8766_REG_IFCTRL,
+		.mask1 = WM8766_PHASE_INVERT1,
+	},
+	[WM8766_CTL_PHASE2_SW] = {
+		.name = "Channel 2 Phase Invert Playback Switch",
+		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN,
+		.reg1 = WM8766_REG_IFCTRL,
+		.mask1 = WM8766_PHASE_INVERT2,
+	},
+	[WM8766_CTL_PHASE3_SW] = {
+		.name = "Channel 3 Phase Invert Playback Switch",
+		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN,
+		.reg1 = WM8766_REG_IFCTRL,
+		.mask1 = WM8766_PHASE_INVERT3,
+	},
+	[WM8766_CTL_DEEMPH1_SW] = {
+		.name = "Channel 1 Deemphasis Playback Switch",
+		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN,
+		.reg1 = WM8766_REG_DACCTRL2,
+		.mask1 = WM8766_DAC2_DEEMP1,
+	},
+	[WM8766_CTL_DEEMPH2_SW] = {
+		.name = "Channel 2 Deemphasis Playback Switch",
+		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN,
+		.reg1 = WM8766_REG_DACCTRL2,
+		.mask1 = WM8766_DAC2_DEEMP2,
+	},
+	[WM8766_CTL_DEEMPH3_SW] = {
+		.name = "Channel 3 Deemphasis Playback Switch",
+		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN,
+		.reg1 = WM8766_REG_DACCTRL2,
+		.mask1 = WM8766_DAC2_DEEMP3,
+	},
+	[WM8766_CTL_IZD_SW] = {
+		.name = "Infinite Zero Detect Playback Switch",
+		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN,
+		.reg1 = WM8766_REG_DACCTRL1,
+		.mask1 = WM8766_DAC_IZD,
+	},
+	[WM8766_CTL_ZC_SW] = {
+		.name = "Zero Cross Detect Playback Switch",
+		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN,
+		.reg1 = WM8766_REG_DACCTRL2,
+		.mask1 = WM8766_DAC2_ZCD,
+		.flags = WM8766_FLAG_INVERT,
+	},
+};
+
+/* exported functions */
+
+void snd_wm8766_init(struct snd_wm8766 *wm)
+{
+	int i;
+	static const u16 default_values[] = {
+		0x000, 0x100,
+		0x120, 0x000,
+		0x000, 0x100, 0x000, 0x100, 0x000,
+		0x000, 0x080,
+	};
+
+	memcpy(wm->ctl, default_ctl, sizeof(wm->ctl));
+
+	snd_wm8766_write(wm, WM8766_REG_RESET, 0x00); /* reset */
+	udelay(10);
+	/* load defaults */
+	for (i = 0; i < ARRAY_SIZE(default_values); i++)
+		snd_wm8766_write(wm, i, default_values[i]);
+}
+EXPORT_SYMBOL(snd_wm8766_init);
+
+void snd_wm8766_set_if(struct snd_wm8766 *wm, u16 dac)
+{
+	u16 val = wm->regs[WM8766_REG_IFCTRL] & ~WM8766_IF_MASK;
+
+	dac &= WM8766_IF_MASK;
+	snd_wm8766_write(wm, WM8766_REG_IFCTRL, val | dac);
+}
+EXPORT_SYMBOL(snd_wm8766_set_if);
+
+void snd_wm8766_set_master_mode(struct snd_wm8766 *wm, u16 mode)
+{
+	u16 val = wm->regs[WM8766_REG_DACCTRL3] & ~WM8766_DAC3_MSTR_MASK;
+
+	mode &= WM8766_DAC3_MSTR_MASK;
+	snd_wm8766_write(wm, WM8766_REG_DACCTRL3, val | mode);
+}
+EXPORT_SYMBOL(snd_wm8766_set_master_mode);
+
+void snd_wm8766_set_power(struct snd_wm8766 *wm, u16 power)
+{
+	u16 val = wm->regs[WM8766_REG_DACCTRL3] & ~WM8766_DAC3_POWER_MASK;
+
+	power &= WM8766_DAC3_POWER_MASK;
+	snd_wm8766_write(wm, WM8766_REG_DACCTRL3, val | power);
+}
+EXPORT_SYMBOL(snd_wm8766_set_power);
+
+void snd_wm8766_volume_restore(struct snd_wm8766 *wm)
+{
+	u16 val = wm->regs[WM8766_REG_DACR1];
+	/* restore volume after MCLK stopped */
+	snd_wm8766_write(wm, WM8766_REG_DACR1, val | WM8766_VOL_UPDATE);
+}
+EXPORT_SYMBOL(snd_wm8766_volume_restore);
+
+/* mixer callbacks */
+
+static int snd_wm8766_volume_info(struct snd_kcontrol *kcontrol,
+				   struct snd_ctl_elem_info *uinfo)
+{
+	struct snd_wm8766 *wm = snd_kcontrol_chip(kcontrol);
+	int n = kcontrol->private_value;
+
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+	uinfo->count = (wm->ctl[n].flags & WM8766_FLAG_STEREO) ? 2 : 1;
+	uinfo->value.integer.min = wm->ctl[n].min;
+	uinfo->value.integer.max = wm->ctl[n].max;
+
+	return 0;
+}
+
+static int snd_wm8766_enum_info(struct snd_kcontrol *kcontrol,
+				      struct snd_ctl_elem_info *uinfo)
+{
+	struct snd_wm8766 *wm = snd_kcontrol_chip(kcontrol);
+	int n = kcontrol->private_value;
+
+	return snd_ctl_enum_info(uinfo, 1, wm->ctl[n].max,
+						wm->ctl[n].enum_names);
+}
+
+static int snd_wm8766_ctl_get(struct snd_kcontrol *kcontrol,
+				  struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_wm8766 *wm = snd_kcontrol_chip(kcontrol);
+	int n = kcontrol->private_value;
+	u16 val1, val2;
+
+	if (wm->ctl[n].get)
+		wm->ctl[n].get(wm, &val1, &val2);
+	else {
+		val1 = wm->regs[wm->ctl[n].reg1] & wm->ctl[n].mask1;
+		val1 >>= __ffs(wm->ctl[n].mask1);
+		if (wm->ctl[n].flags & WM8766_FLAG_STEREO) {
+			val2 = wm->regs[wm->ctl[n].reg2] & wm->ctl[n].mask2;
+			val2 >>= __ffs(wm->ctl[n].mask2);
+			if (wm->ctl[n].flags & WM8766_FLAG_VOL_UPDATE)
+				val2 &= ~WM8766_VOL_UPDATE;
+		}
+	}
+	if (wm->ctl[n].flags & WM8766_FLAG_INVERT) {
+		val1 = wm->ctl[n].max - (val1 - wm->ctl[n].min);
+		val2 = wm->ctl[n].max - (val2 - wm->ctl[n].min);
+	}
+	ucontrol->value.integer.value[0] = val1;
+	if (wm->ctl[n].flags & WM8766_FLAG_STEREO)
+		ucontrol->value.integer.value[1] = val2;
+
+	return 0;
+}
+
+static int snd_wm8766_ctl_put(struct snd_kcontrol *kcontrol,
+				  struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_wm8766 *wm = snd_kcontrol_chip(kcontrol);
+	int n = kcontrol->private_value;
+	u16 val, regval1, regval2;
+
+	/* this also works for enum because value is an union */
+	regval1 = ucontrol->value.integer.value[0];
+	regval2 = ucontrol->value.integer.value[1];
+	if (wm->ctl[n].flags & WM8766_FLAG_INVERT) {
+		regval1 = wm->ctl[n].max - (regval1 - wm->ctl[n].min);
+		regval2 = wm->ctl[n].max - (regval2 - wm->ctl[n].min);
+	}
+	if (wm->ctl[n].set)
+		wm->ctl[n].set(wm, regval1, regval2);
+	else {
+		val = wm->regs[wm->ctl[n].reg1] & ~wm->ctl[n].mask1;
+		val |= regval1 << __ffs(wm->ctl[n].mask1);
+		/* both stereo controls in one register */
+		if (wm->ctl[n].flags & WM8766_FLAG_STEREO &&
+				wm->ctl[n].reg1 == wm->ctl[n].reg2) {
+			val &= ~wm->ctl[n].mask2;
+			val |= regval2 << __ffs(wm->ctl[n].mask2);
+		}
+		snd_wm8766_write(wm, wm->ctl[n].reg1, val);
+		/* stereo controls in different registers */
+		if (wm->ctl[n].flags & WM8766_FLAG_STEREO &&
+				wm->ctl[n].reg1 != wm->ctl[n].reg2) {
+			val = wm->regs[wm->ctl[n].reg2] & ~wm->ctl[n].mask2;
+			val |= regval2 << __ffs(wm->ctl[n].mask2);
+			if (wm->ctl[n].flags & WM8766_FLAG_VOL_UPDATE)
+				val |= WM8766_VOL_UPDATE;
+			snd_wm8766_write(wm, wm->ctl[n].reg2, val);
+		}
+	}
+
+	return 0;
+}
+
+int snd_wm8766_add_control(struct snd_wm8766 *wm, int num)
+{
+	struct snd_kcontrol_new cont;
+	struct snd_kcontrol *ctl;
+
+	memset(&cont, 0, sizeof(cont));
+	cont.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
+	cont.private_value = num;
+	cont.name = wm->ctl[num].name;
+	cont.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
+	if (wm->ctl[num].flags & WM8766_FLAG_LIM ||
+	    wm->ctl[num].flags & WM8766_FLAG_ALC)
+		cont.access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
+	cont.tlv.p = NULL;
+	cont.get = snd_wm8766_ctl_get;
+	cont.put = snd_wm8766_ctl_put;
+
+	switch (wm->ctl[num].type) {
+	case SNDRV_CTL_ELEM_TYPE_INTEGER:
+		cont.info = snd_wm8766_volume_info;
+		cont.access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ;
+		cont.tlv.p = wm->ctl[num].tlv;
+		break;
+	case SNDRV_CTL_ELEM_TYPE_BOOLEAN:
+		wm->ctl[num].max = 1;
+		if (wm->ctl[num].flags & WM8766_FLAG_STEREO)
+			cont.info = snd_ctl_boolean_stereo_info;
+		else
+			cont.info = snd_ctl_boolean_mono_info;
+		break;
+	case SNDRV_CTL_ELEM_TYPE_ENUMERATED:
+		cont.info = snd_wm8766_enum_info;
+		break;
+	default:
+		return -EINVAL;
+	}
+	ctl = snd_ctl_new1(&cont, wm);
+	if (!ctl)
+		return -ENOMEM;
+	wm->ctl[num].kctl = ctl;
+
+	return snd_ctl_add(wm->card, ctl);
+}
+
+int snd_wm8766_build_controls(struct snd_wm8766 *wm)
+{
+	int err, i;
+
+	for (i = 0; i < WM8766_CTL_COUNT; i++)
+		if (wm->ctl[i].name) {
+			err = snd_wm8766_add_control(wm, i);
+			if (err < 0)
+				return err;
+		}
+
+	return 0;
+}
+EXPORT_SYMBOL(snd_wm8766_build_controls);
+
+static int __init alsa_wm8766_module_init(void)
+{
+	return 0;
+}
+
+static void __exit alsa_wm8766_module_exit(void)
+{
+}
+
+module_init(alsa_wm8766_module_init)
+module_exit(alsa_wm8766_module_exit)
-- 
Ondrej Zary


^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH 3/4] Add Wolfson Microelectronics WM8776 codec ALSA driver
  2012-04-16 21:18 [RFC PATCH 0/4] snd-ice1712: Add Philips PSC724 Ultimate Edge Ondrej Zary
  2012-04-16 21:18 ` [PATCH 1/4] snd-ice1712: add chip_exit callback Ondrej Zary
  2012-04-16 21:18 ` [PATCH 2/4] Add Wolfson Microelectronics WM8766 codec ALSA driver Ondrej Zary
@ 2012-04-16 21:18 ` Ondrej Zary
  2012-04-17 15:02   ` Mark Brown
  2012-04-16 21:18 ` [PATCH 4/4] snd-ice1712: Add Philips PSC724 Ultimate Edge Ondrej Zary
  3 siblings, 1 reply; 37+ messages in thread
From: Ondrej Zary @ 2012-04-16 21:18 UTC (permalink / raw)
  To: alsa-devel; +Cc: linux-kernel

Needed by Philips PSC724 subdriver. The code does not contain any
card-specific bits so it can be used by any other ALSA driver.

Signed-off-by: Ondrej Zary <linux@rainbow-software.org>
---
 include/sound/wm8776.h   |  223 ++++++++++++++++
 sound/i2c/other/Makefile |    3 +-
 sound/i2c/other/wm8776.c |  645 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 870 insertions(+), 1 deletions(-)
 create mode 100644 include/sound/wm8776.h
 create mode 100644 sound/i2c/other/wm8776.c

diff --git a/include/sound/wm8776.h b/include/sound/wm8776.h
new file mode 100644
index 0000000..78a73eb
--- /dev/null
+++ b/include/sound/wm8776.h
@@ -0,0 +1,223 @@
+#ifndef __SOUND_WM8776_H
+#define __SOUND_WM8776_H
+
+/*
+ *   ALSA driver for WM8776 codecs
+ *
+ *	Copyright (c) 2012 Ondrej Zary <linux@rainbow-software.org>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ */
+
+#define WM8776_REG_HPLVOL	0x00
+#define WM8776_REG_HPRVOL	0x01
+#define WM8776_REG_HPMASTER	0x02
+#define WM8776_HPVOL_MASK		0x17f		/* incl. update bit */
+#define WM8776_VOL_HPZCEN		(1 << 7)	/* zero cross detect */
+#define WM8776_VOL_UPDATE		(1 << 8)	/* update volume */
+#define WM8776_REG_DACLVOL	0x03
+#define WM8776_REG_DACRVOL	0x04
+#define WM8776_REG_DACMASTER	0x05
+#define WM8776_DACVOL_MASK		0x1ff		/* incl. update bit */
+#define WM8776_REG_PHASESWAP	0x06
+#define WM8776_PHASE_INVERTL		(1 << 0)
+#define WM8776_PHASE_INVERTR		(1 << 1)
+#define WM8776_REG_DACCTRL1	0x07
+#define WM8776_DAC_DZCEN		(1 << 0)
+#define WM8776_DAC_ATC			(1 << 1)
+#define WM8776_DAC_IZD			(1 << 2)
+#define WM8776_DAC_TOD			(1 << 3)
+#define WM8776_DAC_PL_MASK		0xf0
+#define WM8776_DAC_PL_LL		(1 << 4)	/* L chan: L signal */
+#define WM8776_DAC_PL_LR		(2 << 4)	/* L chan: R signal */
+#define WM8776_DAC_PL_LB		(3 << 4)	/* L chan: both */
+#define WM8776_DAC_PL_RL		(1 << 6)	/* R chan: L signal */
+#define WM8776_DAC_PL_RR		(2 << 6)	/* R chan: R signal */
+#define WM8776_DAC_PL_RB		(3 << 6)	/* R chan: both */
+#define WM8776_REG_DACMUTE	0x08
+#define WM8776_DACMUTE			(1 << 0)
+#define WM8776_REG_DACCTRL2	0x09
+#define WM8776_DAC2_DEEMPH		(1 << 0)
+#define WM8776_DAC2_ZFLAG_DISABLE	(0 << 1)
+#define WM8776_DAC2_ZFLAG_OWN		(1 << 1)
+#define WM8776_DAC2_ZFLAG_BOTH		(2 << 1)
+#define WM8776_DAC2_ZFLAG_EITHER	(3 << 1)
+#define WM8776_REG_DACIFCTRL	0x0a
+#define WM8776_FMT_RIGHTJ		(0 << 0)
+#define WM8776_FMT_LEFTJ		(1 << 0)
+#define WM8776_FMT_I2S			(2 << 0)
+#define WM8776_FMT_DSP			(3 << 0)
+#define WM8776_FMT_DSP_LATE		(1 << 2)	/* in DSP mode */
+#define WM8776_FMT_LRC_INVERTED		(1 << 2)	/* in other modes */
+#define WM8776_FMT_BCLK_INVERTED	(1 << 3)
+#define WM8776_FMT_16BIT		(0 << 4)
+#define WM8776_FMT_20BIT		(1 << 4)
+#define WM8776_FMT_24BIT		(2 << 4)
+#define WM8776_FMT_32BIT		(3 << 4)
+#define WM8776_REG_ADCIFCTRL	0x0b
+#define WM8776_FMT_ADCMCLK_INVERTED	(1 << 6)
+#define WM8776_FMT_ADCHPD		(1 << 8)
+#define WM8776_REG_MSTRCTRL	0x0c
+#define WM8776_IF_ADC256FS		(2 << 0)
+#define WM8776_IF_ADC384FS		(3 << 0)
+#define WM8776_IF_ADC512FS		(4 << 0)
+#define WM8776_IF_ADC768FS		(5 << 0)
+#define WM8776_IF_OVERSAMP64		(1 << 3)
+#define WM8776_IF_DAC128FS		(0 << 4)
+#define WM8776_IF_DAC192FS		(1 << 4)
+#define WM8776_IF_DAC256FS		(2 << 4)
+#define WM8776_IF_DAC384FS		(3 << 4)
+#define WM8776_IF_DAC512FS		(4 << 4)
+#define WM8776_IF_DAC768FS		(5 << 4)
+#define WM8776_IF_DAC_MASTER		(1 << 7)
+#define WM8776_IF_ADC_MASTER		(1 << 8)
+#define WM8776_REG_PWRDOWN	0x0d
+#define WM8776_PWR_PDWN			(1 << 0)
+#define WM8776_PWR_ADCPD		(1 << 1)
+#define WM8776_PWR_DACPD		(1 << 2)
+#define WM8776_PWR_HPPD			(1 << 3)
+#define WM8776_PWR_AINPD		(1 << 6)
+#define WM8776_REG_ADCLVOL	0x0e
+#define WM8776_REG_ADCRVOL	0x0f
+#define WM8776_ADC_GAIN_MASK		0xff
+#define WM8776_ADC_ZCEN			(1 << 8)
+#define WM8776_REG_ALCCTRL1	0x10
+#define WM8776_ALC1_LCT_MASK		0x0f	/* 0=-16dB, 1=-15dB..15=-1dB */
+#define WM8776_ALC1_MAXGAIN_MASK	0x70	/* 0,1=0dB, 2=+4dB...7=+24dB */
+#define WM8776_ALC1_LCSEL_MASK		0x180
+#define WM8776_ALC1_LCSEL_LIMITER	(0 << 7)
+#define WM8776_ALC1_LCSEL_ALCR		(1 << 7)
+#define WM8776_ALC1_LCSEL_ALCL		(2 << 7)
+#define WM8776_ALC1_LCSEL_ALCSTEREO	(3 << 7)
+#define WM8776_REG_ALCCTRL2	0x11
+#define WM8776_ALC2_HOLD_MASK		0x0f	/*0=0ms, 1=2.67ms, 2=5.33ms.. */
+#define WM8776_ALC2_ZCEN		(1 << 7)
+#define WM8776_ALC2_LCEN		(1 << 8)
+#define WM8776_REG_ALCCTRL3	0x12
+#define WM8776_ALC3_ATK_MASK		0x0f
+#define WM8776_ALC3_DCY_MASK		0xf0
+#define WM8776_ALC3_FDECAY		(1 << 8)
+#define WM8776_REG_NOISEGATE	0x13
+#define WM8776_NGAT_ENABLE		(1 << 0)
+#define WM8776_NGAT_THR_MASK		0x1c	/*0=-78dB, 1=-72dB...7=-36dB */
+#define WM8776_REG_LIMITER	0x14
+#define WM8776_LIM_MAXATTEN_MASK	0x0f
+#define WM8776_LIM_TRANWIN_MASK		0x70	/*0=0us, 1=62.5us, 2=125us.. */
+#define WM8776_REG_ADCMUX	0x15
+#define WM8776_ADC_MUX_AIN1		(1 << 0)
+#define WM8776_ADC_MUX_AIN2		(1 << 1)
+#define WM8776_ADC_MUX_AIN3		(1 << 2)
+#define WM8776_ADC_MUX_AIN4		(1 << 3)
+#define WM8776_ADC_MUX_AIN5		(1 << 4)
+#define WM8776_ADC_MUTER		(1 << 6)
+#define WM8776_ADC_MUTEL		(1 << 7)
+#define WM8776_ADC_LRBOTH		(1 << 8)
+#define WM8776_REG_OUTMUX	0x16
+#define WM8776_OUTMUX_DAC		(1 << 0)
+#define WM8776_OUTMUX_AUX		(1 << 1)
+#define WM8776_OUTMUX_BYPASS		(1 << 2)
+#define WM8776_REG_RESET	0x17
+
+#define WM8776_REG_COUNT	0x17	/* don't cache the RESET register */
+
+struct snd_wm8776;
+
+struct snd_wm8776_ops {
+	void (*write)(struct snd_wm8776 *wm, u8 addr, u8 data);
+};
+
+enum snd_wm8776_ctl_id {
+	WM8776_CTL_DAC_VOL,
+	WM8776_CTL_DAC_SW,
+	WM8776_CTL_DAC_ZC_SW,
+	WM8776_CTL_HP_VOL,
+	WM8776_CTL_HP_SW,
+	WM8776_CTL_HP_ZC_SW,
+	WM8776_CTL_AUX_SW,
+	WM8776_CTL_BYPASS_SW,
+	WM8776_CTL_DAC_IZD_SW,
+	WM8776_CTL_PHASE_SW,
+	WM8776_CTL_DEEMPH_SW,
+	WM8776_CTL_ADC_VOL,
+	WM8776_CTL_ADC_SW,
+	WM8776_CTL_INPUT1_SW,
+	WM8776_CTL_INPUT2_SW,
+	WM8776_CTL_INPUT3_SW,
+	WM8776_CTL_INPUT4_SW,
+	WM8776_CTL_INPUT5_SW,
+	WM8776_CTL_AGC_SEL,
+	WM8776_CTL_LIM_THR,
+	WM8776_CTL_LIM_ATK,
+	WM8776_CTL_LIM_DCY,
+	WM8776_CTL_LIM_TRANWIN,
+	WM8776_CTL_LIM_MAXATTN,
+	WM8776_CTL_ALC_TGT,
+	WM8776_CTL_ALC_ATK,
+	WM8776_CTL_ALC_DCY,
+	WM8776_CTL_ALC_MAXGAIN,
+	WM8776_CTL_ALC_MAXATTN,
+	WM8776_CTL_ALC_HLD,
+	WM8776_CTL_NGT_SW,
+	WM8776_CTL_NGT_THR,
+
+	WM8776_CTL_COUNT,
+};
+
+#define WM8776_ENUM_MAX		16
+
+#define WM8776_FLAG_STEREO	(1 << 0)
+#define WM8776_FLAG_VOL_UPDATE	(1 << 1)
+#define WM8776_FLAG_INVERT	(1 << 2)
+#define WM8776_FLAG_LIM		(1 << 3)
+#define WM8776_FLAG_ALC		(1 << 4)
+
+struct snd_wm8776_ctl {
+	char *name;
+	snd_ctl_elem_type_t type;
+	const char *const enum_names[WM8776_ENUM_MAX];
+	const unsigned int *tlv;
+	u16 reg1, reg2, mask1, mask2, min, max, flags;
+	void (*set)(struct snd_wm8776 *wm, u16 ch1, u16 ch2);
+	void (*get)(struct snd_wm8776 *wm, u16 *ch1, u16 *ch2);
+};
+
+enum snd_wm8776_agc_mode {
+	WM8776_AGC_OFF,
+	WM8776_AGC_LIM,
+	WM8776_AGC_ALC_R,
+	WM8776_AGC_ALC_L,
+	WM8776_AGC_ALC_STEREO
+};
+
+struct snd_wm8776 {
+	struct snd_card *card;
+	struct snd_wm8776_ctl ctl[WM8776_CTL_COUNT];
+	enum snd_wm8776_agc_mode agc_mode;
+	struct snd_wm8776_ops ops;
+	u16 regs[WM8776_REG_COUNT];	/* 9-bit registers */
+};
+
+
+
+void snd_wm8776_init(struct snd_wm8776 *wm);
+void snd_wm8776_set_dac_if(struct snd_wm8776 *wm, u16 dac);
+void snd_wm8776_set_adc_if(struct snd_wm8776 *wm, u16 adc);
+void snd_wm8776_set_master_mode(struct snd_wm8776 *wm, u16 mode);
+void snd_wm8776_set_power(struct snd_wm8776 *wm, u16 power);
+void snd_wm8776_volume_restore(struct snd_wm8776 *wm);
+int snd_wm8776_build_controls(struct snd_wm8776 *wm);
+
+#endif /* __SOUND_WM8776_H */
diff --git a/sound/i2c/other/Makefile b/sound/i2c/other/Makefile
index 93406f7..433a76d 100644
--- a/sound/i2c/other/Makefile
+++ b/sound/i2c/other/Makefile
@@ -10,9 +10,10 @@ snd-ak4xxx-adda-objs := ak4xxx-adda.o
 snd-pt2258-objs := pt2258.o
 snd-tea575x-tuner-objs := tea575x-tuner.o
 snd-wm8766-objs := wm8766.o
+snd-wm8776-objs := wm8776.o
 
 # Module Dependency
 obj-$(CONFIG_SND_PDAUDIOCF) += snd-ak4117.o
 obj-$(CONFIG_SND_ICE1712) += snd-ak4xxx-adda.o
-obj-$(CONFIG_SND_ICE1724) += snd-ak4114.o snd-ak4113.o snd-ak4xxx-adda.o snd-pt2258.o snd-wm8766.o
+obj-$(CONFIG_SND_ICE1724) += snd-ak4114.o snd-ak4113.o snd-ak4xxx-adda.o snd-pt2258.o snd-wm8766.o snd-wm8776.o
 obj-$(CONFIG_SND_TEA575X) += snd-tea575x-tuner.o
diff --git a/sound/i2c/other/wm8776.c b/sound/i2c/other/wm8776.c
new file mode 100644
index 0000000..253cbcf
--- /dev/null
+++ b/sound/i2c/other/wm8776.c
@@ -0,0 +1,645 @@
+/*
+ *   ALSA driver for WM8776 codecs
+ *
+ *	Copyright (c) 2012 Ondrej Zary <linux@rainbow-software.org>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <sound/control.h>
+#include <sound/tlv.h>
+#include <sound/wm8776.h>
+
+MODULE_AUTHOR("Ondrej Zary <linux@rainbow-software.org>");
+MODULE_DESCRIPTION("Routines for control of WM8776 codecs");
+MODULE_LICENSE("GPL");
+
+/* low-level access */
+
+void snd_wm8776_write(struct snd_wm8776 *wm, u16 addr, u16 data)
+{
+	u8 bus_addr = addr << 1 | data >> 8;	/* addr + 9th data bit */
+	u8 bus_data = data & 0xff;		/* remaining 8 data bits */
+
+	if (addr < WM8776_REG_RESET)
+		wm->regs[addr] = data;
+	wm->ops.write(wm, bus_addr, bus_data);
+}
+
+/* register-level functions */
+
+void snd_wm8776_activate_ctl(struct snd_wm8776 *wm, char *ctl_name, bool active)
+{
+	struct snd_card *card = wm->card;
+	struct snd_kcontrol *kctl;
+	struct snd_kcontrol_volatile *vd;
+	struct snd_ctl_elem_id elem_id;
+	unsigned int index_offset;
+
+	memset(&elem_id, 0, sizeof(elem_id));
+	strncpy(elem_id.name, ctl_name, sizeof(elem_id.name));
+	elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
+	kctl = snd_ctl_find_id(card, &elem_id);
+	if (!kctl)
+		return;
+	index_offset = snd_ctl_get_ioff(kctl, &kctl->id);
+	vd = &kctl->vd[index_offset];
+	if (active)
+		vd->access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
+	else
+		vd->access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
+	snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_INFO, &kctl->id);
+}
+
+static void snd_wm8776_update_agc_ctl(struct snd_wm8776 *wm)
+{
+	int i, flags_on = 0, flags_off = 0;
+
+	switch (wm->agc_mode) {
+	case WM8776_AGC_OFF:
+		flags_off = WM8776_FLAG_LIM | WM8776_FLAG_ALC;
+		break;
+	case WM8776_AGC_LIM:
+		flags_off = WM8776_FLAG_ALC;
+		flags_on = WM8776_FLAG_LIM;
+		break;
+	case WM8776_AGC_ALC_R:
+	case WM8776_AGC_ALC_L:
+	case WM8776_AGC_ALC_STEREO:
+		flags_off = WM8776_FLAG_LIM;
+		flags_on = WM8776_FLAG_ALC;
+		break;
+	}
+
+	for (i = 0; i < WM8776_CTL_COUNT; i++)
+		if (wm->ctl[i].flags & flags_off)
+			snd_wm8776_activate_ctl(wm, wm->ctl[i].name, false);
+		else if (wm->ctl[i].flags & flags_on)
+			snd_wm8776_activate_ctl(wm, wm->ctl[i].name, true);
+}
+
+static void snd_wm8776_set_agc(struct snd_wm8776 *wm, u16 agc, u16 nothing)
+{
+	u16 alc1 = wm->regs[WM8776_REG_ALCCTRL1] & ~WM8776_ALC1_LCT_MASK;
+	u16 alc2 = wm->regs[WM8776_REG_ALCCTRL2] & ~WM8776_ALC2_LCEN;
+
+	switch (agc) {
+	case 0:	/* Off */
+		wm->agc_mode = WM8776_AGC_OFF;
+		break;
+	case 1: /* Limiter */
+		alc2 |= WM8776_ALC2_LCEN;
+		wm->agc_mode = WM8776_AGC_LIM;
+		break;
+	case 2: /* ALC Right */
+		alc1 |= WM8776_ALC1_LCSEL_ALCR;
+		alc2 |= WM8776_ALC2_LCEN;
+		wm->agc_mode = WM8776_AGC_ALC_R;
+		break;
+	case 3: /* ALC Left */
+		alc1 |= WM8776_ALC1_LCSEL_ALCL;
+		alc2 |= WM8776_ALC2_LCEN;
+		wm->agc_mode = WM8776_AGC_ALC_L;
+		break;
+	case 4: /* ALC Stereo */
+		alc1 |= WM8776_ALC1_LCSEL_ALCSTEREO;
+		alc2 |= WM8776_ALC2_LCEN;
+		wm->agc_mode = WM8776_AGC_ALC_STEREO;
+		break;
+	}
+	snd_wm8776_write(wm, WM8776_REG_ALCCTRL1, alc1);
+	snd_wm8776_write(wm, WM8776_REG_ALCCTRL2, alc2);
+	snd_wm8776_update_agc_ctl(wm);
+}
+
+static void snd_wm8776_get_agc(struct snd_wm8776 *wm, u16 *mode, u16 *nothing)
+{
+	*mode = wm->agc_mode;
+}
+
+/* mixer controls */
+
+static const DECLARE_TLV_DB_SCALE(wm8776_hp_tlv, -7400, 100, 1);
+static const DECLARE_TLV_DB_SCALE(wm8776_dac_tlv, -12750, 50, 1);
+static const DECLARE_TLV_DB_SCALE(wm8776_adc_tlv, -10350, 50, 1);
+static const DECLARE_TLV_DB_SCALE(wm8776_lct_tlv, -1600, 100, 0);
+static const DECLARE_TLV_DB_SCALE(wm8776_maxgain_tlv, 0, 400, 0);
+static const DECLARE_TLV_DB_SCALE(wm8776_ngth_tlv, -7800, 600, 0);
+static const DECLARE_TLV_DB_SCALE(wm8776_maxatten_lim_tlv, -1200, 100, 0);
+static const DECLARE_TLV_DB_SCALE(wm8776_maxatten_alc_tlv, -2100, 400, 0);
+
+static struct snd_wm8776_ctl default_ctl[WM8776_CTL_COUNT] = {
+	[WM8776_CTL_DAC_VOL] = {
+		.name = "Master Playback Volume",
+		.type = SNDRV_CTL_ELEM_TYPE_INTEGER,
+		.tlv = wm8776_dac_tlv,
+		.reg1 = WM8776_REG_DACLVOL,
+		.reg2 = WM8776_REG_DACRVOL,
+		.mask1 = WM8776_DACVOL_MASK,
+		.mask2 = WM8776_DACVOL_MASK,
+		.max = 0xff,
+		.flags = WM8776_FLAG_STEREO | WM8776_FLAG_VOL_UPDATE,
+	},
+	[WM8776_CTL_DAC_SW] = {
+		.name = "Master Playback Switch",
+		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN,
+		.reg1 = WM8776_REG_DACCTRL1,
+		.reg2 = WM8776_REG_DACCTRL1,
+		.mask1 = WM8776_DAC_PL_LL,
+		.mask2 = WM8776_DAC_PL_RR,
+		.flags = WM8776_FLAG_STEREO,
+	},
+	[WM8776_CTL_DAC_ZC_SW] = {
+		.name = "Master Zero Cross Detect Playback Switch",
+		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN,
+		.reg1 = WM8776_REG_DACCTRL1,
+		.mask1 = WM8776_DAC_DZCEN,
+	},
+	[WM8776_CTL_HP_VOL] = {
+		.name = "Headphone Playback Volume",
+		.type = SNDRV_CTL_ELEM_TYPE_INTEGER,
+		.tlv = wm8776_hp_tlv,
+		.reg1 = WM8776_REG_HPLVOL,
+		.reg2 = WM8776_REG_HPRVOL,
+		.mask1 = WM8776_HPVOL_MASK,
+		.mask2 = WM8776_HPVOL_MASK,
+		.min = 0x2f,
+		.max = 0x7f,
+		.flags = WM8776_FLAG_STEREO | WM8776_FLAG_VOL_UPDATE,
+	},
+	[WM8776_CTL_HP_SW] = {
+		.name = "Headphone Playback Switch",
+		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN,
+		.reg1 = WM8776_REG_PWRDOWN,
+		.mask1 = WM8776_PWR_HPPD,
+		.flags = WM8776_FLAG_INVERT,
+	},
+	[WM8776_CTL_HP_ZC_SW] = {
+		.name = "Headphone Zero Cross Detect Playback Switch",
+		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN,
+		.reg1 = WM8776_REG_HPLVOL,
+		.reg2 = WM8776_REG_HPRVOL,
+		.mask1 = WM8776_VOL_HPZCEN,
+		.mask2 = WM8776_VOL_HPZCEN,
+		.flags = WM8776_FLAG_STEREO,
+	},
+	[WM8776_CTL_AUX_SW] = {
+		.name = "AUX Playback Switch",
+		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN,
+		.reg1 = WM8776_REG_OUTMUX,
+		.mask1 = WM8776_OUTMUX_AUX,
+	},
+	[WM8776_CTL_BYPASS_SW] = {
+		.name = "Bypass Playback Switch",
+		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN,
+		.reg1 = WM8776_REG_OUTMUX,
+		.mask1 = WM8776_OUTMUX_BYPASS,
+	},
+	[WM8776_CTL_DAC_IZD_SW] = {
+		.name = "Infinite Zero Detect Playback Switch",
+		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN,
+		.reg1 = WM8776_REG_DACCTRL1,
+		.mask1 = WM8776_DAC_IZD,
+	},
+	[WM8776_CTL_PHASE_SW] = {
+		.name = "Phase Invert Playback Switch",
+		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN,
+		.reg1 = WM8776_REG_PHASESWAP,
+		.reg2 = WM8776_REG_PHASESWAP,
+		.mask1 = WM8776_PHASE_INVERTL,
+		.mask2 = WM8776_PHASE_INVERTR,
+		.flags = WM8776_FLAG_STEREO,
+	},
+	[WM8776_CTL_DEEMPH_SW] = {
+		.name = "Deemphasis Playback Switch",
+		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN,
+		.reg1 = WM8776_REG_DACCTRL2,
+		.mask1 = WM8776_DAC2_DEEMPH,
+	},
+	[WM8776_CTL_ADC_VOL] = {
+		.name = "Input Capture Volume",
+		.type = SNDRV_CTL_ELEM_TYPE_INTEGER,
+		.tlv = wm8776_adc_tlv,
+		.reg1 = WM8776_REG_ADCLVOL,
+		.reg2 = WM8776_REG_ADCRVOL,
+		.mask1 = WM8776_ADC_GAIN_MASK,
+		.mask2 = WM8776_ADC_GAIN_MASK,
+		.max = 0xff,
+		.flags = WM8776_FLAG_STEREO | WM8776_FLAG_VOL_UPDATE,
+	},
+	[WM8776_CTL_ADC_SW] = {
+		.name = "Input Capture Switch",
+		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN,
+		.reg1 = WM8776_REG_ADCMUX,
+		.reg2 = WM8776_REG_ADCMUX,
+		.mask1 = WM8776_ADC_MUTEL,
+		.mask2 = WM8776_ADC_MUTER,
+		.flags = WM8776_FLAG_STEREO | WM8776_FLAG_INVERT,
+	},
+	[WM8776_CTL_INPUT1_SW] = {
+		.name = "AIN1 Capture Switch",
+		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN,
+		.reg1 = WM8776_REG_ADCMUX,
+		.mask1 = WM8776_ADC_MUX_AIN1,
+	},
+	[WM8776_CTL_INPUT2_SW] = {
+		.name = "AIN2 Capture Switch",
+		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN,
+		.reg1 = WM8776_REG_ADCMUX,
+		.mask1 = WM8776_ADC_MUX_AIN2,
+	},
+	[WM8776_CTL_INPUT3_SW] = {
+		.name = "AIN3 Capture Switch",
+		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN,
+		.reg1 = WM8776_REG_ADCMUX,
+		.mask1 = WM8776_ADC_MUX_AIN3,
+	},
+	[WM8776_CTL_INPUT4_SW] = {
+		.name = "AIN4 Capture Switch",
+		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN,
+		.reg1 = WM8776_REG_ADCMUX,
+		.mask1 = WM8776_ADC_MUX_AIN4,
+	},
+	[WM8776_CTL_INPUT5_SW] = {
+		.name = "AIN5 Capture Switch",
+		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN,
+		.reg1 = WM8776_REG_ADCMUX,
+		.mask1 = WM8776_ADC_MUX_AIN5,
+	},
+	[WM8776_CTL_AGC_SEL] = {
+		.name = "AGC Select Capture Enum",
+		.type = SNDRV_CTL_ELEM_TYPE_ENUMERATED,
+		.enum_names = { "Off", "Limiter", "ALC Right", "ALC Left",
+				"ALC Stereo" },
+		.max = 5,	/* .enum_names item count */
+		.set = snd_wm8776_set_agc,
+		.get = snd_wm8776_get_agc,
+	},
+	[WM8776_CTL_LIM_THR] = {
+		.name = "Limiter Threshold Capture Volume",
+		.type = SNDRV_CTL_ELEM_TYPE_INTEGER,
+		.tlv = wm8776_lct_tlv,
+		.reg1 = WM8776_REG_ALCCTRL1,
+		.mask1 = WM8776_ALC1_LCT_MASK,
+		.max = 15,
+		.flags = WM8776_FLAG_LIM,
+	},
+	[WM8776_CTL_LIM_ATK] = {
+		.name = "Limiter Attack Time Capture Enum",
+		.type = SNDRV_CTL_ELEM_TYPE_ENUMERATED,
+		.enum_names = { "0.25 ms", "0.5 ms", "1 ms", "2 ms", "4 ms",
+			"8 ms", "16 ms", "32 ms", "64 ms", "128 ms", "256 ms" },
+		.max = 11,	/* .enum_names item count */
+		.reg1 = WM8776_REG_ALCCTRL3,
+		.mask1 = WM8776_ALC3_ATK_MASK,
+		.flags = WM8776_FLAG_LIM,
+	},
+	[WM8776_CTL_LIM_DCY] = {
+		.name = "Limiter Decay Time Capture Enum",
+		.type = SNDRV_CTL_ELEM_TYPE_ENUMERATED,
+		.enum_names = {	"1.2 ms", "2.4 ms", "4.8 ms", "9.6 ms",
+			"19.2 ms", "38.4 ms", "76.8 ms", "154 ms", "307 ms",
+			"614 ms", "1.23 s" },
+		.max = 11,	/* .enum_names item count */
+		.reg1 = WM8776_REG_ALCCTRL3,
+		.mask1 = WM8776_ALC3_DCY_MASK,
+		.flags = WM8776_FLAG_LIM,
+	},
+	[WM8776_CTL_LIM_TRANWIN] = {
+		.name = "Limiter Transient Window Capture Enum",
+		.type = SNDRV_CTL_ELEM_TYPE_ENUMERATED,
+		.enum_names = {	"0 us", "62.5 us", "125 us", "250 us", "500 us",
+			"1 ms", "2 ms", "4 ms" },
+		.max = 8,	/* .enum_names item count */
+		.reg1 = WM8776_REG_LIMITER,
+		.mask1 = WM8776_LIM_TRANWIN_MASK,
+		.flags = WM8776_FLAG_LIM,
+	},
+	[WM8776_CTL_LIM_MAXATTN] = {
+		.name = "Limiter Maximum Attenuation Capture Volume",
+		.type = SNDRV_CTL_ELEM_TYPE_INTEGER,
+		.tlv = wm8776_maxatten_lim_tlv,
+		.reg1 = WM8776_REG_LIMITER,
+		.mask1 = WM8776_LIM_MAXATTEN_MASK,
+		.min = 3,
+		.max = 12,
+		.flags = WM8776_FLAG_LIM | WM8776_FLAG_INVERT,
+	},
+	[WM8776_CTL_ALC_TGT] = {
+		.name = "ALC Target Level Capture Volume",
+		.type = SNDRV_CTL_ELEM_TYPE_INTEGER,
+		.tlv = wm8776_lct_tlv,
+		.reg1 = WM8776_REG_ALCCTRL1,
+		.mask1 = WM8776_ALC1_LCT_MASK,
+		.max = 15,
+		.flags = WM8776_FLAG_ALC,
+	},
+	[WM8776_CTL_ALC_ATK] = {
+		.name = "ALC Attack Time Capture Enum",
+		.type = SNDRV_CTL_ELEM_TYPE_ENUMERATED,
+		.enum_names = { "8.40 ms", "16.8 ms", "33.6 ms", "67.2 ms",
+			"134 ms", "269 ms", "538 ms", "1.08 s",	"2.15 s",
+			"4.3 s", "8.6 s" },
+		.max = 11,	/* .enum_names item count */
+		.reg1 = WM8776_REG_ALCCTRL3,
+		.mask1 = WM8776_ALC3_ATK_MASK,
+		.flags = WM8776_FLAG_ALC,
+	},
+	[WM8776_CTL_ALC_DCY] = {
+		.name = "ALC Decay Time Capture Enum",
+		.type = SNDRV_CTL_ELEM_TYPE_ENUMERATED,
+		.enum_names = {	"33.5 ms", "67.0 ms", "134 ms", "268 ms",
+			"536 ms", "1.07 s", "2.14 s", "4.29 s",	"8.58 s",
+			"17.2 s", "34.3 s" },
+		.max = 11,	/* .enum_names item count */
+		.reg1 = WM8776_REG_ALCCTRL3,
+		.mask1 = WM8776_ALC3_DCY_MASK,
+		.flags = WM8776_FLAG_ALC,
+	},
+	[WM8776_CTL_ALC_MAXGAIN] = {
+		.name = "ALC Maximum Gain Capture Volume",
+		.type = SNDRV_CTL_ELEM_TYPE_INTEGER,
+		.tlv = wm8776_maxgain_tlv,
+		.reg1 = WM8776_REG_ALCCTRL1,
+		.mask1 = WM8776_ALC1_MAXGAIN_MASK,
+		.min = 1,
+		.max = 7,
+		.flags = WM8776_FLAG_ALC,
+	},
+	[WM8776_CTL_ALC_MAXATTN] = {
+		.name = "ALC Maximum Attenuation Capture Volume",
+		.type = SNDRV_CTL_ELEM_TYPE_INTEGER,
+		.tlv = wm8776_maxatten_alc_tlv,
+		.reg1 = WM8776_REG_LIMITER,
+		.mask1 = WM8776_LIM_MAXATTEN_MASK,
+		.min = 10,
+		.max = 15,
+		.flags = WM8776_FLAG_ALC | WM8776_FLAG_INVERT,
+	},
+	[WM8776_CTL_ALC_HLD] = {
+		.name = "ALC Hold Time Capture Enum",
+		.type = SNDRV_CTL_ELEM_TYPE_ENUMERATED,
+		.enum_names = {	"0 ms", "2.67 ms", "5.33 ms", "10.6 ms",
+			"21.3 ms", "42.7 ms", "85.3 ms", "171 ms", "341 ms",
+			"683 ms", "1.37 s", "2.73 s", "5.46 s", "10.9 s",
+			"21.8 s", "43.7 s" },
+		.max = 16,	/* .enum_names item count */
+		.reg1 = WM8776_REG_ALCCTRL2,
+		.mask1 = WM8776_ALC2_HOLD_MASK,
+		.flags = WM8776_FLAG_ALC,
+	},
+	[WM8776_CTL_NGT_SW] = {
+		.name = "Noise Gate Capture Switch",
+		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN,
+		.reg1 = WM8776_REG_NOISEGATE,
+		.mask1 = WM8776_NGAT_ENABLE,
+		.flags = WM8776_FLAG_ALC,
+	},
+	[WM8776_CTL_NGT_THR] = {
+		.name = "Noise Gate Threshold Capture Volume",
+		.type = SNDRV_CTL_ELEM_TYPE_INTEGER,
+		.tlv = wm8776_ngth_tlv,
+		.reg1 = WM8776_REG_NOISEGATE,
+		.mask1 = WM8776_NGAT_THR_MASK,
+		.max = 7,
+		.flags = WM8776_FLAG_ALC,
+	},
+};
+
+/* exported functions */
+
+void snd_wm8776_init(struct snd_wm8776 *wm)
+{
+	int i;
+	static const u16 default_values[] = {
+		0x000, 0x100, 0x000,
+		0x000, 0x100, 0x000,
+		0x000, 0x090, 0x000, 0x000,
+		0x022, 0x022, 0x022,
+		0x008, 0x0cf, 0x0cf, 0x07b, 0x000,
+		0x032, 0x000, 0x0a6, 0x001, 0x001
+	};
+
+	memcpy(wm->ctl, default_ctl, sizeof(wm->ctl));
+
+	snd_wm8776_write(wm, WM8776_REG_RESET, 0x00); /* reset */
+	udelay(10);
+	/* load defaults */
+	for (i = 0; i < ARRAY_SIZE(default_values); i++)
+		snd_wm8776_write(wm, i, default_values[i]);
+}
+EXPORT_SYMBOL(snd_wm8776_init);
+
+void snd_wm8776_set_dac_if(struct snd_wm8776 *wm, u16 dac)
+{
+	snd_wm8776_write(wm, WM8776_REG_DACIFCTRL, dac);
+}
+EXPORT_SYMBOL(snd_wm8776_set_dac_if);
+
+void snd_wm8776_set_adc_if(struct snd_wm8776 *wm, u16 adc)
+{
+	snd_wm8776_write(wm, WM8776_REG_ADCIFCTRL, adc);
+}
+EXPORT_SYMBOL(snd_wm8776_set_adc_if);
+
+void snd_wm8776_set_master_mode(struct snd_wm8776 *wm, u16 mode)
+{
+	snd_wm8776_write(wm, WM8776_REG_MSTRCTRL, mode);
+}
+EXPORT_SYMBOL(snd_wm8776_set_master_mode);
+
+void snd_wm8776_set_power(struct snd_wm8776 *wm, u16 power)
+{
+	snd_wm8776_write(wm, WM8776_REG_PWRDOWN, power);
+}
+EXPORT_SYMBOL(snd_wm8776_set_power);
+
+void snd_wm8776_volume_restore(struct snd_wm8776 *wm)
+{
+	u16 val = wm->regs[WM8776_REG_DACRVOL];
+	/* restore volume after MCLK stopped */
+	snd_wm8776_write(wm, WM8776_REG_DACRVOL, val | WM8776_VOL_UPDATE);
+}
+EXPORT_SYMBOL(snd_wm8776_volume_restore);
+
+/* mixer callbacks */
+
+static int snd_wm8776_volume_info(struct snd_kcontrol *kcontrol,
+				   struct snd_ctl_elem_info *uinfo)
+{
+	struct snd_wm8776 *wm = snd_kcontrol_chip(kcontrol);
+	int n = kcontrol->private_value;
+
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+	uinfo->count = (wm->ctl[n].flags & WM8776_FLAG_STEREO) ? 2 : 1;
+	uinfo->value.integer.min = wm->ctl[n].min;
+	uinfo->value.integer.max = wm->ctl[n].max;
+
+	return 0;
+}
+
+static int snd_wm8776_enum_info(struct snd_kcontrol *kcontrol,
+				      struct snd_ctl_elem_info *uinfo)
+{
+	struct snd_wm8776 *wm = snd_kcontrol_chip(kcontrol);
+	int n = kcontrol->private_value;
+
+	return snd_ctl_enum_info(uinfo, 1, wm->ctl[n].max,
+						wm->ctl[n].enum_names);
+}
+
+static int snd_wm8776_ctl_get(struct snd_kcontrol *kcontrol,
+				  struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_wm8776 *wm = snd_kcontrol_chip(kcontrol);
+	int n = kcontrol->private_value;
+	u16 val1, val2;
+
+	if (wm->ctl[n].get)
+		wm->ctl[n].get(wm, &val1, &val2);
+	else {
+		val1 = wm->regs[wm->ctl[n].reg1] & wm->ctl[n].mask1;
+		val1 >>= __ffs(wm->ctl[n].mask1);
+		if (wm->ctl[n].flags & WM8776_FLAG_STEREO) {
+			val2 = wm->regs[wm->ctl[n].reg2] & wm->ctl[n].mask2;
+			val2 >>= __ffs(wm->ctl[n].mask2);
+			if (wm->ctl[n].flags & WM8776_FLAG_VOL_UPDATE)
+				val2 &= ~WM8776_VOL_UPDATE;
+		}
+	}
+	if (wm->ctl[n].flags & WM8776_FLAG_INVERT) {
+		val1 = wm->ctl[n].max - (val1 - wm->ctl[n].min);
+		val2 = wm->ctl[n].max - (val2 - wm->ctl[n].min);
+	}
+	ucontrol->value.integer.value[0] = val1;
+	if (wm->ctl[n].flags & WM8776_FLAG_STEREO)
+		ucontrol->value.integer.value[1] = val2;
+
+	return 0;
+}
+
+static int snd_wm8776_ctl_put(struct snd_kcontrol *kcontrol,
+				  struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_wm8776 *wm = snd_kcontrol_chip(kcontrol);
+	int n = kcontrol->private_value;
+	u16 val, regval1, regval2;
+
+	/* this also works for enum because value is an union */
+	regval1 = ucontrol->value.integer.value[0];
+	regval2 = ucontrol->value.integer.value[1];
+	if (wm->ctl[n].flags & WM8776_FLAG_INVERT) {
+		regval1 = wm->ctl[n].max - (regval1 - wm->ctl[n].min);
+		regval2 = wm->ctl[n].max - (regval2 - wm->ctl[n].min);
+	}
+	if (wm->ctl[n].set)
+		wm->ctl[n].set(wm, regval1, regval2);
+	else {
+		val = wm->regs[wm->ctl[n].reg1] & ~wm->ctl[n].mask1;
+		val |= regval1 << __ffs(wm->ctl[n].mask1);
+		/* both stereo controls in one register */
+		if (wm->ctl[n].flags & WM8776_FLAG_STEREO &&
+				wm->ctl[n].reg1 == wm->ctl[n].reg2) {
+			val &= ~wm->ctl[n].mask2;
+			val |= regval2 << __ffs(wm->ctl[n].mask2);
+		}
+		snd_wm8776_write(wm, wm->ctl[n].reg1, val);
+		/* stereo controls in different registers */
+		if (wm->ctl[n].flags & WM8776_FLAG_STEREO &&
+				wm->ctl[n].reg1 != wm->ctl[n].reg2) {
+			val = wm->regs[wm->ctl[n].reg2] & ~wm->ctl[n].mask2;
+			val |= regval2 << __ffs(wm->ctl[n].mask2);
+			if (wm->ctl[n].flags & WM8776_FLAG_VOL_UPDATE)
+				val |= WM8776_VOL_UPDATE;
+			snd_wm8776_write(wm, wm->ctl[n].reg2, val);
+		}
+	}
+
+	return 0;
+}
+
+int snd_wm8776_add_control(struct snd_wm8776 *wm, int num)
+{
+	struct snd_kcontrol_new cont;
+	struct snd_kcontrol *ctl;
+
+	memset(&cont, 0, sizeof(cont));
+	cont.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
+	cont.private_value = num;
+	cont.name = wm->ctl[num].name;
+	cont.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
+	if (wm->ctl[num].flags & WM8776_FLAG_LIM ||
+	    wm->ctl[num].flags & WM8776_FLAG_ALC)
+		cont.access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
+	cont.tlv.p = NULL;
+	cont.get = snd_wm8776_ctl_get;
+	cont.put = snd_wm8776_ctl_put;
+
+	switch (wm->ctl[num].type) {
+	case SNDRV_CTL_ELEM_TYPE_INTEGER:
+		cont.info = snd_wm8776_volume_info;
+		cont.access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ;
+		cont.tlv.p = wm->ctl[num].tlv;
+		break;
+	case SNDRV_CTL_ELEM_TYPE_BOOLEAN:
+		wm->ctl[num].max = 1;
+		if (wm->ctl[num].flags & WM8776_FLAG_STEREO)
+			cont.info = snd_ctl_boolean_stereo_info;
+		else
+			cont.info = snd_ctl_boolean_mono_info;
+		break;
+	case SNDRV_CTL_ELEM_TYPE_ENUMERATED:
+		cont.info = snd_wm8776_enum_info;
+		break;
+	default:
+		return -EINVAL;
+	}
+	ctl = snd_ctl_new1(&cont, wm);
+	if (!ctl)
+		return -ENOMEM;
+
+	return snd_ctl_add(wm->card, ctl);
+}
+
+int snd_wm8776_build_controls(struct snd_wm8776 *wm)
+{
+	int err, i;
+
+	for (i = 0; i < WM8776_CTL_COUNT; i++)
+		if (wm->ctl[i].name) {
+			err = snd_wm8776_add_control(wm, i);
+			if (err < 0)
+				return err;
+		}
+
+	return 0;
+}
+EXPORT_SYMBOL(snd_wm8776_build_controls);
+
+static int __init alsa_wm8776_module_init(void)
+{
+	return 0;
+}
+
+static void __exit alsa_wm8776_module_exit(void)
+{
+}
+
+module_init(alsa_wm8776_module_init)
+module_exit(alsa_wm8776_module_exit)
-- 
Ondrej Zary


^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH 4/4] snd-ice1712: Add Philips PSC724 Ultimate Edge
  2012-04-16 21:18 [RFC PATCH 0/4] snd-ice1712: Add Philips PSC724 Ultimate Edge Ondrej Zary
                   ` (2 preceding siblings ...)
  2012-04-16 21:18 ` [PATCH 3/4] Add Wolfson Microelectronics WM8776 " Ondrej Zary
@ 2012-04-16 21:18 ` Ondrej Zary
  3 siblings, 0 replies; 37+ messages in thread
From: Ondrej Zary @ 2012-04-16 21:18 UTC (permalink / raw)
  To: alsa-devel; +Cc: linux-kernel

Add psc724 subdriver to snd-ice1712 that provides full support for
Philips PSC724 Ultimate Edge sound cards. Outputs and inputs are provided
by WM8766 and WM8776 codec drivers.

Signed-off-by: Ondrej Zary <linux@rainbow-software.org>
---
 sound/pci/ice1712/Makefile  |    2 +-
 sound/pci/ice1712/ice1724.c |    4 +-
 sound/pci/ice1712/psc724.c  |  446 +++++++++++++++++++++++++++++++++++++++++++
 sound/pci/ice1712/psc724.h  |   13 ++
 4 files changed, 463 insertions(+), 2 deletions(-)
 create mode 100644 sound/pci/ice1712/psc724.c
 create mode 100644 sound/pci/ice1712/psc724.h

diff --git a/sound/pci/ice1712/Makefile b/sound/pci/ice1712/Makefile
index f7ce33f..6d6ae06 100644
--- a/sound/pci/ice1712/Makefile
+++ b/sound/pci/ice1712/Makefile
@@ -5,7 +5,7 @@
 
 snd-ice17xx-ak4xxx-objs := ak4xxx.o
 snd-ice1712-objs := ice1712.o delta.o hoontech.o ews.o
-snd-ice1724-objs := ice1724.o amp.o revo.o aureon.o vt1720_mobo.o pontis.o prodigy192.o prodigy_hifi.o juli.o phase.o wtm.o se.o maya44.o quartet.o
+snd-ice1724-objs := ice1724.o amp.o revo.o aureon.o vt1720_mobo.o pontis.o prodigy192.o prodigy_hifi.o juli.o phase.o wtm.o se.o maya44.o quartet.o psc724.o
 
 # Toplevel Module Dependency
 obj-$(CONFIG_SND_ICE1712) += snd-ice1712.o snd-ice17xx-ak4xxx.o
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c
index ea686c4..f76e8a8 100644
--- a/sound/pci/ice1712/ice1724.c
+++ b/sound/pci/ice1712/ice1724.c
@@ -54,6 +54,7 @@
 #include "wtm.h"
 #include "se.h"
 #include "quartet.h"
+#include "psc724.h"
 
 MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
 MODULE_DESCRIPTION("VIA ICEnsemble ICE1724/1720 (Envy24HT/PT)");
@@ -2234,6 +2235,7 @@ static struct snd_ice1712_card_info *card_tables[] __devinitdata = {
 	snd_vt1724_se_cards,
 	snd_vt1724_qtet_cards,
 	snd_vt1724_ooaoo_cards,
+	snd_vt1724_psc724_cards,
 	NULL,
 };
 
@@ -2349,7 +2351,7 @@ static int __devinit snd_vt1724_read_eeprom(struct snd_ice1712 *ice,
 		return -EIO;
 	}
 	ice->eeprom.version = snd_vt1724_read_i2c(ice, dev, 0x05);
-	if (ice->eeprom.version != 2)
+	if (ice->eeprom.version != 1 && ice->eeprom.version != 2)
 		printk(KERN_WARNING "ice1724: Invalid EEPROM version %i\n",
 		       ice->eeprom.version);
 	size = ice->eeprom.size - 6;
diff --git a/sound/pci/ice1712/psc724.c b/sound/pci/ice1712/psc724.c
new file mode 100644
index 0000000..f00eda0
--- /dev/null
+++ b/sound/pci/ice1712/psc724.c
@@ -0,0 +1,446 @@
+/*
+ *   ALSA driver for ICEnsemble VT1724 (Envy24HT)
+ *
+ *   Lowlevel functions for Philips PSC724 Ultimate Edge
+ *
+ *	Copyright (c) 2012 Ondrej Zary <linux@rainbow-software.org>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <sound/core.h>
+
+#include "ice1712.h"
+#include "envy24ht.h"
+#include "psc724.h"
+#include "sound/wm8766.h"
+#include "sound/wm8776.h"
+
+struct psc724_spec {
+	struct snd_wm8766 wm8766;
+	struct snd_wm8776 wm8776;
+	bool mute_all, jack_detect;
+	struct snd_ice1712 *ice;
+	struct delayed_work hp_work;
+	bool hp_connected;
+};
+
+/****************************************************************************/
+/*  PHILIPS PSC724 ULTIMATE EDGE                                            */
+/****************************************************************************/
+/*
+ *  VT1722 (Envy24GT) - 6 outputs, 4 inputs (only 2 used), 24-bit/96kHz
+ *
+ *  system configuration ICE_EEP2_SYSCONF=0x42
+ *    XIN1 49.152MHz
+ *    no MPU401
+ *    one stereo ADC, no S/PDIF receiver
+ *    three stereo DACs (FRONT, REAR, CENTER+LFE)
+ *
+ *  AC-Link configuration ICE_EEP2_ACLINK=0x80
+ *    use I2S, not AC97
+ *
+ *  I2S converters feature ICE_EEP2_I2S=0x30
+ *    I2S codec has no volume/mute control feature (bug!)
+ *    I2S codec does not support 96KHz or 192KHz (bug!)
+ *    I2S codec 24bits
+ *
+ *  S/PDIF configuration ICE_EEP2_SPDIF=0xc1
+ *    Enable integrated S/PDIF transmitter
+ *    internal S/PDIF out implemented
+ *    No S/PDIF input
+ *    External S/PDIF out implemented
+ *
+ *
+ * ** connected chips **
+ *
+ *  WM8776
+ *     2-channel DAC used for main output and stereo ADC (with 10-channel MUX)
+ *     AIN1: LINE IN, AIN2: CD/VIDEO, AIN3: AUX, AIN4: Front MIC, AIN5: Rear MIC
+ *     Controlled by I2C using VT1722 I2C interface:
+ *          MODE (pin16) -- GND
+ *          CE   (pin17) -- GND  I2C mode (address=0x34)
+ *          DI   (pin18) -- SDA  (VT1722 pin70)
+ *          CL   (pin19) -- SCLK (VT1722 pin71)
+ *
+ *  WM8766
+ *      6-channel DAC used for rear & center/LFE outputs (only 4 channels used)
+ *      Controlled by SPI using VT1722 GPIO pins:
+ *          MODE   (pin 1) -- GPIO19 (VT1722 pin99)
+ *          ML/I2S (pin11) -- GPIO18 (VT1722 pin98)
+ *          MC/IWL (pin12) -- GPIO17 (VT1722 pin97)
+ *          MD/DM  (pin13) -- GPIO16 (VT1722 pin96)
+ *          MUTE   (pin14) -- GPIO20 (VT1722 pin101)
+ *
+ *  GPIO14 is used as input for headphone jack detection (1 = connected)
+ *  GPIO22 is used as MUTE ALL output, grounding all 6 channels
+ *
+ * ** output pins and device names **
+ *
+ *   5.1ch name -- output connector color -- device (-D option)
+ *
+ *      FRONT 2ch                  -- green  -- plughw:0,0
+ *      CENTER(Lch) SUBWOOFER(Rch) -- orange -- plughw:0,2,0
+ *      REAR 2ch                   -- black  -- plughw:0,2,1
+ */
+
+/* codec access low-level functions */
+
+#define GPIO_HP_JACK	(1 << 14)
+#define GPIO_MUTE_SUR	(1 << 20)
+#define GPIO_MUTE_ALL	(1 << 22)
+
+#define JACK_INTERVAL	1000
+
+#define PSC724_SPI_DELAY 1
+
+#define PSC724_SPI_DATA	(1 << 16)
+#define PSC724_SPI_CLK	(1 << 17)
+#define PSC724_SPI_LOAD	(1 << 18)
+#define PSC724_SPI_MASK	(PSC724_SPI_DATA | PSC724_SPI_CLK | PSC724_SPI_LOAD)
+
+static void psc724_wm8766_write(struct snd_wm8766 *wm, u16 addr, u16 data)
+{
+	struct psc724_spec *spec = container_of(wm, struct psc724_spec, wm8766);
+	struct snd_ice1712 *ice = spec->ice;
+	u32 st, bits;
+	int i;
+
+	snd_ice1712_save_gpio_status(ice);
+
+	st = ((addr & 0x7f) << 9) | (data & 0x1ff);
+	snd_ice1712_gpio_set_dir(ice, ice->gpio.direction | PSC724_SPI_MASK);
+	snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask & ~PSC724_SPI_MASK);
+	bits = snd_ice1712_gpio_read(ice) & ~PSC724_SPI_MASK;
+	snd_ice1712_gpio_write(ice, bits);
+
+	for (i = 0; i < 16; i++) {
+		udelay(PSC724_SPI_DELAY);
+		bits &= ~PSC724_SPI_CLK;
+		/* MSB first */
+		st <<= 1;
+		if (st & 0x10000)
+			bits |= PSC724_SPI_DATA;
+		else
+			bits &= ~PSC724_SPI_DATA;
+		snd_ice1712_gpio_write(ice, bits);
+		/* CLOCK high */
+		udelay(PSC724_SPI_DELAY);
+		bits |= PSC724_SPI_CLK;
+		snd_ice1712_gpio_write(ice, bits);
+	}
+	/* LOAD high */
+	udelay(PSC724_SPI_DELAY);
+	bits |= PSC724_SPI_LOAD;
+	snd_ice1712_gpio_write(ice, bits);
+	/* LOAD low, DATA and CLOCK high */
+	udelay(PSC724_SPI_DELAY);
+	bits |= (PSC724_SPI_DATA | PSC724_SPI_CLK);
+	snd_ice1712_gpio_write(ice, bits);
+
+	snd_ice1712_restore_gpio_status(ice);
+}
+
+static void psc724_wm8776_write(struct snd_wm8776 *wm, u8 addr, u8 data)
+{
+	struct psc724_spec *spec = container_of(wm, struct psc724_spec, wm8776);
+
+	snd_vt1724_write_i2c(spec->ice, 0x34, addr, data);
+}
+
+/* mute all */
+
+static void psc724_set_master_switch(struct snd_ice1712 *ice, bool on)
+{
+	unsigned int bits = snd_ice1712_gpio_read(ice);
+	struct psc724_spec *spec = ice->spec;
+
+	spec->mute_all = !on;
+	if (on)
+		bits &= ~(GPIO_MUTE_ALL | GPIO_MUTE_SUR);
+	else
+		bits |= GPIO_MUTE_ALL | GPIO_MUTE_SUR;
+	snd_ice1712_gpio_write(ice, bits);
+}
+
+static bool psc724_get_master_switch(struct snd_ice1712 *ice)
+{
+	struct psc724_spec *spec = ice->spec;
+
+	return !spec->mute_all;
+}
+
+/* jack detection */
+
+static void psc724_set_jack_state(struct snd_ice1712 *ice, bool hp_connected)
+{
+	struct psc724_spec *spec = ice->spec;
+	struct snd_ctl_elem_id elem_id;
+	struct snd_kcontrol *kctl;	
+	u16 power = spec->wm8776.regs[WM8776_REG_PWRDOWN] & ~WM8776_PWR_HPPD;
+
+	psc724_set_master_switch(ice, !hp_connected);
+	if (!hp_connected)
+		power |= WM8776_PWR_HPPD;
+	snd_wm8776_set_power(&spec->wm8776, power);
+	spec->hp_connected = hp_connected;
+	/* notify about master speaker mute change */
+	memset(&elem_id, 0, sizeof(elem_id));
+	elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
+	strncpy(elem_id.name, "Master Speakers Playback Switch",
+						sizeof(elem_id.name));
+	kctl = snd_ctl_find_id(ice->card, &elem_id);
+	snd_ctl_notify(ice->card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id);
+	/* and headphone mute change */
+	strncpy(elem_id.name, spec->wm8776.ctl[WM8776_CTL_HP_SW].name,
+						sizeof(elem_id.name));
+	kctl = snd_ctl_find_id(ice->card, &elem_id);
+	snd_ctl_notify(ice->card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id);
+}
+
+static void psc724_update_hp_jack_state(struct work_struct *work)
+{
+	struct psc724_spec *spec = container_of(work, struct psc724_spec,
+						hp_work.work);
+	struct snd_ice1712 *ice = spec->ice;
+	bool hp_connected = snd_ice1712_gpio_read(ice) & GPIO_HP_JACK;
+
+	schedule_delayed_work(&spec->hp_work, msecs_to_jiffies(JACK_INTERVAL));
+	if (hp_connected == spec->hp_connected)
+		return;
+	psc724_set_jack_state(ice, hp_connected);
+}
+
+static void psc724_set_jack_detection(struct snd_ice1712 *ice, bool on)
+{
+	struct psc724_spec *spec = ice->spec;
+
+	if (spec->jack_detect == on)
+		return;
+
+	spec->jack_detect = on;
+	if (on) {
+		bool hp_connected = snd_ice1712_gpio_read(ice) & GPIO_HP_JACK;
+		psc724_set_jack_state(ice, hp_connected);
+		schedule_delayed_work(&spec->hp_work,
+					msecs_to_jiffies(JACK_INTERVAL));
+	} else
+		cancel_delayed_work_sync(&spec->hp_work);
+}
+
+static bool psc724_get_jack_detection(struct snd_ice1712 *ice)
+{
+	struct psc724_spec *spec = ice->spec;
+
+	return spec->jack_detect;
+}
+
+/* mixer controls */
+
+struct psc724_control {
+	char *name;
+	void (*set)(struct snd_ice1712 *ice, bool on);
+	bool (*get)(struct snd_ice1712 *ice);
+};
+
+static const struct psc724_control psc724_cont[] = {
+	{
+		.name = "Master Speakers Playback Switch",
+		.set = psc724_set_master_switch,
+		.get = psc724_get_master_switch,
+	},
+	{
+		.name = "Headphone Jack Detection Playback Switch",
+		.set = psc724_set_jack_detection,
+		.get = psc724_get_jack_detection,
+	},
+};
+
+static int psc724_ctl_get(struct snd_kcontrol *kcontrol,
+				  struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
+	int n = kcontrol->private_value;
+
+	ucontrol->value.integer.value[0] = psc724_cont[n].get(ice);
+
+	return 0;
+}
+
+static int psc724_ctl_put(struct snd_kcontrol *kcontrol,
+				  struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
+	int n = kcontrol->private_value;
+
+	psc724_cont[n].set(ice, ucontrol->value.integer.value[0]);
+
+	return 0;
+}
+
+static char *front_volume	= "Front Playback Volume";
+static char *front_switch	= "Front Playback Switch";
+static char *front_zc		= "Front Zero Cross Detect Playback Switch";
+static char *front_izd		= "Front Infinite Zero Detect Playback Switch";
+static char *front_phase	= "Front Phase Invert Playback Switch";
+static char *front_deemph	= "Front Deemphasis Playback Switch";
+static char *ain1_switch	= "Line Capture Switch";
+static char *ain2_switch	= "CD Capture Switch";
+static char *ain3_switch	= "AUX Capture Switch";
+static char *ain4_switch	= "Front Mic Capture Switch";
+static char *ain5_switch	= "Rear Mic Capture Switch";
+static char *rear_volume	= "Surround Playback Volume";
+static char *clfe_volume	= "CLFE Playback Volume";
+static char *rear_switch	= "Surround Playback Switch";
+static char *clfe_switch	= "CLFE Playback Switch";
+static char *rear_phase		= "Surround Phase Invert Playback Switch";
+static char *clfe_phase		= "CLFE Phase Invert Playback Switch";
+static char *rear_deemph	= "Surround Deemphasis Playback Switch";
+static char *clfe_deemph	= "CLFE Deemphasis Playback Switch";
+static char *rear_clfe_izd	= "Rear Infinite Zero Detect Playback Switch";
+static char *rear_clfe_zc	= "Rear Zero Cross Detect Playback Switch";
+
+static int __devinit psc724_add_controls(struct snd_ice1712 *ice)
+{
+	struct snd_kcontrol_new cont;
+	struct snd_kcontrol *ctl;
+	int err, i;
+	struct psc724_spec *spec = ice->spec;
+
+	spec->wm8776.ctl[WM8776_CTL_DAC_VOL].name = front_volume;
+	spec->wm8776.ctl[WM8776_CTL_DAC_SW].name = front_switch;
+	spec->wm8776.ctl[WM8776_CTL_DAC_ZC_SW].name = front_zc;
+	spec->wm8776.ctl[WM8776_CTL_AUX_SW].name = NULL;
+	spec->wm8776.ctl[WM8776_CTL_DAC_IZD_SW].name = front_izd;
+	spec->wm8776.ctl[WM8776_CTL_PHASE_SW].name = front_phase;
+	spec->wm8776.ctl[WM8776_CTL_DEEMPH_SW].name = front_deemph;
+	spec->wm8776.ctl[WM8776_CTL_INPUT1_SW].name = ain1_switch;
+	spec->wm8776.ctl[WM8776_CTL_INPUT2_SW].name = ain2_switch;
+	spec->wm8776.ctl[WM8776_CTL_INPUT3_SW].name = ain3_switch;
+	spec->wm8776.ctl[WM8776_CTL_INPUT4_SW].name = ain4_switch;
+	spec->wm8776.ctl[WM8776_CTL_INPUT5_SW].name = ain5_switch;
+	snd_wm8776_build_controls(&spec->wm8776);
+	spec->wm8766.ctl[WM8766_CTL_CH1_VOL].name = rear_volume;
+	spec->wm8766.ctl[WM8766_CTL_CH2_VOL].name = clfe_volume;
+	spec->wm8766.ctl[WM8766_CTL_CH3_VOL].name = NULL;
+	spec->wm8766.ctl[WM8766_CTL_CH1_SW].name = rear_switch;
+	spec->wm8766.ctl[WM8766_CTL_CH2_SW].name = clfe_switch;
+	spec->wm8766.ctl[WM8766_CTL_CH3_SW].name = NULL;
+	spec->wm8766.ctl[WM8766_CTL_PHASE1_SW].name = rear_phase;
+	spec->wm8766.ctl[WM8766_CTL_PHASE2_SW].name = clfe_phase;
+	spec->wm8766.ctl[WM8766_CTL_PHASE3_SW].name = NULL;
+	spec->wm8766.ctl[WM8766_CTL_DEEMPH1_SW].name = rear_deemph;
+	spec->wm8766.ctl[WM8766_CTL_DEEMPH2_SW].name = clfe_deemph;
+	spec->wm8766.ctl[WM8766_CTL_DEEMPH3_SW].name = NULL;
+	spec->wm8766.ctl[WM8766_CTL_IZD_SW].name = rear_clfe_izd;
+	spec->wm8766.ctl[WM8766_CTL_ZC_SW].name = rear_clfe_zc;
+	snd_wm8766_build_controls(&spec->wm8766);
+
+	memset(&cont, 0, sizeof(cont));
+	cont.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
+	for (i = 0; i < ARRAY_SIZE(psc724_cont); i++) {
+		cont.private_value = i;
+		cont.name = psc724_cont[i].name;
+		cont.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
+		cont.info = snd_ctl_boolean_mono_info;
+		cont.get = psc724_ctl_get;
+		cont.put = psc724_ctl_put;
+		ctl = snd_ctl_new1(&cont, ice);
+		if (!ctl)
+			return -ENOMEM;
+		err = snd_ctl_add(ice->card, ctl);
+		if (err < 0)
+			return err;
+	}
+
+	return 0;
+}
+
+static void psc724_set_pro_rate(struct snd_ice1712 *ice, unsigned int rate)
+{
+	struct psc724_spec *spec = ice->spec;
+	/* restore codec volume settings after rate change (PMCLK stop) */
+	snd_wm8776_volume_restore(&spec->wm8776);
+	snd_wm8766_volume_restore(&spec->wm8766);
+}
+
+/* init */
+
+static int __devinit psc724_init(struct snd_ice1712 *ice)
+{
+	struct psc724_spec *spec;
+
+	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
+	if (!spec)
+		return -ENOMEM;
+	ice->spec = spec;
+	spec->ice = ice;
+
+	ice->num_total_dacs = 6;
+	ice->num_total_adcs = 2;
+	spec->wm8776.ops.write = psc724_wm8776_write;
+	spec->wm8776.card = ice->card;
+	snd_wm8776_init(&spec->wm8776);
+	spec->wm8766.ops.write = psc724_wm8766_write;
+	spec->wm8766.card = ice->card;
+	snd_wm8766_init(&spec->wm8766);
+	snd_wm8766_set_if(&spec->wm8766,
+			WM8766_IF_FMT_I2S | WM8766_IF_IWL_24BIT);
+	ice->gpio.set_pro_rate = psc724_set_pro_rate;
+	INIT_DELAYED_WORK(&spec->hp_work, psc724_update_hp_jack_state);
+	psc724_set_jack_detection(ice, true);
+	return 0;
+}
+
+static void psc724_exit(struct snd_ice1712 *ice)
+{
+	struct psc724_spec *spec = ice->spec;
+
+	cancel_delayed_work_sync(&spec->hp_work);
+}
+
+/* PSC724 has buggy EEPROM (no 96&192kHz, all FFh GPIOs), so override it here */
+static unsigned char psc724_eeprom[] __devinitdata = {
+	[ICE_EEP2_SYSCONF]	= 0x42,	/* 49.152MHz, 1 ADC, 3 DACs */
+	[ICE_EEP2_ACLINK]	= 0x80,	/* I2S */
+	[ICE_EEP2_I2S]		= 0xf0,	/* I2S volume, 96kHz, 24bit */
+	[ICE_EEP2_SPDIF]	= 0xc1,	/* spdif out-en, out-int, no input */
+	/* GPIO outputs */
+	[ICE_EEP2_GPIO_DIR2]	= 0x5f, /* MUTE_ALL,WM8766 MUTE/MODE/ML/MC/MD */
+	/* GPIO write enable */
+	[ICE_EEP2_GPIO_MASK]	= 0xff, /* read-only */
+	[ICE_EEP2_GPIO_MASK1]	= 0xff, /* read-only */
+	[ICE_EEP2_GPIO_MASK2]	= 0xa0, /* MUTE_ALL,WM8766 MUTE/MODE/ML/MC/MD */
+	/* GPIO initial state */
+	[ICE_EEP2_GPIO_STATE2]	= 0x20,	/* unmuted, all WM8766 pins low */
+};
+
+struct snd_ice1712_card_info snd_vt1724_psc724_cards[] __devinitdata = {
+	{
+		.subvendor = VT1724_SUBDEVICE_PSC724,
+		.name = "Philips PSC724 Ultimate Edge",
+		.model = "psc724",
+		.chip_init = psc724_init,
+		.chip_exit = psc724_exit,
+		.build_controls = psc724_add_controls,
+		.eeprom_size = sizeof(psc724_eeprom),
+		.eeprom_data = psc724_eeprom,
+	},
+	{} /*terminator*/
+};
diff --git a/sound/pci/ice1712/psc724.h b/sound/pci/ice1712/psc724.h
new file mode 100644
index 0000000..858e5fd
--- /dev/null
+++ b/sound/pci/ice1712/psc724.h
@@ -0,0 +1,13 @@
+#ifndef __SOUND_PSC724_H
+#define __SOUND_PSC724_H
+
+/* ID */
+#define PSC724_DEVICE_DESC	\
+		"{Philips,PSC724 Ultimate Edge},"
+
+#define VT1724_SUBDEVICE_PSC724		0xab170619
+
+/* entry struct */
+extern struct snd_ice1712_card_info snd_vt1724_psc724_cards[];
+
+#endif /* __SOUND_PSC724_H */
-- 
Ondrej Zary


^ permalink raw reply related	[flat|nested] 37+ messages in thread

* Re: [PATCH 2/4] Add Wolfson Microelectronics WM8766 codec ALSA driver
  2012-04-16 21:18 ` [PATCH 2/4] Add Wolfson Microelectronics WM8766 codec ALSA driver Ondrej Zary
@ 2012-04-17 14:59   ` Mark Brown
  2012-04-17 16:35     ` Ondrej Zary
  0 siblings, 1 reply; 37+ messages in thread
From: Mark Brown @ 2012-04-17 14:59 UTC (permalink / raw)
  To: Ondrej Zary; +Cc: alsa-devel, linux-kernel

On Mon, Apr 16, 2012 at 11:18:36PM +0200, Ondrej Zary wrote:
> Needed by Philips PSC724 subdriver. The code does not contain any
> card-specific bits so it can be used by any other ALSA driver.
> 
> Signed-off-by: Ondrej Zary <linux@rainbow-software.org>

Please CC me (and ideally all of patches@opensource.wolfsonmicro.com)
on any drivers for Wolfson devices.  It's not like we're secretive!

> ---
>  include/sound/wm8766.h   |  160 ++++++++++++++++++++
>  sound/i2c/other/Makefile |    3 +-
>  sound/i2c/other/wm8766.c |  374 ++++++++++++++++++++++++++++++++++++++++++++++

No, this should be supported in ASoC - anything adding new code in
sound/i2c is *deeply* suspicious.

> +struct snd_wm8766_ops {
> +	void (*write)(struct snd_wm8766 *wm, u16 addr, u16 data);
> +};

You should in general use regmap rather than open coding register I/O
for I2C devices.

> +void snd_wm8766_init(struct snd_wm8766 *wm);
> +void snd_wm8766_set_if(struct snd_wm8766 *wm, u16 dac);
> +void snd_wm8766_set_master_mode(struct snd_wm8766 *wm, u16 mode);
> +void snd_wm8766_set_power(struct snd_wm8766 *wm, u16 power);
> +void snd_wm8766_volume_restore(struct snd_wm8766 *wm);
> +int snd_wm8766_build_controls(struct snd_wm8766 *wm);

I've not yet looked at the rest of the code but this looks awfully like
you've just invented a minimal version of the ASoC interfaces...

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 3/4] Add Wolfson Microelectronics WM8776 codec ALSA driver
  2012-04-16 21:18 ` [PATCH 3/4] Add Wolfson Microelectronics WM8776 " Ondrej Zary
@ 2012-04-17 15:02   ` Mark Brown
  2012-04-17 16:13     ` Ondrej Zary
  0 siblings, 1 reply; 37+ messages in thread
From: Mark Brown @ 2012-04-17 15:02 UTC (permalink / raw)
  To: Ondrej Zary; +Cc: alsa-devel, linux-kernel

On Mon, Apr 16, 2012 at 11:18:37PM +0200, Ondrej Zary wrote:
> Needed by Philips PSC724 subdriver. The code does not contain any
> card-specific bits so it can be used by any other ALSA driver.

Same comments as the previous patch, this should be using ASoC.  In this
case the device has in fact been supported in mainline since 2.6.32...

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 3/4] Add Wolfson Microelectronics WM8776 codec ALSA driver
  2012-04-17 15:02   ` Mark Brown
@ 2012-04-17 16:13     ` Ondrej Zary
  2012-04-17 16:18       ` Mark Brown
  0 siblings, 1 reply; 37+ messages in thread
From: Ondrej Zary @ 2012-04-17 16:13 UTC (permalink / raw)
  To: Mark Brown; +Cc: alsa-devel, linux-kernel

On Tuesday 17 April 2012 17:02:34 Mark Brown wrote:
> On Mon, Apr 16, 2012 at 11:18:37PM +0200, Ondrej Zary wrote:
> > Needed by Philips PSC724 subdriver. The code does not contain any
> > card-specific bits so it can be used by any other ALSA driver.
>
> Same comments as the previous patch, this should be using ASoC.  In this
> case the device has in fact been supported in mainline since 2.6.32...

Yes, the driver is there - but I dont's see any way to use it. ASoC was not 
designed to be used with sound cards and nobody has ever used any ASoC driver 
in a sound card driver. I don't feel like breaking a working driver (with 16 
subdrivers for many more card types).

-- 
Ondrej Zary

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 3/4] Add Wolfson Microelectronics WM8776 codec ALSA driver
  2012-04-17 16:13     ` Ondrej Zary
@ 2012-04-17 16:18       ` Mark Brown
  2012-04-17 16:32           ` Takashi Iwai
  0 siblings, 1 reply; 37+ messages in thread
From: Mark Brown @ 2012-04-17 16:18 UTC (permalink / raw)
  To: Ondrej Zary; +Cc: alsa-devel, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 700 bytes --]

On Tue, Apr 17, 2012 at 06:13:40PM +0200, Ondrej Zary wrote:
> On Tuesday 17 April 2012 17:02:34 Mark Brown wrote:

> > Same comments as the previous patch, this should be using ASoC.  In this
> > case the device has in fact been supported in mainline since 2.6.32...

> Yes, the driver is there - but I dont's see any way to use it. ASoC was not 
> designed to be used with sound cards and nobody has ever used any ASoC driver 
> in a sound card driver. I don't feel like breaking a working driver (with 16 
> subdrivers for many more card types).

What makes you cleaim that "ASoC was not designed to be used with sound
cards"?  Implementing sound cards is the sole purpose of ASoC...

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [alsa-devel] [PATCH 3/4] Add Wolfson Microelectronics WM8776 codec ALSA driver
  2012-04-17 16:18       ` Mark Brown
@ 2012-04-17 16:32           ` Takashi Iwai
  0 siblings, 0 replies; 37+ messages in thread
From: Takashi Iwai @ 2012-04-17 16:32 UTC (permalink / raw)
  To: Mark Brown; +Cc: Ondrej Zary, alsa-devel, linux-kernel

At Tue, 17 Apr 2012 17:18:21 +0100,
Mark Brown wrote:
> 
> On Tue, Apr 17, 2012 at 06:13:40PM +0200, Ondrej Zary wrote:
> > On Tuesday 17 April 2012 17:02:34 Mark Brown wrote:
> 
> > > Same comments as the previous patch, this should be using ASoC.  In this
> > > case the device has in fact been supported in mainline since 2.6.32...
> 
> > Yes, the driver is there - but I dont's see any way to use it. ASoC was not 
> > designed to be used with sound cards and nobody has ever used any ASoC driver 
> > in a sound card driver. I don't feel like breaking a working driver (with 16 
> > subdrivers for many more card types).
> 
> What makes you cleaim that "ASoC was not designed to be used with sound
> cards"?  Implementing sound cards is the sole purpose of ASoC...

You don't need to overreact, he surely means only about the existing
ice1724 sound driver for his device :)

Restructuring ice1712 and ice1724 drivers to use ASoC would require
quite a lot of works, and no one really wants it, I guess.  Many
boards are old and can't be tested easily.  And, we still need to
match the ASoC components with the controls of the current driver.

This was already discussed a bit, and Clemens suggested like this
way.


thanks,

Takashi

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 3/4] Add Wolfson Microelectronics WM8776 codec ALSA driver
@ 2012-04-17 16:32           ` Takashi Iwai
  0 siblings, 0 replies; 37+ messages in thread
From: Takashi Iwai @ 2012-04-17 16:32 UTC (permalink / raw)
  To: Mark Brown; +Cc: alsa-devel, Ondrej Zary, linux-kernel

At Tue, 17 Apr 2012 17:18:21 +0100,
Mark Brown wrote:
> 
> On Tue, Apr 17, 2012 at 06:13:40PM +0200, Ondrej Zary wrote:
> > On Tuesday 17 April 2012 17:02:34 Mark Brown wrote:
> 
> > > Same comments as the previous patch, this should be using ASoC.  In this
> > > case the device has in fact been supported in mainline since 2.6.32...
> 
> > Yes, the driver is there - but I dont's see any way to use it. ASoC was not 
> > designed to be used with sound cards and nobody has ever used any ASoC driver 
> > in a sound card driver. I don't feel like breaking a working driver (with 16 
> > subdrivers for many more card types).
> 
> What makes you cleaim that "ASoC was not designed to be used with sound
> cards"?  Implementing sound cards is the sole purpose of ASoC...

You don't need to overreact, he surely means only about the existing
ice1724 sound driver for his device :)

Restructuring ice1712 and ice1724 drivers to use ASoC would require
quite a lot of works, and no one really wants it, I guess.  Many
boards are old and can't be tested easily.  And, we still need to
match the ASoC components with the controls of the current driver.

This was already discussed a bit, and Clemens suggested like this
way.


thanks,

Takashi

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 2/4] Add Wolfson Microelectronics WM8766 codec ALSA driver
  2012-04-17 14:59   ` Mark Brown
@ 2012-04-17 16:35     ` Ondrej Zary
  2012-04-17 16:54       ` Mark Brown
  0 siblings, 1 reply; 37+ messages in thread
From: Ondrej Zary @ 2012-04-17 16:35 UTC (permalink / raw)
  To: Mark Brown; +Cc: alsa-devel, linux-kernel

On Tuesday 17 April 2012 16:59:29 Mark Brown wrote:
> On Mon, Apr 16, 2012 at 11:18:36PM +0200, Ondrej Zary wrote:
> > Needed by Philips PSC724 subdriver. The code does not contain any
> > card-specific bits so it can be used by any other ALSA driver.
> >
> > Signed-off-by: Ondrej Zary <linux@rainbow-software.org>
>
> Please CC me (and ideally all of patches@opensource.wolfsonmicro.com)
> on any drivers for Wolfson devices.  It's not like we're secretive!
>
> > ---
> >  include/sound/wm8766.h   |  160 ++++++++++++++++++++
> >  sound/i2c/other/Makefile |    3 +-
> >  sound/i2c/other/wm8766.c |  374
> > ++++++++++++++++++++++++++++++++++++++++++++++
>
> No, this should be supported in ASoC - anything adding new code in
> sound/i2c is *deeply* suspicious.

I agree that sound/i2c is wrong. I worked on tea575x-tuner before which lives 
in this directory too - but it's neither an I2C device nor a sound chip...
There should probably be something like sound/codecs instead that could be 
used by any sound card drivers.

> > +struct snd_wm8766_ops {
> > +	void (*write)(struct snd_wm8766 *wm, u16 addr, u16 data);
> > +};
>
> You should in general use regmap rather than open coding register I/O
> for I2C devices.

regmap seems like an overkill here. It requires the i2c bus to be registered 
in the kernel i2c subsystem (which is not in the case of ice1712).

> > +void snd_wm8766_init(struct snd_wm8766 *wm);
> > +void snd_wm8766_set_if(struct snd_wm8766 *wm, u16 dac);
> > +void snd_wm8766_set_master_mode(struct snd_wm8766 *wm, u16 mode);
> > +void snd_wm8766_set_power(struct snd_wm8766 *wm, u16 power);
> > +void snd_wm8766_volume_restore(struct snd_wm8766 *wm);
> > +int snd_wm8766_build_controls(struct snd_wm8766 *wm);
>
> I've not yet looked at the rest of the code but this looks awfully like
> you've just invented a minimal version of the ASoC interfaces...

The _set functions are just simple register writes - the caller needs to know 
what to write there (only _set_if is used by psc724).

-- 
Ondrej Zary

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [alsa-devel] [PATCH 3/4] Add Wolfson Microelectronics WM8776 codec ALSA driver
  2012-04-17 16:32           ` Takashi Iwai
  (?)
@ 2012-04-17 16:50           ` Mark Brown
  2012-04-17 16:52               ` Takashi Iwai
  -1 siblings, 1 reply; 37+ messages in thread
From: Mark Brown @ 2012-04-17 16:50 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: Ondrej Zary, alsa-devel, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1065 bytes --]

On Tue, Apr 17, 2012 at 06:32:18PM +0200, Takashi Iwai wrote:
> Mark Brown wrote:

> > What makes you cleaim that "ASoC was not designed to be used with sound
> > cards"?  Implementing sound cards is the sole purpose of ASoC...

> You don't need to overreact, he surely means only about the existing
> ice1724 sound driver for his device :)

Possibly...  it's really not clear.

> Restructuring ice1712 and ice1724 drivers to use ASoC would require
> quite a lot of works, and no one really wants it, I guess.  Many
> boards are old and can't be tested easily.  And, we still need to
> match the ASoC components with the controls of the current driver.

> This was already discussed a bit, and Clemens suggested like this
> way.

This isn't just adding something into a specific driver which fails at
abstraction, it's adding generic code.  If it were adding something to
the ice17xx driver then that'd be one thing but look at the subject line
and location of the file...  this stuff should be buried inside the
driver if it's too painful to make the driver sane.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [alsa-devel] [PATCH 3/4] Add Wolfson Microelectronics WM8776 codec ALSA driver
  2012-04-17 16:50           ` [alsa-devel] " Mark Brown
@ 2012-04-17 16:52               ` Takashi Iwai
  0 siblings, 0 replies; 37+ messages in thread
From: Takashi Iwai @ 2012-04-17 16:52 UTC (permalink / raw)
  To: Mark Brown; +Cc: Ondrej Zary, alsa-devel, linux-kernel

At Tue, 17 Apr 2012 17:50:06 +0100,
Mark Brown wrote:
> 
> On Tue, Apr 17, 2012 at 06:32:18PM +0200, Takashi Iwai wrote:
> > Mark Brown wrote:
> 
> > > What makes you cleaim that "ASoC was not designed to be used with sound
> > > cards"?  Implementing sound cards is the sole purpose of ASoC...
> 
> > You don't need to overreact, he surely means only about the existing
> > ice1724 sound driver for his device :)
> 
> Possibly...  it's really not clear.
> 
> > Restructuring ice1712 and ice1724 drivers to use ASoC would require
> > quite a lot of works, and no one really wants it, I guess.  Many
> > boards are old and can't be tested easily.  And, we still need to
> > match the ASoC components with the controls of the current driver.
> 
> > This was already discussed a bit, and Clemens suggested like this
> > way.
> 
> This isn't just adding something into a specific driver which fails at
> abstraction, it's adding generic code.  If it were adding something to
> the ice17xx driver then that'd be one thing but look at the subject line
> and location of the file...  this stuff should be buried inside the
> driver if it's too painful to make the driver sane.

The codes in sound/i2c are mostly oly for ice1712/ice1724 drivers
after all...  They could be used by others, but I don't think there
will be any more at this point.


Takashi

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 3/4] Add Wolfson Microelectronics WM8776 codec ALSA driver
@ 2012-04-17 16:52               ` Takashi Iwai
  0 siblings, 0 replies; 37+ messages in thread
From: Takashi Iwai @ 2012-04-17 16:52 UTC (permalink / raw)
  To: Mark Brown; +Cc: alsa-devel, Ondrej Zary, linux-kernel

At Tue, 17 Apr 2012 17:50:06 +0100,
Mark Brown wrote:
> 
> On Tue, Apr 17, 2012 at 06:32:18PM +0200, Takashi Iwai wrote:
> > Mark Brown wrote:
> 
> > > What makes you cleaim that "ASoC was not designed to be used with sound
> > > cards"?  Implementing sound cards is the sole purpose of ASoC...
> 
> > You don't need to overreact, he surely means only about the existing
> > ice1724 sound driver for his device :)
> 
> Possibly...  it's really not clear.
> 
> > Restructuring ice1712 and ice1724 drivers to use ASoC would require
> > quite a lot of works, and no one really wants it, I guess.  Many
> > boards are old and can't be tested easily.  And, we still need to
> > match the ASoC components with the controls of the current driver.
> 
> > This was already discussed a bit, and Clemens suggested like this
> > way.
> 
> This isn't just adding something into a specific driver which fails at
> abstraction, it's adding generic code.  If it were adding something to
> the ice17xx driver then that'd be one thing but look at the subject line
> and location of the file...  this stuff should be buried inside the
> driver if it's too painful to make the driver sane.

The codes in sound/i2c are mostly oly for ice1712/ice1724 drivers
after all...  They could be used by others, but I don't think there
will be any more at this point.


Takashi

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 2/4] Add Wolfson Microelectronics WM8766 codec ALSA driver
  2012-04-17 16:35     ` Ondrej Zary
@ 2012-04-17 16:54       ` Mark Brown
  0 siblings, 0 replies; 37+ messages in thread
From: Mark Brown @ 2012-04-17 16:54 UTC (permalink / raw)
  To: Ondrej Zary; +Cc: alsa-devel, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1615 bytes --]

On Tue, Apr 17, 2012 at 06:35:32PM +0200, Ondrej Zary wrote:
> On Tuesday 17 April 2012 16:59:29 Mark Brown wrote:

> > No, this should be supported in ASoC - anything adding new code in
> > sound/i2c is *deeply* suspicious.

> I agree that sound/i2c is wrong. I worked on tea575x-tuner before which lives 
> in this directory too - but it's neither an I2C device nor a sound chip...
> There should probably be something like sound/codecs instead that could be 
> used by any sound card drivers.

That's what sound/soc/codecs is - anything with sufficiently split up
hardware to have distinct CODECs ought to be within that framework.
"soc" in this case to a large extent just means "mix and match CODEC and
CPU interface".

> > > +struct snd_wm8766_ops {
> > > +	void (*write)(struct snd_wm8766 *wm, u16 addr, u16 data);
> > > +};

> > You should in general use regmap rather than open coding register I/O
> > for I2C devices.

> regmap seems like an overkill here. It requires the i2c bus to be registered 
> in the kernel i2c subsystem (which is not in the case of ice1712).

Oh, that's fail.  I did notice that patch 4 looked to be open coding
rather generic stuff - I guess this is why.

> > I've not yet looked at the rest of the code but this looks awfully like
> > you've just invented a minimal version of the ASoC interfaces...

> The _set functions are just simple register writes - the caller needs to know 
> what to write there (only _set_if is used by psc724).

You can obviously do stuff as hard coded register write sequences, many
of which will be very short.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [alsa-devel] [PATCH 3/4] Add Wolfson Microelectronics WM8776 codec ALSA driver
  2012-04-17 16:52               ` Takashi Iwai
  (?)
@ 2012-04-17 17:04               ` Mark Brown
  2012-04-17 18:06                 ` Takashi Iwai
  -1 siblings, 1 reply; 37+ messages in thread
From: Mark Brown @ 2012-04-17 17:04 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: Ondrej Zary, alsa-devel, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1068 bytes --]

On Tue, Apr 17, 2012 at 06:52:49PM +0200, Takashi Iwai wrote:
> Mark Brown wrote:

> > This isn't just adding something into a specific driver which fails at
> > abstraction, it's adding generic code.  If it were adding something to
> > the ice17xx driver then that'd be one thing but look at the subject line
> > and location of the file...  this stuff should be buried inside the
> > driver if it's too painful to make the driver sane.

> The codes in sound/i2c are mostly oly for ice1712/ice1724 drivers
> after all...  They could be used by others, but I don't think there
> will be any more at this point.

If they're specific to that driver we should make them specific to that
driver and make sure the pain is confined there.  We really don't want
to end up going back to the bad old days of having to do per-CPU/card
drivers for CODECs because nobody had thought to abstract this stuff,
that just makes everyone miserable.

Looking at these commits I'd not expect anyone to figure out that this
isn't how we want or expect people to add generic CODEC drivers.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [alsa-devel] [PATCH 3/4] Add Wolfson Microelectronics WM8776 codec ALSA driver
  2012-04-17 17:04               ` [alsa-devel] " Mark Brown
@ 2012-04-17 18:06                 ` Takashi Iwai
  2012-04-17 18:15                     ` Ondrej Zary
  0 siblings, 1 reply; 37+ messages in thread
From: Takashi Iwai @ 2012-04-17 18:06 UTC (permalink / raw)
  To: Mark Brown; +Cc: Ondrej Zary, alsa-devel, linux-kernel

At Tue, 17 Apr 2012 18:04:31 +0100,
Mark Brown wrote:
> 

> On Tue, Apr 17, 2012 at 06:52:49PM +0200, Takashi Iwai wrote:
> > Mark Brown wrote:
> 
> > > This isn't just adding something into a specific driver which fails at
> > > abstraction, it's adding generic code.  If it were adding something to
> > > the ice17xx driver then that'd be one thing but look at the subject line
> > > and location of the file...  this stuff should be buried inside the
> > > driver if it's too painful to make the driver sane.
> 
> > The codes in sound/i2c are mostly oly for ice1712/ice1724 drivers
> > after all...  They could be used by others, but I don't think there
> > will be any more at this point.
> 
> If they're specific to that driver we should make them specific to that
> driver and make sure the pain is confined there.  We really don't want
> to end up going back to the bad old days of having to do per-CPU/card
> drivers for CODECs because nobody had thought to abstract this stuff,
> that just makes everyone miserable.
> 
> Looking at these commits I'd not expect anyone to figure out that this
> isn't how we want or expect people to add generic CODEC drivers.

Yeah, these stuff can be better put in pci/ice1712/ directory only
for ice1724 driver.  In that way, you can avoid unnecessary exported
symbols, too.


Takashi

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [alsa-devel] [PATCH 3/4] Add Wolfson Microelectronics WM8776 codec ALSA driver
  2012-04-17 18:06                 ` Takashi Iwai
@ 2012-04-17 18:15                     ` Ondrej Zary
  0 siblings, 0 replies; 37+ messages in thread
From: Ondrej Zary @ 2012-04-17 18:15 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: Mark Brown, alsa-devel, linux-kernel

On Tuesday 17 April 2012 20:06:19 Takashi Iwai wrote:
> At Tue, 17 Apr 2012 18:04:31 +0100,
>
> Mark Brown wrote:
> > On Tue, Apr 17, 2012 at 06:52:49PM +0200, Takashi Iwai wrote:
> > > Mark Brown wrote:
> > > > This isn't just adding something into a specific driver which fails
> > > > at abstraction, it's adding generic code.  If it were adding
> > > > something to the ice17xx driver then that'd be one thing but look at
> > > > the subject line and location of the file...  this stuff should be
> > > > buried inside the driver if it's too painful to make the driver sane.
> > >
> > > The codes in sound/i2c are mostly oly for ice1712/ice1724 drivers
> > > after all...  They could be used by others, but I don't think there
> > > will be any more at this point.
> >
> > If they're specific to that driver we should make them specific to that
> > driver and make sure the pain is confined there.  We really don't want
> > to end up going back to the bad old days of having to do per-CPU/card
> > drivers for CODECs because nobody had thought to abstract this stuff,
> > that just makes everyone miserable.
> >
> > Looking at these commits I'd not expect anyone to figure out that this
> > isn't how we want or expect people to add generic CODEC drivers.
>
> Yeah, these stuff can be better put in pci/ice1712/ directory only
> for ice1724 driver.  In that way, you can avoid unnecessary exported
> symbols, too.

Xonar (oxygen) has a private version of these drivers too. It could be 
converted to use common code instead.

-- 
Ondrej Zary

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 3/4] Add Wolfson Microelectronics WM8776 codec ALSA driver
@ 2012-04-17 18:15                     ` Ondrej Zary
  0 siblings, 0 replies; 37+ messages in thread
From: Ondrej Zary @ 2012-04-17 18:15 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel, Mark Brown, linux-kernel

On Tuesday 17 April 2012 20:06:19 Takashi Iwai wrote:
> At Tue, 17 Apr 2012 18:04:31 +0100,
>
> Mark Brown wrote:
> > On Tue, Apr 17, 2012 at 06:52:49PM +0200, Takashi Iwai wrote:
> > > Mark Brown wrote:
> > > > This isn't just adding something into a specific driver which fails
> > > > at abstraction, it's adding generic code.  If it were adding
> > > > something to the ice17xx driver then that'd be one thing but look at
> > > > the subject line and location of the file...  this stuff should be
> > > > buried inside the driver if it's too painful to make the driver sane.
> > >
> > > The codes in sound/i2c are mostly oly for ice1712/ice1724 drivers
> > > after all...  They could be used by others, but I don't think there
> > > will be any more at this point.
> >
> > If they're specific to that driver we should make them specific to that
> > driver and make sure the pain is confined there.  We really don't want
> > to end up going back to the bad old days of having to do per-CPU/card
> > drivers for CODECs because nobody had thought to abstract this stuff,
> > that just makes everyone miserable.
> >
> > Looking at these commits I'd not expect anyone to figure out that this
> > isn't how we want or expect people to add generic CODEC drivers.
>
> Yeah, these stuff can be better put in pci/ice1712/ directory only
> for ice1724 driver.  In that way, you can avoid unnecessary exported
> symbols, too.

Xonar (oxygen) has a private version of these drivers too. It could be 
converted to use common code instead.

-- 
Ondrej Zary

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [alsa-devel] [PATCH 3/4] Add Wolfson Microelectronics WM8776 codec ALSA driver
  2012-04-17 18:15                     ` Ondrej Zary
@ 2012-04-17 18:22                       ` Mark Brown
  -1 siblings, 0 replies; 37+ messages in thread
From: Mark Brown @ 2012-04-17 18:22 UTC (permalink / raw)
  To: Ondrej Zary; +Cc: Takashi Iwai, alsa-devel, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 510 bytes --]

On Tue, Apr 17, 2012 at 08:15:06PM +0200, Ondrej Zary wrote:
> On Tuesday 17 April 2012 20:06:19 Takashi Iwai wrote:

> > Yeah, these stuff can be better put in pci/ice1712/ directory only
> > for ice1724 driver.  In that way, you can avoid unnecessary exported
> > symbols, too.

> Xonar (oxygen) has a private version of these drivers too. It could be 
> converted to use common code instead.

Can we make a sound/legacy-codec or something?  Or fix these drivers if
they're actively developed...

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 3/4] Add Wolfson Microelectronics WM8776 codec ALSA driver
@ 2012-04-17 18:22                       ` Mark Brown
  0 siblings, 0 replies; 37+ messages in thread
From: Mark Brown @ 2012-04-17 18:22 UTC (permalink / raw)
  To: Ondrej Zary; +Cc: Takashi Iwai, alsa-devel, linux-kernel


[-- Attachment #1.1: Type: text/plain, Size: 510 bytes --]

On Tue, Apr 17, 2012 at 08:15:06PM +0200, Ondrej Zary wrote:
> On Tuesday 17 April 2012 20:06:19 Takashi Iwai wrote:

> > Yeah, these stuff can be better put in pci/ice1712/ directory only
> > for ice1724 driver.  In that way, you can avoid unnecessary exported
> > symbols, too.

> Xonar (oxygen) has a private version of these drivers too. It could be 
> converted to use common code instead.

Can we make a sound/legacy-codec or something?  Or fix these drivers if
they're actively developed...

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

[-- Attachment #2: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [alsa-devel] [PATCH 3/4] Add Wolfson Microelectronics WM8776 codec ALSA driver
  2012-04-17 18:15                     ` Ondrej Zary
  (?)
  (?)
@ 2012-04-17 19:12                     ` Takashi Iwai
  2012-04-17 21:07                         ` Ondrej Zary
  -1 siblings, 1 reply; 37+ messages in thread
From: Takashi Iwai @ 2012-04-17 19:12 UTC (permalink / raw)
  To: Ondrej Zary; +Cc: Mark Brown, alsa-devel, linux-kernel

At Tue, 17 Apr 2012 20:15:06 +0200,
Ondrej Zary wrote:
> 
> On Tuesday 17 April 2012 20:06:19 Takashi Iwai wrote:
> > At Tue, 17 Apr 2012 18:04:31 +0100,
> >
> > Mark Brown wrote:
> > > On Tue, Apr 17, 2012 at 06:52:49PM +0200, Takashi Iwai wrote:
> > > > Mark Brown wrote:
> > > > > This isn't just adding something into a specific driver which fails
> > > > > at abstraction, it's adding generic code.  If it were adding
> > > > > something to the ice17xx driver then that'd be one thing but look at
> > > > > the subject line and location of the file...  this stuff should be
> > > > > buried inside the driver if it's too painful to make the driver sane.
> > > >
> > > > The codes in sound/i2c are mostly oly for ice1712/ice1724 drivers
> > > > after all...  They could be used by others, but I don't think there
> > > > will be any more at this point.
> > >
> > > If they're specific to that driver we should make them specific to that
> > > driver and make sure the pain is confined there.  We really don't want
> > > to end up going back to the bad old days of having to do per-CPU/card
> > > drivers for CODECs because nobody had thought to abstract this stuff,
> > > that just makes everyone miserable.
> > >
> > > Looking at these commits I'd not expect anyone to figure out that this
> > > isn't how we want or expect people to add generic CODEC drivers.
> >
> > Yeah, these stuff can be better put in pci/ice1712/ directory only
> > for ice1724 driver.  In that way, you can avoid unnecessary exported
> > symbols, too.
> 
> Xonar (oxygen) has a private version of these drivers too. It could be 
> converted to use common code instead.

Hm, only if the generated controls do match with your case,..
It's case by case, especally if there is only one another candidate.


Takashi

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [alsa-devel] [PATCH 3/4] Add Wolfson Microelectronics WM8776 codec ALSA driver
  2012-04-17 18:22                       ` Mark Brown
  (?)
@ 2012-04-17 19:14                       ` Takashi Iwai
  2012-04-17 19:43                           ` Mark Brown
  -1 siblings, 1 reply; 37+ messages in thread
From: Takashi Iwai @ 2012-04-17 19:14 UTC (permalink / raw)
  To: Mark Brown; +Cc: Ondrej Zary, alsa-devel, linux-kernel

At Tue, 17 Apr 2012 19:22:05 +0100,
Mark Brown wrote:
> 
> On Tue, Apr 17, 2012 at 08:15:06PM +0200, Ondrej Zary wrote:
> > On Tuesday 17 April 2012 20:06:19 Takashi Iwai wrote:
> 
> > > Yeah, these stuff can be better put in pci/ice1712/ directory only
> > > for ice1724 driver.  In that way, you can avoid unnecessary exported
> > > symbols, too.
> 
> > Xonar (oxygen) has a private version of these drivers too. It could be 
> > converted to use common code instead.
> 
> Can we make a sound/legacy-codec or something?  Or fix these drivers if
> they're actively developed...

sound/i2c are obvious components for such drivers.
You don't have to react against each rare action.  There aren't so
many hardware any longer, and will be less and less in future.


Takashi

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [alsa-devel] [PATCH 3/4] Add Wolfson Microelectronics WM8776 codec ALSA driver
  2012-04-17 19:14                       ` [alsa-devel] " Takashi Iwai
@ 2012-04-17 19:43                           ` Mark Brown
  0 siblings, 0 replies; 37+ messages in thread
From: Mark Brown @ 2012-04-17 19:43 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: Ondrej Zary, alsa-devel, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 938 bytes --]

On Tue, Apr 17, 2012 at 09:14:49PM +0200, Takashi Iwai wrote:
> Mark Brown wrote:

> > Can we make a sound/legacy-codec or something?  Or fix these drivers if
> > they're actively developed...

> sound/i2c are obvious components for such drivers.
> You don't have to react against each rare action.  There aren't so
> many hardware any longer, and will be less and less in future.

That's the case in the PC world but obviously this is exactly how
essentially all embedded systems are built up.  It needs to be very
clear that this is just legacy code for these old PC sound cards and
nothing else, nothing about either the directory naming or the changelog
here suggests that this is anything other than the standard way to add
support for new CODECs to ALSA.

We usually have to go through a loop of "you need to use the frameworks"
with new vendors, we need to make the process of figuring out what they
should do as simple as we can.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 3/4] Add Wolfson Microelectronics WM8776 codec ALSA driver
@ 2012-04-17 19:43                           ` Mark Brown
  0 siblings, 0 replies; 37+ messages in thread
From: Mark Brown @ 2012-04-17 19:43 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel, Ondrej Zary, linux-kernel


[-- Attachment #1.1: Type: text/plain, Size: 938 bytes --]

On Tue, Apr 17, 2012 at 09:14:49PM +0200, Takashi Iwai wrote:
> Mark Brown wrote:

> > Can we make a sound/legacy-codec or something?  Or fix these drivers if
> > they're actively developed...

> sound/i2c are obvious components for such drivers.
> You don't have to react against each rare action.  There aren't so
> many hardware any longer, and will be less and less in future.

That's the case in the PC world but obviously this is exactly how
essentially all embedded systems are built up.  It needs to be very
clear that this is just legacy code for these old PC sound cards and
nothing else, nothing about either the directory naming or the changelog
here suggests that this is anything other than the standard way to add
support for new CODECs to ALSA.

We usually have to go through a loop of "you need to use the frameworks"
with new vendors, we need to make the process of figuring out what they
should do as simple as we can.

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

[-- Attachment #2: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 3/4] Add Wolfson Microelectronics WM8776 codec ALSA driver
  2012-04-17 19:43                           ` Mark Brown
  (?)
@ 2012-04-17 20:16                           ` Pavel Hofman
  2012-04-17 21:29                             ` Mark Brown
  -1 siblings, 1 reply; 37+ messages in thread
From: Pavel Hofman @ 2012-04-17 20:16 UTC (permalink / raw)
  To: Mark Brown; +Cc: Takashi Iwai, alsa-devel, Ondrej Zary

Dne 17.4.2012 21:43, Mark Brown napsal(a):
>
> That's the case in the PC world but obviously this is exactly how
> essentially all embedded systems are built up.  It needs to be very
> clear that this is just legacy code for these old PC sound cards and
> nothing else, nothing about either the directory naming or the changelog
> here suggests that this is anything other than the standard way to add
> support for new CODECs to ALSA.
>
> We usually have to go through a loop of "you need to use the frameworks"
> with new vendors, we need to make the process of figuring out what they
> should do as simple as we can.

Mark, I have always viewed alsa drivers as split to two parts

1. the "PC world" where mostly individual often amateur developers post 
patches improving support of the hardware they own.

2. the ASoC world of embedded solutions, where mostly vendors contribute 
patches for the hardware they produce. All ASoC posts are prefixed by 
ASoC and I have always viewed them as something I do not have to care 
about when fixing and developing stuff for PCI.

Even the until recently highly active intel-hda section does not use any 
of the ASoC infrastructure. If you read the ASoC documentation 
http://alsa-project.org/main/index.php/ASoC, it would not occur to me I 
should be using asoc codecs infrastructure for ice1724 card.

If you want these independent contributors to start using the kernel 
infrastructure common in the ASoC "tree", please tell them clearly on 
the alsa-project.org website, at best directly at 
http://alsa-project.org/main/index.php/Developer_Zone

Working hard on series of patches and being met with cold attitude as 
for not adhering to ASoC standards (quoting the alsa-project.org: "The 
overall project goal of the ALSA System on Chip (ASoC) layer is to 
provide better ALSA support for embedded system on chip procesors") the 
developer had no idea he was supposed to follow is not really 
motivating. And I think every helpful hand and brain counts here.

I can understand the very active ASoC subproject is defining current 
standards for the rest of alsa tree but please tell the currently valid 
rules to all the developers.

Thanks a lot for understanding,

Pavel.

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [alsa-devel] [PATCH 3/4] Add Wolfson Microelectronics WM8776 codec ALSA driver
  2012-04-17 19:12                     ` [alsa-devel] " Takashi Iwai
@ 2012-04-17 21:07                         ` Ondrej Zary
  0 siblings, 0 replies; 37+ messages in thread
From: Ondrej Zary @ 2012-04-17 21:07 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: Mark Brown, alsa-devel, linux-kernel

On Tuesday 17 April 2012 21:12:33 you wrote:
> At Tue, 17 Apr 2012 20:15:06 +0200,
>
> Ondrej Zary wrote:
> > On Tuesday 17 April 2012 20:06:19 Takashi Iwai wrote:
> > > At Tue, 17 Apr 2012 18:04:31 +0100,
> > >
> > > Mark Brown wrote:
> > > > On Tue, Apr 17, 2012 at 06:52:49PM +0200, Takashi Iwai wrote:
> > > > > Mark Brown wrote:
> > > > > > This isn't just adding something into a specific driver which
> > > > > > fails at abstraction, it's adding generic code.  If it were
> > > > > > adding something to the ice17xx driver then that'd be one thing
> > > > > > but look at the subject line and location of the file...  this
> > > > > > stuff should be buried inside the driver if it's too painful to
> > > > > > make the driver sane.
> > > > >
> > > > > The codes in sound/i2c are mostly oly for ice1712/ice1724 drivers
> > > > > after all...  They could be used by others, but I don't think there
> > > > > will be any more at this point.
> > > >
> > > > If they're specific to that driver we should make them specific to
> > > > that driver and make sure the pain is confined there.  We really
> > > > don't want to end up going back to the bad old days of having to do
> > > > per-CPU/card drivers for CODECs because nobody had thought to
> > > > abstract this stuff, that just makes everyone miserable.
> > > >
> > > > Looking at these commits I'd not expect anyone to figure out that
> > > > this isn't how we want or expect people to add generic CODEC drivers.
> > >
> > > Yeah, these stuff can be better put in pci/ice1712/ directory only
> > > for ice1724 driver.  In that way, you can avoid unnecessary exported
> > > symbols, too.
> >
> > Xonar (oxygen) has a private version of these drivers too. It could be
> > converted to use common code instead.
>
> Hm, only if the generated controls do match with your case,..
> It's case by case, especally if there is only one another candidate.

Control names can be changed (and also disabled) by the driver. In fact, 
psc724 does exactly this as is needs the WM8776 controls to be named 
as "front" and WM8766 as "rear".
I don't see any problem if something needs to be changed for this code to be 
used by Xonar (or some other driver).

-- 
Ondrej Zary

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 3/4] Add Wolfson Microelectronics WM8776 codec ALSA driver
@ 2012-04-17 21:07                         ` Ondrej Zary
  0 siblings, 0 replies; 37+ messages in thread
From: Ondrej Zary @ 2012-04-17 21:07 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel, Mark Brown, linux-kernel

On Tuesday 17 April 2012 21:12:33 you wrote:
> At Tue, 17 Apr 2012 20:15:06 +0200,
>
> Ondrej Zary wrote:
> > On Tuesday 17 April 2012 20:06:19 Takashi Iwai wrote:
> > > At Tue, 17 Apr 2012 18:04:31 +0100,
> > >
> > > Mark Brown wrote:
> > > > On Tue, Apr 17, 2012 at 06:52:49PM +0200, Takashi Iwai wrote:
> > > > > Mark Brown wrote:
> > > > > > This isn't just adding something into a specific driver which
> > > > > > fails at abstraction, it's adding generic code.  If it were
> > > > > > adding something to the ice17xx driver then that'd be one thing
> > > > > > but look at the subject line and location of the file...  this
> > > > > > stuff should be buried inside the driver if it's too painful to
> > > > > > make the driver sane.
> > > > >
> > > > > The codes in sound/i2c are mostly oly for ice1712/ice1724 drivers
> > > > > after all...  They could be used by others, but I don't think there
> > > > > will be any more at this point.
> > > >
> > > > If they're specific to that driver we should make them specific to
> > > > that driver and make sure the pain is confined there.  We really
> > > > don't want to end up going back to the bad old days of having to do
> > > > per-CPU/card drivers for CODECs because nobody had thought to
> > > > abstract this stuff, that just makes everyone miserable.
> > > >
> > > > Looking at these commits I'd not expect anyone to figure out that
> > > > this isn't how we want or expect people to add generic CODEC drivers.
> > >
> > > Yeah, these stuff can be better put in pci/ice1712/ directory only
> > > for ice1724 driver.  In that way, you can avoid unnecessary exported
> > > symbols, too.
> >
> > Xonar (oxygen) has a private version of these drivers too. It could be
> > converted to use common code instead.
>
> Hm, only if the generated controls do match with your case,..
> It's case by case, especally if there is only one another candidate.

Control names can be changed (and also disabled) by the driver. In fact, 
psc724 does exactly this as is needs the WM8776 controls to be named 
as "front" and WM8766 as "rear".
I don't see any problem if something needs to be changed for this code to be 
used by Xonar (or some other driver).

-- 
Ondrej Zary

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 3/4] Add Wolfson Microelectronics WM8776 codec ALSA driver
  2012-04-17 20:16                           ` Pavel Hofman
@ 2012-04-17 21:29                             ` Mark Brown
  2012-04-18  9:06                               ` Mark Brown
  0 siblings, 1 reply; 37+ messages in thread
From: Mark Brown @ 2012-04-17 21:29 UTC (permalink / raw)
  To: Pavel Hofman; +Cc: Takashi Iwai, alsa-devel, Ondrej Zary


[-- Attachment #1.1: Type: text/plain, Size: 3829 bytes --]

On Tue, Apr 17, 2012 at 10:16:01PM +0200, Pavel Hofman wrote:

> Mark, I have always viewed alsa drivers as split to two parts

> 1. the "PC world" where mostly individual often amateur developers
> post patches improving support of the hardware they own.

> 2. the ASoC world of embedded solutions, where mostly vendors
> contribute patches for the hardware they produce. All ASoC posts are

That's really not a good split - while audio seems to be one of the few
areas where embedded vendors are in the forefront of contributing code
for their own parts there's a fair amount of hobbyist work in the
embedded space too.  The first example that springs to mind is the
Kirkwood support which has never had any involvement at all from
Marvell.  Even where people are employed to work on the code they're
often not working for the device vendor but rather for some other
company who happens to be using the device.

> Even the until recently highly active intel-hda section does not use
> any of the ASoC infrastructure. If you read the ASoC documentation

It wouldn't be appropriate for HDA to use ASoC, the hardware has a
rather different model for how it's constructed - the main thing being
that obviously there's only one control interface for all devices and
you're supposed to be able to write a generic HDA driver which works on
any system using HDA.

> http://alsa-project.org/main/index.php/ASoC, it would not occur to
> me I should be using asoc codecs infrastructure for ice1724 card.

If you feel there's something that could be improved about the wiki
please contribute to it.  Though that said as far as I'm aware the ALSA
wiki is about as actively maintained as the bug tracker which we still
haven't managed to get shut down.  All the content I've ever had any
cause to look at is links to off site documentation, most of which are
now broken as they're to pre-breakin kernel.org, and most of what's
there is extremely old.

> Working hard on series of patches and being met with cold attitude
> as for not adhering to ASoC standards (quoting the alsa-project.org:

It's really the fact that it's not using ASoC, it's the fact that patch
here is adding a driver for a device which already has an in-tree
driver; that alone should be a very big warning sign.  Ending up with
two totally separate drivers for a single device is never a good idea,
if only from a duplication of work point of view.

I'd at least expect the presence of the existing driver to have prompted
a question along the lines of "I can't figure out how I'm supposed to
use this driver here, what am I missing?", or something in the changelog
indicating that this issue had been considered and that the duplication
is a sensible solution for whatever reason.

> If you want these independent contributors to start using the kernel
> infrastructure common in the ASoC "tree", please tell them clearly on
> the alsa-project.org website, at best directly at
> http://alsa-project.org/main/index.php/Developer_Zone

Again, if you feel the documentation needs to be improved please
contribute to the documentation.  I honestly can't see where I'd put any
information so that people would usefully find it, but then like I say
that's largely because it doesn't look like the wiki gets much use so
it'd put me off looking in the first place.  If you're saying people
actively use the wiki then probably you've got a better idea of where
they're looking in there.

> I can understand the very active ASoC subproject is defining current
> standards for the rest of alsa tree but please tell the currently
> valid rules to all the developers.

Like I say the major issue here is further back at the point where we're
ending up with two drivers for one bit of hardware.  That's not
something to do with knowing about ASoC, it's more general good
practice.

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

[-- Attachment #2: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [alsa-devel] [PATCH 3/4] Add Wolfson Microelectronics WM8776 codec ALSA driver
  2012-04-17 21:07                         ` Ondrej Zary
@ 2012-04-18  5:54                           ` Takashi Iwai
  -1 siblings, 0 replies; 37+ messages in thread
From: Takashi Iwai @ 2012-04-18  5:54 UTC (permalink / raw)
  To: Ondrej Zary; +Cc: Clemens Ladisch, Mark Brown, alsa-devel, linux-kernel

At Tue, 17 Apr 2012 23:07:48 +0200,
Ondrej Zary wrote:
> 
> On Tuesday 17 April 2012 21:12:33 you wrote:
> > At Tue, 17 Apr 2012 20:15:06 +0200,
> >
> > Ondrej Zary wrote:
> > > On Tuesday 17 April 2012 20:06:19 Takashi Iwai wrote:
> > > > At Tue, 17 Apr 2012 18:04:31 +0100,
> > > >
> > > > Mark Brown wrote:
> > > > > On Tue, Apr 17, 2012 at 06:52:49PM +0200, Takashi Iwai wrote:
> > > > > > Mark Brown wrote:
> > > > > > > This isn't just adding something into a specific driver which
> > > > > > > fails at abstraction, it's adding generic code.  If it were
> > > > > > > adding something to the ice17xx driver then that'd be one thing
> > > > > > > but look at the subject line and location of the file...  this
> > > > > > > stuff should be buried inside the driver if it's too painful to
> > > > > > > make the driver sane.
> > > > > >
> > > > > > The codes in sound/i2c are mostly oly for ice1712/ice1724 drivers
> > > > > > after all...  They could be used by others, but I don't think there
> > > > > > will be any more at this point.
> > > > >
> > > > > If they're specific to that driver we should make them specific to
> > > > > that driver and make sure the pain is confined there.  We really
> > > > > don't want to end up going back to the bad old days of having to do
> > > > > per-CPU/card drivers for CODECs because nobody had thought to
> > > > > abstract this stuff, that just makes everyone miserable.
> > > > >
> > > > > Looking at these commits I'd not expect anyone to figure out that
> > > > > this isn't how we want or expect people to add generic CODEC drivers.
> > > >
> > > > Yeah, these stuff can be better put in pci/ice1712/ directory only
> > > > for ice1724 driver.  In that way, you can avoid unnecessary exported
> > > > symbols, too.
> > >
> > > Xonar (oxygen) has a private version of these drivers too. It could be
> > > converted to use common code instead.
> >
> > Hm, only if the generated controls do match with your case,..
> > It's case by case, especally if there is only one another candidate.
> 
> Control names can be changed (and also disabled) by the driver. In fact, 
> psc724 does exactly this as is needs the WM8776 controls to be named 
> as "front" and WM8766 as "rear".
> I don't see any problem if something needs to be changed for this code to be 
> used by Xonar (or some other driver).

OK, it depends on Clemens, whether the shared code is preferred (and
maintainable).

If sharing your code between ice1724 and xonar is planned, sound/i2c
is the best place to put indeed.  In that case, better to start from
moving the code from xonar to sound/i2c, then reuse it in ice1724,
instead of having double codes in xonar and ice1724.

OTOH, if it isn't worthwhile, better to make all your code local to
ice1724.


thanks,

Takashi

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 3/4] Add Wolfson Microelectronics WM8776 codec ALSA driver
@ 2012-04-18  5:54                           ` Takashi Iwai
  0 siblings, 0 replies; 37+ messages in thread
From: Takashi Iwai @ 2012-04-18  5:54 UTC (permalink / raw)
  To: Ondrej Zary; +Cc: alsa-devel, Mark Brown, Clemens Ladisch, linux-kernel

At Tue, 17 Apr 2012 23:07:48 +0200,
Ondrej Zary wrote:
> 
> On Tuesday 17 April 2012 21:12:33 you wrote:
> > At Tue, 17 Apr 2012 20:15:06 +0200,
> >
> > Ondrej Zary wrote:
> > > On Tuesday 17 April 2012 20:06:19 Takashi Iwai wrote:
> > > > At Tue, 17 Apr 2012 18:04:31 +0100,
> > > >
> > > > Mark Brown wrote:
> > > > > On Tue, Apr 17, 2012 at 06:52:49PM +0200, Takashi Iwai wrote:
> > > > > > Mark Brown wrote:
> > > > > > > This isn't just adding something into a specific driver which
> > > > > > > fails at abstraction, it's adding generic code.  If it were
> > > > > > > adding something to the ice17xx driver then that'd be one thing
> > > > > > > but look at the subject line and location of the file...  this
> > > > > > > stuff should be buried inside the driver if it's too painful to
> > > > > > > make the driver sane.
> > > > > >
> > > > > > The codes in sound/i2c are mostly oly for ice1712/ice1724 drivers
> > > > > > after all...  They could be used by others, but I don't think there
> > > > > > will be any more at this point.
> > > > >
> > > > > If they're specific to that driver we should make them specific to
> > > > > that driver and make sure the pain is confined there.  We really
> > > > > don't want to end up going back to the bad old days of having to do
> > > > > per-CPU/card drivers for CODECs because nobody had thought to
> > > > > abstract this stuff, that just makes everyone miserable.
> > > > >
> > > > > Looking at these commits I'd not expect anyone to figure out that
> > > > > this isn't how we want or expect people to add generic CODEC drivers.
> > > >
> > > > Yeah, these stuff can be better put in pci/ice1712/ directory only
> > > > for ice1724 driver.  In that way, you can avoid unnecessary exported
> > > > symbols, too.
> > >
> > > Xonar (oxygen) has a private version of these drivers too. It could be
> > > converted to use common code instead.
> >
> > Hm, only if the generated controls do match with your case,..
> > It's case by case, especally if there is only one another candidate.
> 
> Control names can be changed (and also disabled) by the driver. In fact, 
> psc724 does exactly this as is needs the WM8776 controls to be named 
> as "front" and WM8766 as "rear".
> I don't see any problem if something needs to be changed for this code to be 
> used by Xonar (or some other driver).

OK, it depends on Clemens, whether the shared code is preferred (and
maintainable).

If sharing your code between ice1724 and xonar is planned, sound/i2c
is the best place to put indeed.  In that case, better to start from
moving the code from xonar to sound/i2c, then reuse it in ice1724,
instead of having double codes in xonar and ice1724.

OTOH, if it isn't worthwhile, better to make all your code local to
ice1724.


thanks,

Takashi

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [alsa-devel] [PATCH 3/4] Add Wolfson Microelectronics WM8776 codec ALSA driver
  2012-04-18  5:54                           ` Takashi Iwai
@ 2012-04-18  6:52                             ` Clemens Ladisch
  -1 siblings, 0 replies; 37+ messages in thread
From: Clemens Ladisch @ 2012-04-18  6:52 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: Ondrej Zary, Mark Brown, alsa-devel, linux-kernel

Takashi Iwai wrote:
> Ondrej Zary wrote:
>> On Tuesday 17 April 2012 21:12:33 you wrote:
>>> Ondrej Zary wrote:
>>>> Xonar (oxygen) has a private version of these drivers too. It could be
>>>> converted to use common code instead.
>>>
>>> Hm, only if the generated controls do match with your case,..
>>> It's case by case, especally if there is only one another candidate.
>>
>> Control names can be changed (and also disabled) by the driver. In fact,
>> psc724 does exactly this as is needs the WM8776 controls to be named
>> as "front" and WM8766 as "rear".
>> I don't see any problem if something needs to be changed for this code to be
>> used by Xonar (or some other driver).
>
> OK, it depends on Clemens, whether the shared code is preferred (and
> maintainable).

I've always planned to move the Xonar driver to the ASoC framework.
(I didn't at first because ASoC didn't support multiple codecs then.)
The only problem is finding time to do this ...

Sharing the code between ice1712 and xonar might be a first step.


Regards,
Clemens

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 3/4] Add Wolfson Microelectronics WM8776 codec ALSA driver
@ 2012-04-18  6:52                             ` Clemens Ladisch
  0 siblings, 0 replies; 37+ messages in thread
From: Clemens Ladisch @ 2012-04-18  6:52 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel, Mark Brown, Ondrej Zary, linux-kernel

Takashi Iwai wrote:
> Ondrej Zary wrote:
>> On Tuesday 17 April 2012 21:12:33 you wrote:
>>> Ondrej Zary wrote:
>>>> Xonar (oxygen) has a private version of these drivers too. It could be
>>>> converted to use common code instead.
>>>
>>> Hm, only if the generated controls do match with your case,..
>>> It's case by case, especally if there is only one another candidate.
>>
>> Control names can be changed (and also disabled) by the driver. In fact,
>> psc724 does exactly this as is needs the WM8776 controls to be named
>> as "front" and WM8766 as "rear".
>> I don't see any problem if something needs to be changed for this code to be
>> used by Xonar (or some other driver).
>
> OK, it depends on Clemens, whether the shared code is preferred (and
> maintainable).

I've always planned to move the Xonar driver to the ASoC framework.
(I didn't at first because ASoC didn't support multiple codecs then.)
The only problem is finding time to do this ...

Sharing the code between ice1712 and xonar might be a first step.


Regards,
Clemens

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 3/4] Add Wolfson Microelectronics WM8776 codec ALSA driver
  2012-04-17 21:29                             ` Mark Brown
@ 2012-04-18  9:06                               ` Mark Brown
  2012-04-18  9:27                                 ` Pavel Hofman
  0 siblings, 1 reply; 37+ messages in thread
From: Mark Brown @ 2012-04-18  9:06 UTC (permalink / raw)
  To: Pavel Hofman; +Cc: Takashi Iwai, alsa-devel, Ondrej Zary

On Tue, Apr 17, 2012 at 10:29:15PM +0100, Mark Brown wrote:
> On Tue, Apr 17, 2012 at 10:16:01PM +0200, Pavel Hofman wrote:

> > Working hard on series of patches and being met with cold attitude
> > as for not adhering to ASoC standards (quoting the alsa-project.org:

> It's really the fact that it's not using ASoC, it's the fact that patch

s/really/really not/

> > If you want these independent contributors to start using the kernel
> > infrastructure common in the ASoC "tree", please tell them clearly on

BTW, this probably deserves picking up a bit more: there's really no
distinction between commercial and non-commercial contributors, if
anything I'd say that on average the hobbyist contributors tend to be
working to a higher standard on average.

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 3/4] Add Wolfson Microelectronics WM8776 codec ALSA driver
  2012-04-18  9:06                               ` Mark Brown
@ 2012-04-18  9:27                                 ` Pavel Hofman
  2012-04-18 10:34                                   ` Mark Brown
  0 siblings, 1 reply; 37+ messages in thread
From: Pavel Hofman @ 2012-04-18  9:27 UTC (permalink / raw)
  To: Mark Brown; +Cc: Takashi Iwai, alsa-devel, Ondrej Zary

Dne 18.4.2012 11:06, Mark Brown napsal(a):
> On Tue, Apr 17, 2012 at 10:29:15PM +0100, Mark Brown wrote:
>> On Tue, Apr 17, 2012 at 10:16:01PM +0200, Pavel Hofman wrote:
> 
>>> Working hard on series of patches and being met with cold attitude
>>> as for not adhering to ASoC standards (quoting the alsa-project.org:
> 
>> It's really the fact that it's not using ASoC, it's the fact that patch
> 
> s/really/really not/
> 
>>> If you want these independent contributors to start using the kernel
>>> infrastructure common in the ASoC "tree", please tell them clearly on
> 
> BTW, this probably deserves picking up a bit more: there's really no
> distinction between commercial and non-commercial contributors, if
> anything I'd say that on average the hobbyist contributors tend to be
> working to a higher standard on average.

Mark, my whole point is most nonASoC alsa developers have no idea they
are supposed to use stuff in the asoc subdir for the drivers outside of
the asoc subtree. And I guess they mostly do not follow mailinglist
messages prefixed ASoC either.

If sound/asoc/codecs was in sound/codecs, they would certainly take a
look. But right now to them asoc really feels like a separate world.

I understand you would like to change that (or IOW - it would be
beneficial to whole alsa to change that), very good. That is why I am
talking about some guidelines for the non-asoc developers. I cannot
write them, I am one of those having lived in the old-ages dark so far :)

Thanks a lot,

Pavel.

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 3/4] Add Wolfson Microelectronics WM8776 codec ALSA driver
  2012-04-18  9:27                                 ` Pavel Hofman
@ 2012-04-18 10:34                                   ` Mark Brown
  0 siblings, 0 replies; 37+ messages in thread
From: Mark Brown @ 2012-04-18 10:34 UTC (permalink / raw)
  To: Pavel Hofman; +Cc: Takashi Iwai, alsa-devel, Ondrej Zary


[-- Attachment #1.1: Type: text/plain, Size: 2500 bytes --]

On Wed, Apr 18, 2012 at 11:27:05AM +0200, Pavel Hofman wrote:
> Dne 18.4.2012 11:06, Mark Brown napsal(a):

> > BTW, this probably deserves picking up a bit more: there's really no
> > distinction between commercial and non-commercial contributors, if
> > anything I'd say that on average the hobbyist contributors tend to be
> > working to a higher standard on average.

> Mark, my whole point is most nonASoC alsa developers have no idea they
> are supposed to use stuff in the asoc subdir for the drivers outside of
> the asoc subtree. And I guess they mostly do not follow mailinglist
> messages prefixed ASoC either.

You're not engaging with my core point here - the simple fact that
there is an existing driver for the device ought to be enough of a clue
to allow someone to figure out that there's a problem here.  This
doesn't really need understanding of the code.

> If sound/asoc/codecs was in sound/codecs, they would certainly take a
> look. But right now to them asoc really feels like a separate world.

To be honest if you're at the point where you're familiar enough with
development to be ignoring bits of the tree you don't normally work on
then not noticing the duplicate driver is in many ways even more
surprising.

If we're going to reorganise the tree then there's a whole bunch of
other things that could usefully be cleaned up like moving to drivers/
and cleaning up all the legacy embedded platforms.  This wouldn't be a
bad thing, I'm sure it's actually been discussed before.  I'd expect
we'd probably still end up with all these devices grouped together
though as organising by subframework does seem sensible, the issue is
more that we've got some things that are duplicating effort.

In fact I'm actually tempted to create a legacy subdirectory as a first
step...

> I understand you would like to change that (or IOW - it would be
> beneficial to whole alsa to change that), very good. That is why I am
> talking about some guidelines for the non-asoc developers. I cannot
> write them, I am one of those having lived in the old-ages dark so far :)

Well, it's pretty simple really - anything where the audio CODEC is a
distinct piece of hardware connected with I2S or similar format
interfaces ought to be using ASoC.

Aside from legacy drivers like this, and the few in media/ it's really
where we're at already.  We do from time to time get vendors trying to
submit their own custom stacks but they get just the same sort of
pushback for exactly the same reason.

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

[-- Attachment #2: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply	[flat|nested] 37+ messages in thread

end of thread, other threads:[~2012-04-18 10:34 UTC | newest]

Thread overview: 37+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-04-16 21:18 [RFC PATCH 0/4] snd-ice1712: Add Philips PSC724 Ultimate Edge Ondrej Zary
2012-04-16 21:18 ` [PATCH 1/4] snd-ice1712: add chip_exit callback Ondrej Zary
2012-04-16 21:18 ` [PATCH 2/4] Add Wolfson Microelectronics WM8766 codec ALSA driver Ondrej Zary
2012-04-17 14:59   ` Mark Brown
2012-04-17 16:35     ` Ondrej Zary
2012-04-17 16:54       ` Mark Brown
2012-04-16 21:18 ` [PATCH 3/4] Add Wolfson Microelectronics WM8776 " Ondrej Zary
2012-04-17 15:02   ` Mark Brown
2012-04-17 16:13     ` Ondrej Zary
2012-04-17 16:18       ` Mark Brown
2012-04-17 16:32         ` [alsa-devel] " Takashi Iwai
2012-04-17 16:32           ` Takashi Iwai
2012-04-17 16:50           ` [alsa-devel] " Mark Brown
2012-04-17 16:52             ` Takashi Iwai
2012-04-17 16:52               ` Takashi Iwai
2012-04-17 17:04               ` [alsa-devel] " Mark Brown
2012-04-17 18:06                 ` Takashi Iwai
2012-04-17 18:15                   ` Ondrej Zary
2012-04-17 18:15                     ` Ondrej Zary
2012-04-17 18:22                     ` [alsa-devel] " Mark Brown
2012-04-17 18:22                       ` Mark Brown
2012-04-17 19:14                       ` [alsa-devel] " Takashi Iwai
2012-04-17 19:43                         ` Mark Brown
2012-04-17 19:43                           ` Mark Brown
2012-04-17 20:16                           ` Pavel Hofman
2012-04-17 21:29                             ` Mark Brown
2012-04-18  9:06                               ` Mark Brown
2012-04-18  9:27                                 ` Pavel Hofman
2012-04-18 10:34                                   ` Mark Brown
2012-04-17 19:12                     ` [alsa-devel] " Takashi Iwai
2012-04-17 21:07                       ` Ondrej Zary
2012-04-17 21:07                         ` Ondrej Zary
2012-04-18  5:54                         ` [alsa-devel] " Takashi Iwai
2012-04-18  5:54                           ` Takashi Iwai
2012-04-18  6:52                           ` [alsa-devel] " Clemens Ladisch
2012-04-18  6:52                             ` Clemens Ladisch
2012-04-16 21:18 ` [PATCH 4/4] snd-ice1712: Add Philips PSC724 Ultimate Edge Ondrej Zary

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.