[01/12] ALSA: hdac: Add codec helper library
diff mbox

Message ID 1472451806-10605-2-git-send-email-subhransu.s.prusty@intel.com
State New
Headers show

Commit Message

Subhransu S. Prusty Aug. 29, 2016, 6:23 a.m. UTC
Add hdac helpers to enumerate the HDA widgets and fill connection
lists for each.

Signed-off-by: Subhransu S. Prusty <subhransu.s.prusty@intel.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
---
 include/sound/hdaudio.h    |   1 +
 sound/hda/ext/Makefile     |   3 +-
 sound/hda/ext/hdac_codec.c | 182 +++++++++++++++++++++++++++++++++++++++++++++
 sound/hda/ext/hdac_codec.h |  53 +++++++++++++
 4 files changed, 238 insertions(+), 1 deletion(-)
 create mode 100644 sound/hda/ext/hdac_codec.c
 create mode 100644 sound/hda/ext/hdac_codec.h

Comments

Takashi Iwai Aug. 29, 2016, 8:41 a.m. UTC | #1
On Mon, 29 Aug 2016 08:23:15 +0200,
Subhransu S. Prusty wrote:
> 
> Add hdac helpers to enumerate the HDA widgets and fill connection
> lists for each.
> 
> Signed-off-by: Subhransu S. Prusty <subhransu.s.prusty@intel.com>
> Signed-off-by: Vinod Koul <vinod.koul@intel.com>
> ---
>  include/sound/hdaudio.h    |   1 +
>  sound/hda/ext/Makefile     |   3 +-
>  sound/hda/ext/hdac_codec.c | 182 +++++++++++++++++++++++++++++++++++++++++++++
>  sound/hda/ext/hdac_codec.h |  53 +++++++++++++
>  4 files changed, 238 insertions(+), 1 deletion(-)
>  create mode 100644 sound/hda/ext/hdac_codec.c
>  create mode 100644 sound/hda/ext/hdac_codec.h
> 
> diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h
> index 93e63c5..79502dc 100644
> --- a/include/sound/hdaudio.h
> +++ b/include/sound/hdaudio.h
> @@ -71,6 +71,7 @@ struct hdac_device {
>  			 unsigned int flags, unsigned int *res);
>  
>  	/* widgets */
> +	struct list_head widget_list;
>  	unsigned int num_nodes;
>  	hda_nid_t start_nid, end_nid;

Any reason to add this to hdac_device although it's used only by
hda/ext?


thanks,

Takashi
Subhransu S. Prusty Aug. 29, 2016, 12:47 p.m. UTC | #2
On Mon, Aug 29, 2016 at 10:41:22AM +0200, Takashi Iwai wrote:
> On Mon, 29 Aug 2016 08:23:15 +0200,
> Subhransu S. Prusty wrote:
> > 
> > Add hdac helpers to enumerate the HDA widgets and fill connection
> > lists for each.
> > 
> > Signed-off-by: Subhransu S. Prusty <subhransu.s.prusty@intel.com>
> > Signed-off-by: Vinod Koul <vinod.koul@intel.com>
> > ---
> >  include/sound/hdaudio.h    |   1 +
> >  sound/hda/ext/Makefile     |   3 +-
> >  sound/hda/ext/hdac_codec.c | 182 +++++++++++++++++++++++++++++++++++++++++++++
> >  sound/hda/ext/hdac_codec.h |  53 +++++++++++++
> >  4 files changed, 238 insertions(+), 1 deletion(-)
> >  create mode 100644 sound/hda/ext/hdac_codec.c
> >  create mode 100644 sound/hda/ext/hdac_codec.h
> > 
> > diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h
> > index 93e63c5..79502dc 100644
> > --- a/include/sound/hdaudio.h
> > +++ b/include/sound/hdaudio.h
> > @@ -71,6 +71,7 @@ struct hdac_device {
> >  			 unsigned int flags, unsigned int *res);
> >  
> >  	/* widgets */
> > +	struct list_head widget_list;
> >  	unsigned int num_nodes;
> >  	hda_nid_t start_nid, end_nid;
> 
> Any reason to add this to hdac_device although it's used only by
> hda/ext?

