Subversion Repositories shark

Rev

Rev 773 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
425 giacomo 1
/*
2
    saa7146.o - driver for generic saa7146-based hardware
3
 
4
    Copyright (C) 1998-2003 Michael Hunold <michael@mihu.de>
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
    GNU General Public License for more details.
15
 
16
    You should have received a copy of the GNU General Public License
17
    along with this program; if not, write to the Free Software
18
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19
*/
20
 
773 giacomo 21
#include <linuxcomp.h>
22
 
425 giacomo 23
#include <media/saa7146.h>
24
 
25
/* global variables */
26
struct list_head saa7146_devices;
27
struct semaphore saa7146_devices_lock;
28
 
29
static int initialized = 0;
30
int saa7146_num = 0;
31
 
773 giacomo 32
unsigned int saa7146_debug = 9;
425 giacomo 33
 
34
MODULE_PARM(saa7146_debug,"i");
35
MODULE_PARM_DESC(saa7146_debug, "debug level (default: 0)");
36
 
37
#if 0
38
static void dump_registers(struct saa7146_dev* dev)
39
{
40
        int i = 0;
41
 
42
        INFO((" @ %li jiffies:\n",jiffies));
43
        for(i = 0; i <= 0x148; i+=4) {
44
                printk("0x%03x: 0x%08x\n",i,saa7146_read(dev,i));
45
        }
46
}
47
#endif
48
 
49
/****************************************************************************
50
 * gpio and debi helper functions
51
 ****************************************************************************/
52
 
53
/* write "data" to the gpio-pin "pin" */
54
void saa7146_set_gpio(struct saa7146_dev *dev, u8 pin, u8 data)
55
{
56
        u32 value = 0;
57
 
58
        /* sanity check */
59
        if(pin > 3)
60
                return;
61
 
62
        /* read old register contents */
63
        value = saa7146_read(dev, GPIO_CTRL );
64
 
65
        value &= ~(0xff << (8*pin));
66
        value |= (data << (8*pin));
67
 
68
        saa7146_write(dev, GPIO_CTRL, value);
69
}
70
 
71
/* This DEBI code is based on the saa7146 Stradis driver by Nathan Laredo */
72
int saa7146_wait_for_debi_done(struct saa7146_dev *dev)
73
{
74
        int start;
75
 
76
        /* wait for registers to be programmed */
774 giacomo 77
        start = jiffies26;
425 giacomo 78
        while (1) {
79
                if (saa7146_read(dev, MC2) & 2)
80
                        break;
774 giacomo 81
                if (jiffies26-start > HZ/20) {
425 giacomo 82
                        DEB_S(("timed out while waiting for registers getting programmed\n"));
83
                        return -ETIMEDOUT;
84
                }
85
        }
86
 
87
        /* wait for transfer to complete */
774 giacomo 88
        start = jiffies26;
425 giacomo 89
        while (1) {
90
                if (!(saa7146_read(dev, PSR) & SPCI_DEBI_S))
91
                        break;
92
                saa7146_read(dev, MC2);
774 giacomo 93
                if (jiffies26-start > HZ/4) {
425 giacomo 94
                        DEB_S(("timed out while waiting for transfer completion\n"));
95
                        return -ETIMEDOUT;
96
                }
97
        }
98
 
99
        return 0;
100
}
101
 
102
/****************************************************************************
103
 * general helper functions
104
 ****************************************************************************/
105
 
106
/* this is videobuf_vmalloc_to_sg() from video-buf.c
107
   make sure virt has been allocated with vmalloc_32(), otherwise the BUG()
108
   may be triggered on highmem machines */
