Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/media/dvb/pluto2/pluto2.c
15111 views
1
/*
2
* pluto2.c - Satelco Easywatch Mobile Terrestrial Receiver [DVB-T]
3
*
4
* Copyright (C) 2005 Andreas Oberritter <[email protected]>
5
*
6
* based on pluto2.c 1.10 - http://instinct-wp8.no-ip.org/pluto/
7
* by Dany Salman <[email protected]>
8
* Copyright (c) 2004 TDF
9
*
10
* This program is free software; you can redistribute it and/or modify
11
* it under the terms of the GNU General Public License as published by
12
* the Free Software Foundation; either version 2 of the License, or
13
* (at your option) any later version.
14
*
15
* This program is distributed in the hope that it will be useful,
16
* but WITHOUT ANY WARRANTY; without even the implied warranty of
17
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
* GNU General Public License for more details.
19
*
20
* You should have received a copy of the GNU General Public License
21
* along with this program; if not, write to the Free Software
22
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23
*
24
*/
25
26
#include <linux/i2c.h>
27
#include <linux/i2c-algo-bit.h>
28
#include <linux/init.h>
29
#include <linux/kernel.h>
30
#include <linux/module.h>
31
#include <linux/pci.h>
32
#include <linux/dma-mapping.h>
33
#include <linux/slab.h>
34
35
#include "demux.h"
36
#include "dmxdev.h"
37
#include "dvb_demux.h"
38
#include "dvb_frontend.h"
39
#include "dvb_net.h"
40
#include "dvbdev.h"
41
#include "tda1004x.h"
42
43
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
44
45
#define DRIVER_NAME "pluto2"
46
47
#define REG_PIDn(n) ((n) << 2) /* PID n pattern registers */
48
#define REG_PCAR 0x0020 /* PC address register */
49
#define REG_TSCR 0x0024 /* TS ctrl & status */
50
#define REG_MISC 0x0028 /* miscellaneous */
51
#define REG_MMAC 0x002c /* MSB MAC address */
52
#define REG_IMAC 0x0030 /* ISB MAC address */
53
#define REG_LMAC 0x0034 /* LSB MAC address */
54
#define REG_SPID 0x0038 /* SPI data */
55
#define REG_SLCS 0x003c /* serial links ctrl/status */
56
57
#define PID0_NOFIL (0x0001 << 16)
58
#define PIDn_ENP (0x0001 << 15)
59
#define PID0_END (0x0001 << 14)
60
#define PID0_AFIL (0x0001 << 13)
61
#define PIDn_PID (0x1fff << 0)
62
63
#define TSCR_NBPACKETS (0x00ff << 24)
64
#define TSCR_DEM (0x0001 << 17)
65
#define TSCR_DE (0x0001 << 16)
66
#define TSCR_RSTN (0x0001 << 15)
67
#define TSCR_MSKO (0x0001 << 14)
68
#define TSCR_MSKA (0x0001 << 13)
69
#define TSCR_MSKL (0x0001 << 12)
70
#define TSCR_OVR (0x0001 << 11)
71
#define TSCR_AFUL (0x0001 << 10)
72
#define TSCR_LOCK (0x0001 << 9)
73
#define TSCR_IACK (0x0001 << 8)
74
#define TSCR_ADEF (0x007f << 0)
75
76
#define MISC_DVR (0x0fff << 4)
77
#define MISC_ALED (0x0001 << 3)
78
#define MISC_FRST (0x0001 << 2)
79
#define MISC_LED1 (0x0001 << 1)
80
#define MISC_LED0 (0x0001 << 0)
81
82
#define SPID_SPIDR (0x00ff << 0)
83
84
#define SLCS_SCL (0x0001 << 7)
85
#define SLCS_SDA (0x0001 << 6)
86
#define SLCS_CSN (0x0001 << 2)
87
#define SLCS_OVR (0x0001 << 1)
88
#define SLCS_SWC (0x0001 << 0)
89
90
#define TS_DMA_PACKETS (8)
91
#define TS_DMA_BYTES (188 * TS_DMA_PACKETS)
92
93
#define I2C_ADDR_TDA10046 0x10
94
#define I2C_ADDR_TUA6034 0xc2
95
#define NHWFILTERS 8
96
97
struct pluto {
98
/* pci */
99
struct pci_dev *pdev;
100
u8 __iomem *io_mem;
101
102
/* dvb */
103
struct dmx_frontend hw_frontend;
104
struct dmx_frontend mem_frontend;
105
struct dmxdev dmxdev;
106
struct dvb_adapter dvb_adapter;
107
struct dvb_demux demux;
108
struct dvb_frontend *fe;
109
struct dvb_net dvbnet;
110
unsigned int full_ts_users;
111
unsigned int users;
112
113
/* i2c */
114
struct i2c_algo_bit_data i2c_bit;
115
struct i2c_adapter i2c_adap;
116
unsigned int i2cbug;
117
118
/* irq */
119
unsigned int overflow;
120
unsigned int dead;
121
122
/* dma */
123
dma_addr_t dma_addr;
124
u8 dma_buf[TS_DMA_BYTES];
125
u8 dummy[4096];
126
};
127
128
static inline struct pluto *feed_to_pluto(struct dvb_demux_feed *feed)
129
{
130
return container_of(feed->demux, struct pluto, demux);
131
}
132
133
static inline struct pluto *frontend_to_pluto(struct dvb_frontend *fe)
134
{
135
return container_of(fe->dvb, struct pluto, dvb_adapter);
136
}
137
138
static inline u32 pluto_readreg(struct pluto *pluto, u32 reg)
139
{
140
return readl(&pluto->io_mem[reg]);
141
}
142
143
static inline void pluto_writereg(struct pluto *pluto, u32 reg, u32 val)
144
{
145
writel(val, &pluto->io_mem[reg]);
146
}
147
148
static inline void pluto_rw(struct pluto *pluto, u32 reg, u32 mask, u32 bits)
149
{
150
u32 val = readl(&pluto->io_mem[reg]);
151
val &= ~mask;
152
val |= bits;
153
writel(val, &pluto->io_mem[reg]);
154
}
155
156
static void pluto_write_tscr(struct pluto *pluto, u32 val)
157
{
158
/* set the number of packets */
159
val &= ~TSCR_ADEF;
160
val |= TS_DMA_PACKETS / 2;
161
162
pluto_writereg(pluto, REG_TSCR, val);
163
}
164
165
static void pluto_setsda(void *data, int state)
166
{
167
struct pluto *pluto = data;
168
169
if (state)
170
pluto_rw(pluto, REG_SLCS, SLCS_SDA, SLCS_SDA);
171
else
172
pluto_rw(pluto, REG_SLCS, SLCS_SDA, 0);
173
}
174
175
static void pluto_setscl(void *data, int state)
176
{
177
struct pluto *pluto = data;
178
179
if (state)
180
pluto_rw(pluto, REG_SLCS, SLCS_SCL, SLCS_SCL);
181
else
182
pluto_rw(pluto, REG_SLCS, SLCS_SCL, 0);
183
184
/* try to detect i2c_inb() to workaround hardware bug:
185
* reset SDA to high after SCL has been set to low */
186
if ((state) && (pluto->i2cbug == 0)) {
187
pluto->i2cbug = 1;
188
} else {
189
if ((!state) && (pluto->i2cbug == 1))
190
pluto_setsda(pluto, 1);
191
pluto->i2cbug = 0;
192
}
193
}
194
195
static int pluto_getsda(void *data)
196
{
197
struct pluto *pluto = data;
198
199
return pluto_readreg(pluto, REG_SLCS) & SLCS_SDA;
200
}
201
202
static int pluto_getscl(void *data)
203
{
204
struct pluto *pluto = data;
205
206
return pluto_readreg(pluto, REG_SLCS) & SLCS_SCL;
207
}
208
209
static void pluto_reset_frontend(struct pluto *pluto, int reenable)
210
{
211
u32 val = pluto_readreg(pluto, REG_MISC);
212
213
if (val & MISC_FRST) {
214
val &= ~MISC_FRST;
215
pluto_writereg(pluto, REG_MISC, val);
216
}
217
if (reenable) {
218
val |= MISC_FRST;
219
pluto_writereg(pluto, REG_MISC, val);
220
}
221
}
222
223
static void pluto_reset_ts(struct pluto *pluto, int reenable)
224
{
225
u32 val = pluto_readreg(pluto, REG_TSCR);
226
227
if (val & TSCR_RSTN) {
228
val &= ~TSCR_RSTN;
229
pluto_write_tscr(pluto, val);
230
}
231
if (reenable) {
232
val |= TSCR_RSTN;
233
pluto_write_tscr(pluto, val);
234
}
235
}
236
237
static void pluto_set_dma_addr(struct pluto *pluto)
238
{
239
pluto_writereg(pluto, REG_PCAR, pluto->dma_addr);
240
}
241
242
static int __devinit pluto_dma_map(struct pluto *pluto)
243
{
244
pluto->dma_addr = pci_map_single(pluto->pdev, pluto->dma_buf,
245
TS_DMA_BYTES, PCI_DMA_FROMDEVICE);
246
247
return pci_dma_mapping_error(pluto->pdev, pluto->dma_addr);
248
}
249
250
static void pluto_dma_unmap(struct pluto *pluto)
251
{
252
pci_unmap_single(pluto->pdev, pluto->dma_addr,
253
TS_DMA_BYTES, PCI_DMA_FROMDEVICE);
254
}
255
256
static int pluto_start_feed(struct dvb_demux_feed *f)
257
{
258
struct pluto *pluto = feed_to_pluto(f);
259
260
/* enable PID filtering */
261
if (pluto->users++ == 0)
262
pluto_rw(pluto, REG_PIDn(0), PID0_AFIL | PID0_NOFIL, 0);
263
264
if ((f->pid < 0x2000) && (f->index < NHWFILTERS))
265
pluto_rw(pluto, REG_PIDn(f->index), PIDn_ENP | PIDn_PID, PIDn_ENP | f->pid);
266
else if (pluto->full_ts_users++ == 0)
267
pluto_rw(pluto, REG_PIDn(0), PID0_NOFIL, PID0_NOFIL);
268
269
return 0;
270
}
271
272
static int pluto_stop_feed(struct dvb_demux_feed *f)
273
{
274
struct pluto *pluto = feed_to_pluto(f);
275
276
/* disable PID filtering */
277
if (--pluto->users == 0)
278
pluto_rw(pluto, REG_PIDn(0), PID0_AFIL, PID0_AFIL);
279
280
if ((f->pid < 0x2000) && (f->index < NHWFILTERS))
281
pluto_rw(pluto, REG_PIDn(f->index), PIDn_ENP | PIDn_PID, 0x1fff);
282
else if (--pluto->full_ts_users == 0)
283
pluto_rw(pluto, REG_PIDn(0), PID0_NOFIL, 0);
284
285
return 0;
286
}
287
288
static void pluto_dma_end(struct pluto *pluto, unsigned int nbpackets)
289
{
290
/* synchronize the DMA transfer with the CPU
291
* first so that we see updated contents. */
292
pci_dma_sync_single_for_cpu(pluto->pdev, pluto->dma_addr,
293
TS_DMA_BYTES, PCI_DMA_FROMDEVICE);
294
295
/* Workaround for broken hardware:
296
* [1] On startup NBPACKETS seems to contain an uninitialized value,
297
* but no packets have been transferred.
298
* [2] Sometimes (actually very often) NBPACKETS stays at zero
299
* although one packet has been transferred.
300
* [3] Sometimes (actually rarely), the card gets into an erroneous
301
* mode where it continuously generates interrupts, claiming it
302
* has received nbpackets>TS_DMA_PACKETS packets, but no packet
303
* has been transferred. Only a reset seems to solve this
304
*/
305
if ((nbpackets == 0) || (nbpackets > TS_DMA_PACKETS)) {
306
unsigned int i = 0;
307
while (pluto->dma_buf[i] == 0x47)
308
i += 188;
309
nbpackets = i / 188;
310
if (i == 0) {
311
pluto_reset_ts(pluto, 1);
312
dev_printk(KERN_DEBUG, &pluto->pdev->dev, "resetting TS because of invalid packet counter\n");
313
}
314
}
315
316
dvb_dmx_swfilter_packets(&pluto->demux, pluto->dma_buf, nbpackets);
317
318
/* clear the dma buffer. this is needed to be able to identify
319
* new valid ts packets above */
320
memset(pluto->dma_buf, 0, nbpackets * 188);
321
322
/* reset the dma address */
323
pluto_set_dma_addr(pluto);
324
325
/* sync the buffer and give it back to the card */
326
pci_dma_sync_single_for_device(pluto->pdev, pluto->dma_addr,
327
TS_DMA_BYTES, PCI_DMA_FROMDEVICE);
328
}
329
330
static irqreturn_t pluto_irq(int irq, void *dev_id)
331
{
332
struct pluto *pluto = dev_id;
333
u32 tscr;
334
335
/* check whether an interrupt occurred on this device */
336
tscr = pluto_readreg(pluto, REG_TSCR);
337
if (!(tscr & (TSCR_DE | TSCR_OVR)))
338
return IRQ_NONE;
339
340
if (tscr == 0xffffffff) {
341
if (pluto->dead == 0)
342
dev_err(&pluto->pdev->dev, "card has hung or been ejected.\n");
343
/* It's dead Jim */
344
pluto->dead = 1;
345
return IRQ_HANDLED;
346
}
347
348
/* dma end interrupt */
349
if (tscr & TSCR_DE) {
350
pluto_dma_end(pluto, (tscr & TSCR_NBPACKETS) >> 24);
351
/* overflow interrupt */
352
if (tscr & TSCR_OVR)
353
pluto->overflow++;
354
if (pluto->overflow) {
355
dev_err(&pluto->pdev->dev, "overflow irq (%d)\n",
356
pluto->overflow);
357
pluto_reset_ts(pluto, 1);
358
pluto->overflow = 0;
359
}
360
} else if (tscr & TSCR_OVR) {
361
pluto->overflow++;
362
}
363
364
/* ACK the interrupt */
365
pluto_write_tscr(pluto, tscr | TSCR_IACK);
366
367
return IRQ_HANDLED;
368
}
369
370
static void __devinit pluto_enable_irqs(struct pluto *pluto)
371
{
372
u32 val = pluto_readreg(pluto, REG_TSCR);
373
374
/* disable AFUL and LOCK interrupts */
375
val |= (TSCR_MSKA | TSCR_MSKL);
376
/* enable DMA and OVERFLOW interrupts */
377
val &= ~(TSCR_DEM | TSCR_MSKO);
378
/* clear pending interrupts */
379
val |= TSCR_IACK;
380
381
pluto_write_tscr(pluto, val);
382
}
383
384
static void pluto_disable_irqs(struct pluto *pluto)
385
{
386
u32 val = pluto_readreg(pluto, REG_TSCR);
387
388
/* disable all interrupts */
389
val |= (TSCR_DEM | TSCR_MSKO | TSCR_MSKA | TSCR_MSKL);
390
/* clear pending interrupts */
391
val |= TSCR_IACK;
392
393
pluto_write_tscr(pluto, val);
394
}
395
396
static int __devinit pluto_hw_init(struct pluto *pluto)
397
{
398
pluto_reset_frontend(pluto, 1);
399
400
/* set automatic LED control by FPGA */
401
pluto_rw(pluto, REG_MISC, MISC_ALED, MISC_ALED);
402
403
/* set data endianess */
404
#ifdef __LITTLE_ENDIAN
405
pluto_rw(pluto, REG_PIDn(0), PID0_END, PID0_END);
406
#else
407
pluto_rw(pluto, REG_PIDn(0), PID0_END, 0);
408
#endif
409
/* map DMA and set address */
410
pluto_dma_map(pluto);
411
pluto_set_dma_addr(pluto);
412
413
/* enable interrupts */
414
pluto_enable_irqs(pluto);
415
416
/* reset TS logic */
417
pluto_reset_ts(pluto, 1);
418
419
return 0;
420
}
421
422
static void pluto_hw_exit(struct pluto *pluto)
423
{
424
/* disable interrupts */
425
pluto_disable_irqs(pluto);
426
427
pluto_reset_ts(pluto, 0);
428
429
/* LED: disable automatic control, enable yellow, disable green */
430
pluto_rw(pluto, REG_MISC, MISC_ALED | MISC_LED1 | MISC_LED0, MISC_LED1);
431
432
/* unmap DMA */
433
pluto_dma_unmap(pluto);
434
435
pluto_reset_frontend(pluto, 0);
436
}
437
438
static inline u32 divide(u32 numerator, u32 denominator)
439
{
440
if (denominator == 0)
441
return ~0;
442
443
return DIV_ROUND_CLOSEST(numerator, denominator);
444
}
445
446
/* LG Innotek TDTE-E001P (Infineon TUA6034) */
447
static int lg_tdtpe001p_tuner_set_params(struct dvb_frontend *fe,
448
struct dvb_frontend_parameters *p)
449
{
450
struct pluto *pluto = frontend_to_pluto(fe);
451
struct i2c_msg msg;
452
int ret;
453
u8 buf[4];
454
u32 div;
455
456
// Fref = 166.667 Hz
457
// Fref * 3 = 500.000 Hz
458
// IF = 36166667
459
// IF / Fref = 217
460
//div = divide(p->frequency + 36166667, 166667);
461
div = divide(p->frequency * 3, 500000) + 217;
462
buf[0] = (div >> 8) & 0x7f;
463
buf[1] = (div >> 0) & 0xff;
464
465
if (p->frequency < 611000000)
466
buf[2] = 0xb4;
467
else if (p->frequency < 811000000)
468
buf[2] = 0xbc;
469
else
470
buf[2] = 0xf4;
471
472
// VHF: 174-230 MHz
473
// center: 350 MHz
474
// UHF: 470-862 MHz
475
if (p->frequency < 350000000)
476
buf[3] = 0x02;
477
else
478
buf[3] = 0x04;
479
480
if (p->u.ofdm.bandwidth == BANDWIDTH_8_MHZ)
481
buf[3] |= 0x08;
482
483
if (sizeof(buf) == 6) {
484
buf[4] = buf[2];
485
buf[4] &= ~0x1c;
486
buf[4] |= 0x18;
487
488
buf[5] = (0 << 7) | (2 << 4);
489
}
490
491
msg.addr = I2C_ADDR_TUA6034 >> 1;
492
msg.flags = 0;
493
msg.buf = buf;
494
msg.len = sizeof(buf);
495
496
if (fe->ops.i2c_gate_ctrl)
497
fe->ops.i2c_gate_ctrl(fe, 1);
498
ret = i2c_transfer(&pluto->i2c_adap, &msg, 1);
499
if (ret < 0)
500
return ret;
501
else if (ret == 0)
502
return -EREMOTEIO;
503
504
return 0;
505
}
506
507
static int pluto2_request_firmware(struct dvb_frontend *fe,
508
const struct firmware **fw, char *name)
509
{
510
struct pluto *pluto = frontend_to_pluto(fe);
511
512
return request_firmware(fw, name, &pluto->pdev->dev);
513
}
514
515
static struct tda1004x_config pluto2_fe_config __devinitdata = {
516
.demod_address = I2C_ADDR_TDA10046 >> 1,
517
.invert = 1,
518
.invert_oclk = 0,
519
.xtal_freq = TDA10046_XTAL_16M,
520
.agc_config = TDA10046_AGC_DEFAULT,
521
.if_freq = TDA10046_FREQ_3617,
522
.request_firmware = pluto2_request_firmware,
523
};
524
525
static int __devinit frontend_init(struct pluto *pluto)
526
{
527
int ret;
528
529
pluto->fe = tda10046_attach(&pluto2_fe_config, &pluto->i2c_adap);
530
if (!pluto->fe) {
531
dev_err(&pluto->pdev->dev, "could not attach frontend\n");
532
return -ENODEV;
533
}
534
pluto->fe->ops.tuner_ops.set_params = lg_tdtpe001p_tuner_set_params;
535
536
ret = dvb_register_frontend(&pluto->dvb_adapter, pluto->fe);
537
if (ret < 0) {
538
if (pluto->fe->ops.release)
539
pluto->fe->ops.release(pluto->fe);
540
return ret;
541
}
542
543
return 0;
544
}
545
546
static void __devinit pluto_read_rev(struct pluto *pluto)
547
{
548
u32 val = pluto_readreg(pluto, REG_MISC) & MISC_DVR;
549
dev_info(&pluto->pdev->dev, "board revision %d.%d\n",
550
(val >> 12) & 0x0f, (val >> 4) & 0xff);
551
}
552
553
static void __devinit pluto_read_mac(struct pluto *pluto, u8 *mac)
554
{
555
u32 val = pluto_readreg(pluto, REG_MMAC);
556
mac[0] = (val >> 8) & 0xff;
557
mac[1] = (val >> 0) & 0xff;
558
559
val = pluto_readreg(pluto, REG_IMAC);
560
mac[2] = (val >> 8) & 0xff;
561
mac[3] = (val >> 0) & 0xff;
562
563
val = pluto_readreg(pluto, REG_LMAC);
564
mac[4] = (val >> 8) & 0xff;
565
mac[5] = (val >> 0) & 0xff;
566
567
dev_info(&pluto->pdev->dev, "MAC %pM\n", mac);
568
}
569
570
static int __devinit pluto_read_serial(struct pluto *pluto)
571
{
572
struct pci_dev *pdev = pluto->pdev;
573
unsigned int i, j;
574
u8 __iomem *cis;
575
576
cis = pci_iomap(pdev, 1, 0);
577
if (!cis)
578
return -EIO;
579
580
dev_info(&pdev->dev, "S/N ");
581
582
for (i = 0xe0; i < 0x100; i += 4) {
583
u32 val = readl(&cis[i]);
584
for (j = 0; j < 32; j += 8) {
585
if ((val & 0xff) == 0xff)
586
goto out;
587
printk("%c", val & 0xff);
588
val >>= 8;
589
}
590
}
591
out:
592
printk("\n");
593
pci_iounmap(pdev, cis);
594
595
return 0;
596
}
597
598
static int __devinit pluto2_probe(struct pci_dev *pdev,
599
const struct pci_device_id *ent)
600
{
601
struct pluto *pluto;
602
struct dvb_adapter *dvb_adapter;
603
struct dvb_demux *dvbdemux;
604
struct dmx_demux *dmx;
605
int ret = -ENOMEM;
606
607
pluto = kzalloc(sizeof(struct pluto), GFP_KERNEL);
608
if (!pluto)
609
goto out;
610
611
pluto->pdev = pdev;
612
613
ret = pci_enable_device(pdev);
614
if (ret < 0)
615
goto err_kfree;
616
617
/* enable interrupts */
618
pci_write_config_dword(pdev, 0x6c, 0x8000);
619
620
ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
621
if (ret < 0)
622
goto err_pci_disable_device;
623
624
pci_set_master(pdev);
625
626
ret = pci_request_regions(pdev, DRIVER_NAME);
627
if (ret < 0)
628
goto err_pci_disable_device;
629
630
pluto->io_mem = pci_iomap(pdev, 0, 0x40);
631
if (!pluto->io_mem) {
632
ret = -EIO;
633
goto err_pci_release_regions;
634
}
635
636
pci_set_drvdata(pdev, pluto);
637
638
ret = request_irq(pdev->irq, pluto_irq, IRQF_SHARED, DRIVER_NAME, pluto);
639
if (ret < 0)
640
goto err_pci_iounmap;
641
642
ret = pluto_hw_init(pluto);
643
if (ret < 0)
644
goto err_free_irq;
645
646
/* i2c */
647
i2c_set_adapdata(&pluto->i2c_adap, pluto);
648
strcpy(pluto->i2c_adap.name, DRIVER_NAME);
649
pluto->i2c_adap.owner = THIS_MODULE;
650
pluto->i2c_adap.dev.parent = &pdev->dev;
651
pluto->i2c_adap.algo_data = &pluto->i2c_bit;
652
pluto->i2c_bit.data = pluto;
653
pluto->i2c_bit.setsda = pluto_setsda;
654
pluto->i2c_bit.setscl = pluto_setscl;
655
pluto->i2c_bit.getsda = pluto_getsda;
656
pluto->i2c_bit.getscl = pluto_getscl;
657
pluto->i2c_bit.udelay = 10;
658
pluto->i2c_bit.timeout = 10;
659
660
/* Raise SCL and SDA */
661
pluto_setsda(pluto, 1);
662
pluto_setscl(pluto, 1);
663
664
ret = i2c_bit_add_bus(&pluto->i2c_adap);
665
if (ret < 0)
666
goto err_pluto_hw_exit;
667
668
/* dvb */
669
ret = dvb_register_adapter(&pluto->dvb_adapter, DRIVER_NAME,
670
THIS_MODULE, &pdev->dev, adapter_nr);
671
if (ret < 0)
672
goto err_i2c_del_adapter;
673
674
dvb_adapter = &pluto->dvb_adapter;
675
676
pluto_read_rev(pluto);
677
pluto_read_serial(pluto);
678
pluto_read_mac(pluto, dvb_adapter->proposed_mac);
679
680
dvbdemux = &pluto->demux;
681
dvbdemux->filternum = 256;
682
dvbdemux->feednum = 256;
683
dvbdemux->start_feed = pluto_start_feed;
684
dvbdemux->stop_feed = pluto_stop_feed;
685
dvbdemux->dmx.capabilities = (DMX_TS_FILTERING |
686
DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING);
687
ret = dvb_dmx_init(dvbdemux);
688
if (ret < 0)
689
goto err_dvb_unregister_adapter;
690
691
dmx = &dvbdemux->dmx;
692
693
pluto->hw_frontend.source = DMX_FRONTEND_0;
694
pluto->mem_frontend.source = DMX_MEMORY_FE;
695
pluto->dmxdev.filternum = NHWFILTERS;
696
pluto->dmxdev.demux = dmx;
697
698
ret = dvb_dmxdev_init(&pluto->dmxdev, dvb_adapter);
699
if (ret < 0)
700
goto err_dvb_dmx_release;
701
702
ret = dmx->add_frontend(dmx, &pluto->hw_frontend);
703
if (ret < 0)
704
goto err_dvb_dmxdev_release;
705
706
ret = dmx->add_frontend(dmx, &pluto->mem_frontend);
707
if (ret < 0)
708
goto err_remove_hw_frontend;
709
710
ret = dmx->connect_frontend(dmx, &pluto->hw_frontend);
711
if (ret < 0)
712
goto err_remove_mem_frontend;
713
714
ret = frontend_init(pluto);
715
if (ret < 0)
716
goto err_disconnect_frontend;
717
718
dvb_net_init(dvb_adapter, &pluto->dvbnet, dmx);
719
out:
720
return ret;
721
722
err_disconnect_frontend:
723
dmx->disconnect_frontend(dmx);
724
err_remove_mem_frontend:
725
dmx->remove_frontend(dmx, &pluto->mem_frontend);
726
err_remove_hw_frontend:
727
dmx->remove_frontend(dmx, &pluto->hw_frontend);
728
err_dvb_dmxdev_release:
729
dvb_dmxdev_release(&pluto->dmxdev);
730
err_dvb_dmx_release:
731
dvb_dmx_release(dvbdemux);
732
err_dvb_unregister_adapter:
733
dvb_unregister_adapter(dvb_adapter);
734
err_i2c_del_adapter:
735
i2c_del_adapter(&pluto->i2c_adap);
736
err_pluto_hw_exit:
737
pluto_hw_exit(pluto);
738
err_free_irq:
739
free_irq(pdev->irq, pluto);
740
err_pci_iounmap:
741
pci_iounmap(pdev, pluto->io_mem);
742
err_pci_release_regions:
743
pci_release_regions(pdev);
744
err_pci_disable_device:
745
pci_disable_device(pdev);
746
err_kfree:
747
pci_set_drvdata(pdev, NULL);
748
kfree(pluto);
749
goto out;
750
}
751
752
static void __devexit pluto2_remove(struct pci_dev *pdev)
753
{
754
struct pluto *pluto = pci_get_drvdata(pdev);
755
struct dvb_adapter *dvb_adapter = &pluto->dvb_adapter;
756
struct dvb_demux *dvbdemux = &pluto->demux;
757
struct dmx_demux *dmx = &dvbdemux->dmx;
758
759
dmx->close(dmx);
760
dvb_net_release(&pluto->dvbnet);
761
if (pluto->fe)
762
dvb_unregister_frontend(pluto->fe);
763
764
dmx->disconnect_frontend(dmx);
765
dmx->remove_frontend(dmx, &pluto->mem_frontend);
766
dmx->remove_frontend(dmx, &pluto->hw_frontend);
767
dvb_dmxdev_release(&pluto->dmxdev);
768
dvb_dmx_release(dvbdemux);
769
dvb_unregister_adapter(dvb_adapter);
770
i2c_del_adapter(&pluto->i2c_adap);
771
pluto_hw_exit(pluto);
772
free_irq(pdev->irq, pluto);
773
pci_iounmap(pdev, pluto->io_mem);
774
pci_release_regions(pdev);
775
pci_disable_device(pdev);
776
pci_set_drvdata(pdev, NULL);
777
kfree(pluto);
778
}
779
780
#ifndef PCI_VENDOR_ID_SCM
781
#define PCI_VENDOR_ID_SCM 0x0432
782
#endif
783
#ifndef PCI_DEVICE_ID_PLUTO2
784
#define PCI_DEVICE_ID_PLUTO2 0x0001
785
#endif
786
787
static struct pci_device_id pluto2_id_table[] __devinitdata = {
788
{
789
.vendor = PCI_VENDOR_ID_SCM,
790
.device = PCI_DEVICE_ID_PLUTO2,
791
.subvendor = PCI_ANY_ID,
792
.subdevice = PCI_ANY_ID,
793
}, {
794
/* empty */
795
},
796
};
797
798
MODULE_DEVICE_TABLE(pci, pluto2_id_table);
799
800
static struct pci_driver pluto2_driver = {
801
.name = DRIVER_NAME,
802
.id_table = pluto2_id_table,
803
.probe = pluto2_probe,
804
.remove = __devexit_p(pluto2_remove),
805
};
806
807
static int __init pluto2_init(void)
808
{
809
return pci_register_driver(&pluto2_driver);
810
}
811
812
static void __exit pluto2_exit(void)
813
{
814
pci_unregister_driver(&pluto2_driver);
815
}
816
817
module_init(pluto2_init);
818
module_exit(pluto2_exit);
819
820
MODULE_AUTHOR("Andreas Oberritter <[email protected]>");
821
MODULE_DESCRIPTION("Pluto2 driver");
822
MODULE_LICENSE("GPL");
823
824