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, proc_id: (++adap->cmd_xid), |
29 | cmd_len: 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(r: prsp, proc_id: 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, proc_id: (++adap->cmd_xid), |
86 | cmd_len: 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(r: prsp, proc_id: 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, proc_id: (++adap->cmd_xid), |
130 | cmd_len: 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(r: prsp, proc_id: 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, proc_id: (++adap->cmd_xid), |
173 | cmd_len: 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(r: prsp, proc_id: CONTROL_PROC_STOP_STREAMING_RSP); |
195 | |
196 | out: |
197 | return error; |
198 | } |
199 | |