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