1 /* compress_hw.c
2 **
3 ** Copyright (c) 2019, The Linux Foundation. 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
7 ** met:
8 ** * Redistributions of source code must retain the above copyright
9 ** notice, this list of conditions and the following disclaimer.
10 ** * Redistributions in binary form must reproduce the above
11 ** copyright notice, this list of conditions and the following
12 ** disclaimer in the documentation and/or other materials provided
13 ** with the distribution.
14 ** * Neither the name of The Linux Foundation nor the names of its
15 ** contributors may be used to endorse or promote products derived
16 ** from this software without specific prior written permission.
17 **
18 ** THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
19 ** WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
20 ** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
21 ** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
22 ** BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 ** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 ** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
25 ** BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26 ** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
27 ** OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
28 ** IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 **/
30
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <fcntl.h>
34 #include <stdarg.h>
35 #include <string.h>
36 #include <stdbool.h>
37 #include <errno.h>
38 #include <unistd.h>
39 #include <poll.h>
40
41 #include <sys/ioctl.h>
42 #include <linux/ioctl.h>
43 #include <sound/asound.h>
44 #include "tinycompress/tinycompress.h"
45 #include "compress_ops.h"
46
47 struct compress_hw_data {
48 unsigned int card;
49 unsigned int device;
50 unsigned int fd;
51 };
52
compress_hw_poll(void * data,struct pollfd * fds,nfds_t nfds,int timeout)53 static int compress_hw_poll(void *data, struct pollfd *fds,
54 nfds_t nfds, int timeout)
55 {
56 struct compress_hw_data *hw_data = data;
57
58 fds->fd = hw_data->fd;
59 return poll(fds, nfds, timeout);
60 }
61
compress_hw_write(void * data,const void * buf,size_t size)62 static int compress_hw_write(void *data, const void *buf, size_t size)
63 {
64 struct compress_hw_data *hw_data = data;
65
66 return write(hw_data->fd, buf, size);
67 }
68
compress_hw_read(void * data,void * buf,size_t size)69 static int compress_hw_read(void *data, void *buf, size_t size)
70 {
71 struct compress_hw_data *hw_data = data;
72
73 return read(hw_data->fd, buf, size);
74 }
75
compress_hw_ioctl(void * data,unsigned int cmd,...)76 static int compress_hw_ioctl(void *data, unsigned int cmd, ...)
77 {
78 struct compress_hw_data *hw_data = data;
79 va_list ap;
80 void *arg;
81
82 va_start(ap, cmd);
83 arg = va_arg(ap, void *);
84 va_end(ap);
85
86 return ioctl(hw_data->fd, cmd, arg);
87 }
88
compress_hw_close(void * data)89 static void compress_hw_close(void *data)
90 {
91 struct compress_hw_data *hw_data = data;
92
93 if (hw_data->fd > 0)
94 close(hw_data->fd);
95
96 free(hw_data);
97 }
98
compress_hw_open(unsigned int card,unsigned int device,unsigned int flags,void ** data,__unused void * node)99 static int compress_hw_open(unsigned int card, unsigned int device,
100 unsigned int flags, void **data, __unused void *node)
101 {
102 struct compress_hw_data *hw_data;
103 char fn[256];
104 int fd;
105
106 hw_data = calloc(1, sizeof(*hw_data));
107 if (!hw_data) {
108 return -ENOMEM;
109 }
110
111 snprintf(fn, sizeof(fn), "/dev/snd/comprC%uD%u", card, device);
112
113 if (flags & COMPRESS_OUT)
114 fd = open(fn, O_RDONLY);
115 else
116 fd = open(fn, O_WRONLY);
117
118 if (fd < 0) {
119 return fd;
120 }
121
122 hw_data->card = card;
123 hw_data->device = device;
124 hw_data->fd = fd;
125
126 *data = hw_data;
127
128 return fd;
129 }
130
131 struct compress_ops compr_hw_ops = {
132 .open = compress_hw_open,
133 .close = compress_hw_close,
134 .ioctl = compress_hw_ioctl,
135 .read = compress_hw_read,
136 .write = compress_hw_write,
137 .poll = compress_hw_poll,
138 };
139