1*6014e902STakashi Iwai /* SPDX-License-Identifier: GPL-2.0-or-later */
2*6014e902STakashi Iwai /*
3*6014e902STakashi Iwai * HD audio Component Binding Interface
4*6014e902STakashi Iwai *
5*6014e902STakashi Iwai * Copyright (C) 2021 Cirrus Logic, Inc. and
6*6014e902STakashi Iwai * Cirrus Logic International Semiconductor Ltd.
7*6014e902STakashi Iwai */
8*6014e902STakashi Iwai
9*6014e902STakashi Iwai #ifndef __HDA_COMPONENT_H__
10*6014e902STakashi Iwai #define __HDA_COMPONENT_H__
11*6014e902STakashi Iwai
12*6014e902STakashi Iwai #include <linux/acpi.h>
13*6014e902STakashi Iwai #include <linux/component.h>
14*6014e902STakashi Iwai #include <linux/mutex.h>
15*6014e902STakashi Iwai #include <sound/hda_codec.h>
16*6014e902STakashi Iwai
17*6014e902STakashi Iwai #define HDA_MAX_COMPONENTS 4
18*6014e902STakashi Iwai #define HDA_MAX_NAME_SIZE 50
19*6014e902STakashi Iwai
20*6014e902STakashi Iwai struct hda_component {
21*6014e902STakashi Iwai struct device *dev;
22*6014e902STakashi Iwai char name[HDA_MAX_NAME_SIZE];
23*6014e902STakashi Iwai struct acpi_device *adev;
24*6014e902STakashi Iwai bool acpi_notifications_supported;
25*6014e902STakashi Iwai void (*acpi_notify)(acpi_handle handle, u32 event, struct device *dev);
26*6014e902STakashi Iwai void (*pre_playback_hook)(struct device *dev, int action);
27*6014e902STakashi Iwai void (*playback_hook)(struct device *dev, int action);
28*6014e902STakashi Iwai void (*post_playback_hook)(struct device *dev, int action);
29*6014e902STakashi Iwai };
30*6014e902STakashi Iwai
31*6014e902STakashi Iwai struct hda_component_parent {
32*6014e902STakashi Iwai struct mutex mutex;
33*6014e902STakashi Iwai struct hda_codec *codec;
34*6014e902STakashi Iwai struct hda_component comps[HDA_MAX_COMPONENTS];
35*6014e902STakashi Iwai };
36*6014e902STakashi Iwai
37*6014e902STakashi Iwai #ifdef CONFIG_ACPI
38*6014e902STakashi Iwai void hda_component_acpi_device_notify(struct hda_component_parent *parent,
39*6014e902STakashi Iwai acpi_handle handle, u32 event, void *data);
40*6014e902STakashi Iwai int hda_component_manager_bind_acpi_notifications(struct hda_codec *cdc,
41*6014e902STakashi Iwai struct hda_component_parent *parent,
42*6014e902STakashi Iwai acpi_notify_handler handler, void *data);
43*6014e902STakashi Iwai void hda_component_manager_unbind_acpi_notifications(struct hda_codec *cdc,
44*6014e902STakashi Iwai struct hda_component_parent *parent,
45*6014e902STakashi Iwai acpi_notify_handler handler);
46*6014e902STakashi Iwai #else
hda_component_acpi_device_notify(struct hda_component_parent * parent,acpi_handle handle,u32 event,void * data)47*6014e902STakashi Iwai static inline void hda_component_acpi_device_notify(struct hda_component_parent *parent,
48*6014e902STakashi Iwai acpi_handle handle,
49*6014e902STakashi Iwai u32 event,
50*6014e902STakashi Iwai void *data)
51*6014e902STakashi Iwai {
52*6014e902STakashi Iwai }
53*6014e902STakashi Iwai
hda_component_manager_bind_acpi_notifications(struct hda_codec * cdc,struct hda_component_parent * parent,acpi_notify_handler handler,void * data)54*6014e902STakashi Iwai static inline int hda_component_manager_bind_acpi_notifications(struct hda_codec *cdc,
55*6014e902STakashi Iwai struct hda_component_parent *parent,
56*6014e902STakashi Iwai acpi_notify_handler handler,
57*6014e902STakashi Iwai void *data)
58*6014e902STakashi Iwai
59*6014e902STakashi Iwai {
60*6014e902STakashi Iwai return 0;
61*6014e902STakashi Iwai }
62*6014e902STakashi Iwai
hda_component_manager_unbind_acpi_notifications(struct hda_codec * cdc,struct hda_component_parent * parent,acpi_notify_handler handler)63*6014e902STakashi Iwai static inline void hda_component_manager_unbind_acpi_notifications(struct hda_codec *cdc,
64*6014e902STakashi Iwai struct hda_component_parent *parent,
65*6014e902STakashi Iwai acpi_notify_handler handler)
66*6014e902STakashi Iwai {
67*6014e902STakashi Iwai }
68*6014e902STakashi Iwai #endif /* ifdef CONFIG_ACPI */
69*6014e902STakashi Iwai
70*6014e902STakashi Iwai void hda_component_manager_playback_hook(struct hda_component_parent *parent, int action);
71*6014e902STakashi Iwai
72*6014e902STakashi Iwai int hda_component_manager_init(struct hda_codec *cdc,
73*6014e902STakashi Iwai struct hda_component_parent *parent, int count,
74*6014e902STakashi Iwai const char *bus, const char *hid,
75*6014e902STakashi Iwai const char *match_str,
76*6014e902STakashi Iwai const struct component_master_ops *ops);
77*6014e902STakashi Iwai
78*6014e902STakashi Iwai void hda_component_manager_free(struct hda_component_parent *parent,
79*6014e902STakashi Iwai const struct component_master_ops *ops);
80*6014e902STakashi Iwai
81*6014e902STakashi Iwai int hda_component_manager_bind(struct hda_codec *cdc, struct hda_component_parent *parent);
82*6014e902STakashi Iwai
hda_component_from_index(struct hda_component_parent * parent,int index)83*6014e902STakashi Iwai static inline struct hda_component *hda_component_from_index(struct hda_component_parent *parent,
84*6014e902STakashi Iwai int index)
85*6014e902STakashi Iwai {
86*6014e902STakashi Iwai if (!parent)
87*6014e902STakashi Iwai return NULL;
88*6014e902STakashi Iwai
89*6014e902STakashi Iwai if (index < 0 || index >= ARRAY_SIZE(parent->comps))
90*6014e902STakashi Iwai return NULL;
91*6014e902STakashi Iwai
92*6014e902STakashi Iwai return &parent->comps[index];
93*6014e902STakashi Iwai }
94*6014e902STakashi Iwai
hda_component_manager_unbind(struct hda_codec * cdc,struct hda_component_parent * parent)95*6014e902STakashi Iwai static inline void hda_component_manager_unbind(struct hda_codec *cdc,
96*6014e902STakashi Iwai struct hda_component_parent *parent)
97*6014e902STakashi Iwai {
98*6014e902STakashi Iwai mutex_lock(&parent->mutex);
99*6014e902STakashi Iwai component_unbind_all(hda_codec_dev(cdc), parent);
100*6014e902STakashi Iwai mutex_unlock(&parent->mutex);
101*6014e902STakashi Iwai }
102*6014e902STakashi Iwai
103*6014e902STakashi Iwai #endif /* ifndef __HDA_COMPONENT_H__ */
104