Message ID | 1472451806-10605-2-git-send-email-subhransu.s.prusty@intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
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
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
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
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
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
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
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
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
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__ */