aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/dvb')
-rw-r--r--drivers/media/dvb/Kconfig4
-rw-r--r--drivers/media/dvb/Makefile2
-rw-r--r--drivers/media/dvb/firewire/Kconfig19
-rw-r--r--drivers/media/dvb/firewire/Makefile6
-rw-r--r--drivers/media/dvb/firewire/firedtv-avc.c1457
-rw-r--r--drivers/media/dvb/firewire/firedtv-ci.c258
-rw-r--r--drivers/media/dvb/firewire/firedtv-dvb.c248
-rw-r--r--drivers/media/dvb/firewire/firedtv-fe.c254
-rw-r--r--drivers/media/dvb/firewire/firedtv-fw.c429
-rw-r--r--drivers/media/dvb/firewire/firedtv-rc.c196
-rw-r--r--drivers/media/dvb/firewire/firedtv.h168
11 files changed, 0 insertions, 3041 deletions
diff --git a/drivers/media/dvb/Kconfig b/drivers/media/dvb/Kconfig
index e610c361d185..b4665460c74d 100644
--- a/drivers/media/dvb/Kconfig
+++ b/drivers/media/dvb/Kconfig
@@ -39,10 +39,6 @@ comment "Supported SDMC DM1105 Adapters"
39 depends on DVB_CORE && PCI && I2C 39 depends on DVB_CORE && PCI && I2C
40source "drivers/media/dvb/dm1105/Kconfig" 40source "drivers/media/dvb/dm1105/Kconfig"
41 41
42comment "Supported FireWire (IEEE 1394) Adapters"
43 depends on DVB_CORE && FIREWIRE
44source "drivers/media/dvb/firewire/Kconfig"
45
46comment "Supported Earthsoft PT1 Adapters" 42comment "Supported Earthsoft PT1 Adapters"
47 depends on DVB_CORE && PCI && I2C 43 depends on DVB_CORE && PCI && I2C
48source "drivers/media/dvb/pt1/Kconfig" 44source "drivers/media/dvb/pt1/Kconfig"
diff --git a/drivers/media/dvb/Makefile b/drivers/media/dvb/Makefile
index 0cee8f82a5d4..fc248268cb5a 100644
--- a/drivers/media/dvb/Makefile
+++ b/drivers/media/dvb/Makefile
@@ -16,5 +16,3 @@ obj-y := ttpci/ \
16 mantis/ \ 16 mantis/ \
17 ngene/ \ 17 ngene/ \
18 ddbridge/ 18 ddbridge/
19
20obj-$(CONFIG_DVB_FIREDTV) += firewire/
diff --git a/drivers/media/dvb/firewire/Kconfig b/drivers/media/dvb/firewire/Kconfig
deleted file mode 100644
index f3e9448c3955..000000000000
--- a/drivers/media/dvb/firewire/Kconfig
+++ /dev/null
@@ -1,19 +0,0 @@
1config DVB_FIREDTV
2 tristate "FireDTV and FloppyDTV"
3 depends on DVB_CORE && FIREWIRE
4 help
5 Support for DVB receivers from Digital Everywhere
6 which are connected via IEEE 1394 (FireWire).
7
8 These devices don't have an MPEG decoder built in,
9 so you need an external software decoder to watch TV.
10
11 To compile this driver as a module, say M here:
12 the module will be called firedtv.
13
14if DVB_FIREDTV
15
16config DVB_FIREDTV_INPUT
17 def_bool INPUT = y || (INPUT = m && DVB_FIREDTV = m)
18
19endif # DVB_FIREDTV
diff --git a/drivers/media/dvb/firewire/Makefile b/drivers/media/dvb/firewire/Makefile
deleted file mode 100644
index f3148138c963..000000000000
--- a/drivers/media/dvb/firewire/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
1obj-$(CONFIG_DVB_FIREDTV) += firedtv.o
2
3firedtv-y := firedtv-avc.o firedtv-ci.o firedtv-dvb.o firedtv-fe.o firedtv-fw.o
4firedtv-$(CONFIG_DVB_FIREDTV_INPUT) += firedtv-rc.o
5
6ccflags-y += -Idrivers/media/dvb-core
diff --git a/drivers/media/dvb/firewire/firedtv-avc.c b/drivers/media/dvb/firewire/firedtv-avc.c
deleted file mode 100644
index d1a1a1324ef8..000000000000
--- a/drivers/media/dvb/firewire/firedtv-avc.c
+++ /dev/null
@@ -1,1457 +0,0 @@
1/*
2 * FireDTV driver (formerly known as FireSAT)
3 *
4 * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com>
5 * Copyright (C) 2008 Ben Backx <ben@bbackx.com>
6 * Copyright (C) 2008 Henrik Kurelid <henrik@kurelid.se>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
12 */
13
14#include <linux/bug.h>
15#include <linux/crc32.h>
16#include <linux/delay.h>
17#include <linux/device.h>
18#include <linux/jiffies.h>
19#include <linux/kernel.h>
20#include <linux/moduleparam.h>
21#include <linux/mutex.h>
22#include <linux/string.h>
23#include <linux/stringify.h>
24#include <linux/wait.h>
25#include <linux/workqueue.h>
26
27#include <dvb_frontend.h>
28
29#include "firedtv.h"
30
31#define FCP_COMMAND_REGISTER 0xfffff0000b00ULL
32
33#define AVC_CTYPE_CONTROL 0x0
34#define AVC_CTYPE_STATUS 0x1
35#define AVC_CTYPE_NOTIFY 0x3
36
37#define AVC_RESPONSE_ACCEPTED 0x9
38#define AVC_RESPONSE_STABLE 0xc
39#define AVC_RESPONSE_CHANGED 0xd
40#define AVC_RESPONSE_INTERIM 0xf
41
42#define AVC_SUBUNIT_TYPE_TUNER (0x05 << 3)
43#define AVC_SUBUNIT_TYPE_UNIT (0x1f << 3)
44
45#define AVC_OPCODE_VENDOR 0x00
46#define AVC_OPCODE_READ_DESCRIPTOR 0x09
47#define AVC_OPCODE_DSIT 0xc8
48#define AVC_OPCODE_DSD 0xcb
49
50#define DESCRIPTOR_TUNER_STATUS 0x80
51#define DESCRIPTOR_SUBUNIT_IDENTIFIER 0x00
52
53#define SFE_VENDOR_DE_COMPANYID_0 0x00 /* OUI of Digital Everywhere */
54#define SFE_VENDOR_DE_COMPANYID_1 0x12
55#define SFE_VENDOR_DE_COMPANYID_2 0x87
56
57#define SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL 0x0a
58#define SFE_VENDOR_OPCODE_LNB_CONTROL 0x52
59#define SFE_VENDOR_OPCODE_TUNE_QPSK 0x58 /* for DVB-S */
60
61#define SFE_VENDOR_OPCODE_GET_FIRMWARE_VERSION 0x00
62#define SFE_VENDOR_OPCODE_HOST2CA 0x56
63#define SFE_VENDOR_OPCODE_CA2HOST 0x57
64#define SFE_VENDOR_OPCODE_CISTATUS 0x59
65#define SFE_VENDOR_OPCODE_TUNE_QPSK2 0x60 /* for DVB-S2 */
66
67#define SFE_VENDOR_TAG_CA_RESET 0x00
68#define SFE_VENDOR_TAG_CA_APPLICATION_INFO 0x01
69#define SFE_VENDOR_TAG_CA_PMT 0x02
70#define SFE_VENDOR_TAG_CA_DATE_TIME 0x04
71#define SFE_VENDOR_TAG_CA_MMI 0x05
72#define SFE_VENDOR_TAG_CA_ENTER_MENU 0x07
73
74#define EN50221_LIST_MANAGEMENT_ONLY 0x03
75#define EN50221_TAG_APP_INFO 0x9f8021
76#define EN50221_TAG_CA_INFO 0x9f8031
77
78struct avc_command_frame {
79 u8 ctype;
80 u8 subunit;
81 u8 opcode;
82 u8 operand[509];
83};
84
85struct avc_response_frame {
86 u8 response;
87 u8 subunit;
88 u8 opcode;
89 u8 operand[509];
90};
91
92#define LAST_OPERAND (509 - 1)
93
94static inline void clear_operands(struct avc_command_frame *c, int from, int to)
95{
96 memset(&c->operand[from], 0, to - from + 1);
97}
98
99static void pad_operands(struct avc_command_frame *c, int from)
100{
101 int to = ALIGN(from, 4);
102
103 if (from <= to && to <= LAST_OPERAND)
104 clear_operands(c, from, to);
105}
106
107#define AVC_DEBUG_READ_DESCRIPTOR 0x0001
108#define AVC_DEBUG_DSIT 0x0002
109#define AVC_DEBUG_DSD 0x0004
110#define AVC_DEBUG_REGISTER_REMOTE_CONTROL 0x0008
111#define AVC_DEBUG_LNB_CONTROL 0x0010
112#define AVC_DEBUG_TUNE_QPSK 0x0020
113#define AVC_DEBUG_TUNE_QPSK2 0x0040
114#define AVC_DEBUG_HOST2CA 0x0080
115#define AVC_DEBUG_CA2HOST 0x0100
116#define AVC_DEBUG_APPLICATION_PMT 0x4000
117#define AVC_DEBUG_FCP_PAYLOADS 0x8000
118
119static int avc_debug;
120module_param_named(debug, avc_debug, int, 0644);
121MODULE_PARM_DESC(debug, "Verbose logging (none = 0"
122 ", FCP subactions"
123 ": READ DESCRIPTOR = " __stringify(AVC_DEBUG_READ_DESCRIPTOR)
124 ", DSIT = " __stringify(AVC_DEBUG_DSIT)
125 ", REGISTER_REMOTE_CONTROL = " __stringify(AVC_DEBUG_REGISTER_REMOTE_CONTROL)
126 ", LNB CONTROL = " __stringify(AVC_DEBUG_LNB_CONTROL)
127 ", TUNE QPSK = " __stringify(AVC_DEBUG_TUNE_QPSK)
128 ", TUNE QPSK2 = " __stringify(AVC_DEBUG_TUNE_QPSK2)
129 ", HOST2CA = " __stringify(AVC_DEBUG_HOST2CA)
130 ", CA2HOST = " __stringify(AVC_DEBUG_CA2HOST)
131 "; Application sent PMT = " __stringify(AVC_DEBUG_APPLICATION_PMT)
132 ", FCP payloads = " __stringify(AVC_DEBUG_FCP_PAYLOADS)
133 ", or a combination, or all = -1)");
134
135/*
136 * This is a workaround since there is no vendor specific command to retrieve
137 * ca_info using AVC. If this parameter is not used, ca_system_id will be
138 * filled with application_manufacturer from ca_app_info.
139 * Digital Everywhere have said that adding ca_info is on their TODO list.
140 */
141static unsigned int num_fake_ca_system_ids;
142static int fake_ca_system_ids[4] = { -1, -1, -1, -1 };
143module_param_array(fake_ca_system_ids, int, &num_fake_ca_system_ids, 0644);
144MODULE_PARM_DESC(fake_ca_system_ids, "If your CAM application manufacturer "
145 "does not have the same ca_system_id as your CAS, you can "
146 "override what ca_system_ids are presented to the "
147 "application by setting this field to an array of ids.");
148
149static const char *debug_fcp_ctype(unsigned int ctype)
150{
151 static const char *ctypes[] = {
152 [0x0] = "CONTROL", [0x1] = "STATUS",
153 [0x2] = "SPECIFIC INQUIRY", [0x3] = "NOTIFY",
154 [0x4] = "GENERAL INQUIRY", [0x8] = "NOT IMPLEMENTED",
155 [0x9] = "ACCEPTED", [0xa] = "REJECTED",
156 [0xb] = "IN TRANSITION", [0xc] = "IMPLEMENTED/STABLE",
157 [0xd] = "CHANGED", [0xf] = "INTERIM",
158 };
159 const char *ret = ctype < ARRAY_SIZE(ctypes) ? ctypes[ctype] : NULL;
160
161 return ret ? ret : "?";
162}
163
164static const char *debug_fcp_opcode(unsigned int opcode,
165 const u8 *data, int length)
166{
167 switch (opcode) {
168 case AVC_OPCODE_VENDOR:
169 break;
170 case AVC_OPCODE_READ_DESCRIPTOR:
171 return avc_debug & AVC_DEBUG_READ_DESCRIPTOR ?
172 "ReadDescriptor" : NULL;
173 case AVC_OPCODE_DSIT:
174 return avc_debug & AVC_DEBUG_DSIT ?
175 "DirectSelectInfo.Type" : NULL;
176 case AVC_OPCODE_DSD:
177 return avc_debug & AVC_DEBUG_DSD ? "DirectSelectData" : NULL;
178 default:
179 return "Unknown";
180 }
181
182 if (length < 7 ||
183 data[3] != SFE_VENDOR_DE_COMPANYID_0 ||
184 data[4] != SFE_VENDOR_DE_COMPANYID_1 ||
185 data[5] != SFE_VENDOR_DE_COMPANYID_2)
186 return "Vendor/Unknown";
187
188 switch (data[6]) {
189 case SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL:
190 return avc_debug & AVC_DEBUG_REGISTER_REMOTE_CONTROL ?
191 "RegisterRC" : NULL;
192 case SFE_VENDOR_OPCODE_LNB_CONTROL:
193 return avc_debug & AVC_DEBUG_LNB_CONTROL ? "LNBControl" : NULL;
194 case SFE_VENDOR_OPCODE_TUNE_QPSK:
195 return avc_debug & AVC_DEBUG_TUNE_QPSK ? "TuneQPSK" : NULL;
196 case SFE_VENDOR_OPCODE_TUNE_QPSK2:
197 return avc_debug & AVC_DEBUG_TUNE_QPSK2 ? "TuneQPSK2" : NULL;
198 case SFE_VENDOR_OPCODE_HOST2CA:
199 return avc_debug & AVC_DEBUG_HOST2CA ? "Host2CA" : NULL;
200 case SFE_VENDOR_OPCODE_CA2HOST:
201 return avc_debug & AVC_DEBUG_CA2HOST ? "CA2Host" : NULL;
202 }
203 return "Vendor/Unknown";
204}
205
206static void debug_fcp(const u8 *data, int length)
207{
208 unsigned int subunit_type, subunit_id, opcode;
209 const char *op, *prefix;
210
211 prefix = data[0] > 7 ? "FCP <- " : "FCP -> ";
212 subunit_type = data[1] >> 3;
213 subunit_id = data[1] & 7;
214 opcode = subunit_type == 0x1e || subunit_id == 5 ? ~0 : data[2];
215 op = debug_fcp_opcode(opcode, data, length);
216
217 if (op) {
218 printk(KERN_INFO "%ssu=%x.%x l=%d: %-8s - %s\n",
219 prefix, subunit_type, subunit_id, length,
220 debug_fcp_ctype(data[0]), op);
221 if (avc_debug & AVC_DEBUG_FCP_PAYLOADS)
222 print_hex_dump(KERN_INFO, prefix, DUMP_PREFIX_NONE,
223 16, 1, data, length, false);
224 }
225}
226
227static void debug_pmt(char *msg, int length)
228{
229 printk(KERN_INFO "APP PMT -> l=%d\n", length);
230 print_hex_dump(KERN_INFO, "APP PMT -> ", DUMP_PREFIX_NONE,
231 16, 1, msg, length, false);
232}
233
234static int avc_write(struct firedtv *fdtv)
235{
236 int err, retry;
237
238 fdtv->avc_reply_received = false;
239
240 for (retry = 0; retry < 6; retry++) {
241 if (unlikely(avc_debug))
242 debug_fcp(fdtv->avc_data, fdtv->avc_data_length);
243
244 err = fdtv_write(fdtv, FCP_COMMAND_REGISTER,
245 fdtv->avc_data, fdtv->avc_data_length);
246 if (err) {
247 dev_err(fdtv->device, "FCP command write failed\n");
248
249 return err;
250 }
251
252 /*
253 * AV/C specs say that answers should be sent within 150 ms.
254 * Time out after 200 ms.
255 */
256 if (wait_event_timeout(fdtv->avc_wait,
257 fdtv->avc_reply_received,
258 msecs_to_jiffies(200)) != 0)
259 return 0;
260 }
261 dev_err(fdtv->device, "FCP response timed out\n");
262
263 return -ETIMEDOUT;
264}
265
266static bool is_register_rc(struct avc_response_frame *r)
267{
268 return r->opcode == AVC_OPCODE_VENDOR &&
269 r->operand[0] == SFE_VENDOR_DE_COMPANYID_0 &&
270 r->operand[1] == SFE_VENDOR_DE_COMPANYID_1 &&
271 r->operand[2] == SFE_VENDOR_DE_COMPANYID_2 &&
272 r->operand[3] == SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL;
273}
274
275int avc_recv(struct firedtv *fdtv, void *data, size_t length)
276{
277 struct avc_response_frame *r = data;
278
279 if (unlikely(avc_debug))
280 debug_fcp(data, length);
281
282 if (length >= 8 && is_register_rc(r)) {
283 switch (r->response) {
284 case AVC_RESPONSE_CHANGED:
285 fdtv_handle_rc(fdtv, r->operand[4] << 8 | r->operand[5]);
286 schedule_work(&fdtv->remote_ctrl_work);
287 break;
288 case AVC_RESPONSE_INTERIM:
289 if (is_register_rc((void *)fdtv->avc_data))
290 goto wake;
291 break;
292 default:
293 dev_info(fdtv->device,
294 "remote control result = %d\n", r->response);
295 }
296 return 0;
297 }
298
299 if (fdtv->avc_reply_received) {
300 dev_err(fdtv->device, "out-of-order AVC response, ignored\n");
301 return -EIO;
302 }
303
304 memcpy(fdtv->avc_data, data, length);
305 fdtv->avc_data_length = length;
306wake:
307 fdtv->avc_reply_received = true;
308 wake_up(&fdtv->avc_wait);
309
310 return 0;
311}
312
313static int add_pid_filter(struct firedtv *fdtv, u8 *operand)
314{
315 int i, n, pos = 1;
316
317 for (i = 0, n = 0; i < 16; i++) {
318 if (test_bit(i, &fdtv->channel_active)) {
319 operand[pos++] = 0x13; /* flowfunction relay */
320 operand[pos++] = 0x80; /* dsd_sel_spec_valid_flags -> PID */
321 operand[pos++] = (fdtv->channel_pid[i] >> 8) & 0x1f;
322 operand[pos++] = fdtv->channel_pid[i] & 0xff;
323 operand[pos++] = 0x00; /* tableID */
324 operand[pos++] = 0x00; /* filter_length */
325 n++;
326 }
327 }
328 operand[0] = n;
329
330 return pos;
331}
332
333/*
334 * tuning command for setting the relative LNB frequency
335 * (not supported by the AVC standard)
336 */
337static int avc_tuner_tuneqpsk(struct firedtv *fdtv,
338 struct dtv_frontend_properties *p)
339{
340 struct avc_command_frame *c = (void *)fdtv->avc_data;
341
342 c->opcode = AVC_OPCODE_VENDOR;
343
344 c->operand[0] = SFE_VENDOR_DE_COMPANYID_0;
345 c->operand[1] = SFE_VENDOR_DE_COMPANYID_1;
346 c->operand[2] = SFE_VENDOR_DE_COMPANYID_2;
347 if (fdtv->type == FIREDTV_DVB_S2)
348 c->operand[3] = SFE_VENDOR_OPCODE_TUNE_QPSK2;
349 else
350 c->operand[3] = SFE_VENDOR_OPCODE_TUNE_QPSK;
351
352 c->operand[4] = (p->frequency >> 24) & 0xff;
353 c->operand[5] = (p->frequency >> 16) & 0xff;
354 c->operand[6] = (p->frequency >> 8) & 0xff;
355 c->operand[7] = p->frequency & 0xff;
356
357 c->operand[8] = ((p->symbol_rate / 1000) >> 8) & 0xff;
358 c->operand[9] = (p->symbol_rate / 1000) & 0xff;
359
360 switch (p->fec_inner) {
361 case FEC_1_2: c->operand[10] = 0x1; break;
362 case FEC_2_3: c->operand[10] = 0x2; break;
363 case FEC_3_4: c->operand[10] = 0x3; break;
364 case FEC_5_6: c->operand[10] = 0x4; break;
365 case FEC_7_8: c->operand[10] = 0x5; break;
366 case FEC_4_5:
367 case FEC_8_9:
368 case FEC_AUTO:
369 default: c->operand[10] = 0x0;
370 }
371
372 if (fdtv->voltage == 0xff)
373 c->operand[11] = 0xff;
374 else if (fdtv->voltage == SEC_VOLTAGE_18) /* polarisation */
375 c->operand[11] = 0;
376 else
377 c->operand[11] = 1;
378
379 if (fdtv->tone == 0xff)
380 c->operand[12] = 0xff;
381 else if (fdtv->tone == SEC_TONE_ON) /* band */
382 c->operand[12] = 1;
383 else
384 c->operand[12] = 0;
385
386 if (fdtv->type == FIREDTV_DVB_S2) {
387 if (fdtv->fe.dtv_property_cache.delivery_system == SYS_DVBS2) {
388 switch (fdtv->fe.dtv_property_cache.modulation) {
389 case QAM_16: c->operand[13] = 0x1; break;
390 case QPSK: c->operand[13] = 0x2; break;
391 case PSK_8: c->operand[13] = 0x3; break;
392 default: c->operand[13] = 0x2; break;
393 }
394 switch (fdtv->fe.dtv_property_cache.rolloff) {
395 case ROLLOFF_35: c->operand[14] = 0x2; break;
396 case ROLLOFF_20: c->operand[14] = 0x0; break;
397 case ROLLOFF_25: c->operand[14] = 0x1; break;
398 case ROLLOFF_AUTO:
399 default: c->operand[14] = 0x2; break;
400 /* case ROLLOFF_NONE: c->operand[14] = 0xff; break; */
401 }
402 switch (fdtv->fe.dtv_property_cache.pilot) {
403 case PILOT_AUTO: c->operand[15] = 0x0; break;
404 case PILOT_OFF: c->operand[15] = 0x0; break;
405 case PILOT_ON: c->operand[15] = 0x1; break;
406 }
407 } else {
408 c->operand[13] = 0x1; /* auto modulation */
409 c->operand[14] = 0xff; /* disable rolloff */
410 c->operand[15] = 0xff; /* disable pilot */
411 }
412 return 16;
413 } else {
414 return 13;
415 }
416}
417
418static int avc_tuner_dsd_dvb_c(struct firedtv *fdtv,
419 struct dtv_frontend_properties *p)
420{
421 struct avc_command_frame *c = (void *)fdtv->avc_data;
422
423 c->opcode = AVC_OPCODE_DSD;
424
425 c->operand[0] = 0; /* source plug */
426 c->operand[1] = 0xd2; /* subfunction replace */
427 c->operand[2] = 0x20; /* system id = DVB */
428 c->operand[3] = 0x00; /* antenna number */
429 c->operand[4] = 0x11; /* system_specific_multiplex selection_length */
430
431 /* multiplex_valid_flags, high byte */
432 c->operand[5] = 0 << 7 /* reserved */
433 | 0 << 6 /* Polarisation */
434 | 0 << 5 /* Orbital_Pos */
435 | 1 << 4 /* Frequency */
436 | 1 << 3 /* Symbol_Rate */
437 | 0 << 2 /* FEC_outer */
438 | (p->fec_inner != FEC_AUTO ? 1 << 1 : 0)
439 | (p->modulation != QAM_AUTO ? 1 << 0 : 0);
440
441 /* multiplex_valid_flags, low byte */
442 c->operand[6] = 0 << 7 /* NetworkID */
443 | 0 << 0 /* reserved */ ;
444
445 c->operand[7] = 0x00;
446 c->operand[8] = 0x00;
447 c->operand[9] = 0x00;
448 c->operand[10] = 0x00;
449
450 c->operand[11] = (((p->frequency / 4000) >> 16) & 0xff) | (2 << 6);
451 c->operand[12] = ((p->frequency / 4000) >> 8) & 0xff;
452 c->operand[13] = (p->frequency / 4000) & 0xff;
453 c->operand[14] = ((p->symbol_rate / 1000) >> 12) & 0xff;
454 c->operand[15] = ((p->symbol_rate / 1000) >> 4) & 0xff;
455 c->operand[16] = ((p->symbol_rate / 1000) << 4) & 0xf0;
456 c->operand[17] = 0x00;
457
458 switch (p->fec_inner) {
459 case FEC_1_2: c->operand[18] = 0x1; break;
460 case FEC_2_3: c->operand[18] = 0x2; break;
461 case FEC_3_4: c->operand[18] = 0x3; break;
462 case FEC_5_6: c->operand[18] = 0x4; break;
463 case FEC_7_8: c->operand[18] = 0x5; break;
464 case FEC_8_9: c->operand[18] = 0x6; break;
465 case FEC_4_5: c->operand[18] = 0x8; break;
466 case FEC_AUTO:
467 default: c->operand[18] = 0x0;
468 }
469
470 switch (p->modulation) {
471 case QAM_16: c->operand[19] = 0x08; break;
472 case QAM_32: c->operand[19] = 0x10; break;
473 case QAM_64: c->operand[19] = 0x18; break;
474 case QAM_128: c->operand[19] = 0x20; break;
475 case QAM_256: c->operand[19] = 0x28; break;
476 case QAM_AUTO:
477 default: c->operand[19] = 0x00;
478 }
479
480 c->operand[20] = 0x00;
481 c->operand[21] = 0x00;
482
483 return 22 + add_pid_filter(fdtv, &c->operand[22]);
484}
485
486static int avc_tuner_dsd_dvb_t(struct firedtv *fdtv,
487 struct dtv_frontend_properties *p)
488{
489 struct avc_command_frame *c = (void *)fdtv->avc_data;
490
491 c->opcode = AVC_OPCODE_DSD;
492
493 c->operand[0] = 0; /* source plug */
494 c->operand[1] = 0xd2; /* subfunction replace */
495 c->operand[2] = 0x20; /* system id = DVB */
496 c->operand[3] = 0x00; /* antenna number */
497 c->operand[4] = 0x0c; /* system_specific_multiplex selection_length */
498
499 /* multiplex_valid_flags, high byte */
500 c->operand[5] =
501 0 << 7 /* reserved */
502 | 1 << 6 /* CenterFrequency */
503 | (p->bandwidth_hz != 0 ? 1 << 5 : 0)
504 | (p->modulation != QAM_AUTO ? 1 << 4 : 0)
505 | (p->hierarchy != HIERARCHY_AUTO ? 1 << 3 : 0)
506 | (p->code_rate_HP != FEC_AUTO ? 1 << 2 : 0)
507 | (p->code_rate_LP != FEC_AUTO ? 1 << 1 : 0)
508 | (p->guard_interval != GUARD_INTERVAL_AUTO ? 1 << 0 : 0);
509
510 /* multiplex_valid_flags, low byte */
511 c->operand[6] =
512 0 << 7 /* NetworkID */
513 | (p->transmission_mode != TRANSMISSION_MODE_AUTO ? 1 << 6 : 0)
514 | 0 << 5 /* OtherFrequencyFlag */
515 | 0 << 0 /* reserved */ ;
516
517 c->operand[7] = 0x0;
518 c->operand[8] = (p->frequency / 10) >> 24;
519 c->operand[9] = ((p->frequency / 10) >> 16) & 0xff;
520 c->operand[10] = ((p->frequency / 10) >> 8) & 0xff;
521 c->operand[11] = (p->frequency / 10) & 0xff;
522
523 switch (p->bandwidth_hz) {
524 case 7000000: c->operand[12] = 0x20; break;
525 case 8000000:
526 case 6000000: /* not defined by AVC spec */
527 case 0:
528 default: c->operand[12] = 0x00;
529 }
530
531 switch (p->modulation) {
532 case QAM_16: c->operand[13] = 1 << 6; break;
533 case QAM_64: c->operand[13] = 2 << 6; break;
534 case QPSK:
535 default: c->operand[13] = 0x00;
536 }
537
538 switch (p->hierarchy) {
539 case HIERARCHY_1: c->operand[13] |= 1 << 3; break;
540 case HIERARCHY_2: c->operand[13] |= 2 << 3; break;
541 case HIERARCHY_4: c->operand[13] |= 3 << 3; break;
542 case HIERARCHY_AUTO:
543 case HIERARCHY_NONE:
544 default: break;
545 }
546
547 switch (p->code_rate_HP) {
548 case FEC_2_3: c->operand[13] |= 1; break;
549 case FEC_3_4: c->operand[13] |= 2; break;
550 case FEC_5_6: c->operand[13] |= 3; break;
551 case FEC_7_8: c->operand[13] |= 4; break;
552 case FEC_1_2:
553 default: break;
554 }
555
556 switch (p->code_rate_LP) {
557 case FEC_2_3: c->operand[14] = 1 << 5; break;
558 case FEC_3_4: c->operand[14] = 2 << 5; break;
559 case FEC_5_6: c->operand[14] = 3 << 5; break;
560 case FEC_7_8: c->operand[14] = 4 << 5; break;
561 case FEC_1_2:
562 default: c->operand[14] = 0x00; break;
563 }
564
565 switch (p->guard_interval) {
566 case GUARD_INTERVAL_1_16: c->operand[14] |= 1 << 3; break;
567 case GUARD_INTERVAL_1_8: c->operand[14] |= 2 << 3; break;
568 case GUARD_INTERVAL_1_4: c->operand[14] |= 3 << 3; break;
569 case GUARD_INTERVAL_1_32:
570 case GUARD_INTERVAL_AUTO:
571 default: break;
572 }
573
574 switch (p->transmission_mode) {
575 case TRANSMISSION_MODE_8K: c->operand[14] |= 1 << 1; break;
576 case TRANSMISSION_MODE_2K:
577 case TRANSMISSION_MODE_AUTO:
578 default: break;
579 }
580
581 c->operand[15] = 0x00; /* network_ID[0] */
582 c->operand[16] = 0x00; /* network_ID[1] */
583
584 return 17 + add_pid_filter(fdtv, &c->operand[17]);
585}
586
587int avc_tuner_dsd(struct firedtv *fdtv,
588 struct dtv_frontend_properties *p)
589{
590 struct avc_command_frame *c = (void *)fdtv->avc_data;
591 int pos, ret;
592
593 mutex_lock(&fdtv->avc_mutex);
594
595 c->ctype = AVC_CTYPE_CONTROL;
596 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
597
598 switch (fdtv->type) {
599 case FIREDTV_DVB_S:
600 case FIREDTV_DVB_S2: pos = avc_tuner_tuneqpsk(fdtv, p); break;
601 case FIREDTV_DVB_C: pos = avc_tuner_dsd_dvb_c(fdtv, p); break;
602 case FIREDTV_DVB_T: pos = avc_tuner_dsd_dvb_t(fdtv, p); break;
603 default:
604 BUG();
605 }
606 pad_operands(c, pos);
607
608 fdtv->avc_data_length = ALIGN(3 + pos, 4);
609 ret = avc_write(fdtv);
610#if 0
611 /*
612 * FIXME:
613 * u8 *status was an out-parameter of avc_tuner_dsd, unused by caller.
614 * Check for AVC_RESPONSE_ACCEPTED here instead?
615 */
616 if (status)
617 *status = r->operand[2];
618#endif
619 mutex_unlock(&fdtv->avc_mutex);
620
621 if (ret == 0)
622 msleep(500);
623
624 return ret;
625}
626
627int avc_tuner_set_pids(struct firedtv *fdtv, unsigned char pidc, u16 pid[])
628{
629 struct avc_command_frame *c = (void *)fdtv->avc_data;
630 int ret, pos, k;
631
632 if (pidc > 16 && pidc != 0xff)
633 return -EINVAL;
634
635 mutex_lock(&fdtv->avc_mutex);
636
637 c->ctype = AVC_CTYPE_CONTROL;
638 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
639 c->opcode = AVC_OPCODE_DSD;
640
641 c->operand[0] = 0; /* source plug */
642 c->operand[1] = 0xd2; /* subfunction replace */
643 c->operand[2] = 0x20; /* system id = DVB */
644 c->operand[3] = 0x00; /* antenna number */
645 c->operand[4] = 0x00; /* system_specific_multiplex selection_length */
646 c->operand[5] = pidc; /* Nr_of_dsd_sel_specs */
647
648 pos = 6;
649 if (pidc != 0xff)
650 for (k = 0; k < pidc; k++) {
651 c->operand[pos++] = 0x13; /* flowfunction relay */
652 c->operand[pos++] = 0x80; /* dsd_sel_spec_valid_flags -> PID */
653 c->operand[pos++] = (pid[k] >> 8) & 0x1f;
654 c->operand[pos++] = pid[k] & 0xff;
655 c->operand[pos++] = 0x00; /* tableID */
656 c->operand[pos++] = 0x00; /* filter_length */
657 }
658 pad_operands(c, pos);
659
660 fdtv->avc_data_length = ALIGN(3 + pos, 4);
661 ret = avc_write(fdtv);
662
663 /* FIXME: check response code? */
664
665 mutex_unlock(&fdtv->avc_mutex);
666
667 if (ret == 0)
668 msleep(50);
669
670 return ret;
671}
672
673int avc_tuner_get_ts(struct firedtv *fdtv)
674{
675 struct avc_command_frame *c = (void *)fdtv->avc_data;
676 int ret, sl;
677
678 mutex_lock(&fdtv->avc_mutex);
679
680 c->ctype = AVC_CTYPE_CONTROL;
681 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
682 c->opcode = AVC_OPCODE_DSIT;
683
684 sl = fdtv->type == FIREDTV_DVB_T ? 0x0c : 0x11;
685
686 c->operand[0] = 0; /* source plug */
687 c->operand[1] = 0xd2; /* subfunction replace */
688 c->operand[2] = 0xff; /* status */
689 c->operand[3] = 0x20; /* system id = DVB */
690 c->operand[4] = 0x00; /* antenna number */
691 c->operand[5] = 0x0; /* system_specific_search_flags */
692 c->operand[6] = sl; /* system_specific_multiplex selection_length */
693 /*
694 * operand[7]: valid_flags[0]
695 * operand[8]: valid_flags[1]
696 * operand[7 + sl]: nr_of_dsit_sel_specs (always 0)
697 */
698 clear_operands(c, 7, 24);
699
700 fdtv->avc_data_length = fdtv->type == FIREDTV_DVB_T ? 24 : 28;
701 ret = avc_write(fdtv);
702
703 /* FIXME: check response code? */
704
705 mutex_unlock(&fdtv->avc_mutex);
706
707 if (ret == 0)
708 msleep(250);
709
710 return ret;
711}
712
713int avc_identify_subunit(struct firedtv *fdtv)
714{
715 struct avc_command_frame *c = (void *)fdtv->avc_data;
716 struct avc_response_frame *r = (void *)fdtv->avc_data;
717 int ret;
718
719 mutex_lock(&fdtv->avc_mutex);
720
721 c->ctype = AVC_CTYPE_CONTROL;
722 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
723 c->opcode = AVC_OPCODE_READ_DESCRIPTOR;
724
725 c->operand[0] = DESCRIPTOR_SUBUNIT_IDENTIFIER;
726 c->operand[1] = 0xff;
727 c->operand[2] = 0x00;
728 c->operand[3] = 0x00; /* length highbyte */
729 c->operand[4] = 0x08; /* length lowbyte */
730 c->operand[5] = 0x00; /* offset highbyte */
731 c->operand[6] = 0x0d; /* offset lowbyte */
732 clear_operands(c, 7, 8); /* padding */
733
734 fdtv->avc_data_length = 12;
735 ret = avc_write(fdtv);
736 if (ret < 0)
737 goto out;
738
739 if ((r->response != AVC_RESPONSE_STABLE &&
740 r->response != AVC_RESPONSE_ACCEPTED) ||
741 (r->operand[3] << 8) + r->operand[4] != 8) {
742 dev_err(fdtv->device, "cannot read subunit identifier\n");
743 ret = -EINVAL;
744 }
745out:
746 mutex_unlock(&fdtv->avc_mutex);
747
748 return ret;
749}
750
751#define SIZEOF_ANTENNA_INPUT_INFO 22
752
753int avc_tuner_status(struct firedtv *fdtv, struct firedtv_tuner_status *stat)
754{
755 struct avc_command_frame *c = (void *)fdtv->avc_data;
756 struct avc_response_frame *r = (void *)fdtv->avc_data;
757 int length, ret;
758
759 mutex_lock(&fdtv->avc_mutex);
760
761 c->ctype = AVC_CTYPE_CONTROL;
762 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
763 c->opcode = AVC_OPCODE_READ_DESCRIPTOR;
764
765 c->operand[0] = DESCRIPTOR_TUNER_STATUS;
766 c->operand[1] = 0xff; /* read_result_status */
767 /*
768 * operand[2]: reserved
769 * operand[3]: SIZEOF_ANTENNA_INPUT_INFO >> 8
770 * operand[4]: SIZEOF_ANTENNA_INPUT_INFO & 0xff
771 */
772 clear_operands(c, 2, 31);
773
774 fdtv->avc_data_length = 12;
775 ret = avc_write(fdtv);
776 if (ret < 0)
777 goto out;
778
779 if (r->response != AVC_RESPONSE_STABLE &&
780 r->response != AVC_RESPONSE_ACCEPTED) {
781 dev_err(fdtv->device, "cannot read tuner status\n");
782 ret = -EINVAL;
783 goto out;
784 }
785
786 length = r->operand[9];
787 if (r->operand[1] != 0x10 || length != SIZEOF_ANTENNA_INPUT_INFO) {
788 dev_err(fdtv->device, "got invalid tuner status\n");
789 ret = -EINVAL;
790 goto out;
791 }
792
793 stat->active_system = r->operand[10];
794 stat->searching = r->operand[11] >> 7 & 1;
795 stat->moving = r->operand[11] >> 6 & 1;
796 stat->no_rf = r->operand[11] >> 5 & 1;
797 stat->input = r->operand[12] >> 7 & 1;
798 stat->selected_antenna = r->operand[12] & 0x7f;
799 stat->ber = r->operand[13] << 24 |
800 r->operand[14] << 16 |
801 r->operand[15] << 8 |
802 r->operand[16];
803 stat->signal_strength = r->operand[17];
804 stat->raster_frequency = r->operand[18] >> 6 & 2;
805 stat->rf_frequency = (r->operand[18] & 0x3f) << 16 |
806 r->operand[19] << 8 |
807 r->operand[20];
808 stat->man_dep_info_length = r->operand[21];
809 stat->front_end_error = r->operand[22] >> 4 & 1;
810 stat->antenna_error = r->operand[22] >> 3 & 1;
811 stat->front_end_power_status = r->operand[22] >> 1 & 1;
812 stat->power_supply = r->operand[22] & 1;
813 stat->carrier_noise_ratio = r->operand[23] << 8 |
814 r->operand[24];
815 stat->power_supply_voltage = r->operand[27];
816 stat->antenna_voltage = r->operand[28];
817 stat->firewire_bus_voltage = r->operand[29];
818 stat->ca_mmi = r->operand[30] & 1;
819 stat->ca_pmt_reply = r->operand[31] >> 7 & 1;
820 stat->ca_date_time_request = r->operand[31] >> 6 & 1;
821 stat->ca_application_info = r->operand[31] >> 5 & 1;
822 stat->ca_module_present_status = r->operand[31] >> 4 & 1;
823 stat->ca_dvb_flag = r->operand[31] >> 3 & 1;
824 stat->ca_error_flag = r->operand[31] >> 2 & 1;
825 stat->ca_initialization_status = r->operand[31] >> 1 & 1;
826out:
827 mutex_unlock(&fdtv->avc_mutex);
828
829 return ret;
830}
831
832int avc_lnb_control(struct firedtv *fdtv, char voltage, char burst,
833 char conttone, char nrdiseq,
834 struct dvb_diseqc_master_cmd *diseqcmd)
835{
836 struct avc_command_frame *c = (void *)fdtv->avc_data;
837 struct avc_response_frame *r = (void *)fdtv->avc_data;
838 int pos, j, k, ret;
839
840 mutex_lock(&fdtv->avc_mutex);
841
842 c->ctype = AVC_CTYPE_CONTROL;
843 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
844 c->opcode = AVC_OPCODE_VENDOR;
845
846 c->operand[0] = SFE_VENDOR_DE_COMPANYID_0;
847 c->operand[1] = SFE_VENDOR_DE_COMPANYID_1;
848 c->operand[2] = SFE_VENDOR_DE_COMPANYID_2;
849 c->operand[3] = SFE_VENDOR_OPCODE_LNB_CONTROL;
850 c->operand[4] = voltage;
851 c->operand[5] = nrdiseq;
852
853 pos = 6;
854 for (j = 0; j < nrdiseq; j++) {
855 c->operand[pos++] = diseqcmd[j].msg_len;
856
857 for (k = 0; k < diseqcmd[j].msg_len; k++)
858 c->operand[pos++] = diseqcmd[j].msg[k];
859 }
860 c->operand[pos++] = burst;
861 c->operand[pos++] = conttone;
862 pad_operands(c, pos);
863
864 fdtv->avc_data_length = ALIGN(3 + pos, 4);
865 ret = avc_write(fdtv);
866 if (ret < 0)
867 goto out;
868
869 if (r->response != AVC_RESPONSE_ACCEPTED) {
870 dev_err(fdtv->device, "LNB control failed\n");
871 ret = -EINVAL;
872 }
873out:
874 mutex_unlock(&fdtv->avc_mutex);
875
876 return ret;
877}
878
879int avc_register_remote_control(struct firedtv *fdtv)
880{
881 struct avc_command_frame *c = (void *)fdtv->avc_data;
882 int ret;
883
884 mutex_lock(&fdtv->avc_mutex);
885
886 c->ctype = AVC_CTYPE_NOTIFY;
887 c->subunit = AVC_SUBUNIT_TYPE_UNIT | 7;
888 c->opcode = AVC_OPCODE_VENDOR;
889
890 c->operand[0] = SFE_VENDOR_DE_COMPANYID_0;
891 c->operand[1] = SFE_VENDOR_DE_COMPANYID_1;
892 c->operand[2] = SFE_VENDOR_DE_COMPANYID_2;
893 c->operand[3] = SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL;
894 c->operand[4] = 0; /* padding */
895
896 fdtv->avc_data_length = 8;
897 ret = avc_write(fdtv);
898
899 /* FIXME: check response code? */
900
901 mutex_unlock(&fdtv->avc_mutex);
902
903 return ret;
904}
905
906void avc_remote_ctrl_work(struct work_struct *work)
907{
908 struct firedtv *fdtv =
909 container_of(work, struct firedtv, remote_ctrl_work);
910
911 /* Should it be rescheduled in failure cases? */
912 avc_register_remote_control(fdtv);
913}
914
915#if 0 /* FIXME: unused */
916int avc_tuner_host2ca(struct firedtv *fdtv)
917{
918 struct avc_command_frame *c = (void *)fdtv->avc_data;
919 int ret;
920
921 mutex_lock(&fdtv->avc_mutex);
922
923 c->ctype = AVC_CTYPE_CONTROL;
924 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
925 c->opcode = AVC_OPCODE_VENDOR;
926
927 c->operand[0] = SFE_VENDOR_DE_COMPANYID_0;
928 c->operand[1] = SFE_VENDOR_DE_COMPANYID_1;
929 c->operand[2] = SFE_VENDOR_DE_COMPANYID_2;
930 c->operand[3] = SFE_VENDOR_OPCODE_HOST2CA;
931 c->operand[4] = 0; /* slot */
932 c->operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; /* ca tag */
933 clear_operands(c, 6, 8);
934
935 fdtv->avc_data_length = 12;
936 ret = avc_write(fdtv);
937
938 /* FIXME: check response code? */
939
940 mutex_unlock(&fdtv->avc_mutex);
941
942 return ret;
943}
944#endif
945
946static int get_ca_object_pos(struct avc_response_frame *r)
947{
948 int length = 1;
949
950 /* Check length of length field */
951 if (r->operand[7] & 0x80)
952 length = (r->operand[7] & 0x7f) + 1;
953 return length + 7;
954}
955
956static int get_ca_object_length(struct avc_response_frame *r)
957{
958#if 0 /* FIXME: unused */
959 int size = 0;
960 int i;
961
962 if (r->operand[7] & 0x80)
963 for (i = 0; i < (r->operand[7] & 0x7f); i++) {
964 size <<= 8;
965 size += r->operand[8 + i];
966 }
967#endif
968 return r->operand[7];
969}
970
971int avc_ca_app_info(struct firedtv *fdtv, char *app_info, unsigned int *len)
972{
973 struct avc_command_frame *c = (void *)fdtv->avc_data;
974 struct avc_response_frame *r = (void *)fdtv->avc_data;
975 int pos, ret;
976
977 mutex_lock(&fdtv->avc_mutex);
978
979 c->ctype = AVC_CTYPE_STATUS;
980 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
981 c->opcode = AVC_OPCODE_VENDOR;
982
983 c->operand[0] = SFE_VENDOR_DE_COMPANYID_0;
984 c->operand[1] = SFE_VENDOR_DE_COMPANYID_1;
985 c->operand[2] = SFE_VENDOR_DE_COMPANYID_2;
986 c->operand[3] = SFE_VENDOR_OPCODE_CA2HOST;
987 c->operand[4] = 0; /* slot */
988 c->operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; /* ca tag */
989 clear_operands(c, 6, LAST_OPERAND);
990
991 fdtv->avc_data_length = 12;
992 ret = avc_write(fdtv);
993 if (ret < 0)
994 goto out;
995
996 /* FIXME: check response code and validate response data */
997
998 pos = get_ca_object_pos(r);
999 app_info[0] = (EN50221_TAG_APP_INFO >> 16) & 0xff;
1000 app_info[1] = (EN50221_TAG_APP_INFO >> 8) & 0xff;
1001 app_info[2] = (EN50221_TAG_APP_INFO >> 0) & 0xff;
1002 app_info[3] = 6 + r->operand[pos + 4];
1003 app_info[4] = 0x01;
1004 memcpy(&app_info[5], &r->operand[pos], 5 + r->operand[pos + 4]);
1005 *len = app_info[3] + 4;
1006out:
1007 mutex_unlock(&fdtv->avc_mutex);
1008
1009 return ret;
1010}
1011
1012int avc_ca_info(struct firedtv *fdtv, char *app_info, unsigned int *len)
1013{
1014 struct avc_command_frame *c = (void *)fdtv->avc_data;
1015 struct avc_response_frame *r = (void *)fdtv->avc_data;
1016 int i, pos, ret;
1017
1018 mutex_lock(&fdtv->avc_mutex);
1019
1020 c->ctype = AVC_CTYPE_STATUS;
1021 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
1022 c->opcode = AVC_OPCODE_VENDOR;
1023
1024 c->operand[0] = SFE_VENDOR_DE_COMPANYID_0;
1025 c->operand[1] = SFE_VENDOR_DE_COMPANYID_1;
1026 c->operand[2] = SFE_VENDOR_DE_COMPANYID_2;
1027 c->operand[3] = SFE_VENDOR_OPCODE_CA2HOST;
1028 c->operand[4] = 0; /* slot */
1029 c->operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; /* ca tag */
1030 clear_operands(c, 6, LAST_OPERAND);
1031
1032 fdtv->avc_data_length = 12;
1033 ret = avc_write(fdtv);
1034 if (ret < 0)
1035 goto out;
1036
1037 /* FIXME: check response code and validate response data */
1038
1039 pos = get_ca_object_pos(r);
1040 app_info[0] = (EN50221_TAG_CA_INFO >> 16) & 0xff;
1041 app_info[1] = (EN50221_TAG_CA_INFO >> 8) & 0xff;
1042 app_info[2] = (EN50221_TAG_CA_INFO >> 0) & 0xff;
1043 if (num_fake_ca_system_ids == 0) {
1044 app_info[3] = 2;
1045 app_info[4] = r->operand[pos + 0];
1046 app_info[5] = r->operand[pos + 1];
1047 } else {
1048 app_info[3] = num_fake_ca_system_ids * 2;
1049 for (i = 0; i < num_fake_ca_system_ids; i++) {
1050 app_info[4 + i * 2] =
1051 (fake_ca_system_ids[i] >> 8) & 0xff;
1052 app_info[5 + i * 2] = fake_ca_system_ids[i] & 0xff;
1053 }
1054 }
1055 *len = app_info[3] + 4;
1056out:
1057 mutex_unlock(&fdtv->avc_mutex);
1058
1059 return ret;
1060}
1061
1062int avc_ca_reset(struct firedtv *fdtv)
1063{
1064 struct avc_command_frame *c = (void *)fdtv->avc_data;
1065 int ret;
1066
1067 mutex_lock(&fdtv->avc_mutex);
1068
1069 c->ctype = AVC_CTYPE_CONTROL;
1070 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
1071 c->opcode = AVC_OPCODE_VENDOR;
1072
1073 c->operand[0] = SFE_VENDOR_DE_COMPANYID_0;
1074 c->operand[1] = SFE_VENDOR_DE_COMPANYID_1;
1075 c->operand[2] = SFE_VENDOR_DE_COMPANYID_2;
1076 c->operand[3] = SFE_VENDOR_OPCODE_HOST2CA;
1077 c->operand[4] = 0; /* slot */
1078 c->operand[5] = SFE_VENDOR_TAG_CA_RESET; /* ca tag */
1079 c->operand[6] = 0; /* more/last */
1080 c->operand[7] = 1; /* length */
1081 c->operand[8] = 0; /* force hardware reset */
1082
1083 fdtv->avc_data_length = 12;
1084 ret = avc_write(fdtv);
1085
1086 /* FIXME: check response code? */
1087
1088 mutex_unlock(&fdtv->avc_mutex);
1089
1090 return ret;
1091}
1092
1093int avc_ca_pmt(struct firedtv *fdtv, char *msg, int length)
1094{
1095 struct avc_command_frame *c = (void *)fdtv->avc_data;
1096 struct avc_response_frame *r = (void *)fdtv->avc_data;
1097 int list_management;
1098 int program_info_length;
1099 int pmt_cmd_id;
1100 int read_pos;
1101 int write_pos;
1102 int es_info_length;
1103 int crc32_csum;
1104 int ret;
1105
1106 if (unlikely(avc_debug & AVC_DEBUG_APPLICATION_PMT))
1107 debug_pmt(msg, length);
1108
1109 mutex_lock(&fdtv->avc_mutex);
1110
1111 c->ctype = AVC_CTYPE_CONTROL;
1112 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
1113 c->opcode = AVC_OPCODE_VENDOR;
1114
1115 if (msg[0] != EN50221_LIST_MANAGEMENT_ONLY) {
1116 dev_info(fdtv->device, "forcing list_management to ONLY\n");
1117 msg[0] = EN50221_LIST_MANAGEMENT_ONLY;
1118 }
1119 /* We take the cmd_id from the programme level only! */
1120 list_management = msg[0];
1121 program_info_length = ((msg[4] & 0x0f) << 8) + msg[5];
1122 if (program_info_length > 0)
1123 program_info_length--; /* Remove pmt_cmd_id */
1124 pmt_cmd_id = msg[6];
1125
1126 c->operand[0] = SFE_VENDOR_DE_COMPANYID_0;
1127 c->operand[1] = SFE_VENDOR_DE_COMPANYID_1;
1128 c->operand[2] = SFE_VENDOR_DE_COMPANYID_2;
1129 c->operand[3] = SFE_VENDOR_OPCODE_HOST2CA;
1130 c->operand[4] = 0; /* slot */
1131 c->operand[5] = SFE_VENDOR_TAG_CA_PMT; /* ca tag */
1132 c->operand[6] = 0; /* more/last */
1133 /* Use three bytes for length field in case length > 127 */
1134 c->operand[10] = list_management;
1135 c->operand[11] = 0x01; /* pmt_cmd=OK_descramble */
1136
1137 /* TS program map table */
1138
1139 c->operand[12] = 0x02; /* Table id=2 */
1140 c->operand[13] = 0x80; /* Section syntax + length */
1141
1142 c->operand[15] = msg[1]; /* Program number */
1143 c->operand[16] = msg[2];
1144 c->operand[17] = msg[3]; /* Version number and current/next */
1145 c->operand[18] = 0x00; /* Section number=0 */
1146 c->operand[19] = 0x00; /* Last section number=0 */
1147 c->operand[20] = 0x1f; /* PCR_PID=1FFF */
1148 c->operand[21] = 0xff;
1149 c->operand[22] = (program_info_length >> 8); /* Program info length */
1150 c->operand[23] = (program_info_length & 0xff);
1151
1152 /* CA descriptors at programme level */
1153 read_pos = 6;
1154 write_pos = 24;
1155 if (program_info_length > 0) {
1156 pmt_cmd_id = msg[read_pos++];
1157 if (pmt_cmd_id != 1 && pmt_cmd_id != 4)
1158 dev_err(fdtv->device,
1159 "invalid pmt_cmd_id %d\n", pmt_cmd_id);
1160
1161 memcpy(&c->operand[write_pos], &msg[read_pos],
1162 program_info_length);
1163 read_pos += program_info_length;
1164 write_pos += program_info_length;
1165 }
1166 while (read_pos < length) {
1167 c->operand[write_pos++] = msg[read_pos++];
1168 c->operand[write_pos++] = msg[read_pos++];
1169 c->operand[write_pos++] = msg[read_pos++];
1170 es_info_length =
1171 ((msg[read_pos] & 0x0f) << 8) + msg[read_pos + 1];
1172 read_pos += 2;
1173 if (es_info_length > 0)
1174 es_info_length--; /* Remove pmt_cmd_id */
1175 c->operand[write_pos++] = es_info_length >> 8;
1176 c->operand[write_pos++] = es_info_length & 0xff;
1177 if (es_info_length > 0) {
1178 pmt_cmd_id = msg[read_pos++];
1179 if (pmt_cmd_id != 1 && pmt_cmd_id != 4)
1180 dev_err(fdtv->device, "invalid pmt_cmd_id %d "
1181 "at stream level\n", pmt_cmd_id);
1182
1183 memcpy(&c->operand[write_pos], &msg[read_pos],
1184 es_info_length);
1185 read_pos += es_info_length;
1186 write_pos += es_info_length;
1187 }
1188 }
1189 write_pos += 4; /* CRC */
1190
1191 c->operand[7] = 0x82;
1192 c->operand[8] = (write_pos - 10) >> 8;
1193 c->operand[9] = (write_pos - 10) & 0xff;
1194 c->operand[14] = write_pos - 15;
1195
1196 crc32_csum = crc32_be(0, &c->operand[10], c->operand[12] - 1);
1197 c->operand[write_pos - 4] = (crc32_csum >> 24) & 0xff;
1198 c->operand[write_pos - 3] = (crc32_csum >> 16) & 0xff;
1199 c->operand[write_pos - 2] = (crc32_csum >> 8) & 0xff;
1200 c->operand[write_pos - 1] = (crc32_csum >> 0) & 0xff;
1201 pad_operands(c, write_pos);
1202
1203 fdtv->avc_data_length = ALIGN(3 + write_pos, 4);
1204 ret = avc_write(fdtv);
1205 if (ret < 0)
1206 goto out;
1207
1208 if (r->response != AVC_RESPONSE_ACCEPTED) {
1209 dev_err(fdtv->device,
1210 "CA PMT failed with response 0x%x\n", r->response);
1211 ret = -EACCES;
1212 }
1213out:
1214 mutex_unlock(&fdtv->avc_mutex);
1215
1216 return ret;
1217}
1218
1219int avc_ca_get_time_date(struct firedtv *fdtv, int *interval)
1220{
1221 struct avc_command_frame *c = (void *)fdtv->avc_data;
1222 struct avc_response_frame *r = (void *)fdtv->avc_data;
1223 int ret;
1224
1225 mutex_lock(&fdtv->avc_mutex);
1226
1227 c->ctype = AVC_CTYPE_STATUS;
1228 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
1229 c->opcode = AVC_OPCODE_VENDOR;
1230
1231 c->operand[0] = SFE_VENDOR_DE_COMPANYID_0;
1232 c->operand[1] = SFE_VENDOR_DE_COMPANYID_1;
1233 c->operand[2] = SFE_VENDOR_DE_COMPANYID_2;
1234 c->operand[3] = SFE_VENDOR_OPCODE_CA2HOST;
1235 c->operand[4] = 0; /* slot */
1236 c->operand[5] = SFE_VENDOR_TAG_CA_DATE_TIME; /* ca tag */
1237 clear_operands(c, 6, LAST_OPERAND);
1238
1239 fdtv->avc_data_length = 12;
1240 ret = avc_write(fdtv);
1241 if (ret < 0)
1242 goto out;
1243
1244 /* FIXME: check response code and validate response data */
1245
1246 *interval = r->operand[get_ca_object_pos(r)];
1247out:
1248 mutex_unlock(&fdtv->avc_mutex);
1249
1250 return ret;
1251}
1252
1253int avc_ca_enter_menu(struct firedtv *fdtv)
1254{
1255 struct avc_command_frame *c = (void *)fdtv->avc_data;
1256 int ret;
1257
1258 mutex_lock(&fdtv->avc_mutex);
1259
1260 c->ctype = AVC_CTYPE_STATUS;
1261 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
1262 c->opcode = AVC_OPCODE_VENDOR;
1263
1264 c->operand[0] = SFE_VENDOR_DE_COMPANYID_0;
1265 c->operand[1] = SFE_VENDOR_DE_COMPANYID_1;
1266 c->operand[2] = SFE_VENDOR_DE_COMPANYID_2;
1267 c->operand[3] = SFE_VENDOR_OPCODE_HOST2CA;
1268 c->operand[4] = 0; /* slot */
1269 c->operand[5] = SFE_VENDOR_TAG_CA_ENTER_MENU;
1270 clear_operands(c, 6, 8);
1271
1272 fdtv->avc_data_length = 12;
1273 ret = avc_write(fdtv);
1274
1275 /* FIXME: check response code? */
1276
1277 mutex_unlock(&fdtv->avc_mutex);
1278
1279 return ret;
1280}
1281
1282int avc_ca_get_mmi(struct firedtv *fdtv, char *mmi_object, unsigned int *len)
1283{
1284 struct avc_command_frame *c = (void *)fdtv->avc_data;
1285 struct avc_response_frame *r = (void *)fdtv->avc_data;
1286 int ret;
1287
1288 mutex_lock(&fdtv->avc_mutex);
1289
1290 c->ctype = AVC_CTYPE_STATUS;
1291 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
1292 c->opcode = AVC_OPCODE_VENDOR;
1293
1294 c->operand[0] = SFE_VENDOR_DE_COMPANYID_0;
1295 c->operand[1] = SFE_VENDOR_DE_COMPANYID_1;
1296 c->operand[2] = SFE_VENDOR_DE_COMPANYID_2;
1297 c->operand[3] = SFE_VENDOR_OPCODE_CA2HOST;
1298 c->operand[4] = 0; /* slot */
1299 c->operand[5] = SFE_VENDOR_TAG_CA_MMI;
1300 clear_operands(c, 6, LAST_OPERAND);
1301
1302 fdtv->avc_data_length = 12;
1303 ret = avc_write(fdtv);
1304 if (ret < 0)
1305 goto out;
1306
1307 /* FIXME: check response code and validate response data */
1308
1309 *len = get_ca_object_length(r);
1310 memcpy(mmi_object, &r->operand[get_ca_object_pos(r)], *len);
1311out:
1312 mutex_unlock(&fdtv->avc_mutex);
1313
1314 return ret;
1315}
1316
1317#define CMP_OUTPUT_PLUG_CONTROL_REG_0 0xfffff0000904ULL
1318
1319static int cmp_read(struct firedtv *fdtv, u64 addr, __be32 *data)
1320{
1321 int ret;
1322
1323 ret = fdtv_read(fdtv, addr, data);
1324 if (ret < 0)
1325 dev_err(fdtv->device, "CMP: read I/O error\n");
1326
1327 return ret;
1328}
1329
1330static int cmp_lock(struct firedtv *fdtv, u64 addr, __be32 data[])
1331{
1332 int ret;
1333
1334 ret = fdtv_lock(fdtv, addr, data);
1335 if (ret < 0)
1336 dev_err(fdtv->device, "CMP: lock I/O error\n");
1337
1338 return ret;
1339}
1340
1341static inline u32 get_opcr(__be32 opcr, u32 mask, u32 shift)
1342{
1343 return (be32_to_cpu(opcr) >> shift) & mask;
1344}
1345
1346static inline void set_opcr(__be32 *opcr, u32 value, u32 mask, u32 shift)
1347{
1348 *opcr &= ~cpu_to_be32(mask << shift);
1349 *opcr |= cpu_to_be32((value & mask) << shift);
1350}
1351
1352#define get_opcr_online(v) get_opcr((v), 0x1, 31)
1353#define get_opcr_p2p_connections(v) get_opcr((v), 0x3f, 24)
1354#define get_opcr_channel(v) get_opcr((v), 0x3f, 16)
1355
1356#define set_opcr_p2p_connections(p, v) set_opcr((p), (v), 0x3f, 24)
1357#define set_opcr_channel(p, v) set_opcr((p), (v), 0x3f, 16)
1358#define set_opcr_data_rate(p, v) set_opcr((p), (v), 0x3, 14)
1359#define set_opcr_overhead_id(p, v) set_opcr((p), (v), 0xf, 10)
1360
1361int cmp_establish_pp_connection(struct firedtv *fdtv, int plug, int channel)
1362{
1363 __be32 old_opcr, opcr[2];
1364 u64 opcr_address = CMP_OUTPUT_PLUG_CONTROL_REG_0 + (plug << 2);
1365 int attempts = 0;
1366 int ret;
1367
1368 ret = cmp_read(fdtv, opcr_address, opcr);
1369 if (ret < 0)
1370 return ret;
1371
1372repeat:
1373 if (!get_opcr_online(*opcr)) {
1374 dev_err(fdtv->device, "CMP: output offline\n");
1375 return -EBUSY;
1376 }
1377
1378 old_opcr = *opcr;
1379
1380 if (get_opcr_p2p_connections(*opcr)) {
1381 if (get_opcr_channel(*opcr) != channel) {
1382 dev_err(fdtv->device, "CMP: cannot change channel\n");
1383 return -EBUSY;
1384 }
1385 dev_info(fdtv->device, "CMP: overlaying connection\n");
1386
1387 /* We don't allocate isochronous resources. */
1388 } else {
1389 set_opcr_channel(opcr, channel);
1390 set_opcr_data_rate(opcr, 2); /* S400 */
1391
1392 /* FIXME: this is for the worst case - optimize */
1393 set_opcr_overhead_id(opcr, 0);
1394
1395 /* FIXME: allocate isochronous channel and bandwidth at IRM */
1396 }
1397
1398 set_opcr_p2p_connections(opcr, get_opcr_p2p_connections(*opcr) + 1);
1399
1400 opcr[1] = *opcr;
1401 opcr[0] = old_opcr;
1402
1403 ret = cmp_lock(fdtv, opcr_address, opcr);
1404 if (ret < 0)
1405 return ret;
1406
1407 if (old_opcr != *opcr) {
1408 /*
1409 * FIXME: if old_opcr.P2P_Connections > 0,
1410 * deallocate isochronous channel and bandwidth at IRM
1411 */
1412
1413 if (++attempts < 6) /* arbitrary limit */
1414 goto repeat;
1415 return -EBUSY;
1416 }
1417
1418 return 0;
1419}
1420
1421void cmp_break_pp_connection(struct firedtv *fdtv, int plug, int channel)
1422{
1423 __be32 old_opcr, opcr[2];
1424 u64 opcr_address = CMP_OUTPUT_PLUG_CONTROL_REG_0 + (plug << 2);
1425 int attempts = 0;
1426
1427 if (cmp_read(fdtv, opcr_address, opcr) < 0)
1428 return;
1429
1430repeat:
1431 if (!get_opcr_online(*opcr) || !get_opcr_p2p_connections(*opcr) ||
1432 get_opcr_channel(*opcr) != channel) {
1433 dev_err(fdtv->device, "CMP: no connection to break\n");
1434 return;
1435 }
1436
1437 old_opcr = *opcr;
1438 set_opcr_p2p_connections(opcr, get_opcr_p2p_connections(*opcr) - 1);
1439
1440 opcr[1] = *opcr;
1441 opcr[0] = old_opcr;
1442
1443 if (cmp_lock(fdtv, opcr_address, opcr) < 0)
1444 return;
1445
1446 if (old_opcr != *opcr) {
1447 /*
1448 * FIXME: if old_opcr.P2P_Connections == 1, i.e. we were last
1449 * owner, deallocate isochronous channel and bandwidth at IRM
1450 * if (...)
1451 * fdtv->backend->dealloc_resources(fdtv, channel, bw);
1452 */
1453
1454 if (++attempts < 6) /* arbitrary limit */
1455 goto repeat;
1456 }
1457}
diff --git a/drivers/media/dvb/firewire/firedtv-ci.c b/drivers/media/dvb/firewire/firedtv-ci.c
deleted file mode 100644
index e5ebdbfe8c19..000000000000
--- a/drivers/media/dvb/firewire/firedtv-ci.c
+++ /dev/null
@@ -1,258 +0,0 @@
1/*
2 * FireDTV driver (formerly known as FireSAT)
3 *
4 * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com>
5 * Copyright (C) 2008 Henrik Kurelid <henrik@kurelid.se>
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/dvb/ca.h>
15#include <linux/fs.h>
16#include <linux/module.h>
17
18#include <dvbdev.h>
19
20#include "firedtv.h"
21
22#define EN50221_TAG_APP_INFO_ENQUIRY 0x9f8020
23#define EN50221_TAG_CA_INFO_ENQUIRY 0x9f8030
24#define EN50221_TAG_CA_PMT 0x9f8032
25#define EN50221_TAG_ENTER_MENU 0x9f8022
26
27static int fdtv_ca_ready(struct firedtv_tuner_status *stat)
28{
29 return stat->ca_initialization_status == 1 &&
30 stat->ca_error_flag == 0 &&
31 stat->ca_dvb_flag == 1 &&
32 stat->ca_module_present_status == 1;
33}
34
35static int fdtv_get_ca_flags(struct firedtv_tuner_status *stat)
36{
37 int flags = 0;
38
39 if (stat->ca_module_present_status == 1)
40 flags |= CA_CI_MODULE_PRESENT;
41 if (stat->ca_initialization_status == 1 &&
42 stat->ca_error_flag == 0 &&
43 stat->ca_dvb_flag == 1)
44 flags |= CA_CI_MODULE_READY;
45 return flags;
46}
47
48static int fdtv_ca_get_caps(void *arg)
49{
50 struct ca_caps *cap = arg;
51
52 cap->slot_num = 1;
53 cap->slot_type = CA_CI;
54 cap->descr_num = 1;
55 cap->descr_type = CA_ECD;
56 return 0;
57}
58
59static int fdtv_ca_get_slot_info(struct firedtv *fdtv, void *arg)
60{
61 struct firedtv_tuner_status stat;
62 struct ca_slot_info *slot = arg;
63 int err;
64
65 err = avc_tuner_status(fdtv, &stat);
66 if (err)
67 return err;
68
69 if (slot->num != 0)
70 return -EACCES;
71
72 slot->type = CA_CI;
73 slot->flags = fdtv_get_ca_flags(&stat);
74 return 0;
75}
76
77static int fdtv_ca_app_info(struct firedtv *fdtv, void *arg)
78{
79 struct ca_msg *reply = arg;
80
81 return avc_ca_app_info(fdtv, reply->msg, &reply->length);
82}
83
84static int fdtv_ca_info(struct firedtv *fdtv, void *arg)
85{
86 struct ca_msg *reply = arg;
87
88 return avc_ca_info(fdtv, reply->msg, &reply->length);
89}
90
91static int fdtv_ca_get_mmi(struct firedtv *fdtv, void *arg)
92{
93 struct ca_msg *reply = arg;
94
95 return avc_ca_get_mmi(fdtv, reply->msg, &reply->length);
96}
97
98static int fdtv_ca_get_msg(struct firedtv *fdtv, void *arg)
99{
100 struct firedtv_tuner_status stat;
101 int err;
102
103 switch (fdtv->ca_last_command) {
104 case EN50221_TAG_APP_INFO_ENQUIRY:
105 err = fdtv_ca_app_info(fdtv, arg);
106 break;
107 case EN50221_TAG_CA_INFO_ENQUIRY:
108 err = fdtv_ca_info(fdtv, arg);
109 break;
110 default:
111 err = avc_tuner_status(fdtv, &stat);
112 if (err)
113 break;
114 if (stat.ca_mmi == 1)
115 err = fdtv_ca_get_mmi(fdtv, arg);
116 else {
117 dev_info(fdtv->device, "unhandled CA message 0x%08x\n",
118 fdtv->ca_last_command);
119 err = -EACCES;
120 }
121 }
122 fdtv->ca_last_command = 0;
123 return err;
124}
125
126static int fdtv_ca_pmt(struct firedtv *fdtv, void *arg)
127{
128 struct ca_msg *msg = arg;
129 int data_pos;
130 int data_length;
131 int i;
132
133 data_pos = 4;
134 if (msg->msg[3] & 0x80) {
135 data_length = 0;
136 for (i = 0; i < (msg->msg[3] & 0x7f); i++)
137 data_length = (data_length << 8) + msg->msg[data_pos++];
138 } else {
139 data_length = msg->msg[3];
140 }
141
142 return avc_ca_pmt(fdtv, &msg->msg[data_pos], data_length);
143}
144
145static int fdtv_ca_send_msg(struct firedtv *fdtv, void *arg)
146{
147 struct ca_msg *msg = arg;
148 int err;
149
150 /* Do we need a semaphore for this? */
151 fdtv->ca_last_command =
152 (msg->msg[0] << 16) + (msg->msg[1] << 8) + msg->msg[2];
153 switch (fdtv->ca_last_command) {
154 case EN50221_TAG_CA_PMT:
155 err = fdtv_ca_pmt(fdtv, arg);
156 break;
157 case EN50221_TAG_APP_INFO_ENQUIRY:
158 /* handled in ca_get_msg */
159 err = 0;
160 break;
161 case EN50221_TAG_CA_INFO_ENQUIRY:
162 /* handled in ca_get_msg */
163 err = 0;
164 break;
165 case EN50221_TAG_ENTER_MENU:
166 err = avc_ca_enter_menu(fdtv);
167 break;
168 default:
169 dev_err(fdtv->device, "unhandled CA message 0x%08x\n",
170 fdtv->ca_last_command);
171 err = -EACCES;
172 }
173 return err;
174}
175
176static int fdtv_ca_ioctl(struct file *file, unsigned int cmd, void *arg)
177{
178 struct dvb_device *dvbdev = file->private_data;
179 struct firedtv *fdtv = dvbdev->priv;
180 struct firedtv_tuner_status stat;
181 int err;
182
183 switch (cmd) {
184 case CA_RESET:
185 err = avc_ca_reset(fdtv);
186 break;
187 case CA_GET_CAP:
188 err = fdtv_ca_get_caps(arg);
189 break;
190 case CA_GET_SLOT_INFO:
191 err = fdtv_ca_get_slot_info(fdtv, arg);
192 break;
193 case CA_GET_MSG:
194 err = fdtv_ca_get_msg(fdtv, arg);
195 break;
196 case CA_SEND_MSG:
197 err = fdtv_ca_send_msg(fdtv, arg);
198 break;
199 default:
200 dev_info(fdtv->device, "unhandled CA ioctl %u\n", cmd);
201 err = -EOPNOTSUPP;
202 }
203
204 /* FIXME Is this necessary? */
205 avc_tuner_status(fdtv, &stat);
206
207 return err;
208}
209
210static unsigned int fdtv_ca_io_poll(struct file *file, poll_table *wait)
211{
212 return POLLIN;
213}
214
215static const struct file_operations fdtv_ca_fops = {
216 .owner = THIS_MODULE,
217 .unlocked_ioctl = dvb_generic_ioctl,
218 .open = dvb_generic_open,
219 .release = dvb_generic_release,
220 .poll = fdtv_ca_io_poll,
221 .llseek = noop_llseek,
222};
223
224static struct dvb_device fdtv_ca = {
225 .users = 1,
226 .readers = 1,
227 .writers = 1,
228 .fops = &fdtv_ca_fops,
229 .kernel_ioctl = fdtv_ca_ioctl,
230};
231
232int fdtv_ca_register(struct firedtv *fdtv)
233{
234 struct firedtv_tuner_status stat;
235 int err;
236
237 if (avc_tuner_status(fdtv, &stat))
238 return -EINVAL;
239
240 if (!fdtv_ca_ready(&stat))
241 return -EFAULT;
242
243 err = dvb_register_device(&fdtv->adapter, &fdtv->cadev,
244 &fdtv_ca, fdtv, DVB_DEVICE_CA);
245
246 if (stat.ca_application_info == 0)
247 dev_err(fdtv->device, "CaApplicationInfo is not set\n");
248 if (stat.ca_date_time_request == 1)
249 avc_ca_get_time_date(fdtv, &fdtv->ca_time_interval);
250
251 return err;
252}
253
254void fdtv_ca_release(struct firedtv *fdtv)
255{
256 if (fdtv->cadev)
257 dvb_unregister_device(fdtv->cadev);
258}
diff --git a/drivers/media/dvb/firewire/firedtv-dvb.c b/drivers/media/dvb/firewire/firedtv-dvb.c
deleted file mode 100644
index eb7496eab130..000000000000
--- a/drivers/media/dvb/firewire/firedtv-dvb.c
+++ /dev/null
@@ -1,248 +0,0 @@
1/*
2 * FireDTV driver (formerly known as FireSAT)
3 *
4 * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com>
5 * Copyright (C) 2008 Henrik Kurelid <henrik@kurelid.se>
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/bitops.h>
14#include <linux/device.h>
15#include <linux/errno.h>
16#include <linux/kernel.h>
17#include <linux/module.h>
18#include <linux/mutex.h>
19#include <linux/types.h>
20
21#include <dmxdev.h>
22#include <dvb_demux.h>
23#include <dvbdev.h>
24#include <dvb_frontend.h>
25
26#include "firedtv.h"
27
28static int alloc_channel(struct firedtv *fdtv)
29{
30 int i;
31
32 for (i = 0; i < 16; i++)
33 if (!__test_and_set_bit(i, &fdtv->channel_active))
34 break;
35 return i;
36}
37
38static void collect_channels(struct firedtv *fdtv, int *pidc, u16 pid[])
39{
40 int i, n;
41
42 for (i = 0, n = 0; i < 16; i++)
43 if (test_bit(i, &fdtv->channel_active))
44 pid[n++] = fdtv->channel_pid[i];
45 *pidc = n;
46}
47
48static inline void dealloc_channel(struct firedtv *fdtv, int i)
49{
50 __clear_bit(i, &fdtv->channel_active);
51}
52
53int fdtv_start_feed(struct dvb_demux_feed *dvbdmxfeed)
54{
55 struct firedtv *fdtv = dvbdmxfeed->demux->priv;
56 int pidc, c, ret;
57 u16 pids[16];
58
59 switch (dvbdmxfeed->type) {
60 case DMX_TYPE_TS:
61 case DMX_TYPE_SEC:
62 break;
63 default:
64 dev_err(fdtv->device, "can't start dmx feed: invalid type %u\n",
65 dvbdmxfeed->type);
66 return -EINVAL;
67 }
68
69 if (mutex_lock_interruptible(&fdtv->demux_mutex))
70 return -EINTR;
71
72 if (dvbdmxfeed->type == DMX_TYPE_TS) {
73 switch (dvbdmxfeed->pes_type) {
74 case DMX_TS_PES_VIDEO:
75 case DMX_TS_PES_AUDIO:
76 case DMX_TS_PES_TELETEXT:
77 case DMX_TS_PES_PCR:
78 case DMX_TS_PES_OTHER:
79 c = alloc_channel(fdtv);
80 break;
81 default:
82 dev_err(fdtv->device,
83 "can't start dmx feed: invalid pes type %u\n",
84 dvbdmxfeed->pes_type);
85 ret = -EINVAL;
86 goto out;
87 }
88 } else {
89 c = alloc_channel(fdtv);
90 }
91
92 if (c > 15) {
93 dev_err(fdtv->device, "can't start dmx feed: busy\n");
94 ret = -EBUSY;
95 goto out;
96 }
97
98 dvbdmxfeed->priv = (typeof(dvbdmxfeed->priv))(unsigned long)c;
99 fdtv->channel_pid[c] = dvbdmxfeed->pid;
100 collect_channels(fdtv, &pidc, pids);
101
102 if (dvbdmxfeed->pid == 8192) {
103 ret = avc_tuner_get_ts(fdtv);
104 if (ret) {
105 dealloc_channel(fdtv, c);
106 dev_err(fdtv->device, "can't get TS\n");
107 goto out;
108 }
109 } else {
110 ret = avc_tuner_set_pids(fdtv, pidc, pids);
111 if (ret) {
112 dealloc_channel(fdtv, c);
113 dev_err(fdtv->device, "can't set PIDs\n");
114 goto out;
115 }
116 }
117out:
118 mutex_unlock(&fdtv->demux_mutex);
119
120 return ret;
121}
122
123int fdtv_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
124{
125 struct dvb_demux *demux = dvbdmxfeed->demux;
126 struct firedtv *fdtv = demux->priv;
127 int pidc, c, ret;
128 u16 pids[16];
129
130 if (dvbdmxfeed->type == DMX_TYPE_TS &&
131 !((dvbdmxfeed->ts_type & TS_PACKET) &&
132 (demux->dmx.frontend->source != DMX_MEMORY_FE))) {
133
134 if (dvbdmxfeed->ts_type & TS_DECODER) {
135 if (dvbdmxfeed->pes_type >= DMX_TS_PES_OTHER ||
136 !demux->pesfilter[dvbdmxfeed->pes_type])
137 return -EINVAL;
138
139 demux->pids[dvbdmxfeed->pes_type] |= 0x8000;
140 demux->pesfilter[dvbdmxfeed->pes_type] = NULL;
141 }
142
143 if (!(dvbdmxfeed->ts_type & TS_DECODER &&
144 dvbdmxfeed->pes_type < DMX_TS_PES_OTHER))
145 return 0;
146 }
147
148 if (mutex_lock_interruptible(&fdtv->demux_mutex))
149 return -EINTR;
150
151 c = (unsigned long)dvbdmxfeed->priv;
152 dealloc_channel(fdtv, c);
153 collect_channels(fdtv, &pidc, pids);
154
155 ret = avc_tuner_set_pids(fdtv, pidc, pids);
156
157 mutex_unlock(&fdtv->demux_mutex);
158
159 return ret;
160}
161
162DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
163
164int fdtv_dvb_register(struct firedtv *fdtv, const char *name)
165{
166 int err;
167
168 err = dvb_register_adapter(&fdtv->adapter, name,
169 THIS_MODULE, fdtv->device, adapter_nr);
170 if (err < 0)
171 goto fail_log;
172
173 /*DMX_TS_FILTERING | DMX_SECTION_FILTERING*/
174 fdtv->demux.dmx.capabilities = 0;
175
176 fdtv->demux.priv = fdtv;
177 fdtv->demux.filternum = 16;
178 fdtv->demux.feednum = 16;
179 fdtv->demux.start_feed = fdtv_start_feed;
180 fdtv->demux.stop_feed = fdtv_stop_feed;
181 fdtv->demux.write_to_decoder = NULL;
182
183 err = dvb_dmx_init(&fdtv->demux);
184 if (err)
185 goto fail_unreg_adapter;
186
187 fdtv->dmxdev.filternum = 16;
188 fdtv->dmxdev.demux = &fdtv->demux.dmx;
189 fdtv->dmxdev.capabilities = 0;
190
191 err = dvb_dmxdev_init(&fdtv->dmxdev, &fdtv->adapter);
192 if (err)
193 goto fail_dmx_release;
194
195 fdtv->frontend.source = DMX_FRONTEND_0;
196
197 err = fdtv->demux.dmx.add_frontend(&fdtv->demux.dmx, &fdtv->frontend);
198 if (err)
199 goto fail_dmxdev_release;
200
201 err = fdtv->demux.dmx.connect_frontend(&fdtv->demux.dmx,
202 &fdtv->frontend);
203 if (err)
204 goto fail_rem_frontend;
205
206 err = dvb_net_init(&fdtv->adapter, &fdtv->dvbnet, &fdtv->demux.dmx);
207 if (err)
208 goto fail_disconnect_frontend;
209
210 fdtv_frontend_init(fdtv, name);
211 err = dvb_register_frontend(&fdtv->adapter, &fdtv->fe);
212 if (err)
213 goto fail_net_release;
214
215 err = fdtv_ca_register(fdtv);
216 if (err)
217 dev_info(fdtv->device,
218 "Conditional Access Module not enabled\n");
219 return 0;
220
221fail_net_release:
222 dvb_net_release(&fdtv->dvbnet);
223fail_disconnect_frontend:
224 fdtv->demux.dmx.close(&fdtv->demux.dmx);
225fail_rem_frontend:
226 fdtv->demux.dmx.remove_frontend(&fdtv->demux.dmx, &fdtv->frontend);
227fail_dmxdev_release:
228 dvb_dmxdev_release(&fdtv->dmxdev);
229fail_dmx_release:
230 dvb_dmx_release(&fdtv->demux);
231fail_unreg_adapter:
232 dvb_unregister_adapter(&fdtv->adapter);
233fail_log:
234 dev_err(fdtv->device, "DVB initialization failed\n");
235 return err;
236}
237
238void fdtv_dvb_unregister(struct firedtv *fdtv)
239{
240 fdtv_ca_release(fdtv);
241 dvb_unregister_frontend(&fdtv->fe);
242 dvb_net_release(&fdtv->dvbnet);
243 fdtv->demux.dmx.close(&fdtv->demux.dmx);
244 fdtv->demux.dmx.remove_frontend(&fdtv->demux.dmx, &fdtv->frontend);
245 dvb_dmxdev_release(&fdtv->dmxdev);
246 dvb_dmx_release(&fdtv->demux);
247 dvb_unregister_adapter(&fdtv->adapter);
248}
diff --git a/drivers/media/dvb/firewire/firedtv-fe.c b/drivers/media/dvb/firewire/firedtv-fe.c
deleted file mode 100644
index 6fe9793b98b3..000000000000
--- a/drivers/media/dvb/firewire/firedtv-fe.c
+++ /dev/null
@@ -1,254 +0,0 @@
1/*
2 * FireDTV driver (formerly known as FireSAT)
3 *
4 * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com>
5 * Copyright (C) 2008 Henrik Kurelid <henrik@kurelid.se>
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
23static 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
42static 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
54static 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
59 return avc_lnb_control(fdtv, LNBCONTROL_DONTCARE, LNBCONTROL_DONTCARE,
60 LNBCONTROL_DONTCARE, 1, cmd);
61}
62
63static int fdtv_diseqc_send_burst(struct dvb_frontend *fe,
64 fe_sec_mini_cmd_t minicmd)
65{
66 return 0;
67}
68
69static 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
77static int fdtv_set_voltage(struct dvb_frontend *fe,
78 fe_sec_voltage_t voltage)
79{
80 struct firedtv *fdtv = fe->sec_priv;
81
82 fdtv->voltage = voltage;
83 return 0;
84}
85
86static int fdtv_read_status(struct dvb_frontend *fe, fe_status_t *status)
87{
88 struct firedtv *fdtv = fe->sec_priv;
89 struct firedtv_tuner_status stat;
90
91 if (avc_tuner_status(fdtv, &stat))
92 return -EINVAL;
93
94 if (stat.no_rf)
95 *status = 0;
96 else
97 *status = FE_HAS_SIGNAL | FE_HAS_VITERBI | FE_HAS_SYNC |
98 FE_HAS_CARRIER | FE_HAS_LOCK;
99 return 0;
100}
101
102static 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
114static 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
126static 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
139static int fdtv_read_uncorrected_blocks(struct dvb_frontend *fe, u32 *ucblocks)
140{
141 return -EOPNOTSUPP;
142}
143
144static int fdtv_set_frontend(struct dvb_frontend *fe)
145{
146 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
147 struct firedtv *fdtv = fe->sec_priv;
148
149 return avc_tuner_dsd(fdtv, p);
150}
151
152void 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
183 fi->caps = FE_CAN_INVERSION_AUTO |
184 FE_CAN_FEC_1_2 |
185 FE_CAN_FEC_2_3 |
186 FE_CAN_FEC_3_4 |
187 FE_CAN_FEC_5_6 |
188 FE_CAN_FEC_7_8 |
189 FE_CAN_FEC_AUTO |
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
203 fi->caps = FE_CAN_INVERSION_AUTO |
204 FE_CAN_FEC_1_2 |
205 FE_CAN_FEC_2_3 |
206 FE_CAN_FEC_3_4 |
207 FE_CAN_FEC_5_6 |
208 FE_CAN_FEC_7_8 |
209 FE_CAN_FEC_AUTO |
210 FE_CAN_QPSK |
211 FE_CAN_2G_MODULATION;
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
223 fi->caps = FE_CAN_INVERSION_AUTO |
224 FE_CAN_QAM_16 |
225 FE_CAN_QAM_32 |
226 FE_CAN_QAM_64 |
227 FE_CAN_QAM_128 |
228 FE_CAN_QAM_256 |
229 FE_CAN_QAM_AUTO;
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
239 fi->caps = FE_CAN_INVERSION_AUTO |
240 FE_CAN_FEC_2_3 |
241 FE_CAN_TRANSMISSION_MODE_AUTO |
242 FE_CAN_GUARD_INTERVAL_AUTO |
243 FE_CAN_HIERARCHY_AUTO;
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}
diff --git a/drivers/media/dvb/firewire/firedtv-fw.c b/drivers/media/dvb/firewire/firedtv-fw.c
deleted file mode 100644
index e24ec539a5fd..000000000000
--- a/drivers/media/dvb/firewire/firedtv-fw.c
+++ /dev/null
@@ -1,429 +0,0 @@
1/*
2 * FireDTV driver -- firewire I/O backend
3 */
4
5#include <linux/device.h>
6#include <linux/errno.h>
7#include <linux/firewire.h>
8#include <linux/firewire-constants.h>
9#include <linux/kernel.h>
10#include <linux/list.h>
11#include <linux/mm.h>
12#include <linux/mod_devicetable.h>
13#include <linux/module.h>
14#include <linux/mutex.h>
15#include <linux/slab.h>
16#include <linux/spinlock.h>
17#include <linux/string.h>
18#include <linux/types.h>
19#include <linux/wait.h>
20#include <linux/workqueue.h>
21
22#include <asm/page.h>
23
24#include <dvb_demux.h>
25
26#include "firedtv.h"
27
28static LIST_HEAD(node_list);
29static DEFINE_SPINLOCK(node_list_lock);
30
31static inline struct fw_device *device_of(struct firedtv *fdtv)
32{
33 return fw_device(fdtv->device->parent);
34}
35
36static int node_req(struct firedtv *fdtv, u64 addr, void *data, size_t len,
37 int tcode)
38{
39 struct fw_device *device = device_of(fdtv);
40 int rcode, generation = device->generation;
41
42 smp_rmb(); /* node_id vs. generation */
43
44 rcode = fw_run_transaction(device->card, tcode, device->node_id,
45 generation, device->max_speed, addr, data, len);
46
47 return rcode != RCODE_COMPLETE ? -EIO : 0;
48}
49
50int fdtv_lock(struct firedtv *fdtv, u64 addr, void *data)
51{
52 return node_req(fdtv, addr, data, 8, TCODE_LOCK_COMPARE_SWAP);
53}
54
55int fdtv_read(struct firedtv *fdtv, u64 addr, void *data)
56{
57 return node_req(fdtv, addr, data, 4, TCODE_READ_QUADLET_REQUEST);
58}
59
60int fdtv_write(struct firedtv *fdtv, u64 addr, void *data, size_t len)
61{
62 return node_req(fdtv, addr, data, len, TCODE_WRITE_BLOCK_REQUEST);
63}
64
65#define ISO_HEADER_SIZE 4
66#define CIP_HEADER_SIZE 8
67#define MPEG2_TS_HEADER_SIZE 4
68#define MPEG2_TS_SOURCE_PACKET_SIZE (4 + 188)
69
70#define MAX_PACKET_SIZE 1024 /* 776, rounded up to 2^n */
71#define PACKETS_PER_PAGE (PAGE_SIZE / MAX_PACKET_SIZE)
72#define N_PACKETS 64 /* buffer size */
73#define N_PAGES DIV_ROUND_UP(N_PACKETS, PACKETS_PER_PAGE)
74#define IRQ_INTERVAL 16
75
76struct fdtv_ir_context {
77 struct fw_iso_context *context;
78 struct fw_iso_buffer buffer;
79 int interrupt_packet;
80 int current_packet;
81 char *pages[N_PAGES];
82};
83
84static int queue_iso(struct fdtv_ir_context *ctx, int index)
85{
86 struct fw_iso_packet p;
87
88 p.payload_length = MAX_PACKET_SIZE;
89 p.interrupt = !(++ctx->interrupt_packet & (IRQ_INTERVAL - 1));
90 p.skip = 0;
91 p.header_length = ISO_HEADER_SIZE;
92
93 return fw_iso_context_queue(ctx->context, &p, &ctx->buffer,
94 index * MAX_PACKET_SIZE);
95}
96
97static void handle_iso(struct fw_iso_context *context, u32 cycle,
98 size_t header_length, void *header, void *data)
99{
100 struct firedtv *fdtv = data;
101 struct fdtv_ir_context *ctx = fdtv->ir_context;
102 __be32 *h, *h_end;
103 int length, err, i = ctx->current_packet;
104 char *p, *p_end;
105
106 for (h = header, h_end = h + header_length / 4; h < h_end; h++) {
107 length = be32_to_cpup(h) >> 16;
108 if (unlikely(length > MAX_PACKET_SIZE)) {
109 dev_err(fdtv->device, "length = %d\n", length);
110 length = MAX_PACKET_SIZE;
111 }
112
113 p = ctx->pages[i / PACKETS_PER_PAGE]
114 + (i % PACKETS_PER_PAGE) * MAX_PACKET_SIZE;
115 p_end = p + length;
116
117 for (p += CIP_HEADER_SIZE + MPEG2_TS_HEADER_SIZE; p < p_end;
118 p += MPEG2_TS_SOURCE_PACKET_SIZE)
119 dvb_dmx_swfilter_packets(&fdtv->demux, p, 1);
120
121 err = queue_iso(ctx, i);
122 if (unlikely(err))
123 dev_err(fdtv->device, "requeue failed\n");
124
125 i = (i + 1) & (N_PACKETS - 1);
126 }
127 fw_iso_context_queue_flush(ctx->context);
128 ctx->current_packet = i;
129}
130
131int fdtv_start_iso(struct firedtv *fdtv)
132{
133 struct fdtv_ir_context *ctx;
134 struct fw_device *device = device_of(fdtv);
135 int i, err;
136
137 ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
138 if (!ctx)
139 return -ENOMEM;
140
141 ctx->context = fw_iso_context_create(device->card,
142 FW_ISO_CONTEXT_RECEIVE, fdtv->isochannel,
143 device->max_speed, ISO_HEADER_SIZE, handle_iso, fdtv);
144 if (IS_ERR(ctx->context)) {
145 err = PTR_ERR(ctx->context);
146 goto fail_free;
147 }
148
149 err = fw_iso_buffer_init(&ctx->buffer, device->card,
150 N_PAGES, DMA_FROM_DEVICE);
151 if (err)
152 goto fail_context_destroy;
153
154 ctx->interrupt_packet = 0;
155 ctx->current_packet = 0;
156
157 for (i = 0; i < N_PAGES; i++)
158 ctx->pages[i] = page_address(ctx->buffer.pages[i]);
159
160 for (i = 0; i < N_PACKETS; i++) {
161 err = queue_iso(ctx, i);
162 if (err)
163 goto fail;
164 }
165
166 err = fw_iso_context_start(ctx->context, -1, 0,
167 FW_ISO_CONTEXT_MATCH_ALL_TAGS);
168 if (err)
169 goto fail;
170
171 fdtv->ir_context = ctx;
172
173 return 0;
174fail:
175 fw_iso_buffer_destroy(&ctx->buffer, device->card);
176fail_context_destroy:
177 fw_iso_context_destroy(ctx->context);
178fail_free:
179 kfree(ctx);
180
181 return err;
182}
183
184void fdtv_stop_iso(struct firedtv *fdtv)
185{
186 struct fdtv_ir_context *ctx = fdtv->ir_context;
187
188 fw_iso_context_stop(ctx->context);
189 fw_iso_buffer_destroy(&ctx->buffer, device_of(fdtv)->card);
190 fw_iso_context_destroy(ctx->context);
191 kfree(ctx);
192}
193
194static void handle_fcp(struct fw_card *card, struct fw_request *request,
195 int tcode, int destination, int source, int generation,
196 unsigned long long offset, void *payload, size_t length,
197 void *callback_data)
198{
199 struct firedtv *f, *fdtv = NULL;
200 struct fw_device *device;
201 unsigned long flags;
202 int su;
203
204 if (length < 2 || (((u8 *)payload)[0] & 0xf0) != 0)
205 return;
206
207 su = ((u8 *)payload)[1] & 0x7;
208
209 spin_lock_irqsave(&node_list_lock, flags);
210 list_for_each_entry(f, &node_list, list) {
211 device = device_of(f);
212 if (device->generation != generation)
213 continue;
214
215 smp_rmb(); /* node_id vs. generation */
216
217 if (device->card == card &&
218 device->node_id == source &&
219 (f->subunit == su || (f->subunit == 0 && su == 0x7))) {
220 fdtv = f;
221 break;
222 }
223 }
224 spin_unlock_irqrestore(&node_list_lock, flags);
225
226 if (fdtv)
227 avc_recv(fdtv, payload, length);
228}
229
230static struct fw_address_handler fcp_handler = {
231 .length = CSR_FCP_END - CSR_FCP_RESPONSE,
232 .address_callback = handle_fcp,
233};
234
235static const struct fw_address_region fcp_region = {
236 .start = CSR_REGISTER_BASE + CSR_FCP_RESPONSE,
237 .end = CSR_REGISTER_BASE + CSR_FCP_END,
238};
239
240static const char * const model_names[] = {
241 [FIREDTV_UNKNOWN] = "unknown type",
242 [FIREDTV_DVB_S] = "FireDTV S/CI",
243 [FIREDTV_DVB_C] = "FireDTV C/CI",
244 [FIREDTV_DVB_T] = "FireDTV T/CI",
245 [FIREDTV_DVB_S2] = "FireDTV S2 ",
246};
247
248/* Adjust the template string if models with longer names appear. */
249#define MAX_MODEL_NAME_LEN sizeof("FireDTV ????")
250
251static int node_probe(struct device *dev)
252{
253 struct firedtv *fdtv;
254 char name[MAX_MODEL_NAME_LEN];
255 int name_len, i, err;
256
257 fdtv = kzalloc(sizeof(*fdtv), GFP_KERNEL);
258 if (!fdtv)
259 return -ENOMEM;
260
261 dev_set_drvdata(dev, fdtv);
262 fdtv->device = dev;
263 fdtv->isochannel = -1;
264 fdtv->voltage = 0xff;
265 fdtv->tone = 0xff;
266
267 mutex_init(&fdtv->avc_mutex);
268 init_waitqueue_head(&fdtv->avc_wait);
269 mutex_init(&fdtv->demux_mutex);
270 INIT_WORK(&fdtv->remote_ctrl_work, avc_remote_ctrl_work);
271
272 name_len = fw_csr_string(fw_unit(dev)->directory, CSR_MODEL,
273 name, sizeof(name));
274 for (i = ARRAY_SIZE(model_names); --i; )
275 if (strlen(model_names[i]) <= name_len &&
276 strncmp(name, model_names[i], name_len) == 0)
277 break;
278 fdtv->type = i;
279
280 err = fdtv_register_rc(fdtv, dev);
281 if (err)
282 goto fail_free;
283
284 spin_lock_irq(&node_list_lock);
285 list_add_tail(&fdtv->list, &node_list);
286 spin_unlock_irq(&node_list_lock);
287
288 err = avc_identify_subunit(fdtv);
289 if (err)
290 goto fail;
291
292 err = fdtv_dvb_register(fdtv, model_names[fdtv->type]);
293 if (err)
294 goto fail;
295
296 avc_register_remote_control(fdtv);
297
298 return 0;
299fail:
300 spin_lock_irq(&node_list_lock);
301 list_del(&fdtv->list);
302 spin_unlock_irq(&node_list_lock);
303 fdtv_unregister_rc(fdtv);
304fail_free:
305 kfree(fdtv);
306
307 return err;
308}
309
310static int node_remove(struct device *dev)
311{
312 struct firedtv *fdtv = dev_get_drvdata(dev);
313
314 fdtv_dvb_unregister(fdtv);
315
316 spin_lock_irq(&node_list_lock);
317 list_del(&fdtv->list);
318 spin_unlock_irq(&node_list_lock);
319
320 fdtv_unregister_rc(fdtv);
321
322 kfree(fdtv);
323 return 0;
324}
325
326static void node_update(struct fw_unit *unit)
327{
328 struct firedtv *fdtv = dev_get_drvdata(&unit->device);
329
330 if (fdtv->isochannel >= 0)
331 cmp_establish_pp_connection(fdtv, fdtv->subunit,
332 fdtv->isochannel);
333}
334
335#define MATCH_FLAGS (IEEE1394_MATCH_VENDOR_ID | IEEE1394_MATCH_MODEL_ID | \
336 IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION)
337
338#define DIGITAL_EVERYWHERE_OUI 0x001287
339#define AVC_UNIT_SPEC_ID_ENTRY 0x00a02d
340#define AVC_SW_VERSION_ENTRY 0x010001
341
342static const struct ieee1394_device_id fdtv_id_table[] = {
343 {
344 /* FloppyDTV S/CI and FloppyDTV S2 */
345 .match_flags = MATCH_FLAGS,
346 .vendor_id = DIGITAL_EVERYWHERE_OUI,
347 .model_id = 0x000024,
348 .specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
349 .version = AVC_SW_VERSION_ENTRY,
350 }, {
351 /* FloppyDTV T/CI */
352 .match_flags = MATCH_FLAGS,
353 .vendor_id = DIGITAL_EVERYWHERE_OUI,
354 .model_id = 0x000025,
355 .specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
356 .version = AVC_SW_VERSION_ENTRY,
357 }, {
358 /* FloppyDTV C/CI */
359 .match_flags = MATCH_FLAGS,
360 .vendor_id = DIGITAL_EVERYWHERE_OUI,
361 .model_id = 0x000026,
362 .specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
363 .version = AVC_SW_VERSION_ENTRY,
364 }, {
365 /* FireDTV S/CI and FloppyDTV S2 */
366 .match_flags = MATCH_FLAGS,
367 .vendor_id = DIGITAL_EVERYWHERE_OUI,
368 .model_id = 0x000034,
369 .specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
370 .version = AVC_SW_VERSION_ENTRY,
371 }, {
372 /* FireDTV T/CI */
373 .match_flags = MATCH_FLAGS,
374 .vendor_id = DIGITAL_EVERYWHERE_OUI,
375 .model_id = 0x000035,
376 .specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
377 .version = AVC_SW_VERSION_ENTRY,
378 }, {
379 /* FireDTV C/CI */
380 .match_flags = MATCH_FLAGS,
381 .vendor_id = DIGITAL_EVERYWHERE_OUI,
382 .model_id = 0x000036,
383 .specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
384 .version = AVC_SW_VERSION_ENTRY,
385 }, {}
386};
387MODULE_DEVICE_TABLE(ieee1394, fdtv_id_table);
388
389static struct fw_driver fdtv_driver = {
390 .driver = {
391 .owner = THIS_MODULE,
392 .name = "firedtv",
393 .bus = &fw_bus_type,
394 .probe = node_probe,
395 .remove = node_remove,
396 },
397 .update = node_update,
398 .id_table = fdtv_id_table,
399};
400
401static int __init fdtv_init(void)
402{
403 int ret;
404
405 ret = fw_core_add_address_handler(&fcp_handler, &fcp_region);
406 if (ret < 0)
407 return ret;
408
409 ret = driver_register(&fdtv_driver.driver);
410 if (ret < 0)
411 fw_core_remove_address_handler(&fcp_handler);
412
413 return ret;
414}
415
416static void __exit fdtv_exit(void)
417{
418 driver_unregister(&fdtv_driver.driver);
419 fw_core_remove_address_handler(&fcp_handler);
420}
421
422module_init(fdtv_init);
423module_exit(fdtv_exit);
424
425MODULE_AUTHOR("Andreas Monitzer <andy@monitzer.com>");
426MODULE_AUTHOR("Ben Backx <ben@bbackx.com>");
427MODULE_DESCRIPTION("FireDTV DVB Driver");
428MODULE_LICENSE("GPL");
429MODULE_SUPPORTED_DEVICE("FireDTV DVB");
diff --git a/drivers/media/dvb/firewire/firedtv-rc.c b/drivers/media/dvb/firewire/firedtv-rc.c
deleted file mode 100644
index f82d4a93feb3..000000000000
--- a/drivers/media/dvb/firewire/firedtv-rc.c
+++ /dev/null
@@ -1,196 +0,0 @@
1/*
2 * FireDTV driver (formerly known as FireSAT)
3 *
4 * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of
9 * the License, or (at your option) any later version.
10 */
11
12#include <linux/bitops.h>
13#include <linux/input.h>
14#include <linux/kernel.h>
15#include <linux/slab.h>
16#include <linux/string.h>
17#include <linux/types.h>
18#include <linux/workqueue.h>
19
20#include "firedtv.h"
21
22/* fixed table with older keycodes, geared towards MythTV */
23static const u16 oldtable[] = {
24
25 /* code from device: 0x4501...0x451f */
26
27 KEY_ESC,
28 KEY_F9,
29 KEY_1,
30 KEY_2,
31 KEY_3,
32 KEY_4,
33 KEY_5,
34 KEY_6,
35 KEY_7,
36 KEY_8,
37 KEY_9,
38 KEY_I,
39 KEY_0,
40 KEY_ENTER,
41 KEY_RED,
42 KEY_UP,
43 KEY_GREEN,
44 KEY_F10,
45 KEY_SPACE,
46 KEY_F11,
47 KEY_YELLOW,
48 KEY_DOWN,
49 KEY_BLUE,
50 KEY_Z,
51 KEY_P,
52 KEY_PAGEDOWN,
53 KEY_LEFT,
54 KEY_W,
55 KEY_RIGHT,
56 KEY_P,
57 KEY_M,
58
59 /* code from device: 0x4540...0x4542 */
60
61 KEY_R,
62 KEY_V,
63 KEY_C,
64};
65
66/* user-modifiable table for a remote as sold in 2008 */
67static const u16 keytable[] = {
68
69 /* code from device: 0x0300...0x031f */
70
71 [0x00] = KEY_POWER,
72 [0x01] = KEY_SLEEP,
73 [0x02] = KEY_STOP,
74 [0x03] = KEY_OK,
75 [0x04] = KEY_RIGHT,
76 [0x05] = KEY_1,
77 [0x06] = KEY_2,
78 [0x07] = KEY_3,
79 [0x08] = KEY_LEFT,
80 [0x09] = KEY_4,
81 [0x0a] = KEY_5,
82 [0x0b] = KEY_6,
83 [0x0c] = KEY_UP,
84 [0x0d] = KEY_7,
85 [0x0e] = KEY_8,
86 [0x0f] = KEY_9,
87 [0x10] = KEY_DOWN,
88 [0x11] = KEY_TITLE, /* "OSD" - fixme */
89 [0x12] = KEY_0,
90 [0x13] = KEY_F20, /* "16:9" - fixme */
91 [0x14] = KEY_SCREEN, /* "FULL" - fixme */
92 [0x15] = KEY_MUTE,
93 [0x16] = KEY_SUBTITLE,
94 [0x17] = KEY_RECORD,
95 [0x18] = KEY_TEXT,
96 [0x19] = KEY_AUDIO,
97 [0x1a] = KEY_RED,
98 [0x1b] = KEY_PREVIOUS,
99 [0x1c] = KEY_REWIND,
100 [0x1d] = KEY_PLAYPAUSE,
101 [0x1e] = KEY_NEXT,
102 [0x1f] = KEY_VOLUMEUP,
103
104 /* code from device: 0x0340...0x0354 */
105
106 [0x20] = KEY_CHANNELUP,
107 [0x21] = KEY_F21, /* "4:3" - fixme */
108 [0x22] = KEY_TV,
109 [0x23] = KEY_DVD,
110 [0x24] = KEY_VCR,
111 [0x25] = KEY_AUX,
112 [0x26] = KEY_GREEN,
113 [0x27] = KEY_YELLOW,
114 [0x28] = KEY_BLUE,
115 [0x29] = KEY_CHANNEL, /* "CH.LIST" */
116 [0x2a] = KEY_VENDOR, /* "CI" - fixme */
117 [0x2b] = KEY_VOLUMEDOWN,
118 [0x2c] = KEY_CHANNELDOWN,
119 [0x2d] = KEY_LAST,
120 [0x2e] = KEY_INFO,
121 [0x2f] = KEY_FORWARD,
122 [0x30] = KEY_LIST,
123 [0x31] = KEY_FAVORITES,
124 [0x32] = KEY_MENU,
125 [0x33] = KEY_EPG,
126 [0x34] = KEY_EXIT,
127};
128
129int fdtv_register_rc(struct firedtv *fdtv, struct device *dev)
130{
131 struct input_dev *idev;
132 int i, err;
133
134 idev = input_allocate_device();
135 if (!idev)
136 return -ENOMEM;
137
138 fdtv->remote_ctrl_dev = idev;
139 idev->name = "FireDTV remote control";
140 idev->dev.parent = dev;
141 idev->evbit[0] = BIT_MASK(EV_KEY);
142 idev->keycode = kmemdup(keytable, sizeof(keytable), GFP_KERNEL);
143 if (!idev->keycode) {
144 err = -ENOMEM;
145 goto fail;
146 }
147 idev->keycodesize = sizeof(keytable[0]);
148 idev->keycodemax = ARRAY_SIZE(keytable);
149
150 for (i = 0; i < ARRAY_SIZE(keytable); i++)
151 set_bit(keytable[i], idev->keybit);
152
153 err = input_register_device(idev);
154 if (err)
155 goto fail_free_keymap;
156
157 return 0;
158
159fail_free_keymap:
160 kfree(idev->keycode);
161fail:
162 input_free_device(idev);
163 return err;
164}
165
166void fdtv_unregister_rc(struct firedtv *fdtv)
167{
168 cancel_work_sync(&fdtv->remote_ctrl_work);
169 kfree(fdtv->remote_ctrl_dev->keycode);
170 input_unregister_device(fdtv->remote_ctrl_dev);
171}
172
173void fdtv_handle_rc(struct firedtv *fdtv, unsigned int code)
174{
175 struct input_dev *idev = fdtv->remote_ctrl_dev;
176 u16 *keycode = idev->keycode;
177
178 if (code >= 0x0300 && code <= 0x031f)
179 code = keycode[code - 0x0300];
180 else if (code >= 0x0340 && code <= 0x0354)
181 code = keycode[code - 0x0320];
182 else if (code >= 0x4501 && code <= 0x451f)
183 code = oldtable[code - 0x4501];
184 else if (code >= 0x4540 && code <= 0x4542)
185 code = oldtable[code - 0x4521];
186 else {
187 printk(KERN_DEBUG "firedtv: invalid key code 0x%04x "
188 "from remote control\n", code);
189 return;
190 }
191
192 input_report_key(idev, code, 1);
193 input_sync(idev);
194 input_report_key(idev, code, 0);
195 input_sync(idev);
196}
diff --git a/drivers/media/dvb/firewire/firedtv.h b/drivers/media/dvb/firewire/firedtv.h
deleted file mode 100644
index 4fdcd8cb7530..000000000000
--- a/drivers/media/dvb/firewire/firedtv.h
+++ /dev/null
@@ -1,168 +0,0 @@
1/*
2 * FireDTV driver (formerly known as FireSAT)
3 *
4 * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com>
5 * Copyright (C) 2008 Henrik Kurelid <henrik@kurelid.se>
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#ifndef _FIREDTV_H
14#define _FIREDTV_H
15
16#include <linux/dvb/dmx.h>
17#include <linux/dvb/frontend.h>
18#include <linux/list.h>
19#include <linux/mod_devicetable.h>
20#include <linux/mutex.h>
21#include <linux/spinlock_types.h>
22#include <linux/types.h>
23#include <linux/wait.h>
24#include <linux/workqueue.h>
25
26#include <demux.h>
27#include <dmxdev.h>
28#include <dvb_demux.h>
29#include <dvb_frontend.h>
30#include <dvb_net.h>
31#include <dvbdev.h>
32
33struct firedtv_tuner_status {
34 unsigned active_system:8;
35 unsigned searching:1;
36 unsigned moving:1;
37 unsigned no_rf:1;
38 unsigned input:1;
39 unsigned selected_antenna:7;
40 unsigned ber:32;
41 unsigned signal_strength:8;
42 unsigned raster_frequency:2;
43 unsigned rf_frequency:22;
44 unsigned man_dep_info_length:8;
45 unsigned front_end_error:1;
46 unsigned antenna_error:1;
47 unsigned front_end_power_status:1;
48 unsigned power_supply:1;
49 unsigned carrier_noise_ratio:16;
50 unsigned power_supply_voltage:8;
51 unsigned antenna_voltage:8;
52 unsigned firewire_bus_voltage:8;
53 unsigned ca_mmi:1;
54 unsigned ca_pmt_reply:1;
55 unsigned ca_date_time_request:1;
56 unsigned ca_application_info:1;
57 unsigned ca_module_present_status:1;
58 unsigned ca_dvb_flag:1;
59 unsigned ca_error_flag:1;
60 unsigned ca_initialization_status:1;
61};
62
63enum model_type {
64 FIREDTV_UNKNOWN = 0,
65 FIREDTV_DVB_S = 1,
66 FIREDTV_DVB_C = 2,
67 FIREDTV_DVB_T = 3,
68 FIREDTV_DVB_S2 = 4,
69};
70
71struct device;
72struct input_dev;
73struct fdtv_ir_context;
74
75struct firedtv {
76 struct device *device;
77 struct list_head list;
78
79 struct dvb_adapter adapter;
80 struct dmxdev dmxdev;
81 struct dvb_demux demux;
82 struct dmx_frontend frontend;
83 struct dvb_net dvbnet;
84 struct dvb_frontend fe;
85
86 struct dvb_device *cadev;
87 int ca_last_command;
88 int ca_time_interval;
89
90 struct mutex avc_mutex;
91 wait_queue_head_t avc_wait;
92 bool avc_reply_received;
93 struct work_struct remote_ctrl_work;
94 struct input_dev *remote_ctrl_dev;
95
96 enum model_type type;
97 char subunit;
98 char isochannel;
99 struct fdtv_ir_context *ir_context;
100
101 fe_sec_voltage_t voltage;
102 fe_sec_tone_mode_t tone;
103
104 struct mutex demux_mutex;
105 unsigned long channel_active;
106 u16 channel_pid[16];
107
108 int avc_data_length;
109 u8 avc_data[512];
110};
111
112/* firedtv-avc.c */
113int avc_recv(struct firedtv *fdtv, void *data, size_t length);
114int avc_tuner_status(struct firedtv *fdtv, struct firedtv_tuner_status *stat);
115struct dtv_frontend_properties;
116int avc_tuner_dsd(struct firedtv *fdtv, struct dtv_frontend_properties *params);
117int avc_tuner_set_pids(struct firedtv *fdtv, unsigned char pidc, u16 pid[]);
118int avc_tuner_get_ts(struct firedtv *fdtv);
119int avc_identify_subunit(struct firedtv *fdtv);
120struct dvb_diseqc_master_cmd;
121int avc_lnb_control(struct firedtv *fdtv, char voltage, char burst,
122 char conttone, char nrdiseq,
123 struct dvb_diseqc_master_cmd *diseqcmd);
124void avc_remote_ctrl_work(struct work_struct *work);
125int avc_register_remote_control(struct firedtv *fdtv);
126int avc_ca_app_info(struct firedtv *fdtv, char *app_info, unsigned int *len);
127int avc_ca_info(struct firedtv *fdtv, char *app_info, unsigned int *len);
128int avc_ca_reset(struct firedtv *fdtv);
129int avc_ca_pmt(struct firedtv *fdtv, char *app_info, int length);
130int avc_ca_get_time_date(struct firedtv *fdtv, int *interval);
131int avc_ca_enter_menu(struct firedtv *fdtv);
132int avc_ca_get_mmi(struct firedtv *fdtv, char *mmi_object, unsigned int *len);
133int cmp_establish_pp_connection(struct firedtv *fdtv, int plug, int channel);
134void cmp_break_pp_connection(struct firedtv *fdtv, int plug, int channel);
135
136/* firedtv-ci.c */
137int fdtv_ca_register(struct firedtv *fdtv);
138void fdtv_ca_release(struct firedtv *fdtv);
139
140/* firedtv-dvb.c */
141int fdtv_start_feed(struct dvb_demux_feed *dvbdmxfeed);
142int fdtv_stop_feed(struct dvb_demux_feed *dvbdmxfeed);
143int fdtv_dvb_register(struct firedtv *fdtv, const char *name);
144void fdtv_dvb_unregister(struct firedtv *fdtv);
145
146/* firedtv-fe.c */
147void fdtv_frontend_init(struct firedtv *fdtv, const char *name);
148
149/* firedtv-fw.c */
150int fdtv_lock(struct firedtv *fdtv, u64 addr, void *data);
151int fdtv_read(struct firedtv *fdtv, u64 addr, void *data);
152int fdtv_write(struct firedtv *fdtv, u64 addr, void *data, size_t len);
153int fdtv_start_iso(struct firedtv *fdtv);
154void fdtv_stop_iso(struct firedtv *fdtv);
155
156/* firedtv-rc.c */
157#ifdef CONFIG_DVB_FIREDTV_INPUT
158int fdtv_register_rc(struct firedtv *fdtv, struct device *dev);
159void fdtv_unregister_rc(struct firedtv *fdtv);
160void fdtv_handle_rc(struct firedtv *fdtv, unsigned int code);
161#else
162static inline int fdtv_register_rc(struct firedtv *fdtv,
163 struct device *dev) { return 0; }
164static inline void fdtv_unregister_rc(struct firedtv *fdtv) {}
165static inline void fdtv_handle_rc(struct firedtv *fdtv, unsigned int code) {}
166#endif
167
168#endif /* _FIREDTV_H */