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 }
199