Hi Takashi,

Added this in the hdac_device, as this looked to be the more suitable data
structure for the widget_list and is more specific to the hdac device. 

Regards,
Subhransu
> 
> 
> thanks,
> 
> Takashi
Takashi Iwai Aug. 29, 2016, 12:55 p.m. UTC | #3
On Mon, 29 Aug 2016 14:47:33 +0200,
Subhransu S. Prusty wrote:
> 
> On Mon, Aug 29, 2016 at 10:41:22AM +0200, Takashi Iwai wrote:
> > On Mon, 29 Aug 2016 08:23:15 +0200,
> > Subhransu S. Prusty wrote:
> > > 
> > > Add hdac helpers to enumerate the HDA widgets and fill connection
> > > lists for each.
> > > 
> > > Signed-off-by: Subhransu S. Prusty <subhransu.s.prusty@intel.com>
> > > Signed-off-by: Vinod Koul <vinod.koul@intel.com>
> > > ---
> > >  include/sound/hdaudio.h    |   1 +
> > >  sound/hda/ext/Makefile     |   3 +-
> > >  sound/hda/ext/hdac_codec.c | 182 +++++++++++++++++++++++++++++++++++++++++++++
> > >  sound/hda/ext/hdac_codec.h |  53 +++++++++++++
> > >  4 files changed, 238 insertions(+), 1 deletion(-)
> > >  create mode 100644 sound/hda/ext/hdac_codec.c
> > >  create mode 100644 sound/hda/ext/hdac_codec.h
> > > 
> > > diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h
> > > index 93e63c5..79502dc 100644
> > > --- a/include/sound/hdaudio.h
> > > +++ b/include/sound/hdaudio.h
> > > @@ -71,6 +71,7 @@ struct hdac_device {
> > >  			 unsigned int flags, unsigned int *res);
> > >  
> > >  	/* widgets */
> > > +	struct list_head widget_list;
> > >  	unsigned int num_nodes;
> > >  	hda_nid_t start_nid, end_nid;
> > 
> > Any reason to add this to hdac_device although it's used only by
> > hda/ext?
> 
> Hi Takashi,
> 
> Added this in the hdac_device, as this looked to be the more suitable data
> structure for the widget_list and is more specific to the hdac device. 

Doesn't struct hdac_ext_device fit better?


Takashi
Subhransu S. Prusty Aug. 29, 2016, 1:17 p.m. UTC | #4
On Mon, Aug 29, 2016 at 02:55:41PM +0200, Takashi Iwai wrote:
> On Mon, 29 Aug 2016 14:47:33 +0200,
> Subhransu S. Prusty wrote:
> > 
> > On Mon, Aug 29, 2016 at 10:41:22AM +0200, Takashi Iwai wrote:
> > > On Mon, 29 Aug 2016 08:23:15 +0200,
> > > Subhransu S. Prusty wrote:
> > > > 
> > > > Add hdac helpers to enumerate the HDA widgets and fill connection
> > > > lists for each.
> > > > 
> > > > Signed-off-by: Subhransu S. Prusty <subhransu.s.prusty@intel.com>
> > > > Signed-off-by: Vinod Koul <vinod.koul@intel.com>
> > > > ---
> > > >  include/sound/hdaudio.h    |   1 +
> > > >  sound/hda/ext/Makefile     |   3 +-
> > > >  sound/hda/ext/hdac_codec.c | 182 +++++++++++++++++++++++++++++++++++++++++++++
> > > >  sound/hda/ext/hdac_codec.h |  53 +++++++++++++
> > > >  4 files changed, 238 insertions(+), 1 deletion(-)
> > > >  create mode 100644 sound/hda/ext/hdac_codec.c
> > > >  create mode 100644 sound/hda/ext/hdac_codec.h
> > > > 
> > > > diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h
> > > > index 93e63c5..79502dc 100644
> > > > --- a/include/sound/hdaudio.h
> > > > +++ b/include/sound/hdaudio.h
> > > > @@ -71,6 +71,7 @@ struct hdac_device {
> > > >  			 unsigned int flags, unsigned int *res);
> > > >  
> > > >  	/* widgets */
> > > > +	struct list_head widget_list;
> > > >  	unsigned int num_nodes;
> > > >  	hda_nid_t start_nid, end_nid;
> > > 
> > > Any reason to add this to hdac_device although it's used only by
> > > hda/ext?
> > 
> > Hi Takashi,
> > 
> > Added this in the hdac_device, as this looked to be the more suitable data
> > structure for the widget_list and is more specific to the hdac device. 
> 
> Doesn't struct hdac_ext_device fit better?

