blob: fd0d65ef23b126a7916e32eca5e2b0e70e6b4921 [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:
125 case COMP_CMD_RELEASE:
Liam Girdwood4ad0a662017-09-20 12:21:53 +0100126 dev->state = COMP_STATE_ACTIVE;
Ranjani Sridharan62004082017-09-06 22:01:40 +0100127 break;
128 case COMP_CMD_STOP:
Liam Girdwood4ad0a662017-09-20 12:21:53 +0100129 if (dev->state == COMP_STATE_ACTIVE ||
Ranjani Sridharan62004082017-09-06 22:01:40 +0100130 dev->state == COMP_STATE_PAUSED) {
131 comp_buffer_reset(dev);
Liam Girdwood4ad0a662017-09-20 12:21:53 +0100132 dev->state = COMP_STATE_READY;
Ranjani Sridharan62004082017-09-06 22:01:40 +0100133 } else {
134 trace_comp_error("CEs");
135 ret = -EINVAL;
136 }
137 break;
138 case COMP_CMD_PAUSE:
139 /* only support pausing for running */
Liam Girdwood4ad0a662017-09-20 12:21:53 +0100140 if (dev->state == COMP_STATE_ACTIVE)
Ranjani Sridharan62004082017-09-06 22:01:40 +0100141 dev->state = COMP_STATE_PAUSED;
142 else {
143 trace_comp_error("CEp");
144 ret = -EINVAL;
145 }
146 break;
147 default:
148 trace_comp_error("CEd");
Liam Girdwood30743962017-09-08 14:28:15 +0100149 trace_value(cmd);
Ranjani Sridharan62004082017-09-06 22:01:40 +0100150 ret = -EINVAL;
151 break;
152 }
153
154 return ret;
155}
156
Liam Girdwoodc0dfb4e2016-09-21 15:57:22 +0100157void sys_comp_init(void)
158{
Liam Girdwood50f7b0e2017-06-06 12:52:15 +0100159 cd = rzalloc(RZONE_SYS, RFLAGS_NONE, sizeof(*cd));
Liam Girdwoodc0dfb4e2016-09-21 15:57:22 +0100160 list_init(&cd->list);
161 spinlock_init(&cd->lock);
162}