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