From 3787a39852b0d6a9e67336f8fb5815c13ab78bb6 Mon Sep 17 00:00:00 2001 From: Rakesh Ughreja Date: Fri, 1 Jun 2018 22:53:49 -0500 Subject: ALSA: hdac: Remove usage of struct hdac_ext_device and use hdac_device instead This patch removes the hdac_ext_device structure. The legacy and enhanced HDaudio capabilities can be handled in a backward-compatible way without separate definitions. Follow-up patches in this series handle the bus and driver definitions. Signed-off-by: Rakesh Ughreja Signed-off-by: Pierre-Louis Bossart Signed-off-by: Takashi Iwai --- include/sound/hdaudio_ext.h | 36 ++++-------------------------------- 1 file changed, 4 insertions(+), 32 deletions(-) (limited to 'include') diff --git a/include/sound/hdaudio_ext.h b/include/sound/hdaudio_ext.h index 9c14e21dda85..c1a5ad0e6e39 100644 --- a/include/sound/hdaudio_ext.h +++ b/include/sound/hdaudio_ext.h @@ -181,48 +181,20 @@ struct hda_dai_map { u32 maxbps; }; -#define HDA_MAX_NIDS 16 - -/** - * struct hdac_ext_device - HDAC Ext device - * - * @hdac: hdac core device - * @nid_list - the dai map which matches the dai-name with the nid - * @map_cur_idx - the idx in use in dai_map - * @ops - the hda codec ops common to all codec drivers - * @pvt_data - private data, for asoc contains asoc codec object - */ -struct hdac_ext_device { - struct hdac_device hdev; - struct hdac_ext_bus *ebus; - - /* soc-dai to nid map */ - struct hda_dai_map nid_list[HDA_MAX_NIDS]; - unsigned int map_cur_idx; - - /* codec ops */ - struct hdac_ext_codec_ops ops; - - struct snd_card *card; - void *scodec; - void *private_data; -}; - struct hdac_ext_dma_params { u32 format; u8 stream_tag; }; -#define to_ehdac_device(dev) (container_of((dev), \ - struct hdac_ext_device, hdev)) + /* * HD-audio codec base driver */ struct hdac_ext_driver { struct hdac_driver hdac; - int (*probe)(struct hdac_ext_device *dev); - int (*remove)(struct hdac_ext_device *dev); - void (*shutdown)(struct hdac_ext_device *dev); + int (*probe)(struct hdac_device *dev); + int (*remove)(struct hdac_device *dev); + void (*shutdown)(struct hdac_device *dev); }; int snd_hda_ext_driver_register(struct hdac_ext_driver *drv); -- cgit v1.2.3-58-ga151 From 76f56fae1cf9040325a58d1375291baf71dfaf03 Mon Sep 17 00:00:00 2001 From: Rakesh Ughreja Date: Fri, 1 Jun 2018 22:53:50 -0500 Subject: ALSA: hdac: Remove usage of struct hdac_ext_bus and use hdac_bus instead This patch removes the hdac_ext_bus structure. The legacy and enhanced HDaudio capabilities can be handled in a backward-compatible way without separate definitions. Follow-up patches in this series handle the driver definition. Signed-off-by: Rakesh Ughreja Signed-off-by: Pierre-Louis Bossart Signed-off-by: Takashi Iwai --- include/sound/hdaudio.h | 15 +++ include/sound/hdaudio_ext.h | 74 +++++-------- sound/hda/ext/hdac_ext_bus.c | 27 +++-- sound/hda/ext/hdac_ext_controller.c | 55 +++++----- sound/hda/ext/hdac_ext_stream.c | 104 ++++++++----------- sound/soc/codecs/hdac_hdmi.c | 22 ++-- sound/soc/intel/skylake/skl-messages.c | 50 ++++----- sound/soc/intel/skylake/skl-nhlt.c | 8 +- sound/soc/intel/skylake/skl-pcm.c | 112 ++++++++++---------- sound/soc/intel/skylake/skl-topology.c | 20 ++-- sound/soc/intel/skylake/skl-topology.h | 6 +- sound/soc/intel/skylake/skl.c | 184 +++++++++++++++------------------ sound/soc/intel/skylake/skl.h | 7 +- 13 files changed, 308 insertions(+), 376 deletions(-) (limited to 'include') diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h index c052afc27547..9735b51aef08 100644 --- a/include/sound/hdaudio.h +++ b/include/sound/hdaudio.h @@ -250,6 +250,11 @@ struct hdac_rb { * @mlcap: MultiLink capabilities pointer * @gtscap: gts capabilities pointer * @drsmcap: dma resume capabilities pointer + * @num_streams: streams supported + * @idx: HDA link index + * @hlink_list: link list of HDA links + * @lock: lock for link mgmt + * @cmd_dma_state: state of cmd DMAs: CORB and RIRB */ struct hdac_bus { struct device *dev; @@ -317,6 +322,16 @@ struct hdac_bus { /* i915 component interface */ struct i915_audio_component *audio_component; int i915_power_refcount; + + /* parameters required for enhanced capabilities */ + int num_streams; + int idx; + + struct list_head hlink_list; + + struct mutex lock; + bool cmd_dma_state; + }; int snd_hdac_bus_init(struct hdac_bus *bus, struct device *dev, diff --git a/include/sound/hdaudio_ext.h b/include/sound/hdaudio_ext.h index c1a5ad0e6e39..e5b0cd1ade19 100644 --- a/include/sound/hdaudio_ext.h +++ b/include/sound/hdaudio_ext.h @@ -4,38 +4,14 @@ #include -/** - * hdac_ext_bus: HDAC extended bus for extended HDA caps - * - * @bus: hdac bus - * @num_streams: streams supported - * @hlink_list: link list of HDA links - * @lock: lock for link mgmt - * @cmd_dma_state: state of cmd DMAs: CORB and RIRB - */ -struct hdac_ext_bus { - struct hdac_bus bus; - int num_streams; - int idx; - - struct list_head hlink_list; - - struct mutex lock; - bool cmd_dma_state; -}; - -int snd_hdac_ext_bus_init(struct hdac_ext_bus *sbus, struct device *dev, +int snd_hdac_ext_bus_init(struct hdac_bus *bus, struct device *dev, const struct hdac_bus_ops *ops, const struct hdac_io_ops *io_ops); -void snd_hdac_ext_bus_exit(struct hdac_ext_bus *sbus); -int snd_hdac_ext_bus_device_init(struct hdac_ext_bus *sbus, int addr); +void snd_hdac_ext_bus_exit(struct hdac_bus *bus); +int snd_hdac_ext_bus_device_init(struct hdac_bus *bus, int addr); void snd_hdac_ext_bus_device_exit(struct hdac_device *hdev); -void snd_hdac_ext_bus_device_remove(struct hdac_ext_bus *ebus); - -#define ebus_to_hbus(ebus) (&(ebus)->bus) -#define hbus_to_ebus(_bus) \ - container_of(_bus, struct hdac_ext_bus, bus) +void snd_hdac_ext_bus_device_remove(struct hdac_bus *bus); #define HDA_CODEC_REV_EXT_ENTRY(_vid, _rev, _name, drv_data) \ { .vendor_id = (_vid), .rev_id = (_rev), .name = (_name), \ @@ -44,14 +20,14 @@ void snd_hdac_ext_bus_device_remove(struct hdac_ext_bus *ebus); #define HDA_CODEC_EXT_ENTRY(_vid, _revid, _name, _drv_data) \ HDA_CODEC_REV_EXT_ENTRY(_vid, _revid, _name, _drv_data) -void snd_hdac_ext_bus_ppcap_enable(struct hdac_ext_bus *chip, bool enable); -void snd_hdac_ext_bus_ppcap_int_enable(struct hdac_ext_bus *chip, bool enable); +void snd_hdac_ext_bus_ppcap_enable(struct hdac_bus *chip, bool enable); +void snd_hdac_ext_bus_ppcap_int_enable(struct hdac_bus *chip, bool enable); -void snd_hdac_ext_stream_spbcap_enable(struct hdac_ext_bus *chip, +void snd_hdac_ext_stream_spbcap_enable(struct hdac_bus *chip, bool enable, int index); -int snd_hdac_ext_bus_get_ml_capabilities(struct hdac_ext_bus *bus); -struct hdac_ext_link *snd_hdac_ext_bus_get_link(struct hdac_ext_bus *bus, +int snd_hdac_ext_bus_get_ml_capabilities(struct hdac_bus *bus); +struct hdac_ext_link *snd_hdac_ext_bus_get_link(struct hdac_bus *bus, const char *codec_name); enum hdac_ext_stream_type { @@ -100,28 +76,28 @@ struct hdac_ext_stream { #define stream_to_hdac_ext_stream(s) \ container_of(s, struct hdac_ext_stream, hstream) -void snd_hdac_ext_stream_init(struct hdac_ext_bus *bus, +void snd_hdac_ext_stream_init(struct hdac_bus *bus, struct hdac_ext_stream *stream, int idx, int direction, int tag); -int snd_hdac_ext_stream_init_all(struct hdac_ext_bus *ebus, int start_idx, +int snd_hdac_ext_stream_init_all(struct hdac_bus *bus, int start_idx, int num_stream, int dir); -void snd_hdac_stream_free_all(struct hdac_ext_bus *ebus); -void snd_hdac_link_free_all(struct hdac_ext_bus *ebus); -struct hdac_ext_stream *snd_hdac_ext_stream_assign(struct hdac_ext_bus *bus, +void snd_hdac_stream_free_all(struct hdac_bus *bus); +void snd_hdac_link_free_all(struct hdac_bus *bus); +struct hdac_ext_stream *snd_hdac_ext_stream_assign(struct hdac_bus *bus, struct snd_pcm_substream *substream, int type); void snd_hdac_ext_stream_release(struct hdac_ext_stream *azx_dev, int type); -void snd_hdac_ext_stream_decouple(struct hdac_ext_bus *bus, +void snd_hdac_ext_stream_decouple(struct hdac_bus *bus, struct hdac_ext_stream *azx_dev, bool decouple); -void snd_hdac_ext_stop_streams(struct hdac_ext_bus *sbus); +void snd_hdac_ext_stop_streams(struct hdac_bus *bus); -int snd_hdac_ext_stream_set_spib(struct hdac_ext_bus *ebus, +int snd_hdac_ext_stream_set_spib(struct hdac_bus *bus, struct hdac_ext_stream *stream, u32 value); -int snd_hdac_ext_stream_get_spbmaxfifo(struct hdac_ext_bus *ebus, +int snd_hdac_ext_stream_get_spbmaxfifo(struct hdac_bus *bus, struct hdac_ext_stream *stream); -void snd_hdac_ext_stream_drsm_enable(struct hdac_ext_bus *ebus, +void snd_hdac_ext_stream_drsm_enable(struct hdac_bus *bus, bool enable, int index); -int snd_hdac_ext_stream_set_dpibr(struct hdac_ext_bus *ebus, +int snd_hdac_ext_stream_set_dpibr(struct hdac_bus *bus, struct hdac_ext_stream *stream, u32 value); int snd_hdac_ext_stream_set_lpib(struct hdac_ext_stream *stream, u32 value); @@ -144,17 +120,15 @@ struct hdac_ext_link { int snd_hdac_ext_bus_link_power_up(struct hdac_ext_link *link); int snd_hdac_ext_bus_link_power_down(struct hdac_ext_link *link); -int snd_hdac_ext_bus_link_power_up_all(struct hdac_ext_bus *ebus); -int snd_hdac_ext_bus_link_power_down_all(struct hdac_ext_bus *ebus); +int snd_hdac_ext_bus_link_power_up_all(struct hdac_bus *bus); +int snd_hdac_ext_bus_link_power_down_all(struct hdac_bus *bus); void snd_hdac_ext_link_set_stream_id(struct hdac_ext_link *link, int stream); void snd_hdac_ext_link_clear_stream_id(struct hdac_ext_link *link, int stream); -int snd_hdac_ext_bus_link_get(struct hdac_ext_bus *ebus, - struct hdac_ext_link *link); -int snd_hdac_ext_bus_link_put(struct hdac_ext_bus *ebus, - struct hdac_ext_link *link); +int snd_hdac_ext_bus_link_get(struct hdac_bus *bus, struct hdac_ext_link *link); +int snd_hdac_ext_bus_link_put(struct hdac_bus *bus, struct hdac_ext_link *link); /* update register macro */ #define snd_hdac_updatel(addr, reg, mask, val) \ diff --git a/sound/hda/ext/hdac_ext_bus.c b/sound/hda/ext/hdac_ext_bus.c index 0e4823fdd411..77547ede9ae8 100644 --- a/sound/hda/ext/hdac_ext_bus.c +++ b/sound/hda/ext/hdac_ext_bus.c @@ -87,7 +87,7 @@ static const struct hdac_io_ops hdac_ext_default_io = { * * Returns 0 if successful, or a negative error code. */ -int snd_hdac_ext_bus_init(struct hdac_ext_bus *ebus, struct device *dev, +int snd_hdac_ext_bus_init(struct hdac_bus *bus, struct device *dev, const struct hdac_bus_ops *ops, const struct hdac_io_ops *io_ops) { @@ -98,15 +98,15 @@ int snd_hdac_ext_bus_init(struct hdac_ext_bus *ebus, struct device *dev, if (io_ops == NULL) io_ops = &hdac_ext_default_io; - ret = snd_hdac_bus_init(&ebus->bus, dev, ops, io_ops); + ret = snd_hdac_bus_init(bus, dev, ops, io_ops); if (ret < 0) return ret; - INIT_LIST_HEAD(&ebus->hlink_list); - ebus->idx = idx++; + INIT_LIST_HEAD(&bus->hlink_list); + bus->idx = idx++; - mutex_init(&ebus->lock); - ebus->cmd_dma_state = true; + mutex_init(&bus->lock); + bus->cmd_dma_state = true; return 0; } @@ -116,10 +116,10 @@ EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_init); * snd_hdac_ext_bus_exit - clean up a HD-audio extended bus * @ebus: the pointer to extended bus object */ -void snd_hdac_ext_bus_exit(struct hdac_ext_bus *ebus) +void snd_hdac_ext_bus_exit(struct hdac_bus *bus) { - snd_hdac_bus_exit(&ebus->bus); - WARN_ON(!list_empty(&ebus->hlink_list)); + snd_hdac_bus_exit(bus); + WARN_ON(!list_empty(&bus->hlink_list)); } EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_exit); @@ -135,10 +135,9 @@ static void default_release(struct device *dev) * * Returns zero for success or a negative error code. */ -int snd_hdac_ext_bus_device_init(struct hdac_ext_bus *ebus, int addr) +int snd_hdac_ext_bus_device_init(struct hdac_bus *bus, int addr) { struct hdac_device *hdev = NULL; - struct hdac_bus *bus = ebus_to_hbus(ebus); char name[15]; int ret; @@ -148,7 +147,7 @@ int snd_hdac_ext_bus_device_init(struct hdac_ext_bus *ebus, int addr) hdev->bus = bus; - snprintf(name, sizeof(name), "ehdaudio%dD%d", ebus->idx, addr); + snprintf(name, sizeof(name), "ehdaudio%dD%d", bus->idx, addr); ret = snd_hdac_device_init(hdev, bus, name, addr); if (ret < 0) { @@ -185,14 +184,14 @@ EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_device_exit); * * @ebus: HD-audio extended bus */ -void snd_hdac_ext_bus_device_remove(struct hdac_ext_bus *ebus) +void snd_hdac_ext_bus_device_remove(struct hdac_bus *bus) { struct hdac_device *codec, *__codec; /* * we need to remove all the codec devices objects created in the * snd_hdac_ext_bus_device_init */ - list_for_each_entry_safe(codec, __codec, &ebus->bus.codec_list, list) { + list_for_each_entry_safe(codec, __codec, &bus->codec_list, list) { snd_hdac_device_unregister(codec); put_device(&codec->dev); } diff --git a/sound/hda/ext/hdac_ext_controller.c b/sound/hda/ext/hdac_ext_controller.c index 84f3b8168716..72774119dd11 100644 --- a/sound/hda/ext/hdac_ext_controller.c +++ b/sound/hda/ext/hdac_ext_controller.c @@ -39,9 +39,8 @@ * @ebus: HD-audio extended core bus * @enable: flag to turn on/off the capability */ -void snd_hdac_ext_bus_ppcap_enable(struct hdac_ext_bus *ebus, bool enable) +void snd_hdac_ext_bus_ppcap_enable(struct hdac_bus *bus, bool enable) { - struct hdac_bus *bus = &ebus->bus; if (!bus->ppcap) { dev_err(bus->dev, "Address of PP capability is NULL"); @@ -60,9 +59,8 @@ EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_ppcap_enable); * @ebus: HD-audio extended core bus * @enable: flag to enable/disable interrupt */ -void snd_hdac_ext_bus_ppcap_int_enable(struct hdac_ext_bus *ebus, bool enable) +void snd_hdac_ext_bus_ppcap_int_enable(struct hdac_bus *bus, bool enable) { - struct hdac_bus *bus = &ebus->bus; if (!bus->ppcap) { dev_err(bus->dev, "Address of PP capability is NULL\n"); @@ -89,12 +87,11 @@ EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_ppcap_int_enable); * in hlink_list of extended hdac bus * Note: this will be freed on bus exit by driver */ -int snd_hdac_ext_bus_get_ml_capabilities(struct hdac_ext_bus *ebus) +int snd_hdac_ext_bus_get_ml_capabilities(struct hdac_bus *bus) { int idx; u32 link_count; struct hdac_ext_link *hlink; - struct hdac_bus *bus = &ebus->bus; link_count = readl(bus->mlcap + AZX_REG_ML_MLCD) + 1; @@ -114,7 +111,7 @@ int snd_hdac_ext_bus_get_ml_capabilities(struct hdac_ext_bus *ebus) /* since link in On, update the ref */ hlink->ref_count = 1; - list_add_tail(&hlink->list, &ebus->hlink_list); + list_add_tail(&hlink->list, &bus->hlink_list); } return 0; @@ -127,12 +124,12 @@ EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_get_ml_capabilities); * @ebus: HD-audio ext core bus */ -void snd_hdac_link_free_all(struct hdac_ext_bus *ebus) +void snd_hdac_link_free_all(struct hdac_bus *bus) { struct hdac_ext_link *l; - while (!list_empty(&ebus->hlink_list)) { - l = list_first_entry(&ebus->hlink_list, struct hdac_ext_link, list); + while (!list_empty(&bus->hlink_list)) { + l = list_first_entry(&bus->hlink_list, struct hdac_ext_link, list); list_del(&l->list); kfree(l); } @@ -144,7 +141,7 @@ EXPORT_SYMBOL_GPL(snd_hdac_link_free_all); * @ebus: HD-audio extended core bus * @codec_name: codec name */ -struct hdac_ext_link *snd_hdac_ext_bus_get_link(struct hdac_ext_bus *ebus, +struct hdac_ext_link *snd_hdac_ext_bus_get_link(struct hdac_bus *bus, const char *codec_name) { int i; @@ -153,10 +150,10 @@ struct hdac_ext_link *snd_hdac_ext_bus_get_link(struct hdac_ext_bus *ebus, if (sscanf(codec_name, "ehdaudio%dD%d", &bus_idx, &addr) != 2) return NULL; - if (ebus->idx != bus_idx) + if (bus->idx != bus_idx) return NULL; - list_for_each_entry(hlink, &ebus->hlink_list, list) { + list_for_each_entry(hlink, &bus->hlink_list, list) { for (i = 0; i < HDA_MAX_CODECS; i++) { if (hlink->lsdiid & (0x1 << addr)) return hlink; @@ -219,12 +216,12 @@ EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_link_power_down); * snd_hdac_ext_bus_link_power_up_all -power up all hda link * @ebus: HD-audio extended bus */ -int snd_hdac_ext_bus_link_power_up_all(struct hdac_ext_bus *ebus) +int snd_hdac_ext_bus_link_power_up_all(struct hdac_bus *bus) { struct hdac_ext_link *hlink = NULL; int ret; - list_for_each_entry(hlink, &ebus->hlink_list, list) { + list_for_each_entry(hlink, &bus->hlink_list, list) { snd_hdac_updatel(hlink->ml_addr, AZX_REG_ML_LCTL, 0, AZX_MLCTL_SPA); ret = check_hdac_link_power_active(hlink, true); @@ -240,12 +237,12 @@ EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_link_power_up_all); * snd_hdac_ext_bus_link_power_down_all -power down all hda link * @ebus: HD-audio extended bus */ -int snd_hdac_ext_bus_link_power_down_all(struct hdac_ext_bus *ebus) +int snd_hdac_ext_bus_link_power_down_all(struct hdac_bus *bus) { struct hdac_ext_link *hlink = NULL; int ret; - list_for_each_entry(hlink, &ebus->hlink_list, list) { + list_for_each_entry(hlink, &bus->hlink_list, list) { snd_hdac_updatel(hlink->ml_addr, AZX_REG_ML_LCTL, AZX_MLCTL_SPA, 0); ret = check_hdac_link_power_active(hlink, false); if (ret < 0) @@ -256,39 +253,39 @@ int snd_hdac_ext_bus_link_power_down_all(struct hdac_ext_bus *ebus) } EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_link_power_down_all); -int snd_hdac_ext_bus_link_get(struct hdac_ext_bus *ebus, +int snd_hdac_ext_bus_link_get(struct hdac_bus *bus, struct hdac_ext_link *link) { int ret = 0; - mutex_lock(&ebus->lock); + mutex_lock(&bus->lock); /* * if we move from 0 to 1, count will be 1 so power up this link * as well, also check the dma status and trigger that */ if (++link->ref_count == 1) { - if (!ebus->cmd_dma_state) { - snd_hdac_bus_init_cmd_io(&ebus->bus); - ebus->cmd_dma_state = true; + if (!bus->cmd_dma_state) { + snd_hdac_bus_init_cmd_io(bus); + bus->cmd_dma_state = true; } ret = snd_hdac_ext_bus_link_power_up(link); } - mutex_unlock(&ebus->lock); + mutex_unlock(&bus->lock); return ret; } EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_link_get); -int snd_hdac_ext_bus_link_put(struct hdac_ext_bus *ebus, +int snd_hdac_ext_bus_link_put(struct hdac_bus *bus, struct hdac_ext_link *link) { int ret = 0; struct hdac_ext_link *hlink; bool link_up = false; - mutex_lock(&ebus->lock); + mutex_lock(&bus->lock); /* * if we move from 1 to 0, count will be 0 @@ -301,7 +298,7 @@ int snd_hdac_ext_bus_link_put(struct hdac_ext_bus *ebus, * now check if all links are off, if so turn off * cmd dma as well */ - list_for_each_entry(hlink, &ebus->hlink_list, list) { + list_for_each_entry(hlink, &bus->hlink_list, list) { if (hlink->ref_count) { link_up = true; break; @@ -309,12 +306,12 @@ int snd_hdac_ext_bus_link_put(struct hdac_ext_bus *ebus, } if (!link_up) { - snd_hdac_bus_stop_cmd_io(&ebus->bus); - ebus->cmd_dma_state = false; + snd_hdac_bus_stop_cmd_io(bus); + bus->cmd_dma_state = false; } } - mutex_unlock(&ebus->lock); + mutex_unlock(&bus->lock); return ret; } EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_link_put); diff --git a/sound/hda/ext/hdac_ext_stream.c b/sound/hda/ext/hdac_ext_stream.c index c96d7a7a36af..1bd27576db98 100644 --- a/sound/hda/ext/hdac_ext_stream.c +++ b/sound/hda/ext/hdac_ext_stream.c @@ -25,7 +25,7 @@ /** * snd_hdac_ext_stream_init - initialize each stream (aka device) - * @ebus: HD-audio ext core bus + * @bus: HD-audio core bus * @stream: HD-audio ext core stream object to initialize * @idx: stream index number * @direction: stream direction (SNDRV_PCM_STREAM_PLAYBACK or SNDRV_PCM_STREAM_CAPTURE) @@ -34,18 +34,16 @@ * initialize the stream, if ppcap is enabled then init those and then * invoke hdac stream initialization routine */ -void snd_hdac_ext_stream_init(struct hdac_ext_bus *ebus, +void snd_hdac_ext_stream_init(struct hdac_bus *bus, struct hdac_ext_stream *stream, int idx, int direction, int tag) { - struct hdac_bus *bus = &ebus->bus; - if (bus->ppcap) { stream->pphc_addr = bus->ppcap + AZX_PPHC_BASE + AZX_PPHC_INTERVAL * idx; stream->pplc_addr = bus->ppcap + AZX_PPLC_BASE + - AZX_PPLC_MULTI * ebus->num_streams + + AZX_PPLC_MULTI * bus->num_streams + AZX_PPLC_INTERVAL * idx; } @@ -71,12 +69,12 @@ EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_init); /** * snd_hdac_ext_stream_init_all - create and initialize the stream objects * for an extended hda bus - * @ebus: HD-audio ext core bus + * @bus: HD-audio core bus * @start_idx: start index for streams * @num_stream: number of streams to initialize * @dir: direction of streams */ -int snd_hdac_ext_stream_init_all(struct hdac_ext_bus *ebus, int start_idx, +int snd_hdac_ext_stream_init_all(struct hdac_bus *bus, int start_idx, int num_stream, int dir) { int stream_tag = 0; @@ -88,7 +86,7 @@ int snd_hdac_ext_stream_init_all(struct hdac_ext_bus *ebus, int start_idx, if (!stream) return -ENOMEM; tag = ++stream_tag; - snd_hdac_ext_stream_init(ebus, stream, idx, dir, tag); + snd_hdac_ext_stream_init(bus, stream, idx, dir, tag); idx++; } @@ -100,17 +98,16 @@ EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_init_all); /** * snd_hdac_stream_free_all - free hdac extended stream objects * - * @ebus: HD-audio ext core bus + * @bus: HD-audio core bus */ -void snd_hdac_stream_free_all(struct hdac_ext_bus *ebus) +void snd_hdac_stream_free_all(struct hdac_bus *bus) { struct hdac_stream *s, *_s; struct hdac_ext_stream *stream; - struct hdac_bus *bus = ebus_to_hbus(ebus); list_for_each_entry_safe(s, _s, &bus->stream_list, list) { stream = stream_to_hdac_ext_stream(s); - snd_hdac_ext_stream_decouple(ebus, stream, false); + snd_hdac_ext_stream_decouple(bus, stream, false); list_del(&s->list); kfree(stream); } @@ -119,15 +116,14 @@ EXPORT_SYMBOL_GPL(snd_hdac_stream_free_all); /** * snd_hdac_ext_stream_decouple - decouple the hdac stream - * @ebus: HD-audio ext core bus + * @bus: HD-audio core bus * @stream: HD-audio ext core stream object to initialize * @decouple: flag to decouple */ -void snd_hdac_ext_stream_decouple(struct hdac_ext_bus *ebus, +void snd_hdac_ext_stream_decouple(struct hdac_bus *bus, struct hdac_ext_stream *stream, bool decouple) { struct hdac_stream *hstream = &stream->hstream; - struct hdac_bus *bus = &ebus->bus; u32 val; int mask = AZX_PPCTL_PROCEN(hstream->index); @@ -251,19 +247,18 @@ void snd_hdac_ext_link_clear_stream_id(struct hdac_ext_link *link, EXPORT_SYMBOL_GPL(snd_hdac_ext_link_clear_stream_id); static struct hdac_ext_stream * -hdac_ext_link_stream_assign(struct hdac_ext_bus *ebus, +hdac_ext_link_stream_assign(struct hdac_bus *bus, struct snd_pcm_substream *substream) { struct hdac_ext_stream *res = NULL; struct hdac_stream *stream = NULL; - struct hdac_bus *hbus = &ebus->bus; - if (!hbus->ppcap) { - dev_err(hbus->dev, "stream type not supported\n"); + if (!bus->ppcap) { + dev_err(bus->dev, "stream type not supported\n"); return NULL; } - list_for_each_entry(stream, &hbus->stream_list, list) { + list_for_each_entry(stream, &bus->stream_list, list) { struct hdac_ext_stream *hstream = container_of(stream, struct hdac_ext_stream, hstream); @@ -277,34 +272,33 @@ hdac_ext_link_stream_assign(struct hdac_ext_bus *ebus, } if (!hstream->link_locked) { - snd_hdac_ext_stream_decouple(ebus, hstream, true); + snd_hdac_ext_stream_decouple(bus, hstream, true); res = hstream; break; } } if (res) { - spin_lock_irq(&hbus->reg_lock); + spin_lock_irq(&bus->reg_lock); res->link_locked = 1; res->link_substream = substream; - spin_unlock_irq(&hbus->reg_lock); + spin_unlock_irq(&bus->reg_lock); } return res; } static struct hdac_ext_stream * -hdac_ext_host_stream_assign(struct hdac_ext_bus *ebus, +hdac_ext_host_stream_assign(struct hdac_bus *bus, struct snd_pcm_substream *substream) { struct hdac_ext_stream *res = NULL; struct hdac_stream *stream = NULL; - struct hdac_bus *hbus = &ebus->bus; - if (!hbus->ppcap) { - dev_err(hbus->dev, "stream type not supported\n"); + if (!bus->ppcap) { + dev_err(bus->dev, "stream type not supported\n"); return NULL; } - list_for_each_entry(stream, &hbus->stream_list, list) { + list_for_each_entry(stream, &bus->stream_list, list) { struct hdac_ext_stream *hstream = container_of(stream, struct hdac_ext_stream, hstream); @@ -313,17 +307,17 @@ hdac_ext_host_stream_assign(struct hdac_ext_bus *ebus, if (!stream->opened) { if (!hstream->decoupled) - snd_hdac_ext_stream_decouple(ebus, hstream, true); + snd_hdac_ext_stream_decouple(bus, hstream, true); res = hstream; break; } } if (res) { - spin_lock_irq(&hbus->reg_lock); + spin_lock_irq(&bus->reg_lock); res->hstream.opened = 1; res->hstream.running = 0; res->hstream.substream = substream; - spin_unlock_irq(&hbus->reg_lock); + spin_unlock_irq(&bus->reg_lock); } return res; @@ -331,7 +325,7 @@ hdac_ext_host_stream_assign(struct hdac_ext_bus *ebus, /** * snd_hdac_ext_stream_assign - assign a stream for the PCM - * @ebus: HD-audio ext core bus + * @bus: HD-audio core bus * @substream: PCM substream to assign * @type: type of stream (coupled, host or link stream) * @@ -346,27 +340,26 @@ hdac_ext_host_stream_assign(struct hdac_ext_bus *ebus, * the same stream object when it's used beforehand. when a stream is * decoupled, it becomes a host stream and link stream. */ -struct hdac_ext_stream *snd_hdac_ext_stream_assign(struct hdac_ext_bus *ebus, +struct hdac_ext_stream *snd_hdac_ext_stream_assign(struct hdac_bus *bus, struct snd_pcm_substream *substream, int type) { struct hdac_ext_stream *hstream = NULL; struct hdac_stream *stream = NULL; - struct hdac_bus *hbus = &ebus->bus; switch (type) { case HDAC_EXT_STREAM_TYPE_COUPLED: - stream = snd_hdac_stream_assign(hbus, substream); + stream = snd_hdac_stream_assign(bus, substream); if (stream) hstream = container_of(stream, struct hdac_ext_stream, hstream); return hstream; case HDAC_EXT_STREAM_TYPE_HOST: - return hdac_ext_host_stream_assign(ebus, substream); + return hdac_ext_host_stream_assign(bus, substream); case HDAC_EXT_STREAM_TYPE_LINK: - return hdac_ext_link_stream_assign(ebus, substream); + return hdac_ext_link_stream_assign(bus, substream); default: return NULL; @@ -384,7 +377,6 @@ EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_assign); void snd_hdac_ext_stream_release(struct hdac_ext_stream *stream, int type) { struct hdac_bus *bus = stream->hstream.bus; - struct hdac_ext_bus *ebus = hbus_to_ebus(bus); switch (type) { case HDAC_EXT_STREAM_TYPE_COUPLED: @@ -393,13 +385,13 @@ void snd_hdac_ext_stream_release(struct hdac_ext_stream *stream, int type) case HDAC_EXT_STREAM_TYPE_HOST: if (stream->decoupled && !stream->link_locked) - snd_hdac_ext_stream_decouple(ebus, stream, false); + snd_hdac_ext_stream_decouple(bus, stream, false); snd_hdac_stream_release(&stream->hstream); break; case HDAC_EXT_STREAM_TYPE_LINK: if (stream->decoupled && !stream->hstream.opened) - snd_hdac_ext_stream_decouple(ebus, stream, false); + snd_hdac_ext_stream_decouple(bus, stream, false); spin_lock_irq(&bus->reg_lock); stream->link_locked = 0; stream->link_substream = NULL; @@ -415,16 +407,15 @@ EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_release); /** * snd_hdac_ext_stream_spbcap_enable - enable SPIB for a stream - * @ebus: HD-audio ext core bus + * @bus: HD-audio core bus * @enable: flag to enable/disable SPIB * @index: stream index for which SPIB need to be enabled */ -void snd_hdac_ext_stream_spbcap_enable(struct hdac_ext_bus *ebus, +void snd_hdac_ext_stream_spbcap_enable(struct hdac_bus *bus, bool enable, int index) { u32 mask = 0; u32 register_mask = 0; - struct hdac_bus *bus = &ebus->bus; if (!bus->spbcap) { dev_err(bus->dev, "Address of SPB capability is NULL\n"); @@ -446,14 +437,13 @@ EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_spbcap_enable); /** * snd_hdac_ext_stream_set_spib - sets the spib value of a stream - * @ebus: HD-audio ext core bus + * @bus: HD-audio core bus * @stream: hdac_ext_stream * @value: spib value to set */ -int snd_hdac_ext_stream_set_spib(struct hdac_ext_bus *ebus, +int snd_hdac_ext_stream_set_spib(struct hdac_bus *bus, struct hdac_ext_stream *stream, u32 value) { - struct hdac_bus *bus = &ebus->bus; if (!bus->spbcap) { dev_err(bus->dev, "Address of SPB capability is NULL\n"); @@ -468,15 +458,14 @@ EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_set_spib); /** * snd_hdac_ext_stream_get_spbmaxfifo - gets the spib value of a stream - * @ebus: HD-audio ext core bus + * @bus: HD-audio core bus * @stream: hdac_ext_stream * * Return maxfifo for the stream */ -int snd_hdac_ext_stream_get_spbmaxfifo(struct hdac_ext_bus *ebus, +int snd_hdac_ext_stream_get_spbmaxfifo(struct hdac_bus *bus, struct hdac_ext_stream *stream) { - struct hdac_bus *bus = &ebus->bus; if (!bus->spbcap) { dev_err(bus->dev, "Address of SPB capability is NULL\n"); @@ -490,11 +479,10 @@ EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_get_spbmaxfifo); /** * snd_hdac_ext_stop_streams - stop all stream if running - * @ebus: HD-audio ext core bus + * @bus: HD-audio core bus */ -void snd_hdac_ext_stop_streams(struct hdac_ext_bus *ebus) +void snd_hdac_ext_stop_streams(struct hdac_bus *bus) { - struct hdac_bus *bus = ebus_to_hbus(ebus); struct hdac_stream *stream; if (bus->chip_init) { @@ -507,16 +495,15 @@ EXPORT_SYMBOL_GPL(snd_hdac_ext_stop_streams); /** * snd_hdac_ext_stream_drsm_enable - enable DMA resume for a stream - * @ebus: HD-audio ext core bus + * @bus: HD-audio core bus * @enable: flag to enable/disable DRSM * @index: stream index for which DRSM need to be enabled */ -void snd_hdac_ext_stream_drsm_enable(struct hdac_ext_bus *ebus, +void snd_hdac_ext_stream_drsm_enable(struct hdac_bus *bus, bool enable, int index) { u32 mask = 0; u32 register_mask = 0; - struct hdac_bus *bus = &ebus->bus; if (!bus->drsmcap) { dev_err(bus->dev, "Address of DRSM capability is NULL\n"); @@ -538,14 +525,13 @@ EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_drsm_enable); /** * snd_hdac_ext_stream_set_dpibr - sets the dpibr value of a stream - * @ebus: HD-audio ext core bus + * @bus: HD-audio core bus * @stream: hdac_ext_stream * @value: dpib value to set */ -int snd_hdac_ext_stream_set_dpibr(struct hdac_ext_bus *ebus, +int snd_hdac_ext_stream_set_dpibr(struct hdac_bus *bus, struct hdac_ext_stream *stream, u32 value) { - struct hdac_bus *bus = &ebus->bus; if (!bus->drsmcap) { dev_err(bus->dev, "Address of DRSM capability is NULL\n"); @@ -560,7 +546,7 @@ EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_set_dpibr); /** * snd_hdac_ext_stream_set_lpib - sets the lpib value of a stream - * @ebus: HD-audio ext core bus + * @bus: HD-audio core bus * @stream: hdac_ext_stream * @value: lpib value to set */ diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c index f1e235817a65..c3ccc8d9c91d 100644 --- a/sound/soc/codecs/hdac_hdmi.c +++ b/sound/soc/codecs/hdac_hdmi.c @@ -1799,14 +1799,13 @@ static int hdmi_codec_probe(struct snd_soc_component *component) * hold the ref while we probe, also no need to drop the ref on * exit, we call pm_runtime_suspend() so that will do for us */ - hlink = snd_hdac_ext_bus_get_link(hbus_to_ebus(hdev->bus), - dev_name(&hdev->dev)); + hlink = snd_hdac_ext_bus_get_link(hdev->bus, dev_name(&hdev->dev)); if (!hlink) { dev_err(&hdev->dev, "hdac link not found\n"); return -EIO; } - snd_hdac_ext_bus_link_get(hbus_to_ebus(hdev->bus), hlink); + snd_hdac_ext_bus_link_get(hdev->bus, hlink); ret = create_fill_widget_route_map(dapm); if (ret < 0) @@ -1984,14 +1983,13 @@ static int hdac_hdmi_dev_probe(struct hdac_device *hdev) const struct hda_device_id *hdac_id = hdac_get_device_id(hdev, hdrv); /* hold the ref while we probe */ - hlink = snd_hdac_ext_bus_get_link(hbus_to_ebus(hdev->bus), - dev_name(&hdev->dev)); + hlink = snd_hdac_ext_bus_get_link(hdev->bus, dev_name(&hdev->dev)); if (!hlink) { dev_err(&hdev->dev, "hdac link not found\n"); return -EIO; } - snd_hdac_ext_bus_link_get(hbus_to_ebus(hdev->bus), hlink); + snd_hdac_ext_bus_link_get(hdev->bus, hlink); hdmi_priv = devm_kzalloc(&hdev->dev, sizeof(*hdmi_priv), GFP_KERNEL); if (hdmi_priv == NULL) @@ -2044,7 +2042,7 @@ static int hdac_hdmi_dev_probe(struct hdac_device *hdev) ret = devm_snd_soc_register_component(&hdev->dev, &hdmi_hda_codec, hdmi_dais, num_dais); - snd_hdac_ext_bus_link_put(hbus_to_ebus(hdev->bus), hlink); + snd_hdac_ext_bus_link_put(hdev->bus, hlink); return ret; } @@ -2093,7 +2091,6 @@ static int hdac_hdmi_runtime_suspend(struct device *dev) { struct hdac_device *hdev = dev_to_hdac_dev(dev); struct hdac_bus *bus = hdev->bus; - struct hdac_ext_bus *ebus = hbus_to_ebus(bus); struct hdac_ext_link *hlink = NULL; int err; @@ -2118,13 +2115,13 @@ static int hdac_hdmi_runtime_suspend(struct device *dev) return err; } - hlink = snd_hdac_ext_bus_get_link(ebus, dev_name(dev)); + hlink = snd_hdac_ext_bus_get_link(bus, dev_name(dev)); if (!hlink) { dev_err(dev, "hdac link not found\n"); return -EIO; } - snd_hdac_ext_bus_link_put(ebus, hlink); + snd_hdac_ext_bus_link_put(bus, hlink); return 0; } @@ -2133,7 +2130,6 @@ static int hdac_hdmi_runtime_resume(struct device *dev) { struct hdac_device *hdev = dev_to_hdac_dev(dev); struct hdac_bus *bus = hdev->bus; - struct hdac_ext_bus *ebus = hbus_to_ebus(bus); struct hdac_ext_link *hlink = NULL; int err; @@ -2143,13 +2139,13 @@ static int hdac_hdmi_runtime_resume(struct device *dev) if (!bus) return 0; - hlink = snd_hdac_ext_bus_get_link(ebus, dev_name(dev)); + hlink = snd_hdac_ext_bus_get_link(bus, dev_name(dev)); if (!hlink) { dev_err(dev, "hdac link not found\n"); return -EIO; } - snd_hdac_ext_bus_link_get(ebus, hlink); + snd_hdac_ext_bus_link_get(bus, hlink); err = snd_hdac_display_power(bus, true); if (err < 0) { diff --git a/sound/soc/intel/skylake/skl-messages.c b/sound/soc/intel/skylake/skl-messages.c index d5f9c30eba32..8bfb8b0fa3d5 100644 --- a/sound/soc/intel/skylake/skl-messages.c +++ b/sound/soc/intel/skylake/skl-messages.c @@ -33,8 +33,7 @@ static int skl_alloc_dma_buf(struct device *dev, struct snd_dma_buffer *dmab, size_t size) { - struct hdac_ext_bus *ebus = dev_get_drvdata(dev); - struct hdac_bus *bus = ebus_to_hbus(ebus); + struct hdac_bus *bus = dev_get_drvdata(dev); if (!bus) return -ENODEV; @@ -44,8 +43,7 @@ static int skl_alloc_dma_buf(struct device *dev, static int skl_free_dma_buf(struct device *dev, struct snd_dma_buffer *dmab) { - struct hdac_ext_bus *ebus = dev_get_drvdata(dev); - struct hdac_bus *bus = ebus_to_hbus(ebus); + struct hdac_bus *bus = dev_get_drvdata(dev); if (!bus) return -ENODEV; @@ -89,8 +87,7 @@ void skl_dsp_enable_notification(struct skl_sst *ctx, bool enable) static int skl_dsp_setup_spib(struct device *dev, unsigned int size, int stream_tag, int enable) { - struct hdac_ext_bus *ebus = dev_get_drvdata(dev); - struct hdac_bus *bus = ebus_to_hbus(ebus); + struct hdac_bus *bus = dev_get_drvdata(dev); struct hdac_stream *stream = snd_hdac_get_stream(bus, SNDRV_PCM_STREAM_PLAYBACK, stream_tag); struct hdac_ext_stream *estream; @@ -100,10 +97,10 @@ static int skl_dsp_setup_spib(struct device *dev, unsigned int size, estream = stream_to_hdac_ext_stream(stream); /* enable/disable SPIB for this hdac stream */ - snd_hdac_ext_stream_spbcap_enable(ebus, enable, stream->index); + snd_hdac_ext_stream_spbcap_enable(bus, enable, stream->index); /* set the spib value */ - snd_hdac_ext_stream_set_spib(ebus, estream, size); + snd_hdac_ext_stream_set_spib(bus, estream, size); return 0; } @@ -111,8 +108,7 @@ static int skl_dsp_setup_spib(struct device *dev, unsigned int size, static int skl_dsp_prepare(struct device *dev, unsigned int format, unsigned int size, struct snd_dma_buffer *dmab) { - struct hdac_ext_bus *ebus = dev_get_drvdata(dev); - struct hdac_bus *bus = ebus_to_hbus(ebus); + struct hdac_bus *bus = dev_get_drvdata(dev); struct hdac_ext_stream *estream; struct hdac_stream *stream; struct snd_pcm_substream substream; @@ -124,7 +120,7 @@ static int skl_dsp_prepare(struct device *dev, unsigned int format, memset(&substream, 0, sizeof(substream)); substream.stream = SNDRV_PCM_STREAM_PLAYBACK; - estream = snd_hdac_ext_stream_assign(ebus, &substream, + estream = snd_hdac_ext_stream_assign(bus, &substream, HDAC_EXT_STREAM_TYPE_HOST); if (!estream) return -ENODEV; @@ -143,9 +139,8 @@ static int skl_dsp_prepare(struct device *dev, unsigned int format, static int skl_dsp_trigger(struct device *dev, bool start, int stream_tag) { - struct hdac_ext_bus *ebus = dev_get_drvdata(dev); + struct hdac_bus *bus = dev_get_drvdata(dev); struct hdac_stream *stream; - struct hdac_bus *bus = ebus_to_hbus(ebus); if (!bus) return -ENODEV; @@ -163,10 +158,9 @@ static int skl_dsp_trigger(struct device *dev, bool start, int stream_tag) static int skl_dsp_cleanup(struct device *dev, struct snd_dma_buffer *dmab, int stream_tag) { - struct hdac_ext_bus *ebus = dev_get_drvdata(dev); + struct hdac_bus *bus = dev_get_drvdata(dev); struct hdac_stream *stream; struct hdac_ext_stream *estream; - struct hdac_bus *bus = ebus_to_hbus(ebus); if (!bus) return -ENODEV; @@ -270,8 +264,7 @@ const struct skl_dsp_ops *skl_get_dsp_ops(int pci_id) int skl_init_dsp(struct skl *skl) { void __iomem *mmio_base; - struct hdac_ext_bus *ebus = &skl->ebus; - struct hdac_bus *bus = ebus_to_hbus(ebus); + struct hdac_bus *bus = skl_to_bus(skl); struct skl_dsp_loader_ops loader_ops; int irq = bus->irq; const struct skl_dsp_ops *ops; @@ -279,8 +272,8 @@ int skl_init_dsp(struct skl *skl) int ret; /* enable ppcap interrupt */ - snd_hdac_ext_bus_ppcap_enable(&skl->ebus, true); - snd_hdac_ext_bus_ppcap_int_enable(&skl->ebus, true); + snd_hdac_ext_bus_ppcap_enable(bus, true); + snd_hdac_ext_bus_ppcap_int_enable(bus, true); /* read the BAR of the ADSP MMIO */ mmio_base = pci_ioremap_bar(skl->pci, 4); @@ -335,12 +328,11 @@ unmap_mmio: int skl_free_dsp(struct skl *skl) { - struct hdac_ext_bus *ebus = &skl->ebus; - struct hdac_bus *bus = ebus_to_hbus(ebus); + struct hdac_bus *bus = skl_to_bus(skl); struct skl_sst *ctx = skl->skl_sst; /* disable ppcap interrupt */ - snd_hdac_ext_bus_ppcap_int_enable(&skl->ebus, false); + snd_hdac_ext_bus_ppcap_int_enable(bus, false); ctx->dsp_ops->cleanup(bus->dev, ctx); @@ -383,10 +375,11 @@ int skl_suspend_late_dsp(struct skl *skl) int skl_suspend_dsp(struct skl *skl) { struct skl_sst *ctx = skl->skl_sst; + struct hdac_bus *bus = skl_to_bus(skl); int ret; /* if ppcap is not supported return 0 */ - if (!skl->ebus.bus.ppcap) + if (!bus->ppcap) return 0; ret = skl_dsp_sleep(ctx->dsp); @@ -394,8 +387,8 @@ int skl_suspend_dsp(struct skl *skl) return ret; /* disable ppcap interrupt */ - snd_hdac_ext_bus_ppcap_int_enable(&skl->ebus, false); - snd_hdac_ext_bus_ppcap_enable(&skl->ebus, false); + snd_hdac_ext_bus_ppcap_int_enable(bus, false); + snd_hdac_ext_bus_ppcap_enable(bus, false); return 0; } @@ -403,15 +396,16 @@ int skl_suspend_dsp(struct skl *skl) int skl_resume_dsp(struct skl *skl) { struct skl_sst *ctx = skl->skl_sst; + struct hdac_bus *bus = skl_to_bus(skl); int ret; /* if ppcap is not supported return 0 */ - if (!skl->ebus.bus.ppcap) + if (!bus->ppcap) return 0; /* enable ppcap interrupt */ - snd_hdac_ext_bus_ppcap_enable(&skl->ebus, true); - snd_hdac_ext_bus_ppcap_int_enable(&skl->ebus, true); + snd_hdac_ext_bus_ppcap_enable(bus, true); + snd_hdac_ext_bus_ppcap_int_enable(bus, true); /* check if DSP 1st boot is done */ if (skl->skl_sst->is_first_boot == true) diff --git a/sound/soc/intel/skylake/skl-nhlt.c b/sound/soc/intel/skylake/skl-nhlt.c index b9b140275be0..01a050cf8775 100644 --- a/sound/soc/intel/skylake/skl-nhlt.c +++ b/sound/soc/intel/skylake/skl-nhlt.c @@ -141,7 +141,7 @@ struct nhlt_specific_cfg { struct nhlt_fmt *fmt; struct nhlt_endpoint *epnt; - struct hdac_bus *bus = ebus_to_hbus(&skl->ebus); + struct hdac_bus *bus = skl_to_bus(skl); struct device *dev = bus->dev; struct nhlt_specific_cfg *sp_config; struct nhlt_acpi_table *nhlt = skl->nhlt; @@ -228,7 +228,7 @@ static void skl_nhlt_trim_space(char *trim) int skl_nhlt_update_topology_bin(struct skl *skl) { struct nhlt_acpi_table *nhlt = (struct nhlt_acpi_table *)skl->nhlt; - struct hdac_bus *bus = ebus_to_hbus(&skl->ebus); + struct hdac_bus *bus = skl_to_bus(skl); struct device *dev = bus->dev; dev_dbg(dev, "oem_id %.6s, oem_table_id %8s oem_revision %d\n", @@ -248,8 +248,8 @@ static ssize_t skl_nhlt_platform_id_show(struct device *dev, struct device_attribute *attr, char *buf) { struct pci_dev *pci = to_pci_dev(dev); - struct hdac_ext_bus *ebus = pci_get_drvdata(pci); - struct skl *skl = ebus_to_skl(ebus); + struct hdac_bus *bus = pci_get_drvdata(pci); + struct skl *skl = bus_to_skl(bus); struct nhlt_acpi_table *nhlt = (struct nhlt_acpi_table *)skl->nhlt; char platform_id[32]; diff --git a/sound/soc/intel/skylake/skl-pcm.c b/sound/soc/intel/skylake/skl-pcm.c index afa86b9e4dcf..d7fc3b2d3e68 100644 --- a/sound/soc/intel/skylake/skl-pcm.c +++ b/sound/soc/intel/skylake/skl-pcm.c @@ -67,16 +67,15 @@ struct hdac_ext_stream *get_hdac_ext_stream(struct snd_pcm_substream *substream) return substream->runtime->private_data; } -static struct hdac_ext_bus *get_bus_ctx(struct snd_pcm_substream *substream) +static struct hdac_bus *get_bus_ctx(struct snd_pcm_substream *substream) { struct hdac_ext_stream *stream = get_hdac_ext_stream(substream); struct hdac_stream *hstream = hdac_stream(stream); struct hdac_bus *bus = hstream->bus; - - return hbus_to_ebus(bus); + return bus; } -static int skl_substream_alloc_pages(struct hdac_ext_bus *ebus, +static int skl_substream_alloc_pages(struct hdac_bus *bus, struct snd_pcm_substream *substream, size_t size) { @@ -95,7 +94,7 @@ static int skl_substream_free_pages(struct hdac_bus *bus, return snd_pcm_lib_free_pages(substream); } -static void skl_set_pcm_constrains(struct hdac_ext_bus *ebus, +static void skl_set_pcm_constrains(struct hdac_bus *bus, struct snd_pcm_runtime *runtime) { snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); @@ -105,9 +104,9 @@ static void skl_set_pcm_constrains(struct hdac_ext_bus *ebus, 20, 178000000); } -static enum hdac_ext_stream_type skl_get_host_stream_type(struct hdac_ext_bus *ebus) +static enum hdac_ext_stream_type skl_get_host_stream_type(struct hdac_bus *bus) { - if ((ebus_to_hbus(ebus))->ppcap) + if (bus->ppcap) return HDAC_EXT_STREAM_TYPE_HOST; else return HDAC_EXT_STREAM_TYPE_COUPLED; @@ -123,9 +122,9 @@ static enum hdac_ext_stream_type skl_get_host_stream_type(struct hdac_ext_bus *e static void skl_set_suspend_active(struct snd_pcm_substream *substream, struct snd_soc_dai *dai, bool enable) { - struct hdac_ext_bus *ebus = dev_get_drvdata(dai->dev); + struct hdac_bus *bus = dev_get_drvdata(dai->dev); struct snd_soc_dapm_widget *w; - struct skl *skl = ebus_to_skl(ebus); + struct skl *skl = bus_to_skl(bus); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) w = dai->playback_widget; @@ -140,8 +139,7 @@ static void skl_set_suspend_active(struct snd_pcm_substream *substream, int skl_pcm_host_dma_prepare(struct device *dev, struct skl_pipe_params *params) { - struct hdac_ext_bus *ebus = dev_get_drvdata(dev); - struct hdac_bus *bus = ebus_to_hbus(ebus); + struct hdac_bus *bus = dev_get_drvdata(dev); unsigned int format_val; struct hdac_stream *hstream; struct hdac_ext_stream *stream; @@ -153,7 +151,7 @@ int skl_pcm_host_dma_prepare(struct device *dev, struct skl_pipe_params *params) return -EINVAL; stream = stream_to_hdac_ext_stream(hstream); - snd_hdac_ext_stream_decouple(ebus, stream, true); + snd_hdac_ext_stream_decouple(bus, stream, true); format_val = snd_hdac_calc_stream_format(params->s_freq, params->ch, params->format, params->host_bps, 0); @@ -177,8 +175,7 @@ int skl_pcm_host_dma_prepare(struct device *dev, struct skl_pipe_params *params) int skl_pcm_link_dma_prepare(struct device *dev, struct skl_pipe_params *params) { - struct hdac_ext_bus *ebus = dev_get_drvdata(dev); - struct hdac_bus *bus = ebus_to_hbus(ebus); + struct hdac_bus *bus = dev_get_drvdata(dev); unsigned int format_val; struct hdac_stream *hstream; struct hdac_ext_stream *stream; @@ -190,7 +187,7 @@ int skl_pcm_link_dma_prepare(struct device *dev, struct skl_pipe_params *params) return -EINVAL; stream = stream_to_hdac_ext_stream(hstream); - snd_hdac_ext_stream_decouple(ebus, stream, true); + snd_hdac_ext_stream_decouple(bus, stream, true); format_val = snd_hdac_calc_stream_format(params->s_freq, params->ch, params->format, params->link_bps, 0); @@ -201,7 +198,7 @@ int skl_pcm_link_dma_prepare(struct device *dev, struct skl_pipe_params *params) snd_hdac_ext_link_stream_setup(stream, format_val); - list_for_each_entry(link, &ebus->hlink_list, list) { + list_for_each_entry(link, &bus->hlink_list, list) { if (link->index == params->link_index) snd_hdac_ext_link_set_stream_id(link, hstream->stream_tag); @@ -215,7 +212,7 @@ int skl_pcm_link_dma_prepare(struct device *dev, struct skl_pipe_params *params) static int skl_pcm_open(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { - struct hdac_ext_bus *ebus = dev_get_drvdata(dai->dev); + struct hdac_bus *bus = dev_get_drvdata(dai->dev); struct hdac_ext_stream *stream; struct snd_pcm_runtime *runtime = substream->runtime; struct skl_dma_params *dma_params; @@ -224,12 +221,12 @@ static int skl_pcm_open(struct snd_pcm_substream *substream, dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name); - stream = snd_hdac_ext_stream_assign(ebus, substream, - skl_get_host_stream_type(ebus)); + stream = snd_hdac_ext_stream_assign(bus, substream, + skl_get_host_stream_type(bus)); if (stream == NULL) return -EBUSY; - skl_set_pcm_constrains(ebus, runtime); + skl_set_pcm_constrains(bus, runtime); /* * disable WALLCLOCK timestamps for capture streams @@ -301,7 +298,7 @@ static int skl_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) { - struct hdac_ext_bus *ebus = dev_get_drvdata(dai->dev); + struct hdac_bus *bus = dev_get_drvdata(dai->dev); struct hdac_ext_stream *stream = get_hdac_ext_stream(substream); struct snd_pcm_runtime *runtime = substream->runtime; struct skl_pipe_params p_params = {0}; @@ -309,7 +306,7 @@ static int skl_pcm_hw_params(struct snd_pcm_substream *substream, int ret, dma_id; dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name); - ret = skl_substream_alloc_pages(ebus, substream, + ret = skl_substream_alloc_pages(bus, substream, params_buffer_bytes(params)); if (ret < 0) return ret; @@ -343,14 +340,14 @@ static void skl_pcm_close(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct hdac_ext_stream *stream = get_hdac_ext_stream(substream); - struct hdac_ext_bus *ebus = dev_get_drvdata(dai->dev); + struct hdac_bus *bus = dev_get_drvdata(dai->dev); struct skl_dma_params *dma_params = NULL; - struct skl *skl = ebus_to_skl(ebus); + struct skl *skl = bus_to_skl(bus); struct skl_module_cfg *mconfig; dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name); - snd_hdac_ext_stream_release(stream, skl_get_host_stream_type(ebus)); + snd_hdac_ext_stream_release(stream, skl_get_host_stream_type(bus)); dma_params = snd_soc_dai_get_dma_data(dai, substream); /* @@ -380,7 +377,7 @@ static void skl_pcm_close(struct snd_pcm_substream *substream, static int skl_pcm_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { - struct hdac_ext_bus *ebus = dev_get_drvdata(dai->dev); + struct hdac_bus *bus = dev_get_drvdata(dai->dev); struct hdac_ext_stream *stream = get_hdac_ext_stream(substream); struct skl *skl = get_skl_ctx(dai->dev); struct skl_module_cfg *mconfig; @@ -400,7 +397,7 @@ static int skl_pcm_hw_free(struct snd_pcm_substream *substream, snd_hdac_stream_cleanup(hdac_stream(stream)); hdac_stream(stream)->prepared = 0; - return skl_substream_free_pages(ebus_to_hbus(ebus), substream); + return skl_substream_free_pages(bus, substream); } static int skl_be_hw_params(struct snd_pcm_substream *substream, @@ -420,8 +417,7 @@ static int skl_be_hw_params(struct snd_pcm_substream *substream, static int skl_decoupled_trigger(struct snd_pcm_substream *substream, int cmd) { - struct hdac_ext_bus *ebus = get_bus_ctx(substream); - struct hdac_bus *bus = ebus_to_hbus(ebus); + struct hdac_bus *bus = get_bus_ctx(substream); struct hdac_ext_stream *stream; int start; unsigned long cookie; @@ -470,7 +466,7 @@ static int skl_pcm_trigger(struct snd_pcm_substream *substream, int cmd, struct skl *skl = get_skl_ctx(dai->dev); struct skl_sst *ctx = skl->skl_sst; struct skl_module_cfg *mconfig; - struct hdac_ext_bus *ebus = get_bus_ctx(substream); + struct hdac_bus *bus = get_bus_ctx(substream); struct hdac_ext_stream *stream = get_hdac_ext_stream(substream); struct snd_soc_dapm_widget *w; int ret; @@ -492,9 +488,9 @@ static int skl_pcm_trigger(struct snd_pcm_substream *substream, int cmd, * dpib & lpib position to resume before starting the * DMA */ - snd_hdac_ext_stream_drsm_enable(ebus, true, + snd_hdac_ext_stream_drsm_enable(bus, true, hdac_stream(stream)->index); - snd_hdac_ext_stream_set_dpibr(ebus, stream, + snd_hdac_ext_stream_set_dpibr(bus, stream, stream->lpib); snd_hdac_ext_stream_set_lpib(stream, stream->lpib); } @@ -528,14 +524,14 @@ static int skl_pcm_trigger(struct snd_pcm_substream *substream, int cmd, ret = skl_decoupled_trigger(substream, cmd); if ((cmd == SNDRV_PCM_TRIGGER_SUSPEND) && !w->ignore_suspend) { /* save the dpib and lpib positions */ - stream->dpib = readl(ebus->bus.remap_addr + + stream->dpib = readl(bus->remap_addr + AZX_REG_VS_SDXDPIB_XBASE + (AZX_REG_VS_SDXDPIB_XINTERVAL * hdac_stream(stream)->index)); stream->lpib = snd_hdac_stream_get_pos_lpib( hdac_stream(stream)); - snd_hdac_ext_stream_decouple(ebus, stream, false); + snd_hdac_ext_stream_decouple(bus, stream, false); } break; @@ -546,11 +542,12 @@ static int skl_pcm_trigger(struct snd_pcm_substream *substream, int cmd, return 0; } + static int skl_link_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) { - struct hdac_ext_bus *ebus = dev_get_drvdata(dai->dev); + struct hdac_bus *bus = dev_get_drvdata(dai->dev); struct hdac_ext_stream *link_dev; struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream); struct snd_soc_dai *codec_dai = rtd->codec_dai; @@ -558,14 +555,14 @@ static int skl_link_hw_params(struct snd_pcm_substream *substream, struct hdac_ext_link *link; int stream_tag; - link_dev = snd_hdac_ext_stream_assign(ebus, substream, + link_dev = snd_hdac_ext_stream_assign(bus, substream, HDAC_EXT_STREAM_TYPE_LINK); if (!link_dev) return -EBUSY; snd_soc_dai_set_dma_data(dai, substream, (void *)link_dev); - link = snd_hdac_ext_bus_get_link(ebus, codec_dai->component->name); + link = snd_hdac_ext_bus_get_link(bus, codec_dai->component->name); if (!link) return -EINVAL; @@ -610,7 +607,7 @@ static int skl_link_pcm_trigger(struct snd_pcm_substream *substream, { struct hdac_ext_stream *link_dev = snd_soc_dai_get_dma_data(dai, substream); - struct hdac_ext_bus *ebus = get_bus_ctx(substream); + struct hdac_bus *bus = get_bus_ctx(substream); struct hdac_ext_stream *stream = get_hdac_ext_stream(substream); dev_dbg(dai->dev, "In %s cmd=%d\n", __func__, cmd); @@ -626,7 +623,7 @@ static int skl_link_pcm_trigger(struct snd_pcm_substream *substream, case SNDRV_PCM_TRIGGER_STOP: snd_hdac_ext_link_stream_clear(link_dev); if (cmd == SNDRV_PCM_TRIGGER_SUSPEND) - snd_hdac_ext_stream_decouple(ebus, stream, false); + snd_hdac_ext_stream_decouple(bus, stream, false); break; default: @@ -638,7 +635,7 @@ static int skl_link_pcm_trigger(struct snd_pcm_substream *substream, static int skl_link_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { - struct hdac_ext_bus *ebus = dev_get_drvdata(dai->dev); + struct hdac_bus *bus = dev_get_drvdata(dai->dev); struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream); struct hdac_ext_stream *link_dev = snd_soc_dai_get_dma_data(dai, substream); @@ -648,7 +645,7 @@ static int skl_link_hw_free(struct snd_pcm_substream *substream, link_dev->link_prepared = 0; - link = snd_hdac_ext_bus_get_link(ebus, rtd->codec_dai->component->name); + link = snd_hdac_ext_bus_get_link(bus, rtd->codec_dai->component->name); if (!link) return -EINVAL; @@ -1041,8 +1038,7 @@ static int skl_platform_open(struct snd_pcm_substream *substream) static int skl_coupled_trigger(struct snd_pcm_substream *substream, int cmd) { - struct hdac_ext_bus *ebus = get_bus_ctx(substream); - struct hdac_bus *bus = ebus_to_hbus(ebus); + struct hdac_bus *bus = get_bus_ctx(substream); struct hdac_ext_stream *stream; struct snd_pcm_substream *s; bool start; @@ -1115,9 +1111,9 @@ static int skl_coupled_trigger(struct snd_pcm_substream *substream, static int skl_platform_pcm_trigger(struct snd_pcm_substream *substream, int cmd) { - struct hdac_ext_bus *ebus = get_bus_ctx(substream); + struct hdac_bus *bus = get_bus_ctx(substream); - if (!(ebus_to_hbus(ebus))->ppcap) + if (!bus->ppcap) return skl_coupled_trigger(substream, cmd); return 0; @@ -1127,7 +1123,7 @@ static snd_pcm_uframes_t skl_platform_pcm_pointer (struct snd_pcm_substream *substream) { struct hdac_ext_stream *hstream = get_hdac_ext_stream(substream); - struct hdac_ext_bus *ebus = get_bus_ctx(substream); + struct hdac_bus *bus = get_bus_ctx(substream); unsigned int pos; /* @@ -1152,12 +1148,12 @@ static snd_pcm_uframes_t skl_platform_pcm_pointer */ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - pos = readl(ebus->bus.remap_addr + AZX_REG_VS_SDXDPIB_XBASE + + pos = readl(bus->remap_addr + AZX_REG_VS_SDXDPIB_XBASE + (AZX_REG_VS_SDXDPIB_XINTERVAL * hdac_stream(hstream)->index)); } else { udelay(20); - readl(ebus->bus.remap_addr + + readl(bus->remap_addr + AZX_REG_VS_SDXDPIB_XBASE + (AZX_REG_VS_SDXDPIB_XINTERVAL * hdac_stream(hstream)->index)); @@ -1242,11 +1238,11 @@ static void skl_pcm_free(struct snd_pcm *pcm) static int skl_pcm_new(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_dai *dai = rtd->cpu_dai; - struct hdac_ext_bus *ebus = dev_get_drvdata(dai->dev); + struct hdac_bus *bus = dev_get_drvdata(dai->dev); struct snd_pcm *pcm = rtd->pcm; unsigned int size; int retval = 0; - struct skl *skl = ebus_to_skl(ebus); + struct skl *skl = bus_to_skl(bus); if (dai->driver->playback.channels_min || dai->driver->capture.channels_min) { @@ -1356,19 +1352,19 @@ static int skl_populate_modules(struct skl *skl) static int skl_platform_soc_probe(struct snd_soc_component *component) { - struct hdac_ext_bus *ebus = dev_get_drvdata(component->dev); - struct skl *skl = ebus_to_skl(ebus); + struct hdac_bus *bus = dev_get_drvdata(component->dev); + struct skl *skl = bus_to_skl(bus); const struct skl_dsp_ops *ops; int ret; pm_runtime_get_sync(component->dev); - if ((ebus_to_hbus(ebus))->ppcap) { + if (bus->ppcap) { skl->component = component; /* init debugfs */ skl->debugfs = skl_debugfs_init(skl); - ret = skl_tplg_init(component, ebus); + ret = skl_tplg_init(component, bus); if (ret < 0) { dev_err(component->dev, "Failed to init topology!\n"); return ret; @@ -1425,10 +1421,10 @@ static const struct snd_soc_component_driver skl_component = { int skl_platform_register(struct device *dev) { int ret; - struct hdac_ext_bus *ebus = dev_get_drvdata(dev); - struct skl *skl = ebus_to_skl(ebus); struct snd_soc_dai_driver *dais; int num_dais = ARRAY_SIZE(skl_platform_dai); + struct hdac_bus *bus = dev_get_drvdata(dev); + struct skl *skl = bus_to_skl(bus); INIT_LIST_HEAD(&skl->ppl_list); INIT_LIST_HEAD(&skl->bind_list); @@ -1464,8 +1460,8 @@ err: int skl_platform_unregister(struct device *dev) { - struct hdac_ext_bus *ebus = dev_get_drvdata(dev); - struct skl *skl = ebus_to_skl(ebus); + struct hdac_bus *bus = dev_get_drvdata(dev); + struct skl *skl = bus_to_skl(bus); struct skl_module_deferred_bind *modules, *tmp; if (!list_empty(&skl->bind_list)) { diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c index fcdc716754b6..abfdb67c05cc 100644 --- a/sound/soc/intel/skylake/skl-topology.c +++ b/sound/soc/intel/skylake/skl-topology.c @@ -934,7 +934,7 @@ static int skl_tplg_find_moduleid_from_uuid(struct skl *skl, struct soc_bytes_ext *sb = (void *) k->private_value; struct skl_algo_data *bc = (struct skl_algo_data *)sb->dobj.private; struct skl_kpb_params *uuid_params, *params; - struct hdac_bus *bus = ebus_to_hbus(skl_to_ebus(skl)); + struct hdac_bus *bus = skl_to_bus(skl); int i, size, module_id; if (bc->set_params == SKL_PARAM_BIND && bc->max) { @@ -3029,9 +3029,8 @@ static int skl_tplg_widget_load(struct snd_soc_component *cmpnt, struct snd_soc_tplg_dapm_widget *tplg_w) { int ret; - struct hdac_ext_bus *ebus = snd_soc_component_get_drvdata(cmpnt); - struct skl *skl = ebus_to_skl(ebus); - struct hdac_bus *bus = ebus_to_hbus(ebus); + struct hdac_bus *bus = snd_soc_component_get_drvdata(cmpnt); + struct skl *skl = bus_to_skl(bus); struct skl_module_cfg *mconfig; if (!tplg_w->priv.size) @@ -3137,8 +3136,7 @@ static int skl_tplg_control_load(struct snd_soc_component *cmpnt, struct soc_bytes_ext *sb; struct snd_soc_tplg_bytes_control *tplg_bc; struct snd_soc_tplg_enum_control *tplg_ec; - struct hdac_ext_bus *ebus = snd_soc_component_get_drvdata(cmpnt); - struct hdac_bus *bus = ebus_to_hbus(ebus); + struct hdac_bus *bus = snd_soc_component_get_drvdata(cmpnt); struct soc_enum *se; switch (hdr->ops.info) { @@ -3622,9 +3620,8 @@ static int skl_tplg_get_manifest_data(struct snd_soc_tplg_manifest *manifest, static int skl_manifest_load(struct snd_soc_component *cmpnt, struct snd_soc_tplg_manifest *manifest) { - struct hdac_ext_bus *ebus = snd_soc_component_get_drvdata(cmpnt); - struct hdac_bus *bus = ebus_to_hbus(ebus); - struct skl *skl = ebus_to_skl(ebus); + struct hdac_bus *bus = snd_soc_component_get_drvdata(cmpnt); + struct skl *skl = bus_to_skl(bus); /* proceed only if we have private data defined */ if (manifest->priv.size == 0) @@ -3713,12 +3710,11 @@ static void skl_tplg_set_pipe_type(struct skl *skl, struct skl_pipe *pipe) /* * SKL topology init routine */ -int skl_tplg_init(struct snd_soc_component *component, struct hdac_ext_bus *ebus) +int skl_tplg_init(struct snd_soc_component *component, struct hdac_bus *bus) { int ret; const struct firmware *fw; - struct hdac_bus *bus = ebus_to_hbus(ebus); - struct skl *skl = ebus_to_skl(ebus); + struct skl *skl = bus_to_skl(bus); struct skl_pipeline *ppl; ret = request_firmware(&fw, skl->tplg_name, bus->dev); diff --git a/sound/soc/intel/skylake/skl-topology.h b/sound/soc/intel/skylake/skl-topology.h index 6d7e0569695f..daeb6d2bb7fc 100644 --- a/sound/soc/intel/skylake/skl-topology.h +++ b/sound/soc/intel/skylake/skl-topology.h @@ -458,9 +458,9 @@ enum skl_channel { static inline struct skl *get_skl_ctx(struct device *dev) { - struct hdac_ext_bus *ebus = dev_get_drvdata(dev); + struct hdac_bus *bus = dev_get_drvdata(dev); - return ebus_to_skl(ebus); + return bus_to_skl(bus); } int skl_tplg_be_update_params(struct snd_soc_dai *dai, @@ -470,7 +470,7 @@ int skl_dsp_set_dma_control(struct skl_sst *ctx, u32 *caps, void skl_tplg_set_be_dmic_config(struct snd_soc_dai *dai, struct skl_pipe_params *params, int stream); int skl_tplg_init(struct snd_soc_component *component, - struct hdac_ext_bus *ebus); + struct hdac_bus *ebus); struct skl_module_cfg *skl_tplg_fe_get_cpr_module( struct snd_soc_dai *dai, int stream); int skl_tplg_update_pipe_params(struct device *dev, diff --git a/sound/soc/intel/skylake/skl.c b/sound/soc/intel/skylake/skl.c index f0d9793f872a..9c5a701d68ac 100644 --- a/sound/soc/intel/skylake/skl.c +++ b/sound/soc/intel/skylake/skl.c @@ -54,7 +54,7 @@ static void skl_update_pci_byte(struct pci_dev *pci, unsigned int reg, static void skl_init_pci(struct skl *skl) { - struct hdac_ext_bus *ebus = &skl->ebus; + struct hdac_bus *bus = skl_to_bus(skl); /* * Clear bits 0-2 of PCI register TCSEL (at offset 0x44) @@ -63,7 +63,7 @@ static void skl_init_pci(struct skl *skl) * codecs. * The PCI register TCSEL is defined in the Intel manuals. */ - dev_dbg(ebus_to_hbus(ebus)->dev, "Clearing TCSEL\n"); + dev_dbg(bus->dev, "Clearing TCSEL\n"); skl_update_pci_byte(skl->pci, AZX_PCIREG_TCSEL, 0x07, 0); } @@ -103,8 +103,7 @@ static void skl_enable_miscbdcge(struct device *dev, bool enable) static void skl_clock_power_gating(struct device *dev, bool enable) { struct pci_dev *pci = to_pci_dev(dev); - struct hdac_ext_bus *ebus = pci_get_drvdata(pci); - struct hdac_bus *bus = ebus_to_hbus(ebus); + struct hdac_bus *bus = pci_get_drvdata(pci); u32 val; /* Update PDCGE bit of CGCTL register */ @@ -127,7 +126,6 @@ static void skl_clock_power_gating(struct device *dev, bool enable) */ static int skl_init_chip(struct hdac_bus *bus, bool full_reset) { - struct hdac_ext_bus *ebus = hbus_to_ebus(bus); struct hdac_ext_link *hlink; int ret; @@ -135,7 +133,7 @@ static int skl_init_chip(struct hdac_bus *bus, bool full_reset) ret = snd_hdac_bus_init_chip(bus, full_reset); /* Reset stream-to-link mapping */ - list_for_each_entry(hlink, &ebus->hlink_list, list) + list_for_each_entry(hlink, &bus->hlink_list, list) bus->io_ops->reg_writel(0, hlink->ml_addr + AZX_REG_ML_LOSIDV); skl_enable_miscbdcge(bus->dev, true); @@ -146,8 +144,7 @@ static int skl_init_chip(struct hdac_bus *bus, bool full_reset) void skl_update_d0i3c(struct device *dev, bool enable) { struct pci_dev *pci = to_pci_dev(dev); - struct hdac_ext_bus *ebus = pci_get_drvdata(pci); - struct hdac_bus *bus = ebus_to_hbus(ebus); + struct hdac_bus *bus = pci_get_drvdata(pci); u8 reg; int timeout = 50; @@ -197,8 +194,7 @@ static void skl_stream_update(struct hdac_bus *bus, struct hdac_stream *hstr) static irqreturn_t skl_interrupt(int irq, void *dev_id) { - struct hdac_ext_bus *ebus = dev_id; - struct hdac_bus *bus = ebus_to_hbus(ebus); + struct hdac_bus *bus = dev_id; u32 status; if (!pm_runtime_active(bus->dev)) @@ -227,8 +223,7 @@ static irqreturn_t skl_interrupt(int irq, void *dev_id) static irqreturn_t skl_threaded_handler(int irq, void *dev_id) { - struct hdac_ext_bus *ebus = dev_id; - struct hdac_bus *bus = ebus_to_hbus(ebus); + struct hdac_bus *bus = dev_id; u32 status; status = snd_hdac_chip_readl(bus, INTSTS); @@ -238,16 +233,15 @@ static irqreturn_t skl_threaded_handler(int irq, void *dev_id) return IRQ_HANDLED; } -static int skl_acquire_irq(struct hdac_ext_bus *ebus, int do_disconnect) +static int skl_acquire_irq(struct hdac_bus *bus, int do_disconnect) { - struct skl *skl = ebus_to_skl(ebus); - struct hdac_bus *bus = ebus_to_hbus(ebus); + struct skl *skl = bus_to_skl(bus); int ret; ret = request_threaded_irq(skl->pci->irq, skl_interrupt, skl_threaded_handler, IRQF_SHARED, - KBUILD_MODNAME, ebus); + KBUILD_MODNAME, bus); if (ret) { dev_err(bus->dev, "unable to grab IRQ %d, disabling device\n", @@ -264,21 +258,20 @@ static int skl_acquire_irq(struct hdac_ext_bus *ebus, int do_disconnect) static int skl_suspend_late(struct device *dev) { struct pci_dev *pci = to_pci_dev(dev); - struct hdac_ext_bus *ebus = pci_get_drvdata(pci); - struct skl *skl = ebus_to_skl(ebus); + struct hdac_bus *bus = pci_get_drvdata(pci); + struct skl *skl = bus_to_skl(bus); return skl_suspend_late_dsp(skl); } #ifdef CONFIG_PM -static int _skl_suspend(struct hdac_ext_bus *ebus) +static int _skl_suspend(struct hdac_bus *bus) { - struct skl *skl = ebus_to_skl(ebus); - struct hdac_bus *bus = ebus_to_hbus(ebus); + struct skl *skl = bus_to_skl(bus); struct pci_dev *pci = to_pci_dev(bus->dev); int ret; - snd_hdac_ext_bus_link_power_down_all(ebus); + snd_hdac_ext_bus_link_power_down_all(bus); ret = skl_suspend_dsp(skl); if (ret < 0) @@ -295,10 +288,9 @@ static int _skl_suspend(struct hdac_ext_bus *ebus) return 0; } -static int _skl_resume(struct hdac_ext_bus *ebus) +static int _skl_resume(struct hdac_bus *bus) { - struct skl *skl = ebus_to_skl(ebus); - struct hdac_bus *bus = ebus_to_hbus(ebus); + struct skl *skl = bus_to_skl(bus); skl_init_pci(skl); skl_init_chip(bus, true); @@ -314,9 +306,8 @@ static int _skl_resume(struct hdac_ext_bus *ebus) static int skl_suspend(struct device *dev) { struct pci_dev *pci = to_pci_dev(dev); - struct hdac_ext_bus *ebus = pci_get_drvdata(pci); - struct skl *skl = ebus_to_skl(ebus); - struct hdac_bus *bus = ebus_to_hbus(ebus); + struct hdac_bus *bus = pci_get_drvdata(pci); + struct skl *skl = bus_to_skl(bus); int ret = 0; /* @@ -325,15 +316,15 @@ static int skl_suspend(struct device *dev) */ if (skl->supend_active) { /* turn off the links and stop the CORB/RIRB DMA if it is On */ - snd_hdac_ext_bus_link_power_down_all(ebus); + snd_hdac_ext_bus_link_power_down_all(bus); - if (ebus->cmd_dma_state) - snd_hdac_bus_stop_cmd_io(&ebus->bus); + if (bus->cmd_dma_state) + snd_hdac_bus_stop_cmd_io(bus); enable_irq_wake(bus->irq); pci_save_state(pci); } else { - ret = _skl_suspend(ebus); + ret = _skl_suspend(bus); if (ret < 0) return ret; skl->skl_sst->fw_loaded = false; @@ -352,9 +343,8 @@ static int skl_suspend(struct device *dev) static int skl_resume(struct device *dev) { struct pci_dev *pci = to_pci_dev(dev); - struct hdac_ext_bus *ebus = pci_get_drvdata(pci); - struct skl *skl = ebus_to_skl(ebus); - struct hdac_bus *bus = ebus_to_hbus(ebus); + struct hdac_bus *bus = pci_get_drvdata(pci); + struct skl *skl = bus_to_skl(bus); struct hdac_ext_link *hlink = NULL; int ret; @@ -374,32 +364,32 @@ static int skl_resume(struct device *dev) */ if (skl->supend_active) { pci_restore_state(pci); - snd_hdac_ext_bus_link_power_up_all(ebus); + snd_hdac_ext_bus_link_power_up_all(bus); disable_irq_wake(bus->irq); /* * turn On the links which are On before active suspend * and start the CORB/RIRB DMA if On before * active suspend. */ - list_for_each_entry(hlink, &ebus->hlink_list, list) { + list_for_each_entry(hlink, &bus->hlink_list, list) { if (hlink->ref_count) snd_hdac_ext_bus_link_power_up(hlink); } - if (ebus->cmd_dma_state) - snd_hdac_bus_init_cmd_io(&ebus->bus); ret = 0; + if (bus->cmd_dma_state) + snd_hdac_bus_init_cmd_io(bus); } else { - ret = _skl_resume(ebus); + ret = _skl_resume(bus); /* turn off the links which are off before suspend */ - list_for_each_entry(hlink, &ebus->hlink_list, list) { + list_for_each_entry(hlink, &bus->hlink_list, list) { if (!hlink->ref_count) snd_hdac_ext_bus_link_power_down(hlink); } - if (!ebus->cmd_dma_state) - snd_hdac_bus_stop_cmd_io(&ebus->bus); + if (!bus->cmd_dma_state) + snd_hdac_bus_stop_cmd_io(bus); } return ret; @@ -410,23 +400,21 @@ static int skl_resume(struct device *dev) static int skl_runtime_suspend(struct device *dev) { struct pci_dev *pci = to_pci_dev(dev); - struct hdac_ext_bus *ebus = pci_get_drvdata(pci); - struct hdac_bus *bus = ebus_to_hbus(ebus); + struct hdac_bus *bus = pci_get_drvdata(pci); dev_dbg(bus->dev, "in %s\n", __func__); - return _skl_suspend(ebus); + return _skl_suspend(bus); } static int skl_runtime_resume(struct device *dev) { struct pci_dev *pci = to_pci_dev(dev); - struct hdac_ext_bus *ebus = pci_get_drvdata(pci); - struct hdac_bus *bus = ebus_to_hbus(ebus); + struct hdac_bus *bus = pci_get_drvdata(pci); dev_dbg(bus->dev, "in %s\n", __func__); - return _skl_resume(ebus); + return _skl_resume(bus); } #endif /* CONFIG_PM */ @@ -439,20 +427,19 @@ static const struct dev_pm_ops skl_pm = { /* * destructor */ -static int skl_free(struct hdac_ext_bus *ebus) +static int skl_free(struct hdac_bus *bus) { - struct skl *skl = ebus_to_skl(ebus); - struct hdac_bus *bus = ebus_to_hbus(ebus); + struct skl *skl = bus_to_skl(bus); skl->init_done = 0; /* to be sure */ - snd_hdac_ext_stop_streams(ebus); + snd_hdac_ext_stop_streams(bus); if (bus->irq >= 0) - free_irq(bus->irq, (void *)ebus); + free_irq(bus->irq, (void *)bus); snd_hdac_bus_free_stream_pages(bus); - snd_hdac_stream_free_all(ebus); - snd_hdac_link_free_all(ebus); + snd_hdac_stream_free_all(bus); + snd_hdac_link_free_all(bus); if (bus->remap_addr) iounmap(bus->remap_addr); @@ -460,11 +447,11 @@ static int skl_free(struct hdac_ext_bus *ebus) pci_release_regions(skl->pci); pci_disable_device(skl->pci); - snd_hdac_ext_bus_exit(ebus); + snd_hdac_ext_bus_exit(bus); cancel_work_sync(&skl->probe_work); if (IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI)) - snd_hdac_i915_exit(&ebus->bus); + snd_hdac_i915_exit(bus); return 0; } @@ -488,8 +475,8 @@ static struct skl_ssp_clk skl_ssp_clks[] = { static int skl_find_machine(struct skl *skl, void *driver_data) { + struct hdac_bus *bus = skl_to_bus(skl); struct snd_soc_acpi_mach *mach = driver_data; - struct hdac_bus *bus = ebus_to_hbus(&skl->ebus); struct skl_machine_pdata *pdata; mach = snd_soc_acpi_find_machine(mach); @@ -510,7 +497,7 @@ static int skl_find_machine(struct skl *skl, void *driver_data) static int skl_machine_device_register(struct skl *skl) { - struct hdac_bus *bus = ebus_to_hbus(&skl->ebus); + struct hdac_bus *bus = skl_to_bus(skl); struct snd_soc_acpi_mach *mach = skl->mach; struct platform_device *pdev; int ret; @@ -544,7 +531,7 @@ static void skl_machine_device_unregister(struct skl *skl) static int skl_dmic_device_register(struct skl *skl) { - struct hdac_bus *bus = ebus_to_hbus(&skl->ebus); + struct hdac_bus *bus = skl_to_bus(skl); struct platform_device *pdev; int ret; @@ -643,9 +630,8 @@ static void skl_clock_device_unregister(struct skl *skl) /* * Probe the given codec address */ -static int probe_codec(struct hdac_ext_bus *ebus, int addr) +static int probe_codec(struct hdac_bus *bus, int addr) { - struct hdac_bus *bus = ebus_to_hbus(ebus); unsigned int cmd = (addr << 28) | (AC_NODE_ROOT << 20) | (AC_VERB_PARAMETERS << 8) | AC_PAR_VENDOR_ID; unsigned int res = -1; @@ -658,13 +644,12 @@ static int probe_codec(struct hdac_ext_bus *ebus, int addr) return -EIO; dev_dbg(bus->dev, "codec #%d probed OK\n", addr); - return snd_hdac_ext_bus_device_init(ebus, addr); + return snd_hdac_ext_bus_device_init(bus, addr); } /* Codec initialization */ -static void skl_codec_create(struct hdac_ext_bus *ebus) +static void skl_codec_create(struct hdac_bus *bus) { - struct hdac_bus *bus = ebus_to_hbus(ebus); int c, max_slots; max_slots = HDA_MAX_CODECS; @@ -672,7 +657,7 @@ static void skl_codec_create(struct hdac_ext_bus *ebus) /* First try to probe all given codec slots */ for (c = 0; c < max_slots; c++) { if ((bus->codec_mask & (1 << c))) { - if (probe_codec(ebus, c) < 0) { + if (probe_codec(bus, c) < 0) { /* * Some BIOSen give you wrong codec addresses * that don't exist @@ -722,8 +707,7 @@ static int skl_i915_init(struct hdac_bus *bus) static void skl_probe_work(struct work_struct *work) { struct skl *skl = container_of(work, struct skl, probe_work); - struct hdac_ext_bus *ebus = &skl->ebus; - struct hdac_bus *bus = ebus_to_hbus(ebus); + struct hdac_bus *bus = skl_to_bus(skl); struct hdac_ext_link *hlink = NULL; int err; @@ -744,7 +728,7 @@ static void skl_probe_work(struct work_struct *work) dev_info(bus->dev, "no hda codecs found!\n"); /* create codec instances */ - skl_codec_create(ebus); + skl_codec_create(bus); /* register platform dai and controls */ err = skl_platform_register(bus->dev); @@ -773,8 +757,8 @@ static void skl_probe_work(struct work_struct *work) /* * we are done probing so decrement link counts */ - list_for_each_entry(hlink, &ebus->hlink_list, list) - snd_hdac_ext_bus_link_put(ebus, hlink); + list_for_each_entry(hlink, &bus->hlink_list, list) + snd_hdac_ext_bus_link_put(bus, hlink); /* configure PM */ pm_runtime_put_noidle(bus->dev); @@ -796,7 +780,7 @@ static int skl_create(struct pci_dev *pci, struct skl **rskl) { struct skl *skl; - struct hdac_ext_bus *ebus; + struct hdac_bus *bus; int err; @@ -811,23 +795,22 @@ static int skl_create(struct pci_dev *pci, pci_disable_device(pci); return -ENOMEM; } - ebus = &skl->ebus; - snd_hdac_ext_bus_init(ebus, &pci->dev, &bus_core_ops, io_ops); - ebus->bus.use_posbuf = 1; + + bus = skl_to_bus(skl); + snd_hdac_ext_bus_init(bus, &pci->dev, &bus_core_ops, io_ops); + bus->use_posbuf = 1; skl->pci = pci; INIT_WORK(&skl->probe_work, skl_probe_work); - - ebus->bus.bdl_pos_adj = 0; + bus->bdl_pos_adj = 0; *rskl = skl; return 0; } -static int skl_first_init(struct hdac_ext_bus *ebus) +static int skl_first_init(struct hdac_bus *bus) { - struct skl *skl = ebus_to_skl(ebus); - struct hdac_bus *bus = ebus_to_hbus(ebus); + struct skl *skl = bus_to_skl(bus); struct pci_dev *pci = skl->pci; int err; unsigned short gcap; @@ -848,7 +831,7 @@ static int skl_first_init(struct hdac_ext_bus *ebus) snd_hdac_bus_parse_capabilities(bus); - if (skl_acquire_irq(ebus, 0) < 0) + if (skl_acquire_irq(bus, 0) < 0) return -EBUSY; pci_set_master(pci); @@ -872,14 +855,14 @@ static int skl_first_init(struct hdac_ext_bus *ebus) if (!pb_streams && !cp_streams) return -EIO; - ebus->num_streams = cp_streams + pb_streams; + bus->num_streams = cp_streams + pb_streams; /* initialize streams */ snd_hdac_ext_stream_init_all - (ebus, 0, cp_streams, SNDRV_PCM_STREAM_CAPTURE); + (bus, 0, cp_streams, SNDRV_PCM_STREAM_CAPTURE); start_idx = cp_streams; snd_hdac_ext_stream_init_all - (ebus, start_idx, pb_streams, SNDRV_PCM_STREAM_PLAYBACK); + (bus, start_idx, pb_streams, SNDRV_PCM_STREAM_PLAYBACK); err = snd_hdac_bus_alloc_stream_pages(bus); if (err < 0) @@ -895,7 +878,6 @@ static int skl_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) { struct skl *skl; - struct hdac_ext_bus *ebus = NULL; struct hdac_bus *bus = NULL; int err; @@ -904,10 +886,9 @@ static int skl_probe(struct pci_dev *pci, if (err < 0) return err; - ebus = &skl->ebus; - bus = ebus_to_hbus(ebus); + bus = skl_to_bus(skl); - err = skl_first_init(ebus); + err = skl_first_init(bus); if (err < 0) goto out_free; @@ -928,7 +909,7 @@ static int skl_probe(struct pci_dev *pci, skl_nhlt_update_topology_bin(skl); - pci_set_drvdata(skl->pci, ebus); + pci_set_drvdata(skl->pci, bus); skl_dmic_data.dmic_num = skl_get_dmic_geo(skl); @@ -952,7 +933,7 @@ static int skl_probe(struct pci_dev *pci, skl->skl_sst->clock_power_gating = skl_clock_power_gating; } if (bus->mlcap) - snd_hdac_ext_bus_get_ml_capabilities(ebus); + snd_hdac_ext_bus_get_ml_capabilities(bus); snd_hdac_bus_stop_chip(bus); @@ -972,31 +953,30 @@ out_clk_free: out_nhlt_free: skl_nhlt_free(skl->nhlt); out_free: - skl_free(ebus); + skl_free(bus); return err; } static void skl_shutdown(struct pci_dev *pci) { - struct hdac_ext_bus *ebus = pci_get_drvdata(pci); - struct hdac_bus *bus = ebus_to_hbus(ebus); + struct hdac_bus *bus = pci_get_drvdata(pci); struct hdac_stream *s; struct hdac_ext_stream *stream; struct skl *skl; - if (ebus == NULL) + if (!bus) return; - skl = ebus_to_skl(ebus); + skl = bus_to_skl(bus); if (!skl->init_done) return; - snd_hdac_ext_stop_streams(ebus); + snd_hdac_ext_stop_streams(bus); list_for_each_entry(s, &bus->stream_list, list) { stream = stream_to_hdac_ext_stream(s); - snd_hdac_ext_stream_decouple(ebus, stream, false); + snd_hdac_ext_stream_decouple(bus, stream, false); } snd_hdac_bus_stop_chip(bus); @@ -1004,15 +984,15 @@ static void skl_shutdown(struct pci_dev *pci) static void skl_remove(struct pci_dev *pci) { - struct hdac_ext_bus *ebus = pci_get_drvdata(pci); - struct skl *skl = ebus_to_skl(ebus); + struct hdac_bus *bus = pci_get_drvdata(pci); + struct skl *skl = bus_to_skl(bus); release_firmware(skl->tplg); pm_runtime_get_noresume(&pci->dev); /* codec removal, invoke bus_device_remove */ - snd_hdac_ext_bus_device_remove(ebus); + snd_hdac_ext_bus_device_remove(bus); skl->debugfs = NULL; skl_platform_unregister(&pci->dev); @@ -1022,7 +1002,7 @@ static void skl_remove(struct pci_dev *pci) skl_clock_device_unregister(skl); skl_nhlt_remove_sysfs(skl); skl_nhlt_free(skl->nhlt); - skl_free(ebus); + skl_free(bus); dev_set_drvdata(&pci->dev, NULL); } diff --git a/sound/soc/intel/skylake/skl.h b/sound/soc/intel/skylake/skl.h index 0d5375cbcf6e..78aa8bdcb619 100644 --- a/sound/soc/intel/skylake/skl.h +++ b/sound/soc/intel/skylake/skl.h @@ -71,7 +71,7 @@ struct skl_fw_config { }; struct skl { - struct hdac_ext_bus ebus; + struct hdac_bus hbus; struct pci_dev *pci; unsigned int init_done:1; /* delayed init status */ @@ -105,9 +105,8 @@ struct skl { struct snd_soc_acpi_mach *mach; }; -#define skl_to_ebus(s) (&(s)->ebus) -#define ebus_to_skl(sbus) \ - container_of(sbus, struct skl, sbus) +#define skl_to_bus(s) (&(s)->hbus) +#define bus_to_skl(bus) container_of(bus, struct skl, hbus) /* to pass dai dma data */ struct skl_dma_params { -- cgit v1.2.3-58-ga151 From e1df9317cbb192582ed7aa88c5f294c2336a3c75 Mon Sep 17 00:00:00 2001 From: Rakesh Ughreja Date: Fri, 1 Jun 2018 22:53:51 -0500 Subject: ALSA: hdac: Remove usage of struct hdac_ext_driver, use hdac_driver instead This patch removes the hdac_ext_driver structure. The legacy and enhanced HDaudio capabilities can be handled in a backward-compatible way without separate definitions. Signed-off-by: Rakesh Ughreja Signed-off-by: Takashi Iwai --- include/sound/hdaudio.h | 5 +++++ include/sound/hdaudio_ext.h | 17 ++--------------- sound/hda/ext/hdac_ext_bus.c | 30 ++++++++++++++---------------- sound/soc/codecs/hdac_hdmi.c | 12 +++++------- 4 files changed, 26 insertions(+), 38 deletions(-) (limited to 'include') diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h index 9735b51aef08..59ffe63cf194 100644 --- a/include/sound/hdaudio.h +++ b/include/sound/hdaudio.h @@ -188,6 +188,11 @@ struct hdac_driver { const struct hda_device_id *id_table; int (*match)(struct hdac_device *dev, struct hdac_driver *drv); void (*unsol_event)(struct hdac_device *dev, unsigned int event); + + /* fields used by ext bus APIs */ + int (*probe)(struct hdac_device *dev); + int (*remove)(struct hdac_device *dev); + void (*shutdown)(struct hdac_device *dev); }; #define drv_to_hdac_driver(_drv) container_of(_drv, struct hdac_driver, driver) diff --git a/include/sound/hdaudio_ext.h b/include/sound/hdaudio_ext.h index e5b0cd1ade19..3c302477750b 100644 --- a/include/sound/hdaudio_ext.h +++ b/include/sound/hdaudio_ext.h @@ -160,20 +160,7 @@ struct hdac_ext_dma_params { u8 stream_tag; }; -/* - * HD-audio codec base driver - */ -struct hdac_ext_driver { - struct hdac_driver hdac; - - int (*probe)(struct hdac_device *dev); - int (*remove)(struct hdac_device *dev); - void (*shutdown)(struct hdac_device *dev); -}; - -int snd_hda_ext_driver_register(struct hdac_ext_driver *drv); -void snd_hda_ext_driver_unregister(struct hdac_ext_driver *drv); - -#define to_ehdac_driver(_drv) container_of(_drv, struct hdac_ext_driver, hdac) +int snd_hda_ext_driver_register(struct hdac_driver *drv); +void snd_hda_ext_driver_unregister(struct hdac_driver *drv); #endif /* __SOUND_HDAUDIO_EXT_H */ diff --git a/sound/hda/ext/hdac_ext_bus.c b/sound/hda/ext/hdac_ext_bus.c index 77547ede9ae8..52f07766fff3 100644 --- a/sound/hda/ext/hdac_ext_bus.c +++ b/sound/hda/ext/hdac_ext_bus.c @@ -200,12 +200,10 @@ EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_device_remove); #define dev_to_hdac(dev) (container_of((dev), \ struct hdac_device, dev)) -static inline struct hdac_ext_driver *get_edrv(struct device *dev) +static inline struct hdac_driver *get_hdrv(struct device *dev) { struct hdac_driver *hdrv = drv_to_hdac_driver(dev->driver); - struct hdac_ext_driver *edrv = to_ehdac_driver(hdrv); - - return edrv; + return hdrv; } static inline struct hdac_device *get_hdev(struct device *dev) @@ -216,17 +214,17 @@ static inline struct hdac_device *get_hdev(struct device *dev) static int hda_ext_drv_probe(struct device *dev) { - return (get_edrv(dev))->probe(get_hdev(dev)); + return (get_hdrv(dev))->probe(get_hdev(dev)); } static int hdac_ext_drv_remove(struct device *dev) { - return (get_edrv(dev))->remove(get_hdev(dev)); + return (get_hdrv(dev))->remove(get_hdev(dev)); } static void hdac_ext_drv_shutdown(struct device *dev) { - return (get_edrv(dev))->shutdown(get_hdev(dev)); + return (get_hdrv(dev))->shutdown(get_hdev(dev)); } /** @@ -234,20 +232,20 @@ static void hdac_ext_drv_shutdown(struct device *dev) * * @drv: ext hda driver structure */ -int snd_hda_ext_driver_register(struct hdac_ext_driver *drv) +int snd_hda_ext_driver_register(struct hdac_driver *drv) { - drv->hdac.type = HDA_DEV_ASOC; - drv->hdac.driver.bus = &snd_hda_bus_type; + drv->type = HDA_DEV_ASOC; + drv->driver.bus = &snd_hda_bus_type; /* we use default match */ if (drv->probe) - drv->hdac.driver.probe = hda_ext_drv_probe; + drv->driver.probe = hda_ext_drv_probe; if (drv->remove) - drv->hdac.driver.remove = hdac_ext_drv_remove; + drv->driver.remove = hdac_ext_drv_remove; if (drv->shutdown) - drv->hdac.driver.shutdown = hdac_ext_drv_shutdown; + drv->driver.shutdown = hdac_ext_drv_shutdown; - return driver_register(&drv->hdac.driver); + return driver_register(&drv->driver); } EXPORT_SYMBOL_GPL(snd_hda_ext_driver_register); @@ -256,8 +254,8 @@ EXPORT_SYMBOL_GPL(snd_hda_ext_driver_register); * * @drv: ext hda driver structure */ -void snd_hda_ext_driver_unregister(struct hdac_ext_driver *drv) +void snd_hda_ext_driver_unregister(struct hdac_driver *drv) { - driver_unregister(&drv->hdac.driver); + driver_unregister(&drv->driver); } EXPORT_SYMBOL_GPL(snd_hda_ext_driver_unregister); diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c index c3ccc8d9c91d..3e3a2a9ef310 100644 --- a/sound/soc/codecs/hdac_hdmi.c +++ b/sound/soc/codecs/hdac_hdmi.c @@ -2186,14 +2186,12 @@ static const struct hda_device_id hdmi_list[] = { MODULE_DEVICE_TABLE(hdaudio, hdmi_list); -static struct hdac_ext_driver hdmi_driver = { - . hdac = { - .driver = { - .name = "HDMI HDA Codec", - .pm = &hdac_hdmi_pm, - }, - .id_table = hdmi_list, +static struct hdac_driver hdmi_driver = { + .driver = { + .name = "HDMI HDA Codec", + .pm = &hdac_hdmi_pm, }, + .id_table = hdmi_list, .probe = hdac_hdmi_dev_probe, .remove = hdac_hdmi_dev_remove, }; -- cgit v1.2.3-58-ga151 From 6298542fa33b6ba0e3effbace5b99b70b93ed9ae Mon Sep 17 00:00:00 2001 From: Rakesh Ughreja Date: Fri, 1 Jun 2018 22:53:57 -0500 Subject: ALSA: hdac: remove memory allocation from snd_hdac_ext_bus_device_init Remove memory allocation within snd_hdac_ext_bus_device_init, to make its behaviour identical to snd_hdac_bus_device_init. So that caller can allocate the parent data structure containing hdac_device. This API change helps in reusing the legacy HDA codec drivers with ASoC platform drivers. Signed-off-by: Rakesh Ughreja Signed-off-by: Pierre-Louis Bossart Signed-off-by: Takashi Iwai --- include/sound/hdaudio_ext.h | 3 ++- sound/hda/ext/hdac_ext_bus.c | 8 ++------ sound/soc/intel/skylake/skl.c | 8 +++++++- 3 files changed, 11 insertions(+), 8 deletions(-) (limited to 'include') diff --git a/include/sound/hdaudio_ext.h b/include/sound/hdaudio_ext.h index 3c302477750b..c188b801239f 100644 --- a/include/sound/hdaudio_ext.h +++ b/include/sound/hdaudio_ext.h @@ -9,7 +9,8 @@ int snd_hdac_ext_bus_init(struct hdac_bus *bus, struct device *dev, const struct hdac_io_ops *io_ops); void snd_hdac_ext_bus_exit(struct hdac_bus *bus); -int snd_hdac_ext_bus_device_init(struct hdac_bus *bus, int addr); +int snd_hdac_ext_bus_device_init(struct hdac_bus *bus, int addr, + struct hdac_device *hdev); void snd_hdac_ext_bus_device_exit(struct hdac_device *hdev); void snd_hdac_ext_bus_device_remove(struct hdac_bus *bus); diff --git a/sound/hda/ext/hdac_ext_bus.c b/sound/hda/ext/hdac_ext_bus.c index 52f07766fff3..1eb58244688e 100644 --- a/sound/hda/ext/hdac_ext_bus.c +++ b/sound/hda/ext/hdac_ext_bus.c @@ -135,16 +135,12 @@ static void default_release(struct device *dev) * * Returns zero for success or a negative error code. */ -int snd_hdac_ext_bus_device_init(struct hdac_bus *bus, int addr) +int snd_hdac_ext_bus_device_init(struct hdac_bus *bus, int addr, + struct hdac_device *hdev) { - struct hdac_device *hdev = NULL; char name[15]; int ret; - hdev = kzalloc(sizeof(*hdev), GFP_KERNEL); - if (!hdev) - return -ENOMEM; - hdev->bus = bus; snprintf(name, sizeof(name), "ehdaudio%dD%d", bus->idx, addr); diff --git a/sound/soc/intel/skylake/skl.c b/sound/soc/intel/skylake/skl.c index 9c5a701d68ac..3a7f5eb4902b 100644 --- a/sound/soc/intel/skylake/skl.c +++ b/sound/soc/intel/skylake/skl.c @@ -635,6 +635,8 @@ static int probe_codec(struct hdac_bus *bus, int addr) unsigned int cmd = (addr << 28) | (AC_NODE_ROOT << 20) | (AC_VERB_PARAMETERS << 8) | AC_PAR_VENDOR_ID; unsigned int res = -1; + struct skl *skl = bus_to_skl(bus); + struct hdac_device *hdev; mutex_lock(&bus->cmd_mutex); snd_hdac_bus_send_cmd(bus, cmd); @@ -644,7 +646,11 @@ static int probe_codec(struct hdac_bus *bus, int addr) return -EIO; dev_dbg(bus->dev, "codec #%d probed OK\n", addr); - return snd_hdac_ext_bus_device_init(bus, addr); + hdev = devm_kzalloc(&skl->pci->dev, sizeof(*hdev), GFP_KERNEL); + if (!hdev) + return -ENOMEM; + + return snd_hdac_ext_bus_device_init(bus, addr, hdev); } /* Codec initialization */ -- cgit v1.2.3-58-ga151 From cb04ba33187ca571142b67c2fb60d0a8c24994c8 Mon Sep 17 00:00:00 2001 From: Rakesh Ughreja Date: Fri, 1 Jun 2018 22:53:58 -0500 Subject: ALSA: hdac: add extended ops in the hdac_bus Add extended ops in the hdac_bus to allow calling the ASoC HDAC library ops to reuse the legacy HDA codec drivers with ASoC framework. Extended ops are used by the legacy codec drivers to call into hdac_hda library, in the subsequent patches.. Signed-off-by: Rakesh Ughreja Signed-off-by: Pierre-Louis Bossart Signed-off-by: Takashi Iwai --- include/sound/hdaudio.h | 9 +++++++++ include/sound/hdaudio_ext.h | 3 ++- sound/hda/ext/hdac_ext_bus.c | 4 +++- sound/soc/intel/skylake/skl.c | 2 +- 4 files changed, 15 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h index 59ffe63cf194..f1baaa88e766 100644 --- a/include/sound/hdaudio.h +++ b/include/sound/hdaudio.h @@ -213,6 +213,14 @@ struct hdac_bus_ops { int (*link_power)(struct hdac_bus *bus, bool enable); }; +/* + * ops used for ASoC HDA codec drivers + */ +struct hdac_ext_bus_ops { + int (*hdev_attach)(struct hdac_device *hdev); + int (*hdev_detach)(struct hdac_device *hdev); +}; + /* * Lowlevel I/O operators */ @@ -265,6 +273,7 @@ struct hdac_bus { struct device *dev; const struct hdac_bus_ops *ops; const struct hdac_io_ops *io_ops; + const struct hdac_ext_bus_ops *ext_ops; /* h/w resources */ unsigned long addr; diff --git a/include/sound/hdaudio_ext.h b/include/sound/hdaudio_ext.h index c188b801239f..f34aced69ca8 100644 --- a/include/sound/hdaudio_ext.h +++ b/include/sound/hdaudio_ext.h @@ -6,7 +6,8 @@ int snd_hdac_ext_bus_init(struct hdac_bus *bus, struct device *dev, const struct hdac_bus_ops *ops, - const struct hdac_io_ops *io_ops); + const struct hdac_io_ops *io_ops, + const struct hdac_ext_bus_ops *ext_ops); void snd_hdac_ext_bus_exit(struct hdac_bus *bus); int snd_hdac_ext_bus_device_init(struct hdac_bus *bus, int addr, diff --git a/sound/hda/ext/hdac_ext_bus.c b/sound/hda/ext/hdac_ext_bus.c index 1eb58244688e..9c37d9af3023 100644 --- a/sound/hda/ext/hdac_ext_bus.c +++ b/sound/hda/ext/hdac_ext_bus.c @@ -89,7 +89,8 @@ static const struct hdac_io_ops hdac_ext_default_io = { */ int snd_hdac_ext_bus_init(struct hdac_bus *bus, struct device *dev, const struct hdac_bus_ops *ops, - const struct hdac_io_ops *io_ops) + const struct hdac_io_ops *io_ops, + const struct hdac_ext_bus_ops *ext_ops) { int ret; static int idx; @@ -102,6 +103,7 @@ int snd_hdac_ext_bus_init(struct hdac_bus *bus, struct device *dev, if (ret < 0) return ret; + bus->ext_ops = ext_ops; INIT_LIST_HEAD(&bus->hlink_list); bus->idx = idx++; diff --git a/sound/soc/intel/skylake/skl.c b/sound/soc/intel/skylake/skl.c index 3a7f5eb4902b..00e051467a40 100644 --- a/sound/soc/intel/skylake/skl.c +++ b/sound/soc/intel/skylake/skl.c @@ -803,7 +803,7 @@ static int skl_create(struct pci_dev *pci, } bus = skl_to_bus(skl); - snd_hdac_ext_bus_init(bus, &pci->dev, &bus_core_ops, io_ops); + snd_hdac_ext_bus_init(bus, &pci->dev, &bus_core_ops, io_ops, NULL); bus->use_posbuf = 1; skl->pci = pci; INIT_WORK(&skl->probe_work, skl_probe_work); -- cgit v1.2.3-58-ga151 From ae891abe7c2ccf75b69ca8330225e37ecc06924e Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 11 Jul 2018 15:17:22 +0200 Subject: drm/i915: Split audio component to a generic type For allowing other drivers to use the DRM audio component, rename the i915_audio_component_* with drm_audio_component_*, and split the generic part into drm_audio_component.h. The i915 specific stuff remains in struct i915_audio_component, which contains drm_audio_component as the base. The license of drm_audio_component.h is kept to MIT as same as the the original i915_component.h. This is a preliminary change for further development, and no functional changes by this patch itself, merely code-split and renames. v1->v2: Use SPDX for drm_audio_component.h, fix remaining i915 argument in drm_audio_component.h Reviewed-by: Rodrigo Vivi Signed-off-by: Takashi Iwai --- drivers/gpu/drm/i915/intel_audio.c | 22 +++++---- include/drm/drm_audio_component.h | 95 ++++++++++++++++++++++++++++++++++++++ include/drm/i915_component.h | 85 ++-------------------------------- include/sound/hda_i915.h | 6 +-- include/sound/hdaudio.h | 6 +-- sound/hda/hdac_i915.c | 40 ++++++++-------- sound/pci/hda/patch_hdmi.c | 8 ++-- sound/soc/codecs/hdac_hdmi.c | 2 +- 8 files changed, 144 insertions(+), 120 deletions(-) create mode 100644 include/drm/drm_audio_component.h (limited to 'include') diff --git a/drivers/gpu/drm/i915/intel_audio.c b/drivers/gpu/drm/i915/intel_audio.c index 3ea566f99450..7dd5605d94ae 100644 --- a/drivers/gpu/drm/i915/intel_audio.c +++ b/drivers/gpu/drm/i915/intel_audio.c @@ -639,11 +639,12 @@ void intel_audio_codec_enable(struct intel_encoder *encoder, dev_priv->av_enc_map[pipe] = encoder; mutex_unlock(&dev_priv->av_mutex); - if (acomp && acomp->audio_ops && acomp->audio_ops->pin_eld_notify) { + if (acomp && acomp->base.audio_ops && + acomp->base.audio_ops->pin_eld_notify) { /* audio drivers expect pipe = -1 to indicate Non-MST cases */ if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST)) pipe = -1; - acomp->audio_ops->pin_eld_notify(acomp->audio_ops->audio_ptr, + acomp->base.audio_ops->pin_eld_notify(acomp->base.audio_ops->audio_ptr, (int) port, (int) pipe); } @@ -681,11 +682,12 @@ void intel_audio_codec_disable(struct intel_encoder *encoder, dev_priv->av_enc_map[pipe] = NULL; mutex_unlock(&dev_priv->av_mutex); - if (acomp && acomp->audio_ops && acomp->audio_ops->pin_eld_notify) { + if (acomp && acomp->base.audio_ops && + acomp->base.audio_ops->pin_eld_notify) { /* audio drivers expect pipe = -1 to indicate Non-MST cases */ if (!intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_DP_MST)) pipe = -1; - acomp->audio_ops->pin_eld_notify(acomp->audio_ops->audio_ptr, + acomp->base.audio_ops->pin_eld_notify(acomp->base.audio_ops->audio_ptr, (int) port, (int) pipe); } @@ -880,7 +882,7 @@ static int i915_audio_component_get_eld(struct device *kdev, int port, return ret; } -static const struct i915_audio_component_ops i915_audio_component_ops = { +static const struct drm_audio_component_ops i915_audio_component_ops = { .owner = THIS_MODULE, .get_power = i915_audio_component_get_power, .put_power = i915_audio_component_put_power, @@ -897,12 +899,12 @@ static int i915_audio_component_bind(struct device *i915_kdev, struct drm_i915_private *dev_priv = kdev_to_i915(i915_kdev); int i; - if (WARN_ON(acomp->ops || acomp->dev)) + if (WARN_ON(acomp->base.ops || acomp->base.dev)) return -EEXIST; drm_modeset_lock_all(&dev_priv->drm); - acomp->ops = &i915_audio_component_ops; - acomp->dev = i915_kdev; + acomp->base.ops = &i915_audio_component_ops; + acomp->base.dev = i915_kdev; BUILD_BUG_ON(MAX_PORTS != I915_MAX_PORTS); for (i = 0; i < ARRAY_SIZE(acomp->aud_sample_rate); i++) acomp->aud_sample_rate[i] = 0; @@ -919,8 +921,8 @@ static void i915_audio_component_unbind(struct device *i915_kdev, struct drm_i915_private *dev_priv = kdev_to_i915(i915_kdev); drm_modeset_lock_all(&dev_priv->drm); - acomp->ops = NULL; - acomp->dev = NULL; + acomp->base.ops = NULL; + acomp->base.dev = NULL; dev_priv->audio_component = NULL; drm_modeset_unlock_all(&dev_priv->drm); } diff --git a/include/drm/drm_audio_component.h b/include/drm/drm_audio_component.h new file mode 100644 index 000000000000..e85689f212c2 --- /dev/null +++ b/include/drm/drm_audio_component.h @@ -0,0 +1,95 @@ +// SPDX-License-Identifier: MIT +// Copyright © 2014 Intel Corporation + +#ifndef _DRM_AUDIO_COMPONENT_H_ +#define _DRM_AUDIO_COMPONENT_H_ + +/** + * struct drm_audio_component_ops - Ops implemented by DRM driver, called by hda driver + */ +struct drm_audio_component_ops { + /** + * @owner: drm module to pin down + */ + struct module *owner; + /** + * @get_power: get the POWER_DOMAIN_AUDIO power well + * + * Request the power well to be turned on. + */ + void (*get_power)(struct device *); + /** + * @put_power: put the POWER_DOMAIN_AUDIO power well + * + * Allow the power well to be turned off. + */ + void (*put_power)(struct device *); + /** + * @codec_wake_override: Enable/disable codec wake signal + */ + void (*codec_wake_override)(struct device *, bool enable); + /** + * @get_cdclk_freq: Get the Core Display Clock in kHz + */ + int (*get_cdclk_freq)(struct device *); + /** + * @sync_audio_rate: set n/cts based on the sample rate + * + * Called from audio driver. After audio driver sets the + * sample rate, it will call this function to set n/cts + */ + int (*sync_audio_rate)(struct device *, int port, int pipe, int rate); + /** + * @get_eld: fill the audio state and ELD bytes for the given port + * + * Called from audio driver to get the HDMI/DP audio state of the given + * digital port, and also fetch ELD bytes to the given pointer. + * + * It returns the byte size of the original ELD (not the actually + * copied size), zero for an invalid ELD, or a negative error code. + * + * Note that the returned size may be over @max_bytes. Then it + * implies that only a part of ELD has been copied to the buffer. + */ + int (*get_eld)(struct device *, int port, int pipe, bool *enabled, + unsigned char *buf, int max_bytes); +}; + +/** + * struct drm_audio_component_audio_ops - Ops implemented by hda driver, called by DRM driver + */ +struct drm_audio_component_audio_ops { + /** + * @audio_ptr: Pointer to be used in call to pin_eld_notify + */ + void *audio_ptr; + /** + * @pin_eld_notify: Notify the HDA driver that pin sense and/or ELD information has changed + * + * Called when the DRM driver has set up audio pipeline or has just + * begun to tear it down. This allows the HDA driver to update its + * status accordingly (even when the HDA controller is in power save + * mode). + */ + void (*pin_eld_notify)(void *audio_ptr, int port, int pipe); +}; + +/** + * struct drm_audio_component - Used for direct communication between DRM and hda drivers + */ +struct drm_audio_component { + /** + * @dev: DRM device, used as parameter for ops + */ + struct device *dev; + /** + * @ops: Ops implemented by DRM driver, called by hda driver + */ + const struct drm_audio_component_ops *ops; + /** + * @audio_ops: Ops implemented by hda driver, called by DRM driver + */ + const struct drm_audio_component_audio_ops *audio_ops; +}; + +#endif /* _DRM_AUDIO_COMPONENT_H_ */ diff --git a/include/drm/i915_component.h b/include/drm/i915_component.h index 346b1f5cb180..fca22d463e1b 100644 --- a/include/drm/i915_component.h +++ b/include/drm/i915_component.h @@ -24,101 +24,26 @@ #ifndef _I915_COMPONENT_H_ #define _I915_COMPONENT_H_ +#include "drm_audio_component.h" + /* MAX_PORT is the number of port * It must be sync with I915_MAX_PORTS defined i915_drv.h */ #define MAX_PORTS 6 -/** - * struct i915_audio_component_ops - Ops implemented by i915 driver, called by hda driver - */ -struct i915_audio_component_ops { - /** - * @owner: i915 module - */ - struct module *owner; - /** - * @get_power: get the POWER_DOMAIN_AUDIO power well - * - * Request the power well to be turned on. - */ - void (*get_power)(struct device *); - /** - * @put_power: put the POWER_DOMAIN_AUDIO power well - * - * Allow the power well to be turned off. - */ - void (*put_power)(struct device *); - /** - * @codec_wake_override: Enable/disable codec wake signal - */ - void (*codec_wake_override)(struct device *, bool enable); - /** - * @get_cdclk_freq: Get the Core Display Clock in kHz - */ - int (*get_cdclk_freq)(struct device *); - /** - * @sync_audio_rate: set n/cts based on the sample rate - * - * Called from audio driver. After audio driver sets the - * sample rate, it will call this function to set n/cts - */ - int (*sync_audio_rate)(struct device *, int port, int pipe, int rate); - /** - * @get_eld: fill the audio state and ELD bytes for the given port - * - * Called from audio driver to get the HDMI/DP audio state of the given - * digital port, and also fetch ELD bytes to the given pointer. - * - * It returns the byte size of the original ELD (not the actually - * copied size), zero for an invalid ELD, or a negative error code. - * - * Note that the returned size may be over @max_bytes. Then it - * implies that only a part of ELD has been copied to the buffer. - */ - int (*get_eld)(struct device *, int port, int pipe, bool *enabled, - unsigned char *buf, int max_bytes); -}; - -/** - * struct i915_audio_component_audio_ops - Ops implemented by hda driver, called by i915 driver - */ -struct i915_audio_component_audio_ops { - /** - * @audio_ptr: Pointer to be used in call to pin_eld_notify - */ - void *audio_ptr; - /** - * @pin_eld_notify: Notify the HDA driver that pin sense and/or ELD information has changed - * - * Called when the i915 driver has set up audio pipeline or has just - * begun to tear it down. This allows the HDA driver to update its - * status accordingly (even when the HDA controller is in power save - * mode). - */ - void (*pin_eld_notify)(void *audio_ptr, int port, int pipe); -}; - /** * struct i915_audio_component - Used for direct communication between i915 and hda drivers */ struct i915_audio_component { /** - * @dev: i915 device, used as parameter for ops + * @base: the drm_audio_component base class */ - struct device *dev; + struct drm_audio_component base; + /** * @aud_sample_rate: the array of audio sample rate per port */ int aud_sample_rate[MAX_PORTS]; - /** - * @ops: Ops implemented by i915 driver, called by hda driver - */ - const struct i915_audio_component_ops *ops; - /** - * @audio_ops: Ops implemented by hda driver, called by i915 driver - */ - const struct i915_audio_component_audio_ops *audio_ops; }; #endif /* _I915_COMPONENT_H_ */ diff --git a/include/sound/hda_i915.h b/include/sound/hda_i915.h index a94f5b6f92ac..f69ea84e7b65 100644 --- a/include/sound/hda_i915.h +++ b/include/sound/hda_i915.h @@ -5,7 +5,7 @@ #ifndef __SOUND_HDA_I915_H #define __SOUND_HDA_I915_H -#include +#include #ifdef CONFIG_SND_HDA_I915 int snd_hdac_set_codec_wakeup(struct hdac_bus *bus, bool enable); @@ -17,7 +17,7 @@ int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid, int dev_id, bool *audio_enabled, char *buffer, int max_bytes); int snd_hdac_i915_init(struct hdac_bus *bus); int snd_hdac_i915_exit(struct hdac_bus *bus); -int snd_hdac_i915_register_notifier(const struct i915_audio_component_audio_ops *); +int snd_hdac_i915_register_notifier(const struct drm_audio_component_audio_ops *); #else static inline int snd_hdac_set_codec_wakeup(struct hdac_bus *bus, bool enable) { @@ -49,7 +49,7 @@ static inline int snd_hdac_i915_exit(struct hdac_bus *bus) { return 0; } -static inline int snd_hdac_i915_register_notifier(const struct i915_audio_component_audio_ops *ops) +static inline int snd_hdac_i915_register_notifier(const struct drm_audio_component_audio_ops *ops) { return -ENODEV; } diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h index f1baaa88e766..ab5ee3ef2198 100644 --- a/include/sound/hdaudio.h +++ b/include/sound/hdaudio.h @@ -333,9 +333,9 @@ struct hdac_bus { spinlock_t reg_lock; struct mutex cmd_mutex; - /* i915 component interface */ - struct i915_audio_component *audio_component; - int i915_power_refcount; + /* DRM component interface */ + struct drm_audio_component *audio_component; + int drm_power_refcount; /* parameters required for enhanced capabilities */ int num_streams; diff --git a/sound/hda/hdac_i915.c b/sound/hda/hdac_i915.c index cbe818eda336..1a88c1aaf9bb 100644 --- a/sound/hda/hdac_i915.c +++ b/sound/hda/hdac_i915.c @@ -16,13 +16,13 @@ #include #include #include -#include +#include #include #include #include #include -static struct i915_audio_component *hdac_acomp; +static struct drm_audio_component *hdac_acomp; /** * snd_hdac_set_codec_wakeup - Enable / disable HDMI/DP codec wakeup @@ -39,7 +39,7 @@ static struct i915_audio_component *hdac_acomp; */ int snd_hdac_set_codec_wakeup(struct hdac_bus *bus, bool enable) { - struct i915_audio_component *acomp = bus->audio_component; + struct drm_audio_component *acomp = bus->audio_component; if (!acomp || !acomp->ops) return -ENODEV; @@ -74,7 +74,7 @@ EXPORT_SYMBOL_GPL(snd_hdac_set_codec_wakeup); */ int snd_hdac_display_power(struct hdac_bus *bus, bool enable) { - struct i915_audio_component *acomp = bus->audio_component; + struct drm_audio_component *acomp = bus->audio_component; if (!acomp || !acomp->ops) return -ENODEV; @@ -83,14 +83,14 @@ int snd_hdac_display_power(struct hdac_bus *bus, bool enable) enable ? "enable" : "disable"); if (enable) { - if (!bus->i915_power_refcount++) { + if (!bus->drm_power_refcount++) { acomp->ops->get_power(acomp->dev); snd_hdac_set_codec_wakeup(bus, true); snd_hdac_set_codec_wakeup(bus, false); } } else { - WARN_ON(!bus->i915_power_refcount); - if (!--bus->i915_power_refcount) + WARN_ON(!bus->drm_power_refcount); + if (!--bus->drm_power_refcount) acomp->ops->put_power(acomp->dev); } @@ -119,7 +119,7 @@ EXPORT_SYMBOL_GPL(snd_hdac_display_power); */ void snd_hdac_i915_set_bclk(struct hdac_bus *bus) { - struct i915_audio_component *acomp = bus->audio_component; + struct drm_audio_component *acomp = bus->audio_component; struct pci_dev *pci = to_pci_dev(bus->dev); int cdclk_freq; unsigned int bclk_m, bclk_n; @@ -206,7 +206,7 @@ int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid, int dev_id, int rate) { struct hdac_bus *bus = codec->bus; - struct i915_audio_component *acomp = bus->audio_component; + struct drm_audio_component *acomp = bus->audio_component; int port, pipe; if (!acomp || !acomp->ops || !acomp->ops->sync_audio_rate) @@ -244,7 +244,7 @@ int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid, int dev_id, bool *audio_enabled, char *buffer, int max_bytes) { struct hdac_bus *bus = codec->bus; - struct i915_audio_component *acomp = bus->audio_component; + struct drm_audio_component *acomp = bus->audio_component; int port, pipe; if (!acomp || !acomp->ops || !acomp->ops->get_eld) @@ -262,7 +262,7 @@ EXPORT_SYMBOL_GPL(snd_hdac_acomp_get_eld); static int hdac_component_master_bind(struct device *dev) { - struct i915_audio_component *acomp = hdac_acomp; + struct drm_audio_component *acomp = hdac_acomp; int ret; ret = component_bind_all(dev, acomp); @@ -294,7 +294,7 @@ out_unbind: static void hdac_component_master_unbind(struct device *dev) { - struct i915_audio_component *acomp = hdac_acomp; + struct drm_audio_component *acomp = hdac_acomp; module_put(acomp->ops->owner); component_unbind_all(dev, acomp); @@ -323,7 +323,7 @@ static int hdac_component_master_match(struct device *dev, void *data) * * Returns zero for success or a negative error code. */ -int snd_hdac_i915_register_notifier(const struct i915_audio_component_audio_ops *aops) +int snd_hdac_i915_register_notifier(const struct drm_audio_component_audio_ops *aops) { if (!hdac_acomp) return -ENODEV; @@ -361,7 +361,8 @@ int snd_hdac_i915_init(struct hdac_bus *bus) { struct component_match *match = NULL; struct device *dev = bus->dev; - struct i915_audio_component *acomp; + struct i915_audio_component *i915_acomp; + struct drm_audio_component *acomp; int ret; if (WARN_ON(hdac_acomp)) @@ -370,9 +371,10 @@ int snd_hdac_i915_init(struct hdac_bus *bus) if (!i915_gfx_present()) return -ENODEV; - acomp = kzalloc(sizeof(*acomp), GFP_KERNEL); - if (!acomp) + i915_acomp = kzalloc(sizeof(*i915_acomp), GFP_KERNEL); + if (!i915_acomp) return -ENOMEM; + acomp = &i915_acomp->base; bus->audio_component = acomp; hdac_acomp = acomp; @@ -421,13 +423,13 @@ EXPORT_SYMBOL_GPL(snd_hdac_i915_init); int snd_hdac_i915_exit(struct hdac_bus *bus) { struct device *dev = bus->dev; - struct i915_audio_component *acomp = bus->audio_component; + struct drm_audio_component *acomp = bus->audio_component; if (!acomp) return 0; - WARN_ON(bus->i915_power_refcount); - if (bus->i915_power_refcount > 0 && acomp->ops) + WARN_ON(bus->drm_power_refcount); + if (bus->drm_power_refcount > 0 && acomp->ops) acomp->ops->put_power(acomp->dev); component_master_del(dev, &hdac_component_master_ops); diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 8a49415aebac..c0847017114c 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -177,7 +177,7 @@ struct hdmi_spec { /* i915/powerwell (Haswell+/Valleyview+) specific */ bool use_acomp_notifier; /* use i915 eld_notify callback for hotplug */ - struct i915_audio_component_audio_ops i915_audio_ops; + struct drm_audio_component_audio_ops drm_audio_ops; struct hdac_chmap chmap; hda_nid_t vendor_nid; @@ -2511,14 +2511,14 @@ static void register_i915_notifier(struct hda_codec *codec) struct hdmi_spec *spec = codec->spec; spec->use_acomp_notifier = true; - spec->i915_audio_ops.audio_ptr = codec; + spec->drm_audio_ops.audio_ptr = codec; /* intel_audio_codec_enable() or intel_audio_codec_disable() * will call pin_eld_notify with using audio_ptr pointer * We need make sure audio_ptr is really setup */ wmb(); - spec->i915_audio_ops.pin_eld_notify = intel_pin_eld_notify; - snd_hdac_i915_register_notifier(&spec->i915_audio_ops); + spec->drm_audio_ops.pin_eld_notify = intel_pin_eld_notify; + snd_hdac_i915_register_notifier(&spec->drm_audio_ops); } /* setup_stream ops override for HSW+ */ diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c index 3e3a2a9ef310..460075475f20 100644 --- a/sound/soc/codecs/hdac_hdmi.c +++ b/sound/soc/codecs/hdac_hdmi.c @@ -1583,7 +1583,7 @@ static void hdac_hdmi_eld_notify_cb(void *aptr, int port, int pipe) } -static struct i915_audio_component_audio_ops aops = { +static struct drm_audio_component_audio_ops aops = { .pin_eld_notify = hdac_hdmi_eld_notify_cb, }; -- cgit v1.2.3-58-ga151 From 82887c0beb1ee6b33eed8318d8e8d41c5b3eddae Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 11 Jul 2018 15:48:18 +0200 Subject: ALSA: hda/i915: Associate audio component with devres The HD-audio i915 binding code contains a single pointer, hdac_acomp, for allowing the access to audio component from the master bind/unbind callbacks. This was needed because the callbacks pass only the device pointer and we can't guarantee the object type assigned to the drvdata (which is free for each controller driver implementation). And this implementation will be a problem if we support multiple components for different DRM drivers, not only i915. As a solution, allocate the audio component object via devres and associate it with the given device, so that the component callbacks can refer to it via devres_find(). The removal of the object is still done half-manually via devres_destroy() to make the code consistent (although it may work without the explicit call). Also, the snd_hda_i915_register_notifier() had the reference to hdac_acomp as well. In this patch, the corresponding code is removed by passing hdac_bus object to the function, too. Signed-off-by: Takashi Iwai --- include/sound/hda_i915.h | 6 ++++-- sound/hda/hdac_i915.c | 34 +++++++++++++++++++++------------- sound/pci/hda/patch_hdmi.c | 5 +++-- sound/soc/codecs/hdac_hdmi.c | 2 +- 4 files changed, 29 insertions(+), 18 deletions(-) (limited to 'include') diff --git a/include/sound/hda_i915.h b/include/sound/hda_i915.h index f69ea84e7b65..648263791559 100644 --- a/include/sound/hda_i915.h +++ b/include/sound/hda_i915.h @@ -17,7 +17,8 @@ int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid, int dev_id, bool *audio_enabled, char *buffer, int max_bytes); int snd_hdac_i915_init(struct hdac_bus *bus); int snd_hdac_i915_exit(struct hdac_bus *bus); -int snd_hdac_i915_register_notifier(const struct drm_audio_component_audio_ops *); +int snd_hdac_i915_register_notifier(struct hdac_bus *bus, + const struct drm_audio_component_audio_ops *ops); #else static inline int snd_hdac_set_codec_wakeup(struct hdac_bus *bus, bool enable) { @@ -49,7 +50,8 @@ static inline int snd_hdac_i915_exit(struct hdac_bus *bus) { return 0; } -static inline int snd_hdac_i915_register_notifier(const struct drm_audio_component_audio_ops *ops) +static inline int snd_hdac_i915_register_notifier(struct hdac_bus *bus, + const struct drm_audio_component_audio_ops *ops) { return -ENODEV; } diff --git a/sound/hda/hdac_i915.c b/sound/hda/hdac_i915.c index 1a88c1aaf9bb..861b77bbc7df 100644 --- a/sound/hda/hdac_i915.c +++ b/sound/hda/hdac_i915.c @@ -22,7 +22,14 @@ #include #include -static struct drm_audio_component *hdac_acomp; +static void hdac_acomp_release(struct device *dev, void *res) +{ +} + +static struct drm_audio_component *hdac_get_acomp(struct device *dev) +{ + return devres_find(dev, hdac_acomp_release, NULL, NULL); +} /** * snd_hdac_set_codec_wakeup - Enable / disable HDMI/DP codec wakeup @@ -262,7 +269,7 @@ EXPORT_SYMBOL_GPL(snd_hdac_acomp_get_eld); static int hdac_component_master_bind(struct device *dev) { - struct drm_audio_component *acomp = hdac_acomp; + struct drm_audio_component *acomp = hdac_get_acomp(dev); int ret; ret = component_bind_all(dev, acomp); @@ -294,7 +301,7 @@ out_unbind: static void hdac_component_master_unbind(struct device *dev) { - struct drm_audio_component *acomp = hdac_acomp; + struct drm_audio_component *acomp = hdac_get_acomp(dev); module_put(acomp->ops->owner); component_unbind_all(dev, acomp); @@ -314,6 +321,7 @@ static int hdac_component_master_match(struct device *dev, void *data) /** * snd_hdac_i915_register_notifier - Register i915 audio component ops + * @bus: HDA core bus * @aops: i915 audio component ops * * This function is supposed to be used only by a HD-audio controller @@ -323,12 +331,13 @@ static int hdac_component_master_match(struct device *dev, void *data) * * Returns zero for success or a negative error code. */ -int snd_hdac_i915_register_notifier(const struct drm_audio_component_audio_ops *aops) +int snd_hdac_i915_register_notifier(struct hdac_bus *bus, + const struct drm_audio_component_audio_ops *aops) { - if (!hdac_acomp) + if (!bus->audio_component) return -ENODEV; - hdac_acomp->audio_ops = aops; + bus->audio_component->audio_ops = aops; return 0; } EXPORT_SYMBOL_GPL(snd_hdac_i915_register_notifier); @@ -365,18 +374,19 @@ int snd_hdac_i915_init(struct hdac_bus *bus) struct drm_audio_component *acomp; int ret; - if (WARN_ON(hdac_acomp)) + if (WARN_ON(hdac_get_acomp(dev))) return -EBUSY; if (!i915_gfx_present()) return -ENODEV; - i915_acomp = kzalloc(sizeof(*i915_acomp), GFP_KERNEL); + i915_acomp = devres_alloc(hdac_acomp_release, sizeof(*i915_acomp), + GFP_KERNEL); if (!i915_acomp) return -ENOMEM; acomp = &i915_acomp->base; bus->audio_component = acomp; - hdac_acomp = acomp; + devres_add(dev, acomp); component_match_add(dev, &match, hdac_component_master_match, bus); ret = component_master_add_with_match(dev, &hdac_component_master_ops, @@ -400,9 +410,8 @@ int snd_hdac_i915_init(struct hdac_bus *bus) out_master_del: component_master_del(dev, &hdac_component_master_ops); out_err: - kfree(acomp); bus->audio_component = NULL; - hdac_acomp = NULL; + devres_destroy(dev, hdac_acomp_release, NULL, NULL); dev_info(dev, "failed to add i915 component master (%d)\n", ret); return ret; @@ -434,9 +443,8 @@ int snd_hdac_i915_exit(struct hdac_bus *bus) component_master_del(dev, &hdac_component_master_ops); - kfree(acomp); bus->audio_component = NULL; - hdac_acomp = NULL; + devres_destroy(dev, hdac_acomp_release, NULL, NULL); return 0; } diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index c0847017114c..bf174a013f2d 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -2288,7 +2288,7 @@ static void generic_hdmi_free(struct hda_codec *codec) int pin_idx, pcm_idx; if (codec_has_acomp(codec)) - snd_hdac_i915_register_notifier(NULL); + snd_hdac_i915_register_notifier(&codec->bus->core, NULL); for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx); @@ -2518,7 +2518,8 @@ static void register_i915_notifier(struct hda_codec *codec) */ wmb(); spec->drm_audio_ops.pin_eld_notify = intel_pin_eld_notify; - snd_hdac_i915_register_notifier(&spec->drm_audio_ops); + snd_hdac_i915_register_notifier(&codec->bus->core, + &spec->drm_audio_ops); } /* setup_stream ops override for HSW+ */ diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c index 460075475f20..2b7c33db4ded 100644 --- a/sound/soc/codecs/hdac_hdmi.c +++ b/sound/soc/codecs/hdac_hdmi.c @@ -1812,7 +1812,7 @@ static int hdmi_codec_probe(struct snd_soc_component *component) return ret; aops.audio_ptr = hdev; - ret = snd_hdac_i915_register_notifier(&aops); + ret = snd_hdac_i915_register_notifier(hdev->bus, &aops); if (ret < 0) { dev_err(&hdev->dev, "notifier register failed: err: %d\n", ret); return ret; -- cgit v1.2.3-58-ga151 From a57942bfdd61b46df94021c9c33b8faaae5b65e1 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 11 Jul 2018 16:23:16 +0200 Subject: ALSA: hda: Make audio component support more generic This is the final step for more generic support of DRM audio component. The generic audio component code is now moved to its own file, and the symbols are renamed from snd_hac_i915_* to snd_hdac_acomp_*, respectively. The generic code is enabled via the new kconfig, CONFIG_SND_HDA_COMPONENT, while CONFIG_SND_HDA_I915 is kept as the super-class. Along with the split, three new callbacks are added to audio_ops: pin2port is for providing the conversion between the pin number and the widget id, and master_bind/master_unbin are called at binding / unbinding the master component, respectively. All these are optional, but used in i915 implementation and also other later implementations. A note about the new snd_hdac_acomp_init() function: there is a slight difference between this and the old snd_hdac_i915_init(). The latter (still) synchronizes with the master component binding, i.e. it assures that the relevant DRM component gets bound when it returns, or gives a negative error. Meanwhile the new function doesn't synchronize but just leaves as is. It's the responsibility by the caller's side to synchronize, or the caller may accept the asynchronous binding on the fly. v1->v2: Fix missing NULL check in master_bind/unbind Signed-off-by: Takashi Iwai --- drivers/gpu/drm/i915/Kconfig | 1 + include/drm/drm_audio_component.h | 23 +++ include/sound/hda_component.h | 61 +++++++ include/sound/hda_i915.h | 39 +---- sound/hda/Kconfig | 7 +- sound/hda/Makefile | 1 + sound/hda/hdac_component.c | 335 +++++++++++++++++++++++++++++++++++++ sound/hda/hdac_i915.c | 343 ++------------------------------------ sound/pci/hda/patch_hdmi.c | 50 ++++-- sound/soc/codecs/hdac_hdmi.c | 8 +- 10 files changed, 486 insertions(+), 382 deletions(-) create mode 100644 include/sound/hda_component.h create mode 100644 sound/hda/hdac_component.c (limited to 'include') diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig index dfd95889f4b7..5c607f2c707b 100644 --- a/drivers/gpu/drm/i915/Kconfig +++ b/drivers/gpu/drm/i915/Kconfig @@ -23,6 +23,7 @@ config DRM_I915 select SYNC_FILE select IOSF_MBI select CRC32 + select SND_HDA_I915 if SND_HDA_CORE help Choose this option if you have a system that has "Intel Graphics Media Accelerator" or "HD Graphics" integrated graphics, diff --git a/include/drm/drm_audio_component.h b/include/drm/drm_audio_component.h index e85689f212c2..4923b00328c1 100644 --- a/include/drm/drm_audio_component.h +++ b/include/drm/drm_audio_component.h @@ -4,6 +4,8 @@ #ifndef _DRM_AUDIO_COMPONENT_H_ #define _DRM_AUDIO_COMPONENT_H_ +struct drm_audio_component; + /** * struct drm_audio_component_ops - Ops implemented by DRM driver, called by hda driver */ @@ -72,6 +74,27 @@ struct drm_audio_component_audio_ops { * mode). */ void (*pin_eld_notify)(void *audio_ptr, int port, int pipe); + /** + * @pin2port: Check and convert from pin node to port number + * + * Called by HDA driver to check and convert from the pin widget node + * number to a port number in the graphics side. + */ + int (*pin2port)(void *audio_ptr, int pin); + /** + * @master_bind: (Optional) component master bind callback + * + * Called at binding master component, for HDA codec-specific + * handling of dynamic binding. + */ + int (*master_bind)(struct device *dev, struct drm_audio_component *); + /** + * @master_unbind: (Optional) component master unbind callback + * + * Called at unbinding master component, for HDA codec-specific + * handling of dynamic unbinding. + */ + void (*master_unbind)(struct device *dev, struct drm_audio_component *); }; /** diff --git a/include/sound/hda_component.h b/include/sound/hda_component.h new file mode 100644 index 000000000000..78626cde7081 --- /dev/null +++ b/include/sound/hda_component.h @@ -0,0 +1,61 @@ +// SPDX-License-Identifier: GPL-2.0 +// HD-Audio helpers to sync with DRM driver + +#ifndef __SOUND_HDA_COMPONENT_H +#define __SOUND_HDA_COMPONENT_H + +#include + +#ifdef CONFIG_SND_HDA_COMPONENT +int snd_hdac_set_codec_wakeup(struct hdac_bus *bus, bool enable); +int snd_hdac_display_power(struct hdac_bus *bus, bool enable); +int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid, + int dev_id, int rate); +int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid, int dev_id, + bool *audio_enabled, char *buffer, int max_bytes); +int snd_hdac_acomp_init(struct hdac_bus *bus, + const struct drm_audio_component_audio_ops *aops, + int (*match_master)(struct device *, void *), + size_t extra_size); +int snd_hdac_acomp_exit(struct hdac_bus *bus); +int snd_hdac_acomp_register_notifier(struct hdac_bus *bus, + const struct drm_audio_component_audio_ops *ops); +#else +static inline int snd_hdac_set_codec_wakeup(struct hdac_bus *bus, bool enable) +{ + return 0; +} +static inline int snd_hdac_display_power(struct hdac_bus *bus, bool enable) +{ + return 0; +} +static inline int snd_hdac_sync_audio_rate(struct hdac_device *codec, + hda_nid_t nid, int dev_id, int rate) +{ + return 0; +} +static inline int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid, + int dev_id, bool *audio_enabled, + char *buffer, int max_bytes) +{ + return -ENODEV; +} +static inline int snd_hdac_acomp_init(struct hdac_bus *bus, + const struct drm_audio_component_audio_ops *aops, + int (*match_master)(struct device *, void *), + size_t extra_size) +{ + return -ENODEV; +} +static inline int snd_hdac_acomp_exit(struct hdac_bus *bus) +{ + return 0; +} +static inline int snd_hdac_acomp_register_notifier(struct hdac_bus *bus, + const struct drm_audio_component_audio_ops *ops) +{ + return -ENODEV; +} +#endif + +#endif /* __SOUND_HDA_COMPONENT_H */ diff --git a/include/sound/hda_i915.h b/include/sound/hda_i915.h index 648263791559..6b79614a893b 100644 --- a/include/sound/hda_i915.h +++ b/include/sound/hda_i915.h @@ -5,56 +5,23 @@ #ifndef __SOUND_HDA_I915_H #define __SOUND_HDA_I915_H -#include +#include "hda_component.h" #ifdef CONFIG_SND_HDA_I915 -int snd_hdac_set_codec_wakeup(struct hdac_bus *bus, bool enable); -int snd_hdac_display_power(struct hdac_bus *bus, bool enable); void snd_hdac_i915_set_bclk(struct hdac_bus *bus); -int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid, - int dev_id, int rate); -int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid, int dev_id, - bool *audio_enabled, char *buffer, int max_bytes); int snd_hdac_i915_init(struct hdac_bus *bus); -int snd_hdac_i915_exit(struct hdac_bus *bus); -int snd_hdac_i915_register_notifier(struct hdac_bus *bus, - const struct drm_audio_component_audio_ops *ops); #else -static inline int snd_hdac_set_codec_wakeup(struct hdac_bus *bus, bool enable) -{ - return 0; -} -static inline int snd_hdac_display_power(struct hdac_bus *bus, bool enable) -{ - return 0; -} static inline void snd_hdac_i915_set_bclk(struct hdac_bus *bus) { } -static inline int snd_hdac_sync_audio_rate(struct hdac_device *codec, - hda_nid_t nid, int dev_id, int rate) -{ - return 0; -} -static inline int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid, - int dev_id, bool *audio_enabled, - char *buffer, int max_bytes) -{ - return -ENODEV; -} static inline int snd_hdac_i915_init(struct hdac_bus *bus) { return -ENODEV; } +#endif static inline int snd_hdac_i915_exit(struct hdac_bus *bus) { - return 0; + return snd_hdac_acomp_exit(bus); } -static inline int snd_hdac_i915_register_notifier(struct hdac_bus *bus, - const struct drm_audio_component_audio_ops *ops) -{ - return -ENODEV; -} -#endif #endif /* __SOUND_HDA_I915_H */ diff --git a/sound/hda/Kconfig b/sound/hda/Kconfig index 3129546398d0..2d90e11b3eaa 100644 --- a/sound/hda/Kconfig +++ b/sound/hda/Kconfig @@ -5,11 +5,12 @@ config SND_HDA_CORE config SND_HDA_DSP_LOADER bool +config SND_HDA_COMPONENT + bool + config SND_HDA_I915 bool - default y - depends on DRM_I915 - depends on SND_HDA_CORE + select SND_HDA_COMPONENT config SND_HDA_EXT_CORE tristate diff --git a/sound/hda/Makefile b/sound/hda/Makefile index e4e726f2ce98..2160202e2dc1 100644 --- a/sound/hda/Makefile +++ b/sound/hda/Makefile @@ -6,6 +6,7 @@ snd-hda-core-objs += trace.o CFLAGS_trace.o := -I$(src) # for sync with i915 gfx driver +snd-hda-core-$(CONFIG_SND_HDA_COMPONENT) += hdac_component.o snd-hda-core-$(CONFIG_SND_HDA_I915) += hdac_i915.o obj-$(CONFIG_SND_HDA_CORE) += snd-hda-core.o diff --git a/sound/hda/hdac_component.c b/sound/hda/hdac_component.c new file mode 100644 index 000000000000..6e46a9c73aed --- /dev/null +++ b/sound/hda/hdac_component.c @@ -0,0 +1,335 @@ +// SPDX-License-Identifier: GPL-2.0 +// hdac_component.c - routines for sync between HD-A core and DRM driver + +#include +#include +#include +#include +#include +#include +#include +#include + +static void hdac_acomp_release(struct device *dev, void *res) +{ +} + +static struct drm_audio_component *hdac_get_acomp(struct device *dev) +{ + return devres_find(dev, hdac_acomp_release, NULL, NULL); +} + +/** + * snd_hdac_set_codec_wakeup - Enable / disable HDMI/DP codec wakeup + * @bus: HDA core bus + * @enable: enable or disable the wakeup + * + * This function is supposed to be used only by a HD-audio controller + * driver that needs the interaction with graphics driver. + * + * This function should be called during the chip reset, also called at + * resume for updating STATESTS register read. + * + * Returns zero for success or a negative error code. + */ +int snd_hdac_set_codec_wakeup(struct hdac_bus *bus, bool enable) +{ + struct drm_audio_component *acomp = bus->audio_component; + + if (!acomp || !acomp->ops) + return -ENODEV; + + if (!acomp->ops->codec_wake_override) + return 0; + + dev_dbg(bus->dev, "%s codec wakeup\n", + enable ? "enable" : "disable"); + + acomp->ops->codec_wake_override(acomp->dev, enable); + + return 0; +} +EXPORT_SYMBOL_GPL(snd_hdac_set_codec_wakeup); + +/** + * snd_hdac_display_power - Power up / down the power refcount + * @bus: HDA core bus + * @enable: power up or down + * + * This function is supposed to be used only by a HD-audio controller + * driver that needs the interaction with graphics driver. + * + * This function manages a refcount and calls the get_power() and + * put_power() ops accordingly, toggling the codec wakeup, too. + * + * Returns zero for success or a negative error code. + */ +int snd_hdac_display_power(struct hdac_bus *bus, bool enable) +{ + struct drm_audio_component *acomp = bus->audio_component; + + if (!acomp || !acomp->ops) + return -ENODEV; + + dev_dbg(bus->dev, "display power %s\n", + enable ? "enable" : "disable"); + + if (enable) { + if (!bus->drm_power_refcount++) { + if (acomp->ops->get_power) + acomp->ops->get_power(acomp->dev); + snd_hdac_set_codec_wakeup(bus, true); + snd_hdac_set_codec_wakeup(bus, false); + } + } else { + WARN_ON(!bus->drm_power_refcount); + if (!--bus->drm_power_refcount) + if (acomp->ops->put_power) + acomp->ops->put_power(acomp->dev); + } + + return 0; +} +EXPORT_SYMBOL_GPL(snd_hdac_display_power); + +/** + * snd_hdac_sync_audio_rate - Set N/CTS based on the sample rate + * @codec: HDA codec + * @nid: the pin widget NID + * @dev_id: device identifier + * @rate: the sample rate to set + * + * This function is supposed to be used only by a HD-audio controller + * driver that needs the interaction with graphics driver. + * + * This function sets N/CTS value based on the given sample rate. + * Returns zero for success, or a negative error code. + */ +int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid, + int dev_id, int rate) +{ + struct hdac_bus *bus = codec->bus; + struct drm_audio_component *acomp = bus->audio_component; + int port, pipe; + + if (!acomp || !acomp->ops || !acomp->ops->sync_audio_rate) + return -ENODEV; + port = nid; + if (acomp->audio_ops && acomp->audio_ops->pin2port) { + port = acomp->audio_ops->pin2port(codec, nid); + if (port < 0) + return -EINVAL; + } + pipe = dev_id; + return acomp->ops->sync_audio_rate(acomp->dev, port, pipe, rate); +} +EXPORT_SYMBOL_GPL(snd_hdac_sync_audio_rate); + +/** + * snd_hdac_acomp_get_eld - Get the audio state and ELD via component + * @codec: HDA codec + * @nid: the pin widget NID + * @dev_id: device identifier + * @audio_enabled: the pointer to store the current audio state + * @buffer: the buffer pointer to store ELD bytes + * @max_bytes: the max bytes to be stored on @buffer + * + * This function is supposed to be used only by a HD-audio controller + * driver that needs the interaction with graphics driver. + * + * This function queries the current state of the audio on the given + * digital port and fetches the ELD bytes onto the given buffer. + * It returns the number of bytes for the total ELD data, zero for + * invalid ELD, or a negative error code. + * + * The return size is the total bytes required for the whole ELD bytes, + * thus it may be over @max_bytes. If it's over @max_bytes, it implies + * that only a part of ELD bytes have been fetched. + */ +int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid, int dev_id, + bool *audio_enabled, char *buffer, int max_bytes) +{ + struct hdac_bus *bus = codec->bus; + struct drm_audio_component *acomp = bus->audio_component; + int port, pipe; + + if (!acomp || !acomp->ops || !acomp->ops->get_eld) + return -ENODEV; + + port = nid; + if (acomp->audio_ops && acomp->audio_ops->pin2port) { + port = acomp->audio_ops->pin2port(codec, nid); + if (port < 0) + return -EINVAL; + } + pipe = dev_id; + return acomp->ops->get_eld(acomp->dev, port, pipe, audio_enabled, + buffer, max_bytes); +} +EXPORT_SYMBOL_GPL(snd_hdac_acomp_get_eld); + +static int hdac_component_master_bind(struct device *dev) +{ + struct drm_audio_component *acomp = hdac_get_acomp(dev); + int ret; + + if (WARN_ON(!acomp)) + return -EINVAL; + + ret = component_bind_all(dev, acomp); + if (ret < 0) + return ret; + + if (WARN_ON(!(acomp->dev && acomp->ops))) { + ret = -EINVAL; + goto out_unbind; + } + + /* pin the module to avoid dynamic unbinding, but only if given */ + if (!try_module_get(acomp->ops->owner)) { + ret = -ENODEV; + goto out_unbind; + } + + if (acomp->audio_ops && acomp->audio_ops->master_bind) { + ret = acomp->audio_ops->master_bind(dev, acomp); + if (ret < 0) + goto module_put; + } + + return 0; + + module_put: + module_put(acomp->ops->owner); +out_unbind: + component_unbind_all(dev, acomp); + + return ret; +} + +static void hdac_component_master_unbind(struct device *dev) +{ + struct drm_audio_component *acomp = hdac_get_acomp(dev); + + if (acomp->audio_ops && acomp->audio_ops->master_unbind) + acomp->audio_ops->master_unbind(dev, acomp); + module_put(acomp->ops->owner); + component_unbind_all(dev, acomp); + WARN_ON(acomp->ops || acomp->dev); +} + +static const struct component_master_ops hdac_component_master_ops = { + .bind = hdac_component_master_bind, + .unbind = hdac_component_master_unbind, +}; + +/** + * snd_hdac_acomp_register_notifier - Register audio component ops + * @bus: HDA core bus + * @aops: audio component ops + * + * This function is supposed to be used only by a HD-audio controller + * driver that needs the interaction with graphics driver. + * + * This function sets the given ops to be called by the graphics driver. + * + * Returns zero for success or a negative error code. + */ +int snd_hdac_acomp_register_notifier(struct hdac_bus *bus, + const struct drm_audio_component_audio_ops *aops) +{ + if (!bus->audio_component) + return -ENODEV; + + bus->audio_component->audio_ops = aops; + return 0; +} +EXPORT_SYMBOL_GPL(snd_hdac_acomp_register_notifier); + +/** + * snd_hdac_acomp_init - Initialize audio component + * @bus: HDA core bus + * @match_master: match function for finding components + * @extra_size: Extra bytes to allocate + * + * This function is supposed to be used only by a HD-audio controller + * driver that needs the interaction with graphics driver. + * + * This function initializes and sets up the audio component to communicate + * with graphics driver. + * + * Unlike snd_hdac_i915_init(), this function doesn't synchronize with the + * binding with the DRM component. Each caller needs to sync via master_bind + * audio_ops. + * + * Returns zero for success or a negative error code. + */ +int snd_hdac_acomp_init(struct hdac_bus *bus, + const struct drm_audio_component_audio_ops *aops, + int (*match_master)(struct device *, void *), + size_t extra_size) +{ + struct component_match *match = NULL; + struct device *dev = bus->dev; + struct drm_audio_component *acomp; + int ret; + + if (WARN_ON(hdac_get_acomp(dev))) + return -EBUSY; + + acomp = devres_alloc(hdac_acomp_release, sizeof(*acomp) + extra_size, + GFP_KERNEL); + if (!acomp) + return -ENOMEM; + acomp->audio_ops = aops; + bus->audio_component = acomp; + devres_add(dev, acomp); + + component_match_add(dev, &match, match_master, bus); + ret = component_master_add_with_match(dev, &hdac_component_master_ops, + match); + if (ret < 0) + goto out_err; + + return 0; + +out_err: + bus->audio_component = NULL; + devres_destroy(dev, hdac_acomp_release, NULL, NULL); + dev_info(dev, "failed to add audio component master (%d)\n", ret); + + return ret; +} +EXPORT_SYMBOL_GPL(snd_hdac_acomp_init); + +/** + * snd_hdac_acomp_exit - Finalize audio component + * @bus: HDA core bus + * + * This function is supposed to be used only by a HD-audio controller + * driver that needs the interaction with graphics driver. + * + * This function releases the audio component that has been used. + * + * Returns zero for success or a negative error code. + */ +int snd_hdac_acomp_exit(struct hdac_bus *bus) +{ + struct device *dev = bus->dev; + struct drm_audio_component *acomp = bus->audio_component; + + if (!acomp) + return 0; + + WARN_ON(bus->drm_power_refcount); + if (bus->drm_power_refcount > 0 && acomp->ops) + acomp->ops->put_power(acomp->dev); + + component_master_del(dev, &hdac_component_master_ops); + + bus->audio_component = NULL; + devres_destroy(dev, hdac_acomp_release, NULL, NULL); + + return 0; +} +EXPORT_SYMBOL_GPL(snd_hdac_acomp_exit); diff --git a/sound/hda/hdac_i915.c b/sound/hda/hdac_i915.c index 861b77bbc7df..8f2aa8bc1185 100644 --- a/sound/hda/hdac_i915.c +++ b/sound/hda/hdac_i915.c @@ -15,96 +15,11 @@ #include #include #include -#include -#include #include #include #include #include -static void hdac_acomp_release(struct device *dev, void *res) -{ -} - -static struct drm_audio_component *hdac_get_acomp(struct device *dev) -{ - return devres_find(dev, hdac_acomp_release, NULL, NULL); -} - -/** - * snd_hdac_set_codec_wakeup - Enable / disable HDMI/DP codec wakeup - * @bus: HDA core bus - * @enable: enable or disable the wakeup - * - * This function is supposed to be used only by a HD-audio controller - * driver that needs the interaction with i915 graphics. - * - * This function should be called during the chip reset, also called at - * resume for updating STATESTS register read. - * - * Returns zero for success or a negative error code. - */ -int snd_hdac_set_codec_wakeup(struct hdac_bus *bus, bool enable) -{ - struct drm_audio_component *acomp = bus->audio_component; - - if (!acomp || !acomp->ops) - return -ENODEV; - - if (!acomp->ops->codec_wake_override) { - dev_warn(bus->dev, - "Invalid codec wake callback\n"); - return 0; - } - - dev_dbg(bus->dev, "%s codec wakeup\n", - enable ? "enable" : "disable"); - - acomp->ops->codec_wake_override(acomp->dev, enable); - - return 0; -} -EXPORT_SYMBOL_GPL(snd_hdac_set_codec_wakeup); - -/** - * snd_hdac_display_power - Power up / down the power refcount - * @bus: HDA core bus - * @enable: power up or down - * - * This function is supposed to be used only by a HD-audio controller - * driver that needs the interaction with i915 graphics. - * - * This function manages a refcount and calls the i915 get_power() and - * put_power() ops accordingly, toggling the codec wakeup, too. - * - * Returns zero for success or a negative error code. - */ -int snd_hdac_display_power(struct hdac_bus *bus, bool enable) -{ - struct drm_audio_component *acomp = bus->audio_component; - - if (!acomp || !acomp->ops) - return -ENODEV; - - dev_dbg(bus->dev, "display power %s\n", - enable ? "enable" : "disable"); - - if (enable) { - if (!bus->drm_power_refcount++) { - acomp->ops->get_power(acomp->dev); - snd_hdac_set_codec_wakeup(bus, true); - snd_hdac_set_codec_wakeup(bus, false); - } - } else { - WARN_ON(!bus->drm_power_refcount); - if (!--bus->drm_power_refcount) - acomp->ops->put_power(acomp->dev); - } - - return 0; -} -EXPORT_SYMBOL_GPL(snd_hdac_display_power); - #define CONTROLLER_IN_GPU(pci) (((pci)->device == 0x0a0c) || \ ((pci)->device == 0x0c0c) || \ ((pci)->device == 0x0d0c) || \ @@ -165,183 +80,11 @@ void snd_hdac_i915_set_bclk(struct hdac_bus *bus) } EXPORT_SYMBOL_GPL(snd_hdac_i915_set_bclk); -/* There is a fixed mapping between audio pin node and display port. - * on SNB, IVY, HSW, BSW, SKL, BXT, KBL: - * Pin Widget 5 - PORT B (port = 1 in i915 driver) - * Pin Widget 6 - PORT C (port = 2 in i915 driver) - * Pin Widget 7 - PORT D (port = 3 in i915 driver) - * - * on VLV, ILK: - * Pin Widget 4 - PORT B (port = 1 in i915 driver) - * Pin Widget 5 - PORT C (port = 2 in i915 driver) - * Pin Widget 6 - PORT D (port = 3 in i915 driver) - */ -static int pin2port(struct hdac_device *codec, hda_nid_t pin_nid) -{ - int base_nid; - - switch (codec->vendor_id) { - case 0x80860054: /* ILK */ - case 0x80862804: /* ILK */ - case 0x80862882: /* VLV */ - base_nid = 3; - break; - default: - base_nid = 4; - break; - } - - if (WARN_ON(pin_nid <= base_nid || pin_nid > base_nid + 3)) - return -1; - return pin_nid - base_nid; -} - -/** - * snd_hdac_sync_audio_rate - Set N/CTS based on the sample rate - * @codec: HDA codec - * @nid: the pin widget NID - * @dev_id: device identifier - * @rate: the sample rate to set - * - * This function is supposed to be used only by a HD-audio controller - * driver that needs the interaction with i915 graphics. - * - * This function sets N/CTS value based on the given sample rate. - * Returns zero for success, or a negative error code. - */ -int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid, - int dev_id, int rate) +static int i915_component_master_match(struct device *dev, void *data) { - struct hdac_bus *bus = codec->bus; - struct drm_audio_component *acomp = bus->audio_component; - int port, pipe; - - if (!acomp || !acomp->ops || !acomp->ops->sync_audio_rate) - return -ENODEV; - port = pin2port(codec, nid); - if (port < 0) - return -EINVAL; - pipe = dev_id; - return acomp->ops->sync_audio_rate(acomp->dev, port, pipe, rate); -} -EXPORT_SYMBOL_GPL(snd_hdac_sync_audio_rate); - -/** - * snd_hdac_acomp_get_eld - Get the audio state and ELD via component - * @codec: HDA codec - * @nid: the pin widget NID - * @dev_id: device identifier - * @audio_enabled: the pointer to store the current audio state - * @buffer: the buffer pointer to store ELD bytes - * @max_bytes: the max bytes to be stored on @buffer - * - * This function is supposed to be used only by a HD-audio controller - * driver that needs the interaction with i915 graphics. - * - * This function queries the current state of the audio on the given - * digital port and fetches the ELD bytes onto the given buffer. - * It returns the number of bytes for the total ELD data, zero for - * invalid ELD, or a negative error code. - * - * The return size is the total bytes required for the whole ELD bytes, - * thus it may be over @max_bytes. If it's over @max_bytes, it implies - * that only a part of ELD bytes have been fetched. - */ -int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid, int dev_id, - bool *audio_enabled, char *buffer, int max_bytes) -{ - struct hdac_bus *bus = codec->bus; - struct drm_audio_component *acomp = bus->audio_component; - int port, pipe; - - if (!acomp || !acomp->ops || !acomp->ops->get_eld) - return -ENODEV; - - port = pin2port(codec, nid); - if (port < 0) - return -EINVAL; - - pipe = dev_id; - return acomp->ops->get_eld(acomp->dev, port, pipe, audio_enabled, - buffer, max_bytes); -} -EXPORT_SYMBOL_GPL(snd_hdac_acomp_get_eld); - -static int hdac_component_master_bind(struct device *dev) -{ - struct drm_audio_component *acomp = hdac_get_acomp(dev); - int ret; - - ret = component_bind_all(dev, acomp); - if (ret < 0) - return ret; - - if (WARN_ON(!(acomp->dev && acomp->ops && acomp->ops->get_power && - acomp->ops->put_power && acomp->ops->get_cdclk_freq))) { - ret = -EINVAL; - goto out_unbind; - } - - /* - * Atm, we don't support dynamic unbinding initiated by the child - * component, so pin its containing module until we unbind. - */ - if (!try_module_get(acomp->ops->owner)) { - ret = -ENODEV; - goto out_unbind; - } - - return 0; - -out_unbind: - component_unbind_all(dev, acomp); - - return ret; -} - -static void hdac_component_master_unbind(struct device *dev) -{ - struct drm_audio_component *acomp = hdac_get_acomp(dev); - - module_put(acomp->ops->owner); - component_unbind_all(dev, acomp); - WARN_ON(acomp->ops || acomp->dev); -} - -static const struct component_master_ops hdac_component_master_ops = { - .bind = hdac_component_master_bind, - .unbind = hdac_component_master_unbind, -}; - -static int hdac_component_master_match(struct device *dev, void *data) -{ - /* i915 is the only supported component */ return !strcmp(dev->driver->name, "i915"); } -/** - * snd_hdac_i915_register_notifier - Register i915 audio component ops - * @bus: HDA core bus - * @aops: i915 audio component ops - * - * This function is supposed to be used only by a HD-audio controller - * driver that needs the interaction with i915 graphics. - * - * This function sets the given ops to be called by the i915 graphics driver. - * - * Returns zero for success or a negative error code. - */ -int snd_hdac_i915_register_notifier(struct hdac_bus *bus, - const struct drm_audio_component_audio_ops *aops) -{ - if (!bus->audio_component) - return -ENODEV; - - bus->audio_component->audio_ops = aops; - return 0; -} -EXPORT_SYMBOL_GPL(snd_hdac_i915_register_notifier); - /* check whether intel graphics is present */ static bool i915_gfx_present(void) { @@ -368,84 +111,26 @@ static bool i915_gfx_present(void) */ int snd_hdac_i915_init(struct hdac_bus *bus) { - struct component_match *match = NULL; - struct device *dev = bus->dev; - struct i915_audio_component *i915_acomp; struct drm_audio_component *acomp; - int ret; - - if (WARN_ON(hdac_get_acomp(dev))) - return -EBUSY; + int err; if (!i915_gfx_present()) return -ENODEV; - i915_acomp = devres_alloc(hdac_acomp_release, sizeof(*i915_acomp), - GFP_KERNEL); - if (!i915_acomp) - return -ENOMEM; - acomp = &i915_acomp->base; - bus->audio_component = acomp; - devres_add(dev, acomp); - - component_match_add(dev, &match, hdac_component_master_match, bus); - ret = component_master_add_with_match(dev, &hdac_component_master_ops, - match); - if (ret < 0) - goto out_err; - - /* - * Atm, we don't support deferring the component binding, so make sure - * i915 is loaded and that the binding successfully completes. - */ - request_module("i915"); - + err = snd_hdac_acomp_init(bus, NULL, + i915_component_master_match, + sizeof(struct i915_audio_component) - sizeof(*acomp)); + if (err < 0) + return err; + acomp = bus->audio_component; + if (!acomp) + return -ENODEV; + if (!acomp->ops) + request_module("i915"); if (!acomp->ops) { - ret = -ENODEV; - goto out_master_del; + snd_hdac_acomp_exit(bus); + return -ENODEV; } - dev_dbg(dev, "bound to i915 component master\n"); - return 0; -out_master_del: - component_master_del(dev, &hdac_component_master_ops); -out_err: - bus->audio_component = NULL; - devres_destroy(dev, hdac_acomp_release, NULL, NULL); - dev_info(dev, "failed to add i915 component master (%d)\n", ret); - - return ret; } EXPORT_SYMBOL_GPL(snd_hdac_i915_init); - -/** - * snd_hdac_i915_exit - Finalize i915 audio component - * @bus: HDA core bus - * - * This function is supposed to be used only by a HD-audio controller - * driver that needs the interaction with i915 graphics. - * - * This function releases the i915 audio component that has been used. - * - * Returns zero for success or a negative error code. - */ -int snd_hdac_i915_exit(struct hdac_bus *bus) -{ - struct device *dev = bus->dev; - struct drm_audio_component *acomp = bus->audio_component; - - if (!acomp) - return 0; - - WARN_ON(bus->drm_power_refcount); - if (bus->drm_power_refcount > 0 && acomp->ops) - acomp->ops->put_power(acomp->dev); - - component_master_del(dev, &hdac_component_master_ops); - - bus->audio_component = NULL; - devres_destroy(dev, hdac_acomp_release, NULL, NULL); - - return 0; -} -EXPORT_SYMBOL_GPL(snd_hdac_i915_exit); diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index bf174a013f2d..1de5491fb9bf 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -183,7 +183,7 @@ struct hdmi_spec { hda_nid_t vendor_nid; }; -#ifdef CONFIG_SND_HDA_I915 +#ifdef CONFIG_SND_HDA_COMPONENT static inline bool codec_has_acomp(struct hda_codec *codec) { struct hdmi_spec *spec = codec->spec; @@ -2288,7 +2288,7 @@ static void generic_hdmi_free(struct hda_codec *codec) int pin_idx, pcm_idx; if (codec_has_acomp(codec)) - snd_hdac_i915_register_notifier(&codec->bus->core, NULL); + snd_hdac_acomp_register_notifier(&codec->bus->core, NULL); for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx); @@ -2471,6 +2471,38 @@ static void haswell_set_power_state(struct hda_codec *codec, hda_nid_t fg, snd_hda_codec_set_power_to_all(codec, fg, power_state); } +/* There is a fixed mapping between audio pin node and display port. + * on SNB, IVY, HSW, BSW, SKL, BXT, KBL: + * Pin Widget 5 - PORT B (port = 1 in i915 driver) + * Pin Widget 6 - PORT C (port = 2 in i915 driver) + * Pin Widget 7 - PORT D (port = 3 in i915 driver) + * + * on VLV, ILK: + * Pin Widget 4 - PORT B (port = 1 in i915 driver) + * Pin Widget 5 - PORT C (port = 2 in i915 driver) + * Pin Widget 6 - PORT D (port = 3 in i915 driver) + */ +static int intel_base_nid(struct hda_codec *codec) +{ + switch (codec->core.vendor_id) { + case 0x80860054: /* ILK */ + case 0x80862804: /* ILK */ + case 0x80862882: /* VLV */ + return 4; + default: + return 5; + } +} + +static int intel_pin2port(void *audio_ptr, int pin_nid) +{ + int base_nid = intel_base_nid(audio_ptr); + + if (WARN_ON(pin_nid < base_nid || pin_nid >= base_nid + 3)) + return -1; + return pin_nid - base_nid + 1; /* intel port is 1-based */ +} + static void intel_pin_eld_notify(void *audio_ptr, int port, int pipe) { struct hda_codec *codec = audio_ptr; @@ -2481,16 +2513,7 @@ static void intel_pin_eld_notify(void *audio_ptr, int port, int pipe) if (port < 1 || port > 3) return; - switch (codec->core.vendor_id) { - case 0x80860054: /* ILK */ - case 0x80862804: /* ILK */ - case 0x80862882: /* VLV */ - pin_nid = port + 0x03; - break; - default: - pin_nid = port + 0x04; - break; - } + pin_nid = port + intel_base_nid(codec) - 1; /* intel port is 1-based */ /* skip notification during system suspend (but not in runtime PM); * the state will be updated at resume @@ -2517,8 +2540,9 @@ static void register_i915_notifier(struct hda_codec *codec) * We need make sure audio_ptr is really setup */ wmb(); + spec->drm_audio_ops.pin2port = intel_pin2port; spec->drm_audio_ops.pin_eld_notify = intel_pin_eld_notify; - snd_hdac_i915_register_notifier(&codec->bus->core, + snd_hdac_acomp_register_notifier(&codec->bus->core, &spec->drm_audio_ops); } diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c index 2b7c33db4ded..4748a9d5de3b 100644 --- a/sound/soc/codecs/hdac_hdmi.c +++ b/sound/soc/codecs/hdac_hdmi.c @@ -1530,6 +1530,11 @@ free_widgets: return ret; } +static int hdac_hdmi_pin2port(void *aptr, int pin) +{ + return pin - 4; /* map NID 0x05 -> port #1 */ +} + static void hdac_hdmi_eld_notify_cb(void *aptr, int port, int pipe) { struct hdac_device *hdev = aptr; @@ -1584,6 +1589,7 @@ static void hdac_hdmi_eld_notify_cb(void *aptr, int port, int pipe) } static struct drm_audio_component_audio_ops aops = { + .pin2port = hdac_hdmi_pin2port, .pin_eld_notify = hdac_hdmi_eld_notify_cb, }; @@ -1812,7 +1818,7 @@ static int hdmi_codec_probe(struct snd_soc_component *component) return ret; aops.audio_ptr = hdev; - ret = snd_hdac_i915_register_notifier(hdev->bus, &aops); + ret = snd_hdac_acomp_register_notifier(hdev->bus, &aops); if (ret < 0) { dev_err(&hdev->dev, "notifier register failed: err: %d\n", ret); return ret; -- cgit v1.2.3-58-ga151