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 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 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 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 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 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