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 */
18int 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
64out:
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 */
75int 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
110out:
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 */
120int 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
153out:
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 */
163int 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
196out:
197	return error;
198}
199