Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
as10x_cmd.c
Go to the documentation of this file.
1 /*
2  * Abilis Systems Single DVB-T Receiver
3  * Copyright (C) 2008 Pierrick Hascoet <[email protected]>
4  * Copyright (C) 2010 Devin Heitmueller <[email protected]>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2, or (at your option)
9  * any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  */
20 
21 #include <linux/kernel.h>
22 #include "as102_drv.h"
23 #include "as10x_types.h"
24 #include "as10x_cmd.h"
25 
33 {
34  int error = AS10X_CMD_ERROR;
35  struct as10x_cmd_t *pcmd, *prsp;
36 
37  ENTER();
38 
39  pcmd = adap->cmd;
40  prsp = adap->rsp;
41 
42  /* prepare command */
43  as10x_cmd_build(pcmd, (++adap->cmd_xid),
44  sizeof(pcmd->body.turn_on.req));
45 
46  /* fill command */
48 
49  /* send command */
50  if (adap->ops->xfer_cmd) {
51  error = adap->ops->xfer_cmd(adap, (uint8_t *) pcmd,
52  sizeof(pcmd->body.turn_on.req) +
54  (uint8_t *) prsp,
55  sizeof(prsp->body.turn_on.rsp) +
56  HEADER_SIZE);
57  }
58 
59  if (error < 0)
60  goto out;
61 
62  /* parse response */
64 
65 out:
66  LEAVE();
67  return error;
68 }
69 
77 {
78  int error = AS10X_CMD_ERROR;
79  struct as10x_cmd_t *pcmd, *prsp;
80 
81  ENTER();
82 
83  pcmd = adap->cmd;
84  prsp = adap->rsp;
85 
86  /* prepare command */
87  as10x_cmd_build(pcmd, (++adap->cmd_xid),
88  sizeof(pcmd->body.turn_off.req));
89 
90  /* fill command */
92 
93  /* send command */
94  if (adap->ops->xfer_cmd) {
95  error = adap->ops->xfer_cmd(
96  adap, (uint8_t *) pcmd,
97  sizeof(pcmd->body.turn_off.req) + HEADER_SIZE,
98  (uint8_t *) prsp,
99  sizeof(prsp->body.turn_off.rsp) + HEADER_SIZE);
100  }
101 
102  if (error < 0)
103  goto out;
104 
105  /* parse response */
107 
108 out:
109  LEAVE();
110  return error;
111 }
112 
121  struct as10x_tune_args *ptune)
122 {
123  int error = AS10X_CMD_ERROR;
124  struct as10x_cmd_t *preq, *prsp;
125 
126  ENTER();
127 
128  preq = adap->cmd;
129  prsp = adap->rsp;
130 
131  /* prepare command */
132  as10x_cmd_build(preq, (++adap->cmd_xid),
133  sizeof(preq->body.set_tune.req));
134 
135  /* fill command */
137  preq->body.set_tune.req.args.freq = cpu_to_le32(ptune->freq);
138  preq->body.set_tune.req.args.bandwidth = ptune->bandwidth;
139  preq->body.set_tune.req.args.hier_select = ptune->hier_select;
140  preq->body.set_tune.req.args.modulation = ptune->modulation;
141  preq->body.set_tune.req.args.hierarchy = ptune->hierarchy;
142  preq->body.set_tune.req.args.interleaving_mode =
143  ptune->interleaving_mode;
144  preq->body.set_tune.req.args.code_rate = ptune->code_rate;
145  preq->body.set_tune.req.args.guard_interval = ptune->guard_interval;
146  preq->body.set_tune.req.args.transmission_mode =
147  ptune->transmission_mode;
148 
149  /* send command */
150  if (adap->ops->xfer_cmd) {
151  error = adap->ops->xfer_cmd(adap,
152  (uint8_t *) preq,
153  sizeof(preq->body.set_tune.req)
154  + HEADER_SIZE,
155  (uint8_t *) prsp,
156  sizeof(prsp->body.set_tune.rsp)
157  + HEADER_SIZE);
158  }
159 
160  if (error < 0)
161  goto out;
162 
163  /* parse response */
165 
166 out:
167  LEAVE();
168  return error;
169 }
170 
179  struct as10x_tune_status *pstatus)
180 {
181  int error = AS10X_CMD_ERROR;
182  struct as10x_cmd_t *preq, *prsp;
183 
184  ENTER();
185 
186  preq = adap->cmd;
187  prsp = adap->rsp;
188 
189  /* prepare command */
190  as10x_cmd_build(preq, (++adap->cmd_xid),
191  sizeof(preq->body.get_tune_status.req));
192 
193  /* fill command */
194  preq->body.get_tune_status.req.proc_id =
196 
197  /* send command */
198  if (adap->ops->xfer_cmd) {
199  error = adap->ops->xfer_cmd(
200  adap,
201  (uint8_t *) preq,
202  sizeof(preq->body.get_tune_status.req) + HEADER_SIZE,
203  (uint8_t *) prsp,
204  sizeof(prsp->body.get_tune_status.rsp) + HEADER_SIZE);
205  }
206 
207  if (error < 0)
208  goto out;
209 
210  /* parse response */
212  if (error < 0)
213  goto out;
214 
215  /* Response OK -> get response data */
216  pstatus->tune_state = prsp->body.get_tune_status.rsp.sts.tune_state;
217  pstatus->signal_strength =
218  le16_to_cpu(prsp->body.get_tune_status.rsp.sts.signal_strength);
219  pstatus->PER = le16_to_cpu(prsp->body.get_tune_status.rsp.sts.PER);
220  pstatus->BER = le16_to_cpu(prsp->body.get_tune_status.rsp.sts.BER);
221 
222 out:
223  LEAVE();
224  return error;
225 }
226 
234 int as10x_cmd_get_tps(struct as10x_bus_adapter_t *adap, struct as10x_tps *ptps)
235 {
236  int error = AS10X_CMD_ERROR;
237  struct as10x_cmd_t *pcmd, *prsp;
238 
239  ENTER();
240 
241  pcmd = adap->cmd;
242  prsp = adap->rsp;
243 
244  /* prepare command */
245  as10x_cmd_build(pcmd, (++adap->cmd_xid),
246  sizeof(pcmd->body.get_tps.req));
247 
248  /* fill command */
249  pcmd->body.get_tune_status.req.proc_id =
251 
252  /* send command */
253  if (adap->ops->xfer_cmd) {
254  error = adap->ops->xfer_cmd(adap,
255  (uint8_t *) pcmd,
256  sizeof(pcmd->body.get_tps.req) +
257  HEADER_SIZE,
258  (uint8_t *) prsp,
259  sizeof(prsp->body.get_tps.rsp) +
260  HEADER_SIZE);
261  }
262 
263  if (error < 0)
264  goto out;
265 
266  /* parse response */
268  if (error < 0)
269  goto out;
270 
271  /* Response OK -> get response data */
272  ptps->modulation = prsp->body.get_tps.rsp.tps.modulation;
273  ptps->hierarchy = prsp->body.get_tps.rsp.tps.hierarchy;
274  ptps->interleaving_mode = prsp->body.get_tps.rsp.tps.interleaving_mode;
275  ptps->code_rate_HP = prsp->body.get_tps.rsp.tps.code_rate_HP;
276  ptps->code_rate_LP = prsp->body.get_tps.rsp.tps.code_rate_LP;
277  ptps->guard_interval = prsp->body.get_tps.rsp.tps.guard_interval;
278  ptps->transmission_mode = prsp->body.get_tps.rsp.tps.transmission_mode;
279  ptps->DVBH_mask_HP = prsp->body.get_tps.rsp.tps.DVBH_mask_HP;
280  ptps->DVBH_mask_LP = prsp->body.get_tps.rsp.tps.DVBH_mask_LP;
281  ptps->cell_ID = le16_to_cpu(prsp->body.get_tps.rsp.tps.cell_ID);
282 
283 out:
284  LEAVE();
285  return error;
286 }
287 
296  struct as10x_demod_stats *pdemod_stats)
297 {
298  int error = AS10X_CMD_ERROR;
299  struct as10x_cmd_t *pcmd, *prsp;
300 
301  ENTER();
302 
303  pcmd = adap->cmd;
304  prsp = adap->rsp;
305 
306  /* prepare command */
307  as10x_cmd_build(pcmd, (++adap->cmd_xid),
308  sizeof(pcmd->body.get_demod_stats.req));
309 
310  /* fill command */
311  pcmd->body.get_demod_stats.req.proc_id =
313 
314  /* send command */
315  if (adap->ops->xfer_cmd) {
316  error = adap->ops->xfer_cmd(adap,
317  (uint8_t *) pcmd,
318  sizeof(pcmd->body.get_demod_stats.req)
319  + HEADER_SIZE,
320  (uint8_t *) prsp,
321  sizeof(prsp->body.get_demod_stats.rsp)
322  + HEADER_SIZE);
323  }
324 
325  if (error < 0)
326  goto out;
327 
328  /* parse response */
330  if (error < 0)
331  goto out;
332 
333  /* Response OK -> get response data */
334  pdemod_stats->frame_count =
335  le32_to_cpu(prsp->body.get_demod_stats.rsp.stats.frame_count);
336  pdemod_stats->bad_frame_count =
337  le32_to_cpu(prsp->body.get_demod_stats.rsp.stats.bad_frame_count);
338  pdemod_stats->bytes_fixed_by_rs =
339  le32_to_cpu(prsp->body.get_demod_stats.rsp.stats.bytes_fixed_by_rs);
340  pdemod_stats->mer =
341  le16_to_cpu(prsp->body.get_demod_stats.rsp.stats.mer);
342  pdemod_stats->has_started =
343  prsp->body.get_demod_stats.rsp.stats.has_started;
344 
345 out:
346  LEAVE();
347  return error;
348 }
349 
359  uint8_t *is_ready)
360 {
361  int error = AS10X_CMD_ERROR;
362  struct as10x_cmd_t *pcmd, *prsp;
363 
364  ENTER();
365 
366  pcmd = adap->cmd;
367  prsp = adap->rsp;
368 
369  /* prepare command */
370  as10x_cmd_build(pcmd, (++adap->cmd_xid),
371  sizeof(pcmd->body.get_impulse_rsp.req));
372 
373  /* fill command */
374  pcmd->body.get_impulse_rsp.req.proc_id =
376 
377  /* send command */
378  if (adap->ops->xfer_cmd) {
379  error = adap->ops->xfer_cmd(adap,
380  (uint8_t *) pcmd,
381  sizeof(pcmd->body.get_impulse_rsp.req)
382  + HEADER_SIZE,
383  (uint8_t *) prsp,
384  sizeof(prsp->body.get_impulse_rsp.rsp)
385  + HEADER_SIZE);
386  }
387 
388  if (error < 0)
389  goto out;
390 
391  /* parse response */
393  if (error < 0)
394  goto out;
395 
396  /* Response OK -> get response data */
397  *is_ready = prsp->body.get_impulse_rsp.rsp.is_ready;
398 
399 out:
400  LEAVE();
401  return error;
402 }
403 
410 void as10x_cmd_build(struct as10x_cmd_t *pcmd,
412 {
413  pcmd->header.req_id = cpu_to_le16(xid);
414  pcmd->header.prog = cpu_to_le16(SERVICE_PROG_ID);
415  pcmd->header.version = cpu_to_le16(SERVICE_PROG_VERSION);
416  pcmd->header.data_len = cpu_to_le16(cmd_len);
417 }
418 
427 {
428  int error;
429 
430  /* extract command error code */
431  error = prsp->body.common.rsp.error;
432 
433  if ((error == 0) &&
434  (le16_to_cpu(prsp->body.common.rsp.proc_id) == proc_id)) {
435  return 0;
436  }
437 
438  return AS10X_CMD_ERROR;
439 }