109
static struct scatterlist* vmalloc_to_sg(unsigned char *virt, int nr_pages)
110
{
111
        struct scatterlist *sglist;
112
        struct page *pg;
113
        int i;
114
 
115
        sglist = kmalloc(sizeof(struct scatterlist)*nr_pages, GFP_KERNEL);
116
        if (NULL == sglist)
117
                return NULL;
118
        memset(sglist,0,sizeof(struct scatterlist)*nr_pages);
774 giacomo 119
/*      for (i = 0; i < nr_pages; i++, virt += PAGE_SIZE) {
425 giacomo 120
                pg = vmalloc_to_page(virt);
121
                if (NULL == pg)
122
                        goto err;
123
                if (PageHighMem(pg))
124
                        BUG();
125
                sglist[i].page   = pg;
126
                sglist[i].length = PAGE_SIZE;
774 giacomo 127
        }*/
425 giacomo 128
        return sglist;
129
 
130
 err:
131
        kfree(sglist);
132
        return NULL;
133
}
134
 
135
/********************************************************************************/
136
/* common page table functions */
137
 
138
#define SAA7146_PGTABLE_SIZE 4096
139
 
140
char *saa7146_vmalloc_build_pgtable(struct pci_dev *pci, long length, struct saa7146_pgtable *pt)
141
{
142
        int pages = (length+PAGE_SIZE-1)/PAGE_SIZE;
143
        char *mem = vmalloc_32(length);
144
        int slen = 0;
145
 
146
        if (NULL == mem) {
147
                return NULL;
148
        }
149
 
150
        if (!(pt->slist = vmalloc_to_sg(mem, pages))) {
151
                vfree(mem);
152
                return NULL;
153
        }
154
 
155
        if (saa7146_pgtable_alloc(pci, pt)) {
156
                kfree(pt->slist);
157
                pt->slist = NULL;
158
                vfree(mem);
159
                return NULL;
160
        }
161
 
774 giacomo 162
        //slen = pci_map_sg(pci,pt->slist,pages,PCI_DMA_FROMDEVICE);
425 giacomo 163
        if (0 != saa7146_pgtable_build_single(pci, pt, pt->slist, slen)) {
164
                return NULL;
165
        }
166
 
167
        return mem;
168
}
169
 
170
void saa7146_pgtable_free(struct pci_dev *pci, struct saa7146_pgtable *pt)
171
{
172
        if (NULL == pt->cpu)
173
                return;
174
        pci_free_consistent(pci, pt->size, pt->cpu, pt->dma);
175
        pt->cpu = NULL;
176
        if (NULL != pt->slist) {
177
                kfree(pt->slist);
178
                pt->slist = NULL;
179
        }
180
}
181
 
182
int saa7146_pgtable_alloc(struct pci_dev *pci, struct saa7146_pgtable *pt)
183
{
184
        u32          *cpu;
185
        dma_addr_t   dma_addr;
186
 
187
        cpu = pci_alloc_consistent(pci, SAA7146_PGTABLE_SIZE, &dma_addr);
188
        if (NULL == cpu) {
189
                return -ENOMEM;
190
        }
191
        pt->size = SAA7146_PGTABLE_SIZE;
192
        pt->cpu  = cpu;
193
        pt->dma  = dma_addr;
194
 
195
        return 0;
196
}
197
 
198
int saa7146_pgtable_build_single(struct pci_dev *pci, struct saa7146_pgtable *pt,
199
        struct scatterlist *list, int sglen  )
200
{
201
        u32 *ptr, fill;
202
        int nr_pages = 0;
203
        int i,p;
204
 
205
        BUG_ON( 0 == sglen);
206
 
207
        if (list->offset > PAGE_SIZE) {
208
                DEB_D(("offset > PAGE_SIZE. this should not happen."));
209
                return -EINVAL;
210
        }
211
 
212
        /* if we have a user buffer, the first page may not be
213
           aligned to a page boundary. */
214
        pt->offset = list->offset;
215
 
216
        ptr = pt->cpu;
217
        for (i = 0; i < sglen; i++, list++) {
218
/*
219
                printk("i:%d, adr:0x%08x, len:%d, offset:%d\n", i,sg_dma_address(list), sg_dma_len(list), list->offset);
220
*/
221
                for (p = 0; p * 4096 < list->length; p++, ptr++) {
222
                        *ptr = sg_dma_address(list) + p * 4096;
223
                        nr_pages++;
224
                }
225
        }
226
 
227
 
228
        /* safety; fill the page table up with the last valid page */
229
        fill = *(ptr-1);
230
        for(i=nr_pages;i<1024;i++) {
231
                *ptr++ = fill;
232
        }
233
 
234
/*
235
        ptr = pt->cpu;
236
        printk("offset: %d\n",pt->offset);
237
        for(i=0;i<5;i++) {
238
                printk("ptr1 %d: 0x%08x\n",i,ptr[i]);
239
        }
240
*/
241
        return 0;
242
}
243
 
