aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/firewire/firedtv-dvb.c
diff options
context:
space:
mode:
authorRambaldi <Rambaldi@xs4all.nl>2009-01-17 08:47:34 -0500
committerStefan Richter <stefanr@s5r6.in-berlin.de>2009-02-24 08:51:29 -0500
commita70f81c1c0dac113ac4705e7701e2676e67905cd (patch)
tree2ff18425bc3b9a4cbf083c82e011a06a0f88f926 /drivers/media/dvb/firewire/firedtv-dvb.c
parent291f006efeebeeb2073289e44efb8f97cf157220 (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-dvb.c')
-rw-r--r--drivers/media/dvb/firewire/firedtv-dvb.c276
1 files changed, 276 insertions, 0 deletions
diff --git a/drivers/media/dvb/firewire/firedtv-dvb.c b/drivers/media/dvb/firewire/firedtv-dvb.c
new file mode 100644
index 00000000000..1823058696f
--- /dev/null
+++ b/drivers/media/dvb/firewire/firedtv-dvb.c
@@ -0,0 +1,276 @@
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/errno.h>
14#include <linux/kernel.h>
15#include <linux/mutex.h>
16#include <linux/types.h>
17
18#include <dvb_demux.h>
19#include <dvb_frontend.h>
20#include <dvbdev.h>
21
22#include "avc.h"
23#include "firedtv.h"
24#include "firedtv-ci.h"
25
26DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
27
28static struct firedtv_channel *fdtv_channel_allocate(struct firedtv *fdtv)
29{
30 struct firedtv_channel *c = NULL;
31 int k;
32
33 if (mutex_lock_interruptible(&fdtv->demux_mutex))
34 return NULL;
35
36 for (k = 0; k < 16; k++)
37 if (!fdtv->channel[k].active) {
38 fdtv->channel[k].active = true;
39 c = &fdtv->channel[k];
40 break;
41 }
42
43 mutex_unlock(&fdtv->demux_mutex);
44 return c;
45}
46
47static int fdtv_channel_collect(struct firedtv *fdtv, int *pidc, u16 pid[])
48{
49 int k, l = 0;
50
51 if (mutex_lock_interruptible(&fdtv->demux_mutex))
52 return -EINTR;
53
54 for (k = 0; k < 16; k++)
55 if (fdtv->channel[k].active)
56 pid[l++] = fdtv->channel[k].pid;
57
58 mutex_unlock(&fdtv->demux_mutex);
59
60 *pidc = l;
61
62 return 0;
63}
64
65static int fdtv_channel_release(struct firedtv *fdtv,
66 struct firedtv_channel *channel)
67{
68 if (mutex_lock_interruptible(&fdtv->demux_mutex))
69 return -EINTR;
70
71 channel->active = false;
72
73 mutex_unlock(&fdtv->demux_mutex);
74 return 0;
75}
76
77int fdtv_start_feed(struct dvb_demux_feed *dvbdmxfeed)
78{
79 struct firedtv *fdtv = (struct firedtv*)dvbdmxfeed->demux->priv;
80 struct firedtv_channel *channel;
81 int pidc,k;
82 u16 pids[16];
83
84 switch (dvbdmxfeed->type) {
85 case DMX_TYPE_TS:
86 case DMX_TYPE_SEC:
87 break;
88 default:
89 printk(KERN_ERR "%s: invalid type %u\n",
90 __func__, dvbdmxfeed->type);
91 return -EINVAL;
92 }
93
94 if (dvbdmxfeed->type == DMX_TYPE_TS) {
95 switch (dvbdmxfeed->pes_type) {
96 case DMX_TS_PES_VIDEO:
97 case DMX_TS_PES_AUDIO:
98 case DMX_TS_PES_TELETEXT:
99 case DMX_TS_PES_PCR:
100 case DMX_TS_PES_OTHER:
101 //Dirty fix to keep fdtv->channel pid-list up to date
102 for(k=0;k<16;k++){
103 if (!fdtv->channel[k].active)
104 fdtv->channel[k].pid =
105 dvbdmxfeed->pid;
106 break;
107 }
108 channel = fdtv_channel_allocate(fdtv);
109 break;
110 default:
111 printk(KERN_ERR "%s: invalid pes type %u\n",
112 __func__, dvbdmxfeed->pes_type);
113 return -EINVAL;
114 }
115 } else {
116 channel = fdtv_channel_allocate(fdtv);
117 }
118
119 if (!channel) {
120 printk(KERN_ERR "%s: busy!\n", __func__);
121 return -EBUSY;
122 }
123
124 dvbdmxfeed->priv = channel;
125 channel->pid = dvbdmxfeed->pid;
126
127 if (fdtv_channel_collect(fdtv, &pidc, pids)) {
128 fdtv_channel_release(fdtv, channel);
129 printk(KERN_ERR "%s: could not collect pids!\n", __func__);
130 return -EINTR;
131 }
132
133 if (dvbdmxfeed->pid == 8192) {
134 k = avc_tuner_get_ts(fdtv);
135 if (k) {
136 fdtv_channel_release(fdtv, channel);
137 printk("%s: AVCTuner_GetTS failed with error %d\n",
138 __func__, k);
139 return k;
140 }
141 } else {
142 k = avc_tuner_set_pids(fdtv, pidc, pids);
143 if (k) {
144 fdtv_channel_release(fdtv, channel);
145 printk("%s: AVCTuner_SetPIDs failed with error %d\n",
146 __func__, k);
147 return k;
148 }
149 }
150
151 return 0;
152}
153
154int fdtv_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
155{
156 struct dvb_demux *demux = dvbdmxfeed->demux;
157 struct firedtv *fdtv = (struct firedtv*)demux->priv;
158 struct firedtv_channel *c = dvbdmxfeed->priv;
159 int k, l;
160 u16 pids[16];
161
162 if (dvbdmxfeed->type == DMX_TYPE_TS && !((dvbdmxfeed->ts_type & TS_PACKET) &&
163 (demux->dmx.frontend->source != DMX_MEMORY_FE))) {
164
165 if (dvbdmxfeed->ts_type & TS_DECODER) {
166
167 if (dvbdmxfeed->pes_type >= DMX_TS_PES_OTHER ||
168 !demux->pesfilter[dvbdmxfeed->pes_type])
169
170 return -EINVAL;
171
172 demux->pids[dvbdmxfeed->pes_type] |= 0x8000;
173 demux->pesfilter[dvbdmxfeed->pes_type] = NULL;
174 }
175
176 if (!(dvbdmxfeed->ts_type & TS_DECODER &&
177 dvbdmxfeed->pes_type < DMX_TS_PES_OTHER))
178
179 return 0;
180 }
181
182 if (mutex_lock_interruptible(&fdtv->demux_mutex))
183 return -EINTR;
184
185 /* list except channel to be removed */
186 for (k = 0, l = 0; k < 16; k++)
187 if (fdtv->channel[k].active) {
188 if (&fdtv->channel[k] != c)
189 pids[l++] = fdtv->channel[k].pid;
190 else
191 fdtv->channel[k].active = false;
192 }
193
194 k = avc_tuner_set_pids(fdtv, l, pids);
195 if (!k)
196 c->active = false;
197
198 mutex_unlock(&fdtv->demux_mutex);
199 return k;
200}
201
202int fdtv_dvbdev_init(struct firedtv *fdtv, struct device *dev)
203{
204 int err;
205
206 err = DVB_REGISTER_ADAPTER(&fdtv->adapter,
207 fdtv_model_names[fdtv->type],
208 THIS_MODULE, dev, adapter_nr);
209 if (err < 0)
210 goto fail_log;
211
212 /*DMX_TS_FILTERING | DMX_SECTION_FILTERING*/
213 fdtv->demux.dmx.capabilities = 0;
214
215 fdtv->demux.priv = fdtv;
216 fdtv->demux.filternum = 16;
217 fdtv->demux.feednum = 16;
218 fdtv->demux.start_feed = fdtv_start_feed;
219 fdtv->demux.stop_feed = fdtv_stop_feed;
220 fdtv->demux.write_to_decoder = NULL;
221
222 err = dvb_dmx_init(&fdtv->demux);
223 if (err)
224 goto fail_unreg_adapter;
225
226 fdtv->dmxdev.filternum = 16;
227 fdtv->dmxdev.demux = &fdtv->demux.dmx;
228 fdtv->dmxdev.capabilities = 0;
229
230 err = dvb_dmxdev_init(&fdtv->dmxdev, &fdtv->adapter);
231 if (err)
232 goto fail_dmx_release;
233
234 fdtv->frontend.source = DMX_FRONTEND_0;
235
236 err = fdtv->demux.dmx.add_frontend(&fdtv->demux.dmx,
237 &fdtv->frontend);
238 if (err)
239 goto fail_dmxdev_release;
240
241 err = fdtv->demux.dmx.connect_frontend(&fdtv->demux.dmx,
242 &fdtv->frontend);
243 if (err)
244 goto fail_rem_frontend;
245
246 dvb_net_init(&fdtv->adapter, &fdtv->dvbnet, &fdtv->demux.dmx);
247
248 fdtv_frontend_init(fdtv);
249 err = dvb_register_frontend(&fdtv->adapter, &fdtv->fe);
250 if (err)
251 goto fail_net_release;
252
253 err = fdtv_ca_register(fdtv);
254 if (err)
255 dev_info(dev, "Conditional Access Module not enabled\n");
256
257 return 0;
258
259fail_net_release:
260 dvb_net_release(&fdtv->dvbnet);
261 fdtv->demux.dmx.close(&fdtv->demux.dmx);
262fail_rem_frontend:
263 fdtv->demux.dmx.remove_frontend(&fdtv->demux.dmx,
264 &fdtv->frontend);
265fail_dmxdev_release:
266 dvb_dmxdev_release(&fdtv->dmxdev);
267fail_dmx_release:
268 dvb_dmx_release(&fdtv->demux);
269fail_unreg_adapter:
270 dvb_unregister_adapter(&fdtv->adapter);
271fail_log:
272 dev_err(dev, "DVB initialization failed\n");
273 return err;
274}
275
276