The snd_hdac_parse_widgets helper defined in hdac_codec.c populates members
of hdac_device structure like num_nodes, start_nid etc. Even though
widget_list is used in hda/ext, this looked generic to be added in
hdac_device. I am inclined to add these helpers in hdac_device.c or may be
move hdac_codec.c to sound/hda if you are ok.

Regards,
Subhransu

> 
> 
> Takashi
Takashi Iwai Aug. 29, 2016, 1:28 p.m. UTC | #5
On Mon, 29 Aug 2016 15:17:50 +0200,
Subhransu S. Prusty wrote:
> 
> On Mon, Aug 29, 2016 at 02:55:41PM +0200, Takashi Iwai wrote:
> > On Mon, 29 Aug 2016 14:47:33 +0200,
> > Subhransu S. Prusty wrote:
> > > 
> > > On Mon, Aug 29, 2016 at 10:41:22AM +0200, Takashi Iwai wrote:
> > > > On Mon, 29 Aug 2016 08:23:15 +0200,
> > > > Subhransu S. Prusty wrote:
> > > > > 
> > > > > Add hdac helpers to enumerate the HDA widgets and fill connection
> > > > > lists for each.
> > > > > 
> > > > > Signed-off-by: Subhransu S. Prusty <subhransu.s.prusty@intel.com>
> > > > > Signed-off-by: Vinod Koul <vinod.koul@intel.com>
> > > > > ---
> > > > >  include/sound/hdaudio.h    |   1 +
> > > > >  sound/hda/ext/Makefile     |   3 +-
> > > > >  sound/hda/ext/hdac_codec.c | 182 +++++++++++++++++++++++++++++++++++++++++++++
> > > > >  sound/hda/ext/hdac_codec.h |  53 +++++++++++++
> > > > >  4 files changed, 238 insertions(+), 1 deletion(-)
> > > > >  create mode 100644 sound/hda/ext/hdac_codec.c
> > > > >  create mode 100644 sound/hda/ext/hdac_codec.h
> > > > > 
> > > > > diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h
> > > > > index 93e63c5..79502dc 100644
> > > > > --- a/include/sound/hdaudio.h
> > > > > +++ b/include/sound/hdaudio.h
> > > > > @@ -71,6 +71,7 @@ struct hdac_device {
> > > > >  			 unsigned int flags, unsigned int *res);
> > > > >  
> > > > >  	/* widgets */
> > > > > +	struct list_head widget_list;
> > > > >  	unsigned int num_nodes;
> > > > >  	hda_nid_t start_nid, end_nid;
> > > > 
> > > > Any reason to add this to hdac_device although it's used only by
> > > > hda/ext?
> > > 
> > > Hi Takashi,
> > > 
> > > Added this in the hdac_device, as this looked to be the more suitable data
> > > structure for the widget_list and is more specific to the hdac device. 
> > 
> > Doesn't struct hdac_ext_device fit better?
> 
> The snd_hdac_parse_widgets helper defined in hdac_codec.c populates members
> of hdac_device structure like num_nodes, start_nid etc. Even though
> widget_list is used in hda/ext, this looked generic to be added in
> hdac_device.

If it's used only in hda/ext, why it's generic, i.e. putting to the
place used commonly for legacy drivers?  I don't follow this logic...

> I am inclined to add these helpers in hdac_device.c or may be
> move hdac_codec.c to sound/hda if you are ok.

Even if we put it in hdac_device, initializing in another function is
wrong.  It must be initialized in snd_hdac_device_init(), if it's a
part of the common struct.


