13e0a4e85SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
2d6317c68SMauro Carvalho Chehab /*
3d6317c68SMauro Carvalho Chehab  * Abilis Systems Single DVB-T Receiver
4d6317c68SMauro Carvalho Chehab  * Copyright (C) 2008 Pierrick Hascoet <pierrick.hascoet@abilis.com>
5d6317c68SMauro Carvalho Chehab  * Copyright (C) 2010 Devin Heitmueller <dheitmueller@kernellabs.com>
6d6317c68SMauro Carvalho Chehab  */
7d6317c68SMauro Carvalho Chehab 
8d6317c68SMauro Carvalho Chehab #include <linux/kernel.h>
9d6317c68SMauro Carvalho Chehab #include "as102_drv.h"
10d6317c68SMauro Carvalho Chehab #include "as10x_cmd.h"
11d6317c68SMauro Carvalho Chehab 
12d6317c68SMauro Carvalho Chehab /**
13d6317c68SMauro Carvalho Chehab  * as10x_cmd_turn_on - send turn on command to AS10x
14d6317c68SMauro Carvalho Chehab  * @adap:   pointer to AS10x bus adapter
15d6317c68SMauro Carvalho Chehab  *
16d6317c68SMauro Carvalho Chehab  * Return 0 when no error, < 0 in case of error.
17d6317c68SMauro Carvalho Chehab  */
as10x_cmd_turn_on(struct as10x_bus_adapter_t * adap)18d6317c68SMauro Carvalho Chehab int as10x_cmd_turn_on(struct as10x_bus_adapter_t *adap)
19d6317c68SMauro Carvalho Chehab {
20d6317c68SMauro Carvalho Chehab 	int error = AS10X_CMD_ERROR;
21d6317c68SMauro Carvalho Chehab 	struct as10x_cmd_t *pcmd, *prsp;
22d6317c68SMauro Carvalho Chehab 
23d6317c68SMauro Carvalho Chehab 	pcmd = adap->cmd;
24d6317c68SMauro Carvalho Chehab 	prsp = adap->rsp;
25d6317c68SMauro Carvalho Chehab 
26d6317c68SMauro Carvalho Chehab 	/* prepare command */
27d6317c68SMauro Carvalho Chehab 	as10x_cmd_build(pcmd, (++adap->cmd_xid),
28d6317c68SMauro Carvalho Chehab 			sizeof(pcmd->body.turn_on.req));
29d6317c68SMauro Carvalho Chehab 
30d6317c68SMauro Carvalho Chehab 	/* fill command */
31d6317c68SMauro Carvalho Chehab 	pcmd->body.turn_on.req.proc_id = cpu_to_le16(CONTROL_PROC_TURNON);
32d6317c68SMauro Carvalho Chehab 
33d6317c68SMauro Carvalho Chehab 	/* send command */
34d6317c68SMauro Carvalho Chehab 	if (adap->ops->xfer_cmd) {
35d6317c68SMauro Carvalho Chehab 		error = adap->ops->xfer_cmd(adap, (uint8_t *) pcmd,
36d6317c68SMauro Carvalho Chehab 					    sizeof(pcmd->body.turn_on.req) +
37d6317c68SMauro Carvalho Chehab 					    HEADER_SIZE,
38d6317c68SMauro Carvalho Chehab 					    (uint8_t *) prsp,
39d6317c68SMauro Carvalho Chehab 					    sizeof(prsp->body.turn_on.rsp) +
40d6317c68SMauro Carvalho Chehab 					    HEADER_SIZE);
41d6317c68SMauro Carvalho Chehab 	}
42d6317c68SMauro Carvalho Chehab 
43d6317c68SMauro Carvalho Chehab 	if (error < 0)
44d6317c68SMauro Carvalho Chehab 		goto out;
45d6317c68SMauro Carvalho Chehab 
46d6317c68SMauro Carvalho Chehab 	/* parse response */
47d6317c68SMauro Carvalho Chehab 	error = as10x_rsp_parse(prsp, CONTROL_PROC_TURNON_RSP);
48d6317c68SMauro Carvalho Chehab 
49d6317c68SMauro Carvalho Chehab out:
50d6317c68SMauro Carvalho Chehab 	return error;
51d6317c68SMauro Carvalho Chehab }
52d6317c68SMauro Carvalho Chehab 
53d6317c68SMauro Carvalho Chehab /**
54d6317c68SMauro Carvalho Chehab  * as10x_cmd_turn_off - send turn off command to AS10x
55d6317c68SMauro Carvalho Chehab  * @adap:   pointer to AS10x bus adapter
56d6317c68SMauro Carvalho Chehab  *
57d6317c68SMauro Carvalho Chehab  * Return 0 on success or negative value in case of error.
58d6317c68SMauro Carvalho Chehab  */
as10x_cmd_turn_off(struct as10x_bus_adapter_t * adap)59d6317c68SMauro Carvalho Chehab int as10x_cmd_turn_off(struct as10x_bus_adapter_t *adap)
60d6317c68SMauro Carvalho Chehab {
61d6317c68SMauro Carvalho Chehab 	int error = AS10X_CMD_ERROR;
62d6317c68SMauro Carvalho Chehab 	struct as10x_cmd_t *pcmd, *prsp;
63d6317c68SMauro Carvalho Chehab 
64d6317c68SMauro Carvalho Chehab 	pcmd = adap->cmd;
65d6317c68SMauro Carvalho Chehab 	prsp = adap->rsp;
66d6317c68SMauro Carvalho Chehab 
67d6317c68SMauro Carvalho Chehab 	/* prepare command */
68d6317c68SMauro Carvalho Chehab 	as10x_cmd_build(pcmd, (++adap->cmd_xid),
69d6317c68SMauro Carvalho Chehab 			sizeof(pcmd->body.turn_off.req));
70d6317c68SMauro Carvalho Chehab 
71d6317c68SMauro Carvalho Chehab 	/* fill command */
72d6317c68SMauro Carvalho Chehab 	pcmd->body.turn_off.req.proc_id = cpu_to_le16(CONTROL_PROC_TURNOFF);
73d6317c68SMauro Carvalho Chehab 
74d6317c68SMauro Carvalho Chehab 	/* send command */
75d6317c68SMauro Carvalho Chehab 	if (adap->ops->xfer_cmd) {
76d6317c68SMauro Carvalho Chehab 		error = adap->ops->xfer_cmd(
77d6317c68SMauro Carvalho Chehab 			adap, (uint8_t *) pcmd,
78d6317c68SMauro Carvalho Chehab 			sizeof(pcmd->body.turn_off.req) + HEADER_SIZE,
79d6317c68SMauro Carvalho Chehab 			(uint8_t *) prsp,
80d6317c68SMauro Carvalho Chehab 			sizeof(prsp->body.turn_off.rsp) + HEADER_SIZE);
81d6317c68SMauro Carvalho Chehab 	}
82d6317c68SMauro Carvalho Chehab 
83d6317c68SMauro Carvalho Chehab 	if (error < 0)
84d6317c68SMauro Carvalho Chehab 		goto out;
85d6317c68SMauro Carvalho Chehab 
86d6317c68SMauro Carvalho Chehab 	/* parse response */
87d6317c68SMauro Carvalho Chehab 	error = as10x_rsp_parse(prsp, CONTROL_PROC_TURNOFF_RSP);
88d6317c68SMauro Carvalho Chehab 
89d6317c68SMauro Carvalho Chehab out:
90d6317c68SMauro Carvalho Chehab 	return error;
91d6317c68SMauro Carvalho Chehab }
92d6317c68SMauro Carvalho Chehab 
93d6317c68SMauro Carvalho Chehab /**
94d6317c68SMauro Carvalho Chehab  * as10x_cmd_set_tune - send set tune command to AS10x
95d6317c68SMauro Carvalho Chehab  * @adap:    pointer to AS10x bus adapter
96d6317c68SMauro Carvalho Chehab  * @ptune:   tune parameters
97d6317c68SMauro Carvalho Chehab  *
98d6317c68SMauro Carvalho Chehab  * Return 0 on success or negative value in case of error.
99d6317c68SMauro Carvalho Chehab  */
as10x_cmd_set_tune(struct as10x_bus_adapter_t * adap,struct as10x_tune_args * ptune)100d6317c68SMauro Carvalho Chehab int as10x_cmd_set_tune(struct as10x_bus_adapter_t *adap,
101d6317c68SMauro Carvalho Chehab 		       struct as10x_tune_args *ptune)
102d6317c68SMauro Carvalho Chehab {
103d6317c68SMauro Carvalho Chehab 	int error = AS10X_CMD_ERROR;
104d6317c68SMauro Carvalho Chehab 	struct as10x_cmd_t *preq, *prsp;
105d6317c68SMauro Carvalho Chehab 
106d6317c68SMauro Carvalho Chehab 	preq = adap->cmd;
107d6317c68SMauro Carvalho Chehab 	prsp = adap->rsp;
108d6317c68SMauro Carvalho Chehab 
109d6317c68SMauro Carvalho Chehab 	/* prepare command */
110d6317c68SMauro Carvalho Chehab 	as10x_cmd_build(preq, (++adap->cmd_xid),
111d6317c68SMauro Carvalho Chehab 			sizeof(preq->body.set_tune.req));
112d6317c68SMauro Carvalho Chehab 
113d6317c68SMauro Carvalho Chehab 	/* fill command */
114d6317c68SMauro Carvalho Chehab 	preq->body.set_tune.req.proc_id = cpu_to_le16(CONTROL_PROC_SETTUNE);
115d51a12c9SMauro Carvalho Chehab 	preq->body.set_tune.req.args.freq = (__force __u32)cpu_to_le32(ptune->freq);
116d6317c68SMauro Carvalho Chehab 	preq->body.set_tune.req.args.bandwidth = ptune->bandwidth;
117d6317c68SMauro Carvalho Chehab 	preq->body.set_tune.req.args.hier_select = ptune->hier_select;
118d6317c68SMauro Carvalho Chehab 	preq->body.set_tune.req.args.modulation = ptune->modulation;
119d6317c68SMauro Carvalho Chehab 	preq->body.set_tune.req.args.hierarchy = ptune->hierarchy;
120d6317c68SMauro Carvalho Chehab 	preq->body.set_tune.req.args.interleaving_mode  =
121d6317c68SMauro Carvalho Chehab 		ptune->interleaving_mode;
122d6317c68SMauro Carvalho Chehab 	preq->body.set_tune.req.args.code_rate  = ptune->code_rate;
123d6317c68SMauro Carvalho Chehab 	preq->body.set_tune.req.args.guard_interval = ptune->guard_interval;
124d6317c68SMauro Carvalho Chehab 	preq->body.set_tune.req.args.transmission_mode  =
125d6317c68SMauro Carvalho Chehab 		ptune->transmission_mode;
126d6317c68SMauro Carvalho Chehab 
127d6317c68SMauro Carvalho Chehab 	/* send command */
128d6317c68SMauro Carvalho Chehab 	if (adap->ops->xfer_cmd) {
129d6317c68SMauro Carvalho Chehab 		error = adap->ops->xfer_cmd(adap,
130d6317c68SMauro Carvalho Chehab 					    (uint8_t *) preq,
131d6317c68SMauro Carvalho Chehab 					    sizeof(preq->body.set_tune.req)
132d6317c68SMauro Carvalho Chehab 					    + HEADER_SIZE,
133d6317c68SMauro Carvalho Chehab 					    (uint8_t *) prsp,
134d6317c68SMauro Carvalho Chehab 					    sizeof(prsp->body.set_tune.rsp)
135d6317c68SMauro Carvalho Chehab 					    + HEADER_SIZE);
136d6317c68SMauro Carvalho Chehab 	}
137d6317c68SMauro Carvalho Chehab 
138d6317c68SMauro Carvalho Chehab 	if (error < 0)
139d6317c68SMauro Carvalho Chehab 		goto out;
140d6317c68SMauro Carvalho Chehab 
141d6317c68SMauro Carvalho Chehab 	/* parse response */
142d6317c68SMauro Carvalho Chehab 	error = as10x_rsp_parse(prsp, CONTROL_PROC_SETTUNE_RSP);
143d6317c68SMauro Carvalho Chehab 
144d6317c68SMauro Carvalho Chehab out:
145d6317c68SMauro Carvalho Chehab 	return error;
146d6317c68SMauro Carvalho Chehab }
147d6317c68SMauro Carvalho Chehab 
148d6317c68SMauro Carvalho Chehab /**
149d6317c68SMauro Carvalho Chehab  * as10x_cmd_get_tune_status - send get tune status command to AS10x
150d6317c68SMauro Carvalho Chehab  * @adap: pointer to AS10x bus adapter
151d6317c68SMauro Carvalho Chehab  * @pstatus: pointer to updated status structure of the current tune
152d6317c68SMauro Carvalho Chehab  *
153d6317c68SMauro Carvalho Chehab  * Return 0 on success or negative value in case of error.
154d6317c68SMauro Carvalho Chehab  */
as10x_cmd_get_tune_status(struct as10x_bus_adapter_t * adap,struct as10x_tune_status * pstatus)155d6317c68SMauro Carvalho Chehab int as10x_cmd_get_tune_status(struct as10x_bus_adapter_t *adap,
156d6317c68SMauro Carvalho Chehab 			      struct as10x_tune_status *pstatus)
157d6317c68SMauro Carvalho Chehab {
158d6317c68SMauro Carvalho Chehab 	int error = AS10X_CMD_ERROR;
159d6317c68SMauro Carvalho Chehab 	struct as10x_cmd_t  *preq, *prsp;
160d6317c68SMauro Carvalho Chehab 
161d6317c68SMauro Carvalho Chehab 	preq = adap->cmd;
162d6317c68SMauro Carvalho Chehab 	prsp = adap->rsp;
163d6317c68SMauro Carvalho Chehab 
164d6317c68SMauro Carvalho Chehab 	/* prepare command */
165d6317c68SMauro Carvalho Chehab 	as10x_cmd_build(preq, (++adap->cmd_xid),
166d6317c68SMauro Carvalho Chehab 			sizeof(preq->body.get_tune_status.req));
167d6317c68SMauro Carvalho Chehab 
168d6317c68SMauro Carvalho Chehab 	/* fill command */
169d6317c68SMauro Carvalho Chehab 	preq->body.get_tune_status.req.proc_id =
170d6317c68SMauro Carvalho Chehab 		cpu_to_le16(CONTROL_PROC_GETTUNESTAT);
171d6317c68SMauro Carvalho Chehab 
172d6317c68SMauro Carvalho Chehab 	/* send command */
173d6317c68SMauro Carvalho Chehab 	if (adap->ops->xfer_cmd) {
174d6317c68SMauro Carvalho Chehab 		error = adap->ops->xfer_cmd(
175d6317c68SMauro Carvalho Chehab 			adap,
176d6317c68SMauro Carvalho Chehab 			(uint8_t *) preq,
177d6317c68SMauro Carvalho Chehab 			sizeof(preq->body.get_tune_status.req) + HEADER_SIZE,
178d6317c68SMauro Carvalho Chehab 			(uint8_t *) prsp,
179d6317c68SMauro Carvalho Chehab 			sizeof(prsp->body.get_tune_status.rsp) + HEADER_SIZE);
180d6317c68SMauro Carvalho Chehab 	}
181d6317c68SMauro Carvalho Chehab 
182d6317c68SMauro Carvalho Chehab 	if (error < 0)
183d6317c68SMauro Carvalho Chehab 		goto out;
184d6317c68SMauro Carvalho Chehab 
185d6317c68SMauro Carvalho Chehab 	/* parse response */
186d6317c68SMauro Carvalho Chehab 	error = as10x_rsp_parse(prsp, CONTROL_PROC_GETTUNESTAT_RSP);
187d6317c68SMauro Carvalho Chehab 	if (error < 0)
188d6317c68SMauro Carvalho Chehab 		goto out;
189d6317c68SMauro Carvalho Chehab 
190d6317c68SMauro Carvalho Chehab 	/* Response OK -> get response data */
191d6317c68SMauro Carvalho Chehab 	pstatus->tune_state = prsp->body.get_tune_status.rsp.sts.tune_state;
192d6317c68SMauro Carvalho Chehab 	pstatus->signal_strength  =
193d51a12c9SMauro Carvalho Chehab 		le16_to_cpu((__force __le16)prsp->body.get_tune_status.rsp.sts.signal_strength);
194d51a12c9SMauro Carvalho Chehab 	pstatus->PER = le16_to_cpu((__force __le16)prsp->body.get_tune_status.rsp.sts.PER);
195d51a12c9SMauro Carvalho Chehab 	pstatus->BER = le16_to_cpu((__force __le16)prsp->body.get_tune_status.rsp.sts.BER);
196d6317c68SMauro Carvalho Chehab 
197d6317c68SMauro Carvalho Chehab out:
198d6317c68SMauro Carvalho Chehab 	return error;
199d6317c68SMauro Carvalho Chehab }
200d6317c68SMauro Carvalho Chehab 
201d6317c68SMauro Carvalho Chehab /**
202d6317c68SMauro Carvalho Chehab  * as10x_cmd_get_tps - send get TPS command to AS10x
203d6317c68SMauro Carvalho Chehab  * @adap:      pointer to AS10x handle
204d6317c68SMauro Carvalho Chehab  * @ptps:      pointer to TPS parameters structure
205d6317c68SMauro Carvalho Chehab  *
206d6317c68SMauro Carvalho Chehab  * Return 0 on success or negative value in case of error.
207d6317c68SMauro Carvalho Chehab  */
as10x_cmd_get_tps(struct as10x_bus_adapter_t * adap,struct as10x_tps * ptps)208d6317c68SMauro Carvalho Chehab int as10x_cmd_get_tps(struct as10x_bus_adapter_t *adap, struct as10x_tps *ptps)
209d6317c68SMauro Carvalho Chehab {
210d6317c68SMauro Carvalho Chehab 	int error = AS10X_CMD_ERROR;
211d6317c68SMauro Carvalho Chehab 	struct as10x_cmd_t *pcmd, *prsp;
212d6317c68SMauro Carvalho Chehab 
213d6317c68SMauro Carvalho Chehab 	pcmd = adap->cmd;
214d6317c68SMauro Carvalho Chehab 	prsp = adap->rsp;
215d6317c68SMauro Carvalho Chehab 
216d6317c68SMauro Carvalho Chehab 	/* prepare command */
217d6317c68SMauro Carvalho Chehab 	as10x_cmd_build(pcmd, (++adap->cmd_xid),
218d6317c68SMauro Carvalho Chehab 			sizeof(pcmd->body.get_tps.req));
219d6317c68SMauro Carvalho Chehab 
220d6317c68SMauro Carvalho Chehab 	/* fill command */
221d6317c68SMauro Carvalho Chehab 	pcmd->body.get_tune_status.req.proc_id =
222d6317c68SMauro Carvalho Chehab 		cpu_to_le16(CONTROL_PROC_GETTPS);
223d6317c68SMauro Carvalho Chehab 
224d6317c68SMauro Carvalho Chehab 	/* send command */
225d6317c68SMauro Carvalho Chehab 	if (adap->ops->xfer_cmd) {
226d6317c68SMauro Carvalho Chehab 		error = adap->ops->xfer_cmd(adap,
227d6317c68SMauro Carvalho Chehab 					    (uint8_t *) pcmd,
228d6317c68SMauro Carvalho Chehab 					    sizeof(pcmd->body.get_tps.req) +
229d6317c68SMauro Carvalho Chehab 					    HEADER_SIZE,
230d6317c68SMauro Carvalho Chehab 					    (uint8_t *) prsp,
231d6317c68SMauro Carvalho Chehab 					    sizeof(prsp->body.get_tps.rsp) +
232d6317c68SMauro Carvalho Chehab 					    HEADER_SIZE);
233d6317c68SMauro Carvalho Chehab 	}
234d6317c68SMauro Carvalho Chehab 
235d6317c68SMauro Carvalho Chehab 	if (error < 0)
236d6317c68SMauro Carvalho Chehab 		goto out;
237d6317c68SMauro Carvalho Chehab 
238d6317c68SMauro Carvalho Chehab 	/* parse response */
239d6317c68SMauro Carvalho Chehab 	error = as10x_rsp_parse(prsp, CONTROL_PROC_GETTPS_RSP);
240d6317c68SMauro Carvalho Chehab 	if (error < 0)
241d6317c68SMauro Carvalho Chehab 		goto out;
242d6317c68SMauro Carvalho Chehab 
243d6317c68SMauro Carvalho Chehab 	/* Response OK -> get response data */
244d6317c68SMauro Carvalho Chehab 	ptps->modulation = prsp->body.get_tps.rsp.tps.modulation;
245d6317c68SMauro Carvalho Chehab 	ptps->hierarchy = prsp->body.get_tps.rsp.tps.hierarchy;
246d6317c68SMauro Carvalho Chehab 	ptps->interleaving_mode = prsp->body.get_tps.rsp.tps.interleaving_mode;
247d6317c68SMauro Carvalho Chehab 	ptps->code_rate_HP = prsp->body.get_tps.rsp.tps.code_rate_HP;
248d6317c68SMauro Carvalho Chehab 	ptps->code_rate_LP = prsp->body.get_tps.rsp.tps.code_rate_LP;
249d6317c68SMauro Carvalho Chehab 	ptps->guard_interval = prsp->body.get_tps.rsp.tps.guard_interval;
250d6317c68SMauro Carvalho Chehab 	ptps->transmission_mode  = prsp->body.get_tps.rsp.tps.transmission_mode;
251d6317c68SMauro Carvalho Chehab 	ptps->DVBH_mask_HP = prsp->body.get_tps.rsp.tps.DVBH_mask_HP;
252d6317c68SMauro Carvalho Chehab 	ptps->DVBH_mask_LP = prsp->body.get_tps.rsp.tps.DVBH_mask_LP;
253d51a12c9SMauro Carvalho Chehab 	ptps->cell_ID = le16_to_cpu((__force __le16)prsp->body.get_tps.rsp.tps.cell_ID);
254d6317c68SMauro Carvalho Chehab 
255d6317c68SMauro Carvalho Chehab out:
256d6317c68SMauro Carvalho Chehab 	return error;
257d6317c68SMauro Carvalho Chehab }
258d6317c68SMauro Carvalho Chehab 
259d6317c68SMauro Carvalho Chehab /**
260d6317c68SMauro Carvalho Chehab  * as10x_cmd_get_demod_stats - send get demod stats command to AS10x
261d6317c68SMauro Carvalho Chehab  * @adap:          pointer to AS10x bus adapter
262d6317c68SMauro Carvalho Chehab  * @pdemod_stats:  pointer to demod stats parameters structure
263d6317c68SMauro Carvalho Chehab  *
264d6317c68SMauro Carvalho Chehab  * Return 0 on success or negative value in case of error.
265d6317c68SMauro Carvalho Chehab  */
as10x_cmd_get_demod_stats(struct as10x_bus_adapter_t * adap,struct as10x_demod_stats * pdemod_stats)266d6317c68SMauro Carvalho Chehab int as10x_cmd_get_demod_stats(struct as10x_bus_adapter_t *adap,
267d6317c68SMauro Carvalho Chehab 			      struct as10x_demod_stats *pdemod_stats)
268d6317c68SMauro Carvalho Chehab {
269d6317c68SMauro Carvalho Chehab 	int error = AS10X_CMD_ERROR;
270d6317c68SMauro Carvalho Chehab 	struct as10x_cmd_t *pcmd, *prsp;
271d6317c68SMauro Carvalho Chehab 
272d6317c68SMauro Carvalho Chehab 	pcmd = adap->cmd;
273d6317c68SMauro Carvalho Chehab 	prsp = adap->rsp;
274d6317c68SMauro Carvalho Chehab 
275d6317c68SMauro Carvalho Chehab 	/* prepare command */
276d6317c68SMauro Carvalho Chehab 	as10x_cmd_build(pcmd, (++adap->cmd_xid),
277d6317c68SMauro Carvalho Chehab 			sizeof(pcmd->body.get_demod_stats.req));
278d6317c68SMauro Carvalho Chehab 
279d6317c68SMauro Carvalho Chehab 	/* fill command */
280d6317c68SMauro Carvalho Chehab 	pcmd->body.get_demod_stats.req.proc_id =
281d6317c68SMauro Carvalho Chehab 		cpu_to_le16(CONTROL_PROC_GET_DEMOD_STATS);
282d6317c68SMauro Carvalho Chehab 
283d6317c68SMauro Carvalho Chehab 	/* send command */
284d6317c68SMauro Carvalho Chehab 	if (adap->ops->xfer_cmd) {
285d6317c68SMauro Carvalho Chehab 		error = adap->ops->xfer_cmd(adap,
286d6317c68SMauro Carvalho Chehab 				(uint8_t *) pcmd,
287d6317c68SMauro Carvalho Chehab 				sizeof(pcmd->body.get_demod_stats.req)
288d6317c68SMauro Carvalho Chehab 				+ HEADER_SIZE,
289d6317c68SMauro Carvalho Chehab 				(uint8_t *) prsp,
290d6317c68SMauro Carvalho Chehab 				sizeof(prsp->body.get_demod_stats.rsp)
291d6317c68SMauro Carvalho Chehab 				+ HEADER_SIZE);
292d6317c68SMauro Carvalho Chehab 	}
293d6317c68SMauro Carvalho Chehab 
294d6317c68SMauro Carvalho Chehab 	if (error < 0)
295d6317c68SMauro Carvalho Chehab 		goto out;
296d6317c68SMauro Carvalho Chehab 
297d6317c68SMauro Carvalho Chehab 	/* parse response */
298d6317c68SMauro Carvalho Chehab 	error = as10x_rsp_parse(prsp, CONTROL_PROC_GET_DEMOD_STATS_RSP);
299d6317c68SMauro Carvalho Chehab 	if (error < 0)
300d6317c68SMauro Carvalho Chehab 		goto out;
301d6317c68SMauro Carvalho Chehab 
302d6317c68SMauro Carvalho Chehab 	/* Response OK -> get response data */
303d6317c68SMauro Carvalho Chehab 	pdemod_stats->frame_count =
304d51a12c9SMauro Carvalho Chehab 		le32_to_cpu((__force __le32)prsp->body.get_demod_stats.rsp.stats.frame_count);
305d6317c68SMauro Carvalho Chehab 	pdemod_stats->bad_frame_count =
306d51a12c9SMauro Carvalho Chehab 		le32_to_cpu((__force __le32)prsp->body.get_demod_stats.rsp.stats.bad_frame_count);
307d6317c68SMauro Carvalho Chehab 	pdemod_stats->bytes_fixed_by_rs =
308d51a12c9SMauro Carvalho Chehab 		le32_to_cpu((__force __le32)prsp->body.get_demod_stats.rsp.stats.bytes_fixed_by_rs);
309d6317c68SMauro Carvalho Chehab 	pdemod_stats->mer =
310d51a12c9SMauro Carvalho Chehab 		le16_to_cpu((__force __le16)prsp->body.get_demod_stats.rsp.stats.mer);
311d6317c68SMauro Carvalho Chehab 	pdemod_stats->has_started =
312d6317c68SMauro Carvalho Chehab 		prsp->body.get_demod_stats.rsp.stats.has_started;
313d6317c68SMauro Carvalho Chehab 
314d6317c68SMauro Carvalho Chehab out:
315d6317c68SMauro Carvalho Chehab 	return error;
316d6317c68SMauro Carvalho Chehab }
317d6317c68SMauro Carvalho Chehab 
318d6317c68SMauro Carvalho Chehab /**
319d6317c68SMauro Carvalho Chehab  * as10x_cmd_get_impulse_resp - send get impulse response command to AS10x
320d6317c68SMauro Carvalho Chehab  * @adap:     pointer to AS10x bus adapter
321d6317c68SMauro Carvalho Chehab  * @is_ready: pointer to value indicating when impulse
322d6317c68SMauro Carvalho Chehab  *	      response data is ready
323d6317c68SMauro Carvalho Chehab  *
324d6317c68SMauro Carvalho Chehab  * Return 0 on success or negative value in case of error.
325d6317c68SMauro Carvalho Chehab  */
as10x_cmd_get_impulse_resp(struct as10x_bus_adapter_t * adap,uint8_t * is_ready)326d6317c68SMauro Carvalho Chehab int as10x_cmd_get_impulse_resp(struct as10x_bus_adapter_t *adap,
327d6317c68SMauro Carvalho Chehab 			       uint8_t *is_ready)
328d6317c68SMauro Carvalho Chehab {
329d6317c68SMauro Carvalho Chehab 	int error = AS10X_CMD_ERROR;
330d6317c68SMauro Carvalho Chehab 	struct as10x_cmd_t *pcmd, *prsp;
331d6317c68SMauro Carvalho Chehab 
332d6317c68SMauro Carvalho Chehab 	pcmd = adap->cmd;
333d6317c68SMauro Carvalho Chehab 	prsp = adap->rsp;
334d6317c68SMauro Carvalho Chehab 
335d6317c68SMauro Carvalho Chehab 	/* prepare command */
336d6317c68SMauro Carvalho Chehab 	as10x_cmd_build(pcmd, (++adap->cmd_xid),
337d6317c68SMauro Carvalho Chehab 			sizeof(pcmd->body.get_impulse_rsp.req));
338d6317c68SMauro Carvalho Chehab 
339d6317c68SMauro Carvalho Chehab 	/* fill command */
340d6317c68SMauro Carvalho Chehab 	pcmd->body.get_impulse_rsp.req.proc_id =
341d6317c68SMauro Carvalho Chehab 		cpu_to_le16(CONTROL_PROC_GET_IMPULSE_RESP);
342d6317c68SMauro Carvalho Chehab 
343d6317c68SMauro Carvalho Chehab 	/* send command */
344d6317c68SMauro Carvalho Chehab 	if (adap->ops->xfer_cmd) {
345d6317c68SMauro Carvalho Chehab 		error = adap->ops->xfer_cmd(adap,
346d6317c68SMauro Carvalho Chehab 					(uint8_t *) pcmd,
347d6317c68SMauro Carvalho Chehab 					sizeof(pcmd->body.get_impulse_rsp.req)
348d6317c68SMauro Carvalho Chehab 					+ HEADER_SIZE,
349d6317c68SMauro Carvalho Chehab 					(uint8_t *) prsp,
350d6317c68SMauro Carvalho Chehab 					sizeof(prsp->body.get_impulse_rsp.rsp)
351d6317c68SMauro Carvalho Chehab 					+ HEADER_SIZE);
352d6317c68SMauro Carvalho Chehab 	}
353d6317c68SMauro Carvalho Chehab 
354d6317c68SMauro Carvalho Chehab 	if (error < 0)
355d6317c68SMauro Carvalho Chehab 		goto out;
356d6317c68SMauro Carvalho Chehab 
357d6317c68SMauro Carvalho Chehab 	/* parse response */
358d6317c68SMauro Carvalho Chehab 	error = as10x_rsp_parse(prsp, CONTROL_PROC_GET_IMPULSE_RESP_RSP);
359d6317c68SMauro Carvalho Chehab 	if (error < 0)
360d6317c68SMauro Carvalho Chehab 		goto out;
361d6317c68SMauro Carvalho Chehab 
362d6317c68SMauro Carvalho Chehab 	/* Response OK -> get response data */
363d6317c68SMauro Carvalho Chehab 	*is_ready = prsp->body.get_impulse_rsp.rsp.is_ready;
364d6317c68SMauro Carvalho Chehab 
365d6317c68SMauro Carvalho Chehab out:
366d6317c68SMauro Carvalho Chehab 	return error;
367d6317c68SMauro Carvalho Chehab }
368d6317c68SMauro Carvalho Chehab 
369d6317c68SMauro Carvalho Chehab /**
370d6317c68SMauro Carvalho Chehab  * as10x_cmd_build - build AS10x command header
371d6317c68SMauro Carvalho Chehab  * @pcmd:     pointer to AS10x command buffer
372d6317c68SMauro Carvalho Chehab  * @xid:      sequence id of the command
373d6317c68SMauro Carvalho Chehab  * @cmd_len:  length of the command
374d6317c68SMauro Carvalho Chehab  */
as10x_cmd_build(struct as10x_cmd_t * pcmd,uint16_t xid,uint16_t cmd_len)375d6317c68SMauro Carvalho Chehab void as10x_cmd_build(struct as10x_cmd_t *pcmd,
376d6317c68SMauro Carvalho Chehab 		     uint16_t xid, uint16_t cmd_len)
377d6317c68SMauro Carvalho Chehab {
378d6317c68SMauro Carvalho Chehab 	pcmd->header.req_id = cpu_to_le16(xid);
379d6317c68SMauro Carvalho Chehab 	pcmd->header.prog = cpu_to_le16(SERVICE_PROG_ID);
380d6317c68SMauro Carvalho Chehab 	pcmd->header.version = cpu_to_le16(SERVICE_PROG_VERSION);
381d6317c68SMauro Carvalho Chehab 	pcmd->header.data_len = cpu_to_le16(cmd_len);
382d6317c68SMauro Carvalho Chehab }
383d6317c68SMauro Carvalho Chehab 
384d6317c68SMauro Carvalho Chehab /**
385d6317c68SMauro Carvalho Chehab  * as10x_rsp_parse - Parse command response
386d6317c68SMauro Carvalho Chehab  * @prsp:       pointer to AS10x command buffer
387d6317c68SMauro Carvalho Chehab  * @proc_id:    id of the command
388d6317c68SMauro Carvalho Chehab  *
389d6317c68SMauro Carvalho Chehab  * Return 0 on success or negative value in case of error.
390d6317c68SMauro Carvalho Chehab  */
as10x_rsp_parse(struct as10x_cmd_t * prsp,uint16_t proc_id)391d6317c68SMauro Carvalho Chehab int as10x_rsp_parse(struct as10x_cmd_t *prsp, uint16_t proc_id)
392d6317c68SMauro Carvalho Chehab {
393d6317c68SMauro Carvalho Chehab 	int error;
394d6317c68SMauro Carvalho Chehab 
395d6317c68SMauro Carvalho Chehab 	/* extract command error code */
396d6317c68SMauro Carvalho Chehab 	error = prsp->body.common.rsp.error;
397d6317c68SMauro Carvalho Chehab 
398d6317c68SMauro Carvalho Chehab 	if ((error == 0) &&
399d6317c68SMauro Carvalho Chehab 	    (le16_to_cpu(prsp->body.common.rsp.proc_id) == proc_id)) {
400d6317c68SMauro Carvalho Chehab 		return 0;
401d6317c68SMauro Carvalho Chehab 	}
402d6317c68SMauro Carvalho Chehab 
403d6317c68SMauro Carvalho Chehab 	return AS10X_CMD_ERROR;
404d6317c68SMauro Carvalho Chehab }
405