Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/media/dvb/mantis/mantis_dvb.c
15112 views
1
/*
2
Mantis PCI bridge driver
3
Copyright (C) Manu Abraham ([email protected])
4
5
This program is free software; you can redistribute it and/or modify
6
it under the terms of the GNU General Public License as published by
7
the Free Software Foundation; either version 2 of the License, or
8
(at your option) any later version.
9
10
This program is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
GNU General Public License for more details.
14
15
You should have received a copy of the GNU General Public License
16
along with this program; if not, write to the Free Software
17
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18
*/
19
20
#include <linux/kernel.h>
21
#include <linux/bitops.h>
22
23
#include <linux/signal.h>
24
#include <linux/sched.h>
25
#include <linux/interrupt.h>
26
#include <linux/pci.h>
27
#include <linux/i2c.h>
28
29
#include "dmxdev.h"
30
#include "dvbdev.h"
31
#include "dvb_demux.h"
32
#include "dvb_frontend.h"
33
#include "dvb_net.h"
34
35
#include "mantis_common.h"
36
#include "mantis_dma.h"
37
#include "mantis_ca.h"
38
#include "mantis_ioc.h"
39
#include "mantis_dvb.h"
40
41
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
42
43
int mantis_frontend_power(struct mantis_pci *mantis, enum mantis_power power)
44
{
45
struct mantis_hwconfig *config = mantis->hwconfig;
46
47
switch (power) {
48
case POWER_ON:
49
dprintk(MANTIS_DEBUG, 1, "Power ON");
50
mantis_gpio_set_bits(mantis, config->power, POWER_ON);
51
msleep(100);
52
mantis_gpio_set_bits(mantis, config->power, POWER_ON);
53
msleep(100);
54
break;
55
56
case POWER_OFF:
57
dprintk(MANTIS_DEBUG, 1, "Power OFF");
58
mantis_gpio_set_bits(mantis, config->power, POWER_OFF);
59
msleep(100);
60
break;
61
62
default:
63
dprintk(MANTIS_DEBUG, 1, "Unknown state <%02x>", power);
64
return -1;
65
}
66
67
return 0;
68
}
69
EXPORT_SYMBOL_GPL(mantis_frontend_power);
70
71
void mantis_frontend_soft_reset(struct mantis_pci *mantis)
72
{
73
struct mantis_hwconfig *config = mantis->hwconfig;
74
75
dprintk(MANTIS_DEBUG, 1, "Frontend RESET");
76
mantis_gpio_set_bits(mantis, config->reset, 0);
77
msleep(100);
78
mantis_gpio_set_bits(mantis, config->reset, 0);
79
msleep(100);
80
mantis_gpio_set_bits(mantis, config->reset, 1);
81
msleep(100);
82
mantis_gpio_set_bits(mantis, config->reset, 1);
83
msleep(100);
84
85
return;
86
}
87
EXPORT_SYMBOL_GPL(mantis_frontend_soft_reset);
88
89
static int mantis_frontend_shutdown(struct mantis_pci *mantis)
90
{
91
int err;
92
93
mantis_frontend_soft_reset(mantis);
94
err = mantis_frontend_power(mantis, POWER_OFF);
95
if (err != 0) {
96
dprintk(MANTIS_ERROR, 1, "Frontend POWER OFF failed! <%d>", err);
97
return 1;
98
}
99
100
return 0;
101
}
102
103
static int mantis_dvb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
104
{
105
struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
106
struct mantis_pci *mantis = dvbdmx->priv;
107
108
dprintk(MANTIS_DEBUG, 1, "Mantis DVB Start feed");
109
if (!dvbdmx->dmx.frontend) {
110
dprintk(MANTIS_DEBUG, 1, "no frontend ?");
111
return -EINVAL;
112
}
113
114
mantis->feeds++;
115
dprintk(MANTIS_DEBUG, 1, "mantis start feed, feeds=%d", mantis->feeds);
116
117
if (mantis->feeds == 1) {
118
dprintk(MANTIS_DEBUG, 1, "mantis start feed & dma");
119
mantis_dma_start(mantis);
120
tasklet_enable(&mantis->tasklet);
121
}
122
123
return mantis->feeds;
124
}
125
126
static int mantis_dvb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
127
{
128
struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
129
struct mantis_pci *mantis = dvbdmx->priv;
130
131
dprintk(MANTIS_DEBUG, 1, "Mantis DVB Stop feed");
132
if (!dvbdmx->dmx.frontend) {
133
dprintk(MANTIS_DEBUG, 1, "no frontend ?");
134
return -EINVAL;
135
}
136
137
mantis->feeds--;
138
if (mantis->feeds == 0) {
139
dprintk(MANTIS_DEBUG, 1, "mantis stop feed and dma");
140
tasklet_disable(&mantis->tasklet);
141
mantis_dma_stop(mantis);
142
}
143
144
return 0;
145
}
146
147
int __devinit mantis_dvb_init(struct mantis_pci *mantis)
148
{
149
struct mantis_hwconfig *config = mantis->hwconfig;
150
int result = -1;
151
152
dprintk(MANTIS_DEBUG, 1, "dvb_register_adapter");
153
154
result = dvb_register_adapter(&mantis->dvb_adapter,
155
"Mantis DVB adapter",
156
THIS_MODULE,
157
&mantis->pdev->dev,
158
adapter_nr);
159
160
if (result < 0) {
161
162
dprintk(MANTIS_ERROR, 1, "Error registering adapter");
163
return -ENODEV;
164
}
165
166
mantis->dvb_adapter.priv = mantis;
167
mantis->demux.dmx.capabilities = DMX_TS_FILTERING |
168
DMX_SECTION_FILTERING |
169
DMX_MEMORY_BASED_FILTERING;
170
171
mantis->demux.priv = mantis;
172
mantis->demux.filternum = 256;
173
mantis->demux.feednum = 256;
174
mantis->demux.start_feed = mantis_dvb_start_feed;
175
mantis->demux.stop_feed = mantis_dvb_stop_feed;
176
mantis->demux.write_to_decoder = NULL;
177
178
dprintk(MANTIS_DEBUG, 1, "dvb_dmx_init");
179
result = dvb_dmx_init(&mantis->demux);
180
if (result < 0) {
181
dprintk(MANTIS_ERROR, 1, "dvb_dmx_init failed, ERROR=%d", result);
182
183
goto err0;
184
}
185
186
mantis->dmxdev.filternum = 256;
187
mantis->dmxdev.demux = &mantis->demux.dmx;
188
mantis->dmxdev.capabilities = 0;
189
dprintk(MANTIS_DEBUG, 1, "dvb_dmxdev_init");
190
191
result = dvb_dmxdev_init(&mantis->dmxdev, &mantis->dvb_adapter);
192
if (result < 0) {
193
194
dprintk(MANTIS_ERROR, 1, "dvb_dmxdev_init failed, ERROR=%d", result);
195
goto err1;
196
}
197
198
mantis->fe_hw.source = DMX_FRONTEND_0;
199
result = mantis->demux.dmx.add_frontend(&mantis->demux.dmx, &mantis->fe_hw);
200
if (result < 0) {
201
202
dprintk(MANTIS_ERROR, 1, "dvb_dmx_init failed, ERROR=%d", result);
203
goto err2;
204
}
205
206
mantis->fe_mem.source = DMX_MEMORY_FE;
207
result = mantis->demux.dmx.add_frontend(&mantis->demux.dmx, &mantis->fe_mem);
208
if (result < 0) {
209
dprintk(MANTIS_ERROR, 1, "dvb_dmx_init failed, ERROR=%d", result);
210
goto err3;
211
}
212
213
result = mantis->demux.dmx.connect_frontend(&mantis->demux.dmx, &mantis->fe_hw);
214
if (result < 0) {
215
dprintk(MANTIS_ERROR, 1, "dvb_dmx_init failed, ERROR=%d", result);
216
goto err4;
217
}
218
219
dvb_net_init(&mantis->dvb_adapter, &mantis->dvbnet, &mantis->demux.dmx);
220
tasklet_init(&mantis->tasklet, mantis_dma_xfer, (unsigned long) mantis);
221
tasklet_disable(&mantis->tasklet);
222
if (mantis->hwconfig) {
223
result = config->frontend_init(mantis, mantis->fe);
224
if (result < 0) {
225
dprintk(MANTIS_ERROR, 1, "!!! NO Frontends found !!!");
226
goto err5;
227
} else {
228
if (mantis->fe == NULL) {
229
dprintk(MANTIS_ERROR, 1, "FE <NULL>");
230
goto err5;
231
}
232
233
if (dvb_register_frontend(&mantis->dvb_adapter, mantis->fe)) {
234
dprintk(MANTIS_ERROR, 1, "ERROR: Frontend registration failed");
235
236
if (mantis->fe->ops.release)
237
mantis->fe->ops.release(mantis->fe);
238
239
mantis->fe = NULL;
240
goto err5;
241
}
242
}
243
}
244
245
return 0;
246
247
/* Error conditions .. */
248
err5:
249
tasklet_kill(&mantis->tasklet);
250
dvb_net_release(&mantis->dvbnet);
251
dvb_unregister_frontend(mantis->fe);
252
dvb_frontend_detach(mantis->fe);
253
err4:
254
mantis->demux.dmx.remove_frontend(&mantis->demux.dmx, &mantis->fe_mem);
255
256
err3:
257
mantis->demux.dmx.remove_frontend(&mantis->demux.dmx, &mantis->fe_hw);
258
259
err2:
260
dvb_dmxdev_release(&mantis->dmxdev);
261
262
err1:
263
dvb_dmx_release(&mantis->demux);
264
265
err0:
266
dvb_unregister_adapter(&mantis->dvb_adapter);
267
268
return result;
269
}
270
EXPORT_SYMBOL_GPL(mantis_dvb_init);
271
272
int __devexit mantis_dvb_exit(struct mantis_pci *mantis)
273
{
274
int err;
275
276
if (mantis->fe) {
277
/* mantis_ca_exit(mantis); */
278
err = mantis_frontend_shutdown(mantis);
279
if (err != 0)
280
dprintk(MANTIS_ERROR, 1, "Frontend exit while POWER ON! <%d>", err);
281
dvb_unregister_frontend(mantis->fe);
282
dvb_frontend_detach(mantis->fe);
283
}
284
285
tasklet_kill(&mantis->tasklet);
286
dvb_net_release(&mantis->dvbnet);
287
288
mantis->demux.dmx.remove_frontend(&mantis->demux.dmx, &mantis->fe_mem);
289
mantis->demux.dmx.remove_frontend(&mantis->demux.dmx, &mantis->fe_hw);
290
291
dvb_dmxdev_release(&mantis->dmxdev);
292
dvb_dmx_release(&mantis->demux);
293
294
dprintk(MANTIS_DEBUG, 1, "dvb_unregister_adapter");
295
dvb_unregister_adapter(&mantis->dvb_adapter);
296
297
return 0;
298
}
299
EXPORT_SYMBOL_GPL(mantis_dvb_exit);
300
301