blob: ec170c6b5248a7a04e88da622fe612738f958751 [file] [log] [blame]
Liam Girdwoodc0dfb4e2016-09-21 15:57:22 +01001/*
2 * Copyright (c) 2016, Intel Corporation
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 are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the Intel Corporation nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 *
28 * Author: Liam Girdwood <liam.r.girdwood@linux.intel.com>
29 */
30
31#include <stdint.h>
32#include <stddef.h>
33#include <errno.h>
34#include <reef/reef.h>
35#include <reef/lock.h>
36#include <reef/list.h>
37#include <reef/stream.h>
38#include <reef/alloc.h>
39#include <reef/audio/component.h>
40#include <reef/audio/pipeline.h>
Liam Girdwood425aa5e2017-06-06 20:34:10 +010041#include <uapi/ipc.h>
Liam Girdwoodc0dfb4e2016-09-21 15:57:22 +010042
43struct comp_data {
44 struct list_item list; /* list of components */
45 spinlock_t lock;
46};
47
48static struct comp_data *cd;
49
Liam Girdwood425aa5e2017-06-06 20:34:10 +010050static struct comp_driver *get_drv(uint32_t type)
Liam Girdwoodc0dfb4e2016-09-21 15:57:22 +010051{
52 struct list_item *clist;
Liam Girdwood425aa5e2017-06-06 20:34:10 +010053 struct comp_driver *drv = NULL;
Liam Girdwoodc0dfb4e2016-09-21 15:57:22 +010054
55 spin_lock(&cd->lock);
56
Liam Girdwood425aa5e2017-06-06 20:34:10 +010057 /* search driver list for driver type */
Liam Girdwoodc0dfb4e2016-09-21 15:57:22 +010058 list_for_item(clist, &cd->list) {
59
60 drv = container_of(clist, struct comp_driver, list);
Liam Girdwood425aa5e2017-06-06 20:34:10 +010061 if (drv->type == type)
Liam Girdwoodc0dfb4e2016-09-21 15:57:22 +010062 goto out;
Liam Girdwoodc0dfb4e2016-09-21 15:57:22 +010063 }
64
Liam Girdwood425aa5e2017-06-06 20:34:10 +010065 /* not found */
66 drv = NULL;
67
Liam Girdwoodc0dfb4e2016-09-21 15:57:22 +010068out:
69 spin_unlock(&cd->lock);
Liam Girdwood425aa5e2017-06-06 20:34:10 +010070 return drv;
71}
72
73struct comp_dev *comp_new(struct sof_ipc_comp *comp)
74{
75 struct comp_dev *cdev;
76 struct comp_driver *drv;
77
78 /* find the driver for our new component */
79 drv = get_drv(comp->type);
80 if (drv == NULL) {
81 trace_comp_error("eCD");
82 trace_value(comp->type);
83 return NULL;
84 }
85
86 /* create the new component */
87 cdev = drv->ops.new(comp);
88 if (cdev == NULL) {
89 trace_comp_error("eCN");
90 return NULL;
91 }
92
93 /* init component */
94 memcpy(&cdev->comp, comp, sizeof(*comp));
95 cdev->drv = drv;
Liam Girdwood425aa5e2017-06-06 20:34:10 +010096 spinlock_init(&cdev->lock);
97 list_init(&cdev->bsource_list);
98 list_init(&cdev->bsink_list);
99
100 return cdev;
Liam Girdwoodc0dfb4e2016-09-21 15:57:22 +0100101}
102
103int comp_register(struct comp_driver *drv)
104{
105 spin_lock(&cd->lock);
106 list_item_prepend(&drv->list, &cd->list);
107 spin_unlock(&cd->lock);
108
109 return 0;
110}
111
112void comp_unregister(struct comp_driver *drv)
113{
114 spin_lock(&cd->lock);
115 list_item_del(&drv->list);
116 spin_unlock(&cd->lock);
117}
118
Ranjani Sridharan62004082017-09-06 22:01:40 +0100119int comp_set_state(struct comp_dev *dev, int cmd)
120{
121 int ret = 0;
122
123 switch (cmd) {
124 case COMP_CMD_START:
Liam Girdwoode7b21922017-09-20 23:29:35 +0100125 if (dev->state == COMP_STATE_PREPARE) {
126 dev->state = COMP_STATE_ACTIVE;
127 } else {
128 trace_comp_error("CES");
Liam Girdwoodbe41b682017-09-21 16:48:18 +0100129 trace_value(dev->state);
Liam Girdwoode7b21922017-09-20 23:29:35 +0100130 ret = -EINVAL;
131 }
132 break;
Ranjani Sridharan62004082017-09-06 22:01:40 +0100133 case COMP_CMD_RELEASE:
Liam Girdwoode7b21922017-09-20 23:29:35 +0100134 if (dev->state == COMP_STATE_PAUSED) {
135 dev->state = COMP_STATE_ACTIVE;
136 } else {
137 trace_comp_error("CEr");
Liam Girdwoodbe41b682017-09-21 16:48:18 +0100138 trace_value(dev->state);
Liam Girdwoode7b21922017-09-20 23:29:35 +0100139 ret = -EINVAL;
140 }
Ranjani Sridharan62004082017-09-06 22:01:40 +0100141 break;
142 case COMP_CMD_STOP:
Liam Girdwoode7b21922017-09-20 23:29:35 +0100143 if (dev->state == COMP_STATE_ACTIVE) {
Liam Girdwood4ad0a662017-09-20 12:21:53 +0100144 dev->state = COMP_STATE_READY;
Ranjani Sridharan62004082017-09-06 22:01:40 +0100145 } else {
146 trace_comp_error("CEs");
Liam Girdwoodbe41b682017-09-21 16:48:18 +0100147 trace_value(dev->state);
Ranjani Sridharan62004082017-09-06 22:01:40 +0100148 ret = -EINVAL;
149 }
150 break;
151 case COMP_CMD_PAUSE:
152 /* only support pausing for running */
Liam Girdwood4ad0a662017-09-20 12:21:53 +0100153 if (dev->state == COMP_STATE_ACTIVE)
Ranjani Sridharan62004082017-09-06 22:01:40 +0100154 dev->state = COMP_STATE_PAUSED;
155 else {
156 trace_comp_error("CEp");
Liam Girdwoodbe41b682017-09-21 16:48:18 +0100157 trace_value(dev->state);
Ranjani Sridharan62004082017-09-06 22:01:40 +0100158 ret = -EINVAL;
159 }
160 break;
161 default:
Ranjani Sridharan62004082017-09-06 22:01:40 +0100162 break;
163 }
164
165 return ret;
166}
167
Liam Girdwoodc0dfb4e2016-09-21 15:57:22 +0100168void sys_comp_init(void)
169{
Liam Girdwood50f7b0e2017-06-06 12:52:15 +0100170 cd = rzalloc(RZONE_SYS, RFLAGS_NONE, sizeof(*cd));
Liam Girdwoodc0dfb4e2016-09-21 15:57:22 +0100171 list_init(&cd->list);
172 spinlock_init(&cd->lock);
173}