]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - drivers/media/dvb/mantis/mantis_dvb.c
V4L/DVB (13792): [Mantis/VP-2033] Do not claim TDA10023
[mirror_ubuntu-artful-kernel.git] / drivers / media / dvb / mantis / mantis_dvb.c
CommitLineData
41e840b1
MA
1/*
2 Mantis PCI bridge driver
3 Copyright (C) 2005, 2006 Manu Abraham (abraham.manu@gmail.com)
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/bitops.h>
21#include "mantis_common.h"
22#include "mantis_core.h"
23
24#include "dmxdev.h"
25#include "dvbdev.h"
26#include "dvb_demux.h"
27#include "dvb_frontend.h"
28#include "mantis_vp1033.h"
29#include "mantis_vp1034.h"
873c8c25 30#include "mantis_vp1041.h"
41e840b1 31#include "mantis_vp2033.h"
b2eb1312 32#include "mantis_vp2040.h"
41e840b1
MA
33#include "mantis_vp3030.h"
34
616f75e1
MA
35DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
36
41e840b1
MA
37/* Tuner power supply control */
38void mantis_fe_powerup(struct mantis_pci *mantis)
39{
40 dprintk(verbose, MANTIS_DEBUG, 1, "Frontend Power ON");
41 gpio_set_bits(mantis, 0x0c, 1);
42 msleep_interruptible(100);
43 gpio_set_bits(mantis, 0x0c, 1);
44 msleep_interruptible(100);
45}
46
47void mantis_fe_powerdown(struct mantis_pci *mantis)
48{
49 dprintk(verbose, MANTIS_DEBUG, 1, "Frontend Power OFF");
50 gpio_set_bits(mantis, 0x0c, 0);
51}
52
53static int mantis_fe_reset(struct dvb_frontend *fe)
54{
55 struct mantis_pci *mantis = fe->dvb->priv;
56
57 dprintk(verbose, MANTIS_DEBUG, 1, "Frontend Reset");
58 gpio_set_bits(mantis, 13, 0);
59 msleep_interruptible(100);
60 gpio_set_bits(mantis, 13, 0);
61 msleep_interruptible(100);
62 gpio_set_bits(mantis, 13, 1);
63 msleep_interruptible(100);
64 gpio_set_bits(mantis, 13, 1);
65
66 return 0;
67}
68
69static int mantis_frontend_reset(struct mantis_pci *mantis)
70{
71 dprintk(verbose, MANTIS_DEBUG, 1, "Frontend Reset");
72 gpio_set_bits(mantis, 13, 0);
73 msleep_interruptible(100);
74 gpio_set_bits(mantis, 13, 0);
75 msleep_interruptible(100);
76 gpio_set_bits(mantis, 13, 1);
77 msleep_interruptible(100);
78 gpio_set_bits(mantis, 13, 1);
79
80 return 0;
81}
82
83static int mantis_dvb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
84{
85 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
86 struct mantis_pci *mantis = dvbdmx->priv;
87
88 dprintk(verbose, MANTIS_DEBUG, 1, "Mantis DVB Start feed");
89 if (!dvbdmx->dmx.frontend) {
90 dprintk(verbose, MANTIS_DEBUG, 1, "no frontend ?");
91 return -EINVAL;
92 }
93 mantis->feeds++;
94 dprintk(verbose, MANTIS_DEBUG, 1,
95 "mantis start feed, feeds=%d",
96 mantis->feeds);
97
98 if (mantis->feeds == 1) {
99 dprintk(verbose, MANTIS_DEBUG, 1, "mantis start feed & dma");
100 printk("mantis start feed & dma\n");
101 mantis_dma_start(mantis);
102 }
103
104 return mantis->feeds;
105}
106
107static int mantis_dvb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
108{
109 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
110 struct mantis_pci *mantis = dvbdmx->priv;
111
112 dprintk(verbose, MANTIS_DEBUG, 1, "Mantis DVB Stop feed");
113 if (!dvbdmx->dmx.frontend) {
114 dprintk(verbose, MANTIS_DEBUG, 1, "no frontend ?");
115 return -EINVAL;
116 }
117 mantis->feeds--;
118 if (mantis->feeds == 0) {
119 dprintk(verbose, MANTIS_DEBUG, 1, "mantis stop feed and dma");
120 printk("mantis stop feed and dma\n");
121 mantis_dma_stop(mantis);
122 }
123 return 0;
124}
125
126int __devinit mantis_dvb_init(struct mantis_pci *mantis)
127{
128 int result;
129
130 dprintk(verbose, MANTIS_DEBUG, 1, "dvb_register_adapter");
131 if (dvb_register_adapter(&mantis->dvb_adapter,
132 "Mantis dvb adapter", THIS_MODULE,
616f75e1
MA
133 &mantis->pdev->dev,
134 adapter_nr) < 0) {
41e840b1
MA
135
136 dprintk(verbose, MANTIS_ERROR, 1, "Error registering adapter");
137 return -ENODEV;
138 }
139 mantis->dvb_adapter.priv = mantis;
140 mantis->demux.dmx.capabilities = DMX_TS_FILTERING |
141 DMX_SECTION_FILTERING |
142 DMX_MEMORY_BASED_FILTERING;
143
144 mantis->demux.priv = mantis;
145 mantis->demux.filternum = 256;
146 mantis->demux.feednum = 256;
147 mantis->demux.start_feed = mantis_dvb_start_feed;
148 mantis->demux.stop_feed = mantis_dvb_stop_feed;
149 mantis->demux.write_to_decoder = NULL;
41e840b1
MA
150 dprintk(verbose, MANTIS_DEBUG, 1, "dvb_dmx_init");
151 if ((result = dvb_dmx_init(&mantis->demux)) < 0) {
152 dprintk(verbose, MANTIS_ERROR, 1,
153 "dvb_dmx_init failed, ERROR=%d", result);
154
155 goto err0;
156 }
157 mantis->dmxdev.filternum = 256;
158 mantis->dmxdev.demux = &mantis->demux.dmx;
159 mantis->dmxdev.capabilities = 0;
160 dprintk(verbose, MANTIS_DEBUG, 1, "dvb_dmxdev_init");
161 if ((result = dvb_dmxdev_init(&mantis->dmxdev,
162 &mantis->dvb_adapter)) < 0) {
163
164 dprintk(verbose, MANTIS_ERROR, 1,
165 "dvb_dmxdev_init failed, ERROR=%d", result);
166 goto err1;
167 }
168 mantis->fe_hw.source = DMX_FRONTEND_0;
169 if ((result = mantis->demux.dmx.add_frontend(&mantis->demux.dmx,
170 &mantis->fe_hw)) < 0) {
171
172 dprintk(verbose, MANTIS_ERROR, 1,
173 "dvb_dmx_init failed, ERROR=%d", result);
174
175 goto err2;
176 }
177 mantis->fe_mem.source = DMX_MEMORY_FE;
178 if ((result = mantis->demux.dmx.add_frontend(&mantis->demux.dmx,
179 &mantis->fe_mem)) < 0) {
180 dprintk(verbose, MANTIS_ERROR, 1,
181 "dvb_dmx_init failed, ERROR=%d", result);
182
183 goto err3;
184 }
185 if ((result = mantis->demux.dmx.connect_frontend(&mantis->demux.dmx,
186 &mantis->fe_hw)) < 0) {
187
188 dprintk(verbose, MANTIS_ERROR, 1,
189 "dvb_dmx_init failed, ERROR=%d", result);
190
191 goto err4;
192 }
193 dvb_net_init(&mantis->dvb_adapter, &mantis->dvbnet, &mantis->demux.dmx);
194 tasklet_init(&mantis->tasklet, mantis_dma_xfer, (unsigned long) mantis);
195 mantis_frontend_init(mantis);
d9dd5f71
MA
196 mantis_ca_init(mantis);
197
41e840b1
MA
198 return 0;
199
200 /* Error conditions .. */
201err4:
202 mantis->demux.dmx.remove_frontend(&mantis->demux.dmx, &mantis->fe_mem);
203err3:
204 mantis->demux.dmx.remove_frontend(&mantis->demux.dmx, &mantis->fe_hw);
205err2:
206 dvb_dmxdev_release(&mantis->dmxdev);
207err1:
208 dvb_dmx_release(&mantis->demux);
209err0:
210 dvb_unregister_adapter(&mantis->dvb_adapter);
211
212 return result;
213}
214
41e840b1
MA
215int __devinit mantis_frontend_init(struct mantis_pci *mantis)
216{
217 dprintk(verbose, MANTIS_DEBUG, 1, "Mantis frontend Init");
218 mantis_fe_powerup(mantis);
219 mantis_frontend_reset(mantis);
df0cca17
MA
220 dprintk(verbose, MANTIS_DEBUG, 1, "Device ID=%02x", mantis->subsystem_device);
221 switch (mantis->subsystem_device) {
41e840b1
MA
222 case MANTIS_VP_1033_DVB_S: // VP-1033
223 dprintk(verbose, MANTIS_ERROR, 1, "Probing for STV0299 (DVB-S)");
224 mantis->fe = stv0299_attach(&lgtdqcs001f_config,
225 &mantis->adapter);
226
227 if (mantis->fe) {
228 mantis->fe->ops.tuner_ops.set_params = lgtdqcs001f_tuner_set;
229 dprintk(verbose, MANTIS_ERROR, 1,
230 "found STV0299 DVB-S frontend @ 0x%02x",
231 lgtdqcs001f_config.demod_address);
232
233 dprintk(verbose, MANTIS_ERROR, 1,
234 "Mantis DVB-S STV0299 frontend attach success");
235 }
236 break;
237 case MANTIS_VP_1034_DVB_S: // VP-1034
238 dprintk(verbose, MANTIS_ERROR, 1, "Probing for MB86A16 (DVB-S/DSS)");
239 mantis->fe = mb86a16_attach(&vp1034_config, &mantis->adapter);
240 if (mantis->fe) {
241 dprintk(verbose, MANTIS_ERROR, 1,
242 "found MB86A16 DVB-S/DSS frontend @0x%02x",
243 vp1034_config.demod_address);
244
245 }
246 break;
873c8c25 247 case MANTIS_VP_1041_DVB_S2:
35afca91 248 case TECHNISAT_SKYSTAR_HD2:
873c8c25
MA
249 mantis->fe = stb0899_attach(&vp1041_config, &mantis->adapter);
250 if (mantis->fe) {
251 dprintk(verbose, MANTIS_ERROR, 1,
252 "found STB0899 DVB-S/DVB-S2 frontend @0x%02x",
253 vp1041_config.demod_address);
254
255 if (stb6100_attach(mantis->fe, &vp1041_stb6100_config, &mantis->adapter)) {
256 if (!lnbp21_attach(mantis->fe, &mantis->adapter, 0, 0)) {
257 printk("%s: No LNBP21 found!\n", __FUNCTION__);
258 mantis->fe = NULL;
259 }
260 } else {
261 mantis->fe = NULL;
262 }
263 }
264 break;
41e840b1 265 case MANTIS_VP_2033_DVB_C: // VP-2033
ec1b6ff1
NE
266 case MANTIS_VP_2040_DVB_C: // VP-2040
267 case TERRATEC_CINERGY_C_PCI:
268 case TECHNISAT_CABLESTAR_HD2:
41e840b1 269 dprintk(verbose, MANTIS_ERROR, 1, "Probing for CU1216 (DVB-C)");
ec1b6ff1
NE
270 mantis->fe = tda10021_attach(&philips_cu1216_config,
271 &mantis->adapter,
272 read_pwm(mantis));
273
41e840b1 274 if (mantis->fe) {
41e840b1 275 dprintk(verbose, MANTIS_ERROR, 1,
b2eb1312 276 "found Philips CU1216 DVB-C frontend (TDA10021) @ 0x%02x",
41e840b1 277 philips_cu1216_config.demod_address);
ec1b6ff1
NE
278 } else {
279 mantis->fe = tda10023_attach(&tda10023_cu1216_config,
280 &mantis->adapter,
281 read_pwm(mantis));
282
283 if (mantis->fe) {
284 dprintk(verbose, MANTIS_ERROR, 1,
285 "found Philips CU1216 DVB-C frontend (TDA10023) @ 0x%02x",
286 philips_cu1216_config.demod_address);
287 }
41e840b1 288 }
b2eb1312
MA
289 if (mantis->fe) {
290 mantis->fe->ops.tuner_ops.set_params = philips_cu1216_tuner_set;
b2eb1312
MA
291 dprintk(verbose, MANTIS_ERROR, 1,
292 "Mantis DVB-C Philips CU1216 frontend attach success");
293 }
294 break;
41e840b1
MA
295 default:
296 dprintk(verbose, MANTIS_DEBUG, 1, "Unknown frontend:[0x%02x]",
297 mantis->sub_device_id);
298
299 return -ENODEV;
300 }
301 if (mantis->fe == NULL) {
302 dprintk(verbose, MANTIS_ERROR, 1, "!!! NO Frontends found !!!");
303 return -ENODEV;
304 } else {
305 if (dvb_register_frontend(&mantis->dvb_adapter, mantis->fe)) {
306 dprintk(verbose, MANTIS_ERROR, 1,
307 "ERROR: Frontend registration failed");
308
309 if (mantis->fe->ops.release)
310 mantis->fe->ops.release(mantis->fe);
311
312 mantis->fe = NULL;
313 return -ENODEV;
314 }
315 }
316
317 return 0;
318}
319
320int __devexit mantis_dvb_exit(struct mantis_pci *mantis)
321{
3062b157 322 mantis_ca_exit(mantis);
41e840b1
MA
323 tasklet_kill(&mantis->tasklet);
324 dvb_net_release(&mantis->dvbnet);
325 mantis->demux.dmx.remove_frontend(&mantis->demux.dmx, &mantis->fe_mem);
326 mantis->demux.dmx.remove_frontend(&mantis->demux.dmx, &mantis->fe_hw);
327 dvb_dmxdev_release(&mantis->dmxdev);
328 dvb_dmx_release(&mantis->demux);
329
330 if (mantis->fe)
331 dvb_unregister_frontend(mantis->fe);
332 dprintk(verbose, MANTIS_DEBUG, 1, "dvb_unregister_adapter");
333 dvb_unregister_adapter(&mantis->dvb_adapter);
334
335 return 0;
336}