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.5-rc2 600 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#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 22 23#include <media/saa7146.h> 24#include <linux/module.h> 25 26LIST_HEAD(saa7146_devices); 27DEFINE_MUTEX(saa7146_devices_lock); 28 29static int saa7146_num; 30 31unsigned int saa7146_debug; 32 33module_param(saa7146_debug, uint, 0644); 34MODULE_PARM_DESC(saa7146_debug, "debug level (default: 0)"); 35 36#if 0 37static void dump_registers(struct saa7146_dev* dev) 38{ 39 int i = 0; 40 41 pr_info(" @ %li jiffies:\n", jiffies); 42 for (i = 0; i <= 0x148; i += 4) 43 pr_info("0x%03x: 0x%08x\n", i, saa7146_read(dev, i)); 44} 45#endif 46 47/**************************************************************************** 48 * gpio and debi helper functions 49 ****************************************************************************/ 50 51void saa7146_setgpio(struct saa7146_dev *dev, int port, u32 data) 52{ 53 u32 value = 0; 54 55 BUG_ON(port > 3); 56 57 value = saa7146_read(dev, GPIO_CTRL); 58 value &= ~(0xff << (8*port)); 59 value |= (data << (8*port)); 60 saa7146_write(dev, GPIO_CTRL, value); 61} 62 63/* This DEBI code is based on the saa7146 Stradis driver by Nathan Laredo */ 64static inline int saa7146_wait_for_debi_done_sleep(struct saa7146_dev *dev, 65 unsigned long us1, unsigned long us2) 66{ 67 unsigned long timeout; 68 int err; 69 70 /* wait for registers to be programmed */ 71 timeout = jiffies + usecs_to_jiffies(us1); 72 while (1) { 73 err = time_after(jiffies, timeout); 74 if (saa7146_read(dev, MC2) & 2) 75 break; 76 if (err) { 77 pr_err("%s: %s timed out while waiting for registers getting programmed\n", 78 dev->name, __func__); 79 return -ETIMEDOUT; 80 } 81 msleep(1); 82 } 83 84 /* wait for transfer to complete */ 85 timeout = jiffies + usecs_to_jiffies(us2); 86 while (1) { 87 err = time_after(jiffies, timeout); 88 if (!(saa7146_read(dev, PSR) & SPCI_DEBI_S)) 89 break; 90 saa7146_read(dev, MC2); 91 if (err) { 92 DEB_S("%s: %s timed out while waiting for transfer completion\n", 93 dev->name, __func__); 94 return -ETIMEDOUT; 95 } 96 msleep(1); 97 } 98 99 return 0; 100} 101 102static inline int saa7146_wait_for_debi_done_busyloop(struct saa7146_dev *dev, 103 unsigned long us1, unsigned long us2) 104{ 105 unsigned long loops; 106 107 /* wait for registers to be programmed */ 108 loops = us1; 109 while (1) { 110 if (saa7146_read(dev, MC2) & 2) 111 break; 112 if (!loops--) { 113 pr_err("%s: %s timed out while waiting for 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 completion\n", 128 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 pr_debug("i:%d, adr:0x%08x, len:%d, offset:%d\n", 268 i, sg_dma_address(list), sg_dma_len(list), 269 list->offset); 270*/ 271 for (p = 0; p * 4096 < list->length; p++, ptr++) { 272 *ptr = cpu_to_le32(sg_dma_address(list) + p * 4096); 273 nr_pages++; 274 } 275 } 276 277 278 /* safety; fill the page table up with the last valid page */ 279 fill = *(ptr-1); 280 for(i=nr_pages;i<1024;i++) { 281 *ptr++ = fill; 282 } 283 284/* 285 ptr = pt->cpu; 286 pr_debug("offset: %d\n", pt->offset); 287 for(i=0;i<5;i++) { 288 pr_debug("ptr1 %d: 0x%08x\n", i, ptr[i]); 289 } 290*/ 291 return 0; 292} 293 294/********************************************************************************/ 295/* interrupt handler */ 296static irqreturn_t interrupt_hw(int irq, void *dev_id) 297{ 298 struct saa7146_dev *dev = dev_id; 299 u32 isr; 300 u32 ack_isr; 301 302 /* read out the interrupt status register */ 303 ack_isr = isr = saa7146_read(dev, ISR); 304 305 /* is this our interrupt? */ 306 if ( 0 == isr ) { 307 /* nope, some other device */ 308 return IRQ_NONE; 309 } 310 311 if (dev->ext) { 312 if (dev->ext->irq_mask & isr) { 313 if (dev->ext->irq_func) 314 dev->ext->irq_func(dev, &isr); 315 isr &= ~dev->ext->irq_mask; 316 } 317 } 318 if (0 != (isr & (MASK_27))) { 319 DEB_INT("irq: RPS0 (0x%08x)\n", isr); 320 if (dev->vv_data && dev->vv_callback) 321 dev->vv_callback(dev,isr); 322 isr &= ~MASK_27; 323 } 324 if (0 != (isr & (MASK_28))) { 325 if (dev->vv_data && dev->vv_callback) 326 dev->vv_callback(dev,isr); 327 isr &= ~MASK_28; 328 } 329 if (0 != (isr & (MASK_16|MASK_17))) { 330 SAA7146_IER_DISABLE(dev, MASK_16|MASK_17); 331 /* only wake up if we expect something */ 332 if (0 != dev->i2c_op) { 333 dev->i2c_op = 0; 334 wake_up(&dev->i2c_wq); 335 } else { 336 u32 psr = saa7146_read(dev, PSR); 337 u32 ssr = saa7146_read(dev, SSR); 338 pr_warn("%s: unexpected i2c irq: isr %08x psr %08x ssr %08x\n", 339 dev->name, isr, psr, ssr); 340 } 341 isr &= ~(MASK_16|MASK_17); 342 } 343 if( 0 != isr ) { 344 ERR("warning: interrupt enabled, but not handled properly.(0x%08x)\n", 345 isr); 346 ERR("disabling interrupt source(s)!\n"); 347 SAA7146_IER_DISABLE(dev,isr); 348 } 349 saa7146_write(dev, ISR, ack_isr); 350 return IRQ_HANDLED; 351} 352 353/*********************************************************************************/ 354/* configuration-functions */ 355 356static int saa7146_init_one(struct pci_dev *pci, const struct pci_device_id *ent) 357{ 358 struct saa7146_pci_extension_data *pci_ext = (struct saa7146_pci_extension_data *)ent->driver_data; 359 struct saa7146_extension *ext = pci_ext->ext; 360 struct saa7146_dev *dev; 361 int err = -ENOMEM; 362 363 /* clear out mem for sure */ 364 dev = kzalloc(sizeof(struct saa7146_dev), GFP_KERNEL); 365 if (!dev) { 366 ERR("out of memory\n"); 367 goto out; 368 } 369 370 DEB_EE("pci:%p\n", pci); 371 372 err = pci_enable_device(pci); 373 if (err < 0) { 374 ERR("pci_enable_device() failed\n"); 375 goto err_free; 376 } 377 378 /* enable bus-mastering */ 379 pci_set_master(pci); 380 381 dev->pci = pci; 382 383 /* get chip-revision; this is needed to enable bug-fixes */ 384 dev->revision = pci->revision; 385 386 /* remap the memory from virtual to physical address */ 387 388 err = pci_request_region(pci, 0, "saa7146"); 389 if (err < 0) 390 goto err_disable; 391 392 dev->mem = ioremap(pci_resource_start(pci, 0), 393 pci_resource_len(pci, 0)); 394 if (!dev->mem) { 395 ERR("ioremap() failed\n"); 396 err = -ENODEV; 397 goto err_release; 398 } 399 400 /* we don't do a master reset here anymore, it screws up 401 some boards that don't have an i2c-eeprom for configuration 402 values */ 403/* 404 saa7146_write(dev, MC1, MASK_31); 405*/ 406 407 /* disable all irqs */ 408 saa7146_write(dev, IER, 0); 409 410 /* shut down all dma transfers and rps tasks */ 411 saa7146_write(dev, MC1, 0x30ff0000); 412 413 /* clear out any rps-signals pending */ 414 saa7146_write(dev, MC2, 0xf8000000); 415 416 /* request an interrupt for the saa7146 */ 417 err = request_irq(pci->irq, interrupt_hw, IRQF_SHARED | IRQF_DISABLED, 418 dev->name, dev); 419 if (err < 0) { 420 ERR("request_irq() failed\n"); 421 goto err_unmap; 422 } 423 424 err = -ENOMEM; 425 426 /* get memory for various stuff */ 427 dev->d_rps0.cpu_addr = pci_alloc_consistent(pci, SAA7146_RPS_MEM, 428 &dev->d_rps0.dma_handle); 429 if (!dev->d_rps0.cpu_addr) 430 goto err_free_irq; 431 memset(dev->d_rps0.cpu_addr, 0x0, SAA7146_RPS_MEM); 432 433 dev->d_rps1.cpu_addr = pci_alloc_consistent(pci, SAA7146_RPS_MEM, 434 &dev->d_rps1.dma_handle); 435 if (!dev->d_rps1.cpu_addr) 436 goto err_free_rps0; 437 memset(dev->d_rps1.cpu_addr, 0x0, SAA7146_RPS_MEM); 438 439 dev->d_i2c.cpu_addr = pci_alloc_consistent(pci, SAA7146_RPS_MEM, 440 &dev->d_i2c.dma_handle); 441 if (!dev->d_i2c.cpu_addr) 442 goto err_free_rps1; 443 memset(dev->d_i2c.cpu_addr, 0x0, SAA7146_RPS_MEM); 444 445 /* the rest + print status message */ 446 447 /* create a nice device name */ 448 sprintf(dev->name, "saa7146 (%d)", saa7146_num); 449 450 pr_info("found saa7146 @ mem %p (revision %d, irq %d) (0x%04x,0x%04x)\n", 451 dev->mem, dev->revision, pci->irq, 452 pci->subsystem_vendor, pci->subsystem_device); 453 dev->ext = ext; 454 455 mutex_init(&dev->v4l2_lock); 456 spin_lock_init(&dev->int_slock); 457 spin_lock_init(&dev->slock); 458 459 mutex_init(&dev->i2c_lock); 460 461 dev->module = THIS_MODULE; 462 init_waitqueue_head(&dev->i2c_wq); 463 464 /* set some sane pci arbitrition values */ 465 saa7146_write(dev, PCI_BT_V1, 0x1c00101f); 466 467 /* TODO: use the status code of the callback */ 468 469 err = -ENODEV; 470 471 if (ext->probe && ext->probe(dev)) { 472 DEB_D("ext->probe() failed for %p. skipping device.\n", dev); 473 goto err_free_i2c; 474 } 475 476 if (ext->attach(dev, pci_ext)) { 477 DEB_D("ext->attach() failed for %p. skipping device.\n", dev); 478 goto err_free_i2c; 479 } 480 /* V4L extensions will set the pci drvdata to the v4l2_device in the 481 attach() above. So for those cards that do not use V4L we have to 482 set it explicitly. */ 483 pci_set_drvdata(pci, &dev->v4l2_dev); 484 485 INIT_LIST_HEAD(&dev->item); 486 list_add_tail(&dev->item,&saa7146_devices); 487 saa7146_num++; 488 489 err = 0; 490out: 491 return err; 492 493err_free_i2c: 494 pci_free_consistent(pci, SAA7146_RPS_MEM, dev->d_i2c.cpu_addr, 495 dev->d_i2c.dma_handle); 496err_free_rps1: 497 pci_free_consistent(pci, SAA7146_RPS_MEM, dev->d_rps1.cpu_addr, 498 dev->d_rps1.dma_handle); 499err_free_rps0: 500 pci_free_consistent(pci, SAA7146_RPS_MEM, dev->d_rps0.cpu_addr, 501 dev->d_rps0.dma_handle); 502err_free_irq: 503 free_irq(pci->irq, (void *)dev); 504err_unmap: 505 iounmap(dev->mem); 506err_release: 507 pci_release_region(pci, 0); 508err_disable: 509 pci_disable_device(pci); 510err_free: 511 kfree(dev); 512 goto out; 513} 514 515static void saa7146_remove_one(struct pci_dev *pdev) 516{ 517 struct v4l2_device *v4l2_dev = pci_get_drvdata(pdev); 518 struct saa7146_dev *dev = to_saa7146_dev(v4l2_dev); 519 struct { 520 void *addr; 521 dma_addr_t dma; 522 } dev_map[] = { 523 { dev->d_i2c.cpu_addr, dev->d_i2c.dma_handle }, 524 { dev->d_rps1.cpu_addr, dev->d_rps1.dma_handle }, 525 { dev->d_rps0.cpu_addr, dev->d_rps0.dma_handle }, 526 { NULL, 0 } 527 }, *p; 528 529 DEB_EE("dev:%p\n", dev); 530 531 dev->ext->detach(dev); 532 /* Zero the PCI drvdata after use. */ 533 pci_set_drvdata(pdev, NULL); 534 535 /* shut down all video dma transfers */ 536 saa7146_write(dev, MC1, 0x00ff0000); 537 538 /* disable all irqs, release irq-routine */ 539 saa7146_write(dev, IER, 0); 540 541 free_irq(pdev->irq, dev); 542 543 for (p = dev_map; p->addr; p++) 544 pci_free_consistent(pdev, SAA7146_RPS_MEM, p->addr, p->dma); 545 546 iounmap(dev->mem); 547 pci_release_region(pdev, 0); 548 list_del(&dev->item); 549 pci_disable_device(pdev); 550 kfree(dev); 551 552 saa7146_num--; 553} 554 555/*********************************************************************************/ 556/* extension handling functions */ 557 558int saa7146_register_extension(struct saa7146_extension* ext) 559{ 560 DEB_EE("ext:%p\n", ext); 561 562 ext->driver.name = ext->name; 563 ext->driver.id_table = ext->pci_tbl; 564 ext->driver.probe = saa7146_init_one; 565 ext->driver.remove = saa7146_remove_one; 566 567 pr_info("register extension '%s'\n", ext->name); 568 return pci_register_driver(&ext->driver); 569} 570 571int saa7146_unregister_extension(struct saa7146_extension* ext) 572{ 573 DEB_EE("ext:%p\n", ext); 574 pr_info("unregister extension '%s'\n", ext->name); 575 pci_unregister_driver(&ext->driver); 576 return 0; 577} 578 579EXPORT_SYMBOL_GPL(saa7146_register_extension); 580EXPORT_SYMBOL_GPL(saa7146_unregister_extension); 581 582/* misc functions used by extension modules */ 583EXPORT_SYMBOL_GPL(saa7146_pgtable_alloc); 584EXPORT_SYMBOL_GPL(saa7146_pgtable_free); 585EXPORT_SYMBOL_GPL(saa7146_pgtable_build_single); 586EXPORT_SYMBOL_GPL(saa7146_vmalloc_build_pgtable); 587EXPORT_SYMBOL_GPL(saa7146_vfree_destroy_pgtable); 588EXPORT_SYMBOL_GPL(saa7146_wait_for_debi_done); 589 590EXPORT_SYMBOL_GPL(saa7146_setgpio); 591 592EXPORT_SYMBOL_GPL(saa7146_i2c_adapter_prepare); 593 594EXPORT_SYMBOL_GPL(saa7146_debug); 595EXPORT_SYMBOL_GPL(saa7146_devices); 596EXPORT_SYMBOL_GPL(saa7146_devices_lock); 597 598MODULE_AUTHOR("Michael Hunold <michael@mihu.de>"); 599MODULE_DESCRIPTION("driver for generic saa7146-based hardware"); 600MODULE_LICENSE("GPL");