1 // SPDX-License-Identifier: GPL-2.0-or-later
3 Mantis PCI bridge driver
4 Copyright (C) Manu Abraham (abraham.manu@gmail.com)
8 #include <linux/kernel.h>
9 #include <linux/bitops.h>
11 #include <linux/signal.h>
12 #include <linux/sched.h>
13 #include <linux/interrupt.h>
14 #include <linux/pci.h>
15 #include <linux/i2c.h>
17 #include <media/dmxdev.h>
18 #include <media/dvbdev.h>
19 #include <media/dvb_demux.h>
20 #include <media/dvb_frontend.h>
21 #include <media/dvb_net.h>
23 #include "mantis_common.h"
24 #include "mantis_dma.h"
25 #include "mantis_ca.h"
26 #include "mantis_ioc.h"
27 #include "mantis_dvb.h"
29 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr
);
31 int mantis_frontend_power(struct mantis_pci
*mantis
, enum mantis_power power
)
33 struct mantis_hwconfig
*config
= mantis
->hwconfig
;
37 dprintk(MANTIS_DEBUG
, 1, "Power ON");
38 mantis_gpio_set_bits(mantis
, config
->power
, POWER_ON
);
40 mantis_gpio_set_bits(mantis
, config
->power
, POWER_ON
);
45 dprintk(MANTIS_DEBUG
, 1, "Power OFF");
46 mantis_gpio_set_bits(mantis
, config
->power
, POWER_OFF
);
51 dprintk(MANTIS_DEBUG
, 1, "Unknown state <%02x>", power
);
57 EXPORT_SYMBOL_GPL(mantis_frontend_power
);
59 void mantis_frontend_soft_reset(struct mantis_pci
*mantis
)
61 struct mantis_hwconfig
*config
= mantis
->hwconfig
;
63 dprintk(MANTIS_DEBUG
, 1, "Frontend RESET");
64 mantis_gpio_set_bits(mantis
, config
->reset
, 0);
66 mantis_gpio_set_bits(mantis
, config
->reset
, 0);
68 mantis_gpio_set_bits(mantis
, config
->reset
, 1);
70 mantis_gpio_set_bits(mantis
, config
->reset
, 1);
75 EXPORT_SYMBOL_GPL(mantis_frontend_soft_reset
);
77 static int mantis_frontend_shutdown(struct mantis_pci
*mantis
)
81 mantis_frontend_soft_reset(mantis
);
82 err
= mantis_frontend_power(mantis
, POWER_OFF
);
84 dprintk(MANTIS_ERROR
, 1, "Frontend POWER OFF failed! <%d>", err
);
91 static int mantis_dvb_start_feed(struct dvb_demux_feed
*dvbdmxfeed
)
93 struct dvb_demux
*dvbdmx
= dvbdmxfeed
->demux
;
94 struct mantis_pci
*mantis
= dvbdmx
->priv
;
96 dprintk(MANTIS_DEBUG
, 1, "Mantis DVB Start feed");
97 if (!dvbdmx
->dmx
.frontend
) {
98 dprintk(MANTIS_DEBUG
, 1, "no frontend ?");
103 dprintk(MANTIS_DEBUG
, 1, "mantis start feed, feeds=%d", mantis
->feeds
);
105 if (mantis
->feeds
== 1) {
106 dprintk(MANTIS_DEBUG
, 1, "mantis start feed & dma");
107 mantis_dma_start(mantis
);
108 enable_and_queue_work(system_bh_wq
, &mantis
->bh_work
);
111 return mantis
->feeds
;
114 static int mantis_dvb_stop_feed(struct dvb_demux_feed
*dvbdmxfeed
)
116 struct dvb_demux
*dvbdmx
= dvbdmxfeed
->demux
;
117 struct mantis_pci
*mantis
= dvbdmx
->priv
;
119 dprintk(MANTIS_DEBUG
, 1, "Mantis DVB Stop feed");
120 if (!dvbdmx
->dmx
.frontend
) {
121 dprintk(MANTIS_DEBUG
, 1, "no frontend ?");
126 if (mantis
->feeds
== 0) {
127 dprintk(MANTIS_DEBUG
, 1, "mantis stop feed and dma");
128 disable_work_sync(&mantis
->bh_work
);
129 mantis_dma_stop(mantis
);
135 int mantis_dvb_init(struct mantis_pci
*mantis
)
137 struct mantis_hwconfig
*config
= mantis
->hwconfig
;
140 dprintk(MANTIS_DEBUG
, 1, "dvb_register_adapter");
142 result
= dvb_register_adapter(&mantis
->dvb_adapter
,
143 "Mantis DVB adapter",
150 dprintk(MANTIS_ERROR
, 1, "Error registering adapter");
154 mantis
->dvb_adapter
.priv
= mantis
;
155 mantis
->demux
.dmx
.capabilities
= DMX_TS_FILTERING
|
156 DMX_SECTION_FILTERING
|
157 DMX_MEMORY_BASED_FILTERING
;
159 mantis
->demux
.priv
= mantis
;
160 mantis
->demux
.filternum
= 256;
161 mantis
->demux
.feednum
= 256;
162 mantis
->demux
.start_feed
= mantis_dvb_start_feed
;
163 mantis
->demux
.stop_feed
= mantis_dvb_stop_feed
;
164 mantis
->demux
.write_to_decoder
= NULL
;
166 dprintk(MANTIS_DEBUG
, 1, "dvb_dmx_init");
167 result
= dvb_dmx_init(&mantis
->demux
);
169 dprintk(MANTIS_ERROR
, 1, "dvb_dmx_init failed, ERROR=%d", result
);
174 mantis
->dmxdev
.filternum
= 256;
175 mantis
->dmxdev
.demux
= &mantis
->demux
.dmx
;
176 mantis
->dmxdev
.capabilities
= 0;
177 dprintk(MANTIS_DEBUG
, 1, "dvb_dmxdev_init");
179 result
= dvb_dmxdev_init(&mantis
->dmxdev
, &mantis
->dvb_adapter
);
182 dprintk(MANTIS_ERROR
, 1, "dvb_dmxdev_init failed, ERROR=%d", result
);
186 mantis
->fe_hw
.source
= DMX_FRONTEND_0
;
187 result
= mantis
->demux
.dmx
.add_frontend(&mantis
->demux
.dmx
, &mantis
->fe_hw
);
190 dprintk(MANTIS_ERROR
, 1, "dvb_dmx_init failed, ERROR=%d", result
);
194 mantis
->fe_mem
.source
= DMX_MEMORY_FE
;
195 result
= mantis
->demux
.dmx
.add_frontend(&mantis
->demux
.dmx
, &mantis
->fe_mem
);
197 dprintk(MANTIS_ERROR
, 1, "dvb_dmx_init failed, ERROR=%d", result
);
201 result
= mantis
->demux
.dmx
.connect_frontend(&mantis
->demux
.dmx
, &mantis
->fe_hw
);
203 dprintk(MANTIS_ERROR
, 1, "dvb_dmx_init failed, ERROR=%d", result
);
207 dvb_net_init(&mantis
->dvb_adapter
, &mantis
->dvbnet
, &mantis
->demux
.dmx
);
208 INIT_WORK(&mantis
->bh_work
, mantis_dma_xfer
);
209 disable_work_sync(&mantis
->bh_work
);
210 if (mantis
->hwconfig
) {
211 result
= config
->frontend_init(mantis
, mantis
->fe
);
213 dprintk(MANTIS_ERROR
, 1, "!!! NO Frontends found !!!");
216 if (mantis
->fe
== NULL
) {
218 dprintk(MANTIS_ERROR
, 1, "FE <NULL>");
221 result
= dvb_register_frontend(&mantis
->dvb_adapter
, mantis
->fe
);
223 dprintk(MANTIS_ERROR
, 1, "ERROR: Frontend registration failed");
225 if (mantis
->fe
->ops
.release
)
226 mantis
->fe
->ops
.release(mantis
->fe
);
236 /* Error conditions .. */
238 cancel_work_sync(&mantis
->bh_work
);
239 dvb_net_release(&mantis
->dvbnet
);
241 dvb_unregister_frontend(mantis
->fe
);
242 dvb_frontend_detach(mantis
->fe
);
245 mantis
->demux
.dmx
.remove_frontend(&mantis
->demux
.dmx
, &mantis
->fe_mem
);
248 mantis
->demux
.dmx
.remove_frontend(&mantis
->demux
.dmx
, &mantis
->fe_hw
);
251 dvb_dmxdev_release(&mantis
->dmxdev
);
254 dvb_dmx_release(&mantis
->demux
);
257 dvb_unregister_adapter(&mantis
->dvb_adapter
);
261 EXPORT_SYMBOL_GPL(mantis_dvb_init
);
263 int mantis_dvb_exit(struct mantis_pci
*mantis
)
268 /* mantis_ca_exit(mantis); */
269 err
= mantis_frontend_shutdown(mantis
);
271 dprintk(MANTIS_ERROR
, 1, "Frontend exit while POWER ON! <%d>", err
);
272 dvb_unregister_frontend(mantis
->fe
);
273 dvb_frontend_detach(mantis
->fe
);
276 cancel_work_sync(&mantis
->bh_work
);
277 dvb_net_release(&mantis
->dvbnet
);
279 mantis
->demux
.dmx
.remove_frontend(&mantis
->demux
.dmx
, &mantis
->fe_mem
);
280 mantis
->demux
.dmx
.remove_frontend(&mantis
->demux
.dmx
, &mantis
->fe_hw
);
282 dvb_dmxdev_release(&mantis
->dmxdev
);
283 dvb_dmx_release(&mantis
->demux
);
285 dprintk(MANTIS_DEBUG
, 1, "dvb_unregister_adapter");
286 dvb_unregister_adapter(&mantis
->dvb_adapter
);
290 EXPORT_SYMBOL_GPL(mantis_dvb_exit
);