Takashi
Subhransu S. Prusty Aug. 29, 2016, 1:33 p.m. UTC | #6
On Mon, Aug 29, 2016 at 03:28:35PM +0200, Takashi Iwai wrote:
> On Mon, 29 Aug 2016 15:17:50 +0200,
> Subhransu S. Prusty wrote:
> > 
> > On Mon, Aug 29, 2016 at 02:55:41PM +0200, Takashi Iwai wrote:
> > > On Mon, 29 Aug 2016 14:47:33 +0200,
> > > Subhransu S. Prusty wrote:
> > > > 
> > > > On Mon, Aug 29, 2016 at 10:41:22AM +0200, Takashi Iwai wrote:
> > > > > On Mon, 29 Aug 2016 08:23:15 +0200,
> > > > > Subhransu S. Prusty wrote:
> > > > > > 
> > > > > > Add hdac helpers to enumerate the HDA widgets and fill connection
> > > > > > lists for each.
> > > > > > 
> > > > > > Signed-off-by: Subhransu S. Prusty <subhransu.s.prusty@intel.com>
> > > > > > Signed-off-by: Vinod Koul <vinod.koul@intel.com>
> > > > > > ---
> > > > > >  include/sound/hdaudio.h    |   1 +
> > > > > >  sound/hda/ext/Makefile     |   3 +-
> > > > > >  sound/hda/ext/hdac_codec.c | 182 +++++++++++++++++++++++++++++++++++++++++++++
> > > > > >  sound/hda/ext/hdac_codec.h |  53 +++++++++++++
> > > > > >  4 files changed, 238 insertions(+), 1 deletion(-)
> > > > > >  create mode 100644 sound/hda/ext/hdac_codec.c
> > > > > >  create mode 100644 sound/hda/ext/hdac_codec.h
> > > > > > 
> > > > > > diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h
> > > > > > index 93e63c5..79502dc 100644
> > > > > > --- a/include/sound/hdaudio.h
> > > > > > +++ b/include/sound/hdaudio.h
> > > > > > @@ -71,6 +71,7 @@ struct hdac_device {
> > > > > >  			 unsigned int flags, unsigned int *res);
> > > > > >  
> > > > > >  	/* widgets */
> > > > > > +	struct list_head widget_list;
> > > > > >  	unsigned int num_nodes;
> > > > > >  	hda_nid_t start_nid, end_nid;
> > > > > 
> > > > > Any reason to add this to hdac_device although it's used only by
> > > > > hda/ext?
> > > > 
> > > > Hi Takashi,
> > > > 
> > > > Added this in the hdac_device, as this looked to be the more suitable data
> > > > structure for the widget_list and is more specific to the hdac device. 
> > > 
> > > Doesn't struct hdac_ext_device fit better?
> > 
> > The snd_hdac_parse_widgets helper defined in hdac_codec.c populates members
> > of hdac_device structure like num_nodes, start_nid etc. Even though
> > widget_list is used in hda/ext, this looked generic to be added in
> > hdac_device.
> 
> If it's used only in hda/ext, why it's generic, i.e. putting to the
> place used commonly for legacy drivers?  I don't follow this logic...
> 
> > I am inclined to add these helpers in hdac_device.c or may be
> > move hdac_codec.c to sound/hda if you are ok.
> 
> Even if we put it in hdac_device, initializing in another function is
> wrong.  It must be initialized in snd_hdac_device_init(), if it's a
> part of the common struct.

Ok, got it. Will move this to hdac_ext_device.

