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