xref: /aosp_15_r20/external/tinycompress/compress_plugin.c (revision de0de75214967e333758016dcf6345eb33d24356)
1*de0de752SAndroid Build Coastguard Worker /* compress_plugin.c
2*de0de752SAndroid Build Coastguard Worker **
3*de0de752SAndroid Build Coastguard Worker ** Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
4*de0de752SAndroid Build Coastguard Worker **
5*de0de752SAndroid Build Coastguard Worker ** Redistribution and use in source and binary forms, with or without
6*de0de752SAndroid Build Coastguard Worker ** modification, are permitted provided that the following conditions are
7*de0de752SAndroid Build Coastguard Worker ** met:
8*de0de752SAndroid Build Coastguard Worker **   * Redistributions of source code must retain the above copyright
9*de0de752SAndroid Build Coastguard Worker **     notice, this list of conditions and the following disclaimer.
10*de0de752SAndroid Build Coastguard Worker **   * Redistributions in binary form must reproduce the above
11*de0de752SAndroid Build Coastguard Worker **     copyright notice, this list of conditions and the following
12*de0de752SAndroid Build Coastguard Worker **     disclaimer in the documentation and/or other materials provided
13*de0de752SAndroid Build Coastguard Worker **     with the distribution.
14*de0de752SAndroid Build Coastguard Worker **   * Neither the name of The Linux Foundation nor the names of its
15*de0de752SAndroid Build Coastguard Worker **     contributors may be used to endorse or promote products derived
16*de0de752SAndroid Build Coastguard Worker **     from this software without specific prior written permission.
17*de0de752SAndroid Build Coastguard Worker **
18*de0de752SAndroid Build Coastguard Worker ** THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
19*de0de752SAndroid Build Coastguard Worker ** WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
20*de0de752SAndroid Build Coastguard Worker ** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
21*de0de752SAndroid Build Coastguard Worker ** ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
22*de0de752SAndroid Build Coastguard Worker ** BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23*de0de752SAndroid Build Coastguard Worker ** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24*de0de752SAndroid Build Coastguard Worker ** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
25*de0de752SAndroid Build Coastguard Worker ** BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26*de0de752SAndroid Build Coastguard Worker ** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
27*de0de752SAndroid Build Coastguard Worker ** OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
28*de0de752SAndroid Build Coastguard Worker ** IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29*de0de752SAndroid Build Coastguard Worker **/
30*de0de752SAndroid Build Coastguard Worker 
31*de0de752SAndroid Build Coastguard Worker #include <stdio.h>
32*de0de752SAndroid Build Coastguard Worker #include <stdlib.h>
33*de0de752SAndroid Build Coastguard Worker #include <stdint.h>
34*de0de752SAndroid Build Coastguard Worker #include <fcntl.h>
35*de0de752SAndroid Build Coastguard Worker #include <stdarg.h>
36*de0de752SAndroid Build Coastguard Worker #include <string.h>
37*de0de752SAndroid Build Coastguard Worker #include <errno.h>
38*de0de752SAndroid Build Coastguard Worker #include <unistd.h>
39*de0de752SAndroid Build Coastguard Worker #include <poll.h>
40*de0de752SAndroid Build Coastguard Worker #include <dlfcn.h>
41*de0de752SAndroid Build Coastguard Worker 
42*de0de752SAndroid Build Coastguard Worker #include <sys/ioctl.h>
43*de0de752SAndroid Build Coastguard Worker #include <linux/ioctl.h>
44*de0de752SAndroid Build Coastguard Worker #include <sound/asound.h>
45*de0de752SAndroid Build Coastguard Worker #include "tinycompress/compress_plugin.h"
46*de0de752SAndroid Build Coastguard Worker #include "sound/compress_offload.h"
47*de0de752SAndroid Build Coastguard Worker #include "compress_ops.h"
48*de0de752SAndroid Build Coastguard Worker #include "snd_utils.h"
49*de0de752SAndroid Build Coastguard Worker 
50*de0de752SAndroid Build Coastguard Worker #define U32_MAX	((uint32_t)~0U)
51*de0de752SAndroid Build Coastguard Worker 
52*de0de752SAndroid Build Coastguard Worker enum {
53*de0de752SAndroid Build Coastguard Worker 	COMPRESS_PLUG_STATE_OPEN,
54*de0de752SAndroid Build Coastguard Worker 	COMPRESS_PLUG_STATE_SETUP,
55*de0de752SAndroid Build Coastguard Worker 	COMPRESS_PLUG_STATE_PREPARED,
56*de0de752SAndroid Build Coastguard Worker 	COMPRESS_PLUG_STATE_PAUSE,
57*de0de752SAndroid Build Coastguard Worker 	COMPRESS_PLUG_STATE_RUNNING,
58*de0de752SAndroid Build Coastguard Worker };
59*de0de752SAndroid Build Coastguard Worker 
60*de0de752SAndroid Build Coastguard Worker struct compress_plug_data {
61*de0de752SAndroid Build Coastguard Worker 	unsigned int card;
62*de0de752SAndroid Build Coastguard Worker 	unsigned int device;
63*de0de752SAndroid Build Coastguard Worker 	unsigned int fd;
64*de0de752SAndroid Build Coastguard Worker 	unsigned int flags;
65*de0de752SAndroid Build Coastguard Worker 
66*de0de752SAndroid Build Coastguard Worker 	void *dl_hdl;
67*de0de752SAndroid Build Coastguard Worker 	COMPRESS_PLUGIN_OPEN_FN_PTR();
68*de0de752SAndroid Build Coastguard Worker 
69*de0de752SAndroid Build Coastguard Worker 	struct compress_plugin *plugin;
70*de0de752SAndroid Build Coastguard Worker 	void *dev_node;
71*de0de752SAndroid Build Coastguard Worker };
72*de0de752SAndroid Build Coastguard Worker 
compress_plug_get_caps(struct compress_plug_data * plug_data,struct snd_compr_caps * caps)73*de0de752SAndroid Build Coastguard Worker static int compress_plug_get_caps(struct compress_plug_data *plug_data,
74*de0de752SAndroid Build Coastguard Worker 		struct snd_compr_caps *caps)
75*de0de752SAndroid Build Coastguard Worker {
76*de0de752SAndroid Build Coastguard Worker 	struct compress_plugin *plugin = plug_data->plugin;
77*de0de752SAndroid Build Coastguard Worker 
78*de0de752SAndroid Build Coastguard Worker 	return plugin->ops->get_caps(plugin, caps);
79*de0de752SAndroid Build Coastguard Worker }
80*de0de752SAndroid Build Coastguard Worker 
compress_plug_set_params(struct compress_plug_data * plug_data,struct snd_compr_params * params)81*de0de752SAndroid Build Coastguard Worker static int compress_plug_set_params(struct compress_plug_data *plug_data,
82*de0de752SAndroid Build Coastguard Worker 		struct snd_compr_params *params)
83*de0de752SAndroid Build Coastguard Worker {
84*de0de752SAndroid Build Coastguard Worker 	struct compress_plugin *plugin = plug_data->plugin;
85*de0de752SAndroid Build Coastguard Worker 	int rc;
86*de0de752SAndroid Build Coastguard Worker 
87*de0de752SAndroid Build Coastguard Worker 	if (plugin->state == COMPRESS_PLUG_STATE_RUNNING)
88*de0de752SAndroid Build Coastguard Worker 		return plugin->ops->set_params(plugin, params);
89*de0de752SAndroid Build Coastguard Worker 	else if (plugin->state != COMPRESS_PLUG_STATE_OPEN)
90*de0de752SAndroid Build Coastguard Worker 		return -EBADFD;
91*de0de752SAndroid Build Coastguard Worker 
92*de0de752SAndroid Build Coastguard Worker 	if (params->buffer.fragment_size == 0 ||
93*de0de752SAndroid Build Coastguard Worker 	   params->buffer.fragments > U32_MAX / params->buffer.fragment_size ||
94*de0de752SAndroid Build Coastguard Worker 	   params->buffer.fragments == 0)
95*de0de752SAndroid Build Coastguard Worker 		return -EINVAL;
96*de0de752SAndroid Build Coastguard Worker 
97*de0de752SAndroid Build Coastguard Worker 	rc = plugin->ops->set_params(plugin, params);
98*de0de752SAndroid Build Coastguard Worker 	if (!rc)
99*de0de752SAndroid Build Coastguard Worker 		plugin->state = COMPRESS_PLUG_STATE_SETUP;
100*de0de752SAndroid Build Coastguard Worker 
101*de0de752SAndroid Build Coastguard Worker 	return rc;
102*de0de752SAndroid Build Coastguard Worker }
103*de0de752SAndroid Build Coastguard Worker 
compress_plug_avail(struct compress_plug_data * plug_data,struct snd_compr_avail * avail)104*de0de752SAndroid Build Coastguard Worker static int compress_plug_avail(struct compress_plug_data *plug_data,
105*de0de752SAndroid Build Coastguard Worker 		struct snd_compr_avail *avail)
106*de0de752SAndroid Build Coastguard Worker {
107*de0de752SAndroid Build Coastguard Worker 	struct compress_plugin *plugin = plug_data->plugin;
108*de0de752SAndroid Build Coastguard Worker 
109*de0de752SAndroid Build Coastguard Worker 	return plugin->ops->avail(plugin, avail);
110*de0de752SAndroid Build Coastguard Worker }
111*de0de752SAndroid Build Coastguard Worker 
compress_plug_tstamp(struct compress_plug_data * plug_data,struct snd_compr_tstamp * tstamp)112*de0de752SAndroid Build Coastguard Worker static int compress_plug_tstamp(struct compress_plug_data *plug_data,
113*de0de752SAndroid Build Coastguard Worker 		struct snd_compr_tstamp *tstamp)
114*de0de752SAndroid Build Coastguard Worker {
115*de0de752SAndroid Build Coastguard Worker 	struct compress_plugin *plugin = plug_data->plugin;
116*de0de752SAndroid Build Coastguard Worker 
117*de0de752SAndroid Build Coastguard Worker 	if (plugin->state != COMPRESS_PLUG_STATE_SETUP)
118*de0de752SAndroid Build Coastguard Worker 		return -EBADFD;
119*de0de752SAndroid Build Coastguard Worker 
120*de0de752SAndroid Build Coastguard Worker 	return plugin->ops->tstamp(plugin, tstamp);
121*de0de752SAndroid Build Coastguard Worker }
122*de0de752SAndroid Build Coastguard Worker 
compress_plug_start(struct compress_plug_data * plug_data)123*de0de752SAndroid Build Coastguard Worker static int compress_plug_start(struct compress_plug_data *plug_data)
124*de0de752SAndroid Build Coastguard Worker {
125*de0de752SAndroid Build Coastguard Worker 	struct compress_plugin *plugin = plug_data->plugin;
126*de0de752SAndroid Build Coastguard Worker 	int rc;
127*de0de752SAndroid Build Coastguard Worker 
128*de0de752SAndroid Build Coastguard Worker 	/* for playback moved to prepare in first write */
129*de0de752SAndroid Build Coastguard Worker 	/* for capture: move to prepare state set params */
130*de0de752SAndroid Build Coastguard Worker 	 /* TODO: add direction in set params */
131*de0de752SAndroid Build Coastguard Worker 	if (plugin->state != COMPRESS_PLUG_STATE_PREPARED)
132*de0de752SAndroid Build Coastguard Worker 		return -EBADFD;
133*de0de752SAndroid Build Coastguard Worker 
134*de0de752SAndroid Build Coastguard Worker 	rc = plugin->ops->start(plugin);
135*de0de752SAndroid Build Coastguard Worker 	if (!rc)
136*de0de752SAndroid Build Coastguard Worker 		plugin->state = COMPRESS_PLUG_STATE_RUNNING;
137*de0de752SAndroid Build Coastguard Worker 
138*de0de752SAndroid Build Coastguard Worker 	return rc;
139*de0de752SAndroid Build Coastguard Worker }
140*de0de752SAndroid Build Coastguard Worker 
compress_plug_stop(struct compress_plug_data * plug_data)141*de0de752SAndroid Build Coastguard Worker static int compress_plug_stop(struct compress_plug_data *plug_data)
142*de0de752SAndroid Build Coastguard Worker {
143*de0de752SAndroid Build Coastguard Worker 	struct compress_plugin *plugin = plug_data->plugin;
144*de0de752SAndroid Build Coastguard Worker 	int rc;
145*de0de752SAndroid Build Coastguard Worker 
146*de0de752SAndroid Build Coastguard Worker 	if (plugin->state == COMPRESS_PLUG_STATE_PREPARED ||
147*de0de752SAndroid Build Coastguard Worker 		plugin->state == COMPRESS_PLUG_STATE_SETUP)
148*de0de752SAndroid Build Coastguard Worker 		return -EBADFD;
149*de0de752SAndroid Build Coastguard Worker 
150*de0de752SAndroid Build Coastguard Worker 	rc = plugin->ops->stop(plugin);
151*de0de752SAndroid Build Coastguard Worker 	if (!rc)
152*de0de752SAndroid Build Coastguard Worker 		plugin->state = COMPRESS_PLUG_STATE_SETUP;
153*de0de752SAndroid Build Coastguard Worker 
154*de0de752SAndroid Build Coastguard Worker 	return rc;
155*de0de752SAndroid Build Coastguard Worker }
156*de0de752SAndroid Build Coastguard Worker 
compress_plug_pause(struct compress_plug_data * plug_data)157*de0de752SAndroid Build Coastguard Worker static int compress_plug_pause(struct compress_plug_data *plug_data)
158*de0de752SAndroid Build Coastguard Worker {
159*de0de752SAndroid Build Coastguard Worker 	struct compress_plugin *plugin = plug_data->plugin;
160*de0de752SAndroid Build Coastguard Worker 	int rc;
161*de0de752SAndroid Build Coastguard Worker 
162*de0de752SAndroid Build Coastguard Worker 	if (plugin->state != COMPRESS_PLUG_STATE_RUNNING)
163*de0de752SAndroid Build Coastguard Worker 		return -EBADFD;
164*de0de752SAndroid Build Coastguard Worker 
165*de0de752SAndroid Build Coastguard Worker 	rc = plugin->ops->pause(plugin);
166*de0de752SAndroid Build Coastguard Worker 	if (!rc)
167*de0de752SAndroid Build Coastguard Worker 		plugin->state = COMPRESS_PLUG_STATE_PAUSE;
168*de0de752SAndroid Build Coastguard Worker 
169*de0de752SAndroid Build Coastguard Worker 	return rc;
170*de0de752SAndroid Build Coastguard Worker }
171*de0de752SAndroid Build Coastguard Worker 
compress_plug_resume(struct compress_plug_data * plug_data)172*de0de752SAndroid Build Coastguard Worker static int compress_plug_resume(struct compress_plug_data *plug_data)
173*de0de752SAndroid Build Coastguard Worker {
174*de0de752SAndroid Build Coastguard Worker 	struct compress_plugin *plugin = plug_data->plugin;
175*de0de752SAndroid Build Coastguard Worker 	int rc;
176*de0de752SAndroid Build Coastguard Worker 
177*de0de752SAndroid Build Coastguard Worker 	if (plugin->state != COMPRESS_PLUG_STATE_PAUSE)
178*de0de752SAndroid Build Coastguard Worker 		return -EBADFD;
179*de0de752SAndroid Build Coastguard Worker 
180*de0de752SAndroid Build Coastguard Worker 	rc = plugin->ops->resume(plugin);
181*de0de752SAndroid Build Coastguard Worker 	if (!rc)
182*de0de752SAndroid Build Coastguard Worker 		plugin->state = COMPRESS_PLUG_STATE_RUNNING;
183*de0de752SAndroid Build Coastguard Worker 
184*de0de752SAndroid Build Coastguard Worker 	return rc;
185*de0de752SAndroid Build Coastguard Worker }
186*de0de752SAndroid Build Coastguard Worker 
compress_plug_drain(struct compress_plug_data * plug_data)187*de0de752SAndroid Build Coastguard Worker static int compress_plug_drain(struct compress_plug_data *plug_data)
188*de0de752SAndroid Build Coastguard Worker {
189*de0de752SAndroid Build Coastguard Worker 	struct compress_plugin *plugin = plug_data->plugin;
190*de0de752SAndroid Build Coastguard Worker 
191*de0de752SAndroid Build Coastguard Worker 	/* check if we will allow in pause */
192*de0de752SAndroid Build Coastguard Worker 	if (plugin->state != COMPRESS_PLUG_STATE_RUNNING)
193*de0de752SAndroid Build Coastguard Worker 		return -EBADFD;
194*de0de752SAndroid Build Coastguard Worker 
195*de0de752SAndroid Build Coastguard Worker 	return plugin->ops->drain(plugin);
196*de0de752SAndroid Build Coastguard Worker }
197*de0de752SAndroid Build Coastguard Worker 
compress_plug_partial_drain(struct compress_plug_data * plug_data)198*de0de752SAndroid Build Coastguard Worker static int compress_plug_partial_drain(struct compress_plug_data *plug_data)
199*de0de752SAndroid Build Coastguard Worker {
200*de0de752SAndroid Build Coastguard Worker 	struct compress_plugin *plugin = plug_data->plugin;
201*de0de752SAndroid Build Coastguard Worker 
202*de0de752SAndroid Build Coastguard Worker 	 /* check if we will allow in pause */
203*de0de752SAndroid Build Coastguard Worker 	if (plugin->state != COMPRESS_PLUG_STATE_RUNNING)
204*de0de752SAndroid Build Coastguard Worker 		return -EBADFD;
205*de0de752SAndroid Build Coastguard Worker 
206*de0de752SAndroid Build Coastguard Worker 	return plugin->ops->partial_drain(plugin);
207*de0de752SAndroid Build Coastguard Worker }
208*de0de752SAndroid Build Coastguard Worker 
compress_plug_next_track(struct compress_plug_data * plug_data)209*de0de752SAndroid Build Coastguard Worker static int compress_plug_next_track(struct compress_plug_data *plug_data)
210*de0de752SAndroid Build Coastguard Worker {
211*de0de752SAndroid Build Coastguard Worker 	struct compress_plugin *plugin = plug_data->plugin;
212*de0de752SAndroid Build Coastguard Worker 
213*de0de752SAndroid Build Coastguard Worker 	/* transion to next track applied to running stream only */
214*de0de752SAndroid Build Coastguard Worker 	if (plugin->state != COMPRESS_PLUG_STATE_RUNNING)
215*de0de752SAndroid Build Coastguard Worker 		return -EBADFD;
216*de0de752SAndroid Build Coastguard Worker 
217*de0de752SAndroid Build Coastguard Worker 	return plugin->ops->next_track(plugin);
218*de0de752SAndroid Build Coastguard Worker }
219*de0de752SAndroid Build Coastguard Worker 
compress_plug_ioctl(void * data,unsigned int cmd,...)220*de0de752SAndroid Build Coastguard Worker static int compress_plug_ioctl(void *data, unsigned int cmd, ...)
221*de0de752SAndroid Build Coastguard Worker {
222*de0de752SAndroid Build Coastguard Worker 	struct compress_plug_data *plug_data = data;
223*de0de752SAndroid Build Coastguard Worker 	struct compress_plugin *plugin = plug_data->plugin;
224*de0de752SAndroid Build Coastguard Worker 	int ret = 0;
225*de0de752SAndroid Build Coastguard Worker 	va_list ap;
226*de0de752SAndroid Build Coastguard Worker 	void *arg;
227*de0de752SAndroid Build Coastguard Worker 
228*de0de752SAndroid Build Coastguard Worker 	va_start(ap, cmd);
229*de0de752SAndroid Build Coastguard Worker 	arg = va_arg(ap, void *);
230*de0de752SAndroid Build Coastguard Worker 	va_end(ap);
231*de0de752SAndroid Build Coastguard Worker 
232*de0de752SAndroid Build Coastguard Worker 	switch (cmd) {
233*de0de752SAndroid Build Coastguard Worker 	case SNDRV_COMPRESS_IOCTL_VERSION:
234*de0de752SAndroid Build Coastguard Worker 		*((int*)arg) = SNDRV_COMPRESS_VERSION;
235*de0de752SAndroid Build Coastguard Worker 		break;
236*de0de752SAndroid Build Coastguard Worker 	case SNDRV_COMPRESS_GET_CAPS:
237*de0de752SAndroid Build Coastguard Worker 		ret = compress_plug_get_caps(plug_data, arg);
238*de0de752SAndroid Build Coastguard Worker 		break;
239*de0de752SAndroid Build Coastguard Worker 	case SNDRV_COMPRESS_SET_PARAMS:
240*de0de752SAndroid Build Coastguard Worker 		ret = compress_plug_set_params(plug_data, arg);
241*de0de752SAndroid Build Coastguard Worker 		break;
242*de0de752SAndroid Build Coastguard Worker 	case SNDRV_COMPRESS_AVAIL:
243*de0de752SAndroid Build Coastguard Worker 		ret = compress_plug_avail(plug_data, arg);
244*de0de752SAndroid Build Coastguard Worker 		break;
245*de0de752SAndroid Build Coastguard Worker 	case SNDRV_COMPRESS_TSTAMP:
246*de0de752SAndroid Build Coastguard Worker 		ret = compress_plug_tstamp(plug_data, arg);
247*de0de752SAndroid Build Coastguard Worker 		break;
248*de0de752SAndroid Build Coastguard Worker 	case SNDRV_COMPRESS_START:
249*de0de752SAndroid Build Coastguard Worker 		ret = compress_plug_start(plug_data);
250*de0de752SAndroid Build Coastguard Worker 		break;
251*de0de752SAndroid Build Coastguard Worker 	case SNDRV_COMPRESS_STOP:
252*de0de752SAndroid Build Coastguard Worker 		ret = compress_plug_stop(plug_data);
253*de0de752SAndroid Build Coastguard Worker 		break;
254*de0de752SAndroid Build Coastguard Worker 	case SNDRV_COMPRESS_PAUSE:
255*de0de752SAndroid Build Coastguard Worker 		ret = compress_plug_pause(plug_data);
256*de0de752SAndroid Build Coastguard Worker 		break;
257*de0de752SAndroid Build Coastguard Worker 	case SNDRV_COMPRESS_RESUME:
258*de0de752SAndroid Build Coastguard Worker 		ret = compress_plug_resume(plug_data);
259*de0de752SAndroid Build Coastguard Worker 		break;
260*de0de752SAndroid Build Coastguard Worker 	case SNDRV_COMPRESS_DRAIN:
261*de0de752SAndroid Build Coastguard Worker 		ret = compress_plug_drain(plug_data);
262*de0de752SAndroid Build Coastguard Worker 		break;
263*de0de752SAndroid Build Coastguard Worker 	case SNDRV_COMPRESS_PARTIAL_DRAIN:
264*de0de752SAndroid Build Coastguard Worker 		ret = compress_plug_partial_drain(plug_data);
265*de0de752SAndroid Build Coastguard Worker 		break;
266*de0de752SAndroid Build Coastguard Worker 	case SNDRV_COMPRESS_NEXT_TRACK:
267*de0de752SAndroid Build Coastguard Worker 		ret = compress_plug_next_track(plug_data);
268*de0de752SAndroid Build Coastguard Worker 		break;
269*de0de752SAndroid Build Coastguard Worker 	default:
270*de0de752SAndroid Build Coastguard Worker 		if (plugin->ops->ioctl)
271*de0de752SAndroid Build Coastguard Worker 			ret = plugin->ops->ioctl(plugin, cmd, arg);
272*de0de752SAndroid Build Coastguard Worker 		else
273*de0de752SAndroid Build Coastguard Worker 			ret = -EINVAL;
274*de0de752SAndroid Build Coastguard Worker 		break;
275*de0de752SAndroid Build Coastguard Worker 	}
276*de0de752SAndroid Build Coastguard Worker 
277*de0de752SAndroid Build Coastguard Worker 	return ret;
278*de0de752SAndroid Build Coastguard Worker }
279*de0de752SAndroid Build Coastguard Worker 
compress_plug_poll(void * data,struct pollfd * fds,nfds_t nfds,int timeout)280*de0de752SAndroid Build Coastguard Worker static int compress_plug_poll(void *data, struct pollfd *fds,
281*de0de752SAndroid Build Coastguard Worker 				nfds_t nfds, int timeout)
282*de0de752SAndroid Build Coastguard Worker {
283*de0de752SAndroid Build Coastguard Worker 	struct compress_plug_data *plug_data = data;
284*de0de752SAndroid Build Coastguard Worker 	struct compress_plugin *plugin = plug_data->plugin;
285*de0de752SAndroid Build Coastguard Worker 
286*de0de752SAndroid Build Coastguard Worker 	if (plugin->state != COMPRESS_PLUG_STATE_RUNNING)
287*de0de752SAndroid Build Coastguard Worker 		return -EBADFD;
288*de0de752SAndroid Build Coastguard Worker 
289*de0de752SAndroid Build Coastguard Worker 	return plugin->ops->poll(plugin, fds, nfds, timeout);
290*de0de752SAndroid Build Coastguard Worker }
291*de0de752SAndroid Build Coastguard Worker 
292*de0de752SAndroid Build Coastguard Worker 
compress_plug_read(void * data,void * buf,size_t size)293*de0de752SAndroid Build Coastguard Worker static int compress_plug_read(void *data, void *buf, size_t size)
294*de0de752SAndroid Build Coastguard Worker {
295*de0de752SAndroid Build Coastguard Worker 	struct compress_plug_data *plug_data = data;
296*de0de752SAndroid Build Coastguard Worker 	struct compress_plugin *plugin = plug_data->plugin;
297*de0de752SAndroid Build Coastguard Worker 
298*de0de752SAndroid Build Coastguard Worker 	if (plugin->state != COMPRESS_PLUG_STATE_RUNNING &&
299*de0de752SAndroid Build Coastguard Worker 		plugin->state != COMPRESS_PLUG_STATE_SETUP)
300*de0de752SAndroid Build Coastguard Worker 		return -EBADFD;
301*de0de752SAndroid Build Coastguard Worker 
302*de0de752SAndroid Build Coastguard Worker 	return plugin->ops->read(plugin, buf, size);
303*de0de752SAndroid Build Coastguard Worker }
304*de0de752SAndroid Build Coastguard Worker 
compress_plug_write(void * data,const void * buf,size_t size)305*de0de752SAndroid Build Coastguard Worker static int compress_plug_write(void *data, const void *buf, size_t size)
306*de0de752SAndroid Build Coastguard Worker {
307*de0de752SAndroid Build Coastguard Worker 	struct compress_plug_data *plug_data = data;
308*de0de752SAndroid Build Coastguard Worker 	struct compress_plugin *plugin = plug_data->plugin;
309*de0de752SAndroid Build Coastguard Worker 	int rc;
310*de0de752SAndroid Build Coastguard Worker 
311*de0de752SAndroid Build Coastguard Worker 	if (plugin->state != COMPRESS_PLUG_STATE_SETUP &&
312*de0de752SAndroid Build Coastguard Worker 	    plugin->state != COMPRESS_PLUG_STATE_PREPARED &&
313*de0de752SAndroid Build Coastguard Worker 	    plugin->state != COMPRESS_PLUG_STATE_RUNNING)
314*de0de752SAndroid Build Coastguard Worker 		return -EBADFD;
315*de0de752SAndroid Build Coastguard Worker 
316*de0de752SAndroid Build Coastguard Worker 	rc = plugin->ops->write(plugin, buf, size);
317*de0de752SAndroid Build Coastguard Worker 	if ((rc > 0) && (plugin->state == COMPRESS_PLUG_STATE_SETUP))
318*de0de752SAndroid Build Coastguard Worker 		plugin->state = COMPRESS_PLUG_STATE_PREPARED;
319*de0de752SAndroid Build Coastguard Worker 
320*de0de752SAndroid Build Coastguard Worker 	return rc;
321*de0de752SAndroid Build Coastguard Worker }
322*de0de752SAndroid Build Coastguard Worker 
compress_plug_close(void * data)323*de0de752SAndroid Build Coastguard Worker static void compress_plug_close(void *data)
324*de0de752SAndroid Build Coastguard Worker {
325*de0de752SAndroid Build Coastguard Worker 	struct compress_plug_data *plug_data = data;
326*de0de752SAndroid Build Coastguard Worker 	struct compress_plugin *plugin = plug_data->plugin;
327*de0de752SAndroid Build Coastguard Worker 
328*de0de752SAndroid Build Coastguard Worker 	plugin->ops->close(plugin);
329*de0de752SAndroid Build Coastguard Worker 	dlclose(plug_data->dl_hdl);
330*de0de752SAndroid Build Coastguard Worker 
331*de0de752SAndroid Build Coastguard Worker 	free(plug_data);
332*de0de752SAndroid Build Coastguard Worker }
333*de0de752SAndroid Build Coastguard Worker 
compress_plug_open(unsigned int card,unsigned int device,unsigned int flags,void ** data,void * node)334*de0de752SAndroid Build Coastguard Worker static int compress_plug_open(unsigned int card, unsigned int device,
335*de0de752SAndroid Build Coastguard Worker 			unsigned int flags, void **data, void *node)
336*de0de752SAndroid Build Coastguard Worker {
337*de0de752SAndroid Build Coastguard Worker 	struct compress_plug_data *plug_data;
338*de0de752SAndroid Build Coastguard Worker 	void *dl_hdl;
339*de0de752SAndroid Build Coastguard Worker 	int rc = 0;
340*de0de752SAndroid Build Coastguard Worker 	char *so_name, *open_fn, token[80], *name, *token_saveptr;
341*de0de752SAndroid Build Coastguard Worker 
342*de0de752SAndroid Build Coastguard Worker 	plug_data = calloc(1, sizeof(*plug_data));
343*de0de752SAndroid Build Coastguard Worker 	if (!plug_data) {
344*de0de752SAndroid Build Coastguard Worker 		return -ENOMEM;
345*de0de752SAndroid Build Coastguard Worker 	}
346*de0de752SAndroid Build Coastguard Worker 
347*de0de752SAndroid Build Coastguard Worker 	rc = snd_utils_get_str(node, "so-name", &so_name);
348*de0de752SAndroid Build Coastguard Worker 	if (rc) {
349*de0de752SAndroid Build Coastguard Worker 		fprintf(stderr, "%s: failed to get plugin lib name\n",
350*de0de752SAndroid Build Coastguard Worker 				__func__);
351*de0de752SAndroid Build Coastguard Worker 		goto err_get_lib;
352*de0de752SAndroid Build Coastguard Worker 	}
353*de0de752SAndroid Build Coastguard Worker 
354*de0de752SAndroid Build Coastguard Worker 	dl_hdl = dlopen(so_name, RTLD_NOW);
355*de0de752SAndroid Build Coastguard Worker 	if (!dl_hdl) {
356*de0de752SAndroid Build Coastguard Worker 		fprintf(stderr, "%s: unable to open %s, error: %s\n",
357*de0de752SAndroid Build Coastguard Worker 					__func__, so_name, dlerror());
358*de0de752SAndroid Build Coastguard Worker 		goto err_dl_open;
359*de0de752SAndroid Build Coastguard Worker 	} else {
360*de0de752SAndroid Build Coastguard Worker 		fprintf(stderr, "%s: dlopen successful for %s\n",
361*de0de752SAndroid Build Coastguard Worker 					__func__, so_name);
362*de0de752SAndroid Build Coastguard Worker 	}
363*de0de752SAndroid Build Coastguard Worker 
364*de0de752SAndroid Build Coastguard Worker 	sscanf(so_name, "lib%s", token);
365*de0de752SAndroid Build Coastguard Worker 	token_saveptr = token;
366*de0de752SAndroid Build Coastguard Worker 	name = strtok_r(token, ".", &token_saveptr);
367*de0de752SAndroid Build Coastguard Worker 	if (!name) {
368*de0de752SAndroid Build Coastguard Worker 		fprintf(stderr, "%s: invalid library name\n", __func__);
369*de0de752SAndroid Build Coastguard Worker 		goto err_open_fn;
370*de0de752SAndroid Build Coastguard Worker 	}
371*de0de752SAndroid Build Coastguard Worker 	const size_t open_fn_size = strlen(name) + strlen("_open") + 1;
372*de0de752SAndroid Build Coastguard Worker 	open_fn = calloc(1, open_fn_size);
373*de0de752SAndroid Build Coastguard Worker 	if (!open_fn) {
374*de0de752SAndroid Build Coastguard Worker 		rc = -ENOMEM;
375*de0de752SAndroid Build Coastguard Worker 		goto err_open_fn;
376*de0de752SAndroid Build Coastguard Worker 	}
377*de0de752SAndroid Build Coastguard Worker 
378*de0de752SAndroid Build Coastguard Worker 	strlcpy(open_fn, name, open_fn_size);
379*de0de752SAndroid Build Coastguard Worker 	strlcat(open_fn, "_open", open_fn_size);
380*de0de752SAndroid Build Coastguard Worker 
381*de0de752SAndroid Build Coastguard Worker 	plug_data->plugin_open_fn = dlsym(dl_hdl, open_fn);
382*de0de752SAndroid Build Coastguard Worker 	if (!plug_data->plugin_open_fn) {
383*de0de752SAndroid Build Coastguard Worker 		fprintf(stderr, "%s: dlsym to open fn failed, err = '%s'\n",
384*de0de752SAndroid Build Coastguard Worker 				__func__, dlerror());
385*de0de752SAndroid Build Coastguard Worker 		goto err_dlsym;
386*de0de752SAndroid Build Coastguard Worker 	}
387*de0de752SAndroid Build Coastguard Worker 
388*de0de752SAndroid Build Coastguard Worker 	rc = plug_data->plugin_open_fn(&plug_data->plugin,
389*de0de752SAndroid Build Coastguard Worker 					card, device, flags);
390*de0de752SAndroid Build Coastguard Worker 	if (rc) {
391*de0de752SAndroid Build Coastguard Worker 		fprintf(stderr, "%s: failed to open plugin\n", __func__);
392*de0de752SAndroid Build Coastguard Worker 		goto err_dlsym;
393*de0de752SAndroid Build Coastguard Worker 	}
394*de0de752SAndroid Build Coastguard Worker 
395*de0de752SAndroid Build Coastguard Worker 	/* Call snd-card-def to get card and compress nodes */
396*de0de752SAndroid Build Coastguard Worker 	/* Check how to manage fd for plugin */
397*de0de752SAndroid Build Coastguard Worker 
398*de0de752SAndroid Build Coastguard Worker 	plug_data->dl_hdl = dl_hdl;
399*de0de752SAndroid Build Coastguard Worker 	plug_data->card = card;
400*de0de752SAndroid Build Coastguard Worker 	plug_data->device = device;
401*de0de752SAndroid Build Coastguard Worker 	plug_data->dev_node = node;
402*de0de752SAndroid Build Coastguard Worker 	plug_data->flags = flags;
403*de0de752SAndroid Build Coastguard Worker 
404*de0de752SAndroid Build Coastguard Worker 	*data = plug_data;
405*de0de752SAndroid Build Coastguard Worker 
406*de0de752SAndroid Build Coastguard Worker 	plug_data->plugin->state = COMPRESS_PLUG_STATE_OPEN;
407*de0de752SAndroid Build Coastguard Worker 
408*de0de752SAndroid Build Coastguard Worker 	return 0;
409*de0de752SAndroid Build Coastguard Worker 
410*de0de752SAndroid Build Coastguard Worker err_dlsym:
411*de0de752SAndroid Build Coastguard Worker 	free(open_fn);
412*de0de752SAndroid Build Coastguard Worker err_open_fn:
413*de0de752SAndroid Build Coastguard Worker 	dlclose(dl_hdl);
414*de0de752SAndroid Build Coastguard Worker err_get_lib:
415*de0de752SAndroid Build Coastguard Worker err_dl_open:
416*de0de752SAndroid Build Coastguard Worker 	free(plug_data);
417*de0de752SAndroid Build Coastguard Worker 
418*de0de752SAndroid Build Coastguard Worker 	return rc;
419*de0de752SAndroid Build Coastguard Worker }
420*de0de752SAndroid Build Coastguard Worker 
421*de0de752SAndroid Build Coastguard Worker struct compress_ops compr_plug_ops = {
422*de0de752SAndroid Build Coastguard Worker 	.open = compress_plug_open,
423*de0de752SAndroid Build Coastguard Worker 	.close = compress_plug_close,
424*de0de752SAndroid Build Coastguard Worker 	.ioctl = compress_plug_ioctl,
425*de0de752SAndroid Build Coastguard Worker 	.read = compress_plug_read,
426*de0de752SAndroid Build Coastguard Worker 	.write = compress_plug_write,
427*de0de752SAndroid Build Coastguard Worker 	.poll = compress_plug_poll,
428*de0de752SAndroid Build Coastguard Worker };
429