Regards,
Subhransu
Takashi Iwai Aug. 29, 2016, 1:43 p.m. UTC | #7
On Mon, 29 Aug 2016 15:33:57 +0200,
Subhransu S. Prusty wrote:
> 
> On Mon, Aug 29, 2016 at 03:28:35PM +0200, Takashi Iwai wrote:
> > On Mon, 29 Aug 2016 15:17:50 +0200,
> > Subhransu S. Prusty wrote:
> > > 
> > > On Mon, Aug 29, 2016 at 02:55:41PM +0200, Takashi Iwai wrote:
> > > > On Mon, 29 Aug 2016 14:47:33 +0200,
> > > > Subhransu S. Prusty wrote:
> > > > > 
> > > > > On Mon, Aug 29, 2016 at 10:41:22AM +0200, Takashi Iwai wrote:
> > > > > > On Mon, 29 Aug 2016 08:23:15 +0200,
> > > > > > Subhransu S. Prusty wrote:
> > > > > > > 
> > > > > > > Add hdac helpers to enumerate the HDA widgets and fill connection
> > > > > > > lists for each.
> > > > > > > 
> > > > > > > Signed-off-by: Subhransu S. Prusty <subhransu.s.prusty@intel.com>
> > > > > > > Signed-off-by: Vinod Koul <vinod.koul@intel.com>
> > > > > > > ---
> > > > > > >  include/sound/hdaudio.h    |   1 +
> > > > > > >  sound/hda/ext/Makefile     |   3 +-
> > > > > > >  sound/hda/ext/hdac_codec.c | 182 +++++++++++++++++++++++++++++++++++++++++++++
> > > > > > >  sound/hda/ext/hdac_codec.h |  53 +++++++++++++
> > > > > > >  4 files changed, 238 insertions(+), 1 deletion(-)
> > > > > > >  create mode 100644 sound/hda/ext/hdac_codec.c
> > > > > > >  create mode 100644 sound/hda/ext/hdac_codec.h
> > > > > > > 
> > > > > > > diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h
> > > > > > > index 93e63c5..79502dc 100644
> > > > > > > --- a/include/sound/hdaudio.h
> > > > > > > +++ b/include/sound/hdaudio.h
> > > > > > > @@ -71,6 +71,7 @@ struct hdac_device {
> > > > > > >  			 unsigned int flags, unsigned int *res);
> > > > > > >  
> > > > > > >  	/* widgets */
> > > > > > > +	struct list_head widget_list;
> > > > > > >  	unsigned int num_nodes;
> > > > > > >  	hda_nid_t start_nid, end_nid;
> > > > > > 
> > > > > > Any reason to add this to hdac_device although it's used only by
> > > > > > hda/ext?
> > > > > 
> > > > > Hi Takashi,
> > > > > 
> > > > > Added this in the hdac_device, as this looked to be the more suitable data
> > > > > structure for the widget_list and is more specific to the hdac device. 
> > > > 
> > > > Doesn't struct hdac_ext_device fit better?
> > > 
> > > The snd_hdac_parse_widgets helper defined in hdac_codec.c populates members
> > > of hdac_device structure like num_nodes, start_nid etc. Even though
> > > widget_list is used in hda/ext, this looked generic to be added in
> > > hdac_device.
> > 
> > If it's used only in hda/ext, why it's generic, i.e. putting to the
> > place used commonly for legacy drivers?  I don't follow this logic...
> > 
> > > I am inclined to add these helpers in hdac_device.c or may be
> > > move hdac_codec.c to sound/hda if you are ok.
> > 
> > Even if we put it in hdac_device, initializing in another function is
> > wrong.  It must be initialized in snd_hdac_device_init(), if it's a
> > part of the common struct.
> 
> Ok, got it. Will move this to hdac_ext_device.

Don't get me wrong: I'd like to understand why it's put to
hdac_device.  If this makes the code easier / simpler, it's a good
justification.  Without the explanation, placing to the relevant
struct makes more sense.  That's my point.


