All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH 0/7] AC97 device/driver model revamp
@ 2016-04-30 21:15 ` Robert Jarzmik
  0 siblings, 0 replies; 74+ messages in thread
From: Robert Jarzmik @ 2016-04-30 21:15 UTC (permalink / raw)
  To: Robert Jarzmik, Daniel Mack, Haojian Zhuang, Jaroslav Kysela,
	Takashi Iwai, Liam Girdwood, Mark Brown
  Cc: linux-arm-kernel, linux-kernel, alsa-devel, patches

It all started in the pxa device-tree submission here :
   https://lkml.org/lkml/2016/2/25/965
It will be maintained in :
   git fetch https://github.com/rjarzmik/linux.git work/ac97

And now it transformed into this RFC, which would bring a ground for AC'97
devices closer to the linux device/driver model.

This is just an RFC to see if we understand each other Mark.

Amongst the driving ideas behind this RFC :
 - use device/driver model for AC'97
   device/driver binding is based on vendor_id{1,2}
 - use auto-probe of the AC'97 bus to enumerate codecs and create devices
 - be compatible with previous platform_data model for codecs
   => this enables a smooth transition, where a codec (here wm9713) can
      be used either through platform_device or automatic discovery
 - struct snd_ac97 is not used
   This structure is really heavy, and doesn't represent an AC97 device, but
   rather an AC'97 codec internals IIUC.
   I think it's right place would be in include/sound/ac97/codec.h.
   This is also a problem for regmap adherence, hence the
   include/sound/ac97/compat.h.
 - a new AC'97 bus Kconfig is created
   This was done for a smooth transition ... let's see if it's a good idea.
 - split the AC'97 into :
   - the codec
   - the digital controller
   - the bus

Amongst the things that are not all touched yet :
 - ac97_codec.c
   The generic AC'97 codec in sound/pci/ac97/ac97_codec.c has really a lot
   features, which are not at all PCI related. They could be transfered to
   sound/ac97, without the pci specific field.
   => this deserves a deep ahead thinking, which I'll do if the current approach
   is accepted by the communauty.

The most important patch is 2/7 "ALSA: ac97: add an ac97 bus". This is the main
evaluation point for the serie, the others are here so that I can test it all.

Well, this is a long term effort, which might need a complete rewrite according
to the comments it'll get. Let's expose it for comments and see how I can
progress with it.

Cheers.

--
Robert

Robert Jarzmik (7):
  ALSA: ac97: split out the generic ac97 registers
  ALSA: ac97: add an ac97 bus
  ASoC: wm9713: add ac97 new bus support
  ASoC: pxa: switch to new ac97 bus support
  ARM: pxa: mioa701 remove wm9713 from platform devices
  ASoC: mioa701_wm9713: convert to new ac97 bus
  ASoC: add new ac97 bus support

 arch/arm/mach-pxa/mioa701.c     |   1 -
 include/sound/ac97/codec.h      |  98 ++++++++++++
 include/sound/ac97/compat.h     |  21 +++
 include/sound/ac97/controller.h |  39 +++++
 include/sound/ac97/regs.h       | 262 +++++++++++++++++++++++++++++++
 include/sound/ac97_codec.h      | 239 +----------------------------
 include/sound/pxa2xx-lib.h      |  14 +-
 sound/Kconfig                   |   7 +
 sound/Makefile                  |   1 +
 sound/ac97/Kconfig              |   9 ++
 sound/ac97/Makefile             |   5 +
 sound/ac97/ac97_core.h          |  10 ++
 sound/ac97/bus.c                | 330 ++++++++++++++++++++++++++++++++++++++++
 sound/ac97/codec.c              |  15 ++
 sound/ac97/snd_ac97_compat.c    | 104 +++++++++++++
 sound/arm/Kconfig               |   1 -
 sound/arm/pxa2xx-ac97-lib.c     |  31 ++--
 sound/soc/Kconfig               |   4 +
 sound/soc/codecs/wm9713.c       |  62 +++++++-
 sound/soc/pxa/Kconfig           |   4 +-
 sound/soc/pxa/mioa701_wm9713.c  |   4 +-
 sound/soc/pxa/pxa2xx-ac97.c     |  12 +-
 22 files changed, 1000 insertions(+), 273 deletions(-)
 create mode 100644 include/sound/ac97/codec.h
 create mode 100644 include/sound/ac97/compat.h
 create mode 100644 include/sound/ac97/controller.h
 create mode 100644 include/sound/ac97/regs.h
 create mode 100644 sound/ac97/Kconfig
 create mode 100644 sound/ac97/Makefile
 create mode 100644 sound/ac97/ac97_core.h
 create mode 100644 sound/ac97/bus.c
 create mode 100644 sound/ac97/codec.c
 create mode 100644 sound/ac97/snd_ac97_compat.c

-- 
2.1.4

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

* [RFC PATCH 0/7] AC97 device/driver model revamp
@ 2016-04-30 21:15 ` Robert Jarzmik
  0 siblings, 0 replies; 74+ messages in thread
From: Robert Jarzmik @ 2016-04-30 21:15 UTC (permalink / raw)
  To: linux-arm-kernel

It all started in the pxa device-tree submission here :
   https://lkml.org/lkml/2016/2/25/965
It will be maintained in :
   git fetch https://github.com/rjarzmik/linux.git work/ac97

And now it transformed into this RFC, which would bring a ground for AC'97
devices closer to the linux device/driver model.

This is just an RFC to see if we understand each other Mark.

Amongst the driving ideas behind this RFC :
 - use device/driver model for AC'97
   device/driver binding is based on vendor_id{1,2}
 - use auto-probe of the AC'97 bus to enumerate codecs and create devices
 - be compatible with previous platform_data model for codecs
   => this enables a smooth transition, where a codec (here wm9713) can
      be used either through platform_device or automatic discovery
 - struct snd_ac97 is not used
   This structure is really heavy, and doesn't represent an AC97 device, but
   rather an AC'97 codec internals IIUC.
   I think it's right place would be in include/sound/ac97/codec.h.
   This is also a problem for regmap adherence, hence the
   include/sound/ac97/compat.h.
 - a new AC'97 bus Kconfig is created
   This was done for a smooth transition ... let's see if it's a good idea.
 - split the AC'97 into :
   - the codec
   - the digital controller
   - the bus

Amongst the things that are not all touched yet :
 - ac97_codec.c
   The generic AC'97 codec in sound/pci/ac97/ac97_codec.c has really a lot
   features, which are not at all PCI related. They could be transfered to
   sound/ac97, without the pci specific field.
   => this deserves a deep ahead thinking, which I'll do if the current approach
   is accepted by the communauty.

The most important patch is 2/7 "ALSA: ac97: add an ac97 bus". This is the main
evaluation point for the serie, the others are here so that I can test it all.

Well, this is a long term effort, which might need a complete rewrite according
to the comments it'll get. Let's expose it for comments and see how I can
progress with it.

Cheers.

--
Robert

Robert Jarzmik (7):
  ALSA: ac97: split out the generic ac97 registers
  ALSA: ac97: add an ac97 bus
  ASoC: wm9713: add ac97 new bus support
  ASoC: pxa: switch to new ac97 bus support
  ARM: pxa: mioa701 remove wm9713 from platform devices
  ASoC: mioa701_wm9713: convert to new ac97 bus
  ASoC: add new ac97 bus support

 arch/arm/mach-pxa/mioa701.c     |   1 -
 include/sound/ac97/codec.h      |  98 ++++++++++++
 include/sound/ac97/compat.h     |  21 +++
 include/sound/ac97/controller.h |  39 +++++
 include/sound/ac97/regs.h       | 262 +++++++++++++++++++++++++++++++
 include/sound/ac97_codec.h      | 239 +----------------------------
 include/sound/pxa2xx-lib.h      |  14 +-
 sound/Kconfig                   |   7 +
 sound/Makefile                  |   1 +
 sound/ac97/Kconfig              |   9 ++
 sound/ac97/Makefile             |   5 +
 sound/ac97/ac97_core.h          |  10 ++
 sound/ac97/bus.c                | 330 ++++++++++++++++++++++++++++++++++++++++
 sound/ac97/codec.c              |  15 ++
 sound/ac97/snd_ac97_compat.c    | 104 +++++++++++++
 sound/arm/Kconfig               |   1 -
 sound/arm/pxa2xx-ac97-lib.c     |  31 ++--
 sound/soc/Kconfig               |   4 +
 sound/soc/codecs/wm9713.c       |  62 +++++++-
 sound/soc/pxa/Kconfig           |   4 +-
 sound/soc/pxa/mioa701_wm9713.c  |   4 +-
 sound/soc/pxa/pxa2xx-ac97.c     |  12 +-
 22 files changed, 1000 insertions(+), 273 deletions(-)
 create mode 100644 include/sound/ac97/codec.h
 create mode 100644 include/sound/ac97/compat.h
 create mode 100644 include/sound/ac97/controller.h
 create mode 100644 include/sound/ac97/regs.h
 create mode 100644 sound/ac97/Kconfig
 create mode 100644 sound/ac97/Makefile
 create mode 100644 sound/ac97/ac97_core.h
 create mode 100644 sound/ac97/bus.c
 create mode 100644 sound/ac97/codec.c
 create mode 100644 sound/ac97/snd_ac97_compat.c

-- 
2.1.4

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

* [RFC PATCH 1/7] ALSA: ac97: split out the generic ac97 registers
  2016-04-30 21:15 ` Robert Jarzmik
@ 2016-04-30 21:15   ` Robert Jarzmik
  -1 siblings, 0 replies; 74+ messages in thread
From: Robert Jarzmik @ 2016-04-30 21:15 UTC (permalink / raw)
  To: Robert Jarzmik, Daniel Mack, Haojian Zhuang, Jaroslav Kysela,
	Takashi Iwai, Liam Girdwood, Mark Brown
  Cc: linux-arm-kernel, linux-kernel, alsa-devel, patches

Split out from the ac97_codec.h the ac97 generic registers, which can be
used by a codec, typically a generic ac97 codec, and by the ac97 bus, to
scan an ac97 AC-Link.

Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
---
 include/sound/ac97/regs.h  | 262 +++++++++++++++++++++++++++++++++++++++++++++
 include/sound/ac97_codec.h | 239 +----------------------------------------
 2 files changed, 263 insertions(+), 238 deletions(-)
 create mode 100644 include/sound/ac97/regs.h

diff --git a/include/sound/ac97/regs.h b/include/sound/ac97/regs.h
new file mode 100644
index 000000000000..4bb86d379bd5
--- /dev/null
+++ b/include/sound/ac97/regs.h
@@ -0,0 +1,262 @@
+/*
+ *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>
+ *  Universal interface for Audio Codec '97
+ *
+ *  For more details look to AC '97 component specification revision 2.1
+ *  by Intel Corporation (http://developer.intel.com).
+ *
+ *
+ *   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
+ *
+ */
+
+/*
+ *  AC'97 codec registers
+ */
+
+#define AC97_RESET		0x00	/* Reset */
+#define AC97_MASTER		0x02	/* Master Volume */
+#define AC97_HEADPHONE		0x04	/* Headphone Volume (optional) */
+#define AC97_MASTER_MONO	0x06	/* Master Volume Mono (optional) */
+#define AC97_MASTER_TONE	0x08	/* Master Tone (Bass & Treble) (optional) */
+#define AC97_PC_BEEP		0x0a	/* PC Beep Volume (optinal) */
+#define AC97_PHONE		0x0c	/* Phone Volume (optional) */
+#define AC97_MIC		0x0e	/* MIC Volume */
+#define AC97_LINE		0x10	/* Line In Volume */
+#define AC97_CD			0x12	/* CD Volume */
+#define AC97_VIDEO		0x14	/* Video Volume (optional) */
+#define AC97_AUX		0x16	/* AUX Volume (optional) */
+#define AC97_PCM		0x18	/* PCM Volume */
+#define AC97_REC_SEL		0x1a	/* Record Select */
+#define AC97_REC_GAIN		0x1c	/* Record Gain */
+#define AC97_REC_GAIN_MIC	0x1e	/* Record Gain MIC (optional) */
+#define AC97_GENERAL_PURPOSE	0x20	/* General Purpose (optional) */
+#define AC97_3D_CONTROL		0x22	/* 3D Control (optional) */
+#define AC97_INT_PAGING		0x24	/* Audio Interrupt & Paging (AC'97 2.3) */
+#define AC97_POWERDOWN		0x26	/* Powerdown control / status */
+/* range 0x28-0x3a - AUDIO AC'97 2.0 extensions */
+#define AC97_EXTENDED_ID	0x28	/* Extended Audio ID */
+#define AC97_EXTENDED_STATUS	0x2a	/* Extended Audio Status and Control */
+#define AC97_PCM_FRONT_DAC_RATE 0x2c	/* PCM Front DAC Rate */
+#define AC97_PCM_SURR_DAC_RATE	0x2e	/* PCM Surround DAC Rate */
+#define AC97_PCM_LFE_DAC_RATE	0x30	/* PCM LFE DAC Rate */
+#define AC97_PCM_LR_ADC_RATE	0x32	/* PCM LR ADC Rate */
+#define AC97_PCM_MIC_ADC_RATE	0x34	/* PCM MIC ADC Rate */
+#define AC97_CENTER_LFE_MASTER	0x36	/* Center + LFE Master Volume */
+#define AC97_SURROUND_MASTER	0x38	/* Surround (Rear) Master Volume */
+#define AC97_SPDIF		0x3a	/* S/PDIF control */
+/* range 0x3c-0x58 - MODEM */
+#define AC97_EXTENDED_MID	0x3c	/* Extended Modem ID */
+#define AC97_EXTENDED_MSTATUS	0x3e	/* Extended Modem Status and Control */
+#define AC97_LINE1_RATE		0x40	/* Line1 DAC/ADC Rate */
+#define AC97_LINE2_RATE		0x42	/* Line2 DAC/ADC Rate */
+#define AC97_HANDSET_RATE	0x44	/* Handset DAC/ADC Rate */
+#define AC97_LINE1_LEVEL	0x46	/* Line1 DAC/ADC Level */
+#define AC97_LINE2_LEVEL	0x48	/* Line2 DAC/ADC Level */
+#define AC97_HANDSET_LEVEL	0x4a	/* Handset DAC/ADC Level */
+#define AC97_GPIO_CFG		0x4c	/* GPIO Configuration */
+#define AC97_GPIO_POLARITY	0x4e	/* GPIO Pin Polarity/Type, 0=low, 1=high active */
+#define AC97_GPIO_STICKY	0x50	/* GPIO Pin Sticky, 0=not, 1=sticky */
+#define AC97_GPIO_WAKEUP	0x52	/* GPIO Pin Wakeup, 0=no int, 1=yes int */
+#define AC97_GPIO_STATUS	0x54	/* GPIO Pin Status, slot 12 */
+#define AC97_MISC_AFE		0x56	/* Miscellaneous Modem AFE Status and Control */
+/* range 0x5a-0x7b - Vendor Specific */
+#define AC97_VENDOR_ID1		0x7c	/* Vendor ID1 */
+#define AC97_VENDOR_ID2		0x7e	/* Vendor ID2 / revision */
+/* range 0x60-0x6f (page 1) - extended codec registers */
+#define AC97_CODEC_CLASS_REV	0x60	/* Codec Class/Revision */
+#define AC97_PCI_SVID		0x62	/* PCI Subsystem Vendor ID */
+#define AC97_PCI_SID		0x64	/* PCI Subsystem ID */
+#define AC97_FUNC_SELECT	0x66	/* Function Select */
+#define AC97_FUNC_INFO		0x68	/* Function Information */
+#define AC97_SENSE_INFO		0x6a	/* Sense Details */
+
+/* volume controls */
+#define AC97_MUTE_MASK_MONO	0x8000
+#define AC97_MUTE_MASK_STEREO	0x8080
+
+/* slot allocation */
+#define AC97_SLOT_TAG		0
+#define AC97_SLOT_CMD_ADDR	1
+#define AC97_SLOT_CMD_DATA	2
+#define AC97_SLOT_PCM_LEFT	3
+#define AC97_SLOT_PCM_RIGHT	4
+#define AC97_SLOT_MODEM_LINE1	5
+#define AC97_SLOT_PCM_CENTER	6
+#define AC97_SLOT_MIC		6	/* input */
+#define AC97_SLOT_SPDIF_LEFT1	6
+#define AC97_SLOT_PCM_SLEFT	7	/* surround left */
+#define AC97_SLOT_PCM_LEFT_0	7	/* double rate operation */
+#define AC97_SLOT_SPDIF_LEFT	7
+#define AC97_SLOT_PCM_SRIGHT	8	/* surround right */
+#define AC97_SLOT_PCM_RIGHT_0	8	/* double rate operation */
+#define AC97_SLOT_SPDIF_RIGHT	8
+#define AC97_SLOT_LFE		9
+#define AC97_SLOT_SPDIF_RIGHT1	9
+#define AC97_SLOT_MODEM_LINE2	10
+#define AC97_SLOT_PCM_LEFT_1	10	/* double rate operation */
+#define AC97_SLOT_SPDIF_LEFT2	10
+#define AC97_SLOT_HANDSET	11	/* output */
+#define AC97_SLOT_PCM_RIGHT_1	11	/* double rate operation */
+#define AC97_SLOT_SPDIF_RIGHT2	11
+#define AC97_SLOT_MODEM_GPIO	12	/* modem GPIO */
+#define AC97_SLOT_PCM_CENTER_1	12	/* double rate operation */
+
+/* basic capabilities (reset register) */
+#define AC97_BC_DEDICATED_MIC	0x0001	/* Dedicated Mic PCM In Channel */
+#define AC97_BC_RESERVED1	0x0002	/* Reserved (was Modem Line Codec support) */
+#define AC97_BC_BASS_TREBLE	0x0004	/* Bass & Treble Control */
+#define AC97_BC_SIM_STEREO	0x0008	/* Simulated stereo */
+#define AC97_BC_HEADPHONE	0x0010	/* Headphone Out Support */
+#define AC97_BC_LOUDNESS	0x0020	/* Loudness (bass boost) Support */
+#define AC97_BC_16BIT_DAC	0x0000	/* 16-bit DAC resolution */
+#define AC97_BC_18BIT_DAC	0x0040	/* 18-bit DAC resolution */
+#define AC97_BC_20BIT_DAC	0x0080	/* 20-bit DAC resolution */
+#define AC97_BC_DAC_MASK	0x00c0
+#define AC97_BC_16BIT_ADC	0x0000	/* 16-bit ADC resolution */
+#define AC97_BC_18BIT_ADC	0x0100	/* 18-bit ADC resolution */
+#define AC97_BC_20BIT_ADC	0x0200	/* 20-bit ADC resolution */
+#define AC97_BC_ADC_MASK	0x0300
+#define AC97_BC_3D_TECH_ID_MASK	0x7c00	/* Per-vendor ID of 3D enhancement */
+
+/* general purpose */
+#define AC97_GP_DRSS_MASK	0x0c00	/* double rate slot select */
+#define AC97_GP_DRSS_1011	0x0000	/* LR(C) 10+11(+12) */
+#define AC97_GP_DRSS_78		0x0400	/* LR 7+8 */
+
+/* powerdown bits */
+#define AC97_PD_ADC_STATUS	0x0001	/* ADC status (RO) */
+#define AC97_PD_DAC_STATUS	0x0002	/* DAC status (RO) */
+#define AC97_PD_MIXER_STATUS	0x0004	/* Analog mixer status (RO) */
+#define AC97_PD_VREF_STATUS	0x0008	/* Vref status (RO) */
+#define AC97_PD_PR0		0x0100	/* Power down PCM ADCs and input MUX */
+#define AC97_PD_PR1		0x0200	/* Power down PCM front DAC */
+#define AC97_PD_PR2		0x0400	/* Power down Mixer (Vref still on) */
+#define AC97_PD_PR3		0x0800	/* Power down Mixer (Vref off) */
+#define AC97_PD_PR4		0x1000	/* Power down AC-Link */
+#define AC97_PD_PR5		0x2000	/* Disable internal clock usage */
+#define AC97_PD_PR6		0x4000	/* Headphone amplifier */
+#define AC97_PD_EAPD		0x8000	/* External Amplifer Power Down (EAPD) */
+
+/* extended audio ID bit defines */
+#define AC97_EI_VRA		0x0001	/* Variable bit rate supported */
+#define AC97_EI_DRA		0x0002	/* Double rate supported */
+#define AC97_EI_SPDIF		0x0004	/* S/PDIF out supported */
+#define AC97_EI_VRM		0x0008	/* Variable bit rate supported for MIC */
+#define AC97_EI_DACS_SLOT_MASK	0x0030	/* DACs slot assignment */
+#define AC97_EI_DACS_SLOT_SHIFT	4
+#define AC97_EI_CDAC		0x0040	/* PCM Center DAC available */
+#define AC97_EI_SDAC		0x0080	/* PCM Surround DACs available */
+#define AC97_EI_LDAC		0x0100	/* PCM LFE DAC available */
+#define AC97_EI_AMAP		0x0200	/* indicates optional slot/DAC mapping based on codec ID */
+#define AC97_EI_REV_MASK	0x0c00	/* AC'97 revision mask */
+#define AC97_EI_REV_22		0x0400	/* AC'97 revision 2.2 */
+#define AC97_EI_REV_23		0x0800	/* AC'97 revision 2.3 */
+#define AC97_EI_REV_SHIFT	10
+#define AC97_EI_ADDR_MASK	0xc000	/* physical codec ID (address) */
+#define AC97_EI_ADDR_SHIFT	14
+
+/* extended audio status and control bit defines */
+#define AC97_EA_VRA		0x0001	/* Variable bit rate enable bit */
+#define AC97_EA_DRA		0x0002	/* Double-rate audio enable bit */
+#define AC97_EA_SPDIF		0x0004	/* S/PDIF out enable bit */
+#define AC97_EA_VRM		0x0008	/* Variable bit rate for MIC enable bit */
+#define AC97_EA_SPSA_SLOT_MASK	0x0030	/* Mask for slot assignment bits */
+#define AC97_EA_SPSA_SLOT_SHIFT 4
+#define AC97_EA_SPSA_3_4	0x0000	/* Slot assigned to 3 & 4 */
+#define AC97_EA_SPSA_7_8	0x0010	/* Slot assigned to 7 & 8 */
+#define AC97_EA_SPSA_6_9	0x0020	/* Slot assigned to 6 & 9 */
+#define AC97_EA_SPSA_10_11	0x0030	/* Slot assigned to 10 & 11 */
+#define AC97_EA_CDAC		0x0040	/* PCM Center DAC is ready (Read only) */
+#define AC97_EA_SDAC		0x0080	/* PCM Surround DACs are ready (Read only) */
+#define AC97_EA_LDAC		0x0100	/* PCM LFE DAC is ready (Read only) */
+#define AC97_EA_MDAC		0x0200	/* MIC ADC is ready (Read only) */
+#define AC97_EA_SPCV		0x0400	/* S/PDIF configuration valid (Read only) */
+#define AC97_EA_PRI		0x0800	/* Turns the PCM Center DAC off */
+#define AC97_EA_PRJ		0x1000	/* Turns the PCM Surround DACs off */
+#define AC97_EA_PRK		0x2000	/* Turns the PCM LFE DAC off */
+#define AC97_EA_PRL		0x4000	/* Turns the MIC ADC off */
+
+/* S/PDIF control bit defines */
+#define AC97_SC_PRO		0x0001	/* Professional status */
+#define AC97_SC_NAUDIO		0x0002	/* Non audio stream */
+#define AC97_SC_COPY		0x0004	/* Copyright status */
+#define AC97_SC_PRE		0x0008	/* Preemphasis status */
+#define AC97_SC_CC_MASK		0x07f0	/* Category Code mask */
+#define AC97_SC_CC_SHIFT	4
+#define AC97_SC_L		0x0800	/* Generation Level status */
+#define AC97_SC_SPSR_MASK	0x3000	/* S/PDIF Sample Rate bits */
+#define AC97_SC_SPSR_SHIFT	12
+#define AC97_SC_SPSR_44K	0x0000	/* Use 44.1kHz Sample rate */
+#define AC97_SC_SPSR_48K	0x2000	/* Use 48kHz Sample rate */
+#define AC97_SC_SPSR_32K	0x3000	/* Use 32kHz Sample rate */
+#define AC97_SC_DRS		0x4000	/* Double Rate S/PDIF */
+#define AC97_SC_V		0x8000	/* Validity status */
+
+/* Interrupt and Paging bit defines (AC'97 2.3) */
+#define AC97_PAGE_MASK		0x000f	/* Page Selector */
+#define AC97_PAGE_VENDOR	0	/* Vendor-specific registers */
+#define AC97_PAGE_1		1	/* Extended Codec Registers page 1 */
+#define AC97_INT_ENABLE		0x0800	/* Interrupt Enable */
+#define AC97_INT_SENSE		0x1000	/* Sense Cycle */
+#define AC97_INT_CAUSE_SENSE	0x2000	/* Sense Cycle Completed (RO) */
+#define AC97_INT_CAUSE_GPIO	0x4000	/* GPIO bits changed (RO) */
+#define AC97_INT_STATUS		0x8000	/* Interrupt Status */
+
+/* extended modem ID bit defines */
+#define AC97_MEI_LINE1		0x0001	/* Line1 present */
+#define AC97_MEI_LINE2		0x0002	/* Line2 present */
+#define AC97_MEI_HANDSET	0x0004	/* Handset present */
+#define AC97_MEI_CID1		0x0008	/* caller ID decode for Line1 is supported */
+#define AC97_MEI_CID2		0x0010	/* caller ID decode for Line2 is supported */
+#define AC97_MEI_ADDR_MASK	0xc000	/* physical codec ID (address) */
+#define AC97_MEI_ADDR_SHIFT	14
+
+/* extended modem status and control bit defines */
+#define AC97_MEA_GPIO		0x0001	/* GPIO is ready (ro) */
+#define AC97_MEA_MREF		0x0002	/* Vref is up to nominal level (ro) */
+#define AC97_MEA_ADC1		0x0004	/* ADC1 operational (ro) */
+#define AC97_MEA_DAC1		0x0008	/* DAC1 operational (ro) */
+#define AC97_MEA_ADC2		0x0010	/* ADC2 operational (ro) */
+#define AC97_MEA_DAC2		0x0020	/* DAC2 operational (ro) */
+#define AC97_MEA_HADC		0x0040	/* HADC operational (ro) */
+#define AC97_MEA_HDAC		0x0080	/* HDAC operational (ro) */
+#define AC97_MEA_PRA		0x0100	/* GPIO power down (high) */
+#define AC97_MEA_PRB		0x0200	/* reserved */
+#define AC97_MEA_PRC		0x0400	/* ADC1 power down (high) */
+#define AC97_MEA_PRD		0x0800	/* DAC1 power down (high) */
+#define AC97_MEA_PRE		0x1000	/* ADC2 power down (high) */
+#define AC97_MEA_PRF		0x2000	/* DAC2 power down (high) */
+#define AC97_MEA_PRG		0x4000	/* HADC power down (high) */
+#define AC97_MEA_PRH		0x8000	/* HDAC power down (high) */
+
+/* modem gpio status defines */
+#define AC97_GPIO_LINE1_OH      0x0001  /* Off Hook Line1 */
+#define AC97_GPIO_LINE1_RI      0x0002  /* Ring Detect Line1 */
+#define AC97_GPIO_LINE1_CID     0x0004  /* Caller ID path enable Line1 */
+#define AC97_GPIO_LINE1_LCS     0x0008  /* Loop Current Sense Line1 */
+#define AC97_GPIO_LINE1_PULSE   0x0010  /* Opt./ Pulse Dial Line1 (out) */
+#define AC97_GPIO_LINE1_HL1R    0x0020  /* Opt./ Handset to Line1 relay control (out) */
+#define AC97_GPIO_LINE1_HOHD    0x0040  /* Opt./ Handset off hook detect Line1 (in) */
+#define AC97_GPIO_LINE12_AC     0x0080  /* Opt./ Int.bit 1 / Line1/2 AC (out) */
+#define AC97_GPIO_LINE12_DC     0x0100  /* Opt./ Int.bit 2 / Line1/2 DC (out) */
+#define AC97_GPIO_LINE12_RS     0x0200  /* Opt./ Int.bit 3 / Line1/2 RS (out) */
+#define AC97_GPIO_LINE2_OH      0x0400  /* Off Hook Line2 */
+#define AC97_GPIO_LINE2_RI      0x0800  /* Ring Detect Line2 */
+#define AC97_GPIO_LINE2_CID     0x1000  /* Caller ID path enable Line2 */
+#define AC97_GPIO_LINE2_LCS     0x2000  /* Loop Current Sense Line2 */
+#define AC97_GPIO_LINE2_PULSE   0x4000  /* Opt./ Pulse Dial Line2 (out) */
+#define AC97_GPIO_LINE2_HL1R    0x8000  /* Opt./ Handset to Line2 relay control (out) */
+
diff --git a/include/sound/ac97_codec.h b/include/sound/ac97_codec.h
index 15aa5f07c955..89d311a503d3 100644
--- a/include/sound/ac97_codec.h
+++ b/include/sound/ac97_codec.h
@@ -28,6 +28,7 @@
 #include <linux/bitops.h>
 #include <linux/device.h>
 #include <linux/workqueue.h>
+#include <sound/ac97/regs.h>
 #include <sound/pcm.h>
 #include <sound/control.h>
 #include <sound/info.h>
@@ -35,244 +36,6 @@
 /* maximum number of devices on the AC97 bus */
 #define	AC97_BUS_MAX_DEVICES	4
 
-/*
- *  AC'97 codec registers
- */
-
-#define AC97_RESET		0x00	/* Reset */
-#define AC97_MASTER		0x02	/* Master Volume */
-#define AC97_HEADPHONE		0x04	/* Headphone Volume (optional) */
-#define AC97_MASTER_MONO	0x06	/* Master Volume Mono (optional) */
-#define AC97_MASTER_TONE	0x08	/* Master Tone (Bass & Treble) (optional) */
-#define AC97_PC_BEEP		0x0a	/* PC Beep Volume (optinal) */
-#define AC97_PHONE		0x0c	/* Phone Volume (optional) */
-#define AC97_MIC		0x0e	/* MIC Volume */
-#define AC97_LINE		0x10	/* Line In Volume */
-#define AC97_CD			0x12	/* CD Volume */
-#define AC97_VIDEO		0x14	/* Video Volume (optional) */
-#define AC97_AUX		0x16	/* AUX Volume (optional) */
-#define AC97_PCM		0x18	/* PCM Volume */
-#define AC97_REC_SEL		0x1a	/* Record Select */
-#define AC97_REC_GAIN		0x1c	/* Record Gain */
-#define AC97_REC_GAIN_MIC	0x1e	/* Record Gain MIC (optional) */
-#define AC97_GENERAL_PURPOSE	0x20	/* General Purpose (optional) */
-#define AC97_3D_CONTROL		0x22	/* 3D Control (optional) */
-#define AC97_INT_PAGING		0x24	/* Audio Interrupt & Paging (AC'97 2.3) */
-#define AC97_POWERDOWN		0x26	/* Powerdown control / status */
-/* range 0x28-0x3a - AUDIO AC'97 2.0 extensions */
-#define AC97_EXTENDED_ID	0x28	/* Extended Audio ID */
-#define AC97_EXTENDED_STATUS	0x2a	/* Extended Audio Status and Control */
-#define AC97_PCM_FRONT_DAC_RATE 0x2c	/* PCM Front DAC Rate */
-#define AC97_PCM_SURR_DAC_RATE	0x2e	/* PCM Surround DAC Rate */
-#define AC97_PCM_LFE_DAC_RATE	0x30	/* PCM LFE DAC Rate */
-#define AC97_PCM_LR_ADC_RATE	0x32	/* PCM LR ADC Rate */
-#define AC97_PCM_MIC_ADC_RATE	0x34	/* PCM MIC ADC Rate */
-#define AC97_CENTER_LFE_MASTER	0x36	/* Center + LFE Master Volume */
-#define AC97_SURROUND_MASTER	0x38	/* Surround (Rear) Master Volume */
-#define AC97_SPDIF		0x3a	/* S/PDIF control */
-/* range 0x3c-0x58 - MODEM */
-#define AC97_EXTENDED_MID	0x3c	/* Extended Modem ID */
-#define AC97_EXTENDED_MSTATUS	0x3e	/* Extended Modem Status and Control */
-#define AC97_LINE1_RATE		0x40	/* Line1 DAC/ADC Rate */
-#define AC97_LINE2_RATE		0x42	/* Line2 DAC/ADC Rate */
-#define AC97_HANDSET_RATE	0x44	/* Handset DAC/ADC Rate */
-#define AC97_LINE1_LEVEL	0x46	/* Line1 DAC/ADC Level */
-#define AC97_LINE2_LEVEL	0x48	/* Line2 DAC/ADC Level */
-#define AC97_HANDSET_LEVEL	0x4a	/* Handset DAC/ADC Level */
-#define AC97_GPIO_CFG		0x4c	/* GPIO Configuration */
-#define AC97_GPIO_POLARITY	0x4e	/* GPIO Pin Polarity/Type, 0=low, 1=high active */
-#define AC97_GPIO_STICKY	0x50	/* GPIO Pin Sticky, 0=not, 1=sticky */
-#define AC97_GPIO_WAKEUP	0x52	/* GPIO Pin Wakeup, 0=no int, 1=yes int */
-#define AC97_GPIO_STATUS	0x54	/* GPIO Pin Status, slot 12 */
-#define AC97_MISC_AFE		0x56	/* Miscellaneous Modem AFE Status and Control */
-/* range 0x5a-0x7b - Vendor Specific */
-#define AC97_VENDOR_ID1		0x7c	/* Vendor ID1 */
-#define AC97_VENDOR_ID2		0x7e	/* Vendor ID2 / revision */
-/* range 0x60-0x6f (page 1) - extended codec registers */
-#define AC97_CODEC_CLASS_REV	0x60	/* Codec Class/Revision */
-#define AC97_PCI_SVID		0x62	/* PCI Subsystem Vendor ID */
-#define AC97_PCI_SID		0x64	/* PCI Subsystem ID */
-#define AC97_FUNC_SELECT	0x66	/* Function Select */
-#define AC97_FUNC_INFO		0x68	/* Function Information */
-#define AC97_SENSE_INFO		0x6a	/* Sense Details */
-
-/* volume controls */
-#define AC97_MUTE_MASK_MONO	0x8000
-#define AC97_MUTE_MASK_STEREO	0x8080
-
-/* slot allocation */
-#define AC97_SLOT_TAG		0
-#define AC97_SLOT_CMD_ADDR	1
-#define AC97_SLOT_CMD_DATA	2
-#define AC97_SLOT_PCM_LEFT	3
-#define AC97_SLOT_PCM_RIGHT	4
-#define AC97_SLOT_MODEM_LINE1	5
-#define AC97_SLOT_PCM_CENTER	6
-#define AC97_SLOT_MIC		6	/* input */
-#define AC97_SLOT_SPDIF_LEFT1	6
-#define AC97_SLOT_PCM_SLEFT	7	/* surround left */
-#define AC97_SLOT_PCM_LEFT_0	7	/* double rate operation */
-#define AC97_SLOT_SPDIF_LEFT	7
-#define AC97_SLOT_PCM_SRIGHT	8	/* surround right */
-#define AC97_SLOT_PCM_RIGHT_0	8	/* double rate operation */
-#define AC97_SLOT_SPDIF_RIGHT	8
-#define AC97_SLOT_LFE		9
-#define AC97_SLOT_SPDIF_RIGHT1	9
-#define AC97_SLOT_MODEM_LINE2	10
-#define AC97_SLOT_PCM_LEFT_1	10	/* double rate operation */
-#define AC97_SLOT_SPDIF_LEFT2	10
-#define AC97_SLOT_HANDSET	11	/* output */
-#define AC97_SLOT_PCM_RIGHT_1	11	/* double rate operation */
-#define AC97_SLOT_SPDIF_RIGHT2	11
-#define AC97_SLOT_MODEM_GPIO	12	/* modem GPIO */
-#define AC97_SLOT_PCM_CENTER_1	12	/* double rate operation */
-
-/* basic capabilities (reset register) */
-#define AC97_BC_DEDICATED_MIC	0x0001	/* Dedicated Mic PCM In Channel */
-#define AC97_BC_RESERVED1	0x0002	/* Reserved (was Modem Line Codec support) */
-#define AC97_BC_BASS_TREBLE	0x0004	/* Bass & Treble Control */
-#define AC97_BC_SIM_STEREO	0x0008	/* Simulated stereo */
-#define AC97_BC_HEADPHONE	0x0010	/* Headphone Out Support */
-#define AC97_BC_LOUDNESS	0x0020	/* Loudness (bass boost) Support */
-#define AC97_BC_16BIT_DAC	0x0000	/* 16-bit DAC resolution */
-#define AC97_BC_18BIT_DAC	0x0040	/* 18-bit DAC resolution */
-#define AC97_BC_20BIT_DAC	0x0080	/* 20-bit DAC resolution */
-#define AC97_BC_DAC_MASK	0x00c0
-#define AC97_BC_16BIT_ADC	0x0000	/* 16-bit ADC resolution */
-#define AC97_BC_18BIT_ADC	0x0100	/* 18-bit ADC resolution */
-#define AC97_BC_20BIT_ADC	0x0200	/* 20-bit ADC resolution */
-#define AC97_BC_ADC_MASK	0x0300
-#define AC97_BC_3D_TECH_ID_MASK	0x7c00	/* Per-vendor ID of 3D enhancement */
-
-/* general purpose */
-#define AC97_GP_DRSS_MASK	0x0c00	/* double rate slot select */
-#define AC97_GP_DRSS_1011	0x0000	/* LR(C) 10+11(+12) */
-#define AC97_GP_DRSS_78		0x0400	/* LR 7+8 */
-
-/* powerdown bits */
-#define AC97_PD_ADC_STATUS	0x0001	/* ADC status (RO) */
-#define AC97_PD_DAC_STATUS	0x0002	/* DAC status (RO) */
-#define AC97_PD_MIXER_STATUS	0x0004	/* Analog mixer status (RO) */
-#define AC97_PD_VREF_STATUS	0x0008	/* Vref status (RO) */
-#define AC97_PD_PR0		0x0100	/* Power down PCM ADCs and input MUX */
-#define AC97_PD_PR1		0x0200	/* Power down PCM front DAC */
-#define AC97_PD_PR2		0x0400	/* Power down Mixer (Vref still on) */
-#define AC97_PD_PR3		0x0800	/* Power down Mixer (Vref off) */
-#define AC97_PD_PR4		0x1000	/* Power down AC-Link */
-#define AC97_PD_PR5		0x2000	/* Disable internal clock usage */
-#define AC97_PD_PR6		0x4000	/* Headphone amplifier */
-#define AC97_PD_EAPD		0x8000	/* External Amplifer Power Down (EAPD) */
-
-/* extended audio ID bit defines */
-#define AC97_EI_VRA		0x0001	/* Variable bit rate supported */
-#define AC97_EI_DRA		0x0002	/* Double rate supported */
-#define AC97_EI_SPDIF		0x0004	/* S/PDIF out supported */
-#define AC97_EI_VRM		0x0008	/* Variable bit rate supported for MIC */
-#define AC97_EI_DACS_SLOT_MASK	0x0030	/* DACs slot assignment */
-#define AC97_EI_DACS_SLOT_SHIFT	4
-#define AC97_EI_CDAC		0x0040	/* PCM Center DAC available */
-#define AC97_EI_SDAC		0x0080	/* PCM Surround DACs available */
-#define AC97_EI_LDAC		0x0100	/* PCM LFE DAC available */
-#define AC97_EI_AMAP		0x0200	/* indicates optional slot/DAC mapping based on codec ID */
-#define AC97_EI_REV_MASK	0x0c00	/* AC'97 revision mask */
-#define AC97_EI_REV_22		0x0400	/* AC'97 revision 2.2 */
-#define AC97_EI_REV_23		0x0800	/* AC'97 revision 2.3 */
-#define AC97_EI_REV_SHIFT	10
-#define AC97_EI_ADDR_MASK	0xc000	/* physical codec ID (address) */
-#define AC97_EI_ADDR_SHIFT	14
-
-/* extended audio status and control bit defines */
-#define AC97_EA_VRA		0x0001	/* Variable bit rate enable bit */
-#define AC97_EA_DRA		0x0002	/* Double-rate audio enable bit */
-#define AC97_EA_SPDIF		0x0004	/* S/PDIF out enable bit */
-#define AC97_EA_VRM		0x0008	/* Variable bit rate for MIC enable bit */
-#define AC97_EA_SPSA_SLOT_MASK	0x0030	/* Mask for slot assignment bits */
-#define AC97_EA_SPSA_SLOT_SHIFT 4
-#define AC97_EA_SPSA_3_4	0x0000	/* Slot assigned to 3 & 4 */
-#define AC97_EA_SPSA_7_8	0x0010	/* Slot assigned to 7 & 8 */
-#define AC97_EA_SPSA_6_9	0x0020	/* Slot assigned to 6 & 9 */
-#define AC97_EA_SPSA_10_11	0x0030	/* Slot assigned to 10 & 11 */
-#define AC97_EA_CDAC		0x0040	/* PCM Center DAC is ready (Read only) */
-#define AC97_EA_SDAC		0x0080	/* PCM Surround DACs are ready (Read only) */
-#define AC97_EA_LDAC		0x0100	/* PCM LFE DAC is ready (Read only) */
-#define AC97_EA_MDAC		0x0200	/* MIC ADC is ready (Read only) */
-#define AC97_EA_SPCV		0x0400	/* S/PDIF configuration valid (Read only) */
-#define AC97_EA_PRI		0x0800	/* Turns the PCM Center DAC off */
-#define AC97_EA_PRJ		0x1000	/* Turns the PCM Surround DACs off */
-#define AC97_EA_PRK		0x2000	/* Turns the PCM LFE DAC off */
-#define AC97_EA_PRL		0x4000	/* Turns the MIC ADC off */
-
-/* S/PDIF control bit defines */
-#define AC97_SC_PRO		0x0001	/* Professional status */
-#define AC97_SC_NAUDIO		0x0002	/* Non audio stream */
-#define AC97_SC_COPY		0x0004	/* Copyright status */
-#define AC97_SC_PRE		0x0008	/* Preemphasis status */
-#define AC97_SC_CC_MASK		0x07f0	/* Category Code mask */
-#define AC97_SC_CC_SHIFT	4
-#define AC97_SC_L		0x0800	/* Generation Level status */
-#define AC97_SC_SPSR_MASK	0x3000	/* S/PDIF Sample Rate bits */
-#define AC97_SC_SPSR_SHIFT	12
-#define AC97_SC_SPSR_44K	0x0000	/* Use 44.1kHz Sample rate */
-#define AC97_SC_SPSR_48K	0x2000	/* Use 48kHz Sample rate */
-#define AC97_SC_SPSR_32K	0x3000	/* Use 32kHz Sample rate */
-#define AC97_SC_DRS		0x4000	/* Double Rate S/PDIF */
-#define AC97_SC_V		0x8000	/* Validity status */
-
-/* Interrupt and Paging bit defines (AC'97 2.3) */
-#define AC97_PAGE_MASK		0x000f	/* Page Selector */
-#define AC97_PAGE_VENDOR	0	/* Vendor-specific registers */
-#define AC97_PAGE_1		1	/* Extended Codec Registers page 1 */
-#define AC97_INT_ENABLE		0x0800	/* Interrupt Enable */
-#define AC97_INT_SENSE		0x1000	/* Sense Cycle */
-#define AC97_INT_CAUSE_SENSE	0x2000	/* Sense Cycle Completed (RO) */
-#define AC97_INT_CAUSE_GPIO	0x4000	/* GPIO bits changed (RO) */
-#define AC97_INT_STATUS		0x8000	/* Interrupt Status */
-
-/* extended modem ID bit defines */
-#define AC97_MEI_LINE1		0x0001	/* Line1 present */
-#define AC97_MEI_LINE2		0x0002	/* Line2 present */
-#define AC97_MEI_HANDSET	0x0004	/* Handset present */
-#define AC97_MEI_CID1		0x0008	/* caller ID decode for Line1 is supported */
-#define AC97_MEI_CID2		0x0010	/* caller ID decode for Line2 is supported */
-#define AC97_MEI_ADDR_MASK	0xc000	/* physical codec ID (address) */
-#define AC97_MEI_ADDR_SHIFT	14
-
-/* extended modem status and control bit defines */
-#define AC97_MEA_GPIO		0x0001	/* GPIO is ready (ro) */
-#define AC97_MEA_MREF		0x0002	/* Vref is up to nominal level (ro) */
-#define AC97_MEA_ADC1		0x0004	/* ADC1 operational (ro) */
-#define AC97_MEA_DAC1		0x0008	/* DAC1 operational (ro) */
-#define AC97_MEA_ADC2		0x0010	/* ADC2 operational (ro) */
-#define AC97_MEA_DAC2		0x0020	/* DAC2 operational (ro) */
-#define AC97_MEA_HADC		0x0040	/* HADC operational (ro) */
-#define AC97_MEA_HDAC		0x0080	/* HDAC operational (ro) */
-#define AC97_MEA_PRA		0x0100	/* GPIO power down (high) */
-#define AC97_MEA_PRB		0x0200	/* reserved */
-#define AC97_MEA_PRC		0x0400	/* ADC1 power down (high) */
-#define AC97_MEA_PRD		0x0800	/* DAC1 power down (high) */
-#define AC97_MEA_PRE		0x1000	/* ADC2 power down (high) */
-#define AC97_MEA_PRF		0x2000	/* DAC2 power down (high) */
-#define AC97_MEA_PRG		0x4000	/* HADC power down (high) */
-#define AC97_MEA_PRH		0x8000	/* HDAC power down (high) */
-
-/* modem gpio status defines */
-#define AC97_GPIO_LINE1_OH      0x0001  /* Off Hook Line1 */
-#define AC97_GPIO_LINE1_RI      0x0002  /* Ring Detect Line1 */
-#define AC97_GPIO_LINE1_CID     0x0004  /* Caller ID path enable Line1 */
-#define AC97_GPIO_LINE1_LCS     0x0008  /* Loop Current Sense Line1 */
-#define AC97_GPIO_LINE1_PULSE   0x0010  /* Opt./ Pulse Dial Line1 (out) */
-#define AC97_GPIO_LINE1_HL1R    0x0020  /* Opt./ Handset to Line1 relay control (out) */
-#define AC97_GPIO_LINE1_HOHD    0x0040  /* Opt./ Handset off hook detect Line1 (in) */
-#define AC97_GPIO_LINE12_AC     0x0080  /* Opt./ Int.bit 1 / Line1/2 AC (out) */
-#define AC97_GPIO_LINE12_DC     0x0100  /* Opt./ Int.bit 2 / Line1/2 DC (out) */
-#define AC97_GPIO_LINE12_RS     0x0200  /* Opt./ Int.bit 3 / Line1/2 RS (out) */
-#define AC97_GPIO_LINE2_OH      0x0400  /* Off Hook Line2 */
-#define AC97_GPIO_LINE2_RI      0x0800  /* Ring Detect Line2 */
-#define AC97_GPIO_LINE2_CID     0x1000  /* Caller ID path enable Line2 */
-#define AC97_GPIO_LINE2_LCS     0x2000  /* Loop Current Sense Line2 */
-#define AC97_GPIO_LINE2_PULSE   0x4000  /* Opt./ Pulse Dial Line2 (out) */
-#define AC97_GPIO_LINE2_HL1R    0x8000  /* Opt./ Handset to Line2 relay control (out) */
-
 /* specific - SigmaTel */
 #define AC97_SIGMATEL_OUTSEL	0x64	/* Output Select, STAC9758 */
 #define AC97_SIGMATEL_INSEL	0x66	/* Input Select, STAC9758 */
-- 
2.1.4

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

* [RFC PATCH 1/7] ALSA: ac97: split out the generic ac97 registers
@ 2016-04-30 21:15   ` Robert Jarzmik
  0 siblings, 0 replies; 74+ messages in thread
From: Robert Jarzmik @ 2016-04-30 21:15 UTC (permalink / raw)
  To: linux-arm-kernel

Split out from the ac97_codec.h the ac97 generic registers, which can be
used by a codec, typically a generic ac97 codec, and by the ac97 bus, to
scan an ac97 AC-Link.

Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
---
 include/sound/ac97/regs.h  | 262 +++++++++++++++++++++++++++++++++++++++++++++
 include/sound/ac97_codec.h | 239 +----------------------------------------
 2 files changed, 263 insertions(+), 238 deletions(-)
 create mode 100644 include/sound/ac97/regs.h

diff --git a/include/sound/ac97/regs.h b/include/sound/ac97/regs.h
new file mode 100644
index 000000000000..4bb86d379bd5
--- /dev/null
+++ b/include/sound/ac97/regs.h
@@ -0,0 +1,262 @@
+/*
+ *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>
+ *  Universal interface for Audio Codec '97
+ *
+ *  For more details look to AC '97 component specification revision 2.1
+ *  by Intel Corporation (http://developer.intel.com).
+ *
+ *
+ *   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
+ *
+ */
+
+/*
+ *  AC'97 codec registers
+ */
+
+#define AC97_RESET		0x00	/* Reset */
+#define AC97_MASTER		0x02	/* Master Volume */
+#define AC97_HEADPHONE		0x04	/* Headphone Volume (optional) */
+#define AC97_MASTER_MONO	0x06	/* Master Volume Mono (optional) */
+#define AC97_MASTER_TONE	0x08	/* Master Tone (Bass & Treble) (optional) */
+#define AC97_PC_BEEP		0x0a	/* PC Beep Volume (optinal) */
+#define AC97_PHONE		0x0c	/* Phone Volume (optional) */
+#define AC97_MIC		0x0e	/* MIC Volume */
+#define AC97_LINE		0x10	/* Line In Volume */
+#define AC97_CD			0x12	/* CD Volume */
+#define AC97_VIDEO		0x14	/* Video Volume (optional) */
+#define AC97_AUX		0x16	/* AUX Volume (optional) */
+#define AC97_PCM		0x18	/* PCM Volume */
+#define AC97_REC_SEL		0x1a	/* Record Select */
+#define AC97_REC_GAIN		0x1c	/* Record Gain */
+#define AC97_REC_GAIN_MIC	0x1e	/* Record Gain MIC (optional) */
+#define AC97_GENERAL_PURPOSE	0x20	/* General Purpose (optional) */
+#define AC97_3D_CONTROL		0x22	/* 3D Control (optional) */
+#define AC97_INT_PAGING		0x24	/* Audio Interrupt & Paging (AC'97 2.3) */
+#define AC97_POWERDOWN		0x26	/* Powerdown control / status */
+/* range 0x28-0x3a - AUDIO AC'97 2.0 extensions */
+#define AC97_EXTENDED_ID	0x28	/* Extended Audio ID */
+#define AC97_EXTENDED_STATUS	0x2a	/* Extended Audio Status and Control */
+#define AC97_PCM_FRONT_DAC_RATE 0x2c	/* PCM Front DAC Rate */
+#define AC97_PCM_SURR_DAC_RATE	0x2e	/* PCM Surround DAC Rate */
+#define AC97_PCM_LFE_DAC_RATE	0x30	/* PCM LFE DAC Rate */
+#define AC97_PCM_LR_ADC_RATE	0x32	/* PCM LR ADC Rate */
+#define AC97_PCM_MIC_ADC_RATE	0x34	/* PCM MIC ADC Rate */
+#define AC97_CENTER_LFE_MASTER	0x36	/* Center + LFE Master Volume */
+#define AC97_SURROUND_MASTER	0x38	/* Surround (Rear) Master Volume */
+#define AC97_SPDIF		0x3a	/* S/PDIF control */
+/* range 0x3c-0x58 - MODEM */
+#define AC97_EXTENDED_MID	0x3c	/* Extended Modem ID */
+#define AC97_EXTENDED_MSTATUS	0x3e	/* Extended Modem Status and Control */
+#define AC97_LINE1_RATE		0x40	/* Line1 DAC/ADC Rate */
+#define AC97_LINE2_RATE		0x42	/* Line2 DAC/ADC Rate */
+#define AC97_HANDSET_RATE	0x44	/* Handset DAC/ADC Rate */
+#define AC97_LINE1_LEVEL	0x46	/* Line1 DAC/ADC Level */
+#define AC97_LINE2_LEVEL	0x48	/* Line2 DAC/ADC Level */
+#define AC97_HANDSET_LEVEL	0x4a	/* Handset DAC/ADC Level */
+#define AC97_GPIO_CFG		0x4c	/* GPIO Configuration */
+#define AC97_GPIO_POLARITY	0x4e	/* GPIO Pin Polarity/Type, 0=low, 1=high active */
+#define AC97_GPIO_STICKY	0x50	/* GPIO Pin Sticky, 0=not, 1=sticky */
+#define AC97_GPIO_WAKEUP	0x52	/* GPIO Pin Wakeup, 0=no int, 1=yes int */
+#define AC97_GPIO_STATUS	0x54	/* GPIO Pin Status, slot 12 */
+#define AC97_MISC_AFE		0x56	/* Miscellaneous Modem AFE Status and Control */
+/* range 0x5a-0x7b - Vendor Specific */
+#define AC97_VENDOR_ID1		0x7c	/* Vendor ID1 */
+#define AC97_VENDOR_ID2		0x7e	/* Vendor ID2 / revision */
+/* range 0x60-0x6f (page 1) - extended codec registers */
+#define AC97_CODEC_CLASS_REV	0x60	/* Codec Class/Revision */
+#define AC97_PCI_SVID		0x62	/* PCI Subsystem Vendor ID */
+#define AC97_PCI_SID		0x64	/* PCI Subsystem ID */
+#define AC97_FUNC_SELECT	0x66	/* Function Select */
+#define AC97_FUNC_INFO		0x68	/* Function Information */
+#define AC97_SENSE_INFO		0x6a	/* Sense Details */
+
+/* volume controls */
+#define AC97_MUTE_MASK_MONO	0x8000
+#define AC97_MUTE_MASK_STEREO	0x8080
+
+/* slot allocation */
+#define AC97_SLOT_TAG		0
+#define AC97_SLOT_CMD_ADDR	1
+#define AC97_SLOT_CMD_DATA	2
+#define AC97_SLOT_PCM_LEFT	3
+#define AC97_SLOT_PCM_RIGHT	4
+#define AC97_SLOT_MODEM_LINE1	5
+#define AC97_SLOT_PCM_CENTER	6
+#define AC97_SLOT_MIC		6	/* input */
+#define AC97_SLOT_SPDIF_LEFT1	6
+#define AC97_SLOT_PCM_SLEFT	7	/* surround left */
+#define AC97_SLOT_PCM_LEFT_0	7	/* double rate operation */
+#define AC97_SLOT_SPDIF_LEFT	7
+#define AC97_SLOT_PCM_SRIGHT	8	/* surround right */
+#define AC97_SLOT_PCM_RIGHT_0	8	/* double rate operation */
+#define AC97_SLOT_SPDIF_RIGHT	8
+#define AC97_SLOT_LFE		9
+#define AC97_SLOT_SPDIF_RIGHT1	9
+#define AC97_SLOT_MODEM_LINE2	10
+#define AC97_SLOT_PCM_LEFT_1	10	/* double rate operation */
+#define AC97_SLOT_SPDIF_LEFT2	10
+#define AC97_SLOT_HANDSET	11	/* output */
+#define AC97_SLOT_PCM_RIGHT_1	11	/* double rate operation */
+#define AC97_SLOT_SPDIF_RIGHT2	11
+#define AC97_SLOT_MODEM_GPIO	12	/* modem GPIO */
+#define AC97_SLOT_PCM_CENTER_1	12	/* double rate operation */
+
+/* basic capabilities (reset register) */
+#define AC97_BC_DEDICATED_MIC	0x0001	/* Dedicated Mic PCM In Channel */
+#define AC97_BC_RESERVED1	0x0002	/* Reserved (was Modem Line Codec support) */
+#define AC97_BC_BASS_TREBLE	0x0004	/* Bass & Treble Control */
+#define AC97_BC_SIM_STEREO	0x0008	/* Simulated stereo */
+#define AC97_BC_HEADPHONE	0x0010	/* Headphone Out Support */
+#define AC97_BC_LOUDNESS	0x0020	/* Loudness (bass boost) Support */
+#define AC97_BC_16BIT_DAC	0x0000	/* 16-bit DAC resolution */
+#define AC97_BC_18BIT_DAC	0x0040	/* 18-bit DAC resolution */
+#define AC97_BC_20BIT_DAC	0x0080	/* 20-bit DAC resolution */
+#define AC97_BC_DAC_MASK	0x00c0
+#define AC97_BC_16BIT_ADC	0x0000	/* 16-bit ADC resolution */
+#define AC97_BC_18BIT_ADC	0x0100	/* 18-bit ADC resolution */
+#define AC97_BC_20BIT_ADC	0x0200	/* 20-bit ADC resolution */
+#define AC97_BC_ADC_MASK	0x0300
+#define AC97_BC_3D_TECH_ID_MASK	0x7c00	/* Per-vendor ID of 3D enhancement */
+
+/* general purpose */
+#define AC97_GP_DRSS_MASK	0x0c00	/* double rate slot select */
+#define AC97_GP_DRSS_1011	0x0000	/* LR(C) 10+11(+12) */
+#define AC97_GP_DRSS_78		0x0400	/* LR 7+8 */
+
+/* powerdown bits */
+#define AC97_PD_ADC_STATUS	0x0001	/* ADC status (RO) */
+#define AC97_PD_DAC_STATUS	0x0002	/* DAC status (RO) */
+#define AC97_PD_MIXER_STATUS	0x0004	/* Analog mixer status (RO) */
+#define AC97_PD_VREF_STATUS	0x0008	/* Vref status (RO) */
+#define AC97_PD_PR0		0x0100	/* Power down PCM ADCs and input MUX */
+#define AC97_PD_PR1		0x0200	/* Power down PCM front DAC */
+#define AC97_PD_PR2		0x0400	/* Power down Mixer (Vref still on) */
+#define AC97_PD_PR3		0x0800	/* Power down Mixer (Vref off) */
+#define AC97_PD_PR4		0x1000	/* Power down AC-Link */
+#define AC97_PD_PR5		0x2000	/* Disable internal clock usage */
+#define AC97_PD_PR6		0x4000	/* Headphone amplifier */
+#define AC97_PD_EAPD		0x8000	/* External Amplifer Power Down (EAPD) */
+
+/* extended audio ID bit defines */
+#define AC97_EI_VRA		0x0001	/* Variable bit rate supported */
+#define AC97_EI_DRA		0x0002	/* Double rate supported */
+#define AC97_EI_SPDIF		0x0004	/* S/PDIF out supported */
+#define AC97_EI_VRM		0x0008	/* Variable bit rate supported for MIC */
+#define AC97_EI_DACS_SLOT_MASK	0x0030	/* DACs slot assignment */
+#define AC97_EI_DACS_SLOT_SHIFT	4
+#define AC97_EI_CDAC		0x0040	/* PCM Center DAC available */
+#define AC97_EI_SDAC		0x0080	/* PCM Surround DACs available */
+#define AC97_EI_LDAC		0x0100	/* PCM LFE DAC available */
+#define AC97_EI_AMAP		0x0200	/* indicates optional slot/DAC mapping based on codec ID */
+#define AC97_EI_REV_MASK	0x0c00	/* AC'97 revision mask */
+#define AC97_EI_REV_22		0x0400	/* AC'97 revision 2.2 */
+#define AC97_EI_REV_23		0x0800	/* AC'97 revision 2.3 */
+#define AC97_EI_REV_SHIFT	10
+#define AC97_EI_ADDR_MASK	0xc000	/* physical codec ID (address) */
+#define AC97_EI_ADDR_SHIFT	14
+
+/* extended audio status and control bit defines */
+#define AC97_EA_VRA		0x0001	/* Variable bit rate enable bit */
+#define AC97_EA_DRA		0x0002	/* Double-rate audio enable bit */
+#define AC97_EA_SPDIF		0x0004	/* S/PDIF out enable bit */
+#define AC97_EA_VRM		0x0008	/* Variable bit rate for MIC enable bit */
+#define AC97_EA_SPSA_SLOT_MASK	0x0030	/* Mask for slot assignment bits */
+#define AC97_EA_SPSA_SLOT_SHIFT 4
+#define AC97_EA_SPSA_3_4	0x0000	/* Slot assigned to 3 & 4 */
+#define AC97_EA_SPSA_7_8	0x0010	/* Slot assigned to 7 & 8 */
+#define AC97_EA_SPSA_6_9	0x0020	/* Slot assigned to 6 & 9 */
+#define AC97_EA_SPSA_10_11	0x0030	/* Slot assigned to 10 & 11 */
+#define AC97_EA_CDAC		0x0040	/* PCM Center DAC is ready (Read only) */
+#define AC97_EA_SDAC		0x0080	/* PCM Surround DACs are ready (Read only) */
+#define AC97_EA_LDAC		0x0100	/* PCM LFE DAC is ready (Read only) */
+#define AC97_EA_MDAC		0x0200	/* MIC ADC is ready (Read only) */
+#define AC97_EA_SPCV		0x0400	/* S/PDIF configuration valid (Read only) */
+#define AC97_EA_PRI		0x0800	/* Turns the PCM Center DAC off */
+#define AC97_EA_PRJ		0x1000	/* Turns the PCM Surround DACs off */
+#define AC97_EA_PRK		0x2000	/* Turns the PCM LFE DAC off */
+#define AC97_EA_PRL		0x4000	/* Turns the MIC ADC off */
+
+/* S/PDIF control bit defines */
+#define AC97_SC_PRO		0x0001	/* Professional status */
+#define AC97_SC_NAUDIO		0x0002	/* Non audio stream */
+#define AC97_SC_COPY		0x0004	/* Copyright status */
+#define AC97_SC_PRE		0x0008	/* Preemphasis status */
+#define AC97_SC_CC_MASK		0x07f0	/* Category Code mask */
+#define AC97_SC_CC_SHIFT	4
+#define AC97_SC_L		0x0800	/* Generation Level status */
+#define AC97_SC_SPSR_MASK	0x3000	/* S/PDIF Sample Rate bits */
+#define AC97_SC_SPSR_SHIFT	12
+#define AC97_SC_SPSR_44K	0x0000	/* Use 44.1kHz Sample rate */
+#define AC97_SC_SPSR_48K	0x2000	/* Use 48kHz Sample rate */
+#define AC97_SC_SPSR_32K	0x3000	/* Use 32kHz Sample rate */
+#define AC97_SC_DRS		0x4000	/* Double Rate S/PDIF */
+#define AC97_SC_V		0x8000	/* Validity status */
+
+/* Interrupt and Paging bit defines (AC'97 2.3) */
+#define AC97_PAGE_MASK		0x000f	/* Page Selector */
+#define AC97_PAGE_VENDOR	0	/* Vendor-specific registers */
+#define AC97_PAGE_1		1	/* Extended Codec Registers page 1 */
+#define AC97_INT_ENABLE		0x0800	/* Interrupt Enable */
+#define AC97_INT_SENSE		0x1000	/* Sense Cycle */
+#define AC97_INT_CAUSE_SENSE	0x2000	/* Sense Cycle Completed (RO) */
+#define AC97_INT_CAUSE_GPIO	0x4000	/* GPIO bits changed (RO) */
+#define AC97_INT_STATUS		0x8000	/* Interrupt Status */
+
+/* extended modem ID bit defines */
+#define AC97_MEI_LINE1		0x0001	/* Line1 present */
+#define AC97_MEI_LINE2		0x0002	/* Line2 present */
+#define AC97_MEI_HANDSET	0x0004	/* Handset present */
+#define AC97_MEI_CID1		0x0008	/* caller ID decode for Line1 is supported */
+#define AC97_MEI_CID2		0x0010	/* caller ID decode for Line2 is supported */
+#define AC97_MEI_ADDR_MASK	0xc000	/* physical codec ID (address) */
+#define AC97_MEI_ADDR_SHIFT	14
+
+/* extended modem status and control bit defines */
+#define AC97_MEA_GPIO		0x0001	/* GPIO is ready (ro) */
+#define AC97_MEA_MREF		0x0002	/* Vref is up to nominal level (ro) */
+#define AC97_MEA_ADC1		0x0004	/* ADC1 operational (ro) */
+#define AC97_MEA_DAC1		0x0008	/* DAC1 operational (ro) */
+#define AC97_MEA_ADC2		0x0010	/* ADC2 operational (ro) */
+#define AC97_MEA_DAC2		0x0020	/* DAC2 operational (ro) */
+#define AC97_MEA_HADC		0x0040	/* HADC operational (ro) */
+#define AC97_MEA_HDAC		0x0080	/* HDAC operational (ro) */
+#define AC97_MEA_PRA		0x0100	/* GPIO power down (high) */
+#define AC97_MEA_PRB		0x0200	/* reserved */
+#define AC97_MEA_PRC		0x0400	/* ADC1 power down (high) */
+#define AC97_MEA_PRD		0x0800	/* DAC1 power down (high) */
+#define AC97_MEA_PRE		0x1000	/* ADC2 power down (high) */
+#define AC97_MEA_PRF		0x2000	/* DAC2 power down (high) */
+#define AC97_MEA_PRG		0x4000	/* HADC power down (high) */
+#define AC97_MEA_PRH		0x8000	/* HDAC power down (high) */
+
+/* modem gpio status defines */
+#define AC97_GPIO_LINE1_OH      0x0001  /* Off Hook Line1 */
+#define AC97_GPIO_LINE1_RI      0x0002  /* Ring Detect Line1 */
+#define AC97_GPIO_LINE1_CID     0x0004  /* Caller ID path enable Line1 */
+#define AC97_GPIO_LINE1_LCS     0x0008  /* Loop Current Sense Line1 */
+#define AC97_GPIO_LINE1_PULSE   0x0010  /* Opt./ Pulse Dial Line1 (out) */
+#define AC97_GPIO_LINE1_HL1R    0x0020  /* Opt./ Handset to Line1 relay control (out) */
+#define AC97_GPIO_LINE1_HOHD    0x0040  /* Opt./ Handset off hook detect Line1 (in) */
+#define AC97_GPIO_LINE12_AC     0x0080  /* Opt./ Int.bit 1 / Line1/2 AC (out) */
+#define AC97_GPIO_LINE12_DC     0x0100  /* Opt./ Int.bit 2 / Line1/2 DC (out) */
+#define AC97_GPIO_LINE12_RS     0x0200  /* Opt./ Int.bit 3 / Line1/2 RS (out) */
+#define AC97_GPIO_LINE2_OH      0x0400  /* Off Hook Line2 */
+#define AC97_GPIO_LINE2_RI      0x0800  /* Ring Detect Line2 */
+#define AC97_GPIO_LINE2_CID     0x1000  /* Caller ID path enable Line2 */
+#define AC97_GPIO_LINE2_LCS     0x2000  /* Loop Current Sense Line2 */
+#define AC97_GPIO_LINE2_PULSE   0x4000  /* Opt./ Pulse Dial Line2 (out) */
+#define AC97_GPIO_LINE2_HL1R    0x8000  /* Opt./ Handset to Line2 relay control (out) */
+
diff --git a/include/sound/ac97_codec.h b/include/sound/ac97_codec.h
index 15aa5f07c955..89d311a503d3 100644
--- a/include/sound/ac97_codec.h
+++ b/include/sound/ac97_codec.h
@@ -28,6 +28,7 @@
 #include <linux/bitops.h>
 #include <linux/device.h>
 #include <linux/workqueue.h>
+#include <sound/ac97/regs.h>
 #include <sound/pcm.h>
 #include <sound/control.h>
 #include <sound/info.h>
@@ -35,244 +36,6 @@
 /* maximum number of devices on the AC97 bus */
 #define	AC97_BUS_MAX_DEVICES	4
 
-/*
- *  AC'97 codec registers
- */
-
-#define AC97_RESET		0x00	/* Reset */
-#define AC97_MASTER		0x02	/* Master Volume */
-#define AC97_HEADPHONE		0x04	/* Headphone Volume (optional) */
-#define AC97_MASTER_MONO	0x06	/* Master Volume Mono (optional) */
-#define AC97_MASTER_TONE	0x08	/* Master Tone (Bass & Treble) (optional) */
-#define AC97_PC_BEEP		0x0a	/* PC Beep Volume (optinal) */
-#define AC97_PHONE		0x0c	/* Phone Volume (optional) */
-#define AC97_MIC		0x0e	/* MIC Volume */
-#define AC97_LINE		0x10	/* Line In Volume */
-#define AC97_CD			0x12	/* CD Volume */
-#define AC97_VIDEO		0x14	/* Video Volume (optional) */
-#define AC97_AUX		0x16	/* AUX Volume (optional) */
-#define AC97_PCM		0x18	/* PCM Volume */
-#define AC97_REC_SEL		0x1a	/* Record Select */
-#define AC97_REC_GAIN		0x1c	/* Record Gain */
-#define AC97_REC_GAIN_MIC	0x1e	/* Record Gain MIC (optional) */
-#define AC97_GENERAL_PURPOSE	0x20	/* General Purpose (optional) */
-#define AC97_3D_CONTROL		0x22	/* 3D Control (optional) */
-#define AC97_INT_PAGING		0x24	/* Audio Interrupt & Paging (AC'97 2.3) */
-#define AC97_POWERDOWN		0x26	/* Powerdown control / status */
-/* range 0x28-0x3a - AUDIO AC'97 2.0 extensions */
-#define AC97_EXTENDED_ID	0x28	/* Extended Audio ID */
-#define AC97_EXTENDED_STATUS	0x2a	/* Extended Audio Status and Control */
-#define AC97_PCM_FRONT_DAC_RATE 0x2c	/* PCM Front DAC Rate */
-#define AC97_PCM_SURR_DAC_RATE	0x2e	/* PCM Surround DAC Rate */
-#define AC97_PCM_LFE_DAC_RATE	0x30	/* PCM LFE DAC Rate */
-#define AC97_PCM_LR_ADC_RATE	0x32	/* PCM LR ADC Rate */
-#define AC97_PCM_MIC_ADC_RATE	0x34	/* PCM MIC ADC Rate */
-#define AC97_CENTER_LFE_MASTER	0x36	/* Center + LFE Master Volume */
-#define AC97_SURROUND_MASTER	0x38	/* Surround (Rear) Master Volume */
-#define AC97_SPDIF		0x3a	/* S/PDIF control */
-/* range 0x3c-0x58 - MODEM */
-#define AC97_EXTENDED_MID	0x3c	/* Extended Modem ID */
-#define AC97_EXTENDED_MSTATUS	0x3e	/* Extended Modem Status and Control */
-#define AC97_LINE1_RATE		0x40	/* Line1 DAC/ADC Rate */
-#define AC97_LINE2_RATE		0x42	/* Line2 DAC/ADC Rate */
-#define AC97_HANDSET_RATE	0x44	/* Handset DAC/ADC Rate */
-#define AC97_LINE1_LEVEL	0x46	/* Line1 DAC/ADC Level */
-#define AC97_LINE2_LEVEL	0x48	/* Line2 DAC/ADC Level */
-#define AC97_HANDSET_LEVEL	0x4a	/* Handset DAC/ADC Level */
-#define AC97_GPIO_CFG		0x4c	/* GPIO Configuration */
-#define AC97_GPIO_POLARITY	0x4e	/* GPIO Pin Polarity/Type, 0=low, 1=high active */
-#define AC97_GPIO_STICKY	0x50	/* GPIO Pin Sticky, 0=not, 1=sticky */
-#define AC97_GPIO_WAKEUP	0x52	/* GPIO Pin Wakeup, 0=no int, 1=yes int */
-#define AC97_GPIO_STATUS	0x54	/* GPIO Pin Status, slot 12 */
-#define AC97_MISC_AFE		0x56	/* Miscellaneous Modem AFE Status and Control */
-/* range 0x5a-0x7b - Vendor Specific */
-#define AC97_VENDOR_ID1		0x7c	/* Vendor ID1 */
-#define AC97_VENDOR_ID2		0x7e	/* Vendor ID2 / revision */
-/* range 0x60-0x6f (page 1) - extended codec registers */
-#define AC97_CODEC_CLASS_REV	0x60	/* Codec Class/Revision */
-#define AC97_PCI_SVID		0x62	/* PCI Subsystem Vendor ID */
-#define AC97_PCI_SID		0x64	/* PCI Subsystem ID */
-#define AC97_FUNC_SELECT	0x66	/* Function Select */
-#define AC97_FUNC_INFO		0x68	/* Function Information */
-#define AC97_SENSE_INFO		0x6a	/* Sense Details */
-
-/* volume controls */
-#define AC97_MUTE_MASK_MONO	0x8000
-#define AC97_MUTE_MASK_STEREO	0x8080
-
-/* slot allocation */
-#define AC97_SLOT_TAG		0
-#define AC97_SLOT_CMD_ADDR	1
-#define AC97_SLOT_CMD_DATA	2
-#define AC97_SLOT_PCM_LEFT	3
-#define AC97_SLOT_PCM_RIGHT	4
-#define AC97_SLOT_MODEM_LINE1	5
-#define AC97_SLOT_PCM_CENTER	6
-#define AC97_SLOT_MIC		6	/* input */
-#define AC97_SLOT_SPDIF_LEFT1	6
-#define AC97_SLOT_PCM_SLEFT	7	/* surround left */
-#define AC97_SLOT_PCM_LEFT_0	7	/* double rate operation */
-#define AC97_SLOT_SPDIF_LEFT	7
-#define AC97_SLOT_PCM_SRIGHT	8	/* surround right */
-#define AC97_SLOT_PCM_RIGHT_0	8	/* double rate operation */
-#define AC97_SLOT_SPDIF_RIGHT	8
-#define AC97_SLOT_LFE		9
-#define AC97_SLOT_SPDIF_RIGHT1	9
-#define AC97_SLOT_MODEM_LINE2	10
-#define AC97_SLOT_PCM_LEFT_1	10	/* double rate operation */
-#define AC97_SLOT_SPDIF_LEFT2	10
-#define AC97_SLOT_HANDSET	11	/* output */
-#define AC97_SLOT_PCM_RIGHT_1	11	/* double rate operation */
-#define AC97_SLOT_SPDIF_RIGHT2	11
-#define AC97_SLOT_MODEM_GPIO	12	/* modem GPIO */
-#define AC97_SLOT_PCM_CENTER_1	12	/* double rate operation */
-
-/* basic capabilities (reset register) */
-#define AC97_BC_DEDICATED_MIC	0x0001	/* Dedicated Mic PCM In Channel */
-#define AC97_BC_RESERVED1	0x0002	/* Reserved (was Modem Line Codec support) */
-#define AC97_BC_BASS_TREBLE	0x0004	/* Bass & Treble Control */
-#define AC97_BC_SIM_STEREO	0x0008	/* Simulated stereo */
-#define AC97_BC_HEADPHONE	0x0010	/* Headphone Out Support */
-#define AC97_BC_LOUDNESS	0x0020	/* Loudness (bass boost) Support */
-#define AC97_BC_16BIT_DAC	0x0000	/* 16-bit DAC resolution */
-#define AC97_BC_18BIT_DAC	0x0040	/* 18-bit DAC resolution */
-#define AC97_BC_20BIT_DAC	0x0080	/* 20-bit DAC resolution */
-#define AC97_BC_DAC_MASK	0x00c0
-#define AC97_BC_16BIT_ADC	0x0000	/* 16-bit ADC resolution */
-#define AC97_BC_18BIT_ADC	0x0100	/* 18-bit ADC resolution */
-#define AC97_BC_20BIT_ADC	0x0200	/* 20-bit ADC resolution */
-#define AC97_BC_ADC_MASK	0x0300
-#define AC97_BC_3D_TECH_ID_MASK	0x7c00	/* Per-vendor ID of 3D enhancement */
-
-/* general purpose */
-#define AC97_GP_DRSS_MASK	0x0c00	/* double rate slot select */
-#define AC97_GP_DRSS_1011	0x0000	/* LR(C) 10+11(+12) */
-#define AC97_GP_DRSS_78		0x0400	/* LR 7+8 */
-
-/* powerdown bits */
-#define AC97_PD_ADC_STATUS	0x0001	/* ADC status (RO) */
-#define AC97_PD_DAC_STATUS	0x0002	/* DAC status (RO) */
-#define AC97_PD_MIXER_STATUS	0x0004	/* Analog mixer status (RO) */
-#define AC97_PD_VREF_STATUS	0x0008	/* Vref status (RO) */
-#define AC97_PD_PR0		0x0100	/* Power down PCM ADCs and input MUX */
-#define AC97_PD_PR1		0x0200	/* Power down PCM front DAC */
-#define AC97_PD_PR2		0x0400	/* Power down Mixer (Vref still on) */
-#define AC97_PD_PR3		0x0800	/* Power down Mixer (Vref off) */
-#define AC97_PD_PR4		0x1000	/* Power down AC-Link */
-#define AC97_PD_PR5		0x2000	/* Disable internal clock usage */
-#define AC97_PD_PR6		0x4000	/* Headphone amplifier */
-#define AC97_PD_EAPD		0x8000	/* External Amplifer Power Down (EAPD) */
-
-/* extended audio ID bit defines */
-#define AC97_EI_VRA		0x0001	/* Variable bit rate supported */
-#define AC97_EI_DRA		0x0002	/* Double rate supported */
-#define AC97_EI_SPDIF		0x0004	/* S/PDIF out supported */
-#define AC97_EI_VRM		0x0008	/* Variable bit rate supported for MIC */
-#define AC97_EI_DACS_SLOT_MASK	0x0030	/* DACs slot assignment */
-#define AC97_EI_DACS_SLOT_SHIFT	4
-#define AC97_EI_CDAC		0x0040	/* PCM Center DAC available */
-#define AC97_EI_SDAC		0x0080	/* PCM Surround DACs available */
-#define AC97_EI_LDAC		0x0100	/* PCM LFE DAC available */
-#define AC97_EI_AMAP		0x0200	/* indicates optional slot/DAC mapping based on codec ID */
-#define AC97_EI_REV_MASK	0x0c00	/* AC'97 revision mask */
-#define AC97_EI_REV_22		0x0400	/* AC'97 revision 2.2 */
-#define AC97_EI_REV_23		0x0800	/* AC'97 revision 2.3 */
-#define AC97_EI_REV_SHIFT	10
-#define AC97_EI_ADDR_MASK	0xc000	/* physical codec ID (address) */
-#define AC97_EI_ADDR_SHIFT	14
-
-/* extended audio status and control bit defines */
-#define AC97_EA_VRA		0x0001	/* Variable bit rate enable bit */
-#define AC97_EA_DRA		0x0002	/* Double-rate audio enable bit */
-#define AC97_EA_SPDIF		0x0004	/* S/PDIF out enable bit */
-#define AC97_EA_VRM		0x0008	/* Variable bit rate for MIC enable bit */
-#define AC97_EA_SPSA_SLOT_MASK	0x0030	/* Mask for slot assignment bits */
-#define AC97_EA_SPSA_SLOT_SHIFT 4
-#define AC97_EA_SPSA_3_4	0x0000	/* Slot assigned to 3 & 4 */
-#define AC97_EA_SPSA_7_8	0x0010	/* Slot assigned to 7 & 8 */
-#define AC97_EA_SPSA_6_9	0x0020	/* Slot assigned to 6 & 9 */
-#define AC97_EA_SPSA_10_11	0x0030	/* Slot assigned to 10 & 11 */
-#define AC97_EA_CDAC		0x0040	/* PCM Center DAC is ready (Read only) */
-#define AC97_EA_SDAC		0x0080	/* PCM Surround DACs are ready (Read only) */
-#define AC97_EA_LDAC		0x0100	/* PCM LFE DAC is ready (Read only) */
-#define AC97_EA_MDAC		0x0200	/* MIC ADC is ready (Read only) */
-#define AC97_EA_SPCV		0x0400	/* S/PDIF configuration valid (Read only) */
-#define AC97_EA_PRI		0x0800	/* Turns the PCM Center DAC off */
-#define AC97_EA_PRJ		0x1000	/* Turns the PCM Surround DACs off */
-#define AC97_EA_PRK		0x2000	/* Turns the PCM LFE DAC off */
-#define AC97_EA_PRL		0x4000	/* Turns the MIC ADC off */
-
-/* S/PDIF control bit defines */
-#define AC97_SC_PRO		0x0001	/* Professional status */
-#define AC97_SC_NAUDIO		0x0002	/* Non audio stream */
-#define AC97_SC_COPY		0x0004	/* Copyright status */
-#define AC97_SC_PRE		0x0008	/* Preemphasis status */
-#define AC97_SC_CC_MASK		0x07f0	/* Category Code mask */
-#define AC97_SC_CC_SHIFT	4
-#define AC97_SC_L		0x0800	/* Generation Level status */
-#define AC97_SC_SPSR_MASK	0x3000	/* S/PDIF Sample Rate bits */
-#define AC97_SC_SPSR_SHIFT	12
-#define AC97_SC_SPSR_44K	0x0000	/* Use 44.1kHz Sample rate */
-#define AC97_SC_SPSR_48K	0x2000	/* Use 48kHz Sample rate */
-#define AC97_SC_SPSR_32K	0x3000	/* Use 32kHz Sample rate */
-#define AC97_SC_DRS		0x4000	/* Double Rate S/PDIF */
-#define AC97_SC_V		0x8000	/* Validity status */
-
-/* Interrupt and Paging bit defines (AC'97 2.3) */
-#define AC97_PAGE_MASK		0x000f	/* Page Selector */
-#define AC97_PAGE_VENDOR	0	/* Vendor-specific registers */
-#define AC97_PAGE_1		1	/* Extended Codec Registers page 1 */
-#define AC97_INT_ENABLE		0x0800	/* Interrupt Enable */
-#define AC97_INT_SENSE		0x1000	/* Sense Cycle */
-#define AC97_INT_CAUSE_SENSE	0x2000	/* Sense Cycle Completed (RO) */
-#define AC97_INT_CAUSE_GPIO	0x4000	/* GPIO bits changed (RO) */
-#define AC97_INT_STATUS		0x8000	/* Interrupt Status */
-
-/* extended modem ID bit defines */
-#define AC97_MEI_LINE1		0x0001	/* Line1 present */
-#define AC97_MEI_LINE2		0x0002	/* Line2 present */
-#define AC97_MEI_HANDSET	0x0004	/* Handset present */
-#define AC97_MEI_CID1		0x0008	/* caller ID decode for Line1 is supported */
-#define AC97_MEI_CID2		0x0010	/* caller ID decode for Line2 is supported */
-#define AC97_MEI_ADDR_MASK	0xc000	/* physical codec ID (address) */
-#define AC97_MEI_ADDR_SHIFT	14
-
-/* extended modem status and control bit defines */
-#define AC97_MEA_GPIO		0x0001	/* GPIO is ready (ro) */
-#define AC97_MEA_MREF		0x0002	/* Vref is up to nominal level (ro) */
-#define AC97_MEA_ADC1		0x0004	/* ADC1 operational (ro) */
-#define AC97_MEA_DAC1		0x0008	/* DAC1 operational (ro) */
-#define AC97_MEA_ADC2		0x0010	/* ADC2 operational (ro) */
-#define AC97_MEA_DAC2		0x0020	/* DAC2 operational (ro) */
-#define AC97_MEA_HADC		0x0040	/* HADC operational (ro) */
-#define AC97_MEA_HDAC		0x0080	/* HDAC operational (ro) */
-#define AC97_MEA_PRA		0x0100	/* GPIO power down (high) */
-#define AC97_MEA_PRB		0x0200	/* reserved */
-#define AC97_MEA_PRC		0x0400	/* ADC1 power down (high) */
-#define AC97_MEA_PRD		0x0800	/* DAC1 power down (high) */
-#define AC97_MEA_PRE		0x1000	/* ADC2 power down (high) */
-#define AC97_MEA_PRF		0x2000	/* DAC2 power down (high) */
-#define AC97_MEA_PRG		0x4000	/* HADC power down (high) */
-#define AC97_MEA_PRH		0x8000	/* HDAC power down (high) */
-
-/* modem gpio status defines */
-#define AC97_GPIO_LINE1_OH      0x0001  /* Off Hook Line1 */
-#define AC97_GPIO_LINE1_RI      0x0002  /* Ring Detect Line1 */
-#define AC97_GPIO_LINE1_CID     0x0004  /* Caller ID path enable Line1 */
-#define AC97_GPIO_LINE1_LCS     0x0008  /* Loop Current Sense Line1 */
-#define AC97_GPIO_LINE1_PULSE   0x0010  /* Opt./ Pulse Dial Line1 (out) */
-#define AC97_GPIO_LINE1_HL1R    0x0020  /* Opt./ Handset to Line1 relay control (out) */
-#define AC97_GPIO_LINE1_HOHD    0x0040  /* Opt./ Handset off hook detect Line1 (in) */
-#define AC97_GPIO_LINE12_AC     0x0080  /* Opt./ Int.bit 1 / Line1/2 AC (out) */
-#define AC97_GPIO_LINE12_DC     0x0100  /* Opt./ Int.bit 2 / Line1/2 DC (out) */
-#define AC97_GPIO_LINE12_RS     0x0200  /* Opt./ Int.bit 3 / Line1/2 RS (out) */
-#define AC97_GPIO_LINE2_OH      0x0400  /* Off Hook Line2 */
-#define AC97_GPIO_LINE2_RI      0x0800  /* Ring Detect Line2 */
-#define AC97_GPIO_LINE2_CID     0x1000  /* Caller ID path enable Line2 */
-#define AC97_GPIO_LINE2_LCS     0x2000  /* Loop Current Sense Line2 */
-#define AC97_GPIO_LINE2_PULSE   0x4000  /* Opt./ Pulse Dial Line2 (out) */
-#define AC97_GPIO_LINE2_HL1R    0x8000  /* Opt./ Handset to Line2 relay control (out) */
-
 /* specific - SigmaTel */
 #define AC97_SIGMATEL_OUTSEL	0x64	/* Output Select, STAC9758 */
 #define AC97_SIGMATEL_INSEL	0x66	/* Input Select, STAC9758 */
-- 
2.1.4

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

* [RFC PATCH 2/7] ALSA: ac97: add an ac97 bus
  2016-04-30 21:15 ` Robert Jarzmik
@ 2016-04-30 21:15   ` Robert Jarzmik
  -1 siblings, 0 replies; 74+ messages in thread
From: Robert Jarzmik @ 2016-04-30 21:15 UTC (permalink / raw)
  To: Robert Jarzmik, Daniel Mack, Haojian Zhuang, Jaroslav Kysela,
	Takashi Iwai, Liam Girdwood, Mark Brown
  Cc: linux-arm-kernel, linux-kernel, alsa-devel, patches

AC97 is a bus for sound usage. It enables for a AC97 AC-Link to link one
controller to 0 to 4 AC97 codecs.

The goal of this new implementation is to implement a device/driver
model for AC97, with an automatic scan of the bus and automatic
discovery of AC97 codec devices.

Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
---
 include/sound/ac97/codec.h      |  98 ++++++++++++
 include/sound/ac97/compat.h     |  21 +++
 include/sound/ac97/controller.h |  39 +++++
 sound/ac97/Kconfig              |   9 ++
 sound/ac97/Makefile             |   5 +
 sound/ac97/ac97_core.h          |  10 ++
 sound/ac97/bus.c                | 330 ++++++++++++++++++++++++++++++++++++++++
 sound/ac97/codec.c              |  15 ++
 sound/ac97/snd_ac97_compat.c    | 104 +++++++++++++
 9 files changed, 631 insertions(+)
 create mode 100644 include/sound/ac97/codec.h
 create mode 100644 include/sound/ac97/compat.h
 create mode 100644 include/sound/ac97/controller.h
 create mode 100644 sound/ac97/Kconfig
 create mode 100644 sound/ac97/Makefile
 create mode 100644 sound/ac97/ac97_core.h
 create mode 100644 sound/ac97/bus.c
 create mode 100644 sound/ac97/codec.c
 create mode 100644 sound/ac97/snd_ac97_compat.c

diff --git a/include/sound/ac97/codec.h b/include/sound/ac97/codec.h
new file mode 100644
index 000000000000..4b8b3e570892
--- /dev/null
+++ b/include/sound/ac97/codec.h
@@ -0,0 +1,98 @@
+/*
+ *  Copyright (C) 2016 Robert Jarzmik <robert.jarzmik@free.fr>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef AC97_CODEC_H
+#define AC97_CODEC_H
+
+#include <linux/device.h>
+
+#define AC97_ID(vendor_id1, vendor_id2) \
+	(((vendor_id1 & 0xffff) << 16) | (vendor_id2 & 0xffff))
+#define AC97_DRIVER_ID(vendor_id1, vendor_id2, mask_id1, mask_id2, _data) \
+	{ .id = ((vendor_id1 & 0xffff) << 16) | (vendor_id2 & 0xffff), \
+	  .mask = ((mask_id1 & 0xffff) << 16) | (mask_id2 & 0xffff), \
+	  .data = _data }
+
+#define to_ac97_device(d) container_of(d, struct ac97_codec_device, dev)
+#define to_ac97_driver(d) container_of(d, struct ac97_codec_driver, driver)
+
+struct ac97_controller;
+
+/**
+ * struct ac97_id - matches a codec device and driver on an ac97 bus
+ * @id: The significant bits if the codec vendor ID1 and ID2
+ * @mask: Bitmask specifying which bits of the id field are significant when
+ *	  matching. A driver binds to a device when :
+ *        ((vendorID1 << 8 | vendorID2) & (mask_id1 << 8 | mask_id2)) == id.
+ * @data: Private data used by the driver.
+ */
+struct ac97_id {
+	unsigned int		id;
+	unsigned int		mask;
+	void			*data;
+};
+
+/**
+ * ac97_codec_device - a ac97 codec
+ * @dev: the code device
+ * @vendor_id: the vendor_id of the codec, as sensed on the AC-link
+ * @num: the codec number, 0 is primary, 1 is first slave, etc ...
+ * @ac97_ctrl: ac97 digital controller on the same AC-link
+ *
+ * This is the device instanciated for each codec living on a AC-link. There are
+ * normally 0 to 4 codec devices per AC-link, and all of them are controlled by
+ * an AC97 digital controller.
+ */
+struct ac97_codec_device {
+	struct device		dev;	/* Must stay first member */
+	unsigned int		vendor_id;
+	unsigned int		num;
+	struct list_head	list;
+	struct ac97_controller	*ac97_ctrl;
+};
+
+/**
+ * ac97_codec_driver - a ac97 codec driver
+ * @driver: the device driver structure
+ * @probe: the function called when a ac97_codec_device is matched
+ * @remove: the function called when the device is unbound/removed
+ * @suspend: suspend function (might be NULL)
+ * @resume: resume function (might be NULL)
+ * @shutdown: shutdown function (might be NULL)
+ * @id_table: ac97 vendor_id match table, { } member terminated
+ */
+struct ac97_codec_driver {
+	struct device_driver	driver;
+	int			(*probe)(struct ac97_codec_device *);
+	int			(*remove)(struct ac97_codec_device *);
+	int			(*suspend)(struct ac97_codec_device *);
+	int			(*resume)(struct ac97_codec_device *);
+	void			(*shutdown)(struct ac97_codec_device *);
+	struct ac97_id		*id_table;
+};
+
+int ac97_codec_driver_register(struct ac97_codec_driver *drv);
+void ac97_codec_driver_unregister(struct ac97_codec_driver *drv);
+
+static inline struct device *
+ac97_codec_dev2dev(const struct ac97_codec_device *adev)
+{
+	return (struct device *)(adev);
+}
+
+static inline void *ac97_get_drvdata(const struct ac97_codec_device *adev)
+{
+	return dev_get_drvdata(ac97_codec_dev2dev(adev));
+}
+
+static inline void ac97_set_drvdata(const struct ac97_codec_device *adev,
+				    void *data)
+{
+	dev_set_drvdata(ac97_codec_dev2dev(adev), data);
+}
+
+#endif
diff --git a/include/sound/ac97/compat.h b/include/sound/ac97/compat.h
new file mode 100644
index 000000000000..bf611f572f2d
--- /dev/null
+++ b/include/sound/ac97/compat.h
@@ -0,0 +1,21 @@
+/*
+ *  Copyright (C) 2016 Robert Jarzmik <robert.jarzmik@free.fr>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This file is for backward compatibility with snd_ac97 structure and its
+ * multiple usages, such as the snd_ac97_bus and snd_ac97_build_ops.
+ *
+ */
+#ifndef AC97_COMPAT_H
+#define AC97_COMPAT_H
+
+#include <sound/ac97_codec.h>
+#include <sound/soc.h>
+
+struct snd_ac97 *compat_alloc_snd_ac97_codec(struct snd_soc_codec *codec);
+void compat_release_snd_ac97_codec(struct snd_ac97 *ac97);
+
+#endif
diff --git a/include/sound/ac97/controller.h b/include/sound/ac97/controller.h
new file mode 100644
index 000000000000..f1e5e645f5ef
--- /dev/null
+++ b/include/sound/ac97/controller.h
@@ -0,0 +1,39 @@
+/*
+ *  Copyright (C) 2016 Robert Jarzmik <robert.jarzmik@free.fr>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef AC97_CONTROLLER_H
+#define AC97_CONTROLLER_H
+
+#include <linux/list.h>
+
+struct device;
+struct ac97_codec_device;
+
+struct ac97_controller_ops {
+	void (*reset)(struct ac97_codec_device *ac97);
+	void (*warm_reset)(struct ac97_codec_device *ac97);
+	int (*write)(struct ac97_codec_device *ac97, unsigned short reg,
+		     unsigned short val);
+	int (*read)(struct ac97_codec_device *ac97, unsigned short reg);
+	void (*wait)(struct ac97_codec_device *ac97);
+	void (*init)(struct ac97_codec_device *ac97);
+};
+
+struct ac97_controller {
+	const struct ac97_controller_ops *ops;
+	struct list_head controllers;
+	struct device *dev;
+	int bus_idx;
+	int bound_codecs;
+	struct list_head codecs;
+};
+
+int ac97_digital_controller_register(const struct ac97_controller_ops *ops,
+				     struct device *dev);
+int ac97_digital_controller_unregister(const struct device *dev);
+
+#endif
diff --git a/sound/ac97/Kconfig b/sound/ac97/Kconfig
new file mode 100644
index 000000000000..fd2c2d031e62
--- /dev/null
+++ b/sound/ac97/Kconfig
@@ -0,0 +1,9 @@
+#
+# PCI configuration
+#
+
+config AC97
+	bool "AC97 bus"
+	help
+	   Say Y here if you want to have AC97 devices, which are sound oriented
+	   devices around an AC-Link.
diff --git a/sound/ac97/Makefile b/sound/ac97/Makefile
new file mode 100644
index 000000000000..5575909d46e2
--- /dev/null
+++ b/sound/ac97/Makefile
@@ -0,0 +1,5 @@
+#
+# make for AC97 bus drivers
+#
+
+obj-y	+= bus.o codec.o snd_ac97_compat.o
diff --git a/sound/ac97/ac97_core.h b/sound/ac97/ac97_core.h
new file mode 100644
index 000000000000..db6e27288357
--- /dev/null
+++ b/sound/ac97/ac97_core.h
@@ -0,0 +1,10 @@
+/*
+ * Copyright (C) 2016 Robert Jarzmik <robert.jarzmik@free.fr>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+unsigned int ac97_bus_scan_one(struct ac97_controller *ac97,
+			       int codec_num);
diff --git a/sound/ac97/bus.c b/sound/ac97/bus.c
new file mode 100644
index 000000000000..f9bf5632d4aa
--- /dev/null
+++ b/sound/ac97/bus.c
@@ -0,0 +1,330 @@
+/*
+ * Copyright (C) 2016 Robert Jarzmik <robert.jarzmik@free.fr>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <linux/pm.h>
+#include <linux/slab.h>
+#include <sound/ac97/codec.h>
+#include <sound/ac97/controller.h>
+#include <sound/ac97/regs.h>
+
+#define AC97_BUS_MAX_CODECS 4
+
+/*
+ * Protects ac97_controllers and each ac97_controller structure.
+ */
+static DEFINE_MUTEX(ac97_controllers_mutex);
+static LIST_HEAD(ac97_controllers);
+static int ac97_bus_idx;
+
+struct bus_type ac97_bus_type;
+
+static struct ac97_codec_device *
+ac97_codec_find(struct ac97_controller *ac97_ctrl, int codec_num)
+{
+	struct ac97_codec_device *codec;
+
+	list_for_each_entry(codec, &ac97_ctrl->codecs, list)
+		if (codec->num == codec_num)
+			return codec;
+
+	return NULL;
+}
+
+static void ac97_codec_release(struct device *dev)
+{
+	struct ac97_codec_device *codec;
+
+	codec = container_of(dev, struct ac97_codec_device, dev);
+	list_del(&codec->list);
+	kfree(codec);
+}
+
+static int ac97_codec_add(struct ac97_controller *ac97_ctrl, int idx,
+		   unsigned int vendor_id)
+{
+	struct ac97_codec_device *codec;
+	char *codec_name;
+	int ret;
+
+	codec = kzalloc(sizeof(*codec), GFP_KERNEL);
+	if (!codec)
+		return -ENOMEM;
+
+	codec->vendor_id = vendor_id;
+	codec->dev.release = ac97_codec_release;
+	codec->dev.bus = &ac97_bus_type;
+	codec->dev.parent = ac97_ctrl->dev;
+	codec->num = idx;
+	codec->ac97_ctrl = ac97_ctrl;
+	INIT_LIST_HEAD(&codec->list);
+	list_move_tail(&codec->list, &ac97_ctrl->codecs);
+
+	codec_name = kasprintf(GFP_KERNEL, "%s:%d", dev_name(ac97_ctrl->dev),
+			       idx);
+	codec->dev.init_name = codec_name;
+
+	ret = device_register(&codec->dev);
+	kfree(codec_name);
+
+	return ret;
+}
+
+unsigned int ac97_bus_scan_one(struct ac97_controller *ac97,
+				      int codec_num)
+{
+	struct ac97_codec_device codec;
+	unsigned short vid1, vid2;
+	int ret;
+
+	codec.dev = *ac97->dev;
+	codec.num = codec_num;
+	ret = ac97->ops->read(&codec, AC97_VENDOR_ID1);
+	vid1 = (ret & 0xffff);
+	if (ret < 0)
+		return 0;
+
+	ret = ac97->ops->read(&codec, AC97_VENDOR_ID2);
+	vid2 = (ret & 0xffff);
+	if (ret < 0)
+		return 0;
+
+	dev_dbg(&codec.dev, "%s(codec_num=%d): vendor_id=0x%08x\n",
+		__func__, codec_num, AC97_ID(vid1, vid2));
+	return AC97_ID(vid1, vid2);
+}
+
+static int ac97_bus_scan(struct ac97_controller *ac97_ctrl)
+{
+	int ret, i;
+	unsigned int vendor_id;
+
+	for (i = 0; i < AC97_BUS_MAX_CODECS; i++) {
+		if (ac97_codec_find(ac97_ctrl, i))
+			continue;
+		vendor_id = ac97_bus_scan_one(ac97_ctrl, i);
+		if (!vendor_id)
+			continue;
+
+		ret = ac97_codec_add(ac97_ctrl, i, vendor_id);
+		if (ret < 0)
+			return ret;
+	}
+	return 0;
+}
+
+void ac97_rescan_all_controllers(void)
+{
+	struct ac97_controller *ac97_ctrl;
+	int ret;
+
+	mutex_lock(&ac97_controllers_mutex);
+	list_for_each_entry(ac97_ctrl, &ac97_controllers, controllers) {
+		ret = ac97_bus_scan(ac97_ctrl);
+		if (ret)
+			dev_warn(ac97_ctrl->dev, "scan failed: %d\n", ret);
+	}
+	mutex_unlock(&ac97_controllers_mutex);
+}
+EXPORT_SYMBOL(ac97_rescan_all_controllers);
+
+static int ac97_bus_reset(struct ac97_controller *ac97_ctrl)
+{
+	struct ac97_codec_device codec;
+
+	memset(&codec, 0, sizeof(codec));
+	codec.dev = *ac97_ctrl->dev;
+
+	ac97_ctrl->ops->reset(&codec);
+	return 0;
+}
+
+/**
+ * ac97_codec_driver_register - register an AC97 codec driver
+ * @dev: AC97 driver codec to register
+ *
+ * Register an AC97 codec driver to the ac97 bus driver, aka. the AC97 digital
+ * controller.
+ *
+ * Returns 0 on success or error code
+ */
+int ac97_codec_driver_register(struct ac97_codec_driver *drv)
+{
+	int ret;
+
+	drv->driver.bus = &ac97_bus_type;
+
+	ret = driver_register(&drv->driver);
+	if (!ret)
+		ac97_rescan_all_controllers();
+
+	return ret;
+}
+EXPORT_SYMBOL(ac97_codec_driver_register);
+
+/**
+ * ac97_codec_driver_unregister - unregister an AC97 codec driver
+ * @dev: AC97 codec driver to unregister
+ *
+ * Unregister a previously registered ac97 codec driver.
+ */
+void ac97_codec_driver_unregister(struct ac97_codec_driver *drv)
+{
+	driver_unregister(&drv->driver);
+}
+EXPORT_SYMBOL(ac97_codec_driver_unregister);
+
+static int ac97_dc_codecs_unregister(struct ac97_controller *ac97_ctrl)
+{
+	struct ac97_codec_device *codec, *tmp;
+
+	list_for_each_entry_safe(codec, tmp, &ac97_ctrl->codecs, list)
+		put_device(&codec->dev);
+
+	return 0;
+}
+
+/**
+ * ac97_digital_controller_register - register an ac97 controller
+ * @ops: the ac97 bus operations
+ * @dev: the device providing the ac97 DC function
+ *
+ * Register a digital controller which can control up to 4 ac97 codecs. This is
+ * the controller side of the AC97 AC-link, while the slave side are the codecs.
+ *
+ * Returns a positive bus index upon success, negative value upon error
+ */
+int ac97_digital_controller_register(const struct ac97_controller_ops *ops,
+				     struct device *dev)
+{
+	struct ac97_controller *ac97_ctrl;
+
+	ac97_ctrl = kzalloc(sizeof(*ac97_ctrl), GFP_KERNEL);
+	if (!ac97_ctrl)
+		return -ENOMEM;
+
+	mutex_lock(&ac97_controllers_mutex);
+	ac97_ctrl->ops = ops;
+	ac97_ctrl->bus_idx = ac97_bus_idx++;
+	ac97_ctrl->dev = dev;
+	INIT_LIST_HEAD(&ac97_ctrl->codecs);
+	list_add(&ac97_ctrl->controllers, &ac97_controllers);
+	mutex_unlock(&ac97_controllers_mutex);
+
+	ac97_bus_reset(ac97_ctrl);
+	ac97_bus_scan(ac97_ctrl);
+
+	return ac97_ctrl->bus_idx;
+}
+EXPORT_SYMBOL(ac97_digital_controller_register);
+
+/**
+ * ac97_digital_controller_unregister - unregister an ac97 controller
+ * @dev: the device previously provided to ac97_digital_controller_register()
+ *
+ * Returns 0 on success, negative upon error
+ */
+int ac97_digital_controller_unregister(const struct device *dev)
+{
+	struct ac97_controller *ac97_ctrl, *tmp;
+	int ret = -ENODEV;
+
+	mutex_lock(&ac97_controllers_mutex);
+	list_for_each_entry_safe(ac97_ctrl, tmp, &ac97_controllers,
+				 controllers) {
+		if (ac97_ctrl->dev != dev)
+			continue;
+		if (ac97_ctrl->bound_codecs)
+			ret = -EBUSY;
+		else
+			ret = ac97_dc_codecs_unregister(ac97_ctrl);
+		if (!ret)
+			list_del(&ac97_ctrl->controllers);
+	}
+
+	mutex_unlock(&ac97_controllers_mutex);
+	return ret;
+}
+EXPORT_SYMBOL(ac97_digital_controller_unregister);
+
+static const struct dev_pm_ops ac97_pm = {
+	.suspend	= pm_generic_suspend,
+	.resume		= pm_generic_resume,
+	.freeze		= pm_generic_freeze,
+	.thaw		= pm_generic_thaw,
+	.poweroff	= pm_generic_poweroff,
+	.restore	= pm_generic_restore,
+};
+
+static ssize_t vendor_id_show(struct device *dev,
+			      struct device_attribute *attr, char *buf)
+{
+	struct ac97_codec_device *codec = to_ac97_device(dev);
+
+	return sprintf(buf, "%08x", codec->vendor_id);
+}
+
+static struct device_attribute ac97_dev_attrs[] = {
+	__ATTR_RO(vendor_id),
+	__ATTR_NULL,
+};
+
+int ac97_bus_match(struct device *dev, struct device_driver *drv)
+{
+	struct ac97_codec_device *adev = to_ac97_device(dev);
+	struct ac97_codec_driver *adrv = to_ac97_driver(drv);
+	struct ac97_id *id = adrv->id_table;
+
+	if (adev->vendor_id == 0x0 || adev->vendor_id == 0xffffffff)
+		return false;
+
+	do {
+		if ((id->id & id->mask) == (adev->vendor_id & id->mask))
+			return true;
+	} while (++id->id);
+
+	return false;
+}
+
+static int ac97_bus_probe(struct device *dev)
+{
+	struct ac97_codec_device *adev = to_ac97_device(dev);
+	struct ac97_codec_driver *adrv = to_ac97_driver(dev->driver);
+
+	return adrv->probe(adev);
+}
+
+static int ac97_bus_remove(struct device *dev)
+{
+	struct ac97_codec_device *adev = to_ac97_device(dev);
+	struct ac97_codec_driver *adrv = to_ac97_driver(dev->driver);
+
+	return adrv->remove(adev);
+}
+
+struct bus_type ac97_bus_type = {
+	.name		= "ac97",
+	.dev_attrs	= ac97_dev_attrs,
+	.match		= ac97_bus_match,
+	.pm		= &ac97_pm,
+	.probe		= ac97_bus_probe,
+	.remove		= ac97_bus_remove,
+};
+EXPORT_SYMBOL(ac97_bus_type);
+
+static int __init ac97_bus_init(void)
+{
+	return bus_register(&ac97_bus_type);
+}
+subsys_initcall(ac97_bus_init);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Robert Jarzmik <robert.jarzmik@free.fr>");
diff --git a/sound/ac97/codec.c b/sound/ac97/codec.c
new file mode 100644
index 000000000000..a835f03744bf
--- /dev/null
+++ b/sound/ac97/codec.c
@@ -0,0 +1,15 @@
+/*
+ *  Copyright (C) 2016 Robert Jarzmik <robert.jarzmik@free.fr>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <sound/ac97_codec.h>
+#include <sound/ac97/codec.h>
+#include <sound/ac97/controller.h>
+#include <linux/device.h>
+#include <linux/slab.h>
+#include <sound/soc.h>	/* For compat_ac97_* */
+
diff --git a/sound/ac97/snd_ac97_compat.c b/sound/ac97/snd_ac97_compat.c
new file mode 100644
index 000000000000..7e2f01c96fc9
--- /dev/null
+++ b/sound/ac97/snd_ac97_compat.c
@@ -0,0 +1,104 @@
+/*
+ *  Copyright (C) 2016 Robert Jarzmik <robert.jarzmik@free.fr>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/list.h>
+#include <linux/slab.h>
+#include <sound/ac97/codec.h>
+#include <sound/ac97/controller.h>
+#include <sound/soc.h>
+
+#include "ac97_core.h"
+
+static void compat_ac97_reset(struct snd_ac97 *ac97)
+{
+	struct ac97_codec_device *adev = to_ac97_device(ac97->private_data);
+	struct ac97_controller *actrl = adev->ac97_ctrl;
+
+	if (actrl->ops->reset)
+		actrl->ops->reset(adev);
+}
+
+static void compat_ac97_warm_reset(struct snd_ac97 *ac97)
+{
+	struct ac97_codec_device *adev = to_ac97_device(ac97->private_data);
+	struct ac97_controller *actrl = adev->ac97_ctrl;
+
+	if (actrl->ops->warm_reset)
+		actrl->ops->warm_reset(adev);
+}
+
+static void compat_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
+			      unsigned short val)
+{
+	struct ac97_codec_device *adev = to_ac97_device(ac97->private_data);
+	struct ac97_controller *actrl = adev->ac97_ctrl;
+
+	actrl->ops->write(adev, reg, val);
+}
+
+static unsigned short compat_ac97_read(struct snd_ac97 *ac97,
+				       unsigned short reg)
+{
+	struct ac97_codec_device *adev = to_ac97_device(ac97->private_data);
+	struct ac97_controller *actrl = adev->ac97_ctrl;
+
+	return actrl->ops->read(adev, reg);
+}
+
+static struct snd_ac97_bus_ops compat_snd_ac97_bus_ops = {
+	.reset = compat_ac97_reset,
+	.warm_reset = compat_ac97_warm_reset,
+	.write = compat_ac97_write,
+	.read = compat_ac97_read,
+};
+
+static struct snd_ac97_bus compat_soc_ac97_bus = {
+	.ops = &compat_snd_ac97_bus_ops,
+};
+
+struct snd_ac97 *compat_alloc_snd_ac97_codec(struct snd_soc_codec *codec)
+{
+	struct snd_ac97 *ac97;
+
+	ac97 = kzalloc(sizeof(struct snd_ac97), GFP_KERNEL);
+	if (ac97 == NULL)
+		return ERR_PTR(-ENOMEM);
+
+	ac97->dev = *codec->dev;
+	ac97->private_data = codec->dev;
+	ac97->bus = &compat_soc_ac97_bus;
+	return ac97;
+}
+EXPORT_SYMBOL_GPL(compat_alloc_snd_ac97_codec);
+
+void compat_release_snd_ac97_codec(struct snd_ac97 *ac97)
+{
+	kfree(ac97);
+}
+EXPORT_SYMBOL_GPL(compat_release_snd_ac97_codec);
+
+int snd_ac97_reset(struct snd_ac97 *ac97, bool try_warm, unsigned int id,
+	unsigned int id_mask)
+{
+	struct ac97_codec_device *adev = to_ac97_device(ac97->private_data);
+	struct ac97_controller *actrl = adev->ac97_ctrl;
+
+	if (try_warm) {
+		compat_ac97_warm_reset(ac97);
+		if (ac97_bus_scan_one(actrl, adev->num) == adev->vendor_id)
+			return 1;
+	}
+
+	compat_ac97_reset(ac97);
+	compat_ac97_warm_reset(ac97);
+	if (ac97_bus_scan_one(actrl, adev->num) == adev->vendor_id)
+		return 0;
+
+	return -ENODEV;
+}
+EXPORT_SYMBOL_GPL(snd_ac97_reset);
-- 
2.1.4

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

* [RFC PATCH 2/7] ALSA: ac97: add an ac97 bus
@ 2016-04-30 21:15   ` Robert Jarzmik
  0 siblings, 0 replies; 74+ messages in thread
From: Robert Jarzmik @ 2016-04-30 21:15 UTC (permalink / raw)
  To: linux-arm-kernel

AC97 is a bus for sound usage. It enables for a AC97 AC-Link to link one
controller to 0 to 4 AC97 codecs.

The goal of this new implementation is to implement a device/driver
model for AC97, with an automatic scan of the bus and automatic
discovery of AC97 codec devices.

Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
---
 include/sound/ac97/codec.h      |  98 ++++++++++++
 include/sound/ac97/compat.h     |  21 +++
 include/sound/ac97/controller.h |  39 +++++
 sound/ac97/Kconfig              |   9 ++
 sound/ac97/Makefile             |   5 +
 sound/ac97/ac97_core.h          |  10 ++
 sound/ac97/bus.c                | 330 ++++++++++++++++++++++++++++++++++++++++
 sound/ac97/codec.c              |  15 ++
 sound/ac97/snd_ac97_compat.c    | 104 +++++++++++++
 9 files changed, 631 insertions(+)
 create mode 100644 include/sound/ac97/codec.h
 create mode 100644 include/sound/ac97/compat.h
 create mode 100644 include/sound/ac97/controller.h
 create mode 100644 sound/ac97/Kconfig
 create mode 100644 sound/ac97/Makefile
 create mode 100644 sound/ac97/ac97_core.h
 create mode 100644 sound/ac97/bus.c
 create mode 100644 sound/ac97/codec.c
 create mode 100644 sound/ac97/snd_ac97_compat.c

diff --git a/include/sound/ac97/codec.h b/include/sound/ac97/codec.h
new file mode 100644
index 000000000000..4b8b3e570892
--- /dev/null
+++ b/include/sound/ac97/codec.h
@@ -0,0 +1,98 @@
+/*
+ *  Copyright (C) 2016 Robert Jarzmik <robert.jarzmik@free.fr>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef AC97_CODEC_H
+#define AC97_CODEC_H
+
+#include <linux/device.h>
+
+#define AC97_ID(vendor_id1, vendor_id2) \
+	(((vendor_id1 & 0xffff) << 16) | (vendor_id2 & 0xffff))
+#define AC97_DRIVER_ID(vendor_id1, vendor_id2, mask_id1, mask_id2, _data) \
+	{ .id = ((vendor_id1 & 0xffff) << 16) | (vendor_id2 & 0xffff), \
+	  .mask = ((mask_id1 & 0xffff) << 16) | (mask_id2 & 0xffff), \
+	  .data = _data }
+
+#define to_ac97_device(d) container_of(d, struct ac97_codec_device, dev)
+#define to_ac97_driver(d) container_of(d, struct ac97_codec_driver, driver)
+
+struct ac97_controller;
+
+/**
+ * struct ac97_id - matches a codec device and driver on an ac97 bus
+ * @id: The significant bits if the codec vendor ID1 and ID2
+ * @mask: Bitmask specifying which bits of the id field are significant when
+ *	  matching. A driver binds to a device when :
+ *        ((vendorID1 << 8 | vendorID2) & (mask_id1 << 8 | mask_id2)) == id.
+ * @data: Private data used by the driver.
+ */
+struct ac97_id {
+	unsigned int		id;
+	unsigned int		mask;
+	void			*data;
+};
+
+/**
+ * ac97_codec_device - a ac97 codec
+ * @dev: the code device
+ * @vendor_id: the vendor_id of the codec, as sensed on the AC-link
+ * @num: the codec number, 0 is primary, 1 is first slave, etc ...
+ * @ac97_ctrl: ac97 digital controller on the same AC-link
+ *
+ * This is the device instanciated for each codec living on a AC-link. There are
+ * normally 0 to 4 codec devices per AC-link, and all of them are controlled by
+ * an AC97 digital controller.
+ */
+struct ac97_codec_device {
+	struct device		dev;	/* Must stay first member */
+	unsigned int		vendor_id;
+	unsigned int		num;
+	struct list_head	list;
+	struct ac97_controller	*ac97_ctrl;
+};
+
+/**
+ * ac97_codec_driver - a ac97 codec driver
+ * @driver: the device driver structure
+ * @probe: the function called when a ac97_codec_device is matched
+ * @remove: the function called when the device is unbound/removed
+ * @suspend: suspend function (might be NULL)
+ * @resume: resume function (might be NULL)
+ * @shutdown: shutdown function (might be NULL)
+ * @id_table: ac97 vendor_id match table, { } member terminated
+ */
+struct ac97_codec_driver {
+	struct device_driver	driver;
+	int			(*probe)(struct ac97_codec_device *);
+	int			(*remove)(struct ac97_codec_device *);
+	int			(*suspend)(struct ac97_codec_device *);
+	int			(*resume)(struct ac97_codec_device *);
+	void			(*shutdown)(struct ac97_codec_device *);
+	struct ac97_id		*id_table;
+};
+
+int ac97_codec_driver_register(struct ac97_codec_driver *drv);
+void ac97_codec_driver_unregister(struct ac97_codec_driver *drv);
+
+static inline struct device *
+ac97_codec_dev2dev(const struct ac97_codec_device *adev)
+{
+	return (struct device *)(adev);
+}
+
+static inline void *ac97_get_drvdata(const struct ac97_codec_device *adev)
+{
+	return dev_get_drvdata(ac97_codec_dev2dev(adev));
+}
+
+static inline void ac97_set_drvdata(const struct ac97_codec_device *adev,
+				    void *data)
+{
+	dev_set_drvdata(ac97_codec_dev2dev(adev), data);
+}
+
+#endif
diff --git a/include/sound/ac97/compat.h b/include/sound/ac97/compat.h
new file mode 100644
index 000000000000..bf611f572f2d
--- /dev/null
+++ b/include/sound/ac97/compat.h
@@ -0,0 +1,21 @@
+/*
+ *  Copyright (C) 2016 Robert Jarzmik <robert.jarzmik@free.fr>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This file is for backward compatibility with snd_ac97 structure and its
+ * multiple usages, such as the snd_ac97_bus and snd_ac97_build_ops.
+ *
+ */
+#ifndef AC97_COMPAT_H
+#define AC97_COMPAT_H
+
+#include <sound/ac97_codec.h>
+#include <sound/soc.h>
+
+struct snd_ac97 *compat_alloc_snd_ac97_codec(struct snd_soc_codec *codec);
+void compat_release_snd_ac97_codec(struct snd_ac97 *ac97);
+
+#endif
diff --git a/include/sound/ac97/controller.h b/include/sound/ac97/controller.h
new file mode 100644
index 000000000000..f1e5e645f5ef
--- /dev/null
+++ b/include/sound/ac97/controller.h
@@ -0,0 +1,39 @@
+/*
+ *  Copyright (C) 2016 Robert Jarzmik <robert.jarzmik@free.fr>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef AC97_CONTROLLER_H
+#define AC97_CONTROLLER_H
+
+#include <linux/list.h>
+
+struct device;
+struct ac97_codec_device;
+
+struct ac97_controller_ops {
+	void (*reset)(struct ac97_codec_device *ac97);
+	void (*warm_reset)(struct ac97_codec_device *ac97);
+	int (*write)(struct ac97_codec_device *ac97, unsigned short reg,
+		     unsigned short val);
+	int (*read)(struct ac97_codec_device *ac97, unsigned short reg);
+	void (*wait)(struct ac97_codec_device *ac97);
+	void (*init)(struct ac97_codec_device *ac97);
+};
+
+struct ac97_controller {
+	const struct ac97_controller_ops *ops;
+	struct list_head controllers;
+	struct device *dev;
+	int bus_idx;
+	int bound_codecs;
+	struct list_head codecs;
+};
+
+int ac97_digital_controller_register(const struct ac97_controller_ops *ops,
+				     struct device *dev);
+int ac97_digital_controller_unregister(const struct device *dev);
+
+#endif
diff --git a/sound/ac97/Kconfig b/sound/ac97/Kconfig
new file mode 100644
index 000000000000..fd2c2d031e62
--- /dev/null
+++ b/sound/ac97/Kconfig
@@ -0,0 +1,9 @@
+#
+# PCI configuration
+#
+
+config AC97
+	bool "AC97 bus"
+	help
+	   Say Y here if you want to have AC97 devices, which are sound oriented
+	   devices around an AC-Link.
diff --git a/sound/ac97/Makefile b/sound/ac97/Makefile
new file mode 100644
index 000000000000..5575909d46e2
--- /dev/null
+++ b/sound/ac97/Makefile
@@ -0,0 +1,5 @@
+#
+# make for AC97 bus drivers
+#
+
+obj-y	+= bus.o codec.o snd_ac97_compat.o
diff --git a/sound/ac97/ac97_core.h b/sound/ac97/ac97_core.h
new file mode 100644
index 000000000000..db6e27288357
--- /dev/null
+++ b/sound/ac97/ac97_core.h
@@ -0,0 +1,10 @@
+/*
+ * Copyright (C) 2016 Robert Jarzmik <robert.jarzmik@free.fr>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+unsigned int ac97_bus_scan_one(struct ac97_controller *ac97,
+			       int codec_num);
diff --git a/sound/ac97/bus.c b/sound/ac97/bus.c
new file mode 100644
index 000000000000..f9bf5632d4aa
--- /dev/null
+++ b/sound/ac97/bus.c
@@ -0,0 +1,330 @@
+/*
+ * Copyright (C) 2016 Robert Jarzmik <robert.jarzmik@free.fr>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <linux/pm.h>
+#include <linux/slab.h>
+#include <sound/ac97/codec.h>
+#include <sound/ac97/controller.h>
+#include <sound/ac97/regs.h>
+
+#define AC97_BUS_MAX_CODECS 4
+
+/*
+ * Protects ac97_controllers and each ac97_controller structure.
+ */
+static DEFINE_MUTEX(ac97_controllers_mutex);
+static LIST_HEAD(ac97_controllers);
+static int ac97_bus_idx;
+
+struct bus_type ac97_bus_type;
+
+static struct ac97_codec_device *
+ac97_codec_find(struct ac97_controller *ac97_ctrl, int codec_num)
+{
+	struct ac97_codec_device *codec;
+
+	list_for_each_entry(codec, &ac97_ctrl->codecs, list)
+		if (codec->num == codec_num)
+			return codec;
+
+	return NULL;
+}
+
+static void ac97_codec_release(struct device *dev)
+{
+	struct ac97_codec_device *codec;
+
+	codec = container_of(dev, struct ac97_codec_device, dev);
+	list_del(&codec->list);
+	kfree(codec);
+}
+
+static int ac97_codec_add(struct ac97_controller *ac97_ctrl, int idx,
+		   unsigned int vendor_id)
+{
+	struct ac97_codec_device *codec;
+	char *codec_name;
+	int ret;
+
+	codec = kzalloc(sizeof(*codec), GFP_KERNEL);
+	if (!codec)
+		return -ENOMEM;
+
+	codec->vendor_id = vendor_id;
+	codec->dev.release = ac97_codec_release;
+	codec->dev.bus = &ac97_bus_type;
+	codec->dev.parent = ac97_ctrl->dev;
+	codec->num = idx;
+	codec->ac97_ctrl = ac97_ctrl;
+	INIT_LIST_HEAD(&codec->list);
+	list_move_tail(&codec->list, &ac97_ctrl->codecs);
+
+	codec_name = kasprintf(GFP_KERNEL, "%s:%d", dev_name(ac97_ctrl->dev),
+			       idx);
+	codec->dev.init_name = codec_name;
+
+	ret = device_register(&codec->dev);
+	kfree(codec_name);
+
+	return ret;
+}
+
+unsigned int ac97_bus_scan_one(struct ac97_controller *ac97,
+				      int codec_num)
+{
+	struct ac97_codec_device codec;
+	unsigned short vid1, vid2;
+	int ret;
+
+	codec.dev = *ac97->dev;
+	codec.num = codec_num;
+	ret = ac97->ops->read(&codec, AC97_VENDOR_ID1);
+	vid1 = (ret & 0xffff);
+	if (ret < 0)
+		return 0;
+
+	ret = ac97->ops->read(&codec, AC97_VENDOR_ID2);
+	vid2 = (ret & 0xffff);
+	if (ret < 0)
+		return 0;
+
+	dev_dbg(&codec.dev, "%s(codec_num=%d): vendor_id=0x%08x\n",
+		__func__, codec_num, AC97_ID(vid1, vid2));
+	return AC97_ID(vid1, vid2);
+}
+
+static int ac97_bus_scan(struct ac97_controller *ac97_ctrl)
+{
+	int ret, i;
+	unsigned int vendor_id;
+
+	for (i = 0; i < AC97_BUS_MAX_CODECS; i++) {
+		if (ac97_codec_find(ac97_ctrl, i))
+			continue;
+		vendor_id = ac97_bus_scan_one(ac97_ctrl, i);
+		if (!vendor_id)
+			continue;
+
+		ret = ac97_codec_add(ac97_ctrl, i, vendor_id);
+		if (ret < 0)
+			return ret;
+	}
+	return 0;
+}
+
+void ac97_rescan_all_controllers(void)
+{
+	struct ac97_controller *ac97_ctrl;
+	int ret;
+
+	mutex_lock(&ac97_controllers_mutex);
+	list_for_each_entry(ac97_ctrl, &ac97_controllers, controllers) {
+		ret = ac97_bus_scan(ac97_ctrl);
+		if (ret)
+			dev_warn(ac97_ctrl->dev, "scan failed: %d\n", ret);
+	}
+	mutex_unlock(&ac97_controllers_mutex);
+}
+EXPORT_SYMBOL(ac97_rescan_all_controllers);
+
+static int ac97_bus_reset(struct ac97_controller *ac97_ctrl)
+{
+	struct ac97_codec_device codec;
+
+	memset(&codec, 0, sizeof(codec));
+	codec.dev = *ac97_ctrl->dev;
+
+	ac97_ctrl->ops->reset(&codec);
+	return 0;
+}
+
+/**
+ * ac97_codec_driver_register - register an AC97 codec driver
+ * @dev: AC97 driver codec to register
+ *
+ * Register an AC97 codec driver to the ac97 bus driver, aka. the AC97 digital
+ * controller.
+ *
+ * Returns 0 on success or error code
+ */
+int ac97_codec_driver_register(struct ac97_codec_driver *drv)
+{
+	int ret;
+
+	drv->driver.bus = &ac97_bus_type;
+
+	ret = driver_register(&drv->driver);
+	if (!ret)
+		ac97_rescan_all_controllers();
+
+	return ret;
+}
+EXPORT_SYMBOL(ac97_codec_driver_register);
+
+/**
+ * ac97_codec_driver_unregister - unregister an AC97 codec driver
+ * @dev: AC97 codec driver to unregister
+ *
+ * Unregister a previously registered ac97 codec driver.
+ */
+void ac97_codec_driver_unregister(struct ac97_codec_driver *drv)
+{
+	driver_unregister(&drv->driver);
+}
+EXPORT_SYMBOL(ac97_codec_driver_unregister);
+
+static int ac97_dc_codecs_unregister(struct ac97_controller *ac97_ctrl)
+{
+	struct ac97_codec_device *codec, *tmp;
+
+	list_for_each_entry_safe(codec, tmp, &ac97_ctrl->codecs, list)
+		put_device(&codec->dev);
+
+	return 0;
+}
+
+/**
+ * ac97_digital_controller_register - register an ac97 controller
+ * @ops: the ac97 bus operations
+ * @dev: the device providing the ac97 DC function
+ *
+ * Register a digital controller which can control up to 4 ac97 codecs. This is
+ * the controller side of the AC97 AC-link, while the slave side are the codecs.
+ *
+ * Returns a positive bus index upon success, negative value upon error
+ */
+int ac97_digital_controller_register(const struct ac97_controller_ops *ops,
+				     struct device *dev)
+{
+	struct ac97_controller *ac97_ctrl;
+
+	ac97_ctrl = kzalloc(sizeof(*ac97_ctrl), GFP_KERNEL);
+	if (!ac97_ctrl)
+		return -ENOMEM;
+
+	mutex_lock(&ac97_controllers_mutex);
+	ac97_ctrl->ops = ops;
+	ac97_ctrl->bus_idx = ac97_bus_idx++;
+	ac97_ctrl->dev = dev;
+	INIT_LIST_HEAD(&ac97_ctrl->codecs);
+	list_add(&ac97_ctrl->controllers, &ac97_controllers);
+	mutex_unlock(&ac97_controllers_mutex);
+
+	ac97_bus_reset(ac97_ctrl);
+	ac97_bus_scan(ac97_ctrl);
+
+	return ac97_ctrl->bus_idx;
+}
+EXPORT_SYMBOL(ac97_digital_controller_register);
+
+/**
+ * ac97_digital_controller_unregister - unregister an ac97 controller
+ * @dev: the device previously provided to ac97_digital_controller_register()
+ *
+ * Returns 0 on success, negative upon error
+ */
+int ac97_digital_controller_unregister(const struct device *dev)
+{
+	struct ac97_controller *ac97_ctrl, *tmp;
+	int ret = -ENODEV;
+
+	mutex_lock(&ac97_controllers_mutex);
+	list_for_each_entry_safe(ac97_ctrl, tmp, &ac97_controllers,
+				 controllers) {
+		if (ac97_ctrl->dev != dev)
+			continue;
+		if (ac97_ctrl->bound_codecs)
+			ret = -EBUSY;
+		else
+			ret = ac97_dc_codecs_unregister(ac97_ctrl);
+		if (!ret)
+			list_del(&ac97_ctrl->controllers);
+	}
+
+	mutex_unlock(&ac97_controllers_mutex);
+	return ret;
+}
+EXPORT_SYMBOL(ac97_digital_controller_unregister);
+
+static const struct dev_pm_ops ac97_pm = {
+	.suspend	= pm_generic_suspend,
+	.resume		= pm_generic_resume,
+	.freeze		= pm_generic_freeze,
+	.thaw		= pm_generic_thaw,
+	.poweroff	= pm_generic_poweroff,
+	.restore	= pm_generic_restore,
+};
+
+static ssize_t vendor_id_show(struct device *dev,
+			      struct device_attribute *attr, char *buf)
+{
+	struct ac97_codec_device *codec = to_ac97_device(dev);
+
+	return sprintf(buf, "%08x", codec->vendor_id);
+}
+
+static struct device_attribute ac97_dev_attrs[] = {
+	__ATTR_RO(vendor_id),
+	__ATTR_NULL,
+};
+
+int ac97_bus_match(struct device *dev, struct device_driver *drv)
+{
+	struct ac97_codec_device *adev = to_ac97_device(dev);
+	struct ac97_codec_driver *adrv = to_ac97_driver(drv);
+	struct ac97_id *id = adrv->id_table;
+
+	if (adev->vendor_id == 0x0 || adev->vendor_id == 0xffffffff)
+		return false;
+
+	do {
+		if ((id->id & id->mask) == (adev->vendor_id & id->mask))
+			return true;
+	} while (++id->id);
+
+	return false;
+}
+
+static int ac97_bus_probe(struct device *dev)
+{
+	struct ac97_codec_device *adev = to_ac97_device(dev);
+	struct ac97_codec_driver *adrv = to_ac97_driver(dev->driver);
+
+	return adrv->probe(adev);
+}
+
+static int ac97_bus_remove(struct device *dev)
+{
+	struct ac97_codec_device *adev = to_ac97_device(dev);
+	struct ac97_codec_driver *adrv = to_ac97_driver(dev->driver);
+
+	return adrv->remove(adev);
+}
+
+struct bus_type ac97_bus_type = {
+	.name		= "ac97",
+	.dev_attrs	= ac97_dev_attrs,
+	.match		= ac97_bus_match,
+	.pm		= &ac97_pm,
+	.probe		= ac97_bus_probe,
+	.remove		= ac97_bus_remove,
+};
+EXPORT_SYMBOL(ac97_bus_type);
+
+static int __init ac97_bus_init(void)
+{
+	return bus_register(&ac97_bus_type);
+}
+subsys_initcall(ac97_bus_init);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Robert Jarzmik <robert.jarzmik@free.fr>");
diff --git a/sound/ac97/codec.c b/sound/ac97/codec.c
new file mode 100644
index 000000000000..a835f03744bf
--- /dev/null
+++ b/sound/ac97/codec.c
@@ -0,0 +1,15 @@
+/*
+ *  Copyright (C) 2016 Robert Jarzmik <robert.jarzmik@free.fr>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <sound/ac97_codec.h>
+#include <sound/ac97/codec.h>
+#include <sound/ac97/controller.h>
+#include <linux/device.h>
+#include <linux/slab.h>
+#include <sound/soc.h>	/* For compat_ac97_* */
+
diff --git a/sound/ac97/snd_ac97_compat.c b/sound/ac97/snd_ac97_compat.c
new file mode 100644
index 000000000000..7e2f01c96fc9
--- /dev/null
+++ b/sound/ac97/snd_ac97_compat.c
@@ -0,0 +1,104 @@
+/*
+ *  Copyright (C) 2016 Robert Jarzmik <robert.jarzmik@free.fr>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/list.h>
+#include <linux/slab.h>
+#include <sound/ac97/codec.h>
+#include <sound/ac97/controller.h>
+#include <sound/soc.h>
+
+#include "ac97_core.h"
+
+static void compat_ac97_reset(struct snd_ac97 *ac97)
+{
+	struct ac97_codec_device *adev = to_ac97_device(ac97->private_data);
+	struct ac97_controller *actrl = adev->ac97_ctrl;
+
+	if (actrl->ops->reset)
+		actrl->ops->reset(adev);
+}
+
+static void compat_ac97_warm_reset(struct snd_ac97 *ac97)
+{
+	struct ac97_codec_device *adev = to_ac97_device(ac97->private_data);
+	struct ac97_controller *actrl = adev->ac97_ctrl;
+
+	if (actrl->ops->warm_reset)
+		actrl->ops->warm_reset(adev);
+}
+
+static void compat_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
+			      unsigned short val)
+{
+	struct ac97_codec_device *adev = to_ac97_device(ac97->private_data);
+	struct ac97_controller *actrl = adev->ac97_ctrl;
+
+	actrl->ops->write(adev, reg, val);
+}
+
+static unsigned short compat_ac97_read(struct snd_ac97 *ac97,
+				       unsigned short reg)
+{
+	struct ac97_codec_device *adev = to_ac97_device(ac97->private_data);
+	struct ac97_controller *actrl = adev->ac97_ctrl;
+
+	return actrl->ops->read(adev, reg);
+}
+
+static struct snd_ac97_bus_ops compat_snd_ac97_bus_ops = {
+	.reset = compat_ac97_reset,
+	.warm_reset = compat_ac97_warm_reset,
+	.write = compat_ac97_write,
+	.read = compat_ac97_read,
+};
+
+static struct snd_ac97_bus compat_soc_ac97_bus = {
+	.ops = &compat_snd_ac97_bus_ops,
+};
+
+struct snd_ac97 *compat_alloc_snd_ac97_codec(struct snd_soc_codec *codec)
+{
+	struct snd_ac97 *ac97;
+
+	ac97 = kzalloc(sizeof(struct snd_ac97), GFP_KERNEL);
+	if (ac97 == NULL)
+		return ERR_PTR(-ENOMEM);
+
+	ac97->dev = *codec->dev;
+	ac97->private_data = codec->dev;
+	ac97->bus = &compat_soc_ac97_bus;
+	return ac97;
+}
+EXPORT_SYMBOL_GPL(compat_alloc_snd_ac97_codec);
+
+void compat_release_snd_ac97_codec(struct snd_ac97 *ac97)
+{
+	kfree(ac97);
+}
+EXPORT_SYMBOL_GPL(compat_release_snd_ac97_codec);
+
+int snd_ac97_reset(struct snd_ac97 *ac97, bool try_warm, unsigned int id,
+	unsigned int id_mask)
+{
+	struct ac97_codec_device *adev = to_ac97_device(ac97->private_data);
+	struct ac97_controller *actrl = adev->ac97_ctrl;
+
+	if (try_warm) {
+		compat_ac97_warm_reset(ac97);
+		if (ac97_bus_scan_one(actrl, adev->num) == adev->vendor_id)
+			return 1;
+	}
+
+	compat_ac97_reset(ac97);
+	compat_ac97_warm_reset(ac97);
+	if (ac97_bus_scan_one(actrl, adev->num) == adev->vendor_id)
+		return 0;
+
+	return -ENODEV;
+}
+EXPORT_SYMBOL_GPL(snd_ac97_reset);
-- 
2.1.4

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

* [RFC PATCH 3/7] ASoC: wm9713: add ac97 new bus support
  2016-04-30 21:15 ` Robert Jarzmik
@ 2016-04-30 21:15   ` Robert Jarzmik
  -1 siblings, 0 replies; 74+ messages in thread
From: Robert Jarzmik @ 2016-04-30 21:15 UTC (permalink / raw)
  To: Robert Jarzmik, Daniel Mack, Haojian Zhuang, Jaroslav Kysela,
	Takashi Iwai, Liam Girdwood, Mark Brown
  Cc: linux-arm-kernel, linux-kernel, alsa-devel, patches

Add support for the new ac97 bus model, where devices are automatically
discovered on AC-Links.

Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
---
 sound/soc/codecs/wm9713.c | 62 ++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 56 insertions(+), 6 deletions(-)

diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c
index 9849643ef809..bd5229236a8a 100644
--- a/sound/soc/codecs/wm9713.c
+++ b/sound/soc/codecs/wm9713.c
@@ -22,7 +22,8 @@
 #include <linux/regmap.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
-#include <sound/ac97_codec.h>
+#include <sound/ac97/codec.h>
+#include <sound/ac97/compat.h>
 #include <sound/initval.h>
 #include <sound/pcm_params.h>
 #include <sound/tlv.h>
@@ -1207,14 +1208,13 @@ static int wm9713_soc_probe(struct snd_soc_codec *codec)
 	struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec);
 	struct regmap *regmap;
 
-	wm9713->ac97 = snd_soc_new_ac97_codec(codec, WM9713_VENDOR_ID,
-		WM9713_VENDOR_ID_MASK);
+	wm9713->ac97 = compat_alloc_snd_ac97_codec(codec);
 	if (IS_ERR(wm9713->ac97))
 		return PTR_ERR(wm9713->ac97);
 
 	regmap = regmap_init_ac97(wm9713->ac97, &wm9713_regmap_config);
 	if (IS_ERR(regmap)) {
-		snd_soc_free_ac97_codec(wm9713->ac97);
+		compat_release_snd_ac97_codec(wm9713->ac97);
 		return PTR_ERR(regmap);
 	}
 
@@ -1231,7 +1231,7 @@ static int wm9713_soc_remove(struct snd_soc_codec *codec)
 	struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec);
 
 	snd_soc_codec_exit_regmap(codec);
-	snd_soc_free_ac97_codec(wm9713->ac97);
+	compat_release_snd_ac97_codec(wm9713->ac97);
 	return 0;
 }
 
@@ -1281,7 +1281,57 @@ static struct platform_driver wm9713_codec_driver = {
 	.remove = wm9713_remove,
 };
 
-module_platform_driver(wm9713_codec_driver);
+static int wm9713_ac97_probe(struct ac97_codec_device *adev)
+{
+	struct wm9713_priv *wm9713;
+
+	wm9713 = devm_kzalloc(ac97_codec_dev2dev(adev),
+			      sizeof(*wm9713), GFP_KERNEL);
+	if (wm9713 == NULL)
+		return -ENOMEM;
+
+	mutex_init(&wm9713->lock);
+
+	ac97_set_drvdata(adev, wm9713);
+
+	return snd_soc_register_codec(ac97_codec_dev2dev(adev),
+				      &soc_codec_dev_wm9713, wm9713_dai,
+				      ARRAY_SIZE(wm9713_dai));
+}
+
+static int wm9713_ac97_remove(struct ac97_codec_device *adev)
+{
+	snd_soc_unregister_codec(ac97_codec_dev2dev(adev));
+	return 0;
+}
+
+static struct ac97_id wm9713_ac97_ids[] = {
+	{ .id = WM9713_VENDOR_ID, .mask = WM9713_VENDOR_ID_MASK },
+	{ }
+};
+
+static struct ac97_codec_driver wm9713_ac97_driver = {
+	.driver = {
+			.name = "wm9713-codec",
+	},
+	.probe		= wm9713_ac97_probe,
+	.remove		= wm9713_ac97_remove,
+	.id_table	= wm9713_ac97_ids,
+};
+
+static int __init wm9713_init(void)
+{
+	ac97_codec_driver_register(&wm9713_ac97_driver);
+	return platform_driver_register(&wm9713_codec_driver);
+}
+module_init(wm9713_init);
+
+static void __exit wm9713_exit(void)
+{
+	ac97_codec_driver_unregister(&wm9713_ac97_driver);
+	return platform_driver_unregister(&wm9713_codec_driver);
+}
+module_exit(wm9713_exit);
 
 MODULE_DESCRIPTION("ASoC WM9713/WM9714 driver");
 MODULE_AUTHOR("Liam Girdwood");
-- 
2.1.4

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

* [RFC PATCH 3/7] ASoC: wm9713: add ac97 new bus support
@ 2016-04-30 21:15   ` Robert Jarzmik
  0 siblings, 0 replies; 74+ messages in thread
From: Robert Jarzmik @ 2016-04-30 21:15 UTC (permalink / raw)
  To: linux-arm-kernel

Add support for the new ac97 bus model, where devices are automatically
discovered on AC-Links.

Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
---
 sound/soc/codecs/wm9713.c | 62 ++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 56 insertions(+), 6 deletions(-)

diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c
index 9849643ef809..bd5229236a8a 100644
--- a/sound/soc/codecs/wm9713.c
+++ b/sound/soc/codecs/wm9713.c
@@ -22,7 +22,8 @@
 #include <linux/regmap.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
-#include <sound/ac97_codec.h>
+#include <sound/ac97/codec.h>
+#include <sound/ac97/compat.h>
 #include <sound/initval.h>
 #include <sound/pcm_params.h>
 #include <sound/tlv.h>
@@ -1207,14 +1208,13 @@ static int wm9713_soc_probe(struct snd_soc_codec *codec)
 	struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec);
 	struct regmap *regmap;
 
-	wm9713->ac97 = snd_soc_new_ac97_codec(codec, WM9713_VENDOR_ID,
-		WM9713_VENDOR_ID_MASK);
+	wm9713->ac97 = compat_alloc_snd_ac97_codec(codec);
 	if (IS_ERR(wm9713->ac97))
 		return PTR_ERR(wm9713->ac97);
 
 	regmap = regmap_init_ac97(wm9713->ac97, &wm9713_regmap_config);
 	if (IS_ERR(regmap)) {
-		snd_soc_free_ac97_codec(wm9713->ac97);
+		compat_release_snd_ac97_codec(wm9713->ac97);
 		return PTR_ERR(regmap);
 	}
 
@@ -1231,7 +1231,7 @@ static int wm9713_soc_remove(struct snd_soc_codec *codec)
 	struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec);
 
 	snd_soc_codec_exit_regmap(codec);
-	snd_soc_free_ac97_codec(wm9713->ac97);
+	compat_release_snd_ac97_codec(wm9713->ac97);
 	return 0;
 }
 
@@ -1281,7 +1281,57 @@ static struct platform_driver wm9713_codec_driver = {
 	.remove = wm9713_remove,
 };
 
-module_platform_driver(wm9713_codec_driver);
+static int wm9713_ac97_probe(struct ac97_codec_device *adev)
+{
+	struct wm9713_priv *wm9713;
+
+	wm9713 = devm_kzalloc(ac97_codec_dev2dev(adev),
+			      sizeof(*wm9713), GFP_KERNEL);
+	if (wm9713 == NULL)
+		return -ENOMEM;
+
+	mutex_init(&wm9713->lock);
+
+	ac97_set_drvdata(adev, wm9713);
+
+	return snd_soc_register_codec(ac97_codec_dev2dev(adev),
+				      &soc_codec_dev_wm9713, wm9713_dai,
+				      ARRAY_SIZE(wm9713_dai));
+}
+
+static int wm9713_ac97_remove(struct ac97_codec_device *adev)
+{
+	snd_soc_unregister_codec(ac97_codec_dev2dev(adev));
+	return 0;
+}
+
+static struct ac97_id wm9713_ac97_ids[] = {
+	{ .id = WM9713_VENDOR_ID, .mask = WM9713_VENDOR_ID_MASK },
+	{ }
+};
+
+static struct ac97_codec_driver wm9713_ac97_driver = {
+	.driver = {
+			.name = "wm9713-codec",
+	},
+	.probe		= wm9713_ac97_probe,
+	.remove		= wm9713_ac97_remove,
+	.id_table	= wm9713_ac97_ids,
+};
+
+static int __init wm9713_init(void)
+{
+	ac97_codec_driver_register(&wm9713_ac97_driver);
+	return platform_driver_register(&wm9713_codec_driver);
+}
+module_init(wm9713_init);
+
+static void __exit wm9713_exit(void)
+{
+	ac97_codec_driver_unregister(&wm9713_ac97_driver);
+	return platform_driver_unregister(&wm9713_codec_driver);
+}
+module_exit(wm9713_exit);
 
 MODULE_DESCRIPTION("ASoC WM9713/WM9714 driver");
 MODULE_AUTHOR("Liam Girdwood");
-- 
2.1.4

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

* [RFC PATCH 4/7] ASoC: pxa: switch to new ac97 bus support
  2016-04-30 21:15 ` Robert Jarzmik
@ 2016-04-30 21:15   ` Robert Jarzmik
  -1 siblings, 0 replies; 74+ messages in thread
From: Robert Jarzmik @ 2016-04-30 21:15 UTC (permalink / raw)
  To: Robert Jarzmik, Daniel Mack, Haojian Zhuang, Jaroslav Kysela,
	Takashi Iwai, Liam Girdwood, Mark Brown
  Cc: linux-arm-kernel, linux-kernel, alsa-devel, patches

Switch to the new ac97 bus support in sound/ac97 instead of the legacy
snd_ac97 one.

Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
---
 include/sound/pxa2xx-lib.h  | 14 ++++++++------
 sound/arm/Kconfig           |  1 -
 sound/arm/pxa2xx-ac97-lib.c | 31 +++++++++++++++++++------------
 sound/soc/pxa/Kconfig       |  4 ++--
 sound/soc/pxa/pxa2xx-ac97.c | 12 +++++++-----
 5 files changed, 36 insertions(+), 26 deletions(-)

diff --git a/include/sound/pxa2xx-lib.h b/include/sound/pxa2xx-lib.h
index 6ef629bde164..7072353234f9 100644
--- a/include/sound/pxa2xx-lib.h
+++ b/include/sound/pxa2xx-lib.h
@@ -2,7 +2,8 @@
 #define PXA2XX_LIB_H
 
 #include <linux/platform_device.h>
-#include <sound/ac97_codec.h>
+#include <sound/ac97/codec.h>
+#include <sound/ac97/compat.h>
 
 /* PCM */
 
@@ -21,12 +22,13 @@ extern void pxa2xx_pcm_free_dma_buffers(struct snd_pcm *pcm);
 
 /* AC97 */
 
-extern unsigned short pxa2xx_ac97_read(struct snd_ac97 *ac97, unsigned short reg);
-extern void pxa2xx_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val);
+extern int pxa2xx_ac97_read(struct ac97_codec_device *ac97, unsigned short reg);
+extern int pxa2xx_ac97_write(struct ac97_codec_device *ac97,
+			     unsigned short reg, unsigned short val);
 
-extern bool pxa2xx_ac97_try_warm_reset(struct snd_ac97 *ac97);
-extern bool pxa2xx_ac97_try_cold_reset(struct snd_ac97 *ac97);
-extern void pxa2xx_ac97_finish_reset(struct snd_ac97 *ac97);
+extern bool pxa2xx_ac97_try_warm_reset(struct ac97_codec_device *ac97);
+extern bool pxa2xx_ac97_try_cold_reset(struct ac97_codec_device *ac97);
+extern void pxa2xx_ac97_finish_reset(struct ac97_codec_device *ac97);
 
 extern int pxa2xx_ac97_hw_suspend(void);
 extern int pxa2xx_ac97_hw_resume(void);
diff --git a/sound/arm/Kconfig b/sound/arm/Kconfig
index e0406211716b..94f7539a2c1f 100644
--- a/sound/arm/Kconfig
+++ b/sound/arm/Kconfig
@@ -11,7 +11,6 @@ menuconfig SND_ARM
 
 config SND_PXA2XX_LIB
 	tristate
-	select SND_AC97_CODEC if SND_PXA2XX_LIB_AC97
 	select SND_DMAENGINE_PCM
 
 config SND_PXA2XX_LIB_AC97
diff --git a/sound/arm/pxa2xx-ac97-lib.c b/sound/arm/pxa2xx-ac97-lib.c
index 39c3969ac1c7..bc5c6d72510a 100644
--- a/sound/arm/pxa2xx-ac97-lib.c
+++ b/sound/arm/pxa2xx-ac97-lib.c
@@ -20,7 +20,7 @@
 #include <linux/io.h>
 #include <linux/gpio.h>
 
-#include <sound/ac97_codec.h>
+#include <sound/ac97/controller.h>
 #include <sound/pxa2xx-lib.h>
 
 #include <mach/irqs.h>
@@ -46,11 +46,14 @@ extern void pxa27x_configure_ac97reset(int reset_gpio, bool to_gpio);
  * 1 jiffy timeout if interrupt never comes).
  */
 
-unsigned short pxa2xx_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
+int pxa2xx_ac97_read(struct ac97_codec_device *ac97, unsigned short reg)
 {
-	unsigned short val = -1;
+	int val = -ENODEV;
 	volatile u32 *reg_addr;
 
+	if (ac97->num > 0)
+		return -ENODEV;
+
 	mutex_lock(&car_mutex);
 
 	/* set up primary or secondary codec space */
@@ -63,21 +66,21 @@ unsigned short pxa2xx_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
 	/* start read access across the ac97 link */
 	GSR = GSR_CDONE | GSR_SDONE;
 	gsr_bits = 0;
-	val = *reg_addr;
+	val = (*reg_addr & 0xffff);
 	if (reg == AC97_GPIO_STATUS)
 		goto out;
 	if (wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_SDONE, 1) <= 0 &&
 	    !((GSR | gsr_bits) & GSR_SDONE)) {
 		printk(KERN_ERR "%s: read error (ac97_reg=%d GSR=%#lx)\n",
 				__func__, reg, GSR | gsr_bits);
-		val = -1;
+		val = -ETIMEDOUT;
 		goto out;
 	}
 
 	/* valid data now */
 	GSR = GSR_CDONE | GSR_SDONE;
 	gsr_bits = 0;
-	val = *reg_addr;
+	val = (*reg_addr & 0xffff);
 	/* but we've just started another cycle... */
 	wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_SDONE, 1);
 
@@ -86,10 +89,11 @@ out:	mutex_unlock(&car_mutex);
 }
 EXPORT_SYMBOL_GPL(pxa2xx_ac97_read);
 
-void pxa2xx_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
-			unsigned short val)
+int pxa2xx_ac97_write(struct ac97_codec_device *ac97, unsigned short reg,
+		      unsigned short val)
 {
 	volatile u32 *reg_addr;
+	int ret = 0;
 
 	mutex_lock(&car_mutex);
 
@@ -104,11 +108,14 @@ void pxa2xx_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
 	gsr_bits = 0;
 	*reg_addr = val;
 	if (wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_CDONE, 1) <= 0 &&
-	    !((GSR | gsr_bits) & GSR_CDONE))
+	    !((GSR | gsr_bits) & GSR_CDONE)) {
 		printk(KERN_ERR "%s: write error (ac97_reg=%d GSR=%#lx)\n",
 				__func__, reg, GSR | gsr_bits);
+		ret = -EIO;
+	}
 
 	mutex_unlock(&car_mutex);
+	return ret;
 }
 EXPORT_SYMBOL_GPL(pxa2xx_ac97_write);
 
@@ -188,7 +195,7 @@ static inline void pxa_ac97_cold_pxa3xx(void)
 }
 #endif
 
-bool pxa2xx_ac97_try_warm_reset(struct snd_ac97 *ac97)
+bool pxa2xx_ac97_try_warm_reset(struct ac97_codec_device *ac97)
 {
 	unsigned long gsr;
 	unsigned int timeout = 100;
@@ -225,7 +232,7 @@ bool pxa2xx_ac97_try_warm_reset(struct snd_ac97 *ac97)
 }
 EXPORT_SYMBOL_GPL(pxa2xx_ac97_try_warm_reset);
 
-bool pxa2xx_ac97_try_cold_reset(struct snd_ac97 *ac97)
+bool pxa2xx_ac97_try_cold_reset(struct ac97_codec_device *ac97)
 {
 	unsigned long gsr;
 	unsigned int timeout = 1000;
@@ -263,7 +270,7 @@ bool pxa2xx_ac97_try_cold_reset(struct snd_ac97 *ac97)
 EXPORT_SYMBOL_GPL(pxa2xx_ac97_try_cold_reset);
 
 
-void pxa2xx_ac97_finish_reset(struct snd_ac97 *ac97)
+void pxa2xx_ac97_finish_reset(struct ac97_codec_device *ac97)
 {
 	GCR &= ~(GCR_PRIRDY_IEN|GCR_SECRDY_IEN);
 	GCR |= GCR_SDONE_IE|GCR_CDONE_IE;
diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig
index f2bf8661dd21..784e6dedf5bf 100644
--- a/sound/soc/pxa/Kconfig
+++ b/sound/soc/pxa/Kconfig
@@ -23,9 +23,9 @@ config SND_PXA2XX_AC97
 
 config SND_PXA2XX_SOC_AC97
 	tristate
-	select AC97_BUS
+	select AC97_BUS_NEW
 	select SND_PXA2XX_LIB_AC97
-	select SND_SOC_AC97_BUS
+	select SND_SOC_AC97_BUS_NEW
 
 config SND_PXA2XX_SOC_I2S
 	tristate
diff --git a/sound/soc/pxa/pxa2xx-ac97.c b/sound/soc/pxa/pxa2xx-ac97.c
index f3de615aacd7..eb3ba630994b 100644
--- a/sound/soc/pxa/pxa2xx-ac97.c
+++ b/sound/soc/pxa/pxa2xx-ac97.c
@@ -10,6 +10,7 @@
  * published by the Free Software Foundation.
  */
 
+#include <sound/ac97/controller.h>
 #include <linux/init.h>
 #include <linux/io.h>
 #include <linux/module.h>
@@ -29,21 +30,21 @@
 
 #include "pxa2xx-ac97.h"
 
-static void pxa2xx_ac97_warm_reset(struct snd_ac97 *ac97)
+static void pxa2xx_ac97_warm_reset(struct ac97_codec_device *ac97)
 {
 	pxa2xx_ac97_try_warm_reset(ac97);
 
 	pxa2xx_ac97_finish_reset(ac97);
 }
 
-static void pxa2xx_ac97_cold_reset(struct snd_ac97 *ac97)
+static void pxa2xx_ac97_cold_reset(struct ac97_codec_device *ac97)
 {
 	pxa2xx_ac97_try_cold_reset(ac97);
 
 	pxa2xx_ac97_finish_reset(ac97);
 }
 
-static struct snd_ac97_bus_ops pxa2xx_ac97_ops = {
+static struct ac97_controller_ops pxa2xx_ac97_ops = {
 	.read	= pxa2xx_ac97_read,
 	.write	= pxa2xx_ac97_write,
 	.warm_reset	= pxa2xx_ac97_warm_reset,
@@ -236,7 +237,8 @@ static int pxa2xx_ac97_dev_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	ret = snd_soc_set_ac97_ops(&pxa2xx_ac97_ops);
+	//RJK: no more ret = snd_soc_set_ac97_ops(&pxa2xx_ac97_ops);
+	ret = ac97_digital_controller_register(&pxa2xx_ac97_ops, &pdev->dev);
 	if (ret != 0)
 		return ret;
 
@@ -251,7 +253,7 @@ static int pxa2xx_ac97_dev_probe(struct platform_device *pdev)
 static int pxa2xx_ac97_dev_remove(struct platform_device *pdev)
 {
 	snd_soc_unregister_component(&pdev->dev);
-	snd_soc_set_ac97_ops(NULL);
+	ac97_digital_controller_unregister(&pdev->dev);
 	pxa2xx_ac97_hw_remove(pdev);
 	return 0;
 }
-- 
2.1.4

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

* [RFC PATCH 4/7] ASoC: pxa: switch to new ac97 bus support
@ 2016-04-30 21:15   ` Robert Jarzmik
  0 siblings, 0 replies; 74+ messages in thread
From: Robert Jarzmik @ 2016-04-30 21:15 UTC (permalink / raw)
  To: linux-arm-kernel

Switch to the new ac97 bus support in sound/ac97 instead of the legacy
snd_ac97 one.

Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
---
 include/sound/pxa2xx-lib.h  | 14 ++++++++------
 sound/arm/Kconfig           |  1 -
 sound/arm/pxa2xx-ac97-lib.c | 31 +++++++++++++++++++------------
 sound/soc/pxa/Kconfig       |  4 ++--
 sound/soc/pxa/pxa2xx-ac97.c | 12 +++++++-----
 5 files changed, 36 insertions(+), 26 deletions(-)

diff --git a/include/sound/pxa2xx-lib.h b/include/sound/pxa2xx-lib.h
index 6ef629bde164..7072353234f9 100644
--- a/include/sound/pxa2xx-lib.h
+++ b/include/sound/pxa2xx-lib.h
@@ -2,7 +2,8 @@
 #define PXA2XX_LIB_H
 
 #include <linux/platform_device.h>
-#include <sound/ac97_codec.h>
+#include <sound/ac97/codec.h>
+#include <sound/ac97/compat.h>
 
 /* PCM */
 
@@ -21,12 +22,13 @@ extern void pxa2xx_pcm_free_dma_buffers(struct snd_pcm *pcm);
 
 /* AC97 */
 
-extern unsigned short pxa2xx_ac97_read(struct snd_ac97 *ac97, unsigned short reg);
-extern void pxa2xx_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val);
+extern int pxa2xx_ac97_read(struct ac97_codec_device *ac97, unsigned short reg);
+extern int pxa2xx_ac97_write(struct ac97_codec_device *ac97,
+			     unsigned short reg, unsigned short val);
 
-extern bool pxa2xx_ac97_try_warm_reset(struct snd_ac97 *ac97);
-extern bool pxa2xx_ac97_try_cold_reset(struct snd_ac97 *ac97);
-extern void pxa2xx_ac97_finish_reset(struct snd_ac97 *ac97);
+extern bool pxa2xx_ac97_try_warm_reset(struct ac97_codec_device *ac97);
+extern bool pxa2xx_ac97_try_cold_reset(struct ac97_codec_device *ac97);
+extern void pxa2xx_ac97_finish_reset(struct ac97_codec_device *ac97);
 
 extern int pxa2xx_ac97_hw_suspend(void);
 extern int pxa2xx_ac97_hw_resume(void);
diff --git a/sound/arm/Kconfig b/sound/arm/Kconfig
index e0406211716b..94f7539a2c1f 100644
--- a/sound/arm/Kconfig
+++ b/sound/arm/Kconfig
@@ -11,7 +11,6 @@ menuconfig SND_ARM
 
 config SND_PXA2XX_LIB
 	tristate
-	select SND_AC97_CODEC if SND_PXA2XX_LIB_AC97
 	select SND_DMAENGINE_PCM
 
 config SND_PXA2XX_LIB_AC97
diff --git a/sound/arm/pxa2xx-ac97-lib.c b/sound/arm/pxa2xx-ac97-lib.c
index 39c3969ac1c7..bc5c6d72510a 100644
--- a/sound/arm/pxa2xx-ac97-lib.c
+++ b/sound/arm/pxa2xx-ac97-lib.c
@@ -20,7 +20,7 @@
 #include <linux/io.h>
 #include <linux/gpio.h>
 
-#include <sound/ac97_codec.h>
+#include <sound/ac97/controller.h>
 #include <sound/pxa2xx-lib.h>
 
 #include <mach/irqs.h>
@@ -46,11 +46,14 @@ extern void pxa27x_configure_ac97reset(int reset_gpio, bool to_gpio);
  * 1 jiffy timeout if interrupt never comes).
  */
 
-unsigned short pxa2xx_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
+int pxa2xx_ac97_read(struct ac97_codec_device *ac97, unsigned short reg)
 {
-	unsigned short val = -1;
+	int val = -ENODEV;
 	volatile u32 *reg_addr;
 
+	if (ac97->num > 0)
+		return -ENODEV;
+
 	mutex_lock(&car_mutex);
 
 	/* set up primary or secondary codec space */
@@ -63,21 +66,21 @@ unsigned short pxa2xx_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
 	/* start read access across the ac97 link */
 	GSR = GSR_CDONE | GSR_SDONE;
 	gsr_bits = 0;
-	val = *reg_addr;
+	val = (*reg_addr & 0xffff);
 	if (reg == AC97_GPIO_STATUS)
 		goto out;
 	if (wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_SDONE, 1) <= 0 &&
 	    !((GSR | gsr_bits) & GSR_SDONE)) {
 		printk(KERN_ERR "%s: read error (ac97_reg=%d GSR=%#lx)\n",
 				__func__, reg, GSR | gsr_bits);
-		val = -1;
+		val = -ETIMEDOUT;
 		goto out;
 	}
 
 	/* valid data now */
 	GSR = GSR_CDONE | GSR_SDONE;
 	gsr_bits = 0;
-	val = *reg_addr;
+	val = (*reg_addr & 0xffff);
 	/* but we've just started another cycle... */
 	wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_SDONE, 1);
 
@@ -86,10 +89,11 @@ out:	mutex_unlock(&car_mutex);
 }
 EXPORT_SYMBOL_GPL(pxa2xx_ac97_read);
 
-void pxa2xx_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
-			unsigned short val)
+int pxa2xx_ac97_write(struct ac97_codec_device *ac97, unsigned short reg,
+		      unsigned short val)
 {
 	volatile u32 *reg_addr;
+	int ret = 0;
 
 	mutex_lock(&car_mutex);
 
@@ -104,11 +108,14 @@ void pxa2xx_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
 	gsr_bits = 0;
 	*reg_addr = val;
 	if (wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_CDONE, 1) <= 0 &&
-	    !((GSR | gsr_bits) & GSR_CDONE))
+	    !((GSR | gsr_bits) & GSR_CDONE)) {
 		printk(KERN_ERR "%s: write error (ac97_reg=%d GSR=%#lx)\n",
 				__func__, reg, GSR | gsr_bits);
+		ret = -EIO;
+	}
 
 	mutex_unlock(&car_mutex);
+	return ret;
 }
 EXPORT_SYMBOL_GPL(pxa2xx_ac97_write);
 
@@ -188,7 +195,7 @@ static inline void pxa_ac97_cold_pxa3xx(void)
 }
 #endif
 
-bool pxa2xx_ac97_try_warm_reset(struct snd_ac97 *ac97)
+bool pxa2xx_ac97_try_warm_reset(struct ac97_codec_device *ac97)
 {
 	unsigned long gsr;
 	unsigned int timeout = 100;
@@ -225,7 +232,7 @@ bool pxa2xx_ac97_try_warm_reset(struct snd_ac97 *ac97)
 }
 EXPORT_SYMBOL_GPL(pxa2xx_ac97_try_warm_reset);
 
-bool pxa2xx_ac97_try_cold_reset(struct snd_ac97 *ac97)
+bool pxa2xx_ac97_try_cold_reset(struct ac97_codec_device *ac97)
 {
 	unsigned long gsr;
 	unsigned int timeout = 1000;
@@ -263,7 +270,7 @@ bool pxa2xx_ac97_try_cold_reset(struct snd_ac97 *ac97)
 EXPORT_SYMBOL_GPL(pxa2xx_ac97_try_cold_reset);
 
 
-void pxa2xx_ac97_finish_reset(struct snd_ac97 *ac97)
+void pxa2xx_ac97_finish_reset(struct ac97_codec_device *ac97)
 {
 	GCR &= ~(GCR_PRIRDY_IEN|GCR_SECRDY_IEN);
 	GCR |= GCR_SDONE_IE|GCR_CDONE_IE;
diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig
index f2bf8661dd21..784e6dedf5bf 100644
--- a/sound/soc/pxa/Kconfig
+++ b/sound/soc/pxa/Kconfig
@@ -23,9 +23,9 @@ config SND_PXA2XX_AC97
 
 config SND_PXA2XX_SOC_AC97
 	tristate
-	select AC97_BUS
+	select AC97_BUS_NEW
 	select SND_PXA2XX_LIB_AC97
-	select SND_SOC_AC97_BUS
+	select SND_SOC_AC97_BUS_NEW
 
 config SND_PXA2XX_SOC_I2S
 	tristate
diff --git a/sound/soc/pxa/pxa2xx-ac97.c b/sound/soc/pxa/pxa2xx-ac97.c
index f3de615aacd7..eb3ba630994b 100644
--- a/sound/soc/pxa/pxa2xx-ac97.c
+++ b/sound/soc/pxa/pxa2xx-ac97.c
@@ -10,6 +10,7 @@
  * published by the Free Software Foundation.
  */
 
+#include <sound/ac97/controller.h>
 #include <linux/init.h>
 #include <linux/io.h>
 #include <linux/module.h>
@@ -29,21 +30,21 @@
 
 #include "pxa2xx-ac97.h"
 
-static void pxa2xx_ac97_warm_reset(struct snd_ac97 *ac97)
+static void pxa2xx_ac97_warm_reset(struct ac97_codec_device *ac97)
 {
 	pxa2xx_ac97_try_warm_reset(ac97);
 
 	pxa2xx_ac97_finish_reset(ac97);
 }
 
-static void pxa2xx_ac97_cold_reset(struct snd_ac97 *ac97)
+static void pxa2xx_ac97_cold_reset(struct ac97_codec_device *ac97)
 {
 	pxa2xx_ac97_try_cold_reset(ac97);
 
 	pxa2xx_ac97_finish_reset(ac97);
 }
 
-static struct snd_ac97_bus_ops pxa2xx_ac97_ops = {
+static struct ac97_controller_ops pxa2xx_ac97_ops = {
 	.read	= pxa2xx_ac97_read,
 	.write	= pxa2xx_ac97_write,
 	.warm_reset	= pxa2xx_ac97_warm_reset,
@@ -236,7 +237,8 @@ static int pxa2xx_ac97_dev_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	ret = snd_soc_set_ac97_ops(&pxa2xx_ac97_ops);
+	//RJK: no more ret = snd_soc_set_ac97_ops(&pxa2xx_ac97_ops);
+	ret = ac97_digital_controller_register(&pxa2xx_ac97_ops, &pdev->dev);
 	if (ret != 0)
 		return ret;
 
@@ -251,7 +253,7 @@ static int pxa2xx_ac97_dev_probe(struct platform_device *pdev)
 static int pxa2xx_ac97_dev_remove(struct platform_device *pdev)
 {
 	snd_soc_unregister_component(&pdev->dev);
-	snd_soc_set_ac97_ops(NULL);
+	ac97_digital_controller_unregister(&pdev->dev);
 	pxa2xx_ac97_hw_remove(pdev);
 	return 0;
 }
-- 
2.1.4

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

* [RFC PATCH 5/7] ARM: pxa: mioa701 remove wm9713 from platform devices
  2016-04-30 21:15 ` Robert Jarzmik
  (?)
@ 2016-04-30 21:15   ` Robert Jarzmik
  -1 siblings, 0 replies; 74+ messages in thread
From: Robert Jarzmik @ 2016-04-30 21:15 UTC (permalink / raw)
  To: Robert Jarzmik, Daniel Mack, Haojian Zhuang, Jaroslav Kysela,
	Takashi Iwai, Liam Girdwood, Mark Brown
  Cc: linux-arm-kernel, linux-kernel, alsa-devel, patches

As the ac97 autoprobing is introduced, remove the manually added wm9713
device.

Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
---
 arch/arm/mach-pxa/mioa701.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/mach-pxa/mioa701.c b/arch/arm/mach-pxa/mioa701.c
index 38a96a193dc4..e69e20febf83 100644
--- a/arch/arm/mach-pxa/mioa701.c
+++ b/arch/arm/mach-pxa/mioa701.c
@@ -690,7 +690,6 @@ static struct platform_device *devices[] __initdata = {
 	&mioa701_gpio_keys,
 	&mioa701_backlight,
 	&mioa701_led,
-	&wm9713_acodec,
 	&pxa2xx_pcm,
 	&mioa701_sound,
 	&power_dev,
-- 
2.1.4

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

* [RFC PATCH 5/7] ARM: pxa: mioa701 remove wm9713 from platform devices
@ 2016-04-30 21:15   ` Robert Jarzmik
  0 siblings, 0 replies; 74+ messages in thread
From: Robert Jarzmik @ 2016-04-30 21:15 UTC (permalink / raw)
  To: Robert Jarzmik, Daniel Mack, Haojian Zhuang, Jaroslav Kysela,
	Takashi Iwai, Liam Girdwood, Mark Brown
  Cc: alsa-devel, patches, linux-kernel, linux-arm-kernel

As the ac97 autoprobing is introduced, remove the manually added wm9713
device.

Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
---
 arch/arm/mach-pxa/mioa701.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/mach-pxa/mioa701.c b/arch/arm/mach-pxa/mioa701.c
index 38a96a193dc4..e69e20febf83 100644
--- a/arch/arm/mach-pxa/mioa701.c
+++ b/arch/arm/mach-pxa/mioa701.c
@@ -690,7 +690,6 @@ static struct platform_device *devices[] __initdata = {
 	&mioa701_gpio_keys,
 	&mioa701_backlight,
 	&mioa701_led,
-	&wm9713_acodec,
 	&pxa2xx_pcm,
 	&mioa701_sound,
 	&power_dev,
-- 
2.1.4

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

* [RFC PATCH 5/7] ARM: pxa: mioa701 remove wm9713 from platform devices
@ 2016-04-30 21:15   ` Robert Jarzmik
  0 siblings, 0 replies; 74+ messages in thread
From: Robert Jarzmik @ 2016-04-30 21:15 UTC (permalink / raw)
  To: linux-arm-kernel

As the ac97 autoprobing is introduced, remove the manually added wm9713
device.

Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
---
 arch/arm/mach-pxa/mioa701.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/mach-pxa/mioa701.c b/arch/arm/mach-pxa/mioa701.c
index 38a96a193dc4..e69e20febf83 100644
--- a/arch/arm/mach-pxa/mioa701.c
+++ b/arch/arm/mach-pxa/mioa701.c
@@ -690,7 +690,6 @@ static struct platform_device *devices[] __initdata = {
 	&mioa701_gpio_keys,
 	&mioa701_backlight,
 	&mioa701_led,
-	&wm9713_acodec,
 	&pxa2xx_pcm,
 	&mioa701_sound,
 	&power_dev,
-- 
2.1.4

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

* [RFC PATCH 6/7] ASoC: mioa701_wm9713: convert to new ac97 bus
  2016-04-30 21:15 ` Robert Jarzmik
  (?)
@ 2016-04-30 21:15   ` Robert Jarzmik
  -1 siblings, 0 replies; 74+ messages in thread
From: Robert Jarzmik @ 2016-04-30 21:15 UTC (permalink / raw)
  To: Robert Jarzmik, Daniel Mack, Haojian Zhuang, Jaroslav Kysela,
	Takashi Iwai, Liam Girdwood, Mark Brown
  Cc: linux-arm-kernel, linux-kernel, alsa-devel, patches

Convert to the new auto-probing ac97 bus, which changes the device name.

Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
---
 sound/soc/pxa/mioa701_wm9713.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/sound/soc/pxa/mioa701_wm9713.c b/sound/soc/pxa/mioa701_wm9713.c
index 5c8f9db50a47..4ed10e6ff5d1 100644
--- a/sound/soc/pxa/mioa701_wm9713.c
+++ b/sound/soc/pxa/mioa701_wm9713.c
@@ -149,7 +149,7 @@ static struct snd_soc_dai_link mioa701_dai[] = {
 		.stream_name = "AC97 HiFi",
 		.cpu_dai_name = "pxa2xx-ac97",
 		.codec_dai_name = "wm9713-hifi",
-		.codec_name = "wm9713-codec",
+		.codec_name = "pxa2xx-ac97:0",
 		.init = mioa701_wm9713_init,
 		.platform_name = "pxa-pcm-audio",
 		.ops = &mioa701_ops,
@@ -159,7 +159,7 @@ static struct snd_soc_dai_link mioa701_dai[] = {
 		.stream_name = "AC97 Aux",
 		.cpu_dai_name = "pxa2xx-ac97-aux",
 		.codec_dai_name ="wm9713-aux",
-		.codec_name = "wm9713-codec",
+		.codec_name = "pxa2xx-ac97:0",
 		.platform_name = "pxa-pcm-audio",
 		.ops = &mioa701_ops,
 	},
-- 
2.1.4

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

* [RFC PATCH 6/7] ASoC: mioa701_wm9713: convert to new ac97 bus
@ 2016-04-30 21:15   ` Robert Jarzmik
  0 siblings, 0 replies; 74+ messages in thread
From: Robert Jarzmik @ 2016-04-30 21:15 UTC (permalink / raw)
  To: Robert Jarzmik, Daniel Mack, Haojian Zhuang, Jaroslav Kysela,
	Takashi Iwai, Liam Girdwood, Mark Brown
  Cc: alsa-devel, patches, linux-kernel, linux-arm-kernel

Convert to the new auto-probing ac97 bus, which changes the device name.

Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
---
 sound/soc/pxa/mioa701_wm9713.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/sound/soc/pxa/mioa701_wm9713.c b/sound/soc/pxa/mioa701_wm9713.c
index 5c8f9db50a47..4ed10e6ff5d1 100644
--- a/sound/soc/pxa/mioa701_wm9713.c
+++ b/sound/soc/pxa/mioa701_wm9713.c
@@ -149,7 +149,7 @@ static struct snd_soc_dai_link mioa701_dai[] = {
 		.stream_name = "AC97 HiFi",
 		.cpu_dai_name = "pxa2xx-ac97",
 		.codec_dai_name = "wm9713-hifi",
-		.codec_name = "wm9713-codec",
+		.codec_name = "pxa2xx-ac97:0",
 		.init = mioa701_wm9713_init,
 		.platform_name = "pxa-pcm-audio",
 		.ops = &mioa701_ops,
@@ -159,7 +159,7 @@ static struct snd_soc_dai_link mioa701_dai[] = {
 		.stream_name = "AC97 Aux",
 		.cpu_dai_name = "pxa2xx-ac97-aux",
 		.codec_dai_name ="wm9713-aux",
-		.codec_name = "wm9713-codec",
+		.codec_name = "pxa2xx-ac97:0",
 		.platform_name = "pxa-pcm-audio",
 		.ops = &mioa701_ops,
 	},
-- 
2.1.4

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

* [RFC PATCH 6/7] ASoC: mioa701_wm9713: convert to new ac97 bus
@ 2016-04-30 21:15   ` Robert Jarzmik
  0 siblings, 0 replies; 74+ messages in thread
From: Robert Jarzmik @ 2016-04-30 21:15 UTC (permalink / raw)
  To: linux-arm-kernel

Convert to the new auto-probing ac97 bus, which changes the device name.

Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
---
 sound/soc/pxa/mioa701_wm9713.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/sound/soc/pxa/mioa701_wm9713.c b/sound/soc/pxa/mioa701_wm9713.c
index 5c8f9db50a47..4ed10e6ff5d1 100644
--- a/sound/soc/pxa/mioa701_wm9713.c
+++ b/sound/soc/pxa/mioa701_wm9713.c
@@ -149,7 +149,7 @@ static struct snd_soc_dai_link mioa701_dai[] = {
 		.stream_name = "AC97 HiFi",
 		.cpu_dai_name = "pxa2xx-ac97",
 		.codec_dai_name = "wm9713-hifi",
-		.codec_name = "wm9713-codec",
+		.codec_name = "pxa2xx-ac97:0",
 		.init = mioa701_wm9713_init,
 		.platform_name = "pxa-pcm-audio",
 		.ops = &mioa701_ops,
@@ -159,7 +159,7 @@ static struct snd_soc_dai_link mioa701_dai[] = {
 		.stream_name = "AC97 Aux",
 		.cpu_dai_name = "pxa2xx-ac97-aux",
 		.codec_dai_name ="wm9713-aux",
-		.codec_name = "wm9713-codec",
+		.codec_name = "pxa2xx-ac97:0",
 		.platform_name = "pxa-pcm-audio",
 		.ops = &mioa701_ops,
 	},
-- 
2.1.4

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

* [RFC PATCH 7/7] ASoC: add new ac97 bus support
  2016-04-30 21:15 ` Robert Jarzmik
@ 2016-04-30 21:15   ` Robert Jarzmik
  -1 siblings, 0 replies; 74+ messages in thread
From: Robert Jarzmik @ 2016-04-30 21:15 UTC (permalink / raw)
  To: Robert Jarzmik, Daniel Mack, Haojian Zhuang, Jaroslav Kysela,
	Takashi Iwai, Liam Girdwood, Mark Brown
  Cc: linux-arm-kernel, linux-kernel, alsa-devel, patches

Add the new ac97 bus support, with ac97 bus automatic probing.

Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
---
 sound/Kconfig     | 7 +++++++
 sound/Makefile    | 1 +
 sound/soc/Kconfig | 4 ++++
 3 files changed, 12 insertions(+)

diff --git a/sound/Kconfig b/sound/Kconfig
index 5a240e050ae6..83d67eae3580 100644
--- a/sound/Kconfig
+++ b/sound/Kconfig
@@ -134,3 +134,10 @@ config AC97_BUS
 	  sound subsystem and other function drivers completely unrelated to
 	  sound although they're sharing the AC97 bus. Concerned drivers
 	  should "select" this.
+
+config AC97_BUS_NEW
+	tristate
+	help
+	  This is the new AC97 bus type, successor of AC97_BUS. The ported
+	  drivers which benefit from the AC97 automatic probing should "select"
+	  this instead of the AC97_BUS.
diff --git a/sound/Makefile b/sound/Makefile
index 77320709fd26..74728aee25d5 100644
--- a/sound/Makefile
+++ b/sound/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_SND_AOA) += aoa/
 
 # This one must be compilable even if sound is configured out
 obj-$(CONFIG_AC97_BUS) += ac97_bus.o
+obj-$(CONFIG_AC97_BUS_NEW) += ac97/
 
 ifeq ($(CONFIG_SND),y)
   obj-y += last.o
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
index 182d92efc7c8..5ad0a0422054 100644
--- a/sound/soc/Kconfig
+++ b/sound/soc/Kconfig
@@ -6,6 +6,7 @@ menuconfig SND_SOC
 	tristate "ALSA for SoC audio support"
 	select SND_PCM
 	select AC97_BUS if SND_SOC_AC97_BUS
+	select AC97_BUS_NEW if SND_SOC_AC97_BUS_NEW
 	select SND_JACK
 	select REGMAP_I2C if I2C
 	select REGMAP_SPI if SPI_MASTER
@@ -25,6 +26,9 @@ if SND_SOC
 config SND_SOC_AC97_BUS
 	bool
 
+config SND_SOC_AC97_BUS_NEW
+	bool
+
 config SND_SOC_GENERIC_DMAENGINE_PCM
 	bool
 	select SND_DMAENGINE_PCM
-- 
2.1.4

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

* [RFC PATCH 7/7] ASoC: add new ac97 bus support
@ 2016-04-30 21:15   ` Robert Jarzmik
  0 siblings, 0 replies; 74+ messages in thread
From: Robert Jarzmik @ 2016-04-30 21:15 UTC (permalink / raw)
  To: linux-arm-kernel

Add the new ac97 bus support, with ac97 bus automatic probing.

Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
---
 sound/Kconfig     | 7 +++++++
 sound/Makefile    | 1 +
 sound/soc/Kconfig | 4 ++++
 3 files changed, 12 insertions(+)

diff --git a/sound/Kconfig b/sound/Kconfig
index 5a240e050ae6..83d67eae3580 100644
--- a/sound/Kconfig
+++ b/sound/Kconfig
@@ -134,3 +134,10 @@ config AC97_BUS
 	  sound subsystem and other function drivers completely unrelated to
 	  sound although they're sharing the AC97 bus. Concerned drivers
 	  should "select" this.
+
+config AC97_BUS_NEW
+	tristate
+	help
+	  This is the new AC97 bus type, successor of AC97_BUS. The ported
+	  drivers which benefit from the AC97 automatic probing should "select"
+	  this instead of the AC97_BUS.
diff --git a/sound/Makefile b/sound/Makefile
index 77320709fd26..74728aee25d5 100644
--- a/sound/Makefile
+++ b/sound/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_SND_AOA) += aoa/
 
 # This one must be compilable even if sound is configured out
 obj-$(CONFIG_AC97_BUS) += ac97_bus.o
+obj-$(CONFIG_AC97_BUS_NEW) += ac97/
 
 ifeq ($(CONFIG_SND),y)
   obj-y += last.o
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
index 182d92efc7c8..5ad0a0422054 100644
--- a/sound/soc/Kconfig
+++ b/sound/soc/Kconfig
@@ -6,6 +6,7 @@ menuconfig SND_SOC
 	tristate "ALSA for SoC audio support"
 	select SND_PCM
 	select AC97_BUS if SND_SOC_AC97_BUS
+	select AC97_BUS_NEW if SND_SOC_AC97_BUS_NEW
 	select SND_JACK
 	select REGMAP_I2C if I2C
 	select REGMAP_SPI if SPI_MASTER
@@ -25,6 +26,9 @@ if SND_SOC
 config SND_SOC_AC97_BUS
 	bool
 
+config SND_SOC_AC97_BUS_NEW
+	bool
+
 config SND_SOC_GENERIC_DMAENGINE_PCM
 	bool
 	select SND_DMAENGINE_PCM
-- 
2.1.4

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

* Re: [RFC PATCH 1/7] ALSA: ac97: split out the generic ac97 registers
  2016-04-30 21:15   ` Robert Jarzmik
@ 2016-05-03 11:51     ` Mark Brown
  -1 siblings, 0 replies; 74+ messages in thread
From: Mark Brown @ 2016-05-03 11:51 UTC (permalink / raw)
  To: Robert Jarzmik
  Cc: Daniel Mack, Haojian Zhuang, Jaroslav Kysela, Takashi Iwai,
	Liam Girdwood, linux-arm-kernel, linux-kernel, alsa-devel,
	patches

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

On Sat, Apr 30, 2016 at 11:15:33PM +0200, Robert Jarzmik wrote:
> Split out from the ac97_codec.h the ac97 generic registers, which can be
> used by a codec, typically a generic ac97 codec, and by the ac97 bus, to
> scan an ac97 AC-Link.

I don't entirely see the value in this one but equally it does no harm.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

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

* [RFC PATCH 1/7] ALSA: ac97: split out the generic ac97 registers
@ 2016-05-03 11:51     ` Mark Brown
  0 siblings, 0 replies; 74+ messages in thread
From: Mark Brown @ 2016-05-03 11:51 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Apr 30, 2016 at 11:15:33PM +0200, Robert Jarzmik wrote:
> Split out from the ac97_codec.h the ac97 generic registers, which can be
> used by a codec, typically a generic ac97 codec, and by the ac97 bus, to
> scan an ac97 AC-Link.

I don't entirely see the value in this one but equally it does no harm.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20160503/bbd13938/attachment.sig>

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

* Re: [RFC PATCH 2/7] ALSA: ac97: add an ac97 bus
  2016-04-30 21:15   ` Robert Jarzmik
@ 2016-05-03 16:29     ` Mark Brown
  -1 siblings, 0 replies; 74+ messages in thread
From: Mark Brown @ 2016-05-03 16:29 UTC (permalink / raw)
  To: Robert Jarzmik
  Cc: Daniel Mack, Haojian Zhuang, Jaroslav Kysela, Takashi Iwai,
	Liam Girdwood, linux-arm-kernel, linux-kernel, alsa-devel,
	patches

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

On Sat, Apr 30, 2016 at 11:15:34PM +0200, Robert Jarzmik wrote:
> AC97 is a bus for sound usage. It enables for a AC97 AC-Link to link one
> controller to 0 to 4 AC97 codecs.

> The goal of this new implementation is to implement a device/driver
> model for AC97, with an automatic scan of the bus and automatic
> discovery of AC97 codec devices.

I think this is basically what I was thinking of, yes.  One thing we'll
need to do is work out how to handle systems that need some explicit
action to start clocks for the bus clock, though they were never very
common and it's entirely possible nobody cares any more so perhaps we
just punt and see if anyone notices for now.

> +int ac97_digital_controller_register(const struct ac97_controller_ops *ops,
> +				     struct device *dev);
> +int ac97_digital_controller_unregister(const struct device *dev);

Why "digital"? 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

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

* [RFC PATCH 2/7] ALSA: ac97: add an ac97 bus
@ 2016-05-03 16:29     ` Mark Brown
  0 siblings, 0 replies; 74+ messages in thread
From: Mark Brown @ 2016-05-03 16:29 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Apr 30, 2016 at 11:15:34PM +0200, Robert Jarzmik wrote:
> AC97 is a bus for sound usage. It enables for a AC97 AC-Link to link one
> controller to 0 to 4 AC97 codecs.

> The goal of this new implementation is to implement a device/driver
> model for AC97, with an automatic scan of the bus and automatic
> discovery of AC97 codec devices.

I think this is basically what I was thinking of, yes.  One thing we'll
need to do is work out how to handle systems that need some explicit
action to start clocks for the bus clock, though they were never very
common and it's entirely possible nobody cares any more so perhaps we
just punt and see if anyone notices for now.

> +int ac97_digital_controller_register(const struct ac97_controller_ops *ops,
> +				     struct device *dev);
> +int ac97_digital_controller_unregister(const struct device *dev);

Why "digital"? 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20160503/22fb87c5/attachment.sig>

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

* Re: [RFC PATCH 1/7] ALSA: ac97: split out the generic ac97 registers
  2016-05-03 11:51     ` Mark Brown
  (?)
@ 2016-05-03 19:22       ` Robert Jarzmik
  -1 siblings, 0 replies; 74+ messages in thread
From: Robert Jarzmik @ 2016-05-03 19:22 UTC (permalink / raw)
  To: Mark Brown
  Cc: Daniel Mack, Haojian Zhuang, Jaroslav Kysela, Takashi Iwai,
	Liam Girdwood, linux-arm-kernel, linux-kernel, alsa-devel,
	patches

Mark Brown <broonie@kernel.org> writes:

> On Sat, Apr 30, 2016 at 11:15:33PM +0200, Robert Jarzmik wrote:
>> Split out from the ac97_codec.h the ac97 generic registers, which can be
>> used by a codec, typically a generic ac97 codec, and by the ac97 bus, to
>> scan an ac97 AC-Link.
>
> I don't entirely see the value in this one but equally it does no harm.
Oh that's to have the defines AC97_VENDOR_ID1 and AC97_VENDOR_ID2, but without
including ac97_codec.h in sound/ac97/bus.c.

Cheers.

-- 
Robert

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

* Re: [RFC PATCH 1/7] ALSA: ac97: split out the generic ac97 registers
@ 2016-05-03 19:22       ` Robert Jarzmik
  0 siblings, 0 replies; 74+ messages in thread
From: Robert Jarzmik @ 2016-05-03 19:22 UTC (permalink / raw)
  To: Mark Brown
  Cc: alsa-devel, linux-kernel, patches, Liam Girdwood, Haojian Zhuang,
	Takashi Iwai, Daniel Mack, Jaroslav Kysela, linux-arm-kernel

Mark Brown <broonie@kernel.org> writes:

> On Sat, Apr 30, 2016 at 11:15:33PM +0200, Robert Jarzmik wrote:
>> Split out from the ac97_codec.h the ac97 generic registers, which can be
>> used by a codec, typically a generic ac97 codec, and by the ac97 bus, to
>> scan an ac97 AC-Link.
>
> I don't entirely see the value in this one but equally it does no harm.
Oh that's to have the defines AC97_VENDOR_ID1 and AC97_VENDOR_ID2, but without
including ac97_codec.h in sound/ac97/bus.c.

Cheers.

-- 
Robert

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

* [RFC PATCH 1/7] ALSA: ac97: split out the generic ac97 registers
@ 2016-05-03 19:22       ` Robert Jarzmik
  0 siblings, 0 replies; 74+ messages in thread
From: Robert Jarzmik @ 2016-05-03 19:22 UTC (permalink / raw)
  To: linux-arm-kernel

Mark Brown <broonie@kernel.org> writes:

> On Sat, Apr 30, 2016 at 11:15:33PM +0200, Robert Jarzmik wrote:
>> Split out from the ac97_codec.h the ac97 generic registers, which can be
>> used by a codec, typically a generic ac97 codec, and by the ac97 bus, to
>> scan an ac97 AC-Link.
>
> I don't entirely see the value in this one but equally it does no harm.
Oh that's to have the defines AC97_VENDOR_ID1 and AC97_VENDOR_ID2, but without
including ac97_codec.h in sound/ac97/bus.c.

Cheers.

-- 
Robert

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

* Re: [RFC PATCH 2/7] ALSA: ac97: add an ac97 bus
  2016-05-03 16:29     ` Mark Brown
@ 2016-05-03 19:43       ` Robert Jarzmik
  -1 siblings, 0 replies; 74+ messages in thread
From: Robert Jarzmik @ 2016-05-03 19:43 UTC (permalink / raw)
  To: Mark Brown
  Cc: Daniel Mack, Haojian Zhuang, Jaroslav Kysela, Takashi Iwai,
	Liam Girdwood, linux-arm-kernel, linux-kernel, alsa-devel,
	patches

Mark Brown <broonie@kernel.org> writes:

> On Sat, Apr 30, 2016 at 11:15:34PM +0200, Robert Jarzmik wrote:
>> AC97 is a bus for sound usage. It enables for a AC97 AC-Link to link one
>> controller to 0 to 4 AC97 codecs.
>
>> The goal of this new implementation is to implement a device/driver
>> model for AC97, with an automatic scan of the bus and automatic
>> discovery of AC97 codec devices.
>
> I think this is basically what I was thinking of, yes.  One thing we'll
> need to do is work out how to handle systems that need some explicit
> action to start clocks for the bus clock, though they were never very
> common and it's entirely possible nobody cares any more so perhaps we
> just punt and see if anyone notices for now.
You probably mean the BITCLK clock.

What is a bit pesky about this clock is that it can either be mastered by
digital controller and the codec is a slave, or the other way around.

So we had either the BITCLK provided by :
 - the controller
   => this could be passed in ac97_digital_controller_register()
 - the codec
   => this is trouble, I don't really know how to handle this case

If the bus code has this clock, it can indeed prepare and enable it.

>> +int ac97_digital_controller_register(const struct ac97_controller_ops *ops,
>> +				     struct device *dev);
>> +int ac97_digital_controller_unregister(const struct device *dev);
>
> Why "digital"?
I copy-pasted this from Audio Codec '97 Revision 2.3, where in several places
they call the controller a "digital controller".

Quoting chapter 1.4:
    The digital link that connects the AC ‘97 Digital Controller to the AC ‘97
    Codec, referred to as AC-link, is a bi- directional, 5-wire, serial time
    domain multiplexed (TDM) format interface. AC-link supports connections
    between a single Controller and up to 4 CODECs on a circuit board and/or
    riser card.

Now if you prefer "ac97_controller" or something like that, that's as you wish,
the name does not matter that much to me ;)

Cheers.

-- 
Robert

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

* [RFC PATCH 2/7] ALSA: ac97: add an ac97 bus
@ 2016-05-03 19:43       ` Robert Jarzmik
  0 siblings, 0 replies; 74+ messages in thread
From: Robert Jarzmik @ 2016-05-03 19:43 UTC (permalink / raw)
  To: linux-arm-kernel

Mark Brown <broonie@kernel.org> writes:

> On Sat, Apr 30, 2016 at 11:15:34PM +0200, Robert Jarzmik wrote:
>> AC97 is a bus for sound usage. It enables for a AC97 AC-Link to link one
>> controller to 0 to 4 AC97 codecs.
>
>> The goal of this new implementation is to implement a device/driver
>> model for AC97, with an automatic scan of the bus and automatic
>> discovery of AC97 codec devices.
>
> I think this is basically what I was thinking of, yes.  One thing we'll
> need to do is work out how to handle systems that need some explicit
> action to start clocks for the bus clock, though they were never very
> common and it's entirely possible nobody cares any more so perhaps we
> just punt and see if anyone notices for now.
You probably mean the BITCLK clock.

What is a bit pesky about this clock is that it can either be mastered by
digital controller and the codec is a slave, or the other way around.

So we had either the BITCLK provided by :
 - the controller
   => this could be passed in ac97_digital_controller_register()
 - the codec
   => this is trouble, I don't really know how to handle this case

If the bus code has this clock, it can indeed prepare and enable it.

>> +int ac97_digital_controller_register(const struct ac97_controller_ops *ops,
>> +				     struct device *dev);
>> +int ac97_digital_controller_unregister(const struct device *dev);
>
> Why "digital"?
I copy-pasted this from Audio Codec '97 Revision 2.3, where in several places
they call the controller a "digital controller".

Quoting chapter 1.4:
    The digital link that connects the AC ?97 Digital Controller to the AC ?97
    Codec, referred to as AC-link, is a bi- directional, 5-wire, serial time
    domain multiplexed (TDM) format interface. AC-link supports connections
    between a single Controller and up to 4 CODECs on a circuit board and/or
    riser card.

Now if you prefer "ac97_controller" or something like that, that's as you wish,
the name does not matter that much to me ;)

Cheers.

-- 
Robert

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

* Re: [RFC PATCH 1/7] ALSA: ac97: split out the generic ac97 registers
  2016-05-03 19:22       ` Robert Jarzmik
@ 2016-05-04  9:07         ` Mark Brown
  -1 siblings, 0 replies; 74+ messages in thread
From: Mark Brown @ 2016-05-04  9:07 UTC (permalink / raw)
  To: Robert Jarzmik
  Cc: Daniel Mack, Haojian Zhuang, Jaroslav Kysela, Takashi Iwai,
	Liam Girdwood, linux-arm-kernel, linux-kernel, alsa-devel,
	patches

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

On Tue, May 03, 2016 at 09:22:05PM +0200, Robert Jarzmik wrote:
> Mark Brown <broonie@kernel.org> writes:

> > On Sat, Apr 30, 2016 at 11:15:33PM +0200, Robert Jarzmik wrote:

> >> Split out from the ac97_codec.h the ac97 generic registers, which can be
> >> used by a codec, typically a generic ac97 codec, and by the ac97 bus, to
> >> scan an ac97 AC-Link.

> > I don't entirely see the value in this one but equally it does no harm.

> Oh that's to have the defines AC97_VENDOR_ID1 and AC97_VENDOR_ID2, but without
> including ac97_codec.h in sound/ac97/bus.c.

I see that, I just don't know why that helps.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

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

* [RFC PATCH 1/7] ALSA: ac97: split out the generic ac97 registers
@ 2016-05-04  9:07         ` Mark Brown
  0 siblings, 0 replies; 74+ messages in thread
From: Mark Brown @ 2016-05-04  9:07 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, May 03, 2016 at 09:22:05PM +0200, Robert Jarzmik wrote:
> Mark Brown <broonie@kernel.org> writes:

> > On Sat, Apr 30, 2016 at 11:15:33PM +0200, Robert Jarzmik wrote:

> >> Split out from the ac97_codec.h the ac97 generic registers, which can be
> >> used by a codec, typically a generic ac97 codec, and by the ac97 bus, to
> >> scan an ac97 AC-Link.

> > I don't entirely see the value in this one but equally it does no harm.

> Oh that's to have the defines AC97_VENDOR_ID1 and AC97_VENDOR_ID2, but without
> including ac97_codec.h in sound/ac97/bus.c.

I see that, I just don't know why that helps.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20160504/dd7af245/attachment.sig>

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

* Re: [RFC PATCH 2/7] ALSA: ac97: add an ac97 bus
  2016-05-03 19:43       ` Robert Jarzmik
@ 2016-05-04 16:22         ` Mark Brown
  -1 siblings, 0 replies; 74+ messages in thread
From: Mark Brown @ 2016-05-04 16:22 UTC (permalink / raw)
  To: Robert Jarzmik
  Cc: Daniel Mack, Haojian Zhuang, Jaroslav Kysela, Takashi Iwai,
	Liam Girdwood, linux-arm-kernel, linux-kernel, alsa-devel,
	patches

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

On Tue, May 03, 2016 at 09:43:20PM +0200, Robert Jarzmik wrote:

> You probably mean the BITCLK clock.

> What is a bit pesky about this clock is that it can either be mastered by
> digital controller and the codec is a slave, or the other way around.

That's a bit surprising - I've never encountered a system that
impelemnts this, it may be permitted by the spec but it's always the
CODEC.  The master clock from the CODEC is often provided by the SoC but
I've not seen systems where anything other than the CODEC drives the
actual AC'97 bus.

> >> +int ac97_digital_controller_register(const struct ac97_controller_ops *ops,
> >> +				     struct device *dev);
> >> +int ac97_digital_controller_unregister(const struct device *dev);

> > Why "digital"?

> I copy-pasted this from Audio Codec '97 Revision 2.3, where in several places
> they call the controller a "digital controller".

It's not really adding anything though, it's just clumsy wording on
their part - it's not like we need to distinguish this from analogue
or any other type of AC'97 controllers.

> Now if you prefer "ac97_controller" or something like that, that's as you wish,
> the name does not matter that much to me ;)

Yes.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

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

* [RFC PATCH 2/7] ALSA: ac97: add an ac97 bus
@ 2016-05-04 16:22         ` Mark Brown
  0 siblings, 0 replies; 74+ messages in thread
From: Mark Brown @ 2016-05-04 16:22 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, May 03, 2016 at 09:43:20PM +0200, Robert Jarzmik wrote:

> You probably mean the BITCLK clock.

> What is a bit pesky about this clock is that it can either be mastered by
> digital controller and the codec is a slave, or the other way around.

That's a bit surprising - I've never encountered a system that
impelemnts this, it may be permitted by the spec but it's always the
CODEC.  The master clock from the CODEC is often provided by the SoC but
I've not seen systems where anything other than the CODEC drives the
actual AC'97 bus.

> >> +int ac97_digital_controller_register(const struct ac97_controller_ops *ops,
> >> +				     struct device *dev);
> >> +int ac97_digital_controller_unregister(const struct device *dev);

> > Why "digital"?

> I copy-pasted this from Audio Codec '97 Revision 2.3, where in several places
> they call the controller a "digital controller".

It's not really adding anything though, it's just clumsy wording on
their part - it's not like we need to distinguish this from analogue
or any other type of AC'97 controllers.

> Now if you prefer "ac97_controller" or something like that, that's as you wish,
> the name does not matter that much to me ;)

Yes.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20160504/59b0edd1/attachment-0001.sig>

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

* Re: [RFC PATCH 1/7] ALSA: ac97: split out the generic ac97 registers
  2016-05-04  9:07         ` Mark Brown
  (?)
@ 2016-05-05 19:06           ` Robert Jarzmik
  -1 siblings, 0 replies; 74+ messages in thread
From: Robert Jarzmik @ 2016-05-05 19:06 UTC (permalink / raw)
  To: Mark Brown
  Cc: Daniel Mack, Haojian Zhuang, Jaroslav Kysela, Takashi Iwai,
	Liam Girdwood, linux-arm-kernel, linux-kernel, alsa-devel,
	patches

Mark Brown <broonie@kernel.org> writes:

> On Tue, May 03, 2016 at 09:22:05PM +0200, Robert Jarzmik wrote:
>> Mark Brown <broonie@kernel.org> writes:
>
>> > On Sat, Apr 30, 2016 at 11:15:33PM +0200, Robert Jarzmik wrote:
>
>> >> Split out from the ac97_codec.h the ac97 generic registers, which can be
>> >> used by a codec, typically a generic ac97 codec, and by the ac97 bus, to
>> >> scan an ac97 AC-Link.
>
>> > I don't entirely see the value in this one but equally it does no harm.
>
>> Oh that's to have the defines AC97_VENDOR_ID1 and AC97_VENDOR_ID2, but without
>> including ac97_codec.h in sound/ac97/bus.c.
>
> I see that, I just don't know why that helps.
Ok, so let me explain.

As you already understood, AC97_VENDOR* is needed in bus.c for the
autoscanning. The remaining is the reason why I don't want to include
ac97_codec.h in bus.c, which follows.

In order to have a clean split between former ac97 bus implementation and this
new one, I didn't want to include any former ac97 includes, excepting in
sound/ac97/compat.c.

Amongst the thing I wanted to isolate :
 - didn't want the struct snd_ac97 in sound/ac97/* (except compat.c) to see not
   be "fooled" by a definition which would come with ac97_codec.h by "chance".
 - didn't want to have snd_a97_*() functions, as they rely on struct snd_ac97.
 - didn't want the struct snd_ac97_bus_ops, there is a new one
   => the main grudge I have is the void (*write)() and unsigned short (*read)()
   prototype which prevent from returning error codes such as -EIO, etc ...

Moreover, to have a smooth transition, my plan is :
 - have this new ac97 bus
 - provide any needed function in compat.c so that previous codecs, regmap,
   ... continue to work
 - port the ac97 "pci" codec to have a generic ac97 codec so that codecs can be
   shrinked from common ac97 code.
 - port the codecs ... several monthes of work, etc ...
 - once the port is done, remove compat.c

This transition will be easier if the new ac97 code is isolated as much as
possible from the former code while providing backward compatibility ... hence
this patch.

Cheers.

-- 
Robert

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

* Re: [RFC PATCH 1/7] ALSA: ac97: split out the generic ac97 registers
@ 2016-05-05 19:06           ` Robert Jarzmik
  0 siblings, 0 replies; 74+ messages in thread
From: Robert Jarzmik @ 2016-05-05 19:06 UTC (permalink / raw)
  To: Mark Brown
  Cc: alsa-devel, linux-kernel, patches, Liam Girdwood, Haojian Zhuang,
	Takashi Iwai, Daniel Mack, linux-arm-kernel

Mark Brown <broonie@kernel.org> writes:

> On Tue, May 03, 2016 at 09:22:05PM +0200, Robert Jarzmik wrote:
>> Mark Brown <broonie@kernel.org> writes:
>
>> > On Sat, Apr 30, 2016 at 11:15:33PM +0200, Robert Jarzmik wrote:
>
>> >> Split out from the ac97_codec.h the ac97 generic registers, which can be
>> >> used by a codec, typically a generic ac97 codec, and by the ac97 bus, to
>> >> scan an ac97 AC-Link.
>
>> > I don't entirely see the value in this one but equally it does no harm.
>
>> Oh that's to have the defines AC97_VENDOR_ID1 and AC97_VENDOR_ID2, but without
>> including ac97_codec.h in sound/ac97/bus.c.
>
> I see that, I just don't know why that helps.
Ok, so let me explain.

As you already understood, AC97_VENDOR* is needed in bus.c for the
autoscanning. The remaining is the reason why I don't want to include
ac97_codec.h in bus.c, which follows.

In order to have a clean split between former ac97 bus implementation and this
new one, I didn't want to include any former ac97 includes, excepting in
sound/ac97/compat.c.

Amongst the thing I wanted to isolate :
 - didn't want the struct snd_ac97 in sound/ac97/* (except compat.c) to see not
   be "fooled" by a definition which would come with ac97_codec.h by "chance".
 - didn't want to have snd_a97_*() functions, as they rely on struct snd_ac97.
 - didn't want the struct snd_ac97_bus_ops, there is a new one
   => the main grudge I have is the void (*write)() and unsigned short (*read)()
   prototype which prevent from returning error codes such as -EIO, etc ...

Moreover, to have a smooth transition, my plan is :
 - have this new ac97 bus
 - provide any needed function in compat.c so that previous codecs, regmap,
   ... continue to work
 - port the ac97 "pci" codec to have a generic ac97 codec so that codecs can be
   shrinked from common ac97 code.
 - port the codecs ... several monthes of work, etc ...
 - once the port is done, remove compat.c

This transition will be easier if the new ac97 code is isolated as much as
possible from the former code while providing backward compatibility ... hence
this patch.

Cheers.

-- 
Robert

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

* [RFC PATCH 1/7] ALSA: ac97: split out the generic ac97 registers
@ 2016-05-05 19:06           ` Robert Jarzmik
  0 siblings, 0 replies; 74+ messages in thread
From: Robert Jarzmik @ 2016-05-05 19:06 UTC (permalink / raw)
  To: linux-arm-kernel

Mark Brown <broonie@kernel.org> writes:

> On Tue, May 03, 2016 at 09:22:05PM +0200, Robert Jarzmik wrote:
>> Mark Brown <broonie@kernel.org> writes:
>
>> > On Sat, Apr 30, 2016 at 11:15:33PM +0200, Robert Jarzmik wrote:
>
>> >> Split out from the ac97_codec.h the ac97 generic registers, which can be
>> >> used by a codec, typically a generic ac97 codec, and by the ac97 bus, to
>> >> scan an ac97 AC-Link.
>
>> > I don't entirely see the value in this one but equally it does no harm.
>
>> Oh that's to have the defines AC97_VENDOR_ID1 and AC97_VENDOR_ID2, but without
>> including ac97_codec.h in sound/ac97/bus.c.
>
> I see that, I just don't know why that helps.
Ok, so let me explain.

As you already understood, AC97_VENDOR* is needed in bus.c for the
autoscanning. The remaining is the reason why I don't want to include
ac97_codec.h in bus.c, which follows.

In order to have a clean split between former ac97 bus implementation and this
new one, I didn't want to include any former ac97 includes, excepting in
sound/ac97/compat.c.

Amongst the thing I wanted to isolate :
 - didn't want the struct snd_ac97 in sound/ac97/* (except compat.c) to see not
   be "fooled" by a definition which would come with ac97_codec.h by "chance".
 - didn't want to have snd_a97_*() functions, as they rely on struct snd_ac97.
 - didn't want the struct snd_ac97_bus_ops, there is a new one
   => the main grudge I have is the void (*write)() and unsigned short (*read)()
   prototype which prevent from returning error codes such as -EIO, etc ...

Moreover, to have a smooth transition, my plan is :
 - have this new ac97 bus
 - provide any needed function in compat.c so that previous codecs, regmap,
   ... continue to work
 - port the ac97 "pci" codec to have a generic ac97 codec so that codecs can be
   shrinked from common ac97 code.
 - port the codecs ... several monthes of work, etc ...
 - once the port is done, remove compat.c

This transition will be easier if the new ac97 code is isolated as much as
possible from the former code while providing backward compatibility ... hence
this patch.

Cheers.

-- 
Robert

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

* Re: [RFC PATCH 2/7] ALSA: ac97: add an ac97 bus
  2016-05-04 16:22         ` Mark Brown
@ 2016-05-05 19:14           ` Robert Jarzmik
  -1 siblings, 0 replies; 74+ messages in thread
From: Robert Jarzmik @ 2016-05-05 19:14 UTC (permalink / raw)
  To: Mark Brown
  Cc: Daniel Mack, Haojian Zhuang, Jaroslav Kysela, Takashi Iwai,
	Liam Girdwood, linux-arm-kernel, linux-kernel, alsa-devel,
	patches

Mark Brown <broonie@kernel.org> writes:

> On Tue, May 03, 2016 at 09:43:20PM +0200, Robert Jarzmik wrote:
>
>> You probably mean the BITCLK clock.
>
>> What is a bit pesky about this clock is that it can either be mastered by
>> digital controller and the codec is a slave, or the other way around.
>
> That's a bit surprising - I've never encountered a system that
> impelemnts this, it may be permitted by the spec but it's always the
> CODEC.  The master clock from the CODEC is often provided by the SoC but
> I've not seen systems where anything other than the CODEC drives the
> actual AC'97 bus.

Ok, so let's assume a one direction. I'll have a look how I could add this clock
to the probe() exactly as amba_probe() does.

> It's not really adding anything though, it's just clumsy wording on
> their part - it's not like we need to distinguish this from analogue
> or any other type of AC'97 controllers.
>
>> Now if you prefer "ac97_controller" or something like that, that's as you wish,
>> the name does not matter that much to me ;)
>
> Yes.
Okay, let me add this to my todo list for v2.
I already have suspend/resume/pm_suspend/pm_resume.

Cheers.

-- 
Robert

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

* [RFC PATCH 2/7] ALSA: ac97: add an ac97 bus
@ 2016-05-05 19:14           ` Robert Jarzmik
  0 siblings, 0 replies; 74+ messages in thread
From: Robert Jarzmik @ 2016-05-05 19:14 UTC (permalink / raw)
  To: linux-arm-kernel

Mark Brown <broonie@kernel.org> writes:

> On Tue, May 03, 2016 at 09:43:20PM +0200, Robert Jarzmik wrote:
>
>> You probably mean the BITCLK clock.
>
>> What is a bit pesky about this clock is that it can either be mastered by
>> digital controller and the codec is a slave, or the other way around.
>
> That's a bit surprising - I've never encountered a system that
> impelemnts this, it may be permitted by the spec but it's always the
> CODEC.  The master clock from the CODEC is often provided by the SoC but
> I've not seen systems where anything other than the CODEC drives the
> actual AC'97 bus.

Ok, so let's assume a one direction. I'll have a look how I could add this clock
to the probe() exactly as amba_probe() does.

> It's not really adding anything though, it's just clumsy wording on
> their part - it's not like we need to distinguish this from analogue
> or any other type of AC'97 controllers.
>
>> Now if you prefer "ac97_controller" or something like that, that's as you wish,
>> the name does not matter that much to me ;)
>
> Yes.
Okay, let me add this to my todo list for v2.
I already have suspend/resume/pm_suspend/pm_resume.

Cheers.

-- 
Robert

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

* Re: [RFC PATCH 1/7] ALSA: ac97: split out the generic ac97 registers
  2016-05-05 19:06           ` Robert Jarzmik
@ 2016-05-05 19:17             ` Mark Brown
  -1 siblings, 0 replies; 74+ messages in thread
From: Mark Brown @ 2016-05-05 19:17 UTC (permalink / raw)
  To: Robert Jarzmik
  Cc: Daniel Mack, Haojian Zhuang, Jaroslav Kysela, Takashi Iwai,
	Liam Girdwood, linux-arm-kernel, linux-kernel, alsa-devel,
	patches

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

On Thu, May 05, 2016 at 09:06:44PM +0200, Robert Jarzmik wrote:
> Mark Brown <broonie@kernel.org> writes:

> > I see that, I just don't know why that helps.

> Ok, so let me explain.

> As you already understood, AC97_VENDOR* is needed in bus.c for the
> autoscanning. The remaining is the reason why I don't want to include
> ac97_codec.h in bus.c, which follows.

> In order to have a clean split between former ac97 bus implementation and this
> new one, I didn't want to include any former ac97 includes, excepting in
> sound/ac97/compat.c.

It's probably a good idea to articulate some of this in the commit log
then!

> This transition will be easier if the new ac97 code is isolated as much as
> possible from the former code while providing backward compatibility ... hence
> this patch.

It'd probably have been clearer to me if it were splitting out all the
register definitions rather than just some of them.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

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

* [RFC PATCH 1/7] ALSA: ac97: split out the generic ac97 registers
@ 2016-05-05 19:17             ` Mark Brown
  0 siblings, 0 replies; 74+ messages in thread
From: Mark Brown @ 2016-05-05 19:17 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, May 05, 2016 at 09:06:44PM +0200, Robert Jarzmik wrote:
> Mark Brown <broonie@kernel.org> writes:

> > I see that, I just don't know why that helps.

> Ok, so let me explain.

> As you already understood, AC97_VENDOR* is needed in bus.c for the
> autoscanning. The remaining is the reason why I don't want to include
> ac97_codec.h in bus.c, which follows.

> In order to have a clean split between former ac97 bus implementation and this
> new one, I didn't want to include any former ac97 includes, excepting in
> sound/ac97/compat.c.

It's probably a good idea to articulate some of this in the commit log
then!

> This transition will be easier if the new ac97 code is isolated as much as
> possible from the former code while providing backward compatibility ... hence
> this patch.

It'd probably have been clearer to me if it were splitting out all the
register definitions rather than just some of them.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20160505/2dd6048c/attachment.sig>

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

* Re: [RFC PATCH 1/7] ALSA: ac97: split out the generic ac97 registers
  2016-05-05 19:17             ` Mark Brown
@ 2016-05-05 19:46               ` Robert Jarzmik
  -1 siblings, 0 replies; 74+ messages in thread
From: Robert Jarzmik @ 2016-05-05 19:46 UTC (permalink / raw)
  To: Mark Brown
  Cc: Daniel Mack, Haojian Zhuang, Jaroslav Kysela, Takashi Iwai,
	Liam Girdwood, linux-arm-kernel, linux-kernel, alsa-devel,
	patches

Mark Brown <broonie@kernel.org> writes:

> On Thu, May 05, 2016 at 09:06:44PM +0200, Robert Jarzmik wrote:
>> Mark Brown <broonie@kernel.org> writes:
>
>> > I see that, I just don't know why that helps.
>> In order to have a clean split between former ac97 bus implementation and this
>> new one, I didn't want to include any former ac97 includes, excepting in
>> sound/ac97/compat.c.
>
> It's probably a good idea to articulate some of this in the commit log
> then!
Fair point, I'll improve that.

>> This transition will be easier if the new ac97 code is isolated as much as
>> possible from the former code while providing backward compatibility ... hence
>> this patch.
>
> It'd probably have been clearer to me if it were splitting out all the
> register definitions rather than just some of them.
Euh unless I'm missing something I have splitted out all the ac97 generic
registers AFAIK. The only remaining ones are chip specific which I didn't take
as they should be in codec specific code and not ac97 generic one.

Cheers.

-- 
Robert

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

* [RFC PATCH 1/7] ALSA: ac97: split out the generic ac97 registers
@ 2016-05-05 19:46               ` Robert Jarzmik
  0 siblings, 0 replies; 74+ messages in thread
From: Robert Jarzmik @ 2016-05-05 19:46 UTC (permalink / raw)
  To: linux-arm-kernel

Mark Brown <broonie@kernel.org> writes:

> On Thu, May 05, 2016 at 09:06:44PM +0200, Robert Jarzmik wrote:
>> Mark Brown <broonie@kernel.org> writes:
>
>> > I see that, I just don't know why that helps.
>> In order to have a clean split between former ac97 bus implementation and this
>> new one, I didn't want to include any former ac97 includes, excepting in
>> sound/ac97/compat.c.
>
> It's probably a good idea to articulate some of this in the commit log
> then!
Fair point, I'll improve that.

>> This transition will be easier if the new ac97 code is isolated as much as
>> possible from the former code while providing backward compatibility ... hence
>> this patch.
>
> It'd probably have been clearer to me if it were splitting out all the
> register definitions rather than just some of them.
Euh unless I'm missing something I have splitted out all the ac97 generic
registers AFAIK. The only remaining ones are chip specific which I didn't take
as they should be in codec specific code and not ac97 generic one.

Cheers.

-- 
Robert

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

* Re: [RFC PATCH 1/7] ALSA: ac97: split out the generic ac97 registers
  2016-05-05 19:46               ` Robert Jarzmik
@ 2016-05-06 17:17                 ` Mark Brown
  -1 siblings, 0 replies; 74+ messages in thread
From: Mark Brown @ 2016-05-06 17:17 UTC (permalink / raw)
  To: Robert Jarzmik
  Cc: Daniel Mack, Haojian Zhuang, Jaroslav Kysela, Takashi Iwai,
	Liam Girdwood, linux-arm-kernel, linux-kernel, alsa-devel,
	patches

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

On Thu, May 05, 2016 at 09:46:10PM +0200, Robert Jarzmik wrote:
> Mark Brown <broonie@kernel.org> writes:
> > On Thu, May 05, 2016 at 09:06:44PM +0200, Robert Jarzmik wrote:
> >> Mark Brown <broonie@kernel.org> writes:

> >> This transition will be easier if the new ac97 code is isolated as much as
> >> possible from the former code while providing backward compatibility ... hence
> >> this patch.

> > It'd probably have been clearer to me if it were splitting out all the
> > register definitions rather than just some of them.

> Euh unless I'm missing something I have splitted out all the ac97 generic
> registers AFAIK. The only remaining ones are chip specific which I didn't take
> as they should be in codec specific code and not ac97 generic one.

The changelog read like it was trying to split things used by the
controller vs things used by CODEC drivers, I didn't get as far as
checking all the registers TBH.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

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

* [RFC PATCH 1/7] ALSA: ac97: split out the generic ac97 registers
@ 2016-05-06 17:17                 ` Mark Brown
  0 siblings, 0 replies; 74+ messages in thread
From: Mark Brown @ 2016-05-06 17:17 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, May 05, 2016 at 09:46:10PM +0200, Robert Jarzmik wrote:
> Mark Brown <broonie@kernel.org> writes:
> > On Thu, May 05, 2016 at 09:06:44PM +0200, Robert Jarzmik wrote:
> >> Mark Brown <broonie@kernel.org> writes:

> >> This transition will be easier if the new ac97 code is isolated as much as
> >> possible from the former code while providing backward compatibility ... hence
> >> this patch.

> > It'd probably have been clearer to me if it were splitting out all the
> > register definitions rather than just some of them.

> Euh unless I'm missing something I have splitted out all the ac97 generic
> registers AFAIK. The only remaining ones are chip specific which I didn't take
> as they should be in codec specific code and not ac97 generic one.

The changelog read like it was trying to split things used by the
controller vs things used by CODEC drivers, I didn't get as far as
checking all the registers TBH.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20160506/e5df7443/attachment.sig>

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

* Re: [RFC PATCH 0/7] AC97 device/driver model revamp
  2016-04-30 21:15 ` Robert Jarzmik
  (?)
@ 2016-05-09  9:04   ` Takashi Iwai
  -1 siblings, 0 replies; 74+ messages in thread
From: Takashi Iwai @ 2016-05-09  9:04 UTC (permalink / raw)
  To: Robert Jarzmik
  Cc: Haojian Zhuang, Liam Girdwood, Mark Brown, Jaroslav Kysela,
	Daniel Mack, alsa-devel, linux-arm-kernel, patches, linux-kernel

On Sat, 30 Apr 2016 23:15:32 +0200,
Robert Jarzmik wrote:
> 
> It all started in the pxa device-tree submission here :
>    https://lkml.org/lkml/2016/2/25/965
> It will be maintained in :
>    git fetch https://github.com/rjarzmik/linux.git work/ac97
> 
> And now it transformed into this RFC, which would bring a ground for AC'97
> devices closer to the linux device/driver model.
> 
> This is just an RFC to see if we understand each other Mark.
> 
> Amongst the driving ideas behind this RFC :
>  - use device/driver model for AC'97
>    device/driver binding is based on vendor_id{1,2}
>  - use auto-probe of the AC'97 bus to enumerate codecs and create devices
>  - be compatible with previous platform_data model for codecs
>    => this enables a smooth transition, where a codec (here wm9713) can
>       be used either through platform_device or automatic discovery
>  - struct snd_ac97 is not used
>    This structure is really heavy, and doesn't represent an AC97 device, but
>    rather an AC'97 codec internals IIUC.
>    I think it's right place would be in include/sound/ac97/codec.h.
>    This is also a problem for regmap adherence, hence the
>    include/sound/ac97/compat.h.
>  - a new AC'97 bus Kconfig is created
>    This was done for a smooth transition ... let's see if it's a good idea.
>  - split the AC'97 into :
>    - the codec
>    - the digital controller
>    - the bus
> 
> Amongst the things that are not all touched yet :
>  - ac97_codec.c
>    The generic AC'97 codec in sound/pci/ac97/ac97_codec.c has really a lot
>    features, which are not at all PCI related. They could be transfered to
>    sound/ac97, without the pci specific field.
>    => this deserves a deep ahead thinking, which I'll do if the current approach
>    is accepted by the communauty.
> 
> The most important patch is 2/7 "ALSA: ac97: add an ac97 bus". This is the main
> evaluation point for the serie, the others are here so that I can test it all.
> 
> Well, this is a long term effort, which might need a complete rewrite according
> to the comments it'll get. Let's expose it for comments and see how I can
> progress with it.

I think it's good in general.  The implementation looks fairly simple
and thin enough.

An open question is whether migrating the former AC97 layer into the
new bus.  I'm not sure about this.  Transition to a new layer always
brings subtle bugs, especially when the target devices are in wide
range of legacy ones...   If any, we should start just wrapping via
the new bus ops.

Some other nitpicks:
- We usually use snd_ prefix for sound stuff.  Better to keep this for
  exported symbols at least.

- I don't see much value in the usefulness of compat_* stuff.
  For example, it doesn't cover the actual reset procedure or such
  done as in the old ac97 code.  So it won't work compatibly.  If it's
  a few lines of changes, the direct call would be likely simpler in
  the end.

- The order of patches needs reconsideration.  The current patchset
  will break the build, as the hook to sound/ac97/* is done in the
  last patch, while you're already building against to the new stuff
  beforehand.


I'll comment more on each patch if any...


thanks,

Takashi

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

* Re: [RFC PATCH 0/7] AC97 device/driver model revamp
@ 2016-05-09  9:04   ` Takashi Iwai
  0 siblings, 0 replies; 74+ messages in thread
From: Takashi Iwai @ 2016-05-09  9:04 UTC (permalink / raw)
  To: Robert Jarzmik
  Cc: alsa-devel, linux-kernel, patches, Liam Girdwood, Haojian Zhuang,
	Jaroslav Kysela, Mark Brown, linux-arm-kernel, Daniel Mack

On Sat, 30 Apr 2016 23:15:32 +0200,
Robert Jarzmik wrote:
> 
> It all started in the pxa device-tree submission here :
>    https://lkml.org/lkml/2016/2/25/965
> It will be maintained in :
>    git fetch https://github.com/rjarzmik/linux.git work/ac97
> 
> And now it transformed into this RFC, which would bring a ground for AC'97
> devices closer to the linux device/driver model.
> 
> This is just an RFC to see if we understand each other Mark.
> 
> Amongst the driving ideas behind this RFC :
>  - use device/driver model for AC'97
>    device/driver binding is based on vendor_id{1,2}
>  - use auto-probe of the AC'97 bus to enumerate codecs and create devices
>  - be compatible with previous platform_data model for codecs
>    => this enables a smooth transition, where a codec (here wm9713) can
>       be used either through platform_device or automatic discovery
>  - struct snd_ac97 is not used
>    This structure is really heavy, and doesn't represent an AC97 device, but
>    rather an AC'97 codec internals IIUC.
>    I think it's right place would be in include/sound/ac97/codec.h.
>    This is also a problem for regmap adherence, hence the
>    include/sound/ac97/compat.h.
>  - a new AC'97 bus Kconfig is created
>    This was done for a smooth transition ... let's see if it's a good idea.
>  - split the AC'97 into :
>    - the codec
>    - the digital controller
>    - the bus
> 
> Amongst the things that are not all touched yet :
>  - ac97_codec.c
>    The generic AC'97 codec in sound/pci/ac97/ac97_codec.c has really a lot
>    features, which are not at all PCI related. They could be transfered to
>    sound/ac97, without the pci specific field.
>    => this deserves a deep ahead thinking, which I'll do if the current approach
>    is accepted by the communauty.
> 
> The most important patch is 2/7 "ALSA: ac97: add an ac97 bus". This is the main
> evaluation point for the serie, the others are here so that I can test it all.
> 
> Well, this is a long term effort, which might need a complete rewrite according
> to the comments it'll get. Let's expose it for comments and see how I can
> progress with it.

I think it's good in general.  The implementation looks fairly simple
and thin enough.

An open question is whether migrating the former AC97 layer into the
new bus.  I'm not sure about this.  Transition to a new layer always
brings subtle bugs, especially when the target devices are in wide
range of legacy ones...   If any, we should start just wrapping via
the new bus ops.

Some other nitpicks:
- We usually use snd_ prefix for sound stuff.  Better to keep this for
  exported symbols at least.

- I don't see much value in the usefulness of compat_* stuff.
  For example, it doesn't cover the actual reset procedure or such
  done as in the old ac97 code.  So it won't work compatibly.  If it's
  a few lines of changes, the direct call would be likely simpler in
  the end.

- The order of patches needs reconsideration.  The current patchset
  will break the build, as the hook to sound/ac97/* is done in the
  last patch, while you're already building against to the new stuff
  beforehand.


I'll comment more on each patch if any...


thanks,

Takashi

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

* [RFC PATCH 0/7] AC97 device/driver model revamp
@ 2016-05-09  9:04   ` Takashi Iwai
  0 siblings, 0 replies; 74+ messages in thread
From: Takashi Iwai @ 2016-05-09  9:04 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, 30 Apr 2016 23:15:32 +0200,
Robert Jarzmik wrote:
> 
> It all started in the pxa device-tree submission here :
>    https://lkml.org/lkml/2016/2/25/965
> It will be maintained in :
>    git fetch https://github.com/rjarzmik/linux.git work/ac97
> 
> And now it transformed into this RFC, which would bring a ground for AC'97
> devices closer to the linux device/driver model.
> 
> This is just an RFC to see if we understand each other Mark.
> 
> Amongst the driving ideas behind this RFC :
>  - use device/driver model for AC'97
>    device/driver binding is based on vendor_id{1,2}
>  - use auto-probe of the AC'97 bus to enumerate codecs and create devices
>  - be compatible with previous platform_data model for codecs
>    => this enables a smooth transition, where a codec (here wm9713) can
>       be used either through platform_device or automatic discovery
>  - struct snd_ac97 is not used
>    This structure is really heavy, and doesn't represent an AC97 device, but
>    rather an AC'97 codec internals IIUC.
>    I think it's right place would be in include/sound/ac97/codec.h.
>    This is also a problem for regmap adherence, hence the
>    include/sound/ac97/compat.h.
>  - a new AC'97 bus Kconfig is created
>    This was done for a smooth transition ... let's see if it's a good idea.
>  - split the AC'97 into :
>    - the codec
>    - the digital controller
>    - the bus
> 
> Amongst the things that are not all touched yet :
>  - ac97_codec.c
>    The generic AC'97 codec in sound/pci/ac97/ac97_codec.c has really a lot
>    features, which are not at all PCI related. They could be transfered to
>    sound/ac97, without the pci specific field.
>    => this deserves a deep ahead thinking, which I'll do if the current approach
>    is accepted by the communauty.
> 
> The most important patch is 2/7 "ALSA: ac97: add an ac97 bus". This is the main
> evaluation point for the serie, the others are here so that I can test it all.
> 
> Well, this is a long term effort, which might need a complete rewrite according
> to the comments it'll get. Let's expose it for comments and see how I can
> progress with it.

I think it's good in general.  The implementation looks fairly simple
and thin enough.

An open question is whether migrating the former AC97 layer into the
new bus.  I'm not sure about this.  Transition to a new layer always
brings subtle bugs, especially when the target devices are in wide
range of legacy ones...   If any, we should start just wrapping via
the new bus ops.

Some other nitpicks:
- We usually use snd_ prefix for sound stuff.  Better to keep this for
  exported symbols at least.

- I don't see much value in the usefulness of compat_* stuff.
  For example, it doesn't cover the actual reset procedure or such
  done as in the old ac97 code.  So it won't work compatibly.  If it's
  a few lines of changes, the direct call would be likely simpler in
  the end.

- The order of patches needs reconsideration.  The current patchset
  will break the build, as the hook to sound/ac97/* is done in the
  last patch, while you're already building against to the new stuff
  beforehand.


I'll comment more on each patch if any...


thanks,

Takashi

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

* Re: [RFC PATCH 2/7] ALSA: ac97: add an ac97 bus
  2016-04-30 21:15   ` Robert Jarzmik
  (?)
@ 2016-05-09  9:31     ` Takashi Iwai
  -1 siblings, 0 replies; 74+ messages in thread
From: Takashi Iwai @ 2016-05-09  9:31 UTC (permalink / raw)
  To: Robert Jarzmik
  Cc: Haojian Zhuang, Liam Girdwood, Mark Brown, Jaroslav Kysela,
	Daniel Mack, alsa-devel, linux-arm-kernel, patches, linux-kernel

On Sat, 30 Apr 2016 23:15:34 +0200,
Robert Jarzmik wrote:
> 
> diff --git a/include/sound/ac97/codec.h b/include/sound/ac97/codec.h
> new file mode 100644
> index 000000000000..4b8b3e570892
> --- /dev/null
> +++ b/include/sound/ac97/codec.h
> @@ -0,0 +1,98 @@
> +/*
> + *  Copyright (C) 2016 Robert Jarzmik <robert.jarzmik@free.fr>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +#ifndef AC97_CODEC_H
> +#define AC97_CODEC_H

Let's be careful about the choice of the guard.


> +
> +#include <linux/device.h>
> +
> +#define AC97_ID(vendor_id1, vendor_id2) \
> +	(((vendor_id1 & 0xffff) << 16) | (vendor_id2 & 0xffff))
> +#define AC97_DRIVER_ID(vendor_id1, vendor_id2, mask_id1, mask_id2, _data) \
> +	{ .id = ((vendor_id1 & 0xffff) << 16) | (vendor_id2 & 0xffff), \
> +	  .mask = ((mask_id1 & 0xffff) << 16) | (mask_id2 & 0xffff), \
> +	  .data = _data }

Give parentheses around the macro arguments.


> +
> +#define to_ac97_device(d) container_of(d, struct ac97_codec_device, dev)
> +#define to_ac97_driver(d) container_of(d, struct ac97_codec_driver, driver)
> +
> +struct ac97_controller;
> +
> +/**
> + * struct ac97_id - matches a codec device and driver on an ac97 bus
> + * @id: The significant bits if the codec vendor ID1 and ID2
> + * @mask: Bitmask specifying which bits of the id field are significant when
> + *	  matching. A driver binds to a device when :
> + *        ((vendorID1 << 8 | vendorID2) & (mask_id1 << 8 | mask_id2)) == id.
> + * @data: Private data used by the driver.
> + */
> +struct ac97_id {
> +	unsigned int		id;
> +	unsigned int		mask;
> +	void			*data;
> +};
> +
> +/**
> + * ac97_codec_device - a ac97 codec
> + * @dev: the code device
> + * @vendor_id: the vendor_id of the codec, as sensed on the AC-link
> + * @num: the codec number, 0 is primary, 1 is first slave, etc ...
> + * @ac97_ctrl: ac97 digital controller on the same AC-link
> + *
> + * This is the device instanciated for each codec living on a AC-link. There are
> + * normally 0 to 4 codec devices per AC-link, and all of them are controlled by
> + * an AC97 digital controller.
> + */
> +struct ac97_codec_device {
> +	struct device		dev;	/* Must stay first member */

This doesn't have to be the first element as long as you use container_of().


> +	unsigned int		vendor_id;
> +	unsigned int		num;
> +	struct list_head	list;
> +	struct ac97_controller	*ac97_ctrl;
> +};
> +
> +/**
> + * ac97_codec_driver - a ac97 codec driver
> + * @driver: the device driver structure
> + * @probe: the function called when a ac97_codec_device is matched
> + * @remove: the function called when the device is unbound/removed
> + * @suspend: suspend function (might be NULL)
> + * @resume: resume function (might be NULL)
> + * @shutdown: shutdown function (might be NULL)
> + * @id_table: ac97 vendor_id match table, { } member terminated
> + */
> +struct ac97_codec_driver {
> +	struct device_driver	driver;
> +	int			(*probe)(struct ac97_codec_device *);
> +	int			(*remove)(struct ac97_codec_device *);
> +	int			(*suspend)(struct ac97_codec_device *);
> +	int			(*resume)(struct ac97_codec_device *);
> +	void			(*shutdown)(struct ac97_codec_device *);
> +	struct ac97_id		*id_table;

Missing const?

> +};
> +
> +int ac97_codec_driver_register(struct ac97_codec_driver *drv);
> +void ac97_codec_driver_unregister(struct ac97_codec_driver *drv);
> +
> +static inline struct device *
> +ac97_codec_dev2dev(const struct ac97_codec_device *adev)
> +{
> +	return (struct device *)(adev);

What's wrong with the simple &adev->dev ?  Cast looks scary.

> +}
> +
> +static inline void *ac97_get_drvdata(const struct ac97_codec_device *adev)
> +{
> +	return dev_get_drvdata(ac97_codec_dev2dev(adev));
> +}
> +
> +static inline void ac97_set_drvdata(const struct ac97_codec_device *adev,
> +				    void *data)
> +{
> +	dev_set_drvdata(ac97_codec_dev2dev(adev), data);
> +}
> +
> +#endif
> diff --git a/include/sound/ac97/compat.h b/include/sound/ac97/compat.h
> new file mode 100644
> index 000000000000..bf611f572f2d
> --- /dev/null
> +++ b/include/sound/ac97/compat.h
> @@ -0,0 +1,21 @@
> +/*
> + *  Copyright (C) 2016 Robert Jarzmik <robert.jarzmik@free.fr>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * This file is for backward compatibility with snd_ac97 structure and its
> + * multiple usages, such as the snd_ac97_bus and snd_ac97_build_ops.
> + *
> + */
> +#ifndef AC97_COMPAT_H
> +#define AC97_COMPAT_H
> +
> +#include <sound/ac97_codec.h>
> +#include <sound/soc.h>
> +
> +struct snd_ac97 *compat_alloc_snd_ac97_codec(struct snd_soc_codec *codec);
> +void compat_release_snd_ac97_codec(struct snd_ac97 *ac97);
> +
> +#endif
> diff --git a/include/sound/ac97/controller.h b/include/sound/ac97/controller.h
> new file mode 100644
> index 000000000000..f1e5e645f5ef
> --- /dev/null
> +++ b/include/sound/ac97/controller.h
> @@ -0,0 +1,39 @@
> +/*
> + *  Copyright (C) 2016 Robert Jarzmik <robert.jarzmik@free.fr>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +#ifndef AC97_CONTROLLER_H
> +#define AC97_CONTROLLER_H
> +
> +#include <linux/list.h>
> +
> +struct device;
> +struct ac97_codec_device;
> +
> +struct ac97_controller_ops {
> +	void (*reset)(struct ac97_codec_device *ac97);
> +	void (*warm_reset)(struct ac97_codec_device *ac97);
> +	int (*write)(struct ac97_codec_device *ac97, unsigned short reg,
> +		     unsigned short val);
> +	int (*read)(struct ac97_codec_device *ac97, unsigned short reg);
> +	void (*wait)(struct ac97_codec_device *ac97);
> +	void (*init)(struct ac97_codec_device *ac97);
> +};
> +
> +struct ac97_controller {
> +	const struct ac97_controller_ops *ops;
> +	struct list_head controllers;
> +	struct device *dev;
> +	int bus_idx;

What is this bus_idx for?


> +	int bound_codecs;
> +	struct list_head codecs;
> +};
> +
> +int ac97_digital_controller_register(const struct ac97_controller_ops *ops,
> +				     struct device *dev);
> +int ac97_digital_controller_unregister(const struct device *dev);
> +
> +#endif
> diff --git a/sound/ac97/Kconfig b/sound/ac97/Kconfig
> new file mode 100644
> index 000000000000..fd2c2d031e62
> --- /dev/null
> +++ b/sound/ac97/Kconfig
> @@ -0,0 +1,9 @@
> +#
> +# PCI configuration
> +#
 
Still only for PCI? :)


> +
> +config AC97
> +	bool "AC97 bus"
> +	help
> +	   Say Y here if you want to have AC97 devices, which are sound oriented
> +	   devices around an AC-Link.
> diff --git a/sound/ac97/Makefile b/sound/ac97/Makefile
> new file mode 100644
> index 000000000000..5575909d46e2
> --- /dev/null
> +++ b/sound/ac97/Makefile
> @@ -0,0 +1,5 @@
> +#
> +# make for AC97 bus drivers
> +#
> +
> +obj-y	+= bus.o codec.o snd_ac97_compat.o

No possibility for modules?


> diff --git a/sound/ac97/ac97_core.h b/sound/ac97/ac97_core.h
> new file mode 100644
> index 000000000000..db6e27288357
> --- /dev/null
> +++ b/sound/ac97/ac97_core.h
> @@ -0,0 +1,10 @@
> +/*
> + * Copyright (C) 2016 Robert Jarzmik <robert.jarzmik@free.fr>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +unsigned int ac97_bus_scan_one(struct ac97_controller *ac97,
> +			       int codec_num);
> diff --git a/sound/ac97/bus.c b/sound/ac97/bus.c
> new file mode 100644
> index 000000000000..f9bf5632d4aa
> --- /dev/null
> +++ b/sound/ac97/bus.c
> @@ -0,0 +1,330 @@
> +/*
> + * Copyright (C) 2016 Robert Jarzmik <robert.jarzmik@free.fr>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/module.h>
> +#include <linux/device.h>
> +#include <linux/list.h>
> +#include <linux/mutex.h>
> +#include <linux/pm.h>
> +#include <linux/slab.h>
> +#include <sound/ac97/codec.h>
> +#include <sound/ac97/controller.h>
> +#include <sound/ac97/regs.h>
> +
> +#define AC97_BUS_MAX_CODECS 4
> +
> +/*
> + * Protects ac97_controllers and each ac97_controller structure.
> + */
> +static DEFINE_MUTEX(ac97_controllers_mutex);
> +static LIST_HEAD(ac97_controllers);
> +static int ac97_bus_idx;
> +
> +struct bus_type ac97_bus_type;
> +
> +static struct ac97_codec_device *
> +ac97_codec_find(struct ac97_controller *ac97_ctrl, int codec_num)
> +{
> +	struct ac97_codec_device *codec;
> +
> +	list_for_each_entry(codec, &ac97_ctrl->codecs, list)
> +		if (codec->num == codec_num)
> +			return codec;
> +
> +	return NULL;
> +}

It's a question whether we need to manage the codecs in the linked
list.  There can be at most 4 codecs, so it fits in an array well,
too.  Then some codes like this would be simpler. (And it'll even
reduce the footprint, too.)


> +
> +static void ac97_codec_release(struct device *dev)
> +{
> +	struct ac97_codec_device *codec;
> +
> +	codec = container_of(dev, struct ac97_codec_device, dev);
> +	list_del(&codec->list);
> +	kfree(codec);
> +}
> +
> +static int ac97_codec_add(struct ac97_controller *ac97_ctrl, int idx,
> +		   unsigned int vendor_id)
> +{
> +	struct ac97_codec_device *codec;
> +	char *codec_name;
> +	int ret;
> +
> +	codec = kzalloc(sizeof(*codec), GFP_KERNEL);
> +	if (!codec)
> +		return -ENOMEM;
> +
> +	codec->vendor_id = vendor_id;
> +	codec->dev.release = ac97_codec_release;
> +	codec->dev.bus = &ac97_bus_type;
> +	codec->dev.parent = ac97_ctrl->dev;
> +	codec->num = idx;
> +	codec->ac97_ctrl = ac97_ctrl;
> +	INIT_LIST_HEAD(&codec->list);
> +	list_move_tail(&codec->list, &ac97_ctrl->codecs);
> +
> +	codec_name = kasprintf(GFP_KERNEL, "%s:%d", dev_name(ac97_ctrl->dev),
> +			       idx);
> +	codec->dev.init_name = codec_name;
> +
> +	ret = device_register(&codec->dev);
> +	kfree(codec_name);
> +
> +	return ret;
> +}
> +
> +unsigned int ac97_bus_scan_one(struct ac97_controller *ac97,
> +				      int codec_num)
> +{
> +	struct ac97_codec_device codec;
> +	unsigned short vid1, vid2;
> +	int ret;
> +
> +	codec.dev = *ac97->dev;
> +	codec.num = codec_num;
> +	ret = ac97->ops->read(&codec, AC97_VENDOR_ID1);
> +	vid1 = (ret & 0xffff);
> +	if (ret < 0)
> +		return 0;

Hmm.  This looks pretty hackish and dangerous.



> +	ret = ac97->ops->read(&codec, AC97_VENDOR_ID2);
> +	vid2 = (ret & 0xffff);
> +	if (ret < 0)
> +		return 0;
> +
> +	dev_dbg(&codec.dev, "%s(codec_num=%d): vendor_id=0x%08x\n",
> +		__func__, codec_num, AC97_ID(vid1, vid2));
> +	return AC97_ID(vid1, vid2);
> +}
> +
> +static int ac97_bus_scan(struct ac97_controller *ac97_ctrl)
> +{
> +	int ret, i;
> +	unsigned int vendor_id;
> +
> +	for (i = 0; i < AC97_BUS_MAX_CODECS; i++) {
> +		if (ac97_codec_find(ac97_ctrl, i))
> +			continue;
> +		vendor_id = ac97_bus_scan_one(ac97_ctrl, i);
> +		if (!vendor_id)
> +			continue;
> +
> +		ret = ac97_codec_add(ac97_ctrl, i, vendor_id);
> +		if (ret < 0)
> +			return ret;

This is one of concerns: we don't know whether the device really
reacts well if you access to a non-existing slot.  At least, it'd be
safer to have the masks for the devices we already know the slots.


> +	}
> +	return 0;
> +}
> +
> +void ac97_rescan_all_controllers(void)
> +{
> +	struct ac97_controller *ac97_ctrl;
> +	int ret;
> +
> +	mutex_lock(&ac97_controllers_mutex);
> +	list_for_each_entry(ac97_ctrl, &ac97_controllers, controllers) {
> +		ret = ac97_bus_scan(ac97_ctrl);
> +		if (ret)
> +			dev_warn(ac97_ctrl->dev, "scan failed: %d\n", ret);
> +	}
> +	mutex_unlock(&ac97_controllers_mutex);
> +}
> +EXPORT_SYMBOL(ac97_rescan_all_controllers);
> +
> +static int ac97_bus_reset(struct ac97_controller *ac97_ctrl)
> +{
> +	struct ac97_codec_device codec;
> +
> +	memset(&codec, 0, sizeof(codec));
> +	codec.dev = *ac97_ctrl->dev;
> +
> +	ac97_ctrl->ops->reset(&codec);

So, this assumes that reset ops is mandatory?  Then document it at
least.


thanks,

Takashi

> +	return 0;
> +}
> +
> +/**
> + * ac97_codec_driver_register - register an AC97 codec driver
> + * @dev: AC97 driver codec to register
> + *
> + * Register an AC97 codec driver to the ac97 bus driver, aka. the AC97 digital
> + * controller.
> + *
> + * Returns 0 on success or error code
> + */
> +int ac97_codec_driver_register(struct ac97_codec_driver *drv)
> +{
> +	int ret;
> +
> +	drv->driver.bus = &ac97_bus_type;
> +
> +	ret = driver_register(&drv->driver);
> +	if (!ret)
> +		ac97_rescan_all_controllers();
> +
> +	return ret;
> +}
> +EXPORT_SYMBOL(ac97_codec_driver_register);
> +
> +/**
> + * ac97_codec_driver_unregister - unregister an AC97 codec driver
> + * @dev: AC97 codec driver to unregister
> + *
> + * Unregister a previously registered ac97 codec driver.
> + */
> +void ac97_codec_driver_unregister(struct ac97_codec_driver *drv)
> +{
> +	driver_unregister(&drv->driver);
> +}
> +EXPORT_SYMBOL(ac97_codec_driver_unregister);
> +
> +static int ac97_dc_codecs_unregister(struct ac97_controller *ac97_ctrl)
> +{
> +	struct ac97_codec_device *codec, *tmp;
> +
> +	list_for_each_entry_safe(codec, tmp, &ac97_ctrl->codecs, list)
> +		put_device(&codec->dev);
> +
> +	return 0;
> +}
> +
> +/**
> + * ac97_digital_controller_register - register an ac97 controller
> + * @ops: the ac97 bus operations
> + * @dev: the device providing the ac97 DC function
> + *
> + * Register a digital controller which can control up to 4 ac97 codecs. This is
> + * the controller side of the AC97 AC-link, while the slave side are the codecs.
> + *
> + * Returns a positive bus index upon success, negative value upon error
> + */
> +int ac97_digital_controller_register(const struct ac97_controller_ops *ops,
> +				     struct device *dev)
> +{
> +	struct ac97_controller *ac97_ctrl;
> +
> +	ac97_ctrl = kzalloc(sizeof(*ac97_ctrl), GFP_KERNEL);
> +	if (!ac97_ctrl)
> +		return -ENOMEM;
> +
> +	mutex_lock(&ac97_controllers_mutex);
> +	ac97_ctrl->ops = ops;
> +	ac97_ctrl->bus_idx = ac97_bus_idx++;
> +	ac97_ctrl->dev = dev;
> +	INIT_LIST_HEAD(&ac97_ctrl->codecs);
> +	list_add(&ac97_ctrl->controllers, &ac97_controllers);
> +	mutex_unlock(&ac97_controllers_mutex);
> +
> +	ac97_bus_reset(ac97_ctrl);
> +	ac97_bus_scan(ac97_ctrl);
> +
> +	return ac97_ctrl->bus_idx;
> +}
> +EXPORT_SYMBOL(ac97_digital_controller_register);
> +
> +/**
> + * ac97_digital_controller_unregister - unregister an ac97 controller
> + * @dev: the device previously provided to ac97_digital_controller_register()
> + *
> + * Returns 0 on success, negative upon error
> + */
> +int ac97_digital_controller_unregister(const struct device *dev)
> +{
> +	struct ac97_controller *ac97_ctrl, *tmp;
> +	int ret = -ENODEV;
> +
> +	mutex_lock(&ac97_controllers_mutex);
> +	list_for_each_entry_safe(ac97_ctrl, tmp, &ac97_controllers,
> +				 controllers) {
> +		if (ac97_ctrl->dev != dev)
> +			continue;
> +		if (ac97_ctrl->bound_codecs)
> +			ret = -EBUSY;
> +		else
> +			ret = ac97_dc_codecs_unregister(ac97_ctrl);
> +		if (!ret)
> +			list_del(&ac97_ctrl->controllers);
> +	}
> +
> +	mutex_unlock(&ac97_controllers_mutex);
> +	return ret;
> +}
> +EXPORT_SYMBOL(ac97_digital_controller_unregister);
> +
> +static const struct dev_pm_ops ac97_pm = {
> +	.suspend	= pm_generic_suspend,
> +	.resume		= pm_generic_resume,
> +	.freeze		= pm_generic_freeze,
> +	.thaw		= pm_generic_thaw,
> +	.poweroff	= pm_generic_poweroff,
> +	.restore	= pm_generic_restore,
> +};
> +
> +static ssize_t vendor_id_show(struct device *dev,
> +			      struct device_attribute *attr, char *buf)
> +{
> +	struct ac97_codec_device *codec = to_ac97_device(dev);
> +
> +	return sprintf(buf, "%08x", codec->vendor_id);
> +}
> +
> +static struct device_attribute ac97_dev_attrs[] = {
> +	__ATTR_RO(vendor_id),
> +	__ATTR_NULL,
> +};
> +
> +int ac97_bus_match(struct device *dev, struct device_driver *drv)
> +{
> +	struct ac97_codec_device *adev = to_ac97_device(dev);
> +	struct ac97_codec_driver *adrv = to_ac97_driver(drv);
> +	struct ac97_id *id = adrv->id_table;
> +
> +	if (adev->vendor_id == 0x0 || adev->vendor_id == 0xffffffff)
> +		return false;
> +
> +	do {
> +		if ((id->id & id->mask) == (adev->vendor_id & id->mask))
> +			return true;
> +	} while (++id->id);
> +
> +	return false;
> +}
> +
> +static int ac97_bus_probe(struct device *dev)
> +{
> +	struct ac97_codec_device *adev = to_ac97_device(dev);
> +	struct ac97_codec_driver *adrv = to_ac97_driver(dev->driver);
> +
> +	return adrv->probe(adev);
> +}
> +
> +static int ac97_bus_remove(struct device *dev)
> +{
> +	struct ac97_codec_device *adev = to_ac97_device(dev);
> +	struct ac97_codec_driver *adrv = to_ac97_driver(dev->driver);
> +
> +	return adrv->remove(adev);
> +}
> +
> +struct bus_type ac97_bus_type = {
> +	.name		= "ac97",
> +	.dev_attrs	= ac97_dev_attrs,
> +	.match		= ac97_bus_match,
> +	.pm		= &ac97_pm,
> +	.probe		= ac97_bus_probe,
> +	.remove		= ac97_bus_remove,
> +};
> +EXPORT_SYMBOL(ac97_bus_type);
> +
> +static int __init ac97_bus_init(void)
> +{
> +	return bus_register(&ac97_bus_type);
> +}
> +subsys_initcall(ac97_bus_init);
> +
> +MODULE_LICENSE("GPL");
> +MODULE_AUTHOR("Robert Jarzmik <robert.jarzmik@free.fr>");
> diff --git a/sound/ac97/codec.c b/sound/ac97/codec.c
> new file mode 100644
> index 000000000000..a835f03744bf
> --- /dev/null
> +++ b/sound/ac97/codec.c
> @@ -0,0 +1,15 @@
> +/*
> + *  Copyright (C) 2016 Robert Jarzmik <robert.jarzmik@free.fr>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <sound/ac97_codec.h>
> +#include <sound/ac97/codec.h>
> +#include <sound/ac97/controller.h>
> +#include <linux/device.h>
> +#include <linux/slab.h>
> +#include <sound/soc.h>	/* For compat_ac97_* */
> +
> diff --git a/sound/ac97/snd_ac97_compat.c b/sound/ac97/snd_ac97_compat.c
> new file mode 100644
> index 000000000000..7e2f01c96fc9
> --- /dev/null
> +++ b/sound/ac97/snd_ac97_compat.c
> @@ -0,0 +1,104 @@
> +/*
> + *  Copyright (C) 2016 Robert Jarzmik <robert.jarzmik@free.fr>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/list.h>
> +#include <linux/slab.h>
> +#include <sound/ac97/codec.h>
> +#include <sound/ac97/controller.h>
> +#include <sound/soc.h>
> +
> +#include "ac97_core.h"
> +
> +static void compat_ac97_reset(struct snd_ac97 *ac97)
> +{
> +	struct ac97_codec_device *adev = to_ac97_device(ac97->private_data);
> +	struct ac97_controller *actrl = adev->ac97_ctrl;
> +
> +	if (actrl->ops->reset)
> +		actrl->ops->reset(adev);
> +}
> +
> +static void compat_ac97_warm_reset(struct snd_ac97 *ac97)
> +{
> +	struct ac97_codec_device *adev = to_ac97_device(ac97->private_data);
> +	struct ac97_controller *actrl = adev->ac97_ctrl;
> +
> +	if (actrl->ops->warm_reset)
> +		actrl->ops->warm_reset(adev);
> +}
> +
> +static void compat_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
> +			      unsigned short val)
> +{
> +	struct ac97_codec_device *adev = to_ac97_device(ac97->private_data);
> +	struct ac97_controller *actrl = adev->ac97_ctrl;
> +
> +	actrl->ops->write(adev, reg, val);
> +}
> +
> +static unsigned short compat_ac97_read(struct snd_ac97 *ac97,
> +				       unsigned short reg)
> +{
> +	struct ac97_codec_device *adev = to_ac97_device(ac97->private_data);
> +	struct ac97_controller *actrl = adev->ac97_ctrl;
> +
> +	return actrl->ops->read(adev, reg);
> +}
> +
> +static struct snd_ac97_bus_ops compat_snd_ac97_bus_ops = {
> +	.reset = compat_ac97_reset,
> +	.warm_reset = compat_ac97_warm_reset,
> +	.write = compat_ac97_write,
> +	.read = compat_ac97_read,
> +};
> +
> +static struct snd_ac97_bus compat_soc_ac97_bus = {
> +	.ops = &compat_snd_ac97_bus_ops,
> +};
> +
> +struct snd_ac97 *compat_alloc_snd_ac97_codec(struct snd_soc_codec *codec)
> +{
> +	struct snd_ac97 *ac97;
> +
> +	ac97 = kzalloc(sizeof(struct snd_ac97), GFP_KERNEL);
> +	if (ac97 == NULL)
> +		return ERR_PTR(-ENOMEM);
> +
> +	ac97->dev = *codec->dev;
> +	ac97->private_data = codec->dev;
> +	ac97->bus = &compat_soc_ac97_bus;
> +	return ac97;
> +}
> +EXPORT_SYMBOL_GPL(compat_alloc_snd_ac97_codec);
> +
> +void compat_release_snd_ac97_codec(struct snd_ac97 *ac97)
> +{
> +	kfree(ac97);
> +}
> +EXPORT_SYMBOL_GPL(compat_release_snd_ac97_codec);
> +
> +int snd_ac97_reset(struct snd_ac97 *ac97, bool try_warm, unsigned int id,
> +	unsigned int id_mask)
> +{
> +	struct ac97_codec_device *adev = to_ac97_device(ac97->private_data);
> +	struct ac97_controller *actrl = adev->ac97_ctrl;
> +
> +	if (try_warm) {
> +		compat_ac97_warm_reset(ac97);
> +		if (ac97_bus_scan_one(actrl, adev->num) == adev->vendor_id)
> +			return 1;
> +	}
> +
> +	compat_ac97_reset(ac97);
> +	compat_ac97_warm_reset(ac97);
> +	if (ac97_bus_scan_one(actrl, adev->num) == adev->vendor_id)
> +		return 0;
> +
> +	return -ENODEV;
> +}
> +EXPORT_SYMBOL_GPL(snd_ac97_reset);
> -- 
> 2.1.4
> 
> 

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

* Re: [RFC PATCH 2/7] ALSA: ac97: add an ac97 bus
@ 2016-05-09  9:31     ` Takashi Iwai
  0 siblings, 0 replies; 74+ messages in thread
From: Takashi Iwai @ 2016-05-09  9:31 UTC (permalink / raw)
  To: Robert Jarzmik
  Cc: alsa-devel, linux-kernel, patches, Liam Girdwood, Haojian Zhuang,
	Mark Brown, linux-arm-kernel, Daniel Mack

On Sat, 30 Apr 2016 23:15:34 +0200,
Robert Jarzmik wrote:
> 
> diff --git a/include/sound/ac97/codec.h b/include/sound/ac97/codec.h
> new file mode 100644
> index 000000000000..4b8b3e570892
> --- /dev/null
> +++ b/include/sound/ac97/codec.h
> @@ -0,0 +1,98 @@
> +/*
> + *  Copyright (C) 2016 Robert Jarzmik <robert.jarzmik@free.fr>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +#ifndef AC97_CODEC_H
> +#define AC97_CODEC_H

Let's be careful about the choice of the guard.


> +
> +#include <linux/device.h>
> +
> +#define AC97_ID(vendor_id1, vendor_id2) \
> +	(((vendor_id1 & 0xffff) << 16) | (vendor_id2 & 0xffff))
> +#define AC97_DRIVER_ID(vendor_id1, vendor_id2, mask_id1, mask_id2, _data) \
> +	{ .id = ((vendor_id1 & 0xffff) << 16) | (vendor_id2 & 0xffff), \
> +	  .mask = ((mask_id1 & 0xffff) << 16) | (mask_id2 & 0xffff), \
> +	  .data = _data }

Give parentheses around the macro arguments.


> +
> +#define to_ac97_device(d) container_of(d, struct ac97_codec_device, dev)
> +#define to_ac97_driver(d) container_of(d, struct ac97_codec_driver, driver)
> +
> +struct ac97_controller;
> +
> +/**
> + * struct ac97_id - matches a codec device and driver on an ac97 bus
> + * @id: The significant bits if the codec vendor ID1 and ID2
> + * @mask: Bitmask specifying which bits of the id field are significant when
> + *	  matching. A driver binds to a device when :
> + *        ((vendorID1 << 8 | vendorID2) & (mask_id1 << 8 | mask_id2)) == id.
> + * @data: Private data used by the driver.
> + */
> +struct ac97_id {
> +	unsigned int		id;
> +	unsigned int		mask;
> +	void			*data;
> +};
> +
> +/**
> + * ac97_codec_device - a ac97 codec
> + * @dev: the code device
> + * @vendor_id: the vendor_id of the codec, as sensed on the AC-link
> + * @num: the codec number, 0 is primary, 1 is first slave, etc ...
> + * @ac97_ctrl: ac97 digital controller on the same AC-link
> + *
> + * This is the device instanciated for each codec living on a AC-link. There are
> + * normally 0 to 4 codec devices per AC-link, and all of them are controlled by
> + * an AC97 digital controller.
> + */
> +struct ac97_codec_device {
> +	struct device		dev;	/* Must stay first member */

This doesn't have to be the first element as long as you use container_of().


> +	unsigned int		vendor_id;
> +	unsigned int		num;
> +	struct list_head	list;
> +	struct ac97_controller	*ac97_ctrl;
> +};
> +
> +/**
> + * ac97_codec_driver - a ac97 codec driver
> + * @driver: the device driver structure
> + * @probe: the function called when a ac97_codec_device is matched
> + * @remove: the function called when the device is unbound/removed
> + * @suspend: suspend function (might be NULL)
> + * @resume: resume function (might be NULL)
> + * @shutdown: shutdown function (might be NULL)
> + * @id_table: ac97 vendor_id match table, { } member terminated
> + */
> +struct ac97_codec_driver {
> +	struct device_driver	driver;
> +	int			(*probe)(struct ac97_codec_device *);
> +	int			(*remove)(struct ac97_codec_device *);
> +	int			(*suspend)(struct ac97_codec_device *);
> +	int			(*resume)(struct ac97_codec_device *);
> +	void			(*shutdown)(struct ac97_codec_device *);
> +	struct ac97_id		*id_table;

Missing const?

> +};
> +
> +int ac97_codec_driver_register(struct ac97_codec_driver *drv);
> +void ac97_codec_driver_unregister(struct ac97_codec_driver *drv);
> +
> +static inline struct device *
> +ac97_codec_dev2dev(const struct ac97_codec_device *adev)
> +{
> +	return (struct device *)(adev);

What's wrong with the simple &adev->dev ?  Cast looks scary.

> +}
> +
> +static inline void *ac97_get_drvdata(const struct ac97_codec_device *adev)
> +{
> +	return dev_get_drvdata(ac97_codec_dev2dev(adev));
> +}
> +
> +static inline void ac97_set_drvdata(const struct ac97_codec_device *adev,
> +				    void *data)
> +{
> +	dev_set_drvdata(ac97_codec_dev2dev(adev), data);
> +}
> +
> +#endif
> diff --git a/include/sound/ac97/compat.h b/include/sound/ac97/compat.h
> new file mode 100644
> index 000000000000..bf611f572f2d
> --- /dev/null
> +++ b/include/sound/ac97/compat.h
> @@ -0,0 +1,21 @@
> +/*
> + *  Copyright (C) 2016 Robert Jarzmik <robert.jarzmik@free.fr>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * This file is for backward compatibility with snd_ac97 structure and its
> + * multiple usages, such as the snd_ac97_bus and snd_ac97_build_ops.
> + *
> + */
> +#ifndef AC97_COMPAT_H
> +#define AC97_COMPAT_H
> +
> +#include <sound/ac97_codec.h>
> +#include <sound/soc.h>
> +
> +struct snd_ac97 *compat_alloc_snd_ac97_codec(struct snd_soc_codec *codec);
> +void compat_release_snd_ac97_codec(struct snd_ac97 *ac97);
> +
> +#endif
> diff --git a/include/sound/ac97/controller.h b/include/sound/ac97/controller.h
> new file mode 100644
> index 000000000000..f1e5e645f5ef
> --- /dev/null
> +++ b/include/sound/ac97/controller.h
> @@ -0,0 +1,39 @@
> +/*
> + *  Copyright (C) 2016 Robert Jarzmik <robert.jarzmik@free.fr>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +#ifndef AC97_CONTROLLER_H
> +#define AC97_CONTROLLER_H
> +
> +#include <linux/list.h>
> +
> +struct device;
> +struct ac97_codec_device;
> +
> +struct ac97_controller_ops {
> +	void (*reset)(struct ac97_codec_device *ac97);
> +	void (*warm_reset)(struct ac97_codec_device *ac97);
> +	int (*write)(struct ac97_codec_device *ac97, unsigned short reg,
> +		     unsigned short val);
> +	int (*read)(struct ac97_codec_device *ac97, unsigned short reg);
> +	void (*wait)(struct ac97_codec_device *ac97);
> +	void (*init)(struct ac97_codec_device *ac97);
> +};
> +
> +struct ac97_controller {
> +	const struct ac97_controller_ops *ops;
> +	struct list_head controllers;
> +	struct device *dev;
> +	int bus_idx;

What is this bus_idx for?


> +	int bound_codecs;
> +	struct list_head codecs;
> +};
> +
> +int ac97_digital_controller_register(const struct ac97_controller_ops *ops,
> +				     struct device *dev);
> +int ac97_digital_controller_unregister(const struct device *dev);
> +
> +#endif
> diff --git a/sound/ac97/Kconfig b/sound/ac97/Kconfig
> new file mode 100644
> index 000000000000..fd2c2d031e62
> --- /dev/null
> +++ b/sound/ac97/Kconfig
> @@ -0,0 +1,9 @@
> +#
> +# PCI configuration
> +#
 
Still only for PCI? :)


> +
> +config AC97
> +	bool "AC97 bus"
> +	help
> +	   Say Y here if you want to have AC97 devices, which are sound oriented
> +	   devices around an AC-Link.
> diff --git a/sound/ac97/Makefile b/sound/ac97/Makefile
> new file mode 100644
> index 000000000000..5575909d46e2
> --- /dev/null
> +++ b/sound/ac97/Makefile
> @@ -0,0 +1,5 @@
> +#
> +# make for AC97 bus drivers
> +#
> +
> +obj-y	+= bus.o codec.o snd_ac97_compat.o

No possibility for modules?


> diff --git a/sound/ac97/ac97_core.h b/sound/ac97/ac97_core.h
> new file mode 100644
> index 000000000000..db6e27288357
> --- /dev/null
> +++ b/sound/ac97/ac97_core.h
> @@ -0,0 +1,10 @@
> +/*
> + * Copyright (C) 2016 Robert Jarzmik <robert.jarzmik@free.fr>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +unsigned int ac97_bus_scan_one(struct ac97_controller *ac97,
> +			       int codec_num);
> diff --git a/sound/ac97/bus.c b/sound/ac97/bus.c
> new file mode 100644
> index 000000000000..f9bf5632d4aa
> --- /dev/null
> +++ b/sound/ac97/bus.c
> @@ -0,0 +1,330 @@
> +/*
> + * Copyright (C) 2016 Robert Jarzmik <robert.jarzmik@free.fr>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/module.h>
> +#include <linux/device.h>
> +#include <linux/list.h>
> +#include <linux/mutex.h>
> +#include <linux/pm.h>
> +#include <linux/slab.h>
> +#include <sound/ac97/codec.h>
> +#include <sound/ac97/controller.h>
> +#include <sound/ac97/regs.h>
> +
> +#define AC97_BUS_MAX_CODECS 4
> +
> +/*
> + * Protects ac97_controllers and each ac97_controller structure.
> + */
> +static DEFINE_MUTEX(ac97_controllers_mutex);
> +static LIST_HEAD(ac97_controllers);
> +static int ac97_bus_idx;
> +
> +struct bus_type ac97_bus_type;
> +
> +static struct ac97_codec_device *
> +ac97_codec_find(struct ac97_controller *ac97_ctrl, int codec_num)
> +{
> +	struct ac97_codec_device *codec;
> +
> +	list_for_each_entry(codec, &ac97_ctrl->codecs, list)
> +		if (codec->num == codec_num)
> +			return codec;
> +
> +	return NULL;
> +}

It's a question whether we need to manage the codecs in the linked
list.  There can be at most 4 codecs, so it fits in an array well,
too.  Then some codes like this would be simpler. (And it'll even
reduce the footprint, too.)


> +
> +static void ac97_codec_release(struct device *dev)
> +{
> +	struct ac97_codec_device *codec;
> +
> +	codec = container_of(dev, struct ac97_codec_device, dev);
> +	list_del(&codec->list);
> +	kfree(codec);
> +}
> +
> +static int ac97_codec_add(struct ac97_controller *ac97_ctrl, int idx,
> +		   unsigned int vendor_id)
> +{
> +	struct ac97_codec_device *codec;
> +	char *codec_name;
> +	int ret;
> +
> +	codec = kzalloc(sizeof(*codec), GFP_KERNEL);
> +	if (!codec)
> +		return -ENOMEM;
> +
> +	codec->vendor_id = vendor_id;
> +	codec->dev.release = ac97_codec_release;
> +	codec->dev.bus = &ac97_bus_type;
> +	codec->dev.parent = ac97_ctrl->dev;
> +	codec->num = idx;
> +	codec->ac97_ctrl = ac97_ctrl;
> +	INIT_LIST_HEAD(&codec->list);
> +	list_move_tail(&codec->list, &ac97_ctrl->codecs);
> +
> +	codec_name = kasprintf(GFP_KERNEL, "%s:%d", dev_name(ac97_ctrl->dev),
> +			       idx);
> +	codec->dev.init_name = codec_name;
> +
> +	ret = device_register(&codec->dev);
> +	kfree(codec_name);
> +
> +	return ret;
> +}
> +
> +unsigned int ac97_bus_scan_one(struct ac97_controller *ac97,
> +				      int codec_num)
> +{
> +	struct ac97_codec_device codec;
> +	unsigned short vid1, vid2;
> +	int ret;
> +
> +	codec.dev = *ac97->dev;
> +	codec.num = codec_num;
> +	ret = ac97->ops->read(&codec, AC97_VENDOR_ID1);
> +	vid1 = (ret & 0xffff);
> +	if (ret < 0)
> +		return 0;

Hmm.  This looks pretty hackish and dangerous.



> +	ret = ac97->ops->read(&codec, AC97_VENDOR_ID2);
> +	vid2 = (ret & 0xffff);
> +	if (ret < 0)
> +		return 0;
> +
> +	dev_dbg(&codec.dev, "%s(codec_num=%d): vendor_id=0x%08x\n",
> +		__func__, codec_num, AC97_ID(vid1, vid2));
> +	return AC97_ID(vid1, vid2);
> +}
> +
> +static int ac97_bus_scan(struct ac97_controller *ac97_ctrl)
> +{
> +	int ret, i;
> +	unsigned int vendor_id;
> +
> +	for (i = 0; i < AC97_BUS_MAX_CODECS; i++) {
> +		if (ac97_codec_find(ac97_ctrl, i))
> +			continue;
> +		vendor_id = ac97_bus_scan_one(ac97_ctrl, i);
> +		if (!vendor_id)
> +			continue;
> +
> +		ret = ac97_codec_add(ac97_ctrl, i, vendor_id);
> +		if (ret < 0)
> +			return ret;

This is one of concerns: we don't know whether the device really
reacts well if you access to a non-existing slot.  At least, it'd be
safer to have the masks for the devices we already know the slots.


> +	}
> +	return 0;
> +}
> +
> +void ac97_rescan_all_controllers(void)
> +{
> +	struct ac97_controller *ac97_ctrl;
> +	int ret;
> +
> +	mutex_lock(&ac97_controllers_mutex);
> +	list_for_each_entry(ac97_ctrl, &ac97_controllers, controllers) {
> +		ret = ac97_bus_scan(ac97_ctrl);
> +		if (ret)
> +			dev_warn(ac97_ctrl->dev, "scan failed: %d\n", ret);
> +	}
> +	mutex_unlock(&ac97_controllers_mutex);
> +}
> +EXPORT_SYMBOL(ac97_rescan_all_controllers);
> +
> +static int ac97_bus_reset(struct ac97_controller *ac97_ctrl)
> +{
> +	struct ac97_codec_device codec;
> +
> +	memset(&codec, 0, sizeof(codec));
> +	codec.dev = *ac97_ctrl->dev;
> +
> +	ac97_ctrl->ops->reset(&codec);

So, this assumes that reset ops is mandatory?  Then document it at
least.


thanks,

Takashi

> +	return 0;
> +}
> +
> +/**
> + * ac97_codec_driver_register - register an AC97 codec driver
> + * @dev: AC97 driver codec to register
> + *
> + * Register an AC97 codec driver to the ac97 bus driver, aka. the AC97 digital
> + * controller.
> + *
> + * Returns 0 on success or error code
> + */
> +int ac97_codec_driver_register(struct ac97_codec_driver *drv)
> +{
> +	int ret;
> +
> +	drv->driver.bus = &ac97_bus_type;
> +
> +	ret = driver_register(&drv->driver);
> +	if (!ret)
> +		ac97_rescan_all_controllers();
> +
> +	return ret;
> +}
> +EXPORT_SYMBOL(ac97_codec_driver_register);
> +
> +/**
> + * ac97_codec_driver_unregister - unregister an AC97 codec driver
> + * @dev: AC97 codec driver to unregister
> + *
> + * Unregister a previously registered ac97 codec driver.
> + */
> +void ac97_codec_driver_unregister(struct ac97_codec_driver *drv)
> +{
> +	driver_unregister(&drv->driver);
> +}
> +EXPORT_SYMBOL(ac97_codec_driver_unregister);
> +
> +static int ac97_dc_codecs_unregister(struct ac97_controller *ac97_ctrl)
> +{
> +	struct ac97_codec_device *codec, *tmp;
> +
> +	list_for_each_entry_safe(codec, tmp, &ac97_ctrl->codecs, list)
> +		put_device(&codec->dev);
> +
> +	return 0;
> +}
> +
> +/**
> + * ac97_digital_controller_register - register an ac97 controller
> + * @ops: the ac97 bus operations
> + * @dev: the device providing the ac97 DC function
> + *
> + * Register a digital controller which can control up to 4 ac97 codecs. This is
> + * the controller side of the AC97 AC-link, while the slave side are the codecs.
> + *
> + * Returns a positive bus index upon success, negative value upon error
> + */
> +int ac97_digital_controller_register(const struct ac97_controller_ops *ops,
> +				     struct device *dev)
> +{
> +	struct ac97_controller *ac97_ctrl;
> +
> +	ac97_ctrl = kzalloc(sizeof(*ac97_ctrl), GFP_KERNEL);
> +	if (!ac97_ctrl)
> +		return -ENOMEM;
> +
> +	mutex_lock(&ac97_controllers_mutex);
> +	ac97_ctrl->ops = ops;
> +	ac97_ctrl->bus_idx = ac97_bus_idx++;
> +	ac97_ctrl->dev = dev;
> +	INIT_LIST_HEAD(&ac97_ctrl->codecs);
> +	list_add(&ac97_ctrl->controllers, &ac97_controllers);
> +	mutex_unlock(&ac97_controllers_mutex);
> +
> +	ac97_bus_reset(ac97_ctrl);
> +	ac97_bus_scan(ac97_ctrl);
> +
> +	return ac97_ctrl->bus_idx;
> +}
> +EXPORT_SYMBOL(ac97_digital_controller_register);
> +
> +/**
> + * ac97_digital_controller_unregister - unregister an ac97 controller
> + * @dev: the device previously provided to ac97_digital_controller_register()
> + *
> + * Returns 0 on success, negative upon error
> + */
> +int ac97_digital_controller_unregister(const struct device *dev)
> +{
> +	struct ac97_controller *ac97_ctrl, *tmp;
> +	int ret = -ENODEV;
> +
> +	mutex_lock(&ac97_controllers_mutex);
> +	list_for_each_entry_safe(ac97_ctrl, tmp, &ac97_controllers,
> +				 controllers) {
> +		if (ac97_ctrl->dev != dev)
> +			continue;
> +		if (ac97_ctrl->bound_codecs)
> +			ret = -EBUSY;
> +		else
> +			ret = ac97_dc_codecs_unregister(ac97_ctrl);
> +		if (!ret)
> +			list_del(&ac97_ctrl->controllers);
> +	}
> +
> +	mutex_unlock(&ac97_controllers_mutex);
> +	return ret;
> +}
> +EXPORT_SYMBOL(ac97_digital_controller_unregister);
> +
> +static const struct dev_pm_ops ac97_pm = {
> +	.suspend	= pm_generic_suspend,
> +	.resume		= pm_generic_resume,
> +	.freeze		= pm_generic_freeze,
> +	.thaw		= pm_generic_thaw,
> +	.poweroff	= pm_generic_poweroff,
> +	.restore	= pm_generic_restore,
> +};
> +
> +static ssize_t vendor_id_show(struct device *dev,
> +			      struct device_attribute *attr, char *buf)
> +{
> +	struct ac97_codec_device *codec = to_ac97_device(dev);
> +
> +	return sprintf(buf, "%08x", codec->vendor_id);
> +}
> +
> +static struct device_attribute ac97_dev_attrs[] = {
> +	__ATTR_RO(vendor_id),
> +	__ATTR_NULL,
> +};
> +
> +int ac97_bus_match(struct device *dev, struct device_driver *drv)
> +{
> +	struct ac97_codec_device *adev = to_ac97_device(dev);
> +	struct ac97_codec_driver *adrv = to_ac97_driver(drv);
> +	struct ac97_id *id = adrv->id_table;
> +
> +	if (adev->vendor_id == 0x0 || adev->vendor_id == 0xffffffff)
> +		return false;
> +
> +	do {
> +		if ((id->id & id->mask) == (adev->vendor_id & id->mask))
> +			return true;
> +	} while (++id->id);
> +
> +	return false;
> +}
> +
> +static int ac97_bus_probe(struct device *dev)
> +{
> +	struct ac97_codec_device *adev = to_ac97_device(dev);
> +	struct ac97_codec_driver *adrv = to_ac97_driver(dev->driver);
> +
> +	return adrv->probe(adev);
> +}
> +
> +static int ac97_bus_remove(struct device *dev)
> +{
> +	struct ac97_codec_device *adev = to_ac97_device(dev);
> +	struct ac97_codec_driver *adrv = to_ac97_driver(dev->driver);
> +
> +	return adrv->remove(adev);
> +}
> +
> +struct bus_type ac97_bus_type = {
> +	.name		= "ac97",
> +	.dev_attrs	= ac97_dev_attrs,
> +	.match		= ac97_bus_match,
> +	.pm		= &ac97_pm,
> +	.probe		= ac97_bus_probe,
> +	.remove		= ac97_bus_remove,
> +};
> +EXPORT_SYMBOL(ac97_bus_type);
> +
> +static int __init ac97_bus_init(void)
> +{
> +	return bus_register(&ac97_bus_type);
> +}
> +subsys_initcall(ac97_bus_init);
> +
> +MODULE_LICENSE("GPL");
> +MODULE_AUTHOR("Robert Jarzmik <robert.jarzmik@free.fr>");
> diff --git a/sound/ac97/codec.c b/sound/ac97/codec.c
> new file mode 100644
> index 000000000000..a835f03744bf
> --- /dev/null
> +++ b/sound/ac97/codec.c
> @@ -0,0 +1,15 @@
> +/*
> + *  Copyright (C) 2016 Robert Jarzmik <robert.jarzmik@free.fr>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <sound/ac97_codec.h>
> +#include <sound/ac97/codec.h>
> +#include <sound/ac97/controller.h>
> +#include <linux/device.h>
> +#include <linux/slab.h>
> +#include <sound/soc.h>	/* For compat_ac97_* */
> +
> diff --git a/sound/ac97/snd_ac97_compat.c b/sound/ac97/snd_ac97_compat.c
> new file mode 100644
> index 000000000000..7e2f01c96fc9
> --- /dev/null
> +++ b/sound/ac97/snd_ac97_compat.c
> @@ -0,0 +1,104 @@
> +/*
> + *  Copyright (C) 2016 Robert Jarzmik <robert.jarzmik@free.fr>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/list.h>
> +#include <linux/slab.h>
> +#include <sound/ac97/codec.h>
> +#include <sound/ac97/controller.h>
> +#include <sound/soc.h>
> +
> +#include "ac97_core.h"
> +
> +static void compat_ac97_reset(struct snd_ac97 *ac97)
> +{
> +	struct ac97_codec_device *adev = to_ac97_device(ac97->private_data);
> +	struct ac97_controller *actrl = adev->ac97_ctrl;
> +
> +	if (actrl->ops->reset)
> +		actrl->ops->reset(adev);
> +}
> +
> +static void compat_ac97_warm_reset(struct snd_ac97 *ac97)
> +{
> +	struct ac97_codec_device *adev = to_ac97_device(ac97->private_data);
> +	struct ac97_controller *actrl = adev->ac97_ctrl;
> +
> +	if (actrl->ops->warm_reset)
> +		actrl->ops->warm_reset(adev);
> +}
> +
> +static void compat_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
> +			      unsigned short val)
> +{
> +	struct ac97_codec_device *adev = to_ac97_device(ac97->private_data);
> +	struct ac97_controller *actrl = adev->ac97_ctrl;
> +
> +	actrl->ops->write(adev, reg, val);
> +}
> +
> +static unsigned short compat_ac97_read(struct snd_ac97 *ac97,
> +				       unsigned short reg)
> +{
> +	struct ac97_codec_device *adev = to_ac97_device(ac97->private_data);
> +	struct ac97_controller *actrl = adev->ac97_ctrl;
> +
> +	return actrl->ops->read(adev, reg);
> +}
> +
> +static struct snd_ac97_bus_ops compat_snd_ac97_bus_ops = {
> +	.reset = compat_ac97_reset,
> +	.warm_reset = compat_ac97_warm_reset,
> +	.write = compat_ac97_write,
> +	.read = compat_ac97_read,
> +};
> +
> +static struct snd_ac97_bus compat_soc_ac97_bus = {
> +	.ops = &compat_snd_ac97_bus_ops,
> +};
> +
> +struct snd_ac97 *compat_alloc_snd_ac97_codec(struct snd_soc_codec *codec)
> +{
> +	struct snd_ac97 *ac97;
> +
> +	ac97 = kzalloc(sizeof(struct snd_ac97), GFP_KERNEL);
> +	if (ac97 == NULL)
> +		return ERR_PTR(-ENOMEM);
> +
> +	ac97->dev = *codec->dev;
> +	ac97->private_data = codec->dev;
> +	ac97->bus = &compat_soc_ac97_bus;
> +	return ac97;
> +}
> +EXPORT_SYMBOL_GPL(compat_alloc_snd_ac97_codec);
> +
> +void compat_release_snd_ac97_codec(struct snd_ac97 *ac97)
> +{
> +	kfree(ac97);
> +}
> +EXPORT_SYMBOL_GPL(compat_release_snd_ac97_codec);
> +
> +int snd_ac97_reset(struct snd_ac97 *ac97, bool try_warm, unsigned int id,
> +	unsigned int id_mask)
> +{
> +	struct ac97_codec_device *adev = to_ac97_device(ac97->private_data);
> +	struct ac97_controller *actrl = adev->ac97_ctrl;
> +
> +	if (try_warm) {
> +		compat_ac97_warm_reset(ac97);
> +		if (ac97_bus_scan_one(actrl, adev->num) == adev->vendor_id)
> +			return 1;
> +	}
> +
> +	compat_ac97_reset(ac97);
> +	compat_ac97_warm_reset(ac97);
> +	if (ac97_bus_scan_one(actrl, adev->num) == adev->vendor_id)
> +		return 0;
> +
> +	return -ENODEV;
> +}
> +EXPORT_SYMBOL_GPL(snd_ac97_reset);
> -- 
> 2.1.4
> 
> 

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

* [RFC PATCH 2/7] ALSA: ac97: add an ac97 bus
@ 2016-05-09  9:31     ` Takashi Iwai
  0 siblings, 0 replies; 74+ messages in thread
From: Takashi Iwai @ 2016-05-09  9:31 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, 30 Apr 2016 23:15:34 +0200,
Robert Jarzmik wrote:
> 
> diff --git a/include/sound/ac97/codec.h b/include/sound/ac97/codec.h
> new file mode 100644
> index 000000000000..4b8b3e570892
> --- /dev/null
> +++ b/include/sound/ac97/codec.h
> @@ -0,0 +1,98 @@
> +/*
> + *  Copyright (C) 2016 Robert Jarzmik <robert.jarzmik@free.fr>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +#ifndef AC97_CODEC_H
> +#define AC97_CODEC_H

Let's be careful about the choice of the guard.


> +
> +#include <linux/device.h>
> +
> +#define AC97_ID(vendor_id1, vendor_id2) \
> +	(((vendor_id1 & 0xffff) << 16) | (vendor_id2 & 0xffff))
> +#define AC97_DRIVER_ID(vendor_id1, vendor_id2, mask_id1, mask_id2, _data) \
> +	{ .id = ((vendor_id1 & 0xffff) << 16) | (vendor_id2 & 0xffff), \
> +	  .mask = ((mask_id1 & 0xffff) << 16) | (mask_id2 & 0xffff), \
> +	  .data = _data }

Give parentheses around the macro arguments.


> +
> +#define to_ac97_device(d) container_of(d, struct ac97_codec_device, dev)
> +#define to_ac97_driver(d) container_of(d, struct ac97_codec_driver, driver)
> +
> +struct ac97_controller;
> +
> +/**
> + * struct ac97_id - matches a codec device and driver on an ac97 bus
> + * @id: The significant bits if the codec vendor ID1 and ID2
> + * @mask: Bitmask specifying which bits of the id field are significant when
> + *	  matching. A driver binds to a device when :
> + *        ((vendorID1 << 8 | vendorID2) & (mask_id1 << 8 | mask_id2)) == id.
> + * @data: Private data used by the driver.
> + */
> +struct ac97_id {
> +	unsigned int		id;
> +	unsigned int		mask;
> +	void			*data;
> +};
> +
> +/**
> + * ac97_codec_device - a ac97 codec
> + * @dev: the code device
> + * @vendor_id: the vendor_id of the codec, as sensed on the AC-link
> + * @num: the codec number, 0 is primary, 1 is first slave, etc ...
> + * @ac97_ctrl: ac97 digital controller on the same AC-link
> + *
> + * This is the device instanciated for each codec living on a AC-link. There are
> + * normally 0 to 4 codec devices per AC-link, and all of them are controlled by
> + * an AC97 digital controller.
> + */
> +struct ac97_codec_device {
> +	struct device		dev;	/* Must stay first member */

This doesn't have to be the first element as long as you use container_of().


> +	unsigned int		vendor_id;
> +	unsigned int		num;
> +	struct list_head	list;
> +	struct ac97_controller	*ac97_ctrl;
> +};
> +
> +/**
> + * ac97_codec_driver - a ac97 codec driver
> + * @driver: the device driver structure
> + * @probe: the function called when a ac97_codec_device is matched
> + * @remove: the function called when the device is unbound/removed
> + * @suspend: suspend function (might be NULL)
> + * @resume: resume function (might be NULL)
> + * @shutdown: shutdown function (might be NULL)
> + * @id_table: ac97 vendor_id match table, { } member terminated
> + */
> +struct ac97_codec_driver {
> +	struct device_driver	driver;
> +	int			(*probe)(struct ac97_codec_device *);
> +	int			(*remove)(struct ac97_codec_device *);
> +	int			(*suspend)(struct ac97_codec_device *);
> +	int			(*resume)(struct ac97_codec_device *);
> +	void			(*shutdown)(struct ac97_codec_device *);
> +	struct ac97_id		*id_table;

Missing const?

> +};
> +
> +int ac97_codec_driver_register(struct ac97_codec_driver *drv);
> +void ac97_codec_driver_unregister(struct ac97_codec_driver *drv);
> +
> +static inline struct device *
> +ac97_codec_dev2dev(const struct ac97_codec_device *adev)
> +{
> +	return (struct device *)(adev);

What's wrong with the simple &adev->dev ?  Cast looks scary.

> +}
> +
> +static inline void *ac97_get_drvdata(const struct ac97_codec_device *adev)
> +{
> +	return dev_get_drvdata(ac97_codec_dev2dev(adev));
> +}
> +
> +static inline void ac97_set_drvdata(const struct ac97_codec_device *adev,
> +				    void *data)
> +{
> +	dev_set_drvdata(ac97_codec_dev2dev(adev), data);
> +}
> +
> +#endif
> diff --git a/include/sound/ac97/compat.h b/include/sound/ac97/compat.h
> new file mode 100644
> index 000000000000..bf611f572f2d
> --- /dev/null
> +++ b/include/sound/ac97/compat.h
> @@ -0,0 +1,21 @@
> +/*
> + *  Copyright (C) 2016 Robert Jarzmik <robert.jarzmik@free.fr>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * This file is for backward compatibility with snd_ac97 structure and its
> + * multiple usages, such as the snd_ac97_bus and snd_ac97_build_ops.
> + *
> + */
> +#ifndef AC97_COMPAT_H
> +#define AC97_COMPAT_H
> +
> +#include <sound/ac97_codec.h>
> +#include <sound/soc.h>
> +
> +struct snd_ac97 *compat_alloc_snd_ac97_codec(struct snd_soc_codec *codec);
> +void compat_release_snd_ac97_codec(struct snd_ac97 *ac97);
> +
> +#endif
> diff --git a/include/sound/ac97/controller.h b/include/sound/ac97/controller.h
> new file mode 100644
> index 000000000000..f1e5e645f5ef
> --- /dev/null
> +++ b/include/sound/ac97/controller.h
> @@ -0,0 +1,39 @@
> +/*
> + *  Copyright (C) 2016 Robert Jarzmik <robert.jarzmik@free.fr>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +#ifndef AC97_CONTROLLER_H
> +#define AC97_CONTROLLER_H
> +
> +#include <linux/list.h>
> +
> +struct device;
> +struct ac97_codec_device;
> +
> +struct ac97_controller_ops {
> +	void (*reset)(struct ac97_codec_device *ac97);
> +	void (*warm_reset)(struct ac97_codec_device *ac97);
> +	int (*write)(struct ac97_codec_device *ac97, unsigned short reg,
> +		     unsigned short val);
> +	int (*read)(struct ac97_codec_device *ac97, unsigned short reg);
> +	void (*wait)(struct ac97_codec_device *ac97);
> +	void (*init)(struct ac97_codec_device *ac97);
> +};
> +
> +struct ac97_controller {
> +	const struct ac97_controller_ops *ops;
> +	struct list_head controllers;
> +	struct device *dev;
> +	int bus_idx;

What is this bus_idx for?


> +	int bound_codecs;
> +	struct list_head codecs;
> +};
> +
> +int ac97_digital_controller_register(const struct ac97_controller_ops *ops,
> +				     struct device *dev);
> +int ac97_digital_controller_unregister(const struct device *dev);
> +
> +#endif
> diff --git a/sound/ac97/Kconfig b/sound/ac97/Kconfig
> new file mode 100644
> index 000000000000..fd2c2d031e62
> --- /dev/null
> +++ b/sound/ac97/Kconfig
> @@ -0,0 +1,9 @@
> +#
> +# PCI configuration
> +#
 
Still only for PCI? :)


> +
> +config AC97
> +	bool "AC97 bus"
> +	help
> +	   Say Y here if you want to have AC97 devices, which are sound oriented
> +	   devices around an AC-Link.
> diff --git a/sound/ac97/Makefile b/sound/ac97/Makefile
> new file mode 100644
> index 000000000000..5575909d46e2
> --- /dev/null
> +++ b/sound/ac97/Makefile
> @@ -0,0 +1,5 @@
> +#
> +# make for AC97 bus drivers
> +#
> +
> +obj-y	+= bus.o codec.o snd_ac97_compat.o

No possibility for modules?


> diff --git a/sound/ac97/ac97_core.h b/sound/ac97/ac97_core.h
> new file mode 100644
> index 000000000000..db6e27288357
> --- /dev/null
> +++ b/sound/ac97/ac97_core.h
> @@ -0,0 +1,10 @@
> +/*
> + * Copyright (C) 2016 Robert Jarzmik <robert.jarzmik@free.fr>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +unsigned int ac97_bus_scan_one(struct ac97_controller *ac97,
> +			       int codec_num);
> diff --git a/sound/ac97/bus.c b/sound/ac97/bus.c
> new file mode 100644
> index 000000000000..f9bf5632d4aa
> --- /dev/null
> +++ b/sound/ac97/bus.c
> @@ -0,0 +1,330 @@
> +/*
> + * Copyright (C) 2016 Robert Jarzmik <robert.jarzmik@free.fr>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/module.h>
> +#include <linux/device.h>
> +#include <linux/list.h>
> +#include <linux/mutex.h>
> +#include <linux/pm.h>
> +#include <linux/slab.h>
> +#include <sound/ac97/codec.h>
> +#include <sound/ac97/controller.h>
> +#include <sound/ac97/regs.h>
> +
> +#define AC97_BUS_MAX_CODECS 4
> +
> +/*
> + * Protects ac97_controllers and each ac97_controller structure.
> + */
> +static DEFINE_MUTEX(ac97_controllers_mutex);
> +static LIST_HEAD(ac97_controllers);
> +static int ac97_bus_idx;
> +
> +struct bus_type ac97_bus_type;
> +
> +static struct ac97_codec_device *
> +ac97_codec_find(struct ac97_controller *ac97_ctrl, int codec_num)
> +{
> +	struct ac97_codec_device *codec;
> +
> +	list_for_each_entry(codec, &ac97_ctrl->codecs, list)
> +		if (codec->num == codec_num)
> +			return codec;
> +
> +	return NULL;
> +}

It's a question whether we need to manage the codecs in the linked
list.  There can be at most 4 codecs, so it fits in an array well,
too.  Then some codes like this would be simpler. (And it'll even
reduce the footprint, too.)


> +
> +static void ac97_codec_release(struct device *dev)
> +{
> +	struct ac97_codec_device *codec;
> +
> +	codec = container_of(dev, struct ac97_codec_device, dev);
> +	list_del(&codec->list);
> +	kfree(codec);
> +}
> +
> +static int ac97_codec_add(struct ac97_controller *ac97_ctrl, int idx,
> +		   unsigned int vendor_id)
> +{
> +	struct ac97_codec_device *codec;
> +	char *codec_name;
> +	int ret;
> +
> +	codec = kzalloc(sizeof(*codec), GFP_KERNEL);
> +	if (!codec)
> +		return -ENOMEM;
> +
> +	codec->vendor_id = vendor_id;
> +	codec->dev.release = ac97_codec_release;
> +	codec->dev.bus = &ac97_bus_type;
> +	codec->dev.parent = ac97_ctrl->dev;
> +	codec->num = idx;
> +	codec->ac97_ctrl = ac97_ctrl;
> +	INIT_LIST_HEAD(&codec->list);
> +	list_move_tail(&codec->list, &ac97_ctrl->codecs);
> +
> +	codec_name = kasprintf(GFP_KERNEL, "%s:%d", dev_name(ac97_ctrl->dev),
> +			       idx);
> +	codec->dev.init_name = codec_name;
> +
> +	ret = device_register(&codec->dev);
> +	kfree(codec_name);
> +
> +	return ret;
> +}
> +
> +unsigned int ac97_bus_scan_one(struct ac97_controller *ac97,
> +				      int codec_num)
> +{
> +	struct ac97_codec_device codec;
> +	unsigned short vid1, vid2;
> +	int ret;
> +
> +	codec.dev = *ac97->dev;
> +	codec.num = codec_num;
> +	ret = ac97->ops->read(&codec, AC97_VENDOR_ID1);
> +	vid1 = (ret & 0xffff);
> +	if (ret < 0)
> +		return 0;

Hmm.  This looks pretty hackish and dangerous.



> +	ret = ac97->ops->read(&codec, AC97_VENDOR_ID2);
> +	vid2 = (ret & 0xffff);
> +	if (ret < 0)
> +		return 0;
> +
> +	dev_dbg(&codec.dev, "%s(codec_num=%d): vendor_id=0x%08x\n",
> +		__func__, codec_num, AC97_ID(vid1, vid2));
> +	return AC97_ID(vid1, vid2);
> +}
> +
> +static int ac97_bus_scan(struct ac97_controller *ac97_ctrl)
> +{
> +	int ret, i;
> +	unsigned int vendor_id;
> +
> +	for (i = 0; i < AC97_BUS_MAX_CODECS; i++) {
> +		if (ac97_codec_find(ac97_ctrl, i))
> +			continue;
> +		vendor_id = ac97_bus_scan_one(ac97_ctrl, i);
> +		if (!vendor_id)
> +			continue;
> +
> +		ret = ac97_codec_add(ac97_ctrl, i, vendor_id);
> +		if (ret < 0)
> +			return ret;

This is one of concerns: we don't know whether the device really
reacts well if you access to a non-existing slot.  At least, it'd be
safer to have the masks for the devices we already know the slots.


> +	}
> +	return 0;
> +}
> +
> +void ac97_rescan_all_controllers(void)
> +{
> +	struct ac97_controller *ac97_ctrl;
> +	int ret;
> +
> +	mutex_lock(&ac97_controllers_mutex);
> +	list_for_each_entry(ac97_ctrl, &ac97_controllers, controllers) {
> +		ret = ac97_bus_scan(ac97_ctrl);
> +		if (ret)
> +			dev_warn(ac97_ctrl->dev, "scan failed: %d\n", ret);
> +	}
> +	mutex_unlock(&ac97_controllers_mutex);
> +}
> +EXPORT_SYMBOL(ac97_rescan_all_controllers);
> +
> +static int ac97_bus_reset(struct ac97_controller *ac97_ctrl)
> +{
> +	struct ac97_codec_device codec;
> +
> +	memset(&codec, 0, sizeof(codec));
> +	codec.dev = *ac97_ctrl->dev;
> +
> +	ac97_ctrl->ops->reset(&codec);

So, this assumes that reset ops is mandatory?  Then document it at
least.


thanks,

Takashi

> +	return 0;
> +}
> +
> +/**
> + * ac97_codec_driver_register - register an AC97 codec driver
> + * @dev: AC97 driver codec to register
> + *
> + * Register an AC97 codec driver to the ac97 bus driver, aka. the AC97 digital
> + * controller.
> + *
> + * Returns 0 on success or error code
> + */
> +int ac97_codec_driver_register(struct ac97_codec_driver *drv)
> +{
> +	int ret;
> +
> +	drv->driver.bus = &ac97_bus_type;
> +
> +	ret = driver_register(&drv->driver);
> +	if (!ret)
> +		ac97_rescan_all_controllers();
> +
> +	return ret;
> +}
> +EXPORT_SYMBOL(ac97_codec_driver_register);
> +
> +/**
> + * ac97_codec_driver_unregister - unregister an AC97 codec driver
> + * @dev: AC97 codec driver to unregister
> + *
> + * Unregister a previously registered ac97 codec driver.
> + */
> +void ac97_codec_driver_unregister(struct ac97_codec_driver *drv)
> +{
> +	driver_unregister(&drv->driver);
> +}
> +EXPORT_SYMBOL(ac97_codec_driver_unregister);
> +
> +static int ac97_dc_codecs_unregister(struct ac97_controller *ac97_ctrl)
> +{
> +	struct ac97_codec_device *codec, *tmp;
> +
> +	list_for_each_entry_safe(codec, tmp, &ac97_ctrl->codecs, list)
> +		put_device(&codec->dev);
> +
> +	return 0;
> +}
> +
> +/**
> + * ac97_digital_controller_register - register an ac97 controller
> + * @ops: the ac97 bus operations
> + * @dev: the device providing the ac97 DC function
> + *
> + * Register a digital controller which can control up to 4 ac97 codecs. This is
> + * the controller side of the AC97 AC-link, while the slave side are the codecs.
> + *
> + * Returns a positive bus index upon success, negative value upon error
> + */
> +int ac97_digital_controller_register(const struct ac97_controller_ops *ops,
> +				     struct device *dev)
> +{
> +	struct ac97_controller *ac97_ctrl;
> +
> +	ac97_ctrl = kzalloc(sizeof(*ac97_ctrl), GFP_KERNEL);
> +	if (!ac97_ctrl)
> +		return -ENOMEM;
> +
> +	mutex_lock(&ac97_controllers_mutex);
> +	ac97_ctrl->ops = ops;
> +	ac97_ctrl->bus_idx = ac97_bus_idx++;
> +	ac97_ctrl->dev = dev;
> +	INIT_LIST_HEAD(&ac97_ctrl->codecs);
> +	list_add(&ac97_ctrl->controllers, &ac97_controllers);
> +	mutex_unlock(&ac97_controllers_mutex);
> +
> +	ac97_bus_reset(ac97_ctrl);
> +	ac97_bus_scan(ac97_ctrl);
> +
> +	return ac97_ctrl->bus_idx;
> +}
> +EXPORT_SYMBOL(ac97_digital_controller_register);
> +
> +/**
> + * ac97_digital_controller_unregister - unregister an ac97 controller
> + * @dev: the device previously provided to ac97_digital_controller_register()
> + *
> + * Returns 0 on success, negative upon error
> + */
> +int ac97_digital_controller_unregister(const struct device *dev)
> +{
> +	struct ac97_controller *ac97_ctrl, *tmp;
> +	int ret = -ENODEV;
> +
> +	mutex_lock(&ac97_controllers_mutex);
> +	list_for_each_entry_safe(ac97_ctrl, tmp, &ac97_controllers,
> +				 controllers) {
> +		if (ac97_ctrl->dev != dev)
> +			continue;
> +		if (ac97_ctrl->bound_codecs)
> +			ret = -EBUSY;
> +		else
> +			ret = ac97_dc_codecs_unregister(ac97_ctrl);
> +		if (!ret)
> +			list_del(&ac97_ctrl->controllers);
> +	}
> +
> +	mutex_unlock(&ac97_controllers_mutex);
> +	return ret;
> +}
> +EXPORT_SYMBOL(ac97_digital_controller_unregister);
> +
> +static const struct dev_pm_ops ac97_pm = {
> +	.suspend	= pm_generic_suspend,
> +	.resume		= pm_generic_resume,
> +	.freeze		= pm_generic_freeze,
> +	.thaw		= pm_generic_thaw,
> +	.poweroff	= pm_generic_poweroff,
> +	.restore	= pm_generic_restore,
> +};
> +
> +static ssize_t vendor_id_show(struct device *dev,
> +			      struct device_attribute *attr, char *buf)
> +{
> +	struct ac97_codec_device *codec = to_ac97_device(dev);
> +
> +	return sprintf(buf, "%08x", codec->vendor_id);
> +}
> +
> +static struct device_attribute ac97_dev_attrs[] = {
> +	__ATTR_RO(vendor_id),
> +	__ATTR_NULL,
> +};
> +
> +int ac97_bus_match(struct device *dev, struct device_driver *drv)
> +{
> +	struct ac97_codec_device *adev = to_ac97_device(dev);
> +	struct ac97_codec_driver *adrv = to_ac97_driver(drv);
> +	struct ac97_id *id = adrv->id_table;
> +
> +	if (adev->vendor_id == 0x0 || adev->vendor_id == 0xffffffff)
> +		return false;
> +
> +	do {
> +		if ((id->id & id->mask) == (adev->vendor_id & id->mask))
> +			return true;
> +	} while (++id->id);
> +
> +	return false;
> +}
> +
> +static int ac97_bus_probe(struct device *dev)
> +{
> +	struct ac97_codec_device *adev = to_ac97_device(dev);
> +	struct ac97_codec_driver *adrv = to_ac97_driver(dev->driver);
> +
> +	return adrv->probe(adev);
> +}
> +
> +static int ac97_bus_remove(struct device *dev)
> +{
> +	struct ac97_codec_device *adev = to_ac97_device(dev);
> +	struct ac97_codec_driver *adrv = to_ac97_driver(dev->driver);
> +
> +	return adrv->remove(adev);
> +}
> +
> +struct bus_type ac97_bus_type = {
> +	.name		= "ac97",
> +	.dev_attrs	= ac97_dev_attrs,
> +	.match		= ac97_bus_match,
> +	.pm		= &ac97_pm,
> +	.probe		= ac97_bus_probe,
> +	.remove		= ac97_bus_remove,
> +};
> +EXPORT_SYMBOL(ac97_bus_type);
> +
> +static int __init ac97_bus_init(void)
> +{
> +	return bus_register(&ac97_bus_type);
> +}
> +subsys_initcall(ac97_bus_init);
> +
> +MODULE_LICENSE("GPL");
> +MODULE_AUTHOR("Robert Jarzmik <robert.jarzmik@free.fr>");
> diff --git a/sound/ac97/codec.c b/sound/ac97/codec.c
> new file mode 100644
> index 000000000000..a835f03744bf
> --- /dev/null
> +++ b/sound/ac97/codec.c
> @@ -0,0 +1,15 @@
> +/*
> + *  Copyright (C) 2016 Robert Jarzmik <robert.jarzmik@free.fr>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <sound/ac97_codec.h>
> +#include <sound/ac97/codec.h>
> +#include <sound/ac97/controller.h>
> +#include <linux/device.h>
> +#include <linux/slab.h>
> +#include <sound/soc.h>	/* For compat_ac97_* */
> +
> diff --git a/sound/ac97/snd_ac97_compat.c b/sound/ac97/snd_ac97_compat.c
> new file mode 100644
> index 000000000000..7e2f01c96fc9
> --- /dev/null
> +++ b/sound/ac97/snd_ac97_compat.c
> @@ -0,0 +1,104 @@
> +/*
> + *  Copyright (C) 2016 Robert Jarzmik <robert.jarzmik@free.fr>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/list.h>
> +#include <linux/slab.h>
> +#include <sound/ac97/codec.h>
> +#include <sound/ac97/controller.h>
> +#include <sound/soc.h>
> +
> +#include "ac97_core.h"
> +
> +static void compat_ac97_reset(struct snd_ac97 *ac97)
> +{
> +	struct ac97_codec_device *adev = to_ac97_device(ac97->private_data);
> +	struct ac97_controller *actrl = adev->ac97_ctrl;
> +
> +	if (actrl->ops->reset)
> +		actrl->ops->reset(adev);
> +}
> +
> +static void compat_ac97_warm_reset(struct snd_ac97 *ac97)
> +{
> +	struct ac97_codec_device *adev = to_ac97_device(ac97->private_data);
> +	struct ac97_controller *actrl = adev->ac97_ctrl;
> +
> +	if (actrl->ops->warm_reset)
> +		actrl->ops->warm_reset(adev);
> +}
> +
> +static void compat_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
> +			      unsigned short val)
> +{
> +	struct ac97_codec_device *adev = to_ac97_device(ac97->private_data);
> +	struct ac97_controller *actrl = adev->ac97_ctrl;
> +
> +	actrl->ops->write(adev, reg, val);
> +}
> +
> +static unsigned short compat_ac97_read(struct snd_ac97 *ac97,
> +				       unsigned short reg)
> +{
> +	struct ac97_codec_device *adev = to_ac97_device(ac97->private_data);
> +	struct ac97_controller *actrl = adev->ac97_ctrl;
> +
> +	return actrl->ops->read(adev, reg);
> +}
> +
> +static struct snd_ac97_bus_ops compat_snd_ac97_bus_ops = {
> +	.reset = compat_ac97_reset,
> +	.warm_reset = compat_ac97_warm_reset,
> +	.write = compat_ac97_write,
> +	.read = compat_ac97_read,
> +};
> +
> +static struct snd_ac97_bus compat_soc_ac97_bus = {
> +	.ops = &compat_snd_ac97_bus_ops,
> +};
> +
> +struct snd_ac97 *compat_alloc_snd_ac97_codec(struct snd_soc_codec *codec)
> +{
> +	struct snd_ac97 *ac97;
> +
> +	ac97 = kzalloc(sizeof(struct snd_ac97), GFP_KERNEL);
> +	if (ac97 == NULL)
> +		return ERR_PTR(-ENOMEM);
> +
> +	ac97->dev = *codec->dev;
> +	ac97->private_data = codec->dev;
> +	ac97->bus = &compat_soc_ac97_bus;
> +	return ac97;
> +}
> +EXPORT_SYMBOL_GPL(compat_alloc_snd_ac97_codec);
> +
> +void compat_release_snd_ac97_codec(struct snd_ac97 *ac97)
> +{
> +	kfree(ac97);
> +}
> +EXPORT_SYMBOL_GPL(compat_release_snd_ac97_codec);
> +
> +int snd_ac97_reset(struct snd_ac97 *ac97, bool try_warm, unsigned int id,
> +	unsigned int id_mask)
> +{
> +	struct ac97_codec_device *adev = to_ac97_device(ac97->private_data);
> +	struct ac97_controller *actrl = adev->ac97_ctrl;
> +
> +	if (try_warm) {
> +		compat_ac97_warm_reset(ac97);
> +		if (ac97_bus_scan_one(actrl, adev->num) == adev->vendor_id)
> +			return 1;
> +	}
> +
> +	compat_ac97_reset(ac97);
> +	compat_ac97_warm_reset(ac97);
> +	if (ac97_bus_scan_one(actrl, adev->num) == adev->vendor_id)
> +		return 0;
> +
> +	return -ENODEV;
> +}
> +EXPORT_SYMBOL_GPL(snd_ac97_reset);
> -- 
> 2.1.4
> 
> 

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

* Re: [RFC PATCH 0/7] AC97 device/driver model revamp
  2016-05-09  9:04   ` Takashi Iwai
  (?)
@ 2016-05-14  8:13     ` Robert Jarzmik
  -1 siblings, 0 replies; 74+ messages in thread
From: Robert Jarzmik @ 2016-05-14  8:13 UTC (permalink / raw)
  To: Takashi Iwai
  Cc: Haojian Zhuang, Liam Girdwood, Mark Brown, Jaroslav Kysela,
	Daniel Mack, alsa-devel, linux-arm-kernel, patches, linux-kernel

Takashi Iwai <tiwai@suse.de> writes:

> On Sat, 30 Apr 2016 23:15:32 +0200,
> Robert Jarzmik wrote:
>> 
>> Well, this is a long term effort, which might need a complete rewrite according
>> to the comments it'll get. Let's expose it for comments and see how I can
>> progress with it.
>
> I think it's good in general.  The implementation looks fairly simple
> and thin enough.
Thanks.

> An open question is whether migrating the former AC97 layer into the
> new bus.  I'm not sure about this.  Transition to a new layer always
> brings subtle bugs, especially when the target devices are in wide
> range of legacy ones...   If any, we should start just wrapping via
> the new bus ops.
I agree, the migration to the new layer will bring bugs. And the test might be
impossible to carry out by lack of testers.

The wrapping of bus operations is the goal of sound/ac97/snd_ac97_compat.c.

> Some other nitpicks:
> - We usually use snd_ prefix for sound stuff.  Better to keep this for
>   exported symbols at least.
Of course, for RFC v2.

> - I don't see much value in the usefulness of compat_* stuff.
That's mainly the bus operation wrapping and backward compatibility. The idea is
to be able to convert only the probing/removal/suspend/resume of an ac97 codec
or controller without changing its main code in a first patch, and then consider
surgery (if applicable) to convert it wholly.

>   For example, it doesn't cover the actual reset procedure or such
>   done as in the old ac97 code.
Ah then my code is incomplete and I must work on it.

For the reset procedure I have ported snd_ac97_reset(), as well as the
snd_ac97_us_ops operation wrappers. Would you give me an example of the reset
I'm missing (a file and a function) ?

> So it won't work compatibly.  If it's a few lines of changes, the direct call
> would be likely simpler in the end.

>
> - The order of patches needs reconsideration.  The current patchset
>   will break the build, as the hook to sound/ac97/* is done in the
>   last patch, while you're already building against to the new stuff
>   beforehand.
Very true. kbuild robot objected as well :) For RFC v2.

Cheers.

-- 
Robert

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

* Re: [RFC PATCH 0/7] AC97 device/driver model revamp
@ 2016-05-14  8:13     ` Robert Jarzmik
  0 siblings, 0 replies; 74+ messages in thread
From: Robert Jarzmik @ 2016-05-14  8:13 UTC (permalink / raw)
  To: Takashi Iwai
  Cc: alsa-devel, linux-kernel, patches, Liam Girdwood, Haojian Zhuang,
	Mark Brown, linux-arm-kernel, Daniel Mack

Takashi Iwai <tiwai@suse.de> writes:

> On Sat, 30 Apr 2016 23:15:32 +0200,
> Robert Jarzmik wrote:
>> 
>> Well, this is a long term effort, which might need a complete rewrite according
>> to the comments it'll get. Let's expose it for comments and see how I can
>> progress with it.
>
> I think it's good in general.  The implementation looks fairly simple
> and thin enough.
Thanks.

> An open question is whether migrating the former AC97 layer into the
> new bus.  I'm not sure about this.  Transition to a new layer always
> brings subtle bugs, especially when the target devices are in wide
> range of legacy ones...   If any, we should start just wrapping via
> the new bus ops.
I agree, the migration to the new layer will bring bugs. And the test might be
impossible to carry out by lack of testers.

The wrapping of bus operations is the goal of sound/ac97/snd_ac97_compat.c.

> Some other nitpicks:
> - We usually use snd_ prefix for sound stuff.  Better to keep this for
>   exported symbols at least.
Of course, for RFC v2.

> - I don't see much value in the usefulness of compat_* stuff.
That's mainly the bus operation wrapping and backward compatibility. The idea is
to be able to convert only the probing/removal/suspend/resume of an ac97 codec
or controller without changing its main code in a first patch, and then consider
surgery (if applicable) to convert it wholly.

>   For example, it doesn't cover the actual reset procedure or such
>   done as in the old ac97 code.
Ah then my code is incomplete and I must work on it.

For the reset procedure I have ported snd_ac97_reset(), as well as the
snd_ac97_us_ops operation wrappers. Would you give me an example of the reset
I'm missing (a file and a function) ?

> So it won't work compatibly.  If it's a few lines of changes, the direct call
> would be likely simpler in the end.

>
> - The order of patches needs reconsideration.  The current patchset
>   will break the build, as the hook to sound/ac97/* is done in the
>   last patch, while you're already building against to the new stuff
>   beforehand.
Very true. kbuild robot objected as well :) For RFC v2.

Cheers.

-- 
Robert

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

* [RFC PATCH 0/7] AC97 device/driver model revamp
@ 2016-05-14  8:13     ` Robert Jarzmik
  0 siblings, 0 replies; 74+ messages in thread
From: Robert Jarzmik @ 2016-05-14  8:13 UTC (permalink / raw)
  To: linux-arm-kernel

Takashi Iwai <tiwai@suse.de> writes:

> On Sat, 30 Apr 2016 23:15:32 +0200,
> Robert Jarzmik wrote:
>> 
>> Well, this is a long term effort, which might need a complete rewrite according
>> to the comments it'll get. Let's expose it for comments and see how I can
>> progress with it.
>
> I think it's good in general.  The implementation looks fairly simple
> and thin enough.
Thanks.

> An open question is whether migrating the former AC97 layer into the
> new bus.  I'm not sure about this.  Transition to a new layer always
> brings subtle bugs, especially when the target devices are in wide
> range of legacy ones...   If any, we should start just wrapping via
> the new bus ops.
I agree, the migration to the new layer will bring bugs. And the test might be
impossible to carry out by lack of testers.

The wrapping of bus operations is the goal of sound/ac97/snd_ac97_compat.c.

> Some other nitpicks:
> - We usually use snd_ prefix for sound stuff.  Better to keep this for
>   exported symbols at least.
Of course, for RFC v2.

> - I don't see much value in the usefulness of compat_* stuff.
That's mainly the bus operation wrapping and backward compatibility. The idea is
to be able to convert only the probing/removal/suspend/resume of an ac97 codec
or controller without changing its main code in a first patch, and then consider
surgery (if applicable) to convert it wholly.

>   For example, it doesn't cover the actual reset procedure or such
>   done as in the old ac97 code.
Ah then my code is incomplete and I must work on it.

For the reset procedure I have ported snd_ac97_reset(), as well as the
snd_ac97_us_ops operation wrappers. Would you give me an example of the reset
I'm missing (a file and a function) ?

> So it won't work compatibly.  If it's a few lines of changes, the direct call
> would be likely simpler in the end.

>
> - The order of patches needs reconsideration.  The current patchset
>   will break the build, as the hook to sound/ac97/* is done in the
>   last patch, while you're already building against to the new stuff
>   beforehand.
Very true. kbuild robot objected as well :) For RFC v2.

Cheers.

-- 
Robert

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

* Re: [RFC PATCH 2/7] ALSA: ac97: add an ac97 bus
  2016-05-09  9:31     ` Takashi Iwai
  (?)
@ 2016-05-14  9:50       ` Robert Jarzmik
  -1 siblings, 0 replies; 74+ messages in thread
From: Robert Jarzmik @ 2016-05-14  9:50 UTC (permalink / raw)
  To: Takashi Iwai
  Cc: Haojian Zhuang, Liam Girdwood, Mark Brown, Jaroslav Kysela,
	Daniel Mack, alsa-devel, linux-arm-kernel, patches, linux-kernel

Takashi Iwai <tiwai@suse.de> writes:

> On Sat, 30 Apr 2016 23:15:34 +0200,
> Robert Jarzmik wrote:
>> 
>> diff --git a/include/sound/ac97/codec.h b/include/sound/ac97/codec.h
>> new file mode 100644
>> index 000000000000..4b8b3e570892
>> --- /dev/null
>> +++ b/include/sound/ac97/codec.h
>> @@ -0,0 +1,98 @@
>> +/*
>> + *  Copyright (C) 2016 Robert Jarzmik <robert.jarzmik@free.fr>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2 as
>> + * published by the Free Software Foundation.
>> + */
>> +#ifndef AC97_CODEC_H
>> +#define AC97_CODEC_H
>
> Let's be careful about the choice of the guard.
Ok, would _SND_AC97_CODEC_H be better ?

>> +#define AC97_ID(vendor_id1, vendor_id2) \
>> +	(((vendor_id1 & 0xffff) << 16) | (vendor_id2 & 0xffff))
>> +#define AC97_DRIVER_ID(vendor_id1, vendor_id2, mask_id1, mask_id2, _data) \
>> +	{ .id = ((vendor_id1 & 0xffff) << 16) | (vendor_id2 & 0xffff), \
>> +	  .mask = ((mask_id1 & 0xffff) << 16) | (mask_id2 & 0xffff), \
>> +	  .data = _data }
>
> Give parentheses around the macro arguments.
Right, for RFC v2.

>> +struct ac97_codec_device {
>> +	struct device		dev;	/* Must stay first member */
>
> This doesn't have to be the first element as long as you use container_of().
Ah yes, that's a leftover from a former idea, I'll remove that comment.

In the initial code I'd done "struct ac97_codec_device" was hidden from this
file (ie. there was only a "struct ac97_codec_device;" statement), the body of
the struct was contained in sound/ac97/ac97_core.h.

The only provided macro to access the "struct device" inside "struct
ac97_codec_device" was relying on this "trick" (that's a bit like in the
video4linux area).

Anyway, good point, I'll remove that.

>> +struct ac97_codec_driver {
>> +	struct device_driver	driver;
>> +	int			(*probe)(struct ac97_codec_device *);
>> +	int			(*remove)(struct ac97_codec_device *);
>> +	int			(*suspend)(struct ac97_codec_device *);
>> +	int			(*resume)(struct ac97_codec_device *);
>> +	void			(*shutdown)(struct ac97_codec_device *);
>> +	struct ac97_id		*id_table;
>
> Missing const?
Ah no, unfortunately not, or rather not yet.

I tried that one, not very hard, but at least ac97_bus_match() with the pair
"struct ac97_id *id = adrv->id_table" and "do { } while (++id->id);" is not
possible AFAIK with a const.

I will see if I can come up with something better for ac97_bus_match, such as
array usage instead of pointer arithmetics.

>> +};
>> +
>> +int ac97_codec_driver_register(struct ac97_codec_driver *drv);
>> +void ac97_codec_driver_unregister(struct ac97_codec_driver *drv);
>> +
>> +static inline struct device *
>> +ac97_codec_dev2dev(const struct ac97_codec_device *adev)
>> +{
>> +	return (struct device *)(adev);
>
> What's wrong with the simple &adev->dev ?  Cast looks scary.
The same leftover than above, I'll change that for RFC v2.

>> +struct ac97_controller {
>> +	const struct ac97_controller_ops *ops;
>> +	struct list_head controllers;
>> +	struct device *dev;
>> +	int bus_idx;
>
> What is this bus_idx for?
Initially it was to distinguish 2 different AC97 controllers. In the current
patchset state, it's not usefull anymore AFAICS.
So let's remove it.

>> +	int bound_codecs;
The same comment would apply here. I don't think that information is important
anymore. I thought I would use that to prevent AC97 controler removal while
codecs are still bound.

In a second thought what would be better is to have get_device() called for each
bound codec which will prevent ac97_digital_controller_unregister() to succeed
(-EBUSY).

>> +	struct list_head codecs;
>> +};
>> +
>> +int ac97_digital_controller_register(const struct ac97_controller_ops *ops,
>> +				     struct device *dev);
>> +int ac97_digital_controller_unregister(const struct device *dev);
>> +
>> +#endif
>> diff --git a/sound/ac97/Kconfig b/sound/ac97/Kconfig
>> new file mode 100644
>> index 000000000000..fd2c2d031e62
>> --- /dev/null
>> +++ b/sound/ac97/Kconfig
>> @@ -0,0 +1,9 @@
>> +#
>> +# PCI configuration
>> +#
>  
> Still only for PCI? :)
Ouch ;) I'll amend that for RFC v2.
>
>> +
>> +config AC97
>> +	bool "AC97 bus"
>> +	help
>> +	   Say Y here if you want to have AC97 devices, which are sound oriented
>> +	   devices around an AC-Link.
>> diff --git a/sound/ac97/Makefile b/sound/ac97/Makefile
>> new file mode 100644
>> index 000000000000..5575909d46e2
>> --- /dev/null
>> +++ b/sound/ac97/Makefile
>> @@ -0,0 +1,5 @@
>> +#
>> +# make for AC97 bus drivers
>> +#
>> +
>> +obj-y	+= bus.o codec.o snd_ac97_compat.o
>
> No possibility for modules?
There should be, so I'll put that on my TODO list for RFC v2.

>> +static struct ac97_codec_device *
>> +ac97_codec_find(struct ac97_controller *ac97_ctrl, int codec_num)
>> +{
>> +	struct ac97_codec_device *codec;
>> +
>> +	list_for_each_entry(codec, &ac97_ctrl->codecs, list)
>> +		if (codec->num == codec_num)
>> +			return codec;
>> +
>> +	return NULL;
>> +}
>
> It's a question whether we need to manage the codecs in the linked
> list.  There can be at most 4 codecs, so it fits in an array well,
> too.  Then some codes like this would be simpler. (And it'll even
> reduce the footprint, too.)
Agreed. For RFC v2.

>> +unsigned int ac97_bus_scan_one(struct ac97_controller *ac97,
>> +				      int codec_num)
>> +{
>> +	struct ac97_codec_device codec;
>> +	unsigned short vid1, vid2;
>> +	int ret;
>> +
>> +	codec.dev = *ac97->dev;
>> +	codec.num = codec_num;
>> +	ret = ac97->ops->read(&codec, AC97_VENDOR_ID1);
>> +	vid1 = (ret & 0xffff);
>> +	if (ret < 0)
>> +		return 0;
>
> Hmm.  This looks pretty hackish and dangerous.
You mean returning 0 even if the read failed, right ?
A better prototype would probably be (for RFC v2):
  int ac97_bus_scan_one(struct ac97_controller *ac97, int codec_num,
                        unsigned int *vendor_id);

>> +static int ac97_bus_scan(struct ac97_controller *ac97_ctrl)
>> +{
>> +	int ret, i;
>> +	unsigned int vendor_id;
>> +
>> +	for (i = 0; i < AC97_BUS_MAX_CODECS; i++) {
>> +		if (ac97_codec_find(ac97_ctrl, i))
>> +			continue;
>> +		vendor_id = ac97_bus_scan_one(ac97_ctrl, i);
>> +		if (!vendor_id)
>> +			continue;
>> +
>> +		ret = ac97_codec_add(ac97_ctrl, i, vendor_id);
>> +		if (ret < 0)
>> +			return ret;
>
> This is one of concerns: we don't know whether the device really
> reacts well if you access to a non-existing slot.  At least, it'd be
> safer to have the masks for the devices we already know the slots.

Ah you mean upon ac97 controller registration, the
ac97_digital_controller_register() should provide the information for each of
the 4 slots :
 - does the controller enable this slot (default yes)
 - does the controller support auto-scan for this slot (default yes)
   I'm not sure this "feature" is required, it looks a bit over-engineered.

That could be a matter of 1 or 2 masks as input parameters to
ac97_digital_controller_register().

>> +static int ac97_bus_reset(struct ac97_controller *ac97_ctrl)
>> +{
>> +	struct ac97_codec_device codec;
>> +
>> +	memset(&codec, 0, sizeof(codec));
>> +	codec.dev = *ac97_ctrl->dev;
>> +
>> +	ac97_ctrl->ops->reset(&codec);
>
> So, this assumes that reset ops is mandatory?  Then document it at
> least.
Ok, for RFC v2.

Thanks for your review and feedbacks Takashi, I'll work on both Mark and your
comments in the next weeks.

Cheers.

-- 
Robert

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

* Re: [RFC PATCH 2/7] ALSA: ac97: add an ac97 bus
@ 2016-05-14  9:50       ` Robert Jarzmik
  0 siblings, 0 replies; 74+ messages in thread
From: Robert Jarzmik @ 2016-05-14  9:50 UTC (permalink / raw)
  To: Takashi Iwai
  Cc: alsa-devel, linux-kernel, patches, Liam Girdwood, Haojian Zhuang,
	Mark Brown, linux-arm-kernel, Daniel Mack

Takashi Iwai <tiwai@suse.de> writes:

> On Sat, 30 Apr 2016 23:15:34 +0200,
> Robert Jarzmik wrote:
>> 
>> diff --git a/include/sound/ac97/codec.h b/include/sound/ac97/codec.h
>> new file mode 100644
>> index 000000000000..4b8b3e570892
>> --- /dev/null
>> +++ b/include/sound/ac97/codec.h
>> @@ -0,0 +1,98 @@
>> +/*
>> + *  Copyright (C) 2016 Robert Jarzmik <robert.jarzmik@free.fr>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2 as
>> + * published by the Free Software Foundation.
>> + */
>> +#ifndef AC97_CODEC_H
>> +#define AC97_CODEC_H
>
> Let's be careful about the choice of the guard.
Ok, would _SND_AC97_CODEC_H be better ?

>> +#define AC97_ID(vendor_id1, vendor_id2) \
>> +	(((vendor_id1 & 0xffff) << 16) | (vendor_id2 & 0xffff))
>> +#define AC97_DRIVER_ID(vendor_id1, vendor_id2, mask_id1, mask_id2, _data) \
>> +	{ .id = ((vendor_id1 & 0xffff) << 16) | (vendor_id2 & 0xffff), \
>> +	  .mask = ((mask_id1 & 0xffff) << 16) | (mask_id2 & 0xffff), \
>> +	  .data = _data }
>
> Give parentheses around the macro arguments.
Right, for RFC v2.

>> +struct ac97_codec_device {
>> +	struct device		dev;	/* Must stay first member */
>
> This doesn't have to be the first element as long as you use container_of().
Ah yes, that's a leftover from a former idea, I'll remove that comment.

In the initial code I'd done "struct ac97_codec_device" was hidden from this
file (ie. there was only a "struct ac97_codec_device;" statement), the body of
the struct was contained in sound/ac97/ac97_core.h.

The only provided macro to access the "struct device" inside "struct
ac97_codec_device" was relying on this "trick" (that's a bit like in the
video4linux area).

Anyway, good point, I'll remove that.

>> +struct ac97_codec_driver {
>> +	struct device_driver	driver;
>> +	int			(*probe)(struct ac97_codec_device *);
>> +	int			(*remove)(struct ac97_codec_device *);
>> +	int			(*suspend)(struct ac97_codec_device *);
>> +	int			(*resume)(struct ac97_codec_device *);
>> +	void			(*shutdown)(struct ac97_codec_device *);
>> +	struct ac97_id		*id_table;
>
> Missing const?
Ah no, unfortunately not, or rather not yet.

I tried that one, not very hard, but at least ac97_bus_match() with the pair
"struct ac97_id *id = adrv->id_table" and "do { } while (++id->id);" is not
possible AFAIK with a const.

I will see if I can come up with something better for ac97_bus_match, such as
array usage instead of pointer arithmetics.

>> +};
>> +
>> +int ac97_codec_driver_register(struct ac97_codec_driver *drv);
>> +void ac97_codec_driver_unregister(struct ac97_codec_driver *drv);
>> +
>> +static inline struct device *
>> +ac97_codec_dev2dev(const struct ac97_codec_device *adev)
>> +{
>> +	return (struct device *)(adev);
>
> What's wrong with the simple &adev->dev ?  Cast looks scary.
The same leftover than above, I'll change that for RFC v2.

>> +struct ac97_controller {
>> +	const struct ac97_controller_ops *ops;
>> +	struct list_head controllers;
>> +	struct device *dev;
>> +	int bus_idx;
>
> What is this bus_idx for?
Initially it was to distinguish 2 different AC97 controllers. In the current
patchset state, it's not usefull anymore AFAICS.
So let's remove it.

>> +	int bound_codecs;
The same comment would apply here. I don't think that information is important
anymore. I thought I would use that to prevent AC97 controler removal while
codecs are still bound.

In a second thought what would be better is to have get_device() called for each
bound codec which will prevent ac97_digital_controller_unregister() to succeed
(-EBUSY).

>> +	struct list_head codecs;
>> +};
>> +
>> +int ac97_digital_controller_register(const struct ac97_controller_ops *ops,
>> +				     struct device *dev);
>> +int ac97_digital_controller_unregister(const struct device *dev);
>> +
>> +#endif
>> diff --git a/sound/ac97/Kconfig b/sound/ac97/Kconfig
>> new file mode 100644
>> index 000000000000..fd2c2d031e62
>> --- /dev/null
>> +++ b/sound/ac97/Kconfig
>> @@ -0,0 +1,9 @@
>> +#
>> +# PCI configuration
>> +#
>  
> Still only for PCI? :)
Ouch ;) I'll amend that for RFC v2.
>
>> +
>> +config AC97
>> +	bool "AC97 bus"
>> +	help
>> +	   Say Y here if you want to have AC97 devices, which are sound oriented
>> +	   devices around an AC-Link.
>> diff --git a/sound/ac97/Makefile b/sound/ac97/Makefile
>> new file mode 100644
>> index 000000000000..5575909d46e2
>> --- /dev/null
>> +++ b/sound/ac97/Makefile
>> @@ -0,0 +1,5 @@
>> +#
>> +# make for AC97 bus drivers
>> +#
>> +
>> +obj-y	+= bus.o codec.o snd_ac97_compat.o
>
> No possibility for modules?
There should be, so I'll put that on my TODO list for RFC v2.

>> +static struct ac97_codec_device *
>> +ac97_codec_find(struct ac97_controller *ac97_ctrl, int codec_num)
>> +{
>> +	struct ac97_codec_device *codec;
>> +
>> +	list_for_each_entry(codec, &ac97_ctrl->codecs, list)
>> +		if (codec->num == codec_num)
>> +			return codec;
>> +
>> +	return NULL;
>> +}
>
> It's a question whether we need to manage the codecs in the linked
> list.  There can be at most 4 codecs, so it fits in an array well,
> too.  Then some codes like this would be simpler. (And it'll even
> reduce the footprint, too.)
Agreed. For RFC v2.

>> +unsigned int ac97_bus_scan_one(struct ac97_controller *ac97,
>> +				      int codec_num)
>> +{
>> +	struct ac97_codec_device codec;
>> +	unsigned short vid1, vid2;
>> +	int ret;
>> +
>> +	codec.dev = *ac97->dev;
>> +	codec.num = codec_num;
>> +	ret = ac97->ops->read(&codec, AC97_VENDOR_ID1);
>> +	vid1 = (ret & 0xffff);
>> +	if (ret < 0)
>> +		return 0;
>
> Hmm.  This looks pretty hackish and dangerous.
You mean returning 0 even if the read failed, right ?
A better prototype would probably be (for RFC v2):
  int ac97_bus_scan_one(struct ac97_controller *ac97, int codec_num,
                        unsigned int *vendor_id);

>> +static int ac97_bus_scan(struct ac97_controller *ac97_ctrl)
>> +{
>> +	int ret, i;
>> +	unsigned int vendor_id;
>> +
>> +	for (i = 0; i < AC97_BUS_MAX_CODECS; i++) {
>> +		if (ac97_codec_find(ac97_ctrl, i))
>> +			continue;
>> +		vendor_id = ac97_bus_scan_one(ac97_ctrl, i);
>> +		if (!vendor_id)
>> +			continue;
>> +
>> +		ret = ac97_codec_add(ac97_ctrl, i, vendor_id);
>> +		if (ret < 0)
>> +			return ret;
>
> This is one of concerns: we don't know whether the device really
> reacts well if you access to a non-existing slot.  At least, it'd be
> safer to have the masks for the devices we already know the slots.

Ah you mean upon ac97 controller registration, the
ac97_digital_controller_register() should provide the information for each of
the 4 slots :
 - does the controller enable this slot (default yes)
 - does the controller support auto-scan for this slot (default yes)
   I'm not sure this "feature" is required, it looks a bit over-engineered.

That could be a matter of 1 or 2 masks as input parameters to
ac97_digital_controller_register().

>> +static int ac97_bus_reset(struct ac97_controller *ac97_ctrl)
>> +{
>> +	struct ac97_codec_device codec;
>> +
>> +	memset(&codec, 0, sizeof(codec));
>> +	codec.dev = *ac97_ctrl->dev;
>> +
>> +	ac97_ctrl->ops->reset(&codec);
>
> So, this assumes that reset ops is mandatory?  Then document it at
> least.
Ok, for RFC v2.

Thanks for your review and feedbacks Takashi, I'll work on both Mark and your
comments in the next weeks.

Cheers.

-- 
Robert

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

* [RFC PATCH 2/7] ALSA: ac97: add an ac97 bus
@ 2016-05-14  9:50       ` Robert Jarzmik
  0 siblings, 0 replies; 74+ messages in thread
From: Robert Jarzmik @ 2016-05-14  9:50 UTC (permalink / raw)
  To: linux-arm-kernel

Takashi Iwai <tiwai@suse.de> writes:

> On Sat, 30 Apr 2016 23:15:34 +0200,
> Robert Jarzmik wrote:
>> 
>> diff --git a/include/sound/ac97/codec.h b/include/sound/ac97/codec.h
>> new file mode 100644
>> index 000000000000..4b8b3e570892
>> --- /dev/null
>> +++ b/include/sound/ac97/codec.h
>> @@ -0,0 +1,98 @@
>> +/*
>> + *  Copyright (C) 2016 Robert Jarzmik <robert.jarzmik@free.fr>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2 as
>> + * published by the Free Software Foundation.
>> + */
>> +#ifndef AC97_CODEC_H
>> +#define AC97_CODEC_H
>
> Let's be careful about the choice of the guard.
Ok, would _SND_AC97_CODEC_H be better ?

>> +#define AC97_ID(vendor_id1, vendor_id2) \
>> +	(((vendor_id1 & 0xffff) << 16) | (vendor_id2 & 0xffff))
>> +#define AC97_DRIVER_ID(vendor_id1, vendor_id2, mask_id1, mask_id2, _data) \
>> +	{ .id = ((vendor_id1 & 0xffff) << 16) | (vendor_id2 & 0xffff), \
>> +	  .mask = ((mask_id1 & 0xffff) << 16) | (mask_id2 & 0xffff), \
>> +	  .data = _data }
>
> Give parentheses around the macro arguments.
Right, for RFC v2.

>> +struct ac97_codec_device {
>> +	struct device		dev;	/* Must stay first member */
>
> This doesn't have to be the first element as long as you use container_of().
Ah yes, that's a leftover from a former idea, I'll remove that comment.

In the initial code I'd done "struct ac97_codec_device" was hidden from this
file (ie. there was only a "struct ac97_codec_device;" statement), the body of
the struct was contained in sound/ac97/ac97_core.h.

The only provided macro to access the "struct device" inside "struct
ac97_codec_device" was relying on this "trick" (that's a bit like in the
video4linux area).

Anyway, good point, I'll remove that.

>> +struct ac97_codec_driver {
>> +	struct device_driver	driver;
>> +	int			(*probe)(struct ac97_codec_device *);
>> +	int			(*remove)(struct ac97_codec_device *);
>> +	int			(*suspend)(struct ac97_codec_device *);
>> +	int			(*resume)(struct ac97_codec_device *);
>> +	void			(*shutdown)(struct ac97_codec_device *);
>> +	struct ac97_id		*id_table;
>
> Missing const?
Ah no, unfortunately not, or rather not yet.

I tried that one, not very hard, but at least ac97_bus_match() with the pair
"struct ac97_id *id = adrv->id_table" and "do { } while (++id->id);" is not
possible AFAIK with a const.

I will see if I can come up with something better for ac97_bus_match, such as
array usage instead of pointer arithmetics.

>> +};
>> +
>> +int ac97_codec_driver_register(struct ac97_codec_driver *drv);
>> +void ac97_codec_driver_unregister(struct ac97_codec_driver *drv);
>> +
>> +static inline struct device *
>> +ac97_codec_dev2dev(const struct ac97_codec_device *adev)
>> +{
>> +	return (struct device *)(adev);
>
> What's wrong with the simple &adev->dev ?  Cast looks scary.
The same leftover than above, I'll change that for RFC v2.

>> +struct ac97_controller {
>> +	const struct ac97_controller_ops *ops;
>> +	struct list_head controllers;
>> +	struct device *dev;
>> +	int bus_idx;
>
> What is this bus_idx for?
Initially it was to distinguish 2 different AC97 controllers. In the current
patchset state, it's not usefull anymore AFAICS.
So let's remove it.

>> +	int bound_codecs;
The same comment would apply here. I don't think that information is important
anymore. I thought I would use that to prevent AC97 controler removal while
codecs are still bound.

In a second thought what would be better is to have get_device() called for each
bound codec which will prevent ac97_digital_controller_unregister() to succeed
(-EBUSY).

>> +	struct list_head codecs;
>> +};
>> +
>> +int ac97_digital_controller_register(const struct ac97_controller_ops *ops,
>> +				     struct device *dev);
>> +int ac97_digital_controller_unregister(const struct device *dev);
>> +
>> +#endif
>> diff --git a/sound/ac97/Kconfig b/sound/ac97/Kconfig
>> new file mode 100644
>> index 000000000000..fd2c2d031e62
>> --- /dev/null
>> +++ b/sound/ac97/Kconfig
>> @@ -0,0 +1,9 @@
>> +#
>> +# PCI configuration
>> +#
>  
> Still only for PCI? :)
Ouch ;) I'll amend that for RFC v2.
>
>> +
>> +config AC97
>> +	bool "AC97 bus"
>> +	help
>> +	   Say Y here if you want to have AC97 devices, which are sound oriented
>> +	   devices around an AC-Link.
>> diff --git a/sound/ac97/Makefile b/sound/ac97/Makefile
>> new file mode 100644
>> index 000000000000..5575909d46e2
>> --- /dev/null
>> +++ b/sound/ac97/Makefile
>> @@ -0,0 +1,5 @@
>> +#
>> +# make for AC97 bus drivers
>> +#
>> +
>> +obj-y	+= bus.o codec.o snd_ac97_compat.o
>
> No possibility for modules?
There should be, so I'll put that on my TODO list for RFC v2.

>> +static struct ac97_codec_device *
>> +ac97_codec_find(struct ac97_controller *ac97_ctrl, int codec_num)
>> +{
>> +	struct ac97_codec_device *codec;
>> +
>> +	list_for_each_entry(codec, &ac97_ctrl->codecs, list)
>> +		if (codec->num == codec_num)
>> +			return codec;
>> +
>> +	return NULL;
>> +}
>
> It's a question whether we need to manage the codecs in the linked
> list.  There can be at most 4 codecs, so it fits in an array well,
> too.  Then some codes like this would be simpler. (And it'll even
> reduce the footprint, too.)
Agreed. For RFC v2.

>> +unsigned int ac97_bus_scan_one(struct ac97_controller *ac97,
>> +				      int codec_num)
>> +{
>> +	struct ac97_codec_device codec;
>> +	unsigned short vid1, vid2;
>> +	int ret;
>> +
>> +	codec.dev = *ac97->dev;
>> +	codec.num = codec_num;
>> +	ret = ac97->ops->read(&codec, AC97_VENDOR_ID1);
>> +	vid1 = (ret & 0xffff);
>> +	if (ret < 0)
>> +		return 0;
>
> Hmm.  This looks pretty hackish and dangerous.
You mean returning 0 even if the read failed, right ?
A better prototype would probably be (for RFC v2):
  int ac97_bus_scan_one(struct ac97_controller *ac97, int codec_num,
                        unsigned int *vendor_id);

>> +static int ac97_bus_scan(struct ac97_controller *ac97_ctrl)
>> +{
>> +	int ret, i;
>> +	unsigned int vendor_id;
>> +
>> +	for (i = 0; i < AC97_BUS_MAX_CODECS; i++) {
>> +		if (ac97_codec_find(ac97_ctrl, i))
>> +			continue;
>> +		vendor_id = ac97_bus_scan_one(ac97_ctrl, i);
>> +		if (!vendor_id)
>> +			continue;
>> +
>> +		ret = ac97_codec_add(ac97_ctrl, i, vendor_id);
>> +		if (ret < 0)
>> +			return ret;
>
> This is one of concerns: we don't know whether the device really
> reacts well if you access to a non-existing slot.  At least, it'd be
> safer to have the masks for the devices we already know the slots.

Ah you mean upon ac97 controller registration, the
ac97_digital_controller_register() should provide the information for each of
the 4 slots :
 - does the controller enable this slot (default yes)
 - does the controller support auto-scan for this slot (default yes)
   I'm not sure this "feature" is required, it looks a bit over-engineered.

That could be a matter of 1 or 2 masks as input parameters to
ac97_digital_controller_register().

>> +static int ac97_bus_reset(struct ac97_controller *ac97_ctrl)
>> +{
>> +	struct ac97_codec_device codec;
>> +
>> +	memset(&codec, 0, sizeof(codec));
>> +	codec.dev = *ac97_ctrl->dev;
>> +
>> +	ac97_ctrl->ops->reset(&codec);
>
> So, this assumes that reset ops is mandatory?  Then document it at
> least.
Ok, for RFC v2.

Thanks for your review and feedbacks Takashi, I'll work on both Mark and your
comments in the next weeks.

Cheers.

-- 
Robert

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

* Re: [RFC PATCH 2/7] ALSA: ac97: add an ac97 bus
  2016-05-14  9:50       ` Robert Jarzmik
  (?)
@ 2016-05-14 15:13         ` Takashi Iwai
  -1 siblings, 0 replies; 74+ messages in thread
From: Takashi Iwai @ 2016-05-14 15:13 UTC (permalink / raw)
  To: Robert Jarzmik
  Cc: Haojian Zhuang, Liam Girdwood, Mark Brown, Jaroslav Kysela,
	Daniel Mack, alsa-devel, linux-arm-kernel, patches, linux-kernel

On Sat, 14 May 2016 11:50:50 +0200,
Robert Jarzmik wrote:
> >> +unsigned int ac97_bus_scan_one(struct ac97_controller *ac97,
> >> +				      int codec_num)
> >> +{
> >> +	struct ac97_codec_device codec;
> >> +	unsigned short vid1, vid2;
> >> +	int ret;
> >> +
> >> +	codec.dev = *ac97->dev;
> >> +	codec.num = codec_num;
> >> +	ret = ac97->ops->read(&codec, AC97_VENDOR_ID1);
> >> +	vid1 = (ret & 0xffff);
> >> +	if (ret < 0)
> >> +		return 0;
> >
> > Hmm.  This looks pretty hackish and dangerous.
> You mean returning 0 even if the read failed, right ?

No, my concern is that it's creating a dummy codec object temporarily
on the stack just by copying some fields and calling the ops with it.
(And actually the current code may work wrongly because lack of
 zero-clear of the object.)

IMO, a cleaner way would be to define the ops passed with both
controller and codec objects as arguments, and pass NULL codec here.


Takashi

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

* Re: [RFC PATCH 2/7] ALSA: ac97: add an ac97 bus
@ 2016-05-14 15:13         ` Takashi Iwai
  0 siblings, 0 replies; 74+ messages in thread
From: Takashi Iwai @ 2016-05-14 15:13 UTC (permalink / raw)
  To: Robert Jarzmik
  Cc: Haojian Zhuang, Liam Girdwood, Mark Brown, Jaroslav Kysela,
	Daniel Mack, alsa-devel, linux-arm-kernel, patches, linux-kernel

On Sat, 14 May 2016 11:50:50 +0200,
Robert Jarzmik wrote:
> >> +unsigned int ac97_bus_scan_one(struct ac97_controller *ac97,
> >> +				      int codec_num)
> >> +{
> >> +	struct ac97_codec_device codec;
> >> +	unsigned short vid1, vid2;
> >> +	int ret;
> >> +
> >> +	codec.dev = *ac97->dev;
> >> +	codec.num = codec_num;
> >> +	ret = ac97->ops->read(&codec, AC97_VENDOR_ID1);
> >> +	vid1 = (ret & 0xffff);
> >> +	if (ret < 0)
> >> +		return 0;
> >
> > Hmm.  This looks pretty hackish and dangerous.
> You mean returning 0 even if the read failed, right ?

No, my concern is that it's creating a dummy codec object temporarily
on the stack just by copying some fields and calling the ops with it.
(And actually the current code may work wrongly because lack of
 zero-clear of the object.)

IMO, a cleaner way would be to define the ops passed with both
controller and codec objects as arguments, and pass NULL codec here.


Takashi

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

* [RFC PATCH 2/7] ALSA: ac97: add an ac97 bus
@ 2016-05-14 15:13         ` Takashi Iwai
  0 siblings, 0 replies; 74+ messages in thread
From: Takashi Iwai @ 2016-05-14 15:13 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, 14 May 2016 11:50:50 +0200,
Robert Jarzmik wrote:
> >> +unsigned int ac97_bus_scan_one(struct ac97_controller *ac97,
> >> +				      int codec_num)
> >> +{
> >> +	struct ac97_codec_device codec;
> >> +	unsigned short vid1, vid2;
> >> +	int ret;
> >> +
> >> +	codec.dev = *ac97->dev;
> >> +	codec.num = codec_num;
> >> +	ret = ac97->ops->read(&codec, AC97_VENDOR_ID1);
> >> +	vid1 = (ret & 0xffff);
> >> +	if (ret < 0)
> >> +		return 0;
> >
> > Hmm.  This looks pretty hackish and dangerous.
> You mean returning 0 even if the read failed, right ?

No, my concern is that it's creating a dummy codec object temporarily
on the stack just by copying some fields and calling the ops with it.
(And actually the current code may work wrongly because lack of
 zero-clear of the object.)

IMO, a cleaner way would be to define the ops passed with both
controller and codec objects as arguments, and pass NULL codec here.


Takashi

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

* Re: [RFC PATCH 2/7] ALSA: ac97: add an ac97 bus
  2016-05-14 15:13         ` Takashi Iwai
  (?)
@ 2016-05-15 21:29           ` Robert Jarzmik
  -1 siblings, 0 replies; 74+ messages in thread
From: Robert Jarzmik @ 2016-05-15 21:29 UTC (permalink / raw)
  To: Takashi Iwai
  Cc: Haojian Zhuang, Liam Girdwood, Mark Brown, Jaroslav Kysela,
	Daniel Mack, alsa-devel, linux-arm-kernel, patches, linux-kernel

Takashi Iwai <tiwai@suse.de> writes:

> On Sat, 14 May 2016 11:50:50 +0200,
> Robert Jarzmik wrote:
>> >> +unsigned int ac97_bus_scan_one(struct ac97_controller *ac97,
>> >> +				      int codec_num)
>> >> +{
>> >> +	struct ac97_codec_device codec;
>> >> +	unsigned short vid1, vid2;
>> >> +	int ret;
>> >> +
>> >> +	codec.dev = *ac97->dev;
>> >> +	codec.num = codec_num;
>> >> +	ret = ac97->ops->read(&codec, AC97_VENDOR_ID1);
>> >> +	vid1 = (ret & 0xffff);
>> >> +	if (ret < 0)
>> >> +		return 0;
>> >
>> > Hmm.  This looks pretty hackish and dangerous.
>> You mean returning 0 even if the read failed, right ?
>
> No, my concern is that it's creating a dummy codec object temporarily
> on the stack just by copying some fields and calling the ops with it.
> (And actually the current code may work wrongly because lack of
>  zero-clear of the object.)
Ah yes, I remember now, the on-stack generated device, indeed ugly.

> IMO, a cleaner way would be to define the ops passed with both
> controller and codec objects as arguments, and pass NULL codec here.
It's rather unusual to need both the device and its controller in bus
operations. I must admit I have no better idea so far, so I'll try that just to
see how it looks like, and let's see next ...

Cheers.

-- 
Robert

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

* Re: [RFC PATCH 2/7] ALSA: ac97: add an ac97 bus
@ 2016-05-15 21:29           ` Robert Jarzmik
  0 siblings, 0 replies; 74+ messages in thread
From: Robert Jarzmik @ 2016-05-15 21:29 UTC (permalink / raw)
  To: Takashi Iwai
  Cc: alsa-devel, linux-kernel, patches, Liam Girdwood, Haojian Zhuang,
	Mark Brown, linux-arm-kernel, Daniel Mack

Takashi Iwai <tiwai@suse.de> writes:

> On Sat, 14 May 2016 11:50:50 +0200,
> Robert Jarzmik wrote:
>> >> +unsigned int ac97_bus_scan_one(struct ac97_controller *ac97,
>> >> +				      int codec_num)
>> >> +{
>> >> +	struct ac97_codec_device codec;
>> >> +	unsigned short vid1, vid2;
>> >> +	int ret;
>> >> +
>> >> +	codec.dev = *ac97->dev;
>> >> +	codec.num = codec_num;
>> >> +	ret = ac97->ops->read(&codec, AC97_VENDOR_ID1);
>> >> +	vid1 = (ret & 0xffff);
>> >> +	if (ret < 0)
>> >> +		return 0;
>> >
>> > Hmm.  This looks pretty hackish and dangerous.
>> You mean returning 0 even if the read failed, right ?
>
> No, my concern is that it's creating a dummy codec object temporarily
> on the stack just by copying some fields and calling the ops with it.
> (And actually the current code may work wrongly because lack of
>  zero-clear of the object.)
Ah yes, I remember now, the on-stack generated device, indeed ugly.

> IMO, a cleaner way would be to define the ops passed with both
> controller and codec objects as arguments, and pass NULL codec here.
It's rather unusual to need both the device and its controller in bus
operations. I must admit I have no better idea so far, so I'll try that just to
see how it looks like, and let's see next ...

Cheers.

-- 
Robert

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

* [RFC PATCH 2/7] ALSA: ac97: add an ac97 bus
@ 2016-05-15 21:29           ` Robert Jarzmik
  0 siblings, 0 replies; 74+ messages in thread
From: Robert Jarzmik @ 2016-05-15 21:29 UTC (permalink / raw)
  To: linux-arm-kernel

Takashi Iwai <tiwai@suse.de> writes:

> On Sat, 14 May 2016 11:50:50 +0200,
> Robert Jarzmik wrote:
>> >> +unsigned int ac97_bus_scan_one(struct ac97_controller *ac97,
>> >> +				      int codec_num)
>> >> +{
>> >> +	struct ac97_codec_device codec;
>> >> +	unsigned short vid1, vid2;
>> >> +	int ret;
>> >> +
>> >> +	codec.dev = *ac97->dev;
>> >> +	codec.num = codec_num;
>> >> +	ret = ac97->ops->read(&codec, AC97_VENDOR_ID1);
>> >> +	vid1 = (ret & 0xffff);
>> >> +	if (ret < 0)
>> >> +		return 0;
>> >
>> > Hmm.  This looks pretty hackish and dangerous.
>> You mean returning 0 even if the read failed, right ?
>
> No, my concern is that it's creating a dummy codec object temporarily
> on the stack just by copying some fields and calling the ops with it.
> (And actually the current code may work wrongly because lack of
>  zero-clear of the object.)
Ah yes, I remember now, the on-stack generated device, indeed ugly.

> IMO, a cleaner way would be to define the ops passed with both
> controller and codec objects as arguments, and pass NULL codec here.
It's rather unusual to need both the device and its controller in bus
operations. I must admit I have no better idea so far, so I'll try that just to
see how it looks like, and let's see next ...

Cheers.

-- 
Robert

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

* Re: [RFC PATCH 2/7] ALSA: ac97: add an ac97 bus
  2016-05-15 21:29           ` Robert Jarzmik
  (?)
@ 2016-05-16  5:40             ` Takashi Iwai
  -1 siblings, 0 replies; 74+ messages in thread
From: Takashi Iwai @ 2016-05-16  5:40 UTC (permalink / raw)
  To: Robert Jarzmik
  Cc: Haojian Zhuang, Liam Girdwood, Mark Brown, Jaroslav Kysela,
	Daniel Mack, alsa-devel, linux-arm-kernel, patches, linux-kernel

On Sun, 15 May 2016 23:29:27 +0200,
Robert Jarzmik wrote:
> 
> Takashi Iwai <tiwai@suse.de> writes:
> 
> > On Sat, 14 May 2016 11:50:50 +0200,
> > Robert Jarzmik wrote:
> >> >> +unsigned int ac97_bus_scan_one(struct ac97_controller *ac97,
> >> >> +				      int codec_num)
> >> >> +{
> >> >> +	struct ac97_codec_device codec;
> >> >> +	unsigned short vid1, vid2;
> >> >> +	int ret;
> >> >> +
> >> >> +	codec.dev = *ac97->dev;
> >> >> +	codec.num = codec_num;
> >> >> +	ret = ac97->ops->read(&codec, AC97_VENDOR_ID1);
> >> >> +	vid1 = (ret & 0xffff);
> >> >> +	if (ret < 0)
> >> >> +		return 0;
> >> >
> >> > Hmm.  This looks pretty hackish and dangerous.
> >> You mean returning 0 even if the read failed, right ?
> >
> > No, my concern is that it's creating a dummy codec object temporarily
> > on the stack just by copying some fields and calling the ops with it.
> > (And actually the current code may work wrongly because lack of
> >  zero-clear of the object.)
> Ah yes, I remember now, the on-stack generated device, indeed ugly.
> 
> > IMO, a cleaner way would be to define the ops passed with both
> > controller and codec objects as arguments, and pass NULL codec here.
> It's rather unusual to need both the device and its controller in bus
> operations. I must admit I have no better idea so far, so I'll try that just to
> see how it looks like, and let's see next ...

Thinking of this again, I wonder now why we need to pass the codec
object at all.  It's the read/write ops via ac97, so we just need the
ac97_controller object and the address slot of the accessed codec?


Takashi

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

* Re: [RFC PATCH 2/7] ALSA: ac97: add an ac97 bus
@ 2016-05-16  5:40             ` Takashi Iwai
  0 siblings, 0 replies; 74+ messages in thread
From: Takashi Iwai @ 2016-05-16  5:40 UTC (permalink / raw)
  To: Robert Jarzmik
  Cc: alsa-devel, linux-kernel, patches, Liam Girdwood, Haojian Zhuang,
	Mark Brown, linux-arm-kernel, Daniel Mack

On Sun, 15 May 2016 23:29:27 +0200,
Robert Jarzmik wrote:
> 
> Takashi Iwai <tiwai@suse.de> writes:
> 
> > On Sat, 14 May 2016 11:50:50 +0200,
> > Robert Jarzmik wrote:
> >> >> +unsigned int ac97_bus_scan_one(struct ac97_controller *ac97,
> >> >> +				      int codec_num)
> >> >> +{
> >> >> +	struct ac97_codec_device codec;
> >> >> +	unsigned short vid1, vid2;
> >> >> +	int ret;
> >> >> +
> >> >> +	codec.dev = *ac97->dev;
> >> >> +	codec.num = codec_num;
> >> >> +	ret = ac97->ops->read(&codec, AC97_VENDOR_ID1);
> >> >> +	vid1 = (ret & 0xffff);
> >> >> +	if (ret < 0)
> >> >> +		return 0;
> >> >
> >> > Hmm.  This looks pretty hackish and dangerous.
> >> You mean returning 0 even if the read failed, right ?
> >
> > No, my concern is that it's creating a dummy codec object temporarily
> > on the stack just by copying some fields and calling the ops with it.
> > (And actually the current code may work wrongly because lack of
> >  zero-clear of the object.)
> Ah yes, I remember now, the on-stack generated device, indeed ugly.
> 
> > IMO, a cleaner way would be to define the ops passed with both
> > controller and codec objects as arguments, and pass NULL codec here.
> It's rather unusual to need both the device and its controller in bus
> operations. I must admit I have no better idea so far, so I'll try that just to
> see how it looks like, and let's see next ...

Thinking of this again, I wonder now why we need to pass the codec
object at all.  It's the read/write ops via ac97, so we just need the
ac97_controller object and the address slot of the accessed codec?


Takashi

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

* [RFC PATCH 2/7] ALSA: ac97: add an ac97 bus
@ 2016-05-16  5:40             ` Takashi Iwai
  0 siblings, 0 replies; 74+ messages in thread
From: Takashi Iwai @ 2016-05-16  5:40 UTC (permalink / raw)
  To: linux-arm-kernel

On Sun, 15 May 2016 23:29:27 +0200,
Robert Jarzmik wrote:
> 
> Takashi Iwai <tiwai@suse.de> writes:
> 
> > On Sat, 14 May 2016 11:50:50 +0200,
> > Robert Jarzmik wrote:
> >> >> +unsigned int ac97_bus_scan_one(struct ac97_controller *ac97,
> >> >> +				      int codec_num)
> >> >> +{
> >> >> +	struct ac97_codec_device codec;
> >> >> +	unsigned short vid1, vid2;
> >> >> +	int ret;
> >> >> +
> >> >> +	codec.dev = *ac97->dev;
> >> >> +	codec.num = codec_num;
> >> >> +	ret = ac97->ops->read(&codec, AC97_VENDOR_ID1);
> >> >> +	vid1 = (ret & 0xffff);
> >> >> +	if (ret < 0)
> >> >> +		return 0;
> >> >
> >> > Hmm.  This looks pretty hackish and dangerous.
> >> You mean returning 0 even if the read failed, right ?
> >
> > No, my concern is that it's creating a dummy codec object temporarily
> > on the stack just by copying some fields and calling the ops with it.
> > (And actually the current code may work wrongly because lack of
> >  zero-clear of the object.)
> Ah yes, I remember now, the on-stack generated device, indeed ugly.
> 
> > IMO, a cleaner way would be to define the ops passed with both
> > controller and codec objects as arguments, and pass NULL codec here.
> It's rather unusual to need both the device and its controller in bus
> operations. I must admit I have no better idea so far, so I'll try that just to
> see how it looks like, and let's see next ...

Thinking of this again, I wonder now why we need to pass the codec
object at all.  It's the read/write ops via ac97, so we just need the
ac97_controller object and the address slot of the accessed codec?


Takashi

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

* Re: [RFC PATCH 2/7] ALSA: ac97: add an ac97 bus
  2016-05-16  5:40             ` Takashi Iwai
  (?)
@ 2016-05-16  8:53               ` Robert Jarzmik
  -1 siblings, 0 replies; 74+ messages in thread
From: Robert Jarzmik @ 2016-05-16  8:53 UTC (permalink / raw)
  To: Takashi Iwai
  Cc: Haojian Zhuang, Liam Girdwood, Mark Brown, Jaroslav Kysela,
	Daniel Mack, alsa-devel, linux-arm-kernel, patches, linux-kernel

Takashi Iwai <tiwai@suse.de> writes:

> On Sun, 15 May 2016 23:29:27 +0200,
> Robert Jarzmik wrote:
>> 
>> Takashi Iwai <tiwai@suse.de> writes:
>> 
>> > On Sat, 14 May 2016 11:50:50 +0200,
>> >
>> > No, my concern is that it's creating a dummy codec object temporarily
>> > on the stack just by copying some fields and calling the ops with it.
>> > (And actually the current code may work wrongly because lack of
>> >  zero-clear of the object.)
>> Ah yes, I remember now, the on-stack generated device, indeed ugly.
>> 
>> > IMO, a cleaner way would be to define the ops passed with both
>> > controller and codec objects as arguments, and pass NULL codec here.
>> It's rather unusual to need both the device and its controller in bus
>> operations. I must admit I have no better idea so far, so I'll try that just to
>> see how it looks like, and let's see next ...
>
> Thinking of this again, I wonder now why we need to pass the codec
> object at all.  It's the read/write ops via ac97, so we just need the
> ac97_controller object and the address slot of the accessed codec?
So far it would work. The only objection I would see is if in the future the bus
operation needs a specialization which is ac97 codec dependent, such as a flag
or a mask in ac97_codec_device structure.

Even if I'd like to not have these in bus operations, the struct snd_ac97 had a
need for a 'caps', 'ext_id', ... fields for example. Yet these could be
contained in the ac97_codec_device structure and not exposed to bus operations.

Another worry is the pattern (as an example) in atmel_ac97c_write() in
sound/atmel/ac97.c, where the codec structure is used to get the controller
through a container_of() type call. Yet passing the controller to bus operations
takes care of this one.

>From a "purely API" point of view the couple (ac97_controller, ac97_slot_id) is
what will route an ac97 bus operation, be that a read/write/reset/..., the
remaining question is will it cover the cases we've not thought of ?

Cheers.

-- 
Robert

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

* Re: [RFC PATCH 2/7] ALSA: ac97: add an ac97 bus
@ 2016-05-16  8:53               ` Robert Jarzmik
  0 siblings, 0 replies; 74+ messages in thread
From: Robert Jarzmik @ 2016-05-16  8:53 UTC (permalink / raw)
  To: Takashi Iwai
  Cc: Haojian Zhuang, Liam Girdwood, Mark Brown, Jaroslav Kysela,
	Daniel Mack, alsa-devel, linux-arm-kernel, patches, linux-kernel

Takashi Iwai <tiwai@suse.de> writes:

> On Sun, 15 May 2016 23:29:27 +0200,
> Robert Jarzmik wrote:
>> 
>> Takashi Iwai <tiwai@suse.de> writes:
>> 
>> > On Sat, 14 May 2016 11:50:50 +0200,
>> >
>> > No, my concern is that it's creating a dummy codec object temporarily
>> > on the stack just by copying some fields and calling the ops with it.
>> > (And actually the current code may work wrongly because lack of
>> >  zero-clear of the object.)
>> Ah yes, I remember now, the on-stack generated device, indeed ugly.
>> 
>> > IMO, a cleaner way would be to define the ops passed with both
>> > controller and codec objects as arguments, and pass NULL codec here.
>> It's rather unusual to need both the device and its controller in bus
>> operations. I must admit I have no better idea so far, so I'll try that just to
>> see how it looks like, and let's see next ...
>
> Thinking of this again, I wonder now why we need to pass the codec
> object at all.  It's the read/write ops via ac97, so we just need the
> ac97_controller object and the address slot of the accessed codec?
So far it would work. The only objection I would see is if in the future the bus
operation needs a specialization which is ac97 codec dependent, such as a flag
or a mask in ac97_codec_device structure.

Even if I'd like to not have these in bus operations, the struct snd_ac97 had a
need for a 'caps', 'ext_id', ... fields for example. Yet these could be
contained in the ac97_codec_device structure and not exposed to bus operations.

Another worry is the pattern (as an example) in atmel_ac97c_write() in
sound/atmel/ac97.c, where the codec structure is used to get the controller
through a container_of() type call. Yet passing the controller to bus operations
takes care of this one.

>From a "purely API" point of view the couple (ac97_controller, ac97_slot_id) is
what will route an ac97 bus operation, be that a read/write/reset/..., the
remaining question is will it cover the cases we've not thought of ?

Cheers.

-- 
Robert

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

* [RFC PATCH 2/7] ALSA: ac97: add an ac97 bus
@ 2016-05-16  8:53               ` Robert Jarzmik
  0 siblings, 0 replies; 74+ messages in thread
From: Robert Jarzmik @ 2016-05-16  8:53 UTC (permalink / raw)
  To: linux-arm-kernel

Takashi Iwai <tiwai@suse.de> writes:

> On Sun, 15 May 2016 23:29:27 +0200,
> Robert Jarzmik wrote:
>> 
>> Takashi Iwai <tiwai@suse.de> writes:
>> 
>> > On Sat, 14 May 2016 11:50:50 +0200,
>> >
>> > No, my concern is that it's creating a dummy codec object temporarily
>> > on the stack just by copying some fields and calling the ops with it.
>> > (And actually the current code may work wrongly because lack of
>> >  zero-clear of the object.)
>> Ah yes, I remember now, the on-stack generated device, indeed ugly.
>> 
>> > IMO, a cleaner way would be to define the ops passed with both
>> > controller and codec objects as arguments, and pass NULL codec here.
>> It's rather unusual to need both the device and its controller in bus
>> operations. I must admit I have no better idea so far, so I'll try that just to
>> see how it looks like, and let's see next ...
>
> Thinking of this again, I wonder now why we need to pass the codec
> object at all.  It's the read/write ops via ac97, so we just need the
> ac97_controller object and the address slot of the accessed codec?
So far it would work. The only objection I would see is if in the future the bus
operation needs a specialization which is ac97 codec dependent, such as a flag
or a mask in ac97_codec_device structure.

Even if I'd like to not have these in bus operations, the struct snd_ac97 had a
need for a 'caps', 'ext_id', ... fields for example. Yet these could be
contained in the ac97_codec_device structure and not exposed to bus operations.

Another worry is the pattern (as an example) in atmel_ac97c_write() in
sound/atmel/ac97.c, where the codec structure is used to get the controller
through a container_of() type call. Yet passing the controller to bus operations
takes care of this one.

>From a "purely API" point of view the couple (ac97_controller, ac97_slot_id) is
what will route an ac97 bus operation, be that a read/write/reset/..., the
remaining question is will it cover the cases we've not thought of ?

Cheers.

-- 
Robert

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

* Re: [RFC PATCH 2/7] ALSA: ac97: add an ac97 bus
  2016-05-16  8:53               ` Robert Jarzmik
  (?)
@ 2016-05-16 12:58                 ` Takashi Iwai
  -1 siblings, 0 replies; 74+ messages in thread
From: Takashi Iwai @ 2016-05-16 12:58 UTC (permalink / raw)
  To: Robert Jarzmik
  Cc: Haojian Zhuang, Liam Girdwood, Mark Brown, Jaroslav Kysela,
	Daniel Mack, alsa-devel, linux-arm-kernel, patches, linux-kernel

On Mon, 16 May 2016 10:53:56 +0200,
Robert Jarzmik wrote:
> 
> Takashi Iwai <tiwai@suse.de> writes:
> 
> > On Sun, 15 May 2016 23:29:27 +0200,
> > Robert Jarzmik wrote:
> >> 
> >> Takashi Iwai <tiwai@suse.de> writes:
> >> 
> >> > On Sat, 14 May 2016 11:50:50 +0200,
> >> >
> >> > No, my concern is that it's creating a dummy codec object temporarily
> >> > on the stack just by copying some fields and calling the ops with it.
> >> > (And actually the current code may work wrongly because lack of
> >> >  zero-clear of the object.)
> >> Ah yes, I remember now, the on-stack generated device, indeed ugly.
> >> 
> >> > IMO, a cleaner way would be to define the ops passed with both
> >> > controller and codec objects as arguments, and pass NULL codec here.
> >> It's rather unusual to need both the device and its controller in bus
> >> operations. I must admit I have no better idea so far, so I'll try that just to
> >> see how it looks like, and let's see next ...
> >
> > Thinking of this again, I wonder now why we need to pass the codec
> > object at all.  It's the read/write ops via ac97, so we just need the
> > ac97_controller object and the address slot of the accessed codec?
> So far it would work. The only objection I would see is if in the future the bus
> operation needs a specialization which is ac97 codec dependent, such as a flag
> or a mask in ac97_codec_device structure.
> 
> Even if I'd like to not have these in bus operations, the struct snd_ac97 had a
> need for a 'caps', 'ext_id', ... fields for example. Yet these could be
> contained in the ac97_codec_device structure and not exposed to bus operations.

Do we have any example of such exceptions?  For AC97, we don't need to
think of future extensions at all.

If any, we may provide two levels of ops abstractions: the lower
ac97_controller_ops.read/write, and the upper ac97_codec_ops
read/write that may override if defined, but as default it just wraps 
over controller ops.  But I don't think we'd need such unless we
really see the demand to be exposed outside the codec driver itself.

> Another worry is the pattern (as an example) in atmel_ac97c_write() in
> sound/atmel/ac97.c, where the codec structure is used to get the controller
> through a container_of() type call. Yet passing the controller to bus operations
> takes care of this one.

Right.

> From a "purely API" point of view the couple (ac97_controller, ac97_slot_id) is
> what will route an ac97 bus operation, be that a read/write/reset/..., the
> remaining question is will it cover the cases we've not thought of ?

The remaining ops are rather codec-specific operations, and they don't
have to be implemented in the bus (controller) level.  We should keep
the bus ops as small as possible.


thanks,

Takashi

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

* Re: [RFC PATCH 2/7] ALSA: ac97: add an ac97 bus
@ 2016-05-16 12:58                 ` Takashi Iwai
  0 siblings, 0 replies; 74+ messages in thread
From: Takashi Iwai @ 2016-05-16 12:58 UTC (permalink / raw)
  To: Robert Jarzmik
  Cc: Haojian Zhuang, Liam Girdwood, Mark Brown, Jaroslav Kysela,
	Daniel Mack, alsa-devel, linux-arm-kernel, patches, linux-kernel

On Mon, 16 May 2016 10:53:56 +0200,
Robert Jarzmik wrote:
> 
> Takashi Iwai <tiwai@suse.de> writes:
> 
> > On Sun, 15 May 2016 23:29:27 +0200,
> > Robert Jarzmik wrote:
> >> 
> >> Takashi Iwai <tiwai@suse.de> writes:
> >> 
> >> > On Sat, 14 May 2016 11:50:50 +0200,
> >> >
> >> > No, my concern is that it's creating a dummy codec object temporarily
> >> > on the stack just by copying some fields and calling the ops with it.
> >> > (And actually the current code may work wrongly because lack of
> >> >  zero-clear of the object.)
> >> Ah yes, I remember now, the on-stack generated device, indeed ugly.
> >> 
> >> > IMO, a cleaner way would be to define the ops passed with both
> >> > controller and codec objects as arguments, and pass NULL codec here.
> >> It's rather unusual to need both the device and its controller in bus
> >> operations. I must admit I have no better idea so far, so I'll try that just to
> >> see how it looks like, and let's see next ...
> >
> > Thinking of this again, I wonder now why we need to pass the codec
> > object at all.  It's the read/write ops via ac97, so we just need the
> > ac97_controller object and the address slot of the accessed codec?
> So far it would work. The only objection I would see is if in the future the bus
> operation needs a specialization which is ac97 codec dependent, such as a flag
> or a mask in ac97_codec_device structure.
> 
> Even if I'd like to not have these in bus operations, the struct snd_ac97 had a
> need for a 'caps', 'ext_id', ... fields for example. Yet these could be
> contained in the ac97_codec_device structure and not exposed to bus operations.

Do we have any example of such exceptions?  For AC97, we don't need to
think of future extensions at all.

If any, we may provide two levels of ops abstractions: the lower
ac97_controller_ops.read/write, and the upper ac97_codec_ops
read/write that may override if defined, but as default it just wraps 
over controller ops.  But I don't think we'd need such unless we
really see the demand to be exposed outside the codec driver itself.

> Another worry is the pattern (as an example) in atmel_ac97c_write() in
> sound/atmel/ac97.c, where the codec structure is used to get the controller
> through a container_of() type call. Yet passing the controller to bus operations
> takes care of this one.

Right.

> From a "purely API" point of view the couple (ac97_controller, ac97_slot_id) is
> what will route an ac97 bus operation, be that a read/write/reset/..., the
> remaining question is will it cover the cases we've not thought of ?

The remaining ops are rather codec-specific operations, and they don't
have to be implemented in the bus (controller) level.  We should keep
the bus ops as small as possible.


thanks,

Takashi

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

* [RFC PATCH 2/7] ALSA: ac97: add an ac97 bus
@ 2016-05-16 12:58                 ` Takashi Iwai
  0 siblings, 0 replies; 74+ messages in thread
From: Takashi Iwai @ 2016-05-16 12:58 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, 16 May 2016 10:53:56 +0200,
Robert Jarzmik wrote:
> 
> Takashi Iwai <tiwai@suse.de> writes:
> 
> > On Sun, 15 May 2016 23:29:27 +0200,
> > Robert Jarzmik wrote:
> >> 
> >> Takashi Iwai <tiwai@suse.de> writes:
> >> 
> >> > On Sat, 14 May 2016 11:50:50 +0200,
> >> >
> >> > No, my concern is that it's creating a dummy codec object temporarily
> >> > on the stack just by copying some fields and calling the ops with it.
> >> > (And actually the current code may work wrongly because lack of
> >> >  zero-clear of the object.)
> >> Ah yes, I remember now, the on-stack generated device, indeed ugly.
> >> 
> >> > IMO, a cleaner way would be to define the ops passed with both
> >> > controller and codec objects as arguments, and pass NULL codec here.
> >> It's rather unusual to need both the device and its controller in bus
> >> operations. I must admit I have no better idea so far, so I'll try that just to
> >> see how it looks like, and let's see next ...
> >
> > Thinking of this again, I wonder now why we need to pass the codec
> > object at all.  It's the read/write ops via ac97, so we just need the
> > ac97_controller object and the address slot of the accessed codec?
> So far it would work. The only objection I would see is if in the future the bus
> operation needs a specialization which is ac97 codec dependent, such as a flag
> or a mask in ac97_codec_device structure.
> 
> Even if I'd like to not have these in bus operations, the struct snd_ac97 had a
> need for a 'caps', 'ext_id', ... fields for example. Yet these could be
> contained in the ac97_codec_device structure and not exposed to bus operations.

Do we have any example of such exceptions?  For AC97, we don't need to
think of future extensions at all.

If any, we may provide two levels of ops abstractions: the lower
ac97_controller_ops.read/write, and the upper ac97_codec_ops
read/write that may override if defined, but as default it just wraps 
over controller ops.  But I don't think we'd need such unless we
really see the demand to be exposed outside the codec driver itself.

> Another worry is the pattern (as an example) in atmel_ac97c_write() in
> sound/atmel/ac97.c, where the codec structure is used to get the controller
> through a container_of() type call. Yet passing the controller to bus operations
> takes care of this one.

Right.

> From a "purely API" point of view the couple (ac97_controller, ac97_slot_id) is
> what will route an ac97 bus operation, be that a read/write/reset/..., the
> remaining question is will it cover the cases we've not thought of ?

The remaining ops are rather codec-specific operations, and they don't
have to be implemented in the bus (controller) level.  We should keep
the bus ops as small as possible.


thanks,

Takashi

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

* Re: [RFC PATCH 2/7] ALSA: ac97: add an ac97 bus
  2016-05-16 12:58                 ` Takashi Iwai
@ 2016-05-16 13:12                   ` Mark Brown
  -1 siblings, 0 replies; 74+ messages in thread
From: Mark Brown @ 2016-05-16 13:12 UTC (permalink / raw)
  To: Takashi Iwai
  Cc: Robert Jarzmik, Haojian Zhuang, Liam Girdwood, Jaroslav Kysela,
	Daniel Mack, alsa-devel, linux-arm-kernel, patches, linux-kernel

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

On Mon, May 16, 2016 at 02:58:13PM +0200, Takashi Iwai wrote:
> Robert Jarzmik wrote:

> > Even if I'd like to not have these in bus operations, the struct snd_ac97 had a
> > need for a 'caps', 'ext_id', ... fields for example. Yet these could be
> > contained in the ac97_codec_device structure and not exposed to bus operations.

> Do we have any example of such exceptions?  For AC97, we don't need to
> think of future extensions at all.

I can't think of any, even for some of the more fancy CODECs used in
embedded systems.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

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

* [RFC PATCH 2/7] ALSA: ac97: add an ac97 bus
@ 2016-05-16 13:12                   ` Mark Brown
  0 siblings, 0 replies; 74+ messages in thread
From: Mark Brown @ 2016-05-16 13:12 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, May 16, 2016 at 02:58:13PM +0200, Takashi Iwai wrote:
> Robert Jarzmik wrote:

> > Even if I'd like to not have these in bus operations, the struct snd_ac97 had a
> > need for a 'caps', 'ext_id', ... fields for example. Yet these could be
> > contained in the ac97_codec_device structure and not exposed to bus operations.

> Do we have any example of such exceptions?  For AC97, we don't need to
> think of future extensions at all.

I can't think of any, even for some of the more fancy CODECs used in
embedded systems.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20160516/56fd982c/attachment.sig>

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

* Applied "ALSA: ac97: split out the generic ac97 registers" to the asoc tree
  2016-04-30 21:15   ` Robert Jarzmik
  (?)
@ 2017-09-04 17:25     ` Mark Brown
  -1 siblings, 0 replies; 74+ messages in thread
From: Mark Brown @ 2017-09-04 17:25 UTC (permalink / raw)
  To: Robert Jarzmik
  Cc: Mark Brown, Daniel Mack, Haojian Zhuang, Jaroslav Kysela,
	Takashi Iwai, Liam Girdwood, Mark Brown, alsa-devel, patches,
	linux-kernel, linux-arm-kernel, alsa-devel

The patch

   ALSA: ac97: split out the generic ac97 registers

has been applied to the asoc tree at

   git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

>From 8e4f7d9b8c652b4eb3ceb790e1e9fe433f9e3b58 Mon Sep 17 00:00:00 2001
From: Robert Jarzmik <robert.jarzmik@free.fr>
Date: Sat, 2 Sep 2017 21:54:03 +0200
Subject: [PATCH] ALSA: ac97: split out the generic ac97 registers

Split out from the ac97_codec.h the ac97 generic registers, which can be
used by a codec, typically a generic ac97 codec, and by the ac97 bus, to
scan an ac97 AC-Link.

This split encompasses all the AC97 standard registers, but not the
codec specific ones.

In order to have a clean split between former ac97 bus implementation
and the new coming one in sound/ac97, it is safer to not include any
former ac97 includes, excepting in sound/ac97/compat.c.

Amongst the thing to isolate :
 - don't have the struct snd_ac97 in sound/ac97/* (except compat.c) to not
   be "fooled" by a definition which would come with ac97_codec.h by
   "chance".
 - don't have to have snd_a97_*() functions, as they rely on struct
   snd_ac97.
  - don't want the struct snd_ac97_bus_ops, there is a new one

Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
Reviewed-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 include/sound/ac97/regs.h  | 262 +++++++++++++++++++++++++++++++++++++++++++++
 include/sound/ac97_codec.h | 239 +----------------------------------------
 2 files changed, 263 insertions(+), 238 deletions(-)
 create mode 100644 include/sound/ac97/regs.h

diff --git a/include/sound/ac97/regs.h b/include/sound/ac97/regs.h
new file mode 100644
index 000000000000..4bb86d379bd5
--- /dev/null
+++ b/include/sound/ac97/regs.h
@@ -0,0 +1,262 @@
+/*
+ *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>
+ *  Universal interface for Audio Codec '97
+ *
+ *  For more details look to AC '97 component specification revision 2.1
+ *  by Intel Corporation (http://developer.intel.com).
+ *
+ *
+ *   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
+ *
+ */
+
+/*
+ *  AC'97 codec registers
+ */
+
+#define AC97_RESET		0x00	/* Reset */
+#define AC97_MASTER		0x02	/* Master Volume */
+#define AC97_HEADPHONE		0x04	/* Headphone Volume (optional) */
+#define AC97_MASTER_MONO	0x06	/* Master Volume Mono (optional) */
+#define AC97_MASTER_TONE	0x08	/* Master Tone (Bass & Treble) (optional) */
+#define AC97_PC_BEEP		0x0a	/* PC Beep Volume (optinal) */
+#define AC97_PHONE		0x0c	/* Phone Volume (optional) */
+#define AC97_MIC		0x0e	/* MIC Volume */
+#define AC97_LINE		0x10	/* Line In Volume */
+#define AC97_CD			0x12	/* CD Volume */
+#define AC97_VIDEO		0x14	/* Video Volume (optional) */
+#define AC97_AUX		0x16	/* AUX Volume (optional) */
+#define AC97_PCM		0x18	/* PCM Volume */
+#define AC97_REC_SEL		0x1a	/* Record Select */
+#define AC97_REC_GAIN		0x1c	/* Record Gain */
+#define AC97_REC_GAIN_MIC	0x1e	/* Record Gain MIC (optional) */
+#define AC97_GENERAL_PURPOSE	0x20	/* General Purpose (optional) */
+#define AC97_3D_CONTROL		0x22	/* 3D Control (optional) */
+#define AC97_INT_PAGING		0x24	/* Audio Interrupt & Paging (AC'97 2.3) */
+#define AC97_POWERDOWN		0x26	/* Powerdown control / status */
+/* range 0x28-0x3a - AUDIO AC'97 2.0 extensions */
+#define AC97_EXTENDED_ID	0x28	/* Extended Audio ID */
+#define AC97_EXTENDED_STATUS	0x2a	/* Extended Audio Status and Control */
+#define AC97_PCM_FRONT_DAC_RATE 0x2c	/* PCM Front DAC Rate */
+#define AC97_PCM_SURR_DAC_RATE	0x2e	/* PCM Surround DAC Rate */
+#define AC97_PCM_LFE_DAC_RATE	0x30	/* PCM LFE DAC Rate */
+#define AC97_PCM_LR_ADC_RATE	0x32	/* PCM LR ADC Rate */
+#define AC97_PCM_MIC_ADC_RATE	0x34	/* PCM MIC ADC Rate */
+#define AC97_CENTER_LFE_MASTER	0x36	/* Center + LFE Master Volume */
+#define AC97_SURROUND_MASTER	0x38	/* Surround (Rear) Master Volume */
+#define AC97_SPDIF		0x3a	/* S/PDIF control */
+/* range 0x3c-0x58 - MODEM */
+#define AC97_EXTENDED_MID	0x3c	/* Extended Modem ID */
+#define AC97_EXTENDED_MSTATUS	0x3e	/* Extended Modem Status and Control */
+#define AC97_LINE1_RATE		0x40	/* Line1 DAC/ADC Rate */
+#define AC97_LINE2_RATE		0x42	/* Line2 DAC/ADC Rate */
+#define AC97_HANDSET_RATE	0x44	/* Handset DAC/ADC Rate */
+#define AC97_LINE1_LEVEL	0x46	/* Line1 DAC/ADC Level */
+#define AC97_LINE2_LEVEL	0x48	/* Line2 DAC/ADC Level */
+#define AC97_HANDSET_LEVEL	0x4a	/* Handset DAC/ADC Level */
+#define AC97_GPIO_CFG		0x4c	/* GPIO Configuration */
+#define AC97_GPIO_POLARITY	0x4e	/* GPIO Pin Polarity/Type, 0=low, 1=high active */
+#define AC97_GPIO_STICKY	0x50	/* GPIO Pin Sticky, 0=not, 1=sticky */
+#define AC97_GPIO_WAKEUP	0x52	/* GPIO Pin Wakeup, 0=no int, 1=yes int */
+#define AC97_GPIO_STATUS	0x54	/* GPIO Pin Status, slot 12 */
+#define AC97_MISC_AFE		0x56	/* Miscellaneous Modem AFE Status and Control */
+/* range 0x5a-0x7b - Vendor Specific */
+#define AC97_VENDOR_ID1		0x7c	/* Vendor ID1 */
+#define AC97_VENDOR_ID2		0x7e	/* Vendor ID2 / revision */
+/* range 0x60-0x6f (page 1) - extended codec registers */
+#define AC97_CODEC_CLASS_REV	0x60	/* Codec Class/Revision */
+#define AC97_PCI_SVID		0x62	/* PCI Subsystem Vendor ID */
+#define AC97_PCI_SID		0x64	/* PCI Subsystem ID */
+#define AC97_FUNC_SELECT	0x66	/* Function Select */
+#define AC97_FUNC_INFO		0x68	/* Function Information */
+#define AC97_SENSE_INFO		0x6a	/* Sense Details */
+
+/* volume controls */
+#define AC97_MUTE_MASK_MONO	0x8000
+#define AC97_MUTE_MASK_STEREO	0x8080
+
+/* slot allocation */
+#define AC97_SLOT_TAG		0
+#define AC97_SLOT_CMD_ADDR	1
+#define AC97_SLOT_CMD_DATA	2
+#define AC97_SLOT_PCM_LEFT	3
+#define AC97_SLOT_PCM_RIGHT	4
+#define AC97_SLOT_MODEM_LINE1	5
+#define AC97_SLOT_PCM_CENTER	6
+#define AC97_SLOT_MIC		6	/* input */
+#define AC97_SLOT_SPDIF_LEFT1	6
+#define AC97_SLOT_PCM_SLEFT	7	/* surround left */
+#define AC97_SLOT_PCM_LEFT_0	7	/* double rate operation */
+#define AC97_SLOT_SPDIF_LEFT	7
+#define AC97_SLOT_PCM_SRIGHT	8	/* surround right */
+#define AC97_SLOT_PCM_RIGHT_0	8	/* double rate operation */
+#define AC97_SLOT_SPDIF_RIGHT	8
+#define AC97_SLOT_LFE		9
+#define AC97_SLOT_SPDIF_RIGHT1	9
+#define AC97_SLOT_MODEM_LINE2	10
+#define AC97_SLOT_PCM_LEFT_1	10	/* double rate operation */
+#define AC97_SLOT_SPDIF_LEFT2	10
+#define AC97_SLOT_HANDSET	11	/* output */
+#define AC97_SLOT_PCM_RIGHT_1	11	/* double rate operation */
+#define AC97_SLOT_SPDIF_RIGHT2	11
+#define AC97_SLOT_MODEM_GPIO	12	/* modem GPIO */
+#define AC97_SLOT_PCM_CENTER_1	12	/* double rate operation */
+
+/* basic capabilities (reset register) */
+#define AC97_BC_DEDICATED_MIC	0x0001	/* Dedicated Mic PCM In Channel */
+#define AC97_BC_RESERVED1	0x0002	/* Reserved (was Modem Line Codec support) */
+#define AC97_BC_BASS_TREBLE	0x0004	/* Bass & Treble Control */
+#define AC97_BC_SIM_STEREO	0x0008	/* Simulated stereo */
+#define AC97_BC_HEADPHONE	0x0010	/* Headphone Out Support */
+#define AC97_BC_LOUDNESS	0x0020	/* Loudness (bass boost) Support */
+#define AC97_BC_16BIT_DAC	0x0000	/* 16-bit DAC resolution */
+#define AC97_BC_18BIT_DAC	0x0040	/* 18-bit DAC resolution */
+#define AC97_BC_20BIT_DAC	0x0080	/* 20-bit DAC resolution */
+#define AC97_BC_DAC_MASK	0x00c0
+#define AC97_BC_16BIT_ADC	0x0000	/* 16-bit ADC resolution */
+#define AC97_BC_18BIT_ADC	0x0100	/* 18-bit ADC resolution */
+#define AC97_BC_20BIT_ADC	0x0200	/* 20-bit ADC resolution */
+#define AC97_BC_ADC_MASK	0x0300
+#define AC97_BC_3D_TECH_ID_MASK	0x7c00	/* Per-vendor ID of 3D enhancement */
+
+/* general purpose */
+#define AC97_GP_DRSS_MASK	0x0c00	/* double rate slot select */
+#define AC97_GP_DRSS_1011	0x0000	/* LR(C) 10+11(+12) */
+#define AC97_GP_DRSS_78		0x0400	/* LR 7+8 */
+
+/* powerdown bits */
+#define AC97_PD_ADC_STATUS	0x0001	/* ADC status (RO) */
+#define AC97_PD_DAC_STATUS	0x0002	/* DAC status (RO) */
+#define AC97_PD_MIXER_STATUS	0x0004	/* Analog mixer status (RO) */
+#define AC97_PD_VREF_STATUS	0x0008	/* Vref status (RO) */
+#define AC97_PD_PR0		0x0100	/* Power down PCM ADCs and input MUX */
+#define AC97_PD_PR1		0x0200	/* Power down PCM front DAC */
+#define AC97_PD_PR2		0x0400	/* Power down Mixer (Vref still on) */
+#define AC97_PD_PR3		0x0800	/* Power down Mixer (Vref off) */
+#define AC97_PD_PR4		0x1000	/* Power down AC-Link */
+#define AC97_PD_PR5		0x2000	/* Disable internal clock usage */
+#define AC97_PD_PR6		0x4000	/* Headphone amplifier */
+#define AC97_PD_EAPD		0x8000	/* External Amplifer Power Down (EAPD) */
+
+/* extended audio ID bit defines */
+#define AC97_EI_VRA		0x0001	/* Variable bit rate supported */
+#define AC97_EI_DRA		0x0002	/* Double rate supported */
+#define AC97_EI_SPDIF		0x0004	/* S/PDIF out supported */
+#define AC97_EI_VRM		0x0008	/* Variable bit rate supported for MIC */
+#define AC97_EI_DACS_SLOT_MASK	0x0030	/* DACs slot assignment */
+#define AC97_EI_DACS_SLOT_SHIFT	4
+#define AC97_EI_CDAC		0x0040	/* PCM Center DAC available */
+#define AC97_EI_SDAC		0x0080	/* PCM Surround DACs available */
+#define AC97_EI_LDAC		0x0100	/* PCM LFE DAC available */
+#define AC97_EI_AMAP		0x0200	/* indicates optional slot/DAC mapping based on codec ID */
+#define AC97_EI_REV_MASK	0x0c00	/* AC'97 revision mask */
+#define AC97_EI_REV_22		0x0400	/* AC'97 revision 2.2 */
+#define AC97_EI_REV_23		0x0800	/* AC'97 revision 2.3 */
+#define AC97_EI_REV_SHIFT	10
+#define AC97_EI_ADDR_MASK	0xc000	/* physical codec ID (address) */
+#define AC97_EI_ADDR_SHIFT	14
+
+/* extended audio status and control bit defines */
+#define AC97_EA_VRA		0x0001	/* Variable bit rate enable bit */
+#define AC97_EA_DRA		0x0002	/* Double-rate audio enable bit */
+#define AC97_EA_SPDIF		0x0004	/* S/PDIF out enable bit */
+#define AC97_EA_VRM		0x0008	/* Variable bit rate for MIC enable bit */
+#define AC97_EA_SPSA_SLOT_MASK	0x0030	/* Mask for slot assignment bits */
+#define AC97_EA_SPSA_SLOT_SHIFT 4
+#define AC97_EA_SPSA_3_4	0x0000	/* Slot assigned to 3 & 4 */
+#define AC97_EA_SPSA_7_8	0x0010	/* Slot assigned to 7 & 8 */
+#define AC97_EA_SPSA_6_9	0x0020	/* Slot assigned to 6 & 9 */
+#define AC97_EA_SPSA_10_11	0x0030	/* Slot assigned to 10 & 11 */
+#define AC97_EA_CDAC		0x0040	/* PCM Center DAC is ready (Read only) */
+#define AC97_EA_SDAC		0x0080	/* PCM Surround DACs are ready (Read only) */
+#define AC97_EA_LDAC		0x0100	/* PCM LFE DAC is ready (Read only) */
+#define AC97_EA_MDAC		0x0200	/* MIC ADC is ready (Read only) */
+#define AC97_EA_SPCV		0x0400	/* S/PDIF configuration valid (Read only) */
+#define AC97_EA_PRI		0x0800	/* Turns the PCM Center DAC off */
+#define AC97_EA_PRJ		0x1000	/* Turns the PCM Surround DACs off */
+#define AC97_EA_PRK		0x2000	/* Turns the PCM LFE DAC off */
+#define AC97_EA_PRL		0x4000	/* Turns the MIC ADC off */
+
+/* S/PDIF control bit defines */
+#define AC97_SC_PRO		0x0001	/* Professional status */
+#define AC97_SC_NAUDIO		0x0002	/* Non audio stream */
+#define AC97_SC_COPY		0x0004	/* Copyright status */
+#define AC97_SC_PRE		0x0008	/* Preemphasis status */
+#define AC97_SC_CC_MASK		0x07f0	/* Category Code mask */
+#define AC97_SC_CC_SHIFT	4
+#define AC97_SC_L		0x0800	/* Generation Level status */
+#define AC97_SC_SPSR_MASK	0x3000	/* S/PDIF Sample Rate bits */
+#define AC97_SC_SPSR_SHIFT	12
+#define AC97_SC_SPSR_44K	0x0000	/* Use 44.1kHz Sample rate */
+#define AC97_SC_SPSR_48K	0x2000	/* Use 48kHz Sample rate */
+#define AC97_SC_SPSR_32K	0x3000	/* Use 32kHz Sample rate */
+#define AC97_SC_DRS		0x4000	/* Double Rate S/PDIF */
+#define AC97_SC_V		0x8000	/* Validity status */
+
+/* Interrupt and Paging bit defines (AC'97 2.3) */
+#define AC97_PAGE_MASK		0x000f	/* Page Selector */
+#define AC97_PAGE_VENDOR	0	/* Vendor-specific registers */
+#define AC97_PAGE_1		1	/* Extended Codec Registers page 1 */
+#define AC97_INT_ENABLE		0x0800	/* Interrupt Enable */
+#define AC97_INT_SENSE		0x1000	/* Sense Cycle */
+#define AC97_INT_CAUSE_SENSE	0x2000	/* Sense Cycle Completed (RO) */
+#define AC97_INT_CAUSE_GPIO	0x4000	/* GPIO bits changed (RO) */
+#define AC97_INT_STATUS		0x8000	/* Interrupt Status */
+
+/* extended modem ID bit defines */
+#define AC97_MEI_LINE1		0x0001	/* Line1 present */
+#define AC97_MEI_LINE2		0x0002	/* Line2 present */
+#define AC97_MEI_HANDSET	0x0004	/* Handset present */
+#define AC97_MEI_CID1		0x0008	/* caller ID decode for Line1 is supported */
+#define AC97_MEI_CID2		0x0010	/* caller ID decode for Line2 is supported */
+#define AC97_MEI_ADDR_MASK	0xc000	/* physical codec ID (address) */
+#define AC97_MEI_ADDR_SHIFT	14
+
+/* extended modem status and control bit defines */
+#define AC97_MEA_GPIO		0x0001	/* GPIO is ready (ro) */
+#define AC97_MEA_MREF		0x0002	/* Vref is up to nominal level (ro) */
+#define AC97_MEA_ADC1		0x0004	/* ADC1 operational (ro) */
+#define AC97_MEA_DAC1		0x0008	/* DAC1 operational (ro) */
+#define AC97_MEA_ADC2		0x0010	/* ADC2 operational (ro) */
+#define AC97_MEA_DAC2		0x0020	/* DAC2 operational (ro) */
+#define AC97_MEA_HADC		0x0040	/* HADC operational (ro) */
+#define AC97_MEA_HDAC		0x0080	/* HDAC operational (ro) */
+#define AC97_MEA_PRA		0x0100	/* GPIO power down (high) */
+#define AC97_MEA_PRB		0x0200	/* reserved */
+#define AC97_MEA_PRC		0x0400	/* ADC1 power down (high) */
+#define AC97_MEA_PRD		0x0800	/* DAC1 power down (high) */
+#define AC97_MEA_PRE		0x1000	/* ADC2 power down (high) */
+#define AC97_MEA_PRF		0x2000	/* DAC2 power down (high) */
+#define AC97_MEA_PRG		0x4000	/* HADC power down (high) */
+#define AC97_MEA_PRH		0x8000	/* HDAC power down (high) */
+
+/* modem gpio status defines */
+#define AC97_GPIO_LINE1_OH      0x0001  /* Off Hook Line1 */
+#define AC97_GPIO_LINE1_RI      0x0002  /* Ring Detect Line1 */
+#define AC97_GPIO_LINE1_CID     0x0004  /* Caller ID path enable Line1 */
+#define AC97_GPIO_LINE1_LCS     0x0008  /* Loop Current Sense Line1 */
+#define AC97_GPIO_LINE1_PULSE   0x0010  /* Opt./ Pulse Dial Line1 (out) */
+#define AC97_GPIO_LINE1_HL1R    0x0020  /* Opt./ Handset to Line1 relay control (out) */
+#define AC97_GPIO_LINE1_HOHD    0x0040  /* Opt./ Handset off hook detect Line1 (in) */
+#define AC97_GPIO_LINE12_AC     0x0080  /* Opt./ Int.bit 1 / Line1/2 AC (out) */
+#define AC97_GPIO_LINE12_DC     0x0100  /* Opt./ Int.bit 2 / Line1/2 DC (out) */
+#define AC97_GPIO_LINE12_RS     0x0200  /* Opt./ Int.bit 3 / Line1/2 RS (out) */
+#define AC97_GPIO_LINE2_OH      0x0400  /* Off Hook Line2 */
+#define AC97_GPIO_LINE2_RI      0x0800  /* Ring Detect Line2 */
+#define AC97_GPIO_LINE2_CID     0x1000  /* Caller ID path enable Line2 */
+#define AC97_GPIO_LINE2_LCS     0x2000  /* Loop Current Sense Line2 */
+#define AC97_GPIO_LINE2_PULSE   0x4000  /* Opt./ Pulse Dial Line2 (out) */
+#define AC97_GPIO_LINE2_HL1R    0x8000  /* Opt./ Handset to Line2 relay control (out) */
+
diff --git a/include/sound/ac97_codec.h b/include/sound/ac97_codec.h
index 15aa5f07c955..89d311a503d3 100644
--- a/include/sound/ac97_codec.h
+++ b/include/sound/ac97_codec.h
@@ -28,6 +28,7 @@
 #include <linux/bitops.h>
 #include <linux/device.h>
 #include <linux/workqueue.h>
+#include <sound/ac97/regs.h>
 #include <sound/pcm.h>
 #include <sound/control.h>
 #include <sound/info.h>
@@ -35,244 +36,6 @@
 /* maximum number of devices on the AC97 bus */
 #define	AC97_BUS_MAX_DEVICES	4
 
-/*
- *  AC'97 codec registers
- */
-
-#define AC97_RESET		0x00	/* Reset */
-#define AC97_MASTER		0x02	/* Master Volume */
-#define AC97_HEADPHONE		0x04	/* Headphone Volume (optional) */
-#define AC97_MASTER_MONO	0x06	/* Master Volume Mono (optional) */
-#define AC97_MASTER_TONE	0x08	/* Master Tone (Bass & Treble) (optional) */
-#define AC97_PC_BEEP		0x0a	/* PC Beep Volume (optinal) */
-#define AC97_PHONE		0x0c	/* Phone Volume (optional) */
-#define AC97_MIC		0x0e	/* MIC Volume */
-#define AC97_LINE		0x10	/* Line In Volume */
-#define AC97_CD			0x12	/* CD Volume */
-#define AC97_VIDEO		0x14	/* Video Volume (optional) */
-#define AC97_AUX		0x16	/* AUX Volume (optional) */
-#define AC97_PCM		0x18	/* PCM Volume */
-#define AC97_REC_SEL		0x1a	/* Record Select */
-#define AC97_REC_GAIN		0x1c	/* Record Gain */
-#define AC97_REC_GAIN_MIC	0x1e	/* Record Gain MIC (optional) */
-#define AC97_GENERAL_PURPOSE	0x20	/* General Purpose (optional) */
-#define AC97_3D_CONTROL		0x22	/* 3D Control (optional) */
-#define AC97_INT_PAGING		0x24	/* Audio Interrupt & Paging (AC'97 2.3) */
-#define AC97_POWERDOWN		0x26	/* Powerdown control / status */
-/* range 0x28-0x3a - AUDIO AC'97 2.0 extensions */
-#define AC97_EXTENDED_ID	0x28	/* Extended Audio ID */
-#define AC97_EXTENDED_STATUS	0x2a	/* Extended Audio Status and Control */
-#define AC97_PCM_FRONT_DAC_RATE 0x2c	/* PCM Front DAC Rate */
-#define AC97_PCM_SURR_DAC_RATE	0x2e	/* PCM Surround DAC Rate */
-#define AC97_PCM_LFE_DAC_RATE	0x30	/* PCM LFE DAC Rate */
-#define AC97_PCM_LR_ADC_RATE	0x32	/* PCM LR ADC Rate */
-#define AC97_PCM_MIC_ADC_RATE	0x34	/* PCM MIC ADC Rate */
-#define AC97_CENTER_LFE_MASTER	0x36	/* Center + LFE Master Volume */
-#define AC97_SURROUND_MASTER	0x38	/* Surround (Rear) Master Volume */
-#define AC97_SPDIF		0x3a	/* S/PDIF control */
-/* range 0x3c-0x58 - MODEM */
-#define AC97_EXTENDED_MID	0x3c	/* Extended Modem ID */
-#define AC97_EXTENDED_MSTATUS	0x3e	/* Extended Modem Status and Control */
-#define AC97_LINE1_RATE		0x40	/* Line1 DAC/ADC Rate */
-#define AC97_LINE2_RATE		0x42	/* Line2 DAC/ADC Rate */
-#define AC97_HANDSET_RATE	0x44	/* Handset DAC/ADC Rate */
-#define AC97_LINE1_LEVEL	0x46	/* Line1 DAC/ADC Level */
-#define AC97_LINE2_LEVEL	0x48	/* Line2 DAC/ADC Level */
-#define AC97_HANDSET_LEVEL	0x4a	/* Handset DAC/ADC Level */
-#define AC97_GPIO_CFG		0x4c	/* GPIO Configuration */
-#define AC97_GPIO_POLARITY	0x4e	/* GPIO Pin Polarity/Type, 0=low, 1=high active */
-#define AC97_GPIO_STICKY	0x50	/* GPIO Pin Sticky, 0=not, 1=sticky */
-#define AC97_GPIO_WAKEUP	0x52	/* GPIO Pin Wakeup, 0=no int, 1=yes int */
-#define AC97_GPIO_STATUS	0x54	/* GPIO Pin Status, slot 12 */
-#define AC97_MISC_AFE		0x56	/* Miscellaneous Modem AFE Status and Control */
-/* range 0x5a-0x7b - Vendor Specific */
-#define AC97_VENDOR_ID1		0x7c	/* Vendor ID1 */
-#define AC97_VENDOR_ID2		0x7e	/* Vendor ID2 / revision */
-/* range 0x60-0x6f (page 1) - extended codec registers */
-#define AC97_CODEC_CLASS_REV	0x60	/* Codec Class/Revision */
-#define AC97_PCI_SVID		0x62	/* PCI Subsystem Vendor ID */
-#define AC97_PCI_SID		0x64	/* PCI Subsystem ID */
-#define AC97_FUNC_SELECT	0x66	/* Function Select */
-#define AC97_FUNC_INFO		0x68	/* Function Information */
-#define AC97_SENSE_INFO		0x6a	/* Sense Details */
-
-/* volume controls */
-#define AC97_MUTE_MASK_MONO	0x8000
-#define AC97_MUTE_MASK_STEREO	0x8080
-
-/* slot allocation */
-#define AC97_SLOT_TAG		0
-#define AC97_SLOT_CMD_ADDR	1
-#define AC97_SLOT_CMD_DATA	2
-#define AC97_SLOT_PCM_LEFT	3
-#define AC97_SLOT_PCM_RIGHT	4
-#define AC97_SLOT_MODEM_LINE1	5
-#define AC97_SLOT_PCM_CENTER	6
-#define AC97_SLOT_MIC		6	/* input */
-#define AC97_SLOT_SPDIF_LEFT1	6
-#define AC97_SLOT_PCM_SLEFT	7	/* surround left */
-#define AC97_SLOT_PCM_LEFT_0	7	/* double rate operation */
-#define AC97_SLOT_SPDIF_LEFT	7
-#define AC97_SLOT_PCM_SRIGHT	8	/* surround right */
-#define AC97_SLOT_PCM_RIGHT_0	8	/* double rate operation */
-#define AC97_SLOT_SPDIF_RIGHT	8
-#define AC97_SLOT_LFE		9
-#define AC97_SLOT_SPDIF_RIGHT1	9
-#define AC97_SLOT_MODEM_LINE2	10
-#define AC97_SLOT_PCM_LEFT_1	10	/* double rate operation */
-#define AC97_SLOT_SPDIF_LEFT2	10
-#define AC97_SLOT_HANDSET	11	/* output */
-#define AC97_SLOT_PCM_RIGHT_1	11	/* double rate operation */
-#define AC97_SLOT_SPDIF_RIGHT2	11
-#define AC97_SLOT_MODEM_GPIO	12	/* modem GPIO */
-#define AC97_SLOT_PCM_CENTER_1	12	/* double rate operation */
-
-/* basic capabilities (reset register) */
-#define AC97_BC_DEDICATED_MIC	0x0001	/* Dedicated Mic PCM In Channel */
-#define AC97_BC_RESERVED1	0x0002	/* Reserved (was Modem Line Codec support) */
-#define AC97_BC_BASS_TREBLE	0x0004	/* Bass & Treble Control */
-#define AC97_BC_SIM_STEREO	0x0008	/* Simulated stereo */
-#define AC97_BC_HEADPHONE	0x0010	/* Headphone Out Support */
-#define AC97_BC_LOUDNESS	0x0020	/* Loudness (bass boost) Support */
-#define AC97_BC_16BIT_DAC	0x0000	/* 16-bit DAC resolution */
-#define AC97_BC_18BIT_DAC	0x0040	/* 18-bit DAC resolution */
-#define AC97_BC_20BIT_DAC	0x0080	/* 20-bit DAC resolution */
-#define AC97_BC_DAC_MASK	0x00c0
-#define AC97_BC_16BIT_ADC	0x0000	/* 16-bit ADC resolution */
-#define AC97_BC_18BIT_ADC	0x0100	/* 18-bit ADC resolution */
-#define AC97_BC_20BIT_ADC	0x0200	/* 20-bit ADC resolution */
-#define AC97_BC_ADC_MASK	0x0300
-#define AC97_BC_3D_TECH_ID_MASK	0x7c00	/* Per-vendor ID of 3D enhancement */
-
-/* general purpose */
-#define AC97_GP_DRSS_MASK	0x0c00	/* double rate slot select */
-#define AC97_GP_DRSS_1011	0x0000	/* LR(C) 10+11(+12) */
-#define AC97_GP_DRSS_78		0x0400	/* LR 7+8 */
-
-/* powerdown bits */
-#define AC97_PD_ADC_STATUS	0x0001	/* ADC status (RO) */
-#define AC97_PD_DAC_STATUS	0x0002	/* DAC status (RO) */
-#define AC97_PD_MIXER_STATUS	0x0004	/* Analog mixer status (RO) */
-#define AC97_PD_VREF_STATUS	0x0008	/* Vref status (RO) */
-#define AC97_PD_PR0		0x0100	/* Power down PCM ADCs and input MUX */
-#define AC97_PD_PR1		0x0200	/* Power down PCM front DAC */
-#define AC97_PD_PR2		0x0400	/* Power down Mixer (Vref still on) */
-#define AC97_PD_PR3		0x0800	/* Power down Mixer (Vref off) */
-#define AC97_PD_PR4		0x1000	/* Power down AC-Link */
-#define AC97_PD_PR5		0x2000	/* Disable internal clock usage */
-#define AC97_PD_PR6		0x4000	/* Headphone amplifier */
-#define AC97_PD_EAPD		0x8000	/* External Amplifer Power Down (EAPD) */
-
-/* extended audio ID bit defines */
-#define AC97_EI_VRA		0x0001	/* Variable bit rate supported */
-#define AC97_EI_DRA		0x0002	/* Double rate supported */
-#define AC97_EI_SPDIF		0x0004	/* S/PDIF out supported */
-#define AC97_EI_VRM		0x0008	/* Variable bit rate supported for MIC */
-#define AC97_EI_DACS_SLOT_MASK	0x0030	/* DACs slot assignment */
-#define AC97_EI_DACS_SLOT_SHIFT	4
-#define AC97_EI_CDAC		0x0040	/* PCM Center DAC available */
-#define AC97_EI_SDAC		0x0080	/* PCM Surround DACs available */
-#define AC97_EI_LDAC		0x0100	/* PCM LFE DAC available */
-#define AC97_EI_AMAP		0x0200	/* indicates optional slot/DAC mapping based on codec ID */
-#define AC97_EI_REV_MASK	0x0c00	/* AC'97 revision mask */
-#define AC97_EI_REV_22		0x0400	/* AC'97 revision 2.2 */
-#define AC97_EI_REV_23		0x0800	/* AC'97 revision 2.3 */
-#define AC97_EI_REV_SHIFT	10
-#define AC97_EI_ADDR_MASK	0xc000	/* physical codec ID (address) */
-#define AC97_EI_ADDR_SHIFT	14
-
-/* extended audio status and control bit defines */
-#define AC97_EA_VRA		0x0001	/* Variable bit rate enable bit */
-#define AC97_EA_DRA		0x0002	/* Double-rate audio enable bit */
-#define AC97_EA_SPDIF		0x0004	/* S/PDIF out enable bit */
-#define AC97_EA_VRM		0x0008	/* Variable bit rate for MIC enable bit */
-#define AC97_EA_SPSA_SLOT_MASK	0x0030	/* Mask for slot assignment bits */
-#define AC97_EA_SPSA_SLOT_SHIFT 4
-#define AC97_EA_SPSA_3_4	0x0000	/* Slot assigned to 3 & 4 */
-#define AC97_EA_SPSA_7_8	0x0010	/* Slot assigned to 7 & 8 */
-#define AC97_EA_SPSA_6_9	0x0020	/* Slot assigned to 6 & 9 */
-#define AC97_EA_SPSA_10_11	0x0030	/* Slot assigned to 10 & 11 */
-#define AC97_EA_CDAC		0x0040	/* PCM Center DAC is ready (Read only) */
-#define AC97_EA_SDAC		0x0080	/* PCM Surround DACs are ready (Read only) */
-#define AC97_EA_LDAC		0x0100	/* PCM LFE DAC is ready (Read only) */
-#define AC97_EA_MDAC		0x0200	/* MIC ADC is ready (Read only) */
-#define AC97_EA_SPCV		0x0400	/* S/PDIF configuration valid (Read only) */
-#define AC97_EA_PRI		0x0800	/* Turns the PCM Center DAC off */
-#define AC97_EA_PRJ		0x1000	/* Turns the PCM Surround DACs off */
-#define AC97_EA_PRK		0x2000	/* Turns the PCM LFE DAC off */
-#define AC97_EA_PRL		0x4000	/* Turns the MIC ADC off */
-
-/* S/PDIF control bit defines */
-#define AC97_SC_PRO		0x0001	/* Professional status */
-#define AC97_SC_NAUDIO		0x0002	/* Non audio stream */
-#define AC97_SC_COPY		0x0004	/* Copyright status */
-#define AC97_SC_PRE		0x0008	/* Preemphasis status */
-#define AC97_SC_CC_MASK		0x07f0	/* Category Code mask */
-#define AC97_SC_CC_SHIFT	4
-#define AC97_SC_L		0x0800	/* Generation Level status */
-#define AC97_SC_SPSR_MASK	0x3000	/* S/PDIF Sample Rate bits */
-#define AC97_SC_SPSR_SHIFT	12
-#define AC97_SC_SPSR_44K	0x0000	/* Use 44.1kHz Sample rate */
-#define AC97_SC_SPSR_48K	0x2000	/* Use 48kHz Sample rate */
-#define AC97_SC_SPSR_32K	0x3000	/* Use 32kHz Sample rate */
-#define AC97_SC_DRS		0x4000	/* Double Rate S/PDIF */
-#define AC97_SC_V		0x8000	/* Validity status */
-
-/* Interrupt and Paging bit defines (AC'97 2.3) */
-#define AC97_PAGE_MASK		0x000f	/* Page Selector */
-#define AC97_PAGE_VENDOR	0	/* Vendor-specific registers */
-#define AC97_PAGE_1		1	/* Extended Codec Registers page 1 */
-#define AC97_INT_ENABLE		0x0800	/* Interrupt Enable */
-#define AC97_INT_SENSE		0x1000	/* Sense Cycle */
-#define AC97_INT_CAUSE_SENSE	0x2000	/* Sense Cycle Completed (RO) */
-#define AC97_INT_CAUSE_GPIO	0x4000	/* GPIO bits changed (RO) */
-#define AC97_INT_STATUS		0x8000	/* Interrupt Status */
-
-/* extended modem ID bit defines */
-#define AC97_MEI_LINE1		0x0001	/* Line1 present */
-#define AC97_MEI_LINE2		0x0002	/* Line2 present */
-#define AC97_MEI_HANDSET	0x0004	/* Handset present */
-#define AC97_MEI_CID1		0x0008	/* caller ID decode for Line1 is supported */
-#define AC97_MEI_CID2		0x0010	/* caller ID decode for Line2 is supported */
-#define AC97_MEI_ADDR_MASK	0xc000	/* physical codec ID (address) */
-#define AC97_MEI_ADDR_SHIFT	14
-
-/* extended modem status and control bit defines */
-#define AC97_MEA_GPIO		0x0001	/* GPIO is ready (ro) */
-#define AC97_MEA_MREF		0x0002	/* Vref is up to nominal level (ro) */
-#define AC97_MEA_ADC1		0x0004	/* ADC1 operational (ro) */
-#define AC97_MEA_DAC1		0x0008	/* DAC1 operational (ro) */
-#define AC97_MEA_ADC2		0x0010	/* ADC2 operational (ro) */
-#define AC97_MEA_DAC2		0x0020	/* DAC2 operational (ro) */
-#define AC97_MEA_HADC		0x0040	/* HADC operational (ro) */
-#define AC97_MEA_HDAC		0x0080	/* HDAC operational (ro) */
-#define AC97_MEA_PRA		0x0100	/* GPIO power down (high) */
-#define AC97_MEA_PRB		0x0200	/* reserved */
-#define AC97_MEA_PRC		0x0400	/* ADC1 power down (high) */
-#define AC97_MEA_PRD		0x0800	/* DAC1 power down (high) */
-#define AC97_MEA_PRE		0x1000	/* ADC2 power down (high) */
-#define AC97_MEA_PRF		0x2000	/* DAC2 power down (high) */
-#define AC97_MEA_PRG		0x4000	/* HADC power down (high) */
-#define AC97_MEA_PRH		0x8000	/* HDAC power down (high) */
-
-/* modem gpio status defines */
-#define AC97_GPIO_LINE1_OH      0x0001  /* Off Hook Line1 */
-#define AC97_GPIO_LINE1_RI      0x0002  /* Ring Detect Line1 */
-#define AC97_GPIO_LINE1_CID     0x0004  /* Caller ID path enable Line1 */
-#define AC97_GPIO_LINE1_LCS     0x0008  /* Loop Current Sense Line1 */
-#define AC97_GPIO_LINE1_PULSE   0x0010  /* Opt./ Pulse Dial Line1 (out) */
-#define AC97_GPIO_LINE1_HL1R    0x0020  /* Opt./ Handset to Line1 relay control (out) */
-#define AC97_GPIO_LINE1_HOHD    0x0040  /* Opt./ Handset off hook detect Line1 (in) */
-#define AC97_GPIO_LINE12_AC     0x0080  /* Opt./ Int.bit 1 / Line1/2 AC (out) */
-#define AC97_GPIO_LINE12_DC     0x0100  /* Opt./ Int.bit 2 / Line1/2 DC (out) */
-#define AC97_GPIO_LINE12_RS     0x0200  /* Opt./ Int.bit 3 / Line1/2 RS (out) */
-#define AC97_GPIO_LINE2_OH      0x0400  /* Off Hook Line2 */
-#define AC97_GPIO_LINE2_RI      0x0800  /* Ring Detect Line2 */
-#define AC97_GPIO_LINE2_CID     0x1000  /* Caller ID path enable Line2 */
-#define AC97_GPIO_LINE2_LCS     0x2000  /* Loop Current Sense Line2 */
-#define AC97_GPIO_LINE2_PULSE   0x4000  /* Opt./ Pulse Dial Line2 (out) */
-#define AC97_GPIO_LINE2_HL1R    0x8000  /* Opt./ Handset to Line2 relay control (out) */
-
 /* specific - SigmaTel */
 #define AC97_SIGMATEL_OUTSEL	0x64	/* Output Select, STAC9758 */
 #define AC97_SIGMATEL_INSEL	0x66	/* Input Select, STAC9758 */
-- 
2.14.1

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

* Applied "ALSA: ac97: split out the generic ac97 registers" to the asoc tree
@ 2017-09-04 17:25     ` Mark Brown
  0 siblings, 0 replies; 74+ messages in thread
From: Mark Brown @ 2017-09-04 17:25 UTC (permalink / raw)
  To: Robert Jarzmik
  Cc: Mark Brown, Daniel Mack, Haojian Zhuang, Jaroslav Kysela,
	Takashi Iwai, Liam Girdwood

The patch

   ALSA: ac97: split out the generic ac97 registers

has been applied to the asoc tree at

   git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

>From 8e4f7d9b8c652b4eb3ceb790e1e9fe433f9e3b58 Mon Sep 17 00:00:00 2001
From: Robert Jarzmik <robert.jarzmik@free.fr>
Date: Sat, 2 Sep 2017 21:54:03 +0200
Subject: [PATCH] ALSA: ac97: split out the generic ac97 registers

Split out from the ac97_codec.h the ac97 generic registers, which can be
used by a codec, typically a generic ac97 codec, and by the ac97 bus, to
scan an ac97 AC-Link.

This split encompasses all the AC97 standard registers, but not the
codec specific ones.

In order to have a clean split between former ac97 bus implementation
and the new coming one in sound/ac97, it is safer to not include any
former ac97 includes, excepting in sound/ac97/compat.c.

Amongst the thing to isolate :
 - don't have the struct snd_ac97 in sound/ac97/* (except compat.c) to not
   be "fooled" by a definition which would come with ac97_codec.h by
   "chance".
 - don't have to have snd_a97_*() functions, as they rely on struct
   snd_ac97.
  - don't want the struct snd_ac97_bus_ops, there is a new one

Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
Reviewed-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 include/sound/ac97/regs.h  | 262 +++++++++++++++++++++++++++++++++++++++++++++
 include/sound/ac97_codec.h | 239 +----------------------------------------
 2 files changed, 263 insertions(+), 238 deletions(-)
 create mode 100644 include/sound/ac97/regs.h

diff --git a/include/sound/ac97/regs.h b/include/sound/ac97/regs.h
new file mode 100644
index 000000000000..4bb86d379bd5
--- /dev/null
+++ b/include/sound/ac97/regs.h
@@ -0,0 +1,262 @@
+/*
+ *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>
+ *  Universal interface for Audio Codec '97
+ *
+ *  For more details look to AC '97 component specification revision 2.1
+ *  by Intel Corporation (http://developer.intel.com).
+ *
+ *
+ *   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
+ *
+ */
+
+/*
+ *  AC'97 codec registers
+ */
+
+#define AC97_RESET		0x00	/* Reset */
+#define AC97_MASTER		0x02	/* Master Volume */
+#define AC97_HEADPHONE		0x04	/* Headphone Volume (optional) */
+#define AC97_MASTER_MONO	0x06	/* Master Volume Mono (optional) */
+#define AC97_MASTER_TONE	0x08	/* Master Tone (Bass & Treble) (optional) */
+#define AC97_PC_BEEP		0x0a	/* PC Beep Volume (optinal) */
+#define AC97_PHONE		0x0c	/* Phone Volume (optional) */
+#define AC97_MIC		0x0e	/* MIC Volume */
+#define AC97_LINE		0x10	/* Line In Volume */
+#define AC97_CD			0x12	/* CD Volume */
+#define AC97_VIDEO		0x14	/* Video Volume (optional) */
+#define AC97_AUX		0x16	/* AUX Volume (optional) */
+#define AC97_PCM		0x18	/* PCM Volume */
+#define AC97_REC_SEL		0x1a	/* Record Select */
+#define AC97_REC_GAIN		0x1c	/* Record Gain */
+#define AC97_REC_GAIN_MIC	0x1e	/* Record Gain MIC (optional) */
+#define AC97_GENERAL_PURPOSE	0x20	/* General Purpose (optional) */
+#define AC97_3D_CONTROL		0x22	/* 3D Control (optional) */
+#define AC97_INT_PAGING		0x24	/* Audio Interrupt & Paging (AC'97 2.3) */
+#define AC97_POWERDOWN		0x26	/* Powerdown control / status */
+/* range 0x28-0x3a - AUDIO AC'97 2.0 extensions */
+#define AC97_EXTENDED_ID	0x28	/* Extended Audio ID */
+#define AC97_EXTENDED_STATUS	0x2a	/* Extended Audio Status and Control */
+#define AC97_PCM_FRONT_DAC_RATE 0x2c	/* PCM Front DAC Rate */
+#define AC97_PCM_SURR_DAC_RATE	0x2e	/* PCM Surround DAC Rate */
+#define AC97_PCM_LFE_DAC_RATE	0x30	/* PCM LFE DAC Rate */
+#define AC97_PCM_LR_ADC_RATE	0x32	/* PCM LR ADC Rate */
+#define AC97_PCM_MIC_ADC_RATE	0x34	/* PCM MIC ADC Rate */
+#define AC97_CENTER_LFE_MASTER	0x36	/* Center + LFE Master Volume */
+#define AC97_SURROUND_MASTER	0x38	/* Surround (Rear) Master Volume */
+#define AC97_SPDIF		0x3a	/* S/PDIF control */
+/* range 0x3c-0x58 - MODEM */
+#define AC97_EXTENDED_MID	0x3c	/* Extended Modem ID */
+#define AC97_EXTENDED_MSTATUS	0x3e	/* Extended Modem Status and Control */
+#define AC97_LINE1_RATE		0x40	/* Line1 DAC/ADC Rate */
+#define AC97_LINE2_RATE		0x42	/* Line2 DAC/ADC Rate */
+#define AC97_HANDSET_RATE	0x44	/* Handset DAC/ADC Rate */
+#define AC97_LINE1_LEVEL	0x46	/* Line1 DAC/ADC Level */
+#define AC97_LINE2_LEVEL	0x48	/* Line2 DAC/ADC Level */
+#define AC97_HANDSET_LEVEL	0x4a	/* Handset DAC/ADC Level */
+#define AC97_GPIO_CFG		0x4c	/* GPIO Configuration */
+#define AC97_GPIO_POLARITY	0x4e	/* GPIO Pin Polarity/Type, 0=low, 1=high active */
+#define AC97_GPIO_STICKY	0x50	/* GPIO Pin Sticky, 0=not, 1=sticky */
+#define AC97_GPIO_WAKEUP	0x52	/* GPIO Pin Wakeup, 0=no int, 1=yes int */
+#define AC97_GPIO_STATUS	0x54	/* GPIO Pin Status, slot 12 */
+#define AC97_MISC_AFE		0x56	/* Miscellaneous Modem AFE Status and Control */
+/* range 0x5a-0x7b - Vendor Specific */
+#define AC97_VENDOR_ID1		0x7c	/* Vendor ID1 */
+#define AC97_VENDOR_ID2		0x7e	/* Vendor ID2 / revision */
+/* range 0x60-0x6f (page 1) - extended codec registers */
+#define AC97_CODEC_CLASS_REV	0x60	/* Codec Class/Revision */
+#define AC97_PCI_SVID		0x62	/* PCI Subsystem Vendor ID */
+#define AC97_PCI_SID		0x64	/* PCI Subsystem ID */
+#define AC97_FUNC_SELECT	0x66	/* Function Select */
+#define AC97_FUNC_INFO		0x68	/* Function Information */
+#define AC97_SENSE_INFO		0x6a	/* Sense Details */
+
+/* volume controls */
+#define AC97_MUTE_MASK_MONO	0x8000
+#define AC97_MUTE_MASK_STEREO	0x8080
+
+/* slot allocation */
+#define AC97_SLOT_TAG		0
+#define AC97_SLOT_CMD_ADDR	1
+#define AC97_SLOT_CMD_DATA	2
+#define AC97_SLOT_PCM_LEFT	3
+#define AC97_SLOT_PCM_RIGHT	4
+#define AC97_SLOT_MODEM_LINE1	5
+#define AC97_SLOT_PCM_CENTER	6
+#define AC97_SLOT_MIC		6	/* input */
+#define AC97_SLOT_SPDIF_LEFT1	6
+#define AC97_SLOT_PCM_SLEFT	7	/* surround left */
+#define AC97_SLOT_PCM_LEFT_0	7	/* double rate operation */
+#define AC97_SLOT_SPDIF_LEFT	7
+#define AC97_SLOT_PCM_SRIGHT	8	/* surround right */
+#define AC97_SLOT_PCM_RIGHT_0	8	/* double rate operation */
+#define AC97_SLOT_SPDIF_RIGHT	8
+#define AC97_SLOT_LFE		9
+#define AC97_SLOT_SPDIF_RIGHT1	9
+#define AC97_SLOT_MODEM_LINE2	10
+#define AC97_SLOT_PCM_LEFT_1	10	/* double rate operation */
+#define AC97_SLOT_SPDIF_LEFT2	10
+#define AC97_SLOT_HANDSET	11	/* output */
+#define AC97_SLOT_PCM_RIGHT_1	11	/* double rate operation */
+#define AC97_SLOT_SPDIF_RIGHT2	11
+#define AC97_SLOT_MODEM_GPIO	12	/* modem GPIO */
+#define AC97_SLOT_PCM_CENTER_1	12	/* double rate operation */
+
+/* basic capabilities (reset register) */
+#define AC97_BC_DEDICATED_MIC	0x0001	/* Dedicated Mic PCM In Channel */
+#define AC97_BC_RESERVED1	0x0002	/* Reserved (was Modem Line Codec support) */
+#define AC97_BC_BASS_TREBLE	0x0004	/* Bass & Treble Control */
+#define AC97_BC_SIM_STEREO	0x0008	/* Simulated stereo */
+#define AC97_BC_HEADPHONE	0x0010	/* Headphone Out Support */
+#define AC97_BC_LOUDNESS	0x0020	/* Loudness (bass boost) Support */
+#define AC97_BC_16BIT_DAC	0x0000	/* 16-bit DAC resolution */
+#define AC97_BC_18BIT_DAC	0x0040	/* 18-bit DAC resolution */
+#define AC97_BC_20BIT_DAC	0x0080	/* 20-bit DAC resolution */
+#define AC97_BC_DAC_MASK	0x00c0
+#define AC97_BC_16BIT_ADC	0x0000	/* 16-bit ADC resolution */
+#define AC97_BC_18BIT_ADC	0x0100	/* 18-bit ADC resolution */
+#define AC97_BC_20BIT_ADC	0x0200	/* 20-bit ADC resolution */
+#define AC97_BC_ADC_MASK	0x0300
+#define AC97_BC_3D_TECH_ID_MASK	0x7c00	/* Per-vendor ID of 3D enhancement */
+
+/* general purpose */
+#define AC97_GP_DRSS_MASK	0x0c00	/* double rate slot select */
+#define AC97_GP_DRSS_1011	0x0000	/* LR(C) 10+11(+12) */
+#define AC97_GP_DRSS_78		0x0400	/* LR 7+8 */
+
+/* powerdown bits */
+#define AC97_PD_ADC_STATUS	0x0001	/* ADC status (RO) */
+#define AC97_PD_DAC_STATUS	0x0002	/* DAC status (RO) */
+#define AC97_PD_MIXER_STATUS	0x0004	/* Analog mixer status (RO) */
+#define AC97_PD_VREF_STATUS	0x0008	/* Vref status (RO) */
+#define AC97_PD_PR0		0x0100	/* Power down PCM ADCs and input MUX */
+#define AC97_PD_PR1		0x0200	/* Power down PCM front DAC */
+#define AC97_PD_PR2		0x0400	/* Power down Mixer (Vref still on) */
+#define AC97_PD_PR3		0x0800	/* Power down Mixer (Vref off) */
+#define AC97_PD_PR4		0x1000	/* Power down AC-Link */
+#define AC97_PD_PR5		0x2000	/* Disable internal clock usage */
+#define AC97_PD_PR6		0x4000	/* Headphone amplifier */
+#define AC97_PD_EAPD		0x8000	/* External Amplifer Power Down (EAPD) */
+
+/* extended audio ID bit defines */
+#define AC97_EI_VRA		0x0001	/* Variable bit rate supported */
+#define AC97_EI_DRA		0x0002	/* Double rate supported */
+#define AC97_EI_SPDIF		0x0004	/* S/PDIF out supported */
+#define AC97_EI_VRM		0x0008	/* Variable bit rate supported for MIC */
+#define AC97_EI_DACS_SLOT_MASK	0x0030	/* DACs slot assignment */
+#define AC97_EI_DACS_SLOT_SHIFT	4
+#define AC97_EI_CDAC		0x0040	/* PCM Center DAC available */
+#define AC97_EI_SDAC		0x0080	/* PCM Surround DACs available */
+#define AC97_EI_LDAC		0x0100	/* PCM LFE DAC available */
+#define AC97_EI_AMAP		0x0200	/* indicates optional slot/DAC mapping based on codec ID */
+#define AC97_EI_REV_MASK	0x0c00	/* AC'97 revision mask */
+#define AC97_EI_REV_22		0x0400	/* AC'97 revision 2.2 */
+#define AC97_EI_REV_23		0x0800	/* AC'97 revision 2.3 */
+#define AC97_EI_REV_SHIFT	10
+#define AC97_EI_ADDR_MASK	0xc000	/* physical codec ID (address) */
+#define AC97_EI_ADDR_SHIFT	14
+
+/* extended audio status and control bit defines */
+#define AC97_EA_VRA		0x0001	/* Variable bit rate enable bit */
+#define AC97_EA_DRA		0x0002	/* Double-rate audio enable bit */
+#define AC97_EA_SPDIF		0x0004	/* S/PDIF out enable bit */
+#define AC97_EA_VRM		0x0008	/* Variable bit rate for MIC enable bit */
+#define AC97_EA_SPSA_SLOT_MASK	0x0030	/* Mask for slot assignment bits */
+#define AC97_EA_SPSA_SLOT_SHIFT 4
+#define AC97_EA_SPSA_3_4	0x0000	/* Slot assigned to 3 & 4 */
+#define AC97_EA_SPSA_7_8	0x0010	/* Slot assigned to 7 & 8 */
+#define AC97_EA_SPSA_6_9	0x0020	/* Slot assigned to 6 & 9 */
+#define AC97_EA_SPSA_10_11	0x0030	/* Slot assigned to 10 & 11 */
+#define AC97_EA_CDAC		0x0040	/* PCM Center DAC is ready (Read only) */
+#define AC97_EA_SDAC		0x0080	/* PCM Surround DACs are ready (Read only) */
+#define AC97_EA_LDAC		0x0100	/* PCM LFE DAC is ready (Read only) */
+#define AC97_EA_MDAC		0x0200	/* MIC ADC is ready (Read only) */
+#define AC97_EA_SPCV		0x0400	/* S/PDIF configuration valid (Read only) */
+#define AC97_EA_PRI		0x0800	/* Turns the PCM Center DAC off */
+#define AC97_EA_PRJ		0x1000	/* Turns the PCM Surround DACs off */
+#define AC97_EA_PRK		0x2000	/* Turns the PCM LFE DAC off */
+#define AC97_EA_PRL		0x4000	/* Turns the MIC ADC off */
+
+/* S/PDIF control bit defines */
+#define AC97_SC_PRO		0x0001	/* Professional status */
+#define AC97_SC_NAUDIO		0x0002	/* Non audio stream */
+#define AC97_SC_COPY		0x0004	/* Copyright status */
+#define AC97_SC_PRE		0x0008	/* Preemphasis status */
+#define AC97_SC_CC_MASK		0x07f0	/* Category Code mask */
+#define AC97_SC_CC_SHIFT	4
+#define AC97_SC_L		0x0800	/* Generation Level status */
+#define AC97_SC_SPSR_MASK	0x3000	/* S/PDIF Sample Rate bits */
+#define AC97_SC_SPSR_SHIFT	12
+#define AC97_SC_SPSR_44K	0x0000	/* Use 44.1kHz Sample rate */
+#define AC97_SC_SPSR_48K	0x2000	/* Use 48kHz Sample rate */
+#define AC97_SC_SPSR_32K	0x3000	/* Use 32kHz Sample rate */
+#define AC97_SC_DRS		0x4000	/* Double Rate S/PDIF */
+#define AC97_SC_V		0x8000	/* Validity status */
+
+/* Interrupt and Paging bit defines (AC'97 2.3) */
+#define AC97_PAGE_MASK		0x000f	/* Page Selector */
+#define AC97_PAGE_VENDOR	0	/* Vendor-specific registers */
+#define AC97_PAGE_1		1	/* Extended Codec Registers page 1 */
+#define AC97_INT_ENABLE		0x0800	/* Interrupt Enable */
+#define AC97_INT_SENSE		0x1000	/* Sense Cycle */
+#define AC97_INT_CAUSE_SENSE	0x2000	/* Sense Cycle Completed (RO) */
+#define AC97_INT_CAUSE_GPIO	0x4000	/* GPIO bits changed (RO) */
+#define AC97_INT_STATUS		0x8000	/* Interrupt Status */
+
+/* extended modem ID bit defines */
+#define AC97_MEI_LINE1		0x0001	/* Line1 present */
+#define AC97_MEI_LINE2		0x0002	/* Line2 present */
+#define AC97_MEI_HANDSET	0x0004	/* Handset present */
+#define AC97_MEI_CID1		0x0008	/* caller ID decode for Line1 is supported */
+#define AC97_MEI_CID2		0x0010	/* caller ID decode for Line2 is supported */
+#define AC97_MEI_ADDR_MASK	0xc000	/* physical codec ID (address) */
+#define AC97_MEI_ADDR_SHIFT	14
+
+/* extended modem status and control bit defines */
+#define AC97_MEA_GPIO		0x0001	/* GPIO is ready (ro) */
+#define AC97_MEA_MREF		0x0002	/* Vref is up to nominal level (ro) */
+#define AC97_MEA_ADC1		0x0004	/* ADC1 operational (ro) */
+#define AC97_MEA_DAC1		0x0008	/* DAC1 operational (ro) */
+#define AC97_MEA_ADC2		0x0010	/* ADC2 operational (ro) */
+#define AC97_MEA_DAC2		0x0020	/* DAC2 operational (ro) */
+#define AC97_MEA_HADC		0x0040	/* HADC operational (ro) */
+#define AC97_MEA_HDAC		0x0080	/* HDAC operational (ro) */
+#define AC97_MEA_PRA		0x0100	/* GPIO power down (high) */
+#define AC97_MEA_PRB		0x0200	/* reserved */
+#define AC97_MEA_PRC		0x0400	/* ADC1 power down (high) */
+#define AC97_MEA_PRD		0x0800	/* DAC1 power down (high) */
+#define AC97_MEA_PRE		0x1000	/* ADC2 power down (high) */
+#define AC97_MEA_PRF		0x2000	/* DAC2 power down (high) */
+#define AC97_MEA_PRG		0x4000	/* HADC power down (high) */
+#define AC97_MEA_PRH		0x8000	/* HDAC power down (high) */
+
+/* modem gpio status defines */
+#define AC97_GPIO_LINE1_OH      0x0001  /* Off Hook Line1 */
+#define AC97_GPIO_LINE1_RI      0x0002  /* Ring Detect Line1 */
+#define AC97_GPIO_LINE1_CID     0x0004  /* Caller ID path enable Line1 */
+#define AC97_GPIO_LINE1_LCS     0x0008  /* Loop Current Sense Line1 */
+#define AC97_GPIO_LINE1_PULSE   0x0010  /* Opt./ Pulse Dial Line1 (out) */
+#define AC97_GPIO_LINE1_HL1R    0x0020  /* Opt./ Handset to Line1 relay control (out) */
+#define AC97_GPIO_LINE1_HOHD    0x0040  /* Opt./ Handset off hook detect Line1 (in) */
+#define AC97_GPIO_LINE12_AC     0x0080  /* Opt./ Int.bit 1 / Line1/2 AC (out) */
+#define AC97_GPIO_LINE12_DC     0x0100  /* Opt./ Int.bit 2 / Line1/2 DC (out) */
+#define AC97_GPIO_LINE12_RS     0x0200  /* Opt./ Int.bit 3 / Line1/2 RS (out) */
+#define AC97_GPIO_LINE2_OH      0x0400  /* Off Hook Line2 */
+#define AC97_GPIO_LINE2_RI      0x0800  /* Ring Detect Line2 */
+#define AC97_GPIO_LINE2_CID     0x1000  /* Caller ID path enable Line2 */
+#define AC97_GPIO_LINE2_LCS     0x2000  /* Loop Current Sense Line2 */
+#define AC97_GPIO_LINE2_PULSE   0x4000  /* Opt./ Pulse Dial Line2 (out) */
+#define AC97_GPIO_LINE2_HL1R    0x8000  /* Opt./ Handset to Line2 relay control (out) */
+
diff --git a/include/sound/ac97_codec.h b/include/sound/ac97_codec.h
index 15aa5f07c955..89d311a503d3 100644
--- a/include/sound/ac97_codec.h
+++ b/include/sound/ac97_codec.h
@@ -28,6 +28,7 @@
 #include <linux/bitops.h>
 #include <linux/device.h>
 #include <linux/workqueue.h>
+#include <sound/ac97/regs.h>
 #include <sound/pcm.h>
 #include <sound/control.h>
 #include <sound/info.h>
@@ -35,244 +36,6 @@
 /* maximum number of devices on the AC97 bus */
 #define	AC97_BUS_MAX_DEVICES	4
 
-/*
- *  AC'97 codec registers
- */
-
-#define AC97_RESET		0x00	/* Reset */
-#define AC97_MASTER		0x02	/* Master Volume */
-#define AC97_HEADPHONE		0x04	/* Headphone Volume (optional) */
-#define AC97_MASTER_MONO	0x06	/* Master Volume Mono (optional) */
-#define AC97_MASTER_TONE	0x08	/* Master Tone (Bass & Treble) (optional) */
-#define AC97_PC_BEEP		0x0a	/* PC Beep Volume (optinal) */
-#define AC97_PHONE		0x0c	/* Phone Volume (optional) */
-#define AC97_MIC		0x0e	/* MIC Volume */
-#define AC97_LINE		0x10	/* Line In Volume */
-#define AC97_CD			0x12	/* CD Volume */
-#define AC97_VIDEO		0x14	/* Video Volume (optional) */
-#define AC97_AUX		0x16	/* AUX Volume (optional) */
-#define AC97_PCM		0x18	/* PCM Volume */
-#define AC97_REC_SEL		0x1a	/* Record Select */
-#define AC97_REC_GAIN		0x1c	/* Record Gain */
-#define AC97_REC_GAIN_MIC	0x1e	/* Record Gain MIC (optional) */
-#define AC97_GENERAL_PURPOSE	0x20	/* General Purpose (optional) */
-#define AC97_3D_CONTROL		0x22	/* 3D Control (optional) */
-#define AC97_INT_PAGING		0x24	/* Audio Interrupt & Paging (AC'97 2.3) */
-#define AC97_POWERDOWN		0x26	/* Powerdown control / status */
-/* range 0x28-0x3a - AUDIO AC'97 2.0 extensions */
-#define AC97_EXTENDED_ID	0x28	/* Extended Audio ID */
-#define AC97_EXTENDED_STATUS	0x2a	/* Extended Audio Status and Control */
-#define AC97_PCM_FRONT_DAC_RATE 0x2c	/* PCM Front DAC Rate */
-#define AC97_PCM_SURR_DAC_RATE	0x2e	/* PCM Surround DAC Rate */
-#define AC97_PCM_LFE_DAC_RATE	0x30	/* PCM LFE DAC Rate */
-#define AC97_PCM_LR_ADC_RATE	0x32	/* PCM LR ADC Rate */
-#define AC97_PCM_MIC_ADC_RATE	0x34	/* PCM MIC ADC Rate */
-#define AC97_CENTER_LFE_MASTER	0x36	/* Center + LFE Master Volume */
-#define AC97_SURROUND_MASTER	0x38	/* Surround (Rear) Master Volume */
-#define AC97_SPDIF		0x3a	/* S/PDIF control */
-/* range 0x3c-0x58 - MODEM */
-#define AC97_EXTENDED_MID	0x3c	/* Extended Modem ID */
-#define AC97_EXTENDED_MSTATUS	0x3e	/* Extended Modem Status and Control */
-#define AC97_LINE1_RATE		0x40	/* Line1 DAC/ADC Rate */
-#define AC97_LINE2_RATE		0x42	/* Line2 DAC/ADC Rate */
-#define AC97_HANDSET_RATE	0x44	/* Handset DAC/ADC Rate */
-#define AC97_LINE1_LEVEL	0x46	/* Line1 DAC/ADC Level */
-#define AC97_LINE2_LEVEL	0x48	/* Line2 DAC/ADC Level */
-#define AC97_HANDSET_LEVEL	0x4a	/* Handset DAC/ADC Level */
-#define AC97_GPIO_CFG		0x4c	/* GPIO Configuration */
-#define AC97_GPIO_POLARITY	0x4e	/* GPIO Pin Polarity/Type, 0=low, 1=high active */
-#define AC97_GPIO_STICKY	0x50	/* GPIO Pin Sticky, 0=not, 1=sticky */
-#define AC97_GPIO_WAKEUP	0x52	/* GPIO Pin Wakeup, 0=no int, 1=yes int */
-#define AC97_GPIO_STATUS	0x54	/* GPIO Pin Status, slot 12 */
-#define AC97_MISC_AFE		0x56	/* Miscellaneous Modem AFE Status and Control */
-/* range 0x5a-0x7b - Vendor Specific */
-#define AC97_VENDOR_ID1		0x7c	/* Vendor ID1 */
-#define AC97_VENDOR_ID2		0x7e	/* Vendor ID2 / revision */
-/* range 0x60-0x6f (page 1) - extended codec registers */
-#define AC97_CODEC_CLASS_REV	0x60	/* Codec Class/Revision */
-#define AC97_PCI_SVID		0x62	/* PCI Subsystem Vendor ID */
-#define AC97_PCI_SID		0x64	/* PCI Subsystem ID */
-#define AC97_FUNC_SELECT	0x66	/* Function Select */
-#define AC97_FUNC_INFO		0x68	/* Function Information */
-#define AC97_SENSE_INFO		0x6a	/* Sense Details */
-
-/* volume controls */
-#define AC97_MUTE_MASK_MONO	0x8000
-#define AC97_MUTE_MASK_STEREO	0x8080
-
-/* slot allocation */
-#define AC97_SLOT_TAG		0
-#define AC97_SLOT_CMD_ADDR	1
-#define AC97_SLOT_CMD_DATA	2
-#define AC97_SLOT_PCM_LEFT	3
-#define AC97_SLOT_PCM_RIGHT	4
-#define AC97_SLOT_MODEM_LINE1	5
-#define AC97_SLOT_PCM_CENTER	6
-#define AC97_SLOT_MIC		6	/* input */
-#define AC97_SLOT_SPDIF_LEFT1	6
-#define AC97_SLOT_PCM_SLEFT	7	/* surround left */
-#define AC97_SLOT_PCM_LEFT_0	7	/* double rate operation */
-#define AC97_SLOT_SPDIF_LEFT	7
-#define AC97_SLOT_PCM_SRIGHT	8	/* surround right */
-#define AC97_SLOT_PCM_RIGHT_0	8	/* double rate operation */
-#define AC97_SLOT_SPDIF_RIGHT	8
-#define AC97_SLOT_LFE		9
-#define AC97_SLOT_SPDIF_RIGHT1	9
-#define AC97_SLOT_MODEM_LINE2	10
-#define AC97_SLOT_PCM_LEFT_1	10	/* double rate operation */
-#define AC97_SLOT_SPDIF_LEFT2	10
-#define AC97_SLOT_HANDSET	11	/* output */
-#define AC97_SLOT_PCM_RIGHT_1	11	/* double rate operation */
-#define AC97_SLOT_SPDIF_RIGHT2	11
-#define AC97_SLOT_MODEM_GPIO	12	/* modem GPIO */
-#define AC97_SLOT_PCM_CENTER_1	12	/* double rate operation */
-
-/* basic capabilities (reset register) */
-#define AC97_BC_DEDICATED_MIC	0x0001	/* Dedicated Mic PCM In Channel */
-#define AC97_BC_RESERVED1	0x0002	/* Reserved (was Modem Line Codec support) */
-#define AC97_BC_BASS_TREBLE	0x0004	/* Bass & Treble Control */
-#define AC97_BC_SIM_STEREO	0x0008	/* Simulated stereo */
-#define AC97_BC_HEADPHONE	0x0010	/* Headphone Out Support */
-#define AC97_BC_LOUDNESS	0x0020	/* Loudness (bass boost) Support */
-#define AC97_BC_16BIT_DAC	0x0000	/* 16-bit DAC resolution */
-#define AC97_BC_18BIT_DAC	0x0040	/* 18-bit DAC resolution */
-#define AC97_BC_20BIT_DAC	0x0080	/* 20-bit DAC resolution */
-#define AC97_BC_DAC_MASK	0x00c0
-#define AC97_BC_16BIT_ADC	0x0000	/* 16-bit ADC resolution */
-#define AC97_BC_18BIT_ADC	0x0100	/* 18-bit ADC resolution */
-#define AC97_BC_20BIT_ADC	0x0200	/* 20-bit ADC resolution */
-#define AC97_BC_ADC_MASK	0x0300
-#define AC97_BC_3D_TECH_ID_MASK	0x7c00	/* Per-vendor ID of 3D enhancement */
-
-/* general purpose */
-#define AC97_GP_DRSS_MASK	0x0c00	/* double rate slot select */
-#define AC97_GP_DRSS_1011	0x0000	/* LR(C) 10+11(+12) */
-#define AC97_GP_DRSS_78		0x0400	/* LR 7+8 */
-
-/* powerdown bits */
-#define AC97_PD_ADC_STATUS	0x0001	/* ADC status (RO) */
-#define AC97_PD_DAC_STATUS	0x0002	/* DAC status (RO) */
-#define AC97_PD_MIXER_STATUS	0x0004	/* Analog mixer status (RO) */
-#define AC97_PD_VREF_STATUS	0x0008	/* Vref status (RO) */
-#define AC97_PD_PR0		0x0100	/* Power down PCM ADCs and input MUX */
-#define AC97_PD_PR1		0x0200	/* Power down PCM front DAC */
-#define AC97_PD_PR2		0x0400	/* Power down Mixer (Vref still on) */
-#define AC97_PD_PR3		0x0800	/* Power down Mixer (Vref off) */
-#define AC97_PD_PR4		0x1000	/* Power down AC-Link */
-#define AC97_PD_PR5		0x2000	/* Disable internal clock usage */
-#define AC97_PD_PR6		0x4000	/* Headphone amplifier */
-#define AC97_PD_EAPD		0x8000	/* External Amplifer Power Down (EAPD) */
-
-/* extended audio ID bit defines */
-#define AC97_EI_VRA		0x0001	/* Variable bit rate supported */
-#define AC97_EI_DRA		0x0002	/* Double rate supported */
-#define AC97_EI_SPDIF		0x0004	/* S/PDIF out supported */
-#define AC97_EI_VRM		0x0008	/* Variable bit rate supported for MIC */
-#define AC97_EI_DACS_SLOT_MASK	0x0030	/* DACs slot assignment */
-#define AC97_EI_DACS_SLOT_SHIFT	4
-#define AC97_EI_CDAC		0x0040	/* PCM Center DAC available */
-#define AC97_EI_SDAC		0x0080	/* PCM Surround DACs available */
-#define AC97_EI_LDAC		0x0100	/* PCM LFE DAC available */
-#define AC97_EI_AMAP		0x0200	/* indicates optional slot/DAC mapping based on codec ID */
-#define AC97_EI_REV_MASK	0x0c00	/* AC'97 revision mask */
-#define AC97_EI_REV_22		0x0400	/* AC'97 revision 2.2 */
-#define AC97_EI_REV_23		0x0800	/* AC'97 revision 2.3 */
-#define AC97_EI_REV_SHIFT	10
-#define AC97_EI_ADDR_MASK	0xc000	/* physical codec ID (address) */
-#define AC97_EI_ADDR_SHIFT	14
-
-/* extended audio status and control bit defines */
-#define AC97_EA_VRA		0x0001	/* Variable bit rate enable bit */
-#define AC97_EA_DRA		0x0002	/* Double-rate audio enable bit */
-#define AC97_EA_SPDIF		0x0004	/* S/PDIF out enable bit */
-#define AC97_EA_VRM		0x0008	/* Variable bit rate for MIC enable bit */
-#define AC97_EA_SPSA_SLOT_MASK	0x0030	/* Mask for slot assignment bits */
-#define AC97_EA_SPSA_SLOT_SHIFT 4
-#define AC97_EA_SPSA_3_4	0x0000	/* Slot assigned to 3 & 4 */
-#define AC97_EA_SPSA_7_8	0x0010	/* Slot assigned to 7 & 8 */
-#define AC97_EA_SPSA_6_9	0x0020	/* Slot assigned to 6 & 9 */
-#define AC97_EA_SPSA_10_11	0x0030	/* Slot assigned to 10 & 11 */
-#define AC97_EA_CDAC		0x0040	/* PCM Center DAC is ready (Read only) */
-#define AC97_EA_SDAC		0x0080	/* PCM Surround DACs are ready (Read only) */
-#define AC97_EA_LDAC		0x0100	/* PCM LFE DAC is ready (Read only) */
-#define AC97_EA_MDAC		0x0200	/* MIC ADC is ready (Read only) */
-#define AC97_EA_SPCV		0x0400	/* S/PDIF configuration valid (Read only) */
-#define AC97_EA_PRI		0x0800	/* Turns the PCM Center DAC off */
-#define AC97_EA_PRJ		0x1000	/* Turns the PCM Surround DACs off */
-#define AC97_EA_PRK		0x2000	/* Turns the PCM LFE DAC off */
-#define AC97_EA_PRL		0x4000	/* Turns the MIC ADC off */
-
-/* S/PDIF control bit defines */
-#define AC97_SC_PRO		0x0001	/* Professional status */
-#define AC97_SC_NAUDIO		0x0002	/* Non audio stream */
-#define AC97_SC_COPY		0x0004	/* Copyright status */
-#define AC97_SC_PRE		0x0008	/* Preemphasis status */
-#define AC97_SC_CC_MASK		0x07f0	/* Category Code mask */
-#define AC97_SC_CC_SHIFT	4
-#define AC97_SC_L		0x0800	/* Generation Level status */
-#define AC97_SC_SPSR_MASK	0x3000	/* S/PDIF Sample Rate bits */
-#define AC97_SC_SPSR_SHIFT	12
-#define AC97_SC_SPSR_44K	0x0000	/* Use 44.1kHz Sample rate */
-#define AC97_SC_SPSR_48K	0x2000	/* Use 48kHz Sample rate */
-#define AC97_SC_SPSR_32K	0x3000	/* Use 32kHz Sample rate */
-#define AC97_SC_DRS		0x4000	/* Double Rate S/PDIF */
-#define AC97_SC_V		0x8000	/* Validity status */
-
-/* Interrupt and Paging bit defines (AC'97 2.3) */
-#define AC97_PAGE_MASK		0x000f	/* Page Selector */
-#define AC97_PAGE_VENDOR	0	/* Vendor-specific registers */
-#define AC97_PAGE_1		1	/* Extended Codec Registers page 1 */
-#define AC97_INT_ENABLE		0x0800	/* Interrupt Enable */
-#define AC97_INT_SENSE		0x1000	/* Sense Cycle */
-#define AC97_INT_CAUSE_SENSE	0x2000	/* Sense Cycle Completed (RO) */
-#define AC97_INT_CAUSE_GPIO	0x4000	/* GPIO bits changed (RO) */
-#define AC97_INT_STATUS		0x8000	/* Interrupt Status */
-
-/* extended modem ID bit defines */
-#define AC97_MEI_LINE1		0x0001	/* Line1 present */
-#define AC97_MEI_LINE2		0x0002	/* Line2 present */
-#define AC97_MEI_HANDSET	0x0004	/* Handset present */
-#define AC97_MEI_CID1		0x0008	/* caller ID decode for Line1 is supported */
-#define AC97_MEI_CID2		0x0010	/* caller ID decode for Line2 is supported */
-#define AC97_MEI_ADDR_MASK	0xc000	/* physical codec ID (address) */
-#define AC97_MEI_ADDR_SHIFT	14
-
-/* extended modem status and control bit defines */
-#define AC97_MEA_GPIO		0x0001	/* GPIO is ready (ro) */
-#define AC97_MEA_MREF		0x0002	/* Vref is up to nominal level (ro) */
-#define AC97_MEA_ADC1		0x0004	/* ADC1 operational (ro) */
-#define AC97_MEA_DAC1		0x0008	/* DAC1 operational (ro) */
-#define AC97_MEA_ADC2		0x0010	/* ADC2 operational (ro) */
-#define AC97_MEA_DAC2		0x0020	/* DAC2 operational (ro) */
-#define AC97_MEA_HADC		0x0040	/* HADC operational (ro) */
-#define AC97_MEA_HDAC		0x0080	/* HDAC operational (ro) */
-#define AC97_MEA_PRA		0x0100	/* GPIO power down (high) */
-#define AC97_MEA_PRB		0x0200	/* reserved */
-#define AC97_MEA_PRC		0x0400	/* ADC1 power down (high) */
-#define AC97_MEA_PRD		0x0800	/* DAC1 power down (high) */
-#define AC97_MEA_PRE		0x1000	/* ADC2 power down (high) */
-#define AC97_MEA_PRF		0x2000	/* DAC2 power down (high) */
-#define AC97_MEA_PRG		0x4000	/* HADC power down (high) */
-#define AC97_MEA_PRH		0x8000	/* HDAC power down (high) */
-
-/* modem gpio status defines */
-#define AC97_GPIO_LINE1_OH      0x0001  /* Off Hook Line1 */
-#define AC97_GPIO_LINE1_RI      0x0002  /* Ring Detect Line1 */
-#define AC97_GPIO_LINE1_CID     0x0004  /* Caller ID path enable Line1 */
-#define AC97_GPIO_LINE1_LCS     0x0008  /* Loop Current Sense Line1 */
-#define AC97_GPIO_LINE1_PULSE   0x0010  /* Opt./ Pulse Dial Line1 (out) */
-#define AC97_GPIO_LINE1_HL1R    0x0020  /* Opt./ Handset to Line1 relay control (out) */
-#define AC97_GPIO_LINE1_HOHD    0x0040  /* Opt./ Handset off hook detect Line1 (in) */
-#define AC97_GPIO_LINE12_AC     0x0080  /* Opt./ Int.bit 1 / Line1/2 AC (out) */
-#define AC97_GPIO_LINE12_DC     0x0100  /* Opt./ Int.bit 2 / Line1/2 DC (out) */
-#define AC97_GPIO_LINE12_RS     0x0200  /* Opt./ Int.bit 3 / Line1/2 RS (out) */
-#define AC97_GPIO_LINE2_OH      0x0400  /* Off Hook Line2 */
-#define AC97_GPIO_LINE2_RI      0x0800  /* Ring Detect Line2 */
-#define AC97_GPIO_LINE2_CID     0x1000  /* Caller ID path enable Line2 */
-#define AC97_GPIO_LINE2_LCS     0x2000  /* Loop Current Sense Line2 */
-#define AC97_GPIO_LINE2_PULSE   0x4000  /* Opt./ Pulse Dial Line2 (out) */
-#define AC97_GPIO_LINE2_HL1R    0x8000  /* Opt./ Handset to Line2 relay control (out) */
-
 /* specific - SigmaTel */
 #define AC97_SIGMATEL_OUTSEL	0x64	/* Output Select, STAC9758 */
 #define AC97_SIGMATEL_INSEL	0x66	/* Input Select, STAC9758 */
-- 
2.14.1

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

* Applied "ALSA: ac97: split out the generic ac97 registers" to the asoc tree
@ 2017-09-04 17:25     ` Mark Brown
  0 siblings, 0 replies; 74+ messages in thread
From: Mark Brown @ 2017-09-04 17:25 UTC (permalink / raw)
  To: linux-arm-kernel

The patch

   ALSA: ac97: split out the generic ac97 registers

has been applied to the asoc tree at

   git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

>From 8e4f7d9b8c652b4eb3ceb790e1e9fe433f9e3b58 Mon Sep 17 00:00:00 2001
From: Robert Jarzmik <robert.jarzmik@free.fr>
Date: Sat, 2 Sep 2017 21:54:03 +0200
Subject: [PATCH] ALSA: ac97: split out the generic ac97 registers

Split out from the ac97_codec.h the ac97 generic registers, which can be
used by a codec, typically a generic ac97 codec, and by the ac97 bus, to
scan an ac97 AC-Link.

This split encompasses all the AC97 standard registers, but not the
codec specific ones.

In order to have a clean split between former ac97 bus implementation
and the new coming one in sound/ac97, it is safer to not include any
former ac97 includes, excepting in sound/ac97/compat.c.

Amongst the thing to isolate :
 - don't have the struct snd_ac97 in sound/ac97/* (except compat.c) to not
   be "fooled" by a definition which would come with ac97_codec.h by
   "chance".
 - don't have to have snd_a97_*() functions, as they rely on struct
   snd_ac97.
  - don't want the struct snd_ac97_bus_ops, there is a new one

Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
Reviewed-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 include/sound/ac97/regs.h  | 262 +++++++++++++++++++++++++++++++++++++++++++++
 include/sound/ac97_codec.h | 239 +----------------------------------------
 2 files changed, 263 insertions(+), 238 deletions(-)
 create mode 100644 include/sound/ac97/regs.h

diff --git a/include/sound/ac97/regs.h b/include/sound/ac97/regs.h
new file mode 100644
index 000000000000..4bb86d379bd5
--- /dev/null
+++ b/include/sound/ac97/regs.h
@@ -0,0 +1,262 @@
+/*
+ *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>
+ *  Universal interface for Audio Codec '97
+ *
+ *  For more details look to AC '97 component specification revision 2.1
+ *  by Intel Corporation (http://developer.intel.com).
+ *
+ *
+ *   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
+ *
+ */
+
+/*
+ *  AC'97 codec registers
+ */
+
+#define AC97_RESET		0x00	/* Reset */
+#define AC97_MASTER		0x02	/* Master Volume */
+#define AC97_HEADPHONE		0x04	/* Headphone Volume (optional) */
+#define AC97_MASTER_MONO	0x06	/* Master Volume Mono (optional) */
+#define AC97_MASTER_TONE	0x08	/* Master Tone (Bass & Treble) (optional) */
+#define AC97_PC_BEEP		0x0a	/* PC Beep Volume (optinal) */
+#define AC97_PHONE		0x0c	/* Phone Volume (optional) */
+#define AC97_MIC		0x0e	/* MIC Volume */
+#define AC97_LINE		0x10	/* Line In Volume */
+#define AC97_CD			0x12	/* CD Volume */
+#define AC97_VIDEO		0x14	/* Video Volume (optional) */
+#define AC97_AUX		0x16	/* AUX Volume (optional) */
+#define AC97_PCM		0x18	/* PCM Volume */
+#define AC97_REC_SEL		0x1a	/* Record Select */
+#define AC97_REC_GAIN		0x1c	/* Record Gain */
+#define AC97_REC_GAIN_MIC	0x1e	/* Record Gain MIC (optional) */
+#define AC97_GENERAL_PURPOSE	0x20	/* General Purpose (optional) */
+#define AC97_3D_CONTROL		0x22	/* 3D Control (optional) */
+#define AC97_INT_PAGING		0x24	/* Audio Interrupt & Paging (AC'97 2.3) */
+#define AC97_POWERDOWN		0x26	/* Powerdown control / status */
+/* range 0x28-0x3a - AUDIO AC'97 2.0 extensions */
+#define AC97_EXTENDED_ID	0x28	/* Extended Audio ID */
+#define AC97_EXTENDED_STATUS	0x2a	/* Extended Audio Status and Control */
+#define AC97_PCM_FRONT_DAC_RATE 0x2c	/* PCM Front DAC Rate */
+#define AC97_PCM_SURR_DAC_RATE	0x2e	/* PCM Surround DAC Rate */
+#define AC97_PCM_LFE_DAC_RATE	0x30	/* PCM LFE DAC Rate */
+#define AC97_PCM_LR_ADC_RATE	0x32	/* PCM LR ADC Rate */
+#define AC97_PCM_MIC_ADC_RATE	0x34	/* PCM MIC ADC Rate */
+#define AC97_CENTER_LFE_MASTER	0x36	/* Center + LFE Master Volume */
+#define AC97_SURROUND_MASTER	0x38	/* Surround (Rear) Master Volume */
+#define AC97_SPDIF		0x3a	/* S/PDIF control */
+/* range 0x3c-0x58 - MODEM */
+#define AC97_EXTENDED_MID	0x3c	/* Extended Modem ID */
+#define AC97_EXTENDED_MSTATUS	0x3e	/* Extended Modem Status and Control */
+#define AC97_LINE1_RATE		0x40	/* Line1 DAC/ADC Rate */
+#define AC97_LINE2_RATE		0x42	/* Line2 DAC/ADC Rate */
+#define AC97_HANDSET_RATE	0x44	/* Handset DAC/ADC Rate */
+#define AC97_LINE1_LEVEL	0x46	/* Line1 DAC/ADC Level */
+#define AC97_LINE2_LEVEL	0x48	/* Line2 DAC/ADC Level */
+#define AC97_HANDSET_LEVEL	0x4a	/* Handset DAC/ADC Level */
+#define AC97_GPIO_CFG		0x4c	/* GPIO Configuration */
+#define AC97_GPIO_POLARITY	0x4e	/* GPIO Pin Polarity/Type, 0=low, 1=high active */
+#define AC97_GPIO_STICKY	0x50	/* GPIO Pin Sticky, 0=not, 1=sticky */
+#define AC97_GPIO_WAKEUP	0x52	/* GPIO Pin Wakeup, 0=no int, 1=yes int */
+#define AC97_GPIO_STATUS	0x54	/* GPIO Pin Status, slot 12 */
+#define AC97_MISC_AFE		0x56	/* Miscellaneous Modem AFE Status and Control */
+/* range 0x5a-0x7b - Vendor Specific */
+#define AC97_VENDOR_ID1		0x7c	/* Vendor ID1 */
+#define AC97_VENDOR_ID2		0x7e	/* Vendor ID2 / revision */
+/* range 0x60-0x6f (page 1) - extended codec registers */
+#define AC97_CODEC_CLASS_REV	0x60	/* Codec Class/Revision */
+#define AC97_PCI_SVID		0x62	/* PCI Subsystem Vendor ID */
+#define AC97_PCI_SID		0x64	/* PCI Subsystem ID */
+#define AC97_FUNC_SELECT	0x66	/* Function Select */
+#define AC97_FUNC_INFO		0x68	/* Function Information */
+#define AC97_SENSE_INFO		0x6a	/* Sense Details */
+
+/* volume controls */
+#define AC97_MUTE_MASK_MONO	0x8000
+#define AC97_MUTE_MASK_STEREO	0x8080
+
+/* slot allocation */
+#define AC97_SLOT_TAG		0
+#define AC97_SLOT_CMD_ADDR	1
+#define AC97_SLOT_CMD_DATA	2
+#define AC97_SLOT_PCM_LEFT	3
+#define AC97_SLOT_PCM_RIGHT	4
+#define AC97_SLOT_MODEM_LINE1	5
+#define AC97_SLOT_PCM_CENTER	6
+#define AC97_SLOT_MIC		6	/* input */
+#define AC97_SLOT_SPDIF_LEFT1	6
+#define AC97_SLOT_PCM_SLEFT	7	/* surround left */
+#define AC97_SLOT_PCM_LEFT_0	7	/* double rate operation */
+#define AC97_SLOT_SPDIF_LEFT	7
+#define AC97_SLOT_PCM_SRIGHT	8	/* surround right */
+#define AC97_SLOT_PCM_RIGHT_0	8	/* double rate operation */
+#define AC97_SLOT_SPDIF_RIGHT	8
+#define AC97_SLOT_LFE		9
+#define AC97_SLOT_SPDIF_RIGHT1	9
+#define AC97_SLOT_MODEM_LINE2	10
+#define AC97_SLOT_PCM_LEFT_1	10	/* double rate operation */
+#define AC97_SLOT_SPDIF_LEFT2	10
+#define AC97_SLOT_HANDSET	11	/* output */
+#define AC97_SLOT_PCM_RIGHT_1	11	/* double rate operation */
+#define AC97_SLOT_SPDIF_RIGHT2	11
+#define AC97_SLOT_MODEM_GPIO	12	/* modem GPIO */
+#define AC97_SLOT_PCM_CENTER_1	12	/* double rate operation */
+
+/* basic capabilities (reset register) */
+#define AC97_BC_DEDICATED_MIC	0x0001	/* Dedicated Mic PCM In Channel */
+#define AC97_BC_RESERVED1	0x0002	/* Reserved (was Modem Line Codec support) */
+#define AC97_BC_BASS_TREBLE	0x0004	/* Bass & Treble Control */
+#define AC97_BC_SIM_STEREO	0x0008	/* Simulated stereo */
+#define AC97_BC_HEADPHONE	0x0010	/* Headphone Out Support */
+#define AC97_BC_LOUDNESS	0x0020	/* Loudness (bass boost) Support */
+#define AC97_BC_16BIT_DAC	0x0000	/* 16-bit DAC resolution */
+#define AC97_BC_18BIT_DAC	0x0040	/* 18-bit DAC resolution */
+#define AC97_BC_20BIT_DAC	0x0080	/* 20-bit DAC resolution */
+#define AC97_BC_DAC_MASK	0x00c0
+#define AC97_BC_16BIT_ADC	0x0000	/* 16-bit ADC resolution */
+#define AC97_BC_18BIT_ADC	0x0100	/* 18-bit ADC resolution */
+#define AC97_BC_20BIT_ADC	0x0200	/* 20-bit ADC resolution */
+#define AC97_BC_ADC_MASK	0x0300
+#define AC97_BC_3D_TECH_ID_MASK	0x7c00	/* Per-vendor ID of 3D enhancement */
+
+/* general purpose */
+#define AC97_GP_DRSS_MASK	0x0c00	/* double rate slot select */
+#define AC97_GP_DRSS_1011	0x0000	/* LR(C) 10+11(+12) */
+#define AC97_GP_DRSS_78		0x0400	/* LR 7+8 */
+
+/* powerdown bits */
+#define AC97_PD_ADC_STATUS	0x0001	/* ADC status (RO) */
+#define AC97_PD_DAC_STATUS	0x0002	/* DAC status (RO) */
+#define AC97_PD_MIXER_STATUS	0x0004	/* Analog mixer status (RO) */
+#define AC97_PD_VREF_STATUS	0x0008	/* Vref status (RO) */
+#define AC97_PD_PR0		0x0100	/* Power down PCM ADCs and input MUX */
+#define AC97_PD_PR1		0x0200	/* Power down PCM front DAC */
+#define AC97_PD_PR2		0x0400	/* Power down Mixer (Vref still on) */
+#define AC97_PD_PR3		0x0800	/* Power down Mixer (Vref off) */
+#define AC97_PD_PR4		0x1000	/* Power down AC-Link */
+#define AC97_PD_PR5		0x2000	/* Disable internal clock usage */
+#define AC97_PD_PR6		0x4000	/* Headphone amplifier */
+#define AC97_PD_EAPD		0x8000	/* External Amplifer Power Down (EAPD) */
+
+/* extended audio ID bit defines */
+#define AC97_EI_VRA		0x0001	/* Variable bit rate supported */
+#define AC97_EI_DRA		0x0002	/* Double rate supported */
+#define AC97_EI_SPDIF		0x0004	/* S/PDIF out supported */
+#define AC97_EI_VRM		0x0008	/* Variable bit rate supported for MIC */
+#define AC97_EI_DACS_SLOT_MASK	0x0030	/* DACs slot assignment */
+#define AC97_EI_DACS_SLOT_SHIFT	4
+#define AC97_EI_CDAC		0x0040	/* PCM Center DAC available */
+#define AC97_EI_SDAC		0x0080	/* PCM Surround DACs available */
+#define AC97_EI_LDAC		0x0100	/* PCM LFE DAC available */
+#define AC97_EI_AMAP		0x0200	/* indicates optional slot/DAC mapping based on codec ID */
+#define AC97_EI_REV_MASK	0x0c00	/* AC'97 revision mask */
+#define AC97_EI_REV_22		0x0400	/* AC'97 revision 2.2 */
+#define AC97_EI_REV_23		0x0800	/* AC'97 revision 2.3 */
+#define AC97_EI_REV_SHIFT	10
+#define AC97_EI_ADDR_MASK	0xc000	/* physical codec ID (address) */
+#define AC97_EI_ADDR_SHIFT	14
+
+/* extended audio status and control bit defines */
+#define AC97_EA_VRA		0x0001	/* Variable bit rate enable bit */
+#define AC97_EA_DRA		0x0002	/* Double-rate audio enable bit */
+#define AC97_EA_SPDIF		0x0004	/* S/PDIF out enable bit */
+#define AC97_EA_VRM		0x0008	/* Variable bit rate for MIC enable bit */
+#define AC97_EA_SPSA_SLOT_MASK	0x0030	/* Mask for slot assignment bits */
+#define AC97_EA_SPSA_SLOT_SHIFT 4
+#define AC97_EA_SPSA_3_4	0x0000	/* Slot assigned to 3 & 4 */
+#define AC97_EA_SPSA_7_8	0x0010	/* Slot assigned to 7 & 8 */
+#define AC97_EA_SPSA_6_9	0x0020	/* Slot assigned to 6 & 9 */
+#define AC97_EA_SPSA_10_11	0x0030	/* Slot assigned to 10 & 11 */
+#define AC97_EA_CDAC		0x0040	/* PCM Center DAC is ready (Read only) */
+#define AC97_EA_SDAC		0x0080	/* PCM Surround DACs are ready (Read only) */
+#define AC97_EA_LDAC		0x0100	/* PCM LFE DAC is ready (Read only) */
+#define AC97_EA_MDAC		0x0200	/* MIC ADC is ready (Read only) */
+#define AC97_EA_SPCV		0x0400	/* S/PDIF configuration valid (Read only) */
+#define AC97_EA_PRI		0x0800	/* Turns the PCM Center DAC off */
+#define AC97_EA_PRJ		0x1000	/* Turns the PCM Surround DACs off */
+#define AC97_EA_PRK		0x2000	/* Turns the PCM LFE DAC off */
+#define AC97_EA_PRL		0x4000	/* Turns the MIC ADC off */
+
+/* S/PDIF control bit defines */
+#define AC97_SC_PRO		0x0001	/* Professional status */
+#define AC97_SC_NAUDIO		0x0002	/* Non audio stream */
+#define AC97_SC_COPY		0x0004	/* Copyright status */
+#define AC97_SC_PRE		0x0008	/* Preemphasis status */
+#define AC97_SC_CC_MASK		0x07f0	/* Category Code mask */
+#define AC97_SC_CC_SHIFT	4
+#define AC97_SC_L		0x0800	/* Generation Level status */
+#define AC97_SC_SPSR_MASK	0x3000	/* S/PDIF Sample Rate bits */
+#define AC97_SC_SPSR_SHIFT	12
+#define AC97_SC_SPSR_44K	0x0000	/* Use 44.1kHz Sample rate */
+#define AC97_SC_SPSR_48K	0x2000	/* Use 48kHz Sample rate */
+#define AC97_SC_SPSR_32K	0x3000	/* Use 32kHz Sample rate */
+#define AC97_SC_DRS		0x4000	/* Double Rate S/PDIF */
+#define AC97_SC_V		0x8000	/* Validity status */
+
+/* Interrupt and Paging bit defines (AC'97 2.3) */
+#define AC97_PAGE_MASK		0x000f	/* Page Selector */
+#define AC97_PAGE_VENDOR	0	/* Vendor-specific registers */
+#define AC97_PAGE_1		1	/* Extended Codec Registers page 1 */
+#define AC97_INT_ENABLE		0x0800	/* Interrupt Enable */
+#define AC97_INT_SENSE		0x1000	/* Sense Cycle */
+#define AC97_INT_CAUSE_SENSE	0x2000	/* Sense Cycle Completed (RO) */
+#define AC97_INT_CAUSE_GPIO	0x4000	/* GPIO bits changed (RO) */
+#define AC97_INT_STATUS		0x8000	/* Interrupt Status */
+
+/* extended modem ID bit defines */
+#define AC97_MEI_LINE1		0x0001	/* Line1 present */
+#define AC97_MEI_LINE2		0x0002	/* Line2 present */
+#define AC97_MEI_HANDSET	0x0004	/* Handset present */
+#define AC97_MEI_CID1		0x0008	/* caller ID decode for Line1 is supported */
+#define AC97_MEI_CID2		0x0010	/* caller ID decode for Line2 is supported */
+#define AC97_MEI_ADDR_MASK	0xc000	/* physical codec ID (address) */
+#define AC97_MEI_ADDR_SHIFT	14
+
+/* extended modem status and control bit defines */
+#define AC97_MEA_GPIO		0x0001	/* GPIO is ready (ro) */
+#define AC97_MEA_MREF		0x0002	/* Vref is up to nominal level (ro) */
+#define AC97_MEA_ADC1		0x0004	/* ADC1 operational (ro) */
+#define AC97_MEA_DAC1		0x0008	/* DAC1 operational (ro) */
+#define AC97_MEA_ADC2		0x0010	/* ADC2 operational (ro) */
+#define AC97_MEA_DAC2		0x0020	/* DAC2 operational (ro) */
+#define AC97_MEA_HADC		0x0040	/* HADC operational (ro) */
+#define AC97_MEA_HDAC		0x0080	/* HDAC operational (ro) */
+#define AC97_MEA_PRA		0x0100	/* GPIO power down (high) */
+#define AC97_MEA_PRB		0x0200	/* reserved */
+#define AC97_MEA_PRC		0x0400	/* ADC1 power down (high) */
+#define AC97_MEA_PRD		0x0800	/* DAC1 power down (high) */
+#define AC97_MEA_PRE		0x1000	/* ADC2 power down (high) */
+#define AC97_MEA_PRF		0x2000	/* DAC2 power down (high) */
+#define AC97_MEA_PRG		0x4000	/* HADC power down (high) */
+#define AC97_MEA_PRH		0x8000	/* HDAC power down (high) */
+
+/* modem gpio status defines */
+#define AC97_GPIO_LINE1_OH      0x0001  /* Off Hook Line1 */
+#define AC97_GPIO_LINE1_RI      0x0002  /* Ring Detect Line1 */
+#define AC97_GPIO_LINE1_CID     0x0004  /* Caller ID path enable Line1 */
+#define AC97_GPIO_LINE1_LCS     0x0008  /* Loop Current Sense Line1 */
+#define AC97_GPIO_LINE1_PULSE   0x0010  /* Opt./ Pulse Dial Line1 (out) */
+#define AC97_GPIO_LINE1_HL1R    0x0020  /* Opt./ Handset to Line1 relay control (out) */
+#define AC97_GPIO_LINE1_HOHD    0x0040  /* Opt./ Handset off hook detect Line1 (in) */
+#define AC97_GPIO_LINE12_AC     0x0080  /* Opt./ Int.bit 1 / Line1/2 AC (out) */
+#define AC97_GPIO_LINE12_DC     0x0100  /* Opt./ Int.bit 2 / Line1/2 DC (out) */
+#define AC97_GPIO_LINE12_RS     0x0200  /* Opt./ Int.bit 3 / Line1/2 RS (out) */
+#define AC97_GPIO_LINE2_OH      0x0400  /* Off Hook Line2 */
+#define AC97_GPIO_LINE2_RI      0x0800  /* Ring Detect Line2 */
+#define AC97_GPIO_LINE2_CID     0x1000  /* Caller ID path enable Line2 */
+#define AC97_GPIO_LINE2_LCS     0x2000  /* Loop Current Sense Line2 */
+#define AC97_GPIO_LINE2_PULSE   0x4000  /* Opt./ Pulse Dial Line2 (out) */
+#define AC97_GPIO_LINE2_HL1R    0x8000  /* Opt./ Handset to Line2 relay control (out) */
+
diff --git a/include/sound/ac97_codec.h b/include/sound/ac97_codec.h
index 15aa5f07c955..89d311a503d3 100644
--- a/include/sound/ac97_codec.h
+++ b/include/sound/ac97_codec.h
@@ -28,6 +28,7 @@
 #include <linux/bitops.h>
 #include <linux/device.h>
 #include <linux/workqueue.h>
+#include <sound/ac97/regs.h>
 #include <sound/pcm.h>
 #include <sound/control.h>
 #include <sound/info.h>
@@ -35,244 +36,6 @@
 /* maximum number of devices on the AC97 bus */
 #define	AC97_BUS_MAX_DEVICES	4
 
-/*
- *  AC'97 codec registers
- */
-
-#define AC97_RESET		0x00	/* Reset */
-#define AC97_MASTER		0x02	/* Master Volume */
-#define AC97_HEADPHONE		0x04	/* Headphone Volume (optional) */
-#define AC97_MASTER_MONO	0x06	/* Master Volume Mono (optional) */
-#define AC97_MASTER_TONE	0x08	/* Master Tone (Bass & Treble) (optional) */
-#define AC97_PC_BEEP		0x0a	/* PC Beep Volume (optinal) */
-#define AC97_PHONE		0x0c	/* Phone Volume (optional) */
-#define AC97_MIC		0x0e	/* MIC Volume */
-#define AC97_LINE		0x10	/* Line In Volume */
-#define AC97_CD			0x12	/* CD Volume */
-#define AC97_VIDEO		0x14	/* Video Volume (optional) */
-#define AC97_AUX		0x16	/* AUX Volume (optional) */
-#define AC97_PCM		0x18	/* PCM Volume */
-#define AC97_REC_SEL		0x1a	/* Record Select */
-#define AC97_REC_GAIN		0x1c	/* Record Gain */
-#define AC97_REC_GAIN_MIC	0x1e	/* Record Gain MIC (optional) */
-#define AC97_GENERAL_PURPOSE	0x20	/* General Purpose (optional) */
-#define AC97_3D_CONTROL		0x22	/* 3D Control (optional) */
-#define AC97_INT_PAGING		0x24	/* Audio Interrupt & Paging (AC'97 2.3) */
-#define AC97_POWERDOWN		0x26	/* Powerdown control / status */
-/* range 0x28-0x3a - AUDIO AC'97 2.0 extensions */
-#define AC97_EXTENDED_ID	0x28	/* Extended Audio ID */
-#define AC97_EXTENDED_STATUS	0x2a	/* Extended Audio Status and Control */
-#define AC97_PCM_FRONT_DAC_RATE 0x2c	/* PCM Front DAC Rate */
-#define AC97_PCM_SURR_DAC_RATE	0x2e	/* PCM Surround DAC Rate */
-#define AC97_PCM_LFE_DAC_RATE	0x30	/* PCM LFE DAC Rate */
-#define AC97_PCM_LR_ADC_RATE	0x32	/* PCM LR ADC Rate */
-#define AC97_PCM_MIC_ADC_RATE	0x34	/* PCM MIC ADC Rate */
-#define AC97_CENTER_LFE_MASTER	0x36	/* Center + LFE Master Volume */
-#define AC97_SURROUND_MASTER	0x38	/* Surround (Rear) Master Volume */
-#define AC97_SPDIF		0x3a	/* S/PDIF control */
-/* range 0x3c-0x58 - MODEM */
-#define AC97_EXTENDED_MID	0x3c	/* Extended Modem ID */
-#define AC97_EXTENDED_MSTATUS	0x3e	/* Extended Modem Status and Control */
-#define AC97_LINE1_RATE		0x40	/* Line1 DAC/ADC Rate */
-#define AC97_LINE2_RATE		0x42	/* Line2 DAC/ADC Rate */
-#define AC97_HANDSET_RATE	0x44	/* Handset DAC/ADC Rate */
-#define AC97_LINE1_LEVEL	0x46	/* Line1 DAC/ADC Level */
-#define AC97_LINE2_LEVEL	0x48	/* Line2 DAC/ADC Level */
-#define AC97_HANDSET_LEVEL	0x4a	/* Handset DAC/ADC Level */
-#define AC97_GPIO_CFG		0x4c	/* GPIO Configuration */
-#define AC97_GPIO_POLARITY	0x4e	/* GPIO Pin Polarity/Type, 0=low, 1=high active */
-#define AC97_GPIO_STICKY	0x50	/* GPIO Pin Sticky, 0=not, 1=sticky */
-#define AC97_GPIO_WAKEUP	0x52	/* GPIO Pin Wakeup, 0=no int, 1=yes int */
-#define AC97_GPIO_STATUS	0x54	/* GPIO Pin Status, slot 12 */
-#define AC97_MISC_AFE		0x56	/* Miscellaneous Modem AFE Status and Control */
-/* range 0x5a-0x7b - Vendor Specific */
-#define AC97_VENDOR_ID1		0x7c	/* Vendor ID1 */
-#define AC97_VENDOR_ID2		0x7e	/* Vendor ID2 / revision */
-/* range 0x60-0x6f (page 1) - extended codec registers */
-#define AC97_CODEC_CLASS_REV	0x60	/* Codec Class/Revision */
-#define AC97_PCI_SVID		0x62	/* PCI Subsystem Vendor ID */
-#define AC97_PCI_SID		0x64	/* PCI Subsystem ID */
-#define AC97_FUNC_SELECT	0x66	/* Function Select */
-#define AC97_FUNC_INFO		0x68	/* Function Information */
-#define AC97_SENSE_INFO		0x6a	/* Sense Details */
-
-/* volume controls */
-#define AC97_MUTE_MASK_MONO	0x8000
-#define AC97_MUTE_MASK_STEREO	0x8080
-
-/* slot allocation */
-#define AC97_SLOT_TAG		0
-#define AC97_SLOT_CMD_ADDR	1
-#define AC97_SLOT_CMD_DATA	2
-#define AC97_SLOT_PCM_LEFT	3
-#define AC97_SLOT_PCM_RIGHT	4
-#define AC97_SLOT_MODEM_LINE1	5
-#define AC97_SLOT_PCM_CENTER	6
-#define AC97_SLOT_MIC		6	/* input */
-#define AC97_SLOT_SPDIF_LEFT1	6
-#define AC97_SLOT_PCM_SLEFT	7	/* surround left */
-#define AC97_SLOT_PCM_LEFT_0	7	/* double rate operation */
-#define AC97_SLOT_SPDIF_LEFT	7
-#define AC97_SLOT_PCM_SRIGHT	8	/* surround right */
-#define AC97_SLOT_PCM_RIGHT_0	8	/* double rate operation */
-#define AC97_SLOT_SPDIF_RIGHT	8
-#define AC97_SLOT_LFE		9
-#define AC97_SLOT_SPDIF_RIGHT1	9
-#define AC97_SLOT_MODEM_LINE2	10
-#define AC97_SLOT_PCM_LEFT_1	10	/* double rate operation */
-#define AC97_SLOT_SPDIF_LEFT2	10
-#define AC97_SLOT_HANDSET	11	/* output */
-#define AC97_SLOT_PCM_RIGHT_1	11	/* double rate operation */
-#define AC97_SLOT_SPDIF_RIGHT2	11
-#define AC97_SLOT_MODEM_GPIO	12	/* modem GPIO */
-#define AC97_SLOT_PCM_CENTER_1	12	/* double rate operation */
-
-/* basic capabilities (reset register) */
-#define AC97_BC_DEDICATED_MIC	0x0001	/* Dedicated Mic PCM In Channel */
-#define AC97_BC_RESERVED1	0x0002	/* Reserved (was Modem Line Codec support) */
-#define AC97_BC_BASS_TREBLE	0x0004	/* Bass & Treble Control */
-#define AC97_BC_SIM_STEREO	0x0008	/* Simulated stereo */
-#define AC97_BC_HEADPHONE	0x0010	/* Headphone Out Support */
-#define AC97_BC_LOUDNESS	0x0020	/* Loudness (bass boost) Support */
-#define AC97_BC_16BIT_DAC	0x0000	/* 16-bit DAC resolution */
-#define AC97_BC_18BIT_DAC	0x0040	/* 18-bit DAC resolution */
-#define AC97_BC_20BIT_DAC	0x0080	/* 20-bit DAC resolution */
-#define AC97_BC_DAC_MASK	0x00c0
-#define AC97_BC_16BIT_ADC	0x0000	/* 16-bit ADC resolution */
-#define AC97_BC_18BIT_ADC	0x0100	/* 18-bit ADC resolution */
-#define AC97_BC_20BIT_ADC	0x0200	/* 20-bit ADC resolution */
-#define AC97_BC_ADC_MASK	0x0300
-#define AC97_BC_3D_TECH_ID_MASK	0x7c00	/* Per-vendor ID of 3D enhancement */
-
-/* general purpose */
-#define AC97_GP_DRSS_MASK	0x0c00	/* double rate slot select */
-#define AC97_GP_DRSS_1011	0x0000	/* LR(C) 10+11(+12) */
-#define AC97_GP_DRSS_78		0x0400	/* LR 7+8 */
-
-/* powerdown bits */
-#define AC97_PD_ADC_STATUS	0x0001	/* ADC status (RO) */
-#define AC97_PD_DAC_STATUS	0x0002	/* DAC status (RO) */
-#define AC97_PD_MIXER_STATUS	0x0004	/* Analog mixer status (RO) */
-#define AC97_PD_VREF_STATUS	0x0008	/* Vref status (RO) */
-#define AC97_PD_PR0		0x0100	/* Power down PCM ADCs and input MUX */
-#define AC97_PD_PR1		0x0200	/* Power down PCM front DAC */
-#define AC97_PD_PR2		0x0400	/* Power down Mixer (Vref still on) */
-#define AC97_PD_PR3		0x0800	/* Power down Mixer (Vref off) */
-#define AC97_PD_PR4		0x1000	/* Power down AC-Link */
-#define AC97_PD_PR5		0x2000	/* Disable internal clock usage */
-#define AC97_PD_PR6		0x4000	/* Headphone amplifier */
-#define AC97_PD_EAPD		0x8000	/* External Amplifer Power Down (EAPD) */
-
-/* extended audio ID bit defines */
-#define AC97_EI_VRA		0x0001	/* Variable bit rate supported */
-#define AC97_EI_DRA		0x0002	/* Double rate supported */
-#define AC97_EI_SPDIF		0x0004	/* S/PDIF out supported */
-#define AC97_EI_VRM		0x0008	/* Variable bit rate supported for MIC */
-#define AC97_EI_DACS_SLOT_MASK	0x0030	/* DACs slot assignment */
-#define AC97_EI_DACS_SLOT_SHIFT	4
-#define AC97_EI_CDAC		0x0040	/* PCM Center DAC available */
-#define AC97_EI_SDAC		0x0080	/* PCM Surround DACs available */
-#define AC97_EI_LDAC		0x0100	/* PCM LFE DAC available */
-#define AC97_EI_AMAP		0x0200	/* indicates optional slot/DAC mapping based on codec ID */
-#define AC97_EI_REV_MASK	0x0c00	/* AC'97 revision mask */
-#define AC97_EI_REV_22		0x0400	/* AC'97 revision 2.2 */
-#define AC97_EI_REV_23		0x0800	/* AC'97 revision 2.3 */
-#define AC97_EI_REV_SHIFT	10
-#define AC97_EI_ADDR_MASK	0xc000	/* physical codec ID (address) */
-#define AC97_EI_ADDR_SHIFT	14
-
-/* extended audio status and control bit defines */
-#define AC97_EA_VRA		0x0001	/* Variable bit rate enable bit */
-#define AC97_EA_DRA		0x0002	/* Double-rate audio enable bit */
-#define AC97_EA_SPDIF		0x0004	/* S/PDIF out enable bit */
-#define AC97_EA_VRM		0x0008	/* Variable bit rate for MIC enable bit */
-#define AC97_EA_SPSA_SLOT_MASK	0x0030	/* Mask for slot assignment bits */
-#define AC97_EA_SPSA_SLOT_SHIFT 4
-#define AC97_EA_SPSA_3_4	0x0000	/* Slot assigned to 3 & 4 */
-#define AC97_EA_SPSA_7_8	0x0010	/* Slot assigned to 7 & 8 */
-#define AC97_EA_SPSA_6_9	0x0020	/* Slot assigned to 6 & 9 */
-#define AC97_EA_SPSA_10_11	0x0030	/* Slot assigned to 10 & 11 */
-#define AC97_EA_CDAC		0x0040	/* PCM Center DAC is ready (Read only) */
-#define AC97_EA_SDAC		0x0080	/* PCM Surround DACs are ready (Read only) */
-#define AC97_EA_LDAC		0x0100	/* PCM LFE DAC is ready (Read only) */
-#define AC97_EA_MDAC		0x0200	/* MIC ADC is ready (Read only) */
-#define AC97_EA_SPCV		0x0400	/* S/PDIF configuration valid (Read only) */
-#define AC97_EA_PRI		0x0800	/* Turns the PCM Center DAC off */
-#define AC97_EA_PRJ		0x1000	/* Turns the PCM Surround DACs off */
-#define AC97_EA_PRK		0x2000	/* Turns the PCM LFE DAC off */
-#define AC97_EA_PRL		0x4000	/* Turns the MIC ADC off */
-
-/* S/PDIF control bit defines */
-#define AC97_SC_PRO		0x0001	/* Professional status */
-#define AC97_SC_NAUDIO		0x0002	/* Non audio stream */
-#define AC97_SC_COPY		0x0004	/* Copyright status */
-#define AC97_SC_PRE		0x0008	/* Preemphasis status */
-#define AC97_SC_CC_MASK		0x07f0	/* Category Code mask */
-#define AC97_SC_CC_SHIFT	4
-#define AC97_SC_L		0x0800	/* Generation Level status */
-#define AC97_SC_SPSR_MASK	0x3000	/* S/PDIF Sample Rate bits */
-#define AC97_SC_SPSR_SHIFT	12
-#define AC97_SC_SPSR_44K	0x0000	/* Use 44.1kHz Sample rate */
-#define AC97_SC_SPSR_48K	0x2000	/* Use 48kHz Sample rate */
-#define AC97_SC_SPSR_32K	0x3000	/* Use 32kHz Sample rate */
-#define AC97_SC_DRS		0x4000	/* Double Rate S/PDIF */
-#define AC97_SC_V		0x8000	/* Validity status */
-
-/* Interrupt and Paging bit defines (AC'97 2.3) */
-#define AC97_PAGE_MASK		0x000f	/* Page Selector */
-#define AC97_PAGE_VENDOR	0	/* Vendor-specific registers */
-#define AC97_PAGE_1		1	/* Extended Codec Registers page 1 */
-#define AC97_INT_ENABLE		0x0800	/* Interrupt Enable */
-#define AC97_INT_SENSE		0x1000	/* Sense Cycle */
-#define AC97_INT_CAUSE_SENSE	0x2000	/* Sense Cycle Completed (RO) */
-#define AC97_INT_CAUSE_GPIO	0x4000	/* GPIO bits changed (RO) */
-#define AC97_INT_STATUS		0x8000	/* Interrupt Status */
-
-/* extended modem ID bit defines */
-#define AC97_MEI_LINE1		0x0001	/* Line1 present */
-#define AC97_MEI_LINE2		0x0002	/* Line2 present */
-#define AC97_MEI_HANDSET	0x0004	/* Handset present */
-#define AC97_MEI_CID1		0x0008	/* caller ID decode for Line1 is supported */
-#define AC97_MEI_CID2		0x0010	/* caller ID decode for Line2 is supported */
-#define AC97_MEI_ADDR_MASK	0xc000	/* physical codec ID (address) */
-#define AC97_MEI_ADDR_SHIFT	14
-
-/* extended modem status and control bit defines */
-#define AC97_MEA_GPIO		0x0001	/* GPIO is ready (ro) */
-#define AC97_MEA_MREF		0x0002	/* Vref is up to nominal level (ro) */
-#define AC97_MEA_ADC1		0x0004	/* ADC1 operational (ro) */
-#define AC97_MEA_DAC1		0x0008	/* DAC1 operational (ro) */
-#define AC97_MEA_ADC2		0x0010	/* ADC2 operational (ro) */
-#define AC97_MEA_DAC2		0x0020	/* DAC2 operational (ro) */
-#define AC97_MEA_HADC		0x0040	/* HADC operational (ro) */
-#define AC97_MEA_HDAC		0x0080	/* HDAC operational (ro) */
-#define AC97_MEA_PRA		0x0100	/* GPIO power down (high) */
-#define AC97_MEA_PRB		0x0200	/* reserved */
-#define AC97_MEA_PRC		0x0400	/* ADC1 power down (high) */
-#define AC97_MEA_PRD		0x0800	/* DAC1 power down (high) */
-#define AC97_MEA_PRE		0x1000	/* ADC2 power down (high) */
-#define AC97_MEA_PRF		0x2000	/* DAC2 power down (high) */
-#define AC97_MEA_PRG		0x4000	/* HADC power down (high) */
-#define AC97_MEA_PRH		0x8000	/* HDAC power down (high) */
-
-/* modem gpio status defines */
-#define AC97_GPIO_LINE1_OH      0x0001  /* Off Hook Line1 */
-#define AC97_GPIO_LINE1_RI      0x0002  /* Ring Detect Line1 */
-#define AC97_GPIO_LINE1_CID     0x0004  /* Caller ID path enable Line1 */
-#define AC97_GPIO_LINE1_LCS     0x0008  /* Loop Current Sense Line1 */
-#define AC97_GPIO_LINE1_PULSE   0x0010  /* Opt./ Pulse Dial Line1 (out) */
-#define AC97_GPIO_LINE1_HL1R    0x0020  /* Opt./ Handset to Line1 relay control (out) */
-#define AC97_GPIO_LINE1_HOHD    0x0040  /* Opt./ Handset off hook detect Line1 (in) */
-#define AC97_GPIO_LINE12_AC     0x0080  /* Opt./ Int.bit 1 / Line1/2 AC (out) */
-#define AC97_GPIO_LINE12_DC     0x0100  /* Opt./ Int.bit 2 / Line1/2 DC (out) */
-#define AC97_GPIO_LINE12_RS     0x0200  /* Opt./ Int.bit 3 / Line1/2 RS (out) */
-#define AC97_GPIO_LINE2_OH      0x0400  /* Off Hook Line2 */
-#define AC97_GPIO_LINE2_RI      0x0800  /* Ring Detect Line2 */
-#define AC97_GPIO_LINE2_CID     0x1000  /* Caller ID path enable Line2 */
-#define AC97_GPIO_LINE2_LCS     0x2000  /* Loop Current Sense Line2 */
-#define AC97_GPIO_LINE2_PULSE   0x4000  /* Opt./ Pulse Dial Line2 (out) */
-#define AC97_GPIO_LINE2_HL1R    0x8000  /* Opt./ Handset to Line2 relay control (out) */
-
 /* specific - SigmaTel */
 #define AC97_SIGMATEL_OUTSEL	0x64	/* Output Select, STAC9758 */
 #define AC97_SIGMATEL_INSEL	0x66	/* Input Select, STAC9758 */
-- 
2.14.1

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

end of thread, other threads:[~2017-09-04 17:26 UTC | newest]

Thread overview: 74+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-04-30 21:15 [RFC PATCH 0/7] AC97 device/driver model revamp Robert Jarzmik
2016-04-30 21:15 ` Robert Jarzmik
2016-04-30 21:15 ` [RFC PATCH 1/7] ALSA: ac97: split out the generic ac97 registers Robert Jarzmik
2016-04-30 21:15   ` Robert Jarzmik
2016-05-03 11:51   ` Mark Brown
2016-05-03 11:51     ` Mark Brown
2016-05-03 19:22     ` Robert Jarzmik
2016-05-03 19:22       ` Robert Jarzmik
2016-05-03 19:22       ` Robert Jarzmik
2016-05-04  9:07       ` Mark Brown
2016-05-04  9:07         ` Mark Brown
2016-05-05 19:06         ` Robert Jarzmik
2016-05-05 19:06           ` Robert Jarzmik
2016-05-05 19:06           ` Robert Jarzmik
2016-05-05 19:17           ` Mark Brown
2016-05-05 19:17             ` Mark Brown
2016-05-05 19:46             ` Robert Jarzmik
2016-05-05 19:46               ` Robert Jarzmik
2016-05-06 17:17               ` Mark Brown
2016-05-06 17:17                 ` Mark Brown
2017-09-04 17:25   ` Applied "ALSA: ac97: split out the generic ac97 registers" to the asoc tree Mark Brown
2017-09-04 17:25     ` Mark Brown
2017-09-04 17:25     ` Mark Brown
2016-04-30 21:15 ` [RFC PATCH 2/7] ALSA: ac97: add an ac97 bus Robert Jarzmik
2016-04-30 21:15   ` Robert Jarzmik
2016-05-03 16:29   ` Mark Brown
2016-05-03 16:29     ` Mark Brown
2016-05-03 19:43     ` Robert Jarzmik
2016-05-03 19:43       ` Robert Jarzmik
2016-05-04 16:22       ` Mark Brown
2016-05-04 16:22         ` Mark Brown
2016-05-05 19:14         ` Robert Jarzmik
2016-05-05 19:14           ` Robert Jarzmik
2016-05-09  9:31   ` Takashi Iwai
2016-05-09  9:31     ` Takashi Iwai
2016-05-09  9:31     ` Takashi Iwai
2016-05-14  9:50     ` Robert Jarzmik
2016-05-14  9:50       ` Robert Jarzmik
2016-05-14  9:50       ` Robert Jarzmik
2016-05-14 15:13       ` Takashi Iwai
2016-05-14 15:13         ` Takashi Iwai
2016-05-14 15:13         ` Takashi Iwai
2016-05-15 21:29         ` Robert Jarzmik
2016-05-15 21:29           ` Robert Jarzmik
2016-05-15 21:29           ` Robert Jarzmik
2016-05-16  5:40           ` Takashi Iwai
2016-05-16  5:40             ` Takashi Iwai
2016-05-16  5:40             ` Takashi Iwai
2016-05-16  8:53             ` Robert Jarzmik
2016-05-16  8:53               ` Robert Jarzmik
2016-05-16  8:53               ` Robert Jarzmik
2016-05-16 12:58               ` Takashi Iwai
2016-05-16 12:58                 ` Takashi Iwai
2016-05-16 12:58                 ` Takashi Iwai
2016-05-16 13:12                 ` Mark Brown
2016-05-16 13:12                   ` Mark Brown
2016-04-30 21:15 ` [RFC PATCH 3/7] ASoC: wm9713: add ac97 new bus support Robert Jarzmik
2016-04-30 21:15   ` Robert Jarzmik
2016-04-30 21:15 ` [RFC PATCH 4/7] ASoC: pxa: switch to new ac97 " Robert Jarzmik
2016-04-30 21:15   ` Robert Jarzmik
2016-04-30 21:15 ` [RFC PATCH 5/7] ARM: pxa: mioa701 remove wm9713 from platform devices Robert Jarzmik
2016-04-30 21:15   ` Robert Jarzmik
2016-04-30 21:15   ` Robert Jarzmik
2016-04-30 21:15 ` [RFC PATCH 6/7] ASoC: mioa701_wm9713: convert to new ac97 bus Robert Jarzmik
2016-04-30 21:15   ` Robert Jarzmik
2016-04-30 21:15   ` Robert Jarzmik
2016-04-30 21:15 ` [RFC PATCH 7/7] ASoC: add new ac97 bus support Robert Jarzmik
2016-04-30 21:15   ` Robert Jarzmik
2016-05-09  9:04 ` [RFC PATCH 0/7] AC97 device/driver model revamp Takashi Iwai
2016-05-09  9:04   ` Takashi Iwai
2016-05-09  9:04   ` Takashi Iwai
2016-05-14  8:13   ` Robert Jarzmik
2016-05-14  8:13     ` Robert Jarzmik
2016-05-14  8:13     ` Robert Jarzmik

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.