Linux-libre 5.4.47-gnu
[librecmc/linux-libre.git] / drivers / media / usb / as102 / as10x_cmd_stream.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Abilis Systems Single DVB-T Receiver
4  * Copyright (C) 2008 Pierrick Hascoet <pierrick.hascoet@abilis.com>
5  */
6
7 #include <linux/kernel.h>
8 #include "as102_drv.h"
9 #include "as10x_cmd.h"
10
11 /**
12  * as10x_cmd_add_PID_filter - send add filter command to AS10x
13  * @adap:      pointer to AS10x bus adapter
14  * @filter:    TSFilter filter for DVB-T
15  *
16  * Return 0 on success or negative value in case of error.
17  */
18 int as10x_cmd_add_PID_filter(struct as10x_bus_adapter_t *adap,
19                              struct as10x_ts_filter *filter)
20 {
21         int error;
22         struct as10x_cmd_t *pcmd, *prsp;
23
24         pcmd = adap->cmd;
25         prsp = adap->rsp;
26
27         /* prepare command */
28         as10x_cmd_build(pcmd, (++adap->cmd_xid),
29                         sizeof(pcmd->body.add_pid_filter.req));
30
31         /* fill command */
32         pcmd->body.add_pid_filter.req.proc_id =
33                 cpu_to_le16(CONTROL_PROC_SETFILTER);
34         pcmd->body.add_pid_filter.req.pid = cpu_to_le16(filter->pid);
35         pcmd->body.add_pid_filter.req.stream_type = filter->type;
36
37         if (filter->idx < 16)
38                 pcmd->body.add_pid_filter.req.idx = filter->idx;
39         else
40                 pcmd->body.add_pid_filter.req.idx = 0xFF;
41
42         /* send command */
43         if (adap->ops->xfer_cmd) {
44                 error = adap->ops->xfer_cmd(adap, (uint8_t *) pcmd,
45                                 sizeof(pcmd->body.add_pid_filter.req)
46                                 + HEADER_SIZE, (uint8_t *) prsp,
47                                 sizeof(prsp->body.add_pid_filter.rsp)
48                                 + HEADER_SIZE);
49         } else {
50                 error = AS10X_CMD_ERROR;
51         }
52
53         if (error < 0)
54                 goto out;
55
56         /* parse response */
57         error = as10x_rsp_parse(prsp, CONTROL_PROC_SETFILTER_RSP);
58
59         if (error == 0) {
60                 /* Response OK -> get response data */
61                 filter->idx = prsp->body.add_pid_filter.rsp.filter_id;
62         }
63
64 out:
65         return error;
66 }
67
68 /**
69  * as10x_cmd_del_PID_filter - Send delete filter command to AS10x
70  * @adap:         pointer to AS10x bus adapte
71  * @pid_value:    PID to delete
72  *
73  * Return 0 on success or negative value in case of error.
74  */
75 int as10x_cmd_del_PID_filter(struct as10x_bus_adapter_t *adap,
76                              uint16_t pid_value)
77 {
78         int error;
79         struct as10x_cmd_t *pcmd, *prsp;
80
81         pcmd = adap->cmd;
82         prsp = adap->rsp;
83
84         /* prepare command */
85         as10x_cmd_build(pcmd, (++adap->cmd_xid),
86                         sizeof(pcmd->body.del_pid_filter.req));
87
88         /* fill command */
89         pcmd->body.del_pid_filter.req.proc_id =
90                 cpu_to_le16(CONTROL_PROC_REMOVEFILTER);
91         pcmd->body.del_pid_filter.req.pid = cpu_to_le16(pid_value);
92
93         /* send command */
94         if (adap->ops->xfer_cmd) {
95                 error = adap->ops->xfer_cmd(adap, (uint8_t *) pcmd,
96                                 sizeof(pcmd->body.del_pid_filter.req)
97                                 + HEADER_SIZE, (uint8_t *) prsp,
98                                 sizeof(prsp->body.del_pid_filter.rsp)
99                                 + HEADER_SIZE);
100         } else {
101                 error = AS10X_CMD_ERROR;
102         }
103
104         if (error < 0)
105                 goto out;
106
107         /* parse response */
108         error = as10x_rsp_parse(prsp, CONTROL_PROC_REMOVEFILTER_RSP);
109
110 out:
111         return error;
112 }
113
114 /**
115  * as10x_cmd_start_streaming - Send start streaming command to AS10x
116  * @adap:   pointer to AS10x bus adapter
117  *
118  * Return 0 on success or negative value in case of error.
119  */
120 int as10x_cmd_start_streaming(struct as10x_bus_adapter_t *adap)
121 {
122         int error;
123         struct as10x_cmd_t *pcmd, *prsp;
124
125         pcmd = adap->cmd;
126         prsp = adap->rsp;
127
128         /* prepare command */
129         as10x_cmd_build(pcmd, (++adap->cmd_xid),
130                         sizeof(pcmd->body.start_streaming.req));
131
132         /* fill command */
133         pcmd->body.start_streaming.req.proc_id =
134                 cpu_to_le16(CONTROL_PROC_START_STREAMING);
135
136         /* send command */
137         if (adap->ops->xfer_cmd) {
138                 error = adap->ops->xfer_cmd(adap, (uint8_t *) pcmd,
139                                 sizeof(pcmd->body.start_streaming.req)
140                                 + HEADER_SIZE, (uint8_t *) prsp,
141                                 sizeof(prsp->body.start_streaming.rsp)
142                                 + HEADER_SIZE);
143         } else {
144                 error = AS10X_CMD_ERROR;
145         }
146
147         if (error < 0)
148                 goto out;
149
150         /* parse response */
151         error = as10x_rsp_parse(prsp, CONTROL_PROC_START_STREAMING_RSP);
152
153 out:
154         return error;
155 }
156
157 /**
158  * as10x_cmd_stop_streaming - Send stop streaming command to AS10x
159  * @adap:   pointer to AS10x bus adapter
160  *
161  * Return 0 on success or negative value in case of error.
162  */
163 int as10x_cmd_stop_streaming(struct as10x_bus_adapter_t *adap)
164 {
165         int8_t error;
166         struct as10x_cmd_t *pcmd, *prsp;
167
168         pcmd = adap->cmd;
169         prsp = adap->rsp;
170
171         /* prepare command */
172         as10x_cmd_build(pcmd, (++adap->cmd_xid),
173                         sizeof(pcmd->body.stop_streaming.req));
174
175         /* fill command */
176         pcmd->body.stop_streaming.req.proc_id =
177                 cpu_to_le16(CONTROL_PROC_STOP_STREAMING);
178
179         /* send command */
180         if (adap->ops->xfer_cmd) {
181                 error = adap->ops->xfer_cmd(adap, (uint8_t *) pcmd,
182                                 sizeof(pcmd->body.stop_streaming.req)
183                                 + HEADER_SIZE, (uint8_t *) prsp,
184                                 sizeof(prsp->body.stop_streaming.rsp)
185                                 + HEADER_SIZE);
186         } else {
187                 error = AS10X_CMD_ERROR;
188         }
189
190         if (error < 0)
191                 goto out;
192
193         /* parse response */
194         error = as10x_rsp_parse(prsp, CONTROL_PROC_STOP_STREAMING_RSP);
195
196 out:
197         return error;
198 }