Takashi
Subhransu S. Prusty Aug. 30, 2016, 7:46 a.m. UTC | #8
On Mon, Aug 29, 2016 at 03:43:27PM +0200, Takashi Iwai wrote:
> On Mon, 29 Aug 2016 15:33:57 +0200,
> Subhransu S. Prusty wrote:
> > 
> > On Mon, Aug 29, 2016 at 03:28:35PM +0200, Takashi Iwai wrote:
> > > On Mon, 29 Aug 2016 15:17:50 +0200,
> > > Subhransu S. Prusty wrote:
> > > > 
> > > > On Mon, Aug 29, 2016 at 02:55:41PM +0200, Takashi Iwai wrote:
> > > > > On Mon, 29 Aug 2016 14:47:33 +0200,
> > > > > Subhransu S. Prusty wrote:
> > > > > > 
> > > > > > On Mon, Aug 29, 2016 at 10:41:22AM +0200, Takashi Iwai wrote:
> > > > > > > On Mon, 29 Aug 2016 08:23:15 +0200,
> > > > > > > Subhransu S. Prusty wrote:
> > > > > > > > 
> > > > > > > > Add hdac helpers to enumerate the HDA widgets and fill connection
> > > > > > > > lists for each.
> > > > > > > > 
> > > > > > > > Signed-off-by: Subhransu S. Prusty <subhransu.s.prusty@intel.com>
> > > > > > > > Signed-off-by: Vinod Koul <vinod.koul@intel.com>
> > > > > > > > ---
> > > > > > > >  include/sound/hdaudio.h    |   1 +
> > > > > > > >  sound/hda/ext/Makefile     |   3 +-
> > > > > > > >  sound/hda/ext/hdac_codec.c | 182 +++++++++++++++++++++++++++++++++++++++++++++
> > > > > > > >  sound/hda/ext/hdac_codec.h |  53 +++++++++++++
> > > > > > > >  4 files changed, 238 insertions(+), 1 deletion(-)
> > > > > > > >  create mode 100644 sound/hda/ext/hdac_codec.c
> > > > > > > >  create mode 100644 sound/hda/ext/hdac_codec.h
> > > > > > > > 
> > > > > > > > diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h
> > > > > > > > index 93e63c5..79502dc 100644
> > > > > > > > --- a/include/sound/hdaudio.h
> > > > > > > > +++ b/include/sound/hdaudio.h
> > > > > > > > @@ -71,6 +71,7 @@ struct hdac_device {
> > > > > > > >  			 unsigned int flags, unsigned int *res);
> > > > > > > >  
> > > > > > > >  	/* widgets */
> > > > > > > > +	struct list_head widget_list;
> > > > > > > >  	unsigned int num_nodes;
> > > > > > > >  	hda_nid_t start_nid, end_nid;
> > > > > > > 
> > > > > > > Any reason to add this to hdac_device although it's used only by
> > > > > > > hda/ext?
> > > > > > 
> > > > > > Hi Takashi,
> > > > > > 
> > > > > > Added this in the hdac_device, as this looked to be the more suitable data
> > > > > > structure for the widget_list and is more specific to the hdac device. 
> > > > > 
> > > > > Doesn't struct hdac_ext_device fit better?
> > > > 
> > > > The snd_hdac_parse_widgets helper defined in hdac_codec.c populates members
> > > > of hdac_device structure like num_nodes, start_nid etc. Even though
> > > > widget_list is used in hda/ext, this looked generic to be added in
> > > > hdac_device.
> > > 
> > > If it's used only in hda/ext, why it's generic, i.e. putting to the
> > > place used commonly for legacy drivers?  I don't follow this logic...
> > > 
> > > > I am inclined to add these helpers in hdac_device.c or may be
> > > > move hdac_codec.c to sound/hda if you are ok.
> > > 
> > > Even if we put it in hdac_device, initializing in another function is
> > > wrong.  It must be initialized in snd_hdac_device_init(), if it's a
> > > part of the common struct.
> > 
> > Ok, got it. Will move this to hdac_ext_device.
> 
> Don't get me wrong: I'd like to understand why it's put to
> hdac_device.  If this makes the code easier / simpler, it's a good
> justification.  Without the explanation, placing to the relevant
> struct makes more sense.  That's my point.

I understand what you meant to convey.

In this patch a generic widget structure is created to abstract the
properties of HDA widgets. These widgets are added to the widget_list member
as n when these are enumerated. I am unsure whether this hda_codec_widget
struture and the widget_list can be used through a common library by both
legacy and ASoC drivers. May not be now but in future. So adding this to
hdac_ext_device for now.

Regards
Subhransu

Patch
diff mbox

diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h
index 93e63c5..79502dc 100644
--- a/include/sound/hdaudio.h
+++ b/include/sound/hdaudio.h
@@ -71,6 +71,7 @@  struct hdac_device {
 			 unsigned int flags, unsigned int *res);
 
 	/* widgets */
+	struct list_head widget_list;
 	unsigned int num_nodes;
 	hda_nid_t start_nid, end_nid;
 
