From: Jeeja KP jeeja.kp@intel.com
For device/driver matching, uses id table if device type is HDA_DEV_ASOC.
Signed-off-by: Jeeja KP jeeja.kp@intel.com Signed-off-by: Subhransu S. Prusty subhransu.s.prusty@intel.com Signed-off-by: Vinod Koul vinod.koul@intel.com --- include/sound/hdaudio.h | 16 ++++++++++++++++ sound/hda/hda_bus_type.c | 2 ++ sound/hda/hdac_bus.c | 24 ++++++++++++++++++++++++ 3 files changed, 42 insertions(+)
diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h index 1652764..3628a09 100644 --- a/include/sound/hdaudio.h +++ b/include/sound/hdaudio.h @@ -42,6 +42,14 @@ struct hdac_widget_tree; */ extern struct bus_type snd_hda_bus_type;
+/*HDA device table*/ +#define HDA_NAME_SIZE 20 +struct hdac_device_id { + __u32 id; + char name[HDA_NAME_SIZE]; + unsigned long driver_data; +}; + /* * HD-audio codec base device */ @@ -82,6 +90,8 @@ struct hdac_device {
/* sysfs */ struct hdac_widget_tree *widgets; + + const struct hdac_device_id *id_entry; };
/* device/driver type used for matching */ @@ -96,6 +106,9 @@ enum { HDA_INPUT, HDA_OUTPUT };
+ +#define hda_get_device_id(pdev) ((pdev)->id_entry) + #define dev_to_hdac_dev(_dev) container_of(_dev, struct hdac_device, dev)
int snd_hdac_device_init(struct hdac_device *dev, struct hdac_bus *bus, @@ -126,12 +139,14 @@ static inline void snd_hdac_power_up(struct hdac_device *codec) {} static inline void snd_hdac_power_down(struct hdac_device *codec) {} #endif
+ /* * HD-audio codec base driver */ struct hdac_driver { struct device_driver driver; int type; + struct hdac_device_id *id_table; int (*match)(struct hdac_device *dev, struct hdac_driver *drv); void (*unsol_event)(struct hdac_device *dev, unsigned int event); }; @@ -248,6 +263,7 @@ void snd_hdac_bus_queue_event(struct hdac_bus *bus, u32 res, u32 res_ex); int snd_hdac_bus_add_device(struct hdac_bus *bus, struct hdac_device *codec); void snd_hdac_bus_remove_device(struct hdac_bus *bus, struct hdac_device *codec); +int snd_hdac_bus_match_id(struct hdac_device *dev, struct hdac_driver *drv);
static inline void snd_hdac_codec_link_up(struct hdac_device *codec) { diff --git a/sound/hda/hda_bus_type.c b/sound/hda/hda_bus_type.c index 519914a..8899c56 100644 --- a/sound/hda/hda_bus_type.c +++ b/sound/hda/hda_bus_type.c @@ -19,6 +19,8 @@ static int hda_bus_match(struct device *dev, struct device_driver *drv) return 0; if (hdrv->match) return hdrv->match(hdev, hdrv); + if (hdrv->id_table) + return snd_hdac_bus_match_id(hdev, hdrv); return 1; }
diff --git a/sound/hda/hdac_bus.c b/sound/hda/hdac_bus.c index 3294fd4..f0ee295 100644 --- a/sound/hda/hdac_bus.c +++ b/sound/hda/hdac_bus.c @@ -195,3 +195,27 @@ void snd_hdac_bus_remove_device(struct hdac_bus *bus, bus->num_codecs--; } EXPORT_SYMBOL_GPL(snd_hdac_bus_remove_device); + +/** + * snd_hdac_bus_match_id - bind hdac device to hdac driver. + * @hdev: device. + * @hdrv: driver. + * + */ +int snd_hdac_bus_match_id(struct hdac_device *dev, + struct hdac_driver *drv) +{ + if (drv->id_table) { + struct hdac_device_id *id = drv->id_table; + + while (id->name[0]) { + if (dev->vendor_id == id->id) { + dev->id_entry = id; + return 1; + } + id++; + } + } + return 0; +} +EXPORT_SYMBOL_GPL(snd_hdac_bus_match_id);