aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/firesat/firesat_fe.c
diff options
context:
space:
mode:
authorStefan Richter <stefanr@s5r6.in-berlin.de>2008-11-02 07:45:00 -0500
committerStefan Richter <stefanr@s5r6.in-berlin.de>2009-02-24 08:51:28 -0500
commit8ae83cdf3297d7da301af36bdb6ff45bd331c6d0 (patch)
tree0363a01f1b3655507bdaf7e1f55af6a3ee9d26b7 /drivers/media/dvb/firesat/firesat_fe.c
parent00fc3072e484c1c6fdbd9c3b1851f866000a6cb9 (diff)
firedtv: cleanups and minor fixes
Combination of the following changes: Sun, 2 Nov 2008 13:45:00 +0100 (CET) firedtv: increase FCP frame length for DVB-S2 tune QSPK The last three bytes didn't go out to the wire. Effect of the fix not yet tested. Sun, 2 Nov 2008 13:45:00 +0100 (CET) firedtv: replace mdelay by msleep These functions can sleep (and in fact sleep for the duration of a whole FCP transaction). Hence msleep is more appropriate here. Sun, 2 Nov 2008 13:45:00 +0100 (CET) firedtv: trivial reorganization in avc_api Reduce nesting level by factoring code out of avc_tuner_dsd() into helper functions. Sun, 2 Nov 2008 13:45:00 +0100 (CET) firedtv: trivial cleanups in avc_api Use dev_err(), no CamelCase function names, adjust comment style, put #if 0 around unused code and add FIXME comments, standardize on lower-case hexadecimal constants, use ALIGN() for some frame length calculations, make a local function static... The code which writes FCP command frames and reads FCP response frames is not yet brought into canonical kernel coding style because this involves changes of typedefs (on-the-wire bitfields). Sun, 2 Nov 2008 13:45:00 +0100 (CET) firedtv: don't retry oPCR updates endlessly In the theoretical case that the target node wasn't handling the lock transactions as expected or there was continued interference by other initiating nodes, these functions wouldn't return for ages. Sun, 2 Nov 2008 13:45:00 +0100 (CET) firedtv: remove bitfield typedefs from cmp, fix for big endian CPUs Use macros/ inline functions/ standard byte order accessors to read and write oPCR register values (big endian bitfields, on-the-wire data). The new code may not be the ultimate optimum, but it doesn't occur in a hot path. This fixes the CMP code for big endian CPUs. So far I tested it only on a little endian CPU though. For now, include <asm/byteorder.h> instead of <linux/byteorder.h> because drivers/ieee1394/*.h also include the former. I will fix this in drivers/ieee1394 and firedtv later. Sun, 2 Nov 2008 13:45:00 +0100 (CET) firedtv: trivial cleanups in cmp Reduce nesting level by means of early exit and goto. Remove obsolete includes, use dev_err(), no CamelCase function names... Sun, 2 Nov 2008 13:45:00 +0100 (CET) firedtv: trivial cleanups in firesat-ci Whitespace, variable names, comment style... Also, use dvb_generic_open() and dvb_generic_release() directly as our hooks in struct file_operations because firedtv's wrappers merely called these generic functions. Sun, 2 Nov 2008 13:45:00 +0100 (CET) firedtv: remove CA debug code This looks like it is not necessary to have available for endusers who cannot patch kernels for bug reporting and tests of fixes. Sun, 2 Nov 2008 13:45:00 +0100 (CET) firedtv: remove AV/C debug code This looks like it is not necessary to have available for endusers who cannot patch kernels for bug reporting and tests of fixes. Sun, 2 Nov 2008 13:45:00 +0100 (CET) firedtv: remove various debug code Most of this was already commented out. And that which wasn't is not relevant in normal use. Mon, 29 Sep 2008 19:22:48 +0200 (CEST) firedtv: register input device as child of a FireWire device Instead of one virtual input device which exists for the whole lifetime of the driver and receives events from all connected FireDTVs, register one input device for each firedtv device. These input devices will show up as children of the respective firedtv devices in the sysfs hierarchy. However, the implementation falls short because of a bug in userspace: Udev's path_id script gets stuck with 100% CPU utilization, maybe because of an assumption about the maximum ieee1394 device hierarchy depth. To avoid this bug, we use the fw-host device instead of the proper unit_directory device as parent of the input device. There is hope that the port to the new firewire stack won't be inhibited by this userspace bug because there are no fw-host devices there. Mon, 29 Sep 2008 19:21:52 +0200 (CEST) firedtv: fix string comparison and a few sparse warnings Sparse found a bug: while ((kv_buf + kv_len - 1) == '\0') should have been while (kv_buf[kv_len - 1] == '\0') We fix it by a better implementation without a temporary copy. Also fix sparse warnings of 0 instead of NULL and signedness mismatches. Mon, 29 Sep 2008 19:21:20 +0200 (CEST) firedtv: remove unused struct members and redefine an int as a bool. Mon, 29 Sep 2008 19:20:36 +0200 (CEST) firedtv: fix initialization of dvb_frontend.ops There was a NULL pointer reference if no dvb_frontend_info was found. Also, don't directly assign struct typed values to struct typed variables. Instead write out assignments to individual strcut members. This reduces module size by about 1 kB. Mon, 29 Sep 2008 19:19:41 +0200 (CEST) firedtv: remove unused dual subunit code from initialization No FireDTVs with more than one subunit exists, hence simplify the initialization for the special case of one subunit. The driver was able to check for more than one subunit but was broken for more than two subunits. While we are at it, add several missing cleanups after failure, and include a few dynamically allocated structures diretly into struct firesat instead of allocating them separately. Mon, 29 Sep 2008 19:19:08 +0200 (CEST) firedtv: add vendor_id and version to driver match table Now that nodemgr was enhanced to match against the root directory's vendor ID if there isn't one in the unit directory, use this to prevent firedtv to be bound to wrong devices by accident. Also add the AV/C software version ID to the match flags for completeness; specifier ID and software only make sense as a pair. Mon, 29 Sep 2008 19:18:30 +0200 (CEST) firedtv: use hpsb_node_read(), _write(), _lock() because they are simpler and treat the node generation more correctly. While we are at it, clean up and simplify surrounding code. Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
Diffstat (limited to 'drivers/media/dvb/firesat/firesat_fe.c')
-rw-r--r--drivers/media/dvb/firesat/firesat_fe.c223
1 files changed, 96 insertions, 127 deletions
diff --git a/drivers/media/dvb/firesat/firesat_fe.c b/drivers/media/dvb/firesat/firesat_fe.c
index ec614ea8de22..1ed972b79573 100644
--- a/drivers/media/dvb/firesat/firesat_fe.c
+++ b/drivers/media/dvb/firesat/firesat_fe.c
@@ -12,6 +12,7 @@
12 12
13#include <linux/errno.h> 13#include <linux/errno.h>
14#include <linux/kernel.h> 14#include <linux/kernel.h>
15#include <linux/string.h>
15#include <linux/types.h> 16#include <linux/types.h>
16 17
17#include <dvb_frontend.h> 18#include <dvb_frontend.h>
@@ -22,22 +23,21 @@
22 23
23static int firesat_dvb_init(struct dvb_frontend *fe) 24static int firesat_dvb_init(struct dvb_frontend *fe)
24{ 25{
25 int result;
26 struct firesat *firesat = fe->sec_priv; 26 struct firesat *firesat = fe->sec_priv;
27// printk("fdi: 1\n"); 27 int err;
28 firesat->isochannel = firesat->adapter->num; //<< 1 | (firesat->subunit & 0x1); // ### ask IRM 28
29// printk("fdi: 2\n"); 29 /* FIXME - allocate free channel at IRM */
30 result = try_CMPEstablishPPconnection(firesat, firesat->subunit, firesat->isochannel); 30 firesat->isochannel = firesat->adapter.num;
31 if (result != 0) { 31
32 err = cmp_establish_pp_connection(firesat, firesat->subunit,
33 firesat->isochannel);
34 if (err) {
32 printk(KERN_ERR "Could not establish point to point " 35 printk(KERN_ERR "Could not establish point to point "
33 "connection.\n"); 36 "connection.\n");
34 return -1; 37 return err;
35 } 38 }
36// printk("fdi: 3\n");
37 39
38 result = setup_iso_channel(firesat); 40 return setup_iso_channel(firesat);
39// printk("fdi: 4. Result was %d\n", result);
40 return result;
41} 41}
42 42
43static int firesat_sleep(struct dvb_frontend *fe) 43static int firesat_sleep(struct dvb_frontend *fe)
@@ -45,7 +45,7 @@ static int firesat_sleep(struct dvb_frontend *fe)
45 struct firesat *firesat = fe->sec_priv; 45 struct firesat *firesat = fe->sec_priv;
46 46
47 tear_down_iso_channel(firesat); 47 tear_down_iso_channel(firesat);
48 try_CMPBreakPPconnection(firesat, firesat->subunit, firesat->isochannel); 48 cmp_break_pp_connection(firesat, firesat->subunit, firesat->isochannel);
49 firesat->isochannel = -1; 49 firesat->isochannel = -1;
50 return 0; 50 return 0;
51} 51}
@@ -55,8 +55,8 @@ static int firesat_diseqc_send_master_cmd(struct dvb_frontend *fe,
55{ 55{
56 struct firesat *firesat = fe->sec_priv; 56 struct firesat *firesat = fe->sec_priv;
57 57
58 return AVCLNBControl(firesat, LNBCONTROL_DONTCARE, LNBCONTROL_DONTCARE, 58 return avc_lnb_control(firesat, LNBCONTROL_DONTCARE,
59 LNBCONTROL_DONTCARE, 1, cmd); 59 LNBCONTROL_DONTCARE, LNBCONTROL_DONTCARE, 1, cmd);
60} 60}
61 61
62static int firesat_diseqc_send_burst(struct dvb_frontend *fe, 62static int firesat_diseqc_send_burst(struct dvb_frontend *fe,
@@ -82,24 +82,19 @@ static int firesat_set_voltage(struct dvb_frontend *fe,
82 return 0; 82 return 0;
83} 83}
84 84
85static int firesat_read_status (struct dvb_frontend *fe, fe_status_t *status) 85static int firesat_read_status(struct dvb_frontend *fe, fe_status_t *status)
86{ 86{
87 struct firesat *firesat = fe->sec_priv; 87 struct firesat *firesat = fe->sec_priv;
88 ANTENNA_INPUT_INFO info; 88 ANTENNA_INPUT_INFO info;
89 89
90 if (AVCTunerStatus(firesat, &info)) 90 if (avc_tuner_status(firesat, &info))
91 return -EINVAL; 91 return -EINVAL;
92 92
93 if (info.NoRF) { 93 if (info.NoRF)
94 *status = 0; 94 *status = 0;
95 } else { 95 else
96 *status = FE_HAS_SIGNAL | 96 *status = FE_HAS_SIGNAL | FE_HAS_VITERBI | FE_HAS_SYNC |
97 FE_HAS_VITERBI | 97 FE_HAS_CARRIER | FE_HAS_LOCK;
98 FE_HAS_SYNC |
99 FE_HAS_CARRIER |
100 FE_HAS_LOCK;
101 }
102
103 return 0; 98 return 0;
104} 99}
105 100
@@ -108,14 +103,11 @@ static int firesat_read_ber(struct dvb_frontend *fe, u32 *ber)
108 struct firesat *firesat = fe->sec_priv; 103 struct firesat *firesat = fe->sec_priv;
109 ANTENNA_INPUT_INFO info; 104 ANTENNA_INPUT_INFO info;
110 105
111 if (AVCTunerStatus(firesat, &info)) 106 if (avc_tuner_status(firesat, &info))
112 return -EINVAL; 107 return -EINVAL;
113 108
114 *ber = (info.BER[0] << 24) | 109 *ber = info.BER[0] << 24 | info.BER[1] << 16 |
115 (info.BER[1] << 16) | 110 info.BER[2] << 8 | info.BER[3];
116 (info.BER[2] << 8) |
117 info.BER[3];
118
119 return 0; 111 return 0;
120} 112}
121 113
@@ -124,11 +116,10 @@ static int firesat_read_signal_strength (struct dvb_frontend *fe, u16 *strength)
124 struct firesat *firesat = fe->sec_priv; 116 struct firesat *firesat = fe->sec_priv;
125 ANTENNA_INPUT_INFO info; 117 ANTENNA_INPUT_INFO info;
126 118
127 if (AVCTunerStatus(firesat, &info)) 119 if (avc_tuner_status(firesat, &info))
128 return -EINVAL; 120 return -EINVAL;
129 121
130 *strength = info.SignalStrength << 8; 122 *strength = info.SignalStrength << 8;
131
132 return 0; 123 return 0;
133} 124}
134 125
@@ -137,14 +128,12 @@ static int firesat_read_snr(struct dvb_frontend *fe, u16 *snr)
137 struct firesat *firesat = fe->sec_priv; 128 struct firesat *firesat = fe->sec_priv;
138 ANTENNA_INPUT_INFO info; 129 ANTENNA_INPUT_INFO info;
139 130
140 if (AVCTunerStatus(firesat, &info)) 131 if (avc_tuner_status(firesat, &info))
141 return -EINVAL; 132 return -EINVAL;
142 133
143 *snr = (info.CarrierNoiseRatio[0] << 8) + 134 /* C/N[dB] = -10 * log10(snr / 65535) */
144 info.CarrierNoiseRatio[1]; 135 *snr = (info.CarrierNoiseRatio[0] << 8) + info.CarrierNoiseRatio[1];
145 *snr *= 257; 136 *snr *= 257;
146 // C/N[dB] = -10 * log10(snr / 65535)
147
148 return 0; 137 return 0;
149} 138}
150 139
@@ -158,10 +147,11 @@ static int firesat_set_frontend(struct dvb_frontend *fe,
158{ 147{
159 struct firesat *firesat = fe->sec_priv; 148 struct firesat *firesat = fe->sec_priv;
160 149
161 if (AVCTuner_DSD(firesat, params, NULL) != ACCEPTED) 150 /* FIXME: avc_tuner_dsd never returns ACCEPTED. Check status? */
151 if (avc_tuner_dsd(firesat, params) != ACCEPTED)
162 return -EINVAL; 152 return -EINVAL;
163 else 153 else
164 return 0; //not sure of this... 154 return 0; /* not sure of this... */
165} 155}
166 156
167static int firesat_get_frontend(struct dvb_frontend *fe, 157static int firesat_get_frontend(struct dvb_frontend *fe,
@@ -170,107 +160,86 @@ static int firesat_get_frontend(struct dvb_frontend *fe,
170 return -EOPNOTSUPP; 160 return -EOPNOTSUPP;
171} 161}
172 162
173static struct dvb_frontend_info firesat_S_frontend_info; 163void firesat_frontend_init(struct firesat *firesat)
174static struct dvb_frontend_info firesat_C_frontend_info; 164{
175static struct dvb_frontend_info firesat_T_frontend_info; 165 struct dvb_frontend_ops *ops = &firesat->fe.ops;
176 166 struct dvb_frontend_info *fi = &ops->info;
177static struct dvb_frontend_ops firesat_ops = {
178 167
179 .init = firesat_dvb_init, 168 ops->init = firesat_dvb_init;
180 .sleep = firesat_sleep, 169 ops->sleep = firesat_sleep;
181 170
182 .set_frontend = firesat_set_frontend, 171 ops->set_frontend = firesat_set_frontend;
183 .get_frontend = firesat_get_frontend, 172 ops->get_frontend = firesat_get_frontend;
184 173
185 .read_status = firesat_read_status, 174 ops->read_status = firesat_read_status;
186 .read_ber = firesat_read_ber, 175 ops->read_ber = firesat_read_ber;
187 .read_signal_strength = firesat_read_signal_strength, 176 ops->read_signal_strength = firesat_read_signal_strength;
188 .read_snr = firesat_read_snr, 177 ops->read_snr = firesat_read_snr;
189 .read_ucblocks = firesat_read_uncorrected_blocks, 178 ops->read_ucblocks = firesat_read_uncorrected_blocks;
190 179
191 .diseqc_send_master_cmd = firesat_diseqc_send_master_cmd, 180 ops->diseqc_send_master_cmd = firesat_diseqc_send_master_cmd;
192 .diseqc_send_burst = firesat_diseqc_send_burst, 181 ops->diseqc_send_burst = firesat_diseqc_send_burst;
193 .set_tone = firesat_set_tone, 182 ops->set_tone = firesat_set_tone;
194 .set_voltage = firesat_set_voltage, 183 ops->set_voltage = firesat_set_voltage;
195};
196 184
197int firesat_frontend_attach(struct firesat *firesat, struct dvb_frontend *fe)
198{
199 switch (firesat->type) { 185 switch (firesat->type) {
200 case FireSAT_DVB_S: 186 case FireSAT_DVB_S:
201 firesat->frontend_info = &firesat_S_frontend_info; 187 fi->type = FE_QPSK;
188
189 fi->frequency_min = 950000;
190 fi->frequency_max = 2150000;
191 fi->frequency_stepsize = 125;
192 fi->symbol_rate_min = 1000000;
193 fi->symbol_rate_max = 40000000;
194
195 fi->caps = FE_CAN_INVERSION_AUTO |
196 FE_CAN_FEC_1_2 |
197 FE_CAN_FEC_2_3 |
198 FE_CAN_FEC_3_4 |
199 FE_CAN_FEC_5_6 |
200 FE_CAN_FEC_7_8 |
201 FE_CAN_FEC_AUTO |
202 FE_CAN_QPSK;
202 break; 203 break;
204
203 case FireSAT_DVB_C: 205 case FireSAT_DVB_C:
204 firesat->frontend_info = &firesat_C_frontend_info; 206 fi->type = FE_QAM;
207
208 fi->frequency_min = 47000000;
209 fi->frequency_max = 866000000;
210 fi->frequency_stepsize = 62500;
211 fi->symbol_rate_min = 870000;
212 fi->symbol_rate_max = 6900000;
213
214 fi->caps = FE_CAN_INVERSION_AUTO |
215 FE_CAN_QAM_16 |
216 FE_CAN_QAM_32 |
217 FE_CAN_QAM_64 |
218 FE_CAN_QAM_128 |
219 FE_CAN_QAM_256 |
220 FE_CAN_QAM_AUTO;
205 break; 221 break;
222
206 case FireSAT_DVB_T: 223 case FireSAT_DVB_T:
207 firesat->frontend_info = &firesat_T_frontend_info; 224 fi->type = FE_OFDM;
225
226 fi->frequency_min = 49000000;
227 fi->frequency_max = 861000000;
228 fi->frequency_stepsize = 62500;
229
230 fi->caps = FE_CAN_INVERSION_AUTO |
231 FE_CAN_FEC_2_3 |
232 FE_CAN_TRANSMISSION_MODE_AUTO |
233 FE_CAN_GUARD_INTERVAL_AUTO |
234 FE_CAN_HIERARCHY_AUTO;
208 break; 235 break;
236
209 default: 237 default:
210 printk(KERN_ERR "firedtv: no frontend for model type 0x%x\n", 238 printk(KERN_ERR "FireDTV: no frontend for model type %d\n",
211 firesat->type); 239 firesat->type);
212 firesat->frontend_info = NULL;
213 } 240 }
214 fe->ops = firesat_ops; 241 strcpy(fi->name, firedtv_model_names[firesat->type]);
215 fe->ops.info = *(firesat->frontend_info);
216 fe->dvb = firesat->adapter;
217 242
218 return 0; 243 firesat->fe.dvb = &firesat->adapter;
244 firesat->fe.sec_priv = firesat;
219} 245}
220
221static struct dvb_frontend_info firesat_S_frontend_info = {
222
223 .name = "FireDTV DVB-S Frontend",
224 .type = FE_QPSK,
225
226 .frequency_min = 950000,
227 .frequency_max = 2150000,
228 .frequency_stepsize = 125,
229 .symbol_rate_min = 1000000,
230 .symbol_rate_max = 40000000,
231
232 .caps = FE_CAN_INVERSION_AUTO |
233 FE_CAN_FEC_1_2 |
234 FE_CAN_FEC_2_3 |
235 FE_CAN_FEC_3_4 |
236 FE_CAN_FEC_5_6 |
237 FE_CAN_FEC_7_8 |
238 FE_CAN_FEC_AUTO |
239 FE_CAN_QPSK,
240};
241
242static struct dvb_frontend_info firesat_C_frontend_info = {
243
244 .name = "FireDTV DVB-C Frontend",
245 .type = FE_QAM,
246
247 .frequency_min = 47000000,
248 .frequency_max = 866000000,
249 .frequency_stepsize = 62500,
250 .symbol_rate_min = 870000,
251 .symbol_rate_max = 6900000,
252
253 .caps = FE_CAN_INVERSION_AUTO |
254 FE_CAN_QAM_16 |
255 FE_CAN_QAM_32 |
256 FE_CAN_QAM_64 |
257 FE_CAN_QAM_128 |
258 FE_CAN_QAM_256 |
259 FE_CAN_QAM_AUTO,
260};
261
262static struct dvb_frontend_info firesat_T_frontend_info = {
263
264 .name = "FireDTV DVB-T Frontend",
265 .type = FE_OFDM,
266
267 .frequency_min = 49000000,
268 .frequency_max = 861000000,
269 .frequency_stepsize = 62500,
270
271 .caps = FE_CAN_INVERSION_AUTO |
272 FE_CAN_FEC_2_3 |
273 FE_CAN_TRANSMISSION_MODE_AUTO |
274 FE_CAN_GUARD_INTERVAL_AUTO |
275 FE_CAN_HIERARCHY_AUTO,
276};