diff --git a/sound/hda/ext/Makefile b/sound/hda/ext/Makefile
index 9b6f641..0aebd9d 100644
--- a/sound/hda/ext/Makefile
+++ b/sound/hda/ext/Makefile
@@ -1,3 +1,4 @@ 
-snd-hda-ext-core-objs := hdac_ext_bus.o hdac_ext_controller.o hdac_ext_stream.o
+snd-hda-ext-core-objs := hdac_ext_bus.o hdac_ext_controller.o hdac_ext_stream.o \
+			hdac_codec.o
 
 obj-$(CONFIG_SND_HDA_EXT_CORE) += snd-hda-ext-core.o
diff --git a/sound/hda/ext/hdac_codec.c b/sound/hda/ext/hdac_codec.c
new file mode 100644
index 0000000..ba87af0
--- /dev/null
+++ b/sound/hda/ext/hdac_codec.c
@@ -0,0 +1,182 @@ 
+/*
+ *  hdac_codec.c - HDA codec library
+ *
+ *  Copyright (C) 2016 Intel Corp
+ *  Author: Subhransu S. Prusty <subhransu.s.prusty@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; version 2 of the License.
+ *
+ *  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.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <sound/soc.h>
+#include <sound/hdaudio_ext.h>
+#include "../../hda/local.h"
+#include "hdac_codec.h"
+#include <sound/hda_verbs.h>
+
+static int hdac_generic_query_connlist(struct hdac_device *hdac,
+				struct hdac_codec_widget *wid)
+{
+	hda_nid_t mux_nids[HDA_MAX_CONNECTIONS];
+	unsigned int caps;
+	int i;
+
+	if (!(get_wcaps(hdac, wid->nid) & AC_WCAP_CONN_LIST)) {
+		dev_dbg(&hdac->dev,
+			"HDAC: wid %d wcaps %#x doesn't support connection list\n",
+			wid->nid, get_wcaps(hdac, wid->nid));
+
+		return 0;
+	}
+
+	wid->num_inputs = snd_hdac_get_connections(hdac, wid->nid,
+					mux_nids, HDA_MAX_CONNECTIONS);
+
+	if (wid->num_inputs == 0) {
+		dev_warn(&hdac->dev, "No connections found for wid: %d\n",
+							wid->nid);
+		return 0;
+	}
+
+	for (i = 0; i < wid->num_inputs; i++) {
+		wid->conn_list[i].nid = mux_nids[i];
+		caps = get_wcaps(hdac, mux_nids[i]);
+		wid->conn_list[i].type = get_wcaps_type(caps);
+	}
+
+	dev_dbg(&hdac->dev, "num_inputs %d for wid: %d\n",
+			wid->num_inputs, wid->nid);
+
+	return wid->num_inputs;
+}
+
+static int hdac_codec_add_widget(struct hdac_device *codec, hda_nid_t nid,
+				unsigned int type, unsigned int caps)
+{
+	struct hdac_codec_widget *widget;
+	unsigned int *cfg;
+
+	widget = kzalloc(sizeof(*widget), GFP_KERNEL);
+	if (!widget)
+		return -ENOMEM;
+
+	widget->nid = nid;
+	widget->type = type;
+	widget->caps = caps;
+	list_add_tail(&widget->head, &codec->widget_list);
+
+	if (type == AC_WID_PIN) {
+		cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
+		if (!cfg)
+			return -ENOMEM;
+
+		*cfg = snd_hdac_codec_read(codec, nid, 0,
+					AC_VERB_GET_CONFIG_DEFAULT, 0);
+		widget->params = cfg;
+	}
+
+	return hdac_generic_query_connlist(codec, widget);
+}
+
+/**
+ * snd_hdac_parse_widgets - Iterates over the hda codec, enumerates the
+ *			    widgets and its connections.
+ * @hdac: pointer to HDAC devcie
+ *
+ * Returns 0 if successful, or a negative error code.
+ */
+int snd_hdac_parse_widgets(struct hdac_device *hdac)
+{
+	hda_nid_t nid;
+	int num_nodes, i;
+	struct hdac_codec_widget *wid;
+	struct hdac_codec_widget *tmp;
+	int ret = 0;
+
+	num_nodes = snd_hdac_get_sub_nodes(hdac, hdac->afg, &nid);
+	if (!nid || num_nodes <= 0) {
+		dev_err(&hdac->dev, "HDAC: failed to get afg sub nodes\n");
+		return -EINVAL;
+	}
+	hdac->num_nodes = num_nodes;
+	hdac->start_nid = nid;
+
+	for (i = 0; i < hdac->num_nodes; i++, nid++) {
+		unsigned int caps;
+		unsigned int type;
+
+		caps = get_wcaps(hdac, nid);
+		type = get_wcaps_type(caps);
+
+		ret = hdac_codec_add_widget(hdac, nid, type, caps);
+		if (ret < 0)
+			goto fail_add_widget;
+
+	}
+
+	hdac->end_nid = nid;
+
+	/* Cache input connection to a widget */
+	list_for_each_entry(wid, &hdac->widget_list, head) {
+		if (!wid->num_inputs)
+			continue;
+
+		for (i = 0; i < wid->num_inputs; i++) {
+			list_for_each_entry(tmp, &hdac->widget_list, head) {
+				if (wid->conn_list[i].nid == tmp->nid) {
+					wid->conn_list[i].input_w = tmp;
+					break;
+				}
+			}
+		}
+	}
+
+	return 0;
+
+fail_add_widget:
+	snd_hdac_codec_cleanup(hdac);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(snd_hdac_parse_widgets);
+
+/**
+ * snd_hdac_codec_init - Initialize some more hdac device elements
+ * @hdac: pointer to hdac device
+ *
+ * Returns 0 if successful.
+ */
+int snd_hdac_codec_init(struct hdac_device *hdac)
+{
+	INIT_LIST_HEAD(&hdac->widget_list);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(snd_hdac_codec_init);
+
+/**
+ * snd_hdac_codec_cleanup - Cleanup resources allocated during device
+ * initialization.
+ * @hdac: pointer to hdac device
+ */
+void snd_hdac_codec_cleanup(struct hdac_device *hdac)
+{
+	struct hdac_codec_widget *wid, *tmp;
+
+	list_for_each_entry_safe(wid, tmp, &hdac->widget_list, head) {
+		kfree(wid->params);
+		list_del(&wid->head);
+		kfree(wid);
+	}
+}
+EXPORT_SYMBOL_GPL(snd_hdac_codec_cleanup);
diff --git a/sound/hda/ext/hdac_codec.h b/sound/hda/ext/hdac_codec.h
new file mode 100644
index 0000000..7f47a7e
--- /dev/null
+++ b/sound/hda/ext/hdac_codec.h
@@ -0,0 +1,53 @@ 
+/*
+ *  hdac_codec.h - HDA codec library
+ *
+ *  Copyright (C) 2016 Intel Corp
+ *  Author: Subhransu S. Prusty <subhransu.s.prusty@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; version 2 of the License.
+ *
+ *  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.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+#ifndef __HDAC_CODEC_H__
+#define __HDAC_CODEC_H__
+
+#define HDA_MAX_CONNECTIONS 32
+/* amp values */
+#define AMP_IN_MUTE(idx)	(0x7080 | ((idx)<<8))
+#define AMP_IN_UNMUTE(idx)	(0x7000 | ((idx)<<8))
+#define AMP_OUT_MUTE		0xb080
+#define AMP_OUT_UNMUTE		0xb000
+
+struct hdac_codec_widget;
+
+struct hdac_codec_connection_list {
+	hda_nid_t nid;
+	unsigned int type;
+	struct hdac_codec_widget *input_w;
+};
+
+struct hdac_codec_widget {
+	struct list_head head;
+	hda_nid_t nid;
+	unsigned int caps;
+	unsigned int type;
+	int num_inputs;
+	struct hdac_codec_connection_list conn_list[HDA_MAX_CONNECTIONS];
+	void *priv;	/* Codec specific widget data */
+	void *params;	/* Widget specific parameters */
+};
+
+int snd_hdac_parse_widgets(struct hdac_device *hdac);
+int snd_hdac_codec_init(struct hdac_device *hdac);
+void snd_hdac_codec_cleanup(struct hdac_device *hdac);
+
+#endif /* __HDAC_CODEC_H__ */