[media] saa7164: New firmware changes, new size, new filename
[deliverable/linux.git] / drivers / media / video / saa7164 / saa7164-core.c
CommitLineData
443c1228
ST
1/*
2 * Driver for the NXP SAA7164 PCIe bridge
3 *
9b8b0199 4 * Copyright (c) 2010 Steven Toth <stoth@kernellabs.com>
443c1228
ST
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include <linux/init.h>
23#include <linux/list.h>
24#include <linux/module.h>
25#include <linux/moduleparam.h>
26#include <linux/kmod.h>
27#include <linux/kernel.h>
28#include <linux/slab.h>
29#include <linux/interrupt.h>
30#include <linux/delay.h>
31#include <asm/div64.h>
32
33#include "saa7164.h"
34
35MODULE_DESCRIPTION("Driver for NXP SAA7164 based TV cards");
9d119c33 36MODULE_AUTHOR("Steven Toth <stoth@kernellabs.com>");
443c1228
ST
37MODULE_LICENSE("GPL");
38
39/*
40 1 Basic
41 2
42 4 i2c
43 8 api
44 16 cmd
45 32 bus
46 */
47
b1912a85
IM
48unsigned int saa_debug;
49module_param_named(debug, saa_debug, int, 0644);
443c1228
ST
50MODULE_PARM_DESC(debug, "enable debug messages");
51
66e1d378
ST
52unsigned int encoder_buffers = SAA7164_MAX_ENCODER_BUFFERS;
53module_param(encoder_buffers, int, 0644);
54MODULE_PARM_DESC(encoder_buffers, "Total buffers in read queue 16-512 def:64");
55
bbf504c3 56unsigned int waitsecs = 10;
dd1ee444 57module_param(waitsecs, int, 0644);
66e1d378 58MODULE_PARM_DESC(waitsecs, "timeout on firmware messages");
dd1ee444 59
443c1228
ST
60static unsigned int card[] = {[0 ... (SAA7164_MAXBOARDS - 1)] = UNSET };
61module_param_array(card, int, NULL, 0444);
62MODULE_PARM_DESC(card, "card type");
63
91d80189
ST
64unsigned int print_histogram = 64;
65module_param(print_histogram, int, 0644);
66e1d378 66MODULE_PARM_DESC(print_histogram, "print histogram values once");
91d80189 67
1b0e8e46
ST
68unsigned int crc_checking = 1;
69module_param(crc_checking, int, 0644);
70MODULE_PARM_DESC(crc_checking, "enable crc sanity checking on buffers");
71
72unsigned int guard_checking = 1;
73module_param(guard_checking, int, 0644);
74MODULE_PARM_DESC(guard_checking, "enable dma sanity checking for buffer overruns");
75
443c1228
ST
76static unsigned int saa7164_devcount;
77
78static DEFINE_MUTEX(devlist);
79LIST_HEAD(saa7164_devlist);
80
81#define INT_SIZE 16
82
12d3203e
ST
83void saa7164_dumphex16FF(struct saa7164_dev *dev, u8 *buf, int len)
84{
85 int i;
86 u8 tmp[16];
87 memset(&tmp[0], 0xff, sizeof(tmp));
88
89 printk(KERN_INFO "--------------------> "
90 "00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n");
91
92 for (i = 0; i < len; i += 16) {
93 if (memcmp(&tmp, buf + i, sizeof(tmp)) != 0) {
94 printk(KERN_INFO " [0x%08x] "
95 "%02x %02x %02x %02x %02x %02x %02x %02x "
96 "%02x %02x %02x %02x %02x %02x %02x %02x\n", i,
97 *(buf+i+0), *(buf+i+1), *(buf+i+2), *(buf+i+3),
98 *(buf+i+4), *(buf+i+5), *(buf+i+6), *(buf+i+7),
99 *(buf+i+8), *(buf+i+9), *(buf+i+10), *(buf+i+11),
100 *(buf+i+12), *(buf+i+13), *(buf+i+14), *(buf+i+15));
101 }
102 }
103}
104
a97781ac
ST
105static void saa7164_pack_verifier(struct saa7164_buffer *buf)
106{
107 u8 *p = (u8 *)buf->cpu;
108 int i;
109
110 for (i = 0; i < buf->actual_size; i += 2048) {
111
1b0e8e46
ST
112 if ( (*(p + i + 0) != 0x00) || (*(p + i + 1) != 0x00) ||
113 (*(p + i + 2) != 0x01) || (*(p + i + 3) != 0xBA) ) {
a97781ac 114 printk(KERN_ERR "No pack at 0x%x\n", i);
1b0e8e46
ST
115// saa7164_dumphex16FF(buf->port->dev, (p + i), 32);
116 }
a97781ac
ST
117 }
118}
119
1b0e8e46
ST
120#define FIXED_VIDEO_PID 0xf1
121#define FIXED_AUDIO_PID 0xf2
122
9230acaa
ST
123static void saa7164_ts_verifier(struct saa7164_buffer *buf)
124{
125 struct saa7164_port *port = buf->port;
9230acaa 126 u32 i;
1b0e8e46
ST
127 u8 cc, a;
128 u16 pid;
129 u8 __iomem *bufcpu = (u8 *)buf->cpu;
9230acaa
ST
130
131 port->sync_errors = 0;
132 port->v_cc_errors = 0;
133 port->a_cc_errors = 0;
134
135 for (i = 0; i < buf->actual_size; i += 188) {
136 if (*(bufcpu + i) != 0x47)
137 port->sync_errors++;
138
1b0e8e46
ST
139 /* TODO: Query pid lower 8 bits, ignoring upper bits intensionally */
140 pid = ((*(bufcpu + i + 1) & 0x1f) << 8) | *(bufcpu + i + 2);
9230acaa
ST
141 cc = *(bufcpu + i + 3) & 0x0f;
142
1b0e8e46 143 if (pid == FIXED_VIDEO_PID) {
9230acaa
ST
144 a = ((port->last_v_cc + 1) & 0x0f);
145 if (a != cc) {
1b0e8e46
ST
146 printk(KERN_ERR "video cc last = %x current = %x i = %d\n",
147 port->last_v_cc, cc, i);
9230acaa
ST
148 port->v_cc_errors++;
149 }
150
151 port->last_v_cc = cc;
152 } else
1b0e8e46 153 if (pid == FIXED_AUDIO_PID) {
9230acaa
ST
154 a = ((port->last_a_cc + 1) & 0x0f);
155 if (a != cc) {
1b0e8e46
ST
156 printk(KERN_ERR "audio cc last = %x current = %x i = %d\n",
157 port->last_a_cc, cc, i);
9230acaa
ST
158 port->a_cc_errors++;
159 }
160
161 port->last_a_cc = cc;
162 }
163
164 }
165
166 if (port->v_cc_errors)
167 printk(KERN_ERR "video pid cc, %d errors\n", port->v_cc_errors);
168
169 if (port->a_cc_errors)
170 printk(KERN_ERR "audio pid cc, %d errors\n", port->a_cc_errors);
171
172 if (port->sync_errors)
173 printk(KERN_ERR "sync_errors = %d\n", port->sync_errors);
174}
175
91d80189 176static void saa7164_histogram_reset(struct saa7164_histogram *hg, char *name)
443c1228 177{
91d80189 178 int i;
443c1228 179
91d80189
ST
180 memset(hg, 0, sizeof(struct saa7164_histogram));
181 strcpy(hg->name, name);
182
183 /* First 30ms x 1ms */
184 for (i = 0; i < 30; i++) {
185 hg->counter1[0 + i].val = i;
186 }
187
188 /* 30 - 200ms x 10ms */
189 for (i = 0; i < 18; i++) {
190 hg->counter1[30 + i].val = 30 + (i * 10);
191 }
192
193 /* 200 - 2000ms x 100ms */
194 for (i = 0; i < 15; i++) {
58acca10 195 hg->counter1[48 + i].val = 200 + (i * 200);
91d80189
ST
196 }
197
58acca10
ST
198 /* Catch all massive value (2secs) */
199 hg->counter1[55].val = 2000;
200
201 /* Catch all massive value (4secs) */
202 hg->counter1[56].val = 4000;
203
204 /* Catch all massive value (8secs) */
205 hg->counter1[57].val = 8000;
206
207 /* Catch all massive value (15secs) */
208 hg->counter1[58].val = 15000;
209
210 /* Catch all massive value (30secs) */
211 hg->counter1[59].val = 30000;
212
213 /* Catch all massive value (60secs) */
214 hg->counter1[60].val = 60000;
215
216 /* Catch all massive value (5mins) */
217 hg->counter1[61].val = 300000;
218
219 /* Catch all massive value (15mins) */
220 hg->counter1[62].val = 900000;
221
222 /* Catch all massive values (1hr) */
91d80189 223 hg->counter1[63].val = 3600000;
443c1228
ST
224}
225
58acca10 226void saa7164_histogram_update(struct saa7164_histogram *hg, u32 val)
443c1228 227{
91d80189
ST
228 int i;
229 for (i = 0; i < 64; i++ ) {
230 if (val <= hg->counter1[i].val) {
231 hg->counter1[i].count++;
232 hg->counter1[i].update_time = jiffies;
233 break;
234 }
235 }
236}
443c1228 237
91d80189
ST
238static void saa7164_histogram_print(struct saa7164_port *port,
239 struct saa7164_histogram *hg)
240{
91d80189
ST
241 u32 entries = 0;
242 int i;
243
58acca10 244 printk(KERN_ERR "Histogram named %s (ms, count, last_update_jiffy)\n", hg->name);
91d80189
ST
245 for (i = 0; i < 64; i++ ) {
246 if (hg->counter1[i].count == 0)
247 continue;
443c1228 248
91d80189
ST
249 printk(KERN_ERR " %4d %12d %Ld\n",
250 hg->counter1[i].val,
251 hg->counter1[i].count,
252 hg->counter1[i].update_time);
253
254 entries++;
255 }
256 printk(KERN_ERR "Total: %d\n", entries);
443c1228
ST
257}
258
cfbaf337 259static void saa7164_work_enchandler_helper(struct saa7164_port *port, int bufnr)
7615e434
ST
260{
261 struct saa7164_dev *dev = port->dev;
cfbaf337
ST
262 struct saa7164_buffer *buf = 0;
263 struct saa7164_user_buffer *ubuf = 0;
7615e434 264 struct list_head *c, *n;
cfbaf337 265 int i = 0;
1b0e8e46 266 u8 __iomem *p;
91d80189
ST
267
268 mutex_lock(&port->dmaqueue_lock);
7615e434 269 list_for_each_safe(c, n, &port->dmaqueue.list) {
91d80189 270
7615e434 271 buf = list_entry(c, struct saa7164_buffer, list);
91d80189
ST
272 if (i++ > port->hwcfg.buffercount) {
273 printk(KERN_ERR "%s() illegal i count %d\n",
274 __func__, i);
275 break;
276 }
7615e434 277
cfbaf337 278 if (buf->idx == bufnr) {
12d3203e 279
7615e434 280 /* Found the buffer, deal with it */
1b0e8e46
ST
281 dprintk(DBGLVL_IRQ, "%s() bufnr: %d\n", __func__, bufnr);
282
283 if (crc_checking) {
284 /* Throw a new checksum on the dma buffer */
285 buf->crc = crc32(0, buf->cpu, buf->actual_size);
286 }
287
288 if (guard_checking) {
289 p = (u8 *)buf->cpu;
290 if ( (*(p + buf->actual_size + 0) != 0xff) ||
291 (*(p + buf->actual_size + 1) != 0xff) ||
292 (*(p + buf->actual_size + 2) != 0xff) ||
293 (*(p + buf->actual_size + 3) != 0xff) ||
294 (*(p + buf->actual_size + 0x10) != 0xff) ||
295 (*(p + buf->actual_size + 0x11) != 0xff) ||
296 (*(p + buf->actual_size + 0x12) != 0xff) ||
297 (*(p + buf->actual_size + 0x13) != 0xff) ) {
298 printk(KERN_ERR "%s() buf %p guard buffer breach\n",
299 __func__, buf);
300// saa7164_dumphex16FF(dev, (p + buf->actual_size) - 32 , 64);
301 }
302 }
7615e434 303
9230acaa
ST
304 /* Validate the incoming buffer content */
305 if (port->encoder_params.stream_type == V4L2_MPEG_STREAM_TYPE_MPEG2_TS)
306 saa7164_ts_verifier(buf);
1b0e8e46 307 else if (port->encoder_params.stream_type == V4L2_MPEG_STREAM_TYPE_MPEG2_PS)
a97781ac 308 saa7164_pack_verifier(buf);
9230acaa 309
7615e434
ST
310 /* find a free user buffer and clone to it */
311 if (!list_empty(&port->list_buf_free.list)) {
312
313 /* Pull the first buffer from the used list */
314 ubuf = list_first_entry(&port->list_buf_free.list,
315 struct saa7164_user_buffer, list);
316
a97781ac
ST
317 if (buf->actual_size <= ubuf->actual_size) {
318
cfbaf337 319 memcpy_fromio(ubuf->data, buf->cpu,
f6eeece8 320 ubuf->actual_size);
12d3203e 321
1b0e8e46
ST
322 if (crc_checking) {
323 /* Throw a new checksum on the read buffer */
324 ubuf->crc = crc32(0, ubuf->data, ubuf->actual_size);
325 }
12d3203e 326
a97781ac
ST
327 /* Requeue the buffer on the free list */
328 ubuf->pos = 0;
7615e434 329
a97781ac
ST
330 list_move_tail(&ubuf->list,
331 &port->list_buf_used.list);
7615e434 332
a97781ac
ST
333 /* Flag any userland waiters */
334 wake_up_interruptible(&port->wait_read);
7615e434 335
a97781ac
ST
336 } else {
337 printk(KERN_ERR "buf %p bufsize fails match\n", buf);
338 }
7615e434
ST
339
340 } else
66e1d378 341 printk(KERN_ERR "encirq no free buffers, increase param encoder_buffers\n");
7615e434 342
9230acaa 343 /* Ensure offset into buffer remains 0, fill buffer
a97781ac
ST
344 * with known bad data. We check for this data at a later point
345 * in time. */
cfbaf337 346 saa7164_buffer_zero_offsets(port, bufnr);
12d3203e 347 memset_io(buf->cpu, 0xff, buf->pci_size);
1b0e8e46
ST
348 if (crc_checking) {
349 /* Throw yet aanother new checksum on the dma buffer */
350 buf->crc = crc32(0, buf->cpu, buf->actual_size);
351 }
12d3203e 352
a97781ac 353 break;
cfbaf337
ST
354 }
355 }
356 mutex_unlock(&port->dmaqueue_lock);
357}
358
359static void saa7164_work_enchandler(struct work_struct *w)
360{
361 struct saa7164_port *port =
362 container_of(w, struct saa7164_port, workenc);
363 struct saa7164_dev *dev = port->dev;
364
365 u32 wp, mcb, rp, cnt = 0;
366
367 port->last_svc_msecs_diff = port->last_svc_msecs;
368 port->last_svc_msecs = jiffies_to_msecs(jiffies);
369
370 port->last_svc_msecs_diff = port->last_svc_msecs -
371 port->last_svc_msecs_diff;
372
373 saa7164_histogram_update(&port->svc_interval,
374 port->last_svc_msecs_diff);
375
376 port->last_irq_svc_msecs_diff = port->last_svc_msecs -
377 port->last_irq_msecs;
378
379 saa7164_histogram_update(&port->irq_svc_interval,
380 port->last_irq_svc_msecs_diff);
9230acaa 381
cfbaf337
ST
382 dprintk(DBGLVL_IRQ,
383 "%s() %Ldms elapsed irq->deferred %Ldms wp: %d rp: %d\n",
384 __func__,
385 port->last_svc_msecs_diff,
386 port->last_irq_svc_msecs_diff,
387 port->last_svc_wp,
388 port->last_svc_rp
389 );
390
391 /* Current write position */
392 wp = saa7164_readl(port->bufcounter);
393 if (wp > (port->hwcfg.buffercount - 1)) {
394 printk(KERN_ERR "%s() illegal buf count %d\n", __func__, wp);
395 return;
396 }
397
398 /* Most current complete buffer */
399 if (wp == 0)
1b0e8e46 400 mcb = (port->hwcfg.buffercount - 1);
cfbaf337
ST
401 else
402 mcb = wp - 1;
403
404 while (1) {
1b0e8e46
ST
405 if (port->done_first_interrupt == 0) {
406 port->done_first_interrupt++;
407 rp = mcb;
408 } else
409 rp = (port->last_svc_rp + 1) % 8;
cfbaf337 410
1b0e8e46 411 if ((rp < 0) || (rp > (port->hwcfg.buffercount - 1))) {
cfbaf337
ST
412 printk(KERN_ERR "%s() illegal rp count %d\n", __func__, rp);
413 break;
7615e434 414 }
1b0e8e46 415
cfbaf337
ST
416 saa7164_work_enchandler_helper(port, rp);
417 port->last_svc_rp = rp;
418 cnt++;
419
420 if (rp == mcb)
421 break;
7615e434 422 }
cfbaf337 423
1b0e8e46 424 /* TODO: Convert this into a /proc/saa7164 style readable file */
91d80189
ST
425 if (print_histogram == port->nr) {
426 saa7164_histogram_print(port, &port->irq_interval);
427 saa7164_histogram_print(port, &port->svc_interval);
428 saa7164_histogram_print(port, &port->irq_svc_interval);
58acca10
ST
429 saa7164_histogram_print(port, &port->read_interval);
430 saa7164_histogram_print(port, &port->poll_interval);
7c161822 431 /* TODO: fix this to preserve any previous state */
91d80189
ST
432 print_histogram = 64 + port->nr;
433 }
434}
cfbaf337 435
91d80189
ST
436static void saa7164_work_cmdhandler(struct work_struct *w)
437{
438 struct saa7164_dev *dev = container_of(w, struct saa7164_dev, workcmd);
439
440 /* Wake up any complete commands */
441 saa7164_irq_dequeue(dev);
442}
443
444static void saa7164_buffer_deliver(struct saa7164_buffer *buf)
445{
446 struct saa7164_port *port = buf->port;
447
448 /* Feed the transport payload into the kernel demux */
449 dvb_dmx_swfilter_packets(&port->dvb.demux, (u8 *)buf->cpu,
450 SAA7164_TS_NUMBER_OF_LINES);
451
452}
453
454static irqreturn_t saa7164_irq_encoder(struct saa7164_port *port)
455{
456 struct saa7164_dev *dev = port->dev;
07603131
ST
457
458 /* Store old time */
91d80189
ST
459 port->last_irq_msecs_diff = port->last_irq_msecs;
460
461 /* Collect new stats */
462 port->last_irq_msecs = jiffies_to_msecs(jiffies);
91d80189
ST
463
464 /* Calculate stats */
465 port->last_irq_msecs_diff = port->last_irq_msecs -
466 port->last_irq_msecs_diff;
467
468 saa7164_histogram_update(&port->irq_interval,
469 port->last_irq_msecs_diff);
470
cfbaf337
ST
471 dprintk(DBGLVL_IRQ, "%s() %Ldms elapsed\n", __func__,
472 port->last_irq_msecs_diff);
12d3203e 473
91d80189 474 schedule_work(&port->workenc);
7615e434
ST
475 return 0;
476}
477
add3f580 478static irqreturn_t saa7164_irq_ts(struct saa7164_port *port)
443c1228
ST
479{
480 struct saa7164_dev *dev = port->dev;
481 struct saa7164_buffer *buf;
482 struct list_head *c, *n;
483 int wp, i = 0, rp;
484
485 /* Find the current write point from the hardware */
486 wp = saa7164_readl(port->bufcounter);
487 if (wp > (port->hwcfg.buffercount - 1))
488 BUG();
489
490 /* Find the previous buffer to the current write point */
491 if (wp == 0)
1b0e8e46 492 rp = (port->hwcfg.buffercount - 1);
443c1228
ST
493 else
494 rp = wp - 1;
495
496 /* Lookup the WP in the buffer list */
497 /* TODO: turn this into a worker thread */
498 list_for_each_safe(c, n, &port->dmaqueue.list) {
499 buf = list_entry(c, struct saa7164_buffer, list);
500 if (i++ > port->hwcfg.buffercount)
501 BUG();
502
add3f580 503 if (buf->idx == rp) {
443c1228
ST
504 /* Found the buffer, deal with it */
505 dprintk(DBGLVL_IRQ, "%s() wp: %d processing: %d\n",
506 __func__, wp, rp);
507 saa7164_buffer_deliver(buf);
508 break;
509 }
510
511 }
512 return 0;
513}
514
515/* Primary IRQ handler and dispatch mechanism */
516static irqreturn_t saa7164_irq(int irq, void *dev_id)
517{
518 struct saa7164_dev *dev = dev_id;
7615e434
ST
519 struct saa7164_port *porta = &dev->ports[ SAA7164_PORT_TS1 ];
520 struct saa7164_port *portb = &dev->ports[ SAA7164_PORT_TS2 ];
521 struct saa7164_port *portc = &dev->ports[ SAA7164_PORT_ENC1 ];
522 struct saa7164_port *portd = &dev->ports[ SAA7164_PORT_ENC2 ];
523
50bcb4ae 524 u32 intid, intstat[INT_SIZE/4];
443c1228
ST
525 int i, handled = 0, bit;
526
d888ea03
ST
527 if (dev == 0) {
528 printk(KERN_ERR "%s() No device specified\n", __func__);
529 handled = 0;
530 goto out;
531 }
532
443c1228
ST
533 /* Check that the hardware is accessable. If the status bytes are
534 * 0xFF then the device is not accessable, the the IRQ belongs
535 * to another driver.
1a6450d4 536 * 4 x u32 interrupt registers.
443c1228
ST
537 */
538 for (i = 0; i < INT_SIZE/4; i++) {
539
540 /* TODO: Convert into saa7164_readl() */
541 /* Read the 4 hardware interrupt registers */
1a6450d4 542 intstat[i] = saa7164_readl(dev->int_status + (i * 4));
443c1228 543
50bcb4ae
ST
544 if (intstat[i])
545 handled = 1;
443c1228 546 }
50bcb4ae 547 if (handled == 0)
443c1228 548 goto out;
443c1228
ST
549
550 /* For each of the HW interrupt registers */
551 for (i = 0; i < INT_SIZE/4; i++) {
552
553 if (intstat[i]) {
554 /* Each function of the board has it's own interruptid.
555 * Find the function that triggered then call
556 * it's handler.
557 */
558 for (bit = 0; bit < 32; bit++) {
559
560 if (((intstat[i] >> bit) & 0x00000001) == 0)
561 continue;
562
563 /* Calculate the interrupt id (0x00 to 0x7f) */
564
50bcb4ae
ST
565 intid = (i * 32) + bit;
566 if (intid == dev->intfdesc.bInterruptId) {
443c1228
ST
567 /* A response to an cmd/api call */
568 schedule_work(&dev->workcmd);
7615e434 569 } else if (intid == porta->hwcfg.interruptid) {
443c1228
ST
570
571 /* Transport path 1 */
7615e434 572 saa7164_irq_ts(porta);
443c1228 573
7615e434 574 } else if (intid == portb->hwcfg.interruptid) {
443c1228
ST
575
576 /* Transport path 2 */
7615e434
ST
577 saa7164_irq_ts(portb);
578
579 } else if (intid == portc->hwcfg.interruptid) {
580
581 /* Encoder path 1 */
582 saa7164_irq_encoder(portc);
583
584 } else if (intid == portd->hwcfg.interruptid) {
585
586 /* Encoder path 1 */
587 saa7164_irq_encoder(portd);
443c1228
ST
588
589 } else {
590 /* Find the function */
591 dprintk(DBGLVL_IRQ,
592 "%s() unhandled interrupt "
593 "reg 0x%x bit 0x%x "
594 "intid = 0x%x\n",
50bcb4ae 595 __func__, i, bit, intid);
443c1228
ST
596 }
597 }
598
443c1228 599 /* Ack it */
1a6450d4 600 saa7164_writel(dev->int_ack + (i * 4), intstat[i]);
443c1228
ST
601
602 }
603 }
604out:
605 return IRQ_RETVAL(handled);
606}
607
608void saa7164_getfirmwarestatus(struct saa7164_dev *dev)
609{
610 struct saa7164_fw_status *s = &dev->fw_status;
611
612 dev->fw_status.status = saa7164_readl(SAA_DEVICE_SYSINIT_STATUS);
613 dev->fw_status.mode = saa7164_readl(SAA_DEVICE_SYSINIT_MODE);
614 dev->fw_status.spec = saa7164_readl(SAA_DEVICE_SYSINIT_SPEC);
615 dev->fw_status.inst = saa7164_readl(SAA_DEVICE_SYSINIT_INST);
616 dev->fw_status.cpuload = saa7164_readl(SAA_DEVICE_SYSINIT_CPULOAD);
617 dev->fw_status.remainheap =
618 saa7164_readl(SAA_DEVICE_SYSINIT_REMAINHEAP);
619
620 dprintk(1, "Firmware status:\n");
621 dprintk(1, " .status = 0x%08x\n", s->status);
622 dprintk(1, " .mode = 0x%08x\n", s->mode);
623 dprintk(1, " .spec = 0x%08x\n", s->spec);
624 dprintk(1, " .inst = 0x%08x\n", s->inst);
625 dprintk(1, " .cpuload = 0x%08x\n", s->cpuload);
626 dprintk(1, " .remainheap = 0x%08x\n", s->remainheap);
627}
628
629u32 saa7164_getcurrentfirmwareversion(struct saa7164_dev *dev)
630{
631 u32 reg;
632
633 reg = saa7164_readl(SAA_DEVICE_VERSION);
634 dprintk(1, "Device running firmware version %d.%d.%d.%d (0x%x)\n",
635 (reg & 0x0000fc00) >> 10,
636 (reg & 0x000003e0) >> 5,
637 (reg & 0x0000001f),
638 (reg & 0xffff0000) >> 16,
639 reg);
640
641 return reg;
642}
643
644/* TODO: Debugging func, remove */
645void saa7164_dumphex16(struct saa7164_dev *dev, u8 *buf, int len)
646{
647 int i;
648
649 printk(KERN_INFO "--------------------> "
650 "00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n");
651
652 for (i = 0; i < len; i += 16)
653 printk(KERN_INFO " [0x%08x] "
654 "%02x %02x %02x %02x %02x %02x %02x %02x "
655 "%02x %02x %02x %02x %02x %02x %02x %02x\n", i,
656 *(buf+i+0), *(buf+i+1), *(buf+i+2), *(buf+i+3),
657 *(buf+i+4), *(buf+i+5), *(buf+i+6), *(buf+i+7),
658 *(buf+i+8), *(buf+i+9), *(buf+i+10), *(buf+i+11),
659 *(buf+i+12), *(buf+i+13), *(buf+i+14), *(buf+i+15));
660}
661
662/* TODO: Debugging func, remove */
663void saa7164_dumpregs(struct saa7164_dev *dev, u32 addr)
664{
665 int i;
666
667 dprintk(1, "--------------------> "
668 "00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n");
669
670 for (i = 0; i < 0x100; i += 16)
671 dprintk(1, "region0[0x%08x] = "
672 "%02x %02x %02x %02x %02x %02x %02x %02x"
673 " %02x %02x %02x %02x %02x %02x %02x %02x\n", i,
674 (u8)saa7164_readb(addr + i + 0),
675 (u8)saa7164_readb(addr + i + 1),
676 (u8)saa7164_readb(addr + i + 2),
677 (u8)saa7164_readb(addr + i + 3),
678 (u8)saa7164_readb(addr + i + 4),
679 (u8)saa7164_readb(addr + i + 5),
680 (u8)saa7164_readb(addr + i + 6),
681 (u8)saa7164_readb(addr + i + 7),
682 (u8)saa7164_readb(addr + i + 8),
683 (u8)saa7164_readb(addr + i + 9),
684 (u8)saa7164_readb(addr + i + 10),
685 (u8)saa7164_readb(addr + i + 11),
686 (u8)saa7164_readb(addr + i + 12),
687 (u8)saa7164_readb(addr + i + 13),
688 (u8)saa7164_readb(addr + i + 14),
689 (u8)saa7164_readb(addr + i + 15)
690 );
691}
692
693static void saa7164_dump_hwdesc(struct saa7164_dev *dev)
694{
207b42c4
ST
695 dprintk(1, "@0x%p hwdesc sizeof(tmComResHWDescr_t) = %d bytes\n",
696 &dev->hwdesc, (u32)sizeof(tmComResHWDescr_t));
443c1228
ST
697
698 dprintk(1, " .bLength = 0x%x\n", dev->hwdesc.bLength);
699 dprintk(1, " .bDescriptorType = 0x%x\n", dev->hwdesc.bDescriptorType);
700 dprintk(1, " .bDescriptorSubtype = 0x%x\n",
701 dev->hwdesc.bDescriptorSubtype);
702
703 dprintk(1, " .bcdSpecVersion = 0x%x\n", dev->hwdesc.bcdSpecVersion);
704 dprintk(1, " .dwClockFrequency = 0x%x\n", dev->hwdesc.dwClockFrequency);
705 dprintk(1, " .dwClockUpdateRes = 0x%x\n", dev->hwdesc.dwClockUpdateRes);
706 dprintk(1, " .bCapabilities = 0x%x\n", dev->hwdesc.bCapabilities);
707 dprintk(1, " .dwDeviceRegistersLocation = 0x%x\n",
708 dev->hwdesc.dwDeviceRegistersLocation);
709
710 dprintk(1, " .dwHostMemoryRegion = 0x%x\n",
711 dev->hwdesc.dwHostMemoryRegion);
712
713 dprintk(1, " .dwHostMemoryRegionSize = 0x%x\n",
714 dev->hwdesc.dwHostMemoryRegionSize);
715
716 dprintk(1, " .dwHostHibernatMemRegion = 0x%x\n",
717 dev->hwdesc.dwHostHibernatMemRegion);
718
719 dprintk(1, " .dwHostHibernatMemRegionSize = 0x%x\n",
720 dev->hwdesc.dwHostHibernatMemRegionSize);
721}
722
723static void saa7164_dump_intfdesc(struct saa7164_dev *dev)
724{
725 dprintk(1, "@0x%p intfdesc "
207b42c4
ST
726 "sizeof(tmComResInterfaceDescr_t) = %d bytes\n",
727 &dev->intfdesc, (u32)sizeof(tmComResInterfaceDescr_t));
443c1228
ST
728
729 dprintk(1, " .bLength = 0x%x\n", dev->intfdesc.bLength);
730 dprintk(1, " .bDescriptorType = 0x%x\n", dev->intfdesc.bDescriptorType);
731 dprintk(1, " .bDescriptorSubtype = 0x%x\n",
732 dev->intfdesc.bDescriptorSubtype);
733
734 dprintk(1, " .bFlags = 0x%x\n", dev->intfdesc.bFlags);
735 dprintk(1, " .bInterfaceType = 0x%x\n", dev->intfdesc.bInterfaceType);
736 dprintk(1, " .bInterfaceId = 0x%x\n", dev->intfdesc.bInterfaceId);
737 dprintk(1, " .bBaseInterface = 0x%x\n", dev->intfdesc.bBaseInterface);
738 dprintk(1, " .bInterruptId = 0x%x\n", dev->intfdesc.bInterruptId);
739 dprintk(1, " .bDebugInterruptId = 0x%x\n",
740 dev->intfdesc.bDebugInterruptId);
741
742 dprintk(1, " .BARLocation = 0x%x\n", dev->intfdesc.BARLocation);
743}
744
745static void saa7164_dump_busdesc(struct saa7164_dev *dev)
746{
207b42c4
ST
747 dprintk(1, "@0x%p busdesc sizeof(tmComResBusDescr_t) = %d bytes\n",
748 &dev->busdesc, (u32)sizeof(tmComResBusDescr_t));
443c1228
ST
749
750 dprintk(1, " .CommandRing = 0x%016Lx\n", dev->busdesc.CommandRing);
751 dprintk(1, " .ResponseRing = 0x%016Lx\n", dev->busdesc.ResponseRing);
752 dprintk(1, " .CommandWrite = 0x%x\n", dev->busdesc.CommandWrite);
753 dprintk(1, " .CommandRead = 0x%x\n", dev->busdesc.CommandRead);
754 dprintk(1, " .ResponseWrite = 0x%x\n", dev->busdesc.ResponseWrite);
755 dprintk(1, " .ResponseRead = 0x%x\n", dev->busdesc.ResponseRead);
756}
757
758/* Much of the hardware configuration and PCI registers are configured
759 * dynamically depending on firmware. We have to cache some initial
760 * structures then use these to locate other important structures
761 * from PCI space.
762 */
763static void saa7164_get_descriptors(struct saa7164_dev *dev)
764{
12d3203e
ST
765 memcpy_fromio(&dev->hwdesc, dev->bmmio, sizeof(tmComResHWDescr_t));
766 memcpy_fromio(&dev->intfdesc, dev->bmmio + sizeof(tmComResHWDescr_t),
443c1228 767 sizeof(tmComResInterfaceDescr_t));
12d3203e 768 memcpy_fromio(&dev->busdesc, dev->bmmio + dev->intfdesc.BARLocation,
443c1228
ST
769 sizeof(tmComResBusDescr_t));
770
771 if (dev->hwdesc.bLength != sizeof(tmComResHWDescr_t)) {
772 printk(KERN_ERR "Structure tmComResHWDescr_t is mangled\n");
207b42c4
ST
773 printk(KERN_ERR "Need %x got %d\n", dev->hwdesc.bLength,
774 (u32)sizeof(tmComResHWDescr_t));
443c1228
ST
775 } else
776 saa7164_dump_hwdesc(dev);
777
778 if (dev->intfdesc.bLength != sizeof(tmComResInterfaceDescr_t)) {
779 printk(KERN_ERR "struct tmComResInterfaceDescr_t is mangled\n");
207b42c4
ST
780 printk(KERN_ERR "Need %x got %d\n", dev->intfdesc.bLength,
781 (u32)sizeof(tmComResInterfaceDescr_t));
443c1228
ST
782 } else
783 saa7164_dump_intfdesc(dev);
784
785 saa7164_dump_busdesc(dev);
786}
787
788static int saa7164_pci_quirks(struct saa7164_dev *dev)
789{
790 return 0;
791}
792
793static int get_resources(struct saa7164_dev *dev)
794{
795 if (request_mem_region(pci_resource_start(dev->pci, 0),
796 pci_resource_len(dev->pci, 0), dev->name)) {
797
798 if (request_mem_region(pci_resource_start(dev->pci, 2),
799 pci_resource_len(dev->pci, 2), dev->name))
800 return 0;
801 }
802
803 printk(KERN_ERR "%s: can't get MMIO memory @ 0x%llx or 0x%llx\n",
804 dev->name,
805 (u64)pci_resource_start(dev->pci, 0),
806 (u64)pci_resource_start(dev->pci, 2));
807
808 return -EBUSY;
809}
810
7615e434
ST
811static int saa7164_port_init(struct saa7164_dev *dev, int portnr)
812{
813 struct saa7164_port *port = 0;
814
815 if ((portnr < 0) || (portnr >= SAA7164_MAX_PORTS))
816 BUG();
817
818 port = &dev->ports[ portnr ];
819
820 port->dev = dev;
821 port->nr = portnr;
822
823 if ((portnr == SAA7164_PORT_TS1) || (portnr == SAA7164_PORT_TS2))
824 port->type = SAA7164_MPEG_DVB;
825 else
826 if ((portnr == SAA7164_PORT_ENC1) || (portnr == SAA7164_PORT_ENC2))
827 port->type = SAA7164_MPEG_ENCODER;
828 else
829 BUG();
830
831 /* Init all the critical resources */
832 mutex_init(&port->dvb.lock);
833 INIT_LIST_HEAD(&port->dmaqueue.list);
834 mutex_init(&port->dmaqueue_lock);
835
836 INIT_LIST_HEAD(&port->list_buf_used.list);
837 INIT_LIST_HEAD(&port->list_buf_free.list);
838 init_waitqueue_head(&port->wait_read);
91d80189
ST
839
840 /* We need a deferred interrupt handler for cmd handling */
841 INIT_WORK(&port->workenc, saa7164_work_enchandler);
842
843 saa7164_histogram_reset(&port->irq_interval, "irq intervals");
844 saa7164_histogram_reset(&port->svc_interval, "deferred intervals");
845 saa7164_histogram_reset(&port->irq_svc_interval,
846 "irq to deferred intervals");
58acca10
ST
847 saa7164_histogram_reset(&port->read_interval,
848 "encoder read() intervals");
849 saa7164_histogram_reset(&port->poll_interval,
850 "encoder poll() intervals");
91d80189 851
7615e434
ST
852 return 0;
853}
854
443c1228
ST
855static int saa7164_dev_setup(struct saa7164_dev *dev)
856{
857 int i;
858
859 mutex_init(&dev->lock);
860 atomic_inc(&dev->refcount);
861 dev->nr = saa7164_devcount++;
862
863 sprintf(dev->name, "saa7164[%d]", dev->nr);
864
865 mutex_lock(&devlist);
866 list_add_tail(&dev->devlist, &saa7164_devlist);
867 mutex_unlock(&devlist);
868
869 /* board config */
870 dev->board = UNSET;
871 if (card[dev->nr] < saa7164_bcount)
872 dev->board = card[dev->nr];
873
874 for (i = 0; UNSET == dev->board && i < saa7164_idcount; i++)
875 if (dev->pci->subsystem_vendor == saa7164_subids[i].subvendor &&
876 dev->pci->subsystem_device ==
877 saa7164_subids[i].subdevice)
878 dev->board = saa7164_subids[i].card;
879
880 if (UNSET == dev->board) {
881 dev->board = SAA7164_BOARD_UNKNOWN;
882 saa7164_card_list(dev);
883 }
884
885 dev->pci_bus = dev->pci->bus->number;
886 dev->pci_slot = PCI_SLOT(dev->pci->devfn);
887
888 /* I2C Defaults / setup */
889 dev->i2c_bus[0].dev = dev;
890 dev->i2c_bus[0].nr = 0;
891 dev->i2c_bus[1].dev = dev;
892 dev->i2c_bus[1].nr = 1;
893 dev->i2c_bus[2].dev = dev;
894 dev->i2c_bus[2].nr = 2;
895
7615e434
ST
896 /* Transport + Encoder ports 1, 2, 3, 4 - Defaults / setup */
897 saa7164_port_init(dev, SAA7164_PORT_TS1);
898 saa7164_port_init(dev, SAA7164_PORT_TS2);
899 saa7164_port_init(dev, SAA7164_PORT_ENC1);
900 saa7164_port_init(dev, SAA7164_PORT_ENC2);
443c1228
ST
901
902 if (get_resources(dev) < 0) {
903 printk(KERN_ERR "CORE %s No more PCIe resources for "
904 "subsystem: %04x:%04x\n",
905 dev->name, dev->pci->subsystem_vendor,
906 dev->pci->subsystem_device);
907
908 saa7164_devcount--;
909 return -ENODEV;
910 }
911
912 /* PCI/e allocations */
913 dev->lmmio = ioremap(pci_resource_start(dev->pci, 0),
914 pci_resource_len(dev->pci, 0));
915
916 dev->lmmio2 = ioremap(pci_resource_start(dev->pci, 2),
917 pci_resource_len(dev->pci, 2));
918
443c1228
ST
919 dev->bmmio = (u8 __iomem *)dev->lmmio;
920 dev->bmmio2 = (u8 __iomem *)dev->lmmio2;
443c1228 921
1a6450d4
ST
922 /* Inerrupt and ack register locations offset of bmmio */
923 dev->int_status = 0x183000 + 0xf80;
924 dev->int_ack = 0x183000 + 0xf90;
443c1228
ST
925
926 printk(KERN_INFO
927 "CORE %s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n",
928 dev->name, dev->pci->subsystem_vendor,
929 dev->pci->subsystem_device, saa7164_boards[dev->board].name,
930 dev->board, card[dev->nr] == dev->board ?
931 "insmod option" : "autodetected");
932
933 saa7164_pci_quirks(dev);
934
935 return 0;
936}
937
938static void saa7164_dev_unregister(struct saa7164_dev *dev)
939{
940 dprintk(1, "%s()\n", __func__);
941
942 release_mem_region(pci_resource_start(dev->pci, 0),
943 pci_resource_len(dev->pci, 0));
944
945 release_mem_region(pci_resource_start(dev->pci, 2),
946 pci_resource_len(dev->pci, 2));
947
948 if (!atomic_dec_and_test(&dev->refcount))
949 return;
950
951 iounmap(dev->lmmio);
952 iounmap(dev->lmmio2);
953
954 return;
955}
956
957static int __devinit saa7164_initdev(struct pci_dev *pci_dev,
958 const struct pci_device_id *pci_id)
959{
960 struct saa7164_dev *dev;
961 int err, i;
962 u32 version;
963
964 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
965 if (NULL == dev)
966 return -ENOMEM;
967
968 /* pci init */
969 dev->pci = pci_dev;
970 if (pci_enable_device(pci_dev)) {
971 err = -EIO;
972 goto fail_free;
973 }
974
975 if (saa7164_dev_setup(dev) < 0) {
976 err = -EINVAL;
977 goto fail_free;
978 }
979
980 /* print pci info */
981 pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev);
982 pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat);
983 printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, "
984 "latency: %d, mmio: 0x%llx\n", dev->name,
985 pci_name(pci_dev), dev->pci_rev, pci_dev->irq,
986 dev->pci_lat,
987 (unsigned long long)pci_resource_start(pci_dev, 0));
988
989 pci_set_master(pci_dev);
990 /* TODO */
991 if (!pci_dma_supported(pci_dev, 0xffffffff)) {
992 printk("%s/0: Oops: no 32bit PCI DMA ???\n", dev->name);
993 err = -EIO;
994 goto fail_irq;
995 }
996
997 err = request_irq(pci_dev->irq, saa7164_irq,
998 IRQF_SHARED | IRQF_DISABLED, dev->name, dev);
999 if (err < 0) {
1000 printk(KERN_ERR "%s: can't get IRQ %d\n", dev->name,
1001 pci_dev->irq);
1002 err = -EIO;
1003 goto fail_irq;
1004 }
1005
1006 pci_set_drvdata(pci_dev, dev);
1007
443c1228
ST
1008 /* Init the internal command list */
1009 for (i = 0; i < SAA_CMD_MAX_MSG_UNITS; i++) {
1010 dev->cmds[i].seqno = i;
1011 dev->cmds[i].inuse = 0;
1012 mutex_init(&dev->cmds[i].lock);
1013 init_waitqueue_head(&dev->cmds[i].wait);
1014 }
1015
1016 /* We need a deferred interrupt handler for cmd handling */
1017 INIT_WORK(&dev->workcmd, saa7164_work_cmdhandler);
1018
1019 /* Only load the firmware if we know the board */
1020 if (dev->board != SAA7164_BOARD_UNKNOWN) {
1021
1022 err = saa7164_downloadfirmware(dev);
1023 if (err < 0) {
1024 printk(KERN_ERR
50bcb4ae
ST
1025 "Failed to boot firmware, no features "
1026 "registered\n");
1027 goto fail_fw;
443c1228
ST
1028 }
1029
1030 saa7164_get_descriptors(dev);
1031 saa7164_dumpregs(dev, 0);
1032 saa7164_getcurrentfirmwareversion(dev);
1033 saa7164_getfirmwarestatus(dev);
1034 err = saa7164_bus_setup(dev);
1035 if (err < 0)
1036 printk(KERN_ERR
1037 "Failed to setup the bus, will continue\n");
1038 saa7164_bus_dump(dev);
1039
1040 /* Ping the running firmware via the command bus and get the
1041 * firmware version, this checks the bus is running OK.
1042 */
1043 version = 0;
1044 if (saa7164_api_get_fw_version(dev, &version) == SAA_OK)
1045 dprintk(1, "Bus is operating correctly using "
1046 "version %d.%d.%d.%d (0x%x)\n",
1047 (version & 0x0000fc00) >> 10,
1048 (version & 0x000003e0) >> 5,
1049 (version & 0x0000001f),
1050 (version & 0xffff0000) >> 16,
1051 version);
1052 else
1053 printk(KERN_ERR
1054 "Failed to communicate with the firmware\n");
1055
1056 /* Bring up the I2C buses */
1057 saa7164_i2c_register(&dev->i2c_bus[0]);
1058 saa7164_i2c_register(&dev->i2c_bus[1]);
1059 saa7164_i2c_register(&dev->i2c_bus[2]);
1060 saa7164_gpio_setup(dev);
1061 saa7164_card_setup(dev);
1062
1063
1064 /* Parse the dynamic device configuration, find various
1065 * media endpoints (MPEG, WMV, PS, TS) and cache their
1066 * configuration details into the driver, so we can
1067 * reference them later during simething_register() func,
1068 * interrupt handlers, deferred work handlers etc.
1069 */
1070 saa7164_api_enum_subdevs(dev);
1071
443c1228
ST
1072 /* Begin to create the video sub-systems and register funcs */
1073 if (saa7164_boards[dev->board].porta == SAA7164_MPEG_DVB) {
7615e434 1074 if (saa7164_dvb_register(&dev->ports[ SAA7164_PORT_TS1 ]) < 0) {
443c1228
ST
1075 printk(KERN_ERR "%s() Failed to register "
1076 "dvb adapters on porta\n",
1077 __func__);
1078 }
1079 }
1080
1081 if (saa7164_boards[dev->board].portb == SAA7164_MPEG_DVB) {
7615e434 1082 if (saa7164_dvb_register(&dev->ports[ SAA7164_PORT_TS2 ]) < 0) {
443c1228
ST
1083 printk(KERN_ERR"%s() Failed to register "
1084 "dvb adapters on portb\n",
1085 __func__);
1086 }
1087 }
1088
7615e434
ST
1089 if (saa7164_boards[dev->board].portc == SAA7164_MPEG_ENCODER) {
1090 if (saa7164_encoder_register(&dev->ports[ SAA7164_PORT_ENC1 ]) < 0) {
1091 printk(KERN_ERR"%s() Failed to register "
1092 "mpeg encoder\n", __func__);
1093 }
1094 }
1095
1096 if (saa7164_boards[dev->board].portd == SAA7164_MPEG_ENCODER) {
1097 if (saa7164_encoder_register(&dev->ports[ SAA7164_PORT_ENC2 ]) < 0) {
1098 printk(KERN_ERR"%s() Failed to register "
1099 "mpeg encoder\n", __func__);
1100 }
1101 }
1102
443c1228
ST
1103 } /* != BOARD_UNKNOWN */
1104 else
1105 printk(KERN_ERR "%s() Unsupported board detected, "
1106 "registering without firmware\n", __func__);
1107
b1912a85 1108 dprintk(1, "%s() parameter debug = %d\n", __func__, saa_debug);
2ceae8fd
ST
1109 dprintk(1, "%s() parameter waitsecs = %d\n", __func__, waitsecs);
1110
50bcb4ae 1111fail_fw:
443c1228
ST
1112 return 0;
1113
1114fail_irq:
1115 saa7164_dev_unregister(dev);
1116fail_free:
1117 kfree(dev);
1118 return err;
1119}
1120
1121static void saa7164_shutdown(struct saa7164_dev *dev)
1122{
1123 dprintk(1, "%s()\n", __func__);
1124}
1125
1126static void __devexit saa7164_finidev(struct pci_dev *pci_dev)
1127{
1128 struct saa7164_dev *dev = pci_get_drvdata(pci_dev);
1129
91d80189
ST
1130 saa7164_histogram_print(&dev->ports[ SAA7164_PORT_ENC1 ],
1131 &dev->ports[ SAA7164_PORT_ENC1 ].irq_interval);
1132 saa7164_histogram_print(&dev->ports[ SAA7164_PORT_ENC1 ],
1133 &dev->ports[ SAA7164_PORT_ENC1 ].svc_interval);
1134 saa7164_histogram_print(&dev->ports[ SAA7164_PORT_ENC1 ],
1135 &dev->ports[ SAA7164_PORT_ENC1 ].irq_svc_interval);
58acca10
ST
1136 saa7164_histogram_print(&dev->ports[ SAA7164_PORT_ENC1 ],
1137 &dev->ports[ SAA7164_PORT_ENC1 ].read_interval);
1138 saa7164_histogram_print(&dev->ports[ SAA7164_PORT_ENC1 ],
1139 &dev->ports[ SAA7164_PORT_ENC1 ].poll_interval);
91d80189 1140
443c1228
ST
1141 saa7164_shutdown(dev);
1142
1143 if (saa7164_boards[dev->board].porta == SAA7164_MPEG_DVB)
7615e434 1144 saa7164_dvb_unregister(&dev->ports[ SAA7164_PORT_TS1 ]);
443c1228
ST
1145
1146 if (saa7164_boards[dev->board].portb == SAA7164_MPEG_DVB)
7615e434
ST
1147 saa7164_dvb_unregister(&dev->ports[ SAA7164_PORT_TS2 ]);
1148
1149 if (saa7164_boards[dev->board].portc == SAA7164_MPEG_ENCODER)
1150 saa7164_encoder_unregister(&dev->ports[ SAA7164_PORT_ENC1 ]);
1151
1152 if (saa7164_boards[dev->board].portd == SAA7164_MPEG_ENCODER)
1153 saa7164_encoder_unregister(&dev->ports[ SAA7164_PORT_ENC2 ]);
443c1228
ST
1154
1155 saa7164_i2c_unregister(&dev->i2c_bus[0]);
1156 saa7164_i2c_unregister(&dev->i2c_bus[1]);
1157 saa7164_i2c_unregister(&dev->i2c_bus[2]);
1158
1159 pci_disable_device(pci_dev);
1160
1161 /* unregister stuff */
1162 free_irq(pci_dev->irq, dev);
1163 pci_set_drvdata(pci_dev, NULL);
1164
1165 mutex_lock(&devlist);
1166 list_del(&dev->devlist);
1167 mutex_unlock(&devlist);
1168
1169 saa7164_dev_unregister(dev);
1170 kfree(dev);
1171}
1172
1173static struct pci_device_id saa7164_pci_tbl[] = {
1174 {
1175 /* SAA7164 */
1176 .vendor = 0x1131,
1177 .device = 0x7164,
1178 .subvendor = PCI_ANY_ID,
1179 .subdevice = PCI_ANY_ID,
1180 }, {
1181 /* --- end of list --- */
1182 }
1183};
1184MODULE_DEVICE_TABLE(pci, saa7164_pci_tbl);
1185
1186static struct pci_driver saa7164_pci_driver = {
1187 .name = "saa7164",
1188 .id_table = saa7164_pci_tbl,
1189 .probe = saa7164_initdev,
1190 .remove = __devexit_p(saa7164_finidev),
1191 /* TODO */
1192 .suspend = NULL,
1193 .resume = NULL,
1194};
1195
9d440a08 1196static int __init saa7164_init(void)
443c1228
ST
1197{
1198 printk(KERN_INFO "saa7164 driver loaded\n");
1199 return pci_register_driver(&saa7164_pci_driver);
1200}
1201
9d440a08 1202static void __exit saa7164_fini(void)
443c1228
ST
1203{
1204 pci_unregister_driver(&saa7164_pci_driver);
1205}
1206
1207module_init(saa7164_init);
1208module_exit(saa7164_fini);
1209
This page took 0.179921 seconds and 5 git commands to generate.