aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Richter <stefanr@s5r6.in-berlin.de>2011-02-06 09:41:44 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-03-21 19:32:21 -0400
commit92374e886c7518387e6816dedfe60fc7bdfa8fdd (patch)
tree68aa4fa6ff251d7d97bcc3139d718da583f3ccbb
parent14ddc3188d50855ae2a419a6aced995e2834e5d4 (diff)
[media] firedtv: drop obsolete backend abstraction
Since the drivers/ieee1394/ backend was removed from firedtv, its I/O no longer needs to be abstracted as exchangeable backend methods. Also, ieee1394 variants of module and device probe and removal are no longer there. Move module probe and removal into firedtv-fw.c where device probe and removal are implemented. Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/media/dvb/firewire/firedtv-avc.c15
-rw-r--r--drivers/media/dvb/firewire/firedtv-dvb.c130
-rw-r--r--drivers/media/dvb/firewire/firedtv-fe.c8
-rw-r--r--drivers/media/dvb/firewire/firedtv-fw.c146
-rw-r--r--drivers/media/dvb/firewire/firedtv.h31
5 files changed, 140 insertions, 190 deletions
diff --git a/drivers/media/dvb/firewire/firedtv-avc.c b/drivers/media/dvb/firewire/firedtv-avc.c
index f0f1842fab60..fc5ccd8c923a 100644
--- a/drivers/media/dvb/firewire/firedtv-avc.c
+++ b/drivers/media/dvb/firewire/firedtv-avc.c
@@ -241,8 +241,8 @@ static int avc_write(struct firedtv *fdtv)
241 if (unlikely(avc_debug)) 241 if (unlikely(avc_debug))
242 debug_fcp(fdtv->avc_data, fdtv->avc_data_length); 242 debug_fcp(fdtv->avc_data, fdtv->avc_data_length);
243 243
244 err = fdtv->backend->write(fdtv, FCP_COMMAND_REGISTER, 244 err = fdtv_write(fdtv, FCP_COMMAND_REGISTER,
245 fdtv->avc_data, fdtv->avc_data_length); 245 fdtv->avc_data, fdtv->avc_data_length);
246 if (err) { 246 if (err) {
247 dev_err(fdtv->device, "FCP command write failed\n"); 247 dev_err(fdtv->device, "FCP command write failed\n");
248 248
@@ -1322,7 +1322,7 @@ static int cmp_read(struct firedtv *fdtv, u64 addr, __be32 *data)
1322 1322
1323 mutex_lock(&fdtv->avc_mutex); 1323 mutex_lock(&fdtv->avc_mutex);
1324 1324
1325 ret = fdtv->backend->read(fdtv, addr, data); 1325 ret = fdtv_read(fdtv, addr, data);
1326 if (ret < 0) 1326 if (ret < 0)
1327 dev_err(fdtv->device, "CMP: read I/O error\n"); 1327 dev_err(fdtv->device, "CMP: read I/O error\n");
1328 1328
@@ -1340,7 +1340,7 @@ static int cmp_lock(struct firedtv *fdtv, u64 addr, __be32 data[])
1340 /* data[] is stack-allocated and should not be DMA-mapped. */ 1340 /* data[] is stack-allocated and should not be DMA-mapped. */
1341 memcpy(fdtv->avc_data, data, 8); 1341 memcpy(fdtv->avc_data, data, 8);
1342 1342
1343 ret = fdtv->backend->lock(fdtv, addr, fdtv->avc_data); 1343 ret = fdtv_lock(fdtv, addr, fdtv->avc_data);
1344 if (ret < 0) 1344 if (ret < 0)
1345 dev_err(fdtv->device, "CMP: lock I/O error\n"); 1345 dev_err(fdtv->device, "CMP: lock I/O error\n");
1346 else 1346 else
@@ -1405,10 +1405,7 @@ repeat:
1405 /* FIXME: this is for the worst case - optimize */ 1405 /* FIXME: this is for the worst case - optimize */
1406 set_opcr_overhead_id(opcr, 0); 1406 set_opcr_overhead_id(opcr, 0);
1407 1407
1408 /* 1408 /* FIXME: allocate isochronous channel and bandwidth at IRM */
1409 * FIXME: allocate isochronous channel and bandwidth at IRM
1410 * fdtv->backend->alloc_resources(fdtv, channels_mask, bw);
1411 */
1412 } 1409 }
1413 1410
1414 set_opcr_p2p_connections(opcr, get_opcr_p2p_connections(*opcr) + 1); 1411 set_opcr_p2p_connections(opcr, get_opcr_p2p_connections(*opcr) + 1);
@@ -1424,8 +1421,6 @@ repeat:
1424 /* 1421 /*
1425 * FIXME: if old_opcr.P2P_Connections > 0, 1422 * FIXME: if old_opcr.P2P_Connections > 0,
1426 * deallocate isochronous channel and bandwidth at IRM 1423 * deallocate isochronous channel and bandwidth at IRM
1427 * if (...)
1428 * fdtv->backend->dealloc_resources(fdtv, channel, bw);
1429 */ 1424 */
1430 1425
1431 if (++attempts < 6) /* arbitrary limit */ 1426 if (++attempts < 6) /* arbitrary limit */
diff --git a/drivers/media/dvb/firewire/firedtv-dvb.c b/drivers/media/dvb/firewire/firedtv-dvb.c
index 86349db75250..fd8bbbfa5c59 100644
--- a/drivers/media/dvb/firewire/firedtv-dvb.c
+++ b/drivers/media/dvb/firewire/firedtv-dvb.c
@@ -14,14 +14,9 @@
14#include <linux/device.h> 14#include <linux/device.h>
15#include <linux/errno.h> 15#include <linux/errno.h>
16#include <linux/kernel.h> 16#include <linux/kernel.h>
17#include <linux/mod_devicetable.h>
18#include <linux/module.h> 17#include <linux/module.h>
19#include <linux/mutex.h> 18#include <linux/mutex.h>
20#include <linux/slab.h>
21#include <linux/string.h>
22#include <linux/types.h> 19#include <linux/types.h>
23#include <linux/wait.h>
24#include <linux/workqueue.h>
25 20
26#include <dmxdev.h> 21#include <dmxdev.h>
27#include <dvb_demux.h> 22#include <dvb_demux.h>
@@ -166,11 +161,11 @@ int fdtv_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
166 161
167DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); 162DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
168 163
169int fdtv_dvb_register(struct firedtv *fdtv) 164int fdtv_dvb_register(struct firedtv *fdtv, const char *name)
170{ 165{
171 int err; 166 int err;
172 167
173 err = dvb_register_adapter(&fdtv->adapter, fdtv_model_names[fdtv->type], 168 err = dvb_register_adapter(&fdtv->adapter, name,
174 THIS_MODULE, fdtv->device, adapter_nr); 169 THIS_MODULE, fdtv->device, adapter_nr);
175 if (err < 0) 170 if (err < 0)
176 goto fail_log; 171 goto fail_log;
@@ -210,7 +205,7 @@ int fdtv_dvb_register(struct firedtv *fdtv)
210 205
211 dvb_net_init(&fdtv->adapter, &fdtv->dvbnet, &fdtv->demux.dmx); 206 dvb_net_init(&fdtv->adapter, &fdtv->dvbnet, &fdtv->demux.dmx);
212 207
213 fdtv_frontend_init(fdtv); 208 fdtv_frontend_init(fdtv, name);
214 err = dvb_register_frontend(&fdtv->adapter, &fdtv->fe); 209 err = dvb_register_frontend(&fdtv->adapter, &fdtv->fe);
215 if (err) 210 if (err)
216 goto fail_net_release; 211 goto fail_net_release;
@@ -248,122 +243,3 @@ void fdtv_dvb_unregister(struct firedtv *fdtv)
248 dvb_dmx_release(&fdtv->demux); 243 dvb_dmx_release(&fdtv->demux);
249 dvb_unregister_adapter(&fdtv->adapter); 244 dvb_unregister_adapter(&fdtv->adapter);
250} 245}
251
252const char *fdtv_model_names[] = {
253 [FIREDTV_UNKNOWN] = "unknown type",
254 [FIREDTV_DVB_S] = "FireDTV S/CI",
255 [FIREDTV_DVB_C] = "FireDTV C/CI",
256 [FIREDTV_DVB_T] = "FireDTV T/CI",
257 [FIREDTV_DVB_S2] = "FireDTV S2 ",
258};
259
260struct firedtv *fdtv_alloc(struct device *dev,
261 const struct firedtv_backend *backend,
262 const char *name, size_t name_len)
263{
264 struct firedtv *fdtv;
265 int i;
266
267 fdtv = kzalloc(sizeof(*fdtv), GFP_KERNEL);
268 if (!fdtv)
269 return NULL;
270
271 dev_set_drvdata(dev, fdtv);
272 fdtv->device = dev;
273 fdtv->isochannel = -1;
274 fdtv->voltage = 0xff;
275 fdtv->tone = 0xff;
276 fdtv->backend = backend;
277
278 mutex_init(&fdtv->avc_mutex);
279 init_waitqueue_head(&fdtv->avc_wait);
280 mutex_init(&fdtv->demux_mutex);
281 INIT_WORK(&fdtv->remote_ctrl_work, avc_remote_ctrl_work);
282
283 for (i = ARRAY_SIZE(fdtv_model_names); --i; )
284 if (strlen(fdtv_model_names[i]) <= name_len &&
285 strncmp(name, fdtv_model_names[i], name_len) == 0)
286 break;
287 fdtv->type = i;
288
289 return fdtv;
290}
291
292#define MATCH_FLAGS (IEEE1394_MATCH_VENDOR_ID | IEEE1394_MATCH_MODEL_ID | \
293 IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION)
294
295#define DIGITAL_EVERYWHERE_OUI 0x001287
296#define AVC_UNIT_SPEC_ID_ENTRY 0x00a02d
297#define AVC_SW_VERSION_ENTRY 0x010001
298
299const struct ieee1394_device_id fdtv_id_table[] = {
300 {
301 /* FloppyDTV S/CI and FloppyDTV S2 */
302 .match_flags = MATCH_FLAGS,
303 .vendor_id = DIGITAL_EVERYWHERE_OUI,
304 .model_id = 0x000024,
305 .specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
306 .version = AVC_SW_VERSION_ENTRY,
307 }, {
308 /* FloppyDTV T/CI */
309 .match_flags = MATCH_FLAGS,
310 .vendor_id = DIGITAL_EVERYWHERE_OUI,
311 .model_id = 0x000025,
312 .specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
313 .version = AVC_SW_VERSION_ENTRY,
314 }, {
315 /* FloppyDTV C/CI */
316 .match_flags = MATCH_FLAGS,
317 .vendor_id = DIGITAL_EVERYWHERE_OUI,
318 .model_id = 0x000026,
319 .specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
320 .version = AVC_SW_VERSION_ENTRY,
321 }, {
322 /* FireDTV S/CI and FloppyDTV S2 */
323 .match_flags = MATCH_FLAGS,
324 .vendor_id = DIGITAL_EVERYWHERE_OUI,
325 .model_id = 0x000034,
326 .specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
327 .version = AVC_SW_VERSION_ENTRY,
328 }, {
329 /* FireDTV T/CI */
330 .match_flags = MATCH_FLAGS,
331 .vendor_id = DIGITAL_EVERYWHERE_OUI,
332 .model_id = 0x000035,
333 .specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
334 .version = AVC_SW_VERSION_ENTRY,
335 }, {
336 /* FireDTV C/CI */
337 .match_flags = MATCH_FLAGS,
338 .vendor_id = DIGITAL_EVERYWHERE_OUI,
339 .model_id = 0x000036,
340 .specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
341 .version = AVC_SW_VERSION_ENTRY,
342 }, {}
343};
344MODULE_DEVICE_TABLE(ieee1394, fdtv_id_table);
345
346static int __init fdtv_init(void)
347{
348 int ret;
349
350 ret = fdtv_fw_init();
351 if (ret < 0)
352 return ret;
353
354 return ret;
355}
356
357static void __exit fdtv_exit(void)
358{
359 fdtv_fw_exit();
360}
361
362module_init(fdtv_init);
363module_exit(fdtv_exit);
364
365MODULE_AUTHOR("Andreas Monitzer <andy@monitzer.com>");
366MODULE_AUTHOR("Ben Backx <ben@bbackx.com>");
367MODULE_DESCRIPTION("FireDTV DVB Driver");
368MODULE_LICENSE("GPL");
369MODULE_SUPPORTED_DEVICE("FireDTV DVB");
diff --git a/drivers/media/dvb/firewire/firedtv-fe.c b/drivers/media/dvb/firewire/firedtv-fe.c
index d10920e2f3a2..8748a61be73d 100644
--- a/drivers/media/dvb/firewire/firedtv-fe.c
+++ b/drivers/media/dvb/firewire/firedtv-fe.c
@@ -36,14 +36,14 @@ static int fdtv_dvb_init(struct dvb_frontend *fe)
36 return err; 36 return err;
37 } 37 }
38 38
39 return fdtv->backend->start_iso(fdtv); 39 return fdtv_start_iso(fdtv);
40} 40}
41 41
42static int fdtv_sleep(struct dvb_frontend *fe) 42static int fdtv_sleep(struct dvb_frontend *fe)
43{ 43{
44 struct firedtv *fdtv = fe->sec_priv; 44 struct firedtv *fdtv = fe->sec_priv;
45 45
46 fdtv->backend->stop_iso(fdtv); 46 fdtv_stop_iso(fdtv);
47 cmp_break_pp_connection(fdtv, fdtv->subunit, fdtv->isochannel); 47 cmp_break_pp_connection(fdtv, fdtv->subunit, fdtv->isochannel);
48 fdtv->isochannel = -1; 48 fdtv->isochannel = -1;
49 return 0; 49 return 0;
@@ -165,7 +165,7 @@ static int fdtv_set_property(struct dvb_frontend *fe, struct dtv_property *tvp)
165 return 0; 165 return 0;
166} 166}
167 167
168void fdtv_frontend_init(struct firedtv *fdtv) 168void fdtv_frontend_init(struct firedtv *fdtv, const char *name)
169{ 169{
170 struct dvb_frontend_ops *ops = &fdtv->fe.ops; 170 struct dvb_frontend_ops *ops = &fdtv->fe.ops;
171 struct dvb_frontend_info *fi = &ops->info; 171 struct dvb_frontend_info *fi = &ops->info;
@@ -266,7 +266,7 @@ void fdtv_frontend_init(struct firedtv *fdtv)
266 dev_err(fdtv->device, "no frontend for model type %d\n", 266 dev_err(fdtv->device, "no frontend for model type %d\n",
267 fdtv->type); 267 fdtv->type);
268 } 268 }
269 strcpy(fi->name, fdtv_model_names[fdtv->type]); 269 strcpy(fi->name, name);
270 270
271 fdtv->fe.dvb = &fdtv->adapter; 271 fdtv->fe.dvb = &fdtv->adapter;
272 fdtv->fe.sec_priv = fdtv; 272 fdtv->fe.sec_priv = fdtv;
diff --git a/drivers/media/dvb/firewire/firedtv-fw.c b/drivers/media/dvb/firewire/firedtv-fw.c
index 7424b0493f9d..8022b743af91 100644
--- a/drivers/media/dvb/firewire/firedtv-fw.c
+++ b/drivers/media/dvb/firewire/firedtv-fw.c
@@ -9,11 +9,18 @@
9#include <linux/kernel.h> 9#include <linux/kernel.h>
10#include <linux/list.h> 10#include <linux/list.h>
11#include <linux/mm.h> 11#include <linux/mm.h>
12#include <linux/mod_devicetable.h>
13#include <linux/module.h>
14#include <linux/mutex.h>
12#include <linux/slab.h> 15#include <linux/slab.h>
13#include <linux/spinlock.h> 16#include <linux/spinlock.h>
17#include <linux/string.h>
14#include <linux/types.h> 18#include <linux/types.h>
19#include <linux/wait.h>
20#include <linux/workqueue.h>
15 21
16#include <asm/page.h> 22#include <asm/page.h>
23#include <asm/system.h>
17 24
18#include <dvb_demux.h> 25#include <dvb_demux.h>
19 26
@@ -41,17 +48,17 @@ static int node_req(struct firedtv *fdtv, u64 addr, void *data, size_t len,
41 return rcode != RCODE_COMPLETE ? -EIO : 0; 48 return rcode != RCODE_COMPLETE ? -EIO : 0;
42} 49}
43 50
44static int node_lock(struct firedtv *fdtv, u64 addr, void *data) 51int fdtv_lock(struct firedtv *fdtv, u64 addr, void *data)
45{ 52{
46 return node_req(fdtv, addr, data, 8, TCODE_LOCK_COMPARE_SWAP); 53 return node_req(fdtv, addr, data, 8, TCODE_LOCK_COMPARE_SWAP);
47} 54}
48 55
49static int node_read(struct firedtv *fdtv, u64 addr, void *data) 56int fdtv_read(struct firedtv *fdtv, u64 addr, void *data)
50{ 57{
51 return node_req(fdtv, addr, data, 4, TCODE_READ_QUADLET_REQUEST); 58 return node_req(fdtv, addr, data, 4, TCODE_READ_QUADLET_REQUEST);
52} 59}
53 60
54static int node_write(struct firedtv *fdtv, u64 addr, void *data, size_t len) 61int fdtv_write(struct firedtv *fdtv, u64 addr, void *data, size_t len)
55{ 62{
56 return node_req(fdtv, addr, data, len, TCODE_WRITE_BLOCK_REQUEST); 63 return node_req(fdtv, addr, data, len, TCODE_WRITE_BLOCK_REQUEST);
57} 64}
@@ -67,7 +74,7 @@ static int node_write(struct firedtv *fdtv, u64 addr, void *data, size_t len)
67#define N_PAGES DIV_ROUND_UP(N_PACKETS, PACKETS_PER_PAGE) 74#define N_PAGES DIV_ROUND_UP(N_PACKETS, PACKETS_PER_PAGE)
68#define IRQ_INTERVAL 16 75#define IRQ_INTERVAL 16
69 76
70struct firedtv_receive_context { 77struct fdtv_ir_context {
71 struct fw_iso_context *context; 78 struct fw_iso_context *context;
72 struct fw_iso_buffer buffer; 79 struct fw_iso_buffer buffer;
73 int interrupt_packet; 80 int interrupt_packet;
@@ -75,7 +82,7 @@ struct firedtv_receive_context {
75 char *pages[N_PAGES]; 82 char *pages[N_PAGES];
76}; 83};
77 84
78static int queue_iso(struct firedtv_receive_context *ctx, int index) 85static int queue_iso(struct fdtv_ir_context *ctx, int index)
79{ 86{
80 struct fw_iso_packet p; 87 struct fw_iso_packet p;
81 88
@@ -92,7 +99,7 @@ static void handle_iso(struct fw_iso_context *context, u32 cycle,
92 size_t header_length, void *header, void *data) 99 size_t header_length, void *header, void *data)
93{ 100{
94 struct firedtv *fdtv = data; 101 struct firedtv *fdtv = data;
95 struct firedtv_receive_context *ctx = fdtv->backend_data; 102 struct fdtv_ir_context *ctx = fdtv->ir_context;
96 __be32 *h, *h_end; 103 __be32 *h, *h_end;
97 int length, err, i = ctx->current_packet; 104 int length, err, i = ctx->current_packet;
98 char *p, *p_end; 105 char *p, *p_end;
@@ -121,9 +128,9 @@ static void handle_iso(struct fw_iso_context *context, u32 cycle,
121 ctx->current_packet = i; 128 ctx->current_packet = i;
122} 129}
123 130
124static int start_iso(struct firedtv *fdtv) 131int fdtv_start_iso(struct firedtv *fdtv)
125{ 132{
126 struct firedtv_receive_context *ctx; 133 struct fdtv_ir_context *ctx;
127 struct fw_device *device = device_of(fdtv); 134 struct fw_device *device = device_of(fdtv);
128 int i, err; 135 int i, err;
129 136
@@ -161,7 +168,7 @@ static int start_iso(struct firedtv *fdtv)
161 if (err) 168 if (err)
162 goto fail; 169 goto fail;
163 170
164 fdtv->backend_data = ctx; 171 fdtv->ir_context = ctx;
165 172
166 return 0; 173 return 0;
167fail: 174fail:
@@ -174,9 +181,9 @@ fail_free:
174 return err; 181 return err;
175} 182}
176 183
177static void stop_iso(struct firedtv *fdtv) 184void fdtv_stop_iso(struct firedtv *fdtv)
178{ 185{
179 struct firedtv_receive_context *ctx = fdtv->backend_data; 186 struct fdtv_ir_context *ctx = fdtv->ir_context;
180 187
181 fw_iso_context_stop(ctx->context); 188 fw_iso_context_stop(ctx->context);
182 fw_iso_buffer_destroy(&ctx->buffer, device_of(fdtv)->card); 189 fw_iso_buffer_destroy(&ctx->buffer, device_of(fdtv)->card);
@@ -184,14 +191,6 @@ static void stop_iso(struct firedtv *fdtv)
184 kfree(ctx); 191 kfree(ctx);
185} 192}
186 193
187static const struct firedtv_backend backend = {
188 .lock = node_lock,
189 .read = node_read,
190 .write = node_write,
191 .start_iso = start_iso,
192 .stop_iso = stop_iso,
193};
194
195static void handle_fcp(struct fw_card *card, struct fw_request *request, 194static void handle_fcp(struct fw_card *card, struct fw_request *request,
196 int tcode, int destination, int source, int generation, 195 int tcode, int destination, int source, int generation,
197 unsigned long long offset, void *payload, size_t length, 196 unsigned long long offset, void *payload, size_t length,
@@ -238,6 +237,14 @@ static const struct fw_address_region fcp_region = {
238 .end = CSR_REGISTER_BASE + CSR_FCP_END, 237 .end = CSR_REGISTER_BASE + CSR_FCP_END,
239}; 238};
240 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
241/* Adjust the template string if models with longer names appear. */ 248/* Adjust the template string if models with longer names appear. */
242#define MAX_MODEL_NAME_LEN sizeof("FireDTV ????") 249#define MAX_MODEL_NAME_LEN sizeof("FireDTV ????")
243 250
@@ -245,15 +252,31 @@ static int node_probe(struct device *dev)
245{ 252{
246 struct firedtv *fdtv; 253 struct firedtv *fdtv;
247 char name[MAX_MODEL_NAME_LEN]; 254 char name[MAX_MODEL_NAME_LEN];
248 int name_len, err; 255 int name_len, i, err;
249
250 name_len = fw_csr_string(fw_unit(dev)->directory, CSR_MODEL,
251 name, sizeof(name));
252 256
253 fdtv = fdtv_alloc(dev, &backend, name, name_len >= 0 ? name_len : 0); 257 fdtv = kzalloc(sizeof(*fdtv), GFP_KERNEL);
254 if (!fdtv) 258 if (!fdtv)
255 return -ENOMEM; 259 return -ENOMEM;
256 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
257 err = fdtv_register_rc(fdtv, dev); 280 err = fdtv_register_rc(fdtv, dev);
258 if (err) 281 if (err)
259 goto fail_free; 282 goto fail_free;
@@ -266,7 +289,7 @@ static int node_probe(struct device *dev)
266 if (err) 289 if (err)
267 goto fail; 290 goto fail;
268 291
269 err = fdtv_dvb_register(fdtv); 292 err = fdtv_dvb_register(fdtv, model_names[fdtv->type]);
270 if (err) 293 if (err)
271 goto fail; 294 goto fail;
272 295
@@ -309,6 +332,60 @@ static void node_update(struct fw_unit *unit)
309 fdtv->isochannel); 332 fdtv->isochannel);
310} 333}
311 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
312static struct fw_driver fdtv_driver = { 389static struct fw_driver fdtv_driver = {
313 .driver = { 390 .driver = {
314 .owner = THIS_MODULE, 391 .owner = THIS_MODULE,
@@ -321,7 +398,7 @@ static struct fw_driver fdtv_driver = {
321 .id_table = fdtv_id_table, 398 .id_table = fdtv_id_table,
322}; 399};
323 400
324int __init fdtv_fw_init(void) 401static int __init fdtv_init(void)
325{ 402{
326 int ret; 403 int ret;
327 404
@@ -329,11 +406,24 @@ int __init fdtv_fw_init(void)
329 if (ret < 0) 406 if (ret < 0)
330 return ret; 407 return ret;
331 408
332 return driver_register(&fdtv_driver.driver); 409 ret = driver_register(&fdtv_driver.driver);
410 if (ret < 0)
411 fw_core_remove_address_handler(&fcp_handler);
412
413 return ret;
333} 414}
334 415
335void fdtv_fw_exit(void) 416static void __exit fdtv_exit(void)
336{ 417{
337 driver_unregister(&fdtv_driver.driver); 418 driver_unregister(&fdtv_driver.driver);
338 fw_core_remove_address_handler(&fcp_handler); 419 fw_core_remove_address_handler(&fcp_handler);
339} 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.h b/drivers/media/dvb/firewire/firedtv.h
index 4a87049c9132..bd00b04e079d 100644
--- a/drivers/media/dvb/firewire/firedtv.h
+++ b/drivers/media/dvb/firewire/firedtv.h
@@ -70,15 +70,7 @@ enum model_type {
70 70
71struct device; 71struct device;
72struct input_dev; 72struct input_dev;
73struct firedtv; 73struct fdtv_ir_context;
74
75struct firedtv_backend {
76 int (*lock)(struct firedtv *fdtv, u64 addr, void *data);
77 int (*read)(struct firedtv *fdtv, u64 addr, void *data);
78 int (*write)(struct firedtv *fdtv, u64 addr, void *data, size_t len);
79 int (*start_iso)(struct firedtv *fdtv);
80 void (*stop_iso)(struct firedtv *fdtv);
81};
82 74
83struct firedtv { 75struct firedtv {
84 struct device *device; 76 struct device *device;
@@ -104,12 +96,11 @@ struct firedtv {
104 enum model_type type; 96 enum model_type type;
105 char subunit; 97 char subunit;
106 char isochannel; 98 char isochannel;
99 struct fdtv_ir_context *ir_context;
100
107 fe_sec_voltage_t voltage; 101 fe_sec_voltage_t voltage;
108 fe_sec_tone_mode_t tone; 102 fe_sec_tone_mode_t tone;
109 103
110 const struct firedtv_backend *backend;
111 void *backend_data;
112
113 struct mutex demux_mutex; 104 struct mutex demux_mutex;
114 unsigned long channel_active; 105 unsigned long channel_active;
115 u16 channel_pid[16]; 106 u16 channel_pid[16];
@@ -149,20 +140,18 @@ void fdtv_ca_release(struct firedtv *fdtv);
149/* firedtv-dvb.c */ 140/* firedtv-dvb.c */
150int fdtv_start_feed(struct dvb_demux_feed *dvbdmxfeed); 141int fdtv_start_feed(struct dvb_demux_feed *dvbdmxfeed);
151int fdtv_stop_feed(struct dvb_demux_feed *dvbdmxfeed); 142int fdtv_stop_feed(struct dvb_demux_feed *dvbdmxfeed);
152int fdtv_dvb_register(struct firedtv *fdtv); 143int fdtv_dvb_register(struct firedtv *fdtv, const char *name);
153void fdtv_dvb_unregister(struct firedtv *fdtv); 144void fdtv_dvb_unregister(struct firedtv *fdtv);
154struct firedtv *fdtv_alloc(struct device *dev,
155 const struct firedtv_backend *backend,
156 const char *name, size_t name_len);
157extern const char *fdtv_model_names[];
158extern const struct ieee1394_device_id fdtv_id_table[];
159 145
160/* firedtv-fe.c */ 146/* firedtv-fe.c */
161void fdtv_frontend_init(struct firedtv *fdtv); 147void fdtv_frontend_init(struct firedtv *fdtv, const char *name);
162 148
163/* firedtv-fw.c */ 149/* firedtv-fw.c */
164int fdtv_fw_init(void); 150int fdtv_lock(struct firedtv *fdtv, u64 addr, void *data);
165void fdtv_fw_exit(void); 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);
166 155
167/* firedtv-rc.c */ 156/* firedtv-rc.c */
168#ifdef CONFIG_DVB_FIREDTV_INPUT 157#ifdef CONFIG_DVB_FIREDTV_INPUT