Subversion Repositories shark

Rev

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