ALSA: hda - add HDA default codec match function
authorVinod Koul <vinod.koul@intel.com>
Wed, 3 Jun 2015 06:54:31 +0000 (12:24 +0530)
committerTakashi Iwai <tiwai@suse.de>
Wed, 3 Jun 2015 09:58:49 +0000 (11:58 +0200)
HDA codec drivers can be matched using vendor id and revision id typically.
So provide a match function which does this and is loaded when driver hasn't
provided one (default behaviour)

Signed-off-by: Jeeja KP <jeeja.kp@intel.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
include/sound/hdaudio.h
sound/hda/hda_bus_type.c

index 64fff4db81bb2bf86d4956b3fc8eda021a2d6129..4caf1fde8a4f8af47e321f6caf1dca82245ac828 100644 (file)
@@ -27,6 +27,16 @@ struct hdac_widget_tree;
  */
 extern struct bus_type snd_hda_bus_type;
 
+/*
+ * HDA device table
+ */
+struct hda_device_id {
+       __u32 vendor_id;
+       __u32 rev_id;
+       const char *name;
+       unsigned long driver_data;
+};
+
 /*
  * generic arrays
  */
@@ -171,12 +181,16 @@ static inline void snd_hdac_power_down_pm(struct hdac_device *codec) {}
 struct hdac_driver {
        struct device_driver driver;
        int type;
+       const struct hda_device_id *id_table;
        int (*match)(struct hdac_device *dev, struct hdac_driver *drv);
        void (*unsol_event)(struct hdac_device *dev, unsigned int event);
 };
 
 #define drv_to_hdac_driver(_drv) container_of(_drv, struct hdac_driver, driver)
 
+const struct hda_device_id *
+hdac_get_device_id(struct hdac_device *hdev, struct hdac_driver *drv);
+
 /*
  * Bus verb operators
  */
index 519914a12e8aaf93893455e6542e559ea9a3b3ed..89c2711baaaf40c72753b50e05628e53cd0771ea 100644 (file)
 MODULE_DESCRIPTION("HD-audio bus");
 MODULE_LICENSE("GPL");
 
+/**
+ * hdac_get_device_id - gets the hdac device id entry
+ * @hdev: HD-audio core device
+ * @drv: HD-audio codec driver
+ *
+ * Compares the hdac device vendor_id and revision_id to the hdac_device
+ * driver id_table and returns the matching device id entry.
+ */
+const struct hda_device_id *
+hdac_get_device_id(struct hdac_device *hdev, struct hdac_driver *drv)
+{
+       if (drv->id_table) {
+               const struct hda_device_id *id  = drv->id_table;
+
+               while (id->vendor_id) {
+                       if (hdev->vendor_id == id->vendor_id &&
+                               (!id->rev_id || id->rev_id == hdev->revision_id))
+                               return id;
+                       id++;
+               }
+       }
+
+       return NULL;
+}
+EXPORT_SYMBOL_GPL(hdac_get_device_id);
+
+static int hdac_codec_match(struct hdac_device *dev, struct hdac_driver *drv)
+{
+       if (hdac_get_device_id(dev, drv))
+               return 1;
+       else
+               return 0;
+}
+
 static int hda_bus_match(struct device *dev, struct device_driver *drv)
 {
        struct hdac_device *hdev = dev_to_hdac_dev(dev);
@@ -17,8 +51,15 @@ static int hda_bus_match(struct device *dev, struct device_driver *drv)
 
        if (hdev->type != hdrv->type)
                return 0;
+
+       /*
+        * if driver provided a match function use that otherwise we will
+        * use hdac_codec_match function
+        */
        if (hdrv->match)
                return hdrv->match(hdev, hdrv);
+       else
+               return hdac_codec_match(hdev, hdrv);
        return 1;
 }