diff options
author | Rambaldi <Rambaldi@xs4all.nl> | 2009-01-17 08:47:34 -0500 |
---|---|---|
committer | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2009-02-24 08:51:29 -0500 |
commit | a70f81c1c0dac113ac4705e7701e2676e67905cd (patch) | |
tree | 2ff18425bc3b9a4cbf083c82e011a06a0f88f926 /drivers/media/dvb/firewire/firedtv-1394.c | |
parent | 291f006efeebeeb2073289e44efb8f97cf157220 (diff) |
firedtv: rename files, variables, functions from firesat to firedtv
Combination of the following changes:
Sat, 17 Jan 2009 14:47:34 +0100
firedtv: rename variables and functions from firesat to firedtv
Signed-off-by: Rambaldi <Rambaldi@xs4all.nl>
Additional changes by Stefan Richter:
Renamed struct firedtv *firedtv to struct firedtv *fdtv and
firedtv_foo_bar() to fdtv_foo_bar() for brevity.
Sat, 17 Jan 2009 13:07:44 +0100
firedtv: rename files from firesat to firedtv
Signed-off-by: Rambaldi <Rambaldi@xs4all.nl>
Additional changes by Stefan Richter:
Name the directory "firewire" instead of "firedtv".
Standardize on "-" instead of "_" in file names, because that's what
drivers/firewire/ and drivers/media/dvb/dvb-usb/ use too.
Build fix.
Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
Diffstat (limited to 'drivers/media/dvb/firewire/firedtv-1394.c')
-rw-r--r-- | drivers/media/dvb/firewire/firedtv-1394.c | 291 |
1 files changed, 291 insertions, 0 deletions
diff --git a/drivers/media/dvb/firewire/firedtv-1394.c b/drivers/media/dvb/firewire/firedtv-1394.c new file mode 100644 index 000000000000..953618246e8e --- /dev/null +++ b/drivers/media/dvb/firewire/firedtv-1394.c | |||
@@ -0,0 +1,291 @@ | |||
1 | /* | ||
2 | * FireDTV driver (formerly known as FireSAT) | ||
3 | * | ||
4 | * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com> | ||
5 | * Copyright (C) 2007-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/device.h> | ||
15 | #include <linux/errno.h> | ||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/list.h> | ||
18 | #include <linux/module.h> | ||
19 | #include <linux/mutex.h> | ||
20 | #include <linux/slab.h> | ||
21 | #include <linux/spinlock.h> | ||
22 | #include <linux/string.h> | ||
23 | #include <linux/types.h> | ||
24 | |||
25 | #include <dmxdev.h> | ||
26 | #include <dvb_demux.h> | ||
27 | #include <dvb_frontend.h> | ||
28 | #include <dvbdev.h> | ||
29 | |||
30 | #include <csr1212.h> | ||
31 | #include <highlevel.h> | ||
32 | #include <hosts.h> | ||
33 | #include <ieee1394_hotplug.h> | ||
34 | #include <nodemgr.h> | ||
35 | |||
36 | #include "avc.h" | ||
37 | #include "cmp.h" | ||
38 | #include "firedtv.h" | ||
39 | #include "firedtv-ci.h" | ||
40 | #include "firedtv-rc.h" | ||
41 | |||
42 | #define MATCH_FLAGS IEEE1394_MATCH_VENDOR_ID | IEEE1394_MATCH_MODEL_ID | \ | ||
43 | IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION | ||
44 | #define DIGITAL_EVERYWHERE_OUI 0x001287 | ||
45 | |||
46 | static struct ieee1394_device_id fdtv_id_table[] = { | ||
47 | |||
48 | { | ||
49 | /* FloppyDTV S/CI and FloppyDTV S2 */ | ||
50 | .match_flags = MATCH_FLAGS, | ||
51 | .vendor_id = DIGITAL_EVERYWHERE_OUI, | ||
52 | .model_id = 0x000024, | ||
53 | .specifier_id = AVC_UNIT_SPEC_ID_ENTRY, | ||
54 | .version = AVC_SW_VERSION_ENTRY, | ||
55 | },{ | ||
56 | /* FloppyDTV T/CI */ | ||
57 | .match_flags = MATCH_FLAGS, | ||
58 | .vendor_id = DIGITAL_EVERYWHERE_OUI, | ||
59 | .model_id = 0x000025, | ||
60 | .specifier_id = AVC_UNIT_SPEC_ID_ENTRY, | ||
61 | .version = AVC_SW_VERSION_ENTRY, | ||
62 | },{ | ||
63 | /* FloppyDTV C/CI */ | ||
64 | .match_flags = MATCH_FLAGS, | ||
65 | .vendor_id = DIGITAL_EVERYWHERE_OUI, | ||
66 | .model_id = 0x000026, | ||
67 | .specifier_id = AVC_UNIT_SPEC_ID_ENTRY, | ||
68 | .version = AVC_SW_VERSION_ENTRY, | ||
69 | },{ | ||
70 | /* FireDTV S/CI and FloppyDTV S2 */ | ||
71 | .match_flags = MATCH_FLAGS, | ||
72 | .vendor_id = DIGITAL_EVERYWHERE_OUI, | ||
73 | .model_id = 0x000034, | ||
74 | .specifier_id = AVC_UNIT_SPEC_ID_ENTRY, | ||
75 | .version = AVC_SW_VERSION_ENTRY, | ||
76 | },{ | ||
77 | /* FireDTV T/CI */ | ||
78 | .match_flags = MATCH_FLAGS, | ||
79 | .vendor_id = DIGITAL_EVERYWHERE_OUI, | ||
80 | .model_id = 0x000035, | ||
81 | .specifier_id = AVC_UNIT_SPEC_ID_ENTRY, | ||
82 | .version = AVC_SW_VERSION_ENTRY, | ||
83 | },{ | ||
84 | /* FireDTV C/CI */ | ||
85 | .match_flags = MATCH_FLAGS, | ||
86 | .vendor_id = DIGITAL_EVERYWHERE_OUI, | ||
87 | .model_id = 0x000036, | ||
88 | .specifier_id = AVC_UNIT_SPEC_ID_ENTRY, | ||
89 | .version = AVC_SW_VERSION_ENTRY, | ||
90 | }, { } | ||
91 | }; | ||
92 | |||
93 | MODULE_DEVICE_TABLE(ieee1394, fdtv_id_table); | ||
94 | |||
95 | /* list of all firedtv devices */ | ||
96 | LIST_HEAD(fdtv_list); | ||
97 | DEFINE_SPINLOCK(fdtv_list_lock); | ||
98 | |||
99 | static void fcp_request(struct hpsb_host *host, | ||
100 | int nodeid, | ||
101 | int direction, | ||
102 | int cts, | ||
103 | u8 *data, | ||
104 | size_t length) | ||
105 | { | ||
106 | struct firedtv *fdtv = NULL; | ||
107 | struct firedtv *fdtv_entry; | ||
108 | unsigned long flags; | ||
109 | |||
110 | if (length > 0 && ((data[0] & 0xf0) >> 4) == 0) { | ||
111 | |||
112 | spin_lock_irqsave(&fdtv_list_lock, flags); | ||
113 | list_for_each_entry(fdtv_entry,&fdtv_list,list) { | ||
114 | if (fdtv_entry->ud->ne->host == host && | ||
115 | fdtv_entry->ud->ne->nodeid == nodeid && | ||
116 | (fdtv_entry->subunit == (data[1]&0x7) || | ||
117 | (fdtv_entry->subunit == 0 && | ||
118 | (data[1]&0x7) == 0x7))) { | ||
119 | fdtv=fdtv_entry; | ||
120 | break; | ||
121 | } | ||
122 | } | ||
123 | spin_unlock_irqrestore(&fdtv_list_lock, flags); | ||
124 | |||
125 | if (fdtv) | ||
126 | avc_recv(fdtv, data, length); | ||
127 | } | ||
128 | } | ||
129 | |||
130 | const char *fdtv_model_names[] = { | ||
131 | [FIREDTV_UNKNOWN] = "unknown type", | ||
132 | [FIREDTV_DVB_S] = "FireDTV S/CI", | ||
133 | [FIREDTV_DVB_C] = "FireDTV C/CI", | ||
134 | [FIREDTV_DVB_T] = "FireDTV T/CI", | ||
135 | [FIREDTV_DVB_S2] = "FireDTV S2 ", | ||
136 | }; | ||
137 | |||
138 | static int fdtv_probe(struct device *dev) | ||
139 | { | ||
140 | struct unit_directory *ud = | ||
141 | container_of(dev, struct unit_directory, device); | ||
142 | struct firedtv *fdtv; | ||
143 | unsigned long flags; | ||
144 | int kv_len; | ||
145 | void *kv_str; | ||
146 | int i; | ||
147 | int err = -ENOMEM; | ||
148 | |||
149 | fdtv = kzalloc(sizeof(*fdtv), GFP_KERNEL); | ||
150 | if (!fdtv) | ||
151 | return -ENOMEM; | ||
152 | |||
153 | dev->driver_data = fdtv; | ||
154 | fdtv->ud = ud; | ||
155 | fdtv->subunit = 0; | ||
156 | fdtv->isochannel = -1; | ||
157 | fdtv->tone = 0xff; | ||
158 | fdtv->voltage = 0xff; | ||
159 | |||
160 | mutex_init(&fdtv->avc_mutex); | ||
161 | init_waitqueue_head(&fdtv->avc_wait); | ||
162 | fdtv->avc_reply_received = true; | ||
163 | mutex_init(&fdtv->demux_mutex); | ||
164 | INIT_WORK(&fdtv->remote_ctrl_work, avc_remote_ctrl_work); | ||
165 | |||
166 | /* Reading device model from ROM */ | ||
167 | kv_len = (ud->model_name_kv->value.leaf.len - 2) * sizeof(quadlet_t); | ||
168 | kv_str = CSR1212_TEXTUAL_DESCRIPTOR_LEAF_DATA(ud->model_name_kv); | ||
169 | for (i = ARRAY_SIZE(fdtv_model_names); --i;) | ||
170 | if (strlen(fdtv_model_names[i]) <= kv_len && | ||
171 | strncmp(kv_str, fdtv_model_names[i], kv_len) == 0) | ||
172 | break; | ||
173 | fdtv->type = i; | ||
174 | |||
175 | /* | ||
176 | * Work around a bug in udev's path_id script: Use the fw-host's dev | ||
177 | * instead of the unit directory's dev as parent of the input device. | ||
178 | */ | ||
179 | err = fdtv_register_rc(fdtv, dev->parent->parent); | ||
180 | if (err) | ||
181 | goto fail_free; | ||
182 | |||
183 | INIT_LIST_HEAD(&fdtv->list); | ||
184 | spin_lock_irqsave(&fdtv_list_lock, flags); | ||
185 | list_add_tail(&fdtv->list, &fdtv_list); | ||
186 | spin_unlock_irqrestore(&fdtv_list_lock, flags); | ||
187 | |||
188 | err = avc_identify_subunit(fdtv); | ||
189 | if (err) | ||
190 | goto fail; | ||
191 | |||
192 | err = fdtv_dvbdev_init(fdtv, dev); | ||
193 | if (err) | ||
194 | goto fail; | ||
195 | |||
196 | avc_register_remote_control(fdtv); | ||
197 | return 0; | ||
198 | |||
199 | fail: | ||
200 | spin_lock_irqsave(&fdtv_list_lock, flags); | ||
201 | list_del(&fdtv->list); | ||
202 | spin_unlock_irqrestore(&fdtv_list_lock, flags); | ||
203 | fdtv_unregister_rc(fdtv); | ||
204 | fail_free: | ||
205 | kfree(fdtv); | ||
206 | return err; | ||
207 | } | ||
208 | |||
209 | static int fdtv_remove(struct device *dev) | ||
210 | { | ||
211 | struct firedtv *fdtv = dev->driver_data; | ||
212 | unsigned long flags; | ||
213 | |||
214 | fdtv_ca_release(fdtv); | ||
215 | dvb_unregister_frontend(&fdtv->fe); | ||
216 | dvb_net_release(&fdtv->dvbnet); | ||
217 | fdtv->demux.dmx.close(&fdtv->demux.dmx); | ||
218 | fdtv->demux.dmx.remove_frontend(&fdtv->demux.dmx, | ||
219 | &fdtv->frontend); | ||
220 | dvb_dmxdev_release(&fdtv->dmxdev); | ||
221 | dvb_dmx_release(&fdtv->demux); | ||
222 | dvb_unregister_adapter(&fdtv->adapter); | ||
223 | |||
224 | spin_lock_irqsave(&fdtv_list_lock, flags); | ||
225 | list_del(&fdtv->list); | ||
226 | spin_unlock_irqrestore(&fdtv_list_lock, flags); | ||
227 | |||
228 | cancel_work_sync(&fdtv->remote_ctrl_work); | ||
229 | fdtv_unregister_rc(fdtv); | ||
230 | |||
231 | kfree(fdtv); | ||
232 | return 0; | ||
233 | } | ||
234 | |||
235 | static int fdtv_update(struct unit_directory *ud) | ||
236 | { | ||
237 | struct firedtv *fdtv = ud->device.driver_data; | ||
238 | |||
239 | if (fdtv->isochannel >= 0) | ||
240 | cmp_establish_pp_connection(fdtv, fdtv->subunit, | ||
241 | fdtv->isochannel); | ||
242 | return 0; | ||
243 | } | ||
244 | |||
245 | static struct hpsb_protocol_driver fdtv_driver = { | ||
246 | |||
247 | .name = "firedtv", | ||
248 | .id_table = fdtv_id_table, | ||
249 | .update = fdtv_update, | ||
250 | |||
251 | .driver = { | ||
252 | //.name and .bus are filled in for us in more recent linux versions | ||
253 | //.name = "FireDTV", | ||
254 | //.bus = &ieee1394_bus_type, | ||
255 | .probe = fdtv_probe, | ||
256 | .remove = fdtv_remove, | ||
257 | }, | ||
258 | }; | ||
259 | |||
260 | static struct hpsb_highlevel fdtv_highlevel = { | ||
261 | .name = "firedtv", | ||
262 | .fcp_request = fcp_request, | ||
263 | }; | ||
264 | |||
265 | static int __init fdtv_init(void) | ||
266 | { | ||
267 | int ret; | ||
268 | |||
269 | hpsb_register_highlevel(&fdtv_highlevel); | ||
270 | ret = hpsb_register_protocol(&fdtv_driver); | ||
271 | if (ret) { | ||
272 | printk(KERN_ERR "firedtv: failed to register protocol\n"); | ||
273 | hpsb_unregister_highlevel(&fdtv_highlevel); | ||
274 | } | ||
275 | return ret; | ||
276 | } | ||
277 | |||
278 | static void __exit fdtv_exit(void) | ||
279 | { | ||
280 | hpsb_unregister_protocol(&fdtv_driver); | ||
281 | hpsb_unregister_highlevel(&fdtv_highlevel); | ||
282 | } | ||
283 | |||
284 | module_init(fdtv_init); | ||
285 | module_exit(fdtv_exit); | ||
286 | |||
287 | MODULE_AUTHOR("Andreas Monitzer <andy@monitzer.com>"); | ||
288 | MODULE_AUTHOR("Ben Backx <ben@bbackx.com>"); | ||
289 | MODULE_DESCRIPTION("FireDTV DVB Driver"); | ||
290 | MODULE_LICENSE("GPL"); | ||
291 | MODULE_SUPPORTED_DEVICE("FireDTV DVB"); | ||