aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVinod Koul <vinod.koul@intel.com>2016-08-04 06:16:00 -0400
committerTakashi Iwai <tiwai@suse.de>2016-08-09 02:53:56 -0400
commit6720b38420a01d40dbeb8ee575eb601d612de691 (patch)
tree4e2e0da0197aff3f78b6c1cc104a9350f75f6e25
parent29b4817d4018df78086157ea3a55c1d9424a7cfc (diff)
ALSA: hda - move bus_parse_capabilities to core
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>
-rw-r--r--include/sound/hdaudio.h13
-rw-r--r--sound/hda/hdac_controller.c75
2 files changed, 88 insertions, 0 deletions
diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h
index 93e63c56f48f..56004ec8d441 100644
--- a/include/sound/hdaudio.h
+++ b/include/sound/hdaudio.h
@@ -245,6 +245,12 @@ struct hdac_rb {
245 245
246/* 246/*
247 * HD-audio bus base driver 247 * HD-audio bus base driver
248 *
249 * @ppcap: pp capabilities pointer
250 * @spbcap: SPIB capabilities pointer
251 * @mlcap: MultiLink capabilities pointer
252 * @gtscap: gts capabilities pointer
253 * @drsmcap: dma resume capabilities pointer
248 */ 254 */
249struct hdac_bus { 255struct hdac_bus {
250 struct device *dev; 256 struct device *dev;
@@ -256,6 +262,12 @@ struct hdac_bus {
256 void __iomem *remap_addr; 262 void __iomem *remap_addr;
257 int irq; 263 int irq;
258 264
265 void __iomem *ppcap;
266 void __iomem *spbcap;
267 void __iomem *mlcap;
268 void __iomem *gtscap;
269 void __iomem *drsmcap;
270
259 /* codec linked list */ 271 /* codec linked list */
260 struct list_head codec_list; 272 struct list_head codec_list;
261 unsigned int num_codecs; 273 unsigned int num_codecs;
@@ -335,6 +347,7 @@ static inline void snd_hdac_codec_link_down(struct hdac_device *codec)
335int snd_hdac_bus_send_cmd(struct hdac_bus *bus, unsigned int val); 347int snd_hdac_bus_send_cmd(struct hdac_bus *bus, unsigned int val);
336int snd_hdac_bus_get_response(struct hdac_bus *bus, unsigned int addr, 348int snd_hdac_bus_get_response(struct hdac_bus *bus, unsigned int addr,
337 unsigned int *res); 349 unsigned int *res);
350int snd_hdac_bus_parse_capabilities(struct hdac_bus *bus);
338int snd_hdac_link_power(struct hdac_device *codec, bool enable); 351int snd_hdac_link_power(struct hdac_device *codec, bool enable);
339 352
340bool snd_hdac_bus_init_chip(struct hdac_bus *bus, bool full_reset); 353bool snd_hdac_bus_init_chip(struct hdac_bus *bus, bool full_reset);
diff --git a/sound/hda/hdac_controller.c b/sound/hda/hdac_controller.c
index 9fee464e5d49..043065867656 100644
--- a/sound/hda/hdac_controller.c
+++ b/sound/hda/hdac_controller.c
@@ -255,6 +255,81 @@ int snd_hdac_bus_get_response(struct hdac_bus *bus, unsigned int addr,
255} 255}
256EXPORT_SYMBOL_GPL(snd_hdac_bus_get_response); 256EXPORT_SYMBOL_GPL(snd_hdac_bus_get_response);
257 257
258#define HDAC_MAX_CAPS 10
259/**
260 * snd_hdac_bus_parse_capabilities - parse capability structure
261 * @bus: the pointer to bus object
262 *
263 * Returns 0 if successful, or a negative error code.
264 */
265int snd_hdac_bus_parse_capabilities(struct hdac_bus *bus)
266{
267 unsigned int cur_cap;
268 unsigned int offset;
269 unsigned int counter = 0;
270
271 offset = snd_hdac_chip_readl(bus, LLCH);
272
273 /* Lets walk the linked capabilities list */
274 do {
275 cur_cap = _snd_hdac_chip_read(l, bus, offset);
276
277 dev_dbg(bus->dev, "Capability version: 0x%x\n",
278 (cur_cap & AZX_CAP_HDR_VER_MASK) >> AZX_CAP_HDR_VER_OFF);
279
280 dev_dbg(bus->dev, "HDA capability ID: 0x%x\n",
281 (cur_cap & AZX_CAP_HDR_ID_MASK) >> AZX_CAP_HDR_ID_OFF);
282
283 switch ((cur_cap & AZX_CAP_HDR_ID_MASK) >> AZX_CAP_HDR_ID_OFF) {
284 case AZX_ML_CAP_ID:
285 dev_dbg(bus->dev, "Found ML capability\n");
286 bus->mlcap = bus->remap_addr + offset;
287 break;
288
289 case AZX_GTS_CAP_ID:
290 dev_dbg(bus->dev, "Found GTS capability offset=%x\n", offset);
291 bus->gtscap = bus->remap_addr + offset;
292 break;
293
294 case AZX_PP_CAP_ID:
295 /* PP capability found, the Audio DSP is present */
296 dev_dbg(bus->dev, "Found PP capability offset=%x\n", offset);
297 bus->ppcap = bus->remap_addr + offset;
298 break;
299
300 case AZX_SPB_CAP_ID:
301 /* SPIB capability found, handler function */
302 dev_dbg(bus->dev, "Found SPB capability\n");
303 bus->spbcap = bus->remap_addr + offset;
304 break;
305
306 case AZX_DRSM_CAP_ID:
307 /* DMA resume capability found, handler function */
308 dev_dbg(bus->dev, "Found DRSM capability\n");
309 bus->drsmcap = bus->remap_addr + offset;
310 break;
311
312 default:
313 dev_dbg(bus->dev, "Unknown capability %d\n", cur_cap);
314 break;
315 }
316
317 counter++;
318
319 if (counter > HDAC_MAX_CAPS) {
320 dev_err(bus->dev, "We exceeded HDAC capabilities!!!\n");
321 break;
322 }
323
324 /* read the offset of next capability */
325 offset = cur_cap & AZX_CAP_HDR_NXT_PTR_MASK;
326
327 } while (offset);
328
329 return 0;
330}
331EXPORT_SYMBOL_GPL(snd_hdac_bus_parse_capabilities);
332
258/* 333/*
259 * Lowlevel interface 334 * Lowlevel interface
260 */ 335 */