Commit 960ccf6e authored by Simon Trimmer's avatar Simon Trimmer Committed by Takashi Iwai

ALSA: hda: hda_component: Introduce component parent structure

In preparation for moving duplicated members from the hda_component
structure introduce a parent structure that wraps the array of
components. This also allows us to confine the knowledge of the maximum
number of entries to the hda_component files and eliminate passing that
redundant information around and making direct accesses to the array.
Signed-off-by: default avatarSimon Trimmer <simont@opensource.cirrus.com>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/20240617154105.108635-2-simont@opensource.cirrus.com
parent d85002b5
...@@ -15,35 +15,39 @@ ...@@ -15,35 +15,39 @@
#include "hda_local.h" #include "hda_local.h"
#ifdef CONFIG_ACPI #ifdef CONFIG_ACPI
void hda_component_acpi_device_notify(struct hda_component *comps, int num_comps, void hda_component_acpi_device_notify(struct hda_component_parent *parent,
acpi_handle handle, u32 event, void *data) acpi_handle handle, u32 event, void *data)
{ {
struct hda_component *comp;
int i; int i;
for (i = 0; i < num_comps; i++) { for (i = 0; i < ARRAY_SIZE(parent->comps); i++) {
if (comps[i].dev && comps[i].acpi_notify) comp = hda_component_from_index(parent, i);
comps[i].acpi_notify(acpi_device_handle(comps[i].adev), event, if (comp->dev && comp->acpi_notify)
comps[i].dev); comp->acpi_notify(acpi_device_handle(comp->adev), event, comp->dev);
} }
} }
EXPORT_SYMBOL_NS_GPL(hda_component_acpi_device_notify, SND_HDA_SCODEC_COMPONENT); EXPORT_SYMBOL_NS_GPL(hda_component_acpi_device_notify, SND_HDA_SCODEC_COMPONENT);
int hda_component_manager_bind_acpi_notifications(struct hda_codec *cdc, int hda_component_manager_bind_acpi_notifications(struct hda_codec *cdc,
struct hda_component *comps, int num_comps, struct hda_component_parent *parent,
acpi_notify_handler handler, void *data) acpi_notify_handler handler, void *data)
{ {
bool support_notifications = false; bool support_notifications = false;
struct acpi_device *adev; struct acpi_device *adev;
struct hda_component *comp;
int ret; int ret;
int i; int i;
adev = comps[0].adev; adev = parent->comps[0].adev;
if (!acpi_device_handle(adev)) if (!acpi_device_handle(adev))
return 0; return 0;
for (i = 0; i < num_comps; i++) for (i = 0; i < ARRAY_SIZE(parent->comps); i++) {
comp = hda_component_from_index(parent, i);
support_notifications = support_notifications || support_notifications = support_notifications ||
comps[i].acpi_notifications_supported; comp->acpi_notifications_supported;
}
if (support_notifications) { if (support_notifications) {
ret = acpi_install_notify_handler(adev->handle, ACPI_DEVICE_NOTIFY, ret = acpi_install_notify_handler(adev->handle, ACPI_DEVICE_NOTIFY,
...@@ -61,13 +65,13 @@ int hda_component_manager_bind_acpi_notifications(struct hda_codec *cdc, ...@@ -61,13 +65,13 @@ int hda_component_manager_bind_acpi_notifications(struct hda_codec *cdc,
EXPORT_SYMBOL_NS_GPL(hda_component_manager_bind_acpi_notifications, SND_HDA_SCODEC_COMPONENT); EXPORT_SYMBOL_NS_GPL(hda_component_manager_bind_acpi_notifications, SND_HDA_SCODEC_COMPONENT);
void hda_component_manager_unbind_acpi_notifications(struct hda_codec *cdc, void hda_component_manager_unbind_acpi_notifications(struct hda_codec *cdc,
struct hda_component *comps, struct hda_component_parent *parent,
acpi_notify_handler handler) acpi_notify_handler handler)
{ {
struct acpi_device *adev; struct acpi_device *adev;
int ret; int ret;
adev = comps[0].adev; adev = parent->comps[0].adev;
if (!acpi_device_handle(adev)) if (!acpi_device_handle(adev))
return; return;
...@@ -78,21 +82,25 @@ void hda_component_manager_unbind_acpi_notifications(struct hda_codec *cdc, ...@@ -78,21 +82,25 @@ void hda_component_manager_unbind_acpi_notifications(struct hda_codec *cdc,
EXPORT_SYMBOL_NS_GPL(hda_component_manager_unbind_acpi_notifications, SND_HDA_SCODEC_COMPONENT); EXPORT_SYMBOL_NS_GPL(hda_component_manager_unbind_acpi_notifications, SND_HDA_SCODEC_COMPONENT);
#endif /* ifdef CONFIG_ACPI */ #endif /* ifdef CONFIG_ACPI */
void hda_component_manager_playback_hook(struct hda_component *comps, int num_comps, int action) void hda_component_manager_playback_hook(struct hda_component_parent *parent, int action)
{ {
struct hda_component *comp;
int i; int i;
for (i = 0; i < num_comps; i++) { for (i = 0; i < ARRAY_SIZE(parent->comps); i++) {
if (comps[i].dev && comps[i].pre_playback_hook) comp = hda_component_from_index(parent, i);
comps[i].pre_playback_hook(comps[i].dev, action); if (comp->dev && comp->pre_playback_hook)
comp->pre_playback_hook(comp->dev, action);
} }
for (i = 0; i < num_comps; i++) { for (i = 0; i < ARRAY_SIZE(parent->comps); i++) {
if (comps[i].dev && comps[i].playback_hook) comp = hda_component_from_index(parent, i);
comps[i].playback_hook(comps[i].dev, action); if (comp->dev && comp->playback_hook)
comp->playback_hook(comp->dev, action);
} }
for (i = 0; i < num_comps; i++) { for (i = 0; i < ARRAY_SIZE(parent->comps); i++) {
if (comps[i].dev && comps[i].post_playback_hook) comp = hda_component_from_index(parent, i);
comps[i].post_playback_hook(comps[i].dev, action); if (comp->dev && comp->post_playback_hook)
comp->post_playback_hook(comp->dev, action);
} }
} }
EXPORT_SYMBOL_NS_GPL(hda_component_manager_playback_hook, SND_HDA_SCODEC_COMPONENT); EXPORT_SYMBOL_NS_GPL(hda_component_manager_playback_hook, SND_HDA_SCODEC_COMPONENT);
...@@ -124,22 +132,21 @@ static int hda_comp_match_dev_name(struct device *dev, void *data) ...@@ -124,22 +132,21 @@ static int hda_comp_match_dev_name(struct device *dev, void *data)
} }
int hda_component_manager_bind(struct hda_codec *cdc, int hda_component_manager_bind(struct hda_codec *cdc,
struct hda_component *comps, int count) struct hda_component_parent *parent)
{ {
int i; int i;
/* Init shared data */ /* Init shared and component specific data */
for (i = 0; i < count; ++i) { memset(parent, 0, sizeof(*parent));
memset(&comps[i], 0, sizeof(comps[i])); for (i = 0; i < ARRAY_SIZE(parent->comps); i++)
comps[i].codec = cdc; parent->comps[i].codec = cdc;
}
return component_bind_all(hda_codec_dev(cdc), comps); return component_bind_all(hda_codec_dev(cdc), &parent->comps);
} }
EXPORT_SYMBOL_NS_GPL(hda_component_manager_bind, SND_HDA_SCODEC_COMPONENT); EXPORT_SYMBOL_NS_GPL(hda_component_manager_bind, SND_HDA_SCODEC_COMPONENT);
int hda_component_manager_init(struct hda_codec *cdc, int hda_component_manager_init(struct hda_codec *cdc,
struct hda_component *comps, int count, struct hda_component_parent *parent, int count,
const char *bus, const char *hid, const char *bus, const char *hid,
const char *match_str, const char *match_str,
const struct component_master_ops *ops) const struct component_master_ops *ops)
......
...@@ -28,18 +28,21 @@ struct hda_component { ...@@ -28,18 +28,21 @@ struct hda_component {
void (*post_playback_hook)(struct device *dev, int action); void (*post_playback_hook)(struct device *dev, int action);
}; };
struct hda_component_parent {
struct hda_component comps[HDA_MAX_COMPONENTS];
};
#ifdef CONFIG_ACPI #ifdef CONFIG_ACPI
void hda_component_acpi_device_notify(struct hda_component *comps, int num_comps, void hda_component_acpi_device_notify(struct hda_component_parent *parent,
acpi_handle handle, u32 event, void *data); acpi_handle handle, u32 event, void *data);
int hda_component_manager_bind_acpi_notifications(struct hda_codec *cdc, int hda_component_manager_bind_acpi_notifications(struct hda_codec *cdc,
struct hda_component *comps, int num_comps, struct hda_component_parent *parent,
acpi_notify_handler handler, void *data); acpi_notify_handler handler, void *data);
void hda_component_manager_unbind_acpi_notifications(struct hda_codec *cdc, void hda_component_manager_unbind_acpi_notifications(struct hda_codec *cdc,
struct hda_component *comps, struct hda_component_parent *parent,
acpi_notify_handler handler); acpi_notify_handler handler);
#else #else
static inline void hda_component_acpi_device_notify(struct hda_component *comps, static inline void hda_component_acpi_device_notify(struct hda_component_parent *parent,
int num_comps,
acpi_handle handle, acpi_handle handle,
u32 event, u32 event,
void *data) void *data)
...@@ -47,8 +50,7 @@ static inline void hda_component_acpi_device_notify(struct hda_component *comps, ...@@ -47,8 +50,7 @@ static inline void hda_component_acpi_device_notify(struct hda_component *comps,
} }
static inline int hda_component_manager_bind_acpi_notifications(struct hda_codec *cdc, static inline int hda_component_manager_bind_acpi_notifications(struct hda_codec *cdc,
struct hda_component *comps, struct hda_component_parent *parent,
int num_comps,
acpi_notify_handler handler, acpi_notify_handler handler,
void *data) void *data)
...@@ -57,17 +59,16 @@ static inline int hda_component_manager_bind_acpi_notifications(struct hda_codec ...@@ -57,17 +59,16 @@ static inline int hda_component_manager_bind_acpi_notifications(struct hda_codec
} }
static inline void hda_component_manager_unbind_acpi_notifications(struct hda_codec *cdc, static inline void hda_component_manager_unbind_acpi_notifications(struct hda_codec *cdc,
struct hda_component *comps, struct hda_component_parent *parent,
acpi_notify_handler handler) acpi_notify_handler handler)
{ {
} }
#endif /* ifdef CONFIG_ACPI */ #endif /* ifdef CONFIG_ACPI */
void hda_component_manager_playback_hook(struct hda_component *comps, int num_comps, void hda_component_manager_playback_hook(struct hda_component_parent *parent, int action);
int action);
int hda_component_manager_init(struct hda_codec *cdc, int hda_component_manager_init(struct hda_codec *cdc,
struct hda_component *comps, int count, struct hda_component_parent *parent, int count,
const char *bus, const char *hid, const char *bus, const char *hid,
const char *match_str, const char *match_str,
const struct component_master_ops *ops); const struct component_master_ops *ops);
...@@ -75,13 +76,24 @@ int hda_component_manager_init(struct hda_codec *cdc, ...@@ -75,13 +76,24 @@ int hda_component_manager_init(struct hda_codec *cdc,
void hda_component_manager_free(struct hda_codec *cdc, void hda_component_manager_free(struct hda_codec *cdc,
const struct component_master_ops *ops); const struct component_master_ops *ops);
int hda_component_manager_bind(struct hda_codec *cdc, int hda_component_manager_bind(struct hda_codec *cdc, struct hda_component_parent *parent);
struct hda_component *comps, int count);
static inline struct hda_component *hda_component_from_index(struct hda_component_parent *parent,
int index)
{
if (!parent)
return NULL;
if (index < 0 || index >= ARRAY_SIZE(parent->comps))
return NULL;
return &parent->comps[index];
}
static inline void hda_component_manager_unbind(struct hda_codec *cdc, static inline void hda_component_manager_unbind(struct hda_codec *cdc,
struct hda_component *comps) struct hda_component_parent *parent)
{ {
component_unbind_all(hda_codec_dev(cdc), comps); component_unbind_all(hda_codec_dev(cdc), &parent->comps);
} }
#endif /* ifndef __HDA_COMPONENT_H__ */ #endif /* ifndef __HDA_COMPONENT_H__ */
...@@ -131,7 +131,7 @@ struct alc_spec { ...@@ -131,7 +131,7 @@ struct alc_spec {
u8 alc_mute_keycode_map[1]; u8 alc_mute_keycode_map[1];
/* component binding */ /* component binding */
struct hda_component comps[HDA_MAX_COMPONENTS]; struct hda_component_parent comps;
}; };
/* /*
...@@ -6793,8 +6793,7 @@ static void comp_acpi_device_notify(acpi_handle handle, u32 event, void *data) ...@@ -6793,8 +6793,7 @@ static void comp_acpi_device_notify(acpi_handle handle, u32 event, void *data)
codec_info(cdc, "ACPI Notification %d\n", event); codec_info(cdc, "ACPI Notification %d\n", event);
hda_component_acpi_device_notify(spec->comps, ARRAY_SIZE(spec->comps), hda_component_acpi_device_notify(&spec->comps, handle, event, data);
handle, event, data);
} }
static int comp_bind(struct device *dev) static int comp_bind(struct device *dev)
...@@ -6803,12 +6802,12 @@ static int comp_bind(struct device *dev) ...@@ -6803,12 +6802,12 @@ static int comp_bind(struct device *dev)
struct alc_spec *spec = cdc->spec; struct alc_spec *spec = cdc->spec;
int ret; int ret;
ret = hda_component_manager_bind(cdc, spec->comps, ARRAY_SIZE(spec->comps)); ret = hda_component_manager_bind(cdc, &spec->comps);
if (ret) if (ret)
return ret; return ret;
return hda_component_manager_bind_acpi_notifications(cdc, return hda_component_manager_bind_acpi_notifications(cdc,
spec->comps, ARRAY_SIZE(spec->comps), &spec->comps,
comp_acpi_device_notify, cdc); comp_acpi_device_notify, cdc);
} }
...@@ -6817,8 +6816,8 @@ static void comp_unbind(struct device *dev) ...@@ -6817,8 +6816,8 @@ static void comp_unbind(struct device *dev)
struct hda_codec *cdc = dev_to_hda_codec(dev); struct hda_codec *cdc = dev_to_hda_codec(dev);
struct alc_spec *spec = cdc->spec; struct alc_spec *spec = cdc->spec;
hda_component_manager_unbind_acpi_notifications(cdc, spec->comps, comp_acpi_device_notify); hda_component_manager_unbind_acpi_notifications(cdc, &spec->comps, comp_acpi_device_notify);
hda_component_manager_unbind(cdc, spec->comps); hda_component_manager_unbind(cdc, &spec->comps);
} }
static const struct component_master_ops comp_master_ops = { static const struct component_master_ops comp_master_ops = {
...@@ -6831,7 +6830,7 @@ static void comp_generic_playback_hook(struct hda_pcm_stream *hinfo, struct hda_ ...@@ -6831,7 +6830,7 @@ static void comp_generic_playback_hook(struct hda_pcm_stream *hinfo, struct hda_
{ {
struct alc_spec *spec = cdc->spec; struct alc_spec *spec = cdc->spec;
hda_component_manager_playback_hook(spec->comps, ARRAY_SIZE(spec->comps), action); hda_component_manager_playback_hook(&spec->comps, action);
} }
static void comp_generic_fixup(struct hda_codec *cdc, int action, const char *bus, static void comp_generic_fixup(struct hda_codec *cdc, int action, const char *bus,
...@@ -6842,7 +6841,7 @@ static void comp_generic_fixup(struct hda_codec *cdc, int action, const char *bu ...@@ -6842,7 +6841,7 @@ static void comp_generic_fixup(struct hda_codec *cdc, int action, const char *bu
switch (action) { switch (action) {
case HDA_FIXUP_ACT_PRE_PROBE: case HDA_FIXUP_ACT_PRE_PROBE:
ret = hda_component_manager_init(cdc, spec->comps, count, bus, hid, ret = hda_component_manager_init(cdc, &spec->comps, count, bus, hid,
match_str, &comp_master_ops); match_str, &comp_master_ops);
if (ret) if (ret)
return; return;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment