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