source: mainline/uspace/drv/audio/hdaudio/hdaudio.c@ 8d070710

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 8d070710 was 7978d1e7, checked in by Jiri Svoboda <jiri@…>, 11 years ago

Initialize CORB and RIRB.

  • Property mode set to 100644
File size: 5.2 KB
Line 
1/*
2 * Copyright (c) 2014 Jiri Svoboda
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup hdaudio
30 * @{
31 */
32/** @file High Definition Audio driver
33 */
34
35#include <assert.h>
36#include <ddi.h>
37#include <device/hw_res_parsed.h>
38#include <stdio.h>
39#include <errno.h>
40#include <str_error.h>
41#include <ddf/driver.h>
42#include <ddf/log.h>
43
44#include "hdactl.h"
45#include "hdaudio.h"
46#include "spec/regs.h"
47
48#define NAME "hdaudio"
49
50static int hda_dev_add(ddf_dev_t *dev);
51static int hda_dev_remove(ddf_dev_t *dev);
52static int hda_dev_gone(ddf_dev_t *dev);
53static int hda_fun_online(ddf_fun_t *fun);
54static int hda_fun_offline(ddf_fun_t *fun);
55
56static driver_ops_t driver_ops = {
57 .dev_add = &hda_dev_add,
58 .dev_remove = &hda_dev_remove,
59 .dev_gone = &hda_dev_gone,
60 .fun_online = &hda_fun_online,
61 .fun_offline = &hda_fun_offline
62};
63
64static driver_t hda_driver = {
65 .name = NAME,
66 .driver_ops = &driver_ops
67};
68
69static int hda_dev_add(ddf_dev_t *dev)
70{
71 ddf_fun_t *fun_a;
72 hda_t *hda = NULL;
73 hw_res_list_parsed_t res;
74 void *regs;
75 int rc;
76
77 ddf_msg(LVL_NOTE, "hda_dev_add()");
78
79 hda = ddf_dev_data_alloc(dev, sizeof(hda_t));
80 if (hda == NULL) {
81 ddf_msg(LVL_ERROR, "Failed allocating soft state.\n");
82 rc = ENOMEM;
83 goto error;
84 }
85
86 ddf_msg(LVL_NOTE, "create parent sess");
87 hda->parent_sess = ddf_dev_parent_sess_create(dev,
88 EXCHANGE_SERIALIZE);
89 if (hda->parent_sess == NULL) {
90 ddf_msg(LVL_ERROR, "Failed connecting parent driver.\n");
91 rc = ENOMEM;
92 goto error;
93 }
94
95 ddf_msg(LVL_NOTE, "get HW res list");
96 hw_res_list_parsed_init(&res);
97 rc = hw_res_get_list_parsed(hda->parent_sess, &res, 0);
98 if (rc != EOK) {
99 ddf_msg(LVL_ERROR, "Failed getting resource list.\n");
100 goto error;
101 }
102
103 if (res.mem_ranges.count != 1) {
104 ddf_msg(LVL_ERROR, "Expected exactly one memory range.\n");
105 rc = EINVAL;
106 goto error;
107 }
108
109 hda->rwbase = RNGABS(res.mem_ranges.ranges[0]);
110 hda->rwsize = RNGSZ(res.mem_ranges.ranges[0]);
111
112 if (hda->rwsize < sizeof(hda_regs_t)) {
113 ddf_msg(LVL_ERROR, "Memory range is too small.");
114 rc = EINVAL;
115 goto error;
116 }
117
118 ddf_msg(LVL_NOTE, "enable PIO");
119 rc = pio_enable((void *)(uintptr_t)hda->rwbase, hda->rwsize, &regs);
120 if (rc != EOK) {
121 ddf_msg(LVL_ERROR, "Error enabling PIO range.");
122 goto error;
123 }
124
125 hda->regs = (hda_regs_t *)regs;
126
127 if (hda_ctl_init(hda) == NULL) {
128 rc = EIO;
129 goto error;
130 }
131
132 ddf_msg(LVL_NOTE, "create function");
133 fun_a = ddf_fun_create(dev, fun_exposed, "a");
134 if (fun_a == NULL) {
135 ddf_msg(LVL_ERROR, "Failed creating function 'a'.");
136 rc = ENOMEM;
137 goto error;
138 }
139
140 hda->fun_a = fun_a;
141
142 rc = ddf_fun_bind(fun_a);
143 if (rc != EOK) {
144 ddf_msg(LVL_ERROR, "Failed binding function 'a'.");
145 ddf_fun_destroy(fun_a);
146 goto error;
147 }
148
149 ddf_fun_add_to_category(fun_a, "virtual");
150 return EOK;
151error:
152 if (hda != NULL) {
153 if (hda->ctl != NULL)
154 hda_ctl_fini(hda->ctl);
155 if (hda->parent_sess != NULL)
156 async_hangup(hda->parent_sess);
157 }
158
159 return rc;
160}
161
162static int hda_dev_remove(ddf_dev_t *dev)
163{
164 hda_t *hda = (hda_t *)ddf_dev_data_get(dev);
165 int rc;
166
167 ddf_msg(LVL_DEBUG, "hda_dev_remove(%p)", dev);
168
169 if (hda->fun_a != NULL) {
170 rc = ddf_fun_offline(hda->fun_a);
171 if (rc != EOK)
172 return rc;
173
174 rc = ddf_fun_unbind(hda->fun_a);
175 if (rc != EOK)
176 return rc;
177 }
178
179 return EOK;
180}
181
182static int hda_dev_gone(ddf_dev_t *dev)
183{
184 hda_t *hda = (hda_t *)ddf_dev_data_get(dev);
185 int rc;
186
187 ddf_msg(LVL_DEBUG, "hda_dev_remove(%p)", dev);
188
189 if (hda->fun_a != NULL) {
190 rc = ddf_fun_unbind(hda->fun_a);
191 if (rc != EOK)
192 return rc;
193 }
194
195 return EOK;
196}
197
198static int hda_fun_online(ddf_fun_t *fun)
199{
200 ddf_msg(LVL_DEBUG, "hda_fun_online()");
201 return ddf_fun_online(fun);
202}
203
204static int hda_fun_offline(ddf_fun_t *fun)
205{
206 ddf_msg(LVL_DEBUG, "hda_fun_offline()");
207 return ddf_fun_offline(fun);
208}
209
210int main(int argc, char *argv[])
211{
212 printf(NAME ": High Definition Audio driver\n");
213 ddf_log_init(NAME);
214 return ddf_driver_main(&hda_driver);
215}
216
217/** @}
218 */
Note: See TracBrowser for help on using the repository browser.