162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Abilis Systems Single DVB-T Receiver
462306a36Sopenharmony_ci * Copyright (C) 2008 Pierrick Hascoet <pierrick.hascoet@abilis.com>
562306a36Sopenharmony_ci */
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci#include <linux/kernel.h>
862306a36Sopenharmony_ci#include "as102_drv.h"
962306a36Sopenharmony_ci#include "as10x_cmd.h"
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci/**
1262306a36Sopenharmony_ci * as10x_cmd_add_PID_filter - send add filter command to AS10x
1362306a36Sopenharmony_ci * @adap:      pointer to AS10x bus adapter
1462306a36Sopenharmony_ci * @filter:    TSFilter filter for DVB-T
1562306a36Sopenharmony_ci *
1662306a36Sopenharmony_ci * Return 0 on success or negative value in case of error.
1762306a36Sopenharmony_ci */
1862306a36Sopenharmony_ciint as10x_cmd_add_PID_filter(struct as10x_bus_adapter_t *adap,
1962306a36Sopenharmony_ci			     struct as10x_ts_filter *filter)
2062306a36Sopenharmony_ci{
2162306a36Sopenharmony_ci	int error;
2262306a36Sopenharmony_ci	struct as10x_cmd_t *pcmd, *prsp;
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ci	pcmd = adap->cmd;
2562306a36Sopenharmony_ci	prsp = adap->rsp;
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci	/* prepare command */
2862306a36Sopenharmony_ci	as10x_cmd_build(pcmd, (++adap->cmd_xid),
2962306a36Sopenharmony_ci			sizeof(pcmd->body.add_pid_filter.req));
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_ci	/* fill command */
3262306a36Sopenharmony_ci	pcmd->body.add_pid_filter.req.proc_id =
3362306a36Sopenharmony_ci		cpu_to_le16(CONTROL_PROC_SETFILTER);
3462306a36Sopenharmony_ci	pcmd->body.add_pid_filter.req.pid = cpu_to_le16(filter->pid);
3562306a36Sopenharmony_ci	pcmd->body.add_pid_filter.req.stream_type = filter->type;
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_ci	if (filter->idx < 16)
3862306a36Sopenharmony_ci		pcmd->body.add_pid_filter.req.idx = filter->idx;
3962306a36Sopenharmony_ci	else
4062306a36Sopenharmony_ci		pcmd->body.add_pid_filter.req.idx = 0xFF;
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_ci	/* send command */
4362306a36Sopenharmony_ci	if (adap->ops->xfer_cmd) {
4462306a36Sopenharmony_ci		error = adap->ops->xfer_cmd(adap, (uint8_t *) pcmd,
4562306a36Sopenharmony_ci				sizeof(pcmd->body.add_pid_filter.req)
4662306a36Sopenharmony_ci				+ HEADER_SIZE, (uint8_t *) prsp,
4762306a36Sopenharmony_ci				sizeof(prsp->body.add_pid_filter.rsp)
4862306a36Sopenharmony_ci				+ HEADER_SIZE);
4962306a36Sopenharmony_ci	} else {
5062306a36Sopenharmony_ci		error = AS10X_CMD_ERROR;
5162306a36Sopenharmony_ci	}
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_ci	if (error < 0)
5462306a36Sopenharmony_ci		goto out;
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ci	/* parse response */
5762306a36Sopenharmony_ci	error = as10x_rsp_parse(prsp, CONTROL_PROC_SETFILTER_RSP);
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_ci	if (error == 0) {
6062306a36Sopenharmony_ci		/* Response OK -> get response data */
6162306a36Sopenharmony_ci		filter->idx = prsp->body.add_pid_filter.rsp.filter_id;
6262306a36Sopenharmony_ci	}
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_ciout:
6562306a36Sopenharmony_ci	return error;
6662306a36Sopenharmony_ci}
6762306a36Sopenharmony_ci
6862306a36Sopenharmony_ci/**
6962306a36Sopenharmony_ci * as10x_cmd_del_PID_filter - Send delete filter command to AS10x
7062306a36Sopenharmony_ci * @adap:         pointer to AS10x bus adapte
7162306a36Sopenharmony_ci * @pid_value:    PID to delete
7262306a36Sopenharmony_ci *
7362306a36Sopenharmony_ci * Return 0 on success or negative value in case of error.
7462306a36Sopenharmony_ci */
7562306a36Sopenharmony_ciint as10x_cmd_del_PID_filter(struct as10x_bus_adapter_t *adap,
7662306a36Sopenharmony_ci			     uint16_t pid_value)
7762306a36Sopenharmony_ci{
7862306a36Sopenharmony_ci	int error;
7962306a36Sopenharmony_ci	struct as10x_cmd_t *pcmd, *prsp;
8062306a36Sopenharmony_ci
8162306a36Sopenharmony_ci	pcmd = adap->cmd;
8262306a36Sopenharmony_ci	prsp = adap->rsp;
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_ci	/* prepare command */
8562306a36Sopenharmony_ci	as10x_cmd_build(pcmd, (++adap->cmd_xid),
8662306a36Sopenharmony_ci			sizeof(pcmd->body.del_pid_filter.req));
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_ci	/* fill command */
8962306a36Sopenharmony_ci	pcmd->body.del_pid_filter.req.proc_id =
9062306a36Sopenharmony_ci		cpu_to_le16(CONTROL_PROC_REMOVEFILTER);
9162306a36Sopenharmony_ci	pcmd->body.del_pid_filter.req.pid = cpu_to_le16(pid_value);
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_ci	/* send command */
9462306a36Sopenharmony_ci	if (adap->ops->xfer_cmd) {
9562306a36Sopenharmony_ci		error = adap->ops->xfer_cmd(adap, (uint8_t *) pcmd,
9662306a36Sopenharmony_ci				sizeof(pcmd->body.del_pid_filter.req)
9762306a36Sopenharmony_ci				+ HEADER_SIZE, (uint8_t *) prsp,
9862306a36Sopenharmony_ci				sizeof(prsp->body.del_pid_filter.rsp)
9962306a36Sopenharmony_ci				+ HEADER_SIZE);
10062306a36Sopenharmony_ci	} else {
10162306a36Sopenharmony_ci		error = AS10X_CMD_ERROR;
10262306a36Sopenharmony_ci	}
10362306a36Sopenharmony_ci
10462306a36Sopenharmony_ci	if (error < 0)
10562306a36Sopenharmony_ci		goto out;
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_ci	/* parse response */
10862306a36Sopenharmony_ci	error = as10x_rsp_parse(prsp, CONTROL_PROC_REMOVEFILTER_RSP);
10962306a36Sopenharmony_ci
11062306a36Sopenharmony_ciout:
11162306a36Sopenharmony_ci	return error;
11262306a36Sopenharmony_ci}
11362306a36Sopenharmony_ci
11462306a36Sopenharmony_ci/**
11562306a36Sopenharmony_ci * as10x_cmd_start_streaming - Send start streaming command to AS10x
11662306a36Sopenharmony_ci * @adap:   pointer to AS10x bus adapter
11762306a36Sopenharmony_ci *
11862306a36Sopenharmony_ci * Return 0 on success or negative value in case of error.
11962306a36Sopenharmony_ci */
12062306a36Sopenharmony_ciint as10x_cmd_start_streaming(struct as10x_bus_adapter_t *adap)
12162306a36Sopenharmony_ci{
12262306a36Sopenharmony_ci	int error;
12362306a36Sopenharmony_ci	struct as10x_cmd_t *pcmd, *prsp;
12462306a36Sopenharmony_ci
12562306a36Sopenharmony_ci	pcmd = adap->cmd;
12662306a36Sopenharmony_ci	prsp = adap->rsp;
12762306a36Sopenharmony_ci
12862306a36Sopenharmony_ci	/* prepare command */
12962306a36Sopenharmony_ci	as10x_cmd_build(pcmd, (++adap->cmd_xid),
13062306a36Sopenharmony_ci			sizeof(pcmd->body.start_streaming.req));
13162306a36Sopenharmony_ci
13262306a36Sopenharmony_ci	/* fill command */
13362306a36Sopenharmony_ci	pcmd->body.start_streaming.req.proc_id =
13462306a36Sopenharmony_ci		cpu_to_le16(CONTROL_PROC_START_STREAMING);
13562306a36Sopenharmony_ci
13662306a36Sopenharmony_ci	/* send command */
13762306a36Sopenharmony_ci	if (adap->ops->xfer_cmd) {
13862306a36Sopenharmony_ci		error = adap->ops->xfer_cmd(adap, (uint8_t *) pcmd,
13962306a36Sopenharmony_ci				sizeof(pcmd->body.start_streaming.req)
14062306a36Sopenharmony_ci				+ HEADER_SIZE, (uint8_t *) prsp,
14162306a36Sopenharmony_ci				sizeof(prsp->body.start_streaming.rsp)
14262306a36Sopenharmony_ci				+ HEADER_SIZE);
14362306a36Sopenharmony_ci	} else {
14462306a36Sopenharmony_ci		error = AS10X_CMD_ERROR;
14562306a36Sopenharmony_ci	}
14662306a36Sopenharmony_ci
14762306a36Sopenharmony_ci	if (error < 0)
14862306a36Sopenharmony_ci		goto out;
14962306a36Sopenharmony_ci
15062306a36Sopenharmony_ci	/* parse response */
15162306a36Sopenharmony_ci	error = as10x_rsp_parse(prsp, CONTROL_PROC_START_STREAMING_RSP);
15262306a36Sopenharmony_ci
15362306a36Sopenharmony_ciout:
15462306a36Sopenharmony_ci	return error;
15562306a36Sopenharmony_ci}
15662306a36Sopenharmony_ci
15762306a36Sopenharmony_ci/**
15862306a36Sopenharmony_ci * as10x_cmd_stop_streaming - Send stop streaming command to AS10x
15962306a36Sopenharmony_ci * @adap:   pointer to AS10x bus adapter
16062306a36Sopenharmony_ci *
16162306a36Sopenharmony_ci * Return 0 on success or negative value in case of error.
16262306a36Sopenharmony_ci */
16362306a36Sopenharmony_ciint as10x_cmd_stop_streaming(struct as10x_bus_adapter_t *adap)
16462306a36Sopenharmony_ci{
16562306a36Sopenharmony_ci	int8_t error;
16662306a36Sopenharmony_ci	struct as10x_cmd_t *pcmd, *prsp;
16762306a36Sopenharmony_ci
16862306a36Sopenharmony_ci	pcmd = adap->cmd;
16962306a36Sopenharmony_ci	prsp = adap->rsp;
17062306a36Sopenharmony_ci
17162306a36Sopenharmony_ci	/* prepare command */
17262306a36Sopenharmony_ci	as10x_cmd_build(pcmd, (++adap->cmd_xid),
17362306a36Sopenharmony_ci			sizeof(pcmd->body.stop_streaming.req));
17462306a36Sopenharmony_ci
17562306a36Sopenharmony_ci	/* fill command */
17662306a36Sopenharmony_ci	pcmd->body.stop_streaming.req.proc_id =
17762306a36Sopenharmony_ci		cpu_to_le16(CONTROL_PROC_STOP_STREAMING);
17862306a36Sopenharmony_ci
17962306a36Sopenharmony_ci	/* send command */
18062306a36Sopenharmony_ci	if (adap->ops->xfer_cmd) {
18162306a36Sopenharmony_ci		error = adap->ops->xfer_cmd(adap, (uint8_t *) pcmd,
18262306a36Sopenharmony_ci				sizeof(pcmd->body.stop_streaming.req)
18362306a36Sopenharmony_ci				+ HEADER_SIZE, (uint8_t *) prsp,
18462306a36Sopenharmony_ci				sizeof(prsp->body.stop_streaming.rsp)
18562306a36Sopenharmony_ci				+ HEADER_SIZE);
18662306a36Sopenharmony_ci	} else {
18762306a36Sopenharmony_ci		error = AS10X_CMD_ERROR;
18862306a36Sopenharmony_ci	}
18962306a36Sopenharmony_ci
19062306a36Sopenharmony_ci	if (error < 0)
19162306a36Sopenharmony_ci		goto out;
19262306a36Sopenharmony_ci
19362306a36Sopenharmony_ci	/* parse response */
19462306a36Sopenharmony_ci	error = as10x_rsp_parse(prsp, CONTROL_PROC_STOP_STREAMING_RSP);
19562306a36Sopenharmony_ci
19662306a36Sopenharmony_ciout:
19762306a36Sopenharmony_ci	return error;
19862306a36Sopenharmony_ci}
199