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