diff options
156 files changed, 13214 insertions, 6482 deletions
diff --git a/Documentation/filesystems/ext4.txt b/Documentation/filesystems/ext4.txt index eb154ef36c2a..174eaff7ded9 100644 --- a/Documentation/filesystems/ext4.txt +++ b/Documentation/filesystems/ext4.txt | |||
@@ -2,19 +2,24 @@ | |||
2 | Ext4 Filesystem | 2 | Ext4 Filesystem |
3 | =============== | 3 | =============== |
4 | 4 | ||
5 | This is a development version of the ext4 filesystem, an advanced level | 5 | Ext4 is an an advanced level of the ext3 filesystem which incorporates |
6 | of the ext3 filesystem which incorporates scalability and reliability | 6 | scalability and reliability enhancements for supporting large filesystems |
7 | enhancements for supporting large filesystems (64 bit) in keeping with | 7 | (64 bit) in keeping with increasing disk capacities and state-of-the-art |
8 | increasing disk capacities and state-of-the-art feature requirements. | 8 | feature requirements. |
9 | 9 | ||
10 | Mailing list: linux-ext4@vger.kernel.org | 10 | Mailing list: linux-ext4@vger.kernel.org |
11 | Web site: http://ext4.wiki.kernel.org | ||
11 | 12 | ||
12 | 13 | ||
13 | 1. Quick usage instructions: | 14 | 1. Quick usage instructions: |
14 | =========================== | 15 | =========================== |
15 | 16 | ||
17 | Note: More extensive information for getting started with ext4 can be | ||
18 | found at the ext4 wiki site at the URL: | ||
19 | http://ext4.wiki.kernel.org/index.php/Ext4_Howto | ||
20 | |||
16 | - Compile and install the latest version of e2fsprogs (as of this | 21 | - Compile and install the latest version of e2fsprogs (as of this |
17 | writing version 1.41) from: | 22 | writing version 1.41.3) from: |
18 | 23 | ||
19 | http://sourceforge.net/project/showfiles.php?group_id=2406 | 24 | http://sourceforge.net/project/showfiles.php?group_id=2406 |
20 | 25 | ||
@@ -36,11 +41,9 @@ Mailing list: linux-ext4@vger.kernel.org | |||
36 | 41 | ||
37 | # mke2fs -t ext4 /dev/hda1 | 42 | # mke2fs -t ext4 /dev/hda1 |
38 | 43 | ||
39 | Or configure an existing ext3 filesystem to support extents and set | 44 | Or to configure an existing ext3 filesystem to support extents: |
40 | the test_fs flag to indicate that it's ok for an in-development | ||
41 | filesystem to touch this filesystem: | ||
42 | 45 | ||
43 | # tune2fs -O extents -E test_fs /dev/hda1 | 46 | # tune2fs -O extents /dev/hda1 |
44 | 47 | ||
45 | If the filesystem was created with 128 byte inodes, it can be | 48 | If the filesystem was created with 128 byte inodes, it can be |
46 | converted to use 256 byte for greater efficiency via: | 49 | converted to use 256 byte for greater efficiency via: |
@@ -104,8 +107,8 @@ exist yet so I'm not sure they're in the near-term roadmap. | |||
104 | The big performance win will come with mballoc, delalloc and flex_bg | 107 | The big performance win will come with mballoc, delalloc and flex_bg |
105 | grouping of bitmaps and inode tables. Some test results available here: | 108 | grouping of bitmaps and inode tables. Some test results available here: |
106 | 109 | ||
107 | - http://www.bullopensource.org/ext4/20080530/ffsb-write-2.6.26-rc2.html | 110 | - http://www.bullopensource.org/ext4/20080818-ffsb/ffsb-write-2.6.27-rc1.html |
108 | - http://www.bullopensource.org/ext4/20080530/ffsb-readwrite-2.6.26-rc2.html | 111 | - http://www.bullopensource.org/ext4/20080818-ffsb/ffsb-readwrite-2.6.27-rc1.html |
109 | 112 | ||
110 | 3. Options | 113 | 3. Options |
111 | ========== | 114 | ========== |
@@ -214,9 +217,6 @@ noreservation | |||
214 | bsddf (*) Make 'df' act like BSD. | 217 | bsddf (*) Make 'df' act like BSD. |
215 | minixdf Make 'df' act like Minix. | 218 | minixdf Make 'df' act like Minix. |
216 | 219 | ||
217 | check=none Don't do extra checking of bitmaps on mount. | ||
218 | nocheck | ||
219 | |||
220 | debug Extra debugging information is sent to syslog. | 220 | debug Extra debugging information is sent to syslog. |
221 | 221 | ||
222 | errors=remount-ro(*) Remount the filesystem read-only on an error. | 222 | errors=remount-ro(*) Remount the filesystem read-only on an error. |
@@ -253,8 +253,6 @@ nobh (a) cache disk block mapping information | |||
253 | "nobh" option tries to avoid associating buffer | 253 | "nobh" option tries to avoid associating buffer |
254 | heads (supported only for "writeback" mode). | 254 | heads (supported only for "writeback" mode). |
255 | 255 | ||
256 | mballoc (*) Use the multiple block allocator for block allocation | ||
257 | nomballoc disabled multiple block allocator for block allocation. | ||
258 | stripe=n Number of filesystem blocks that mballoc will try | 256 | stripe=n Number of filesystem blocks that mballoc will try |
259 | to use for allocation size and alignment. For RAID5/6 | 257 | to use for allocation size and alignment. For RAID5/6 |
260 | systems this should be the number of data | 258 | systems this should be the number of data |
diff --git a/Documentation/video4linux/CARDLIST.au0828 b/Documentation/video4linux/CARDLIST.au0828 index aa05e5bb22fb..d5cb4ea287b2 100644 --- a/Documentation/video4linux/CARDLIST.au0828 +++ b/Documentation/video4linux/CARDLIST.au0828 | |||
@@ -1,5 +1,5 @@ | |||
1 | 0 -> Unknown board (au0828) | 1 | 0 -> Unknown board (au0828) |
2 | 1 -> Hauppauge HVR950Q (au0828) [2040:7200,2040:7210,2040:7217,2040:721b,2040:721f,2040:7280,0fd9:0008] | 2 | 1 -> Hauppauge HVR950Q (au0828) [2040:7200,2040:7210,2040:7217,2040:721b,2040:721e,2040:721f,2040:7280,0fd9:0008] |
3 | 2 -> Hauppauge HVR850 (au0828) [2040:7240] | 3 | 2 -> Hauppauge HVR850 (au0828) [2040:7240] |
4 | 3 -> DViCO FusionHDTV USB (au0828) [0fe9:d620] | 4 | 3 -> DViCO FusionHDTV USB (au0828) [0fe9:d620] |
5 | 4 -> Hauppauge HVR950Q rev xxF8 (au0828) [2040:7201,2040:7211,2040:7281] | 5 | 4 -> Hauppauge HVR950Q rev xxF8 (au0828) [2040:7201,2040:7211,2040:7281] |
diff --git a/Documentation/video4linux/CARDLIST.tuner b/Documentation/video4linux/CARDLIST.tuner index 30bbdda68d03..691d2f37dc57 100644 --- a/Documentation/video4linux/CARDLIST.tuner +++ b/Documentation/video4linux/CARDLIST.tuner | |||
@@ -75,3 +75,4 @@ tuner=73 - Samsung TCPG 6121P30A | |||
75 | tuner=75 - Philips TEA5761 FM Radio | 75 | tuner=75 - Philips TEA5761 FM Radio |
76 | tuner=76 - Xceive 5000 tuner | 76 | tuner=76 - Xceive 5000 tuner |
77 | tuner=77 - TCL tuner MF02GIP-5N-E | 77 | tuner=77 - TCL tuner MF02GIP-5N-E |
78 | tuner=78 - Philips FMD1216MEX MK3 Hybrid Tuner | ||
diff --git a/arch/x86/mm/highmem_32.c b/arch/x86/mm/highmem_32.c index 165c871ba9af..bcc079c282dd 100644 --- a/arch/x86/mm/highmem_32.c +++ b/arch/x86/mm/highmem_32.c | |||
@@ -137,6 +137,7 @@ void *kmap_atomic_pfn(unsigned long pfn, enum km_type type) | |||
137 | 137 | ||
138 | return (void*) vaddr; | 138 | return (void*) vaddr; |
139 | } | 139 | } |
140 | EXPORT_SYMBOL_GPL(kmap_atomic_pfn); /* temporarily in use by i915 GEM until vmap */ | ||
140 | 141 | ||
141 | struct page *kmap_atomic_to_page(void *ptr) | 142 | struct page *kmap_atomic_to_page(void *ptr) |
142 | { | 143 | { |
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 610d6fd5bb50..9097500de5f4 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig | |||
@@ -6,7 +6,7 @@ | |||
6 | # | 6 | # |
7 | menuconfig DRM | 7 | menuconfig DRM |
8 | tristate "Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)" | 8 | tristate "Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)" |
9 | depends on (AGP || AGP=n) && PCI && !EMULATED_CMPXCHG | 9 | depends on (AGP || AGP=n) && PCI && !EMULATED_CMPXCHG && SHMEM |
10 | help | 10 | help |
11 | Kernel-level support for the Direct Rendering Infrastructure (DRI) | 11 | Kernel-level support for the Direct Rendering Infrastructure (DRI) |
12 | introduced in XFree86 4.0. If you say Y here, you need to select | 12 | introduced in XFree86 4.0. If you say Y here, you need to select |
@@ -87,6 +87,7 @@ config DRM_MGA | |||
87 | config DRM_SIS | 87 | config DRM_SIS |
88 | tristate "SiS video cards" | 88 | tristate "SiS video cards" |
89 | depends on DRM && AGP | 89 | depends on DRM && AGP |
90 | depends on FB_SIS || FB_SIS=n | ||
90 | help | 91 | help |
91 | Choose this option if you have a SiS 630 or compatible video | 92 | Choose this option if you have a SiS 630 or compatible video |
92 | chipset. If M is selected the module will be called sis. AGP | 93 | chipset. If M is selected the module will be called sis. AGP |
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index e9f9a97ae00a..74da99495e21 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile | |||
@@ -4,8 +4,9 @@ | |||
4 | 4 | ||
5 | ccflags-y := -Iinclude/drm | 5 | ccflags-y := -Iinclude/drm |
6 | 6 | ||
7 | drm-y := drm_auth.o drm_bufs.o drm_context.o drm_dma.o drm_drawable.o \ | 7 | drm-y := drm_auth.o drm_bufs.o drm_cache.o \ |
8 | drm_drv.o drm_fops.o drm_ioctl.o drm_irq.o \ | 8 | drm_context.o drm_dma.o drm_drawable.o \ |
9 | drm_drv.o drm_fops.o drm_gem.o drm_ioctl.o drm_irq.o \ | ||
9 | drm_lock.o drm_memory.o drm_proc.o drm_stub.o drm_vm.o \ | 10 | drm_lock.o drm_memory.o drm_proc.o drm_stub.o drm_vm.o \ |
10 | drm_agpsupport.o drm_scatter.o ati_pcigart.o drm_pci.o \ | 11 | drm_agpsupport.o drm_scatter.o ati_pcigart.o drm_pci.o \ |
11 | drm_sysfs.o drm_hashtab.o drm_sman.o drm_mm.o | 12 | drm_sysfs.o drm_hashtab.o drm_sman.o drm_mm.o |
diff --git a/drivers/gpu/drm/drm_agpsupport.c b/drivers/gpu/drm/drm_agpsupport.c index aefa5ac4c0b1..3d33b8252b58 100644 --- a/drivers/gpu/drm/drm_agpsupport.c +++ b/drivers/gpu/drm/drm_agpsupport.c | |||
@@ -33,6 +33,7 @@ | |||
33 | 33 | ||
34 | #include "drmP.h" | 34 | #include "drmP.h" |
35 | #include <linux/module.h> | 35 | #include <linux/module.h> |
36 | #include <asm/agp.h> | ||
36 | 37 | ||
37 | #if __OS_HAS_AGP | 38 | #if __OS_HAS_AGP |
38 | 39 | ||
@@ -452,4 +453,53 @@ int drm_agp_unbind_memory(DRM_AGP_MEM * handle) | |||
452 | return agp_unbind_memory(handle); | 453 | return agp_unbind_memory(handle); |
453 | } | 454 | } |
454 | 455 | ||
455 | #endif /* __OS_HAS_AGP */ | 456 | /** |
457 | * Binds a collection of pages into AGP memory at the given offset, returning | ||
458 | * the AGP memory structure containing them. | ||
459 | * | ||
460 | * No reference is held on the pages during this time -- it is up to the | ||
461 | * caller to handle that. | ||
462 | */ | ||
463 | DRM_AGP_MEM * | ||
464 | drm_agp_bind_pages(struct drm_device *dev, | ||
465 | struct page **pages, | ||
466 | unsigned long num_pages, | ||
467 | uint32_t gtt_offset, | ||
468 | u32 type) | ||
469 | { | ||
470 | DRM_AGP_MEM *mem; | ||
471 | int ret, i; | ||
472 | |||
473 | DRM_DEBUG("\n"); | ||
474 | |||
475 | mem = drm_agp_allocate_memory(dev->agp->bridge, num_pages, | ||
476 | type); | ||
477 | if (mem == NULL) { | ||
478 | DRM_ERROR("Failed to allocate memory for %ld pages\n", | ||
479 | num_pages); | ||
480 | return NULL; | ||
481 | } | ||
482 | |||
483 | for (i = 0; i < num_pages; i++) | ||
484 | mem->memory[i] = phys_to_gart(page_to_phys(pages[i])); | ||
485 | mem->page_count = num_pages; | ||
486 | |||
487 | mem->is_flushed = true; | ||
488 | ret = drm_agp_bind_memory(mem, gtt_offset / PAGE_SIZE); | ||
489 | if (ret != 0) { | ||
490 | DRM_ERROR("Failed to bind AGP memory: %d\n", ret); | ||
491 | agp_free_memory(mem); | ||
492 | return NULL; | ||
493 | } | ||
494 | |||
495 | return mem; | ||
496 | } | ||
497 | EXPORT_SYMBOL(drm_agp_bind_pages); | ||
498 | |||
499 | void drm_agp_chipset_flush(struct drm_device *dev) | ||
500 | { | ||
501 | agp_flush_chipset(dev->agp->bridge); | ||
502 | } | ||
503 | EXPORT_SYMBOL(drm_agp_chipset_flush); | ||
504 | |||
505 | #endif /* __OS_HAS_AGP */ | ||
diff --git a/drivers/gpu/drm/drm_cache.c b/drivers/gpu/drm/drm_cache.c new file mode 100644 index 000000000000..0e994a0e46d4 --- /dev/null +++ b/drivers/gpu/drm/drm_cache.c | |||
@@ -0,0 +1,69 @@ | |||
1 | /************************************************************************** | ||
2 | * | ||
3 | * Copyright (c) 2006-2007 Tungsten Graphics, Inc., Cedar Park, TX., USA | ||
4 | * All Rights Reserved. | ||
5 | * | ||
6 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
7 | * copy of this software and associated documentation files (the | ||
8 | * "Software"), to deal in the Software without restriction, including | ||
9 | * without limitation the rights to use, copy, modify, merge, publish, | ||
10 | * distribute, sub license, and/or sell copies of the Software, and to | ||
11 | * permit persons to whom the Software is furnished to do so, subject to | ||
12 | * the following conditions: | ||
13 | * | ||
14 | * The above copyright notice and this permission notice (including the | ||
15 | * next paragraph) shall be included in all copies or substantial portions | ||
16 | * of the Software. | ||
17 | * | ||
18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
20 | * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | ||
21 | * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, | ||
22 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | ||
23 | * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | ||
24 | * USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
25 | * | ||
26 | **************************************************************************/ | ||
27 | /* | ||
28 | * Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com> | ||
29 | */ | ||
30 | |||
31 | #include "drmP.h" | ||
32 | |||
33 | #if defined(CONFIG_X86) | ||
34 | static void | ||
35 | drm_clflush_page(struct page *page) | ||
36 | { | ||
37 | uint8_t *page_virtual; | ||
38 | unsigned int i; | ||
39 | |||
40 | if (unlikely(page == NULL)) | ||
41 | return; | ||
42 | |||
43 | page_virtual = kmap_atomic(page, KM_USER0); | ||
44 | for (i = 0; i < PAGE_SIZE; i += boot_cpu_data.x86_clflush_size) | ||
45 | clflush(page_virtual + i); | ||
46 | kunmap_atomic(page_virtual, KM_USER0); | ||
47 | } | ||
48 | #endif | ||
49 | |||
50 | void | ||
51 | drm_clflush_pages(struct page *pages[], unsigned long num_pages) | ||
52 | { | ||
53 | |||
54 | #if defined(CONFIG_X86) | ||
55 | if (cpu_has_clflush) { | ||
56 | unsigned long i; | ||
57 | |||
58 | mb(); | ||
59 | for (i = 0; i < num_pages; ++i) | ||
60 | drm_clflush_page(*pages++); | ||
61 | mb(); | ||
62 | |||
63 | return; | ||
64 | } | ||
65 | |||
66 | wbinvd(); | ||
67 | #endif | ||
68 | } | ||
69 | EXPORT_SYMBOL(drm_clflush_pages); | ||
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 452c2d866ec5..96f416afc3f6 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c | |||
@@ -116,7 +116,13 @@ static struct drm_ioctl_desc drm_ioctls[] = { | |||
116 | 116 | ||
117 | DRM_IOCTL_DEF(DRM_IOCTL_WAIT_VBLANK, drm_wait_vblank, 0), | 117 | DRM_IOCTL_DEF(DRM_IOCTL_WAIT_VBLANK, drm_wait_vblank, 0), |
118 | 118 | ||
119 | DRM_IOCTL_DEF(DRM_IOCTL_MODESET_CTL, drm_modeset_ctl, 0), | ||
120 | |||
119 | DRM_IOCTL_DEF(DRM_IOCTL_UPDATE_DRAW, drm_update_drawable_info, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 121 | DRM_IOCTL_DEF(DRM_IOCTL_UPDATE_DRAW, drm_update_drawable_info, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
122 | |||
123 | DRM_IOCTL_DEF(DRM_IOCTL_GEM_CLOSE, drm_gem_close_ioctl, 0), | ||
124 | DRM_IOCTL_DEF(DRM_IOCTL_GEM_FLINK, drm_gem_flink_ioctl, DRM_AUTH), | ||
125 | DRM_IOCTL_DEF(DRM_IOCTL_GEM_OPEN, drm_gem_open_ioctl, DRM_AUTH), | ||
120 | }; | 126 | }; |
121 | 127 | ||
122 | #define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls ) | 128 | #define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls ) |
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c index 851a53f1acce..0d46627663b1 100644 --- a/drivers/gpu/drm/drm_fops.c +++ b/drivers/gpu/drm/drm_fops.c | |||
@@ -246,7 +246,7 @@ static int drm_open_helper(struct inode *inode, struct file *filp, | |||
246 | memset(priv, 0, sizeof(*priv)); | 246 | memset(priv, 0, sizeof(*priv)); |
247 | filp->private_data = priv; | 247 | filp->private_data = priv; |
248 | priv->filp = filp; | 248 | priv->filp = filp; |
249 | priv->uid = current->euid; | 249 | priv->uid = current_euid(); |
250 | priv->pid = task_pid_nr(current); | 250 | priv->pid = task_pid_nr(current); |
251 | priv->minor = idr_find(&drm_minors_idr, minor_id); | 251 | priv->minor = idr_find(&drm_minors_idr, minor_id); |
252 | priv->ioctl_count = 0; | 252 | priv->ioctl_count = 0; |
@@ -256,6 +256,9 @@ static int drm_open_helper(struct inode *inode, struct file *filp, | |||
256 | 256 | ||
257 | INIT_LIST_HEAD(&priv->lhead); | 257 | INIT_LIST_HEAD(&priv->lhead); |
258 | 258 | ||
259 | if (dev->driver->driver_features & DRIVER_GEM) | ||
260 | drm_gem_open(dev, priv); | ||
261 | |||
259 | if (dev->driver->open) { | 262 | if (dev->driver->open) { |
260 | ret = dev->driver->open(dev, priv); | 263 | ret = dev->driver->open(dev, priv); |
261 | if (ret < 0) | 264 | if (ret < 0) |
@@ -400,6 +403,9 @@ int drm_release(struct inode *inode, struct file *filp) | |||
400 | dev->driver->reclaim_buffers(dev, file_priv); | 403 | dev->driver->reclaim_buffers(dev, file_priv); |
401 | } | 404 | } |
402 | 405 | ||
406 | if (dev->driver->driver_features & DRIVER_GEM) | ||
407 | drm_gem_release(dev, file_priv); | ||
408 | |||
403 | drm_fasync(-1, filp, 0); | 409 | drm_fasync(-1, filp, 0); |
404 | 410 | ||
405 | mutex_lock(&dev->ctxlist_mutex); | 411 | mutex_lock(&dev->ctxlist_mutex); |
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c new file mode 100644 index 000000000000..ccd1afdede02 --- /dev/null +++ b/drivers/gpu/drm/drm_gem.c | |||
@@ -0,0 +1,421 @@ | |||
1 | /* | ||
2 | * Copyright © 2008 Intel Corporation | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice (including the next | ||
12 | * paragraph) shall be included in all copies or substantial portions of the | ||
13 | * Software. | ||
14 | * | ||
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||
21 | * IN THE SOFTWARE. | ||
22 | * | ||
23 | * Authors: | ||
24 | * Eric Anholt <eric@anholt.net> | ||
25 | * | ||
26 | */ | ||
27 | |||
28 | #include <linux/types.h> | ||
29 | #include <linux/slab.h> | ||
30 | #include <linux/mm.h> | ||
31 | #include <linux/uaccess.h> | ||
32 | #include <linux/fs.h> | ||
33 | #include <linux/file.h> | ||
34 | #include <linux/module.h> | ||
35 | #include <linux/mman.h> | ||
36 | #include <linux/pagemap.h> | ||
37 | #include "drmP.h" | ||
38 | |||
39 | /** @file drm_gem.c | ||
40 | * | ||
41 | * This file provides some of the base ioctls and library routines for | ||
42 | * the graphics memory manager implemented by each device driver. | ||
43 | * | ||
44 | * Because various devices have different requirements in terms of | ||
45 | * synchronization and migration strategies, implementing that is left up to | ||
46 | * the driver, and all that the general API provides should be generic -- | ||
47 | * allocating objects, reading/writing data with the cpu, freeing objects. | ||
48 | * Even there, platform-dependent optimizations for reading/writing data with | ||
49 | * the CPU mean we'll likely hook those out to driver-specific calls. However, | ||
50 | * the DRI2 implementation wants to have at least allocate/mmap be generic. | ||
51 | * | ||
52 | * The goal was to have swap-backed object allocation managed through | ||
53 | * struct file. However, file descriptors as handles to a struct file have | ||
54 | * two major failings: | ||
55 | * - Process limits prevent more than 1024 or so being used at a time by | ||
56 | * default. | ||
57 | * - Inability to allocate high fds will aggravate the X Server's select() | ||
58 | * handling, and likely that of many GL client applications as well. | ||
59 | * | ||
60 | * This led to a plan of using our own integer IDs (called handles, following | ||
61 | * DRM terminology) to mimic fds, and implement the fd syscalls we need as | ||
62 | * ioctls. The objects themselves will still include the struct file so | ||
63 | * that we can transition to fds if the required kernel infrastructure shows | ||
64 | * up at a later date, and as our interface with shmfs for memory allocation. | ||
65 | */ | ||
66 | |||
67 | /** | ||
68 | * Initialize the GEM device fields | ||
69 | */ | ||
70 | |||
71 | int | ||
72 | drm_gem_init(struct drm_device *dev) | ||
73 | { | ||
74 | spin_lock_init(&dev->object_name_lock); | ||
75 | idr_init(&dev->object_name_idr); | ||
76 | atomic_set(&dev->object_count, 0); | ||
77 | atomic_set(&dev->object_memory, 0); | ||
78 | atomic_set(&dev->pin_count, 0); | ||
79 | atomic_set(&dev->pin_memory, 0); | ||
80 | atomic_set(&dev->gtt_count, 0); | ||
81 | atomic_set(&dev->gtt_memory, 0); | ||
82 | return 0; | ||
83 | } | ||
84 | |||
85 | /** | ||
86 | * Allocate a GEM object of the specified size with shmfs backing store | ||
87 | */ | ||
88 | struct drm_gem_object * | ||
89 | drm_gem_object_alloc(struct drm_device *dev, size_t size) | ||
90 | { | ||
91 | struct drm_gem_object *obj; | ||
92 | |||
93 | BUG_ON((size & (PAGE_SIZE - 1)) != 0); | ||
94 | |||
95 | obj = kcalloc(1, sizeof(*obj), GFP_KERNEL); | ||
96 | |||
97 | obj->dev = dev; | ||
98 | obj->filp = shmem_file_setup("drm mm object", size, 0); | ||
99 | if (IS_ERR(obj->filp)) { | ||
100 | kfree(obj); | ||
101 | return NULL; | ||
102 | } | ||
103 | |||
104 | kref_init(&obj->refcount); | ||
105 | kref_init(&obj->handlecount); | ||
106 | obj->size = size; | ||
107 | if (dev->driver->gem_init_object != NULL && | ||
108 | dev->driver->gem_init_object(obj) != 0) { | ||
109 | fput(obj->filp); | ||
110 | kfree(obj); | ||
111 | return NULL; | ||
112 | } | ||
113 | atomic_inc(&dev->object_count); | ||
114 | atomic_add(obj->size, &dev->object_memory); | ||
115 | return obj; | ||
116 | } | ||
117 | EXPORT_SYMBOL(drm_gem_object_alloc); | ||
118 | |||
119 | /** | ||
120 | * Removes the mapping from handle to filp for this object. | ||
121 | */ | ||
122 | static int | ||
123 | drm_gem_handle_delete(struct drm_file *filp, int handle) | ||
124 | { | ||
125 | struct drm_device *dev; | ||
126 | struct drm_gem_object *obj; | ||
127 | |||
128 | /* This is gross. The idr system doesn't let us try a delete and | ||
129 | * return an error code. It just spews if you fail at deleting. | ||
130 | * So, we have to grab a lock around finding the object and then | ||
131 | * doing the delete on it and dropping the refcount, or the user | ||
132 | * could race us to double-decrement the refcount and cause a | ||
133 | * use-after-free later. Given the frequency of our handle lookups, | ||
134 | * we may want to use ida for number allocation and a hash table | ||
135 | * for the pointers, anyway. | ||
136 | */ | ||
137 | spin_lock(&filp->table_lock); | ||
138 | |||
139 | /* Check if we currently have a reference on the object */ | ||
140 | obj = idr_find(&filp->object_idr, handle); | ||
141 | if (obj == NULL) { | ||
142 | spin_unlock(&filp->table_lock); | ||
143 | return -EINVAL; | ||
144 | } | ||
145 | dev = obj->dev; | ||
146 | |||
147 | /* Release reference and decrement refcount. */ | ||
148 | idr_remove(&filp->object_idr, handle); | ||
149 | spin_unlock(&filp->table_lock); | ||
150 | |||
151 | mutex_lock(&dev->struct_mutex); | ||
152 | drm_gem_object_handle_unreference(obj); | ||
153 | mutex_unlock(&dev->struct_mutex); | ||
154 | |||
155 | return 0; | ||
156 | } | ||
157 | |||
158 | /** | ||
159 | * Create a handle for this object. This adds a handle reference | ||
160 | * to the object, which includes a regular reference count. Callers | ||
161 | * will likely want to dereference the object afterwards. | ||
162 | */ | ||
163 | int | ||
164 | drm_gem_handle_create(struct drm_file *file_priv, | ||
165 | struct drm_gem_object *obj, | ||
166 | int *handlep) | ||
167 | { | ||
168 | int ret; | ||
169 | |||
170 | /* | ||
171 | * Get the user-visible handle using idr. | ||
172 | */ | ||
173 | again: | ||
174 | /* ensure there is space available to allocate a handle */ | ||
175 | if (idr_pre_get(&file_priv->object_idr, GFP_KERNEL) == 0) | ||
176 | return -ENOMEM; | ||
177 | |||
178 | /* do the allocation under our spinlock */ | ||
179 | spin_lock(&file_priv->table_lock); | ||
180 | ret = idr_get_new_above(&file_priv->object_idr, obj, 1, handlep); | ||
181 | spin_unlock(&file_priv->table_lock); | ||
182 | if (ret == -EAGAIN) | ||
183 | goto again; | ||
184 | |||
185 | if (ret != 0) | ||
186 | return ret; | ||
187 | |||
188 | drm_gem_object_handle_reference(obj); | ||
189 | return 0; | ||
190 | } | ||
191 | EXPORT_SYMBOL(drm_gem_handle_create); | ||
192 | |||
193 | /** Returns a reference to the object named by the handle. */ | ||
194 | struct drm_gem_object * | ||
195 | drm_gem_object_lookup(struct drm_device *dev, struct drm_file *filp, | ||
196 | int handle) | ||
197 | { | ||
198 | struct drm_gem_object *obj; | ||
199 | |||
200 | spin_lock(&filp->table_lock); | ||
201 | |||
202 | /* Check if we currently have a reference on the object */ | ||
203 | obj = idr_find(&filp->object_idr, handle); | ||
204 | if (obj == NULL) { | ||
205 | spin_unlock(&filp->table_lock); | ||
206 | return NULL; | ||
207 | } | ||
208 | |||
209 | drm_gem_object_reference(obj); | ||
210 | |||
211 | spin_unlock(&filp->table_lock); | ||
212 | |||
213 | return obj; | ||
214 | } | ||
215 | EXPORT_SYMBOL(drm_gem_object_lookup); | ||
216 | |||
217 | /** | ||
218 | * Releases the handle to an mm object. | ||
219 | */ | ||
220 | int | ||
221 | drm_gem_close_ioctl(struct drm_device *dev, void *data, | ||
222 | struct drm_file *file_priv) | ||
223 | { | ||
224 | struct drm_gem_close *args = data; | ||
225 | int ret; | ||
226 | |||
227 | if (!(dev->driver->driver_features & DRIVER_GEM)) | ||
228 | return -ENODEV; | ||
229 | |||
230 | ret = drm_gem_handle_delete(file_priv, args->handle); | ||
231 | |||
232 | return ret; | ||
233 | } | ||
234 | |||
235 | /** | ||
236 | * Create a global name for an object, returning the name. | ||
237 | * | ||
238 | * Note that the name does not hold a reference; when the object | ||
239 | * is freed, the name goes away. | ||
240 | */ | ||
241 | int | ||
242 | drm_gem_flink_ioctl(struct drm_device *dev, void *data, | ||
243 | struct drm_file *file_priv) | ||
244 | { | ||
245 | struct drm_gem_flink *args = data; | ||
246 | struct drm_gem_object *obj; | ||
247 | int ret; | ||
248 | |||
249 | if (!(dev->driver->driver_features & DRIVER_GEM)) | ||
250 | return -ENODEV; | ||
251 | |||
252 | obj = drm_gem_object_lookup(dev, file_priv, args->handle); | ||
253 | if (obj == NULL) | ||
254 | return -EBADF; | ||
255 | |||
256 | again: | ||
257 | if (idr_pre_get(&dev->object_name_idr, GFP_KERNEL) == 0) | ||
258 | return -ENOMEM; | ||
259 | |||
260 | spin_lock(&dev->object_name_lock); | ||
261 | if (obj->name) { | ||
262 | args->name = obj->name; | ||
263 | spin_unlock(&dev->object_name_lock); | ||
264 | return 0; | ||
265 | } | ||
266 | ret = idr_get_new_above(&dev->object_name_idr, obj, 1, | ||
267 | &obj->name); | ||
268 | spin_unlock(&dev->object_name_lock); | ||
269 | if (ret == -EAGAIN) | ||
270 | goto again; | ||
271 | |||
272 | if (ret != 0) { | ||
273 | mutex_lock(&dev->struct_mutex); | ||
274 | drm_gem_object_unreference(obj); | ||
275 | mutex_unlock(&dev->struct_mutex); | ||
276 | return ret; | ||
277 | } | ||
278 | |||
279 | /* | ||
280 | * Leave the reference from the lookup around as the | ||
281 | * name table now holds one | ||
282 | */ | ||
283 | args->name = (uint64_t) obj->name; | ||
284 | |||
285 | return 0; | ||
286 | } | ||
287 | |||
288 | /** | ||
289 | * Open an object using the global name, returning a handle and the size. | ||
290 | * | ||
291 | * This handle (of course) holds a reference to the object, so the object | ||
292 | * will not go away until the handle is deleted. | ||
293 | */ | ||
294 | int | ||
295 | drm_gem_open_ioctl(struct drm_device *dev, void *data, | ||
296 | struct drm_file *file_priv) | ||
297 | { | ||
298 | struct drm_gem_open *args = data; | ||
299 | struct drm_gem_object *obj; | ||
300 | int ret; | ||
301 | int handle; | ||
302 | |||
303 | if (!(dev->driver->driver_features & DRIVER_GEM)) | ||
304 | return -ENODEV; | ||
305 | |||
306 | spin_lock(&dev->object_name_lock); | ||
307 | obj = idr_find(&dev->object_name_idr, (int) args->name); | ||
308 | if (obj) | ||
309 | drm_gem_object_reference(obj); | ||
310 | spin_unlock(&dev->object_name_lock); | ||
311 | if (!obj) | ||
312 | return -ENOENT; | ||
313 | |||
314 | ret = drm_gem_handle_create(file_priv, obj, &handle); | ||
315 | mutex_lock(&dev->struct_mutex); | ||
316 | drm_gem_object_unreference(obj); | ||
317 | mutex_unlock(&dev->struct_mutex); | ||
318 | if (ret) | ||
319 | return ret; | ||
320 | |||
321 | args->handle = handle; | ||
322 | args->size = obj->size; | ||
323 | |||
324 | return 0; | ||
325 | } | ||
326 | |||
327 | /** | ||
328 | * Called at device open time, sets up the structure for handling refcounting | ||
329 | * of mm objects. | ||
330 | */ | ||
331 | void | ||
332 | drm_gem_open(struct drm_device *dev, struct drm_file *file_private) | ||
333 | { | ||
334 | idr_init(&file_private->object_idr); | ||
335 | spin_lock_init(&file_private->table_lock); | ||
336 | } | ||
337 | |||
338 | /** | ||
339 | * Called at device close to release the file's | ||
340 | * handle references on objects. | ||
341 | */ | ||
342 | static int | ||
343 | drm_gem_object_release_handle(int id, void *ptr, void *data) | ||
344 | { | ||
345 | struct drm_gem_object *obj = ptr; | ||
346 | |||
347 | drm_gem_object_handle_unreference(obj); | ||
348 | |||
349 | return 0; | ||
350 | } | ||
351 | |||
352 | /** | ||
353 | * Called at close time when the filp is going away. | ||
354 | * | ||
355 | * Releases any remaining references on objects by this filp. | ||
356 | */ | ||
357 | void | ||
358 | drm_gem_release(struct drm_device *dev, struct drm_file *file_private) | ||
359 | { | ||
360 | mutex_lock(&dev->struct_mutex); | ||
361 | idr_for_each(&file_private->object_idr, | ||
362 | &drm_gem_object_release_handle, NULL); | ||
363 | |||
364 | idr_destroy(&file_private->object_idr); | ||
365 | mutex_unlock(&dev->struct_mutex); | ||
366 | } | ||
367 | |||
368 | /** | ||
369 | * Called after the last reference to the object has been lost. | ||
370 | * | ||
371 | * Frees the object | ||
372 | */ | ||
373 | void | ||
374 | drm_gem_object_free(struct kref *kref) | ||
375 | { | ||
376 | struct drm_gem_object *obj = (struct drm_gem_object *) kref; | ||
377 | struct drm_device *dev = obj->dev; | ||
378 | |||
379 | BUG_ON(!mutex_is_locked(&dev->struct_mutex)); | ||
380 | |||
381 | if (dev->driver->gem_free_object != NULL) | ||
382 | dev->driver->gem_free_object(obj); | ||
383 | |||
384 | fput(obj->filp); | ||
385 | atomic_dec(&dev->object_count); | ||
386 | atomic_sub(obj->size, &dev->object_memory); | ||
387 | kfree(obj); | ||
388 | } | ||
389 | EXPORT_SYMBOL(drm_gem_object_free); | ||
390 | |||
391 | /** | ||
392 | * Called after the last handle to the object has been closed | ||
393 | * | ||
394 | * Removes any name for the object. Note that this must be | ||
395 | * called before drm_gem_object_free or we'll be touching | ||
396 | * freed memory | ||
397 | */ | ||
398 | void | ||
399 | drm_gem_object_handle_free(struct kref *kref) | ||
400 | { | ||
401 | struct drm_gem_object *obj = container_of(kref, | ||
402 | struct drm_gem_object, | ||
403 | handlecount); | ||
404 | struct drm_device *dev = obj->dev; | ||
405 | |||
406 | /* Remove any name for this object */ | ||
407 | spin_lock(&dev->object_name_lock); | ||
408 | if (obj->name) { | ||
409 | idr_remove(&dev->object_name_idr, obj->name); | ||
410 | spin_unlock(&dev->object_name_lock); | ||
411 | /* | ||
412 | * The object name held a reference to this object, drop | ||
413 | * that now. | ||
414 | */ | ||
415 | drm_gem_object_unreference(obj); | ||
416 | } else | ||
417 | spin_unlock(&dev->object_name_lock); | ||
418 | |||
419 | } | ||
420 | EXPORT_SYMBOL(drm_gem_object_handle_free); | ||
421 | |||
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 53f0e5af1cc8..4091b9e291f9 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c | |||
@@ -63,7 +63,7 @@ int drm_irq_by_busid(struct drm_device *dev, void *data, | |||
63 | p->devnum != PCI_SLOT(dev->pdev->devfn) || p->funcnum != PCI_FUNC(dev->pdev->devfn)) | 63 | p->devnum != PCI_SLOT(dev->pdev->devfn) || p->funcnum != PCI_FUNC(dev->pdev->devfn)) |
64 | return -EINVAL; | 64 | return -EINVAL; |
65 | 65 | ||
66 | p->irq = dev->irq; | 66 | p->irq = dev->pdev->irq; |
67 | 67 | ||
68 | DRM_DEBUG("%d:%d:%d => IRQ %d\n", p->busnum, p->devnum, p->funcnum, | 68 | DRM_DEBUG("%d:%d:%d => IRQ %d\n", p->busnum, p->devnum, p->funcnum, |
69 | p->irq); | 69 | p->irq); |
@@ -71,25 +71,137 @@ int drm_irq_by_busid(struct drm_device *dev, void *data, | |||
71 | return 0; | 71 | return 0; |
72 | } | 72 | } |
73 | 73 | ||
74 | static void vblank_disable_fn(unsigned long arg) | ||
75 | { | ||
76 | struct drm_device *dev = (struct drm_device *)arg; | ||
77 | unsigned long irqflags; | ||
78 | int i; | ||
79 | |||
80 | if (!dev->vblank_disable_allowed) | ||
81 | return; | ||
82 | |||
83 | for (i = 0; i < dev->num_crtcs; i++) { | ||
84 | spin_lock_irqsave(&dev->vbl_lock, irqflags); | ||
85 | if (atomic_read(&dev->vblank_refcount[i]) == 0 && | ||
86 | dev->vblank_enabled[i]) { | ||
87 | DRM_DEBUG("disabling vblank on crtc %d\n", i); | ||
88 | dev->last_vblank[i] = | ||
89 | dev->driver->get_vblank_counter(dev, i); | ||
90 | dev->driver->disable_vblank(dev, i); | ||
91 | dev->vblank_enabled[i] = 0; | ||
92 | } | ||
93 | spin_unlock_irqrestore(&dev->vbl_lock, irqflags); | ||
94 | } | ||
95 | } | ||
96 | |||
97 | static void drm_vblank_cleanup(struct drm_device *dev) | ||
98 | { | ||
99 | /* Bail if the driver didn't call drm_vblank_init() */ | ||
100 | if (dev->num_crtcs == 0) | ||
101 | return; | ||
102 | |||
103 | del_timer(&dev->vblank_disable_timer); | ||
104 | |||
105 | vblank_disable_fn((unsigned long)dev); | ||
106 | |||
107 | drm_free(dev->vbl_queue, sizeof(*dev->vbl_queue) * dev->num_crtcs, | ||
108 | DRM_MEM_DRIVER); | ||
109 | drm_free(dev->vbl_sigs, sizeof(*dev->vbl_sigs) * dev->num_crtcs, | ||
110 | DRM_MEM_DRIVER); | ||
111 | drm_free(dev->_vblank_count, sizeof(*dev->_vblank_count) * | ||
112 | dev->num_crtcs, DRM_MEM_DRIVER); | ||
113 | drm_free(dev->vblank_refcount, sizeof(*dev->vblank_refcount) * | ||
114 | dev->num_crtcs, DRM_MEM_DRIVER); | ||
115 | drm_free(dev->vblank_enabled, sizeof(*dev->vblank_enabled) * | ||
116 | dev->num_crtcs, DRM_MEM_DRIVER); | ||
117 | drm_free(dev->last_vblank, sizeof(*dev->last_vblank) * dev->num_crtcs, | ||
118 | DRM_MEM_DRIVER); | ||
119 | drm_free(dev->vblank_inmodeset, sizeof(*dev->vblank_inmodeset) * | ||
120 | dev->num_crtcs, DRM_MEM_DRIVER); | ||
121 | |||
122 | dev->num_crtcs = 0; | ||
123 | } | ||
124 | |||
125 | int drm_vblank_init(struct drm_device *dev, int num_crtcs) | ||
126 | { | ||
127 | int i, ret = -ENOMEM; | ||
128 | |||
129 | setup_timer(&dev->vblank_disable_timer, vblank_disable_fn, | ||
130 | (unsigned long)dev); | ||
131 | spin_lock_init(&dev->vbl_lock); | ||
132 | atomic_set(&dev->vbl_signal_pending, 0); | ||
133 | dev->num_crtcs = num_crtcs; | ||
134 | |||
135 | dev->vbl_queue = drm_alloc(sizeof(wait_queue_head_t) * num_crtcs, | ||
136 | DRM_MEM_DRIVER); | ||
137 | if (!dev->vbl_queue) | ||
138 | goto err; | ||
139 | |||
140 | dev->vbl_sigs = drm_alloc(sizeof(struct list_head) * num_crtcs, | ||
141 | DRM_MEM_DRIVER); | ||
142 | if (!dev->vbl_sigs) | ||
143 | goto err; | ||
144 | |||
145 | dev->_vblank_count = drm_alloc(sizeof(atomic_t) * num_crtcs, | ||
146 | DRM_MEM_DRIVER); | ||
147 | if (!dev->_vblank_count) | ||
148 | goto err; | ||
149 | |||
150 | dev->vblank_refcount = drm_alloc(sizeof(atomic_t) * num_crtcs, | ||
151 | DRM_MEM_DRIVER); | ||
152 | if (!dev->vblank_refcount) | ||
153 | goto err; | ||
154 | |||
155 | dev->vblank_enabled = drm_calloc(num_crtcs, sizeof(int), | ||
156 | DRM_MEM_DRIVER); | ||
157 | if (!dev->vblank_enabled) | ||
158 | goto err; | ||
159 | |||
160 | dev->last_vblank = drm_calloc(num_crtcs, sizeof(u32), DRM_MEM_DRIVER); | ||
161 | if (!dev->last_vblank) | ||
162 | goto err; | ||
163 | |||
164 | dev->vblank_inmodeset = drm_calloc(num_crtcs, sizeof(int), | ||
165 | DRM_MEM_DRIVER); | ||
166 | if (!dev->vblank_inmodeset) | ||
167 | goto err; | ||
168 | |||
169 | /* Zero per-crtc vblank stuff */ | ||
170 | for (i = 0; i < num_crtcs; i++) { | ||
171 | init_waitqueue_head(&dev->vbl_queue[i]); | ||
172 | INIT_LIST_HEAD(&dev->vbl_sigs[i]); | ||
173 | atomic_set(&dev->_vblank_count[i], 0); | ||
174 | atomic_set(&dev->vblank_refcount[i], 0); | ||
175 | } | ||
176 | |||
177 | dev->vblank_disable_allowed = 0; | ||
178 | |||
179 | return 0; | ||
180 | |||
181 | err: | ||
182 | drm_vblank_cleanup(dev); | ||
183 | return ret; | ||
184 | } | ||
185 | EXPORT_SYMBOL(drm_vblank_init); | ||
186 | |||
74 | /** | 187 | /** |
75 | * Install IRQ handler. | 188 | * Install IRQ handler. |
76 | * | 189 | * |
77 | * \param dev DRM device. | 190 | * \param dev DRM device. |
78 | * \param irq IRQ number. | ||
79 | * | 191 | * |
80 | * Initializes the IRQ related data, and setups drm_device::vbl_queue. Installs the handler, calling the driver | 192 | * Initializes the IRQ related data. Installs the handler, calling the driver |
81 | * \c drm_driver_irq_preinstall() and \c drm_driver_irq_postinstall() functions | 193 | * \c drm_driver_irq_preinstall() and \c drm_driver_irq_postinstall() functions |
82 | * before and after the installation. | 194 | * before and after the installation. |
83 | */ | 195 | */ |
84 | static int drm_irq_install(struct drm_device * dev) | 196 | int drm_irq_install(struct drm_device *dev) |
85 | { | 197 | { |
86 | int ret; | 198 | int ret = 0; |
87 | unsigned long sh_flags = 0; | 199 | unsigned long sh_flags = 0; |
88 | 200 | ||
89 | if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ)) | 201 | if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ)) |
90 | return -EINVAL; | 202 | return -EINVAL; |
91 | 203 | ||
92 | if (dev->irq == 0) | 204 | if (dev->pdev->irq == 0) |
93 | return -EINVAL; | 205 | return -EINVAL; |
94 | 206 | ||
95 | mutex_lock(&dev->struct_mutex); | 207 | mutex_lock(&dev->struct_mutex); |
@@ -107,18 +219,7 @@ static int drm_irq_install(struct drm_device * dev) | |||
107 | dev->irq_enabled = 1; | 219 | dev->irq_enabled = 1; |
108 | mutex_unlock(&dev->struct_mutex); | 220 | mutex_unlock(&dev->struct_mutex); |
109 | 221 | ||
110 | DRM_DEBUG("irq=%d\n", dev->irq); | 222 | DRM_DEBUG("irq=%d\n", dev->pdev->irq); |
111 | |||
112 | if (drm_core_check_feature(dev, DRIVER_IRQ_VBL)) { | ||
113 | init_waitqueue_head(&dev->vbl_queue); | ||
114 | |||
115 | spin_lock_init(&dev->vbl_lock); | ||
116 | |||
117 | INIT_LIST_HEAD(&dev->vbl_sigs); | ||
118 | INIT_LIST_HEAD(&dev->vbl_sigs2); | ||
119 | |||
120 | dev->vbl_pending = 0; | ||
121 | } | ||
122 | 223 | ||
123 | /* Before installing handler */ | 224 | /* Before installing handler */ |
124 | dev->driver->irq_preinstall(dev); | 225 | dev->driver->irq_preinstall(dev); |
@@ -127,8 +228,9 @@ static int drm_irq_install(struct drm_device * dev) | |||
127 | if (drm_core_check_feature(dev, DRIVER_IRQ_SHARED)) | 228 | if (drm_core_check_feature(dev, DRIVER_IRQ_SHARED)) |
128 | sh_flags = IRQF_SHARED; | 229 | sh_flags = IRQF_SHARED; |
129 | 230 | ||
130 | ret = request_irq(dev->irq, dev->driver->irq_handler, | 231 | ret = request_irq(drm_dev_to_irq(dev), dev->driver->irq_handler, |
131 | sh_flags, dev->devname, dev); | 232 | sh_flags, dev->devname, dev); |
233 | |||
132 | if (ret < 0) { | 234 | if (ret < 0) { |
133 | mutex_lock(&dev->struct_mutex); | 235 | mutex_lock(&dev->struct_mutex); |
134 | dev->irq_enabled = 0; | 236 | dev->irq_enabled = 0; |
@@ -137,10 +239,16 @@ static int drm_irq_install(struct drm_device * dev) | |||
137 | } | 239 | } |
138 | 240 | ||
139 | /* After installing handler */ | 241 | /* After installing handler */ |
140 | dev->driver->irq_postinstall(dev); | 242 | ret = dev->driver->irq_postinstall(dev); |
243 | if (ret < 0) { | ||
244 | mutex_lock(&dev->struct_mutex); | ||
245 | dev->irq_enabled = 0; | ||
246 | mutex_unlock(&dev->struct_mutex); | ||
247 | } | ||
141 | 248 | ||
142 | return 0; | 249 | return ret; |
143 | } | 250 | } |
251 | EXPORT_SYMBOL(drm_irq_install); | ||
144 | 252 | ||
145 | /** | 253 | /** |
146 | * Uninstall the IRQ handler. | 254 | * Uninstall the IRQ handler. |
@@ -164,17 +272,18 @@ int drm_irq_uninstall(struct drm_device * dev) | |||
164 | if (!irq_enabled) | 272 | if (!irq_enabled) |
165 | return -EINVAL; | 273 | return -EINVAL; |
166 | 274 | ||
167 | DRM_DEBUG("irq=%d\n", dev->irq); | 275 | DRM_DEBUG("irq=%d\n", dev->pdev->irq); |
168 | 276 | ||
169 | dev->driver->irq_uninstall(dev); | 277 | dev->driver->irq_uninstall(dev); |
170 | 278 | ||
171 | free_irq(dev->irq, dev); | 279 | free_irq(dev->pdev->irq, dev); |
280 | |||
281 | drm_vblank_cleanup(dev); | ||
172 | 282 | ||
173 | dev->locked_tasklet_func = NULL; | 283 | dev->locked_tasklet_func = NULL; |
174 | 284 | ||
175 | return 0; | 285 | return 0; |
176 | } | 286 | } |
177 | |||
178 | EXPORT_SYMBOL(drm_irq_uninstall); | 287 | EXPORT_SYMBOL(drm_irq_uninstall); |
179 | 288 | ||
180 | /** | 289 | /** |
@@ -201,7 +310,7 @@ int drm_control(struct drm_device *dev, void *data, | |||
201 | if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ)) | 310 | if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ)) |
202 | return 0; | 311 | return 0; |
203 | if (dev->if_version < DRM_IF_VERSION(1, 2) && | 312 | if (dev->if_version < DRM_IF_VERSION(1, 2) && |
204 | ctl->irq != dev->irq) | 313 | ctl->irq != dev->pdev->irq) |
205 | return -EINVAL; | 314 | return -EINVAL; |
206 | return drm_irq_install(dev); | 315 | return drm_irq_install(dev); |
207 | case DRM_UNINST_HANDLER: | 316 | case DRM_UNINST_HANDLER: |
@@ -214,6 +323,174 @@ int drm_control(struct drm_device *dev, void *data, | |||
214 | } | 323 | } |
215 | 324 | ||
216 | /** | 325 | /** |
326 | * drm_vblank_count - retrieve "cooked" vblank counter value | ||
327 | * @dev: DRM device | ||
328 | * @crtc: which counter to retrieve | ||
329 | * | ||
330 | * Fetches the "cooked" vblank count value that represents the number of | ||
331 | * vblank events since the system was booted, including lost events due to | ||
332 | * modesetting activity. | ||
333 | */ | ||
334 | u32 drm_vblank_count(struct drm_device *dev, int crtc) | ||
335 | { | ||
336 | return atomic_read(&dev->_vblank_count[crtc]); | ||
337 | } | ||
338 | EXPORT_SYMBOL(drm_vblank_count); | ||
339 | |||
340 | /** | ||
341 | * drm_update_vblank_count - update the master vblank counter | ||
342 | * @dev: DRM device | ||
343 | * @crtc: counter to update | ||
344 | * | ||
345 | * Call back into the driver to update the appropriate vblank counter | ||
346 | * (specified by @crtc). Deal with wraparound, if it occurred, and | ||
347 | * update the last read value so we can deal with wraparound on the next | ||
348 | * call if necessary. | ||
349 | * | ||
350 | * Only necessary when going from off->on, to account for frames we | ||
351 | * didn't get an interrupt for. | ||
352 | * | ||
353 | * Note: caller must hold dev->vbl_lock since this reads & writes | ||
354 | * device vblank fields. | ||
355 | */ | ||
356 | static void drm_update_vblank_count(struct drm_device *dev, int crtc) | ||
357 | { | ||
358 | u32 cur_vblank, diff; | ||
359 | |||
360 | /* | ||
361 | * Interrupts were disabled prior to this call, so deal with counter | ||
362 | * wrap if needed. | ||
363 | * NOTE! It's possible we lost a full dev->max_vblank_count events | ||
364 | * here if the register is small or we had vblank interrupts off for | ||
365 | * a long time. | ||
366 | */ | ||
367 | cur_vblank = dev->driver->get_vblank_counter(dev, crtc); | ||
368 | diff = cur_vblank - dev->last_vblank[crtc]; | ||
369 | if (cur_vblank < dev->last_vblank[crtc]) { | ||
370 | diff += dev->max_vblank_count; | ||
371 | |||
372 | DRM_DEBUG("last_vblank[%d]=0x%x, cur_vblank=0x%x => diff=0x%x\n", | ||
373 | crtc, dev->last_vblank[crtc], cur_vblank, diff); | ||
374 | } | ||
375 | |||
376 | DRM_DEBUG("enabling vblank interrupts on crtc %d, missed %d\n", | ||
377 | crtc, diff); | ||
378 | |||
379 | atomic_add(diff, &dev->_vblank_count[crtc]); | ||
380 | } | ||
381 | |||
382 | /** | ||
383 | * drm_vblank_get - get a reference count on vblank events | ||
384 | * @dev: DRM device | ||
385 | * @crtc: which CRTC to own | ||
386 | * | ||
387 | * Acquire a reference count on vblank events to avoid having them disabled | ||
388 | * while in use. | ||
389 | * | ||
390 | * RETURNS | ||
391 | * Zero on success, nonzero on failure. | ||
392 | */ | ||
393 | int drm_vblank_get(struct drm_device *dev, int crtc) | ||
394 | { | ||
395 | unsigned long irqflags; | ||
396 | int ret = 0; | ||
397 | |||
398 | spin_lock_irqsave(&dev->vbl_lock, irqflags); | ||
399 | /* Going from 0->1 means we have to enable interrupts again */ | ||
400 | if (atomic_add_return(1, &dev->vblank_refcount[crtc]) == 1 && | ||
401 | !dev->vblank_enabled[crtc]) { | ||
402 | ret = dev->driver->enable_vblank(dev, crtc); | ||
403 | DRM_DEBUG("enabling vblank on crtc %d, ret: %d\n", crtc, ret); | ||
404 | if (ret) | ||
405 | atomic_dec(&dev->vblank_refcount[crtc]); | ||
406 | else { | ||
407 | dev->vblank_enabled[crtc] = 1; | ||
408 | drm_update_vblank_count(dev, crtc); | ||
409 | } | ||
410 | } | ||
411 | spin_unlock_irqrestore(&dev->vbl_lock, irqflags); | ||
412 | |||
413 | return ret; | ||
414 | } | ||
415 | EXPORT_SYMBOL(drm_vblank_get); | ||
416 | |||
417 | /** | ||
418 | * drm_vblank_put - give up ownership of vblank events | ||
419 | * @dev: DRM device | ||
420 | * @crtc: which counter to give up | ||
421 | * | ||
422 | * Release ownership of a given vblank counter, turning off interrupts | ||
423 | * if possible. | ||
424 | */ | ||
425 | void drm_vblank_put(struct drm_device *dev, int crtc) | ||
426 | { | ||
427 | /* Last user schedules interrupt disable */ | ||
428 | if (atomic_dec_and_test(&dev->vblank_refcount[crtc])) | ||
429 | mod_timer(&dev->vblank_disable_timer, jiffies + 5*DRM_HZ); | ||
430 | } | ||
431 | EXPORT_SYMBOL(drm_vblank_put); | ||
432 | |||
433 | /** | ||
434 | * drm_modeset_ctl - handle vblank event counter changes across mode switch | ||
435 | * @DRM_IOCTL_ARGS: standard ioctl arguments | ||
436 | * | ||
437 | * Applications should call the %_DRM_PRE_MODESET and %_DRM_POST_MODESET | ||
438 | * ioctls around modesetting so that any lost vblank events are accounted for. | ||
439 | * | ||
440 | * Generally the counter will reset across mode sets. If interrupts are | ||
441 | * enabled around this call, we don't have to do anything since the counter | ||
442 | * will have already been incremented. | ||
443 | */ | ||
444 | int drm_modeset_ctl(struct drm_device *dev, void *data, | ||
445 | struct drm_file *file_priv) | ||
446 | { | ||
447 | struct drm_modeset_ctl *modeset = data; | ||
448 | unsigned long irqflags; | ||
449 | int crtc, ret = 0; | ||
450 | |||
451 | /* If drm_vblank_init() hasn't been called yet, just no-op */ | ||
452 | if (!dev->num_crtcs) | ||
453 | goto out; | ||
454 | |||
455 | crtc = modeset->crtc; | ||
456 | if (crtc >= dev->num_crtcs) { | ||
457 | ret = -EINVAL; | ||
458 | goto out; | ||
459 | } | ||
460 | |||
461 | /* | ||
462 | * To avoid all the problems that might happen if interrupts | ||
463 | * were enabled/disabled around or between these calls, we just | ||
464 | * have the kernel take a reference on the CRTC (just once though | ||
465 | * to avoid corrupting the count if multiple, mismatch calls occur), | ||
466 | * so that interrupts remain enabled in the interim. | ||
467 | */ | ||
468 | switch (modeset->cmd) { | ||
469 | case _DRM_PRE_MODESET: | ||
470 | if (!dev->vblank_inmodeset[crtc]) { | ||
471 | dev->vblank_inmodeset[crtc] = 1; | ||
472 | drm_vblank_get(dev, crtc); | ||
473 | } | ||
474 | break; | ||
475 | case _DRM_POST_MODESET: | ||
476 | if (dev->vblank_inmodeset[crtc]) { | ||
477 | spin_lock_irqsave(&dev->vbl_lock, irqflags); | ||
478 | dev->vblank_disable_allowed = 1; | ||
479 | dev->vblank_inmodeset[crtc] = 0; | ||
480 | spin_unlock_irqrestore(&dev->vbl_lock, irqflags); | ||
481 | drm_vblank_put(dev, crtc); | ||
482 | } | ||
483 | break; | ||
484 | default: | ||
485 | ret = -EINVAL; | ||
486 | break; | ||
487 | } | ||
488 | |||
489 | out: | ||
490 | return ret; | ||
491 | } | ||
492 | |||
493 | /** | ||
217 | * Wait for VBLANK. | 494 | * Wait for VBLANK. |
218 | * | 495 | * |
219 | * \param inode device inode. | 496 | * \param inode device inode. |
@@ -232,14 +509,14 @@ int drm_control(struct drm_device *dev, void *data, | |||
232 | * | 509 | * |
233 | * If a signal is not requested, then calls vblank_wait(). | 510 | * If a signal is not requested, then calls vblank_wait(). |
234 | */ | 511 | */ |
235 | int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_priv) | 512 | int drm_wait_vblank(struct drm_device *dev, void *data, |
513 | struct drm_file *file_priv) | ||
236 | { | 514 | { |
237 | union drm_wait_vblank *vblwait = data; | 515 | union drm_wait_vblank *vblwait = data; |
238 | struct timeval now; | ||
239 | int ret = 0; | 516 | int ret = 0; |
240 | unsigned int flags, seq; | 517 | unsigned int flags, seq, crtc; |
241 | 518 | ||
242 | if ((!dev->irq) || (!dev->irq_enabled)) | 519 | if ((!dev->pdev->irq) || (!dev->irq_enabled)) |
243 | return -EINVAL; | 520 | return -EINVAL; |
244 | 521 | ||
245 | if (vblwait->request.type & | 522 | if (vblwait->request.type & |
@@ -251,13 +528,17 @@ int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_pr | |||
251 | } | 528 | } |
252 | 529 | ||
253 | flags = vblwait->request.type & _DRM_VBLANK_FLAGS_MASK; | 530 | flags = vblwait->request.type & _DRM_VBLANK_FLAGS_MASK; |
531 | crtc = flags & _DRM_VBLANK_SECONDARY ? 1 : 0; | ||
254 | 532 | ||
255 | if (!drm_core_check_feature(dev, (flags & _DRM_VBLANK_SECONDARY) ? | 533 | if (crtc >= dev->num_crtcs) |
256 | DRIVER_IRQ_VBL2 : DRIVER_IRQ_VBL)) | ||
257 | return -EINVAL; | 534 | return -EINVAL; |
258 | 535 | ||
259 | seq = atomic_read((flags & _DRM_VBLANK_SECONDARY) ? &dev->vbl_received2 | 536 | ret = drm_vblank_get(dev, crtc); |
260 | : &dev->vbl_received); | 537 | if (ret) { |
538 | DRM_ERROR("failed to acquire vblank counter, %d\n", ret); | ||
539 | return ret; | ||
540 | } | ||
541 | seq = drm_vblank_count(dev, crtc); | ||
261 | 542 | ||
262 | switch (vblwait->request.type & _DRM_VBLANK_TYPES_MASK) { | 543 | switch (vblwait->request.type & _DRM_VBLANK_TYPES_MASK) { |
263 | case _DRM_VBLANK_RELATIVE: | 544 | case _DRM_VBLANK_RELATIVE: |
@@ -266,7 +547,8 @@ int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_pr | |||
266 | case _DRM_VBLANK_ABSOLUTE: | 547 | case _DRM_VBLANK_ABSOLUTE: |
267 | break; | 548 | break; |
268 | default: | 549 | default: |
269 | return -EINVAL; | 550 | ret = -EINVAL; |
551 | goto done; | ||
270 | } | 552 | } |
271 | 553 | ||
272 | if ((flags & _DRM_VBLANK_NEXTONMISS) && | 554 | if ((flags & _DRM_VBLANK_NEXTONMISS) && |
@@ -276,8 +558,7 @@ int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_pr | |||
276 | 558 | ||
277 | if (flags & _DRM_VBLANK_SIGNAL) { | 559 | if (flags & _DRM_VBLANK_SIGNAL) { |
278 | unsigned long irqflags; | 560 | unsigned long irqflags; |
279 | struct list_head *vbl_sigs = (flags & _DRM_VBLANK_SECONDARY) | 561 | struct list_head *vbl_sigs = &dev->vbl_sigs[crtc]; |
280 | ? &dev->vbl_sigs2 : &dev->vbl_sigs; | ||
281 | struct drm_vbl_sig *vbl_sig; | 562 | struct drm_vbl_sig *vbl_sig; |
282 | 563 | ||
283 | spin_lock_irqsave(&dev->vbl_lock, irqflags); | 564 | spin_lock_irqsave(&dev->vbl_lock, irqflags); |
@@ -298,22 +579,29 @@ int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_pr | |||
298 | } | 579 | } |
299 | } | 580 | } |
300 | 581 | ||
301 | if (dev->vbl_pending >= 100) { | 582 | if (atomic_read(&dev->vbl_signal_pending) >= 100) { |
302 | spin_unlock_irqrestore(&dev->vbl_lock, irqflags); | 583 | spin_unlock_irqrestore(&dev->vbl_lock, irqflags); |
303 | return -EBUSY; | 584 | ret = -EBUSY; |
585 | goto done; | ||
304 | } | 586 | } |
305 | 587 | ||
306 | dev->vbl_pending++; | ||
307 | |||
308 | spin_unlock_irqrestore(&dev->vbl_lock, irqflags); | 588 | spin_unlock_irqrestore(&dev->vbl_lock, irqflags); |
309 | 589 | ||
310 | if (! | 590 | vbl_sig = drm_calloc(1, sizeof(struct drm_vbl_sig), |
311 | (vbl_sig = | 591 | DRM_MEM_DRIVER); |
312 | drm_alloc(sizeof(struct drm_vbl_sig), DRM_MEM_DRIVER))) { | 592 | if (!vbl_sig) { |
313 | return -ENOMEM; | 593 | ret = -ENOMEM; |
594 | goto done; | ||
595 | } | ||
596 | |||
597 | ret = drm_vblank_get(dev, crtc); | ||
598 | if (ret) { | ||
599 | drm_free(vbl_sig, sizeof(struct drm_vbl_sig), | ||
600 | DRM_MEM_DRIVER); | ||
601 | return ret; | ||
314 | } | 602 | } |
315 | 603 | ||
316 | memset((void *)vbl_sig, 0, sizeof(*vbl_sig)); | 604 | atomic_inc(&dev->vbl_signal_pending); |
317 | 605 | ||
318 | vbl_sig->sequence = vblwait->request.sequence; | 606 | vbl_sig->sequence = vblwait->request.sequence; |
319 | vbl_sig->info.si_signo = vblwait->request.signal; | 607 | vbl_sig->info.si_signo = vblwait->request.signal; |
@@ -327,20 +615,29 @@ int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_pr | |||
327 | 615 | ||
328 | vblwait->reply.sequence = seq; | 616 | vblwait->reply.sequence = seq; |
329 | } else { | 617 | } else { |
330 | if (flags & _DRM_VBLANK_SECONDARY) { | 618 | DRM_DEBUG("waiting on vblank count %d, crtc %d\n", |
331 | if (dev->driver->vblank_wait2) | 619 | vblwait->request.sequence, crtc); |
332 | ret = dev->driver->vblank_wait2(dev, &vblwait->request.sequence); | 620 | DRM_WAIT_ON(ret, dev->vbl_queue[crtc], 3 * DRM_HZ, |
333 | } else if (dev->driver->vblank_wait) | 621 | ((drm_vblank_count(dev, crtc) |
334 | ret = | 622 | - vblwait->request.sequence) <= (1 << 23))); |
335 | dev->driver->vblank_wait(dev, | 623 | |
336 | &vblwait->request.sequence); | 624 | if (ret != -EINTR) { |
337 | 625 | struct timeval now; | |
338 | do_gettimeofday(&now); | 626 | |
339 | vblwait->reply.tval_sec = now.tv_sec; | 627 | do_gettimeofday(&now); |
340 | vblwait->reply.tval_usec = now.tv_usec; | 628 | |
629 | vblwait->reply.tval_sec = now.tv_sec; | ||
630 | vblwait->reply.tval_usec = now.tv_usec; | ||
631 | vblwait->reply.sequence = drm_vblank_count(dev, crtc); | ||
632 | DRM_DEBUG("returning %d to client\n", | ||
633 | vblwait->reply.sequence); | ||
634 | } else { | ||
635 | DRM_DEBUG("vblank wait interrupted by signal\n"); | ||
636 | } | ||
341 | } | 637 | } |
342 | 638 | ||
343 | done: | 639 | done: |
640 | drm_vblank_put(dev, crtc); | ||
344 | return ret; | 641 | return ret; |
345 | } | 642 | } |
346 | 643 | ||
@@ -348,44 +645,57 @@ int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_pr | |||
348 | * Send the VBLANK signals. | 645 | * Send the VBLANK signals. |
349 | * | 646 | * |
350 | * \param dev DRM device. | 647 | * \param dev DRM device. |
648 | * \param crtc CRTC where the vblank event occurred | ||
351 | * | 649 | * |
352 | * Sends a signal for each task in drm_device::vbl_sigs and empties the list. | 650 | * Sends a signal for each task in drm_device::vbl_sigs and empties the list. |
353 | * | 651 | * |
354 | * If a signal is not requested, then calls vblank_wait(). | 652 | * If a signal is not requested, then calls vblank_wait(). |
355 | */ | 653 | */ |
356 | void drm_vbl_send_signals(struct drm_device * dev) | 654 | static void drm_vbl_send_signals(struct drm_device *dev, int crtc) |
357 | { | 655 | { |
656 | struct drm_vbl_sig *vbl_sig, *tmp; | ||
657 | struct list_head *vbl_sigs; | ||
658 | unsigned int vbl_seq; | ||
358 | unsigned long flags; | 659 | unsigned long flags; |
359 | int i; | ||
360 | 660 | ||
361 | spin_lock_irqsave(&dev->vbl_lock, flags); | 661 | spin_lock_irqsave(&dev->vbl_lock, flags); |
362 | 662 | ||
363 | for (i = 0; i < 2; i++) { | 663 | vbl_sigs = &dev->vbl_sigs[crtc]; |
364 | struct drm_vbl_sig *vbl_sig, *tmp; | 664 | vbl_seq = drm_vblank_count(dev, crtc); |
365 | struct list_head *vbl_sigs = i ? &dev->vbl_sigs2 : &dev->vbl_sigs; | ||
366 | unsigned int vbl_seq = atomic_read(i ? &dev->vbl_received2 : | ||
367 | &dev->vbl_received); | ||
368 | 665 | ||
369 | list_for_each_entry_safe(vbl_sig, tmp, vbl_sigs, head) { | 666 | list_for_each_entry_safe(vbl_sig, tmp, vbl_sigs, head) { |
370 | if ((vbl_seq - vbl_sig->sequence) <= (1 << 23)) { | 667 | if ((vbl_seq - vbl_sig->sequence) <= (1 << 23)) { |
371 | vbl_sig->info.si_code = vbl_seq; | 668 | vbl_sig->info.si_code = vbl_seq; |
372 | send_sig_info(vbl_sig->info.si_signo, | 669 | send_sig_info(vbl_sig->info.si_signo, |
373 | &vbl_sig->info, vbl_sig->task); | 670 | &vbl_sig->info, vbl_sig->task); |
374 | 671 | ||
375 | list_del(&vbl_sig->head); | 672 | list_del(&vbl_sig->head); |
376 | |||
377 | drm_free(vbl_sig, sizeof(*vbl_sig), | ||
378 | DRM_MEM_DRIVER); | ||
379 | 673 | ||
380 | dev->vbl_pending--; | 674 | drm_free(vbl_sig, sizeof(*vbl_sig), |
381 | } | 675 | DRM_MEM_DRIVER); |
382 | } | 676 | atomic_dec(&dev->vbl_signal_pending); |
677 | drm_vblank_put(dev, crtc); | ||
678 | } | ||
383 | } | 679 | } |
384 | 680 | ||
385 | spin_unlock_irqrestore(&dev->vbl_lock, flags); | 681 | spin_unlock_irqrestore(&dev->vbl_lock, flags); |
386 | } | 682 | } |
387 | 683 | ||
388 | EXPORT_SYMBOL(drm_vbl_send_signals); | 684 | /** |
685 | * drm_handle_vblank - handle a vblank event | ||
686 | * @dev: DRM device | ||
687 | * @crtc: where this event occurred | ||
688 | * | ||
689 | * Drivers should call this routine in their vblank interrupt handlers to | ||
690 | * update the vblank counter and send any signals that may be pending. | ||
691 | */ | ||
692 | void drm_handle_vblank(struct drm_device *dev, int crtc) | ||
693 | { | ||
694 | atomic_inc(&dev->_vblank_count[crtc]); | ||
695 | DRM_WAKEUP(&dev->vbl_queue[crtc]); | ||
696 | drm_vbl_send_signals(dev, crtc); | ||
697 | } | ||
698 | EXPORT_SYMBOL(drm_handle_vblank); | ||
389 | 699 | ||
390 | /** | 700 | /** |
391 | * Tasklet wrapper function. | 701 | * Tasklet wrapper function. |
diff --git a/drivers/gpu/drm/drm_memory.c b/drivers/gpu/drm/drm_memory.c index 0177012845c6..803bc9e7ce3c 100644 --- a/drivers/gpu/drm/drm_memory.c +++ b/drivers/gpu/drm/drm_memory.c | |||
@@ -133,6 +133,7 @@ int drm_free_agp(DRM_AGP_MEM * handle, int pages) | |||
133 | { | 133 | { |
134 | return drm_agp_free_memory(handle) ? 0 : -EINVAL; | 134 | return drm_agp_free_memory(handle) ? 0 : -EINVAL; |
135 | } | 135 | } |
136 | EXPORT_SYMBOL(drm_free_agp); | ||
136 | 137 | ||
137 | /** Wrapper around agp_bind_memory() */ | 138 | /** Wrapper around agp_bind_memory() */ |
138 | int drm_bind_agp(DRM_AGP_MEM * handle, unsigned int start) | 139 | int drm_bind_agp(DRM_AGP_MEM * handle, unsigned int start) |
@@ -145,6 +146,7 @@ int drm_unbind_agp(DRM_AGP_MEM * handle) | |||
145 | { | 146 | { |
146 | return drm_agp_unbind_memory(handle); | 147 | return drm_agp_unbind_memory(handle); |
147 | } | 148 | } |
149 | EXPORT_SYMBOL(drm_unbind_agp); | ||
148 | 150 | ||
149 | #else /* __OS_HAS_AGP */ | 151 | #else /* __OS_HAS_AGP */ |
150 | static inline void *agp_remap(unsigned long offset, unsigned long size, | 152 | static inline void *agp_remap(unsigned long offset, unsigned long size, |
diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c index dcff9e9b52e3..217ad7dc7076 100644 --- a/drivers/gpu/drm/drm_mm.c +++ b/drivers/gpu/drm/drm_mm.c | |||
@@ -169,6 +169,7 @@ struct drm_mm_node *drm_mm_get_block(struct drm_mm_node * parent, | |||
169 | 169 | ||
170 | return child; | 170 | return child; |
171 | } | 171 | } |
172 | EXPORT_SYMBOL(drm_mm_get_block); | ||
172 | 173 | ||
173 | /* | 174 | /* |
174 | * Put a block. Merge with the previous and / or next block if they are free. | 175 | * Put a block. Merge with the previous and / or next block if they are free. |
@@ -217,6 +218,7 @@ void drm_mm_put_block(struct drm_mm_node * cur) | |||
217 | drm_free(cur, sizeof(*cur), DRM_MEM_MM); | 218 | drm_free(cur, sizeof(*cur), DRM_MEM_MM); |
218 | } | 219 | } |
219 | } | 220 | } |
221 | EXPORT_SYMBOL(drm_mm_put_block); | ||
220 | 222 | ||
221 | struct drm_mm_node *drm_mm_search_free(const struct drm_mm * mm, | 223 | struct drm_mm_node *drm_mm_search_free(const struct drm_mm * mm, |
222 | unsigned long size, | 224 | unsigned long size, |
@@ -265,6 +267,7 @@ int drm_mm_clean(struct drm_mm * mm) | |||
265 | 267 | ||
266 | return (head->next->next == head); | 268 | return (head->next->next == head); |
267 | } | 269 | } |
270 | EXPORT_SYMBOL(drm_mm_search_free); | ||
268 | 271 | ||
269 | int drm_mm_init(struct drm_mm * mm, unsigned long start, unsigned long size) | 272 | int drm_mm_init(struct drm_mm * mm, unsigned long start, unsigned long size) |
270 | { | 273 | { |
@@ -273,7 +276,7 @@ int drm_mm_init(struct drm_mm * mm, unsigned long start, unsigned long size) | |||
273 | 276 | ||
274 | return drm_mm_create_tail_node(mm, start, size); | 277 | return drm_mm_create_tail_node(mm, start, size); |
275 | } | 278 | } |
276 | 279 | EXPORT_SYMBOL(drm_mm_init); | |
277 | 280 | ||
278 | void drm_mm_takedown(struct drm_mm * mm) | 281 | void drm_mm_takedown(struct drm_mm * mm) |
279 | { | 282 | { |
diff --git a/drivers/gpu/drm/drm_proc.c b/drivers/gpu/drm/drm_proc.c index 93b1e0475c93..d490db4c0de0 100644 --- a/drivers/gpu/drm/drm_proc.c +++ b/drivers/gpu/drm/drm_proc.c | |||
@@ -49,6 +49,10 @@ static int drm_queues_info(char *buf, char **start, off_t offset, | |||
49 | int request, int *eof, void *data); | 49 | int request, int *eof, void *data); |
50 | static int drm_bufs_info(char *buf, char **start, off_t offset, | 50 | static int drm_bufs_info(char *buf, char **start, off_t offset, |
51 | int request, int *eof, void *data); | 51 | int request, int *eof, void *data); |
52 | static int drm_gem_name_info(char *buf, char **start, off_t offset, | ||
53 | int request, int *eof, void *data); | ||
54 | static int drm_gem_object_info(char *buf, char **start, off_t offset, | ||
55 | int request, int *eof, void *data); | ||
52 | #if DRM_DEBUG_CODE | 56 | #if DRM_DEBUG_CODE |
53 | static int drm_vma_info(char *buf, char **start, off_t offset, | 57 | static int drm_vma_info(char *buf, char **start, off_t offset, |
54 | int request, int *eof, void *data); | 58 | int request, int *eof, void *data); |
@@ -60,13 +64,16 @@ static int drm_vma_info(char *buf, char **start, off_t offset, | |||
60 | static struct drm_proc_list { | 64 | static struct drm_proc_list { |
61 | const char *name; /**< file name */ | 65 | const char *name; /**< file name */ |
62 | int (*f) (char *, char **, off_t, int, int *, void *); /**< proc callback*/ | 66 | int (*f) (char *, char **, off_t, int, int *, void *); /**< proc callback*/ |
67 | u32 driver_features; /**< Required driver features for this entry */ | ||
63 | } drm_proc_list[] = { | 68 | } drm_proc_list[] = { |
64 | {"name", drm_name_info}, | 69 | {"name", drm_name_info, 0}, |
65 | {"mem", drm_mem_info}, | 70 | {"mem", drm_mem_info, 0}, |
66 | {"vm", drm_vm_info}, | 71 | {"vm", drm_vm_info, 0}, |
67 | {"clients", drm_clients_info}, | 72 | {"clients", drm_clients_info, 0}, |
68 | {"queues", drm_queues_info}, | 73 | {"queues", drm_queues_info, 0}, |
69 | {"bufs", drm_bufs_info}, | 74 | {"bufs", drm_bufs_info, 0}, |
75 | {"gem_names", drm_gem_name_info, DRIVER_GEM}, | ||
76 | {"gem_objects", drm_gem_object_info, DRIVER_GEM}, | ||
70 | #if DRM_DEBUG_CODE | 77 | #if DRM_DEBUG_CODE |
71 | {"vma", drm_vma_info}, | 78 | {"vma", drm_vma_info}, |
72 | #endif | 79 | #endif |
@@ -90,8 +97,9 @@ static struct drm_proc_list { | |||
90 | int drm_proc_init(struct drm_minor *minor, int minor_id, | 97 | int drm_proc_init(struct drm_minor *minor, int minor_id, |
91 | struct proc_dir_entry *root) | 98 | struct proc_dir_entry *root) |
92 | { | 99 | { |
100 | struct drm_device *dev = minor->dev; | ||
93 | struct proc_dir_entry *ent; | 101 | struct proc_dir_entry *ent; |
94 | int i, j; | 102 | int i, j, ret; |
95 | char name[64]; | 103 | char name[64]; |
96 | 104 | ||
97 | sprintf(name, "%d", minor_id); | 105 | sprintf(name, "%d", minor_id); |
@@ -102,23 +110,42 @@ int drm_proc_init(struct drm_minor *minor, int minor_id, | |||
102 | } | 110 | } |
103 | 111 | ||
104 | for (i = 0; i < DRM_PROC_ENTRIES; i++) { | 112 | for (i = 0; i < DRM_PROC_ENTRIES; i++) { |
113 | u32 features = drm_proc_list[i].driver_features; | ||
114 | |||
115 | if (features != 0 && | ||
116 | (dev->driver->driver_features & features) != features) | ||
117 | continue; | ||
118 | |||
105 | ent = create_proc_entry(drm_proc_list[i].name, | 119 | ent = create_proc_entry(drm_proc_list[i].name, |
106 | S_IFREG | S_IRUGO, minor->dev_root); | 120 | S_IFREG | S_IRUGO, minor->dev_root); |
107 | if (!ent) { | 121 | if (!ent) { |
108 | DRM_ERROR("Cannot create /proc/dri/%s/%s\n", | 122 | DRM_ERROR("Cannot create /proc/dri/%s/%s\n", |
109 | name, drm_proc_list[i].name); | 123 | name, drm_proc_list[i].name); |
110 | for (j = 0; j < i; j++) | 124 | ret = -1; |
111 | remove_proc_entry(drm_proc_list[i].name, | 125 | goto fail; |
112 | minor->dev_root); | ||
113 | remove_proc_entry(name, root); | ||
114 | minor->dev_root = NULL; | ||
115 | return -1; | ||
116 | } | 126 | } |
117 | ent->read_proc = drm_proc_list[i].f; | 127 | ent->read_proc = drm_proc_list[i].f; |
118 | ent->data = minor; | 128 | ent->data = minor; |
119 | } | 129 | } |
120 | 130 | ||
131 | if (dev->driver->proc_init) { | ||
132 | ret = dev->driver->proc_init(minor); | ||
133 | if (ret) { | ||
134 | DRM_ERROR("DRM: Driver failed to initialize " | ||
135 | "/proc/dri.\n"); | ||
136 | goto fail; | ||
137 | } | ||
138 | } | ||
139 | |||
121 | return 0; | 140 | return 0; |
141 | fail: | ||
142 | |||
143 | for (j = 0; j < i; j++) | ||
144 | remove_proc_entry(drm_proc_list[i].name, | ||
145 | minor->dev_root); | ||
146 | remove_proc_entry(name, root); | ||
147 | minor->dev_root = NULL; | ||
148 | return ret; | ||
122 | } | 149 | } |
123 | 150 | ||
124 | /** | 151 | /** |
@@ -133,12 +160,16 @@ int drm_proc_init(struct drm_minor *minor, int minor_id, | |||
133 | */ | 160 | */ |
134 | int drm_proc_cleanup(struct drm_minor *minor, struct proc_dir_entry *root) | 161 | int drm_proc_cleanup(struct drm_minor *minor, struct proc_dir_entry *root) |
135 | { | 162 | { |
163 | struct drm_device *dev = minor->dev; | ||
136 | int i; | 164 | int i; |
137 | char name[64]; | 165 | char name[64]; |
138 | 166 | ||
139 | if (!root || !minor->dev_root) | 167 | if (!root || !minor->dev_root) |
140 | return 0; | 168 | return 0; |
141 | 169 | ||
170 | if (dev->driver->proc_cleanup) | ||
171 | dev->driver->proc_cleanup(minor); | ||
172 | |||
142 | for (i = 0; i < DRM_PROC_ENTRIES; i++) | 173 | for (i = 0; i < DRM_PROC_ENTRIES; i++) |
143 | remove_proc_entry(drm_proc_list[i].name, minor->dev_root); | 174 | remove_proc_entry(drm_proc_list[i].name, minor->dev_root); |
144 | sprintf(name, "%d", minor->index); | 175 | sprintf(name, "%d", minor->index); |
@@ -480,6 +511,84 @@ static int drm_clients_info(char *buf, char **start, off_t offset, | |||
480 | return ret; | 511 | return ret; |
481 | } | 512 | } |
482 | 513 | ||
514 | struct drm_gem_name_info_data { | ||
515 | int len; | ||
516 | char *buf; | ||
517 | int eof; | ||
518 | }; | ||
519 | |||
520 | static int drm_gem_one_name_info(int id, void *ptr, void *data) | ||
521 | { | ||
522 | struct drm_gem_object *obj = ptr; | ||
523 | struct drm_gem_name_info_data *nid = data; | ||
524 | |||
525 | DRM_INFO("name %d size %d\n", obj->name, obj->size); | ||
526 | if (nid->eof) | ||
527 | return 0; | ||
528 | |||
529 | nid->len += sprintf(&nid->buf[nid->len], | ||
530 | "%6d%9d%8d%9d\n", | ||
531 | obj->name, obj->size, | ||
532 | atomic_read(&obj->handlecount.refcount), | ||
533 | atomic_read(&obj->refcount.refcount)); | ||
534 | if (nid->len > DRM_PROC_LIMIT) { | ||
535 | nid->eof = 1; | ||
536 | return 0; | ||
537 | } | ||
538 | return 0; | ||
539 | } | ||
540 | |||
541 | static int drm_gem_name_info(char *buf, char **start, off_t offset, | ||
542 | int request, int *eof, void *data) | ||
543 | { | ||
544 | struct drm_minor *minor = (struct drm_minor *) data; | ||
545 | struct drm_device *dev = minor->dev; | ||
546 | struct drm_gem_name_info_data nid; | ||
547 | |||
548 | if (offset > DRM_PROC_LIMIT) { | ||
549 | *eof = 1; | ||
550 | return 0; | ||
551 | } | ||
552 | |||
553 | nid.len = sprintf(buf, " name size handles refcount\n"); | ||
554 | nid.buf = buf; | ||
555 | nid.eof = 0; | ||
556 | idr_for_each(&dev->object_name_idr, drm_gem_one_name_info, &nid); | ||
557 | |||
558 | *start = &buf[offset]; | ||
559 | *eof = 0; | ||
560 | if (nid.len > request + offset) | ||
561 | return request; | ||
562 | *eof = 1; | ||
563 | return nid.len - offset; | ||
564 | } | ||
565 | |||
566 | static int drm_gem_object_info(char *buf, char **start, off_t offset, | ||
567 | int request, int *eof, void *data) | ||
568 | { | ||
569 | struct drm_minor *minor = (struct drm_minor *) data; | ||
570 | struct drm_device *dev = minor->dev; | ||
571 | int len = 0; | ||
572 | |||
573 | if (offset > DRM_PROC_LIMIT) { | ||
574 | *eof = 1; | ||
575 | return 0; | ||
576 | } | ||
577 | |||
578 | *start = &buf[offset]; | ||
579 | *eof = 0; | ||
580 | DRM_PROC_PRINT("%d objects\n", atomic_read(&dev->object_count)); | ||
581 | DRM_PROC_PRINT("%d object bytes\n", atomic_read(&dev->object_memory)); | ||
582 | DRM_PROC_PRINT("%d pinned\n", atomic_read(&dev->pin_count)); | ||
583 | DRM_PROC_PRINT("%d pin bytes\n", atomic_read(&dev->pin_memory)); | ||
584 | DRM_PROC_PRINT("%d gtt bytes\n", atomic_read(&dev->gtt_memory)); | ||
585 | DRM_PROC_PRINT("%d gtt total\n", dev->gtt_total); | ||
586 | if (len > request + offset) | ||
587 | return request; | ||
588 | *eof = 1; | ||
589 | return len - offset; | ||
590 | } | ||
591 | |||
483 | #if DRM_DEBUG_CODE | 592 | #if DRM_DEBUG_CODE |
484 | 593 | ||
485 | static int drm__vma_info(char *buf, char **start, off_t offset, int request, | 594 | static int drm__vma_info(char *buf, char **start, off_t offset, int request, |
diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c index c2f584f3b46c..141e33004a76 100644 --- a/drivers/gpu/drm/drm_stub.c +++ b/drivers/gpu/drm/drm_stub.c | |||
@@ -107,7 +107,6 @@ static int drm_fill_in_dev(struct drm_device * dev, struct pci_dev *pdev, | |||
107 | #ifdef __alpha__ | 107 | #ifdef __alpha__ |
108 | dev->hose = pdev->sysdata; | 108 | dev->hose = pdev->sysdata; |
109 | #endif | 109 | #endif |
110 | dev->irq = pdev->irq; | ||
111 | 110 | ||
112 | if (drm_ht_create(&dev->map_hash, 12)) { | 111 | if (drm_ht_create(&dev->map_hash, 12)) { |
113 | return -ENOMEM; | 112 | return -ENOMEM; |
@@ -152,6 +151,15 @@ static int drm_fill_in_dev(struct drm_device * dev, struct pci_dev *pdev, | |||
152 | goto error_out_unreg; | 151 | goto error_out_unreg; |
153 | } | 152 | } |
154 | 153 | ||
154 | if (driver->driver_features & DRIVER_GEM) { | ||
155 | retcode = drm_gem_init(dev); | ||
156 | if (retcode) { | ||
157 | DRM_ERROR("Cannot initialize graphics execution " | ||
158 | "manager (GEM)\n"); | ||
159 | goto error_out_unreg; | ||
160 | } | ||
161 | } | ||
162 | |||
155 | return 0; | 163 | return 0; |
156 | 164 | ||
157 | error_out_unreg: | 165 | error_out_unreg: |
@@ -317,6 +325,7 @@ int drm_put_dev(struct drm_device * dev) | |||
317 | int drm_put_minor(struct drm_minor **minor_p) | 325 | int drm_put_minor(struct drm_minor **minor_p) |
318 | { | 326 | { |
319 | struct drm_minor *minor = *minor_p; | 327 | struct drm_minor *minor = *minor_p; |
328 | |||
320 | DRM_DEBUG("release secondary minor %d\n", minor->index); | 329 | DRM_DEBUG("release secondary minor %d\n", minor->index); |
321 | 330 | ||
322 | if (minor->type == DRM_MINOR_LEGACY) | 331 | if (minor->type == DRM_MINOR_LEGACY) |
diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c index af211a0ef179..1611b9bcbe7f 100644 --- a/drivers/gpu/drm/drm_sysfs.c +++ b/drivers/gpu/drm/drm_sysfs.c | |||
@@ -184,7 +184,7 @@ int drm_sysfs_device_add(struct drm_minor *minor) | |||
184 | err_out_files: | 184 | err_out_files: |
185 | if (i > 0) | 185 | if (i > 0) |
186 | for (j = 0; j < i; j++) | 186 | for (j = 0; j < i; j++) |
187 | device_remove_file(&minor->kdev, &device_attrs[i]); | 187 | device_remove_file(&minor->kdev, &device_attrs[j]); |
188 | device_unregister(&minor->kdev); | 188 | device_unregister(&minor->kdev); |
189 | err_out: | 189 | err_out: |
190 | 190 | ||
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index a9e60464df74..5ba78e4fd2b5 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile | |||
@@ -3,7 +3,12 @@ | |||
3 | # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. | 3 | # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. |
4 | 4 | ||
5 | ccflags-y := -Iinclude/drm | 5 | ccflags-y := -Iinclude/drm |
6 | i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o | 6 | i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o i915_opregion.o \ |
7 | i915_suspend.o \ | ||
8 | i915_gem.o \ | ||
9 | i915_gem_debug.o \ | ||
10 | i915_gem_proc.o \ | ||
11 | i915_gem_tiling.o | ||
7 | 12 | ||
8 | i915-$(CONFIG_COMPAT) += i915_ioc32.o | 13 | i915-$(CONFIG_COMPAT) += i915_ioc32.o |
9 | 14 | ||
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 9ac4720e647b..db34780edbb2 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -40,40 +40,96 @@ int i915_wait_ring(struct drm_device * dev, int n, const char *caller) | |||
40 | { | 40 | { |
41 | drm_i915_private_t *dev_priv = dev->dev_private; | 41 | drm_i915_private_t *dev_priv = dev->dev_private; |
42 | drm_i915_ring_buffer_t *ring = &(dev_priv->ring); | 42 | drm_i915_ring_buffer_t *ring = &(dev_priv->ring); |
43 | u32 last_head = I915_READ(LP_RING + RING_HEAD) & HEAD_ADDR; | 43 | u32 acthd_reg = IS_I965G(dev) ? ACTHD_I965 : ACTHD; |
44 | u32 last_acthd = I915_READ(acthd_reg); | ||
45 | u32 acthd; | ||
46 | u32 last_head = I915_READ(PRB0_HEAD) & HEAD_ADDR; | ||
44 | int i; | 47 | int i; |
45 | 48 | ||
46 | for (i = 0; i < 10000; i++) { | 49 | for (i = 0; i < 100000; i++) { |
47 | ring->head = I915_READ(LP_RING + RING_HEAD) & HEAD_ADDR; | 50 | ring->head = I915_READ(PRB0_HEAD) & HEAD_ADDR; |
51 | acthd = I915_READ(acthd_reg); | ||
48 | ring->space = ring->head - (ring->tail + 8); | 52 | ring->space = ring->head - (ring->tail + 8); |
49 | if (ring->space < 0) | 53 | if (ring->space < 0) |
50 | ring->space += ring->Size; | 54 | ring->space += ring->Size; |
51 | if (ring->space >= n) | 55 | if (ring->space >= n) |
52 | return 0; | 56 | return 0; |
53 | 57 | ||
54 | dev_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT; | 58 | if (dev_priv->sarea_priv) |
59 | dev_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT; | ||
55 | 60 | ||
56 | if (ring->head != last_head) | 61 | if (ring->head != last_head) |
57 | i = 0; | 62 | i = 0; |
63 | if (acthd != last_acthd) | ||
64 | i = 0; | ||
58 | 65 | ||
59 | last_head = ring->head; | 66 | last_head = ring->head; |
67 | last_acthd = acthd; | ||
68 | msleep_interruptible(10); | ||
69 | |||
60 | } | 70 | } |
61 | 71 | ||
62 | return -EBUSY; | 72 | return -EBUSY; |
63 | } | 73 | } |
64 | 74 | ||
75 | /** | ||
76 | * Sets up the hardware status page for devices that need a physical address | ||
77 | * in the register. | ||
78 | */ | ||
79 | static int i915_init_phys_hws(struct drm_device *dev) | ||
80 | { | ||
81 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
82 | /* Program Hardware Status Page */ | ||
83 | dev_priv->status_page_dmah = | ||
84 | drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 0xffffffff); | ||
85 | |||
86 | if (!dev_priv->status_page_dmah) { | ||
87 | DRM_ERROR("Can not allocate hardware status page\n"); | ||
88 | return -ENOMEM; | ||
89 | } | ||
90 | dev_priv->hw_status_page = dev_priv->status_page_dmah->vaddr; | ||
91 | dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr; | ||
92 | |||
93 | memset(dev_priv->hw_status_page, 0, PAGE_SIZE); | ||
94 | |||
95 | I915_WRITE(HWS_PGA, dev_priv->dma_status_page); | ||
96 | DRM_DEBUG("Enabled hardware status page\n"); | ||
97 | return 0; | ||
98 | } | ||
99 | |||
100 | /** | ||
101 | * Frees the hardware status page, whether it's a physical address or a virtual | ||
102 | * address set up by the X Server. | ||
103 | */ | ||
104 | static void i915_free_hws(struct drm_device *dev) | ||
105 | { | ||
106 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
107 | if (dev_priv->status_page_dmah) { | ||
108 | drm_pci_free(dev, dev_priv->status_page_dmah); | ||
109 | dev_priv->status_page_dmah = NULL; | ||
110 | } | ||
111 | |||
112 | if (dev_priv->status_gfx_addr) { | ||
113 | dev_priv->status_gfx_addr = 0; | ||
114 | drm_core_ioremapfree(&dev_priv->hws_map, dev); | ||
115 | } | ||
116 | |||
117 | /* Need to rewrite hardware status page */ | ||
118 | I915_WRITE(HWS_PGA, 0x1ffff000); | ||
119 | } | ||
120 | |||
65 | void i915_kernel_lost_context(struct drm_device * dev) | 121 | void i915_kernel_lost_context(struct drm_device * dev) |
66 | { | 122 | { |
67 | drm_i915_private_t *dev_priv = dev->dev_private; | 123 | drm_i915_private_t *dev_priv = dev->dev_private; |
68 | drm_i915_ring_buffer_t *ring = &(dev_priv->ring); | 124 | drm_i915_ring_buffer_t *ring = &(dev_priv->ring); |
69 | 125 | ||
70 | ring->head = I915_READ(LP_RING + RING_HEAD) & HEAD_ADDR; | 126 | ring->head = I915_READ(PRB0_HEAD) & HEAD_ADDR; |
71 | ring->tail = I915_READ(LP_RING + RING_TAIL) & TAIL_ADDR; | 127 | ring->tail = I915_READ(PRB0_TAIL) & TAIL_ADDR; |
72 | ring->space = ring->head - (ring->tail + 8); | 128 | ring->space = ring->head - (ring->tail + 8); |
73 | if (ring->space < 0) | 129 | if (ring->space < 0) |
74 | ring->space += ring->Size; | 130 | ring->space += ring->Size; |
75 | 131 | ||
76 | if (ring->head == ring->tail) | 132 | if (ring->head == ring->tail && dev_priv->sarea_priv) |
77 | dev_priv->sarea_priv->perf_boxes |= I915_BOX_RING_EMPTY; | 133 | dev_priv->sarea_priv->perf_boxes |= I915_BOX_RING_EMPTY; |
78 | } | 134 | } |
79 | 135 | ||
@@ -84,28 +140,19 @@ static int i915_dma_cleanup(struct drm_device * dev) | |||
84 | * may not have been called from userspace and after dev_private | 140 | * may not have been called from userspace and after dev_private |
85 | * is freed, it's too late. | 141 | * is freed, it's too late. |
86 | */ | 142 | */ |
87 | if (dev->irq) | 143 | if (dev->irq_enabled) |
88 | drm_irq_uninstall(dev); | 144 | drm_irq_uninstall(dev); |
89 | 145 | ||
90 | if (dev_priv->ring.virtual_start) { | 146 | if (dev_priv->ring.virtual_start) { |
91 | drm_core_ioremapfree(&dev_priv->ring.map, dev); | 147 | drm_core_ioremapfree(&dev_priv->ring.map, dev); |
92 | dev_priv->ring.virtual_start = 0; | 148 | dev_priv->ring.virtual_start = NULL; |
93 | dev_priv->ring.map.handle = 0; | 149 | dev_priv->ring.map.handle = NULL; |
94 | dev_priv->ring.map.size = 0; | 150 | dev_priv->ring.map.size = 0; |
95 | } | 151 | } |
96 | 152 | ||
97 | if (dev_priv->status_page_dmah) { | 153 | /* Clear the HWS virtual address at teardown */ |
98 | drm_pci_free(dev, dev_priv->status_page_dmah); | 154 | if (I915_NEED_GFX_HWS(dev)) |
99 | dev_priv->status_page_dmah = NULL; | 155 | i915_free_hws(dev); |
100 | /* Need to rewrite hardware status page */ | ||
101 | I915_WRITE(0x02080, 0x1ffff000); | ||
102 | } | ||
103 | |||
104 | if (dev_priv->status_gfx_addr) { | ||
105 | dev_priv->status_gfx_addr = 0; | ||
106 | drm_core_ioremapfree(&dev_priv->hws_map, dev); | ||
107 | I915_WRITE(0x2080, 0x1ffff000); | ||
108 | } | ||
109 | 156 | ||
110 | return 0; | 157 | return 0; |
111 | } | 158 | } |
@@ -121,34 +168,34 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init) | |||
121 | return -EINVAL; | 168 | return -EINVAL; |
122 | } | 169 | } |
123 | 170 | ||
124 | dev_priv->mmio_map = drm_core_findmap(dev, init->mmio_offset); | ||
125 | if (!dev_priv->mmio_map) { | ||
126 | i915_dma_cleanup(dev); | ||
127 | DRM_ERROR("can not find mmio map!\n"); | ||
128 | return -EINVAL; | ||
129 | } | ||
130 | |||
131 | dev_priv->sarea_priv = (drm_i915_sarea_t *) | 171 | dev_priv->sarea_priv = (drm_i915_sarea_t *) |
132 | ((u8 *) dev_priv->sarea->handle + init->sarea_priv_offset); | 172 | ((u8 *) dev_priv->sarea->handle + init->sarea_priv_offset); |
133 | 173 | ||
134 | dev_priv->ring.Start = init->ring_start; | 174 | if (init->ring_size != 0) { |
135 | dev_priv->ring.End = init->ring_end; | 175 | if (dev_priv->ring.ring_obj != NULL) { |
136 | dev_priv->ring.Size = init->ring_size; | 176 | i915_dma_cleanup(dev); |
137 | dev_priv->ring.tail_mask = dev_priv->ring.Size - 1; | 177 | DRM_ERROR("Client tried to initialize ringbuffer in " |
178 | "GEM mode\n"); | ||
179 | return -EINVAL; | ||
180 | } | ||
138 | 181 | ||
139 | dev_priv->ring.map.offset = init->ring_start; | 182 | dev_priv->ring.Size = init->ring_size; |
140 | dev_priv->ring.map.size = init->ring_size; | 183 | dev_priv->ring.tail_mask = dev_priv->ring.Size - 1; |
141 | dev_priv->ring.map.type = 0; | ||
142 | dev_priv->ring.map.flags = 0; | ||
143 | dev_priv->ring.map.mtrr = 0; | ||
144 | 184 | ||
145 | drm_core_ioremap(&dev_priv->ring.map, dev); | 185 | dev_priv->ring.map.offset = init->ring_start; |
186 | dev_priv->ring.map.size = init->ring_size; | ||
187 | dev_priv->ring.map.type = 0; | ||
188 | dev_priv->ring.map.flags = 0; | ||
189 | dev_priv->ring.map.mtrr = 0; | ||
146 | 190 | ||
147 | if (dev_priv->ring.map.handle == NULL) { | 191 | drm_core_ioremap(&dev_priv->ring.map, dev); |
148 | i915_dma_cleanup(dev); | 192 | |
149 | DRM_ERROR("can not ioremap virtual address for" | 193 | if (dev_priv->ring.map.handle == NULL) { |
150 | " ring buffer\n"); | 194 | i915_dma_cleanup(dev); |
151 | return -ENOMEM; | 195 | DRM_ERROR("can not ioremap virtual address for" |
196 | " ring buffer\n"); | ||
197 | return -ENOMEM; | ||
198 | } | ||
152 | } | 199 | } |
153 | 200 | ||
154 | dev_priv->ring.virtual_start = dev_priv->ring.map.handle; | 201 | dev_priv->ring.virtual_start = dev_priv->ring.map.handle; |
@@ -159,34 +206,10 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init) | |||
159 | dev_priv->current_page = 0; | 206 | dev_priv->current_page = 0; |
160 | dev_priv->sarea_priv->pf_current_page = dev_priv->current_page; | 207 | dev_priv->sarea_priv->pf_current_page = dev_priv->current_page; |
161 | 208 | ||
162 | /* We are using separate values as placeholders for mechanisms for | ||
163 | * private backbuffer/depthbuffer usage. | ||
164 | */ | ||
165 | dev_priv->use_mi_batchbuffer_start = 0; | ||
166 | if (IS_I965G(dev)) /* 965 doesn't support older method */ | ||
167 | dev_priv->use_mi_batchbuffer_start = 1; | ||
168 | |||
169 | /* Allow hardware batchbuffers unless told otherwise. | 209 | /* Allow hardware batchbuffers unless told otherwise. |
170 | */ | 210 | */ |
171 | dev_priv->allow_batchbuffer = 1; | 211 | dev_priv->allow_batchbuffer = 1; |
172 | 212 | ||
173 | /* Program Hardware Status Page */ | ||
174 | if (!I915_NEED_GFX_HWS(dev)) { | ||
175 | dev_priv->status_page_dmah = | ||
176 | drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 0xffffffff); | ||
177 | |||
178 | if (!dev_priv->status_page_dmah) { | ||
179 | i915_dma_cleanup(dev); | ||
180 | DRM_ERROR("Can not allocate hardware status page\n"); | ||
181 | return -ENOMEM; | ||
182 | } | ||
183 | dev_priv->hw_status_page = dev_priv->status_page_dmah->vaddr; | ||
184 | dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr; | ||
185 | |||
186 | memset(dev_priv->hw_status_page, 0, PAGE_SIZE); | ||
187 | I915_WRITE(0x02080, dev_priv->dma_status_page); | ||
188 | } | ||
189 | DRM_DEBUG("Enabled hardware status page\n"); | ||
190 | return 0; | 213 | return 0; |
191 | } | 214 | } |
192 | 215 | ||
@@ -201,11 +224,6 @@ static int i915_dma_resume(struct drm_device * dev) | |||
201 | return -EINVAL; | 224 | return -EINVAL; |
202 | } | 225 | } |
203 | 226 | ||
204 | if (!dev_priv->mmio_map) { | ||
205 | DRM_ERROR("can not find mmio map!\n"); | ||
206 | return -EINVAL; | ||
207 | } | ||
208 | |||
209 | if (dev_priv->ring.map.handle == NULL) { | 227 | if (dev_priv->ring.map.handle == NULL) { |
210 | DRM_ERROR("can not ioremap virtual address for" | 228 | DRM_ERROR("can not ioremap virtual address for" |
211 | " ring buffer\n"); | 229 | " ring buffer\n"); |
@@ -220,9 +238,9 @@ static int i915_dma_resume(struct drm_device * dev) | |||
220 | DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page); | 238 | DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page); |
221 | 239 | ||
222 | if (dev_priv->status_gfx_addr != 0) | 240 | if (dev_priv->status_gfx_addr != 0) |
223 | I915_WRITE(0x02080, dev_priv->status_gfx_addr); | 241 | I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr); |
224 | else | 242 | else |
225 | I915_WRITE(0x02080, dev_priv->dma_status_page); | 243 | I915_WRITE(HWS_PGA, dev_priv->dma_status_page); |
226 | DRM_DEBUG("Enabled hardware status page\n"); | 244 | DRM_DEBUG("Enabled hardware status page\n"); |
227 | 245 | ||
228 | return 0; | 246 | return 0; |
@@ -367,9 +385,10 @@ static int i915_emit_cmds(struct drm_device * dev, int __user * buffer, int dwor | |||
367 | return 0; | 385 | return 0; |
368 | } | 386 | } |
369 | 387 | ||
370 | static int i915_emit_box(struct drm_device * dev, | 388 | int |
371 | struct drm_clip_rect __user * boxes, | 389 | i915_emit_box(struct drm_device *dev, |
372 | int i, int DR1, int DR4) | 390 | struct drm_clip_rect __user *boxes, |
391 | int i, int DR1, int DR4) | ||
373 | { | 392 | { |
374 | drm_i915_private_t *dev_priv = dev->dev_private; | 393 | drm_i915_private_t *dev_priv = dev->dev_private; |
375 | struct drm_clip_rect box; | 394 | struct drm_clip_rect box; |
@@ -415,14 +434,15 @@ static void i915_emit_breadcrumb(struct drm_device *dev) | |||
415 | drm_i915_private_t *dev_priv = dev->dev_private; | 434 | drm_i915_private_t *dev_priv = dev->dev_private; |
416 | RING_LOCALS; | 435 | RING_LOCALS; |
417 | 436 | ||
418 | dev_priv->sarea_priv->last_enqueue = ++dev_priv->counter; | 437 | dev_priv->counter++; |
419 | |||
420 | if (dev_priv->counter > 0x7FFFFFFFUL) | 438 | if (dev_priv->counter > 0x7FFFFFFFUL) |
421 | dev_priv->sarea_priv->last_enqueue = dev_priv->counter = 1; | 439 | dev_priv->counter = 0; |
440 | if (dev_priv->sarea_priv) | ||
441 | dev_priv->sarea_priv->last_enqueue = dev_priv->counter; | ||
422 | 442 | ||
423 | BEGIN_LP_RING(4); | 443 | BEGIN_LP_RING(4); |
424 | OUT_RING(CMD_STORE_DWORD_IDX); | 444 | OUT_RING(MI_STORE_DWORD_INDEX); |
425 | OUT_RING(20); | 445 | OUT_RING(5 << MI_STORE_DWORD_INDEX_SHIFT); |
426 | OUT_RING(dev_priv->counter); | 446 | OUT_RING(dev_priv->counter); |
427 | OUT_RING(0); | 447 | OUT_RING(0); |
428 | ADVANCE_LP_RING(); | 448 | ADVANCE_LP_RING(); |
@@ -486,7 +506,7 @@ static int i915_dispatch_batchbuffer(struct drm_device * dev, | |||
486 | return ret; | 506 | return ret; |
487 | } | 507 | } |
488 | 508 | ||
489 | if (dev_priv->use_mi_batchbuffer_start) { | 509 | if (!IS_I830(dev) && !IS_845G(dev)) { |
490 | BEGIN_LP_RING(2); | 510 | BEGIN_LP_RING(2); |
491 | if (IS_I965G(dev)) { | 511 | if (IS_I965G(dev)) { |
492 | OUT_RING(MI_BATCH_BUFFER_START | (2 << 6) | MI_BATCH_NON_SECURE_I965); | 512 | OUT_RING(MI_BATCH_BUFFER_START | (2 << 6) | MI_BATCH_NON_SECURE_I965); |
@@ -516,6 +536,9 @@ static int i915_dispatch_flip(struct drm_device * dev) | |||
516 | drm_i915_private_t *dev_priv = dev->dev_private; | 536 | drm_i915_private_t *dev_priv = dev->dev_private; |
517 | RING_LOCALS; | 537 | RING_LOCALS; |
518 | 538 | ||
539 | if (!dev_priv->sarea_priv) | ||
540 | return -EINVAL; | ||
541 | |||
519 | DRM_DEBUG("%s: page=%d pfCurrentPage=%d\n", | 542 | DRM_DEBUG("%s: page=%d pfCurrentPage=%d\n", |
520 | __func__, | 543 | __func__, |
521 | dev_priv->current_page, | 544 | dev_priv->current_page, |
@@ -524,7 +547,7 @@ static int i915_dispatch_flip(struct drm_device * dev) | |||
524 | i915_kernel_lost_context(dev); | 547 | i915_kernel_lost_context(dev); |
525 | 548 | ||
526 | BEGIN_LP_RING(2); | 549 | BEGIN_LP_RING(2); |
527 | OUT_RING(INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE); | 550 | OUT_RING(MI_FLUSH | MI_READ_FLUSH); |
528 | OUT_RING(0); | 551 | OUT_RING(0); |
529 | ADVANCE_LP_RING(); | 552 | ADVANCE_LP_RING(); |
530 | 553 | ||
@@ -549,8 +572,8 @@ static int i915_dispatch_flip(struct drm_device * dev) | |||
549 | dev_priv->sarea_priv->last_enqueue = dev_priv->counter++; | 572 | dev_priv->sarea_priv->last_enqueue = dev_priv->counter++; |
550 | 573 | ||
551 | BEGIN_LP_RING(4); | 574 | BEGIN_LP_RING(4); |
552 | OUT_RING(CMD_STORE_DWORD_IDX); | 575 | OUT_RING(MI_STORE_DWORD_INDEX); |
553 | OUT_RING(20); | 576 | OUT_RING(5 << MI_STORE_DWORD_INDEX_SHIFT); |
554 | OUT_RING(dev_priv->counter); | 577 | OUT_RING(dev_priv->counter); |
555 | OUT_RING(0); | 578 | OUT_RING(0); |
556 | ADVANCE_LP_RING(); | 579 | ADVANCE_LP_RING(); |
@@ -570,9 +593,15 @@ static int i915_quiescent(struct drm_device * dev) | |||
570 | static int i915_flush_ioctl(struct drm_device *dev, void *data, | 593 | static int i915_flush_ioctl(struct drm_device *dev, void *data, |
571 | struct drm_file *file_priv) | 594 | struct drm_file *file_priv) |
572 | { | 595 | { |
573 | LOCK_TEST_WITH_RETURN(dev, file_priv); | 596 | int ret; |
597 | |||
598 | RING_LOCK_TEST_WITH_RETURN(dev, file_priv); | ||
599 | |||
600 | mutex_lock(&dev->struct_mutex); | ||
601 | ret = i915_quiescent(dev); | ||
602 | mutex_unlock(&dev->struct_mutex); | ||
574 | 603 | ||
575 | return i915_quiescent(dev); | 604 | return ret; |
576 | } | 605 | } |
577 | 606 | ||
578 | static int i915_batchbuffer(struct drm_device *dev, void *data, | 607 | static int i915_batchbuffer(struct drm_device *dev, void *data, |
@@ -593,16 +622,19 @@ static int i915_batchbuffer(struct drm_device *dev, void *data, | |||
593 | DRM_DEBUG("i915 batchbuffer, start %x used %d cliprects %d\n", | 622 | DRM_DEBUG("i915 batchbuffer, start %x used %d cliprects %d\n", |
594 | batch->start, batch->used, batch->num_cliprects); | 623 | batch->start, batch->used, batch->num_cliprects); |
595 | 624 | ||
596 | LOCK_TEST_WITH_RETURN(dev, file_priv); | 625 | RING_LOCK_TEST_WITH_RETURN(dev, file_priv); |
597 | 626 | ||
598 | if (batch->num_cliprects && DRM_VERIFYAREA_READ(batch->cliprects, | 627 | if (batch->num_cliprects && DRM_VERIFYAREA_READ(batch->cliprects, |
599 | batch->num_cliprects * | 628 | batch->num_cliprects * |
600 | sizeof(struct drm_clip_rect))) | 629 | sizeof(struct drm_clip_rect))) |
601 | return -EFAULT; | 630 | return -EFAULT; |
602 | 631 | ||
632 | mutex_lock(&dev->struct_mutex); | ||
603 | ret = i915_dispatch_batchbuffer(dev, batch); | 633 | ret = i915_dispatch_batchbuffer(dev, batch); |
634 | mutex_unlock(&dev->struct_mutex); | ||
604 | 635 | ||
605 | sarea_priv->last_dispatch = (int)hw_status[5]; | 636 | if (sarea_priv) |
637 | sarea_priv->last_dispatch = (int)hw_status[5]; | ||
606 | return ret; | 638 | return ret; |
607 | } | 639 | } |
608 | 640 | ||
@@ -619,7 +651,7 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data, | |||
619 | DRM_DEBUG("i915 cmdbuffer, buf %p sz %d cliprects %d\n", | 651 | DRM_DEBUG("i915 cmdbuffer, buf %p sz %d cliprects %d\n", |
620 | cmdbuf->buf, cmdbuf->sz, cmdbuf->num_cliprects); | 652 | cmdbuf->buf, cmdbuf->sz, cmdbuf->num_cliprects); |
621 | 653 | ||
622 | LOCK_TEST_WITH_RETURN(dev, file_priv); | 654 | RING_LOCK_TEST_WITH_RETURN(dev, file_priv); |
623 | 655 | ||
624 | if (cmdbuf->num_cliprects && | 656 | if (cmdbuf->num_cliprects && |
625 | DRM_VERIFYAREA_READ(cmdbuf->cliprects, | 657 | DRM_VERIFYAREA_READ(cmdbuf->cliprects, |
@@ -629,24 +661,33 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data, | |||
629 | return -EFAULT; | 661 | return -EFAULT; |
630 | } | 662 | } |
631 | 663 | ||
664 | mutex_lock(&dev->struct_mutex); | ||
632 | ret = i915_dispatch_cmdbuffer(dev, cmdbuf); | 665 | ret = i915_dispatch_cmdbuffer(dev, cmdbuf); |
666 | mutex_unlock(&dev->struct_mutex); | ||
633 | if (ret) { | 667 | if (ret) { |
634 | DRM_ERROR("i915_dispatch_cmdbuffer failed\n"); | 668 | DRM_ERROR("i915_dispatch_cmdbuffer failed\n"); |
635 | return ret; | 669 | return ret; |
636 | } | 670 | } |
637 | 671 | ||
638 | sarea_priv->last_dispatch = (int)hw_status[5]; | 672 | if (sarea_priv) |
673 | sarea_priv->last_dispatch = (int)hw_status[5]; | ||
639 | return 0; | 674 | return 0; |
640 | } | 675 | } |
641 | 676 | ||
642 | static int i915_flip_bufs(struct drm_device *dev, void *data, | 677 | static int i915_flip_bufs(struct drm_device *dev, void *data, |
643 | struct drm_file *file_priv) | 678 | struct drm_file *file_priv) |
644 | { | 679 | { |
680 | int ret; | ||
681 | |||
645 | DRM_DEBUG("%s\n", __func__); | 682 | DRM_DEBUG("%s\n", __func__); |
646 | 683 | ||
647 | LOCK_TEST_WITH_RETURN(dev, file_priv); | 684 | RING_LOCK_TEST_WITH_RETURN(dev, file_priv); |
685 | |||
686 | mutex_lock(&dev->struct_mutex); | ||
687 | ret = i915_dispatch_flip(dev); | ||
688 | mutex_unlock(&dev->struct_mutex); | ||
648 | 689 | ||
649 | return i915_dispatch_flip(dev); | 690 | return ret; |
650 | } | 691 | } |
651 | 692 | ||
652 | static int i915_getparam(struct drm_device *dev, void *data, | 693 | static int i915_getparam(struct drm_device *dev, void *data, |
@@ -663,7 +704,7 @@ static int i915_getparam(struct drm_device *dev, void *data, | |||
663 | 704 | ||
664 | switch (param->param) { | 705 | switch (param->param) { |
665 | case I915_PARAM_IRQ_ACTIVE: | 706 | case I915_PARAM_IRQ_ACTIVE: |
666 | value = dev->irq ? 1 : 0; | 707 | value = dev->pdev->irq ? 1 : 0; |
667 | break; | 708 | break; |
668 | case I915_PARAM_ALLOW_BATCHBUFFER: | 709 | case I915_PARAM_ALLOW_BATCHBUFFER: |
669 | value = dev_priv->allow_batchbuffer ? 1 : 0; | 710 | value = dev_priv->allow_batchbuffer ? 1 : 0; |
@@ -671,6 +712,12 @@ static int i915_getparam(struct drm_device *dev, void *data, | |||
671 | case I915_PARAM_LAST_DISPATCH: | 712 | case I915_PARAM_LAST_DISPATCH: |
672 | value = READ_BREADCRUMB(dev_priv); | 713 | value = READ_BREADCRUMB(dev_priv); |
673 | break; | 714 | break; |
715 | case I915_PARAM_CHIPSET_ID: | ||
716 | value = dev->pci_device; | ||
717 | break; | ||
718 | case I915_PARAM_HAS_GEM: | ||
719 | value = 1; | ||
720 | break; | ||
674 | default: | 721 | default: |
675 | DRM_ERROR("Unknown parameter %d\n", param->param); | 722 | DRM_ERROR("Unknown parameter %d\n", param->param); |
676 | return -EINVAL; | 723 | return -EINVAL; |
@@ -697,8 +744,6 @@ static int i915_setparam(struct drm_device *dev, void *data, | |||
697 | 744 | ||
698 | switch (param->param) { | 745 | switch (param->param) { |
699 | case I915_SETPARAM_USE_MI_BATCHBUFFER_START: | 746 | case I915_SETPARAM_USE_MI_BATCHBUFFER_START: |
700 | if (!IS_I965G(dev)) | ||
701 | dev_priv->use_mi_batchbuffer_start = param->value; | ||
702 | break; | 747 | break; |
703 | case I915_SETPARAM_TEX_LRU_LOG_GRANULARITY: | 748 | case I915_SETPARAM_TEX_LRU_LOG_GRANULARITY: |
704 | dev_priv->tex_lru_log_granularity = param->value; | 749 | dev_priv->tex_lru_log_granularity = param->value; |
@@ -749,8 +794,8 @@ static int i915_set_status_page(struct drm_device *dev, void *data, | |||
749 | dev_priv->hw_status_page = dev_priv->hws_map.handle; | 794 | dev_priv->hw_status_page = dev_priv->hws_map.handle; |
750 | 795 | ||
751 | memset(dev_priv->hw_status_page, 0, PAGE_SIZE); | 796 | memset(dev_priv->hw_status_page, 0, PAGE_SIZE); |
752 | I915_WRITE(0x02080, dev_priv->status_gfx_addr); | 797 | I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr); |
753 | DRM_DEBUG("load hws 0x2080 with gfx mem 0x%x\n", | 798 | DRM_DEBUG("load hws HWS_PGA with gfx mem 0x%x\n", |
754 | dev_priv->status_gfx_addr); | 799 | dev_priv->status_gfx_addr); |
755 | DRM_DEBUG("load hws at %p\n", dev_priv->hw_status_page); | 800 | DRM_DEBUG("load hws at %p\n", dev_priv->hw_status_page); |
756 | return 0; | 801 | return 0; |
@@ -776,14 +821,38 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
776 | memset(dev_priv, 0, sizeof(drm_i915_private_t)); | 821 | memset(dev_priv, 0, sizeof(drm_i915_private_t)); |
777 | 822 | ||
778 | dev->dev_private = (void *)dev_priv; | 823 | dev->dev_private = (void *)dev_priv; |
824 | dev_priv->dev = dev; | ||
779 | 825 | ||
780 | /* Add register map (needed for suspend/resume) */ | 826 | /* Add register map (needed for suspend/resume) */ |
781 | base = drm_get_resource_start(dev, mmio_bar); | 827 | base = drm_get_resource_start(dev, mmio_bar); |
782 | size = drm_get_resource_len(dev, mmio_bar); | 828 | size = drm_get_resource_len(dev, mmio_bar); |
783 | 829 | ||
784 | ret = drm_addmap(dev, base, size, _DRM_REGISTERS, | 830 | dev_priv->regs = ioremap(base, size); |
785 | _DRM_KERNEL | _DRM_DRIVER, | 831 | |
786 | &dev_priv->mmio_map); | 832 | i915_gem_load(dev); |
833 | |||
834 | /* Init HWS */ | ||
835 | if (!I915_NEED_GFX_HWS(dev)) { | ||
836 | ret = i915_init_phys_hws(dev); | ||
837 | if (ret != 0) | ||
838 | return ret; | ||
839 | } | ||
840 | |||
841 | /* On the 945G/GM, the chipset reports the MSI capability on the | ||
842 | * integrated graphics even though the support isn't actually there | ||
843 | * according to the published specs. It doesn't appear to function | ||
844 | * correctly in testing on 945G. | ||
845 | * This may be a side effect of MSI having been made available for PEG | ||
846 | * and the registers being closely associated. | ||
847 | */ | ||
848 | if (!IS_I945G(dev) && !IS_I945GM(dev)) | ||
849 | if (pci_enable_msi(dev->pdev)) | ||
850 | DRM_ERROR("failed to enable MSI\n"); | ||
851 | |||
852 | intel_opregion_init(dev); | ||
853 | |||
854 | spin_lock_init(&dev_priv->user_irq_lock); | ||
855 | |||
787 | return ret; | 856 | return ret; |
788 | } | 857 | } |
789 | 858 | ||
@@ -791,8 +860,15 @@ int i915_driver_unload(struct drm_device *dev) | |||
791 | { | 860 | { |
792 | struct drm_i915_private *dev_priv = dev->dev_private; | 861 | struct drm_i915_private *dev_priv = dev->dev_private; |
793 | 862 | ||
794 | if (dev_priv->mmio_map) | 863 | if (dev->pdev->msi_enabled) |
795 | drm_rmmap(dev, dev_priv->mmio_map); | 864 | pci_disable_msi(dev->pdev); |
865 | |||
866 | i915_free_hws(dev); | ||
867 | |||
868 | if (dev_priv->regs != NULL) | ||
869 | iounmap(dev_priv->regs); | ||
870 | |||
871 | intel_opregion_free(dev); | ||
796 | 872 | ||
797 | drm_free(dev->dev_private, sizeof(drm_i915_private_t), | 873 | drm_free(dev->dev_private, sizeof(drm_i915_private_t), |
798 | DRM_MEM_DRIVER); | 874 | DRM_MEM_DRIVER); |
@@ -800,6 +876,25 @@ int i915_driver_unload(struct drm_device *dev) | |||
800 | return 0; | 876 | return 0; |
801 | } | 877 | } |
802 | 878 | ||
879 | int i915_driver_open(struct drm_device *dev, struct drm_file *file_priv) | ||
880 | { | ||
881 | struct drm_i915_file_private *i915_file_priv; | ||
882 | |||
883 | DRM_DEBUG("\n"); | ||
884 | i915_file_priv = (struct drm_i915_file_private *) | ||
885 | drm_alloc(sizeof(*i915_file_priv), DRM_MEM_FILES); | ||
886 | |||
887 | if (!i915_file_priv) | ||
888 | return -ENOMEM; | ||
889 | |||
890 | file_priv->driver_priv = i915_file_priv; | ||
891 | |||
892 | i915_file_priv->mm.last_gem_seqno = 0; | ||
893 | i915_file_priv->mm.last_gem_throttle_seqno = 0; | ||
894 | |||
895 | return 0; | ||
896 | } | ||
897 | |||
803 | void i915_driver_lastclose(struct drm_device * dev) | 898 | void i915_driver_lastclose(struct drm_device * dev) |
804 | { | 899 | { |
805 | drm_i915_private_t *dev_priv = dev->dev_private; | 900 | drm_i915_private_t *dev_priv = dev->dev_private; |
@@ -807,6 +902,8 @@ void i915_driver_lastclose(struct drm_device * dev) | |||
807 | if (!dev_priv) | 902 | if (!dev_priv) |
808 | return; | 903 | return; |
809 | 904 | ||
905 | i915_gem_lastclose(dev); | ||
906 | |||
810 | if (dev_priv->agp_heap) | 907 | if (dev_priv->agp_heap) |
811 | i915_mem_takedown(&(dev_priv->agp_heap)); | 908 | i915_mem_takedown(&(dev_priv->agp_heap)); |
812 | 909 | ||
@@ -819,6 +916,13 @@ void i915_driver_preclose(struct drm_device * dev, struct drm_file *file_priv) | |||
819 | i915_mem_release(dev, file_priv, dev_priv->agp_heap); | 916 | i915_mem_release(dev, file_priv, dev_priv->agp_heap); |
820 | } | 917 | } |
821 | 918 | ||
919 | void i915_driver_postclose(struct drm_device *dev, struct drm_file *file_priv) | ||
920 | { | ||
921 | struct drm_i915_file_private *i915_file_priv = file_priv->driver_priv; | ||
922 | |||
923 | drm_free(i915_file_priv, sizeof(*i915_file_priv), DRM_MEM_FILES); | ||
924 | } | ||
925 | |||
822 | struct drm_ioctl_desc i915_ioctls[] = { | 926 | struct drm_ioctl_desc i915_ioctls[] = { |
823 | DRM_IOCTL_DEF(DRM_I915_INIT, i915_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 927 | DRM_IOCTL_DEF(DRM_I915_INIT, i915_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
824 | DRM_IOCTL_DEF(DRM_I915_FLUSH, i915_flush_ioctl, DRM_AUTH), | 928 | DRM_IOCTL_DEF(DRM_I915_FLUSH, i915_flush_ioctl, DRM_AUTH), |
@@ -836,7 +940,23 @@ struct drm_ioctl_desc i915_ioctls[] = { | |||
836 | DRM_IOCTL_DEF(DRM_I915_SET_VBLANK_PIPE, i915_vblank_pipe_set, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY ), | 940 | DRM_IOCTL_DEF(DRM_I915_SET_VBLANK_PIPE, i915_vblank_pipe_set, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY ), |
837 | DRM_IOCTL_DEF(DRM_I915_GET_VBLANK_PIPE, i915_vblank_pipe_get, DRM_AUTH ), | 941 | DRM_IOCTL_DEF(DRM_I915_GET_VBLANK_PIPE, i915_vblank_pipe_get, DRM_AUTH ), |
838 | DRM_IOCTL_DEF(DRM_I915_VBLANK_SWAP, i915_vblank_swap, DRM_AUTH), | 942 | DRM_IOCTL_DEF(DRM_I915_VBLANK_SWAP, i915_vblank_swap, DRM_AUTH), |
839 | DRM_IOCTL_DEF(DRM_I915_HWS_ADDR, i915_set_status_page, DRM_AUTH), | 943 | DRM_IOCTL_DEF(DRM_I915_HWS_ADDR, i915_set_status_page, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
944 | DRM_IOCTL_DEF(DRM_I915_GEM_INIT, i915_gem_init_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | ||
945 | DRM_IOCTL_DEF(DRM_I915_GEM_EXECBUFFER, i915_gem_execbuffer, DRM_AUTH), | ||
946 | DRM_IOCTL_DEF(DRM_I915_GEM_PIN, i915_gem_pin_ioctl, DRM_AUTH|DRM_ROOT_ONLY), | ||
947 | DRM_IOCTL_DEF(DRM_I915_GEM_UNPIN, i915_gem_unpin_ioctl, DRM_AUTH|DRM_ROOT_ONLY), | ||
948 | DRM_IOCTL_DEF(DRM_I915_GEM_BUSY, i915_gem_busy_ioctl, DRM_AUTH), | ||
949 | DRM_IOCTL_DEF(DRM_I915_GEM_THROTTLE, i915_gem_throttle_ioctl, DRM_AUTH), | ||
950 | DRM_IOCTL_DEF(DRM_I915_GEM_ENTERVT, i915_gem_entervt_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | ||
951 | DRM_IOCTL_DEF(DRM_I915_GEM_LEAVEVT, i915_gem_leavevt_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | ||
952 | DRM_IOCTL_DEF(DRM_I915_GEM_CREATE, i915_gem_create_ioctl, 0), | ||
953 | DRM_IOCTL_DEF(DRM_I915_GEM_PREAD, i915_gem_pread_ioctl, 0), | ||
954 | DRM_IOCTL_DEF(DRM_I915_GEM_PWRITE, i915_gem_pwrite_ioctl, 0), | ||
955 | DRM_IOCTL_DEF(DRM_I915_GEM_MMAP, i915_gem_mmap_ioctl, 0), | ||
956 | DRM_IOCTL_DEF(DRM_I915_GEM_SET_DOMAIN, i915_gem_set_domain_ioctl, 0), | ||
957 | DRM_IOCTL_DEF(DRM_I915_GEM_SW_FINISH, i915_gem_sw_finish_ioctl, 0), | ||
958 | DRM_IOCTL_DEF(DRM_I915_GEM_SET_TILING, i915_gem_set_tiling, 0), | ||
959 | DRM_IOCTL_DEF(DRM_I915_GEM_GET_TILING, i915_gem_get_tiling, 0), | ||
840 | }; | 960 | }; |
841 | 961 | ||
842 | int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls); | 962 | int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls); |
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 93aed1c38bd2..a80ead215282 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
@@ -38,211 +38,9 @@ static struct pci_device_id pciidlist[] = { | |||
38 | i915_PCI_IDS | 38 | i915_PCI_IDS |
39 | }; | 39 | }; |
40 | 40 | ||
41 | enum pipe { | ||
42 | PIPE_A = 0, | ||
43 | PIPE_B, | ||
44 | }; | ||
45 | |||
46 | static bool i915_pipe_enabled(struct drm_device *dev, enum pipe pipe) | ||
47 | { | ||
48 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
49 | |||
50 | if (pipe == PIPE_A) | ||
51 | return (I915_READ(DPLL_A) & DPLL_VCO_ENABLE); | ||
52 | else | ||
53 | return (I915_READ(DPLL_B) & DPLL_VCO_ENABLE); | ||
54 | } | ||
55 | |||
56 | static void i915_save_palette(struct drm_device *dev, enum pipe pipe) | ||
57 | { | ||
58 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
59 | unsigned long reg = (pipe == PIPE_A ? PALETTE_A : PALETTE_B); | ||
60 | u32 *array; | ||
61 | int i; | ||
62 | |||
63 | if (!i915_pipe_enabled(dev, pipe)) | ||
64 | return; | ||
65 | |||
66 | if (pipe == PIPE_A) | ||
67 | array = dev_priv->save_palette_a; | ||
68 | else | ||
69 | array = dev_priv->save_palette_b; | ||
70 | |||
71 | for(i = 0; i < 256; i++) | ||
72 | array[i] = I915_READ(reg + (i << 2)); | ||
73 | } | ||
74 | |||
75 | static void i915_restore_palette(struct drm_device *dev, enum pipe pipe) | ||
76 | { | ||
77 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
78 | unsigned long reg = (pipe == PIPE_A ? PALETTE_A : PALETTE_B); | ||
79 | u32 *array; | ||
80 | int i; | ||
81 | |||
82 | if (!i915_pipe_enabled(dev, pipe)) | ||
83 | return; | ||
84 | |||
85 | if (pipe == PIPE_A) | ||
86 | array = dev_priv->save_palette_a; | ||
87 | else | ||
88 | array = dev_priv->save_palette_b; | ||
89 | |||
90 | for(i = 0; i < 256; i++) | ||
91 | I915_WRITE(reg + (i << 2), array[i]); | ||
92 | } | ||
93 | |||
94 | static u8 i915_read_indexed(u16 index_port, u16 data_port, u8 reg) | ||
95 | { | ||
96 | outb(reg, index_port); | ||
97 | return inb(data_port); | ||
98 | } | ||
99 | |||
100 | static u8 i915_read_ar(u16 st01, u8 reg, u16 palette_enable) | ||
101 | { | ||
102 | inb(st01); | ||
103 | outb(palette_enable | reg, VGA_AR_INDEX); | ||
104 | return inb(VGA_AR_DATA_READ); | ||
105 | } | ||
106 | |||
107 | static void i915_write_ar(u8 st01, u8 reg, u8 val, u16 palette_enable) | ||
108 | { | ||
109 | inb(st01); | ||
110 | outb(palette_enable | reg, VGA_AR_INDEX); | ||
111 | outb(val, VGA_AR_DATA_WRITE); | ||
112 | } | ||
113 | |||
114 | static void i915_write_indexed(u16 index_port, u16 data_port, u8 reg, u8 val) | ||
115 | { | ||
116 | outb(reg, index_port); | ||
117 | outb(val, data_port); | ||
118 | } | ||
119 | |||
120 | static void i915_save_vga(struct drm_device *dev) | ||
121 | { | ||
122 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
123 | int i; | ||
124 | u16 cr_index, cr_data, st01; | ||
125 | |||
126 | /* VGA color palette registers */ | ||
127 | dev_priv->saveDACMASK = inb(VGA_DACMASK); | ||
128 | /* DACCRX automatically increments during read */ | ||
129 | outb(0, VGA_DACRX); | ||
130 | /* Read 3 bytes of color data from each index */ | ||
131 | for (i = 0; i < 256 * 3; i++) | ||
132 | dev_priv->saveDACDATA[i] = inb(VGA_DACDATA); | ||
133 | |||
134 | /* MSR bits */ | ||
135 | dev_priv->saveMSR = inb(VGA_MSR_READ); | ||
136 | if (dev_priv->saveMSR & VGA_MSR_CGA_MODE) { | ||
137 | cr_index = VGA_CR_INDEX_CGA; | ||
138 | cr_data = VGA_CR_DATA_CGA; | ||
139 | st01 = VGA_ST01_CGA; | ||
140 | } else { | ||
141 | cr_index = VGA_CR_INDEX_MDA; | ||
142 | cr_data = VGA_CR_DATA_MDA; | ||
143 | st01 = VGA_ST01_MDA; | ||
144 | } | ||
145 | |||
146 | /* CRT controller regs */ | ||
147 | i915_write_indexed(cr_index, cr_data, 0x11, | ||
148 | i915_read_indexed(cr_index, cr_data, 0x11) & | ||
149 | (~0x80)); | ||
150 | for (i = 0; i <= 0x24; i++) | ||
151 | dev_priv->saveCR[i] = | ||
152 | i915_read_indexed(cr_index, cr_data, i); | ||
153 | /* Make sure we don't turn off CR group 0 writes */ | ||
154 | dev_priv->saveCR[0x11] &= ~0x80; | ||
155 | |||
156 | /* Attribute controller registers */ | ||
157 | inb(st01); | ||
158 | dev_priv->saveAR_INDEX = inb(VGA_AR_INDEX); | ||
159 | for (i = 0; i <= 0x14; i++) | ||
160 | dev_priv->saveAR[i] = i915_read_ar(st01, i, 0); | ||
161 | inb(st01); | ||
162 | outb(dev_priv->saveAR_INDEX, VGA_AR_INDEX); | ||
163 | inb(st01); | ||
164 | |||
165 | /* Graphics controller registers */ | ||
166 | for (i = 0; i < 9; i++) | ||
167 | dev_priv->saveGR[i] = | ||
168 | i915_read_indexed(VGA_GR_INDEX, VGA_GR_DATA, i); | ||
169 | |||
170 | dev_priv->saveGR[0x10] = | ||
171 | i915_read_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x10); | ||
172 | dev_priv->saveGR[0x11] = | ||
173 | i915_read_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x11); | ||
174 | dev_priv->saveGR[0x18] = | ||
175 | i915_read_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x18); | ||
176 | |||
177 | /* Sequencer registers */ | ||
178 | for (i = 0; i < 8; i++) | ||
179 | dev_priv->saveSR[i] = | ||
180 | i915_read_indexed(VGA_SR_INDEX, VGA_SR_DATA, i); | ||
181 | } | ||
182 | |||
183 | static void i915_restore_vga(struct drm_device *dev) | ||
184 | { | ||
185 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
186 | int i; | ||
187 | u16 cr_index, cr_data, st01; | ||
188 | |||
189 | /* MSR bits */ | ||
190 | outb(dev_priv->saveMSR, VGA_MSR_WRITE); | ||
191 | if (dev_priv->saveMSR & VGA_MSR_CGA_MODE) { | ||
192 | cr_index = VGA_CR_INDEX_CGA; | ||
193 | cr_data = VGA_CR_DATA_CGA; | ||
194 | st01 = VGA_ST01_CGA; | ||
195 | } else { | ||
196 | cr_index = VGA_CR_INDEX_MDA; | ||
197 | cr_data = VGA_CR_DATA_MDA; | ||
198 | st01 = VGA_ST01_MDA; | ||
199 | } | ||
200 | |||
201 | /* Sequencer registers, don't write SR07 */ | ||
202 | for (i = 0; i < 7; i++) | ||
203 | i915_write_indexed(VGA_SR_INDEX, VGA_SR_DATA, i, | ||
204 | dev_priv->saveSR[i]); | ||
205 | |||
206 | /* CRT controller regs */ | ||
207 | /* Enable CR group 0 writes */ | ||
208 | i915_write_indexed(cr_index, cr_data, 0x11, dev_priv->saveCR[0x11]); | ||
209 | for (i = 0; i <= 0x24; i++) | ||
210 | i915_write_indexed(cr_index, cr_data, i, dev_priv->saveCR[i]); | ||
211 | |||
212 | /* Graphics controller regs */ | ||
213 | for (i = 0; i < 9; i++) | ||
214 | i915_write_indexed(VGA_GR_INDEX, VGA_GR_DATA, i, | ||
215 | dev_priv->saveGR[i]); | ||
216 | |||
217 | i915_write_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x10, | ||
218 | dev_priv->saveGR[0x10]); | ||
219 | i915_write_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x11, | ||
220 | dev_priv->saveGR[0x11]); | ||
221 | i915_write_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x18, | ||
222 | dev_priv->saveGR[0x18]); | ||
223 | |||
224 | /* Attribute controller registers */ | ||
225 | inb(st01); | ||
226 | for (i = 0; i <= 0x14; i++) | ||
227 | i915_write_ar(st01, i, dev_priv->saveAR[i], 0); | ||
228 | inb(st01); /* switch back to index mode */ | ||
229 | outb(dev_priv->saveAR_INDEX | 0x20, VGA_AR_INDEX); | ||
230 | inb(st01); | ||
231 | |||
232 | /* VGA color palette registers */ | ||
233 | outb(dev_priv->saveDACMASK, VGA_DACMASK); | ||
234 | /* DACCRX automatically increments during read */ | ||
235 | outb(0, VGA_DACWX); | ||
236 | /* Read 3 bytes of color data from each index */ | ||
237 | for (i = 0; i < 256 * 3; i++) | ||
238 | outb(dev_priv->saveDACDATA[i], VGA_DACDATA); | ||
239 | |||
240 | } | ||
241 | |||
242 | static int i915_suspend(struct drm_device *dev, pm_message_t state) | 41 | static int i915_suspend(struct drm_device *dev, pm_message_t state) |
243 | { | 42 | { |
244 | struct drm_i915_private *dev_priv = dev->dev_private; | 43 | struct drm_i915_private *dev_priv = dev->dev_private; |
245 | int i; | ||
246 | 44 | ||
247 | if (!dev || !dev_priv) { | 45 | if (!dev || !dev_priv) { |
248 | printk(KERN_ERR "dev: %p, dev_priv: %p\n", dev, dev_priv); | 46 | printk(KERN_ERR "dev: %p, dev_priv: %p\n", dev, dev_priv); |
@@ -254,122 +52,10 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state) | |||
254 | return 0; | 52 | return 0; |
255 | 53 | ||
256 | pci_save_state(dev->pdev); | 54 | pci_save_state(dev->pdev); |
257 | pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB); | ||
258 | |||
259 | /* Display arbitration control */ | ||
260 | dev_priv->saveDSPARB = I915_READ(DSPARB); | ||
261 | |||
262 | /* Pipe & plane A info */ | ||
263 | dev_priv->savePIPEACONF = I915_READ(PIPEACONF); | ||
264 | dev_priv->savePIPEASRC = I915_READ(PIPEASRC); | ||
265 | dev_priv->saveFPA0 = I915_READ(FPA0); | ||
266 | dev_priv->saveFPA1 = I915_READ(FPA1); | ||
267 | dev_priv->saveDPLL_A = I915_READ(DPLL_A); | ||
268 | if (IS_I965G(dev)) | ||
269 | dev_priv->saveDPLL_A_MD = I915_READ(DPLL_A_MD); | ||
270 | dev_priv->saveHTOTAL_A = I915_READ(HTOTAL_A); | ||
271 | dev_priv->saveHBLANK_A = I915_READ(HBLANK_A); | ||
272 | dev_priv->saveHSYNC_A = I915_READ(HSYNC_A); | ||
273 | dev_priv->saveVTOTAL_A = I915_READ(VTOTAL_A); | ||
274 | dev_priv->saveVBLANK_A = I915_READ(VBLANK_A); | ||
275 | dev_priv->saveVSYNC_A = I915_READ(VSYNC_A); | ||
276 | dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A); | ||
277 | |||
278 | dev_priv->saveDSPACNTR = I915_READ(DSPACNTR); | ||
279 | dev_priv->saveDSPASTRIDE = I915_READ(DSPASTRIDE); | ||
280 | dev_priv->saveDSPASIZE = I915_READ(DSPASIZE); | ||
281 | dev_priv->saveDSPAPOS = I915_READ(DSPAPOS); | ||
282 | dev_priv->saveDSPABASE = I915_READ(DSPABASE); | ||
283 | if (IS_I965G(dev)) { | ||
284 | dev_priv->saveDSPASURF = I915_READ(DSPASURF); | ||
285 | dev_priv->saveDSPATILEOFF = I915_READ(DSPATILEOFF); | ||
286 | } | ||
287 | i915_save_palette(dev, PIPE_A); | ||
288 | dev_priv->savePIPEASTAT = I915_READ(I915REG_PIPEASTAT); | ||
289 | |||
290 | /* Pipe & plane B info */ | ||
291 | dev_priv->savePIPEBCONF = I915_READ(PIPEBCONF); | ||
292 | dev_priv->savePIPEBSRC = I915_READ(PIPEBSRC); | ||
293 | dev_priv->saveFPB0 = I915_READ(FPB0); | ||
294 | dev_priv->saveFPB1 = I915_READ(FPB1); | ||
295 | dev_priv->saveDPLL_B = I915_READ(DPLL_B); | ||
296 | if (IS_I965G(dev)) | ||
297 | dev_priv->saveDPLL_B_MD = I915_READ(DPLL_B_MD); | ||
298 | dev_priv->saveHTOTAL_B = I915_READ(HTOTAL_B); | ||
299 | dev_priv->saveHBLANK_B = I915_READ(HBLANK_B); | ||
300 | dev_priv->saveHSYNC_B = I915_READ(HSYNC_B); | ||
301 | dev_priv->saveVTOTAL_B = I915_READ(VTOTAL_B); | ||
302 | dev_priv->saveVBLANK_B = I915_READ(VBLANK_B); | ||
303 | dev_priv->saveVSYNC_B = I915_READ(VSYNC_B); | ||
304 | dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A); | ||
305 | |||
306 | dev_priv->saveDSPBCNTR = I915_READ(DSPBCNTR); | ||
307 | dev_priv->saveDSPBSTRIDE = I915_READ(DSPBSTRIDE); | ||
308 | dev_priv->saveDSPBSIZE = I915_READ(DSPBSIZE); | ||
309 | dev_priv->saveDSPBPOS = I915_READ(DSPBPOS); | ||
310 | dev_priv->saveDSPBBASE = I915_READ(DSPBBASE); | ||
311 | if (IS_I965GM(dev) || IS_IGD_GM(dev)) { | ||
312 | dev_priv->saveDSPBSURF = I915_READ(DSPBSURF); | ||
313 | dev_priv->saveDSPBTILEOFF = I915_READ(DSPBTILEOFF); | ||
314 | } | ||
315 | i915_save_palette(dev, PIPE_B); | ||
316 | dev_priv->savePIPEBSTAT = I915_READ(I915REG_PIPEBSTAT); | ||
317 | 55 | ||
318 | /* CRT state */ | 56 | i915_save_state(dev); |
319 | dev_priv->saveADPA = I915_READ(ADPA); | ||
320 | 57 | ||
321 | /* LVDS state */ | 58 | intel_opregion_free(dev); |
322 | dev_priv->savePP_CONTROL = I915_READ(PP_CONTROL); | ||
323 | dev_priv->savePFIT_PGM_RATIOS = I915_READ(PFIT_PGM_RATIOS); | ||
324 | dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_CTL); | ||
325 | if (IS_I965G(dev)) | ||
326 | dev_priv->saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_CTL2); | ||
327 | if (IS_MOBILE(dev) && !IS_I830(dev)) | ||
328 | dev_priv->saveLVDS = I915_READ(LVDS); | ||
329 | if (!IS_I830(dev) && !IS_845G(dev)) | ||
330 | dev_priv->savePFIT_CONTROL = I915_READ(PFIT_CONTROL); | ||
331 | dev_priv->saveLVDSPP_ON = I915_READ(LVDSPP_ON); | ||
332 | dev_priv->saveLVDSPP_OFF = I915_READ(LVDSPP_OFF); | ||
333 | dev_priv->savePP_CYCLE = I915_READ(PP_CYCLE); | ||
334 | |||
335 | /* FIXME: save TV & SDVO state */ | ||
336 | |||
337 | /* FBC state */ | ||
338 | dev_priv->saveFBC_CFB_BASE = I915_READ(FBC_CFB_BASE); | ||
339 | dev_priv->saveFBC_LL_BASE = I915_READ(FBC_LL_BASE); | ||
340 | dev_priv->saveFBC_CONTROL2 = I915_READ(FBC_CONTROL2); | ||
341 | dev_priv->saveFBC_CONTROL = I915_READ(FBC_CONTROL); | ||
342 | |||
343 | /* Interrupt state */ | ||
344 | dev_priv->saveIIR = I915_READ(I915REG_INT_IDENTITY_R); | ||
345 | dev_priv->saveIER = I915_READ(I915REG_INT_ENABLE_R); | ||
346 | dev_priv->saveIMR = I915_READ(I915REG_INT_MASK_R); | ||
347 | |||
348 | /* VGA state */ | ||
349 | dev_priv->saveVCLK_DIVISOR_VGA0 = I915_READ(VCLK_DIVISOR_VGA0); | ||
350 | dev_priv->saveVCLK_DIVISOR_VGA1 = I915_READ(VCLK_DIVISOR_VGA1); | ||
351 | dev_priv->saveVCLK_POST_DIV = I915_READ(VCLK_POST_DIV); | ||
352 | dev_priv->saveVGACNTRL = I915_READ(VGACNTRL); | ||
353 | |||
354 | /* Clock gating state */ | ||
355 | dev_priv->saveD_STATE = I915_READ(D_STATE); | ||
356 | dev_priv->saveDSPCLK_GATE_D = I915_READ(DSPCLK_GATE_D); | ||
357 | |||
358 | /* Cache mode state */ | ||
359 | dev_priv->saveCACHE_MODE_0 = I915_READ(CACHE_MODE_0); | ||
360 | |||
361 | /* Memory Arbitration state */ | ||
362 | dev_priv->saveMI_ARB_STATE = I915_READ(MI_ARB_STATE); | ||
363 | |||
364 | /* Scratch space */ | ||
365 | for (i = 0; i < 16; i++) { | ||
366 | dev_priv->saveSWF0[i] = I915_READ(SWF0 + (i << 2)); | ||
367 | dev_priv->saveSWF1[i] = I915_READ(SWF10 + (i << 2)); | ||
368 | } | ||
369 | for (i = 0; i < 3; i++) | ||
370 | dev_priv->saveSWF2[i] = I915_READ(SWF30 + (i << 2)); | ||
371 | |||
372 | i915_save_vga(dev); | ||
373 | 59 | ||
374 | if (state.event == PM_EVENT_SUSPEND) { | 60 | if (state.event == PM_EVENT_SUSPEND) { |
375 | /* Shut down the device */ | 61 | /* Shut down the device */ |
@@ -382,155 +68,15 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state) | |||
382 | 68 | ||
383 | static int i915_resume(struct drm_device *dev) | 69 | static int i915_resume(struct drm_device *dev) |
384 | { | 70 | { |
385 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
386 | int i; | ||
387 | |||
388 | pci_set_power_state(dev->pdev, PCI_D0); | 71 | pci_set_power_state(dev->pdev, PCI_D0); |
389 | pci_restore_state(dev->pdev); | 72 | pci_restore_state(dev->pdev); |
390 | if (pci_enable_device(dev->pdev)) | 73 | if (pci_enable_device(dev->pdev)) |
391 | return -1; | 74 | return -1; |
392 | pci_set_master(dev->pdev); | 75 | pci_set_master(dev->pdev); |
393 | 76 | ||
394 | pci_write_config_byte(dev->pdev, LBB, dev_priv->saveLBB); | 77 | i915_restore_state(dev); |
395 | |||
396 | I915_WRITE(DSPARB, dev_priv->saveDSPARB); | ||
397 | |||
398 | /* Pipe & plane A info */ | ||
399 | /* Prime the clock */ | ||
400 | if (dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) { | ||
401 | I915_WRITE(DPLL_A, dev_priv->saveDPLL_A & | ||
402 | ~DPLL_VCO_ENABLE); | ||
403 | udelay(150); | ||
404 | } | ||
405 | I915_WRITE(FPA0, dev_priv->saveFPA0); | ||
406 | I915_WRITE(FPA1, dev_priv->saveFPA1); | ||
407 | /* Actually enable it */ | ||
408 | I915_WRITE(DPLL_A, dev_priv->saveDPLL_A); | ||
409 | udelay(150); | ||
410 | if (IS_I965G(dev)) | ||
411 | I915_WRITE(DPLL_A_MD, dev_priv->saveDPLL_A_MD); | ||
412 | udelay(150); | ||
413 | |||
414 | /* Restore mode */ | ||
415 | I915_WRITE(HTOTAL_A, dev_priv->saveHTOTAL_A); | ||
416 | I915_WRITE(HBLANK_A, dev_priv->saveHBLANK_A); | ||
417 | I915_WRITE(HSYNC_A, dev_priv->saveHSYNC_A); | ||
418 | I915_WRITE(VTOTAL_A, dev_priv->saveVTOTAL_A); | ||
419 | I915_WRITE(VBLANK_A, dev_priv->saveVBLANK_A); | ||
420 | I915_WRITE(VSYNC_A, dev_priv->saveVSYNC_A); | ||
421 | I915_WRITE(BCLRPAT_A, dev_priv->saveBCLRPAT_A); | ||
422 | |||
423 | /* Restore plane info */ | ||
424 | I915_WRITE(DSPASIZE, dev_priv->saveDSPASIZE); | ||
425 | I915_WRITE(DSPAPOS, dev_priv->saveDSPAPOS); | ||
426 | I915_WRITE(PIPEASRC, dev_priv->savePIPEASRC); | ||
427 | I915_WRITE(DSPABASE, dev_priv->saveDSPABASE); | ||
428 | I915_WRITE(DSPASTRIDE, dev_priv->saveDSPASTRIDE); | ||
429 | if (IS_I965G(dev)) { | ||
430 | I915_WRITE(DSPASURF, dev_priv->saveDSPASURF); | ||
431 | I915_WRITE(DSPATILEOFF, dev_priv->saveDSPATILEOFF); | ||
432 | } | ||
433 | |||
434 | I915_WRITE(PIPEACONF, dev_priv->savePIPEACONF); | ||
435 | |||
436 | i915_restore_palette(dev, PIPE_A); | ||
437 | /* Enable the plane */ | ||
438 | I915_WRITE(DSPACNTR, dev_priv->saveDSPACNTR); | ||
439 | I915_WRITE(DSPABASE, I915_READ(DSPABASE)); | ||
440 | |||
441 | /* Pipe & plane B info */ | ||
442 | if (dev_priv->saveDPLL_B & DPLL_VCO_ENABLE) { | ||
443 | I915_WRITE(DPLL_B, dev_priv->saveDPLL_B & | ||
444 | ~DPLL_VCO_ENABLE); | ||
445 | udelay(150); | ||
446 | } | ||
447 | I915_WRITE(FPB0, dev_priv->saveFPB0); | ||
448 | I915_WRITE(FPB1, dev_priv->saveFPB1); | ||
449 | /* Actually enable it */ | ||
450 | I915_WRITE(DPLL_B, dev_priv->saveDPLL_B); | ||
451 | udelay(150); | ||
452 | if (IS_I965G(dev)) | ||
453 | I915_WRITE(DPLL_B_MD, dev_priv->saveDPLL_B_MD); | ||
454 | udelay(150); | ||
455 | |||
456 | /* Restore mode */ | ||
457 | I915_WRITE(HTOTAL_B, dev_priv->saveHTOTAL_B); | ||
458 | I915_WRITE(HBLANK_B, dev_priv->saveHBLANK_B); | ||
459 | I915_WRITE(HSYNC_B, dev_priv->saveHSYNC_B); | ||
460 | I915_WRITE(VTOTAL_B, dev_priv->saveVTOTAL_B); | ||
461 | I915_WRITE(VBLANK_B, dev_priv->saveVBLANK_B); | ||
462 | I915_WRITE(VSYNC_B, dev_priv->saveVSYNC_B); | ||
463 | I915_WRITE(BCLRPAT_B, dev_priv->saveBCLRPAT_B); | ||
464 | |||
465 | /* Restore plane info */ | ||
466 | I915_WRITE(DSPBSIZE, dev_priv->saveDSPBSIZE); | ||
467 | I915_WRITE(DSPBPOS, dev_priv->saveDSPBPOS); | ||
468 | I915_WRITE(PIPEBSRC, dev_priv->savePIPEBSRC); | ||
469 | I915_WRITE(DSPBBASE, dev_priv->saveDSPBBASE); | ||
470 | I915_WRITE(DSPBSTRIDE, dev_priv->saveDSPBSTRIDE); | ||
471 | if (IS_I965G(dev)) { | ||
472 | I915_WRITE(DSPBSURF, dev_priv->saveDSPBSURF); | ||
473 | I915_WRITE(DSPBTILEOFF, dev_priv->saveDSPBTILEOFF); | ||
474 | } | ||
475 | |||
476 | I915_WRITE(PIPEBCONF, dev_priv->savePIPEBCONF); | ||
477 | |||
478 | i915_restore_palette(dev, PIPE_B); | ||
479 | /* Enable the plane */ | ||
480 | I915_WRITE(DSPBCNTR, dev_priv->saveDSPBCNTR); | ||
481 | I915_WRITE(DSPBBASE, I915_READ(DSPBBASE)); | ||
482 | |||
483 | /* CRT state */ | ||
484 | I915_WRITE(ADPA, dev_priv->saveADPA); | ||
485 | |||
486 | /* LVDS state */ | ||
487 | if (IS_I965G(dev)) | ||
488 | I915_WRITE(BLC_PWM_CTL2, dev_priv->saveBLC_PWM_CTL2); | ||
489 | if (IS_MOBILE(dev) && !IS_I830(dev)) | ||
490 | I915_WRITE(LVDS, dev_priv->saveLVDS); | ||
491 | if (!IS_I830(dev) && !IS_845G(dev)) | ||
492 | I915_WRITE(PFIT_CONTROL, dev_priv->savePFIT_CONTROL); | ||
493 | |||
494 | I915_WRITE(PFIT_PGM_RATIOS, dev_priv->savePFIT_PGM_RATIOS); | ||
495 | I915_WRITE(BLC_PWM_CTL, dev_priv->saveBLC_PWM_CTL); | ||
496 | I915_WRITE(LVDSPP_ON, dev_priv->saveLVDSPP_ON); | ||
497 | I915_WRITE(LVDSPP_OFF, dev_priv->saveLVDSPP_OFF); | ||
498 | I915_WRITE(PP_CYCLE, dev_priv->savePP_CYCLE); | ||
499 | I915_WRITE(PP_CONTROL, dev_priv->savePP_CONTROL); | ||
500 | |||
501 | /* FIXME: restore TV & SDVO state */ | ||
502 | |||
503 | /* FBC info */ | ||
504 | I915_WRITE(FBC_CFB_BASE, dev_priv->saveFBC_CFB_BASE); | ||
505 | I915_WRITE(FBC_LL_BASE, dev_priv->saveFBC_LL_BASE); | ||
506 | I915_WRITE(FBC_CONTROL2, dev_priv->saveFBC_CONTROL2); | ||
507 | I915_WRITE(FBC_CONTROL, dev_priv->saveFBC_CONTROL); | ||
508 | |||
509 | /* VGA state */ | ||
510 | I915_WRITE(VGACNTRL, dev_priv->saveVGACNTRL); | ||
511 | I915_WRITE(VCLK_DIVISOR_VGA0, dev_priv->saveVCLK_DIVISOR_VGA0); | ||
512 | I915_WRITE(VCLK_DIVISOR_VGA1, dev_priv->saveVCLK_DIVISOR_VGA1); | ||
513 | I915_WRITE(VCLK_POST_DIV, dev_priv->saveVCLK_POST_DIV); | ||
514 | udelay(150); | ||
515 | |||
516 | /* Clock gating state */ | ||
517 | I915_WRITE (D_STATE, dev_priv->saveD_STATE); | ||
518 | I915_WRITE (DSPCLK_GATE_D, dev_priv->saveDSPCLK_GATE_D); | ||
519 | |||
520 | /* Cache mode state */ | ||
521 | I915_WRITE (CACHE_MODE_0, dev_priv->saveCACHE_MODE_0 | 0xffff0000); | ||
522 | |||
523 | /* Memory arbitration state */ | ||
524 | I915_WRITE (MI_ARB_STATE, dev_priv->saveMI_ARB_STATE | 0xffff0000); | ||
525 | |||
526 | for (i = 0; i < 16; i++) { | ||
527 | I915_WRITE(SWF0 + (i << 2), dev_priv->saveSWF0[i]); | ||
528 | I915_WRITE(SWF10 + (i << 2), dev_priv->saveSWF1[i+7]); | ||
529 | } | ||
530 | for (i = 0; i < 3; i++) | ||
531 | I915_WRITE(SWF30 + (i << 2), dev_priv->saveSWF2[i]); | ||
532 | 78 | ||
533 | i915_restore_vga(dev); | 79 | intel_opregion_init(dev); |
534 | 80 | ||
535 | return 0; | 81 | return 0; |
536 | } | 82 | } |
@@ -541,17 +87,19 @@ static struct drm_driver driver = { | |||
541 | */ | 87 | */ |
542 | .driver_features = | 88 | .driver_features = |
543 | DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | /* DRIVER_USE_MTRR |*/ | 89 | DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | /* DRIVER_USE_MTRR |*/ |
544 | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL | | 90 | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM, |
545 | DRIVER_IRQ_VBL2, | ||
546 | .load = i915_driver_load, | 91 | .load = i915_driver_load, |
547 | .unload = i915_driver_unload, | 92 | .unload = i915_driver_unload, |
93 | .open = i915_driver_open, | ||
548 | .lastclose = i915_driver_lastclose, | 94 | .lastclose = i915_driver_lastclose, |
549 | .preclose = i915_driver_preclose, | 95 | .preclose = i915_driver_preclose, |
96 | .postclose = i915_driver_postclose, | ||
550 | .suspend = i915_suspend, | 97 | .suspend = i915_suspend, |
551 | .resume = i915_resume, | 98 | .resume = i915_resume, |
552 | .device_is_agp = i915_driver_device_is_agp, | 99 | .device_is_agp = i915_driver_device_is_agp, |
553 | .vblank_wait = i915_driver_vblank_wait, | 100 | .get_vblank_counter = i915_get_vblank_counter, |
554 | .vblank_wait2 = i915_driver_vblank_wait2, | 101 | .enable_vblank = i915_enable_vblank, |
102 | .disable_vblank = i915_disable_vblank, | ||
555 | .irq_preinstall = i915_driver_irq_preinstall, | 103 | .irq_preinstall = i915_driver_irq_preinstall, |
556 | .irq_postinstall = i915_driver_irq_postinstall, | 104 | .irq_postinstall = i915_driver_irq_postinstall, |
557 | .irq_uninstall = i915_driver_irq_uninstall, | 105 | .irq_uninstall = i915_driver_irq_uninstall, |
@@ -559,6 +107,10 @@ static struct drm_driver driver = { | |||
559 | .reclaim_buffers = drm_core_reclaim_buffers, | 107 | .reclaim_buffers = drm_core_reclaim_buffers, |
560 | .get_map_ofs = drm_core_get_map_ofs, | 108 | .get_map_ofs = drm_core_get_map_ofs, |
561 | .get_reg_ofs = drm_core_get_reg_ofs, | 109 | .get_reg_ofs = drm_core_get_reg_ofs, |
110 | .proc_init = i915_gem_proc_init, | ||
111 | .proc_cleanup = i915_gem_proc_cleanup, | ||
112 | .gem_init_object = i915_gem_init_object, | ||
113 | .gem_free_object = i915_gem_free_object, | ||
562 | .ioctls = i915_ioctls, | 114 | .ioctls = i915_ioctls, |
563 | .fops = { | 115 | .fops = { |
564 | .owner = THIS_MODULE, | 116 | .owner = THIS_MODULE, |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index d7326d92a237..eae4ed3956e0 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -30,6 +30,8 @@ | |||
30 | #ifndef _I915_DRV_H_ | 30 | #ifndef _I915_DRV_H_ |
31 | #define _I915_DRV_H_ | 31 | #define _I915_DRV_H_ |
32 | 32 | ||
33 | #include "i915_reg.h" | ||
34 | |||
33 | /* General customization: | 35 | /* General customization: |
34 | */ | 36 | */ |
35 | 37 | ||
@@ -37,7 +39,12 @@ | |||
37 | 39 | ||
38 | #define DRIVER_NAME "i915" | 40 | #define DRIVER_NAME "i915" |
39 | #define DRIVER_DESC "Intel Graphics" | 41 | #define DRIVER_DESC "Intel Graphics" |
40 | #define DRIVER_DATE "20060119" | 42 | #define DRIVER_DATE "20080730" |
43 | |||
44 | enum pipe { | ||
45 | PIPE_A = 0, | ||
46 | PIPE_B, | ||
47 | }; | ||
41 | 48 | ||
42 | /* Interface history: | 49 | /* Interface history: |
43 | * | 50 | * |
@@ -53,16 +60,23 @@ | |||
53 | #define DRIVER_MINOR 6 | 60 | #define DRIVER_MINOR 6 |
54 | #define DRIVER_PATCHLEVEL 0 | 61 | #define DRIVER_PATCHLEVEL 0 |
55 | 62 | ||
63 | #define WATCH_COHERENCY 0 | ||
64 | #define WATCH_BUF 0 | ||
65 | #define WATCH_EXEC 0 | ||
66 | #define WATCH_LRU 0 | ||
67 | #define WATCH_RELOC 0 | ||
68 | #define WATCH_INACTIVE 0 | ||
69 | #define WATCH_PWRITE 0 | ||
70 | |||
56 | typedef struct _drm_i915_ring_buffer { | 71 | typedef struct _drm_i915_ring_buffer { |
57 | int tail_mask; | 72 | int tail_mask; |
58 | unsigned long Start; | ||
59 | unsigned long End; | ||
60 | unsigned long Size; | 73 | unsigned long Size; |
61 | u8 *virtual_start; | 74 | u8 *virtual_start; |
62 | int head; | 75 | int head; |
63 | int tail; | 76 | int tail; |
64 | int space; | 77 | int space; |
65 | drm_local_map_t map; | 78 | drm_local_map_t map; |
79 | struct drm_gem_object *ring_obj; | ||
66 | } drm_i915_ring_buffer_t; | 80 | } drm_i915_ring_buffer_t; |
67 | 81 | ||
68 | struct mem_block { | 82 | struct mem_block { |
@@ -76,13 +90,28 @@ struct mem_block { | |||
76 | typedef struct _drm_i915_vbl_swap { | 90 | typedef struct _drm_i915_vbl_swap { |
77 | struct list_head head; | 91 | struct list_head head; |
78 | drm_drawable_t drw_id; | 92 | drm_drawable_t drw_id; |
79 | unsigned int pipe; | 93 | unsigned int plane; |
80 | unsigned int sequence; | 94 | unsigned int sequence; |
81 | } drm_i915_vbl_swap_t; | 95 | } drm_i915_vbl_swap_t; |
82 | 96 | ||
97 | struct opregion_header; | ||
98 | struct opregion_acpi; | ||
99 | struct opregion_swsci; | ||
100 | struct opregion_asle; | ||
101 | |||
102 | struct intel_opregion { | ||
103 | struct opregion_header *header; | ||
104 | struct opregion_acpi *acpi; | ||
105 | struct opregion_swsci *swsci; | ||
106 | struct opregion_asle *asle; | ||
107 | int enabled; | ||
108 | }; | ||
109 | |||
83 | typedef struct drm_i915_private { | 110 | typedef struct drm_i915_private { |
111 | struct drm_device *dev; | ||
112 | |||
113 | void __iomem *regs; | ||
84 | drm_local_map_t *sarea; | 114 | drm_local_map_t *sarea; |
85 | drm_local_map_t *mmio_map; | ||
86 | 115 | ||
87 | drm_i915_sarea_t *sarea_priv; | 116 | drm_i915_sarea_t *sarea_priv; |
88 | drm_i915_ring_buffer_t ring; | 117 | drm_i915_ring_buffer_t ring; |
@@ -90,20 +119,25 @@ typedef struct drm_i915_private { | |||
90 | drm_dma_handle_t *status_page_dmah; | 119 | drm_dma_handle_t *status_page_dmah; |
91 | void *hw_status_page; | 120 | void *hw_status_page; |
92 | dma_addr_t dma_status_page; | 121 | dma_addr_t dma_status_page; |
93 | unsigned long counter; | 122 | uint32_t counter; |
94 | unsigned int status_gfx_addr; | 123 | unsigned int status_gfx_addr; |
95 | drm_local_map_t hws_map; | 124 | drm_local_map_t hws_map; |
125 | struct drm_gem_object *hws_obj; | ||
96 | 126 | ||
97 | unsigned int cpp; | 127 | unsigned int cpp; |
98 | int back_offset; | 128 | int back_offset; |
99 | int front_offset; | 129 | int front_offset; |
100 | int current_page; | 130 | int current_page; |
101 | int page_flipping; | 131 | int page_flipping; |
102 | int use_mi_batchbuffer_start; | ||
103 | 132 | ||
104 | wait_queue_head_t irq_queue; | 133 | wait_queue_head_t irq_queue; |
105 | atomic_t irq_received; | 134 | atomic_t irq_received; |
106 | atomic_t irq_emitted; | 135 | /** Protects user_irq_refcount and irq_mask_reg */ |
136 | spinlock_t user_irq_lock; | ||
137 | /** Refcount for i915_user_irq_get() versus i915_user_irq_put(). */ | ||
138 | int user_irq_refcount; | ||
139 | /** Cached value of IMR to avoid reads in updating the bitfield */ | ||
140 | u32 irq_mask_reg; | ||
107 | 141 | ||
108 | int tex_lru_log_granularity; | 142 | int tex_lru_log_granularity; |
109 | int allow_batchbuffer; | 143 | int allow_batchbuffer; |
@@ -115,6 +149,8 @@ typedef struct drm_i915_private { | |||
115 | drm_i915_vbl_swap_t vbl_swaps; | 149 | drm_i915_vbl_swap_t vbl_swaps; |
116 | unsigned int swaps_pending; | 150 | unsigned int swaps_pending; |
117 | 151 | ||
152 | struct intel_opregion opregion; | ||
153 | |||
118 | /* Register state */ | 154 | /* Register state */ |
119 | u8 saveLBB; | 155 | u8 saveLBB; |
120 | u32 saveDSPACNTR; | 156 | u32 saveDSPACNTR; |
@@ -139,7 +175,7 @@ typedef struct drm_i915_private { | |||
139 | u32 saveDSPASTRIDE; | 175 | u32 saveDSPASTRIDE; |
140 | u32 saveDSPASIZE; | 176 | u32 saveDSPASIZE; |
141 | u32 saveDSPAPOS; | 177 | u32 saveDSPAPOS; |
142 | u32 saveDSPABASE; | 178 | u32 saveDSPAADDR; |
143 | u32 saveDSPASURF; | 179 | u32 saveDSPASURF; |
144 | u32 saveDSPATILEOFF; | 180 | u32 saveDSPATILEOFF; |
145 | u32 savePFIT_PGM_RATIOS; | 181 | u32 savePFIT_PGM_RATIOS; |
@@ -160,24 +196,24 @@ typedef struct drm_i915_private { | |||
160 | u32 saveDSPBSTRIDE; | 196 | u32 saveDSPBSTRIDE; |
161 | u32 saveDSPBSIZE; | 197 | u32 saveDSPBSIZE; |
162 | u32 saveDSPBPOS; | 198 | u32 saveDSPBPOS; |
163 | u32 saveDSPBBASE; | 199 | u32 saveDSPBADDR; |
164 | u32 saveDSPBSURF; | 200 | u32 saveDSPBSURF; |
165 | u32 saveDSPBTILEOFF; | 201 | u32 saveDSPBTILEOFF; |
166 | u32 saveVCLK_DIVISOR_VGA0; | 202 | u32 saveVGA0; |
167 | u32 saveVCLK_DIVISOR_VGA1; | 203 | u32 saveVGA1; |
168 | u32 saveVCLK_POST_DIV; | 204 | u32 saveVGA_PD; |
169 | u32 saveVGACNTRL; | 205 | u32 saveVGACNTRL; |
170 | u32 saveADPA; | 206 | u32 saveADPA; |
171 | u32 saveLVDS; | 207 | u32 saveLVDS; |
172 | u32 saveLVDSPP_ON; | 208 | u32 savePP_ON_DELAYS; |
173 | u32 saveLVDSPP_OFF; | 209 | u32 savePP_OFF_DELAYS; |
174 | u32 saveDVOA; | 210 | u32 saveDVOA; |
175 | u32 saveDVOB; | 211 | u32 saveDVOB; |
176 | u32 saveDVOC; | 212 | u32 saveDVOC; |
177 | u32 savePP_ON; | 213 | u32 savePP_ON; |
178 | u32 savePP_OFF; | 214 | u32 savePP_OFF; |
179 | u32 savePP_CONTROL; | 215 | u32 savePP_CONTROL; |
180 | u32 savePP_CYCLE; | 216 | u32 savePP_DIVISOR; |
181 | u32 savePFIT_CONTROL; | 217 | u32 savePFIT_CONTROL; |
182 | u32 save_palette_a[256]; | 218 | u32 save_palette_a[256]; |
183 | u32 save_palette_b[256]; | 219 | u32 save_palette_b[256]; |
@@ -190,7 +226,7 @@ typedef struct drm_i915_private { | |||
190 | u32 saveIMR; | 226 | u32 saveIMR; |
191 | u32 saveCACHE_MODE_0; | 227 | u32 saveCACHE_MODE_0; |
192 | u32 saveD_STATE; | 228 | u32 saveD_STATE; |
193 | u32 saveDSPCLK_GATE_D; | 229 | u32 saveCG_2D_DIS; |
194 | u32 saveMI_ARB_STATE; | 230 | u32 saveMI_ARB_STATE; |
195 | u32 saveSWF0[16]; | 231 | u32 saveSWF0[16]; |
196 | u32 saveSWF1[16]; | 232 | u32 saveSWF1[16]; |
@@ -203,8 +239,180 @@ typedef struct drm_i915_private { | |||
203 | u8 saveDACMASK; | 239 | u8 saveDACMASK; |
204 | u8 saveDACDATA[256*3]; /* 256 3-byte colors */ | 240 | u8 saveDACDATA[256*3]; /* 256 3-byte colors */ |
205 | u8 saveCR[37]; | 241 | u8 saveCR[37]; |
242 | |||
243 | struct { | ||
244 | struct drm_mm gtt_space; | ||
245 | |||
246 | /** | ||
247 | * List of objects currently involved in rendering from the | ||
248 | * ringbuffer. | ||
249 | * | ||
250 | * A reference is held on the buffer while on this list. | ||
251 | */ | ||
252 | struct list_head active_list; | ||
253 | |||
254 | /** | ||
255 | * List of objects which are not in the ringbuffer but which | ||
256 | * still have a write_domain which needs to be flushed before | ||
257 | * unbinding. | ||
258 | * | ||
259 | * A reference is held on the buffer while on this list. | ||
260 | */ | ||
261 | struct list_head flushing_list; | ||
262 | |||
263 | /** | ||
264 | * LRU list of objects which are not in the ringbuffer and | ||
265 | * are ready to unbind, but are still in the GTT. | ||
266 | * | ||
267 | * A reference is not held on the buffer while on this list, | ||
268 | * as merely being GTT-bound shouldn't prevent its being | ||
269 | * freed, and we'll pull it off the list in the free path. | ||
270 | */ | ||
271 | struct list_head inactive_list; | ||
272 | |||
273 | /** | ||
274 | * List of breadcrumbs associated with GPU requests currently | ||
275 | * outstanding. | ||
276 | */ | ||
277 | struct list_head request_list; | ||
278 | |||
279 | /** | ||
280 | * We leave the user IRQ off as much as possible, | ||
281 | * but this means that requests will finish and never | ||
282 | * be retired once the system goes idle. Set a timer to | ||
283 | * fire periodically while the ring is running. When it | ||
284 | * fires, go retire requests. | ||
285 | */ | ||
286 | struct delayed_work retire_work; | ||
287 | |||
288 | /** Work task for vblank-related ring access */ | ||
289 | struct work_struct vblank_work; | ||
290 | |||
291 | uint32_t next_gem_seqno; | ||
292 | |||
293 | /** | ||
294 | * Waiting sequence number, if any | ||
295 | */ | ||
296 | uint32_t waiting_gem_seqno; | ||
297 | |||
298 | /** | ||
299 | * Last seq seen at irq time | ||
300 | */ | ||
301 | uint32_t irq_gem_seqno; | ||
302 | |||
303 | /** | ||
304 | * Flag if the X Server, and thus DRM, is not currently in | ||
305 | * control of the device. | ||
306 | * | ||
307 | * This is set between LeaveVT and EnterVT. It needs to be | ||
308 | * replaced with a semaphore. It also needs to be | ||
309 | * transitioned away from for kernel modesetting. | ||
310 | */ | ||
311 | int suspended; | ||
312 | |||
313 | /** | ||
314 | * Flag if the hardware appears to be wedged. | ||
315 | * | ||
316 | * This is set when attempts to idle the device timeout. | ||
317 | * It prevents command submission from occuring and makes | ||
318 | * every pending request fail | ||
319 | */ | ||
320 | int wedged; | ||
321 | |||
322 | /** Bit 6 swizzling required for X tiling */ | ||
323 | uint32_t bit_6_swizzle_x; | ||
324 | /** Bit 6 swizzling required for Y tiling */ | ||
325 | uint32_t bit_6_swizzle_y; | ||
326 | } mm; | ||
206 | } drm_i915_private_t; | 327 | } drm_i915_private_t; |
207 | 328 | ||
329 | /** driver private structure attached to each drm_gem_object */ | ||
330 | struct drm_i915_gem_object { | ||
331 | struct drm_gem_object *obj; | ||
332 | |||
333 | /** Current space allocated to this object in the GTT, if any. */ | ||
334 | struct drm_mm_node *gtt_space; | ||
335 | |||
336 | /** This object's place on the active/flushing/inactive lists */ | ||
337 | struct list_head list; | ||
338 | |||
339 | /** | ||
340 | * This is set if the object is on the active or flushing lists | ||
341 | * (has pending rendering), and is not set if it's on inactive (ready | ||
342 | * to be unbound). | ||
343 | */ | ||
344 | int active; | ||
345 | |||
346 | /** | ||
347 | * This is set if the object has been written to since last bound | ||
348 | * to the GTT | ||
349 | */ | ||
350 | int dirty; | ||
351 | |||
352 | /** AGP memory structure for our GTT binding. */ | ||
353 | DRM_AGP_MEM *agp_mem; | ||
354 | |||
355 | struct page **page_list; | ||
356 | |||
357 | /** | ||
358 | * Current offset of the object in GTT space. | ||
359 | * | ||
360 | * This is the same as gtt_space->start | ||
361 | */ | ||
362 | uint32_t gtt_offset; | ||
363 | |||
364 | /** Boolean whether this object has a valid gtt offset. */ | ||
365 | int gtt_bound; | ||
366 | |||
367 | /** How many users have pinned this object in GTT space */ | ||
368 | int pin_count; | ||
369 | |||
370 | /** Breadcrumb of last rendering to the buffer. */ | ||
371 | uint32_t last_rendering_seqno; | ||
372 | |||
373 | /** Current tiling mode for the object. */ | ||
374 | uint32_t tiling_mode; | ||
375 | |||
376 | /** AGP mapping type (AGP_USER_MEMORY or AGP_USER_CACHED_MEMORY */ | ||
377 | uint32_t agp_type; | ||
378 | |||
379 | /** | ||
380 | * Flagging of which individual pages are valid in GEM_DOMAIN_CPU when | ||
381 | * GEM_DOMAIN_CPU is not in the object's read domain. | ||
382 | */ | ||
383 | uint8_t *page_cpu_valid; | ||
384 | }; | ||
385 | |||
386 | /** | ||
387 | * Request queue structure. | ||
388 | * | ||
389 | * The request queue allows us to note sequence numbers that have been emitted | ||
390 | * and may be associated with active buffers to be retired. | ||
391 | * | ||
392 | * By keeping this list, we can avoid having to do questionable | ||
393 | * sequence-number comparisons on buffer last_rendering_seqnos, and associate | ||
394 | * an emission time with seqnos for tracking how far ahead of the GPU we are. | ||
395 | */ | ||
396 | struct drm_i915_gem_request { | ||
397 | /** GEM sequence number associated with this request. */ | ||
398 | uint32_t seqno; | ||
399 | |||
400 | /** Time at which this request was emitted, in jiffies. */ | ||
401 | unsigned long emitted_jiffies; | ||
402 | |||
403 | /** Cache domains that were flushed at the start of the request. */ | ||
404 | uint32_t flush_domains; | ||
405 | |||
406 | struct list_head list; | ||
407 | }; | ||
408 | |||
409 | struct drm_i915_file_private { | ||
410 | struct { | ||
411 | uint32_t last_gem_seqno; | ||
412 | uint32_t last_gem_throttle_seqno; | ||
413 | } mm; | ||
414 | }; | ||
415 | |||
208 | extern struct drm_ioctl_desc i915_ioctls[]; | 416 | extern struct drm_ioctl_desc i915_ioctls[]; |
209 | extern int i915_max_ioctl; | 417 | extern int i915_max_ioctl; |
210 | 418 | ||
@@ -212,31 +420,42 @@ extern int i915_max_ioctl; | |||
212 | extern void i915_kernel_lost_context(struct drm_device * dev); | 420 | extern void i915_kernel_lost_context(struct drm_device * dev); |
213 | extern int i915_driver_load(struct drm_device *, unsigned long flags); | 421 | extern int i915_driver_load(struct drm_device *, unsigned long flags); |
214 | extern int i915_driver_unload(struct drm_device *); | 422 | extern int i915_driver_unload(struct drm_device *); |
423 | extern int i915_driver_open(struct drm_device *dev, struct drm_file *file_priv); | ||
215 | extern void i915_driver_lastclose(struct drm_device * dev); | 424 | extern void i915_driver_lastclose(struct drm_device * dev); |
216 | extern void i915_driver_preclose(struct drm_device *dev, | 425 | extern void i915_driver_preclose(struct drm_device *dev, |
217 | struct drm_file *file_priv); | 426 | struct drm_file *file_priv); |
427 | extern void i915_driver_postclose(struct drm_device *dev, | ||
428 | struct drm_file *file_priv); | ||
218 | extern int i915_driver_device_is_agp(struct drm_device * dev); | 429 | extern int i915_driver_device_is_agp(struct drm_device * dev); |
219 | extern long i915_compat_ioctl(struct file *filp, unsigned int cmd, | 430 | extern long i915_compat_ioctl(struct file *filp, unsigned int cmd, |
220 | unsigned long arg); | 431 | unsigned long arg); |
432 | extern int i915_emit_box(struct drm_device *dev, | ||
433 | struct drm_clip_rect __user *boxes, | ||
434 | int i, int DR1, int DR4); | ||
221 | 435 | ||
222 | /* i915_irq.c */ | 436 | /* i915_irq.c */ |
223 | extern int i915_irq_emit(struct drm_device *dev, void *data, | 437 | extern int i915_irq_emit(struct drm_device *dev, void *data, |
224 | struct drm_file *file_priv); | 438 | struct drm_file *file_priv); |
225 | extern int i915_irq_wait(struct drm_device *dev, void *data, | 439 | extern int i915_irq_wait(struct drm_device *dev, void *data, |
226 | struct drm_file *file_priv); | 440 | struct drm_file *file_priv); |
441 | void i915_user_irq_get(struct drm_device *dev); | ||
442 | void i915_user_irq_put(struct drm_device *dev); | ||
227 | 443 | ||
228 | extern int i915_driver_vblank_wait(struct drm_device *dev, unsigned int *sequence); | 444 | extern void i915_gem_vblank_work_handler(struct work_struct *work); |
229 | extern int i915_driver_vblank_wait2(struct drm_device *dev, unsigned int *sequence); | ||
230 | extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS); | 445 | extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS); |
231 | extern void i915_driver_irq_preinstall(struct drm_device * dev); | 446 | extern void i915_driver_irq_preinstall(struct drm_device * dev); |
232 | extern void i915_driver_irq_postinstall(struct drm_device * dev); | 447 | extern int i915_driver_irq_postinstall(struct drm_device *dev); |
233 | extern void i915_driver_irq_uninstall(struct drm_device * dev); | 448 | extern void i915_driver_irq_uninstall(struct drm_device * dev); |
234 | extern int i915_vblank_pipe_set(struct drm_device *dev, void *data, | 449 | extern int i915_vblank_pipe_set(struct drm_device *dev, void *data, |
235 | struct drm_file *file_priv); | 450 | struct drm_file *file_priv); |
236 | extern int i915_vblank_pipe_get(struct drm_device *dev, void *data, | 451 | extern int i915_vblank_pipe_get(struct drm_device *dev, void *data, |
237 | struct drm_file *file_priv); | 452 | struct drm_file *file_priv); |
453 | extern int i915_enable_vblank(struct drm_device *dev, int crtc); | ||
454 | extern void i915_disable_vblank(struct drm_device *dev, int crtc); | ||
455 | extern u32 i915_get_vblank_counter(struct drm_device *dev, int crtc); | ||
238 | extern int i915_vblank_swap(struct drm_device *dev, void *data, | 456 | extern int i915_vblank_swap(struct drm_device *dev, void *data, |
239 | struct drm_file *file_priv); | 457 | struct drm_file *file_priv); |
458 | extern void i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask); | ||
240 | 459 | ||
241 | /* i915_mem.c */ | 460 | /* i915_mem.c */ |
242 | extern int i915_mem_alloc(struct drm_device *dev, void *data, | 461 | extern int i915_mem_alloc(struct drm_device *dev, void *data, |
@@ -250,11 +469,99 @@ extern int i915_mem_destroy_heap(struct drm_device *dev, void *data, | |||
250 | extern void i915_mem_takedown(struct mem_block **heap); | 469 | extern void i915_mem_takedown(struct mem_block **heap); |
251 | extern void i915_mem_release(struct drm_device * dev, | 470 | extern void i915_mem_release(struct drm_device * dev, |
252 | struct drm_file *file_priv, struct mem_block *heap); | 471 | struct drm_file *file_priv, struct mem_block *heap); |
472 | /* i915_gem.c */ | ||
473 | int i915_gem_init_ioctl(struct drm_device *dev, void *data, | ||
474 | struct drm_file *file_priv); | ||
475 | int i915_gem_create_ioctl(struct drm_device *dev, void *data, | ||
476 | struct drm_file *file_priv); | ||
477 | int i915_gem_pread_ioctl(struct drm_device *dev, void *data, | ||
478 | struct drm_file *file_priv); | ||
479 | int i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, | ||
480 | struct drm_file *file_priv); | ||
481 | int i915_gem_mmap_ioctl(struct drm_device *dev, void *data, | ||
482 | struct drm_file *file_priv); | ||
483 | int i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, | ||
484 | struct drm_file *file_priv); | ||
485 | int i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data, | ||
486 | struct drm_file *file_priv); | ||
487 | int i915_gem_execbuffer(struct drm_device *dev, void *data, | ||
488 | struct drm_file *file_priv); | ||
489 | int i915_gem_pin_ioctl(struct drm_device *dev, void *data, | ||
490 | struct drm_file *file_priv); | ||
491 | int i915_gem_unpin_ioctl(struct drm_device *dev, void *data, | ||
492 | struct drm_file *file_priv); | ||
493 | int i915_gem_busy_ioctl(struct drm_device *dev, void *data, | ||
494 | struct drm_file *file_priv); | ||
495 | int i915_gem_throttle_ioctl(struct drm_device *dev, void *data, | ||
496 | struct drm_file *file_priv); | ||
497 | int i915_gem_entervt_ioctl(struct drm_device *dev, void *data, | ||
498 | struct drm_file *file_priv); | ||
499 | int i915_gem_leavevt_ioctl(struct drm_device *dev, void *data, | ||
500 | struct drm_file *file_priv); | ||
501 | int i915_gem_set_tiling(struct drm_device *dev, void *data, | ||
502 | struct drm_file *file_priv); | ||
503 | int i915_gem_get_tiling(struct drm_device *dev, void *data, | ||
504 | struct drm_file *file_priv); | ||
505 | void i915_gem_load(struct drm_device *dev); | ||
506 | int i915_gem_proc_init(struct drm_minor *minor); | ||
507 | void i915_gem_proc_cleanup(struct drm_minor *minor); | ||
508 | int i915_gem_init_object(struct drm_gem_object *obj); | ||
509 | void i915_gem_free_object(struct drm_gem_object *obj); | ||
510 | int i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment); | ||
511 | void i915_gem_object_unpin(struct drm_gem_object *obj); | ||
512 | void i915_gem_lastclose(struct drm_device *dev); | ||
513 | uint32_t i915_get_gem_seqno(struct drm_device *dev); | ||
514 | void i915_gem_retire_requests(struct drm_device *dev); | ||
515 | void i915_gem_retire_work_handler(struct work_struct *work); | ||
516 | void i915_gem_clflush_object(struct drm_gem_object *obj); | ||
517 | |||
518 | /* i915_gem_tiling.c */ | ||
519 | void i915_gem_detect_bit_6_swizzle(struct drm_device *dev); | ||
520 | |||
521 | /* i915_gem_debug.c */ | ||
522 | void i915_gem_dump_object(struct drm_gem_object *obj, int len, | ||
523 | const char *where, uint32_t mark); | ||
524 | #if WATCH_INACTIVE | ||
525 | void i915_verify_inactive(struct drm_device *dev, char *file, int line); | ||
526 | #else | ||
527 | #define i915_verify_inactive(dev, file, line) | ||
528 | #endif | ||
529 | void i915_gem_object_check_coherency(struct drm_gem_object *obj, int handle); | ||
530 | void i915_gem_dump_object(struct drm_gem_object *obj, int len, | ||
531 | const char *where, uint32_t mark); | ||
532 | void i915_dump_lru(struct drm_device *dev, const char *where); | ||
533 | |||
534 | /* i915_suspend.c */ | ||
535 | extern int i915_save_state(struct drm_device *dev); | ||
536 | extern int i915_restore_state(struct drm_device *dev); | ||
537 | |||
538 | /* i915_suspend.c */ | ||
539 | extern int i915_save_state(struct drm_device *dev); | ||
540 | extern int i915_restore_state(struct drm_device *dev); | ||
541 | |||
542 | /* i915_opregion.c */ | ||
543 | extern int intel_opregion_init(struct drm_device *dev); | ||
544 | extern void intel_opregion_free(struct drm_device *dev); | ||
545 | extern void opregion_asle_intr(struct drm_device *dev); | ||
546 | extern void opregion_enable_asle(struct drm_device *dev); | ||
547 | |||
548 | /** | ||
549 | * Lock test for when it's just for synchronization of ring access. | ||
550 | * | ||
551 | * In that case, we don't need to do it when GEM is initialized as nobody else | ||
552 | * has access to the ring. | ||
553 | */ | ||
554 | #define RING_LOCK_TEST_WITH_RETURN(dev, file_priv) do { \ | ||
555 | if (((drm_i915_private_t *)dev->dev_private)->ring.ring_obj == NULL) \ | ||
556 | LOCK_TEST_WITH_RETURN(dev, file_priv); \ | ||
557 | } while (0) | ||
253 | 558 | ||
254 | #define I915_READ(reg) DRM_READ32(dev_priv->mmio_map, (reg)) | 559 | #define I915_READ(reg) readl(dev_priv->regs + (reg)) |
255 | #define I915_WRITE(reg,val) DRM_WRITE32(dev_priv->mmio_map, (reg), (val)) | 560 | #define I915_WRITE(reg, val) writel(val, dev_priv->regs + (reg)) |
256 | #define I915_READ16(reg) DRM_READ16(dev_priv->mmio_map, (reg)) | 561 | #define I915_READ16(reg) readw(dev_priv->regs + (reg)) |
257 | #define I915_WRITE16(reg,val) DRM_WRITE16(dev_priv->mmio_map, (reg), (val)) | 562 | #define I915_WRITE16(reg, val) writel(val, dev_priv->regs + (reg)) |
563 | #define I915_READ8(reg) readb(dev_priv->regs + (reg)) | ||
564 | #define I915_WRITE8(reg, val) writeb(val, dev_priv->regs + (reg)) | ||
258 | 565 | ||
259 | #define I915_VERBOSE 0 | 566 | #define I915_VERBOSE 0 |
260 | 567 | ||
@@ -284,816 +591,29 @@ extern void i915_mem_release(struct drm_device * dev, | |||
284 | if (I915_VERBOSE) DRM_DEBUG("ADVANCE_LP_RING %x\n", outring); \ | 591 | if (I915_VERBOSE) DRM_DEBUG("ADVANCE_LP_RING %x\n", outring); \ |
285 | dev_priv->ring.tail = outring; \ | 592 | dev_priv->ring.tail = outring; \ |
286 | dev_priv->ring.space -= outcount * 4; \ | 593 | dev_priv->ring.space -= outcount * 4; \ |
287 | I915_WRITE(LP_RING + RING_TAIL, outring); \ | 594 | I915_WRITE(PRB0_TAIL, outring); \ |
288 | } while(0) | 595 | } while(0) |
289 | 596 | ||
290 | extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); | ||
291 | |||
292 | /* Extended config space */ | ||
293 | #define LBB 0xf4 | ||
294 | |||
295 | /* VGA stuff */ | ||
296 | |||
297 | #define VGA_ST01_MDA 0x3ba | ||
298 | #define VGA_ST01_CGA 0x3da | ||
299 | |||
300 | #define VGA_MSR_WRITE 0x3c2 | ||
301 | #define VGA_MSR_READ 0x3cc | ||
302 | #define VGA_MSR_MEM_EN (1<<1) | ||
303 | #define VGA_MSR_CGA_MODE (1<<0) | ||
304 | |||
305 | #define VGA_SR_INDEX 0x3c4 | ||
306 | #define VGA_SR_DATA 0x3c5 | ||
307 | |||
308 | #define VGA_AR_INDEX 0x3c0 | ||
309 | #define VGA_AR_VID_EN (1<<5) | ||
310 | #define VGA_AR_DATA_WRITE 0x3c0 | ||
311 | #define VGA_AR_DATA_READ 0x3c1 | ||
312 | |||
313 | #define VGA_GR_INDEX 0x3ce | ||
314 | #define VGA_GR_DATA 0x3cf | ||
315 | /* GR05 */ | ||
316 | #define VGA_GR_MEM_READ_MODE_SHIFT 3 | ||
317 | #define VGA_GR_MEM_READ_MODE_PLANE 1 | ||
318 | /* GR06 */ | ||
319 | #define VGA_GR_MEM_MODE_MASK 0xc | ||
320 | #define VGA_GR_MEM_MODE_SHIFT 2 | ||
321 | #define VGA_GR_MEM_A0000_AFFFF 0 | ||
322 | #define VGA_GR_MEM_A0000_BFFFF 1 | ||
323 | #define VGA_GR_MEM_B0000_B7FFF 2 | ||
324 | #define VGA_GR_MEM_B0000_BFFFF 3 | ||
325 | |||
326 | #define VGA_DACMASK 0x3c6 | ||
327 | #define VGA_DACRX 0x3c7 | ||
328 | #define VGA_DACWX 0x3c8 | ||
329 | #define VGA_DACDATA 0x3c9 | ||
330 | |||
331 | #define VGA_CR_INDEX_MDA 0x3b4 | ||
332 | #define VGA_CR_DATA_MDA 0x3b5 | ||
333 | #define VGA_CR_INDEX_CGA 0x3d4 | ||
334 | #define VGA_CR_DATA_CGA 0x3d5 | ||
335 | |||
336 | #define GFX_OP_USER_INTERRUPT ((0<<29)|(2<<23)) | ||
337 | #define GFX_OP_BREAKPOINT_INTERRUPT ((0<<29)|(1<<23)) | ||
338 | #define CMD_REPORT_HEAD (7<<23) | ||
339 | #define CMD_STORE_DWORD_IDX ((0x21<<23) | 0x1) | ||
340 | #define CMD_OP_BATCH_BUFFER ((0x0<<29)|(0x30<<23)|0x1) | ||
341 | |||
342 | #define INST_PARSER_CLIENT 0x00000000 | ||
343 | #define INST_OP_FLUSH 0x02000000 | ||
344 | #define INST_FLUSH_MAP_CACHE 0x00000001 | ||
345 | |||
346 | #define BB1_START_ADDR_MASK (~0x7) | ||
347 | #define BB1_PROTECTED (1<<0) | ||
348 | #define BB1_UNPROTECTED (0<<0) | ||
349 | #define BB2_END_ADDR_MASK (~0x7) | ||
350 | |||
351 | /* Framebuffer compression */ | ||
352 | #define FBC_CFB_BASE 0x03200 /* 4k page aligned */ | ||
353 | #define FBC_LL_BASE 0x03204 /* 4k page aligned */ | ||
354 | #define FBC_CONTROL 0x03208 | ||
355 | #define FBC_CTL_EN (1<<31) | ||
356 | #define FBC_CTL_PERIODIC (1<<30) | ||
357 | #define FBC_CTL_INTERVAL_SHIFT (16) | ||
358 | #define FBC_CTL_UNCOMPRESSIBLE (1<<14) | ||
359 | #define FBC_CTL_STRIDE_SHIFT (5) | ||
360 | #define FBC_CTL_FENCENO (1<<0) | ||
361 | #define FBC_COMMAND 0x0320c | ||
362 | #define FBC_CMD_COMPRESS (1<<0) | ||
363 | #define FBC_STATUS 0x03210 | ||
364 | #define FBC_STAT_COMPRESSING (1<<31) | ||
365 | #define FBC_STAT_COMPRESSED (1<<30) | ||
366 | #define FBC_STAT_MODIFIED (1<<29) | ||
367 | #define FBC_STAT_CURRENT_LINE (1<<0) | ||
368 | #define FBC_CONTROL2 0x03214 | ||
369 | #define FBC_CTL_FENCE_DBL (0<<4) | ||
370 | #define FBC_CTL_IDLE_IMM (0<<2) | ||
371 | #define FBC_CTL_IDLE_FULL (1<<2) | ||
372 | #define FBC_CTL_IDLE_LINE (2<<2) | ||
373 | #define FBC_CTL_IDLE_DEBUG (3<<2) | ||
374 | #define FBC_CTL_CPU_FENCE (1<<1) | ||
375 | #define FBC_CTL_PLANEA (0<<0) | ||
376 | #define FBC_CTL_PLANEB (1<<0) | ||
377 | #define FBC_FENCE_OFF 0x0321b | ||
378 | |||
379 | #define FBC_LL_SIZE (1536) | ||
380 | #define FBC_LL_PAD (32) | ||
381 | |||
382 | /* Interrupt bits: | ||
383 | */ | ||
384 | #define USER_INT_FLAG (1<<1) | ||
385 | #define VSYNC_PIPEB_FLAG (1<<5) | ||
386 | #define VSYNC_PIPEA_FLAG (1<<7) | ||
387 | #define HWB_OOM_FLAG (1<<13) /* binner out of memory */ | ||
388 | |||
389 | #define I915REG_HWSTAM 0x02098 | ||
390 | #define I915REG_INT_IDENTITY_R 0x020a4 | ||
391 | #define I915REG_INT_MASK_R 0x020a8 | ||
392 | #define I915REG_INT_ENABLE_R 0x020a0 | ||
393 | |||
394 | #define I915REG_PIPEASTAT 0x70024 | ||
395 | #define I915REG_PIPEBSTAT 0x71024 | ||
396 | |||
397 | #define I915_VBLANK_INTERRUPT_ENABLE (1UL<<17) | ||
398 | #define I915_VBLANK_CLEAR (1UL<<1) | ||
399 | |||
400 | #define SRX_INDEX 0x3c4 | ||
401 | #define SRX_DATA 0x3c5 | ||
402 | #define SR01 1 | ||
403 | #define SR01_SCREEN_OFF (1<<5) | ||
404 | |||
405 | #define PPCR 0x61204 | ||
406 | #define PPCR_ON (1<<0) | ||
407 | |||
408 | #define DVOB 0x61140 | ||
409 | #define DVOB_ON (1<<31) | ||
410 | #define DVOC 0x61160 | ||
411 | #define DVOC_ON (1<<31) | ||
412 | #define LVDS 0x61180 | ||
413 | #define LVDS_ON (1<<31) | ||
414 | |||
415 | #define ADPA 0x61100 | ||
416 | #define ADPA_DPMS_MASK (~(3<<10)) | ||
417 | #define ADPA_DPMS_ON (0<<10) | ||
418 | #define ADPA_DPMS_SUSPEND (1<<10) | ||
419 | #define ADPA_DPMS_STANDBY (2<<10) | ||
420 | #define ADPA_DPMS_OFF (3<<10) | ||
421 | |||
422 | #define NOPID 0x2094 | ||
423 | #define LP_RING 0x2030 | ||
424 | #define HP_RING 0x2040 | ||
425 | /* The binner has its own ring buffer: | ||
426 | */ | ||
427 | #define HWB_RING 0x2400 | ||
428 | |||
429 | #define RING_TAIL 0x00 | ||
430 | #define TAIL_ADDR 0x001FFFF8 | ||
431 | #define RING_HEAD 0x04 | ||
432 | #define HEAD_WRAP_COUNT 0xFFE00000 | ||
433 | #define HEAD_WRAP_ONE 0x00200000 | ||
434 | #define HEAD_ADDR 0x001FFFFC | ||
435 | #define RING_START 0x08 | ||
436 | #define START_ADDR 0x0xFFFFF000 | ||
437 | #define RING_LEN 0x0C | ||
438 | #define RING_NR_PAGES 0x001FF000 | ||
439 | #define RING_REPORT_MASK 0x00000006 | ||
440 | #define RING_REPORT_64K 0x00000002 | ||
441 | #define RING_REPORT_128K 0x00000004 | ||
442 | #define RING_NO_REPORT 0x00000000 | ||
443 | #define RING_VALID_MASK 0x00000001 | ||
444 | #define RING_VALID 0x00000001 | ||
445 | #define RING_INVALID 0x00000000 | ||
446 | |||
447 | /* Instruction parser error reg: | ||
448 | */ | ||
449 | #define IPEIR 0x2088 | ||
450 | |||
451 | /* Scratch pad debug 0 reg: | ||
452 | */ | ||
453 | #define SCPD0 0x209c | ||
454 | |||
455 | /* Error status reg: | ||
456 | */ | ||
457 | #define ESR 0x20b8 | ||
458 | |||
459 | /* Secondary DMA fetch address debug reg: | ||
460 | */ | ||
461 | #define DMA_FADD_S 0x20d4 | ||
462 | |||
463 | /* Memory Interface Arbitration State | ||
464 | */ | ||
465 | #define MI_ARB_STATE 0x20e4 | ||
466 | |||
467 | /* Cache mode 0 reg. | ||
468 | * - Manipulating render cache behaviour is central | ||
469 | * to the concept of zone rendering, tuning this reg can help avoid | ||
470 | * unnecessary render cache reads and even writes (for z/stencil) | ||
471 | * at beginning and end of scene. | ||
472 | * | ||
473 | * - To change a bit, write to this reg with a mask bit set and the | ||
474 | * bit of interest either set or cleared. EG: (BIT<<16) | BIT to set. | ||
475 | */ | ||
476 | #define Cache_Mode_0 0x2120 | ||
477 | #define CACHE_MODE_0 0x2120 | ||
478 | #define CM0_MASK_SHIFT 16 | ||
479 | #define CM0_IZ_OPT_DISABLE (1<<6) | ||
480 | #define CM0_ZR_OPT_DISABLE (1<<5) | ||
481 | #define CM0_DEPTH_EVICT_DISABLE (1<<4) | ||
482 | #define CM0_COLOR_EVICT_DISABLE (1<<3) | ||
483 | #define CM0_DEPTH_WRITE_DISABLE (1<<1) | ||
484 | #define CM0_RC_OP_FLUSH_DISABLE (1<<0) | ||
485 | |||
486 | |||
487 | /* Graphics flush control. A CPU write flushes the GWB of all writes. | ||
488 | * The data is discarded. | ||
489 | */ | ||
490 | #define GFX_FLSH_CNTL 0x2170 | ||
491 | |||
492 | /* Binner control. Defines the location of the bin pointer list: | ||
493 | */ | ||
494 | #define BINCTL 0x2420 | ||
495 | #define BC_MASK (1 << 9) | ||
496 | |||
497 | /* Binned scene info. | ||
498 | */ | ||
499 | #define BINSCENE 0x2428 | ||
500 | #define BS_OP_LOAD (1 << 8) | ||
501 | #define BS_MASK (1 << 22) | ||
502 | |||
503 | /* Bin command parser debug reg: | ||
504 | */ | ||
505 | #define BCPD 0x2480 | ||
506 | |||
507 | /* Bin memory control debug reg: | ||
508 | */ | ||
509 | #define BMCD 0x2484 | ||
510 | |||
511 | /* Bin data cache debug reg: | ||
512 | */ | ||
513 | #define BDCD 0x2488 | ||
514 | |||
515 | /* Binner pointer cache debug reg: | ||
516 | */ | ||
517 | #define BPCD 0x248c | ||
518 | |||
519 | /* Binner scratch pad debug reg: | ||
520 | */ | ||
521 | #define BINSKPD 0x24f0 | ||
522 | |||
523 | /* HWB scratch pad debug reg: | ||
524 | */ | ||
525 | #define HWBSKPD 0x24f4 | ||
526 | |||
527 | /* Binner memory pool reg: | ||
528 | */ | ||
529 | #define BMP_BUFFER 0x2430 | ||
530 | #define BMP_PAGE_SIZE_4K (0 << 10) | ||
531 | #define BMP_BUFFER_SIZE_SHIFT 1 | ||
532 | #define BMP_ENABLE (1 << 0) | ||
533 | |||
534 | /* Get/put memory from the binner memory pool: | ||
535 | */ | ||
536 | #define BMP_GET 0x2438 | ||
537 | #define BMP_PUT 0x2440 | ||
538 | #define BMP_OFFSET_SHIFT 5 | ||
539 | |||
540 | /* 3D state packets: | ||
541 | */ | ||
542 | #define GFX_OP_RASTER_RULES ((0x3<<29)|(0x7<<24)) | ||
543 | |||
544 | #define GFX_OP_SCISSOR ((0x3<<29)|(0x1c<<24)|(0x10<<19)) | ||
545 | #define SC_UPDATE_SCISSOR (0x1<<1) | ||
546 | #define SC_ENABLE_MASK (0x1<<0) | ||
547 | #define SC_ENABLE (0x1<<0) | ||
548 | |||
549 | #define GFX_OP_LOAD_INDIRECT ((0x3<<29)|(0x1d<<24)|(0x7<<16)) | ||
550 | |||
551 | #define GFX_OP_SCISSOR_INFO ((0x3<<29)|(0x1d<<24)|(0x81<<16)|(0x1)) | ||
552 | #define SCI_YMIN_MASK (0xffff<<16) | ||
553 | #define SCI_XMIN_MASK (0xffff<<0) | ||
554 | #define SCI_YMAX_MASK (0xffff<<16) | ||
555 | #define SCI_XMAX_MASK (0xffff<<0) | ||
556 | |||
557 | #define GFX_OP_SCISSOR_ENABLE ((0x3<<29)|(0x1c<<24)|(0x10<<19)) | ||
558 | #define GFX_OP_SCISSOR_RECT ((0x3<<29)|(0x1d<<24)|(0x81<<16)|1) | ||
559 | #define GFX_OP_COLOR_FACTOR ((0x3<<29)|(0x1d<<24)|(0x1<<16)|0x0) | ||
560 | #define GFX_OP_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16)) | ||
561 | #define GFX_OP_MAP_INFO ((0x3<<29)|(0x1d<<24)|0x4) | ||
562 | #define GFX_OP_DESTBUFFER_VARS ((0x3<<29)|(0x1d<<24)|(0x85<<16)|0x0) | ||
563 | #define GFX_OP_DRAWRECT_INFO ((0x3<<29)|(0x1d<<24)|(0x80<<16)|(0x3)) | ||
564 | |||
565 | #define GFX_OP_DRAWRECT_INFO_I965 ((0x7900<<16)|0x2) | ||
566 | |||
567 | #define SRC_COPY_BLT_CMD ((2<<29)|(0x43<<22)|4) | ||
568 | #define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6) | ||
569 | #define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21) | ||
570 | #define XY_SRC_COPY_BLT_WRITE_RGB (1<<20) | ||
571 | #define XY_SRC_COPY_BLT_SRC_TILED (1<<15) | ||
572 | #define XY_SRC_COPY_BLT_DST_TILED (1<<11) | ||
573 | |||
574 | #define MI_BATCH_BUFFER ((0x30<<23)|1) | ||
575 | #define MI_BATCH_BUFFER_START (0x31<<23) | ||
576 | #define MI_BATCH_BUFFER_END (0xA<<23) | ||
577 | #define MI_BATCH_NON_SECURE (1) | ||
578 | #define MI_BATCH_NON_SECURE_I965 (1<<8) | ||
579 | |||
580 | #define MI_WAIT_FOR_EVENT ((0x3<<23)) | ||
581 | #define MI_WAIT_FOR_PLANE_B_FLIP (1<<6) | ||
582 | #define MI_WAIT_FOR_PLANE_A_FLIP (1<<2) | ||
583 | #define MI_WAIT_FOR_PLANE_A_SCANLINES (1<<1) | ||
584 | |||
585 | #define MI_LOAD_SCAN_LINES_INCL ((0x12<<23)) | ||
586 | |||
587 | #define CMD_OP_DISPLAYBUFFER_INFO ((0x0<<29)|(0x14<<23)|2) | ||
588 | #define ASYNC_FLIP (1<<22) | ||
589 | #define DISPLAY_PLANE_A (0<<20) | ||
590 | #define DISPLAY_PLANE_B (1<<20) | ||
591 | |||
592 | /* Display regs */ | ||
593 | #define DSPACNTR 0x70180 | ||
594 | #define DSPBCNTR 0x71180 | ||
595 | #define DISPPLANE_SEL_PIPE_MASK (1<<24) | ||
596 | |||
597 | /* Define the region of interest for the binner: | ||
598 | */ | ||
599 | #define CMD_OP_BIN_CONTROL ((0x3<<29)|(0x1d<<24)|(0x84<<16)|4) | ||
600 | |||
601 | #define CMD_OP_DESTBUFFER_INFO ((0x3<<29)|(0x1d<<24)|(0x8e<<16)|1) | ||
602 | |||
603 | #define CMD_MI_FLUSH (0x04 << 23) | ||
604 | #define MI_NO_WRITE_FLUSH (1 << 2) | ||
605 | #define MI_READ_FLUSH (1 << 0) | ||
606 | #define MI_EXE_FLUSH (1 << 1) | ||
607 | #define MI_END_SCENE (1 << 4) /* flush binner and incr scene count */ | ||
608 | #define MI_SCENE_COUNT (1 << 3) /* just increment scene count */ | ||
609 | |||
610 | #define BREADCRUMB_BITS 31 | ||
611 | #define BREADCRUMB_MASK ((1U << BREADCRUMB_BITS) - 1) | ||
612 | |||
613 | #define READ_BREADCRUMB(dev_priv) (((volatile u32*)(dev_priv->hw_status_page))[5]) | ||
614 | #define READ_HWSP(dev_priv, reg) (((volatile u32*)(dev_priv->hw_status_page))[reg]) | ||
615 | |||
616 | #define BLC_PWM_CTL 0x61254 | ||
617 | #define BACKLIGHT_MODULATION_FREQ_SHIFT (17) | ||
618 | |||
619 | #define BLC_PWM_CTL2 0x61250 | ||
620 | /** | ||
621 | * This is the most significant 15 bits of the number of backlight cycles in a | ||
622 | * complete cycle of the modulated backlight control. | ||
623 | * | ||
624 | * The actual value is this field multiplied by two. | ||
625 | */ | ||
626 | #define BACKLIGHT_MODULATION_FREQ_MASK (0x7fff << 17) | ||
627 | #define BLM_LEGACY_MODE (1 << 16) | ||
628 | /** | ||
629 | * This is the number of cycles out of the backlight modulation cycle for which | ||
630 | * the backlight is on. | ||
631 | * | ||
632 | * This field must be no greater than the number of cycles in the complete | ||
633 | * backlight modulation cycle. | ||
634 | */ | ||
635 | #define BACKLIGHT_DUTY_CYCLE_SHIFT (0) | ||
636 | #define BACKLIGHT_DUTY_CYCLE_MASK (0xffff) | ||
637 | |||
638 | #define I915_GCFGC 0xf0 | ||
639 | #define I915_LOW_FREQUENCY_ENABLE (1 << 7) | ||
640 | #define I915_DISPLAY_CLOCK_190_200_MHZ (0 << 4) | ||
641 | #define I915_DISPLAY_CLOCK_333_MHZ (4 << 4) | ||
642 | #define I915_DISPLAY_CLOCK_MASK (7 << 4) | ||
643 | |||
644 | #define I855_HPLLCC 0xc0 | ||
645 | #define I855_CLOCK_CONTROL_MASK (3 << 0) | ||
646 | #define I855_CLOCK_133_200 (0 << 0) | ||
647 | #define I855_CLOCK_100_200 (1 << 0) | ||
648 | #define I855_CLOCK_100_133 (2 << 0) | ||
649 | #define I855_CLOCK_166_250 (3 << 0) | ||
650 | |||
651 | /* p317, 319 | ||
652 | */ | ||
653 | #define VCLK2_VCO_M 0x6008 /* treat as 16 bit? (includes msbs) */ | ||
654 | #define VCLK2_VCO_N 0x600a | ||
655 | #define VCLK2_VCO_DIV_SEL 0x6012 | ||
656 | |||
657 | #define VCLK_DIVISOR_VGA0 0x6000 | ||
658 | #define VCLK_DIVISOR_VGA1 0x6004 | ||
659 | #define VCLK_POST_DIV 0x6010 | ||
660 | /** Selects a post divisor of 4 instead of 2. */ | ||
661 | # define VGA1_PD_P2_DIV_4 (1 << 15) | ||
662 | /** Overrides the p2 post divisor field */ | ||
663 | # define VGA1_PD_P1_DIV_2 (1 << 13) | ||
664 | # define VGA1_PD_P1_SHIFT 8 | ||
665 | /** P1 value is 2 greater than this field */ | ||
666 | # define VGA1_PD_P1_MASK (0x1f << 8) | ||
667 | /** Selects a post divisor of 4 instead of 2. */ | ||
668 | # define VGA0_PD_P2_DIV_4 (1 << 7) | ||
669 | /** Overrides the p2 post divisor field */ | ||
670 | # define VGA0_PD_P1_DIV_2 (1 << 5) | ||
671 | # define VGA0_PD_P1_SHIFT 0 | ||
672 | /** P1 value is 2 greater than this field */ | ||
673 | # define VGA0_PD_P1_MASK (0x1f << 0) | ||
674 | |||
675 | /* PCI D state control register */ | ||
676 | #define D_STATE 0x6104 | ||
677 | #define DSPCLK_GATE_D 0x6200 | ||
678 | |||
679 | /* I830 CRTC registers */ | ||
680 | #define HTOTAL_A 0x60000 | ||
681 | #define HBLANK_A 0x60004 | ||
682 | #define HSYNC_A 0x60008 | ||
683 | #define VTOTAL_A 0x6000c | ||
684 | #define VBLANK_A 0x60010 | ||
685 | #define VSYNC_A 0x60014 | ||
686 | #define PIPEASRC 0x6001c | ||
687 | #define BCLRPAT_A 0x60020 | ||
688 | #define VSYNCSHIFT_A 0x60028 | ||
689 | |||
690 | #define HTOTAL_B 0x61000 | ||
691 | #define HBLANK_B 0x61004 | ||
692 | #define HSYNC_B 0x61008 | ||
693 | #define VTOTAL_B 0x6100c | ||
694 | #define VBLANK_B 0x61010 | ||
695 | #define VSYNC_B 0x61014 | ||
696 | #define PIPEBSRC 0x6101c | ||
697 | #define BCLRPAT_B 0x61020 | ||
698 | #define VSYNCSHIFT_B 0x61028 | ||
699 | |||
700 | #define PP_STATUS 0x61200 | ||
701 | # define PP_ON (1 << 31) | ||
702 | /** | ||
703 | * Indicates that all dependencies of the panel are on: | ||
704 | * | ||
705 | * - PLL enabled | ||
706 | * - pipe enabled | ||
707 | * - LVDS/DVOB/DVOC on | ||
708 | */ | ||
709 | # define PP_READY (1 << 30) | ||
710 | # define PP_SEQUENCE_NONE (0 << 28) | ||
711 | # define PP_SEQUENCE_ON (1 << 28) | ||
712 | # define PP_SEQUENCE_OFF (2 << 28) | ||
713 | # define PP_SEQUENCE_MASK 0x30000000 | ||
714 | #define PP_CONTROL 0x61204 | ||
715 | # define POWER_TARGET_ON (1 << 0) | ||
716 | |||
717 | #define LVDSPP_ON 0x61208 | ||
718 | #define LVDSPP_OFF 0x6120c | ||
719 | #define PP_CYCLE 0x61210 | ||
720 | |||
721 | #define PFIT_CONTROL 0x61230 | ||
722 | # define PFIT_ENABLE (1 << 31) | ||
723 | # define PFIT_PIPE_MASK (3 << 29) | ||
724 | # define PFIT_PIPE_SHIFT 29 | ||
725 | # define VERT_INTERP_DISABLE (0 << 10) | ||
726 | # define VERT_INTERP_BILINEAR (1 << 10) | ||
727 | # define VERT_INTERP_MASK (3 << 10) | ||
728 | # define VERT_AUTO_SCALE (1 << 9) | ||
729 | # define HORIZ_INTERP_DISABLE (0 << 6) | ||
730 | # define HORIZ_INTERP_BILINEAR (1 << 6) | ||
731 | # define HORIZ_INTERP_MASK (3 << 6) | ||
732 | # define HORIZ_AUTO_SCALE (1 << 5) | ||
733 | # define PANEL_8TO6_DITHER_ENABLE (1 << 3) | ||
734 | |||
735 | #define PFIT_PGM_RATIOS 0x61234 | ||
736 | # define PFIT_VERT_SCALE_MASK 0xfff00000 | ||
737 | # define PFIT_HORIZ_SCALE_MASK 0x0000fff0 | ||
738 | |||
739 | #define PFIT_AUTO_RATIOS 0x61238 | ||
740 | |||
741 | |||
742 | #define DPLL_A 0x06014 | ||
743 | #define DPLL_B 0x06018 | ||
744 | # define DPLL_VCO_ENABLE (1 << 31) | ||
745 | # define DPLL_DVO_HIGH_SPEED (1 << 30) | ||
746 | # define DPLL_SYNCLOCK_ENABLE (1 << 29) | ||
747 | # define DPLL_VGA_MODE_DIS (1 << 28) | ||
748 | # define DPLLB_MODE_DAC_SERIAL (1 << 26) /* i915 */ | ||
749 | # define DPLLB_MODE_LVDS (2 << 26) /* i915 */ | ||
750 | # define DPLL_MODE_MASK (3 << 26) | ||
751 | # define DPLL_DAC_SERIAL_P2_CLOCK_DIV_10 (0 << 24) /* i915 */ | ||
752 | # define DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 (1 << 24) /* i915 */ | ||
753 | # define DPLLB_LVDS_P2_CLOCK_DIV_14 (0 << 24) /* i915 */ | ||
754 | # define DPLLB_LVDS_P2_CLOCK_DIV_7 (1 << 24) /* i915 */ | ||
755 | # define DPLL_P2_CLOCK_DIV_MASK 0x03000000 /* i915 */ | ||
756 | # define DPLL_FPA01_P1_POST_DIV_MASK 0x00ff0000 /* i915 */ | ||
757 | /** | ||
758 | * The i830 generation, in DAC/serial mode, defines p1 as two plus this | ||
759 | * bitfield, or just 2 if PLL_P1_DIVIDE_BY_TWO is set. | ||
760 | */ | ||
761 | # define DPLL_FPA01_P1_POST_DIV_MASK_I830 0x001f0000 | ||
762 | /** | ||
763 | * The i830 generation, in LVDS mode, defines P1 as the bit number set within | ||
764 | * this field (only one bit may be set). | ||
765 | */ | ||
766 | # define DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS 0x003f0000 | ||
767 | # define DPLL_FPA01_P1_POST_DIV_SHIFT 16 | ||
768 | # define PLL_P2_DIVIDE_BY_4 (1 << 23) /* i830, required in DVO non-gang */ | ||
769 | # define PLL_P1_DIVIDE_BY_TWO (1 << 21) /* i830 */ | ||
770 | # define PLL_REF_INPUT_DREFCLK (0 << 13) | ||
771 | # define PLL_REF_INPUT_TVCLKINA (1 << 13) /* i830 */ | ||
772 | # define PLL_REF_INPUT_TVCLKINBC (2 << 13) /* SDVO TVCLKIN */ | ||
773 | # define PLLB_REF_INPUT_SPREADSPECTRUMIN (3 << 13) | ||
774 | # define PLL_REF_INPUT_MASK (3 << 13) | ||
775 | # define PLL_LOAD_PULSE_PHASE_SHIFT 9 | ||
776 | /* | ||
777 | * Parallel to Serial Load Pulse phase selection. | ||
778 | * Selects the phase for the 10X DPLL clock for the PCIe | ||
779 | * digital display port. The range is 4 to 13; 10 or more | ||
780 | * is just a flip delay. The default is 6 | ||
781 | */ | ||
782 | # define PLL_LOAD_PULSE_PHASE_MASK (0xf << PLL_LOAD_PULSE_PHASE_SHIFT) | ||
783 | # define DISPLAY_RATE_SELECT_FPA1 (1 << 8) | ||
784 | |||
785 | /** | ||
786 | * SDVO multiplier for 945G/GM. Not used on 965. | ||
787 | * | ||
788 | * \sa DPLL_MD_UDI_MULTIPLIER_MASK | ||
789 | */ | ||
790 | # define SDVO_MULTIPLIER_MASK 0x000000ff | ||
791 | # define SDVO_MULTIPLIER_SHIFT_HIRES 4 | ||
792 | # define SDVO_MULTIPLIER_SHIFT_VGA 0 | ||
793 | |||
794 | /** @defgroup DPLL_MD | ||
795 | * @{ | ||
796 | */ | ||
797 | /** Pipe A SDVO/UDI clock multiplier/divider register for G965. */ | ||
798 | #define DPLL_A_MD 0x0601c | ||
799 | /** Pipe B SDVO/UDI clock multiplier/divider register for G965. */ | ||
800 | #define DPLL_B_MD 0x06020 | ||
801 | /** | ||
802 | * UDI pixel divider, controlling how many pixels are stuffed into a packet. | ||
803 | * | ||
804 | * Value is pixels minus 1. Must be set to 1 pixel for SDVO. | ||
805 | */ | ||
806 | # define DPLL_MD_UDI_DIVIDER_MASK 0x3f000000 | ||
807 | # define DPLL_MD_UDI_DIVIDER_SHIFT 24 | ||
808 | /** UDI pixel divider for VGA, same as DPLL_MD_UDI_DIVIDER_MASK. */ | ||
809 | # define DPLL_MD_VGA_UDI_DIVIDER_MASK 0x003f0000 | ||
810 | # define DPLL_MD_VGA_UDI_DIVIDER_SHIFT 16 | ||
811 | /** | ||
812 | * SDVO/UDI pixel multiplier. | ||
813 | * | ||
814 | * SDVO requires that the bus clock rate be between 1 and 2 Ghz, and the bus | ||
815 | * clock rate is 10 times the DPLL clock. At low resolution/refresh rate | ||
816 | * modes, the bus rate would be below the limits, so SDVO allows for stuffing | ||
817 | * dummy bytes in the datastream at an increased clock rate, with both sides of | ||
818 | * the link knowing how many bytes are fill. | ||
819 | * | ||
820 | * So, for a mode with a dotclock of 65Mhz, we would want to double the clock | ||
821 | * rate to 130Mhz to get a bus rate of 1.30Ghz. The DPLL clock rate would be | ||
822 | * set to 130Mhz, and the SDVO multiplier set to 2x in this register and | ||
823 | * through an SDVO command. | ||
824 | * | ||
825 | * This register field has values of multiplication factor minus 1, with | ||
826 | * a maximum multiplier of 5 for SDVO. | ||
827 | */ | ||
828 | # define DPLL_MD_UDI_MULTIPLIER_MASK 0x00003f00 | ||
829 | # define DPLL_MD_UDI_MULTIPLIER_SHIFT 8 | ||
830 | /** SDVO/UDI pixel multiplier for VGA, same as DPLL_MD_UDI_MULTIPLIER_MASK. | ||
831 | * This best be set to the default value (3) or the CRT won't work. No, | ||
832 | * I don't entirely understand what this does... | ||
833 | */ | ||
834 | # define DPLL_MD_VGA_UDI_MULTIPLIER_MASK 0x0000003f | ||
835 | # define DPLL_MD_VGA_UDI_MULTIPLIER_SHIFT 0 | ||
836 | /** @} */ | ||
837 | |||
838 | #define DPLL_TEST 0x606c | ||
839 | # define DPLLB_TEST_SDVO_DIV_1 (0 << 22) | ||
840 | # define DPLLB_TEST_SDVO_DIV_2 (1 << 22) | ||
841 | # define DPLLB_TEST_SDVO_DIV_4 (2 << 22) | ||
842 | # define DPLLB_TEST_SDVO_DIV_MASK (3 << 22) | ||
843 | # define DPLLB_TEST_N_BYPASS (1 << 19) | ||
844 | # define DPLLB_TEST_M_BYPASS (1 << 18) | ||
845 | # define DPLLB_INPUT_BUFFER_ENABLE (1 << 16) | ||
846 | # define DPLLA_TEST_N_BYPASS (1 << 3) | ||
847 | # define DPLLA_TEST_M_BYPASS (1 << 2) | ||
848 | # define DPLLA_INPUT_BUFFER_ENABLE (1 << 0) | ||
849 | |||
850 | #define ADPA 0x61100 | ||
851 | #define ADPA_DAC_ENABLE (1<<31) | ||
852 | #define ADPA_DAC_DISABLE 0 | ||
853 | #define ADPA_PIPE_SELECT_MASK (1<<30) | ||
854 | #define ADPA_PIPE_A_SELECT 0 | ||
855 | #define ADPA_PIPE_B_SELECT (1<<30) | ||
856 | #define ADPA_USE_VGA_HVPOLARITY (1<<15) | ||
857 | #define ADPA_SETS_HVPOLARITY 0 | ||
858 | #define ADPA_VSYNC_CNTL_DISABLE (1<<11) | ||
859 | #define ADPA_VSYNC_CNTL_ENABLE 0 | ||
860 | #define ADPA_HSYNC_CNTL_DISABLE (1<<10) | ||
861 | #define ADPA_HSYNC_CNTL_ENABLE 0 | ||
862 | #define ADPA_VSYNC_ACTIVE_HIGH (1<<4) | ||
863 | #define ADPA_VSYNC_ACTIVE_LOW 0 | ||
864 | #define ADPA_HSYNC_ACTIVE_HIGH (1<<3) | ||
865 | #define ADPA_HSYNC_ACTIVE_LOW 0 | ||
866 | |||
867 | #define FPA0 0x06040 | ||
868 | #define FPA1 0x06044 | ||
869 | #define FPB0 0x06048 | ||
870 | #define FPB1 0x0604c | ||
871 | # define FP_N_DIV_MASK 0x003f0000 | ||
872 | # define FP_N_DIV_SHIFT 16 | ||
873 | # define FP_M1_DIV_MASK 0x00003f00 | ||
874 | # define FP_M1_DIV_SHIFT 8 | ||
875 | # define FP_M2_DIV_MASK 0x0000003f | ||
876 | # define FP_M2_DIV_SHIFT 0 | ||
877 | |||
878 | |||
879 | #define PORT_HOTPLUG_EN 0x61110 | ||
880 | # define SDVOB_HOTPLUG_INT_EN (1 << 26) | ||
881 | # define SDVOC_HOTPLUG_INT_EN (1 << 25) | ||
882 | # define TV_HOTPLUG_INT_EN (1 << 18) | ||
883 | # define CRT_HOTPLUG_INT_EN (1 << 9) | ||
884 | # define CRT_HOTPLUG_FORCE_DETECT (1 << 3) | ||
885 | |||
886 | #define PORT_HOTPLUG_STAT 0x61114 | ||
887 | # define CRT_HOTPLUG_INT_STATUS (1 << 11) | ||
888 | # define TV_HOTPLUG_INT_STATUS (1 << 10) | ||
889 | # define CRT_HOTPLUG_MONITOR_MASK (3 << 8) | ||
890 | # define CRT_HOTPLUG_MONITOR_COLOR (3 << 8) | ||
891 | # define CRT_HOTPLUG_MONITOR_MONO (2 << 8) | ||
892 | # define CRT_HOTPLUG_MONITOR_NONE (0 << 8) | ||
893 | # define SDVOC_HOTPLUG_INT_STATUS (1 << 7) | ||
894 | # define SDVOB_HOTPLUG_INT_STATUS (1 << 6) | ||
895 | |||
896 | #define SDVOB 0x61140 | ||
897 | #define SDVOC 0x61160 | ||
898 | #define SDVO_ENABLE (1 << 31) | ||
899 | #define SDVO_PIPE_B_SELECT (1 << 30) | ||
900 | #define SDVO_STALL_SELECT (1 << 29) | ||
901 | #define SDVO_INTERRUPT_ENABLE (1 << 26) | ||
902 | /** | 597 | /** |
903 | * 915G/GM SDVO pixel multiplier. | 598 | * Reads a dword out of the status page, which is written to from the command |
599 | * queue by automatic updates, MI_REPORT_HEAD, MI_STORE_DATA_INDEX, or | ||
600 | * MI_STORE_DATA_IMM. | ||
904 | * | 601 | * |
905 | * Programmed value is multiplier - 1, up to 5x. | 602 | * The following dwords have a reserved meaning: |
906 | * | 603 | * 0x00: ISR copy, updated when an ISR bit not set in the HWSTAM changes. |
907 | * \sa DPLL_MD_UDI_MULTIPLIER_MASK | 604 | * 0x04: ring 0 head pointer |
908 | */ | 605 | * 0x05: ring 1 head pointer (915-class) |
909 | #define SDVO_PORT_MULTIPLY_MASK (7 << 23) | 606 | * 0x06: ring 2 head pointer (915-class) |
910 | #define SDVO_PORT_MULTIPLY_SHIFT 23 | 607 | * 0x10-0x1b: Context status DWords (GM45) |
911 | #define SDVO_PHASE_SELECT_MASK (15 << 19) | 608 | * 0x1f: Last written status offset. (GM45) |
912 | #define SDVO_PHASE_SELECT_DEFAULT (6 << 19) | ||
913 | #define SDVO_CLOCK_OUTPUT_INVERT (1 << 18) | ||
914 | #define SDVOC_GANG_MODE (1 << 16) | ||
915 | #define SDVO_BORDER_ENABLE (1 << 7) | ||
916 | #define SDVOB_PCIE_CONCURRENCY (1 << 3) | ||
917 | #define SDVO_DETECTED (1 << 2) | ||
918 | /* Bits to be preserved when writing */ | ||
919 | #define SDVOB_PRESERVE_MASK ((1 << 17) | (1 << 16) | (1 << 14)) | ||
920 | #define SDVOC_PRESERVE_MASK (1 << 17) | ||
921 | |||
922 | /** @defgroup LVDS | ||
923 | * @{ | ||
924 | */ | ||
925 | /** | ||
926 | * This register controls the LVDS output enable, pipe selection, and data | ||
927 | * format selection. | ||
928 | * | 609 | * |
929 | * All of the clock/data pairs are force powered down by power sequencing. | 610 | * The area from dword 0x20 to 0x3ff is available for driver usage. |
930 | */ | ||
931 | #define LVDS 0x61180 | ||
932 | /** | ||
933 | * Enables the LVDS port. This bit must be set before DPLLs are enabled, as | ||
934 | * the DPLL semantics change when the LVDS is assigned to that pipe. | ||
935 | */ | ||
936 | # define LVDS_PORT_EN (1 << 31) | ||
937 | /** Selects pipe B for LVDS data. Must be set on pre-965. */ | ||
938 | # define LVDS_PIPEB_SELECT (1 << 30) | ||
939 | |||
940 | /** | ||
941 | * Enables the A0-A2 data pairs and CLKA, containing 18 bits of color data per | ||
942 | * pixel. | ||
943 | */ | ||
944 | # define LVDS_A0A2_CLKA_POWER_MASK (3 << 8) | ||
945 | # define LVDS_A0A2_CLKA_POWER_DOWN (0 << 8) | ||
946 | # define LVDS_A0A2_CLKA_POWER_UP (3 << 8) | ||
947 | /** | ||
948 | * Controls the A3 data pair, which contains the additional LSBs for 24 bit | ||
949 | * mode. Only enabled if LVDS_A0A2_CLKA_POWER_UP also indicates it should be | ||
950 | * on. | ||
951 | */ | ||
952 | # define LVDS_A3_POWER_MASK (3 << 6) | ||
953 | # define LVDS_A3_POWER_DOWN (0 << 6) | ||
954 | # define LVDS_A3_POWER_UP (3 << 6) | ||
955 | /** | ||
956 | * Controls the CLKB pair. This should only be set when LVDS_B0B3_POWER_UP | ||
957 | * is set. | ||
958 | */ | ||
959 | # define LVDS_CLKB_POWER_MASK (3 << 4) | ||
960 | # define LVDS_CLKB_POWER_DOWN (0 << 4) | ||
961 | # define LVDS_CLKB_POWER_UP (3 << 4) | ||
962 | |||
963 | /** | ||
964 | * Controls the B0-B3 data pairs. This must be set to match the DPLL p2 | ||
965 | * setting for whether we are in dual-channel mode. The B3 pair will | ||
966 | * additionally only be powered up when LVDS_A3_POWER_UP is set. | ||
967 | */ | ||
968 | # define LVDS_B0B3_POWER_MASK (3 << 2) | ||
969 | # define LVDS_B0B3_POWER_DOWN (0 << 2) | ||
970 | # define LVDS_B0B3_POWER_UP (3 << 2) | ||
971 | |||
972 | #define PIPEACONF 0x70008 | ||
973 | #define PIPEACONF_ENABLE (1<<31) | ||
974 | #define PIPEACONF_DISABLE 0 | ||
975 | #define PIPEACONF_DOUBLE_WIDE (1<<30) | ||
976 | #define I965_PIPECONF_ACTIVE (1<<30) | ||
977 | #define PIPEACONF_SINGLE_WIDE 0 | ||
978 | #define PIPEACONF_PIPE_UNLOCKED 0 | ||
979 | #define PIPEACONF_PIPE_LOCKED (1<<25) | ||
980 | #define PIPEACONF_PALETTE 0 | ||
981 | #define PIPEACONF_GAMMA (1<<24) | ||
982 | #define PIPECONF_FORCE_BORDER (1<<25) | ||
983 | #define PIPECONF_PROGRESSIVE (0 << 21) | ||
984 | #define PIPECONF_INTERLACE_W_FIELD_INDICATION (6 << 21) | ||
985 | #define PIPECONF_INTERLACE_FIELD_0_ONLY (7 << 21) | ||
986 | |||
987 | #define DSPARB 0x70030 | ||
988 | #define DSPARB_CSTART_MASK (0x7f << 7) | ||
989 | #define DSPARB_CSTART_SHIFT 7 | ||
990 | #define DSPARB_BSTART_MASK (0x7f) | ||
991 | #define DSPARB_BSTART_SHIFT 0 | ||
992 | |||
993 | #define PIPEBCONF 0x71008 | ||
994 | #define PIPEBCONF_ENABLE (1<<31) | ||
995 | #define PIPEBCONF_DISABLE 0 | ||
996 | #define PIPEBCONF_DOUBLE_WIDE (1<<30) | ||
997 | #define PIPEBCONF_DISABLE 0 | ||
998 | #define PIPEBCONF_GAMMA (1<<24) | ||
999 | #define PIPEBCONF_PALETTE 0 | ||
1000 | |||
1001 | #define PIPEBGCMAXRED 0x71010 | ||
1002 | #define PIPEBGCMAXGREEN 0x71014 | ||
1003 | #define PIPEBGCMAXBLUE 0x71018 | ||
1004 | #define PIPEBSTAT 0x71024 | ||
1005 | #define PIPEBFRAMEHIGH 0x71040 | ||
1006 | #define PIPEBFRAMEPIXEL 0x71044 | ||
1007 | |||
1008 | #define DSPACNTR 0x70180 | ||
1009 | #define DSPBCNTR 0x71180 | ||
1010 | #define DISPLAY_PLANE_ENABLE (1<<31) | ||
1011 | #define DISPLAY_PLANE_DISABLE 0 | ||
1012 | #define DISPPLANE_GAMMA_ENABLE (1<<30) | ||
1013 | #define DISPPLANE_GAMMA_DISABLE 0 | ||
1014 | #define DISPPLANE_PIXFORMAT_MASK (0xf<<26) | ||
1015 | #define DISPPLANE_8BPP (0x2<<26) | ||
1016 | #define DISPPLANE_15_16BPP (0x4<<26) | ||
1017 | #define DISPPLANE_16BPP (0x5<<26) | ||
1018 | #define DISPPLANE_32BPP_NO_ALPHA (0x6<<26) | ||
1019 | #define DISPPLANE_32BPP (0x7<<26) | ||
1020 | #define DISPPLANE_STEREO_ENABLE (1<<25) | ||
1021 | #define DISPPLANE_STEREO_DISABLE 0 | ||
1022 | #define DISPPLANE_SEL_PIPE_MASK (1<<24) | ||
1023 | #define DISPPLANE_SEL_PIPE_A 0 | ||
1024 | #define DISPPLANE_SEL_PIPE_B (1<<24) | ||
1025 | #define DISPPLANE_SRC_KEY_ENABLE (1<<22) | ||
1026 | #define DISPPLANE_SRC_KEY_DISABLE 0 | ||
1027 | #define DISPPLANE_LINE_DOUBLE (1<<20) | ||
1028 | #define DISPPLANE_NO_LINE_DOUBLE 0 | ||
1029 | #define DISPPLANE_STEREO_POLARITY_FIRST 0 | ||
1030 | #define DISPPLANE_STEREO_POLARITY_SECOND (1<<18) | ||
1031 | /* plane B only */ | ||
1032 | #define DISPPLANE_ALPHA_TRANS_ENABLE (1<<15) | ||
1033 | #define DISPPLANE_ALPHA_TRANS_DISABLE 0 | ||
1034 | #define DISPPLANE_SPRITE_ABOVE_DISPLAYA 0 | ||
1035 | #define DISPPLANE_SPRITE_ABOVE_OVERLAY (1) | ||
1036 | |||
1037 | #define DSPABASE 0x70184 | ||
1038 | #define DSPASTRIDE 0x70188 | ||
1039 | |||
1040 | #define DSPBBASE 0x71184 | ||
1041 | #define DSPBADDR DSPBBASE | ||
1042 | #define DSPBSTRIDE 0x71188 | ||
1043 | |||
1044 | #define DSPAKEYVAL 0x70194 | ||
1045 | #define DSPAKEYMASK 0x70198 | ||
1046 | |||
1047 | #define DSPAPOS 0x7018C /* reserved */ | ||
1048 | #define DSPASIZE 0x70190 | ||
1049 | #define DSPBPOS 0x7118C | ||
1050 | #define DSPBSIZE 0x71190 | ||
1051 | |||
1052 | #define DSPASURF 0x7019C | ||
1053 | #define DSPATILEOFF 0x701A4 | ||
1054 | |||
1055 | #define DSPBSURF 0x7119C | ||
1056 | #define DSPBTILEOFF 0x711A4 | ||
1057 | |||
1058 | #define VGACNTRL 0x71400 | ||
1059 | # define VGA_DISP_DISABLE (1 << 31) | ||
1060 | # define VGA_2X_MODE (1 << 30) | ||
1061 | # define VGA_PIPE_B_SELECT (1 << 29) | ||
1062 | |||
1063 | /* | ||
1064 | * Some BIOS scratch area registers. The 845 (and 830?) store the amount | ||
1065 | * of video memory available to the BIOS in SWF1. | ||
1066 | */ | ||
1067 | |||
1068 | #define SWF0 0x71410 | ||
1069 | |||
1070 | /* | ||
1071 | * 855 scratch registers. | ||
1072 | */ | ||
1073 | #define SWF10 0x70410 | ||
1074 | |||
1075 | #define SWF30 0x72414 | ||
1076 | |||
1077 | /* | ||
1078 | * Overlay registers. These are overlay registers accessed via MMIO. | ||
1079 | * Those loaded via the overlay register page are defined in i830_video.c. | ||
1080 | */ | 611 | */ |
1081 | #define OVADD 0x30000 | 612 | #define READ_HWSP(dev_priv, reg) (((volatile u32*)(dev_priv->hw_status_page))[reg]) |
1082 | 613 | #define READ_BREADCRUMB(dev_priv) READ_HWSP(dev_priv, 5) | |
1083 | #define DOVSTA 0x30008 | 614 | #define I915_GEM_HWS_INDEX 0x20 |
1084 | #define OC_BUF (0x3<<20) | ||
1085 | 615 | ||
1086 | #define OGAMC5 0x30010 | 616 | extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); |
1087 | #define OGAMC4 0x30014 | ||
1088 | #define OGAMC3 0x30018 | ||
1089 | #define OGAMC2 0x3001c | ||
1090 | #define OGAMC1 0x30020 | ||
1091 | #define OGAMC0 0x30024 | ||
1092 | /* | ||
1093 | * Palette registers | ||
1094 | */ | ||
1095 | #define PALETTE_A 0x0a000 | ||
1096 | #define PALETTE_B 0x0a800 | ||
1097 | 617 | ||
1098 | #define IS_I830(dev) ((dev)->pci_device == 0x3577) | 618 | #define IS_I830(dev) ((dev)->pci_device == 0x3577) |
1099 | #define IS_845G(dev) ((dev)->pci_device == 0x2562) | 619 | #define IS_845G(dev) ((dev)->pci_device == 0x2562) |
@@ -1119,7 +639,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); | |||
1119 | 639 | ||
1120 | #define IS_I965GM(dev) ((dev)->pci_device == 0x2A02) | 640 | #define IS_I965GM(dev) ((dev)->pci_device == 0x2A02) |
1121 | 641 | ||
1122 | #define IS_IGD_GM(dev) ((dev)->pci_device == 0x2A42) | 642 | #define IS_GM45(dev) ((dev)->pci_device == 0x2A42) |
1123 | 643 | ||
1124 | #define IS_G4X(dev) ((dev)->pci_device == 0x2E02 || \ | 644 | #define IS_G4X(dev) ((dev)->pci_device == 0x2E02 || \ |
1125 | (dev)->pci_device == 0x2E12 || \ | 645 | (dev)->pci_device == 0x2E12 || \ |
@@ -1133,9 +653,9 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); | |||
1133 | IS_I945GM(dev) || IS_I965G(dev) || IS_G33(dev)) | 653 | IS_I945GM(dev) || IS_I965G(dev) || IS_G33(dev)) |
1134 | 654 | ||
1135 | #define IS_MOBILE(dev) (IS_I830(dev) || IS_I85X(dev) || IS_I915GM(dev) || \ | 655 | #define IS_MOBILE(dev) (IS_I830(dev) || IS_I85X(dev) || IS_I915GM(dev) || \ |
1136 | IS_I945GM(dev) || IS_I965GM(dev) || IS_IGD_GM(dev)) | 656 | IS_I945GM(dev) || IS_I965GM(dev) || IS_GM45(dev)) |
1137 | 657 | ||
1138 | #define I915_NEED_GFX_HWS(dev) (IS_G33(dev) || IS_IGD_GM(dev) || IS_G4X(dev)) | 658 | #define I915_NEED_GFX_HWS(dev) (IS_G33(dev) || IS_GM45(dev) || IS_G4X(dev)) |
1139 | 659 | ||
1140 | #define PRIMARY_RINGBUFFER_SIZE (128*1024) | 660 | #define PRIMARY_RINGBUFFER_SIZE (128*1024) |
1141 | 661 | ||
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c new file mode 100644 index 000000000000..9ac73dd1b422 --- /dev/null +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -0,0 +1,2558 @@ | |||
1 | /* | ||
2 | * Copyright © 2008 Intel Corporation | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice (including the next | ||
12 | * paragraph) shall be included in all copies or substantial portions of the | ||
13 | * Software. | ||
14 | * | ||
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||
21 | * IN THE SOFTWARE. | ||
22 | * | ||
23 | * Authors: | ||
24 | * Eric Anholt <eric@anholt.net> | ||
25 | * | ||
26 | */ | ||
27 | |||
28 | #include "drmP.h" | ||
29 | #include "drm.h" | ||
30 | #include "i915_drm.h" | ||
31 | #include "i915_drv.h" | ||
32 | #include <linux/swap.h> | ||
33 | |||
34 | static int | ||
35 | i915_gem_object_set_domain(struct drm_gem_object *obj, | ||
36 | uint32_t read_domains, | ||
37 | uint32_t write_domain); | ||
38 | static int | ||
39 | i915_gem_object_set_domain_range(struct drm_gem_object *obj, | ||
40 | uint64_t offset, | ||
41 | uint64_t size, | ||
42 | uint32_t read_domains, | ||
43 | uint32_t write_domain); | ||
44 | static int | ||
45 | i915_gem_set_domain(struct drm_gem_object *obj, | ||
46 | struct drm_file *file_priv, | ||
47 | uint32_t read_domains, | ||
48 | uint32_t write_domain); | ||
49 | static int i915_gem_object_get_page_list(struct drm_gem_object *obj); | ||
50 | static void i915_gem_object_free_page_list(struct drm_gem_object *obj); | ||
51 | static int i915_gem_object_wait_rendering(struct drm_gem_object *obj); | ||
52 | |||
53 | static void | ||
54 | i915_gem_cleanup_ringbuffer(struct drm_device *dev); | ||
55 | |||
56 | int | ||
57 | i915_gem_init_ioctl(struct drm_device *dev, void *data, | ||
58 | struct drm_file *file_priv) | ||
59 | { | ||
60 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
61 | struct drm_i915_gem_init *args = data; | ||
62 | |||
63 | mutex_lock(&dev->struct_mutex); | ||
64 | |||
65 | if (args->gtt_start >= args->gtt_end || | ||
66 | (args->gtt_start & (PAGE_SIZE - 1)) != 0 || | ||
67 | (args->gtt_end & (PAGE_SIZE - 1)) != 0) { | ||
68 | mutex_unlock(&dev->struct_mutex); | ||
69 | return -EINVAL; | ||
70 | } | ||
71 | |||
72 | drm_mm_init(&dev_priv->mm.gtt_space, args->gtt_start, | ||
73 | args->gtt_end - args->gtt_start); | ||
74 | |||
75 | dev->gtt_total = (uint32_t) (args->gtt_end - args->gtt_start); | ||
76 | |||
77 | mutex_unlock(&dev->struct_mutex); | ||
78 | |||
79 | return 0; | ||
80 | } | ||
81 | |||
82 | |||
83 | /** | ||
84 | * Creates a new mm object and returns a handle to it. | ||
85 | */ | ||
86 | int | ||
87 | i915_gem_create_ioctl(struct drm_device *dev, void *data, | ||
88 | struct drm_file *file_priv) | ||
89 | { | ||
90 | struct drm_i915_gem_create *args = data; | ||
91 | struct drm_gem_object *obj; | ||
92 | int handle, ret; | ||
93 | |||
94 | args->size = roundup(args->size, PAGE_SIZE); | ||
95 | |||
96 | /* Allocate the new object */ | ||
97 | obj = drm_gem_object_alloc(dev, args->size); | ||
98 | if (obj == NULL) | ||
99 | return -ENOMEM; | ||
100 | |||
101 | ret = drm_gem_handle_create(file_priv, obj, &handle); | ||
102 | mutex_lock(&dev->struct_mutex); | ||
103 | drm_gem_object_handle_unreference(obj); | ||
104 | mutex_unlock(&dev->struct_mutex); | ||
105 | |||
106 | if (ret) | ||
107 | return ret; | ||
108 | |||
109 | args->handle = handle; | ||
110 | |||
111 | return 0; | ||
112 | } | ||
113 | |||
114 | /** | ||
115 | * Reads data from the object referenced by handle. | ||
116 | * | ||
117 | * On error, the contents of *data are undefined. | ||
118 | */ | ||
119 | int | ||
120 | i915_gem_pread_ioctl(struct drm_device *dev, void *data, | ||
121 | struct drm_file *file_priv) | ||
122 | { | ||
123 | struct drm_i915_gem_pread *args = data; | ||
124 | struct drm_gem_object *obj; | ||
125 | struct drm_i915_gem_object *obj_priv; | ||
126 | ssize_t read; | ||
127 | loff_t offset; | ||
128 | int ret; | ||
129 | |||
130 | obj = drm_gem_object_lookup(dev, file_priv, args->handle); | ||
131 | if (obj == NULL) | ||
132 | return -EBADF; | ||
133 | obj_priv = obj->driver_private; | ||
134 | |||
135 | /* Bounds check source. | ||
136 | * | ||
137 | * XXX: This could use review for overflow issues... | ||
138 | */ | ||
139 | if (args->offset > obj->size || args->size > obj->size || | ||
140 | args->offset + args->size > obj->size) { | ||
141 | drm_gem_object_unreference(obj); | ||
142 | return -EINVAL; | ||
143 | } | ||
144 | |||
145 | mutex_lock(&dev->struct_mutex); | ||
146 | |||
147 | ret = i915_gem_object_set_domain_range(obj, args->offset, args->size, | ||
148 | I915_GEM_DOMAIN_CPU, 0); | ||
149 | if (ret != 0) { | ||
150 | drm_gem_object_unreference(obj); | ||
151 | mutex_unlock(&dev->struct_mutex); | ||
152 | return ret; | ||
153 | } | ||
154 | |||
155 | offset = args->offset; | ||
156 | |||
157 | read = vfs_read(obj->filp, (char __user *)(uintptr_t)args->data_ptr, | ||
158 | args->size, &offset); | ||
159 | if (read != args->size) { | ||
160 | drm_gem_object_unreference(obj); | ||
161 | mutex_unlock(&dev->struct_mutex); | ||
162 | if (read < 0) | ||
163 | return read; | ||
164 | else | ||
165 | return -EINVAL; | ||
166 | } | ||
167 | |||
168 | drm_gem_object_unreference(obj); | ||
169 | mutex_unlock(&dev->struct_mutex); | ||
170 | |||
171 | return 0; | ||
172 | } | ||
173 | |||
174 | static int | ||
175 | i915_gem_gtt_pwrite(struct drm_device *dev, struct drm_gem_object *obj, | ||
176 | struct drm_i915_gem_pwrite *args, | ||
177 | struct drm_file *file_priv) | ||
178 | { | ||
179 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | ||
180 | ssize_t remain; | ||
181 | loff_t offset; | ||
182 | char __user *user_data; | ||
183 | char __iomem *vaddr; | ||
184 | char *vaddr_atomic; | ||
185 | int i, o, l; | ||
186 | int ret = 0; | ||
187 | unsigned long pfn; | ||
188 | unsigned long unwritten; | ||
189 | |||
190 | user_data = (char __user *) (uintptr_t) args->data_ptr; | ||
191 | remain = args->size; | ||
192 | if (!access_ok(VERIFY_READ, user_data, remain)) | ||
193 | return -EFAULT; | ||
194 | |||
195 | |||
196 | mutex_lock(&dev->struct_mutex); | ||
197 | ret = i915_gem_object_pin(obj, 0); | ||
198 | if (ret) { | ||
199 | mutex_unlock(&dev->struct_mutex); | ||
200 | return ret; | ||
201 | } | ||
202 | ret = i915_gem_set_domain(obj, file_priv, | ||
203 | I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT); | ||
204 | if (ret) | ||
205 | goto fail; | ||
206 | |||
207 | obj_priv = obj->driver_private; | ||
208 | offset = obj_priv->gtt_offset + args->offset; | ||
209 | obj_priv->dirty = 1; | ||
210 | |||
211 | while (remain > 0) { | ||
212 | /* Operation in this page | ||
213 | * | ||
214 | * i = page number | ||
215 | * o = offset within page | ||
216 | * l = bytes to copy | ||
217 | */ | ||
218 | i = offset >> PAGE_SHIFT; | ||
219 | o = offset & (PAGE_SIZE-1); | ||
220 | l = remain; | ||
221 | if ((o + l) > PAGE_SIZE) | ||
222 | l = PAGE_SIZE - o; | ||
223 | |||
224 | pfn = (dev->agp->base >> PAGE_SHIFT) + i; | ||
225 | |||
226 | #ifdef CONFIG_HIGHMEM | ||
227 | /* This is a workaround for the low performance of iounmap | ||
228 | * (approximate 10% cpu cost on normal 3D workloads). | ||
229 | * kmap_atomic on HIGHMEM kernels happens to let us map card | ||
230 | * memory without taking IPIs. When the vmap rework lands | ||
231 | * we should be able to dump this hack. | ||
232 | */ | ||
233 | vaddr_atomic = kmap_atomic_pfn(pfn, KM_USER0); | ||
234 | #if WATCH_PWRITE | ||
235 | DRM_INFO("pwrite i %d o %d l %d pfn %ld vaddr %p\n", | ||
236 | i, o, l, pfn, vaddr_atomic); | ||
237 | #endif | ||
238 | unwritten = __copy_from_user_inatomic_nocache(vaddr_atomic + o, | ||
239 | user_data, l); | ||
240 | kunmap_atomic(vaddr_atomic, KM_USER0); | ||
241 | |||
242 | if (unwritten) | ||
243 | #endif /* CONFIG_HIGHMEM */ | ||
244 | { | ||
245 | vaddr = ioremap_wc(pfn << PAGE_SHIFT, PAGE_SIZE); | ||
246 | #if WATCH_PWRITE | ||
247 | DRM_INFO("pwrite slow i %d o %d l %d " | ||
248 | "pfn %ld vaddr %p\n", | ||
249 | i, o, l, pfn, vaddr); | ||
250 | #endif | ||
251 | if (vaddr == NULL) { | ||
252 | ret = -EFAULT; | ||
253 | goto fail; | ||
254 | } | ||
255 | unwritten = __copy_from_user(vaddr + o, user_data, l); | ||
256 | #if WATCH_PWRITE | ||
257 | DRM_INFO("unwritten %ld\n", unwritten); | ||
258 | #endif | ||
259 | iounmap(vaddr); | ||
260 | if (unwritten) { | ||
261 | ret = -EFAULT; | ||
262 | goto fail; | ||
263 | } | ||
264 | } | ||
265 | |||
266 | remain -= l; | ||
267 | user_data += l; | ||
268 | offset += l; | ||
269 | } | ||
270 | #if WATCH_PWRITE && 1 | ||
271 | i915_gem_clflush_object(obj); | ||
272 | i915_gem_dump_object(obj, args->offset + args->size, __func__, ~0); | ||
273 | i915_gem_clflush_object(obj); | ||
274 | #endif | ||
275 | |||
276 | fail: | ||
277 | i915_gem_object_unpin(obj); | ||
278 | mutex_unlock(&dev->struct_mutex); | ||
279 | |||
280 | return ret; | ||
281 | } | ||
282 | |||
283 | static int | ||
284 | i915_gem_shmem_pwrite(struct drm_device *dev, struct drm_gem_object *obj, | ||
285 | struct drm_i915_gem_pwrite *args, | ||
286 | struct drm_file *file_priv) | ||
287 | { | ||
288 | int ret; | ||
289 | loff_t offset; | ||
290 | ssize_t written; | ||
291 | |||
292 | mutex_lock(&dev->struct_mutex); | ||
293 | |||
294 | ret = i915_gem_set_domain(obj, file_priv, | ||
295 | I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU); | ||
296 | if (ret) { | ||
297 | mutex_unlock(&dev->struct_mutex); | ||
298 | return ret; | ||
299 | } | ||
300 | |||
301 | offset = args->offset; | ||
302 | |||
303 | written = vfs_write(obj->filp, | ||
304 | (char __user *)(uintptr_t) args->data_ptr, | ||
305 | args->size, &offset); | ||
306 | if (written != args->size) { | ||
307 | mutex_unlock(&dev->struct_mutex); | ||
308 | if (written < 0) | ||
309 | return written; | ||
310 | else | ||
311 | return -EINVAL; | ||
312 | } | ||
313 | |||
314 | mutex_unlock(&dev->struct_mutex); | ||
315 | |||
316 | return 0; | ||
317 | } | ||
318 | |||
319 | /** | ||
320 | * Writes data to the object referenced by handle. | ||
321 | * | ||
322 | * On error, the contents of the buffer that were to be modified are undefined. | ||
323 | */ | ||
324 | int | ||
325 | i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, | ||
326 | struct drm_file *file_priv) | ||
327 | { | ||
328 | struct drm_i915_gem_pwrite *args = data; | ||
329 | struct drm_gem_object *obj; | ||
330 | struct drm_i915_gem_object *obj_priv; | ||
331 | int ret = 0; | ||
332 | |||
333 | obj = drm_gem_object_lookup(dev, file_priv, args->handle); | ||
334 | if (obj == NULL) | ||
335 | return -EBADF; | ||
336 | obj_priv = obj->driver_private; | ||
337 | |||
338 | /* Bounds check destination. | ||
339 | * | ||
340 | * XXX: This could use review for overflow issues... | ||
341 | */ | ||
342 | if (args->offset > obj->size || args->size > obj->size || | ||
343 | args->offset + args->size > obj->size) { | ||
344 | drm_gem_object_unreference(obj); | ||
345 | return -EINVAL; | ||
346 | } | ||
347 | |||
348 | /* We can only do the GTT pwrite on untiled buffers, as otherwise | ||
349 | * it would end up going through the fenced access, and we'll get | ||
350 | * different detiling behavior between reading and writing. | ||
351 | * pread/pwrite currently are reading and writing from the CPU | ||
352 | * perspective, requiring manual detiling by the client. | ||
353 | */ | ||
354 | if (obj_priv->tiling_mode == I915_TILING_NONE && | ||
355 | dev->gtt_total != 0) | ||
356 | ret = i915_gem_gtt_pwrite(dev, obj, args, file_priv); | ||
357 | else | ||
358 | ret = i915_gem_shmem_pwrite(dev, obj, args, file_priv); | ||
359 | |||
360 | #if WATCH_PWRITE | ||
361 | if (ret) | ||
362 | DRM_INFO("pwrite failed %d\n", ret); | ||
363 | #endif | ||
364 | |||
365 | drm_gem_object_unreference(obj); | ||
366 | |||
367 | return ret; | ||
368 | } | ||
369 | |||
370 | /** | ||
371 | * Called when user space prepares to use an object | ||
372 | */ | ||
373 | int | ||
374 | i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, | ||
375 | struct drm_file *file_priv) | ||
376 | { | ||
377 | struct drm_i915_gem_set_domain *args = data; | ||
378 | struct drm_gem_object *obj; | ||
379 | int ret; | ||
380 | |||
381 | if (!(dev->driver->driver_features & DRIVER_GEM)) | ||
382 | return -ENODEV; | ||
383 | |||
384 | obj = drm_gem_object_lookup(dev, file_priv, args->handle); | ||
385 | if (obj == NULL) | ||
386 | return -EBADF; | ||
387 | |||
388 | mutex_lock(&dev->struct_mutex); | ||
389 | #if WATCH_BUF | ||
390 | DRM_INFO("set_domain_ioctl %p(%d), %08x %08x\n", | ||
391 | obj, obj->size, args->read_domains, args->write_domain); | ||
392 | #endif | ||
393 | ret = i915_gem_set_domain(obj, file_priv, | ||
394 | args->read_domains, args->write_domain); | ||
395 | drm_gem_object_unreference(obj); | ||
396 | mutex_unlock(&dev->struct_mutex); | ||
397 | return ret; | ||
398 | } | ||
399 | |||
400 | /** | ||
401 | * Called when user space has done writes to this buffer | ||
402 | */ | ||
403 | int | ||
404 | i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data, | ||
405 | struct drm_file *file_priv) | ||
406 | { | ||
407 | struct drm_i915_gem_sw_finish *args = data; | ||
408 | struct drm_gem_object *obj; | ||
409 | struct drm_i915_gem_object *obj_priv; | ||
410 | int ret = 0; | ||
411 | |||
412 | if (!(dev->driver->driver_features & DRIVER_GEM)) | ||
413 | return -ENODEV; | ||
414 | |||
415 | mutex_lock(&dev->struct_mutex); | ||
416 | obj = drm_gem_object_lookup(dev, file_priv, args->handle); | ||
417 | if (obj == NULL) { | ||
418 | mutex_unlock(&dev->struct_mutex); | ||
419 | return -EBADF; | ||
420 | } | ||
421 | |||
422 | #if WATCH_BUF | ||
423 | DRM_INFO("%s: sw_finish %d (%p %d)\n", | ||
424 | __func__, args->handle, obj, obj->size); | ||
425 | #endif | ||
426 | obj_priv = obj->driver_private; | ||
427 | |||
428 | /* Pinned buffers may be scanout, so flush the cache */ | ||
429 | if ((obj->write_domain & I915_GEM_DOMAIN_CPU) && obj_priv->pin_count) { | ||
430 | i915_gem_clflush_object(obj); | ||
431 | drm_agp_chipset_flush(dev); | ||
432 | } | ||
433 | drm_gem_object_unreference(obj); | ||
434 | mutex_unlock(&dev->struct_mutex); | ||
435 | return ret; | ||
436 | } | ||
437 | |||
438 | /** | ||
439 | * Maps the contents of an object, returning the address it is mapped | ||
440 | * into. | ||
441 | * | ||
442 | * While the mapping holds a reference on the contents of the object, it doesn't | ||
443 | * imply a ref on the object itself. | ||
444 | */ | ||
445 | int | ||
446 | i915_gem_mmap_ioctl(struct drm_device *dev, void *data, | ||
447 | struct drm_file *file_priv) | ||
448 | { | ||
449 | struct drm_i915_gem_mmap *args = data; | ||
450 | struct drm_gem_object *obj; | ||
451 | loff_t offset; | ||
452 | unsigned long addr; | ||
453 | |||
454 | if (!(dev->driver->driver_features & DRIVER_GEM)) | ||
455 | return -ENODEV; | ||
456 | |||
457 | obj = drm_gem_object_lookup(dev, file_priv, args->handle); | ||
458 | if (obj == NULL) | ||
459 | return -EBADF; | ||
460 | |||
461 | offset = args->offset; | ||
462 | |||
463 | down_write(¤t->mm->mmap_sem); | ||
464 | addr = do_mmap(obj->filp, 0, args->size, | ||
465 | PROT_READ | PROT_WRITE, MAP_SHARED, | ||
466 | args->offset); | ||
467 | up_write(¤t->mm->mmap_sem); | ||
468 | mutex_lock(&dev->struct_mutex); | ||
469 | drm_gem_object_unreference(obj); | ||
470 | mutex_unlock(&dev->struct_mutex); | ||
471 | if (IS_ERR((void *)addr)) | ||
472 | return addr; | ||
473 | |||
474 | args->addr_ptr = (uint64_t) addr; | ||
475 | |||
476 | return 0; | ||
477 | } | ||
478 | |||
479 | static void | ||
480 | i915_gem_object_free_page_list(struct drm_gem_object *obj) | ||
481 | { | ||
482 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | ||
483 | int page_count = obj->size / PAGE_SIZE; | ||
484 | int i; | ||
485 | |||
486 | if (obj_priv->page_list == NULL) | ||
487 | return; | ||
488 | |||
489 | |||
490 | for (i = 0; i < page_count; i++) | ||
491 | if (obj_priv->page_list[i] != NULL) { | ||
492 | if (obj_priv->dirty) | ||
493 | set_page_dirty(obj_priv->page_list[i]); | ||
494 | mark_page_accessed(obj_priv->page_list[i]); | ||
495 | page_cache_release(obj_priv->page_list[i]); | ||
496 | } | ||
497 | obj_priv->dirty = 0; | ||
498 | |||
499 | drm_free(obj_priv->page_list, | ||
500 | page_count * sizeof(struct page *), | ||
501 | DRM_MEM_DRIVER); | ||
502 | obj_priv->page_list = NULL; | ||
503 | } | ||
504 | |||
505 | static void | ||
506 | i915_gem_object_move_to_active(struct drm_gem_object *obj) | ||
507 | { | ||
508 | struct drm_device *dev = obj->dev; | ||
509 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
510 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | ||
511 | |||
512 | /* Add a reference if we're newly entering the active list. */ | ||
513 | if (!obj_priv->active) { | ||
514 | drm_gem_object_reference(obj); | ||
515 | obj_priv->active = 1; | ||
516 | } | ||
517 | /* Move from whatever list we were on to the tail of execution. */ | ||
518 | list_move_tail(&obj_priv->list, | ||
519 | &dev_priv->mm.active_list); | ||
520 | } | ||
521 | |||
522 | |||
523 | static void | ||
524 | i915_gem_object_move_to_inactive(struct drm_gem_object *obj) | ||
525 | { | ||
526 | struct drm_device *dev = obj->dev; | ||
527 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
528 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | ||
529 | |||
530 | i915_verify_inactive(dev, __FILE__, __LINE__); | ||
531 | if (obj_priv->pin_count != 0) | ||
532 | list_del_init(&obj_priv->list); | ||
533 | else | ||
534 | list_move_tail(&obj_priv->list, &dev_priv->mm.inactive_list); | ||
535 | |||
536 | if (obj_priv->active) { | ||
537 | obj_priv->active = 0; | ||
538 | drm_gem_object_unreference(obj); | ||
539 | } | ||
540 | i915_verify_inactive(dev, __FILE__, __LINE__); | ||
541 | } | ||
542 | |||
543 | /** | ||
544 | * Creates a new sequence number, emitting a write of it to the status page | ||
545 | * plus an interrupt, which will trigger i915_user_interrupt_handler. | ||
546 | * | ||
547 | * Must be called with struct_lock held. | ||
548 | * | ||
549 | * Returned sequence numbers are nonzero on success. | ||
550 | */ | ||
551 | static uint32_t | ||
552 | i915_add_request(struct drm_device *dev, uint32_t flush_domains) | ||
553 | { | ||
554 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
555 | struct drm_i915_gem_request *request; | ||
556 | uint32_t seqno; | ||
557 | int was_empty; | ||
558 | RING_LOCALS; | ||
559 | |||
560 | request = drm_calloc(1, sizeof(*request), DRM_MEM_DRIVER); | ||
561 | if (request == NULL) | ||
562 | return 0; | ||
563 | |||
564 | /* Grab the seqno we're going to make this request be, and bump the | ||
565 | * next (skipping 0 so it can be the reserved no-seqno value). | ||
566 | */ | ||
567 | seqno = dev_priv->mm.next_gem_seqno; | ||
568 | dev_priv->mm.next_gem_seqno++; | ||
569 | if (dev_priv->mm.next_gem_seqno == 0) | ||
570 | dev_priv->mm.next_gem_seqno++; | ||
571 | |||
572 | BEGIN_LP_RING(4); | ||
573 | OUT_RING(MI_STORE_DWORD_INDEX); | ||
574 | OUT_RING(I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); | ||
575 | OUT_RING(seqno); | ||
576 | |||
577 | OUT_RING(MI_USER_INTERRUPT); | ||
578 | ADVANCE_LP_RING(); | ||
579 | |||
580 | DRM_DEBUG("%d\n", seqno); | ||
581 | |||
582 | request->seqno = seqno; | ||
583 | request->emitted_jiffies = jiffies; | ||
584 | request->flush_domains = flush_domains; | ||
585 | was_empty = list_empty(&dev_priv->mm.request_list); | ||
586 | list_add_tail(&request->list, &dev_priv->mm.request_list); | ||
587 | |||
588 | if (was_empty && !dev_priv->mm.suspended) | ||
589 | schedule_delayed_work(&dev_priv->mm.retire_work, HZ); | ||
590 | return seqno; | ||
591 | } | ||
592 | |||
593 | /** | ||
594 | * Command execution barrier | ||
595 | * | ||
596 | * Ensures that all commands in the ring are finished | ||
597 | * before signalling the CPU | ||
598 | */ | ||
599 | static uint32_t | ||
600 | i915_retire_commands(struct drm_device *dev) | ||
601 | { | ||
602 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
603 | uint32_t cmd = MI_FLUSH | MI_NO_WRITE_FLUSH; | ||
604 | uint32_t flush_domains = 0; | ||
605 | RING_LOCALS; | ||
606 | |||
607 | /* The sampler always gets flushed on i965 (sigh) */ | ||
608 | if (IS_I965G(dev)) | ||
609 | flush_domains |= I915_GEM_DOMAIN_SAMPLER; | ||
610 | BEGIN_LP_RING(2); | ||
611 | OUT_RING(cmd); | ||
612 | OUT_RING(0); /* noop */ | ||
613 | ADVANCE_LP_RING(); | ||
614 | return flush_domains; | ||
615 | } | ||
616 | |||
617 | /** | ||
618 | * Moves buffers associated only with the given active seqno from the active | ||
619 | * to inactive list, potentially freeing them. | ||
620 | */ | ||
621 | static void | ||
622 | i915_gem_retire_request(struct drm_device *dev, | ||
623 | struct drm_i915_gem_request *request) | ||
624 | { | ||
625 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
626 | |||
627 | /* Move any buffers on the active list that are no longer referenced | ||
628 | * by the ringbuffer to the flushing/inactive lists as appropriate. | ||
629 | */ | ||
630 | while (!list_empty(&dev_priv->mm.active_list)) { | ||
631 | struct drm_gem_object *obj; | ||
632 | struct drm_i915_gem_object *obj_priv; | ||
633 | |||
634 | obj_priv = list_first_entry(&dev_priv->mm.active_list, | ||
635 | struct drm_i915_gem_object, | ||
636 | list); | ||
637 | obj = obj_priv->obj; | ||
638 | |||
639 | /* If the seqno being retired doesn't match the oldest in the | ||
640 | * list, then the oldest in the list must still be newer than | ||
641 | * this seqno. | ||
642 | */ | ||
643 | if (obj_priv->last_rendering_seqno != request->seqno) | ||
644 | return; | ||
645 | #if WATCH_LRU | ||
646 | DRM_INFO("%s: retire %d moves to inactive list %p\n", | ||
647 | __func__, request->seqno, obj); | ||
648 | #endif | ||
649 | |||
650 | if (obj->write_domain != 0) { | ||
651 | list_move_tail(&obj_priv->list, | ||
652 | &dev_priv->mm.flushing_list); | ||
653 | } else { | ||
654 | i915_gem_object_move_to_inactive(obj); | ||
655 | } | ||
656 | } | ||
657 | |||
658 | if (request->flush_domains != 0) { | ||
659 | struct drm_i915_gem_object *obj_priv, *next; | ||
660 | |||
661 | /* Clear the write domain and activity from any buffers | ||
662 | * that are just waiting for a flush matching the one retired. | ||
663 | */ | ||
664 | list_for_each_entry_safe(obj_priv, next, | ||
665 | &dev_priv->mm.flushing_list, list) { | ||
666 | struct drm_gem_object *obj = obj_priv->obj; | ||
667 | |||
668 | if (obj->write_domain & request->flush_domains) { | ||
669 | obj->write_domain = 0; | ||
670 | i915_gem_object_move_to_inactive(obj); | ||
671 | } | ||
672 | } | ||
673 | |||
674 | } | ||
675 | } | ||
676 | |||
677 | /** | ||
678 | * Returns true if seq1 is later than seq2. | ||
679 | */ | ||
680 | static int | ||
681 | i915_seqno_passed(uint32_t seq1, uint32_t seq2) | ||
682 | { | ||
683 | return (int32_t)(seq1 - seq2) >= 0; | ||
684 | } | ||
685 | |||
686 | uint32_t | ||
687 | i915_get_gem_seqno(struct drm_device *dev) | ||
688 | { | ||
689 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
690 | |||
691 | return READ_HWSP(dev_priv, I915_GEM_HWS_INDEX); | ||
692 | } | ||
693 | |||
694 | /** | ||
695 | * This function clears the request list as sequence numbers are passed. | ||
696 | */ | ||
697 | void | ||
698 | i915_gem_retire_requests(struct drm_device *dev) | ||
699 | { | ||
700 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
701 | uint32_t seqno; | ||
702 | |||
703 | seqno = i915_get_gem_seqno(dev); | ||
704 | |||
705 | while (!list_empty(&dev_priv->mm.request_list)) { | ||
706 | struct drm_i915_gem_request *request; | ||
707 | uint32_t retiring_seqno; | ||
708 | |||
709 | request = list_first_entry(&dev_priv->mm.request_list, | ||
710 | struct drm_i915_gem_request, | ||
711 | list); | ||
712 | retiring_seqno = request->seqno; | ||
713 | |||
714 | if (i915_seqno_passed(seqno, retiring_seqno) || | ||
715 | dev_priv->mm.wedged) { | ||
716 | i915_gem_retire_request(dev, request); | ||
717 | |||
718 | list_del(&request->list); | ||
719 | drm_free(request, sizeof(*request), DRM_MEM_DRIVER); | ||
720 | } else | ||
721 | break; | ||
722 | } | ||
723 | } | ||
724 | |||
725 | void | ||
726 | i915_gem_retire_work_handler(struct work_struct *work) | ||
727 | { | ||
728 | drm_i915_private_t *dev_priv; | ||
729 | struct drm_device *dev; | ||
730 | |||
731 | dev_priv = container_of(work, drm_i915_private_t, | ||
732 | mm.retire_work.work); | ||
733 | dev = dev_priv->dev; | ||
734 | |||
735 | mutex_lock(&dev->struct_mutex); | ||
736 | i915_gem_retire_requests(dev); | ||
737 | if (!dev_priv->mm.suspended && | ||
738 | !list_empty(&dev_priv->mm.request_list)) | ||
739 | schedule_delayed_work(&dev_priv->mm.retire_work, HZ); | ||
740 | mutex_unlock(&dev->struct_mutex); | ||
741 | } | ||
742 | |||
743 | /** | ||
744 | * Waits for a sequence number to be signaled, and cleans up the | ||
745 | * request and object lists appropriately for that event. | ||
746 | */ | ||
747 | static int | ||
748 | i915_wait_request(struct drm_device *dev, uint32_t seqno) | ||
749 | { | ||
750 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
751 | int ret = 0; | ||
752 | |||
753 | BUG_ON(seqno == 0); | ||
754 | |||
755 | if (!i915_seqno_passed(i915_get_gem_seqno(dev), seqno)) { | ||
756 | dev_priv->mm.waiting_gem_seqno = seqno; | ||
757 | i915_user_irq_get(dev); | ||
758 | ret = wait_event_interruptible(dev_priv->irq_queue, | ||
759 | i915_seqno_passed(i915_get_gem_seqno(dev), | ||
760 | seqno) || | ||
761 | dev_priv->mm.wedged); | ||
762 | i915_user_irq_put(dev); | ||
763 | dev_priv->mm.waiting_gem_seqno = 0; | ||
764 | } | ||
765 | if (dev_priv->mm.wedged) | ||
766 | ret = -EIO; | ||
767 | |||
768 | if (ret && ret != -ERESTARTSYS) | ||
769 | DRM_ERROR("%s returns %d (awaiting %d at %d)\n", | ||
770 | __func__, ret, seqno, i915_get_gem_seqno(dev)); | ||
771 | |||
772 | /* Directly dispatch request retiring. While we have the work queue | ||
773 | * to handle this, the waiter on a request often wants an associated | ||
774 | * buffer to have made it to the inactive list, and we would need | ||
775 | * a separate wait queue to handle that. | ||
776 | */ | ||
777 | if (ret == 0) | ||
778 | i915_gem_retire_requests(dev); | ||
779 | |||
780 | return ret; | ||
781 | } | ||
782 | |||
783 | static void | ||
784 | i915_gem_flush(struct drm_device *dev, | ||
785 | uint32_t invalidate_domains, | ||
786 | uint32_t flush_domains) | ||
787 | { | ||
788 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
789 | uint32_t cmd; | ||
790 | RING_LOCALS; | ||
791 | |||
792 | #if WATCH_EXEC | ||
793 | DRM_INFO("%s: invalidate %08x flush %08x\n", __func__, | ||
794 | invalidate_domains, flush_domains); | ||
795 | #endif | ||
796 | |||
797 | if (flush_domains & I915_GEM_DOMAIN_CPU) | ||
798 | drm_agp_chipset_flush(dev); | ||
799 | |||
800 | if ((invalidate_domains | flush_domains) & ~(I915_GEM_DOMAIN_CPU | | ||
801 | I915_GEM_DOMAIN_GTT)) { | ||
802 | /* | ||
803 | * read/write caches: | ||
804 | * | ||
805 | * I915_GEM_DOMAIN_RENDER is always invalidated, but is | ||
806 | * only flushed if MI_NO_WRITE_FLUSH is unset. On 965, it is | ||
807 | * also flushed at 2d versus 3d pipeline switches. | ||
808 | * | ||
809 | * read-only caches: | ||
810 | * | ||
811 | * I915_GEM_DOMAIN_SAMPLER is flushed on pre-965 if | ||
812 | * MI_READ_FLUSH is set, and is always flushed on 965. | ||
813 | * | ||
814 | * I915_GEM_DOMAIN_COMMAND may not exist? | ||
815 | * | ||
816 | * I915_GEM_DOMAIN_INSTRUCTION, which exists on 965, is | ||
817 | * invalidated when MI_EXE_FLUSH is set. | ||
818 | * | ||
819 | * I915_GEM_DOMAIN_VERTEX, which exists on 965, is | ||
820 | * invalidated with every MI_FLUSH. | ||
821 | * | ||
822 | * TLBs: | ||
823 | * | ||
824 | * On 965, TLBs associated with I915_GEM_DOMAIN_COMMAND | ||
825 | * and I915_GEM_DOMAIN_CPU in are invalidated at PTE write and | ||
826 | * I915_GEM_DOMAIN_RENDER and I915_GEM_DOMAIN_SAMPLER | ||
827 | * are flushed at any MI_FLUSH. | ||
828 | */ | ||
829 | |||
830 | cmd = MI_FLUSH | MI_NO_WRITE_FLUSH; | ||
831 | if ((invalidate_domains|flush_domains) & | ||
832 | I915_GEM_DOMAIN_RENDER) | ||
833 | cmd &= ~MI_NO_WRITE_FLUSH; | ||
834 | if (!IS_I965G(dev)) { | ||
835 | /* | ||
836 | * On the 965, the sampler cache always gets flushed | ||
837 | * and this bit is reserved. | ||
838 | */ | ||
839 | if (invalidate_domains & I915_GEM_DOMAIN_SAMPLER) | ||
840 | cmd |= MI_READ_FLUSH; | ||
841 | } | ||
842 | if (invalidate_domains & I915_GEM_DOMAIN_INSTRUCTION) | ||
843 | cmd |= MI_EXE_FLUSH; | ||
844 | |||
845 | #if WATCH_EXEC | ||
846 | DRM_INFO("%s: queue flush %08x to ring\n", __func__, cmd); | ||
847 | #endif | ||
848 | BEGIN_LP_RING(2); | ||
849 | OUT_RING(cmd); | ||
850 | OUT_RING(0); /* noop */ | ||
851 | ADVANCE_LP_RING(); | ||
852 | } | ||
853 | } | ||
854 | |||
855 | /** | ||
856 | * Ensures that all rendering to the object has completed and the object is | ||
857 | * safe to unbind from the GTT or access from the CPU. | ||
858 | */ | ||
859 | static int | ||
860 | i915_gem_object_wait_rendering(struct drm_gem_object *obj) | ||
861 | { | ||
862 | struct drm_device *dev = obj->dev; | ||
863 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | ||
864 | int ret; | ||
865 | |||
866 | /* If there are writes queued to the buffer, flush and | ||
867 | * create a new seqno to wait for. | ||
868 | */ | ||
869 | if (obj->write_domain & ~(I915_GEM_DOMAIN_CPU|I915_GEM_DOMAIN_GTT)) { | ||
870 | uint32_t write_domain = obj->write_domain; | ||
871 | #if WATCH_BUF | ||
872 | DRM_INFO("%s: flushing object %p from write domain %08x\n", | ||
873 | __func__, obj, write_domain); | ||
874 | #endif | ||
875 | i915_gem_flush(dev, 0, write_domain); | ||
876 | |||
877 | i915_gem_object_move_to_active(obj); | ||
878 | obj_priv->last_rendering_seqno = i915_add_request(dev, | ||
879 | write_domain); | ||
880 | BUG_ON(obj_priv->last_rendering_seqno == 0); | ||
881 | #if WATCH_LRU | ||
882 | DRM_INFO("%s: flush moves to exec list %p\n", __func__, obj); | ||
883 | #endif | ||
884 | } | ||
885 | |||
886 | /* If there is rendering queued on the buffer being evicted, wait for | ||
887 | * it. | ||
888 | */ | ||
889 | if (obj_priv->active) { | ||
890 | #if WATCH_BUF | ||
891 | DRM_INFO("%s: object %p wait for seqno %08x\n", | ||
892 | __func__, obj, obj_priv->last_rendering_seqno); | ||
893 | #endif | ||
894 | ret = i915_wait_request(dev, obj_priv->last_rendering_seqno); | ||
895 | if (ret != 0) | ||
896 | return ret; | ||
897 | } | ||
898 | |||
899 | return 0; | ||
900 | } | ||
901 | |||
902 | /** | ||
903 | * Unbinds an object from the GTT aperture. | ||
904 | */ | ||
905 | static int | ||
906 | i915_gem_object_unbind(struct drm_gem_object *obj) | ||
907 | { | ||
908 | struct drm_device *dev = obj->dev; | ||
909 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | ||
910 | int ret = 0; | ||
911 | |||
912 | #if WATCH_BUF | ||
913 | DRM_INFO("%s:%d %p\n", __func__, __LINE__, obj); | ||
914 | DRM_INFO("gtt_space %p\n", obj_priv->gtt_space); | ||
915 | #endif | ||
916 | if (obj_priv->gtt_space == NULL) | ||
917 | return 0; | ||
918 | |||
919 | if (obj_priv->pin_count != 0) { | ||
920 | DRM_ERROR("Attempting to unbind pinned buffer\n"); | ||
921 | return -EINVAL; | ||
922 | } | ||
923 | |||
924 | /* Wait for any rendering to complete | ||
925 | */ | ||
926 | ret = i915_gem_object_wait_rendering(obj); | ||
927 | if (ret) { | ||
928 | DRM_ERROR("wait_rendering failed: %d\n", ret); | ||
929 | return ret; | ||
930 | } | ||
931 | |||
932 | /* Move the object to the CPU domain to ensure that | ||
933 | * any possible CPU writes while it's not in the GTT | ||
934 | * are flushed when we go to remap it. This will | ||
935 | * also ensure that all pending GPU writes are finished | ||
936 | * before we unbind. | ||
937 | */ | ||
938 | ret = i915_gem_object_set_domain(obj, I915_GEM_DOMAIN_CPU, | ||
939 | I915_GEM_DOMAIN_CPU); | ||
940 | if (ret) { | ||
941 | DRM_ERROR("set_domain failed: %d\n", ret); | ||
942 | return ret; | ||
943 | } | ||
944 | |||
945 | if (obj_priv->agp_mem != NULL) { | ||
946 | drm_unbind_agp(obj_priv->agp_mem); | ||
947 | drm_free_agp(obj_priv->agp_mem, obj->size / PAGE_SIZE); | ||
948 | obj_priv->agp_mem = NULL; | ||
949 | } | ||
950 | |||
951 | BUG_ON(obj_priv->active); | ||
952 | |||
953 | i915_gem_object_free_page_list(obj); | ||
954 | |||
955 | if (obj_priv->gtt_space) { | ||
956 | atomic_dec(&dev->gtt_count); | ||
957 | atomic_sub(obj->size, &dev->gtt_memory); | ||
958 | |||
959 | drm_mm_put_block(obj_priv->gtt_space); | ||
960 | obj_priv->gtt_space = NULL; | ||
961 | } | ||
962 | |||
963 | /* Remove ourselves from the LRU list if present. */ | ||
964 | if (!list_empty(&obj_priv->list)) | ||
965 | list_del_init(&obj_priv->list); | ||
966 | |||
967 | return 0; | ||
968 | } | ||
969 | |||
970 | static int | ||
971 | i915_gem_evict_something(struct drm_device *dev) | ||
972 | { | ||
973 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
974 | struct drm_gem_object *obj; | ||
975 | struct drm_i915_gem_object *obj_priv; | ||
976 | int ret = 0; | ||
977 | |||
978 | for (;;) { | ||
979 | /* If there's an inactive buffer available now, grab it | ||
980 | * and be done. | ||
981 | */ | ||
982 | if (!list_empty(&dev_priv->mm.inactive_list)) { | ||
983 | obj_priv = list_first_entry(&dev_priv->mm.inactive_list, | ||
984 | struct drm_i915_gem_object, | ||
985 | list); | ||
986 | obj = obj_priv->obj; | ||
987 | BUG_ON(obj_priv->pin_count != 0); | ||
988 | #if WATCH_LRU | ||
989 | DRM_INFO("%s: evicting %p\n", __func__, obj); | ||
990 | #endif | ||
991 | BUG_ON(obj_priv->active); | ||
992 | |||
993 | /* Wait on the rendering and unbind the buffer. */ | ||
994 | ret = i915_gem_object_unbind(obj); | ||
995 | break; | ||
996 | } | ||
997 | |||
998 | /* If we didn't get anything, but the ring is still processing | ||
999 | * things, wait for one of those things to finish and hopefully | ||
1000 | * leave us a buffer to evict. | ||
1001 | */ | ||
1002 | if (!list_empty(&dev_priv->mm.request_list)) { | ||
1003 | struct drm_i915_gem_request *request; | ||
1004 | |||
1005 | request = list_first_entry(&dev_priv->mm.request_list, | ||
1006 | struct drm_i915_gem_request, | ||
1007 | list); | ||
1008 | |||
1009 | ret = i915_wait_request(dev, request->seqno); | ||
1010 | if (ret) | ||
1011 | break; | ||
1012 | |||
1013 | /* if waiting caused an object to become inactive, | ||
1014 | * then loop around and wait for it. Otherwise, we | ||
1015 | * assume that waiting freed and unbound something, | ||
1016 | * so there should now be some space in the GTT | ||
1017 | */ | ||
1018 | if (!list_empty(&dev_priv->mm.inactive_list)) | ||
1019 | continue; | ||
1020 | break; | ||
1021 | } | ||
1022 | |||
1023 | /* If we didn't have anything on the request list but there | ||
1024 | * are buffers awaiting a flush, emit one and try again. | ||
1025 | * When we wait on it, those buffers waiting for that flush | ||
1026 | * will get moved to inactive. | ||
1027 | */ | ||
1028 | if (!list_empty(&dev_priv->mm.flushing_list)) { | ||
1029 | obj_priv = list_first_entry(&dev_priv->mm.flushing_list, | ||
1030 | struct drm_i915_gem_object, | ||
1031 | list); | ||
1032 | obj = obj_priv->obj; | ||
1033 | |||
1034 | i915_gem_flush(dev, | ||
1035 | obj->write_domain, | ||
1036 | obj->write_domain); | ||
1037 | i915_add_request(dev, obj->write_domain); | ||
1038 | |||
1039 | obj = NULL; | ||
1040 | continue; | ||
1041 | } | ||
1042 | |||
1043 | DRM_ERROR("inactive empty %d request empty %d " | ||
1044 | "flushing empty %d\n", | ||
1045 | list_empty(&dev_priv->mm.inactive_list), | ||
1046 | list_empty(&dev_priv->mm.request_list), | ||
1047 | list_empty(&dev_priv->mm.flushing_list)); | ||
1048 | /* If we didn't do any of the above, there's nothing to be done | ||
1049 | * and we just can't fit it in. | ||
1050 | */ | ||
1051 | return -ENOMEM; | ||
1052 | } | ||
1053 | return ret; | ||
1054 | } | ||
1055 | |||
1056 | static int | ||
1057 | i915_gem_object_get_page_list(struct drm_gem_object *obj) | ||
1058 | { | ||
1059 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | ||
1060 | int page_count, i; | ||
1061 | struct address_space *mapping; | ||
1062 | struct inode *inode; | ||
1063 | struct page *page; | ||
1064 | int ret; | ||
1065 | |||
1066 | if (obj_priv->page_list) | ||
1067 | return 0; | ||
1068 | |||
1069 | /* Get the list of pages out of our struct file. They'll be pinned | ||
1070 | * at this point until we release them. | ||
1071 | */ | ||
1072 | page_count = obj->size / PAGE_SIZE; | ||
1073 | BUG_ON(obj_priv->page_list != NULL); | ||
1074 | obj_priv->page_list = drm_calloc(page_count, sizeof(struct page *), | ||
1075 | DRM_MEM_DRIVER); | ||
1076 | if (obj_priv->page_list == NULL) { | ||
1077 | DRM_ERROR("Faled to allocate page list\n"); | ||
1078 | return -ENOMEM; | ||
1079 | } | ||
1080 | |||
1081 | inode = obj->filp->f_path.dentry->d_inode; | ||
1082 | mapping = inode->i_mapping; | ||
1083 | for (i = 0; i < page_count; i++) { | ||
1084 | page = read_mapping_page(mapping, i, NULL); | ||
1085 | if (IS_ERR(page)) { | ||
1086 | ret = PTR_ERR(page); | ||
1087 | DRM_ERROR("read_mapping_page failed: %d\n", ret); | ||
1088 | i915_gem_object_free_page_list(obj); | ||
1089 | return ret; | ||
1090 | } | ||
1091 | obj_priv->page_list[i] = page; | ||
1092 | } | ||
1093 | return 0; | ||
1094 | } | ||
1095 | |||
1096 | /** | ||
1097 | * Finds free space in the GTT aperture and binds the object there. | ||
1098 | */ | ||
1099 | static int | ||
1100 | i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) | ||
1101 | { | ||
1102 | struct drm_device *dev = obj->dev; | ||
1103 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
1104 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | ||
1105 | struct drm_mm_node *free_space; | ||
1106 | int page_count, ret; | ||
1107 | |||
1108 | if (alignment == 0) | ||
1109 | alignment = PAGE_SIZE; | ||
1110 | if (alignment & (PAGE_SIZE - 1)) { | ||
1111 | DRM_ERROR("Invalid object alignment requested %u\n", alignment); | ||
1112 | return -EINVAL; | ||
1113 | } | ||
1114 | |||
1115 | search_free: | ||
1116 | free_space = drm_mm_search_free(&dev_priv->mm.gtt_space, | ||
1117 | obj->size, alignment, 0); | ||
1118 | if (free_space != NULL) { | ||
1119 | obj_priv->gtt_space = drm_mm_get_block(free_space, obj->size, | ||
1120 | alignment); | ||
1121 | if (obj_priv->gtt_space != NULL) { | ||
1122 | obj_priv->gtt_space->private = obj; | ||
1123 | obj_priv->gtt_offset = obj_priv->gtt_space->start; | ||
1124 | } | ||
1125 | } | ||
1126 | if (obj_priv->gtt_space == NULL) { | ||
1127 | /* If the gtt is empty and we're still having trouble | ||
1128 | * fitting our object in, we're out of memory. | ||
1129 | */ | ||
1130 | #if WATCH_LRU | ||
1131 | DRM_INFO("%s: GTT full, evicting something\n", __func__); | ||
1132 | #endif | ||
1133 | if (list_empty(&dev_priv->mm.inactive_list) && | ||
1134 | list_empty(&dev_priv->mm.flushing_list) && | ||
1135 | list_empty(&dev_priv->mm.active_list)) { | ||
1136 | DRM_ERROR("GTT full, but LRU list empty\n"); | ||
1137 | return -ENOMEM; | ||
1138 | } | ||
1139 | |||
1140 | ret = i915_gem_evict_something(dev); | ||
1141 | if (ret != 0) { | ||
1142 | DRM_ERROR("Failed to evict a buffer %d\n", ret); | ||
1143 | return ret; | ||
1144 | } | ||
1145 | goto search_free; | ||
1146 | } | ||
1147 | |||
1148 | #if WATCH_BUF | ||
1149 | DRM_INFO("Binding object of size %d at 0x%08x\n", | ||
1150 | obj->size, obj_priv->gtt_offset); | ||
1151 | #endif | ||
1152 | ret = i915_gem_object_get_page_list(obj); | ||
1153 | if (ret) { | ||
1154 | drm_mm_put_block(obj_priv->gtt_space); | ||
1155 | obj_priv->gtt_space = NULL; | ||
1156 | return ret; | ||
1157 | } | ||
1158 | |||
1159 | page_count = obj->size / PAGE_SIZE; | ||
1160 | /* Create an AGP memory structure pointing at our pages, and bind it | ||
1161 | * into the GTT. | ||
1162 | */ | ||
1163 | obj_priv->agp_mem = drm_agp_bind_pages(dev, | ||
1164 | obj_priv->page_list, | ||
1165 | page_count, | ||
1166 | obj_priv->gtt_offset, | ||
1167 | obj_priv->agp_type); | ||
1168 | if (obj_priv->agp_mem == NULL) { | ||
1169 | i915_gem_object_free_page_list(obj); | ||
1170 | drm_mm_put_block(obj_priv->gtt_space); | ||
1171 | obj_priv->gtt_space = NULL; | ||
1172 | return -ENOMEM; | ||
1173 | } | ||
1174 | atomic_inc(&dev->gtt_count); | ||
1175 | atomic_add(obj->size, &dev->gtt_memory); | ||
1176 | |||
1177 | /* Assert that the object is not currently in any GPU domain. As it | ||
1178 | * wasn't in the GTT, there shouldn't be any way it could have been in | ||
1179 | * a GPU cache | ||
1180 | */ | ||
1181 | BUG_ON(obj->read_domains & ~(I915_GEM_DOMAIN_CPU|I915_GEM_DOMAIN_GTT)); | ||
1182 | BUG_ON(obj->write_domain & ~(I915_GEM_DOMAIN_CPU|I915_GEM_DOMAIN_GTT)); | ||
1183 | |||
1184 | return 0; | ||
1185 | } | ||
1186 | |||
1187 | void | ||
1188 | i915_gem_clflush_object(struct drm_gem_object *obj) | ||
1189 | { | ||
1190 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | ||
1191 | |||
1192 | /* If we don't have a page list set up, then we're not pinned | ||
1193 | * to GPU, and we can ignore the cache flush because it'll happen | ||
1194 | * again at bind time. | ||
1195 | */ | ||
1196 | if (obj_priv->page_list == NULL) | ||
1197 | return; | ||
1198 | |||
1199 | drm_clflush_pages(obj_priv->page_list, obj->size / PAGE_SIZE); | ||
1200 | } | ||
1201 | |||
1202 | /* | ||
1203 | * Set the next domain for the specified object. This | ||
1204 | * may not actually perform the necessary flushing/invaliding though, | ||
1205 | * as that may want to be batched with other set_domain operations | ||
1206 | * | ||
1207 | * This is (we hope) the only really tricky part of gem. The goal | ||
1208 | * is fairly simple -- track which caches hold bits of the object | ||
1209 | * and make sure they remain coherent. A few concrete examples may | ||
1210 | * help to explain how it works. For shorthand, we use the notation | ||
1211 | * (read_domains, write_domain), e.g. (CPU, CPU) to indicate the | ||
1212 | * a pair of read and write domain masks. | ||
1213 | * | ||
1214 | * Case 1: the batch buffer | ||
1215 | * | ||
1216 | * 1. Allocated | ||
1217 | * 2. Written by CPU | ||
1218 | * 3. Mapped to GTT | ||
1219 | * 4. Read by GPU | ||
1220 | * 5. Unmapped from GTT | ||
1221 | * 6. Freed | ||
1222 | * | ||
1223 | * Let's take these a step at a time | ||
1224 | * | ||
1225 | * 1. Allocated | ||
1226 | * Pages allocated from the kernel may still have | ||
1227 | * cache contents, so we set them to (CPU, CPU) always. | ||
1228 | * 2. Written by CPU (using pwrite) | ||
1229 | * The pwrite function calls set_domain (CPU, CPU) and | ||
1230 | * this function does nothing (as nothing changes) | ||
1231 | * 3. Mapped by GTT | ||
1232 | * This function asserts that the object is not | ||
1233 | * currently in any GPU-based read or write domains | ||
1234 | * 4. Read by GPU | ||
1235 | * i915_gem_execbuffer calls set_domain (COMMAND, 0). | ||
1236 | * As write_domain is zero, this function adds in the | ||
1237 | * current read domains (CPU+COMMAND, 0). | ||
1238 | * flush_domains is set to CPU. | ||
1239 | * invalidate_domains is set to COMMAND | ||
1240 | * clflush is run to get data out of the CPU caches | ||
1241 | * then i915_dev_set_domain calls i915_gem_flush to | ||
1242 | * emit an MI_FLUSH and drm_agp_chipset_flush | ||
1243 | * 5. Unmapped from GTT | ||
1244 | * i915_gem_object_unbind calls set_domain (CPU, CPU) | ||
1245 | * flush_domains and invalidate_domains end up both zero | ||
1246 | * so no flushing/invalidating happens | ||
1247 | * 6. Freed | ||
1248 | * yay, done | ||
1249 | * | ||
1250 | * Case 2: The shared render buffer | ||
1251 | * | ||
1252 | * 1. Allocated | ||
1253 | * 2. Mapped to GTT | ||
1254 | * 3. Read/written by GPU | ||
1255 | * 4. set_domain to (CPU,CPU) | ||
1256 | * 5. Read/written by CPU | ||
1257 | * 6. Read/written by GPU | ||
1258 | * | ||
1259 | * 1. Allocated | ||
1260 | * Same as last example, (CPU, CPU) | ||
1261 | * 2. Mapped to GTT | ||
1262 | * Nothing changes (assertions find that it is not in the GPU) | ||
1263 | * 3. Read/written by GPU | ||
1264 | * execbuffer calls set_domain (RENDER, RENDER) | ||
1265 | * flush_domains gets CPU | ||
1266 | * invalidate_domains gets GPU | ||
1267 | * clflush (obj) | ||
1268 | * MI_FLUSH and drm_agp_chipset_flush | ||
1269 | * 4. set_domain (CPU, CPU) | ||
1270 | * flush_domains gets GPU | ||
1271 | * invalidate_domains gets CPU | ||
1272 | * wait_rendering (obj) to make sure all drawing is complete. | ||
1273 | * This will include an MI_FLUSH to get the data from GPU | ||
1274 | * to memory | ||
1275 | * clflush (obj) to invalidate the CPU cache | ||
1276 | * Another MI_FLUSH in i915_gem_flush (eliminate this somehow?) | ||
1277 | * 5. Read/written by CPU | ||
1278 | * cache lines are loaded and dirtied | ||
1279 | * 6. Read written by GPU | ||
1280 | * Same as last GPU access | ||
1281 | * | ||
1282 | * Case 3: The constant buffer | ||
1283 | * | ||
1284 | * 1. Allocated | ||
1285 | * 2. Written by CPU | ||
1286 | * 3. Read by GPU | ||
1287 | * 4. Updated (written) by CPU again | ||
1288 | * 5. Read by GPU | ||
1289 | * | ||
1290 | * 1. Allocated | ||
1291 | * (CPU, CPU) | ||
1292 | * 2. Written by CPU | ||
1293 | * (CPU, CPU) | ||
1294 | * 3. Read by GPU | ||
1295 | * (CPU+RENDER, 0) | ||
1296 | * flush_domains = CPU | ||
1297 | * invalidate_domains = RENDER | ||
1298 | * clflush (obj) | ||
1299 | * MI_FLUSH | ||
1300 | * drm_agp_chipset_flush | ||
1301 | * 4. Updated (written) by CPU again | ||
1302 | * (CPU, CPU) | ||
1303 | * flush_domains = 0 (no previous write domain) | ||
1304 | * invalidate_domains = 0 (no new read domains) | ||
1305 | * 5. Read by GPU | ||
1306 | * (CPU+RENDER, 0) | ||
1307 | * flush_domains = CPU | ||
1308 | * invalidate_domains = RENDER | ||
1309 | * clflush (obj) | ||
1310 | * MI_FLUSH | ||
1311 | * drm_agp_chipset_flush | ||
1312 | */ | ||
1313 | static int | ||
1314 | i915_gem_object_set_domain(struct drm_gem_object *obj, | ||
1315 | uint32_t read_domains, | ||
1316 | uint32_t write_domain) | ||
1317 | { | ||
1318 | struct drm_device *dev = obj->dev; | ||
1319 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | ||
1320 | uint32_t invalidate_domains = 0; | ||
1321 | uint32_t flush_domains = 0; | ||
1322 | int ret; | ||
1323 | |||
1324 | #if WATCH_BUF | ||
1325 | DRM_INFO("%s: object %p read %08x -> %08x write %08x -> %08x\n", | ||
1326 | __func__, obj, | ||
1327 | obj->read_domains, read_domains, | ||
1328 | obj->write_domain, write_domain); | ||
1329 | #endif | ||
1330 | /* | ||
1331 | * If the object isn't moving to a new write domain, | ||
1332 | * let the object stay in multiple read domains | ||
1333 | */ | ||
1334 | if (write_domain == 0) | ||
1335 | read_domains |= obj->read_domains; | ||
1336 | else | ||
1337 | obj_priv->dirty = 1; | ||
1338 | |||
1339 | /* | ||
1340 | * Flush the current write domain if | ||
1341 | * the new read domains don't match. Invalidate | ||
1342 | * any read domains which differ from the old | ||
1343 | * write domain | ||
1344 | */ | ||
1345 | if (obj->write_domain && obj->write_domain != read_domains) { | ||
1346 | flush_domains |= obj->write_domain; | ||
1347 | invalidate_domains |= read_domains & ~obj->write_domain; | ||
1348 | } | ||
1349 | /* | ||
1350 | * Invalidate any read caches which may have | ||
1351 | * stale data. That is, any new read domains. | ||
1352 | */ | ||
1353 | invalidate_domains |= read_domains & ~obj->read_domains; | ||
1354 | if ((flush_domains | invalidate_domains) & I915_GEM_DOMAIN_CPU) { | ||
1355 | #if WATCH_BUF | ||
1356 | DRM_INFO("%s: CPU domain flush %08x invalidate %08x\n", | ||
1357 | __func__, flush_domains, invalidate_domains); | ||
1358 | #endif | ||
1359 | /* | ||
1360 | * If we're invaliding the CPU cache and flushing a GPU cache, | ||
1361 | * then pause for rendering so that the GPU caches will be | ||
1362 | * flushed before the cpu cache is invalidated | ||
1363 | */ | ||
1364 | if ((invalidate_domains & I915_GEM_DOMAIN_CPU) && | ||
1365 | (flush_domains & ~(I915_GEM_DOMAIN_CPU | | ||
1366 | I915_GEM_DOMAIN_GTT))) { | ||
1367 | ret = i915_gem_object_wait_rendering(obj); | ||
1368 | if (ret) | ||
1369 | return ret; | ||
1370 | } | ||
1371 | i915_gem_clflush_object(obj); | ||
1372 | } | ||
1373 | |||
1374 | if ((write_domain | flush_domains) != 0) | ||
1375 | obj->write_domain = write_domain; | ||
1376 | |||
1377 | /* If we're invalidating the CPU domain, clear the per-page CPU | ||
1378 | * domain list as well. | ||
1379 | */ | ||
1380 | if (obj_priv->page_cpu_valid != NULL && | ||
1381 | (write_domain != 0 || | ||
1382 | read_domains & I915_GEM_DOMAIN_CPU)) { | ||
1383 | drm_free(obj_priv->page_cpu_valid, obj->size / PAGE_SIZE, | ||
1384 | DRM_MEM_DRIVER); | ||
1385 | obj_priv->page_cpu_valid = NULL; | ||
1386 | } | ||
1387 | obj->read_domains = read_domains; | ||
1388 | |||
1389 | dev->invalidate_domains |= invalidate_domains; | ||
1390 | dev->flush_domains |= flush_domains; | ||
1391 | #if WATCH_BUF | ||
1392 | DRM_INFO("%s: read %08x write %08x invalidate %08x flush %08x\n", | ||
1393 | __func__, | ||
1394 | obj->read_domains, obj->write_domain, | ||
1395 | dev->invalidate_domains, dev->flush_domains); | ||
1396 | #endif | ||
1397 | return 0; | ||
1398 | } | ||
1399 | |||
1400 | /** | ||
1401 | * Set the read/write domain on a range of the object. | ||
1402 | * | ||
1403 | * Currently only implemented for CPU reads, otherwise drops to normal | ||
1404 | * i915_gem_object_set_domain(). | ||
1405 | */ | ||
1406 | static int | ||
1407 | i915_gem_object_set_domain_range(struct drm_gem_object *obj, | ||
1408 | uint64_t offset, | ||
1409 | uint64_t size, | ||
1410 | uint32_t read_domains, | ||
1411 | uint32_t write_domain) | ||
1412 | { | ||
1413 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | ||
1414 | int ret, i; | ||
1415 | |||
1416 | if (obj->read_domains & I915_GEM_DOMAIN_CPU) | ||
1417 | return 0; | ||
1418 | |||
1419 | if (read_domains != I915_GEM_DOMAIN_CPU || | ||
1420 | write_domain != 0) | ||
1421 | return i915_gem_object_set_domain(obj, | ||
1422 | read_domains, write_domain); | ||
1423 | |||
1424 | /* Wait on any GPU rendering to the object to be flushed. */ | ||
1425 | if (obj->write_domain & ~(I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT)) { | ||
1426 | ret = i915_gem_object_wait_rendering(obj); | ||
1427 | if (ret) | ||
1428 | return ret; | ||
1429 | } | ||
1430 | |||
1431 | if (obj_priv->page_cpu_valid == NULL) { | ||
1432 | obj_priv->page_cpu_valid = drm_calloc(1, obj->size / PAGE_SIZE, | ||
1433 | DRM_MEM_DRIVER); | ||
1434 | } | ||
1435 | |||
1436 | /* Flush the cache on any pages that are still invalid from the CPU's | ||
1437 | * perspective. | ||
1438 | */ | ||
1439 | for (i = offset / PAGE_SIZE; i <= (offset + size - 1) / PAGE_SIZE; i++) { | ||
1440 | if (obj_priv->page_cpu_valid[i]) | ||
1441 | continue; | ||
1442 | |||
1443 | drm_clflush_pages(obj_priv->page_list + i, 1); | ||
1444 | |||
1445 | obj_priv->page_cpu_valid[i] = 1; | ||
1446 | } | ||
1447 | |||
1448 | return 0; | ||
1449 | } | ||
1450 | |||
1451 | /** | ||
1452 | * Once all of the objects have been set in the proper domain, | ||
1453 | * perform the necessary flush and invalidate operations. | ||
1454 | * | ||
1455 | * Returns the write domains flushed, for use in flush tracking. | ||
1456 | */ | ||
1457 | static uint32_t | ||
1458 | i915_gem_dev_set_domain(struct drm_device *dev) | ||
1459 | { | ||
1460 | uint32_t flush_domains = dev->flush_domains; | ||
1461 | |||
1462 | /* | ||
1463 | * Now that all the buffers are synced to the proper domains, | ||
1464 | * flush and invalidate the collected domains | ||
1465 | */ | ||
1466 | if (dev->invalidate_domains | dev->flush_domains) { | ||
1467 | #if WATCH_EXEC | ||
1468 | DRM_INFO("%s: invalidate_domains %08x flush_domains %08x\n", | ||
1469 | __func__, | ||
1470 | dev->invalidate_domains, | ||
1471 | dev->flush_domains); | ||
1472 | #endif | ||
1473 | i915_gem_flush(dev, | ||
1474 | dev->invalidate_domains, | ||
1475 | dev->flush_domains); | ||
1476 | dev->invalidate_domains = 0; | ||
1477 | dev->flush_domains = 0; | ||
1478 | } | ||
1479 | |||
1480 | return flush_domains; | ||
1481 | } | ||
1482 | |||
1483 | /** | ||
1484 | * Pin an object to the GTT and evaluate the relocations landing in it. | ||
1485 | */ | ||
1486 | static int | ||
1487 | i915_gem_object_pin_and_relocate(struct drm_gem_object *obj, | ||
1488 | struct drm_file *file_priv, | ||
1489 | struct drm_i915_gem_exec_object *entry) | ||
1490 | { | ||
1491 | struct drm_device *dev = obj->dev; | ||
1492 | struct drm_i915_gem_relocation_entry reloc; | ||
1493 | struct drm_i915_gem_relocation_entry __user *relocs; | ||
1494 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | ||
1495 | int i, ret; | ||
1496 | uint32_t last_reloc_offset = -1; | ||
1497 | void __iomem *reloc_page = NULL; | ||
1498 | |||
1499 | /* Choose the GTT offset for our buffer and put it there. */ | ||
1500 | ret = i915_gem_object_pin(obj, (uint32_t) entry->alignment); | ||
1501 | if (ret) | ||
1502 | return ret; | ||
1503 | |||
1504 | entry->offset = obj_priv->gtt_offset; | ||
1505 | |||
1506 | relocs = (struct drm_i915_gem_relocation_entry __user *) | ||
1507 | (uintptr_t) entry->relocs_ptr; | ||
1508 | /* Apply the relocations, using the GTT aperture to avoid cache | ||
1509 | * flushing requirements. | ||
1510 | */ | ||
1511 | for (i = 0; i < entry->relocation_count; i++) { | ||
1512 | struct drm_gem_object *target_obj; | ||
1513 | struct drm_i915_gem_object *target_obj_priv; | ||
1514 | uint32_t reloc_val, reloc_offset; | ||
1515 | uint32_t __iomem *reloc_entry; | ||
1516 | |||
1517 | ret = copy_from_user(&reloc, relocs + i, sizeof(reloc)); | ||
1518 | if (ret != 0) { | ||
1519 | i915_gem_object_unpin(obj); | ||
1520 | return ret; | ||
1521 | } | ||
1522 | |||
1523 | target_obj = drm_gem_object_lookup(obj->dev, file_priv, | ||
1524 | reloc.target_handle); | ||
1525 | if (target_obj == NULL) { | ||
1526 | i915_gem_object_unpin(obj); | ||
1527 | return -EBADF; | ||
1528 | } | ||
1529 | target_obj_priv = target_obj->driver_private; | ||
1530 | |||
1531 | /* The target buffer should have appeared before us in the | ||
1532 | * exec_object list, so it should have a GTT space bound by now. | ||
1533 | */ | ||
1534 | if (target_obj_priv->gtt_space == NULL) { | ||
1535 | DRM_ERROR("No GTT space found for object %d\n", | ||
1536 | reloc.target_handle); | ||
1537 | drm_gem_object_unreference(target_obj); | ||
1538 | i915_gem_object_unpin(obj); | ||
1539 | return -EINVAL; | ||
1540 | } | ||
1541 | |||
1542 | if (reloc.offset > obj->size - 4) { | ||
1543 | DRM_ERROR("Relocation beyond object bounds: " | ||
1544 | "obj %p target %d offset %d size %d.\n", | ||
1545 | obj, reloc.target_handle, | ||
1546 | (int) reloc.offset, (int) obj->size); | ||
1547 | drm_gem_object_unreference(target_obj); | ||
1548 | i915_gem_object_unpin(obj); | ||
1549 | return -EINVAL; | ||
1550 | } | ||
1551 | if (reloc.offset & 3) { | ||
1552 | DRM_ERROR("Relocation not 4-byte aligned: " | ||
1553 | "obj %p target %d offset %d.\n", | ||
1554 | obj, reloc.target_handle, | ||
1555 | (int) reloc.offset); | ||
1556 | drm_gem_object_unreference(target_obj); | ||
1557 | i915_gem_object_unpin(obj); | ||
1558 | return -EINVAL; | ||
1559 | } | ||
1560 | |||
1561 | if (reloc.write_domain && target_obj->pending_write_domain && | ||
1562 | reloc.write_domain != target_obj->pending_write_domain) { | ||
1563 | DRM_ERROR("Write domain conflict: " | ||
1564 | "obj %p target %d offset %d " | ||
1565 | "new %08x old %08x\n", | ||
1566 | obj, reloc.target_handle, | ||
1567 | (int) reloc.offset, | ||
1568 | reloc.write_domain, | ||
1569 | target_obj->pending_write_domain); | ||
1570 | drm_gem_object_unreference(target_obj); | ||
1571 | i915_gem_object_unpin(obj); | ||
1572 | return -EINVAL; | ||
1573 | } | ||
1574 | |||
1575 | #if WATCH_RELOC | ||
1576 | DRM_INFO("%s: obj %p offset %08x target %d " | ||
1577 | "read %08x write %08x gtt %08x " | ||
1578 | "presumed %08x delta %08x\n", | ||
1579 | __func__, | ||
1580 | obj, | ||
1581 | (int) reloc.offset, | ||
1582 | (int) reloc.target_handle, | ||
1583 | (int) reloc.read_domains, | ||
1584 | (int) reloc.write_domain, | ||
1585 | (int) target_obj_priv->gtt_offset, | ||
1586 | (int) reloc.presumed_offset, | ||
1587 | reloc.delta); | ||
1588 | #endif | ||
1589 | |||
1590 | target_obj->pending_read_domains |= reloc.read_domains; | ||
1591 | target_obj->pending_write_domain |= reloc.write_domain; | ||
1592 | |||
1593 | /* If the relocation already has the right value in it, no | ||
1594 | * more work needs to be done. | ||
1595 | */ | ||
1596 | if (target_obj_priv->gtt_offset == reloc.presumed_offset) { | ||
1597 | drm_gem_object_unreference(target_obj); | ||
1598 | continue; | ||
1599 | } | ||
1600 | |||
1601 | /* Now that we're going to actually write some data in, | ||
1602 | * make sure that any rendering using this buffer's contents | ||
1603 | * is completed. | ||
1604 | */ | ||
1605 | i915_gem_object_wait_rendering(obj); | ||
1606 | |||
1607 | /* As we're writing through the gtt, flush | ||
1608 | * any CPU writes before we write the relocations | ||
1609 | */ | ||
1610 | if (obj->write_domain & I915_GEM_DOMAIN_CPU) { | ||
1611 | i915_gem_clflush_object(obj); | ||
1612 | drm_agp_chipset_flush(dev); | ||
1613 | obj->write_domain = 0; | ||
1614 | } | ||
1615 | |||
1616 | /* Map the page containing the relocation we're going to | ||
1617 | * perform. | ||
1618 | */ | ||
1619 | reloc_offset = obj_priv->gtt_offset + reloc.offset; | ||
1620 | if (reloc_page == NULL || | ||
1621 | (last_reloc_offset & ~(PAGE_SIZE - 1)) != | ||
1622 | (reloc_offset & ~(PAGE_SIZE - 1))) { | ||
1623 | if (reloc_page != NULL) | ||
1624 | iounmap(reloc_page); | ||
1625 | |||
1626 | reloc_page = ioremap_wc(dev->agp->base + | ||
1627 | (reloc_offset & | ||
1628 | ~(PAGE_SIZE - 1)), | ||
1629 | PAGE_SIZE); | ||
1630 | last_reloc_offset = reloc_offset; | ||
1631 | if (reloc_page == NULL) { | ||
1632 | drm_gem_object_unreference(target_obj); | ||
1633 | i915_gem_object_unpin(obj); | ||
1634 | return -ENOMEM; | ||
1635 | } | ||
1636 | } | ||
1637 | |||
1638 | reloc_entry = (uint32_t __iomem *)(reloc_page + | ||
1639 | (reloc_offset & (PAGE_SIZE - 1))); | ||
1640 | reloc_val = target_obj_priv->gtt_offset + reloc.delta; | ||
1641 | |||
1642 | #if WATCH_BUF | ||
1643 | DRM_INFO("Applied relocation: %p@0x%08x %08x -> %08x\n", | ||
1644 | obj, (unsigned int) reloc.offset, | ||
1645 | readl(reloc_entry), reloc_val); | ||
1646 | #endif | ||
1647 | writel(reloc_val, reloc_entry); | ||
1648 | |||
1649 | /* Write the updated presumed offset for this entry back out | ||
1650 | * to the user. | ||
1651 | */ | ||
1652 | reloc.presumed_offset = target_obj_priv->gtt_offset; | ||
1653 | ret = copy_to_user(relocs + i, &reloc, sizeof(reloc)); | ||
1654 | if (ret != 0) { | ||
1655 | drm_gem_object_unreference(target_obj); | ||
1656 | i915_gem_object_unpin(obj); | ||
1657 | return ret; | ||
1658 | } | ||
1659 | |||
1660 | drm_gem_object_unreference(target_obj); | ||
1661 | } | ||
1662 | |||
1663 | if (reloc_page != NULL) | ||
1664 | iounmap(reloc_page); | ||
1665 | |||
1666 | #if WATCH_BUF | ||
1667 | if (0) | ||
1668 | i915_gem_dump_object(obj, 128, __func__, ~0); | ||
1669 | #endif | ||
1670 | return 0; | ||
1671 | } | ||
1672 | |||
1673 | /** Dispatch a batchbuffer to the ring | ||
1674 | */ | ||
1675 | static int | ||
1676 | i915_dispatch_gem_execbuffer(struct drm_device *dev, | ||
1677 | struct drm_i915_gem_execbuffer *exec, | ||
1678 | uint64_t exec_offset) | ||
1679 | { | ||
1680 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
1681 | struct drm_clip_rect __user *boxes = (struct drm_clip_rect __user *) | ||
1682 | (uintptr_t) exec->cliprects_ptr; | ||
1683 | int nbox = exec->num_cliprects; | ||
1684 | int i = 0, count; | ||
1685 | uint32_t exec_start, exec_len; | ||
1686 | RING_LOCALS; | ||
1687 | |||
1688 | exec_start = (uint32_t) exec_offset + exec->batch_start_offset; | ||
1689 | exec_len = (uint32_t) exec->batch_len; | ||
1690 | |||
1691 | if ((exec_start | exec_len) & 0x7) { | ||
1692 | DRM_ERROR("alignment\n"); | ||
1693 | return -EINVAL; | ||
1694 | } | ||
1695 | |||
1696 | if (!exec_start) | ||
1697 | return -EINVAL; | ||
1698 | |||
1699 | count = nbox ? nbox : 1; | ||
1700 | |||
1701 | for (i = 0; i < count; i++) { | ||
1702 | if (i < nbox) { | ||
1703 | int ret = i915_emit_box(dev, boxes, i, | ||
1704 | exec->DR1, exec->DR4); | ||
1705 | if (ret) | ||
1706 | return ret; | ||
1707 | } | ||
1708 | |||
1709 | if (IS_I830(dev) || IS_845G(dev)) { | ||
1710 | BEGIN_LP_RING(4); | ||
1711 | OUT_RING(MI_BATCH_BUFFER); | ||
1712 | OUT_RING(exec_start | MI_BATCH_NON_SECURE); | ||
1713 | OUT_RING(exec_start + exec_len - 4); | ||
1714 | OUT_RING(0); | ||
1715 | ADVANCE_LP_RING(); | ||
1716 | } else { | ||
1717 | BEGIN_LP_RING(2); | ||
1718 | if (IS_I965G(dev)) { | ||
1719 | OUT_RING(MI_BATCH_BUFFER_START | | ||
1720 | (2 << 6) | | ||
1721 | MI_BATCH_NON_SECURE_I965); | ||
1722 | OUT_RING(exec_start); | ||
1723 | } else { | ||
1724 | OUT_RING(MI_BATCH_BUFFER_START | | ||
1725 | (2 << 6)); | ||
1726 | OUT_RING(exec_start | MI_BATCH_NON_SECURE); | ||
1727 | } | ||
1728 | ADVANCE_LP_RING(); | ||
1729 | } | ||
1730 | } | ||
1731 | |||
1732 | /* XXX breadcrumb */ | ||
1733 | return 0; | ||
1734 | } | ||
1735 | |||
1736 | /* Throttle our rendering by waiting until the ring has completed our requests | ||
1737 | * emitted over 20 msec ago. | ||
1738 | * | ||
1739 | * This should get us reasonable parallelism between CPU and GPU but also | ||
1740 | * relatively low latency when blocking on a particular request to finish. | ||
1741 | */ | ||
1742 | static int | ||
1743 | i915_gem_ring_throttle(struct drm_device *dev, struct drm_file *file_priv) | ||
1744 | { | ||
1745 | struct drm_i915_file_private *i915_file_priv = file_priv->driver_priv; | ||
1746 | int ret = 0; | ||
1747 | uint32_t seqno; | ||
1748 | |||
1749 | mutex_lock(&dev->struct_mutex); | ||
1750 | seqno = i915_file_priv->mm.last_gem_throttle_seqno; | ||
1751 | i915_file_priv->mm.last_gem_throttle_seqno = | ||
1752 | i915_file_priv->mm.last_gem_seqno; | ||
1753 | if (seqno) | ||
1754 | ret = i915_wait_request(dev, seqno); | ||
1755 | mutex_unlock(&dev->struct_mutex); | ||
1756 | return ret; | ||
1757 | } | ||
1758 | |||
1759 | int | ||
1760 | i915_gem_execbuffer(struct drm_device *dev, void *data, | ||
1761 | struct drm_file *file_priv) | ||
1762 | { | ||
1763 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
1764 | struct drm_i915_file_private *i915_file_priv = file_priv->driver_priv; | ||
1765 | struct drm_i915_gem_execbuffer *args = data; | ||
1766 | struct drm_i915_gem_exec_object *exec_list = NULL; | ||
1767 | struct drm_gem_object **object_list = NULL; | ||
1768 | struct drm_gem_object *batch_obj; | ||
1769 | int ret, i, pinned = 0; | ||
1770 | uint64_t exec_offset; | ||
1771 | uint32_t seqno, flush_domains; | ||
1772 | |||
1773 | #if WATCH_EXEC | ||
1774 | DRM_INFO("buffers_ptr %d buffer_count %d len %08x\n", | ||
1775 | (int) args->buffers_ptr, args->buffer_count, args->batch_len); | ||
1776 | #endif | ||
1777 | |||
1778 | if (args->buffer_count < 1) { | ||
1779 | DRM_ERROR("execbuf with %d buffers\n", args->buffer_count); | ||
1780 | return -EINVAL; | ||
1781 | } | ||
1782 | /* Copy in the exec list from userland */ | ||
1783 | exec_list = drm_calloc(sizeof(*exec_list), args->buffer_count, | ||
1784 | DRM_MEM_DRIVER); | ||
1785 | object_list = drm_calloc(sizeof(*object_list), args->buffer_count, | ||
1786 | DRM_MEM_DRIVER); | ||
1787 | if (exec_list == NULL || object_list == NULL) { | ||
1788 | DRM_ERROR("Failed to allocate exec or object list " | ||
1789 | "for %d buffers\n", | ||
1790 | args->buffer_count); | ||
1791 | ret = -ENOMEM; | ||
1792 | goto pre_mutex_err; | ||
1793 | } | ||
1794 | ret = copy_from_user(exec_list, | ||
1795 | (struct drm_i915_relocation_entry __user *) | ||
1796 | (uintptr_t) args->buffers_ptr, | ||
1797 | sizeof(*exec_list) * args->buffer_count); | ||
1798 | if (ret != 0) { | ||
1799 | DRM_ERROR("copy %d exec entries failed %d\n", | ||
1800 | args->buffer_count, ret); | ||
1801 | goto pre_mutex_err; | ||
1802 | } | ||
1803 | |||
1804 | mutex_lock(&dev->struct_mutex); | ||
1805 | |||
1806 | i915_verify_inactive(dev, __FILE__, __LINE__); | ||
1807 | |||
1808 | if (dev_priv->mm.wedged) { | ||
1809 | DRM_ERROR("Execbuf while wedged\n"); | ||
1810 | mutex_unlock(&dev->struct_mutex); | ||
1811 | return -EIO; | ||
1812 | } | ||
1813 | |||
1814 | if (dev_priv->mm.suspended) { | ||
1815 | DRM_ERROR("Execbuf while VT-switched.\n"); | ||
1816 | mutex_unlock(&dev->struct_mutex); | ||
1817 | return -EBUSY; | ||
1818 | } | ||
1819 | |||
1820 | /* Zero the gloabl flush/invalidate flags. These | ||
1821 | * will be modified as each object is bound to the | ||
1822 | * gtt | ||
1823 | */ | ||
1824 | dev->invalidate_domains = 0; | ||
1825 | dev->flush_domains = 0; | ||
1826 | |||
1827 | /* Look up object handles and perform the relocations */ | ||
1828 | for (i = 0; i < args->buffer_count; i++) { | ||
1829 | object_list[i] = drm_gem_object_lookup(dev, file_priv, | ||
1830 | exec_list[i].handle); | ||
1831 | if (object_list[i] == NULL) { | ||
1832 | DRM_ERROR("Invalid object handle %d at index %d\n", | ||
1833 | exec_list[i].handle, i); | ||
1834 | ret = -EBADF; | ||
1835 | goto err; | ||
1836 | } | ||
1837 | |||
1838 | object_list[i]->pending_read_domains = 0; | ||
1839 | object_list[i]->pending_write_domain = 0; | ||
1840 | ret = i915_gem_object_pin_and_relocate(object_list[i], | ||
1841 | file_priv, | ||
1842 | &exec_list[i]); | ||
1843 | if (ret) { | ||
1844 | DRM_ERROR("object bind and relocate failed %d\n", ret); | ||
1845 | goto err; | ||
1846 | } | ||
1847 | pinned = i + 1; | ||
1848 | } | ||
1849 | |||
1850 | /* Set the pending read domains for the batch buffer to COMMAND */ | ||
1851 | batch_obj = object_list[args->buffer_count-1]; | ||
1852 | batch_obj->pending_read_domains = I915_GEM_DOMAIN_COMMAND; | ||
1853 | batch_obj->pending_write_domain = 0; | ||
1854 | |||
1855 | i915_verify_inactive(dev, __FILE__, __LINE__); | ||
1856 | |||
1857 | for (i = 0; i < args->buffer_count; i++) { | ||
1858 | struct drm_gem_object *obj = object_list[i]; | ||
1859 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | ||
1860 | |||
1861 | if (obj_priv->gtt_space == NULL) { | ||
1862 | /* We evicted the buffer in the process of validating | ||
1863 | * our set of buffers in. We could try to recover by | ||
1864 | * kicking them everything out and trying again from | ||
1865 | * the start. | ||
1866 | */ | ||
1867 | ret = -ENOMEM; | ||
1868 | goto err; | ||
1869 | } | ||
1870 | |||
1871 | /* make sure all previous memory operations have passed */ | ||
1872 | ret = i915_gem_object_set_domain(obj, | ||
1873 | obj->pending_read_domains, | ||
1874 | obj->pending_write_domain); | ||
1875 | if (ret) | ||
1876 | goto err; | ||
1877 | } | ||
1878 | |||
1879 | i915_verify_inactive(dev, __FILE__, __LINE__); | ||
1880 | |||
1881 | /* Flush/invalidate caches and chipset buffer */ | ||
1882 | flush_domains = i915_gem_dev_set_domain(dev); | ||
1883 | |||
1884 | i915_verify_inactive(dev, __FILE__, __LINE__); | ||
1885 | |||
1886 | #if WATCH_COHERENCY | ||
1887 | for (i = 0; i < args->buffer_count; i++) { | ||
1888 | i915_gem_object_check_coherency(object_list[i], | ||
1889 | exec_list[i].handle); | ||
1890 | } | ||
1891 | #endif | ||
1892 | |||
1893 | exec_offset = exec_list[args->buffer_count - 1].offset; | ||
1894 | |||
1895 | #if WATCH_EXEC | ||
1896 | i915_gem_dump_object(object_list[args->buffer_count - 1], | ||
1897 | args->batch_len, | ||
1898 | __func__, | ||
1899 | ~0); | ||
1900 | #endif | ||
1901 | |||
1902 | (void)i915_add_request(dev, flush_domains); | ||
1903 | |||
1904 | /* Exec the batchbuffer */ | ||
1905 | ret = i915_dispatch_gem_execbuffer(dev, args, exec_offset); | ||
1906 | if (ret) { | ||
1907 | DRM_ERROR("dispatch failed %d\n", ret); | ||
1908 | goto err; | ||
1909 | } | ||
1910 | |||
1911 | /* | ||
1912 | * Ensure that the commands in the batch buffer are | ||
1913 | * finished before the interrupt fires | ||
1914 | */ | ||
1915 | flush_domains = i915_retire_commands(dev); | ||
1916 | |||
1917 | i915_verify_inactive(dev, __FILE__, __LINE__); | ||
1918 | |||
1919 | /* | ||
1920 | * Get a seqno representing the execution of the current buffer, | ||
1921 | * which we can wait on. We would like to mitigate these interrupts, | ||
1922 | * likely by only creating seqnos occasionally (so that we have | ||
1923 | * *some* interrupts representing completion of buffers that we can | ||
1924 | * wait on when trying to clear up gtt space). | ||
1925 | */ | ||
1926 | seqno = i915_add_request(dev, flush_domains); | ||
1927 | BUG_ON(seqno == 0); | ||
1928 | i915_file_priv->mm.last_gem_seqno = seqno; | ||
1929 | for (i = 0; i < args->buffer_count; i++) { | ||
1930 | struct drm_gem_object *obj = object_list[i]; | ||
1931 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | ||
1932 | |||
1933 | i915_gem_object_move_to_active(obj); | ||
1934 | obj_priv->last_rendering_seqno = seqno; | ||
1935 | #if WATCH_LRU | ||
1936 | DRM_INFO("%s: move to exec list %p\n", __func__, obj); | ||
1937 | #endif | ||
1938 | } | ||
1939 | #if WATCH_LRU | ||
1940 | i915_dump_lru(dev, __func__); | ||
1941 | #endif | ||
1942 | |||
1943 | i915_verify_inactive(dev, __FILE__, __LINE__); | ||
1944 | |||
1945 | /* Copy the new buffer offsets back to the user's exec list. */ | ||
1946 | ret = copy_to_user((struct drm_i915_relocation_entry __user *) | ||
1947 | (uintptr_t) args->buffers_ptr, | ||
1948 | exec_list, | ||
1949 | sizeof(*exec_list) * args->buffer_count); | ||
1950 | if (ret) | ||
1951 | DRM_ERROR("failed to copy %d exec entries " | ||
1952 | "back to user (%d)\n", | ||
1953 | args->buffer_count, ret); | ||
1954 | err: | ||
1955 | if (object_list != NULL) { | ||
1956 | for (i = 0; i < pinned; i++) | ||
1957 | i915_gem_object_unpin(object_list[i]); | ||
1958 | |||
1959 | for (i = 0; i < args->buffer_count; i++) | ||
1960 | drm_gem_object_unreference(object_list[i]); | ||
1961 | } | ||
1962 | mutex_unlock(&dev->struct_mutex); | ||
1963 | |||
1964 | pre_mutex_err: | ||
1965 | drm_free(object_list, sizeof(*object_list) * args->buffer_count, | ||
1966 | DRM_MEM_DRIVER); | ||
1967 | drm_free(exec_list, sizeof(*exec_list) * args->buffer_count, | ||
1968 | DRM_MEM_DRIVER); | ||
1969 | |||
1970 | return ret; | ||
1971 | } | ||
1972 | |||
1973 | int | ||
1974 | i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment) | ||
1975 | { | ||
1976 | struct drm_device *dev = obj->dev; | ||
1977 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | ||
1978 | int ret; | ||
1979 | |||
1980 | i915_verify_inactive(dev, __FILE__, __LINE__); | ||
1981 | if (obj_priv->gtt_space == NULL) { | ||
1982 | ret = i915_gem_object_bind_to_gtt(obj, alignment); | ||
1983 | if (ret != 0) { | ||
1984 | DRM_ERROR("Failure to bind: %d", ret); | ||
1985 | return ret; | ||
1986 | } | ||
1987 | } | ||
1988 | obj_priv->pin_count++; | ||
1989 | |||
1990 | /* If the object is not active and not pending a flush, | ||
1991 | * remove it from the inactive list | ||
1992 | */ | ||
1993 | if (obj_priv->pin_count == 1) { | ||
1994 | atomic_inc(&dev->pin_count); | ||
1995 | atomic_add(obj->size, &dev->pin_memory); | ||
1996 | if (!obj_priv->active && | ||
1997 | (obj->write_domain & ~(I915_GEM_DOMAIN_CPU | | ||
1998 | I915_GEM_DOMAIN_GTT)) == 0 && | ||
1999 | !list_empty(&obj_priv->list)) | ||
2000 | list_del_init(&obj_priv->list); | ||
2001 | } | ||
2002 | i915_verify_inactive(dev, __FILE__, __LINE__); | ||
2003 | |||
2004 | return 0; | ||
2005 | } | ||
2006 | |||
2007 | void | ||
2008 | i915_gem_object_unpin(struct drm_gem_object *obj) | ||
2009 | { | ||
2010 | struct drm_device *dev = obj->dev; | ||
2011 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
2012 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | ||
2013 | |||
2014 | i915_verify_inactive(dev, __FILE__, __LINE__); | ||
2015 | obj_priv->pin_count--; | ||
2016 | BUG_ON(obj_priv->pin_count < 0); | ||
2017 | BUG_ON(obj_priv->gtt_space == NULL); | ||
2018 | |||
2019 | /* If the object is no longer pinned, and is | ||
2020 | * neither active nor being flushed, then stick it on | ||
2021 | * the inactive list | ||
2022 | */ | ||
2023 | if (obj_priv->pin_count == 0) { | ||
2024 | if (!obj_priv->active && | ||
2025 | (obj->write_domain & ~(I915_GEM_DOMAIN_CPU | | ||
2026 | I915_GEM_DOMAIN_GTT)) == 0) | ||
2027 | list_move_tail(&obj_priv->list, | ||
2028 | &dev_priv->mm.inactive_list); | ||
2029 | atomic_dec(&dev->pin_count); | ||
2030 | atomic_sub(obj->size, &dev->pin_memory); | ||
2031 | } | ||
2032 | i915_verify_inactive(dev, __FILE__, __LINE__); | ||
2033 | } | ||
2034 | |||
2035 | int | ||
2036 | i915_gem_pin_ioctl(struct drm_device *dev, void *data, | ||
2037 | struct drm_file *file_priv) | ||
2038 | { | ||
2039 | struct drm_i915_gem_pin *args = data; | ||
2040 | struct drm_gem_object *obj; | ||
2041 | struct drm_i915_gem_object *obj_priv; | ||
2042 | int ret; | ||
2043 | |||
2044 | mutex_lock(&dev->struct_mutex); | ||
2045 | |||
2046 | obj = drm_gem_object_lookup(dev, file_priv, args->handle); | ||
2047 | if (obj == NULL) { | ||
2048 | DRM_ERROR("Bad handle in i915_gem_pin_ioctl(): %d\n", | ||
2049 | args->handle); | ||
2050 | mutex_unlock(&dev->struct_mutex); | ||
2051 | return -EBADF; | ||
2052 | } | ||
2053 | obj_priv = obj->driver_private; | ||
2054 | |||
2055 | ret = i915_gem_object_pin(obj, args->alignment); | ||
2056 | if (ret != 0) { | ||
2057 | drm_gem_object_unreference(obj); | ||
2058 | mutex_unlock(&dev->struct_mutex); | ||
2059 | return ret; | ||
2060 | } | ||
2061 | |||
2062 | /* XXX - flush the CPU caches for pinned objects | ||
2063 | * as the X server doesn't manage domains yet | ||
2064 | */ | ||
2065 | if (obj->write_domain & I915_GEM_DOMAIN_CPU) { | ||
2066 | i915_gem_clflush_object(obj); | ||
2067 | drm_agp_chipset_flush(dev); | ||
2068 | obj->write_domain = 0; | ||
2069 | } | ||
2070 | args->offset = obj_priv->gtt_offset; | ||
2071 | drm_gem_object_unreference(obj); | ||
2072 | mutex_unlock(&dev->struct_mutex); | ||
2073 | |||
2074 | return 0; | ||
2075 | } | ||
2076 | |||
2077 | int | ||
2078 | i915_gem_unpin_ioctl(struct drm_device *dev, void *data, | ||
2079 | struct drm_file *file_priv) | ||
2080 | { | ||
2081 | struct drm_i915_gem_pin *args = data; | ||
2082 | struct drm_gem_object *obj; | ||
2083 | |||
2084 | mutex_lock(&dev->struct_mutex); | ||
2085 | |||
2086 | obj = drm_gem_object_lookup(dev, file_priv, args->handle); | ||
2087 | if (obj == NULL) { | ||
2088 | DRM_ERROR("Bad handle in i915_gem_unpin_ioctl(): %d\n", | ||
2089 | args->handle); | ||
2090 | mutex_unlock(&dev->struct_mutex); | ||
2091 | return -EBADF; | ||
2092 | } | ||
2093 | |||
2094 | i915_gem_object_unpin(obj); | ||
2095 | |||
2096 | drm_gem_object_unreference(obj); | ||
2097 | mutex_unlock(&dev->struct_mutex); | ||
2098 | return 0; | ||
2099 | } | ||
2100 | |||
2101 | int | ||
2102 | i915_gem_busy_ioctl(struct drm_device *dev, void *data, | ||
2103 | struct drm_file *file_priv) | ||
2104 | { | ||
2105 | struct drm_i915_gem_busy *args = data; | ||
2106 | struct drm_gem_object *obj; | ||
2107 | struct drm_i915_gem_object *obj_priv; | ||
2108 | |||
2109 | mutex_lock(&dev->struct_mutex); | ||
2110 | obj = drm_gem_object_lookup(dev, file_priv, args->handle); | ||
2111 | if (obj == NULL) { | ||
2112 | DRM_ERROR("Bad handle in i915_gem_busy_ioctl(): %d\n", | ||
2113 | args->handle); | ||
2114 | mutex_unlock(&dev->struct_mutex); | ||
2115 | return -EBADF; | ||
2116 | } | ||
2117 | |||
2118 | obj_priv = obj->driver_private; | ||
2119 | args->busy = obj_priv->active; | ||
2120 | |||
2121 | drm_gem_object_unreference(obj); | ||
2122 | mutex_unlock(&dev->struct_mutex); | ||
2123 | return 0; | ||
2124 | } | ||
2125 | |||
2126 | int | ||
2127 | i915_gem_throttle_ioctl(struct drm_device *dev, void *data, | ||
2128 | struct drm_file *file_priv) | ||
2129 | { | ||
2130 | return i915_gem_ring_throttle(dev, file_priv); | ||
2131 | } | ||
2132 | |||
2133 | int i915_gem_init_object(struct drm_gem_object *obj) | ||
2134 | { | ||
2135 | struct drm_i915_gem_object *obj_priv; | ||
2136 | |||
2137 | obj_priv = drm_calloc(1, sizeof(*obj_priv), DRM_MEM_DRIVER); | ||
2138 | if (obj_priv == NULL) | ||
2139 | return -ENOMEM; | ||
2140 | |||
2141 | /* | ||
2142 | * We've just allocated pages from the kernel, | ||
2143 | * so they've just been written by the CPU with | ||
2144 | * zeros. They'll need to be clflushed before we | ||
2145 | * use them with the GPU. | ||
2146 | */ | ||
2147 | obj->write_domain = I915_GEM_DOMAIN_CPU; | ||
2148 | obj->read_domains = I915_GEM_DOMAIN_CPU; | ||
2149 | |||
2150 | obj_priv->agp_type = AGP_USER_MEMORY; | ||
2151 | |||
2152 | obj->driver_private = obj_priv; | ||
2153 | obj_priv->obj = obj; | ||
2154 | INIT_LIST_HEAD(&obj_priv->list); | ||
2155 | return 0; | ||
2156 | } | ||
2157 | |||
2158 | void i915_gem_free_object(struct drm_gem_object *obj) | ||
2159 | { | ||
2160 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | ||
2161 | |||
2162 | while (obj_priv->pin_count > 0) | ||
2163 | i915_gem_object_unpin(obj); | ||
2164 | |||
2165 | i915_gem_object_unbind(obj); | ||
2166 | |||
2167 | drm_free(obj_priv->page_cpu_valid, 1, DRM_MEM_DRIVER); | ||
2168 | drm_free(obj->driver_private, 1, DRM_MEM_DRIVER); | ||
2169 | } | ||
2170 | |||
2171 | static int | ||
2172 | i915_gem_set_domain(struct drm_gem_object *obj, | ||
2173 | struct drm_file *file_priv, | ||
2174 | uint32_t read_domains, | ||
2175 | uint32_t write_domain) | ||
2176 | { | ||
2177 | struct drm_device *dev = obj->dev; | ||
2178 | int ret; | ||
2179 | uint32_t flush_domains; | ||
2180 | |||
2181 | BUG_ON(!mutex_is_locked(&dev->struct_mutex)); | ||
2182 | |||
2183 | ret = i915_gem_object_set_domain(obj, read_domains, write_domain); | ||
2184 | if (ret) | ||
2185 | return ret; | ||
2186 | flush_domains = i915_gem_dev_set_domain(obj->dev); | ||
2187 | |||
2188 | if (flush_domains & ~(I915_GEM_DOMAIN_CPU|I915_GEM_DOMAIN_GTT)) | ||
2189 | (void) i915_add_request(dev, flush_domains); | ||
2190 | |||
2191 | return 0; | ||
2192 | } | ||
2193 | |||
2194 | /** Unbinds all objects that are on the given buffer list. */ | ||
2195 | static int | ||
2196 | i915_gem_evict_from_list(struct drm_device *dev, struct list_head *head) | ||
2197 | { | ||
2198 | struct drm_gem_object *obj; | ||
2199 | struct drm_i915_gem_object *obj_priv; | ||
2200 | int ret; | ||
2201 | |||
2202 | while (!list_empty(head)) { | ||
2203 | obj_priv = list_first_entry(head, | ||
2204 | struct drm_i915_gem_object, | ||
2205 | list); | ||
2206 | obj = obj_priv->obj; | ||
2207 | |||
2208 | if (obj_priv->pin_count != 0) { | ||
2209 | DRM_ERROR("Pinned object in unbind list\n"); | ||
2210 | mutex_unlock(&dev->struct_mutex); | ||
2211 | return -EINVAL; | ||
2212 | } | ||
2213 | |||
2214 | ret = i915_gem_object_unbind(obj); | ||
2215 | if (ret != 0) { | ||
2216 | DRM_ERROR("Error unbinding object in LeaveVT: %d\n", | ||
2217 | ret); | ||
2218 | mutex_unlock(&dev->struct_mutex); | ||
2219 | return ret; | ||
2220 | } | ||
2221 | } | ||
2222 | |||
2223 | |||
2224 | return 0; | ||
2225 | } | ||
2226 | |||
2227 | static int | ||
2228 | i915_gem_idle(struct drm_device *dev) | ||
2229 | { | ||
2230 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
2231 | uint32_t seqno, cur_seqno, last_seqno; | ||
2232 | int stuck, ret; | ||
2233 | |||
2234 | mutex_lock(&dev->struct_mutex); | ||
2235 | |||
2236 | if (dev_priv->mm.suspended || dev_priv->ring.ring_obj == NULL) { | ||
2237 | mutex_unlock(&dev->struct_mutex); | ||
2238 | return 0; | ||
2239 | } | ||
2240 | |||
2241 | /* Hack! Don't let anybody do execbuf while we don't control the chip. | ||
2242 | * We need to replace this with a semaphore, or something. | ||
2243 | */ | ||
2244 | dev_priv->mm.suspended = 1; | ||
2245 | |||
2246 | /* Cancel the retire work handler, wait for it to finish if running | ||
2247 | */ | ||
2248 | mutex_unlock(&dev->struct_mutex); | ||
2249 | cancel_delayed_work_sync(&dev_priv->mm.retire_work); | ||
2250 | mutex_lock(&dev->struct_mutex); | ||
2251 | |||
2252 | i915_kernel_lost_context(dev); | ||
2253 | |||
2254 | /* Flush the GPU along with all non-CPU write domains | ||
2255 | */ | ||
2256 | i915_gem_flush(dev, ~(I915_GEM_DOMAIN_CPU|I915_GEM_DOMAIN_GTT), | ||
2257 | ~(I915_GEM_DOMAIN_CPU|I915_GEM_DOMAIN_GTT)); | ||
2258 | seqno = i915_add_request(dev, ~(I915_GEM_DOMAIN_CPU | | ||
2259 | I915_GEM_DOMAIN_GTT)); | ||
2260 | |||
2261 | if (seqno == 0) { | ||
2262 | mutex_unlock(&dev->struct_mutex); | ||
2263 | return -ENOMEM; | ||
2264 | } | ||
2265 | |||
2266 | dev_priv->mm.waiting_gem_seqno = seqno; | ||
2267 | last_seqno = 0; | ||
2268 | stuck = 0; | ||
2269 | for (;;) { | ||
2270 | cur_seqno = i915_get_gem_seqno(dev); | ||
2271 | if (i915_seqno_passed(cur_seqno, seqno)) | ||
2272 | break; | ||
2273 | if (last_seqno == cur_seqno) { | ||
2274 | if (stuck++ > 100) { | ||
2275 | DRM_ERROR("hardware wedged\n"); | ||
2276 | dev_priv->mm.wedged = 1; | ||
2277 | DRM_WAKEUP(&dev_priv->irq_queue); | ||
2278 | break; | ||
2279 | } | ||
2280 | } | ||
2281 | msleep(10); | ||
2282 | last_seqno = cur_seqno; | ||
2283 | } | ||
2284 | dev_priv->mm.waiting_gem_seqno = 0; | ||
2285 | |||
2286 | i915_gem_retire_requests(dev); | ||
2287 | |||
2288 | /* Active and flushing should now be empty as we've | ||
2289 | * waited for a sequence higher than any pending execbuffer | ||
2290 | */ | ||
2291 | BUG_ON(!list_empty(&dev_priv->mm.active_list)); | ||
2292 | BUG_ON(!list_empty(&dev_priv->mm.flushing_list)); | ||
2293 | |||
2294 | /* Request should now be empty as we've also waited | ||
2295 | * for the last request in the list | ||
2296 | */ | ||
2297 | BUG_ON(!list_empty(&dev_priv->mm.request_list)); | ||
2298 | |||
2299 | /* Move all buffers out of the GTT. */ | ||
2300 | ret = i915_gem_evict_from_list(dev, &dev_priv->mm.inactive_list); | ||
2301 | if (ret) { | ||
2302 | mutex_unlock(&dev->struct_mutex); | ||
2303 | return ret; | ||
2304 | } | ||
2305 | |||
2306 | BUG_ON(!list_empty(&dev_priv->mm.active_list)); | ||
2307 | BUG_ON(!list_empty(&dev_priv->mm.flushing_list)); | ||
2308 | BUG_ON(!list_empty(&dev_priv->mm.inactive_list)); | ||
2309 | BUG_ON(!list_empty(&dev_priv->mm.request_list)); | ||
2310 | |||
2311 | i915_gem_cleanup_ringbuffer(dev); | ||
2312 | mutex_unlock(&dev->struct_mutex); | ||
2313 | |||
2314 | return 0; | ||
2315 | } | ||
2316 | |||
2317 | static int | ||
2318 | i915_gem_init_hws(struct drm_device *dev) | ||
2319 | { | ||
2320 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
2321 | struct drm_gem_object *obj; | ||
2322 | struct drm_i915_gem_object *obj_priv; | ||
2323 | int ret; | ||
2324 | |||
2325 | /* If we need a physical address for the status page, it's already | ||
2326 | * initialized at driver load time. | ||
2327 | */ | ||
2328 | if (!I915_NEED_GFX_HWS(dev)) | ||
2329 | return 0; | ||
2330 | |||
2331 | obj = drm_gem_object_alloc(dev, 4096); | ||
2332 | if (obj == NULL) { | ||
2333 | DRM_ERROR("Failed to allocate status page\n"); | ||
2334 | return -ENOMEM; | ||
2335 | } | ||
2336 | obj_priv = obj->driver_private; | ||
2337 | obj_priv->agp_type = AGP_USER_CACHED_MEMORY; | ||
2338 | |||
2339 | ret = i915_gem_object_pin(obj, 4096); | ||
2340 | if (ret != 0) { | ||
2341 | drm_gem_object_unreference(obj); | ||
2342 | return ret; | ||
2343 | } | ||
2344 | |||
2345 | dev_priv->status_gfx_addr = obj_priv->gtt_offset; | ||
2346 | |||
2347 | dev_priv->hw_status_page = kmap(obj_priv->page_list[0]); | ||
2348 | if (dev_priv->hw_status_page == NULL) { | ||
2349 | DRM_ERROR("Failed to map status page.\n"); | ||
2350 | memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map)); | ||
2351 | drm_gem_object_unreference(obj); | ||
2352 | return -EINVAL; | ||
2353 | } | ||
2354 | dev_priv->hws_obj = obj; | ||
2355 | memset(dev_priv->hw_status_page, 0, PAGE_SIZE); | ||
2356 | I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr); | ||
2357 | I915_READ(HWS_PGA); /* posting read */ | ||
2358 | DRM_DEBUG("hws offset: 0x%08x\n", dev_priv->status_gfx_addr); | ||
2359 | |||
2360 | return 0; | ||
2361 | } | ||
2362 | |||
2363 | static int | ||
2364 | i915_gem_init_ringbuffer(struct drm_device *dev) | ||
2365 | { | ||
2366 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
2367 | struct drm_gem_object *obj; | ||
2368 | struct drm_i915_gem_object *obj_priv; | ||
2369 | int ret; | ||
2370 | u32 head; | ||
2371 | |||
2372 | ret = i915_gem_init_hws(dev); | ||
2373 | if (ret != 0) | ||
2374 | return ret; | ||
2375 | |||
2376 | obj = drm_gem_object_alloc(dev, 128 * 1024); | ||
2377 | if (obj == NULL) { | ||
2378 | DRM_ERROR("Failed to allocate ringbuffer\n"); | ||
2379 | return -ENOMEM; | ||
2380 | } | ||
2381 | obj_priv = obj->driver_private; | ||
2382 | |||
2383 | ret = i915_gem_object_pin(obj, 4096); | ||
2384 | if (ret != 0) { | ||
2385 | drm_gem_object_unreference(obj); | ||
2386 | return ret; | ||
2387 | } | ||
2388 | |||
2389 | /* Set up the kernel mapping for the ring. */ | ||
2390 | dev_priv->ring.Size = obj->size; | ||
2391 | dev_priv->ring.tail_mask = obj->size - 1; | ||
2392 | |||
2393 | dev_priv->ring.map.offset = dev->agp->base + obj_priv->gtt_offset; | ||
2394 | dev_priv->ring.map.size = obj->size; | ||
2395 | dev_priv->ring.map.type = 0; | ||
2396 | dev_priv->ring.map.flags = 0; | ||
2397 | dev_priv->ring.map.mtrr = 0; | ||
2398 | |||
2399 | drm_core_ioremap_wc(&dev_priv->ring.map, dev); | ||
2400 | if (dev_priv->ring.map.handle == NULL) { | ||
2401 | DRM_ERROR("Failed to map ringbuffer.\n"); | ||
2402 | memset(&dev_priv->ring, 0, sizeof(dev_priv->ring)); | ||
2403 | drm_gem_object_unreference(obj); | ||
2404 | return -EINVAL; | ||
2405 | } | ||
2406 | dev_priv->ring.ring_obj = obj; | ||
2407 | dev_priv->ring.virtual_start = dev_priv->ring.map.handle; | ||
2408 | |||
2409 | /* Stop the ring if it's running. */ | ||
2410 | I915_WRITE(PRB0_CTL, 0); | ||
2411 | I915_WRITE(PRB0_TAIL, 0); | ||
2412 | I915_WRITE(PRB0_HEAD, 0); | ||
2413 | |||
2414 | /* Initialize the ring. */ | ||
2415 | I915_WRITE(PRB0_START, obj_priv->gtt_offset); | ||
2416 | head = I915_READ(PRB0_HEAD) & HEAD_ADDR; | ||
2417 | |||
2418 | /* G45 ring initialization fails to reset head to zero */ | ||
2419 | if (head != 0) { | ||
2420 | DRM_ERROR("Ring head not reset to zero " | ||
2421 | "ctl %08x head %08x tail %08x start %08x\n", | ||
2422 | I915_READ(PRB0_CTL), | ||
2423 | I915_READ(PRB0_HEAD), | ||
2424 | I915_READ(PRB0_TAIL), | ||
2425 | I915_READ(PRB0_START)); | ||
2426 | I915_WRITE(PRB0_HEAD, 0); | ||
2427 | |||
2428 | DRM_ERROR("Ring head forced to zero " | ||
2429 | "ctl %08x head %08x tail %08x start %08x\n", | ||
2430 | I915_READ(PRB0_CTL), | ||
2431 | I915_READ(PRB0_HEAD), | ||
2432 | I915_READ(PRB0_TAIL), | ||
2433 | I915_READ(PRB0_START)); | ||
2434 | } | ||
2435 | |||
2436 | I915_WRITE(PRB0_CTL, | ||
2437 | ((obj->size - 4096) & RING_NR_PAGES) | | ||
2438 | RING_NO_REPORT | | ||
2439 | RING_VALID); | ||
2440 | |||
2441 | head = I915_READ(PRB0_HEAD) & HEAD_ADDR; | ||
2442 | |||
2443 | /* If the head is still not zero, the ring is dead */ | ||
2444 | if (head != 0) { | ||
2445 | DRM_ERROR("Ring initialization failed " | ||
2446 | "ctl %08x head %08x tail %08x start %08x\n", | ||
2447 | I915_READ(PRB0_CTL), | ||
2448 | I915_READ(PRB0_HEAD), | ||
2449 | I915_READ(PRB0_TAIL), | ||
2450 | I915_READ(PRB0_START)); | ||
2451 | return -EIO; | ||
2452 | } | ||
2453 | |||
2454 | /* Update our cache of the ring state */ | ||
2455 | i915_kernel_lost_context(dev); | ||
2456 | |||
2457 | return 0; | ||
2458 | } | ||
2459 | |||
2460 | static void | ||
2461 | i915_gem_cleanup_ringbuffer(struct drm_device *dev) | ||
2462 | { | ||
2463 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
2464 | |||
2465 | if (dev_priv->ring.ring_obj == NULL) | ||
2466 | return; | ||
2467 | |||
2468 | drm_core_ioremapfree(&dev_priv->ring.map, dev); | ||
2469 | |||
2470 | i915_gem_object_unpin(dev_priv->ring.ring_obj); | ||
2471 | drm_gem_object_unreference(dev_priv->ring.ring_obj); | ||
2472 | dev_priv->ring.ring_obj = NULL; | ||
2473 | memset(&dev_priv->ring, 0, sizeof(dev_priv->ring)); | ||
2474 | |||
2475 | if (dev_priv->hws_obj != NULL) { | ||
2476 | struct drm_gem_object *obj = dev_priv->hws_obj; | ||
2477 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | ||
2478 | |||
2479 | kunmap(obj_priv->page_list[0]); | ||
2480 | i915_gem_object_unpin(obj); | ||
2481 | drm_gem_object_unreference(obj); | ||
2482 | dev_priv->hws_obj = NULL; | ||
2483 | memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map)); | ||
2484 | dev_priv->hw_status_page = NULL; | ||
2485 | |||
2486 | /* Write high address into HWS_PGA when disabling. */ | ||
2487 | I915_WRITE(HWS_PGA, 0x1ffff000); | ||
2488 | } | ||
2489 | } | ||
2490 | |||
2491 | int | ||
2492 | i915_gem_entervt_ioctl(struct drm_device *dev, void *data, | ||
2493 | struct drm_file *file_priv) | ||
2494 | { | ||
2495 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
2496 | int ret; | ||
2497 | |||
2498 | if (dev_priv->mm.wedged) { | ||
2499 | DRM_ERROR("Reenabling wedged hardware, good luck\n"); | ||
2500 | dev_priv->mm.wedged = 0; | ||
2501 | } | ||
2502 | |||
2503 | ret = i915_gem_init_ringbuffer(dev); | ||
2504 | if (ret != 0) | ||
2505 | return ret; | ||
2506 | |||
2507 | mutex_lock(&dev->struct_mutex); | ||
2508 | BUG_ON(!list_empty(&dev_priv->mm.active_list)); | ||
2509 | BUG_ON(!list_empty(&dev_priv->mm.flushing_list)); | ||
2510 | BUG_ON(!list_empty(&dev_priv->mm.inactive_list)); | ||
2511 | BUG_ON(!list_empty(&dev_priv->mm.request_list)); | ||
2512 | dev_priv->mm.suspended = 0; | ||
2513 | mutex_unlock(&dev->struct_mutex); | ||
2514 | |||
2515 | drm_irq_install(dev); | ||
2516 | |||
2517 | return 0; | ||
2518 | } | ||
2519 | |||
2520 | int | ||
2521 | i915_gem_leavevt_ioctl(struct drm_device *dev, void *data, | ||
2522 | struct drm_file *file_priv) | ||
2523 | { | ||
2524 | int ret; | ||
2525 | |||
2526 | ret = i915_gem_idle(dev); | ||
2527 | drm_irq_uninstall(dev); | ||
2528 | |||
2529 | return ret; | ||
2530 | } | ||
2531 | |||
2532 | void | ||
2533 | i915_gem_lastclose(struct drm_device *dev) | ||
2534 | { | ||
2535 | int ret; | ||
2536 | |||
2537 | ret = i915_gem_idle(dev); | ||
2538 | if (ret) | ||
2539 | DRM_ERROR("failed to idle hardware: %d\n", ret); | ||
2540 | } | ||
2541 | |||
2542 | void | ||
2543 | i915_gem_load(struct drm_device *dev) | ||
2544 | { | ||
2545 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
2546 | |||
2547 | INIT_LIST_HEAD(&dev_priv->mm.active_list); | ||
2548 | INIT_LIST_HEAD(&dev_priv->mm.flushing_list); | ||
2549 | INIT_LIST_HEAD(&dev_priv->mm.inactive_list); | ||
2550 | INIT_LIST_HEAD(&dev_priv->mm.request_list); | ||
2551 | INIT_DELAYED_WORK(&dev_priv->mm.retire_work, | ||
2552 | i915_gem_retire_work_handler); | ||
2553 | INIT_WORK(&dev_priv->mm.vblank_work, | ||
2554 | i915_gem_vblank_work_handler); | ||
2555 | dev_priv->mm.next_gem_seqno = 1; | ||
2556 | |||
2557 | i915_gem_detect_bit_6_swizzle(dev); | ||
2558 | } | ||
diff --git a/drivers/gpu/drm/i915/i915_gem_debug.c b/drivers/gpu/drm/i915/i915_gem_debug.c new file mode 100644 index 000000000000..131c088f8c8a --- /dev/null +++ b/drivers/gpu/drm/i915/i915_gem_debug.c | |||
@@ -0,0 +1,201 @@ | |||
1 | /* | ||
2 | * Copyright © 2008 Intel Corporation | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice (including the next | ||
12 | * paragraph) shall be included in all copies or substantial portions of the | ||
13 | * Software. | ||
14 | * | ||
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||
21 | * IN THE SOFTWARE. | ||
22 | * | ||
23 | * Authors: | ||
24 | * Keith Packard <keithp@keithp.com> | ||
25 | * | ||
26 | */ | ||
27 | |||
28 | #include "drmP.h" | ||
29 | #include "drm.h" | ||
30 | #include "i915_drm.h" | ||
31 | #include "i915_drv.h" | ||
32 | |||
33 | #if WATCH_INACTIVE | ||
34 | void | ||
35 | i915_verify_inactive(struct drm_device *dev, char *file, int line) | ||
36 | { | ||
37 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
38 | struct drm_gem_object *obj; | ||
39 | struct drm_i915_gem_object *obj_priv; | ||
40 | |||
41 | list_for_each_entry(obj_priv, &dev_priv->mm.inactive_list, list) { | ||
42 | obj = obj_priv->obj; | ||
43 | if (obj_priv->pin_count || obj_priv->active || | ||
44 | (obj->write_domain & ~(I915_GEM_DOMAIN_CPU | | ||
45 | I915_GEM_DOMAIN_GTT))) | ||
46 | DRM_ERROR("inactive %p (p %d a %d w %x) %s:%d\n", | ||
47 | obj, | ||
48 | obj_priv->pin_count, obj_priv->active, | ||
49 | obj->write_domain, file, line); | ||
50 | } | ||
51 | } | ||
52 | #endif /* WATCH_INACTIVE */ | ||
53 | |||
54 | |||
55 | #if WATCH_BUF | WATCH_EXEC | WATCH_PWRITE | ||
56 | static void | ||
57 | i915_gem_dump_page(struct page *page, uint32_t start, uint32_t end, | ||
58 | uint32_t bias, uint32_t mark) | ||
59 | { | ||
60 | uint32_t *mem = kmap_atomic(page, KM_USER0); | ||
61 | int i; | ||
62 | for (i = start; i < end; i += 4) | ||
63 | DRM_INFO("%08x: %08x%s\n", | ||
64 | (int) (bias + i), mem[i / 4], | ||
65 | (bias + i == mark) ? " ********" : ""); | ||
66 | kunmap_atomic(mem, KM_USER0); | ||
67 | /* give syslog time to catch up */ | ||
68 | msleep(1); | ||
69 | } | ||
70 | |||
71 | void | ||
72 | i915_gem_dump_object(struct drm_gem_object *obj, int len, | ||
73 | const char *where, uint32_t mark) | ||
74 | { | ||
75 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | ||
76 | int page; | ||
77 | |||
78 | DRM_INFO("%s: object at offset %08x\n", where, obj_priv->gtt_offset); | ||
79 | for (page = 0; page < (len + PAGE_SIZE-1) / PAGE_SIZE; page++) { | ||
80 | int page_len, chunk, chunk_len; | ||
81 | |||
82 | page_len = len - page * PAGE_SIZE; | ||
83 | if (page_len > PAGE_SIZE) | ||
84 | page_len = PAGE_SIZE; | ||
85 | |||
86 | for (chunk = 0; chunk < page_len; chunk += 128) { | ||
87 | chunk_len = page_len - chunk; | ||
88 | if (chunk_len > 128) | ||
89 | chunk_len = 128; | ||
90 | i915_gem_dump_page(obj_priv->page_list[page], | ||
91 | chunk, chunk + chunk_len, | ||
92 | obj_priv->gtt_offset + | ||
93 | page * PAGE_SIZE, | ||
94 | mark); | ||
95 | } | ||
96 | } | ||
97 | } | ||
98 | #endif | ||
99 | |||
100 | #if WATCH_LRU | ||
101 | void | ||
102 | i915_dump_lru(struct drm_device *dev, const char *where) | ||
103 | { | ||
104 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
105 | struct drm_i915_gem_object *obj_priv; | ||
106 | |||
107 | DRM_INFO("active list %s {\n", where); | ||
108 | list_for_each_entry(obj_priv, &dev_priv->mm.active_list, | ||
109 | list) | ||
110 | { | ||
111 | DRM_INFO(" %p: %08x\n", obj_priv, | ||
112 | obj_priv->last_rendering_seqno); | ||
113 | } | ||
114 | DRM_INFO("}\n"); | ||
115 | DRM_INFO("flushing list %s {\n", where); | ||
116 | list_for_each_entry(obj_priv, &dev_priv->mm.flushing_list, | ||
117 | list) | ||
118 | { | ||
119 | DRM_INFO(" %p: %08x\n", obj_priv, | ||
120 | obj_priv->last_rendering_seqno); | ||
121 | } | ||
122 | DRM_INFO("}\n"); | ||
123 | DRM_INFO("inactive %s {\n", where); | ||
124 | list_for_each_entry(obj_priv, &dev_priv->mm.inactive_list, list) { | ||
125 | DRM_INFO(" %p: %08x\n", obj_priv, | ||
126 | obj_priv->last_rendering_seqno); | ||
127 | } | ||
128 | DRM_INFO("}\n"); | ||
129 | } | ||
130 | #endif | ||
131 | |||
132 | |||
133 | #if WATCH_COHERENCY | ||
134 | void | ||
135 | i915_gem_object_check_coherency(struct drm_gem_object *obj, int handle) | ||
136 | { | ||
137 | struct drm_device *dev = obj->dev; | ||
138 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | ||
139 | int page; | ||
140 | uint32_t *gtt_mapping; | ||
141 | uint32_t *backing_map = NULL; | ||
142 | int bad_count = 0; | ||
143 | |||
144 | DRM_INFO("%s: checking coherency of object %p@0x%08x (%d, %dkb):\n", | ||
145 | __func__, obj, obj_priv->gtt_offset, handle, | ||
146 | obj->size / 1024); | ||
147 | |||
148 | gtt_mapping = ioremap(dev->agp->base + obj_priv->gtt_offset, | ||
149 | obj->size); | ||
150 | if (gtt_mapping == NULL) { | ||
151 | DRM_ERROR("failed to map GTT space\n"); | ||
152 | return; | ||
153 | } | ||
154 | |||
155 | for (page = 0; page < obj->size / PAGE_SIZE; page++) { | ||
156 | int i; | ||
157 | |||
158 | backing_map = kmap_atomic(obj_priv->page_list[page], KM_USER0); | ||
159 | |||
160 | if (backing_map == NULL) { | ||
161 | DRM_ERROR("failed to map backing page\n"); | ||
162 | goto out; | ||
163 | } | ||
164 | |||
165 | for (i = 0; i < PAGE_SIZE / 4; i++) { | ||
166 | uint32_t cpuval = backing_map[i]; | ||
167 | uint32_t gttval = readl(gtt_mapping + | ||
168 | page * 1024 + i); | ||
169 | |||
170 | if (cpuval != gttval) { | ||
171 | DRM_INFO("incoherent CPU vs GPU at 0x%08x: " | ||
172 | "0x%08x vs 0x%08x\n", | ||
173 | (int)(obj_priv->gtt_offset + | ||
174 | page * PAGE_SIZE + i * 4), | ||
175 | cpuval, gttval); | ||
176 | if (bad_count++ >= 8) { | ||
177 | DRM_INFO("...\n"); | ||
178 | goto out; | ||
179 | } | ||
180 | } | ||
181 | } | ||
182 | kunmap_atomic(backing_map, KM_USER0); | ||
183 | backing_map = NULL; | ||
184 | } | ||
185 | |||
186 | out: | ||
187 | if (backing_map != NULL) | ||
188 | kunmap_atomic(backing_map, KM_USER0); | ||
189 | iounmap(gtt_mapping); | ||
190 | |||
191 | /* give syslog time to catch up */ | ||
192 | msleep(1); | ||
193 | |||
194 | /* Directly flush the object, since we just loaded values with the CPU | ||
195 | * from the backing pages and we don't want to disturb the cache | ||
196 | * management that we're trying to observe. | ||
197 | */ | ||
198 | |||
199 | i915_gem_clflush_object(obj); | ||
200 | } | ||
201 | #endif | ||
diff --git a/drivers/gpu/drm/i915/i915_gem_proc.c b/drivers/gpu/drm/i915/i915_gem_proc.c new file mode 100644 index 000000000000..15d4160415b0 --- /dev/null +++ b/drivers/gpu/drm/i915/i915_gem_proc.c | |||
@@ -0,0 +1,292 @@ | |||
1 | /* | ||
2 | * Copyright © 2008 Intel Corporation | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice (including the next | ||
12 | * paragraph) shall be included in all copies or substantial portions of the | ||
13 | * Software. | ||
14 | * | ||
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||
21 | * IN THE SOFTWARE. | ||
22 | * | ||
23 | * Authors: | ||
24 | * Eric Anholt <eric@anholt.net> | ||
25 | * Keith Packard <keithp@keithp.com> | ||
26 | * | ||
27 | */ | ||
28 | |||
29 | #include "drmP.h" | ||
30 | #include "drm.h" | ||
31 | #include "i915_drm.h" | ||
32 | #include "i915_drv.h" | ||
33 | |||
34 | static int i915_gem_active_info(char *buf, char **start, off_t offset, | ||
35 | int request, int *eof, void *data) | ||
36 | { | ||
37 | struct drm_minor *minor = (struct drm_minor *) data; | ||
38 | struct drm_device *dev = minor->dev; | ||
39 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
40 | struct drm_i915_gem_object *obj_priv; | ||
41 | int len = 0; | ||
42 | |||
43 | if (offset > DRM_PROC_LIMIT) { | ||
44 | *eof = 1; | ||
45 | return 0; | ||
46 | } | ||
47 | |||
48 | *start = &buf[offset]; | ||
49 | *eof = 0; | ||
50 | DRM_PROC_PRINT("Active:\n"); | ||
51 | list_for_each_entry(obj_priv, &dev_priv->mm.active_list, | ||
52 | list) | ||
53 | { | ||
54 | struct drm_gem_object *obj = obj_priv->obj; | ||
55 | if (obj->name) { | ||
56 | DRM_PROC_PRINT(" %p(%d): %08x %08x %d\n", | ||
57 | obj, obj->name, | ||
58 | obj->read_domains, obj->write_domain, | ||
59 | obj_priv->last_rendering_seqno); | ||
60 | } else { | ||
61 | DRM_PROC_PRINT(" %p: %08x %08x %d\n", | ||
62 | obj, | ||
63 | obj->read_domains, obj->write_domain, | ||
64 | obj_priv->last_rendering_seqno); | ||
65 | } | ||
66 | } | ||
67 | if (len > request + offset) | ||
68 | return request; | ||
69 | *eof = 1; | ||
70 | return len - offset; | ||
71 | } | ||
72 | |||
73 | static int i915_gem_flushing_info(char *buf, char **start, off_t offset, | ||
74 | int request, int *eof, void *data) | ||
75 | { | ||
76 | struct drm_minor *minor = (struct drm_minor *) data; | ||
77 | struct drm_device *dev = minor->dev; | ||
78 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
79 | struct drm_i915_gem_object *obj_priv; | ||
80 | int len = 0; | ||
81 | |||
82 | if (offset > DRM_PROC_LIMIT) { | ||
83 | *eof = 1; | ||
84 | return 0; | ||
85 | } | ||
86 | |||
87 | *start = &buf[offset]; | ||
88 | *eof = 0; | ||
89 | DRM_PROC_PRINT("Flushing:\n"); | ||
90 | list_for_each_entry(obj_priv, &dev_priv->mm.flushing_list, | ||
91 | list) | ||
92 | { | ||
93 | struct drm_gem_object *obj = obj_priv->obj; | ||
94 | if (obj->name) { | ||
95 | DRM_PROC_PRINT(" %p(%d): %08x %08x %d\n", | ||
96 | obj, obj->name, | ||
97 | obj->read_domains, obj->write_domain, | ||
98 | obj_priv->last_rendering_seqno); | ||
99 | } else { | ||
100 | DRM_PROC_PRINT(" %p: %08x %08x %d\n", obj, | ||
101 | obj->read_domains, obj->write_domain, | ||
102 | obj_priv->last_rendering_seqno); | ||
103 | } | ||
104 | } | ||
105 | if (len > request + offset) | ||
106 | return request; | ||
107 | *eof = 1; | ||
108 | return len - offset; | ||
109 | } | ||
110 | |||
111 | static int i915_gem_inactive_info(char *buf, char **start, off_t offset, | ||
112 | int request, int *eof, void *data) | ||
113 | { | ||
114 | struct drm_minor *minor = (struct drm_minor *) data; | ||
115 | struct drm_device *dev = minor->dev; | ||
116 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
117 | struct drm_i915_gem_object *obj_priv; | ||
118 | int len = 0; | ||
119 | |||
120 | if (offset > DRM_PROC_LIMIT) { | ||
121 | *eof = 1; | ||
122 | return 0; | ||
123 | } | ||
124 | |||
125 | *start = &buf[offset]; | ||
126 | *eof = 0; | ||
127 | DRM_PROC_PRINT("Inactive:\n"); | ||
128 | list_for_each_entry(obj_priv, &dev_priv->mm.inactive_list, | ||
129 | list) | ||
130 | { | ||
131 | struct drm_gem_object *obj = obj_priv->obj; | ||
132 | if (obj->name) { | ||
133 | DRM_PROC_PRINT(" %p(%d): %08x %08x %d\n", | ||
134 | obj, obj->name, | ||
135 | obj->read_domains, obj->write_domain, | ||
136 | obj_priv->last_rendering_seqno); | ||
137 | } else { | ||
138 | DRM_PROC_PRINT(" %p: %08x %08x %d\n", obj, | ||
139 | obj->read_domains, obj->write_domain, | ||
140 | obj_priv->last_rendering_seqno); | ||
141 | } | ||
142 | } | ||
143 | if (len > request + offset) | ||
144 | return request; | ||
145 | *eof = 1; | ||
146 | return len - offset; | ||
147 | } | ||
148 | |||
149 | static int i915_gem_request_info(char *buf, char **start, off_t offset, | ||
150 | int request, int *eof, void *data) | ||
151 | { | ||
152 | struct drm_minor *minor = (struct drm_minor *) data; | ||
153 | struct drm_device *dev = minor->dev; | ||
154 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
155 | struct drm_i915_gem_request *gem_request; | ||
156 | int len = 0; | ||
157 | |||
158 | if (offset > DRM_PROC_LIMIT) { | ||
159 | *eof = 1; | ||
160 | return 0; | ||
161 | } | ||
162 | |||
163 | *start = &buf[offset]; | ||
164 | *eof = 0; | ||
165 | DRM_PROC_PRINT("Request:\n"); | ||
166 | list_for_each_entry(gem_request, &dev_priv->mm.request_list, | ||
167 | list) | ||
168 | { | ||
169 | DRM_PROC_PRINT(" %d @ %d %08x\n", | ||
170 | gem_request->seqno, | ||
171 | (int) (jiffies - gem_request->emitted_jiffies), | ||
172 | gem_request->flush_domains); | ||
173 | } | ||
174 | if (len > request + offset) | ||
175 | return request; | ||
176 | *eof = 1; | ||
177 | return len - offset; | ||
178 | } | ||
179 | |||
180 | static int i915_gem_seqno_info(char *buf, char **start, off_t offset, | ||
181 | int request, int *eof, void *data) | ||
182 | { | ||
183 | struct drm_minor *minor = (struct drm_minor *) data; | ||
184 | struct drm_device *dev = minor->dev; | ||
185 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
186 | int len = 0; | ||
187 | |||
188 | if (offset > DRM_PROC_LIMIT) { | ||
189 | *eof = 1; | ||
190 | return 0; | ||
191 | } | ||
192 | |||
193 | *start = &buf[offset]; | ||
194 | *eof = 0; | ||
195 | DRM_PROC_PRINT("Current sequence: %d\n", i915_get_gem_seqno(dev)); | ||
196 | DRM_PROC_PRINT("Waiter sequence: %d\n", | ||
197 | dev_priv->mm.waiting_gem_seqno); | ||
198 | DRM_PROC_PRINT("IRQ sequence: %d\n", dev_priv->mm.irq_gem_seqno); | ||
199 | if (len > request + offset) | ||
200 | return request; | ||
201 | *eof = 1; | ||
202 | return len - offset; | ||
203 | } | ||
204 | |||
205 | |||
206 | static int i915_interrupt_info(char *buf, char **start, off_t offset, | ||
207 | int request, int *eof, void *data) | ||
208 | { | ||
209 | struct drm_minor *minor = (struct drm_minor *) data; | ||
210 | struct drm_device *dev = minor->dev; | ||
211 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
212 | int len = 0; | ||
213 | |||
214 | if (offset > DRM_PROC_LIMIT) { | ||
215 | *eof = 1; | ||
216 | return 0; | ||
217 | } | ||
218 | |||
219 | *start = &buf[offset]; | ||
220 | *eof = 0; | ||
221 | DRM_PROC_PRINT("Interrupt enable: %08x\n", | ||
222 | I915_READ(IER)); | ||
223 | DRM_PROC_PRINT("Interrupt identity: %08x\n", | ||
224 | I915_READ(IIR)); | ||
225 | DRM_PROC_PRINT("Interrupt mask: %08x\n", | ||
226 | I915_READ(IMR)); | ||
227 | DRM_PROC_PRINT("Pipe A stat: %08x\n", | ||
228 | I915_READ(PIPEASTAT)); | ||
229 | DRM_PROC_PRINT("Pipe B stat: %08x\n", | ||
230 | I915_READ(PIPEBSTAT)); | ||
231 | DRM_PROC_PRINT("Interrupts received: %d\n", | ||
232 | atomic_read(&dev_priv->irq_received)); | ||
233 | DRM_PROC_PRINT("Current sequence: %d\n", | ||
234 | i915_get_gem_seqno(dev)); | ||
235 | DRM_PROC_PRINT("Waiter sequence: %d\n", | ||
236 | dev_priv->mm.waiting_gem_seqno); | ||
237 | DRM_PROC_PRINT("IRQ sequence: %d\n", | ||
238 | dev_priv->mm.irq_gem_seqno); | ||
239 | if (len > request + offset) | ||
240 | return request; | ||
241 | *eof = 1; | ||
242 | return len - offset; | ||
243 | } | ||
244 | |||
245 | static struct drm_proc_list { | ||
246 | /** file name */ | ||
247 | const char *name; | ||
248 | /** proc callback*/ | ||
249 | int (*f) (char *, char **, off_t, int, int *, void *); | ||
250 | } i915_gem_proc_list[] = { | ||
251 | {"i915_gem_active", i915_gem_active_info}, | ||
252 | {"i915_gem_flushing", i915_gem_flushing_info}, | ||
253 | {"i915_gem_inactive", i915_gem_inactive_info}, | ||
254 | {"i915_gem_request", i915_gem_request_info}, | ||
255 | {"i915_gem_seqno", i915_gem_seqno_info}, | ||
256 | {"i915_gem_interrupt", i915_interrupt_info}, | ||
257 | }; | ||
258 | |||
259 | #define I915_GEM_PROC_ENTRIES ARRAY_SIZE(i915_gem_proc_list) | ||
260 | |||
261 | int i915_gem_proc_init(struct drm_minor *minor) | ||
262 | { | ||
263 | struct proc_dir_entry *ent; | ||
264 | int i, j; | ||
265 | |||
266 | for (i = 0; i < I915_GEM_PROC_ENTRIES; i++) { | ||
267 | ent = create_proc_entry(i915_gem_proc_list[i].name, | ||
268 | S_IFREG | S_IRUGO, minor->dev_root); | ||
269 | if (!ent) { | ||
270 | DRM_ERROR("Cannot create /proc/dri/.../%s\n", | ||
271 | i915_gem_proc_list[i].name); | ||
272 | for (j = 0; j < i; j++) | ||
273 | remove_proc_entry(i915_gem_proc_list[i].name, | ||
274 | minor->dev_root); | ||
275 | return -1; | ||
276 | } | ||
277 | ent->read_proc = i915_gem_proc_list[i].f; | ||
278 | ent->data = minor; | ||
279 | } | ||
280 | return 0; | ||
281 | } | ||
282 | |||
283 | void i915_gem_proc_cleanup(struct drm_minor *minor) | ||
284 | { | ||
285 | int i; | ||
286 | |||
287 | if (!minor->dev_root) | ||
288 | return; | ||
289 | |||
290 | for (i = 0; i < I915_GEM_PROC_ENTRIES; i++) | ||
291 | remove_proc_entry(i915_gem_proc_list[i].name, minor->dev_root); | ||
292 | } | ||
diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c new file mode 100644 index 000000000000..e8b85ac4ca04 --- /dev/null +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c | |||
@@ -0,0 +1,257 @@ | |||
1 | /* | ||
2 | * Copyright © 2008 Intel Corporation | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice (including the next | ||
12 | * paragraph) shall be included in all copies or substantial portions of the | ||
13 | * Software. | ||
14 | * | ||
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||
21 | * IN THE SOFTWARE. | ||
22 | * | ||
23 | * Authors: | ||
24 | * Eric Anholt <eric@anholt.net> | ||
25 | * | ||
26 | */ | ||
27 | |||
28 | #include "drmP.h" | ||
29 | #include "drm.h" | ||
30 | #include "i915_drm.h" | ||
31 | #include "i915_drv.h" | ||
32 | |||
33 | /** @file i915_gem_tiling.c | ||
34 | * | ||
35 | * Support for managing tiling state of buffer objects. | ||
36 | * | ||
37 | * The idea behind tiling is to increase cache hit rates by rearranging | ||
38 | * pixel data so that a group of pixel accesses are in the same cacheline. | ||
39 | * Performance improvement from doing this on the back/depth buffer are on | ||
40 | * the order of 30%. | ||
41 | * | ||
42 | * Intel architectures make this somewhat more complicated, though, by | ||
43 | * adjustments made to addressing of data when the memory is in interleaved | ||
44 | * mode (matched pairs of DIMMS) to improve memory bandwidth. | ||
45 | * For interleaved memory, the CPU sends every sequential 64 bytes | ||
46 | * to an alternate memory channel so it can get the bandwidth from both. | ||
47 | * | ||
48 | * The GPU also rearranges its accesses for increased bandwidth to interleaved | ||
49 | * memory, and it matches what the CPU does for non-tiled. However, when tiled | ||
50 | * it does it a little differently, since one walks addresses not just in the | ||
51 | * X direction but also Y. So, along with alternating channels when bit | ||
52 | * 6 of the address flips, it also alternates when other bits flip -- Bits 9 | ||
53 | * (every 512 bytes, an X tile scanline) and 10 (every two X tile scanlines) | ||
54 | * are common to both the 915 and 965-class hardware. | ||
55 | * | ||
56 | * The CPU also sometimes XORs in higher bits as well, to improve | ||
57 | * bandwidth doing strided access like we do so frequently in graphics. This | ||
58 | * is called "Channel XOR Randomization" in the MCH documentation. The result | ||
59 | * is that the CPU is XORing in either bit 11 or bit 17 to bit 6 of its address | ||
60 | * decode. | ||
61 | * | ||
62 | * All of this bit 6 XORing has an effect on our memory management, | ||
63 | * as we need to make sure that the 3d driver can correctly address object | ||
64 | * contents. | ||
65 | * | ||
66 | * If we don't have interleaved memory, all tiling is safe and no swizzling is | ||
67 | * required. | ||
68 | * | ||
69 | * When bit 17 is XORed in, we simply refuse to tile at all. Bit | ||
70 | * 17 is not just a page offset, so as we page an objet out and back in, | ||
71 | * individual pages in it will have different bit 17 addresses, resulting in | ||
72 | * each 64 bytes being swapped with its neighbor! | ||
73 | * | ||
74 | * Otherwise, if interleaved, we have to tell the 3d driver what the address | ||
75 | * swizzling it needs to do is, since it's writing with the CPU to the pages | ||
76 | * (bit 6 and potentially bit 11 XORed in), and the GPU is reading from the | ||
77 | * pages (bit 6, 9, and 10 XORed in), resulting in a cumulative bit swizzling | ||
78 | * required by the CPU of XORing in bit 6, 9, 10, and potentially 11, in order | ||
79 | * to match what the GPU expects. | ||
80 | */ | ||
81 | |||
82 | /** | ||
83 | * Detects bit 6 swizzling of address lookup between IGD access and CPU | ||
84 | * access through main memory. | ||
85 | */ | ||
86 | void | ||
87 | i915_gem_detect_bit_6_swizzle(struct drm_device *dev) | ||
88 | { | ||
89 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
90 | uint32_t swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN; | ||
91 | uint32_t swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN; | ||
92 | |||
93 | if (!IS_I9XX(dev)) { | ||
94 | /* As far as we know, the 865 doesn't have these bit 6 | ||
95 | * swizzling issues. | ||
96 | */ | ||
97 | swizzle_x = I915_BIT_6_SWIZZLE_NONE; | ||
98 | swizzle_y = I915_BIT_6_SWIZZLE_NONE; | ||
99 | } else if ((!IS_I965G(dev) && !IS_G33(dev)) || IS_I965GM(dev) || | ||
100 | IS_GM45(dev)) { | ||
101 | uint32_t dcc; | ||
102 | |||
103 | /* On 915-945 and GM965, channel interleave by the CPU is | ||
104 | * determined by DCC. The CPU will alternate based on bit 6 | ||
105 | * in interleaved mode, and the GPU will then also alternate | ||
106 | * on bit 6, 9, and 10 for X, but the CPU may also optionally | ||
107 | * alternate based on bit 17 (XOR not disabled and XOR | ||
108 | * bit == 17). | ||
109 | */ | ||
110 | dcc = I915_READ(DCC); | ||
111 | switch (dcc & DCC_ADDRESSING_MODE_MASK) { | ||
112 | case DCC_ADDRESSING_MODE_SINGLE_CHANNEL: | ||
113 | case DCC_ADDRESSING_MODE_DUAL_CHANNEL_ASYMMETRIC: | ||
114 | swizzle_x = I915_BIT_6_SWIZZLE_NONE; | ||
115 | swizzle_y = I915_BIT_6_SWIZZLE_NONE; | ||
116 | break; | ||
117 | case DCC_ADDRESSING_MODE_DUAL_CHANNEL_INTERLEAVED: | ||
118 | if (IS_I915G(dev) || IS_I915GM(dev) || | ||
119 | dcc & DCC_CHANNEL_XOR_DISABLE) { | ||
120 | swizzle_x = I915_BIT_6_SWIZZLE_9_10; | ||
121 | swizzle_y = I915_BIT_6_SWIZZLE_9; | ||
122 | } else if (IS_I965GM(dev) || IS_GM45(dev)) { | ||
123 | /* GM965 only does bit 11-based channel | ||
124 | * randomization | ||
125 | */ | ||
126 | swizzle_x = I915_BIT_6_SWIZZLE_9_10_11; | ||
127 | swizzle_y = I915_BIT_6_SWIZZLE_9_11; | ||
128 | } else { | ||
129 | /* Bit 17 or perhaps other swizzling */ | ||
130 | swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN; | ||
131 | swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN; | ||
132 | } | ||
133 | break; | ||
134 | } | ||
135 | if (dcc == 0xffffffff) { | ||
136 | DRM_ERROR("Couldn't read from MCHBAR. " | ||
137 | "Disabling tiling.\n"); | ||
138 | swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN; | ||
139 | swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN; | ||
140 | } | ||
141 | } else { | ||
142 | /* The 965, G33, and newer, have a very flexible memory | ||
143 | * configuration. It will enable dual-channel mode | ||
144 | * (interleaving) on as much memory as it can, and the GPU | ||
145 | * will additionally sometimes enable different bit 6 | ||
146 | * swizzling for tiled objects from the CPU. | ||
147 | * | ||
148 | * Here's what I found on the G965: | ||
149 | * slot fill memory size swizzling | ||
150 | * 0A 0B 1A 1B 1-ch 2-ch | ||
151 | * 512 0 0 0 512 0 O | ||
152 | * 512 0 512 0 16 1008 X | ||
153 | * 512 0 0 512 16 1008 X | ||
154 | * 0 512 0 512 16 1008 X | ||
155 | * 1024 1024 1024 0 2048 1024 O | ||
156 | * | ||
157 | * We could probably detect this based on either the DRB | ||
158 | * matching, which was the case for the swizzling required in | ||
159 | * the table above, or from the 1-ch value being less than | ||
160 | * the minimum size of a rank. | ||
161 | */ | ||
162 | if (I915_READ16(C0DRB3) != I915_READ16(C1DRB3)) { | ||
163 | swizzle_x = I915_BIT_6_SWIZZLE_NONE; | ||
164 | swizzle_y = I915_BIT_6_SWIZZLE_NONE; | ||
165 | } else { | ||
166 | swizzle_x = I915_BIT_6_SWIZZLE_9_10; | ||
167 | swizzle_y = I915_BIT_6_SWIZZLE_9; | ||
168 | } | ||
169 | } | ||
170 | |||
171 | dev_priv->mm.bit_6_swizzle_x = swizzle_x; | ||
172 | dev_priv->mm.bit_6_swizzle_y = swizzle_y; | ||
173 | } | ||
174 | |||
175 | /** | ||
176 | * Sets the tiling mode of an object, returning the required swizzling of | ||
177 | * bit 6 of addresses in the object. | ||
178 | */ | ||
179 | int | ||
180 | i915_gem_set_tiling(struct drm_device *dev, void *data, | ||
181 | struct drm_file *file_priv) | ||
182 | { | ||
183 | struct drm_i915_gem_set_tiling *args = data; | ||
184 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
185 | struct drm_gem_object *obj; | ||
186 | struct drm_i915_gem_object *obj_priv; | ||
187 | |||
188 | obj = drm_gem_object_lookup(dev, file_priv, args->handle); | ||
189 | if (obj == NULL) | ||
190 | return -EINVAL; | ||
191 | obj_priv = obj->driver_private; | ||
192 | |||
193 | mutex_lock(&dev->struct_mutex); | ||
194 | |||
195 | if (args->tiling_mode == I915_TILING_NONE) { | ||
196 | obj_priv->tiling_mode = I915_TILING_NONE; | ||
197 | args->swizzle_mode = I915_BIT_6_SWIZZLE_NONE; | ||
198 | } else { | ||
199 | if (args->tiling_mode == I915_TILING_X) | ||
200 | args->swizzle_mode = dev_priv->mm.bit_6_swizzle_x; | ||
201 | else | ||
202 | args->swizzle_mode = dev_priv->mm.bit_6_swizzle_y; | ||
203 | /* If we can't handle the swizzling, make it untiled. */ | ||
204 | if (args->swizzle_mode == I915_BIT_6_SWIZZLE_UNKNOWN) { | ||
205 | args->tiling_mode = I915_TILING_NONE; | ||
206 | args->swizzle_mode = I915_BIT_6_SWIZZLE_NONE; | ||
207 | } | ||
208 | } | ||
209 | obj_priv->tiling_mode = args->tiling_mode; | ||
210 | |||
211 | mutex_unlock(&dev->struct_mutex); | ||
212 | |||
213 | drm_gem_object_unreference(obj); | ||
214 | |||
215 | return 0; | ||
216 | } | ||
217 | |||
218 | /** | ||
219 | * Returns the current tiling mode and required bit 6 swizzling for the object. | ||
220 | */ | ||
221 | int | ||
222 | i915_gem_get_tiling(struct drm_device *dev, void *data, | ||
223 | struct drm_file *file_priv) | ||
224 | { | ||
225 | struct drm_i915_gem_get_tiling *args = data; | ||
226 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
227 | struct drm_gem_object *obj; | ||
228 | struct drm_i915_gem_object *obj_priv; | ||
229 | |||
230 | obj = drm_gem_object_lookup(dev, file_priv, args->handle); | ||
231 | if (obj == NULL) | ||
232 | return -EINVAL; | ||
233 | obj_priv = obj->driver_private; | ||
234 | |||
235 | mutex_lock(&dev->struct_mutex); | ||
236 | |||
237 | args->tiling_mode = obj_priv->tiling_mode; | ||
238 | switch (obj_priv->tiling_mode) { | ||
239 | case I915_TILING_X: | ||
240 | args->swizzle_mode = dev_priv->mm.bit_6_swizzle_x; | ||
241 | break; | ||
242 | case I915_TILING_Y: | ||
243 | args->swizzle_mode = dev_priv->mm.bit_6_swizzle_y; | ||
244 | break; | ||
245 | case I915_TILING_NONE: | ||
246 | args->swizzle_mode = I915_BIT_6_SWIZZLE_NONE; | ||
247 | break; | ||
248 | default: | ||
249 | DRM_ERROR("unknown tiling mode\n"); | ||
250 | } | ||
251 | |||
252 | mutex_unlock(&dev->struct_mutex); | ||
253 | |||
254 | drm_gem_object_unreference(obj); | ||
255 | |||
256 | return 0; | ||
257 | } | ||
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index df036118b8b1..baae511c785b 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -31,12 +31,92 @@ | |||
31 | #include "i915_drm.h" | 31 | #include "i915_drm.h" |
32 | #include "i915_drv.h" | 32 | #include "i915_drv.h" |
33 | 33 | ||
34 | #define USER_INT_FLAG (1<<1) | ||
35 | #define VSYNC_PIPEB_FLAG (1<<5) | ||
36 | #define VSYNC_PIPEA_FLAG (1<<7) | ||
37 | |||
38 | #define MAX_NOPID ((u32)~0) | 34 | #define MAX_NOPID ((u32)~0) |
39 | 35 | ||
36 | /** These are the interrupts used by the driver */ | ||
37 | #define I915_INTERRUPT_ENABLE_MASK (I915_USER_INTERRUPT | \ | ||
38 | I915_ASLE_INTERRUPT | \ | ||
39 | I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | \ | ||
40 | I915_DISPLAY_PIPE_B_EVENT_INTERRUPT) | ||
41 | |||
42 | void | ||
43 | i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask) | ||
44 | { | ||
45 | if ((dev_priv->irq_mask_reg & mask) != 0) { | ||
46 | dev_priv->irq_mask_reg &= ~mask; | ||
47 | I915_WRITE(IMR, dev_priv->irq_mask_reg); | ||
48 | (void) I915_READ(IMR); | ||
49 | } | ||
50 | } | ||
51 | |||
52 | static inline void | ||
53 | i915_disable_irq(drm_i915_private_t *dev_priv, u32 mask) | ||
54 | { | ||
55 | if ((dev_priv->irq_mask_reg & mask) != mask) { | ||
56 | dev_priv->irq_mask_reg |= mask; | ||
57 | I915_WRITE(IMR, dev_priv->irq_mask_reg); | ||
58 | (void) I915_READ(IMR); | ||
59 | } | ||
60 | } | ||
61 | |||
62 | /** | ||
63 | * i915_get_pipe - return the the pipe associated with a given plane | ||
64 | * @dev: DRM device | ||
65 | * @plane: plane to look for | ||
66 | * | ||
67 | * The Intel Mesa & 2D drivers call the vblank routines with a plane number | ||
68 | * rather than a pipe number, since they may not always be equal. This routine | ||
69 | * maps the given @plane back to a pipe number. | ||
70 | */ | ||
71 | static int | ||
72 | i915_get_pipe(struct drm_device *dev, int plane) | ||
73 | { | ||
74 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | ||
75 | u32 dspcntr; | ||
76 | |||
77 | dspcntr = plane ? I915_READ(DSPBCNTR) : I915_READ(DSPACNTR); | ||
78 | |||
79 | return dspcntr & DISPPLANE_SEL_PIPE_MASK ? 1 : 0; | ||
80 | } | ||
81 | |||
82 | /** | ||
83 | * i915_get_plane - return the the plane associated with a given pipe | ||
84 | * @dev: DRM device | ||
85 | * @pipe: pipe to look for | ||
86 | * | ||
87 | * The Intel Mesa & 2D drivers call the vblank routines with a plane number | ||
88 | * rather than a plane number, since they may not always be equal. This routine | ||
89 | * maps the given @pipe back to a plane number. | ||
90 | */ | ||
91 | static int | ||
92 | i915_get_plane(struct drm_device *dev, int pipe) | ||
93 | { | ||
94 | if (i915_get_pipe(dev, 0) == pipe) | ||
95 | return 0; | ||
96 | return 1; | ||
97 | } | ||
98 | |||
99 | /** | ||
100 | * i915_pipe_enabled - check if a pipe is enabled | ||
101 | * @dev: DRM device | ||
102 | * @pipe: pipe to check | ||
103 | * | ||
104 | * Reading certain registers when the pipe is disabled can hang the chip. | ||
105 | * Use this routine to make sure the PLL is running and the pipe is active | ||
106 | * before reading such registers if unsure. | ||
107 | */ | ||
108 | static int | ||
109 | i915_pipe_enabled(struct drm_device *dev, int pipe) | ||
110 | { | ||
111 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | ||
112 | unsigned long pipeconf = pipe ? PIPEBCONF : PIPEACONF; | ||
113 | |||
114 | if (I915_READ(pipeconf) & PIPEACONF_ENABLE) | ||
115 | return 1; | ||
116 | |||
117 | return 0; | ||
118 | } | ||
119 | |||
40 | /** | 120 | /** |
41 | * Emit blits for scheduled buffer swaps. | 121 | * Emit blits for scheduled buffer swaps. |
42 | * | 122 | * |
@@ -48,8 +128,7 @@ static void i915_vblank_tasklet(struct drm_device *dev) | |||
48 | unsigned long irqflags; | 128 | unsigned long irqflags; |
49 | struct list_head *list, *tmp, hits, *hit; | 129 | struct list_head *list, *tmp, hits, *hit; |
50 | int nhits, nrects, slice[2], upper[2], lower[2], i; | 130 | int nhits, nrects, slice[2], upper[2], lower[2], i; |
51 | unsigned counter[2] = { atomic_read(&dev->vbl_received), | 131 | unsigned counter[2]; |
52 | atomic_read(&dev->vbl_received2) }; | ||
53 | struct drm_drawable_info *drw; | 132 | struct drm_drawable_info *drw; |
54 | drm_i915_sarea_t *sarea_priv = dev_priv->sarea_priv; | 133 | drm_i915_sarea_t *sarea_priv = dev_priv->sarea_priv; |
55 | u32 cpp = dev_priv->cpp; | 134 | u32 cpp = dev_priv->cpp; |
@@ -71,6 +150,9 @@ static void i915_vblank_tasklet(struct drm_device *dev) | |||
71 | src_pitch >>= 2; | 150 | src_pitch >>= 2; |
72 | } | 151 | } |
73 | 152 | ||
153 | counter[0] = drm_vblank_count(dev, 0); | ||
154 | counter[1] = drm_vblank_count(dev, 1); | ||
155 | |||
74 | DRM_DEBUG("\n"); | 156 | DRM_DEBUG("\n"); |
75 | 157 | ||
76 | INIT_LIST_HEAD(&hits); | 158 | INIT_LIST_HEAD(&hits); |
@@ -83,12 +165,14 @@ static void i915_vblank_tasklet(struct drm_device *dev) | |||
83 | list_for_each_safe(list, tmp, &dev_priv->vbl_swaps.head) { | 165 | list_for_each_safe(list, tmp, &dev_priv->vbl_swaps.head) { |
84 | drm_i915_vbl_swap_t *vbl_swap = | 166 | drm_i915_vbl_swap_t *vbl_swap = |
85 | list_entry(list, drm_i915_vbl_swap_t, head); | 167 | list_entry(list, drm_i915_vbl_swap_t, head); |
168 | int pipe = i915_get_pipe(dev, vbl_swap->plane); | ||
86 | 169 | ||
87 | if ((counter[vbl_swap->pipe] - vbl_swap->sequence) > (1<<23)) | 170 | if ((counter[pipe] - vbl_swap->sequence) > (1<<23)) |
88 | continue; | 171 | continue; |
89 | 172 | ||
90 | list_del(list); | 173 | list_del(list); |
91 | dev_priv->swaps_pending--; | 174 | dev_priv->swaps_pending--; |
175 | drm_vblank_put(dev, pipe); | ||
92 | 176 | ||
93 | spin_unlock(&dev_priv->swaps_lock); | 177 | spin_unlock(&dev_priv->swaps_lock); |
94 | spin_lock(&dev->drw_lock); | 178 | spin_lock(&dev->drw_lock); |
@@ -181,7 +265,7 @@ static void i915_vblank_tasklet(struct drm_device *dev) | |||
181 | drm_i915_vbl_swap_t *swap_hit = | 265 | drm_i915_vbl_swap_t *swap_hit = |
182 | list_entry(hit, drm_i915_vbl_swap_t, head); | 266 | list_entry(hit, drm_i915_vbl_swap_t, head); |
183 | struct drm_clip_rect *rect; | 267 | struct drm_clip_rect *rect; |
184 | int num_rects, pipe; | 268 | int num_rects, plane; |
185 | unsigned short top, bottom; | 269 | unsigned short top, bottom; |
186 | 270 | ||
187 | drw = drm_get_drawable_info(dev, swap_hit->drw_id); | 271 | drw = drm_get_drawable_info(dev, swap_hit->drw_id); |
@@ -190,9 +274,9 @@ static void i915_vblank_tasklet(struct drm_device *dev) | |||
190 | continue; | 274 | continue; |
191 | 275 | ||
192 | rect = drw->rects; | 276 | rect = drw->rects; |
193 | pipe = swap_hit->pipe; | 277 | plane = swap_hit->plane; |
194 | top = upper[pipe]; | 278 | top = upper[plane]; |
195 | bottom = lower[pipe]; | 279 | bottom = lower[plane]; |
196 | 280 | ||
197 | for (num_rects = drw->num_rects; num_rects--; rect++) { | 281 | for (num_rects = drw->num_rects; num_rects--; rect++) { |
198 | int y1 = max(rect->y1, top); | 282 | int y1 = max(rect->y1, top); |
@@ -229,61 +313,139 @@ static void i915_vblank_tasklet(struct drm_device *dev) | |||
229 | } | 313 | } |
230 | } | 314 | } |
231 | 315 | ||
316 | u32 i915_get_vblank_counter(struct drm_device *dev, int plane) | ||
317 | { | ||
318 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | ||
319 | unsigned long high_frame; | ||
320 | unsigned long low_frame; | ||
321 | u32 high1, high2, low, count; | ||
322 | int pipe; | ||
323 | |||
324 | pipe = i915_get_pipe(dev, plane); | ||
325 | high_frame = pipe ? PIPEBFRAMEHIGH : PIPEAFRAMEHIGH; | ||
326 | low_frame = pipe ? PIPEBFRAMEPIXEL : PIPEAFRAMEPIXEL; | ||
327 | |||
328 | if (!i915_pipe_enabled(dev, pipe)) { | ||
329 | DRM_ERROR("trying to get vblank count for disabled pipe %d\n", pipe); | ||
330 | return 0; | ||
331 | } | ||
332 | |||
333 | /* | ||
334 | * High & low register fields aren't synchronized, so make sure | ||
335 | * we get a low value that's stable across two reads of the high | ||
336 | * register. | ||
337 | */ | ||
338 | do { | ||
339 | high1 = ((I915_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >> | ||
340 | PIPE_FRAME_HIGH_SHIFT); | ||
341 | low = ((I915_READ(low_frame) & PIPE_FRAME_LOW_MASK) >> | ||
342 | PIPE_FRAME_LOW_SHIFT); | ||
343 | high2 = ((I915_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >> | ||
344 | PIPE_FRAME_HIGH_SHIFT); | ||
345 | } while (high1 != high2); | ||
346 | |||
347 | count = (high1 << 8) | low; | ||
348 | |||
349 | return count; | ||
350 | } | ||
351 | |||
352 | void | ||
353 | i915_gem_vblank_work_handler(struct work_struct *work) | ||
354 | { | ||
355 | drm_i915_private_t *dev_priv; | ||
356 | struct drm_device *dev; | ||
357 | |||
358 | dev_priv = container_of(work, drm_i915_private_t, | ||
359 | mm.vblank_work); | ||
360 | dev = dev_priv->dev; | ||
361 | |||
362 | mutex_lock(&dev->struct_mutex); | ||
363 | i915_vblank_tasklet(dev); | ||
364 | mutex_unlock(&dev->struct_mutex); | ||
365 | } | ||
366 | |||
232 | irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) | 367 | irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) |
233 | { | 368 | { |
234 | struct drm_device *dev = (struct drm_device *) arg; | 369 | struct drm_device *dev = (struct drm_device *) arg; |
235 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 370 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
236 | u16 temp; | 371 | u32 iir; |
237 | u32 pipea_stats, pipeb_stats; | 372 | u32 pipea_stats, pipeb_stats; |
373 | int vblank = 0; | ||
238 | 374 | ||
239 | pipea_stats = I915_READ(I915REG_PIPEASTAT); | 375 | atomic_inc(&dev_priv->irq_received); |
240 | pipeb_stats = I915_READ(I915REG_PIPEBSTAT); | ||
241 | 376 | ||
242 | temp = I915_READ16(I915REG_INT_IDENTITY_R); | 377 | if (dev->pdev->msi_enabled) |
378 | I915_WRITE(IMR, ~0); | ||
379 | iir = I915_READ(IIR); | ||
243 | 380 | ||
244 | temp &= (USER_INT_FLAG | VSYNC_PIPEA_FLAG | VSYNC_PIPEB_FLAG); | 381 | if (iir == 0) { |
382 | if (dev->pdev->msi_enabled) { | ||
383 | I915_WRITE(IMR, dev_priv->irq_mask_reg); | ||
384 | (void) I915_READ(IMR); | ||
385 | } | ||
386 | return IRQ_NONE; | ||
387 | } | ||
245 | 388 | ||
246 | DRM_DEBUG("%s flag=%08x\n", __FUNCTION__, temp); | 389 | /* |
390 | * Clear the PIPE(A|B)STAT regs before the IIR otherwise | ||
391 | * we may get extra interrupts. | ||
392 | */ | ||
393 | if (iir & I915_DISPLAY_PIPE_A_EVENT_INTERRUPT) { | ||
394 | pipea_stats = I915_READ(PIPEASTAT); | ||
395 | if (!(dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_A)) | ||
396 | pipea_stats &= ~(PIPE_START_VBLANK_INTERRUPT_ENABLE | | ||
397 | PIPE_VBLANK_INTERRUPT_ENABLE); | ||
398 | else if (pipea_stats & (PIPE_START_VBLANK_INTERRUPT_STATUS| | ||
399 | PIPE_VBLANK_INTERRUPT_STATUS)) { | ||
400 | vblank++; | ||
401 | drm_handle_vblank(dev, i915_get_plane(dev, 0)); | ||
402 | } | ||
247 | 403 | ||
248 | if (temp == 0) | 404 | I915_WRITE(PIPEASTAT, pipea_stats); |
249 | return IRQ_NONE; | 405 | } |
406 | if (iir & I915_DISPLAY_PIPE_B_EVENT_INTERRUPT) { | ||
407 | pipeb_stats = I915_READ(PIPEBSTAT); | ||
408 | /* Ack the event */ | ||
409 | I915_WRITE(PIPEBSTAT, pipeb_stats); | ||
410 | |||
411 | /* The vblank interrupt gets enabled even if we didn't ask for | ||
412 | it, so make sure it's shut down again */ | ||
413 | if (!(dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_B)) | ||
414 | pipeb_stats &= ~(PIPE_START_VBLANK_INTERRUPT_ENABLE | | ||
415 | PIPE_VBLANK_INTERRUPT_ENABLE); | ||
416 | else if (pipeb_stats & (PIPE_START_VBLANK_INTERRUPT_STATUS| | ||
417 | PIPE_VBLANK_INTERRUPT_STATUS)) { | ||
418 | vblank++; | ||
419 | drm_handle_vblank(dev, i915_get_plane(dev, 1)); | ||
420 | } | ||
250 | 421 | ||
251 | I915_WRITE16(I915REG_INT_IDENTITY_R, temp); | 422 | if (pipeb_stats & I915_LEGACY_BLC_EVENT_STATUS) |
252 | (void) I915_READ16(I915REG_INT_IDENTITY_R); | 423 | opregion_asle_intr(dev); |
253 | DRM_READMEMORYBARRIER(); | 424 | I915_WRITE(PIPEBSTAT, pipeb_stats); |
425 | } | ||
426 | |||
427 | I915_WRITE(IIR, iir); | ||
428 | if (dev->pdev->msi_enabled) | ||
429 | I915_WRITE(IMR, dev_priv->irq_mask_reg); | ||
430 | (void) I915_READ(IIR); /* Flush posted writes */ | ||
254 | 431 | ||
255 | dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); | 432 | if (dev_priv->sarea_priv) |
433 | dev_priv->sarea_priv->last_dispatch = | ||
434 | READ_BREADCRUMB(dev_priv); | ||
256 | 435 | ||
257 | if (temp & USER_INT_FLAG) | 436 | if (iir & I915_USER_INTERRUPT) { |
437 | dev_priv->mm.irq_gem_seqno = i915_get_gem_seqno(dev); | ||
258 | DRM_WAKEUP(&dev_priv->irq_queue); | 438 | DRM_WAKEUP(&dev_priv->irq_queue); |
439 | } | ||
259 | 440 | ||
260 | if (temp & (VSYNC_PIPEA_FLAG | VSYNC_PIPEB_FLAG)) { | 441 | if (iir & I915_ASLE_INTERRUPT) |
261 | int vblank_pipe = dev_priv->vblank_pipe; | 442 | opregion_asle_intr(dev); |
262 | 443 | ||
263 | if ((vblank_pipe & | 444 | if (vblank && dev_priv->swaps_pending > 0) { |
264 | (DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B)) | 445 | if (dev_priv->ring.ring_obj == NULL) |
265 | == (DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B)) { | ||
266 | if (temp & VSYNC_PIPEA_FLAG) | ||
267 | atomic_inc(&dev->vbl_received); | ||
268 | if (temp & VSYNC_PIPEB_FLAG) | ||
269 | atomic_inc(&dev->vbl_received2); | ||
270 | } else if (((temp & VSYNC_PIPEA_FLAG) && | ||
271 | (vblank_pipe & DRM_I915_VBLANK_PIPE_A)) || | ||
272 | ((temp & VSYNC_PIPEB_FLAG) && | ||
273 | (vblank_pipe & DRM_I915_VBLANK_PIPE_B))) | ||
274 | atomic_inc(&dev->vbl_received); | ||
275 | |||
276 | DRM_WAKEUP(&dev->vbl_queue); | ||
277 | drm_vbl_send_signals(dev); | ||
278 | |||
279 | if (dev_priv->swaps_pending > 0) | ||
280 | drm_locked_tasklet(dev, i915_vblank_tasklet); | 446 | drm_locked_tasklet(dev, i915_vblank_tasklet); |
281 | I915_WRITE(I915REG_PIPEASTAT, | 447 | else |
282 | pipea_stats|I915_VBLANK_INTERRUPT_ENABLE| | 448 | schedule_work(&dev_priv->mm.vblank_work); |
283 | I915_VBLANK_CLEAR); | ||
284 | I915_WRITE(I915REG_PIPEBSTAT, | ||
285 | pipeb_stats|I915_VBLANK_INTERRUPT_ENABLE| | ||
286 | I915_VBLANK_CLEAR); | ||
287 | } | 449 | } |
288 | 450 | ||
289 | return IRQ_HANDLED; | 451 | return IRQ_HANDLED; |
@@ -298,23 +460,45 @@ static int i915_emit_irq(struct drm_device * dev) | |||
298 | 460 | ||
299 | DRM_DEBUG("\n"); | 461 | DRM_DEBUG("\n"); |
300 | 462 | ||
301 | dev_priv->sarea_priv->last_enqueue = ++dev_priv->counter; | 463 | dev_priv->counter++; |
302 | |||
303 | if (dev_priv->counter > 0x7FFFFFFFUL) | 464 | if (dev_priv->counter > 0x7FFFFFFFUL) |
304 | dev_priv->sarea_priv->last_enqueue = dev_priv->counter = 1; | 465 | dev_priv->counter = 1; |
466 | if (dev_priv->sarea_priv) | ||
467 | dev_priv->sarea_priv->last_enqueue = dev_priv->counter; | ||
305 | 468 | ||
306 | BEGIN_LP_RING(6); | 469 | BEGIN_LP_RING(6); |
307 | OUT_RING(CMD_STORE_DWORD_IDX); | 470 | OUT_RING(MI_STORE_DWORD_INDEX); |
308 | OUT_RING(20); | 471 | OUT_RING(5 << MI_STORE_DWORD_INDEX_SHIFT); |
309 | OUT_RING(dev_priv->counter); | 472 | OUT_RING(dev_priv->counter); |
310 | OUT_RING(0); | 473 | OUT_RING(0); |
311 | OUT_RING(0); | 474 | OUT_RING(0); |
312 | OUT_RING(GFX_OP_USER_INTERRUPT); | 475 | OUT_RING(MI_USER_INTERRUPT); |
313 | ADVANCE_LP_RING(); | 476 | ADVANCE_LP_RING(); |
314 | 477 | ||
315 | return dev_priv->counter; | 478 | return dev_priv->counter; |
316 | } | 479 | } |
317 | 480 | ||
481 | void i915_user_irq_get(struct drm_device *dev) | ||
482 | { | ||
483 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | ||
484 | |||
485 | spin_lock(&dev_priv->user_irq_lock); | ||
486 | if (dev->irq_enabled && (++dev_priv->user_irq_refcount == 1)) | ||
487 | i915_enable_irq(dev_priv, I915_USER_INTERRUPT); | ||
488 | spin_unlock(&dev_priv->user_irq_lock); | ||
489 | } | ||
490 | |||
491 | void i915_user_irq_put(struct drm_device *dev) | ||
492 | { | ||
493 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | ||
494 | |||
495 | spin_lock(&dev_priv->user_irq_lock); | ||
496 | BUG_ON(dev->irq_enabled && dev_priv->user_irq_refcount <= 0); | ||
497 | if (dev->irq_enabled && (--dev_priv->user_irq_refcount == 0)) | ||
498 | i915_disable_irq(dev_priv, I915_USER_INTERRUPT); | ||
499 | spin_unlock(&dev_priv->user_irq_lock); | ||
500 | } | ||
501 | |||
318 | static int i915_wait_irq(struct drm_device * dev, int irq_nr) | 502 | static int i915_wait_irq(struct drm_device * dev, int irq_nr) |
319 | { | 503 | { |
320 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 504 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
@@ -323,55 +507,34 @@ static int i915_wait_irq(struct drm_device * dev, int irq_nr) | |||
323 | DRM_DEBUG("irq_nr=%d breadcrumb=%d\n", irq_nr, | 507 | DRM_DEBUG("irq_nr=%d breadcrumb=%d\n", irq_nr, |
324 | READ_BREADCRUMB(dev_priv)); | 508 | READ_BREADCRUMB(dev_priv)); |
325 | 509 | ||
326 | if (READ_BREADCRUMB(dev_priv) >= irq_nr) | 510 | if (READ_BREADCRUMB(dev_priv) >= irq_nr) { |
511 | if (dev_priv->sarea_priv) { | ||
512 | dev_priv->sarea_priv->last_dispatch = | ||
513 | READ_BREADCRUMB(dev_priv); | ||
514 | } | ||
327 | return 0; | 515 | return 0; |
516 | } | ||
328 | 517 | ||
329 | dev_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT; | 518 | if (dev_priv->sarea_priv) |
519 | dev_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT; | ||
330 | 520 | ||
521 | i915_user_irq_get(dev); | ||
331 | DRM_WAIT_ON(ret, dev_priv->irq_queue, 3 * DRM_HZ, | 522 | DRM_WAIT_ON(ret, dev_priv->irq_queue, 3 * DRM_HZ, |
332 | READ_BREADCRUMB(dev_priv) >= irq_nr); | 523 | READ_BREADCRUMB(dev_priv) >= irq_nr); |
524 | i915_user_irq_put(dev); | ||
333 | 525 | ||
334 | if (ret == -EBUSY) { | 526 | if (ret == -EBUSY) { |
335 | DRM_ERROR("EBUSY -- rec: %d emitted: %d\n", | 527 | DRM_ERROR("EBUSY -- rec: %d emitted: %d\n", |
336 | READ_BREADCRUMB(dev_priv), (int)dev_priv->counter); | 528 | READ_BREADCRUMB(dev_priv), (int)dev_priv->counter); |
337 | } | 529 | } |
338 | 530 | ||
339 | dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); | 531 | if (dev_priv->sarea_priv) |
340 | return ret; | 532 | dev_priv->sarea_priv->last_dispatch = |
341 | } | 533 | READ_BREADCRUMB(dev_priv); |
342 | |||
343 | static int i915_driver_vblank_do_wait(struct drm_device *dev, unsigned int *sequence, | ||
344 | atomic_t *counter) | ||
345 | { | ||
346 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
347 | unsigned int cur_vblank; | ||
348 | int ret = 0; | ||
349 | |||
350 | if (!dev_priv) { | ||
351 | DRM_ERROR("called with no initialization\n"); | ||
352 | return -EINVAL; | ||
353 | } | ||
354 | |||
355 | DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ, | ||
356 | (((cur_vblank = atomic_read(counter)) | ||
357 | - *sequence) <= (1<<23))); | ||
358 | |||
359 | *sequence = cur_vblank; | ||
360 | 534 | ||
361 | return ret; | 535 | return ret; |
362 | } | 536 | } |
363 | 537 | ||
364 | |||
365 | int i915_driver_vblank_wait(struct drm_device *dev, unsigned int *sequence) | ||
366 | { | ||
367 | return i915_driver_vblank_do_wait(dev, sequence, &dev->vbl_received); | ||
368 | } | ||
369 | |||
370 | int i915_driver_vblank_wait2(struct drm_device *dev, unsigned int *sequence) | ||
371 | { | ||
372 | return i915_driver_vblank_do_wait(dev, sequence, &dev->vbl_received2); | ||
373 | } | ||
374 | |||
375 | /* Needs the lock as it touches the ring. | 538 | /* Needs the lock as it touches the ring. |
376 | */ | 539 | */ |
377 | int i915_irq_emit(struct drm_device *dev, void *data, | 540 | int i915_irq_emit(struct drm_device *dev, void *data, |
@@ -381,14 +544,15 @@ int i915_irq_emit(struct drm_device *dev, void *data, | |||
381 | drm_i915_irq_emit_t *emit = data; | 544 | drm_i915_irq_emit_t *emit = data; |
382 | int result; | 545 | int result; |
383 | 546 | ||
384 | LOCK_TEST_WITH_RETURN(dev, file_priv); | 547 | RING_LOCK_TEST_WITH_RETURN(dev, file_priv); |
385 | 548 | ||
386 | if (!dev_priv) { | 549 | if (!dev_priv) { |
387 | DRM_ERROR("called with no initialization\n"); | 550 | DRM_ERROR("called with no initialization\n"); |
388 | return -EINVAL; | 551 | return -EINVAL; |
389 | } | 552 | } |
390 | 553 | mutex_lock(&dev->struct_mutex); | |
391 | result = i915_emit_irq(dev); | 554 | result = i915_emit_irq(dev); |
555 | mutex_unlock(&dev->struct_mutex); | ||
392 | 556 | ||
393 | if (DRM_COPY_TO_USER(emit->irq_seq, &result, sizeof(int))) { | 557 | if (DRM_COPY_TO_USER(emit->irq_seq, &result, sizeof(int))) { |
394 | DRM_ERROR("copy_to_user\n"); | 558 | DRM_ERROR("copy_to_user\n"); |
@@ -414,18 +578,74 @@ int i915_irq_wait(struct drm_device *dev, void *data, | |||
414 | return i915_wait_irq(dev, irqwait->irq_seq); | 578 | return i915_wait_irq(dev, irqwait->irq_seq); |
415 | } | 579 | } |
416 | 580 | ||
417 | static void i915_enable_interrupt (struct drm_device *dev) | 581 | int i915_enable_vblank(struct drm_device *dev, int plane) |
418 | { | 582 | { |
419 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 583 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
420 | u16 flag; | 584 | int pipe = i915_get_pipe(dev, plane); |
585 | u32 pipestat_reg = 0; | ||
586 | u32 pipestat; | ||
587 | |||
588 | switch (pipe) { | ||
589 | case 0: | ||
590 | pipestat_reg = PIPEASTAT; | ||
591 | i915_enable_irq(dev_priv, I915_DISPLAY_PIPE_A_EVENT_INTERRUPT); | ||
592 | break; | ||
593 | case 1: | ||
594 | pipestat_reg = PIPEBSTAT; | ||
595 | i915_enable_irq(dev_priv, I915_DISPLAY_PIPE_B_EVENT_INTERRUPT); | ||
596 | break; | ||
597 | default: | ||
598 | DRM_ERROR("tried to enable vblank on non-existent pipe %d\n", | ||
599 | pipe); | ||
600 | break; | ||
601 | } | ||
602 | |||
603 | if (pipestat_reg) { | ||
604 | pipestat = I915_READ(pipestat_reg); | ||
605 | if (IS_I965G(dev)) | ||
606 | pipestat |= PIPE_START_VBLANK_INTERRUPT_ENABLE; | ||
607 | else | ||
608 | pipestat |= PIPE_VBLANK_INTERRUPT_ENABLE; | ||
609 | /* Clear any stale interrupt status */ | ||
610 | pipestat |= (PIPE_START_VBLANK_INTERRUPT_STATUS | | ||
611 | PIPE_VBLANK_INTERRUPT_STATUS); | ||
612 | I915_WRITE(pipestat_reg, pipestat); | ||
613 | } | ||
614 | |||
615 | return 0; | ||
616 | } | ||
421 | 617 | ||
422 | flag = 0; | 618 | void i915_disable_vblank(struct drm_device *dev, int plane) |
423 | if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_A) | 619 | { |
424 | flag |= VSYNC_PIPEA_FLAG; | 620 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
425 | if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_B) | 621 | int pipe = i915_get_pipe(dev, plane); |
426 | flag |= VSYNC_PIPEB_FLAG; | 622 | u32 pipestat_reg = 0; |
623 | u32 pipestat; | ||
624 | |||
625 | switch (pipe) { | ||
626 | case 0: | ||
627 | pipestat_reg = PIPEASTAT; | ||
628 | i915_disable_irq(dev_priv, I915_DISPLAY_PIPE_A_EVENT_INTERRUPT); | ||
629 | break; | ||
630 | case 1: | ||
631 | pipestat_reg = PIPEBSTAT; | ||
632 | i915_disable_irq(dev_priv, I915_DISPLAY_PIPE_B_EVENT_INTERRUPT); | ||
633 | break; | ||
634 | default: | ||
635 | DRM_ERROR("tried to disable vblank on non-existent pipe %d\n", | ||
636 | pipe); | ||
637 | break; | ||
638 | } | ||
427 | 639 | ||
428 | I915_WRITE16(I915REG_INT_ENABLE_R, USER_INT_FLAG | flag); | 640 | if (pipestat_reg) { |
641 | pipestat = I915_READ(pipestat_reg); | ||
642 | pipestat &= ~(PIPE_START_VBLANK_INTERRUPT_ENABLE | | ||
643 | PIPE_VBLANK_INTERRUPT_ENABLE); | ||
644 | /* Clear any stale interrupt status */ | ||
645 | pipestat |= (PIPE_START_VBLANK_INTERRUPT_STATUS | | ||
646 | PIPE_VBLANK_INTERRUPT_STATUS); | ||
647 | I915_WRITE(pipestat_reg, pipestat); | ||
648 | } | ||
429 | } | 649 | } |
430 | 650 | ||
431 | /* Set the vblank monitor pipe | 651 | /* Set the vblank monitor pipe |
@@ -434,22 +654,12 @@ int i915_vblank_pipe_set(struct drm_device *dev, void *data, | |||
434 | struct drm_file *file_priv) | 654 | struct drm_file *file_priv) |
435 | { | 655 | { |
436 | drm_i915_private_t *dev_priv = dev->dev_private; | 656 | drm_i915_private_t *dev_priv = dev->dev_private; |
437 | drm_i915_vblank_pipe_t *pipe = data; | ||
438 | 657 | ||
439 | if (!dev_priv) { | 658 | if (!dev_priv) { |
440 | DRM_ERROR("called with no initialization\n"); | 659 | DRM_ERROR("called with no initialization\n"); |
441 | return -EINVAL; | 660 | return -EINVAL; |
442 | } | 661 | } |
443 | 662 | ||
444 | if (pipe->pipe & ~(DRM_I915_VBLANK_PIPE_A|DRM_I915_VBLANK_PIPE_B)) { | ||
445 | DRM_ERROR("called with invalid pipe 0x%x\n", pipe->pipe); | ||
446 | return -EINVAL; | ||
447 | } | ||
448 | |||
449 | dev_priv->vblank_pipe = pipe->pipe; | ||
450 | |||
451 | i915_enable_interrupt (dev); | ||
452 | |||
453 | return 0; | 663 | return 0; |
454 | } | 664 | } |
455 | 665 | ||
@@ -458,19 +668,13 @@ int i915_vblank_pipe_get(struct drm_device *dev, void *data, | |||
458 | { | 668 | { |
459 | drm_i915_private_t *dev_priv = dev->dev_private; | 669 | drm_i915_private_t *dev_priv = dev->dev_private; |
460 | drm_i915_vblank_pipe_t *pipe = data; | 670 | drm_i915_vblank_pipe_t *pipe = data; |
461 | u16 flag; | ||
462 | 671 | ||
463 | if (!dev_priv) { | 672 | if (!dev_priv) { |
464 | DRM_ERROR("called with no initialization\n"); | 673 | DRM_ERROR("called with no initialization\n"); |
465 | return -EINVAL; | 674 | return -EINVAL; |
466 | } | 675 | } |
467 | 676 | ||
468 | flag = I915_READ(I915REG_INT_ENABLE_R); | 677 | pipe->pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B; |
469 | pipe->pipe = 0; | ||
470 | if (flag & VSYNC_PIPEA_FLAG) | ||
471 | pipe->pipe |= DRM_I915_VBLANK_PIPE_A; | ||
472 | if (flag & VSYNC_PIPEB_FLAG) | ||
473 | pipe->pipe |= DRM_I915_VBLANK_PIPE_B; | ||
474 | 678 | ||
475 | return 0; | 679 | return 0; |
476 | } | 680 | } |
@@ -484,11 +688,12 @@ int i915_vblank_swap(struct drm_device *dev, void *data, | |||
484 | drm_i915_private_t *dev_priv = dev->dev_private; | 688 | drm_i915_private_t *dev_priv = dev->dev_private; |
485 | drm_i915_vblank_swap_t *swap = data; | 689 | drm_i915_vblank_swap_t *swap = data; |
486 | drm_i915_vbl_swap_t *vbl_swap; | 690 | drm_i915_vbl_swap_t *vbl_swap; |
487 | unsigned int pipe, seqtype, curseq; | 691 | unsigned int pipe, seqtype, curseq, plane; |
488 | unsigned long irqflags; | 692 | unsigned long irqflags; |
489 | struct list_head *list; | 693 | struct list_head *list; |
694 | int ret; | ||
490 | 695 | ||
491 | if (!dev_priv) { | 696 | if (!dev_priv || !dev_priv->sarea_priv) { |
492 | DRM_ERROR("%s called with no initialization\n", __func__); | 697 | DRM_ERROR("%s called with no initialization\n", __func__); |
493 | return -EINVAL; | 698 | return -EINVAL; |
494 | } | 699 | } |
@@ -504,7 +709,8 @@ int i915_vblank_swap(struct drm_device *dev, void *data, | |||
504 | return -EINVAL; | 709 | return -EINVAL; |
505 | } | 710 | } |
506 | 711 | ||
507 | pipe = (swap->seqtype & _DRM_VBLANK_SECONDARY) ? 1 : 0; | 712 | plane = (swap->seqtype & _DRM_VBLANK_SECONDARY) ? 1 : 0; |
713 | pipe = i915_get_pipe(dev, plane); | ||
508 | 714 | ||
509 | seqtype = swap->seqtype & (_DRM_VBLANK_RELATIVE | _DRM_VBLANK_ABSOLUTE); | 715 | seqtype = swap->seqtype & (_DRM_VBLANK_RELATIVE | _DRM_VBLANK_ABSOLUTE); |
510 | 716 | ||
@@ -523,7 +729,14 @@ int i915_vblank_swap(struct drm_device *dev, void *data, | |||
523 | 729 | ||
524 | spin_unlock_irqrestore(&dev->drw_lock, irqflags); | 730 | spin_unlock_irqrestore(&dev->drw_lock, irqflags); |
525 | 731 | ||
526 | curseq = atomic_read(pipe ? &dev->vbl_received2 : &dev->vbl_received); | 732 | /* |
733 | * We take the ref here and put it when the swap actually completes | ||
734 | * in the tasklet. | ||
735 | */ | ||
736 | ret = drm_vblank_get(dev, pipe); | ||
737 | if (ret) | ||
738 | return ret; | ||
739 | curseq = drm_vblank_count(dev, pipe); | ||
527 | 740 | ||
528 | if (seqtype == _DRM_VBLANK_RELATIVE) | 741 | if (seqtype == _DRM_VBLANK_RELATIVE) |
529 | swap->sequence += curseq; | 742 | swap->sequence += curseq; |
@@ -533,6 +746,7 @@ int i915_vblank_swap(struct drm_device *dev, void *data, | |||
533 | swap->sequence = curseq + 1; | 746 | swap->sequence = curseq + 1; |
534 | } else { | 747 | } else { |
535 | DRM_DEBUG("Missed target sequence\n"); | 748 | DRM_DEBUG("Missed target sequence\n"); |
749 | drm_vblank_put(dev, pipe); | ||
536 | return -EINVAL; | 750 | return -EINVAL; |
537 | } | 751 | } |
538 | } | 752 | } |
@@ -543,7 +757,7 @@ int i915_vblank_swap(struct drm_device *dev, void *data, | |||
543 | vbl_swap = list_entry(list, drm_i915_vbl_swap_t, head); | 757 | vbl_swap = list_entry(list, drm_i915_vbl_swap_t, head); |
544 | 758 | ||
545 | if (vbl_swap->drw_id == swap->drawable && | 759 | if (vbl_swap->drw_id == swap->drawable && |
546 | vbl_swap->pipe == pipe && | 760 | vbl_swap->plane == plane && |
547 | vbl_swap->sequence == swap->sequence) { | 761 | vbl_swap->sequence == swap->sequence) { |
548 | spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags); | 762 | spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags); |
549 | DRM_DEBUG("Already scheduled\n"); | 763 | DRM_DEBUG("Already scheduled\n"); |
@@ -555,6 +769,7 @@ int i915_vblank_swap(struct drm_device *dev, void *data, | |||
555 | 769 | ||
556 | if (dev_priv->swaps_pending >= 100) { | 770 | if (dev_priv->swaps_pending >= 100) { |
557 | DRM_DEBUG("Too many swaps queued\n"); | 771 | DRM_DEBUG("Too many swaps queued\n"); |
772 | drm_vblank_put(dev, pipe); | ||
558 | return -EBUSY; | 773 | return -EBUSY; |
559 | } | 774 | } |
560 | 775 | ||
@@ -562,13 +777,14 @@ int i915_vblank_swap(struct drm_device *dev, void *data, | |||
562 | 777 | ||
563 | if (!vbl_swap) { | 778 | if (!vbl_swap) { |
564 | DRM_ERROR("Failed to allocate memory to queue swap\n"); | 779 | DRM_ERROR("Failed to allocate memory to queue swap\n"); |
780 | drm_vblank_put(dev, pipe); | ||
565 | return -ENOMEM; | 781 | return -ENOMEM; |
566 | } | 782 | } |
567 | 783 | ||
568 | DRM_DEBUG("\n"); | 784 | DRM_DEBUG("\n"); |
569 | 785 | ||
570 | vbl_swap->drw_id = swap->drawable; | 786 | vbl_swap->drw_id = swap->drawable; |
571 | vbl_swap->pipe = pipe; | 787 | vbl_swap->plane = plane; |
572 | vbl_swap->sequence = swap->sequence; | 788 | vbl_swap->sequence = swap->sequence; |
573 | 789 | ||
574 | spin_lock_irqsave(&dev_priv->swaps_lock, irqflags); | 790 | spin_lock_irqsave(&dev_priv->swaps_lock, irqflags); |
@@ -587,37 +803,63 @@ void i915_driver_irq_preinstall(struct drm_device * dev) | |||
587 | { | 803 | { |
588 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 804 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
589 | 805 | ||
590 | I915_WRITE16(I915REG_HWSTAM, 0xfffe); | 806 | I915_WRITE(HWSTAM, 0xeffe); |
591 | I915_WRITE16(I915REG_INT_MASK_R, 0x0); | 807 | I915_WRITE(IMR, 0xffffffff); |
592 | I915_WRITE16(I915REG_INT_ENABLE_R, 0x0); | 808 | I915_WRITE(IER, 0x0); |
593 | } | 809 | } |
594 | 810 | ||
595 | void i915_driver_irq_postinstall(struct drm_device * dev) | 811 | int i915_driver_irq_postinstall(struct drm_device *dev) |
596 | { | 812 | { |
597 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 813 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
814 | int ret, num_pipes = 2; | ||
598 | 815 | ||
599 | spin_lock_init(&dev_priv->swaps_lock); | 816 | spin_lock_init(&dev_priv->swaps_lock); |
600 | INIT_LIST_HEAD(&dev_priv->vbl_swaps.head); | 817 | INIT_LIST_HEAD(&dev_priv->vbl_swaps.head); |
601 | dev_priv->swaps_pending = 0; | 818 | dev_priv->swaps_pending = 0; |
602 | 819 | ||
603 | if (!dev_priv->vblank_pipe) | 820 | /* Set initial unmasked IRQs to just the selected vblank pipes. */ |
604 | dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A; | 821 | dev_priv->irq_mask_reg = ~0; |
605 | i915_enable_interrupt(dev); | 822 | |
823 | ret = drm_vblank_init(dev, num_pipes); | ||
824 | if (ret) | ||
825 | return ret; | ||
826 | |||
827 | dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B; | ||
828 | dev_priv->irq_mask_reg &= ~I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT; | ||
829 | dev_priv->irq_mask_reg &= ~I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT; | ||
830 | |||
831 | dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ | ||
832 | |||
833 | dev_priv->irq_mask_reg &= I915_INTERRUPT_ENABLE_MASK; | ||
834 | |||
835 | I915_WRITE(IMR, dev_priv->irq_mask_reg); | ||
836 | I915_WRITE(IER, I915_INTERRUPT_ENABLE_MASK); | ||
837 | (void) I915_READ(IER); | ||
838 | |||
839 | opregion_enable_asle(dev); | ||
606 | DRM_INIT_WAITQUEUE(&dev_priv->irq_queue); | 840 | DRM_INIT_WAITQUEUE(&dev_priv->irq_queue); |
841 | |||
842 | return 0; | ||
607 | } | 843 | } |
608 | 844 | ||
609 | void i915_driver_irq_uninstall(struct drm_device * dev) | 845 | void i915_driver_irq_uninstall(struct drm_device * dev) |
610 | { | 846 | { |
611 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 847 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
612 | u16 temp; | 848 | u32 temp; |
613 | 849 | ||
614 | if (!dev_priv) | 850 | if (!dev_priv) |
615 | return; | 851 | return; |
616 | 852 | ||
617 | I915_WRITE16(I915REG_HWSTAM, 0xffff); | 853 | dev_priv->vblank_pipe = 0; |
618 | I915_WRITE16(I915REG_INT_MASK_R, 0xffff); | 854 | |
619 | I915_WRITE16(I915REG_INT_ENABLE_R, 0x0); | 855 | I915_WRITE(HWSTAM, 0xffffffff); |
856 | I915_WRITE(IMR, 0xffffffff); | ||
857 | I915_WRITE(IER, 0x0); | ||
620 | 858 | ||
621 | temp = I915_READ16(I915REG_INT_IDENTITY_R); | 859 | temp = I915_READ(PIPEASTAT); |
622 | I915_WRITE16(I915REG_INT_IDENTITY_R, temp); | 860 | I915_WRITE(PIPEASTAT, temp); |
861 | temp = I915_READ(PIPEBSTAT); | ||
862 | I915_WRITE(PIPEBSTAT, temp); | ||
863 | temp = I915_READ(IIR); | ||
864 | I915_WRITE(IIR, temp); | ||
623 | } | 865 | } |
diff --git a/drivers/gpu/drm/i915/i915_opregion.c b/drivers/gpu/drm/i915/i915_opregion.c new file mode 100644 index 000000000000..1787a0c7e3ab --- /dev/null +++ b/drivers/gpu/drm/i915/i915_opregion.c | |||
@@ -0,0 +1,371 @@ | |||
1 | /* | ||
2 | * Copyright 2008 Intel Corporation <hong.liu@intel.com> | ||
3 | * Copyright 2008 Red Hat <mjg@redhat.com> | ||
4 | * | ||
5 | * Permission is hereby granted, free of charge, to any person obtaining | ||
6 | * a copy of this software and associated documentation files (the | ||
7 | * "Software"), to deal in the Software without restriction, including | ||
8 | * without limitation the rights to use, copy, modify, merge, publish, | ||
9 | * distribute, sub license, and/or sell copies of the Software, and to | ||
10 | * permit persons to whom the Software is furnished to do so, subject to | ||
11 | * the following conditions: | ||
12 | * | ||
13 | * The above copyright notice and this permission notice (including the | ||
14 | * next paragraph) shall be included in all copies or substantial | ||
15 | * portions of the Software. | ||
16 | * | ||
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
18 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
20 | * NON-INFRINGEMENT. IN NO EVENT SHALL INTEL AND/OR ITS SUPPLIERS BE | ||
21 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
22 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
23 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
24 | * SOFTWARE. | ||
25 | * | ||
26 | */ | ||
27 | |||
28 | #include <linux/acpi.h> | ||
29 | |||
30 | #include "drmP.h" | ||
31 | #include "i915_drm.h" | ||
32 | #include "i915_drv.h" | ||
33 | |||
34 | #define PCI_ASLE 0xe4 | ||
35 | #define PCI_LBPC 0xf4 | ||
36 | #define PCI_ASLS 0xfc | ||
37 | |||
38 | #define OPREGION_SZ (8*1024) | ||
39 | #define OPREGION_HEADER_OFFSET 0 | ||
40 | #define OPREGION_ACPI_OFFSET 0x100 | ||
41 | #define OPREGION_SWSCI_OFFSET 0x200 | ||
42 | #define OPREGION_ASLE_OFFSET 0x300 | ||
43 | #define OPREGION_VBT_OFFSET 0x1000 | ||
44 | |||
45 | #define OPREGION_SIGNATURE "IntelGraphicsMem" | ||
46 | #define MBOX_ACPI (1<<0) | ||
47 | #define MBOX_SWSCI (1<<1) | ||
48 | #define MBOX_ASLE (1<<2) | ||
49 | |||
50 | struct opregion_header { | ||
51 | u8 signature[16]; | ||
52 | u32 size; | ||
53 | u32 opregion_ver; | ||
54 | u8 bios_ver[32]; | ||
55 | u8 vbios_ver[16]; | ||
56 | u8 driver_ver[16]; | ||
57 | u32 mboxes; | ||
58 | u8 reserved[164]; | ||
59 | } __attribute__((packed)); | ||
60 | |||
61 | /* OpRegion mailbox #1: public ACPI methods */ | ||
62 | struct opregion_acpi { | ||
63 | u32 drdy; /* driver readiness */ | ||
64 | u32 csts; /* notification status */ | ||
65 | u32 cevt; /* current event */ | ||
66 | u8 rsvd1[20]; | ||
67 | u32 didl[8]; /* supported display devices ID list */ | ||
68 | u32 cpdl[8]; /* currently presented display list */ | ||
69 | u32 cadl[8]; /* currently active display list */ | ||
70 | u32 nadl[8]; /* next active devices list */ | ||
71 | u32 aslp; /* ASL sleep time-out */ | ||
72 | u32 tidx; /* toggle table index */ | ||
73 | u32 chpd; /* current hotplug enable indicator */ | ||
74 | u32 clid; /* current lid state*/ | ||
75 | u32 cdck; /* current docking state */ | ||
76 | u32 sxsw; /* Sx state resume */ | ||
77 | u32 evts; /* ASL supported events */ | ||
78 | u32 cnot; /* current OS notification */ | ||
79 | u32 nrdy; /* driver status */ | ||
80 | u8 rsvd2[60]; | ||
81 | } __attribute__((packed)); | ||
82 | |||
83 | /* OpRegion mailbox #2: SWSCI */ | ||
84 | struct opregion_swsci { | ||
85 | u32 scic; /* SWSCI command|status|data */ | ||
86 | u32 parm; /* command parameters */ | ||
87 | u32 dslp; /* driver sleep time-out */ | ||
88 | u8 rsvd[244]; | ||
89 | } __attribute__((packed)); | ||
90 | |||
91 | /* OpRegion mailbox #3: ASLE */ | ||
92 | struct opregion_asle { | ||
93 | u32 ardy; /* driver readiness */ | ||
94 | u32 aslc; /* ASLE interrupt command */ | ||
95 | u32 tche; /* technology enabled indicator */ | ||
96 | u32 alsi; /* current ALS illuminance reading */ | ||
97 | u32 bclp; /* backlight brightness to set */ | ||
98 | u32 pfit; /* panel fitting state */ | ||
99 | u32 cblv; /* current brightness level */ | ||
100 | u16 bclm[20]; /* backlight level duty cycle mapping table */ | ||
101 | u32 cpfm; /* current panel fitting mode */ | ||
102 | u32 epfm; /* enabled panel fitting modes */ | ||
103 | u8 plut[74]; /* panel LUT and identifier */ | ||
104 | u32 pfmb; /* PWM freq and min brightness */ | ||
105 | u8 rsvd[102]; | ||
106 | } __attribute__((packed)); | ||
107 | |||
108 | /* ASLE irq request bits */ | ||
109 | #define ASLE_SET_ALS_ILLUM (1 << 0) | ||
110 | #define ASLE_SET_BACKLIGHT (1 << 1) | ||
111 | #define ASLE_SET_PFIT (1 << 2) | ||
112 | #define ASLE_SET_PWM_FREQ (1 << 3) | ||
113 | #define ASLE_REQ_MSK 0xf | ||
114 | |||
115 | /* response bits of ASLE irq request */ | ||
116 | #define ASLE_ALS_ILLUM_FAIL (2<<10) | ||
117 | #define ASLE_BACKLIGHT_FAIL (2<<12) | ||
118 | #define ASLE_PFIT_FAIL (2<<14) | ||
119 | #define ASLE_PWM_FREQ_FAIL (2<<16) | ||
120 | |||
121 | /* ASLE backlight brightness to set */ | ||
122 | #define ASLE_BCLP_VALID (1<<31) | ||
123 | #define ASLE_BCLP_MSK (~(1<<31)) | ||
124 | |||
125 | /* ASLE panel fitting request */ | ||
126 | #define ASLE_PFIT_VALID (1<<31) | ||
127 | #define ASLE_PFIT_CENTER (1<<0) | ||
128 | #define ASLE_PFIT_STRETCH_TEXT (1<<1) | ||
129 | #define ASLE_PFIT_STRETCH_GFX (1<<2) | ||
130 | |||
131 | /* PWM frequency and minimum brightness */ | ||
132 | #define ASLE_PFMB_BRIGHTNESS_MASK (0xff) | ||
133 | #define ASLE_PFMB_BRIGHTNESS_VALID (1<<8) | ||
134 | #define ASLE_PFMB_PWM_MASK (0x7ffffe00) | ||
135 | #define ASLE_PFMB_PWM_VALID (1<<31) | ||
136 | |||
137 | #define ASLE_CBLV_VALID (1<<31) | ||
138 | |||
139 | static u32 asle_set_backlight(struct drm_device *dev, u32 bclp) | ||
140 | { | ||
141 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
142 | struct opregion_asle *asle = dev_priv->opregion.asle; | ||
143 | u32 blc_pwm_ctl, blc_pwm_ctl2; | ||
144 | |||
145 | if (!(bclp & ASLE_BCLP_VALID)) | ||
146 | return ASLE_BACKLIGHT_FAIL; | ||
147 | |||
148 | bclp &= ASLE_BCLP_MSK; | ||
149 | if (bclp < 0 || bclp > 255) | ||
150 | return ASLE_BACKLIGHT_FAIL; | ||
151 | |||
152 | blc_pwm_ctl = I915_READ(BLC_PWM_CTL); | ||
153 | blc_pwm_ctl &= ~BACKLIGHT_DUTY_CYCLE_MASK; | ||
154 | blc_pwm_ctl2 = I915_READ(BLC_PWM_CTL2); | ||
155 | |||
156 | if (blc_pwm_ctl2 & BLM_COMBINATION_MODE) | ||
157 | pci_write_config_dword(dev->pdev, PCI_LBPC, bclp); | ||
158 | else | ||
159 | I915_WRITE(BLC_PWM_CTL, blc_pwm_ctl | ((bclp * 0x101)-1)); | ||
160 | |||
161 | asle->cblv = (bclp*0x64)/0xff | ASLE_CBLV_VALID; | ||
162 | |||
163 | return 0; | ||
164 | } | ||
165 | |||
166 | static u32 asle_set_als_illum(struct drm_device *dev, u32 alsi) | ||
167 | { | ||
168 | /* alsi is the current ALS reading in lux. 0 indicates below sensor | ||
169 | range, 0xffff indicates above sensor range. 1-0xfffe are valid */ | ||
170 | return 0; | ||
171 | } | ||
172 | |||
173 | static u32 asle_set_pwm_freq(struct drm_device *dev, u32 pfmb) | ||
174 | { | ||
175 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
176 | if (pfmb & ASLE_PFMB_PWM_VALID) { | ||
177 | u32 blc_pwm_ctl = I915_READ(BLC_PWM_CTL); | ||
178 | u32 pwm = pfmb & ASLE_PFMB_PWM_MASK; | ||
179 | blc_pwm_ctl &= BACKLIGHT_DUTY_CYCLE_MASK; | ||
180 | pwm = pwm >> 9; | ||
181 | /* FIXME - what do we do with the PWM? */ | ||
182 | } | ||
183 | return 0; | ||
184 | } | ||
185 | |||
186 | static u32 asle_set_pfit(struct drm_device *dev, u32 pfit) | ||
187 | { | ||
188 | /* Panel fitting is currently controlled by the X code, so this is a | ||
189 | noop until modesetting support works fully */ | ||
190 | if (!(pfit & ASLE_PFIT_VALID)) | ||
191 | return ASLE_PFIT_FAIL; | ||
192 | return 0; | ||
193 | } | ||
194 | |||
195 | void opregion_asle_intr(struct drm_device *dev) | ||
196 | { | ||
197 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
198 | struct opregion_asle *asle = dev_priv->opregion.asle; | ||
199 | u32 asle_stat = 0; | ||
200 | u32 asle_req; | ||
201 | |||
202 | if (!asle) | ||
203 | return; | ||
204 | |||
205 | asle_req = asle->aslc & ASLE_REQ_MSK; | ||
206 | |||
207 | if (!asle_req) { | ||
208 | DRM_DEBUG("non asle set request??\n"); | ||
209 | return; | ||
210 | } | ||
211 | |||
212 | if (asle_req & ASLE_SET_ALS_ILLUM) | ||
213 | asle_stat |= asle_set_als_illum(dev, asle->alsi); | ||
214 | |||
215 | if (asle_req & ASLE_SET_BACKLIGHT) | ||
216 | asle_stat |= asle_set_backlight(dev, asle->bclp); | ||
217 | |||
218 | if (asle_req & ASLE_SET_PFIT) | ||
219 | asle_stat |= asle_set_pfit(dev, asle->pfit); | ||
220 | |||
221 | if (asle_req & ASLE_SET_PWM_FREQ) | ||
222 | asle_stat |= asle_set_pwm_freq(dev, asle->pfmb); | ||
223 | |||
224 | asle->aslc = asle_stat; | ||
225 | } | ||
226 | |||
227 | #define ASLE_ALS_EN (1<<0) | ||
228 | #define ASLE_BLC_EN (1<<1) | ||
229 | #define ASLE_PFIT_EN (1<<2) | ||
230 | #define ASLE_PFMB_EN (1<<3) | ||
231 | |||
232 | void opregion_enable_asle(struct drm_device *dev) | ||
233 | { | ||
234 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
235 | struct opregion_asle *asle = dev_priv->opregion.asle; | ||
236 | |||
237 | if (asle) { | ||
238 | u32 pipeb_stats = I915_READ(PIPEBSTAT); | ||
239 | if (IS_MOBILE(dev)) { | ||
240 | /* Many devices trigger events with a write to the | ||
241 | legacy backlight controller, so we need to ensure | ||
242 | that it's able to generate interrupts */ | ||
243 | I915_WRITE(PIPEBSTAT, pipeb_stats |= | ||
244 | I915_LEGACY_BLC_EVENT_ENABLE); | ||
245 | i915_enable_irq(dev_priv, I915_ASLE_INTERRUPT | | ||
246 | I915_DISPLAY_PIPE_B_EVENT_INTERRUPT); | ||
247 | } else | ||
248 | i915_enable_irq(dev_priv, I915_ASLE_INTERRUPT); | ||
249 | |||
250 | asle->tche = ASLE_ALS_EN | ASLE_BLC_EN | ASLE_PFIT_EN | | ||
251 | ASLE_PFMB_EN; | ||
252 | asle->ardy = 1; | ||
253 | } | ||
254 | } | ||
255 | |||
256 | #define ACPI_EV_DISPLAY_SWITCH (1<<0) | ||
257 | #define ACPI_EV_LID (1<<1) | ||
258 | #define ACPI_EV_DOCK (1<<2) | ||
259 | |||
260 | static struct intel_opregion *system_opregion; | ||
261 | |||
262 | int intel_opregion_video_event(struct notifier_block *nb, unsigned long val, | ||
263 | void *data) | ||
264 | { | ||
265 | /* The only video events relevant to opregion are 0x80. These indicate | ||
266 | either a docking event, lid switch or display switch request. In | ||
267 | Linux, these are handled by the dock, button and video drivers. | ||
268 | We might want to fix the video driver to be opregion-aware in | ||
269 | future, but right now we just indicate to the firmware that the | ||
270 | request has been handled */ | ||
271 | |||
272 | struct opregion_acpi *acpi; | ||
273 | |||
274 | if (!system_opregion) | ||
275 | return NOTIFY_DONE; | ||
276 | |||
277 | acpi = system_opregion->acpi; | ||
278 | acpi->csts = 0; | ||
279 | |||
280 | return NOTIFY_OK; | ||
281 | } | ||
282 | |||
283 | static struct notifier_block intel_opregion_notifier = { | ||
284 | .notifier_call = intel_opregion_video_event, | ||
285 | }; | ||
286 | |||
287 | int intel_opregion_init(struct drm_device *dev) | ||
288 | { | ||
289 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
290 | struct intel_opregion *opregion = &dev_priv->opregion; | ||
291 | void *base; | ||
292 | u32 asls, mboxes; | ||
293 | int err = 0; | ||
294 | |||
295 | pci_read_config_dword(dev->pdev, PCI_ASLS, &asls); | ||
296 | DRM_DEBUG("graphic opregion physical addr: 0x%x\n", asls); | ||
297 | if (asls == 0) { | ||
298 | DRM_DEBUG("ACPI OpRegion not supported!\n"); | ||
299 | return -ENOTSUPP; | ||
300 | } | ||
301 | |||
302 | base = ioremap(asls, OPREGION_SZ); | ||
303 | if (!base) | ||
304 | return -ENOMEM; | ||
305 | |||
306 | opregion->header = base; | ||
307 | if (memcmp(opregion->header->signature, OPREGION_SIGNATURE, 16)) { | ||
308 | DRM_DEBUG("opregion signature mismatch\n"); | ||
309 | err = -EINVAL; | ||
310 | goto err_out; | ||
311 | } | ||
312 | |||
313 | mboxes = opregion->header->mboxes; | ||
314 | if (mboxes & MBOX_ACPI) { | ||
315 | DRM_DEBUG("Public ACPI methods supported\n"); | ||
316 | opregion->acpi = base + OPREGION_ACPI_OFFSET; | ||
317 | } else { | ||
318 | DRM_DEBUG("Public ACPI methods not supported\n"); | ||
319 | err = -ENOTSUPP; | ||
320 | goto err_out; | ||
321 | } | ||
322 | opregion->enabled = 1; | ||
323 | |||
324 | if (mboxes & MBOX_SWSCI) { | ||
325 | DRM_DEBUG("SWSCI supported\n"); | ||
326 | opregion->swsci = base + OPREGION_SWSCI_OFFSET; | ||
327 | } | ||
328 | if (mboxes & MBOX_ASLE) { | ||
329 | DRM_DEBUG("ASLE supported\n"); | ||
330 | opregion->asle = base + OPREGION_ASLE_OFFSET; | ||
331 | } | ||
332 | |||
333 | /* Notify BIOS we are ready to handle ACPI video ext notifs. | ||
334 | * Right now, all the events are handled by the ACPI video module. | ||
335 | * We don't actually need to do anything with them. */ | ||
336 | opregion->acpi->csts = 0; | ||
337 | opregion->acpi->drdy = 1; | ||
338 | |||
339 | system_opregion = opregion; | ||
340 | register_acpi_notifier(&intel_opregion_notifier); | ||
341 | |||
342 | return 0; | ||
343 | |||
344 | err_out: | ||
345 | iounmap(opregion->header); | ||
346 | opregion->header = NULL; | ||
347 | return err; | ||
348 | } | ||
349 | |||
350 | void intel_opregion_free(struct drm_device *dev) | ||
351 | { | ||
352 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
353 | struct intel_opregion *opregion = &dev_priv->opregion; | ||
354 | |||
355 | if (!opregion->enabled) | ||
356 | return; | ||
357 | |||
358 | opregion->acpi->drdy = 0; | ||
359 | |||
360 | system_opregion = NULL; | ||
361 | unregister_acpi_notifier(&intel_opregion_notifier); | ||
362 | |||
363 | /* just clear all opregion memory pointers now */ | ||
364 | iounmap(opregion->header); | ||
365 | opregion->header = NULL; | ||
366 | opregion->acpi = NULL; | ||
367 | opregion->swsci = NULL; | ||
368 | opregion->asle = NULL; | ||
369 | |||
370 | opregion->enabled = 0; | ||
371 | } | ||
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h new file mode 100644 index 000000000000..5c2d9f206d05 --- /dev/null +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -0,0 +1,1417 @@ | |||
1 | /* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. | ||
2 | * All Rights Reserved. | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the | ||
6 | * "Software"), to deal in the Software without restriction, including | ||
7 | * without limitation the rights to use, copy, modify, merge, publish, | ||
8 | * distribute, sub license, and/or sell copies of the Software, and to | ||
9 | * permit persons to whom the Software is furnished to do so, subject to | ||
10 | * the following conditions: | ||
11 | * | ||
12 | * The above copyright notice and this permission notice (including the | ||
13 | * next paragraph) shall be included in all copies or substantial portions | ||
14 | * of the Software. | ||
15 | * | ||
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | ||
17 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
18 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. | ||
19 | * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR | ||
20 | * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, | ||
21 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | ||
22 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
23 | */ | ||
24 | |||
25 | #ifndef _I915_REG_H_ | ||
26 | #define _I915_REG_H_ | ||
27 | |||
28 | /* | ||
29 | * The Bridge device's PCI config space has information about the | ||
30 | * fb aperture size and the amount of pre-reserved memory. | ||
31 | */ | ||
32 | #define INTEL_GMCH_CTRL 0x52 | ||
33 | #define INTEL_GMCH_ENABLED 0x4 | ||
34 | #define INTEL_GMCH_MEM_MASK 0x1 | ||
35 | #define INTEL_GMCH_MEM_64M 0x1 | ||
36 | #define INTEL_GMCH_MEM_128M 0 | ||
37 | |||
38 | #define INTEL_855_GMCH_GMS_MASK (0x7 << 4) | ||
39 | #define INTEL_855_GMCH_GMS_DISABLED (0x0 << 4) | ||
40 | #define INTEL_855_GMCH_GMS_STOLEN_1M (0x1 << 4) | ||
41 | #define INTEL_855_GMCH_GMS_STOLEN_4M (0x2 << 4) | ||
42 | #define INTEL_855_GMCH_GMS_STOLEN_8M (0x3 << 4) | ||
43 | #define INTEL_855_GMCH_GMS_STOLEN_16M (0x4 << 4) | ||
44 | #define INTEL_855_GMCH_GMS_STOLEN_32M (0x5 << 4) | ||
45 | |||
46 | #define INTEL_915G_GMCH_GMS_STOLEN_48M (0x6 << 4) | ||
47 | #define INTEL_915G_GMCH_GMS_STOLEN_64M (0x7 << 4) | ||
48 | |||
49 | /* PCI config space */ | ||
50 | |||
51 | #define HPLLCC 0xc0 /* 855 only */ | ||
52 | #define GC_CLOCK_CONTROL_MASK (3 << 0) | ||
53 | #define GC_CLOCK_133_200 (0 << 0) | ||
54 | #define GC_CLOCK_100_200 (1 << 0) | ||
55 | #define GC_CLOCK_100_133 (2 << 0) | ||
56 | #define GC_CLOCK_166_250 (3 << 0) | ||
57 | #define GCFGC 0xf0 /* 915+ only */ | ||
58 | #define GC_LOW_FREQUENCY_ENABLE (1 << 7) | ||
59 | #define GC_DISPLAY_CLOCK_190_200_MHZ (0 << 4) | ||
60 | #define GC_DISPLAY_CLOCK_333_MHZ (4 << 4) | ||
61 | #define GC_DISPLAY_CLOCK_MASK (7 << 4) | ||
62 | #define LBB 0xf4 | ||
63 | |||
64 | /* VGA stuff */ | ||
65 | |||
66 | #define VGA_ST01_MDA 0x3ba | ||
67 | #define VGA_ST01_CGA 0x3da | ||
68 | |||
69 | #define VGA_MSR_WRITE 0x3c2 | ||
70 | #define VGA_MSR_READ 0x3cc | ||
71 | #define VGA_MSR_MEM_EN (1<<1) | ||
72 | #define VGA_MSR_CGA_MODE (1<<0) | ||
73 | |||
74 | #define VGA_SR_INDEX 0x3c4 | ||
75 | #define VGA_SR_DATA 0x3c5 | ||
76 | |||
77 | #define VGA_AR_INDEX 0x3c0 | ||
78 | #define VGA_AR_VID_EN (1<<5) | ||
79 | #define VGA_AR_DATA_WRITE 0x3c0 | ||
80 | #define VGA_AR_DATA_READ 0x3c1 | ||
81 | |||
82 | #define VGA_GR_INDEX 0x3ce | ||
83 | #define VGA_GR_DATA 0x3cf | ||
84 | /* GR05 */ | ||
85 | #define VGA_GR_MEM_READ_MODE_SHIFT 3 | ||
86 | #define VGA_GR_MEM_READ_MODE_PLANE 1 | ||
87 | /* GR06 */ | ||
88 | #define VGA_GR_MEM_MODE_MASK 0xc | ||
89 | #define VGA_GR_MEM_MODE_SHIFT 2 | ||
90 | #define VGA_GR_MEM_A0000_AFFFF 0 | ||
91 | #define VGA_GR_MEM_A0000_BFFFF 1 | ||
92 | #define VGA_GR_MEM_B0000_B7FFF 2 | ||
93 | #define VGA_GR_MEM_B0000_BFFFF 3 | ||
94 | |||
95 | #define VGA_DACMASK 0x3c6 | ||
96 | #define VGA_DACRX 0x3c7 | ||
97 | #define VGA_DACWX 0x3c8 | ||
98 | #define VGA_DACDATA 0x3c9 | ||
99 | |||
100 | #define VGA_CR_INDEX_MDA 0x3b4 | ||
101 | #define VGA_CR_DATA_MDA 0x3b5 | ||
102 | #define VGA_CR_INDEX_CGA 0x3d4 | ||
103 | #define VGA_CR_DATA_CGA 0x3d5 | ||
104 | |||
105 | /* | ||
106 | * Memory interface instructions used by the kernel | ||
107 | */ | ||
108 | #define MI_INSTR(opcode, flags) (((opcode) << 23) | (flags)) | ||
109 | |||
110 | #define MI_NOOP MI_INSTR(0, 0) | ||
111 | #define MI_USER_INTERRUPT MI_INSTR(0x02, 0) | ||
112 | #define MI_WAIT_FOR_EVENT MI_INSTR(0x03, 0) | ||
113 | #define MI_WAIT_FOR_PLANE_B_FLIP (1<<6) | ||
114 | #define MI_WAIT_FOR_PLANE_A_FLIP (1<<2) | ||
115 | #define MI_WAIT_FOR_PLANE_A_SCANLINES (1<<1) | ||
116 | #define MI_FLUSH MI_INSTR(0x04, 0) | ||
117 | #define MI_READ_FLUSH (1 << 0) | ||
118 | #define MI_EXE_FLUSH (1 << 1) | ||
119 | #define MI_NO_WRITE_FLUSH (1 << 2) | ||
120 | #define MI_SCENE_COUNT (1 << 3) /* just increment scene count */ | ||
121 | #define MI_END_SCENE (1 << 4) /* flush binner and incr scene count */ | ||
122 | #define MI_BATCH_BUFFER_END MI_INSTR(0x0a, 0) | ||
123 | #define MI_REPORT_HEAD MI_INSTR(0x07, 0) | ||
124 | #define MI_LOAD_SCAN_LINES_INCL MI_INSTR(0x12, 0) | ||
125 | #define MI_STORE_DWORD_IMM MI_INSTR(0x20, 1) | ||
126 | #define MI_MEM_VIRTUAL (1 << 22) /* 965+ only */ | ||
127 | #define MI_STORE_DWORD_INDEX MI_INSTR(0x21, 1) | ||
128 | #define MI_STORE_DWORD_INDEX_SHIFT 2 | ||
129 | #define MI_LOAD_REGISTER_IMM MI_INSTR(0x22, 1) | ||
130 | #define MI_BATCH_BUFFER MI_INSTR(0x30, 1) | ||
131 | #define MI_BATCH_NON_SECURE (1) | ||
132 | #define MI_BATCH_NON_SECURE_I965 (1<<8) | ||
133 | #define MI_BATCH_BUFFER_START MI_INSTR(0x31, 0) | ||
134 | |||
135 | /* | ||
136 | * 3D instructions used by the kernel | ||
137 | */ | ||
138 | #define GFX_INSTR(opcode, flags) ((0x3 << 29) | ((opcode) << 24) | (flags)) | ||
139 | |||
140 | #define GFX_OP_RASTER_RULES ((0x3<<29)|(0x7<<24)) | ||
141 | #define GFX_OP_SCISSOR ((0x3<<29)|(0x1c<<24)|(0x10<<19)) | ||
142 | #define SC_UPDATE_SCISSOR (0x1<<1) | ||
143 | #define SC_ENABLE_MASK (0x1<<0) | ||
144 | #define SC_ENABLE (0x1<<0) | ||
145 | #define GFX_OP_LOAD_INDIRECT ((0x3<<29)|(0x1d<<24)|(0x7<<16)) | ||
146 | #define GFX_OP_SCISSOR_INFO ((0x3<<29)|(0x1d<<24)|(0x81<<16)|(0x1)) | ||
147 | #define SCI_YMIN_MASK (0xffff<<16) | ||
148 | #define SCI_XMIN_MASK (0xffff<<0) | ||
149 | #define SCI_YMAX_MASK (0xffff<<16) | ||
150 | #define SCI_XMAX_MASK (0xffff<<0) | ||
151 | #define GFX_OP_SCISSOR_ENABLE ((0x3<<29)|(0x1c<<24)|(0x10<<19)) | ||
152 | #define GFX_OP_SCISSOR_RECT ((0x3<<29)|(0x1d<<24)|(0x81<<16)|1) | ||
153 | #define GFX_OP_COLOR_FACTOR ((0x3<<29)|(0x1d<<24)|(0x1<<16)|0x0) | ||
154 | #define GFX_OP_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16)) | ||
155 | #define GFX_OP_MAP_INFO ((0x3<<29)|(0x1d<<24)|0x4) | ||
156 | #define GFX_OP_DESTBUFFER_VARS ((0x3<<29)|(0x1d<<24)|(0x85<<16)|0x0) | ||
157 | #define GFX_OP_DESTBUFFER_INFO ((0x3<<29)|(0x1d<<24)|(0x8e<<16)|1) | ||
158 | #define GFX_OP_DRAWRECT_INFO ((0x3<<29)|(0x1d<<24)|(0x80<<16)|(0x3)) | ||
159 | #define GFX_OP_DRAWRECT_INFO_I965 ((0x7900<<16)|0x2) | ||
160 | #define SRC_COPY_BLT_CMD ((2<<29)|(0x43<<22)|4) | ||
161 | #define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6) | ||
162 | #define XY_MONO_SRC_COPY_IMM_BLT ((2<<29)|(0x71<<22)|5) | ||
163 | #define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21) | ||
164 | #define XY_SRC_COPY_BLT_WRITE_RGB (1<<20) | ||
165 | #define BLT_DEPTH_8 (0<<24) | ||
166 | #define BLT_DEPTH_16_565 (1<<24) | ||
167 | #define BLT_DEPTH_16_1555 (2<<24) | ||
168 | #define BLT_DEPTH_32 (3<<24) | ||
169 | #define BLT_ROP_GXCOPY (0xcc<<16) | ||
170 | #define XY_SRC_COPY_BLT_SRC_TILED (1<<15) /* 965+ only */ | ||
171 | #define XY_SRC_COPY_BLT_DST_TILED (1<<11) /* 965+ only */ | ||
172 | #define CMD_OP_DISPLAYBUFFER_INFO ((0x0<<29)|(0x14<<23)|2) | ||
173 | #define ASYNC_FLIP (1<<22) | ||
174 | #define DISPLAY_PLANE_A (0<<20) | ||
175 | #define DISPLAY_PLANE_B (1<<20) | ||
176 | |||
177 | /* | ||
178 | * Instruction and interrupt control regs | ||
179 | */ | ||
180 | |||
181 | #define PRB0_TAIL 0x02030 | ||
182 | #define PRB0_HEAD 0x02034 | ||
183 | #define PRB0_START 0x02038 | ||
184 | #define PRB0_CTL 0x0203c | ||
185 | #define TAIL_ADDR 0x001FFFF8 | ||
186 | #define HEAD_WRAP_COUNT 0xFFE00000 | ||
187 | #define HEAD_WRAP_ONE 0x00200000 | ||
188 | #define HEAD_ADDR 0x001FFFFC | ||
189 | #define RING_NR_PAGES 0x001FF000 | ||
190 | #define RING_REPORT_MASK 0x00000006 | ||
191 | #define RING_REPORT_64K 0x00000002 | ||
192 | #define RING_REPORT_128K 0x00000004 | ||
193 | #define RING_NO_REPORT 0x00000000 | ||
194 | #define RING_VALID_MASK 0x00000001 | ||
195 | #define RING_VALID 0x00000001 | ||
196 | #define RING_INVALID 0x00000000 | ||
197 | #define PRB1_TAIL 0x02040 /* 915+ only */ | ||
198 | #define PRB1_HEAD 0x02044 /* 915+ only */ | ||
199 | #define PRB1_START 0x02048 /* 915+ only */ | ||
200 | #define PRB1_CTL 0x0204c /* 915+ only */ | ||
201 | #define ACTHD_I965 0x02074 | ||
202 | #define HWS_PGA 0x02080 | ||
203 | #define HWS_ADDRESS_MASK 0xfffff000 | ||
204 | #define HWS_START_ADDRESS_SHIFT 4 | ||
205 | #define IPEIR 0x02088 | ||
206 | #define NOPID 0x02094 | ||
207 | #define HWSTAM 0x02098 | ||
208 | #define SCPD0 0x0209c /* 915+ only */ | ||
209 | #define IER 0x020a0 | ||
210 | #define IIR 0x020a4 | ||
211 | #define IMR 0x020a8 | ||
212 | #define ISR 0x020ac | ||
213 | #define I915_PIPE_CONTROL_NOTIFY_INTERRUPT (1<<18) | ||
214 | #define I915_DISPLAY_PORT_INTERRUPT (1<<17) | ||
215 | #define I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT (1<<15) | ||
216 | #define I915_GMCH_THERMAL_SENSOR_EVENT_INTERRUPT (1<<14) | ||
217 | #define I915_HWB_OOM_INTERRUPT (1<<13) | ||
218 | #define I915_SYNC_STATUS_INTERRUPT (1<<12) | ||
219 | #define I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT (1<<11) | ||
220 | #define I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT (1<<10) | ||
221 | #define I915_OVERLAY_PLANE_FLIP_PENDING_INTERRUPT (1<<9) | ||
222 | #define I915_DISPLAY_PLANE_C_FLIP_PENDING_INTERRUPT (1<<8) | ||
223 | #define I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT (1<<7) | ||
224 | #define I915_DISPLAY_PIPE_A_EVENT_INTERRUPT (1<<6) | ||
225 | #define I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT (1<<5) | ||
226 | #define I915_DISPLAY_PIPE_B_EVENT_INTERRUPT (1<<4) | ||
227 | #define I915_DEBUG_INTERRUPT (1<<2) | ||
228 | #define I915_USER_INTERRUPT (1<<1) | ||
229 | #define I915_ASLE_INTERRUPT (1<<0) | ||
230 | #define EIR 0x020b0 | ||
231 | #define EMR 0x020b4 | ||
232 | #define ESR 0x020b8 | ||
233 | #define INSTPM 0x020c0 | ||
234 | #define ACTHD 0x020c8 | ||
235 | #define FW_BLC 0x020d8 | ||
236 | #define FW_BLC_SELF 0x020e0 /* 915+ only */ | ||
237 | #define MI_ARB_STATE 0x020e4 /* 915+ only */ | ||
238 | #define CACHE_MODE_0 0x02120 /* 915+ only */ | ||
239 | #define CM0_MASK_SHIFT 16 | ||
240 | #define CM0_IZ_OPT_DISABLE (1<<6) | ||
241 | #define CM0_ZR_OPT_DISABLE (1<<5) | ||
242 | #define CM0_DEPTH_EVICT_DISABLE (1<<4) | ||
243 | #define CM0_COLOR_EVICT_DISABLE (1<<3) | ||
244 | #define CM0_DEPTH_WRITE_DISABLE (1<<1) | ||
245 | #define CM0_RC_OP_FLUSH_DISABLE (1<<0) | ||
246 | #define GFX_FLSH_CNTL 0x02170 /* 915+ only */ | ||
247 | |||
248 | /* | ||
249 | * Framebuffer compression (915+ only) | ||
250 | */ | ||
251 | |||
252 | #define FBC_CFB_BASE 0x03200 /* 4k page aligned */ | ||
253 | #define FBC_LL_BASE 0x03204 /* 4k page aligned */ | ||
254 | #define FBC_CONTROL 0x03208 | ||
255 | #define FBC_CTL_EN (1<<31) | ||
256 | #define FBC_CTL_PERIODIC (1<<30) | ||
257 | #define FBC_CTL_INTERVAL_SHIFT (16) | ||
258 | #define FBC_CTL_UNCOMPRESSIBLE (1<<14) | ||
259 | #define FBC_CTL_STRIDE_SHIFT (5) | ||
260 | #define FBC_CTL_FENCENO (1<<0) | ||
261 | #define FBC_COMMAND 0x0320c | ||
262 | #define FBC_CMD_COMPRESS (1<<0) | ||
263 | #define FBC_STATUS 0x03210 | ||
264 | #define FBC_STAT_COMPRESSING (1<<31) | ||
265 | #define FBC_STAT_COMPRESSED (1<<30) | ||
266 | #define FBC_STAT_MODIFIED (1<<29) | ||
267 | #define FBC_STAT_CURRENT_LINE (1<<0) | ||
268 | #define FBC_CONTROL2 0x03214 | ||
269 | #define FBC_CTL_FENCE_DBL (0<<4) | ||
270 | #define FBC_CTL_IDLE_IMM (0<<2) | ||
271 | #define FBC_CTL_IDLE_FULL (1<<2) | ||
272 | #define FBC_CTL_IDLE_LINE (2<<2) | ||
273 | #define FBC_CTL_IDLE_DEBUG (3<<2) | ||
274 | #define FBC_CTL_CPU_FENCE (1<<1) | ||
275 | #define FBC_CTL_PLANEA (0<<0) | ||
276 | #define FBC_CTL_PLANEB (1<<0) | ||
277 | #define FBC_FENCE_OFF 0x0321b | ||
278 | |||
279 | #define FBC_LL_SIZE (1536) | ||
280 | |||
281 | /* | ||
282 | * GPIO regs | ||
283 | */ | ||
284 | #define GPIOA 0x5010 | ||
285 | #define GPIOB 0x5014 | ||
286 | #define GPIOC 0x5018 | ||
287 | #define GPIOD 0x501c | ||
288 | #define GPIOE 0x5020 | ||
289 | #define GPIOF 0x5024 | ||
290 | #define GPIOG 0x5028 | ||
291 | #define GPIOH 0x502c | ||
292 | # define GPIO_CLOCK_DIR_MASK (1 << 0) | ||
293 | # define GPIO_CLOCK_DIR_IN (0 << 1) | ||
294 | # define GPIO_CLOCK_DIR_OUT (1 << 1) | ||
295 | # define GPIO_CLOCK_VAL_MASK (1 << 2) | ||
296 | # define GPIO_CLOCK_VAL_OUT (1 << 3) | ||
297 | # define GPIO_CLOCK_VAL_IN (1 << 4) | ||
298 | # define GPIO_CLOCK_PULLUP_DISABLE (1 << 5) | ||
299 | # define GPIO_DATA_DIR_MASK (1 << 8) | ||
300 | # define GPIO_DATA_DIR_IN (0 << 9) | ||
301 | # define GPIO_DATA_DIR_OUT (1 << 9) | ||
302 | # define GPIO_DATA_VAL_MASK (1 << 10) | ||
303 | # define GPIO_DATA_VAL_OUT (1 << 11) | ||
304 | # define GPIO_DATA_VAL_IN (1 << 12) | ||
305 | # define GPIO_DATA_PULLUP_DISABLE (1 << 13) | ||
306 | |||
307 | /* | ||
308 | * Clock control & power management | ||
309 | */ | ||
310 | |||
311 | #define VGA0 0x6000 | ||
312 | #define VGA1 0x6004 | ||
313 | #define VGA_PD 0x6010 | ||
314 | #define VGA0_PD_P2_DIV_4 (1 << 7) | ||
315 | #define VGA0_PD_P1_DIV_2 (1 << 5) | ||
316 | #define VGA0_PD_P1_SHIFT 0 | ||
317 | #define VGA0_PD_P1_MASK (0x1f << 0) | ||
318 | #define VGA1_PD_P2_DIV_4 (1 << 15) | ||
319 | #define VGA1_PD_P1_DIV_2 (1 << 13) | ||
320 | #define VGA1_PD_P1_SHIFT 8 | ||
321 | #define VGA1_PD_P1_MASK (0x1f << 8) | ||
322 | #define DPLL_A 0x06014 | ||
323 | #define DPLL_B 0x06018 | ||
324 | #define DPLL_VCO_ENABLE (1 << 31) | ||
325 | #define DPLL_DVO_HIGH_SPEED (1 << 30) | ||
326 | #define DPLL_SYNCLOCK_ENABLE (1 << 29) | ||
327 | #define DPLL_VGA_MODE_DIS (1 << 28) | ||
328 | #define DPLLB_MODE_DAC_SERIAL (1 << 26) /* i915 */ | ||
329 | #define DPLLB_MODE_LVDS (2 << 26) /* i915 */ | ||
330 | #define DPLL_MODE_MASK (3 << 26) | ||
331 | #define DPLL_DAC_SERIAL_P2_CLOCK_DIV_10 (0 << 24) /* i915 */ | ||
332 | #define DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 (1 << 24) /* i915 */ | ||
333 | #define DPLLB_LVDS_P2_CLOCK_DIV_14 (0 << 24) /* i915 */ | ||
334 | #define DPLLB_LVDS_P2_CLOCK_DIV_7 (1 << 24) /* i915 */ | ||
335 | #define DPLL_P2_CLOCK_DIV_MASK 0x03000000 /* i915 */ | ||
336 | #define DPLL_FPA01_P1_POST_DIV_MASK 0x00ff0000 /* i915 */ | ||
337 | |||
338 | #define I915_FIFO_UNDERRUN_STATUS (1UL<<31) | ||
339 | #define I915_CRC_ERROR_ENABLE (1UL<<29) | ||
340 | #define I915_CRC_DONE_ENABLE (1UL<<28) | ||
341 | #define I915_GMBUS_EVENT_ENABLE (1UL<<27) | ||
342 | #define I915_VSYNC_INTERRUPT_ENABLE (1UL<<25) | ||
343 | #define I915_DISPLAY_LINE_COMPARE_ENABLE (1UL<<24) | ||
344 | #define I915_DPST_EVENT_ENABLE (1UL<<23) | ||
345 | #define I915_LEGACY_BLC_EVENT_ENABLE (1UL<<22) | ||
346 | #define I915_ODD_FIELD_INTERRUPT_ENABLE (1UL<<21) | ||
347 | #define I915_EVEN_FIELD_INTERRUPT_ENABLE (1UL<<20) | ||
348 | #define I915_START_VBLANK_INTERRUPT_ENABLE (1UL<<18) /* 965 or later */ | ||
349 | #define I915_VBLANK_INTERRUPT_ENABLE (1UL<<17) | ||
350 | #define I915_OVERLAY_UPDATED_ENABLE (1UL<<16) | ||
351 | #define I915_CRC_ERROR_INTERRUPT_STATUS (1UL<<13) | ||
352 | #define I915_CRC_DONE_INTERRUPT_STATUS (1UL<<12) | ||
353 | #define I915_GMBUS_INTERRUPT_STATUS (1UL<<11) | ||
354 | #define I915_VSYNC_INTERRUPT_STATUS (1UL<<9) | ||
355 | #define I915_DISPLAY_LINE_COMPARE_STATUS (1UL<<8) | ||
356 | #define I915_DPST_EVENT_STATUS (1UL<<7) | ||
357 | #define I915_LEGACY_BLC_EVENT_STATUS (1UL<<6) | ||
358 | #define I915_ODD_FIELD_INTERRUPT_STATUS (1UL<<5) | ||
359 | #define I915_EVEN_FIELD_INTERRUPT_STATUS (1UL<<4) | ||
360 | #define I915_START_VBLANK_INTERRUPT_STATUS (1UL<<2) /* 965 or later */ | ||
361 | #define I915_VBLANK_INTERRUPT_STATUS (1UL<<1) | ||
362 | #define I915_OVERLAY_UPDATED_STATUS (1UL<<0) | ||
363 | |||
364 | #define SRX_INDEX 0x3c4 | ||
365 | #define SRX_DATA 0x3c5 | ||
366 | #define SR01 1 | ||
367 | #define SR01_SCREEN_OFF (1<<5) | ||
368 | |||
369 | #define PPCR 0x61204 | ||
370 | #define PPCR_ON (1<<0) | ||
371 | |||
372 | #define DVOB 0x61140 | ||
373 | #define DVOB_ON (1<<31) | ||
374 | #define DVOC 0x61160 | ||
375 | #define DVOC_ON (1<<31) | ||
376 | #define LVDS 0x61180 | ||
377 | #define LVDS_ON (1<<31) | ||
378 | |||
379 | #define ADPA 0x61100 | ||
380 | #define ADPA_DPMS_MASK (~(3<<10)) | ||
381 | #define ADPA_DPMS_ON (0<<10) | ||
382 | #define ADPA_DPMS_SUSPEND (1<<10) | ||
383 | #define ADPA_DPMS_STANDBY (2<<10) | ||
384 | #define ADPA_DPMS_OFF (3<<10) | ||
385 | |||
386 | #define RING_TAIL 0x00 | ||
387 | #define TAIL_ADDR 0x001FFFF8 | ||
388 | #define RING_HEAD 0x04 | ||
389 | #define HEAD_WRAP_COUNT 0xFFE00000 | ||
390 | #define HEAD_WRAP_ONE 0x00200000 | ||
391 | #define HEAD_ADDR 0x001FFFFC | ||
392 | #define RING_START 0x08 | ||
393 | #define START_ADDR 0xFFFFF000 | ||
394 | #define RING_LEN 0x0C | ||
395 | #define RING_NR_PAGES 0x001FF000 | ||
396 | #define RING_REPORT_MASK 0x00000006 | ||
397 | #define RING_REPORT_64K 0x00000002 | ||
398 | #define RING_REPORT_128K 0x00000004 | ||
399 | #define RING_NO_REPORT 0x00000000 | ||
400 | #define RING_VALID_MASK 0x00000001 | ||
401 | #define RING_VALID 0x00000001 | ||
402 | #define RING_INVALID 0x00000000 | ||
403 | |||
404 | /* Scratch pad debug 0 reg: | ||
405 | */ | ||
406 | #define DPLL_FPA01_P1_POST_DIV_MASK_I830 0x001f0000 | ||
407 | /* | ||
408 | * The i830 generation, in LVDS mode, defines P1 as the bit number set within | ||
409 | * this field (only one bit may be set). | ||
410 | */ | ||
411 | #define DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS 0x003f0000 | ||
412 | #define DPLL_FPA01_P1_POST_DIV_SHIFT 16 | ||
413 | /* i830, required in DVO non-gang */ | ||
414 | #define PLL_P2_DIVIDE_BY_4 (1 << 23) | ||
415 | #define PLL_P1_DIVIDE_BY_TWO (1 << 21) /* i830 */ | ||
416 | #define PLL_REF_INPUT_DREFCLK (0 << 13) | ||
417 | #define PLL_REF_INPUT_TVCLKINA (1 << 13) /* i830 */ | ||
418 | #define PLL_REF_INPUT_TVCLKINBC (2 << 13) /* SDVO TVCLKIN */ | ||
419 | #define PLLB_REF_INPUT_SPREADSPECTRUMIN (3 << 13) | ||
420 | #define PLL_REF_INPUT_MASK (3 << 13) | ||
421 | #define PLL_LOAD_PULSE_PHASE_SHIFT 9 | ||
422 | /* | ||
423 | * Parallel to Serial Load Pulse phase selection. | ||
424 | * Selects the phase for the 10X DPLL clock for the PCIe | ||
425 | * digital display port. The range is 4 to 13; 10 or more | ||
426 | * is just a flip delay. The default is 6 | ||
427 | */ | ||
428 | #define PLL_LOAD_PULSE_PHASE_MASK (0xf << PLL_LOAD_PULSE_PHASE_SHIFT) | ||
429 | #define DISPLAY_RATE_SELECT_FPA1 (1 << 8) | ||
430 | /* | ||
431 | * SDVO multiplier for 945G/GM. Not used on 965. | ||
432 | */ | ||
433 | #define SDVO_MULTIPLIER_MASK 0x000000ff | ||
434 | #define SDVO_MULTIPLIER_SHIFT_HIRES 4 | ||
435 | #define SDVO_MULTIPLIER_SHIFT_VGA 0 | ||
436 | #define DPLL_A_MD 0x0601c /* 965+ only */ | ||
437 | /* | ||
438 | * UDI pixel divider, controlling how many pixels are stuffed into a packet. | ||
439 | * | ||
440 | * Value is pixels minus 1. Must be set to 1 pixel for SDVO. | ||
441 | */ | ||
442 | #define DPLL_MD_UDI_DIVIDER_MASK 0x3f000000 | ||
443 | #define DPLL_MD_UDI_DIVIDER_SHIFT 24 | ||
444 | /* UDI pixel divider for VGA, same as DPLL_MD_UDI_DIVIDER_MASK. */ | ||
445 | #define DPLL_MD_VGA_UDI_DIVIDER_MASK 0x003f0000 | ||
446 | #define DPLL_MD_VGA_UDI_DIVIDER_SHIFT 16 | ||
447 | /* | ||
448 | * SDVO/UDI pixel multiplier. | ||
449 | * | ||
450 | * SDVO requires that the bus clock rate be between 1 and 2 Ghz, and the bus | ||
451 | * clock rate is 10 times the DPLL clock. At low resolution/refresh rate | ||
452 | * modes, the bus rate would be below the limits, so SDVO allows for stuffing | ||
453 | * dummy bytes in the datastream at an increased clock rate, with both sides of | ||
454 | * the link knowing how many bytes are fill. | ||
455 | * | ||
456 | * So, for a mode with a dotclock of 65Mhz, we would want to double the clock | ||
457 | * rate to 130Mhz to get a bus rate of 1.30Ghz. The DPLL clock rate would be | ||
458 | * set to 130Mhz, and the SDVO multiplier set to 2x in this register and | ||
459 | * through an SDVO command. | ||
460 | * | ||
461 | * This register field has values of multiplication factor minus 1, with | ||
462 | * a maximum multiplier of 5 for SDVO. | ||
463 | */ | ||
464 | #define DPLL_MD_UDI_MULTIPLIER_MASK 0x00003f00 | ||
465 | #define DPLL_MD_UDI_MULTIPLIER_SHIFT 8 | ||
466 | /* | ||
467 | * SDVO/UDI pixel multiplier for VGA, same as DPLL_MD_UDI_MULTIPLIER_MASK. | ||
468 | * This best be set to the default value (3) or the CRT won't work. No, | ||
469 | * I don't entirely understand what this does... | ||
470 | */ | ||
471 | #define DPLL_MD_VGA_UDI_MULTIPLIER_MASK 0x0000003f | ||
472 | #define DPLL_MD_VGA_UDI_MULTIPLIER_SHIFT 0 | ||
473 | #define DPLL_B_MD 0x06020 /* 965+ only */ | ||
474 | #define FPA0 0x06040 | ||
475 | #define FPA1 0x06044 | ||
476 | #define FPB0 0x06048 | ||
477 | #define FPB1 0x0604c | ||
478 | #define FP_N_DIV_MASK 0x003f0000 | ||
479 | #define FP_N_DIV_SHIFT 16 | ||
480 | #define FP_M1_DIV_MASK 0x00003f00 | ||
481 | #define FP_M1_DIV_SHIFT 8 | ||
482 | #define FP_M2_DIV_MASK 0x0000003f | ||
483 | #define FP_M2_DIV_SHIFT 0 | ||
484 | #define DPLL_TEST 0x606c | ||
485 | #define DPLLB_TEST_SDVO_DIV_1 (0 << 22) | ||
486 | #define DPLLB_TEST_SDVO_DIV_2 (1 << 22) | ||
487 | #define DPLLB_TEST_SDVO_DIV_4 (2 << 22) | ||
488 | #define DPLLB_TEST_SDVO_DIV_MASK (3 << 22) | ||
489 | #define DPLLB_TEST_N_BYPASS (1 << 19) | ||
490 | #define DPLLB_TEST_M_BYPASS (1 << 18) | ||
491 | #define DPLLB_INPUT_BUFFER_ENABLE (1 << 16) | ||
492 | #define DPLLA_TEST_N_BYPASS (1 << 3) | ||
493 | #define DPLLA_TEST_M_BYPASS (1 << 2) | ||
494 | #define DPLLA_INPUT_BUFFER_ENABLE (1 << 0) | ||
495 | #define D_STATE 0x6104 | ||
496 | #define CG_2D_DIS 0x6200 | ||
497 | #define CG_3D_DIS 0x6204 | ||
498 | |||
499 | /* | ||
500 | * Palette regs | ||
501 | */ | ||
502 | |||
503 | #define PALETTE_A 0x0a000 | ||
504 | #define PALETTE_B 0x0a800 | ||
505 | |||
506 | /* MCH MMIO space */ | ||
507 | |||
508 | /* | ||
509 | * MCHBAR mirror. | ||
510 | * | ||
511 | * This mirrors the MCHBAR MMIO space whose location is determined by | ||
512 | * device 0 function 0's pci config register 0x44 or 0x48 and matches it in | ||
513 | * every way. It is not accessible from the CP register read instructions. | ||
514 | * | ||
515 | */ | ||
516 | #define MCHBAR_MIRROR_BASE 0x10000 | ||
517 | |||
518 | /** 915-945 and GM965 MCH register controlling DRAM channel access */ | ||
519 | #define DCC 0x10200 | ||
520 | #define DCC_ADDRESSING_MODE_SINGLE_CHANNEL (0 << 0) | ||
521 | #define DCC_ADDRESSING_MODE_DUAL_CHANNEL_ASYMMETRIC (1 << 0) | ||
522 | #define DCC_ADDRESSING_MODE_DUAL_CHANNEL_INTERLEAVED (2 << 0) | ||
523 | #define DCC_ADDRESSING_MODE_MASK (3 << 0) | ||
524 | #define DCC_CHANNEL_XOR_DISABLE (1 << 10) | ||
525 | |||
526 | /** 965 MCH register controlling DRAM channel configuration */ | ||
527 | #define C0DRB3 0x10206 | ||
528 | #define C1DRB3 0x10606 | ||
529 | |||
530 | /* | ||
531 | * Overlay regs | ||
532 | */ | ||
533 | |||
534 | #define OVADD 0x30000 | ||
535 | #define DOVSTA 0x30008 | ||
536 | #define OC_BUF (0x3<<20) | ||
537 | #define OGAMC5 0x30010 | ||
538 | #define OGAMC4 0x30014 | ||
539 | #define OGAMC3 0x30018 | ||
540 | #define OGAMC2 0x3001c | ||
541 | #define OGAMC1 0x30020 | ||
542 | #define OGAMC0 0x30024 | ||
543 | |||
544 | /* | ||
545 | * Display engine regs | ||
546 | */ | ||
547 | |||
548 | /* Pipe A timing regs */ | ||
549 | #define HTOTAL_A 0x60000 | ||
550 | #define HBLANK_A 0x60004 | ||
551 | #define HSYNC_A 0x60008 | ||
552 | #define VTOTAL_A 0x6000c | ||
553 | #define VBLANK_A 0x60010 | ||
554 | #define VSYNC_A 0x60014 | ||
555 | #define PIPEASRC 0x6001c | ||
556 | #define BCLRPAT_A 0x60020 | ||
557 | |||
558 | /* Pipe B timing regs */ | ||
559 | #define HTOTAL_B 0x61000 | ||
560 | #define HBLANK_B 0x61004 | ||
561 | #define HSYNC_B 0x61008 | ||
562 | #define VTOTAL_B 0x6100c | ||
563 | #define VBLANK_B 0x61010 | ||
564 | #define VSYNC_B 0x61014 | ||
565 | #define PIPEBSRC 0x6101c | ||
566 | #define BCLRPAT_B 0x61020 | ||
567 | |||
568 | /* VGA port control */ | ||
569 | #define ADPA 0x61100 | ||
570 | #define ADPA_DAC_ENABLE (1<<31) | ||
571 | #define ADPA_DAC_DISABLE 0 | ||
572 | #define ADPA_PIPE_SELECT_MASK (1<<30) | ||
573 | #define ADPA_PIPE_A_SELECT 0 | ||
574 | #define ADPA_PIPE_B_SELECT (1<<30) | ||
575 | #define ADPA_USE_VGA_HVPOLARITY (1<<15) | ||
576 | #define ADPA_SETS_HVPOLARITY 0 | ||
577 | #define ADPA_VSYNC_CNTL_DISABLE (1<<11) | ||
578 | #define ADPA_VSYNC_CNTL_ENABLE 0 | ||
579 | #define ADPA_HSYNC_CNTL_DISABLE (1<<10) | ||
580 | #define ADPA_HSYNC_CNTL_ENABLE 0 | ||
581 | #define ADPA_VSYNC_ACTIVE_HIGH (1<<4) | ||
582 | #define ADPA_VSYNC_ACTIVE_LOW 0 | ||
583 | #define ADPA_HSYNC_ACTIVE_HIGH (1<<3) | ||
584 | #define ADPA_HSYNC_ACTIVE_LOW 0 | ||
585 | #define ADPA_DPMS_MASK (~(3<<10)) | ||
586 | #define ADPA_DPMS_ON (0<<10) | ||
587 | #define ADPA_DPMS_SUSPEND (1<<10) | ||
588 | #define ADPA_DPMS_STANDBY (2<<10) | ||
589 | #define ADPA_DPMS_OFF (3<<10) | ||
590 | |||
591 | /* Hotplug control (945+ only) */ | ||
592 | #define PORT_HOTPLUG_EN 0x61110 | ||
593 | #define SDVOB_HOTPLUG_INT_EN (1 << 26) | ||
594 | #define SDVOC_HOTPLUG_INT_EN (1 << 25) | ||
595 | #define TV_HOTPLUG_INT_EN (1 << 18) | ||
596 | #define CRT_HOTPLUG_INT_EN (1 << 9) | ||
597 | #define CRT_HOTPLUG_FORCE_DETECT (1 << 3) | ||
598 | |||
599 | #define PORT_HOTPLUG_STAT 0x61114 | ||
600 | #define CRT_HOTPLUG_INT_STATUS (1 << 11) | ||
601 | #define TV_HOTPLUG_INT_STATUS (1 << 10) | ||
602 | #define CRT_HOTPLUG_MONITOR_MASK (3 << 8) | ||
603 | #define CRT_HOTPLUG_MONITOR_COLOR (3 << 8) | ||
604 | #define CRT_HOTPLUG_MONITOR_MONO (2 << 8) | ||
605 | #define CRT_HOTPLUG_MONITOR_NONE (0 << 8) | ||
606 | #define SDVOC_HOTPLUG_INT_STATUS (1 << 7) | ||
607 | #define SDVOB_HOTPLUG_INT_STATUS (1 << 6) | ||
608 | |||
609 | /* SDVO port control */ | ||
610 | #define SDVOB 0x61140 | ||
611 | #define SDVOC 0x61160 | ||
612 | #define SDVO_ENABLE (1 << 31) | ||
613 | #define SDVO_PIPE_B_SELECT (1 << 30) | ||
614 | #define SDVO_STALL_SELECT (1 << 29) | ||
615 | #define SDVO_INTERRUPT_ENABLE (1 << 26) | ||
616 | /** | ||
617 | * 915G/GM SDVO pixel multiplier. | ||
618 | * | ||
619 | * Programmed value is multiplier - 1, up to 5x. | ||
620 | * | ||
621 | * \sa DPLL_MD_UDI_MULTIPLIER_MASK | ||
622 | */ | ||
623 | #define SDVO_PORT_MULTIPLY_MASK (7 << 23) | ||
624 | #define SDVO_PORT_MULTIPLY_SHIFT 23 | ||
625 | #define SDVO_PHASE_SELECT_MASK (15 << 19) | ||
626 | #define SDVO_PHASE_SELECT_DEFAULT (6 << 19) | ||
627 | #define SDVO_CLOCK_OUTPUT_INVERT (1 << 18) | ||
628 | #define SDVOC_GANG_MODE (1 << 16) | ||
629 | #define SDVO_BORDER_ENABLE (1 << 7) | ||
630 | #define SDVOB_PCIE_CONCURRENCY (1 << 3) | ||
631 | #define SDVO_DETECTED (1 << 2) | ||
632 | /* Bits to be preserved when writing */ | ||
633 | #define SDVOB_PRESERVE_MASK ((1 << 17) | (1 << 16) | (1 << 14) | (1 << 26)) | ||
634 | #define SDVOC_PRESERVE_MASK ((1 << 17) | (1 << 26)) | ||
635 | |||
636 | /* DVO port control */ | ||
637 | #define DVOA 0x61120 | ||
638 | #define DVOB 0x61140 | ||
639 | #define DVOC 0x61160 | ||
640 | #define DVO_ENABLE (1 << 31) | ||
641 | #define DVO_PIPE_B_SELECT (1 << 30) | ||
642 | #define DVO_PIPE_STALL_UNUSED (0 << 28) | ||
643 | #define DVO_PIPE_STALL (1 << 28) | ||
644 | #define DVO_PIPE_STALL_TV (2 << 28) | ||
645 | #define DVO_PIPE_STALL_MASK (3 << 28) | ||
646 | #define DVO_USE_VGA_SYNC (1 << 15) | ||
647 | #define DVO_DATA_ORDER_I740 (0 << 14) | ||
648 | #define DVO_DATA_ORDER_FP (1 << 14) | ||
649 | #define DVO_VSYNC_DISABLE (1 << 11) | ||
650 | #define DVO_HSYNC_DISABLE (1 << 10) | ||
651 | #define DVO_VSYNC_TRISTATE (1 << 9) | ||
652 | #define DVO_HSYNC_TRISTATE (1 << 8) | ||
653 | #define DVO_BORDER_ENABLE (1 << 7) | ||
654 | #define DVO_DATA_ORDER_GBRG (1 << 6) | ||
655 | #define DVO_DATA_ORDER_RGGB (0 << 6) | ||
656 | #define DVO_DATA_ORDER_GBRG_ERRATA (0 << 6) | ||
657 | #define DVO_DATA_ORDER_RGGB_ERRATA (1 << 6) | ||
658 | #define DVO_VSYNC_ACTIVE_HIGH (1 << 4) | ||
659 | #define DVO_HSYNC_ACTIVE_HIGH (1 << 3) | ||
660 | #define DVO_BLANK_ACTIVE_HIGH (1 << 2) | ||
661 | #define DVO_OUTPUT_CSTATE_PIXELS (1 << 1) /* SDG only */ | ||
662 | #define DVO_OUTPUT_SOURCE_SIZE_PIXELS (1 << 0) /* SDG only */ | ||
663 | #define DVO_PRESERVE_MASK (0x7<<24) | ||
664 | #define DVOA_SRCDIM 0x61124 | ||
665 | #define DVOB_SRCDIM 0x61144 | ||
666 | #define DVOC_SRCDIM 0x61164 | ||
667 | #define DVO_SRCDIM_HORIZONTAL_SHIFT 12 | ||
668 | #define DVO_SRCDIM_VERTICAL_SHIFT 0 | ||
669 | |||
670 | /* LVDS port control */ | ||
671 | #define LVDS 0x61180 | ||
672 | /* | ||
673 | * Enables the LVDS port. This bit must be set before DPLLs are enabled, as | ||
674 | * the DPLL semantics change when the LVDS is assigned to that pipe. | ||
675 | */ | ||
676 | #define LVDS_PORT_EN (1 << 31) | ||
677 | /* Selects pipe B for LVDS data. Must be set on pre-965. */ | ||
678 | #define LVDS_PIPEB_SELECT (1 << 30) | ||
679 | /* | ||
680 | * Enables the A0-A2 data pairs and CLKA, containing 18 bits of color data per | ||
681 | * pixel. | ||
682 | */ | ||
683 | #define LVDS_A0A2_CLKA_POWER_MASK (3 << 8) | ||
684 | #define LVDS_A0A2_CLKA_POWER_DOWN (0 << 8) | ||
685 | #define LVDS_A0A2_CLKA_POWER_UP (3 << 8) | ||
686 | /* | ||
687 | * Controls the A3 data pair, which contains the additional LSBs for 24 bit | ||
688 | * mode. Only enabled if LVDS_A0A2_CLKA_POWER_UP also indicates it should be | ||
689 | * on. | ||
690 | */ | ||
691 | #define LVDS_A3_POWER_MASK (3 << 6) | ||
692 | #define LVDS_A3_POWER_DOWN (0 << 6) | ||
693 | #define LVDS_A3_POWER_UP (3 << 6) | ||
694 | /* | ||
695 | * Controls the CLKB pair. This should only be set when LVDS_B0B3_POWER_UP | ||
696 | * is set. | ||
697 | */ | ||
698 | #define LVDS_CLKB_POWER_MASK (3 << 4) | ||
699 | #define LVDS_CLKB_POWER_DOWN (0 << 4) | ||
700 | #define LVDS_CLKB_POWER_UP (3 << 4) | ||
701 | /* | ||
702 | * Controls the B0-B3 data pairs. This must be set to match the DPLL p2 | ||
703 | * setting for whether we are in dual-channel mode. The B3 pair will | ||
704 | * additionally only be powered up when LVDS_A3_POWER_UP is set. | ||
705 | */ | ||
706 | #define LVDS_B0B3_POWER_MASK (3 << 2) | ||
707 | #define LVDS_B0B3_POWER_DOWN (0 << 2) | ||
708 | #define LVDS_B0B3_POWER_UP (3 << 2) | ||
709 | |||
710 | /* Panel power sequencing */ | ||
711 | #define PP_STATUS 0x61200 | ||
712 | #define PP_ON (1 << 31) | ||
713 | /* | ||
714 | * Indicates that all dependencies of the panel are on: | ||
715 | * | ||
716 | * - PLL enabled | ||
717 | * - pipe enabled | ||
718 | * - LVDS/DVOB/DVOC on | ||
719 | */ | ||
720 | #define PP_READY (1 << 30) | ||
721 | #define PP_SEQUENCE_NONE (0 << 28) | ||
722 | #define PP_SEQUENCE_ON (1 << 28) | ||
723 | #define PP_SEQUENCE_OFF (2 << 28) | ||
724 | #define PP_SEQUENCE_MASK 0x30000000 | ||
725 | #define PP_CONTROL 0x61204 | ||
726 | #define POWER_TARGET_ON (1 << 0) | ||
727 | #define PP_ON_DELAYS 0x61208 | ||
728 | #define PP_OFF_DELAYS 0x6120c | ||
729 | #define PP_DIVISOR 0x61210 | ||
730 | |||
731 | /* Panel fitting */ | ||
732 | #define PFIT_CONTROL 0x61230 | ||
733 | #define PFIT_ENABLE (1 << 31) | ||
734 | #define PFIT_PIPE_MASK (3 << 29) | ||
735 | #define PFIT_PIPE_SHIFT 29 | ||
736 | #define VERT_INTERP_DISABLE (0 << 10) | ||
737 | #define VERT_INTERP_BILINEAR (1 << 10) | ||
738 | #define VERT_INTERP_MASK (3 << 10) | ||
739 | #define VERT_AUTO_SCALE (1 << 9) | ||
740 | #define HORIZ_INTERP_DISABLE (0 << 6) | ||
741 | #define HORIZ_INTERP_BILINEAR (1 << 6) | ||
742 | #define HORIZ_INTERP_MASK (3 << 6) | ||
743 | #define HORIZ_AUTO_SCALE (1 << 5) | ||
744 | #define PANEL_8TO6_DITHER_ENABLE (1 << 3) | ||
745 | #define PFIT_PGM_RATIOS 0x61234 | ||
746 | #define PFIT_VERT_SCALE_MASK 0xfff00000 | ||
747 | #define PFIT_HORIZ_SCALE_MASK 0x0000fff0 | ||
748 | #define PFIT_AUTO_RATIOS 0x61238 | ||
749 | |||
750 | /* Backlight control */ | ||
751 | #define BLC_PWM_CTL 0x61254 | ||
752 | #define BACKLIGHT_MODULATION_FREQ_SHIFT (17) | ||
753 | #define BLC_PWM_CTL2 0x61250 /* 965+ only */ | ||
754 | #define BLM_COMBINATION_MODE (1 << 30) | ||
755 | /* | ||
756 | * This is the most significant 15 bits of the number of backlight cycles in a | ||
757 | * complete cycle of the modulated backlight control. | ||
758 | * | ||
759 | * The actual value is this field multiplied by two. | ||
760 | */ | ||
761 | #define BACKLIGHT_MODULATION_FREQ_MASK (0x7fff << 17) | ||
762 | #define BLM_LEGACY_MODE (1 << 16) | ||
763 | /* | ||
764 | * This is the number of cycles out of the backlight modulation cycle for which | ||
765 | * the backlight is on. | ||
766 | * | ||
767 | * This field must be no greater than the number of cycles in the complete | ||
768 | * backlight modulation cycle. | ||
769 | */ | ||
770 | #define BACKLIGHT_DUTY_CYCLE_SHIFT (0) | ||
771 | #define BACKLIGHT_DUTY_CYCLE_MASK (0xffff) | ||
772 | |||
773 | /* TV port control */ | ||
774 | #define TV_CTL 0x68000 | ||
775 | /** Enables the TV encoder */ | ||
776 | # define TV_ENC_ENABLE (1 << 31) | ||
777 | /** Sources the TV encoder input from pipe B instead of A. */ | ||
778 | # define TV_ENC_PIPEB_SELECT (1 << 30) | ||
779 | /** Outputs composite video (DAC A only) */ | ||
780 | # define TV_ENC_OUTPUT_COMPOSITE (0 << 28) | ||
781 | /** Outputs SVideo video (DAC B/C) */ | ||
782 | # define TV_ENC_OUTPUT_SVIDEO (1 << 28) | ||
783 | /** Outputs Component video (DAC A/B/C) */ | ||
784 | # define TV_ENC_OUTPUT_COMPONENT (2 << 28) | ||
785 | /** Outputs Composite and SVideo (DAC A/B/C) */ | ||
786 | # define TV_ENC_OUTPUT_SVIDEO_COMPOSITE (3 << 28) | ||
787 | # define TV_TRILEVEL_SYNC (1 << 21) | ||
788 | /** Enables slow sync generation (945GM only) */ | ||
789 | # define TV_SLOW_SYNC (1 << 20) | ||
790 | /** Selects 4x oversampling for 480i and 576p */ | ||
791 | # define TV_OVERSAMPLE_4X (0 << 18) | ||
792 | /** Selects 2x oversampling for 720p and 1080i */ | ||
793 | # define TV_OVERSAMPLE_2X (1 << 18) | ||
794 | /** Selects no oversampling for 1080p */ | ||
795 | # define TV_OVERSAMPLE_NONE (2 << 18) | ||
796 | /** Selects 8x oversampling */ | ||
797 | # define TV_OVERSAMPLE_8X (3 << 18) | ||
798 | /** Selects progressive mode rather than interlaced */ | ||
799 | # define TV_PROGRESSIVE (1 << 17) | ||
800 | /** Sets the colorburst to PAL mode. Required for non-M PAL modes. */ | ||
801 | # define TV_PAL_BURST (1 << 16) | ||
802 | /** Field for setting delay of Y compared to C */ | ||
803 | # define TV_YC_SKEW_MASK (7 << 12) | ||
804 | /** Enables a fix for 480p/576p standard definition modes on the 915GM only */ | ||
805 | # define TV_ENC_SDP_FIX (1 << 11) | ||
806 | /** | ||
807 | * Enables a fix for the 915GM only. | ||
808 | * | ||
809 | * Not sure what it does. | ||
810 | */ | ||
811 | # define TV_ENC_C0_FIX (1 << 10) | ||
812 | /** Bits that must be preserved by software */ | ||
813 | # define TV_CTL_SAVE ((3 << 8) | (3 << 6)) | ||
814 | # define TV_FUSE_STATE_MASK (3 << 4) | ||
815 | /** Read-only state that reports all features enabled */ | ||
816 | # define TV_FUSE_STATE_ENABLED (0 << 4) | ||
817 | /** Read-only state that reports that Macrovision is disabled in hardware*/ | ||
818 | # define TV_FUSE_STATE_NO_MACROVISION (1 << 4) | ||
819 | /** Read-only state that reports that TV-out is disabled in hardware. */ | ||
820 | # define TV_FUSE_STATE_DISABLED (2 << 4) | ||
821 | /** Normal operation */ | ||
822 | # define TV_TEST_MODE_NORMAL (0 << 0) | ||
823 | /** Encoder test pattern 1 - combo pattern */ | ||
824 | # define TV_TEST_MODE_PATTERN_1 (1 << 0) | ||
825 | /** Encoder test pattern 2 - full screen vertical 75% color bars */ | ||
826 | # define TV_TEST_MODE_PATTERN_2 (2 << 0) | ||
827 | /** Encoder test pattern 3 - full screen horizontal 75% color bars */ | ||
828 | # define TV_TEST_MODE_PATTERN_3 (3 << 0) | ||
829 | /** Encoder test pattern 4 - random noise */ | ||
830 | # define TV_TEST_MODE_PATTERN_4 (4 << 0) | ||
831 | /** Encoder test pattern 5 - linear color ramps */ | ||
832 | # define TV_TEST_MODE_PATTERN_5 (5 << 0) | ||
833 | /** | ||
834 | * This test mode forces the DACs to 50% of full output. | ||
835 | * | ||
836 | * This is used for load detection in combination with TVDAC_SENSE_MASK | ||
837 | */ | ||
838 | # define TV_TEST_MODE_MONITOR_DETECT (7 << 0) | ||
839 | # define TV_TEST_MODE_MASK (7 << 0) | ||
840 | |||
841 | #define TV_DAC 0x68004 | ||
842 | /** | ||
843 | * Reports that DAC state change logic has reported change (RO). | ||
844 | * | ||
845 | * This gets cleared when TV_DAC_STATE_EN is cleared | ||
846 | */ | ||
847 | # define TVDAC_STATE_CHG (1 << 31) | ||
848 | # define TVDAC_SENSE_MASK (7 << 28) | ||
849 | /** Reports that DAC A voltage is above the detect threshold */ | ||
850 | # define TVDAC_A_SENSE (1 << 30) | ||
851 | /** Reports that DAC B voltage is above the detect threshold */ | ||
852 | # define TVDAC_B_SENSE (1 << 29) | ||
853 | /** Reports that DAC C voltage is above the detect threshold */ | ||
854 | # define TVDAC_C_SENSE (1 << 28) | ||
855 | /** | ||
856 | * Enables DAC state detection logic, for load-based TV detection. | ||
857 | * | ||
858 | * The PLL of the chosen pipe (in TV_CTL) must be running, and the encoder set | ||
859 | * to off, for load detection to work. | ||
860 | */ | ||
861 | # define TVDAC_STATE_CHG_EN (1 << 27) | ||
862 | /** Sets the DAC A sense value to high */ | ||
863 | # define TVDAC_A_SENSE_CTL (1 << 26) | ||
864 | /** Sets the DAC B sense value to high */ | ||
865 | # define TVDAC_B_SENSE_CTL (1 << 25) | ||
866 | /** Sets the DAC C sense value to high */ | ||
867 | # define TVDAC_C_SENSE_CTL (1 << 24) | ||
868 | /** Overrides the ENC_ENABLE and DAC voltage levels */ | ||
869 | # define DAC_CTL_OVERRIDE (1 << 7) | ||
870 | /** Sets the slew rate. Must be preserved in software */ | ||
871 | # define ENC_TVDAC_SLEW_FAST (1 << 6) | ||
872 | # define DAC_A_1_3_V (0 << 4) | ||
873 | # define DAC_A_1_1_V (1 << 4) | ||
874 | # define DAC_A_0_7_V (2 << 4) | ||
875 | # define DAC_A_OFF (3 << 4) | ||
876 | # define DAC_B_1_3_V (0 << 2) | ||
877 | # define DAC_B_1_1_V (1 << 2) | ||
878 | # define DAC_B_0_7_V (2 << 2) | ||
879 | # define DAC_B_OFF (3 << 2) | ||
880 | # define DAC_C_1_3_V (0 << 0) | ||
881 | # define DAC_C_1_1_V (1 << 0) | ||
882 | # define DAC_C_0_7_V (2 << 0) | ||
883 | # define DAC_C_OFF (3 << 0) | ||
884 | |||
885 | /** | ||
886 | * CSC coefficients are stored in a floating point format with 9 bits of | ||
887 | * mantissa and 2 or 3 bits of exponent. The exponent is represented as 2**-n, | ||
888 | * where 2-bit exponents are unsigned n, and 3-bit exponents are signed n with | ||
889 | * -1 (0x3) being the only legal negative value. | ||
890 | */ | ||
891 | #define TV_CSC_Y 0x68010 | ||
892 | # define TV_RY_MASK 0x07ff0000 | ||
893 | # define TV_RY_SHIFT 16 | ||
894 | # define TV_GY_MASK 0x00000fff | ||
895 | # define TV_GY_SHIFT 0 | ||
896 | |||
897 | #define TV_CSC_Y2 0x68014 | ||
898 | # define TV_BY_MASK 0x07ff0000 | ||
899 | # define TV_BY_SHIFT 16 | ||
900 | /** | ||
901 | * Y attenuation for component video. | ||
902 | * | ||
903 | * Stored in 1.9 fixed point. | ||
904 | */ | ||
905 | # define TV_AY_MASK 0x000003ff | ||
906 | # define TV_AY_SHIFT 0 | ||
907 | |||
908 | #define TV_CSC_U 0x68018 | ||
909 | # define TV_RU_MASK 0x07ff0000 | ||
910 | # define TV_RU_SHIFT 16 | ||
911 | # define TV_GU_MASK 0x000007ff | ||
912 | # define TV_GU_SHIFT 0 | ||
913 | |||
914 | #define TV_CSC_U2 0x6801c | ||
915 | # define TV_BU_MASK 0x07ff0000 | ||
916 | # define TV_BU_SHIFT 16 | ||
917 | /** | ||
918 | * U attenuation for component video. | ||
919 | * | ||
920 | * Stored in 1.9 fixed point. | ||
921 | */ | ||
922 | # define TV_AU_MASK 0x000003ff | ||
923 | # define TV_AU_SHIFT 0 | ||
924 | |||
925 | #define TV_CSC_V 0x68020 | ||
926 | # define TV_RV_MASK 0x0fff0000 | ||
927 | # define TV_RV_SHIFT 16 | ||
928 | # define TV_GV_MASK 0x000007ff | ||
929 | # define TV_GV_SHIFT 0 | ||
930 | |||
931 | #define TV_CSC_V2 0x68024 | ||
932 | # define TV_BV_MASK 0x07ff0000 | ||
933 | # define TV_BV_SHIFT 16 | ||
934 | /** | ||
935 | * V attenuation for component video. | ||
936 | * | ||
937 | * Stored in 1.9 fixed point. | ||
938 | */ | ||
939 | # define TV_AV_MASK 0x000007ff | ||
940 | # define TV_AV_SHIFT 0 | ||
941 | |||
942 | #define TV_CLR_KNOBS 0x68028 | ||
943 | /** 2s-complement brightness adjustment */ | ||
944 | # define TV_BRIGHTNESS_MASK 0xff000000 | ||
945 | # define TV_BRIGHTNESS_SHIFT 24 | ||
946 | /** Contrast adjustment, as a 2.6 unsigned floating point number */ | ||
947 | # define TV_CONTRAST_MASK 0x00ff0000 | ||
948 | # define TV_CONTRAST_SHIFT 16 | ||
949 | /** Saturation adjustment, as a 2.6 unsigned floating point number */ | ||
950 | # define TV_SATURATION_MASK 0x0000ff00 | ||
951 | # define TV_SATURATION_SHIFT 8 | ||
952 | /** Hue adjustment, as an integer phase angle in degrees */ | ||
953 | # define TV_HUE_MASK 0x000000ff | ||
954 | # define TV_HUE_SHIFT 0 | ||
955 | |||
956 | #define TV_CLR_LEVEL 0x6802c | ||
957 | /** Controls the DAC level for black */ | ||
958 | # define TV_BLACK_LEVEL_MASK 0x01ff0000 | ||
959 | # define TV_BLACK_LEVEL_SHIFT 16 | ||
960 | /** Controls the DAC level for blanking */ | ||
961 | # define TV_BLANK_LEVEL_MASK 0x000001ff | ||
962 | # define TV_BLANK_LEVEL_SHIFT 0 | ||
963 | |||
964 | #define TV_H_CTL_1 0x68030 | ||
965 | /** Number of pixels in the hsync. */ | ||
966 | # define TV_HSYNC_END_MASK 0x1fff0000 | ||
967 | # define TV_HSYNC_END_SHIFT 16 | ||
968 | /** Total number of pixels minus one in the line (display and blanking). */ | ||
969 | # define TV_HTOTAL_MASK 0x00001fff | ||
970 | # define TV_HTOTAL_SHIFT 0 | ||
971 | |||
972 | #define TV_H_CTL_2 0x68034 | ||
973 | /** Enables the colorburst (needed for non-component color) */ | ||
974 | # define TV_BURST_ENA (1 << 31) | ||
975 | /** Offset of the colorburst from the start of hsync, in pixels minus one. */ | ||
976 | # define TV_HBURST_START_SHIFT 16 | ||
977 | # define TV_HBURST_START_MASK 0x1fff0000 | ||
978 | /** Length of the colorburst */ | ||
979 | # define TV_HBURST_LEN_SHIFT 0 | ||
980 | # define TV_HBURST_LEN_MASK 0x0001fff | ||
981 | |||
982 | #define TV_H_CTL_3 0x68038 | ||
983 | /** End of hblank, measured in pixels minus one from start of hsync */ | ||
984 | # define TV_HBLANK_END_SHIFT 16 | ||
985 | # define TV_HBLANK_END_MASK 0x1fff0000 | ||
986 | /** Start of hblank, measured in pixels minus one from start of hsync */ | ||
987 | # define TV_HBLANK_START_SHIFT 0 | ||
988 | # define TV_HBLANK_START_MASK 0x0001fff | ||
989 | |||
990 | #define TV_V_CTL_1 0x6803c | ||
991 | /** XXX */ | ||
992 | # define TV_NBR_END_SHIFT 16 | ||
993 | # define TV_NBR_END_MASK 0x07ff0000 | ||
994 | /** XXX */ | ||
995 | # define TV_VI_END_F1_SHIFT 8 | ||
996 | # define TV_VI_END_F1_MASK 0x00003f00 | ||
997 | /** XXX */ | ||
998 | # define TV_VI_END_F2_SHIFT 0 | ||
999 | # define TV_VI_END_F2_MASK 0x0000003f | ||
1000 | |||
1001 | #define TV_V_CTL_2 0x68040 | ||
1002 | /** Length of vsync, in half lines */ | ||
1003 | # define TV_VSYNC_LEN_MASK 0x07ff0000 | ||
1004 | # define TV_VSYNC_LEN_SHIFT 16 | ||
1005 | /** Offset of the start of vsync in field 1, measured in one less than the | ||
1006 | * number of half lines. | ||
1007 | */ | ||
1008 | # define TV_VSYNC_START_F1_MASK 0x00007f00 | ||
1009 | # define TV_VSYNC_START_F1_SHIFT 8 | ||
1010 | /** | ||
1011 | * Offset of the start of vsync in field 2, measured in one less than the | ||
1012 | * number of half lines. | ||
1013 | */ | ||
1014 | # define TV_VSYNC_START_F2_MASK 0x0000007f | ||
1015 | # define TV_VSYNC_START_F2_SHIFT 0 | ||
1016 | |||
1017 | #define TV_V_CTL_3 0x68044 | ||
1018 | /** Enables generation of the equalization signal */ | ||
1019 | # define TV_EQUAL_ENA (1 << 31) | ||
1020 | /** Length of vsync, in half lines */ | ||
1021 | # define TV_VEQ_LEN_MASK 0x007f0000 | ||
1022 | # define TV_VEQ_LEN_SHIFT 16 | ||
1023 | /** Offset of the start of equalization in field 1, measured in one less than | ||
1024 | * the number of half lines. | ||
1025 | */ | ||
1026 | # define TV_VEQ_START_F1_MASK 0x0007f00 | ||
1027 | # define TV_VEQ_START_F1_SHIFT 8 | ||
1028 | /** | ||
1029 | * Offset of the start of equalization in field 2, measured in one less than | ||
1030 | * the number of half lines. | ||
1031 | */ | ||
1032 | # define TV_VEQ_START_F2_MASK 0x000007f | ||
1033 | # define TV_VEQ_START_F2_SHIFT 0 | ||
1034 | |||
1035 | #define TV_V_CTL_4 0x68048 | ||
1036 | /** | ||
1037 | * Offset to start of vertical colorburst, measured in one less than the | ||
1038 | * number of lines from vertical start. | ||
1039 | */ | ||
1040 | # define TV_VBURST_START_F1_MASK 0x003f0000 | ||
1041 | # define TV_VBURST_START_F1_SHIFT 16 | ||
1042 | /** | ||
1043 | * Offset to the end of vertical colorburst, measured in one less than the | ||
1044 | * number of lines from the start of NBR. | ||
1045 | */ | ||
1046 | # define TV_VBURST_END_F1_MASK 0x000000ff | ||
1047 | # define TV_VBURST_END_F1_SHIFT 0 | ||
1048 | |||
1049 | #define TV_V_CTL_5 0x6804c | ||
1050 | /** | ||
1051 | * Offset to start of vertical colorburst, measured in one less than the | ||
1052 | * number of lines from vertical start. | ||
1053 | */ | ||
1054 | # define TV_VBURST_START_F2_MASK 0x003f0000 | ||
1055 | # define TV_VBURST_START_F2_SHIFT 16 | ||
1056 | /** | ||
1057 | * Offset to the end of vertical colorburst, measured in one less than the | ||
1058 | * number of lines from the start of NBR. | ||
1059 | */ | ||
1060 | # define TV_VBURST_END_F2_MASK 0x000000ff | ||
1061 | # define TV_VBURST_END_F2_SHIFT 0 | ||
1062 | |||
1063 | #define TV_V_CTL_6 0x68050 | ||
1064 | /** | ||
1065 | * Offset to start of vertical colorburst, measured in one less than the | ||
1066 | * number of lines from vertical start. | ||
1067 | */ | ||
1068 | # define TV_VBURST_START_F3_MASK 0x003f0000 | ||
1069 | # define TV_VBURST_START_F3_SHIFT 16 | ||
1070 | /** | ||
1071 | * Offset to the end of vertical colorburst, measured in one less than the | ||
1072 | * number of lines from the start of NBR. | ||
1073 | */ | ||
1074 | # define TV_VBURST_END_F3_MASK 0x000000ff | ||
1075 | # define TV_VBURST_END_F3_SHIFT 0 | ||
1076 | |||
1077 | #define TV_V_CTL_7 0x68054 | ||
1078 | /** | ||
1079 | * Offset to start of vertical colorburst, measured in one less than the | ||
1080 | * number of lines from vertical start. | ||
1081 | */ | ||
1082 | # define TV_VBURST_START_F4_MASK 0x003f0000 | ||
1083 | # define TV_VBURST_START_F4_SHIFT 16 | ||
1084 | /** | ||
1085 | * Offset to the end of vertical colorburst, measured in one less than the | ||
1086 | * number of lines from the start of NBR. | ||
1087 | */ | ||
1088 | # define TV_VBURST_END_F4_MASK 0x000000ff | ||
1089 | # define TV_VBURST_END_F4_SHIFT 0 | ||
1090 | |||
1091 | #define TV_SC_CTL_1 0x68060 | ||
1092 | /** Turns on the first subcarrier phase generation DDA */ | ||
1093 | # define TV_SC_DDA1_EN (1 << 31) | ||
1094 | /** Turns on the first subcarrier phase generation DDA */ | ||
1095 | # define TV_SC_DDA2_EN (1 << 30) | ||
1096 | /** Turns on the first subcarrier phase generation DDA */ | ||
1097 | # define TV_SC_DDA3_EN (1 << 29) | ||
1098 | /** Sets the subcarrier DDA to reset frequency every other field */ | ||
1099 | # define TV_SC_RESET_EVERY_2 (0 << 24) | ||
1100 | /** Sets the subcarrier DDA to reset frequency every fourth field */ | ||
1101 | # define TV_SC_RESET_EVERY_4 (1 << 24) | ||
1102 | /** Sets the subcarrier DDA to reset frequency every eighth field */ | ||
1103 | # define TV_SC_RESET_EVERY_8 (2 << 24) | ||
1104 | /** Sets the subcarrier DDA to never reset the frequency */ | ||
1105 | # define TV_SC_RESET_NEVER (3 << 24) | ||
1106 | /** Sets the peak amplitude of the colorburst.*/ | ||
1107 | # define TV_BURST_LEVEL_MASK 0x00ff0000 | ||
1108 | # define TV_BURST_LEVEL_SHIFT 16 | ||
1109 | /** Sets the increment of the first subcarrier phase generation DDA */ | ||
1110 | # define TV_SCDDA1_INC_MASK 0x00000fff | ||
1111 | # define TV_SCDDA1_INC_SHIFT 0 | ||
1112 | |||
1113 | #define TV_SC_CTL_2 0x68064 | ||
1114 | /** Sets the rollover for the second subcarrier phase generation DDA */ | ||
1115 | # define TV_SCDDA2_SIZE_MASK 0x7fff0000 | ||
1116 | # define TV_SCDDA2_SIZE_SHIFT 16 | ||
1117 | /** Sets the increent of the second subcarrier phase generation DDA */ | ||
1118 | # define TV_SCDDA2_INC_MASK 0x00007fff | ||
1119 | # define TV_SCDDA2_INC_SHIFT 0 | ||
1120 | |||
1121 | #define TV_SC_CTL_3 0x68068 | ||
1122 | /** Sets the rollover for the third subcarrier phase generation DDA */ | ||
1123 | # define TV_SCDDA3_SIZE_MASK 0x7fff0000 | ||
1124 | # define TV_SCDDA3_SIZE_SHIFT 16 | ||
1125 | /** Sets the increent of the third subcarrier phase generation DDA */ | ||
1126 | # define TV_SCDDA3_INC_MASK 0x00007fff | ||
1127 | # define TV_SCDDA3_INC_SHIFT 0 | ||
1128 | |||
1129 | #define TV_WIN_POS 0x68070 | ||
1130 | /** X coordinate of the display from the start of horizontal active */ | ||
1131 | # define TV_XPOS_MASK 0x1fff0000 | ||
1132 | # define TV_XPOS_SHIFT 16 | ||
1133 | /** Y coordinate of the display from the start of vertical active (NBR) */ | ||
1134 | # define TV_YPOS_MASK 0x00000fff | ||
1135 | # define TV_YPOS_SHIFT 0 | ||
1136 | |||
1137 | #define TV_WIN_SIZE 0x68074 | ||
1138 | /** Horizontal size of the display window, measured in pixels*/ | ||
1139 | # define TV_XSIZE_MASK 0x1fff0000 | ||
1140 | # define TV_XSIZE_SHIFT 16 | ||
1141 | /** | ||
1142 | * Vertical size of the display window, measured in pixels. | ||
1143 | * | ||
1144 | * Must be even for interlaced modes. | ||
1145 | */ | ||
1146 | # define TV_YSIZE_MASK 0x00000fff | ||
1147 | # define TV_YSIZE_SHIFT 0 | ||
1148 | |||
1149 | #define TV_FILTER_CTL_1 0x68080 | ||
1150 | /** | ||
1151 | * Enables automatic scaling calculation. | ||
1152 | * | ||
1153 | * If set, the rest of the registers are ignored, and the calculated values can | ||
1154 | * be read back from the register. | ||
1155 | */ | ||
1156 | # define TV_AUTO_SCALE (1 << 31) | ||
1157 | /** | ||
1158 | * Disables the vertical filter. | ||
1159 | * | ||
1160 | * This is required on modes more than 1024 pixels wide */ | ||
1161 | # define TV_V_FILTER_BYPASS (1 << 29) | ||
1162 | /** Enables adaptive vertical filtering */ | ||
1163 | # define TV_VADAPT (1 << 28) | ||
1164 | # define TV_VADAPT_MODE_MASK (3 << 26) | ||
1165 | /** Selects the least adaptive vertical filtering mode */ | ||
1166 | # define TV_VADAPT_MODE_LEAST (0 << 26) | ||
1167 | /** Selects the moderately adaptive vertical filtering mode */ | ||
1168 | # define TV_VADAPT_MODE_MODERATE (1 << 26) | ||
1169 | /** Selects the most adaptive vertical filtering mode */ | ||
1170 | # define TV_VADAPT_MODE_MOST (3 << 26) | ||
1171 | /** | ||
1172 | * Sets the horizontal scaling factor. | ||
1173 | * | ||
1174 | * This should be the fractional part of the horizontal scaling factor divided | ||
1175 | * by the oversampling rate. TV_HSCALE should be less than 1, and set to: | ||
1176 | * | ||
1177 | * (src width - 1) / ((oversample * dest width) - 1) | ||
1178 | */ | ||
1179 | # define TV_HSCALE_FRAC_MASK 0x00003fff | ||
1180 | # define TV_HSCALE_FRAC_SHIFT 0 | ||
1181 | |||
1182 | #define TV_FILTER_CTL_2 0x68084 | ||
1183 | /** | ||
1184 | * Sets the integer part of the 3.15 fixed-point vertical scaling factor. | ||
1185 | * | ||
1186 | * TV_VSCALE should be (src height - 1) / ((interlace * dest height) - 1) | ||
1187 | */ | ||
1188 | # define TV_VSCALE_INT_MASK 0x00038000 | ||
1189 | # define TV_VSCALE_INT_SHIFT 15 | ||
1190 | /** | ||
1191 | * Sets the fractional part of the 3.15 fixed-point vertical scaling factor. | ||
1192 | * | ||
1193 | * \sa TV_VSCALE_INT_MASK | ||
1194 | */ | ||
1195 | # define TV_VSCALE_FRAC_MASK 0x00007fff | ||
1196 | # define TV_VSCALE_FRAC_SHIFT 0 | ||
1197 | |||
1198 | #define TV_FILTER_CTL_3 0x68088 | ||
1199 | /** | ||
1200 | * Sets the integer part of the 3.15 fixed-point vertical scaling factor. | ||
1201 | * | ||
1202 | * TV_VSCALE should be (src height - 1) / (1/4 * (dest height - 1)) | ||
1203 | * | ||
1204 | * For progressive modes, TV_VSCALE_IP_INT should be set to zeroes. | ||
1205 | */ | ||
1206 | # define TV_VSCALE_IP_INT_MASK 0x00038000 | ||
1207 | # define TV_VSCALE_IP_INT_SHIFT 15 | ||
1208 | /** | ||
1209 | * Sets the fractional part of the 3.15 fixed-point vertical scaling factor. | ||
1210 | * | ||
1211 | * For progressive modes, TV_VSCALE_IP_INT should be set to zeroes. | ||
1212 | * | ||
1213 | * \sa TV_VSCALE_IP_INT_MASK | ||
1214 | */ | ||
1215 | # define TV_VSCALE_IP_FRAC_MASK 0x00007fff | ||
1216 | # define TV_VSCALE_IP_FRAC_SHIFT 0 | ||
1217 | |||
1218 | #define TV_CC_CONTROL 0x68090 | ||
1219 | # define TV_CC_ENABLE (1 << 31) | ||
1220 | /** | ||
1221 | * Specifies which field to send the CC data in. | ||
1222 | * | ||
1223 | * CC data is usually sent in field 0. | ||
1224 | */ | ||
1225 | # define TV_CC_FID_MASK (1 << 27) | ||
1226 | # define TV_CC_FID_SHIFT 27 | ||
1227 | /** Sets the horizontal position of the CC data. Usually 135. */ | ||
1228 | # define TV_CC_HOFF_MASK 0x03ff0000 | ||
1229 | # define TV_CC_HOFF_SHIFT 16 | ||
1230 | /** Sets the vertical position of the CC data. Usually 21 */ | ||
1231 | # define TV_CC_LINE_MASK 0x0000003f | ||
1232 | # define TV_CC_LINE_SHIFT 0 | ||
1233 | |||
1234 | #define TV_CC_DATA 0x68094 | ||
1235 | # define TV_CC_RDY (1 << 31) | ||
1236 | /** Second word of CC data to be transmitted. */ | ||
1237 | # define TV_CC_DATA_2_MASK 0x007f0000 | ||
1238 | # define TV_CC_DATA_2_SHIFT 16 | ||
1239 | /** First word of CC data to be transmitted. */ | ||
1240 | # define TV_CC_DATA_1_MASK 0x0000007f | ||
1241 | # define TV_CC_DATA_1_SHIFT 0 | ||
1242 | |||
1243 | #define TV_H_LUMA_0 0x68100 | ||
1244 | #define TV_H_LUMA_59 0x681ec | ||
1245 | #define TV_H_CHROMA_0 0x68200 | ||
1246 | #define TV_H_CHROMA_59 0x682ec | ||
1247 | #define TV_V_LUMA_0 0x68300 | ||
1248 | #define TV_V_LUMA_42 0x683a8 | ||
1249 | #define TV_V_CHROMA_0 0x68400 | ||
1250 | #define TV_V_CHROMA_42 0x684a8 | ||
1251 | |||
1252 | /* Display & cursor control */ | ||
1253 | |||
1254 | /* Pipe A */ | ||
1255 | #define PIPEADSL 0x70000 | ||
1256 | #define PIPEACONF 0x70008 | ||
1257 | #define PIPEACONF_ENABLE (1<<31) | ||
1258 | #define PIPEACONF_DISABLE 0 | ||
1259 | #define PIPEACONF_DOUBLE_WIDE (1<<30) | ||
1260 | #define I965_PIPECONF_ACTIVE (1<<30) | ||
1261 | #define PIPEACONF_SINGLE_WIDE 0 | ||
1262 | #define PIPEACONF_PIPE_UNLOCKED 0 | ||
1263 | #define PIPEACONF_PIPE_LOCKED (1<<25) | ||
1264 | #define PIPEACONF_PALETTE 0 | ||
1265 | #define PIPEACONF_GAMMA (1<<24) | ||
1266 | #define PIPECONF_FORCE_BORDER (1<<25) | ||
1267 | #define PIPECONF_PROGRESSIVE (0 << 21) | ||
1268 | #define PIPECONF_INTERLACE_W_FIELD_INDICATION (6 << 21) | ||
1269 | #define PIPECONF_INTERLACE_FIELD_0_ONLY (7 << 21) | ||
1270 | #define PIPEASTAT 0x70024 | ||
1271 | #define PIPE_FIFO_UNDERRUN_STATUS (1UL<<31) | ||
1272 | #define PIPE_CRC_ERROR_ENABLE (1UL<<29) | ||
1273 | #define PIPE_CRC_DONE_ENABLE (1UL<<28) | ||
1274 | #define PIPE_GMBUS_EVENT_ENABLE (1UL<<27) | ||
1275 | #define PIPE_HOTPLUG_INTERRUPT_ENABLE (1UL<<26) | ||
1276 | #define PIPE_VSYNC_INTERRUPT_ENABLE (1UL<<25) | ||
1277 | #define PIPE_DISPLAY_LINE_COMPARE_ENABLE (1UL<<24) | ||
1278 | #define PIPE_DPST_EVENT_ENABLE (1UL<<23) | ||
1279 | #define PIPE_LEGACY_BLC_EVENT_ENABLE (1UL<<22) | ||
1280 | #define PIPE_ODD_FIELD_INTERRUPT_ENABLE (1UL<<21) | ||
1281 | #define PIPE_EVEN_FIELD_INTERRUPT_ENABLE (1UL<<20) | ||
1282 | #define PIPE_HOTPLUG_TV_INTERRUPT_ENABLE (1UL<<18) /* pre-965 */ | ||
1283 | #define PIPE_START_VBLANK_INTERRUPT_ENABLE (1UL<<18) /* 965 or later */ | ||
1284 | #define PIPE_VBLANK_INTERRUPT_ENABLE (1UL<<17) | ||
1285 | #define PIPE_OVERLAY_UPDATED_ENABLE (1UL<<16) | ||
1286 | #define PIPE_CRC_ERROR_INTERRUPT_STATUS (1UL<<13) | ||
1287 | #define PIPE_CRC_DONE_INTERRUPT_STATUS (1UL<<12) | ||
1288 | #define PIPE_GMBUS_INTERRUPT_STATUS (1UL<<11) | ||
1289 | #define PIPE_HOTPLUG_INTERRUPT_STATUS (1UL<<10) | ||
1290 | #define PIPE_VSYNC_INTERRUPT_STATUS (1UL<<9) | ||
1291 | #define PIPE_DISPLAY_LINE_COMPARE_STATUS (1UL<<8) | ||
1292 | #define PIPE_DPST_EVENT_STATUS (1UL<<7) | ||
1293 | #define PIPE_LEGACY_BLC_EVENT_STATUS (1UL<<6) | ||
1294 | #define PIPE_ODD_FIELD_INTERRUPT_STATUS (1UL<<5) | ||
1295 | #define PIPE_EVEN_FIELD_INTERRUPT_STATUS (1UL<<4) | ||
1296 | #define PIPE_HOTPLUG_TV_INTERRUPT_STATUS (1UL<<2) /* pre-965 */ | ||
1297 | #define PIPE_START_VBLANK_INTERRUPT_STATUS (1UL<<2) /* 965 or later */ | ||
1298 | #define PIPE_VBLANK_INTERRUPT_STATUS (1UL<<1) | ||
1299 | #define PIPE_OVERLAY_UPDATED_STATUS (1UL<<0) | ||
1300 | |||
1301 | #define DSPARB 0x70030 | ||
1302 | #define DSPARB_CSTART_MASK (0x7f << 7) | ||
1303 | #define DSPARB_CSTART_SHIFT 7 | ||
1304 | #define DSPARB_BSTART_MASK (0x7f) | ||
1305 | #define DSPARB_BSTART_SHIFT 0 | ||
1306 | /* | ||
1307 | * The two pipe frame counter registers are not synchronized, so | ||
1308 | * reading a stable value is somewhat tricky. The following code | ||
1309 | * should work: | ||
1310 | * | ||
1311 | * do { | ||
1312 | * high1 = ((INREG(PIPEAFRAMEHIGH) & PIPE_FRAME_HIGH_MASK) >> | ||
1313 | * PIPE_FRAME_HIGH_SHIFT; | ||
1314 | * low1 = ((INREG(PIPEAFRAMEPIXEL) & PIPE_FRAME_LOW_MASK) >> | ||
1315 | * PIPE_FRAME_LOW_SHIFT); | ||
1316 | * high2 = ((INREG(PIPEAFRAMEHIGH) & PIPE_FRAME_HIGH_MASK) >> | ||
1317 | * PIPE_FRAME_HIGH_SHIFT); | ||
1318 | * } while (high1 != high2); | ||
1319 | * frame = (high1 << 8) | low1; | ||
1320 | */ | ||
1321 | #define PIPEAFRAMEHIGH 0x70040 | ||
1322 | #define PIPE_FRAME_HIGH_MASK 0x0000ffff | ||
1323 | #define PIPE_FRAME_HIGH_SHIFT 0 | ||
1324 | #define PIPEAFRAMEPIXEL 0x70044 | ||
1325 | #define PIPE_FRAME_LOW_MASK 0xff000000 | ||
1326 | #define PIPE_FRAME_LOW_SHIFT 24 | ||
1327 | #define PIPE_PIXEL_MASK 0x00ffffff | ||
1328 | #define PIPE_PIXEL_SHIFT 0 | ||
1329 | |||
1330 | /* Cursor A & B regs */ | ||
1331 | #define CURACNTR 0x70080 | ||
1332 | #define CURSOR_MODE_DISABLE 0x00 | ||
1333 | #define CURSOR_MODE_64_32B_AX 0x07 | ||
1334 | #define CURSOR_MODE_64_ARGB_AX ((1 << 5) | CURSOR_MODE_64_32B_AX) | ||
1335 | #define MCURSOR_GAMMA_ENABLE (1 << 26) | ||
1336 | #define CURABASE 0x70084 | ||
1337 | #define CURAPOS 0x70088 | ||
1338 | #define CURSOR_POS_MASK 0x007FF | ||
1339 | #define CURSOR_POS_SIGN 0x8000 | ||
1340 | #define CURSOR_X_SHIFT 0 | ||
1341 | #define CURSOR_Y_SHIFT 16 | ||
1342 | #define CURBCNTR 0x700c0 | ||
1343 | #define CURBBASE 0x700c4 | ||
1344 | #define CURBPOS 0x700c8 | ||
1345 | |||
1346 | /* Display A control */ | ||
1347 | #define DSPACNTR 0x70180 | ||
1348 | #define DISPLAY_PLANE_ENABLE (1<<31) | ||
1349 | #define DISPLAY_PLANE_DISABLE 0 | ||
1350 | #define DISPPLANE_GAMMA_ENABLE (1<<30) | ||
1351 | #define DISPPLANE_GAMMA_DISABLE 0 | ||
1352 | #define DISPPLANE_PIXFORMAT_MASK (0xf<<26) | ||
1353 | #define DISPPLANE_8BPP (0x2<<26) | ||
1354 | #define DISPPLANE_15_16BPP (0x4<<26) | ||
1355 | #define DISPPLANE_16BPP (0x5<<26) | ||
1356 | #define DISPPLANE_32BPP_NO_ALPHA (0x6<<26) | ||
1357 | #define DISPPLANE_32BPP (0x7<<26) | ||
1358 | #define DISPPLANE_STEREO_ENABLE (1<<25) | ||
1359 | #define DISPPLANE_STEREO_DISABLE 0 | ||
1360 | #define DISPPLANE_SEL_PIPE_MASK (1<<24) | ||
1361 | #define DISPPLANE_SEL_PIPE_A 0 | ||
1362 | #define DISPPLANE_SEL_PIPE_B (1<<24) | ||
1363 | #define DISPPLANE_SRC_KEY_ENABLE (1<<22) | ||
1364 | #define DISPPLANE_SRC_KEY_DISABLE 0 | ||
1365 | #define DISPPLANE_LINE_DOUBLE (1<<20) | ||
1366 | #define DISPPLANE_NO_LINE_DOUBLE 0 | ||
1367 | #define DISPPLANE_STEREO_POLARITY_FIRST 0 | ||
1368 | #define DISPPLANE_STEREO_POLARITY_SECOND (1<<18) | ||
1369 | #define DSPAADDR 0x70184 | ||
1370 | #define DSPASTRIDE 0x70188 | ||
1371 | #define DSPAPOS 0x7018C /* reserved */ | ||
1372 | #define DSPASIZE 0x70190 | ||
1373 | #define DSPASURF 0x7019C /* 965+ only */ | ||
1374 | #define DSPATILEOFF 0x701A4 /* 965+ only */ | ||
1375 | |||
1376 | /* VBIOS flags */ | ||
1377 | #define SWF00 0x71410 | ||
1378 | #define SWF01 0x71414 | ||
1379 | #define SWF02 0x71418 | ||
1380 | #define SWF03 0x7141c | ||
1381 | #define SWF04 0x71420 | ||
1382 | #define SWF05 0x71424 | ||
1383 | #define SWF06 0x71428 | ||
1384 | #define SWF10 0x70410 | ||
1385 | #define SWF11 0x70414 | ||
1386 | #define SWF14 0x71420 | ||
1387 | #define SWF30 0x72414 | ||
1388 | #define SWF31 0x72418 | ||
1389 | #define SWF32 0x7241c | ||
1390 | |||
1391 | /* Pipe B */ | ||
1392 | #define PIPEBDSL 0x71000 | ||
1393 | #define PIPEBCONF 0x71008 | ||
1394 | #define PIPEBSTAT 0x71024 | ||
1395 | #define PIPEBFRAMEHIGH 0x71040 | ||
1396 | #define PIPEBFRAMEPIXEL 0x71044 | ||
1397 | |||
1398 | /* Display B control */ | ||
1399 | #define DSPBCNTR 0x71180 | ||
1400 | #define DISPPLANE_ALPHA_TRANS_ENABLE (1<<15) | ||
1401 | #define DISPPLANE_ALPHA_TRANS_DISABLE 0 | ||
1402 | #define DISPPLANE_SPRITE_ABOVE_DISPLAY 0 | ||
1403 | #define DISPPLANE_SPRITE_ABOVE_OVERLAY (1) | ||
1404 | #define DSPBADDR 0x71184 | ||
1405 | #define DSPBSTRIDE 0x71188 | ||
1406 | #define DSPBPOS 0x7118C | ||
1407 | #define DSPBSIZE 0x71190 | ||
1408 | #define DSPBSURF 0x7119C | ||
1409 | #define DSPBTILEOFF 0x711A4 | ||
1410 | |||
1411 | /* VBIOS regs */ | ||
1412 | #define VGACNTRL 0x71400 | ||
1413 | # define VGA_DISP_DISABLE (1 << 31) | ||
1414 | # define VGA_2X_MODE (1 << 30) | ||
1415 | # define VGA_PIPE_B_SELECT (1 << 29) | ||
1416 | |||
1417 | #endif /* _I915_REG_H_ */ | ||
diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c new file mode 100644 index 000000000000..603fe742ccd4 --- /dev/null +++ b/drivers/gpu/drm/i915/i915_suspend.c | |||
@@ -0,0 +1,509 @@ | |||
1 | /* | ||
2 | * | ||
3 | * Copyright 2008 (c) Intel Corporation | ||
4 | * Jesse Barnes <jbarnes@virtuousgeek.org> | ||
5 | * | ||
6 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
7 | * copy of this software and associated documentation files (the | ||
8 | * "Software"), to deal in the Software without restriction, including | ||
9 | * without limitation the rights to use, copy, modify, merge, publish, | ||
10 | * distribute, sub license, and/or sell copies of the Software, and to | ||
11 | * permit persons to whom the Software is furnished to do so, subject to | ||
12 | * the following conditions: | ||
13 | * | ||
14 | * The above copyright notice and this permission notice (including the | ||
15 | * next paragraph) shall be included in all copies or substantial portions | ||
16 | * of the Software. | ||
17 | * | ||
18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | ||
19 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
20 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. | ||
21 | * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR | ||
22 | * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, | ||
23 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | ||
24 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
25 | */ | ||
26 | |||
27 | #include "drmP.h" | ||
28 | #include "drm.h" | ||
29 | #include "i915_drm.h" | ||
30 | #include "i915_drv.h" | ||
31 | |||
32 | static bool i915_pipe_enabled(struct drm_device *dev, enum pipe pipe) | ||
33 | { | ||
34 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
35 | |||
36 | if (pipe == PIPE_A) | ||
37 | return (I915_READ(DPLL_A) & DPLL_VCO_ENABLE); | ||
38 | else | ||
39 | return (I915_READ(DPLL_B) & DPLL_VCO_ENABLE); | ||
40 | } | ||
41 | |||
42 | static void i915_save_palette(struct drm_device *dev, enum pipe pipe) | ||
43 | { | ||
44 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
45 | unsigned long reg = (pipe == PIPE_A ? PALETTE_A : PALETTE_B); | ||
46 | u32 *array; | ||
47 | int i; | ||
48 | |||
49 | if (!i915_pipe_enabled(dev, pipe)) | ||
50 | return; | ||
51 | |||
52 | if (pipe == PIPE_A) | ||
53 | array = dev_priv->save_palette_a; | ||
54 | else | ||
55 | array = dev_priv->save_palette_b; | ||
56 | |||
57 | for(i = 0; i < 256; i++) | ||
58 | array[i] = I915_READ(reg + (i << 2)); | ||
59 | } | ||
60 | |||
61 | static void i915_restore_palette(struct drm_device *dev, enum pipe pipe) | ||
62 | { | ||
63 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
64 | unsigned long reg = (pipe == PIPE_A ? PALETTE_A : PALETTE_B); | ||
65 | u32 *array; | ||
66 | int i; | ||
67 | |||
68 | if (!i915_pipe_enabled(dev, pipe)) | ||
69 | return; | ||
70 | |||
71 | if (pipe == PIPE_A) | ||
72 | array = dev_priv->save_palette_a; | ||
73 | else | ||
74 | array = dev_priv->save_palette_b; | ||
75 | |||
76 | for(i = 0; i < 256; i++) | ||
77 | I915_WRITE(reg + (i << 2), array[i]); | ||
78 | } | ||
79 | |||
80 | static u8 i915_read_indexed(struct drm_device *dev, u16 index_port, u16 data_port, u8 reg) | ||
81 | { | ||
82 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
83 | |||
84 | I915_WRITE8(index_port, reg); | ||
85 | return I915_READ8(data_port); | ||
86 | } | ||
87 | |||
88 | static u8 i915_read_ar(struct drm_device *dev, u16 st01, u8 reg, u16 palette_enable) | ||
89 | { | ||
90 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
91 | |||
92 | I915_READ8(st01); | ||
93 | I915_WRITE8(VGA_AR_INDEX, palette_enable | reg); | ||
94 | return I915_READ8(VGA_AR_DATA_READ); | ||
95 | } | ||
96 | |||
97 | static void i915_write_ar(struct drm_device *dev, u16 st01, u8 reg, u8 val, u16 palette_enable) | ||
98 | { | ||
99 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
100 | |||
101 | I915_READ8(st01); | ||
102 | I915_WRITE8(VGA_AR_INDEX, palette_enable | reg); | ||
103 | I915_WRITE8(VGA_AR_DATA_WRITE, val); | ||
104 | } | ||
105 | |||
106 | static void i915_write_indexed(struct drm_device *dev, u16 index_port, u16 data_port, u8 reg, u8 val) | ||
107 | { | ||
108 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
109 | |||
110 | I915_WRITE8(index_port, reg); | ||
111 | I915_WRITE8(data_port, val); | ||
112 | } | ||
113 | |||
114 | static void i915_save_vga(struct drm_device *dev) | ||
115 | { | ||
116 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
117 | int i; | ||
118 | u16 cr_index, cr_data, st01; | ||
119 | |||
120 | /* VGA color palette registers */ | ||
121 | dev_priv->saveDACMASK = I915_READ8(VGA_DACMASK); | ||
122 | /* DACCRX automatically increments during read */ | ||
123 | I915_WRITE8(VGA_DACRX, 0); | ||
124 | /* Read 3 bytes of color data from each index */ | ||
125 | for (i = 0; i < 256 * 3; i++) | ||
126 | dev_priv->saveDACDATA[i] = I915_READ8(VGA_DACDATA); | ||
127 | |||
128 | /* MSR bits */ | ||
129 | dev_priv->saveMSR = I915_READ8(VGA_MSR_READ); | ||
130 | if (dev_priv->saveMSR & VGA_MSR_CGA_MODE) { | ||
131 | cr_index = VGA_CR_INDEX_CGA; | ||
132 | cr_data = VGA_CR_DATA_CGA; | ||
133 | st01 = VGA_ST01_CGA; | ||
134 | } else { | ||
135 | cr_index = VGA_CR_INDEX_MDA; | ||
136 | cr_data = VGA_CR_DATA_MDA; | ||
137 | st01 = VGA_ST01_MDA; | ||
138 | } | ||
139 | |||
140 | /* CRT controller regs */ | ||
141 | i915_write_indexed(dev, cr_index, cr_data, 0x11, | ||
142 | i915_read_indexed(dev, cr_index, cr_data, 0x11) & | ||
143 | (~0x80)); | ||
144 | for (i = 0; i <= 0x24; i++) | ||
145 | dev_priv->saveCR[i] = | ||
146 | i915_read_indexed(dev, cr_index, cr_data, i); | ||
147 | /* Make sure we don't turn off CR group 0 writes */ | ||
148 | dev_priv->saveCR[0x11] &= ~0x80; | ||
149 | |||
150 | /* Attribute controller registers */ | ||
151 | I915_READ8(st01); | ||
152 | dev_priv->saveAR_INDEX = I915_READ8(VGA_AR_INDEX); | ||
153 | for (i = 0; i <= 0x14; i++) | ||
154 | dev_priv->saveAR[i] = i915_read_ar(dev, st01, i, 0); | ||
155 | I915_READ8(st01); | ||
156 | I915_WRITE8(VGA_AR_INDEX, dev_priv->saveAR_INDEX); | ||
157 | I915_READ8(st01); | ||
158 | |||
159 | /* Graphics controller registers */ | ||
160 | for (i = 0; i < 9; i++) | ||
161 | dev_priv->saveGR[i] = | ||
162 | i915_read_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, i); | ||
163 | |||
164 | dev_priv->saveGR[0x10] = | ||
165 | i915_read_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x10); | ||
166 | dev_priv->saveGR[0x11] = | ||
167 | i915_read_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x11); | ||
168 | dev_priv->saveGR[0x18] = | ||
169 | i915_read_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x18); | ||
170 | |||
171 | /* Sequencer registers */ | ||
172 | for (i = 0; i < 8; i++) | ||
173 | dev_priv->saveSR[i] = | ||
174 | i915_read_indexed(dev, VGA_SR_INDEX, VGA_SR_DATA, i); | ||
175 | } | ||
176 | |||
177 | static void i915_restore_vga(struct drm_device *dev) | ||
178 | { | ||
179 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
180 | int i; | ||
181 | u16 cr_index, cr_data, st01; | ||
182 | |||
183 | /* MSR bits */ | ||
184 | I915_WRITE8(VGA_MSR_WRITE, dev_priv->saveMSR); | ||
185 | if (dev_priv->saveMSR & VGA_MSR_CGA_MODE) { | ||
186 | cr_index = VGA_CR_INDEX_CGA; | ||
187 | cr_data = VGA_CR_DATA_CGA; | ||
188 | st01 = VGA_ST01_CGA; | ||
189 | } else { | ||
190 | cr_index = VGA_CR_INDEX_MDA; | ||
191 | cr_data = VGA_CR_DATA_MDA; | ||
192 | st01 = VGA_ST01_MDA; | ||
193 | } | ||
194 | |||
195 | /* Sequencer registers, don't write SR07 */ | ||
196 | for (i = 0; i < 7; i++) | ||
197 | i915_write_indexed(dev, VGA_SR_INDEX, VGA_SR_DATA, i, | ||
198 | dev_priv->saveSR[i]); | ||
199 | |||
200 | /* CRT controller regs */ | ||
201 | /* Enable CR group 0 writes */ | ||
202 | i915_write_indexed(dev, cr_index, cr_data, 0x11, dev_priv->saveCR[0x11]); | ||
203 | for (i = 0; i <= 0x24; i++) | ||
204 | i915_write_indexed(dev, cr_index, cr_data, i, dev_priv->saveCR[i]); | ||
205 | |||
206 | /* Graphics controller regs */ | ||
207 | for (i = 0; i < 9; i++) | ||
208 | i915_write_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, i, | ||
209 | dev_priv->saveGR[i]); | ||
210 | |||
211 | i915_write_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x10, | ||
212 | dev_priv->saveGR[0x10]); | ||
213 | i915_write_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x11, | ||
214 | dev_priv->saveGR[0x11]); | ||
215 | i915_write_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x18, | ||
216 | dev_priv->saveGR[0x18]); | ||
217 | |||
218 | /* Attribute controller registers */ | ||
219 | I915_READ8(st01); /* switch back to index mode */ | ||
220 | for (i = 0; i <= 0x14; i++) | ||
221 | i915_write_ar(dev, st01, i, dev_priv->saveAR[i], 0); | ||
222 | I915_READ8(st01); /* switch back to index mode */ | ||
223 | I915_WRITE8(VGA_AR_INDEX, dev_priv->saveAR_INDEX | 0x20); | ||
224 | I915_READ8(st01); | ||
225 | |||
226 | /* VGA color palette registers */ | ||
227 | I915_WRITE8(VGA_DACMASK, dev_priv->saveDACMASK); | ||
228 | /* DACCRX automatically increments during read */ | ||
229 | I915_WRITE8(VGA_DACWX, 0); | ||
230 | /* Read 3 bytes of color data from each index */ | ||
231 | for (i = 0; i < 256 * 3; i++) | ||
232 | I915_WRITE8(VGA_DACDATA, dev_priv->saveDACDATA[i]); | ||
233 | |||
234 | } | ||
235 | |||
236 | int i915_save_state(struct drm_device *dev) | ||
237 | { | ||
238 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
239 | int i; | ||
240 | |||
241 | pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB); | ||
242 | |||
243 | /* Display arbitration control */ | ||
244 | dev_priv->saveDSPARB = I915_READ(DSPARB); | ||
245 | |||
246 | /* Pipe & plane A info */ | ||
247 | dev_priv->savePIPEACONF = I915_READ(PIPEACONF); | ||
248 | dev_priv->savePIPEASRC = I915_READ(PIPEASRC); | ||
249 | dev_priv->saveFPA0 = I915_READ(FPA0); | ||
250 | dev_priv->saveFPA1 = I915_READ(FPA1); | ||
251 | dev_priv->saveDPLL_A = I915_READ(DPLL_A); | ||
252 | if (IS_I965G(dev)) | ||
253 | dev_priv->saveDPLL_A_MD = I915_READ(DPLL_A_MD); | ||
254 | dev_priv->saveHTOTAL_A = I915_READ(HTOTAL_A); | ||
255 | dev_priv->saveHBLANK_A = I915_READ(HBLANK_A); | ||
256 | dev_priv->saveHSYNC_A = I915_READ(HSYNC_A); | ||
257 | dev_priv->saveVTOTAL_A = I915_READ(VTOTAL_A); | ||
258 | dev_priv->saveVBLANK_A = I915_READ(VBLANK_A); | ||
259 | dev_priv->saveVSYNC_A = I915_READ(VSYNC_A); | ||
260 | dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A); | ||
261 | |||
262 | dev_priv->saveDSPACNTR = I915_READ(DSPACNTR); | ||
263 | dev_priv->saveDSPASTRIDE = I915_READ(DSPASTRIDE); | ||
264 | dev_priv->saveDSPASIZE = I915_READ(DSPASIZE); | ||
265 | dev_priv->saveDSPAPOS = I915_READ(DSPAPOS); | ||
266 | dev_priv->saveDSPAADDR = I915_READ(DSPAADDR); | ||
267 | if (IS_I965G(dev)) { | ||
268 | dev_priv->saveDSPASURF = I915_READ(DSPASURF); | ||
269 | dev_priv->saveDSPATILEOFF = I915_READ(DSPATILEOFF); | ||
270 | } | ||
271 | i915_save_palette(dev, PIPE_A); | ||
272 | dev_priv->savePIPEASTAT = I915_READ(PIPEASTAT); | ||
273 | |||
274 | /* Pipe & plane B info */ | ||
275 | dev_priv->savePIPEBCONF = I915_READ(PIPEBCONF); | ||
276 | dev_priv->savePIPEBSRC = I915_READ(PIPEBSRC); | ||
277 | dev_priv->saveFPB0 = I915_READ(FPB0); | ||
278 | dev_priv->saveFPB1 = I915_READ(FPB1); | ||
279 | dev_priv->saveDPLL_B = I915_READ(DPLL_B); | ||
280 | if (IS_I965G(dev)) | ||
281 | dev_priv->saveDPLL_B_MD = I915_READ(DPLL_B_MD); | ||
282 | dev_priv->saveHTOTAL_B = I915_READ(HTOTAL_B); | ||
283 | dev_priv->saveHBLANK_B = I915_READ(HBLANK_B); | ||
284 | dev_priv->saveHSYNC_B = I915_READ(HSYNC_B); | ||
285 | dev_priv->saveVTOTAL_B = I915_READ(VTOTAL_B); | ||
286 | dev_priv->saveVBLANK_B = I915_READ(VBLANK_B); | ||
287 | dev_priv->saveVSYNC_B = I915_READ(VSYNC_B); | ||
288 | dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A); | ||
289 | |||
290 | dev_priv->saveDSPBCNTR = I915_READ(DSPBCNTR); | ||
291 | dev_priv->saveDSPBSTRIDE = I915_READ(DSPBSTRIDE); | ||
292 | dev_priv->saveDSPBSIZE = I915_READ(DSPBSIZE); | ||
293 | dev_priv->saveDSPBPOS = I915_READ(DSPBPOS); | ||
294 | dev_priv->saveDSPBADDR = I915_READ(DSPBADDR); | ||
295 | if (IS_I965GM(dev) || IS_GM45(dev)) { | ||
296 | dev_priv->saveDSPBSURF = I915_READ(DSPBSURF); | ||
297 | dev_priv->saveDSPBTILEOFF = I915_READ(DSPBTILEOFF); | ||
298 | } | ||
299 | i915_save_palette(dev, PIPE_B); | ||
300 | dev_priv->savePIPEBSTAT = I915_READ(PIPEBSTAT); | ||
301 | |||
302 | /* CRT state */ | ||
303 | dev_priv->saveADPA = I915_READ(ADPA); | ||
304 | |||
305 | /* LVDS state */ | ||
306 | dev_priv->savePP_CONTROL = I915_READ(PP_CONTROL); | ||
307 | dev_priv->savePFIT_PGM_RATIOS = I915_READ(PFIT_PGM_RATIOS); | ||
308 | dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_CTL); | ||
309 | if (IS_I965G(dev)) | ||
310 | dev_priv->saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_CTL2); | ||
311 | if (IS_MOBILE(dev) && !IS_I830(dev)) | ||
312 | dev_priv->saveLVDS = I915_READ(LVDS); | ||
313 | if (!IS_I830(dev) && !IS_845G(dev)) | ||
314 | dev_priv->savePFIT_CONTROL = I915_READ(PFIT_CONTROL); | ||
315 | dev_priv->savePP_ON_DELAYS = I915_READ(PP_ON_DELAYS); | ||
316 | dev_priv->savePP_OFF_DELAYS = I915_READ(PP_OFF_DELAYS); | ||
317 | dev_priv->savePP_DIVISOR = I915_READ(PP_DIVISOR); | ||
318 | |||
319 | /* FIXME: save TV & SDVO state */ | ||
320 | |||
321 | /* FBC state */ | ||
322 | dev_priv->saveFBC_CFB_BASE = I915_READ(FBC_CFB_BASE); | ||
323 | dev_priv->saveFBC_LL_BASE = I915_READ(FBC_LL_BASE); | ||
324 | dev_priv->saveFBC_CONTROL2 = I915_READ(FBC_CONTROL2); | ||
325 | dev_priv->saveFBC_CONTROL = I915_READ(FBC_CONTROL); | ||
326 | |||
327 | /* Interrupt state */ | ||
328 | dev_priv->saveIIR = I915_READ(IIR); | ||
329 | dev_priv->saveIER = I915_READ(IER); | ||
330 | dev_priv->saveIMR = I915_READ(IMR); | ||
331 | |||
332 | /* VGA state */ | ||
333 | dev_priv->saveVGA0 = I915_READ(VGA0); | ||
334 | dev_priv->saveVGA1 = I915_READ(VGA1); | ||
335 | dev_priv->saveVGA_PD = I915_READ(VGA_PD); | ||
336 | dev_priv->saveVGACNTRL = I915_READ(VGACNTRL); | ||
337 | |||
338 | /* Clock gating state */ | ||
339 | dev_priv->saveD_STATE = I915_READ(D_STATE); | ||
340 | dev_priv->saveCG_2D_DIS = I915_READ(CG_2D_DIS); | ||
341 | |||
342 | /* Cache mode state */ | ||
343 | dev_priv->saveCACHE_MODE_0 = I915_READ(CACHE_MODE_0); | ||
344 | |||
345 | /* Memory Arbitration state */ | ||
346 | dev_priv->saveMI_ARB_STATE = I915_READ(MI_ARB_STATE); | ||
347 | |||
348 | /* Scratch space */ | ||
349 | for (i = 0; i < 16; i++) { | ||
350 | dev_priv->saveSWF0[i] = I915_READ(SWF00 + (i << 2)); | ||
351 | dev_priv->saveSWF1[i] = I915_READ(SWF10 + (i << 2)); | ||
352 | } | ||
353 | for (i = 0; i < 3; i++) | ||
354 | dev_priv->saveSWF2[i] = I915_READ(SWF30 + (i << 2)); | ||
355 | |||
356 | i915_save_vga(dev); | ||
357 | |||
358 | return 0; | ||
359 | } | ||
360 | |||
361 | int i915_restore_state(struct drm_device *dev) | ||
362 | { | ||
363 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
364 | int i; | ||
365 | |||
366 | pci_write_config_byte(dev->pdev, LBB, dev_priv->saveLBB); | ||
367 | |||
368 | I915_WRITE(DSPARB, dev_priv->saveDSPARB); | ||
369 | |||
370 | /* Pipe & plane A info */ | ||
371 | /* Prime the clock */ | ||
372 | if (dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) { | ||
373 | I915_WRITE(DPLL_A, dev_priv->saveDPLL_A & | ||
374 | ~DPLL_VCO_ENABLE); | ||
375 | DRM_UDELAY(150); | ||
376 | } | ||
377 | I915_WRITE(FPA0, dev_priv->saveFPA0); | ||
378 | I915_WRITE(FPA1, dev_priv->saveFPA1); | ||
379 | /* Actually enable it */ | ||
380 | I915_WRITE(DPLL_A, dev_priv->saveDPLL_A); | ||
381 | DRM_UDELAY(150); | ||
382 | if (IS_I965G(dev)) | ||
383 | I915_WRITE(DPLL_A_MD, dev_priv->saveDPLL_A_MD); | ||
384 | DRM_UDELAY(150); | ||
385 | |||
386 | /* Restore mode */ | ||
387 | I915_WRITE(HTOTAL_A, dev_priv->saveHTOTAL_A); | ||
388 | I915_WRITE(HBLANK_A, dev_priv->saveHBLANK_A); | ||
389 | I915_WRITE(HSYNC_A, dev_priv->saveHSYNC_A); | ||
390 | I915_WRITE(VTOTAL_A, dev_priv->saveVTOTAL_A); | ||
391 | I915_WRITE(VBLANK_A, dev_priv->saveVBLANK_A); | ||
392 | I915_WRITE(VSYNC_A, dev_priv->saveVSYNC_A); | ||
393 | I915_WRITE(BCLRPAT_A, dev_priv->saveBCLRPAT_A); | ||
394 | |||
395 | /* Restore plane info */ | ||
396 | I915_WRITE(DSPASIZE, dev_priv->saveDSPASIZE); | ||
397 | I915_WRITE(DSPAPOS, dev_priv->saveDSPAPOS); | ||
398 | I915_WRITE(PIPEASRC, dev_priv->savePIPEASRC); | ||
399 | I915_WRITE(DSPAADDR, dev_priv->saveDSPAADDR); | ||
400 | I915_WRITE(DSPASTRIDE, dev_priv->saveDSPASTRIDE); | ||
401 | if (IS_I965G(dev)) { | ||
402 | I915_WRITE(DSPASURF, dev_priv->saveDSPASURF); | ||
403 | I915_WRITE(DSPATILEOFF, dev_priv->saveDSPATILEOFF); | ||
404 | } | ||
405 | |||
406 | I915_WRITE(PIPEACONF, dev_priv->savePIPEACONF); | ||
407 | |||
408 | i915_restore_palette(dev, PIPE_A); | ||
409 | /* Enable the plane */ | ||
410 | I915_WRITE(DSPACNTR, dev_priv->saveDSPACNTR); | ||
411 | I915_WRITE(DSPAADDR, I915_READ(DSPAADDR)); | ||
412 | |||
413 | /* Pipe & plane B info */ | ||
414 | if (dev_priv->saveDPLL_B & DPLL_VCO_ENABLE) { | ||
415 | I915_WRITE(DPLL_B, dev_priv->saveDPLL_B & | ||
416 | ~DPLL_VCO_ENABLE); | ||
417 | DRM_UDELAY(150); | ||
418 | } | ||
419 | I915_WRITE(FPB0, dev_priv->saveFPB0); | ||
420 | I915_WRITE(FPB1, dev_priv->saveFPB1); | ||
421 | /* Actually enable it */ | ||
422 | I915_WRITE(DPLL_B, dev_priv->saveDPLL_B); | ||
423 | DRM_UDELAY(150); | ||
424 | if (IS_I965G(dev)) | ||
425 | I915_WRITE(DPLL_B_MD, dev_priv->saveDPLL_B_MD); | ||
426 | DRM_UDELAY(150); | ||
427 | |||
428 | /* Restore mode */ | ||
429 | I915_WRITE(HTOTAL_B, dev_priv->saveHTOTAL_B); | ||
430 | I915_WRITE(HBLANK_B, dev_priv->saveHBLANK_B); | ||
431 | I915_WRITE(HSYNC_B, dev_priv->saveHSYNC_B); | ||
432 | I915_WRITE(VTOTAL_B, dev_priv->saveVTOTAL_B); | ||
433 | I915_WRITE(VBLANK_B, dev_priv->saveVBLANK_B); | ||
434 | I915_WRITE(VSYNC_B, dev_priv->saveVSYNC_B); | ||
435 | I915_WRITE(BCLRPAT_B, dev_priv->saveBCLRPAT_B); | ||
436 | |||
437 | /* Restore plane info */ | ||
438 | I915_WRITE(DSPBSIZE, dev_priv->saveDSPBSIZE); | ||
439 | I915_WRITE(DSPBPOS, dev_priv->saveDSPBPOS); | ||
440 | I915_WRITE(PIPEBSRC, dev_priv->savePIPEBSRC); | ||
441 | I915_WRITE(DSPBADDR, dev_priv->saveDSPBADDR); | ||
442 | I915_WRITE(DSPBSTRIDE, dev_priv->saveDSPBSTRIDE); | ||
443 | if (IS_I965G(dev)) { | ||
444 | I915_WRITE(DSPBSURF, dev_priv->saveDSPBSURF); | ||
445 | I915_WRITE(DSPBTILEOFF, dev_priv->saveDSPBTILEOFF); | ||
446 | } | ||
447 | |||
448 | I915_WRITE(PIPEBCONF, dev_priv->savePIPEBCONF); | ||
449 | |||
450 | i915_restore_palette(dev, PIPE_B); | ||
451 | /* Enable the plane */ | ||
452 | I915_WRITE(DSPBCNTR, dev_priv->saveDSPBCNTR); | ||
453 | I915_WRITE(DSPBADDR, I915_READ(DSPBADDR)); | ||
454 | |||
455 | /* CRT state */ | ||
456 | I915_WRITE(ADPA, dev_priv->saveADPA); | ||
457 | |||
458 | /* LVDS state */ | ||
459 | if (IS_I965G(dev)) | ||
460 | I915_WRITE(BLC_PWM_CTL2, dev_priv->saveBLC_PWM_CTL2); | ||
461 | if (IS_MOBILE(dev) && !IS_I830(dev)) | ||
462 | I915_WRITE(LVDS, dev_priv->saveLVDS); | ||
463 | if (!IS_I830(dev) && !IS_845G(dev)) | ||
464 | I915_WRITE(PFIT_CONTROL, dev_priv->savePFIT_CONTROL); | ||
465 | |||
466 | I915_WRITE(PFIT_PGM_RATIOS, dev_priv->savePFIT_PGM_RATIOS); | ||
467 | I915_WRITE(BLC_PWM_CTL, dev_priv->saveBLC_PWM_CTL); | ||
468 | I915_WRITE(PP_ON_DELAYS, dev_priv->savePP_ON_DELAYS); | ||
469 | I915_WRITE(PP_OFF_DELAYS, dev_priv->savePP_OFF_DELAYS); | ||
470 | I915_WRITE(PP_DIVISOR, dev_priv->savePP_DIVISOR); | ||
471 | I915_WRITE(PP_CONTROL, dev_priv->savePP_CONTROL); | ||
472 | |||
473 | /* FIXME: restore TV & SDVO state */ | ||
474 | |||
475 | /* FBC info */ | ||
476 | I915_WRITE(FBC_CFB_BASE, dev_priv->saveFBC_CFB_BASE); | ||
477 | I915_WRITE(FBC_LL_BASE, dev_priv->saveFBC_LL_BASE); | ||
478 | I915_WRITE(FBC_CONTROL2, dev_priv->saveFBC_CONTROL2); | ||
479 | I915_WRITE(FBC_CONTROL, dev_priv->saveFBC_CONTROL); | ||
480 | |||
481 | /* VGA state */ | ||
482 | I915_WRITE(VGACNTRL, dev_priv->saveVGACNTRL); | ||
483 | I915_WRITE(VGA0, dev_priv->saveVGA0); | ||
484 | I915_WRITE(VGA1, dev_priv->saveVGA1); | ||
485 | I915_WRITE(VGA_PD, dev_priv->saveVGA_PD); | ||
486 | DRM_UDELAY(150); | ||
487 | |||
488 | /* Clock gating state */ | ||
489 | I915_WRITE (D_STATE, dev_priv->saveD_STATE); | ||
490 | I915_WRITE (CG_2D_DIS, dev_priv->saveCG_2D_DIS); | ||
491 | |||
492 | /* Cache mode state */ | ||
493 | I915_WRITE (CACHE_MODE_0, dev_priv->saveCACHE_MODE_0 | 0xffff0000); | ||
494 | |||
495 | /* Memory arbitration state */ | ||
496 | I915_WRITE (MI_ARB_STATE, dev_priv->saveMI_ARB_STATE | 0xffff0000); | ||
497 | |||
498 | for (i = 0; i < 16; i++) { | ||
499 | I915_WRITE(SWF00 + (i << 2), dev_priv->saveSWF0[i]); | ||
500 | I915_WRITE(SWF10 + (i << 2), dev_priv->saveSWF1[i+7]); | ||
501 | } | ||
502 | for (i = 0; i < 3; i++) | ||
503 | I915_WRITE(SWF30 + (i << 2), dev_priv->saveSWF2[i]); | ||
504 | |||
505 | i915_restore_vga(dev); | ||
506 | |||
507 | return 0; | ||
508 | } | ||
509 | |||
diff --git a/drivers/gpu/drm/mga/mga_drv.c b/drivers/gpu/drm/mga/mga_drv.c index 5572939fc7d1..97ee566ef749 100644 --- a/drivers/gpu/drm/mga/mga_drv.c +++ b/drivers/gpu/drm/mga/mga_drv.c | |||
@@ -45,15 +45,16 @@ static struct pci_device_id pciidlist[] = { | |||
45 | static struct drm_driver driver = { | 45 | static struct drm_driver driver = { |
46 | .driver_features = | 46 | .driver_features = |
47 | DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | | 47 | DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | |
48 | DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | | 48 | DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED, |
49 | DRIVER_IRQ_VBL, | ||
50 | .dev_priv_size = sizeof(drm_mga_buf_priv_t), | 49 | .dev_priv_size = sizeof(drm_mga_buf_priv_t), |
51 | .load = mga_driver_load, | 50 | .load = mga_driver_load, |
52 | .unload = mga_driver_unload, | 51 | .unload = mga_driver_unload, |
53 | .lastclose = mga_driver_lastclose, | 52 | .lastclose = mga_driver_lastclose, |
54 | .dma_quiescent = mga_driver_dma_quiescent, | 53 | .dma_quiescent = mga_driver_dma_quiescent, |
55 | .device_is_agp = mga_driver_device_is_agp, | 54 | .device_is_agp = mga_driver_device_is_agp, |
56 | .vblank_wait = mga_driver_vblank_wait, | 55 | .get_vblank_counter = mga_get_vblank_counter, |
56 | .enable_vblank = mga_enable_vblank, | ||
57 | .disable_vblank = mga_disable_vblank, | ||
57 | .irq_preinstall = mga_driver_irq_preinstall, | 58 | .irq_preinstall = mga_driver_irq_preinstall, |
58 | .irq_postinstall = mga_driver_irq_postinstall, | 59 | .irq_postinstall = mga_driver_irq_postinstall, |
59 | .irq_uninstall = mga_driver_irq_uninstall, | 60 | .irq_uninstall = mga_driver_irq_uninstall, |
@@ -64,20 +65,20 @@ static struct drm_driver driver = { | |||
64 | .ioctls = mga_ioctls, | 65 | .ioctls = mga_ioctls, |
65 | .dma_ioctl = mga_dma_buffers, | 66 | .dma_ioctl = mga_dma_buffers, |
66 | .fops = { | 67 | .fops = { |
67 | .owner = THIS_MODULE, | 68 | .owner = THIS_MODULE, |
68 | .open = drm_open, | 69 | .open = drm_open, |
69 | .release = drm_release, | 70 | .release = drm_release, |
70 | .ioctl = drm_ioctl, | 71 | .ioctl = drm_ioctl, |
71 | .mmap = drm_mmap, | 72 | .mmap = drm_mmap, |
72 | .poll = drm_poll, | 73 | .poll = drm_poll, |
73 | .fasync = drm_fasync, | 74 | .fasync = drm_fasync, |
74 | #ifdef CONFIG_COMPAT | 75 | #ifdef CONFIG_COMPAT |
75 | .compat_ioctl = mga_compat_ioctl, | 76 | .compat_ioctl = mga_compat_ioctl, |
76 | #endif | 77 | #endif |
77 | }, | 78 | }, |
78 | .pci_driver = { | 79 | .pci_driver = { |
79 | .name = DRIVER_NAME, | 80 | .name = DRIVER_NAME, |
80 | .id_table = pciidlist, | 81 | .id_table = pciidlist, |
81 | }, | 82 | }, |
82 | 83 | ||
83 | .name = DRIVER_NAME, | 84 | .name = DRIVER_NAME, |
diff --git a/drivers/gpu/drm/mga/mga_drv.h b/drivers/gpu/drm/mga/mga_drv.h index f6ebd24bd587..88257c276eb9 100644 --- a/drivers/gpu/drm/mga/mga_drv.h +++ b/drivers/gpu/drm/mga/mga_drv.h | |||
@@ -120,6 +120,7 @@ typedef struct drm_mga_private { | |||
120 | u32 clear_cmd; | 120 | u32 clear_cmd; |
121 | u32 maccess; | 121 | u32 maccess; |
122 | 122 | ||
123 | atomic_t vbl_received; /**< Number of vblanks received. */ | ||
123 | wait_queue_head_t fence_queue; | 124 | wait_queue_head_t fence_queue; |
124 | atomic_t last_fence_retired; | 125 | atomic_t last_fence_retired; |
125 | u32 next_fence_to_post; | 126 | u32 next_fence_to_post; |
@@ -181,11 +182,14 @@ extern int mga_warp_install_microcode(drm_mga_private_t * dev_priv); | |||
181 | extern int mga_warp_init(drm_mga_private_t * dev_priv); | 182 | extern int mga_warp_init(drm_mga_private_t * dev_priv); |
182 | 183 | ||
183 | /* mga_irq.c */ | 184 | /* mga_irq.c */ |
185 | extern int mga_enable_vblank(struct drm_device *dev, int crtc); | ||
186 | extern void mga_disable_vblank(struct drm_device *dev, int crtc); | ||
187 | extern u32 mga_get_vblank_counter(struct drm_device *dev, int crtc); | ||
184 | extern int mga_driver_fence_wait(struct drm_device * dev, unsigned int *sequence); | 188 | extern int mga_driver_fence_wait(struct drm_device * dev, unsigned int *sequence); |
185 | extern int mga_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence); | 189 | extern int mga_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence); |
186 | extern irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS); | 190 | extern irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS); |
187 | extern void mga_driver_irq_preinstall(struct drm_device * dev); | 191 | extern void mga_driver_irq_preinstall(struct drm_device * dev); |
188 | extern void mga_driver_irq_postinstall(struct drm_device * dev); | 192 | extern int mga_driver_irq_postinstall(struct drm_device *dev); |
189 | extern void mga_driver_irq_uninstall(struct drm_device * dev); | 193 | extern void mga_driver_irq_uninstall(struct drm_device * dev); |
190 | extern long mga_compat_ioctl(struct file *filp, unsigned int cmd, | 194 | extern long mga_compat_ioctl(struct file *filp, unsigned int cmd, |
191 | unsigned long arg); | 195 | unsigned long arg); |
diff --git a/drivers/gpu/drm/mga/mga_irq.c b/drivers/gpu/drm/mga/mga_irq.c index 9302cb8f0f83..bab42f41188b 100644 --- a/drivers/gpu/drm/mga/mga_irq.c +++ b/drivers/gpu/drm/mga/mga_irq.c | |||
@@ -1,5 +1,6 @@ | |||
1 | /* mga_irq.c -- IRQ handling for radeon -*- linux-c -*- | 1 | /* mga_irq.c -- IRQ handling for radeon -*- linux-c -*- |
2 | * | 2 | */ |
3 | /* | ||
3 | * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. | 4 | * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. |
4 | * | 5 | * |
5 | * The Weather Channel (TM) funded Tungsten Graphics to develop the | 6 | * The Weather Channel (TM) funded Tungsten Graphics to develop the |
@@ -35,6 +36,18 @@ | |||
35 | #include "mga_drm.h" | 36 | #include "mga_drm.h" |
36 | #include "mga_drv.h" | 37 | #include "mga_drv.h" |
37 | 38 | ||
39 | u32 mga_get_vblank_counter(struct drm_device *dev, int crtc) | ||
40 | { | ||
41 | const drm_mga_private_t *const dev_priv = | ||
42 | (drm_mga_private_t *) dev->dev_private; | ||
43 | |||
44 | if (crtc != 0) | ||
45 | return 0; | ||
46 | |||
47 | return atomic_read(&dev_priv->vbl_received); | ||
48 | } | ||
49 | |||
50 | |||
38 | irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS) | 51 | irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS) |
39 | { | 52 | { |
40 | struct drm_device *dev = (struct drm_device *) arg; | 53 | struct drm_device *dev = (struct drm_device *) arg; |
@@ -47,9 +60,8 @@ irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS) | |||
47 | /* VBLANK interrupt */ | 60 | /* VBLANK interrupt */ |
48 | if (status & MGA_VLINEPEN) { | 61 | if (status & MGA_VLINEPEN) { |
49 | MGA_WRITE(MGA_ICLEAR, MGA_VLINEICLR); | 62 | MGA_WRITE(MGA_ICLEAR, MGA_VLINEICLR); |
50 | atomic_inc(&dev->vbl_received); | 63 | atomic_inc(&dev_priv->vbl_received); |
51 | DRM_WAKEUP(&dev->vbl_queue); | 64 | drm_handle_vblank(dev, 0); |
52 | drm_vbl_send_signals(dev); | ||
53 | handled = 1; | 65 | handled = 1; |
54 | } | 66 | } |
55 | 67 | ||
@@ -58,6 +70,7 @@ irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS) | |||
58 | const u32 prim_start = MGA_READ(MGA_PRIMADDRESS); | 70 | const u32 prim_start = MGA_READ(MGA_PRIMADDRESS); |
59 | const u32 prim_end = MGA_READ(MGA_PRIMEND); | 71 | const u32 prim_end = MGA_READ(MGA_PRIMEND); |
60 | 72 | ||
73 | |||
61 | MGA_WRITE(MGA_ICLEAR, MGA_SOFTRAPICLR); | 74 | MGA_WRITE(MGA_ICLEAR, MGA_SOFTRAPICLR); |
62 | 75 | ||
63 | /* In addition to clearing the interrupt-pending bit, we | 76 | /* In addition to clearing the interrupt-pending bit, we |
@@ -72,28 +85,39 @@ irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS) | |||
72 | handled = 1; | 85 | handled = 1; |
73 | } | 86 | } |
74 | 87 | ||
75 | if (handled) { | 88 | if (handled) |
76 | return IRQ_HANDLED; | 89 | return IRQ_HANDLED; |
77 | } | ||
78 | return IRQ_NONE; | 90 | return IRQ_NONE; |
79 | } | 91 | } |
80 | 92 | ||
81 | int mga_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence) | 93 | int mga_enable_vblank(struct drm_device *dev, int crtc) |
82 | { | 94 | { |
83 | unsigned int cur_vblank; | 95 | drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; |
84 | int ret = 0; | ||
85 | 96 | ||
86 | /* Assume that the user has missed the current sequence number | 97 | if (crtc != 0) { |
87 | * by about a day rather than she wants to wait for years | 98 | DRM_ERROR("tried to enable vblank on non-existent crtc %d\n", |
88 | * using vertical blanks... | 99 | crtc); |
89 | */ | 100 | return 0; |
90 | DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ, | 101 | } |
91 | (((cur_vblank = atomic_read(&dev->vbl_received)) | ||
92 | - *sequence) <= (1 << 23))); | ||
93 | 102 | ||
94 | *sequence = cur_vblank; | 103 | MGA_WRITE(MGA_IEN, MGA_VLINEIEN | MGA_SOFTRAPEN); |
104 | return 0; | ||
105 | } | ||
95 | 106 | ||
96 | return ret; | 107 | |
108 | void mga_disable_vblank(struct drm_device *dev, int crtc) | ||
109 | { | ||
110 | if (crtc != 0) { | ||
111 | DRM_ERROR("tried to disable vblank on non-existent crtc %d\n", | ||
112 | crtc); | ||
113 | } | ||
114 | |||
115 | /* Do *NOT* disable the vertical refresh interrupt. MGA doesn't have | ||
116 | * a nice hardware counter that tracks the number of refreshes when | ||
117 | * the interrupt is disabled, and the kernel doesn't know the refresh | ||
118 | * rate to calculate an estimate. | ||
119 | */ | ||
120 | /* MGA_WRITE(MGA_IEN, MGA_VLINEIEN | MGA_SOFTRAPEN); */ | ||
97 | } | 121 | } |
98 | 122 | ||
99 | int mga_driver_fence_wait(struct drm_device * dev, unsigned int *sequence) | 123 | int mga_driver_fence_wait(struct drm_device * dev, unsigned int *sequence) |
@@ -125,14 +149,22 @@ void mga_driver_irq_preinstall(struct drm_device * dev) | |||
125 | MGA_WRITE(MGA_ICLEAR, ~0); | 149 | MGA_WRITE(MGA_ICLEAR, ~0); |
126 | } | 150 | } |
127 | 151 | ||
128 | void mga_driver_irq_postinstall(struct drm_device * dev) | 152 | int mga_driver_irq_postinstall(struct drm_device *dev) |
129 | { | 153 | { |
130 | drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; | 154 | drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; |
155 | int ret; | ||
156 | |||
157 | ret = drm_vblank_init(dev, 1); | ||
158 | if (ret) | ||
159 | return ret; | ||
131 | 160 | ||
132 | DRM_INIT_WAITQUEUE(&dev_priv->fence_queue); | 161 | DRM_INIT_WAITQUEUE(&dev_priv->fence_queue); |
133 | 162 | ||
134 | /* Turn on vertical blank interrupt and soft trap interrupt. */ | 163 | /* Turn on soft trap interrupt. Vertical blank interrupts are enabled |
135 | MGA_WRITE(MGA_IEN, MGA_VLINEIEN | MGA_SOFTRAPEN); | 164 | * in mga_enable_vblank. |
165 | */ | ||
166 | MGA_WRITE(MGA_IEN, MGA_SOFTRAPEN); | ||
167 | return 0; | ||
136 | } | 168 | } |
137 | 169 | ||
138 | void mga_driver_irq_uninstall(struct drm_device * dev) | 170 | void mga_driver_irq_uninstall(struct drm_device * dev) |
diff --git a/drivers/gpu/drm/mga/mga_state.c b/drivers/gpu/drm/mga/mga_state.c index d3f8aade07b3..b710fab21cb3 100644 --- a/drivers/gpu/drm/mga/mga_state.c +++ b/drivers/gpu/drm/mga/mga_state.c | |||
@@ -1022,7 +1022,7 @@ static int mga_getparam(struct drm_device *dev, void *data, struct drm_file *fil | |||
1022 | 1022 | ||
1023 | switch (param->param) { | 1023 | switch (param->param) { |
1024 | case MGA_PARAM_IRQ_NR: | 1024 | case MGA_PARAM_IRQ_NR: |
1025 | value = dev->irq; | 1025 | value = drm_dev_to_irq(dev); |
1026 | break; | 1026 | break; |
1027 | case MGA_PARAM_CARD_TYPE: | 1027 | case MGA_PARAM_CARD_TYPE: |
1028 | value = dev_priv->chipset; | 1028 | value = dev_priv->chipset; |
diff --git a/drivers/gpu/drm/r128/r128_drv.c b/drivers/gpu/drm/r128/r128_drv.c index 6108e7587e12..3265d53ba91f 100644 --- a/drivers/gpu/drm/r128/r128_drv.c +++ b/drivers/gpu/drm/r128/r128_drv.c | |||
@@ -43,12 +43,13 @@ static struct pci_device_id pciidlist[] = { | |||
43 | static struct drm_driver driver = { | 43 | static struct drm_driver driver = { |
44 | .driver_features = | 44 | .driver_features = |
45 | DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | | 45 | DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | |
46 | DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | | 46 | DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED, |
47 | DRIVER_IRQ_VBL, | ||
48 | .dev_priv_size = sizeof(drm_r128_buf_priv_t), | 47 | .dev_priv_size = sizeof(drm_r128_buf_priv_t), |
49 | .preclose = r128_driver_preclose, | 48 | .preclose = r128_driver_preclose, |
50 | .lastclose = r128_driver_lastclose, | 49 | .lastclose = r128_driver_lastclose, |
51 | .vblank_wait = r128_driver_vblank_wait, | 50 | .get_vblank_counter = r128_get_vblank_counter, |
51 | .enable_vblank = r128_enable_vblank, | ||
52 | .disable_vblank = r128_disable_vblank, | ||
52 | .irq_preinstall = r128_driver_irq_preinstall, | 53 | .irq_preinstall = r128_driver_irq_preinstall, |
53 | .irq_postinstall = r128_driver_irq_postinstall, | 54 | .irq_postinstall = r128_driver_irq_postinstall, |
54 | .irq_uninstall = r128_driver_irq_uninstall, | 55 | .irq_uninstall = r128_driver_irq_uninstall, |
@@ -59,21 +60,20 @@ static struct drm_driver driver = { | |||
59 | .ioctls = r128_ioctls, | 60 | .ioctls = r128_ioctls, |
60 | .dma_ioctl = r128_cce_buffers, | 61 | .dma_ioctl = r128_cce_buffers, |
61 | .fops = { | 62 | .fops = { |
62 | .owner = THIS_MODULE, | 63 | .owner = THIS_MODULE, |
63 | .open = drm_open, | 64 | .open = drm_open, |
64 | .release = drm_release, | 65 | .release = drm_release, |
65 | .ioctl = drm_ioctl, | 66 | .ioctl = drm_ioctl, |
66 | .mmap = drm_mmap, | 67 | .mmap = drm_mmap, |
67 | .poll = drm_poll, | 68 | .poll = drm_poll, |
68 | .fasync = drm_fasync, | 69 | .fasync = drm_fasync, |
69 | #ifdef CONFIG_COMPAT | 70 | #ifdef CONFIG_COMPAT |
70 | .compat_ioctl = r128_compat_ioctl, | 71 | .compat_ioctl = r128_compat_ioctl, |
71 | #endif | 72 | #endif |
72 | }, | 73 | }, |
73 | |||
74 | .pci_driver = { | 74 | .pci_driver = { |
75 | .name = DRIVER_NAME, | 75 | .name = DRIVER_NAME, |
76 | .id_table = pciidlist, | 76 | .id_table = pciidlist, |
77 | }, | 77 | }, |
78 | 78 | ||
79 | .name = DRIVER_NAME, | 79 | .name = DRIVER_NAME, |
@@ -87,6 +87,7 @@ static struct drm_driver driver = { | |||
87 | static int __init r128_init(void) | 87 | static int __init r128_init(void) |
88 | { | 88 | { |
89 | driver.num_ioctls = r128_max_ioctl; | 89 | driver.num_ioctls = r128_max_ioctl; |
90 | |||
90 | return drm_init(&driver); | 91 | return drm_init(&driver); |
91 | } | 92 | } |
92 | 93 | ||
diff --git a/drivers/gpu/drm/r128/r128_drv.h b/drivers/gpu/drm/r128/r128_drv.h index 011105e51ac6..5898b274279d 100644 --- a/drivers/gpu/drm/r128/r128_drv.h +++ b/drivers/gpu/drm/r128/r128_drv.h | |||
@@ -29,7 +29,7 @@ | |||
29 | * Rickard E. (Rik) Faith <faith@valinux.com> | 29 | * Rickard E. (Rik) Faith <faith@valinux.com> |
30 | * Kevin E. Martin <martin@valinux.com> | 30 | * Kevin E. Martin <martin@valinux.com> |
31 | * Gareth Hughes <gareth@valinux.com> | 31 | * Gareth Hughes <gareth@valinux.com> |
32 | * Michel Dänzer <daenzerm@student.ethz.ch> | 32 | * Michel D�zer <daenzerm@student.ethz.ch> |
33 | */ | 33 | */ |
34 | 34 | ||
35 | #ifndef __R128_DRV_H__ | 35 | #ifndef __R128_DRV_H__ |
@@ -97,6 +97,8 @@ typedef struct drm_r128_private { | |||
97 | u32 crtc_offset; | 97 | u32 crtc_offset; |
98 | u32 crtc_offset_cntl; | 98 | u32 crtc_offset_cntl; |
99 | 99 | ||
100 | atomic_t vbl_received; | ||
101 | |||
100 | u32 color_fmt; | 102 | u32 color_fmt; |
101 | unsigned int front_offset; | 103 | unsigned int front_offset; |
102 | unsigned int front_pitch; | 104 | unsigned int front_pitch; |
@@ -149,11 +151,12 @@ extern int r128_wait_ring(drm_r128_private_t * dev_priv, int n); | |||
149 | extern int r128_do_cce_idle(drm_r128_private_t * dev_priv); | 151 | extern int r128_do_cce_idle(drm_r128_private_t * dev_priv); |
150 | extern int r128_do_cleanup_cce(struct drm_device * dev); | 152 | extern int r128_do_cleanup_cce(struct drm_device * dev); |
151 | 153 | ||
152 | extern int r128_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence); | 154 | extern int r128_enable_vblank(struct drm_device *dev, int crtc); |
153 | 155 | extern void r128_disable_vblank(struct drm_device *dev, int crtc); | |
156 | extern u32 r128_get_vblank_counter(struct drm_device *dev, int crtc); | ||
154 | extern irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS); | 157 | extern irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS); |
155 | extern void r128_driver_irq_preinstall(struct drm_device * dev); | 158 | extern void r128_driver_irq_preinstall(struct drm_device * dev); |
156 | extern void r128_driver_irq_postinstall(struct drm_device * dev); | 159 | extern int r128_driver_irq_postinstall(struct drm_device *dev); |
157 | extern void r128_driver_irq_uninstall(struct drm_device * dev); | 160 | extern void r128_driver_irq_uninstall(struct drm_device * dev); |
158 | extern void r128_driver_lastclose(struct drm_device * dev); | 161 | extern void r128_driver_lastclose(struct drm_device * dev); |
159 | extern void r128_driver_preclose(struct drm_device * dev, | 162 | extern void r128_driver_preclose(struct drm_device * dev, |
diff --git a/drivers/gpu/drm/r128/r128_irq.c b/drivers/gpu/drm/r128/r128_irq.c index c76fdca7662d..d7349012a680 100644 --- a/drivers/gpu/drm/r128/r128_irq.c +++ b/drivers/gpu/drm/r128/r128_irq.c | |||
@@ -35,6 +35,16 @@ | |||
35 | #include "r128_drm.h" | 35 | #include "r128_drm.h" |
36 | #include "r128_drv.h" | 36 | #include "r128_drv.h" |
37 | 37 | ||
38 | u32 r128_get_vblank_counter(struct drm_device *dev, int crtc) | ||
39 | { | ||
40 | const drm_r128_private_t *dev_priv = dev->dev_private; | ||
41 | |||
42 | if (crtc != 0) | ||
43 | return 0; | ||
44 | |||
45 | return atomic_read(&dev_priv->vbl_received); | ||
46 | } | ||
47 | |||
38 | irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS) | 48 | irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS) |
39 | { | 49 | { |
40 | struct drm_device *dev = (struct drm_device *) arg; | 50 | struct drm_device *dev = (struct drm_device *) arg; |
@@ -46,30 +56,38 @@ irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS) | |||
46 | /* VBLANK interrupt */ | 56 | /* VBLANK interrupt */ |
47 | if (status & R128_CRTC_VBLANK_INT) { | 57 | if (status & R128_CRTC_VBLANK_INT) { |
48 | R128_WRITE(R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK); | 58 | R128_WRITE(R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK); |
49 | atomic_inc(&dev->vbl_received); | 59 | atomic_inc(&dev_priv->vbl_received); |
50 | DRM_WAKEUP(&dev->vbl_queue); | 60 | drm_handle_vblank(dev, 0); |
51 | drm_vbl_send_signals(dev); | ||
52 | return IRQ_HANDLED; | 61 | return IRQ_HANDLED; |
53 | } | 62 | } |
54 | return IRQ_NONE; | 63 | return IRQ_NONE; |
55 | } | 64 | } |
56 | 65 | ||
57 | int r128_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence) | 66 | int r128_enable_vblank(struct drm_device *dev, int crtc) |
58 | { | 67 | { |
59 | unsigned int cur_vblank; | 68 | drm_r128_private_t *dev_priv = dev->dev_private; |
60 | int ret = 0; | ||
61 | 69 | ||
62 | /* Assume that the user has missed the current sequence number | 70 | if (crtc != 0) { |
63 | * by about a day rather than she wants to wait for years | 71 | DRM_ERROR("%s: bad crtc %d\n", __func__, crtc); |
64 | * using vertical blanks... | 72 | return -EINVAL; |
65 | */ | 73 | } |
66 | DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ, | ||
67 | (((cur_vblank = atomic_read(&dev->vbl_received)) | ||
68 | - *sequence) <= (1 << 23))); | ||
69 | 74 | ||
70 | *sequence = cur_vblank; | 75 | R128_WRITE(R128_GEN_INT_CNTL, R128_CRTC_VBLANK_INT_EN); |
76 | return 0; | ||
77 | } | ||
78 | |||
79 | void r128_disable_vblank(struct drm_device *dev, int crtc) | ||
80 | { | ||
81 | if (crtc != 0) | ||
82 | DRM_ERROR("%s: bad crtc %d\n", __func__, crtc); | ||
71 | 83 | ||
72 | return ret; | 84 | /* |
85 | * FIXME: implement proper interrupt disable by using the vblank | ||
86 | * counter register (if available) | ||
87 | * | ||
88 | * R128_WRITE(R128_GEN_INT_CNTL, | ||
89 | * R128_READ(R128_GEN_INT_CNTL) & ~R128_CRTC_VBLANK_INT_EN); | ||
90 | */ | ||
73 | } | 91 | } |
74 | 92 | ||
75 | void r128_driver_irq_preinstall(struct drm_device * dev) | 93 | void r128_driver_irq_preinstall(struct drm_device * dev) |
@@ -82,12 +100,9 @@ void r128_driver_irq_preinstall(struct drm_device * dev) | |||
82 | R128_WRITE(R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK); | 100 | R128_WRITE(R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK); |
83 | } | 101 | } |
84 | 102 | ||
85 | void r128_driver_irq_postinstall(struct drm_device * dev) | 103 | int r128_driver_irq_postinstall(struct drm_device *dev) |
86 | { | 104 | { |
87 | drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private; | 105 | return drm_vblank_init(dev, 1); |
88 | |||
89 | /* Turn on VBL interrupt */ | ||
90 | R128_WRITE(R128_GEN_INT_CNTL, R128_CRTC_VBLANK_INT_EN); | ||
91 | } | 106 | } |
92 | 107 | ||
93 | void r128_driver_irq_uninstall(struct drm_device * dev) | 108 | void r128_driver_irq_uninstall(struct drm_device * dev) |
diff --git a/drivers/gpu/drm/r128/r128_state.c b/drivers/gpu/drm/r128/r128_state.c index 51a9afce7b9b..f7a5b5740764 100644 --- a/drivers/gpu/drm/r128/r128_state.c +++ b/drivers/gpu/drm/r128/r128_state.c | |||
@@ -1629,7 +1629,7 @@ static int r128_getparam(struct drm_device *dev, void *data, struct drm_file *fi | |||
1629 | 1629 | ||
1630 | switch (param->param) { | 1630 | switch (param->param) { |
1631 | case R128_PARAM_IRQ_NR: | 1631 | case R128_PARAM_IRQ_NR: |
1632 | value = dev->irq; | 1632 | value = drm_dev_to_irq(dev); |
1633 | break; | 1633 | break; |
1634 | default: | 1634 | default: |
1635 | return -EINVAL; | 1635 | return -EINVAL; |
diff --git a/drivers/gpu/drm/radeon/radeon_cp.c b/drivers/gpu/drm/radeon/radeon_cp.c index 248ab4a7d39f..59a2132a8f57 100644 --- a/drivers/gpu/drm/radeon/radeon_cp.c +++ b/drivers/gpu/drm/radeon/radeon_cp.c | |||
@@ -71,7 +71,8 @@ static u32 RS690_READ_MCIND(drm_radeon_private_t *dev_priv, int addr) | |||
71 | 71 | ||
72 | static u32 IGP_READ_MCIND(drm_radeon_private_t *dev_priv, int addr) | 72 | static u32 IGP_READ_MCIND(drm_radeon_private_t *dev_priv, int addr) |
73 | { | 73 | { |
74 | if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) | 74 | if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || |
75 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) | ||
75 | return RS690_READ_MCIND(dev_priv, addr); | 76 | return RS690_READ_MCIND(dev_priv, addr); |
76 | else | 77 | else |
77 | return RS480_READ_MCIND(dev_priv, addr); | 78 | return RS480_READ_MCIND(dev_priv, addr); |
@@ -82,7 +83,8 @@ u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv) | |||
82 | 83 | ||
83 | if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) | 84 | if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) |
84 | return R500_READ_MCIND(dev_priv, RV515_MC_FB_LOCATION); | 85 | return R500_READ_MCIND(dev_priv, RV515_MC_FB_LOCATION); |
85 | else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) | 86 | else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || |
87 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) | ||
86 | return RS690_READ_MCIND(dev_priv, RS690_MC_FB_LOCATION); | 88 | return RS690_READ_MCIND(dev_priv, RS690_MC_FB_LOCATION); |
87 | else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) | 89 | else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) |
88 | return R500_READ_MCIND(dev_priv, R520_MC_FB_LOCATION); | 90 | return R500_READ_MCIND(dev_priv, R520_MC_FB_LOCATION); |
@@ -94,7 +96,8 @@ static void radeon_write_fb_location(drm_radeon_private_t *dev_priv, u32 fb_loc) | |||
94 | { | 96 | { |
95 | if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) | 97 | if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) |
96 | R500_WRITE_MCIND(RV515_MC_FB_LOCATION, fb_loc); | 98 | R500_WRITE_MCIND(RV515_MC_FB_LOCATION, fb_loc); |
97 | else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) | 99 | else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || |
100 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) | ||
98 | RS690_WRITE_MCIND(RS690_MC_FB_LOCATION, fb_loc); | 101 | RS690_WRITE_MCIND(RS690_MC_FB_LOCATION, fb_loc); |
99 | else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) | 102 | else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) |
100 | R500_WRITE_MCIND(R520_MC_FB_LOCATION, fb_loc); | 103 | R500_WRITE_MCIND(R520_MC_FB_LOCATION, fb_loc); |
@@ -106,7 +109,8 @@ static void radeon_write_agp_location(drm_radeon_private_t *dev_priv, u32 agp_lo | |||
106 | { | 109 | { |
107 | if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) | 110 | if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) |
108 | R500_WRITE_MCIND(RV515_MC_AGP_LOCATION, agp_loc); | 111 | R500_WRITE_MCIND(RV515_MC_AGP_LOCATION, agp_loc); |
109 | else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) | 112 | else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || |
113 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) | ||
110 | RS690_WRITE_MCIND(RS690_MC_AGP_LOCATION, agp_loc); | 114 | RS690_WRITE_MCIND(RS690_MC_AGP_LOCATION, agp_loc); |
111 | else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) | 115 | else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) |
112 | R500_WRITE_MCIND(R520_MC_AGP_LOCATION, agp_loc); | 116 | R500_WRITE_MCIND(R520_MC_AGP_LOCATION, agp_loc); |
@@ -122,15 +126,17 @@ static void radeon_write_agp_base(drm_radeon_private_t *dev_priv, u64 agp_base) | |||
122 | if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) { | 126 | if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) { |
123 | R500_WRITE_MCIND(RV515_MC_AGP_BASE, agp_base_lo); | 127 | R500_WRITE_MCIND(RV515_MC_AGP_BASE, agp_base_lo); |
124 | R500_WRITE_MCIND(RV515_MC_AGP_BASE_2, agp_base_hi); | 128 | R500_WRITE_MCIND(RV515_MC_AGP_BASE_2, agp_base_hi); |
125 | } else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) { | 129 | } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || |
130 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) { | ||
126 | RS690_WRITE_MCIND(RS690_MC_AGP_BASE, agp_base_lo); | 131 | RS690_WRITE_MCIND(RS690_MC_AGP_BASE, agp_base_lo); |
127 | RS690_WRITE_MCIND(RS690_MC_AGP_BASE_2, agp_base_hi); | 132 | RS690_WRITE_MCIND(RS690_MC_AGP_BASE_2, agp_base_hi); |
128 | } else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) { | 133 | } else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) { |
129 | R500_WRITE_MCIND(R520_MC_AGP_BASE, agp_base_lo); | 134 | R500_WRITE_MCIND(R520_MC_AGP_BASE, agp_base_lo); |
130 | R500_WRITE_MCIND(R520_MC_AGP_BASE_2, agp_base_hi); | 135 | R500_WRITE_MCIND(R520_MC_AGP_BASE_2, agp_base_hi); |
131 | } else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS480) { | 136 | } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS400) || |
137 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS480)) { | ||
132 | RADEON_WRITE(RADEON_AGP_BASE, agp_base_lo); | 138 | RADEON_WRITE(RADEON_AGP_BASE, agp_base_lo); |
133 | RADEON_WRITE(RS480_AGP_BASE_2, 0); | 139 | RADEON_WRITE(RS480_AGP_BASE_2, agp_base_hi); |
134 | } else { | 140 | } else { |
135 | RADEON_WRITE(RADEON_AGP_BASE, agp_base_lo); | 141 | RADEON_WRITE(RADEON_AGP_BASE, agp_base_lo); |
136 | if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R200) | 142 | if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R200) |
@@ -347,6 +353,7 @@ static void radeon_cp_load_microcode(drm_radeon_private_t * dev_priv) | |||
347 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R350) || | 353 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R350) || |
348 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV350) || | 354 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV350) || |
349 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV380) || | 355 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV380) || |
356 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS400) || | ||
350 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS480)) { | 357 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS480)) { |
351 | DRM_INFO("Loading R300 Microcode\n"); | 358 | DRM_INFO("Loading R300 Microcode\n"); |
352 | for (i = 0; i < 256; i++) { | 359 | for (i = 0; i < 256; i++) { |
@@ -356,6 +363,7 @@ static void radeon_cp_load_microcode(drm_radeon_private_t * dev_priv) | |||
356 | R300_cp_microcode[i][0]); | 363 | R300_cp_microcode[i][0]); |
357 | } | 364 | } |
358 | } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R420) || | 365 | } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R420) || |
366 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R423) || | ||
359 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV410)) { | 367 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV410)) { |
360 | DRM_INFO("Loading R400 Microcode\n"); | 368 | DRM_INFO("Loading R400 Microcode\n"); |
361 | for (i = 0; i < 256; i++) { | 369 | for (i = 0; i < 256; i++) { |
@@ -364,8 +372,9 @@ static void radeon_cp_load_microcode(drm_radeon_private_t * dev_priv) | |||
364 | RADEON_WRITE(RADEON_CP_ME_RAM_DATAL, | 372 | RADEON_WRITE(RADEON_CP_ME_RAM_DATAL, |
365 | R420_cp_microcode[i][0]); | 373 | R420_cp_microcode[i][0]); |
366 | } | 374 | } |
367 | } else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) { | 375 | } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || |
368 | DRM_INFO("Loading RS690 Microcode\n"); | 376 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) { |
377 | DRM_INFO("Loading RS690/RS740 Microcode\n"); | ||
369 | for (i = 0; i < 256; i++) { | 378 | for (i = 0; i < 256; i++) { |
370 | RADEON_WRITE(RADEON_CP_ME_RAM_DATAH, | 379 | RADEON_WRITE(RADEON_CP_ME_RAM_DATAH, |
371 | RS690_cp_microcode[i][1]); | 380 | RS690_cp_microcode[i][1]); |
@@ -626,8 +635,6 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev, | |||
626 | dev_priv->ring.size_l2qw); | 635 | dev_priv->ring.size_l2qw); |
627 | #endif | 636 | #endif |
628 | 637 | ||
629 | /* Start with assuming that writeback doesn't work */ | ||
630 | dev_priv->writeback_works = 0; | ||
631 | 638 | ||
632 | /* Initialize the scratch register pointer. This will cause | 639 | /* Initialize the scratch register pointer. This will cause |
633 | * the scratch register values to be written out to memory | 640 | * the scratch register values to be written out to memory |
@@ -646,8 +653,18 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev, | |||
646 | RADEON_WRITE(RADEON_SCRATCH_UMSK, 0x7); | 653 | RADEON_WRITE(RADEON_SCRATCH_UMSK, 0x7); |
647 | 654 | ||
648 | /* Turn on bus mastering */ | 655 | /* Turn on bus mastering */ |
649 | tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS; | 656 | if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS400) || |
650 | RADEON_WRITE(RADEON_BUS_CNTL, tmp); | 657 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || |
658 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) { | ||
659 | /* rs400, rs690/rs740 */ | ||
660 | tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RS400_BUS_MASTER_DIS; | ||
661 | RADEON_WRITE(RADEON_BUS_CNTL, tmp); | ||
662 | } else if (!(((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV380) || | ||
663 | ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R423))) { | ||
664 | /* r1xx, r2xx, r300, r(v)350, r420/r481, rs480 */ | ||
665 | tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS; | ||
666 | RADEON_WRITE(RADEON_BUS_CNTL, tmp); | ||
667 | } /* PCIE cards appears to not need this */ | ||
651 | 668 | ||
652 | dev_priv->sarea_priv->last_frame = dev_priv->scratch[0] = 0; | 669 | dev_priv->sarea_priv->last_frame = dev_priv->scratch[0] = 0; |
653 | RADEON_WRITE(RADEON_LAST_FRAME_REG, dev_priv->sarea_priv->last_frame); | 670 | RADEON_WRITE(RADEON_LAST_FRAME_REG, dev_priv->sarea_priv->last_frame); |
@@ -674,6 +691,9 @@ static void radeon_test_writeback(drm_radeon_private_t * dev_priv) | |||
674 | { | 691 | { |
675 | u32 tmp; | 692 | u32 tmp; |
676 | 693 | ||
694 | /* Start with assuming that writeback doesn't work */ | ||
695 | dev_priv->writeback_works = 0; | ||
696 | |||
677 | /* Writeback doesn't seem to work everywhere, test it here and possibly | 697 | /* Writeback doesn't seem to work everywhere, test it here and possibly |
678 | * enable it if it appears to work | 698 | * enable it if it appears to work |
679 | */ | 699 | */ |
@@ -719,7 +739,8 @@ static void radeon_set_igpgart(drm_radeon_private_t * dev_priv, int on) | |||
719 | dev_priv->gart_size); | 739 | dev_priv->gart_size); |
720 | 740 | ||
721 | temp = IGP_READ_MCIND(dev_priv, RS480_MC_MISC_CNTL); | 741 | temp = IGP_READ_MCIND(dev_priv, RS480_MC_MISC_CNTL); |
722 | if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) | 742 | if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || |
743 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) | ||
723 | IGP_WRITE_MCIND(RS480_MC_MISC_CNTL, (RS480_GART_INDEX_REG_EN | | 744 | IGP_WRITE_MCIND(RS480_MC_MISC_CNTL, (RS480_GART_INDEX_REG_EN | |
724 | RS690_BLOCK_GFX_D3_EN)); | 745 | RS690_BLOCK_GFX_D3_EN)); |
725 | else | 746 | else |
@@ -812,6 +833,7 @@ static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on) | |||
812 | u32 tmp; | 833 | u32 tmp; |
813 | 834 | ||
814 | if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || | 835 | if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || |
836 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740) || | ||
815 | (dev_priv->flags & RADEON_IS_IGPGART)) { | 837 | (dev_priv->flags & RADEON_IS_IGPGART)) { |
816 | radeon_set_igpgart(dev_priv, on); | 838 | radeon_set_igpgart(dev_priv, on); |
817 | return; | 839 | return; |
@@ -1286,7 +1308,7 @@ static int radeon_do_resume_cp(struct drm_device * dev) | |||
1286 | radeon_cp_init_ring_buffer(dev, dev_priv); | 1308 | radeon_cp_init_ring_buffer(dev, dev_priv); |
1287 | 1309 | ||
1288 | radeon_do_engine_reset(dev); | 1310 | radeon_do_engine_reset(dev); |
1289 | radeon_enable_interrupt(dev); | 1311 | radeon_irq_set_state(dev, RADEON_SW_INT_ENABLE, 1); |
1290 | 1312 | ||
1291 | DRM_DEBUG("radeon_do_resume_cp() complete\n"); | 1313 | DRM_DEBUG("radeon_do_resume_cp() complete\n"); |
1292 | 1314 | ||
@@ -1708,6 +1730,7 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags) | |||
1708 | case CHIP_R300: | 1730 | case CHIP_R300: |
1709 | case CHIP_R350: | 1731 | case CHIP_R350: |
1710 | case CHIP_R420: | 1732 | case CHIP_R420: |
1733 | case CHIP_R423: | ||
1711 | case CHIP_RV410: | 1734 | case CHIP_RV410: |
1712 | case CHIP_RV515: | 1735 | case CHIP_RV515: |
1713 | case CHIP_R520: | 1736 | case CHIP_R520: |
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 637bd7faf132..71af746a4e47 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c | |||
@@ -52,6 +52,28 @@ static int dri_library_name(struct drm_device *dev, char *buf) | |||
52 | "r300")); | 52 | "r300")); |
53 | } | 53 | } |
54 | 54 | ||
55 | static int radeon_suspend(struct drm_device *dev, pm_message_t state) | ||
56 | { | ||
57 | drm_radeon_private_t *dev_priv = dev->dev_private; | ||
58 | |||
59 | /* Disable *all* interrupts */ | ||
60 | if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) | ||
61 | RADEON_WRITE(R500_DxMODE_INT_MASK, 0); | ||
62 | RADEON_WRITE(RADEON_GEN_INT_CNTL, 0); | ||
63 | return 0; | ||
64 | } | ||
65 | |||
66 | static int radeon_resume(struct drm_device *dev) | ||
67 | { | ||
68 | drm_radeon_private_t *dev_priv = dev->dev_private; | ||
69 | |||
70 | /* Restore interrupt registers */ | ||
71 | if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) | ||
72 | RADEON_WRITE(R500_DxMODE_INT_MASK, dev_priv->r500_disp_irq_reg); | ||
73 | RADEON_WRITE(RADEON_GEN_INT_CNTL, dev_priv->irq_enable_reg); | ||
74 | return 0; | ||
75 | } | ||
76 | |||
55 | static struct pci_device_id pciidlist[] = { | 77 | static struct pci_device_id pciidlist[] = { |
56 | radeon_PCI_IDS | 78 | radeon_PCI_IDS |
57 | }; | 79 | }; |
@@ -59,8 +81,7 @@ static struct pci_device_id pciidlist[] = { | |||
59 | static struct drm_driver driver = { | 81 | static struct drm_driver driver = { |
60 | .driver_features = | 82 | .driver_features = |
61 | DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | | 83 | DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | |
62 | DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED | | 84 | DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED, |
63 | DRIVER_IRQ_VBL | DRIVER_IRQ_VBL2, | ||
64 | .dev_priv_size = sizeof(drm_radeon_buf_priv_t), | 85 | .dev_priv_size = sizeof(drm_radeon_buf_priv_t), |
65 | .load = radeon_driver_load, | 86 | .load = radeon_driver_load, |
66 | .firstopen = radeon_driver_firstopen, | 87 | .firstopen = radeon_driver_firstopen, |
@@ -69,8 +90,11 @@ static struct drm_driver driver = { | |||
69 | .postclose = radeon_driver_postclose, | 90 | .postclose = radeon_driver_postclose, |
70 | .lastclose = radeon_driver_lastclose, | 91 | .lastclose = radeon_driver_lastclose, |
71 | .unload = radeon_driver_unload, | 92 | .unload = radeon_driver_unload, |
72 | .vblank_wait = radeon_driver_vblank_wait, | 93 | .suspend = radeon_suspend, |
73 | .vblank_wait2 = radeon_driver_vblank_wait2, | 94 | .resume = radeon_resume, |
95 | .get_vblank_counter = radeon_get_vblank_counter, | ||
96 | .enable_vblank = radeon_enable_vblank, | ||
97 | .disable_vblank = radeon_disable_vblank, | ||
74 | .dri_library_name = dri_library_name, | 98 | .dri_library_name = dri_library_name, |
75 | .irq_preinstall = radeon_driver_irq_preinstall, | 99 | .irq_preinstall = radeon_driver_irq_preinstall, |
76 | .irq_postinstall = radeon_driver_irq_postinstall, | 100 | .irq_postinstall = radeon_driver_irq_postinstall, |
diff --git a/drivers/gpu/drm/radeon/radeon_drv.h b/drivers/gpu/drm/radeon/radeon_drv.h index 099381693175..4dbb813910c3 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.h +++ b/drivers/gpu/drm/radeon/radeon_drv.h | |||
@@ -122,9 +122,12 @@ enum radeon_family { | |||
122 | CHIP_RV350, | 122 | CHIP_RV350, |
123 | CHIP_RV380, | 123 | CHIP_RV380, |
124 | CHIP_R420, | 124 | CHIP_R420, |
125 | CHIP_R423, | ||
125 | CHIP_RV410, | 126 | CHIP_RV410, |
127 | CHIP_RS400, | ||
126 | CHIP_RS480, | 128 | CHIP_RS480, |
127 | CHIP_RS690, | 129 | CHIP_RS690, |
130 | CHIP_RS740, | ||
128 | CHIP_RV515, | 131 | CHIP_RV515, |
129 | CHIP_R520, | 132 | CHIP_R520, |
130 | CHIP_RV530, | 133 | CHIP_RV530, |
@@ -378,17 +381,17 @@ extern void radeon_mem_release(struct drm_file *file_priv, | |||
378 | struct mem_block *heap); | 381 | struct mem_block *heap); |
379 | 382 | ||
380 | /* radeon_irq.c */ | 383 | /* radeon_irq.c */ |
384 | extern void radeon_irq_set_state(struct drm_device *dev, u32 mask, int state); | ||
381 | extern int radeon_irq_emit(struct drm_device *dev, void *data, struct drm_file *file_priv); | 385 | extern int radeon_irq_emit(struct drm_device *dev, void *data, struct drm_file *file_priv); |
382 | extern int radeon_irq_wait(struct drm_device *dev, void *data, struct drm_file *file_priv); | 386 | extern int radeon_irq_wait(struct drm_device *dev, void *data, struct drm_file *file_priv); |
383 | 387 | ||
384 | extern void radeon_do_release(struct drm_device * dev); | 388 | extern void radeon_do_release(struct drm_device * dev); |
385 | extern int radeon_driver_vblank_wait(struct drm_device * dev, | 389 | extern u32 radeon_get_vblank_counter(struct drm_device *dev, int crtc); |
386 | unsigned int *sequence); | 390 | extern int radeon_enable_vblank(struct drm_device *dev, int crtc); |
387 | extern int radeon_driver_vblank_wait2(struct drm_device * dev, | 391 | extern void radeon_disable_vblank(struct drm_device *dev, int crtc); |
388 | unsigned int *sequence); | ||
389 | extern irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS); | 392 | extern irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS); |
390 | extern void radeon_driver_irq_preinstall(struct drm_device * dev); | 393 | extern void radeon_driver_irq_preinstall(struct drm_device * dev); |
391 | extern void radeon_driver_irq_postinstall(struct drm_device * dev); | 394 | extern int radeon_driver_irq_postinstall(struct drm_device *dev); |
392 | extern void radeon_driver_irq_uninstall(struct drm_device * dev); | 395 | extern void radeon_driver_irq_uninstall(struct drm_device * dev); |
393 | extern void radeon_enable_interrupt(struct drm_device *dev); | 396 | extern void radeon_enable_interrupt(struct drm_device *dev); |
394 | extern int radeon_vblank_crtc_get(struct drm_device *dev); | 397 | extern int radeon_vblank_crtc_get(struct drm_device *dev); |
@@ -397,19 +400,22 @@ extern int radeon_vblank_crtc_set(struct drm_device *dev, int64_t value); | |||
397 | extern int radeon_driver_load(struct drm_device *dev, unsigned long flags); | 400 | extern int radeon_driver_load(struct drm_device *dev, unsigned long flags); |
398 | extern int radeon_driver_unload(struct drm_device *dev); | 401 | extern int radeon_driver_unload(struct drm_device *dev); |
399 | extern int radeon_driver_firstopen(struct drm_device *dev); | 402 | extern int radeon_driver_firstopen(struct drm_device *dev); |
400 | extern void radeon_driver_preclose(struct drm_device * dev, struct drm_file *file_priv); | 403 | extern void radeon_driver_preclose(struct drm_device *dev, |
401 | extern void radeon_driver_postclose(struct drm_device * dev, struct drm_file * filp); | 404 | struct drm_file *file_priv); |
405 | extern void radeon_driver_postclose(struct drm_device *dev, | ||
406 | struct drm_file *file_priv); | ||
402 | extern void radeon_driver_lastclose(struct drm_device * dev); | 407 | extern void radeon_driver_lastclose(struct drm_device * dev); |
403 | extern int radeon_driver_open(struct drm_device * dev, struct drm_file * filp_priv); | 408 | extern int radeon_driver_open(struct drm_device *dev, |
409 | struct drm_file *file_priv); | ||
404 | extern long radeon_compat_ioctl(struct file *filp, unsigned int cmd, | 410 | extern long radeon_compat_ioctl(struct file *filp, unsigned int cmd, |
405 | unsigned long arg); | 411 | unsigned long arg); |
406 | 412 | ||
407 | /* r300_cmdbuf.c */ | 413 | /* r300_cmdbuf.c */ |
408 | extern void r300_init_reg_flags(struct drm_device *dev); | 414 | extern void r300_init_reg_flags(struct drm_device *dev); |
409 | 415 | ||
410 | extern int r300_do_cp_cmdbuf(struct drm_device * dev, | 416 | extern int r300_do_cp_cmdbuf(struct drm_device *dev, |
411 | struct drm_file *file_priv, | 417 | struct drm_file *file_priv, |
412 | drm_radeon_kcmd_buffer_t * cmdbuf); | 418 | drm_radeon_kcmd_buffer_t *cmdbuf); |
413 | 419 | ||
414 | /* Flags for stats.boxes | 420 | /* Flags for stats.boxes |
415 | */ | 421 | */ |
@@ -434,8 +440,31 @@ extern int r300_do_cp_cmdbuf(struct drm_device * dev, | |||
434 | # define RADEON_SCISSOR_1_ENABLE (1 << 29) | 440 | # define RADEON_SCISSOR_1_ENABLE (1 << 29) |
435 | # define RADEON_SCISSOR_2_ENABLE (1 << 30) | 441 | # define RADEON_SCISSOR_2_ENABLE (1 << 30) |
436 | 442 | ||
443 | /* | ||
444 | * PCIE radeons (rv370/rv380, rv410, r423/r430/r480, r5xx) | ||
445 | * don't have an explicit bus mastering disable bit. It's handled | ||
446 | * by the PCI D-states. PMI_BM_DIS disables D-state bus master | ||
447 | * handling, not bus mastering itself. | ||
448 | */ | ||
437 | #define RADEON_BUS_CNTL 0x0030 | 449 | #define RADEON_BUS_CNTL 0x0030 |
450 | /* r1xx, r2xx, r300, r(v)350, r420/r481, rs480 */ | ||
438 | # define RADEON_BUS_MASTER_DIS (1 << 6) | 451 | # define RADEON_BUS_MASTER_DIS (1 << 6) |
452 | /* rs400, rs690/rs740 */ | ||
453 | # define RS400_BUS_MASTER_DIS (1 << 14) | ||
454 | # define RS400_MSI_REARM (1 << 20) | ||
455 | /* see RS480_MSI_REARM in AIC_CNTL for rs480 */ | ||
456 | |||
457 | #define RADEON_BUS_CNTL1 0x0034 | ||
458 | # define RADEON_PMI_BM_DIS (1 << 2) | ||
459 | # define RADEON_PMI_INT_DIS (1 << 3) | ||
460 | |||
461 | #define RV370_BUS_CNTL 0x004c | ||
462 | # define RV370_PMI_BM_DIS (1 << 5) | ||
463 | # define RV370_PMI_INT_DIS (1 << 6) | ||
464 | |||
465 | #define RADEON_MSI_REARM_EN 0x0160 | ||
466 | /* rv370/rv380, rv410, r423/r430/r480, r5xx */ | ||
467 | # define RV370_MSI_REARM_EN (1 << 0) | ||
439 | 468 | ||
440 | #define RADEON_CLOCK_CNTL_DATA 0x000c | 469 | #define RADEON_CLOCK_CNTL_DATA 0x000c |
441 | # define RADEON_PLL_WR_EN (1 << 7) | 470 | # define RADEON_PLL_WR_EN (1 << 7) |
@@ -623,6 +652,7 @@ extern int r300_do_cp_cmdbuf(struct drm_device * dev, | |||
623 | # define RADEON_SW_INT_TEST (1 << 25) | 652 | # define RADEON_SW_INT_TEST (1 << 25) |
624 | # define RADEON_SW_INT_TEST_ACK (1 << 25) | 653 | # define RADEON_SW_INT_TEST_ACK (1 << 25) |
625 | # define RADEON_SW_INT_FIRE (1 << 26) | 654 | # define RADEON_SW_INT_FIRE (1 << 26) |
655 | # define R500_DISPLAY_INT_STATUS (1 << 0) | ||
626 | 656 | ||
627 | #define RADEON_HOST_PATH_CNTL 0x0130 | 657 | #define RADEON_HOST_PATH_CNTL 0x0130 |
628 | # define RADEON_HDP_SOFT_RESET (1 << 26) | 658 | # define RADEON_HDP_SOFT_RESET (1 << 26) |
@@ -907,6 +937,7 @@ extern int r300_do_cp_cmdbuf(struct drm_device * dev, | |||
907 | 937 | ||
908 | #define RADEON_AIC_CNTL 0x01d0 | 938 | #define RADEON_AIC_CNTL 0x01d0 |
909 | # define RADEON_PCIGART_TRANSLATE_EN (1 << 0) | 939 | # define RADEON_PCIGART_TRANSLATE_EN (1 << 0) |
940 | # define RS480_MSI_REARM (1 << 3) | ||
910 | #define RADEON_AIC_STAT 0x01d4 | 941 | #define RADEON_AIC_STAT 0x01d4 |
911 | #define RADEON_AIC_PT_BASE 0x01d8 | 942 | #define RADEON_AIC_PT_BASE 0x01d8 |
912 | #define RADEON_AIC_LO_ADDR 0x01dc | 943 | #define RADEON_AIC_LO_ADDR 0x01dc |
@@ -1116,6 +1147,9 @@ extern int r300_do_cp_cmdbuf(struct drm_device * dev, | |||
1116 | 1147 | ||
1117 | #define R200_VAP_PVS_CNTL_1 0x22D0 | 1148 | #define R200_VAP_PVS_CNTL_1 0x22D0 |
1118 | 1149 | ||
1150 | #define RADEON_CRTC_CRNT_FRAME 0x0214 | ||
1151 | #define RADEON_CRTC2_CRNT_FRAME 0x0314 | ||
1152 | |||
1119 | #define R500_D1CRTC_STATUS 0x609c | 1153 | #define R500_D1CRTC_STATUS 0x609c |
1120 | #define R500_D2CRTC_STATUS 0x689c | 1154 | #define R500_D2CRTC_STATUS 0x689c |
1121 | #define R500_CRTC_V_BLANK (1<<0) | 1155 | #define R500_CRTC_V_BLANK (1<<0) |
@@ -1200,7 +1234,8 @@ do { \ | |||
1200 | 1234 | ||
1201 | #define IGP_WRITE_MCIND(addr, val) \ | 1235 | #define IGP_WRITE_MCIND(addr, val) \ |
1202 | do { \ | 1236 | do { \ |
1203 | if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) \ | 1237 | if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || \ |
1238 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) \ | ||
1204 | RS690_WRITE_MCIND(addr, val); \ | 1239 | RS690_WRITE_MCIND(addr, val); \ |
1205 | else \ | 1240 | else \ |
1206 | RS480_WRITE_MCIND(addr, val); \ | 1241 | RS480_WRITE_MCIND(addr, val); \ |
diff --git a/drivers/gpu/drm/radeon/radeon_irq.c b/drivers/gpu/drm/radeon/radeon_irq.c index ee40d197deb7..5079f7054a2f 100644 --- a/drivers/gpu/drm/radeon/radeon_irq.c +++ b/drivers/gpu/drm/radeon/radeon_irq.c | |||
@@ -27,7 +27,7 @@ | |||
27 | * | 27 | * |
28 | * Authors: | 28 | * Authors: |
29 | * Keith Whitwell <keith@tungstengraphics.com> | 29 | * Keith Whitwell <keith@tungstengraphics.com> |
30 | * Michel Dänzer <michel@daenzer.net> | 30 | * Michel D�zer <michel@daenzer.net> |
31 | */ | 31 | */ |
32 | 32 | ||
33 | #include "drmP.h" | 33 | #include "drmP.h" |
@@ -35,12 +35,128 @@ | |||
35 | #include "radeon_drm.h" | 35 | #include "radeon_drm.h" |
36 | #include "radeon_drv.h" | 36 | #include "radeon_drv.h" |
37 | 37 | ||
38 | static __inline__ u32 radeon_acknowledge_irqs(drm_radeon_private_t * dev_priv, | 38 | void radeon_irq_set_state(struct drm_device *dev, u32 mask, int state) |
39 | u32 mask) | ||
40 | { | 39 | { |
41 | u32 irqs = RADEON_READ(RADEON_GEN_INT_STATUS) & mask; | 40 | drm_radeon_private_t *dev_priv = dev->dev_private; |
41 | |||
42 | if (state) | ||
43 | dev_priv->irq_enable_reg |= mask; | ||
44 | else | ||
45 | dev_priv->irq_enable_reg &= ~mask; | ||
46 | |||
47 | RADEON_WRITE(RADEON_GEN_INT_CNTL, dev_priv->irq_enable_reg); | ||
48 | } | ||
49 | |||
50 | static void r500_vbl_irq_set_state(struct drm_device *dev, u32 mask, int state) | ||
51 | { | ||
52 | drm_radeon_private_t *dev_priv = dev->dev_private; | ||
53 | |||
54 | if (state) | ||
55 | dev_priv->r500_disp_irq_reg |= mask; | ||
56 | else | ||
57 | dev_priv->r500_disp_irq_reg &= ~mask; | ||
58 | |||
59 | RADEON_WRITE(R500_DxMODE_INT_MASK, dev_priv->r500_disp_irq_reg); | ||
60 | } | ||
61 | |||
62 | int radeon_enable_vblank(struct drm_device *dev, int crtc) | ||
63 | { | ||
64 | drm_radeon_private_t *dev_priv = dev->dev_private; | ||
65 | |||
66 | if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) { | ||
67 | switch (crtc) { | ||
68 | case 0: | ||
69 | r500_vbl_irq_set_state(dev, R500_D1MODE_INT_MASK, 1); | ||
70 | break; | ||
71 | case 1: | ||
72 | r500_vbl_irq_set_state(dev, R500_D2MODE_INT_MASK, 1); | ||
73 | break; | ||
74 | default: | ||
75 | DRM_ERROR("tried to enable vblank on non-existent crtc %d\n", | ||
76 | crtc); | ||
77 | return EINVAL; | ||
78 | } | ||
79 | } else { | ||
80 | switch (crtc) { | ||
81 | case 0: | ||
82 | radeon_irq_set_state(dev, RADEON_CRTC_VBLANK_MASK, 1); | ||
83 | break; | ||
84 | case 1: | ||
85 | radeon_irq_set_state(dev, RADEON_CRTC2_VBLANK_MASK, 1); | ||
86 | break; | ||
87 | default: | ||
88 | DRM_ERROR("tried to enable vblank on non-existent crtc %d\n", | ||
89 | crtc); | ||
90 | return EINVAL; | ||
91 | } | ||
92 | } | ||
93 | |||
94 | return 0; | ||
95 | } | ||
96 | |||
97 | void radeon_disable_vblank(struct drm_device *dev, int crtc) | ||
98 | { | ||
99 | drm_radeon_private_t *dev_priv = dev->dev_private; | ||
100 | |||
101 | if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) { | ||
102 | switch (crtc) { | ||
103 | case 0: | ||
104 | r500_vbl_irq_set_state(dev, R500_D1MODE_INT_MASK, 0); | ||
105 | break; | ||
106 | case 1: | ||
107 | r500_vbl_irq_set_state(dev, R500_D2MODE_INT_MASK, 0); | ||
108 | break; | ||
109 | default: | ||
110 | DRM_ERROR("tried to enable vblank on non-existent crtc %d\n", | ||
111 | crtc); | ||
112 | break; | ||
113 | } | ||
114 | } else { | ||
115 | switch (crtc) { | ||
116 | case 0: | ||
117 | radeon_irq_set_state(dev, RADEON_CRTC_VBLANK_MASK, 0); | ||
118 | break; | ||
119 | case 1: | ||
120 | radeon_irq_set_state(dev, RADEON_CRTC2_VBLANK_MASK, 0); | ||
121 | break; | ||
122 | default: | ||
123 | DRM_ERROR("tried to enable vblank on non-existent crtc %d\n", | ||
124 | crtc); | ||
125 | break; | ||
126 | } | ||
127 | } | ||
128 | } | ||
129 | |||
130 | static inline u32 radeon_acknowledge_irqs(drm_radeon_private_t *dev_priv, u32 *r500_disp_int) | ||
131 | { | ||
132 | u32 irqs = RADEON_READ(RADEON_GEN_INT_STATUS); | ||
133 | u32 irq_mask = RADEON_SW_INT_TEST; | ||
134 | |||
135 | *r500_disp_int = 0; | ||
136 | if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) { | ||
137 | /* vbl interrupts in a different place */ | ||
138 | |||
139 | if (irqs & R500_DISPLAY_INT_STATUS) { | ||
140 | /* if a display interrupt */ | ||
141 | u32 disp_irq; | ||
142 | |||
143 | disp_irq = RADEON_READ(R500_DISP_INTERRUPT_STATUS); | ||
144 | |||
145 | *r500_disp_int = disp_irq; | ||
146 | if (disp_irq & R500_D1_VBLANK_INTERRUPT) | ||
147 | RADEON_WRITE(R500_D1MODE_VBLANK_STATUS, R500_VBLANK_ACK); | ||
148 | if (disp_irq & R500_D2_VBLANK_INTERRUPT) | ||
149 | RADEON_WRITE(R500_D2MODE_VBLANK_STATUS, R500_VBLANK_ACK); | ||
150 | } | ||
151 | irq_mask |= R500_DISPLAY_INT_STATUS; | ||
152 | } else | ||
153 | irq_mask |= RADEON_CRTC_VBLANK_STAT | RADEON_CRTC2_VBLANK_STAT; | ||
154 | |||
155 | irqs &= irq_mask; | ||
156 | |||
42 | if (irqs) | 157 | if (irqs) |
43 | RADEON_WRITE(RADEON_GEN_INT_STATUS, irqs); | 158 | RADEON_WRITE(RADEON_GEN_INT_STATUS, irqs); |
159 | |||
44 | return irqs; | 160 | return irqs; |
45 | } | 161 | } |
46 | 162 | ||
@@ -68,44 +184,33 @@ irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS) | |||
68 | drm_radeon_private_t *dev_priv = | 184 | drm_radeon_private_t *dev_priv = |
69 | (drm_radeon_private_t *) dev->dev_private; | 185 | (drm_radeon_private_t *) dev->dev_private; |
70 | u32 stat; | 186 | u32 stat; |
187 | u32 r500_disp_int; | ||
71 | 188 | ||
72 | /* Only consider the bits we're interested in - others could be used | 189 | /* Only consider the bits we're interested in - others could be used |
73 | * outside the DRM | 190 | * outside the DRM |
74 | */ | 191 | */ |
75 | stat = radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK | | 192 | stat = radeon_acknowledge_irqs(dev_priv, &r500_disp_int); |
76 | RADEON_CRTC_VBLANK_STAT | | ||
77 | RADEON_CRTC2_VBLANK_STAT)); | ||
78 | if (!stat) | 193 | if (!stat) |
79 | return IRQ_NONE; | 194 | return IRQ_NONE; |
80 | 195 | ||
81 | stat &= dev_priv->irq_enable_reg; | 196 | stat &= dev_priv->irq_enable_reg; |
82 | 197 | ||
83 | /* SW interrupt */ | 198 | /* SW interrupt */ |
84 | if (stat & RADEON_SW_INT_TEST) { | 199 | if (stat & RADEON_SW_INT_TEST) |
85 | DRM_WAKEUP(&dev_priv->swi_queue); | 200 | DRM_WAKEUP(&dev_priv->swi_queue); |
86 | } | ||
87 | 201 | ||
88 | /* VBLANK interrupt */ | 202 | /* VBLANK interrupt */ |
89 | if (stat & (RADEON_CRTC_VBLANK_STAT|RADEON_CRTC2_VBLANK_STAT)) { | 203 | if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) { |
90 | int vblank_crtc = dev_priv->vblank_crtc; | 204 | if (r500_disp_int & R500_D1_VBLANK_INTERRUPT) |
91 | 205 | drm_handle_vblank(dev, 0); | |
92 | if ((vblank_crtc & | 206 | if (r500_disp_int & R500_D2_VBLANK_INTERRUPT) |
93 | (DRM_RADEON_VBLANK_CRTC1 | DRM_RADEON_VBLANK_CRTC2)) == | 207 | drm_handle_vblank(dev, 1); |
94 | (DRM_RADEON_VBLANK_CRTC1 | DRM_RADEON_VBLANK_CRTC2)) { | 208 | } else { |
95 | if (stat & RADEON_CRTC_VBLANK_STAT) | 209 | if (stat & RADEON_CRTC_VBLANK_STAT) |
96 | atomic_inc(&dev->vbl_received); | 210 | drm_handle_vblank(dev, 0); |
97 | if (stat & RADEON_CRTC2_VBLANK_STAT) | 211 | if (stat & RADEON_CRTC2_VBLANK_STAT) |
98 | atomic_inc(&dev->vbl_received2); | 212 | drm_handle_vblank(dev, 1); |
99 | } else if (((stat & RADEON_CRTC_VBLANK_STAT) && | ||
100 | (vblank_crtc & DRM_RADEON_VBLANK_CRTC1)) || | ||
101 | ((stat & RADEON_CRTC2_VBLANK_STAT) && | ||
102 | (vblank_crtc & DRM_RADEON_VBLANK_CRTC2))) | ||
103 | atomic_inc(&dev->vbl_received); | ||
104 | |||
105 | DRM_WAKEUP(&dev->vbl_queue); | ||
106 | drm_vbl_send_signals(dev); | ||
107 | } | 213 | } |
108 | |||
109 | return IRQ_HANDLED; | 214 | return IRQ_HANDLED; |
110 | } | 215 | } |
111 | 216 | ||
@@ -144,54 +249,31 @@ static int radeon_wait_irq(struct drm_device * dev, int swi_nr) | |||
144 | return ret; | 249 | return ret; |
145 | } | 250 | } |
146 | 251 | ||
147 | static int radeon_driver_vblank_do_wait(struct drm_device * dev, | 252 | u32 radeon_get_vblank_counter(struct drm_device *dev, int crtc) |
148 | unsigned int *sequence, int crtc) | ||
149 | { | 253 | { |
150 | drm_radeon_private_t *dev_priv = | 254 | drm_radeon_private_t *dev_priv = dev->dev_private; |
151 | (drm_radeon_private_t *) dev->dev_private; | 255 | |
152 | unsigned int cur_vblank; | ||
153 | int ret = 0; | ||
154 | int ack = 0; | ||
155 | atomic_t *counter; | ||
156 | if (!dev_priv) { | 256 | if (!dev_priv) { |
157 | DRM_ERROR("called with no initialization\n"); | 257 | DRM_ERROR("called with no initialization\n"); |
158 | return -EINVAL; | 258 | return -EINVAL; |
159 | } | 259 | } |
160 | 260 | ||
161 | if (crtc == DRM_RADEON_VBLANK_CRTC1) { | 261 | if (crtc < 0 || crtc > 1) { |
162 | counter = &dev->vbl_received; | 262 | DRM_ERROR("Invalid crtc %d\n", crtc); |
163 | ack |= RADEON_CRTC_VBLANK_STAT; | ||
164 | } else if (crtc == DRM_RADEON_VBLANK_CRTC2) { | ||
165 | counter = &dev->vbl_received2; | ||
166 | ack |= RADEON_CRTC2_VBLANK_STAT; | ||
167 | } else | ||
168 | return -EINVAL; | 263 | return -EINVAL; |
264 | } | ||
169 | 265 | ||
170 | radeon_acknowledge_irqs(dev_priv, ack); | 266 | if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) { |
171 | 267 | if (crtc == 0) | |
172 | dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; | 268 | return RADEON_READ(R500_D1CRTC_FRAME_COUNT); |
173 | 269 | else | |
174 | /* Assume that the user has missed the current sequence number | 270 | return RADEON_READ(R500_D2CRTC_FRAME_COUNT); |
175 | * by about a day rather than she wants to wait for years | 271 | } else { |
176 | * using vertical blanks... | 272 | if (crtc == 0) |
177 | */ | 273 | return RADEON_READ(RADEON_CRTC_CRNT_FRAME); |
178 | DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ, | 274 | else |
179 | (((cur_vblank = atomic_read(counter)) | 275 | return RADEON_READ(RADEON_CRTC2_CRNT_FRAME); |
180 | - *sequence) <= (1 << 23))); | 276 | } |
181 | |||
182 | *sequence = cur_vblank; | ||
183 | |||
184 | return ret; | ||
185 | } | ||
186 | |||
187 | int radeon_driver_vblank_wait(struct drm_device *dev, unsigned int *sequence) | ||
188 | { | ||
189 | return radeon_driver_vblank_do_wait(dev, sequence, DRM_RADEON_VBLANK_CRTC1); | ||
190 | } | ||
191 | |||
192 | int radeon_driver_vblank_wait2(struct drm_device *dev, unsigned int *sequence) | ||
193 | { | ||
194 | return radeon_driver_vblank_do_wait(dev, sequence, DRM_RADEON_VBLANK_CRTC2); | ||
195 | } | 277 | } |
196 | 278 | ||
197 | /* Needs the lock as it touches the ring. | 279 | /* Needs the lock as it touches the ring. |
@@ -234,46 +316,41 @@ int radeon_irq_wait(struct drm_device *dev, void *data, struct drm_file *file_pr | |||
234 | return radeon_wait_irq(dev, irqwait->irq_seq); | 316 | return radeon_wait_irq(dev, irqwait->irq_seq); |
235 | } | 317 | } |
236 | 318 | ||
237 | void radeon_enable_interrupt(struct drm_device *dev) | ||
238 | { | ||
239 | drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private; | ||
240 | |||
241 | dev_priv->irq_enable_reg = RADEON_SW_INT_ENABLE; | ||
242 | if (dev_priv->vblank_crtc & DRM_RADEON_VBLANK_CRTC1) | ||
243 | dev_priv->irq_enable_reg |= RADEON_CRTC_VBLANK_MASK; | ||
244 | |||
245 | if (dev_priv->vblank_crtc & DRM_RADEON_VBLANK_CRTC2) | ||
246 | dev_priv->irq_enable_reg |= RADEON_CRTC2_VBLANK_MASK; | ||
247 | |||
248 | RADEON_WRITE(RADEON_GEN_INT_CNTL, dev_priv->irq_enable_reg); | ||
249 | dev_priv->irq_enabled = 1; | ||
250 | } | ||
251 | |||
252 | /* drm_dma.h hooks | 319 | /* drm_dma.h hooks |
253 | */ | 320 | */ |
254 | void radeon_driver_irq_preinstall(struct drm_device * dev) | 321 | void radeon_driver_irq_preinstall(struct drm_device * dev) |
255 | { | 322 | { |
256 | drm_radeon_private_t *dev_priv = | 323 | drm_radeon_private_t *dev_priv = |
257 | (drm_radeon_private_t *) dev->dev_private; | 324 | (drm_radeon_private_t *) dev->dev_private; |
325 | u32 dummy; | ||
258 | 326 | ||
259 | /* Disable *all* interrupts */ | 327 | /* Disable *all* interrupts */ |
328 | if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) | ||
329 | RADEON_WRITE(R500_DxMODE_INT_MASK, 0); | ||
260 | RADEON_WRITE(RADEON_GEN_INT_CNTL, 0); | 330 | RADEON_WRITE(RADEON_GEN_INT_CNTL, 0); |
261 | 331 | ||
262 | /* Clear bits if they're already high */ | 332 | /* Clear bits if they're already high */ |
263 | radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK | | 333 | radeon_acknowledge_irqs(dev_priv, &dummy); |
264 | RADEON_CRTC_VBLANK_STAT | | ||
265 | RADEON_CRTC2_VBLANK_STAT)); | ||
266 | } | 334 | } |
267 | 335 | ||
268 | void radeon_driver_irq_postinstall(struct drm_device * dev) | 336 | int radeon_driver_irq_postinstall(struct drm_device *dev) |
269 | { | 337 | { |
270 | drm_radeon_private_t *dev_priv = | 338 | drm_radeon_private_t *dev_priv = |
271 | (drm_radeon_private_t *) dev->dev_private; | 339 | (drm_radeon_private_t *) dev->dev_private; |
340 | int ret; | ||
272 | 341 | ||
273 | atomic_set(&dev_priv->swi_emitted, 0); | 342 | atomic_set(&dev_priv->swi_emitted, 0); |
274 | DRM_INIT_WAITQUEUE(&dev_priv->swi_queue); | 343 | DRM_INIT_WAITQUEUE(&dev_priv->swi_queue); |
275 | 344 | ||
276 | radeon_enable_interrupt(dev); | 345 | ret = drm_vblank_init(dev, 2); |
346 | if (ret) | ||
347 | return ret; | ||
348 | |||
349 | dev->max_vblank_count = 0x001fffff; | ||
350 | |||
351 | radeon_irq_set_state(dev, RADEON_SW_INT_ENABLE, 1); | ||
352 | |||
353 | return 0; | ||
277 | } | 354 | } |
278 | 355 | ||
279 | void radeon_driver_irq_uninstall(struct drm_device * dev) | 356 | void radeon_driver_irq_uninstall(struct drm_device * dev) |
@@ -285,6 +362,8 @@ void radeon_driver_irq_uninstall(struct drm_device * dev) | |||
285 | 362 | ||
286 | dev_priv->irq_enabled = 0; | 363 | dev_priv->irq_enabled = 0; |
287 | 364 | ||
365 | if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) | ||
366 | RADEON_WRITE(R500_DxMODE_INT_MASK, 0); | ||
288 | /* Disable *all* interrupts */ | 367 | /* Disable *all* interrupts */ |
289 | RADEON_WRITE(RADEON_GEN_INT_CNTL, 0); | 368 | RADEON_WRITE(RADEON_GEN_INT_CNTL, 0); |
290 | } | 369 | } |
@@ -293,18 +372,8 @@ void radeon_driver_irq_uninstall(struct drm_device * dev) | |||
293 | int radeon_vblank_crtc_get(struct drm_device *dev) | 372 | int radeon_vblank_crtc_get(struct drm_device *dev) |
294 | { | 373 | { |
295 | drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private; | 374 | drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private; |
296 | u32 flag; | ||
297 | u32 value; | ||
298 | |||
299 | flag = RADEON_READ(RADEON_GEN_INT_CNTL); | ||
300 | value = 0; | ||
301 | |||
302 | if (flag & RADEON_CRTC_VBLANK_MASK) | ||
303 | value |= DRM_RADEON_VBLANK_CRTC1; | ||
304 | 375 | ||
305 | if (flag & RADEON_CRTC2_VBLANK_MASK) | 376 | return dev_priv->vblank_crtc; |
306 | value |= DRM_RADEON_VBLANK_CRTC2; | ||
307 | return value; | ||
308 | } | 377 | } |
309 | 378 | ||
310 | int radeon_vblank_crtc_set(struct drm_device *dev, int64_t value) | 379 | int radeon_vblank_crtc_set(struct drm_device *dev, int64_t value) |
@@ -315,6 +384,5 @@ int radeon_vblank_crtc_set(struct drm_device *dev, int64_t value) | |||
315 | return -EINVAL; | 384 | return -EINVAL; |
316 | } | 385 | } |
317 | dev_priv->vblank_crtc = (unsigned int)value; | 386 | dev_priv->vblank_crtc = (unsigned int)value; |
318 | radeon_enable_interrupt(dev); | ||
319 | return 0; | 387 | return 0; |
320 | } | 388 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_state.c b/drivers/gpu/drm/radeon/radeon_state.c index 11c146b49211..5d7153fcc7b0 100644 --- a/drivers/gpu/drm/radeon/radeon_state.c +++ b/drivers/gpu/drm/radeon/radeon_state.c | |||
@@ -2997,7 +2997,7 @@ static int radeon_cp_getparam(struct drm_device *dev, void *data, struct drm_fil | |||
2997 | value = GET_SCRATCH(2); | 2997 | value = GET_SCRATCH(2); |
2998 | break; | 2998 | break; |
2999 | case RADEON_PARAM_IRQ_NR: | 2999 | case RADEON_PARAM_IRQ_NR: |
3000 | value = dev->irq; | 3000 | value = drm_dev_to_irq(dev); |
3001 | break; | 3001 | break; |
3002 | case RADEON_PARAM_GART_BASE: | 3002 | case RADEON_PARAM_GART_BASE: |
3003 | value = dev_priv->gart_vm_start; | 3003 | value = dev_priv->gart_vm_start; |
diff --git a/drivers/gpu/drm/sis/sis_mm.c b/drivers/gpu/drm/sis/sis_mm.c index b3878770fce1..af22111397d8 100644 --- a/drivers/gpu/drm/sis/sis_mm.c +++ b/drivers/gpu/drm/sis/sis_mm.c | |||
@@ -41,7 +41,7 @@ | |||
41 | #define AGP_TYPE 1 | 41 | #define AGP_TYPE 1 |
42 | 42 | ||
43 | 43 | ||
44 | #if defined(CONFIG_FB_SIS) | 44 | #if defined(CONFIG_FB_SIS) || defined(CONFIG_FB_SIS_MODULE) |
45 | /* fb management via fb device */ | 45 | /* fb management via fb device */ |
46 | 46 | ||
47 | #define SIS_MM_ALIGN_SHIFT 0 | 47 | #define SIS_MM_ALIGN_SHIFT 0 |
@@ -57,7 +57,7 @@ static void *sis_sman_mm_allocate(void *private, unsigned long size, | |||
57 | if (req.size == 0) | 57 | if (req.size == 0) |
58 | return NULL; | 58 | return NULL; |
59 | else | 59 | else |
60 | return (void *)~req.offset; | 60 | return (void *)(unsigned long)~req.offset; |
61 | } | 61 | } |
62 | 62 | ||
63 | static void sis_sman_mm_free(void *private, void *ref) | 63 | static void sis_sman_mm_free(void *private, void *ref) |
@@ -75,12 +75,12 @@ static unsigned long sis_sman_mm_offset(void *private, void *ref) | |||
75 | return ~((unsigned long)ref); | 75 | return ~((unsigned long)ref); |
76 | } | 76 | } |
77 | 77 | ||
78 | #else /* CONFIG_FB_SIS */ | 78 | #else /* CONFIG_FB_SIS[_MODULE] */ |
79 | 79 | ||
80 | #define SIS_MM_ALIGN_SHIFT 4 | 80 | #define SIS_MM_ALIGN_SHIFT 4 |
81 | #define SIS_MM_ALIGN_MASK ( (1 << SIS_MM_ALIGN_SHIFT) - 1) | 81 | #define SIS_MM_ALIGN_MASK ( (1 << SIS_MM_ALIGN_SHIFT) - 1) |
82 | 82 | ||
83 | #endif /* CONFIG_FB_SIS */ | 83 | #endif /* CONFIG_FB_SIS[_MODULE] */ |
84 | 84 | ||
85 | static int sis_fb_init(struct drm_device *dev, void *data, struct drm_file *file_priv) | 85 | static int sis_fb_init(struct drm_device *dev, void *data, struct drm_file *file_priv) |
86 | { | 86 | { |
@@ -89,7 +89,7 @@ static int sis_fb_init(struct drm_device *dev, void *data, struct drm_file *file | |||
89 | int ret; | 89 | int ret; |
90 | 90 | ||
91 | mutex_lock(&dev->struct_mutex); | 91 | mutex_lock(&dev->struct_mutex); |
92 | #if defined(CONFIG_FB_SIS) | 92 | #if defined(CONFIG_FB_SIS) || defined(CONFIG_FB_SIS_MODULE) |
93 | { | 93 | { |
94 | struct drm_sman_mm sman_mm; | 94 | struct drm_sman_mm sman_mm; |
95 | sman_mm.private = (void *)0xFFFFFFFF; | 95 | sman_mm.private = (void *)0xFFFFFFFF; |
diff --git a/drivers/gpu/drm/via/via_drv.c b/drivers/gpu/drm/via/via_drv.c index 80c01cdfa37d..0993b441fc42 100644 --- a/drivers/gpu/drm/via/via_drv.c +++ b/drivers/gpu/drm/via/via_drv.c | |||
@@ -40,11 +40,13 @@ static struct pci_device_id pciidlist[] = { | |||
40 | static struct drm_driver driver = { | 40 | static struct drm_driver driver = { |
41 | .driver_features = | 41 | .driver_features = |
42 | DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_IRQ | | 42 | DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_IRQ | |
43 | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL, | 43 | DRIVER_IRQ_SHARED, |
44 | .load = via_driver_load, | 44 | .load = via_driver_load, |
45 | .unload = via_driver_unload, | 45 | .unload = via_driver_unload, |
46 | .context_dtor = via_final_context, | 46 | .context_dtor = via_final_context, |
47 | .vblank_wait = via_driver_vblank_wait, | 47 | .get_vblank_counter = via_get_vblank_counter, |
48 | .enable_vblank = via_enable_vblank, | ||
49 | .disable_vblank = via_disable_vblank, | ||
48 | .irq_preinstall = via_driver_irq_preinstall, | 50 | .irq_preinstall = via_driver_irq_preinstall, |
49 | .irq_postinstall = via_driver_irq_postinstall, | 51 | .irq_postinstall = via_driver_irq_postinstall, |
50 | .irq_uninstall = via_driver_irq_uninstall, | 52 | .irq_uninstall = via_driver_irq_uninstall, |
@@ -59,17 +61,17 @@ static struct drm_driver driver = { | |||
59 | .get_reg_ofs = drm_core_get_reg_ofs, | 61 | .get_reg_ofs = drm_core_get_reg_ofs, |
60 | .ioctls = via_ioctls, | 62 | .ioctls = via_ioctls, |
61 | .fops = { | 63 | .fops = { |
62 | .owner = THIS_MODULE, | 64 | .owner = THIS_MODULE, |
63 | .open = drm_open, | 65 | .open = drm_open, |
64 | .release = drm_release, | 66 | .release = drm_release, |
65 | .ioctl = drm_ioctl, | 67 | .ioctl = drm_ioctl, |
66 | .mmap = drm_mmap, | 68 | .mmap = drm_mmap, |
67 | .poll = drm_poll, | 69 | .poll = drm_poll, |
68 | .fasync = drm_fasync, | 70 | .fasync = drm_fasync, |
69 | }, | 71 | }, |
70 | .pci_driver = { | 72 | .pci_driver = { |
71 | .name = DRIVER_NAME, | 73 | .name = DRIVER_NAME, |
72 | .id_table = pciidlist, | 74 | .id_table = pciidlist, |
73 | }, | 75 | }, |
74 | 76 | ||
75 | .name = DRIVER_NAME, | 77 | .name = DRIVER_NAME, |
diff --git a/drivers/gpu/drm/via/via_drv.h b/drivers/gpu/drm/via/via_drv.h index 2daae81874cd..cafcb844a223 100644 --- a/drivers/gpu/drm/via/via_drv.h +++ b/drivers/gpu/drm/via/via_drv.h | |||
@@ -75,6 +75,7 @@ typedef struct drm_via_private { | |||
75 | struct timeval last_vblank; | 75 | struct timeval last_vblank; |
76 | int last_vblank_valid; | 76 | int last_vblank_valid; |
77 | unsigned usec_per_vblank; | 77 | unsigned usec_per_vblank; |
78 | atomic_t vbl_received; | ||
78 | drm_via_state_t hc_state; | 79 | drm_via_state_t hc_state; |
79 | char pci_buf[VIA_PCI_BUF_SIZE]; | 80 | char pci_buf[VIA_PCI_BUF_SIZE]; |
80 | const uint32_t *fire_offsets[VIA_FIRE_BUF_SIZE]; | 81 | const uint32_t *fire_offsets[VIA_FIRE_BUF_SIZE]; |
@@ -130,21 +131,24 @@ extern int via_init_context(struct drm_device * dev, int context); | |||
130 | extern int via_final_context(struct drm_device * dev, int context); | 131 | extern int via_final_context(struct drm_device * dev, int context); |
131 | 132 | ||
132 | extern int via_do_cleanup_map(struct drm_device * dev); | 133 | extern int via_do_cleanup_map(struct drm_device * dev); |
133 | extern int via_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence); | 134 | extern u32 via_get_vblank_counter(struct drm_device *dev, int crtc); |
135 | extern int via_enable_vblank(struct drm_device *dev, int crtc); | ||
136 | extern void via_disable_vblank(struct drm_device *dev, int crtc); | ||
134 | 137 | ||
135 | extern irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS); | 138 | extern irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS); |
136 | extern void via_driver_irq_preinstall(struct drm_device * dev); | 139 | extern void via_driver_irq_preinstall(struct drm_device * dev); |
137 | extern void via_driver_irq_postinstall(struct drm_device * dev); | 140 | extern int via_driver_irq_postinstall(struct drm_device *dev); |
138 | extern void via_driver_irq_uninstall(struct drm_device * dev); | 141 | extern void via_driver_irq_uninstall(struct drm_device * dev); |
139 | 142 | ||
140 | extern int via_dma_cleanup(struct drm_device * dev); | 143 | extern int via_dma_cleanup(struct drm_device * dev); |
141 | extern void via_init_command_verifier(void); | 144 | extern void via_init_command_verifier(void); |
142 | extern int via_driver_dma_quiescent(struct drm_device * dev); | 145 | extern int via_driver_dma_quiescent(struct drm_device * dev); |
143 | extern void via_init_futex(drm_via_private_t * dev_priv); | 146 | extern void via_init_futex(drm_via_private_t *dev_priv); |
144 | extern void via_cleanup_futex(drm_via_private_t * dev_priv); | 147 | extern void via_cleanup_futex(drm_via_private_t *dev_priv); |
145 | extern void via_release_futex(drm_via_private_t * dev_priv, int context); | 148 | extern void via_release_futex(drm_via_private_t *dev_priv, int context); |
146 | 149 | ||
147 | extern void via_reclaim_buffers_locked(struct drm_device *dev, struct drm_file *file_priv); | 150 | extern void via_reclaim_buffers_locked(struct drm_device *dev, |
151 | struct drm_file *file_priv); | ||
148 | extern void via_lastclose(struct drm_device *dev); | 152 | extern void via_lastclose(struct drm_device *dev); |
149 | 153 | ||
150 | extern void via_dmablit_handler(struct drm_device *dev, int engine, int from_irq); | 154 | extern void via_dmablit_handler(struct drm_device *dev, int engine, int from_irq); |
diff --git a/drivers/gpu/drm/via/via_irq.c b/drivers/gpu/drm/via/via_irq.c index c6bb978a1106..665d319b927b 100644 --- a/drivers/gpu/drm/via/via_irq.c +++ b/drivers/gpu/drm/via/via_irq.c | |||
@@ -43,7 +43,7 @@ | |||
43 | #define VIA_REG_INTERRUPT 0x200 | 43 | #define VIA_REG_INTERRUPT 0x200 |
44 | 44 | ||
45 | /* VIA_REG_INTERRUPT */ | 45 | /* VIA_REG_INTERRUPT */ |
46 | #define VIA_IRQ_GLOBAL (1 << 31) | 46 | #define VIA_IRQ_GLOBAL (1 << 31) |
47 | #define VIA_IRQ_VBLANK_ENABLE (1 << 19) | 47 | #define VIA_IRQ_VBLANK_ENABLE (1 << 19) |
48 | #define VIA_IRQ_VBLANK_PENDING (1 << 3) | 48 | #define VIA_IRQ_VBLANK_PENDING (1 << 3) |
49 | #define VIA_IRQ_HQV0_ENABLE (1 << 11) | 49 | #define VIA_IRQ_HQV0_ENABLE (1 << 11) |
@@ -68,16 +68,15 @@ | |||
68 | 68 | ||
69 | static maskarray_t via_pro_group_a_irqs[] = { | 69 | static maskarray_t via_pro_group_a_irqs[] = { |
70 | {VIA_IRQ_HQV0_ENABLE, VIA_IRQ_HQV0_PENDING, 0x000003D0, 0x00008010, | 70 | {VIA_IRQ_HQV0_ENABLE, VIA_IRQ_HQV0_PENDING, 0x000003D0, 0x00008010, |
71 | 0x00000000}, | 71 | 0x00000000 }, |
72 | {VIA_IRQ_HQV1_ENABLE, VIA_IRQ_HQV1_PENDING, 0x000013D0, 0x00008010, | 72 | {VIA_IRQ_HQV1_ENABLE, VIA_IRQ_HQV1_PENDING, 0x000013D0, 0x00008010, |
73 | 0x00000000}, | 73 | 0x00000000 }, |
74 | {VIA_IRQ_DMA0_TD_ENABLE, VIA_IRQ_DMA0_TD_PENDING, VIA_PCI_DMA_CSR0, | 74 | {VIA_IRQ_DMA0_TD_ENABLE, VIA_IRQ_DMA0_TD_PENDING, VIA_PCI_DMA_CSR0, |
75 | VIA_DMA_CSR_TA | VIA_DMA_CSR_TD, 0x00000008}, | 75 | VIA_DMA_CSR_TA | VIA_DMA_CSR_TD, 0x00000008}, |
76 | {VIA_IRQ_DMA1_TD_ENABLE, VIA_IRQ_DMA1_TD_PENDING, VIA_PCI_DMA_CSR1, | 76 | {VIA_IRQ_DMA1_TD_ENABLE, VIA_IRQ_DMA1_TD_PENDING, VIA_PCI_DMA_CSR1, |
77 | VIA_DMA_CSR_TA | VIA_DMA_CSR_TD, 0x00000008}, | 77 | VIA_DMA_CSR_TA | VIA_DMA_CSR_TD, 0x00000008}, |
78 | }; | 78 | }; |
79 | static int via_num_pro_group_a = | 79 | static int via_num_pro_group_a = ARRAY_SIZE(via_pro_group_a_irqs); |
80 | sizeof(via_pro_group_a_irqs) / sizeof(maskarray_t); | ||
81 | static int via_irqmap_pro_group_a[] = {0, 1, -1, 2, -1, 3}; | 80 | static int via_irqmap_pro_group_a[] = {0, 1, -1, 2, -1, 3}; |
82 | 81 | ||
83 | static maskarray_t via_unichrome_irqs[] = { | 82 | static maskarray_t via_unichrome_irqs[] = { |
@@ -86,14 +85,24 @@ static maskarray_t via_unichrome_irqs[] = { | |||
86 | {VIA_IRQ_DMA1_TD_ENABLE, VIA_IRQ_DMA1_TD_PENDING, VIA_PCI_DMA_CSR1, | 85 | {VIA_IRQ_DMA1_TD_ENABLE, VIA_IRQ_DMA1_TD_PENDING, VIA_PCI_DMA_CSR1, |
87 | VIA_DMA_CSR_TA | VIA_DMA_CSR_TD, 0x00000008} | 86 | VIA_DMA_CSR_TA | VIA_DMA_CSR_TD, 0x00000008} |
88 | }; | 87 | }; |
89 | static int via_num_unichrome = sizeof(via_unichrome_irqs) / sizeof(maskarray_t); | 88 | static int via_num_unichrome = ARRAY_SIZE(via_unichrome_irqs); |
90 | static int via_irqmap_unichrome[] = {-1, -1, -1, 0, -1, 1}; | 89 | static int via_irqmap_unichrome[] = {-1, -1, -1, 0, -1, 1}; |
91 | 90 | ||
91 | |||
92 | static unsigned time_diff(struct timeval *now, struct timeval *then) | 92 | static unsigned time_diff(struct timeval *now, struct timeval *then) |
93 | { | 93 | { |
94 | return (now->tv_usec >= then->tv_usec) ? | 94 | return (now->tv_usec >= then->tv_usec) ? |
95 | now->tv_usec - then->tv_usec : | 95 | now->tv_usec - then->tv_usec : |
96 | 1000000 - (then->tv_usec - now->tv_usec); | 96 | 1000000 - (then->tv_usec - now->tv_usec); |
97 | } | ||
98 | |||
99 | u32 via_get_vblank_counter(struct drm_device *dev, int crtc) | ||
100 | { | ||
101 | drm_via_private_t *dev_priv = dev->dev_private; | ||
102 | if (crtc != 0) | ||
103 | return 0; | ||
104 | |||
105 | return atomic_read(&dev_priv->vbl_received); | ||
97 | } | 106 | } |
98 | 107 | ||
99 | irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS) | 108 | irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS) |
@@ -108,23 +117,22 @@ irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS) | |||
108 | 117 | ||
109 | status = VIA_READ(VIA_REG_INTERRUPT); | 118 | status = VIA_READ(VIA_REG_INTERRUPT); |
110 | if (status & VIA_IRQ_VBLANK_PENDING) { | 119 | if (status & VIA_IRQ_VBLANK_PENDING) { |
111 | atomic_inc(&dev->vbl_received); | 120 | atomic_inc(&dev_priv->vbl_received); |
112 | if (!(atomic_read(&dev->vbl_received) & 0x0F)) { | 121 | if (!(atomic_read(&dev_priv->vbl_received) & 0x0F)) { |
113 | do_gettimeofday(&cur_vblank); | 122 | do_gettimeofday(&cur_vblank); |
114 | if (dev_priv->last_vblank_valid) { | 123 | if (dev_priv->last_vblank_valid) { |
115 | dev_priv->usec_per_vblank = | 124 | dev_priv->usec_per_vblank = |
116 | time_diff(&cur_vblank, | 125 | time_diff(&cur_vblank, |
117 | &dev_priv->last_vblank) >> 4; | 126 | &dev_priv->last_vblank) >> 4; |
118 | } | 127 | } |
119 | dev_priv->last_vblank = cur_vblank; | 128 | dev_priv->last_vblank = cur_vblank; |
120 | dev_priv->last_vblank_valid = 1; | 129 | dev_priv->last_vblank_valid = 1; |
121 | } | 130 | } |
122 | if (!(atomic_read(&dev->vbl_received) & 0xFF)) { | 131 | if (!(atomic_read(&dev_priv->vbl_received) & 0xFF)) { |
123 | DRM_DEBUG("US per vblank is: %u\n", | 132 | DRM_DEBUG("US per vblank is: %u\n", |
124 | dev_priv->usec_per_vblank); | 133 | dev_priv->usec_per_vblank); |
125 | } | 134 | } |
126 | DRM_WAKEUP(&dev->vbl_queue); | 135 | drm_handle_vblank(dev, 0); |
127 | drm_vbl_send_signals(dev); | ||
128 | handled = 1; | 136 | handled = 1; |
129 | } | 137 | } |
130 | 138 | ||
@@ -145,6 +153,7 @@ irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS) | |||
145 | /* Acknowlege interrupts */ | 153 | /* Acknowlege interrupts */ |
146 | VIA_WRITE(VIA_REG_INTERRUPT, status); | 154 | VIA_WRITE(VIA_REG_INTERRUPT, status); |
147 | 155 | ||
156 | |||
148 | if (handled) | 157 | if (handled) |
149 | return IRQ_HANDLED; | 158 | return IRQ_HANDLED; |
150 | else | 159 | else |
@@ -163,31 +172,34 @@ static __inline__ void viadrv_acknowledge_irqs(drm_via_private_t * dev_priv) | |||
163 | } | 172 | } |
164 | } | 173 | } |
165 | 174 | ||
166 | int via_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence) | 175 | int via_enable_vblank(struct drm_device *dev, int crtc) |
167 | { | 176 | { |
168 | drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; | 177 | drm_via_private_t *dev_priv = dev->dev_private; |
169 | unsigned int cur_vblank; | 178 | u32 status; |
170 | int ret = 0; | ||
171 | 179 | ||
172 | DRM_DEBUG("\n"); | 180 | if (crtc != 0) { |
173 | if (!dev_priv) { | 181 | DRM_ERROR("%s: bad crtc %d\n", __func__, crtc); |
174 | DRM_ERROR("called with no initialization\n"); | ||
175 | return -EINVAL; | 182 | return -EINVAL; |
176 | } | 183 | } |
177 | 184 | ||
178 | viadrv_acknowledge_irqs(dev_priv); | 185 | status = VIA_READ(VIA_REG_INTERRUPT); |
186 | VIA_WRITE(VIA_REG_INTERRUPT, status & VIA_IRQ_VBLANK_ENABLE); | ||
187 | |||
188 | VIA_WRITE8(0x83d4, 0x11); | ||
189 | VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) | 0x30); | ||
179 | 190 | ||
180 | /* Assume that the user has missed the current sequence number | 191 | return 0; |
181 | * by about a day rather than she wants to wait for years | 192 | } |
182 | * using vertical blanks... | 193 | |
183 | */ | 194 | void via_disable_vblank(struct drm_device *dev, int crtc) |
195 | { | ||
196 | drm_via_private_t *dev_priv = dev->dev_private; | ||
184 | 197 | ||
185 | DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ, | 198 | VIA_WRITE8(0x83d4, 0x11); |
186 | (((cur_vblank = atomic_read(&dev->vbl_received)) - | 199 | VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) & ~0x30); |
187 | *sequence) <= (1 << 23))); | ||
188 | 200 | ||
189 | *sequence = cur_vblank; | 201 | if (crtc != 0) |
190 | return ret; | 202 | DRM_ERROR("%s: bad crtc %d\n", __func__, crtc); |
191 | } | 203 | } |
192 | 204 | ||
193 | static int | 205 | static int |
@@ -239,6 +251,7 @@ via_driver_irq_wait(struct drm_device * dev, unsigned int irq, int force_sequenc | |||
239 | return ret; | 251 | return ret; |
240 | } | 252 | } |
241 | 253 | ||
254 | |||
242 | /* | 255 | /* |
243 | * drm_dma.h hooks | 256 | * drm_dma.h hooks |
244 | */ | 257 | */ |
@@ -292,23 +305,25 @@ void via_driver_irq_preinstall(struct drm_device * dev) | |||
292 | } | 305 | } |
293 | } | 306 | } |
294 | 307 | ||
295 | void via_driver_irq_postinstall(struct drm_device * dev) | 308 | int via_driver_irq_postinstall(struct drm_device *dev) |
296 | { | 309 | { |
297 | drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; | 310 | drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; |
298 | u32 status; | 311 | u32 status; |
299 | 312 | ||
300 | DRM_DEBUG("\n"); | 313 | DRM_DEBUG("via_driver_irq_postinstall\n"); |
301 | if (dev_priv) { | 314 | if (!dev_priv) |
302 | status = VIA_READ(VIA_REG_INTERRUPT); | 315 | return -EINVAL; |
303 | VIA_WRITE(VIA_REG_INTERRUPT, status | VIA_IRQ_GLOBAL | ||
304 | | dev_priv->irq_enable_mask); | ||
305 | 316 | ||
306 | /* Some magic, oh for some data sheets ! */ | 317 | drm_vblank_init(dev, 1); |
318 | status = VIA_READ(VIA_REG_INTERRUPT); | ||
319 | VIA_WRITE(VIA_REG_INTERRUPT, status | VIA_IRQ_GLOBAL | ||
320 | | dev_priv->irq_enable_mask); | ||
307 | 321 | ||
308 | VIA_WRITE8(0x83d4, 0x11); | 322 | /* Some magic, oh for some data sheets ! */ |
309 | VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) | 0x30); | 323 | VIA_WRITE8(0x83d4, 0x11); |
324 | VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) | 0x30); | ||
310 | 325 | ||
311 | } | 326 | return 0; |
312 | } | 327 | } |
313 | 328 | ||
314 | void via_driver_irq_uninstall(struct drm_device * dev) | 329 | void via_driver_irq_uninstall(struct drm_device * dev) |
@@ -339,9 +354,6 @@ int via_wait_irq(struct drm_device *dev, void *data, struct drm_file *file_priv) | |||
339 | drm_via_irq_t *cur_irq = dev_priv->via_irqs; | 354 | drm_via_irq_t *cur_irq = dev_priv->via_irqs; |
340 | int force_sequence; | 355 | int force_sequence; |
341 | 356 | ||
342 | if (!dev->irq) | ||
343 | return -EINVAL; | ||
344 | |||
345 | if (irqwait->request.irq >= dev_priv->num_irqs) { | 357 | if (irqwait->request.irq >= dev_priv->num_irqs) { |
346 | DRM_ERROR("Trying to wait on unknown irq %d\n", | 358 | DRM_ERROR("Trying to wait on unknown irq %d\n", |
347 | irqwait->request.irq); | 359 | irqwait->request.irq); |
@@ -352,7 +364,8 @@ int via_wait_irq(struct drm_device *dev, void *data, struct drm_file *file_priv) | |||
352 | 364 | ||
353 | switch (irqwait->request.type & ~VIA_IRQ_FLAGS_MASK) { | 365 | switch (irqwait->request.type & ~VIA_IRQ_FLAGS_MASK) { |
354 | case VIA_IRQ_RELATIVE: | 366 | case VIA_IRQ_RELATIVE: |
355 | irqwait->request.sequence += atomic_read(&cur_irq->irq_received); | 367 | irqwait->request.sequence += |
368 | atomic_read(&cur_irq->irq_received); | ||
356 | irqwait->request.type &= ~_DRM_VBLANK_RELATIVE; | 369 | irqwait->request.type &= ~_DRM_VBLANK_RELATIVE; |
357 | case VIA_IRQ_ABSOLUTE: | 370 | case VIA_IRQ_ABSOLUTE: |
358 | break; | 371 | break; |
diff --git a/drivers/gpu/drm/via/via_mm.c b/drivers/gpu/drm/via/via_mm.c index e64094916e4f..f694cb5ededc 100644 --- a/drivers/gpu/drm/via/via_mm.c +++ b/drivers/gpu/drm/via/via_mm.c | |||
@@ -93,8 +93,7 @@ int via_final_context(struct drm_device *dev, int context) | |||
93 | /* Last context, perform cleanup */ | 93 | /* Last context, perform cleanup */ |
94 | if (dev->ctx_count == 1 && dev->dev_private) { | 94 | if (dev->ctx_count == 1 && dev->dev_private) { |
95 | DRM_DEBUG("Last Context\n"); | 95 | DRM_DEBUG("Last Context\n"); |
96 | if (dev->irq) | 96 | drm_irq_uninstall(dev); |
97 | drm_irq_uninstall(dev); | ||
98 | via_cleanup_futex(dev_priv); | 97 | via_cleanup_futex(dev_priv); |
99 | via_do_cleanup_map(dev); | 98 | via_do_cleanup_map(dev); |
100 | } | 99 | } |
diff --git a/drivers/media/common/tuners/mxl5005s.c b/drivers/media/common/tuners/mxl5005s.c index 227642b044ae..a8878244bb3c 100644 --- a/drivers/media/common/tuners/mxl5005s.c +++ b/drivers/media/common/tuners/mxl5005s.c | |||
@@ -3481,7 +3481,9 @@ static u16 MXL_ControlWrite_Group(struct dvb_frontend *fe, u16 controlNum, | |||
3481 | } | 3481 | } |
3482 | ctrlVal = 0; | 3482 | ctrlVal = 0; |
3483 | for (k = 0; k < state->MXL_Ctrl[i].size; k++) | 3483 | for (k = 0; k < state->MXL_Ctrl[i].size; k++) |
3484 | ctrlVal += state->MXL_Ctrl[i].val[k] * (1 << k); | 3484 | ctrlVal += state-> |
3485 | MXL_Ctrl[i].val[k] * | ||
3486 | (1 << k); | ||
3485 | } else | 3487 | } else |
3486 | return -1; | 3488 | return -1; |
3487 | } | 3489 | } |
@@ -3581,7 +3583,7 @@ static void MXL_RegWriteBit(struct dvb_frontend *fe, u8 address, u8 bit, | |||
3581 | 3583 | ||
3582 | static u32 MXL_Ceiling(u32 value, u32 resolution) | 3584 | static u32 MXL_Ceiling(u32 value, u32 resolution) |
3583 | { | 3585 | { |
3584 | return (value/resolution + (value % resolution > 0 ? 1 : 0)); | 3586 | return value / resolution + (value % resolution > 0 ? 1 : 0); |
3585 | } | 3587 | } |
3586 | 3588 | ||
3587 | /* Retrieve the Initialzation Registers */ | 3589 | /* Retrieve the Initialzation Registers */ |
@@ -3910,7 +3912,10 @@ static int mxl5005s_writeregs(struct dvb_frontend *fe, u8 *addrtable, | |||
3910 | 3912 | ||
3911 | static int mxl5005s_init(struct dvb_frontend *fe) | 3913 | static int mxl5005s_init(struct dvb_frontend *fe) |
3912 | { | 3914 | { |
3915 | struct mxl5005s_state *state = fe->tuner_priv; | ||
3916 | |||
3913 | dprintk(1, "%s()\n", __func__); | 3917 | dprintk(1, "%s()\n", __func__); |
3918 | state->current_mode = MXL_QAM; | ||
3914 | return mxl5005s_reconfigure(fe, MXL_QAM, MXL5005S_BANDWIDTH_6MHZ); | 3919 | return mxl5005s_reconfigure(fe, MXL_QAM, MXL5005S_BANDWIDTH_6MHZ); |
3915 | } | 3920 | } |
3916 | 3921 | ||
@@ -4092,7 +4097,6 @@ struct dvb_frontend *mxl5005s_attach(struct dvb_frontend *fe, | |||
4092 | state->frontend = fe; | 4097 | state->frontend = fe; |
4093 | state->config = config; | 4098 | state->config = config; |
4094 | state->i2c = i2c; | 4099 | state->i2c = i2c; |
4095 | state->current_mode = MXL_QAM; | ||
4096 | 4100 | ||
4097 | printk(KERN_INFO "MXL5005S: Attached at address 0x%02x\n", | 4101 | printk(KERN_INFO "MXL5005S: Attached at address 0x%02x\n", |
4098 | config->i2c_address); | 4102 | config->i2c_address); |
diff --git a/drivers/media/common/tuners/tuner-simple.c b/drivers/media/common/tuners/tuner-simple.c index 2a1aac1cc755..fb3f3b3adaba 100644 --- a/drivers/media/common/tuners/tuner-simple.c +++ b/drivers/media/common/tuners/tuner-simple.c | |||
@@ -493,6 +493,7 @@ static int simple_radio_bandswitch(struct dvb_frontend *fe, u8 *buffer) | |||
493 | case TUNER_PHILIPS_FM1216ME_MK3: | 493 | case TUNER_PHILIPS_FM1216ME_MK3: |
494 | case TUNER_PHILIPS_FM1236_MK3: | 494 | case TUNER_PHILIPS_FM1236_MK3: |
495 | case TUNER_PHILIPS_FMD1216ME_MK3: | 495 | case TUNER_PHILIPS_FMD1216ME_MK3: |
496 | case TUNER_PHILIPS_FMD1216MEX_MK3: | ||
496 | case TUNER_LG_NTSC_TAPE: | 497 | case TUNER_LG_NTSC_TAPE: |
497 | case TUNER_PHILIPS_FM1256_IH3: | 498 | case TUNER_PHILIPS_FM1256_IH3: |
498 | case TUNER_TCL_MF02GIP_5N: | 499 | case TUNER_TCL_MF02GIP_5N: |
@@ -767,6 +768,7 @@ static void simple_set_dvb(struct dvb_frontend *fe, u8 *buf, | |||
767 | 768 | ||
768 | switch (priv->type) { | 769 | switch (priv->type) { |
769 | case TUNER_PHILIPS_FMD1216ME_MK3: | 770 | case TUNER_PHILIPS_FMD1216ME_MK3: |
771 | case TUNER_PHILIPS_FMD1216MEX_MK3: | ||
770 | if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ && | 772 | if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ && |
771 | params->frequency >= 158870000) | 773 | params->frequency >= 158870000) |
772 | buf[3] |= 0x08; | 774 | buf[3] |= 0x08; |
diff --git a/drivers/media/common/tuners/tuner-types.c b/drivers/media/common/tuners/tuner-types.c index 04961a1f44be..7c0bc064c008 100644 --- a/drivers/media/common/tuners/tuner-types.c +++ b/drivers/media/common/tuners/tuner-types.c | |||
@@ -946,7 +946,7 @@ static struct tuner_params tuner_tena_9533_di_params[] = { | |||
946 | }, | 946 | }, |
947 | }; | 947 | }; |
948 | 948 | ||
949 | /* ------------ TUNER_PHILIPS_FMD1216ME_MK3 - Philips PAL ------------ */ | 949 | /* ------------ TUNER_PHILIPS_FMD1216ME(X)_MK3 - Philips PAL ------------ */ |
950 | 950 | ||
951 | static struct tuner_range tuner_philips_fmd1216me_mk3_pal_ranges[] = { | 951 | static struct tuner_range tuner_philips_fmd1216me_mk3_pal_ranges[] = { |
952 | { 16 * 160.00 /*MHz*/, 0x86, 0x51, }, | 952 | { 16 * 160.00 /*MHz*/, 0x86, 0x51, }, |
@@ -984,6 +984,27 @@ static struct tuner_params tuner_philips_fmd1216me_mk3_params[] = { | |||
984 | }, | 984 | }, |
985 | }; | 985 | }; |
986 | 986 | ||
987 | static struct tuner_params tuner_philips_fmd1216mex_mk3_params[] = { | ||
988 | { | ||
989 | .type = TUNER_PARAM_TYPE_PAL, | ||
990 | .ranges = tuner_philips_fmd1216me_mk3_pal_ranges, | ||
991 | .count = ARRAY_SIZE(tuner_philips_fmd1216me_mk3_pal_ranges), | ||
992 | .has_tda9887 = 1, | ||
993 | .port1_active = 1, | ||
994 | .port2_active = 1, | ||
995 | .port2_fm_high_sensitivity = 1, | ||
996 | .port2_invert_for_secam_lc = 1, | ||
997 | .port1_set_for_fm_mono = 1, | ||
998 | .radio_if = 1, | ||
999 | .fm_gain_normal = 1, | ||
1000 | }, | ||
1001 | { | ||
1002 | .type = TUNER_PARAM_TYPE_DIGITAL, | ||
1003 | .ranges = tuner_philips_fmd1216me_mk3_dvb_ranges, | ||
1004 | .count = ARRAY_SIZE(tuner_philips_fmd1216me_mk3_dvb_ranges), | ||
1005 | .iffreq = 16 * 36.125, /*MHz*/ | ||
1006 | }, | ||
1007 | }; | ||
987 | 1008 | ||
988 | /* ------ TUNER_LG_TDVS_H06XF - LG INNOTEK / INFINEON ATSC ----- */ | 1009 | /* ------ TUNER_LG_TDVS_H06XF - LG INNOTEK / INFINEON ATSC ----- */ |
989 | 1010 | ||
@@ -1663,6 +1684,16 @@ struct tunertype tuners[] = { | |||
1663 | .params = tuner_tcl_mf02gip_5n_params, | 1684 | .params = tuner_tcl_mf02gip_5n_params, |
1664 | .count = ARRAY_SIZE(tuner_tcl_mf02gip_5n_params), | 1685 | .count = ARRAY_SIZE(tuner_tcl_mf02gip_5n_params), |
1665 | }, | 1686 | }, |
1687 | [TUNER_PHILIPS_FMD1216MEX_MK3] = { /* Philips PAL */ | ||
1688 | .name = "Philips FMD1216MEX MK3 Hybrid Tuner", | ||
1689 | .params = tuner_philips_fmd1216mex_mk3_params, | ||
1690 | .count = ARRAY_SIZE(tuner_philips_fmd1216mex_mk3_params), | ||
1691 | .min = 16 * 50.87, | ||
1692 | .max = 16 * 858.00, | ||
1693 | .stepsize = 166667, | ||
1694 | .initdata = tua603x_agc112, | ||
1695 | .sleepdata = (u8[]){ 4, 0x9c, 0x60, 0x85, 0x54 }, | ||
1696 | }, | ||
1666 | }; | 1697 | }; |
1667 | EXPORT_SYMBOL(tuners); | 1698 | EXPORT_SYMBOL(tuners); |
1668 | 1699 | ||
diff --git a/drivers/media/common/tuners/xc5000.c b/drivers/media/common/tuners/xc5000.c index f9c2bb917f54..e12d13e0cbe9 100644 --- a/drivers/media/common/tuners/xc5000.c +++ b/drivers/media/common/tuners/xc5000.c | |||
@@ -43,7 +43,7 @@ MODULE_PARM_DESC(init_fw, "Load firmware during driver initialization."); | |||
43 | static DEFINE_MUTEX(xc5000_list_mutex); | 43 | static DEFINE_MUTEX(xc5000_list_mutex); |
44 | static LIST_HEAD(hybrid_tuner_instance_list); | 44 | static LIST_HEAD(hybrid_tuner_instance_list); |
45 | 45 | ||
46 | #define dprintk(level,fmt, arg...) if (debug >= level) \ | 46 | #define dprintk(level, fmt, arg...) if (debug >= level) \ |
47 | printk(KERN_INFO "%s: " fmt, "xc5000", ## arg) | 47 | printk(KERN_INFO "%s: " fmt, "xc5000", ## arg) |
48 | 48 | ||
49 | #define XC5000_DEFAULT_FIRMWARE "dvb-fe-xc5000-1.1.fw" | 49 | #define XC5000_DEFAULT_FIRMWARE "dvb-fe-xc5000-1.1.fw" |
@@ -138,11 +138,11 @@ struct xc5000_priv { | |||
138 | immediately the length of the following transaction. | 138 | immediately the length of the following transaction. |
139 | 139 | ||
140 | */ | 140 | */ |
141 | typedef struct { | 141 | struct XC_TV_STANDARD { |
142 | char *Name; | 142 | char *Name; |
143 | u16 AudioMode; | 143 | u16 AudioMode; |
144 | u16 VideoMode; | 144 | u16 VideoMode; |
145 | } XC_TV_STANDARD; | 145 | }; |
146 | 146 | ||
147 | /* Tuner standards */ | 147 | /* Tuner standards */ |
148 | #define MN_NTSC_PAL_BTSC 0 | 148 | #define MN_NTSC_PAL_BTSC 0 |
@@ -169,7 +169,7 @@ typedef struct { | |||
169 | #define FM_Radio_INPUT2 21 | 169 | #define FM_Radio_INPUT2 21 |
170 | #define FM_Radio_INPUT1 22 | 170 | #define FM_Radio_INPUT1 22 |
171 | 171 | ||
172 | static XC_TV_STANDARD XC5000_Standard[MAX_TV_STANDARD] = { | 172 | static struct XC_TV_STANDARD XC5000_Standard[MAX_TV_STANDARD] = { |
173 | {"M/N-NTSC/PAL-BTSC", 0x0400, 0x8020}, | 173 | {"M/N-NTSC/PAL-BTSC", 0x0400, 0x8020}, |
174 | {"M/N-NTSC/PAL-A2", 0x0600, 0x8020}, | 174 | {"M/N-NTSC/PAL-A2", 0x0600, 0x8020}, |
175 | {"M/N-NTSC/PAL-EIAJ", 0x0440, 0x8020}, | 175 | {"M/N-NTSC/PAL-EIAJ", 0x0440, 0x8020}, |
@@ -183,7 +183,7 @@ static XC_TV_STANDARD XC5000_Standard[MAX_TV_STANDARD] = { | |||
183 | {"D/K-PAL-NICAM", 0x0E80, 0x8009}, | 183 | {"D/K-PAL-NICAM", 0x0E80, 0x8009}, |
184 | {"D/K-PAL-MONO", 0x1478, 0x8009}, | 184 | {"D/K-PAL-MONO", 0x1478, 0x8009}, |
185 | {"D/K-SECAM-A2 DK1", 0x1200, 0x8009}, | 185 | {"D/K-SECAM-A2 DK1", 0x1200, 0x8009}, |
186 | {"D/K-SECAM-A2 L/DK3",0x0E00, 0x8009}, | 186 | {"D/K-SECAM-A2 L/DK3", 0x0E00, 0x8009}, |
187 | {"D/K-SECAM-A2 MONO", 0x1478, 0x8009}, | 187 | {"D/K-SECAM-A2 MONO", 0x1478, 0x8009}, |
188 | {"L-SECAM-NICAM", 0x8E82, 0x0009}, | 188 | {"L-SECAM-NICAM", 0x8E82, 0x0009}, |
189 | {"L'-SECAM-NICAM", 0x8E82, 0x4009}, | 189 | {"L'-SECAM-NICAM", 0x8E82, 0x4009}, |
@@ -307,9 +307,10 @@ static int xc_load_i2c_sequence(struct dvb_frontend *fe, const u8 *i2c_sequence) | |||
307 | unsigned int len, pos, index; | 307 | unsigned int len, pos, index; |
308 | u8 buf[XC_MAX_I2C_WRITE_LENGTH]; | 308 | u8 buf[XC_MAX_I2C_WRITE_LENGTH]; |
309 | 309 | ||
310 | index=0; | 310 | index = 0; |
311 | while ((i2c_sequence[index]!=0xFF) || (i2c_sequence[index+1]!=0xFF)) { | 311 | while ((i2c_sequence[index] != 0xFF) || |
312 | len = i2c_sequence[index]* 256 + i2c_sequence[index+1]; | 312 | (i2c_sequence[index + 1] != 0xFF)) { |
313 | len = i2c_sequence[index] * 256 + i2c_sequence[index+1]; | ||
313 | if (len == 0x0000) { | 314 | if (len == 0x0000) { |
314 | /* RESET command */ | 315 | /* RESET command */ |
315 | result = xc_reset(fe); | 316 | result = xc_reset(fe); |
@@ -329,15 +330,17 @@ static int xc_load_i2c_sequence(struct dvb_frontend *fe, const u8 *i2c_sequence) | |||
329 | buf[1] = i2c_sequence[index + 1]; | 330 | buf[1] = i2c_sequence[index + 1]; |
330 | pos = 2; | 331 | pos = 2; |
331 | while (pos < len) { | 332 | while (pos < len) { |
332 | if ((len - pos) > XC_MAX_I2C_WRITE_LENGTH - 2) { | 333 | if ((len - pos) > XC_MAX_I2C_WRITE_LENGTH - 2) |
333 | nbytes_to_send = XC_MAX_I2C_WRITE_LENGTH; | 334 | nbytes_to_send = |
334 | } else { | 335 | XC_MAX_I2C_WRITE_LENGTH; |
336 | else | ||
335 | nbytes_to_send = (len - pos + 2); | 337 | nbytes_to_send = (len - pos + 2); |
338 | for (i = 2; i < nbytes_to_send; i++) { | ||
339 | buf[i] = i2c_sequence[index + pos + | ||
340 | i - 2]; | ||
336 | } | 341 | } |
337 | for (i=2; i<nbytes_to_send; i++) { | 342 | result = xc_send_i2c_data(priv, buf, |
338 | buf[i] = i2c_sequence[index + pos + i - 2]; | 343 | nbytes_to_send); |
339 | } | ||
340 | result = xc_send_i2c_data(priv, buf, nbytes_to_send); | ||
341 | 344 | ||
342 | if (result != XC_RESULT_SUCCESS) | 345 | if (result != XC_RESULT_SUCCESS) |
343 | return result; | 346 | return result; |
@@ -386,8 +389,7 @@ static int xc_SetSignalSource(struct xc5000_priv *priv, u16 rf_mode) | |||
386 | dprintk(1, "%s(%d) Source = %s\n", __func__, rf_mode, | 389 | dprintk(1, "%s(%d) Source = %s\n", __func__, rf_mode, |
387 | rf_mode == XC_RF_MODE_AIR ? "ANTENNA" : "CABLE"); | 390 | rf_mode == XC_RF_MODE_AIR ? "ANTENNA" : "CABLE"); |
388 | 391 | ||
389 | if ((rf_mode != XC_RF_MODE_AIR) && (rf_mode != XC_RF_MODE_CABLE)) | 392 | if ((rf_mode != XC_RF_MODE_AIR) && (rf_mode != XC_RF_MODE_CABLE)) { |
390 | { | ||
391 | rf_mode = XC_RF_MODE_CABLE; | 393 | rf_mode = XC_RF_MODE_CABLE; |
392 | printk(KERN_ERR | 394 | printk(KERN_ERR |
393 | "%s(), Invalid mode, defaulting to CABLE", | 395 | "%s(), Invalid mode, defaulting to CABLE", |
@@ -560,13 +562,13 @@ static int xc5000_readregs(struct xc5000_priv *priv, u8 *buf, u8 len) | |||
560 | .flags = I2C_M_RD, .buf = buf, .len = len }; | 562 | .flags = I2C_M_RD, .buf = buf, .len = len }; |
561 | 563 | ||
562 | if (i2c_transfer(priv->i2c_props.adap, &msg, 1) != 1) { | 564 | if (i2c_transfer(priv->i2c_props.adap, &msg, 1) != 1) { |
563 | printk(KERN_ERR "xc5000 I2C read failed (len=%i)\n",(int)len); | 565 | printk(KERN_ERR "xc5000 I2C read failed (len=%i)\n", (int)len); |
564 | return -EREMOTEIO; | 566 | return -EREMOTEIO; |
565 | } | 567 | } |
566 | return 0; | 568 | return 0; |
567 | } | 569 | } |
568 | 570 | ||
569 | static int xc5000_fwupload(struct dvb_frontend* fe) | 571 | static int xc5000_fwupload(struct dvb_frontend *fe) |
570 | { | 572 | { |
571 | struct xc5000_priv *priv = fe->tuner_priv; | 573 | struct xc5000_priv *priv = fe->tuner_priv; |
572 | const struct firmware *fw; | 574 | const struct firmware *fw; |
@@ -576,7 +578,8 @@ static int xc5000_fwupload(struct dvb_frontend* fe) | |||
576 | printk(KERN_INFO "xc5000: waiting for firmware upload (%s)...\n", | 578 | printk(KERN_INFO "xc5000: waiting for firmware upload (%s)...\n", |
577 | XC5000_DEFAULT_FIRMWARE); | 579 | XC5000_DEFAULT_FIRMWARE); |
578 | 580 | ||
579 | ret = request_firmware(&fw, XC5000_DEFAULT_FIRMWARE, &priv->i2c_props.adap->dev); | 581 | ret = request_firmware(&fw, XC5000_DEFAULT_FIRMWARE, |
582 | &priv->i2c_props.adap->dev); | ||
580 | if (ret) { | 583 | if (ret) { |
581 | printk(KERN_ERR "xc5000: Upload failed. (file not found?)\n"); | 584 | printk(KERN_ERR "xc5000: Upload failed. (file not found?)\n"); |
582 | ret = XC_RESULT_RESET_FAILURE; | 585 | ret = XC_RESULT_RESET_FAILURE; |
@@ -592,7 +595,7 @@ static int xc5000_fwupload(struct dvb_frontend* fe) | |||
592 | ret = XC_RESULT_RESET_FAILURE; | 595 | ret = XC_RESULT_RESET_FAILURE; |
593 | } else { | 596 | } else { |
594 | printk(KERN_INFO "xc5000: firmware upload\n"); | 597 | printk(KERN_INFO "xc5000: firmware upload\n"); |
595 | ret = xc_load_i2c_sequence(fe, fw->data ); | 598 | ret = xc_load_i2c_sequence(fe, fw->data); |
596 | } | 599 | } |
597 | 600 | ||
598 | out: | 601 | out: |
@@ -651,7 +654,7 @@ static int xc5000_set_params(struct dvb_frontend *fe, | |||
651 | 654 | ||
652 | dprintk(1, "%s() frequency=%d (Hz)\n", __func__, params->frequency); | 655 | dprintk(1, "%s() frequency=%d (Hz)\n", __func__, params->frequency); |
653 | 656 | ||
654 | switch(params->u.vsb.modulation) { | 657 | switch (params->u.vsb.modulation) { |
655 | case VSB_8: | 658 | case VSB_8: |
656 | case VSB_16: | 659 | case VSB_16: |
657 | dprintk(1, "%s() VSB modulation\n", __func__); | 660 | dprintk(1, "%s() VSB modulation\n", __func__); |
@@ -748,42 +751,42 @@ static int xc5000_set_analog_params(struct dvb_frontend *fe, | |||
748 | /* FIX ME: Some video standards may have several possible audio | 751 | /* FIX ME: Some video standards may have several possible audio |
749 | standards. We simply default to one of them here. | 752 | standards. We simply default to one of them here. |
750 | */ | 753 | */ |
751 | if(params->std & V4L2_STD_MN) { | 754 | if (params->std & V4L2_STD_MN) { |
752 | /* default to BTSC audio standard */ | 755 | /* default to BTSC audio standard */ |
753 | priv->video_standard = MN_NTSC_PAL_BTSC; | 756 | priv->video_standard = MN_NTSC_PAL_BTSC; |
754 | goto tune_channel; | 757 | goto tune_channel; |
755 | } | 758 | } |
756 | 759 | ||
757 | if(params->std & V4L2_STD_PAL_BG) { | 760 | if (params->std & V4L2_STD_PAL_BG) { |
758 | /* default to NICAM audio standard */ | 761 | /* default to NICAM audio standard */ |
759 | priv->video_standard = BG_PAL_NICAM; | 762 | priv->video_standard = BG_PAL_NICAM; |
760 | goto tune_channel; | 763 | goto tune_channel; |
761 | } | 764 | } |
762 | 765 | ||
763 | if(params->std & V4L2_STD_PAL_I) { | 766 | if (params->std & V4L2_STD_PAL_I) { |
764 | /* default to NICAM audio standard */ | 767 | /* default to NICAM audio standard */ |
765 | priv->video_standard = I_PAL_NICAM; | 768 | priv->video_standard = I_PAL_NICAM; |
766 | goto tune_channel; | 769 | goto tune_channel; |
767 | } | 770 | } |
768 | 771 | ||
769 | if(params->std & V4L2_STD_PAL_DK) { | 772 | if (params->std & V4L2_STD_PAL_DK) { |
770 | /* default to NICAM audio standard */ | 773 | /* default to NICAM audio standard */ |
771 | priv->video_standard = DK_PAL_NICAM; | 774 | priv->video_standard = DK_PAL_NICAM; |
772 | goto tune_channel; | 775 | goto tune_channel; |
773 | } | 776 | } |
774 | 777 | ||
775 | if(params->std & V4L2_STD_SECAM_DK) { | 778 | if (params->std & V4L2_STD_SECAM_DK) { |
776 | /* default to A2 DK1 audio standard */ | 779 | /* default to A2 DK1 audio standard */ |
777 | priv->video_standard = DK_SECAM_A2DK1; | 780 | priv->video_standard = DK_SECAM_A2DK1; |
778 | goto tune_channel; | 781 | goto tune_channel; |
779 | } | 782 | } |
780 | 783 | ||
781 | if(params->std & V4L2_STD_SECAM_L) { | 784 | if (params->std & V4L2_STD_SECAM_L) { |
782 | priv->video_standard = L_SECAM_NICAM; | 785 | priv->video_standard = L_SECAM_NICAM; |
783 | goto tune_channel; | 786 | goto tune_channel; |
784 | } | 787 | } |
785 | 788 | ||
786 | if(params->std & V4L2_STD_SECAM_LC) { | 789 | if (params->std & V4L2_STD_SECAM_LC) { |
787 | priv->video_standard = LC_SECAM_NICAM; | 790 | priv->video_standard = LC_SECAM_NICAM; |
788 | goto tune_channel; | 791 | goto tune_channel; |
789 | } | 792 | } |
@@ -791,7 +794,7 @@ static int xc5000_set_analog_params(struct dvb_frontend *fe, | |||
791 | tune_channel: | 794 | tune_channel: |
792 | ret = xc_SetSignalSource(priv, priv->rf_mode); | 795 | ret = xc_SetSignalSource(priv, priv->rf_mode); |
793 | if (ret != XC_RESULT_SUCCESS) { | 796 | if (ret != XC_RESULT_SUCCESS) { |
794 | printk(KERN_ERR | 797 | printk(KERN_ERR |
795 | "xc5000: xc_SetSignalSource(%d) failed\n", | 798 | "xc5000: xc_SetSignalSource(%d) failed\n", |
796 | priv->rf_mode); | 799 | priv->rf_mode); |
797 | return -EREMOTEIO; | 800 | return -EREMOTEIO; |
@@ -863,7 +866,7 @@ static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe) | |||
863 | * I2C transactions until calibration is complete. This way we | 866 | * I2C transactions until calibration is complete. This way we |
864 | * don't have to rely on clock stretching working. | 867 | * don't have to rely on clock stretching working. |
865 | */ | 868 | */ |
866 | xc_wait( 100 ); | 869 | xc_wait(100); |
867 | 870 | ||
868 | /* Default to "CABLE" mode */ | 871 | /* Default to "CABLE" mode */ |
869 | ret |= xc_write_reg(priv, XREG_SIGNALSOURCE, XC_RF_MODE_CABLE); | 872 | ret |= xc_write_reg(priv, XREG_SIGNALSOURCE, XC_RF_MODE_CABLE); |
@@ -885,15 +888,13 @@ static int xc5000_sleep(struct dvb_frontend *fe) | |||
885 | */ | 888 | */ |
886 | 889 | ||
887 | ret = xc_shutdown(priv); | 890 | ret = xc_shutdown(priv); |
888 | if(ret != XC_RESULT_SUCCESS) { | 891 | if (ret != XC_RESULT_SUCCESS) { |
889 | printk(KERN_ERR | 892 | printk(KERN_ERR |
890 | "xc5000: %s() unable to shutdown tuner\n", | 893 | "xc5000: %s() unable to shutdown tuner\n", |
891 | __func__); | 894 | __func__); |
892 | return -EREMOTEIO; | 895 | return -EREMOTEIO; |
893 | } | 896 | } else |
894 | else { | ||
895 | return XC_RESULT_SUCCESS; | 897 | return XC_RESULT_SUCCESS; |
896 | } | ||
897 | } | 898 | } |
898 | 899 | ||
899 | static int xc5000_init(struct dvb_frontend *fe) | 900 | static int xc5000_init(struct dvb_frontend *fe) |
@@ -989,7 +990,7 @@ struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe, | |||
989 | if (xc5000_readreg(priv, XREG_PRODUCT_ID, &id) != 0) | 990 | if (xc5000_readreg(priv, XREG_PRODUCT_ID, &id) != 0) |
990 | goto fail; | 991 | goto fail; |
991 | 992 | ||
992 | switch(id) { | 993 | switch (id) { |
993 | case XC_PRODUCT_ID_FW_LOADED: | 994 | case XC_PRODUCT_ID_FW_LOADED: |
994 | printk(KERN_INFO | 995 | printk(KERN_INFO |
995 | "xc5000: Successfully identified at address 0x%02x\n", | 996 | "xc5000: Successfully identified at address 0x%02x\n", |
diff --git a/drivers/media/common/tuners/xc5000.h b/drivers/media/common/tuners/xc5000.h index cf1a558e0e7f..f4c146698a00 100644 --- a/drivers/media/common/tuners/xc5000.h +++ b/drivers/media/common/tuners/xc5000.h | |||
@@ -45,17 +45,17 @@ struct xc5000_config { | |||
45 | 45 | ||
46 | #if defined(CONFIG_MEDIA_TUNER_XC5000) || \ | 46 | #if defined(CONFIG_MEDIA_TUNER_XC5000) || \ |
47 | (defined(CONFIG_MEDIA_TUNER_XC5000_MODULE) && defined(MODULE)) | 47 | (defined(CONFIG_MEDIA_TUNER_XC5000_MODULE) && defined(MODULE)) |
48 | extern struct dvb_frontend* xc5000_attach(struct dvb_frontend *fe, | 48 | extern struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe, |
49 | struct i2c_adapter *i2c, | 49 | struct i2c_adapter *i2c, |
50 | struct xc5000_config *cfg); | 50 | struct xc5000_config *cfg); |
51 | #else | 51 | #else |
52 | static inline struct dvb_frontend* xc5000_attach(struct dvb_frontend *fe, | 52 | static inline struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe, |
53 | struct i2c_adapter *i2c, | 53 | struct i2c_adapter *i2c, |
54 | struct xc5000_config *cfg) | 54 | struct xc5000_config *cfg) |
55 | { | 55 | { |
56 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | 56 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); |
57 | return NULL; | 57 | return NULL; |
58 | } | 58 | } |
59 | #endif // CONFIG_MEDIA_TUNER_XC5000 | 59 | #endif |
60 | 60 | ||
61 | #endif // __XC5000_H__ | 61 | #endif |
diff --git a/drivers/media/dvb/dm1105/dm1105.c b/drivers/media/dvb/dm1105/dm1105.c index f7321448b4b1..14e627ef6465 100644 --- a/drivers/media/dvb/dm1105/dm1105.c +++ b/drivers/media/dvb/dm1105/dm1105.c | |||
@@ -595,6 +595,18 @@ static void dm1105dvb_hw_exit(struct dm1105dvb *dm1105dvb) | |||
595 | dm1105dvb_dma_unmap(dm1105dvb); | 595 | dm1105dvb_dma_unmap(dm1105dvb); |
596 | } | 596 | } |
597 | 597 | ||
598 | static struct stv0299_config sharp_z0194a_config = { | ||
599 | .demod_address = 0x68, | ||
600 | .inittab = sharp_z0194a_inittab, | ||
601 | .mclk = 88000000UL, | ||
602 | .invert = 1, | ||
603 | .skip_reinit = 0, | ||
604 | .lock_output = STV0299_LOCKOUTPUT_1, | ||
605 | .volt13_op0_op1 = STV0299_VOLT13_OP1, | ||
606 | .min_delay_ms = 100, | ||
607 | .set_symbol_rate = sharp_z0194a_set_symbol_rate, | ||
608 | }; | ||
609 | |||
598 | static struct stv0288_config earda_config = { | 610 | static struct stv0288_config earda_config = { |
599 | .demod_address = 0x68, | 611 | .demod_address = 0x68, |
600 | .min_delay_ms = 100, | 612 | .min_delay_ms = 100, |
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c index f170e822fadc..5689d1f1d444 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb/dvb-core/dvb_frontend.c | |||
@@ -47,6 +47,7 @@ static int dvb_shutdown_timeout; | |||
47 | static int dvb_force_auto_inversion; | 47 | static int dvb_force_auto_inversion; |
48 | static int dvb_override_tune_delay; | 48 | static int dvb_override_tune_delay; |
49 | static int dvb_powerdown_on_sleep = 1; | 49 | static int dvb_powerdown_on_sleep = 1; |
50 | static int dvb_mfe_wait_time = 5; | ||
50 | 51 | ||
51 | module_param_named(frontend_debug, dvb_frontend_debug, int, 0644); | 52 | module_param_named(frontend_debug, dvb_frontend_debug, int, 0644); |
52 | MODULE_PARM_DESC(frontend_debug, "Turn on/off frontend core debugging (default:off)."); | 53 | MODULE_PARM_DESC(frontend_debug, "Turn on/off frontend core debugging (default:off)."); |
@@ -58,6 +59,8 @@ module_param(dvb_override_tune_delay, int, 0644); | |||
58 | MODULE_PARM_DESC(dvb_override_tune_delay, "0: normal (default), >0 => delay in milliseconds to wait for lock after a tune attempt"); | 59 | MODULE_PARM_DESC(dvb_override_tune_delay, "0: normal (default), >0 => delay in milliseconds to wait for lock after a tune attempt"); |
59 | module_param(dvb_powerdown_on_sleep, int, 0644); | 60 | module_param(dvb_powerdown_on_sleep, int, 0644); |
60 | MODULE_PARM_DESC(dvb_powerdown_on_sleep, "0: do not power down, 1: turn LNB voltage off on sleep (default)"); | 61 | MODULE_PARM_DESC(dvb_powerdown_on_sleep, "0: do not power down, 1: turn LNB voltage off on sleep (default)"); |
62 | module_param(dvb_mfe_wait_time, int, 0644); | ||
63 | MODULE_PARM_DESC(dvb_mfe_wait_time, "Wait up to <mfe_wait_time> seconds on open() for multi-frontend to become available (default:5 seconds)"); | ||
61 | 64 | ||
62 | #define dprintk if (dvb_frontend_debug) printk | 65 | #define dprintk if (dvb_frontend_debug) printk |
63 | 66 | ||
@@ -212,8 +215,9 @@ static int dvb_frontend_get_event(struct dvb_frontend *fe, | |||
212 | 215 | ||
213 | static void dvb_frontend_init(struct dvb_frontend *fe) | 216 | static void dvb_frontend_init(struct dvb_frontend *fe) |
214 | { | 217 | { |
215 | dprintk ("DVB: initialising frontend %i (%s)...\n", | 218 | dprintk ("DVB: initialising adapter %i frontend %i (%s)...\n", |
216 | fe->dvb->num, | 219 | fe->dvb->num, |
220 | fe->id, | ||
217 | fe->ops.info.name); | 221 | fe->ops.info.name); |
218 | 222 | ||
219 | if (fe->ops.init) | 223 | if (fe->ops.init) |
@@ -686,7 +690,7 @@ static int dvb_frontend_start(struct dvb_frontend *fe) | |||
686 | mb(); | 690 | mb(); |
687 | 691 | ||
688 | fe_thread = kthread_run(dvb_frontend_thread, fe, | 692 | fe_thread = kthread_run(dvb_frontend_thread, fe, |
689 | "kdvb-fe-%i", fe->dvb->num); | 693 | "kdvb-ad-%i-fe-%i", fe->dvb->num,fe->id); |
690 | if (IS_ERR(fe_thread)) { | 694 | if (IS_ERR(fe_thread)) { |
691 | ret = PTR_ERR(fe_thread); | 695 | ret = PTR_ERR(fe_thread); |
692 | printk("dvb_frontend_start: failed to start kthread (%d)\n", ret); | 696 | printk("dvb_frontend_start: failed to start kthread (%d)\n", ret); |
@@ -710,8 +714,8 @@ static void dvb_frontend_get_frequeny_limits(struct dvb_frontend *fe, | |||
710 | *freq_max = min(fe->ops.info.frequency_max, fe->ops.tuner_ops.info.frequency_max); | 714 | *freq_max = min(fe->ops.info.frequency_max, fe->ops.tuner_ops.info.frequency_max); |
711 | 715 | ||
712 | if (*freq_min == 0 || *freq_max == 0) | 716 | if (*freq_min == 0 || *freq_max == 0) |
713 | printk(KERN_WARNING "DVB: frontend %u frequency limits undefined - fix the driver\n", | 717 | printk(KERN_WARNING "DVB: adapter %i frontend %u frequency limits undefined - fix the driver\n", |
714 | fe->dvb->num); | 718 | fe->dvb->num,fe->id); |
715 | } | 719 | } |
716 | 720 | ||
717 | static int dvb_frontend_check_parameters(struct dvb_frontend *fe, | 721 | static int dvb_frontend_check_parameters(struct dvb_frontend *fe, |
@@ -724,8 +728,8 @@ static int dvb_frontend_check_parameters(struct dvb_frontend *fe, | |||
724 | dvb_frontend_get_frequeny_limits(fe, &freq_min, &freq_max); | 728 | dvb_frontend_get_frequeny_limits(fe, &freq_min, &freq_max); |
725 | if ((freq_min && parms->frequency < freq_min) || | 729 | if ((freq_min && parms->frequency < freq_min) || |
726 | (freq_max && parms->frequency > freq_max)) { | 730 | (freq_max && parms->frequency > freq_max)) { |
727 | printk(KERN_WARNING "DVB: frontend %u frequency %u out of range (%u..%u)\n", | 731 | printk(KERN_WARNING "DVB: adapter %i frontend %i frequency %u out of range (%u..%u)\n", |
728 | fe->dvb->num, parms->frequency, freq_min, freq_max); | 732 | fe->dvb->num, fe->id, parms->frequency, freq_min, freq_max); |
729 | return -EINVAL; | 733 | return -EINVAL; |
730 | } | 734 | } |
731 | 735 | ||
@@ -735,8 +739,8 @@ static int dvb_frontend_check_parameters(struct dvb_frontend *fe, | |||
735 | parms->u.qpsk.symbol_rate < fe->ops.info.symbol_rate_min) || | 739 | parms->u.qpsk.symbol_rate < fe->ops.info.symbol_rate_min) || |
736 | (fe->ops.info.symbol_rate_max && | 740 | (fe->ops.info.symbol_rate_max && |
737 | parms->u.qpsk.symbol_rate > fe->ops.info.symbol_rate_max)) { | 741 | parms->u.qpsk.symbol_rate > fe->ops.info.symbol_rate_max)) { |
738 | printk(KERN_WARNING "DVB: frontend %u symbol rate %u out of range (%u..%u)\n", | 742 | printk(KERN_WARNING "DVB: adapter %i frontend %i symbol rate %u out of range (%u..%u)\n", |
739 | fe->dvb->num, parms->u.qpsk.symbol_rate, | 743 | fe->dvb->num, fe->id, parms->u.qpsk.symbol_rate, |
740 | fe->ops.info.symbol_rate_min, fe->ops.info.symbol_rate_max); | 744 | fe->ops.info.symbol_rate_min, fe->ops.info.symbol_rate_max); |
741 | return -EINVAL; | 745 | return -EINVAL; |
742 | } | 746 | } |
@@ -746,8 +750,8 @@ static int dvb_frontend_check_parameters(struct dvb_frontend *fe, | |||
746 | parms->u.qam.symbol_rate < fe->ops.info.symbol_rate_min) || | 750 | parms->u.qam.symbol_rate < fe->ops.info.symbol_rate_min) || |
747 | (fe->ops.info.symbol_rate_max && | 751 | (fe->ops.info.symbol_rate_max && |
748 | parms->u.qam.symbol_rate > fe->ops.info.symbol_rate_max)) { | 752 | parms->u.qam.symbol_rate > fe->ops.info.symbol_rate_max)) { |
749 | printk(KERN_WARNING "DVB: frontend %u symbol rate %u out of range (%u..%u)\n", | 753 | printk(KERN_WARNING "DVB: adapter %i frontend %i symbol rate %u out of range (%u..%u)\n", |
750 | fe->dvb->num, parms->u.qam.symbol_rate, | 754 | fe->dvb->num, fe->id, parms->u.qam.symbol_rate, |
751 | fe->ops.info.symbol_rate_min, fe->ops.info.symbol_rate_max); | 755 | fe->ops.info.symbol_rate_min, fe->ops.info.symbol_rate_max); |
752 | return -EINVAL; | 756 | return -EINVAL; |
753 | } | 757 | } |
@@ -899,30 +903,30 @@ void dtv_property_dump(struct dtv_property *tvp) | |||
899 | int i; | 903 | int i; |
900 | 904 | ||
901 | if (tvp->cmd <= 0 || tvp->cmd > DTV_MAX_COMMAND) { | 905 | if (tvp->cmd <= 0 || tvp->cmd > DTV_MAX_COMMAND) { |
902 | printk("%s: tvp.cmd = 0x%08x (undefined/unknown/invalid)\n", | 906 | printk(KERN_WARNING "%s: tvp.cmd = 0x%08x undefined\n", |
903 | __func__, tvp->cmd); | 907 | __func__, tvp->cmd); |
904 | return; | 908 | return; |
905 | } | 909 | } |
906 | 910 | ||
907 | printk("%s() tvp.cmd = 0x%08x (%s)\n" | 911 | dprintk("%s() tvp.cmd = 0x%08x (%s)\n" |
908 | ,__FUNCTION__ | 912 | ,__func__ |
909 | ,tvp->cmd | 913 | ,tvp->cmd |
910 | ,dtv_cmds[ tvp->cmd ].name); | 914 | ,dtv_cmds[ tvp->cmd ].name); |
911 | 915 | ||
912 | if(dtv_cmds[ tvp->cmd ].buffer) { | 916 | if(dtv_cmds[ tvp->cmd ].buffer) { |
913 | 917 | ||
914 | printk("%s() tvp.u.buffer.len = 0x%02x\n" | 918 | dprintk("%s() tvp.u.buffer.len = 0x%02x\n" |
915 | ,__FUNCTION__ | 919 | ,__func__ |
916 | ,tvp->u.buffer.len); | 920 | ,tvp->u.buffer.len); |
917 | 921 | ||
918 | for(i = 0; i < tvp->u.buffer.len; i++) | 922 | for(i = 0; i < tvp->u.buffer.len; i++) |
919 | printk("%s() tvp.u.buffer.data[0x%02x] = 0x%02x\n" | 923 | dprintk("%s() tvp.u.buffer.data[0x%02x] = 0x%02x\n" |
920 | ,__FUNCTION__ | 924 | ,__func__ |
921 | ,i | 925 | ,i |
922 | ,tvp->u.buffer.data[i]); | 926 | ,tvp->u.buffer.data[i]); |
923 | 927 | ||
924 | } else | 928 | } else |
925 | printk("%s() tvp.u.data = 0x%08x\n", __FUNCTION__, tvp->u.data); | 929 | dprintk("%s() tvp.u.data = 0x%08x\n", __func__, tvp->u.data); |
926 | } | 930 | } |
927 | 931 | ||
928 | int is_legacy_delivery_system(fe_delivery_system_t s) | 932 | int is_legacy_delivery_system(fe_delivery_system_t s) |
@@ -942,8 +946,6 @@ void dtv_property_cache_sync(struct dvb_frontend *fe, struct dvb_frontend_parame | |||
942 | { | 946 | { |
943 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | 947 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; |
944 | 948 | ||
945 | printk("%s()\n", __FUNCTION__); | ||
946 | |||
947 | c->frequency = p->frequency; | 949 | c->frequency = p->frequency; |
948 | c->inversion = p->inversion; | 950 | c->inversion = p->inversion; |
949 | 951 | ||
@@ -998,27 +1000,25 @@ void dtv_property_legacy_params_sync(struct dvb_frontend *fe) | |||
998 | struct dvb_frontend_private *fepriv = fe->frontend_priv; | 1000 | struct dvb_frontend_private *fepriv = fe->frontend_priv; |
999 | struct dvb_frontend_parameters *p = &fepriv->parameters; | 1001 | struct dvb_frontend_parameters *p = &fepriv->parameters; |
1000 | 1002 | ||
1001 | printk("%s()\n", __FUNCTION__); | ||
1002 | |||
1003 | p->frequency = c->frequency; | 1003 | p->frequency = c->frequency; |
1004 | p->inversion = c->inversion; | 1004 | p->inversion = c->inversion; |
1005 | 1005 | ||
1006 | switch (fe->ops.info.type) { | 1006 | switch (fe->ops.info.type) { |
1007 | case FE_QPSK: | 1007 | case FE_QPSK: |
1008 | printk("%s() Preparing QPSK req\n", __FUNCTION__); | 1008 | dprintk("%s() Preparing QPSK req\n", __func__); |
1009 | p->u.qpsk.symbol_rate = c->symbol_rate; | 1009 | p->u.qpsk.symbol_rate = c->symbol_rate; |
1010 | p->u.qpsk.fec_inner = c->fec_inner; | 1010 | p->u.qpsk.fec_inner = c->fec_inner; |
1011 | c->delivery_system = SYS_DVBS; | 1011 | c->delivery_system = SYS_DVBS; |
1012 | break; | 1012 | break; |
1013 | case FE_QAM: | 1013 | case FE_QAM: |
1014 | printk("%s() Preparing QAM req\n", __FUNCTION__); | 1014 | dprintk("%s() Preparing QAM req\n", __func__); |
1015 | p->u.qam.symbol_rate = c->symbol_rate; | 1015 | p->u.qam.symbol_rate = c->symbol_rate; |
1016 | p->u.qam.fec_inner = c->fec_inner; | 1016 | p->u.qam.fec_inner = c->fec_inner; |
1017 | p->u.qam.modulation = c->modulation; | 1017 | p->u.qam.modulation = c->modulation; |
1018 | c->delivery_system = SYS_DVBC_ANNEX_AC; | 1018 | c->delivery_system = SYS_DVBC_ANNEX_AC; |
1019 | break; | 1019 | break; |
1020 | case FE_OFDM: | 1020 | case FE_OFDM: |
1021 | printk("%s() Preparing OFDM req\n", __FUNCTION__); | 1021 | dprintk("%s() Preparing OFDM req\n", __func__); |
1022 | if (c->bandwidth_hz == 6000000) | 1022 | if (c->bandwidth_hz == 6000000) |
1023 | p->u.ofdm.bandwidth = BANDWIDTH_6_MHZ; | 1023 | p->u.ofdm.bandwidth = BANDWIDTH_6_MHZ; |
1024 | else if (c->bandwidth_hz == 7000000) | 1024 | else if (c->bandwidth_hz == 7000000) |
@@ -1036,7 +1036,7 @@ void dtv_property_legacy_params_sync(struct dvb_frontend *fe) | |||
1036 | c->delivery_system = SYS_DVBT; | 1036 | c->delivery_system = SYS_DVBT; |
1037 | break; | 1037 | break; |
1038 | case FE_ATSC: | 1038 | case FE_ATSC: |
1039 | printk("%s() Preparing VSB req\n", __FUNCTION__); | 1039 | dprintk("%s() Preparing VSB req\n", __func__); |
1040 | p->u.vsb.modulation = c->modulation; | 1040 | p->u.vsb.modulation = c->modulation; |
1041 | if ((c->modulation == VSB_8) || (c->modulation == VSB_16)) | 1041 | if ((c->modulation == VSB_8) || (c->modulation == VSB_16)) |
1042 | c->delivery_system = SYS_ATSC; | 1042 | c->delivery_system = SYS_ATSC; |
@@ -1055,14 +1055,13 @@ void dtv_property_adv_params_sync(struct dvb_frontend *fe) | |||
1055 | struct dvb_frontend_private *fepriv = fe->frontend_priv; | 1055 | struct dvb_frontend_private *fepriv = fe->frontend_priv; |
1056 | struct dvb_frontend_parameters *p = &fepriv->parameters; | 1056 | struct dvb_frontend_parameters *p = &fepriv->parameters; |
1057 | 1057 | ||
1058 | printk("%s()\n", __FUNCTION__); | ||
1059 | |||
1060 | p->frequency = c->frequency; | 1058 | p->frequency = c->frequency; |
1061 | p->inversion = c->inversion; | 1059 | p->inversion = c->inversion; |
1062 | 1060 | ||
1063 | switch(c->modulation) { | 1061 | switch(c->modulation) { |
1064 | case PSK_8: | 1062 | case PSK_8: |
1065 | case APSK_16: | 1063 | case APSK_16: |
1064 | case APSK_32: | ||
1066 | case QPSK: | 1065 | case QPSK: |
1067 | p->u.qpsk.symbol_rate = c->symbol_rate; | 1066 | p->u.qpsk.symbol_rate = c->symbol_rate; |
1068 | p->u.qpsk.fec_inner = c->fec_inner; | 1067 | p->u.qpsk.fec_inner = c->fec_inner; |
@@ -1089,19 +1088,17 @@ void dtv_property_cache_submit(struct dvb_frontend *fe) | |||
1089 | { | 1088 | { |
1090 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | 1089 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; |
1091 | 1090 | ||
1092 | printk("%s()\n", __FUNCTION__); | ||
1093 | |||
1094 | /* For legacy delivery systems we don't need the delivery_system to | 1091 | /* For legacy delivery systems we don't need the delivery_system to |
1095 | * be specified, but we populate the older structures from the cache | 1092 | * be specified, but we populate the older structures from the cache |
1096 | * so we can call set_frontend on older drivers. | 1093 | * so we can call set_frontend on older drivers. |
1097 | */ | 1094 | */ |
1098 | if(is_legacy_delivery_system(c->delivery_system)) { | 1095 | if(is_legacy_delivery_system(c->delivery_system)) { |
1099 | 1096 | ||
1100 | printk("%s() legacy, modulation = %d\n", __FUNCTION__, c->modulation); | 1097 | dprintk("%s() legacy, modulation = %d\n", __func__, c->modulation); |
1101 | dtv_property_legacy_params_sync(fe); | 1098 | dtv_property_legacy_params_sync(fe); |
1102 | 1099 | ||
1103 | } else { | 1100 | } else { |
1104 | printk("%s() adv, modulation = %d\n", __FUNCTION__, c->modulation); | 1101 | dprintk("%s() adv, modulation = %d\n", __func__, c->modulation); |
1105 | 1102 | ||
1106 | /* For advanced delivery systems / modulation types ... | 1103 | /* For advanced delivery systems / modulation types ... |
1107 | * we seed the lecacy dvb_frontend_parameters structure | 1104 | * we seed the lecacy dvb_frontend_parameters structure |
@@ -1123,8 +1120,6 @@ int dtv_property_process_get(struct dvb_frontend *fe, struct dtv_property *tvp, | |||
1123 | { | 1120 | { |
1124 | int r = 0; | 1121 | int r = 0; |
1125 | 1122 | ||
1126 | printk("%s()\n", __FUNCTION__); | ||
1127 | |||
1128 | dtv_property_dump(tvp); | 1123 | dtv_property_dump(tvp); |
1129 | 1124 | ||
1130 | /* Allow the frontend to validate incoming properties */ | 1125 | /* Allow the frontend to validate incoming properties */ |
@@ -1198,7 +1193,6 @@ int dtv_property_process_set(struct dvb_frontend *fe, struct dtv_property *tvp, | |||
1198 | { | 1193 | { |
1199 | int r = 0; | 1194 | int r = 0; |
1200 | struct dvb_frontend_private *fepriv = fe->frontend_priv; | 1195 | struct dvb_frontend_private *fepriv = fe->frontend_priv; |
1201 | printk("%s()\n", __FUNCTION__); | ||
1202 | dtv_property_dump(tvp); | 1196 | dtv_property_dump(tvp); |
1203 | 1197 | ||
1204 | /* Allow the frontend to validate incoming properties */ | 1198 | /* Allow the frontend to validate incoming properties */ |
@@ -1213,7 +1207,7 @@ int dtv_property_process_set(struct dvb_frontend *fe, struct dtv_property *tvp, | |||
1213 | /* Reset a cache of data specific to the frontend here. This does | 1207 | /* Reset a cache of data specific to the frontend here. This does |
1214 | * not effect hardware. | 1208 | * not effect hardware. |
1215 | */ | 1209 | */ |
1216 | printk("%s() Flushing property cache\n", __FUNCTION__); | 1210 | dprintk("%s() Flushing property cache\n", __func__); |
1217 | memset(&fe->dtv_property_cache, 0, sizeof(struct dtv_frontend_properties)); | 1211 | memset(&fe->dtv_property_cache, 0, sizeof(struct dtv_frontend_properties)); |
1218 | fe->dtv_property_cache.state = tvp->cmd; | 1212 | fe->dtv_property_cache.state = tvp->cmd; |
1219 | fe->dtv_property_cache.delivery_system = SYS_UNDEFINED; | 1213 | fe->dtv_property_cache.delivery_system = SYS_UNDEFINED; |
@@ -1224,7 +1218,7 @@ int dtv_property_process_set(struct dvb_frontend *fe, struct dtv_property *tvp, | |||
1224 | * ioctl. | 1218 | * ioctl. |
1225 | */ | 1219 | */ |
1226 | fe->dtv_property_cache.state = tvp->cmd; | 1220 | fe->dtv_property_cache.state = tvp->cmd; |
1227 | printk("%s() Finalised property cache\n", __FUNCTION__); | 1221 | dprintk("%s() Finalised property cache\n", __func__); |
1228 | dtv_property_cache_submit(fe); | 1222 | dtv_property_cache_submit(fe); |
1229 | 1223 | ||
1230 | r |= dvb_frontend_ioctl_legacy(inode, file, FE_SET_FRONTEND, | 1224 | r |= dvb_frontend_ioctl_legacy(inode, file, FE_SET_FRONTEND, |
@@ -1335,12 +1329,10 @@ static int dvb_frontend_ioctl_properties(struct inode *inode, struct file *file, | |||
1335 | dprintk("%s\n", __func__); | 1329 | dprintk("%s\n", __func__); |
1336 | 1330 | ||
1337 | if(cmd == FE_SET_PROPERTY) { | 1331 | if(cmd == FE_SET_PROPERTY) { |
1338 | printk("%s() FE_SET_PROPERTY\n", __FUNCTION__); | ||
1339 | |||
1340 | tvps = (struct dtv_properties __user *)parg; | 1332 | tvps = (struct dtv_properties __user *)parg; |
1341 | 1333 | ||
1342 | printk("%s() properties.num = %d\n", __FUNCTION__, tvps->num); | 1334 | dprintk("%s() properties.num = %d\n", __func__, tvps->num); |
1343 | printk("%s() properties.props = %p\n", __FUNCTION__, tvps->props); | 1335 | dprintk("%s() properties.props = %p\n", __func__, tvps->props); |
1344 | 1336 | ||
1345 | /* Put an arbitrary limit on the number of messages that can | 1337 | /* Put an arbitrary limit on the number of messages that can |
1346 | * be sent at once */ | 1338 | * be sent at once */ |
@@ -1364,18 +1356,16 @@ static int dvb_frontend_ioctl_properties(struct inode *inode, struct file *file, | |||
1364 | err |= (tvp + i)->result; | 1356 | err |= (tvp + i)->result; |
1365 | } | 1357 | } |
1366 | 1358 | ||
1367 | if(fe->dtv_property_cache.state == DTV_TUNE) { | 1359 | if(fe->dtv_property_cache.state == DTV_TUNE) |
1368 | printk("%s() Property cache is full, tuning\n", __FUNCTION__); | 1360 | dprintk("%s() Property cache is full, tuning\n", __func__); |
1369 | } | ||
1370 | 1361 | ||
1371 | } else | 1362 | } else |
1372 | if(cmd == FE_GET_PROPERTY) { | 1363 | if(cmd == FE_GET_PROPERTY) { |
1373 | printk("%s() FE_GET_PROPERTY\n", __FUNCTION__); | ||
1374 | 1364 | ||
1375 | tvps = (struct dtv_properties __user *)parg; | 1365 | tvps = (struct dtv_properties __user *)parg; |
1376 | 1366 | ||
1377 | printk("%s() properties.num = %d\n", __FUNCTION__, tvps->num); | 1367 | dprintk("%s() properties.num = %d\n", __func__, tvps->num); |
1378 | printk("%s() properties.props = %p\n", __FUNCTION__, tvps->props); | 1368 | dprintk("%s() properties.props = %p\n", __func__, tvps->props); |
1379 | 1369 | ||
1380 | /* Put an arbitrary limit on the number of messages that can | 1370 | /* Put an arbitrary limit on the number of messages that can |
1381 | * be sent at once */ | 1371 | * be sent at once */ |
@@ -1704,13 +1694,53 @@ static int dvb_frontend_open(struct inode *inode, struct file *file) | |||
1704 | struct dvb_device *dvbdev = file->private_data; | 1694 | struct dvb_device *dvbdev = file->private_data; |
1705 | struct dvb_frontend *fe = dvbdev->priv; | 1695 | struct dvb_frontend *fe = dvbdev->priv; |
1706 | struct dvb_frontend_private *fepriv = fe->frontend_priv; | 1696 | struct dvb_frontend_private *fepriv = fe->frontend_priv; |
1697 | struct dvb_adapter *adapter = fe->dvb; | ||
1707 | int ret; | 1698 | int ret; |
1708 | 1699 | ||
1709 | dprintk ("%s\n", __func__); | 1700 | dprintk ("%s\n", __func__); |
1710 | 1701 | ||
1702 | if (adapter->mfe_shared) { | ||
1703 | mutex_lock (&adapter->mfe_lock); | ||
1704 | |||
1705 | if (adapter->mfe_dvbdev == NULL) | ||
1706 | adapter->mfe_dvbdev = dvbdev; | ||
1707 | |||
1708 | else if (adapter->mfe_dvbdev != dvbdev) { | ||
1709 | struct dvb_device | ||
1710 | *mfedev = adapter->mfe_dvbdev; | ||
1711 | struct dvb_frontend | ||
1712 | *mfe = mfedev->priv; | ||
1713 | struct dvb_frontend_private | ||
1714 | *mfepriv = mfe->frontend_priv; | ||
1715 | int mferetry = (dvb_mfe_wait_time << 1); | ||
1716 | |||
1717 | mutex_unlock (&adapter->mfe_lock); | ||
1718 | while (mferetry-- && (mfedev->users != -1 || | ||
1719 | mfepriv->thread != NULL)) { | ||
1720 | if(msleep_interruptible(500)) { | ||
1721 | if(signal_pending(current)) | ||
1722 | return -EINTR; | ||
1723 | } | ||
1724 | } | ||
1725 | |||
1726 | mutex_lock (&adapter->mfe_lock); | ||
1727 | if(adapter->mfe_dvbdev != dvbdev) { | ||
1728 | mfedev = adapter->mfe_dvbdev; | ||
1729 | mfe = mfedev->priv; | ||
1730 | mfepriv = mfe->frontend_priv; | ||
1731 | if (mfedev->users != -1 || | ||
1732 | mfepriv->thread != NULL) { | ||
1733 | mutex_unlock (&adapter->mfe_lock); | ||
1734 | return -EBUSY; | ||
1735 | } | ||
1736 | adapter->mfe_dvbdev = dvbdev; | ||
1737 | } | ||
1738 | } | ||
1739 | } | ||
1740 | |||
1711 | if (dvbdev->users == -1 && fe->ops.ts_bus_ctrl) { | 1741 | if (dvbdev->users == -1 && fe->ops.ts_bus_ctrl) { |
1712 | if ((ret = fe->ops.ts_bus_ctrl(fe, 1)) < 0) | 1742 | if ((ret = fe->ops.ts_bus_ctrl(fe, 1)) < 0) |
1713 | return ret; | 1743 | goto err0; |
1714 | } | 1744 | } |
1715 | 1745 | ||
1716 | if ((ret = dvb_generic_open (inode, file)) < 0) | 1746 | if ((ret = dvb_generic_open (inode, file)) < 0) |
@@ -1730,6 +1760,8 @@ static int dvb_frontend_open(struct inode *inode, struct file *file) | |||
1730 | fepriv->events.eventr = fepriv->events.eventw = 0; | 1760 | fepriv->events.eventr = fepriv->events.eventw = 0; |
1731 | } | 1761 | } |
1732 | 1762 | ||
1763 | if (adapter->mfe_shared) | ||
1764 | mutex_unlock (&adapter->mfe_lock); | ||
1733 | return ret; | 1765 | return ret; |
1734 | 1766 | ||
1735 | err2: | 1767 | err2: |
@@ -1737,6 +1769,9 @@ err2: | |||
1737 | err1: | 1769 | err1: |
1738 | if (dvbdev->users == -1 && fe->ops.ts_bus_ctrl) | 1770 | if (dvbdev->users == -1 && fe->ops.ts_bus_ctrl) |
1739 | fe->ops.ts_bus_ctrl(fe, 0); | 1771 | fe->ops.ts_bus_ctrl(fe, 0); |
1772 | err0: | ||
1773 | if (adapter->mfe_shared) | ||
1774 | mutex_unlock (&adapter->mfe_lock); | ||
1740 | return ret; | 1775 | return ret; |
1741 | } | 1776 | } |
1742 | 1777 | ||
@@ -1806,8 +1841,9 @@ int dvb_register_frontend(struct dvb_adapter* dvb, | |||
1806 | fe->dvb = dvb; | 1841 | fe->dvb = dvb; |
1807 | fepriv->inversion = INVERSION_OFF; | 1842 | fepriv->inversion = INVERSION_OFF; |
1808 | 1843 | ||
1809 | printk ("DVB: registering frontend %i (%s)...\n", | 1844 | printk ("DVB: registering adapter %i frontend %i (%s)...\n", |
1810 | fe->dvb->num, | 1845 | fe->dvb->num, |
1846 | fe->id, | ||
1811 | fe->ops.info.name); | 1847 | fe->ops.info.name); |
1812 | 1848 | ||
1813 | dvb_register_device (fe->dvb, &fepriv->dvbdev, &dvbdev_template, | 1849 | dvb_register_device (fe->dvb, &fepriv->dvbdev, &dvbdev_template, |
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.h b/drivers/media/dvb/dvb-core/dvb_frontend.h index 3055301ff3ca..db4a63b0a32e 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.h +++ b/drivers/media/dvb/dvb-core/dvb_frontend.h | |||
@@ -222,6 +222,7 @@ struct dvb_frontend { | |||
222 | struct dtv_frontend_properties dtv_property_cache; | 222 | struct dtv_frontend_properties dtv_property_cache; |
223 | #define DVB_FRONTEND_COMPONENT_TUNER 0 | 223 | #define DVB_FRONTEND_COMPONENT_TUNER 0 |
224 | int (*callback)(void *adapter_priv, int component, int cmd, int arg); | 224 | int (*callback)(void *adapter_priv, int component, int cmd, int arg); |
225 | int id; | ||
225 | }; | 226 | }; |
226 | 227 | ||
227 | extern int dvb_register_frontend(struct dvb_adapter *dvb, | 228 | extern int dvb_register_frontend(struct dvb_adapter *dvb, |
diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c index 665776d72a48..a113744a56cc 100644 --- a/drivers/media/dvb/dvb-core/dvbdev.c +++ b/drivers/media/dvb/dvb-core/dvbdev.c | |||
@@ -326,6 +326,9 @@ int dvb_register_adapter(struct dvb_adapter *adap, const char *name, | |||
326 | adap->name = name; | 326 | adap->name = name; |
327 | adap->module = module; | 327 | adap->module = module; |
328 | adap->device = device; | 328 | adap->device = device; |
329 | adap->mfe_shared = 0; | ||
330 | adap->mfe_dvbdev = NULL; | ||
331 | mutex_init (&adap->mfe_lock); | ||
329 | 332 | ||
330 | list_add_tail (&adap->list_head, &dvb_adapter_list); | 333 | list_add_tail (&adap->list_head, &dvb_adapter_list); |
331 | 334 | ||
diff --git a/drivers/media/dvb/dvb-core/dvbdev.h b/drivers/media/dvb/dvb-core/dvbdev.h index 89d12dc477a7..574e336bac35 100644 --- a/drivers/media/dvb/dvb-core/dvbdev.h +++ b/drivers/media/dvb/dvb-core/dvbdev.h | |||
@@ -62,6 +62,10 @@ struct dvb_adapter { | |||
62 | struct device *device; | 62 | struct device *device; |
63 | 63 | ||
64 | struct module *module; | 64 | struct module *module; |
65 | |||
66 | int mfe_shared; /* indicates mutually exclusive frontends */ | ||
67 | struct dvb_device *mfe_dvbdev; /* frontend device in use */ | ||
68 | struct mutex mfe_lock; /* access lock for thread creation */ | ||
65 | }; | 69 | }; |
66 | 70 | ||
67 | 71 | ||
diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c index ca53df61caa8..6286fbbe7fb5 100644 --- a/drivers/media/dvb/dvb-usb/dw2102.c +++ b/drivers/media/dvb/dvb-usb/dw2102.c | |||
@@ -422,6 +422,18 @@ static int dw210x_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) | |||
422 | return 0; | 422 | return 0; |
423 | } | 423 | } |
424 | 424 | ||
425 | static struct stv0299_config sharp_z0194a_config = { | ||
426 | .demod_address = 0x68, | ||
427 | .inittab = sharp_z0194a_inittab, | ||
428 | .mclk = 88000000UL, | ||
429 | .invert = 1, | ||
430 | .skip_reinit = 0, | ||
431 | .lock_output = STV0299_LOCKOUTPUT_1, | ||
432 | .volt13_op0_op1 = STV0299_VOLT13_OP1, | ||
433 | .min_delay_ms = 100, | ||
434 | .set_symbol_rate = sharp_z0194a_set_symbol_rate, | ||
435 | }; | ||
436 | |||
425 | static struct cx24116_config dw2104_config = { | 437 | static struct cx24116_config dw2104_config = { |
426 | .demod_address = 0x55, | 438 | .demod_address = 0x55, |
427 | .mpg_clk_pos_pol = 0x01, | 439 | .mpg_clk_pos_pol = 0x01, |
diff --git a/drivers/media/dvb/frontends/cx22702.c b/drivers/media/dvb/frontends/cx22702.c index 9430e03dba6c..5d1abe34bddb 100644 --- a/drivers/media/dvb/frontends/cx22702.c +++ b/drivers/media/dvb/frontends/cx22702.c | |||
@@ -34,13 +34,12 @@ | |||
34 | #include "dvb_frontend.h" | 34 | #include "dvb_frontend.h" |
35 | #include "cx22702.h" | 35 | #include "cx22702.h" |
36 | 36 | ||
37 | |||
38 | struct cx22702_state { | 37 | struct cx22702_state { |
39 | 38 | ||
40 | struct i2c_adapter* i2c; | 39 | struct i2c_adapter *i2c; |
41 | 40 | ||
42 | /* configuration settings */ | 41 | /* configuration settings */ |
43 | const struct cx22702_config* config; | 42 | const struct cx22702_config *config; |
44 | 43 | ||
45 | struct dvb_frontend frontend; | 44 | struct dvb_frontend frontend; |
46 | 45 | ||
@@ -49,10 +48,13 @@ struct cx22702_state { | |||
49 | }; | 48 | }; |
50 | 49 | ||
51 | static int debug; | 50 | static int debug; |
51 | module_param(debug, int, 0644); | ||
52 | MODULE_PARM_DESC(debug, "Enable verbose debug messages"); | ||
53 | |||
52 | #define dprintk if (debug) printk | 54 | #define dprintk if (debug) printk |
53 | 55 | ||
54 | /* Register values to initialise the demod */ | 56 | /* Register values to initialise the demod */ |
55 | static u8 init_tab [] = { | 57 | static u8 init_tab[] = { |
56 | 0x00, 0x00, /* Stop aquisition */ | 58 | 0x00, 0x00, /* Stop aquisition */ |
57 | 0x0B, 0x06, | 59 | 0x0B, 0x06, |
58 | 0x09, 0x01, | 60 | 0x09, 0x01, |
@@ -80,65 +82,67 @@ static u8 init_tab [] = { | |||
80 | 0xfd, 0x00, | 82 | 0xfd, 0x00, |
81 | }; | 83 | }; |
82 | 84 | ||
83 | static int cx22702_writereg (struct cx22702_state* state, u8 reg, u8 data) | 85 | static int cx22702_writereg(struct cx22702_state *state, u8 reg, u8 data) |
84 | { | 86 | { |
85 | int ret; | 87 | int ret; |
86 | u8 buf [] = { reg, data }; | 88 | u8 buf[] = { reg, data }; |
87 | struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 }; | 89 | struct i2c_msg msg = { |
90 | .addr = state->config->demod_address, .flags = 0, | ||
91 | .buf = buf, .len = 2 }; | ||
88 | 92 | ||
89 | ret = i2c_transfer(state->i2c, &msg, 1); | 93 | ret = i2c_transfer(state->i2c, &msg, 1); |
90 | 94 | ||
91 | if (ret != 1) | 95 | if (ret != 1) |
92 | printk("%s: writereg error (reg == 0x%02x, val == 0x%02x, ret == %i)\n", | 96 | printk(KERN_ERR |
97 | "%s: error (reg == 0x%02x, val == 0x%02x, ret == %i)\n", | ||
93 | __func__, reg, data, ret); | 98 | __func__, reg, data, ret); |
94 | 99 | ||
95 | return (ret != 1) ? -1 : 0; | 100 | return (ret != 1) ? -1 : 0; |
96 | } | 101 | } |
97 | 102 | ||
98 | static u8 cx22702_readreg (struct cx22702_state* state, u8 reg) | 103 | static u8 cx22702_readreg(struct cx22702_state *state, u8 reg) |
99 | { | 104 | { |
100 | int ret; | 105 | int ret; |
101 | u8 b0 [] = { reg }; | 106 | u8 b0[] = { reg }; |
102 | u8 b1 [] = { 0 }; | 107 | u8 b1[] = { 0 }; |
103 | 108 | ||
104 | struct i2c_msg msg [] = { | 109 | struct i2c_msg msg[] = { |
105 | { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 }, | 110 | { .addr = state->config->demod_address, .flags = 0, |
106 | { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } }; | 111 | .buf = b0, .len = 1 }, |
112 | { .addr = state->config->demod_address, .flags = I2C_M_RD, | ||
113 | .buf = b1, .len = 1 } }; | ||
107 | 114 | ||
108 | ret = i2c_transfer(state->i2c, msg, 2); | 115 | ret = i2c_transfer(state->i2c, msg, 2); |
109 | 116 | ||
110 | if (ret != 2) | 117 | if (ret != 2) |
111 | printk("%s: readreg error (ret == %i)\n", __func__, ret); | 118 | printk(KERN_ERR "%s: readreg error (ret == %i)\n", |
119 | __func__, ret); | ||
112 | 120 | ||
113 | return b1[0]; | 121 | return b1[0]; |
114 | } | 122 | } |
115 | 123 | ||
116 | static int cx22702_set_inversion (struct cx22702_state *state, int inversion) | 124 | static int cx22702_set_inversion(struct cx22702_state *state, int inversion) |
117 | { | 125 | { |
118 | u8 val; | 126 | u8 val; |
119 | 127 | ||
120 | switch (inversion) { | 128 | switch (inversion) { |
121 | 129 | case INVERSION_AUTO: | |
122 | case INVERSION_AUTO: | 130 | return -EOPNOTSUPP; |
123 | return -EOPNOTSUPP; | 131 | case INVERSION_ON: |
124 | 132 | val = cx22702_readreg(state, 0x0C); | |
125 | case INVERSION_ON: | 133 | return cx22702_writereg(state, 0x0C, val | 0x01); |
126 | val = cx22702_readreg (state, 0x0C); | 134 | case INVERSION_OFF: |
127 | return cx22702_writereg (state, 0x0C, val | 0x01); | 135 | val = cx22702_readreg(state, 0x0C); |
128 | 136 | return cx22702_writereg(state, 0x0C, val & 0xfe); | |
129 | case INVERSION_OFF: | 137 | default: |
130 | val = cx22702_readreg (state, 0x0C); | 138 | return -EINVAL; |
131 | return cx22702_writereg (state, 0x0C, val & 0xfe); | ||
132 | |||
133 | default: | ||
134 | return -EINVAL; | ||
135 | |||
136 | } | 139 | } |
137 | 140 | ||
138 | } | 141 | } |
139 | 142 | ||
140 | /* Retrieve the demod settings */ | 143 | /* Retrieve the demod settings */ |
141 | static int cx22702_get_tps (struct cx22702_state *state, struct dvb_ofdm_parameters *p) | 144 | static int cx22702_get_tps(struct cx22702_state *state, |
145 | struct dvb_ofdm_parameters *p) | ||
142 | { | 146 | { |
143 | u8 val; | 147 | u8 val; |
144 | 148 | ||
@@ -146,180 +150,281 @@ static int cx22702_get_tps (struct cx22702_state *state, struct dvb_ofdm_paramet | |||
146 | if (!(cx22702_readreg(state, 0x0A) & 0x20)) | 150 | if (!(cx22702_readreg(state, 0x0A) & 0x20)) |
147 | return -EAGAIN; | 151 | return -EAGAIN; |
148 | 152 | ||
149 | val = cx22702_readreg (state, 0x01); | 153 | val = cx22702_readreg(state, 0x01); |
150 | switch( (val&0x18)>>3) { | 154 | switch ((val & 0x18) >> 3) { |
151 | case 0: p->constellation = QPSK; break; | 155 | case 0: |
152 | case 1: p->constellation = QAM_16; break; | 156 | p->constellation = QPSK; |
153 | case 2: p->constellation = QAM_64; break; | 157 | break; |
158 | case 1: | ||
159 | p->constellation = QAM_16; | ||
160 | break; | ||
161 | case 2: | ||
162 | p->constellation = QAM_64; | ||
163 | break; | ||
154 | } | 164 | } |
155 | switch( val&0x07 ) { | 165 | switch (val & 0x07) { |
156 | case 0: p->hierarchy_information = HIERARCHY_NONE; break; | 166 | case 0: |
157 | case 1: p->hierarchy_information = HIERARCHY_1; break; | 167 | p->hierarchy_information = HIERARCHY_NONE; |
158 | case 2: p->hierarchy_information = HIERARCHY_2; break; | 168 | break; |
159 | case 3: p->hierarchy_information = HIERARCHY_4; break; | 169 | case 1: |
170 | p->hierarchy_information = HIERARCHY_1; | ||
171 | break; | ||
172 | case 2: | ||
173 | p->hierarchy_information = HIERARCHY_2; | ||
174 | break; | ||
175 | case 3: | ||
176 | p->hierarchy_information = HIERARCHY_4; | ||
177 | break; | ||
160 | } | 178 | } |
161 | 179 | ||
162 | 180 | ||
163 | val = cx22702_readreg (state, 0x02); | 181 | val = cx22702_readreg(state, 0x02); |
164 | switch( (val&0x38)>>3 ) { | 182 | switch ((val & 0x38) >> 3) { |
165 | case 0: p->code_rate_HP = FEC_1_2; break; | 183 | case 0: |
166 | case 1: p->code_rate_HP = FEC_2_3; break; | 184 | p->code_rate_HP = FEC_1_2; |
167 | case 2: p->code_rate_HP = FEC_3_4; break; | 185 | break; |
168 | case 3: p->code_rate_HP = FEC_5_6; break; | 186 | case 1: |
169 | case 4: p->code_rate_HP = FEC_7_8; break; | 187 | p->code_rate_HP = FEC_2_3; |
188 | break; | ||
189 | case 2: | ||
190 | p->code_rate_HP = FEC_3_4; | ||
191 | break; | ||
192 | case 3: | ||
193 | p->code_rate_HP = FEC_5_6; | ||
194 | break; | ||
195 | case 4: | ||
196 | p->code_rate_HP = FEC_7_8; | ||
197 | break; | ||
170 | } | 198 | } |
171 | switch( val&0x07 ) { | 199 | switch (val & 0x07) { |
172 | case 0: p->code_rate_LP = FEC_1_2; break; | 200 | case 0: |
173 | case 1: p->code_rate_LP = FEC_2_3; break; | 201 | p->code_rate_LP = FEC_1_2; |
174 | case 2: p->code_rate_LP = FEC_3_4; break; | 202 | break; |
175 | case 3: p->code_rate_LP = FEC_5_6; break; | 203 | case 1: |
176 | case 4: p->code_rate_LP = FEC_7_8; break; | 204 | p->code_rate_LP = FEC_2_3; |
205 | break; | ||
206 | case 2: | ||
207 | p->code_rate_LP = FEC_3_4; | ||
208 | break; | ||
209 | case 3: | ||
210 | p->code_rate_LP = FEC_5_6; | ||
211 | break; | ||
212 | case 4: | ||
213 | p->code_rate_LP = FEC_7_8; | ||
214 | break; | ||
177 | } | 215 | } |
178 | 216 | ||
179 | 217 | val = cx22702_readreg(state, 0x03); | |
180 | val = cx22702_readreg (state, 0x03); | 218 | switch ((val & 0x0c) >> 2) { |
181 | switch( (val&0x0c)>>2 ) { | 219 | case 0: |
182 | case 0: p->guard_interval = GUARD_INTERVAL_1_32; break; | 220 | p->guard_interval = GUARD_INTERVAL_1_32; |
183 | case 1: p->guard_interval = GUARD_INTERVAL_1_16; break; | 221 | break; |
184 | case 2: p->guard_interval = GUARD_INTERVAL_1_8; break; | 222 | case 1: |
185 | case 3: p->guard_interval = GUARD_INTERVAL_1_4; break; | 223 | p->guard_interval = GUARD_INTERVAL_1_16; |
224 | break; | ||
225 | case 2: | ||
226 | p->guard_interval = GUARD_INTERVAL_1_8; | ||
227 | break; | ||
228 | case 3: | ||
229 | p->guard_interval = GUARD_INTERVAL_1_4; | ||
230 | break; | ||
186 | } | 231 | } |
187 | switch( val&0x03 ) { | 232 | switch (val & 0x03) { |
188 | case 0: p->transmission_mode = TRANSMISSION_MODE_2K; break; | 233 | case 0: |
189 | case 1: p->transmission_mode = TRANSMISSION_MODE_8K; break; | 234 | p->transmission_mode = TRANSMISSION_MODE_2K; |
235 | break; | ||
236 | case 1: | ||
237 | p->transmission_mode = TRANSMISSION_MODE_8K; | ||
238 | break; | ||
190 | } | 239 | } |
191 | 240 | ||
192 | return 0; | 241 | return 0; |
193 | } | 242 | } |
194 | 243 | ||
195 | static int cx22702_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) | 244 | static int cx22702_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) |
196 | { | 245 | { |
197 | struct cx22702_state* state = fe->demodulator_priv; | 246 | struct cx22702_state *state = fe->demodulator_priv; |
198 | dprintk ("%s(%d)\n", __func__, enable); | 247 | dprintk("%s(%d)\n", __func__, enable); |
199 | if (enable) | 248 | if (enable) |
200 | return cx22702_writereg (state, 0x0D, cx22702_readreg(state, 0x0D) & 0xfe); | 249 | return cx22702_writereg(state, 0x0D, |
250 | cx22702_readreg(state, 0x0D) & 0xfe); | ||
201 | else | 251 | else |
202 | return cx22702_writereg (state, 0x0D, cx22702_readreg(state, 0x0D) | 1); | 252 | return cx22702_writereg(state, 0x0D, |
253 | cx22702_readreg(state, 0x0D) | 1); | ||
203 | } | 254 | } |
204 | 255 | ||
205 | /* Talk to the demod, set the FEC, GUARD, QAM settings etc */ | 256 | /* Talk to the demod, set the FEC, GUARD, QAM settings etc */ |
206 | static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_parameters *p) | 257 | static int cx22702_set_tps(struct dvb_frontend *fe, |
258 | struct dvb_frontend_parameters *p) | ||
207 | { | 259 | { |
208 | u8 val; | 260 | u8 val; |
209 | struct cx22702_state* state = fe->demodulator_priv; | 261 | struct cx22702_state *state = fe->demodulator_priv; |
210 | 262 | ||
211 | if (fe->ops.tuner_ops.set_params) { | 263 | if (fe->ops.tuner_ops.set_params) { |
212 | fe->ops.tuner_ops.set_params(fe, p); | 264 | fe->ops.tuner_ops.set_params(fe, p); |
213 | if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); | 265 | if (fe->ops.i2c_gate_ctrl) |
266 | fe->ops.i2c_gate_ctrl(fe, 0); | ||
214 | } | 267 | } |
215 | 268 | ||
216 | /* set inversion */ | 269 | /* set inversion */ |
217 | cx22702_set_inversion (state, p->inversion); | 270 | cx22702_set_inversion(state, p->inversion); |
218 | 271 | ||
219 | /* set bandwidth */ | 272 | /* set bandwidth */ |
220 | switch(p->u.ofdm.bandwidth) { | 273 | switch (p->u.ofdm.bandwidth) { |
221 | case BANDWIDTH_6_MHZ: | 274 | case BANDWIDTH_6_MHZ: |
222 | cx22702_writereg(state, 0x0C, (cx22702_readreg(state, 0x0C) & 0xcf) | 0x20 ); | 275 | cx22702_writereg(state, 0x0C, |
276 | (cx22702_readreg(state, 0x0C) & 0xcf) | 0x20); | ||
223 | break; | 277 | break; |
224 | case BANDWIDTH_7_MHZ: | 278 | case BANDWIDTH_7_MHZ: |
225 | cx22702_writereg(state, 0x0C, (cx22702_readreg(state, 0x0C) & 0xcf) | 0x10 ); | 279 | cx22702_writereg(state, 0x0C, |
280 | (cx22702_readreg(state, 0x0C) & 0xcf) | 0x10); | ||
226 | break; | 281 | break; |
227 | case BANDWIDTH_8_MHZ: | 282 | case BANDWIDTH_8_MHZ: |
228 | cx22702_writereg(state, 0x0C, cx22702_readreg(state, 0x0C) &0xcf ); | 283 | cx22702_writereg(state, 0x0C, |
284 | cx22702_readreg(state, 0x0C) & 0xcf); | ||
229 | break; | 285 | break; |
230 | default: | 286 | default: |
231 | dprintk ("%s: invalid bandwidth\n",__func__); | 287 | dprintk("%s: invalid bandwidth\n", __func__); |
232 | return -EINVAL; | 288 | return -EINVAL; |
233 | } | 289 | } |
234 | 290 | ||
235 | 291 | p->u.ofdm.code_rate_LP = FEC_AUTO; /* temp hack as manual not working */ | |
236 | p->u.ofdm.code_rate_LP = FEC_AUTO; //temp hack as manual not working | ||
237 | 292 | ||
238 | /* use auto configuration? */ | 293 | /* use auto configuration? */ |
239 | if((p->u.ofdm.hierarchy_information==HIERARCHY_AUTO) || | 294 | if ((p->u.ofdm.hierarchy_information == HIERARCHY_AUTO) || |
240 | (p->u.ofdm.constellation==QAM_AUTO) || | 295 | (p->u.ofdm.constellation == QAM_AUTO) || |
241 | (p->u.ofdm.code_rate_HP==FEC_AUTO) || | 296 | (p->u.ofdm.code_rate_HP == FEC_AUTO) || |
242 | (p->u.ofdm.code_rate_LP==FEC_AUTO) || | 297 | (p->u.ofdm.code_rate_LP == FEC_AUTO) || |
243 | (p->u.ofdm.guard_interval==GUARD_INTERVAL_AUTO) || | 298 | (p->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO) || |
244 | (p->u.ofdm.transmission_mode==TRANSMISSION_MODE_AUTO) ) { | 299 | (p->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO)) { |
245 | 300 | ||
246 | /* TPS Source - use hardware driven values */ | 301 | /* TPS Source - use hardware driven values */ |
247 | cx22702_writereg(state, 0x06, 0x10); | 302 | cx22702_writereg(state, 0x06, 0x10); |
248 | cx22702_writereg(state, 0x07, 0x9); | 303 | cx22702_writereg(state, 0x07, 0x9); |
249 | cx22702_writereg(state, 0x08, 0xC1); | 304 | cx22702_writereg(state, 0x08, 0xC1); |
250 | cx22702_writereg(state, 0x0B, cx22702_readreg(state, 0x0B) & 0xfc ); | 305 | cx22702_writereg(state, 0x0B, cx22702_readreg(state, 0x0B) |
251 | cx22702_writereg(state, 0x0C, (cx22702_readreg(state, 0x0C) & 0xBF) | 0x40 ); | 306 | & 0xfc); |
307 | cx22702_writereg(state, 0x0C, | ||
308 | (cx22702_readreg(state, 0x0C) & 0xBF) | 0x40); | ||
252 | cx22702_writereg(state, 0x00, 0x01); /* Begin aquisition */ | 309 | cx22702_writereg(state, 0x00, 0x01); /* Begin aquisition */ |
253 | dprintk("%s: Autodetecting\n",__func__); | 310 | dprintk("%s: Autodetecting\n", __func__); |
254 | return 0; | 311 | return 0; |
255 | } | 312 | } |
256 | 313 | ||
257 | /* manually programmed values */ | 314 | /* manually programmed values */ |
258 | val=0; | 315 | val = 0; |
259 | switch(p->u.ofdm.constellation) { | 316 | switch (p->u.ofdm.constellation) { |
260 | case QPSK: val = (val&0xe7); break; | 317 | case QPSK: |
261 | case QAM_16: val = (val&0xe7)|0x08; break; | 318 | val = (val & 0xe7); |
262 | case QAM_64: val = (val&0xe7)|0x10; break; | 319 | break; |
263 | default: | 320 | case QAM_16: |
264 | dprintk ("%s: invalid constellation\n",__func__); | 321 | val = (val & 0xe7) | 0x08; |
265 | return -EINVAL; | 322 | break; |
323 | case QAM_64: | ||
324 | val = (val & 0xe7) | 0x10; | ||
325 | break; | ||
326 | default: | ||
327 | dprintk("%s: invalid constellation\n", __func__); | ||
328 | return -EINVAL; | ||
266 | } | 329 | } |
267 | switch(p->u.ofdm.hierarchy_information) { | 330 | switch (p->u.ofdm.hierarchy_information) { |
268 | case HIERARCHY_NONE: val = (val&0xf8); break; | 331 | case HIERARCHY_NONE: |
269 | case HIERARCHY_1: val = (val&0xf8)|1; break; | 332 | val = (val & 0xf8); |
270 | case HIERARCHY_2: val = (val&0xf8)|2; break; | 333 | break; |
271 | case HIERARCHY_4: val = (val&0xf8)|3; break; | 334 | case HIERARCHY_1: |
272 | default: | 335 | val = (val & 0xf8) | 1; |
273 | dprintk ("%s: invalid hierarchy\n",__func__); | 336 | break; |
274 | return -EINVAL; | 337 | case HIERARCHY_2: |
338 | val = (val & 0xf8) | 2; | ||
339 | break; | ||
340 | case HIERARCHY_4: | ||
341 | val = (val & 0xf8) | 3; | ||
342 | break; | ||
343 | default: | ||
344 | dprintk("%s: invalid hierarchy\n", __func__); | ||
345 | return -EINVAL; | ||
275 | } | 346 | } |
276 | cx22702_writereg (state, 0x06, val); | 347 | cx22702_writereg(state, 0x06, val); |
277 | 348 | ||
278 | val=0; | 349 | val = 0; |
279 | switch(p->u.ofdm.code_rate_HP) { | 350 | switch (p->u.ofdm.code_rate_HP) { |
280 | case FEC_NONE: | 351 | case FEC_NONE: |
281 | case FEC_1_2: val = (val&0xc7); break; | 352 | case FEC_1_2: |
282 | case FEC_2_3: val = (val&0xc7)|0x08; break; | 353 | val = (val & 0xc7); |
283 | case FEC_3_4: val = (val&0xc7)|0x10; break; | 354 | break; |
284 | case FEC_5_6: val = (val&0xc7)|0x18; break; | 355 | case FEC_2_3: |
285 | case FEC_7_8: val = (val&0xc7)|0x20; break; | 356 | val = (val & 0xc7) | 0x08; |
286 | default: | 357 | break; |
287 | dprintk ("%s: invalid code_rate_HP\n",__func__); | 358 | case FEC_3_4: |
288 | return -EINVAL; | 359 | val = (val & 0xc7) | 0x10; |
360 | break; | ||
361 | case FEC_5_6: | ||
362 | val = (val & 0xc7) | 0x18; | ||
363 | break; | ||
364 | case FEC_7_8: | ||
365 | val = (val & 0xc7) | 0x20; | ||
366 | break; | ||
367 | default: | ||
368 | dprintk("%s: invalid code_rate_HP\n", __func__); | ||
369 | return -EINVAL; | ||
289 | } | 370 | } |
290 | switch(p->u.ofdm.code_rate_LP) { | 371 | switch (p->u.ofdm.code_rate_LP) { |
291 | case FEC_NONE: | 372 | case FEC_NONE: |
292 | case FEC_1_2: val = (val&0xf8); break; | 373 | case FEC_1_2: |
293 | case FEC_2_3: val = (val&0xf8)|1; break; | 374 | val = (val & 0xf8); |
294 | case FEC_3_4: val = (val&0xf8)|2; break; | 375 | break; |
295 | case FEC_5_6: val = (val&0xf8)|3; break; | 376 | case FEC_2_3: |
296 | case FEC_7_8: val = (val&0xf8)|4; break; | 377 | val = (val & 0xf8) | 1; |
297 | default: | 378 | break; |
298 | dprintk ("%s: invalid code_rate_LP\n",__func__); | 379 | case FEC_3_4: |
299 | return -EINVAL; | 380 | val = (val & 0xf8) | 2; |
381 | break; | ||
382 | case FEC_5_6: | ||
383 | val = (val & 0xf8) | 3; | ||
384 | break; | ||
385 | case FEC_7_8: | ||
386 | val = (val & 0xf8) | 4; | ||
387 | break; | ||
388 | default: | ||
389 | dprintk("%s: invalid code_rate_LP\n", __func__); | ||
390 | return -EINVAL; | ||
300 | } | 391 | } |
301 | cx22702_writereg (state, 0x07, val); | 392 | cx22702_writereg(state, 0x07, val); |
302 | 393 | ||
303 | val=0; | 394 | val = 0; |
304 | switch(p->u.ofdm.guard_interval) { | 395 | switch (p->u.ofdm.guard_interval) { |
305 | case GUARD_INTERVAL_1_32: val = (val&0xf3); break; | 396 | case GUARD_INTERVAL_1_32: |
306 | case GUARD_INTERVAL_1_16: val = (val&0xf3)|0x04; break; | 397 | val = (val & 0xf3); |
307 | case GUARD_INTERVAL_1_8: val = (val&0xf3)|0x08; break; | 398 | break; |
308 | case GUARD_INTERVAL_1_4: val = (val&0xf3)|0x0c; break; | 399 | case GUARD_INTERVAL_1_16: |
309 | default: | 400 | val = (val & 0xf3) | 0x04; |
310 | dprintk ("%s: invalid guard_interval\n",__func__); | 401 | break; |
311 | return -EINVAL; | 402 | case GUARD_INTERVAL_1_8: |
403 | val = (val & 0xf3) | 0x08; | ||
404 | break; | ||
405 | case GUARD_INTERVAL_1_4: | ||
406 | val = (val & 0xf3) | 0x0c; | ||
407 | break; | ||
408 | default: | ||
409 | dprintk("%s: invalid guard_interval\n", __func__); | ||
410 | return -EINVAL; | ||
312 | } | 411 | } |
313 | switch(p->u.ofdm.transmission_mode) { | 412 | switch (p->u.ofdm.transmission_mode) { |
314 | case TRANSMISSION_MODE_2K: val = (val&0xfc); break; | 413 | case TRANSMISSION_MODE_2K: |
315 | case TRANSMISSION_MODE_8K: val = (val&0xfc)|1; break; | 414 | val = (val & 0xfc); |
316 | default: | 415 | break; |
317 | dprintk ("%s: invalid transmission_mode\n",__func__); | 416 | case TRANSMISSION_MODE_8K: |
318 | return -EINVAL; | 417 | val = (val & 0xfc) | 1; |
418 | break; | ||
419 | default: | ||
420 | dprintk("%s: invalid transmission_mode\n", __func__); | ||
421 | return -EINVAL; | ||
319 | } | 422 | } |
320 | cx22702_writereg(state, 0x08, val); | 423 | cx22702_writereg(state, 0x08, val); |
321 | cx22702_writereg(state, 0x0B, (cx22702_readreg(state, 0x0B) & 0xfc) | 0x02 ); | 424 | cx22702_writereg(state, 0x0B, |
322 | cx22702_writereg(state, 0x0C, (cx22702_readreg(state, 0x0C) & 0xBF) | 0x40 ); | 425 | (cx22702_readreg(state, 0x0B) & 0xfc) | 0x02); |
426 | cx22702_writereg(state, 0x0C, | ||
427 | (cx22702_readreg(state, 0x0C) & 0xBF) | 0x40); | ||
323 | 428 | ||
324 | /* Begin channel aquisition */ | 429 | /* Begin channel aquisition */ |
325 | cx22702_writereg(state, 0x00, 0x01); | 430 | cx22702_writereg(state, 0x00, 0x01); |
@@ -329,109 +434,111 @@ static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_paramet | |||
329 | 434 | ||
330 | /* Reset the demod hardware and reset all of the configuration registers | 435 | /* Reset the demod hardware and reset all of the configuration registers |
331 | to a default state. */ | 436 | to a default state. */ |
332 | static int cx22702_init (struct dvb_frontend* fe) | 437 | static int cx22702_init(struct dvb_frontend *fe) |
333 | { | 438 | { |
334 | int i; | 439 | int i; |
335 | struct cx22702_state* state = fe->demodulator_priv; | 440 | struct cx22702_state *state = fe->demodulator_priv; |
336 | 441 | ||
337 | cx22702_writereg (state, 0x00, 0x02); | 442 | cx22702_writereg(state, 0x00, 0x02); |
338 | 443 | ||
339 | msleep(10); | 444 | msleep(10); |
340 | 445 | ||
341 | for (i=0; i<sizeof(init_tab); i+=2) | 446 | for (i = 0; i < ARRAY_SIZE(init_tab); i += 2) |
342 | cx22702_writereg (state, init_tab[i], init_tab[i+1]); | 447 | cx22702_writereg(state, init_tab[i], init_tab[i + 1]); |
343 | 448 | ||
344 | cx22702_writereg (state, 0xf8, (state->config->output_mode << 1) & 0x02); | 449 | cx22702_writereg(state, 0xf8, (state->config->output_mode << 1) |
450 | & 0x02); | ||
345 | 451 | ||
346 | cx22702_i2c_gate_ctrl(fe, 0); | 452 | cx22702_i2c_gate_ctrl(fe, 0); |
347 | 453 | ||
348 | return 0; | 454 | return 0; |
349 | } | 455 | } |
350 | 456 | ||
351 | static int cx22702_read_status(struct dvb_frontend* fe, fe_status_t* status) | 457 | static int cx22702_read_status(struct dvb_frontend *fe, fe_status_t *status) |
352 | { | 458 | { |
353 | struct cx22702_state* state = fe->demodulator_priv; | 459 | struct cx22702_state *state = fe->demodulator_priv; |
354 | u8 reg0A; | 460 | u8 reg0A; |
355 | u8 reg23; | 461 | u8 reg23; |
356 | 462 | ||
357 | *status = 0; | 463 | *status = 0; |
358 | 464 | ||
359 | reg0A = cx22702_readreg (state, 0x0A); | 465 | reg0A = cx22702_readreg(state, 0x0A); |
360 | reg23 = cx22702_readreg (state, 0x23); | 466 | reg23 = cx22702_readreg(state, 0x23); |
361 | 467 | ||
362 | dprintk ("%s: status demod=0x%02x agc=0x%02x\n" | 468 | dprintk("%s: status demod=0x%02x agc=0x%02x\n" |
363 | ,__func__,reg0A,reg23); | 469 | , __func__, reg0A, reg23); |
364 | 470 | ||
365 | if(reg0A & 0x10) { | 471 | if (reg0A & 0x10) { |
366 | *status |= FE_HAS_LOCK; | 472 | *status |= FE_HAS_LOCK; |
367 | *status |= FE_HAS_VITERBI; | 473 | *status |= FE_HAS_VITERBI; |
368 | *status |= FE_HAS_SYNC; | 474 | *status |= FE_HAS_SYNC; |
369 | } | 475 | } |
370 | 476 | ||
371 | if(reg0A & 0x20) | 477 | if (reg0A & 0x20) |
372 | *status |= FE_HAS_CARRIER; | 478 | *status |= FE_HAS_CARRIER; |
373 | 479 | ||
374 | if(reg23 < 0xf0) | 480 | if (reg23 < 0xf0) |
375 | *status |= FE_HAS_SIGNAL; | 481 | *status |= FE_HAS_SIGNAL; |
376 | 482 | ||
377 | return 0; | 483 | return 0; |
378 | } | 484 | } |
379 | 485 | ||
380 | static int cx22702_read_ber(struct dvb_frontend* fe, u32* ber) | 486 | static int cx22702_read_ber(struct dvb_frontend *fe, u32 *ber) |
381 | { | 487 | { |
382 | struct cx22702_state* state = fe->demodulator_priv; | 488 | struct cx22702_state *state = fe->demodulator_priv; |
383 | 489 | ||
384 | if(cx22702_readreg (state, 0xE4) & 0x02) { | 490 | if (cx22702_readreg(state, 0xE4) & 0x02) { |
385 | /* Realtime statistics */ | 491 | /* Realtime statistics */ |
386 | *ber = (cx22702_readreg (state, 0xDE) & 0x7F) << 7 | 492 | *ber = (cx22702_readreg(state, 0xDE) & 0x7F) << 7 |
387 | | (cx22702_readreg (state, 0xDF)&0x7F); | 493 | | (cx22702_readreg(state, 0xDF) & 0x7F); |
388 | } else { | 494 | } else { |
389 | /* Averagtine statistics */ | 495 | /* Averagtine statistics */ |
390 | *ber = (cx22702_readreg (state, 0xDE) & 0x7F) << 7 | 496 | *ber = (cx22702_readreg(state, 0xDE) & 0x7F) << 7 |
391 | | cx22702_readreg (state, 0xDF); | 497 | | cx22702_readreg(state, 0xDF); |
392 | } | 498 | } |
393 | 499 | ||
394 | return 0; | 500 | return 0; |
395 | } | 501 | } |
396 | 502 | ||
397 | static int cx22702_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength) | 503 | static int cx22702_read_signal_strength(struct dvb_frontend *fe, |
504 | u16 *signal_strength) | ||
398 | { | 505 | { |
399 | struct cx22702_state* state = fe->demodulator_priv; | 506 | struct cx22702_state *state = fe->demodulator_priv; |
400 | 507 | ||
401 | u16 rs_ber = 0; | 508 | u16 rs_ber = 0; |
402 | rs_ber = cx22702_readreg (state, 0x23); | 509 | rs_ber = cx22702_readreg(state, 0x23); |
403 | *signal_strength = (rs_ber << 8) | rs_ber; | 510 | *signal_strength = (rs_ber << 8) | rs_ber; |
404 | 511 | ||
405 | return 0; | 512 | return 0; |
406 | } | 513 | } |
407 | 514 | ||
408 | static int cx22702_read_snr(struct dvb_frontend* fe, u16* snr) | 515 | static int cx22702_read_snr(struct dvb_frontend *fe, u16 *snr) |
409 | { | 516 | { |
410 | struct cx22702_state* state = fe->demodulator_priv; | 517 | struct cx22702_state *state = fe->demodulator_priv; |
411 | 518 | ||
412 | u16 rs_ber=0; | 519 | u16 rs_ber = 0; |
413 | if(cx22702_readreg (state, 0xE4) & 0x02) { | 520 | if (cx22702_readreg(state, 0xE4) & 0x02) { |
414 | /* Realtime statistics */ | 521 | /* Realtime statistics */ |
415 | rs_ber = (cx22702_readreg (state, 0xDE) & 0x7F) << 7 | 522 | rs_ber = (cx22702_readreg(state, 0xDE) & 0x7F) << 7 |
416 | | (cx22702_readreg (state, 0xDF)& 0x7F); | 523 | | (cx22702_readreg(state, 0xDF) & 0x7F); |
417 | } else { | 524 | } else { |
418 | /* Averagine statistics */ | 525 | /* Averagine statistics */ |
419 | rs_ber = (cx22702_readreg (state, 0xDE) & 0x7F) << 8 | 526 | rs_ber = (cx22702_readreg(state, 0xDE) & 0x7F) << 8 |
420 | | cx22702_readreg (state, 0xDF); | 527 | | cx22702_readreg(state, 0xDF); |
421 | } | 528 | } |
422 | *snr = ~rs_ber; | 529 | *snr = ~rs_ber; |
423 | 530 | ||
424 | return 0; | 531 | return 0; |
425 | } | 532 | } |
426 | 533 | ||
427 | static int cx22702_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) | 534 | static int cx22702_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) |
428 | { | 535 | { |
429 | struct cx22702_state* state = fe->demodulator_priv; | 536 | struct cx22702_state *state = fe->demodulator_priv; |
430 | 537 | ||
431 | u8 _ucblocks; | 538 | u8 _ucblocks; |
432 | 539 | ||
433 | /* RS Uncorrectable Packet Count then reset */ | 540 | /* RS Uncorrectable Packet Count then reset */ |
434 | _ucblocks = cx22702_readreg (state, 0xE3); | 541 | _ucblocks = cx22702_readreg(state, 0xE3); |
435 | if (state->prevUCBlocks < _ucblocks) | 542 | if (state->prevUCBlocks < _ucblocks) |
436 | *ucblocks = (_ucblocks - state->prevUCBlocks); | 543 | *ucblocks = (_ucblocks - state->prevUCBlocks); |
437 | else | 544 | else |
@@ -441,34 +548,36 @@ static int cx22702_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) | |||
441 | return 0; | 548 | return 0; |
442 | } | 549 | } |
443 | 550 | ||
444 | static int cx22702_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) | 551 | static int cx22702_get_frontend(struct dvb_frontend *fe, |
552 | struct dvb_frontend_parameters *p) | ||
445 | { | 553 | { |
446 | struct cx22702_state* state = fe->demodulator_priv; | 554 | struct cx22702_state *state = fe->demodulator_priv; |
447 | 555 | ||
448 | u8 reg0C = cx22702_readreg (state, 0x0C); | 556 | u8 reg0C = cx22702_readreg(state, 0x0C); |
449 | 557 | ||
450 | p->inversion = reg0C & 0x1 ? INVERSION_ON : INVERSION_OFF; | 558 | p->inversion = reg0C & 0x1 ? INVERSION_ON : INVERSION_OFF; |
451 | return cx22702_get_tps (state, &p->u.ofdm); | 559 | return cx22702_get_tps(state, &p->u.ofdm); |
452 | } | 560 | } |
453 | 561 | ||
454 | static int cx22702_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune) | 562 | static int cx22702_get_tune_settings(struct dvb_frontend *fe, |
563 | struct dvb_frontend_tune_settings *tune) | ||
455 | { | 564 | { |
456 | tune->min_delay_ms = 1000; | 565 | tune->min_delay_ms = 1000; |
457 | return 0; | 566 | return 0; |
458 | } | 567 | } |
459 | 568 | ||
460 | static void cx22702_release(struct dvb_frontend* fe) | 569 | static void cx22702_release(struct dvb_frontend *fe) |
461 | { | 570 | { |
462 | struct cx22702_state* state = fe->demodulator_priv; | 571 | struct cx22702_state *state = fe->demodulator_priv; |
463 | kfree(state); | 572 | kfree(state); |
464 | } | 573 | } |
465 | 574 | ||
466 | static struct dvb_frontend_ops cx22702_ops; | 575 | static struct dvb_frontend_ops cx22702_ops; |
467 | 576 | ||
468 | struct dvb_frontend* cx22702_attach(const struct cx22702_config* config, | 577 | struct dvb_frontend *cx22702_attach(const struct cx22702_config *config, |
469 | struct i2c_adapter* i2c) | 578 | struct i2c_adapter *i2c) |
470 | { | 579 | { |
471 | struct cx22702_state* state = NULL; | 580 | struct cx22702_state *state = NULL; |
472 | 581 | ||
473 | /* allocate memory for the internal state */ | 582 | /* allocate memory for the internal state */ |
474 | state = kmalloc(sizeof(struct cx22702_state), GFP_KERNEL); | 583 | state = kmalloc(sizeof(struct cx22702_state), GFP_KERNEL); |
@@ -485,7 +594,8 @@ struct dvb_frontend* cx22702_attach(const struct cx22702_config* config, | |||
485 | goto error; | 594 | goto error; |
486 | 595 | ||
487 | /* create dvb_frontend */ | 596 | /* create dvb_frontend */ |
488 | memcpy(&state->frontend.ops, &cx22702_ops, sizeof(struct dvb_frontend_ops)); | 597 | memcpy(&state->frontend.ops, &cx22702_ops, |
598 | sizeof(struct dvb_frontend_ops)); | ||
489 | state->frontend.demodulator_priv = state; | 599 | state->frontend.demodulator_priv = state; |
490 | return &state->frontend; | 600 | return &state->frontend; |
491 | 601 | ||
@@ -493,6 +603,7 @@ error: | |||
493 | kfree(state); | 603 | kfree(state); |
494 | return NULL; | 604 | return NULL; |
495 | } | 605 | } |
606 | EXPORT_SYMBOL(cx22702_attach); | ||
496 | 607 | ||
497 | static struct dvb_frontend_ops cx22702_ops = { | 608 | static struct dvb_frontend_ops cx22702_ops = { |
498 | 609 | ||
@@ -525,11 +636,6 @@ static struct dvb_frontend_ops cx22702_ops = { | |||
525 | .read_ucblocks = cx22702_read_ucblocks, | 636 | .read_ucblocks = cx22702_read_ucblocks, |
526 | }; | 637 | }; |
527 | 638 | ||
528 | module_param(debug, int, 0644); | ||
529 | MODULE_PARM_DESC(debug, "Enable verbose debug messages"); | ||
530 | |||
531 | MODULE_DESCRIPTION("Conexant CX22702 DVB-T Demodulator driver"); | 639 | MODULE_DESCRIPTION("Conexant CX22702 DVB-T Demodulator driver"); |
532 | MODULE_AUTHOR("Steven Toth"); | 640 | MODULE_AUTHOR("Steven Toth"); |
533 | MODULE_LICENSE("GPL"); | 641 | MODULE_LICENSE("GPL"); |
534 | |||
535 | EXPORT_SYMBOL(cx22702_attach); | ||
diff --git a/drivers/media/dvb/frontends/cx22702.h b/drivers/media/dvb/frontends/cx22702.h index b1e465c6c2ce..f154e1f428eb 100644 --- a/drivers/media/dvb/frontends/cx22702.h +++ b/drivers/media/dvb/frontends/cx22702.h | |||
@@ -30,8 +30,7 @@ | |||
30 | 30 | ||
31 | #include <linux/dvb/frontend.h> | 31 | #include <linux/dvb/frontend.h> |
32 | 32 | ||
33 | struct cx22702_config | 33 | struct cx22702_config { |
34 | { | ||
35 | /* the demodulator's i2c address */ | 34 | /* the demodulator's i2c address */ |
36 | u8 demod_address; | 35 | u8 demod_address; |
37 | 36 | ||
@@ -41,16 +40,19 @@ struct cx22702_config | |||
41 | u8 output_mode; | 40 | u8 output_mode; |
42 | }; | 41 | }; |
43 | 42 | ||
44 | #if defined(CONFIG_DVB_CX22702) || (defined(CONFIG_DVB_CX22702_MODULE) && defined(MODULE)) | 43 | #if defined(CONFIG_DVB_CX22702) || (defined(CONFIG_DVB_CX22702_MODULE) \ |
45 | extern struct dvb_frontend* cx22702_attach(const struct cx22702_config* config, | 44 | && defined(MODULE)) |
46 | struct i2c_adapter* i2c); | 45 | extern struct dvb_frontend *cx22702_attach( |
46 | const struct cx22702_config *config, | ||
47 | struct i2c_adapter *i2c); | ||
47 | #else | 48 | #else |
48 | static inline struct dvb_frontend* cx22702_attach(const struct cx22702_config* config, | 49 | static inline struct dvb_frontend *cx22702_attach( |
49 | struct i2c_adapter* i2c) | 50 | const struct cx22702_config *config, |
51 | struct i2c_adapter *i2c) | ||
50 | { | 52 | { |
51 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | 53 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); |
52 | return NULL; | 54 | return NULL; |
53 | } | 55 | } |
54 | #endif // CONFIG_DVB_CX22702 | 56 | #endif |
55 | 57 | ||
56 | #endif // CX22702_H | 58 | #endif |
diff --git a/drivers/media/dvb/frontends/cx24116.c b/drivers/media/dvb/frontends/cx24116.c index deb36f469ada..b144b308a4dd 100644 --- a/drivers/media/dvb/frontends/cx24116.c +++ b/drivers/media/dvb/frontends/cx24116.c | |||
@@ -41,10 +41,14 @@ | |||
41 | #include "dvb_frontend.h" | 41 | #include "dvb_frontend.h" |
42 | #include "cx24116.h" | 42 | #include "cx24116.h" |
43 | 43 | ||
44 | static int debug = 0; | 44 | static int debug; |
45 | module_param(debug, int, 0644); | ||
46 | MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)"); | ||
47 | |||
45 | #define dprintk(args...) \ | 48 | #define dprintk(args...) \ |
46 | do { \ | 49 | do { \ |
47 | if (debug) printk ("cx24116: " args); \ | 50 | if (debug) \ |
51 | printk(KERN_INFO "cx24116: " args); \ | ||
48 | } while (0) | 52 | } while (0) |
49 | 53 | ||
50 | #define CX24116_DEFAULT_FIRMWARE "dvb-fe-cx24116.fw" | 54 | #define CX24116_DEFAULT_FIRMWARE "dvb-fe-cx24116.fw" |
@@ -68,13 +72,20 @@ static int debug = 0; | |||
68 | #define CX24116_REG_UCB8 (0xca) | 72 | #define CX24116_REG_UCB8 (0xca) |
69 | #define CX24116_REG_CLKDIV (0xf3) | 73 | #define CX24116_REG_CLKDIV (0xf3) |
70 | #define CX24116_REG_RATEDIV (0xf9) | 74 | #define CX24116_REG_RATEDIV (0xf9) |
71 | #define CX24116_REG_FECSTATUS (0x9c) /* configured fec (not tuned) or actual FEC (tuned) 1=1/2 2=2/3 etc */ | 75 | |
76 | /* configured fec (not tuned) or actual FEC (tuned) 1=1/2 2=2/3 etc */ | ||
77 | #define CX24116_REG_FECSTATUS (0x9c) | ||
72 | 78 | ||
73 | /* FECSTATUS bits */ | 79 | /* FECSTATUS bits */ |
74 | #define CX24116_FEC_FECMASK (0x1f) /* mask to determine configured fec (not tuned) or actual fec (tuned) */ | 80 | /* mask to determine configured fec (not tuned) or actual fec (tuned) */ |
75 | #define CX24116_FEC_DVBS (0x20) /* Select DVB-S demodulator, else DVB-S2 */ | 81 | #define CX24116_FEC_FECMASK (0x1f) |
82 | |||
83 | /* Select DVB-S demodulator, else DVB-S2 */ | ||
84 | #define CX24116_FEC_DVBS (0x20) | ||
76 | #define CX24116_FEC_UNKNOWN (0x40) /* Unknown/unused */ | 85 | #define CX24116_FEC_UNKNOWN (0x40) /* Unknown/unused */ |
77 | #define CX24116_FEC_PILOT (0x80) /* Pilot mode requested when tuning else always reset when tuned */ | 86 | |
87 | /* Pilot mode requested when tuning else always reset when tuned */ | ||
88 | #define CX24116_FEC_PILOT (0x80) | ||
78 | 89 | ||
79 | /* arg buffer size */ | 90 | /* arg buffer size */ |
80 | #define CX24116_ARGLEN (0x1e) | 91 | #define CX24116_ARGLEN (0x1e) |
@@ -116,12 +127,17 @@ static int debug = 0; | |||
116 | 127 | ||
117 | /* DiSEqC tone burst */ | 128 | /* DiSEqC tone burst */ |
118 | static int toneburst = 1; | 129 | static int toneburst = 1; |
130 | module_param(toneburst, int, 0644); | ||
131 | MODULE_PARM_DESC(toneburst, "DiSEqC toneburst 0=OFF, 1=TONE CACHE, "\ | ||
132 | "2=MESSAGE CACHE (default:1)"); | ||
119 | 133 | ||
120 | /* SNR measurements */ | 134 | /* SNR measurements */ |
121 | static int esno_snr = 0; | 135 | static int esno_snr; |
136 | module_param(esno_snr, int, 0644); | ||
137 | MODULE_PARM_DESC(debug, "SNR return units, 0=PERCENTAGE 0-100, "\ | ||
138 | "1=ESNO(db * 10) (default:0)"); | ||
122 | 139 | ||
123 | enum cmds | 140 | enum cmds { |
124 | { | ||
125 | CMD_SET_VCO = 0x10, | 141 | CMD_SET_VCO = 0x10, |
126 | CMD_TUNEREQUEST = 0x11, | 142 | CMD_TUNEREQUEST = 0x11, |
127 | CMD_MPEGCONFIG = 0x13, | 143 | CMD_MPEGCONFIG = 0x13, |
@@ -138,8 +154,7 @@ enum cmds | |||
138 | }; | 154 | }; |
139 | 155 | ||
140 | /* The Demod/Tuner can't easily provide these, we cache them */ | 156 | /* The Demod/Tuner can't easily provide these, we cache them */ |
141 | struct cx24116_tuning | 157 | struct cx24116_tuning { |
142 | { | ||
143 | u32 frequency; | 158 | u32 frequency; |
144 | u32 symbol_rate; | 159 | u32 symbol_rate; |
145 | fe_spectral_inversion_t inversion; | 160 | fe_spectral_inversion_t inversion; |
@@ -158,16 +173,14 @@ struct cx24116_tuning | |||
158 | }; | 173 | }; |
159 | 174 | ||
160 | /* Basic commands that are sent to the firmware */ | 175 | /* Basic commands that are sent to the firmware */ |
161 | struct cx24116_cmd | 176 | struct cx24116_cmd { |
162 | { | ||
163 | u8 len; | 177 | u8 len; |
164 | u8 args[CX24116_ARGLEN]; | 178 | u8 args[CX24116_ARGLEN]; |
165 | }; | 179 | }; |
166 | 180 | ||
167 | struct cx24116_state | 181 | struct cx24116_state { |
168 | { | 182 | struct i2c_adapter *i2c; |
169 | struct i2c_adapter* i2c; | 183 | const struct cx24116_config *config; |
170 | const struct cx24116_config* config; | ||
171 | 184 | ||
172 | struct dvb_frontend frontend; | 185 | struct dvb_frontend frontend; |
173 | 186 | ||
@@ -179,19 +192,20 @@ struct cx24116_state | |||
179 | struct cx24116_cmd dsec_cmd; | 192 | struct cx24116_cmd dsec_cmd; |
180 | }; | 193 | }; |
181 | 194 | ||
182 | static int cx24116_writereg(struct cx24116_state* state, int reg, int data) | 195 | static int cx24116_writereg(struct cx24116_state *state, int reg, int data) |
183 | { | 196 | { |
184 | u8 buf[] = { reg, data }; | 197 | u8 buf[] = { reg, data }; |
185 | struct i2c_msg msg = { .addr = state->config->demod_address, | 198 | struct i2c_msg msg = { .addr = state->config->demod_address, |
186 | .flags = 0, .buf = buf, .len = 2 }; | 199 | .flags = 0, .buf = buf, .len = 2 }; |
187 | int err; | 200 | int err; |
188 | 201 | ||
189 | if (debug>1) | 202 | if (debug > 1) |
190 | printk("cx24116: %s: write reg 0x%02x, value 0x%02x\n", | 203 | printk("cx24116: %s: write reg 0x%02x, value 0x%02x\n", |
191 | __func__,reg, data); | 204 | __func__, reg, data); |
192 | 205 | ||
193 | if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) { | 206 | err = i2c_transfer(state->i2c, &msg, 1); |
194 | printk("%s: writereg error(err == %i, reg == 0x%02x," | 207 | if (err != 1) { |
208 | printk(KERN_ERR "%s: writereg error(err == %i, reg == 0x%02x," | ||
195 | " value == 0x%02x)\n", __func__, err, reg, data); | 209 | " value == 0x%02x)\n", __func__, err, reg, data); |
196 | return -EREMOTEIO; | 210 | return -EREMOTEIO; |
197 | } | 211 | } |
@@ -200,7 +214,8 @@ static int cx24116_writereg(struct cx24116_state* state, int reg, int data) | |||
200 | } | 214 | } |
201 | 215 | ||
202 | /* Bulk byte writes to a single I2C address, for 32k firmware load */ | 216 | /* Bulk byte writes to a single I2C address, for 32k firmware load */ |
203 | static int cx24116_writeregN(struct cx24116_state* state, int reg, u8 *data, u16 len) | 217 | static int cx24116_writeregN(struct cx24116_state *state, int reg, |
218 | const u8 *data, u16 len) | ||
204 | { | 219 | { |
205 | int ret = -EREMOTEIO; | 220 | int ret = -EREMOTEIO; |
206 | struct i2c_msg msg; | 221 | struct i2c_msg msg; |
@@ -221,12 +236,13 @@ static int cx24116_writeregN(struct cx24116_state* state, int reg, u8 *data, u16 | |||
221 | msg.buf = buf; | 236 | msg.buf = buf; |
222 | msg.len = len + 1; | 237 | msg.len = len + 1; |
223 | 238 | ||
224 | if (debug>1) | 239 | if (debug > 1) |
225 | printk("cx24116: %s: write regN 0x%02x, len = %d\n", | 240 | printk(KERN_INFO "cx24116: %s: write regN 0x%02x, len = %d\n", |
226 | __func__,reg, len); | 241 | __func__, reg, len); |
227 | 242 | ||
228 | if ((ret = i2c_transfer(state->i2c, &msg, 1)) != 1) { | 243 | ret = i2c_transfer(state->i2c, &msg, 1); |
229 | printk("%s: writereg error(err == %i, reg == 0x%02x\n", | 244 | if (ret != 1) { |
245 | printk(KERN_ERR "%s: writereg error(err == %i, reg == 0x%02x\n", | ||
230 | __func__, ret, reg); | 246 | __func__, ret, reg); |
231 | ret = -EREMOTEIO; | 247 | ret = -EREMOTEIO; |
232 | } | 248 | } |
@@ -237,30 +253,35 @@ error: | |||
237 | return ret; | 253 | return ret; |
238 | } | 254 | } |
239 | 255 | ||
240 | static int cx24116_readreg(struct cx24116_state* state, u8 reg) | 256 | static int cx24116_readreg(struct cx24116_state *state, u8 reg) |
241 | { | 257 | { |
242 | int ret; | 258 | int ret; |
243 | u8 b0[] = { reg }; | 259 | u8 b0[] = { reg }; |
244 | u8 b1[] = { 0 }; | 260 | u8 b1[] = { 0 }; |
245 | struct i2c_msg msg[] = { | 261 | struct i2c_msg msg[] = { |
246 | { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 }, | 262 | { .addr = state->config->demod_address, .flags = 0, |
247 | { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } | 263 | .buf = b0, .len = 1 }, |
264 | { .addr = state->config->demod_address, .flags = I2C_M_RD, | ||
265 | .buf = b1, .len = 1 } | ||
248 | }; | 266 | }; |
249 | 267 | ||
250 | ret = i2c_transfer(state->i2c, msg, 2); | 268 | ret = i2c_transfer(state->i2c, msg, 2); |
251 | 269 | ||
252 | if (ret != 2) { | 270 | if (ret != 2) { |
253 | printk("%s: reg=0x%x (error=%d)\n", __func__, reg, ret); | 271 | printk(KERN_ERR "%s: reg=0x%x (error=%d)\n", |
272 | __func__, reg, ret); | ||
254 | return ret; | 273 | return ret; |
255 | } | 274 | } |
256 | 275 | ||
257 | if (debug>1) | 276 | if (debug > 1) |
258 | printk("cx24116: read reg 0x%02x, value 0x%02x\n",reg, b1[0]); | 277 | printk(KERN_INFO "cx24116: read reg 0x%02x, value 0x%02x\n", |
278 | reg, b1[0]); | ||
259 | 279 | ||
260 | return b1[0]; | 280 | return b1[0]; |
261 | } | 281 | } |
262 | 282 | ||
263 | static int cx24116_set_inversion(struct cx24116_state* state, fe_spectral_inversion_t inversion) | 283 | static int cx24116_set_inversion(struct cx24116_state *state, |
284 | fe_spectral_inversion_t inversion) | ||
264 | { | 285 | { |
265 | dprintk("%s(%d)\n", __func__, inversion); | 286 | dprintk("%s(%d)\n", __func__, inversion); |
266 | 287 | ||
@@ -308,10 +329,10 @@ static int cx24116_set_inversion(struct cx24116_state* state, fe_spectral_invers | |||
308 | * Eg.(2/3) szap "Zone Horror" | 329 | * Eg.(2/3) szap "Zone Horror" |
309 | * | 330 | * |
310 | * mask/val = 0x04, 0x20 | 331 | * mask/val = 0x04, 0x20 |
311 | * status 1f | signal c3c0 | snr a333 | ber 00000098 | unc 00000000 | FE_HAS_LOCK | 332 | * status 1f | signal c3c0 | snr a333 | ber 00000098 | unc 0 | FE_HAS_LOCK |
312 | * | 333 | * |
313 | * mask/val = 0x04, 0x30 | 334 | * mask/val = 0x04, 0x30 |
314 | * status 1f | signal c3c0 | snr a333 | ber 00000000 | unc 00000000 | FE_HAS_LOCK | 335 | * status 1f | signal c3c0 | snr a333 | ber 00000000 | unc 0 | FE_HAS_LOCK |
315 | * | 336 | * |
316 | * After tuning FECSTATUS contains actual FEC | 337 | * After tuning FECSTATUS contains actual FEC |
317 | * in use numbered 1 through to 8 for 1/2 .. 2/3 etc | 338 | * in use numbered 1 through to 8 for 1/2 .. 2/3 etc |
@@ -389,18 +410,16 @@ struct cx24116_modfec { | |||
389 | */ | 410 | */ |
390 | }; | 411 | }; |
391 | 412 | ||
392 | static int cx24116_lookup_fecmod(struct cx24116_state* state, | 413 | static int cx24116_lookup_fecmod(struct cx24116_state *state, |
393 | fe_modulation_t m, fe_code_rate_t f) | 414 | fe_modulation_t m, fe_code_rate_t f) |
394 | { | 415 | { |
395 | int i, ret = -EOPNOTSUPP; | 416 | int i, ret = -EOPNOTSUPP; |
396 | 417 | ||
397 | dprintk("%s(0x%02x,0x%02x)\n", __func__, m, f); | 418 | dprintk("%s(0x%02x,0x%02x)\n", __func__, m, f); |
398 | 419 | ||
399 | for(i=0 ; i < sizeof(CX24116_MODFEC_MODES) / sizeof(struct cx24116_modfec) ; i++) | 420 | for (i = 0; i < ARRAY_SIZE(CX24116_MODFEC_MODES); i++) { |
400 | { | 421 | if ((m == CX24116_MODFEC_MODES[i].modulation) && |
401 | if( (m == CX24116_MODFEC_MODES[i].modulation) && | 422 | (f == CX24116_MODFEC_MODES[i].fec)) { |
402 | (f == CX24116_MODFEC_MODES[i].fec) ) | ||
403 | { | ||
404 | ret = i; | 423 | ret = i; |
405 | break; | 424 | break; |
406 | } | 425 | } |
@@ -409,7 +428,8 @@ static int cx24116_lookup_fecmod(struct cx24116_state* state, | |||
409 | return ret; | 428 | return ret; |
410 | } | 429 | } |
411 | 430 | ||
412 | static int cx24116_set_fec(struct cx24116_state* state, fe_modulation_t mod, fe_code_rate_t fec) | 431 | static int cx24116_set_fec(struct cx24116_state *state, |
432 | fe_modulation_t mod, fe_code_rate_t fec) | ||
413 | { | 433 | { |
414 | int ret = 0; | 434 | int ret = 0; |
415 | 435 | ||
@@ -417,7 +437,7 @@ static int cx24116_set_fec(struct cx24116_state* state, fe_modulation_t mod, fe_ | |||
417 | 437 | ||
418 | ret = cx24116_lookup_fecmod(state, mod, fec); | 438 | ret = cx24116_lookup_fecmod(state, mod, fec); |
419 | 439 | ||
420 | if(ret < 0) | 440 | if (ret < 0) |
421 | return ret; | 441 | return ret; |
422 | 442 | ||
423 | state->dnxt.fec = fec; | 443 | state->dnxt.fec = fec; |
@@ -429,7 +449,7 @@ static int cx24116_set_fec(struct cx24116_state* state, fe_modulation_t mod, fe_ | |||
429 | return 0; | 449 | return 0; |
430 | } | 450 | } |
431 | 451 | ||
432 | static int cx24116_set_symbolrate(struct cx24116_state* state, u32 rate) | 452 | static int cx24116_set_symbolrate(struct cx24116_state *state, u32 rate) |
433 | { | 453 | { |
434 | dprintk("%s(%d)\n", __func__, rate); | 454 | dprintk("%s(%d)\n", __func__, rate); |
435 | 455 | ||
@@ -446,42 +466,49 @@ static int cx24116_set_symbolrate(struct cx24116_state* state, u32 rate) | |||
446 | return 0; | 466 | return 0; |
447 | } | 467 | } |
448 | 468 | ||
449 | static int cx24116_load_firmware (struct dvb_frontend* fe, const struct firmware *fw); | 469 | static int cx24116_load_firmware(struct dvb_frontend *fe, |
470 | const struct firmware *fw); | ||
450 | 471 | ||
451 | static int cx24116_firmware_ondemand(struct dvb_frontend* fe) | 472 | static int cx24116_firmware_ondemand(struct dvb_frontend *fe) |
452 | { | 473 | { |
453 | struct cx24116_state *state = fe->demodulator_priv; | 474 | struct cx24116_state *state = fe->demodulator_priv; |
454 | const struct firmware *fw; | 475 | const struct firmware *fw; |
455 | int ret = 0; | 476 | int ret = 0; |
456 | 477 | ||
457 | dprintk("%s()\n",__func__); | 478 | dprintk("%s()\n", __func__); |
458 | 479 | ||
459 | if (cx24116_readreg(state, 0x20) > 0) | 480 | if (cx24116_readreg(state, 0x20) > 0) { |
460 | { | ||
461 | 481 | ||
462 | if (state->skip_fw_load) | 482 | if (state->skip_fw_load) |
463 | return 0; | 483 | return 0; |
464 | 484 | ||
465 | /* Load firmware */ | 485 | /* Load firmware */ |
466 | /* request the firmware, this will block until someone uploads it */ | 486 | /* request the firmware, this will block until loaded */ |
467 | printk("%s: Waiting for firmware upload (%s)...\n", __func__, CX24116_DEFAULT_FIRMWARE); | 487 | printk(KERN_INFO "%s: Waiting for firmware upload (%s)...\n", |
468 | ret = request_firmware(&fw, CX24116_DEFAULT_FIRMWARE, &state->i2c->dev); | 488 | __func__, CX24116_DEFAULT_FIRMWARE); |
469 | printk("%s: Waiting for firmware upload(2)...\n", __func__); | 489 | ret = request_firmware(&fw, CX24116_DEFAULT_FIRMWARE, |
490 | &state->i2c->dev); | ||
491 | printk(KERN_INFO "%s: Waiting for firmware upload(2)...\n", | ||
492 | __func__); | ||
470 | if (ret) { | 493 | if (ret) { |
471 | printk("%s: No firmware uploaded (timeout or file not found?)\n", __func__); | 494 | printk(KERN_ERR "%s: No firmware uploaded " |
495 | "(timeout or file not found?)\n", __func__); | ||
472 | return ret; | 496 | return ret; |
473 | } | 497 | } |
474 | 498 | ||
475 | /* Make sure we don't recurse back through here during loading */ | 499 | /* Make sure we don't recurse back through here |
500 | * during loading */ | ||
476 | state->skip_fw_load = 1; | 501 | state->skip_fw_load = 1; |
477 | 502 | ||
478 | ret = cx24116_load_firmware(fe, fw); | 503 | ret = cx24116_load_firmware(fe, fw); |
479 | if (ret) | 504 | if (ret) |
480 | printk("%s: Writing firmware to device failed\n", __func__); | 505 | printk(KERN_ERR "%s: Writing firmware to device failed\n", |
506 | __func__); | ||
481 | 507 | ||
482 | release_firmware(fw); | 508 | release_firmware(fw); |
483 | 509 | ||
484 | printk("%s: Firmware upload %s\n", __func__, ret == 0 ? "complete" : "failed"); | 510 | printk(KERN_INFO "%s: Firmware upload %s\n", __func__, |
511 | ret == 0 ? "complete" : "failed"); | ||
485 | 512 | ||
486 | /* Ensure firmware is always loaded if required */ | 513 | /* Ensure firmware is always loaded if required */ |
487 | state->skip_fw_load = 0; | 514 | state->skip_fw_load = 0; |
@@ -490,8 +517,10 @@ static int cx24116_firmware_ondemand(struct dvb_frontend* fe) | |||
490 | return ret; | 517 | return ret; |
491 | } | 518 | } |
492 | 519 | ||
493 | /* Take a basic firmware command structure, format it and forward it for processing */ | 520 | /* Take a basic firmware command structure, format it |
494 | static int cx24116_cmd_execute(struct dvb_frontend* fe, struct cx24116_cmd *cmd) | 521 | * and forward it for processing |
522 | */ | ||
523 | static int cx24116_cmd_execute(struct dvb_frontend *fe, struct cx24116_cmd *cmd) | ||
495 | { | 524 | { |
496 | struct cx24116_state *state = fe->demodulator_priv; | 525 | struct cx24116_state *state = fe->demodulator_priv; |
497 | int i, ret; | 526 | int i, ret; |
@@ -499,49 +528,49 @@ static int cx24116_cmd_execute(struct dvb_frontend* fe, struct cx24116_cmd *cmd) | |||
499 | dprintk("%s()\n", __func__); | 528 | dprintk("%s()\n", __func__); |
500 | 529 | ||
501 | /* Load the firmware if required */ | 530 | /* Load the firmware if required */ |
502 | if ( (ret = cx24116_firmware_ondemand(fe)) != 0) | 531 | ret = cx24116_firmware_ondemand(fe); |
503 | { | 532 | if (ret != 0) { |
504 | printk("%s(): Unable initialise the firmware\n", __func__); | 533 | printk(KERN_ERR "%s(): Unable initialise the firmware\n", |
534 | __func__); | ||
505 | return ret; | 535 | return ret; |
506 | } | 536 | } |
507 | 537 | ||
508 | /* Write the command */ | 538 | /* Write the command */ |
509 | for(i = 0; i < cmd->len ; i++) | 539 | for (i = 0; i < cmd->len ; i++) { |
510 | { | ||
511 | dprintk("%s: 0x%02x == 0x%02x\n", __func__, i, cmd->args[i]); | 540 | dprintk("%s: 0x%02x == 0x%02x\n", __func__, i, cmd->args[i]); |
512 | cx24116_writereg(state, i, cmd->args[i]); | 541 | cx24116_writereg(state, i, cmd->args[i]); |
513 | } | 542 | } |
514 | 543 | ||
515 | /* Start execution and wait for cmd to terminate */ | 544 | /* Start execution and wait for cmd to terminate */ |
516 | cx24116_writereg(state, CX24116_REG_EXECUTE, 0x01); | 545 | cx24116_writereg(state, CX24116_REG_EXECUTE, 0x01); |
517 | while( cx24116_readreg(state, CX24116_REG_EXECUTE) ) | 546 | while (cx24116_readreg(state, CX24116_REG_EXECUTE)) { |
518 | { | ||
519 | msleep(10); | 547 | msleep(10); |
520 | if(i++ > 64) | 548 | if (i++ > 64) { |
521 | { | 549 | /* Avoid looping forever if the firmware does |
522 | /* Avoid looping forever if the firmware does no respond */ | 550 | not respond */ |
523 | printk("%s() Firmware not responding\n", __func__); | 551 | printk(KERN_WARNING "%s() Firmware not responding\n", |
552 | __func__); | ||
524 | return -EREMOTEIO; | 553 | return -EREMOTEIO; |
525 | } | 554 | } |
526 | } | 555 | } |
527 | return 0; | 556 | return 0; |
528 | } | 557 | } |
529 | 558 | ||
530 | static int cx24116_load_firmware (struct dvb_frontend* fe, const struct firmware *fw) | 559 | static int cx24116_load_firmware(struct dvb_frontend *fe, |
560 | const struct firmware *fw) | ||
531 | { | 561 | { |
532 | struct cx24116_state* state = fe->demodulator_priv; | 562 | struct cx24116_state *state = fe->demodulator_priv; |
533 | struct cx24116_cmd cmd; | 563 | struct cx24116_cmd cmd; |
534 | int i, ret; | 564 | int i, ret; |
535 | unsigned char vers[4]; | 565 | unsigned char vers[4]; |
536 | 566 | ||
537 | dprintk("%s\n", __func__); | 567 | dprintk("%s\n", __func__); |
538 | dprintk("Firmware is %zu bytes (%02x %02x .. %02x %02x)\n" | 568 | dprintk("Firmware is %zu bytes (%02x %02x .. %02x %02x)\n", |
539 | ,fw->size | 569 | fw->size, |
540 | ,fw->data[0] | 570 | fw->data[0], |
541 | ,fw->data[1] | 571 | fw->data[1], |
542 | ,fw->data[ fw->size-2 ] | 572 | fw->data[fw->size-2], |
543 | ,fw->data[ fw->size-1 ] | 573 | fw->data[fw->size-1]); |
544 | ); | ||
545 | 574 | ||
546 | /* Toggle 88x SRST pin to reset demod */ | 575 | /* Toggle 88x SRST pin to reset demod */ |
547 | if (state->config->reset_device) | 576 | if (state->config->reset_device) |
@@ -587,7 +616,7 @@ static int cx24116_load_firmware (struct dvb_frontend* fe, const struct firmware | |||
587 | cmd.args[0x07] = 0x9d; | 616 | cmd.args[0x07] = 0x9d; |
588 | cmd.args[0x08] = 0xfc; | 617 | cmd.args[0x08] = 0xfc; |
589 | cmd.args[0x09] = 0x06; | 618 | cmd.args[0x09] = 0x06; |
590 | cmd.len= 0x0a; | 619 | cmd.len = 0x0a; |
591 | ret = cx24116_cmd_execute(fe, &cmd); | 620 | ret = cx24116_cmd_execute(fe, &cmd); |
592 | if (ret != 0) | 621 | if (ret != 0) |
593 | return ret; | 622 | return ret; |
@@ -598,7 +627,7 @@ static int cx24116_load_firmware (struct dvb_frontend* fe, const struct firmware | |||
598 | cmd.args[0x00] = CMD_TUNERINIT; | 627 | cmd.args[0x00] = CMD_TUNERINIT; |
599 | cmd.args[0x01] = 0x00; | 628 | cmd.args[0x01] = 0x00; |
600 | cmd.args[0x02] = 0x00; | 629 | cmd.args[0x02] = 0x00; |
601 | cmd.len= 0x03; | 630 | cmd.len = 0x03; |
602 | ret = cx24116_cmd_execute(fe, &cmd); | 631 | ret = cx24116_cmd_execute(fe, &cmd); |
603 | if (ret != 0) | 632 | if (ret != 0) |
604 | return ret; | 633 | return ret; |
@@ -615,36 +644,38 @@ static int cx24116_load_firmware (struct dvb_frontend* fe, const struct firmware | |||
615 | else | 644 | else |
616 | cmd.args[0x04] = 0x02; | 645 | cmd.args[0x04] = 0x02; |
617 | cmd.args[0x05] = 0x00; | 646 | cmd.args[0x05] = 0x00; |
618 | cmd.len= 0x06; | 647 | cmd.len = 0x06; |
619 | ret = cx24116_cmd_execute(fe, &cmd); | 648 | ret = cx24116_cmd_execute(fe, &cmd); |
620 | if (ret != 0) | 649 | if (ret != 0) |
621 | return ret; | 650 | return ret; |
622 | 651 | ||
623 | /* Firmware CMD 35: Get firmware version */ | 652 | /* Firmware CMD 35: Get firmware version */ |
624 | cmd.args[0x00] = CMD_UPDFWVERS; | 653 | cmd.args[0x00] = CMD_UPDFWVERS; |
625 | cmd.len= 0x02; | 654 | cmd.len = 0x02; |
626 | for(i=0; i<4; i++) { | 655 | for (i = 0; i < 4; i++) { |
627 | cmd.args[0x01] = i; | 656 | cmd.args[0x01] = i; |
628 | ret = cx24116_cmd_execute(fe, &cmd); | 657 | ret = cx24116_cmd_execute(fe, &cmd); |
629 | if (ret != 0) | 658 | if (ret != 0) |
630 | return ret; | 659 | return ret; |
631 | vers[i]= cx24116_readreg(state, CX24116_REG_MAILBOX); | 660 | vers[i] = cx24116_readreg(state, CX24116_REG_MAILBOX); |
632 | } | 661 | } |
633 | printk("%s: FW version %i.%i.%i.%i\n", __func__, | 662 | printk(KERN_INFO "%s: FW version %i.%i.%i.%i\n", __func__, |
634 | vers[0], vers[1], vers[2], vers[3]); | 663 | vers[0], vers[1], vers[2], vers[3]); |
635 | 664 | ||
636 | return 0; | 665 | return 0; |
637 | } | 666 | } |
638 | 667 | ||
639 | static int cx24116_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) | 668 | static int cx24116_set_voltage(struct dvb_frontend *fe, |
669 | fe_sec_voltage_t voltage) | ||
640 | { | 670 | { |
641 | /* The isl6421 module will override this function in the fops. */ | 671 | /* The isl6421 module will override this function in the fops. */ |
642 | dprintk("%s() This should never appear if the isl6421 module is loaded correctly\n",__func__); | 672 | dprintk("%s() This should never appear if the isl6421 module " |
673 | "is loaded correctly\n", __func__); | ||
643 | 674 | ||
644 | return -EOPNOTSUPP; | 675 | return -EOPNOTSUPP; |
645 | } | 676 | } |
646 | 677 | ||
647 | static int cx24116_read_status(struct dvb_frontend* fe, fe_status_t* status) | 678 | static int cx24116_read_status(struct dvb_frontend *fe, fe_status_t *status) |
648 | { | 679 | { |
649 | struct cx24116_state *state = fe->demodulator_priv; | 680 | struct cx24116_state *state = fe->demodulator_priv; |
650 | 681 | ||
@@ -666,22 +697,23 @@ static int cx24116_read_status(struct dvb_frontend* fe, fe_status_t* status) | |||
666 | return 0; | 697 | return 0; |
667 | } | 698 | } |
668 | 699 | ||
669 | static int cx24116_read_ber(struct dvb_frontend* fe, u32* ber) | 700 | static int cx24116_read_ber(struct dvb_frontend *fe, u32 *ber) |
670 | { | 701 | { |
671 | struct cx24116_state *state = fe->demodulator_priv; | 702 | struct cx24116_state *state = fe->demodulator_priv; |
672 | 703 | ||
673 | dprintk("%s()\n", __func__); | 704 | dprintk("%s()\n", __func__); |
674 | 705 | ||
675 | *ber = ( cx24116_readreg(state, CX24116_REG_BER24) << 24 ) | | 706 | *ber = (cx24116_readreg(state, CX24116_REG_BER24) << 24) | |
676 | ( cx24116_readreg(state, CX24116_REG_BER16) << 16 ) | | 707 | (cx24116_readreg(state, CX24116_REG_BER16) << 16) | |
677 | ( cx24116_readreg(state, CX24116_REG_BER8 ) << 8 ) | | 708 | (cx24116_readreg(state, CX24116_REG_BER8) << 8) | |
678 | cx24116_readreg(state, CX24116_REG_BER0 ); | 709 | cx24116_readreg(state, CX24116_REG_BER0); |
679 | 710 | ||
680 | return 0; | 711 | return 0; |
681 | } | 712 | } |
682 | 713 | ||
683 | /* TODO Determine function and scale appropriately */ | 714 | /* TODO Determine function and scale appropriately */ |
684 | static int cx24116_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength) | 715 | static int cx24116_read_signal_strength(struct dvb_frontend *fe, |
716 | u16 *signal_strength) | ||
685 | { | 717 | { |
686 | struct cx24116_state *state = fe->demodulator_priv; | 718 | struct cx24116_state *state = fe->demodulator_priv; |
687 | struct cx24116_cmd cmd; | 719 | struct cx24116_cmd cmd; |
@@ -692,39 +724,43 @@ static int cx24116_read_signal_strength(struct dvb_frontend* fe, u16* signal_str | |||
692 | 724 | ||
693 | /* Firmware CMD 19: Get AGC */ | 725 | /* Firmware CMD 19: Get AGC */ |
694 | cmd.args[0x00] = CMD_GETAGC; | 726 | cmd.args[0x00] = CMD_GETAGC; |
695 | cmd.len= 0x01; | 727 | cmd.len = 0x01; |
696 | ret = cx24116_cmd_execute(fe, &cmd); | 728 | ret = cx24116_cmd_execute(fe, &cmd); |
697 | if (ret != 0) | 729 | if (ret != 0) |
698 | return ret; | 730 | return ret; |
699 | 731 | ||
700 | sig_reading = ( cx24116_readreg(state, CX24116_REG_SSTATUS) & CX24116_SIGNAL_MASK ) | | 732 | sig_reading = |
701 | ( cx24116_readreg(state, CX24116_REG_SIGNAL) << 6 ); | 733 | (cx24116_readreg(state, |
702 | *signal_strength= 0 - sig_reading; | 734 | CX24116_REG_SSTATUS) & CX24116_SIGNAL_MASK) | |
735 | (cx24116_readreg(state, CX24116_REG_SIGNAL) << 6); | ||
736 | *signal_strength = 0 - sig_reading; | ||
703 | 737 | ||
704 | dprintk("%s: raw / cooked = 0x%04x / 0x%04x\n", __func__, sig_reading, *signal_strength); | 738 | dprintk("%s: raw / cooked = 0x%04x / 0x%04x\n", |
739 | __func__, sig_reading, *signal_strength); | ||
705 | 740 | ||
706 | return 0; | 741 | return 0; |
707 | } | 742 | } |
708 | 743 | ||
709 | /* SNR (0..100)% = (sig & 0xf0) * 10 + (sig & 0x0f) * 10 / 16 */ | 744 | /* SNR (0..100)% = (sig & 0xf0) * 10 + (sig & 0x0f) * 10 / 16 */ |
710 | static int cx24116_read_snr_pct(struct dvb_frontend* fe, u16* snr) | 745 | static int cx24116_read_snr_pct(struct dvb_frontend *fe, u16 *snr) |
711 | { | 746 | { |
712 | struct cx24116_state *state = fe->demodulator_priv; | 747 | struct cx24116_state *state = fe->demodulator_priv; |
713 | u8 snr_reading; | 748 | u8 snr_reading; |
714 | static const u32 snr_tab[] = { /* 10 x Table (rounded up) */ | 749 | static const u32 snr_tab[] = { /* 10 x Table (rounded up) */ |
715 | 0x00000,0x0199A,0x03333,0x04ccD,0x06667, | 750 | 0x00000, 0x0199A, 0x03333, 0x04ccD, 0x06667, |
716 | 0x08000,0x0999A,0x0b333,0x0cccD,0x0e667, | 751 | 0x08000, 0x0999A, 0x0b333, 0x0cccD, 0x0e667, |
717 | 0x10000,0x1199A,0x13333,0x14ccD,0x16667,0x18000 }; | 752 | 0x10000, 0x1199A, 0x13333, 0x14ccD, 0x16667, |
753 | 0x18000 }; | ||
718 | 754 | ||
719 | dprintk("%s()\n", __func__); | 755 | dprintk("%s()\n", __func__); |
720 | 756 | ||
721 | snr_reading = cx24116_readreg(state, CX24116_REG_QUALITY0); | 757 | snr_reading = cx24116_readreg(state, CX24116_REG_QUALITY0); |
722 | 758 | ||
723 | if(snr_reading >= 0xa0 /* 100% */) | 759 | if (snr_reading >= 0xa0 /* 100% */) |
724 | *snr = 0xffff; | 760 | *snr = 0xffff; |
725 | else | 761 | else |
726 | *snr = snr_tab [ ( snr_reading & 0xf0 ) >> 4 ] + | 762 | *snr = snr_tab[(snr_reading & 0xf0) >> 4] + |
727 | ( snr_tab [ ( snr_reading & 0x0f ) ] >> 4 ); | 763 | (snr_tab[(snr_reading & 0x0f)] >> 4); |
728 | 764 | ||
729 | dprintk("%s: raw / cooked = 0x%02x / 0x%04x\n", __func__, | 765 | dprintk("%s: raw / cooked = 0x%02x / 0x%04x\n", __func__, |
730 | snr_reading, *snr); | 766 | snr_reading, *snr); |
@@ -736,7 +772,7 @@ static int cx24116_read_snr_pct(struct dvb_frontend* fe, u16* snr) | |||
736 | * ESNO, from 0->30db (values 0->300). We provide this value by | 772 | * ESNO, from 0->30db (values 0->300). We provide this value by |
737 | * default. | 773 | * default. |
738 | */ | 774 | */ |
739 | static int cx24116_read_snr_esno(struct dvb_frontend* fe, u16* snr) | 775 | static int cx24116_read_snr_esno(struct dvb_frontend *fe, u16 *snr) |
740 | { | 776 | { |
741 | struct cx24116_state *state = fe->demodulator_priv; | 777 | struct cx24116_state *state = fe->demodulator_priv; |
742 | 778 | ||
@@ -750,7 +786,7 @@ static int cx24116_read_snr_esno(struct dvb_frontend* fe, u16* snr) | |||
750 | return 0; | 786 | return 0; |
751 | } | 787 | } |
752 | 788 | ||
753 | static int cx24116_read_snr(struct dvb_frontend* fe, u16* snr) | 789 | static int cx24116_read_snr(struct dvb_frontend *fe, u16 *snr) |
754 | { | 790 | { |
755 | if (esno_snr == 1) | 791 | if (esno_snr == 1) |
756 | return cx24116_read_snr_esno(fe, snr); | 792 | return cx24116_read_snr_esno(fe, snr); |
@@ -758,27 +794,27 @@ static int cx24116_read_snr(struct dvb_frontend* fe, u16* snr) | |||
758 | return cx24116_read_snr_pct(fe, snr); | 794 | return cx24116_read_snr_pct(fe, snr); |
759 | } | 795 | } |
760 | 796 | ||
761 | static int cx24116_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) | 797 | static int cx24116_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) |
762 | { | 798 | { |
763 | struct cx24116_state *state = fe->demodulator_priv; | 799 | struct cx24116_state *state = fe->demodulator_priv; |
764 | 800 | ||
765 | dprintk("%s()\n", __func__); | 801 | dprintk("%s()\n", __func__); |
766 | 802 | ||
767 | *ucblocks = ( cx24116_readreg(state, CX24116_REG_UCB8) << 8 ) | | 803 | *ucblocks = (cx24116_readreg(state, CX24116_REG_UCB8) << 8) | |
768 | cx24116_readreg(state, CX24116_REG_UCB0); | 804 | cx24116_readreg(state, CX24116_REG_UCB0); |
769 | 805 | ||
770 | return 0; | 806 | return 0; |
771 | } | 807 | } |
772 | 808 | ||
773 | /* Overwrite the current tuning params, we are about to tune */ | 809 | /* Overwrite the current tuning params, we are about to tune */ |
774 | static void cx24116_clone_params(struct dvb_frontend* fe) | 810 | static void cx24116_clone_params(struct dvb_frontend *fe) |
775 | { | 811 | { |
776 | struct cx24116_state *state = fe->demodulator_priv; | 812 | struct cx24116_state *state = fe->demodulator_priv; |
777 | memcpy(&state->dcur, &state->dnxt, sizeof(state->dcur)); | 813 | memcpy(&state->dcur, &state->dnxt, sizeof(state->dcur)); |
778 | } | 814 | } |
779 | 815 | ||
780 | /* Wait for LNB */ | 816 | /* Wait for LNB */ |
781 | static int cx24116_wait_for_lnb(struct dvb_frontend* fe) | 817 | static int cx24116_wait_for_lnb(struct dvb_frontend *fe) |
782 | { | 818 | { |
783 | struct cx24116_state *state = fe->demodulator_priv; | 819 | struct cx24116_state *state = fe->demodulator_priv; |
784 | int i; | 820 | int i; |
@@ -787,7 +823,7 @@ static int cx24116_wait_for_lnb(struct dvb_frontend* fe) | |||
787 | cx24116_readreg(state, CX24116_REG_QSTATUS)); | 823 | cx24116_readreg(state, CX24116_REG_QSTATUS)); |
788 | 824 | ||
789 | /* Wait for up to 300 ms */ | 825 | /* Wait for up to 300 ms */ |
790 | for(i = 0; i < 30 ; i++) { | 826 | for (i = 0; i < 30 ; i++) { |
791 | if (cx24116_readreg(state, CX24116_REG_QSTATUS) & 0x20) | 827 | if (cx24116_readreg(state, CX24116_REG_QSTATUS) & 0x20) |
792 | return 0; | 828 | return 0; |
793 | msleep(10); | 829 | msleep(10); |
@@ -798,20 +834,21 @@ static int cx24116_wait_for_lnb(struct dvb_frontend* fe) | |||
798 | return -ETIMEDOUT; /* -EBUSY ? */ | 834 | return -ETIMEDOUT; /* -EBUSY ? */ |
799 | } | 835 | } |
800 | 836 | ||
801 | static int cx24116_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) | 837 | static int cx24116_set_tone(struct dvb_frontend *fe, |
838 | fe_sec_tone_mode_t tone) | ||
802 | { | 839 | { |
803 | struct cx24116_cmd cmd; | 840 | struct cx24116_cmd cmd; |
804 | int ret; | 841 | int ret; |
805 | 842 | ||
806 | dprintk("%s(%d)\n", __func__, tone); | 843 | dprintk("%s(%d)\n", __func__, tone); |
807 | if ( (tone != SEC_TONE_ON) && (tone != SEC_TONE_OFF) ) { | 844 | if ((tone != SEC_TONE_ON) && (tone != SEC_TONE_OFF)) { |
808 | printk("%s: Invalid, tone=%d\n", __func__, tone); | 845 | printk(KERN_ERR "%s: Invalid, tone=%d\n", __func__, tone); |
809 | return -EINVAL; | 846 | return -EINVAL; |
810 | } | 847 | } |
811 | 848 | ||
812 | /* Wait for LNB ready */ | 849 | /* Wait for LNB ready */ |
813 | ret = cx24116_wait_for_lnb(fe); | 850 | ret = cx24116_wait_for_lnb(fe); |
814 | if(ret != 0) | 851 | if (ret != 0) |
815 | return ret; | 852 | return ret; |
816 | 853 | ||
817 | /* Min delay time after DiSEqC send */ | 854 | /* Min delay time after DiSEqC send */ |
@@ -820,7 +857,7 @@ static int cx24116_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) | |||
820 | /* This is always done before the tone is set */ | 857 | /* This is always done before the tone is set */ |
821 | cmd.args[0x00] = CMD_SET_TONEPRE; | 858 | cmd.args[0x00] = CMD_SET_TONEPRE; |
822 | cmd.args[0x01] = 0x00; | 859 | cmd.args[0x01] = 0x00; |
823 | cmd.len= 0x02; | 860 | cmd.len = 0x02; |
824 | ret = cx24116_cmd_execute(fe, &cmd); | 861 | ret = cx24116_cmd_execute(fe, &cmd); |
825 | if (ret != 0) | 862 | if (ret != 0) |
826 | return ret; | 863 | return ret; |
@@ -836,11 +873,11 @@ static int cx24116_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) | |||
836 | cmd.args[0x03] = 0x01; | 873 | cmd.args[0x03] = 0x01; |
837 | break; | 874 | break; |
838 | case SEC_TONE_OFF: | 875 | case SEC_TONE_OFF: |
839 | dprintk("%s: setting tone off\n",__func__); | 876 | dprintk("%s: setting tone off\n", __func__); |
840 | cmd.args[0x03] = 0x00; | 877 | cmd.args[0x03] = 0x00; |
841 | break; | 878 | break; |
842 | } | 879 | } |
843 | cmd.len= 0x04; | 880 | cmd.len = 0x04; |
844 | 881 | ||
845 | /* Min delay time before DiSEqC send */ | 882 | /* Min delay time before DiSEqC send */ |
846 | msleep(15); /* XXX determine is FW does this, see send_diseqc/burst */ | 883 | msleep(15); /* XXX determine is FW does this, see send_diseqc/burst */ |
@@ -849,7 +886,7 @@ static int cx24116_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) | |||
849 | } | 886 | } |
850 | 887 | ||
851 | /* Initialise DiSEqC */ | 888 | /* Initialise DiSEqC */ |
852 | static int cx24116_diseqc_init(struct dvb_frontend* fe) | 889 | static int cx24116_diseqc_init(struct dvb_frontend *fe) |
853 | { | 890 | { |
854 | struct cx24116_state *state = fe->demodulator_priv; | 891 | struct cx24116_state *state = fe->demodulator_priv; |
855 | struct cx24116_cmd cmd; | 892 | struct cx24116_cmd cmd; |
@@ -864,7 +901,7 @@ static int cx24116_diseqc_init(struct dvb_frontend* fe) | |||
864 | cmd.args[0x05] = 0x28; | 901 | cmd.args[0x05] = 0x28; |
865 | cmd.args[0x06] = (toneburst == CX24116_DISEQC_TONEOFF) ? 0x00 : 0x01; | 902 | cmd.args[0x06] = (toneburst == CX24116_DISEQC_TONEOFF) ? 0x00 : 0x01; |
866 | cmd.args[0x07] = 0x01; | 903 | cmd.args[0x07] = 0x01; |
867 | cmd.len= 0x08; | 904 | cmd.len = 0x08; |
868 | ret = cx24116_cmd_execute(fe, &cmd); | 905 | ret = cx24116_cmd_execute(fe, &cmd); |
869 | if (ret != 0) | 906 | if (ret != 0) |
870 | return ret; | 907 | return ret; |
@@ -878,36 +915,38 @@ static int cx24116_diseqc_init(struct dvb_frontend* fe) | |||
878 | /* Unknown */ | 915 | /* Unknown */ |
879 | state->dsec_cmd.args[CX24116_DISEQC_ARG2_2] = 0x02; | 916 | state->dsec_cmd.args[CX24116_DISEQC_ARG2_2] = 0x02; |
880 | state->dsec_cmd.args[CX24116_DISEQC_ARG3_0] = 0x00; | 917 | state->dsec_cmd.args[CX24116_DISEQC_ARG3_0] = 0x00; |
881 | state->dsec_cmd.args[CX24116_DISEQC_ARG4_0] = 0x00; /* Continuation flag? */ | 918 | /* Continuation flag? */ |
919 | state->dsec_cmd.args[CX24116_DISEQC_ARG4_0] = 0x00; | ||
882 | 920 | ||
883 | /* DiSEqC message length */ | 921 | /* DiSEqC message length */ |
884 | state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] = 0x00; | 922 | state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] = 0x00; |
885 | 923 | ||
886 | /* Command length */ | 924 | /* Command length */ |
887 | state->dsec_cmd.len= CX24116_DISEQC_MSGOFS; | 925 | state->dsec_cmd.len = CX24116_DISEQC_MSGOFS; |
888 | 926 | ||
889 | return 0; | 927 | return 0; |
890 | } | 928 | } |
891 | 929 | ||
892 | /* Send DiSEqC message with derived burst (hack) || previous burst */ | 930 | /* Send DiSEqC message with derived burst (hack) || previous burst */ |
893 | static int cx24116_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd *d) | 931 | static int cx24116_send_diseqc_msg(struct dvb_frontend *fe, |
932 | struct dvb_diseqc_master_cmd *d) | ||
894 | { | 933 | { |
895 | struct cx24116_state *state = fe->demodulator_priv; | 934 | struct cx24116_state *state = fe->demodulator_priv; |
896 | int i, ret; | 935 | int i, ret; |
897 | 936 | ||
898 | /* Dump DiSEqC message */ | 937 | /* Dump DiSEqC message */ |
899 | if (debug) { | 938 | if (debug) { |
900 | printk("cx24116: %s(", __func__); | 939 | printk(KERN_INFO "cx24116: %s(", __func__); |
901 | for(i = 0 ; i < d->msg_len ;) { | 940 | for (i = 0 ; i < d->msg_len ;) { |
902 | printk("0x%02x", d->msg[i]); | 941 | printk(KERN_INFO "0x%02x", d->msg[i]); |
903 | if(++i < d->msg_len) | 942 | if (++i < d->msg_len) |
904 | printk(", "); | 943 | printk(KERN_INFO ", "); |
905 | } | 944 | } |
906 | printk(") toneburst=%d\n", toneburst); | 945 | printk(") toneburst=%d\n", toneburst); |
907 | } | 946 | } |
908 | 947 | ||
909 | /* Validate length */ | 948 | /* Validate length */ |
910 | if(d->msg_len > (CX24116_ARGLEN - CX24116_DISEQC_MSGOFS)) | 949 | if (d->msg_len > (CX24116_ARGLEN - CX24116_DISEQC_MSGOFS)) |
911 | return -EINVAL; | 950 | return -EINVAL; |
912 | 951 | ||
913 | /* DiSEqC message */ | 952 | /* DiSEqC message */ |
@@ -918,18 +957,19 @@ static int cx24116_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_ma | |||
918 | state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] = d->msg_len; | 957 | state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] = d->msg_len; |
919 | 958 | ||
920 | /* Command length */ | 959 | /* Command length */ |
921 | state->dsec_cmd.len= CX24116_DISEQC_MSGOFS + state->dsec_cmd.args[CX24116_DISEQC_MSGLEN]; | 960 | state->dsec_cmd.len = CX24116_DISEQC_MSGOFS + |
961 | state->dsec_cmd.args[CX24116_DISEQC_MSGLEN]; | ||
922 | 962 | ||
923 | /* DiSEqC toneburst */ | 963 | /* DiSEqC toneburst */ |
924 | if(toneburst == CX24116_DISEQC_MESGCACHE) | 964 | if (toneburst == CX24116_DISEQC_MESGCACHE) |
925 | /* Message is cached */ | 965 | /* Message is cached */ |
926 | return 0; | 966 | return 0; |
927 | 967 | ||
928 | else if(toneburst == CX24116_DISEQC_TONEOFF) | 968 | else if (toneburst == CX24116_DISEQC_TONEOFF) |
929 | /* Message is sent without burst */ | 969 | /* Message is sent without burst */ |
930 | state->dsec_cmd.args[CX24116_DISEQC_BURST] = 0; | 970 | state->dsec_cmd.args[CX24116_DISEQC_BURST] = 0; |
931 | 971 | ||
932 | else if(toneburst == CX24116_DISEQC_TONECACHE) { | 972 | else if (toneburst == CX24116_DISEQC_TONECACHE) { |
933 | /* | 973 | /* |
934 | * Message is sent with derived else cached burst | 974 | * Message is sent with derived else cached burst |
935 | * | 975 | * |
@@ -948,15 +988,17 @@ static int cx24116_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_ma | |||
948 | * Y = VOLTAGE (0=13V, 1=18V) | 988 | * Y = VOLTAGE (0=13V, 1=18V) |
949 | * Z = BAND (0=LOW, 1=HIGH(22K)) | 989 | * Z = BAND (0=LOW, 1=HIGH(22K)) |
950 | */ | 990 | */ |
951 | if(d->msg_len >= 4 && d->msg[2] == 0x38) | 991 | if (d->msg_len >= 4 && d->msg[2] == 0x38) |
952 | state->dsec_cmd.args[CX24116_DISEQC_BURST] = ((d->msg[3] & 4) >> 2); | 992 | state->dsec_cmd.args[CX24116_DISEQC_BURST] = |
953 | if(debug) | 993 | ((d->msg[3] & 4) >> 2); |
954 | dprintk("%s burst=%d\n", __func__, state->dsec_cmd.args[CX24116_DISEQC_BURST]); | 994 | if (debug) |
995 | dprintk("%s burst=%d\n", __func__, | ||
996 | state->dsec_cmd.args[CX24116_DISEQC_BURST]); | ||
955 | } | 997 | } |
956 | 998 | ||
957 | /* Wait for LNB ready */ | 999 | /* Wait for LNB ready */ |
958 | ret = cx24116_wait_for_lnb(fe); | 1000 | ret = cx24116_wait_for_lnb(fe); |
959 | if(ret != 0) | 1001 | if (ret != 0) |
960 | return ret; | 1002 | return ret; |
961 | 1003 | ||
962 | /* Wait for voltage/min repeat delay */ | 1004 | /* Wait for voltage/min repeat delay */ |
@@ -964,7 +1006,7 @@ static int cx24116_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_ma | |||
964 | 1006 | ||
965 | /* Command */ | 1007 | /* Command */ |
966 | ret = cx24116_cmd_execute(fe, &state->dsec_cmd); | 1008 | ret = cx24116_cmd_execute(fe, &state->dsec_cmd); |
967 | if(ret != 0) | 1009 | if (ret != 0) |
968 | return ret; | 1010 | return ret; |
969 | /* | 1011 | /* |
970 | * Wait for send | 1012 | * Wait for send |
@@ -976,29 +1018,33 @@ static int cx24116_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_ma | |||
976 | * 12.5ms burst + | 1018 | * 12.5ms burst + |
977 | * >15ms delay (XXX determine if FW does this, see set_tone) | 1019 | * >15ms delay (XXX determine if FW does this, see set_tone) |
978 | */ | 1020 | */ |
979 | msleep( (state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] << 4) + ((toneburst == CX24116_DISEQC_TONEOFF) ? 30 : 60) ); | 1021 | msleep((state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] << 4) + |
1022 | ((toneburst == CX24116_DISEQC_TONEOFF) ? 30 : 60)); | ||
980 | 1023 | ||
981 | return 0; | 1024 | return 0; |
982 | } | 1025 | } |
983 | 1026 | ||
984 | /* Send DiSEqC burst */ | 1027 | /* Send DiSEqC burst */ |
985 | static int cx24116_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t burst) | 1028 | static int cx24116_diseqc_send_burst(struct dvb_frontend *fe, |
1029 | fe_sec_mini_cmd_t burst) | ||
986 | { | 1030 | { |
987 | struct cx24116_state *state = fe->demodulator_priv; | 1031 | struct cx24116_state *state = fe->demodulator_priv; |
988 | int ret; | 1032 | int ret; |
989 | 1033 | ||
990 | dprintk("%s(%d) toneburst=%d\n",__func__, burst, toneburst); | 1034 | dprintk("%s(%d) toneburst=%d\n", __func__, burst, toneburst); |
991 | 1035 | ||
992 | /* DiSEqC burst */ | 1036 | /* DiSEqC burst */ |
993 | if (burst == SEC_MINI_A) | 1037 | if (burst == SEC_MINI_A) |
994 | state->dsec_cmd.args[CX24116_DISEQC_BURST] = CX24116_DISEQC_MINI_A; | 1038 | state->dsec_cmd.args[CX24116_DISEQC_BURST] = |
995 | else if(burst == SEC_MINI_B) | 1039 | CX24116_DISEQC_MINI_A; |
996 | state->dsec_cmd.args[CX24116_DISEQC_BURST] = CX24116_DISEQC_MINI_B; | 1040 | else if (burst == SEC_MINI_B) |
1041 | state->dsec_cmd.args[CX24116_DISEQC_BURST] = | ||
1042 | CX24116_DISEQC_MINI_B; | ||
997 | else | 1043 | else |
998 | return -EINVAL; | 1044 | return -EINVAL; |
999 | 1045 | ||
1000 | /* DiSEqC toneburst */ | 1046 | /* DiSEqC toneburst */ |
1001 | if(toneburst != CX24116_DISEQC_MESGCACHE) | 1047 | if (toneburst != CX24116_DISEQC_MESGCACHE) |
1002 | /* Burst is cached */ | 1048 | /* Burst is cached */ |
1003 | return 0; | 1049 | return 0; |
1004 | 1050 | ||
@@ -1006,7 +1052,7 @@ static int cx24116_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t | |||
1006 | 1052 | ||
1007 | /* Wait for LNB ready */ | 1053 | /* Wait for LNB ready */ |
1008 | ret = cx24116_wait_for_lnb(fe); | 1054 | ret = cx24116_wait_for_lnb(fe); |
1009 | if(ret != 0) | 1055 | if (ret != 0) |
1010 | return ret; | 1056 | return ret; |
1011 | 1057 | ||
1012 | /* Wait for voltage/min repeat delay */ | 1058 | /* Wait for voltage/min repeat delay */ |
@@ -1014,7 +1060,7 @@ static int cx24116_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t | |||
1014 | 1060 | ||
1015 | /* Command */ | 1061 | /* Command */ |
1016 | ret = cx24116_cmd_execute(fe, &state->dsec_cmd); | 1062 | ret = cx24116_cmd_execute(fe, &state->dsec_cmd); |
1017 | if(ret != 0) | 1063 | if (ret != 0) |
1018 | return ret; | 1064 | return ret; |
1019 | 1065 | ||
1020 | /* | 1066 | /* |
@@ -1027,34 +1073,32 @@ static int cx24116_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t | |||
1027 | * 12.5ms burst + | 1073 | * 12.5ms burst + |
1028 | * >15ms delay (XXX determine if FW does this, see set_tone) | 1074 | * >15ms delay (XXX determine if FW does this, see set_tone) |
1029 | */ | 1075 | */ |
1030 | msleep( (state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] << 4) + 60 ); | 1076 | msleep((state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] << 4) + 60); |
1031 | 1077 | ||
1032 | return 0; | 1078 | return 0; |
1033 | } | 1079 | } |
1034 | 1080 | ||
1035 | static void cx24116_release(struct dvb_frontend* fe) | 1081 | static void cx24116_release(struct dvb_frontend *fe) |
1036 | { | 1082 | { |
1037 | struct cx24116_state* state = fe->demodulator_priv; | 1083 | struct cx24116_state *state = fe->demodulator_priv; |
1038 | dprintk("%s\n",__func__); | 1084 | dprintk("%s\n", __func__); |
1039 | kfree(state); | 1085 | kfree(state); |
1040 | } | 1086 | } |
1041 | 1087 | ||
1042 | static struct dvb_frontend_ops cx24116_ops; | 1088 | static struct dvb_frontend_ops cx24116_ops; |
1043 | 1089 | ||
1044 | struct dvb_frontend* cx24116_attach(const struct cx24116_config* config, | 1090 | struct dvb_frontend *cx24116_attach(const struct cx24116_config *config, |
1045 | struct i2c_adapter* i2c) | 1091 | struct i2c_adapter *i2c) |
1046 | { | 1092 | { |
1047 | struct cx24116_state* state = NULL; | 1093 | struct cx24116_state *state = NULL; |
1048 | int ret; | 1094 | int ret; |
1049 | 1095 | ||
1050 | dprintk("%s\n",__func__); | 1096 | dprintk("%s\n", __func__); |
1051 | 1097 | ||
1052 | /* allocate memory for the internal state */ | 1098 | /* allocate memory for the internal state */ |
1053 | state = kmalloc(sizeof(struct cx24116_state), GFP_KERNEL); | 1099 | state = kmalloc(sizeof(struct cx24116_state), GFP_KERNEL); |
1054 | if (state == NULL) { | 1100 | if (state == NULL) |
1055 | printk("Unable to kmalloc\n"); | ||
1056 | goto error1; | 1101 | goto error1; |
1057 | } | ||
1058 | 1102 | ||
1059 | /* setup the state */ | 1103 | /* setup the state */ |
1060 | memset(state, 0, sizeof(struct cx24116_state)); | 1104 | memset(state, 0, sizeof(struct cx24116_state)); |
@@ -1063,32 +1107,36 @@ struct dvb_frontend* cx24116_attach(const struct cx24116_config* config, | |||
1063 | state->i2c = i2c; | 1107 | state->i2c = i2c; |
1064 | 1108 | ||
1065 | /* check if the demod is present */ | 1109 | /* check if the demod is present */ |
1066 | ret = (cx24116_readreg(state, 0xFF) << 8) | cx24116_readreg(state, 0xFE); | 1110 | ret = (cx24116_readreg(state, 0xFF) << 8) | |
1111 | cx24116_readreg(state, 0xFE); | ||
1067 | if (ret != 0x0501) { | 1112 | if (ret != 0x0501) { |
1068 | printk("Invalid probe, probably not a CX24116 device\n"); | 1113 | printk(KERN_INFO "Invalid probe, probably not a CX24116 device\n"); |
1069 | goto error2; | 1114 | goto error2; |
1070 | } | 1115 | } |
1071 | 1116 | ||
1072 | /* create dvb_frontend */ | 1117 | /* create dvb_frontend */ |
1073 | memcpy(&state->frontend.ops, &cx24116_ops, sizeof(struct dvb_frontend_ops)); | 1118 | memcpy(&state->frontend.ops, &cx24116_ops, |
1119 | sizeof(struct dvb_frontend_ops)); | ||
1074 | state->frontend.demodulator_priv = state; | 1120 | state->frontend.demodulator_priv = state; |
1075 | return &state->frontend; | 1121 | return &state->frontend; |
1076 | 1122 | ||
1077 | error2: kfree(state); | 1123 | error2: kfree(state); |
1078 | error1: return NULL; | 1124 | error1: return NULL; |
1079 | } | 1125 | } |
1126 | EXPORT_SYMBOL(cx24116_attach); | ||
1127 | |||
1080 | /* | 1128 | /* |
1081 | * Initialise or wake up device | 1129 | * Initialise or wake up device |
1082 | * | 1130 | * |
1083 | * Power config will reset and load initial firmware if required | 1131 | * Power config will reset and load initial firmware if required |
1084 | */ | 1132 | */ |
1085 | static int cx24116_initfe(struct dvb_frontend* fe) | 1133 | static int cx24116_initfe(struct dvb_frontend *fe) |
1086 | { | 1134 | { |
1087 | struct cx24116_state* state = fe->demodulator_priv; | 1135 | struct cx24116_state *state = fe->demodulator_priv; |
1088 | struct cx24116_cmd cmd; | 1136 | struct cx24116_cmd cmd; |
1089 | int ret; | 1137 | int ret; |
1090 | 1138 | ||
1091 | dprintk("%s()\n",__func__); | 1139 | dprintk("%s()\n", __func__); |
1092 | 1140 | ||
1093 | /* Power on */ | 1141 | /* Power on */ |
1094 | cx24116_writereg(state, 0xe0, 0); | 1142 | cx24116_writereg(state, 0xe0, 0); |
@@ -1098,9 +1146,9 @@ static int cx24116_initfe(struct dvb_frontend* fe) | |||
1098 | /* Firmware CMD 36: Power config */ | 1146 | /* Firmware CMD 36: Power config */ |
1099 | cmd.args[0x00] = CMD_TUNERSLEEP; | 1147 | cmd.args[0x00] = CMD_TUNERSLEEP; |
1100 | cmd.args[0x01] = 0; | 1148 | cmd.args[0x01] = 0; |
1101 | cmd.len= 0x02; | 1149 | cmd.len = 0x02; |
1102 | ret = cx24116_cmd_execute(fe, &cmd); | 1150 | ret = cx24116_cmd_execute(fe, &cmd); |
1103 | if(ret != 0) | 1151 | if (ret != 0) |
1104 | return ret; | 1152 | return ret; |
1105 | 1153 | ||
1106 | return cx24116_diseqc_init(fe); | 1154 | return cx24116_diseqc_init(fe); |
@@ -1109,20 +1157,20 @@ static int cx24116_initfe(struct dvb_frontend* fe) | |||
1109 | /* | 1157 | /* |
1110 | * Put device to sleep | 1158 | * Put device to sleep |
1111 | */ | 1159 | */ |
1112 | static int cx24116_sleep(struct dvb_frontend* fe) | 1160 | static int cx24116_sleep(struct dvb_frontend *fe) |
1113 | { | 1161 | { |
1114 | struct cx24116_state* state = fe->demodulator_priv; | 1162 | struct cx24116_state *state = fe->demodulator_priv; |
1115 | struct cx24116_cmd cmd; | 1163 | struct cx24116_cmd cmd; |
1116 | int ret; | 1164 | int ret; |
1117 | 1165 | ||
1118 | dprintk("%s()\n",__func__); | 1166 | dprintk("%s()\n", __func__); |
1119 | 1167 | ||
1120 | /* Firmware CMD 36: Power config */ | 1168 | /* Firmware CMD 36: Power config */ |
1121 | cmd.args[0x00] = CMD_TUNERSLEEP; | 1169 | cmd.args[0x00] = CMD_TUNERSLEEP; |
1122 | cmd.args[0x01] = 1; | 1170 | cmd.args[0x01] = 1; |
1123 | cmd.len= 0x02; | 1171 | cmd.len = 0x02; |
1124 | ret = cx24116_cmd_execute(fe, &cmd); | 1172 | ret = cx24116_cmd_execute(fe, &cmd); |
1125 | if(ret != 0) | 1173 | if (ret != 0) |
1126 | return ret; | 1174 | return ret; |
1127 | 1175 | ||
1128 | /* Power off (Shutdown clocks) */ | 1176 | /* Power off (Shutdown clocks) */ |
@@ -1133,13 +1181,15 @@ static int cx24116_sleep(struct dvb_frontend* fe) | |||
1133 | return 0; | 1181 | return 0; |
1134 | } | 1182 | } |
1135 | 1183 | ||
1136 | static int cx24116_set_property(struct dvb_frontend *fe, struct dtv_property* tvp) | 1184 | static int cx24116_set_property(struct dvb_frontend *fe, |
1185 | struct dtv_property *tvp) | ||
1137 | { | 1186 | { |
1138 | dprintk("%s(..)\n", __func__); | 1187 | dprintk("%s(..)\n", __func__); |
1139 | return 0; | 1188 | return 0; |
1140 | } | 1189 | } |
1141 | 1190 | ||
1142 | static int cx24116_get_property(struct dvb_frontend *fe, struct dtv_property* tvp) | 1191 | static int cx24116_get_property(struct dvb_frontend *fe, |
1192 | struct dtv_property *tvp) | ||
1143 | { | 1193 | { |
1144 | dprintk("%s(..)\n", __func__); | 1194 | dprintk("%s(..)\n", __func__); |
1145 | return 0; | 1195 | return 0; |
@@ -1148,7 +1198,8 @@ static int cx24116_get_property(struct dvb_frontend *fe, struct dtv_property* tv | |||
1148 | /* dvb-core told us to tune, the tv property cache will be complete, | 1198 | /* dvb-core told us to tune, the tv property cache will be complete, |
1149 | * it's safe for is to pull values and use them for tuning purposes. | 1199 | * it's safe for is to pull values and use them for tuning purposes. |
1150 | */ | 1200 | */ |
1151 | static int cx24116_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) | 1201 | static int cx24116_set_frontend(struct dvb_frontend *fe, |
1202 | struct dvb_frontend_parameters *p) | ||
1152 | { | 1203 | { |
1153 | struct cx24116_state *state = fe->demodulator_priv; | 1204 | struct cx24116_state *state = fe->demodulator_priv; |
1154 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | 1205 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; |
@@ -1156,96 +1207,102 @@ static int cx24116_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par | |||
1156 | fe_status_t tunerstat; | 1207 | fe_status_t tunerstat; |
1157 | int i, status, ret, retune; | 1208 | int i, status, ret, retune; |
1158 | 1209 | ||
1159 | dprintk("%s()\n",__func__); | 1210 | dprintk("%s()\n", __func__); |
1160 | 1211 | ||
1161 | switch(c->delivery_system) { | 1212 | switch (c->delivery_system) { |
1162 | case SYS_DVBS: | 1213 | case SYS_DVBS: |
1163 | dprintk("%s: DVB-S delivery system selected\n",__func__); | 1214 | dprintk("%s: DVB-S delivery system selected\n", __func__); |
1164 | 1215 | ||
1165 | /* Only QPSK is supported for DVB-S */ | 1216 | /* Only QPSK is supported for DVB-S */ |
1166 | if(c->modulation != QPSK) { | 1217 | if (c->modulation != QPSK) { |
1167 | dprintk("%s: unsupported modulation selected (%d)\n", | 1218 | dprintk("%s: unsupported modulation selected (%d)\n", |
1168 | __func__, c->modulation); | 1219 | __func__, c->modulation); |
1169 | return -EOPNOTSUPP; | 1220 | return -EOPNOTSUPP; |
1170 | } | 1221 | } |
1171 | 1222 | ||
1172 | /* Pilot doesn't exist in DVB-S, turn bit off */ | 1223 | /* Pilot doesn't exist in DVB-S, turn bit off */ |
1173 | state->dnxt.pilot_val = CX24116_PILOT_OFF; | 1224 | state->dnxt.pilot_val = CX24116_PILOT_OFF; |
1174 | retune = 1; | 1225 | retune = 1; |
1175 | 1226 | ||
1176 | /* DVB-S only supports 0.35 */ | 1227 | /* DVB-S only supports 0.35 */ |
1177 | if(c->rolloff != ROLLOFF_35) { | 1228 | if (c->rolloff != ROLLOFF_35) { |
1178 | dprintk("%s: unsupported rolloff selected (%d)\n", | 1229 | dprintk("%s: unsupported rolloff selected (%d)\n", |
1179 | __func__, c->rolloff); | 1230 | __func__, c->rolloff); |
1180 | return -EOPNOTSUPP; | 1231 | return -EOPNOTSUPP; |
1181 | } | 1232 | } |
1182 | state->dnxt.rolloff_val = CX24116_ROLLOFF_035; | 1233 | state->dnxt.rolloff_val = CX24116_ROLLOFF_035; |
1183 | break; | 1234 | break; |
1184 | 1235 | ||
1185 | case SYS_DVBS2: | 1236 | case SYS_DVBS2: |
1186 | dprintk("%s: DVB-S2 delivery system selected\n",__func__); | 1237 | dprintk("%s: DVB-S2 delivery system selected\n", __func__); |
1187 | |||
1188 | /* | ||
1189 | * NBC 8PSK/QPSK with DVB-S is supported for DVB-S2, | ||
1190 | * but not hardware auto detection | ||
1191 | */ | ||
1192 | if(c->modulation != PSK_8 && c->modulation != QPSK) { | ||
1193 | dprintk("%s: unsupported modulation selected (%d)\n", | ||
1194 | __func__, c->modulation); | ||
1195 | return -EOPNOTSUPP; | ||
1196 | } | ||
1197 | 1238 | ||
1198 | switch(c->pilot) { | 1239 | /* |
1199 | case PILOT_AUTO: /* Not supported but emulated */ | 1240 | * NBC 8PSK/QPSK with DVB-S is supported for DVB-S2, |
1200 | retune = 2; /* Fall-through */ | 1241 | * but not hardware auto detection |
1201 | case PILOT_OFF: | 1242 | */ |
1202 | state->dnxt.pilot_val = CX24116_PILOT_OFF; | 1243 | if (c->modulation != PSK_8 && c->modulation != QPSK) { |
1203 | break; | 1244 | dprintk("%s: unsupported modulation selected (%d)\n", |
1204 | case PILOT_ON: | 1245 | __func__, c->modulation); |
1205 | state->dnxt.pilot_val = CX24116_PILOT_ON; | 1246 | return -EOPNOTSUPP; |
1206 | break; | 1247 | } |
1207 | default: | ||
1208 | dprintk("%s: unsupported pilot mode selected (%d)\n", | ||
1209 | __func__, c->pilot); | ||
1210 | return -EOPNOTSUPP; | ||
1211 | } | ||
1212 | 1248 | ||
1213 | switch(c->rolloff) { | 1249 | switch (c->pilot) { |
1214 | case ROLLOFF_20: | 1250 | case PILOT_AUTO: /* Not supported but emulated */ |
1215 | state->dnxt.rolloff_val= CX24116_ROLLOFF_020; | 1251 | state->dnxt.pilot_val = (c->modulation == QPSK) |
1216 | break; | 1252 | ? CX24116_PILOT_OFF : CX24116_PILOT_ON; |
1217 | case ROLLOFF_25: | 1253 | retune = 2; |
1218 | state->dnxt.rolloff_val= CX24116_ROLLOFF_025; | 1254 | break; |
1219 | break; | 1255 | case PILOT_OFF: |
1220 | case ROLLOFF_35: | 1256 | state->dnxt.pilot_val = CX24116_PILOT_OFF; |
1221 | state->dnxt.rolloff_val= CX24116_ROLLOFF_035; | 1257 | break; |
1222 | break; | 1258 | case PILOT_ON: |
1223 | case ROLLOFF_AUTO: /* Rolloff must be explicit */ | 1259 | state->dnxt.pilot_val = CX24116_PILOT_ON; |
1224 | default: | ||
1225 | dprintk("%s: unsupported rolloff selected (%d)\n", | ||
1226 | __func__, c->rolloff); | ||
1227 | return -EOPNOTSUPP; | ||
1228 | } | ||
1229 | break; | 1260 | break; |
1261 | default: | ||
1262 | dprintk("%s: unsupported pilot mode selected (%d)\n", | ||
1263 | __func__, c->pilot); | ||
1264 | return -EOPNOTSUPP; | ||
1265 | } | ||
1230 | 1266 | ||
1267 | switch (c->rolloff) { | ||
1268 | case ROLLOFF_20: | ||
1269 | state->dnxt.rolloff_val = CX24116_ROLLOFF_020; | ||
1270 | break; | ||
1271 | case ROLLOFF_25: | ||
1272 | state->dnxt.rolloff_val = CX24116_ROLLOFF_025; | ||
1273 | break; | ||
1274 | case ROLLOFF_35: | ||
1275 | state->dnxt.rolloff_val = CX24116_ROLLOFF_035; | ||
1276 | break; | ||
1277 | case ROLLOFF_AUTO: /* Rolloff must be explicit */ | ||
1231 | default: | 1278 | default: |
1232 | dprintk("%s: unsupported delivery system selected (%d)\n", | 1279 | dprintk("%s: unsupported rolloff selected (%d)\n", |
1233 | __func__, c->delivery_system); | 1280 | __func__, c->rolloff); |
1234 | return -EOPNOTSUPP; | 1281 | return -EOPNOTSUPP; |
1282 | } | ||
1283 | break; | ||
1284 | |||
1285 | default: | ||
1286 | dprintk("%s: unsupported delivery system selected (%d)\n", | ||
1287 | __func__, c->delivery_system); | ||
1288 | return -EOPNOTSUPP; | ||
1235 | } | 1289 | } |
1236 | state->dnxt.modulation = c->modulation; | 1290 | state->dnxt.modulation = c->modulation; |
1237 | state->dnxt.frequency = c->frequency; | 1291 | state->dnxt.frequency = c->frequency; |
1238 | state->dnxt.pilot = c->pilot; | 1292 | state->dnxt.pilot = c->pilot; |
1239 | state->dnxt.rolloff = c->rolloff; | 1293 | state->dnxt.rolloff = c->rolloff; |
1240 | 1294 | ||
1241 | if ((ret = cx24116_set_inversion(state, c->inversion)) != 0) | 1295 | ret = cx24116_set_inversion(state, c->inversion); |
1296 | if (ret != 0) | ||
1242 | return ret; | 1297 | return ret; |
1243 | 1298 | ||
1244 | /* FEC_NONE/AUTO for DVB-S2 is not supported and detected here */ | 1299 | /* FEC_NONE/AUTO for DVB-S2 is not supported and detected here */ |
1245 | if ((ret = cx24116_set_fec(state, c->modulation, c->fec_inner)) != 0) | 1300 | ret = cx24116_set_fec(state, c->modulation, c->fec_inner); |
1301 | if (ret != 0) | ||
1246 | return ret; | 1302 | return ret; |
1247 | 1303 | ||
1248 | if ((ret = cx24116_set_symbolrate(state, c->symbol_rate)) != 0) | 1304 | ret = cx24116_set_symbolrate(state, c->symbol_rate); |
1305 | if (ret != 0) | ||
1249 | return ret; | 1306 | return ret; |
1250 | 1307 | ||
1251 | /* discard the 'current' tuning parameters and prepare to tune */ | 1308 | /* discard the 'current' tuning parameters and prepare to tune */ |
@@ -1271,7 +1328,7 @@ static int cx24116_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par | |||
1271 | /* Set/Reset B/W */ | 1328 | /* Set/Reset B/W */ |
1272 | cmd.args[0x00] = CMD_BANDWIDTH; | 1329 | cmd.args[0x00] = CMD_BANDWIDTH; |
1273 | cmd.args[0x01] = 0x01; | 1330 | cmd.args[0x01] = 0x01; |
1274 | cmd.len= 0x02; | 1331 | cmd.len = 0x02; |
1275 | ret = cx24116_cmd_execute(fe, &cmd); | 1332 | ret = cx24116_cmd_execute(fe, &cmd); |
1276 | if (ret != 0) | 1333 | if (ret != 0) |
1277 | return ret; | 1334 | return ret; |
@@ -1319,7 +1376,7 @@ static int cx24116_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par | |||
1319 | cx24116_writereg(state, CX24116_REG_RATEDIV, 0x00); | 1376 | cx24116_writereg(state, CX24116_REG_RATEDIV, 0x00); |
1320 | } | 1377 | } |
1321 | 1378 | ||
1322 | cmd.len= 0x13; | 1379 | cmd.len = 0x13; |
1323 | 1380 | ||
1324 | /* We need to support pilot and non-pilot tuning in the | 1381 | /* We need to support pilot and non-pilot tuning in the |
1325 | * driver automatically. This is a workaround for because | 1382 | * driver automatically. This is a workaround for because |
@@ -1327,12 +1384,13 @@ static int cx24116_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par | |||
1327 | */ | 1384 | */ |
1328 | do { | 1385 | do { |
1329 | /* Reset status register */ | 1386 | /* Reset status register */ |
1330 | status = cx24116_readreg(state, CX24116_REG_SSTATUS) & CX24116_SIGNAL_MASK; | 1387 | status = cx24116_readreg(state, CX24116_REG_SSTATUS) |
1388 | & CX24116_SIGNAL_MASK; | ||
1331 | cx24116_writereg(state, CX24116_REG_SSTATUS, status); | 1389 | cx24116_writereg(state, CX24116_REG_SSTATUS, status); |
1332 | 1390 | ||
1333 | /* Tune */ | 1391 | /* Tune */ |
1334 | ret = cx24116_cmd_execute(fe, &cmd); | 1392 | ret = cx24116_cmd_execute(fe, &cmd); |
1335 | if( ret != 0 ) | 1393 | if (ret != 0) |
1336 | break; | 1394 | break; |
1337 | 1395 | ||
1338 | /* | 1396 | /* |
@@ -1341,28 +1399,27 @@ static int cx24116_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par | |||
1341 | * If we are able to tune then generally it occurs within 100ms. | 1399 | * If we are able to tune then generally it occurs within 100ms. |
1342 | * If it takes longer, try a different toneburst setting. | 1400 | * If it takes longer, try a different toneburst setting. |
1343 | */ | 1401 | */ |
1344 | for(i = 0; i < 50 ; i++) { | 1402 | for (i = 0; i < 50 ; i++) { |
1345 | cx24116_read_status(fe, &tunerstat); | 1403 | cx24116_read_status(fe, &tunerstat); |
1346 | status = tunerstat & (FE_HAS_SIGNAL | FE_HAS_SYNC); | 1404 | status = tunerstat & (FE_HAS_SIGNAL | FE_HAS_SYNC); |
1347 | if(status == (FE_HAS_SIGNAL | FE_HAS_SYNC)) { | 1405 | if (status == (FE_HAS_SIGNAL | FE_HAS_SYNC)) { |
1348 | dprintk("%s: Tuned\n",__func__); | 1406 | dprintk("%s: Tuned\n", __func__); |
1349 | goto tuned; | 1407 | goto tuned; |
1350 | } | 1408 | } |
1351 | msleep(10); | 1409 | msleep(10); |
1352 | } | 1410 | } |
1353 | 1411 | ||
1354 | dprintk("%s: Not tuned\n",__func__); | 1412 | dprintk("%s: Not tuned\n", __func__); |
1355 | 1413 | ||
1356 | /* Toggle pilot bit when in auto-pilot */ | 1414 | /* Toggle pilot bit when in auto-pilot */ |
1357 | if(state->dcur.pilot == PILOT_AUTO) | 1415 | if (state->dcur.pilot == PILOT_AUTO) |
1358 | cmd.args[0x07] ^= CX24116_PILOT_ON; | 1416 | cmd.args[0x07] ^= CX24116_PILOT_ON; |
1359 | } | 1417 | } while (--retune); |
1360 | while(--retune); | ||
1361 | 1418 | ||
1362 | tuned: /* Set/Reset B/W */ | 1419 | tuned: /* Set/Reset B/W */ |
1363 | cmd.args[0x00] = CMD_BANDWIDTH; | 1420 | cmd.args[0x00] = CMD_BANDWIDTH; |
1364 | cmd.args[0x01] = 0x00; | 1421 | cmd.args[0x01] = 0x00; |
1365 | cmd.len= 0x02; | 1422 | cmd.len = 0x02; |
1366 | ret = cx24116_cmd_execute(fe, &cmd); | 1423 | ret = cx24116_cmd_execute(fe, &cmd); |
1367 | if (ret != 0) | 1424 | if (ret != 0) |
1368 | return ret; | 1425 | return ret; |
@@ -1407,17 +1464,7 @@ static struct dvb_frontend_ops cx24116_ops = { | |||
1407 | .set_frontend = cx24116_set_frontend, | 1464 | .set_frontend = cx24116_set_frontend, |
1408 | }; | 1465 | }; |
1409 | 1466 | ||
1410 | module_param(debug, int, 0644); | ||
1411 | MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)"); | ||
1412 | |||
1413 | module_param(toneburst, int, 0644); | ||
1414 | MODULE_PARM_DESC(toneburst, "DiSEqC toneburst 0=OFF, 1=TONE CACHE, 2=MESSAGE CACHE (default:1)"); | ||
1415 | |||
1416 | module_param(esno_snr, int, 0644); | ||
1417 | MODULE_PARM_DESC(debug, "SNR return units, 0=PERCENTAGE 0-100, 1=ESNO(db * 10) (default:0)"); | ||
1418 | |||
1419 | MODULE_DESCRIPTION("DVB Frontend module for Conexant cx24116/cx24118 hardware"); | 1467 | MODULE_DESCRIPTION("DVB Frontend module for Conexant cx24116/cx24118 hardware"); |
1420 | MODULE_AUTHOR("Steven Toth"); | 1468 | MODULE_AUTHOR("Steven Toth"); |
1421 | MODULE_LICENSE("GPL"); | 1469 | MODULE_LICENSE("GPL"); |
1422 | 1470 | ||
1423 | EXPORT_SYMBOL(cx24116_attach); | ||
diff --git a/drivers/media/dvb/frontends/cx24116.h b/drivers/media/dvb/frontends/cx24116.h index 8dbcec268394..4cb3ddd6c626 100644 --- a/drivers/media/dvb/frontends/cx24116.h +++ b/drivers/media/dvb/frontends/cx24116.h | |||
@@ -23,31 +23,32 @@ | |||
23 | 23 | ||
24 | #include <linux/dvb/frontend.h> | 24 | #include <linux/dvb/frontend.h> |
25 | 25 | ||
26 | struct cx24116_config | 26 | struct cx24116_config { |
27 | { | ||
28 | /* the demodulator's i2c address */ | 27 | /* the demodulator's i2c address */ |
29 | u8 demod_address; | 28 | u8 demod_address; |
30 | 29 | ||
31 | /* Need to set device param for start_dma */ | 30 | /* Need to set device param for start_dma */ |
32 | int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured); | 31 | int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured); |
33 | 32 | ||
34 | /* Need to reset device during firmware loading */ | 33 | /* Need to reset device during firmware loading */ |
35 | int (*reset_device)(struct dvb_frontend* fe); | 34 | int (*reset_device)(struct dvb_frontend *fe); |
36 | 35 | ||
37 | /* Need to set MPEG parameters */ | 36 | /* Need to set MPEG parameters */ |
38 | u8 mpg_clk_pos_pol:0x02; | 37 | u8 mpg_clk_pos_pol:0x02; |
39 | }; | 38 | }; |
40 | 39 | ||
41 | #if defined(CONFIG_DVB_CX24116) || defined(CONFIG_DVB_CX24116_MODULE) | 40 | #if defined(CONFIG_DVB_CX24116) || defined(CONFIG_DVB_CX24116_MODULE) |
42 | extern struct dvb_frontend* cx24116_attach(const struct cx24116_config* config, | 41 | extern struct dvb_frontend *cx24116_attach( |
43 | struct i2c_adapter* i2c); | 42 | const struct cx24116_config *config, |
43 | struct i2c_adapter *i2c); | ||
44 | #else | 44 | #else |
45 | static inline struct dvb_frontend* cx24116_attach(const struct cx24116_config* config, | 45 | static inline struct dvb_frontend *cx24116_attach( |
46 | struct i2c_adapter* i2c) | 46 | const struct cx24116_config *config, |
47 | struct i2c_adapter *i2c) | ||
47 | { | 48 | { |
48 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); | 49 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); |
49 | return NULL; | 50 | return NULL; |
50 | } | 51 | } |
51 | #endif // CONFIG_DVB_CX24116 | 52 | #endif |
52 | 53 | ||
53 | #endif /* CX24116_H */ | 54 | #endif /* CX24116_H */ |
diff --git a/drivers/media/dvb/frontends/cx24123.c b/drivers/media/dvb/frontends/cx24123.c index 7156157cb34b..1a8c36f76061 100644 --- a/drivers/media/dvb/frontends/cx24123.c +++ b/drivers/media/dvb/frontends/cx24123.c | |||
@@ -33,7 +33,13 @@ | |||
33 | #define XTAL 10111000 | 33 | #define XTAL 10111000 |
34 | 34 | ||
35 | static int force_band; | 35 | static int force_band; |
36 | module_param(force_band, int, 0644); | ||
37 | MODULE_PARM_DESC(force_band, "Force a specific band select "\ | ||
38 | "(1-9, default:off)."); | ||
39 | |||
36 | static int debug; | 40 | static int debug; |
41 | module_param(debug, int, 0644); | ||
42 | MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)"); | ||
37 | 43 | ||
38 | #define info(args...) do { printk(KERN_INFO "CX24123: " args); } while (0) | 44 | #define info(args...) do { printk(KERN_INFO "CX24123: " args); } while (0) |
39 | #define err(args...) do { printk(KERN_ERR "CX24123: " args); } while (0) | 45 | #define err(args...) do { printk(KERN_ERR "CX24123: " args); } while (0) |
@@ -46,10 +52,9 @@ static int debug; | |||
46 | } \ | 52 | } \ |
47 | } while (0) | 53 | } while (0) |
48 | 54 | ||
49 | struct cx24123_state | 55 | struct cx24123_state { |
50 | { | 56 | struct i2c_adapter *i2c; |
51 | struct i2c_adapter* i2c; | 57 | const struct cx24123_config *config; |
52 | const struct cx24123_config* config; | ||
53 | 58 | ||
54 | struct dvb_frontend frontend; | 59 | struct dvb_frontend frontend; |
55 | 60 | ||
@@ -70,8 +75,7 @@ struct cx24123_state | |||
70 | }; | 75 | }; |
71 | 76 | ||
72 | /* Various tuner defaults need to be established for a given symbol rate Sps */ | 77 | /* Various tuner defaults need to be established for a given symbol rate Sps */ |
73 | static struct | 78 | static struct cx24123_AGC_val { |
74 | { | ||
75 | u32 symbolrate_low; | 79 | u32 symbolrate_low; |
76 | u32 symbolrate_high; | 80 | u32 symbolrate_high; |
77 | u32 VCAprogdata; | 81 | u32 VCAprogdata; |
@@ -109,8 +113,7 @@ static struct | |||
109 | * fixme: The bounds on the bands do not match the doc in real life. | 113 | * fixme: The bounds on the bands do not match the doc in real life. |
110 | * fixme: Some of them have been moved, other might need adjustment. | 114 | * fixme: Some of them have been moved, other might need adjustment. |
111 | */ | 115 | */ |
112 | static struct | 116 | static struct cx24123_bandselect_val { |
113 | { | ||
114 | u32 freq_low; | 117 | u32 freq_low; |
115 | u32 freq_high; | 118 | u32 freq_high; |
116 | u32 VCOdivider; | 119 | u32 VCOdivider; |
@@ -249,7 +252,8 @@ static int cx24123_i2c_writereg(struct cx24123_state *state, | |||
249 | 252 | ||
250 | /* printk(KERN_DEBUG "wr(%02x): %02x %02x\n", i2c_addr, reg, data); */ | 253 | /* printk(KERN_DEBUG "wr(%02x): %02x %02x\n", i2c_addr, reg, data); */ |
251 | 254 | ||
252 | if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) { | 255 | err = i2c_transfer(state->i2c, &msg, 1); |
256 | if (err != 1) { | ||
253 | printk("%s: writereg error(err == %i, reg == 0x%02x," | 257 | printk("%s: writereg error(err == %i, reg == 0x%02x," |
254 | " data == 0x%02x)\n", __func__, err, reg, data); | 258 | " data == 0x%02x)\n", __func__, err, reg, data); |
255 | return err; | 259 | return err; |
@@ -284,7 +288,8 @@ static int cx24123_i2c_readreg(struct cx24123_state *state, u8 i2c_addr, u8 reg) | |||
284 | #define cx24123_writereg(state, reg, val) \ | 288 | #define cx24123_writereg(state, reg, val) \ |
285 | cx24123_i2c_writereg(state, state->config->demod_address, reg, val) | 289 | cx24123_i2c_writereg(state, state->config->demod_address, reg, val) |
286 | 290 | ||
287 | static int cx24123_set_inversion(struct cx24123_state* state, fe_spectral_inversion_t inversion) | 291 | static int cx24123_set_inversion(struct cx24123_state *state, |
292 | fe_spectral_inversion_t inversion) | ||
288 | { | 293 | { |
289 | u8 nom_reg = cx24123_readreg(state, 0x0e); | 294 | u8 nom_reg = cx24123_readreg(state, 0x0e); |
290 | u8 auto_reg = cx24123_readreg(state, 0x10); | 295 | u8 auto_reg = cx24123_readreg(state, 0x10); |
@@ -311,7 +316,8 @@ static int cx24123_set_inversion(struct cx24123_state* state, fe_spectral_invers | |||
311 | return 0; | 316 | return 0; |
312 | } | 317 | } |
313 | 318 | ||
314 | static int cx24123_get_inversion(struct cx24123_state* state, fe_spectral_inversion_t *inversion) | 319 | static int cx24123_get_inversion(struct cx24123_state *state, |
320 | fe_spectral_inversion_t *inversion) | ||
315 | { | 321 | { |
316 | u8 val; | 322 | u8 val; |
317 | 323 | ||
@@ -328,18 +334,20 @@ static int cx24123_get_inversion(struct cx24123_state* state, fe_spectral_invers | |||
328 | return 0; | 334 | return 0; |
329 | } | 335 | } |
330 | 336 | ||
331 | static int cx24123_set_fec(struct cx24123_state* state, fe_code_rate_t fec) | 337 | static int cx24123_set_fec(struct cx24123_state *state, fe_code_rate_t fec) |
332 | { | 338 | { |
333 | u8 nom_reg = cx24123_readreg(state, 0x0e) & ~0x07; | 339 | u8 nom_reg = cx24123_readreg(state, 0x0e) & ~0x07; |
334 | 340 | ||
335 | if ( (fec < FEC_NONE) || (fec > FEC_AUTO) ) | 341 | if ((fec < FEC_NONE) || (fec > FEC_AUTO)) |
336 | fec = FEC_AUTO; | 342 | fec = FEC_AUTO; |
337 | 343 | ||
338 | /* Set the soft decision threshold */ | 344 | /* Set the soft decision threshold */ |
339 | if(fec == FEC_1_2) | 345 | if (fec == FEC_1_2) |
340 | cx24123_writereg(state, 0x43, cx24123_readreg(state, 0x43) | 0x01); | 346 | cx24123_writereg(state, 0x43, |
347 | cx24123_readreg(state, 0x43) | 0x01); | ||
341 | else | 348 | else |
342 | cx24123_writereg(state, 0x43, cx24123_readreg(state, 0x43) & ~0x01); | 349 | cx24123_writereg(state, 0x43, |
350 | cx24123_readreg(state, 0x43) & ~0x01); | ||
343 | 351 | ||
344 | switch (fec) { | 352 | switch (fec) { |
345 | case FEC_1_2: | 353 | case FEC_1_2: |
@@ -388,11 +396,11 @@ static int cx24123_set_fec(struct cx24123_state* state, fe_code_rate_t fec) | |||
388 | return 0; | 396 | return 0; |
389 | } | 397 | } |
390 | 398 | ||
391 | static int cx24123_get_fec(struct cx24123_state* state, fe_code_rate_t *fec) | 399 | static int cx24123_get_fec(struct cx24123_state *state, fe_code_rate_t *fec) |
392 | { | 400 | { |
393 | int ret; | 401 | int ret; |
394 | 402 | ||
395 | ret = cx24123_readreg (state, 0x1b); | 403 | ret = cx24123_readreg(state, 0x1b); |
396 | if (ret < 0) | 404 | if (ret < 0) |
397 | return ret; | 405 | return ret; |
398 | ret = ret & 0x07; | 406 | ret = ret & 0x07; |
@@ -433,16 +441,16 @@ static u32 cx24123_int_log2(u32 a, u32 b) | |||
433 | { | 441 | { |
434 | u32 exp, nearest = 0; | 442 | u32 exp, nearest = 0; |
435 | u32 div = a / b; | 443 | u32 div = a / b; |
436 | if(a % b >= b / 2) ++div; | 444 | if (a % b >= b / 2) |
437 | if(div < (1 << 31)) | 445 | ++div; |
438 | { | 446 | if (div < (1 << 31)) { |
439 | for(exp = 1; div > exp; nearest++) | 447 | for (exp = 1; div > exp; nearest++) |
440 | exp += exp; | 448 | exp += exp; |
441 | } | 449 | } |
442 | return nearest; | 450 | return nearest; |
443 | } | 451 | } |
444 | 452 | ||
445 | static int cx24123_set_symbolrate(struct cx24123_state* state, u32 srate) | 453 | static int cx24123_set_symbolrate(struct cx24123_state *state, u32 srate) |
446 | { | 454 | { |
447 | u32 tmp, sample_rate, ratio, sample_gain; | 455 | u32 tmp, sample_rate, ratio, sample_gain; |
448 | u8 pll_mult; | 456 | u8 pll_mult; |
@@ -498,9 +506,9 @@ static int cx24123_set_symbolrate(struct cx24123_state* state, u32 srate) | |||
498 | 506 | ||
499 | cx24123_writereg(state, 0x01, pll_mult * 6); | 507 | cx24123_writereg(state, 0x01, pll_mult * 6); |
500 | 508 | ||
501 | cx24123_writereg(state, 0x08, (ratio >> 16) & 0x3f ); | 509 | cx24123_writereg(state, 0x08, (ratio >> 16) & 0x3f); |
502 | cx24123_writereg(state, 0x09, (ratio >> 8) & 0xff ); | 510 | cx24123_writereg(state, 0x09, (ratio >> 8) & 0xff); |
503 | cx24123_writereg(state, 0x0a, (ratio ) & 0xff ); | 511 | cx24123_writereg(state, 0x0a, ratio & 0xff); |
504 | 512 | ||
505 | /* also set the demodulator sample gain */ | 513 | /* also set the demodulator sample gain */ |
506 | sample_gain = cx24123_int_log2(sample_rate, srate); | 514 | sample_gain = cx24123_int_log2(sample_rate, srate); |
@@ -514,10 +522,12 @@ static int cx24123_set_symbolrate(struct cx24123_state* state, u32 srate) | |||
514 | } | 522 | } |
515 | 523 | ||
516 | /* | 524 | /* |
517 | * Based on the required frequency and symbolrate, the tuner AGC has to be configured | 525 | * Based on the required frequency and symbolrate, the tuner AGC has |
518 | * and the correct band selected. Calculate those values | 526 | * to be configured and the correct band selected. |
527 | * Calculate those values. | ||
519 | */ | 528 | */ |
520 | static int cx24123_pll_calculate(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) | 529 | static int cx24123_pll_calculate(struct dvb_frontend *fe, |
530 | struct dvb_frontend_parameters *p) | ||
521 | { | 531 | { |
522 | struct cx24123_state *state = fe->demodulator_priv; | 532 | struct cx24123_state *state = fe->demodulator_priv; |
523 | u32 ndiv = 0, adiv = 0, vco_div = 0; | 533 | u32 ndiv = 0, adiv = 0, vco_div = 0; |
@@ -525,6 +535,8 @@ static int cx24123_pll_calculate(struct dvb_frontend* fe, struct dvb_frontend_pa | |||
525 | int pump = 2; | 535 | int pump = 2; |
526 | int band = 0; | 536 | int band = 0; |
527 | int num_bands = ARRAY_SIZE(cx24123_bandselect_vals); | 537 | int num_bands = ARRAY_SIZE(cx24123_bandselect_vals); |
538 | struct cx24123_bandselect_val *bsv = NULL; | ||
539 | struct cx24123_AGC_val *agcv = NULL; | ||
528 | 540 | ||
529 | /* Defaults for low freq, low rate */ | 541 | /* Defaults for low freq, low rate */ |
530 | state->VCAarg = cx24123_AGC_vals[0].VCAprogdata; | 542 | state->VCAarg = cx24123_AGC_vals[0].VCAprogdata; |
@@ -532,58 +544,65 @@ static int cx24123_pll_calculate(struct dvb_frontend* fe, struct dvb_frontend_pa | |||
532 | state->bandselectarg = cx24123_bandselect_vals[0].progdata; | 544 | state->bandselectarg = cx24123_bandselect_vals[0].progdata; |
533 | vco_div = cx24123_bandselect_vals[0].VCOdivider; | 545 | vco_div = cx24123_bandselect_vals[0].VCOdivider; |
534 | 546 | ||
535 | /* For the given symbol rate, determine the VCA, VGA and FILTUNE programming bits */ | 547 | /* For the given symbol rate, determine the VCA, VGA and |
536 | for (i = 0; i < ARRAY_SIZE(cx24123_AGC_vals); i++) | 548 | * FILTUNE programming bits */ |
537 | { | 549 | for (i = 0; i < ARRAY_SIZE(cx24123_AGC_vals); i++) { |
538 | if ((cx24123_AGC_vals[i].symbolrate_low <= p->u.qpsk.symbol_rate) && | 550 | agcv = &cx24123_AGC_vals[i]; |
539 | (cx24123_AGC_vals[i].symbolrate_high >= p->u.qpsk.symbol_rate) ) { | 551 | if ((agcv->symbolrate_low <= p->u.qpsk.symbol_rate) && |
540 | state->VCAarg = cx24123_AGC_vals[i].VCAprogdata; | 552 | (agcv->symbolrate_high >= p->u.qpsk.symbol_rate)) { |
541 | state->VGAarg = cx24123_AGC_vals[i].VGAprogdata; | 553 | state->VCAarg = agcv->VCAprogdata; |
542 | state->FILTune = cx24123_AGC_vals[i].FILTune; | 554 | state->VGAarg = agcv->VGAprogdata; |
555 | state->FILTune = agcv->FILTune; | ||
543 | } | 556 | } |
544 | } | 557 | } |
545 | 558 | ||
546 | /* determine the band to use */ | 559 | /* determine the band to use */ |
547 | if(force_band < 1 || force_band > num_bands) | 560 | if (force_band < 1 || force_band > num_bands) { |
548 | { | 561 | for (i = 0; i < num_bands; i++) { |
549 | for (i = 0; i < num_bands; i++) | 562 | bsv = &cx24123_bandselect_vals[i]; |
550 | { | 563 | if ((bsv->freq_low <= p->frequency) && |
551 | if ((cx24123_bandselect_vals[i].freq_low <= p->frequency) && | 564 | (bsv->freq_high >= p->frequency)) |
552 | (cx24123_bandselect_vals[i].freq_high >= p->frequency) ) | ||
553 | band = i; | 565 | band = i; |
554 | } | 566 | } |
555 | } | 567 | } else |
556 | else | ||
557 | band = force_band - 1; | 568 | band = force_band - 1; |
558 | 569 | ||
559 | state->bandselectarg = cx24123_bandselect_vals[band].progdata; | 570 | state->bandselectarg = cx24123_bandselect_vals[band].progdata; |
560 | vco_div = cx24123_bandselect_vals[band].VCOdivider; | 571 | vco_div = cx24123_bandselect_vals[band].VCOdivider; |
561 | 572 | ||
562 | /* determine the charge pump current */ | 573 | /* determine the charge pump current */ |
563 | if ( p->frequency < (cx24123_bandselect_vals[band].freq_low + cx24123_bandselect_vals[band].freq_high)/2 ) | 574 | if (p->frequency < (cx24123_bandselect_vals[band].freq_low + |
575 | cx24123_bandselect_vals[band].freq_high) / 2) | ||
564 | pump = 0x01; | 576 | pump = 0x01; |
565 | else | 577 | else |
566 | pump = 0x02; | 578 | pump = 0x02; |
567 | 579 | ||
568 | /* Determine the N/A dividers for the requested lband freq (in kHz). */ | 580 | /* Determine the N/A dividers for the requested lband freq (in kHz). */ |
569 | /* Note: the reference divider R=10, frequency is in KHz, XTAL is in Hz */ | 581 | /* Note: the reference divider R=10, frequency is in KHz, |
570 | ndiv = ( ((p->frequency * vco_div * 10) / (2 * XTAL / 1000)) / 32) & 0x1ff; | 582 | * XTAL is in Hz */ |
571 | adiv = ( ((p->frequency * vco_div * 10) / (2 * XTAL / 1000)) % 32) & 0x1f; | 583 | ndiv = (((p->frequency * vco_div * 10) / |
584 | (2 * XTAL / 1000)) / 32) & 0x1ff; | ||
585 | adiv = (((p->frequency * vco_div * 10) / | ||
586 | (2 * XTAL / 1000)) % 32) & 0x1f; | ||
572 | 587 | ||
573 | if (adiv == 0 && ndiv > 0) | 588 | if (adiv == 0 && ndiv > 0) |
574 | ndiv--; | 589 | ndiv--; |
575 | 590 | ||
576 | /* control bits 11, refdiv 11, charge pump polarity 1, charge pump current, ndiv, adiv */ | 591 | /* control bits 11, refdiv 11, charge pump polarity 1, |
577 | state->pllarg = (3 << 19) | (3 << 17) | (1 << 16) | (pump << 14) | (ndiv << 5) | adiv; | 592 | * charge pump current, ndiv, adiv */ |
593 | state->pllarg = (3 << 19) | (3 << 17) | (1 << 16) | | ||
594 | (pump << 14) | (ndiv << 5) | adiv; | ||
578 | 595 | ||
579 | return 0; | 596 | return 0; |
580 | } | 597 | } |
581 | 598 | ||
582 | /* | 599 | /* |
583 | * Tuner data is 21 bits long, must be left-aligned in data. | 600 | * Tuner data is 21 bits long, must be left-aligned in data. |
584 | * Tuner cx24109 is written through a dedicated 3wire interface on the demod chip. | 601 | * Tuner cx24109 is written through a dedicated 3wire interface |
602 | * on the demod chip. | ||
585 | */ | 603 | */ |
586 | static int cx24123_pll_writereg(struct dvb_frontend* fe, struct dvb_frontend_parameters *p, u32 data) | 604 | static int cx24123_pll_writereg(struct dvb_frontend *fe, |
605 | struct dvb_frontend_parameters *p, u32 data) | ||
587 | { | 606 | { |
588 | struct cx24123_state *state = fe->demodulator_priv; | 607 | struct cx24123_state *state = fe->demodulator_priv; |
589 | unsigned long timeout; | 608 | unsigned long timeout; |
@@ -610,7 +629,7 @@ static int cx24123_pll_writereg(struct dvb_frontend* fe, struct dvb_frontend_par | |||
610 | 629 | ||
611 | /* send another 8 bytes, wait for the send to be completed */ | 630 | /* send another 8 bytes, wait for the send to be completed */ |
612 | timeout = jiffies + msecs_to_jiffies(40); | 631 | timeout = jiffies + msecs_to_jiffies(40); |
613 | cx24123_writereg(state, 0x22, (data>>8) & 0xff ); | 632 | cx24123_writereg(state, 0x22, (data >> 8) & 0xff); |
614 | while ((cx24123_readreg(state, 0x20) & 0x40) == 0) { | 633 | while ((cx24123_readreg(state, 0x20) & 0x40) == 0) { |
615 | if (time_after(jiffies, timeout)) { | 634 | if (time_after(jiffies, timeout)) { |
616 | err("%s: demodulator is not responding, "\ | 635 | err("%s: demodulator is not responding, "\ |
@@ -620,9 +639,10 @@ static int cx24123_pll_writereg(struct dvb_frontend* fe, struct dvb_frontend_par | |||
620 | msleep(10); | 639 | msleep(10); |
621 | } | 640 | } |
622 | 641 | ||
623 | /* send the lower 5 bits of this byte, padded with 3 LBB, wait for the send to be completed */ | 642 | /* send the lower 5 bits of this byte, padded with 3 LBB, |
643 | * wait for the send to be completed */ | ||
624 | timeout = jiffies + msecs_to_jiffies(40); | 644 | timeout = jiffies + msecs_to_jiffies(40); |
625 | cx24123_writereg(state, 0x22, (data) & 0xff ); | 645 | cx24123_writereg(state, 0x22, (data) & 0xff); |
626 | while ((cx24123_readreg(state, 0x20) & 0x80)) { | 646 | while ((cx24123_readreg(state, 0x20) & 0x80)) { |
627 | if (time_after(jiffies, timeout)) { | 647 | if (time_after(jiffies, timeout)) { |
628 | err("%s: demodulator is not responding," \ | 648 | err("%s: demodulator is not responding," \ |
@@ -639,7 +659,8 @@ static int cx24123_pll_writereg(struct dvb_frontend* fe, struct dvb_frontend_par | |||
639 | return 0; | 659 | return 0; |
640 | } | 660 | } |
641 | 661 | ||
642 | static int cx24123_pll_tune(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) | 662 | static int cx24123_pll_tune(struct dvb_frontend *fe, |
663 | struct dvb_frontend_parameters *p) | ||
643 | { | 664 | { |
644 | struct cx24123_state *state = fe->demodulator_priv; | 665 | struct cx24123_state *state = fe->demodulator_priv; |
645 | u8 val; | 666 | u8 val; |
@@ -690,7 +711,7 @@ static int cx24123_repeater_mode(struct cx24123_state *state, u8 mode, u8 start) | |||
690 | return cx24123_writereg(state, 0x23, r); | 711 | return cx24123_writereg(state, 0x23, r); |
691 | } | 712 | } |
692 | 713 | ||
693 | static int cx24123_initfe(struct dvb_frontend* fe) | 714 | static int cx24123_initfe(struct dvb_frontend *fe) |
694 | { | 715 | { |
695 | struct cx24123_state *state = fe->demodulator_priv; | 716 | struct cx24123_state *state = fe->demodulator_priv; |
696 | int i; | 717 | int i; |
@@ -699,19 +720,22 @@ static int cx24123_initfe(struct dvb_frontend* fe) | |||
699 | 720 | ||
700 | /* Configure the demod to a good set of defaults */ | 721 | /* Configure the demod to a good set of defaults */ |
701 | for (i = 0; i < ARRAY_SIZE(cx24123_regdata); i++) | 722 | for (i = 0; i < ARRAY_SIZE(cx24123_regdata); i++) |
702 | cx24123_writereg(state, cx24123_regdata[i].reg, cx24123_regdata[i].data); | 723 | cx24123_writereg(state, cx24123_regdata[i].reg, |
724 | cx24123_regdata[i].data); | ||
703 | 725 | ||
704 | /* Set the LNB polarity */ | 726 | /* Set the LNB polarity */ |
705 | if(state->config->lnb_polarity) | 727 | if (state->config->lnb_polarity) |
706 | cx24123_writereg(state, 0x32, cx24123_readreg(state, 0x32) | 0x02); | 728 | cx24123_writereg(state, 0x32, |
729 | cx24123_readreg(state, 0x32) | 0x02); | ||
707 | 730 | ||
708 | if (state->config->dont_use_pll) | 731 | if (state->config->dont_use_pll) |
709 | cx24123_repeater_mode(state, 1, 0); | 732 | cx24123_repeater_mode(state, 1, 0); |
710 | 733 | ||
711 | return 0; | 734 | return 0; |
712 | } | 735 | } |
713 | 736 | ||
714 | static int cx24123_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) | 737 | static int cx24123_set_voltage(struct dvb_frontend *fe, |
738 | fe_sec_voltage_t voltage) | ||
715 | { | 739 | { |
716 | struct cx24123_state *state = fe->demodulator_priv; | 740 | struct cx24123_state *state = fe->demodulator_priv; |
717 | u8 val; | 741 | u8 val; |
@@ -740,7 +764,7 @@ static void cx24123_wait_for_diseqc(struct cx24123_state *state) | |||
740 | { | 764 | { |
741 | unsigned long timeout = jiffies + msecs_to_jiffies(200); | 765 | unsigned long timeout = jiffies + msecs_to_jiffies(200); |
742 | while (!(cx24123_readreg(state, 0x29) & 0x40)) { | 766 | while (!(cx24123_readreg(state, 0x29) & 0x40)) { |
743 | if(time_after(jiffies, timeout)) { | 767 | if (time_after(jiffies, timeout)) { |
744 | err("%s: diseqc queue not ready, " \ | 768 | err("%s: diseqc queue not ready, " \ |
745 | "command may be lost.\n", __func__); | 769 | "command may be lost.\n", __func__); |
746 | break; | 770 | break; |
@@ -749,7 +773,8 @@ static void cx24123_wait_for_diseqc(struct cx24123_state *state) | |||
749 | } | 773 | } |
750 | } | 774 | } |
751 | 775 | ||
752 | static int cx24123_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd *cmd) | 776 | static int cx24123_send_diseqc_msg(struct dvb_frontend *fe, |
777 | struct dvb_diseqc_master_cmd *cmd) | ||
753 | { | 778 | { |
754 | struct cx24123_state *state = fe->demodulator_priv; | 779 | struct cx24123_state *state = fe->demodulator_priv; |
755 | int i, val, tone; | 780 | int i, val, tone; |
@@ -771,20 +796,21 @@ static int cx24123_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_ma | |||
771 | cx24123_writereg(state, 0x2C + i, cmd->msg[i]); | 796 | cx24123_writereg(state, 0x2C + i, cmd->msg[i]); |
772 | 797 | ||
773 | val = cx24123_readreg(state, 0x29); | 798 | val = cx24123_readreg(state, 0x29); |
774 | cx24123_writereg(state, 0x29, ((val & 0x90) | 0x40) | ((cmd->msg_len-3) & 3)); | 799 | cx24123_writereg(state, 0x29, ((val & 0x90) | 0x40) | |
800 | ((cmd->msg_len-3) & 3)); | ||
775 | 801 | ||
776 | /* wait for diseqc message to finish sending */ | 802 | /* wait for diseqc message to finish sending */ |
777 | cx24123_wait_for_diseqc(state); | 803 | cx24123_wait_for_diseqc(state); |
778 | 804 | ||
779 | /* restart continuous tone if enabled */ | 805 | /* restart continuous tone if enabled */ |
780 | if (tone & 0x10) { | 806 | if (tone & 0x10) |
781 | cx24123_writereg(state, 0x29, tone & ~0x40); | 807 | cx24123_writereg(state, 0x29, tone & ~0x40); |
782 | } | ||
783 | 808 | ||
784 | return 0; | 809 | return 0; |
785 | } | 810 | } |
786 | 811 | ||
787 | static int cx24123_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t burst) | 812 | static int cx24123_diseqc_send_burst(struct dvb_frontend *fe, |
813 | fe_sec_mini_cmd_t burst) | ||
788 | { | 814 | { |
789 | struct cx24123_state *state = fe->demodulator_priv; | 815 | struct cx24123_state *state = fe->demodulator_priv; |
790 | int val, tone; | 816 | int val, tone; |
@@ -814,13 +840,13 @@ static int cx24123_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t | |||
814 | cx24123_writereg(state, 0x2a, cx24123_readreg(state, 0x2a) & 0xfb); | 840 | cx24123_writereg(state, 0x2a, cx24123_readreg(state, 0x2a) & 0xfb); |
815 | 841 | ||
816 | /* restart continuous tone if enabled */ | 842 | /* restart continuous tone if enabled */ |
817 | if (tone & 0x10) { | 843 | if (tone & 0x10) |
818 | cx24123_writereg(state, 0x29, tone & ~0x40); | 844 | cx24123_writereg(state, 0x29, tone & ~0x40); |
819 | } | 845 | |
820 | return 0; | 846 | return 0; |
821 | } | 847 | } |
822 | 848 | ||
823 | static int cx24123_read_status(struct dvb_frontend* fe, fe_status_t* status) | 849 | static int cx24123_read_status(struct dvb_frontend *fe, fe_status_t *status) |
824 | { | 850 | { |
825 | struct cx24123_state *state = fe->demodulator_priv; | 851 | struct cx24123_state *state = fe->demodulator_priv; |
826 | int sync = cx24123_readreg(state, 0x14); | 852 | int sync = cx24123_readreg(state, 0x14); |
@@ -853,8 +879,9 @@ static int cx24123_read_status(struct dvb_frontend* fe, fe_status_t* status) | |||
853 | } | 879 | } |
854 | 880 | ||
855 | /* | 881 | /* |
856 | * Configured to return the measurement of errors in blocks, because no UCBLOCKS value | 882 | * Configured to return the measurement of errors in blocks, |
857 | * is available, so this value doubles up to satisfy both measurements | 883 | * because no UCBLOCKS value is available, so this value doubles up |
884 | * to satisfy both measurements. | ||
858 | */ | 885 | */ |
859 | static int cx24123_read_ber(struct dvb_frontend *fe, u32 *ber) | 886 | static int cx24123_read_ber(struct dvb_frontend *fe, u32 *ber) |
860 | { | 887 | { |
@@ -876,7 +903,8 @@ static int cx24123_read_signal_strength(struct dvb_frontend *fe, | |||
876 | { | 903 | { |
877 | struct cx24123_state *state = fe->demodulator_priv; | 904 | struct cx24123_state *state = fe->demodulator_priv; |
878 | 905 | ||
879 | *signal_strength = cx24123_readreg(state, 0x3b) << 8; /* larger = better */ | 906 | /* larger = better */ |
907 | *signal_strength = cx24123_readreg(state, 0x3b) << 8; | ||
880 | 908 | ||
881 | dprintk("Signal strength = %d\n", *signal_strength); | 909 | dprintk("Signal strength = %d\n", *signal_strength); |
882 | 910 | ||
@@ -907,7 +935,7 @@ static int cx24123_set_frontend(struct dvb_frontend *fe, | |||
907 | if (state->config->set_ts_params) | 935 | if (state->config->set_ts_params) |
908 | state->config->set_ts_params(fe, 0); | 936 | state->config->set_ts_params(fe, 0); |
909 | 937 | ||
910 | state->currentfreq=p->frequency; | 938 | state->currentfreq = p->frequency; |
911 | state->currentsymbolrate = p->u.qpsk.symbol_rate; | 939 | state->currentsymbolrate = p->u.qpsk.symbol_rate; |
912 | 940 | ||
913 | cx24123_set_inversion(state, p->inversion); | 941 | cx24123_set_inversion(state, p->inversion); |
@@ -932,7 +960,8 @@ static int cx24123_set_frontend(struct dvb_frontend *fe, | |||
932 | return 0; | 960 | return 0; |
933 | } | 961 | } |
934 | 962 | ||
935 | static int cx24123_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) | 963 | static int cx24123_get_frontend(struct dvb_frontend *fe, |
964 | struct dvb_frontend_parameters *p) | ||
936 | { | 965 | { |
937 | struct cx24123_state *state = fe->demodulator_priv; | 966 | struct cx24123_state *state = fe->demodulator_priv; |
938 | 967 | ||
@@ -952,7 +981,7 @@ static int cx24123_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_par | |||
952 | return 0; | 981 | return 0; |
953 | } | 982 | } |
954 | 983 | ||
955 | static int cx24123_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) | 984 | static int cx24123_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) |
956 | { | 985 | { |
957 | struct cx24123_state *state = fe->demodulator_priv; | 986 | struct cx24123_state *state = fe->demodulator_priv; |
958 | u8 val; | 987 | u8 val; |
@@ -977,8 +1006,8 @@ static int cx24123_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) | |||
977 | return 0; | 1006 | return 0; |
978 | } | 1007 | } |
979 | 1008 | ||
980 | static int cx24123_tune(struct dvb_frontend* fe, | 1009 | static int cx24123_tune(struct dvb_frontend *fe, |
981 | struct dvb_frontend_parameters* params, | 1010 | struct dvb_frontend_parameters *params, |
982 | unsigned int mode_flags, | 1011 | unsigned int mode_flags, |
983 | unsigned int *delay, | 1012 | unsigned int *delay, |
984 | fe_status_t *status) | 1013 | fe_status_t *status) |
@@ -997,12 +1026,12 @@ static int cx24123_tune(struct dvb_frontend* fe, | |||
997 | 1026 | ||
998 | static int cx24123_get_algo(struct dvb_frontend *fe) | 1027 | static int cx24123_get_algo(struct dvb_frontend *fe) |
999 | { | 1028 | { |
1000 | return 1; //FE_ALGO_HW | 1029 | return 1; /* FE_ALGO_HW */ |
1001 | } | 1030 | } |
1002 | 1031 | ||
1003 | static void cx24123_release(struct dvb_frontend* fe) | 1032 | static void cx24123_release(struct dvb_frontend *fe) |
1004 | { | 1033 | { |
1005 | struct cx24123_state* state = fe->demodulator_priv; | 1034 | struct cx24123_state *state = fe->demodulator_priv; |
1006 | dprintk("\n"); | 1035 | dprintk("\n"); |
1007 | i2c_del_adapter(&state->tuner_i2c_adapter); | 1036 | i2c_del_adapter(&state->tuner_i2c_adapter); |
1008 | kfree(state); | 1037 | kfree(state); |
@@ -1013,7 +1042,7 @@ static int cx24123_tuner_i2c_tuner_xfer(struct i2c_adapter *i2c_adap, | |||
1013 | { | 1042 | { |
1014 | struct cx24123_state *state = i2c_get_adapdata(i2c_adap); | 1043 | struct cx24123_state *state = i2c_get_adapdata(i2c_adap); |
1015 | /* this repeater closes after the first stop */ | 1044 | /* this repeater closes after the first stop */ |
1016 | cx24123_repeater_mode(state, 1, 1); | 1045 | cx24123_repeater_mode(state, 1, 1); |
1017 | return i2c_transfer(state->i2c, msg, num); | 1046 | return i2c_transfer(state->i2c, msg, num); |
1018 | } | 1047 | } |
1019 | 1048 | ||
@@ -1037,8 +1066,8 @@ EXPORT_SYMBOL(cx24123_get_tuner_i2c_adapter); | |||
1037 | 1066 | ||
1038 | static struct dvb_frontend_ops cx24123_ops; | 1067 | static struct dvb_frontend_ops cx24123_ops; |
1039 | 1068 | ||
1040 | struct dvb_frontend* cx24123_attach(const struct cx24123_config* config, | 1069 | struct dvb_frontend *cx24123_attach(const struct cx24123_config *config, |
1041 | struct i2c_adapter* i2c) | 1070 | struct i2c_adapter *i2c) |
1042 | { | 1071 | { |
1043 | struct cx24123_state *state = | 1072 | struct cx24123_state *state = |
1044 | kzalloc(sizeof(struct cx24123_state), GFP_KERNEL); | 1073 | kzalloc(sizeof(struct cx24123_state), GFP_KERNEL); |
@@ -1057,20 +1086,25 @@ struct dvb_frontend* cx24123_attach(const struct cx24123_config* config, | |||
1057 | /* check if the demod is there */ | 1086 | /* check if the demod is there */ |
1058 | state->demod_rev = cx24123_readreg(state, 0x00); | 1087 | state->demod_rev = cx24123_readreg(state, 0x00); |
1059 | switch (state->demod_rev) { | 1088 | switch (state->demod_rev) { |
1060 | case 0xe1: info("detected CX24123C\n"); break; | 1089 | case 0xe1: |
1061 | case 0xd1: info("detected CX24123\n"); break; | 1090 | info("detected CX24123C\n"); |
1091 | break; | ||
1092 | case 0xd1: | ||
1093 | info("detected CX24123\n"); | ||
1094 | break; | ||
1062 | default: | 1095 | default: |
1063 | err("wrong demod revision: %x\n", state->demod_rev); | 1096 | err("wrong demod revision: %x\n", state->demod_rev); |
1064 | goto error; | 1097 | goto error; |
1065 | } | 1098 | } |
1066 | 1099 | ||
1067 | /* create dvb_frontend */ | 1100 | /* create dvb_frontend */ |
1068 | memcpy(&state->frontend.ops, &cx24123_ops, sizeof(struct dvb_frontend_ops)); | 1101 | memcpy(&state->frontend.ops, &cx24123_ops, |
1102 | sizeof(struct dvb_frontend_ops)); | ||
1069 | state->frontend.demodulator_priv = state; | 1103 | state->frontend.demodulator_priv = state; |
1070 | 1104 | ||
1071 | /* create tuner i2c adapter */ | 1105 | /* create tuner i2c adapter */ |
1072 | if (config->dont_use_pll) | 1106 | if (config->dont_use_pll) |
1073 | cx24123_repeater_mode(state, 1, 0); | 1107 | cx24123_repeater_mode(state, 1, 0); |
1074 | 1108 | ||
1075 | strlcpy(state->tuner_i2c_adapter.name, "CX24123 tuner I2C bus", | 1109 | strlcpy(state->tuner_i2c_adapter.name, "CX24123 tuner I2C bus", |
1076 | sizeof(state->tuner_i2c_adapter.name)); | 1110 | sizeof(state->tuner_i2c_adapter.name)); |
@@ -1079,7 +1113,7 @@ struct dvb_frontend* cx24123_attach(const struct cx24123_config* config, | |||
1079 | state->tuner_i2c_adapter.algo_data = NULL; | 1113 | state->tuner_i2c_adapter.algo_data = NULL; |
1080 | i2c_set_adapdata(&state->tuner_i2c_adapter, state); | 1114 | i2c_set_adapdata(&state->tuner_i2c_adapter, state); |
1081 | if (i2c_add_adapter(&state->tuner_i2c_adapter) < 0) { | 1115 | if (i2c_add_adapter(&state->tuner_i2c_adapter) < 0) { |
1082 | err("tuner i2c bus could not be initialized\n"); | 1116 | err("tuner i2c bus could not be initialized\n"); |
1083 | goto error; | 1117 | goto error; |
1084 | } | 1118 | } |
1085 | 1119 | ||
@@ -1090,6 +1124,7 @@ error: | |||
1090 | 1124 | ||
1091 | return NULL; | 1125 | return NULL; |
1092 | } | 1126 | } |
1127 | EXPORT_SYMBOL(cx24123_attach); | ||
1093 | 1128 | ||
1094 | static struct dvb_frontend_ops cx24123_ops = { | 1129 | static struct dvb_frontend_ops cx24123_ops = { |
1095 | 1130 | ||
@@ -1126,15 +1161,8 @@ static struct dvb_frontend_ops cx24123_ops = { | |||
1126 | .get_frontend_algo = cx24123_get_algo, | 1161 | .get_frontend_algo = cx24123_get_algo, |
1127 | }; | 1162 | }; |
1128 | 1163 | ||
1129 | module_param(debug, int, 0644); | ||
1130 | MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)"); | ||
1131 | |||
1132 | module_param(force_band, int, 0644); | ||
1133 | MODULE_PARM_DESC(force_band, "Force a specific band select (1-9, default:off)."); | ||
1134 | |||
1135 | MODULE_DESCRIPTION("DVB Frontend module for Conexant " \ | 1164 | MODULE_DESCRIPTION("DVB Frontend module for Conexant " \ |
1136 | "CX24123/CX24109/CX24113 hardware"); | 1165 | "CX24123/CX24109/CX24113 hardware"); |
1137 | MODULE_AUTHOR("Steven Toth"); | 1166 | MODULE_AUTHOR("Steven Toth"); |
1138 | MODULE_LICENSE("GPL"); | 1167 | MODULE_LICENSE("GPL"); |
1139 | 1168 | ||
1140 | EXPORT_SYMBOL(cx24123_attach); | ||
diff --git a/drivers/media/dvb/frontends/cx24123.h b/drivers/media/dvb/frontends/cx24123.h index cc6b411d6d20..51ae866e9fed 100644 --- a/drivers/media/dvb/frontends/cx24123.h +++ b/drivers/media/dvb/frontends/cx24123.h | |||
@@ -23,13 +23,12 @@ | |||
23 | 23 | ||
24 | #include <linux/dvb/frontend.h> | 24 | #include <linux/dvb/frontend.h> |
25 | 25 | ||
26 | struct cx24123_config | 26 | struct cx24123_config { |
27 | { | ||
28 | /* the demodulator's i2c address */ | 27 | /* the demodulator's i2c address */ |
29 | u8 demod_address; | 28 | u8 demod_address; |
30 | 29 | ||
31 | /* Need to set device param for start_dma */ | 30 | /* Need to set device param for start_dma */ |
32 | int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured); | 31 | int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured); |
33 | 32 | ||
34 | /* 0 = LNB voltage normal, 1 = LNB voltage inverted */ | 33 | /* 0 = LNB voltage normal, 1 = LNB voltage inverted */ |
35 | int lnb_polarity; | 34 | int lnb_polarity; |
@@ -39,7 +38,8 @@ struct cx24123_config | |||
39 | void (*agc_callback) (struct dvb_frontend *); | 38 | void (*agc_callback) (struct dvb_frontend *); |
40 | }; | 39 | }; |
41 | 40 | ||
42 | #if defined(CONFIG_DVB_CX24123) || (defined(CONFIG_DVB_CX24123_MODULE) && defined(MODULE)) | 41 | #if defined(CONFIG_DVB_CX24123) || (defined(CONFIG_DVB_CX24123_MODULE) \ |
42 | && defined(MODULE)) | ||
43 | extern struct dvb_frontend *cx24123_attach(const struct cx24123_config *config, | 43 | extern struct dvb_frontend *cx24123_attach(const struct cx24123_config *config, |
44 | struct i2c_adapter *i2c); | 44 | struct i2c_adapter *i2c); |
45 | extern struct i2c_adapter *cx24123_get_tuner_i2c_adapter(struct dvb_frontend *); | 45 | extern struct i2c_adapter *cx24123_get_tuner_i2c_adapter(struct dvb_frontend *); |
@@ -56,6 +56,6 @@ static struct i2c_adapter * | |||
56 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | 56 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); |
57 | return NULL; | 57 | return NULL; |
58 | } | 58 | } |
59 | #endif // CONFIG_DVB_CX24123 | 59 | #endif |
60 | 60 | ||
61 | #endif /* CX24123_H */ | 61 | #endif /* CX24123_H */ |
diff --git a/drivers/media/dvb/frontends/s5h1409.c b/drivers/media/dvb/frontends/s5h1409.c index 7500a1c53e68..cf4d8936bb83 100644 --- a/drivers/media/dvb/frontends/s5h1409.c +++ b/drivers/media/dvb/frontends/s5h1409.c | |||
@@ -30,10 +30,10 @@ | |||
30 | 30 | ||
31 | struct s5h1409_state { | 31 | struct s5h1409_state { |
32 | 32 | ||
33 | struct i2c_adapter* i2c; | 33 | struct i2c_adapter *i2c; |
34 | 34 | ||
35 | /* configuration settings */ | 35 | /* configuration settings */ |
36 | const struct s5h1409_config* config; | 36 | const struct s5h1409_config *config; |
37 | 37 | ||
38 | struct dvb_frontend frontend; | 38 | struct dvb_frontend frontend; |
39 | 39 | ||
@@ -48,6 +48,9 @@ struct s5h1409_state { | |||
48 | }; | 48 | }; |
49 | 49 | ||
50 | static int debug; | 50 | static int debug; |
51 | module_param(debug, int, 0644); | ||
52 | MODULE_PARM_DESC(debug, "Enable verbose debug messages"); | ||
53 | |||
51 | #define dprintk if (debug) printk | 54 | #define dprintk if (debug) printk |
52 | 55 | ||
53 | /* Register values to initialise the demod, this will set VSB by default */ | 56 | /* Register values to initialise the demod, this will set VSB by default */ |
@@ -299,10 +302,10 @@ static struct qam256_snr_tab { | |||
299 | }; | 302 | }; |
300 | 303 | ||
301 | /* 8 bit registers, 16 bit values */ | 304 | /* 8 bit registers, 16 bit values */ |
302 | static int s5h1409_writereg(struct s5h1409_state* state, u8 reg, u16 data) | 305 | static int s5h1409_writereg(struct s5h1409_state *state, u8 reg, u16 data) |
303 | { | 306 | { |
304 | int ret; | 307 | int ret; |
305 | u8 buf [] = { reg, data >> 8, data & 0xff }; | 308 | u8 buf[] = { reg, data >> 8, data & 0xff }; |
306 | 309 | ||
307 | struct i2c_msg msg = { .addr = state->config->demod_address, | 310 | struct i2c_msg msg = { .addr = state->config->demod_address, |
308 | .flags = 0, .buf = buf, .len = 3 }; | 311 | .flags = 0, .buf = buf, .len = 3 }; |
@@ -310,19 +313,19 @@ static int s5h1409_writereg(struct s5h1409_state* state, u8 reg, u16 data) | |||
310 | ret = i2c_transfer(state->i2c, &msg, 1); | 313 | ret = i2c_transfer(state->i2c, &msg, 1); |
311 | 314 | ||
312 | if (ret != 1) | 315 | if (ret != 1) |
313 | printk("%s: writereg error (reg == 0x%02x, val == 0x%04x, " | 316 | printk(KERN_ERR "%s: error (reg == 0x%02x, val == 0x%04x, " |
314 | "ret == %i)\n", __func__, reg, data, ret); | 317 | "ret == %i)\n", __func__, reg, data, ret); |
315 | 318 | ||
316 | return (ret != 1) ? -1 : 0; | 319 | return (ret != 1) ? -1 : 0; |
317 | } | 320 | } |
318 | 321 | ||
319 | static u16 s5h1409_readreg(struct s5h1409_state* state, u8 reg) | 322 | static u16 s5h1409_readreg(struct s5h1409_state *state, u8 reg) |
320 | { | 323 | { |
321 | int ret; | 324 | int ret; |
322 | u8 b0 [] = { reg }; | 325 | u8 b0[] = { reg }; |
323 | u8 b1 [] = { 0, 0 }; | 326 | u8 b1[] = { 0, 0 }; |
324 | 327 | ||
325 | struct i2c_msg msg [] = { | 328 | struct i2c_msg msg[] = { |
326 | { .addr = state->config->demod_address, .flags = 0, | 329 | { .addr = state->config->demod_address, .flags = 0, |
327 | .buf = b0, .len = 1 }, | 330 | .buf = b0, .len = 1 }, |
328 | { .addr = state->config->demod_address, .flags = I2C_M_RD, | 331 | { .addr = state->config->demod_address, .flags = I2C_M_RD, |
@@ -335,9 +338,9 @@ static u16 s5h1409_readreg(struct s5h1409_state* state, u8 reg) | |||
335 | return (b1[0] << 8) | b1[1]; | 338 | return (b1[0] << 8) | b1[1]; |
336 | } | 339 | } |
337 | 340 | ||
338 | static int s5h1409_softreset(struct dvb_frontend* fe) | 341 | static int s5h1409_softreset(struct dvb_frontend *fe) |
339 | { | 342 | { |
340 | struct s5h1409_state* state = fe->demodulator_priv; | 343 | struct s5h1409_state *state = fe->demodulator_priv; |
341 | 344 | ||
342 | dprintk("%s()\n", __func__); | 345 | dprintk("%s()\n", __func__); |
343 | 346 | ||
@@ -349,11 +352,11 @@ static int s5h1409_softreset(struct dvb_frontend* fe) | |||
349 | } | 352 | } |
350 | 353 | ||
351 | #define S5H1409_VSB_IF_FREQ 5380 | 354 | #define S5H1409_VSB_IF_FREQ 5380 |
352 | #define S5H1409_QAM_IF_FREQ state->config->qam_if | 355 | #define S5H1409_QAM_IF_FREQ (state->config->qam_if) |
353 | 356 | ||
354 | static int s5h1409_set_if_freq(struct dvb_frontend* fe, int KHz) | 357 | static int s5h1409_set_if_freq(struct dvb_frontend *fe, int KHz) |
355 | { | 358 | { |
356 | struct s5h1409_state* state = fe->demodulator_priv; | 359 | struct s5h1409_state *state = fe->demodulator_priv; |
357 | 360 | ||
358 | dprintk("%s(%d KHz)\n", __func__, KHz); | 361 | dprintk("%s(%d KHz)\n", __func__, KHz); |
359 | 362 | ||
@@ -376,26 +379,26 @@ static int s5h1409_set_if_freq(struct dvb_frontend* fe, int KHz) | |||
376 | return 0; | 379 | return 0; |
377 | } | 380 | } |
378 | 381 | ||
379 | static int s5h1409_set_spectralinversion(struct dvb_frontend* fe, int inverted) | 382 | static int s5h1409_set_spectralinversion(struct dvb_frontend *fe, int inverted) |
380 | { | 383 | { |
381 | struct s5h1409_state* state = fe->demodulator_priv; | 384 | struct s5h1409_state *state = fe->demodulator_priv; |
382 | 385 | ||
383 | dprintk("%s(%d)\n", __func__, inverted); | 386 | dprintk("%s(%d)\n", __func__, inverted); |
384 | 387 | ||
385 | if(inverted == 1) | 388 | if (inverted == 1) |
386 | return s5h1409_writereg(state, 0x1b, 0x1101); /* Inverted */ | 389 | return s5h1409_writereg(state, 0x1b, 0x1101); /* Inverted */ |
387 | else | 390 | else |
388 | return s5h1409_writereg(state, 0x1b, 0x0110); /* Normal */ | 391 | return s5h1409_writereg(state, 0x1b, 0x0110); /* Normal */ |
389 | } | 392 | } |
390 | 393 | ||
391 | static int s5h1409_enable_modulation(struct dvb_frontend* fe, | 394 | static int s5h1409_enable_modulation(struct dvb_frontend *fe, |
392 | fe_modulation_t m) | 395 | fe_modulation_t m) |
393 | { | 396 | { |
394 | struct s5h1409_state* state = fe->demodulator_priv; | 397 | struct s5h1409_state *state = fe->demodulator_priv; |
395 | 398 | ||
396 | dprintk("%s(0x%08x)\n", __func__, m); | 399 | dprintk("%s(0x%08x)\n", __func__, m); |
397 | 400 | ||
398 | switch(m) { | 401 | switch (m) { |
399 | case VSB_8: | 402 | case VSB_8: |
400 | dprintk("%s() VSB_8\n", __func__); | 403 | dprintk("%s() VSB_8\n", __func__); |
401 | if (state->if_freq != S5H1409_VSB_IF_FREQ) | 404 | if (state->if_freq != S5H1409_VSB_IF_FREQ) |
@@ -422,9 +425,9 @@ static int s5h1409_enable_modulation(struct dvb_frontend* fe, | |||
422 | return 0; | 425 | return 0; |
423 | } | 426 | } |
424 | 427 | ||
425 | static int s5h1409_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) | 428 | static int s5h1409_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) |
426 | { | 429 | { |
427 | struct s5h1409_state* state = fe->demodulator_priv; | 430 | struct s5h1409_state *state = fe->demodulator_priv; |
428 | 431 | ||
429 | dprintk("%s(%d)\n", __func__, enable); | 432 | dprintk("%s(%d)\n", __func__, enable); |
430 | 433 | ||
@@ -434,9 +437,9 @@ static int s5h1409_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) | |||
434 | return s5h1409_writereg(state, 0xf3, 0); | 437 | return s5h1409_writereg(state, 0xf3, 0); |
435 | } | 438 | } |
436 | 439 | ||
437 | static int s5h1409_set_gpio(struct dvb_frontend* fe, int enable) | 440 | static int s5h1409_set_gpio(struct dvb_frontend *fe, int enable) |
438 | { | 441 | { |
439 | struct s5h1409_state* state = fe->demodulator_priv; | 442 | struct s5h1409_state *state = fe->demodulator_priv; |
440 | 443 | ||
441 | dprintk("%s(%d)\n", __func__, enable); | 444 | dprintk("%s(%d)\n", __func__, enable); |
442 | 445 | ||
@@ -448,18 +451,18 @@ static int s5h1409_set_gpio(struct dvb_frontend* fe, int enable) | |||
448 | s5h1409_readreg(state, 0xe3) & 0xfeff); | 451 | s5h1409_readreg(state, 0xe3) & 0xfeff); |
449 | } | 452 | } |
450 | 453 | ||
451 | static int s5h1409_sleep(struct dvb_frontend* fe, int enable) | 454 | static int s5h1409_sleep(struct dvb_frontend *fe, int enable) |
452 | { | 455 | { |
453 | struct s5h1409_state* state = fe->demodulator_priv; | 456 | struct s5h1409_state *state = fe->demodulator_priv; |
454 | 457 | ||
455 | dprintk("%s(%d)\n", __func__, enable); | 458 | dprintk("%s(%d)\n", __func__, enable); |
456 | 459 | ||
457 | return s5h1409_writereg(state, 0xf2, enable); | 460 | return s5h1409_writereg(state, 0xf2, enable); |
458 | } | 461 | } |
459 | 462 | ||
460 | static int s5h1409_register_reset(struct dvb_frontend* fe) | 463 | static int s5h1409_register_reset(struct dvb_frontend *fe) |
461 | { | 464 | { |
462 | struct s5h1409_state* state = fe->demodulator_priv; | 465 | struct s5h1409_state *state = fe->demodulator_priv; |
463 | 466 | ||
464 | dprintk("%s()\n", __func__); | 467 | dprintk("%s()\n", __func__); |
465 | 468 | ||
@@ -483,7 +486,7 @@ static void s5h1409_set_qam_amhum_mode(struct dvb_frontend *fe) | |||
483 | reg &= 0xff; | 486 | reg &= 0xff; |
484 | 487 | ||
485 | s5h1409_writereg(state, 0x96, 0x00c); | 488 | s5h1409_writereg(state, 0x96, 0x00c); |
486 | if ((reg < 0x38) || (reg > 0x68) ) { | 489 | if ((reg < 0x38) || (reg > 0x68)) { |
487 | s5h1409_writereg(state, 0x93, 0x3332); | 490 | s5h1409_writereg(state, 0x93, 0x3332); |
488 | s5h1409_writereg(state, 0x9e, 0x2c37); | 491 | s5h1409_writereg(state, 0x9e, 0x2c37); |
489 | } else { | 492 | } else { |
@@ -514,7 +517,7 @@ static void s5h1409_set_qam_interleave_mode(struct dvb_frontend *fe) | |||
514 | 517 | ||
515 | s5h1409_writereg(state, 0x96, 0x20); | 518 | s5h1409_writereg(state, 0x96, 0x20); |
516 | s5h1409_writereg(state, 0xad, | 519 | s5h1409_writereg(state, 0xad, |
517 | ( ((reg1 & 0xf000) >> 4) | (reg2 & 0xf0ff)) ); | 520 | (((reg1 & 0xf000) >> 4) | (reg2 & 0xf0ff))); |
518 | s5h1409_writereg(state, 0xab, | 521 | s5h1409_writereg(state, 0xab, |
519 | s5h1409_readreg(state, 0xab) & 0xeffe); | 522 | s5h1409_readreg(state, 0xab) & 0xeffe); |
520 | } | 523 | } |
@@ -529,10 +532,10 @@ static void s5h1409_set_qam_interleave_mode(struct dvb_frontend *fe) | |||
529 | } | 532 | } |
530 | 533 | ||
531 | /* Talk to the demod, set the FEC, GUARD, QAM settings etc */ | 534 | /* Talk to the demod, set the FEC, GUARD, QAM settings etc */ |
532 | static int s5h1409_set_frontend (struct dvb_frontend* fe, | 535 | static int s5h1409_set_frontend(struct dvb_frontend *fe, |
533 | struct dvb_frontend_parameters *p) | 536 | struct dvb_frontend_parameters *p) |
534 | { | 537 | { |
535 | struct s5h1409_state* state = fe->demodulator_priv; | 538 | struct s5h1409_state *state = fe->demodulator_priv; |
536 | 539 | ||
537 | dprintk("%s(frequency=%d)\n", __func__, p->frequency); | 540 | dprintk("%s(frequency=%d)\n", __func__, p->frequency); |
538 | 541 | ||
@@ -546,9 +549,11 @@ static int s5h1409_set_frontend (struct dvb_frontend* fe, | |||
546 | msleep(100); | 549 | msleep(100); |
547 | 550 | ||
548 | if (fe->ops.tuner_ops.set_params) { | 551 | if (fe->ops.tuner_ops.set_params) { |
549 | if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); | 552 | if (fe->ops.i2c_gate_ctrl) |
553 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
550 | fe->ops.tuner_ops.set_params(fe, p); | 554 | fe->ops.tuner_ops.set_params(fe, p); |
551 | if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); | 555 | if (fe->ops.i2c_gate_ctrl) |
556 | fe->ops.i2c_gate_ctrl(fe, 0); | ||
552 | } | 557 | } |
553 | 558 | ||
554 | /* Optimize the demod for QAM */ | 559 | /* Optimize the demod for QAM */ |
@@ -592,17 +597,17 @@ static int s5h1409_set_mpeg_timing(struct dvb_frontend *fe, int mode) | |||
592 | 597 | ||
593 | /* Reset the demod hardware and reset all of the configuration registers | 598 | /* Reset the demod hardware and reset all of the configuration registers |
594 | to a default state. */ | 599 | to a default state. */ |
595 | static int s5h1409_init (struct dvb_frontend* fe) | 600 | static int s5h1409_init(struct dvb_frontend *fe) |
596 | { | 601 | { |
597 | int i; | 602 | int i; |
598 | 603 | ||
599 | struct s5h1409_state* state = fe->demodulator_priv; | 604 | struct s5h1409_state *state = fe->demodulator_priv; |
600 | dprintk("%s()\n", __func__); | 605 | dprintk("%s()\n", __func__); |
601 | 606 | ||
602 | s5h1409_sleep(fe, 0); | 607 | s5h1409_sleep(fe, 0); |
603 | s5h1409_register_reset(fe); | 608 | s5h1409_register_reset(fe); |
604 | 609 | ||
605 | for (i=0; i < ARRAY_SIZE(init_tab); i++) | 610 | for (i = 0; i < ARRAY_SIZE(init_tab); i++) |
606 | s5h1409_writereg(state, init_tab[i].reg, init_tab[i].data); | 611 | s5h1409_writereg(state, init_tab[i].reg, init_tab[i].data); |
607 | 612 | ||
608 | /* The datasheet says that after initialisation, VSB is default */ | 613 | /* The datasheet says that after initialisation, VSB is default */ |
@@ -627,9 +632,9 @@ static int s5h1409_init (struct dvb_frontend* fe) | |||
627 | return 0; | 632 | return 0; |
628 | } | 633 | } |
629 | 634 | ||
630 | static int s5h1409_read_status(struct dvb_frontend* fe, fe_status_t* status) | 635 | static int s5h1409_read_status(struct dvb_frontend *fe, fe_status_t *status) |
631 | { | 636 | { |
632 | struct s5h1409_state* state = fe->demodulator_priv; | 637 | struct s5h1409_state *state = fe->demodulator_priv; |
633 | u16 reg; | 638 | u16 reg; |
634 | u32 tuner_status = 0; | 639 | u32 tuner_status = 0; |
635 | 640 | ||
@@ -637,12 +642,12 @@ static int s5h1409_read_status(struct dvb_frontend* fe, fe_status_t* status) | |||
637 | 642 | ||
638 | /* Get the demodulator status */ | 643 | /* Get the demodulator status */ |
639 | reg = s5h1409_readreg(state, 0xf1); | 644 | reg = s5h1409_readreg(state, 0xf1); |
640 | if(reg & 0x1000) | 645 | if (reg & 0x1000) |
641 | *status |= FE_HAS_VITERBI; | 646 | *status |= FE_HAS_VITERBI; |
642 | if(reg & 0x8000) | 647 | if (reg & 0x8000) |
643 | *status |= FE_HAS_LOCK | FE_HAS_SYNC; | 648 | *status |= FE_HAS_LOCK | FE_HAS_SYNC; |
644 | 649 | ||
645 | switch(state->config->status_mode) { | 650 | switch (state->config->status_mode) { |
646 | case S5H1409_DEMODLOCKING: | 651 | case S5H1409_DEMODLOCKING: |
647 | if (*status & FE_HAS_VITERBI) | 652 | if (*status & FE_HAS_VITERBI) |
648 | *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL; | 653 | *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL; |
@@ -668,12 +673,12 @@ static int s5h1409_read_status(struct dvb_frontend* fe, fe_status_t* status) | |||
668 | return 0; | 673 | return 0; |
669 | } | 674 | } |
670 | 675 | ||
671 | static int s5h1409_qam256_lookup_snr(struct dvb_frontend* fe, u16* snr, u16 v) | 676 | static int s5h1409_qam256_lookup_snr(struct dvb_frontend *fe, u16 *snr, u16 v) |
672 | { | 677 | { |
673 | int i, ret = -EINVAL; | 678 | int i, ret = -EINVAL; |
674 | dprintk("%s()\n", __func__); | 679 | dprintk("%s()\n", __func__); |
675 | 680 | ||
676 | for (i=0; i < ARRAY_SIZE(qam256_snr_tab); i++) { | 681 | for (i = 0; i < ARRAY_SIZE(qam256_snr_tab); i++) { |
677 | if (v < qam256_snr_tab[i].val) { | 682 | if (v < qam256_snr_tab[i].val) { |
678 | *snr = qam256_snr_tab[i].data; | 683 | *snr = qam256_snr_tab[i].data; |
679 | ret = 0; | 684 | ret = 0; |
@@ -683,12 +688,12 @@ static int s5h1409_qam256_lookup_snr(struct dvb_frontend* fe, u16* snr, u16 v) | |||
683 | return ret; | 688 | return ret; |
684 | } | 689 | } |
685 | 690 | ||
686 | static int s5h1409_qam64_lookup_snr(struct dvb_frontend* fe, u16* snr, u16 v) | 691 | static int s5h1409_qam64_lookup_snr(struct dvb_frontend *fe, u16 *snr, u16 v) |
687 | { | 692 | { |
688 | int i, ret = -EINVAL; | 693 | int i, ret = -EINVAL; |
689 | dprintk("%s()\n", __func__); | 694 | dprintk("%s()\n", __func__); |
690 | 695 | ||
691 | for (i=0; i < ARRAY_SIZE(qam64_snr_tab); i++) { | 696 | for (i = 0; i < ARRAY_SIZE(qam64_snr_tab); i++) { |
692 | if (v < qam64_snr_tab[i].val) { | 697 | if (v < qam64_snr_tab[i].val) { |
693 | *snr = qam64_snr_tab[i].data; | 698 | *snr = qam64_snr_tab[i].data; |
694 | ret = 0; | 699 | ret = 0; |
@@ -698,12 +703,12 @@ static int s5h1409_qam64_lookup_snr(struct dvb_frontend* fe, u16* snr, u16 v) | |||
698 | return ret; | 703 | return ret; |
699 | } | 704 | } |
700 | 705 | ||
701 | static int s5h1409_vsb_lookup_snr(struct dvb_frontend* fe, u16* snr, u16 v) | 706 | static int s5h1409_vsb_lookup_snr(struct dvb_frontend *fe, u16 *snr, u16 v) |
702 | { | 707 | { |
703 | int i, ret = -EINVAL; | 708 | int i, ret = -EINVAL; |
704 | dprintk("%s()\n", __func__); | 709 | dprintk("%s()\n", __func__); |
705 | 710 | ||
706 | for (i=0; i < ARRAY_SIZE(vsb_snr_tab); i++) { | 711 | for (i = 0; i < ARRAY_SIZE(vsb_snr_tab); i++) { |
707 | if (v > vsb_snr_tab[i].val) { | 712 | if (v > vsb_snr_tab[i].val) { |
708 | *snr = vsb_snr_tab[i].data; | 713 | *snr = vsb_snr_tab[i].data; |
709 | ret = 0; | 714 | ret = 0; |
@@ -714,13 +719,13 @@ static int s5h1409_vsb_lookup_snr(struct dvb_frontend* fe, u16* snr, u16 v) | |||
714 | return ret; | 719 | return ret; |
715 | } | 720 | } |
716 | 721 | ||
717 | static int s5h1409_read_snr(struct dvb_frontend* fe, u16* snr) | 722 | static int s5h1409_read_snr(struct dvb_frontend *fe, u16 *snr) |
718 | { | 723 | { |
719 | struct s5h1409_state* state = fe->demodulator_priv; | 724 | struct s5h1409_state *state = fe->demodulator_priv; |
720 | u16 reg; | 725 | u16 reg; |
721 | dprintk("%s()\n", __func__); | 726 | dprintk("%s()\n", __func__); |
722 | 727 | ||
723 | switch(state->current_modulation) { | 728 | switch (state->current_modulation) { |
724 | case QAM_64: | 729 | case QAM_64: |
725 | reg = s5h1409_readreg(state, 0xf0) & 0xff; | 730 | reg = s5h1409_readreg(state, 0xf0) & 0xff; |
726 | return s5h1409_qam64_lookup_snr(fe, snr, reg); | 731 | return s5h1409_qam64_lookup_snr(fe, snr, reg); |
@@ -737,30 +742,30 @@ static int s5h1409_read_snr(struct dvb_frontend* fe, u16* snr) | |||
737 | return -EINVAL; | 742 | return -EINVAL; |
738 | } | 743 | } |
739 | 744 | ||
740 | static int s5h1409_read_signal_strength(struct dvb_frontend* fe, | 745 | static int s5h1409_read_signal_strength(struct dvb_frontend *fe, |
741 | u16* signal_strength) | 746 | u16 *signal_strength) |
742 | { | 747 | { |
743 | return s5h1409_read_snr(fe, signal_strength); | 748 | return s5h1409_read_snr(fe, signal_strength); |
744 | } | 749 | } |
745 | 750 | ||
746 | static int s5h1409_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) | 751 | static int s5h1409_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) |
747 | { | 752 | { |
748 | struct s5h1409_state* state = fe->demodulator_priv; | 753 | struct s5h1409_state *state = fe->demodulator_priv; |
749 | 754 | ||
750 | *ucblocks = s5h1409_readreg(state, 0xb5); | 755 | *ucblocks = s5h1409_readreg(state, 0xb5); |
751 | 756 | ||
752 | return 0; | 757 | return 0; |
753 | } | 758 | } |
754 | 759 | ||
755 | static int s5h1409_read_ber(struct dvb_frontend* fe, u32* ber) | 760 | static int s5h1409_read_ber(struct dvb_frontend *fe, u32 *ber) |
756 | { | 761 | { |
757 | return s5h1409_read_ucblocks(fe, ber); | 762 | return s5h1409_read_ucblocks(fe, ber); |
758 | } | 763 | } |
759 | 764 | ||
760 | static int s5h1409_get_frontend(struct dvb_frontend* fe, | 765 | static int s5h1409_get_frontend(struct dvb_frontend *fe, |
761 | struct dvb_frontend_parameters *p) | 766 | struct dvb_frontend_parameters *p) |
762 | { | 767 | { |
763 | struct s5h1409_state* state = fe->demodulator_priv; | 768 | struct s5h1409_state *state = fe->demodulator_priv; |
764 | 769 | ||
765 | p->frequency = state->current_frequency; | 770 | p->frequency = state->current_frequency; |
766 | p->u.vsb.modulation = state->current_modulation; | 771 | p->u.vsb.modulation = state->current_modulation; |
@@ -768,25 +773,25 @@ static int s5h1409_get_frontend(struct dvb_frontend* fe, | |||
768 | return 0; | 773 | return 0; |
769 | } | 774 | } |
770 | 775 | ||
771 | static int s5h1409_get_tune_settings(struct dvb_frontend* fe, | 776 | static int s5h1409_get_tune_settings(struct dvb_frontend *fe, |
772 | struct dvb_frontend_tune_settings *tune) | 777 | struct dvb_frontend_tune_settings *tune) |
773 | { | 778 | { |
774 | tune->min_delay_ms = 1000; | 779 | tune->min_delay_ms = 1000; |
775 | return 0; | 780 | return 0; |
776 | } | 781 | } |
777 | 782 | ||
778 | static void s5h1409_release(struct dvb_frontend* fe) | 783 | static void s5h1409_release(struct dvb_frontend *fe) |
779 | { | 784 | { |
780 | struct s5h1409_state* state = fe->demodulator_priv; | 785 | struct s5h1409_state *state = fe->demodulator_priv; |
781 | kfree(state); | 786 | kfree(state); |
782 | } | 787 | } |
783 | 788 | ||
784 | static struct dvb_frontend_ops s5h1409_ops; | 789 | static struct dvb_frontend_ops s5h1409_ops; |
785 | 790 | ||
786 | struct dvb_frontend* s5h1409_attach(const struct s5h1409_config* config, | 791 | struct dvb_frontend *s5h1409_attach(const struct s5h1409_config *config, |
787 | struct i2c_adapter* i2c) | 792 | struct i2c_adapter *i2c) |
788 | { | 793 | { |
789 | struct s5h1409_state* state = NULL; | 794 | struct s5h1409_state *state = NULL; |
790 | u16 reg; | 795 | u16 reg; |
791 | 796 | ||
792 | /* allocate memory for the internal state */ | 797 | /* allocate memory for the internal state */ |
@@ -825,6 +830,7 @@ error: | |||
825 | kfree(state); | 830 | kfree(state); |
826 | return NULL; | 831 | return NULL; |
827 | } | 832 | } |
833 | EXPORT_SYMBOL(s5h1409_attach); | ||
828 | 834 | ||
829 | static struct dvb_frontend_ops s5h1409_ops = { | 835 | static struct dvb_frontend_ops s5h1409_ops = { |
830 | 836 | ||
@@ -850,14 +856,10 @@ static struct dvb_frontend_ops s5h1409_ops = { | |||
850 | .release = s5h1409_release, | 856 | .release = s5h1409_release, |
851 | }; | 857 | }; |
852 | 858 | ||
853 | module_param(debug, int, 0644); | ||
854 | MODULE_PARM_DESC(debug, "Enable verbose debug messages"); | ||
855 | |||
856 | MODULE_DESCRIPTION("Samsung S5H1409 QAM-B/ATSC Demodulator driver"); | 859 | MODULE_DESCRIPTION("Samsung S5H1409 QAM-B/ATSC Demodulator driver"); |
857 | MODULE_AUTHOR("Steven Toth"); | 860 | MODULE_AUTHOR("Steven Toth"); |
858 | MODULE_LICENSE("GPL"); | 861 | MODULE_LICENSE("GPL"); |
859 | 862 | ||
860 | EXPORT_SYMBOL(s5h1409_attach); | ||
861 | 863 | ||
862 | /* | 864 | /* |
863 | * Local variables: | 865 | * Local variables: |
diff --git a/drivers/media/dvb/frontends/s5h1409.h b/drivers/media/dvb/frontends/s5h1409.h index d1a1d2eb8e11..070d9743e330 100644 --- a/drivers/media/dvb/frontends/s5h1409.h +++ b/drivers/media/dvb/frontends/s5h1409.h | |||
@@ -24,8 +24,7 @@ | |||
24 | 24 | ||
25 | #include <linux/dvb/frontend.h> | 25 | #include <linux/dvb/frontend.h> |
26 | 26 | ||
27 | struct s5h1409_config | 27 | struct s5h1409_config { |
28 | { | ||
29 | /* the demodulator's i2c address */ | 28 | /* the demodulator's i2c address */ |
30 | u8 demod_address; | 29 | u8 demod_address; |
31 | 30 | ||
@@ -60,12 +59,14 @@ struct s5h1409_config | |||
60 | u16 mpeg_timing; | 59 | u16 mpeg_timing; |
61 | }; | 60 | }; |
62 | 61 | ||
63 | #if defined(CONFIG_DVB_S5H1409) || (defined(CONFIG_DVB_S5H1409_MODULE) && defined(MODULE)) | 62 | #if defined(CONFIG_DVB_S5H1409) || (defined(CONFIG_DVB_S5H1409_MODULE) \ |
64 | extern struct dvb_frontend* s5h1409_attach(const struct s5h1409_config* config, | 63 | && defined(MODULE)) |
65 | struct i2c_adapter* i2c); | 64 | extern struct dvb_frontend *s5h1409_attach(const struct s5h1409_config *config, |
65 | struct i2c_adapter *i2c); | ||
66 | #else | 66 | #else |
67 | static inline struct dvb_frontend* s5h1409_attach(const struct s5h1409_config* config, | 67 | static inline struct dvb_frontend *s5h1409_attach( |
68 | struct i2c_adapter* i2c) | 68 | const struct s5h1409_config *config, |
69 | struct i2c_adapter *i2c) | ||
69 | { | 70 | { |
70 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | 71 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); |
71 | return NULL; | 72 | return NULL; |
diff --git a/drivers/media/dvb/frontends/s5h1411.c b/drivers/media/dvb/frontends/s5h1411.c index 2da1a3763de9..2febfb5a846b 100644 --- a/drivers/media/dvb/frontends/s5h1411.c +++ b/drivers/media/dvb/frontends/s5h1411.c | |||
@@ -343,7 +343,7 @@ static int s5h1411_writereg(struct s5h1411_state *state, | |||
343 | u8 addr, u8 reg, u16 data) | 343 | u8 addr, u8 reg, u16 data) |
344 | { | 344 | { |
345 | int ret; | 345 | int ret; |
346 | u8 buf [] = { reg, data >> 8, data & 0xff }; | 346 | u8 buf[] = { reg, data >> 8, data & 0xff }; |
347 | 347 | ||
348 | struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = buf, .len = 3 }; | 348 | struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = buf, .len = 3 }; |
349 | 349 | ||
@@ -359,10 +359,10 @@ static int s5h1411_writereg(struct s5h1411_state *state, | |||
359 | static u16 s5h1411_readreg(struct s5h1411_state *state, u8 addr, u8 reg) | 359 | static u16 s5h1411_readreg(struct s5h1411_state *state, u8 addr, u8 reg) |
360 | { | 360 | { |
361 | int ret; | 361 | int ret; |
362 | u8 b0 [] = { reg }; | 362 | u8 b0[] = { reg }; |
363 | u8 b1 [] = { 0, 0 }; | 363 | u8 b1[] = { 0, 0 }; |
364 | 364 | ||
365 | struct i2c_msg msg [] = { | 365 | struct i2c_msg msg[] = { |
366 | { .addr = addr, .flags = 0, .buf = b0, .len = 1 }, | 366 | { .addr = addr, .flags = 0, .buf = b0, .len = 1 }, |
367 | { .addr = addr, .flags = I2C_M_RD, .buf = b1, .len = 2 } }; | 367 | { .addr = addr, .flags = I2C_M_RD, .buf = b1, .len = 2 } }; |
368 | 368 | ||
diff --git a/drivers/media/dvb/frontends/tda10048.c b/drivers/media/dvb/frontends/tda10048.c index 04e7f1cc1403..2a8bbcd44cd0 100644 --- a/drivers/media/dvb/frontends/tda10048.c +++ b/drivers/media/dvb/frontends/tda10048.c | |||
@@ -195,7 +195,7 @@ static struct init_tab { | |||
195 | static int tda10048_writereg(struct tda10048_state *state, u8 reg, u8 data) | 195 | static int tda10048_writereg(struct tda10048_state *state, u8 reg, u8 data) |
196 | { | 196 | { |
197 | int ret; | 197 | int ret; |
198 | u8 buf [] = { reg, data }; | 198 | u8 buf[] = { reg, data }; |
199 | struct i2c_msg msg = { | 199 | struct i2c_msg msg = { |
200 | .addr = state->config->demod_address, | 200 | .addr = state->config->demod_address, |
201 | .flags = 0, .buf = buf, .len = 2 }; | 201 | .flags = 0, .buf = buf, .len = 2 }; |
@@ -213,9 +213,9 @@ static int tda10048_writereg(struct tda10048_state *state, u8 reg, u8 data) | |||
213 | static u8 tda10048_readreg(struct tda10048_state *state, u8 reg) | 213 | static u8 tda10048_readreg(struct tda10048_state *state, u8 reg) |
214 | { | 214 | { |
215 | int ret; | 215 | int ret; |
216 | u8 b0 [] = { reg }; | 216 | u8 b0[] = { reg }; |
217 | u8 b1 [] = { 0 }; | 217 | u8 b1[] = { 0 }; |
218 | struct i2c_msg msg [] = { | 218 | struct i2c_msg msg[] = { |
219 | { .addr = state->config->demod_address, | 219 | { .addr = state->config->demod_address, |
220 | .flags = 0, .buf = b0, .len = 1 }, | 220 | .flags = 0, .buf = b0, .len = 1 }, |
221 | { .addr = state->config->demod_address, | 221 | { .addr = state->config->demod_address, |
@@ -393,43 +393,89 @@ static int tda10048_get_tps(struct tda10048_state *state, | |||
393 | 393 | ||
394 | val = tda10048_readreg(state, TDA10048_OUT_CONF2); | 394 | val = tda10048_readreg(state, TDA10048_OUT_CONF2); |
395 | switch ((val & 0x60) >> 5) { | 395 | switch ((val & 0x60) >> 5) { |
396 | case 0: p->constellation = QPSK; break; | 396 | case 0: |
397 | case 1: p->constellation = QAM_16; break; | 397 | p->constellation = QPSK; |
398 | case 2: p->constellation = QAM_64; break; | 398 | break; |
399 | case 1: | ||
400 | p->constellation = QAM_16; | ||
401 | break; | ||
402 | case 2: | ||
403 | p->constellation = QAM_64; | ||
404 | break; | ||
399 | } | 405 | } |
400 | switch ((val & 0x18) >> 3) { | 406 | switch ((val & 0x18) >> 3) { |
401 | case 0: p->hierarchy_information = HIERARCHY_NONE; break; | 407 | case 0: |
402 | case 1: p->hierarchy_information = HIERARCHY_1; break; | 408 | p->hierarchy_information = HIERARCHY_NONE; |
403 | case 2: p->hierarchy_information = HIERARCHY_2; break; | 409 | break; |
404 | case 3: p->hierarchy_information = HIERARCHY_4; break; | 410 | case 1: |
411 | p->hierarchy_information = HIERARCHY_1; | ||
412 | break; | ||
413 | case 2: | ||
414 | p->hierarchy_information = HIERARCHY_2; | ||
415 | break; | ||
416 | case 3: | ||
417 | p->hierarchy_information = HIERARCHY_4; | ||
418 | break; | ||
405 | } | 419 | } |
406 | switch (val & 0x07) { | 420 | switch (val & 0x07) { |
407 | case 0: p->code_rate_HP = FEC_1_2; break; | 421 | case 0: |
408 | case 1: p->code_rate_HP = FEC_2_3; break; | 422 | p->code_rate_HP = FEC_1_2; |
409 | case 2: p->code_rate_HP = FEC_3_4; break; | 423 | break; |
410 | case 3: p->code_rate_HP = FEC_5_6; break; | 424 | case 1: |
411 | case 4: p->code_rate_HP = FEC_7_8; break; | 425 | p->code_rate_HP = FEC_2_3; |
426 | break; | ||
427 | case 2: | ||
428 | p->code_rate_HP = FEC_3_4; | ||
429 | break; | ||
430 | case 3: | ||
431 | p->code_rate_HP = FEC_5_6; | ||
432 | break; | ||
433 | case 4: | ||
434 | p->code_rate_HP = FEC_7_8; | ||
435 | break; | ||
412 | } | 436 | } |
413 | 437 | ||
414 | val = tda10048_readreg(state, TDA10048_OUT_CONF3); | 438 | val = tda10048_readreg(state, TDA10048_OUT_CONF3); |
415 | switch (val & 0x07) { | 439 | switch (val & 0x07) { |
416 | case 0: p->code_rate_LP = FEC_1_2; break; | 440 | case 0: |
417 | case 1: p->code_rate_LP = FEC_2_3; break; | 441 | p->code_rate_LP = FEC_1_2; |
418 | case 2: p->code_rate_LP = FEC_3_4; break; | 442 | break; |
419 | case 3: p->code_rate_LP = FEC_5_6; break; | 443 | case 1: |
420 | case 4: p->code_rate_LP = FEC_7_8; break; | 444 | p->code_rate_LP = FEC_2_3; |
445 | break; | ||
446 | case 2: | ||
447 | p->code_rate_LP = FEC_3_4; | ||
448 | break; | ||
449 | case 3: | ||
450 | p->code_rate_LP = FEC_5_6; | ||
451 | break; | ||
452 | case 4: | ||
453 | p->code_rate_LP = FEC_7_8; | ||
454 | break; | ||
421 | } | 455 | } |
422 | 456 | ||
423 | val = tda10048_readreg(state, TDA10048_OUT_CONF1); | 457 | val = tda10048_readreg(state, TDA10048_OUT_CONF1); |
424 | switch ((val & 0x0c) >> 2) { | 458 | switch ((val & 0x0c) >> 2) { |
425 | case 0: p->guard_interval = GUARD_INTERVAL_1_32; break; | 459 | case 0: |
426 | case 1: p->guard_interval = GUARD_INTERVAL_1_16; break; | 460 | p->guard_interval = GUARD_INTERVAL_1_32; |
427 | case 2: p->guard_interval = GUARD_INTERVAL_1_8; break; | 461 | break; |
428 | case 3: p->guard_interval = GUARD_INTERVAL_1_4; break; | 462 | case 1: |
463 | p->guard_interval = GUARD_INTERVAL_1_16; | ||
464 | break; | ||
465 | case 2: | ||
466 | p->guard_interval = GUARD_INTERVAL_1_8; | ||
467 | break; | ||
468 | case 3: | ||
469 | p->guard_interval = GUARD_INTERVAL_1_4; | ||
470 | break; | ||
429 | } | 471 | } |
430 | switch (val & 0x02) { | 472 | switch (val & 0x02) { |
431 | case 0: p->transmission_mode = TRANSMISSION_MODE_2K; break; | 473 | case 0: |
432 | case 1: p->transmission_mode = TRANSMISSION_MODE_8K; break; | 474 | p->transmission_mode = TRANSMISSION_MODE_2K; |
475 | break; | ||
476 | case 1: | ||
477 | p->transmission_mode = TRANSMISSION_MODE_8K; | ||
478 | break; | ||
433 | } | 479 | } |
434 | 480 | ||
435 | return 0; | 481 | return 0; |
diff --git a/drivers/media/dvb/frontends/z0194a.h b/drivers/media/dvb/frontends/z0194a.h index d2876d2e1769..07f3fc0998f6 100644 --- a/drivers/media/dvb/frontends/z0194a.h +++ b/drivers/media/dvb/frontends/z0194a.h | |||
@@ -12,7 +12,7 @@ | |||
12 | #ifndef Z0194A | 12 | #ifndef Z0194A |
13 | #define Z0194A | 13 | #define Z0194A |
14 | 14 | ||
15 | static int sharp_z0194a__set_symbol_rate(struct dvb_frontend *fe, | 15 | static int sharp_z0194a_set_symbol_rate(struct dvb_frontend *fe, |
16 | u32 srate, u32 ratio) | 16 | u32 srate, u32 ratio) |
17 | { | 17 | { |
18 | u8 aclk = 0; | 18 | u8 aclk = 0; |
@@ -40,7 +40,7 @@ static int sharp_z0194a__set_symbol_rate(struct dvb_frontend *fe, | |||
40 | return 0; | 40 | return 0; |
41 | } | 41 | } |
42 | 42 | ||
43 | static u8 sharp_z0194a__inittab[] = { | 43 | static u8 sharp_z0194a_inittab[] = { |
44 | 0x01, 0x15, | 44 | 0x01, 0x15, |
45 | 0x02, 0x00, | 45 | 0x02, 0x00, |
46 | 0x03, 0x00, | 46 | 0x03, 0x00, |
@@ -82,16 +82,4 @@ static u8 sharp_z0194a__inittab[] = { | |||
82 | 0xff, 0xff | 82 | 0xff, 0xff |
83 | }; | 83 | }; |
84 | 84 | ||
85 | static struct stv0299_config sharp_z0194a_config = { | ||
86 | .demod_address = 0x68, | ||
87 | .inittab = sharp_z0194a__inittab, | ||
88 | .mclk = 88000000UL, | ||
89 | .invert = 1, | ||
90 | .skip_reinit = 0, | ||
91 | .lock_output = STV0299_LOCKOUTPUT_1, | ||
92 | .volt13_op0_op1 = STV0299_VOLT13_OP1, | ||
93 | .min_delay_ms = 100, | ||
94 | .set_symbol_rate = sharp_z0194a__set_symbol_rate, | ||
95 | }; | ||
96 | |||
97 | #endif | 85 | #endif |
diff --git a/drivers/media/dvb/siano/sms-cards.c b/drivers/media/dvb/siano/sms-cards.c index 9da260fe3fd1..6f9b77360440 100644 --- a/drivers/media/dvb/siano/sms-cards.c +++ b/drivers/media/dvb/siano/sms-cards.c | |||
@@ -42,6 +42,10 @@ struct usb_device_id smsusb_id_table[] = { | |||
42 | .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, | 42 | .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, |
43 | { USB_DEVICE(0x2040, 0x5510), | 43 | { USB_DEVICE(0x2040, 0x5510), |
44 | .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, | 44 | .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, |
45 | { USB_DEVICE(0x2040, 0x5520), | ||
46 | .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, | ||
47 | { USB_DEVICE(0x2040, 0x5530), | ||
48 | .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, | ||
45 | { USB_DEVICE(0x2040, 0x5580), | 49 | { USB_DEVICE(0x2040, 0x5580), |
46 | .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, | 50 | .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, |
47 | { USB_DEVICE(0x2040, 0x5590), | 51 | { USB_DEVICE(0x2040, 0x5590), |
diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig index e51d707e58d3..04cd7c04bdde 100644 --- a/drivers/media/radio/Kconfig +++ b/drivers/media/radio/Kconfig | |||
@@ -359,7 +359,7 @@ config USB_SI470X | |||
359 | computer's USB port. | 359 | computer's USB port. |
360 | 360 | ||
361 | To compile this driver as a module, choose M here: the | 361 | To compile this driver as a module, choose M here: the |
362 | module will be called radio-silabs. | 362 | module will be called radio-si470x. |
363 | 363 | ||
364 | config USB_MR800 | 364 | config USB_MR800 |
365 | tristate "AverMedia MR 800 USB FM radio support" | 365 | tristate "AverMedia MR 800 USB FM radio support" |
diff --git a/drivers/media/radio/radio-si470x.c b/drivers/media/radio/radio-si470x.c index f6cedcd3ab97..5920cd306975 100644 --- a/drivers/media/radio/radio-si470x.c +++ b/drivers/media/radio/radio-si470x.c | |||
@@ -104,6 +104,7 @@ | |||
104 | * - hardware frequency seek support | 104 | * - hardware frequency seek support |
105 | * - afc indication | 105 | * - afc indication |
106 | * - more safety checks, let si470x_get_freq return errno | 106 | * - more safety checks, let si470x_get_freq return errno |
107 | * - vidioc behavior corrected according to v4l2 spec | ||
107 | * | 108 | * |
108 | * ToDo: | 109 | * ToDo: |
109 | * - add firmware download/update support | 110 | * - add firmware download/update support |
@@ -141,9 +142,9 @@ | |||
141 | /* USB Device ID List */ | 142 | /* USB Device ID List */ |
142 | static struct usb_device_id si470x_usb_driver_id_table[] = { | 143 | static struct usb_device_id si470x_usb_driver_id_table[] = { |
143 | /* Silicon Labs USB FM Radio Reference Design */ | 144 | /* Silicon Labs USB FM Radio Reference Design */ |
144 | { USB_DEVICE_AND_INTERFACE_INFO(0x10c4, 0x818a, USB_CLASS_HID, 0, 0) }, | 145 | { USB_DEVICE_AND_INTERFACE_INFO(0x10c4, 0x818a, USB_CLASS_HID, 0, 0) }, |
145 | /* ADS/Tech FM Radio Receiver (formerly Instant FM Music) */ | 146 | /* ADS/Tech FM Radio Receiver (formerly Instant FM Music) */ |
146 | { USB_DEVICE_AND_INTERFACE_INFO(0x06e1, 0xa155, USB_CLASS_HID, 0, 0) }, | 147 | { USB_DEVICE_AND_INTERFACE_INFO(0x06e1, 0xa155, USB_CLASS_HID, 0, 0) }, |
147 | /* Terminating entry */ | 148 | /* Terminating entry */ |
148 | { } | 149 | { } |
149 | }; | 150 | }; |
@@ -157,7 +158,7 @@ MODULE_DEVICE_TABLE(usb, si470x_usb_driver_id_table); | |||
157 | 158 | ||
158 | /* Radio Nr */ | 159 | /* Radio Nr */ |
159 | static int radio_nr = -1; | 160 | static int radio_nr = -1; |
160 | module_param(radio_nr, int, 0); | 161 | module_param(radio_nr, int, 0444); |
161 | MODULE_PARM_DESC(radio_nr, "Radio Nr"); | 162 | MODULE_PARM_DESC(radio_nr, "Radio Nr"); |
162 | 163 | ||
163 | /* Spacing (kHz) */ | 164 | /* Spacing (kHz) */ |
@@ -165,42 +166,42 @@ MODULE_PARM_DESC(radio_nr, "Radio Nr"); | |||
165 | /* 1: 100 kHz (Europe, Japan) */ | 166 | /* 1: 100 kHz (Europe, Japan) */ |
166 | /* 2: 50 kHz */ | 167 | /* 2: 50 kHz */ |
167 | static unsigned short space = 2; | 168 | static unsigned short space = 2; |
168 | module_param(space, ushort, 0); | 169 | module_param(space, ushort, 0444); |
169 | MODULE_PARM_DESC(radio_nr, "Spacing: 0=200kHz 1=100kHz *2=50kHz*"); | 170 | MODULE_PARM_DESC(space, "Spacing: 0=200kHz 1=100kHz *2=50kHz*"); |
170 | 171 | ||
171 | /* Bottom of Band (MHz) */ | 172 | /* Bottom of Band (MHz) */ |
172 | /* 0: 87.5 - 108 MHz (USA, Europe)*/ | 173 | /* 0: 87.5 - 108 MHz (USA, Europe)*/ |
173 | /* 1: 76 - 108 MHz (Japan wide band) */ | 174 | /* 1: 76 - 108 MHz (Japan wide band) */ |
174 | /* 2: 76 - 90 MHz (Japan) */ | 175 | /* 2: 76 - 90 MHz (Japan) */ |
175 | static unsigned short band = 1; | 176 | static unsigned short band = 1; |
176 | module_param(band, ushort, 0); | 177 | module_param(band, ushort, 0444); |
177 | MODULE_PARM_DESC(radio_nr, "Band: 0=87.5..108MHz *1=76..108MHz* 2=76..90MHz"); | 178 | MODULE_PARM_DESC(band, "Band: 0=87.5..108MHz *1=76..108MHz* 2=76..90MHz"); |
178 | 179 | ||
179 | /* De-emphasis */ | 180 | /* De-emphasis */ |
180 | /* 0: 75 us (USA) */ | 181 | /* 0: 75 us (USA) */ |
181 | /* 1: 50 us (Europe, Australia, Japan) */ | 182 | /* 1: 50 us (Europe, Australia, Japan) */ |
182 | static unsigned short de = 1; | 183 | static unsigned short de = 1; |
183 | module_param(de, ushort, 0); | 184 | module_param(de, ushort, 0444); |
184 | MODULE_PARM_DESC(radio_nr, "De-emphasis: 0=75us *1=50us*"); | 185 | MODULE_PARM_DESC(de, "De-emphasis: 0=75us *1=50us*"); |
185 | 186 | ||
186 | /* USB timeout */ | 187 | /* USB timeout */ |
187 | static unsigned int usb_timeout = 500; | 188 | static unsigned int usb_timeout = 500; |
188 | module_param(usb_timeout, uint, 0); | 189 | module_param(usb_timeout, uint, 0644); |
189 | MODULE_PARM_DESC(usb_timeout, "USB timeout (ms): *500*"); | 190 | MODULE_PARM_DESC(usb_timeout, "USB timeout (ms): *500*"); |
190 | 191 | ||
191 | /* Tune timeout */ | 192 | /* Tune timeout */ |
192 | static unsigned int tune_timeout = 3000; | 193 | static unsigned int tune_timeout = 3000; |
193 | module_param(tune_timeout, uint, 0); | 194 | module_param(tune_timeout, uint, 0644); |
194 | MODULE_PARM_DESC(tune_timeout, "Tune timeout: *3000*"); | 195 | MODULE_PARM_DESC(tune_timeout, "Tune timeout: *3000*"); |
195 | 196 | ||
196 | /* Seek timeout */ | 197 | /* Seek timeout */ |
197 | static unsigned int seek_timeout = 5000; | 198 | static unsigned int seek_timeout = 5000; |
198 | module_param(seek_timeout, uint, 0); | 199 | module_param(seek_timeout, uint, 0644); |
199 | MODULE_PARM_DESC(seek_timeout, "Seek timeout: *5000*"); | 200 | MODULE_PARM_DESC(seek_timeout, "Seek timeout: *5000*"); |
200 | 201 | ||
201 | /* RDS buffer blocks */ | 202 | /* RDS buffer blocks */ |
202 | static unsigned int rds_buf = 100; | 203 | static unsigned int rds_buf = 100; |
203 | module_param(rds_buf, uint, 0); | 204 | module_param(rds_buf, uint, 0444); |
204 | MODULE_PARM_DESC(rds_buf, "RDS buffer entries: *100*"); | 205 | MODULE_PARM_DESC(rds_buf, "RDS buffer entries: *100*"); |
205 | 206 | ||
206 | /* RDS maximum block errors */ | 207 | /* RDS maximum block errors */ |
@@ -209,7 +210,7 @@ static unsigned short max_rds_errors = 1; | |||
209 | /* 1 means 1-2 errors requiring correction (used by original USBRadio.exe) */ | 210 | /* 1 means 1-2 errors requiring correction (used by original USBRadio.exe) */ |
210 | /* 2 means 3-5 errors requiring correction */ | 211 | /* 2 means 3-5 errors requiring correction */ |
211 | /* 3 means 6+ errors or errors in checkword, correction not possible */ | 212 | /* 3 means 6+ errors or errors in checkword, correction not possible */ |
212 | module_param(max_rds_errors, ushort, 0); | 213 | module_param(max_rds_errors, ushort, 0644); |
213 | MODULE_PARM_DESC(max_rds_errors, "RDS maximum block errors: *1*"); | 214 | MODULE_PARM_DESC(max_rds_errors, "RDS maximum block errors: *1*"); |
214 | 215 | ||
215 | /* RDS poll frequency */ | 216 | /* RDS poll frequency */ |
@@ -218,7 +219,7 @@ static unsigned int rds_poll_time = 40; | |||
218 | /* 50 is used by radio-cadet */ | 219 | /* 50 is used by radio-cadet */ |
219 | /* 75 should be okay */ | 220 | /* 75 should be okay */ |
220 | /* 80 is the usual RDS receive interval */ | 221 | /* 80 is the usual RDS receive interval */ |
221 | module_param(rds_poll_time, uint, 0); | 222 | module_param(rds_poll_time, uint, 0644); |
222 | MODULE_PARM_DESC(rds_poll_time, "RDS poll time (ms): *40*"); | 223 | MODULE_PARM_DESC(rds_poll_time, "RDS poll time (ms): *40*"); |
223 | 224 | ||
224 | 225 | ||
@@ -667,23 +668,29 @@ static int si470x_get_freq(struct si470x_device *radio, unsigned int *freq) | |||
667 | int retval; | 668 | int retval; |
668 | 669 | ||
669 | /* Spacing (kHz) */ | 670 | /* Spacing (kHz) */ |
670 | switch (space) { | 671 | switch ((radio->registers[SYSCONFIG2] & SYSCONFIG2_SPACE) >> 4) { |
671 | /* 0: 200 kHz (USA, Australia) */ | 672 | /* 0: 200 kHz (USA, Australia) */ |
672 | case 0 : spacing = 0.200 * FREQ_MUL; break; | 673 | case 0: |
674 | spacing = 0.200 * FREQ_MUL; break; | ||
673 | /* 1: 100 kHz (Europe, Japan) */ | 675 | /* 1: 100 kHz (Europe, Japan) */ |
674 | case 1 : spacing = 0.100 * FREQ_MUL; break; | 676 | case 1: |
677 | spacing = 0.100 * FREQ_MUL; break; | ||
675 | /* 2: 50 kHz */ | 678 | /* 2: 50 kHz */ |
676 | default: spacing = 0.050 * FREQ_MUL; break; | 679 | default: |
680 | spacing = 0.050 * FREQ_MUL; break; | ||
677 | }; | 681 | }; |
678 | 682 | ||
679 | /* Bottom of Band (MHz) */ | 683 | /* Bottom of Band (MHz) */ |
680 | switch (band) { | 684 | switch ((radio->registers[SYSCONFIG2] & SYSCONFIG2_BAND) >> 6) { |
681 | /* 0: 87.5 - 108 MHz (USA, Europe) */ | 685 | /* 0: 87.5 - 108 MHz (USA, Europe) */ |
682 | case 0 : band_bottom = 87.5 * FREQ_MUL; break; | 686 | case 0: |
687 | band_bottom = 87.5 * FREQ_MUL; break; | ||
683 | /* 1: 76 - 108 MHz (Japan wide band) */ | 688 | /* 1: 76 - 108 MHz (Japan wide band) */ |
684 | default: band_bottom = 76 * FREQ_MUL; break; | 689 | default: |
690 | band_bottom = 76 * FREQ_MUL; break; | ||
685 | /* 2: 76 - 90 MHz (Japan) */ | 691 | /* 2: 76 - 90 MHz (Japan) */ |
686 | case 2 : band_bottom = 76 * FREQ_MUL; break; | 692 | case 2: |
693 | band_bottom = 76 * FREQ_MUL; break; | ||
687 | }; | 694 | }; |
688 | 695 | ||
689 | /* read channel */ | 696 | /* read channel */ |
@@ -706,23 +713,29 @@ static int si470x_set_freq(struct si470x_device *radio, unsigned int freq) | |||
706 | unsigned short chan; | 713 | unsigned short chan; |
707 | 714 | ||
708 | /* Spacing (kHz) */ | 715 | /* Spacing (kHz) */ |
709 | switch (space) { | 716 | switch ((radio->registers[SYSCONFIG2] & SYSCONFIG2_SPACE) >> 4) { |
710 | /* 0: 200 kHz (USA, Australia) */ | 717 | /* 0: 200 kHz (USA, Australia) */ |
711 | case 0 : spacing = 0.200 * FREQ_MUL; break; | 718 | case 0: |
719 | spacing = 0.200 * FREQ_MUL; break; | ||
712 | /* 1: 100 kHz (Europe, Japan) */ | 720 | /* 1: 100 kHz (Europe, Japan) */ |
713 | case 1 : spacing = 0.100 * FREQ_MUL; break; | 721 | case 1: |
722 | spacing = 0.100 * FREQ_MUL; break; | ||
714 | /* 2: 50 kHz */ | 723 | /* 2: 50 kHz */ |
715 | default: spacing = 0.050 * FREQ_MUL; break; | 724 | default: |
725 | spacing = 0.050 * FREQ_MUL; break; | ||
716 | }; | 726 | }; |
717 | 727 | ||
718 | /* Bottom of Band (MHz) */ | 728 | /* Bottom of Band (MHz) */ |
719 | switch (band) { | 729 | switch ((radio->registers[SYSCONFIG2] & SYSCONFIG2_BAND) >> 6) { |
720 | /* 0: 87.5 - 108 MHz (USA, Europe) */ | 730 | /* 0: 87.5 - 108 MHz (USA, Europe) */ |
721 | case 0 : band_bottom = 87.5 * FREQ_MUL; break; | 731 | case 0: |
732 | band_bottom = 87.5 * FREQ_MUL; break; | ||
722 | /* 1: 76 - 108 MHz (Japan wide band) */ | 733 | /* 1: 76 - 108 MHz (Japan wide band) */ |
723 | default: band_bottom = 76 * FREQ_MUL; break; | 734 | default: |
735 | band_bottom = 76 * FREQ_MUL; break; | ||
724 | /* 2: 76 - 90 MHz (Japan) */ | 736 | /* 2: 76 - 90 MHz (Japan) */ |
725 | case 2 : band_bottom = 76 * FREQ_MUL; break; | 737 | case 2: |
738 | band_bottom = 76 * FREQ_MUL; break; | ||
726 | }; | 739 | }; |
727 | 740 | ||
728 | /* Chan = [ Freq (Mhz) - Bottom of Band (MHz) ] / Spacing (kHz) */ | 741 | /* Chan = [ Freq (Mhz) - Bottom of Band (MHz) ] / Spacing (kHz) */ |
@@ -1164,7 +1177,6 @@ static const struct file_operations si470x_fops = { | |||
1164 | * si470x_v4l2_queryctrl - query control | 1177 | * si470x_v4l2_queryctrl - query control |
1165 | */ | 1178 | */ |
1166 | static struct v4l2_queryctrl si470x_v4l2_queryctrl[] = { | 1179 | static struct v4l2_queryctrl si470x_v4l2_queryctrl[] = { |
1167 | /* HINT: the disabled controls are only here to satify kradio and such apps */ | ||
1168 | { | 1180 | { |
1169 | .id = V4L2_CID_AUDIO_VOLUME, | 1181 | .id = V4L2_CID_AUDIO_VOLUME, |
1170 | .type = V4L2_CTRL_TYPE_INTEGER, | 1182 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -1175,18 +1187,6 @@ static struct v4l2_queryctrl si470x_v4l2_queryctrl[] = { | |||
1175 | .default_value = 15, | 1187 | .default_value = 15, |
1176 | }, | 1188 | }, |
1177 | { | 1189 | { |
1178 | .id = V4L2_CID_AUDIO_BALANCE, | ||
1179 | .flags = V4L2_CTRL_FLAG_DISABLED, | ||
1180 | }, | ||
1181 | { | ||
1182 | .id = V4L2_CID_AUDIO_BASS, | ||
1183 | .flags = V4L2_CTRL_FLAG_DISABLED, | ||
1184 | }, | ||
1185 | { | ||
1186 | .id = V4L2_CID_AUDIO_TREBLE, | ||
1187 | .flags = V4L2_CTRL_FLAG_DISABLED, | ||
1188 | }, | ||
1189 | { | ||
1190 | .id = V4L2_CID_AUDIO_MUTE, | 1190 | .id = V4L2_CID_AUDIO_MUTE, |
1191 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 1191 | .type = V4L2_CTRL_TYPE_BOOLEAN, |
1192 | .name = "Mute", | 1192 | .name = "Mute", |
@@ -1195,10 +1195,6 @@ static struct v4l2_queryctrl si470x_v4l2_queryctrl[] = { | |||
1195 | .step = 1, | 1195 | .step = 1, |
1196 | .default_value = 1, | 1196 | .default_value = 1, |
1197 | }, | 1197 | }, |
1198 | { | ||
1199 | .id = V4L2_CID_AUDIO_LOUDNESS, | ||
1200 | .flags = V4L2_CTRL_FLAG_DISABLED, | ||
1201 | }, | ||
1202 | }; | 1198 | }; |
1203 | 1199 | ||
1204 | 1200 | ||
@@ -1220,56 +1216,34 @@ static int si470x_vidioc_querycap(struct file *file, void *priv, | |||
1220 | 1216 | ||
1221 | 1217 | ||
1222 | /* | 1218 | /* |
1223 | * si470x_vidioc_g_input - get input | ||
1224 | */ | ||
1225 | static int si470x_vidioc_g_input(struct file *file, void *priv, | ||
1226 | unsigned int *i) | ||
1227 | { | ||
1228 | *i = 0; | ||
1229 | |||
1230 | return 0; | ||
1231 | } | ||
1232 | |||
1233 | |||
1234 | /* | ||
1235 | * si470x_vidioc_s_input - set input | ||
1236 | */ | ||
1237 | static int si470x_vidioc_s_input(struct file *file, void *priv, unsigned int i) | ||
1238 | { | ||
1239 | int retval = 0; | ||
1240 | |||
1241 | /* safety checks */ | ||
1242 | if (i != 0) | ||
1243 | retval = -EINVAL; | ||
1244 | |||
1245 | if (retval < 0) | ||
1246 | printk(KERN_WARNING DRIVER_NAME | ||
1247 | ": set input failed with %d\n", retval); | ||
1248 | return retval; | ||
1249 | } | ||
1250 | |||
1251 | |||
1252 | /* | ||
1253 | * si470x_vidioc_queryctrl - enumerate control items | 1219 | * si470x_vidioc_queryctrl - enumerate control items |
1254 | */ | 1220 | */ |
1255 | static int si470x_vidioc_queryctrl(struct file *file, void *priv, | 1221 | static int si470x_vidioc_queryctrl(struct file *file, void *priv, |
1256 | struct v4l2_queryctrl *qc) | 1222 | struct v4l2_queryctrl *qc) |
1257 | { | 1223 | { |
1258 | unsigned char i; | 1224 | unsigned char i = 0; |
1259 | int retval = -EINVAL; | 1225 | int retval = -EINVAL; |
1260 | 1226 | ||
1261 | /* safety checks */ | 1227 | /* abort if qc->id is below V4L2_CID_BASE */ |
1262 | if (!qc->id) | 1228 | if (qc->id < V4L2_CID_BASE) |
1263 | goto done; | 1229 | goto done; |
1264 | 1230 | ||
1231 | /* search video control */ | ||
1265 | for (i = 0; i < ARRAY_SIZE(si470x_v4l2_queryctrl); i++) { | 1232 | for (i = 0; i < ARRAY_SIZE(si470x_v4l2_queryctrl); i++) { |
1266 | if (qc->id == si470x_v4l2_queryctrl[i].id) { | 1233 | if (qc->id == si470x_v4l2_queryctrl[i].id) { |
1267 | memcpy(qc, &(si470x_v4l2_queryctrl[i]), sizeof(*qc)); | 1234 | memcpy(qc, &(si470x_v4l2_queryctrl[i]), sizeof(*qc)); |
1268 | retval = 0; | 1235 | retval = 0; /* found */ |
1269 | break; | 1236 | break; |
1270 | } | 1237 | } |
1271 | } | 1238 | } |
1272 | 1239 | ||
1240 | /* disable unsupported base controls */ | ||
1241 | /* to satisfy kradio and such apps */ | ||
1242 | if ((retval == -EINVAL) && (qc->id < V4L2_CID_LASTP1)) { | ||
1243 | qc->flags = V4L2_CTRL_FLAG_DISABLED; | ||
1244 | retval = 0; | ||
1245 | } | ||
1246 | |||
1273 | done: | 1247 | done: |
1274 | if (retval < 0) | 1248 | if (retval < 0) |
1275 | printk(KERN_WARNING DRIVER_NAME | 1249 | printk(KERN_WARNING DRIVER_NAME |
@@ -1360,44 +1334,13 @@ done: | |||
1360 | static int si470x_vidioc_g_audio(struct file *file, void *priv, | 1334 | static int si470x_vidioc_g_audio(struct file *file, void *priv, |
1361 | struct v4l2_audio *audio) | 1335 | struct v4l2_audio *audio) |
1362 | { | 1336 | { |
1363 | int retval = 0; | 1337 | /* driver constants */ |
1364 | 1338 | audio->index = 0; | |
1365 | /* safety checks */ | ||
1366 | if (audio->index != 0) { | ||
1367 | retval = -EINVAL; | ||
1368 | goto done; | ||
1369 | } | ||
1370 | |||
1371 | strcpy(audio->name, "Radio"); | 1339 | strcpy(audio->name, "Radio"); |
1372 | audio->capability = V4L2_AUDCAP_STEREO; | 1340 | audio->capability = V4L2_AUDCAP_STEREO; |
1341 | audio->mode = 0; | ||
1373 | 1342 | ||
1374 | done: | 1343 | return 0; |
1375 | if (retval < 0) | ||
1376 | printk(KERN_WARNING DRIVER_NAME | ||
1377 | ": get audio failed with %d\n", retval); | ||
1378 | return retval; | ||
1379 | } | ||
1380 | |||
1381 | |||
1382 | /* | ||
1383 | * si470x_vidioc_s_audio - set audio attributes | ||
1384 | */ | ||
1385 | static int si470x_vidioc_s_audio(struct file *file, void *priv, | ||
1386 | struct v4l2_audio *audio) | ||
1387 | { | ||
1388 | int retval = 0; | ||
1389 | |||
1390 | /* safety checks */ | ||
1391 | if (audio->index != 0) { | ||
1392 | retval = -EINVAL; | ||
1393 | goto done; | ||
1394 | } | ||
1395 | |||
1396 | done: | ||
1397 | if (retval < 0) | ||
1398 | printk(KERN_WARNING DRIVER_NAME | ||
1399 | ": set audio failed with %d\n", retval); | ||
1400 | return retval; | ||
1401 | } | 1344 | } |
1402 | 1345 | ||
1403 | 1346 | ||
@@ -1415,7 +1358,7 @@ static int si470x_vidioc_g_tuner(struct file *file, void *priv, | |||
1415 | retval = -EIO; | 1358 | retval = -EIO; |
1416 | goto done; | 1359 | goto done; |
1417 | } | 1360 | } |
1418 | if ((tuner->index != 0) && (tuner->type != V4L2_TUNER_RADIO)) { | 1361 | if (tuner->index != 0) { |
1419 | retval = -EINVAL; | 1362 | retval = -EINVAL; |
1420 | goto done; | 1363 | goto done; |
1421 | } | 1364 | } |
@@ -1424,8 +1367,13 @@ static int si470x_vidioc_g_tuner(struct file *file, void *priv, | |||
1424 | if (retval < 0) | 1367 | if (retval < 0) |
1425 | goto done; | 1368 | goto done; |
1426 | 1369 | ||
1370 | /* driver constants */ | ||
1427 | strcpy(tuner->name, "FM"); | 1371 | strcpy(tuner->name, "FM"); |
1428 | switch (band) { | 1372 | tuner->type = V4L2_TUNER_RADIO; |
1373 | tuner->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO; | ||
1374 | |||
1375 | /* range limits */ | ||
1376 | switch ((radio->registers[SYSCONFIG2] & SYSCONFIG2_BAND) >> 6) { | ||
1429 | /* 0: 87.5 - 108 MHz (USA, Europe, default) */ | 1377 | /* 0: 87.5 - 108 MHz (USA, Europe, default) */ |
1430 | default: | 1378 | default: |
1431 | tuner->rangelow = 87.5 * FREQ_MUL; | 1379 | tuner->rangelow = 87.5 * FREQ_MUL; |
@@ -1442,14 +1390,18 @@ static int si470x_vidioc_g_tuner(struct file *file, void *priv, | |||
1442 | tuner->rangehigh = 90 * FREQ_MUL; | 1390 | tuner->rangehigh = 90 * FREQ_MUL; |
1443 | break; | 1391 | break; |
1444 | }; | 1392 | }; |
1445 | tuner->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; | ||
1446 | tuner->capability = V4L2_TUNER_CAP_LOW; | ||
1447 | 1393 | ||
1448 | /* Stereo indicator == Stereo (instead of Mono) */ | 1394 | /* stereo indicator == stereo (instead of mono) */ |
1449 | if ((radio->registers[STATUSRSSI] & STATUSRSSI_ST) == 1) | 1395 | if ((radio->registers[STATUSRSSI] & STATUSRSSI_ST) == 1) |
1450 | tuner->audmode = V4L2_TUNER_MODE_STEREO; | 1396 | tuner->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; |
1451 | else | 1397 | else |
1398 | tuner->rxsubchans = V4L2_TUNER_SUB_MONO; | ||
1399 | |||
1400 | /* mono/stereo selector */ | ||
1401 | if ((radio->registers[POWERCFG] & POWERCFG_MONO) == 1) | ||
1452 | tuner->audmode = V4L2_TUNER_MODE_MONO; | 1402 | tuner->audmode = V4L2_TUNER_MODE_MONO; |
1403 | else | ||
1404 | tuner->audmode = V4L2_TUNER_MODE_STEREO; | ||
1453 | 1405 | ||
1454 | /* min is worst, max is best; signal:0..0xffff; rssi: 0..0xff */ | 1406 | /* min is worst, max is best; signal:0..0xffff; rssi: 0..0xff */ |
1455 | tuner->signal = (radio->registers[STATUSRSSI] & STATUSRSSI_RSSI) | 1407 | tuner->signal = (radio->registers[STATUSRSSI] & STATUSRSSI_RSSI) |
@@ -1474,22 +1426,27 @@ static int si470x_vidioc_s_tuner(struct file *file, void *priv, | |||
1474 | struct v4l2_tuner *tuner) | 1426 | struct v4l2_tuner *tuner) |
1475 | { | 1427 | { |
1476 | struct si470x_device *radio = video_drvdata(file); | 1428 | struct si470x_device *radio = video_drvdata(file); |
1477 | int retval = 0; | 1429 | int retval = -EINVAL; |
1478 | 1430 | ||
1479 | /* safety checks */ | 1431 | /* safety checks */ |
1480 | if (radio->disconnected) { | 1432 | if (radio->disconnected) { |
1481 | retval = -EIO; | 1433 | retval = -EIO; |
1482 | goto done; | 1434 | goto done; |
1483 | } | 1435 | } |
1484 | if ((tuner->index != 0) && (tuner->type != V4L2_TUNER_RADIO)) { | 1436 | if (tuner->index != 0) |
1485 | retval = -EINVAL; | ||
1486 | goto done; | 1437 | goto done; |
1487 | } | ||
1488 | 1438 | ||
1489 | if (tuner->audmode == V4L2_TUNER_MODE_MONO) | 1439 | /* mono/stereo selector */ |
1440 | switch (tuner->audmode) { | ||
1441 | case V4L2_TUNER_MODE_MONO: | ||
1490 | radio->registers[POWERCFG] |= POWERCFG_MONO; /* force mono */ | 1442 | radio->registers[POWERCFG] |= POWERCFG_MONO; /* force mono */ |
1491 | else | 1443 | break; |
1444 | case V4L2_TUNER_MODE_STEREO: | ||
1492 | radio->registers[POWERCFG] &= ~POWERCFG_MONO; /* try stereo */ | 1445 | radio->registers[POWERCFG] &= ~POWERCFG_MONO; /* try stereo */ |
1446 | break; | ||
1447 | default: | ||
1448 | goto done; | ||
1449 | } | ||
1493 | 1450 | ||
1494 | retval = si470x_set_register(radio, POWERCFG); | 1451 | retval = si470x_set_register(radio, POWERCFG); |
1495 | 1452 | ||
@@ -1515,11 +1472,12 @@ static int si470x_vidioc_g_frequency(struct file *file, void *priv, | |||
1515 | retval = -EIO; | 1472 | retval = -EIO; |
1516 | goto done; | 1473 | goto done; |
1517 | } | 1474 | } |
1518 | if ((freq->tuner != 0) && (freq->type != V4L2_TUNER_RADIO)) { | 1475 | if (freq->tuner != 0) { |
1519 | retval = -EINVAL; | 1476 | retval = -EINVAL; |
1520 | goto done; | 1477 | goto done; |
1521 | } | 1478 | } |
1522 | 1479 | ||
1480 | freq->type = V4L2_TUNER_RADIO; | ||
1523 | retval = si470x_get_freq(radio, &freq->frequency); | 1481 | retval = si470x_get_freq(radio, &freq->frequency); |
1524 | 1482 | ||
1525 | done: | 1483 | done: |
@@ -1544,7 +1502,7 @@ static int si470x_vidioc_s_frequency(struct file *file, void *priv, | |||
1544 | retval = -EIO; | 1502 | retval = -EIO; |
1545 | goto done; | 1503 | goto done; |
1546 | } | 1504 | } |
1547 | if ((freq->tuner != 0) && (freq->type != V4L2_TUNER_RADIO)) { | 1505 | if (freq->tuner != 0) { |
1548 | retval = -EINVAL; | 1506 | retval = -EINVAL; |
1549 | goto done; | 1507 | goto done; |
1550 | } | 1508 | } |
@@ -1573,7 +1531,7 @@ static int si470x_vidioc_s_hw_freq_seek(struct file *file, void *priv, | |||
1573 | retval = -EIO; | 1531 | retval = -EIO; |
1574 | goto done; | 1532 | goto done; |
1575 | } | 1533 | } |
1576 | if ((seek->tuner != 0) && (seek->type != V4L2_TUNER_RADIO)) { | 1534 | if (seek->tuner != 0) { |
1577 | retval = -EINVAL; | 1535 | retval = -EINVAL; |
1578 | goto done; | 1536 | goto done; |
1579 | } | 1537 | } |
@@ -1588,15 +1546,16 @@ done: | |||
1588 | return retval; | 1546 | return retval; |
1589 | } | 1547 | } |
1590 | 1548 | ||
1549 | |||
1550 | /* | ||
1551 | * si470x_ioctl_ops - video device ioctl operations | ||
1552 | */ | ||
1591 | static const struct v4l2_ioctl_ops si470x_ioctl_ops = { | 1553 | static const struct v4l2_ioctl_ops si470x_ioctl_ops = { |
1592 | .vidioc_querycap = si470x_vidioc_querycap, | 1554 | .vidioc_querycap = si470x_vidioc_querycap, |
1593 | .vidioc_g_input = si470x_vidioc_g_input, | ||
1594 | .vidioc_s_input = si470x_vidioc_s_input, | ||
1595 | .vidioc_queryctrl = si470x_vidioc_queryctrl, | 1555 | .vidioc_queryctrl = si470x_vidioc_queryctrl, |
1596 | .vidioc_g_ctrl = si470x_vidioc_g_ctrl, | 1556 | .vidioc_g_ctrl = si470x_vidioc_g_ctrl, |
1597 | .vidioc_s_ctrl = si470x_vidioc_s_ctrl, | 1557 | .vidioc_s_ctrl = si470x_vidioc_s_ctrl, |
1598 | .vidioc_g_audio = si470x_vidioc_g_audio, | 1558 | .vidioc_g_audio = si470x_vidioc_g_audio, |
1599 | .vidioc_s_audio = si470x_vidioc_s_audio, | ||
1600 | .vidioc_g_tuner = si470x_vidioc_g_tuner, | 1559 | .vidioc_g_tuner = si470x_vidioc_g_tuner, |
1601 | .vidioc_s_tuner = si470x_vidioc_s_tuner, | 1560 | .vidioc_s_tuner = si470x_vidioc_s_tuner, |
1602 | .vidioc_g_frequency = si470x_vidioc_g_frequency, | 1561 | .vidioc_g_frequency = si470x_vidioc_g_frequency, |
@@ -1604,14 +1563,15 @@ static const struct v4l2_ioctl_ops si470x_ioctl_ops = { | |||
1604 | .vidioc_s_hw_freq_seek = si470x_vidioc_s_hw_freq_seek, | 1563 | .vidioc_s_hw_freq_seek = si470x_vidioc_s_hw_freq_seek, |
1605 | }; | 1564 | }; |
1606 | 1565 | ||
1566 | |||
1607 | /* | 1567 | /* |
1608 | * si470x_viddev_tamples - video device interface | 1568 | * si470x_viddev_template - video device interface |
1609 | */ | 1569 | */ |
1610 | static struct video_device si470x_viddev_template = { | 1570 | static struct video_device si470x_viddev_template = { |
1611 | .fops = &si470x_fops, | 1571 | .fops = &si470x_fops, |
1612 | .ioctl_ops = &si470x_ioctl_ops, | ||
1613 | .name = DRIVER_NAME, | 1572 | .name = DRIVER_NAME, |
1614 | .release = video_device_release, | 1573 | .release = video_device_release, |
1574 | .ioctl_ops = &si470x_ioctl_ops, | ||
1615 | }; | 1575 | }; |
1616 | 1576 | ||
1617 | 1577 | ||
diff --git a/drivers/media/video/adv7170.c b/drivers/media/video/adv7170.c index f794f2dbfb32..e0eb4f321442 100644 --- a/drivers/media/video/adv7170.c +++ b/drivers/media/video/adv7170.c | |||
@@ -29,43 +29,24 @@ | |||
29 | */ | 29 | */ |
30 | 30 | ||
31 | #include <linux/module.h> | 31 | #include <linux/module.h> |
32 | #include <linux/init.h> | ||
33 | #include <linux/delay.h> | ||
34 | #include <linux/errno.h> | ||
35 | #include <linux/fs.h> | ||
36 | #include <linux/kernel.h> | ||
37 | #include <linux/major.h> | ||
38 | #include <linux/slab.h> | ||
39 | #include <linux/mm.h> | ||
40 | #include <linux/signal.h> | ||
41 | #include <linux/types.h> | 32 | #include <linux/types.h> |
42 | #include <linux/i2c.h> | 33 | #include <linux/ioctl.h> |
43 | #include <asm/io.h> | ||
44 | #include <asm/pgtable.h> | ||
45 | #include <asm/page.h> | ||
46 | #include <asm/uaccess.h> | 34 | #include <asm/uaccess.h> |
47 | 35 | #include <linux/i2c.h> | |
36 | #include <linux/i2c-id.h> | ||
48 | #include <linux/videodev.h> | 37 | #include <linux/videodev.h> |
49 | #include <linux/video_encoder.h> | 38 | #include <linux/video_encoder.h> |
39 | #include <media/v4l2-common.h> | ||
40 | #include <media/v4l2-i2c-drv-legacy.h> | ||
50 | 41 | ||
51 | MODULE_DESCRIPTION("Analog Devices ADV7170 video encoder driver"); | 42 | MODULE_DESCRIPTION("Analog Devices ADV7170 video encoder driver"); |
52 | MODULE_AUTHOR("Maxim Yevtyushkin"); | 43 | MODULE_AUTHOR("Maxim Yevtyushkin"); |
53 | MODULE_LICENSE("GPL"); | 44 | MODULE_LICENSE("GPL"); |
54 | 45 | ||
55 | |||
56 | #define I2C_NAME(x) (x)->name | ||
57 | |||
58 | |||
59 | static int debug; | 46 | static int debug; |
60 | module_param(debug, int, 0); | 47 | module_param(debug, int, 0); |
61 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); | 48 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); |
62 | 49 | ||
63 | #define dprintk(num, format, args...) \ | ||
64 | do { \ | ||
65 | if (debug >= num) \ | ||
66 | printk(format, ##args); \ | ||
67 | } while (0) | ||
68 | |||
69 | /* ----------------------------------------------------------------------- */ | 50 | /* ----------------------------------------------------------------------- */ |
70 | 51 | ||
71 | struct adv7170 { | 52 | struct adv7170 { |
@@ -80,21 +61,12 @@ struct adv7170 { | |||
80 | int sat; | 61 | int sat; |
81 | }; | 62 | }; |
82 | 63 | ||
83 | #define I2C_ADV7170 0xd4 | ||
84 | #define I2C_ADV7171 0x54 | ||
85 | |||
86 | static char adv7170_name[] = "adv7170"; | ||
87 | static char adv7171_name[] = "adv7171"; | ||
88 | |||
89 | static char *inputs[] = { "pass_through", "play_back" }; | 64 | static char *inputs[] = { "pass_through", "play_back" }; |
90 | static char *norms[] = { "PAL", "NTSC" }; | 65 | static char *norms[] = { "PAL", "NTSC" }; |
91 | 66 | ||
92 | /* ----------------------------------------------------------------------- */ | 67 | /* ----------------------------------------------------------------------- */ |
93 | 68 | ||
94 | static inline int | 69 | static inline int adv7170_write(struct i2c_client *client, u8 reg, u8 value) |
95 | adv7170_write (struct i2c_client *client, | ||
96 | u8 reg, | ||
97 | u8 value) | ||
98 | { | 70 | { |
99 | struct adv7170 *encoder = i2c_get_clientdata(client); | 71 | struct adv7170 *encoder = i2c_get_clientdata(client); |
100 | 72 | ||
@@ -102,17 +74,13 @@ adv7170_write (struct i2c_client *client, | |||
102 | return i2c_smbus_write_byte_data(client, reg, value); | 74 | return i2c_smbus_write_byte_data(client, reg, value); |
103 | } | 75 | } |
104 | 76 | ||
105 | static inline int | 77 | static inline int adv7170_read(struct i2c_client *client, u8 reg) |
106 | adv7170_read (struct i2c_client *client, | ||
107 | u8 reg) | ||
108 | { | 78 | { |
109 | return i2c_smbus_read_byte_data(client, reg); | 79 | return i2c_smbus_read_byte_data(client, reg); |
110 | } | 80 | } |
111 | 81 | ||
112 | static int | 82 | static int adv7170_write_block(struct i2c_client *client, |
113 | adv7170_write_block (struct i2c_client *client, | 83 | const u8 *data, unsigned int len) |
114 | const u8 *data, | ||
115 | unsigned int len) | ||
116 | { | 84 | { |
117 | int ret = -1; | 85 | int ret = -1; |
118 | u8 reg; | 86 | u8 reg; |
@@ -133,33 +101,25 @@ adv7170_write_block (struct i2c_client *client, | |||
133 | encoder->reg[reg++] = data[1]; | 101 | encoder->reg[reg++] = data[1]; |
134 | len -= 2; | 102 | len -= 2; |
135 | data += 2; | 103 | data += 2; |
136 | } while (len >= 2 && data[0] == reg && | 104 | } while (len >= 2 && data[0] == reg && block_len < 32); |
137 | block_len < 32); | 105 | ret = i2c_master_send(client, block_data, block_len); |
138 | if ((ret = i2c_master_send(client, block_data, | 106 | if (ret < 0) |
139 | block_len)) < 0) | ||
140 | break; | 107 | break; |
141 | } | 108 | } |
142 | } else { | 109 | } else { |
143 | /* do some slow I2C emulation kind of thing */ | 110 | /* do some slow I2C emulation kind of thing */ |
144 | while (len >= 2) { | 111 | while (len >= 2) { |
145 | reg = *data++; | 112 | reg = *data++; |
146 | if ((ret = adv7170_write(client, reg, | 113 | ret = adv7170_write(client, reg, *data++); |
147 | *data++)) < 0) | 114 | if (ret < 0) |
148 | break; | 115 | break; |
149 | len -= 2; | 116 | len -= 2; |
150 | } | 117 | } |
151 | } | 118 | } |
152 | |||
153 | return ret; | 119 | return ret; |
154 | } | 120 | } |
155 | 121 | ||
156 | /* ----------------------------------------------------------------------- */ | 122 | /* ----------------------------------------------------------------------- */ |
157 | // Output filter: S-Video Composite | ||
158 | |||
159 | #define MR050 0x11 //0x09 | ||
160 | #define MR060 0x14 //0x0c | ||
161 | |||
162 | //--------------------------------------------------------------------------- | ||
163 | 123 | ||
164 | #define TR0MODE 0x4c | 124 | #define TR0MODE 0x4c |
165 | #define TR0RST 0x80 | 125 | #define TR0RST 0x80 |
@@ -167,7 +127,6 @@ adv7170_write_block (struct i2c_client *client, | |||
167 | #define TR1CAPT 0x00 | 127 | #define TR1CAPT 0x00 |
168 | #define TR1PLAY 0x00 | 128 | #define TR1PLAY 0x00 |
169 | 129 | ||
170 | |||
171 | static const unsigned char init_NTSC[] = { | 130 | static const unsigned char init_NTSC[] = { |
172 | 0x00, 0x10, // MR0 | 131 | 0x00, 0x10, // MR0 |
173 | 0x01, 0x20, // MR1 | 132 | 0x01, 0x20, // MR1 |
@@ -227,15 +186,11 @@ static const unsigned char init_PAL[] = { | |||
227 | }; | 186 | }; |
228 | 187 | ||
229 | 188 | ||
230 | static int | 189 | static int adv7170_command(struct i2c_client *client, unsigned cmd, void *arg) |
231 | adv7170_command (struct i2c_client *client, | ||
232 | unsigned int cmd, | ||
233 | void * arg) | ||
234 | { | 190 | { |
235 | struct adv7170 *encoder = i2c_get_clientdata(client); | 191 | struct adv7170 *encoder = i2c_get_clientdata(client); |
236 | 192 | ||
237 | switch (cmd) { | 193 | switch (cmd) { |
238 | |||
239 | case 0: | 194 | case 0: |
240 | #if 0 | 195 | #if 0 |
241 | /* This is just for testing!!! */ | 196 | /* This is just for testing!!! */ |
@@ -254,18 +209,16 @@ adv7170_command (struct i2c_client *client, | |||
254 | VIDEO_ENCODER_NTSC; | 209 | VIDEO_ENCODER_NTSC; |
255 | cap->inputs = 2; | 210 | cap->inputs = 2; |
256 | cap->outputs = 1; | 211 | cap->outputs = 1; |
257 | } | ||
258 | break; | 212 | break; |
213 | } | ||
259 | 214 | ||
260 | case ENCODER_SET_NORM: | 215 | case ENCODER_SET_NORM: |
261 | { | 216 | { |
262 | int iarg = *(int *) arg; | 217 | int iarg = *(int *) arg; |
263 | 218 | ||
264 | dprintk(1, KERN_DEBUG "%s_command: set norm %d", | 219 | v4l_dbg(1, debug, client, "set norm %d\n", iarg); |
265 | I2C_NAME(client), iarg); | ||
266 | 220 | ||
267 | switch (iarg) { | 221 | switch (iarg) { |
268 | |||
269 | case VIDEO_MODE_NTSC: | 222 | case VIDEO_MODE_NTSC: |
270 | adv7170_write_block(client, init_NTSC, | 223 | adv7170_write_block(client, init_NTSC, |
271 | sizeof(init_NTSC)); | 224 | sizeof(init_NTSC)); |
@@ -285,16 +238,13 @@ adv7170_command (struct i2c_client *client, | |||
285 | break; | 238 | break; |
286 | 239 | ||
287 | default: | 240 | default: |
288 | dprintk(1, KERN_ERR "%s: illegal norm: %d\n", | 241 | v4l_dbg(1, debug, client, "illegal norm: %d\n", iarg); |
289 | I2C_NAME(client), iarg); | ||
290 | return -EINVAL; | 242 | return -EINVAL; |
291 | |||
292 | } | 243 | } |
293 | dprintk(1, KERN_DEBUG "%s: switched to %s\n", I2C_NAME(client), | 244 | v4l_dbg(1, debug, client, "switched to %s\n", norms[iarg]); |
294 | norms[iarg]); | ||
295 | encoder->norm = iarg; | 245 | encoder->norm = iarg; |
296 | } | ||
297 | break; | 246 | break; |
247 | } | ||
298 | 248 | ||
299 | case ENCODER_SET_INPUT: | 249 | case ENCODER_SET_INPUT: |
300 | { | 250 | { |
@@ -304,19 +254,17 @@ adv7170_command (struct i2c_client *client, | |||
304 | *iarg = 1: input is from ZR36060 | 254 | *iarg = 1: input is from ZR36060 |
305 | *iarg = 2: color bar */ | 255 | *iarg = 2: color bar */ |
306 | 256 | ||
307 | dprintk(1, KERN_DEBUG "%s_command: set input from %s\n", | 257 | v4l_dbg(1, debug, client, "set input from %s\n", |
308 | I2C_NAME(client), | ||
309 | iarg == 0 ? "decoder" : "ZR36060"); | 258 | iarg == 0 ? "decoder" : "ZR36060"); |
310 | 259 | ||
311 | switch (iarg) { | 260 | switch (iarg) { |
312 | |||
313 | case 0: | 261 | case 0: |
314 | adv7170_write(client, 0x01, 0x20); | 262 | adv7170_write(client, 0x01, 0x20); |
315 | adv7170_write(client, 0x08, TR1CAPT); /* TR1 */ | 263 | adv7170_write(client, 0x08, TR1CAPT); /* TR1 */ |
316 | adv7170_write(client, 0x02, 0x0e); // Enable genlock | 264 | adv7170_write(client, 0x02, 0x0e); // Enable genlock |
317 | adv7170_write(client, 0x07, TR0MODE | TR0RST); | 265 | adv7170_write(client, 0x07, TR0MODE | TR0RST); |
318 | adv7170_write(client, 0x07, TR0MODE); | 266 | adv7170_write(client, 0x07, TR0MODE); |
319 | //udelay(10); | 267 | /* udelay(10); */ |
320 | break; | 268 | break; |
321 | 269 | ||
322 | case 1: | 270 | case 1: |
@@ -325,20 +273,17 @@ adv7170_command (struct i2c_client *client, | |||
325 | adv7170_write(client, 0x02, 0x08); | 273 | adv7170_write(client, 0x02, 0x08); |
326 | adv7170_write(client, 0x07, TR0MODE | TR0RST); | 274 | adv7170_write(client, 0x07, TR0MODE | TR0RST); |
327 | adv7170_write(client, 0x07, TR0MODE); | 275 | adv7170_write(client, 0x07, TR0MODE); |
328 | //udelay(10); | 276 | /* udelay(10); */ |
329 | break; | 277 | break; |
330 | 278 | ||
331 | default: | 279 | default: |
332 | dprintk(1, KERN_ERR "%s: illegal input: %d\n", | 280 | v4l_dbg(1, debug, client, "illegal input: %d\n", iarg); |
333 | I2C_NAME(client), iarg); | ||
334 | return -EINVAL; | 281 | return -EINVAL; |
335 | |||
336 | } | 282 | } |
337 | dprintk(1, KERN_DEBUG "%s: switched to %s\n", I2C_NAME(client), | 283 | v4l_dbg(1, debug, client, "switched to %s\n", inputs[iarg]); |
338 | inputs[iarg]); | ||
339 | encoder->input = iarg; | 284 | encoder->input = iarg; |
340 | } | ||
341 | break; | 285 | break; |
286 | } | ||
342 | 287 | ||
343 | case ENCODER_SET_OUTPUT: | 288 | case ENCODER_SET_OUTPUT: |
344 | { | 289 | { |
@@ -348,16 +293,16 @@ adv7170_command (struct i2c_client *client, | |||
348 | if (*iarg != 0) { | 293 | if (*iarg != 0) { |
349 | return -EINVAL; | 294 | return -EINVAL; |
350 | } | 295 | } |
351 | } | ||
352 | break; | 296 | break; |
297 | } | ||
353 | 298 | ||
354 | case ENCODER_ENABLE_OUTPUT: | 299 | case ENCODER_ENABLE_OUTPUT: |
355 | { | 300 | { |
356 | int *iarg = arg; | 301 | int *iarg = arg; |
357 | 302 | ||
358 | encoder->enable = !!*iarg; | 303 | encoder->enable = !!*iarg; |
359 | } | ||
360 | break; | 304 | break; |
305 | } | ||
361 | 306 | ||
362 | default: | 307 | default: |
363 | return -EINVAL; | 308 | return -EINVAL; |
@@ -368,149 +313,67 @@ adv7170_command (struct i2c_client *client, | |||
368 | 313 | ||
369 | /* ----------------------------------------------------------------------- */ | 314 | /* ----------------------------------------------------------------------- */ |
370 | 315 | ||
371 | /* | 316 | static unsigned short normal_i2c[] = { |
372 | * Generic i2c probe | 317 | 0xd4 >> 1, 0xd6 >> 1, /* adv7170 IDs */ |
373 | * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1' | 318 | 0x54 >> 1, 0x56 >> 1, /* adv7171 IDs */ |
374 | */ | ||
375 | static unsigned short normal_i2c[] = | ||
376 | { I2C_ADV7170 >> 1, (I2C_ADV7170 >> 1) + 1, | ||
377 | I2C_ADV7171 >> 1, (I2C_ADV7171 >> 1) + 1, | ||
378 | I2C_CLIENT_END | 319 | I2C_CLIENT_END |
379 | }; | 320 | }; |
380 | 321 | ||
381 | static unsigned short ignore = I2C_CLIENT_END; | 322 | I2C_CLIENT_INSMOD; |
382 | 323 | ||
383 | static struct i2c_client_address_data addr_data = { | 324 | static int adv7170_probe(struct i2c_client *client, |
384 | .normal_i2c = normal_i2c, | 325 | const struct i2c_device_id *id) |
385 | .probe = &ignore, | ||
386 | .ignore = &ignore, | ||
387 | }; | ||
388 | |||
389 | static struct i2c_driver i2c_driver_adv7170; | ||
390 | |||
391 | static int | ||
392 | adv7170_detect_client (struct i2c_adapter *adapter, | ||
393 | int address, | ||
394 | int kind) | ||
395 | { | 326 | { |
396 | int i; | ||
397 | struct i2c_client *client; | ||
398 | struct adv7170 *encoder; | 327 | struct adv7170 *encoder; |
399 | char *dname; | 328 | int i; |
400 | |||
401 | dprintk(1, | ||
402 | KERN_INFO | ||
403 | "adv7170.c: detecting adv7170 client on address 0x%x\n", | ||
404 | address << 1); | ||
405 | 329 | ||
406 | /* Check if the adapter supports the needed features */ | 330 | /* Check if the adapter supports the needed features */ |
407 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | 331 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) |
408 | return 0; | 332 | return -ENODEV; |
409 | 333 | ||
410 | client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); | 334 | v4l_info(client, "chip found @ 0x%x (%s)\n", |
411 | if (!client) | 335 | client->addr << 1, client->adapter->name); |
412 | return -ENOMEM; | ||
413 | client->addr = address; | ||
414 | client->adapter = adapter; | ||
415 | client->driver = &i2c_driver_adv7170; | ||
416 | if ((client->addr == I2C_ADV7170 >> 1) || | ||
417 | (client->addr == (I2C_ADV7170 >> 1) + 1)) { | ||
418 | dname = adv7170_name; | ||
419 | } else if ((client->addr == I2C_ADV7171 >> 1) || | ||
420 | (client->addr == (I2C_ADV7171 >> 1) + 1)) { | ||
421 | dname = adv7171_name; | ||
422 | } else { | ||
423 | /* We should never get here!!! */ | ||
424 | kfree(client); | ||
425 | return 0; | ||
426 | } | ||
427 | strlcpy(I2C_NAME(client), dname, sizeof(I2C_NAME(client))); | ||
428 | 336 | ||
429 | encoder = kzalloc(sizeof(struct adv7170), GFP_KERNEL); | 337 | encoder = kzalloc(sizeof(struct adv7170), GFP_KERNEL); |
430 | if (encoder == NULL) { | 338 | if (encoder == NULL) |
431 | kfree(client); | ||
432 | return -ENOMEM; | 339 | return -ENOMEM; |
433 | } | ||
434 | encoder->norm = VIDEO_MODE_NTSC; | 340 | encoder->norm = VIDEO_MODE_NTSC; |
435 | encoder->input = 0; | 341 | encoder->input = 0; |
436 | encoder->enable = 1; | 342 | encoder->enable = 1; |
437 | i2c_set_clientdata(client, encoder); | 343 | i2c_set_clientdata(client, encoder); |
438 | 344 | ||
439 | i = i2c_attach_client(client); | ||
440 | if (i) { | ||
441 | kfree(client); | ||
442 | kfree(encoder); | ||
443 | return i; | ||
444 | } | ||
445 | |||
446 | i = adv7170_write_block(client, init_NTSC, sizeof(init_NTSC)); | 345 | i = adv7170_write_block(client, init_NTSC, sizeof(init_NTSC)); |
447 | if (i >= 0) { | 346 | if (i >= 0) { |
448 | i = adv7170_write(client, 0x07, TR0MODE | TR0RST); | 347 | i = adv7170_write(client, 0x07, TR0MODE | TR0RST); |
449 | i = adv7170_write(client, 0x07, TR0MODE); | 348 | i = adv7170_write(client, 0x07, TR0MODE); |
450 | i = adv7170_read(client, 0x12); | 349 | i = adv7170_read(client, 0x12); |
451 | dprintk(1, KERN_INFO "%s_attach: rev. %d at 0x%02x\n", | 350 | v4l_dbg(1, debug, client, "revision %d\n", i & 1); |
452 | I2C_NAME(client), i & 1, client->addr << 1); | ||
453 | } | ||
454 | if (i < 0) { | ||
455 | dprintk(1, KERN_ERR "%s_attach: init error 0x%x\n", | ||
456 | I2C_NAME(client), i); | ||
457 | } | 351 | } |
458 | 352 | if (i < 0) | |
353 | v4l_dbg(1, debug, client, "init error 0x%x\n", i); | ||
459 | return 0; | 354 | return 0; |
460 | } | 355 | } |
461 | 356 | ||
462 | static int | 357 | static int adv7170_remove(struct i2c_client *client) |
463 | adv7170_attach_adapter (struct i2c_adapter *adapter) | ||
464 | { | ||
465 | dprintk(1, | ||
466 | KERN_INFO | ||
467 | "adv7170.c: starting probe for adapter %s (0x%x)\n", | ||
468 | I2C_NAME(adapter), adapter->id); | ||
469 | return i2c_probe(adapter, &addr_data, &adv7170_detect_client); | ||
470 | } | ||
471 | |||
472 | static int | ||
473 | adv7170_detach_client (struct i2c_client *client) | ||
474 | { | 358 | { |
475 | struct adv7170 *encoder = i2c_get_clientdata(client); | 359 | kfree(i2c_get_clientdata(client)); |
476 | int err; | ||
477 | |||
478 | err = i2c_detach_client(client); | ||
479 | if (err) { | ||
480 | return err; | ||
481 | } | ||
482 | |||
483 | kfree(encoder); | ||
484 | kfree(client); | ||
485 | |||
486 | return 0; | 360 | return 0; |
487 | } | 361 | } |
488 | 362 | ||
489 | /* ----------------------------------------------------------------------- */ | 363 | /* ----------------------------------------------------------------------- */ |
490 | 364 | ||
491 | static struct i2c_driver i2c_driver_adv7170 = { | 365 | static const struct i2c_device_id adv7170_id[] = { |
492 | .driver = { | 366 | { "adv7170", 0 }, |
493 | .name = "adv7170", /* name */ | 367 | { "adv7171", 0 }, |
494 | }, | 368 | { } |
495 | 369 | }; | |
496 | .id = I2C_DRIVERID_ADV7170, | 370 | MODULE_DEVICE_TABLE(i2c, adv7170_id); |
497 | 371 | ||
498 | .attach_adapter = adv7170_attach_adapter, | 372 | static struct v4l2_i2c_driver_data v4l2_i2c_data = { |
499 | .detach_client = adv7170_detach_client, | 373 | .name = "adv7170", |
374 | .driverid = I2C_DRIVERID_ADV7170, | ||
500 | .command = adv7170_command, | 375 | .command = adv7170_command, |
376 | .probe = adv7170_probe, | ||
377 | .remove = adv7170_remove, | ||
378 | .id_table = adv7170_id, | ||
501 | }; | 379 | }; |
502 | |||
503 | static int __init | ||
504 | adv7170_init (void) | ||
505 | { | ||
506 | return i2c_add_driver(&i2c_driver_adv7170); | ||
507 | } | ||
508 | |||
509 | static void __exit | ||
510 | adv7170_exit (void) | ||
511 | { | ||
512 | i2c_del_driver(&i2c_driver_adv7170); | ||
513 | } | ||
514 | |||
515 | module_init(adv7170_init); | ||
516 | module_exit(adv7170_exit); | ||
diff --git a/drivers/media/video/adv7175.c b/drivers/media/video/adv7175.c index 8ee07a68f702..6008e84653f1 100644 --- a/drivers/media/video/adv7175.c +++ b/drivers/media/video/adv7175.c | |||
@@ -25,43 +25,24 @@ | |||
25 | */ | 25 | */ |
26 | 26 | ||
27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
28 | #include <linux/init.h> | ||
29 | #include <linux/delay.h> | ||
30 | #include <linux/errno.h> | ||
31 | #include <linux/fs.h> | ||
32 | #include <linux/kernel.h> | ||
33 | #include <linux/major.h> | ||
34 | #include <linux/slab.h> | ||
35 | #include <linux/mm.h> | ||
36 | #include <linux/signal.h> | ||
37 | #include <linux/types.h> | 28 | #include <linux/types.h> |
38 | #include <linux/i2c.h> | 29 | #include <linux/ioctl.h> |
39 | #include <asm/io.h> | ||
40 | #include <asm/pgtable.h> | ||
41 | #include <asm/page.h> | ||
42 | #include <asm/uaccess.h> | 30 | #include <asm/uaccess.h> |
43 | 31 | #include <linux/i2c.h> | |
32 | #include <linux/i2c-id.h> | ||
44 | #include <linux/videodev.h> | 33 | #include <linux/videodev.h> |
45 | #include <linux/video_encoder.h> | 34 | #include <linux/video_encoder.h> |
35 | #include <media/v4l2-common.h> | ||
36 | #include <media/v4l2-i2c-drv-legacy.h> | ||
46 | 37 | ||
47 | MODULE_DESCRIPTION("Analog Devices ADV7175 video encoder driver"); | 38 | MODULE_DESCRIPTION("Analog Devices ADV7175 video encoder driver"); |
48 | MODULE_AUTHOR("Dave Perks"); | 39 | MODULE_AUTHOR("Dave Perks"); |
49 | MODULE_LICENSE("GPL"); | 40 | MODULE_LICENSE("GPL"); |
50 | 41 | ||
51 | |||
52 | #define I2C_NAME(s) (s)->name | ||
53 | |||
54 | |||
55 | static int debug; | 42 | static int debug; |
56 | module_param(debug, int, 0); | 43 | module_param(debug, int, 0); |
57 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); | 44 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); |
58 | 45 | ||
59 | #define dprintk(num, format, args...) \ | ||
60 | do { \ | ||
61 | if (debug >= num) \ | ||
62 | printk(format, ##args); \ | ||
63 | } while (0) | ||
64 | |||
65 | /* ----------------------------------------------------------------------- */ | 46 | /* ----------------------------------------------------------------------- */ |
66 | 47 | ||
67 | struct adv7175 { | 48 | struct adv7175 { |
@@ -77,33 +58,23 @@ struct adv7175 { | |||
77 | #define I2C_ADV7175 0xd4 | 58 | #define I2C_ADV7175 0xd4 |
78 | #define I2C_ADV7176 0x54 | 59 | #define I2C_ADV7176 0x54 |
79 | 60 | ||
80 | static char adv7175_name[] = "adv7175"; | ||
81 | static char adv7176_name[] = "adv7176"; | ||
82 | |||
83 | static char *inputs[] = { "pass_through", "play_back", "color_bar" }; | 61 | static char *inputs[] = { "pass_through", "play_back", "color_bar" }; |
84 | static char *norms[] = { "PAL", "NTSC", "SECAM->PAL (may not work!)" }; | 62 | static char *norms[] = { "PAL", "NTSC", "SECAM->PAL (may not work!)" }; |
85 | 63 | ||
86 | /* ----------------------------------------------------------------------- */ | 64 | /* ----------------------------------------------------------------------- */ |
87 | 65 | ||
88 | static inline int | 66 | static inline int adv7175_write(struct i2c_client *client, u8 reg, u8 value) |
89 | adv7175_write (struct i2c_client *client, | ||
90 | u8 reg, | ||
91 | u8 value) | ||
92 | { | 67 | { |
93 | return i2c_smbus_write_byte_data(client, reg, value); | 68 | return i2c_smbus_write_byte_data(client, reg, value); |
94 | } | 69 | } |
95 | 70 | ||
96 | static inline int | 71 | static inline int adv7175_read(struct i2c_client *client, u8 reg) |
97 | adv7175_read (struct i2c_client *client, | ||
98 | u8 reg) | ||
99 | { | 72 | { |
100 | return i2c_smbus_read_byte_data(client, reg); | 73 | return i2c_smbus_read_byte_data(client, reg); |
101 | } | 74 | } |
102 | 75 | ||
103 | static int | 76 | static int adv7175_write_block(struct i2c_client *client, |
104 | adv7175_write_block (struct i2c_client *client, | 77 | const u8 *data, unsigned int len) |
105 | const u8 *data, | ||
106 | unsigned int len) | ||
107 | { | 78 | { |
108 | int ret = -1; | 79 | int ret = -1; |
109 | u8 reg; | 80 | u8 reg; |
@@ -123,18 +94,17 @@ adv7175_write_block (struct i2c_client *client, | |||
123 | reg++; | 94 | reg++; |
124 | len -= 2; | 95 | len -= 2; |
125 | data += 2; | 96 | data += 2; |
126 | } while (len >= 2 && data[0] == reg && | 97 | } while (len >= 2 && data[0] == reg && block_len < 32); |
127 | block_len < 32); | 98 | ret = i2c_master_send(client, block_data, block_len); |
128 | if ((ret = i2c_master_send(client, block_data, | 99 | if (ret < 0) |
129 | block_len)) < 0) | ||
130 | break; | 100 | break; |
131 | } | 101 | } |
132 | } else { | 102 | } else { |
133 | /* do some slow I2C emulation kind of thing */ | 103 | /* do some slow I2C emulation kind of thing */ |
134 | while (len >= 2) { | 104 | while (len >= 2) { |
135 | reg = *data++; | 105 | reg = *data++; |
136 | if ((ret = adv7175_write(client, reg, | 106 | ret = adv7175_write(client, reg, *data++); |
137 | *data++)) < 0) | 107 | if (ret < 0) |
138 | break; | 108 | break; |
139 | len -= 2; | 109 | len -= 2; |
140 | } | 110 | } |
@@ -143,13 +113,11 @@ adv7175_write_block (struct i2c_client *client, | |||
143 | return ret; | 113 | return ret; |
144 | } | 114 | } |
145 | 115 | ||
146 | static void | 116 | static void set_subcarrier_freq(struct i2c_client *client, int pass_through) |
147 | set_subcarrier_freq (struct i2c_client *client, | ||
148 | int pass_through) | ||
149 | { | 117 | { |
150 | /* for some reason pass_through NTSC needs | 118 | /* for some reason pass_through NTSC needs |
151 | * a different sub-carrier freq to remain stable. */ | 119 | * a different sub-carrier freq to remain stable. */ |
152 | if(pass_through) | 120 | if (pass_through) |
153 | adv7175_write(client, 0x02, 0x00); | 121 | adv7175_write(client, 0x02, 0x00); |
154 | else | 122 | else |
155 | adv7175_write(client, 0x02, 0x55); | 123 | adv7175_write(client, 0x02, 0x55); |
@@ -160,12 +128,12 @@ set_subcarrier_freq (struct i2c_client *client, | |||
160 | } | 128 | } |
161 | 129 | ||
162 | /* ----------------------------------------------------------------------- */ | 130 | /* ----------------------------------------------------------------------- */ |
163 | // Output filter: S-Video Composite | 131 | /* Output filter: S-Video Composite */ |
164 | 132 | ||
165 | #define MR050 0x11 //0x09 | 133 | #define MR050 0x11 /* 0x09 */ |
166 | #define MR060 0x14 //0x0c | 134 | #define MR060 0x14 /* 0x0c */ |
167 | 135 | ||
168 | //--------------------------------------------------------------------------- | 136 | /* ----------------------------------------------------------------------- */ |
169 | 137 | ||
170 | #define TR0MODE 0x46 | 138 | #define TR0MODE 0x46 |
171 | #define TR0RST 0x80 | 139 | #define TR0RST 0x80 |
@@ -216,15 +184,11 @@ static const unsigned char init_ntsc[] = { | |||
216 | 0x06, 0x1a, /* subc. phase */ | 184 | 0x06, 0x1a, /* subc. phase */ |
217 | }; | 185 | }; |
218 | 186 | ||
219 | static int | 187 | static int adv7175_command(struct i2c_client *client, unsigned cmd, void *arg) |
220 | adv7175_command (struct i2c_client *client, | ||
221 | unsigned int cmd, | ||
222 | void *arg) | ||
223 | { | 188 | { |
224 | struct adv7175 *encoder = i2c_get_clientdata(client); | 189 | struct adv7175 *encoder = i2c_get_clientdata(client); |
225 | 190 | ||
226 | switch (cmd) { | 191 | switch (cmd) { |
227 | |||
228 | case 0: | 192 | case 0: |
229 | /* This is just for testing!!! */ | 193 | /* This is just for testing!!! */ |
230 | adv7175_write_block(client, init_common, | 194 | adv7175_write_block(client, init_common, |
@@ -242,15 +206,14 @@ adv7175_command (struct i2c_client *client, | |||
242 | VIDEO_ENCODER_SECAM; /* well, hacky */ | 206 | VIDEO_ENCODER_SECAM; /* well, hacky */ |
243 | cap->inputs = 2; | 207 | cap->inputs = 2; |
244 | cap->outputs = 1; | 208 | cap->outputs = 1; |
245 | } | ||
246 | break; | 209 | break; |
210 | } | ||
247 | 211 | ||
248 | case ENCODER_SET_NORM: | 212 | case ENCODER_SET_NORM: |
249 | { | 213 | { |
250 | int iarg = *(int *) arg; | 214 | int iarg = *(int *) arg; |
251 | 215 | ||
252 | switch (iarg) { | 216 | switch (iarg) { |
253 | |||
254 | case VIDEO_MODE_NTSC: | 217 | case VIDEO_MODE_NTSC: |
255 | adv7175_write_block(client, init_ntsc, | 218 | adv7175_write_block(client, init_ntsc, |
256 | sizeof(init_ntsc)); | 219 | sizeof(init_ntsc)); |
@@ -284,16 +247,13 @@ adv7175_command (struct i2c_client *client, | |||
284 | adv7175_write(client, 0x07, TR0MODE); | 247 | adv7175_write(client, 0x07, TR0MODE); |
285 | break; | 248 | break; |
286 | default: | 249 | default: |
287 | dprintk(1, KERN_ERR "%s: illegal norm: %d\n", | 250 | v4l_dbg(1, debug, client, "illegal norm: %d\n", iarg); |
288 | I2C_NAME(client), iarg); | ||
289 | return -EINVAL; | 251 | return -EINVAL; |
290 | |||
291 | } | 252 | } |
292 | dprintk(1, KERN_INFO "%s: switched to %s\n", I2C_NAME(client), | 253 | v4l_dbg(1, debug, client, "switched to %s\n", norms[iarg]); |
293 | norms[iarg]); | ||
294 | encoder->norm = iarg; | 254 | encoder->norm = iarg; |
295 | } | ||
296 | break; | 255 | break; |
256 | } | ||
297 | 257 | ||
298 | case ENCODER_SET_INPUT: | 258 | case ENCODER_SET_INPUT: |
299 | { | 259 | { |
@@ -304,7 +264,6 @@ adv7175_command (struct i2c_client *client, | |||
304 | *iarg = 2: color bar */ | 264 | *iarg = 2: color bar */ |
305 | 265 | ||
306 | switch (iarg) { | 266 | switch (iarg) { |
307 | |||
308 | case 0: | 267 | case 0: |
309 | adv7175_write(client, 0x01, 0x00); | 268 | adv7175_write(client, 0x01, 0x00); |
310 | 269 | ||
@@ -331,7 +290,7 @@ adv7175_command (struct i2c_client *client, | |||
331 | adv7175_write(client, 0x0d, 0x49); | 290 | adv7175_write(client, 0x0d, 0x49); |
332 | adv7175_write(client, 0x07, TR0MODE | TR0RST); | 291 | adv7175_write(client, 0x07, TR0MODE | TR0RST); |
333 | adv7175_write(client, 0x07, TR0MODE); | 292 | adv7175_write(client, 0x07, TR0MODE); |
334 | //udelay(10); | 293 | /* udelay(10); */ |
335 | break; | 294 | break; |
336 | 295 | ||
337 | case 2: | 296 | case 2: |
@@ -343,39 +302,35 @@ adv7175_command (struct i2c_client *client, | |||
343 | adv7175_write(client, 0x0d, 0x49); | 302 | adv7175_write(client, 0x0d, 0x49); |
344 | adv7175_write(client, 0x07, TR0MODE | TR0RST); | 303 | adv7175_write(client, 0x07, TR0MODE | TR0RST); |
345 | adv7175_write(client, 0x07, TR0MODE); | 304 | adv7175_write(client, 0x07, TR0MODE); |
346 | //udelay(10); | 305 | /* udelay(10); */ |
347 | break; | 306 | break; |
348 | 307 | ||
349 | default: | 308 | default: |
350 | dprintk(1, KERN_ERR "%s: illegal input: %d\n", | 309 | v4l_dbg(1, debug, client, "illegal input: %d\n", iarg); |
351 | I2C_NAME(client), iarg); | ||
352 | return -EINVAL; | 310 | return -EINVAL; |
353 | |||
354 | } | 311 | } |
355 | dprintk(1, KERN_INFO "%s: switched to %s\n", I2C_NAME(client), | 312 | v4l_dbg(1, debug, client, "switched to %s\n", inputs[iarg]); |
356 | inputs[iarg]); | ||
357 | encoder->input = iarg; | 313 | encoder->input = iarg; |
358 | } | ||
359 | break; | 314 | break; |
315 | } | ||
360 | 316 | ||
361 | case ENCODER_SET_OUTPUT: | 317 | case ENCODER_SET_OUTPUT: |
362 | { | 318 | { |
363 | int *iarg = arg; | 319 | int *iarg = arg; |
364 | 320 | ||
365 | /* not much choice of outputs */ | 321 | /* not much choice of outputs */ |
366 | if (*iarg != 0) { | 322 | if (*iarg != 0) |
367 | return -EINVAL; | 323 | return -EINVAL; |
368 | } | ||
369 | } | ||
370 | break; | 324 | break; |
325 | } | ||
371 | 326 | ||
372 | case ENCODER_ENABLE_OUTPUT: | 327 | case ENCODER_ENABLE_OUTPUT: |
373 | { | 328 | { |
374 | int *iarg = arg; | 329 | int *iarg = arg; |
375 | 330 | ||
376 | encoder->enable = !!*iarg; | 331 | encoder->enable = !!*iarg; |
377 | } | ||
378 | break; | 332 | break; |
333 | } | ||
379 | 334 | ||
380 | default: | 335 | default: |
381 | return -EINVAL; | 336 | return -EINVAL; |
@@ -390,145 +345,67 @@ adv7175_command (struct i2c_client *client, | |||
390 | * Generic i2c probe | 345 | * Generic i2c probe |
391 | * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1' | 346 | * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1' |
392 | */ | 347 | */ |
393 | static unsigned short normal_i2c[] = | 348 | static unsigned short normal_i2c[] = { |
394 | { I2C_ADV7175 >> 1, (I2C_ADV7175 >> 1) + 1, | 349 | I2C_ADV7175 >> 1, (I2C_ADV7175 >> 1) + 1, |
395 | I2C_ADV7176 >> 1, (I2C_ADV7176 >> 1) + 1, | 350 | I2C_ADV7176 >> 1, (I2C_ADV7176 >> 1) + 1, |
396 | I2C_CLIENT_END | 351 | I2C_CLIENT_END |
397 | }; | 352 | }; |
398 | 353 | ||
399 | static unsigned short ignore = I2C_CLIENT_END; | 354 | I2C_CLIENT_INSMOD; |
400 | |||
401 | static struct i2c_client_address_data addr_data = { | ||
402 | .normal_i2c = normal_i2c, | ||
403 | .probe = &ignore, | ||
404 | .ignore = &ignore, | ||
405 | }; | ||
406 | |||
407 | static struct i2c_driver i2c_driver_adv7175; | ||
408 | 355 | ||
409 | static int | 356 | static int adv7175_probe(struct i2c_client *client, |
410 | adv7175_detect_client (struct i2c_adapter *adapter, | 357 | const struct i2c_device_id *id) |
411 | int address, | ||
412 | int kind) | ||
413 | { | 358 | { |
414 | int i; | 359 | int i; |
415 | struct i2c_client *client; | ||
416 | struct adv7175 *encoder; | 360 | struct adv7175 *encoder; |
417 | char *dname; | ||
418 | |||
419 | dprintk(1, | ||
420 | KERN_INFO | ||
421 | "adv7175.c: detecting adv7175 client on address 0x%x\n", | ||
422 | address << 1); | ||
423 | 361 | ||
424 | /* Check if the adapter supports the needed features */ | 362 | /* Check if the adapter supports the needed features */ |
425 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | 363 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) |
426 | return 0; | 364 | return -ENODEV; |
427 | 365 | ||
428 | client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); | 366 | v4l_info(client, "chip found @ 0x%x (%s)\n", |
429 | if (!client) | 367 | client->addr << 1, client->adapter->name); |
430 | return -ENOMEM; | ||
431 | client->addr = address; | ||
432 | client->adapter = adapter; | ||
433 | client->driver = &i2c_driver_adv7175; | ||
434 | if ((client->addr == I2C_ADV7175 >> 1) || | ||
435 | (client->addr == (I2C_ADV7175 >> 1) + 1)) { | ||
436 | dname = adv7175_name; | ||
437 | } else if ((client->addr == I2C_ADV7176 >> 1) || | ||
438 | (client->addr == (I2C_ADV7176 >> 1) + 1)) { | ||
439 | dname = adv7176_name; | ||
440 | } else { | ||
441 | /* We should never get here!!! */ | ||
442 | kfree(client); | ||
443 | return 0; | ||
444 | } | ||
445 | strlcpy(I2C_NAME(client), dname, sizeof(I2C_NAME(client))); | ||
446 | 368 | ||
447 | encoder = kzalloc(sizeof(struct adv7175), GFP_KERNEL); | 369 | encoder = kzalloc(sizeof(struct adv7175), GFP_KERNEL); |
448 | if (encoder == NULL) { | 370 | if (encoder == NULL) |
449 | kfree(client); | ||
450 | return -ENOMEM; | 371 | return -ENOMEM; |
451 | } | ||
452 | encoder->norm = VIDEO_MODE_PAL; | 372 | encoder->norm = VIDEO_MODE_PAL; |
453 | encoder->input = 0; | 373 | encoder->input = 0; |
454 | encoder->enable = 1; | 374 | encoder->enable = 1; |
455 | i2c_set_clientdata(client, encoder); | 375 | i2c_set_clientdata(client, encoder); |
456 | 376 | ||
457 | i = i2c_attach_client(client); | ||
458 | if (i) { | ||
459 | kfree(client); | ||
460 | kfree(encoder); | ||
461 | return i; | ||
462 | } | ||
463 | |||
464 | i = adv7175_write_block(client, init_common, sizeof(init_common)); | 377 | i = adv7175_write_block(client, init_common, sizeof(init_common)); |
465 | if (i >= 0) { | 378 | if (i >= 0) { |
466 | i = adv7175_write(client, 0x07, TR0MODE | TR0RST); | 379 | i = adv7175_write(client, 0x07, TR0MODE | TR0RST); |
467 | i = adv7175_write(client, 0x07, TR0MODE); | 380 | i = adv7175_write(client, 0x07, TR0MODE); |
468 | i = adv7175_read(client, 0x12); | 381 | i = adv7175_read(client, 0x12); |
469 | dprintk(1, KERN_INFO "%s_attach: rev. %d at 0x%x\n", | 382 | v4l_dbg(1, debug, client, "revision %d\n", i & 1); |
470 | I2C_NAME(client), i & 1, client->addr << 1); | ||
471 | } | 383 | } |
472 | if (i < 0) { | 384 | if (i < 0) |
473 | dprintk(1, KERN_ERR "%s_attach: init error 0x%x\n", | 385 | v4l_dbg(1, debug, client, "init error 0x%x\n", i); |
474 | I2C_NAME(client), i); | ||
475 | } | ||
476 | |||
477 | return 0; | 386 | return 0; |
478 | } | 387 | } |
479 | 388 | ||
480 | static int | 389 | static int adv7175_remove(struct i2c_client *client) |
481 | adv7175_attach_adapter (struct i2c_adapter *adapter) | ||
482 | { | ||
483 | dprintk(1, | ||
484 | KERN_INFO | ||
485 | "adv7175.c: starting probe for adapter %s (0x%x)\n", | ||
486 | I2C_NAME(adapter), adapter->id); | ||
487 | return i2c_probe(adapter, &addr_data, &adv7175_detect_client); | ||
488 | } | ||
489 | |||
490 | static int | ||
491 | adv7175_detach_client (struct i2c_client *client) | ||
492 | { | 390 | { |
493 | struct adv7175 *encoder = i2c_get_clientdata(client); | 391 | kfree(i2c_get_clientdata(client)); |
494 | int err; | ||
495 | |||
496 | err = i2c_detach_client(client); | ||
497 | if (err) { | ||
498 | return err; | ||
499 | } | ||
500 | |||
501 | kfree(encoder); | ||
502 | kfree(client); | ||
503 | |||
504 | return 0; | 392 | return 0; |
505 | } | 393 | } |
506 | 394 | ||
507 | /* ----------------------------------------------------------------------- */ | 395 | /* ----------------------------------------------------------------------- */ |
508 | 396 | ||
509 | static struct i2c_driver i2c_driver_adv7175 = { | 397 | static const struct i2c_device_id adv7175_id[] = { |
510 | .driver = { | 398 | { "adv7175", 0 }, |
511 | .name = "adv7175", /* name */ | 399 | { "adv7176", 0 }, |
512 | }, | 400 | { } |
513 | 401 | }; | |
514 | .id = I2C_DRIVERID_ADV7175, | 402 | MODULE_DEVICE_TABLE(i2c, adv7175_id); |
515 | 403 | ||
516 | .attach_adapter = adv7175_attach_adapter, | 404 | static struct v4l2_i2c_driver_data v4l2_i2c_data = { |
517 | .detach_client = adv7175_detach_client, | 405 | .name = "adv7175", |
406 | .driverid = I2C_DRIVERID_ADV7175, | ||
518 | .command = adv7175_command, | 407 | .command = adv7175_command, |
408 | .probe = adv7175_probe, | ||
409 | .remove = adv7175_remove, | ||
410 | .id_table = adv7175_id, | ||
519 | }; | 411 | }; |
520 | |||
521 | static int __init | ||
522 | adv7175_init (void) | ||
523 | { | ||
524 | return i2c_add_driver(&i2c_driver_adv7175); | ||
525 | } | ||
526 | |||
527 | static void __exit | ||
528 | adv7175_exit (void) | ||
529 | { | ||
530 | i2c_del_driver(&i2c_driver_adv7175); | ||
531 | } | ||
532 | |||
533 | module_init(adv7175_init); | ||
534 | module_exit(adv7175_exit); | ||
diff --git a/drivers/media/video/au0828/au0828-cards.c b/drivers/media/video/au0828/au0828-cards.c index 5f07a8a072b6..d60123b413f5 100644 --- a/drivers/media/video/au0828/au0828-cards.c +++ b/drivers/media/video/au0828/au0828-cards.c | |||
@@ -90,6 +90,7 @@ static void hauppauge_eeprom(struct au0828_dev *dev, u8 *eeprom_data) | |||
90 | case 72221: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and basic analog video */ | 90 | case 72221: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and basic analog video */ |
91 | case 72231: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and basic analog video */ | 91 | case 72231: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and basic analog video */ |
92 | case 72241: /* WinTV-HVR950q (OEM, No IR, ATSC/QAM and basic analog video */ | 92 | case 72241: /* WinTV-HVR950q (OEM, No IR, ATSC/QAM and basic analog video */ |
93 | case 72251: /* WinTV-HVR950q (Retail, IR, ATSC/QAM and basic analog video */ | ||
93 | case 72301: /* WinTV-HVR850 (Retail, IR, ATSC and basic analog video */ | 94 | case 72301: /* WinTV-HVR850 (Retail, IR, ATSC and basic analog video */ |
94 | case 72500: /* WinTV-HVR950q (OEM, No IR, ATSC/QAM */ | 95 | case 72500: /* WinTV-HVR950q (OEM, No IR, ATSC/QAM */ |
95 | break; | 96 | break; |
@@ -185,7 +186,7 @@ void au0828_gpio_setup(struct au0828_dev *dev) | |||
185 | } | 186 | } |
186 | 187 | ||
187 | /* table of devices that work with this driver */ | 188 | /* table of devices that work with this driver */ |
188 | struct usb_device_id au0828_usb_id_table [] = { | 189 | struct usb_device_id au0828_usb_id_table[] = { |
189 | { USB_DEVICE(0x2040, 0x7200), | 190 | { USB_DEVICE(0x2040, 0x7200), |
190 | .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q }, | 191 | .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q }, |
191 | { USB_DEVICE(0x2040, 0x7240), | 192 | { USB_DEVICE(0x2040, 0x7240), |
@@ -198,6 +199,8 @@ struct usb_device_id au0828_usb_id_table [] = { | |||
198 | .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q }, | 199 | .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q }, |
199 | { USB_DEVICE(0x2040, 0x721b), | 200 | { USB_DEVICE(0x2040, 0x721b), |
200 | .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q }, | 201 | .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q }, |
202 | { USB_DEVICE(0x2040, 0x721e), | ||
203 | .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q }, | ||
201 | { USB_DEVICE(0x2040, 0x721f), | 204 | { USB_DEVICE(0x2040, 0x721f), |
202 | .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q }, | 205 | .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q }, |
203 | { USB_DEVICE(0x2040, 0x7280), | 206 | { USB_DEVICE(0x2040, 0x7280), |
diff --git a/drivers/media/video/au0828/au0828-core.c b/drivers/media/video/au0828/au0828-core.c index d856de9f742f..5765e8656376 100644 --- a/drivers/media/video/au0828/au0828-core.c +++ b/drivers/media/video/au0828/au0828-core.c | |||
@@ -91,7 +91,8 @@ static int send_control_msg(struct au0828_dev *dev, u16 request, u32 value, | |||
91 | status = usb_control_msg(dev->usbdev, | 91 | status = usb_control_msg(dev->usbdev, |
92 | usb_sndctrlpipe(dev->usbdev, 0), | 92 | usb_sndctrlpipe(dev->usbdev, 0), |
93 | request, | 93 | request, |
94 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 94 | USB_DIR_OUT | USB_TYPE_VENDOR | |
95 | USB_RECIP_DEVICE, | ||
95 | value, index, | 96 | value, index, |
96 | cp, size, 1000); | 97 | cp, size, 1000); |
97 | 98 | ||
diff --git a/drivers/media/video/au0828/au0828-dvb.c b/drivers/media/video/au0828/au0828-dvb.c index f0fcdb4769d7..a882cf546d0a 100644 --- a/drivers/media/video/au0828/au0828-dvb.c +++ b/drivers/media/video/au0828/au0828-dvb.c | |||
@@ -173,7 +173,8 @@ static int start_urb_transfer(struct au0828_dev *dev) | |||
173 | purb->status = -EINPROGRESS; | 173 | purb->status = -EINPROGRESS; |
174 | usb_fill_bulk_urb(purb, | 174 | usb_fill_bulk_urb(purb, |
175 | dev->usbdev, | 175 | dev->usbdev, |
176 | usb_rcvbulkpipe(dev->usbdev, _AU0828_BULKPIPE), | 176 | usb_rcvbulkpipe(dev->usbdev, |
177 | _AU0828_BULKPIPE), | ||
177 | purb->transfer_buffer, | 178 | purb->transfer_buffer, |
178 | URB_BUFSIZE, | 179 | URB_BUFSIZE, |
179 | urb_completion, | 180 | urb_completion, |
diff --git a/drivers/media/video/bt819.c b/drivers/media/video/bt819.c index ddd2a7964dec..a07b7b88e5b8 100644 --- a/drivers/media/video/bt819.c +++ b/drivers/media/video/bt819.c | |||
@@ -29,44 +29,25 @@ | |||
29 | */ | 29 | */ |
30 | 30 | ||
31 | #include <linux/module.h> | 31 | #include <linux/module.h> |
32 | #include <linux/init.h> | ||
33 | #include <linux/delay.h> | 32 | #include <linux/delay.h> |
34 | #include <linux/errno.h> | ||
35 | #include <linux/fs.h> | ||
36 | #include <linux/kernel.h> | ||
37 | #include <linux/major.h> | ||
38 | #include <linux/slab.h> | ||
39 | #include <linux/mm.h> | ||
40 | #include <linux/signal.h> | ||
41 | #include <linux/types.h> | 33 | #include <linux/types.h> |
42 | #include <linux/i2c.h> | 34 | #include <linux/ioctl.h> |
43 | #include <asm/io.h> | ||
44 | #include <asm/pgtable.h> | ||
45 | #include <asm/page.h> | ||
46 | #include <asm/uaccess.h> | 35 | #include <asm/uaccess.h> |
47 | 36 | #include <linux/i2c.h> | |
37 | #include <linux/i2c-id.h> | ||
48 | #include <linux/videodev.h> | 38 | #include <linux/videodev.h> |
49 | #include <linux/video_decoder.h> | 39 | #include <linux/video_decoder.h> |
50 | 40 | #include <media/v4l2-common.h> | |
41 | #include <media/v4l2-i2c-drv-legacy.h> | ||
51 | 42 | ||
52 | MODULE_DESCRIPTION("Brooktree-819 video decoder driver"); | 43 | MODULE_DESCRIPTION("Brooktree-819 video decoder driver"); |
53 | MODULE_AUTHOR("Mike Bernson & Dave Perks"); | 44 | MODULE_AUTHOR("Mike Bernson & Dave Perks"); |
54 | MODULE_LICENSE("GPL"); | 45 | MODULE_LICENSE("GPL"); |
55 | 46 | ||
56 | |||
57 | #define I2C_NAME(s) (s)->name | ||
58 | |||
59 | |||
60 | static int debug; | 47 | static int debug; |
61 | module_param(debug, int, 0); | 48 | module_param(debug, int, 0); |
62 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); | 49 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); |
63 | 50 | ||
64 | #define dprintk(num, format, args...) \ | ||
65 | do { \ | ||
66 | if (debug >= num) \ | ||
67 | printk(format, ##args); \ | ||
68 | } while (0) | ||
69 | |||
70 | /* ----------------------------------------------------------------------- */ | 51 | /* ----------------------------------------------------------------------- */ |
71 | 52 | ||
72 | struct bt819 { | 53 | struct bt819 { |
@@ -97,14 +78,9 @@ static struct timing timing_data[] = { | |||
97 | {858 - 24, 20, 525 - 2, 1, 0x00f8, 0x0000}, | 78 | {858 - 24, 20, 525 - 2, 1, 0x00f8, 0x0000}, |
98 | }; | 79 | }; |
99 | 80 | ||
100 | #define I2C_BT819 0x8a | ||
101 | |||
102 | /* ----------------------------------------------------------------------- */ | 81 | /* ----------------------------------------------------------------------- */ |
103 | 82 | ||
104 | static inline int | 83 | static inline int bt819_write(struct i2c_client *client, u8 reg, u8 value) |
105 | bt819_write (struct i2c_client *client, | ||
106 | u8 reg, | ||
107 | u8 value) | ||
108 | { | 84 | { |
109 | struct bt819 *decoder = i2c_get_clientdata(client); | 85 | struct bt819 *decoder = i2c_get_clientdata(client); |
110 | 86 | ||
@@ -112,24 +88,15 @@ bt819_write (struct i2c_client *client, | |||
112 | return i2c_smbus_write_byte_data(client, reg, value); | 88 | return i2c_smbus_write_byte_data(client, reg, value); |
113 | } | 89 | } |
114 | 90 | ||
115 | static inline int | 91 | static inline int bt819_setbit(struct i2c_client *client, u8 reg, u8 bit, u8 value) |
116 | bt819_setbit (struct i2c_client *client, | ||
117 | u8 reg, | ||
118 | u8 bit, | ||
119 | u8 value) | ||
120 | { | 92 | { |
121 | struct bt819 *decoder = i2c_get_clientdata(client); | 93 | struct bt819 *decoder = i2c_get_clientdata(client); |
122 | 94 | ||
123 | return bt819_write(client, reg, | 95 | return bt819_write(client, reg, |
124 | (decoder-> | 96 | (decoder->reg[reg] & ~(1 << bit)) | (value ? (1 << bit) : 0)); |
125 | reg[reg] & ~(1 << bit)) | | ||
126 | (value ? (1 << bit) : 0)); | ||
127 | } | 97 | } |
128 | 98 | ||
129 | static int | 99 | static int bt819_write_block(struct i2c_client *client, const u8 *data, unsigned int len) |
130 | bt819_write_block (struct i2c_client *client, | ||
131 | const u8 *data, | ||
132 | unsigned int len) | ||
133 | { | 100 | { |
134 | int ret = -1; | 101 | int ret = -1; |
135 | u8 reg; | 102 | u8 reg; |
@@ -150,10 +117,9 @@ bt819_write_block (struct i2c_client *client, | |||
150 | decoder->reg[reg++] = data[1]; | 117 | decoder->reg[reg++] = data[1]; |
151 | len -= 2; | 118 | len -= 2; |
152 | data += 2; | 119 | data += 2; |
153 | } while (len >= 2 && data[0] == reg && | 120 | } while (len >= 2 && data[0] == reg && block_len < 32); |
154 | block_len < 32); | 121 | ret = i2c_master_send(client, block_data, block_len); |
155 | if ((ret = i2c_master_send(client, block_data, | 122 | if (ret < 0) |
156 | block_len)) < 0) | ||
157 | break; | 123 | break; |
158 | } | 124 | } |
159 | } else { | 125 | } else { |
@@ -169,20 +135,17 @@ bt819_write_block (struct i2c_client *client, | |||
169 | return ret; | 135 | return ret; |
170 | } | 136 | } |
171 | 137 | ||
172 | static inline int | 138 | static inline int bt819_read(struct i2c_client *client, u8 reg) |
173 | bt819_read (struct i2c_client *client, | ||
174 | u8 reg) | ||
175 | { | 139 | { |
176 | return i2c_smbus_read_byte_data(client, reg); | 140 | return i2c_smbus_read_byte_data(client, reg); |
177 | } | 141 | } |
178 | 142 | ||
179 | static int | 143 | static int bt819_init(struct i2c_client *client) |
180 | bt819_init (struct i2c_client *client) | ||
181 | { | 144 | { |
182 | struct bt819 *decoder = i2c_get_clientdata(client); | 145 | struct bt819 *decoder = i2c_get_clientdata(client); |
183 | 146 | ||
184 | static unsigned char init[] = { | 147 | static unsigned char init[] = { |
185 | //0x1f, 0x00, /* Reset */ | 148 | /*0x1f, 0x00,*/ /* Reset */ |
186 | 0x01, 0x59, /* 0x01 input format */ | 149 | 0x01, 0x59, /* 0x01 input format */ |
187 | 0x02, 0x00, /* 0x02 temporal decimation */ | 150 | 0x02, 0x00, /* 0x02 temporal decimation */ |
188 | 0x03, 0x12, /* 0x03 Cropping msb */ | 151 | 0x03, 0x12, /* 0x03 Cropping msb */ |
@@ -218,12 +181,10 @@ bt819_init (struct i2c_client *client) | |||
218 | struct timing *timing = &timing_data[decoder->norm]; | 181 | struct timing *timing = &timing_data[decoder->norm]; |
219 | 182 | ||
220 | init[0x03 * 2 - 1] = | 183 | init[0x03 * 2 - 1] = |
221 | (((timing->vdelay >> 8) & 0x03) << 6) | (((timing-> | 184 | (((timing->vdelay >> 8) & 0x03) << 6) | |
222 | vactive >> 8) & | 185 | (((timing->vactive >> 8) & 0x03) << 4) | |
223 | 0x03) << 4) | | 186 | (((timing->hdelay >> 8) & 0x03) << 2) | |
224 | (((timing->hdelay >> 8) & 0x03) << 2) | ((timing-> | 187 | ((timing->hactive >> 8) & 0x03); |
225 | hactive >> 8) & | ||
226 | 0x03); | ||
227 | init[0x04 * 2 - 1] = timing->vdelay & 0xff; | 188 | init[0x04 * 2 - 1] = timing->vdelay & 0xff; |
228 | init[0x05 * 2 - 1] = timing->vactive & 0xff; | 189 | init[0x05 * 2 - 1] = timing->vactive & 0xff; |
229 | init[0x06 * 2 - 1] = timing->hdelay & 0xff; | 190 | init[0x06 * 2 - 1] = timing->hdelay & 0xff; |
@@ -238,27 +199,22 @@ bt819_init (struct i2c_client *client) | |||
238 | 199 | ||
239 | /* init */ | 200 | /* init */ |
240 | return bt819_write_block(client, init, sizeof(init)); | 201 | return bt819_write_block(client, init, sizeof(init)); |
241 | |||
242 | } | 202 | } |
243 | 203 | ||
244 | /* ----------------------------------------------------------------------- */ | 204 | /* ----------------------------------------------------------------------- */ |
245 | 205 | ||
246 | static int | 206 | static int bt819_command(struct i2c_client *client, unsigned cmd, void *arg) |
247 | bt819_command (struct i2c_client *client, | ||
248 | unsigned int cmd, | ||
249 | void *arg) | ||
250 | { | 207 | { |
251 | int temp; | 208 | int temp; |
252 | 209 | ||
253 | struct bt819 *decoder = i2c_get_clientdata(client); | 210 | struct bt819 *decoder = i2c_get_clientdata(client); |
254 | 211 | ||
255 | if (!decoder->initialized) { // First call to bt819_init could be | 212 | if (!decoder->initialized) { /* First call to bt819_init could be */ |
256 | bt819_init(client); // without #FRST = 0 | 213 | bt819_init(client); /* without #FRST = 0 */ |
257 | decoder->initialized = 1; | 214 | decoder->initialized = 1; |
258 | } | 215 | } |
259 | 216 | ||
260 | switch (cmd) { | 217 | switch (cmd) { |
261 | |||
262 | case 0: | 218 | case 0: |
263 | /* This is just for testing!!! */ | 219 | /* This is just for testing!!! */ |
264 | bt819_init(client); | 220 | bt819_init(client); |
@@ -274,8 +230,8 @@ bt819_command (struct i2c_client *client, | |||
274 | VIDEO_DECODER_CCIR; | 230 | VIDEO_DECODER_CCIR; |
275 | cap->inputs = 8; | 231 | cap->inputs = 8; |
276 | cap->outputs = 1; | 232 | cap->outputs = 1; |
277 | } | ||
278 | break; | 233 | break; |
234 | } | ||
279 | 235 | ||
280 | case DECODER_GET_STATUS: | 236 | case DECODER_GET_STATUS: |
281 | { | 237 | { |
@@ -285,9 +241,9 @@ bt819_command (struct i2c_client *client, | |||
285 | 241 | ||
286 | status = bt819_read(client, 0x00); | 242 | status = bt819_read(client, 0x00); |
287 | res = 0; | 243 | res = 0; |
288 | if ((status & 0x80)) { | 244 | if ((status & 0x80)) |
289 | res |= DECODER_STATUS_GOOD; | 245 | res |= DECODER_STATUS_GOOD; |
290 | } | 246 | |
291 | switch (decoder->norm) { | 247 | switch (decoder->norm) { |
292 | case VIDEO_MODE_NTSC: | 248 | case VIDEO_MODE_NTSC: |
293 | res |= DECODER_STATUS_NTSC; | 249 | res |= DECODER_STATUS_NTSC; |
@@ -297,28 +253,25 @@ bt819_command (struct i2c_client *client, | |||
297 | break; | 253 | break; |
298 | default: | 254 | default: |
299 | case VIDEO_MODE_AUTO: | 255 | case VIDEO_MODE_AUTO: |
300 | if ((status & 0x10)) { | 256 | if ((status & 0x10)) |
301 | res |= DECODER_STATUS_PAL; | 257 | res |= DECODER_STATUS_PAL; |
302 | } else { | 258 | else |
303 | res |= DECODER_STATUS_NTSC; | 259 | res |= DECODER_STATUS_NTSC; |
304 | } | ||
305 | break; | 260 | break; |
306 | } | 261 | } |
307 | res |= DECODER_STATUS_COLOR; | 262 | res |= DECODER_STATUS_COLOR; |
308 | *iarg = res; | 263 | *iarg = res; |
309 | 264 | ||
310 | dprintk(1, KERN_INFO "%s: get status %x\n", I2C_NAME(client), | 265 | v4l_dbg(1, debug, client, "get status %x\n", *iarg); |
311 | *iarg); | ||
312 | } | ||
313 | break; | 266 | break; |
267 | } | ||
314 | 268 | ||
315 | case DECODER_SET_NORM: | 269 | case DECODER_SET_NORM: |
316 | { | 270 | { |
317 | int *iarg = arg; | 271 | int *iarg = arg; |
318 | struct timing *timing = NULL; | 272 | struct timing *timing = NULL; |
319 | 273 | ||
320 | dprintk(1, KERN_INFO "%s: set norm %x\n", I2C_NAME(client), | 274 | v4l_dbg(1, debug, client, "set norm %x\n", *iarg); |
321 | *iarg); | ||
322 | 275 | ||
323 | switch (*iarg) { | 276 | switch (*iarg) { |
324 | case VIDEO_MODE_NTSC: | 277 | case VIDEO_MODE_NTSC: |
@@ -327,7 +280,7 @@ bt819_command (struct i2c_client *client, | |||
327 | bt819_setbit(client, 0x01, 5, 0); | 280 | bt819_setbit(client, 0x01, 5, 0); |
328 | bt819_write(client, 0x18, 0x68); | 281 | bt819_write(client, 0x18, 0x68); |
329 | bt819_write(client, 0x19, 0x5d); | 282 | bt819_write(client, 0x19, 0x5d); |
330 | //bt819_setbit(client, 0x1a, 5, 1); | 283 | /* bt819_setbit(client, 0x1a, 5, 1); */ |
331 | timing = &timing_data[VIDEO_MODE_NTSC]; | 284 | timing = &timing_data[VIDEO_MODE_NTSC]; |
332 | break; | 285 | break; |
333 | case VIDEO_MODE_PAL: | 286 | case VIDEO_MODE_PAL: |
@@ -336,7 +289,7 @@ bt819_command (struct i2c_client *client, | |||
336 | bt819_setbit(client, 0x01, 5, 1); | 289 | bt819_setbit(client, 0x01, 5, 1); |
337 | bt819_write(client, 0x18, 0x7f); | 290 | bt819_write(client, 0x18, 0x7f); |
338 | bt819_write(client, 0x19, 0x72); | 291 | bt819_write(client, 0x19, 0x72); |
339 | //bt819_setbit(client, 0x1a, 5, 0); | 292 | /* bt819_setbit(client, 0x1a, 5, 0); */ |
340 | timing = &timing_data[VIDEO_MODE_PAL]; | 293 | timing = &timing_data[VIDEO_MODE_PAL]; |
341 | break; | 294 | break; |
342 | case VIDEO_MODE_AUTO: | 295 | case VIDEO_MODE_AUTO: |
@@ -344,10 +297,7 @@ bt819_command (struct i2c_client *client, | |||
344 | bt819_setbit(client, 0x01, 1, 0); | 297 | bt819_setbit(client, 0x01, 1, 0); |
345 | break; | 298 | break; |
346 | default: | 299 | default: |
347 | dprintk(1, | 300 | v4l_dbg(1, debug, client, "unsupported norm %x\n", *iarg); |
348 | KERN_ERR | ||
349 | "%s: unsupported norm %d\n", | ||
350 | I2C_NAME(client), *iarg); | ||
351 | return -EINVAL; | 301 | return -EINVAL; |
352 | } | 302 | } |
353 | 303 | ||
@@ -366,19 +316,17 @@ bt819_command (struct i2c_client *client, | |||
366 | } | 316 | } |
367 | 317 | ||
368 | decoder->norm = *iarg; | 318 | decoder->norm = *iarg; |
369 | } | ||
370 | break; | 319 | break; |
320 | } | ||
371 | 321 | ||
372 | case DECODER_SET_INPUT: | 322 | case DECODER_SET_INPUT: |
373 | { | 323 | { |
374 | int *iarg = arg; | 324 | int *iarg = arg; |
375 | 325 | ||
376 | dprintk(1, KERN_INFO "%s: set input %x\n", I2C_NAME(client), | 326 | v4l_dbg(1, debug, client, "set input %x\n", *iarg); |
377 | *iarg); | ||
378 | 327 | ||
379 | if (*iarg < 0 || *iarg > 7) { | 328 | if (*iarg < 0 || *iarg > 7) |
380 | return -EINVAL; | 329 | return -EINVAL; |
381 | } | ||
382 | 330 | ||
383 | if (decoder->input != *iarg) { | 331 | if (decoder->input != *iarg) { |
384 | decoder->input = *iarg; | 332 | decoder->input = *iarg; |
@@ -391,52 +339,42 @@ bt819_command (struct i2c_client *client, | |||
391 | bt819_setbit(client, 0x1a, 1, 0); | 339 | bt819_setbit(client, 0x1a, 1, 0); |
392 | } | 340 | } |
393 | } | 341 | } |
394 | } | ||
395 | break; | 342 | break; |
343 | } | ||
396 | 344 | ||
397 | case DECODER_SET_OUTPUT: | 345 | case DECODER_SET_OUTPUT: |
398 | { | 346 | { |
399 | int *iarg = arg; | 347 | int *iarg = arg; |
400 | 348 | ||
401 | dprintk(1, KERN_INFO "%s: set output %x\n", I2C_NAME(client), | 349 | v4l_dbg(1, debug, client, "set output %x\n", *iarg); |
402 | *iarg); | ||
403 | 350 | ||
404 | /* not much choice of outputs */ | 351 | /* not much choice of outputs */ |
405 | if (*iarg != 0) { | 352 | if (*iarg != 0) |
406 | return -EINVAL; | 353 | return -EINVAL; |
407 | } | ||
408 | } | ||
409 | break; | 354 | break; |
355 | } | ||
410 | 356 | ||
411 | case DECODER_ENABLE_OUTPUT: | 357 | case DECODER_ENABLE_OUTPUT: |
412 | { | 358 | { |
413 | int *iarg = arg; | 359 | int *iarg = arg; |
414 | int enable = (*iarg != 0); | 360 | int enable = (*iarg != 0); |
415 | 361 | ||
416 | dprintk(1, KERN_INFO "%s: enable output %x\n", | 362 | v4l_dbg(1, debug, client, "enable output %x\n", *iarg); |
417 | I2C_NAME(client), *iarg); | ||
418 | 363 | ||
419 | if (decoder->enable != enable) { | 364 | if (decoder->enable != enable) { |
420 | decoder->enable = enable; | 365 | decoder->enable = enable; |
421 | 366 | bt819_setbit(client, 0x16, 7, !enable); | |
422 | if (decoder->enable) { | ||
423 | bt819_setbit(client, 0x16, 7, 0); | ||
424 | } else { | ||
425 | bt819_setbit(client, 0x16, 7, 1); | ||
426 | } | ||
427 | } | 367 | } |
428 | } | ||
429 | break; | 368 | break; |
369 | } | ||
430 | 370 | ||
431 | case DECODER_SET_PICTURE: | 371 | case DECODER_SET_PICTURE: |
432 | { | 372 | { |
433 | struct video_picture *pic = arg; | 373 | struct video_picture *pic = arg; |
434 | 374 | ||
435 | dprintk(1, | 375 | v4l_dbg(1, debug, client, |
436 | KERN_INFO | 376 | "set picture brightness %d contrast %d colour %d\n", |
437 | "%s: set picture brightness %d contrast %d colour %d\n", | 377 | pic->brightness, pic->contrast, pic->colour); |
438 | I2C_NAME(client), pic->brightness, pic->contrast, | ||
439 | pic->colour); | ||
440 | 378 | ||
441 | 379 | ||
442 | if (decoder->bright != pic->brightness) { | 380 | if (decoder->bright != pic->brightness) { |
@@ -474,8 +412,8 @@ bt819_command (struct i2c_client *client, | |||
474 | bt819_write(client, 0x0f, | 412 | bt819_write(client, 0x0f, |
475 | 128 - (decoder->hue >> 8)); | 413 | 128 - (decoder->hue >> 8)); |
476 | } | 414 | } |
477 | } | ||
478 | break; | 415 | break; |
416 | } | ||
479 | 417 | ||
480 | default: | 418 | default: |
481 | return -EINVAL; | 419 | return -EINVAL; |
@@ -486,55 +424,44 @@ bt819_command (struct i2c_client *client, | |||
486 | 424 | ||
487 | /* ----------------------------------------------------------------------- */ | 425 | /* ----------------------------------------------------------------------- */ |
488 | 426 | ||
489 | /* | 427 | static unsigned short normal_i2c[] = { 0x8a >> 1, I2C_CLIENT_END }; |
490 | * Generic i2c probe | ||
491 | * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1' | ||
492 | */ | ||
493 | static unsigned short normal_i2c[] = { | ||
494 | I2C_BT819 >> 1, | ||
495 | I2C_CLIENT_END, | ||
496 | }; | ||
497 | |||
498 | static unsigned short ignore = I2C_CLIENT_END; | ||
499 | |||
500 | static struct i2c_client_address_data addr_data = { | ||
501 | .normal_i2c = normal_i2c, | ||
502 | .probe = &ignore, | ||
503 | .ignore = &ignore, | ||
504 | }; | ||
505 | 428 | ||
506 | static struct i2c_driver i2c_driver_bt819; | 429 | I2C_CLIENT_INSMOD; |
507 | 430 | ||
508 | static int | 431 | static int bt819_probe(struct i2c_client *client, |
509 | bt819_detect_client (struct i2c_adapter *adapter, | 432 | const struct i2c_device_id *id) |
510 | int address, | ||
511 | int kind) | ||
512 | { | 433 | { |
513 | int i, id; | 434 | int i, ver; |
514 | struct bt819 *decoder; | 435 | struct bt819 *decoder; |
515 | struct i2c_client *client; | 436 | const char *name; |
516 | |||
517 | dprintk(1, | ||
518 | KERN_INFO | ||
519 | "bt819: detecting bt819 client on address 0x%x\n", | ||
520 | address << 1); | ||
521 | 437 | ||
522 | /* Check if the adapter supports the needed features */ | 438 | /* Check if the adapter supports the needed features */ |
523 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | 439 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) |
524 | return 0; | 440 | return -ENODEV; |
525 | 441 | ||
526 | client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); | 442 | ver = bt819_read(client, 0x17); |
527 | if (!client) | 443 | switch (ver & 0xf0) { |
528 | return -ENOMEM; | 444 | case 0x70: |
529 | client->addr = address; | 445 | name = "bt819a"; |
530 | client->adapter = adapter; | 446 | break; |
531 | client->driver = &i2c_driver_bt819; | 447 | case 0x60: |
448 | name = "bt817a"; | ||
449 | break; | ||
450 | case 0x20: | ||
451 | name = "bt815a"; | ||
452 | break; | ||
453 | default: | ||
454 | v4l_dbg(1, debug, client, | ||
455 | "unknown chip version 0x%02x\n", ver); | ||
456 | return -ENODEV; | ||
457 | } | ||
458 | |||
459 | v4l_info(client, "%s found @ 0x%x (%s)\n", name, | ||
460 | client->addr << 1, client->adapter->name); | ||
532 | 461 | ||
533 | decoder = kzalloc(sizeof(struct bt819), GFP_KERNEL); | 462 | decoder = kzalloc(sizeof(struct bt819), GFP_KERNEL); |
534 | if (decoder == NULL) { | 463 | if (decoder == NULL) |
535 | kfree(client); | ||
536 | return -ENOMEM; | 464 | return -ENOMEM; |
537 | } | ||
538 | decoder->norm = VIDEO_MODE_NTSC; | 465 | decoder->norm = VIDEO_MODE_NTSC; |
539 | decoder->input = 0; | 466 | decoder->input = 0; |
540 | decoder->enable = 1; | 467 | decoder->enable = 1; |
@@ -545,97 +472,33 @@ bt819_detect_client (struct i2c_adapter *adapter, | |||
545 | decoder->initialized = 0; | 472 | decoder->initialized = 0; |
546 | i2c_set_clientdata(client, decoder); | 473 | i2c_set_clientdata(client, decoder); |
547 | 474 | ||
548 | id = bt819_read(client, 0x17); | ||
549 | switch (id & 0xf0) { | ||
550 | case 0x70: | ||
551 | strlcpy(I2C_NAME(client), "bt819a", sizeof(I2C_NAME(client))); | ||
552 | break; | ||
553 | case 0x60: | ||
554 | strlcpy(I2C_NAME(client), "bt817a", sizeof(I2C_NAME(client))); | ||
555 | break; | ||
556 | case 0x20: | ||
557 | strlcpy(I2C_NAME(client), "bt815a", sizeof(I2C_NAME(client))); | ||
558 | break; | ||
559 | default: | ||
560 | dprintk(1, | ||
561 | KERN_ERR | ||
562 | "bt819: unknown chip version 0x%x (ver 0x%x)\n", | ||
563 | id & 0xf0, id & 0x0f); | ||
564 | kfree(decoder); | ||
565 | kfree(client); | ||
566 | return 0; | ||
567 | } | ||
568 | |||
569 | i = i2c_attach_client(client); | ||
570 | if (i) { | ||
571 | kfree(client); | ||
572 | kfree(decoder); | ||
573 | return i; | ||
574 | } | ||
575 | |||
576 | i = bt819_init(client); | 475 | i = bt819_init(client); |
577 | if (i < 0) { | 476 | if (i < 0) |
578 | dprintk(1, KERN_ERR "%s_attach: init status %d\n", | 477 | v4l_dbg(1, debug, client, "init status %d\n", i); |
579 | I2C_NAME(client), i); | ||
580 | } else { | ||
581 | dprintk(1, | ||
582 | KERN_INFO | ||
583 | "%s_attach: chip version 0x%x at address 0x%x\n", | ||
584 | I2C_NAME(client), id & 0x0f, | ||
585 | client->addr << 1); | ||
586 | } | ||
587 | |||
588 | return 0; | 478 | return 0; |
589 | } | 479 | } |
590 | 480 | ||
591 | static int | 481 | static int bt819_remove(struct i2c_client *client) |
592 | bt819_attach_adapter (struct i2c_adapter *adapter) | ||
593 | { | ||
594 | return i2c_probe(adapter, &addr_data, &bt819_detect_client); | ||
595 | } | ||
596 | |||
597 | static int | ||
598 | bt819_detach_client (struct i2c_client *client) | ||
599 | { | 482 | { |
600 | struct bt819 *decoder = i2c_get_clientdata(client); | 483 | kfree(i2c_get_clientdata(client)); |
601 | int err; | ||
602 | |||
603 | err = i2c_detach_client(client); | ||
604 | if (err) { | ||
605 | return err; | ||
606 | } | ||
607 | |||
608 | kfree(decoder); | ||
609 | kfree(client); | ||
610 | |||
611 | return 0; | 484 | return 0; |
612 | } | 485 | } |
613 | 486 | ||
614 | /* ----------------------------------------------------------------------- */ | 487 | /* ----------------------------------------------------------------------- */ |
615 | 488 | ||
616 | static struct i2c_driver i2c_driver_bt819 = { | 489 | static const struct i2c_device_id bt819_id[] = { |
617 | .driver = { | 490 | { "bt819a", 0 }, |
618 | .name = "bt819", | 491 | { "bt817a", 0 }, |
619 | }, | 492 | { "bt815a", 0 }, |
620 | 493 | { } | |
621 | .id = I2C_DRIVERID_BT819, | 494 | }; |
495 | MODULE_DEVICE_TABLE(i2c, bt819_id); | ||
622 | 496 | ||
623 | .attach_adapter = bt819_attach_adapter, | 497 | static struct v4l2_i2c_driver_data v4l2_i2c_data = { |
624 | .detach_client = bt819_detach_client, | 498 | .name = "bt819", |
499 | .driverid = I2C_DRIVERID_BT819, | ||
625 | .command = bt819_command, | 500 | .command = bt819_command, |
501 | .probe = bt819_probe, | ||
502 | .remove = bt819_remove, | ||
503 | .id_table = bt819_id, | ||
626 | }; | 504 | }; |
627 | |||
628 | static int __init | ||
629 | bt819_init_module (void) | ||
630 | { | ||
631 | return i2c_add_driver(&i2c_driver_bt819); | ||
632 | } | ||
633 | |||
634 | static void __exit | ||
635 | bt819_exit (void) | ||
636 | { | ||
637 | i2c_del_driver(&i2c_driver_bt819); | ||
638 | } | ||
639 | |||
640 | module_init(bt819_init_module); | ||
641 | module_exit(bt819_exit); | ||
diff --git a/drivers/media/video/bt856.c b/drivers/media/video/bt856.c index ab2ce4d7b5de..4213867507f8 100644 --- a/drivers/media/video/bt856.c +++ b/drivers/media/video/bt856.c | |||
@@ -29,43 +29,24 @@ | |||
29 | */ | 29 | */ |
30 | 30 | ||
31 | #include <linux/module.h> | 31 | #include <linux/module.h> |
32 | #include <linux/init.h> | ||
33 | #include <linux/delay.h> | ||
34 | #include <linux/errno.h> | ||
35 | #include <linux/fs.h> | ||
36 | #include <linux/kernel.h> | ||
37 | #include <linux/major.h> | ||
38 | #include <linux/slab.h> | ||
39 | #include <linux/mm.h> | ||
40 | #include <linux/signal.h> | ||
41 | #include <linux/types.h> | 32 | #include <linux/types.h> |
42 | #include <linux/i2c.h> | 33 | #include <linux/ioctl.h> |
43 | #include <linux/video_encoder.h> | ||
44 | #include <asm/io.h> | ||
45 | #include <asm/pgtable.h> | ||
46 | #include <asm/page.h> | ||
47 | #include <asm/uaccess.h> | 34 | #include <asm/uaccess.h> |
48 | 35 | #include <linux/i2c.h> | |
36 | #include <linux/i2c-id.h> | ||
49 | #include <linux/videodev.h> | 37 | #include <linux/videodev.h> |
38 | #include <linux/video_encoder.h> | ||
39 | #include <media/v4l2-common.h> | ||
40 | #include <media/v4l2-i2c-drv-legacy.h> | ||
50 | 41 | ||
51 | MODULE_DESCRIPTION("Brooktree-856A video encoder driver"); | 42 | MODULE_DESCRIPTION("Brooktree-856A video encoder driver"); |
52 | MODULE_AUTHOR("Mike Bernson & Dave Perks"); | 43 | MODULE_AUTHOR("Mike Bernson & Dave Perks"); |
53 | MODULE_LICENSE("GPL"); | 44 | MODULE_LICENSE("GPL"); |
54 | 45 | ||
55 | |||
56 | #define I2C_NAME(s) (s)->name | ||
57 | |||
58 | |||
59 | static int debug; | 46 | static int debug; |
60 | module_param(debug, int, 0); | 47 | module_param(debug, int, 0); |
61 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); | 48 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); |
62 | 49 | ||
63 | #define dprintk(num, format, args...) \ | ||
64 | do { \ | ||
65 | if (debug >= num) \ | ||
66 | printk(format, ##args); \ | ||
67 | } while (0) | ||
68 | |||
69 | /* ----------------------------------------------------------------------- */ | 50 | /* ----------------------------------------------------------------------- */ |
70 | 51 | ||
71 | #define BT856_REG_OFFSET 0xDA | 52 | #define BT856_REG_OFFSET 0xDA |
@@ -78,14 +59,9 @@ struct bt856 { | |||
78 | int enable; | 59 | int enable; |
79 | }; | 60 | }; |
80 | 61 | ||
81 | #define I2C_BT856 0x88 | ||
82 | |||
83 | /* ----------------------------------------------------------------------- */ | 62 | /* ----------------------------------------------------------------------- */ |
84 | 63 | ||
85 | static inline int | 64 | static inline int bt856_write(struct i2c_client *client, u8 reg, u8 value) |
86 | bt856_write (struct i2c_client *client, | ||
87 | u8 reg, | ||
88 | u8 value) | ||
89 | { | 65 | { |
90 | struct bt856 *encoder = i2c_get_clientdata(client); | 66 | struct bt856 *encoder = i2c_get_clientdata(client); |
91 | 67 | ||
@@ -93,46 +69,36 @@ bt856_write (struct i2c_client *client, | |||
93 | return i2c_smbus_write_byte_data(client, reg, value); | 69 | return i2c_smbus_write_byte_data(client, reg, value); |
94 | } | 70 | } |
95 | 71 | ||
96 | static inline int | 72 | static inline int bt856_setbit(struct i2c_client *client, u8 reg, u8 bit, u8 value) |
97 | bt856_setbit (struct i2c_client *client, | ||
98 | u8 reg, | ||
99 | u8 bit, | ||
100 | u8 value) | ||
101 | { | 73 | { |
102 | struct bt856 *encoder = i2c_get_clientdata(client); | 74 | struct bt856 *encoder = i2c_get_clientdata(client); |
103 | 75 | ||
104 | return bt856_write(client, reg, | 76 | return bt856_write(client, reg, |
105 | (encoder-> | 77 | (encoder->reg[reg - BT856_REG_OFFSET] & ~(1 << bit)) | |
106 | reg[reg - BT856_REG_OFFSET] & ~(1 << bit)) | | 78 | (value ? (1 << bit) : 0)); |
107 | (value ? (1 << bit) : 0)); | ||
108 | } | 79 | } |
109 | 80 | ||
110 | static void | 81 | static void bt856_dump(struct i2c_client *client) |
111 | bt856_dump (struct i2c_client *client) | ||
112 | { | 82 | { |
113 | int i; | 83 | int i; |
114 | struct bt856 *encoder = i2c_get_clientdata(client); | 84 | struct bt856 *encoder = i2c_get_clientdata(client); |
115 | 85 | ||
116 | printk(KERN_INFO "%s: register dump:", I2C_NAME(client)); | 86 | v4l_info(client, "register dump:\n"); |
117 | for (i = 0; i < BT856_NR_REG; i += 2) | 87 | for (i = 0; i < BT856_NR_REG; i += 2) |
118 | printk(" %02x", encoder->reg[i]); | 88 | printk(KERN_CONT " %02x", encoder->reg[i]); |
119 | printk("\n"); | 89 | printk(KERN_CONT "\n"); |
120 | } | 90 | } |
121 | 91 | ||
122 | /* ----------------------------------------------------------------------- */ | 92 | /* ----------------------------------------------------------------------- */ |
123 | 93 | ||
124 | static int | 94 | static int bt856_command(struct i2c_client *client, unsigned cmd, void *arg) |
125 | bt856_command (struct i2c_client *client, | ||
126 | unsigned int cmd, | ||
127 | void *arg) | ||
128 | { | 95 | { |
129 | struct bt856 *encoder = i2c_get_clientdata(client); | 96 | struct bt856 *encoder = i2c_get_clientdata(client); |
130 | 97 | ||
131 | switch (cmd) { | 98 | switch (cmd) { |
132 | |||
133 | case 0: | 99 | case 0: |
134 | /* This is just for testing!!! */ | 100 | /* This is just for testing!!! */ |
135 | dprintk(1, KERN_INFO "bt856: init\n"); | 101 | v4l_dbg(1, debug, client, "init\n"); |
136 | bt856_write(client, 0xdc, 0x18); | 102 | bt856_write(client, 0xdc, 0x18); |
137 | bt856_write(client, 0xda, 0); | 103 | bt856_write(client, 0xda, 0); |
138 | bt856_write(client, 0xde, 0); | 104 | bt856_write(client, 0xde, 0); |
@@ -142,7 +108,6 @@ bt856_command (struct i2c_client *client, | |||
142 | bt856_setbit(client, 0xdc, 4, 1); | 108 | bt856_setbit(client, 0xdc, 4, 1); |
143 | 109 | ||
144 | switch (encoder->norm) { | 110 | switch (encoder->norm) { |
145 | |||
146 | case VIDEO_MODE_NTSC: | 111 | case VIDEO_MODE_NTSC: |
147 | bt856_setbit(client, 0xdc, 2, 0); | 112 | bt856_setbit(client, 0xdc, 2, 0); |
148 | break; | 113 | break; |
@@ -163,26 +128,23 @@ bt856_command (struct i2c_client *client, | |||
163 | { | 128 | { |
164 | struct video_encoder_capability *cap = arg; | 129 | struct video_encoder_capability *cap = arg; |
165 | 130 | ||
166 | dprintk(1, KERN_INFO "%s: get capabilities\n", | 131 | v4l_dbg(1, debug, client, "get capabilities\n"); |
167 | I2C_NAME(client)); | ||
168 | 132 | ||
169 | cap->flags = VIDEO_ENCODER_PAL | | 133 | cap->flags = VIDEO_ENCODER_PAL | |
170 | VIDEO_ENCODER_NTSC | | 134 | VIDEO_ENCODER_NTSC | |
171 | VIDEO_ENCODER_CCIR; | 135 | VIDEO_ENCODER_CCIR; |
172 | cap->inputs = 2; | 136 | cap->inputs = 2; |
173 | cap->outputs = 1; | 137 | cap->outputs = 1; |
174 | } | ||
175 | break; | 138 | break; |
139 | } | ||
176 | 140 | ||
177 | case ENCODER_SET_NORM: | 141 | case ENCODER_SET_NORM: |
178 | { | 142 | { |
179 | int *iarg = arg; | 143 | int *iarg = arg; |
180 | 144 | ||
181 | dprintk(1, KERN_INFO "%s: set norm %d\n", I2C_NAME(client), | 145 | v4l_dbg(1, debug, client, "set norm %d\n", *iarg); |
182 | *iarg); | ||
183 | 146 | ||
184 | switch (*iarg) { | 147 | switch (*iarg) { |
185 | |||
186 | case VIDEO_MODE_NTSC: | 148 | case VIDEO_MODE_NTSC: |
187 | bt856_setbit(client, 0xdc, 2, 0); | 149 | bt856_setbit(client, 0xdc, 2, 0); |
188 | break; | 150 | break; |
@@ -195,27 +157,23 @@ bt856_command (struct i2c_client *client, | |||
195 | 157 | ||
196 | default: | 158 | default: |
197 | return -EINVAL; | 159 | return -EINVAL; |
198 | |||
199 | } | 160 | } |
200 | encoder->norm = *iarg; | 161 | encoder->norm = *iarg; |
201 | if (debug != 0) | 162 | if (debug != 0) |
202 | bt856_dump(client); | 163 | bt856_dump(client); |
203 | } | ||
204 | break; | 164 | break; |
165 | } | ||
205 | 166 | ||
206 | case ENCODER_SET_INPUT: | 167 | case ENCODER_SET_INPUT: |
207 | { | 168 | { |
208 | int *iarg = arg; | 169 | int *iarg = arg; |
209 | 170 | ||
210 | dprintk(1, KERN_INFO "%s: set input %d\n", I2C_NAME(client), | 171 | v4l_dbg(1, debug, client, "set input %d\n", *iarg); |
211 | *iarg); | ||
212 | 172 | ||
213 | /* We only have video bus. | 173 | /* We only have video bus. |
214 | * iarg = 0: input is from bt819 | 174 | * iarg = 0: input is from bt819 |
215 | * iarg = 1: input is from ZR36060 */ | 175 | * iarg = 1: input is from ZR36060 */ |
216 | |||
217 | switch (*iarg) { | 176 | switch (*iarg) { |
218 | |||
219 | case 0: | 177 | case 0: |
220 | bt856_setbit(client, 0xde, 4, 0); | 178 | bt856_setbit(client, 0xde, 4, 0); |
221 | bt856_setbit(client, 0xde, 3, 1); | 179 | bt856_setbit(client, 0xde, 3, 1); |
@@ -234,27 +192,24 @@ bt856_command (struct i2c_client *client, | |||
234 | break; | 192 | break; |
235 | default: | 193 | default: |
236 | return -EINVAL; | 194 | return -EINVAL; |
237 | |||
238 | } | 195 | } |
239 | 196 | ||
240 | if (debug != 0) | 197 | if (debug != 0) |
241 | bt856_dump(client); | 198 | bt856_dump(client); |
242 | } | ||
243 | break; | 199 | break; |
200 | } | ||
244 | 201 | ||
245 | case ENCODER_SET_OUTPUT: | 202 | case ENCODER_SET_OUTPUT: |
246 | { | 203 | { |
247 | int *iarg = arg; | 204 | int *iarg = arg; |
248 | 205 | ||
249 | dprintk(1, KERN_INFO "%s: set output %d\n", I2C_NAME(client), | 206 | v4l_dbg(1, debug, client, "set output %d\n", *iarg); |
250 | *iarg); | ||
251 | 207 | ||
252 | /* not much choice of outputs */ | 208 | /* not much choice of outputs */ |
253 | if (*iarg != 0) { | 209 | if (*iarg != 0) |
254 | return -EINVAL; | 210 | return -EINVAL; |
255 | } | ||
256 | } | ||
257 | break; | 211 | break; |
212 | } | ||
258 | 213 | ||
259 | case ENCODER_ENABLE_OUTPUT: | 214 | case ENCODER_ENABLE_OUTPUT: |
260 | { | 215 | { |
@@ -262,10 +217,9 @@ bt856_command (struct i2c_client *client, | |||
262 | 217 | ||
263 | encoder->enable = !!*iarg; | 218 | encoder->enable = !!*iarg; |
264 | 219 | ||
265 | dprintk(1, KERN_INFO "%s: enable output %d\n", | 220 | v4l_dbg(1, debug, client, "enable output %d\n", encoder->enable); |
266 | I2C_NAME(client), encoder->enable); | ||
267 | } | ||
268 | break; | 221 | break; |
222 | } | ||
269 | 223 | ||
270 | default: | 224 | default: |
271 | return -EINVAL; | 225 | return -EINVAL; |
@@ -276,64 +230,29 @@ bt856_command (struct i2c_client *client, | |||
276 | 230 | ||
277 | /* ----------------------------------------------------------------------- */ | 231 | /* ----------------------------------------------------------------------- */ |
278 | 232 | ||
279 | /* | 233 | static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END }; |
280 | * Generic i2c probe | ||
281 | * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1' | ||
282 | */ | ||
283 | static unsigned short normal_i2c[] = { I2C_BT856 >> 1, I2C_CLIENT_END }; | ||
284 | |||
285 | static unsigned short ignore = I2C_CLIENT_END; | ||
286 | |||
287 | static struct i2c_client_address_data addr_data = { | ||
288 | .normal_i2c = normal_i2c, | ||
289 | .probe = &ignore, | ||
290 | .ignore = &ignore, | ||
291 | }; | ||
292 | 234 | ||
293 | static struct i2c_driver i2c_driver_bt856; | 235 | I2C_CLIENT_INSMOD; |
294 | 236 | ||
295 | static int | 237 | static int bt856_probe(struct i2c_client *client, |
296 | bt856_detect_client (struct i2c_adapter *adapter, | 238 | const struct i2c_device_id *id) |
297 | int address, | ||
298 | int kind) | ||
299 | { | 239 | { |
300 | int i; | ||
301 | struct i2c_client *client; | ||
302 | struct bt856 *encoder; | 240 | struct bt856 *encoder; |
303 | 241 | ||
304 | dprintk(1, | ||
305 | KERN_INFO | ||
306 | "bt856.c: detecting bt856 client on address 0x%x\n", | ||
307 | address << 1); | ||
308 | |||
309 | /* Check if the adapter supports the needed features */ | 242 | /* Check if the adapter supports the needed features */ |
310 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | 243 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) |
311 | return 0; | 244 | return -ENODEV; |
312 | 245 | ||
313 | client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); | 246 | v4l_info(client, "chip found @ 0x%x (%s)\n", |
314 | if (!client) | 247 | client->addr << 1, client->adapter->name); |
315 | return -ENOMEM; | ||
316 | client->addr = address; | ||
317 | client->adapter = adapter; | ||
318 | client->driver = &i2c_driver_bt856; | ||
319 | strlcpy(I2C_NAME(client), "bt856", sizeof(I2C_NAME(client))); | ||
320 | 248 | ||
321 | encoder = kzalloc(sizeof(struct bt856), GFP_KERNEL); | 249 | encoder = kzalloc(sizeof(struct bt856), GFP_KERNEL); |
322 | if (encoder == NULL) { | 250 | if (encoder == NULL) |
323 | kfree(client); | ||
324 | return -ENOMEM; | 251 | return -ENOMEM; |
325 | } | ||
326 | encoder->norm = VIDEO_MODE_NTSC; | 252 | encoder->norm = VIDEO_MODE_NTSC; |
327 | encoder->enable = 1; | 253 | encoder->enable = 1; |
328 | i2c_set_clientdata(client, encoder); | 254 | i2c_set_clientdata(client, encoder); |
329 | 255 | ||
330 | i = i2c_attach_client(client); | ||
331 | if (i) { | ||
332 | kfree(client); | ||
333 | kfree(encoder); | ||
334 | return i; | ||
335 | } | ||
336 | |||
337 | bt856_write(client, 0xdc, 0x18); | 256 | bt856_write(client, 0xdc, 0x18); |
338 | bt856_write(client, 0xda, 0); | 257 | bt856_write(client, 0xda, 0); |
339 | bt856_write(client, 0xde, 0); | 258 | bt856_write(client, 0xde, 0); |
@@ -359,65 +278,26 @@ bt856_detect_client (struct i2c_adapter *adapter, | |||
359 | 278 | ||
360 | if (debug != 0) | 279 | if (debug != 0) |
361 | bt856_dump(client); | 280 | bt856_dump(client); |
362 | |||
363 | dprintk(1, KERN_INFO "%s_attach: at address 0x%x\n", I2C_NAME(client), | ||
364 | client->addr << 1); | ||
365 | |||
366 | return 0; | 281 | return 0; |
367 | } | 282 | } |
368 | 283 | ||
369 | static int | 284 | static int bt856_remove(struct i2c_client *client) |
370 | bt856_attach_adapter (struct i2c_adapter *adapter) | ||
371 | { | 285 | { |
372 | dprintk(1, | 286 | kfree(i2c_get_clientdata(client)); |
373 | KERN_INFO | ||
374 | "bt856.c: starting probe for adapter %s (0x%x)\n", | ||
375 | I2C_NAME(adapter), adapter->id); | ||
376 | return i2c_probe(adapter, &addr_data, &bt856_detect_client); | ||
377 | } | ||
378 | |||
379 | static int | ||
380 | bt856_detach_client (struct i2c_client *client) | ||
381 | { | ||
382 | struct bt856 *encoder = i2c_get_clientdata(client); | ||
383 | int err; | ||
384 | |||
385 | err = i2c_detach_client(client); | ||
386 | if (err) { | ||
387 | return err; | ||
388 | } | ||
389 | |||
390 | kfree(encoder); | ||
391 | kfree(client); | ||
392 | |||
393 | return 0; | 287 | return 0; |
394 | } | 288 | } |
395 | 289 | ||
396 | /* ----------------------------------------------------------------------- */ | 290 | static const struct i2c_device_id bt856_id[] = { |
397 | 291 | { "bt856", 0 }, | |
398 | static struct i2c_driver i2c_driver_bt856 = { | 292 | { } |
399 | .driver = { | 293 | }; |
400 | .name = "bt856", | 294 | MODULE_DEVICE_TABLE(i2c, bt856_id); |
401 | }, | ||
402 | |||
403 | .id = I2C_DRIVERID_BT856, | ||
404 | 295 | ||
405 | .attach_adapter = bt856_attach_adapter, | 296 | static struct v4l2_i2c_driver_data v4l2_i2c_data = { |
406 | .detach_client = bt856_detach_client, | 297 | .name = "bt856", |
298 | .driverid = I2C_DRIVERID_BT856, | ||
407 | .command = bt856_command, | 299 | .command = bt856_command, |
300 | .probe = bt856_probe, | ||
301 | .remove = bt856_remove, | ||
302 | .id_table = bt856_id, | ||
408 | }; | 303 | }; |
409 | |||
410 | static int __init | ||
411 | bt856_init (void) | ||
412 | { | ||
413 | return i2c_add_driver(&i2c_driver_bt856); | ||
414 | } | ||
415 | |||
416 | static void __exit | ||
417 | bt856_exit (void) | ||
418 | { | ||
419 | i2c_del_driver(&i2c_driver_bt856); | ||
420 | } | ||
421 | |||
422 | module_init(bt856_init); | ||
423 | module_exit(bt856_exit); | ||
diff --git a/drivers/media/video/bt866.c b/drivers/media/video/bt866.c index 96b415576f0d..596f9e2376be 100644 --- a/drivers/media/video/bt866.c +++ b/drivers/media/video/bt866.c | |||
@@ -29,42 +29,28 @@ | |||
29 | */ | 29 | */ |
30 | 30 | ||
31 | #include <linux/module.h> | 31 | #include <linux/module.h> |
32 | #include <linux/init.h> | ||
33 | #include <linux/delay.h> | ||
34 | #include <linux/errno.h> | ||
35 | #include <linux/fs.h> | ||
36 | #include <linux/kernel.h> | ||
37 | #include <linux/major.h> | ||
38 | #include <linux/slab.h> | ||
39 | #include <linux/mm.h> | ||
40 | #include <linux/signal.h> | ||
41 | #include <asm/io.h> | ||
42 | #include <asm/pgtable.h> | ||
43 | #include <asm/page.h> | ||
44 | #include <linux/sched.h> | ||
45 | #include <linux/types.h> | 32 | #include <linux/types.h> |
33 | #include <linux/ioctl.h> | ||
34 | #include <asm/uaccess.h> | ||
46 | #include <linux/i2c.h> | 35 | #include <linux/i2c.h> |
47 | 36 | #include <linux/i2c-id.h> | |
48 | #include <linux/videodev.h> | 37 | #include <linux/videodev.h> |
49 | #include <asm/uaccess.h> | ||
50 | |||
51 | #include <linux/video_encoder.h> | 38 | #include <linux/video_encoder.h> |
39 | #include <media/v4l2-common.h> | ||
40 | #include <media/v4l2-i2c-drv-legacy.h> | ||
52 | 41 | ||
42 | MODULE_DESCRIPTION("Brooktree-866 video encoder driver"); | ||
43 | MODULE_AUTHOR("Mike Bernson & Dave Perks"); | ||
53 | MODULE_LICENSE("GPL"); | 44 | MODULE_LICENSE("GPL"); |
54 | 45 | ||
55 | #define BT866_DEVNAME "bt866" | 46 | static int debug; |
56 | #define I2C_BT866 0x88 | 47 | module_param(debug, int, 0); |
57 | 48 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); | |
58 | MODULE_LICENSE("GPL"); | ||
59 | |||
60 | #define DEBUG(x) /* Debug driver */ | ||
61 | 49 | ||
62 | /* ----------------------------------------------------------------------- */ | 50 | /* ----------------------------------------------------------------------- */ |
63 | 51 | ||
64 | struct bt866 { | 52 | struct bt866 { |
65 | struct i2c_client *i2c; | 53 | u8 reg[256]; |
66 | int addr; | ||
67 | unsigned char reg[256]; | ||
68 | 54 | ||
69 | int norm; | 55 | int norm; |
70 | int enable; | 56 | int enable; |
@@ -74,20 +60,45 @@ struct bt866 { | |||
74 | int sat; | 60 | int sat; |
75 | }; | 61 | }; |
76 | 62 | ||
77 | static int bt866_write(struct bt866 *dev, | 63 | static int bt866_write(struct i2c_client *client, u8 subaddr, u8 data) |
78 | unsigned char subaddr, unsigned char data); | 64 | { |
65 | struct bt866 *encoder = i2c_get_clientdata(client); | ||
66 | u8 buffer[2]; | ||
67 | int err; | ||
68 | |||
69 | buffer[0] = subaddr; | ||
70 | buffer[1] = data; | ||
71 | |||
72 | encoder->reg[subaddr] = data; | ||
73 | |||
74 | v4l_dbg(1, debug, client, "write 0x%02x = 0x%02x\n", subaddr, data); | ||
75 | |||
76 | for (err = 0; err < 3;) { | ||
77 | if (i2c_master_send(client, buffer, 2) == 2) | ||
78 | break; | ||
79 | err++; | ||
80 | v4l_warn(client, "error #%d writing to 0x%02x\n", | ||
81 | err, subaddr); | ||
82 | schedule_timeout_interruptible(msecs_to_jiffies(100)); | ||
83 | } | ||
84 | if (err == 3) { | ||
85 | v4l_warn(client, "giving up\n"); | ||
86 | return -1; | ||
87 | } | ||
88 | |||
89 | return 0; | ||
90 | } | ||
79 | 91 | ||
80 | static int bt866_do_command(struct bt866 *encoder, | 92 | static int bt866_command(struct i2c_client *client, unsigned cmd, void *arg) |
81 | unsigned int cmd, void *arg) | ||
82 | { | 93 | { |
94 | struct bt866 *encoder = i2c_get_clientdata(client); | ||
95 | |||
83 | switch (cmd) { | 96 | switch (cmd) { |
84 | case ENCODER_GET_CAPABILITIES: | 97 | case ENCODER_GET_CAPABILITIES: |
85 | { | 98 | { |
86 | struct video_encoder_capability *cap = arg; | 99 | struct video_encoder_capability *cap = arg; |
87 | 100 | ||
88 | DEBUG(printk | 101 | v4l_dbg(1, debug, client, "get capabilities\n"); |
89 | (KERN_INFO "%s: get capabilities\n", | ||
90 | encoder->i2c->name)); | ||
91 | 102 | ||
92 | cap->flags | 103 | cap->flags |
93 | = VIDEO_ENCODER_PAL | 104 | = VIDEO_ENCODER_PAL |
@@ -95,18 +106,16 @@ static int bt866_do_command(struct bt866 *encoder, | |||
95 | | VIDEO_ENCODER_CCIR; | 106 | | VIDEO_ENCODER_CCIR; |
96 | cap->inputs = 2; | 107 | cap->inputs = 2; |
97 | cap->outputs = 1; | 108 | cap->outputs = 1; |
109 | break; | ||
98 | } | 110 | } |
99 | break; | ||
100 | 111 | ||
101 | case ENCODER_SET_NORM: | 112 | case ENCODER_SET_NORM: |
102 | { | 113 | { |
103 | int *iarg = arg; | 114 | int *iarg = arg; |
104 | 115 | ||
105 | DEBUG(printk(KERN_INFO "%s: set norm %d\n", | 116 | v4l_dbg(1, debug, client, "set norm %d\n", *iarg); |
106 | encoder->i2c->name, *iarg)); | ||
107 | 117 | ||
108 | switch (*iarg) { | 118 | switch (*iarg) { |
109 | |||
110 | case VIDEO_MODE_NTSC: | 119 | case VIDEO_MODE_NTSC: |
111 | break; | 120 | break; |
112 | 121 | ||
@@ -115,11 +124,10 @@ static int bt866_do_command(struct bt866 *encoder, | |||
115 | 124 | ||
116 | default: | 125 | default: |
117 | return -EINVAL; | 126 | return -EINVAL; |
118 | |||
119 | } | 127 | } |
120 | encoder->norm = *iarg; | 128 | encoder->norm = *iarg; |
129 | break; | ||
121 | } | 130 | } |
122 | break; | ||
123 | 131 | ||
124 | case ENCODER_SET_INPUT: | 132 | case ENCODER_SET_INPUT: |
125 | { | 133 | { |
@@ -155,7 +163,7 @@ static int bt866_do_command(struct bt866 *encoder, | |||
155 | u8 val; | 163 | u8 val; |
156 | 164 | ||
157 | for (i = 0; i < ARRAY_SIZE(init) / 2; i += 2) | 165 | for (i = 0; i < ARRAY_SIZE(init) / 2; i += 2) |
158 | bt866_write(encoder, init[i], init[i+1]); | 166 | bt866_write(client, init[i], init[i+1]); |
159 | 167 | ||
160 | val = encoder->reg[0xdc]; | 168 | val = encoder->reg[0xdc]; |
161 | 169 | ||
@@ -164,17 +172,16 @@ static int bt866_do_command(struct bt866 *encoder, | |||
164 | else | 172 | else |
165 | val &= ~0x40; /* !CBSWAP */ | 173 | val &= ~0x40; /* !CBSWAP */ |
166 | 174 | ||
167 | bt866_write(encoder, 0xdc, val); | 175 | bt866_write(client, 0xdc, val); |
168 | 176 | ||
169 | val = encoder->reg[0xcc]; | 177 | val = encoder->reg[0xcc]; |
170 | if (*iarg == 2) | 178 | if (*iarg == 2) |
171 | val |= 0x01; /* OSDBAR */ | 179 | val |= 0x01; /* OSDBAR */ |
172 | else | 180 | else |
173 | val &= ~0x01; /* !OSDBAR */ | 181 | val &= ~0x01; /* !OSDBAR */ |
174 | bt866_write(encoder, 0xcc, val); | 182 | bt866_write(client, 0xcc, val); |
175 | 183 | ||
176 | DEBUG(printk(KERN_INFO "%s: set input %d\n", | 184 | v4l_dbg(1, debug, client, "set input %d\n", *iarg); |
177 | encoder->i2c->name, *iarg)); | ||
178 | 185 | ||
179 | switch (*iarg) { | 186 | switch (*iarg) { |
180 | case 0: | 187 | case 0: |
@@ -183,48 +190,44 @@ static int bt866_do_command(struct bt866 *encoder, | |||
183 | break; | 190 | break; |
184 | default: | 191 | default: |
185 | return -EINVAL; | 192 | return -EINVAL; |
186 | |||
187 | } | 193 | } |
194 | break; | ||
188 | } | 195 | } |
189 | break; | ||
190 | 196 | ||
191 | case ENCODER_SET_OUTPUT: | 197 | case ENCODER_SET_OUTPUT: |
192 | { | 198 | { |
193 | int *iarg = arg; | 199 | int *iarg = arg; |
194 | 200 | ||
195 | DEBUG(printk(KERN_INFO "%s: set output %d\n", | 201 | v4l_dbg(1, debug, client, "set output %d\n", *iarg); |
196 | encoder->i2c->name, *iarg)); | ||
197 | 202 | ||
198 | /* not much choice of outputs */ | 203 | /* not much choice of outputs */ |
199 | if (*iarg != 0) | 204 | if (*iarg != 0) |
200 | return -EINVAL; | 205 | return -EINVAL; |
206 | break; | ||
201 | } | 207 | } |
202 | break; | ||
203 | 208 | ||
204 | case ENCODER_ENABLE_OUTPUT: | 209 | case ENCODER_ENABLE_OUTPUT: |
205 | { | 210 | { |
206 | int *iarg = arg; | 211 | int *iarg = arg; |
207 | encoder->enable = !!*iarg; | 212 | encoder->enable = !!*iarg; |
208 | 213 | ||
209 | DEBUG(printk | 214 | v4l_dbg(1, debug, client, "enable output %d\n", encoder->enable); |
210 | (KERN_INFO "%s: enable output %d\n", | 215 | break; |
211 | encoder->i2c->name, encoder->enable)); | ||
212 | } | 216 | } |
213 | break; | ||
214 | 217 | ||
215 | case 4711: | 218 | case 4711: |
216 | { | 219 | { |
217 | int *iarg = arg; | 220 | int *iarg = arg; |
218 | __u8 val; | 221 | __u8 val; |
219 | 222 | ||
220 | printk("bt866: square = %d\n", *iarg); | 223 | v4l_dbg(1, debug, client, "square %d\n", *iarg); |
221 | 224 | ||
222 | val = encoder->reg[0xdc]; | 225 | val = encoder->reg[0xdc]; |
223 | if (*iarg) | 226 | if (*iarg) |
224 | val |= 1; /* SQUARE */ | 227 | val |= 1; /* SQUARE */ |
225 | else | 228 | else |
226 | val &= ~1; /* !SQUARE */ | 229 | val &= ~1; /* !SQUARE */ |
227 | bt866_write(encoder, 0xdc, val); | 230 | bt866_write(client, 0xdc, val); |
228 | break; | 231 | break; |
229 | } | 232 | } |
230 | 233 | ||
@@ -235,141 +238,49 @@ static int bt866_do_command(struct bt866 *encoder, | |||
235 | return 0; | 238 | return 0; |
236 | } | 239 | } |
237 | 240 | ||
238 | static int bt866_write(struct bt866 *encoder, | 241 | static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END }; |
239 | unsigned char subaddr, unsigned char data) | ||
240 | { | ||
241 | unsigned char buffer[2]; | ||
242 | int err; | ||
243 | 242 | ||
244 | buffer[0] = subaddr; | 243 | I2C_CLIENT_INSMOD; |
245 | buffer[1] = data; | ||
246 | |||
247 | encoder->reg[subaddr] = data; | ||
248 | 244 | ||
249 | DEBUG(printk | 245 | static int bt866_probe(struct i2c_client *client, |
250 | ("%s: write 0x%02X = 0x%02X\n", | 246 | const struct i2c_device_id *id) |
251 | encoder->i2c->name, subaddr, data)); | ||
252 | |||
253 | for (err = 0; err < 3;) { | ||
254 | if (i2c_master_send(encoder->i2c, buffer, 2) == 2) | ||
255 | break; | ||
256 | err++; | ||
257 | printk(KERN_WARNING "%s: I/O error #%d " | ||
258 | "(write 0x%02x/0x%02x)\n", | ||
259 | encoder->i2c->name, err, encoder->addr, subaddr); | ||
260 | schedule_timeout_interruptible(msecs_to_jiffies(100)); | ||
261 | } | ||
262 | if (err == 3) { | ||
263 | printk(KERN_WARNING "%s: giving up\n", | ||
264 | encoder->i2c->name); | ||
265 | return -1; | ||
266 | } | ||
267 | |||
268 | return 0; | ||
269 | } | ||
270 | |||
271 | static int bt866_attach(struct i2c_adapter *adapter); | ||
272 | static int bt866_detach(struct i2c_client *client); | ||
273 | static int bt866_command(struct i2c_client *client, | ||
274 | unsigned int cmd, void *arg); | ||
275 | |||
276 | |||
277 | /* Addresses to scan */ | ||
278 | static unsigned short normal_i2c[] = {I2C_BT866>>1, I2C_CLIENT_END}; | ||
279 | static unsigned short probe[2] = {I2C_CLIENT_END, I2C_CLIENT_END}; | ||
280 | static unsigned short ignore[2] = {I2C_CLIENT_END, I2C_CLIENT_END}; | ||
281 | |||
282 | static struct i2c_client_address_data addr_data = { | ||
283 | normal_i2c, | ||
284 | probe, | ||
285 | ignore, | ||
286 | }; | ||
287 | |||
288 | static struct i2c_driver i2c_driver_bt866 = { | ||
289 | .driver.name = BT866_DEVNAME, | ||
290 | .id = I2C_DRIVERID_BT866, | ||
291 | .attach_adapter = bt866_attach, | ||
292 | .detach_client = bt866_detach, | ||
293 | .command = bt866_command | ||
294 | }; | ||
295 | |||
296 | |||
297 | static struct i2c_client bt866_client_tmpl = | ||
298 | { | ||
299 | .name = "(nil)", | ||
300 | .addr = 0, | ||
301 | .adapter = NULL, | ||
302 | .driver = &i2c_driver_bt866, | ||
303 | }; | ||
304 | |||
305 | static int bt866_found_proc(struct i2c_adapter *adapter, | ||
306 | int addr, int kind) | ||
307 | { | 247 | { |
308 | struct bt866 *encoder; | 248 | struct bt866 *encoder; |
309 | struct i2c_client *client; | ||
310 | 249 | ||
311 | client = kzalloc(sizeof(*client), GFP_KERNEL); | 250 | v4l_info(client, "chip found @ 0x%x (%s)\n", |
312 | if (client == NULL) | 251 | client->addr << 1, client->adapter->name); |
313 | return -ENOMEM; | ||
314 | memcpy(client, &bt866_client_tmpl, sizeof(*client)); | ||
315 | 252 | ||
316 | encoder = kzalloc(sizeof(*encoder), GFP_KERNEL); | 253 | encoder = kzalloc(sizeof(*encoder), GFP_KERNEL); |
317 | if (encoder == NULL) { | 254 | if (encoder == NULL) |
318 | kfree(client); | ||
319 | return -ENOMEM; | 255 | return -ENOMEM; |
320 | } | ||
321 | 256 | ||
322 | i2c_set_clientdata(client, encoder); | 257 | i2c_set_clientdata(client, encoder); |
323 | client->adapter = adapter; | ||
324 | client->addr = addr; | ||
325 | sprintf(client->name, "%s-%02x", BT866_DEVNAME, adapter->id); | ||
326 | |||
327 | encoder->i2c = client; | ||
328 | encoder->addr = addr; | ||
329 | //encoder->encoder_type = ENCODER_TYPE_UNKNOWN; | ||
330 | |||
331 | /* initialize */ | ||
332 | |||
333 | i2c_attach_client(client); | ||
334 | |||
335 | return 0; | ||
336 | } | ||
337 | |||
338 | static int bt866_attach(struct i2c_adapter *adapter) | ||
339 | { | ||
340 | if (adapter->id == I2C_HW_B_ZR36067) | ||
341 | return i2c_probe(adapter, &addr_data, bt866_found_proc); | ||
342 | return 0; | ||
343 | } | ||
344 | |||
345 | static int bt866_detach(struct i2c_client *client) | ||
346 | { | ||
347 | struct bt866 *encoder = i2c_get_clientdata(client); | ||
348 | |||
349 | i2c_detach_client(client); | ||
350 | kfree(encoder); | ||
351 | kfree(client); | ||
352 | |||
353 | return 0; | 258 | return 0; |
354 | } | 259 | } |
355 | 260 | ||
356 | static int bt866_command(struct i2c_client *client, | 261 | static int bt866_remove(struct i2c_client *client) |
357 | unsigned int cmd, void *arg) | ||
358 | { | 262 | { |
359 | struct bt866 *encoder = i2c_get_clientdata(client); | 263 | kfree(i2c_get_clientdata(client)); |
360 | return bt866_do_command(encoder, cmd, arg); | ||
361 | } | ||
362 | |||
363 | static int __devinit bt866_init(void) | ||
364 | { | ||
365 | i2c_add_driver(&i2c_driver_bt866); | ||
366 | return 0; | 264 | return 0; |
367 | } | 265 | } |
368 | 266 | ||
369 | static void __devexit bt866_exit(void) | 267 | static int bt866_legacy_probe(struct i2c_adapter *adapter) |
370 | { | 268 | { |
371 | i2c_del_driver(&i2c_driver_bt866); | 269 | return adapter->id == I2C_HW_B_ZR36067; |
372 | } | 270 | } |
373 | 271 | ||
374 | module_init(bt866_init); | 272 | static const struct i2c_device_id bt866_id[] = { |
375 | module_exit(bt866_exit); | 273 | { "bt866", 0 }, |
274 | { } | ||
275 | }; | ||
276 | MODULE_DEVICE_TABLE(i2c, bt866_id); | ||
277 | |||
278 | static struct v4l2_i2c_driver_data v4l2_i2c_data = { | ||
279 | .name = "bt866", | ||
280 | .driverid = I2C_DRIVERID_BT866, | ||
281 | .command = bt866_command, | ||
282 | .probe = bt866_probe, | ||
283 | .remove = bt866_remove, | ||
284 | .legacy_probe = bt866_legacy_probe, | ||
285 | .id_table = bt866_id, | ||
286 | }; | ||
diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c index 2cda15f829fd..dac5ccc9ba72 100644 --- a/drivers/media/video/cx23885/cx23885-cards.c +++ b/drivers/media/video/cx23885/cx23885-cards.c | |||
@@ -39,16 +39,16 @@ struct cx23885_board cx23885_boards[] = { | |||
39 | .input = {{ | 39 | .input = {{ |
40 | .type = CX23885_VMUX_COMPOSITE1, | 40 | .type = CX23885_VMUX_COMPOSITE1, |
41 | .vmux = 0, | 41 | .vmux = 0, |
42 | },{ | 42 | }, { |
43 | .type = CX23885_VMUX_COMPOSITE2, | 43 | .type = CX23885_VMUX_COMPOSITE2, |
44 | .vmux = 1, | 44 | .vmux = 1, |
45 | },{ | 45 | }, { |
46 | .type = CX23885_VMUX_COMPOSITE3, | 46 | .type = CX23885_VMUX_COMPOSITE3, |
47 | .vmux = 2, | 47 | .vmux = 2, |
48 | },{ | 48 | }, { |
49 | .type = CX23885_VMUX_COMPOSITE4, | 49 | .type = CX23885_VMUX_COMPOSITE4, |
50 | .vmux = 3, | 50 | .vmux = 3, |
51 | }}, | 51 | } }, |
52 | }, | 52 | }, |
53 | [CX23885_BOARD_HAUPPAUGE_HVR1800lp] = { | 53 | [CX23885_BOARD_HAUPPAUGE_HVR1800lp] = { |
54 | .name = "Hauppauge WinTV-HVR1800lp", | 54 | .name = "Hauppauge WinTV-HVR1800lp", |
@@ -57,19 +57,19 @@ struct cx23885_board cx23885_boards[] = { | |||
57 | .type = CX23885_VMUX_TELEVISION, | 57 | .type = CX23885_VMUX_TELEVISION, |
58 | .vmux = 0, | 58 | .vmux = 0, |
59 | .gpio0 = 0xff00, | 59 | .gpio0 = 0xff00, |
60 | },{ | 60 | }, { |
61 | .type = CX23885_VMUX_DEBUG, | 61 | .type = CX23885_VMUX_DEBUG, |
62 | .vmux = 0, | 62 | .vmux = 0, |
63 | .gpio0 = 0xff01, | 63 | .gpio0 = 0xff01, |
64 | },{ | 64 | }, { |
65 | .type = CX23885_VMUX_COMPOSITE1, | 65 | .type = CX23885_VMUX_COMPOSITE1, |
66 | .vmux = 1, | 66 | .vmux = 1, |
67 | .gpio0 = 0xff02, | 67 | .gpio0 = 0xff02, |
68 | },{ | 68 | }, { |
69 | .type = CX23885_VMUX_SVIDEO, | 69 | .type = CX23885_VMUX_SVIDEO, |
70 | .vmux = 2, | 70 | .vmux = 2, |
71 | .gpio0 = 0xff02, | 71 | .gpio0 = 0xff02, |
72 | }}, | 72 | } }, |
73 | }, | 73 | }, |
74 | [CX23885_BOARD_HAUPPAUGE_HVR1800] = { | 74 | [CX23885_BOARD_HAUPPAUGE_HVR1800] = { |
75 | .name = "Hauppauge WinTV-HVR1800", | 75 | .name = "Hauppauge WinTV-HVR1800", |
@@ -84,20 +84,20 @@ struct cx23885_board cx23885_boards[] = { | |||
84 | CX25840_VIN5_CH2 | | 84 | CX25840_VIN5_CH2 | |
85 | CX25840_VIN2_CH1, | 85 | CX25840_VIN2_CH1, |
86 | .gpio0 = 0, | 86 | .gpio0 = 0, |
87 | },{ | 87 | }, { |
88 | .type = CX23885_VMUX_COMPOSITE1, | 88 | .type = CX23885_VMUX_COMPOSITE1, |
89 | .vmux = CX25840_VIN7_CH3 | | 89 | .vmux = CX25840_VIN7_CH3 | |
90 | CX25840_VIN4_CH2 | | 90 | CX25840_VIN4_CH2 | |
91 | CX25840_VIN6_CH1, | 91 | CX25840_VIN6_CH1, |
92 | .gpio0 = 0, | 92 | .gpio0 = 0, |
93 | },{ | 93 | }, { |
94 | .type = CX23885_VMUX_SVIDEO, | 94 | .type = CX23885_VMUX_SVIDEO, |
95 | .vmux = CX25840_VIN7_CH3 | | 95 | .vmux = CX25840_VIN7_CH3 | |
96 | CX25840_VIN4_CH2 | | 96 | CX25840_VIN4_CH2 | |
97 | CX25840_VIN8_CH1 | | 97 | CX25840_VIN8_CH1 | |
98 | CX25840_SVIDEO_ON, | 98 | CX25840_SVIDEO_ON, |
99 | .gpio0 = 0, | 99 | .gpio0 = 0, |
100 | }}, | 100 | } }, |
101 | }, | 101 | }, |
102 | [CX23885_BOARD_HAUPPAUGE_HVR1250] = { | 102 | [CX23885_BOARD_HAUPPAUGE_HVR1250] = { |
103 | .name = "Hauppauge WinTV-HVR1250", | 103 | .name = "Hauppauge WinTV-HVR1250", |
@@ -106,19 +106,19 @@ struct cx23885_board cx23885_boards[] = { | |||
106 | .type = CX23885_VMUX_TELEVISION, | 106 | .type = CX23885_VMUX_TELEVISION, |
107 | .vmux = 0, | 107 | .vmux = 0, |
108 | .gpio0 = 0xff00, | 108 | .gpio0 = 0xff00, |
109 | },{ | 109 | }, { |
110 | .type = CX23885_VMUX_DEBUG, | 110 | .type = CX23885_VMUX_DEBUG, |
111 | .vmux = 0, | 111 | .vmux = 0, |
112 | .gpio0 = 0xff01, | 112 | .gpio0 = 0xff01, |
113 | },{ | 113 | }, { |
114 | .type = CX23885_VMUX_COMPOSITE1, | 114 | .type = CX23885_VMUX_COMPOSITE1, |
115 | .vmux = 1, | 115 | .vmux = 1, |
116 | .gpio0 = 0xff02, | 116 | .gpio0 = 0xff02, |
117 | },{ | 117 | }, { |
118 | .type = CX23885_VMUX_SVIDEO, | 118 | .type = CX23885_VMUX_SVIDEO, |
119 | .vmux = 2, | 119 | .vmux = 2, |
120 | .gpio0 = 0xff02, | 120 | .gpio0 = 0xff02, |
121 | }}, | 121 | } }, |
122 | }, | 122 | }, |
123 | [CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP] = { | 123 | [CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP] = { |
124 | .name = "DViCO FusionHDTV5 Express", | 124 | .name = "DViCO FusionHDTV5 Express", |
@@ -169,43 +169,43 @@ struct cx23885_subid cx23885_subids[] = { | |||
169 | .subvendor = 0x0070, | 169 | .subvendor = 0x0070, |
170 | .subdevice = 0x3400, | 170 | .subdevice = 0x3400, |
171 | .card = CX23885_BOARD_UNKNOWN, | 171 | .card = CX23885_BOARD_UNKNOWN, |
172 | },{ | 172 | }, { |
173 | .subvendor = 0x0070, | 173 | .subvendor = 0x0070, |
174 | .subdevice = 0x7600, | 174 | .subdevice = 0x7600, |
175 | .card = CX23885_BOARD_HAUPPAUGE_HVR1800lp, | 175 | .card = CX23885_BOARD_HAUPPAUGE_HVR1800lp, |
176 | },{ | 176 | }, { |
177 | .subvendor = 0x0070, | 177 | .subvendor = 0x0070, |
178 | .subdevice = 0x7800, | 178 | .subdevice = 0x7800, |
179 | .card = CX23885_BOARD_HAUPPAUGE_HVR1800, | 179 | .card = CX23885_BOARD_HAUPPAUGE_HVR1800, |
180 | },{ | 180 | }, { |
181 | .subvendor = 0x0070, | 181 | .subvendor = 0x0070, |
182 | .subdevice = 0x7801, | 182 | .subdevice = 0x7801, |
183 | .card = CX23885_BOARD_HAUPPAUGE_HVR1800, | 183 | .card = CX23885_BOARD_HAUPPAUGE_HVR1800, |
184 | },{ | 184 | }, { |
185 | .subvendor = 0x0070, | 185 | .subvendor = 0x0070, |
186 | .subdevice = 0x7809, | 186 | .subdevice = 0x7809, |
187 | .card = CX23885_BOARD_HAUPPAUGE_HVR1800, | 187 | .card = CX23885_BOARD_HAUPPAUGE_HVR1800, |
188 | },{ | 188 | }, { |
189 | .subvendor = 0x0070, | 189 | .subvendor = 0x0070, |
190 | .subdevice = 0x7911, | 190 | .subdevice = 0x7911, |
191 | .card = CX23885_BOARD_HAUPPAUGE_HVR1250, | 191 | .card = CX23885_BOARD_HAUPPAUGE_HVR1250, |
192 | },{ | 192 | }, { |
193 | .subvendor = 0x18ac, | 193 | .subvendor = 0x18ac, |
194 | .subdevice = 0xd500, | 194 | .subdevice = 0xd500, |
195 | .card = CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP, | 195 | .card = CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP, |
196 | },{ | 196 | }, { |
197 | .subvendor = 0x0070, | 197 | .subvendor = 0x0070, |
198 | .subdevice = 0x7790, | 198 | .subdevice = 0x7790, |
199 | .card = CX23885_BOARD_HAUPPAUGE_HVR1500Q, | 199 | .card = CX23885_BOARD_HAUPPAUGE_HVR1500Q, |
200 | },{ | 200 | }, { |
201 | .subvendor = 0x0070, | 201 | .subvendor = 0x0070, |
202 | .subdevice = 0x7797, | 202 | .subdevice = 0x7797, |
203 | .card = CX23885_BOARD_HAUPPAUGE_HVR1500Q, | 203 | .card = CX23885_BOARD_HAUPPAUGE_HVR1500Q, |
204 | },{ | 204 | }, { |
205 | .subvendor = 0x0070, | 205 | .subvendor = 0x0070, |
206 | .subdevice = 0x7710, | 206 | .subdevice = 0x7710, |
207 | .card = CX23885_BOARD_HAUPPAUGE_HVR1500, | 207 | .card = CX23885_BOARD_HAUPPAUGE_HVR1500, |
208 | },{ | 208 | }, { |
209 | .subvendor = 0x0070, | 209 | .subvendor = 0x0070, |
210 | .subdevice = 0x7717, | 210 | .subdevice = 0x7717, |
211 | .card = CX23885_BOARD_HAUPPAUGE_HVR1500, | 211 | .card = CX23885_BOARD_HAUPPAUGE_HVR1500, |
@@ -225,11 +225,11 @@ struct cx23885_subid cx23885_subids[] = { | |||
225 | .subvendor = 0x0070, | 225 | .subvendor = 0x0070, |
226 | .subdevice = 0x8010, | 226 | .subdevice = 0x8010, |
227 | .card = CX23885_BOARD_HAUPPAUGE_HVR1400, | 227 | .card = CX23885_BOARD_HAUPPAUGE_HVR1400, |
228 | },{ | 228 | }, { |
229 | .subvendor = 0x18ac, | 229 | .subvendor = 0x18ac, |
230 | .subdevice = 0xd618, | 230 | .subdevice = 0xd618, |
231 | .card = CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP, | 231 | .card = CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP, |
232 | },{ | 232 | }, { |
233 | .subvendor = 0x18ac, | 233 | .subvendor = 0x18ac, |
234 | .subdevice = 0xdb78, | 234 | .subdevice = 0xdb78, |
235 | .card = CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP, | 235 | .card = CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP, |
@@ -247,23 +247,25 @@ void cx23885_card_list(struct cx23885_dev *dev) | |||
247 | 247 | ||
248 | if (0 == dev->pci->subsystem_vendor && | 248 | if (0 == dev->pci->subsystem_vendor && |
249 | 0 == dev->pci->subsystem_device) { | 249 | 0 == dev->pci->subsystem_device) { |
250 | printk("%s: Your board has no valid PCIe Subsystem ID and thus can't\n" | 250 | printk(KERN_INFO |
251 | "%s: be autodetected. Please pass card=<n> insmod option to\n" | 251 | "%s: Board has no valid PCIe Subsystem ID and can't\n" |
252 | "%s: workaround that. Redirect complaints to the vendor of\n" | 252 | "%s: be autodetected. Pass card=<n> insmod option\n" |
253 | "%s: the TV card. Best regards,\n" | 253 | "%s: to workaround that. Redirect complaints to the\n" |
254 | "%s: vendor of the TV card. Best regards,\n" | ||
254 | "%s: -- tux\n", | 255 | "%s: -- tux\n", |
255 | dev->name, dev->name, dev->name, dev->name, dev->name); | 256 | dev->name, dev->name, dev->name, dev->name, dev->name); |
256 | } else { | 257 | } else { |
257 | printk("%s: Your board isn't known (yet) to the driver. You can\n" | 258 | printk(KERN_INFO |
258 | "%s: try to pick one of the existing card configs via\n" | 259 | "%s: Your board isn't known (yet) to the driver.\n" |
260 | "%s: Try to pick one of the existing card configs via\n" | ||
259 | "%s: card=<n> insmod option. Updating to the latest\n" | 261 | "%s: card=<n> insmod option. Updating to the latest\n" |
260 | "%s: version might help as well.\n", | 262 | "%s: version might help as well.\n", |
261 | dev->name, dev->name, dev->name, dev->name); | 263 | dev->name, dev->name, dev->name, dev->name); |
262 | } | 264 | } |
263 | printk("%s: Here is a list of valid choices for the card=<n> insmod option:\n", | 265 | printk(KERN_INFO "%s: Here is a list of valid choices for the card=<n> insmod option:\n", |
264 | dev->name); | 266 | dev->name); |
265 | for (i = 0; i < cx23885_bcount; i++) | 267 | for (i = 0; i < cx23885_bcount; i++) |
266 | printk("%s: card=%d -> %s\n", | 268 | printk(KERN_INFO "%s: card=%d -> %s\n", |
267 | dev->name, i, cx23885_boards[i].name); | 269 | dev->name, i, cx23885_boards[i].name); |
268 | } | 270 | } |
269 | 271 | ||
@@ -271,11 +273,11 @@ static void hauppauge_eeprom(struct cx23885_dev *dev, u8 *eeprom_data) | |||
271 | { | 273 | { |
272 | struct tveeprom tv; | 274 | struct tveeprom tv; |
273 | 275 | ||
274 | tveeprom_hauppauge_analog(&dev->i2c_bus[0].i2c_client, &tv, eeprom_data); | 276 | tveeprom_hauppauge_analog(&dev->i2c_bus[0].i2c_client, &tv, |
277 | eeprom_data); | ||
275 | 278 | ||
276 | /* Make sure we support the board model */ | 279 | /* Make sure we support the board model */ |
277 | switch (tv.model) | 280 | switch (tv.model) { |
278 | { | ||
279 | case 71009: | 281 | case 71009: |
280 | /* WinTV-HVR1200 (PCIe, Retail, full height) | 282 | /* WinTV-HVR1200 (PCIe, Retail, full height) |
281 | * DVB-T and basic analog */ | 283 | * DVB-T and basic analog */ |
@@ -303,21 +305,51 @@ static void hauppauge_eeprom(struct cx23885_dev *dev, u8 *eeprom_data) | |||
303 | case 71999: | 305 | case 71999: |
304 | /* WinTV-HVR1200 (PCIe, OEM, full height) | 306 | /* WinTV-HVR1200 (PCIe, OEM, full height) |
305 | * DVB-T and basic analog */ | 307 | * DVB-T and basic analog */ |
306 | case 76601: /* WinTV-HVR1800lp (PCIe, Retail, No IR, Dual channel ATSC and MPEG2 HW Encoder */ | 308 | case 76601: |
307 | case 77001: /* WinTV-HVR1500 (Express Card, OEM, No IR, ATSC and Basic analog */ | 309 | /* WinTV-HVR1800lp (PCIe, Retail, No IR, Dual |
308 | case 77011: /* WinTV-HVR1500 (Express Card, Retail, No IR, ATSC and Basic analog */ | 310 | channel ATSC and MPEG2 HW Encoder */ |
309 | case 77041: /* WinTV-HVR1500Q (Express Card, OEM, No IR, ATSC/QAM and Basic analog */ | 311 | case 77001: |
310 | case 77051: /* WinTV-HVR1500Q (Express Card, Retail, No IR, ATSC/QAM and Basic analog */ | 312 | /* WinTV-HVR1500 (Express Card, OEM, No IR, ATSC |
311 | case 78011: /* WinTV-HVR1800 (PCIe, Retail, 3.5mm in, IR, No FM, Dual channel ATSC and MPEG2 HW Encoder */ | 313 | and Basic analog */ |
312 | case 78501: /* WinTV-HVR1800 (PCIe, OEM, RCA in, No IR, FM, Dual channel ATSC and MPEG2 HW Encoder */ | 314 | case 77011: |
313 | case 78521: /* WinTV-HVR1800 (PCIe, OEM, RCA in, No IR, FM, Dual channel ATSC and MPEG2 HW Encoder */ | 315 | /* WinTV-HVR1500 (Express Card, Retail, No IR, ATSC |
314 | case 78531: /* WinTV-HVR1800 (PCIe, OEM, RCA in, No IR, No FM, Dual channel ATSC and MPEG2 HW Encoder */ | 316 | and Basic analog */ |
315 | case 78631: /* WinTV-HVR1800 (PCIe, OEM, No IR, No FM, Dual channel ATSC and MPEG2 HW Encoder */ | 317 | case 77041: |
316 | case 79001: /* WinTV-HVR1250 (PCIe, Retail, IR, full height, ATSC and Basic analog */ | 318 | /* WinTV-HVR1500Q (Express Card, OEM, No IR, ATSC/QAM |
317 | case 79101: /* WinTV-HVR1250 (PCIe, Retail, IR, half height, ATSC and Basic analog */ | 319 | and Basic analog */ |
318 | case 79561: /* WinTV-HVR1250 (PCIe, OEM, No IR, half height, ATSC and Basic analog */ | 320 | case 77051: |
319 | case 79571: /* WinTV-HVR1250 (PCIe, OEM, No IR, full height, ATSC and Basic analog */ | 321 | /* WinTV-HVR1500Q (Express Card, Retail, No IR, ATSC/QAM |
320 | case 79671: /* WinTV-HVR1250 (PCIe, OEM, No IR, half height, ATSC and Basic analog */ | 322 | and Basic analog */ |
323 | case 78011: | ||
324 | /* WinTV-HVR1800 (PCIe, Retail, 3.5mm in, IR, No FM, | ||
325 | Dual channel ATSC and MPEG2 HW Encoder */ | ||
326 | case 78501: | ||
327 | /* WinTV-HVR1800 (PCIe, OEM, RCA in, No IR, FM, | ||
328 | Dual channel ATSC and MPEG2 HW Encoder */ | ||
329 | case 78521: | ||
330 | /* WinTV-HVR1800 (PCIe, OEM, RCA in, No IR, FM, | ||
331 | Dual channel ATSC and MPEG2 HW Encoder */ | ||
332 | case 78531: | ||
333 | /* WinTV-HVR1800 (PCIe, OEM, RCA in, No IR, No FM, | ||
334 | Dual channel ATSC and MPEG2 HW Encoder */ | ||
335 | case 78631: | ||
336 | /* WinTV-HVR1800 (PCIe, OEM, No IR, No FM, | ||
337 | Dual channel ATSC and MPEG2 HW Encoder */ | ||
338 | case 79001: | ||
339 | /* WinTV-HVR1250 (PCIe, Retail, IR, full height, | ||
340 | ATSC and Basic analog */ | ||
341 | case 79101: | ||
342 | /* WinTV-HVR1250 (PCIe, Retail, IR, half height, | ||
343 | ATSC and Basic analog */ | ||
344 | case 79561: | ||
345 | /* WinTV-HVR1250 (PCIe, OEM, No IR, half height, | ||
346 | ATSC and Basic analog */ | ||
347 | case 79571: | ||
348 | /* WinTV-HVR1250 (PCIe, OEM, No IR, full height, | ||
349 | ATSC and Basic analog */ | ||
350 | case 79671: | ||
351 | /* WinTV-HVR1250 (PCIe, OEM, No IR, half height, | ||
352 | ATSC and Basic analog */ | ||
321 | case 80019: | 353 | case 80019: |
322 | /* WinTV-HVR1400 (Express Card, Retail, IR, | 354 | /* WinTV-HVR1400 (Express Card, Retail, IR, |
323 | * DVB-T and Basic analog */ | 355 | * DVB-T and Basic analog */ |
@@ -329,7 +361,8 @@ static void hauppauge_eeprom(struct cx23885_dev *dev, u8 *eeprom_data) | |||
329 | * DVB-T and MPEG2 HW Encoder */ | 361 | * DVB-T and MPEG2 HW Encoder */ |
330 | break; | 362 | break; |
331 | default: | 363 | default: |
332 | printk("%s: warning: unknown hauppauge model #%d\n", dev->name, tv.model); | 364 | printk(KERN_WARNING "%s: warning: unknown hauppauge model #%d\n", |
365 | dev->name, tv.model); | ||
333 | break; | 366 | break; |
334 | } | 367 | } |
335 | 368 | ||
@@ -352,7 +385,7 @@ int cx23885_tuner_callback(void *priv, int component, int command, int arg) | |||
352 | return -EINVAL; | 385 | return -EINVAL; |
353 | } | 386 | } |
354 | 387 | ||
355 | switch(dev->board) { | 388 | switch (dev->board) { |
356 | case CX23885_BOARD_HAUPPAUGE_HVR1400: | 389 | case CX23885_BOARD_HAUPPAUGE_HVR1400: |
357 | case CX23885_BOARD_HAUPPAUGE_HVR1500: | 390 | case CX23885_BOARD_HAUPPAUGE_HVR1500: |
358 | case CX23885_BOARD_HAUPPAUGE_HVR1500Q: | 391 | case CX23885_BOARD_HAUPPAUGE_HVR1500Q: |
@@ -383,7 +416,7 @@ int cx23885_tuner_callback(void *priv, int component, int command, int arg) | |||
383 | 416 | ||
384 | void cx23885_gpio_setup(struct cx23885_dev *dev) | 417 | void cx23885_gpio_setup(struct cx23885_dev *dev) |
385 | { | 418 | { |
386 | switch(dev->board) { | 419 | switch (dev->board) { |
387 | case CX23885_BOARD_HAUPPAUGE_HVR1250: | 420 | case CX23885_BOARD_HAUPPAUGE_HVR1250: |
388 | /* GPIO-0 cx24227 demodulator reset */ | 421 | /* GPIO-0 cx24227 demodulator reset */ |
389 | cx_set(GP0_IO, 0x00010001); /* Bring the part out of reset */ | 422 | cx_set(GP0_IO, 0x00010001); /* Bring the part out of reset */ |
@@ -617,10 +650,3 @@ void cx23885_card_setup(struct cx23885_dev *dev) | |||
617 | } | 650 | } |
618 | 651 | ||
619 | /* ------------------------------------------------------------------ */ | 652 | /* ------------------------------------------------------------------ */ |
620 | |||
621 | /* | ||
622 | * Local variables: | ||
623 | * c-basic-offset: 8 | ||
624 | * End: | ||
625 | * kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off | ||
626 | */ | ||
diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c index beb3e61669a3..8f6fb2add7de 100644 --- a/drivers/media/video/cx23885/cx23885-core.c +++ b/drivers/media/video/cx23885/cx23885-core.c | |||
@@ -37,12 +37,12 @@ MODULE_AUTHOR("Steven Toth <stoth@linuxtv.org>"); | |||
37 | MODULE_LICENSE("GPL"); | 37 | MODULE_LICENSE("GPL"); |
38 | 38 | ||
39 | static unsigned int debug; | 39 | static unsigned int debug; |
40 | module_param(debug,int,0644); | 40 | module_param(debug, int, 0644); |
41 | MODULE_PARM_DESC(debug,"enable debug messages"); | 41 | MODULE_PARM_DESC(debug, "enable debug messages"); |
42 | 42 | ||
43 | static unsigned int card[] = {[0 ... (CX23885_MAXBOARDS - 1)] = UNSET }; | 43 | static unsigned int card[] = {[0 ... (CX23885_MAXBOARDS - 1)] = UNSET }; |
44 | module_param_array(card, int, NULL, 0444); | 44 | module_param_array(card, int, NULL, 0444); |
45 | MODULE_PARM_DESC(card,"card type"); | 45 | MODULE_PARM_DESC(card, "card type"); |
46 | 46 | ||
47 | #define dprintk(level, fmt, arg...)\ | 47 | #define dprintk(level, fmt, arg...)\ |
48 | do { if (debug >= level)\ | 48 | do { if (debug >= level)\ |
@@ -364,13 +364,12 @@ void cx23885_wakeup(struct cx23885_tsport *port, | |||
364 | list_del(&buf->vb.queue); | 364 | list_del(&buf->vb.queue); |
365 | wake_up(&buf->vb.done); | 365 | wake_up(&buf->vb.done); |
366 | } | 366 | } |
367 | if (list_empty(&q->active)) { | 367 | if (list_empty(&q->active)) |
368 | del_timer(&q->timeout); | 368 | del_timer(&q->timeout); |
369 | } else { | 369 | else |
370 | mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT); | 370 | mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT); |
371 | } | ||
372 | if (bc != 1) | 371 | if (bc != 1) |
373 | printk("%s: %d buffers handled (should be 1)\n", | 372 | printk(KERN_WARNING "%s: %d buffers handled (should be 1)\n", |
374 | __func__, bc); | 373 | __func__, bc); |
375 | } | 374 | } |
376 | 375 | ||
@@ -381,8 +380,7 @@ int cx23885_sram_channel_setup(struct cx23885_dev *dev, | |||
381 | unsigned int i, lines; | 380 | unsigned int i, lines; |
382 | u32 cdt; | 381 | u32 cdt; |
383 | 382 | ||
384 | if (ch->cmds_start == 0) | 383 | if (ch->cmds_start == 0) { |
385 | { | ||
386 | dprintk(1, "%s() Erasing channel [%s]\n", __func__, | 384 | dprintk(1, "%s() Erasing channel [%s]\n", __func__, |
387 | ch->name); | 385 | ch->name); |
388 | cx_write(ch->ptr1_reg, 0); | 386 | cx_write(ch->ptr1_reg, 0); |
@@ -418,15 +416,15 @@ int cx23885_sram_channel_setup(struct cx23885_dev *dev, | |||
418 | 416 | ||
419 | /* write CMDS */ | 417 | /* write CMDS */ |
420 | if (ch->jumponly) | 418 | if (ch->jumponly) |
421 | cx_write(ch->cmds_start + 0, 8); | 419 | cx_write(ch->cmds_start + 0, 8); |
422 | else | 420 | else |
423 | cx_write(ch->cmds_start + 0, risc); | 421 | cx_write(ch->cmds_start + 0, risc); |
424 | cx_write(ch->cmds_start + 4, 0); /* 64 bits 63-32 */ | 422 | cx_write(ch->cmds_start + 4, 0); /* 64 bits 63-32 */ |
425 | cx_write(ch->cmds_start + 8, cdt); | 423 | cx_write(ch->cmds_start + 8, cdt); |
426 | cx_write(ch->cmds_start + 12, (lines*16) >> 3); | 424 | cx_write(ch->cmds_start + 12, (lines*16) >> 3); |
427 | cx_write(ch->cmds_start + 16, ch->ctrl_start); | 425 | cx_write(ch->cmds_start + 16, ch->ctrl_start); |
428 | if (ch->jumponly) | 426 | if (ch->jumponly) |
429 | cx_write(ch->cmds_start + 20, 0x80000000 | (64 >> 2) ); | 427 | cx_write(ch->cmds_start + 20, 0x80000000 | (64 >> 2)); |
430 | else | 428 | else |
431 | cx_write(ch->cmds_start + 20, 64 >> 2); | 429 | cx_write(ch->cmds_start + 20, 64 >> 2); |
432 | for (i = 24; i < 80; i += 4) | 430 | for (i = 24; i < 80; i += 4) |
@@ -436,9 +434,9 @@ int cx23885_sram_channel_setup(struct cx23885_dev *dev, | |||
436 | cx_write(ch->ptr1_reg, ch->fifo_start); | 434 | cx_write(ch->ptr1_reg, ch->fifo_start); |
437 | cx_write(ch->ptr2_reg, cdt); | 435 | cx_write(ch->ptr2_reg, cdt); |
438 | cx_write(ch->cnt2_reg, (lines*16) >> 3); | 436 | cx_write(ch->cnt2_reg, (lines*16) >> 3); |
439 | cx_write(ch->cnt1_reg, (bpl >> 3) -1); | 437 | cx_write(ch->cnt1_reg, (bpl >> 3) - 1); |
440 | 438 | ||
441 | dprintk(2,"[bridge %d] sram setup %s: bpl=%d lines=%d\n", | 439 | dprintk(2, "[bridge %d] sram setup %s: bpl=%d lines=%d\n", |
442 | dev->bridge, | 440 | dev->bridge, |
443 | ch->name, | 441 | ch->name, |
444 | bpl, | 442 | bpl, |
@@ -469,43 +467,43 @@ void cx23885_sram_channel_dump(struct cx23885_dev *dev, | |||
469 | u32 risc; | 467 | u32 risc; |
470 | unsigned int i, j, n; | 468 | unsigned int i, j, n; |
471 | 469 | ||
472 | printk("%s: %s - dma channel status dump\n", | 470 | printk(KERN_WARNING "%s: %s - dma channel status dump\n", |
473 | dev->name, ch->name); | 471 | dev->name, ch->name); |
474 | for (i = 0; i < ARRAY_SIZE(name); i++) | 472 | for (i = 0; i < ARRAY_SIZE(name); i++) |
475 | printk("%s: cmds: %-15s: 0x%08x\n", | 473 | printk(KERN_WARNING "%s: cmds: %-15s: 0x%08x\n", |
476 | dev->name, name[i], | 474 | dev->name, name[i], |
477 | cx_read(ch->cmds_start + 4*i)); | 475 | cx_read(ch->cmds_start + 4*i)); |
478 | 476 | ||
479 | for (i = 0; i < 4; i++) { | 477 | for (i = 0; i < 4; i++) { |
480 | risc = cx_read(ch->cmds_start + 4 * (i + 14)); | 478 | risc = cx_read(ch->cmds_start + 4 * (i + 14)); |
481 | printk("%s: risc%d: ", dev->name, i); | 479 | printk(KERN_WARNING "%s: risc%d: ", dev->name, i); |
482 | cx23885_risc_decode(risc); | 480 | cx23885_risc_decode(risc); |
483 | } | 481 | } |
484 | for (i = 0; i < (64 >> 2); i += n) { | 482 | for (i = 0; i < (64 >> 2); i += n) { |
485 | risc = cx_read(ch->ctrl_start + 4 * i); | 483 | risc = cx_read(ch->ctrl_start + 4 * i); |
486 | /* No consideration for bits 63-32 */ | 484 | /* No consideration for bits 63-32 */ |
487 | 485 | ||
488 | printk("%s: (0x%08x) iq %x: ", dev->name, | 486 | printk(KERN_WARNING "%s: (0x%08x) iq %x: ", dev->name, |
489 | ch->ctrl_start + 4 * i, i); | 487 | ch->ctrl_start + 4 * i, i); |
490 | n = cx23885_risc_decode(risc); | 488 | n = cx23885_risc_decode(risc); |
491 | for (j = 1; j < n; j++) { | 489 | for (j = 1; j < n; j++) { |
492 | risc = cx_read(ch->ctrl_start + 4 * (i + j)); | 490 | risc = cx_read(ch->ctrl_start + 4 * (i + j)); |
493 | printk("%s: iq %x: 0x%08x [ arg #%d ]\n", | 491 | printk(KERN_WARNING "%s: iq %x: 0x%08x [ arg #%d ]\n", |
494 | dev->name, i+j, risc, j); | 492 | dev->name, i+j, risc, j); |
495 | } | 493 | } |
496 | } | 494 | } |
497 | 495 | ||
498 | printk("%s: fifo: 0x%08x -> 0x%x\n", | 496 | printk(KERN_WARNING "%s: fifo: 0x%08x -> 0x%x\n", |
499 | dev->name, ch->fifo_start, ch->fifo_start+ch->fifo_size); | 497 | dev->name, ch->fifo_start, ch->fifo_start+ch->fifo_size); |
500 | printk("%s: ctrl: 0x%08x -> 0x%x\n", | 498 | printk(KERN_WARNING "%s: ctrl: 0x%08x -> 0x%x\n", |
501 | dev->name, ch->ctrl_start, ch->ctrl_start + 6*16); | 499 | dev->name, ch->ctrl_start, ch->ctrl_start + 6*16); |
502 | printk("%s: ptr1_reg: 0x%08x\n", | 500 | printk(KERN_WARNING "%s: ptr1_reg: 0x%08x\n", |
503 | dev->name, cx_read(ch->ptr1_reg)); | 501 | dev->name, cx_read(ch->ptr1_reg)); |
504 | printk("%s: ptr2_reg: 0x%08x\n", | 502 | printk(KERN_WARNING "%s: ptr2_reg: 0x%08x\n", |
505 | dev->name, cx_read(ch->ptr2_reg)); | 503 | dev->name, cx_read(ch->ptr2_reg)); |
506 | printk("%s: cnt1_reg: 0x%08x\n", | 504 | printk(KERN_WARNING "%s: cnt1_reg: 0x%08x\n", |
507 | dev->name, cx_read(ch->cnt1_reg)); | 505 | dev->name, cx_read(ch->cnt1_reg)); |
508 | printk("%s: cnt2_reg: 0x%08x\n", | 506 | printk(KERN_WARNING "%s: cnt2_reg: 0x%08x\n", |
509 | dev->name, cx_read(ch->cnt2_reg)); | 507 | dev->name, cx_read(ch->cnt2_reg)); |
510 | } | 508 | } |
511 | 509 | ||
@@ -515,13 +513,13 @@ static void cx23885_risc_disasm(struct cx23885_tsport *port, | |||
515 | struct cx23885_dev *dev = port->dev; | 513 | struct cx23885_dev *dev = port->dev; |
516 | unsigned int i, j, n; | 514 | unsigned int i, j, n; |
517 | 515 | ||
518 | printk("%s: risc disasm: %p [dma=0x%08lx]\n", | 516 | printk(KERN_INFO "%s: risc disasm: %p [dma=0x%08lx]\n", |
519 | dev->name, risc->cpu, (unsigned long)risc->dma); | 517 | dev->name, risc->cpu, (unsigned long)risc->dma); |
520 | for (i = 0; i < (risc->size >> 2); i += n) { | 518 | for (i = 0; i < (risc->size >> 2); i += n) { |
521 | printk("%s: %04d: ", dev->name, i); | 519 | printk(KERN_INFO "%s: %04d: ", dev->name, i); |
522 | n = cx23885_risc_decode(le32_to_cpu(risc->cpu[i])); | 520 | n = cx23885_risc_decode(le32_to_cpu(risc->cpu[i])); |
523 | for (j = 1; j < n; j++) | 521 | for (j = 1; j < n; j++) |
524 | printk("%s: %04d: 0x%08x [ arg #%d ]\n", | 522 | printk(KERN_INFO "%s: %04d: 0x%08x [ arg #%d ]\n", |
525 | dev->name, i + j, risc->cpu[i + j], j); | 523 | dev->name, i + j, risc->cpu[i + j], j); |
526 | if (risc->cpu[i] == cpu_to_le32(RISC_JUMP)) | 524 | if (risc->cpu[i] == cpu_to_le32(RISC_JUMP)) |
527 | break; | 525 | break; |
@@ -600,7 +598,7 @@ static int cx23885_pci_quirks(struct cx23885_dev *dev) | |||
600 | * when DMA begins if RDR_TLCTL0 bit4 is not cleared. It does not | 598 | * when DMA begins if RDR_TLCTL0 bit4 is not cleared. It does not |
601 | * occur on the cx23887 bridge. | 599 | * occur on the cx23887 bridge. |
602 | */ | 600 | */ |
603 | if(dev->bridge == CX23885_BRIDGE_885) | 601 | if (dev->bridge == CX23885_BRIDGE_885) |
604 | cx_clear(RDR_TLCTL0, 1 << 4); | 602 | cx_clear(RDR_TLCTL0, 1 << 4); |
605 | 603 | ||
606 | return 0; | 604 | return 0; |
@@ -608,13 +606,13 @@ static int cx23885_pci_quirks(struct cx23885_dev *dev) | |||
608 | 606 | ||
609 | static int get_resources(struct cx23885_dev *dev) | 607 | static int get_resources(struct cx23885_dev *dev) |
610 | { | 608 | { |
611 | if (request_mem_region(pci_resource_start(dev->pci,0), | 609 | if (request_mem_region(pci_resource_start(dev->pci, 0), |
612 | pci_resource_len(dev->pci,0), | 610 | pci_resource_len(dev->pci, 0), |
613 | dev->name)) | 611 | dev->name)) |
614 | return 0; | 612 | return 0; |
615 | 613 | ||
616 | printk(KERN_ERR "%s: can't get MMIO memory @ 0x%llx\n", | 614 | printk(KERN_ERR "%s: can't get MMIO memory @ 0x%llx\n", |
617 | dev->name, (unsigned long long)pci_resource_start(dev->pci,0)); | 615 | dev->name, (unsigned long long)pci_resource_start(dev->pci, 0)); |
618 | 616 | ||
619 | return -EBUSY; | 617 | return -EBUSY; |
620 | } | 618 | } |
@@ -623,7 +621,8 @@ static void cx23885_timeout(unsigned long data); | |||
623 | int cx23885_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc, | 621 | int cx23885_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc, |
624 | u32 reg, u32 mask, u32 value); | 622 | u32 reg, u32 mask, u32 value); |
625 | 623 | ||
626 | static int cx23885_init_tsport(struct cx23885_dev *dev, struct cx23885_tsport *port, int portno) | 624 | static int cx23885_init_tsport(struct cx23885_dev *dev, |
625 | struct cx23885_tsport *port, int portno) | ||
627 | { | 626 | { |
628 | dprintk(1, "%s(portno=%d)\n", __func__, portno); | 627 | dprintk(1, "%s(portno=%d)\n", __func__, portno); |
629 | 628 | ||
@@ -643,7 +642,18 @@ static int cx23885_init_tsport(struct cx23885_dev *dev, struct cx23885_tsport *p | |||
643 | port->mpegq.timeout.data = (unsigned long)port; | 642 | port->mpegq.timeout.data = (unsigned long)port; |
644 | init_timer(&port->mpegq.timeout); | 643 | init_timer(&port->mpegq.timeout); |
645 | 644 | ||
646 | switch(portno) { | 645 | mutex_init(&port->frontends.lock); |
646 | INIT_LIST_HEAD(&port->frontends.felist); | ||
647 | port->frontends.active_fe_id = 0; | ||
648 | |||
649 | /* This should be hardcoded allow a single frontend | ||
650 | * attachment to this tsport, keeping the -dvb.c | ||
651 | * code clean and safe. | ||
652 | */ | ||
653 | if (!port->num_frontends) | ||
654 | port->num_frontends = 1; | ||
655 | |||
656 | switch (portno) { | ||
647 | case 1: | 657 | case 1: |
648 | port->reg_gpcnt = VID_B_GPCNT; | 658 | port->reg_gpcnt = VID_B_GPCNT; |
649 | port->reg_gpcnt_ctl = VID_B_GPCNT_CTL; | 659 | port->reg_gpcnt_ctl = VID_B_GPCNT_CTL; |
@@ -744,13 +754,13 @@ static int cx23885_dev_setup(struct cx23885_dev *dev) | |||
744 | mutex_unlock(&devlist); | 754 | mutex_unlock(&devlist); |
745 | 755 | ||
746 | /* Configure the internal memory */ | 756 | /* Configure the internal memory */ |
747 | if(dev->pci->device == 0x8880) { | 757 | if (dev->pci->device == 0x8880) { |
748 | dev->bridge = CX23885_BRIDGE_887; | 758 | dev->bridge = CX23885_BRIDGE_887; |
749 | /* Apply a sensible clock frequency for the PCIe bridge */ | 759 | /* Apply a sensible clock frequency for the PCIe bridge */ |
750 | dev->clk_freq = 25000000; | 760 | dev->clk_freq = 25000000; |
751 | dev->sram_channels = cx23887_sram_channels; | 761 | dev->sram_channels = cx23887_sram_channels; |
752 | } else | 762 | } else |
753 | if(dev->pci->device == 0x8852) { | 763 | if (dev->pci->device == 0x8852) { |
754 | dev->bridge = CX23885_BRIDGE_885; | 764 | dev->bridge = CX23885_BRIDGE_885; |
755 | /* Apply a sensible clock frequency for the PCIe bridge */ | 765 | /* Apply a sensible clock frequency for the PCIe bridge */ |
756 | dev->clk_freq = 28000000; | 766 | dev->clk_freq = 28000000; |
@@ -831,8 +841,8 @@ static int cx23885_dev_setup(struct cx23885_dev *dev) | |||
831 | } | 841 | } |
832 | 842 | ||
833 | /* PCIe stuff */ | 843 | /* PCIe stuff */ |
834 | dev->lmmio = ioremap(pci_resource_start(dev->pci,0), | 844 | dev->lmmio = ioremap(pci_resource_start(dev->pci, 0), |
835 | pci_resource_len(dev->pci,0)); | 845 | pci_resource_len(dev->pci, 0)); |
836 | 846 | ||
837 | dev->bmmio = (u8 __iomem *)dev->lmmio; | 847 | dev->bmmio = (u8 __iomem *)dev->lmmio; |
838 | 848 | ||
@@ -862,7 +872,7 @@ static int cx23885_dev_setup(struct cx23885_dev *dev) | |||
862 | cx23885_i2c_register(&dev->i2c_bus[1]); | 872 | cx23885_i2c_register(&dev->i2c_bus[1]); |
863 | cx23885_i2c_register(&dev->i2c_bus[2]); | 873 | cx23885_i2c_register(&dev->i2c_bus[2]); |
864 | cx23885_card_setup(dev); | 874 | cx23885_card_setup(dev); |
865 | cx23885_call_i2c_clients (&dev->i2c_bus[0], TUNER_SET_STANDBY, NULL); | 875 | cx23885_call_i2c_clients(&dev->i2c_bus[0], TUNER_SET_STANDBY, NULL); |
866 | cx23885_ir_init(dev); | 876 | cx23885_ir_init(dev); |
867 | 877 | ||
868 | if (cx23885_boards[dev->board].porta == CX23885_ANALOG_VIDEO) { | 878 | if (cx23885_boards[dev->board].porta == CX23885_ANALOG_VIDEO) { |
@@ -908,8 +918,8 @@ static int cx23885_dev_setup(struct cx23885_dev *dev) | |||
908 | 918 | ||
909 | static void cx23885_dev_unregister(struct cx23885_dev *dev) | 919 | static void cx23885_dev_unregister(struct cx23885_dev *dev) |
910 | { | 920 | { |
911 | release_mem_region(pci_resource_start(dev->pci,0), | 921 | release_mem_region(pci_resource_start(dev->pci, 0), |
912 | pci_resource_len(dev->pci,0)); | 922 | pci_resource_len(dev->pci, 0)); |
913 | 923 | ||
914 | if (!atomic_dec_and_test(&dev->refcount)) | 924 | if (!atomic_dec_and_test(&dev->refcount)) |
915 | return; | 925 | return; |
@@ -936,7 +946,7 @@ static void cx23885_dev_unregister(struct cx23885_dev *dev) | |||
936 | iounmap(dev->lmmio); | 946 | iounmap(dev->lmmio); |
937 | } | 947 | } |
938 | 948 | ||
939 | static __le32* cx23885_risc_field(__le32 *rp, struct scatterlist *sglist, | 949 | static __le32 *cx23885_risc_field(__le32 *rp, struct scatterlist *sglist, |
940 | unsigned int offset, u32 sync_line, | 950 | unsigned int offset, u32 sync_line, |
941 | unsigned int bpl, unsigned int padding, | 951 | unsigned int bpl, unsigned int padding, |
942 | unsigned int lines) | 952 | unsigned int lines) |
@@ -957,31 +967,31 @@ static __le32* cx23885_risc_field(__le32 *rp, struct scatterlist *sglist, | |||
957 | } | 967 | } |
958 | if (bpl <= sg_dma_len(sg)-offset) { | 968 | if (bpl <= sg_dma_len(sg)-offset) { |
959 | /* fits into current chunk */ | 969 | /* fits into current chunk */ |
960 | *(rp++)=cpu_to_le32(RISC_WRITE|RISC_SOL|RISC_EOL|bpl); | 970 | *(rp++) = cpu_to_le32(RISC_WRITE|RISC_SOL|RISC_EOL|bpl); |
961 | *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset); | 971 | *(rp++) = cpu_to_le32(sg_dma_address(sg)+offset); |
962 | *(rp++)=cpu_to_le32(0); /* bits 63-32 */ | 972 | *(rp++) = cpu_to_le32(0); /* bits 63-32 */ |
963 | offset+=bpl; | 973 | offset += bpl; |
964 | } else { | 974 | } else { |
965 | /* scanline needs to be split */ | 975 | /* scanline needs to be split */ |
966 | todo = bpl; | 976 | todo = bpl; |
967 | *(rp++)=cpu_to_le32(RISC_WRITE|RISC_SOL| | 977 | *(rp++) = cpu_to_le32(RISC_WRITE|RISC_SOL| |
968 | (sg_dma_len(sg)-offset)); | 978 | (sg_dma_len(sg)-offset)); |
969 | *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset); | 979 | *(rp++) = cpu_to_le32(sg_dma_address(sg)+offset); |
970 | *(rp++)=cpu_to_le32(0); /* bits 63-32 */ | 980 | *(rp++) = cpu_to_le32(0); /* bits 63-32 */ |
971 | todo -= (sg_dma_len(sg)-offset); | 981 | todo -= (sg_dma_len(sg)-offset); |
972 | offset = 0; | 982 | offset = 0; |
973 | sg++; | 983 | sg++; |
974 | while (todo > sg_dma_len(sg)) { | 984 | while (todo > sg_dma_len(sg)) { |
975 | *(rp++)=cpu_to_le32(RISC_WRITE| | 985 | *(rp++) = cpu_to_le32(RISC_WRITE| |
976 | sg_dma_len(sg)); | 986 | sg_dma_len(sg)); |
977 | *(rp++)=cpu_to_le32(sg_dma_address(sg)); | 987 | *(rp++) = cpu_to_le32(sg_dma_address(sg)); |
978 | *(rp++)=cpu_to_le32(0); /* bits 63-32 */ | 988 | *(rp++) = cpu_to_le32(0); /* bits 63-32 */ |
979 | todo -= sg_dma_len(sg); | 989 | todo -= sg_dma_len(sg); |
980 | sg++; | 990 | sg++; |
981 | } | 991 | } |
982 | *(rp++)=cpu_to_le32(RISC_WRITE|RISC_EOL|todo); | 992 | *(rp++) = cpu_to_le32(RISC_WRITE|RISC_EOL|todo); |
983 | *(rp++)=cpu_to_le32(sg_dma_address(sg)); | 993 | *(rp++) = cpu_to_le32(sg_dma_address(sg)); |
984 | *(rp++)=cpu_to_le32(0); /* bits 63-32 */ | 994 | *(rp++) = cpu_to_le32(0); /* bits 63-32 */ |
985 | offset += todo; | 995 | offset += todo; |
986 | } | 996 | } |
987 | offset += padding; | 997 | offset += padding; |
@@ -1010,9 +1020,11 @@ int cx23885_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc, | |||
1010 | can cause next bpl to start close to a page border. First DMA | 1020 | can cause next bpl to start close to a page border. First DMA |
1011 | region may be smaller than PAGE_SIZE */ | 1021 | region may be smaller than PAGE_SIZE */ |
1012 | /* write and jump need and extra dword */ | 1022 | /* write and jump need and extra dword */ |
1013 | instructions = fields * (1 + ((bpl + padding) * lines) / PAGE_SIZE + lines); | 1023 | instructions = fields * (1 + ((bpl + padding) * lines) |
1024 | / PAGE_SIZE + lines); | ||
1014 | instructions += 2; | 1025 | instructions += 2; |
1015 | if ((rc = btcx_riscmem_alloc(pci,risc,instructions*12)) < 0) | 1026 | rc = btcx_riscmem_alloc(pci, risc, instructions*12); |
1027 | if (rc < 0) | ||
1016 | return rc; | 1028 | return rc; |
1017 | 1029 | ||
1018 | /* write risc instructions */ | 1030 | /* write risc instructions */ |
@@ -1026,7 +1038,7 @@ int cx23885_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc, | |||
1026 | 1038 | ||
1027 | /* save pointer to jmp instruction address */ | 1039 | /* save pointer to jmp instruction address */ |
1028 | risc->jmp = rp; | 1040 | risc->jmp = rp; |
1029 | BUG_ON((risc->jmp - risc->cpu + 2) * sizeof (*risc->cpu) > risc->size); | 1041 | BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size); |
1030 | return 0; | 1042 | return 0; |
1031 | } | 1043 | } |
1032 | 1044 | ||
@@ -1048,7 +1060,8 @@ static int cx23885_risc_databuffer(struct pci_dev *pci, | |||
1048 | instructions = 1 + (bpl * lines) / PAGE_SIZE + lines; | 1060 | instructions = 1 + (bpl * lines) / PAGE_SIZE + lines; |
1049 | instructions += 1; | 1061 | instructions += 1; |
1050 | 1062 | ||
1051 | if ((rc = btcx_riscmem_alloc(pci,risc,instructions*12)) < 0) | 1063 | rc = btcx_riscmem_alloc(pci, risc, instructions*12); |
1064 | if (rc < 0) | ||
1052 | return rc; | 1065 | return rc; |
1053 | 1066 | ||
1054 | /* write risc instructions */ | 1067 | /* write risc instructions */ |
@@ -1057,7 +1070,7 @@ static int cx23885_risc_databuffer(struct pci_dev *pci, | |||
1057 | 1070 | ||
1058 | /* save pointer to jmp instruction address */ | 1071 | /* save pointer to jmp instruction address */ |
1059 | risc->jmp = rp; | 1072 | risc->jmp = rp; |
1060 | BUG_ON((risc->jmp - risc->cpu + 2) * sizeof (*risc->cpu) > risc->size); | 1073 | BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size); |
1061 | return 0; | 1074 | return 0; |
1062 | } | 1075 | } |
1063 | 1076 | ||
@@ -1067,7 +1080,8 @@ int cx23885_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc, | |||
1067 | __le32 *rp; | 1080 | __le32 *rp; |
1068 | int rc; | 1081 | int rc; |
1069 | 1082 | ||
1070 | if ((rc = btcx_riscmem_alloc(pci, risc, 4*16)) < 0) | 1083 | rc = btcx_riscmem_alloc(pci, risc, 4*16); |
1084 | if (rc < 0) | ||
1071 | return rc; | 1085 | return rc; |
1072 | 1086 | ||
1073 | /* write risc instructions */ | 1087 | /* write risc instructions */ |
@@ -1161,22 +1175,23 @@ static int cx23885_start_dma(struct cx23885_tsport *port, | |||
1161 | 1175 | ||
1162 | /* setup fifo + format */ | 1176 | /* setup fifo + format */ |
1163 | cx23885_sram_channel_setup(dev, | 1177 | cx23885_sram_channel_setup(dev, |
1164 | &dev->sram_channels[ port->sram_chno ], | 1178 | &dev->sram_channels[port->sram_chno], |
1165 | port->ts_packet_size, buf->risc.dma); | 1179 | port->ts_packet_size, buf->risc.dma); |
1166 | if(debug > 5) { | 1180 | if (debug > 5) { |
1167 | cx23885_sram_channel_dump(dev, &dev->sram_channels[ port->sram_chno ] ); | 1181 | cx23885_sram_channel_dump(dev, |
1182 | &dev->sram_channels[port->sram_chno]); | ||
1168 | cx23885_risc_disasm(port, &buf->risc); | 1183 | cx23885_risc_disasm(port, &buf->risc); |
1169 | } | 1184 | } |
1170 | 1185 | ||
1171 | /* write TS length to chip */ | 1186 | /* write TS length to chip */ |
1172 | cx_write(port->reg_lngth, buf->vb.width); | 1187 | cx_write(port->reg_lngth, buf->vb.width); |
1173 | 1188 | ||
1174 | if ( (!(cx23885_boards[dev->board].portb & CX23885_MPEG_DVB)) && | 1189 | if ((!(cx23885_boards[dev->board].portb & CX23885_MPEG_DVB)) && |
1175 | (!(cx23885_boards[dev->board].portc & CX23885_MPEG_DVB)) ) { | 1190 | (!(cx23885_boards[dev->board].portc & CX23885_MPEG_DVB))) { |
1176 | printk( "%s() Failed. Unsupported value in .portb/c (0x%08x)/(0x%08x)\n", | 1191 | printk("%s() Unsupported .portb/c (0x%08x)/(0x%08x)\n", |
1177 | __func__, | 1192 | __func__, |
1178 | cx23885_boards[dev->board].portb, | 1193 | cx23885_boards[dev->board].portb, |
1179 | cx23885_boards[dev->board].portc ); | 1194 | cx23885_boards[dev->board].portc); |
1180 | return -EINVAL; | 1195 | return -EINVAL; |
1181 | } | 1196 | } |
1182 | 1197 | ||
@@ -1186,7 +1201,7 @@ static int cx23885_start_dma(struct cx23885_tsport *port, | |||
1186 | udelay(100); | 1201 | udelay(100); |
1187 | 1202 | ||
1188 | /* If the port supports SRC SELECT, configure it */ | 1203 | /* If the port supports SRC SELECT, configure it */ |
1189 | if(port->reg_src_sel) | 1204 | if (port->reg_src_sel) |
1190 | cx_write(port->reg_src_sel, port->src_sel_val); | 1205 | cx_write(port->reg_src_sel, port->src_sel_val); |
1191 | 1206 | ||
1192 | cx_write(port->reg_hw_sop_ctrl, port->hw_sop_ctrl_val); | 1207 | cx_write(port->reg_hw_sop_ctrl, port->hw_sop_ctrl_val); |
@@ -1195,7 +1210,7 @@ static int cx23885_start_dma(struct cx23885_tsport *port, | |||
1195 | cx_write(port->reg_gen_ctrl, port->gen_ctrl_val); | 1210 | cx_write(port->reg_gen_ctrl, port->gen_ctrl_val); |
1196 | udelay(100); | 1211 | udelay(100); |
1197 | 1212 | ||
1198 | // NOTE: this is 2 (reserved) for portb, does it matter? | 1213 | /* NOTE: this is 2 (reserved) for portb, does it matter? */ |
1199 | /* reset counter to zero */ | 1214 | /* reset counter to zero */ |
1200 | cx_write(port->reg_gpcnt_ctl, 3); | 1215 | cx_write(port->reg_gpcnt_ctl, 3); |
1201 | q->count = 1; | 1216 | q->count = 1; |
@@ -1229,11 +1244,11 @@ static int cx23885_start_dma(struct cx23885_tsport *port, | |||
1229 | cx_write(ALT_PIN_OUT_SEL, 0x10100045); | 1244 | cx_write(ALT_PIN_OUT_SEL, 0x10100045); |
1230 | } | 1245 | } |
1231 | 1246 | ||
1232 | switch(dev->bridge) { | 1247 | switch (dev->bridge) { |
1233 | case CX23885_BRIDGE_885: | 1248 | case CX23885_BRIDGE_885: |
1234 | case CX23885_BRIDGE_887: | 1249 | case CX23885_BRIDGE_887: |
1235 | /* enable irqs */ | 1250 | /* enable irqs */ |
1236 | dprintk(1, "%s() enabling TS int's and DMA\n", __func__ ); | 1251 | dprintk(1, "%s() enabling TS int's and DMA\n", __func__); |
1237 | cx_set(port->reg_ts_int_msk, port->ts_int_msk_val); | 1252 | cx_set(port->reg_ts_int_msk, port->ts_int_msk_val); |
1238 | cx_set(port->reg_dma_ctl, port->dma_ctl_val); | 1253 | cx_set(port->reg_dma_ctl, port->dma_ctl_val); |
1239 | cx_set(PCI_INT_MSK, dev->pci_irqmask | port->pci_irqmask); | 1254 | cx_set(PCI_INT_MSK, dev->pci_irqmask | port->pci_irqmask); |
@@ -1292,8 +1307,7 @@ int cx23885_restart_queue(struct cx23885_tsport *port, | |||
1292 | struct cx23885_buffer *buf; | 1307 | struct cx23885_buffer *buf; |
1293 | 1308 | ||
1294 | dprintk(5, "%s()\n", __func__); | 1309 | dprintk(5, "%s()\n", __func__); |
1295 | if (list_empty(&q->active)) | 1310 | if (list_empty(&q->active)) { |
1296 | { | ||
1297 | struct cx23885_buffer *prev; | 1311 | struct cx23885_buffer *prev; |
1298 | prev = NULL; | 1312 | prev = NULL; |
1299 | 1313 | ||
@@ -1311,7 +1325,7 @@ int cx23885_restart_queue(struct cx23885_tsport *port, | |||
1311 | buf->vb.state = VIDEOBUF_ACTIVE; | 1325 | buf->vb.state = VIDEOBUF_ACTIVE; |
1312 | buf->count = q->count++; | 1326 | buf->count = q->count++; |
1313 | mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); | 1327 | mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); |
1314 | dprintk(5, "[%p/%d] restart_queue - first active\n", | 1328 | dprintk(5, "[%p/%d] restart_queue - f/active\n", |
1315 | buf, buf->vb.i); | 1329 | buf, buf->vb.i); |
1316 | 1330 | ||
1317 | } else if (prev->vb.width == buf->vb.width && | 1331 | } else if (prev->vb.width == buf->vb.width && |
@@ -1322,8 +1336,9 @@ int cx23885_restart_queue(struct cx23885_tsport *port, | |||
1322 | buf->vb.state = VIDEOBUF_ACTIVE; | 1336 | buf->vb.state = VIDEOBUF_ACTIVE; |
1323 | buf->count = q->count++; | 1337 | buf->count = q->count++; |
1324 | prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); | 1338 | prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); |
1325 | prev->risc.jmp[2] = cpu_to_le32(0); /* 64 bit bits 63-32 */ | 1339 | /* 64 bit bits 63-32 */ |
1326 | dprintk(5,"[%p/%d] restart_queue - move to active\n", | 1340 | prev->risc.jmp[2] = cpu_to_le32(0); |
1341 | dprintk(5, "[%p/%d] restart_queue - m/active\n", | ||
1327 | buf, buf->vb.i); | 1342 | buf, buf->vb.i); |
1328 | } else { | 1343 | } else { |
1329 | return 0; | 1344 | return 0; |
@@ -1362,7 +1377,8 @@ int cx23885_buf_prepare(struct videobuf_queue *q, struct cx23885_tsport *port, | |||
1362 | buf->vb.size = size; | 1377 | buf->vb.size = size; |
1363 | buf->vb.field = field /*V4L2_FIELD_TOP*/; | 1378 | buf->vb.field = field /*V4L2_FIELD_TOP*/; |
1364 | 1379 | ||
1365 | if (0 != (rc = videobuf_iolock(q, &buf->vb, NULL))) | 1380 | rc = videobuf_iolock(q, &buf->vb, NULL); |
1381 | if (0 != rc) | ||
1366 | goto fail; | 1382 | goto fail; |
1367 | cx23885_risc_databuffer(dev->pci, &buf->risc, | 1383 | cx23885_risc_databuffer(dev->pci, &buf->risc, |
1368 | videobuf_to_dma(&buf->vb)->sglist, | 1384 | videobuf_to_dma(&buf->vb)->sglist, |
@@ -1388,7 +1404,7 @@ void cx23885_buf_queue(struct cx23885_tsport *port, struct cx23885_buffer *buf) | |||
1388 | buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */ | 1404 | buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */ |
1389 | 1405 | ||
1390 | if (list_empty(&cx88q->active)) { | 1406 | if (list_empty(&cx88q->active)) { |
1391 | dprintk( 1, "queue is empty - first active\n" ); | 1407 | dprintk(1, "queue is empty - first active\n"); |
1392 | list_add_tail(&buf->vb.queue, &cx88q->active); | 1408 | list_add_tail(&buf->vb.queue, &cx88q->active); |
1393 | cx23885_start_dma(port, cx88q, buf); | 1409 | cx23885_start_dma(port, cx88q, buf); |
1394 | buf->vb.state = VIDEOBUF_ACTIVE; | 1410 | buf->vb.state = VIDEOBUF_ACTIVE; |
@@ -1397,7 +1413,7 @@ void cx23885_buf_queue(struct cx23885_tsport *port, struct cx23885_buffer *buf) | |||
1397 | dprintk(1, "[%p/%d] %s - first active\n", | 1413 | dprintk(1, "[%p/%d] %s - first active\n", |
1398 | buf, buf->vb.i, __func__); | 1414 | buf, buf->vb.i, __func__); |
1399 | } else { | 1415 | } else { |
1400 | dprintk( 1, "queue is not empty - append to active\n" ); | 1416 | dprintk(1, "queue is not empty - append to active\n"); |
1401 | prev = list_entry(cx88q->active.prev, struct cx23885_buffer, | 1417 | prev = list_entry(cx88q->active.prev, struct cx23885_buffer, |
1402 | vb.queue); | 1418 | vb.queue); |
1403 | list_add_tail(&buf->vb.queue, &cx88q->active); | 1419 | list_add_tail(&buf->vb.queue, &cx88q->active); |
@@ -1405,7 +1421,7 @@ void cx23885_buf_queue(struct cx23885_tsport *port, struct cx23885_buffer *buf) | |||
1405 | buf->count = cx88q->count++; | 1421 | buf->count = cx88q->count++; |
1406 | prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); | 1422 | prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); |
1407 | prev->risc.jmp[2] = cpu_to_le32(0); /* 64 bit bits 63-32 */ | 1423 | prev->risc.jmp[2] = cpu_to_le32(0); /* 64 bit bits 63-32 */ |
1408 | dprintk( 1, "[%p/%d] %s - append to active\n", | 1424 | dprintk(1, "[%p/%d] %s - append to active\n", |
1409 | buf, buf->vb.i, __func__); | 1425 | buf, buf->vb.i, __func__); |
1410 | } | 1426 | } |
1411 | } | 1427 | } |
@@ -1431,7 +1447,7 @@ static void do_cancel_buffers(struct cx23885_tsport *port, char *reason, | |||
1431 | buf, buf->vb.i, reason, (unsigned long)buf->risc.dma); | 1447 | buf, buf->vb.i, reason, (unsigned long)buf->risc.dma); |
1432 | } | 1448 | } |
1433 | if (restart) { | 1449 | if (restart) { |
1434 | dprintk(1, "restarting queue\n" ); | 1450 | dprintk(1, "restarting queue\n"); |
1435 | cx23885_restart_queue(port, q); | 1451 | cx23885_restart_queue(port, q); |
1436 | } | 1452 | } |
1437 | spin_unlock_irqrestore(&port->slock, flags); | 1453 | spin_unlock_irqrestore(&port->slock, flags); |
@@ -1453,10 +1469,11 @@ static void cx23885_timeout(unsigned long data) | |||
1453 | struct cx23885_tsport *port = (struct cx23885_tsport *)data; | 1469 | struct cx23885_tsport *port = (struct cx23885_tsport *)data; |
1454 | struct cx23885_dev *dev = port->dev; | 1470 | struct cx23885_dev *dev = port->dev; |
1455 | 1471 | ||
1456 | dprintk(1, "%s()\n",__func__); | 1472 | dprintk(1, "%s()\n", __func__); |
1457 | 1473 | ||
1458 | if (debug > 5) | 1474 | if (debug > 5) |
1459 | cx23885_sram_channel_dump(dev, &dev->sram_channels[ port->sram_chno ]); | 1475 | cx23885_sram_channel_dump(dev, |
1476 | &dev->sram_channels[port->sram_chno]); | ||
1460 | 1477 | ||
1461 | cx23885_stop_dma(port); | 1478 | cx23885_stop_dma(port); |
1462 | do_cancel_buffers(port, "timeout", 1); | 1479 | do_cancel_buffers(port, "timeout", 1); |
@@ -1532,16 +1549,23 @@ static int cx23885_irq_ts(struct cx23885_tsport *port, u32 status) | |||
1532 | if ((status & VID_BC_MSK_OPC_ERR) || | 1549 | if ((status & VID_BC_MSK_OPC_ERR) || |
1533 | (status & VID_BC_MSK_BAD_PKT) || | 1550 | (status & VID_BC_MSK_BAD_PKT) || |
1534 | (status & VID_BC_MSK_SYNC) || | 1551 | (status & VID_BC_MSK_SYNC) || |
1535 | (status & VID_BC_MSK_OF)) | 1552 | (status & VID_BC_MSK_OF)) { |
1536 | { | 1553 | |
1537 | if (status & VID_BC_MSK_OPC_ERR) | 1554 | if (status & VID_BC_MSK_OPC_ERR) |
1538 | dprintk(7, " (VID_BC_MSK_OPC_ERR 0x%08x)\n", VID_BC_MSK_OPC_ERR); | 1555 | dprintk(7, " (VID_BC_MSK_OPC_ERR 0x%08x)\n", |
1556 | VID_BC_MSK_OPC_ERR); | ||
1557 | |||
1539 | if (status & VID_BC_MSK_BAD_PKT) | 1558 | if (status & VID_BC_MSK_BAD_PKT) |
1540 | dprintk(7, " (VID_BC_MSK_BAD_PKT 0x%08x)\n", VID_BC_MSK_BAD_PKT); | 1559 | dprintk(7, " (VID_BC_MSK_BAD_PKT 0x%08x)\n", |
1560 | VID_BC_MSK_BAD_PKT); | ||
1561 | |||
1541 | if (status & VID_BC_MSK_SYNC) | 1562 | if (status & VID_BC_MSK_SYNC) |
1542 | dprintk(7, " (VID_BC_MSK_SYNC 0x%08x)\n", VID_BC_MSK_SYNC); | 1563 | dprintk(7, " (VID_BC_MSK_SYNC 0x%08x)\n", |
1564 | VID_BC_MSK_SYNC); | ||
1565 | |||
1543 | if (status & VID_BC_MSK_OF) | 1566 | if (status & VID_BC_MSK_OF) |
1544 | dprintk(7, " (VID_BC_MSK_OF 0x%08x)\n", VID_BC_MSK_OF); | 1567 | dprintk(7, " (VID_BC_MSK_OF 0x%08x)\n", |
1568 | VID_BC_MSK_OF); | ||
1545 | 1569 | ||
1546 | printk(KERN_ERR "%s: mpeg risc op code error\n", dev->name); | 1570 | printk(KERN_ERR "%s: mpeg risc op code error\n", dev->name); |
1547 | 1571 | ||
@@ -1595,7 +1619,7 @@ static irqreturn_t cx23885_irq(int irq, void *dev_id) | |||
1595 | ts2_status = cx_read(VID_C_INT_STAT); | 1619 | ts2_status = cx_read(VID_C_INT_STAT); |
1596 | ts2_mask = cx_read(VID_C_INT_MSK); | 1620 | ts2_mask = cx_read(VID_C_INT_MSK); |
1597 | 1621 | ||
1598 | if ( (pci_status == 0) && (ts2_status == 0) && (ts1_status == 0) ) | 1622 | if ((pci_status == 0) && (ts2_status == 0) && (ts1_status == 0)) |
1599 | goto out; | 1623 | goto out; |
1600 | 1624 | ||
1601 | vida_count = cx_read(VID_A_GPCNT); | 1625 | vida_count = cx_read(VID_A_GPCNT); |
@@ -1610,38 +1634,56 @@ static irqreturn_t cx23885_irq(int irq, void *dev_id) | |||
1610 | dprintk(7, "ts2_status: 0x%08x ts2_mask: 0x%08x count: 0x%x\n", | 1634 | dprintk(7, "ts2_status: 0x%08x ts2_mask: 0x%08x count: 0x%x\n", |
1611 | ts2_status, ts2_mask, ts2_count); | 1635 | ts2_status, ts2_mask, ts2_count); |
1612 | 1636 | ||
1613 | if ( (pci_status & PCI_MSK_RISC_RD) || | 1637 | if ((pci_status & PCI_MSK_RISC_RD) || |
1614 | (pci_status & PCI_MSK_RISC_WR) || | 1638 | (pci_status & PCI_MSK_RISC_WR) || |
1615 | (pci_status & PCI_MSK_AL_RD) || | 1639 | (pci_status & PCI_MSK_AL_RD) || |
1616 | (pci_status & PCI_MSK_AL_WR) || | 1640 | (pci_status & PCI_MSK_AL_WR) || |
1617 | (pci_status & PCI_MSK_APB_DMA) || | 1641 | (pci_status & PCI_MSK_APB_DMA) || |
1618 | (pci_status & PCI_MSK_VID_C) || | 1642 | (pci_status & PCI_MSK_VID_C) || |
1619 | (pci_status & PCI_MSK_VID_B) || | 1643 | (pci_status & PCI_MSK_VID_B) || |
1620 | (pci_status & PCI_MSK_VID_A) || | 1644 | (pci_status & PCI_MSK_VID_A) || |
1621 | (pci_status & PCI_MSK_AUD_INT) || | 1645 | (pci_status & PCI_MSK_AUD_INT) || |
1622 | (pci_status & PCI_MSK_AUD_EXT) ) | 1646 | (pci_status & PCI_MSK_AUD_EXT)) { |
1623 | { | ||
1624 | 1647 | ||
1625 | if (pci_status & PCI_MSK_RISC_RD) | 1648 | if (pci_status & PCI_MSK_RISC_RD) |
1626 | dprintk(7, " (PCI_MSK_RISC_RD 0x%08x)\n", PCI_MSK_RISC_RD); | 1649 | dprintk(7, " (PCI_MSK_RISC_RD 0x%08x)\n", |
1650 | PCI_MSK_RISC_RD); | ||
1651 | |||
1627 | if (pci_status & PCI_MSK_RISC_WR) | 1652 | if (pci_status & PCI_MSK_RISC_WR) |
1628 | dprintk(7, " (PCI_MSK_RISC_WR 0x%08x)\n", PCI_MSK_RISC_WR); | 1653 | dprintk(7, " (PCI_MSK_RISC_WR 0x%08x)\n", |
1654 | PCI_MSK_RISC_WR); | ||
1655 | |||
1629 | if (pci_status & PCI_MSK_AL_RD) | 1656 | if (pci_status & PCI_MSK_AL_RD) |
1630 | dprintk(7, " (PCI_MSK_AL_RD 0x%08x)\n", PCI_MSK_AL_RD); | 1657 | dprintk(7, " (PCI_MSK_AL_RD 0x%08x)\n", |
1658 | PCI_MSK_AL_RD); | ||
1659 | |||
1631 | if (pci_status & PCI_MSK_AL_WR) | 1660 | if (pci_status & PCI_MSK_AL_WR) |
1632 | dprintk(7, " (PCI_MSK_AL_WR 0x%08x)\n", PCI_MSK_AL_WR); | 1661 | dprintk(7, " (PCI_MSK_AL_WR 0x%08x)\n", |
1662 | PCI_MSK_AL_WR); | ||
1663 | |||
1633 | if (pci_status & PCI_MSK_APB_DMA) | 1664 | if (pci_status & PCI_MSK_APB_DMA) |
1634 | dprintk(7, " (PCI_MSK_APB_DMA 0x%08x)\n", PCI_MSK_APB_DMA); | 1665 | dprintk(7, " (PCI_MSK_APB_DMA 0x%08x)\n", |
1666 | PCI_MSK_APB_DMA); | ||
1667 | |||
1635 | if (pci_status & PCI_MSK_VID_C) | 1668 | if (pci_status & PCI_MSK_VID_C) |
1636 | dprintk(7, " (PCI_MSK_VID_C 0x%08x)\n", PCI_MSK_VID_C); | 1669 | dprintk(7, " (PCI_MSK_VID_C 0x%08x)\n", |
1670 | PCI_MSK_VID_C); | ||
1671 | |||
1637 | if (pci_status & PCI_MSK_VID_B) | 1672 | if (pci_status & PCI_MSK_VID_B) |
1638 | dprintk(7, " (PCI_MSK_VID_B 0x%08x)\n", PCI_MSK_VID_B); | 1673 | dprintk(7, " (PCI_MSK_VID_B 0x%08x)\n", |
1674 | PCI_MSK_VID_B); | ||
1675 | |||
1639 | if (pci_status & PCI_MSK_VID_A) | 1676 | if (pci_status & PCI_MSK_VID_A) |
1640 | dprintk(7, " (PCI_MSK_VID_A 0x%08x)\n", PCI_MSK_VID_A); | 1677 | dprintk(7, " (PCI_MSK_VID_A 0x%08x)\n", |
1678 | PCI_MSK_VID_A); | ||
1679 | |||
1641 | if (pci_status & PCI_MSK_AUD_INT) | 1680 | if (pci_status & PCI_MSK_AUD_INT) |
1642 | dprintk(7, " (PCI_MSK_AUD_INT 0x%08x)\n", PCI_MSK_AUD_INT); | 1681 | dprintk(7, " (PCI_MSK_AUD_INT 0x%08x)\n", |
1682 | PCI_MSK_AUD_INT); | ||
1683 | |||
1643 | if (pci_status & PCI_MSK_AUD_EXT) | 1684 | if (pci_status & PCI_MSK_AUD_EXT) |
1644 | dprintk(7, " (PCI_MSK_AUD_EXT 0x%08x)\n", PCI_MSK_AUD_EXT); | 1685 | dprintk(7, " (PCI_MSK_AUD_EXT 0x%08x)\n", |
1686 | PCI_MSK_AUD_EXT); | ||
1645 | 1687 | ||
1646 | } | 1688 | } |
1647 | 1689 | ||
@@ -1753,13 +1795,13 @@ static struct pci_device_id cx23885_pci_tbl[] = { | |||
1753 | .device = 0x8852, | 1795 | .device = 0x8852, |
1754 | .subvendor = PCI_ANY_ID, | 1796 | .subvendor = PCI_ANY_ID, |
1755 | .subdevice = PCI_ANY_ID, | 1797 | .subdevice = PCI_ANY_ID, |
1756 | },{ | 1798 | }, { |
1757 | /* CX23887 Rev 2 */ | 1799 | /* CX23887 Rev 2 */ |
1758 | .vendor = 0x14f1, | 1800 | .vendor = 0x14f1, |
1759 | .device = 0x8880, | 1801 | .device = 0x8880, |
1760 | .subvendor = PCI_ANY_ID, | 1802 | .subvendor = PCI_ANY_ID, |
1761 | .subdevice = PCI_ANY_ID, | 1803 | .subdevice = PCI_ANY_ID, |
1762 | },{ | 1804 | }, { |
1763 | /* --- end of list --- */ | 1805 | /* --- end of list --- */ |
1764 | } | 1806 | } |
1765 | }; | 1807 | }; |
@@ -1797,9 +1839,3 @@ module_init(cx23885_init); | |||
1797 | module_exit(cx23885_fini); | 1839 | module_exit(cx23885_fini); |
1798 | 1840 | ||
1799 | /* ----------------------------------------------------------- */ | 1841 | /* ----------------------------------------------------------- */ |
1800 | /* | ||
1801 | * Local variables: | ||
1802 | * c-basic-offset: 8 | ||
1803 | * End: | ||
1804 | * kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off | ||
1805 | */ | ||
diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c index 24bd18327aa0..e1aac07b3158 100644 --- a/drivers/media/video/cx23885/cx23885-dvb.c +++ b/drivers/media/video/cx23885/cx23885-dvb.c | |||
@@ -78,19 +78,19 @@ static int dvb_buf_prepare(struct videobuf_queue *q, | |||
78 | struct videobuf_buffer *vb, enum v4l2_field field) | 78 | struct videobuf_buffer *vb, enum v4l2_field field) |
79 | { | 79 | { |
80 | struct cx23885_tsport *port = q->priv_data; | 80 | struct cx23885_tsport *port = q->priv_data; |
81 | return cx23885_buf_prepare(q, port, (struct cx23885_buffer*)vb, field); | 81 | return cx23885_buf_prepare(q, port, (struct cx23885_buffer *)vb, field); |
82 | } | 82 | } |
83 | 83 | ||
84 | static void dvb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb) | 84 | static void dvb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb) |
85 | { | 85 | { |
86 | struct cx23885_tsport *port = q->priv_data; | 86 | struct cx23885_tsport *port = q->priv_data; |
87 | cx23885_buf_queue(port, (struct cx23885_buffer*)vb); | 87 | cx23885_buf_queue(port, (struct cx23885_buffer *)vb); |
88 | } | 88 | } |
89 | 89 | ||
90 | static void dvb_buf_release(struct videobuf_queue *q, | 90 | static void dvb_buf_release(struct videobuf_queue *q, |
91 | struct videobuf_buffer *vb) | 91 | struct videobuf_buffer *vb) |
92 | { | 92 | { |
93 | cx23885_free_buffer(q, (struct cx23885_buffer*)vb); | 93 | cx23885_free_buffer(q, (struct cx23885_buffer *)vb); |
94 | } | 94 | } |
95 | 95 | ||
96 | static struct videobuf_queue_ops dvb_qops = { | 96 | static struct videobuf_queue_ops dvb_qops = { |
@@ -312,19 +312,25 @@ static int dvb_register(struct cx23885_tsport *port) | |||
312 | { | 312 | { |
313 | struct cx23885_dev *dev = port->dev; | 313 | struct cx23885_dev *dev = port->dev; |
314 | struct cx23885_i2c *i2c_bus = NULL; | 314 | struct cx23885_i2c *i2c_bus = NULL; |
315 | struct videobuf_dvb_frontend *fe0; | ||
316 | |||
317 | /* Get the first frontend */ | ||
318 | fe0 = videobuf_dvb_get_frontend(&port->frontends, 1); | ||
319 | if (!fe0) | ||
320 | return -EINVAL; | ||
315 | 321 | ||
316 | /* init struct videobuf_dvb */ | 322 | /* init struct videobuf_dvb */ |
317 | port->dvb.name = dev->name; | 323 | fe0->dvb.name = dev->name; |
318 | 324 | ||
319 | /* init frontend */ | 325 | /* init frontend */ |
320 | switch (dev->board) { | 326 | switch (dev->board) { |
321 | case CX23885_BOARD_HAUPPAUGE_HVR1250: | 327 | case CX23885_BOARD_HAUPPAUGE_HVR1250: |
322 | i2c_bus = &dev->i2c_bus[0]; | 328 | i2c_bus = &dev->i2c_bus[0]; |
323 | port->dvb.frontend = dvb_attach(s5h1409_attach, | 329 | fe0->dvb.frontend = dvb_attach(s5h1409_attach, |
324 | &hauppauge_generic_config, | 330 | &hauppauge_generic_config, |
325 | &i2c_bus->i2c_adap); | 331 | &i2c_bus->i2c_adap); |
326 | if (port->dvb.frontend != NULL) { | 332 | if (fe0->dvb.frontend != NULL) { |
327 | dvb_attach(mt2131_attach, port->dvb.frontend, | 333 | dvb_attach(mt2131_attach, fe0->dvb.frontend, |
328 | &i2c_bus->i2c_adap, | 334 | &i2c_bus->i2c_adap, |
329 | &hauppauge_generic_tunerconfig, 0); | 335 | &hauppauge_generic_tunerconfig, 0); |
330 | } | 336 | } |
@@ -333,27 +339,27 @@ static int dvb_register(struct cx23885_tsport *port) | |||
333 | i2c_bus = &dev->i2c_bus[0]; | 339 | i2c_bus = &dev->i2c_bus[0]; |
334 | switch (alt_tuner) { | 340 | switch (alt_tuner) { |
335 | case 1: | 341 | case 1: |
336 | port->dvb.frontend = | 342 | fe0->dvb.frontend = |
337 | dvb_attach(s5h1409_attach, | 343 | dvb_attach(s5h1409_attach, |
338 | &hauppauge_ezqam_config, | 344 | &hauppauge_ezqam_config, |
339 | &i2c_bus->i2c_adap); | 345 | &i2c_bus->i2c_adap); |
340 | if (port->dvb.frontend != NULL) { | 346 | if (fe0->dvb.frontend != NULL) { |
341 | dvb_attach(tda829x_attach, port->dvb.frontend, | 347 | dvb_attach(tda829x_attach, fe0->dvb.frontend, |
342 | &dev->i2c_bus[1].i2c_adap, 0x42, | 348 | &dev->i2c_bus[1].i2c_adap, 0x42, |
343 | &tda829x_no_probe); | 349 | &tda829x_no_probe); |
344 | dvb_attach(tda18271_attach, port->dvb.frontend, | 350 | dvb_attach(tda18271_attach, fe0->dvb.frontend, |
345 | 0x60, &dev->i2c_bus[1].i2c_adap, | 351 | 0x60, &dev->i2c_bus[1].i2c_adap, |
346 | &hauppauge_tda18271_config); | 352 | &hauppauge_tda18271_config); |
347 | } | 353 | } |
348 | break; | 354 | break; |
349 | case 0: | 355 | case 0: |
350 | default: | 356 | default: |
351 | port->dvb.frontend = | 357 | fe0->dvb.frontend = |
352 | dvb_attach(s5h1409_attach, | 358 | dvb_attach(s5h1409_attach, |
353 | &hauppauge_generic_config, | 359 | &hauppauge_generic_config, |
354 | &i2c_bus->i2c_adap); | 360 | &i2c_bus->i2c_adap); |
355 | if (port->dvb.frontend != NULL) | 361 | if (fe0->dvb.frontend != NULL) |
356 | dvb_attach(mt2131_attach, port->dvb.frontend, | 362 | dvb_attach(mt2131_attach, fe0->dvb.frontend, |
357 | &i2c_bus->i2c_adap, | 363 | &i2c_bus->i2c_adap, |
358 | &hauppauge_generic_tunerconfig, 0); | 364 | &hauppauge_generic_tunerconfig, 0); |
359 | break; | 365 | break; |
@@ -361,42 +367,42 @@ static int dvb_register(struct cx23885_tsport *port) | |||
361 | break; | 367 | break; |
362 | case CX23885_BOARD_HAUPPAUGE_HVR1800lp: | 368 | case CX23885_BOARD_HAUPPAUGE_HVR1800lp: |
363 | i2c_bus = &dev->i2c_bus[0]; | 369 | i2c_bus = &dev->i2c_bus[0]; |
364 | port->dvb.frontend = dvb_attach(s5h1409_attach, | 370 | fe0->dvb.frontend = dvb_attach(s5h1409_attach, |
365 | &hauppauge_hvr1800lp_config, | 371 | &hauppauge_hvr1800lp_config, |
366 | &i2c_bus->i2c_adap); | 372 | &i2c_bus->i2c_adap); |
367 | if (port->dvb.frontend != NULL) { | 373 | if (fe0->dvb.frontend != NULL) { |
368 | dvb_attach(mt2131_attach, port->dvb.frontend, | 374 | dvb_attach(mt2131_attach, fe0->dvb.frontend, |
369 | &i2c_bus->i2c_adap, | 375 | &i2c_bus->i2c_adap, |
370 | &hauppauge_generic_tunerconfig, 0); | 376 | &hauppauge_generic_tunerconfig, 0); |
371 | } | 377 | } |
372 | break; | 378 | break; |
373 | case CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP: | 379 | case CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP: |
374 | i2c_bus = &dev->i2c_bus[0]; | 380 | i2c_bus = &dev->i2c_bus[0]; |
375 | port->dvb.frontend = dvb_attach(lgdt330x_attach, | 381 | fe0->dvb.frontend = dvb_attach(lgdt330x_attach, |
376 | &fusionhdtv_5_express, | 382 | &fusionhdtv_5_express, |
377 | &i2c_bus->i2c_adap); | 383 | &i2c_bus->i2c_adap); |
378 | if (port->dvb.frontend != NULL) { | 384 | if (fe0->dvb.frontend != NULL) { |
379 | dvb_attach(simple_tuner_attach, port->dvb.frontend, | 385 | dvb_attach(simple_tuner_attach, fe0->dvb.frontend, |
380 | &i2c_bus->i2c_adap, 0x61, | 386 | &i2c_bus->i2c_adap, 0x61, |
381 | TUNER_LG_TDVS_H06XF); | 387 | TUNER_LG_TDVS_H06XF); |
382 | } | 388 | } |
383 | break; | 389 | break; |
384 | case CX23885_BOARD_HAUPPAUGE_HVR1500Q: | 390 | case CX23885_BOARD_HAUPPAUGE_HVR1500Q: |
385 | i2c_bus = &dev->i2c_bus[1]; | 391 | i2c_bus = &dev->i2c_bus[1]; |
386 | port->dvb.frontend = dvb_attach(s5h1409_attach, | 392 | fe0->dvb.frontend = dvb_attach(s5h1409_attach, |
387 | &hauppauge_hvr1500q_config, | 393 | &hauppauge_hvr1500q_config, |
388 | &dev->i2c_bus[0].i2c_adap); | 394 | &dev->i2c_bus[0].i2c_adap); |
389 | if (port->dvb.frontend != NULL) | 395 | if (fe0->dvb.frontend != NULL) |
390 | dvb_attach(xc5000_attach, port->dvb.frontend, | 396 | dvb_attach(xc5000_attach, fe0->dvb.frontend, |
391 | &i2c_bus->i2c_adap, | 397 | &i2c_bus->i2c_adap, |
392 | &hauppauge_hvr1500q_tunerconfig); | 398 | &hauppauge_hvr1500q_tunerconfig); |
393 | break; | 399 | break; |
394 | case CX23885_BOARD_HAUPPAUGE_HVR1500: | 400 | case CX23885_BOARD_HAUPPAUGE_HVR1500: |
395 | i2c_bus = &dev->i2c_bus[1]; | 401 | i2c_bus = &dev->i2c_bus[1]; |
396 | port->dvb.frontend = dvb_attach(s5h1409_attach, | 402 | fe0->dvb.frontend = dvb_attach(s5h1409_attach, |
397 | &hauppauge_hvr1500_config, | 403 | &hauppauge_hvr1500_config, |
398 | &dev->i2c_bus[0].i2c_adap); | 404 | &dev->i2c_bus[0].i2c_adap); |
399 | if (port->dvb.frontend != NULL) { | 405 | if (fe0->dvb.frontend != NULL) { |
400 | struct dvb_frontend *fe; | 406 | struct dvb_frontend *fe; |
401 | struct xc2028_config cfg = { | 407 | struct xc2028_config cfg = { |
402 | .i2c_adap = &i2c_bus->i2c_adap, | 408 | .i2c_adap = &i2c_bus->i2c_adap, |
@@ -409,7 +415,7 @@ static int dvb_register(struct cx23885_tsport *port) | |||
409 | }; | 415 | }; |
410 | 416 | ||
411 | fe = dvb_attach(xc2028_attach, | 417 | fe = dvb_attach(xc2028_attach, |
412 | port->dvb.frontend, &cfg); | 418 | fe0->dvb.frontend, &cfg); |
413 | if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) | 419 | if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) |
414 | fe->ops.tuner_ops.set_config(fe, &ctl); | 420 | fe->ops.tuner_ops.set_config(fe, &ctl); |
415 | } | 421 | } |
@@ -417,24 +423,24 @@ static int dvb_register(struct cx23885_tsport *port) | |||
417 | case CX23885_BOARD_HAUPPAUGE_HVR1200: | 423 | case CX23885_BOARD_HAUPPAUGE_HVR1200: |
418 | case CX23885_BOARD_HAUPPAUGE_HVR1700: | 424 | case CX23885_BOARD_HAUPPAUGE_HVR1700: |
419 | i2c_bus = &dev->i2c_bus[0]; | 425 | i2c_bus = &dev->i2c_bus[0]; |
420 | port->dvb.frontend = dvb_attach(tda10048_attach, | 426 | fe0->dvb.frontend = dvb_attach(tda10048_attach, |
421 | &hauppauge_hvr1200_config, | 427 | &hauppauge_hvr1200_config, |
422 | &i2c_bus->i2c_adap); | 428 | &i2c_bus->i2c_adap); |
423 | if (port->dvb.frontend != NULL) { | 429 | if (fe0->dvb.frontend != NULL) { |
424 | dvb_attach(tda829x_attach, port->dvb.frontend, | 430 | dvb_attach(tda829x_attach, fe0->dvb.frontend, |
425 | &dev->i2c_bus[1].i2c_adap, 0x42, | 431 | &dev->i2c_bus[1].i2c_adap, 0x42, |
426 | &tda829x_no_probe); | 432 | &tda829x_no_probe); |
427 | dvb_attach(tda18271_attach, port->dvb.frontend, | 433 | dvb_attach(tda18271_attach, fe0->dvb.frontend, |
428 | 0x60, &dev->i2c_bus[1].i2c_adap, | 434 | 0x60, &dev->i2c_bus[1].i2c_adap, |
429 | &hauppauge_hvr1200_tuner_config); | 435 | &hauppauge_hvr1200_tuner_config); |
430 | } | 436 | } |
431 | break; | 437 | break; |
432 | case CX23885_BOARD_HAUPPAUGE_HVR1400: | 438 | case CX23885_BOARD_HAUPPAUGE_HVR1400: |
433 | i2c_bus = &dev->i2c_bus[0]; | 439 | i2c_bus = &dev->i2c_bus[0]; |
434 | port->dvb.frontend = dvb_attach(dib7000p_attach, | 440 | fe0->dvb.frontend = dvb_attach(dib7000p_attach, |
435 | &i2c_bus->i2c_adap, | 441 | &i2c_bus->i2c_adap, |
436 | 0x12, &hauppauge_hvr1400_dib7000_config); | 442 | 0x12, &hauppauge_hvr1400_dib7000_config); |
437 | if (port->dvb.frontend != NULL) { | 443 | if (fe0->dvb.frontend != NULL) { |
438 | struct dvb_frontend *fe; | 444 | struct dvb_frontend *fe; |
439 | struct xc2028_config cfg = { | 445 | struct xc2028_config cfg = { |
440 | .i2c_adap = &dev->i2c_bus[1].i2c_adap, | 446 | .i2c_adap = &dev->i2c_bus[1].i2c_adap, |
@@ -444,12 +450,13 @@ static int dvb_register(struct cx23885_tsport *port) | |||
444 | .fname = XC3028L_DEFAULT_FIRMWARE, | 450 | .fname = XC3028L_DEFAULT_FIRMWARE, |
445 | .max_len = 64, | 451 | .max_len = 64, |
446 | .demod = 5000, | 452 | .demod = 5000, |
447 | /* This is true for all demods with v36 firmware? */ | 453 | /* This is true for all demods with |
454 | v36 firmware? */ | ||
448 | .type = XC2028_D2633, | 455 | .type = XC2028_D2633, |
449 | }; | 456 | }; |
450 | 457 | ||
451 | fe = dvb_attach(xc2028_attach, | 458 | fe = dvb_attach(xc2028_attach, |
452 | port->dvb.frontend, &cfg); | 459 | fe0->dvb.frontend, &cfg); |
453 | if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) | 460 | if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) |
454 | fe->ops.tuner_ops.set_config(fe, &ctl); | 461 | fe->ops.tuner_ops.set_config(fe, &ctl); |
455 | } | 462 | } |
@@ -457,25 +464,25 @@ static int dvb_register(struct cx23885_tsport *port) | |||
457 | case CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP: | 464 | case CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP: |
458 | i2c_bus = &dev->i2c_bus[port->nr - 1]; | 465 | i2c_bus = &dev->i2c_bus[port->nr - 1]; |
459 | 466 | ||
460 | port->dvb.frontend = dvb_attach(s5h1409_attach, | 467 | fe0->dvb.frontend = dvb_attach(s5h1409_attach, |
461 | &dvico_s5h1409_config, | 468 | &dvico_s5h1409_config, |
462 | &i2c_bus->i2c_adap); | 469 | &i2c_bus->i2c_adap); |
463 | if (port->dvb.frontend == NULL) | 470 | if (fe0->dvb.frontend == NULL) |
464 | port->dvb.frontend = dvb_attach(s5h1411_attach, | 471 | fe0->dvb.frontend = dvb_attach(s5h1411_attach, |
465 | &dvico_s5h1411_config, | 472 | &dvico_s5h1411_config, |
466 | &i2c_bus->i2c_adap); | 473 | &i2c_bus->i2c_adap); |
467 | if (port->dvb.frontend != NULL) | 474 | if (fe0->dvb.frontend != NULL) |
468 | dvb_attach(xc5000_attach, port->dvb.frontend, | 475 | dvb_attach(xc5000_attach, fe0->dvb.frontend, |
469 | &i2c_bus->i2c_adap, | 476 | &i2c_bus->i2c_adap, |
470 | &dvico_xc5000_tunerconfig); | 477 | &dvico_xc5000_tunerconfig); |
471 | break; | 478 | break; |
472 | case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP: { | 479 | case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP: { |
473 | i2c_bus = &dev->i2c_bus[port->nr - 1]; | 480 | i2c_bus = &dev->i2c_bus[port->nr - 1]; |
474 | 481 | ||
475 | port->dvb.frontend = dvb_attach(zl10353_attach, | 482 | fe0->dvb.frontend = dvb_attach(zl10353_attach, |
476 | &dvico_fusionhdtv_xc3028, | 483 | &dvico_fusionhdtv_xc3028, |
477 | &i2c_bus->i2c_adap); | 484 | &i2c_bus->i2c_adap); |
478 | if (port->dvb.frontend != NULL) { | 485 | if (fe0->dvb.frontend != NULL) { |
479 | struct dvb_frontend *fe; | 486 | struct dvb_frontend *fe; |
480 | struct xc2028_config cfg = { | 487 | struct xc2028_config cfg = { |
481 | .i2c_adap = &i2c_bus->i2c_adap, | 488 | .i2c_adap = &i2c_bus->i2c_adap, |
@@ -487,7 +494,7 @@ static int dvb_register(struct cx23885_tsport *port) | |||
487 | .demod = XC3028_FE_ZARLINK456, | 494 | .demod = XC3028_FE_ZARLINK456, |
488 | }; | 495 | }; |
489 | 496 | ||
490 | fe = dvb_attach(xc2028_attach, port->dvb.frontend, | 497 | fe = dvb_attach(xc2028_attach, fe0->dvb.frontend, |
491 | &cfg); | 498 | &cfg); |
492 | if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) | 499 | if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) |
493 | fe->ops.tuner_ops.set_config(fe, &ctl); | 500 | fe->ops.tuner_ops.set_config(fe, &ctl); |
@@ -497,10 +504,10 @@ static int dvb_register(struct cx23885_tsport *port) | |||
497 | case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: | 504 | case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: |
498 | i2c_bus = &dev->i2c_bus[0]; | 505 | i2c_bus = &dev->i2c_bus[0]; |
499 | 506 | ||
500 | port->dvb.frontend = dvb_attach(zl10353_attach, | 507 | fe0->dvb.frontend = dvb_attach(zl10353_attach, |
501 | &dvico_fusionhdtv_xc3028, | 508 | &dvico_fusionhdtv_xc3028, |
502 | &i2c_bus->i2c_adap); | 509 | &i2c_bus->i2c_adap); |
503 | if (port->dvb.frontend != NULL) { | 510 | if (fe0->dvb.frontend != NULL) { |
504 | struct dvb_frontend *fe; | 511 | struct dvb_frontend *fe; |
505 | struct xc2028_config cfg = { | 512 | struct xc2028_config cfg = { |
506 | .i2c_adap = &dev->i2c_bus[1].i2c_adap, | 513 | .i2c_adap = &dev->i2c_bus[1].i2c_adap, |
@@ -512,73 +519,108 @@ static int dvb_register(struct cx23885_tsport *port) | |||
512 | .demod = XC3028_FE_ZARLINK456, | 519 | .demod = XC3028_FE_ZARLINK456, |
513 | }; | 520 | }; |
514 | 521 | ||
515 | fe = dvb_attach(xc2028_attach, port->dvb.frontend, | 522 | fe = dvb_attach(xc2028_attach, fe0->dvb.frontend, |
516 | &cfg); | 523 | &cfg); |
517 | if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) | 524 | if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) |
518 | fe->ops.tuner_ops.set_config(fe, &ctl); | 525 | fe->ops.tuner_ops.set_config(fe, &ctl); |
519 | } | 526 | } |
520 | break; | 527 | break; |
521 | default: | 528 | default: |
522 | printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n", | 529 | printk(KERN_INFO "%s: The frontend of your DVB/ATSC card " |
530 | " isn't supported yet\n", | ||
523 | dev->name); | 531 | dev->name); |
524 | break; | 532 | break; |
525 | } | 533 | } |
526 | if (NULL == port->dvb.frontend) { | 534 | if (NULL == fe0->dvb.frontend) { |
527 | printk("%s: frontend initialization failed\n", dev->name); | 535 | printk(KERN_ERR "%s: frontend initialization failed\n", |
536 | dev->name); | ||
528 | return -1; | 537 | return -1; |
529 | } | 538 | } |
530 | /* define general-purpose callback pointer */ | 539 | /* define general-purpose callback pointer */ |
531 | port->dvb.frontend->callback = cx23885_tuner_callback; | 540 | fe0->dvb.frontend->callback = cx23885_tuner_callback; |
532 | 541 | ||
533 | /* Put the analog decoder in standby to keep it quiet */ | 542 | /* Put the analog decoder in standby to keep it quiet */ |
534 | cx23885_call_i2c_clients(i2c_bus, TUNER_SET_STANDBY, NULL); | 543 | cx23885_call_i2c_clients(i2c_bus, TUNER_SET_STANDBY, NULL); |
535 | 544 | ||
536 | if (port->dvb.frontend->ops.analog_ops.standby) | 545 | if (fe0->dvb.frontend->ops.analog_ops.standby) |
537 | port->dvb.frontend->ops.analog_ops.standby(port->dvb.frontend); | 546 | fe0->dvb.frontend->ops.analog_ops.standby(fe0->dvb.frontend); |
538 | 547 | ||
539 | /* register everything */ | 548 | /* register everything */ |
540 | return videobuf_dvb_register(&port->dvb, THIS_MODULE, port, | 549 | return videobuf_dvb_register_bus(&port->frontends, THIS_MODULE, port, |
541 | &dev->pci->dev, adapter_nr); | 550 | &dev->pci->dev, adapter_nr, 0); |
551 | |||
542 | } | 552 | } |
543 | 553 | ||
544 | int cx23885_dvb_register(struct cx23885_tsport *port) | 554 | int cx23885_dvb_register(struct cx23885_tsport *port) |
545 | { | 555 | { |
556 | |||
557 | struct videobuf_dvb_frontend *fe0; | ||
546 | struct cx23885_dev *dev = port->dev; | 558 | struct cx23885_dev *dev = port->dev; |
547 | int err; | 559 | int err, i; |
560 | |||
561 | /* Here we need to allocate the correct number of frontends, | ||
562 | * as reflected in the cards struct. The reality is that currrently | ||
563 | * no cx23885 boards support this - yet. But, if we don't modify this | ||
564 | * code then the second frontend would never be allocated (later) | ||
565 | * and fail with error before the attach in dvb_register(). | ||
566 | * Without these changes we risk an OOPS later. The changes here | ||
567 | * are for safety, and should provide a good foundation for the | ||
568 | * future addition of any multi-frontend cx23885 based boards. | ||
569 | */ | ||
570 | printk(KERN_INFO "%s() allocating %d frontend(s)\n", __func__, | ||
571 | port->num_frontends); | ||
572 | |||
573 | for (i = 1; i <= port->num_frontends; i++) { | ||
574 | if (videobuf_dvb_alloc_frontend( | ||
575 | &port->frontends, i) == NULL) { | ||
576 | printk(KERN_ERR "%s() failed to alloc\n", __func__); | ||
577 | return -ENOMEM; | ||
578 | } | ||
548 | 579 | ||
549 | dprintk(1, "%s\n", __func__); | 580 | fe0 = videobuf_dvb_get_frontend(&port->frontends, i); |
550 | dprintk(1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n", | 581 | if (!fe0) |
551 | dev->board, | 582 | err = -EINVAL; |
552 | dev->name, | ||
553 | dev->pci_bus, | ||
554 | dev->pci_slot); | ||
555 | 583 | ||
556 | err = -ENODEV; | 584 | dprintk(1, "%s\n", __func__); |
585 | dprintk(1, " ->probed by Card=%d Name=%s, PCI %02x:%02x\n", | ||
586 | dev->board, | ||
587 | dev->name, | ||
588 | dev->pci_bus, | ||
589 | dev->pci_slot); | ||
557 | 590 | ||
558 | /* dvb stuff */ | 591 | err = -ENODEV; |
559 | printk("%s: cx23885 based dvb card\n", dev->name); | 592 | |
560 | videobuf_queue_sg_init(&port->dvb.dvbq, &dvb_qops, &dev->pci->dev, &port->slock, | 593 | /* dvb stuff */ |
594 | /* We have to init the queue for each frontend on a port. */ | ||
595 | printk(KERN_INFO "%s: cx23885 based dvb card\n", dev->name); | ||
596 | videobuf_queue_sg_init(&fe0->dvb.dvbq, &dvb_qops, | ||
597 | &dev->pci->dev, &port->slock, | ||
561 | V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_TOP, | 598 | V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_TOP, |
562 | sizeof(struct cx23885_buffer), port); | 599 | sizeof(struct cx23885_buffer), port); |
600 | } | ||
563 | err = dvb_register(port); | 601 | err = dvb_register(port); |
564 | if (err != 0) | 602 | if (err != 0) |
565 | printk("%s() dvb_register failed err = %d\n", __func__, err); | 603 | printk(KERN_ERR "%s() dvb_register failed err = %d\n", |
604 | __func__, err); | ||
566 | 605 | ||
567 | return err; | 606 | return err; |
568 | } | 607 | } |
569 | 608 | ||
570 | int cx23885_dvb_unregister(struct cx23885_tsport *port) | 609 | int cx23885_dvb_unregister(struct cx23885_tsport *port) |
571 | { | 610 | { |
572 | /* dvb */ | 611 | struct videobuf_dvb_frontend *fe0; |
573 | if(port->dvb.frontend) | 612 | |
574 | videobuf_dvb_unregister(&port->dvb); | 613 | /* FIXME: in an error condition where the we have |
614 | * an expected number of frontends (attach problem) | ||
615 | * then this might not clean up correctly, if 1 | ||
616 | * is invalid. | ||
617 | * This comment only applies to future boards IF they | ||
618 | * implement MFE support. | ||
619 | */ | ||
620 | fe0 = videobuf_dvb_get_frontend(&port->frontends, 1); | ||
621 | if (fe0->dvb.frontend) | ||
622 | videobuf_dvb_unregister_bus(&port->frontends); | ||
575 | 623 | ||
576 | return 0; | 624 | return 0; |
577 | } | 625 | } |
578 | 626 | ||
579 | /* | ||
580 | * Local variables: | ||
581 | * c-basic-offset: 8 | ||
582 | * End: | ||
583 | * kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off | ||
584 | */ | ||
diff --git a/drivers/media/video/cx23885/cx23885-i2c.c b/drivers/media/video/cx23885/cx23885-i2c.c index f98e476e9617..bb7f71a1fcbe 100644 --- a/drivers/media/video/cx23885/cx23885-i2c.c +++ b/drivers/media/video/cx23885/cx23885-i2c.c | |||
@@ -131,7 +131,7 @@ static int i2c_sendbytes(struct i2c_adapter *i2c_adap, | |||
131 | printk(" >\n"); | 131 | printk(" >\n"); |
132 | } | 132 | } |
133 | 133 | ||
134 | for (cnt = 1; cnt < msg->len; cnt++ ) { | 134 | for (cnt = 1; cnt < msg->len; cnt++) { |
135 | /* following bytes */ | 135 | /* following bytes */ |
136 | wdata = msg->buf[cnt]; | 136 | wdata = msg->buf[cnt]; |
137 | ctrl = bus->i2c_period | (1 << 12) | (1 << 2); | 137 | ctrl = bus->i2c_period | (1 << 12) | (1 << 2); |
@@ -151,9 +151,9 @@ static int i2c_sendbytes(struct i2c_adapter *i2c_adap, | |||
151 | if (retval == 0) | 151 | if (retval == 0) |
152 | goto eio; | 152 | goto eio; |
153 | if (i2c_debug) { | 153 | if (i2c_debug) { |
154 | printk(" %02x", msg->buf[cnt]); | 154 | dprintk(1, " %02x", msg->buf[cnt]); |
155 | if (!(ctrl & I2C_NOSTOP)) | 155 | if (!(ctrl & I2C_NOSTOP)) |
156 | printk(" >\n"); | 156 | dprintk(1, " >\n"); |
157 | } | 157 | } |
158 | } | 158 | } |
159 | return msg->len; | 159 | return msg->len; |
@@ -162,7 +162,7 @@ static int i2c_sendbytes(struct i2c_adapter *i2c_adap, | |||
162 | retval = -EIO; | 162 | retval = -EIO; |
163 | err: | 163 | err: |
164 | if (i2c_debug) | 164 | if (i2c_debug) |
165 | printk(" ERR: %d\n", retval); | 165 | printk(KERN_ERR " ERR: %d\n", retval); |
166 | return retval; | 166 | return retval; |
167 | } | 167 | } |
168 | 168 | ||
@@ -194,12 +194,12 @@ static int i2c_readbytes(struct i2c_adapter *i2c_adap, | |||
194 | 194 | ||
195 | if (i2c_debug) { | 195 | if (i2c_debug) { |
196 | if (joined) | 196 | if (joined) |
197 | printk(" R"); | 197 | dprintk(1, " R"); |
198 | else | 198 | else |
199 | printk(" <R %02x", (msg->addr << 1) + 1); | 199 | dprintk(1, " <R %02x", (msg->addr << 1) + 1); |
200 | } | 200 | } |
201 | 201 | ||
202 | for(cnt = 0; cnt < msg->len; cnt++) { | 202 | for (cnt = 0; cnt < msg->len; cnt++) { |
203 | 203 | ||
204 | ctrl = bus->i2c_period | (1 << 12) | (1 << 2) | 1; | 204 | ctrl = bus->i2c_period | (1 << 12) | (1 << 2) | 1; |
205 | 205 | ||
@@ -216,9 +216,9 @@ static int i2c_readbytes(struct i2c_adapter *i2c_adap, | |||
216 | goto eio; | 216 | goto eio; |
217 | msg->buf[cnt] = cx_read(bus->reg_rdata) & 0xff; | 217 | msg->buf[cnt] = cx_read(bus->reg_rdata) & 0xff; |
218 | if (i2c_debug) { | 218 | if (i2c_debug) { |
219 | printk(" %02x", msg->buf[cnt]); | 219 | dprintk(1, " %02x", msg->buf[cnt]); |
220 | if (!(ctrl & I2C_NOSTOP)) | 220 | if (!(ctrl & I2C_NOSTOP)) |
221 | printk(" >\n"); | 221 | dprintk(1, " >\n"); |
222 | } | 222 | } |
223 | } | 223 | } |
224 | return msg->len; | 224 | return msg->len; |
@@ -227,7 +227,7 @@ static int i2c_readbytes(struct i2c_adapter *i2c_adap, | |||
227 | retval = -EIO; | 227 | retval = -EIO; |
228 | err: | 228 | err: |
229 | if (i2c_debug) | 229 | if (i2c_debug) |
230 | printk(" ERR: %d\n", retval); | 230 | printk(KERN_ERR " ERR: %d\n", retval); |
231 | return retval; | 231 | return retval; |
232 | } | 232 | } |
233 | 233 | ||
@@ -353,17 +353,17 @@ static struct i2c_client cx23885_i2c_client_template = { | |||
353 | }; | 353 | }; |
354 | 354 | ||
355 | static char *i2c_devs[128] = { | 355 | static char *i2c_devs[128] = { |
356 | [0x10 >> 1] = "tda10048", | 356 | [0x10 >> 1] = "tda10048", |
357 | [0x12 >> 1] = "dib7000pc", | 357 | [0x12 >> 1] = "dib7000pc", |
358 | [ 0x1c >> 1 ] = "lgdt3303", | 358 | [0x1c >> 1] = "lgdt3303", |
359 | [ 0x86 >> 1 ] = "tda9887", | 359 | [0x86 >> 1] = "tda9887", |
360 | [ 0x32 >> 1 ] = "cx24227", | 360 | [0x32 >> 1] = "cx24227", |
361 | [ 0x88 >> 1 ] = "cx25837", | 361 | [0x88 >> 1] = "cx25837", |
362 | [ 0x84 >> 1 ] = "tda8295", | 362 | [0x84 >> 1] = "tda8295", |
363 | [ 0xa0 >> 1 ] = "eeprom", | 363 | [0xa0 >> 1] = "eeprom", |
364 | [ 0xc0 >> 1 ] = "tuner/mt2131/tda8275", | 364 | [0xc0 >> 1] = "tuner/mt2131/tda8275", |
365 | [0xc2 >> 1] = "tuner/mt2131/tda8275/xc5000/xc3028", | 365 | [0xc2 >> 1] = "tuner/mt2131/tda8275/xc5000/xc3028", |
366 | [0xc8 >> 1] = "tuner/xc3028L", | 366 | [0xc8 >> 1] = "tuner/xc3028L", |
367 | }; | 367 | }; |
368 | 368 | ||
369 | static void do_i2c_scan(char *name, struct i2c_client *c) | 369 | static void do_i2c_scan(char *name, struct i2c_client *c) |
@@ -376,7 +376,7 @@ static void do_i2c_scan(char *name, struct i2c_client *c) | |||
376 | rc = i2c_master_recv(c, &buf, 0); | 376 | rc = i2c_master_recv(c, &buf, 0); |
377 | if (rc < 0) | 377 | if (rc < 0) |
378 | continue; | 378 | continue; |
379 | printk("%s: i2c scan: found device @ 0x%x [%s]\n", | 379 | printk(KERN_INFO "%s: i2c scan: found device @ 0x%x [%s]\n", |
380 | name, i << 1, i2c_devs[i] ? i2c_devs[i] : "???"); | 380 | name, i << 1, i2c_devs[i] ? i2c_devs[i] : "???"); |
381 | } | 381 | } |
382 | } | 382 | } |
@@ -408,11 +408,12 @@ int cx23885_i2c_register(struct cx23885_i2c *bus) | |||
408 | bus->i2c_client.adapter = &bus->i2c_adap; | 408 | bus->i2c_client.adapter = &bus->i2c_adap; |
409 | 409 | ||
410 | if (0 == bus->i2c_rc) { | 410 | if (0 == bus->i2c_rc) { |
411 | printk("%s: i2c bus %d registered\n", dev->name, bus->nr); | 411 | dprintk(1, "%s: i2c bus %d registered\n", dev->name, bus->nr); |
412 | if (i2c_scan) | 412 | if (i2c_scan) |
413 | do_i2c_scan(dev->name, &bus->i2c_client); | 413 | do_i2c_scan(dev->name, &bus->i2c_client); |
414 | } else | 414 | } else |
415 | printk("%s: i2c bus %d register FAILED\n", dev->name, bus->nr); | 415 | printk(KERN_WARNING "%s: i2c bus %d register FAILED\n", |
416 | dev->name, bus->nr); | ||
416 | 417 | ||
417 | return bus->i2c_rc; | 418 | return bus->i2c_rc; |
418 | } | 419 | } |
diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c index f75ed1c9b71a..ab3110d6046c 100644 --- a/drivers/media/video/cx23885/cx23885-video.c +++ b/drivers/media/video/cx23885/cx23885-video.c | |||
@@ -285,11 +285,10 @@ static void cx23885_video_wakeup(struct cx23885_dev *dev, | |||
285 | list_del(&buf->vb.queue); | 285 | list_del(&buf->vb.queue); |
286 | wake_up(&buf->vb.done); | 286 | wake_up(&buf->vb.done); |
287 | } | 287 | } |
288 | if (list_empty(&q->active)) { | 288 | if (list_empty(&q->active)) |
289 | del_timer(&q->timeout); | 289 | del_timer(&q->timeout); |
290 | } else { | 290 | else |
291 | mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); | 291 | mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); |
292 | } | ||
293 | if (bc != 1) | 292 | if (bc != 1) |
294 | printk(KERN_ERR "%s: %d buffers handled (should be 1)\n", | 293 | printk(KERN_ERR "%s: %d buffers handled (should be 1)\n", |
295 | __func__, bc); | 294 | __func__, bc); |
@@ -379,12 +378,12 @@ static int res_get(struct cx23885_dev *dev, struct cx23885_fh *fh, | |||
379 | 378 | ||
380 | static int res_check(struct cx23885_fh *fh, unsigned int bit) | 379 | static int res_check(struct cx23885_fh *fh, unsigned int bit) |
381 | { | 380 | { |
382 | return (fh->resources & bit); | 381 | return fh->resources & bit; |
383 | } | 382 | } |
384 | 383 | ||
385 | static int res_locked(struct cx23885_dev *dev, unsigned int bit) | 384 | static int res_locked(struct cx23885_dev *dev, unsigned int bit) |
386 | { | 385 | { |
387 | return (dev->resources & bit); | 386 | return dev->resources & bit; |
388 | } | 387 | } |
389 | 388 | ||
390 | static void res_free(struct cx23885_dev *dev, struct cx23885_fh *fh, | 389 | static void res_free(struct cx23885_dev *dev, struct cx23885_fh *fh, |
@@ -887,14 +886,16 @@ static int video_mmap(struct file *file, struct vm_area_struct *vma) | |||
887 | /* ------------------------------------------------------------------ */ | 886 | /* ------------------------------------------------------------------ */ |
888 | /* VIDEO CTRL IOCTLS */ | 887 | /* VIDEO CTRL IOCTLS */ |
889 | 888 | ||
890 | static int cx23885_get_control(struct cx23885_dev *dev, struct v4l2_control *ctl) | 889 | static int cx23885_get_control(struct cx23885_dev *dev, |
890 | struct v4l2_control *ctl) | ||
891 | { | 891 | { |
892 | dprintk(1, "%s() calling cx25840(VIDIOC_G_CTRL)\n", __func__); | 892 | dprintk(1, "%s() calling cx25840(VIDIOC_G_CTRL)\n", __func__); |
893 | cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_G_CTRL, ctl); | 893 | cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_G_CTRL, ctl); |
894 | return 0; | 894 | return 0; |
895 | } | 895 | } |
896 | 896 | ||
897 | static int cx23885_set_control(struct cx23885_dev *dev, struct v4l2_control *ctl) | 897 | static int cx23885_set_control(struct cx23885_dev *dev, |
898 | struct v4l2_control *ctl) | ||
898 | { | 899 | { |
899 | dprintk(1, "%s() calling cx25840(VIDIOC_S_CTRL)" | 900 | dprintk(1, "%s() calling cx25840(VIDIOC_S_CTRL)" |
900 | " (disabled - no action)\n", __func__); | 901 | " (disabled - no action)\n", __func__); |
@@ -1073,29 +1074,29 @@ static int vidioc_reqbufs(struct file *file, void *priv, | |||
1073 | struct v4l2_requestbuffers *p) | 1074 | struct v4l2_requestbuffers *p) |
1074 | { | 1075 | { |
1075 | struct cx23885_fh *fh = priv; | 1076 | struct cx23885_fh *fh = priv; |
1076 | return (videobuf_reqbufs(get_queue(fh), p)); | 1077 | return videobuf_reqbufs(get_queue(fh), p); |
1077 | } | 1078 | } |
1078 | 1079 | ||
1079 | static int vidioc_querybuf(struct file *file, void *priv, | 1080 | static int vidioc_querybuf(struct file *file, void *priv, |
1080 | struct v4l2_buffer *p) | 1081 | struct v4l2_buffer *p) |
1081 | { | 1082 | { |
1082 | struct cx23885_fh *fh = priv; | 1083 | struct cx23885_fh *fh = priv; |
1083 | return (videobuf_querybuf(get_queue(fh), p)); | 1084 | return videobuf_querybuf(get_queue(fh), p); |
1084 | } | 1085 | } |
1085 | 1086 | ||
1086 | static int vidioc_qbuf(struct file *file, void *priv, | 1087 | static int vidioc_qbuf(struct file *file, void *priv, |
1087 | struct v4l2_buffer *p) | 1088 | struct v4l2_buffer *p) |
1088 | { | 1089 | { |
1089 | struct cx23885_fh *fh = priv; | 1090 | struct cx23885_fh *fh = priv; |
1090 | return (videobuf_qbuf(get_queue(fh), p)); | 1091 | return videobuf_qbuf(get_queue(fh), p); |
1091 | } | 1092 | } |
1092 | 1093 | ||
1093 | static int vidioc_dqbuf(struct file *file, void *priv, | 1094 | static int vidioc_dqbuf(struct file *file, void *priv, |
1094 | struct v4l2_buffer *p) | 1095 | struct v4l2_buffer *p) |
1095 | { | 1096 | { |
1096 | struct cx23885_fh *fh = priv; | 1097 | struct cx23885_fh *fh = priv; |
1097 | return (videobuf_dqbuf(get_queue(fh), p, | 1098 | return videobuf_dqbuf(get_queue(fh), p, |
1098 | file->f_flags & O_NONBLOCK)); | 1099 | file->f_flags & O_NONBLOCK); |
1099 | } | 1100 | } |
1100 | 1101 | ||
1101 | static int vidioc_streamon(struct file *file, void *priv, | 1102 | static int vidioc_streamon(struct file *file, void *priv, |
diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h index ba4e0aaed463..1d53f54cd943 100644 --- a/drivers/media/video/cx23885/cx23885.h +++ b/drivers/media/video/cx23885/cx23885.h | |||
@@ -37,7 +37,7 @@ | |||
37 | #include <linux/version.h> | 37 | #include <linux/version.h> |
38 | #include <linux/mutex.h> | 38 | #include <linux/mutex.h> |
39 | 39 | ||
40 | #define CX23885_VERSION_CODE KERNEL_VERSION(0,0,1) | 40 | #define CX23885_VERSION_CODE KERNEL_VERSION(0, 0, 1) |
41 | 41 | ||
42 | #define UNSET (-1U) | 42 | #define UNSET (-1U) |
43 | 43 | ||
@@ -225,7 +225,7 @@ struct cx23885_tsport { | |||
225 | int nr; | 225 | int nr; |
226 | int sram_chno; | 226 | int sram_chno; |
227 | 227 | ||
228 | struct videobuf_dvb dvb; | 228 | struct videobuf_dvb_frontends frontends; |
229 | 229 | ||
230 | /* dma queues */ | 230 | /* dma queues */ |
231 | struct cx23885_dmaqueue mpegq; | 231 | struct cx23885_dmaqueue mpegq; |
@@ -262,6 +262,9 @@ struct cx23885_tsport { | |||
262 | u32 src_sel_val; | 262 | u32 src_sel_val; |
263 | u32 vld_misc_val; | 263 | u32 vld_misc_val; |
264 | u32 hw_sop_ctrl_val; | 264 | u32 hw_sop_ctrl_val; |
265 | |||
266 | /* Allow a single tsport to have multiple frontends */ | ||
267 | u32 num_frontends; | ||
265 | }; | 268 | }; |
266 | 269 | ||
267 | struct cx23885_dev { | 270 | struct cx23885_dev { |
@@ -367,14 +370,14 @@ struct sram_channel { | |||
367 | /* ----------------------------------------------------------- */ | 370 | /* ----------------------------------------------------------- */ |
368 | 371 | ||
369 | #define cx_read(reg) readl(dev->lmmio + ((reg)>>2)) | 372 | #define cx_read(reg) readl(dev->lmmio + ((reg)>>2)) |
370 | #define cx_write(reg,value) writel((value), dev->lmmio + ((reg)>>2)) | 373 | #define cx_write(reg, value) writel((value), dev->lmmio + ((reg)>>2)) |
371 | 374 | ||
372 | #define cx_andor(reg,mask,value) \ | 375 | #define cx_andor(reg, mask, value) \ |
373 | writel((readl(dev->lmmio+((reg)>>2)) & ~(mask)) |\ | 376 | writel((readl(dev->lmmio+((reg)>>2)) & ~(mask)) |\ |
374 | ((value) & (mask)), dev->lmmio+((reg)>>2)) | 377 | ((value) & (mask)), dev->lmmio+((reg)>>2)) |
375 | 378 | ||
376 | #define cx_set(reg,bit) cx_andor((reg),(bit),(bit)) | 379 | #define cx_set(reg, bit) cx_andor((reg), (bit), (bit)) |
377 | #define cx_clear(reg,bit) cx_andor((reg),(bit),0) | 380 | #define cx_clear(reg, bit) cx_andor((reg), (bit), 0) |
378 | 381 | ||
379 | /* ----------------------------------------------------------- */ | 382 | /* ----------------------------------------------------------- */ |
380 | /* cx23885-core.c */ | 383 | /* cx23885-core.c */ |
@@ -411,7 +414,8 @@ extern const unsigned int cx23885_bcount; | |||
411 | extern struct cx23885_subid cx23885_subids[]; | 414 | extern struct cx23885_subid cx23885_subids[]; |
412 | extern const unsigned int cx23885_idcount; | 415 | extern const unsigned int cx23885_idcount; |
413 | 416 | ||
414 | extern int cx23885_tuner_callback(void *priv, int component, int command, int arg); | 417 | extern int cx23885_tuner_callback(void *priv, int component, |
418 | int command, int arg); | ||
415 | extern void cx23885_card_list(struct cx23885_dev *dev); | 419 | extern void cx23885_card_list(struct cx23885_dev *dev); |
416 | extern int cx23885_ir_init(struct cx23885_dev *dev); | 420 | extern int cx23885_ir_init(struct cx23885_dev *dev); |
417 | extern void cx23885_gpio_setup(struct cx23885_dev *dev); | 421 | extern void cx23885_gpio_setup(struct cx23885_dev *dev); |
@@ -479,11 +483,3 @@ static inline unsigned int norm_swidth(v4l2_std_id norm) | |||
479 | { | 483 | { |
480 | return (norm & (V4L2_STD_MN & ~V4L2_STD_PAL_Nc)) ? 754 : 922; | 484 | return (norm & (V4L2_STD_MN & ~V4L2_STD_PAL_Nc)) ? 754 : 922; |
481 | } | 485 | } |
482 | |||
483 | |||
484 | /* | ||
485 | * Local variables: | ||
486 | * c-basic-offset: 8 | ||
487 | * End: | ||
488 | * kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off | ||
489 | */ | ||
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c index 5da04e811ca2..fbc224f46e0e 100644 --- a/drivers/media/video/cx88/cx88-cards.c +++ b/drivers/media/video/cx88/cx88-cards.c | |||
@@ -1270,27 +1270,40 @@ static const struct cx88_board cx88_boards[] = { | |||
1270 | .mpeg = CX88_MPEG_DVB, | 1270 | .mpeg = CX88_MPEG_DVB, |
1271 | }, | 1271 | }, |
1272 | [CX88_BOARD_HAUPPAUGE_HVR3000] = { | 1272 | [CX88_BOARD_HAUPPAUGE_HVR3000] = { |
1273 | /* FIXME: Add dvb & radio support */ | ||
1274 | .name = "Hauppauge WinTV-HVR3000 TriMode Analog/DVB-S/DVB-T", | 1273 | .name = "Hauppauge WinTV-HVR3000 TriMode Analog/DVB-S/DVB-T", |
1275 | .tuner_type = TUNER_PHILIPS_FMD1216ME_MK3, | 1274 | .tuner_type = TUNER_PHILIPS_FMD1216ME_MK3, |
1276 | .radio_type = UNSET, | 1275 | .radio_type = UNSET, |
1277 | .tuner_addr = ADDR_UNSET, | 1276 | .tuner_addr = ADDR_UNSET, |
1278 | .radio_addr = ADDR_UNSET, | 1277 | .radio_addr = ADDR_UNSET, |
1279 | .tda9887_conf = TDA9887_PRESENT, | 1278 | .tda9887_conf = TDA9887_PRESENT, |
1279 | .audio_chip = V4L2_IDENT_WM8775, | ||
1280 | .input = {{ | 1280 | .input = {{ |
1281 | .type = CX88_VMUX_TELEVISION, | 1281 | .type = CX88_VMUX_TELEVISION, |
1282 | .vmux = 0, | 1282 | .vmux = 0, |
1283 | .gpio0 = 0x84bf, | 1283 | .gpio0 = 0x84bf, |
1284 | /* 1: TV Audio / FM Mono */ | ||
1285 | .audioroute = 1, | ||
1284 | },{ | 1286 | },{ |
1285 | .type = CX88_VMUX_COMPOSITE1, | 1287 | .type = CX88_VMUX_COMPOSITE1, |
1286 | .vmux = 1, | 1288 | .vmux = 1, |
1287 | .gpio0 = 0x84bf, | 1289 | .gpio0 = 0x84bf, |
1290 | /* 2: Line-In */ | ||
1291 | .audioroute = 2, | ||
1288 | },{ | 1292 | },{ |
1289 | .type = CX88_VMUX_SVIDEO, | 1293 | .type = CX88_VMUX_SVIDEO, |
1290 | .vmux = 2, | 1294 | .vmux = 2, |
1291 | .gpio0 = 0x84bf, | 1295 | .gpio0 = 0x84bf, |
1296 | /* 2: Line-In */ | ||
1297 | .audioroute = 2, | ||
1292 | }}, | 1298 | }}, |
1299 | .radio = { | ||
1300 | .type = CX88_RADIO, | ||
1301 | .gpio0 = 0x84bf, | ||
1302 | /* 4: FM Stereo (untested) */ | ||
1303 | .audioroute = 8, | ||
1304 | }, | ||
1293 | .mpeg = CX88_MPEG_DVB, | 1305 | .mpeg = CX88_MPEG_DVB, |
1306 | .num_frontends = 2, | ||
1294 | }, | 1307 | }, |
1295 | [CX88_BOARD_NORWOOD_MICRO] = { | 1308 | [CX88_BOARD_NORWOOD_MICRO] = { |
1296 | .name = "Norwood Micro TV Tuner", | 1309 | .name = "Norwood Micro TV Tuner", |
@@ -1356,23 +1369,27 @@ static const struct cx88_board cx88_boards[] = { | |||
1356 | .type = CX88_VMUX_TELEVISION, | 1369 | .type = CX88_VMUX_TELEVISION, |
1357 | .vmux = 0, | 1370 | .vmux = 0, |
1358 | .gpio0 = 0xef88, | 1371 | .gpio0 = 0xef88, |
1372 | /* 1: TV Audio / FM Mono */ | ||
1359 | .audioroute = 1, | 1373 | .audioroute = 1, |
1360 | },{ | 1374 | },{ |
1361 | .type = CX88_VMUX_COMPOSITE1, | 1375 | .type = CX88_VMUX_COMPOSITE1, |
1362 | .vmux = 1, | 1376 | .vmux = 1, |
1363 | .gpio0 = 0xef88, | 1377 | .gpio0 = 0xef88, |
1378 | /* 2: Line-In */ | ||
1364 | .audioroute = 2, | 1379 | .audioroute = 2, |
1365 | },{ | 1380 | },{ |
1366 | .type = CX88_VMUX_SVIDEO, | 1381 | .type = CX88_VMUX_SVIDEO, |
1367 | .vmux = 2, | 1382 | .vmux = 2, |
1368 | .gpio0 = 0xef88, | 1383 | .gpio0 = 0xef88, |
1384 | /* 2: Line-In */ | ||
1369 | .audioroute = 2, | 1385 | .audioroute = 2, |
1370 | }}, | 1386 | }}, |
1371 | /* fixme: Add radio support */ | ||
1372 | .mpeg = CX88_MPEG_DVB | CX88_MPEG_BLACKBIRD, | 1387 | .mpeg = CX88_MPEG_DVB | CX88_MPEG_BLACKBIRD, |
1373 | .radio = { | 1388 | .radio = { |
1374 | .type = CX88_RADIO, | 1389 | .type = CX88_RADIO, |
1375 | .gpio0 = 0xef88, | 1390 | .gpio0 = 0xef88, |
1391 | /* 4: FM Stereo (untested) */ | ||
1392 | .audioroute = 8, | ||
1376 | }, | 1393 | }, |
1377 | }, | 1394 | }, |
1378 | [CX88_BOARD_ADSTECH_PTV_390] = { | 1395 | [CX88_BOARD_ADSTECH_PTV_390] = { |
@@ -1716,6 +1733,7 @@ static const struct cx88_board cx88_boards[] = { | |||
1716 | .tuner_addr = ADDR_UNSET, | 1733 | .tuner_addr = ADDR_UNSET, |
1717 | .radio_addr = ADDR_UNSET, | 1734 | .radio_addr = ADDR_UNSET, |
1718 | .tda9887_conf = TDA9887_PRESENT, | 1735 | .tda9887_conf = TDA9887_PRESENT, |
1736 | .audio_chip = V4L2_IDENT_WM8775, | ||
1719 | /* | 1737 | /* |
1720 | * GPIO0 (WINTV2000) | 1738 | * GPIO0 (WINTV2000) |
1721 | * | 1739 | * |
@@ -1729,7 +1747,7 @@ static const struct cx88_board cx88_boards[] = { | |||
1729 | * BIT VALUE FUNCTION GP{x}_IO | 1747 | * BIT VALUE FUNCTION GP{x}_IO |
1730 | * 0 1 I:? | 1748 | * 0 1 I:? |
1731 | * 1 1 I:? | 1749 | * 1 1 I:? |
1732 | * 2 1 O:DVB-T DEMOD ENABLE LOW/ANALOG DEMOD ENABLE HIGH | 1750 | * 2 1 O:MPEG PORT 0=DVB-T 1=DVB-S |
1733 | * 3 1 I:? | 1751 | * 3 1 I:? |
1734 | * 4 1 I:? | 1752 | * 4 1 I:? |
1735 | * 5 1 I:? | 1753 | * 5 1 I:? |
@@ -1745,22 +1763,41 @@ static const struct cx88_board cx88_boards[] = { | |||
1745 | * d 0 I | 1763 | * d 0 I |
1746 | * e 1 O | 1764 | * e 1 O |
1747 | * f 1 O | 1765 | * f 1 O |
1766 | * | ||
1767 | * WM8775 ADC | ||
1768 | * | ||
1769 | * 1: TV Audio / FM Mono | ||
1770 | * 2: Line-In | ||
1771 | * 3: Line-In Expansion | ||
1772 | * 4: FM Stereo | ||
1748 | */ | 1773 | */ |
1749 | .input = {{ | 1774 | .input = {{ |
1750 | .type = CX88_VMUX_TELEVISION, | 1775 | .type = CX88_VMUX_TELEVISION, |
1751 | .vmux = 0, | 1776 | .vmux = 0, |
1752 | .gpio0 = 0xc4bf, | 1777 | .gpio0 = 0xc4bf, |
1778 | /* 1: TV Audio / FM Mono */ | ||
1779 | .audioroute = 1, | ||
1753 | }, { | 1780 | }, { |
1754 | .type = CX88_VMUX_COMPOSITE1, | 1781 | .type = CX88_VMUX_COMPOSITE1, |
1755 | .vmux = 1, | 1782 | .vmux = 1, |
1756 | .gpio0 = 0xc4bf, | 1783 | .gpio0 = 0xc4bf, |
1784 | /* 2: Line-In */ | ||
1785 | .audioroute = 2, | ||
1757 | }, { | 1786 | }, { |
1758 | .type = CX88_VMUX_SVIDEO, | 1787 | .type = CX88_VMUX_SVIDEO, |
1759 | .vmux = 2, | 1788 | .vmux = 2, |
1760 | .gpio0 = 0xc4bf, | 1789 | .gpio0 = 0xc4bf, |
1790 | /* 2: Line-In */ | ||
1791 | .audioroute = 2, | ||
1761 | } }, | 1792 | } }, |
1762 | /* fixme: Add radio support */ | 1793 | .radio = { |
1794 | .type = CX88_RADIO, | ||
1795 | .gpio0 = 0xc4bf, | ||
1796 | /* 4: FM Stereo */ | ||
1797 | .audioroute = 8, | ||
1798 | }, | ||
1763 | .mpeg = CX88_MPEG_DVB, | 1799 | .mpeg = CX88_MPEG_DVB, |
1800 | .num_frontends = 2, | ||
1764 | }, | 1801 | }, |
1765 | [CX88_BOARD_HAUPPAUGE_HVR4000LITE] = { | 1802 | [CX88_BOARD_HAUPPAUGE_HVR4000LITE] = { |
1766 | .name = "Hauppauge WinTV-HVR4000(Lite) DVB-S/S2", | 1803 | .name = "Hauppauge WinTV-HVR4000(Lite) DVB-S/S2", |
@@ -2662,10 +2699,13 @@ static void cx88_card_setup_pre_i2c(struct cx88_core *core) | |||
2662 | 2699 | ||
2663 | case CX88_BOARD_HAUPPAUGE_HVR3000: | 2700 | case CX88_BOARD_HAUPPAUGE_HVR3000: |
2664 | case CX88_BOARD_HAUPPAUGE_HVR4000: | 2701 | case CX88_BOARD_HAUPPAUGE_HVR4000: |
2665 | case CX88_BOARD_HAUPPAUGE_HVR4000LITE: | ||
2666 | /* Init GPIO */ | 2702 | /* Init GPIO */ |
2667 | cx_write(MO_GP0_IO, core->board.input[0].gpio0); | 2703 | cx_write(MO_GP0_IO, core->board.input[0].gpio0); |
2668 | udelay(1000); | 2704 | udelay(1000); |
2705 | cx_clear(MO_GP0_IO, 0x00000080); | ||
2706 | udelay(50); | ||
2707 | cx_set(MO_GP0_IO, 0x00000080); /* 702 out of reset */ | ||
2708 | udelay(1000); | ||
2669 | break; | 2709 | break; |
2670 | } | 2710 | } |
2671 | } | 2711 | } |
@@ -3004,10 +3044,14 @@ struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr) | |||
3004 | 3044 | ||
3005 | memcpy(&core->board, &cx88_boards[core->boardnr], sizeof(core->board)); | 3045 | memcpy(&core->board, &cx88_boards[core->boardnr], sizeof(core->board)); |
3006 | 3046 | ||
3007 | info_printk(core, "subsystem: %04x:%04x, board: %s [card=%d,%s]\n", | 3047 | if (!core->board.num_frontends) |
3048 | core->board.num_frontends=1; | ||
3049 | |||
3050 | info_printk(core, "subsystem: %04x:%04x, board: %s [card=%d,%s], frontend(s): %d\n", | ||
3008 | pci->subsystem_vendor, pci->subsystem_device, core->board.name, | 3051 | pci->subsystem_vendor, pci->subsystem_device, core->board.name, |
3009 | core->boardnr, card[core->nr] == core->boardnr ? | 3052 | core->boardnr, card[core->nr] == core->boardnr ? |
3010 | "insmod option" : "autodetected"); | 3053 | "insmod option" : "autodetected", |
3054 | core->board.num_frontends); | ||
3011 | 3055 | ||
3012 | if (tuner[core->nr] != UNSET) | 3056 | if (tuner[core->nr] != UNSET) |
3013 | core->board.tuner_type = tuner[core->nr]; | 3057 | core->board.tuner_type = tuner[core->nr]; |
diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c index d656fec59010..60705b08bfe8 100644 --- a/drivers/media/video/cx88/cx88-core.c +++ b/drivers/media/video/cx88/cx88-core.c | |||
@@ -549,7 +549,8 @@ void cx88_wakeup(struct cx88_core *core, | |||
549 | mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); | 549 | mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); |
550 | } | 550 | } |
551 | if (bc != 1) | 551 | if (bc != 1) |
552 | printk("%s: %d buffers handled (should be 1)\n",__func__,bc); | 552 | dprintk(2, "%s: %d buffers handled (should be 1)\n", |
553 | __func__, bc); | ||
553 | } | 554 | } |
554 | 555 | ||
555 | void cx88_shutdown(struct cx88_core *core) | 556 | void cx88_shutdown(struct cx88_core *core) |
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c index 344ed2626e59..6968ab0181aa 100644 --- a/drivers/media/video/cx88/cx88-dvb.c +++ b/drivers/media/video/cx88/cx88-dvb.c | |||
@@ -116,13 +116,23 @@ static int cx88_dvb_bus_ctrl(struct dvb_frontend* fe, int acquire) | |||
116 | struct cx8802_dev *dev= fe->dvb->priv; | 116 | struct cx8802_dev *dev= fe->dvb->priv; |
117 | struct cx8802_driver *drv = NULL; | 117 | struct cx8802_driver *drv = NULL; |
118 | int ret = 0; | 118 | int ret = 0; |
119 | int fe_id; | ||
120 | |||
121 | fe_id = videobuf_dvb_find_frontend(&dev->frontends, fe); | ||
122 | if (!fe_id) { | ||
123 | printk(KERN_ERR "%s() No frontend found\n", __func__); | ||
124 | return -EINVAL; | ||
125 | } | ||
119 | 126 | ||
120 | drv = cx8802_get_driver(dev, CX88_MPEG_DVB); | 127 | drv = cx8802_get_driver(dev, CX88_MPEG_DVB); |
121 | if (drv) { | 128 | if (drv) { |
122 | if (acquire) | 129 | if (acquire){ |
130 | dev->frontends.active_fe_id = fe_id; | ||
123 | ret = drv->request_acquire(drv); | 131 | ret = drv->request_acquire(drv); |
124 | else | 132 | } else { |
125 | ret = drv->request_release(drv); | 133 | ret = drv->request_release(drv); |
134 | dev->frontends.active_fe_id = 0; | ||
135 | } | ||
126 | } | 136 | } |
127 | 137 | ||
128 | return ret; | 138 | return ret; |
@@ -396,7 +406,7 @@ static int tevii_dvbs_set_voltage(struct dvb_frontend *fe, | |||
396 | cx_write(MO_GP0_IO, 0x00006060); | 406 | cx_write(MO_GP0_IO, 0x00006060); |
397 | break; | 407 | break; |
398 | case SEC_VOLTAGE_OFF: | 408 | case SEC_VOLTAGE_OFF: |
399 | printk("LNB Voltage SEC_VOLTAGE_off\n"); | 409 | printk("LNB Voltage SEC_VOLTAGE_off\n"); |
400 | break; | 410 | break; |
401 | } | 411 | } |
402 | 412 | ||
@@ -483,6 +493,7 @@ static struct xc5000_config dvico_fusionhdtv7_tuner_config = { | |||
483 | static int attach_xc3028(u8 addr, struct cx8802_dev *dev) | 493 | static int attach_xc3028(u8 addr, struct cx8802_dev *dev) |
484 | { | 494 | { |
485 | struct dvb_frontend *fe; | 495 | struct dvb_frontend *fe; |
496 | struct videobuf_dvb_frontend *fe0 = NULL; | ||
486 | struct xc2028_ctrl ctl; | 497 | struct xc2028_ctrl ctl; |
487 | struct xc2028_config cfg = { | 498 | struct xc2028_config cfg = { |
488 | .i2c_adap = &dev->core->i2c_adap, | 499 | .i2c_adap = &dev->core->i2c_adap, |
@@ -490,7 +501,12 @@ static int attach_xc3028(u8 addr, struct cx8802_dev *dev) | |||
490 | .ctrl = &ctl, | 501 | .ctrl = &ctl, |
491 | }; | 502 | }; |
492 | 503 | ||
493 | if (!dev->dvb.frontend) { | 504 | /* Get the first frontend */ |
505 | fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1); | ||
506 | if (!fe0) | ||
507 | return -EINVAL; | ||
508 | |||
509 | if (!fe0->dvb.frontend) { | ||
494 | printk(KERN_ERR "%s/2: dvb frontend not attached. " | 510 | printk(KERN_ERR "%s/2: dvb frontend not attached. " |
495 | "Can't attach xc3028\n", | 511 | "Can't attach xc3028\n", |
496 | dev->core->name); | 512 | dev->core->name); |
@@ -504,10 +520,13 @@ static int attach_xc3028(u8 addr, struct cx8802_dev *dev) | |||
504 | */ | 520 | */ |
505 | cx88_setup_xc3028(dev->core, &ctl); | 521 | cx88_setup_xc3028(dev->core, &ctl); |
506 | 522 | ||
507 | fe = dvb_attach(xc2028_attach, dev->dvb.frontend, &cfg); | 523 | fe = dvb_attach(xc2028_attach, fe0->dvb.frontend, &cfg); |
508 | if (!fe) { | 524 | if (!fe) { |
509 | printk(KERN_ERR "%s/2: xc3028 attach failed\n", | 525 | printk(KERN_ERR "%s/2: xc3028 attach failed\n", |
510 | dev->core->name); | 526 | dev->core->name); |
527 | dvb_frontend_detach(fe0->dvb.frontend); | ||
528 | dvb_unregister_frontend(fe0->dvb.frontend); | ||
529 | fe0->dvb.frontend = NULL; | ||
511 | return -EINVAL; | 530 | return -EINVAL; |
512 | } | 531 | } |
513 | 532 | ||
@@ -532,8 +551,10 @@ static int cx24116_reset_device(struct dvb_frontend *fe) | |||
532 | struct cx88_core *core = dev->core; | 551 | struct cx88_core *core = dev->core; |
533 | 552 | ||
534 | /* Reset the part */ | 553 | /* Reset the part */ |
554 | /* Put the cx24116 into reset */ | ||
535 | cx_write(MO_SRST_IO, 0); | 555 | cx_write(MO_SRST_IO, 0); |
536 | msleep(10); | 556 | msleep(10); |
557 | /* Take the cx24116 out of reset */ | ||
537 | cx_write(MO_SRST_IO, 1); | 558 | cx_write(MO_SRST_IO, 1); |
538 | msleep(10); | 559 | msleep(10); |
539 | 560 | ||
@@ -554,14 +575,14 @@ static struct cx24116_config tevii_s460_config = { | |||
554 | 575 | ||
555 | static struct stv0299_config tevii_tuner_sharp_config = { | 576 | static struct stv0299_config tevii_tuner_sharp_config = { |
556 | .demod_address = 0x68, | 577 | .demod_address = 0x68, |
557 | .inittab = sharp_z0194a__inittab, | 578 | .inittab = sharp_z0194a_inittab, |
558 | .mclk = 88000000UL, | 579 | .mclk = 88000000UL, |
559 | .invert = 1, | 580 | .invert = 1, |
560 | .skip_reinit = 0, | 581 | .skip_reinit = 0, |
561 | .lock_output = 1, | 582 | .lock_output = 1, |
562 | .volt13_op0_op1 = STV0299_VOLT13_OP1, | 583 | .volt13_op0_op1 = STV0299_VOLT13_OP1, |
563 | .min_delay_ms = 100, | 584 | .min_delay_ms = 100, |
564 | .set_symbol_rate = sharp_z0194a__set_symbol_rate, | 585 | .set_symbol_rate = sharp_z0194a_set_symbol_rate, |
565 | .set_ts_params = cx24116_set_ts_param, | 586 | .set_ts_params = cx24116_set_ts_param, |
566 | }; | 587 | }; |
567 | 588 | ||
@@ -574,19 +595,25 @@ static struct stv0288_config tevii_tuner_earda_config = { | |||
574 | static int dvb_register(struct cx8802_dev *dev) | 595 | static int dvb_register(struct cx8802_dev *dev) |
575 | { | 596 | { |
576 | struct cx88_core *core = dev->core; | 597 | struct cx88_core *core = dev->core; |
598 | struct videobuf_dvb_frontend *fe0, *fe1 = NULL; | ||
599 | int mfe_shared = 0; /* bus not shared by default */ | ||
577 | 600 | ||
578 | /* init struct videobuf_dvb */ | 601 | /* Get the first frontend */ |
579 | dev->dvb.name = core->name; | 602 | fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1); |
580 | dev->ts_gen_cntrl = 0x0c; | 603 | if (!fe0) |
604 | return -EINVAL; | ||
581 | 605 | ||
582 | /* init frontend */ | 606 | /* multi-frontend gate control is undefined or defaults to fe0 */ |
607 | dev->frontends.gate = 0; | ||
608 | |||
609 | /* init frontend(s) */ | ||
583 | switch (core->boardnr) { | 610 | switch (core->boardnr) { |
584 | case CX88_BOARD_HAUPPAUGE_DVB_T1: | 611 | case CX88_BOARD_HAUPPAUGE_DVB_T1: |
585 | dev->dvb.frontend = dvb_attach(cx22702_attach, | 612 | fe0->dvb.frontend = dvb_attach(cx22702_attach, |
586 | &connexant_refboard_config, | 613 | &connexant_refboard_config, |
587 | &core->i2c_adap); | 614 | &core->i2c_adap); |
588 | if (dev->dvb.frontend != NULL) { | 615 | if (fe0->dvb.frontend != NULL) { |
589 | if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend, | 616 | if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, |
590 | 0x61, &core->i2c_adap, | 617 | 0x61, &core->i2c_adap, |
591 | DVB_PLL_THOMSON_DTT759X)) | 618 | DVB_PLL_THOMSON_DTT759X)) |
592 | goto frontend_detach; | 619 | goto frontend_detach; |
@@ -596,11 +623,11 @@ static int dvb_register(struct cx8802_dev *dev) | |||
596 | case CX88_BOARD_CONEXANT_DVB_T1: | 623 | case CX88_BOARD_CONEXANT_DVB_T1: |
597 | case CX88_BOARD_KWORLD_DVB_T_CX22702: | 624 | case CX88_BOARD_KWORLD_DVB_T_CX22702: |
598 | case CX88_BOARD_WINFAST_DTV1000: | 625 | case CX88_BOARD_WINFAST_DTV1000: |
599 | dev->dvb.frontend = dvb_attach(cx22702_attach, | 626 | fe0->dvb.frontend = dvb_attach(cx22702_attach, |
600 | &connexant_refboard_config, | 627 | &connexant_refboard_config, |
601 | &core->i2c_adap); | 628 | &core->i2c_adap); |
602 | if (dev->dvb.frontend != NULL) { | 629 | if (fe0->dvb.frontend != NULL) { |
603 | if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend, | 630 | if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, |
604 | 0x60, &core->i2c_adap, | 631 | 0x60, &core->i2c_adap, |
605 | DVB_PLL_THOMSON_DTT7579)) | 632 | DVB_PLL_THOMSON_DTT7579)) |
606 | goto frontend_detach; | 633 | goto frontend_detach; |
@@ -610,33 +637,67 @@ static int dvb_register(struct cx8802_dev *dev) | |||
610 | case CX88_BOARD_HAUPPAUGE_HVR1100: | 637 | case CX88_BOARD_HAUPPAUGE_HVR1100: |
611 | case CX88_BOARD_HAUPPAUGE_HVR1100LP: | 638 | case CX88_BOARD_HAUPPAUGE_HVR1100LP: |
612 | case CX88_BOARD_HAUPPAUGE_HVR1300: | 639 | case CX88_BOARD_HAUPPAUGE_HVR1300: |
613 | case CX88_BOARD_HAUPPAUGE_HVR3000: | 640 | fe0->dvb.frontend = dvb_attach(cx22702_attach, |
614 | dev->dvb.frontend = dvb_attach(cx22702_attach, | ||
615 | &hauppauge_hvr_config, | 641 | &hauppauge_hvr_config, |
616 | &core->i2c_adap); | 642 | &core->i2c_adap); |
617 | if (dev->dvb.frontend != NULL) { | 643 | if (fe0->dvb.frontend != NULL) { |
618 | if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend, | 644 | if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend, |
619 | &core->i2c_adap, 0x61, | 645 | &core->i2c_adap, 0x61, |
620 | TUNER_PHILIPS_FMD1216ME_MK3)) | 646 | TUNER_PHILIPS_FMD1216ME_MK3)) |
621 | goto frontend_detach; | 647 | goto frontend_detach; |
622 | } | 648 | } |
623 | break; | 649 | break; |
650 | case CX88_BOARD_HAUPPAUGE_HVR3000: | ||
651 | /* DVB-S init */ | ||
652 | fe0->dvb.frontend = dvb_attach(cx24123_attach, | ||
653 | &hauppauge_novas_config, | ||
654 | &dev->core->i2c_adap); | ||
655 | if (fe0->dvb.frontend) { | ||
656 | if (!dvb_attach(isl6421_attach, fe0->dvb.frontend, | ||
657 | &dev->core->i2c_adap, 0x08, ISL6421_DCL, 0x00)) { | ||
658 | dprintk( 1, "%s(): HVR3000 - DVB-S LNB Init: failed\n", __func__); | ||
659 | } | ||
660 | } else { | ||
661 | dprintk( 1, "%s(): HVR3000 - DVB-S Init: failed\n", __func__); | ||
662 | } | ||
663 | /* DVB-T init */ | ||
664 | fe1 = videobuf_dvb_get_frontend(&dev->frontends, 2); | ||
665 | if (fe1) { | ||
666 | dev->frontends.gate = 2; | ||
667 | mfe_shared = 1; | ||
668 | fe1->dvb.frontend = dvb_attach(cx22702_attach, | ||
669 | &hauppauge_hvr_config, | ||
670 | &dev->core->i2c_adap); | ||
671 | if (fe1->dvb.frontend) { | ||
672 | fe1->dvb.frontend->id = 1; | ||
673 | if(!dvb_attach(simple_tuner_attach, fe1->dvb.frontend, | ||
674 | &dev->core->i2c_adap, 0x61, | ||
675 | TUNER_PHILIPS_FMD1216ME_MK3)) { | ||
676 | dprintk( 1, "%s(): HVR3000 - DVB-T misc Init: failed\n", __func__); | ||
677 | } | ||
678 | } else { | ||
679 | dprintk( 1, "%s(): HVR3000 - DVB-T Init: failed\n", __func__); | ||
680 | } | ||
681 | } else { | ||
682 | dprintk( 1, "%s(): HVR3000 - DVB-T Init: can't find frontend 2.\n", __func__); | ||
683 | } | ||
684 | break; | ||
624 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS: | 685 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS: |
625 | dev->dvb.frontend = dvb_attach(mt352_attach, | 686 | fe0->dvb.frontend = dvb_attach(mt352_attach, |
626 | &dvico_fusionhdtv, | 687 | &dvico_fusionhdtv, |
627 | &core->i2c_adap); | 688 | &core->i2c_adap); |
628 | if (dev->dvb.frontend != NULL) { | 689 | if (fe0->dvb.frontend != NULL) { |
629 | if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend, | 690 | if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, |
630 | 0x60, NULL, DVB_PLL_THOMSON_DTT7579)) | 691 | 0x60, NULL, DVB_PLL_THOMSON_DTT7579)) |
631 | goto frontend_detach; | 692 | goto frontend_detach; |
632 | break; | 693 | break; |
633 | } | 694 | } |
634 | /* ZL10353 replaces MT352 on later cards */ | 695 | /* ZL10353 replaces MT352 on later cards */ |
635 | dev->dvb.frontend = dvb_attach(zl10353_attach, | 696 | fe0->dvb.frontend = dvb_attach(zl10353_attach, |
636 | &dvico_fusionhdtv_plus_v1_1, | 697 | &dvico_fusionhdtv_plus_v1_1, |
637 | &core->i2c_adap); | 698 | &core->i2c_adap); |
638 | if (dev->dvb.frontend != NULL) { | 699 | if (fe0->dvb.frontend != NULL) { |
639 | if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend, | 700 | if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, |
640 | 0x60, NULL, DVB_PLL_THOMSON_DTT7579)) | 701 | 0x60, NULL, DVB_PLL_THOMSON_DTT7579)) |
641 | goto frontend_detach; | 702 | goto frontend_detach; |
642 | } | 703 | } |
@@ -644,31 +705,31 @@ static int dvb_register(struct cx8802_dev *dev) | |||
644 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL: | 705 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL: |
645 | /* The tin box says DEE1601, but it seems to be DTT7579 | 706 | /* The tin box says DEE1601, but it seems to be DTT7579 |
646 | * compatible, with a slightly different MT352 AGC gain. */ | 707 | * compatible, with a slightly different MT352 AGC gain. */ |
647 | dev->dvb.frontend = dvb_attach(mt352_attach, | 708 | fe0->dvb.frontend = dvb_attach(mt352_attach, |
648 | &dvico_fusionhdtv_dual, | 709 | &dvico_fusionhdtv_dual, |
649 | &core->i2c_adap); | 710 | &core->i2c_adap); |
650 | if (dev->dvb.frontend != NULL) { | 711 | if (fe0->dvb.frontend != NULL) { |
651 | if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend, | 712 | if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, |
652 | 0x61, NULL, DVB_PLL_THOMSON_DTT7579)) | 713 | 0x61, NULL, DVB_PLL_THOMSON_DTT7579)) |
653 | goto frontend_detach; | 714 | goto frontend_detach; |
654 | break; | 715 | break; |
655 | } | 716 | } |
656 | /* ZL10353 replaces MT352 on later cards */ | 717 | /* ZL10353 replaces MT352 on later cards */ |
657 | dev->dvb.frontend = dvb_attach(zl10353_attach, | 718 | fe0->dvb.frontend = dvb_attach(zl10353_attach, |
658 | &dvico_fusionhdtv_plus_v1_1, | 719 | &dvico_fusionhdtv_plus_v1_1, |
659 | &core->i2c_adap); | 720 | &core->i2c_adap); |
660 | if (dev->dvb.frontend != NULL) { | 721 | if (fe0->dvb.frontend != NULL) { |
661 | if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend, | 722 | if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, |
662 | 0x61, NULL, DVB_PLL_THOMSON_DTT7579)) | 723 | 0x61, NULL, DVB_PLL_THOMSON_DTT7579)) |
663 | goto frontend_detach; | 724 | goto frontend_detach; |
664 | } | 725 | } |
665 | break; | 726 | break; |
666 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1: | 727 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1: |
667 | dev->dvb.frontend = dvb_attach(mt352_attach, | 728 | fe0->dvb.frontend = dvb_attach(mt352_attach, |
668 | &dvico_fusionhdtv, | 729 | &dvico_fusionhdtv, |
669 | &core->i2c_adap); | 730 | &core->i2c_adap); |
670 | if (dev->dvb.frontend != NULL) { | 731 | if (fe0->dvb.frontend != NULL) { |
671 | if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend, | 732 | if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, |
672 | 0x61, NULL, DVB_PLL_LG_Z201)) | 733 | 0x61, NULL, DVB_PLL_LG_Z201)) |
673 | goto frontend_detach; | 734 | goto frontend_detach; |
674 | } | 735 | } |
@@ -676,11 +737,11 @@ static int dvb_register(struct cx8802_dev *dev) | |||
676 | case CX88_BOARD_KWORLD_DVB_T: | 737 | case CX88_BOARD_KWORLD_DVB_T: |
677 | case CX88_BOARD_DNTV_LIVE_DVB_T: | 738 | case CX88_BOARD_DNTV_LIVE_DVB_T: |
678 | case CX88_BOARD_ADSTECH_DVB_T_PCI: | 739 | case CX88_BOARD_ADSTECH_DVB_T_PCI: |
679 | dev->dvb.frontend = dvb_attach(mt352_attach, | 740 | fe0->dvb.frontend = dvb_attach(mt352_attach, |
680 | &dntv_live_dvbt_config, | 741 | &dntv_live_dvbt_config, |
681 | &core->i2c_adap); | 742 | &core->i2c_adap); |
682 | if (dev->dvb.frontend != NULL) { | 743 | if (fe0->dvb.frontend != NULL) { |
683 | if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend, | 744 | if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, |
684 | 0x61, NULL, DVB_PLL_UNKNOWN_1)) | 745 | 0x61, NULL, DVB_PLL_UNKNOWN_1)) |
685 | goto frontend_detach; | 746 | goto frontend_detach; |
686 | } | 747 | } |
@@ -688,10 +749,10 @@ static int dvb_register(struct cx8802_dev *dev) | |||
688 | case CX88_BOARD_DNTV_LIVE_DVB_T_PRO: | 749 | case CX88_BOARD_DNTV_LIVE_DVB_T_PRO: |
689 | #if defined(CONFIG_VIDEO_CX88_VP3054) || (defined(CONFIG_VIDEO_CX88_VP3054_MODULE) && defined(MODULE)) | 750 | #if defined(CONFIG_VIDEO_CX88_VP3054) || (defined(CONFIG_VIDEO_CX88_VP3054_MODULE) && defined(MODULE)) |
690 | /* MT352 is on a secondary I2C bus made from some GPIO lines */ | 751 | /* MT352 is on a secondary I2C bus made from some GPIO lines */ |
691 | dev->dvb.frontend = dvb_attach(mt352_attach, &dntv_live_dvbt_pro_config, | 752 | fe0->dvb.frontend = dvb_attach(mt352_attach, &dntv_live_dvbt_pro_config, |
692 | &dev->vp3054->adap); | 753 | &dev->vp3054->adap); |
693 | if (dev->dvb.frontend != NULL) { | 754 | if (fe0->dvb.frontend != NULL) { |
694 | if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend, | 755 | if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend, |
695 | &core->i2c_adap, 0x61, | 756 | &core->i2c_adap, 0x61, |
696 | TUNER_PHILIPS_FMD1216ME_MK3)) | 757 | TUNER_PHILIPS_FMD1216ME_MK3)) |
697 | goto frontend_detach; | 758 | goto frontend_detach; |
@@ -702,22 +763,22 @@ static int dvb_register(struct cx8802_dev *dev) | |||
702 | #endif | 763 | #endif |
703 | break; | 764 | break; |
704 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID: | 765 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID: |
705 | dev->dvb.frontend = dvb_attach(zl10353_attach, | 766 | fe0->dvb.frontend = dvb_attach(zl10353_attach, |
706 | &dvico_fusionhdtv_hybrid, | 767 | &dvico_fusionhdtv_hybrid, |
707 | &core->i2c_adap); | 768 | &core->i2c_adap); |
708 | if (dev->dvb.frontend != NULL) { | 769 | if (fe0->dvb.frontend != NULL) { |
709 | if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend, | 770 | if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend, |
710 | &core->i2c_adap, 0x61, | 771 | &core->i2c_adap, 0x61, |
711 | TUNER_THOMSON_FE6600)) | 772 | TUNER_THOMSON_FE6600)) |
712 | goto frontend_detach; | 773 | goto frontend_detach; |
713 | } | 774 | } |
714 | break; | 775 | break; |
715 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO: | 776 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO: |
716 | dev->dvb.frontend = dvb_attach(zl10353_attach, | 777 | fe0->dvb.frontend = dvb_attach(zl10353_attach, |
717 | &dvico_fusionhdtv_xc3028, | 778 | &dvico_fusionhdtv_xc3028, |
718 | &core->i2c_adap); | 779 | &core->i2c_adap); |
719 | if (dev->dvb.frontend == NULL) | 780 | if (fe0->dvb.frontend == NULL) |
720 | dev->dvb.frontend = dvb_attach(mt352_attach, | 781 | fe0->dvb.frontend = dvb_attach(mt352_attach, |
721 | &dvico_fusionhdtv_mt352_xc3028, | 782 | &dvico_fusionhdtv_mt352_xc3028, |
722 | &core->i2c_adap); | 783 | &core->i2c_adap); |
723 | /* | 784 | /* |
@@ -725,16 +786,16 @@ static int dvb_register(struct cx8802_dev *dev) | |||
725 | * We must not permit gate_ctrl to be performed, or | 786 | * We must not permit gate_ctrl to be performed, or |
726 | * the xc3028 cannot communicate on the bus. | 787 | * the xc3028 cannot communicate on the bus. |
727 | */ | 788 | */ |
728 | if (dev->dvb.frontend) | 789 | if (fe0->dvb.frontend) |
729 | dev->dvb.frontend->ops.i2c_gate_ctrl = NULL; | 790 | fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL; |
730 | if (attach_xc3028(0x61, dev) < 0) | 791 | if (attach_xc3028(0x61, dev) < 0) |
731 | return -EINVAL; | 792 | return -EINVAL; |
732 | break; | 793 | break; |
733 | case CX88_BOARD_PCHDTV_HD3000: | 794 | case CX88_BOARD_PCHDTV_HD3000: |
734 | dev->dvb.frontend = dvb_attach(or51132_attach, &pchdtv_hd3000, | 795 | fe0->dvb.frontend = dvb_attach(or51132_attach, &pchdtv_hd3000, |
735 | &core->i2c_adap); | 796 | &core->i2c_adap); |
736 | if (dev->dvb.frontend != NULL) { | 797 | if (fe0->dvb.frontend != NULL) { |
737 | if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend, | 798 | if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend, |
738 | &core->i2c_adap, 0x61, | 799 | &core->i2c_adap, 0x61, |
739 | TUNER_THOMSON_DTT761X)) | 800 | TUNER_THOMSON_DTT761X)) |
740 | goto frontend_detach; | 801 | goto frontend_detach; |
@@ -751,11 +812,11 @@ static int dvb_register(struct cx8802_dev *dev) | |||
751 | 812 | ||
752 | /* Select RF connector callback */ | 813 | /* Select RF connector callback */ |
753 | fusionhdtv_3_gold.pll_rf_set = lgdt330x_pll_rf_set; | 814 | fusionhdtv_3_gold.pll_rf_set = lgdt330x_pll_rf_set; |
754 | dev->dvb.frontend = dvb_attach(lgdt330x_attach, | 815 | fe0->dvb.frontend = dvb_attach(lgdt330x_attach, |
755 | &fusionhdtv_3_gold, | 816 | &fusionhdtv_3_gold, |
756 | &core->i2c_adap); | 817 | &core->i2c_adap); |
757 | if (dev->dvb.frontend != NULL) { | 818 | if (fe0->dvb.frontend != NULL) { |
758 | if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend, | 819 | if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend, |
759 | &core->i2c_adap, 0x61, | 820 | &core->i2c_adap, 0x61, |
760 | TUNER_MICROTUNE_4042FI5)) | 821 | TUNER_MICROTUNE_4042FI5)) |
761 | goto frontend_detach; | 822 | goto frontend_detach; |
@@ -769,11 +830,11 @@ static int dvb_register(struct cx8802_dev *dev) | |||
769 | mdelay(100); | 830 | mdelay(100); |
770 | cx_set(MO_GP0_IO, 9); | 831 | cx_set(MO_GP0_IO, 9); |
771 | mdelay(200); | 832 | mdelay(200); |
772 | dev->dvb.frontend = dvb_attach(lgdt330x_attach, | 833 | fe0->dvb.frontend = dvb_attach(lgdt330x_attach, |
773 | &fusionhdtv_3_gold, | 834 | &fusionhdtv_3_gold, |
774 | &core->i2c_adap); | 835 | &core->i2c_adap); |
775 | if (dev->dvb.frontend != NULL) { | 836 | if (fe0->dvb.frontend != NULL) { |
776 | if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend, | 837 | if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend, |
777 | &core->i2c_adap, 0x61, | 838 | &core->i2c_adap, 0x61, |
778 | TUNER_THOMSON_DTT761X)) | 839 | TUNER_THOMSON_DTT761X)) |
779 | goto frontend_detach; | 840 | goto frontend_detach; |
@@ -787,15 +848,15 @@ static int dvb_register(struct cx8802_dev *dev) | |||
787 | mdelay(100); | 848 | mdelay(100); |
788 | cx_set(MO_GP0_IO, 1); | 849 | cx_set(MO_GP0_IO, 1); |
789 | mdelay(200); | 850 | mdelay(200); |
790 | dev->dvb.frontend = dvb_attach(lgdt330x_attach, | 851 | fe0->dvb.frontend = dvb_attach(lgdt330x_attach, |
791 | &fusionhdtv_5_gold, | 852 | &fusionhdtv_5_gold, |
792 | &core->i2c_adap); | 853 | &core->i2c_adap); |
793 | if (dev->dvb.frontend != NULL) { | 854 | if (fe0->dvb.frontend != NULL) { |
794 | if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend, | 855 | if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend, |
795 | &core->i2c_adap, 0x61, | 856 | &core->i2c_adap, 0x61, |
796 | TUNER_LG_TDVS_H06XF)) | 857 | TUNER_LG_TDVS_H06XF)) |
797 | goto frontend_detach; | 858 | goto frontend_detach; |
798 | if (!dvb_attach(tda9887_attach, dev->dvb.frontend, | 859 | if (!dvb_attach(tda9887_attach, fe0->dvb.frontend, |
799 | &core->i2c_adap, 0x43)) | 860 | &core->i2c_adap, 0x43)) |
800 | goto frontend_detach; | 861 | goto frontend_detach; |
801 | } | 862 | } |
@@ -808,25 +869,25 @@ static int dvb_register(struct cx8802_dev *dev) | |||
808 | mdelay(100); | 869 | mdelay(100); |
809 | cx_set(MO_GP0_IO, 1); | 870 | cx_set(MO_GP0_IO, 1); |
810 | mdelay(200); | 871 | mdelay(200); |
811 | dev->dvb.frontend = dvb_attach(lgdt330x_attach, | 872 | fe0->dvb.frontend = dvb_attach(lgdt330x_attach, |
812 | &pchdtv_hd5500, | 873 | &pchdtv_hd5500, |
813 | &core->i2c_adap); | 874 | &core->i2c_adap); |
814 | if (dev->dvb.frontend != NULL) { | 875 | if (fe0->dvb.frontend != NULL) { |
815 | if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend, | 876 | if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend, |
816 | &core->i2c_adap, 0x61, | 877 | &core->i2c_adap, 0x61, |
817 | TUNER_LG_TDVS_H06XF)) | 878 | TUNER_LG_TDVS_H06XF)) |
818 | goto frontend_detach; | 879 | goto frontend_detach; |
819 | if (!dvb_attach(tda9887_attach, dev->dvb.frontend, | 880 | if (!dvb_attach(tda9887_attach, fe0->dvb.frontend, |
820 | &core->i2c_adap, 0x43)) | 881 | &core->i2c_adap, 0x43)) |
821 | goto frontend_detach; | 882 | goto frontend_detach; |
822 | } | 883 | } |
823 | break; | 884 | break; |
824 | case CX88_BOARD_ATI_HDTVWONDER: | 885 | case CX88_BOARD_ATI_HDTVWONDER: |
825 | dev->dvb.frontend = dvb_attach(nxt200x_attach, | 886 | fe0->dvb.frontend = dvb_attach(nxt200x_attach, |
826 | &ati_hdtvwonder, | 887 | &ati_hdtvwonder, |
827 | &core->i2c_adap); | 888 | &core->i2c_adap); |
828 | if (dev->dvb.frontend != NULL) { | 889 | if (fe0->dvb.frontend != NULL) { |
829 | if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend, | 890 | if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend, |
830 | &core->i2c_adap, 0x61, | 891 | &core->i2c_adap, 0x61, |
831 | TUNER_PHILIPS_TUV1236D)) | 892 | TUNER_PHILIPS_TUV1236D)) |
832 | goto frontend_detach; | 893 | goto frontend_detach; |
@@ -834,49 +895,49 @@ static int dvb_register(struct cx8802_dev *dev) | |||
834 | break; | 895 | break; |
835 | case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1: | 896 | case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1: |
836 | case CX88_BOARD_HAUPPAUGE_NOVASE2_S1: | 897 | case CX88_BOARD_HAUPPAUGE_NOVASE2_S1: |
837 | dev->dvb.frontend = dvb_attach(cx24123_attach, | 898 | fe0->dvb.frontend = dvb_attach(cx24123_attach, |
838 | &hauppauge_novas_config, | 899 | &hauppauge_novas_config, |
839 | &core->i2c_adap); | 900 | &core->i2c_adap); |
840 | if (dev->dvb.frontend) { | 901 | if (fe0->dvb.frontend) { |
841 | if (!dvb_attach(isl6421_attach, dev->dvb.frontend, | 902 | if (!dvb_attach(isl6421_attach, fe0->dvb.frontend, |
842 | &core->i2c_adap, 0x08, ISL6421_DCL, 0x00)) | 903 | &core->i2c_adap, 0x08, ISL6421_DCL, 0x00)) |
843 | goto frontend_detach; | 904 | goto frontend_detach; |
844 | } | 905 | } |
845 | break; | 906 | break; |
846 | case CX88_BOARD_KWORLD_DVBS_100: | 907 | case CX88_BOARD_KWORLD_DVBS_100: |
847 | dev->dvb.frontend = dvb_attach(cx24123_attach, | 908 | fe0->dvb.frontend = dvb_attach(cx24123_attach, |
848 | &kworld_dvbs_100_config, | 909 | &kworld_dvbs_100_config, |
849 | &core->i2c_adap); | 910 | &core->i2c_adap); |
850 | if (dev->dvb.frontend) { | 911 | if (fe0->dvb.frontend) { |
851 | core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage; | 912 | core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage; |
852 | dev->dvb.frontend->ops.set_voltage = kworld_dvbs_100_set_voltage; | 913 | fe0->dvb.frontend->ops.set_voltage = kworld_dvbs_100_set_voltage; |
853 | } | 914 | } |
854 | break; | 915 | break; |
855 | case CX88_BOARD_GENIATECH_DVBS: | 916 | case CX88_BOARD_GENIATECH_DVBS: |
856 | dev->dvb.frontend = dvb_attach(cx24123_attach, | 917 | fe0->dvb.frontend = dvb_attach(cx24123_attach, |
857 | &geniatech_dvbs_config, | 918 | &geniatech_dvbs_config, |
858 | &core->i2c_adap); | 919 | &core->i2c_adap); |
859 | if (dev->dvb.frontend) { | 920 | if (fe0->dvb.frontend) { |
860 | core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage; | 921 | core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage; |
861 | dev->dvb.frontend->ops.set_voltage = geniatech_dvbs_set_voltage; | 922 | fe0->dvb.frontend->ops.set_voltage = geniatech_dvbs_set_voltage; |
862 | } | 923 | } |
863 | break; | 924 | break; |
864 | case CX88_BOARD_PINNACLE_PCTV_HD_800i: | 925 | case CX88_BOARD_PINNACLE_PCTV_HD_800i: |
865 | dev->dvb.frontend = dvb_attach(s5h1409_attach, | 926 | fe0->dvb.frontend = dvb_attach(s5h1409_attach, |
866 | &pinnacle_pctv_hd_800i_config, | 927 | &pinnacle_pctv_hd_800i_config, |
867 | &core->i2c_adap); | 928 | &core->i2c_adap); |
868 | if (dev->dvb.frontend != NULL) { | 929 | if (fe0->dvb.frontend != NULL) { |
869 | if (!dvb_attach(xc5000_attach, dev->dvb.frontend, | 930 | if (!dvb_attach(xc5000_attach, fe0->dvb.frontend, |
870 | &core->i2c_adap, | 931 | &core->i2c_adap, |
871 | &pinnacle_pctv_hd_800i_tuner_config)) | 932 | &pinnacle_pctv_hd_800i_tuner_config)) |
872 | goto frontend_detach; | 933 | goto frontend_detach; |
873 | } | 934 | } |
874 | break; | 935 | break; |
875 | case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO: | 936 | case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO: |
876 | dev->dvb.frontend = dvb_attach(s5h1409_attach, | 937 | fe0->dvb.frontend = dvb_attach(s5h1409_attach, |
877 | &dvico_hdtv5_pci_nano_config, | 938 | &dvico_hdtv5_pci_nano_config, |
878 | &core->i2c_adap); | 939 | &core->i2c_adap); |
879 | if (dev->dvb.frontend != NULL) { | 940 | if (fe0->dvb.frontend != NULL) { |
880 | struct dvb_frontend *fe; | 941 | struct dvb_frontend *fe; |
881 | struct xc2028_config cfg = { | 942 | struct xc2028_config cfg = { |
882 | .i2c_adap = &core->i2c_adap, | 943 | .i2c_adap = &core->i2c_adap, |
@@ -889,17 +950,17 @@ static int dvb_register(struct cx8802_dev *dev) | |||
889 | }; | 950 | }; |
890 | 951 | ||
891 | fe = dvb_attach(xc2028_attach, | 952 | fe = dvb_attach(xc2028_attach, |
892 | dev->dvb.frontend, &cfg); | 953 | fe0->dvb.frontend, &cfg); |
893 | if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) | 954 | if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) |
894 | fe->ops.tuner_ops.set_config(fe, &ctl); | 955 | fe->ops.tuner_ops.set_config(fe, &ctl); |
895 | } | 956 | } |
896 | break; | 957 | break; |
897 | case CX88_BOARD_PINNACLE_HYBRID_PCTV: | 958 | case CX88_BOARD_PINNACLE_HYBRID_PCTV: |
898 | dev->dvb.frontend = dvb_attach(zl10353_attach, | 959 | fe0->dvb.frontend = dvb_attach(zl10353_attach, |
899 | &cx88_pinnacle_hybrid_pctv, | 960 | &cx88_pinnacle_hybrid_pctv, |
900 | &core->i2c_adap); | 961 | &core->i2c_adap); |
901 | if (dev->dvb.frontend) { | 962 | if (fe0->dvb.frontend) { |
902 | dev->dvb.frontend->ops.i2c_gate_ctrl = NULL; | 963 | fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL; |
903 | if (attach_xc3028(0x61, dev) < 0) | 964 | if (attach_xc3028(0x61, dev) < 0) |
904 | goto frontend_detach; | 965 | goto frontend_detach; |
905 | } | 966 | } |
@@ -907,85 +968,118 @@ static int dvb_register(struct cx8802_dev *dev) | |||
907 | case CX88_BOARD_GENIATECH_X8000_MT: | 968 | case CX88_BOARD_GENIATECH_X8000_MT: |
908 | dev->ts_gen_cntrl = 0x00; | 969 | dev->ts_gen_cntrl = 0x00; |
909 | 970 | ||
910 | dev->dvb.frontend = dvb_attach(zl10353_attach, | 971 | fe0->dvb.frontend = dvb_attach(zl10353_attach, |
911 | &cx88_geniatech_x8000_mt, | 972 | &cx88_geniatech_x8000_mt, |
912 | &core->i2c_adap); | 973 | &core->i2c_adap); |
913 | if (attach_xc3028(0x61, dev) < 0) | 974 | if (attach_xc3028(0x61, dev) < 0) |
914 | goto frontend_detach; | 975 | goto frontend_detach; |
915 | break; | 976 | break; |
916 | case CX88_BOARD_KWORLD_ATSC_120: | 977 | case CX88_BOARD_KWORLD_ATSC_120: |
917 | dev->dvb.frontend = dvb_attach(s5h1409_attach, | 978 | fe0->dvb.frontend = dvb_attach(s5h1409_attach, |
918 | &kworld_atsc_120_config, | 979 | &kworld_atsc_120_config, |
919 | &core->i2c_adap); | 980 | &core->i2c_adap); |
920 | if (attach_xc3028(0x61, dev) < 0) | 981 | if (attach_xc3028(0x61, dev) < 0) |
921 | goto frontend_detach; | 982 | goto frontend_detach; |
922 | break; | 983 | break; |
923 | case CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD: | 984 | case CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD: |
924 | dev->dvb.frontend = dvb_attach(s5h1411_attach, | 985 | fe0->dvb.frontend = dvb_attach(s5h1411_attach, |
925 | &dvico_fusionhdtv7_config, | 986 | &dvico_fusionhdtv7_config, |
926 | &core->i2c_adap); | 987 | &core->i2c_adap); |
927 | if (dev->dvb.frontend != NULL) { | 988 | if (fe0->dvb.frontend != NULL) { |
928 | if (!dvb_attach(xc5000_attach, dev->dvb.frontend, | 989 | if (!dvb_attach(xc5000_attach, fe0->dvb.frontend, |
929 | &core->i2c_adap, | 990 | &core->i2c_adap, |
930 | &dvico_fusionhdtv7_tuner_config)) | 991 | &dvico_fusionhdtv7_tuner_config)) |
931 | goto frontend_detach; | 992 | goto frontend_detach; |
932 | } | 993 | } |
933 | break; | 994 | break; |
934 | case CX88_BOARD_HAUPPAUGE_HVR4000: | 995 | case CX88_BOARD_HAUPPAUGE_HVR4000: |
996 | /* DVB-S/S2 Init */ | ||
997 | fe0->dvb.frontend = dvb_attach(cx24116_attach, | ||
998 | &hauppauge_hvr4000_config, | ||
999 | &dev->core->i2c_adap); | ||
1000 | if (fe0->dvb.frontend) { | ||
1001 | if(!dvb_attach(isl6421_attach, fe0->dvb.frontend, | ||
1002 | &dev->core->i2c_adap, 0x08, ISL6421_DCL, 0x00)) { | ||
1003 | dprintk( 1, "%s(): HVR4000 - DVB-S LNB Init: failed\n", __func__); | ||
1004 | } | ||
1005 | } else { | ||
1006 | dprintk( 1, "%s(): HVR4000 - DVB-S Init: failed\n", __func__); | ||
1007 | } | ||
1008 | /* DVB-T Init */ | ||
1009 | fe1 = videobuf_dvb_get_frontend(&dev->frontends, 2); | ||
1010 | if (fe1) { | ||
1011 | dev->frontends.gate = 2; | ||
1012 | mfe_shared = 1; | ||
1013 | fe1->dvb.frontend = dvb_attach(cx22702_attach, | ||
1014 | &hauppauge_hvr_config, | ||
1015 | &dev->core->i2c_adap); | ||
1016 | if (fe1->dvb.frontend) { | ||
1017 | fe1->dvb.frontend->id = 1; | ||
1018 | if(!dvb_attach(simple_tuner_attach, fe1->dvb.frontend, | ||
1019 | &dev->core->i2c_adap, 0x61, | ||
1020 | TUNER_PHILIPS_FMD1216ME_MK3)) { | ||
1021 | dprintk( 1, "%s(): HVR4000 - DVB-T misc Init: failed\n", __func__); | ||
1022 | } | ||
1023 | } else { | ||
1024 | dprintk( 1, "%s(): HVR4000 - DVB-T Init: failed\n", __func__); | ||
1025 | } | ||
1026 | } else { | ||
1027 | dprintk( 1, "%s(): HVR4000 - DVB-T Init: can't find frontend 2.\n", __func__); | ||
1028 | } | ||
1029 | break; | ||
935 | case CX88_BOARD_HAUPPAUGE_HVR4000LITE: | 1030 | case CX88_BOARD_HAUPPAUGE_HVR4000LITE: |
936 | /* Support for DVB-S only, not DVB-T support */ | 1031 | fe0->dvb.frontend = dvb_attach(cx24116_attach, |
937 | dev->dvb.frontend = dvb_attach(cx24116_attach, | ||
938 | &hauppauge_hvr4000_config, | 1032 | &hauppauge_hvr4000_config, |
939 | &dev->core->i2c_adap); | 1033 | &dev->core->i2c_adap); |
940 | if (dev->dvb.frontend) { | 1034 | if (fe0->dvb.frontend) { |
941 | dvb_attach(isl6421_attach, dev->dvb.frontend, | 1035 | dvb_attach(isl6421_attach, fe0->dvb.frontend, |
942 | &dev->core->i2c_adap, | 1036 | &dev->core->i2c_adap, |
943 | 0x08, ISL6421_DCL, 0x00); | 1037 | 0x08, ISL6421_DCL, 0x00); |
944 | } | 1038 | } |
945 | break; | 1039 | break; |
946 | case CX88_BOARD_TEVII_S420: | 1040 | case CX88_BOARD_TEVII_S420: |
947 | dev->dvb.frontend = dvb_attach(stv0299_attach, | 1041 | fe0->dvb.frontend = dvb_attach(stv0299_attach, |
948 | &tevii_tuner_sharp_config, | 1042 | &tevii_tuner_sharp_config, |
949 | &core->i2c_adap); | 1043 | &core->i2c_adap); |
950 | if (dev->dvb.frontend != NULL) { | 1044 | if (fe0->dvb.frontend != NULL) { |
951 | if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60, | 1045 | if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 0x60, |
952 | &core->i2c_adap, DVB_PLL_OPERA1)) | 1046 | &core->i2c_adap, DVB_PLL_OPERA1)) |
953 | goto frontend_detach; | 1047 | goto frontend_detach; |
954 | core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage; | 1048 | core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage; |
955 | dev->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage; | 1049 | fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage; |
956 | 1050 | ||
957 | } else { | 1051 | } else { |
958 | dev->dvb.frontend = dvb_attach(stv0288_attach, | 1052 | fe0->dvb.frontend = dvb_attach(stv0288_attach, |
959 | &tevii_tuner_earda_config, | 1053 | &tevii_tuner_earda_config, |
960 | &core->i2c_adap); | 1054 | &core->i2c_adap); |
961 | if (dev->dvb.frontend != NULL) { | 1055 | if (fe0->dvb.frontend != NULL) { |
962 | if (!dvb_attach(stb6000_attach, dev->dvb.frontend, 0x61, | 1056 | if (!dvb_attach(stb6000_attach, fe0->dvb.frontend, 0x61, |
963 | &core->i2c_adap)) | 1057 | &core->i2c_adap)) |
964 | goto frontend_detach; | 1058 | goto frontend_detach; |
965 | core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage; | 1059 | core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage; |
966 | dev->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage; | 1060 | fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage; |
967 | 1061 | ||
968 | } | 1062 | } |
969 | } | 1063 | } |
970 | break; | 1064 | break; |
971 | case CX88_BOARD_TEVII_S460: | 1065 | case CX88_BOARD_TEVII_S460: |
972 | dev->dvb.frontend = dvb_attach(cx24116_attach, | 1066 | fe0->dvb.frontend = dvb_attach(cx24116_attach, |
973 | &tevii_s460_config, | 1067 | &tevii_s460_config, |
974 | &core->i2c_adap); | 1068 | &core->i2c_adap); |
975 | if (dev->dvb.frontend != NULL) { | 1069 | if (fe0->dvb.frontend != NULL) { |
976 | core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage; | 1070 | core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage; |
977 | dev->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage; | 1071 | fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage; |
978 | } | 1072 | } |
979 | break; | 1073 | break; |
980 | case CX88_BOARD_OMICOM_SS4_PCI: | 1074 | case CX88_BOARD_OMICOM_SS4_PCI: |
981 | case CX88_BOARD_TBS_8920: | 1075 | case CX88_BOARD_TBS_8920: |
982 | case CX88_BOARD_PROF_7300: | 1076 | case CX88_BOARD_PROF_7300: |
983 | dev->dvb.frontend = dvb_attach(cx24116_attach, | 1077 | fe0->dvb.frontend = dvb_attach(cx24116_attach, |
984 | &hauppauge_hvr4000_config, | 1078 | &hauppauge_hvr4000_config, |
985 | &core->i2c_adap); | 1079 | &core->i2c_adap); |
986 | if (dev->dvb.frontend != NULL) { | 1080 | if (fe0->dvb.frontend != NULL) { |
987 | core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage; | 1081 | core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage; |
988 | dev->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage; | 1082 | fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage; |
989 | } | 1083 | } |
990 | break; | 1084 | break; |
991 | default: | 1085 | default: |
@@ -993,29 +1087,32 @@ static int dvb_register(struct cx8802_dev *dev) | |||
993 | core->name); | 1087 | core->name); |
994 | break; | 1088 | break; |
995 | } | 1089 | } |
996 | if (NULL == dev->dvb.frontend) { | 1090 | |
1091 | if ( (NULL == fe0->dvb.frontend) || (fe1 && NULL == fe1->dvb.frontend) ) { | ||
997 | printk(KERN_ERR | 1092 | printk(KERN_ERR |
998 | "%s/2: frontend initialization failed\n", | 1093 | "%s/2: frontend initialization failed\n", |
999 | core->name); | 1094 | core->name); |
1000 | return -EINVAL; | 1095 | return -EINVAL; |
1001 | } | 1096 | } |
1002 | /* define general-purpose callback pointer */ | 1097 | /* define general-purpose callback pointer */ |
1003 | dev->dvb.frontend->callback = cx88_tuner_callback; | 1098 | fe0->dvb.frontend->callback = cx88_tuner_callback; |
1004 | 1099 | ||
1005 | /* Ensure all frontends negotiate bus access */ | 1100 | /* Ensure all frontends negotiate bus access */ |
1006 | dev->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl; | 1101 | fe0->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl; |
1102 | if (fe1) | ||
1103 | fe1->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl; | ||
1007 | 1104 | ||
1008 | /* Put the analog decoder in standby to keep it quiet */ | 1105 | /* Put the analog decoder in standby to keep it quiet */ |
1009 | cx88_call_i2c_clients(core, TUNER_SET_STANDBY, NULL); | 1106 | cx88_call_i2c_clients(core, TUNER_SET_STANDBY, NULL); |
1010 | 1107 | ||
1011 | /* register everything */ | 1108 | /* register everything */ |
1012 | return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev, | 1109 | return videobuf_dvb_register_bus(&dev->frontends, THIS_MODULE, dev, |
1013 | &dev->pci->dev, adapter_nr); | 1110 | &dev->pci->dev, adapter_nr, mfe_shared); |
1014 | 1111 | ||
1015 | frontend_detach: | 1112 | frontend_detach: |
1016 | if (dev->dvb.frontend) { | 1113 | if (fe0->dvb.frontend) { |
1017 | dvb_frontend_detach(dev->dvb.frontend); | 1114 | dvb_frontend_detach(fe0->dvb.frontend); |
1018 | dev->dvb.frontend = NULL; | 1115 | fe0->dvb.frontend = NULL; |
1019 | } | 1116 | } |
1020 | return -EINVAL; | 1117 | return -EINVAL; |
1021 | } | 1118 | } |
@@ -1039,6 +1136,38 @@ static int cx8802_dvb_advise_acquire(struct cx8802_driver *drv) | |||
1039 | cx_clear(MO_GP0_IO, 0x00000004); | 1136 | cx_clear(MO_GP0_IO, 0x00000004); |
1040 | udelay(1000); | 1137 | udelay(1000); |
1041 | break; | 1138 | break; |
1139 | |||
1140 | case CX88_BOARD_HAUPPAUGE_HVR3000: | ||
1141 | case CX88_BOARD_HAUPPAUGE_HVR4000: | ||
1142 | if(core->dvbdev->frontends.active_fe_id == 1) { | ||
1143 | /* DVB-S/S2 Enabled */ | ||
1144 | |||
1145 | /* Toggle reset on cx22702 leaving i2c active */ | ||
1146 | cx_write(MO_GP0_IO, (core->board.input[0].gpio0 & 0x0000ff00) | 0x00000080); | ||
1147 | udelay(1000); | ||
1148 | cx_clear(MO_GP0_IO, 0x00000080); | ||
1149 | udelay(50); | ||
1150 | cx_set(MO_GP0_IO, 0x00000080); /* cx22702 out of reset */ | ||
1151 | cx_set(MO_GP0_IO, 0x00000004); /* tri-state the cx22702 pins */ | ||
1152 | udelay(1000); | ||
1153 | |||
1154 | cx_write(MO_SRST_IO, 1); /* Take the cx24116/cx24123 out of reset */ | ||
1155 | core->dvbdev->ts_gen_cntrl = 0x02; /* Parallel IO */ | ||
1156 | } else | ||
1157 | if (core->dvbdev->frontends.active_fe_id == 2) { | ||
1158 | /* DVB-T Enabled */ | ||
1159 | |||
1160 | /* Put the cx24116/cx24123 into reset */ | ||
1161 | cx_write(MO_SRST_IO, 0); | ||
1162 | |||
1163 | /* cx22702 out of reset and enable it */ | ||
1164 | cx_set(MO_GP0_IO, 0x00000080); | ||
1165 | cx_clear(MO_GP0_IO, 0x00000004); | ||
1166 | core->dvbdev->ts_gen_cntrl = 0x0c; /* Serial IO */ | ||
1167 | udelay(1000); | ||
1168 | } | ||
1169 | break; | ||
1170 | |||
1042 | default: | 1171 | default: |
1043 | err = -ENODEV; | 1172 | err = -ENODEV; |
1044 | } | 1173 | } |
@@ -1056,6 +1185,9 @@ static int cx8802_dvb_advise_release(struct cx8802_driver *drv) | |||
1056 | case CX88_BOARD_HAUPPAUGE_HVR1300: | 1185 | case CX88_BOARD_HAUPPAUGE_HVR1300: |
1057 | /* Do Nothing, leave the cx22702 on the bus. */ | 1186 | /* Do Nothing, leave the cx22702 on the bus. */ |
1058 | break; | 1187 | break; |
1188 | case CX88_BOARD_HAUPPAUGE_HVR3000: | ||
1189 | case CX88_BOARD_HAUPPAUGE_HVR4000: | ||
1190 | break; | ||
1059 | default: | 1191 | default: |
1060 | err = -ENODEV; | 1192 | err = -ENODEV; |
1061 | } | 1193 | } |
@@ -1066,7 +1198,8 @@ static int cx8802_dvb_probe(struct cx8802_driver *drv) | |||
1066 | { | 1198 | { |
1067 | struct cx88_core *core = drv->core; | 1199 | struct cx88_core *core = drv->core; |
1068 | struct cx8802_dev *dev = drv->core->dvbdev; | 1200 | struct cx8802_dev *dev = drv->core->dvbdev; |
1069 | int err; | 1201 | int err, i; |
1202 | struct videobuf_dvb_frontend *fe; | ||
1070 | 1203 | ||
1071 | dprintk( 1, "%s\n", __func__); | 1204 | dprintk( 1, "%s\n", __func__); |
1072 | dprintk( 1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n", | 1205 | dprintk( 1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n", |
@@ -1086,18 +1219,28 @@ static int cx8802_dvb_probe(struct cx8802_driver *drv) | |||
1086 | 1219 | ||
1087 | /* dvb stuff */ | 1220 | /* dvb stuff */ |
1088 | printk(KERN_INFO "%s/2: cx2388x based DVB/ATSC card\n", core->name); | 1221 | printk(KERN_INFO "%s/2: cx2388x based DVB/ATSC card\n", core->name); |
1089 | videobuf_queue_sg_init(&dev->dvb.dvbq, &dvb_qops, | 1222 | dev->ts_gen_cntrl = 0x0c; |
1223 | |||
1224 | for (i = 1; i <= core->board.num_frontends; i++) { | ||
1225 | fe = videobuf_dvb_get_frontend(&core->dvbdev->frontends, i); | ||
1226 | if (!fe) { | ||
1227 | printk(KERN_ERR "%s() failed to get frontend(%d)\n", __func__, i); | ||
1228 | continue; | ||
1229 | } | ||
1230 | videobuf_queue_sg_init(&fe->dvb.dvbq, &dvb_qops, | ||
1090 | &dev->pci->dev, &dev->slock, | 1231 | &dev->pci->dev, &dev->slock, |
1091 | V4L2_BUF_TYPE_VIDEO_CAPTURE, | 1232 | V4L2_BUF_TYPE_VIDEO_CAPTURE, |
1092 | V4L2_FIELD_TOP, | 1233 | V4L2_FIELD_TOP, |
1093 | sizeof(struct cx88_buffer), | 1234 | sizeof(struct cx88_buffer), |
1094 | dev); | 1235 | dev); |
1236 | /* init struct videobuf_dvb */ | ||
1237 | fe->dvb.name = dev->core->name; | ||
1238 | } | ||
1095 | err = dvb_register(dev); | 1239 | err = dvb_register(dev); |
1096 | if (err != 0) | 1240 | if (err != 0) |
1097 | printk(KERN_ERR "%s/2: dvb_register failed (err = %d)\n", | 1241 | printk(KERN_ERR "%s/2: dvb_register failed (err = %d)\n", |
1098 | core->name, err); | 1242 | core->name, err); |
1099 | 1243 | fail_core: | |
1100 | fail_core: | ||
1101 | return err; | 1244 | return err; |
1102 | } | 1245 | } |
1103 | 1246 | ||
@@ -1105,9 +1248,7 @@ static int cx8802_dvb_remove(struct cx8802_driver *drv) | |||
1105 | { | 1248 | { |
1106 | struct cx8802_dev *dev = drv->core->dvbdev; | 1249 | struct cx8802_dev *dev = drv->core->dvbdev; |
1107 | 1250 | ||
1108 | /* dvb */ | 1251 | videobuf_dvb_unregister_bus(&dev->frontends); |
1109 | if (dev->dvb.frontend) | ||
1110 | videobuf_dvb_unregister(&dev->dvb); | ||
1111 | 1252 | ||
1112 | vp3054_i2c_remove(dev); | 1253 | vp3054_i2c_remove(dev); |
1113 | 1254 | ||
diff --git a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c index 8e74d64fdcd2..01de23007095 100644 --- a/drivers/media/video/cx88/cx88-i2c.c +++ b/drivers/media/video/cx88/cx88-i2c.c | |||
@@ -116,18 +116,25 @@ static int detach_inform(struct i2c_client *client) | |||
116 | 116 | ||
117 | void cx88_call_i2c_clients(struct cx88_core *core, unsigned int cmd, void *arg) | 117 | void cx88_call_i2c_clients(struct cx88_core *core, unsigned int cmd, void *arg) |
118 | { | 118 | { |
119 | struct videobuf_dvb_frontends *f = &core->dvbdev->frontends; | ||
120 | struct videobuf_dvb_frontend *fe = NULL; | ||
119 | if (0 != core->i2c_rc) | 121 | if (0 != core->i2c_rc) |
120 | return; | 122 | return; |
121 | 123 | ||
122 | #if defined(CONFIG_VIDEO_CX88_DVB) || defined(CONFIG_VIDEO_CX88_DVB_MODULE) | 124 | #if defined(CONFIG_VIDEO_CX88_DVB) || defined(CONFIG_VIDEO_CX88_DVB_MODULE) |
123 | if ( (core->dvbdev) && (core->dvbdev->dvb.frontend) ) { | 125 | if (core->dvbdev && f) { |
124 | if (core->dvbdev->dvb.frontend->ops.i2c_gate_ctrl) | 126 | if(f->gate <= 1) /* undefined or fe0 */ |
125 | core->dvbdev->dvb.frontend->ops.i2c_gate_ctrl(core->dvbdev->dvb.frontend, 1); | 127 | fe = videobuf_dvb_get_frontend(f, 1); |
128 | else | ||
129 | fe = videobuf_dvb_get_frontend(f, f->gate); | ||
130 | |||
131 | if (fe && fe->dvb.frontend && fe->dvb.frontend->ops.i2c_gate_ctrl) | ||
132 | fe->dvb.frontend->ops.i2c_gate_ctrl(fe->dvb.frontend, 1); | ||
126 | 133 | ||
127 | i2c_clients_command(&core->i2c_adap, cmd, arg); | 134 | i2c_clients_command(&core->i2c_adap, cmd, arg); |
128 | 135 | ||
129 | if (core->dvbdev->dvb.frontend->ops.i2c_gate_ctrl) | 136 | if (fe && fe->dvb.frontend && fe->dvb.frontend->ops.i2c_gate_ctrl) |
130 | core->dvbdev->dvb.frontend->ops.i2c_gate_ctrl(core->dvbdev->dvb.frontend, 0); | 137 | fe->dvb.frontend->ops.i2c_gate_ctrl(fe->dvb.frontend, 0); |
131 | } else | 138 | } else |
132 | #endif | 139 | #endif |
133 | i2c_clients_command(&core->i2c_adap, cmd, arg); | 140 | i2c_clients_command(&core->i2c_adap, cmd, arg); |
diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c index a6b061c2644a..6df5cf314186 100644 --- a/drivers/media/video/cx88/cx88-mpeg.c +++ b/drivers/media/video/cx88/cx88-mpeg.c | |||
@@ -768,7 +768,8 @@ static int __devinit cx8802_probe(struct pci_dev *pci_dev, | |||
768 | { | 768 | { |
769 | struct cx8802_dev *dev; | 769 | struct cx8802_dev *dev; |
770 | struct cx88_core *core; | 770 | struct cx88_core *core; |
771 | int err; | 771 | struct videobuf_dvb_frontend *demod; |
772 | int err,i; | ||
772 | 773 | ||
773 | /* general setup */ | 774 | /* general setup */ |
774 | core = cx88_core_get(pci_dev); | 775 | core = cx88_core_get(pci_dev); |
@@ -781,6 +782,11 @@ static int __devinit cx8802_probe(struct pci_dev *pci_dev, | |||
781 | if (!core->board.mpeg) | 782 | if (!core->board.mpeg) |
782 | goto fail_core; | 783 | goto fail_core; |
783 | 784 | ||
785 | if (!core->board.num_frontends) { | ||
786 | printk(KERN_ERR "%s() .num_frontends should be non-zero, err = %d\n", __func__, err); | ||
787 | goto fail_core; | ||
788 | } | ||
789 | |||
784 | err = -ENOMEM; | 790 | err = -ENOMEM; |
785 | dev = kzalloc(sizeof(*dev),GFP_KERNEL); | 791 | dev = kzalloc(sizeof(*dev),GFP_KERNEL); |
786 | if (NULL == dev) | 792 | if (NULL == dev) |
@@ -795,6 +801,20 @@ static int __devinit cx8802_probe(struct pci_dev *pci_dev, | |||
795 | INIT_LIST_HEAD(&dev->drvlist); | 801 | INIT_LIST_HEAD(&dev->drvlist); |
796 | list_add_tail(&dev->devlist,&cx8802_devlist); | 802 | list_add_tail(&dev->devlist,&cx8802_devlist); |
797 | 803 | ||
804 | mutex_init(&dev->frontends.lock); | ||
805 | INIT_LIST_HEAD(&dev->frontends.felist); | ||
806 | |||
807 | printk(KERN_INFO "%s() allocating %d frontend(s)\n", __func__, core->board.num_frontends); | ||
808 | |||
809 | for (i = 1; i <= core->board.num_frontends; i++) { | ||
810 | demod = videobuf_dvb_alloc_frontend(&dev->frontends, i); | ||
811 | if(demod == NULL) { | ||
812 | printk(KERN_ERR "%s() failed to alloc\n", __func__); | ||
813 | err = -ENOMEM; | ||
814 | goto fail_free; | ||
815 | } | ||
816 | } | ||
817 | |||
798 | /* Maintain a reference so cx88-video can query the 8802 device. */ | 818 | /* Maintain a reference so cx88-video can query the 8802 device. */ |
799 | core->dvbdev = dev; | 819 | core->dvbdev = dev; |
800 | 820 | ||
diff --git a/drivers/media/video/cx88/cx88-tvaudio.c b/drivers/media/video/cx88/cx88-tvaudio.c index 3a1977f41e27..7dd506b987fe 100644 --- a/drivers/media/video/cx88/cx88-tvaudio.c +++ b/drivers/media/video/cx88/cx88-tvaudio.c | |||
@@ -767,6 +767,14 @@ void cx88_set_tvaudio(struct cx88_core *core) | |||
767 | case WW_FM: | 767 | case WW_FM: |
768 | set_audio_standard_FM(core, radio_deemphasis); | 768 | set_audio_standard_FM(core, radio_deemphasis); |
769 | break; | 769 | break; |
770 | case WW_I2SADC: | ||
771 | set_audio_start(core, 0x01); | ||
772 | /* Slave/Philips/Autobaud */ | ||
773 | cx_write(AUD_I2SINPUTCNTL, 0); | ||
774 | /* Switch to "I2S ADC mode" */ | ||
775 | cx_write(AUD_I2SCNTL, 0x1); | ||
776 | set_audio_finish(core, EN_I2SIN_ENABLE); | ||
777 | break; | ||
770 | case WW_NONE: | 778 | case WW_NONE: |
771 | default: | 779 | default: |
772 | printk("%s/0: unknown tv audio mode [%d]\n", | 780 | printk("%s/0: unknown tv audio mode [%d]\n", |
@@ -895,6 +903,9 @@ void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual) | |||
895 | break; | 903 | break; |
896 | } | 904 | } |
897 | break; | 905 | break; |
906 | case WW_I2SADC: | ||
907 | /* DO NOTHING */ | ||
908 | break; | ||
898 | } | 909 | } |
899 | 910 | ||
900 | if (UNSET != ctl) { | 911 | if (UNSET != ctl) { |
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c index be45955dff68..3904b73f52ee 100644 --- a/drivers/media/video/cx88/cx88-video.c +++ b/drivers/media/video/cx88/cx88-video.c | |||
@@ -426,24 +426,7 @@ int cx88_video_mux(struct cx88_core *core, unsigned int input) | |||
426 | 426 | ||
427 | /* if there are audioroutes defined, we have an external | 427 | /* if there are audioroutes defined, we have an external |
428 | ADC to deal with audio */ | 428 | ADC to deal with audio */ |
429 | |||
430 | if (INPUT(input).audioroute) { | 429 | if (INPUT(input).audioroute) { |
431 | |||
432 | /* cx2388's C-ADC is connected to the tuner only. | ||
433 | When used with S-Video, that ADC is busy dealing with | ||
434 | chroma, so an external must be used for baseband audio */ | ||
435 | |||
436 | if (INPUT(input).type != CX88_VMUX_TELEVISION && | ||
437 | INPUT(input).type != CX88_RADIO) { | ||
438 | /* "ADC mode" */ | ||
439 | cx_write(AUD_I2SCNTL, 0x1); | ||
440 | cx_set(AUD_CTL, EN_I2SIN_ENABLE); | ||
441 | } else { | ||
442 | /* Normal mode */ | ||
443 | cx_write(AUD_I2SCNTL, 0x0); | ||
444 | cx_clear(AUD_CTL, EN_I2SIN_ENABLE); | ||
445 | } | ||
446 | |||
447 | /* The wm8775 module has the "2" route hardwired into | 430 | /* The wm8775 module has the "2" route hardwired into |
448 | the initialization. Some boards may use different | 431 | the initialization. Some boards may use different |
449 | routes for different inputs. HVR-1300 surely does */ | 432 | routes for different inputs. HVR-1300 surely does */ |
@@ -454,9 +437,19 @@ int cx88_video_mux(struct cx88_core *core, unsigned int input) | |||
454 | route.input = INPUT(input).audioroute; | 437 | route.input = INPUT(input).audioroute; |
455 | cx88_call_i2c_clients(core, | 438 | cx88_call_i2c_clients(core, |
456 | VIDIOC_INT_S_AUDIO_ROUTING, &route); | 439 | VIDIOC_INT_S_AUDIO_ROUTING, &route); |
457 | |||
458 | } | 440 | } |
459 | 441 | /* cx2388's C-ADC is connected to the tuner only. | |
442 | When used with S-Video, that ADC is busy dealing with | ||
443 | chroma, so an external must be used for baseband audio */ | ||
444 | if (INPUT(input).type != CX88_VMUX_TELEVISION ) { | ||
445 | /* "I2S ADC mode" */ | ||
446 | core->tvaudio = WW_I2SADC; | ||
447 | cx88_set_tvaudio(core); | ||
448 | } else { | ||
449 | /* Normal mode */ | ||
450 | cx_write(AUD_I2SCNTL, 0x0); | ||
451 | cx_clear(AUD_CTL, EN_I2SIN_ENABLE); | ||
452 | } | ||
460 | } | 453 | } |
461 | 454 | ||
462 | return 0; | 455 | return 0; |
@@ -832,9 +825,24 @@ static int video_open(struct inode *inode, struct file *file) | |||
832 | cx_write(MO_GP0_IO, core->board.radio.gpio0); | 825 | cx_write(MO_GP0_IO, core->board.radio.gpio0); |
833 | cx_write(MO_GP1_IO, core->board.radio.gpio1); | 826 | cx_write(MO_GP1_IO, core->board.radio.gpio1); |
834 | cx_write(MO_GP2_IO, core->board.radio.gpio2); | 827 | cx_write(MO_GP2_IO, core->board.radio.gpio2); |
835 | core->tvaudio = WW_FM; | 828 | if (core->board.radio.audioroute) { |
836 | cx88_set_tvaudio(core); | 829 | if(core->board.audio_chip && |
837 | cx88_set_stereo(core,V4L2_TUNER_MODE_STEREO,1); | 830 | core->board.audio_chip == V4L2_IDENT_WM8775) { |
831 | struct v4l2_routing route; | ||
832 | |||
833 | route.input = core->board.radio.audioroute; | ||
834 | cx88_call_i2c_clients(core, | ||
835 | VIDIOC_INT_S_AUDIO_ROUTING, &route); | ||
836 | } | ||
837 | /* "I2S ADC mode" */ | ||
838 | core->tvaudio = WW_I2SADC; | ||
839 | cx88_set_tvaudio(core); | ||
840 | } else { | ||
841 | /* FM Mode */ | ||
842 | core->tvaudio = WW_FM; | ||
843 | cx88_set_tvaudio(core); | ||
844 | cx88_set_stereo(core,V4L2_TUNER_MODE_STEREO,1); | ||
845 | } | ||
838 | cx88_call_i2c_clients(core,AUDC_SET_RADIO,NULL); | 846 | cx88_call_i2c_clients(core,AUDC_SET_RADIO,NULL); |
839 | } | 847 | } |
840 | unlock_kernel(); | 848 | unlock_kernel(); |
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h index dbf01b8b57a5..76207c2856b7 100644 --- a/drivers/media/video/cx88/cx88.h +++ b/drivers/media/video/cx88/cx88.h | |||
@@ -247,7 +247,7 @@ struct cx88_input { | |||
247 | enum cx88_itype type; | 247 | enum cx88_itype type; |
248 | u32 gpio0, gpio1, gpio2, gpio3; | 248 | u32 gpio0, gpio1, gpio2, gpio3; |
249 | unsigned int vmux:2; | 249 | unsigned int vmux:2; |
250 | unsigned int audioroute:2; | 250 | unsigned int audioroute:4; |
251 | }; | 251 | }; |
252 | 252 | ||
253 | struct cx88_board { | 253 | struct cx88_board { |
@@ -261,6 +261,7 @@ struct cx88_board { | |||
261 | struct cx88_input radio; | 261 | struct cx88_input radio; |
262 | enum cx88_board_type mpeg; | 262 | enum cx88_board_type mpeg; |
263 | unsigned int audio_chip; | 263 | unsigned int audio_chip; |
264 | int num_frontends; | ||
264 | }; | 265 | }; |
265 | 266 | ||
266 | struct cx88_subid { | 267 | struct cx88_subid { |
@@ -356,6 +357,7 @@ struct cx88_core { | |||
356 | struct cx8802_dev *dvbdev; | 357 | struct cx8802_dev *dvbdev; |
357 | enum cx88_board_type active_type_id; | 358 | enum cx88_board_type active_type_id; |
358 | int active_ref; | 359 | int active_ref; |
360 | int active_fe_id; | ||
359 | }; | 361 | }; |
360 | 362 | ||
361 | struct cx8800_dev; | 363 | struct cx8800_dev; |
@@ -490,7 +492,7 @@ struct cx8802_dev { | |||
490 | 492 | ||
491 | #if defined(CONFIG_VIDEO_CX88_DVB) || defined(CONFIG_VIDEO_CX88_DVB_MODULE) | 493 | #if defined(CONFIG_VIDEO_CX88_DVB) || defined(CONFIG_VIDEO_CX88_DVB_MODULE) |
492 | /* for dvb only */ | 494 | /* for dvb only */ |
493 | struct videobuf_dvb dvb; | 495 | struct videobuf_dvb_frontends frontends; |
494 | #endif | 496 | #endif |
495 | 497 | ||
496 | #if defined(CONFIG_VIDEO_CX88_VP3054) || \ | 498 | #if defined(CONFIG_VIDEO_CX88_VP3054) || \ |
@@ -628,6 +630,7 @@ extern void cx88_setup_xc3028(struct cx88_core *core, struct xc2028_ctrl *ctl); | |||
628 | #define WW_EIAJ 7 | 630 | #define WW_EIAJ 7 |
629 | #define WW_I2SPT 8 | 631 | #define WW_I2SPT 8 |
630 | #define WW_FM 9 | 632 | #define WW_FM 9 |
633 | #define WW_I2SADC 10 | ||
631 | 634 | ||
632 | void cx88_set_tvaudio(struct cx88_core *core); | 635 | void cx88_set_tvaudio(struct cx88_core *core); |
633 | void cx88_newstation(struct cx88_core *core); | 636 | void cx88_newstation(struct cx88_core *core); |
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index c21af312ee7c..e48fbfc8ad05 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #define MODULE_NAME "gspca" | 21 | #define MODULE_NAME "gspca" |
22 | 22 | ||
23 | #include <linux/init.h> | 23 | #include <linux/init.h> |
24 | #include <linux/version.h> | ||
24 | #include <linux/fs.h> | 25 | #include <linux/fs.h> |
25 | #include <linux/vmalloc.h> | 26 | #include <linux/vmalloc.h> |
26 | #include <linux/sched.h> | 27 | #include <linux/sched.h> |
@@ -403,7 +404,7 @@ static void destroy_urbs(struct gspca_dev *gspca_dev) | |||
403 | unsigned int i; | 404 | unsigned int i; |
404 | 405 | ||
405 | PDEBUG(D_STREAM, "kill transfer"); | 406 | PDEBUG(D_STREAM, "kill transfer"); |
406 | for (i = 0; i < MAX_NURBS; ++i) { | 407 | for (i = 0; i < MAX_NURBS; i++) { |
407 | urb = gspca_dev->urb[i]; | 408 | urb = gspca_dev->urb[i]; |
408 | if (urb == NULL) | 409 | if (urb == NULL) |
409 | break; | 410 | break; |
diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h index 4779dd0b06da..1d9dc90b4791 100644 --- a/drivers/media/video/gspca/gspca.h +++ b/drivers/media/video/gspca/gspca.h | |||
@@ -2,7 +2,6 @@ | |||
2 | #define GSPCAV2_H | 2 | #define GSPCAV2_H |
3 | 3 | ||
4 | #include <linux/module.h> | 4 | #include <linux/module.h> |
5 | #include <linux/version.h> | ||
6 | #include <linux/kernel.h> | 5 | #include <linux/kernel.h> |
7 | #include <linux/usb.h> | 6 | #include <linux/usb.h> |
8 | #include <linux/videodev2.h> | 7 | #include <linux/videodev2.h> |
diff --git a/drivers/media/video/gspca/m5602/m5602_bridge.h b/drivers/media/video/gspca/m5602/m5602_bridge.h index c786d7d3d44a..1a37ae4bc82d 100644 --- a/drivers/media/video/gspca/m5602/m5602_bridge.h +++ b/drivers/media/video/gspca/m5602/m5602_bridge.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * USB Driver for ALi m5602 based webcams | 2 | * USB Driver for ALi m5602 based webcams |
3 | * | 3 | * |
4 | * Copyright (C) 2008 Erik Andren | 4 | * Copyright (C) 2008 Erik Andrén |
5 | * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. | 5 | * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. |
6 | * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br> | 6 | * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br> |
7 | * | 7 | * |
@@ -25,33 +25,6 @@ | |||
25 | 25 | ||
26 | /*****************************************************************************/ | 26 | /*****************************************************************************/ |
27 | 27 | ||
28 | #undef PDEBUG | ||
29 | #undef info | ||
30 | #undef err | ||
31 | |||
32 | #define err(format, arg...) printk(KERN_ERR KBUILD_MODNAME ": " \ | ||
33 | format "\n" , ## arg) | ||
34 | #define info(format, arg...) printk(KERN_INFO KBUILD_MODNAME ": " \ | ||
35 | format "\n" , ## arg) | ||
36 | |||
37 | /* Debug parameters */ | ||
38 | #define DBG_INIT 0x1 | ||
39 | #define DBG_PROBE 0x2 | ||
40 | #define DBG_V4L2 0x4 | ||
41 | #define DBG_TRACE 0x8 | ||
42 | #define DBG_DATA 0x10 | ||
43 | #define DBG_V4L2_CID 0x20 | ||
44 | #define DBG_GSPCA 0x40 | ||
45 | |||
46 | #define PDEBUG(level, fmt, args...) \ | ||
47 | do { \ | ||
48 | if (m5602_debug & level) \ | ||
49 | info("[%s:%d] " fmt, __func__, __LINE__ , \ | ||
50 | ## args); \ | ||
51 | } while (0) | ||
52 | |||
53 | /*****************************************************************************/ | ||
54 | |||
55 | #define M5602_XB_SENSOR_TYPE 0x00 | 28 | #define M5602_XB_SENSOR_TYPE 0x00 |
56 | #define M5602_XB_SENSOR_CTRL 0x01 | 29 | #define M5602_XB_SENSOR_CTRL 0x01 |
57 | #define M5602_XB_LINE_OF_FRAME_H 0x02 | 30 | #define M5602_XB_LINE_OF_FRAME_H 0x02 |
diff --git a/drivers/media/video/gspca/m5602/m5602_core.c b/drivers/media/video/gspca/m5602/m5602_core.c index 19d5e351ccc1..fd6ce384b487 100644 --- a/drivers/media/video/gspca/m5602/m5602_core.c +++ b/drivers/media/video/gspca/m5602/m5602_core.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * USB Driver for ALi m5602 based webcams | 2 | * USB Driver for ALi m5602 based webcams |
3 | * | 3 | * |
4 | * Copyright (C) 2008 Erik Andren | 4 | * Copyright (C) 2008 Erik Andrén |
5 | * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. | 5 | * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. |
6 | * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br> | 6 | * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br> |
7 | * | 7 | * |
@@ -26,7 +26,6 @@ | |||
26 | int force_sensor; | 26 | int force_sensor; |
27 | int dump_bridge; | 27 | int dump_bridge; |
28 | int dump_sensor; | 28 | int dump_sensor; |
29 | unsigned int m5602_debug; | ||
30 | 29 | ||
31 | static const __devinitdata struct usb_device_id m5602_table[] = { | 30 | static const __devinitdata struct usb_device_id m5602_table[] = { |
32 | {USB_DEVICE(0x0402, 0x5602)}, | 31 | {USB_DEVICE(0x0402, 0x5602)}, |
@@ -48,7 +47,7 @@ int m5602_read_bridge(struct sd *sd, u8 address, u8 *i2c_data) | |||
48 | 1, M5602_URB_MSG_TIMEOUT); | 47 | 1, M5602_URB_MSG_TIMEOUT); |
49 | *i2c_data = buf[0]; | 48 | *i2c_data = buf[0]; |
50 | 49 | ||
51 | PDEBUG(DBG_TRACE, "Reading bridge register 0x%x containing 0x%x", | 50 | PDEBUG(D_CONF, "Reading bridge register 0x%x containing 0x%x", |
52 | address, *i2c_data); | 51 | address, *i2c_data); |
53 | 52 | ||
54 | /* usb_control_msg(...) returns the number of bytes sent upon success, | 53 | /* usb_control_msg(...) returns the number of bytes sent upon success, |
@@ -63,7 +62,7 @@ int m5602_write_bridge(struct sd *sd, u8 address, u8 i2c_data) | |||
63 | struct usb_device *udev = sd->gspca_dev.dev; | 62 | struct usb_device *udev = sd->gspca_dev.dev; |
64 | __u8 *buf = sd->gspca_dev.usb_buf; | 63 | __u8 *buf = sd->gspca_dev.usb_buf; |
65 | 64 | ||
66 | PDEBUG(DBG_TRACE, "Writing bridge register 0x%x with 0x%x", | 65 | PDEBUG(D_CONF, "Writing bridge register 0x%x with 0x%x", |
67 | address, i2c_data); | 66 | address, i2c_data); |
68 | 67 | ||
69 | memcpy(buf, bridge_urb_skeleton, | 68 | memcpy(buf, bridge_urb_skeleton, |
@@ -91,7 +90,8 @@ static void m5602_dump_bridge(struct sd *sd) | |||
91 | m5602_read_bridge(sd, i, &val); | 90 | m5602_read_bridge(sd, i, &val); |
92 | info("ALi m5602 address 0x%x contains 0x%x", i, val); | 91 | info("ALi m5602 address 0x%x contains 0x%x", i, val); |
93 | } | 92 | } |
94 | info("Warning: The camera probably won't work until it's power cycled"); | 93 | info("Warning: The ALi m5602 webcam probably won't work " |
94 | "until it's power cycled"); | ||
95 | } | 95 | } |
96 | 96 | ||
97 | static int m5602_probe_sensor(struct sd *sd) | 97 | static int m5602_probe_sensor(struct sd *sd) |
@@ -135,7 +135,7 @@ static int m5602_init(struct gspca_dev *gspca_dev) | |||
135 | struct sd *sd = (struct sd *) gspca_dev; | 135 | struct sd *sd = (struct sd *) gspca_dev; |
136 | int err; | 136 | int err; |
137 | 137 | ||
138 | PDEBUG(DBG_TRACE, "Initializing ALi m5602 webcam"); | 138 | PDEBUG(D_CONF, "Initializing ALi m5602 webcam"); |
139 | /* Run the init sequence */ | 139 | /* Run the init sequence */ |
140 | err = sd->sensor->init(sd); | 140 | err = sd->sensor->init(sd); |
141 | 141 | ||
@@ -146,16 +146,18 @@ static int m5602_start_transfer(struct gspca_dev *gspca_dev) | |||
146 | { | 146 | { |
147 | struct sd *sd = (struct sd *) gspca_dev; | 147 | struct sd *sd = (struct sd *) gspca_dev; |
148 | __u8 *buf = sd->gspca_dev.usb_buf; | 148 | __u8 *buf = sd->gspca_dev.usb_buf; |
149 | int err; | ||
149 | 150 | ||
150 | /* Send start command to the camera */ | 151 | /* Send start command to the camera */ |
151 | const u8 buffer[4] = {0x13, 0xf9, 0x0f, 0x01}; | 152 | const u8 buffer[4] = {0x13, 0xf9, 0x0f, 0x01}; |
152 | memcpy(buf, buffer, sizeof(buffer)); | 153 | memcpy(buf, buffer, sizeof(buffer)); |
153 | usb_control_msg(gspca_dev->dev, usb_sndctrlpipe(gspca_dev->dev, 0), | 154 | err = usb_control_msg(gspca_dev->dev, |
154 | 0x04, 0x40, 0x19, 0x0000, buf, | 155 | usb_sndctrlpipe(gspca_dev->dev, 0), |
155 | 4, M5602_URB_MSG_TIMEOUT); | 156 | 0x04, 0x40, 0x19, 0x0000, buf, |
157 | 4, M5602_URB_MSG_TIMEOUT); | ||
156 | 158 | ||
157 | PDEBUG(DBG_V4L2, "Transfer started"); | 159 | PDEBUG(D_STREAM, "Transfer started"); |
158 | return 0; | 160 | return (err < 0) ? err : 0; |
159 | } | 161 | } |
160 | 162 | ||
161 | static void m5602_urb_complete(struct gspca_dev *gspca_dev, | 163 | static void m5602_urb_complete(struct gspca_dev *gspca_dev, |
@@ -165,14 +167,14 @@ static void m5602_urb_complete(struct gspca_dev *gspca_dev, | |||
165 | struct sd *sd = (struct sd *) gspca_dev; | 167 | struct sd *sd = (struct sd *) gspca_dev; |
166 | 168 | ||
167 | if (len < 6) { | 169 | if (len < 6) { |
168 | PDEBUG(DBG_DATA, "Packet is less than 6 bytes"); | 170 | PDEBUG(D_PACK, "Packet is less than 6 bytes"); |
169 | return; | 171 | return; |
170 | } | 172 | } |
171 | 173 | ||
172 | /* Frame delimiter: ff xx xx xx ff ff */ | 174 | /* Frame delimiter: ff xx xx xx ff ff */ |
173 | if (data[0] == 0xff && data[4] == 0xff && data[5] == 0xff && | 175 | if (data[0] == 0xff && data[4] == 0xff && data[5] == 0xff && |
174 | data[2] != sd->frame_id) { | 176 | data[2] != sd->frame_id) { |
175 | PDEBUG(DBG_DATA, "Frame delimiter detected"); | 177 | PDEBUG(D_FRAM, "Frame delimiter detected"); |
176 | sd->frame_id = data[2]; | 178 | sd->frame_id = data[2]; |
177 | 179 | ||
178 | /* Remove the extra fluff appended on each header */ | 180 | /* Remove the extra fluff appended on each header */ |
@@ -187,7 +189,7 @@ static void m5602_urb_complete(struct gspca_dev *gspca_dev, | |||
187 | /* Create a new frame */ | 189 | /* Create a new frame */ |
188 | gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len); | 190 | gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len); |
189 | 191 | ||
190 | PDEBUG(DBG_V4L2, "Starting new frame %d", | 192 | PDEBUG(D_FRAM, "Starting new frame %d", |
191 | sd->frame_count); | 193 | sd->frame_count); |
192 | 194 | ||
193 | } else { | 195 | } else { |
@@ -198,7 +200,7 @@ static void m5602_urb_complete(struct gspca_dev *gspca_dev, | |||
198 | len -= 4; | 200 | len -= 4; |
199 | 201 | ||
200 | if (cur_frame_len + len <= frame->v4l2_buf.length) { | 202 | if (cur_frame_len + len <= frame->v4l2_buf.length) { |
201 | PDEBUG(DBG_DATA, "Continuing frame %d copying %d bytes", | 203 | PDEBUG(D_FRAM, "Continuing frame %d copying %d bytes", |
202 | sd->frame_count, len); | 204 | sd->frame_count, len); |
203 | 205 | ||
204 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, | 206 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, |
@@ -234,8 +236,6 @@ static int m5602_configure(struct gspca_dev *gspca_dev, | |||
234 | struct cam *cam; | 236 | struct cam *cam; |
235 | int err; | 237 | int err; |
236 | 238 | ||
237 | PDEBUG(DBG_GSPCA, "m5602_configure start"); | ||
238 | |||
239 | cam = &gspca_dev->cam; | 239 | cam = &gspca_dev->cam; |
240 | cam->epaddr = M5602_ISOC_ENDPOINT_ADDR; | 240 | cam->epaddr = M5602_ISOC_ENDPOINT_ADDR; |
241 | sd->desc = &sd_desc; | 241 | sd->desc = &sd_desc; |
@@ -248,11 +248,10 @@ static int m5602_configure(struct gspca_dev *gspca_dev, | |||
248 | if (err) | 248 | if (err) |
249 | goto fail; | 249 | goto fail; |
250 | 250 | ||
251 | PDEBUG(DBG_GSPCA, "m5602_configure end"); | ||
252 | return 0; | 251 | return 0; |
253 | 252 | ||
254 | fail: | 253 | fail: |
255 | PDEBUG(DBG_GSPCA, "m5602_configure failed"); | 254 | PDEBUG(D_ERR, "ALi m5602 webcam failed"); |
256 | cam->cam_mode = NULL; | 255 | cam->cam_mode = NULL; |
257 | cam->nmodes = 0; | 256 | cam->nmodes = 0; |
258 | 257 | ||
@@ -282,13 +281,13 @@ static int __init mod_m5602_init(void) | |||
282 | { | 281 | { |
283 | if (usb_register(&sd_driver) < 0) | 282 | if (usb_register(&sd_driver) < 0) |
284 | return -1; | 283 | return -1; |
285 | PDEBUG(D_PROBE, "m5602 module registered"); | 284 | PDEBUG(D_PROBE, "registered"); |
286 | return 0; | 285 | return 0; |
287 | } | 286 | } |
288 | static void __exit mod_m5602_exit(void) | 287 | static void __exit mod_m5602_exit(void) |
289 | { | 288 | { |
290 | usb_deregister(&sd_driver); | 289 | usb_deregister(&sd_driver); |
291 | PDEBUG(D_PROBE, "m5602 module deregistered"); | 290 | PDEBUG(D_PROBE, "deregistered"); |
292 | } | 291 | } |
293 | 292 | ||
294 | module_init(mod_m5602_init); | 293 | module_init(mod_m5602_init); |
@@ -297,9 +296,6 @@ module_exit(mod_m5602_exit); | |||
297 | MODULE_AUTHOR(DRIVER_AUTHOR); | 296 | MODULE_AUTHOR(DRIVER_AUTHOR); |
298 | MODULE_DESCRIPTION(DRIVER_DESC); | 297 | MODULE_DESCRIPTION(DRIVER_DESC); |
299 | MODULE_LICENSE("GPL"); | 298 | MODULE_LICENSE("GPL"); |
300 | module_param_named(debug, m5602_debug, int, S_IRUGO | S_IWUSR); | ||
301 | MODULE_PARM_DESC(debug, "toggles debug on/off"); | ||
302 | |||
303 | module_param(force_sensor, int, S_IRUGO | S_IWUSR); | 299 | module_param(force_sensor, int, S_IRUGO | S_IWUSR); |
304 | MODULE_PARM_DESC(force_sensor, | 300 | MODULE_PARM_DESC(force_sensor, |
305 | "force detection of sensor, " | 301 | "force detection of sensor, " |
diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.c b/drivers/media/video/gspca/m5602/m5602_mt9m111.c index 566d4925a0e8..fb700c2d055a 100644 --- a/drivers/media/video/gspca/m5602/m5602_mt9m111.c +++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Driver for the mt9m111 sensor | 2 | * Driver for the mt9m111 sensor |
3 | * | 3 | * |
4 | * Copyright (C) 2008 Erik Andren | 4 | * Copyright (C) 2008 Erik Andrén |
5 | * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. | 5 | * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. |
6 | * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br> | 6 | * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br> |
7 | * | 7 | * |
@@ -107,7 +107,7 @@ int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) | |||
107 | err = mt9m111_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, | 107 | err = mt9m111_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, |
108 | data, 2); | 108 | data, 2); |
109 | *val = data[0] & MT9M111_RMB_MIRROR_ROWS; | 109 | *val = data[0] & MT9M111_RMB_MIRROR_ROWS; |
110 | PDEBUG(DBG_V4L2_CID, "Read vertical flip %d", *val); | 110 | PDEBUG(D_V4L2, "Read vertical flip %d", *val); |
111 | 111 | ||
112 | return (err < 0) ? err : 0; | 112 | return (err < 0) ? err : 0; |
113 | } | 113 | } |
@@ -118,7 +118,7 @@ int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val) | |||
118 | u8 data[2] = {0x00, 0x00}; | 118 | u8 data[2] = {0x00, 0x00}; |
119 | struct sd *sd = (struct sd *) gspca_dev; | 119 | struct sd *sd = (struct sd *) gspca_dev; |
120 | 120 | ||
121 | PDEBUG(DBG_V4L2_CID, "Set vertical flip to %d", val); | 121 | PDEBUG(D_V4L2, "Set vertical flip to %d", val); |
122 | 122 | ||
123 | /* Set the correct page map */ | 123 | /* Set the correct page map */ |
124 | err = mt9m111_write_sensor(sd, MT9M111_PAGE_MAP, data, 2); | 124 | err = mt9m111_write_sensor(sd, MT9M111_PAGE_MAP, data, 2); |
@@ -145,7 +145,7 @@ int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) | |||
145 | err = mt9m111_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, | 145 | err = mt9m111_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, |
146 | data, 2); | 146 | data, 2); |
147 | *val = data[0] & MT9M111_RMB_MIRROR_COLS; | 147 | *val = data[0] & MT9M111_RMB_MIRROR_COLS; |
148 | PDEBUG(DBG_V4L2_CID, "Read horizontal flip %d", *val); | 148 | PDEBUG(D_V4L2, "Read horizontal flip %d", *val); |
149 | 149 | ||
150 | return (err < 0) ? err : 0; | 150 | return (err < 0) ? err : 0; |
151 | } | 151 | } |
@@ -156,7 +156,7 @@ int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val) | |||
156 | u8 data[2] = {0x00, 0x00}; | 156 | u8 data[2] = {0x00, 0x00}; |
157 | struct sd *sd = (struct sd *) gspca_dev; | 157 | struct sd *sd = (struct sd *) gspca_dev; |
158 | 158 | ||
159 | PDEBUG(DBG_V4L2_CID, "Set horizontal flip to %d", val); | 159 | PDEBUG(D_V4L2, "Set horizontal flip to %d", val); |
160 | 160 | ||
161 | /* Set the correct page map */ | 161 | /* Set the correct page map */ |
162 | err = mt9m111_write_sensor(sd, MT9M111_PAGE_MAP, data, 2); | 162 | err = mt9m111_write_sensor(sd, MT9M111_PAGE_MAP, data, 2); |
@@ -188,7 +188,7 @@ int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val) | |||
188 | ((tmp & (1 << 8)) * 2) | | 188 | ((tmp & (1 << 8)) * 2) | |
189 | (tmp & 0x7f); | 189 | (tmp & 0x7f); |
190 | 190 | ||
191 | PDEBUG(DBG_V4L2_CID, "Read gain %d", *val); | 191 | PDEBUG(D_V4L2, "Read gain %d", *val); |
192 | 192 | ||
193 | return (err < 0) ? err : 0; | 193 | return (err < 0) ? err : 0; |
194 | } | 194 | } |
@@ -222,7 +222,7 @@ int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val) | |||
222 | 222 | ||
223 | data[1] = (tmp & 0xff00) >> 8; | 223 | data[1] = (tmp & 0xff00) >> 8; |
224 | data[0] = (tmp & 0xff); | 224 | data[0] = (tmp & 0xff); |
225 | PDEBUG(DBG_V4L2_CID, "tmp=%d, data[1]=%d, data[0]=%d", tmp, | 225 | PDEBUG(D_V4L2, "tmp=%d, data[1]=%d, data[0]=%d", tmp, |
226 | data[1], data[0]); | 226 | data[1], data[0]); |
227 | 227 | ||
228 | err = mt9m111_write_sensor(sd, MT9M111_SC_GLOBAL_GAIN, | 228 | err = mt9m111_write_sensor(sd, MT9M111_SC_GLOBAL_GAIN, |
@@ -257,7 +257,7 @@ int mt9m111_read_sensor(struct sd *sd, const u8 address, | |||
257 | for (i = 0; i < len && !err; i++) { | 257 | for (i = 0; i < len && !err; i++) { |
258 | err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i])); | 258 | err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i])); |
259 | 259 | ||
260 | PDEBUG(DBG_TRACE, "Reading sensor register " | 260 | PDEBUG(D_CONF, "Reading sensor register " |
261 | "0x%x contains 0x%x ", address, *i2c_data); | 261 | "0x%x contains 0x%x ", address, *i2c_data); |
262 | } | 262 | } |
263 | out: | 263 | out: |
@@ -290,7 +290,7 @@ int mt9m111_write_sensor(struct sd *sd, const u8 address, | |||
290 | memcpy(p, sensor_urb_skeleton + 16, 4); | 290 | memcpy(p, sensor_urb_skeleton + 16, 4); |
291 | p[3] = i2c_data[i]; | 291 | p[3] = i2c_data[i]; |
292 | p += 4; | 292 | p += 4; |
293 | PDEBUG(DBG_TRACE, "Writing sensor register 0x%x with 0x%x", | 293 | PDEBUG(D_CONF, "Writing sensor register 0x%x with 0x%x", |
294 | address, i2c_data[i]); | 294 | address, i2c_data[i]); |
295 | } | 295 | } |
296 | 296 | ||
diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.h b/drivers/media/video/gspca/m5602/m5602_mt9m111.h index 79a5d8878190..315209d5aeef 100644 --- a/drivers/media/video/gspca/m5602/m5602_mt9m111.h +++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Driver for the mt9m111 sensor | 2 | * Driver for the mt9m111 sensor |
3 | * | 3 | * |
4 | * Copyright (C) 2008 Erik Andren | 4 | * Copyright (C) 2008 Erik Andrén |
5 | * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. | 5 | * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. |
6 | * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br> | 6 | * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br> |
7 | * | 7 | * |
@@ -82,7 +82,6 @@ | |||
82 | /* Kernel module parameters */ | 82 | /* Kernel module parameters */ |
83 | extern int force_sensor; | 83 | extern int force_sensor; |
84 | extern int dump_sensor; | 84 | extern int dump_sensor; |
85 | extern unsigned int m5602_debug; | ||
86 | 85 | ||
87 | int mt9m111_probe(struct sd *sd); | 86 | int mt9m111_probe(struct sd *sd); |
88 | int mt9m111_init(struct sd *sd); | 87 | int mt9m111_init(struct sd *sd); |
@@ -152,8 +151,8 @@ static struct m5602_sensor mt9m111 = { | |||
152 | .default_value = DEFAULT_GAIN, | 151 | .default_value = DEFAULT_GAIN, |
153 | .flags = V4L2_CTRL_FLAG_SLIDER | 152 | .flags = V4L2_CTRL_FLAG_SLIDER |
154 | }, | 153 | }, |
155 | .set = mt9m111_set_hflip, | 154 | .set = mt9m111_set_gain, |
156 | .get = mt9m111_get_hflip | 155 | .get = mt9m111_get_gain |
157 | } | 156 | } |
158 | }, | 157 | }, |
159 | 158 | ||
diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.c b/drivers/media/video/gspca/m5602/m5602_ov9650.c index 31c5896250e7..837c7e47661c 100644 --- a/drivers/media/video/gspca/m5602/m5602_ov9650.c +++ b/drivers/media/video/gspca/m5602/m5602_ov9650.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Driver for the ov9650 sensor | 2 | * Driver for the ov9650 sensor |
3 | * | 3 | * |
4 | * Copyright (C) 2008 Erik Andren | 4 | * Copyright (C) 2008 Erik Andrén |
5 | * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. | 5 | * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. |
6 | * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br> | 6 | * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br> |
7 | * | 7 | * |
@@ -40,7 +40,7 @@ int ov9650_read_sensor(struct sd *sd, const u8 address, | |||
40 | for (i = 0; i < len; i++) { | 40 | for (i = 0; i < len; i++) { |
41 | err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i])); | 41 | err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i])); |
42 | 42 | ||
43 | PDEBUG(DBG_TRACE, "Reading sensor register " | 43 | PDEBUG(D_CONF, "Reading sensor register " |
44 | "0x%x containing 0x%x ", address, *i2c_data); | 44 | "0x%x containing 0x%x ", address, *i2c_data); |
45 | } | 45 | } |
46 | return (err < 0) ? err : 0; | 46 | return (err < 0) ? err : 0; |
@@ -72,7 +72,7 @@ int ov9650_write_sensor(struct sd *sd, const u8 address, | |||
72 | memcpy(p, sensor_urb_skeleton + 16, 4); | 72 | memcpy(p, sensor_urb_skeleton + 16, 4); |
73 | p[3] = i2c_data[i]; | 73 | p[3] = i2c_data[i]; |
74 | p += 4; | 74 | p += 4; |
75 | PDEBUG(DBG_TRACE, "Writing sensor register 0x%x with 0x%x", | 75 | PDEBUG(D_CONF, "Writing sensor register 0x%x with 0x%x", |
76 | address, i2c_data[i]); | 76 | address, i2c_data[i]); |
77 | } | 77 | } |
78 | 78 | ||
@@ -199,7 +199,7 @@ int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) | |||
199 | goto out; | 199 | goto out; |
200 | *val |= (i2c_data & 0x3f) << 10; | 200 | *val |= (i2c_data & 0x3f) << 10; |
201 | 201 | ||
202 | PDEBUG(DBG_V4L2_CID, "Read exposure %d", *val); | 202 | PDEBUG(D_V4L2, "Read exposure %d", *val); |
203 | out: | 203 | out: |
204 | return (err < 0) ? err : 0; | 204 | return (err < 0) ? err : 0; |
205 | } | 205 | } |
@@ -210,7 +210,7 @@ int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val) | |||
210 | u8 i2c_data; | 210 | u8 i2c_data; |
211 | int err; | 211 | int err; |
212 | 212 | ||
213 | PDEBUG(DBG_V4L2_CID, "Set exposure to %d", | 213 | PDEBUG(D_V4L2, "Set exposure to %d", |
214 | val & 0xffff); | 214 | val & 0xffff); |
215 | 215 | ||
216 | /* The 6 MSBs */ | 216 | /* The 6 MSBs */ |
@@ -246,7 +246,7 @@ int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val) | |||
246 | 246 | ||
247 | err = ov9650_read_sensor(sd, OV9650_GAIN, &i2c_data, 1); | 247 | err = ov9650_read_sensor(sd, OV9650_GAIN, &i2c_data, 1); |
248 | *val |= i2c_data; | 248 | *val |= i2c_data; |
249 | PDEBUG(DBG_V4L2_CID, "Read gain %d", *val); | 249 | PDEBUG(D_V4L2, "Read gain %d", *val); |
250 | return (err < 0) ? err : 0; | 250 | return (err < 0) ? err : 0; |
251 | } | 251 | } |
252 | 252 | ||
@@ -280,7 +280,7 @@ int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val) | |||
280 | err = ov9650_read_sensor(sd, OV9650_RED, &i2c_data, 1); | 280 | err = ov9650_read_sensor(sd, OV9650_RED, &i2c_data, 1); |
281 | *val = i2c_data; | 281 | *val = i2c_data; |
282 | 282 | ||
283 | PDEBUG(DBG_V4L2_CID, "Read red gain %d", *val); | 283 | PDEBUG(D_V4L2, "Read red gain %d", *val); |
284 | 284 | ||
285 | return (err < 0) ? err : 0; | 285 | return (err < 0) ? err : 0; |
286 | } | 286 | } |
@@ -291,7 +291,7 @@ int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) | |||
291 | u8 i2c_data; | 291 | u8 i2c_data; |
292 | struct sd *sd = (struct sd *) gspca_dev; | 292 | struct sd *sd = (struct sd *) gspca_dev; |
293 | 293 | ||
294 | PDEBUG(DBG_V4L2_CID, "Set red gain to %d", | 294 | PDEBUG(D_V4L2, "Set red gain to %d", |
295 | val & 0xff); | 295 | val & 0xff); |
296 | 296 | ||
297 | i2c_data = val & 0xff; | 297 | i2c_data = val & 0xff; |
@@ -309,7 +309,7 @@ int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val) | |||
309 | err = ov9650_read_sensor(sd, OV9650_BLUE, &i2c_data, 1); | 309 | err = ov9650_read_sensor(sd, OV9650_BLUE, &i2c_data, 1); |
310 | *val = i2c_data; | 310 | *val = i2c_data; |
311 | 311 | ||
312 | PDEBUG(DBG_V4L2_CID, "Read blue gain %d", *val); | 312 | PDEBUG(D_V4L2, "Read blue gain %d", *val); |
313 | 313 | ||
314 | return (err < 0) ? err : 0; | 314 | return (err < 0) ? err : 0; |
315 | } | 315 | } |
@@ -320,7 +320,7 @@ int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val) | |||
320 | u8 i2c_data; | 320 | u8 i2c_data; |
321 | struct sd *sd = (struct sd *) gspca_dev; | 321 | struct sd *sd = (struct sd *) gspca_dev; |
322 | 322 | ||
323 | PDEBUG(DBG_V4L2_CID, "Set blue gain to %d", | 323 | PDEBUG(D_V4L2, "Set blue gain to %d", |
324 | val & 0xff); | 324 | val & 0xff); |
325 | 325 | ||
326 | i2c_data = val & 0xff; | 326 | i2c_data = val & 0xff; |
@@ -340,7 +340,7 @@ int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) | |||
340 | *val = ((i2c_data & OV9650_HFLIP) >> 5) ? 0 : 1; | 340 | *val = ((i2c_data & OV9650_HFLIP) >> 5) ? 0 : 1; |
341 | else | 341 | else |
342 | *val = (i2c_data & OV9650_HFLIP) >> 5; | 342 | *val = (i2c_data & OV9650_HFLIP) >> 5; |
343 | PDEBUG(DBG_V4L2_CID, "Read horizontal flip %d", *val); | 343 | PDEBUG(D_V4L2, "Read horizontal flip %d", *val); |
344 | 344 | ||
345 | return (err < 0) ? err : 0; | 345 | return (err < 0) ? err : 0; |
346 | } | 346 | } |
@@ -351,7 +351,7 @@ int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val) | |||
351 | u8 i2c_data; | 351 | u8 i2c_data; |
352 | struct sd *sd = (struct sd *) gspca_dev; | 352 | struct sd *sd = (struct sd *) gspca_dev; |
353 | 353 | ||
354 | PDEBUG(DBG_V4L2_CID, "Set horizontal flip to %d", val); | 354 | PDEBUG(D_V4L2, "Set horizontal flip to %d", val); |
355 | err = ov9650_read_sensor(sd, OV9650_MVFP, &i2c_data, 1); | 355 | err = ov9650_read_sensor(sd, OV9650_MVFP, &i2c_data, 1); |
356 | if (err < 0) | 356 | if (err < 0) |
357 | goto out; | 357 | goto out; |
@@ -379,7 +379,7 @@ int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) | |||
379 | *val = ((i2c_data & 0x10) >> 4) ? 0 : 1; | 379 | *val = ((i2c_data & 0x10) >> 4) ? 0 : 1; |
380 | else | 380 | else |
381 | *val = (i2c_data & 0x10) >> 4; | 381 | *val = (i2c_data & 0x10) >> 4; |
382 | PDEBUG(DBG_V4L2_CID, "Read vertical flip %d", *val); | 382 | PDEBUG(D_V4L2, "Read vertical flip %d", *val); |
383 | 383 | ||
384 | return (err < 0) ? err : 0; | 384 | return (err < 0) ? err : 0; |
385 | } | 385 | } |
@@ -390,7 +390,7 @@ int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val) | |||
390 | u8 i2c_data; | 390 | u8 i2c_data; |
391 | struct sd *sd = (struct sd *) gspca_dev; | 391 | struct sd *sd = (struct sd *) gspca_dev; |
392 | 392 | ||
393 | PDEBUG(DBG_V4L2_CID, "Set vertical flip to %d", val); | 393 | PDEBUG(D_V4L2, "Set vertical flip to %d", val); |
394 | err = ov9650_read_sensor(sd, OV9650_MVFP, &i2c_data, 1); | 394 | err = ov9650_read_sensor(sd, OV9650_MVFP, &i2c_data, 1); |
395 | if (err < 0) | 395 | if (err < 0) |
396 | goto out; | 396 | goto out; |
@@ -420,7 +420,7 @@ int ov9650_get_brightness(struct gspca_dev *gspca_dev, __s32 *val) | |||
420 | 420 | ||
421 | err = ov9650_read_sensor(sd, OV9650_GAIN, &i2c_data, 1); | 421 | err = ov9650_read_sensor(sd, OV9650_GAIN, &i2c_data, 1); |
422 | *val |= i2c_data; | 422 | *val |= i2c_data; |
423 | PDEBUG(DBG_V4L2_CID, "Read gain %d", *val); | 423 | PDEBUG(D_V4L2, "Read gain %d", *val); |
424 | out: | 424 | out: |
425 | return (err < 0) ? err : 0; | 425 | return (err < 0) ? err : 0; |
426 | } | 426 | } |
@@ -431,7 +431,7 @@ int ov9650_set_brightness(struct gspca_dev *gspca_dev, __s32 val) | |||
431 | u8 i2c_data; | 431 | u8 i2c_data; |
432 | struct sd *sd = (struct sd *) gspca_dev; | 432 | struct sd *sd = (struct sd *) gspca_dev; |
433 | 433 | ||
434 | PDEBUG(DBG_V4L2_CID, "Set gain to %d", val & 0x3ff); | 434 | PDEBUG(D_V4L2, "Set gain to %d", val & 0x3ff); |
435 | 435 | ||
436 | /* Read the OV9650_VREF register first to avoid | 436 | /* Read the OV9650_VREF register first to avoid |
437 | corrupting the VREF high and low bits */ | 437 | corrupting the VREF high and low bits */ |
@@ -461,7 +461,7 @@ int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev, __s32 *val) | |||
461 | 461 | ||
462 | err = ov9650_read_sensor(sd, OV9650_COM8, &i2c_data, 1); | 462 | err = ov9650_read_sensor(sd, OV9650_COM8, &i2c_data, 1); |
463 | *val = (i2c_data & OV9650_AWB_EN) >> 1; | 463 | *val = (i2c_data & OV9650_AWB_EN) >> 1; |
464 | PDEBUG(DBG_V4L2_CID, "Read auto white balance %d", *val); | 464 | PDEBUG(D_V4L2, "Read auto white balance %d", *val); |
465 | 465 | ||
466 | return (err < 0) ? err : 0; | 466 | return (err < 0) ? err : 0; |
467 | } | 467 | } |
@@ -472,7 +472,7 @@ int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, __s32 val) | |||
472 | u8 i2c_data; | 472 | u8 i2c_data; |
473 | struct sd *sd = (struct sd *) gspca_dev; | 473 | struct sd *sd = (struct sd *) gspca_dev; |
474 | 474 | ||
475 | PDEBUG(DBG_V4L2_CID, "Set auto white balance to %d", val); | 475 | PDEBUG(D_V4L2, "Set auto white balance to %d", val); |
476 | err = ov9650_read_sensor(sd, OV9650_COM8, &i2c_data, 1); | 476 | err = ov9650_read_sensor(sd, OV9650_COM8, &i2c_data, 1); |
477 | if (err < 0) | 477 | if (err < 0) |
478 | goto out; | 478 | goto out; |
@@ -491,7 +491,7 @@ int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val) | |||
491 | 491 | ||
492 | err = ov9650_read_sensor(sd, OV9650_COM8, &i2c_data, 1); | 492 | err = ov9650_read_sensor(sd, OV9650_COM8, &i2c_data, 1); |
493 | *val = (i2c_data & OV9650_AGC_EN) >> 2; | 493 | *val = (i2c_data & OV9650_AGC_EN) >> 2; |
494 | PDEBUG(DBG_V4L2_CID, "Read auto gain control %d", *val); | 494 | PDEBUG(D_V4L2, "Read auto gain control %d", *val); |
495 | 495 | ||
496 | return (err < 0) ? err : 0; | 496 | return (err < 0) ? err : 0; |
497 | } | 497 | } |
@@ -502,7 +502,7 @@ int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val) | |||
502 | u8 i2c_data; | 502 | u8 i2c_data; |
503 | struct sd *sd = (struct sd *) gspca_dev; | 503 | struct sd *sd = (struct sd *) gspca_dev; |
504 | 504 | ||
505 | PDEBUG(DBG_V4L2_CID, "Set auto gain control to %d", val); | 505 | PDEBUG(D_V4L2, "Set auto gain control to %d", val); |
506 | err = ov9650_read_sensor(sd, OV9650_COM8, &i2c_data, 1); | 506 | err = ov9650_read_sensor(sd, OV9650_COM8, &i2c_data, 1); |
507 | if (err < 0) | 507 | if (err < 0) |
508 | goto out; | 508 | goto out; |
diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.h b/drivers/media/video/gspca/m5602/m5602_ov9650.h index 2f29cb056f30..065632f0378e 100644 --- a/drivers/media/video/gspca/m5602/m5602_ov9650.h +++ b/drivers/media/video/gspca/m5602/m5602_ov9650.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Driver for the ov9650 sensor | 2 | * Driver for the ov9650 sensor |
3 | * | 3 | * |
4 | * Copyright (C) 2008 Erik Andren | 4 | * Copyright (C) 2008 Erik Andrén |
5 | * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. | 5 | * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. |
6 | * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br> | 6 | * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br> |
7 | * | 7 | * |
@@ -121,7 +121,6 @@ | |||
121 | /* Kernel module parameters */ | 121 | /* Kernel module parameters */ |
122 | extern int force_sensor; | 122 | extern int force_sensor; |
123 | extern int dump_sensor; | 123 | extern int dump_sensor; |
124 | extern unsigned int m5602_debug; | ||
125 | 124 | ||
126 | int ov9650_probe(struct sd *sd); | 125 | int ov9650_probe(struct sd *sd); |
127 | int ov9650_init(struct sd *sd); | 126 | int ov9650_init(struct sd *sd); |
diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.c b/drivers/media/video/gspca/m5602/m5602_po1030.c index 08c015bde115..d17ac52566e6 100644 --- a/drivers/media/video/gspca/m5602/m5602_po1030.c +++ b/drivers/media/video/gspca/m5602/m5602_po1030.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Driver for the po1030 sensor | 2 | * Driver for the po1030 sensor |
3 | * | 3 | * |
4 | * Copyright (c) 2008 Erik Andren | 4 | * Copyright (c) 2008 Erik Andrén |
5 | * Copyright (c) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. | 5 | * Copyright (c) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. |
6 | * Copyright (c) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br> | 6 | * Copyright (c) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br> |
7 | * | 7 | * |
@@ -82,7 +82,7 @@ int po1030_read_sensor(struct sd *sd, const u8 address, | |||
82 | for (i = 0; i < len; i++) { | 82 | for (i = 0; i < len; i++) { |
83 | err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i])); | 83 | err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i])); |
84 | 84 | ||
85 | PDEBUG(DBG_TRACE, "Reading sensor register " | 85 | PDEBUG(D_CONF, "Reading sensor register " |
86 | "0x%x containing 0x%x ", address, *i2c_data); | 86 | "0x%x containing 0x%x ", address, *i2c_data); |
87 | } | 87 | } |
88 | return (err < 0) ? err : 0; | 88 | return (err < 0) ? err : 0; |
@@ -112,7 +112,7 @@ int po1030_write_sensor(struct sd *sd, const u8 address, | |||
112 | memcpy(p, sensor_urb_skeleton + 16, 4); | 112 | memcpy(p, sensor_urb_skeleton + 16, 4); |
113 | p[3] = i2c_data[i]; | 113 | p[3] = i2c_data[i]; |
114 | p += 4; | 114 | p += 4; |
115 | PDEBUG(DBG_TRACE, "Writing sensor register 0x%x with 0x%x", | 115 | PDEBUG(D_CONF, "Writing sensor register 0x%x with 0x%x", |
116 | address, i2c_data[i]); | 116 | address, i2c_data[i]); |
117 | } | 117 | } |
118 | 118 | ||
@@ -185,7 +185,7 @@ int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) | |||
185 | &i2c_data, 1); | 185 | &i2c_data, 1); |
186 | *val |= i2c_data; | 186 | *val |= i2c_data; |
187 | 187 | ||
188 | PDEBUG(DBG_V4L2_CID, "Exposure read as %d", *val); | 188 | PDEBUG(D_V4L2, "Exposure read as %d", *val); |
189 | out: | 189 | out: |
190 | return (err < 0) ? err : 0; | 190 | return (err < 0) ? err : 0; |
191 | } | 191 | } |
@@ -196,10 +196,10 @@ int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val) | |||
196 | u8 i2c_data; | 196 | u8 i2c_data; |
197 | int err; | 197 | int err; |
198 | 198 | ||
199 | PDEBUG(DBG_V4L2, "Set exposure to %d", val & 0xffff); | 199 | PDEBUG(D_V4L2, "Set exposure to %d", val & 0xffff); |
200 | 200 | ||
201 | i2c_data = ((val & 0xff00) >> 8); | 201 | i2c_data = ((val & 0xff00) >> 8); |
202 | PDEBUG(DBG_V4L2, "Set exposure to high byte to 0x%x", | 202 | PDEBUG(D_V4L2, "Set exposure to high byte to 0x%x", |
203 | i2c_data); | 203 | i2c_data); |
204 | 204 | ||
205 | err = po1030_write_sensor(sd, PO1030_REG_INTEGLINES_H, | 205 | err = po1030_write_sensor(sd, PO1030_REG_INTEGLINES_H, |
@@ -208,7 +208,7 @@ int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val) | |||
208 | goto out; | 208 | goto out; |
209 | 209 | ||
210 | i2c_data = (val & 0xff); | 210 | i2c_data = (val & 0xff); |
211 | PDEBUG(DBG_V4L2, "Set exposure to low byte to 0x%x", | 211 | PDEBUG(D_V4L2, "Set exposure to low byte to 0x%x", |
212 | i2c_data); | 212 | i2c_data); |
213 | err = po1030_write_sensor(sd, PO1030_REG_INTEGLINES_M, | 213 | err = po1030_write_sensor(sd, PO1030_REG_INTEGLINES_M, |
214 | &i2c_data, 1); | 214 | &i2c_data, 1); |
@@ -226,7 +226,71 @@ int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val) | |||
226 | err = po1030_read_sensor(sd, PO1030_REG_GLOBALGAIN, | 226 | err = po1030_read_sensor(sd, PO1030_REG_GLOBALGAIN, |
227 | &i2c_data, 1); | 227 | &i2c_data, 1); |
228 | *val = i2c_data; | 228 | *val = i2c_data; |
229 | PDEBUG(DBG_V4L2_CID, "Read global gain %d", *val); | 229 | PDEBUG(D_V4L2, "Read global gain %d", *val); |
230 | |||
231 | return (err < 0) ? err : 0; | ||
232 | } | ||
233 | |||
234 | int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) | ||
235 | { | ||
236 | struct sd *sd = (struct sd *) gspca_dev; | ||
237 | u8 i2c_data; | ||
238 | int err; | ||
239 | |||
240 | err = po1030_read_sensor(sd, PO1030_REG_CONTROL2, | ||
241 | &i2c_data, 1); | ||
242 | |||
243 | *val = (i2c_data >> 7) & 0x01 ; | ||
244 | |||
245 | PDEBUG(D_V4L2, "Read hflip %d", *val); | ||
246 | |||
247 | return (err < 0) ? err : 0; | ||
248 | } | ||
249 | |||
250 | int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val) | ||
251 | { | ||
252 | struct sd *sd = (struct sd *) gspca_dev; | ||
253 | u8 i2c_data; | ||
254 | int err; | ||
255 | |||
256 | PDEBUG(D_V4L2, "Set hflip %d", val); | ||
257 | |||
258 | i2c_data = (val & 0x01) << 7; | ||
259 | |||
260 | err = po1030_write_sensor(sd, PO1030_REG_CONTROL2, | ||
261 | &i2c_data, 1); | ||
262 | |||
263 | return (err < 0) ? err : 0; | ||
264 | } | ||
265 | |||
266 | int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) | ||
267 | { | ||
268 | struct sd *sd = (struct sd *) gspca_dev; | ||
269 | u8 i2c_data; | ||
270 | int err; | ||
271 | |||
272 | err = po1030_read_sensor(sd, PO1030_REG_GLOBALGAIN, | ||
273 | &i2c_data, 1); | ||
274 | |||
275 | *val = (i2c_data >> 6) & 0x01; | ||
276 | |||
277 | PDEBUG(D_V4L2, "Read vflip %d", *val); | ||
278 | |||
279 | return (err < 0) ? err : 0; | ||
280 | } | ||
281 | |||
282 | int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val) | ||
283 | { | ||
284 | struct sd *sd = (struct sd *) gspca_dev; | ||
285 | u8 i2c_data; | ||
286 | int err; | ||
287 | |||
288 | PDEBUG(D_V4L2, "Set vflip %d", val); | ||
289 | |||
290 | i2c_data = (val & 0x01) << 6; | ||
291 | |||
292 | err = po1030_write_sensor(sd, PO1030_REG_CONTROL2, | ||
293 | &i2c_data, 1); | ||
230 | 294 | ||
231 | return (err < 0) ? err : 0; | 295 | return (err < 0) ? err : 0; |
232 | } | 296 | } |
@@ -238,7 +302,7 @@ int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val) | |||
238 | int err; | 302 | int err; |
239 | 303 | ||
240 | i2c_data = val & 0xff; | 304 | i2c_data = val & 0xff; |
241 | PDEBUG(DBG_V4L2, "Set global gain to %d", i2c_data); | 305 | PDEBUG(D_V4L2, "Set global gain to %d", i2c_data); |
242 | err = po1030_write_sensor(sd, PO1030_REG_GLOBALGAIN, | 306 | err = po1030_write_sensor(sd, PO1030_REG_GLOBALGAIN, |
243 | &i2c_data, 1); | 307 | &i2c_data, 1); |
244 | return (err < 0) ? err : 0; | 308 | return (err < 0) ? err : 0; |
@@ -253,7 +317,7 @@ int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val) | |||
253 | err = po1030_read_sensor(sd, PO1030_REG_RED_GAIN, | 317 | err = po1030_read_sensor(sd, PO1030_REG_RED_GAIN, |
254 | &i2c_data, 1); | 318 | &i2c_data, 1); |
255 | *val = i2c_data; | 319 | *val = i2c_data; |
256 | PDEBUG(DBG_V4L2_CID, "Read red gain %d", *val); | 320 | PDEBUG(D_V4L2, "Read red gain %d", *val); |
257 | return (err < 0) ? err : 0; | 321 | return (err < 0) ? err : 0; |
258 | } | 322 | } |
259 | 323 | ||
@@ -264,7 +328,7 @@ int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) | |||
264 | int err; | 328 | int err; |
265 | 329 | ||
266 | i2c_data = val & 0xff; | 330 | i2c_data = val & 0xff; |
267 | PDEBUG(DBG_V4L2, "Set red gain to %d", i2c_data); | 331 | PDEBUG(D_V4L2, "Set red gain to %d", i2c_data); |
268 | err = po1030_write_sensor(sd, PO1030_REG_RED_GAIN, | 332 | err = po1030_write_sensor(sd, PO1030_REG_RED_GAIN, |
269 | &i2c_data, 1); | 333 | &i2c_data, 1); |
270 | return (err < 0) ? err : 0; | 334 | return (err < 0) ? err : 0; |
@@ -279,7 +343,7 @@ int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val) | |||
279 | err = po1030_read_sensor(sd, PO1030_REG_BLUE_GAIN, | 343 | err = po1030_read_sensor(sd, PO1030_REG_BLUE_GAIN, |
280 | &i2c_data, 1); | 344 | &i2c_data, 1); |
281 | *val = i2c_data; | 345 | *val = i2c_data; |
282 | PDEBUG(DBG_V4L2_CID, "Read blue gain %d", *val); | 346 | PDEBUG(D_V4L2, "Read blue gain %d", *val); |
283 | 347 | ||
284 | return (err < 0) ? err : 0; | 348 | return (err < 0) ? err : 0; |
285 | } | 349 | } |
@@ -290,7 +354,7 @@ int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val) | |||
290 | u8 i2c_data; | 354 | u8 i2c_data; |
291 | int err; | 355 | int err; |
292 | i2c_data = val & 0xff; | 356 | i2c_data = val & 0xff; |
293 | PDEBUG(DBG_V4L2, "Set blue gain to %d", i2c_data); | 357 | PDEBUG(D_V4L2, "Set blue gain to %d", i2c_data); |
294 | err = po1030_write_sensor(sd, PO1030_REG_BLUE_GAIN, | 358 | err = po1030_write_sensor(sd, PO1030_REG_BLUE_GAIN, |
295 | &i2c_data, 1); | 359 | &i2c_data, 1); |
296 | 360 | ||
diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.h b/drivers/media/video/gspca/m5602/m5602_po1030.h index 68f34c97bf44..a0b75ff61d79 100644 --- a/drivers/media/video/gspca/m5602/m5602_po1030.h +++ b/drivers/media/video/gspca/m5602/m5602_po1030.h | |||
@@ -1,8 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Driver for the po1030 sensor. | 2 | * Driver for the po1030 sensor. |
3 | * This is probably a pixel plus sensor but we haven't identified it yet | ||
4 | * | 3 | * |
5 | * Copyright (c) 2008 Erik Andren | 4 | * Copyright (c) 2008 Erik Andrén |
6 | * Copyright (c) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. | 5 | * Copyright (c) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. |
7 | * Copyright (c) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br> | 6 | * Copyright (c) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br> |
8 | * | 7 | * |
@@ -109,10 +108,13 @@ | |||
109 | #define PO1030_REG_YCONTRAST 0x74 | 108 | #define PO1030_REG_YCONTRAST 0x74 |
110 | #define PO1030_REG_YSATURATION 0x75 | 109 | #define PO1030_REG_YSATURATION 0x75 |
111 | 110 | ||
111 | #define PO1030_HFLIP (1 << 7) | ||
112 | #define PO1030_VFLIP (1 << 6) | ||
113 | |||
112 | /*****************************************************************************/ | 114 | /*****************************************************************************/ |
113 | 115 | ||
114 | #define PO1030_GLOBAL_GAIN_DEFAULT 0x12 | 116 | #define PO1030_GLOBAL_GAIN_DEFAULT 0x12 |
115 | #define PO1030_EXPOSURE_DEFAULT 0xf0ff | 117 | #define PO1030_EXPOSURE_DEFAULT 0x0085 |
116 | #define PO1030_BLUE_GAIN_DEFAULT 0x40 | 118 | #define PO1030_BLUE_GAIN_DEFAULT 0x40 |
117 | #define PO1030_RED_GAIN_DEFAULT 0x40 | 119 | #define PO1030_RED_GAIN_DEFAULT 0x40 |
118 | 120 | ||
@@ -121,7 +123,6 @@ | |||
121 | /* Kernel module parameters */ | 123 | /* Kernel module parameters */ |
122 | extern int force_sensor; | 124 | extern int force_sensor; |
123 | extern int dump_sensor; | 125 | extern int dump_sensor; |
124 | extern unsigned int m5602_debug; | ||
125 | 126 | ||
126 | int po1030_probe(struct sd *sd); | 127 | int po1030_probe(struct sd *sd); |
127 | int po1030_init(struct sd *sd); | 128 | int po1030_init(struct sd *sd); |
@@ -142,6 +143,10 @@ int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val); | |||
142 | int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val); | 143 | int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val); |
143 | int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val); | 144 | int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val); |
144 | int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val); | 145 | int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val); |
146 | int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
147 | int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val); | ||
148 | int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
149 | int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val); | ||
145 | 150 | ||
146 | static struct m5602_sensor po1030 = { | 151 | static struct m5602_sensor po1030 = { |
147 | .name = "PO1030", | 152 | .name = "PO1030", |
@@ -152,7 +157,7 @@ static struct m5602_sensor po1030 = { | |||
152 | .init = po1030_init, | 157 | .init = po1030_init, |
153 | .power_down = po1030_power_down, | 158 | .power_down = po1030_power_down, |
154 | 159 | ||
155 | .nctrls = 4, | 160 | .nctrls = 6, |
156 | .ctrls = { | 161 | .ctrls = { |
157 | { | 162 | { |
158 | { | 163 | { |
@@ -160,7 +165,7 @@ static struct m5602_sensor po1030 = { | |||
160 | .type = V4L2_CTRL_TYPE_INTEGER, | 165 | .type = V4L2_CTRL_TYPE_INTEGER, |
161 | .name = "gain", | 166 | .name = "gain", |
162 | .minimum = 0x00, | 167 | .minimum = 0x00, |
163 | .maximum = 0xff, | 168 | .maximum = 0x4f, |
164 | .step = 0x1, | 169 | .step = 0x1, |
165 | .default_value = PO1030_GLOBAL_GAIN_DEFAULT, | 170 | .default_value = PO1030_GLOBAL_GAIN_DEFAULT, |
166 | .flags = V4L2_CTRL_FLAG_SLIDER | 171 | .flags = V4L2_CTRL_FLAG_SLIDER |
@@ -173,7 +178,7 @@ static struct m5602_sensor po1030 = { | |||
173 | .type = V4L2_CTRL_TYPE_INTEGER, | 178 | .type = V4L2_CTRL_TYPE_INTEGER, |
174 | .name = "exposure", | 179 | .name = "exposure", |
175 | .minimum = 0x00, | 180 | .minimum = 0x00, |
176 | .maximum = 0xffff, | 181 | .maximum = 0x02ff, |
177 | .step = 0x1, | 182 | .step = 0x1, |
178 | .default_value = PO1030_EXPOSURE_DEFAULT, | 183 | .default_value = PO1030_EXPOSURE_DEFAULT, |
179 | .flags = V4L2_CTRL_FLAG_SLIDER | 184 | .flags = V4L2_CTRL_FLAG_SLIDER |
@@ -206,8 +211,33 @@ static struct m5602_sensor po1030 = { | |||
206 | }, | 211 | }, |
207 | .set = po1030_set_blue_balance, | 212 | .set = po1030_set_blue_balance, |
208 | .get = po1030_get_blue_balance | 213 | .get = po1030_get_blue_balance |
214 | }, { | ||
215 | { | ||
216 | .id = V4L2_CID_HFLIP, | ||
217 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
218 | .name = "horizontal flip", | ||
219 | .minimum = 0, | ||
220 | .maximum = 1, | ||
221 | .step = 1, | ||
222 | .default_value = 0, | ||
223 | }, | ||
224 | .set = po1030_set_hflip, | ||
225 | .get = po1030_get_hflip | ||
226 | }, { | ||
227 | { | ||
228 | .id = V4L2_CID_VFLIP, | ||
229 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
230 | .name = "vertical flip", | ||
231 | .minimum = 0, | ||
232 | .maximum = 1, | ||
233 | .step = 1, | ||
234 | .default_value = 0, | ||
235 | }, | ||
236 | .set = po1030_set_vflip, | ||
237 | .get = po1030_get_vflip | ||
209 | } | 238 | } |
210 | }, | 239 | }, |
240 | |||
211 | .nmodes = 1, | 241 | .nmodes = 1, |
212 | .modes = { | 242 | .modes = { |
213 | { | 243 | { |
@@ -381,7 +411,7 @@ static const unsigned char init_po1030[][4] = | |||
381 | 411 | ||
382 | /* Set the y window to 1 */ | 412 | /* Set the y window to 1 */ |
383 | {SENSOR, PO1030_REG_WINDOWY_H, 0x00}, | 413 | {SENSOR, PO1030_REG_WINDOWY_H, 0x00}, |
384 | {SENSOR, PO1030_REG_WINDOWX_L, 0x01}, | 414 | {SENSOR, PO1030_REG_WINDOWY_L, 0x01}, |
385 | 415 | ||
386 | {SENSOR, PO1030_REG_WINDOWWIDTH_H, 0x02}, | 416 | {SENSOR, PO1030_REG_WINDOWWIDTH_H, 0x02}, |
387 | {SENSOR, PO1030_REG_WINDOWWIDTH_L, 0x87}, | 417 | {SENSOR, PO1030_REG_WINDOWWIDTH_L, 0x87}, |
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c index 68202565325d..14b1eac5b812 100644 --- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c +++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Driver for the s5k4aa sensor | 2 | * Driver for the s5k4aa sensor |
3 | * | 3 | * |
4 | * Copyright (C) 2008 Erik Andren | 4 | * Copyright (C) 2008 Erik Andrén |
5 | * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. | 5 | * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. |
6 | * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br> | 6 | * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br> |
7 | * | 7 | * |
@@ -117,7 +117,7 @@ int s5k4aa_read_sensor(struct sd *sd, const u8 address, | |||
117 | for (i = 0; (i < len) & !err; i++) { | 117 | for (i = 0; (i < len) & !err; i++) { |
118 | err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i])); | 118 | err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i])); |
119 | 119 | ||
120 | PDEBUG(DBG_TRACE, "Reading sensor register " | 120 | PDEBUG(D_CONF, "Reading sensor register " |
121 | "0x%x containing 0x%x ", address, *i2c_data); | 121 | "0x%x containing 0x%x ", address, *i2c_data); |
122 | } | 122 | } |
123 | out: | 123 | out: |
@@ -150,7 +150,7 @@ int s5k4aa_write_sensor(struct sd *sd, const u8 address, | |||
150 | memcpy(p, sensor_urb_skeleton + 16, 4); | 150 | memcpy(p, sensor_urb_skeleton + 16, 4); |
151 | p[3] = i2c_data[i]; | 151 | p[3] = i2c_data[i]; |
152 | p += 4; | 152 | p += 4; |
153 | PDEBUG(DBG_TRACE, "Writing sensor register 0x%x with 0x%x", | 153 | PDEBUG(D_CONF, "Writing sensor register 0x%x with 0x%x", |
154 | address, i2c_data[i]); | 154 | address, i2c_data[i]); |
155 | } | 155 | } |
156 | 156 | ||
@@ -248,7 +248,7 @@ int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) | |||
248 | *val = data << 8; | 248 | *val = data << 8; |
249 | err = s5k4aa_read_sensor(sd, S5K4AA_EXPOSURE_LO, &data, 1); | 249 | err = s5k4aa_read_sensor(sd, S5K4AA_EXPOSURE_LO, &data, 1); |
250 | *val |= data; | 250 | *val |= data; |
251 | PDEBUG(DBG_V4L2_CID, "Read exposure %d", *val); | 251 | PDEBUG(D_V4L2, "Read exposure %d", *val); |
252 | out: | 252 | out: |
253 | return (err < 0) ? err : 0; | 253 | return (err < 0) ? err : 0; |
254 | } | 254 | } |
@@ -259,7 +259,7 @@ int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val) | |||
259 | u8 data = S5K4AA_PAGE_MAP_2; | 259 | u8 data = S5K4AA_PAGE_MAP_2; |
260 | int err; | 260 | int err; |
261 | 261 | ||
262 | PDEBUG(DBG_V4L2_CID, "Set exposure to %d", val); | 262 | PDEBUG(D_V4L2, "Set exposure to %d", val); |
263 | err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); | 263 | err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); |
264 | if (err < 0) | 264 | if (err < 0) |
265 | goto out; | 265 | goto out; |
@@ -285,7 +285,7 @@ int s5k4aa_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) | |||
285 | 285 | ||
286 | err = s5k4aa_read_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); | 286 | err = s5k4aa_read_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); |
287 | *val = (data & S5K4AA_RM_V_FLIP) >> 7; | 287 | *val = (data & S5K4AA_RM_V_FLIP) >> 7; |
288 | PDEBUG(DBG_V4L2_CID, "Read vertical flip %d", *val); | 288 | PDEBUG(D_V4L2, "Read vertical flip %d", *val); |
289 | 289 | ||
290 | out: | 290 | out: |
291 | return (err < 0) ? err : 0; | 291 | return (err < 0) ? err : 0; |
@@ -297,7 +297,7 @@ int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val) | |||
297 | u8 data = S5K4AA_PAGE_MAP_2; | 297 | u8 data = S5K4AA_PAGE_MAP_2; |
298 | int err; | 298 | int err; |
299 | 299 | ||
300 | PDEBUG(DBG_V4L2_CID, "Set vertical flip to %d", val); | 300 | PDEBUG(D_V4L2, "Set vertical flip to %d", val); |
301 | err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); | 301 | err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); |
302 | if (err < 0) | 302 | if (err < 0) |
303 | goto out; | 303 | goto out; |
@@ -341,7 +341,7 @@ int s5k4aa_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) | |||
341 | 341 | ||
342 | err = s5k4aa_read_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); | 342 | err = s5k4aa_read_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); |
343 | *val = (data & S5K4AA_RM_H_FLIP) >> 6; | 343 | *val = (data & S5K4AA_RM_H_FLIP) >> 6; |
344 | PDEBUG(DBG_V4L2_CID, "Read horizontal flip %d", *val); | 344 | PDEBUG(D_V4L2, "Read horizontal flip %d", *val); |
345 | out: | 345 | out: |
346 | return (err < 0) ? err : 0; | 346 | return (err < 0) ? err : 0; |
347 | } | 347 | } |
@@ -352,7 +352,7 @@ int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val) | |||
352 | u8 data = S5K4AA_PAGE_MAP_2; | 352 | u8 data = S5K4AA_PAGE_MAP_2; |
353 | int err; | 353 | int err; |
354 | 354 | ||
355 | PDEBUG(DBG_V4L2_CID, "Set horizontal flip to %d", | 355 | PDEBUG(D_V4L2, "Set horizontal flip to %d", |
356 | val); | 356 | val); |
357 | err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); | 357 | err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); |
358 | if (err < 0) | 358 | if (err < 0) |
@@ -397,7 +397,7 @@ int s5k4aa_get_gain(struct gspca_dev *gspca_dev, __s32 *val) | |||
397 | 397 | ||
398 | err = s5k4aa_read_sensor(sd, S5K4AA_GAIN_2, &data, 1); | 398 | err = s5k4aa_read_sensor(sd, S5K4AA_GAIN_2, &data, 1); |
399 | *val = data; | 399 | *val = data; |
400 | PDEBUG(DBG_V4L2_CID, "Read gain %d", *val); | 400 | PDEBUG(D_V4L2, "Read gain %d", *val); |
401 | 401 | ||
402 | out: | 402 | out: |
403 | return (err < 0) ? err : 0; | 403 | return (err < 0) ? err : 0; |
@@ -409,7 +409,7 @@ int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val) | |||
409 | u8 data = S5K4AA_PAGE_MAP_2; | 409 | u8 data = S5K4AA_PAGE_MAP_2; |
410 | int err; | 410 | int err; |
411 | 411 | ||
412 | PDEBUG(DBG_V4L2_CID, "Set gain to %d", val); | 412 | PDEBUG(D_V4L2, "Set gain to %d", val); |
413 | err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); | 413 | err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); |
414 | if (err < 0) | 414 | if (err < 0) |
415 | goto out; | 415 | goto out; |
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.h b/drivers/media/video/gspca/m5602/m5602_s5k4aa.h index bb7f7e3e90af..eaef67655afa 100644 --- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.h +++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Driver for the s5k4aa sensor | 2 | * Driver for the s5k4aa sensor |
3 | * | 3 | * |
4 | * Copyright (C) 2008 Erik Andren | 4 | * Copyright (C) 2008 Erik Andrén |
5 | * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. | 5 | * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. |
6 | * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br> | 6 | * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br> |
7 | * | 7 | * |
@@ -63,7 +63,6 @@ | |||
63 | /* Kernel module parameters */ | 63 | /* Kernel module parameters */ |
64 | extern int force_sensor; | 64 | extern int force_sensor; |
65 | extern int dump_sensor; | 65 | extern int dump_sensor; |
66 | extern unsigned int m5602_debug; | ||
67 | 66 | ||
68 | int s5k4aa_probe(struct sd *sd); | 67 | int s5k4aa_probe(struct sd *sd); |
69 | int s5k4aa_init(struct sd *sd); | 68 | int s5k4aa_init(struct sd *sd); |
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k83a.c b/drivers/media/video/gspca/m5602/m5602_s5k83a.c index b4b33c2d0499..8988a728e0b4 100644 --- a/drivers/media/video/gspca/m5602/m5602_s5k83a.c +++ b/drivers/media/video/gspca/m5602/m5602_s5k83a.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Driver for the s5k83a sensor | 2 | * Driver for the s5k83a sensor |
3 | * | 3 | * |
4 | * Copyright (C) 2008 Erik Andren | 4 | * Copyright (C) 2008 Erik Andrén |
5 | * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. | 5 | * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. |
6 | * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br> | 6 | * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br> |
7 | * | 7 | * |
@@ -101,7 +101,7 @@ int s5k83a_read_sensor(struct sd *sd, const u8 address, | |||
101 | for (i = 0; i < len && !len; i++) { | 101 | for (i = 0; i < len && !len; i++) { |
102 | err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i])); | 102 | err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i])); |
103 | 103 | ||
104 | PDEBUG(DBG_TRACE, "Reading sensor register " | 104 | PDEBUG(D_CONF, "Reading sensor register " |
105 | "0x%x containing 0x%x ", address, *i2c_data); | 105 | "0x%x containing 0x%x ", address, *i2c_data); |
106 | } | 106 | } |
107 | 107 | ||
@@ -135,7 +135,7 @@ int s5k83a_write_sensor(struct sd *sd, const u8 address, | |||
135 | memcpy(p, sensor_urb_skeleton + 16, 4); | 135 | memcpy(p, sensor_urb_skeleton + 16, 4); |
136 | p[3] = i2c_data[i]; | 136 | p[3] = i2c_data[i]; |
137 | p += 4; | 137 | p += 4; |
138 | PDEBUG(DBG_TRACE, "Writing sensor register 0x%x with 0x%x", | 138 | PDEBUG(D_CONF, "Writing sensor register 0x%x with 0x%x", |
139 | address, i2c_data[i]); | 139 | address, i2c_data[i]); |
140 | } | 140 | } |
141 | 141 | ||
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k83a.h b/drivers/media/video/gspca/m5602/m5602_s5k83a.h index 833708eb5a42..ee3ee9cfca1d 100644 --- a/drivers/media/video/gspca/m5602/m5602_s5k83a.h +++ b/drivers/media/video/gspca/m5602/m5602_s5k83a.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Driver for the s5k83a sensor | 2 | * Driver for the s5k83a sensor |
3 | * | 3 | * |
4 | * Copyright (C) 2008 Erik Andren | 4 | * Copyright (C) 2008 Erik Andrén |
5 | * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. | 5 | * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. |
6 | * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br> | 6 | * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br> |
7 | * | 7 | * |
@@ -41,8 +41,6 @@ | |||
41 | /* Kernel module parameters */ | 41 | /* Kernel module parameters */ |
42 | extern int force_sensor; | 42 | extern int force_sensor; |
43 | extern int dump_sensor; | 43 | extern int dump_sensor; |
44 | extern unsigned int m5602_debug; | ||
45 | |||
46 | 44 | ||
47 | int s5k83a_probe(struct sd *sd); | 45 | int s5k83a_probe(struct sd *sd); |
48 | int s5k83a_init(struct sd *sd); | 46 | int s5k83a_init(struct sd *sd); |
diff --git a/drivers/media/video/gspca/m5602/m5602_sensor.h b/drivers/media/video/gspca/m5602/m5602_sensor.h index 930fcaab4416..60c9a48e0c02 100644 --- a/drivers/media/video/gspca/m5602/m5602_sensor.h +++ b/drivers/media/video/gspca/m5602/m5602_sensor.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * USB Driver for ALi m5602 based webcams | 2 | * USB Driver for ALi m5602 based webcams |
3 | * | 3 | * |
4 | * Copyright (C) 2008 Erik Andren | 4 | * Copyright (C) 2008 Erik Andrén |
5 | * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. | 5 | * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. |
6 | * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br> | 6 | * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br> |
7 | * | 7 | * |
diff --git a/drivers/media/video/gspca/t613.c b/drivers/media/video/gspca/t613.c index b561f7c4f066..eac245d7a756 100644 --- a/drivers/media/video/gspca/t613.c +++ b/drivers/media/video/gspca/t613.c | |||
@@ -50,7 +50,7 @@ struct sd { | |||
50 | 50 | ||
51 | __u8 sensor; | 51 | __u8 sensor; |
52 | #define SENSOR_TAS5130A 0 | 52 | #define SENSOR_TAS5130A 0 |
53 | #define SENSOR_OTHER 1 | 53 | #define SENSOR_OM6802 1 |
54 | }; | 54 | }; |
55 | 55 | ||
56 | /* V4L2 controls supported by the driver */ | 56 | /* V4L2 controls supported by the driver */ |
@@ -188,7 +188,7 @@ static struct ctrl sd_ctrls[] = { | |||
188 | .minimum = 0, | 188 | .minimum = 0, |
189 | .maximum = 1, | 189 | .maximum = 1, |
190 | .step = 1, | 190 | .step = 1, |
191 | .default_value = 1, | 191 | .default_value = 0, |
192 | }, | 192 | }, |
193 | .set = sd_setwhitebalance, | 193 | .set = sd_setwhitebalance, |
194 | .get = sd_getwhitebalance | 194 | .get = sd_getwhitebalance |
@@ -261,6 +261,59 @@ static struct v4l2_pix_format vga_mode_t16[] = { | |||
261 | .priv = 0}, | 261 | .priv = 0}, |
262 | }; | 262 | }; |
263 | 263 | ||
264 | /* sensor specific data */ | ||
265 | struct additional_sensor_data { | ||
266 | const __u8 data1[20]; | ||
267 | const __u8 data2[18]; | ||
268 | const __u8 data3[18]; | ||
269 | const __u8 data4[4]; | ||
270 | const __u8 data5[6]; | ||
271 | const __u8 stream[4]; | ||
272 | }; | ||
273 | |||
274 | const static struct additional_sensor_data sensor_data[] = { | ||
275 | { /* TAS5130A */ | ||
276 | .data1 = | ||
277 | {0xd0, 0xbb, 0xd1, 0x28, 0xd2, 0x10, 0xd3, 0x10, | ||
278 | 0xd4, 0xbb, 0xd5, 0x28, 0xd6, 0x1e, 0xd7, 0x27, | ||
279 | 0xd8, 0xc8, 0xd9, 0xfc}, | ||
280 | .data2 = | ||
281 | {0xe0, 0x60, 0xe1, 0xa8, 0xe2, 0xe0, 0xe3, 0x60, | ||
282 | 0xe4, 0xa8, 0xe5, 0xe0, 0xe6, 0x60, 0xe7, 0xa8, | ||
283 | 0xe8, 0xe0}, | ||
284 | .data3 = | ||
285 | {0xc7, 0x60, 0xc8, 0xa8, 0xc9, 0xe0, 0xca, 0x60, | ||
286 | 0xcb, 0xa8, 0xcc, 0xe0, 0xcd, 0x60, 0xce, 0xa8, | ||
287 | 0xcf, 0xe0}, | ||
288 | .data4 = /* Freq (50/60Hz). Splitted for test purpose */ | ||
289 | {0x66, 0x00, 0xa8, 0xe8}, | ||
290 | .data5 = | ||
291 | {0x0c, 0x03, 0xab, 0x10, 0x81, 0x20}, | ||
292 | .stream = | ||
293 | {0x0b, 0x04, 0x0a, 0x40}, | ||
294 | }, | ||
295 | { /* OM6802 */ | ||
296 | .data1 = | ||
297 | {0xd0, 0xc2, 0xd1, 0x28, 0xd2, 0x0f, 0xd3, 0x22, | ||
298 | 0xd4, 0xcd, 0xd5, 0x27, 0xd6, 0x2c, 0xd7, 0x06, | ||
299 | 0xd8, 0xb3, 0xd9, 0xfc}, | ||
300 | .data2 = | ||
301 | {0xe0, 0x80, 0xe1, 0xff, 0xe2, 0xff, 0xe3, 0x80, | ||
302 | 0xe4, 0xff, 0xe5, 0xff, 0xe6, 0x80, 0xe7, 0xff, | ||
303 | 0xe8, 0xff}, | ||
304 | .data3 = | ||
305 | {0xc7, 0x80, 0xc8, 0xff, 0xc9, 0xff, 0xca, 0x80, | ||
306 | 0xcb, 0xff, 0xcc, 0xff, 0xcd, 0x80, 0xce, 0xff, | ||
307 | 0xcf, 0xff}, | ||
308 | .data4 = /*Freq (50/60Hz). Splitted for test purpose */ | ||
309 | {0x66, 0xca, 0xa8, 0xf0 }, | ||
310 | .data5 = /* this could be removed later */ | ||
311 | {0x0c, 0x03, 0xab, 0x13, 0x81, 0x23}, | ||
312 | .stream = | ||
313 | {0x0b, 0x04, 0x0a, 0x78}, | ||
314 | } | ||
315 | }; | ||
316 | |||
264 | #define MAX_EFFECTS 7 | 317 | #define MAX_EFFECTS 7 |
265 | /* easily done by soft, this table could be removed, | 318 | /* easily done by soft, this table could be removed, |
266 | * i keep it here just in case */ | 319 | * i keep it here just in case */ |
@@ -365,6 +418,8 @@ static const __u8 tas5130a_sensor_init[][8] = { | |||
365 | {}, | 418 | {}, |
366 | }; | 419 | }; |
367 | 420 | ||
421 | static __u8 sensor_reset[] = {0x61, 0x68, 0x62, 0xff, 0x60, 0x07}; | ||
422 | |||
368 | /* read 1 byte */ | 423 | /* read 1 byte */ |
369 | static int reg_r(struct gspca_dev *gspca_dev, | 424 | static int reg_r(struct gspca_dev *gspca_dev, |
370 | __u16 index) | 425 | __u16 index) |
@@ -385,12 +440,12 @@ static void reg_w(struct gspca_dev *gspca_dev, | |||
385 | usb_control_msg(gspca_dev->dev, | 440 | usb_control_msg(gspca_dev->dev, |
386 | usb_sndctrlpipe(gspca_dev->dev, 0), | 441 | usb_sndctrlpipe(gspca_dev->dev, 0), |
387 | 0, | 442 | 0, |
388 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, | 443 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
389 | 0, index, | 444 | 0, index, |
390 | NULL, 0, 500); | 445 | NULL, 0, 500); |
391 | } | 446 | } |
392 | 447 | ||
393 | static void i2c_w(struct gspca_dev *gspca_dev, | 448 | static void reg_w_buf(struct gspca_dev *gspca_dev, |
394 | const __u8 *buffer, __u16 len) | 449 | const __u8 *buffer, __u16 len) |
395 | { | 450 | { |
396 | if (len <= USB_BUF_SZ) { | 451 | if (len <= USB_BUF_SZ) { |
@@ -398,7 +453,7 @@ static void i2c_w(struct gspca_dev *gspca_dev, | |||
398 | usb_control_msg(gspca_dev->dev, | 453 | usb_control_msg(gspca_dev->dev, |
399 | usb_sndctrlpipe(gspca_dev->dev, 0), | 454 | usb_sndctrlpipe(gspca_dev->dev, 0), |
400 | 0, | 455 | 0, |
401 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, | 456 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
402 | 0x01, 0, | 457 | 0x01, 0, |
403 | gspca_dev->usb_buf, len, 500); | 458 | gspca_dev->usb_buf, len, 500); |
404 | } else { | 459 | } else { |
@@ -409,14 +464,15 @@ static void i2c_w(struct gspca_dev *gspca_dev, | |||
409 | usb_control_msg(gspca_dev->dev, | 464 | usb_control_msg(gspca_dev->dev, |
410 | usb_sndctrlpipe(gspca_dev->dev, 0), | 465 | usb_sndctrlpipe(gspca_dev->dev, 0), |
411 | 0, | 466 | 0, |
412 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, | 467 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
413 | 0x01, 0, | 468 | 0x01, 0, |
414 | tmpbuf, len, 500); | 469 | tmpbuf, len, 500); |
415 | kfree(tmpbuf); | 470 | kfree(tmpbuf); |
416 | } | 471 | } |
417 | } | 472 | } |
418 | 473 | ||
419 | static void other_sensor_init(struct gspca_dev *gspca_dev) | 474 | /* Reported as OM6802*/ |
475 | static void om6802_sensor_init(struct gspca_dev *gspca_dev) | ||
420 | { | 476 | { |
421 | int i; | 477 | int i; |
422 | const __u8 *p; | 478 | const __u8 *p; |
@@ -436,19 +492,32 @@ static void other_sensor_init(struct gspca_dev *gspca_dev) | |||
436 | 0x90, 0x24, | 492 | 0x90, 0x24, |
437 | 0x91, 0xb2, | 493 | 0x91, 0xb2, |
438 | 0x82, 0x32, | 494 | 0x82, 0x32, |
439 | 0xfd, 0x00, | ||
440 | 0xfd, 0x01, | ||
441 | 0xfd, 0x41, | 495 | 0xfd, 0x41, |
442 | 0x00 /* table end */ | 496 | 0x00 /* table end */ |
443 | }; | 497 | }; |
444 | 498 | ||
499 | reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset); | ||
500 | msleep(5); | ||
501 | i = 4; | ||
502 | while (--i < 0) { | ||
503 | byte = reg_r(gspca_dev, 0x0060); | ||
504 | if (!(byte & 0x01)) | ||
505 | break; | ||
506 | msleep(100); | ||
507 | } | ||
508 | byte = reg_r(gspca_dev, 0x0063); | ||
509 | if (byte != 0x17) { | ||
510 | err("Bad sensor reset %02x", byte); | ||
511 | /* continue? */ | ||
512 | } | ||
513 | |||
445 | p = sensor_init; | 514 | p = sensor_init; |
446 | while (*p != 0) { | 515 | while (*p != 0) { |
447 | val[1] = *p++; | 516 | val[1] = *p++; |
448 | val[3] = *p++; | 517 | val[3] = *p++; |
449 | if (*p == 0) | 518 | if (*p == 0) |
450 | reg_w(gspca_dev, 0x3c80); | 519 | reg_w(gspca_dev, 0x3c80); |
451 | i2c_w(gspca_dev, val, sizeof val); | 520 | reg_w_buf(gspca_dev, val, sizeof val); |
452 | i = 4; | 521 | i = 4; |
453 | while (--i >= 0) { | 522 | while (--i >= 0) { |
454 | msleep(15); | 523 | msleep(15); |
@@ -457,7 +526,8 @@ static void other_sensor_init(struct gspca_dev *gspca_dev) | |||
457 | break; | 526 | break; |
458 | } | 527 | } |
459 | } | 528 | } |
460 | reg_w(gspca_dev, 0x3c80); | 529 | msleep(15); |
530 | reg_w(gspca_dev, 0x3c80); | ||
461 | } | 531 | } |
462 | 532 | ||
463 | /* this function is called at probe time */ | 533 | /* this function is called at probe time */ |
@@ -485,12 +555,75 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
485 | return 0; | 555 | return 0; |
486 | } | 556 | } |
487 | 557 | ||
558 | static void setbrightness(struct gspca_dev *gspca_dev) | ||
559 | { | ||
560 | struct sd *sd = (struct sd *) gspca_dev; | ||
561 | unsigned int brightness; | ||
562 | __u8 set6[4] = { 0x8f, 0x24, 0xc3, 0x00 }; | ||
563 | |||
564 | brightness = sd->brightness; | ||
565 | if (brightness < 7) { | ||
566 | set6[1] = 0x26; | ||
567 | set6[3] = 0x70 - brightness * 0x10; | ||
568 | } else { | ||
569 | set6[3] = 0x00 + ((brightness - 7) * 0x10); | ||
570 | } | ||
571 | |||
572 | reg_w_buf(gspca_dev, set6, sizeof set6); | ||
573 | } | ||
574 | |||
575 | static void setcontrast(struct gspca_dev *gspca_dev) | ||
576 | { | ||
577 | struct sd *sd = (struct sd *) gspca_dev; | ||
578 | unsigned int contrast = sd->contrast; | ||
579 | __u16 reg_to_write; | ||
580 | |||
581 | if (contrast < 7) | ||
582 | reg_to_write = 0x8ea9 - contrast * 0x200; | ||
583 | else | ||
584 | reg_to_write = 0x00a9 + (contrast - 7) * 0x200; | ||
585 | |||
586 | reg_w(gspca_dev, reg_to_write); | ||
587 | } | ||
588 | |||
589 | static void setcolors(struct gspca_dev *gspca_dev) | ||
590 | { | ||
591 | struct sd *sd = (struct sd *) gspca_dev; | ||
592 | __u16 reg_to_write; | ||
593 | |||
594 | reg_to_write = 0x80bb + sd->colors * 0x100; /* was 0xc0 */ | ||
595 | reg_w(gspca_dev, reg_to_write); | ||
596 | } | ||
597 | |||
488 | static void setgamma(struct gspca_dev *gspca_dev) | 598 | static void setgamma(struct gspca_dev *gspca_dev) |
489 | { | 599 | { |
490 | struct sd *sd = (struct sd *) gspca_dev; | 600 | struct sd *sd = (struct sd *) gspca_dev; |
491 | 601 | ||
492 | PDEBUG(D_CONF, "Gamma: %d", sd->gamma); | 602 | PDEBUG(D_CONF, "Gamma: %d", sd->gamma); |
493 | i2c_w(gspca_dev, gamma_table[sd->gamma], sizeof gamma_table[0]); | 603 | reg_w_buf(gspca_dev, gamma_table[sd->gamma], sizeof gamma_table[0]); |
604 | } | ||
605 | |||
606 | static void setwhitebalance(struct gspca_dev *gspca_dev) | ||
607 | { | ||
608 | struct sd *sd = (struct sd *) gspca_dev; | ||
609 | |||
610 | __u8 white_balance[8] = | ||
611 | {0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x80, 0x38}; | ||
612 | |||
613 | if (sd->whitebalance) | ||
614 | white_balance[7] = 0x3c; | ||
615 | |||
616 | reg_w_buf(gspca_dev, white_balance, sizeof white_balance); | ||
617 | } | ||
618 | |||
619 | static void setsharpness(struct gspca_dev *gspca_dev) | ||
620 | { | ||
621 | struct sd *sd = (struct sd *) gspca_dev; | ||
622 | __u16 reg_to_write; | ||
623 | |||
624 | reg_to_write = 0x0aa6 + 0x1000 * sd->sharpness; | ||
625 | |||
626 | reg_w(gspca_dev, reg_to_write); | ||
494 | } | 627 | } |
495 | 628 | ||
496 | /* this function is called at probe and resume time */ | 629 | /* this function is called at probe and resume time */ |
@@ -511,8 +644,6 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
511 | {0x08, 0x03, 0x09, 0x03, 0x12, 0x04}; | 644 | {0x08, 0x03, 0x09, 0x03, 0x12, 0x04}; |
512 | static const __u8 n2[] = | 645 | static const __u8 n2[] = |
513 | {0x08, 0x00}; | 646 | {0x08, 0x00}; |
514 | static const __u8 nset[] = | ||
515 | { 0x61, 0x68, 0x62, 0xff, 0x60, 0x07 }; | ||
516 | static const __u8 n3[] = | 647 | static const __u8 n3[] = |
517 | {0x61, 0x68, 0x65, 0x0a, 0x60, 0x04}; | 648 | {0x61, 0x68, 0x65, 0x0a, 0x60, 0x04}; |
518 | static const __u8 n4[] = | 649 | static const __u8 n4[] = |
@@ -525,51 +656,29 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
525 | 0x65, 0x0a, 0xbb, 0x86, 0xaf, 0x58, 0xb0, 0x68, | 656 | 0x65, 0x0a, 0xbb, 0x86, 0xaf, 0x58, 0xb0, 0x68, |
526 | 0x87, 0x40, 0x89, 0x2b, 0x8d, 0xff, 0x83, 0x40, | 657 | 0x87, 0x40, 0x89, 0x2b, 0x8d, 0xff, 0x83, 0x40, |
527 | 0xac, 0x84, 0xad, 0x86, 0xaf, 0x46}; | 658 | 0xac, 0x84, 0xad, 0x86, 0xaf, 0x46}; |
528 | static const __u8 nset4[] = { | ||
529 | 0xe0, 0x60, 0xe1, 0xa8, 0xe2, 0xe0, 0xe3, 0x60, 0xe4, 0xa8, | ||
530 | 0xe5, 0xe0, 0xe6, 0x60, 0xe7, 0xa8, | ||
531 | 0xe8, 0xe0 | ||
532 | }; | ||
533 | /* ojo puede ser 0xe6 en vez de 0xe9 */ | ||
534 | static const __u8 nset2[] = { | ||
535 | 0xd0, 0xbb, 0xd1, 0x28, 0xd2, 0x10, 0xd3, 0x10, 0xd4, 0xbb, | ||
536 | 0xd5, 0x28, 0xd6, 0x1e, 0xd7, 0x27, | ||
537 | 0xd8, 0xc8, 0xd9, 0xfc | ||
538 | }; | ||
539 | static const __u8 missing[] = | ||
540 | { 0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x80, 0x38 }; | ||
541 | static const __u8 nset3[] = { | ||
542 | 0xc7, 0x60, 0xc8, 0xa8, 0xc9, 0xe0, 0xca, 0x60, 0xcb, 0xa8, | ||
543 | 0xcc, 0xe0, 0xcd, 0x60, 0xce, 0xa8, | ||
544 | 0xcf, 0xe0 | ||
545 | }; | ||
546 | static const __u8 nset5[] = | ||
547 | { 0x8f, 0x24, 0xc3, 0x00 }; /* bright */ | ||
548 | static const __u8 nset7[4] = | ||
549 | { 0x66, 0xca, 0xa8, 0xf8 }; /* 50/60 Hz */ | ||
550 | static const __u8 nset9[4] = | 659 | static const __u8 nset9[4] = |
551 | { 0x0b, 0x04, 0x0a, 0x78 }; | 660 | { 0x0b, 0x04, 0x0a, 0x78 }; |
552 | static const __u8 nset8[6] = | 661 | static const __u8 nset8[6] = |
553 | { 0xa8, 0xf0, 0xc6, 0x88, 0xc0, 0x00 }; | 662 | { 0xa8, 0xf0, 0xc6, 0x88, 0xc0, 0x00 }; |
554 | static const __u8 nset10[6] = | ||
555 | { 0x0c, 0x03, 0xab, 0x10, 0x81, 0x20 }; | ||
556 | 663 | ||
557 | byte = reg_r(gspca_dev, 0x06); | 664 | byte = reg_r(gspca_dev, 0x06); |
558 | test_byte = reg_r(gspca_dev, 0x07); | 665 | test_byte = reg_r(gspca_dev, 0x07); |
559 | if (byte == 0x08 && test_byte == 0x07) { | 666 | if (byte == 0x08 && test_byte == 0x07) { |
560 | PDEBUG(D_CONF, "other sensor"); | 667 | PDEBUG(D_CONF, "sensor om6802"); |
561 | sd->sensor = SENSOR_OTHER; | 668 | sd->sensor = SENSOR_OM6802; |
669 | } else if (byte == 0x08 && test_byte == 0x01) { | ||
670 | PDEBUG(D_CONF, "sensor tas5130a"); | ||
671 | sd->sensor = SENSOR_TAS5130A; | ||
562 | } else { | 672 | } else { |
563 | PDEBUG(D_CONF, "sensor %02x %02x", byte, test_byte); | 673 | PDEBUG(D_CONF, "unknown sensor %02x %02x", byte, test_byte); |
564 | sd->sensor = SENSOR_TAS5130A; | 674 | sd->sensor = SENSOR_TAS5130A; |
565 | } | 675 | } |
566 | 676 | ||
567 | i2c_w(gspca_dev, n1, sizeof n1); | 677 | reg_w_buf(gspca_dev, n1, sizeof n1); |
568 | test_byte = 0; | 678 | test_byte = 0; |
569 | i = 5; | 679 | i = 5; |
570 | while (--i >= 0) { | 680 | while (--i >= 0) { |
571 | i2c_w(gspca_dev, nset, sizeof nset); | 681 | reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset); |
572 | msleep(5); | ||
573 | test_byte = reg_r(gspca_dev, 0x0063); | 682 | test_byte = reg_r(gspca_dev, 0x0063); |
574 | msleep(100); | 683 | msleep(100); |
575 | if (test_byte == 0x17) | 684 | if (test_byte == 0x17) |
@@ -580,7 +689,7 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
580 | /* return -EIO; */ | 689 | /* return -EIO; */ |
581 | /*fixme: test - continue */ | 690 | /*fixme: test - continue */ |
582 | } | 691 | } |
583 | i2c_w(gspca_dev, n2, sizeof n2); | 692 | reg_w_buf(gspca_dev, n2, sizeof n2); |
584 | 693 | ||
585 | i = 0; | 694 | i = 0; |
586 | while (read_indexs[i] != 0x00) { | 695 | while (read_indexs[i] != 0x00) { |
@@ -590,56 +699,50 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
590 | i++; | 699 | i++; |
591 | } | 700 | } |
592 | 701 | ||
593 | i2c_w(gspca_dev, n3, sizeof n3); | 702 | reg_w_buf(gspca_dev, n3, sizeof n3); |
594 | i2c_w(gspca_dev, n4, sizeof n4); | 703 | reg_w_buf(gspca_dev, n4, sizeof n4); |
595 | reg_r(gspca_dev, 0x0080); | 704 | reg_r(gspca_dev, 0x0080); |
596 | reg_w(gspca_dev, 0x2c80); | 705 | reg_w(gspca_dev, 0x2c80); |
597 | i2c_w(gspca_dev, nset2, sizeof nset2); | 706 | |
598 | i2c_w(gspca_dev, nset3, sizeof nset3); | 707 | reg_w_buf(gspca_dev, sensor_data[sd->sensor].data1, |
599 | i2c_w(gspca_dev, nset4, sizeof nset4); | 708 | sizeof sensor_data[sd->sensor].data1); |
709 | reg_w_buf(gspca_dev, sensor_data[sd->sensor].data3, | ||
710 | sizeof sensor_data[sd->sensor].data3); | ||
711 | reg_w_buf(gspca_dev, sensor_data[sd->sensor].data2, | ||
712 | sizeof sensor_data[sd->sensor].data2); | ||
713 | |||
600 | reg_w(gspca_dev, 0x3880); | 714 | reg_w(gspca_dev, 0x3880); |
601 | reg_w(gspca_dev, 0x3880); | 715 | reg_w(gspca_dev, 0x3880); |
602 | reg_w(gspca_dev, 0x338e); | 716 | reg_w(gspca_dev, 0x338e); |
603 | i2c_w(gspca_dev, nset5, sizeof nset5); | ||
604 | reg_w(gspca_dev, 0x00a9); | ||
605 | setgamma(gspca_dev); | ||
606 | reg_w(gspca_dev, 0x86bb); | ||
607 | reg_w(gspca_dev, 0x4aa6); | ||
608 | 717 | ||
609 | i2c_w(gspca_dev, missing, sizeof missing); | 718 | setbrightness(gspca_dev); |
719 | setcontrast(gspca_dev); | ||
720 | setgamma(gspca_dev); | ||
721 | setcolors(gspca_dev); | ||
722 | setsharpness(gspca_dev); | ||
723 | setwhitebalance(gspca_dev); | ||
610 | 724 | ||
611 | reg_w(gspca_dev, 0x2087); | 725 | reg_w(gspca_dev, 0x2087); /* tied to white balance? */ |
612 | reg_w(gspca_dev, 0x2088); | 726 | reg_w(gspca_dev, 0x2088); |
613 | reg_w(gspca_dev, 0x2089); | 727 | reg_w(gspca_dev, 0x2089); |
614 | 728 | ||
615 | i2c_w(gspca_dev, nset7, sizeof nset7); | 729 | reg_w_buf(gspca_dev, sensor_data[sd->sensor].data4, |
616 | i2c_w(gspca_dev, nset10, sizeof nset10); | 730 | sizeof sensor_data[sd->sensor].data4); |
617 | i2c_w(gspca_dev, nset8, sizeof nset8); | 731 | reg_w_buf(gspca_dev, sensor_data[sd->sensor].data5, |
618 | i2c_w(gspca_dev, nset9, sizeof nset9); | 732 | sizeof sensor_data[sd->sensor].data5); |
733 | reg_w_buf(gspca_dev, nset8, sizeof nset8); | ||
734 | reg_w_buf(gspca_dev, nset9, sizeof nset9); | ||
619 | 735 | ||
620 | reg_w(gspca_dev, 0x2880); | 736 | reg_w(gspca_dev, 0x2880); |
621 | i2c_w(gspca_dev, nset2, sizeof nset2); | ||
622 | i2c_w(gspca_dev, nset3, sizeof nset3); | ||
623 | i2c_w(gspca_dev, nset4, sizeof nset4); | ||
624 | |||
625 | return 0; | ||
626 | } | ||
627 | |||
628 | static void setbrightness(struct gspca_dev *gspca_dev) | ||
629 | { | ||
630 | struct sd *sd = (struct sd *) gspca_dev; | ||
631 | unsigned int brightness; | ||
632 | __u8 set6[4] = { 0x8f, 0x26, 0xc3, 0x00 }; | ||
633 | 737 | ||
634 | brightness = sd->brightness; | 738 | reg_w_buf(gspca_dev, sensor_data[sd->sensor].data1, |
635 | if (brightness < 7) { | 739 | sizeof sensor_data[sd->sensor].data1); |
636 | set6[3] = 0x70 - brightness * 0x10; | 740 | reg_w_buf(gspca_dev, sensor_data[sd->sensor].data3, |
637 | } else { | 741 | sizeof sensor_data[sd->sensor].data3); |
638 | set6[1] = 0x24; | 742 | reg_w_buf(gspca_dev, sensor_data[sd->sensor].data2, |
639 | set6[3] = 0x00 + ((brightness - 7) * 0x10); | 743 | sizeof sensor_data[sd->sensor].data2); |
640 | } | ||
641 | 744 | ||
642 | i2c_w(gspca_dev, set6, sizeof set6); | 745 | return 0; |
643 | } | 746 | } |
644 | 747 | ||
645 | static void setflip(struct gspca_dev *gspca_dev) | 748 | static void setflip(struct gspca_dev *gspca_dev) |
@@ -651,14 +754,15 @@ static void setflip(struct gspca_dev *gspca_dev) | |||
651 | if (sd->mirror) | 754 | if (sd->mirror) |
652 | flipcmd[3] = 0x01; | 755 | flipcmd[3] = 0x01; |
653 | 756 | ||
654 | i2c_w(gspca_dev, flipcmd, sizeof flipcmd); | 757 | reg_w_buf(gspca_dev, flipcmd, sizeof flipcmd); |
655 | } | 758 | } |
656 | 759 | ||
657 | static void seteffect(struct gspca_dev *gspca_dev) | 760 | static void seteffect(struct gspca_dev *gspca_dev) |
658 | { | 761 | { |
659 | struct sd *sd = (struct sd *) gspca_dev; | 762 | struct sd *sd = (struct sd *) gspca_dev; |
660 | 763 | ||
661 | i2c_w(gspca_dev, effects_table[sd->effect], sizeof effects_table[0]); | 764 | reg_w_buf(gspca_dev, effects_table[sd->effect], |
765 | sizeof effects_table[0]); | ||
662 | if (sd->effect == 1 || sd->effect == 5) { | 766 | if (sd->effect == 1 || sd->effect == 5) { |
663 | PDEBUG(D_CONF, | 767 | PDEBUG(D_CONF, |
664 | "This effect have been disabled for webcam \"safety\""); | 768 | "This effect have been disabled for webcam \"safety\""); |
@@ -671,19 +775,6 @@ static void seteffect(struct gspca_dev *gspca_dev) | |||
671 | reg_w(gspca_dev, 0xfaa6); | 775 | reg_w(gspca_dev, 0xfaa6); |
672 | } | 776 | } |
673 | 777 | ||
674 | static void setwhitebalance(struct gspca_dev *gspca_dev) | ||
675 | { | ||
676 | struct sd *sd = (struct sd *) gspca_dev; | ||
677 | |||
678 | __u8 white_balance[8] = | ||
679 | { 0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x80, 0x38 }; | ||
680 | |||
681 | if (sd->whitebalance == 1) | ||
682 | white_balance[7] = 0x3c; | ||
683 | |||
684 | i2c_w(gspca_dev, white_balance, sizeof white_balance); | ||
685 | } | ||
686 | |||
687 | static void setlightfreq(struct gspca_dev *gspca_dev) | 778 | static void setlightfreq(struct gspca_dev *gspca_dev) |
688 | { | 779 | { |
689 | struct sd *sd = (struct sd *) gspca_dev; | 780 | struct sd *sd = (struct sd *) gspca_dev; |
@@ -692,52 +783,46 @@ static void setlightfreq(struct gspca_dev *gspca_dev) | |||
692 | if (sd->freq == 2) /* 60hz */ | 783 | if (sd->freq == 2) /* 60hz */ |
693 | freq[1] = 0x00; | 784 | freq[1] = 0x00; |
694 | 785 | ||
695 | i2c_w(gspca_dev, freq, sizeof freq); | 786 | reg_w_buf(gspca_dev, freq, sizeof freq); |
696 | } | 787 | } |
697 | 788 | ||
698 | static void setcontrast(struct gspca_dev *gspca_dev) | 789 | /* Is this really needed? |
790 | * i added some module parameters for test with some users */ | ||
791 | static void poll_sensor(struct gspca_dev *gspca_dev) | ||
699 | { | 792 | { |
700 | struct sd *sd = (struct sd *) gspca_dev; | 793 | struct sd *sd = (struct sd *) gspca_dev; |
701 | unsigned int contrast = sd->contrast; | 794 | static const __u8 poll1[] = |
702 | __u16 reg_to_write; | 795 | {0x67, 0x05, 0x68, 0x81, 0x69, 0x80, 0x6a, 0x82, |
703 | 796 | 0x6b, 0x68, 0x6c, 0x69, 0x72, 0xd9, 0x73, 0x34, | |
704 | if (contrast < 7) | 797 | 0x74, 0x32, 0x75, 0x92, 0x76, 0x00, 0x09, 0x01, |
705 | reg_to_write = 0x8ea9 - (0x200 * contrast); | 798 | 0x60, 0x14}; |
706 | else | 799 | static const __u8 poll2[] = |
707 | reg_to_write = (0x00a9 + ((contrast - 7) * 0x200)); | 800 | {0x67, 0x02, 0x68, 0x71, 0x69, 0x72, 0x72, 0xa9, |
708 | 801 | 0x73, 0x02, 0x73, 0x02, 0x60, 0x14}; | |
709 | reg_w(gspca_dev, reg_to_write); | 802 | static const __u8 poll3[] = |
710 | } | 803 | {0x87, 0x3f, 0x88, 0x20, 0x89, 0x2d}; |
711 | 804 | static const __u8 poll4[] = | |
712 | static void setcolors(struct gspca_dev *gspca_dev) | 805 | {0xa6, 0x0a, 0xea, 0xcf, 0xbe, 0x26, 0xb1, 0x5f, |
713 | { | 806 | 0xa1, 0xb1, 0xda, 0x6b, 0xdb, 0x98, 0xdf, 0x0c, |
714 | struct sd *sd = (struct sd *) gspca_dev; | 807 | 0xc2, 0x80, 0xc3, 0x10}; |
715 | __u16 reg_to_write; | 808 | |
716 | 809 | if (sd->sensor != SENSOR_TAS5130A) { | |
717 | reg_to_write = 0xc0bb + sd->colors * 0x100; | 810 | PDEBUG(D_STREAM, "[Sensor requires polling]"); |
718 | reg_w(gspca_dev, reg_to_write); | 811 | reg_w_buf(gspca_dev, poll1, sizeof poll1); |
719 | } | 812 | reg_w_buf(gspca_dev, poll2, sizeof poll2); |
720 | 813 | reg_w_buf(gspca_dev, poll3, sizeof poll3); | |
721 | static void setsharpness(struct gspca_dev *gspca_dev) | 814 | reg_w_buf(gspca_dev, poll4, sizeof poll4); |
722 | { | 815 | } |
723 | struct sd *sd = (struct sd *) gspca_dev; | ||
724 | __u16 reg_to_write; | ||
725 | |||
726 | reg_to_write = 0x0aa6 + 0x1000 * sd->sharpness; | ||
727 | |||
728 | reg_w(gspca_dev, reg_to_write); | ||
729 | } | 816 | } |
730 | 817 | ||
731 | static int sd_start(struct gspca_dev *gspca_dev) | 818 | static int sd_start(struct gspca_dev *gspca_dev) |
732 | { | 819 | { |
733 | struct sd *sd = (struct sd *) gspca_dev; | 820 | struct sd *sd = (struct sd *) gspca_dev; |
734 | int i, mode; | 821 | int i, mode; |
735 | static const __u8 t1[] = { 0x66, 0x00, 0xa8, 0xe8 }; | ||
736 | __u8 t2[] = { 0x07, 0x00, 0x0d, 0x60, 0x0e, 0x80 }; | 822 | __u8 t2[] = { 0x07, 0x00, 0x0d, 0x60, 0x0e, 0x80 }; |
737 | static const __u8 t3[] = | 823 | static const __u8 t3[] = |
738 | { 0xb3, 0x07, 0xb4, 0x00, 0xb5, 0x88, 0xb6, 0x02, 0xb7, 0x06, | 824 | { 0xb3, 0x07, 0xb4, 0x00, 0xb5, 0x88, 0xb6, 0x02, 0xb7, 0x06, |
739 | 0xb8, 0x00, 0xb9, 0xe7, 0xba, 0x01 }; | 825 | 0xb8, 0x00, 0xb9, 0xe7, 0xba, 0x01 }; |
740 | static const __u8 t4[] = { 0x0b, 0x04, 0x0a, 0x40 }; | ||
741 | 826 | ||
742 | mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode]. priv; | 827 | mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode]. priv; |
743 | switch (mode) { | 828 | switch (mode) { |
@@ -760,25 +845,29 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
760 | if (sd->sensor == SENSOR_TAS5130A) { | 845 | if (sd->sensor == SENSOR_TAS5130A) { |
761 | i = 0; | 846 | i = 0; |
762 | while (tas5130a_sensor_init[i][0] != 0) { | 847 | while (tas5130a_sensor_init[i][0] != 0) { |
763 | i2c_w(gspca_dev, tas5130a_sensor_init[i], | 848 | reg_w_buf(gspca_dev, tas5130a_sensor_init[i], |
764 | sizeof tas5130a_sensor_init[0]); | 849 | sizeof tas5130a_sensor_init[0]); |
765 | i++; | 850 | i++; |
766 | } | 851 | } |
767 | reg_w(gspca_dev, 0x3c80); | 852 | reg_w(gspca_dev, 0x3c80); |
768 | /* just in case and to keep sync with logs (for mine) */ | 853 | /* just in case and to keep sync with logs (for mine) */ |
769 | i2c_w(gspca_dev, tas5130a_sensor_init[3], | 854 | reg_w_buf(gspca_dev, tas5130a_sensor_init[3], |
770 | sizeof tas5130a_sensor_init[0]); | 855 | sizeof tas5130a_sensor_init[0]); |
771 | reg_w(gspca_dev, 0x3c80); | 856 | reg_w(gspca_dev, 0x3c80); |
772 | } else { | 857 | } else { |
773 | other_sensor_init(gspca_dev); | 858 | om6802_sensor_init(gspca_dev); |
774 | } | 859 | } |
775 | /* just in case and to keep sync with logs (for mine) */ | 860 | reg_w_buf(gspca_dev, sensor_data[sd->sensor].data4, |
776 | i2c_w(gspca_dev, t1, sizeof t1); | 861 | sizeof sensor_data[sd->sensor].data4); |
777 | i2c_w(gspca_dev, t2, sizeof t2); | ||
778 | reg_r(gspca_dev, 0x0012); | 862 | reg_r(gspca_dev, 0x0012); |
779 | i2c_w(gspca_dev, t3, sizeof t3); | 863 | reg_w_buf(gspca_dev, t2, sizeof t2); |
864 | reg_w_buf(gspca_dev, t3, sizeof t3); | ||
780 | reg_w(gspca_dev, 0x0013); | 865 | reg_w(gspca_dev, 0x0013); |
781 | i2c_w(gspca_dev, t4, sizeof t4); | 866 | msleep(15); |
867 | reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream, | ||
868 | sizeof sensor_data[sd->sensor].stream); | ||
869 | poll_sensor(gspca_dev); | ||
870 | |||
782 | /* restart on each start, just in case, sometimes regs goes wrong | 871 | /* restart on each start, just in case, sometimes regs goes wrong |
783 | * when using controls from app */ | 872 | * when using controls from app */ |
784 | setbrightness(gspca_dev); | 873 | setbrightness(gspca_dev); |
@@ -787,6 +876,19 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
787 | return 0; | 876 | return 0; |
788 | } | 877 | } |
789 | 878 | ||
879 | static void sd_stopN(struct gspca_dev *gspca_dev) | ||
880 | { | ||
881 | struct sd *sd = (struct sd *) gspca_dev; | ||
882 | |||
883 | reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream, | ||
884 | sizeof sensor_data[sd->sensor].stream); | ||
885 | msleep(20); | ||
886 | reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream, | ||
887 | sizeof sensor_data[sd->sensor].stream); | ||
888 | msleep(20); | ||
889 | reg_w(gspca_dev, 0x0309); | ||
890 | } | ||
891 | |||
790 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | 892 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, |
791 | struct gspca_frame *frame, /* target */ | 893 | struct gspca_frame *frame, /* target */ |
792 | __u8 *data, /* isoc packet */ | 894 | __u8 *data, /* isoc packet */ |
@@ -1036,6 +1138,7 @@ static const struct sd_desc sd_desc = { | |||
1036 | .config = sd_config, | 1138 | .config = sd_config, |
1037 | .init = sd_init, | 1139 | .init = sd_init, |
1038 | .start = sd_start, | 1140 | .start = sd_start, |
1141 | .stopN = sd_stopN, | ||
1039 | .pkt_scan = sd_pkt_scan, | 1142 | .pkt_scan = sd_pkt_scan, |
1040 | .querymenu = sd_querymenu, | 1143 | .querymenu = sd_querymenu, |
1041 | }; | 1144 | }; |
diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c index b7457fc60ba5..1c404e454a36 100644 --- a/drivers/media/video/ivtv/ivtv-fileops.c +++ b/drivers/media/video/ivtv/ivtv-fileops.c | |||
@@ -600,13 +600,14 @@ retry: | |||
600 | since we may get here before the stream has been fully set-up */ | 600 | since we may get here before the stream has been fully set-up */ |
601 | if (mode == OUT_YUV && s->q_full.length == 0 && itv->dma_data_req_size) { | 601 | if (mode == OUT_YUV && s->q_full.length == 0 && itv->dma_data_req_size) { |
602 | while (count >= itv->dma_data_req_size) { | 602 | while (count >= itv->dma_data_req_size) { |
603 | if (!ivtv_yuv_udma_stream_frame (itv, (void __user *)user_buf)) { | 603 | rc = ivtv_yuv_udma_stream_frame(itv, (void __user *)user_buf); |
604 | bytes_written += itv->dma_data_req_size; | 604 | |
605 | user_buf += itv->dma_data_req_size; | 605 | if (rc < 0) |
606 | count -= itv->dma_data_req_size; | 606 | return rc; |
607 | } else { | 607 | |
608 | break; | 608 | bytes_written += itv->dma_data_req_size; |
609 | } | 609 | user_buf += itv->dma_data_req_size; |
610 | count -= itv->dma_data_req_size; | ||
610 | } | 611 | } |
611 | if (count == 0) { | 612 | if (count == 0) { |
612 | IVTV_DEBUG_HI_FILE("Wrote %d bytes to %s (%d)\n", bytes_written, s->name, s->q_full.bytesused); | 613 | IVTV_DEBUG_HI_FILE("Wrote %d bytes to %s (%d)\n", bytes_written, s->name, s->q_full.bytesused); |
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c index 8696527ab134..208fb54842f2 100644 --- a/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/drivers/media/video/ivtv/ivtv-ioctl.c | |||
@@ -509,7 +509,6 @@ static int ivtv_try_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_ | |||
509 | static int ivtv_try_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt) | 509 | static int ivtv_try_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt) |
510 | { | 510 | { |
511 | struct ivtv_open_id *id = fh; | 511 | struct ivtv_open_id *id = fh; |
512 | struct ivtv *itv = id->itv; | ||
513 | s32 w = fmt->fmt.pix.width; | 512 | s32 w = fmt->fmt.pix.width; |
514 | s32 h = fmt->fmt.pix.height; | 513 | s32 h = fmt->fmt.pix.height; |
515 | int field = fmt->fmt.pix.field; | 514 | int field = fmt->fmt.pix.field; |
@@ -517,7 +516,22 @@ static int ivtv_try_fmt_vid_out(struct file *file, void *fh, struct v4l2_format | |||
517 | 516 | ||
518 | w = min(w, 720); | 517 | w = min(w, 720); |
519 | w = max(w, 2); | 518 | w = max(w, 2); |
520 | h = min(h, itv->is_out_50hz ? 576 : 480); | 519 | /* Why can the height be 576 even when the output is NTSC? |
520 | |||
521 | Internally the buffers of the PVR350 are always set to 720x576. The | ||
522 | decoded video frame will always be placed in the top left corner of | ||
523 | this buffer. For any video which is not 720x576, the buffer will | ||
524 | then be cropped to remove the unused right and lower areas, with | ||
525 | the remaining image being scaled by the hardware to fit the display | ||
526 | area. The video can be scaled both up and down, so a 720x480 video | ||
527 | can be displayed full-screen on PAL and a 720x576 video can be | ||
528 | displayed without cropping on NTSC. | ||
529 | |||
530 | Note that the scaling only occurs on the video stream, the osd | ||
531 | resolution is locked to the broadcast standard and not scaled. | ||
532 | |||
533 | Thanks to Ian Armstrong for this explanation. */ | ||
534 | h = min(h, 576); | ||
521 | h = max(h, 2); | 535 | h = max(h, 2); |
522 | if (id->type == IVTV_DEC_STREAM_TYPE_YUV) | 536 | if (id->type == IVTV_DEC_STREAM_TYPE_YUV) |
523 | fmt->fmt.pix.field = field; | 537 | fmt->fmt.pix.field = field; |
diff --git a/drivers/media/video/ks0127.c b/drivers/media/video/ks0127.c index 2fd4b4a44aa9..bae2d2beb709 100644 --- a/drivers/media/video/ks0127.c +++ b/drivers/media/video/ks0127.c | |||
@@ -33,27 +33,20 @@ | |||
33 | * V1.1 Gerard v.d. Horst Added some debugoutput, reset the video-standard | 33 | * V1.1 Gerard v.d. Horst Added some debugoutput, reset the video-standard |
34 | */ | 34 | */ |
35 | 35 | ||
36 | #ifndef __KERNEL__ | ||
37 | #define __KERNEL__ | ||
38 | #endif | ||
39 | |||
40 | #include <linux/init.h> | 36 | #include <linux/init.h> |
41 | #include <linux/module.h> | 37 | #include <linux/module.h> |
42 | #include <linux/delay.h> | 38 | #include <linux/delay.h> |
43 | #include <linux/errno.h> | 39 | #include <linux/errno.h> |
44 | #include <linux/kernel.h> | 40 | #include <linux/kernel.h> |
45 | #include <linux/slab.h> | ||
46 | #include <linux/proc_fs.h> | ||
47 | #include "ks0127.h" | ||
48 | |||
49 | #include <linux/i2c.h> | 41 | #include <linux/i2c.h> |
50 | #include <linux/video_decoder.h> | 42 | #include <linux/video_decoder.h> |
43 | #include <media/v4l2-common.h> | ||
44 | #include <media/v4l2-i2c-drv-legacy.h> | ||
45 | #include "ks0127.h" | ||
51 | 46 | ||
52 | #define dprintk if (debug) printk | 47 | MODULE_DESCRIPTION("KS0127 video decoder driver"); |
53 | 48 | MODULE_AUTHOR("Ryan Drake"); | |
54 | /* i2c identification */ | 49 | MODULE_LICENSE("GPL"); |
55 | #define I2C_KS0127_ADDON 0xD8 | ||
56 | #define I2C_KS0127_ONBOARD 0xDA | ||
57 | 50 | ||
58 | #define KS_TYPE_UNKNOWN 0 | 51 | #define KS_TYPE_UNKNOWN 0 |
59 | #define KS_TYPE_0122S 1 | 52 | #define KS_TYPE_0122S 1 |
@@ -204,8 +197,6 @@ struct adjust { | |||
204 | }; | 197 | }; |
205 | 198 | ||
206 | struct ks0127 { | 199 | struct ks0127 { |
207 | struct i2c_client *client; | ||
208 | unsigned char addr; | ||
209 | int format_width; | 200 | int format_width; |
210 | int format_height; | 201 | int format_height; |
211 | int cap_width; | 202 | int cap_width; |
@@ -220,16 +211,18 @@ static int debug; /* insmod parameter */ | |||
220 | 211 | ||
221 | module_param(debug, int, 0); | 212 | module_param(debug, int, 0); |
222 | MODULE_PARM_DESC(debug, "Debug output"); | 213 | MODULE_PARM_DESC(debug, "Debug output"); |
223 | MODULE_LICENSE("GPL"); | ||
224 | 214 | ||
225 | static u8 reg_defaults[64]; | 215 | static u8 reg_defaults[64]; |
226 | 216 | ||
227 | |||
228 | |||
229 | static void init_reg_defaults(void) | 217 | static void init_reg_defaults(void) |
230 | { | 218 | { |
219 | static int initialized; | ||
231 | u8 *table = reg_defaults; | 220 | u8 *table = reg_defaults; |
232 | 221 | ||
222 | if (initialized) | ||
223 | return; | ||
224 | initialized = 1; | ||
225 | |||
233 | table[KS_CMDA] = 0x2c; /* VSE=0, CCIR 601, autodetect standard */ | 226 | table[KS_CMDA] = 0x2c; /* VSE=0, CCIR 601, autodetect standard */ |
234 | table[KS_CMDB] = 0x12; /* VALIGN=0, AGC control and input */ | 227 | table[KS_CMDB] = 0x12; /* VALIGN=0, AGC control and input */ |
235 | table[KS_CMDC] = 0x00; /* Test options */ | 228 | table[KS_CMDC] = 0x00; /* Test options */ |
@@ -308,50 +301,53 @@ static void init_reg_defaults(void) | |||
308 | * An explanation from kayork@mail.utexas.edu: | 301 | * An explanation from kayork@mail.utexas.edu: |
309 | * | 302 | * |
310 | * During I2C reads, the KS0127 only samples for a stop condition | 303 | * During I2C reads, the KS0127 only samples for a stop condition |
311 | * during the place where the acknoledge bit should be. Any standard | 304 | * during the place where the acknowledge bit should be. Any standard |
312 | * I2C implementation (correctly) throws in another clock transition | 305 | * I2C implementation (correctly) throws in another clock transition |
313 | * at the 9th bit, and the KS0127 will not recognize the stop condition | 306 | * at the 9th bit, and the KS0127 will not recognize the stop condition |
314 | * and will continue to clock out data. | 307 | * and will continue to clock out data. |
315 | * | 308 | * |
316 | * So we have to do the read ourself. Big deal. | 309 | * So we have to do the read ourself. Big deal. |
317 | workaround in i2c-algo-bit | 310 | * workaround in i2c-algo-bit |
318 | */ | 311 | */ |
319 | 312 | ||
320 | 313 | ||
321 | static u8 ks0127_read(struct ks0127 *ks, u8 reg) | 314 | static u8 ks0127_read(struct i2c_client *c, u8 reg) |
322 | { | 315 | { |
323 | struct i2c_client *c = ks->client; | ||
324 | char val = 0; | 316 | char val = 0; |
325 | struct i2c_msg msgs[] = { | 317 | struct i2c_msg msgs[] = { |
326 | {c->addr, 0, sizeof(reg), ®}, | 318 | { c->addr, 0, sizeof(reg), ® }, |
327 | {c->addr, I2C_M_RD | I2C_M_NO_RD_ACK, sizeof(val), &val}}; | 319 | { c->addr, I2C_M_RD | I2C_M_NO_RD_ACK, sizeof(val), &val } |
320 | }; | ||
328 | int ret; | 321 | int ret; |
329 | 322 | ||
330 | ret = i2c_transfer(c->adapter, msgs, ARRAY_SIZE(msgs)); | 323 | ret = i2c_transfer(c->adapter, msgs, ARRAY_SIZE(msgs)); |
331 | if (ret != ARRAY_SIZE(msgs)) | 324 | if (ret != ARRAY_SIZE(msgs)) |
332 | dprintk("ks0127_write error\n"); | 325 | v4l_dbg(1, debug, c, "read error\n"); |
333 | 326 | ||
334 | return val; | 327 | return val; |
335 | } | 328 | } |
336 | 329 | ||
337 | 330 | ||
338 | static void ks0127_write(struct ks0127 *ks, u8 reg, u8 val) | 331 | static void ks0127_write(struct i2c_client *c, u8 reg, u8 val) |
339 | { | 332 | { |
340 | char msg[] = {reg, val}; | 333 | struct ks0127 *ks = i2c_get_clientdata(c); |
334 | char msg[] = { reg, val }; | ||
341 | 335 | ||
342 | if (i2c_master_send(ks->client, msg, sizeof(msg)) != sizeof(msg)) | 336 | if (i2c_master_send(c, msg, sizeof(msg)) != sizeof(msg)) |
343 | dprintk("ks0127_write error\n"); | 337 | v4l_dbg(1, debug, c, "write error\n"); |
344 | 338 | ||
345 | ks->regs[reg] = val; | 339 | ks->regs[reg] = val; |
346 | } | 340 | } |
347 | 341 | ||
348 | 342 | ||
349 | /* generic bit-twiddling */ | 343 | /* generic bit-twiddling */ |
350 | static void ks0127_and_or(struct ks0127 *ks, u8 reg, u8 and_v, u8 or_v) | 344 | static void ks0127_and_or(struct i2c_client *client, u8 reg, u8 and_v, u8 or_v) |
351 | { | 345 | { |
346 | struct ks0127 *ks = i2c_get_clientdata(client); | ||
347 | |||
352 | u8 val = ks->regs[reg]; | 348 | u8 val = ks->regs[reg]; |
353 | val = (val & and_v) | or_v; | 349 | val = (val & and_v) | or_v; |
354 | ks0127_write(ks, reg, val); | 350 | ks0127_write(client, reg, val); |
355 | } | 351 | } |
356 | 352 | ||
357 | 353 | ||
@@ -359,73 +355,69 @@ static void ks0127_and_or(struct ks0127 *ks, u8 reg, u8 and_v, u8 or_v) | |||
359 | /**************************************************************************** | 355 | /**************************************************************************** |
360 | * ks0127 private api | 356 | * ks0127 private api |
361 | ****************************************************************************/ | 357 | ****************************************************************************/ |
362 | static void ks0127_reset(struct ks0127* ks) | 358 | static void ks0127_reset(struct i2c_client *c) |
363 | { | 359 | { |
364 | int i; | 360 | struct ks0127 *ks = i2c_get_clientdata(c); |
365 | u8 *table = reg_defaults; | 361 | u8 *table = reg_defaults; |
362 | int i; | ||
366 | 363 | ||
367 | ks->ks_type = KS_TYPE_UNKNOWN; | 364 | ks->ks_type = KS_TYPE_UNKNOWN; |
368 | 365 | ||
369 | dprintk("ks0127: reset\n"); | 366 | v4l_dbg(1, debug, c, "reset\n"); |
370 | msleep(1); | 367 | msleep(1); |
371 | 368 | ||
372 | /* initialize all registers to known values */ | 369 | /* initialize all registers to known values */ |
373 | /* (except STAT, 0x21, 0x22, TEST and 0x38,0x39) */ | 370 | /* (except STAT, 0x21, 0x22, TEST and 0x38,0x39) */ |
374 | 371 | ||
375 | for(i = 1; i < 33; i++) | 372 | for (i = 1; i < 33; i++) |
376 | ks0127_write(ks, i, table[i]); | 373 | ks0127_write(c, i, table[i]); |
377 | 374 | ||
378 | for(i = 35; i < 40; i++) | 375 | for (i = 35; i < 40; i++) |
379 | ks0127_write(ks, i, table[i]); | 376 | ks0127_write(c, i, table[i]); |
380 | 377 | ||
381 | for(i = 41; i < 56; i++) | 378 | for (i = 41; i < 56; i++) |
382 | ks0127_write(ks, i, table[i]); | 379 | ks0127_write(c, i, table[i]); |
383 | 380 | ||
384 | for(i = 58; i < 64; i++) | 381 | for (i = 58; i < 64; i++) |
385 | ks0127_write(ks, i, table[i]); | 382 | ks0127_write(c, i, table[i]); |
386 | 383 | ||
387 | 384 | ||
388 | if ((ks0127_read(ks, KS_STAT) & 0x80) == 0) { | 385 | if ((ks0127_read(c, KS_STAT) & 0x80) == 0) { |
389 | ks->ks_type = KS_TYPE_0122S; | 386 | ks->ks_type = KS_TYPE_0122S; |
390 | dprintk("ks0127: ks0122s Found\n"); | 387 | v4l_dbg(1, debug, c, "ks0122s found\n"); |
391 | return; | 388 | return; |
392 | } | 389 | } |
393 | 390 | ||
394 | switch(ks0127_read(ks, KS_CMDE) & 0x0f) { | 391 | switch (ks0127_read(c, KS_CMDE) & 0x0f) { |
395 | |||
396 | case 0: | 392 | case 0: |
397 | ks->ks_type = KS_TYPE_0127; | 393 | ks->ks_type = KS_TYPE_0127; |
398 | dprintk("ks0127: ks0127 found\n"); | 394 | v4l_dbg(1, debug, c, "ks0127 found\n"); |
399 | break; | 395 | break; |
400 | 396 | ||
401 | case 9: | 397 | case 9: |
402 | ks->ks_type = KS_TYPE_0127B; | 398 | ks->ks_type = KS_TYPE_0127B; |
403 | dprintk("ks0127: ks0127B Revision A found\n"); | 399 | v4l_dbg(1, debug, c, "ks0127B Revision A found\n"); |
404 | break; | 400 | break; |
405 | 401 | ||
406 | default: | 402 | default: |
407 | dprintk("ks0127: unknown revision\n"); | 403 | v4l_dbg(1, debug, c, "unknown revision\n"); |
408 | break; | 404 | break; |
409 | } | 405 | } |
410 | } | 406 | } |
411 | 407 | ||
412 | static int ks0127_command(struct i2c_client *client, | 408 | static int ks0127_command(struct i2c_client *c, unsigned cmd, void *arg) |
413 | unsigned int cmd, void *arg) | ||
414 | { | 409 | { |
415 | struct ks0127 *ks = i2c_get_clientdata(client); | 410 | struct ks0127 *ks = i2c_get_clientdata(c); |
416 | 411 | int *iarg = (int *)arg; | |
417 | int *iarg = (int*)arg; | ||
418 | |||
419 | int status; | 412 | int status; |
420 | 413 | ||
421 | if (!ks) | 414 | if (!ks) |
422 | return -ENODEV; | 415 | return -ENODEV; |
423 | 416 | ||
424 | switch (cmd) { | 417 | switch (cmd) { |
425 | |||
426 | case DECODER_INIT: | 418 | case DECODER_INIT: |
427 | dprintk("ks0127: command DECODER_INIT\n"); | 419 | v4l_dbg(1, debug, c, "DECODER_INIT\n"); |
428 | ks0127_reset(ks); | 420 | ks0127_reset(c); |
429 | break; | 421 | break; |
430 | 422 | ||
431 | case DECODER_SET_INPUT: | 423 | case DECODER_SET_INPUT: |
@@ -436,161 +428,160 @@ static int ks0127_command(struct i2c_client *client, | |||
436 | case KS_INPUT_COMPOSITE_4: | 428 | case KS_INPUT_COMPOSITE_4: |
437 | case KS_INPUT_COMPOSITE_5: | 429 | case KS_INPUT_COMPOSITE_5: |
438 | case KS_INPUT_COMPOSITE_6: | 430 | case KS_INPUT_COMPOSITE_6: |
439 | dprintk("ks0127: command DECODER_SET_INPUT %d: " | 431 | v4l_dbg(1, debug, c, |
440 | "Composite\n", *iarg); | 432 | "DECODER_SET_INPUT %d: Composite\n", *iarg); |
441 | /* autodetect 50/60 Hz */ | 433 | /* autodetect 50/60 Hz */ |
442 | ks0127_and_or(ks, KS_CMDA, 0xfc, 0x00); | 434 | ks0127_and_or(c, KS_CMDA, 0xfc, 0x00); |
443 | /* VSE=0 */ | 435 | /* VSE=0 */ |
444 | ks0127_and_or(ks, KS_CMDA, ~0x40, 0x00); | 436 | ks0127_and_or(c, KS_CMDA, ~0x40, 0x00); |
445 | /* set input line */ | 437 | /* set input line */ |
446 | ks0127_and_or(ks, KS_CMDB, 0xb0, *iarg); | 438 | ks0127_and_or(c, KS_CMDB, 0xb0, *iarg); |
447 | /* non-freerunning mode */ | 439 | /* non-freerunning mode */ |
448 | ks0127_and_or(ks, KS_CMDC, 0x70, 0x0a); | 440 | ks0127_and_or(c, KS_CMDC, 0x70, 0x0a); |
449 | /* analog input */ | 441 | /* analog input */ |
450 | ks0127_and_or(ks, KS_CMDD, 0x03, 0x00); | 442 | ks0127_and_or(c, KS_CMDD, 0x03, 0x00); |
451 | /* enable chroma demodulation */ | 443 | /* enable chroma demodulation */ |
452 | ks0127_and_or(ks, KS_CTRACK, 0xcf, 0x00); | 444 | ks0127_and_or(c, KS_CTRACK, 0xcf, 0x00); |
453 | /* chroma trap, HYBWR=1 */ | 445 | /* chroma trap, HYBWR=1 */ |
454 | ks0127_and_or(ks, KS_LUMA, 0x00, | 446 | ks0127_and_or(c, KS_LUMA, 0x00, |
455 | (reg_defaults[KS_LUMA])|0x0c); | 447 | (reg_defaults[KS_LUMA])|0x0c); |
456 | /* scaler fullbw, luma comb off */ | 448 | /* scaler fullbw, luma comb off */ |
457 | ks0127_and_or(ks, KS_VERTIA, 0x08, 0x81); | 449 | ks0127_and_or(c, KS_VERTIA, 0x08, 0x81); |
458 | /* manual chroma comb .25 .5 .25 */ | 450 | /* manual chroma comb .25 .5 .25 */ |
459 | ks0127_and_or(ks, KS_VERTIC, 0x0f, 0x90); | 451 | ks0127_and_or(c, KS_VERTIC, 0x0f, 0x90); |
460 | 452 | ||
461 | /* chroma path delay */ | 453 | /* chroma path delay */ |
462 | ks0127_and_or(ks, KS_CHROMB, 0x0f, 0x90); | 454 | ks0127_and_or(c, KS_CHROMB, 0x0f, 0x90); |
463 | 455 | ||
464 | ks0127_write(ks, KS_UGAIN, reg_defaults[KS_UGAIN]); | 456 | ks0127_write(c, KS_UGAIN, reg_defaults[KS_UGAIN]); |
465 | ks0127_write(ks, KS_VGAIN, reg_defaults[KS_VGAIN]); | 457 | ks0127_write(c, KS_VGAIN, reg_defaults[KS_VGAIN]); |
466 | ks0127_write(ks, KS_UVOFFH, reg_defaults[KS_UVOFFH]); | 458 | ks0127_write(c, KS_UVOFFH, reg_defaults[KS_UVOFFH]); |
467 | ks0127_write(ks, KS_UVOFFL, reg_defaults[KS_UVOFFL]); | 459 | ks0127_write(c, KS_UVOFFL, reg_defaults[KS_UVOFFL]); |
468 | break; | 460 | break; |
469 | 461 | ||
470 | case KS_INPUT_SVIDEO_1: | 462 | case KS_INPUT_SVIDEO_1: |
471 | case KS_INPUT_SVIDEO_2: | 463 | case KS_INPUT_SVIDEO_2: |
472 | case KS_INPUT_SVIDEO_3: | 464 | case KS_INPUT_SVIDEO_3: |
473 | dprintk("ks0127: command DECODER_SET_INPUT %d: " | 465 | v4l_dbg(1, debug, c, |
474 | "S-Video\n", *iarg); | 466 | "DECODER_SET_INPUT %d: S-Video\n", *iarg); |
475 | /* autodetect 50/60 Hz */ | 467 | /* autodetect 50/60 Hz */ |
476 | ks0127_and_or(ks, KS_CMDA, 0xfc, 0x00); | 468 | ks0127_and_or(c, KS_CMDA, 0xfc, 0x00); |
477 | /* VSE=0 */ | 469 | /* VSE=0 */ |
478 | ks0127_and_or(ks, KS_CMDA, ~0x40, 0x00); | 470 | ks0127_and_or(c, KS_CMDA, ~0x40, 0x00); |
479 | /* set input line */ | 471 | /* set input line */ |
480 | ks0127_and_or(ks, KS_CMDB, 0xb0, *iarg); | 472 | ks0127_and_or(c, KS_CMDB, 0xb0, *iarg); |
481 | /* non-freerunning mode */ | 473 | /* non-freerunning mode */ |
482 | ks0127_and_or(ks, KS_CMDC, 0x70, 0x0a); | 474 | ks0127_and_or(c, KS_CMDC, 0x70, 0x0a); |
483 | /* analog input */ | 475 | /* analog input */ |
484 | ks0127_and_or(ks, KS_CMDD, 0x03, 0x00); | 476 | ks0127_and_or(c, KS_CMDD, 0x03, 0x00); |
485 | /* enable chroma demodulation */ | 477 | /* enable chroma demodulation */ |
486 | ks0127_and_or(ks, KS_CTRACK, 0xcf, 0x00); | 478 | ks0127_and_or(c, KS_CTRACK, 0xcf, 0x00); |
487 | ks0127_and_or(ks, KS_LUMA, 0x00, | 479 | ks0127_and_or(c, KS_LUMA, 0x00, |
488 | reg_defaults[KS_LUMA]); | 480 | reg_defaults[KS_LUMA]); |
489 | /* disable luma comb */ | 481 | /* disable luma comb */ |
490 | ks0127_and_or(ks, KS_VERTIA, 0x08, | 482 | ks0127_and_or(c, KS_VERTIA, 0x08, |
491 | (reg_defaults[KS_VERTIA]&0xf0)|0x01); | 483 | (reg_defaults[KS_VERTIA]&0xf0)|0x01); |
492 | ks0127_and_or(ks, KS_VERTIC, 0x0f, | 484 | ks0127_and_or(c, KS_VERTIC, 0x0f, |
493 | reg_defaults[KS_VERTIC]&0xf0); | 485 | reg_defaults[KS_VERTIC]&0xf0); |
494 | 486 | ||
495 | ks0127_and_or(ks, KS_CHROMB, 0x0f, | 487 | ks0127_and_or(c, KS_CHROMB, 0x0f, |
496 | reg_defaults[KS_CHROMB]&0xf0); | 488 | reg_defaults[KS_CHROMB]&0xf0); |
497 | 489 | ||
498 | ks0127_write(ks, KS_UGAIN, reg_defaults[KS_UGAIN]); | 490 | ks0127_write(c, KS_UGAIN, reg_defaults[KS_UGAIN]); |
499 | ks0127_write(ks, KS_VGAIN, reg_defaults[KS_VGAIN]); | 491 | ks0127_write(c, KS_VGAIN, reg_defaults[KS_VGAIN]); |
500 | ks0127_write(ks, KS_UVOFFH, reg_defaults[KS_UVOFFH]); | 492 | ks0127_write(c, KS_UVOFFH, reg_defaults[KS_UVOFFH]); |
501 | ks0127_write(ks, KS_UVOFFL, reg_defaults[KS_UVOFFL]); | 493 | ks0127_write(c, KS_UVOFFL, reg_defaults[KS_UVOFFL]); |
502 | break; | 494 | break; |
503 | 495 | ||
504 | case KS_INPUT_YUV656: | 496 | case KS_INPUT_YUV656: |
505 | dprintk("ks0127: command DECODER_SET_INPUT 15: " | 497 | v4l_dbg(1, debug, c, |
506 | "YUV656\n"); | 498 | "DECODER_SET_INPUT 15: YUV656\n"); |
507 | if (ks->norm == VIDEO_MODE_NTSC || | 499 | if (ks->norm == VIDEO_MODE_NTSC || |
508 | ks->norm == KS_STD_PAL_M) | 500 | ks->norm == KS_STD_PAL_M) |
509 | /* force 60 Hz */ | 501 | /* force 60 Hz */ |
510 | ks0127_and_or(ks, KS_CMDA, 0xfc, 0x03); | 502 | ks0127_and_or(c, KS_CMDA, 0xfc, 0x03); |
511 | else | 503 | else |
512 | /* force 50 Hz */ | 504 | /* force 50 Hz */ |
513 | ks0127_and_or(ks, KS_CMDA, 0xfc, 0x02); | 505 | ks0127_and_or(c, KS_CMDA, 0xfc, 0x02); |
514 | 506 | ||
515 | ks0127_and_or(ks, KS_CMDA, 0xff, 0x40); /* VSE=1 */ | 507 | ks0127_and_or(c, KS_CMDA, 0xff, 0x40); /* VSE=1 */ |
516 | /* set input line and VALIGN */ | 508 | /* set input line and VALIGN */ |
517 | ks0127_and_or(ks, KS_CMDB, 0xb0, (*iarg | 0x40)); | 509 | ks0127_and_or(c, KS_CMDB, 0xb0, (*iarg | 0x40)); |
518 | /* freerunning mode, */ | 510 | /* freerunning mode, */ |
519 | /* TSTGEN = 1 TSTGFR=11 TSTGPH=0 TSTGPK=0 VMEM=1*/ | 511 | /* TSTGEN = 1 TSTGFR=11 TSTGPH=0 TSTGPK=0 VMEM=1*/ |
520 | ks0127_and_or(ks, KS_CMDC, 0x70, 0x87); | 512 | ks0127_and_or(c, KS_CMDC, 0x70, 0x87); |
521 | /* digital input, SYNDIR = 0 INPSL=01 CLKDIR=0 EAV=0 */ | 513 | /* digital input, SYNDIR = 0 INPSL=01 CLKDIR=0 EAV=0 */ |
522 | ks0127_and_or(ks, KS_CMDD, 0x03, 0x08); | 514 | ks0127_and_or(c, KS_CMDD, 0x03, 0x08); |
523 | /* disable chroma demodulation */ | 515 | /* disable chroma demodulation */ |
524 | ks0127_and_or(ks, KS_CTRACK, 0xcf, 0x30); | 516 | ks0127_and_or(c, KS_CTRACK, 0xcf, 0x30); |
525 | /* HYPK =01 CTRAP = 0 HYBWR=0 PED=1 RGBH=1 UNIT=1 */ | 517 | /* HYPK =01 CTRAP = 0 HYBWR=0 PED=1 RGBH=1 UNIT=1 */ |
526 | ks0127_and_or(ks, KS_LUMA, 0x00, 0x71); | 518 | ks0127_and_or(c, KS_LUMA, 0x00, 0x71); |
527 | ks0127_and_or(ks, KS_VERTIC, 0x0f, | 519 | ks0127_and_or(c, KS_VERTIC, 0x0f, |
528 | reg_defaults[KS_VERTIC]&0xf0); | 520 | reg_defaults[KS_VERTIC]&0xf0); |
529 | 521 | ||
530 | /* scaler fullbw, luma comb off */ | 522 | /* scaler fullbw, luma comb off */ |
531 | ks0127_and_or(ks, KS_VERTIA, 0x08, 0x81); | 523 | ks0127_and_or(c, KS_VERTIA, 0x08, 0x81); |
532 | 524 | ||
533 | ks0127_and_or(ks, KS_CHROMB, 0x0f, | 525 | ks0127_and_or(c, KS_CHROMB, 0x0f, |
534 | reg_defaults[KS_CHROMB]&0xf0); | 526 | reg_defaults[KS_CHROMB]&0xf0); |
535 | 527 | ||
536 | ks0127_and_or(ks, KS_CON, 0x00, 0x00); | 528 | ks0127_and_or(c, KS_CON, 0x00, 0x00); |
537 | ks0127_and_or(ks, KS_BRT, 0x00, 32); /* spec: 34 */ | 529 | ks0127_and_or(c, KS_BRT, 0x00, 32); /* spec: 34 */ |
538 | /* spec: 229 (e5) */ | 530 | /* spec: 229 (e5) */ |
539 | ks0127_and_or(ks, KS_SAT, 0x00, 0xe8); | 531 | ks0127_and_or(c, KS_SAT, 0x00, 0xe8); |
540 | ks0127_and_or(ks, KS_HUE, 0x00, 0); | 532 | ks0127_and_or(c, KS_HUE, 0x00, 0); |
541 | 533 | ||
542 | ks0127_and_or(ks, KS_UGAIN, 0x00, 238); | 534 | ks0127_and_or(c, KS_UGAIN, 0x00, 238); |
543 | ks0127_and_or(ks, KS_VGAIN, 0x00, 0x00); | 535 | ks0127_and_or(c, KS_VGAIN, 0x00, 0x00); |
544 | 536 | ||
545 | /*UOFF:0x30, VOFF:0x30, TSTCGN=1 */ | 537 | /*UOFF:0x30, VOFF:0x30, TSTCGN=1 */ |
546 | ks0127_and_or(ks, KS_UVOFFH, 0x00, 0x4f); | 538 | ks0127_and_or(c, KS_UVOFFH, 0x00, 0x4f); |
547 | ks0127_and_or(ks, KS_UVOFFL, 0x00, 0x00); | 539 | ks0127_and_or(c, KS_UVOFFL, 0x00, 0x00); |
548 | break; | 540 | break; |
549 | 541 | ||
550 | default: | 542 | default: |
551 | dprintk("ks0127: command DECODER_SET_INPUT: " | 543 | v4l_dbg(1, debug, c, |
552 | "Unknown input %d\n", *iarg); | 544 | "DECODER_SET_INPUT: Unknown input %d\n", *iarg); |
553 | break; | 545 | break; |
554 | } | 546 | } |
555 | 547 | ||
556 | /* hack: CDMLPF sometimes spontaneously switches on; */ | 548 | /* hack: CDMLPF sometimes spontaneously switches on; */ |
557 | /* force back off */ | 549 | /* force back off */ |
558 | ks0127_write(ks, KS_DEMOD, reg_defaults[KS_DEMOD]); | 550 | ks0127_write(c, KS_DEMOD, reg_defaults[KS_DEMOD]); |
559 | break; | 551 | break; |
560 | 552 | ||
561 | case DECODER_SET_OUTPUT: | 553 | case DECODER_SET_OUTPUT: |
562 | switch(*iarg) { | 554 | switch(*iarg) { |
563 | case KS_OUTPUT_YUV656E: | 555 | case KS_OUTPUT_YUV656E: |
564 | dprintk("ks0127: command DECODER_SET_OUTPUT: " | 556 | v4l_dbg(1, debug, c, |
565 | "OUTPUT_YUV656E (Missing)\n"); | 557 | "DECODER_SET_OUTPUT: OUTPUT_YUV656E (Missing)\n"); |
566 | return -EINVAL; | 558 | return -EINVAL; |
567 | break; | ||
568 | 559 | ||
569 | case KS_OUTPUT_EXV: | 560 | case KS_OUTPUT_EXV: |
570 | dprintk("ks0127: command DECODER_SET_OUTPUT: " | 561 | v4l_dbg(1, debug, c, |
571 | "OUTPUT_EXV\n"); | 562 | "DECODER_SET_OUTPUT: OUTPUT_EXV\n"); |
572 | ks0127_and_or(ks, KS_OFMTA, 0xf0, 0x09); | 563 | ks0127_and_or(c, KS_OFMTA, 0xf0, 0x09); |
573 | break; | 564 | break; |
574 | } | 565 | } |
575 | break; | 566 | break; |
576 | 567 | ||
577 | case DECODER_SET_NORM: //sam This block mixes old and new norm names... | 568 | case DECODER_SET_NORM: /* sam This block mixes old and new norm names... */ |
578 | /* Set to automatic SECAM/Fsc mode */ | 569 | /* Set to automatic SECAM/Fsc mode */ |
579 | ks0127_and_or(ks, KS_DEMOD, 0xf0, 0x00); | 570 | ks0127_and_or(c, KS_DEMOD, 0xf0, 0x00); |
580 | 571 | ||
581 | ks->norm = *iarg; | 572 | ks->norm = *iarg; |
582 | switch(*iarg) | 573 | switch (*iarg) { |
583 | { | ||
584 | /* this is untested !! */ | 574 | /* this is untested !! */ |
585 | /* It just detects PAL_N/NTSC_M (no special frequencies) */ | 575 | /* It just detects PAL_N/NTSC_M (no special frequencies) */ |
586 | /* And you have to set the standard a second time afterwards */ | 576 | /* And you have to set the standard a second time afterwards */ |
587 | case VIDEO_MODE_AUTO: | 577 | case VIDEO_MODE_AUTO: |
588 | dprintk("ks0127: command DECODER_SET_NORM: AUTO\n"); | 578 | v4l_dbg(1, debug, c, |
579 | "DECODER_SET_NORM: AUTO\n"); | ||
589 | 580 | ||
590 | /* The chip determines the format */ | 581 | /* The chip determines the format */ |
591 | /* based on the current field rate */ | 582 | /* based on the current field rate */ |
592 | ks0127_and_or(ks, KS_CMDA, 0xfc, 0x00); | 583 | ks0127_and_or(c, KS_CMDA, 0xfc, 0x00); |
593 | ks0127_and_or(ks, KS_CHROMA, 0x9f, 0x20); | 584 | ks0127_and_or(c, KS_CHROMA, 0x9f, 0x20); |
594 | /* This is wrong for PAL ! As I said, */ | 585 | /* This is wrong for PAL ! As I said, */ |
595 | /* you need to set the standard once again !! */ | 586 | /* you need to set the standard once again !! */ |
596 | ks->format_height = 240; | 587 | ks->format_height = 240; |
@@ -598,84 +589,86 @@ static int ks0127_command(struct i2c_client *client, | |||
598 | break; | 589 | break; |
599 | 590 | ||
600 | case VIDEO_MODE_NTSC: | 591 | case VIDEO_MODE_NTSC: |
601 | dprintk("ks0127: command DECODER_SET_NORM: NTSC_M\n"); | 592 | v4l_dbg(1, debug, c, |
602 | ks0127_and_or(ks, KS_CHROMA, 0x9f, 0x20); | 593 | "DECODER_SET_NORM: NTSC_M\n"); |
594 | ks0127_and_or(c, KS_CHROMA, 0x9f, 0x20); | ||
603 | ks->format_height = 240; | 595 | ks->format_height = 240; |
604 | ks->format_width = 704; | 596 | ks->format_width = 704; |
605 | break; | 597 | break; |
606 | 598 | ||
607 | case KS_STD_NTSC_N: | 599 | case KS_STD_NTSC_N: |
608 | dprintk("ks0127: command KS0127_SET_STANDARD: " | 600 | v4l_dbg(1, debug, c, |
609 | "NTSC_N (fixme)\n"); | 601 | "KS0127_SET_NORM: NTSC_N (fixme)\n"); |
610 | ks0127_and_or(ks, KS_CHROMA, 0x9f, 0x40); | 602 | ks0127_and_or(c, KS_CHROMA, 0x9f, 0x40); |
611 | ks->format_height = 240; | 603 | ks->format_height = 240; |
612 | ks->format_width = 704; | 604 | ks->format_width = 704; |
613 | break; | 605 | break; |
614 | 606 | ||
615 | case VIDEO_MODE_PAL: | 607 | case VIDEO_MODE_PAL: |
616 | dprintk("ks0127: command DECODER_SET_NORM: PAL_N\n"); | 608 | v4l_dbg(1, debug, c, |
617 | ks0127_and_or(ks, KS_CHROMA, 0x9f, 0x20); | 609 | "DECODER_SET_NORM: PAL_N\n"); |
610 | ks0127_and_or(c, KS_CHROMA, 0x9f, 0x20); | ||
618 | ks->format_height = 290; | 611 | ks->format_height = 290; |
619 | ks->format_width = 704; | 612 | ks->format_width = 704; |
620 | break; | 613 | break; |
621 | 614 | ||
622 | case KS_STD_PAL_M: | 615 | case KS_STD_PAL_M: |
623 | dprintk("ks0127: command KS0127_SET_STANDARD: " | 616 | v4l_dbg(1, debug, c, |
624 | "PAL_M (fixme)\n"); | 617 | "KS0127_SET_NORM: PAL_M (fixme)\n"); |
625 | ks0127_and_or(ks, KS_CHROMA, 0x9f, 0x40); | 618 | ks0127_and_or(c, KS_CHROMA, 0x9f, 0x40); |
626 | ks->format_height = 290; | 619 | ks->format_height = 290; |
627 | ks->format_width = 704; | 620 | ks->format_width = 704; |
628 | break; | 621 | break; |
629 | 622 | ||
630 | case VIDEO_MODE_SECAM: | 623 | case VIDEO_MODE_SECAM: |
631 | dprintk("ks0127: command KS0127_SET_STANDARD: " | 624 | v4l_dbg(1, debug, c, |
632 | "SECAM\n"); | 625 | "KS0127_SET_NORM: SECAM\n"); |
633 | ks->format_height = 290; | 626 | ks->format_height = 290; |
634 | ks->format_width = 704; | 627 | ks->format_width = 704; |
635 | 628 | ||
636 | /* set to secam autodetection */ | 629 | /* set to secam autodetection */ |
637 | ks0127_and_or(ks, KS_CHROMA, 0xdf, 0x20); | 630 | ks0127_and_or(c, KS_CHROMA, 0xdf, 0x20); |
638 | ks0127_and_or(ks, KS_DEMOD, 0xf0, 0x00); | 631 | ks0127_and_or(c, KS_DEMOD, 0xf0, 0x00); |
639 | schedule_timeout_interruptible(HZ/10+1); | 632 | schedule_timeout_interruptible(HZ/10+1); |
640 | 633 | ||
641 | /* did it autodetect? */ | 634 | /* did it autodetect? */ |
642 | if (ks0127_read(ks, KS_DEMOD) & 0x40) | 635 | if (ks0127_read(c, KS_DEMOD) & 0x40) |
643 | break; | 636 | break; |
644 | 637 | ||
645 | /* force to secam mode */ | 638 | /* force to secam mode */ |
646 | ks0127_and_or(ks, KS_DEMOD, 0xf0, 0x0f); | 639 | ks0127_and_or(c, KS_DEMOD, 0xf0, 0x0f); |
647 | break; | 640 | break; |
648 | 641 | ||
649 | default: | 642 | default: |
650 | dprintk("ks0127: command DECODER_SET_NORM: " | 643 | v4l_dbg(1, debug, c, |
651 | "Unknown norm %d\n", *iarg); | 644 | "DECODER_SET_NORM: Unknown norm %d\n", *iarg); |
652 | break; | 645 | break; |
653 | } | 646 | } |
654 | break; | 647 | break; |
655 | 648 | ||
656 | case DECODER_SET_PICTURE: | 649 | case DECODER_SET_PICTURE: |
657 | dprintk("ks0127: command DECODER_SET_PICTURE " | 650 | v4l_dbg(1, debug, c, |
658 | "not yet supported (fixme)\n"); | 651 | "DECODER_SET_PICTURE: not yet supported\n"); |
659 | return -EINVAL; | 652 | return -EINVAL; |
660 | 653 | ||
661 | //sam todo: KS0127_SET_BRIGHTNESS: Merge into DECODER_SET_PICTURE | 654 | /* sam todo: KS0127_SET_BRIGHTNESS: Merge into DECODER_SET_PICTURE */ |
662 | //sam todo: KS0127_SET_CONTRAST: Merge into DECODER_SET_PICTURE | 655 | /* sam todo: KS0127_SET_CONTRAST: Merge into DECODER_SET_PICTURE */ |
663 | //sam todo: KS0127_SET_HUE: Merge into DECODER_SET_PICTURE? | 656 | /* sam todo: KS0127_SET_HUE: Merge into DECODER_SET_PICTURE? */ |
664 | //sam todo: KS0127_SET_SATURATION: Merge into DECODER_SET_PICTURE | 657 | /* sam todo: KS0127_SET_SATURATION: Merge into DECODER_SET_PICTURE */ |
665 | //sam todo: KS0127_SET_AGC_MODE: | 658 | /* sam todo: KS0127_SET_AGC_MODE: */ |
666 | //sam todo: KS0127_SET_AGC: | 659 | /* sam todo: KS0127_SET_AGC: */ |
667 | //sam todo: KS0127_SET_CHROMA_MODE: | 660 | /* sam todo: KS0127_SET_CHROMA_MODE: */ |
668 | //sam todo: KS0127_SET_PIXCLK_MODE: | 661 | /* sam todo: KS0127_SET_PIXCLK_MODE: */ |
669 | //sam todo: KS0127_SET_GAMMA_MODE: | 662 | /* sam todo: KS0127_SET_GAMMA_MODE: */ |
670 | //sam todo: KS0127_SET_UGAIN: | 663 | /* sam todo: KS0127_SET_UGAIN: */ |
671 | //sam todo: KS0127_SET_VGAIN: | 664 | /* sam todo: KS0127_SET_VGAIN: */ |
672 | //sam todo: KS0127_SET_INVALY: | 665 | /* sam todo: KS0127_SET_INVALY: */ |
673 | //sam todo: KS0127_SET_INVALU: | 666 | /* sam todo: KS0127_SET_INVALU: */ |
674 | //sam todo: KS0127_SET_INVALV: | 667 | /* sam todo: KS0127_SET_INVALV: */ |
675 | //sam todo: KS0127_SET_UNUSEY: | 668 | /* sam todo: KS0127_SET_UNUSEY: */ |
676 | //sam todo: KS0127_SET_UNUSEU: | 669 | /* sam todo: KS0127_SET_UNUSEU: */ |
677 | //sam todo: KS0127_SET_UNUSEV: | 670 | /* sam todo: KS0127_SET_UNUSEV: */ |
678 | //sam todo: KS0127_SET_VSALIGN_MODE: | 671 | /* sam todo: KS0127_SET_VSALIGN_MODE: */ |
679 | 672 | ||
680 | case DECODER_ENABLE_OUTPUT: | 673 | case DECODER_ENABLE_OUTPUT: |
681 | { | 674 | { |
@@ -684,34 +677,32 @@ static int ks0127_command(struct i2c_client *client, | |||
684 | iarg = arg; | 677 | iarg = arg; |
685 | enable = (*iarg != 0); | 678 | enable = (*iarg != 0); |
686 | if (enable) { | 679 | if (enable) { |
687 | dprintk("ks0127: command " | 680 | v4l_dbg(1, debug, c, |
688 | "DECODER_ENABLE_OUTPUT on " | 681 | "DECODER_ENABLE_OUTPUT on\n"); |
689 | "(%d)\n", enable); | ||
690 | /* All output pins on */ | 682 | /* All output pins on */ |
691 | ks0127_and_or(ks, KS_OFMTA, 0xcf, 0x30); | 683 | ks0127_and_or(c, KS_OFMTA, 0xcf, 0x30); |
692 | /* Obey the OEN pin */ | 684 | /* Obey the OEN pin */ |
693 | ks0127_and_or(ks, KS_CDEM, 0x7f, 0x00); | 685 | ks0127_and_or(c, KS_CDEM, 0x7f, 0x00); |
694 | } else { | 686 | } else { |
695 | dprintk("ks0127: command " | 687 | v4l_dbg(1, debug, c, |
696 | "DECODER_ENABLE_OUTPUT off " | 688 | "DECODER_ENABLE_OUTPUT off\n"); |
697 | "(%d)\n", enable); | ||
698 | /* Video output pins off */ | 689 | /* Video output pins off */ |
699 | ks0127_and_or(ks, KS_OFMTA, 0xcf, 0x00); | 690 | ks0127_and_or(c, KS_OFMTA, 0xcf, 0x00); |
700 | /* Ignore the OEN pin */ | 691 | /* Ignore the OEN pin */ |
701 | ks0127_and_or(ks, KS_CDEM, 0x7f, 0x80); | 692 | ks0127_and_or(c, KS_CDEM, 0x7f, 0x80); |
702 | } | 693 | } |
703 | } | ||
704 | break; | 694 | break; |
695 | } | ||
705 | 696 | ||
706 | //sam todo: KS0127_SET_OUTPUT_MODE: | 697 | /* sam todo: KS0127_SET_OUTPUT_MODE: */ |
707 | //sam todo: KS0127_SET_WIDTH: | 698 | /* sam todo: KS0127_SET_WIDTH: */ |
708 | //sam todo: KS0127_SET_HEIGHT: | 699 | /* sam todo: KS0127_SET_HEIGHT: */ |
709 | //sam todo: KS0127_SET_HSCALE: | 700 | /* sam todo: KS0127_SET_HSCALE: */ |
710 | 701 | ||
711 | case DECODER_GET_STATUS: | 702 | case DECODER_GET_STATUS: |
712 | dprintk("ks0127: command DECODER_GET_STATUS\n"); | 703 | v4l_dbg(1, debug, c, "DECODER_GET_STATUS\n"); |
713 | *iarg = 0; | 704 | *iarg = 0; |
714 | status = ks0127_read(ks, KS_STAT); | 705 | status = ks0127_read(c, KS_STAT); |
715 | if (!(status & 0x20)) /* NOVID not set */ | 706 | if (!(status & 0x20)) /* NOVID not set */ |
716 | *iarg = (*iarg | DECODER_STATUS_GOOD); | 707 | *iarg = (*iarg | DECODER_STATUS_GOOD); |
717 | if ((status & 0x01)) /* CLOCK set */ | 708 | if ((status & 0x01)) /* CLOCK set */ |
@@ -722,124 +713,81 @@ static int ks0127_command(struct i2c_client *client, | |||
722 | *iarg = (*iarg | DECODER_STATUS_NTSC); | 713 | *iarg = (*iarg | DECODER_STATUS_NTSC); |
723 | break; | 714 | break; |
724 | 715 | ||
725 | //Catch any unknown command | 716 | /* Catch any unknown command */ |
726 | default: | 717 | default: |
727 | dprintk("ks0127: command unknown: %04X\n", cmd); | 718 | v4l_dbg(1, debug, c, "unknown: 0x%08x\n", cmd); |
728 | return -EINVAL; | 719 | return -EINVAL; |
729 | } | 720 | } |
730 | return 0; | 721 | return 0; |
731 | } | 722 | } |
732 | 723 | ||
733 | 724 | ||
734 | |||
735 | |||
736 | static int ks0127_probe(struct i2c_adapter *adapter); | ||
737 | static int ks0127_detach(struct i2c_client *client); | ||
738 | static int ks0127_command(struct i2c_client *client, | ||
739 | unsigned int cmd, void *arg); | ||
740 | |||
741 | |||
742 | |||
743 | /* Addresses to scan */ | 725 | /* Addresses to scan */ |
744 | static unsigned short normal_i2c[] = {I2C_KS0127_ADDON>>1, | 726 | #define I2C_KS0127_ADDON 0xD8 |
745 | I2C_KS0127_ONBOARD>>1, I2C_CLIENT_END}; | 727 | #define I2C_KS0127_ONBOARD 0xDA |
746 | static unsigned short probe[2] = {I2C_CLIENT_END, I2C_CLIENT_END}; | ||
747 | static unsigned short ignore[2] = {I2C_CLIENT_END, I2C_CLIENT_END}; | ||
748 | static struct i2c_client_address_data addr_data = { | ||
749 | normal_i2c, | ||
750 | probe, | ||
751 | ignore, | ||
752 | }; | ||
753 | 728 | ||
754 | static struct i2c_driver i2c_driver_ks0127 = { | 729 | static unsigned short normal_i2c[] = { |
755 | .driver.name = "ks0127", | 730 | I2C_KS0127_ADDON >> 1, |
756 | .id = I2C_DRIVERID_KS0127, | 731 | I2C_KS0127_ONBOARD >> 1, |
757 | .attach_adapter = ks0127_probe, | 732 | I2C_CLIENT_END |
758 | .detach_client = ks0127_detach, | ||
759 | .command = ks0127_command | ||
760 | }; | 733 | }; |
761 | 734 | ||
762 | static struct i2c_client ks0127_client_tmpl = | 735 | I2C_CLIENT_INSMOD; |
763 | { | ||
764 | .name = "(ks0127 unset)", | ||
765 | .addr = 0, | ||
766 | .adapter = NULL, | ||
767 | .driver = &i2c_driver_ks0127, | ||
768 | }; | ||
769 | 736 | ||
770 | static int ks0127_found_proc(struct i2c_adapter *adapter, int addr, int kind) | 737 | static int ks0127_probe(struct i2c_client *c, const struct i2c_device_id *id) |
771 | { | 738 | { |
772 | struct ks0127 *ks; | 739 | struct ks0127 *ks; |
773 | struct i2c_client *client; | ||
774 | 740 | ||
775 | client = kzalloc(sizeof(*client), GFP_KERNEL); | 741 | v4l_info(c, "%s chip found @ 0x%x (%s)\n", |
776 | if (client == NULL) | 742 | c->addr == (I2C_KS0127_ADDON >> 1) ? "addon" : "on-board", |
777 | return -ENOMEM; | 743 | c->addr << 1, c->adapter->name); |
778 | memcpy(client, &ks0127_client_tmpl, sizeof(*client)); | ||
779 | 744 | ||
780 | ks = kzalloc(sizeof(*ks), GFP_KERNEL); | 745 | ks = kzalloc(sizeof(*ks), GFP_KERNEL); |
781 | if (ks == NULL) { | 746 | if (ks == NULL) |
782 | kfree(client); | ||
783 | return -ENOMEM; | 747 | return -ENOMEM; |
784 | } | ||
785 | 748 | ||
786 | i2c_set_clientdata(client, ks); | 749 | i2c_set_clientdata(c, ks); |
787 | client->adapter = adapter; | ||
788 | client->addr = addr; | ||
789 | sprintf(client->name, "ks0127-%02x", adapter->id); | ||
790 | 750 | ||
791 | ks->client = client; | ||
792 | ks->addr = addr; | ||
793 | ks->ks_type = KS_TYPE_UNKNOWN; | 751 | ks->ks_type = KS_TYPE_UNKNOWN; |
794 | 752 | ||
795 | /* power up */ | 753 | /* power up */ |
796 | ks0127_write(ks, KS_CMDA, 0x2c); | 754 | init_reg_defaults(); |
755 | ks0127_write(c, KS_CMDA, 0x2c); | ||
797 | mdelay(10); | 756 | mdelay(10); |
798 | 757 | ||
799 | /* reset the device */ | 758 | /* reset the device */ |
800 | ks0127_reset(ks); | 759 | ks0127_reset(c); |
801 | printk(KERN_INFO "ks0127: attach: %s video decoder\n", | ||
802 | ks->addr==(I2C_KS0127_ADDON>>1) ? "addon" : "on-board"); | ||
803 | |||
804 | i2c_attach_client(client); | ||
805 | return 0; | 760 | return 0; |
806 | } | 761 | } |
807 | 762 | ||
808 | 763 | static int ks0127_remove(struct i2c_client *c) | |
809 | static int ks0127_probe(struct i2c_adapter *adapter) | ||
810 | { | 764 | { |
811 | if (adapter->id == I2C_HW_B_ZR36067) | 765 | struct ks0127 *ks = i2c_get_clientdata(c); |
812 | return i2c_probe(adapter, &addr_data, ks0127_found_proc); | ||
813 | return 0; | ||
814 | } | ||
815 | |||
816 | static int ks0127_detach(struct i2c_client *client) | ||
817 | { | ||
818 | struct ks0127 *ks = i2c_get_clientdata(client); | ||
819 | 766 | ||
820 | ks0127_write(ks, KS_OFMTA, 0x20); /*tristate*/ | 767 | ks0127_write(c, KS_OFMTA, 0x20); /* tristate */ |
821 | ks0127_write(ks, KS_CMDA, 0x2c | 0x80); /* power down */ | 768 | ks0127_write(c, KS_CMDA, 0x2c | 0x80); /* power down */ |
822 | 769 | ||
823 | i2c_detach_client(client); | ||
824 | kfree(ks); | 770 | kfree(ks); |
825 | kfree(client); | ||
826 | |||
827 | dprintk("ks0127: detach\n"); | ||
828 | return 0; | 771 | return 0; |
829 | } | 772 | } |
830 | 773 | ||
831 | 774 | static int ks0127_legacy_probe(struct i2c_adapter *adapter) | |
832 | static int __devinit ks0127_init_module(void) | ||
833 | { | 775 | { |
834 | init_reg_defaults(); | 776 | return adapter->id == I2C_HW_B_ZR36067; |
835 | return i2c_add_driver(&i2c_driver_ks0127); | ||
836 | } | 777 | } |
837 | 778 | ||
838 | static void __devexit ks0127_cleanup_module(void) | 779 | static const struct i2c_device_id ks0127_id[] = { |
839 | { | 780 | { "ks0127", 0 }, |
840 | i2c_del_driver(&i2c_driver_ks0127); | 781 | { } |
841 | } | 782 | }; |
842 | 783 | MODULE_DEVICE_TABLE(i2c, ks0127_id); | |
843 | 784 | ||
844 | module_init(ks0127_init_module); | 785 | static struct v4l2_i2c_driver_data v4l2_i2c_data = { |
845 | module_exit(ks0127_cleanup_module); | 786 | .name = "ks0127", |
787 | .driverid = I2C_DRIVERID_KS0127, | ||
788 | .command = ks0127_command, | ||
789 | .probe = ks0127_probe, | ||
790 | .remove = ks0127_remove, | ||
791 | .legacy_probe = ks0127_legacy_probe, | ||
792 | .id_table = ks0127_id, | ||
793 | }; | ||
diff --git a/drivers/media/video/saa7110.c b/drivers/media/video/saa7110.c index 4aa82b310708..adf2ba79496a 100644 --- a/drivers/media/video/saa7110.c +++ b/drivers/media/video/saa7110.c | |||
@@ -31,36 +31,24 @@ | |||
31 | #include <linux/delay.h> | 31 | #include <linux/delay.h> |
32 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
33 | #include <linux/wait.h> | 33 | #include <linux/wait.h> |
34 | #include <asm/io.h> | ||
35 | #include <asm/uaccess.h> | 34 | #include <asm/uaccess.h> |
35 | #include <linux/i2c.h> | ||
36 | #include <linux/videodev.h> | ||
37 | #include <linux/video_decoder.h> | ||
38 | #include <media/v4l2-common.h> | ||
39 | #include <media/v4l2-i2c-drv-legacy.h> | ||
36 | 40 | ||
37 | MODULE_DESCRIPTION("Philips SAA7110 video decoder driver"); | 41 | MODULE_DESCRIPTION("Philips SAA7110 video decoder driver"); |
38 | MODULE_AUTHOR("Pauline Middelink"); | 42 | MODULE_AUTHOR("Pauline Middelink"); |
39 | MODULE_LICENSE("GPL"); | 43 | MODULE_LICENSE("GPL"); |
40 | 44 | ||
41 | #include <linux/i2c.h> | ||
42 | |||
43 | #define I2C_NAME(s) (s)->name | ||
44 | |||
45 | #include <linux/videodev.h> | ||
46 | #include <media/v4l2-common.h> | ||
47 | #include <linux/video_decoder.h> | ||
48 | |||
49 | static int debug; | 45 | static int debug; |
50 | module_param(debug, int, 0); | 46 | module_param(debug, int, 0); |
51 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); | 47 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); |
52 | 48 | ||
53 | #define dprintk(num, format, args...) \ | ||
54 | do { \ | ||
55 | if (debug >= num) \ | ||
56 | printk(format, ##args); \ | ||
57 | } while (0) | ||
58 | |||
59 | #define SAA7110_MAX_INPUT 9 /* 6 CVBS, 3 SVHS */ | 49 | #define SAA7110_MAX_INPUT 9 /* 6 CVBS, 3 SVHS */ |
60 | #define SAA7110_MAX_OUTPUT 0 /* its a decoder only */ | 50 | #define SAA7110_MAX_OUTPUT 0 /* its a decoder only */ |
61 | 51 | ||
62 | #define I2C_SAA7110 0x9C /* or 0x9E */ | ||
63 | |||
64 | #define SAA7110_NR_REG 0x35 | 52 | #define SAA7110_NR_REG 0x35 |
65 | 53 | ||
66 | struct saa7110 { | 54 | struct saa7110 { |
@@ -81,10 +69,7 @@ struct saa7110 { | |||
81 | /* I2C support functions */ | 69 | /* I2C support functions */ |
82 | /* ----------------------------------------------------------------------- */ | 70 | /* ----------------------------------------------------------------------- */ |
83 | 71 | ||
84 | static int | 72 | static int saa7110_write(struct i2c_client *client, u8 reg, u8 value) |
85 | saa7110_write (struct i2c_client *client, | ||
86 | u8 reg, | ||
87 | u8 value) | ||
88 | { | 73 | { |
89 | struct saa7110 *decoder = i2c_get_clientdata(client); | 74 | struct saa7110 *decoder = i2c_get_clientdata(client); |
90 | 75 | ||
@@ -92,10 +77,7 @@ saa7110_write (struct i2c_client *client, | |||
92 | return i2c_smbus_write_byte_data(client, reg, value); | 77 | return i2c_smbus_write_byte_data(client, reg, value); |
93 | } | 78 | } |
94 | 79 | ||
95 | static int | 80 | static int saa7110_write_block(struct i2c_client *client, const u8 *data, unsigned int len) |
96 | saa7110_write_block (struct i2c_client *client, | ||
97 | const u8 *data, | ||
98 | unsigned int len) | ||
99 | { | 81 | { |
100 | int ret = -1; | 82 | int ret = -1; |
101 | u8 reg = *data; /* first register to write to */ | 83 | u8 reg = *data; /* first register to write to */ |
@@ -115,8 +97,8 @@ saa7110_write_block (struct i2c_client *client, | |||
115 | memcpy(decoder->reg + reg, data + 1, len - 1); | 97 | memcpy(decoder->reg + reg, data + 1, len - 1); |
116 | } else { | 98 | } else { |
117 | for (++data, --len; len; len--) { | 99 | for (++data, --len; len; len--) { |
118 | if ((ret = saa7110_write(client, reg++, | 100 | ret = saa7110_write(client, reg++, *data++); |
119 | *data++)) < 0) | 101 | if (ret < 0) |
120 | break; | 102 | break; |
121 | } | 103 | } |
122 | } | 104 | } |
@@ -124,8 +106,7 @@ saa7110_write_block (struct i2c_client *client, | |||
124 | return ret; | 106 | return ret; |
125 | } | 107 | } |
126 | 108 | ||
127 | static inline int | 109 | static inline int saa7110_read(struct i2c_client *client) |
128 | saa7110_read (struct i2c_client *client) | ||
129 | { | 110 | { |
130 | return i2c_smbus_read_byte(client); | 111 | return i2c_smbus_read_byte(client); |
131 | } | 112 | } |
@@ -138,9 +119,7 @@ saa7110_read (struct i2c_client *client) | |||
138 | #define FRESP_06H_SVIDEO 0x83 //0xC0 | 119 | #define FRESP_06H_SVIDEO 0x83 //0xC0 |
139 | 120 | ||
140 | 121 | ||
141 | static int | 122 | static int saa7110_selmux(struct i2c_client *client, int chan) |
142 | saa7110_selmux (struct i2c_client *client, | ||
143 | int chan) | ||
144 | { | 123 | { |
145 | static const unsigned char modes[9][8] = { | 124 | static const unsigned char modes[9][8] = { |
146 | /* mode 0 */ | 125 | /* mode 0 */ |
@@ -197,8 +176,7 @@ static const unsigned char initseq[1 + SAA7110_NR_REG] = { | |||
197 | /* 0x30 */ 0x44, 0x71, 0x02, 0x8C, 0x02 | 176 | /* 0x30 */ 0x44, 0x71, 0x02, 0x8C, 0x02 |
198 | }; | 177 | }; |
199 | 178 | ||
200 | static int | 179 | static int determine_norm(struct i2c_client *client) |
201 | determine_norm (struct i2c_client *client) | ||
202 | { | 180 | { |
203 | DEFINE_WAIT(wait); | 181 | DEFINE_WAIT(wait); |
204 | struct saa7110 *decoder = i2c_get_clientdata(client); | 182 | struct saa7110 *decoder = i2c_get_clientdata(client); |
@@ -212,29 +190,23 @@ determine_norm (struct i2c_client *client) | |||
212 | finish_wait(&decoder->wq, &wait); | 190 | finish_wait(&decoder->wq, &wait); |
213 | status = saa7110_read(client); | 191 | status = saa7110_read(client); |
214 | if (status & 0x40) { | 192 | if (status & 0x40) { |
215 | dprintk(1, KERN_INFO "%s: status=0x%02x (no signal)\n", | 193 | v4l_dbg(1, debug, client, "status=0x%02x (no signal)\n", status); |
216 | I2C_NAME(client), status); | ||
217 | return decoder->norm; // no change | 194 | return decoder->norm; // no change |
218 | } | 195 | } |
219 | if ((status & 3) == 0) { | 196 | if ((status & 3) == 0) { |
220 | saa7110_write(client, 0x06, 0x83); | 197 | saa7110_write(client, 0x06, 0x83); |
221 | if (status & 0x20) { | 198 | if (status & 0x20) { |
222 | dprintk(1, | 199 | v4l_dbg(1, debug, client, "status=0x%02x (NTSC/no color)\n", status); |
223 | KERN_INFO | ||
224 | "%s: status=0x%02x (NTSC/no color)\n", | ||
225 | I2C_NAME(client), status); | ||
226 | //saa7110_write(client,0x2E,0x81); | 200 | //saa7110_write(client,0x2E,0x81); |
227 | return VIDEO_MODE_NTSC; | 201 | return VIDEO_MODE_NTSC; |
228 | } | 202 | } |
229 | dprintk(1, KERN_INFO "%s: status=0x%02x (PAL/no color)\n", | 203 | v4l_dbg(1, debug, client, "status=0x%02x (PAL/no color)\n", status); |
230 | I2C_NAME(client), status); | ||
231 | //saa7110_write(client,0x2E,0x9A); | 204 | //saa7110_write(client,0x2E,0x9A); |
232 | return VIDEO_MODE_PAL; | 205 | return VIDEO_MODE_PAL; |
233 | } | 206 | } |
234 | //saa7110_write(client,0x06,0x03); | 207 | //saa7110_write(client,0x06,0x03); |
235 | if (status & 0x20) { /* 60Hz */ | 208 | if (status & 0x20) { /* 60Hz */ |
236 | dprintk(1, KERN_INFO "%s: status=0x%02x (NTSC)\n", | 209 | v4l_dbg(1, debug, client, "status=0x%02x (NTSC)\n", status); |
237 | I2C_NAME(client), status); | ||
238 | saa7110_write(client, 0x0D, 0x86); | 210 | saa7110_write(client, 0x0D, 0x86); |
239 | saa7110_write(client, 0x0F, 0x50); | 211 | saa7110_write(client, 0x0F, 0x50); |
240 | saa7110_write(client, 0x11, 0x2C); | 212 | saa7110_write(client, 0x11, 0x2C); |
@@ -254,13 +226,11 @@ determine_norm (struct i2c_client *client) | |||
254 | 226 | ||
255 | status = saa7110_read(client); | 227 | status = saa7110_read(client); |
256 | if ((status & 0x03) == 0x01) { | 228 | if ((status & 0x03) == 0x01) { |
257 | dprintk(1, KERN_INFO "%s: status=0x%02x (SECAM)\n", | 229 | v4l_dbg(1, debug, client, "status=0x%02x (SECAM)\n", status); |
258 | I2C_NAME(client), status); | ||
259 | saa7110_write(client, 0x0D, 0x87); | 230 | saa7110_write(client, 0x0D, 0x87); |
260 | return VIDEO_MODE_SECAM; | 231 | return VIDEO_MODE_SECAM; |
261 | } | 232 | } |
262 | dprintk(1, KERN_INFO "%s: status=0x%02x (PAL)\n", I2C_NAME(client), | 233 | v4l_dbg(1, debug, client, "status=0x%02x (PAL)\n", status); |
263 | status); | ||
264 | return VIDEO_MODE_PAL; | 234 | return VIDEO_MODE_PAL; |
265 | } | 235 | } |
266 | 236 | ||
@@ -286,8 +256,8 @@ saa7110_command (struct i2c_client *client, | |||
286 | VIDEO_DECODER_SECAM | VIDEO_DECODER_AUTO; | 256 | VIDEO_DECODER_SECAM | VIDEO_DECODER_AUTO; |
287 | dc->inputs = SAA7110_MAX_INPUT; | 257 | dc->inputs = SAA7110_MAX_INPUT; |
288 | dc->outputs = SAA7110_MAX_OUTPUT; | 258 | dc->outputs = SAA7110_MAX_OUTPUT; |
289 | } | ||
290 | break; | 259 | break; |
260 | } | ||
291 | 261 | ||
292 | case DECODER_GET_STATUS: | 262 | case DECODER_GET_STATUS: |
293 | { | 263 | { |
@@ -295,8 +265,8 @@ saa7110_command (struct i2c_client *client, | |||
295 | int res = 0; | 265 | int res = 0; |
296 | 266 | ||
297 | status = saa7110_read(client); | 267 | status = saa7110_read(client); |
298 | dprintk(1, KERN_INFO "%s: status=0x%02x norm=%d\n", | 268 | v4l_dbg(1, debug, client, "status=0x%02x norm=%d\n", |
299 | I2C_NAME(client), status, decoder->norm); | 269 | status, decoder->norm); |
300 | if (!(status & 0x40)) | 270 | if (!(status & 0x40)) |
301 | res |= DECODER_STATUS_GOOD; | 271 | res |= DECODER_STATUS_GOOD; |
302 | if (status & 0x03) | 272 | if (status & 0x03) |
@@ -314,8 +284,8 @@ saa7110_command (struct i2c_client *client, | |||
314 | break; | 284 | break; |
315 | } | 285 | } |
316 | *(int *) arg = res; | 286 | *(int *) arg = res; |
317 | } | ||
318 | break; | 287 | break; |
288 | } | ||
319 | 289 | ||
320 | case DECODER_SET_NORM: | 290 | case DECODER_SET_NORM: |
321 | v = *(int *) arg; | 291 | v = *(int *) arg; |
@@ -328,34 +298,24 @@ saa7110_command (struct i2c_client *client, | |||
328 | saa7110_write(client, 0x0F, 0x50); | 298 | saa7110_write(client, 0x0F, 0x50); |
329 | saa7110_write(client, 0x11, 0x2C); | 299 | saa7110_write(client, 0x11, 0x2C); |
330 | //saa7110_write(client, 0x2E, 0x81); | 300 | //saa7110_write(client, 0x2E, 0x81); |
331 | dprintk(1, | 301 | v4l_dbg(1, debug, client, "switched to NTSC\n"); |
332 | KERN_INFO "%s: switched to NTSC\n", | ||
333 | I2C_NAME(client)); | ||
334 | break; | 302 | break; |
335 | case VIDEO_MODE_PAL: | 303 | case VIDEO_MODE_PAL: |
336 | saa7110_write(client, 0x0D, 0x86); | 304 | saa7110_write(client, 0x0D, 0x86); |
337 | saa7110_write(client, 0x0F, 0x10); | 305 | saa7110_write(client, 0x0F, 0x10); |
338 | saa7110_write(client, 0x11, 0x59); | 306 | saa7110_write(client, 0x11, 0x59); |
339 | //saa7110_write(client, 0x2E, 0x9A); | 307 | //saa7110_write(client, 0x2E, 0x9A); |
340 | dprintk(1, | 308 | v4l_dbg(1, debug, client, "switched to PAL\n"); |
341 | KERN_INFO "%s: switched to PAL\n", | ||
342 | I2C_NAME(client)); | ||
343 | break; | 309 | break; |
344 | case VIDEO_MODE_SECAM: | 310 | case VIDEO_MODE_SECAM: |
345 | saa7110_write(client, 0x0D, 0x87); | 311 | saa7110_write(client, 0x0D, 0x87); |
346 | saa7110_write(client, 0x0F, 0x10); | 312 | saa7110_write(client, 0x0F, 0x10); |
347 | saa7110_write(client, 0x11, 0x59); | 313 | saa7110_write(client, 0x11, 0x59); |
348 | //saa7110_write(client, 0x2E, 0x9A); | 314 | //saa7110_write(client, 0x2E, 0x9A); |
349 | dprintk(1, | 315 | v4l_dbg(1, debug, client, "switched to SECAM\n"); |
350 | KERN_INFO | ||
351 | "%s: switched to SECAM\n", | ||
352 | I2C_NAME(client)); | ||
353 | break; | 316 | break; |
354 | case VIDEO_MODE_AUTO: | 317 | case VIDEO_MODE_AUTO: |
355 | dprintk(1, | 318 | v4l_dbg(1, debug, client, "switched to AUTO\n"); |
356 | KERN_INFO | ||
357 | "%s: TV standard detection...\n", | ||
358 | I2C_NAME(client)); | ||
359 | decoder->norm = determine_norm(client); | 319 | decoder->norm = determine_norm(client); |
360 | *(int *) arg = decoder->norm; | 320 | *(int *) arg = decoder->norm; |
361 | break; | 321 | break; |
@@ -368,15 +328,12 @@ saa7110_command (struct i2c_client *client, | |||
368 | case DECODER_SET_INPUT: | 328 | case DECODER_SET_INPUT: |
369 | v = *(int *) arg; | 329 | v = *(int *) arg; |
370 | if (v < 0 || v > SAA7110_MAX_INPUT) { | 330 | if (v < 0 || v > SAA7110_MAX_INPUT) { |
371 | dprintk(1, | 331 | v4l_dbg(1, debug, client, "input=%d not available\n", v); |
372 | KERN_INFO "%s: input=%d not available\n", | ||
373 | I2C_NAME(client), v); | ||
374 | return -EINVAL; | 332 | return -EINVAL; |
375 | } | 333 | } |
376 | if (decoder->input != v) { | 334 | if (decoder->input != v) { |
377 | saa7110_selmux(client, v); | 335 | saa7110_selmux(client, v); |
378 | dprintk(1, KERN_INFO "%s: switched to input=%d\n", | 336 | v4l_dbg(1, debug, client, "switched to input=%d\n", v); |
379 | I2C_NAME(client), v); | ||
380 | } | 337 | } |
381 | break; | 338 | break; |
382 | 339 | ||
@@ -392,8 +349,7 @@ saa7110_command (struct i2c_client *client, | |||
392 | if (decoder->enable != v) { | 349 | if (decoder->enable != v) { |
393 | decoder->enable = v; | 350 | decoder->enable = v; |
394 | saa7110_write(client, 0x0E, v ? 0x18 : 0x80); | 351 | saa7110_write(client, 0x0E, v ? 0x18 : 0x80); |
395 | dprintk(1, KERN_INFO "%s: YUV %s\n", I2C_NAME(client), | 352 | v4l_dbg(1, debug, client, "YUV %s\n", v ? "on" : "off"); |
396 | v ? "on" : "off"); | ||
397 | } | 353 | } |
398 | break; | 354 | break; |
399 | 355 | ||
@@ -423,23 +379,23 @@ saa7110_command (struct i2c_client *client, | |||
423 | saa7110_write(client, 0x07, | 379 | saa7110_write(client, 0x07, |
424 | (decoder->hue >> 8) - 128); | 380 | (decoder->hue >> 8) - 128); |
425 | } | 381 | } |
426 | } | ||
427 | break; | 382 | break; |
383 | } | ||
428 | 384 | ||
429 | case DECODER_DUMP: | 385 | case DECODER_DUMP: |
386 | if (!debug) | ||
387 | break; | ||
430 | for (v = 0; v < SAA7110_NR_REG; v += 16) { | 388 | for (v = 0; v < SAA7110_NR_REG; v += 16) { |
431 | int j; | 389 | int j; |
432 | dprintk(1, KERN_DEBUG "%s: %02x:", I2C_NAME(client), | 390 | v4l_dbg(1, debug, client, "%02x:", v); |
433 | v); | ||
434 | for (j = 0; j < 16 && v + j < SAA7110_NR_REG; j++) | 391 | for (j = 0; j < 16 && v + j < SAA7110_NR_REG; j++) |
435 | dprintk(1, " %02x", decoder->reg[v + j]); | 392 | printk(KERN_CONT " %02x", decoder->reg[v + j]); |
436 | dprintk(1, "\n"); | 393 | printk(KERN_CONT "\n"); |
437 | } | 394 | } |
438 | break; | 395 | break; |
439 | 396 | ||
440 | default: | 397 | default: |
441 | dprintk(1, KERN_INFO "unknown saa7110_command??(%d)\n", | 398 | v4l_dbg(1, debug, client, "unknown command %08x\n", cmd); |
442 | cmd); | ||
443 | return -EINVAL; | 399 | return -EINVAL; |
444 | } | 400 | } |
445 | return 0; | 401 | return 0; |
@@ -451,55 +407,28 @@ saa7110_command (struct i2c_client *client, | |||
451 | * Generic i2c probe | 407 | * Generic i2c probe |
452 | * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1' | 408 | * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1' |
453 | */ | 409 | */ |
454 | static unsigned short normal_i2c[] = { | ||
455 | I2C_SAA7110 >> 1, | ||
456 | (I2C_SAA7110 >> 1) + 1, | ||
457 | I2C_CLIENT_END | ||
458 | }; | ||
459 | |||
460 | static unsigned short ignore = I2C_CLIENT_END; | ||
461 | 410 | ||
462 | static struct i2c_client_address_data addr_data = { | 411 | static unsigned short normal_i2c[] = { 0x9c >> 1, 0x9e >> 1, I2C_CLIENT_END }; |
463 | .normal_i2c = normal_i2c, | ||
464 | .probe = &ignore, | ||
465 | .ignore = &ignore, | ||
466 | }; | ||
467 | 412 | ||
468 | static struct i2c_driver i2c_driver_saa7110; | 413 | I2C_CLIENT_INSMOD; |
469 | 414 | ||
470 | static int | 415 | static int saa7110_probe(struct i2c_client *client, |
471 | saa7110_detect_client (struct i2c_adapter *adapter, | 416 | const struct i2c_device_id *id) |
472 | int address, | ||
473 | int kind) | ||
474 | { | 417 | { |
475 | struct i2c_client *client; | ||
476 | struct saa7110 *decoder; | 418 | struct saa7110 *decoder; |
477 | int rv; | 419 | int rv; |
478 | 420 | ||
479 | dprintk(1, | ||
480 | KERN_INFO | ||
481 | "saa7110.c: detecting saa7110 client on address 0x%x\n", | ||
482 | address << 1); | ||
483 | |||
484 | /* Check if the adapter supports the needed features */ | 421 | /* Check if the adapter supports the needed features */ |
485 | if (!i2c_check_functionality | 422 | if (!i2c_check_functionality(client->adapter, |
486 | (adapter, | 423 | I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) |
487 | I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) | 424 | return -ENODEV; |
488 | return 0; | ||
489 | 425 | ||
490 | client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); | 426 | v4l_info(client, "chip found @ 0x%x (%s)\n", |
491 | if (!client) | 427 | client->addr << 1, client->adapter->name); |
492 | return -ENOMEM; | ||
493 | client->addr = address; | ||
494 | client->adapter = adapter; | ||
495 | client->driver = &i2c_driver_saa7110; | ||
496 | strlcpy(I2C_NAME(client), "saa7110", sizeof(I2C_NAME(client))); | ||
497 | 428 | ||
498 | decoder = kzalloc(sizeof(struct saa7110), GFP_KERNEL); | 429 | decoder = kzalloc(sizeof(struct saa7110), GFP_KERNEL); |
499 | if (!decoder) { | 430 | if (!decoder) |
500 | kfree(client); | ||
501 | return -ENOMEM; | 431 | return -ENOMEM; |
502 | } | ||
503 | decoder->norm = VIDEO_MODE_PAL; | 432 | decoder->norm = VIDEO_MODE_PAL; |
504 | decoder->input = 0; | 433 | decoder->input = 0; |
505 | decoder->enable = 1; | 434 | decoder->enable = 1; |
@@ -510,18 +439,10 @@ saa7110_detect_client (struct i2c_adapter *adapter, | |||
510 | init_waitqueue_head(&decoder->wq); | 439 | init_waitqueue_head(&decoder->wq); |
511 | i2c_set_clientdata(client, decoder); | 440 | i2c_set_clientdata(client, decoder); |
512 | 441 | ||
513 | rv = i2c_attach_client(client); | ||
514 | if (rv) { | ||
515 | kfree(client); | ||
516 | kfree(decoder); | ||
517 | return rv; | ||
518 | } | ||
519 | |||
520 | rv = saa7110_write_block(client, initseq, sizeof(initseq)); | 442 | rv = saa7110_write_block(client, initseq, sizeof(initseq)); |
521 | if (rv < 0) | 443 | if (rv < 0) { |
522 | dprintk(1, KERN_ERR "%s_attach: init status %d\n", | 444 | v4l_dbg(1, debug, client, "init status %d\n", rv); |
523 | I2C_NAME(client), rv); | 445 | } else { |
524 | else { | ||
525 | int ver, status; | 446 | int ver, status; |
526 | saa7110_write(client, 0x21, 0x10); | 447 | saa7110_write(client, 0x21, 0x10); |
527 | saa7110_write(client, 0x0e, 0x18); | 448 | saa7110_write(client, 0x0e, 0x18); |
@@ -530,10 +451,8 @@ saa7110_detect_client (struct i2c_adapter *adapter, | |||
530 | saa7110_write(client, 0x0D, 0x06); | 451 | saa7110_write(client, 0x0D, 0x06); |
531 | //mdelay(150); | 452 | //mdelay(150); |
532 | status = saa7110_read(client); | 453 | status = saa7110_read(client); |
533 | dprintk(1, | 454 | v4l_dbg(1, debug, client, "version %x, status=0x%02x\n", |
534 | KERN_INFO | 455 | ver, status); |
535 | "%s_attach: SAA7110A version %x at 0x%02x, status=0x%02x\n", | ||
536 | I2C_NAME(client), ver, client->addr << 1, status); | ||
537 | saa7110_write(client, 0x0D, 0x86); | 456 | saa7110_write(client, 0x0D, 0x86); |
538 | saa7110_write(client, 0x0F, 0x10); | 457 | saa7110_write(client, 0x0F, 0x10); |
539 | saa7110_write(client, 0x11, 0x59); | 458 | saa7110_write(client, 0x11, 0x59); |
@@ -547,58 +466,25 @@ saa7110_detect_client (struct i2c_adapter *adapter, | |||
547 | return 0; | 466 | return 0; |
548 | } | 467 | } |
549 | 468 | ||
550 | static int | 469 | static int saa7110_remove(struct i2c_client *client) |
551 | saa7110_attach_adapter (struct i2c_adapter *adapter) | ||
552 | { | ||
553 | dprintk(1, | ||
554 | KERN_INFO | ||
555 | "saa7110.c: starting probe for adapter %s (0x%x)\n", | ||
556 | I2C_NAME(adapter), adapter->id); | ||
557 | return i2c_probe(adapter, &addr_data, &saa7110_detect_client); | ||
558 | } | ||
559 | |||
560 | static int | ||
561 | saa7110_detach_client (struct i2c_client *client) | ||
562 | { | 470 | { |
563 | struct saa7110 *decoder = i2c_get_clientdata(client); | 471 | kfree(i2c_get_clientdata(client)); |
564 | int err; | ||
565 | |||
566 | err = i2c_detach_client(client); | ||
567 | if (err) { | ||
568 | return err; | ||
569 | } | ||
570 | |||
571 | kfree(decoder); | ||
572 | kfree(client); | ||
573 | |||
574 | return 0; | 472 | return 0; |
575 | } | 473 | } |
576 | 474 | ||
577 | /* ----------------------------------------------------------------------- */ | 475 | /* ----------------------------------------------------------------------- */ |
578 | 476 | ||
579 | static struct i2c_driver i2c_driver_saa7110 = { | 477 | static const struct i2c_device_id saa7110_id[] = { |
580 | .driver = { | 478 | { "saa7110", 0 }, |
581 | .name = "saa7110", | 479 | { } |
582 | }, | 480 | }; |
583 | 481 | MODULE_DEVICE_TABLE(i2c, saa7110_id); | |
584 | .id = I2C_DRIVERID_SAA7110, | ||
585 | 482 | ||
586 | .attach_adapter = saa7110_attach_adapter, | 483 | static struct v4l2_i2c_driver_data v4l2_i2c_data = { |
587 | .detach_client = saa7110_detach_client, | 484 | .name = "saa7110", |
485 | .driverid = I2C_DRIVERID_SAA7110, | ||
588 | .command = saa7110_command, | 486 | .command = saa7110_command, |
487 | .probe = saa7110_probe, | ||
488 | .remove = saa7110_remove, | ||
489 | .id_table = saa7110_id, | ||
589 | }; | 490 | }; |
590 | |||
591 | static int __init | ||
592 | saa7110_init (void) | ||
593 | { | ||
594 | return i2c_add_driver(&i2c_driver_saa7110); | ||
595 | } | ||
596 | |||
597 | static void __exit | ||
598 | saa7110_exit (void) | ||
599 | { | ||
600 | i2c_del_driver(&i2c_driver_saa7110); | ||
601 | } | ||
602 | |||
603 | module_init(saa7110_init); | ||
604 | module_exit(saa7110_exit); | ||
diff --git a/drivers/media/video/saa7111.c b/drivers/media/video/saa7111.c index 96c3d4357722..a4738a2fb4d3 100644 --- a/drivers/media/video/saa7111.c +++ b/drivers/media/video/saa7111.c | |||
@@ -28,43 +28,24 @@ | |||
28 | */ | 28 | */ |
29 | 29 | ||
30 | #include <linux/module.h> | 30 | #include <linux/module.h> |
31 | #include <linux/init.h> | ||
32 | #include <linux/delay.h> | ||
33 | #include <linux/errno.h> | ||
34 | #include <linux/fs.h> | ||
35 | #include <linux/kernel.h> | ||
36 | #include <linux/major.h> | ||
37 | #include <linux/slab.h> | ||
38 | #include <linux/mm.h> | ||
39 | #include <linux/signal.h> | ||
40 | #include <linux/types.h> | 31 | #include <linux/types.h> |
41 | #include <linux/i2c.h> | 32 | #include <linux/ioctl.h> |
42 | #include <asm/io.h> | ||
43 | #include <asm/pgtable.h> | ||
44 | #include <asm/page.h> | ||
45 | #include <asm/uaccess.h> | 33 | #include <asm/uaccess.h> |
46 | 34 | #include <linux/i2c.h> | |
35 | #include <linux/i2c-id.h> | ||
47 | #include <linux/videodev.h> | 36 | #include <linux/videodev.h> |
48 | #include <linux/video_decoder.h> | 37 | #include <linux/video_decoder.h> |
38 | #include <media/v4l2-common.h> | ||
39 | #include <media/v4l2-i2c-drv-legacy.h> | ||
49 | 40 | ||
50 | MODULE_DESCRIPTION("Philips SAA7111 video decoder driver"); | 41 | MODULE_DESCRIPTION("Philips SAA7111 video decoder driver"); |
51 | MODULE_AUTHOR("Dave Perks"); | 42 | MODULE_AUTHOR("Dave Perks"); |
52 | MODULE_LICENSE("GPL"); | 43 | MODULE_LICENSE("GPL"); |
53 | 44 | ||
54 | |||
55 | #define I2C_NAME(s) (s)->name | ||
56 | |||
57 | |||
58 | static int debug; | 45 | static int debug; |
59 | module_param(debug, int, 0644); | 46 | module_param(debug, int, 0644); |
60 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); | 47 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); |
61 | 48 | ||
62 | #define dprintk(num, format, args...) \ | ||
63 | do { \ | ||
64 | if (debug >= num) \ | ||
65 | printk(format, ##args); \ | ||
66 | } while (0) | ||
67 | |||
68 | /* ----------------------------------------------------------------------- */ | 49 | /* ----------------------------------------------------------------------- */ |
69 | 50 | ||
70 | #define SAA7111_NR_REG 0x18 | 51 | #define SAA7111_NR_REG 0x18 |
@@ -77,14 +58,9 @@ struct saa7111 { | |||
77 | int enable; | 58 | int enable; |
78 | }; | 59 | }; |
79 | 60 | ||
80 | #define I2C_SAA7111 0x48 | ||
81 | |||
82 | /* ----------------------------------------------------------------------- */ | 61 | /* ----------------------------------------------------------------------- */ |
83 | 62 | ||
84 | static inline int | 63 | static inline int saa7111_write(struct i2c_client *client, u8 reg, u8 value) |
85 | saa7111_write (struct i2c_client *client, | ||
86 | u8 reg, | ||
87 | u8 value) | ||
88 | { | 64 | { |
89 | struct saa7111 *decoder = i2c_get_clientdata(client); | 65 | struct saa7111 *decoder = i2c_get_clientdata(client); |
90 | 66 | ||
@@ -92,8 +68,7 @@ saa7111_write (struct i2c_client *client, | |||
92 | return i2c_smbus_write_byte_data(client, reg, value); | 68 | return i2c_smbus_write_byte_data(client, reg, value); |
93 | } | 69 | } |
94 | 70 | ||
95 | static inline void | 71 | static inline void saa7111_write_if_changed(struct i2c_client *client, u8 reg, u8 value) |
96 | saa7111_write_if_changed(struct i2c_client *client, u8 reg, u8 value) | ||
97 | { | 72 | { |
98 | struct saa7111 *decoder = i2c_get_clientdata(client); | 73 | struct saa7111 *decoder = i2c_get_clientdata(client); |
99 | 74 | ||
@@ -103,10 +78,7 @@ saa7111_write_if_changed(struct i2c_client *client, u8 reg, u8 value) | |||
103 | } | 78 | } |
104 | } | 79 | } |
105 | 80 | ||
106 | static int | 81 | static int saa7111_write_block(struct i2c_client *client, const u8 *data, unsigned int len) |
107 | saa7111_write_block (struct i2c_client *client, | ||
108 | const u8 *data, | ||
109 | unsigned int len) | ||
110 | { | 82 | { |
111 | int ret = -1; | 83 | int ret = -1; |
112 | u8 reg; | 84 | u8 reg; |
@@ -127,18 +99,17 @@ saa7111_write_block (struct i2c_client *client, | |||
127 | decoder->reg[reg++] = data[1]; | 99 | decoder->reg[reg++] = data[1]; |
128 | len -= 2; | 100 | len -= 2; |
129 | data += 2; | 101 | data += 2; |
130 | } while (len >= 2 && data[0] == reg && | 102 | } while (len >= 2 && data[0] == reg && block_len < 32); |
131 | block_len < 32); | 103 | ret = i2c_master_send(client, block_data, block_len); |
132 | if ((ret = i2c_master_send(client, block_data, | 104 | if (ret < 0) |
133 | block_len)) < 0) | ||
134 | break; | 105 | break; |
135 | } | 106 | } |
136 | } else { | 107 | } else { |
137 | /* do some slow I2C emulation kind of thing */ | 108 | /* do some slow I2C emulation kind of thing */ |
138 | while (len >= 2) { | 109 | while (len >= 2) { |
139 | reg = *data++; | 110 | reg = *data++; |
140 | if ((ret = saa7111_write(client, reg, | 111 | ret = saa7111_write(client, reg, *data++); |
141 | *data++)) < 0) | 112 | if (ret < 0) |
142 | break; | 113 | break; |
143 | len -= 2; | 114 | len -= 2; |
144 | } | 115 | } |
@@ -147,16 +118,13 @@ saa7111_write_block (struct i2c_client *client, | |||
147 | return ret; | 118 | return ret; |
148 | } | 119 | } |
149 | 120 | ||
150 | static int | 121 | static int saa7111_init_decoder(struct i2c_client *client, |
151 | saa7111_init_decoder (struct i2c_client *client, | 122 | struct video_decoder_init *init) |
152 | struct video_decoder_init *init) | ||
153 | { | 123 | { |
154 | return saa7111_write_block(client, init->data, init->len); | 124 | return saa7111_write_block(client, init->data, init->len); |
155 | } | 125 | } |
156 | 126 | ||
157 | static inline int | 127 | static inline int saa7111_read(struct i2c_client *client, u8 reg) |
158 | saa7111_read (struct i2c_client *client, | ||
159 | u8 reg) | ||
160 | { | 128 | { |
161 | return i2c_smbus_read_byte_data(client, reg); | 129 | return i2c_smbus_read_byte_data(client, reg); |
162 | } | 130 | } |
@@ -203,28 +171,23 @@ static const unsigned char saa7111_i2c_init[] = { | |||
203 | 0x17, 0x00, /* 17 - VBI */ | 171 | 0x17, 0x00, /* 17 - VBI */ |
204 | }; | 172 | }; |
205 | 173 | ||
206 | static int | 174 | static int saa7111_command(struct i2c_client *client, unsigned cmd, void *arg) |
207 | saa7111_command (struct i2c_client *client, | ||
208 | unsigned int cmd, | ||
209 | void *arg) | ||
210 | { | 175 | { |
211 | struct saa7111 *decoder = i2c_get_clientdata(client); | 176 | struct saa7111 *decoder = i2c_get_clientdata(client); |
212 | 177 | ||
213 | switch (cmd) { | 178 | switch (cmd) { |
214 | |||
215 | case 0: | 179 | case 0: |
216 | break; | 180 | break; |
217 | case DECODER_INIT: | 181 | case DECODER_INIT: |
218 | { | 182 | { |
219 | struct video_decoder_init *init = arg; | 183 | struct video_decoder_init *init = arg; |
184 | struct video_decoder_init vdi; | ||
185 | |||
220 | if (NULL != init) | 186 | if (NULL != init) |
221 | return saa7111_init_decoder(client, init); | 187 | return saa7111_init_decoder(client, init); |
222 | else { | 188 | vdi.data = saa7111_i2c_init; |
223 | struct video_decoder_init vdi; | 189 | vdi.len = sizeof(saa7111_i2c_init); |
224 | vdi.data = saa7111_i2c_init; | 190 | return saa7111_init_decoder(client, &vdi); |
225 | vdi.len = sizeof(saa7111_i2c_init); | ||
226 | return saa7111_init_decoder(client, &vdi); | ||
227 | } | ||
228 | } | 191 | } |
229 | 192 | ||
230 | case DECODER_DUMP: | 193 | case DECODER_DUMP: |
@@ -234,15 +197,15 @@ saa7111_command (struct i2c_client *client, | |||
234 | for (i = 0; i < SAA7111_NR_REG; i += 16) { | 197 | for (i = 0; i < SAA7111_NR_REG; i += 16) { |
235 | int j; | 198 | int j; |
236 | 199 | ||
237 | printk(KERN_DEBUG "%s: %03x", I2C_NAME(client), i); | 200 | v4l_info(client, "%03x", i); |
238 | for (j = 0; j < 16 && i + j < SAA7111_NR_REG; ++j) { | 201 | for (j = 0; j < 16 && i + j < SAA7111_NR_REG; ++j) { |
239 | printk(" %02x", | 202 | printk(KERN_CONT " %02x", |
240 | saa7111_read(client, i + j)); | 203 | saa7111_read(client, i + j)); |
241 | } | 204 | } |
242 | printk("\n"); | 205 | printk(KERN_CONT "\n"); |
243 | } | 206 | } |
244 | } | ||
245 | break; | 207 | break; |
208 | } | ||
246 | 209 | ||
247 | case DECODER_GET_CAPABILITIES: | 210 | case DECODER_GET_CAPABILITIES: |
248 | { | 211 | { |
@@ -255,8 +218,8 @@ saa7111_command (struct i2c_client *client, | |||
255 | VIDEO_DECODER_CCIR; | 218 | VIDEO_DECODER_CCIR; |
256 | cap->inputs = 8; | 219 | cap->inputs = 8; |
257 | cap->outputs = 1; | 220 | cap->outputs = 1; |
258 | } | ||
259 | break; | 221 | break; |
222 | } | ||
260 | 223 | ||
261 | case DECODER_GET_STATUS: | 224 | case DECODER_GET_STATUS: |
262 | { | 225 | { |
@@ -265,8 +228,7 @@ saa7111_command (struct i2c_client *client, | |||
265 | int res; | 228 | int res; |
266 | 229 | ||
267 | status = saa7111_read(client, 0x1f); | 230 | status = saa7111_read(client, 0x1f); |
268 | dprintk(1, KERN_DEBUG "%s status: 0x%02x\n", I2C_NAME(client), | 231 | v4l_dbg(1, debug, client, "status: 0x%02x\n", status); |
269 | status); | ||
270 | res = 0; | 232 | res = 0; |
271 | if ((status & (1 << 6)) == 0) { | 233 | if ((status & (1 << 6)) == 0) { |
272 | res |= DECODER_STATUS_GOOD; | 234 | res |= DECODER_STATUS_GOOD; |
@@ -294,8 +256,8 @@ saa7111_command (struct i2c_client *client, | |||
294 | res |= DECODER_STATUS_COLOR; | 256 | res |= DECODER_STATUS_COLOR; |
295 | } | 257 | } |
296 | *iarg = res; | 258 | *iarg = res; |
297 | } | ||
298 | break; | 259 | break; |
260 | } | ||
299 | 261 | ||
300 | case DECODER_SET_GPIO: | 262 | case DECODER_SET_GPIO: |
301 | { | 263 | { |
@@ -362,8 +324,8 @@ saa7111_command (struct i2c_client *client, | |||
362 | 324 | ||
363 | } | 325 | } |
364 | decoder->norm = *iarg; | 326 | decoder->norm = *iarg; |
365 | } | ||
366 | break; | 327 | break; |
328 | } | ||
367 | 329 | ||
368 | case DECODER_SET_INPUT: | 330 | case DECODER_SET_INPUT: |
369 | { | 331 | { |
@@ -387,8 +349,8 @@ saa7111_command (struct i2c_client *client, | |||
387 | 3) ? 0x80 : | 349 | 3) ? 0x80 : |
388 | 0)); | 350 | 0)); |
389 | } | 351 | } |
390 | } | ||
391 | break; | 352 | break; |
353 | } | ||
392 | 354 | ||
393 | case DECODER_SET_OUTPUT: | 355 | case DECODER_SET_OUTPUT: |
394 | { | 356 | { |
@@ -398,8 +360,8 @@ saa7111_command (struct i2c_client *client, | |||
398 | if (*iarg != 0) { | 360 | if (*iarg != 0) { |
399 | return -EINVAL; | 361 | return -EINVAL; |
400 | } | 362 | } |
401 | } | ||
402 | break; | 363 | break; |
364 | } | ||
403 | 365 | ||
404 | case DECODER_ENABLE_OUTPUT: | 366 | case DECODER_ENABLE_OUTPUT: |
405 | { | 367 | { |
@@ -439,8 +401,8 @@ saa7111_command (struct i2c_client *client, | |||
439 | (decoder->reg[0x11] & 0xf3)); | 401 | (decoder->reg[0x11] & 0xf3)); |
440 | } | 402 | } |
441 | } | 403 | } |
442 | } | ||
443 | break; | 404 | break; |
405 | } | ||
444 | 406 | ||
445 | case DECODER_SET_PICTURE: | 407 | case DECODER_SET_PICTURE: |
446 | { | 408 | { |
@@ -454,8 +416,8 @@ saa7111_command (struct i2c_client *client, | |||
454 | saa7111_write(client, 0x0c, pic->colour >> 9); | 416 | saa7111_write(client, 0x0c, pic->colour >> 9); |
455 | /* We want -128 to 127 we get 0-65535 */ | 417 | /* We want -128 to 127 we get 0-65535 */ |
456 | saa7111_write(client, 0x0d, (pic->hue - 32768) >> 8); | 418 | saa7111_write(client, 0x0d, (pic->hue - 32768) >> 8); |
457 | } | ||
458 | break; | 419 | break; |
420 | } | ||
459 | 421 | ||
460 | default: | 422 | default: |
461 | return -EINVAL; | 423 | return -EINVAL; |
@@ -466,48 +428,23 @@ saa7111_command (struct i2c_client *client, | |||
466 | 428 | ||
467 | /* ----------------------------------------------------------------------- */ | 429 | /* ----------------------------------------------------------------------- */ |
468 | 430 | ||
469 | /* | 431 | static unsigned short normal_i2c[] = { 0x48 >> 1, I2C_CLIENT_END }; |
470 | * Generic i2c probe | ||
471 | * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1' | ||
472 | */ | ||
473 | static unsigned short normal_i2c[] = { I2C_SAA7111 >> 1, I2C_CLIENT_END }; | ||
474 | |||
475 | static unsigned short ignore = I2C_CLIENT_END; | ||
476 | |||
477 | static struct i2c_client_address_data addr_data = { | ||
478 | .normal_i2c = normal_i2c, | ||
479 | .probe = &ignore, | ||
480 | .ignore = &ignore, | ||
481 | }; | ||
482 | 432 | ||
483 | static struct i2c_driver i2c_driver_saa7111; | 433 | I2C_CLIENT_INSMOD; |
484 | 434 | ||
485 | static int | 435 | static int saa7111_probe(struct i2c_client *client, |
486 | saa7111_detect_client (struct i2c_adapter *adapter, | 436 | const struct i2c_device_id *id) |
487 | int address, | ||
488 | int kind) | ||
489 | { | 437 | { |
490 | int i; | 438 | int i; |
491 | struct i2c_client *client; | ||
492 | struct saa7111 *decoder; | 439 | struct saa7111 *decoder; |
493 | struct video_decoder_init vdi; | 440 | struct video_decoder_init vdi; |
494 | 441 | ||
495 | dprintk(1, | ||
496 | KERN_INFO | ||
497 | "saa7111.c: detecting saa7111 client on address 0x%x\n", | ||
498 | address << 1); | ||
499 | |||
500 | /* Check if the adapter supports the needed features */ | 442 | /* Check if the adapter supports the needed features */ |
501 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | 443 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) |
502 | return 0; | 444 | return -ENODEV; |
503 | 445 | ||
504 | client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); | 446 | v4l_info(client, "chip found @ 0x%x (%s)\n", |
505 | if (!client) | 447 | client->addr << 1, client->adapter->name); |
506 | return -ENOMEM; | ||
507 | client->addr = address; | ||
508 | client->adapter = adapter; | ||
509 | client->driver = &i2c_driver_saa7111; | ||
510 | strlcpy(I2C_NAME(client), "saa7111", sizeof(I2C_NAME(client))); | ||
511 | 448 | ||
512 | decoder = kzalloc(sizeof(struct saa7111), GFP_KERNEL); | 449 | decoder = kzalloc(sizeof(struct saa7111), GFP_KERNEL); |
513 | if (decoder == NULL) { | 450 | if (decoder == NULL) { |
@@ -519,82 +456,37 @@ saa7111_detect_client (struct i2c_adapter *adapter, | |||
519 | decoder->enable = 1; | 456 | decoder->enable = 1; |
520 | i2c_set_clientdata(client, decoder); | 457 | i2c_set_clientdata(client, decoder); |
521 | 458 | ||
522 | i = i2c_attach_client(client); | ||
523 | if (i) { | ||
524 | kfree(client); | ||
525 | kfree(decoder); | ||
526 | return i; | ||
527 | } | ||
528 | |||
529 | vdi.data = saa7111_i2c_init; | 459 | vdi.data = saa7111_i2c_init; |
530 | vdi.len = sizeof(saa7111_i2c_init); | 460 | vdi.len = sizeof(saa7111_i2c_init); |
531 | i = saa7111_init_decoder(client, &vdi); | 461 | i = saa7111_init_decoder(client, &vdi); |
532 | if (i < 0) { | 462 | if (i < 0) { |
533 | dprintk(1, KERN_ERR "%s_attach error: init status %d\n", | 463 | v4l_dbg(1, debug, client, "init status %d\n", i); |
534 | I2C_NAME(client), i); | ||
535 | } else { | 464 | } else { |
536 | dprintk(1, | 465 | v4l_dbg(1, debug, client, "revision %x\n", |
537 | KERN_INFO | 466 | saa7111_read(client, 0x00) >> 4); |
538 | "%s_attach: chip version %x at address 0x%x\n", | ||
539 | I2C_NAME(client), saa7111_read(client, 0x00) >> 4, | ||
540 | client->addr << 1); | ||
541 | } | 467 | } |
542 | |||
543 | return 0; | 468 | return 0; |
544 | } | 469 | } |
545 | 470 | ||
546 | static int | 471 | static int saa7111_remove(struct i2c_client *client) |
547 | saa7111_attach_adapter (struct i2c_adapter *adapter) | ||
548 | { | 472 | { |
549 | dprintk(1, | 473 | kfree(i2c_get_clientdata(client)); |
550 | KERN_INFO | ||
551 | "saa7111.c: starting probe for adapter %s (0x%x)\n", | ||
552 | I2C_NAME(adapter), adapter->id); | ||
553 | return i2c_probe(adapter, &addr_data, &saa7111_detect_client); | ||
554 | } | ||
555 | |||
556 | static int | ||
557 | saa7111_detach_client (struct i2c_client *client) | ||
558 | { | ||
559 | struct saa7111 *decoder = i2c_get_clientdata(client); | ||
560 | int err; | ||
561 | |||
562 | err = i2c_detach_client(client); | ||
563 | if (err) { | ||
564 | return err; | ||
565 | } | ||
566 | |||
567 | kfree(decoder); | ||
568 | kfree(client); | ||
569 | |||
570 | return 0; | 474 | return 0; |
571 | } | 475 | } |
572 | 476 | ||
573 | /* ----------------------------------------------------------------------- */ | 477 | /* ----------------------------------------------------------------------- */ |
574 | 478 | ||
575 | static struct i2c_driver i2c_driver_saa7111 = { | 479 | static const struct i2c_device_id saa7111_id[] = { |
576 | .driver = { | 480 | { "saa7111_old", 0 }, /* "saa7111" maps to the saa7115 driver */ |
577 | .name = "saa7111", | 481 | { } |
578 | }, | 482 | }; |
579 | 483 | MODULE_DEVICE_TABLE(i2c, saa7111_id); | |
580 | .id = I2C_DRIVERID_SAA7111A, | ||
581 | 484 | ||
582 | .attach_adapter = saa7111_attach_adapter, | 485 | static struct v4l2_i2c_driver_data v4l2_i2c_data = { |
583 | .detach_client = saa7111_detach_client, | 486 | .name = "saa7111", |
487 | .driverid = I2C_DRIVERID_SAA7111A, | ||
584 | .command = saa7111_command, | 488 | .command = saa7111_command, |
489 | .probe = saa7111_probe, | ||
490 | .remove = saa7111_remove, | ||
491 | .id_table = saa7111_id, | ||
585 | }; | 492 | }; |
586 | |||
587 | static int __init | ||
588 | saa7111_init (void) | ||
589 | { | ||
590 | return i2c_add_driver(&i2c_driver_saa7111); | ||
591 | } | ||
592 | |||
593 | static void __exit | ||
594 | saa7111_exit (void) | ||
595 | { | ||
596 | i2c_del_driver(&i2c_driver_saa7111); | ||
597 | } | ||
598 | |||
599 | module_init(saa7111_init); | ||
600 | module_exit(saa7111_exit); | ||
diff --git a/drivers/media/video/saa7114.c b/drivers/media/video/saa7114.c index e79075533beb..7ca709fda5f4 100644 --- a/drivers/media/video/saa7114.c +++ b/drivers/media/video/saa7114.c | |||
@@ -29,43 +29,24 @@ | |||
29 | */ | 29 | */ |
30 | 30 | ||
31 | #include <linux/module.h> | 31 | #include <linux/module.h> |
32 | #include <linux/init.h> | ||
33 | #include <linux/delay.h> | ||
34 | #include <linux/errno.h> | ||
35 | #include <linux/fs.h> | ||
36 | #include <linux/kernel.h> | ||
37 | #include <linux/major.h> | ||
38 | #include <linux/slab.h> | ||
39 | #include <linux/mm.h> | ||
40 | #include <linux/signal.h> | ||
41 | #include <linux/types.h> | 32 | #include <linux/types.h> |
42 | #include <linux/i2c.h> | 33 | #include <linux/ioctl.h> |
43 | #include <asm/io.h> | ||
44 | #include <asm/pgtable.h> | ||
45 | #include <asm/page.h> | ||
46 | #include <asm/uaccess.h> | 34 | #include <asm/uaccess.h> |
47 | 35 | #include <linux/i2c.h> | |
36 | #include <linux/i2c-id.h> | ||
48 | #include <linux/videodev.h> | 37 | #include <linux/videodev.h> |
49 | #include <linux/video_decoder.h> | 38 | #include <linux/video_decoder.h> |
39 | #include <media/v4l2-common.h> | ||
40 | #include <media/v4l2-i2c-drv-legacy.h> | ||
50 | 41 | ||
51 | MODULE_DESCRIPTION("Philips SAA7114H video decoder driver"); | 42 | MODULE_DESCRIPTION("Philips SAA7114H video decoder driver"); |
52 | MODULE_AUTHOR("Maxim Yevtyushkin"); | 43 | MODULE_AUTHOR("Maxim Yevtyushkin"); |
53 | MODULE_LICENSE("GPL"); | 44 | MODULE_LICENSE("GPL"); |
54 | 45 | ||
55 | |||
56 | #define I2C_NAME(x) (x)->name | ||
57 | |||
58 | |||
59 | static int debug; | 46 | static int debug; |
60 | module_param(debug, int, 0); | 47 | module_param(debug, int, 0); |
61 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); | 48 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); |
62 | 49 | ||
63 | #define dprintk(num, format, args...) \ | ||
64 | do { \ | ||
65 | if (debug >= num) \ | ||
66 | printk(format, ##args); \ | ||
67 | } while (0) | ||
68 | |||
69 | /* ----------------------------------------------------------------------- */ | 50 | /* ----------------------------------------------------------------------- */ |
70 | 51 | ||
71 | struct saa7114 { | 52 | struct saa7114 { |
@@ -81,9 +62,6 @@ struct saa7114 { | |||
81 | int playback; | 62 | int playback; |
82 | }; | 63 | }; |
83 | 64 | ||
84 | #define I2C_SAA7114 0x42 | ||
85 | #define I2C_SAA7114A 0x40 | ||
86 | |||
87 | #define I2C_DELAY 10 | 65 | #define I2C_DELAY 10 |
88 | 66 | ||
89 | 67 | ||
@@ -129,18 +107,12 @@ struct saa7114 { | |||
129 | 107 | ||
130 | /* ----------------------------------------------------------------------- */ | 108 | /* ----------------------------------------------------------------------- */ |
131 | 109 | ||
132 | static inline int | 110 | static inline int saa7114_write(struct i2c_client *client, u8 reg, u8 value) |
133 | saa7114_write (struct i2c_client *client, | ||
134 | u8 reg, | ||
135 | u8 value) | ||
136 | { | 111 | { |
137 | return i2c_smbus_write_byte_data(client, reg, value); | 112 | return i2c_smbus_write_byte_data(client, reg, value); |
138 | } | 113 | } |
139 | 114 | ||
140 | static int | 115 | static int saa7114_write_block(struct i2c_client *client, const u8 *data, unsigned int len) |
141 | saa7114_write_block (struct i2c_client *client, | ||
142 | const u8 *data, | ||
143 | unsigned int len) | ||
144 | { | 116 | { |
145 | int ret = -1; | 117 | int ret = -1; |
146 | u8 reg; | 118 | u8 reg; |
@@ -160,18 +132,17 @@ saa7114_write_block (struct i2c_client *client, | |||
160 | reg++; | 132 | reg++; |
161 | len -= 2; | 133 | len -= 2; |
162 | data += 2; | 134 | data += 2; |
163 | } while (len >= 2 && data[0] == reg && | 135 | } while (len >= 2 && data[0] == reg && block_len < 32); |
164 | block_len < 32); | 136 | ret = i2c_master_send(client, block_data, block_len); |
165 | if ((ret = i2c_master_send(client, block_data, | 137 | if (ret < 0) |
166 | block_len)) < 0) | ||
167 | break; | 138 | break; |
168 | } | 139 | } |
169 | } else { | 140 | } else { |
170 | /* do some slow I2C emulation kind of thing */ | 141 | /* do some slow I2C emulation kind of thing */ |
171 | while (len >= 2) { | 142 | while (len >= 2) { |
172 | reg = *data++; | 143 | reg = *data++; |
173 | if ((ret = saa7114_write(client, reg, | 144 | ret = saa7114_write(client, reg, *data++); |
174 | *data++)) < 0) | 145 | if (ret < 0) |
175 | break; | 146 | break; |
176 | len -= 2; | 147 | len -= 2; |
177 | } | 148 | } |
@@ -180,9 +151,7 @@ saa7114_write_block (struct i2c_client *client, | |||
180 | return ret; | 151 | return ret; |
181 | } | 152 | } |
182 | 153 | ||
183 | static inline int | 154 | static inline int saa7114_read(struct i2c_client *client, u8 reg) |
184 | saa7114_read (struct i2c_client *client, | ||
185 | u8 reg) | ||
186 | { | 155 | { |
187 | return i2c_smbus_read_byte_data(client, reg); | 156 | return i2c_smbus_read_byte_data(client, reg); |
188 | } | 157 | } |
@@ -452,15 +421,11 @@ static const unsigned char init[] = { | |||
452 | 0xef, 0x00 | 421 | 0xef, 0x00 |
453 | }; | 422 | }; |
454 | 423 | ||
455 | static int | 424 | static int saa7114_command(struct i2c_client *client, unsigned cmd, void *arg) |
456 | saa7114_command (struct i2c_client *client, | ||
457 | unsigned int cmd, | ||
458 | void *arg) | ||
459 | { | 425 | { |
460 | struct saa7114 *decoder = i2c_get_clientdata(client); | 426 | struct saa7114 *decoder = i2c_get_clientdata(client); |
461 | 427 | ||
462 | switch (cmd) { | 428 | switch (cmd) { |
463 | |||
464 | case 0: | 429 | case 0: |
465 | //dprintk(1, KERN_INFO "%s: writing init\n", I2C_NAME(client)); | 430 | //dprintk(1, KERN_INFO "%s: writing init\n", I2C_NAME(client)); |
466 | //saa7114_write_block(client, init, sizeof(init)); | 431 | //saa7114_write_block(client, init, sizeof(init)); |
@@ -470,27 +435,28 @@ saa7114_command (struct i2c_client *client, | |||
470 | { | 435 | { |
471 | int i; | 436 | int i; |
472 | 437 | ||
473 | dprintk(1, KERN_INFO "%s: decoder dump\n", I2C_NAME(client)); | 438 | if (!debug) |
439 | break; | ||
440 | v4l_info(client, "decoder dump\n"); | ||
474 | 441 | ||
475 | for (i = 0; i < 32; i += 16) { | 442 | for (i = 0; i < 32; i += 16) { |
476 | int j; | 443 | int j; |
477 | 444 | ||
478 | printk(KERN_DEBUG "%s: %03x", I2C_NAME(client), i); | 445 | v4l_info(client, "%03x", i); |
479 | for (j = 0; j < 16; ++j) { | 446 | for (j = 0; j < 16; ++j) { |
480 | printk(" %02x", | 447 | printk(KERN_CONT " %02x", |
481 | saa7114_read(client, i + j)); | 448 | saa7114_read(client, i + j)); |
482 | } | 449 | } |
483 | printk("\n"); | 450 | printk(KERN_CONT "\n"); |
484 | } | 451 | } |
485 | } | ||
486 | break; | 452 | break; |
453 | } | ||
487 | 454 | ||
488 | case DECODER_GET_CAPABILITIES: | 455 | case DECODER_GET_CAPABILITIES: |
489 | { | 456 | { |
490 | struct video_decoder_capability *cap = arg; | 457 | struct video_decoder_capability *cap = arg; |
491 | 458 | ||
492 | dprintk(1, KERN_DEBUG "%s: decoder get capabilities\n", | 459 | v4l_dbg(1, debug, client, "get capabilities\n"); |
493 | I2C_NAME(client)); | ||
494 | 460 | ||
495 | cap->flags = VIDEO_DECODER_PAL | | 461 | cap->flags = VIDEO_DECODER_PAL | |
496 | VIDEO_DECODER_NTSC | | 462 | VIDEO_DECODER_NTSC | |
@@ -498,8 +464,8 @@ saa7114_command (struct i2c_client *client, | |||
498 | VIDEO_DECODER_CCIR; | 464 | VIDEO_DECODER_CCIR; |
499 | cap->inputs = 8; | 465 | cap->inputs = 8; |
500 | cap->outputs = 1; | 466 | cap->outputs = 1; |
501 | } | ||
502 | break; | 467 | break; |
468 | } | ||
503 | 469 | ||
504 | case DECODER_GET_STATUS: | 470 | case DECODER_GET_STATUS: |
505 | { | 471 | { |
@@ -509,8 +475,7 @@ saa7114_command (struct i2c_client *client, | |||
509 | 475 | ||
510 | status = saa7114_read(client, 0x1f); | 476 | status = saa7114_read(client, 0x1f); |
511 | 477 | ||
512 | dprintk(1, KERN_DEBUG "%s status: 0x%02x\n", I2C_NAME(client), | 478 | v4l_dbg(1, debug, client, "status: 0x%02x\n", status); |
513 | status); | ||
514 | res = 0; | 479 | res = 0; |
515 | if ((status & (1 << 6)) == 0) { | 480 | if ((status & (1 << 6)) == 0) { |
516 | res |= DECODER_STATUS_GOOD; | 481 | res |= DECODER_STATUS_GOOD; |
@@ -538,8 +503,8 @@ saa7114_command (struct i2c_client *client, | |||
538 | res |= DECODER_STATUS_COLOR; | 503 | res |= DECODER_STATUS_COLOR; |
539 | } | 504 | } |
540 | *iarg = res; | 505 | *iarg = res; |
541 | } | ||
542 | break; | 506 | break; |
507 | } | ||
543 | 508 | ||
544 | case DECODER_SET_NORM: | 509 | case DECODER_SET_NORM: |
545 | { | 510 | { |
@@ -547,12 +512,11 @@ saa7114_command (struct i2c_client *client, | |||
547 | 512 | ||
548 | short int hoff = 0, voff = 0, w = 0, h = 0; | 513 | short int hoff = 0, voff = 0, w = 0, h = 0; |
549 | 514 | ||
550 | dprintk(1, KERN_DEBUG "%s: decoder set norm ", | 515 | v4l_dbg(1, debug, client, "set norm\n"); |
551 | I2C_NAME(client)); | ||
552 | switch (*iarg) { | ||
553 | 516 | ||
517 | switch (*iarg) { | ||
554 | case VIDEO_MODE_NTSC: | 518 | case VIDEO_MODE_NTSC: |
555 | dprintk(1, "NTSC\n"); | 519 | v4l_dbg(1, debug, client, "NTSC\n"); |
556 | decoder->reg[REG_ADDR(0x06)] = | 520 | decoder->reg[REG_ADDR(0x06)] = |
557 | SAA_7114_NTSC_HSYNC_START; | 521 | SAA_7114_NTSC_HSYNC_START; |
558 | decoder->reg[REG_ADDR(0x07)] = | 522 | decoder->reg[REG_ADDR(0x07)] = |
@@ -571,7 +535,7 @@ saa7114_command (struct i2c_client *client, | |||
571 | break; | 535 | break; |
572 | 536 | ||
573 | case VIDEO_MODE_PAL: | 537 | case VIDEO_MODE_PAL: |
574 | dprintk(1, "PAL\n"); | 538 | v4l_dbg(1, debug, client, "PAL\n"); |
575 | decoder->reg[REG_ADDR(0x06)] = | 539 | decoder->reg[REG_ADDR(0x06)] = |
576 | SAA_7114_PAL_HSYNC_START; | 540 | SAA_7114_PAL_HSYNC_START; |
577 | decoder->reg[REG_ADDR(0x07)] = | 541 | decoder->reg[REG_ADDR(0x07)] = |
@@ -590,9 +554,8 @@ saa7114_command (struct i2c_client *client, | |||
590 | break; | 554 | break; |
591 | 555 | ||
592 | default: | 556 | default: |
593 | dprintk(1, " Unknown video mode!!!\n"); | 557 | v4l_dbg(1, debug, client, "Unknown video mode\n"); |
594 | return -EINVAL; | 558 | return -EINVAL; |
595 | |||
596 | } | 559 | } |
597 | 560 | ||
598 | 561 | ||
@@ -644,22 +607,20 @@ saa7114_command (struct i2c_client *client, | |||
644 | saa7114_write(client, 0x80, 0x36); // i-port and scaler back end clock selection | 607 | saa7114_write(client, 0x80, 0x36); // i-port and scaler back end clock selection |
645 | 608 | ||
646 | decoder->norm = *iarg; | 609 | decoder->norm = *iarg; |
647 | } | ||
648 | break; | 610 | break; |
611 | } | ||
649 | 612 | ||
650 | case DECODER_SET_INPUT: | 613 | case DECODER_SET_INPUT: |
651 | { | 614 | { |
652 | int *iarg = arg; | 615 | int *iarg = arg; |
653 | 616 | ||
654 | dprintk(1, KERN_DEBUG "%s: decoder set input (%d)\n", | 617 | v4l_dbg(1, debug, client, "set input (%d)\n", *iarg); |
655 | I2C_NAME(client), *iarg); | ||
656 | if (*iarg < 0 || *iarg > 7) { | 618 | if (*iarg < 0 || *iarg > 7) { |
657 | return -EINVAL; | 619 | return -EINVAL; |
658 | } | 620 | } |
659 | 621 | ||
660 | if (decoder->input != *iarg) { | 622 | if (decoder->input != *iarg) { |
661 | dprintk(1, KERN_DEBUG "%s: now setting %s input\n", | 623 | v4l_dbg(1, debug, client, "now setting %s input\n", |
662 | I2C_NAME(client), | ||
663 | *iarg >= 6 ? "S-Video" : "Composite"); | 624 | *iarg >= 6 ? "S-Video" : "Composite"); |
664 | decoder->input = *iarg; | 625 | decoder->input = *iarg; |
665 | 626 | ||
@@ -690,30 +651,29 @@ saa7114_command (struct i2c_client *client, | |||
690 | saa7114_write(client, 0x0e, | 651 | saa7114_write(client, 0x0e, |
691 | decoder->reg[REG_ADDR(0x0e)]); | 652 | decoder->reg[REG_ADDR(0x0e)]); |
692 | } | 653 | } |
693 | } | ||
694 | break; | 654 | break; |
655 | } | ||
695 | 656 | ||
696 | case DECODER_SET_OUTPUT: | 657 | case DECODER_SET_OUTPUT: |
697 | { | 658 | { |
698 | int *iarg = arg; | 659 | int *iarg = arg; |
699 | 660 | ||
700 | dprintk(1, KERN_DEBUG "%s: decoder set output\n", | 661 | v4l_dbg(1, debug, client, "set output\n"); |
701 | I2C_NAME(client)); | ||
702 | 662 | ||
703 | /* not much choice of outputs */ | 663 | /* not much choice of outputs */ |
704 | if (*iarg != 0) { | 664 | if (*iarg != 0) { |
705 | return -EINVAL; | 665 | return -EINVAL; |
706 | } | 666 | } |
707 | } | ||
708 | break; | 667 | break; |
668 | } | ||
709 | 669 | ||
710 | case DECODER_ENABLE_OUTPUT: | 670 | case DECODER_ENABLE_OUTPUT: |
711 | { | 671 | { |
712 | int *iarg = arg; | 672 | int *iarg = arg; |
713 | int enable = (*iarg != 0); | 673 | int enable = (*iarg != 0); |
714 | 674 | ||
715 | dprintk(1, KERN_DEBUG "%s: decoder %s output\n", | 675 | v4l_dbg(1, debug, client, "%s output\n", |
716 | I2C_NAME(client), enable ? "enable" : "disable"); | 676 | enable ? "enable" : "disable"); |
717 | 677 | ||
718 | decoder->playback = !enable; | 678 | decoder->playback = !enable; |
719 | 679 | ||
@@ -754,18 +714,16 @@ saa7114_command (struct i2c_client *client, | |||
754 | saa7114_write(client, 0x80, 0x36); | 714 | saa7114_write(client, 0x80, 0x36); |
755 | 715 | ||
756 | } | 716 | } |
757 | } | ||
758 | break; | 717 | break; |
718 | } | ||
759 | 719 | ||
760 | case DECODER_SET_PICTURE: | 720 | case DECODER_SET_PICTURE: |
761 | { | 721 | { |
762 | struct video_picture *pic = arg; | 722 | struct video_picture *pic = arg; |
763 | 723 | ||
764 | dprintk(1, | 724 | v4l_dbg(1, debug, client, |
765 | KERN_DEBUG | 725 | "decoder set picture bright=%d contrast=%d saturation=%d hue=%d\n", |
766 | "%s: decoder set picture bright=%d contrast=%d saturation=%d hue=%d\n", | 726 | pic->brightness, pic->contrast, pic->colour, pic->hue); |
767 | I2C_NAME(client), pic->brightness, pic->contrast, | ||
768 | pic->colour, pic->hue); | ||
769 | 727 | ||
770 | if (decoder->bright != pic->brightness) { | 728 | if (decoder->bright != pic->brightness) { |
771 | /* We want 0 to 255 we get 0-65535 */ | 729 | /* We want 0 to 255 we get 0-65535 */ |
@@ -789,8 +747,8 @@ saa7114_command (struct i2c_client *client, | |||
789 | saa7114_write(client, 0x0d, | 747 | saa7114_write(client, 0x0d, |
790 | (decoder->hue - 32768) >> 8); | 748 | (decoder->hue - 32768) >> 8); |
791 | } | 749 | } |
792 | } | ||
793 | break; | 750 | break; |
751 | } | ||
794 | 752 | ||
795 | default: | 753 | default: |
796 | return -EINVAL; | 754 | return -EINVAL; |
@@ -801,58 +759,30 @@ saa7114_command (struct i2c_client *client, | |||
801 | 759 | ||
802 | /* ----------------------------------------------------------------------- */ | 760 | /* ----------------------------------------------------------------------- */ |
803 | 761 | ||
804 | /* | 762 | static unsigned short normal_i2c[] = { 0x42 >> 1, 0x40 >> 1, I2C_CLIENT_END }; |
805 | * Generic i2c probe | ||
806 | * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1' | ||
807 | */ | ||
808 | static unsigned short normal_i2c[] = | ||
809 | { I2C_SAA7114 >> 1, I2C_SAA7114A >> 1, I2C_CLIENT_END }; | ||
810 | |||
811 | static unsigned short ignore = I2C_CLIENT_END; | ||
812 | |||
813 | static struct i2c_client_address_data addr_data = { | ||
814 | .normal_i2c = normal_i2c, | ||
815 | .probe = &ignore, | ||
816 | .ignore = &ignore, | ||
817 | }; | ||
818 | 763 | ||
819 | static struct i2c_driver i2c_driver_saa7114; | 764 | I2C_CLIENT_INSMOD; |
820 | 765 | ||
821 | static int | 766 | static int saa7114_probe(struct i2c_client *client, |
822 | saa7114_detect_client (struct i2c_adapter *adapter, | 767 | const struct i2c_device_id *id) |
823 | int address, | ||
824 | int kind) | ||
825 | { | 768 | { |
826 | int i, err[30]; | 769 | int i, err[30]; |
827 | short int hoff = SAA_7114_NTSC_HOFFSET; | 770 | short int hoff = SAA_7114_NTSC_HOFFSET; |
828 | short int voff = SAA_7114_NTSC_VOFFSET; | 771 | short int voff = SAA_7114_NTSC_VOFFSET; |
829 | short int w = SAA_7114_NTSC_WIDTH; | 772 | short int w = SAA_7114_NTSC_WIDTH; |
830 | short int h = SAA_7114_NTSC_HEIGHT; | 773 | short int h = SAA_7114_NTSC_HEIGHT; |
831 | struct i2c_client *client; | ||
832 | struct saa7114 *decoder; | 774 | struct saa7114 *decoder; |
833 | 775 | ||
834 | dprintk(1, | ||
835 | KERN_INFO | ||
836 | "saa7114.c: detecting saa7114 client on address 0x%x\n", | ||
837 | address << 1); | ||
838 | |||
839 | /* Check if the adapter supports the needed features */ | 776 | /* Check if the adapter supports the needed features */ |
840 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | 777 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) |
841 | return 0; | 778 | return -ENODEV; |
842 | 779 | ||
843 | client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); | 780 | v4l_info(client, "chip found @ 0x%x (%s)\n", |
844 | if (!client) | 781 | client->addr << 1, client->adapter->name); |
845 | return -ENOMEM; | ||
846 | client->addr = address; | ||
847 | client->adapter = adapter; | ||
848 | client->driver = &i2c_driver_saa7114; | ||
849 | strlcpy(I2C_NAME(client), "saa7114", sizeof(I2C_NAME(client))); | ||
850 | 782 | ||
851 | decoder = kzalloc(sizeof(struct saa7114), GFP_KERNEL); | 783 | decoder = kzalloc(sizeof(struct saa7114), GFP_KERNEL); |
852 | if (decoder == NULL) { | 784 | if (decoder == NULL) |
853 | kfree(client); | ||
854 | return -ENOMEM; | 785 | return -ENOMEM; |
855 | } | ||
856 | decoder->norm = VIDEO_MODE_NTSC; | 786 | decoder->norm = VIDEO_MODE_NTSC; |
857 | decoder->input = -1; | 787 | decoder->input = -1; |
858 | decoder->enable = 1; | 788 | decoder->enable = 1; |
@@ -937,8 +867,7 @@ saa7114_detect_client (struct i2c_adapter *adapter, | |||
937 | decoder->reg[REG_ADDR(0x0e)] |= 1; // combfilter on | 867 | decoder->reg[REG_ADDR(0x0e)] |= 1; // combfilter on |
938 | 868 | ||
939 | 869 | ||
940 | dprintk(1, KERN_DEBUG "%s_attach: starting decoder init\n", | 870 | v4l_dbg(1, debug, client, "starting init\n"); |
941 | I2C_NAME(client)); | ||
942 | 871 | ||
943 | err[0] = | 872 | err[0] = |
944 | saa7114_write_block(client, decoder->reg + (0x20 << 1), | 873 | saa7114_write_block(client, decoder->reg + (0x20 << 1), |
@@ -962,28 +891,23 @@ saa7114_detect_client (struct i2c_adapter *adapter, | |||
962 | 891 | ||
963 | for (i = 0; i <= 5; i++) { | 892 | for (i = 0; i <= 5; i++) { |
964 | if (err[i] < 0) { | 893 | if (err[i] < 0) { |
965 | dprintk(1, | 894 | v4l_dbg(1, debug, client, |
966 | KERN_ERR | 895 | "init error %d at stage %d, leaving attach.\n", |
967 | "%s_attach: init error %d at stage %d, leaving attach.\n", | 896 | i, err[i]); |
968 | I2C_NAME(client), i, err[i]); | ||
969 | kfree(decoder); | 897 | kfree(decoder); |
970 | kfree(client); | 898 | return -EIO; |
971 | return 0; | ||
972 | } | 899 | } |
973 | } | 900 | } |
974 | 901 | ||
975 | for (i = 6; i < 8; i++) { | 902 | for (i = 6; i < 8; i++) { |
976 | dprintk(1, | 903 | v4l_dbg(1, debug, client, |
977 | KERN_DEBUG | 904 | "reg[0x%02x] = 0x%02x (0x%02x)\n", |
978 | "%s_attach: reg[0x%02x] = 0x%02x (0x%02x)\n", | 905 | i, saa7114_read(client, i), |
979 | I2C_NAME(client), i, saa7114_read(client, i), | ||
980 | decoder->reg[REG_ADDR(i)]); | 906 | decoder->reg[REG_ADDR(i)]); |
981 | } | 907 | } |
982 | 908 | ||
983 | dprintk(1, | 909 | v4l_dbg(1, debug, client, |
984 | KERN_DEBUG | 910 | "performing decoder reset sequence\n"); |
985 | "%s_attach: performing decoder reset sequence\n", | ||
986 | I2C_NAME(client)); | ||
987 | 911 | ||
988 | err[6] = saa7114_write(client, 0x80, 0x06); // i-port and scaler backend clock selection, task A&B off | 912 | err[6] = saa7114_write(client, 0x80, 0x06); // i-port and scaler backend clock selection, task A&B off |
989 | err[7] = saa7114_write(client, 0x88, 0xd8); // sw reset scaler | 913 | err[7] = saa7114_write(client, 0x88, 0xd8); // sw reset scaler |
@@ -991,19 +915,15 @@ saa7114_detect_client (struct i2c_adapter *adapter, | |||
991 | 915 | ||
992 | for (i = 6; i <= 8; i++) { | 916 | for (i = 6; i <= 8; i++) { |
993 | if (err[i] < 0) { | 917 | if (err[i] < 0) { |
994 | dprintk(1, | 918 | v4l_dbg(1, debug, client, |
995 | KERN_ERR | 919 | "init error %d at stage %d, leaving attach.\n", |
996 | "%s_attach: init error %d at stage %d, leaving attach.\n", | 920 | i, err[i]); |
997 | I2C_NAME(client), i, err[i]); | ||
998 | kfree(decoder); | 921 | kfree(decoder); |
999 | kfree(client); | 922 | return -EIO; |
1000 | return 0; | ||
1001 | } | 923 | } |
1002 | } | 924 | } |
1003 | 925 | ||
1004 | dprintk(1, KERN_INFO "%s_attach: performing the rest of init\n", | 926 | v4l_dbg(1, debug, client, "performing the rest of init\n"); |
1005 | I2C_NAME(client)); | ||
1006 | |||
1007 | 927 | ||
1008 | err[9] = saa7114_write(client, 0x01, decoder->reg[REG_ADDR(0x01)]); | 928 | err[9] = saa7114_write(client, 0x01, decoder->reg[REG_ADDR(0x01)]); |
1009 | err[10] = saa7114_write_block(client, decoder->reg + (0x03 << 1), (0x1e + 1 - 0x03) << 1); // big seq | 929 | err[10] = saa7114_write_block(client, decoder->reg + (0x03 << 1), (0x1e + 1 - 0x03) << 1); // big seq |
@@ -1039,37 +959,32 @@ saa7114_detect_client (struct i2c_adapter *adapter, | |||
1039 | 959 | ||
1040 | for (i = 9; i <= 18; i++) { | 960 | for (i = 9; i <= 18; i++) { |
1041 | if (err[i] < 0) { | 961 | if (err[i] < 0) { |
1042 | dprintk(1, | 962 | v4l_dbg(1, debug, client, |
1043 | KERN_ERR | 963 | "init error %d at stage %d, leaving attach.\n", |
1044 | "%s_attach: init error %d at stage %d, leaving attach.\n", | 964 | i, err[i]); |
1045 | I2C_NAME(client), i, err[i]); | ||
1046 | kfree(decoder); | 965 | kfree(decoder); |
1047 | kfree(client); | 966 | return -EIO; |
1048 | return 0; | ||
1049 | } | 967 | } |
1050 | } | 968 | } |
1051 | 969 | ||
1052 | 970 | ||
1053 | for (i = 6; i < 8; i++) { | 971 | for (i = 6; i < 8; i++) { |
1054 | dprintk(1, | 972 | v4l_dbg(1, debug, client, |
1055 | KERN_DEBUG | 973 | "reg[0x%02x] = 0x%02x (0x%02x)\n", |
1056 | "%s_attach: reg[0x%02x] = 0x%02x (0x%02x)\n", | 974 | i, saa7114_read(client, i), |
1057 | I2C_NAME(client), i, saa7114_read(client, i), | ||
1058 | decoder->reg[REG_ADDR(i)]); | 975 | decoder->reg[REG_ADDR(i)]); |
1059 | } | 976 | } |
1060 | 977 | ||
1061 | 978 | ||
1062 | for (i = 0x11; i <= 0x13; i++) { | 979 | for (i = 0x11; i <= 0x13; i++) { |
1063 | dprintk(1, | 980 | v4l_dbg(1, debug, client, |
1064 | KERN_DEBUG | 981 | "reg[0x%02x] = 0x%02x (0x%02x)\n", |
1065 | "%s_attach: reg[0x%02x] = 0x%02x (0x%02x)\n", | 982 | i, saa7114_read(client, i), |
1066 | I2C_NAME(client), i, saa7114_read(client, i), | ||
1067 | decoder->reg[REG_ADDR(i)]); | 983 | decoder->reg[REG_ADDR(i)]); |
1068 | } | 984 | } |
1069 | 985 | ||
1070 | 986 | ||
1071 | dprintk(1, KERN_DEBUG "%s_attach: setting video input\n", | 987 | v4l_dbg(1, debug, client, "setting video input\n"); |
1072 | I2C_NAME(client)); | ||
1073 | 988 | ||
1074 | err[19] = | 989 | err[19] = |
1075 | saa7114_write(client, 0x02, decoder->reg[REG_ADDR(0x02)]); | 990 | saa7114_write(client, 0x02, decoder->reg[REG_ADDR(0x02)]); |
@@ -1080,20 +995,15 @@ saa7114_detect_client (struct i2c_adapter *adapter, | |||
1080 | 995 | ||
1081 | for (i = 19; i <= 21; i++) { | 996 | for (i = 19; i <= 21; i++) { |
1082 | if (err[i] < 0) { | 997 | if (err[i] < 0) { |
1083 | dprintk(1, | 998 | v4l_dbg(1, debug, client, |
1084 | KERN_ERR | 999 | "init error %d at stage %d, leaving attach.\n", |
1085 | "%s_attach: init error %d at stage %d, leaving attach.\n", | 1000 | i, err[i]); |
1086 | I2C_NAME(client), i, err[i]); | ||
1087 | kfree(decoder); | 1001 | kfree(decoder); |
1088 | kfree(client); | 1002 | return -EIO; |
1089 | return 0; | ||
1090 | } | 1003 | } |
1091 | } | 1004 | } |
1092 | 1005 | ||
1093 | dprintk(1, | 1006 | v4l_dbg(1, debug, client, "performing decoder reset sequence\n"); |
1094 | KERN_DEBUG | ||
1095 | "%s_attach: performing decoder reset sequence\n", | ||
1096 | I2C_NAME(client)); | ||
1097 | 1007 | ||
1098 | err[22] = saa7114_write(client, 0x88, 0xd8); // sw reset scaler | 1008 | err[22] = saa7114_write(client, 0x88, 0xd8); // sw reset scaler |
1099 | err[23] = saa7114_write(client, 0x88, 0xf8); // sw reset scaler release | 1009 | err[23] = saa7114_write(client, 0x88, 0xf8); // sw reset scaler release |
@@ -1102,13 +1012,11 @@ saa7114_detect_client (struct i2c_adapter *adapter, | |||
1102 | 1012 | ||
1103 | for (i = 22; i <= 24; i++) { | 1013 | for (i = 22; i <= 24; i++) { |
1104 | if (err[i] < 0) { | 1014 | if (err[i] < 0) { |
1105 | dprintk(1, | 1015 | v4l_dbg(1, debug, client, |
1106 | KERN_ERR | 1016 | "init error %d at stage %d, leaving attach.\n", |
1107 | "%s_attach: init error %d at stage %d, leaving attach.\n", | 1017 | i, err[i]); |
1108 | I2C_NAME(client), i, err[i]); | ||
1109 | kfree(decoder); | 1018 | kfree(decoder); |
1110 | kfree(client); | 1019 | return -EIO; |
1111 | return 0; | ||
1112 | } | 1020 | } |
1113 | } | 1021 | } |
1114 | 1022 | ||
@@ -1116,101 +1024,45 @@ saa7114_detect_client (struct i2c_adapter *adapter, | |||
1116 | err[26] = saa7114_write(client, 0x07, init[REG_ADDR(0x07)]); | 1024 | err[26] = saa7114_write(client, 0x07, init[REG_ADDR(0x07)]); |
1117 | err[27] = saa7114_write(client, 0x10, init[REG_ADDR(0x10)]); | 1025 | err[27] = saa7114_write(client, 0x10, init[REG_ADDR(0x10)]); |
1118 | 1026 | ||
1119 | dprintk(1, | 1027 | v4l_dbg(1, debug, client, "chip version %x, decoder status 0x%02x\n", |
1120 | KERN_INFO | 1028 | saa7114_read(client, 0x00) >> 4, |
1121 | "%s_attach: chip version %x, decoder status 0x%02x\n", | ||
1122 | I2C_NAME(client), saa7114_read(client, 0x00) >> 4, | ||
1123 | saa7114_read(client, 0x1f)); | 1029 | saa7114_read(client, 0x1f)); |
1124 | dprintk(1, | 1030 | v4l_dbg(1, debug, client, |
1125 | KERN_DEBUG | 1031 | "power save control: 0x%02x, scaler status: 0x%02x\n", |
1126 | "%s_attach: power save control: 0x%02x, scaler status: 0x%02x\n", | 1032 | saa7114_read(client, 0x88), |
1127 | I2C_NAME(client), saa7114_read(client, 0x88), | ||
1128 | saa7114_read(client, 0x8f)); | 1033 | saa7114_read(client, 0x8f)); |
1129 | 1034 | ||
1130 | 1035 | ||
1131 | for (i = 0x94; i < 0x96; i++) { | 1036 | for (i = 0x94; i < 0x96; i++) { |
1132 | dprintk(1, | 1037 | v4l_dbg(1, debug, client, |
1133 | KERN_DEBUG | 1038 | "reg[0x%02x] = 0x%02x (0x%02x)\n", |
1134 | "%s_attach: reg[0x%02x] = 0x%02x (0x%02x)\n", | 1039 | i, saa7114_read(client, i), |
1135 | I2C_NAME(client), i, saa7114_read(client, i), | ||
1136 | decoder->reg[REG_ADDR(i)]); | 1040 | decoder->reg[REG_ADDR(i)]); |
1137 | } | 1041 | } |
1138 | 1042 | ||
1139 | i = i2c_attach_client(client); | ||
1140 | if (i) { | ||
1141 | kfree(client); | ||
1142 | kfree(decoder); | ||
1143 | return i; | ||
1144 | } | ||
1145 | |||
1146 | //i = saa7114_write_block(client, init, sizeof(init)); | 1043 | //i = saa7114_write_block(client, init, sizeof(init)); |
1147 | i = 0; | ||
1148 | if (i < 0) { | ||
1149 | dprintk(1, KERN_ERR "%s_attach error: init status %d\n", | ||
1150 | I2C_NAME(client), i); | ||
1151 | } else { | ||
1152 | dprintk(1, | ||
1153 | KERN_INFO | ||
1154 | "%s_attach: chip version %x at address 0x%x\n", | ||
1155 | I2C_NAME(client), saa7114_read(client, 0x00) >> 4, | ||
1156 | client->addr << 1); | ||
1157 | } | ||
1158 | |||
1159 | return 0; | 1044 | return 0; |
1160 | } | 1045 | } |
1161 | 1046 | ||
1162 | static int | 1047 | static int saa7114_remove(struct i2c_client *client) |
1163 | saa7114_attach_adapter (struct i2c_adapter *adapter) | ||
1164 | { | ||
1165 | dprintk(1, | ||
1166 | KERN_INFO | ||
1167 | "saa7114.c: starting probe for adapter %s (0x%x)\n", | ||
1168 | I2C_NAME(adapter), adapter->id); | ||
1169 | return i2c_probe(adapter, &addr_data, &saa7114_detect_client); | ||
1170 | } | ||
1171 | |||
1172 | static int | ||
1173 | saa7114_detach_client (struct i2c_client *client) | ||
1174 | { | 1048 | { |
1175 | struct saa7114 *decoder = i2c_get_clientdata(client); | 1049 | kfree(i2c_get_clientdata(client)); |
1176 | int err; | ||
1177 | |||
1178 | err = i2c_detach_client(client); | ||
1179 | if (err) { | ||
1180 | return err; | ||
1181 | } | ||
1182 | |||
1183 | kfree(decoder); | ||
1184 | kfree(client); | ||
1185 | |||
1186 | return 0; | 1050 | return 0; |
1187 | } | 1051 | } |
1188 | 1052 | ||
1189 | /* ----------------------------------------------------------------------- */ | 1053 | /* ----------------------------------------------------------------------- */ |
1190 | 1054 | ||
1191 | static struct i2c_driver i2c_driver_saa7114 = { | 1055 | static const struct i2c_device_id saa7114_id[] = { |
1192 | .driver = { | 1056 | { "saa7114_old", 0 }, /* "saa7114" maps to the saa7115 driver */ |
1193 | .name = "saa7114", | 1057 | { } |
1194 | }, | 1058 | }; |
1195 | 1059 | MODULE_DEVICE_TABLE(i2c, saa7114_id); | |
1196 | .id = I2C_DRIVERID_SAA7114, | ||
1197 | 1060 | ||
1198 | .attach_adapter = saa7114_attach_adapter, | 1061 | static struct v4l2_i2c_driver_data v4l2_i2c_data = { |
1199 | .detach_client = saa7114_detach_client, | 1062 | .name = "saa7114", |
1063 | .driverid = I2C_DRIVERID_SAA7114, | ||
1200 | .command = saa7114_command, | 1064 | .command = saa7114_command, |
1065 | .probe = saa7114_probe, | ||
1066 | .remove = saa7114_remove, | ||
1067 | .id_table = saa7114_id, | ||
1201 | }; | 1068 | }; |
1202 | |||
1203 | static int __init | ||
1204 | saa7114_init (void) | ||
1205 | { | ||
1206 | return i2c_add_driver(&i2c_driver_saa7114); | ||
1207 | } | ||
1208 | |||
1209 | static void __exit | ||
1210 | saa7114_exit (void) | ||
1211 | { | ||
1212 | i2c_del_driver(&i2c_driver_saa7114); | ||
1213 | } | ||
1214 | |||
1215 | module_init(saa7114_init); | ||
1216 | module_exit(saa7114_exit); | ||
diff --git a/drivers/media/video/saa7127.c b/drivers/media/video/saa7127.c index d0e83fe0ff51..cc02fb18efa7 100644 --- a/drivers/media/video/saa7127.c +++ b/drivers/media/video/saa7127.c | |||
@@ -29,7 +29,7 @@ | |||
29 | * Note: the saa7126 is identical to the saa7127, and the saa7128 is | 29 | * Note: the saa7126 is identical to the saa7127, and the saa7128 is |
30 | * identical to the saa7129, except that the saa7126 and saa7128 have | 30 | * identical to the saa7129, except that the saa7126 and saa7128 have |
31 | * macrovision anti-taping support. This driver will almost certainly | 31 | * macrovision anti-taping support. This driver will almost certainly |
32 | * work find for those chips, except of course for the missing anti-taping | 32 | * work fine for those chips, except of course for the missing anti-taping |
33 | * support. | 33 | * support. |
34 | * | 34 | * |
35 | * This program is free software; you can redistribute it and/or modify | 35 | * This program is free software; you can redistribute it and/or modify |
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c index 87c10983266f..8c46115d4c79 100644 --- a/drivers/media/video/saa7134/saa7134-dvb.c +++ b/drivers/media/video/saa7134/saa7134-dvb.c | |||
@@ -535,11 +535,16 @@ static int configure_tda827x_fe(struct saa7134_dev *dev, | |||
535 | struct tda1004x_config *cdec_conf, | 535 | struct tda1004x_config *cdec_conf, |
536 | struct tda827x_config *tuner_conf) | 536 | struct tda827x_config *tuner_conf) |
537 | { | 537 | { |
538 | dev->dvb.frontend = dvb_attach(tda10046_attach, cdec_conf, &dev->i2c_adap); | 538 | struct videobuf_dvb_frontend *fe0; |
539 | if (dev->dvb.frontend) { | 539 | |
540 | /* Get the first frontend */ | ||
541 | fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1); | ||
542 | |||
543 | fe0->dvb.frontend = dvb_attach(tda10046_attach, cdec_conf, &dev->i2c_adap); | ||
544 | if (fe0->dvb.frontend) { | ||
540 | if (cdec_conf->i2c_gate) | 545 | if (cdec_conf->i2c_gate) |
541 | dev->dvb.frontend->ops.i2c_gate_ctrl = tda8290_i2c_gate_ctrl; | 546 | fe0->dvb.frontend->ops.i2c_gate_ctrl = tda8290_i2c_gate_ctrl; |
542 | if (dvb_attach(tda827x_attach, dev->dvb.frontend, | 547 | if (dvb_attach(tda827x_attach, fe0->dvb.frontend, |
543 | cdec_conf->tuner_address, | 548 | cdec_conf->tuner_address, |
544 | &dev->i2c_adap, tuner_conf)) | 549 | &dev->i2c_adap, tuner_conf)) |
545 | return 0; | 550 | return 0; |
@@ -944,12 +949,30 @@ static int dvb_init(struct saa7134_dev *dev) | |||
944 | { | 949 | { |
945 | int ret; | 950 | int ret; |
946 | int attach_xc3028 = 0; | 951 | int attach_xc3028 = 0; |
952 | struct videobuf_dvb_frontend *fe0; | ||
953 | |||
954 | /* FIXME: add support for multi-frontend */ | ||
955 | mutex_init(&dev->frontends.lock); | ||
956 | INIT_LIST_HEAD(&dev->frontends.felist); | ||
957 | dev->frontends.active_fe_id = 0; | ||
958 | |||
959 | printk(KERN_INFO "%s() allocating 1 frontend\n", __func__); | ||
960 | |||
961 | if (videobuf_dvb_alloc_frontend(&dev->frontends, 1) == NULL) { | ||
962 | printk(KERN_ERR "%s() failed to alloc\n", __func__); | ||
963 | return -ENOMEM; | ||
964 | } | ||
965 | |||
966 | /* Get the first frontend */ | ||
967 | fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1); | ||
968 | if (!fe0) | ||
969 | return -EINVAL; | ||
947 | 970 | ||
948 | /* init struct videobuf_dvb */ | 971 | /* init struct videobuf_dvb */ |
949 | dev->ts.nr_bufs = 32; | 972 | dev->ts.nr_bufs = 32; |
950 | dev->ts.nr_packets = 32*4; | 973 | dev->ts.nr_packets = 32*4; |
951 | dev->dvb.name = dev->name; | 974 | fe0->dvb.name = dev->name; |
952 | videobuf_queue_sg_init(&dev->dvb.dvbq, &saa7134_ts_qops, | 975 | videobuf_queue_sg_init(&fe0->dvb.dvbq, &saa7134_ts_qops, |
953 | &dev->pci->dev, &dev->slock, | 976 | &dev->pci->dev, &dev->slock, |
954 | V4L2_BUF_TYPE_VIDEO_CAPTURE, | 977 | V4L2_BUF_TYPE_VIDEO_CAPTURE, |
955 | V4L2_FIELD_ALTERNATE, | 978 | V4L2_FIELD_ALTERNATE, |
@@ -959,47 +982,47 @@ static int dvb_init(struct saa7134_dev *dev) | |||
959 | switch (dev->board) { | 982 | switch (dev->board) { |
960 | case SAA7134_BOARD_PINNACLE_300I_DVBT_PAL: | 983 | case SAA7134_BOARD_PINNACLE_300I_DVBT_PAL: |
961 | dprintk("pinnacle 300i dvb setup\n"); | 984 | dprintk("pinnacle 300i dvb setup\n"); |
962 | dev->dvb.frontend = dvb_attach(mt352_attach, &pinnacle_300i, | 985 | fe0->dvb.frontend = dvb_attach(mt352_attach, &pinnacle_300i, |
963 | &dev->i2c_adap); | 986 | &dev->i2c_adap); |
964 | if (dev->dvb.frontend) { | 987 | if (fe0->dvb.frontend) { |
965 | dev->dvb.frontend->ops.tuner_ops.set_params = mt352_pinnacle_tuner_set_params; | 988 | fe0->dvb.frontend->ops.tuner_ops.set_params = mt352_pinnacle_tuner_set_params; |
966 | } | 989 | } |
967 | break; | 990 | break; |
968 | case SAA7134_BOARD_AVERMEDIA_777: | 991 | case SAA7134_BOARD_AVERMEDIA_777: |
969 | case SAA7134_BOARD_AVERMEDIA_A16AR: | 992 | case SAA7134_BOARD_AVERMEDIA_A16AR: |
970 | dprintk("avertv 777 dvb setup\n"); | 993 | dprintk("avertv 777 dvb setup\n"); |
971 | dev->dvb.frontend = dvb_attach(mt352_attach, &avermedia_777, | 994 | fe0->dvb.frontend = dvb_attach(mt352_attach, &avermedia_777, |
972 | &dev->i2c_adap); | 995 | &dev->i2c_adap); |
973 | if (dev->dvb.frontend) { | 996 | if (fe0->dvb.frontend) { |
974 | dvb_attach(simple_tuner_attach, dev->dvb.frontend, | 997 | dvb_attach(simple_tuner_attach, fe0->dvb.frontend, |
975 | &dev->i2c_adap, 0x61, | 998 | &dev->i2c_adap, 0x61, |
976 | TUNER_PHILIPS_TD1316); | 999 | TUNER_PHILIPS_TD1316); |
977 | } | 1000 | } |
978 | break; | 1001 | break; |
979 | case SAA7134_BOARD_AVERMEDIA_A16D: | 1002 | case SAA7134_BOARD_AVERMEDIA_A16D: |
980 | dprintk("AverMedia A16D dvb setup\n"); | 1003 | dprintk("AverMedia A16D dvb setup\n"); |
981 | dev->dvb.frontend = dvb_attach(mt352_attach, | 1004 | fe0->dvb.frontend = dvb_attach(mt352_attach, |
982 | &avermedia_xc3028_mt352_dev, | 1005 | &avermedia_xc3028_mt352_dev, |
983 | &dev->i2c_adap); | 1006 | &dev->i2c_adap); |
984 | attach_xc3028 = 1; | 1007 | attach_xc3028 = 1; |
985 | break; | 1008 | break; |
986 | case SAA7134_BOARD_MD7134: | 1009 | case SAA7134_BOARD_MD7134: |
987 | dev->dvb.frontend = dvb_attach(tda10046_attach, | 1010 | fe0->dvb.frontend = dvb_attach(tda10046_attach, |
988 | &medion_cardbus, | 1011 | &medion_cardbus, |
989 | &dev->i2c_adap); | 1012 | &dev->i2c_adap); |
990 | if (dev->dvb.frontend) { | 1013 | if (fe0->dvb.frontend) { |
991 | dvb_attach(simple_tuner_attach, dev->dvb.frontend, | 1014 | dvb_attach(simple_tuner_attach, fe0->dvb.frontend, |
992 | &dev->i2c_adap, medion_cardbus.tuner_address, | 1015 | &dev->i2c_adap, medion_cardbus.tuner_address, |
993 | TUNER_PHILIPS_FMD1216ME_MK3); | 1016 | TUNER_PHILIPS_FMD1216ME_MK3); |
994 | } | 1017 | } |
995 | break; | 1018 | break; |
996 | case SAA7134_BOARD_PHILIPS_TOUGH: | 1019 | case SAA7134_BOARD_PHILIPS_TOUGH: |
997 | dev->dvb.frontend = dvb_attach(tda10046_attach, | 1020 | fe0->dvb.frontend = dvb_attach(tda10046_attach, |
998 | &philips_tu1216_60_config, | 1021 | &philips_tu1216_60_config, |
999 | &dev->i2c_adap); | 1022 | &dev->i2c_adap); |
1000 | if (dev->dvb.frontend) { | 1023 | if (fe0->dvb.frontend) { |
1001 | dev->dvb.frontend->ops.tuner_ops.init = philips_tu1216_init; | 1024 | fe0->dvb.frontend->ops.tuner_ops.init = philips_tu1216_init; |
1002 | dev->dvb.frontend->ops.tuner_ops.set_params = philips_tda6651_pll_set; | 1025 | fe0->dvb.frontend->ops.tuner_ops.set_params = philips_tda6651_pll_set; |
1003 | } | 1026 | } |
1004 | break; | 1027 | break; |
1005 | case SAA7134_BOARD_FLYDVBTDUO: | 1028 | case SAA7134_BOARD_FLYDVBTDUO: |
@@ -1010,24 +1033,24 @@ static int dvb_init(struct saa7134_dev *dev) | |||
1010 | break; | 1033 | break; |
1011 | case SAA7134_BOARD_PHILIPS_EUROPA: | 1034 | case SAA7134_BOARD_PHILIPS_EUROPA: |
1012 | case SAA7134_BOARD_VIDEOMATE_DVBT_300: | 1035 | case SAA7134_BOARD_VIDEOMATE_DVBT_300: |
1013 | dev->dvb.frontend = dvb_attach(tda10046_attach, | 1036 | fe0->dvb.frontend = dvb_attach(tda10046_attach, |
1014 | &philips_europa_config, | 1037 | &philips_europa_config, |
1015 | &dev->i2c_adap); | 1038 | &dev->i2c_adap); |
1016 | if (dev->dvb.frontend) { | 1039 | if (fe0->dvb.frontend) { |
1017 | dev->original_demod_sleep = dev->dvb.frontend->ops.sleep; | 1040 | dev->original_demod_sleep = fe0->dvb.frontend->ops.sleep; |
1018 | dev->dvb.frontend->ops.sleep = philips_europa_demod_sleep; | 1041 | fe0->dvb.frontend->ops.sleep = philips_europa_demod_sleep; |
1019 | dev->dvb.frontend->ops.tuner_ops.init = philips_europa_tuner_init; | 1042 | fe0->dvb.frontend->ops.tuner_ops.init = philips_europa_tuner_init; |
1020 | dev->dvb.frontend->ops.tuner_ops.sleep = philips_europa_tuner_sleep; | 1043 | fe0->dvb.frontend->ops.tuner_ops.sleep = philips_europa_tuner_sleep; |
1021 | dev->dvb.frontend->ops.tuner_ops.set_params = philips_td1316_tuner_set_params; | 1044 | fe0->dvb.frontend->ops.tuner_ops.set_params = philips_td1316_tuner_set_params; |
1022 | } | 1045 | } |
1023 | break; | 1046 | break; |
1024 | case SAA7134_BOARD_VIDEOMATE_DVBT_200: | 1047 | case SAA7134_BOARD_VIDEOMATE_DVBT_200: |
1025 | dev->dvb.frontend = dvb_attach(tda10046_attach, | 1048 | fe0->dvb.frontend = dvb_attach(tda10046_attach, |
1026 | &philips_tu1216_61_config, | 1049 | &philips_tu1216_61_config, |
1027 | &dev->i2c_adap); | 1050 | &dev->i2c_adap); |
1028 | if (dev->dvb.frontend) { | 1051 | if (fe0->dvb.frontend) { |
1029 | dev->dvb.frontend->ops.tuner_ops.init = philips_tu1216_init; | 1052 | fe0->dvb.frontend->ops.tuner_ops.init = philips_tu1216_init; |
1030 | dev->dvb.frontend->ops.tuner_ops.set_params = philips_tda6651_pll_set; | 1053 | fe0->dvb.frontend->ops.tuner_ops.set_params = philips_tda6651_pll_set; |
1031 | } | 1054 | } |
1032 | break; | 1055 | break; |
1033 | case SAA7134_BOARD_KWORLD_DVBT_210: | 1056 | case SAA7134_BOARD_KWORLD_DVBT_210: |
@@ -1066,14 +1089,14 @@ static int dvb_init(struct saa7134_dev *dev) | |||
1066 | &tda827x_cfg_0) < 0) | 1089 | &tda827x_cfg_0) < 0) |
1067 | goto dettach_frontend; | 1090 | goto dettach_frontend; |
1068 | } else { /* satellite */ | 1091 | } else { /* satellite */ |
1069 | dev->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs, &dev->i2c_adap); | 1092 | fe0->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs, &dev->i2c_adap); |
1070 | if (dev->dvb.frontend) { | 1093 | if (fe0->dvb.frontend) { |
1071 | if (dvb_attach(tda826x_attach, dev->dvb.frontend, 0x63, | 1094 | if (dvb_attach(tda826x_attach, fe0->dvb.frontend, 0x63, |
1072 | &dev->i2c_adap, 0) == NULL) { | 1095 | &dev->i2c_adap, 0) == NULL) { |
1073 | wprintk("%s: Lifeview Trio, No tda826x found!\n", __func__); | 1096 | wprintk("%s: Lifeview Trio, No tda826x found!\n", __func__); |
1074 | goto dettach_frontend; | 1097 | goto dettach_frontend; |
1075 | } | 1098 | } |
1076 | if (dvb_attach(isl6421_attach, dev->dvb.frontend, &dev->i2c_adap, | 1099 | if (dvb_attach(isl6421_attach, fe0->dvb.frontend, &dev->i2c_adap, |
1077 | 0x08, 0, 0) == NULL) { | 1100 | 0x08, 0, 0) == NULL) { |
1078 | wprintk("%s: Lifeview Trio, No ISL6421 found!\n", __func__); | 1101 | wprintk("%s: Lifeview Trio, No ISL6421 found!\n", __func__); |
1079 | goto dettach_frontend; | 1102 | goto dettach_frontend; |
@@ -1083,11 +1106,11 @@ static int dvb_init(struct saa7134_dev *dev) | |||
1083 | break; | 1106 | break; |
1084 | case SAA7134_BOARD_ADS_DUO_CARDBUS_PTV331: | 1107 | case SAA7134_BOARD_ADS_DUO_CARDBUS_PTV331: |
1085 | case SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS: | 1108 | case SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS: |
1086 | dev->dvb.frontend = dvb_attach(tda10046_attach, | 1109 | fe0->dvb.frontend = dvb_attach(tda10046_attach, |
1087 | &ads_tech_duo_config, | 1110 | &ads_tech_duo_config, |
1088 | &dev->i2c_adap); | 1111 | &dev->i2c_adap); |
1089 | if (dev->dvb.frontend) { | 1112 | if (fe0->dvb.frontend) { |
1090 | if (dvb_attach(tda827x_attach,dev->dvb.frontend, | 1113 | if (dvb_attach(tda827x_attach,fe0->dvb.frontend, |
1091 | ads_tech_duo_config.tuner_address, &dev->i2c_adap, | 1114 | ads_tech_duo_config.tuner_address, &dev->i2c_adap, |
1092 | &ads_duo_cfg) == NULL) { | 1115 | &ads_duo_cfg) == NULL) { |
1093 | wprintk("no tda827x tuner found at addr: %02x\n", | 1116 | wprintk("no tda827x tuner found at addr: %02x\n", |
@@ -1108,15 +1131,15 @@ static int dvb_init(struct saa7134_dev *dev) | |||
1108 | &tda827x_cfg_0) < 0) | 1131 | &tda827x_cfg_0) < 0) |
1109 | goto dettach_frontend; | 1132 | goto dettach_frontend; |
1110 | } else { /* satellite */ | 1133 | } else { /* satellite */ |
1111 | dev->dvb.frontend = dvb_attach(tda10086_attach, | 1134 | fe0->dvb.frontend = dvb_attach(tda10086_attach, |
1112 | &flydvbs, &dev->i2c_adap); | 1135 | &flydvbs, &dev->i2c_adap); |
1113 | if (dev->dvb.frontend) { | 1136 | if (fe0->dvb.frontend) { |
1114 | struct dvb_frontend *fe = dev->dvb.frontend; | 1137 | struct dvb_frontend *fe = fe0->dvb.frontend; |
1115 | u8 dev_id = dev->eedata[2]; | 1138 | u8 dev_id = dev->eedata[2]; |
1116 | u8 data = 0xc4; | 1139 | u8 data = 0xc4; |
1117 | struct i2c_msg msg = {.addr = 0x08, .flags = 0, .len = 1}; | 1140 | struct i2c_msg msg = {.addr = 0x08, .flags = 0, .len = 1}; |
1118 | 1141 | ||
1119 | if (dvb_attach(tda826x_attach, dev->dvb.frontend, | 1142 | if (dvb_attach(tda826x_attach, fe0->dvb.frontend, |
1120 | 0x60, &dev->i2c_adap, 0) == NULL) { | 1143 | 0x60, &dev->i2c_adap, 0) == NULL) { |
1121 | wprintk("%s: Medion Quadro, no tda826x " | 1144 | wprintk("%s: Medion Quadro, no tda826x " |
1122 | "found !\n", __func__); | 1145 | "found !\n", __func__); |
@@ -1150,31 +1173,31 @@ static int dvb_init(struct saa7134_dev *dev) | |||
1150 | } | 1173 | } |
1151 | break; | 1174 | break; |
1152 | case SAA7134_BOARD_AVERMEDIA_AVERTVHD_A180: | 1175 | case SAA7134_BOARD_AVERMEDIA_AVERTVHD_A180: |
1153 | dev->dvb.frontend = dvb_attach(nxt200x_attach, &avertvhda180, | 1176 | fe0->dvb.frontend = dvb_attach(nxt200x_attach, &avertvhda180, |
1154 | &dev->i2c_adap); | 1177 | &dev->i2c_adap); |
1155 | if (dev->dvb.frontend) | 1178 | if (fe0->dvb.frontend) |
1156 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, | 1179 | dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 0x61, |
1157 | NULL, DVB_PLL_TDHU2); | 1180 | NULL, DVB_PLL_TDHU2); |
1158 | break; | 1181 | break; |
1159 | case SAA7134_BOARD_ADS_INSTANT_HDTV_PCI: | 1182 | case SAA7134_BOARD_ADS_INSTANT_HDTV_PCI: |
1160 | case SAA7134_BOARD_KWORLD_ATSC110: | 1183 | case SAA7134_BOARD_KWORLD_ATSC110: |
1161 | dev->dvb.frontend = dvb_attach(nxt200x_attach, &kworldatsc110, | 1184 | fe0->dvb.frontend = dvb_attach(nxt200x_attach, &kworldatsc110, |
1162 | &dev->i2c_adap); | 1185 | &dev->i2c_adap); |
1163 | if (dev->dvb.frontend) | 1186 | if (fe0->dvb.frontend) |
1164 | dvb_attach(simple_tuner_attach, dev->dvb.frontend, | 1187 | dvb_attach(simple_tuner_attach, fe0->dvb.frontend, |
1165 | &dev->i2c_adap, 0x61, | 1188 | &dev->i2c_adap, 0x61, |
1166 | TUNER_PHILIPS_TUV1236D); | 1189 | TUNER_PHILIPS_TUV1236D); |
1167 | break; | 1190 | break; |
1168 | case SAA7134_BOARD_FLYDVBS_LR300: | 1191 | case SAA7134_BOARD_FLYDVBS_LR300: |
1169 | dev->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs, | 1192 | fe0->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs, |
1170 | &dev->i2c_adap); | 1193 | &dev->i2c_adap); |
1171 | if (dev->dvb.frontend) { | 1194 | if (fe0->dvb.frontend) { |
1172 | if (dvb_attach(tda826x_attach, dev->dvb.frontend, 0x60, | 1195 | if (dvb_attach(tda826x_attach, fe0->dvb.frontend, 0x60, |
1173 | &dev->i2c_adap, 0) == NULL) { | 1196 | &dev->i2c_adap, 0) == NULL) { |
1174 | wprintk("%s: No tda826x found!\n", __func__); | 1197 | wprintk("%s: No tda826x found!\n", __func__); |
1175 | goto dettach_frontend; | 1198 | goto dettach_frontend; |
1176 | } | 1199 | } |
1177 | if (dvb_attach(isl6421_attach, dev->dvb.frontend, | 1200 | if (dvb_attach(isl6421_attach, fe0->dvb.frontend, |
1178 | &dev->i2c_adap, 0x08, 0, 0) == NULL) { | 1201 | &dev->i2c_adap, 0x08, 0, 0) == NULL) { |
1179 | wprintk("%s: No ISL6421 found!\n", __func__); | 1202 | wprintk("%s: No ISL6421 found!\n", __func__); |
1180 | goto dettach_frontend; | 1203 | goto dettach_frontend; |
@@ -1182,25 +1205,25 @@ static int dvb_init(struct saa7134_dev *dev) | |||
1182 | } | 1205 | } |
1183 | break; | 1206 | break; |
1184 | case SAA7134_BOARD_ASUS_EUROPA2_HYBRID: | 1207 | case SAA7134_BOARD_ASUS_EUROPA2_HYBRID: |
1185 | dev->dvb.frontend = dvb_attach(tda10046_attach, | 1208 | fe0->dvb.frontend = dvb_attach(tda10046_attach, |
1186 | &medion_cardbus, | 1209 | &medion_cardbus, |
1187 | &dev->i2c_adap); | 1210 | &dev->i2c_adap); |
1188 | if (dev->dvb.frontend) { | 1211 | if (fe0->dvb.frontend) { |
1189 | dev->original_demod_sleep = dev->dvb.frontend->ops.sleep; | 1212 | dev->original_demod_sleep = fe0->dvb.frontend->ops.sleep; |
1190 | dev->dvb.frontend->ops.sleep = philips_europa_demod_sleep; | 1213 | fe0->dvb.frontend->ops.sleep = philips_europa_demod_sleep; |
1191 | 1214 | ||
1192 | dvb_attach(simple_tuner_attach, dev->dvb.frontend, | 1215 | dvb_attach(simple_tuner_attach, fe0->dvb.frontend, |
1193 | &dev->i2c_adap, medion_cardbus.tuner_address, | 1216 | &dev->i2c_adap, medion_cardbus.tuner_address, |
1194 | TUNER_PHILIPS_FMD1216ME_MK3); | 1217 | TUNER_PHILIPS_FMD1216ME_MK3); |
1195 | } | 1218 | } |
1196 | break; | 1219 | break; |
1197 | case SAA7134_BOARD_VIDEOMATE_DVBT_200A: | 1220 | case SAA7134_BOARD_VIDEOMATE_DVBT_200A: |
1198 | dev->dvb.frontend = dvb_attach(tda10046_attach, | 1221 | fe0->dvb.frontend = dvb_attach(tda10046_attach, |
1199 | &philips_europa_config, | 1222 | &philips_europa_config, |
1200 | &dev->i2c_adap); | 1223 | &dev->i2c_adap); |
1201 | if (dev->dvb.frontend) { | 1224 | if (fe0->dvb.frontend) { |
1202 | dev->dvb.frontend->ops.tuner_ops.init = philips_td1316_tuner_init; | 1225 | fe0->dvb.frontend->ops.tuner_ops.init = philips_td1316_tuner_init; |
1203 | dev->dvb.frontend->ops.tuner_ops.set_params = philips_td1316_tuner_set_params; | 1226 | fe0->dvb.frontend->ops.tuner_ops.set_params = philips_td1316_tuner_set_params; |
1204 | } | 1227 | } |
1205 | break; | 1228 | break; |
1206 | case SAA7134_BOARD_CINERGY_HT_PCMCIA: | 1229 | case SAA7134_BOARD_CINERGY_HT_PCMCIA: |
@@ -1239,15 +1262,15 @@ static int dvb_init(struct saa7134_dev *dev) | |||
1239 | goto dettach_frontend; | 1262 | goto dettach_frontend; |
1240 | break; | 1263 | break; |
1241 | case SAA7134_BOARD_PHILIPS_SNAKE: | 1264 | case SAA7134_BOARD_PHILIPS_SNAKE: |
1242 | dev->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs, | 1265 | fe0->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs, |
1243 | &dev->i2c_adap); | 1266 | &dev->i2c_adap); |
1244 | if (dev->dvb.frontend) { | 1267 | if (fe0->dvb.frontend) { |
1245 | if (dvb_attach(tda826x_attach, dev->dvb.frontend, 0x60, | 1268 | if (dvb_attach(tda826x_attach, fe0->dvb.frontend, 0x60, |
1246 | &dev->i2c_adap, 0) == NULL) { | 1269 | &dev->i2c_adap, 0) == NULL) { |
1247 | wprintk("%s: No tda826x found!\n", __func__); | 1270 | wprintk("%s: No tda826x found!\n", __func__); |
1248 | goto dettach_frontend; | 1271 | goto dettach_frontend; |
1249 | } | 1272 | } |
1250 | if (dvb_attach(lnbp21_attach, dev->dvb.frontend, | 1273 | if (dvb_attach(lnbp21_attach, fe0->dvb.frontend, |
1251 | &dev->i2c_adap, 0, 0) == NULL) { | 1274 | &dev->i2c_adap, 0, 0) == NULL) { |
1252 | wprintk("%s: No lnbp21 found!\n", __func__); | 1275 | wprintk("%s: No lnbp21 found!\n", __func__); |
1253 | goto dettach_frontend; | 1276 | goto dettach_frontend; |
@@ -1269,24 +1292,24 @@ static int dvb_init(struct saa7134_dev *dev) | |||
1269 | saa7134_set_gpio(dev, 25, 0); | 1292 | saa7134_set_gpio(dev, 25, 0); |
1270 | msleep(10); | 1293 | msleep(10); |
1271 | saa7134_set_gpio(dev, 25, 1); | 1294 | saa7134_set_gpio(dev, 25, 1); |
1272 | dev->dvb.frontend = dvb_attach(mt352_attach, | 1295 | fe0->dvb.frontend = dvb_attach(mt352_attach, |
1273 | &avermedia_xc3028_mt352_dev, | 1296 | &avermedia_xc3028_mt352_dev, |
1274 | &dev->i2c_adap); | 1297 | &dev->i2c_adap); |
1275 | attach_xc3028 = 1; | 1298 | attach_xc3028 = 1; |
1276 | break; | 1299 | break; |
1277 | case SAA7134_BOARD_MD7134_BRIDGE_2: | 1300 | case SAA7134_BOARD_MD7134_BRIDGE_2: |
1278 | dev->dvb.frontend = dvb_attach(tda10086_attach, | 1301 | fe0->dvb.frontend = dvb_attach(tda10086_attach, |
1279 | &sd1878_4m, &dev->i2c_adap); | 1302 | &sd1878_4m, &dev->i2c_adap); |
1280 | if (dev->dvb.frontend) { | 1303 | if (fe0->dvb.frontend) { |
1281 | struct dvb_frontend *fe; | 1304 | struct dvb_frontend *fe; |
1282 | if (dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60, | 1305 | if (dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 0x60, |
1283 | &dev->i2c_adap, DVB_PLL_PHILIPS_SD1878_TDA8261) == NULL) { | 1306 | &dev->i2c_adap, DVB_PLL_PHILIPS_SD1878_TDA8261) == NULL) { |
1284 | wprintk("%s: MD7134 DVB-S, no SD1878 " | 1307 | wprintk("%s: MD7134 DVB-S, no SD1878 " |
1285 | "found !\n", __func__); | 1308 | "found !\n", __func__); |
1286 | goto dettach_frontend; | 1309 | goto dettach_frontend; |
1287 | } | 1310 | } |
1288 | /* we need to open the i2c gate (we know it exists) */ | 1311 | /* we need to open the i2c gate (we know it exists) */ |
1289 | fe = dev->dvb.frontend; | 1312 | fe = fe0->dvb.frontend; |
1290 | fe->ops.i2c_gate_ctrl(fe, 1); | 1313 | fe->ops.i2c_gate_ctrl(fe, 1); |
1291 | if (dvb_attach(isl6405_attach, fe, | 1314 | if (dvb_attach(isl6405_attach, fe, |
1292 | &dev->i2c_adap, 0x08, 0, 0) == NULL) { | 1315 | &dev->i2c_adap, 0x08, 0, 0) == NULL) { |
@@ -1305,7 +1328,7 @@ static int dvb_init(struct saa7134_dev *dev) | |||
1305 | saa7134_set_gpio(dev, 25, 0); | 1328 | saa7134_set_gpio(dev, 25, 0); |
1306 | msleep(10); | 1329 | msleep(10); |
1307 | saa7134_set_gpio(dev, 25, 1); | 1330 | saa7134_set_gpio(dev, 25, 1); |
1308 | dev->dvb.frontend = dvb_attach(mt352_attach, | 1331 | fe0->dvb.frontend = dvb_attach(mt352_attach, |
1309 | &avermedia_xc3028_mt352_dev, | 1332 | &avermedia_xc3028_mt352_dev, |
1310 | &dev->i2c_adap); | 1333 | &dev->i2c_adap); |
1311 | attach_xc3028 = 1; | 1334 | attach_xc3028 = 1; |
@@ -1316,17 +1339,17 @@ static int dvb_init(struct saa7134_dev *dev) | |||
1316 | &tda827x_cfg_2) < 0) | 1339 | &tda827x_cfg_2) < 0) |
1317 | goto dettach_frontend; | 1340 | goto dettach_frontend; |
1318 | } else { /* satellite */ | 1341 | } else { /* satellite */ |
1319 | dev->dvb.frontend = dvb_attach(tda10086_attach, | 1342 | fe0->dvb.frontend = dvb_attach(tda10086_attach, |
1320 | &flydvbs, &dev->i2c_adap); | 1343 | &flydvbs, &dev->i2c_adap); |
1321 | if (dev->dvb.frontend) { | 1344 | if (fe0->dvb.frontend) { |
1322 | if (dvb_attach(tda826x_attach, | 1345 | if (dvb_attach(tda826x_attach, |
1323 | dev->dvb.frontend, 0x60, | 1346 | fe0->dvb.frontend, 0x60, |
1324 | &dev->i2c_adap, 0) == NULL) { | 1347 | &dev->i2c_adap, 0) == NULL) { |
1325 | wprintk("%s: Asus Tiger 3in1, no " | 1348 | wprintk("%s: Asus Tiger 3in1, no " |
1326 | "tda826x found!\n", __func__); | 1349 | "tda826x found!\n", __func__); |
1327 | goto dettach_frontend; | 1350 | goto dettach_frontend; |
1328 | } | 1351 | } |
1329 | if (dvb_attach(lnbp21_attach, dev->dvb.frontend, | 1352 | if (dvb_attach(lnbp21_attach, fe0->dvb.frontend, |
1330 | &dev->i2c_adap, 0, 0) == NULL) { | 1353 | &dev->i2c_adap, 0, 0) == NULL) { |
1331 | wprintk("%s: Asus Tiger 3in1, no lnbp21" | 1354 | wprintk("%s: Asus Tiger 3in1, no lnbp21" |
1332 | " found!\n", __func__); | 1355 | " found!\n", __func__); |
@@ -1352,10 +1375,10 @@ static int dvb_init(struct saa7134_dev *dev) | |||
1352 | .i2c_addr = 0x61, | 1375 | .i2c_addr = 0x61, |
1353 | }; | 1376 | }; |
1354 | 1377 | ||
1355 | if (!dev->dvb.frontend) | 1378 | if (!fe0->dvb.frontend) |
1356 | return -1; | 1379 | return -1; |
1357 | 1380 | ||
1358 | fe = dvb_attach(xc2028_attach, dev->dvb.frontend, &cfg); | 1381 | fe = dvb_attach(xc2028_attach, fe0->dvb.frontend, &cfg); |
1359 | if (!fe) { | 1382 | if (!fe) { |
1360 | printk(KERN_ERR "%s/2: xc3028 attach failed\n", | 1383 | printk(KERN_ERR "%s/2: xc3028 attach failed\n", |
1361 | dev->name); | 1384 | dev->name); |
@@ -1363,40 +1386,47 @@ static int dvb_init(struct saa7134_dev *dev) | |||
1363 | } | 1386 | } |
1364 | } | 1387 | } |
1365 | 1388 | ||
1366 | if (NULL == dev->dvb.frontend) { | 1389 | if (NULL == fe0->dvb.frontend) { |
1367 | printk(KERN_ERR "%s/dvb: frontend initialization failed\n", dev->name); | 1390 | printk(KERN_ERR "%s/dvb: frontend initialization failed\n", dev->name); |
1368 | return -1; | 1391 | return -1; |
1369 | } | 1392 | } |
1370 | /* define general-purpose callback pointer */ | 1393 | /* define general-purpose callback pointer */ |
1371 | dev->dvb.frontend->callback = saa7134_tuner_callback; | 1394 | fe0->dvb.frontend->callback = saa7134_tuner_callback; |
1372 | 1395 | ||
1373 | /* register everything else */ | 1396 | /* register everything else */ |
1374 | ret = videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev, &dev->pci->dev, | 1397 | ret = videobuf_dvb_register_bus(&dev->frontends, THIS_MODULE, dev, |
1375 | adapter_nr); | 1398 | &dev->pci->dev, adapter_nr, 0); |
1376 | 1399 | ||
1377 | /* this sequence is necessary to make the tda1004x load its firmware | 1400 | /* this sequence is necessary to make the tda1004x load its firmware |
1378 | * and to enter analog mode of hybrid boards | 1401 | * and to enter analog mode of hybrid boards |
1379 | */ | 1402 | */ |
1380 | if (!ret) { | 1403 | if (!ret) { |
1381 | if (dev->dvb.frontend->ops.init) | 1404 | if (fe0->dvb.frontend->ops.init) |
1382 | dev->dvb.frontend->ops.init(dev->dvb.frontend); | 1405 | fe0->dvb.frontend->ops.init(fe0->dvb.frontend); |
1383 | if (dev->dvb.frontend->ops.sleep) | 1406 | if (fe0->dvb.frontend->ops.sleep) |
1384 | dev->dvb.frontend->ops.sleep(dev->dvb.frontend); | 1407 | fe0->dvb.frontend->ops.sleep(fe0->dvb.frontend); |
1385 | if (dev->dvb.frontend->ops.tuner_ops.sleep) | 1408 | if (fe0->dvb.frontend->ops.tuner_ops.sleep) |
1386 | dev->dvb.frontend->ops.tuner_ops.sleep(dev->dvb.frontend); | 1409 | fe0->dvb.frontend->ops.tuner_ops.sleep(fe0->dvb.frontend); |
1387 | } | 1410 | } |
1388 | return ret; | 1411 | return ret; |
1389 | 1412 | ||
1390 | dettach_frontend: | 1413 | dettach_frontend: |
1391 | if (dev->dvb.frontend) | 1414 | if (fe0->dvb.frontend) |
1392 | dvb_frontend_detach(dev->dvb.frontend); | 1415 | dvb_frontend_detach(fe0->dvb.frontend); |
1393 | dev->dvb.frontend = NULL; | 1416 | fe0->dvb.frontend = NULL; |
1394 | 1417 | ||
1395 | return -1; | 1418 | return -1; |
1396 | } | 1419 | } |
1397 | 1420 | ||
1398 | static int dvb_fini(struct saa7134_dev *dev) | 1421 | static int dvb_fini(struct saa7134_dev *dev) |
1399 | { | 1422 | { |
1423 | struct videobuf_dvb_frontend *fe0; | ||
1424 | |||
1425 | /* Get the first frontend */ | ||
1426 | fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1); | ||
1427 | if (!fe0) | ||
1428 | return -EINVAL; | ||
1429 | |||
1400 | /* FIXME: I suspect that this code is bogus, since the entry for | 1430 | /* FIXME: I suspect that this code is bogus, since the entry for |
1401 | Pinnacle 300I DVB-T PAL already defines the proper init to allow | 1431 | Pinnacle 300I DVB-T PAL already defines the proper init to allow |
1402 | the detection of mt2032 (TDA9887_PORT2_INACTIVE) | 1432 | the detection of mt2032 (TDA9887_PORT2_INACTIVE) |
@@ -1416,7 +1446,7 @@ static int dvb_fini(struct saa7134_dev *dev) | |||
1416 | u8 data = 0x80; | 1446 | u8 data = 0x80; |
1417 | struct i2c_msg msg = {.addr = 0x08, .buf = &data, .flags = 0, .len = 1}; | 1447 | struct i2c_msg msg = {.addr = 0x08, .buf = &data, .flags = 0, .len = 1}; |
1418 | struct dvb_frontend *fe; | 1448 | struct dvb_frontend *fe; |
1419 | fe = dev->dvb.frontend; | 1449 | fe = fe0->dvb.frontend; |
1420 | if (fe->ops.i2c_gate_ctrl) { | 1450 | if (fe->ops.i2c_gate_ctrl) { |
1421 | fe->ops.i2c_gate_ctrl(fe, 1); | 1451 | fe->ops.i2c_gate_ctrl(fe, 1); |
1422 | i2c_transfer(&dev->i2c_adap, &msg, 1); | 1452 | i2c_transfer(&dev->i2c_adap, &msg, 1); |
@@ -1424,8 +1454,8 @@ static int dvb_fini(struct saa7134_dev *dev) | |||
1424 | } | 1454 | } |
1425 | } | 1455 | } |
1426 | } | 1456 | } |
1427 | if (dev->dvb.frontend) | 1457 | if (fe0->dvb.frontend) |
1428 | videobuf_dvb_unregister(&dev->dvb); | 1458 | videobuf_dvb_unregister_bus(&dev->frontends); |
1429 | return 0; | 1459 | return 0; |
1430 | } | 1460 | } |
1431 | 1461 | ||
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h index 491ab1f8fdd3..24096d6e1ef8 100644 --- a/drivers/media/video/saa7134/saa7134.h +++ b/drivers/media/video/saa7134/saa7134.h | |||
@@ -581,7 +581,7 @@ struct saa7134_dev { | |||
581 | 581 | ||
582 | #if defined(CONFIG_VIDEO_SAA7134_DVB) || defined(CONFIG_VIDEO_SAA7134_DVB_MODULE) | 582 | #if defined(CONFIG_VIDEO_SAA7134_DVB) || defined(CONFIG_VIDEO_SAA7134_DVB_MODULE) |
583 | /* SAA7134_MPEG_DVB only */ | 583 | /* SAA7134_MPEG_DVB only */ |
584 | struct videobuf_dvb dvb; | 584 | struct videobuf_dvb_frontends frontends; |
585 | int (*original_demod_sleep)(struct dvb_frontend *fe); | 585 | int (*original_demod_sleep)(struct dvb_frontend *fe); |
586 | int (*original_set_voltage)(struct dvb_frontend *fe, fe_sec_voltage_t voltage); | 586 | int (*original_set_voltage)(struct dvb_frontend *fe, fe_sec_voltage_t voltage); |
587 | int (*original_set_high_voltage)(struct dvb_frontend *fe, long arg); | 587 | int (*original_set_high_voltage)(struct dvb_frontend *fe, long arg); |
diff --git a/drivers/media/video/saa7185.c b/drivers/media/video/saa7185.c index 02fda4eecea3..6debb65152ee 100644 --- a/drivers/media/video/saa7185.c +++ b/drivers/media/video/saa7185.c | |||
@@ -25,43 +25,25 @@ | |||
25 | */ | 25 | */ |
26 | 26 | ||
27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
28 | #include <linux/init.h> | ||
29 | #include <linux/delay.h> | ||
30 | #include <linux/errno.h> | ||
31 | #include <linux/fs.h> | ||
32 | #include <linux/kernel.h> | ||
33 | #include <linux/major.h> | ||
34 | #include <linux/slab.h> | ||
35 | #include <linux/mm.h> | ||
36 | #include <linux/signal.h> | ||
37 | #include <linux/types.h> | 28 | #include <linux/types.h> |
38 | #include <linux/i2c.h> | 29 | #include <linux/ioctl.h> |
39 | #include <asm/io.h> | ||
40 | #include <asm/pgtable.h> | ||
41 | #include <asm/page.h> | ||
42 | #include <asm/uaccess.h> | 30 | #include <asm/uaccess.h> |
43 | 31 | #include <linux/i2c.h> | |
32 | #include <linux/i2c-id.h> | ||
44 | #include <linux/videodev.h> | 33 | #include <linux/videodev.h> |
45 | #include <linux/video_encoder.h> | 34 | #include <linux/video_encoder.h> |
35 | #include <media/v4l2-common.h> | ||
36 | #include <media/v4l2-i2c-drv-legacy.h> | ||
46 | 37 | ||
47 | MODULE_DESCRIPTION("Philips SAA7185 video encoder driver"); | 38 | MODULE_DESCRIPTION("Philips SAA7185 video encoder driver"); |
48 | MODULE_AUTHOR("Dave Perks"); | 39 | MODULE_AUTHOR("Dave Perks"); |
49 | MODULE_LICENSE("GPL"); | 40 | MODULE_LICENSE("GPL"); |
50 | 41 | ||
51 | 42 | ||
52 | #define I2C_NAME(s) (s)->name | ||
53 | |||
54 | |||
55 | static int debug; | 43 | static int debug; |
56 | module_param(debug, int, 0); | 44 | module_param(debug, int, 0); |
57 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); | 45 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); |
58 | 46 | ||
59 | #define dprintk(num, format, args...) \ | ||
60 | do { \ | ||
61 | if (debug >= num) \ | ||
62 | printk(format, ##args); \ | ||
63 | } while (0) | ||
64 | |||
65 | /* ----------------------------------------------------------------------- */ | 47 | /* ----------------------------------------------------------------------- */ |
66 | 48 | ||
67 | struct saa7185 { | 49 | struct saa7185 { |
@@ -75,32 +57,24 @@ struct saa7185 { | |||
75 | int sat; | 57 | int sat; |
76 | }; | 58 | }; |
77 | 59 | ||
78 | #define I2C_SAA7185 0x88 | ||
79 | |||
80 | /* ----------------------------------------------------------------------- */ | 60 | /* ----------------------------------------------------------------------- */ |
81 | 61 | ||
82 | static inline int | 62 | static inline int saa7185_read(struct i2c_client *client) |
83 | saa7185_read (struct i2c_client *client) | ||
84 | { | 63 | { |
85 | return i2c_smbus_read_byte(client); | 64 | return i2c_smbus_read_byte(client); |
86 | } | 65 | } |
87 | 66 | ||
88 | static int | 67 | static int saa7185_write(struct i2c_client *client, u8 reg, u8 value) |
89 | saa7185_write (struct i2c_client *client, | ||
90 | u8 reg, | ||
91 | u8 value) | ||
92 | { | 68 | { |
93 | struct saa7185 *encoder = i2c_get_clientdata(client); | 69 | struct saa7185 *encoder = i2c_get_clientdata(client); |
94 | 70 | ||
95 | dprintk(1, KERN_DEBUG "SAA7185: %02x set to %02x\n", reg, value); | 71 | v4l_dbg(1, debug, client, "%02x set to %02x\n", reg, value); |
96 | encoder->reg[reg] = value; | 72 | encoder->reg[reg] = value; |
97 | return i2c_smbus_write_byte_data(client, reg, value); | 73 | return i2c_smbus_write_byte_data(client, reg, value); |
98 | } | 74 | } |
99 | 75 | ||
100 | static int | 76 | static int saa7185_write_block(struct i2c_client *client, |
101 | saa7185_write_block (struct i2c_client *client, | 77 | const u8 *data, unsigned int len) |
102 | const u8 *data, | ||
103 | unsigned int len) | ||
104 | { | 78 | { |
105 | int ret = -1; | 79 | int ret = -1; |
106 | u8 reg; | 80 | u8 reg; |
@@ -121,18 +95,17 @@ saa7185_write_block (struct i2c_client *client, | |||
121 | encoder->reg[reg++] = data[1]; | 95 | encoder->reg[reg++] = data[1]; |
122 | len -= 2; | 96 | len -= 2; |
123 | data += 2; | 97 | data += 2; |
124 | } while (len >= 2 && data[0] == reg && | 98 | } while (len >= 2 && data[0] == reg && block_len < 32); |
125 | block_len < 32); | 99 | ret = i2c_master_send(client, block_data, block_len); |
126 | if ((ret = i2c_master_send(client, block_data, | 100 | if (ret < 0) |
127 | block_len)) < 0) | ||
128 | break; | 101 | break; |
129 | } | 102 | } |
130 | } else { | 103 | } else { |
131 | /* do some slow I2C emulation kind of thing */ | 104 | /* do some slow I2C emulation kind of thing */ |
132 | while (len >= 2) { | 105 | while (len >= 2) { |
133 | reg = *data++; | 106 | reg = *data++; |
134 | if ((ret = saa7185_write(client, reg, | 107 | ret = saa7185_write(client, reg, *data++); |
135 | *data++)) < 0) | 108 | if (ret < 0) |
136 | break; | 109 | break; |
137 | len -= 2; | 110 | len -= 2; |
138 | } | 111 | } |
@@ -240,15 +213,11 @@ static const unsigned char init_ntsc[] = { | |||
240 | 0x66, 0x21, /* FSC3 */ | 213 | 0x66, 0x21, /* FSC3 */ |
241 | }; | 214 | }; |
242 | 215 | ||
243 | static int | 216 | static int saa7185_command(struct i2c_client *client, unsigned cmd, void *arg) |
244 | saa7185_command (struct i2c_client *client, | ||
245 | unsigned int cmd, | ||
246 | void *arg) | ||
247 | { | 217 | { |
248 | struct saa7185 *encoder = i2c_get_clientdata(client); | 218 | struct saa7185 *encoder = i2c_get_clientdata(client); |
249 | 219 | ||
250 | switch (cmd) { | 220 | switch (cmd) { |
251 | |||
252 | case 0: | 221 | case 0: |
253 | saa7185_write_block(client, init_common, | 222 | saa7185_write_block(client, init_common, |
254 | sizeof(init_common)); | 223 | sizeof(init_common)); |
@@ -264,7 +233,6 @@ saa7185_command (struct i2c_client *client, | |||
264 | sizeof(init_pal)); | 233 | sizeof(init_pal)); |
265 | break; | 234 | break; |
266 | } | 235 | } |
267 | |||
268 | break; | 236 | break; |
269 | 237 | ||
270 | case ENCODER_GET_CAPABILITIES: | 238 | case ENCODER_GET_CAPABILITIES: |
@@ -276,8 +244,8 @@ saa7185_command (struct i2c_client *client, | |||
276 | VIDEO_ENCODER_SECAM | VIDEO_ENCODER_CCIR; | 244 | VIDEO_ENCODER_SECAM | VIDEO_ENCODER_CCIR; |
277 | cap->inputs = 1; | 245 | cap->inputs = 1; |
278 | cap->outputs = 1; | 246 | cap->outputs = 1; |
279 | } | ||
280 | break; | 247 | break; |
248 | } | ||
281 | 249 | ||
282 | case ENCODER_SET_NORM: | 250 | case ENCODER_SET_NORM: |
283 | { | 251 | { |
@@ -286,7 +254,6 @@ saa7185_command (struct i2c_client *client, | |||
286 | //saa7185_write_block(client, init_common, sizeof(init_common)); | 254 | //saa7185_write_block(client, init_common, sizeof(init_common)); |
287 | 255 | ||
288 | switch (*iarg) { | 256 | switch (*iarg) { |
289 | |||
290 | case VIDEO_MODE_NTSC: | 257 | case VIDEO_MODE_NTSC: |
291 | saa7185_write_block(client, init_ntsc, | 258 | saa7185_write_block(client, init_ntsc, |
292 | sizeof(init_ntsc)); | 259 | sizeof(init_ntsc)); |
@@ -300,11 +267,10 @@ saa7185_command (struct i2c_client *client, | |||
300 | case VIDEO_MODE_SECAM: | 267 | case VIDEO_MODE_SECAM: |
301 | default: | 268 | default: |
302 | return -EINVAL; | 269 | return -EINVAL; |
303 | |||
304 | } | 270 | } |
305 | encoder->norm = *iarg; | 271 | encoder->norm = *iarg; |
306 | } | ||
307 | break; | 272 | break; |
273 | } | ||
308 | 274 | ||
309 | case ENCODER_SET_INPUT: | 275 | case ENCODER_SET_INPUT: |
310 | { | 276 | { |
@@ -314,7 +280,6 @@ saa7185_command (struct i2c_client *client, | |||
314 | *iarg = 1: input is from ZR36060 */ | 280 | *iarg = 1: input is from ZR36060 */ |
315 | 281 | ||
316 | switch (*iarg) { | 282 | switch (*iarg) { |
317 | |||
318 | case 0: | 283 | case 0: |
319 | /* Switch RTCE to 1 */ | 284 | /* Switch RTCE to 1 */ |
320 | saa7185_write(client, 0x61, | 285 | saa7185_write(client, 0x61, |
@@ -332,21 +297,19 @@ saa7185_command (struct i2c_client *client, | |||
332 | 297 | ||
333 | default: | 298 | default: |
334 | return -EINVAL; | 299 | return -EINVAL; |
335 | |||
336 | } | 300 | } |
337 | } | ||
338 | break; | 301 | break; |
302 | } | ||
339 | 303 | ||
340 | case ENCODER_SET_OUTPUT: | 304 | case ENCODER_SET_OUTPUT: |
341 | { | 305 | { |
342 | int *iarg = arg; | 306 | int *iarg = arg; |
343 | 307 | ||
344 | /* not much choice of outputs */ | 308 | /* not much choice of outputs */ |
345 | if (*iarg != 0) { | 309 | if (*iarg != 0) |
346 | return -EINVAL; | 310 | return -EINVAL; |
347 | } | ||
348 | } | ||
349 | break; | 311 | break; |
312 | } | ||
350 | 313 | ||
351 | case ENCODER_ENABLE_OUTPUT: | 314 | case ENCODER_ENABLE_OUTPUT: |
352 | { | 315 | { |
@@ -356,8 +319,8 @@ saa7185_command (struct i2c_client *client, | |||
356 | saa7185_write(client, 0x61, | 319 | saa7185_write(client, 0x61, |
357 | (encoder->reg[0x61] & 0xbf) | | 320 | (encoder->reg[0x61] & 0xbf) | |
358 | (encoder->enable ? 0x00 : 0x40)); | 321 | (encoder->enable ? 0x00 : 0x40)); |
359 | } | ||
360 | break; | 322 | break; |
323 | } | ||
361 | 324 | ||
362 | default: | 325 | default: |
363 | return -EINVAL; | 326 | return -EINVAL; |
@@ -368,138 +331,65 @@ saa7185_command (struct i2c_client *client, | |||
368 | 331 | ||
369 | /* ----------------------------------------------------------------------- */ | 332 | /* ----------------------------------------------------------------------- */ |
370 | 333 | ||
371 | /* | 334 | static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END }; |
372 | * Generic i2c probe | ||
373 | * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1' | ||
374 | */ | ||
375 | static unsigned short normal_i2c[] = { I2C_SAA7185 >> 1, I2C_CLIENT_END }; | ||
376 | 335 | ||
377 | static unsigned short ignore = I2C_CLIENT_END; | 336 | I2C_CLIENT_INSMOD; |
378 | 337 | ||
379 | static struct i2c_client_address_data addr_data = { | 338 | static int saa7185_probe(struct i2c_client *client, |
380 | .normal_i2c = normal_i2c, | 339 | const struct i2c_device_id *id) |
381 | .probe = &ignore, | ||
382 | .ignore = &ignore, | ||
383 | }; | ||
384 | |||
385 | static struct i2c_driver i2c_driver_saa7185; | ||
386 | |||
387 | static int | ||
388 | saa7185_detect_client (struct i2c_adapter *adapter, | ||
389 | int address, | ||
390 | int kind) | ||
391 | { | 340 | { |
392 | int i; | 341 | int i; |
393 | struct i2c_client *client; | ||
394 | struct saa7185 *encoder; | 342 | struct saa7185 *encoder; |
395 | 343 | ||
396 | dprintk(1, | ||
397 | KERN_INFO | ||
398 | "saa7185.c: detecting saa7185 client on address 0x%x\n", | ||
399 | address << 1); | ||
400 | |||
401 | /* Check if the adapter supports the needed features */ | 344 | /* Check if the adapter supports the needed features */ |
402 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | 345 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) |
403 | return 0; | 346 | return -ENODEV; |
404 | 347 | ||
405 | client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); | 348 | v4l_info(client, "chip found @ 0x%x (%s)\n", |
406 | if (!client) | 349 | client->addr << 1, client->adapter->name); |
407 | return -ENOMEM; | ||
408 | client->addr = address; | ||
409 | client->adapter = adapter; | ||
410 | client->driver = &i2c_driver_saa7185; | ||
411 | strlcpy(I2C_NAME(client), "saa7185", sizeof(I2C_NAME(client))); | ||
412 | 350 | ||
413 | encoder = kzalloc(sizeof(struct saa7185), GFP_KERNEL); | 351 | encoder = kzalloc(sizeof(struct saa7185), GFP_KERNEL); |
414 | if (encoder == NULL) { | 352 | if (encoder == NULL) |
415 | kfree(client); | ||
416 | return -ENOMEM; | 353 | return -ENOMEM; |
417 | } | ||
418 | encoder->norm = VIDEO_MODE_NTSC; | 354 | encoder->norm = VIDEO_MODE_NTSC; |
419 | encoder->enable = 1; | 355 | encoder->enable = 1; |
420 | i2c_set_clientdata(client, encoder); | 356 | i2c_set_clientdata(client, encoder); |
421 | 357 | ||
422 | i = i2c_attach_client(client); | ||
423 | if (i) { | ||
424 | kfree(client); | ||
425 | kfree(encoder); | ||
426 | return i; | ||
427 | } | ||
428 | |||
429 | i = saa7185_write_block(client, init_common, sizeof(init_common)); | 358 | i = saa7185_write_block(client, init_common, sizeof(init_common)); |
430 | if (i >= 0) { | 359 | if (i >= 0) |
431 | i = saa7185_write_block(client, init_ntsc, | 360 | i = saa7185_write_block(client, init_ntsc, sizeof(init_ntsc)); |
432 | sizeof(init_ntsc)); | 361 | if (i < 0) |
433 | } | 362 | v4l_dbg(1, debug, client, "init error %d\n", i); |
434 | if (i < 0) { | 363 | else |
435 | dprintk(1, KERN_ERR "%s_attach: init error %d\n", | 364 | v4l_dbg(1, debug, client, "revision 0x%x\n", |
436 | I2C_NAME(client), i); | 365 | saa7185_read(client) >> 5); |
437 | } else { | ||
438 | dprintk(1, | ||
439 | KERN_INFO | ||
440 | "%s_attach: chip version %d at address 0x%x\n", | ||
441 | I2C_NAME(client), saa7185_read(client) >> 5, | ||
442 | client->addr << 1); | ||
443 | } | ||
444 | |||
445 | return 0; | 366 | return 0; |
446 | } | 367 | } |
447 | 368 | ||
448 | static int | 369 | static int saa7185_remove(struct i2c_client *client) |
449 | saa7185_attach_adapter (struct i2c_adapter *adapter) | ||
450 | { | ||
451 | dprintk(1, | ||
452 | KERN_INFO | ||
453 | "saa7185.c: starting probe for adapter %s (0x%x)\n", | ||
454 | I2C_NAME(adapter), adapter->id); | ||
455 | return i2c_probe(adapter, &addr_data, &saa7185_detect_client); | ||
456 | } | ||
457 | |||
458 | static int | ||
459 | saa7185_detach_client (struct i2c_client *client) | ||
460 | { | 370 | { |
461 | struct saa7185 *encoder = i2c_get_clientdata(client); | 371 | struct saa7185 *encoder = i2c_get_clientdata(client); |
462 | int err; | ||
463 | |||
464 | err = i2c_detach_client(client); | ||
465 | if (err) { | ||
466 | return err; | ||
467 | } | ||
468 | 372 | ||
469 | saa7185_write(client, 0x61, (encoder->reg[0x61]) | 0x40); /* SW: output off is active */ | 373 | saa7185_write(client, 0x61, (encoder->reg[0x61]) | 0x40); /* SW: output off is active */ |
470 | //saa7185_write(client, 0x3a, (encoder->reg[0x3a]) | 0x80); /* SW: color bar */ | 374 | //saa7185_write(client, 0x3a, (encoder->reg[0x3a]) | 0x80); /* SW: color bar */ |
471 | 375 | ||
472 | kfree(encoder); | 376 | kfree(encoder); |
473 | kfree(client); | ||
474 | |||
475 | return 0; | 377 | return 0; |
476 | } | 378 | } |
477 | 379 | ||
478 | /* ----------------------------------------------------------------------- */ | 380 | /* ----------------------------------------------------------------------- */ |
479 | 381 | ||
480 | static struct i2c_driver i2c_driver_saa7185 = { | 382 | static const struct i2c_device_id saa7185_id[] = { |
481 | .driver = { | 383 | { "saa7185", 0 }, |
482 | .name = "saa7185", /* name */ | 384 | { } |
483 | }, | 385 | }; |
484 | 386 | MODULE_DEVICE_TABLE(i2c, saa7185_id); | |
485 | .id = I2C_DRIVERID_SAA7185B, | ||
486 | 387 | ||
487 | .attach_adapter = saa7185_attach_adapter, | 388 | static struct v4l2_i2c_driver_data v4l2_i2c_data = { |
488 | .detach_client = saa7185_detach_client, | 389 | .name = "saa7185", |
390 | .driverid = I2C_DRIVERID_SAA7185B, | ||
489 | .command = saa7185_command, | 391 | .command = saa7185_command, |
392 | .probe = saa7185_probe, | ||
393 | .remove = saa7185_remove, | ||
394 | .id_table = saa7185_id, | ||
490 | }; | 395 | }; |
491 | |||
492 | static int __init | ||
493 | saa7185_init (void) | ||
494 | { | ||
495 | return i2c_add_driver(&i2c_driver_saa7185); | ||
496 | } | ||
497 | |||
498 | static void __exit | ||
499 | saa7185_exit (void) | ||
500 | { | ||
501 | i2c_del_driver(&i2c_driver_saa7185); | ||
502 | } | ||
503 | |||
504 | module_init(saa7185_init); | ||
505 | module_exit(saa7185_exit); | ||
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c index 76838091dc66..2407607f2eff 100644 --- a/drivers/media/video/sh_mobile_ceu_camera.c +++ b/drivers/media/video/sh_mobile_ceu_camera.c | |||
@@ -40,39 +40,39 @@ | |||
40 | 40 | ||
41 | /* register offsets for sh7722 / sh7723 */ | 41 | /* register offsets for sh7722 / sh7723 */ |
42 | 42 | ||
43 | #define CAPSR 0x00 | 43 | #define CAPSR 0x00 /* Capture start register */ |
44 | #define CAPCR 0x04 | 44 | #define CAPCR 0x04 /* Capture control register */ |
45 | #define CAMCR 0x08 | 45 | #define CAMCR 0x08 /* Capture interface control register */ |
46 | #define CMCYR 0x0c | 46 | #define CMCYR 0x0c /* Capture interface cycle register */ |
47 | #define CAMOR 0x10 | 47 | #define CAMOR 0x10 /* Capture interface offset register */ |
48 | #define CAPWR 0x14 | 48 | #define CAPWR 0x14 /* Capture interface width register */ |
49 | #define CAIFR 0x18 | 49 | #define CAIFR 0x18 /* Capture interface input format register */ |
50 | #define CSTCR 0x20 /* not on sh7723 */ | 50 | #define CSTCR 0x20 /* Camera strobe control register (<= sh7722) */ |
51 | #define CSECR 0x24 /* not on sh7723 */ | 51 | #define CSECR 0x24 /* Camera strobe emission count register (<= sh7722) */ |
52 | #define CRCNTR 0x28 | 52 | #define CRCNTR 0x28 /* CEU register control register */ |
53 | #define CRCMPR 0x2c | 53 | #define CRCMPR 0x2c /* CEU register forcible control register */ |
54 | #define CFLCR 0x30 | 54 | #define CFLCR 0x30 /* Capture filter control register */ |
55 | #define CFSZR 0x34 | 55 | #define CFSZR 0x34 /* Capture filter size clip register */ |
56 | #define CDWDR 0x38 | 56 | #define CDWDR 0x38 /* Capture destination width register */ |
57 | #define CDAYR 0x3c | 57 | #define CDAYR 0x3c /* Capture data address Y register */ |
58 | #define CDACR 0x40 | 58 | #define CDACR 0x40 /* Capture data address C register */ |
59 | #define CDBYR 0x44 | 59 | #define CDBYR 0x44 /* Capture data bottom-field address Y register */ |
60 | #define CDBCR 0x48 | 60 | #define CDBCR 0x48 /* Capture data bottom-field address C register */ |
61 | #define CBDSR 0x4c | 61 | #define CBDSR 0x4c /* Capture bundle destination size register */ |
62 | #define CFWCR 0x5c | 62 | #define CFWCR 0x5c /* Firewall operation control register */ |
63 | #define CLFCR 0x60 | 63 | #define CLFCR 0x60 /* Capture low-pass filter control register */ |
64 | #define CDOCR 0x64 | 64 | #define CDOCR 0x64 /* Capture data output control register */ |
65 | #define CDDCR 0x68 | 65 | #define CDDCR 0x68 /* Capture data complexity level register */ |
66 | #define CDDAR 0x6c | 66 | #define CDDAR 0x6c /* Capture data complexity level address register */ |
67 | #define CEIER 0x70 | 67 | #define CEIER 0x70 /* Capture event interrupt enable register */ |
68 | #define CETCR 0x74 | 68 | #define CETCR 0x74 /* Capture event flag clear register */ |
69 | #define CSTSR 0x7c | 69 | #define CSTSR 0x7c /* Capture status register */ |
70 | #define CSRTR 0x80 | 70 | #define CSRTR 0x80 /* Capture software reset register */ |
71 | #define CDSSR 0x84 | 71 | #define CDSSR 0x84 /* Capture data size register */ |
72 | #define CDAYR2 0x90 | 72 | #define CDAYR2 0x90 /* Capture data address Y register 2 */ |
73 | #define CDACR2 0x94 | 73 | #define CDACR2 0x94 /* Capture data address C register 2 */ |
74 | #define CDBYR2 0x98 | 74 | #define CDBYR2 0x98 /* Capture data bottom-field address Y register 2 */ |
75 | #define CDBCR2 0x9c | 75 | #define CDBCR2 0x9c /* Capture data bottom-field address C register 2 */ |
76 | 76 | ||
77 | static DEFINE_MUTEX(camera_lock); | 77 | static DEFINE_MUTEX(camera_lock); |
78 | 78 | ||
@@ -165,6 +165,7 @@ static void sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev) | |||
165 | ceu_write(pcdev, CETCR, 0x0317f313 ^ 0x10); | 165 | ceu_write(pcdev, CETCR, 0x0317f313 ^ 0x10); |
166 | 166 | ||
167 | if (pcdev->active) { | 167 | if (pcdev->active) { |
168 | pcdev->active->state = VIDEOBUF_ACTIVE; | ||
168 | ceu_write(pcdev, CDAYR, videobuf_to_dma_contig(pcdev->active)); | 169 | ceu_write(pcdev, CDAYR, videobuf_to_dma_contig(pcdev->active)); |
169 | ceu_write(pcdev, CAPSR, 0x1); /* start capture */ | 170 | ceu_write(pcdev, CAPSR, 0x1); /* start capture */ |
170 | } | 171 | } |
@@ -236,7 +237,7 @@ static void sh_mobile_ceu_videobuf_queue(struct videobuf_queue *vq, | |||
236 | dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__, | 237 | dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__, |
237 | vb, vb->baddr, vb->bsize); | 238 | vb, vb->baddr, vb->bsize); |
238 | 239 | ||
239 | vb->state = VIDEOBUF_ACTIVE; | 240 | vb->state = VIDEOBUF_QUEUED; |
240 | spin_lock_irqsave(&pcdev->lock, flags); | 241 | spin_lock_irqsave(&pcdev->lock, flags); |
241 | list_add_tail(&vb->queue, &pcdev->capture); | 242 | list_add_tail(&vb->queue, &pcdev->capture); |
242 | 243 | ||
@@ -323,12 +324,24 @@ static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd) | |||
323 | { | 324 | { |
324 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); | 325 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); |
325 | struct sh_mobile_ceu_dev *pcdev = ici->priv; | 326 | struct sh_mobile_ceu_dev *pcdev = ici->priv; |
327 | unsigned long flags; | ||
326 | 328 | ||
327 | BUG_ON(icd != pcdev->icd); | 329 | BUG_ON(icd != pcdev->icd); |
328 | 330 | ||
329 | /* disable capture, disable interrupts */ | 331 | /* disable capture, disable interrupts */ |
330 | ceu_write(pcdev, CEIER, 0); | 332 | ceu_write(pcdev, CEIER, 0); |
331 | ceu_write(pcdev, CAPSR, 1 << 16); /* reset */ | 333 | ceu_write(pcdev, CAPSR, 1 << 16); /* reset */ |
334 | |||
335 | /* make sure active buffer is canceled */ | ||
336 | spin_lock_irqsave(&pcdev->lock, flags); | ||
337 | if (pcdev->active) { | ||
338 | list_del(&pcdev->active->queue); | ||
339 | pcdev->active->state = VIDEOBUF_ERROR; | ||
340 | wake_up_all(&pcdev->active->done); | ||
341 | pcdev->active = NULL; | ||
342 | } | ||
343 | spin_unlock_irqrestore(&pcdev->lock, flags); | ||
344 | |||
332 | icd->ops->release(icd); | 345 | icd->ops->release(icd); |
333 | 346 | ||
334 | dev_info(&icd->dev, | 347 | dev_info(&icd->dev, |
@@ -391,7 +404,20 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd, | |||
391 | ceu_write(pcdev, CFLCR, 0); /* data fetch mode - no scaling */ | 404 | ceu_write(pcdev, CFLCR, 0); /* data fetch mode - no scaling */ |
392 | ceu_write(pcdev, CFSZR, (icd->height << 16) | cfszr_width); | 405 | ceu_write(pcdev, CFSZR, (icd->height << 16) | cfszr_width); |
393 | ceu_write(pcdev, CLFCR, 0); /* data fetch mode - no lowpass filter */ | 406 | ceu_write(pcdev, CLFCR, 0); /* data fetch mode - no lowpass filter */ |
394 | ceu_write(pcdev, CDOCR, 0x00000016); | 407 | |
408 | /* A few words about byte order (observed in Big Endian mode) | ||
409 | * | ||
410 | * In data fetch mode bytes are received in chunks of 8 bytes. | ||
411 | * D0, D1, D2, D3, D4, D5, D6, D7 (D0 received first) | ||
412 | * | ||
413 | * The data is however by default written to memory in reverse order: | ||
414 | * D7, D6, D5, D4, D3, D2, D1, D0 (D7 written to lowest byte) | ||
415 | * | ||
416 | * The lowest three bits of CDOCR allows us to do swapping, | ||
417 | * using 7 we swap the data bytes to match the incoming order: | ||
418 | * D0, D1, D2, D3, D4, D5, D6, D7 | ||
419 | */ | ||
420 | ceu_write(pcdev, CDOCR, 0x00000017); | ||
395 | 421 | ||
396 | ceu_write(pcdev, CDWDR, cdwdr_width); | 422 | ceu_write(pcdev, CDWDR, cdwdr_width); |
397 | ceu_write(pcdev, CFWCR, 0); /* keep "datafetch firewall" disabled */ | 423 | ceu_write(pcdev, CFWCR, 0); /* keep "datafetch firewall" disabled */ |
diff --git a/drivers/media/video/soc_camera_platform.c b/drivers/media/video/soc_camera_platform.c index 1adc257ebdb9..bb7a9d480e8f 100644 --- a/drivers/media/video/soc_camera_platform.c +++ b/drivers/media/video/soc_camera_platform.c | |||
@@ -18,15 +18,7 @@ | |||
18 | #include <linux/videodev2.h> | 18 | #include <linux/videodev2.h> |
19 | #include <media/v4l2-common.h> | 19 | #include <media/v4l2-common.h> |
20 | #include <media/soc_camera.h> | 20 | #include <media/soc_camera.h> |
21 | 21 | #include <media/soc_camera_platform.h> | |
22 | struct soc_camera_platform_info { | ||
23 | int iface; | ||
24 | char *format_name; | ||
25 | unsigned long format_depth; | ||
26 | struct v4l2_pix_format format; | ||
27 | unsigned long bus_param; | ||
28 | int (*set_capture)(struct soc_camera_platform_info *info, int enable); | ||
29 | }; | ||
30 | 22 | ||
31 | struct soc_camera_platform_priv { | 23 | struct soc_camera_platform_priv { |
32 | struct soc_camera_platform_info *info; | 24 | struct soc_camera_platform_info *info; |
@@ -44,11 +36,21 @@ soc_camera_platform_get_info(struct soc_camera_device *icd) | |||
44 | 36 | ||
45 | static int soc_camera_platform_init(struct soc_camera_device *icd) | 37 | static int soc_camera_platform_init(struct soc_camera_device *icd) |
46 | { | 38 | { |
39 | struct soc_camera_platform_info *p = soc_camera_platform_get_info(icd); | ||
40 | |||
41 | if (p->power) | ||
42 | p->power(1); | ||
43 | |||
47 | return 0; | 44 | return 0; |
48 | } | 45 | } |
49 | 46 | ||
50 | static int soc_camera_platform_release(struct soc_camera_device *icd) | 47 | static int soc_camera_platform_release(struct soc_camera_device *icd) |
51 | { | 48 | { |
49 | struct soc_camera_platform_info *p = soc_camera_platform_get_info(icd); | ||
50 | |||
51 | if (p->power) | ||
52 | p->power(0); | ||
53 | |||
52 | return 0; | 54 | return 0; |
53 | } | 55 | } |
54 | 56 | ||
diff --git a/drivers/media/video/stk-webcam.c b/drivers/media/video/stk-webcam.c index db69bc5556d6..edaea4964513 100644 --- a/drivers/media/video/stk-webcam.c +++ b/drivers/media/video/stk-webcam.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
28 | #include <linux/errno.h> | 28 | #include <linux/errno.h> |
29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | #include <linux/kref.h> | ||
31 | 30 | ||
32 | #include <linux/usb.h> | 31 | #include <linux/usb.h> |
33 | #include <linux/mm.h> | 32 | #include <linux/mm.h> |
@@ -560,7 +559,7 @@ static void stk_clean_iso(struct stk_camera *dev) | |||
560 | 559 | ||
561 | urb = dev->isobufs[i].urb; | 560 | urb = dev->isobufs[i].urb; |
562 | if (urb) { | 561 | if (urb) { |
563 | if (atomic_read(&dev->urbs_used)) | 562 | if (atomic_read(&dev->urbs_used) && is_present(dev)) |
564 | usb_kill_urb(urb); | 563 | usb_kill_urb(urb); |
565 | usb_free_urb(urb); | 564 | usb_free_urb(urb); |
566 | } | 565 | } |
@@ -689,18 +688,14 @@ static int v4l_stk_release(struct inode *inode, struct file *fp) | |||
689 | { | 688 | { |
690 | struct stk_camera *dev = fp->private_data; | 689 | struct stk_camera *dev = fp->private_data; |
691 | 690 | ||
692 | if (dev->owner != fp) { | 691 | if (dev->owner == fp) { |
693 | usb_autopm_put_interface(dev->interface); | 692 | stk_stop_stream(dev); |
694 | return 0; | 693 | stk_free_buffers(dev); |
694 | dev->owner = NULL; | ||
695 | } | 695 | } |
696 | 696 | ||
697 | stk_stop_stream(dev); | 697 | if(is_present(dev)) |
698 | 698 | usb_autopm_put_interface(dev->interface); | |
699 | stk_free_buffers(dev); | ||
700 | |||
701 | dev->owner = NULL; | ||
702 | |||
703 | usb_autopm_put_interface(dev->interface); | ||
704 | 699 | ||
705 | return 0; | 700 | return 0; |
706 | } | 701 | } |
@@ -714,9 +709,6 @@ static ssize_t v4l_stk_read(struct file *fp, char __user *buf, | |||
714 | struct stk_sio_buffer *sbuf; | 709 | struct stk_sio_buffer *sbuf; |
715 | struct stk_camera *dev = fp->private_data; | 710 | struct stk_camera *dev = fp->private_data; |
716 | 711 | ||
717 | if (dev == NULL) | ||
718 | return -EIO; | ||
719 | |||
720 | if (!is_present(dev)) | 712 | if (!is_present(dev)) |
721 | return -EIO; | 713 | return -EIO; |
722 | if (dev->owner && dev->owner != fp) | 714 | if (dev->owner && dev->owner != fp) |
@@ -773,9 +765,6 @@ static unsigned int v4l_stk_poll(struct file *fp, poll_table *wait) | |||
773 | { | 765 | { |
774 | struct stk_camera *dev = fp->private_data; | 766 | struct stk_camera *dev = fp->private_data; |
775 | 767 | ||
776 | if (dev == NULL) | ||
777 | return -ENODEV; | ||
778 | |||
779 | poll_wait(fp, &dev->wait_frame, wait); | 768 | poll_wait(fp, &dev->wait_frame, wait); |
780 | 769 | ||
781 | if (!is_present(dev)) | 770 | if (!is_present(dev)) |
@@ -1436,7 +1425,7 @@ static void stk_camera_disconnect(struct usb_interface *interface) | |||
1436 | wake_up_interruptible(&dev->wait_frame); | 1425 | wake_up_interruptible(&dev->wait_frame); |
1437 | stk_remove_sysfs_files(&dev->vdev); | 1426 | stk_remove_sysfs_files(&dev->vdev); |
1438 | 1427 | ||
1439 | STK_INFO("Syntek USB2.0 Camera release resources" | 1428 | STK_INFO("Syntek USB2.0 Camera release resources " |
1440 | "video device /dev/video%d\n", dev->vdev.minor); | 1429 | "video device /dev/video%d\n", dev->vdev.minor); |
1441 | 1430 | ||
1442 | video_unregister_device(&dev->vdev); | 1431 | video_unregister_device(&dev->vdev); |
diff --git a/drivers/media/video/stk-webcam.h b/drivers/media/video/stk-webcam.h index 084a85bdd16e..9f6736637571 100644 --- a/drivers/media/video/stk-webcam.h +++ b/drivers/media/video/stk-webcam.h | |||
@@ -122,7 +122,6 @@ struct stk_camera { | |||
122 | 122 | ||
123 | #define vdev_to_camera(d) container_of(d, struct stk_camera, vdev) | 123 | #define vdev_to_camera(d) container_of(d, struct stk_camera, vdev) |
124 | 124 | ||
125 | void stk_camera_delete(struct kref *); | ||
126 | int stk_camera_write_reg(struct stk_camera *, u16, u8); | 125 | int stk_camera_write_reg(struct stk_camera *, u16, u8); |
127 | int stk_camera_read_reg(struct stk_camera *, u16, int *); | 126 | int stk_camera_read_reg(struct stk_camera *, u16, int *); |
128 | 127 | ||
diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c index bcc32fa92a81..3b0b84c2e451 100644 --- a/drivers/media/video/tveeprom.c +++ b/drivers/media/video/tveeprom.c | |||
@@ -242,7 +242,7 @@ hauppauge_tuner[] = | |||
242 | { TUNER_ABSENT, "TCL M2523_3DBH_E"}, | 242 | { TUNER_ABSENT, "TCL M2523_3DBH_E"}, |
243 | { TUNER_ABSENT, "TCL M2523_3DIH_E"}, | 243 | { TUNER_ABSENT, "TCL M2523_3DIH_E"}, |
244 | { TUNER_ABSENT, "TCL MFPE05_2_U"}, | 244 | { TUNER_ABSENT, "TCL MFPE05_2_U"}, |
245 | { TUNER_PHILIPS_FMD1216ME_MK3, "Philips FMD1216MEX"}, | 245 | { TUNER_PHILIPS_FMD1216MEX_MK3, "Philips FMD1216MEX"}, |
246 | { TUNER_ABSENT, "Philips FRH2036B"}, | 246 | { TUNER_ABSENT, "Philips FRH2036B"}, |
247 | { TUNER_ABSENT, "Panasonic ENGF75_01GF"}, | 247 | { TUNER_ABSENT, "Panasonic ENGF75_01GF"}, |
248 | { TUNER_ABSENT, "MaxLinear MXL5005"}, | 248 | { TUNER_ABSENT, "MaxLinear MXL5005"}, |
diff --git a/drivers/media/video/videobuf-dvb.c b/drivers/media/video/videobuf-dvb.c index b56cffcbfd45..917277d36605 100644 --- a/drivers/media/video/videobuf-dvb.c +++ b/drivers/media/video/videobuf-dvb.c | |||
@@ -126,7 +126,6 @@ static int videobuf_dvb_stop_feed(struct dvb_demux_feed *feed) | |||
126 | mutex_lock(&dvb->lock); | 126 | mutex_lock(&dvb->lock); |
127 | dvb->nfeeds--; | 127 | dvb->nfeeds--; |
128 | if (0 == dvb->nfeeds && NULL != dvb->thread) { | 128 | if (0 == dvb->nfeeds && NULL != dvb->thread) { |
129 | // FIXME: cx8802_cancel_buffers(dev); | ||
130 | err = kthread_stop(dvb->thread); | 129 | err = kthread_stop(dvb->thread); |
131 | dvb->thread = NULL; | 130 | dvb->thread = NULL; |
132 | } | 131 | } |
@@ -134,30 +133,38 @@ static int videobuf_dvb_stop_feed(struct dvb_demux_feed *feed) | |||
134 | return err; | 133 | return err; |
135 | } | 134 | } |
136 | 135 | ||
137 | /* ------------------------------------------------------------------ */ | 136 | static int videobuf_dvb_register_adapter(struct videobuf_dvb_frontends *fe, |
138 | |||
139 | int videobuf_dvb_register(struct videobuf_dvb *dvb, | ||
140 | struct module *module, | 137 | struct module *module, |
141 | void *adapter_priv, | 138 | void *adapter_priv, |
142 | struct device *device, | 139 | struct device *device, |
143 | short *adapter_nr) | 140 | char *adapter_name, |
141 | short *adapter_nr, | ||
142 | int mfe_shared) | ||
144 | { | 143 | { |
145 | int result; | 144 | int result; |
146 | 145 | ||
147 | mutex_init(&dvb->lock); | 146 | mutex_init(&fe->lock); |
148 | 147 | ||
149 | /* register adapter */ | 148 | /* register adapter */ |
150 | result = dvb_register_adapter(&dvb->adapter, dvb->name, module, device, | 149 | result = dvb_register_adapter(&fe->adapter, adapter_name, module, |
151 | adapter_nr); | 150 | device, adapter_nr); |
152 | if (result < 0) { | 151 | if (result < 0) { |
153 | printk(KERN_WARNING "%s: dvb_register_adapter failed (errno = %d)\n", | 152 | printk(KERN_WARNING "%s: dvb_register_adapter failed (errno = %d)\n", |
154 | dvb->name, result); | 153 | adapter_name, result); |
155 | goto fail_adapter; | ||
156 | } | 154 | } |
157 | dvb->adapter.priv = adapter_priv; | 155 | fe->adapter.priv = adapter_priv; |
156 | fe->adapter.mfe_shared = mfe_shared; | ||
157 | |||
158 | return result; | ||
159 | } | ||
160 | |||
161 | static int videobuf_dvb_register_frontend(struct dvb_adapter *adapter, | ||
162 | struct videobuf_dvb *dvb) | ||
163 | { | ||
164 | int result; | ||
158 | 165 | ||
159 | /* register frontend */ | 166 | /* register frontend */ |
160 | result = dvb_register_frontend(&dvb->adapter, dvb->frontend); | 167 | result = dvb_register_frontend(adapter, dvb->frontend); |
161 | if (result < 0) { | 168 | if (result < 0) { |
162 | printk(KERN_WARNING "%s: dvb_register_frontend failed (errno = %d)\n", | 169 | printk(KERN_WARNING "%s: dvb_register_frontend failed (errno = %d)\n", |
163 | dvb->name, result); | 170 | dvb->name, result); |
@@ -183,7 +190,8 @@ int videobuf_dvb_register(struct videobuf_dvb *dvb, | |||
183 | dvb->dmxdev.filternum = 256; | 190 | dvb->dmxdev.filternum = 256; |
184 | dvb->dmxdev.demux = &dvb->demux.dmx; | 191 | dvb->dmxdev.demux = &dvb->demux.dmx; |
185 | dvb->dmxdev.capabilities = 0; | 192 | dvb->dmxdev.capabilities = 0; |
186 | result = dvb_dmxdev_init(&dvb->dmxdev, &dvb->adapter); | 193 | result = dvb_dmxdev_init(&dvb->dmxdev, adapter); |
194 | |||
187 | if (result < 0) { | 195 | if (result < 0) { |
188 | printk(KERN_WARNING "%s: dvb_dmxdev_init failed (errno = %d)\n", | 196 | printk(KERN_WARNING "%s: dvb_dmxdev_init failed (errno = %d)\n", |
189 | dvb->name, result); | 197 | dvb->name, result); |
@@ -214,7 +222,11 @@ int videobuf_dvb_register(struct videobuf_dvb *dvb, | |||
214 | } | 222 | } |
215 | 223 | ||
216 | /* register network adapter */ | 224 | /* register network adapter */ |
217 | dvb_net_init(&dvb->adapter, &dvb->net, &dvb->demux.dmx); | 225 | dvb_net_init(adapter, &dvb->net, &dvb->demux.dmx); |
226 | if (dvb->net.dvbdev == NULL) { | ||
227 | result = -ENOMEM; | ||
228 | goto fail_fe_conn; | ||
229 | } | ||
218 | return 0; | 230 | return 0; |
219 | 231 | ||
220 | fail_fe_conn: | 232 | fail_fe_conn: |
@@ -229,30 +241,151 @@ fail_dmx: | |||
229 | dvb_unregister_frontend(dvb->frontend); | 241 | dvb_unregister_frontend(dvb->frontend); |
230 | fail_frontend: | 242 | fail_frontend: |
231 | dvb_frontend_detach(dvb->frontend); | 243 | dvb_frontend_detach(dvb->frontend); |
232 | dvb_unregister_adapter(&dvb->adapter); | 244 | dvb->frontend = NULL; |
233 | fail_adapter: | 245 | |
234 | return result; | 246 | return result; |
235 | } | 247 | } |
236 | 248 | ||
237 | void videobuf_dvb_unregister(struct videobuf_dvb *dvb) | 249 | /* ------------------------------------------------------------------ */ |
250 | /* Register a single adapter and one or more frontends */ | ||
251 | int videobuf_dvb_register_bus(struct videobuf_dvb_frontends *f, | ||
252 | struct module *module, | ||
253 | void *adapter_priv, | ||
254 | struct device *device, | ||
255 | short *adapter_nr, | ||
256 | int mfe_shared) | ||
238 | { | 257 | { |
239 | dvb_net_release(&dvb->net); | 258 | struct list_head *list, *q; |
240 | dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem); | 259 | struct videobuf_dvb_frontend *fe; |
241 | dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw); | 260 | int res; |
242 | dvb_dmxdev_release(&dvb->dmxdev); | 261 | |
243 | dvb_dmx_release(&dvb->demux); | 262 | fe = videobuf_dvb_get_frontend(f, 1); |
244 | dvb_unregister_frontend(dvb->frontend); | 263 | if (!fe) { |
245 | dvb_frontend_detach(dvb->frontend); | 264 | printk(KERN_WARNING "Unable to register the adapter which has no frontends\n"); |
246 | dvb_unregister_adapter(&dvb->adapter); | 265 | return -EINVAL; |
266 | } | ||
267 | |||
268 | /* Bring up the adapter */ | ||
269 | res = videobuf_dvb_register_adapter(f, module, adapter_priv, device, | ||
270 | fe->dvb.name, adapter_nr, mfe_shared); | ||
271 | if (res < 0) { | ||
272 | printk(KERN_WARNING "videobuf_dvb_register_adapter failed (errno = %d)\n", res); | ||
273 | return res; | ||
274 | } | ||
275 | |||
276 | /* Attach all of the frontends to the adapter */ | ||
277 | mutex_lock(&f->lock); | ||
278 | list_for_each_safe(list, q, &f->felist) { | ||
279 | fe = list_entry(list, struct videobuf_dvb_frontend, felist); | ||
280 | res = videobuf_dvb_register_frontend(&f->adapter, &fe->dvb); | ||
281 | if (res < 0) { | ||
282 | printk(KERN_WARNING "%s: videobuf_dvb_register_frontend failed (errno = %d)\n", | ||
283 | fe->dvb.name, res); | ||
284 | goto err; | ||
285 | } | ||
286 | } | ||
287 | mutex_unlock(&f->lock); | ||
288 | return 0; | ||
289 | |||
290 | err: | ||
291 | mutex_unlock(&f->lock); | ||
292 | videobuf_dvb_unregister_bus(f); | ||
293 | return res; | ||
247 | } | 294 | } |
295 | EXPORT_SYMBOL(videobuf_dvb_register_bus); | ||
248 | 296 | ||
249 | EXPORT_SYMBOL(videobuf_dvb_register); | 297 | void videobuf_dvb_unregister_bus(struct videobuf_dvb_frontends *f) |
250 | EXPORT_SYMBOL(videobuf_dvb_unregister); | 298 | { |
299 | struct list_head *list, *q; | ||
300 | struct videobuf_dvb_frontend *fe; | ||
301 | |||
302 | mutex_lock(&f->lock); | ||
303 | list_for_each_safe(list, q, &f->felist) { | ||
304 | fe = list_entry(list, struct videobuf_dvb_frontend, felist); | ||
305 | if (fe->dvb.net.dvbdev) { | ||
306 | dvb_net_release(&fe->dvb.net); | ||
307 | fe->dvb.demux.dmx.remove_frontend(&fe->dvb.demux.dmx, | ||
308 | &fe->dvb.fe_mem); | ||
309 | fe->dvb.demux.dmx.remove_frontend(&fe->dvb.demux.dmx, | ||
310 | &fe->dvb.fe_hw); | ||
311 | dvb_dmxdev_release(&fe->dvb.dmxdev); | ||
312 | dvb_dmx_release(&fe->dvb.demux); | ||
313 | dvb_unregister_frontend(fe->dvb.frontend); | ||
314 | } | ||
315 | if (fe->dvb.frontend) | ||
316 | /* always allocated, may have been reset */ | ||
317 | dvb_frontend_detach(fe->dvb.frontend); | ||
318 | list_del(list); | ||
319 | kfree(fe); | ||
320 | } | ||
321 | mutex_unlock(&f->lock); | ||
251 | 322 | ||
252 | /* ------------------------------------------------------------------ */ | 323 | dvb_unregister_adapter(&f->adapter); |
253 | /* | 324 | } |
254 | * Local variables: | 325 | EXPORT_SYMBOL(videobuf_dvb_unregister_bus); |
255 | * c-basic-offset: 8 | 326 | |
256 | * compile-command: "make DVB=1" | 327 | struct videobuf_dvb_frontend *videobuf_dvb_get_frontend( |
257 | * End: | 328 | struct videobuf_dvb_frontends *f, int id) |
258 | */ | 329 | { |
330 | struct list_head *list, *q; | ||
331 | struct videobuf_dvb_frontend *fe, *ret = NULL; | ||
332 | |||
333 | mutex_lock(&f->lock); | ||
334 | |||
335 | list_for_each_safe(list, q, &f->felist) { | ||
336 | fe = list_entry(list, struct videobuf_dvb_frontend, felist); | ||
337 | if (fe->id == id) { | ||
338 | ret = fe; | ||
339 | break; | ||
340 | } | ||
341 | } | ||
342 | |||
343 | mutex_unlock(&f->lock); | ||
344 | |||
345 | return ret; | ||
346 | } | ||
347 | EXPORT_SYMBOL(videobuf_dvb_get_frontend); | ||
348 | |||
349 | int videobuf_dvb_find_frontend(struct videobuf_dvb_frontends *f, | ||
350 | struct dvb_frontend *p) | ||
351 | { | ||
352 | struct list_head *list, *q; | ||
353 | struct videobuf_dvb_frontend *fe = NULL; | ||
354 | int ret = 0; | ||
355 | |||
356 | mutex_lock(&f->lock); | ||
357 | |||
358 | list_for_each_safe(list, q, &f->felist) { | ||
359 | fe = list_entry(list, struct videobuf_dvb_frontend, felist); | ||
360 | if (fe->dvb.frontend == p) { | ||
361 | ret = fe->id; | ||
362 | break; | ||
363 | } | ||
364 | } | ||
365 | |||
366 | mutex_unlock(&f->lock); | ||
367 | |||
368 | return ret; | ||
369 | } | ||
370 | EXPORT_SYMBOL(videobuf_dvb_find_frontend); | ||
371 | |||
372 | struct videobuf_dvb_frontend *videobuf_dvb_alloc_frontend( | ||
373 | struct videobuf_dvb_frontends *f, int id) | ||
374 | { | ||
375 | struct videobuf_dvb_frontend *fe; | ||
376 | |||
377 | fe = kzalloc(sizeof(struct videobuf_dvb_frontend), GFP_KERNEL); | ||
378 | if (fe == NULL) | ||
379 | goto fail_alloc; | ||
380 | |||
381 | fe->id = id; | ||
382 | mutex_init(&fe->dvb.lock); | ||
383 | |||
384 | mutex_lock(&f->lock); | ||
385 | list_add_tail(&fe->felist, &f->felist); | ||
386 | mutex_unlock(&f->lock); | ||
387 | |||
388 | fail_alloc: | ||
389 | return fe; | ||
390 | } | ||
391 | EXPORT_SYMBOL(videobuf_dvb_alloc_frontend); | ||
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c index 65c8af18e767..7d7e51def461 100644 --- a/drivers/media/video/vivi.c +++ b/drivers/media/video/vivi.c | |||
@@ -128,12 +128,56 @@ struct vivi_fmt { | |||
128 | int depth; | 128 | int depth; |
129 | }; | 129 | }; |
130 | 130 | ||
131 | static struct vivi_fmt format = { | 131 | static struct vivi_fmt formats[] = { |
132 | .name = "4:2:2, packed, YUYV", | 132 | { |
133 | .fourcc = V4L2_PIX_FMT_YUYV, | 133 | .name = "4:2:2, packed, YUYV", |
134 | .depth = 16, | 134 | .fourcc = V4L2_PIX_FMT_YUYV, |
135 | .depth = 16, | ||
136 | }, | ||
137 | { | ||
138 | .name = "4:2:2, packed, UYVY", | ||
139 | .fourcc = V4L2_PIX_FMT_UYVY, | ||
140 | .depth = 16, | ||
141 | }, | ||
142 | { | ||
143 | .name = "RGB565 (LE)", | ||
144 | .fourcc = V4L2_PIX_FMT_RGB565, /* gggbbbbb rrrrrggg */ | ||
145 | .depth = 16, | ||
146 | }, | ||
147 | { | ||
148 | .name = "RGB565 (BE)", | ||
149 | .fourcc = V4L2_PIX_FMT_RGB565X, /* rrrrrggg gggbbbbb */ | ||
150 | .depth = 16, | ||
151 | }, | ||
152 | { | ||
153 | .name = "RGB555 (LE)", | ||
154 | .fourcc = V4L2_PIX_FMT_RGB555, /* gggbbbbb arrrrrgg */ | ||
155 | .depth = 16, | ||
156 | }, | ||
157 | { | ||
158 | .name = "RGB555 (BE)", | ||
159 | .fourcc = V4L2_PIX_FMT_RGB555X, /* arrrrrgg gggbbbbb */ | ||
160 | .depth = 16, | ||
161 | }, | ||
135 | }; | 162 | }; |
136 | 163 | ||
164 | static struct vivi_fmt *get_format(struct v4l2_format *f) | ||
165 | { | ||
166 | struct vivi_fmt *fmt; | ||
167 | unsigned int k; | ||
168 | |||
169 | for (k = 0; k < ARRAY_SIZE(formats); k++) { | ||
170 | fmt = &formats[k]; | ||
171 | if (fmt->fourcc == f->fmt.pix.pixelformat) | ||
172 | break; | ||
173 | } | ||
174 | |||
175 | if (k == ARRAY_SIZE(formats)) | ||
176 | return NULL; | ||
177 | |||
178 | return &formats[k]; | ||
179 | } | ||
180 | |||
137 | struct sg_to_addr { | 181 | struct sg_to_addr { |
138 | int pos; | 182 | int pos; |
139 | struct scatterlist *sg; | 183 | struct scatterlist *sg; |
@@ -190,6 +234,7 @@ struct vivi_fh { | |||
190 | struct videobuf_queue vb_vidq; | 234 | struct videobuf_queue vb_vidq; |
191 | 235 | ||
192 | enum v4l2_buf_type type; | 236 | enum v4l2_buf_type type; |
237 | unsigned char bars[8][3]; | ||
193 | }; | 238 | }; |
194 | 239 | ||
195 | /* ------------------------------------------------------------------ | 240 | /* ------------------------------------------------------------------ |
@@ -234,42 +279,118 @@ static u8 bars[8][3] = { | |||
234 | #define TSTAMP_MAX_Y TSTAMP_MIN_Y+15 | 279 | #define TSTAMP_MAX_Y TSTAMP_MIN_Y+15 |
235 | #define TSTAMP_MIN_X 64 | 280 | #define TSTAMP_MIN_X 64 |
236 | 281 | ||
237 | static void gen_line(char *basep, int inipos, int wmax, | 282 | static void gen_twopix(struct vivi_fh *fh, unsigned char *buf, int colorpos) |
238 | int hmax, int line, int count, char *timestr) | ||
239 | { | 283 | { |
240 | int w, i, j, y; | 284 | unsigned char r_y, g_u, b_v; |
241 | int pos = inipos; | 285 | unsigned char *p; |
242 | char *p, *s; | 286 | int color; |
243 | u8 chr, r, g, b, color; | ||
244 | 287 | ||
245 | /* We will just duplicate the second pixel at the packet */ | 288 | r_y = fh->bars[colorpos][0]; /* R or precalculated Y */ |
246 | wmax /= 2; | 289 | g_u = fh->bars[colorpos][1]; /* G or precalculated U */ |
290 | b_v = fh->bars[colorpos][2]; /* B or precalculated V */ | ||
247 | 291 | ||
248 | /* Generate a standard color bar pattern */ | 292 | for (color = 0; color < 4; color++) { |
249 | for (w = 0; w < wmax; w++) { | 293 | p = buf + color; |
250 | int colorpos = ((w + count) * 8/(wmax + 1)) % 8; | ||
251 | r = bars[colorpos][0]; | ||
252 | g = bars[colorpos][1]; | ||
253 | b = bars[colorpos][2]; | ||
254 | |||
255 | for (color = 0; color < 4; color++) { | ||
256 | p = basep + pos; | ||
257 | 294 | ||
295 | switch (fh->fmt->fourcc) { | ||
296 | case V4L2_PIX_FMT_YUYV: | ||
258 | switch (color) { | 297 | switch (color) { |
259 | case 0: | 298 | case 0: |
260 | case 2: | 299 | case 2: |
261 | *p = TO_Y(r, g, b); /* Luma */ | 300 | *p = r_y; |
262 | break; | 301 | break; |
263 | case 1: | 302 | case 1: |
264 | *p = TO_U(r, g, b); /* Cb */ | 303 | *p = g_u; |
265 | break; | 304 | break; |
266 | case 3: | 305 | case 3: |
267 | *p = TO_V(r, g, b); /* Cr */ | 306 | *p = b_v; |
307 | break; | ||
308 | } | ||
309 | break; | ||
310 | case V4L2_PIX_FMT_UYVY: | ||
311 | switch (color) { | ||
312 | case 1: | ||
313 | case 3: | ||
314 | *p = r_y; | ||
315 | break; | ||
316 | case 0: | ||
317 | *p = g_u; | ||
318 | break; | ||
319 | case 2: | ||
320 | *p = b_v; | ||
321 | break; | ||
322 | } | ||
323 | break; | ||
324 | case V4L2_PIX_FMT_RGB565: | ||
325 | switch (color) { | ||
326 | case 0: | ||
327 | case 2: | ||
328 | *p = (g_u << 5) | b_v; | ||
329 | break; | ||
330 | case 1: | ||
331 | case 3: | ||
332 | *p = (r_y << 3) | (g_u >> 3); | ||
333 | break; | ||
334 | } | ||
335 | break; | ||
336 | case V4L2_PIX_FMT_RGB565X: | ||
337 | switch (color) { | ||
338 | case 0: | ||
339 | case 2: | ||
340 | *p = (r_y << 3) | (g_u >> 3); | ||
341 | break; | ||
342 | case 1: | ||
343 | case 3: | ||
344 | *p = (g_u << 5) | b_v; | ||
268 | break; | 345 | break; |
269 | } | 346 | } |
270 | pos++; | 347 | break; |
348 | case V4L2_PIX_FMT_RGB555: | ||
349 | switch (color) { | ||
350 | case 0: | ||
351 | case 2: | ||
352 | *p = (g_u << 5) | b_v; | ||
353 | break; | ||
354 | case 1: | ||
355 | case 3: | ||
356 | *p = (r_y << 2) | (g_u >> 3); | ||
357 | break; | ||
358 | } | ||
359 | break; | ||
360 | case V4L2_PIX_FMT_RGB555X: | ||
361 | switch (color) { | ||
362 | case 0: | ||
363 | case 2: | ||
364 | *p = (r_y << 2) | (g_u >> 3); | ||
365 | break; | ||
366 | case 1: | ||
367 | case 3: | ||
368 | *p = (g_u << 5) | b_v; | ||
369 | break; | ||
370 | } | ||
371 | break; | ||
271 | } | 372 | } |
272 | } | 373 | } |
374 | } | ||
375 | |||
376 | static void gen_line(struct vivi_fh *fh, char *basep, int inipos, int wmax, | ||
377 | int hmax, int line, int count, char *timestr) | ||
378 | { | ||
379 | int w, i, j; | ||
380 | int pos = inipos; | ||
381 | char *s; | ||
382 | u8 chr; | ||
383 | |||
384 | /* We will just duplicate the second pixel at the packet */ | ||
385 | wmax /= 2; | ||
386 | |||
387 | /* Generate a standard color bar pattern */ | ||
388 | for (w = 0; w < wmax; w++) { | ||
389 | int colorpos = ((w + count) * 8/(wmax + 1)) % 8; | ||
390 | |||
391 | gen_twopix(fh, basep + pos, colorpos); | ||
392 | pos += 4; /* only 16 bpp supported for now */ | ||
393 | } | ||
273 | 394 | ||
274 | /* Checks if it is possible to show timestamp */ | 395 | /* Checks if it is possible to show timestamp */ |
275 | if (TSTAMP_MAX_Y >= hmax) | 396 | if (TSTAMP_MAX_Y >= hmax) |
@@ -283,38 +404,12 @@ static void gen_line(char *basep, int inipos, int wmax, | |||
283 | for (s = timestr; *s; s++) { | 404 | for (s = timestr; *s; s++) { |
284 | chr = rom8x16_bits[(*s-0x30)*16+line-TSTAMP_MIN_Y]; | 405 | chr = rom8x16_bits[(*s-0x30)*16+line-TSTAMP_MIN_Y]; |
285 | for (i = 0; i < 7; i++) { | 406 | for (i = 0; i < 7; i++) { |
286 | if (chr & 1 << (7 - i)) { | ||
287 | /* Font color*/ | ||
288 | r = 0; | ||
289 | g = 198; | ||
290 | b = 0; | ||
291 | } else { | ||
292 | /* Background color */ | ||
293 | r = bars[BLACK][0]; | ||
294 | g = bars[BLACK][1]; | ||
295 | b = bars[BLACK][2]; | ||
296 | } | ||
297 | |||
298 | pos = inipos + j * 2; | 407 | pos = inipos + j * 2; |
299 | for (color = 0; color < 4; color++) { | 408 | /* Draw white font on black background */ |
300 | p = basep + pos; | 409 | if (chr & 1 << (7 - i)) |
301 | 410 | gen_twopix(fh, basep + pos, WHITE); | |
302 | y = TO_Y(r, g, b); | 411 | else |
303 | 412 | gen_twopix(fh, basep + pos, BLACK); | |
304 | switch (color) { | ||
305 | case 0: | ||
306 | case 2: | ||
307 | *p = TO_Y(r, g, b); /* Luma */ | ||
308 | break; | ||
309 | case 1: | ||
310 | *p = TO_U(r, g, b); /* Cb */ | ||
311 | break; | ||
312 | case 3: | ||
313 | *p = TO_V(r, g, b); /* Cr */ | ||
314 | break; | ||
315 | } | ||
316 | pos++; | ||
317 | } | ||
318 | j++; | 413 | j++; |
319 | } | 414 | } |
320 | } | 415 | } |
@@ -324,8 +419,9 @@ end: | |||
324 | return; | 419 | return; |
325 | } | 420 | } |
326 | 421 | ||
327 | static void vivi_fillbuff(struct vivi_dev *dev, struct vivi_buffer *buf) | 422 | static void vivi_fillbuff(struct vivi_fh *fh, struct vivi_buffer *buf) |
328 | { | 423 | { |
424 | struct vivi_dev *dev = fh->dev; | ||
329 | int h , pos = 0; | 425 | int h , pos = 0; |
330 | int hmax = buf->vb.height; | 426 | int hmax = buf->vb.height; |
331 | int wmax = buf->vb.width; | 427 | int wmax = buf->vb.width; |
@@ -341,7 +437,7 @@ static void vivi_fillbuff(struct vivi_dev *dev, struct vivi_buffer *buf) | |||
341 | return; | 437 | return; |
342 | 438 | ||
343 | for (h = 0; h < hmax; h++) { | 439 | for (h = 0; h < hmax; h++) { |
344 | gen_line(tmpbuf, 0, wmax, hmax, h, dev->mv_count, | 440 | gen_line(fh, tmpbuf, 0, wmax, hmax, h, dev->mv_count, |
345 | dev->timestr); | 441 | dev->timestr); |
346 | memcpy(vbuf + pos, tmpbuf, wmax * 2); | 442 | memcpy(vbuf + pos, tmpbuf, wmax * 2); |
347 | pos += wmax*2; | 443 | pos += wmax*2; |
@@ -410,7 +506,7 @@ static void vivi_thread_tick(struct vivi_fh *fh) | |||
410 | do_gettimeofday(&buf->vb.ts); | 506 | do_gettimeofday(&buf->vb.ts); |
411 | 507 | ||
412 | /* Fill buffer */ | 508 | /* Fill buffer */ |
413 | vivi_fillbuff(dev, buf); | 509 | vivi_fillbuff(fh, buf); |
414 | dprintk(dev, 1, "filled buffer %p\n", buf); | 510 | dprintk(dev, 1, "filled buffer %p\n", buf); |
415 | 511 | ||
416 | wake_up(&buf->vb.done); | 512 | wake_up(&buf->vb.done); |
@@ -636,11 +732,15 @@ static int vidioc_querycap(struct file *file, void *priv, | |||
636 | static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, | 732 | static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, |
637 | struct v4l2_fmtdesc *f) | 733 | struct v4l2_fmtdesc *f) |
638 | { | 734 | { |
639 | if (f->index > 0) | 735 | struct vivi_fmt *fmt; |
736 | |||
737 | if (f->index >= ARRAY_SIZE(formats)) | ||
640 | return -EINVAL; | 738 | return -EINVAL; |
641 | 739 | ||
642 | strlcpy(f->description, format.name, sizeof(f->description)); | 740 | fmt = &formats[f->index]; |
643 | f->pixelformat = format.fourcc; | 741 | |
742 | strlcpy(f->description, fmt->name, sizeof(f->description)); | ||
743 | f->pixelformat = fmt->fourcc; | ||
644 | return 0; | 744 | return 0; |
645 | } | 745 | } |
646 | 746 | ||
@@ -670,13 +770,12 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, | |||
670 | enum v4l2_field field; | 770 | enum v4l2_field field; |
671 | unsigned int maxw, maxh; | 771 | unsigned int maxw, maxh; |
672 | 772 | ||
673 | if (format.fourcc != f->fmt.pix.pixelformat) { | 773 | fmt = get_format(f); |
674 | dprintk(dev, 1, "Fourcc format (0x%08x) invalid. " | 774 | if (!fmt) { |
675 | "Driver accepts only 0x%08x\n", | 775 | dprintk(dev, 1, "Fourcc format (0x%08x) invalid.\n", |
676 | f->fmt.pix.pixelformat, format.fourcc); | 776 | f->fmt.pix.pixelformat); |
677 | return -EINVAL; | 777 | return -EINVAL; |
678 | } | 778 | } |
679 | fmt = &format; | ||
680 | 779 | ||
681 | field = f->fmt.pix.field; | 780 | field = f->fmt.pix.field; |
682 | 781 | ||
@@ -714,6 +813,8 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, | |||
714 | { | 813 | { |
715 | struct vivi_fh *fh = priv; | 814 | struct vivi_fh *fh = priv; |
716 | struct videobuf_queue *q = &fh->vb_vidq; | 815 | struct videobuf_queue *q = &fh->vb_vidq; |
816 | unsigned char r, g, b; | ||
817 | int k, is_yuv; | ||
717 | 818 | ||
718 | int ret = vidioc_try_fmt_vid_cap(file, fh, f); | 819 | int ret = vidioc_try_fmt_vid_cap(file, fh, f); |
719 | if (ret < 0) | 820 | if (ret < 0) |
@@ -727,12 +828,49 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, | |||
727 | goto out; | 828 | goto out; |
728 | } | 829 | } |
729 | 830 | ||
730 | fh->fmt = &format; | 831 | fh->fmt = get_format(f); |
731 | fh->width = f->fmt.pix.width; | 832 | fh->width = f->fmt.pix.width; |
732 | fh->height = f->fmt.pix.height; | 833 | fh->height = f->fmt.pix.height; |
733 | fh->vb_vidq.field = f->fmt.pix.field; | 834 | fh->vb_vidq.field = f->fmt.pix.field; |
734 | fh->type = f->type; | 835 | fh->type = f->type; |
735 | 836 | ||
837 | /* precalculate color bar values to speed up rendering */ | ||
838 | for (k = 0; k < 8; k++) { | ||
839 | r = bars[k][0]; | ||
840 | g = bars[k][1]; | ||
841 | b = bars[k][2]; | ||
842 | is_yuv = 0; | ||
843 | |||
844 | switch (fh->fmt->fourcc) { | ||
845 | case V4L2_PIX_FMT_YUYV: | ||
846 | case V4L2_PIX_FMT_UYVY: | ||
847 | is_yuv = 1; | ||
848 | break; | ||
849 | case V4L2_PIX_FMT_RGB565: | ||
850 | case V4L2_PIX_FMT_RGB565X: | ||
851 | r >>= 3; | ||
852 | g >>= 2; | ||
853 | b >>= 3; | ||
854 | break; | ||
855 | case V4L2_PIX_FMT_RGB555: | ||
856 | case V4L2_PIX_FMT_RGB555X: | ||
857 | r >>= 3; | ||
858 | g >>= 3; | ||
859 | b >>= 3; | ||
860 | break; | ||
861 | } | ||
862 | |||
863 | if (is_yuv) { | ||
864 | fh->bars[k][0] = TO_Y(r, g, b); /* Luma */ | ||
865 | fh->bars[k][1] = TO_U(r, g, b); /* Cb */ | ||
866 | fh->bars[k][2] = TO_V(r, g, b); /* Cr */ | ||
867 | } else { | ||
868 | fh->bars[k][0] = r; | ||
869 | fh->bars[k][1] = g; | ||
870 | fh->bars[k][2] = b; | ||
871 | } | ||
872 | } | ||
873 | |||
736 | ret = 0; | 874 | ret = 0; |
737 | out: | 875 | out: |
738 | mutex_unlock(&q->vb_lock); | 876 | mutex_unlock(&q->vb_lock); |
@@ -886,8 +1024,6 @@ static int vidioc_s_ctrl(struct file *file, void *priv, | |||
886 | File operations for the device | 1024 | File operations for the device |
887 | ------------------------------------------------------------------*/ | 1025 | ------------------------------------------------------------------*/ |
888 | 1026 | ||
889 | #define line_buf_size(norm) (norm_maxw(norm)*(format.depth+7)/8) | ||
890 | |||
891 | static int vivi_open(struct inode *inode, struct file *file) | 1027 | static int vivi_open(struct inode *inode, struct file *file) |
892 | { | 1028 | { |
893 | int minor = iminor(inode); | 1029 | int minor = iminor(inode); |
@@ -936,7 +1072,7 @@ unlock: | |||
936 | fh->dev = dev; | 1072 | fh->dev = dev; |
937 | 1073 | ||
938 | fh->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 1074 | fh->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
939 | fh->fmt = &format; | 1075 | fh->fmt = &formats[0]; |
940 | fh->width = 640; | 1076 | fh->width = 640; |
941 | fh->height = 480; | 1077 | fh->height = 480; |
942 | 1078 | ||
diff --git a/drivers/media/video/vpx3220.c b/drivers/media/video/vpx3220.c index 45be9ec8edc4..67aa0db4b81a 100644 --- a/drivers/media/video/vpx3220.c +++ b/drivers/media/video/vpx3220.c | |||
@@ -22,32 +22,21 @@ | |||
22 | #include <linux/init.h> | 22 | #include <linux/init.h> |
23 | #include <linux/delay.h> | 23 | #include <linux/delay.h> |
24 | #include <linux/types.h> | 24 | #include <linux/types.h> |
25 | #include <linux/slab.h> | ||
26 | |||
27 | #include <asm/io.h> | ||
28 | #include <asm/uaccess.h> | 25 | #include <asm/uaccess.h> |
29 | |||
30 | #include <linux/i2c.h> | 26 | #include <linux/i2c.h> |
31 | |||
32 | #define I2C_NAME(x) (x)->name | ||
33 | |||
34 | #include <linux/videodev.h> | ||
35 | #include <media/v4l2-common.h> | 27 | #include <media/v4l2-common.h> |
28 | #include <media/v4l2-i2c-drv-legacy.h> | ||
29 | #include <linux/videodev.h> | ||
36 | #include <linux/video_decoder.h> | 30 | #include <linux/video_decoder.h> |
37 | 31 | ||
38 | #define I2C_VPX3220 0x86 | 32 | MODULE_DESCRIPTION("vpx3220a/vpx3216b/vpx3214c video decoder driver"); |
39 | #define VPX3220_DEBUG KERN_DEBUG "vpx3220: " | 33 | MODULE_AUTHOR("Laurent Pinchart"); |
34 | MODULE_LICENSE("GPL"); | ||
40 | 35 | ||
41 | static int debug; | 36 | static int debug; |
42 | module_param(debug, int, 0); | 37 | module_param(debug, int, 0); |
43 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); | 38 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); |
44 | 39 | ||
45 | #define dprintk(num, format, args...) \ | ||
46 | do { \ | ||
47 | if (debug >= num) \ | ||
48 | printk(format, ##args); \ | ||
49 | } while (0) | ||
50 | |||
51 | #define VPX_TIMEOUT_COUNT 10 | 40 | #define VPX_TIMEOUT_COUNT 10 |
52 | 41 | ||
53 | /* ----------------------------------------------------------------------- */ | 42 | /* ----------------------------------------------------------------------- */ |
@@ -67,10 +56,8 @@ struct vpx3220 { | |||
67 | static char *inputs[] = { "internal", "composite", "svideo" }; | 56 | static char *inputs[] = { "internal", "composite", "svideo" }; |
68 | 57 | ||
69 | /* ----------------------------------------------------------------------- */ | 58 | /* ----------------------------------------------------------------------- */ |
70 | static inline int | 59 | |
71 | vpx3220_write (struct i2c_client *client, | 60 | static inline int vpx3220_write(struct i2c_client *client, u8 reg, u8 value) |
72 | u8 reg, | ||
73 | u8 value) | ||
74 | { | 61 | { |
75 | struct vpx3220 *decoder = i2c_get_clientdata(client); | 62 | struct vpx3220 *decoder = i2c_get_clientdata(client); |
76 | 63 | ||
@@ -78,15 +65,12 @@ vpx3220_write (struct i2c_client *client, | |||
78 | return i2c_smbus_write_byte_data(client, reg, value); | 65 | return i2c_smbus_write_byte_data(client, reg, value); |
79 | } | 66 | } |
80 | 67 | ||
81 | static inline int | 68 | static inline int vpx3220_read(struct i2c_client *client, u8 reg) |
82 | vpx3220_read (struct i2c_client *client, | ||
83 | u8 reg) | ||
84 | { | 69 | { |
85 | return i2c_smbus_read_byte_data(client, reg); | 70 | return i2c_smbus_read_byte_data(client, reg); |
86 | } | 71 | } |
87 | 72 | ||
88 | static int | 73 | static int vpx3220_fp_status(struct i2c_client *client) |
89 | vpx3220_fp_status (struct i2c_client *client) | ||
90 | { | 74 | { |
91 | unsigned char status; | 75 | unsigned char status; |
92 | unsigned int i; | 76 | unsigned int i; |
@@ -106,14 +90,11 @@ vpx3220_fp_status (struct i2c_client *client) | |||
106 | return -1; | 90 | return -1; |
107 | } | 91 | } |
108 | 92 | ||
109 | static int | 93 | static int vpx3220_fp_write(struct i2c_client *client, u8 fpaddr, u16 data) |
110 | vpx3220_fp_write (struct i2c_client *client, | ||
111 | u8 fpaddr, | ||
112 | u16 data) | ||
113 | { | 94 | { |
114 | /* Write the 16-bit address to the FPWR register */ | 95 | /* Write the 16-bit address to the FPWR register */ |
115 | if (i2c_smbus_write_word_data(client, 0x27, swab16(fpaddr)) == -1) { | 96 | if (i2c_smbus_write_word_data(client, 0x27, swab16(fpaddr)) == -1) { |
116 | dprintk(1, VPX3220_DEBUG "%s: failed\n", __func__); | 97 | v4l_dbg(1, debug, client, "%s: failed\n", __func__); |
117 | return -1; | 98 | return -1; |
118 | } | 99 | } |
119 | 100 | ||
@@ -122,22 +103,20 @@ vpx3220_fp_write (struct i2c_client *client, | |||
122 | 103 | ||
123 | /* Write the 16-bit data to the FPDAT register */ | 104 | /* Write the 16-bit data to the FPDAT register */ |
124 | if (i2c_smbus_write_word_data(client, 0x28, swab16(data)) == -1) { | 105 | if (i2c_smbus_write_word_data(client, 0x28, swab16(data)) == -1) { |
125 | dprintk(1, VPX3220_DEBUG "%s: failed\n", __func__); | 106 | v4l_dbg(1, debug, client, "%s: failed\n", __func__); |
126 | return -1; | 107 | return -1; |
127 | } | 108 | } |
128 | 109 | ||
129 | return 0; | 110 | return 0; |
130 | } | 111 | } |
131 | 112 | ||
132 | static u16 | 113 | static u16 vpx3220_fp_read(struct i2c_client *client, u16 fpaddr) |
133 | vpx3220_fp_read (struct i2c_client *client, | ||
134 | u16 fpaddr) | ||
135 | { | 114 | { |
136 | s16 data; | 115 | s16 data; |
137 | 116 | ||
138 | /* Write the 16-bit address to the FPRD register */ | 117 | /* Write the 16-bit address to the FPRD register */ |
139 | if (i2c_smbus_write_word_data(client, 0x26, swab16(fpaddr)) == -1) { | 118 | if (i2c_smbus_write_word_data(client, 0x26, swab16(fpaddr)) == -1) { |
140 | dprintk(1, VPX3220_DEBUG "%s: failed\n", __func__); | 119 | v4l_dbg(1, debug, client, "%s: failed\n", __func__); |
141 | return -1; | 120 | return -1; |
142 | } | 121 | } |
143 | 122 | ||
@@ -147,25 +126,22 @@ vpx3220_fp_read (struct i2c_client *client, | |||
147 | /* Read the 16-bit data from the FPDAT register */ | 126 | /* Read the 16-bit data from the FPDAT register */ |
148 | data = i2c_smbus_read_word_data(client, 0x28); | 127 | data = i2c_smbus_read_word_data(client, 0x28); |
149 | if (data == -1) { | 128 | if (data == -1) { |
150 | dprintk(1, VPX3220_DEBUG "%s: failed\n", __func__); | 129 | v4l_dbg(1, debug, client, "%s: failed\n", __func__); |
151 | return -1; | 130 | return -1; |
152 | } | 131 | } |
153 | 132 | ||
154 | return swab16(data); | 133 | return swab16(data); |
155 | } | 134 | } |
156 | 135 | ||
157 | static int | 136 | static int vpx3220_write_block(struct i2c_client *client, const u8 *data, unsigned int len) |
158 | vpx3220_write_block (struct i2c_client *client, | ||
159 | const u8 *data, | ||
160 | unsigned int len) | ||
161 | { | 137 | { |
162 | u8 reg; | 138 | u8 reg; |
163 | int ret = -1; | 139 | int ret = -1; |
164 | 140 | ||
165 | while (len >= 2) { | 141 | while (len >= 2) { |
166 | reg = *data++; | 142 | reg = *data++; |
167 | if ((ret = | 143 | ret = vpx3220_write(client, reg, *data++); |
168 | vpx3220_write(client, reg, *data++)) < 0) | 144 | if (ret < 0) |
169 | break; | 145 | break; |
170 | len -= 2; | 146 | len -= 2; |
171 | } | 147 | } |
@@ -173,10 +149,8 @@ vpx3220_write_block (struct i2c_client *client, | |||
173 | return ret; | 149 | return ret; |
174 | } | 150 | } |
175 | 151 | ||
176 | static int | 152 | static int vpx3220_write_fp_block(struct i2c_client *client, |
177 | vpx3220_write_fp_block (struct i2c_client *client, | 153 | const u16 *data, unsigned int len) |
178 | const u16 *data, | ||
179 | unsigned int len) | ||
180 | { | 154 | { |
181 | u8 reg; | 155 | u8 reg; |
182 | int ret = 0; | 156 | int ret = 0; |
@@ -285,25 +259,20 @@ static const unsigned short init_fp[] = { | |||
285 | 0x4b, 0x298, /* PLL gain */ | 259 | 0x4b, 0x298, /* PLL gain */ |
286 | }; | 260 | }; |
287 | 261 | ||
288 | static void | 262 | static void vpx3220_dump_i2c(struct i2c_client *client) |
289 | vpx3220_dump_i2c (struct i2c_client *client) | ||
290 | { | 263 | { |
291 | int len = sizeof(init_common); | 264 | int len = sizeof(init_common); |
292 | const unsigned char *data = init_common; | 265 | const unsigned char *data = init_common; |
293 | 266 | ||
294 | while (len > 1) { | 267 | while (len > 1) { |
295 | dprintk(1, | 268 | v4l_dbg(1, debug, client, "i2c reg 0x%02x data 0x%02x\n", |
296 | KERN_DEBUG "vpx3216b i2c reg 0x%02x data 0x%02x\n", | ||
297 | *data, vpx3220_read(client, *data)); | 269 | *data, vpx3220_read(client, *data)); |
298 | data += 2; | 270 | data += 2; |
299 | len -= 2; | 271 | len -= 2; |
300 | } | 272 | } |
301 | } | 273 | } |
302 | 274 | ||
303 | static int | 275 | static int vpx3220_command(struct i2c_client *client, unsigned cmd, void *arg) |
304 | vpx3220_command (struct i2c_client *client, | ||
305 | unsigned int cmd, | ||
306 | void *arg) | ||
307 | { | 276 | { |
308 | struct vpx3220 *decoder = i2c_get_clientdata(client); | 277 | struct vpx3220 *decoder = i2c_get_clientdata(client); |
309 | 278 | ||
@@ -315,7 +284,6 @@ vpx3220_command (struct i2c_client *client, | |||
315 | vpx3220_write_fp_block(client, init_fp, | 284 | vpx3220_write_fp_block(client, init_fp, |
316 | sizeof(init_fp) >> 1); | 285 | sizeof(init_fp) >> 1); |
317 | switch (decoder->norm) { | 286 | switch (decoder->norm) { |
318 | |||
319 | case VIDEO_MODE_NTSC: | 287 | case VIDEO_MODE_NTSC: |
320 | vpx3220_write_fp_block(client, init_ntsc, | 288 | vpx3220_write_fp_block(client, init_ntsc, |
321 | sizeof(init_ntsc) >> 1); | 289 | sizeof(init_ntsc) >> 1); |
@@ -334,21 +302,20 @@ vpx3220_command (struct i2c_client *client, | |||
334 | sizeof(init_pal) >> 1); | 302 | sizeof(init_pal) >> 1); |
335 | break; | 303 | break; |
336 | } | 304 | } |
337 | } | ||
338 | break; | 305 | break; |
306 | } | ||
339 | 307 | ||
340 | case DECODER_DUMP: | 308 | case DECODER_DUMP: |
341 | { | 309 | { |
342 | vpx3220_dump_i2c(client); | 310 | vpx3220_dump_i2c(client); |
343 | } | ||
344 | break; | 311 | break; |
312 | } | ||
345 | 313 | ||
346 | case DECODER_GET_CAPABILITIES: | 314 | case DECODER_GET_CAPABILITIES: |
347 | { | 315 | { |
348 | struct video_decoder_capability *cap = arg; | 316 | struct video_decoder_capability *cap = arg; |
349 | 317 | ||
350 | dprintk(1, KERN_DEBUG "%s: DECODER_GET_CAPABILITIES\n", | 318 | v4l_dbg(1, debug, client, "DECODER_GET_CAPABILITIES\n"); |
351 | I2C_NAME(client)); | ||
352 | 319 | ||
353 | cap->flags = VIDEO_DECODER_PAL | | 320 | cap->flags = VIDEO_DECODER_PAL | |
354 | VIDEO_DECODER_NTSC | | 321 | VIDEO_DECODER_NTSC | |
@@ -357,20 +324,18 @@ vpx3220_command (struct i2c_client *client, | |||
357 | VIDEO_DECODER_CCIR; | 324 | VIDEO_DECODER_CCIR; |
358 | cap->inputs = 3; | 325 | cap->inputs = 3; |
359 | cap->outputs = 1; | 326 | cap->outputs = 1; |
360 | } | ||
361 | break; | 327 | break; |
328 | } | ||
362 | 329 | ||
363 | case DECODER_GET_STATUS: | 330 | case DECODER_GET_STATUS: |
364 | { | 331 | { |
365 | int res = 0, status; | 332 | int res = 0, status; |
366 | 333 | ||
367 | dprintk(1, KERN_INFO "%s: DECODER_GET_STATUS\n", | 334 | v4l_dbg(1, debug, client, "DECODER_GET_STATUS\n"); |
368 | I2C_NAME(client)); | ||
369 | 335 | ||
370 | status = vpx3220_fp_read(client, 0x0f3); | 336 | status = vpx3220_fp_read(client, 0x0f3); |
371 | 337 | ||
372 | dprintk(1, KERN_INFO "%s: status: 0x%04x\n", I2C_NAME(client), | 338 | v4l_dbg(1, debug, client, "status: 0x%04x\n", status); |
373 | status); | ||
374 | 339 | ||
375 | if (status < 0) | 340 | if (status < 0) |
376 | return status; | 341 | return status; |
@@ -379,7 +344,6 @@ vpx3220_command (struct i2c_client *client, | |||
379 | res |= DECODER_STATUS_GOOD | DECODER_STATUS_COLOR; | 344 | res |= DECODER_STATUS_GOOD | DECODER_STATUS_COLOR; |
380 | 345 | ||
381 | switch (status & 0x18) { | 346 | switch (status & 0x18) { |
382 | |||
383 | case 0x00: | 347 | case 0x00: |
384 | case 0x10: | 348 | case 0x10: |
385 | case 0x14: | 349 | case 0x14: |
@@ -400,8 +364,8 @@ vpx3220_command (struct i2c_client *client, | |||
400 | } | 364 | } |
401 | 365 | ||
402 | *(int *) arg = res; | 366 | *(int *) arg = res; |
403 | } | ||
404 | break; | 367 | break; |
368 | } | ||
405 | 369 | ||
406 | case DECODER_SET_NORM: | 370 | case DECODER_SET_NORM: |
407 | { | 371 | { |
@@ -413,50 +377,43 @@ vpx3220_command (struct i2c_client *client, | |||
413 | choosen video norm */ | 377 | choosen video norm */ |
414 | temp_input = vpx3220_fp_read(client, 0xf2); | 378 | temp_input = vpx3220_fp_read(client, 0xf2); |
415 | 379 | ||
416 | dprintk(1, KERN_DEBUG "%s: DECODER_SET_NORM %d\n", | 380 | v4l_dbg(1, debug, client, "DECODER_SET_NORM %d\n", *iarg); |
417 | I2C_NAME(client), *iarg); | ||
418 | switch (*iarg) { | 381 | switch (*iarg) { |
419 | |||
420 | case VIDEO_MODE_NTSC: | 382 | case VIDEO_MODE_NTSC: |
421 | vpx3220_write_fp_block(client, init_ntsc, | 383 | vpx3220_write_fp_block(client, init_ntsc, |
422 | sizeof(init_ntsc) >> 1); | 384 | sizeof(init_ntsc) >> 1); |
423 | dprintk(1, KERN_INFO "%s: norm switched to NTSC\n", | 385 | v4l_dbg(1, debug, client, "norm switched to NTSC\n"); |
424 | I2C_NAME(client)); | ||
425 | break; | 386 | break; |
426 | 387 | ||
427 | case VIDEO_MODE_PAL: | 388 | case VIDEO_MODE_PAL: |
428 | vpx3220_write_fp_block(client, init_pal, | 389 | vpx3220_write_fp_block(client, init_pal, |
429 | sizeof(init_pal) >> 1); | 390 | sizeof(init_pal) >> 1); |
430 | dprintk(1, KERN_INFO "%s: norm switched to PAL\n", | 391 | v4l_dbg(1, debug, client, "norm switched to PAL\n"); |
431 | I2C_NAME(client)); | ||
432 | break; | 392 | break; |
433 | 393 | ||
434 | case VIDEO_MODE_SECAM: | 394 | case VIDEO_MODE_SECAM: |
435 | vpx3220_write_fp_block(client, init_secam, | 395 | vpx3220_write_fp_block(client, init_secam, |
436 | sizeof(init_secam) >> 1); | 396 | sizeof(init_secam) >> 1); |
437 | dprintk(1, KERN_INFO "%s: norm switched to SECAM\n", | 397 | v4l_dbg(1, debug, client, "norm switched to SECAM\n"); |
438 | I2C_NAME(client)); | ||
439 | break; | 398 | break; |
440 | 399 | ||
441 | case VIDEO_MODE_AUTO: | 400 | case VIDEO_MODE_AUTO: |
442 | /* FIXME This is only preliminary support */ | 401 | /* FIXME This is only preliminary support */ |
443 | data = vpx3220_fp_read(client, 0xf2) & 0x20; | 402 | data = vpx3220_fp_read(client, 0xf2) & 0x20; |
444 | vpx3220_fp_write(client, 0xf2, 0x00c0 | data); | 403 | vpx3220_fp_write(client, 0xf2, 0x00c0 | data); |
445 | dprintk(1, KERN_INFO "%s: norm switched to Auto\n", | 404 | v4l_dbg(1, debug, client, "norm switched to AUTO\n"); |
446 | I2C_NAME(client)); | ||
447 | break; | 405 | break; |
448 | 406 | ||
449 | default: | 407 | default: |
450 | return -EINVAL; | 408 | return -EINVAL; |
451 | |||
452 | } | 409 | } |
453 | decoder->norm = *iarg; | 410 | decoder->norm = *iarg; |
454 | 411 | ||
455 | /* And here we set the backed up video input again */ | 412 | /* And here we set the backed up video input again */ |
456 | vpx3220_fp_write(client, 0xf2, temp_input | 0x0010); | 413 | vpx3220_fp_write(client, 0xf2, temp_input | 0x0010); |
457 | udelay(10); | 414 | udelay(10); |
458 | } | ||
459 | break; | 415 | break; |
416 | } | ||
460 | 417 | ||
461 | case DECODER_SET_INPUT: | 418 | case DECODER_SET_INPUT: |
462 | { | 419 | { |
@@ -475,8 +432,7 @@ vpx3220_command (struct i2c_client *client, | |||
475 | if (*iarg < 0 || *iarg > 2) | 432 | if (*iarg < 0 || *iarg > 2) |
476 | return -EINVAL; | 433 | return -EINVAL; |
477 | 434 | ||
478 | dprintk(1, KERN_INFO "%s: input switched to %s\n", | 435 | v4l_dbg(1, debug, client, "input switched to %s\n", inputs[*iarg]); |
479 | I2C_NAME(client), inputs[*iarg]); | ||
480 | 436 | ||
481 | vpx3220_write(client, 0x33, input[*iarg][0]); | 437 | vpx3220_write(client, 0x33, input[*iarg][0]); |
482 | 438 | ||
@@ -488,8 +444,8 @@ vpx3220_command (struct i2c_client *client, | |||
488 | data | (input[*iarg][1] << 5) | 0x0010); | 444 | data | (input[*iarg][1] << 5) | 0x0010); |
489 | 445 | ||
490 | udelay(10); | 446 | udelay(10); |
491 | } | ||
492 | break; | 447 | break; |
448 | } | ||
493 | 449 | ||
494 | case DECODER_SET_OUTPUT: | 450 | case DECODER_SET_OUTPUT: |
495 | { | 451 | { |
@@ -499,19 +455,18 @@ vpx3220_command (struct i2c_client *client, | |||
499 | if (*iarg != 0) { | 455 | if (*iarg != 0) { |
500 | return -EINVAL; | 456 | return -EINVAL; |
501 | } | 457 | } |
502 | } | ||
503 | break; | 458 | break; |
459 | } | ||
504 | 460 | ||
505 | case DECODER_ENABLE_OUTPUT: | 461 | case DECODER_ENABLE_OUTPUT: |
506 | { | 462 | { |
507 | int *iarg = arg; | 463 | int *iarg = arg; |
508 | 464 | ||
509 | dprintk(1, KERN_DEBUG "%s: DECODER_ENABLE_OUTPUT %d\n", | 465 | v4l_dbg(1, debug, client, "DECODER_ENABLE_OUTPUT %d\n", *iarg); |
510 | I2C_NAME(client), *iarg); | ||
511 | 466 | ||
512 | vpx3220_write(client, 0xf2, (*iarg ? 0x1b : 0x00)); | 467 | vpx3220_write(client, 0xf2, (*iarg ? 0x1b : 0x00)); |
513 | } | ||
514 | break; | 468 | break; |
469 | } | ||
515 | 470 | ||
516 | case DECODER_SET_PICTURE: | 471 | case DECODER_SET_PICTURE: |
517 | { | 472 | { |
@@ -542,8 +497,8 @@ vpx3220_command (struct i2c_client *client, | |||
542 | vpx3220_fp_write(client, 0x1c, | 497 | vpx3220_fp_write(client, 0x1c, |
543 | ((decoder->hue - 32768) >> 6) & 0xFFF); | 498 | ((decoder->hue - 32768) >> 6) & 0xFFF); |
544 | } | 499 | } |
545 | } | ||
546 | break; | 500 | break; |
501 | } | ||
547 | 502 | ||
548 | default: | 503 | default: |
549 | return -EINVAL; | 504 | return -EINVAL; |
@@ -552,8 +507,7 @@ vpx3220_command (struct i2c_client *client, | |||
552 | return 0; | 507 | return 0; |
553 | } | 508 | } |
554 | 509 | ||
555 | static int | 510 | static int vpx3220_init_client(struct i2c_client *client) |
556 | vpx3220_init_client (struct i2c_client *client) | ||
557 | { | 511 | { |
558 | vpx3220_write_block(client, init_common, sizeof(init_common)); | 512 | vpx3220_write_block(client, init_common, sizeof(init_common)); |
559 | vpx3220_write_fp_block(client, init_fp, sizeof(init_fp) >> 1); | 513 | vpx3220_write_fp_block(client, init_fp, sizeof(init_fp) >> 1); |
@@ -567,115 +521,26 @@ vpx3220_init_client (struct i2c_client *client) | |||
567 | * Client management code | 521 | * Client management code |
568 | */ | 522 | */ |
569 | 523 | ||
570 | /* | 524 | static unsigned short normal_i2c[] = { 0x86 >> 1, 0x8e >> 1, I2C_CLIENT_END }; |
571 | * Generic i2c probe | ||
572 | * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1' | ||
573 | */ | ||
574 | static unsigned short normal_i2c[] = | ||
575 | { I2C_VPX3220 >> 1, (I2C_VPX3220 >> 1) + 4, | ||
576 | I2C_CLIENT_END | ||
577 | }; | ||
578 | |||
579 | static unsigned short ignore = I2C_CLIENT_END; | ||
580 | 525 | ||
581 | static struct i2c_client_address_data addr_data = { | 526 | I2C_CLIENT_INSMOD; |
582 | .normal_i2c = normal_i2c, | ||
583 | .probe = &ignore, | ||
584 | .ignore = &ignore, | ||
585 | }; | ||
586 | |||
587 | static struct i2c_driver vpx3220_i2c_driver; | ||
588 | |||
589 | static int | ||
590 | vpx3220_detach_client (struct i2c_client *client) | ||
591 | { | ||
592 | struct vpx3220 *decoder = i2c_get_clientdata(client); | ||
593 | int err; | ||
594 | |||
595 | err = i2c_detach_client(client); | ||
596 | if (err) { | ||
597 | return err; | ||
598 | } | ||
599 | |||
600 | kfree(decoder); | ||
601 | kfree(client); | ||
602 | |||
603 | return 0; | ||
604 | } | ||
605 | 527 | ||
606 | static int | 528 | static int vpx3220_probe(struct i2c_client *client, |
607 | vpx3220_detect_client (struct i2c_adapter *adapter, | 529 | const struct i2c_device_id *id) |
608 | int address, | ||
609 | int kind) | ||
610 | { | 530 | { |
611 | int err; | ||
612 | struct i2c_client *client; | ||
613 | struct vpx3220 *decoder; | 531 | struct vpx3220 *decoder; |
614 | 532 | const char *name = NULL; | |
615 | dprintk(1, VPX3220_DEBUG "%s\n", __func__); | 533 | u8 ver; |
534 | u16 pn; | ||
616 | 535 | ||
617 | /* Check if the adapter supports the needed features */ | 536 | /* Check if the adapter supports the needed features */ |
618 | if (!i2c_check_functionality | 537 | if (!i2c_check_functionality(client->adapter, |
619 | (adapter, I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA)) | 538 | I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA)) |
620 | return 0; | 539 | return -ENODEV; |
621 | |||
622 | client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); | ||
623 | if (client == NULL) { | ||
624 | return -ENOMEM; | ||
625 | } | ||
626 | |||
627 | client->addr = address; | ||
628 | client->adapter = adapter; | ||
629 | client->driver = &vpx3220_i2c_driver; | ||
630 | |||
631 | /* Check for manufacture ID and part number */ | ||
632 | if (kind < 0) { | ||
633 | u8 id; | ||
634 | u16 pn; | ||
635 | |||
636 | id = vpx3220_read(client, 0x00); | ||
637 | if (id != 0xec) { | ||
638 | dprintk(1, | ||
639 | KERN_INFO | ||
640 | "vpx3220_attach: Wrong manufacturer ID (0x%02x)\n", | ||
641 | id); | ||
642 | kfree(client); | ||
643 | return 0; | ||
644 | } | ||
645 | |||
646 | pn = (vpx3220_read(client, 0x02) << 8) + | ||
647 | vpx3220_read(client, 0x01); | ||
648 | switch (pn) { | ||
649 | case 0x4680: | ||
650 | strlcpy(I2C_NAME(client), "vpx3220a", | ||
651 | sizeof(I2C_NAME(client))); | ||
652 | break; | ||
653 | case 0x4260: | ||
654 | strlcpy(I2C_NAME(client), "vpx3216b", | ||
655 | sizeof(I2C_NAME(client))); | ||
656 | break; | ||
657 | case 0x4280: | ||
658 | strlcpy(I2C_NAME(client), "vpx3214c", | ||
659 | sizeof(I2C_NAME(client))); | ||
660 | break; | ||
661 | default: | ||
662 | dprintk(1, | ||
663 | KERN_INFO | ||
664 | "%s: Wrong part number (0x%04x)\n", | ||
665 | __func__, pn); | ||
666 | kfree(client); | ||
667 | return 0; | ||
668 | } | ||
669 | } else { | ||
670 | strlcpy(I2C_NAME(client), "forced vpx32xx", | ||
671 | sizeof(I2C_NAME(client))); | ||
672 | } | ||
673 | 540 | ||
674 | decoder = kzalloc(sizeof(struct vpx3220), GFP_KERNEL); | 541 | decoder = kzalloc(sizeof(struct vpx3220), GFP_KERNEL); |
675 | if (decoder == NULL) { | 542 | if (decoder == NULL) |
676 | kfree(client); | ||
677 | return -ENOMEM; | 543 | return -ENOMEM; |
678 | } | ||
679 | decoder->norm = VIDEO_MODE_PAL; | 544 | decoder->norm = VIDEO_MODE_PAL; |
680 | decoder->input = 0; | 545 | decoder->input = 0; |
681 | decoder->enable = 1; | 546 | decoder->enable = 1; |
@@ -685,63 +550,52 @@ vpx3220_detect_client (struct i2c_adapter *adapter, | |||
685 | decoder->sat = 32768; | 550 | decoder->sat = 32768; |
686 | i2c_set_clientdata(client, decoder); | 551 | i2c_set_clientdata(client, decoder); |
687 | 552 | ||
688 | err = i2c_attach_client(client); | 553 | ver = i2c_smbus_read_byte_data(client, 0x00); |
689 | if (err) { | 554 | pn = (i2c_smbus_read_byte_data(client, 0x02) << 8) + |
690 | kfree(client); | 555 | i2c_smbus_read_byte_data(client, 0x01); |
691 | kfree(decoder); | 556 | if (ver == 0xec) { |
692 | return err; | 557 | switch (pn) { |
558 | case 0x4680: | ||
559 | name = "vpx3220a"; | ||
560 | break; | ||
561 | case 0x4260: | ||
562 | name = "vpx3216b"; | ||
563 | break; | ||
564 | case 0x4280: | ||
565 | name = "vpx3214c"; | ||
566 | break; | ||
567 | } | ||
693 | } | 568 | } |
694 | 569 | if (name) | |
695 | dprintk(1, KERN_INFO "%s: vpx32xx client found at address 0x%02x\n", | 570 | v4l_info(client, "%s found @ 0x%x (%s)\n", name, |
696 | I2C_NAME(client), client->addr << 1); | 571 | client->addr << 1, client->adapter->name); |
572 | else | ||
573 | v4l_info(client, "chip (%02x:%04x) found @ 0x%x (%s)\n", | ||
574 | ver, pn, client->addr << 1, client->adapter->name); | ||
697 | 575 | ||
698 | vpx3220_init_client(client); | 576 | vpx3220_init_client(client); |
699 | |||
700 | return 0; | 577 | return 0; |
701 | } | 578 | } |
702 | 579 | ||
703 | static int | 580 | static int vpx3220_remove(struct i2c_client *client) |
704 | vpx3220_attach_adapter (struct i2c_adapter *adapter) | ||
705 | { | 581 | { |
706 | int ret; | 582 | kfree(i2c_get_clientdata(client)); |
707 | 583 | return 0; | |
708 | ret = i2c_probe(adapter, &addr_data, &vpx3220_detect_client); | ||
709 | dprintk(1, VPX3220_DEBUG "%s: i2c_probe returned %d\n", | ||
710 | __func__, ret); | ||
711 | return ret; | ||
712 | } | 584 | } |
713 | 585 | ||
714 | /* ----------------------------------------------------------------------- | 586 | static const struct i2c_device_id vpx3220_id[] = { |
715 | * Driver initialization and cleanup code | 587 | { "vpx3220a", 0 }, |
716 | */ | 588 | { "vpx3216b", 0 }, |
717 | 589 | { "vpx3214c", 0 }, | |
718 | static struct i2c_driver vpx3220_i2c_driver = { | 590 | { } |
719 | .driver = { | 591 | }; |
720 | .name = "vpx3220", | 592 | MODULE_DEVICE_TABLE(i2c, vpx3220_id); |
721 | }, | ||
722 | |||
723 | .id = I2C_DRIVERID_VPX3220, | ||
724 | 593 | ||
725 | .attach_adapter = vpx3220_attach_adapter, | 594 | static struct v4l2_i2c_driver_data v4l2_i2c_data = { |
726 | .detach_client = vpx3220_detach_client, | 595 | .name = "vpx3220", |
596 | .driverid = I2C_DRIVERID_VPX3220, | ||
727 | .command = vpx3220_command, | 597 | .command = vpx3220_command, |
598 | .probe = vpx3220_probe, | ||
599 | .remove = vpx3220_remove, | ||
600 | .id_table = vpx3220_id, | ||
728 | }; | 601 | }; |
729 | |||
730 | static int __init | ||
731 | vpx3220_init (void) | ||
732 | { | ||
733 | return i2c_add_driver(&vpx3220_i2c_driver); | ||
734 | } | ||
735 | |||
736 | static void __exit | ||
737 | vpx3220_cleanup (void) | ||
738 | { | ||
739 | i2c_del_driver(&vpx3220_i2c_driver); | ||
740 | } | ||
741 | |||
742 | module_init(vpx3220_init); | ||
743 | module_exit(vpx3220_cleanup); | ||
744 | |||
745 | MODULE_DESCRIPTION("vpx3220a/vpx3216b/vpx3214c video decoder driver"); | ||
746 | MODULE_AUTHOR("Laurent Pinchart"); | ||
747 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/video/zoran/zoran_card.c b/drivers/media/video/zoran/zoran_card.c index 3282be730298..fa5f2f8f518a 100644 --- a/drivers/media/video/zoran/zoran_card.c +++ b/drivers/media/video/zoran/zoran_card.c | |||
@@ -817,6 +817,7 @@ zoran_register_i2c (struct zoran *zr) | |||
817 | memcpy(&zr->i2c_algo, &zoran_i2c_bit_data_template, | 817 | memcpy(&zr->i2c_algo, &zoran_i2c_bit_data_template, |
818 | sizeof(struct i2c_algo_bit_data)); | 818 | sizeof(struct i2c_algo_bit_data)); |
819 | zr->i2c_algo.data = zr; | 819 | zr->i2c_algo.data = zr; |
820 | zr->i2c_adapter.class = I2C_CLASS_TV_ANALOG; | ||
820 | zr->i2c_adapter.id = I2C_HW_B_ZR36067; | 821 | zr->i2c_adapter.id = I2C_HW_B_ZR36067; |
821 | zr->i2c_adapter.client_register = zoran_i2c_client_register; | 822 | zr->i2c_adapter.client_register = zoran_i2c_client_register; |
822 | zr->i2c_adapter.client_unregister = zoran_i2c_client_unregister; | 823 | zr->i2c_adapter.client_unregister = zoran_i2c_client_unregister; |
diff --git a/drivers/media/video/zoran/zoran_driver.c b/drivers/media/video/zoran/zoran_driver.c index 25de7631443e..db11ab9e60da 100644 --- a/drivers/media/video/zoran/zoran_driver.c +++ b/drivers/media/video/zoran/zoran_driver.c | |||
@@ -2996,7 +2996,6 @@ zoran_do_ioctl (struct inode *inode, | |||
2996 | break; | 2996 | break; |
2997 | 2997 | ||
2998 | default: | 2998 | default: |
2999 | dprintk(3, "unsupported\n"); | ||
3000 | dprintk(1, | 2999 | dprintk(1, |
3001 | KERN_ERR | 3000 | KERN_ERR |
3002 | "%s: VIDIOC_S_FMT - unsupported type %d\n", | 3001 | "%s: VIDIOC_S_FMT - unsupported type %d\n", |
diff --git a/fs/Kconfig b/fs/Kconfig index 9e9d70c02a07..d0a1174fb516 100644 --- a/fs/Kconfig +++ b/fs/Kconfig | |||
@@ -160,7 +160,7 @@ config EXT4_FS | |||
160 | filesystem initially. | 160 | filesystem initially. |
161 | 161 | ||
162 | To compile this file system support as a module, choose M here. The | 162 | To compile this file system support as a module, choose M here. The |
163 | module will be called ext4dev. | 163 | module will be called ext4. |
164 | 164 | ||
165 | If unsure, say N. | 165 | If unsure, say N. |
166 | 166 | ||
diff --git a/fs/Makefile b/fs/Makefile index d0c69f57e5bf..2168c902d5ca 100644 --- a/fs/Makefile +++ b/fs/Makefile | |||
@@ -71,7 +71,7 @@ obj-$(CONFIG_DLM) += dlm/ | |||
71 | # Do not add any filesystems before this line | 71 | # Do not add any filesystems before this line |
72 | obj-$(CONFIG_REISERFS_FS) += reiserfs/ | 72 | obj-$(CONFIG_REISERFS_FS) += reiserfs/ |
73 | obj-$(CONFIG_EXT3_FS) += ext3/ # Before ext2 so root fs can be ext3 | 73 | obj-$(CONFIG_EXT3_FS) += ext3/ # Before ext2 so root fs can be ext3 |
74 | obj-$(CONFIG_EXT4_FS) += ext4/ # Before ext2 so root fs can be ext4dev | 74 | obj-$(CONFIG_EXT4_FS) += ext4/ # Before ext2 so root fs can be ext4 |
75 | obj-$(CONFIG_JBD) += jbd/ | 75 | obj-$(CONFIG_JBD) += jbd/ |
76 | obj-$(CONFIG_JBD2) += jbd2/ | 76 | obj-$(CONFIG_JBD2) += jbd2/ |
77 | obj-$(CONFIG_EXT2_FS) += ext2/ | 77 | obj-$(CONFIG_EXT2_FS) += ext2/ |
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index bd2ece228827..b9821be709bd 100644 --- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c | |||
@@ -568,8 +568,16 @@ void ext4_free_blocks(handle_t *handle, struct inode *inode, | |||
568 | 568 | ||
569 | /* this isn't the right place to decide whether block is metadata | 569 | /* this isn't the right place to decide whether block is metadata |
570 | * inode.c/extents.c knows better, but for safety ... */ | 570 | * inode.c/extents.c knows better, but for safety ... */ |
571 | if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode) || | 571 | if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)) |
572 | ext4_should_journal_data(inode)) | 572 | metadata = 1; |
573 | |||
574 | /* We need to make sure we don't reuse | ||
575 | * block released untill the transaction commit. | ||
576 | * writeback mode have weak data consistency so | ||
577 | * don't force data as metadata when freeing block | ||
578 | * for writeback mode. | ||
579 | */ | ||
580 | if (metadata == 0 && !ext4_should_writeback_data(inode)) | ||
573 | metadata = 1; | 581 | metadata = 1; |
574 | 582 | ||
575 | sb = inode->i_sb; | 583 | sb = inode->i_sb; |
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 6690a41cdd9f..4880cc3e6727 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h | |||
@@ -511,7 +511,6 @@ do { \ | |||
511 | /* | 511 | /* |
512 | * Mount flags | 512 | * Mount flags |
513 | */ | 513 | */ |
514 | #define EXT4_MOUNT_CHECK 0x00001 /* Do mount-time checks */ | ||
515 | #define EXT4_MOUNT_OLDALLOC 0x00002 /* Don't use the new Orlov allocator */ | 514 | #define EXT4_MOUNT_OLDALLOC 0x00002 /* Don't use the new Orlov allocator */ |
516 | #define EXT4_MOUNT_GRPID 0x00004 /* Create files with directory's group */ | 515 | #define EXT4_MOUNT_GRPID 0x00004 /* Create files with directory's group */ |
517 | #define EXT4_MOUNT_DEBUG 0x00008 /* Some debugging messages */ | 516 | #define EXT4_MOUNT_DEBUG 0x00008 /* Some debugging messages */ |
diff --git a/fs/ext4/ext4_sb.h b/fs/ext4/ext4_sb.h index 6a0b40d43264..445fde603df8 100644 --- a/fs/ext4/ext4_sb.h +++ b/fs/ext4/ext4_sb.h | |||
@@ -99,9 +99,6 @@ struct ext4_sb_info { | |||
99 | struct inode *s_buddy_cache; | 99 | struct inode *s_buddy_cache; |
100 | long s_blocks_reserved; | 100 | long s_blocks_reserved; |
101 | spinlock_t s_reserve_lock; | 101 | spinlock_t s_reserve_lock; |
102 | struct list_head s_active_transaction; | ||
103 | struct list_head s_closed_transaction; | ||
104 | struct list_head s_committed_transaction; | ||
105 | spinlock_t s_md_lock; | 102 | spinlock_t s_md_lock; |
106 | tid_t s_last_transaction; | 103 | tid_t s_last_transaction; |
107 | unsigned short *s_mb_offsets, *s_mb_maxs; | 104 | unsigned short *s_mb_offsets, *s_mb_maxs; |
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 9b4ec9decfd1..8dbf6953845b 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -1648,6 +1648,7 @@ static int mpage_da_submit_io(struct mpage_da_data *mpd) | |||
1648 | int ret = 0, err, nr_pages, i; | 1648 | int ret = 0, err, nr_pages, i; |
1649 | unsigned long index, end; | 1649 | unsigned long index, end; |
1650 | struct pagevec pvec; | 1650 | struct pagevec pvec; |
1651 | long pages_skipped; | ||
1651 | 1652 | ||
1652 | BUG_ON(mpd->next_page <= mpd->first_page); | 1653 | BUG_ON(mpd->next_page <= mpd->first_page); |
1653 | pagevec_init(&pvec, 0); | 1654 | pagevec_init(&pvec, 0); |
@@ -1655,20 +1656,30 @@ static int mpage_da_submit_io(struct mpage_da_data *mpd) | |||
1655 | end = mpd->next_page - 1; | 1656 | end = mpd->next_page - 1; |
1656 | 1657 | ||
1657 | while (index <= end) { | 1658 | while (index <= end) { |
1658 | /* XXX: optimize tail */ | 1659 | /* |
1659 | nr_pages = pagevec_lookup(&pvec, mapping, index, PAGEVEC_SIZE); | 1660 | * We can use PAGECACHE_TAG_DIRTY lookup here because |
1661 | * even though we have cleared the dirty flag on the page | ||
1662 | * We still keep the page in the radix tree with tag | ||
1663 | * PAGECACHE_TAG_DIRTY. See clear_page_dirty_for_io. | ||
1664 | * The PAGECACHE_TAG_DIRTY is cleared in set_page_writeback | ||
1665 | * which is called via the below writepage callback. | ||
1666 | */ | ||
1667 | nr_pages = pagevec_lookup_tag(&pvec, mapping, &index, | ||
1668 | PAGECACHE_TAG_DIRTY, | ||
1669 | min(end - index, | ||
1670 | (pgoff_t)PAGEVEC_SIZE-1) + 1); | ||
1660 | if (nr_pages == 0) | 1671 | if (nr_pages == 0) |
1661 | break; | 1672 | break; |
1662 | for (i = 0; i < nr_pages; i++) { | 1673 | for (i = 0; i < nr_pages; i++) { |
1663 | struct page *page = pvec.pages[i]; | 1674 | struct page *page = pvec.pages[i]; |
1664 | 1675 | ||
1665 | index = page->index; | 1676 | pages_skipped = mpd->wbc->pages_skipped; |
1666 | if (index > end) | ||
1667 | break; | ||
1668 | index++; | ||
1669 | |||
1670 | err = mapping->a_ops->writepage(page, mpd->wbc); | 1677 | err = mapping->a_ops->writepage(page, mpd->wbc); |
1671 | if (!err) | 1678 | if (!err && (pages_skipped == mpd->wbc->pages_skipped)) |
1679 | /* | ||
1680 | * have successfully written the page | ||
1681 | * without skipping the same | ||
1682 | */ | ||
1672 | mpd->pages_written++; | 1683 | mpd->pages_written++; |
1673 | /* | 1684 | /* |
1674 | * In error case, we have to continue because | 1685 | * In error case, we have to continue because |
@@ -2104,7 +2115,6 @@ static int mpage_da_writepages(struct address_space *mapping, | |||
2104 | struct writeback_control *wbc, | 2115 | struct writeback_control *wbc, |
2105 | struct mpage_da_data *mpd) | 2116 | struct mpage_da_data *mpd) |
2106 | { | 2117 | { |
2107 | long to_write; | ||
2108 | int ret; | 2118 | int ret; |
2109 | 2119 | ||
2110 | if (!mpd->get_block) | 2120 | if (!mpd->get_block) |
@@ -2119,19 +2129,18 @@ static int mpage_da_writepages(struct address_space *mapping, | |||
2119 | mpd->pages_written = 0; | 2129 | mpd->pages_written = 0; |
2120 | mpd->retval = 0; | 2130 | mpd->retval = 0; |
2121 | 2131 | ||
2122 | to_write = wbc->nr_to_write; | ||
2123 | |||
2124 | ret = write_cache_pages(mapping, wbc, __mpage_da_writepage, mpd); | 2132 | ret = write_cache_pages(mapping, wbc, __mpage_da_writepage, mpd); |
2125 | |||
2126 | /* | 2133 | /* |
2127 | * Handle last extent of pages | 2134 | * Handle last extent of pages |
2128 | */ | 2135 | */ |
2129 | if (!mpd->io_done && mpd->next_page != mpd->first_page) { | 2136 | if (!mpd->io_done && mpd->next_page != mpd->first_page) { |
2130 | if (mpage_da_map_blocks(mpd) == 0) | 2137 | if (mpage_da_map_blocks(mpd) == 0) |
2131 | mpage_da_submit_io(mpd); | 2138 | mpage_da_submit_io(mpd); |
2132 | } | ||
2133 | 2139 | ||
2134 | wbc->nr_to_write = to_write - mpd->pages_written; | 2140 | mpd->io_done = 1; |
2141 | ret = MPAGE_DA_EXTENT_TAIL; | ||
2142 | } | ||
2143 | wbc->nr_to_write -= mpd->pages_written; | ||
2135 | return ret; | 2144 | return ret; |
2136 | } | 2145 | } |
2137 | 2146 | ||
@@ -2360,12 +2369,14 @@ static int ext4_da_writepages_trans_blocks(struct inode *inode) | |||
2360 | static int ext4_da_writepages(struct address_space *mapping, | 2369 | static int ext4_da_writepages(struct address_space *mapping, |
2361 | struct writeback_control *wbc) | 2370 | struct writeback_control *wbc) |
2362 | { | 2371 | { |
2372 | pgoff_t index; | ||
2373 | int range_whole = 0; | ||
2363 | handle_t *handle = NULL; | 2374 | handle_t *handle = NULL; |
2364 | loff_t range_start = 0; | ||
2365 | struct mpage_da_data mpd; | 2375 | struct mpage_da_data mpd; |
2366 | struct inode *inode = mapping->host; | 2376 | struct inode *inode = mapping->host; |
2377 | int no_nrwrite_index_update; | ||
2378 | long pages_written = 0, pages_skipped; | ||
2367 | int needed_blocks, ret = 0, nr_to_writebump = 0; | 2379 | int needed_blocks, ret = 0, nr_to_writebump = 0; |
2368 | long to_write, pages_skipped = 0; | ||
2369 | struct ext4_sb_info *sbi = EXT4_SB(mapping->host->i_sb); | 2380 | struct ext4_sb_info *sbi = EXT4_SB(mapping->host->i_sb); |
2370 | 2381 | ||
2371 | /* | 2382 | /* |
@@ -2385,23 +2396,26 @@ static int ext4_da_writepages(struct address_space *mapping, | |||
2385 | nr_to_writebump = sbi->s_mb_stream_request - wbc->nr_to_write; | 2396 | nr_to_writebump = sbi->s_mb_stream_request - wbc->nr_to_write; |
2386 | wbc->nr_to_write = sbi->s_mb_stream_request; | 2397 | wbc->nr_to_write = sbi->s_mb_stream_request; |
2387 | } | 2398 | } |
2399 | if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX) | ||
2400 | range_whole = 1; | ||
2388 | 2401 | ||
2389 | if (!wbc->range_cyclic) | 2402 | if (wbc->range_cyclic) |
2390 | /* | 2403 | index = mapping->writeback_index; |
2391 | * If range_cyclic is not set force range_cont | 2404 | else |
2392 | * and save the old writeback_index | 2405 | index = wbc->range_start >> PAGE_CACHE_SHIFT; |
2393 | */ | ||
2394 | wbc->range_cont = 1; | ||
2395 | |||
2396 | range_start = wbc->range_start; | ||
2397 | pages_skipped = wbc->pages_skipped; | ||
2398 | 2406 | ||
2399 | mpd.wbc = wbc; | 2407 | mpd.wbc = wbc; |
2400 | mpd.inode = mapping->host; | 2408 | mpd.inode = mapping->host; |
2401 | 2409 | ||
2402 | restart_loop: | 2410 | /* |
2403 | to_write = wbc->nr_to_write; | 2411 | * we don't want write_cache_pages to update |
2404 | while (!ret && to_write > 0) { | 2412 | * nr_to_write and writeback_index |
2413 | */ | ||
2414 | no_nrwrite_index_update = wbc->no_nrwrite_index_update; | ||
2415 | wbc->no_nrwrite_index_update = 1; | ||
2416 | pages_skipped = wbc->pages_skipped; | ||
2417 | |||
2418 | while (!ret && wbc->nr_to_write > 0) { | ||
2405 | 2419 | ||
2406 | /* | 2420 | /* |
2407 | * we insert one extent at a time. So we need | 2421 | * we insert one extent at a time. So we need |
@@ -2422,48 +2436,53 @@ restart_loop: | |||
2422 | dump_stack(); | 2436 | dump_stack(); |
2423 | goto out_writepages; | 2437 | goto out_writepages; |
2424 | } | 2438 | } |
2425 | to_write -= wbc->nr_to_write; | ||
2426 | |||
2427 | mpd.get_block = ext4_da_get_block_write; | 2439 | mpd.get_block = ext4_da_get_block_write; |
2428 | ret = mpage_da_writepages(mapping, wbc, &mpd); | 2440 | ret = mpage_da_writepages(mapping, wbc, &mpd); |
2429 | 2441 | ||
2430 | ext4_journal_stop(handle); | 2442 | ext4_journal_stop(handle); |
2431 | 2443 | ||
2432 | if (mpd.retval == -ENOSPC) | 2444 | if (mpd.retval == -ENOSPC) { |
2445 | /* commit the transaction which would | ||
2446 | * free blocks released in the transaction | ||
2447 | * and try again | ||
2448 | */ | ||
2433 | jbd2_journal_force_commit_nested(sbi->s_journal); | 2449 | jbd2_journal_force_commit_nested(sbi->s_journal); |
2434 | 2450 | wbc->pages_skipped = pages_skipped; | |
2435 | /* reset the retry count */ | 2451 | ret = 0; |
2436 | if (ret == MPAGE_DA_EXTENT_TAIL) { | 2452 | } else if (ret == MPAGE_DA_EXTENT_TAIL) { |
2437 | /* | 2453 | /* |
2438 | * got one extent now try with | 2454 | * got one extent now try with |
2439 | * rest of the pages | 2455 | * rest of the pages |
2440 | */ | 2456 | */ |
2441 | to_write += wbc->nr_to_write; | 2457 | pages_written += mpd.pages_written; |
2458 | wbc->pages_skipped = pages_skipped; | ||
2442 | ret = 0; | 2459 | ret = 0; |
2443 | } else if (wbc->nr_to_write) { | 2460 | } else if (wbc->nr_to_write) |
2444 | /* | 2461 | /* |
2445 | * There is no more writeout needed | 2462 | * There is no more writeout needed |
2446 | * or we requested for a noblocking writeout | 2463 | * or we requested for a noblocking writeout |
2447 | * and we found the device congested | 2464 | * and we found the device congested |
2448 | */ | 2465 | */ |
2449 | to_write += wbc->nr_to_write; | ||
2450 | break; | 2466 | break; |
2451 | } | ||
2452 | wbc->nr_to_write = to_write; | ||
2453 | } | ||
2454 | |||
2455 | if (wbc->range_cont && (pages_skipped != wbc->pages_skipped)) { | ||
2456 | /* We skipped pages in this loop */ | ||
2457 | wbc->range_start = range_start; | ||
2458 | wbc->nr_to_write = to_write + | ||
2459 | wbc->pages_skipped - pages_skipped; | ||
2460 | wbc->pages_skipped = pages_skipped; | ||
2461 | goto restart_loop; | ||
2462 | } | 2467 | } |
2468 | if (pages_skipped != wbc->pages_skipped) | ||
2469 | printk(KERN_EMERG "This should not happen leaving %s " | ||
2470 | "with nr_to_write = %ld ret = %d\n", | ||
2471 | __func__, wbc->nr_to_write, ret); | ||
2472 | |||
2473 | /* Update index */ | ||
2474 | index += pages_written; | ||
2475 | if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0)) | ||
2476 | /* | ||
2477 | * set the writeback_index so that range_cyclic | ||
2478 | * mode will write it back later | ||
2479 | */ | ||
2480 | mapping->writeback_index = index; | ||
2463 | 2481 | ||
2464 | out_writepages: | 2482 | out_writepages: |
2465 | wbc->nr_to_write = to_write - nr_to_writebump; | 2483 | if (!no_nrwrite_index_update) |
2466 | wbc->range_start = range_start; | 2484 | wbc->no_nrwrite_index_update = 0; |
2485 | wbc->nr_to_write -= nr_to_writebump; | ||
2467 | return ret; | 2486 | return ret; |
2468 | } | 2487 | } |
2469 | 2488 | ||
@@ -4175,7 +4194,6 @@ static int ext4_inode_blocks_set(handle_t *handle, | |||
4175 | struct inode *inode = &(ei->vfs_inode); | 4194 | struct inode *inode = &(ei->vfs_inode); |
4176 | u64 i_blocks = inode->i_blocks; | 4195 | u64 i_blocks = inode->i_blocks; |
4177 | struct super_block *sb = inode->i_sb; | 4196 | struct super_block *sb = inode->i_sb; |
4178 | int err = 0; | ||
4179 | 4197 | ||
4180 | if (i_blocks <= ~0U) { | 4198 | if (i_blocks <= ~0U) { |
4181 | /* | 4199 | /* |
@@ -4185,36 +4203,27 @@ static int ext4_inode_blocks_set(handle_t *handle, | |||
4185 | raw_inode->i_blocks_lo = cpu_to_le32(i_blocks); | 4203 | raw_inode->i_blocks_lo = cpu_to_le32(i_blocks); |
4186 | raw_inode->i_blocks_high = 0; | 4204 | raw_inode->i_blocks_high = 0; |
4187 | ei->i_flags &= ~EXT4_HUGE_FILE_FL; | 4205 | ei->i_flags &= ~EXT4_HUGE_FILE_FL; |
4188 | } else if (i_blocks <= 0xffffffffffffULL) { | 4206 | return 0; |
4207 | } | ||
4208 | if (!EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_HUGE_FILE)) | ||
4209 | return -EFBIG; | ||
4210 | |||
4211 | if (i_blocks <= 0xffffffffffffULL) { | ||
4189 | /* | 4212 | /* |
4190 | * i_blocks can be represented in a 48 bit variable | 4213 | * i_blocks can be represented in a 48 bit variable |
4191 | * as multiple of 512 bytes | 4214 | * as multiple of 512 bytes |
4192 | */ | 4215 | */ |
4193 | err = ext4_update_rocompat_feature(handle, sb, | ||
4194 | EXT4_FEATURE_RO_COMPAT_HUGE_FILE); | ||
4195 | if (err) | ||
4196 | goto err_out; | ||
4197 | /* i_block is stored in the split 48 bit fields */ | ||
4198 | raw_inode->i_blocks_lo = cpu_to_le32(i_blocks); | 4216 | raw_inode->i_blocks_lo = cpu_to_le32(i_blocks); |
4199 | raw_inode->i_blocks_high = cpu_to_le16(i_blocks >> 32); | 4217 | raw_inode->i_blocks_high = cpu_to_le16(i_blocks >> 32); |
4200 | ei->i_flags &= ~EXT4_HUGE_FILE_FL; | 4218 | ei->i_flags &= ~EXT4_HUGE_FILE_FL; |
4201 | } else { | 4219 | } else { |
4202 | /* | ||
4203 | * i_blocks should be represented in a 48 bit variable | ||
4204 | * as multiple of file system block size | ||
4205 | */ | ||
4206 | err = ext4_update_rocompat_feature(handle, sb, | ||
4207 | EXT4_FEATURE_RO_COMPAT_HUGE_FILE); | ||
4208 | if (err) | ||
4209 | goto err_out; | ||
4210 | ei->i_flags |= EXT4_HUGE_FILE_FL; | 4220 | ei->i_flags |= EXT4_HUGE_FILE_FL; |
4211 | /* i_block is stored in file system block size */ | 4221 | /* i_block is stored in file system block size */ |
4212 | i_blocks = i_blocks >> (inode->i_blkbits - 9); | 4222 | i_blocks = i_blocks >> (inode->i_blkbits - 9); |
4213 | raw_inode->i_blocks_lo = cpu_to_le32(i_blocks); | 4223 | raw_inode->i_blocks_lo = cpu_to_le32(i_blocks); |
4214 | raw_inode->i_blocks_high = cpu_to_le16(i_blocks >> 32); | 4224 | raw_inode->i_blocks_high = cpu_to_le16(i_blocks >> 32); |
4215 | } | 4225 | } |
4216 | err_out: | 4226 | return 0; |
4217 | return err; | ||
4218 | } | 4227 | } |
4219 | 4228 | ||
4220 | /* | 4229 | /* |
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index b580714f0d85..dfe17a134052 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c | |||
@@ -2300,6 +2300,7 @@ int ext4_mb_add_groupinfo(struct super_block *sb, ext4_group_t group, | |||
2300 | } | 2300 | } |
2301 | 2301 | ||
2302 | INIT_LIST_HEAD(&meta_group_info[i]->bb_prealloc_list); | 2302 | INIT_LIST_HEAD(&meta_group_info[i]->bb_prealloc_list); |
2303 | meta_group_info[i]->bb_free_root.rb_node = NULL;; | ||
2303 | 2304 | ||
2304 | #ifdef DOUBLE_CHECK | 2305 | #ifdef DOUBLE_CHECK |
2305 | { | 2306 | { |
@@ -2522,9 +2523,6 @@ int ext4_mb_init(struct super_block *sb, int needs_recovery) | |||
2522 | } | 2523 | } |
2523 | 2524 | ||
2524 | spin_lock_init(&sbi->s_md_lock); | 2525 | spin_lock_init(&sbi->s_md_lock); |
2525 | INIT_LIST_HEAD(&sbi->s_active_transaction); | ||
2526 | INIT_LIST_HEAD(&sbi->s_closed_transaction); | ||
2527 | INIT_LIST_HEAD(&sbi->s_committed_transaction); | ||
2528 | spin_lock_init(&sbi->s_bal_lock); | 2526 | spin_lock_init(&sbi->s_bal_lock); |
2529 | 2527 | ||
2530 | sbi->s_mb_max_to_scan = MB_DEFAULT_MAX_TO_SCAN; | 2528 | sbi->s_mb_max_to_scan = MB_DEFAULT_MAX_TO_SCAN; |
@@ -2553,6 +2551,8 @@ int ext4_mb_init(struct super_block *sb, int needs_recovery) | |||
2553 | ext4_mb_init_per_dev_proc(sb); | 2551 | ext4_mb_init_per_dev_proc(sb); |
2554 | ext4_mb_history_init(sb); | 2552 | ext4_mb_history_init(sb); |
2555 | 2553 | ||
2554 | sbi->s_journal->j_commit_callback = release_blocks_on_commit; | ||
2555 | |||
2556 | printk(KERN_INFO "EXT4-fs: mballoc enabled\n"); | 2556 | printk(KERN_INFO "EXT4-fs: mballoc enabled\n"); |
2557 | return 0; | 2557 | return 0; |
2558 | } | 2558 | } |
@@ -2568,7 +2568,7 @@ static void ext4_mb_cleanup_pa(struct ext4_group_info *grp) | |||
2568 | pa = list_entry(cur, struct ext4_prealloc_space, pa_group_list); | 2568 | pa = list_entry(cur, struct ext4_prealloc_space, pa_group_list); |
2569 | list_del(&pa->pa_group_list); | 2569 | list_del(&pa->pa_group_list); |
2570 | count++; | 2570 | count++; |
2571 | kfree(pa); | 2571 | kmem_cache_free(ext4_pspace_cachep, pa); |
2572 | } | 2572 | } |
2573 | if (count) | 2573 | if (count) |
2574 | mb_debug("mballoc: %u PAs left\n", count); | 2574 | mb_debug("mballoc: %u PAs left\n", count); |
@@ -2582,15 +2582,6 @@ int ext4_mb_release(struct super_block *sb) | |||
2582 | struct ext4_group_info *grinfo; | 2582 | struct ext4_group_info *grinfo; |
2583 | struct ext4_sb_info *sbi = EXT4_SB(sb); | 2583 | struct ext4_sb_info *sbi = EXT4_SB(sb); |
2584 | 2584 | ||
2585 | /* release freed, non-committed blocks */ | ||
2586 | spin_lock(&sbi->s_md_lock); | ||
2587 | list_splice_init(&sbi->s_closed_transaction, | ||
2588 | &sbi->s_committed_transaction); | ||
2589 | list_splice_init(&sbi->s_active_transaction, | ||
2590 | &sbi->s_committed_transaction); | ||
2591 | spin_unlock(&sbi->s_md_lock); | ||
2592 | ext4_mb_free_committed_blocks(sb); | ||
2593 | |||
2594 | if (sbi->s_group_info) { | 2585 | if (sbi->s_group_info) { |
2595 | for (i = 0; i < sbi->s_groups_count; i++) { | 2586 | for (i = 0; i < sbi->s_groups_count; i++) { |
2596 | grinfo = ext4_get_group_info(sb, i); | 2587 | grinfo = ext4_get_group_info(sb, i); |
@@ -2644,61 +2635,57 @@ int ext4_mb_release(struct super_block *sb) | |||
2644 | return 0; | 2635 | return 0; |
2645 | } | 2636 | } |
2646 | 2637 | ||
2647 | static noinline_for_stack void | 2638 | /* |
2648 | ext4_mb_free_committed_blocks(struct super_block *sb) | 2639 | * This function is called by the jbd2 layer once the commit has finished, |
2640 | * so we know we can free the blocks that were released with that commit. | ||
2641 | */ | ||
2642 | static void release_blocks_on_commit(journal_t *journal, transaction_t *txn) | ||
2649 | { | 2643 | { |
2650 | struct ext4_sb_info *sbi = EXT4_SB(sb); | 2644 | struct super_block *sb = journal->j_private; |
2651 | int err; | ||
2652 | int i; | ||
2653 | int count = 0; | ||
2654 | int count2 = 0; | ||
2655 | struct ext4_free_metadata *md; | ||
2656 | struct ext4_buddy e4b; | 2645 | struct ext4_buddy e4b; |
2646 | struct ext4_group_info *db; | ||
2647 | int err, count = 0, count2 = 0; | ||
2648 | struct ext4_free_data *entry; | ||
2649 | ext4_fsblk_t discard_block; | ||
2650 | struct list_head *l, *ltmp; | ||
2657 | 2651 | ||
2658 | if (list_empty(&sbi->s_committed_transaction)) | 2652 | list_for_each_safe(l, ltmp, &txn->t_private_list) { |
2659 | return; | 2653 | entry = list_entry(l, struct ext4_free_data, list); |
2660 | |||
2661 | /* there is committed blocks to be freed yet */ | ||
2662 | do { | ||
2663 | /* get next array of blocks */ | ||
2664 | md = NULL; | ||
2665 | spin_lock(&sbi->s_md_lock); | ||
2666 | if (!list_empty(&sbi->s_committed_transaction)) { | ||
2667 | md = list_entry(sbi->s_committed_transaction.next, | ||
2668 | struct ext4_free_metadata, list); | ||
2669 | list_del(&md->list); | ||
2670 | } | ||
2671 | spin_unlock(&sbi->s_md_lock); | ||
2672 | |||
2673 | if (md == NULL) | ||
2674 | break; | ||
2675 | 2654 | ||
2676 | mb_debug("gonna free %u blocks in group %lu (0x%p):", | 2655 | mb_debug("gonna free %u blocks in group %lu (0x%p):", |
2677 | md->num, md->group, md); | 2656 | entry->count, entry->group, entry); |
2678 | 2657 | ||
2679 | err = ext4_mb_load_buddy(sb, md->group, &e4b); | 2658 | err = ext4_mb_load_buddy(sb, entry->group, &e4b); |
2680 | /* we expect to find existing buddy because it's pinned */ | 2659 | /* we expect to find existing buddy because it's pinned */ |
2681 | BUG_ON(err != 0); | 2660 | BUG_ON(err != 0); |
2682 | 2661 | ||
2662 | db = e4b.bd_info; | ||
2683 | /* there are blocks to put in buddy to make them really free */ | 2663 | /* there are blocks to put in buddy to make them really free */ |
2684 | count += md->num; | 2664 | count += entry->count; |
2685 | count2++; | 2665 | count2++; |
2686 | ext4_lock_group(sb, md->group); | 2666 | ext4_lock_group(sb, entry->group); |
2687 | for (i = 0; i < md->num; i++) { | 2667 | /* Take it out of per group rb tree */ |
2688 | mb_debug(" %u", md->blocks[i]); | 2668 | rb_erase(&entry->node, &(db->bb_free_root)); |
2689 | mb_free_blocks(NULL, &e4b, md->blocks[i], 1); | 2669 | mb_free_blocks(NULL, &e4b, entry->start_blk, entry->count); |
2670 | |||
2671 | if (!db->bb_free_root.rb_node) { | ||
2672 | /* No more items in the per group rb tree | ||
2673 | * balance refcounts from ext4_mb_free_metadata() | ||
2674 | */ | ||
2675 | page_cache_release(e4b.bd_buddy_page); | ||
2676 | page_cache_release(e4b.bd_bitmap_page); | ||
2690 | } | 2677 | } |
2691 | mb_debug("\n"); | 2678 | ext4_unlock_group(sb, entry->group); |
2692 | ext4_unlock_group(sb, md->group); | 2679 | discard_block = (ext4_fsblk_t) entry->group * EXT4_BLOCKS_PER_GROUP(sb) |
2693 | 2680 | + entry->start_blk | |
2694 | /* balance refcounts from ext4_mb_free_metadata() */ | 2681 | + le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block); |
2695 | page_cache_release(e4b.bd_buddy_page); | 2682 | trace_mark(ext4_discard_blocks, "dev %s blk %llu count %u", sb->s_id, |
2696 | page_cache_release(e4b.bd_bitmap_page); | 2683 | (unsigned long long) discard_block, entry->count); |
2697 | 2684 | sb_issue_discard(sb, discard_block, entry->count); | |
2698 | kfree(md); | 2685 | |
2686 | kmem_cache_free(ext4_free_ext_cachep, entry); | ||
2699 | ext4_mb_release_desc(&e4b); | 2687 | ext4_mb_release_desc(&e4b); |
2700 | 2688 | } | |
2701 | } while (md); | ||
2702 | 2689 | ||
2703 | mb_debug("freed %u blocks in %u structures\n", count, count2); | 2690 | mb_debug("freed %u blocks in %u structures\n", count, count2); |
2704 | } | 2691 | } |
@@ -2712,6 +2699,7 @@ ext4_mb_free_committed_blocks(struct super_block *sb) | |||
2712 | 2699 | ||
2713 | static int ext4_mb_init_per_dev_proc(struct super_block *sb) | 2700 | static int ext4_mb_init_per_dev_proc(struct super_block *sb) |
2714 | { | 2701 | { |
2702 | #ifdef CONFIG_PROC_FS | ||
2715 | mode_t mode = S_IFREG | S_IRUGO | S_IWUSR; | 2703 | mode_t mode = S_IFREG | S_IRUGO | S_IWUSR; |
2716 | struct ext4_sb_info *sbi = EXT4_SB(sb); | 2704 | struct ext4_sb_info *sbi = EXT4_SB(sb); |
2717 | struct proc_dir_entry *proc; | 2705 | struct proc_dir_entry *proc; |
@@ -2735,10 +2723,14 @@ err_out: | |||
2735 | remove_proc_entry(EXT4_MB_MAX_TO_SCAN_NAME, sbi->s_proc); | 2723 | remove_proc_entry(EXT4_MB_MAX_TO_SCAN_NAME, sbi->s_proc); |
2736 | remove_proc_entry(EXT4_MB_STATS_NAME, sbi->s_proc); | 2724 | remove_proc_entry(EXT4_MB_STATS_NAME, sbi->s_proc); |
2737 | return -ENOMEM; | 2725 | return -ENOMEM; |
2726 | #else | ||
2727 | return 0; | ||
2728 | #endif | ||
2738 | } | 2729 | } |
2739 | 2730 | ||
2740 | static int ext4_mb_destroy_per_dev_proc(struct super_block *sb) | 2731 | static int ext4_mb_destroy_per_dev_proc(struct super_block *sb) |
2741 | { | 2732 | { |
2733 | #ifdef CONFIG_PROC_FS | ||
2742 | struct ext4_sb_info *sbi = EXT4_SB(sb); | 2734 | struct ext4_sb_info *sbi = EXT4_SB(sb); |
2743 | 2735 | ||
2744 | if (sbi->s_proc == NULL) | 2736 | if (sbi->s_proc == NULL) |
@@ -2750,7 +2742,7 @@ static int ext4_mb_destroy_per_dev_proc(struct super_block *sb) | |||
2750 | remove_proc_entry(EXT4_MB_MIN_TO_SCAN_NAME, sbi->s_proc); | 2742 | remove_proc_entry(EXT4_MB_MIN_TO_SCAN_NAME, sbi->s_proc); |
2751 | remove_proc_entry(EXT4_MB_MAX_TO_SCAN_NAME, sbi->s_proc); | 2743 | remove_proc_entry(EXT4_MB_MAX_TO_SCAN_NAME, sbi->s_proc); |
2752 | remove_proc_entry(EXT4_MB_STATS_NAME, sbi->s_proc); | 2744 | remove_proc_entry(EXT4_MB_STATS_NAME, sbi->s_proc); |
2753 | 2745 | #endif | |
2754 | return 0; | 2746 | return 0; |
2755 | } | 2747 | } |
2756 | 2748 | ||
@@ -2771,6 +2763,16 @@ int __init init_ext4_mballoc(void) | |||
2771 | kmem_cache_destroy(ext4_pspace_cachep); | 2763 | kmem_cache_destroy(ext4_pspace_cachep); |
2772 | return -ENOMEM; | 2764 | return -ENOMEM; |
2773 | } | 2765 | } |
2766 | |||
2767 | ext4_free_ext_cachep = | ||
2768 | kmem_cache_create("ext4_free_block_extents", | ||
2769 | sizeof(struct ext4_free_data), | ||
2770 | 0, SLAB_RECLAIM_ACCOUNT, NULL); | ||
2771 | if (ext4_free_ext_cachep == NULL) { | ||
2772 | kmem_cache_destroy(ext4_pspace_cachep); | ||
2773 | kmem_cache_destroy(ext4_ac_cachep); | ||
2774 | return -ENOMEM; | ||
2775 | } | ||
2774 | return 0; | 2776 | return 0; |
2775 | } | 2777 | } |
2776 | 2778 | ||
@@ -2779,6 +2781,7 @@ void exit_ext4_mballoc(void) | |||
2779 | /* XXX: synchronize_rcu(); */ | 2781 | /* XXX: synchronize_rcu(); */ |
2780 | kmem_cache_destroy(ext4_pspace_cachep); | 2782 | kmem_cache_destroy(ext4_pspace_cachep); |
2781 | kmem_cache_destroy(ext4_ac_cachep); | 2783 | kmem_cache_destroy(ext4_ac_cachep); |
2784 | kmem_cache_destroy(ext4_free_ext_cachep); | ||
2782 | } | 2785 | } |
2783 | 2786 | ||
2784 | 2787 | ||
@@ -4324,8 +4327,6 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle, | |||
4324 | goto out1; | 4327 | goto out1; |
4325 | } | 4328 | } |
4326 | 4329 | ||
4327 | ext4_mb_poll_new_transaction(sb, handle); | ||
4328 | |||
4329 | *errp = ext4_mb_initialize_context(ac, ar); | 4330 | *errp = ext4_mb_initialize_context(ac, ar); |
4330 | if (*errp) { | 4331 | if (*errp) { |
4331 | ar->len = 0; | 4332 | ar->len = 0; |
@@ -4384,35 +4385,20 @@ out1: | |||
4384 | 4385 | ||
4385 | return block; | 4386 | return block; |
4386 | } | 4387 | } |
4387 | static void ext4_mb_poll_new_transaction(struct super_block *sb, | ||
4388 | handle_t *handle) | ||
4389 | { | ||
4390 | struct ext4_sb_info *sbi = EXT4_SB(sb); | ||
4391 | |||
4392 | if (sbi->s_last_transaction == handle->h_transaction->t_tid) | ||
4393 | return; | ||
4394 | |||
4395 | /* new transaction! time to close last one and free blocks for | ||
4396 | * committed transaction. we know that only transaction can be | ||
4397 | * active, so previos transaction can be being logged and we | ||
4398 | * know that transaction before previous is known to be already | ||
4399 | * logged. this means that now we may free blocks freed in all | ||
4400 | * transactions before previous one. hope I'm clear enough ... */ | ||
4401 | 4388 | ||
4402 | spin_lock(&sbi->s_md_lock); | 4389 | /* |
4403 | if (sbi->s_last_transaction != handle->h_transaction->t_tid) { | 4390 | * We can merge two free data extents only if the physical blocks |
4404 | mb_debug("new transaction %lu, old %lu\n", | 4391 | * are contiguous, AND the extents were freed by the same transaction, |
4405 | (unsigned long) handle->h_transaction->t_tid, | 4392 | * AND the blocks are associated with the same group. |
4406 | (unsigned long) sbi->s_last_transaction); | 4393 | */ |
4407 | list_splice_init(&sbi->s_closed_transaction, | 4394 | static int can_merge(struct ext4_free_data *entry1, |
4408 | &sbi->s_committed_transaction); | 4395 | struct ext4_free_data *entry2) |
4409 | list_splice_init(&sbi->s_active_transaction, | 4396 | { |
4410 | &sbi->s_closed_transaction); | 4397 | if ((entry1->t_tid == entry2->t_tid) && |
4411 | sbi->s_last_transaction = handle->h_transaction->t_tid; | 4398 | (entry1->group == entry2->group) && |
4412 | } | 4399 | ((entry1->start_blk + entry1->count) == entry2->start_blk)) |
4413 | spin_unlock(&sbi->s_md_lock); | 4400 | return 1; |
4414 | 4401 | return 0; | |
4415 | ext4_mb_free_committed_blocks(sb); | ||
4416 | } | 4402 | } |
4417 | 4403 | ||
4418 | static noinline_for_stack int | 4404 | static noinline_for_stack int |
@@ -4422,57 +4408,80 @@ ext4_mb_free_metadata(handle_t *handle, struct ext4_buddy *e4b, | |||
4422 | struct ext4_group_info *db = e4b->bd_info; | 4408 | struct ext4_group_info *db = e4b->bd_info; |
4423 | struct super_block *sb = e4b->bd_sb; | 4409 | struct super_block *sb = e4b->bd_sb; |
4424 | struct ext4_sb_info *sbi = EXT4_SB(sb); | 4410 | struct ext4_sb_info *sbi = EXT4_SB(sb); |
4425 | struct ext4_free_metadata *md; | 4411 | struct ext4_free_data *entry, *new_entry; |
4426 | int i; | 4412 | struct rb_node **n = &db->bb_free_root.rb_node, *node; |
4413 | struct rb_node *parent = NULL, *new_node; | ||
4414 | |||
4427 | 4415 | ||
4428 | BUG_ON(e4b->bd_bitmap_page == NULL); | 4416 | BUG_ON(e4b->bd_bitmap_page == NULL); |
4429 | BUG_ON(e4b->bd_buddy_page == NULL); | 4417 | BUG_ON(e4b->bd_buddy_page == NULL); |
4430 | 4418 | ||
4419 | new_entry = kmem_cache_alloc(ext4_free_ext_cachep, GFP_NOFS); | ||
4420 | new_entry->start_blk = block; | ||
4421 | new_entry->group = group; | ||
4422 | new_entry->count = count; | ||
4423 | new_entry->t_tid = handle->h_transaction->t_tid; | ||
4424 | new_node = &new_entry->node; | ||
4425 | |||
4431 | ext4_lock_group(sb, group); | 4426 | ext4_lock_group(sb, group); |
4432 | for (i = 0; i < count; i++) { | 4427 | if (!*n) { |
4433 | md = db->bb_md_cur; | 4428 | /* first free block exent. We need to |
4434 | if (md && db->bb_tid != handle->h_transaction->t_tid) { | 4429 | protect buddy cache from being freed, |
4435 | db->bb_md_cur = NULL; | 4430 | * otherwise we'll refresh it from |
4436 | md = NULL; | 4431 | * on-disk bitmap and lose not-yet-available |
4432 | * blocks */ | ||
4433 | page_cache_get(e4b->bd_buddy_page); | ||
4434 | page_cache_get(e4b->bd_bitmap_page); | ||
4435 | } | ||
4436 | while (*n) { | ||
4437 | parent = *n; | ||
4438 | entry = rb_entry(parent, struct ext4_free_data, node); | ||
4439 | if (block < entry->start_blk) | ||
4440 | n = &(*n)->rb_left; | ||
4441 | else if (block >= (entry->start_blk + entry->count)) | ||
4442 | n = &(*n)->rb_right; | ||
4443 | else { | ||
4444 | ext4_error(sb, __func__, | ||
4445 | "Double free of blocks %d (%d %d)\n", | ||
4446 | block, entry->start_blk, entry->count); | ||
4447 | return 0; | ||
4437 | } | 4448 | } |
4449 | } | ||
4438 | 4450 | ||
4439 | if (md == NULL) { | 4451 | rb_link_node(new_node, parent, n); |
4440 | ext4_unlock_group(sb, group); | 4452 | rb_insert_color(new_node, &db->bb_free_root); |
4441 | md = kmalloc(sizeof(*md), GFP_NOFS); | 4453 | |
4442 | if (md == NULL) | 4454 | /* Now try to see the extent can be merged to left and right */ |
4443 | return -ENOMEM; | 4455 | node = rb_prev(new_node); |
4444 | md->num = 0; | 4456 | if (node) { |
4445 | md->group = group; | 4457 | entry = rb_entry(node, struct ext4_free_data, node); |
4446 | 4458 | if (can_merge(entry, new_entry)) { | |
4447 | ext4_lock_group(sb, group); | 4459 | new_entry->start_blk = entry->start_blk; |
4448 | if (db->bb_md_cur == NULL) { | 4460 | new_entry->count += entry->count; |
4449 | spin_lock(&sbi->s_md_lock); | 4461 | rb_erase(node, &(db->bb_free_root)); |
4450 | list_add(&md->list, &sbi->s_active_transaction); | 4462 | spin_lock(&sbi->s_md_lock); |
4451 | spin_unlock(&sbi->s_md_lock); | 4463 | list_del(&entry->list); |
4452 | /* protect buddy cache from being freed, | 4464 | spin_unlock(&sbi->s_md_lock); |
4453 | * otherwise we'll refresh it from | 4465 | kmem_cache_free(ext4_free_ext_cachep, entry); |
4454 | * on-disk bitmap and lose not-yet-available | ||
4455 | * blocks */ | ||
4456 | page_cache_get(e4b->bd_buddy_page); | ||
4457 | page_cache_get(e4b->bd_bitmap_page); | ||
4458 | db->bb_md_cur = md; | ||
4459 | db->bb_tid = handle->h_transaction->t_tid; | ||
4460 | mb_debug("new md 0x%p for group %lu\n", | ||
4461 | md, md->group); | ||
4462 | } else { | ||
4463 | kfree(md); | ||
4464 | md = db->bb_md_cur; | ||
4465 | } | ||
4466 | } | 4466 | } |
4467 | } | ||
4467 | 4468 | ||
4468 | BUG_ON(md->num >= EXT4_BB_MAX_BLOCKS); | 4469 | node = rb_next(new_node); |
4469 | md->blocks[md->num] = block + i; | 4470 | if (node) { |
4470 | md->num++; | 4471 | entry = rb_entry(node, struct ext4_free_data, node); |
4471 | if (md->num == EXT4_BB_MAX_BLOCKS) { | 4472 | if (can_merge(new_entry, entry)) { |
4472 | /* no more space, put full container on a sb's list */ | 4473 | new_entry->count += entry->count; |
4473 | db->bb_md_cur = NULL; | 4474 | rb_erase(node, &(db->bb_free_root)); |
4475 | spin_lock(&sbi->s_md_lock); | ||
4476 | list_del(&entry->list); | ||
4477 | spin_unlock(&sbi->s_md_lock); | ||
4478 | kmem_cache_free(ext4_free_ext_cachep, entry); | ||
4474 | } | 4479 | } |
4475 | } | 4480 | } |
4481 | /* Add the extent to transaction's private list */ | ||
4482 | spin_lock(&sbi->s_md_lock); | ||
4483 | list_add(&new_entry->list, &handle->h_transaction->t_private_list); | ||
4484 | spin_unlock(&sbi->s_md_lock); | ||
4476 | ext4_unlock_group(sb, group); | 4485 | ext4_unlock_group(sb, group); |
4477 | return 0; | 4486 | return 0; |
4478 | } | 4487 | } |
@@ -4500,8 +4509,6 @@ void ext4_mb_free_blocks(handle_t *handle, struct inode *inode, | |||
4500 | 4509 | ||
4501 | *freed = 0; | 4510 | *freed = 0; |
4502 | 4511 | ||
4503 | ext4_mb_poll_new_transaction(sb, handle); | ||
4504 | |||
4505 | sbi = EXT4_SB(sb); | 4512 | sbi = EXT4_SB(sb); |
4506 | es = EXT4_SB(sb)->s_es; | 4513 | es = EXT4_SB(sb)->s_es; |
4507 | if (block < le32_to_cpu(es->s_first_data_block) || | 4514 | if (block < le32_to_cpu(es->s_first_data_block) || |
diff --git a/fs/ext4/mballoc.h b/fs/ext4/mballoc.h index b3b4828f8b89..b5dff1fff1e5 100644 --- a/fs/ext4/mballoc.h +++ b/fs/ext4/mballoc.h | |||
@@ -18,6 +18,8 @@ | |||
18 | #include <linux/pagemap.h> | 18 | #include <linux/pagemap.h> |
19 | #include <linux/seq_file.h> | 19 | #include <linux/seq_file.h> |
20 | #include <linux/version.h> | 20 | #include <linux/version.h> |
21 | #include <linux/blkdev.h> | ||
22 | #include <linux/marker.h> | ||
21 | #include "ext4_jbd2.h" | 23 | #include "ext4_jbd2.h" |
22 | #include "ext4.h" | 24 | #include "ext4.h" |
23 | #include "group.h" | 25 | #include "group.h" |
@@ -98,23 +100,29 @@ | |||
98 | 100 | ||
99 | static struct kmem_cache *ext4_pspace_cachep; | 101 | static struct kmem_cache *ext4_pspace_cachep; |
100 | static struct kmem_cache *ext4_ac_cachep; | 102 | static struct kmem_cache *ext4_ac_cachep; |
103 | static struct kmem_cache *ext4_free_ext_cachep; | ||
101 | 104 | ||
102 | #ifdef EXT4_BB_MAX_BLOCKS | 105 | struct ext4_free_data { |
103 | #undef EXT4_BB_MAX_BLOCKS | 106 | /* this links the free block information from group_info */ |
104 | #endif | 107 | struct rb_node node; |
105 | #define EXT4_BB_MAX_BLOCKS 30 | ||
106 | 108 | ||
107 | struct ext4_free_metadata { | 109 | /* this links the free block information from ext4_sb_info */ |
108 | ext4_group_t group; | ||
109 | unsigned short num; | ||
110 | ext4_grpblk_t blocks[EXT4_BB_MAX_BLOCKS]; | ||
111 | struct list_head list; | 110 | struct list_head list; |
111 | |||
112 | /* group which free block extent belongs */ | ||
113 | ext4_group_t group; | ||
114 | |||
115 | /* free block extent */ | ||
116 | ext4_grpblk_t start_blk; | ||
117 | ext4_grpblk_t count; | ||
118 | |||
119 | /* transaction which freed this extent */ | ||
120 | tid_t t_tid; | ||
112 | }; | 121 | }; |
113 | 122 | ||
114 | struct ext4_group_info { | 123 | struct ext4_group_info { |
115 | unsigned long bb_state; | 124 | unsigned long bb_state; |
116 | unsigned long bb_tid; | 125 | struct rb_root bb_free_root; |
117 | struct ext4_free_metadata *bb_md_cur; | ||
118 | unsigned short bb_first_free; | 126 | unsigned short bb_first_free; |
119 | unsigned short bb_free; | 127 | unsigned short bb_free; |
120 | unsigned short bb_fragments; | 128 | unsigned short bb_fragments; |
@@ -261,8 +269,6 @@ struct buffer_head *read_block_bitmap(struct super_block *, ext4_group_t); | |||
261 | 269 | ||
262 | static void ext4_mb_generate_from_pa(struct super_block *sb, void *bitmap, | 270 | static void ext4_mb_generate_from_pa(struct super_block *sb, void *bitmap, |
263 | ext4_group_t group); | 271 | ext4_group_t group); |
264 | static void ext4_mb_poll_new_transaction(struct super_block *, handle_t *); | ||
265 | static void ext4_mb_free_committed_blocks(struct super_block *); | ||
266 | static void ext4_mb_return_to_preallocation(struct inode *inode, | 272 | static void ext4_mb_return_to_preallocation(struct inode *inode, |
267 | struct ext4_buddy *e4b, sector_t block, | 273 | struct ext4_buddy *e4b, sector_t block, |
268 | int count); | 274 | int count); |
@@ -270,6 +276,7 @@ static void ext4_mb_put_pa(struct ext4_allocation_context *, | |||
270 | struct super_block *, struct ext4_prealloc_space *pa); | 276 | struct super_block *, struct ext4_prealloc_space *pa); |
271 | static int ext4_mb_init_per_dev_proc(struct super_block *sb); | 277 | static int ext4_mb_init_per_dev_proc(struct super_block *sb); |
272 | static int ext4_mb_destroy_per_dev_proc(struct super_block *sb); | 278 | static int ext4_mb_destroy_per_dev_proc(struct super_block *sb); |
279 | static void release_blocks_on_commit(journal_t *journal, transaction_t *txn); | ||
273 | 280 | ||
274 | 281 | ||
275 | static inline void ext4_lock_group(struct super_block *sb, ext4_group_t group) | 282 | static inline void ext4_lock_group(struct super_block *sb, ext4_group_t group) |
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index dea8f13c2fd9..9b2b2bc4ec17 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -374,66 +374,6 @@ void ext4_update_dynamic_rev(struct super_block *sb) | |||
374 | */ | 374 | */ |
375 | } | 375 | } |
376 | 376 | ||
377 | int ext4_update_compat_feature(handle_t *handle, | ||
378 | struct super_block *sb, __u32 compat) | ||
379 | { | ||
380 | int err = 0; | ||
381 | if (!EXT4_HAS_COMPAT_FEATURE(sb, compat)) { | ||
382 | err = ext4_journal_get_write_access(handle, | ||
383 | EXT4_SB(sb)->s_sbh); | ||
384 | if (err) | ||
385 | return err; | ||
386 | EXT4_SET_COMPAT_FEATURE(sb, compat); | ||
387 | sb->s_dirt = 1; | ||
388 | handle->h_sync = 1; | ||
389 | BUFFER_TRACE(EXT4_SB(sb)->s_sbh, | ||
390 | "call ext4_journal_dirty_met adata"); | ||
391 | err = ext4_journal_dirty_metadata(handle, | ||
392 | EXT4_SB(sb)->s_sbh); | ||
393 | } | ||
394 | return err; | ||
395 | } | ||
396 | |||
397 | int ext4_update_rocompat_feature(handle_t *handle, | ||
398 | struct super_block *sb, __u32 rocompat) | ||
399 | { | ||
400 | int err = 0; | ||
401 | if (!EXT4_HAS_RO_COMPAT_FEATURE(sb, rocompat)) { | ||
402 | err = ext4_journal_get_write_access(handle, | ||
403 | EXT4_SB(sb)->s_sbh); | ||
404 | if (err) | ||
405 | return err; | ||
406 | EXT4_SET_RO_COMPAT_FEATURE(sb, rocompat); | ||
407 | sb->s_dirt = 1; | ||
408 | handle->h_sync = 1; | ||
409 | BUFFER_TRACE(EXT4_SB(sb)->s_sbh, | ||
410 | "call ext4_journal_dirty_met adata"); | ||
411 | err = ext4_journal_dirty_metadata(handle, | ||
412 | EXT4_SB(sb)->s_sbh); | ||
413 | } | ||
414 | return err; | ||
415 | } | ||
416 | |||
417 | int ext4_update_incompat_feature(handle_t *handle, | ||
418 | struct super_block *sb, __u32 incompat) | ||
419 | { | ||
420 | int err = 0; | ||
421 | if (!EXT4_HAS_INCOMPAT_FEATURE(sb, incompat)) { | ||
422 | err = ext4_journal_get_write_access(handle, | ||
423 | EXT4_SB(sb)->s_sbh); | ||
424 | if (err) | ||
425 | return err; | ||
426 | EXT4_SET_INCOMPAT_FEATURE(sb, incompat); | ||
427 | sb->s_dirt = 1; | ||
428 | handle->h_sync = 1; | ||
429 | BUFFER_TRACE(EXT4_SB(sb)->s_sbh, | ||
430 | "call ext4_journal_dirty_met adata"); | ||
431 | err = ext4_journal_dirty_metadata(handle, | ||
432 | EXT4_SB(sb)->s_sbh); | ||
433 | } | ||
434 | return err; | ||
435 | } | ||
436 | |||
437 | /* | 377 | /* |
438 | * Open the external journal device | 378 | * Open the external journal device |
439 | */ | 379 | */ |
@@ -904,7 +844,7 @@ static const struct export_operations ext4_export_ops = { | |||
904 | enum { | 844 | enum { |
905 | Opt_bsd_df, Opt_minix_df, Opt_grpid, Opt_nogrpid, | 845 | Opt_bsd_df, Opt_minix_df, Opt_grpid, Opt_nogrpid, |
906 | Opt_resgid, Opt_resuid, Opt_sb, Opt_err_cont, Opt_err_panic, Opt_err_ro, | 846 | Opt_resgid, Opt_resuid, Opt_sb, Opt_err_cont, Opt_err_panic, Opt_err_ro, |
907 | Opt_nouid32, Opt_nocheck, Opt_debug, Opt_oldalloc, Opt_orlov, | 847 | Opt_nouid32, Opt_debug, Opt_oldalloc, Opt_orlov, |
908 | Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl, | 848 | Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl, |
909 | Opt_reservation, Opt_noreservation, Opt_noload, Opt_nobh, Opt_bh, | 849 | Opt_reservation, Opt_noreservation, Opt_noload, Opt_nobh, Opt_bh, |
910 | Opt_commit, Opt_journal_update, Opt_journal_inum, Opt_journal_dev, | 850 | Opt_commit, Opt_journal_update, Opt_journal_inum, Opt_journal_dev, |
@@ -915,7 +855,7 @@ enum { | |||
915 | Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota, | 855 | Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota, |
916 | Opt_ignore, Opt_barrier, Opt_err, Opt_resize, Opt_usrquota, | 856 | Opt_ignore, Opt_barrier, Opt_err, Opt_resize, Opt_usrquota, |
917 | Opt_grpquota, Opt_extents, Opt_noextents, Opt_i_version, | 857 | Opt_grpquota, Opt_extents, Opt_noextents, Opt_i_version, |
918 | Opt_mballoc, Opt_nomballoc, Opt_stripe, Opt_delalloc, Opt_nodelalloc, | 858 | Opt_stripe, Opt_delalloc, Opt_nodelalloc, |
919 | Opt_inode_readahead_blks | 859 | Opt_inode_readahead_blks |
920 | }; | 860 | }; |
921 | 861 | ||
@@ -933,8 +873,6 @@ static const match_table_t tokens = { | |||
933 | {Opt_err_panic, "errors=panic"}, | 873 | {Opt_err_panic, "errors=panic"}, |
934 | {Opt_err_ro, "errors=remount-ro"}, | 874 | {Opt_err_ro, "errors=remount-ro"}, |
935 | {Opt_nouid32, "nouid32"}, | 875 | {Opt_nouid32, "nouid32"}, |
936 | {Opt_nocheck, "nocheck"}, | ||
937 | {Opt_nocheck, "check=none"}, | ||
938 | {Opt_debug, "debug"}, | 876 | {Opt_debug, "debug"}, |
939 | {Opt_oldalloc, "oldalloc"}, | 877 | {Opt_oldalloc, "oldalloc"}, |
940 | {Opt_orlov, "orlov"}, | 878 | {Opt_orlov, "orlov"}, |
@@ -973,8 +911,6 @@ static const match_table_t tokens = { | |||
973 | {Opt_extents, "extents"}, | 911 | {Opt_extents, "extents"}, |
974 | {Opt_noextents, "noextents"}, | 912 | {Opt_noextents, "noextents"}, |
975 | {Opt_i_version, "i_version"}, | 913 | {Opt_i_version, "i_version"}, |
976 | {Opt_mballoc, "mballoc"}, | ||
977 | {Opt_nomballoc, "nomballoc"}, | ||
978 | {Opt_stripe, "stripe=%u"}, | 914 | {Opt_stripe, "stripe=%u"}, |
979 | {Opt_resize, "resize"}, | 915 | {Opt_resize, "resize"}, |
980 | {Opt_delalloc, "delalloc"}, | 916 | {Opt_delalloc, "delalloc"}, |
@@ -1073,9 +1009,6 @@ static int parse_options(char *options, struct super_block *sb, | |||
1073 | case Opt_nouid32: | 1009 | case Opt_nouid32: |
1074 | set_opt(sbi->s_mount_opt, NO_UID32); | 1010 | set_opt(sbi->s_mount_opt, NO_UID32); |
1075 | break; | 1011 | break; |
1076 | case Opt_nocheck: | ||
1077 | clear_opt(sbi->s_mount_opt, CHECK); | ||
1078 | break; | ||
1079 | case Opt_debug: | 1012 | case Opt_debug: |
1080 | set_opt(sbi->s_mount_opt, DEBUG); | 1013 | set_opt(sbi->s_mount_opt, DEBUG); |
1081 | break; | 1014 | break; |
@@ -1618,14 +1551,14 @@ static int ext4_check_descriptors(struct super_block *sb) | |||
1618 | if (block_bitmap < first_block || block_bitmap > last_block) { | 1551 | if (block_bitmap < first_block || block_bitmap > last_block) { |
1619 | printk(KERN_ERR "EXT4-fs: ext4_check_descriptors: " | 1552 | printk(KERN_ERR "EXT4-fs: ext4_check_descriptors: " |
1620 | "Block bitmap for group %lu not in group " | 1553 | "Block bitmap for group %lu not in group " |
1621 | "(block %llu)!", i, block_bitmap); | 1554 | "(block %llu)!\n", i, block_bitmap); |
1622 | return 0; | 1555 | return 0; |
1623 | } | 1556 | } |
1624 | inode_bitmap = ext4_inode_bitmap(sb, gdp); | 1557 | inode_bitmap = ext4_inode_bitmap(sb, gdp); |
1625 | if (inode_bitmap < first_block || inode_bitmap > last_block) { | 1558 | if (inode_bitmap < first_block || inode_bitmap > last_block) { |
1626 | printk(KERN_ERR "EXT4-fs: ext4_check_descriptors: " | 1559 | printk(KERN_ERR "EXT4-fs: ext4_check_descriptors: " |
1627 | "Inode bitmap for group %lu not in group " | 1560 | "Inode bitmap for group %lu not in group " |
1628 | "(block %llu)!", i, inode_bitmap); | 1561 | "(block %llu)!\n", i, inode_bitmap); |
1629 | return 0; | 1562 | return 0; |
1630 | } | 1563 | } |
1631 | inode_table = ext4_inode_table(sb, gdp); | 1564 | inode_table = ext4_inode_table(sb, gdp); |
@@ -1633,7 +1566,7 @@ static int ext4_check_descriptors(struct super_block *sb) | |||
1633 | inode_table + sbi->s_itb_per_group - 1 > last_block) { | 1566 | inode_table + sbi->s_itb_per_group - 1 > last_block) { |
1634 | printk(KERN_ERR "EXT4-fs: ext4_check_descriptors: " | 1567 | printk(KERN_ERR "EXT4-fs: ext4_check_descriptors: " |
1635 | "Inode table for group %lu not in group " | 1568 | "Inode table for group %lu not in group " |
1636 | "(block %llu)!", i, inode_table); | 1569 | "(block %llu)!\n", i, inode_table); |
1637 | return 0; | 1570 | return 0; |
1638 | } | 1571 | } |
1639 | spin_lock(sb_bgl_lock(sbi, i)); | 1572 | spin_lock(sb_bgl_lock(sbi, i)); |
@@ -1778,13 +1711,13 @@ static void ext4_orphan_cleanup(struct super_block *sb, | |||
1778 | * | 1711 | * |
1779 | * Note, this does *not* consider any metadata overhead for vfs i_blocks. | 1712 | * Note, this does *not* consider any metadata overhead for vfs i_blocks. |
1780 | */ | 1713 | */ |
1781 | static loff_t ext4_max_size(int blkbits) | 1714 | static loff_t ext4_max_size(int blkbits, int has_huge_files) |
1782 | { | 1715 | { |
1783 | loff_t res; | 1716 | loff_t res; |
1784 | loff_t upper_limit = MAX_LFS_FILESIZE; | 1717 | loff_t upper_limit = MAX_LFS_FILESIZE; |
1785 | 1718 | ||
1786 | /* small i_blocks in vfs inode? */ | 1719 | /* small i_blocks in vfs inode? */ |
1787 | if (sizeof(blkcnt_t) < sizeof(u64)) { | 1720 | if (!has_huge_files || sizeof(blkcnt_t) < sizeof(u64)) { |
1788 | /* | 1721 | /* |
1789 | * CONFIG_LSF is not enabled implies the inode | 1722 | * CONFIG_LSF is not enabled implies the inode |
1790 | * i_block represent total blocks in 512 bytes | 1723 | * i_block represent total blocks in 512 bytes |
@@ -1814,7 +1747,7 @@ static loff_t ext4_max_size(int blkbits) | |||
1814 | * block limit, and also a limit of (2^48 - 1) 512-byte sectors in i_blocks. | 1747 | * block limit, and also a limit of (2^48 - 1) 512-byte sectors in i_blocks. |
1815 | * We need to be 1 filesystem block less than the 2^48 sector limit. | 1748 | * We need to be 1 filesystem block less than the 2^48 sector limit. |
1816 | */ | 1749 | */ |
1817 | static loff_t ext4_max_bitmap_size(int bits) | 1750 | static loff_t ext4_max_bitmap_size(int bits, int has_huge_files) |
1818 | { | 1751 | { |
1819 | loff_t res = EXT4_NDIR_BLOCKS; | 1752 | loff_t res = EXT4_NDIR_BLOCKS; |
1820 | int meta_blocks; | 1753 | int meta_blocks; |
@@ -1827,11 +1760,11 @@ static loff_t ext4_max_bitmap_size(int bits) | |||
1827 | * total number of 512 bytes blocks of the file | 1760 | * total number of 512 bytes blocks of the file |
1828 | */ | 1761 | */ |
1829 | 1762 | ||
1830 | if (sizeof(blkcnt_t) < sizeof(u64)) { | 1763 | if (!has_huge_files || sizeof(blkcnt_t) < sizeof(u64)) { |
1831 | /* | 1764 | /* |
1832 | * CONFIG_LSF is not enabled implies the inode | 1765 | * !has_huge_files or CONFIG_LSF is not enabled |
1833 | * i_block represent total blocks in 512 bytes | 1766 | * implies the inode i_block represent total blocks in |
1834 | * 32 == size of vfs inode i_blocks * 8 | 1767 | * 512 bytes 32 == size of vfs inode i_blocks * 8 |
1835 | */ | 1768 | */ |
1836 | upper_limit = (1LL << 32) - 1; | 1769 | upper_limit = (1LL << 32) - 1; |
1837 | 1770 | ||
@@ -1940,7 +1873,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
1940 | int blocksize; | 1873 | int blocksize; |
1941 | int db_count; | 1874 | int db_count; |
1942 | int i; | 1875 | int i; |
1943 | int needs_recovery; | 1876 | int needs_recovery, has_huge_files; |
1944 | __le32 features; | 1877 | __le32 features; |
1945 | __u64 blocks_count; | 1878 | __u64 blocks_count; |
1946 | int err; | 1879 | int err; |
@@ -2081,7 +2014,9 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2081 | sb->s_id, le32_to_cpu(features)); | 2014 | sb->s_id, le32_to_cpu(features)); |
2082 | goto failed_mount; | 2015 | goto failed_mount; |
2083 | } | 2016 | } |
2084 | if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_HUGE_FILE)) { | 2017 | has_huge_files = EXT4_HAS_RO_COMPAT_FEATURE(sb, |
2018 | EXT4_FEATURE_RO_COMPAT_HUGE_FILE); | ||
2019 | if (has_huge_files) { | ||
2085 | /* | 2020 | /* |
2086 | * Large file size enabled file system can only be | 2021 | * Large file size enabled file system can only be |
2087 | * mount if kernel is build with CONFIG_LSF | 2022 | * mount if kernel is build with CONFIG_LSF |
@@ -2131,8 +2066,9 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2131 | } | 2066 | } |
2132 | } | 2067 | } |
2133 | 2068 | ||
2134 | sbi->s_bitmap_maxbytes = ext4_max_bitmap_size(sb->s_blocksize_bits); | 2069 | sbi->s_bitmap_maxbytes = ext4_max_bitmap_size(sb->s_blocksize_bits, |
2135 | sb->s_maxbytes = ext4_max_size(sb->s_blocksize_bits); | 2070 | has_huge_files); |
2071 | sb->s_maxbytes = ext4_max_size(sb->s_blocksize_bits, has_huge_files); | ||
2136 | 2072 | ||
2137 | if (le32_to_cpu(es->s_rev_level) == EXT4_GOOD_OLD_REV) { | 2073 | if (le32_to_cpu(es->s_rev_level) == EXT4_GOOD_OLD_REV) { |
2138 | sbi->s_inode_size = EXT4_GOOD_OLD_INODE_SIZE; | 2074 | sbi->s_inode_size = EXT4_GOOD_OLD_INODE_SIZE; |
@@ -2456,6 +2392,21 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2456 | "available.\n"); | 2392 | "available.\n"); |
2457 | } | 2393 | } |
2458 | 2394 | ||
2395 | if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA) { | ||
2396 | printk(KERN_WARNING "EXT4-fs: Ignoring delalloc option - " | ||
2397 | "requested data journaling mode\n"); | ||
2398 | clear_opt(sbi->s_mount_opt, DELALLOC); | ||
2399 | } else if (test_opt(sb, DELALLOC)) | ||
2400 | printk(KERN_INFO "EXT4-fs: delayed allocation enabled\n"); | ||
2401 | |||
2402 | ext4_ext_init(sb); | ||
2403 | err = ext4_mb_init(sb, needs_recovery); | ||
2404 | if (err) { | ||
2405 | printk(KERN_ERR "EXT4-fs: failed to initalize mballoc (%d)\n", | ||
2406 | err); | ||
2407 | goto failed_mount4; | ||
2408 | } | ||
2409 | |||
2459 | /* | 2410 | /* |
2460 | * akpm: core read_super() calls in here with the superblock locked. | 2411 | * akpm: core read_super() calls in here with the superblock locked. |
2461 | * That deadlocks, because orphan cleanup needs to lock the superblock | 2412 | * That deadlocks, because orphan cleanup needs to lock the superblock |
@@ -2475,21 +2426,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2475 | test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_ORDERED_DATA ? "ordered": | 2426 | test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_ORDERED_DATA ? "ordered": |
2476 | "writeback"); | 2427 | "writeback"); |
2477 | 2428 | ||
2478 | if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA) { | ||
2479 | printk(KERN_WARNING "EXT4-fs: Ignoring delalloc option - " | ||
2480 | "requested data journaling mode\n"); | ||
2481 | clear_opt(sbi->s_mount_opt, DELALLOC); | ||
2482 | } else if (test_opt(sb, DELALLOC)) | ||
2483 | printk(KERN_INFO "EXT4-fs: delayed allocation enabled\n"); | ||
2484 | |||
2485 | ext4_ext_init(sb); | ||
2486 | err = ext4_mb_init(sb, needs_recovery); | ||
2487 | if (err) { | ||
2488 | printk(KERN_ERR "EXT4-fs: failed to initalize mballoc (%d)\n", | ||
2489 | err); | ||
2490 | goto failed_mount4; | ||
2491 | } | ||
2492 | |||
2493 | lock_kernel(); | 2429 | lock_kernel(); |
2494 | return 0; | 2430 | return 0; |
2495 | 2431 | ||
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c index 0abe02c4242a..8b119e16aa36 100644 --- a/fs/jbd2/commit.c +++ b/fs/jbd2/commit.c | |||
@@ -995,6 +995,9 @@ restart_loop: | |||
995 | } | 995 | } |
996 | spin_unlock(&journal->j_list_lock); | 996 | spin_unlock(&journal->j_list_lock); |
997 | 997 | ||
998 | if (journal->j_commit_callback) | ||
999 | journal->j_commit_callback(journal, commit_transaction); | ||
1000 | |||
998 | trace_mark(jbd2_end_commit, "dev %s transaction %d head %d", | 1001 | trace_mark(jbd2_end_commit, "dev %s transaction %d head %d", |
999 | journal->j_devname, commit_transaction->t_tid, | 1002 | journal->j_devname, commit_transaction->t_tid, |
1000 | journal->j_tail_sequence); | 1003 | journal->j_tail_sequence); |
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c index e5d540588fa9..39b7805a599a 100644 --- a/fs/jbd2/transaction.c +++ b/fs/jbd2/transaction.c | |||
@@ -52,6 +52,7 @@ jbd2_get_transaction(journal_t *journal, transaction_t *transaction) | |||
52 | transaction->t_expires = jiffies + journal->j_commit_interval; | 52 | transaction->t_expires = jiffies + journal->j_commit_interval; |
53 | spin_lock_init(&transaction->t_handle_lock); | 53 | spin_lock_init(&transaction->t_handle_lock); |
54 | INIT_LIST_HEAD(&transaction->t_inode_list); | 54 | INIT_LIST_HEAD(&transaction->t_inode_list); |
55 | INIT_LIST_HEAD(&transaction->t_private_list); | ||
55 | 56 | ||
56 | /* Set up the commit timer for the new transaction. */ | 57 | /* Set up the commit timer for the new transaction. */ |
57 | journal->j_commit_timer.expires = round_jiffies(transaction->t_expires); | 58 | journal->j_commit_timer.expires = round_jiffies(transaction->t_expires); |
diff --git a/include/drm/drm.h b/include/drm/drm.h index 38d3c6b8276a..f46ba4b57da4 100644 --- a/include/drm/drm.h +++ b/include/drm/drm.h | |||
@@ -36,7 +36,6 @@ | |||
36 | #ifndef _DRM_H_ | 36 | #ifndef _DRM_H_ |
37 | #define _DRM_H_ | 37 | #define _DRM_H_ |
38 | 38 | ||
39 | #if defined(__linux__) | ||
40 | #if defined(__KERNEL__) | 39 | #if defined(__KERNEL__) |
41 | #endif | 40 | #endif |
42 | #include <asm/ioctl.h> /* For _IO* macros */ | 41 | #include <asm/ioctl.h> /* For _IO* macros */ |
@@ -46,22 +45,6 @@ | |||
46 | #define DRM_IOC_WRITE _IOC_WRITE | 45 | #define DRM_IOC_WRITE _IOC_WRITE |
47 | #define DRM_IOC_READWRITE _IOC_READ|_IOC_WRITE | 46 | #define DRM_IOC_READWRITE _IOC_READ|_IOC_WRITE |
48 | #define DRM_IOC(dir, group, nr, size) _IOC(dir, group, nr, size) | 47 | #define DRM_IOC(dir, group, nr, size) _IOC(dir, group, nr, size) |
49 | #elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) | ||
50 | #if defined(__FreeBSD__) && defined(IN_MODULE) | ||
51 | /* Prevent name collision when including sys/ioccom.h */ | ||
52 | #undef ioctl | ||
53 | #include <sys/ioccom.h> | ||
54 | #define ioctl(a,b,c) xf86ioctl(a,b,c) | ||
55 | #else | ||
56 | #include <sys/ioccom.h> | ||
57 | #endif /* __FreeBSD__ && xf86ioctl */ | ||
58 | #define DRM_IOCTL_NR(n) ((n) & 0xff) | ||
59 | #define DRM_IOC_VOID IOC_VOID | ||
60 | #define DRM_IOC_READ IOC_OUT | ||
61 | #define DRM_IOC_WRITE IOC_IN | ||
62 | #define DRM_IOC_READWRITE IOC_INOUT | ||
63 | #define DRM_IOC(dir, group, nr, size) _IOC(dir, group, nr, size) | ||
64 | #endif | ||
65 | 48 | ||
66 | #define DRM_MAJOR 226 | 49 | #define DRM_MAJOR 226 |
67 | #define DRM_MAX_MINOR 15 | 50 | #define DRM_MAX_MINOR 15 |
@@ -471,6 +454,7 @@ struct drm_irq_busid { | |||
471 | enum drm_vblank_seq_type { | 454 | enum drm_vblank_seq_type { |
472 | _DRM_VBLANK_ABSOLUTE = 0x0, /**< Wait for specific vblank sequence number */ | 455 | _DRM_VBLANK_ABSOLUTE = 0x0, /**< Wait for specific vblank sequence number */ |
473 | _DRM_VBLANK_RELATIVE = 0x1, /**< Wait for given number of vblanks */ | 456 | _DRM_VBLANK_RELATIVE = 0x1, /**< Wait for given number of vblanks */ |
457 | _DRM_VBLANK_FLIP = 0x8000000, /**< Scheduled buffer swap should flip */ | ||
474 | _DRM_VBLANK_NEXTONMISS = 0x10000000, /**< If missed, wait for next vblank */ | 458 | _DRM_VBLANK_NEXTONMISS = 0x10000000, /**< If missed, wait for next vblank */ |
475 | _DRM_VBLANK_SECONDARY = 0x20000000, /**< Secondary display controller */ | 459 | _DRM_VBLANK_SECONDARY = 0x20000000, /**< Secondary display controller */ |
476 | _DRM_VBLANK_SIGNAL = 0x40000000 /**< Send signal instead of blocking */ | 460 | _DRM_VBLANK_SIGNAL = 0x40000000 /**< Send signal instead of blocking */ |
@@ -503,6 +487,19 @@ union drm_wait_vblank { | |||
503 | struct drm_wait_vblank_reply reply; | 487 | struct drm_wait_vblank_reply reply; |
504 | }; | 488 | }; |
505 | 489 | ||
490 | #define _DRM_PRE_MODESET 1 | ||
491 | #define _DRM_POST_MODESET 2 | ||
492 | |||
493 | /** | ||
494 | * DRM_IOCTL_MODESET_CTL ioctl argument type | ||
495 | * | ||
496 | * \sa drmModesetCtl(). | ||
497 | */ | ||
498 | struct drm_modeset_ctl { | ||
499 | uint32_t crtc; | ||
500 | uint32_t cmd; | ||
501 | }; | ||
502 | |||
506 | /** | 503 | /** |
507 | * DRM_IOCTL_AGP_ENABLE ioctl argument type. | 504 | * DRM_IOCTL_AGP_ENABLE ioctl argument type. |
508 | * | 505 | * |
@@ -573,6 +570,34 @@ struct drm_set_version { | |||
573 | int drm_dd_minor; | 570 | int drm_dd_minor; |
574 | }; | 571 | }; |
575 | 572 | ||
573 | /** DRM_IOCTL_GEM_CLOSE ioctl argument type */ | ||
574 | struct drm_gem_close { | ||
575 | /** Handle of the object to be closed. */ | ||
576 | uint32_t handle; | ||
577 | uint32_t pad; | ||
578 | }; | ||
579 | |||
580 | /** DRM_IOCTL_GEM_FLINK ioctl argument type */ | ||
581 | struct drm_gem_flink { | ||
582 | /** Handle for the object being named */ | ||
583 | uint32_t handle; | ||
584 | |||
585 | /** Returned global name */ | ||
586 | uint32_t name; | ||
587 | }; | ||
588 | |||
589 | /** DRM_IOCTL_GEM_OPEN ioctl argument type */ | ||
590 | struct drm_gem_open { | ||
591 | /** Name of object being opened */ | ||
592 | uint32_t name; | ||
593 | |||
594 | /** Returned handle for the object */ | ||
595 | uint32_t handle; | ||
596 | |||
597 | /** Returned size of the object */ | ||
598 | uint64_t size; | ||
599 | }; | ||
600 | |||
576 | #define DRM_IOCTL_BASE 'd' | 601 | #define DRM_IOCTL_BASE 'd' |
577 | #define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr) | 602 | #define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr) |
578 | #define DRM_IOR(nr,type) _IOR(DRM_IOCTL_BASE,nr,type) | 603 | #define DRM_IOR(nr,type) _IOR(DRM_IOCTL_BASE,nr,type) |
@@ -587,6 +612,10 @@ struct drm_set_version { | |||
587 | #define DRM_IOCTL_GET_CLIENT DRM_IOWR(0x05, struct drm_client) | 612 | #define DRM_IOCTL_GET_CLIENT DRM_IOWR(0x05, struct drm_client) |
588 | #define DRM_IOCTL_GET_STATS DRM_IOR( 0x06, struct drm_stats) | 613 | #define DRM_IOCTL_GET_STATS DRM_IOR( 0x06, struct drm_stats) |
589 | #define DRM_IOCTL_SET_VERSION DRM_IOWR(0x07, struct drm_set_version) | 614 | #define DRM_IOCTL_SET_VERSION DRM_IOWR(0x07, struct drm_set_version) |
615 | #define DRM_IOCTL_MODESET_CTL DRM_IOW(0x08, struct drm_modeset_ctl) | ||
616 | #define DRM_IOCTL_GEM_CLOSE DRM_IOW (0x09, struct drm_gem_close) | ||
617 | #define DRM_IOCTL_GEM_FLINK DRM_IOWR(0x0a, struct drm_gem_flink) | ||
618 | #define DRM_IOCTL_GEM_OPEN DRM_IOWR(0x0b, struct drm_gem_open) | ||
590 | 619 | ||
591 | #define DRM_IOCTL_SET_UNIQUE DRM_IOW( 0x10, struct drm_unique) | 620 | #define DRM_IOCTL_SET_UNIQUE DRM_IOW( 0x10, struct drm_unique) |
592 | #define DRM_IOCTL_AUTH_MAGIC DRM_IOW( 0x11, struct drm_auth) | 621 | #define DRM_IOCTL_AUTH_MAGIC DRM_IOW( 0x11, struct drm_auth) |
diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 1c1b13e29223..59c796b46ee7 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h | |||
@@ -104,6 +104,7 @@ struct drm_device; | |||
104 | #define DRIVER_DMA_QUEUE 0x200 | 104 | #define DRIVER_DMA_QUEUE 0x200 |
105 | #define DRIVER_FB_DMA 0x400 | 105 | #define DRIVER_FB_DMA 0x400 |
106 | #define DRIVER_IRQ_VBL2 0x800 | 106 | #define DRIVER_IRQ_VBL2 0x800 |
107 | #define DRIVER_GEM 0x1000 | ||
107 | 108 | ||
108 | /***********************************************************************/ | 109 | /***********************************************************************/ |
109 | /** \name Begin the DRM... */ | 110 | /** \name Begin the DRM... */ |
@@ -387,6 +388,10 @@ struct drm_file { | |||
387 | struct drm_minor *minor; | 388 | struct drm_minor *minor; |
388 | int remove_auth_on_close; | 389 | int remove_auth_on_close; |
389 | unsigned long lock_count; | 390 | unsigned long lock_count; |
391 | /** Mapping of mm object handles to object pointers. */ | ||
392 | struct idr object_idr; | ||
393 | /** Lock for synchronization of access to object_idr. */ | ||
394 | spinlock_t table_lock; | ||
390 | struct file *filp; | 395 | struct file *filp; |
391 | void *driver_priv; | 396 | void *driver_priv; |
392 | }; | 397 | }; |
@@ -558,6 +563,56 @@ struct drm_ati_pcigart_info { | |||
558 | }; | 563 | }; |
559 | 564 | ||
560 | /** | 565 | /** |
566 | * This structure defines the drm_mm memory object, which will be used by the | ||
567 | * DRM for its buffer objects. | ||
568 | */ | ||
569 | struct drm_gem_object { | ||
570 | /** Reference count of this object */ | ||
571 | struct kref refcount; | ||
572 | |||
573 | /** Handle count of this object. Each handle also holds a reference */ | ||
574 | struct kref handlecount; | ||
575 | |||
576 | /** Related drm device */ | ||
577 | struct drm_device *dev; | ||
578 | |||
579 | /** File representing the shmem storage */ | ||
580 | struct file *filp; | ||
581 | |||
582 | /** | ||
583 | * Size of the object, in bytes. Immutable over the object's | ||
584 | * lifetime. | ||
585 | */ | ||
586 | size_t size; | ||
587 | |||
588 | /** | ||
589 | * Global name for this object, starts at 1. 0 means unnamed. | ||
590 | * Access is covered by the object_name_lock in the related drm_device | ||
591 | */ | ||
592 | int name; | ||
593 | |||
594 | /** | ||
595 | * Memory domains. These monitor which caches contain read/write data | ||
596 | * related to the object. When transitioning from one set of domains | ||
597 | * to another, the driver is called to ensure that caches are suitably | ||
598 | * flushed and invalidated | ||
599 | */ | ||
600 | uint32_t read_domains; | ||
601 | uint32_t write_domain; | ||
602 | |||
603 | /** | ||
604 | * While validating an exec operation, the | ||
605 | * new read/write domain values are computed here. | ||
606 | * They will be transferred to the above values | ||
607 | * at the point that any cache flushing occurs | ||
608 | */ | ||
609 | uint32_t pending_read_domains; | ||
610 | uint32_t pending_write_domain; | ||
611 | |||
612 | void *driver_private; | ||
613 | }; | ||
614 | |||
615 | /** | ||
561 | * DRM driver structure. This structure represent the common code for | 616 | * DRM driver structure. This structure represent the common code for |
562 | * a family of cards. There will one drm_device for each card present | 617 | * a family of cards. There will one drm_device for each card present |
563 | * in this family | 618 | * in this family |
@@ -580,11 +635,54 @@ struct drm_driver { | |||
580 | int (*kernel_context_switch) (struct drm_device *dev, int old, | 635 | int (*kernel_context_switch) (struct drm_device *dev, int old, |
581 | int new); | 636 | int new); |
582 | void (*kernel_context_switch_unlock) (struct drm_device *dev); | 637 | void (*kernel_context_switch_unlock) (struct drm_device *dev); |
583 | int (*vblank_wait) (struct drm_device *dev, unsigned int *sequence); | ||
584 | int (*vblank_wait2) (struct drm_device *dev, unsigned int *sequence); | ||
585 | int (*dri_library_name) (struct drm_device *dev, char *buf); | 638 | int (*dri_library_name) (struct drm_device *dev, char *buf); |
586 | 639 | ||
587 | /** | 640 | /** |
641 | * get_vblank_counter - get raw hardware vblank counter | ||
642 | * @dev: DRM device | ||
643 | * @crtc: counter to fetch | ||
644 | * | ||
645 | * Driver callback for fetching a raw hardware vblank counter | ||
646 | * for @crtc. If a device doesn't have a hardware counter, the | ||
647 | * driver can simply return the value of drm_vblank_count and | ||
648 | * make the enable_vblank() and disable_vblank() hooks into no-ops, | ||
649 | * leaving interrupts enabled at all times. | ||
650 | * | ||
651 | * Wraparound handling and loss of events due to modesetting is dealt | ||
652 | * with in the DRM core code. | ||
653 | * | ||
654 | * RETURNS | ||
655 | * Raw vblank counter value. | ||
656 | */ | ||
657 | u32 (*get_vblank_counter) (struct drm_device *dev, int crtc); | ||
658 | |||
659 | /** | ||
660 | * enable_vblank - enable vblank interrupt events | ||
661 | * @dev: DRM device | ||
662 | * @crtc: which irq to enable | ||
663 | * | ||
664 | * Enable vblank interrupts for @crtc. If the device doesn't have | ||
665 | * a hardware vblank counter, this routine should be a no-op, since | ||
666 | * interrupts will have to stay on to keep the count accurate. | ||
667 | * | ||
668 | * RETURNS | ||
669 | * Zero on success, appropriate errno if the given @crtc's vblank | ||
670 | * interrupt cannot be enabled. | ||
671 | */ | ||
672 | int (*enable_vblank) (struct drm_device *dev, int crtc); | ||
673 | |||
674 | /** | ||
675 | * disable_vblank - disable vblank interrupt events | ||
676 | * @dev: DRM device | ||
677 | * @crtc: which irq to enable | ||
678 | * | ||
679 | * Disable vblank interrupts for @crtc. If the device doesn't have | ||
680 | * a hardware vblank counter, this routine should be a no-op, since | ||
681 | * interrupts will have to stay on to keep the count accurate. | ||
682 | */ | ||
683 | void (*disable_vblank) (struct drm_device *dev, int crtc); | ||
684 | |||
685 | /** | ||
588 | * Called by \c drm_device_is_agp. Typically used to determine if a | 686 | * Called by \c drm_device_is_agp. Typically used to determine if a |
589 | * card is really attached to AGP or not. | 687 | * card is really attached to AGP or not. |
590 | * | 688 | * |
@@ -601,7 +699,7 @@ struct drm_driver { | |||
601 | 699 | ||
602 | irqreturn_t(*irq_handler) (DRM_IRQ_ARGS); | 700 | irqreturn_t(*irq_handler) (DRM_IRQ_ARGS); |
603 | void (*irq_preinstall) (struct drm_device *dev); | 701 | void (*irq_preinstall) (struct drm_device *dev); |
604 | void (*irq_postinstall) (struct drm_device *dev); | 702 | int (*irq_postinstall) (struct drm_device *dev); |
605 | void (*irq_uninstall) (struct drm_device *dev); | 703 | void (*irq_uninstall) (struct drm_device *dev); |
606 | void (*reclaim_buffers) (struct drm_device *dev, | 704 | void (*reclaim_buffers) (struct drm_device *dev, |
607 | struct drm_file * file_priv); | 705 | struct drm_file * file_priv); |
@@ -614,6 +712,18 @@ struct drm_driver { | |||
614 | void (*set_version) (struct drm_device *dev, | 712 | void (*set_version) (struct drm_device *dev, |
615 | struct drm_set_version *sv); | 713 | struct drm_set_version *sv); |
616 | 714 | ||
715 | int (*proc_init)(struct drm_minor *minor); | ||
716 | void (*proc_cleanup)(struct drm_minor *minor); | ||
717 | |||
718 | /** | ||
719 | * Driver-specific constructor for drm_gem_objects, to set up | ||
720 | * obj->driver_private. | ||
721 | * | ||
722 | * Returns 0 on success. | ||
723 | */ | ||
724 | int (*gem_init_object) (struct drm_gem_object *obj); | ||
725 | void (*gem_free_object) (struct drm_gem_object *obj); | ||
726 | |||
617 | int major; | 727 | int major; |
618 | int minor; | 728 | int minor; |
619 | int patchlevel; | 729 | int patchlevel; |
@@ -714,7 +824,6 @@ struct drm_device { | |||
714 | 824 | ||
715 | /** \name Context support */ | 825 | /** \name Context support */ |
716 | /*@{ */ | 826 | /*@{ */ |
717 | int irq; /**< Interrupt used by board */ | ||
718 | int irq_enabled; /**< True if irq handler is enabled */ | 827 | int irq_enabled; /**< True if irq handler is enabled */ |
719 | __volatile__ long context_flag; /**< Context swapping flag */ | 828 | __volatile__ long context_flag; /**< Context swapping flag */ |
720 | __volatile__ long interrupt_flag; /**< Interruption handler flag */ | 829 | __volatile__ long interrupt_flag; /**< Interruption handler flag */ |
@@ -730,13 +839,28 @@ struct drm_device { | |||
730 | /** \name VBLANK IRQ support */ | 839 | /** \name VBLANK IRQ support */ |
731 | /*@{ */ | 840 | /*@{ */ |
732 | 841 | ||
733 | wait_queue_head_t vbl_queue; /**< VBLANK wait queue */ | 842 | /* |
734 | atomic_t vbl_received; | 843 | * At load time, disabling the vblank interrupt won't be allowed since |
735 | atomic_t vbl_received2; /**< number of secondary VBLANK interrupts */ | 844 | * old clients may not call the modeset ioctl and therefore misbehave. |
845 | * Once the modeset ioctl *has* been called though, we can safely | ||
846 | * disable them when unused. | ||
847 | */ | ||
848 | int vblank_disable_allowed; | ||
849 | |||
850 | wait_queue_head_t *vbl_queue; /**< VBLANK wait queue */ | ||
851 | atomic_t *_vblank_count; /**< number of VBLANK interrupts (driver must alloc the right number of counters) */ | ||
736 | spinlock_t vbl_lock; | 852 | spinlock_t vbl_lock; |
737 | struct list_head vbl_sigs; /**< signal list to send on VBLANK */ | 853 | struct list_head *vbl_sigs; /**< signal list to send on VBLANK */ |
738 | struct list_head vbl_sigs2; /**< signals to send on secondary VBLANK */ | 854 | atomic_t vbl_signal_pending; /* number of signals pending on all crtcs*/ |
739 | unsigned int vbl_pending; | 855 | atomic_t *vblank_refcount; /* number of users of vblank interruptsper crtc */ |
856 | u32 *last_vblank; /* protected by dev->vbl_lock, used */ | ||
857 | /* for wraparound handling */ | ||
858 | int *vblank_enabled; /* so we don't call enable more than | ||
859 | once per disable */ | ||
860 | int *vblank_inmodeset; /* Display driver is setting mode */ | ||
861 | struct timer_list vblank_disable_timer; | ||
862 | |||
863 | u32 max_vblank_count; /**< size of vblank counter register */ | ||
740 | spinlock_t tasklet_lock; /**< For drm_locked_tasklet */ | 864 | spinlock_t tasklet_lock; /**< For drm_locked_tasklet */ |
741 | void (*locked_tasklet_func)(struct drm_device *dev); | 865 | void (*locked_tasklet_func)(struct drm_device *dev); |
742 | 866 | ||
@@ -757,6 +881,7 @@ struct drm_device { | |||
757 | struct pci_controller *hose; | 881 | struct pci_controller *hose; |
758 | #endif | 882 | #endif |
759 | struct drm_sg_mem *sg; /**< Scatter gather memory */ | 883 | struct drm_sg_mem *sg; /**< Scatter gather memory */ |
884 | int num_crtcs; /**< Number of CRTCs on this device */ | ||
760 | void *dev_private; /**< device private data */ | 885 | void *dev_private; /**< device private data */ |
761 | struct drm_sigdata sigdata; /**< For block_all_signals */ | 886 | struct drm_sigdata sigdata; /**< For block_all_signals */ |
762 | sigset_t sigmask; | 887 | sigset_t sigmask; |
@@ -771,8 +896,29 @@ struct drm_device { | |||
771 | spinlock_t drw_lock; | 896 | spinlock_t drw_lock; |
772 | struct idr drw_idr; | 897 | struct idr drw_idr; |
773 | /*@} */ | 898 | /*@} */ |
899 | |||
900 | /** \name GEM information */ | ||
901 | /*@{ */ | ||
902 | spinlock_t object_name_lock; | ||
903 | struct idr object_name_idr; | ||
904 | atomic_t object_count; | ||
905 | atomic_t object_memory; | ||
906 | atomic_t pin_count; | ||
907 | atomic_t pin_memory; | ||
908 | atomic_t gtt_count; | ||
909 | atomic_t gtt_memory; | ||
910 | uint32_t gtt_total; | ||
911 | uint32_t invalidate_domains; /* domains pending invalidation */ | ||
912 | uint32_t flush_domains; /* domains pending flush */ | ||
913 | /*@} */ | ||
914 | |||
774 | }; | 915 | }; |
775 | 916 | ||
917 | static inline int drm_dev_to_irq(struct drm_device *dev) | ||
918 | { | ||
919 | return dev->pdev->irq; | ||
920 | } | ||
921 | |||
776 | static __inline__ int drm_core_check_feature(struct drm_device *dev, | 922 | static __inline__ int drm_core_check_feature(struct drm_device *dev, |
777 | int feature) | 923 | int feature) |
778 | { | 924 | { |
@@ -867,6 +1013,11 @@ extern void *drm_realloc(void *oldpt, size_t oldsize, size_t size, int area); | |||
867 | extern DRM_AGP_MEM *drm_alloc_agp(struct drm_device *dev, int pages, u32 type); | 1013 | extern DRM_AGP_MEM *drm_alloc_agp(struct drm_device *dev, int pages, u32 type); |
868 | extern int drm_free_agp(DRM_AGP_MEM * handle, int pages); | 1014 | extern int drm_free_agp(DRM_AGP_MEM * handle, int pages); |
869 | extern int drm_bind_agp(DRM_AGP_MEM * handle, unsigned int start); | 1015 | extern int drm_bind_agp(DRM_AGP_MEM * handle, unsigned int start); |
1016 | extern DRM_AGP_MEM *drm_agp_bind_pages(struct drm_device *dev, | ||
1017 | struct page **pages, | ||
1018 | unsigned long num_pages, | ||
1019 | uint32_t gtt_offset, | ||
1020 | uint32_t type); | ||
870 | extern int drm_unbind_agp(DRM_AGP_MEM * handle); | 1021 | extern int drm_unbind_agp(DRM_AGP_MEM * handle); |
871 | 1022 | ||
872 | /* Misc. IOCTL support (drm_ioctl.h) */ | 1023 | /* Misc. IOCTL support (drm_ioctl.h) */ |
@@ -929,6 +1080,9 @@ extern int drm_getmagic(struct drm_device *dev, void *data, | |||
929 | extern int drm_authmagic(struct drm_device *dev, void *data, | 1080 | extern int drm_authmagic(struct drm_device *dev, void *data, |
930 | struct drm_file *file_priv); | 1081 | struct drm_file *file_priv); |
931 | 1082 | ||
1083 | /* Cache management (drm_cache.c) */ | ||
1084 | void drm_clflush_pages(struct page *pages[], unsigned long num_pages); | ||
1085 | |||
932 | /* Locking IOCTL support (drm_lock.h) */ | 1086 | /* Locking IOCTL support (drm_lock.h) */ |
933 | extern int drm_lock(struct drm_device *dev, void *data, | 1087 | extern int drm_lock(struct drm_device *dev, void *data, |
934 | struct drm_file *file_priv); | 1088 | struct drm_file *file_priv); |
@@ -985,15 +1139,25 @@ extern void drm_core_reclaim_buffers(struct drm_device *dev, | |||
985 | extern int drm_control(struct drm_device *dev, void *data, | 1139 | extern int drm_control(struct drm_device *dev, void *data, |
986 | struct drm_file *file_priv); | 1140 | struct drm_file *file_priv); |
987 | extern irqreturn_t drm_irq_handler(DRM_IRQ_ARGS); | 1141 | extern irqreturn_t drm_irq_handler(DRM_IRQ_ARGS); |
1142 | extern int drm_irq_install(struct drm_device *dev); | ||
988 | extern int drm_irq_uninstall(struct drm_device *dev); | 1143 | extern int drm_irq_uninstall(struct drm_device *dev); |
989 | extern void drm_driver_irq_preinstall(struct drm_device *dev); | 1144 | extern void drm_driver_irq_preinstall(struct drm_device *dev); |
990 | extern void drm_driver_irq_postinstall(struct drm_device *dev); | 1145 | extern void drm_driver_irq_postinstall(struct drm_device *dev); |
991 | extern void drm_driver_irq_uninstall(struct drm_device *dev); | 1146 | extern void drm_driver_irq_uninstall(struct drm_device *dev); |
992 | 1147 | ||
1148 | extern int drm_vblank_init(struct drm_device *dev, int num_crtcs); | ||
993 | extern int drm_wait_vblank(struct drm_device *dev, void *data, | 1149 | extern int drm_wait_vblank(struct drm_device *dev, void *data, |
994 | struct drm_file *file_priv); | 1150 | struct drm_file *filp); |
995 | extern int drm_vblank_wait(struct drm_device *dev, unsigned int *vbl_seq); | 1151 | extern int drm_vblank_wait(struct drm_device *dev, unsigned int *vbl_seq); |
996 | extern void drm_vbl_send_signals(struct drm_device *dev); | 1152 | extern void drm_locked_tasklet(struct drm_device *dev, |
1153 | void(*func)(struct drm_device *)); | ||
1154 | extern u32 drm_vblank_count(struct drm_device *dev, int crtc); | ||
1155 | extern void drm_handle_vblank(struct drm_device *dev, int crtc); | ||
1156 | extern int drm_vblank_get(struct drm_device *dev, int crtc); | ||
1157 | extern void drm_vblank_put(struct drm_device *dev, int crtc); | ||
1158 | /* Modesetting support */ | ||
1159 | extern int drm_modeset_ctl(struct drm_device *dev, void *data, | ||
1160 | struct drm_file *file_priv); | ||
997 | extern void drm_locked_tasklet(struct drm_device *dev, void(*func)(struct drm_device*)); | 1161 | extern void drm_locked_tasklet(struct drm_device *dev, void(*func)(struct drm_device*)); |
998 | 1162 | ||
999 | /* AGP/GART support (drm_agpsupport.h) */ | 1163 | /* AGP/GART support (drm_agpsupport.h) */ |
@@ -1026,6 +1190,7 @@ extern DRM_AGP_MEM *drm_agp_allocate_memory(struct agp_bridge_data *bridge, size | |||
1026 | extern int drm_agp_free_memory(DRM_AGP_MEM * handle); | 1190 | extern int drm_agp_free_memory(DRM_AGP_MEM * handle); |
1027 | extern int drm_agp_bind_memory(DRM_AGP_MEM * handle, off_t start); | 1191 | extern int drm_agp_bind_memory(DRM_AGP_MEM * handle, off_t start); |
1028 | extern int drm_agp_unbind_memory(DRM_AGP_MEM * handle); | 1192 | extern int drm_agp_unbind_memory(DRM_AGP_MEM * handle); |
1193 | extern void drm_agp_chipset_flush(struct drm_device *dev); | ||
1029 | 1194 | ||
1030 | /* Stub support (drm_stub.h) */ | 1195 | /* Stub support (drm_stub.h) */ |
1031 | extern int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, | 1196 | extern int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, |
@@ -1088,6 +1253,66 @@ extern unsigned long drm_mm_tail_space(struct drm_mm *mm); | |||
1088 | extern int drm_mm_remove_space_from_tail(struct drm_mm *mm, unsigned long size); | 1253 | extern int drm_mm_remove_space_from_tail(struct drm_mm *mm, unsigned long size); |
1089 | extern int drm_mm_add_space_to_tail(struct drm_mm *mm, unsigned long size); | 1254 | extern int drm_mm_add_space_to_tail(struct drm_mm *mm, unsigned long size); |
1090 | 1255 | ||
1256 | /* Graphics Execution Manager library functions (drm_gem.c) */ | ||
1257 | int drm_gem_init(struct drm_device *dev); | ||
1258 | void drm_gem_object_free(struct kref *kref); | ||
1259 | struct drm_gem_object *drm_gem_object_alloc(struct drm_device *dev, | ||
1260 | size_t size); | ||
1261 | void drm_gem_object_handle_free(struct kref *kref); | ||
1262 | |||
1263 | static inline void | ||
1264 | drm_gem_object_reference(struct drm_gem_object *obj) | ||
1265 | { | ||
1266 | kref_get(&obj->refcount); | ||
1267 | } | ||
1268 | |||
1269 | static inline void | ||
1270 | drm_gem_object_unreference(struct drm_gem_object *obj) | ||
1271 | { | ||
1272 | if (obj == NULL) | ||
1273 | return; | ||
1274 | |||
1275 | kref_put(&obj->refcount, drm_gem_object_free); | ||
1276 | } | ||
1277 | |||
1278 | int drm_gem_handle_create(struct drm_file *file_priv, | ||
1279 | struct drm_gem_object *obj, | ||
1280 | int *handlep); | ||
1281 | |||
1282 | static inline void | ||
1283 | drm_gem_object_handle_reference(struct drm_gem_object *obj) | ||
1284 | { | ||
1285 | drm_gem_object_reference(obj); | ||
1286 | kref_get(&obj->handlecount); | ||
1287 | } | ||
1288 | |||
1289 | static inline void | ||
1290 | drm_gem_object_handle_unreference(struct drm_gem_object *obj) | ||
1291 | { | ||
1292 | if (obj == NULL) | ||
1293 | return; | ||
1294 | |||
1295 | /* | ||
1296 | * Must bump handle count first as this may be the last | ||
1297 | * ref, in which case the object would disappear before we | ||
1298 | * checked for a name | ||
1299 | */ | ||
1300 | kref_put(&obj->handlecount, drm_gem_object_handle_free); | ||
1301 | drm_gem_object_unreference(obj); | ||
1302 | } | ||
1303 | |||
1304 | struct drm_gem_object *drm_gem_object_lookup(struct drm_device *dev, | ||
1305 | struct drm_file *filp, | ||
1306 | int handle); | ||
1307 | int drm_gem_close_ioctl(struct drm_device *dev, void *data, | ||
1308 | struct drm_file *file_priv); | ||
1309 | int drm_gem_flink_ioctl(struct drm_device *dev, void *data, | ||
1310 | struct drm_file *file_priv); | ||
1311 | int drm_gem_open_ioctl(struct drm_device *dev, void *data, | ||
1312 | struct drm_file *file_priv); | ||
1313 | void drm_gem_open(struct drm_device *dev, struct drm_file *file_private); | ||
1314 | void drm_gem_release(struct drm_device *dev, struct drm_file *file_private); | ||
1315 | |||
1091 | extern void drm_core_ioremap(struct drm_map *map, struct drm_device *dev); | 1316 | extern void drm_core_ioremap(struct drm_map *map, struct drm_device *dev); |
1092 | extern void drm_core_ioremap_wc(struct drm_map *map, struct drm_device *dev); | 1317 | extern void drm_core_ioremap_wc(struct drm_map *map, struct drm_device *dev); |
1093 | extern void drm_core_ioremapfree(struct drm_map *map, struct drm_device *dev); | 1318 | extern void drm_core_ioremapfree(struct drm_map *map, struct drm_device *dev); |
diff --git a/include/drm/drm_pciids.h b/include/drm/drm_pciids.h index 135bd19499fc..da04109741e8 100644 --- a/include/drm/drm_pciids.h +++ b/include/drm/drm_pciids.h | |||
@@ -84,18 +84,18 @@ | |||
84 | {0x1002, 0x5462, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \ | 84 | {0x1002, 0x5462, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \ |
85 | {0x1002, 0x5464, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \ | 85 | {0x1002, 0x5464, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \ |
86 | {0x1002, 0x5657, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \ | 86 | {0x1002, 0x5657, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \ |
87 | {0x1002, 0x5548, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ | 87 | {0x1002, 0x5548, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \ |
88 | {0x1002, 0x5549, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ | 88 | {0x1002, 0x5549, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \ |
89 | {0x1002, 0x554A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ | 89 | {0x1002, 0x554A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \ |
90 | {0x1002, 0x554B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ | 90 | {0x1002, 0x554B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \ |
91 | {0x1002, 0x554C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ | 91 | {0x1002, 0x554C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \ |
92 | {0x1002, 0x554D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ | 92 | {0x1002, 0x554D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \ |
93 | {0x1002, 0x554E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ | 93 | {0x1002, 0x554E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \ |
94 | {0x1002, 0x554F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ | 94 | {0x1002, 0x554F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \ |
95 | {0x1002, 0x5550, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ | 95 | {0x1002, 0x5550, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \ |
96 | {0x1002, 0x5551, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ | 96 | {0x1002, 0x5551, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \ |
97 | {0x1002, 0x5552, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ | 97 | {0x1002, 0x5552, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \ |
98 | {0x1002, 0x5554, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ | 98 | {0x1002, 0x5554, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \ |
99 | {0x1002, 0x564A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ | 99 | {0x1002, 0x564A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ |
100 | {0x1002, 0x564B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ | 100 | {0x1002, 0x564B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ |
101 | {0x1002, 0x564F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ | 101 | {0x1002, 0x564F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ |
@@ -113,8 +113,10 @@ | |||
113 | {0x1002, 0x5964, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ | 113 | {0x1002, 0x5964, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ |
114 | {0x1002, 0x5965, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ | 114 | {0x1002, 0x5965, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ |
115 | {0x1002, 0x5969, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \ | 115 | {0x1002, 0x5969, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \ |
116 | {0x1002, 0x5a61, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS480|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \ | 116 | {0x1002, 0x5a41, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_IGPGART}, \ |
117 | {0x1002, 0x5a62, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS480|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \ | 117 | {0x1002, 0x5a42, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \ |
118 | {0x1002, 0x5a61, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_IGPGART}, \ | ||
119 | {0x1002, 0x5a62, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \ | ||
118 | {0x1002, 0x5b60, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \ | 120 | {0x1002, 0x5b60, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \ |
119 | {0x1002, 0x5b62, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \ | 121 | {0x1002, 0x5b62, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \ |
120 | {0x1002, 0x5b63, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \ | 122 | {0x1002, 0x5b63, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \ |
@@ -122,16 +124,16 @@ | |||
122 | {0x1002, 0x5b65, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \ | 124 | {0x1002, 0x5b65, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \ |
123 | {0x1002, 0x5c61, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|RADEON_IS_MOBILITY}, \ | 125 | {0x1002, 0x5c61, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|RADEON_IS_MOBILITY}, \ |
124 | {0x1002, 0x5c63, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|RADEON_IS_MOBILITY}, \ | 126 | {0x1002, 0x5c63, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|RADEON_IS_MOBILITY}, \ |
125 | {0x1002, 0x5d48, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ | 127 | {0x1002, 0x5d48, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ |
126 | {0x1002, 0x5d49, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ | 128 | {0x1002, 0x5d49, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ |
127 | {0x1002, 0x5d4a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ | 129 | {0x1002, 0x5d4a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ |
128 | {0x1002, 0x5d4c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ | 130 | {0x1002, 0x5d4c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \ |
129 | {0x1002, 0x5d4d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ | 131 | {0x1002, 0x5d4d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \ |
130 | {0x1002, 0x5d4e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ | 132 | {0x1002, 0x5d4e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \ |
131 | {0x1002, 0x5d4f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ | 133 | {0x1002, 0x5d4f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \ |
132 | {0x1002, 0x5d50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ | 134 | {0x1002, 0x5d50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \ |
133 | {0x1002, 0x5d52, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ | 135 | {0x1002, 0x5d52, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \ |
134 | {0x1002, 0x5d57, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ | 136 | {0x1002, 0x5d57, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \ |
135 | {0x1002, 0x5e48, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_NEW_MEMMAP}, \ | 137 | {0x1002, 0x5e48, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_NEW_MEMMAP}, \ |
136 | {0x1002, 0x5e4a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_NEW_MEMMAP}, \ | 138 | {0x1002, 0x5e4a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_NEW_MEMMAP}, \ |
137 | {0x1002, 0x5e4b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_NEW_MEMMAP}, \ | 139 | {0x1002, 0x5e4b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_NEW_MEMMAP}, \ |
@@ -237,6 +239,10 @@ | |||
237 | {0x1002, 0x7835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ | 239 | {0x1002, 0x7835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ |
238 | {0x1002, 0x791e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS690|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART}, \ | 240 | {0x1002, 0x791e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS690|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART}, \ |
239 | {0x1002, 0x791f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS690|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART}, \ | 241 | {0x1002, 0x791f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS690|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART}, \ |
242 | {0x1002, 0x796c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS740|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART}, \ | ||
243 | {0x1002, 0x796d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS740|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART}, \ | ||
244 | {0x1002, 0x796e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS740|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART}, \ | ||
245 | {0x1002, 0x796f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS740|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART}, \ | ||
240 | {0, 0, 0} | 246 | {0, 0, 0} |
241 | 247 | ||
242 | #define r128_PCI_IDS \ | 248 | #define r128_PCI_IDS \ |
diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h index 05c66cf03a9e..eb4b35031a55 100644 --- a/include/drm/i915_drm.h +++ b/include/drm/i915_drm.h | |||
@@ -143,6 +143,22 @@ typedef struct _drm_i915_sarea { | |||
143 | #define DRM_I915_GET_VBLANK_PIPE 0x0e | 143 | #define DRM_I915_GET_VBLANK_PIPE 0x0e |
144 | #define DRM_I915_VBLANK_SWAP 0x0f | 144 | #define DRM_I915_VBLANK_SWAP 0x0f |
145 | #define DRM_I915_HWS_ADDR 0x11 | 145 | #define DRM_I915_HWS_ADDR 0x11 |
146 | #define DRM_I915_GEM_INIT 0x13 | ||
147 | #define DRM_I915_GEM_EXECBUFFER 0x14 | ||
148 | #define DRM_I915_GEM_PIN 0x15 | ||
149 | #define DRM_I915_GEM_UNPIN 0x16 | ||
150 | #define DRM_I915_GEM_BUSY 0x17 | ||
151 | #define DRM_I915_GEM_THROTTLE 0x18 | ||
152 | #define DRM_I915_GEM_ENTERVT 0x19 | ||
153 | #define DRM_I915_GEM_LEAVEVT 0x1a | ||
154 | #define DRM_I915_GEM_CREATE 0x1b | ||
155 | #define DRM_I915_GEM_PREAD 0x1c | ||
156 | #define DRM_I915_GEM_PWRITE 0x1d | ||
157 | #define DRM_I915_GEM_MMAP 0x1e | ||
158 | #define DRM_I915_GEM_SET_DOMAIN 0x1f | ||
159 | #define DRM_I915_GEM_SW_FINISH 0x20 | ||
160 | #define DRM_I915_GEM_SET_TILING 0x21 | ||
161 | #define DRM_I915_GEM_GET_TILING 0x22 | ||
146 | 162 | ||
147 | #define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t) | 163 | #define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t) |
148 | #define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH) | 164 | #define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH) |
@@ -160,6 +176,20 @@ typedef struct _drm_i915_sarea { | |||
160 | #define DRM_IOCTL_I915_SET_VBLANK_PIPE DRM_IOW( DRM_COMMAND_BASE + DRM_I915_SET_VBLANK_PIPE, drm_i915_vblank_pipe_t) | 176 | #define DRM_IOCTL_I915_SET_VBLANK_PIPE DRM_IOW( DRM_COMMAND_BASE + DRM_I915_SET_VBLANK_PIPE, drm_i915_vblank_pipe_t) |
161 | #define DRM_IOCTL_I915_GET_VBLANK_PIPE DRM_IOR( DRM_COMMAND_BASE + DRM_I915_GET_VBLANK_PIPE, drm_i915_vblank_pipe_t) | 177 | #define DRM_IOCTL_I915_GET_VBLANK_PIPE DRM_IOR( DRM_COMMAND_BASE + DRM_I915_GET_VBLANK_PIPE, drm_i915_vblank_pipe_t) |
162 | #define DRM_IOCTL_I915_VBLANK_SWAP DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_VBLANK_SWAP, drm_i915_vblank_swap_t) | 178 | #define DRM_IOCTL_I915_VBLANK_SWAP DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_VBLANK_SWAP, drm_i915_vblank_swap_t) |
179 | #define DRM_IOCTL_I915_GEM_PIN DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_PIN, struct drm_i915_gem_pin) | ||
180 | #define DRM_IOCTL_I915_GEM_UNPIN DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_UNPIN, struct drm_i915_gem_unpin) | ||
181 | #define DRM_IOCTL_I915_GEM_BUSY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_BUSY, struct drm_i915_gem_busy) | ||
182 | #define DRM_IOCTL_I915_GEM_THROTTLE DRM_IO ( DRM_COMMAND_BASE + DRM_I915_GEM_THROTTLE) | ||
183 | #define DRM_IOCTL_I915_GEM_ENTERVT DRM_IO(DRM_COMMAND_BASE + DRM_I915_GEM_ENTERVT) | ||
184 | #define DRM_IOCTL_I915_GEM_LEAVEVT DRM_IO(DRM_COMMAND_BASE + DRM_I915_GEM_LEAVEVT) | ||
185 | #define DRM_IOCTL_I915_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_CREATE, struct drm_i915_gem_create) | ||
186 | #define DRM_IOCTL_I915_GEM_PREAD DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_PREAD, struct drm_i915_gem_pread) | ||
187 | #define DRM_IOCTL_I915_GEM_PWRITE DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_PWRITE, struct drm_i915_gem_pwrite) | ||
188 | #define DRM_IOCTL_I915_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MMAP, struct drm_i915_gem_mmap) | ||
189 | #define DRM_IOCTL_I915_GEM_SET_DOMAIN DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_SET_DOMAIN, struct drm_i915_gem_set_domain) | ||
190 | #define DRM_IOCTL_I915_GEM_SW_FINISH DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_SW_FINISH, struct drm_i915_gem_sw_finish) | ||
191 | #define DRM_IOCTL_I915_GEM_SET_TILING DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_SET_TILING, struct drm_i915_gem_set_tiling) | ||
192 | #define DRM_IOCTL_I915_GEM_GET_TILING DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_GET_TILING, struct drm_i915_gem_get_tiling) | ||
163 | 193 | ||
164 | /* Allow drivers to submit batchbuffers directly to hardware, relying | 194 | /* Allow drivers to submit batchbuffers directly to hardware, relying |
165 | * on the security mechanisms provided by hardware. | 195 | * on the security mechanisms provided by hardware. |
@@ -200,6 +230,8 @@ typedef struct drm_i915_irq_wait { | |||
200 | #define I915_PARAM_IRQ_ACTIVE 1 | 230 | #define I915_PARAM_IRQ_ACTIVE 1 |
201 | #define I915_PARAM_ALLOW_BATCHBUFFER 2 | 231 | #define I915_PARAM_ALLOW_BATCHBUFFER 2 |
202 | #define I915_PARAM_LAST_DISPATCH 3 | 232 | #define I915_PARAM_LAST_DISPATCH 3 |
233 | #define I915_PARAM_CHIPSET_ID 4 | ||
234 | #define I915_PARAM_HAS_GEM 5 | ||
203 | 235 | ||
204 | typedef struct drm_i915_getparam { | 236 | typedef struct drm_i915_getparam { |
205 | int param; | 237 | int param; |
@@ -267,4 +299,305 @@ typedef struct drm_i915_hws_addr { | |||
267 | uint64_t addr; | 299 | uint64_t addr; |
268 | } drm_i915_hws_addr_t; | 300 | } drm_i915_hws_addr_t; |
269 | 301 | ||
302 | struct drm_i915_gem_init { | ||
303 | /** | ||
304 | * Beginning offset in the GTT to be managed by the DRM memory | ||
305 | * manager. | ||
306 | */ | ||
307 | uint64_t gtt_start; | ||
308 | /** | ||
309 | * Ending offset in the GTT to be managed by the DRM memory | ||
310 | * manager. | ||
311 | */ | ||
312 | uint64_t gtt_end; | ||
313 | }; | ||
314 | |||
315 | struct drm_i915_gem_create { | ||
316 | /** | ||
317 | * Requested size for the object. | ||
318 | * | ||
319 | * The (page-aligned) allocated size for the object will be returned. | ||
320 | */ | ||
321 | uint64_t size; | ||
322 | /** | ||
323 | * Returned handle for the object. | ||
324 | * | ||
325 | * Object handles are nonzero. | ||
326 | */ | ||
327 | uint32_t handle; | ||
328 | uint32_t pad; | ||
329 | }; | ||
330 | |||
331 | struct drm_i915_gem_pread { | ||
332 | /** Handle for the object being read. */ | ||
333 | uint32_t handle; | ||
334 | uint32_t pad; | ||
335 | /** Offset into the object to read from */ | ||
336 | uint64_t offset; | ||
337 | /** Length of data to read */ | ||
338 | uint64_t size; | ||
339 | /** | ||
340 | * Pointer to write the data into. | ||
341 | * | ||
342 | * This is a fixed-size type for 32/64 compatibility. | ||
343 | */ | ||
344 | uint64_t data_ptr; | ||
345 | }; | ||
346 | |||
347 | struct drm_i915_gem_pwrite { | ||
348 | /** Handle for the object being written to. */ | ||
349 | uint32_t handle; | ||
350 | uint32_t pad; | ||
351 | /** Offset into the object to write to */ | ||
352 | uint64_t offset; | ||
353 | /** Length of data to write */ | ||
354 | uint64_t size; | ||
355 | /** | ||
356 | * Pointer to read the data from. | ||
357 | * | ||
358 | * This is a fixed-size type for 32/64 compatibility. | ||
359 | */ | ||
360 | uint64_t data_ptr; | ||
361 | }; | ||
362 | |||
363 | struct drm_i915_gem_mmap { | ||
364 | /** Handle for the object being mapped. */ | ||
365 | uint32_t handle; | ||
366 | uint32_t pad; | ||
367 | /** Offset in the object to map. */ | ||
368 | uint64_t offset; | ||
369 | /** | ||
370 | * Length of data to map. | ||
371 | * | ||
372 | * The value will be page-aligned. | ||
373 | */ | ||
374 | uint64_t size; | ||
375 | /** | ||
376 | * Returned pointer the data was mapped at. | ||
377 | * | ||
378 | * This is a fixed-size type for 32/64 compatibility. | ||
379 | */ | ||
380 | uint64_t addr_ptr; | ||
381 | }; | ||
382 | |||
383 | struct drm_i915_gem_set_domain { | ||
384 | /** Handle for the object */ | ||
385 | uint32_t handle; | ||
386 | |||
387 | /** New read domains */ | ||
388 | uint32_t read_domains; | ||
389 | |||
390 | /** New write domain */ | ||
391 | uint32_t write_domain; | ||
392 | }; | ||
393 | |||
394 | struct drm_i915_gem_sw_finish { | ||
395 | /** Handle for the object */ | ||
396 | uint32_t handle; | ||
397 | }; | ||
398 | |||
399 | struct drm_i915_gem_relocation_entry { | ||
400 | /** | ||
401 | * Handle of the buffer being pointed to by this relocation entry. | ||
402 | * | ||
403 | * It's appealing to make this be an index into the mm_validate_entry | ||
404 | * list to refer to the buffer, but this allows the driver to create | ||
405 | * a relocation list for state buffers and not re-write it per | ||
406 | * exec using the buffer. | ||
407 | */ | ||
408 | uint32_t target_handle; | ||
409 | |||
410 | /** | ||
411 | * Value to be added to the offset of the target buffer to make up | ||
412 | * the relocation entry. | ||
413 | */ | ||
414 | uint32_t delta; | ||
415 | |||
416 | /** Offset in the buffer the relocation entry will be written into */ | ||
417 | uint64_t offset; | ||
418 | |||
419 | /** | ||
420 | * Offset value of the target buffer that the relocation entry was last | ||
421 | * written as. | ||
422 | * | ||
423 | * If the buffer has the same offset as last time, we can skip syncing | ||
424 | * and writing the relocation. This value is written back out by | ||
425 | * the execbuffer ioctl when the relocation is written. | ||
426 | */ | ||
427 | uint64_t presumed_offset; | ||
428 | |||
429 | /** | ||
430 | * Target memory domains read by this operation. | ||
431 | */ | ||
432 | uint32_t read_domains; | ||
433 | |||
434 | /** | ||
435 | * Target memory domains written by this operation. | ||
436 | * | ||
437 | * Note that only one domain may be written by the whole | ||
438 | * execbuffer operation, so that where there are conflicts, | ||
439 | * the application will get -EINVAL back. | ||
440 | */ | ||
441 | uint32_t write_domain; | ||
442 | }; | ||
443 | |||
444 | /** @{ | ||
445 | * Intel memory domains | ||
446 | * | ||
447 | * Most of these just align with the various caches in | ||
448 | * the system and are used to flush and invalidate as | ||
449 | * objects end up cached in different domains. | ||
450 | */ | ||
451 | /** CPU cache */ | ||
452 | #define I915_GEM_DOMAIN_CPU 0x00000001 | ||
453 | /** Render cache, used by 2D and 3D drawing */ | ||
454 | #define I915_GEM_DOMAIN_RENDER 0x00000002 | ||
455 | /** Sampler cache, used by texture engine */ | ||
456 | #define I915_GEM_DOMAIN_SAMPLER 0x00000004 | ||
457 | /** Command queue, used to load batch buffers */ | ||
458 | #define I915_GEM_DOMAIN_COMMAND 0x00000008 | ||
459 | /** Instruction cache, used by shader programs */ | ||
460 | #define I915_GEM_DOMAIN_INSTRUCTION 0x00000010 | ||
461 | /** Vertex address cache */ | ||
462 | #define I915_GEM_DOMAIN_VERTEX 0x00000020 | ||
463 | /** GTT domain - aperture and scanout */ | ||
464 | #define I915_GEM_DOMAIN_GTT 0x00000040 | ||
465 | /** @} */ | ||
466 | |||
467 | struct drm_i915_gem_exec_object { | ||
468 | /** | ||
469 | * User's handle for a buffer to be bound into the GTT for this | ||
470 | * operation. | ||
471 | */ | ||
472 | uint32_t handle; | ||
473 | |||
474 | /** Number of relocations to be performed on this buffer */ | ||
475 | uint32_t relocation_count; | ||
476 | /** | ||
477 | * Pointer to array of struct drm_i915_gem_relocation_entry containing | ||
478 | * the relocations to be performed in this buffer. | ||
479 | */ | ||
480 | uint64_t relocs_ptr; | ||
481 | |||
482 | /** Required alignment in graphics aperture */ | ||
483 | uint64_t alignment; | ||
484 | |||
485 | /** | ||
486 | * Returned value of the updated offset of the object, for future | ||
487 | * presumed_offset writes. | ||
488 | */ | ||
489 | uint64_t offset; | ||
490 | }; | ||
491 | |||
492 | struct drm_i915_gem_execbuffer { | ||
493 | /** | ||
494 | * List of buffers to be validated with their relocations to be | ||
495 | * performend on them. | ||
496 | * | ||
497 | * This is a pointer to an array of struct drm_i915_gem_validate_entry. | ||
498 | * | ||
499 | * These buffers must be listed in an order such that all relocations | ||
500 | * a buffer is performing refer to buffers that have already appeared | ||
501 | * in the validate list. | ||
502 | */ | ||
503 | uint64_t buffers_ptr; | ||
504 | uint32_t buffer_count; | ||
505 | |||
506 | /** Offset in the batchbuffer to start execution from. */ | ||
507 | uint32_t batch_start_offset; | ||
508 | /** Bytes used in batchbuffer from batch_start_offset */ | ||
509 | uint32_t batch_len; | ||
510 | uint32_t DR1; | ||
511 | uint32_t DR4; | ||
512 | uint32_t num_cliprects; | ||
513 | /** This is a struct drm_clip_rect *cliprects */ | ||
514 | uint64_t cliprects_ptr; | ||
515 | }; | ||
516 | |||
517 | struct drm_i915_gem_pin { | ||
518 | /** Handle of the buffer to be pinned. */ | ||
519 | uint32_t handle; | ||
520 | uint32_t pad; | ||
521 | |||
522 | /** alignment required within the aperture */ | ||
523 | uint64_t alignment; | ||
524 | |||
525 | /** Returned GTT offset of the buffer. */ | ||
526 | uint64_t offset; | ||
527 | }; | ||
528 | |||
529 | struct drm_i915_gem_unpin { | ||
530 | /** Handle of the buffer to be unpinned. */ | ||
531 | uint32_t handle; | ||
532 | uint32_t pad; | ||
533 | }; | ||
534 | |||
535 | struct drm_i915_gem_busy { | ||
536 | /** Handle of the buffer to check for busy */ | ||
537 | uint32_t handle; | ||
538 | |||
539 | /** Return busy status (1 if busy, 0 if idle) */ | ||
540 | uint32_t busy; | ||
541 | }; | ||
542 | |||
543 | #define I915_TILING_NONE 0 | ||
544 | #define I915_TILING_X 1 | ||
545 | #define I915_TILING_Y 2 | ||
546 | |||
547 | #define I915_BIT_6_SWIZZLE_NONE 0 | ||
548 | #define I915_BIT_6_SWIZZLE_9 1 | ||
549 | #define I915_BIT_6_SWIZZLE_9_10 2 | ||
550 | #define I915_BIT_6_SWIZZLE_9_11 3 | ||
551 | #define I915_BIT_6_SWIZZLE_9_10_11 4 | ||
552 | /* Not seen by userland */ | ||
553 | #define I915_BIT_6_SWIZZLE_UNKNOWN 5 | ||
554 | |||
555 | struct drm_i915_gem_set_tiling { | ||
556 | /** Handle of the buffer to have its tiling state updated */ | ||
557 | uint32_t handle; | ||
558 | |||
559 | /** | ||
560 | * Tiling mode for the object (I915_TILING_NONE, I915_TILING_X, | ||
561 | * I915_TILING_Y). | ||
562 | * | ||
563 | * This value is to be set on request, and will be updated by the | ||
564 | * kernel on successful return with the actual chosen tiling layout. | ||
565 | * | ||
566 | * The tiling mode may be demoted to I915_TILING_NONE when the system | ||
567 | * has bit 6 swizzling that can't be managed correctly by GEM. | ||
568 | * | ||
569 | * Buffer contents become undefined when changing tiling_mode. | ||
570 | */ | ||
571 | uint32_t tiling_mode; | ||
572 | |||
573 | /** | ||
574 | * Stride in bytes for the object when in I915_TILING_X or | ||
575 | * I915_TILING_Y. | ||
576 | */ | ||
577 | uint32_t stride; | ||
578 | |||
579 | /** | ||
580 | * Returned address bit 6 swizzling required for CPU access through | ||
581 | * mmap mapping. | ||
582 | */ | ||
583 | uint32_t swizzle_mode; | ||
584 | }; | ||
585 | |||
586 | struct drm_i915_gem_get_tiling { | ||
587 | /** Handle of the buffer to get tiling state for. */ | ||
588 | uint32_t handle; | ||
589 | |||
590 | /** | ||
591 | * Current tiling mode for the object (I915_TILING_NONE, I915_TILING_X, | ||
592 | * I915_TILING_Y). | ||
593 | */ | ||
594 | uint32_t tiling_mode; | ||
595 | |||
596 | /** | ||
597 | * Returned address bit 6 swizzling required for CPU access through | ||
598 | * mmap mapping. | ||
599 | */ | ||
600 | uint32_t swizzle_mode; | ||
601 | }; | ||
602 | |||
270 | #endif /* _I915_DRM_H_ */ | 603 | #endif /* _I915_DRM_H_ */ |
diff --git a/include/linux/dvb/frontend.h b/include/linux/dvb/frontend.h index 6e4ace270276..79a8ed8e6a7d 100644 --- a/include/linux/dvb/frontend.h +++ b/include/linux/dvb/frontend.h | |||
@@ -166,6 +166,7 @@ typedef enum fe_modulation { | |||
166 | VSB_16, | 166 | VSB_16, |
167 | PSK_8, | 167 | PSK_8, |
168 | APSK_16, | 168 | APSK_16, |
169 | APSK_32, | ||
169 | DQPSK, | 170 | DQPSK, |
170 | } fe_modulation_t; | 171 | } fe_modulation_t; |
171 | 172 | ||
@@ -295,6 +296,7 @@ typedef enum fe_delivery_system { | |||
295 | SYS_DVBC_ANNEX_AC, | 296 | SYS_DVBC_ANNEX_AC, |
296 | SYS_DVBC_ANNEX_B, | 297 | SYS_DVBC_ANNEX_B, |
297 | SYS_DVBT, | 298 | SYS_DVBT, |
299 | SYS_DSS, | ||
298 | SYS_DVBS, | 300 | SYS_DVBS, |
299 | SYS_DVBS2, | 301 | SYS_DVBS2, |
300 | SYS_DVBH, | 302 | SYS_DVBH, |
diff --git a/include/linux/i2c-id.h b/include/linux/i2c-id.h index 493435bcdbe5..01d67ba9e985 100644 --- a/include/linux/i2c-id.h +++ b/include/linux/i2c-id.h | |||
@@ -60,7 +60,7 @@ | |||
60 | #define I2C_DRIVERID_WM8775 69 /* wm8775 audio processor */ | 60 | #define I2C_DRIVERID_WM8775 69 /* wm8775 audio processor */ |
61 | #define I2C_DRIVERID_CS53L32A 70 /* cs53l32a audio processor */ | 61 | #define I2C_DRIVERID_CS53L32A 70 /* cs53l32a audio processor */ |
62 | #define I2C_DRIVERID_CX25840 71 /* cx2584x video encoder */ | 62 | #define I2C_DRIVERID_CX25840 71 /* cx2584x video encoder */ |
63 | #define I2C_DRIVERID_SAA7127 72 /* saa7124 video encoder */ | 63 | #define I2C_DRIVERID_SAA7127 72 /* saa7127 video encoder */ |
64 | #define I2C_DRIVERID_SAA711X 73 /* saa711x video encoders */ | 64 | #define I2C_DRIVERID_SAA711X 73 /* saa711x video encoders */ |
65 | #define I2C_DRIVERID_AKITAIOEXP 74 /* IO Expander on Sharp SL-C1000 */ | 65 | #define I2C_DRIVERID_AKITAIOEXP 74 /* IO Expander on Sharp SL-C1000 */ |
66 | #define I2C_DRIVERID_INFRARED 75 /* I2C InfraRed on Video boards */ | 66 | #define I2C_DRIVERID_INFRARED 75 /* I2C InfraRed on Video boards */ |
diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h index 463d6f10b64f..c7d106ef22e2 100644 --- a/include/linux/jbd2.h +++ b/include/linux/jbd2.h | |||
@@ -641,6 +641,11 @@ struct transaction_s | |||
641 | */ | 641 | */ |
642 | int t_handle_count; | 642 | int t_handle_count; |
643 | 643 | ||
644 | /* | ||
645 | * For use by the filesystem to store fs-specific data | ||
646 | * structures associated with the transaction | ||
647 | */ | ||
648 | struct list_head t_private_list; | ||
644 | }; | 649 | }; |
645 | 650 | ||
646 | struct transaction_run_stats_s { | 651 | struct transaction_run_stats_s { |
@@ -935,6 +940,10 @@ struct journal_s | |||
935 | 940 | ||
936 | pid_t j_last_sync_writer; | 941 | pid_t j_last_sync_writer; |
937 | 942 | ||
943 | /* This function is called when a transaction is closed */ | ||
944 | void (*j_commit_callback)(journal_t *, | ||
945 | transaction_t *); | ||
946 | |||
938 | /* | 947 | /* |
939 | * Journal statistics | 948 | * Journal statistics |
940 | */ | 949 | */ |
diff --git a/include/linux/writeback.h b/include/linux/writeback.h index 12b15c561a1f..e585657e9831 100644 --- a/include/linux/writeback.h +++ b/include/linux/writeback.h | |||
@@ -63,7 +63,15 @@ struct writeback_control { | |||
63 | unsigned for_writepages:1; /* This is a writepages() call */ | 63 | unsigned for_writepages:1; /* This is a writepages() call */ |
64 | unsigned range_cyclic:1; /* range_start is cyclic */ | 64 | unsigned range_cyclic:1; /* range_start is cyclic */ |
65 | unsigned more_io:1; /* more io to be dispatched */ | 65 | unsigned more_io:1; /* more io to be dispatched */ |
66 | unsigned range_cont:1; | 66 | /* |
67 | * write_cache_pages() won't update wbc->nr_to_write and | ||
68 | * mapping->writeback_index if no_nrwrite_index_update | ||
69 | * is set. write_cache_pages() may write more than we | ||
70 | * requested and we want to make sure nr_to_write and | ||
71 | * writeback_index are updated in a consistent manner | ||
72 | * so we use a single control to update them | ||
73 | */ | ||
74 | unsigned no_nrwrite_index_update:1; | ||
67 | }; | 75 | }; |
68 | 76 | ||
69 | /* | 77 | /* |
diff --git a/include/media/soc_camera_platform.h b/include/media/soc_camera_platform.h index 851f18220984..1d092b4678aa 100644 --- a/include/media/soc_camera_platform.h +++ b/include/media/soc_camera_platform.h | |||
@@ -1,3 +1,13 @@ | |||
1 | /* | ||
2 | * Generic Platform Camera Driver Header | ||
3 | * | ||
4 | * Copyright (C) 2008 Magnus Damm | ||
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 version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
1 | #ifndef __SOC_CAMERA_H__ | 11 | #ifndef __SOC_CAMERA_H__ |
2 | #define __SOC_CAMERA_H__ | 12 | #define __SOC_CAMERA_H__ |
3 | 13 | ||
@@ -9,6 +19,7 @@ struct soc_camera_platform_info { | |||
9 | unsigned long format_depth; | 19 | unsigned long format_depth; |
10 | struct v4l2_pix_format format; | 20 | struct v4l2_pix_format format; |
11 | unsigned long bus_param; | 21 | unsigned long bus_param; |
22 | void (*power)(int); | ||
12 | int (*set_capture)(struct soc_camera_platform_info *info, int enable); | 23 | int (*set_capture)(struct soc_camera_platform_info *info, int enable); |
13 | }; | 24 | }; |
14 | 25 | ||
diff --git a/include/media/tuner.h b/include/media/tuner.h index 67c1f514d0e2..7d4e2db78076 100644 --- a/include/media/tuner.h +++ b/include/media/tuner.h | |||
@@ -123,6 +123,7 @@ | |||
123 | #define TUNER_TEA5761 75 /* Only FM Radio Tuner */ | 123 | #define TUNER_TEA5761 75 /* Only FM Radio Tuner */ |
124 | #define TUNER_XC5000 76 /* Xceive Silicon Tuner */ | 124 | #define TUNER_XC5000 76 /* Xceive Silicon Tuner */ |
125 | #define TUNER_TCL_MF02GIP_5N 77 /* TCL MF02GIP_5N */ | 125 | #define TUNER_TCL_MF02GIP_5N 77 /* TCL MF02GIP_5N */ |
126 | #define TUNER_PHILIPS_FMD1216MEX_MK3 78 | ||
126 | 127 | ||
127 | /* tv card specific */ | 128 | /* tv card specific */ |
128 | #define TDA9887_PRESENT (1<<0) | 129 | #define TDA9887_PRESENT (1<<0) |
diff --git a/include/media/v4l2-i2c-drv-legacy.h b/include/media/v4l2-i2c-drv-legacy.h index 975ffbf4e2c5..e65dd9d84e8b 100644 --- a/include/media/v4l2-i2c-drv-legacy.h +++ b/include/media/v4l2-i2c-drv-legacy.h | |||
@@ -21,6 +21,17 @@ | |||
21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
22 | */ | 22 | */ |
23 | 23 | ||
24 | /* NOTE: the full version of this header is in the v4l-dvb repository | ||
25 | * and allows v4l i2c drivers to be compiled on older kernels as well. | ||
26 | * The version of this header as it appears in the kernel is a stripped | ||
27 | * version (without all the backwards compatibility stuff) and so it | ||
28 | * looks a bit odd. | ||
29 | * | ||
30 | * If you look at the full version then you will understand the reason | ||
31 | * for introducing this header since you really don't want to have all | ||
32 | * the tricky backwards compatibility code in each and every i2c driver. | ||
33 | */ | ||
34 | |||
24 | struct v4l2_i2c_driver_data { | 35 | struct v4l2_i2c_driver_data { |
25 | const char * const name; | 36 | const char * const name; |
26 | int driverid; | 37 | int driverid; |
diff --git a/include/media/v4l2-i2c-drv.h b/include/media/v4l2-i2c-drv.h index 40ecef29801d..efdc8bf27f87 100644 --- a/include/media/v4l2-i2c-drv.h +++ b/include/media/v4l2-i2c-drv.h | |||
@@ -21,6 +21,17 @@ | |||
21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
22 | */ | 22 | */ |
23 | 23 | ||
24 | /* NOTE: the full version of this header is in the v4l-dvb repository | ||
25 | * and allows v4l i2c drivers to be compiled on older kernels as well. | ||
26 | * The version of this header as it appears in the kernel is a stripped | ||
27 | * version (without all the backwards compatibility stuff) and so it | ||
28 | * looks a bit odd. | ||
29 | * | ||
30 | * If you look at the full version then you will understand the reason | ||
31 | * for introducing this header since you really don't want to have all | ||
32 | * the tricky backwards compatibility code in each and every i2c driver. | ||
33 | */ | ||
34 | |||
24 | #ifndef __V4L2_I2C_DRV_H__ | 35 | #ifndef __V4L2_I2C_DRV_H__ |
25 | #define __V4L2_I2C_DRV_H__ | 36 | #define __V4L2_I2C_DRV_H__ |
26 | 37 | ||
diff --git a/include/media/videobuf-dvb.h b/include/media/videobuf-dvb.h index b77748696329..80471c2b6343 100644 --- a/include/media/videobuf-dvb.h +++ b/include/media/videobuf-dvb.h | |||
@@ -16,7 +16,6 @@ struct videobuf_dvb { | |||
16 | int nfeeds; | 16 | int nfeeds; |
17 | 17 | ||
18 | /* videobuf_dvb_(un)register manges this */ | 18 | /* videobuf_dvb_(un)register manges this */ |
19 | struct dvb_adapter adapter; | ||
20 | struct dvb_demux demux; | 19 | struct dvb_demux demux; |
21 | struct dmxdev dmxdev; | 20 | struct dmxdev dmxdev; |
22 | struct dmx_frontend fe_hw; | 21 | struct dmx_frontend fe_hw; |
@@ -24,12 +23,34 @@ struct videobuf_dvb { | |||
24 | struct dvb_net net; | 23 | struct dvb_net net; |
25 | }; | 24 | }; |
26 | 25 | ||
27 | int videobuf_dvb_register(struct videobuf_dvb *dvb, | 26 | struct videobuf_dvb_frontend { |
27 | struct list_head felist; | ||
28 | int id; | ||
29 | struct videobuf_dvb dvb; | ||
30 | }; | ||
31 | |||
32 | struct videobuf_dvb_frontends { | ||
33 | struct list_head felist; | ||
34 | struct mutex lock; | ||
35 | struct dvb_adapter adapter; | ||
36 | int active_fe_id; /* Indicates which frontend in the felist is in use */ | ||
37 | int gate; /* Frontend with gate control 0=!MFE,1=fe0,2=fe1 etc */ | ||
38 | }; | ||
39 | |||
40 | int videobuf_dvb_register_bus(struct videobuf_dvb_frontends *f, | ||
28 | struct module *module, | 41 | struct module *module, |
29 | void *adapter_priv, | 42 | void *adapter_priv, |
30 | struct device *device, | 43 | struct device *device, |
31 | short *adapter_nr); | 44 | short *adapter_nr, |
32 | void videobuf_dvb_unregister(struct videobuf_dvb *dvb); | 45 | int mfe_shared); |
46 | |||
47 | void videobuf_dvb_unregister_bus(struct videobuf_dvb_frontends *f); | ||
48 | |||
49 | struct videobuf_dvb_frontend * videobuf_dvb_alloc_frontend(struct videobuf_dvb_frontends *f, int id); | ||
50 | |||
51 | struct videobuf_dvb_frontend * videobuf_dvb_get_frontend(struct videobuf_dvb_frontends *f, int id); | ||
52 | int videobuf_dvb_find_frontend(struct videobuf_dvb_frontends *f, struct dvb_frontend *p); | ||
53 | |||
33 | 54 | ||
34 | /* | 55 | /* |
35 | * Local variables: | 56 | * Local variables: |
diff --git a/mm/page-writeback.c b/mm/page-writeback.c index c130a137c129..b40f6d5f8fe9 100644 --- a/mm/page-writeback.c +++ b/mm/page-writeback.c | |||
@@ -876,6 +876,7 @@ int write_cache_pages(struct address_space *mapping, | |||
876 | pgoff_t end; /* Inclusive */ | 876 | pgoff_t end; /* Inclusive */ |
877 | int scanned = 0; | 877 | int scanned = 0; |
878 | int range_whole = 0; | 878 | int range_whole = 0; |
879 | long nr_to_write = wbc->nr_to_write; | ||
879 | 880 | ||
880 | if (wbc->nonblocking && bdi_write_congested(bdi)) { | 881 | if (wbc->nonblocking && bdi_write_congested(bdi)) { |
881 | wbc->encountered_congestion = 1; | 882 | wbc->encountered_congestion = 1; |
@@ -939,7 +940,7 @@ retry: | |||
939 | unlock_page(page); | 940 | unlock_page(page); |
940 | ret = 0; | 941 | ret = 0; |
941 | } | 942 | } |
942 | if (ret || (--(wbc->nr_to_write) <= 0)) | 943 | if (ret || (--nr_to_write <= 0)) |
943 | done = 1; | 944 | done = 1; |
944 | if (wbc->nonblocking && bdi_write_congested(bdi)) { | 945 | if (wbc->nonblocking && bdi_write_congested(bdi)) { |
945 | wbc->encountered_congestion = 1; | 946 | wbc->encountered_congestion = 1; |
@@ -958,11 +959,12 @@ retry: | |||
958 | index = 0; | 959 | index = 0; |
959 | goto retry; | 960 | goto retry; |
960 | } | 961 | } |
961 | if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0)) | 962 | if (!wbc->no_nrwrite_index_update) { |
962 | mapping->writeback_index = index; | 963 | if (wbc->range_cyclic || (range_whole && nr_to_write > 0)) |
964 | mapping->writeback_index = index; | ||
965 | wbc->nr_to_write = nr_to_write; | ||
966 | } | ||
963 | 967 | ||
964 | if (wbc->range_cont) | ||
965 | wbc->range_start = index << PAGE_CACHE_SHIFT; | ||
966 | return ret; | 968 | return ret; |
967 | } | 969 | } |
968 | EXPORT_SYMBOL(write_cache_pages); | 970 | EXPORT_SYMBOL(write_cache_pages); |
diff --git a/mm/shmem.c b/mm/shmem.c index bf66d0191baf..d87958a5f03e 100644 --- a/mm/shmem.c +++ b/mm/shmem.c | |||
@@ -2580,6 +2580,7 @@ put_memory: | |||
2580 | shmem_unacct_size(flags, size); | 2580 | shmem_unacct_size(flags, size); |
2581 | return ERR_PTR(error); | 2581 | return ERR_PTR(error); |
2582 | } | 2582 | } |
2583 | EXPORT_SYMBOL_GPL(shmem_file_setup); | ||
2583 | 2584 | ||
2584 | /** | 2585 | /** |
2585 | * shmem_zero_setup - setup a shared anonymous mapping | 2586 | * shmem_zero_setup - setup a shared anonymous mapping |