1 /*
2  * Abilis Systems Single DVB-T Receiver
3  * Copyright (C) 2008 Pierrick Hascoet <pierrick.hascoet@abilis.com>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2, or (at your option)
8  * any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */
19 
20 #include <linux/kernel.h>
21 #include "as102_drv.h"
22 #include "as10x_cmd.h"
23 
24 /**
25  * as10x_cmd_add_PID_filter - send add filter command to AS10x
26  * @adap:      pointer to AS10x bus adapter
27  * @filter:    TSFilter filter for DVB-T
28  *
29  * Return 0 on success or negative value in case of error.
30  */
as10x_cmd_add_PID_filter(struct as10x_bus_adapter_t * adap,struct as10x_ts_filter * filter)31 int as10x_cmd_add_PID_filter(struct as10x_bus_adapter_t *adap,
32 			     struct as10x_ts_filter *filter)
33 {
34 	int error;
35 	struct as10x_cmd_t *pcmd, *prsp;
36 
37 	ENTER();
38 
39 	pcmd = adap->cmd;
40 	prsp = adap->rsp;
41 
42 	/* prepare command */
43 	as10x_cmd_build(pcmd, (++adap->cmd_xid),
44 			sizeof(pcmd->body.add_pid_filter.req));
45 
46 	/* fill command */
47 	pcmd->body.add_pid_filter.req.proc_id =
48 		cpu_to_le16(CONTROL_PROC_SETFILTER);
49 	pcmd->body.add_pid_filter.req.pid = cpu_to_le16(filter->pid);
50 	pcmd->body.add_pid_filter.req.stream_type = filter->type;
51 
52 	if (filter->idx < 16)
53 		pcmd->body.add_pid_filter.req.idx = filter->idx;
54 	else
55 		pcmd->body.add_pid_filter.req.idx = 0xFF;
56 
57 	/* send command */
58 	if (adap->ops->xfer_cmd) {
59 		error = adap->ops->xfer_cmd(adap, (uint8_t *) pcmd,
60 				sizeof(pcmd->body.add_pid_filter.req)
61 				+ HEADER_SIZE, (uint8_t *) prsp,
62 				sizeof(prsp->body.add_pid_filter.rsp)
63 				+ HEADER_SIZE);
64 	} else {
65 		error = AS10X_CMD_ERROR;
66 	}
67 
68 	if (error < 0)
69 		goto out;
70 
71 	/* parse response */
72 	error = as10x_rsp_parse(prsp, CONTROL_PROC_SETFILTER_RSP);
73 
74 	if (error == 0) {
75 		/* Response OK -> get response data */
76 		filter->idx = prsp->body.add_pid_filter.rsp.filter_id;
77 	}
78 
79 out:
80 	LEAVE();
81 	return error;
82 }
83 
84 /**
85  * as10x_cmd_del_PID_filter - Send delete filter command to AS10x
86  * @adap:         pointer to AS10x bus adapte
87  * @pid_value:    PID to delete
88  *
89  * Return 0 on success or negative value in case of error.
90  */
as10x_cmd_del_PID_filter(struct as10x_bus_adapter_t * adap,uint16_t pid_value)91 int as10x_cmd_del_PID_filter(struct as10x_bus_adapter_t *adap,
92 			     uint16_t pid_value)
93 {
94 	int error;
95 	struct as10x_cmd_t *pcmd, *prsp;
96 
97 	ENTER();
98 
99 	pcmd = adap->cmd;
100 	prsp = adap->rsp;
101 
102 	/* prepare command */
103 	as10x_cmd_build(pcmd, (++adap->cmd_xid),
104 			sizeof(pcmd->body.del_pid_filter.req));
105 
106 	/* fill command */
107 	pcmd->body.del_pid_filter.req.proc_id =
108 		cpu_to_le16(CONTROL_PROC_REMOVEFILTER);
109 	pcmd->body.del_pid_filter.req.pid = cpu_to_le16(pid_value);
110 
111 	/* send command */
112 	if (adap->ops->xfer_cmd) {
113 		error = adap->ops->xfer_cmd(adap, (uint8_t *) pcmd,
114 				sizeof(pcmd->body.del_pid_filter.req)
115 				+ HEADER_SIZE, (uint8_t *) prsp,
116 				sizeof(prsp->body.del_pid_filter.rsp)
117 				+ HEADER_SIZE);
118 	} else {
119 		error = AS10X_CMD_ERROR;
120 	}
121 
122 	if (error < 0)
123 		goto out;
124 
125 	/* parse response */
126 	error = as10x_rsp_parse(prsp, CONTROL_PROC_REMOVEFILTER_RSP);
127 
128 out:
129 	LEAVE();
130 	return error;
131 }
132 
133 /**
134  * as10x_cmd_start_streaming - Send start streaming command to AS10x
135  * @adap:   pointer to AS10x bus adapter
136  *
137  * Return 0 on success or negative value in case of error.
138  */
as10x_cmd_start_streaming(struct as10x_bus_adapter_t * adap)139 int as10x_cmd_start_streaming(struct as10x_bus_adapter_t *adap)
140 {
141 	int error;
142 	struct as10x_cmd_t *pcmd, *prsp;
143 
144 	ENTER();
145 
146 	pcmd = adap->cmd;
147 	prsp = adap->rsp;
148 
149 	/* prepare command */
150 	as10x_cmd_build(pcmd, (++adap->cmd_xid),
151 			sizeof(pcmd->body.start_streaming.req));
152 
153 	/* fill command */
154 	pcmd->body.start_streaming.req.proc_id =
155 		cpu_to_le16(CONTROL_PROC_START_STREAMING);
156 
157 	/* send command */
158 	if (adap->ops->xfer_cmd) {
159 		error = adap->ops->xfer_cmd(adap, (uint8_t *) pcmd,
160 				sizeof(pcmd->body.start_streaming.req)
161 				+ HEADER_SIZE, (uint8_t *) prsp,
162 				sizeof(prsp->body.start_streaming.rsp)
163 				+ HEADER_SIZE);
164 	} else {
165 		error = AS10X_CMD_ERROR;
166 	}
167 
168 	if (error < 0)
169 		goto out;
170 
171 	/* parse response */
172 	error = as10x_rsp_parse(prsp, CONTROL_PROC_START_STREAMING_RSP);
173 
174 out:
175 	LEAVE();
176 	return error;
177 }
178 
179 /**
180  * as10x_cmd_stop_streaming - Send stop streaming command to AS10x
181  * @adap:   pointer to AS10x bus adapter
182  *
183  * Return 0 on success or negative value in case of error.
184  */
as10x_cmd_stop_streaming(struct as10x_bus_adapter_t * adap)185 int as10x_cmd_stop_streaming(struct as10x_bus_adapter_t *adap)
186 {
187 	int8_t error;
188 	struct as10x_cmd_t *pcmd, *prsp;
189 
190 	ENTER();
191 
192 	pcmd = adap->cmd;
193 	prsp = adap->rsp;
194 
195 	/* prepare command */
196 	as10x_cmd_build(pcmd, (++adap->cmd_xid),
197 			sizeof(pcmd->body.stop_streaming.req));
198 
199 	/* fill command */
200 	pcmd->body.stop_streaming.req.proc_id =
201 		cpu_to_le16(CONTROL_PROC_STOP_STREAMING);
202 
203 	/* send command */
204 	if (adap->ops->xfer_cmd) {
205 		error = adap->ops->xfer_cmd(adap, (uint8_t *) pcmd,
206 				sizeof(pcmd->body.stop_streaming.req)
207 				+ HEADER_SIZE, (uint8_t *) prsp,
208 				sizeof(prsp->body.stop_streaming.rsp)
209 				+ HEADER_SIZE);
210 	} else {
211 		error = AS10X_CMD_ERROR;
212 	}
213 
214 	if (error < 0)
215 		goto out;
216 
217 	/* parse response */
218 	error = as10x_rsp_parse(prsp, CONTROL_PROC_STOP_STREAMING_RSP);
219 
220 out:
221 	LEAVE();
222 	return error;
223 }
224