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 */
27int 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
73out:
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 */
84int 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
119out:
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 */
129int 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
162out:
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 */
172int 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
205out:
206	return error;
207}
208