244
/********************************************************************************/
245
/* gpio functions */
246
 
247
void saa7146_setgpio(struct saa7146_dev *dev, int port, u32 data)
248
{
249
        u32 val = 0;
250
 
251
        val=saa7146_read(dev,GPIO_CTRL);
252
        val&=~(0xff << (8*(port)));
253
        val|=(data)<<(8*(port));
254
        saa7146_write(dev, GPIO_CTRL, val);
255
}
256
 
257
/********************************************************************************/
258
/* interrupt handler */
259
static irqreturn_t interrupt_hw(int irq, void *dev_id, struct pt_regs *regs)
260
{
261
        struct saa7146_dev *dev = (struct saa7146_dev*)dev_id;
262
        u32 isr = 0;
263
 
264
        /* read out the interrupt status register */
265
        isr = saa7146_read(dev, ISR);
266
 
267
        /* is this our interrupt? */
268
        if ( 0 == isr ) {
269
                /* nope, some other device */
270
                return IRQ_NONE;
271
        }
272
 
273
        saa7146_write(dev, ISR, isr);
274
 
275
        if( 0 != (dev->ext)) {
276
                if( 0 != (dev->ext->irq_mask & isr )) {
277
                        if( 0 != dev->ext->irq_func ) {
278
                                dev->ext->irq_func(dev, &isr);
279
                        }
280
                        isr &= ~dev->ext->irq_mask;
281
                }
282
        }
283
        if (0 != (isr & (MASK_27))) {
284
                DEB_INT(("irq: RPS0 (0x%08x).\n",isr));
285
                if( 0 != dev->vv_data && 0 != dev->vv_callback) {
286
                        dev->vv_callback(dev,isr);
287
                }
288
                isr &= ~MASK_27;
289
        }
290
        if (0 != (isr & (MASK_28))) {
291
                if( 0 != dev->vv_data && 0 != dev->vv_callback) {
292
                        dev->vv_callback(dev,isr);
293
                }
294
                isr &= ~MASK_28;
295
        }
296
        if (0 != (isr & (MASK_16|MASK_17))) {
297
                u32 status = saa7146_read(dev, I2C_STATUS);
298
                if( (0x3 == (status & 0x3)) || (0 == (status & 0x1)) ) {
299
                        IER_DISABLE(dev, MASK_16|MASK_17);
300
                        /* only wake up if we expect something */
301
                        if( 0 != dev->i2c_op ) {
302
                                u32 psr = (saa7146_read(dev, PSR) >> 16) & 0x2;
303
                                u32 ssr = (saa7146_read(dev, SSR) >> 17) & 0x1f;
304
                                DEB_I2C(("irq: i2c, status: 0x%08x, psr:0x%02x, ssr:0x%02x).\n",status,psr,ssr));
305
                                dev->i2c_op = 0;
773 giacomo 306
                                //wake_up(&dev->i2c_wq);
425 giacomo 307
                        } else {
308
                                DEB_I2C(("unexpected irq: i2c, status: 0x%08x, isr %#x\n",status, isr));
309
                        }
310
                } else {
311
                        DEB_I2C(("unhandled irq: i2c, status: 0x%08x, isr %#x\n",status, isr));
312
                }
313
                isr &= ~(MASK_16|MASK_17);
314
        }
315
        if( 0 != isr ) {
316
                ERR(("warning: interrupt enabled, but not handled properly.(0x%08x)\n",isr));
317
                ERR(("disabling interrupt source(s)!\n"));
318
                IER_DISABLE(dev,isr);
319
        }
320
        return IRQ_HANDLED;
321
}
322
 
