Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
firedtv-fe.c
Go to the documentation of this file.
1 /*
2  * FireDTV driver (formerly known as FireSAT)
3  *
4  * Copyright (C) 2004 Andreas Monitzer <[email protected]>
5  * Copyright (C) 2008 Henrik Kurelid <[email protected]>
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License as
9  * published by the Free Software Foundation; either version 2 of
10  * the License, or (at your option) any later version.
11  */
12 
13 #include <linux/device.h>
14 #include <linux/errno.h>
15 #include <linux/kernel.h>
16 #include <linux/string.h>
17 #include <linux/types.h>
18 
19 #include <dvb_frontend.h>
20 
21 #include "firedtv.h"
22 
23 static int fdtv_dvb_init(struct dvb_frontend *fe)
24 {
25  struct firedtv *fdtv = fe->sec_priv;
26  int err;
27 
28  /* FIXME - allocate free channel at IRM */
29  fdtv->isochannel = fdtv->adapter.num;
30 
31  err = cmp_establish_pp_connection(fdtv, fdtv->subunit,
32  fdtv->isochannel);
33  if (err) {
34  dev_err(fdtv->device,
35  "could not establish point to point connection\n");
36  return err;
37  }
38 
39  return fdtv_start_iso(fdtv);
40 }
41 
42 static int fdtv_sleep(struct dvb_frontend *fe)
43 {
44  struct firedtv *fdtv = fe->sec_priv;
45 
46  fdtv_stop_iso(fdtv);
47  cmp_break_pp_connection(fdtv, fdtv->subunit, fdtv->isochannel);
48  fdtv->isochannel = -1;
49  return 0;
50 }
51 
52 #define LNBCONTROL_DONTCARE 0xff
53 
54 static int fdtv_diseqc_send_master_cmd(struct dvb_frontend *fe,
55  struct dvb_diseqc_master_cmd *cmd)
56 {
57  struct firedtv *fdtv = fe->sec_priv;
58 
60  LNBCONTROL_DONTCARE, 1, cmd);
61 }
62 
63 static int fdtv_diseqc_send_burst(struct dvb_frontend *fe,
64  fe_sec_mini_cmd_t minicmd)
65 {
66  return 0;
67 }
68 
69 static int fdtv_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
70 {
71  struct firedtv *fdtv = fe->sec_priv;
72 
73  fdtv->tone = tone;
74  return 0;
75 }
76 
77 static int fdtv_set_voltage(struct dvb_frontend *fe,
79 {
80  struct firedtv *fdtv = fe->sec_priv;
81 
82  fdtv->voltage = voltage;
83  return 0;
84 }
85 
86 static int fdtv_read_status(struct dvb_frontend *fe, fe_status_t *status)
87 {
88  struct firedtv *fdtv = fe->sec_priv;
90 
91  if (avc_tuner_status(fdtv, &stat))
92  return -EINVAL;
93 
94  if (stat.no_rf)
95  *status = 0;
96  else
99  return 0;
100 }
101 
102 static int fdtv_read_ber(struct dvb_frontend *fe, u32 *ber)
103 {
104  struct firedtv *fdtv = fe->sec_priv;
105  struct firedtv_tuner_status stat;
106 
107  if (avc_tuner_status(fdtv, &stat))
108  return -EINVAL;
109 
110  *ber = stat.ber;
111  return 0;
112 }
113 
114 static int fdtv_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
115 {
116  struct firedtv *fdtv = fe->sec_priv;
117  struct firedtv_tuner_status stat;
118 
119  if (avc_tuner_status(fdtv, &stat))
120  return -EINVAL;
121 
122  *strength = stat.signal_strength << 8;
123  return 0;
124 }
125 
126 static int fdtv_read_snr(struct dvb_frontend *fe, u16 *snr)
127 {
128  struct firedtv *fdtv = fe->sec_priv;
129  struct firedtv_tuner_status stat;
130 
131  if (avc_tuner_status(fdtv, &stat))
132  return -EINVAL;
133 
134  /* C/N[dB] = -10 * log10(snr / 65535) */
135  *snr = stat.carrier_noise_ratio * 257;
136  return 0;
137 }
138 
139 static int fdtv_read_uncorrected_blocks(struct dvb_frontend *fe, u32 *ucblocks)
140 {
141  return -EOPNOTSUPP;
142 }
143 
144 static int fdtv_set_frontend(struct dvb_frontend *fe)
145 {
147  struct firedtv *fdtv = fe->sec_priv;
148 
149  return avc_tuner_dsd(fdtv, p);
150 }
151 
152 void fdtv_frontend_init(struct firedtv *fdtv, const char *name)
153 {
154  struct dvb_frontend_ops *ops = &fdtv->fe.ops;
155  struct dvb_frontend_info *fi = &ops->info;
156 
157  ops->init = fdtv_dvb_init;
158  ops->sleep = fdtv_sleep;
159 
160  ops->set_frontend = fdtv_set_frontend;
161 
162  ops->read_status = fdtv_read_status;
163  ops->read_ber = fdtv_read_ber;
164  ops->read_signal_strength = fdtv_read_signal_strength;
165  ops->read_snr = fdtv_read_snr;
166  ops->read_ucblocks = fdtv_read_uncorrected_blocks;
167 
168  ops->diseqc_send_master_cmd = fdtv_diseqc_send_master_cmd;
169  ops->diseqc_send_burst = fdtv_diseqc_send_burst;
170  ops->set_tone = fdtv_set_tone;
171  ops->set_voltage = fdtv_set_voltage;
172 
173  switch (fdtv->type) {
174  case FIREDTV_DVB_S:
175  ops->delsys[0] = SYS_DVBS;
176 
177  fi->frequency_min = 950000;
178  fi->frequency_max = 2150000;
179  fi->frequency_stepsize = 125;
180  fi->symbol_rate_min = 1000000;
181  fi->symbol_rate_max = 40000000;
182 
190  FE_CAN_QPSK;
191  break;
192 
193  case FIREDTV_DVB_S2:
194  ops->delsys[0] = SYS_DVBS;
195  ops->delsys[1] = SYS_DVBS2;
196 
197  fi->frequency_min = 950000;
198  fi->frequency_max = 2150000;
199  fi->frequency_stepsize = 125;
200  fi->symbol_rate_min = 1000000;
201  fi->symbol_rate_max = 40000000;
202 
210  FE_CAN_QPSK |
212  break;
213 
214  case FIREDTV_DVB_C:
215  ops->delsys[0] = SYS_DVBC_ANNEX_A;
216 
217  fi->frequency_min = 47000000;
218  fi->frequency_max = 866000000;
219  fi->frequency_stepsize = 62500;
220  fi->symbol_rate_min = 870000;
221  fi->symbol_rate_max = 6900000;
222 
224  FE_CAN_QAM_16 |
225  FE_CAN_QAM_32 |
226  FE_CAN_QAM_64 |
230  break;
231 
232  case FIREDTV_DVB_T:
233  ops->delsys[0] = SYS_DVBT;
234 
235  fi->frequency_min = 49000000;
236  fi->frequency_max = 861000000;
237  fi->frequency_stepsize = 62500;
238 
244  break;
245 
246  default:
247  dev_err(fdtv->device, "no frontend for model type %d\n",
248  fdtv->type);
249  }
250  strcpy(fi->name, name);
251 
252  fdtv->fe.dvb = &fdtv->adapter;
253  fdtv->fe.sec_priv = fdtv;
254 }