blob: f1100354c59144baaf82465a277fd0316a87fe93 [file] [log] [blame]
Jeeja KPdfe66a12015-06-11 14:11:47 +05301/*
2 * hdac-ext-bus.c - HD-audio extended core bus functions.
3 *
4 * Copyright (C) 2014-2015 Intel Corp
5 * Author: Jeeja KP <jeeja.kp@intel.com>
6 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; version 2 of the License.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
18 */
19
20#include <linux/module.h>
21#include <linux/slab.h>
22#include <sound/hdaudio_ext.h>
23
24MODULE_DESCRIPTION("HDA extended core");
25MODULE_LICENSE("GPL v2");
26
27/**
28 * snd_hdac_ext_bus_init - initialize a HD-audio extended bus
29 * @ebus: the pointer to extended bus object
30 * @dev: device pointer
31 * @ops: bus verb operators
32 * @io_ops: lowlevel I/O operators
33 *
34 * Returns 0 if successful, or a negative error code.
35 */
36int snd_hdac_ext_bus_init(struct hdac_ext_bus *ebus, struct device *dev,
37 const struct hdac_bus_ops *ops,
38 const struct hdac_io_ops *io_ops)
39{
40 int ret;
41 static int idx;
42
43 ret = snd_hdac_bus_init(&ebus->bus, dev, ops, io_ops);
44 if (ret < 0)
45 return ret;
46
47 INIT_LIST_HEAD(&ebus->hlink_list);
48 ebus->idx = idx++;
49
50 return 0;
51}
52EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_init);
53
54/**
55 * snd_hdac_ext_bus_exit - clean up a HD-audio extended bus
56 * @ebus: the pointer to extended bus object
57 */
58void snd_hdac_ext_bus_exit(struct hdac_ext_bus *ebus)
59{
60 snd_hdac_bus_exit(&ebus->bus);
61 WARN_ON(!list_empty(&ebus->hlink_list));
62}
63EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_exit);
64
65static void default_release(struct device *dev)
66{
67 snd_hdac_ext_bus_device_exit(container_of(dev, struct hdac_device, dev));
68}
69
70/**
71 * snd_hdac_ext_device_init - initialize the HDA extended codec base device
72 * @ebus: hdac extended bus to attach to
73 * @addr: codec address
74 *
75 * Returns zero for success or a negative error code.
76 */
77int snd_hdac_ext_bus_device_init(struct hdac_ext_bus *ebus, int addr)
78{
79 struct hdac_device *hdev = NULL;
80 struct hdac_bus *bus = ebus_to_hbus(ebus);
81 char name[15];
82 int ret;
83
84 hdev = kzalloc(sizeof(*hdev), GFP_KERNEL);
85 if (!hdev)
86 return -ENOMEM;
87
88 snprintf(name, sizeof(name), "ehdaudio%dD%d", ebus->idx, addr);
89
90 ret = snd_hdac_device_init(hdev, bus, name, addr);
91 if (ret < 0) {
92 dev_err(bus->dev, "device init failed for hdac device\n");
93 return ret;
94 }
95 hdev->type = HDA_DEV_ASOC;
96 hdev->dev.release = default_release;
97
98 ret = snd_hdac_device_register(hdev);
99 if (ret) {
100 dev_err(bus->dev, "failed to register hdac device\n");
101 snd_hdac_ext_bus_device_exit(hdev);
102 return ret;
103 }
104 return 0;
105}
106EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_device_init);
107
108/**
109 * snd_hdac_ext_bus_device_exit - clean up a HD-audio extended codec base device
110 * @hdev: hdac device to clean up
111 */
112void snd_hdac_ext_bus_device_exit(struct hdac_device *hdev)
113{
114 snd_hdac_device_exit(hdev);
115 kfree(hdev);
116}
117EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_device_exit);