1e3d280fcSTakashi Iwai /* 2e3d280fcSTakashi Iwai * HD-audio core stuff 3e3d280fcSTakashi Iwai */ 4e3d280fcSTakashi Iwai 5e3d280fcSTakashi Iwai #ifndef __SOUND_HDAUDIO_H 6e3d280fcSTakashi Iwai #define __SOUND_HDAUDIO_H 7e3d280fcSTakashi Iwai 8e3d280fcSTakashi Iwai #include <linux/device.h> 9d068ebc2STakashi Iwai #include <sound/hda_verbs.h> 10d068ebc2STakashi Iwai 117639a06cSTakashi Iwai /* codec node id */ 127639a06cSTakashi Iwai typedef u16 hda_nid_t; 137639a06cSTakashi Iwai 14d068ebc2STakashi Iwai struct hdac_bus; 15d068ebc2STakashi Iwai struct hdac_device; 16d068ebc2STakashi Iwai struct hdac_driver; 17*3256be65STakashi Iwai struct hdac_widget_tree; 18e3d280fcSTakashi Iwai 19e3d280fcSTakashi Iwai /* 20e3d280fcSTakashi Iwai * exported bus type 21e3d280fcSTakashi Iwai */ 22e3d280fcSTakashi Iwai extern struct bus_type snd_hda_bus_type; 23e3d280fcSTakashi Iwai 24e3d280fcSTakashi Iwai /* 25e3d280fcSTakashi Iwai * HD-audio codec base device 26e3d280fcSTakashi Iwai */ 27e3d280fcSTakashi Iwai struct hdac_device { 28e3d280fcSTakashi Iwai struct device dev; 29e3d280fcSTakashi Iwai int type; 30d068ebc2STakashi Iwai struct hdac_bus *bus; 31d068ebc2STakashi Iwai unsigned int addr; /* codec address */ 32d068ebc2STakashi Iwai struct list_head list; /* list point for bus codec_list */ 337639a06cSTakashi Iwai 347639a06cSTakashi Iwai hda_nid_t afg; /* AFG node id */ 357639a06cSTakashi Iwai hda_nid_t mfg; /* MFG node id */ 367639a06cSTakashi Iwai 377639a06cSTakashi Iwai /* ids */ 387639a06cSTakashi Iwai unsigned int vendor_id; 397639a06cSTakashi Iwai unsigned int subsystem_id; 407639a06cSTakashi Iwai unsigned int revision_id; 417639a06cSTakashi Iwai unsigned int afg_function_id; 427639a06cSTakashi Iwai unsigned int mfg_function_id; 437639a06cSTakashi Iwai unsigned int afg_unsol:1; 447639a06cSTakashi Iwai unsigned int mfg_unsol:1; 457639a06cSTakashi Iwai 467639a06cSTakashi Iwai unsigned int power_caps; /* FG power caps */ 477639a06cSTakashi Iwai 487639a06cSTakashi Iwai const char *vendor_name; /* codec vendor name */ 497639a06cSTakashi Iwai const char *chip_name; /* codec chip name */ 507639a06cSTakashi Iwai 517639a06cSTakashi Iwai /* widgets */ 527639a06cSTakashi Iwai unsigned int num_nodes; 537639a06cSTakashi Iwai hda_nid_t start_nid, end_nid; 547639a06cSTakashi Iwai 557639a06cSTakashi Iwai /* misc flags */ 567639a06cSTakashi Iwai atomic_t in_pm; /* suspend/resume being performed */ 57*3256be65STakashi Iwai 58*3256be65STakashi Iwai /* sysfs */ 59*3256be65STakashi Iwai struct hdac_widget_tree *widgets; 60e3d280fcSTakashi Iwai }; 61e3d280fcSTakashi Iwai 62e3d280fcSTakashi Iwai /* device/driver type used for matching */ 63e3d280fcSTakashi Iwai enum { 64e3d280fcSTakashi Iwai HDA_DEV_CORE, 65e3d280fcSTakashi Iwai HDA_DEV_LEGACY, 66e3d280fcSTakashi Iwai }; 67e3d280fcSTakashi Iwai 687639a06cSTakashi Iwai /* direction */ 697639a06cSTakashi Iwai enum { 707639a06cSTakashi Iwai HDA_INPUT, HDA_OUTPUT 717639a06cSTakashi Iwai }; 727639a06cSTakashi Iwai 73e3d280fcSTakashi Iwai #define dev_to_hdac_dev(_dev) container_of(_dev, struct hdac_device, dev) 74e3d280fcSTakashi Iwai 757639a06cSTakashi Iwai int snd_hdac_device_init(struct hdac_device *dev, struct hdac_bus *bus, 767639a06cSTakashi Iwai const char *name, unsigned int addr); 777639a06cSTakashi Iwai void snd_hdac_device_exit(struct hdac_device *dev); 78*3256be65STakashi Iwai int snd_hdac_device_register(struct hdac_device *codec); 79*3256be65STakashi Iwai void snd_hdac_device_unregister(struct hdac_device *codec); 807639a06cSTakashi Iwai 817639a06cSTakashi Iwai int snd_hdac_refresh_widgets(struct hdac_device *codec); 827639a06cSTakashi Iwai 837639a06cSTakashi Iwai unsigned int snd_hdac_make_cmd(struct hdac_device *codec, hda_nid_t nid, 847639a06cSTakashi Iwai unsigned int verb, unsigned int parm); 857639a06cSTakashi Iwai int snd_hdac_read(struct hdac_device *codec, hda_nid_t nid, 867639a06cSTakashi Iwai unsigned int verb, unsigned int parm, unsigned int *res); 877639a06cSTakashi Iwai int snd_hdac_read_parm(struct hdac_device *codec, hda_nid_t nid, int parm); 887639a06cSTakashi Iwai int snd_hdac_get_connections(struct hdac_device *codec, hda_nid_t nid, 897639a06cSTakashi Iwai hda_nid_t *conn_list, int max_conns); 907639a06cSTakashi Iwai int snd_hdac_get_sub_nodes(struct hdac_device *codec, hda_nid_t nid, 917639a06cSTakashi Iwai hda_nid_t *start_id); 927639a06cSTakashi Iwai 937639a06cSTakashi Iwai #ifdef CONFIG_PM 947639a06cSTakashi Iwai void snd_hdac_power_up(struct hdac_device *codec); 957639a06cSTakashi Iwai void snd_hdac_power_down(struct hdac_device *codec); 967639a06cSTakashi Iwai #else 977639a06cSTakashi Iwai static inline void snd_hdac_power_up(struct hdac_device *codec) {} 987639a06cSTakashi Iwai static inline void snd_hdac_power_down(struct hdac_device *codec) {} 997639a06cSTakashi Iwai #endif 1007639a06cSTakashi Iwai 101e3d280fcSTakashi Iwai /* 102e3d280fcSTakashi Iwai * HD-audio codec base driver 103e3d280fcSTakashi Iwai */ 104e3d280fcSTakashi Iwai struct hdac_driver { 105e3d280fcSTakashi Iwai struct device_driver driver; 106e3d280fcSTakashi Iwai int type; 107e3d280fcSTakashi Iwai int (*match)(struct hdac_device *dev, struct hdac_driver *drv); 108d068ebc2STakashi Iwai void (*unsol_event)(struct hdac_device *dev, unsigned int event); 109e3d280fcSTakashi Iwai }; 110e3d280fcSTakashi Iwai 111e3d280fcSTakashi Iwai #define drv_to_hdac_driver(_drv) container_of(_drv, struct hdac_driver, driver) 112e3d280fcSTakashi Iwai 113d068ebc2STakashi Iwai /* 114d068ebc2STakashi Iwai * HD-audio bus base driver 115d068ebc2STakashi Iwai */ 116d068ebc2STakashi Iwai struct hdac_bus_ops { 117d068ebc2STakashi Iwai /* send a single command */ 118d068ebc2STakashi Iwai int (*command)(struct hdac_bus *bus, unsigned int cmd); 119d068ebc2STakashi Iwai /* get a response from the last command */ 120d068ebc2STakashi Iwai int (*get_response)(struct hdac_bus *bus, unsigned int addr, 121d068ebc2STakashi Iwai unsigned int *res); 122d068ebc2STakashi Iwai }; 123d068ebc2STakashi Iwai 124d068ebc2STakashi Iwai #define HDA_UNSOL_QUEUE_SIZE 64 125d068ebc2STakashi Iwai 126d068ebc2STakashi Iwai struct hdac_bus { 127d068ebc2STakashi Iwai struct device *dev; 128d068ebc2STakashi Iwai const struct hdac_bus_ops *ops; 129d068ebc2STakashi Iwai 130d068ebc2STakashi Iwai /* codec linked list */ 131d068ebc2STakashi Iwai struct list_head codec_list; 132d068ebc2STakashi Iwai unsigned int num_codecs; 133d068ebc2STakashi Iwai 134d068ebc2STakashi Iwai /* link caddr -> codec */ 135d068ebc2STakashi Iwai struct hdac_device *caddr_tbl[HDA_MAX_CODEC_ADDRESS + 1]; 136d068ebc2STakashi Iwai 137d068ebc2STakashi Iwai /* unsolicited event queue */ 138d068ebc2STakashi Iwai u32 unsol_queue[HDA_UNSOL_QUEUE_SIZE * 2]; /* ring buffer */ 139d068ebc2STakashi Iwai unsigned int unsol_rp, unsol_wp; 140d068ebc2STakashi Iwai struct work_struct unsol_work; 141d068ebc2STakashi Iwai 142d068ebc2STakashi Iwai /* bit flags of powered codecs */ 143d068ebc2STakashi Iwai unsigned long codec_powered; 144d068ebc2STakashi Iwai 145d068ebc2STakashi Iwai /* flags */ 146d068ebc2STakashi Iwai bool sync_write:1; /* sync after verb write */ 147d068ebc2STakashi Iwai 148d068ebc2STakashi Iwai /* locks */ 149d068ebc2STakashi Iwai struct mutex cmd_mutex; 150d068ebc2STakashi Iwai }; 151d068ebc2STakashi Iwai 152d068ebc2STakashi Iwai int snd_hdac_bus_init(struct hdac_bus *bus, struct device *dev, 153d068ebc2STakashi Iwai const struct hdac_bus_ops *ops); 154d068ebc2STakashi Iwai void snd_hdac_bus_exit(struct hdac_bus *bus); 155d068ebc2STakashi Iwai int snd_hdac_bus_exec_verb(struct hdac_bus *bus, unsigned int addr, 156d068ebc2STakashi Iwai unsigned int cmd, unsigned int *res); 157d068ebc2STakashi Iwai int snd_hdac_bus_exec_verb_unlocked(struct hdac_bus *bus, unsigned int addr, 158d068ebc2STakashi Iwai unsigned int cmd, unsigned int *res); 159d068ebc2STakashi Iwai void snd_hdac_bus_queue_event(struct hdac_bus *bus, u32 res, u32 res_ex); 160d068ebc2STakashi Iwai 161d068ebc2STakashi Iwai int snd_hdac_bus_add_device(struct hdac_bus *bus, struct hdac_device *codec); 162d068ebc2STakashi Iwai void snd_hdac_bus_remove_device(struct hdac_bus *bus, 163d068ebc2STakashi Iwai struct hdac_device *codec); 164d068ebc2STakashi Iwai 1657639a06cSTakashi Iwai static inline void snd_hdac_codec_link_up(struct hdac_device *codec) 1667639a06cSTakashi Iwai { 1677639a06cSTakashi Iwai set_bit(codec->addr, &codec->bus->codec_powered); 1687639a06cSTakashi Iwai } 1697639a06cSTakashi Iwai 1707639a06cSTakashi Iwai static inline void snd_hdac_codec_link_down(struct hdac_device *codec) 1717639a06cSTakashi Iwai { 1727639a06cSTakashi Iwai clear_bit(codec->addr, &codec->bus->codec_powered); 1737639a06cSTakashi Iwai } 1747639a06cSTakashi Iwai 175e3d280fcSTakashi Iwai #endif /* __SOUND_HDAUDIO_H */ 176