323
/*********************************************************************************/
324
/* configuration-functions                                                       */
325
 
326
static int saa7146_init_one(struct pci_dev *pci, const struct pci_device_id *ent)
327
{
328
        unsigned long adr = 0, len = 0;
329
        struct saa7146_dev* dev = kmalloc (sizeof(struct saa7146_dev),GFP_KERNEL);
330
 
331
        struct saa7146_pci_extension_data *pci_ext = (struct saa7146_pci_extension_data *)ent->driver_data;
332
        struct saa7146_extension* ext = pci_ext->ext;
333
        int err = 0;
334
 
335
        if (!(dev = kmalloc (sizeof(struct saa7146_dev),GFP_KERNEL))) {
336
                ERR(("out of memory.\n"));
337
                return -ENOMEM;
338
        }
339
 
340
        /* clear out mem for sure */
341
        memset(dev, 0x0, sizeof(struct saa7146_dev));
342
 
343
        DEB_EE(("pci:%p\n",pci));
344
 
345
        if (pci_enable_device(pci)) {
346
                ERR(("pci_enable_device() failed.\n"));
347
                err = -EIO;
348
                goto pci_error;
349
        }
350
 
351
        /* enable bus-mastering */
352
        pci_set_master(pci);
353
 
354
        dev->pci = pci;
355
        /* get chip-revision; this is needed to enable bug-fixes */
356
        if( 0 > pci_read_config_dword(dev->pci, PCI_CLASS_REVISION, &dev->revision)) {
357
                ERR(("pci_read_config_dword() failed.\n"));
358
                err = -ENODEV;
359
                goto pci_error;
360
        }
361
        dev->revision &= 0xf;
362
 
363
        /* remap the memory from virtual to physical adress */
364
        adr = pci_resource_start(pci,0);
365
        len = pci_resource_len(pci,0);
366
 
367
        if (!request_mem_region(pci_resource_start(pci,0), pci_resource_len(pci,0), "saa7146")) {
368
                ERR(("request_mem_region() failed.\n"));
369
                err = -ENODEV;
370
                goto pci_error;
371
        }
372
 
373
        if (!(dev->mem = ioremap(adr,len))) {
374
                ERR(("ioremap() failed.\n"));
375
                err = -ENODEV;
376
                goto ioremap_error;
377
        }
378
 
379
        /* we don't do a master reset here anymore, it screws up
380
           some boards that don't have an i2c-eeprom for configuration
381
           values */
382
/*
383
        saa7146_write(dev, MC1, MASK_31);
384
*/
385
 
386
        /* disable all irqs */
387
        saa7146_write(dev, IER, 0);
388
 
389
        /* shut down all dma transfers */
390
        saa7146_write(dev, MC1, 0x00ff0000);
391
 
392
        /* clear out any rps-signals pending */
393
        saa7146_write(dev, MC2, 0xf8000000);
394
 
395
        /* request an interrupt for the saa7146 */
396
        if (request_irq(dev->pci->irq, interrupt_hw, SA_SHIRQ | SA_INTERRUPT,
397
                        dev->name, dev))
398
        {
399
                ERR(("request_irq() failed.\n"));
400
                err = -ENODEV;
401
                goto irq_error;
402
        }
403
 
404
        /* get memory for various stuff */
405
        dev->d_rps0.cpu_addr = pci_alloc_consistent(dev->pci, SAA7146_RPS_MEM, &dev->d_rps0.dma_handle);       
406
        if( NULL == dev->d_rps0.cpu_addr ) {
407
                err = -ENOMEM;
408
                goto kmalloc_error_1;
409
        }      
410
        memset(dev->d_rps0.cpu_addr, 0x0, SAA7146_RPS_MEM);
411
 
412
        dev->d_rps1.cpu_addr = pci_alloc_consistent(dev->pci, SAA7146_RPS_MEM, &dev->d_rps1.dma_handle);       
413
        if( NULL == dev->d_rps1.cpu_addr ) {
414
                err = -ENOMEM;
415
                goto kmalloc_error_2;
416
        }      
417
        memset(dev->d_rps1.cpu_addr, 0x0, SAA7146_RPS_MEM);
418
 
419
        dev->d_i2c.cpu_addr = pci_alloc_consistent(dev->pci, SAA7146_RPS_MEM, &dev->d_i2c.dma_handle); 
420
        if( NULL == dev->d_i2c.cpu_addr ) {
421
                err = -ENOMEM;
422
                goto kmalloc_error_3;
423
        }      
424
        memset(dev->d_i2c.cpu_addr, 0x0, SAA7146_RPS_MEM);
425
 
426
        /* the rest + print status message */
427
 
428
        /* create a nice device name */
773 giacomo 429
        sprintf26(&dev->name[0], "saa7146 (%d)",saa7146_num);
425 giacomo 430
 
431
        INFO(("found saa7146 @ mem %p (revision %d, irq %d) (0x%04x,0x%04x).\n", dev->mem, dev->revision,dev->pci->irq,dev->pci->subsystem_vendor,dev->pci->subsystem_device));
432
        dev->ext = ext;
433
 
434
        pci_set_drvdata(pci,dev);
435
 
774 giacomo 436
        //init_MUTEX(&dev->lock);
425 giacomo 437
        dev->int_slock = SPIN_LOCK_UNLOCKED;
438
        dev->slock = SPIN_LOCK_UNLOCKED;
439
 
774 giacomo 440
        //init_MUTEX(&dev->i2c_lock);
425 giacomo 441
 
442
        dev->module = THIS_MODULE;
774 giacomo 443
        //init_waitqueue_head(&dev->i2c_wq);
425 giacomo 444
 
445
        /* set some sane pci arbitrition values */
446
        saa7146_write(dev, PCI_BT_V1, 0x1c00101f);
447
 
448
        if( 0 != ext->probe) {
449
                if( 0 != ext->probe(dev) ) {
450
                        DEB_D(("ext->probe() failed for %p. skipping device.\n",dev));
451
                        err = -ENODEV;
452
                        goto probe_error;
453
                }
454
        }
455
 
456
        if( 0 != ext->attach(dev,pci_ext) ) {
457
                DEB_D(("ext->attach() failed for %p. skipping device.\n",dev));
458
                        err = -ENODEV;
459
                        goto attach_error;
460
        }
461
 
462
        INIT_LIST_HEAD(&dev->item);
463
        list_add_tail(&dev->item,&saa7146_devices);
464
        saa7146_num++;
465
 
466
        err = 0;
467
        goto out;
468
attach_error:
469
probe_error:
470
        pci_set_drvdata(pci,NULL);
471
        pci_free_consistent(dev->pci, SAA7146_RPS_MEM, dev->d_i2c.cpu_addr, dev->d_i2c.dma_handle);
472
kmalloc_error_3:
473
        pci_free_consistent(dev->pci, SAA7146_RPS_MEM, dev->d_rps1.cpu_addr, dev->d_rps1.dma_handle);
474
kmalloc_error_2:
475
        pci_free_consistent(dev->pci, SAA7146_RPS_MEM, dev->d_rps0.cpu_addr, dev->d_rps0.dma_handle);
476
kmalloc_error_1:
477
        free_irq(dev->pci->irq, (void *)dev);
478
irq_error:
479
        iounmap(dev->mem);
480
ioremap_error:
481
        release_mem_region(adr,len);
482
pci_error:
483
        kfree(dev);
484
out:
485
        return err;
486
}
487
 
