Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.1-rc3 595 lines 15 kB view raw
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#if 0 34static void dump_registers(struct saa7146_dev* dev) 35{ 36 int i = 0; 37 38 INFO((" @ %li jiffies:\n",jiffies)); 39 for(i = 0; i <= 0x148; i+=4) { 40 printk("0x%03x: 0x%08x\n",i,saa7146_read(dev,i)); 41 } 42} 43#endif 44 45/**************************************************************************** 46 * gpio and debi helper functions 47 ****************************************************************************/ 48 49void saa7146_setgpio(struct saa7146_dev *dev, int port, u32 data) 50{ 51 u32 value = 0; 52 53 BUG_ON(port > 3); 54 55 value = saa7146_read(dev, GPIO_CTRL); 56 value &= ~(0xff << (8*port)); 57 value |= (data << (8*port)); 58 saa7146_write(dev, GPIO_CTRL, value); 59} 60 61/* This DEBI code is based on the saa7146 Stradis driver by Nathan Laredo */ 62static inline int saa7146_wait_for_debi_done_sleep(struct saa7146_dev *dev, 63 unsigned long us1, unsigned long us2) 64{ 65 unsigned long timeout; 66 int err; 67 68 /* wait for registers to be programmed */ 69 timeout = jiffies + usecs_to_jiffies(us1); 70 while (1) { 71 err = time_after(jiffies, timeout); 72 if (saa7146_read(dev, MC2) & 2) 73 break; 74 if (err) { 75 printk(KERN_ERR "%s: %s timed out while waiting for " 76 "registers getting programmed\n", 77 dev->name, __func__); 78 return -ETIMEDOUT; 79 } 80 msleep(1); 81 } 82 83 /* wait for transfer to complete */ 84 timeout = jiffies + usecs_to_jiffies(us2); 85 while (1) { 86 err = time_after(jiffies, timeout); 87 if (!(saa7146_read(dev, PSR) & SPCI_DEBI_S)) 88 break; 89 saa7146_read(dev, MC2); 90 if (err) { 91 DEB_S(("%s: %s timed out while waiting for transfer " 92 "completion\n", dev->name, __func__)); 93 return -ETIMEDOUT; 94 } 95 msleep(1); 96 } 97 98 return 0; 99} 100 101static inline int saa7146_wait_for_debi_done_busyloop(struct saa7146_dev *dev, 102 unsigned long us1, unsigned long us2) 103{ 104 unsigned long loops; 105 106 /* wait for registers to be programmed */ 107 loops = us1; 108 while (1) { 109 if (saa7146_read(dev, MC2) & 2) 110 break; 111 if (!loops--) { 112 printk(KERN_ERR "%s: %s timed out while waiting for " 113 "registers getting programmed\n", 114 dev->name, __func__); 115 return -ETIMEDOUT; 116 } 117 udelay(1); 118 } 119 120 /* wait for transfer to complete */ 121 loops = us2 / 5; 122 while (1) { 123 if (!(saa7146_read(dev, PSR) & SPCI_DEBI_S)) 124 break; 125 saa7146_read(dev, MC2); 126 if (!loops--) { 127 DEB_S(("%s: %s timed out while waiting for transfer " 128 "completion\n", dev->name, __func__)); 129 return -ETIMEDOUT; 130 } 131 udelay(5); 132 } 133 134 return 0; 135} 136 137int saa7146_wait_for_debi_done(struct saa7146_dev *dev, int nobusyloop) 138{ 139 if (nobusyloop) 140 return saa7146_wait_for_debi_done_sleep(dev, 50000, 250000); 141 else 142 return saa7146_wait_for_debi_done_busyloop(dev, 50000, 250000); 143} 144 145/**************************************************************************** 146 * general helper functions 147 ****************************************************************************/ 148 149/* this is videobuf_vmalloc_to_sg() from videobuf-dma-sg.c 150 make sure virt has been allocated with vmalloc_32(), otherwise the BUG() 151 may be triggered on highmem machines */ 152static struct scatterlist* vmalloc_to_sg(unsigned char *virt, int nr_pages) 153{ 154 struct scatterlist *sglist; 155 struct page *pg; 156 int i; 157 158 sglist = kcalloc(nr_pages, sizeof(struct scatterlist), GFP_KERNEL); 159 if (NULL == sglist) 160 return NULL; 161 sg_init_table(sglist, nr_pages); 162 for (i = 0; i < nr_pages; i++, virt += PAGE_SIZE) { 163 pg = vmalloc_to_page(virt); 164 if (NULL == pg) 165 goto err; 166 BUG_ON(PageHighMem(pg)); 167 sg_set_page(&sglist[i], pg, PAGE_SIZE, 0); 168 } 169 return sglist; 170 171 err: 172 kfree(sglist); 173 return NULL; 174} 175 176/********************************************************************************/ 177/* common page table functions */ 178 179void *saa7146_vmalloc_build_pgtable(struct pci_dev *pci, long length, struct saa7146_pgtable *pt) 180{ 181 int pages = (length+PAGE_SIZE-1)/PAGE_SIZE; 182 void *mem = vmalloc_32(length); 183 int slen = 0; 184 185 if (NULL == mem) 186 goto err_null; 187 188 if (!(pt->slist = vmalloc_to_sg(mem, pages))) 189 goto err_free_mem; 190 191 if (saa7146_pgtable_alloc(pci, pt)) 192 goto err_free_slist; 193 194 pt->nents = pages; 195 slen = pci_map_sg(pci,pt->slist,pt->nents,PCI_DMA_FROMDEVICE); 196 if (0 == slen) 197 goto err_free_pgtable; 198 199 if (0 != saa7146_pgtable_build_single(pci, pt, pt->slist, slen)) 200 goto err_unmap_sg; 201 202 return mem; 203 204err_unmap_sg: 205 pci_unmap_sg(pci, pt->slist, pt->nents, PCI_DMA_FROMDEVICE); 206err_free_pgtable: 207 saa7146_pgtable_free(pci, pt); 208err_free_slist: 209 kfree(pt->slist); 210 pt->slist = NULL; 211err_free_mem: 212 vfree(mem); 213err_null: 214 return NULL; 215} 216 217void saa7146_vfree_destroy_pgtable(struct pci_dev *pci, void *mem, struct saa7146_pgtable *pt) 218{ 219 pci_unmap_sg(pci, pt->slist, pt->nents, PCI_DMA_FROMDEVICE); 220 saa7146_pgtable_free(pci, pt); 221 kfree(pt->slist); 222 pt->slist = NULL; 223 vfree(mem); 224} 225 226void saa7146_pgtable_free(struct pci_dev *pci, struct saa7146_pgtable *pt) 227{ 228 if (NULL == pt->cpu) 229 return; 230 pci_free_consistent(pci, pt->size, pt->cpu, pt->dma); 231 pt->cpu = NULL; 232} 233 234int saa7146_pgtable_alloc(struct pci_dev *pci, struct saa7146_pgtable *pt) 235{ 236 __le32 *cpu; 237 dma_addr_t dma_addr = 0; 238 239 cpu = pci_alloc_consistent(pci, PAGE_SIZE, &dma_addr); 240 if (NULL == cpu) { 241 return -ENOMEM; 242 } 243 pt->size = PAGE_SIZE; 244 pt->cpu = cpu; 245 pt->dma = dma_addr; 246 247 return 0; 248} 249 250int saa7146_pgtable_build_single(struct pci_dev *pci, struct saa7146_pgtable *pt, 251 struct scatterlist *list, int sglen ) 252{ 253 __le32 *ptr, fill; 254 int nr_pages = 0; 255 int i,p; 256 257 BUG_ON(0 == sglen); 258 BUG_ON(list->offset > PAGE_SIZE); 259 260 /* if we have a user buffer, the first page may not be 261 aligned to a page boundary. */ 262 pt->offset = list->offset; 263 264 ptr = pt->cpu; 265 for (i = 0; i < sglen; i++, list++) { 266/* 267 printk("i:%d, adr:0x%08x, len:%d, offset:%d\n", i,sg_dma_address(list), sg_dma_len(list), list->offset); 268*/ 269 for (p = 0; p * 4096 < list->length; p++, ptr++) { 270 *ptr = cpu_to_le32(sg_dma_address(list) + p * 4096); 271 nr_pages++; 272 } 273 } 274 275 276 /* safety; fill the page table up with the last valid page */ 277 fill = *(ptr-1); 278 for(i=nr_pages;i<1024;i++) { 279 *ptr++ = fill; 280 } 281 282/* 283 ptr = pt->cpu; 284 printk("offset: %d\n",pt->offset); 285 for(i=0;i<5;i++) { 286 printk("ptr1 %d: 0x%08x\n",i,ptr[i]); 287 } 288*/ 289 return 0; 290} 291 292/********************************************************************************/ 293/* interrupt handler */ 294static irqreturn_t interrupt_hw(int irq, void *dev_id) 295{ 296 struct saa7146_dev *dev = dev_id; 297 u32 isr; 298 u32 ack_isr; 299 300 /* read out the interrupt status register */ 301 ack_isr = isr = saa7146_read(dev, ISR); 302 303 /* is this our interrupt? */ 304 if ( 0 == isr ) { 305 /* nope, some other device */ 306 return IRQ_NONE; 307 } 308 309 if (dev->ext) { 310 if (dev->ext->irq_mask & isr) { 311 if (dev->ext->irq_func) 312 dev->ext->irq_func(dev, &isr); 313 isr &= ~dev->ext->irq_mask; 314 } 315 } 316 if (0 != (isr & (MASK_27))) { 317 DEB_INT(("irq: RPS0 (0x%08x).\n",isr)); 318 if (dev->vv_data && dev->vv_callback) 319 dev->vv_callback(dev,isr); 320 isr &= ~MASK_27; 321 } 322 if (0 != (isr & (MASK_28))) { 323 if (dev->vv_data && dev->vv_callback) 324 dev->vv_callback(dev,isr); 325 isr &= ~MASK_28; 326 } 327 if (0 != (isr & (MASK_16|MASK_17))) { 328 SAA7146_IER_DISABLE(dev, MASK_16|MASK_17); 329 /* only wake up if we expect something */ 330 if (0 != dev->i2c_op) { 331 dev->i2c_op = 0; 332 wake_up(&dev->i2c_wq); 333 } else { 334 u32 psr = saa7146_read(dev, PSR); 335 u32 ssr = saa7146_read(dev, SSR); 336 printk(KERN_WARNING "%s: unexpected i2c irq: isr %08x psr %08x ssr %08x\n", 337 dev->name, isr, psr, ssr); 338 } 339 isr &= ~(MASK_16|MASK_17); 340 } 341 if( 0 != isr ) { 342 ERR(("warning: interrupt enabled, but not handled properly.(0x%08x)\n",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 353static 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 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)); 448 dev->ext = ext; 449 450 mutex_init(&dev->v4l2_lock); 451 spin_lock_init(&dev->int_slock); 452 spin_lock_init(&dev->slock); 453 454 mutex_init(&dev->i2c_lock); 455 456 dev->module = THIS_MODULE; 457 init_waitqueue_head(&dev->i2c_wq); 458 459 /* set some sane pci arbitrition values */ 460 saa7146_write(dev, PCI_BT_V1, 0x1c00101f); 461 462 /* TODO: use the status code of the callback */ 463 464 err = -ENODEV; 465 466 if (ext->probe && ext->probe(dev)) { 467 DEB_D(("ext->probe() failed for %p. skipping device.\n",dev)); 468 goto err_free_i2c; 469 } 470 471 if (ext->attach(dev, pci_ext)) { 472 DEB_D(("ext->attach() failed for %p. skipping device.\n",dev)); 473 goto err_free_i2c; 474 } 475 /* V4L extensions will set the pci drvdata to the v4l2_device in the 476 attach() above. So for those cards that do not use V4L we have to 477 set it explicitly. */ 478 pci_set_drvdata(pci, &dev->v4l2_dev); 479 480 INIT_LIST_HEAD(&dev->item); 481 list_add_tail(&dev->item,&saa7146_devices); 482 saa7146_num++; 483 484 err = 0; 485out: 486 return err; 487 488err_free_i2c: 489 pci_free_consistent(pci, SAA7146_RPS_MEM, dev->d_i2c.cpu_addr, 490 dev->d_i2c.dma_handle); 491err_free_rps1: 492 pci_free_consistent(pci, SAA7146_RPS_MEM, dev->d_rps1.cpu_addr, 493 dev->d_rps1.dma_handle); 494err_free_rps0: 495 pci_free_consistent(pci, SAA7146_RPS_MEM, dev->d_rps0.cpu_addr, 496 dev->d_rps0.dma_handle); 497err_free_irq: 498 free_irq(pci->irq, (void *)dev); 499err_unmap: 500 iounmap(dev->mem); 501err_release: 502 pci_release_region(pci, 0); 503err_disable: 504 pci_disable_device(pci); 505err_free: 506 kfree(dev); 507 goto out; 508} 509 510static 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 list_del(&dev->item); 544 pci_disable_device(pdev); 545 kfree(dev); 546 547 saa7146_num--; 548} 549 550/*********************************************************************************/ 551/* extension handling functions */ 552 553int saa7146_register_extension(struct saa7146_extension* ext) 554{ 555 DEB_EE(("ext:%p\n",ext)); 556 557 ext->driver.name = ext->name; 558 ext->driver.id_table = ext->pci_tbl; 559 ext->driver.probe = saa7146_init_one; 560 ext->driver.remove = saa7146_remove_one; 561 562 printk("saa7146: register extension '%s'.\n",ext->name); 563 return pci_register_driver(&ext->driver); 564} 565 566int saa7146_unregister_extension(struct saa7146_extension* ext) 567{ 568 DEB_EE(("ext:%p\n",ext)); 569 printk("saa7146: unregister extension '%s'.\n",ext->name); 570 pci_unregister_driver(&ext->driver); 571 return 0; 572} 573 574EXPORT_SYMBOL_GPL(saa7146_register_extension); 575EXPORT_SYMBOL_GPL(saa7146_unregister_extension); 576 577/* misc functions used by extension modules */ 578EXPORT_SYMBOL_GPL(saa7146_pgtable_alloc); 579EXPORT_SYMBOL_GPL(saa7146_pgtable_free); 580EXPORT_SYMBOL_GPL(saa7146_pgtable_build_single); 581EXPORT_SYMBOL_GPL(saa7146_vmalloc_build_pgtable); 582EXPORT_SYMBOL_GPL(saa7146_vfree_destroy_pgtable); 583EXPORT_SYMBOL_GPL(saa7146_wait_for_debi_done); 584 585EXPORT_SYMBOL_GPL(saa7146_setgpio); 586 587EXPORT_SYMBOL_GPL(saa7146_i2c_adapter_prepare); 588 589EXPORT_SYMBOL_GPL(saa7146_debug); 590EXPORT_SYMBOL_GPL(saa7146_devices); 591EXPORT_SYMBOL_GPL(saa7146_devices_lock); 592 593MODULE_AUTHOR("Michael Hunold <michael@mihu.de>"); 594MODULE_DESCRIPTION("driver for generic saa7146-based hardware"); 595MODULE_LICENSE("GPL");