ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / drivers / media / common / saa7146_core.c
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         unsigned long 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 (time_after(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 (time_after(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
258 static irqreturn_t interrupt_hw(int irq, void *dev_id, struct pt_regs *regs)
259 {
260         struct saa7146_dev *dev = (struct saa7146_dev*)dev_id;
261         u32 isr = 0;
262
263         /* read out the interrupt status register */
264         isr = saa7146_read(dev, ISR);
265
266         /* is this our interrupt? */
267         if ( 0 == isr ) {
268                 /* nope, some other device */
269                 return IRQ_NONE;
270         }
271
272         saa7146_write(dev, ISR, isr);
273
274         if( 0 != (dev->ext)) {
275                 if( 0 != (dev->ext->irq_mask & isr )) {
276                         if( 0 != dev->ext->irq_func ) {
277                                 dev->ext->irq_func(dev, &isr);
278                         }
279                         isr &= ~dev->ext->irq_mask;
280                 }
281         }
282         if (0 != (isr & (MASK_27))) {
283                 DEB_INT(("irq: RPS0 (0x%08x).\n",isr));
284                 if( 0 != dev->vv_data && 0 != dev->vv_callback) {
285                         dev->vv_callback(dev,isr);
286                 }
287                 isr &= ~MASK_27;
288         }
289         if (0 != (isr & (MASK_28))) {
290                 if( 0 != dev->vv_data && 0 != dev->vv_callback) {
291                         dev->vv_callback(dev,isr);
292                 }
293                 isr &= ~MASK_28;
294         }
295         if (0 != (isr & (MASK_16|MASK_17))) {
296                 u32 status = saa7146_read(dev, I2C_STATUS);
297                 if( (0x3 == (status & 0x3)) || (0 == (status & 0x1)) ) {
298                         IER_DISABLE(dev, MASK_16|MASK_17);
299                         /* only wake up if we expect something */
300                         if( 0 != dev->i2c_op ) {
301                                 u32 psr = (saa7146_read(dev, PSR) >> 16) & 0x2;
302                                 u32 ssr = (saa7146_read(dev, SSR) >> 17) & 0x1f;
303                                 DEB_I2C(("irq: i2c, status: 0x%08x, psr:0x%02x, ssr:0x%02x).\n",status,psr,ssr));
304                                 dev->i2c_op = 0;
305                                 wake_up(&dev->i2c_wq);
306                         } else {
307                                 DEB_I2C(("unexpected irq: i2c, status: 0x%08x, isr %#x\n",status, isr));
308                         }
309                 } else {
310                         DEB_I2C(("unhandled irq: i2c, status: 0x%08x, isr %#x\n",status, isr));
311                 }
312                 isr &= ~(MASK_16|MASK_17);
313         }
314         if( 0 != isr ) {
315                 ERR(("warning: interrupt enabled, but not handled properly.(0x%08x)\n",isr));
316                 ERR(("disabling interrupt source(s)!\n"));
317                 IER_DISABLE(dev,isr);
318         }
319         return IRQ_HANDLED;
320 }
321
322 /*********************************************************************************/
323 /* configuration-functions                                                       */
324
325 static int saa7146_init_one(struct pci_dev *pci, const struct pci_device_id *ent)
326 {
327         unsigned long adr = 0, len = 0;
328         struct saa7146_dev* dev = kmalloc (sizeof(struct saa7146_dev),GFP_KERNEL);
329         
330         struct saa7146_pci_extension_data *pci_ext = (struct saa7146_pci_extension_data *)ent->driver_data;
331         struct saa7146_extension* ext = pci_ext->ext;
332         int err = 0;
333         
334         if (!(dev = kmalloc (sizeof(struct saa7146_dev),GFP_KERNEL))) {
335                 ERR(("out of memory.\n"));
336                 return -ENOMEM;
337         }
338
339         /* clear out mem for sure */
340         memset(dev, 0x0, sizeof(struct saa7146_dev));
341
342         DEB_EE(("pci:%p\n",pci));
343
344         if (pci_enable_device(pci)) {
345                 ERR(("pci_enable_device() failed.\n"));
346                 err = -EIO;
347                 goto pci_error;
348         }
349
350         /* enable bus-mastering */
351         pci_set_master(pci);
352
353         dev->pci = pci;
354         /* get chip-revision; this is needed to enable bug-fixes */
355         if( 0 > pci_read_config_dword(dev->pci, PCI_CLASS_REVISION, &dev->revision)) {
356                 ERR(("pci_read_config_dword() failed.\n"));
357                 err = -ENODEV;
358                 goto pci_error;
359         }
360         dev->revision &= 0xf;
361
362         /* remap the memory from virtual to physical adress */
363         adr = pci_resource_start(pci,0);
364         len = pci_resource_len(pci,0);
365
366         if (!request_mem_region(pci_resource_start(pci,0), pci_resource_len(pci,0), "saa7146")) {
367                 ERR(("request_mem_region() failed.\n"));
368                 err = -ENODEV;
369                 goto pci_error;
370         }
371
372         if (!(dev->mem = ioremap(adr,len))) {
373                 ERR(("ioremap() failed.\n"));
374                 err = -ENODEV;
375                 goto ioremap_error;
376         }
377
378         /* we don't do a master reset here anymore, it screws up
379            some boards that don't have an i2c-eeprom for configuration
380            values */
381 /*
382         saa7146_write(dev, MC1, MASK_31);
383 */
384
385         /* disable all irqs */
386         saa7146_write(dev, IER, 0);
387
388         /* shut down all dma transfers */
389         saa7146_write(dev, MC1, 0x00ff0000);
390
391         /* clear out any rps-signals pending */
392         saa7146_write(dev, MC2, 0xf8000000);
393
394         /* request an interrupt for the saa7146 */
395         if (request_irq(dev->pci->irq, interrupt_hw, SA_SHIRQ | SA_INTERRUPT,
396                         dev->name, dev))
397         {
398                 ERR(("request_irq() failed.\n"));
399                 err = -ENODEV;
400                 goto irq_error;
401         }
402
403         /* get memory for various stuff */
404         dev->d_rps0.cpu_addr = pci_alloc_consistent(dev->pci, SAA7146_RPS_MEM, &dev->d_rps0.dma_handle);        
405         if( NULL == dev->d_rps0.cpu_addr ) {
406                 err = -ENOMEM;
407                 goto kmalloc_error_1;
408         }
409         memset(dev->d_rps0.cpu_addr, 0x0, SAA7146_RPS_MEM);
410
411         dev->d_rps1.cpu_addr = pci_alloc_consistent(dev->pci, SAA7146_RPS_MEM, &dev->d_rps1.dma_handle);        
412         if( NULL == dev->d_rps1.cpu_addr ) {
413                 err = -ENOMEM;
414                 goto kmalloc_error_2;
415         }
416         memset(dev->d_rps1.cpu_addr, 0x0, SAA7146_RPS_MEM);
417
418         dev->d_i2c.cpu_addr = pci_alloc_consistent(dev->pci, SAA7146_RPS_MEM, &dev->d_i2c.dma_handle);  
419         if( NULL == dev->d_i2c.cpu_addr ) {
420                 err = -ENOMEM;
421                 goto kmalloc_error_3;
422         }
423         memset(dev->d_i2c.cpu_addr, 0x0, SAA7146_RPS_MEM);
424
425         /* the rest + print status message */
426
427         /* create a nice device name */
428         sprintf(&dev->name[0], "saa7146 (%d)",saa7146_num);
429
430         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));
431         dev->ext = ext;
432
433         pci_set_drvdata(pci,dev);
434
435         init_MUTEX(&dev->lock);
436         dev->int_slock = SPIN_LOCK_UNLOCKED;
437         dev->slock = SPIN_LOCK_UNLOCKED;
438
439         init_MUTEX(&dev->i2c_lock);
440
441         dev->module = THIS_MODULE;
442         init_waitqueue_head(&dev->i2c_wq);
443
444         /* set some sane pci arbitrition values */
445         saa7146_write(dev, PCI_BT_V1, 0x1c00101f); 
446
447         if( 0 != ext->probe) {
448                 if( 0 != ext->probe(dev) ) {
449                         DEB_D(("ext->probe() failed for %p. skipping device.\n",dev));
450                         err = -ENODEV;
451                         goto probe_error;
452                 }
453         }
454
455         if( 0 != ext->attach(dev,pci_ext) ) {
456                 DEB_D(("ext->attach() failed for %p. skipping device.\n",dev));
457                         err = -ENODEV;
458                         goto attach_error;
459         }
460
461         INIT_LIST_HEAD(&dev->item);
462         list_add_tail(&dev->item,&saa7146_devices);
463         saa7146_num++;
464
465         err = 0;
466         goto out;
467 attach_error:
468 probe_error:
469         pci_set_drvdata(pci,NULL);
470         pci_free_consistent(dev->pci, SAA7146_RPS_MEM, dev->d_i2c.cpu_addr, dev->d_i2c.dma_handle);
471 kmalloc_error_3:
472         pci_free_consistent(dev->pci, SAA7146_RPS_MEM, dev->d_rps1.cpu_addr, dev->d_rps1.dma_handle);
473 kmalloc_error_2:
474         pci_free_consistent(dev->pci, SAA7146_RPS_MEM, dev->d_rps0.cpu_addr, dev->d_rps0.dma_handle);
475 kmalloc_error_1:
476         free_irq(dev->pci->irq, (void *)dev);
477 irq_error:
478         iounmap(dev->mem);
479 ioremap_error:
480         release_mem_region(adr,len);
481 pci_error:
482         kfree(dev);
483 out:
484         return err;
485 }
486
487 static void saa7146_remove_one(struct pci_dev *pdev)
488 {
489         struct saa7146_dev* dev = (struct saa7146_dev*) pci_get_drvdata(pdev);
490         DEB_EE(("dev:%p\n",dev));
491
492         dev->ext->detach(dev);
493
494         /* shut down all video dma transfers */
495         saa7146_write(dev, MC1, 0x00ff0000);
496
497         /* disable all irqs, release irq-routine */
498         saa7146_write(dev, IER, 0);
499
500         free_irq(dev->pci->irq, (void *)dev);
501
502         /* free kernel memory */
503         pci_free_consistent(dev->pci, SAA7146_RPS_MEM, dev->d_i2c.cpu_addr, dev->d_i2c.dma_handle);
504         pci_free_consistent(dev->pci, SAA7146_RPS_MEM, dev->d_rps1.cpu_addr, dev->d_rps1.dma_handle);
505         pci_free_consistent(dev->pci, SAA7146_RPS_MEM, dev->d_rps0.cpu_addr, dev->d_rps0.dma_handle);
506
507         iounmap(dev->mem);
508         release_mem_region(pci_resource_start(dev->pci,0), pci_resource_len(dev->pci,0));
509
510         list_del(&dev->item);
511         kfree(dev);
512
513         saa7146_num--;
514 }
515
516 /*********************************************************************************/
517 /* extension handling functions                                                  */
518
519 int saa7146_register_extension(struct saa7146_extension* ext)
520 {
521         DEB_EE(("ext:%p\n",ext));
522
523         if( 0 == initialized ) {
524                 INIT_LIST_HEAD(&saa7146_devices);
525                 init_MUTEX(&saa7146_devices_lock);
526                 initialized = 1;
527         }
528
529         ext->driver.name = ext->name;
530         ext->driver.id_table = ext->pci_tbl;
531         ext->driver.probe = saa7146_init_one;
532         ext->driver.remove = saa7146_remove_one;
533
534         printk("saa7146: register extension '%s'.\n",ext->name);
535         return pci_module_init(&ext->driver);
536 }
537
538 int saa7146_unregister_extension(struct saa7146_extension* ext)
539 {
540         DEB_EE(("ext:%p\n",ext));
541         printk("saa7146: unregister extension '%s'.\n",ext->name);
542         pci_unregister_driver(&ext->driver);
543         return 0;
544 }
545
546 static int __init saa7146_init_module(void)
547 {
548         if( 0 == initialized ) {
549                 INIT_LIST_HEAD(&saa7146_devices);
550                 init_MUTEX(&saa7146_devices_lock);
551                 initialized = 1;
552         }
553         return 0;
554 }
555
556 static void __exit saa7146_cleanup_module(void)
557 {
558 }
559
560 module_init(saa7146_init_module);
561 module_exit(saa7146_cleanup_module);
562
563 EXPORT_SYMBOL_GPL(saa7146_register_extension);
564 EXPORT_SYMBOL_GPL(saa7146_unregister_extension);
565
566 /* misc functions used by extension modules */
567 EXPORT_SYMBOL_GPL(saa7146_pgtable_alloc);
568 EXPORT_SYMBOL_GPL(saa7146_pgtable_free);
569 EXPORT_SYMBOL_GPL(saa7146_pgtable_build_single);
570 EXPORT_SYMBOL_GPL(saa7146_vmalloc_build_pgtable);
571 EXPORT_SYMBOL_GPL(saa7146_wait_for_debi_done);
572
573 EXPORT_SYMBOL_GPL(saa7146_setgpio);
574
575 EXPORT_SYMBOL_GPL(saa7146_i2c_transfer);
576 EXPORT_SYMBOL_GPL(saa7146_i2c_adapter_prepare);
577
578 EXPORT_SYMBOL_GPL(saa7146_debug);
579 EXPORT_SYMBOL_GPL(saa7146_devices);
580 EXPORT_SYMBOL_GPL(saa7146_devices_lock);
581
582 MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
583 MODULE_DESCRIPTION("driver for generic saa7146-based hardware");
584 MODULE_LICENSE("GPL");