488
static void saa7146_remove_one(struct pci_dev *pdev)
489
{
490
        struct saa7146_dev* dev = (struct saa7146_dev*) pci_get_drvdata(pdev);
491
        DEB_EE(("dev:%p\n",dev));
492
 
493
        dev->ext->detach(dev);
494
 
495
        /* shut down all video dma transfers */
496
        saa7146_write(dev, MC1, 0x00ff0000);
497
 
498
        /* disable all irqs, release irq-routine */
499
        saa7146_write(dev, IER, 0);
500
 
501
        free_irq(dev->pci->irq, (void *)dev);
502
 
503
        /* free kernel memory */
504
        pci_free_consistent(dev->pci, SAA7146_RPS_MEM, dev->d_i2c.cpu_addr, dev->d_i2c.dma_handle);
505
        pci_free_consistent(dev->pci, SAA7146_RPS_MEM, dev->d_rps1.cpu_addr, dev->d_rps1.dma_handle);
506
        pci_free_consistent(dev->pci, SAA7146_RPS_MEM, dev->d_rps0.cpu_addr, dev->d_rps0.dma_handle);
507
 
508
        iounmap(dev->mem);
509
        release_mem_region(pci_resource_start(dev->pci,0), pci_resource_len(dev->pci,0));
510
 
511
        list_del(&dev->item);
512
        kfree(dev);
513
 
514
        saa7146_num--;
515
}
516
 
