ALSA: hda - move bus_parse_capabilities to core
authorVinod Koul <vinod.koul@intel.com>
Thu, 4 Aug 2016 10:16:00 +0000 (15:46 +0530)
committerTakashi Iwai <tiwai@suse.de>
Tue, 9 Aug 2016 06:53:56 +0000 (08:53 +0200)
HDA capability introduced recently are move to hdac core so that it can
be used by legacy driver as well. Also move the capability pointers up
to hdac_bus object.

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

index 93e63c5..56004ec 100644 (file)
@@ -245,6 +245,12 @@ struct hdac_rb {
 
 /*
  * HD-audio bus base driver
+ *
+ * @ppcap: pp capabilities pointer
+ * @spbcap: SPIB capabilities pointer
+ * @mlcap: MultiLink capabilities pointer
+ * @gtscap: gts capabilities pointer
+ * @drsmcap: dma resume capabilities pointer
  */
 struct hdac_bus {
        struct device *dev;
@@ -256,6 +262,12 @@ struct hdac_bus {
        void __iomem *remap_addr;
        int irq;
 
+       void __iomem *ppcap;
+       void __iomem *spbcap;
+       void __iomem *mlcap;
+       void __iomem *gtscap;
+       void __iomem *drsmcap;
+
        /* codec linked list */
        struct list_head codec_list;
        unsigned int num_codecs;
@@ -335,6 +347,7 @@ static inline void snd_hdac_codec_link_down(struct hdac_device *codec)
 int snd_hdac_bus_send_cmd(struct hdac_bus *bus, unsigned int val);
 int snd_hdac_bus_get_response(struct hdac_bus *bus, unsigned int addr,
                              unsigned int *res);
+int snd_hdac_bus_parse_capabilities(struct hdac_bus *bus);
 int snd_hdac_link_power(struct hdac_device *codec, bool enable);
 
 bool snd_hdac_bus_init_chip(struct hdac_bus *bus, bool full_reset);
index 9fee464..0430658 100644 (file)
@@ -255,6 +255,81 @@ int snd_hdac_bus_get_response(struct hdac_bus *bus, unsigned int addr,
 }
 EXPORT_SYMBOL_GPL(snd_hdac_bus_get_response);
 
+#define HDAC_MAX_CAPS 10
+/**
+ * snd_hdac_bus_parse_capabilities - parse capability structure
+ * @bus: the pointer to bus object
+ *
+ * Returns 0 if successful, or a negative error code.
+ */
+int snd_hdac_bus_parse_capabilities(struct hdac_bus *bus)
+{
+       unsigned int cur_cap;
+       unsigned int offset;
+       unsigned int counter = 0;
+
+       offset = snd_hdac_chip_readl(bus, LLCH);
+
+       /* Lets walk the linked capabilities list */
+       do {
+               cur_cap = _snd_hdac_chip_read(l, bus, offset);
+
+               dev_dbg(bus->dev, "Capability version: 0x%x\n",
+                       (cur_cap & AZX_CAP_HDR_VER_MASK) >> AZX_CAP_HDR_VER_OFF);
+
+               dev_dbg(bus->dev, "HDA capability ID: 0x%x\n",
+                       (cur_cap & AZX_CAP_HDR_ID_MASK) >> AZX_CAP_HDR_ID_OFF);
+
+               switch ((cur_cap & AZX_CAP_HDR_ID_MASK) >> AZX_CAP_HDR_ID_OFF) {
+               case AZX_ML_CAP_ID:
+                       dev_dbg(bus->dev, "Found ML capability\n");
+                       bus->mlcap = bus->remap_addr + offset;
+                       break;
+
+               case AZX_GTS_CAP_ID:
+                       dev_dbg(bus->dev, "Found GTS capability offset=%x\n", offset);
+                       bus->gtscap = bus->remap_addr + offset;
+                       break;
+
+               case AZX_PP_CAP_ID:
+                       /* PP capability found, the Audio DSP is present */
+                       dev_dbg(bus->dev, "Found PP capability offset=%x\n", offset);
+                       bus->ppcap = bus->remap_addr + offset;
+                       break;
+
+               case AZX_SPB_CAP_ID:
+                       /* SPIB capability found, handler function */
+                       dev_dbg(bus->dev, "Found SPB capability\n");
+                       bus->spbcap = bus->remap_addr + offset;
+                       break;
+
+               case AZX_DRSM_CAP_ID:
+                       /* DMA resume  capability found, handler function */
+                       dev_dbg(bus->dev, "Found DRSM capability\n");
+                       bus->drsmcap = bus->remap_addr + offset;
+                       break;
+
+               default:
+                       dev_dbg(bus->dev, "Unknown capability %d\n", cur_cap);
+                       break;
+               }
+
+               counter++;
+
+               if (counter > HDAC_MAX_CAPS) {
+                       dev_err(bus->dev, "We exceeded HDAC capabilities!!!\n");
+                       break;
+               }
+
+               /* read the offset of next capability */
+               offset = cur_cap & AZX_CAP_HDR_NXT_PTR_MASK;
+
+       } while (offset);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(snd_hdac_bus_parse_capabilities);
+
 /*
  * Lowlevel interface
  */