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

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
Loading
Loading
Loading
Loading
+36 −29
Original line number Diff line number Diff line
@@ -15,35 +15,39 @@
#include "hda_local.h"

#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)
{
	struct hda_component *comp;
	int i;

	for (i = 0; i < num_comps; i++) {
		if (comps[i].dev && comps[i].acpi_notify)
			comps[i].acpi_notify(acpi_device_handle(comps[i].adev), event,
					     comps[i].dev);
	for (i = 0; i < ARRAY_SIZE(parent->comps); i++) {
		comp = hda_component_from_index(parent, i);
		if (comp->dev && comp->acpi_notify)
			comp->acpi_notify(acpi_device_handle(comp->adev), event, comp->dev);
	}
}
EXPORT_SYMBOL_NS_GPL(hda_component_acpi_device_notify, SND_HDA_SCODEC_COMPONENT);

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)
{
	bool support_notifications = false;
	struct acpi_device *adev;
	struct hda_component *comp;
	int ret;
	int i;

	adev = comps[0].adev;
	adev = parent->comps[0].adev;
	if (!acpi_device_handle(adev))
		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 ||
			comps[i].acpi_notifications_supported;
			comp->acpi_notifications_supported;
	}

	if (support_notifications) {
		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,
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,
						     struct hda_component *comps,
						     struct hda_component_parent *parent,
						     acpi_notify_handler handler)
{
	struct acpi_device *adev;
	int ret;

	adev = comps[0].adev;
	adev = parent->comps[0].adev;
	if (!acpi_device_handle(adev))
		return;

@@ -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);
#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;

	for (i = 0; i < num_comps; i++) {
		if (comps[i].dev && comps[i].pre_playback_hook)
			comps[i].pre_playback_hook(comps[i].dev, action);
	for (i = 0; i < ARRAY_SIZE(parent->comps); i++) {
		comp = hda_component_from_index(parent, i);
		if (comp->dev && comp->pre_playback_hook)
			comp->pre_playback_hook(comp->dev, action);
	}
	for (i = 0; i < num_comps; i++) {
		if (comps[i].dev && comps[i].playback_hook)
			comps[i].playback_hook(comps[i].dev, action);
	for (i = 0; i < ARRAY_SIZE(parent->comps); i++) {
		comp = hda_component_from_index(parent, i);
		if (comp->dev && comp->playback_hook)
			comp->playback_hook(comp->dev, action);
	}
	for (i = 0; i < num_comps; i++) {
		if (comps[i].dev && comps[i].post_playback_hook)
			comps[i].post_playback_hook(comps[i].dev, action);
	for (i = 0; i < ARRAY_SIZE(parent->comps); i++) {
		comp = hda_component_from_index(parent, i);
		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);
@@ -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,
			       struct hda_component *comps, int count)
			       struct hda_component_parent *parent)
{
	int i;

	/* Init shared data */
	for (i = 0; i < count; ++i) {
		memset(&comps[i], 0, sizeof(comps[i]));
		comps[i].codec = cdc;
	}
	/* Init shared and component specific data */
	memset(parent, 0, sizeof(*parent));
	for (i = 0; i < ARRAY_SIZE(parent->comps); i++)
		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);

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 *match_str,
			       const struct component_master_ops *ops)
+27 −15
Original line number Diff line number Diff line
@@ -28,18 +28,21 @@ struct hda_component {
	void (*post_playback_hook)(struct device *dev, int action);
};

struct hda_component_parent {
	struct hda_component comps[HDA_MAX_COMPONENTS];
};

#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);
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);
void hda_component_manager_unbind_acpi_notifications(struct hda_codec *cdc,
						     struct hda_component *comps,
						     struct hda_component_parent *parent,
						     acpi_notify_handler handler);
#else
static inline void hda_component_acpi_device_notify(struct hda_component *comps,
						    int num_comps,
static inline void hda_component_acpi_device_notify(struct hda_component_parent *parent,
						    acpi_handle handle,
						    u32 event,
						    void *data)
@@ -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,
								struct hda_component *comps,
								int num_comps,
								struct hda_component_parent *parent,
								acpi_notify_handler handler,
								void *data)

@@ -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,
								   struct hda_component *comps,
								   struct hda_component_parent *parent,
								   acpi_notify_handler handler)
{
}
#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);

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 *match_str,
			       const struct component_master_ops *ops);
@@ -75,13 +76,24 @@ int hda_component_manager_init(struct hda_codec *cdc,
void hda_component_manager_free(struct hda_codec *cdc,
				const struct component_master_ops *ops);

int hda_component_manager_bind(struct hda_codec *cdc,
			       struct hda_component *comps, int count);
int hda_component_manager_bind(struct hda_codec *cdc, struct hda_component_parent *parent);

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,
					       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__ */
+8 −9
Original line number Diff line number Diff line
@@ -131,7 +131,7 @@ struct alc_spec {
	u8 alc_mute_keycode_map[1];

	/* 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)

	codec_info(cdc, "ACPI Notification %d\n", event);

	hda_component_acpi_device_notify(spec->comps, ARRAY_SIZE(spec->comps),
					 handle, event, data);
	hda_component_acpi_device_notify(&spec->comps, handle, event, data);
}

static int comp_bind(struct device *dev)
@@ -6803,12 +6802,12 @@ static int comp_bind(struct device *dev)
	struct alc_spec *spec = cdc->spec;
	int ret;

	ret = hda_component_manager_bind(cdc, spec->comps, ARRAY_SIZE(spec->comps));
	ret = hda_component_manager_bind(cdc, &spec->comps);
	if (ret)
		return ret;

	return hda_component_manager_bind_acpi_notifications(cdc,
							     spec->comps, ARRAY_SIZE(spec->comps),
							     &spec->comps,
							     comp_acpi_device_notify, cdc);
}

@@ -6817,8 +6816,8 @@ static void comp_unbind(struct device *dev)
	struct hda_codec *cdc = dev_to_hda_codec(dev);
	struct alc_spec *spec = cdc->spec;

	hda_component_manager_unbind_acpi_notifications(cdc, spec->comps, comp_acpi_device_notify);
	hda_component_manager_unbind(cdc, spec->comps);
	hda_component_manager_unbind_acpi_notifications(cdc, &spec->comps, comp_acpi_device_notify);
	hda_component_manager_unbind(cdc, &spec->comps);
}

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_
{
	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,
@@ -6842,7 +6841,7 @@ static void comp_generic_fixup(struct hda_codec *cdc, int action, const char *bu

	switch (action) {
	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);
		if (ret)
			return;