517
/*********************************************************************************/
518
/* extension handling functions                                                  */
519
 
520
int saa7146_register_extension(struct saa7146_extension* ext)
521
{
522
        DEB_EE(("ext:%p\n",ext));
523
 
524
        if( 0 == initialized ) {
525
                INIT_LIST_HEAD(&saa7146_devices);
774 giacomo 526
                //init_MUTEX(&saa7146_devices_lock);
425 giacomo 527
                initialized = 1;
528
        }
529
 
530
        ext->driver.name = ext->name;
531
        ext->driver.id_table = ext->pci_tbl;
532
        ext->driver.probe = saa7146_init_one;
533
        ext->driver.remove = saa7146_remove_one;
534
 
535
        printk("saa7146: register extension '%s'.\n",ext->name);
536
        return pci_module_init(&ext->driver);
537
}
538
 
539
int saa7146_unregister_extension(struct saa7146_extension* ext)
540
{
541
        DEB_EE(("ext:%p\n",ext));
542
        printk("saa7146: unregister extension '%s'.\n",ext->name);
543
        pci_unregister_driver(&ext->driver);
544
        return 0;
545
}
546
 
774 giacomo 547
int __init saa7146_init_module(void)
425 giacomo 548
{
549
        if( 0 == initialized ) {
550
                INIT_LIST_HEAD(&saa7146_devices);
774 giacomo 551
                //init_MUTEX(&saa7146_devices_lock);
425 giacomo 552
                initialized = 1;
553
        }
554
        return 0;
555
}
556
 
774 giacomo 557
void __exit saa7146_cleanup_module(void)
425 giacomo 558
{
559
}
560
 
561
module_init(saa7146_init_module);
562
module_exit(saa7146_cleanup_module);
563
 
564
EXPORT_SYMBOL_GPL(saa7146_register_extension);
565
EXPORT_SYMBOL_GPL(saa7146_unregister_extension);
566
 
567
/* misc functions used by extension modules */
568
EXPORT_SYMBOL_GPL(saa7146_pgtable_alloc);
569
EXPORT_SYMBOL_GPL(saa7146_pgtable_free);
570
EXPORT_SYMBOL_GPL(saa7146_pgtable_build_single);
571
EXPORT_SYMBOL_GPL(saa7146_vmalloc_build_pgtable);
572
EXPORT_SYMBOL_GPL(saa7146_wait_for_debi_done);
573
 
574
EXPORT_SYMBOL_GPL(saa7146_setgpio);
575
 
576
EXPORT_SYMBOL_GPL(saa7146_i2c_transfer);
577
EXPORT_SYMBOL_GPL(saa7146_i2c_adapter_prepare);
578
 
579
EXPORT_SYMBOL_GPL(saa7146_debug);
580
EXPORT_SYMBOL_GPL(saa7146_devices);
581
EXPORT_SYMBOL_GPL(saa7146_devices_lock);
582
 
583
MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
584
MODULE_DESCRIPTION("driver for generic saa7146-based hardware");
585
MODULE_LICENSE("GPL");