diff --git a/[refs] b/[refs] index 310de1ad8036..5f6c473fe911 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: f7ea4a4ba84f382e8eb143e435551de0feee5b4b +refs/heads/master: b064eca9b0cdbb2b8f731ae2e44fa02194a1219a diff --git a/trunk/Documentation/filesystems/ext4.txt b/trunk/Documentation/filesystems/ext4.txt index 174eaff7ded9..eb154ef36c2a 100644 --- a/trunk/Documentation/filesystems/ext4.txt +++ b/trunk/Documentation/filesystems/ext4.txt @@ -2,24 +2,19 @@ Ext4 Filesystem =============== -Ext4 is an an advanced level of the ext3 filesystem which incorporates -scalability and reliability enhancements for supporting large filesystems -(64 bit) in keeping with increasing disk capacities and state-of-the-art -feature requirements. +This is a development version of the ext4 filesystem, an advanced level +of the ext3 filesystem which incorporates scalability and reliability +enhancements for supporting large filesystems (64 bit) in keeping with +increasing disk capacities and state-of-the-art feature requirements. -Mailing list: linux-ext4@vger.kernel.org -Web site: http://ext4.wiki.kernel.org +Mailing list: linux-ext4@vger.kernel.org 1. Quick usage instructions: =========================== -Note: More extensive information for getting started with ext4 can be - found at the ext4 wiki site at the URL: - http://ext4.wiki.kernel.org/index.php/Ext4_Howto - - Compile and install the latest version of e2fsprogs (as of this - writing version 1.41.3) from: + writing version 1.41) from: http://sourceforge.net/project/showfiles.php?group_id=2406 @@ -41,9 +36,11 @@ Note: More extensive information for getting started with ext4 can be # mke2fs -t ext4 /dev/hda1 - Or to configure an existing ext3 filesystem to support extents: + Or configure an existing ext3 filesystem to support extents and set + the test_fs flag to indicate that it's ok for an in-development + filesystem to touch this filesystem: - # tune2fs -O extents /dev/hda1 + # tune2fs -O extents -E test_fs /dev/hda1 If the filesystem was created with 128 byte inodes, it can be converted to use 256 byte for greater efficiency via: @@ -107,8 +104,8 @@ exist yet so I'm not sure they're in the near-term roadmap. The big performance win will come with mballoc, delalloc and flex_bg grouping of bitmaps and inode tables. Some test results available here: - - http://www.bullopensource.org/ext4/20080818-ffsb/ffsb-write-2.6.27-rc1.html - - http://www.bullopensource.org/ext4/20080818-ffsb/ffsb-readwrite-2.6.27-rc1.html + - http://www.bullopensource.org/ext4/20080530/ffsb-write-2.6.26-rc2.html + - http://www.bullopensource.org/ext4/20080530/ffsb-readwrite-2.6.26-rc2.html 3. Options ========== @@ -217,6 +214,9 @@ noreservation bsddf (*) Make 'df' act like BSD. minixdf Make 'df' act like Minix. +check=none Don't do extra checking of bitmaps on mount. +nocheck + debug Extra debugging information is sent to syslog. errors=remount-ro(*) Remount the filesystem read-only on an error. @@ -253,6 +253,8 @@ nobh (a) cache disk block mapping information "nobh" option tries to avoid associating buffer heads (supported only for "writeback" mode). +mballoc (*) Use the multiple block allocator for block allocation +nomballoc disabled multiple block allocator for block allocation. stripe=n Number of filesystem blocks that mballoc will try to use for allocation size and alignment. For RAID5/6 systems this should be the number of data diff --git a/trunk/Documentation/video4linux/CARDLIST.au0828 b/trunk/Documentation/video4linux/CARDLIST.au0828 index d5cb4ea287b2..aa05e5bb22fb 100644 --- a/trunk/Documentation/video4linux/CARDLIST.au0828 +++ b/trunk/Documentation/video4linux/CARDLIST.au0828 @@ -1,5 +1,5 @@ 0 -> Unknown board (au0828) - 1 -> Hauppauge HVR950Q (au0828) [2040:7200,2040:7210,2040:7217,2040:721b,2040:721e,2040:721f,2040:7280,0fd9:0008] + 1 -> Hauppauge HVR950Q (au0828) [2040:7200,2040:7210,2040:7217,2040:721b,2040:721f,2040:7280,0fd9:0008] 2 -> Hauppauge HVR850 (au0828) [2040:7240] 3 -> DViCO FusionHDTV USB (au0828) [0fe9:d620] 4 -> Hauppauge HVR950Q rev xxF8 (au0828) [2040:7201,2040:7211,2040:7281] diff --git a/trunk/Documentation/video4linux/CARDLIST.tuner b/trunk/Documentation/video4linux/CARDLIST.tuner index 691d2f37dc57..30bbdda68d03 100644 --- a/trunk/Documentation/video4linux/CARDLIST.tuner +++ b/trunk/Documentation/video4linux/CARDLIST.tuner @@ -75,4 +75,3 @@ tuner=73 - Samsung TCPG 6121P30A tuner=75 - Philips TEA5761 FM Radio tuner=76 - Xceive 5000 tuner tuner=77 - TCL tuner MF02GIP-5N-E -tuner=78 - Philips FMD1216MEX MK3 Hybrid Tuner diff --git a/trunk/arch/x86/mm/highmem_32.c b/trunk/arch/x86/mm/highmem_32.c index bcc079c282dd..165c871ba9af 100644 --- a/trunk/arch/x86/mm/highmem_32.c +++ b/trunk/arch/x86/mm/highmem_32.c @@ -137,7 +137,6 @@ void *kmap_atomic_pfn(unsigned long pfn, enum km_type type) return (void*) vaddr; } -EXPORT_SYMBOL_GPL(kmap_atomic_pfn); /* temporarily in use by i915 GEM until vmap */ struct page *kmap_atomic_to_page(void *ptr) { diff --git a/trunk/drivers/gpu/drm/Kconfig b/trunk/drivers/gpu/drm/Kconfig index 9097500de5f4..610d6fd5bb50 100644 --- a/trunk/drivers/gpu/drm/Kconfig +++ b/trunk/drivers/gpu/drm/Kconfig @@ -6,7 +6,7 @@ # menuconfig DRM tristate "Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)" - depends on (AGP || AGP=n) && PCI && !EMULATED_CMPXCHG && SHMEM + depends on (AGP || AGP=n) && PCI && !EMULATED_CMPXCHG help Kernel-level support for the Direct Rendering Infrastructure (DRI) introduced in XFree86 4.0. If you say Y here, you need to select @@ -87,7 +87,6 @@ config DRM_MGA config DRM_SIS tristate "SiS video cards" depends on DRM && AGP - depends on FB_SIS || FB_SIS=n help Choose this option if you have a SiS 630 or compatible video chipset. If M is selected the module will be called sis. AGP diff --git a/trunk/drivers/gpu/drm/Makefile b/trunk/drivers/gpu/drm/Makefile index 74da99495e21..e9f9a97ae00a 100644 --- a/trunk/drivers/gpu/drm/Makefile +++ b/trunk/drivers/gpu/drm/Makefile @@ -4,9 +4,8 @@ ccflags-y := -Iinclude/drm -drm-y := drm_auth.o drm_bufs.o drm_cache.o \ - drm_context.o drm_dma.o drm_drawable.o \ - drm_drv.o drm_fops.o drm_gem.o drm_ioctl.o drm_irq.o \ +drm-y := drm_auth.o drm_bufs.o drm_context.o drm_dma.o drm_drawable.o \ + drm_drv.o drm_fops.o drm_ioctl.o drm_irq.o \ drm_lock.o drm_memory.o drm_proc.o drm_stub.o drm_vm.o \ drm_agpsupport.o drm_scatter.o ati_pcigart.o drm_pci.o \ drm_sysfs.o drm_hashtab.o drm_sman.o drm_mm.o diff --git a/trunk/drivers/gpu/drm/drm_agpsupport.c b/trunk/drivers/gpu/drm/drm_agpsupport.c index 3d33b8252b58..aefa5ac4c0b1 100644 --- a/trunk/drivers/gpu/drm/drm_agpsupport.c +++ b/trunk/drivers/gpu/drm/drm_agpsupport.c @@ -33,7 +33,6 @@ #include "drmP.h" #include -#include #if __OS_HAS_AGP @@ -453,53 +452,4 @@ int drm_agp_unbind_memory(DRM_AGP_MEM * handle) return agp_unbind_memory(handle); } -/** - * Binds a collection of pages into AGP memory at the given offset, returning - * the AGP memory structure containing them. - * - * No reference is held on the pages during this time -- it is up to the - * caller to handle that. - */ -DRM_AGP_MEM * -drm_agp_bind_pages(struct drm_device *dev, - struct page **pages, - unsigned long num_pages, - uint32_t gtt_offset, - u32 type) -{ - DRM_AGP_MEM *mem; - int ret, i; - - DRM_DEBUG("\n"); - - mem = drm_agp_allocate_memory(dev->agp->bridge, num_pages, - type); - if (mem == NULL) { - DRM_ERROR("Failed to allocate memory for %ld pages\n", - num_pages); - return NULL; - } - - for (i = 0; i < num_pages; i++) - mem->memory[i] = phys_to_gart(page_to_phys(pages[i])); - mem->page_count = num_pages; - - mem->is_flushed = true; - ret = drm_agp_bind_memory(mem, gtt_offset / PAGE_SIZE); - if (ret != 0) { - DRM_ERROR("Failed to bind AGP memory: %d\n", ret); - agp_free_memory(mem); - return NULL; - } - - return mem; -} -EXPORT_SYMBOL(drm_agp_bind_pages); - -void drm_agp_chipset_flush(struct drm_device *dev) -{ - agp_flush_chipset(dev->agp->bridge); -} -EXPORT_SYMBOL(drm_agp_chipset_flush); - -#endif /* __OS_HAS_AGP */ +#endif /* __OS_HAS_AGP */ diff --git a/trunk/drivers/gpu/drm/drm_cache.c b/trunk/drivers/gpu/drm/drm_cache.c deleted file mode 100644 index 0e994a0e46d4..000000000000 --- a/trunk/drivers/gpu/drm/drm_cache.c +++ /dev/null @@ -1,69 +0,0 @@ -/************************************************************************** - * - * Copyright (c) 2006-2007 Tungsten Graphics, Inc., Cedar Park, TX., USA - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ -/* - * Authors: Thomas Hellström - */ - -#include "drmP.h" - -#if defined(CONFIG_X86) -static void -drm_clflush_page(struct page *page) -{ - uint8_t *page_virtual; - unsigned int i; - - if (unlikely(page == NULL)) - return; - - page_virtual = kmap_atomic(page, KM_USER0); - for (i = 0; i < PAGE_SIZE; i += boot_cpu_data.x86_clflush_size) - clflush(page_virtual + i); - kunmap_atomic(page_virtual, KM_USER0); -} -#endif - -void -drm_clflush_pages(struct page *pages[], unsigned long num_pages) -{ - -#if defined(CONFIG_X86) - if (cpu_has_clflush) { - unsigned long i; - - mb(); - for (i = 0; i < num_pages; ++i) - drm_clflush_page(*pages++); - mb(); - - return; - } - - wbinvd(); -#endif -} -EXPORT_SYMBOL(drm_clflush_pages); diff --git a/trunk/drivers/gpu/drm/drm_drv.c b/trunk/drivers/gpu/drm/drm_drv.c index 96f416afc3f6..452c2d866ec5 100644 --- a/trunk/drivers/gpu/drm/drm_drv.c +++ b/trunk/drivers/gpu/drm/drm_drv.c @@ -116,13 +116,7 @@ static struct drm_ioctl_desc drm_ioctls[] = { DRM_IOCTL_DEF(DRM_IOCTL_WAIT_VBLANK, drm_wait_vblank, 0), - DRM_IOCTL_DEF(DRM_IOCTL_MODESET_CTL, drm_modeset_ctl, 0), - DRM_IOCTL_DEF(DRM_IOCTL_UPDATE_DRAW, drm_update_drawable_info, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - - DRM_IOCTL_DEF(DRM_IOCTL_GEM_CLOSE, drm_gem_close_ioctl, 0), - DRM_IOCTL_DEF(DRM_IOCTL_GEM_FLINK, drm_gem_flink_ioctl, DRM_AUTH), - DRM_IOCTL_DEF(DRM_IOCTL_GEM_OPEN, drm_gem_open_ioctl, DRM_AUTH), }; #define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls ) diff --git a/trunk/drivers/gpu/drm/drm_fops.c b/trunk/drivers/gpu/drm/drm_fops.c index 0d46627663b1..851a53f1acce 100644 --- a/trunk/drivers/gpu/drm/drm_fops.c +++ b/trunk/drivers/gpu/drm/drm_fops.c @@ -246,7 +246,7 @@ static int drm_open_helper(struct inode *inode, struct file *filp, memset(priv, 0, sizeof(*priv)); filp->private_data = priv; priv->filp = filp; - priv->uid = current_euid(); + priv->uid = current->euid; priv->pid = task_pid_nr(current); priv->minor = idr_find(&drm_minors_idr, minor_id); priv->ioctl_count = 0; @@ -256,9 +256,6 @@ static int drm_open_helper(struct inode *inode, struct file *filp, INIT_LIST_HEAD(&priv->lhead); - if (dev->driver->driver_features & DRIVER_GEM) - drm_gem_open(dev, priv); - if (dev->driver->open) { ret = dev->driver->open(dev, priv); if (ret < 0) @@ -403,9 +400,6 @@ int drm_release(struct inode *inode, struct file *filp) dev->driver->reclaim_buffers(dev, file_priv); } - if (dev->driver->driver_features & DRIVER_GEM) - drm_gem_release(dev, file_priv); - drm_fasync(-1, filp, 0); mutex_lock(&dev->ctxlist_mutex); diff --git a/trunk/drivers/gpu/drm/drm_gem.c b/trunk/drivers/gpu/drm/drm_gem.c deleted file mode 100644 index ccd1afdede02..000000000000 --- a/trunk/drivers/gpu/drm/drm_gem.c +++ /dev/null @@ -1,421 +0,0 @@ -/* - * Copyright © 2008 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - * - * Authors: - * Eric Anholt - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "drmP.h" - -/** @file drm_gem.c - * - * This file provides some of the base ioctls and library routines for - * the graphics memory manager implemented by each device driver. - * - * Because various devices have different requirements in terms of - * synchronization and migration strategies, implementing that is left up to - * the driver, and all that the general API provides should be generic -- - * allocating objects, reading/writing data with the cpu, freeing objects. - * Even there, platform-dependent optimizations for reading/writing data with - * the CPU mean we'll likely hook those out to driver-specific calls. However, - * the DRI2 implementation wants to have at least allocate/mmap be generic. - * - * The goal was to have swap-backed object allocation managed through - * struct file. However, file descriptors as handles to a struct file have - * two major failings: - * - Process limits prevent more than 1024 or so being used at a time by - * default. - * - Inability to allocate high fds will aggravate the X Server's select() - * handling, and likely that of many GL client applications as well. - * - * This led to a plan of using our own integer IDs (called handles, following - * DRM terminology) to mimic fds, and implement the fd syscalls we need as - * ioctls. The objects themselves will still include the struct file so - * that we can transition to fds if the required kernel infrastructure shows - * up at a later date, and as our interface with shmfs for memory allocation. - */ - -/** - * Initialize the GEM device fields - */ - -int -drm_gem_init(struct drm_device *dev) -{ - spin_lock_init(&dev->object_name_lock); - idr_init(&dev->object_name_idr); - atomic_set(&dev->object_count, 0); - atomic_set(&dev->object_memory, 0); - atomic_set(&dev->pin_count, 0); - atomic_set(&dev->pin_memory, 0); - atomic_set(&dev->gtt_count, 0); - atomic_set(&dev->gtt_memory, 0); - return 0; -} - -/** - * Allocate a GEM object of the specified size with shmfs backing store - */ -struct drm_gem_object * -drm_gem_object_alloc(struct drm_device *dev, size_t size) -{ - struct drm_gem_object *obj; - - BUG_ON((size & (PAGE_SIZE - 1)) != 0); - - obj = kcalloc(1, sizeof(*obj), GFP_KERNEL); - - obj->dev = dev; - obj->filp = shmem_file_setup("drm mm object", size, 0); - if (IS_ERR(obj->filp)) { - kfree(obj); - return NULL; - } - - kref_init(&obj->refcount); - kref_init(&obj->handlecount); - obj->size = size; - if (dev->driver->gem_init_object != NULL && - dev->driver->gem_init_object(obj) != 0) { - fput(obj->filp); - kfree(obj); - return NULL; - } - atomic_inc(&dev->object_count); - atomic_add(obj->size, &dev->object_memory); - return obj; -} -EXPORT_SYMBOL(drm_gem_object_alloc); - -/** - * Removes the mapping from handle to filp for this object. - */ -static int -drm_gem_handle_delete(struct drm_file *filp, int handle) -{ - struct drm_device *dev; - struct drm_gem_object *obj; - - /* This is gross. The idr system doesn't let us try a delete and - * return an error code. It just spews if you fail at deleting. - * So, we have to grab a lock around finding the object and then - * doing the delete on it and dropping the refcount, or the user - * could race us to double-decrement the refcount and cause a - * use-after-free later. Given the frequency of our handle lookups, - * we may want to use ida for number allocation and a hash table - * for the pointers, anyway. - */ - spin_lock(&filp->table_lock); - - /* Check if we currently have a reference on the object */ - obj = idr_find(&filp->object_idr, handle); - if (obj == NULL) { - spin_unlock(&filp->table_lock); - return -EINVAL; - } - dev = obj->dev; - - /* Release reference and decrement refcount. */ - idr_remove(&filp->object_idr, handle); - spin_unlock(&filp->table_lock); - - mutex_lock(&dev->struct_mutex); - drm_gem_object_handle_unreference(obj); - mutex_unlock(&dev->struct_mutex); - - return 0; -} - -/** - * Create a handle for this object. This adds a handle reference - * to the object, which includes a regular reference count. Callers - * will likely want to dereference the object afterwards. - */ -int -drm_gem_handle_create(struct drm_file *file_priv, - struct drm_gem_object *obj, - int *handlep) -{ - int ret; - - /* - * Get the user-visible handle using idr. - */ -again: - /* ensure there is space available to allocate a handle */ - if (idr_pre_get(&file_priv->object_idr, GFP_KERNEL) == 0) - return -ENOMEM; - - /* do the allocation under our spinlock */ - spin_lock(&file_priv->table_lock); - ret = idr_get_new_above(&file_priv->object_idr, obj, 1, handlep); - spin_unlock(&file_priv->table_lock); - if (ret == -EAGAIN) - goto again; - - if (ret != 0) - return ret; - - drm_gem_object_handle_reference(obj); - return 0; -} -EXPORT_SYMBOL(drm_gem_handle_create); - -/** Returns a reference to the object named by the handle. */ -struct drm_gem_object * -drm_gem_object_lookup(struct drm_device *dev, struct drm_file *filp, - int handle) -{ - struct drm_gem_object *obj; - - spin_lock(&filp->table_lock); - - /* Check if we currently have a reference on the object */ - obj = idr_find(&filp->object_idr, handle); - if (obj == NULL) { - spin_unlock(&filp->table_lock); - return NULL; - } - - drm_gem_object_reference(obj); - - spin_unlock(&filp->table_lock); - - return obj; -} -EXPORT_SYMBOL(drm_gem_object_lookup); - -/** - * Releases the handle to an mm object. - */ -int -drm_gem_close_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_gem_close *args = data; - int ret; - - if (!(dev->driver->driver_features & DRIVER_GEM)) - return -ENODEV; - - ret = drm_gem_handle_delete(file_priv, args->handle); - - return ret; -} - -/** - * Create a global name for an object, returning the name. - * - * Note that the name does not hold a reference; when the object - * is freed, the name goes away. - */ -int -drm_gem_flink_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_gem_flink *args = data; - struct drm_gem_object *obj; - int ret; - - if (!(dev->driver->driver_features & DRIVER_GEM)) - return -ENODEV; - - obj = drm_gem_object_lookup(dev, file_priv, args->handle); - if (obj == NULL) - return -EBADF; - -again: - if (idr_pre_get(&dev->object_name_idr, GFP_KERNEL) == 0) - return -ENOMEM; - - spin_lock(&dev->object_name_lock); - if (obj->name) { - args->name = obj->name; - spin_unlock(&dev->object_name_lock); - return 0; - } - ret = idr_get_new_above(&dev->object_name_idr, obj, 1, - &obj->name); - spin_unlock(&dev->object_name_lock); - if (ret == -EAGAIN) - goto again; - - if (ret != 0) { - mutex_lock(&dev->struct_mutex); - drm_gem_object_unreference(obj); - mutex_unlock(&dev->struct_mutex); - return ret; - } - - /* - * Leave the reference from the lookup around as the - * name table now holds one - */ - args->name = (uint64_t) obj->name; - - return 0; -} - -/** - * Open an object using the global name, returning a handle and the size. - * - * This handle (of course) holds a reference to the object, so the object - * will not go away until the handle is deleted. - */ -int -drm_gem_open_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_gem_open *args = data; - struct drm_gem_object *obj; - int ret; - int handle; - - if (!(dev->driver->driver_features & DRIVER_GEM)) - return -ENODEV; - - spin_lock(&dev->object_name_lock); - obj = idr_find(&dev->object_name_idr, (int) args->name); - if (obj) - drm_gem_object_reference(obj); - spin_unlock(&dev->object_name_lock); - if (!obj) - return -ENOENT; - - ret = drm_gem_handle_create(file_priv, obj, &handle); - mutex_lock(&dev->struct_mutex); - drm_gem_object_unreference(obj); - mutex_unlock(&dev->struct_mutex); - if (ret) - return ret; - - args->handle = handle; - args->size = obj->size; - - return 0; -} - -/** - * Called at device open time, sets up the structure for handling refcounting - * of mm objects. - */ -void -drm_gem_open(struct drm_device *dev, struct drm_file *file_private) -{ - idr_init(&file_private->object_idr); - spin_lock_init(&file_private->table_lock); -} - -/** - * Called at device close to release the file's - * handle references on objects. - */ -static int -drm_gem_object_release_handle(int id, void *ptr, void *data) -{ - struct drm_gem_object *obj = ptr; - - drm_gem_object_handle_unreference(obj); - - return 0; -} - -/** - * Called at close time when the filp is going away. - * - * Releases any remaining references on objects by this filp. - */ -void -drm_gem_release(struct drm_device *dev, struct drm_file *file_private) -{ - mutex_lock(&dev->struct_mutex); - idr_for_each(&file_private->object_idr, - &drm_gem_object_release_handle, NULL); - - idr_destroy(&file_private->object_idr); - mutex_unlock(&dev->struct_mutex); -} - -/** - * Called after the last reference to the object has been lost. - * - * Frees the object - */ -void -drm_gem_object_free(struct kref *kref) -{ - struct drm_gem_object *obj = (struct drm_gem_object *) kref; - struct drm_device *dev = obj->dev; - - BUG_ON(!mutex_is_locked(&dev->struct_mutex)); - - if (dev->driver->gem_free_object != NULL) - dev->driver->gem_free_object(obj); - - fput(obj->filp); - atomic_dec(&dev->object_count); - atomic_sub(obj->size, &dev->object_memory); - kfree(obj); -} -EXPORT_SYMBOL(drm_gem_object_free); - -/** - * Called after the last handle to the object has been closed - * - * Removes any name for the object. Note that this must be - * called before drm_gem_object_free or we'll be touching - * freed memory - */ -void -drm_gem_object_handle_free(struct kref *kref) -{ - struct drm_gem_object *obj = container_of(kref, - struct drm_gem_object, - handlecount); - struct drm_device *dev = obj->dev; - - /* Remove any name for this object */ - spin_lock(&dev->object_name_lock); - if (obj->name) { - idr_remove(&dev->object_name_idr, obj->name); - spin_unlock(&dev->object_name_lock); - /* - * The object name held a reference to this object, drop - * that now. - */ - drm_gem_object_unreference(obj); - } else - spin_unlock(&dev->object_name_lock); - -} -EXPORT_SYMBOL(drm_gem_object_handle_free); - diff --git a/trunk/drivers/gpu/drm/drm_irq.c b/trunk/drivers/gpu/drm/drm_irq.c index 4091b9e291f9..53f0e5af1cc8 100644 --- a/trunk/drivers/gpu/drm/drm_irq.c +++ b/trunk/drivers/gpu/drm/drm_irq.c @@ -63,7 +63,7 @@ int drm_irq_by_busid(struct drm_device *dev, void *data, p->devnum != PCI_SLOT(dev->pdev->devfn) || p->funcnum != PCI_FUNC(dev->pdev->devfn)) return -EINVAL; - p->irq = dev->pdev->irq; + p->irq = dev->irq; DRM_DEBUG("%d:%d:%d => IRQ %d\n", p->busnum, p->devnum, p->funcnum, p->irq); @@ -71,137 +71,25 @@ int drm_irq_by_busid(struct drm_device *dev, void *data, return 0; } -static void vblank_disable_fn(unsigned long arg) -{ - struct drm_device *dev = (struct drm_device *)arg; - unsigned long irqflags; - int i; - - if (!dev->vblank_disable_allowed) - return; - - for (i = 0; i < dev->num_crtcs; i++) { - spin_lock_irqsave(&dev->vbl_lock, irqflags); - if (atomic_read(&dev->vblank_refcount[i]) == 0 && - dev->vblank_enabled[i]) { - DRM_DEBUG("disabling vblank on crtc %d\n", i); - dev->last_vblank[i] = - dev->driver->get_vblank_counter(dev, i); - dev->driver->disable_vblank(dev, i); - dev->vblank_enabled[i] = 0; - } - spin_unlock_irqrestore(&dev->vbl_lock, irqflags); - } -} - -static void drm_vblank_cleanup(struct drm_device *dev) -{ - /* Bail if the driver didn't call drm_vblank_init() */ - if (dev->num_crtcs == 0) - return; - - del_timer(&dev->vblank_disable_timer); - - vblank_disable_fn((unsigned long)dev); - - drm_free(dev->vbl_queue, sizeof(*dev->vbl_queue) * dev->num_crtcs, - DRM_MEM_DRIVER); - drm_free(dev->vbl_sigs, sizeof(*dev->vbl_sigs) * dev->num_crtcs, - DRM_MEM_DRIVER); - drm_free(dev->_vblank_count, sizeof(*dev->_vblank_count) * - dev->num_crtcs, DRM_MEM_DRIVER); - drm_free(dev->vblank_refcount, sizeof(*dev->vblank_refcount) * - dev->num_crtcs, DRM_MEM_DRIVER); - drm_free(dev->vblank_enabled, sizeof(*dev->vblank_enabled) * - dev->num_crtcs, DRM_MEM_DRIVER); - drm_free(dev->last_vblank, sizeof(*dev->last_vblank) * dev->num_crtcs, - DRM_MEM_DRIVER); - drm_free(dev->vblank_inmodeset, sizeof(*dev->vblank_inmodeset) * - dev->num_crtcs, DRM_MEM_DRIVER); - - dev->num_crtcs = 0; -} - -int drm_vblank_init(struct drm_device *dev, int num_crtcs) -{ - int i, ret = -ENOMEM; - - setup_timer(&dev->vblank_disable_timer, vblank_disable_fn, - (unsigned long)dev); - spin_lock_init(&dev->vbl_lock); - atomic_set(&dev->vbl_signal_pending, 0); - dev->num_crtcs = num_crtcs; - - dev->vbl_queue = drm_alloc(sizeof(wait_queue_head_t) * num_crtcs, - DRM_MEM_DRIVER); - if (!dev->vbl_queue) - goto err; - - dev->vbl_sigs = drm_alloc(sizeof(struct list_head) * num_crtcs, - DRM_MEM_DRIVER); - if (!dev->vbl_sigs) - goto err; - - dev->_vblank_count = drm_alloc(sizeof(atomic_t) * num_crtcs, - DRM_MEM_DRIVER); - if (!dev->_vblank_count) - goto err; - - dev->vblank_refcount = drm_alloc(sizeof(atomic_t) * num_crtcs, - DRM_MEM_DRIVER); - if (!dev->vblank_refcount) - goto err; - - dev->vblank_enabled = drm_calloc(num_crtcs, sizeof(int), - DRM_MEM_DRIVER); - if (!dev->vblank_enabled) - goto err; - - dev->last_vblank = drm_calloc(num_crtcs, sizeof(u32), DRM_MEM_DRIVER); - if (!dev->last_vblank) - goto err; - - dev->vblank_inmodeset = drm_calloc(num_crtcs, sizeof(int), - DRM_MEM_DRIVER); - if (!dev->vblank_inmodeset) - goto err; - - /* Zero per-crtc vblank stuff */ - for (i = 0; i < num_crtcs; i++) { - init_waitqueue_head(&dev->vbl_queue[i]); - INIT_LIST_HEAD(&dev->vbl_sigs[i]); - atomic_set(&dev->_vblank_count[i], 0); - atomic_set(&dev->vblank_refcount[i], 0); - } - - dev->vblank_disable_allowed = 0; - - return 0; - -err: - drm_vblank_cleanup(dev); - return ret; -} -EXPORT_SYMBOL(drm_vblank_init); - /** * Install IRQ handler. * * \param dev DRM device. + * \param irq IRQ number. * - * Initializes the IRQ related data. Installs the handler, calling the driver + * Initializes the IRQ related data, and setups drm_device::vbl_queue. Installs the handler, calling the driver * \c drm_driver_irq_preinstall() and \c drm_driver_irq_postinstall() functions * before and after the installation. */ -int drm_irq_install(struct drm_device *dev) +static int drm_irq_install(struct drm_device * dev) { - int ret = 0; + int ret; unsigned long sh_flags = 0; if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ)) return -EINVAL; - if (dev->pdev->irq == 0) + if (dev->irq == 0) return -EINVAL; mutex_lock(&dev->struct_mutex); @@ -219,7 +107,18 @@ int drm_irq_install(struct drm_device *dev) dev->irq_enabled = 1; mutex_unlock(&dev->struct_mutex); - DRM_DEBUG("irq=%d\n", dev->pdev->irq); + DRM_DEBUG("irq=%d\n", dev->irq); + + if (drm_core_check_feature(dev, DRIVER_IRQ_VBL)) { + init_waitqueue_head(&dev->vbl_queue); + + spin_lock_init(&dev->vbl_lock); + + INIT_LIST_HEAD(&dev->vbl_sigs); + INIT_LIST_HEAD(&dev->vbl_sigs2); + + dev->vbl_pending = 0; + } /* Before installing handler */ dev->driver->irq_preinstall(dev); @@ -228,9 +127,8 @@ int drm_irq_install(struct drm_device *dev) if (drm_core_check_feature(dev, DRIVER_IRQ_SHARED)) sh_flags = IRQF_SHARED; - ret = request_irq(drm_dev_to_irq(dev), dev->driver->irq_handler, + ret = request_irq(dev->irq, dev->driver->irq_handler, sh_flags, dev->devname, dev); - if (ret < 0) { mutex_lock(&dev->struct_mutex); dev->irq_enabled = 0; @@ -239,16 +137,10 @@ int drm_irq_install(struct drm_device *dev) } /* After installing handler */ - ret = dev->driver->irq_postinstall(dev); - if (ret < 0) { - mutex_lock(&dev->struct_mutex); - dev->irq_enabled = 0; - mutex_unlock(&dev->struct_mutex); - } + dev->driver->irq_postinstall(dev); - return ret; + return 0; } -EXPORT_SYMBOL(drm_irq_install); /** * Uninstall the IRQ handler. @@ -272,18 +164,17 @@ int drm_irq_uninstall(struct drm_device * dev) if (!irq_enabled) return -EINVAL; - DRM_DEBUG("irq=%d\n", dev->pdev->irq); + DRM_DEBUG("irq=%d\n", dev->irq); dev->driver->irq_uninstall(dev); - free_irq(dev->pdev->irq, dev); - - drm_vblank_cleanup(dev); + free_irq(dev->irq, dev); dev->locked_tasklet_func = NULL; return 0; } + EXPORT_SYMBOL(drm_irq_uninstall); /** @@ -310,7 +201,7 @@ int drm_control(struct drm_device *dev, void *data, if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ)) return 0; if (dev->if_version < DRM_IF_VERSION(1, 2) && - ctl->irq != dev->pdev->irq) + ctl->irq != dev->irq) return -EINVAL; return drm_irq_install(dev); case DRM_UNINST_HANDLER: @@ -322,174 +213,6 @@ int drm_control(struct drm_device *dev, void *data, } } -/** - * drm_vblank_count - retrieve "cooked" vblank counter value - * @dev: DRM device - * @crtc: which counter to retrieve - * - * Fetches the "cooked" vblank count value that represents the number of - * vblank events since the system was booted, including lost events due to - * modesetting activity. - */ -u32 drm_vblank_count(struct drm_device *dev, int crtc) -{ - return atomic_read(&dev->_vblank_count[crtc]); -} -EXPORT_SYMBOL(drm_vblank_count); - -/** - * drm_update_vblank_count - update the master vblank counter - * @dev: DRM device - * @crtc: counter to update - * - * Call back into the driver to update the appropriate vblank counter - * (specified by @crtc). Deal with wraparound, if it occurred, and - * update the last read value so we can deal with wraparound on the next - * call if necessary. - * - * Only necessary when going from off->on, to account for frames we - * didn't get an interrupt for. - * - * Note: caller must hold dev->vbl_lock since this reads & writes - * device vblank fields. - */ -static void drm_update_vblank_count(struct drm_device *dev, int crtc) -{ - u32 cur_vblank, diff; - - /* - * Interrupts were disabled prior to this call, so deal with counter - * wrap if needed. - * NOTE! It's possible we lost a full dev->max_vblank_count events - * here if the register is small or we had vblank interrupts off for - * a long time. - */ - cur_vblank = dev->driver->get_vblank_counter(dev, crtc); - diff = cur_vblank - dev->last_vblank[crtc]; - if (cur_vblank < dev->last_vblank[crtc]) { - diff += dev->max_vblank_count; - - DRM_DEBUG("last_vblank[%d]=0x%x, cur_vblank=0x%x => diff=0x%x\n", - crtc, dev->last_vblank[crtc], cur_vblank, diff); - } - - DRM_DEBUG("enabling vblank interrupts on crtc %d, missed %d\n", - crtc, diff); - - atomic_add(diff, &dev->_vblank_count[crtc]); -} - -/** - * drm_vblank_get - get a reference count on vblank events - * @dev: DRM device - * @crtc: which CRTC to own - * - * Acquire a reference count on vblank events to avoid having them disabled - * while in use. - * - * RETURNS - * Zero on success, nonzero on failure. - */ -int drm_vblank_get(struct drm_device *dev, int crtc) -{ - unsigned long irqflags; - int ret = 0; - - spin_lock_irqsave(&dev->vbl_lock, irqflags); - /* Going from 0->1 means we have to enable interrupts again */ - if (atomic_add_return(1, &dev->vblank_refcount[crtc]) == 1 && - !dev->vblank_enabled[crtc]) { - ret = dev->driver->enable_vblank(dev, crtc); - DRM_DEBUG("enabling vblank on crtc %d, ret: %d\n", crtc, ret); - if (ret) - atomic_dec(&dev->vblank_refcount[crtc]); - else { - dev->vblank_enabled[crtc] = 1; - drm_update_vblank_count(dev, crtc); - } - } - spin_unlock_irqrestore(&dev->vbl_lock, irqflags); - - return ret; -} -EXPORT_SYMBOL(drm_vblank_get); - -/** - * drm_vblank_put - give up ownership of vblank events - * @dev: DRM device - * @crtc: which counter to give up - * - * Release ownership of a given vblank counter, turning off interrupts - * if possible. - */ -void drm_vblank_put(struct drm_device *dev, int crtc) -{ - /* Last user schedules interrupt disable */ - if (atomic_dec_and_test(&dev->vblank_refcount[crtc])) - mod_timer(&dev->vblank_disable_timer, jiffies + 5*DRM_HZ); -} -EXPORT_SYMBOL(drm_vblank_put); - -/** - * drm_modeset_ctl - handle vblank event counter changes across mode switch - * @DRM_IOCTL_ARGS: standard ioctl arguments - * - * Applications should call the %_DRM_PRE_MODESET and %_DRM_POST_MODESET - * ioctls around modesetting so that any lost vblank events are accounted for. - * - * Generally the counter will reset across mode sets. If interrupts are - * enabled around this call, we don't have to do anything since the counter - * will have already been incremented. - */ -int drm_modeset_ctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_modeset_ctl *modeset = data; - unsigned long irqflags; - int crtc, ret = 0; - - /* If drm_vblank_init() hasn't been called yet, just no-op */ - if (!dev->num_crtcs) - goto out; - - crtc = modeset->crtc; - if (crtc >= dev->num_crtcs) { - ret = -EINVAL; - goto out; - } - - /* - * To avoid all the problems that might happen if interrupts - * were enabled/disabled around or between these calls, we just - * have the kernel take a reference on the CRTC (just once though - * to avoid corrupting the count if multiple, mismatch calls occur), - * so that interrupts remain enabled in the interim. - */ - switch (modeset->cmd) { - case _DRM_PRE_MODESET: - if (!dev->vblank_inmodeset[crtc]) { - dev->vblank_inmodeset[crtc] = 1; - drm_vblank_get(dev, crtc); - } - break; - case _DRM_POST_MODESET: - if (dev->vblank_inmodeset[crtc]) { - spin_lock_irqsave(&dev->vbl_lock, irqflags); - dev->vblank_disable_allowed = 1; - dev->vblank_inmodeset[crtc] = 0; - spin_unlock_irqrestore(&dev->vbl_lock, irqflags); - drm_vblank_put(dev, crtc); - } - break; - default: - ret = -EINVAL; - break; - } - -out: - return ret; -} - /** * Wait for VBLANK. * @@ -509,14 +232,14 @@ int drm_modeset_ctl(struct drm_device *dev, void *data, * * If a signal is not requested, then calls vblank_wait(). */ -int drm_wait_vblank(struct drm_device *dev, void *data, - struct drm_file *file_priv) +int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_priv) { union drm_wait_vblank *vblwait = data; + struct timeval now; int ret = 0; - unsigned int flags, seq, crtc; + unsigned int flags, seq; - if ((!dev->pdev->irq) || (!dev->irq_enabled)) + if ((!dev->irq) || (!dev->irq_enabled)) return -EINVAL; if (vblwait->request.type & @@ -528,17 +251,13 @@ int drm_wait_vblank(struct drm_device *dev, void *data, } flags = vblwait->request.type & _DRM_VBLANK_FLAGS_MASK; - crtc = flags & _DRM_VBLANK_SECONDARY ? 1 : 0; - if (crtc >= dev->num_crtcs) + if (!drm_core_check_feature(dev, (flags & _DRM_VBLANK_SECONDARY) ? + DRIVER_IRQ_VBL2 : DRIVER_IRQ_VBL)) return -EINVAL; - ret = drm_vblank_get(dev, crtc); - if (ret) { - DRM_ERROR("failed to acquire vblank counter, %d\n", ret); - return ret; - } - seq = drm_vblank_count(dev, crtc); + seq = atomic_read((flags & _DRM_VBLANK_SECONDARY) ? &dev->vbl_received2 + : &dev->vbl_received); switch (vblwait->request.type & _DRM_VBLANK_TYPES_MASK) { case _DRM_VBLANK_RELATIVE: @@ -547,8 +266,7 @@ int drm_wait_vblank(struct drm_device *dev, void *data, case _DRM_VBLANK_ABSOLUTE: break; default: - ret = -EINVAL; - goto done; + return -EINVAL; } if ((flags & _DRM_VBLANK_NEXTONMISS) && @@ -558,7 +276,8 @@ int drm_wait_vblank(struct drm_device *dev, void *data, if (flags & _DRM_VBLANK_SIGNAL) { unsigned long irqflags; - struct list_head *vbl_sigs = &dev->vbl_sigs[crtc]; + struct list_head *vbl_sigs = (flags & _DRM_VBLANK_SECONDARY) + ? &dev->vbl_sigs2 : &dev->vbl_sigs; struct drm_vbl_sig *vbl_sig; spin_lock_irqsave(&dev->vbl_lock, irqflags); @@ -579,29 +298,22 @@ int drm_wait_vblank(struct drm_device *dev, void *data, } } - if (atomic_read(&dev->vbl_signal_pending) >= 100) { + if (dev->vbl_pending >= 100) { spin_unlock_irqrestore(&dev->vbl_lock, irqflags); - ret = -EBUSY; - goto done; + return -EBUSY; } - spin_unlock_irqrestore(&dev->vbl_lock, irqflags); + dev->vbl_pending++; - vbl_sig = drm_calloc(1, sizeof(struct drm_vbl_sig), - DRM_MEM_DRIVER); - if (!vbl_sig) { - ret = -ENOMEM; - goto done; - } + spin_unlock_irqrestore(&dev->vbl_lock, irqflags); - ret = drm_vblank_get(dev, crtc); - if (ret) { - drm_free(vbl_sig, sizeof(struct drm_vbl_sig), - DRM_MEM_DRIVER); - return ret; + if (! + (vbl_sig = + drm_alloc(sizeof(struct drm_vbl_sig), DRM_MEM_DRIVER))) { + return -ENOMEM; } - atomic_inc(&dev->vbl_signal_pending); + memset((void *)vbl_sig, 0, sizeof(*vbl_sig)); vbl_sig->sequence = vblwait->request.sequence; vbl_sig->info.si_signo = vblwait->request.signal; @@ -615,29 +327,20 @@ int drm_wait_vblank(struct drm_device *dev, void *data, vblwait->reply.sequence = seq; } else { - DRM_DEBUG("waiting on vblank count %d, crtc %d\n", - vblwait->request.sequence, crtc); - DRM_WAIT_ON(ret, dev->vbl_queue[crtc], 3 * DRM_HZ, - ((drm_vblank_count(dev, crtc) - - vblwait->request.sequence) <= (1 << 23))); - - if (ret != -EINTR) { - struct timeval now; - - do_gettimeofday(&now); - - vblwait->reply.tval_sec = now.tv_sec; - vblwait->reply.tval_usec = now.tv_usec; - vblwait->reply.sequence = drm_vblank_count(dev, crtc); - DRM_DEBUG("returning %d to client\n", - vblwait->reply.sequence); - } else { - DRM_DEBUG("vblank wait interrupted by signal\n"); - } + if (flags & _DRM_VBLANK_SECONDARY) { + if (dev->driver->vblank_wait2) + ret = dev->driver->vblank_wait2(dev, &vblwait->request.sequence); + } else if (dev->driver->vblank_wait) + ret = + dev->driver->vblank_wait(dev, + &vblwait->request.sequence); + + do_gettimeofday(&now); + vblwait->reply.tval_sec = now.tv_sec; + vblwait->reply.tval_usec = now.tv_usec; } -done: - drm_vblank_put(dev, crtc); + done: return ret; } @@ -645,57 +348,44 @@ int drm_wait_vblank(struct drm_device *dev, void *data, * Send the VBLANK signals. * * \param dev DRM device. - * \param crtc CRTC where the vblank event occurred * * Sends a signal for each task in drm_device::vbl_sigs and empties the list. * * If a signal is not requested, then calls vblank_wait(). */ -static void drm_vbl_send_signals(struct drm_device *dev, int crtc) +void drm_vbl_send_signals(struct drm_device * dev) { - struct drm_vbl_sig *vbl_sig, *tmp; - struct list_head *vbl_sigs; - unsigned int vbl_seq; unsigned long flags; + int i; spin_lock_irqsave(&dev->vbl_lock, flags); - vbl_sigs = &dev->vbl_sigs[crtc]; - vbl_seq = drm_vblank_count(dev, crtc); + for (i = 0; i < 2; i++) { + struct drm_vbl_sig *vbl_sig, *tmp; + struct list_head *vbl_sigs = i ? &dev->vbl_sigs2 : &dev->vbl_sigs; + unsigned int vbl_seq = atomic_read(i ? &dev->vbl_received2 : + &dev->vbl_received); - list_for_each_entry_safe(vbl_sig, tmp, vbl_sigs, head) { - if ((vbl_seq - vbl_sig->sequence) <= (1 << 23)) { - vbl_sig->info.si_code = vbl_seq; - send_sig_info(vbl_sig->info.si_signo, - &vbl_sig->info, vbl_sig->task); + list_for_each_entry_safe(vbl_sig, tmp, vbl_sigs, head) { + if ((vbl_seq - vbl_sig->sequence) <= (1 << 23)) { + vbl_sig->info.si_code = vbl_seq; + send_sig_info(vbl_sig->info.si_signo, + &vbl_sig->info, vbl_sig->task); - list_del(&vbl_sig->head); + list_del(&vbl_sig->head); + + drm_free(vbl_sig, sizeof(*vbl_sig), + DRM_MEM_DRIVER); - drm_free(vbl_sig, sizeof(*vbl_sig), - DRM_MEM_DRIVER); - atomic_dec(&dev->vbl_signal_pending); - drm_vblank_put(dev, crtc); - } + dev->vbl_pending--; + } + } } spin_unlock_irqrestore(&dev->vbl_lock, flags); } -/** - * drm_handle_vblank - handle a vblank event - * @dev: DRM device - * @crtc: where this event occurred - * - * Drivers should call this routine in their vblank interrupt handlers to - * update the vblank counter and send any signals that may be pending. - */ -void drm_handle_vblank(struct drm_device *dev, int crtc) -{ - atomic_inc(&dev->_vblank_count[crtc]); - DRM_WAKEUP(&dev->vbl_queue[crtc]); - drm_vbl_send_signals(dev, crtc); -} -EXPORT_SYMBOL(drm_handle_vblank); +EXPORT_SYMBOL(drm_vbl_send_signals); /** * Tasklet wrapper function. diff --git a/trunk/drivers/gpu/drm/drm_memory.c b/trunk/drivers/gpu/drm/drm_memory.c index 803bc9e7ce3c..0177012845c6 100644 --- a/trunk/drivers/gpu/drm/drm_memory.c +++ b/trunk/drivers/gpu/drm/drm_memory.c @@ -133,7 +133,6 @@ int drm_free_agp(DRM_AGP_MEM * handle, int pages) { return drm_agp_free_memory(handle) ? 0 : -EINVAL; } -EXPORT_SYMBOL(drm_free_agp); /** Wrapper around agp_bind_memory() */ int drm_bind_agp(DRM_AGP_MEM * handle, unsigned int start) @@ -146,7 +145,6 @@ int drm_unbind_agp(DRM_AGP_MEM * handle) { return drm_agp_unbind_memory(handle); } -EXPORT_SYMBOL(drm_unbind_agp); #else /* __OS_HAS_AGP */ static inline void *agp_remap(unsigned long offset, unsigned long size, diff --git a/trunk/drivers/gpu/drm/drm_mm.c b/trunk/drivers/gpu/drm/drm_mm.c index 217ad7dc7076..dcff9e9b52e3 100644 --- a/trunk/drivers/gpu/drm/drm_mm.c +++ b/trunk/drivers/gpu/drm/drm_mm.c @@ -169,7 +169,6 @@ struct drm_mm_node *drm_mm_get_block(struct drm_mm_node * parent, return child; } -EXPORT_SYMBOL(drm_mm_get_block); /* * Put a block. Merge with the previous and / or next block if they are free. @@ -218,7 +217,6 @@ void drm_mm_put_block(struct drm_mm_node * cur) drm_free(cur, sizeof(*cur), DRM_MEM_MM); } } -EXPORT_SYMBOL(drm_mm_put_block); struct drm_mm_node *drm_mm_search_free(const struct drm_mm * mm, unsigned long size, @@ -267,7 +265,6 @@ int drm_mm_clean(struct drm_mm * mm) return (head->next->next == head); } -EXPORT_SYMBOL(drm_mm_search_free); int drm_mm_init(struct drm_mm * mm, unsigned long start, unsigned long size) { @@ -276,7 +273,7 @@ int drm_mm_init(struct drm_mm * mm, unsigned long start, unsigned long size) return drm_mm_create_tail_node(mm, start, size); } -EXPORT_SYMBOL(drm_mm_init); + void drm_mm_takedown(struct drm_mm * mm) { diff --git a/trunk/drivers/gpu/drm/drm_proc.c b/trunk/drivers/gpu/drm/drm_proc.c index d490db4c0de0..93b1e0475c93 100644 --- a/trunk/drivers/gpu/drm/drm_proc.c +++ b/trunk/drivers/gpu/drm/drm_proc.c @@ -49,10 +49,6 @@ static int drm_queues_info(char *buf, char **start, off_t offset, int request, int *eof, void *data); static int drm_bufs_info(char *buf, char **start, off_t offset, int request, int *eof, void *data); -static int drm_gem_name_info(char *buf, char **start, off_t offset, - int request, int *eof, void *data); -static int drm_gem_object_info(char *buf, char **start, off_t offset, - int request, int *eof, void *data); #if DRM_DEBUG_CODE static int drm_vma_info(char *buf, char **start, off_t offset, int request, int *eof, void *data); @@ -64,16 +60,13 @@ static int drm_vma_info(char *buf, char **start, off_t offset, static struct drm_proc_list { const char *name; /**< file name */ int (*f) (char *, char **, off_t, int, int *, void *); /**< proc callback*/ - u32 driver_features; /**< Required driver features for this entry */ } drm_proc_list[] = { - {"name", drm_name_info, 0}, - {"mem", drm_mem_info, 0}, - {"vm", drm_vm_info, 0}, - {"clients", drm_clients_info, 0}, - {"queues", drm_queues_info, 0}, - {"bufs", drm_bufs_info, 0}, - {"gem_names", drm_gem_name_info, DRIVER_GEM}, - {"gem_objects", drm_gem_object_info, DRIVER_GEM}, + {"name", drm_name_info}, + {"mem", drm_mem_info}, + {"vm", drm_vm_info}, + {"clients", drm_clients_info}, + {"queues", drm_queues_info}, + {"bufs", drm_bufs_info}, #if DRM_DEBUG_CODE {"vma", drm_vma_info}, #endif @@ -97,9 +90,8 @@ static struct drm_proc_list { int drm_proc_init(struct drm_minor *minor, int minor_id, struct proc_dir_entry *root) { - struct drm_device *dev = minor->dev; struct proc_dir_entry *ent; - int i, j, ret; + int i, j; char name[64]; sprintf(name, "%d", minor_id); @@ -110,42 +102,23 @@ int drm_proc_init(struct drm_minor *minor, int minor_id, } for (i = 0; i < DRM_PROC_ENTRIES; i++) { - u32 features = drm_proc_list[i].driver_features; - - if (features != 0 && - (dev->driver->driver_features & features) != features) - continue; - ent = create_proc_entry(drm_proc_list[i].name, S_IFREG | S_IRUGO, minor->dev_root); if (!ent) { DRM_ERROR("Cannot create /proc/dri/%s/%s\n", name, drm_proc_list[i].name); - ret = -1; - goto fail; + for (j = 0; j < i; j++) + remove_proc_entry(drm_proc_list[i].name, + minor->dev_root); + remove_proc_entry(name, root); + minor->dev_root = NULL; + return -1; } ent->read_proc = drm_proc_list[i].f; ent->data = minor; } - if (dev->driver->proc_init) { - ret = dev->driver->proc_init(minor); - if (ret) { - DRM_ERROR("DRM: Driver failed to initialize " - "/proc/dri.\n"); - goto fail; - } - } - return 0; - fail: - - for (j = 0; j < i; j++) - remove_proc_entry(drm_proc_list[i].name, - minor->dev_root); - remove_proc_entry(name, root); - minor->dev_root = NULL; - return ret; } /** @@ -160,16 +133,12 @@ int drm_proc_init(struct drm_minor *minor, int minor_id, */ int drm_proc_cleanup(struct drm_minor *minor, struct proc_dir_entry *root) { - struct drm_device *dev = minor->dev; int i; char name[64]; if (!root || !minor->dev_root) return 0; - if (dev->driver->proc_cleanup) - dev->driver->proc_cleanup(minor); - for (i = 0; i < DRM_PROC_ENTRIES; i++) remove_proc_entry(drm_proc_list[i].name, minor->dev_root); sprintf(name, "%d", minor->index); @@ -511,84 +480,6 @@ static int drm_clients_info(char *buf, char **start, off_t offset, return ret; } -struct drm_gem_name_info_data { - int len; - char *buf; - int eof; -}; - -static int drm_gem_one_name_info(int id, void *ptr, void *data) -{ - struct drm_gem_object *obj = ptr; - struct drm_gem_name_info_data *nid = data; - - DRM_INFO("name %d size %d\n", obj->name, obj->size); - if (nid->eof) - return 0; - - nid->len += sprintf(&nid->buf[nid->len], - "%6d%9d%8d%9d\n", - obj->name, obj->size, - atomic_read(&obj->handlecount.refcount), - atomic_read(&obj->refcount.refcount)); - if (nid->len > DRM_PROC_LIMIT) { - nid->eof = 1; - return 0; - } - return 0; -} - -static int drm_gem_name_info(char *buf, char **start, off_t offset, - int request, int *eof, void *data) -{ - struct drm_minor *minor = (struct drm_minor *) data; - struct drm_device *dev = minor->dev; - struct drm_gem_name_info_data nid; - - if (offset > DRM_PROC_LIMIT) { - *eof = 1; - return 0; - } - - nid.len = sprintf(buf, " name size handles refcount\n"); - nid.buf = buf; - nid.eof = 0; - idr_for_each(&dev->object_name_idr, drm_gem_one_name_info, &nid); - - *start = &buf[offset]; - *eof = 0; - if (nid.len > request + offset) - return request; - *eof = 1; - return nid.len - offset; -} - -static int drm_gem_object_info(char *buf, char **start, off_t offset, - int request, int *eof, void *data) -{ - struct drm_minor *minor = (struct drm_minor *) data; - struct drm_device *dev = minor->dev; - int len = 0; - - if (offset > DRM_PROC_LIMIT) { - *eof = 1; - return 0; - } - - *start = &buf[offset]; - *eof = 0; - DRM_PROC_PRINT("%d objects\n", atomic_read(&dev->object_count)); - DRM_PROC_PRINT("%d object bytes\n", atomic_read(&dev->object_memory)); - DRM_PROC_PRINT("%d pinned\n", atomic_read(&dev->pin_count)); - DRM_PROC_PRINT("%d pin bytes\n", atomic_read(&dev->pin_memory)); - DRM_PROC_PRINT("%d gtt bytes\n", atomic_read(&dev->gtt_memory)); - DRM_PROC_PRINT("%d gtt total\n", dev->gtt_total); - if (len > request + offset) - return request; - *eof = 1; - return len - offset; -} - #if DRM_DEBUG_CODE static int drm__vma_info(char *buf, char **start, off_t offset, int request, diff --git a/trunk/drivers/gpu/drm/drm_stub.c b/trunk/drivers/gpu/drm/drm_stub.c index 141e33004a76..c2f584f3b46c 100644 --- a/trunk/drivers/gpu/drm/drm_stub.c +++ b/trunk/drivers/gpu/drm/drm_stub.c @@ -107,6 +107,7 @@ static int drm_fill_in_dev(struct drm_device * dev, struct pci_dev *pdev, #ifdef __alpha__ dev->hose = pdev->sysdata; #endif + dev->irq = pdev->irq; if (drm_ht_create(&dev->map_hash, 12)) { return -ENOMEM; @@ -151,15 +152,6 @@ static int drm_fill_in_dev(struct drm_device * dev, struct pci_dev *pdev, goto error_out_unreg; } - if (driver->driver_features & DRIVER_GEM) { - retcode = drm_gem_init(dev); - if (retcode) { - DRM_ERROR("Cannot initialize graphics execution " - "manager (GEM)\n"); - goto error_out_unreg; - } - } - return 0; error_out_unreg: @@ -325,7 +317,6 @@ int drm_put_dev(struct drm_device * dev) int drm_put_minor(struct drm_minor **minor_p) { struct drm_minor *minor = *minor_p; - DRM_DEBUG("release secondary minor %d\n", minor->index); if (minor->type == DRM_MINOR_LEGACY) diff --git a/trunk/drivers/gpu/drm/drm_sysfs.c b/trunk/drivers/gpu/drm/drm_sysfs.c index 1611b9bcbe7f..af211a0ef179 100644 --- a/trunk/drivers/gpu/drm/drm_sysfs.c +++ b/trunk/drivers/gpu/drm/drm_sysfs.c @@ -184,7 +184,7 @@ int drm_sysfs_device_add(struct drm_minor *minor) err_out_files: if (i > 0) for (j = 0; j < i; j++) - device_remove_file(&minor->kdev, &device_attrs[j]); + device_remove_file(&minor->kdev, &device_attrs[i]); device_unregister(&minor->kdev); err_out: diff --git a/trunk/drivers/gpu/drm/i915/Makefile b/trunk/drivers/gpu/drm/i915/Makefile index 5ba78e4fd2b5..a9e60464df74 100644 --- a/trunk/drivers/gpu/drm/i915/Makefile +++ b/trunk/drivers/gpu/drm/i915/Makefile @@ -3,12 +3,7 @@ # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. ccflags-y := -Iinclude/drm -i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o i915_opregion.o \ - i915_suspend.o \ - i915_gem.o \ - i915_gem_debug.o \ - i915_gem_proc.o \ - i915_gem_tiling.o +i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o i915-$(CONFIG_COMPAT) += i915_ioc32.o diff --git a/trunk/drivers/gpu/drm/i915/i915_dma.c b/trunk/drivers/gpu/drm/i915/i915_dma.c index db34780edbb2..9ac4720e647b 100644 --- a/trunk/drivers/gpu/drm/i915/i915_dma.c +++ b/trunk/drivers/gpu/drm/i915/i915_dma.c @@ -40,96 +40,40 @@ int i915_wait_ring(struct drm_device * dev, int n, const char *caller) { drm_i915_private_t *dev_priv = dev->dev_private; drm_i915_ring_buffer_t *ring = &(dev_priv->ring); - u32 acthd_reg = IS_I965G(dev) ? ACTHD_I965 : ACTHD; - u32 last_acthd = I915_READ(acthd_reg); - u32 acthd; - u32 last_head = I915_READ(PRB0_HEAD) & HEAD_ADDR; + u32 last_head = I915_READ(LP_RING + RING_HEAD) & HEAD_ADDR; int i; - for (i = 0; i < 100000; i++) { - ring->head = I915_READ(PRB0_HEAD) & HEAD_ADDR; - acthd = I915_READ(acthd_reg); + for (i = 0; i < 10000; i++) { + ring->head = I915_READ(LP_RING + RING_HEAD) & HEAD_ADDR; ring->space = ring->head - (ring->tail + 8); if (ring->space < 0) ring->space += ring->Size; if (ring->space >= n) return 0; - if (dev_priv->sarea_priv) - dev_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT; + dev_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT; if (ring->head != last_head) i = 0; - if (acthd != last_acthd) - i = 0; last_head = ring->head; - last_acthd = acthd; - msleep_interruptible(10); - } return -EBUSY; } -/** - * Sets up the hardware status page for devices that need a physical address - * in the register. - */ -static int i915_init_phys_hws(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - /* Program Hardware Status Page */ - dev_priv->status_page_dmah = - drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 0xffffffff); - - if (!dev_priv->status_page_dmah) { - DRM_ERROR("Can not allocate hardware status page\n"); - return -ENOMEM; - } - dev_priv->hw_status_page = dev_priv->status_page_dmah->vaddr; - dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr; - - memset(dev_priv->hw_status_page, 0, PAGE_SIZE); - - I915_WRITE(HWS_PGA, dev_priv->dma_status_page); - DRM_DEBUG("Enabled hardware status page\n"); - return 0; -} - -/** - * Frees the hardware status page, whether it's a physical address or a virtual - * address set up by the X Server. - */ -static void i915_free_hws(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - if (dev_priv->status_page_dmah) { - drm_pci_free(dev, dev_priv->status_page_dmah); - dev_priv->status_page_dmah = NULL; - } - - if (dev_priv->status_gfx_addr) { - dev_priv->status_gfx_addr = 0; - drm_core_ioremapfree(&dev_priv->hws_map, dev); - } - - /* Need to rewrite hardware status page */ - I915_WRITE(HWS_PGA, 0x1ffff000); -} - void i915_kernel_lost_context(struct drm_device * dev) { drm_i915_private_t *dev_priv = dev->dev_private; drm_i915_ring_buffer_t *ring = &(dev_priv->ring); - ring->head = I915_READ(PRB0_HEAD) & HEAD_ADDR; - ring->tail = I915_READ(PRB0_TAIL) & TAIL_ADDR; + ring->head = I915_READ(LP_RING + RING_HEAD) & HEAD_ADDR; + ring->tail = I915_READ(LP_RING + RING_TAIL) & TAIL_ADDR; ring->space = ring->head - (ring->tail + 8); if (ring->space < 0) ring->space += ring->Size; - if (ring->head == ring->tail && dev_priv->sarea_priv) + if (ring->head == ring->tail) dev_priv->sarea_priv->perf_boxes |= I915_BOX_RING_EMPTY; } @@ -140,19 +84,28 @@ static int i915_dma_cleanup(struct drm_device * dev) * may not have been called from userspace and after dev_private * is freed, it's too late. */ - if (dev->irq_enabled) + if (dev->irq) drm_irq_uninstall(dev); if (dev_priv->ring.virtual_start) { drm_core_ioremapfree(&dev_priv->ring.map, dev); - dev_priv->ring.virtual_start = NULL; - dev_priv->ring.map.handle = NULL; + dev_priv->ring.virtual_start = 0; + dev_priv->ring.map.handle = 0; dev_priv->ring.map.size = 0; } - /* Clear the HWS virtual address at teardown */ - if (I915_NEED_GFX_HWS(dev)) - i915_free_hws(dev); + if (dev_priv->status_page_dmah) { + drm_pci_free(dev, dev_priv->status_page_dmah); + dev_priv->status_page_dmah = NULL; + /* Need to rewrite hardware status page */ + I915_WRITE(0x02080, 0x1ffff000); + } + + if (dev_priv->status_gfx_addr) { + dev_priv->status_gfx_addr = 0; + drm_core_ioremapfree(&dev_priv->hws_map, dev); + I915_WRITE(0x2080, 0x1ffff000); + } return 0; } @@ -168,34 +121,34 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init) return -EINVAL; } + dev_priv->mmio_map = drm_core_findmap(dev, init->mmio_offset); + if (!dev_priv->mmio_map) { + i915_dma_cleanup(dev); + DRM_ERROR("can not find mmio map!\n"); + return -EINVAL; + } + dev_priv->sarea_priv = (drm_i915_sarea_t *) ((u8 *) dev_priv->sarea->handle + init->sarea_priv_offset); - if (init->ring_size != 0) { - if (dev_priv->ring.ring_obj != NULL) { - i915_dma_cleanup(dev); - DRM_ERROR("Client tried to initialize ringbuffer in " - "GEM mode\n"); - return -EINVAL; - } - - dev_priv->ring.Size = init->ring_size; - dev_priv->ring.tail_mask = dev_priv->ring.Size - 1; + dev_priv->ring.Start = init->ring_start; + dev_priv->ring.End = init->ring_end; + dev_priv->ring.Size = init->ring_size; + dev_priv->ring.tail_mask = dev_priv->ring.Size - 1; - dev_priv->ring.map.offset = init->ring_start; - dev_priv->ring.map.size = init->ring_size; - dev_priv->ring.map.type = 0; - dev_priv->ring.map.flags = 0; - dev_priv->ring.map.mtrr = 0; + dev_priv->ring.map.offset = init->ring_start; + dev_priv->ring.map.size = init->ring_size; + dev_priv->ring.map.type = 0; + dev_priv->ring.map.flags = 0; + dev_priv->ring.map.mtrr = 0; - drm_core_ioremap(&dev_priv->ring.map, dev); + drm_core_ioremap(&dev_priv->ring.map, dev); - if (dev_priv->ring.map.handle == NULL) { - i915_dma_cleanup(dev); - DRM_ERROR("can not ioremap virtual address for" - " ring buffer\n"); - return -ENOMEM; - } + if (dev_priv->ring.map.handle == NULL) { + i915_dma_cleanup(dev); + DRM_ERROR("can not ioremap virtual address for" + " ring buffer\n"); + return -ENOMEM; } dev_priv->ring.virtual_start = dev_priv->ring.map.handle; @@ -206,10 +159,34 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init) dev_priv->current_page = 0; dev_priv->sarea_priv->pf_current_page = dev_priv->current_page; + /* We are using separate values as placeholders for mechanisms for + * private backbuffer/depthbuffer usage. + */ + dev_priv->use_mi_batchbuffer_start = 0; + if (IS_I965G(dev)) /* 965 doesn't support older method */ + dev_priv->use_mi_batchbuffer_start = 1; + /* Allow hardware batchbuffers unless told otherwise. */ dev_priv->allow_batchbuffer = 1; + /* Program Hardware Status Page */ + if (!I915_NEED_GFX_HWS(dev)) { + dev_priv->status_page_dmah = + drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 0xffffffff); + + if (!dev_priv->status_page_dmah) { + i915_dma_cleanup(dev); + DRM_ERROR("Can not allocate hardware status page\n"); + return -ENOMEM; + } + dev_priv->hw_status_page = dev_priv->status_page_dmah->vaddr; + dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr; + + memset(dev_priv->hw_status_page, 0, PAGE_SIZE); + I915_WRITE(0x02080, dev_priv->dma_status_page); + } + DRM_DEBUG("Enabled hardware status page\n"); return 0; } @@ -224,6 +201,11 @@ static int i915_dma_resume(struct drm_device * dev) return -EINVAL; } + if (!dev_priv->mmio_map) { + DRM_ERROR("can not find mmio map!\n"); + return -EINVAL; + } + if (dev_priv->ring.map.handle == NULL) { DRM_ERROR("can not ioremap virtual address for" " ring buffer\n"); @@ -238,9 +220,9 @@ static int i915_dma_resume(struct drm_device * dev) DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page); if (dev_priv->status_gfx_addr != 0) - I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr); + I915_WRITE(0x02080, dev_priv->status_gfx_addr); else - I915_WRITE(HWS_PGA, dev_priv->dma_status_page); + I915_WRITE(0x02080, dev_priv->dma_status_page); DRM_DEBUG("Enabled hardware status page\n"); return 0; @@ -385,10 +367,9 @@ static int i915_emit_cmds(struct drm_device * dev, int __user * buffer, int dwor return 0; } -int -i915_emit_box(struct drm_device *dev, - struct drm_clip_rect __user *boxes, - int i, int DR1, int DR4) +static int i915_emit_box(struct drm_device * dev, + struct drm_clip_rect __user * boxes, + int i, int DR1, int DR4) { drm_i915_private_t *dev_priv = dev->dev_private; struct drm_clip_rect box; @@ -434,15 +415,14 @@ static void i915_emit_breadcrumb(struct drm_device *dev) drm_i915_private_t *dev_priv = dev->dev_private; RING_LOCALS; - dev_priv->counter++; + dev_priv->sarea_priv->last_enqueue = ++dev_priv->counter; + if (dev_priv->counter > 0x7FFFFFFFUL) - dev_priv->counter = 0; - if (dev_priv->sarea_priv) - dev_priv->sarea_priv->last_enqueue = dev_priv->counter; + dev_priv->sarea_priv->last_enqueue = dev_priv->counter = 1; BEGIN_LP_RING(4); - OUT_RING(MI_STORE_DWORD_INDEX); - OUT_RING(5 << MI_STORE_DWORD_INDEX_SHIFT); + OUT_RING(CMD_STORE_DWORD_IDX); + OUT_RING(20); OUT_RING(dev_priv->counter); OUT_RING(0); ADVANCE_LP_RING(); @@ -506,7 +486,7 @@ static int i915_dispatch_batchbuffer(struct drm_device * dev, return ret; } - if (!IS_I830(dev) && !IS_845G(dev)) { + if (dev_priv->use_mi_batchbuffer_start) { BEGIN_LP_RING(2); if (IS_I965G(dev)) { OUT_RING(MI_BATCH_BUFFER_START | (2 << 6) | MI_BATCH_NON_SECURE_I965); @@ -536,9 +516,6 @@ static int i915_dispatch_flip(struct drm_device * dev) drm_i915_private_t *dev_priv = dev->dev_private; RING_LOCALS; - if (!dev_priv->sarea_priv) - return -EINVAL; - DRM_DEBUG("%s: page=%d pfCurrentPage=%d\n", __func__, dev_priv->current_page, @@ -547,7 +524,7 @@ static int i915_dispatch_flip(struct drm_device * dev) i915_kernel_lost_context(dev); BEGIN_LP_RING(2); - OUT_RING(MI_FLUSH | MI_READ_FLUSH); + OUT_RING(INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE); OUT_RING(0); ADVANCE_LP_RING(); @@ -572,8 +549,8 @@ static int i915_dispatch_flip(struct drm_device * dev) dev_priv->sarea_priv->last_enqueue = dev_priv->counter++; BEGIN_LP_RING(4); - OUT_RING(MI_STORE_DWORD_INDEX); - OUT_RING(5 << MI_STORE_DWORD_INDEX_SHIFT); + OUT_RING(CMD_STORE_DWORD_IDX); + OUT_RING(20); OUT_RING(dev_priv->counter); OUT_RING(0); ADVANCE_LP_RING(); @@ -593,15 +570,9 @@ static int i915_quiescent(struct drm_device * dev) static int i915_flush_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { - int ret; - - RING_LOCK_TEST_WITH_RETURN(dev, file_priv); - - mutex_lock(&dev->struct_mutex); - ret = i915_quiescent(dev); - mutex_unlock(&dev->struct_mutex); + LOCK_TEST_WITH_RETURN(dev, file_priv); - return ret; + return i915_quiescent(dev); } static int i915_batchbuffer(struct drm_device *dev, void *data, @@ -622,19 +593,16 @@ static int i915_batchbuffer(struct drm_device *dev, void *data, DRM_DEBUG("i915 batchbuffer, start %x used %d cliprects %d\n", batch->start, batch->used, batch->num_cliprects); - RING_LOCK_TEST_WITH_RETURN(dev, file_priv); + LOCK_TEST_WITH_RETURN(dev, file_priv); if (batch->num_cliprects && DRM_VERIFYAREA_READ(batch->cliprects, batch->num_cliprects * sizeof(struct drm_clip_rect))) return -EFAULT; - mutex_lock(&dev->struct_mutex); ret = i915_dispatch_batchbuffer(dev, batch); - mutex_unlock(&dev->struct_mutex); - if (sarea_priv) - sarea_priv->last_dispatch = (int)hw_status[5]; + sarea_priv->last_dispatch = (int)hw_status[5]; return ret; } @@ -651,7 +619,7 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data, DRM_DEBUG("i915 cmdbuffer, buf %p sz %d cliprects %d\n", cmdbuf->buf, cmdbuf->sz, cmdbuf->num_cliprects); - RING_LOCK_TEST_WITH_RETURN(dev, file_priv); + LOCK_TEST_WITH_RETURN(dev, file_priv); if (cmdbuf->num_cliprects && DRM_VERIFYAREA_READ(cmdbuf->cliprects, @@ -661,33 +629,24 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data, return -EFAULT; } - mutex_lock(&dev->struct_mutex); ret = i915_dispatch_cmdbuffer(dev, cmdbuf); - mutex_unlock(&dev->struct_mutex); if (ret) { DRM_ERROR("i915_dispatch_cmdbuffer failed\n"); return ret; } - if (sarea_priv) - sarea_priv->last_dispatch = (int)hw_status[5]; + sarea_priv->last_dispatch = (int)hw_status[5]; return 0; } static int i915_flip_bufs(struct drm_device *dev, void *data, struct drm_file *file_priv) { - int ret; - DRM_DEBUG("%s\n", __func__); - RING_LOCK_TEST_WITH_RETURN(dev, file_priv); - - mutex_lock(&dev->struct_mutex); - ret = i915_dispatch_flip(dev); - mutex_unlock(&dev->struct_mutex); + LOCK_TEST_WITH_RETURN(dev, file_priv); - return ret; + return i915_dispatch_flip(dev); } static int i915_getparam(struct drm_device *dev, void *data, @@ -704,7 +663,7 @@ static int i915_getparam(struct drm_device *dev, void *data, switch (param->param) { case I915_PARAM_IRQ_ACTIVE: - value = dev->pdev->irq ? 1 : 0; + value = dev->irq ? 1 : 0; break; case I915_PARAM_ALLOW_BATCHBUFFER: value = dev_priv->allow_batchbuffer ? 1 : 0; @@ -712,12 +671,6 @@ static int i915_getparam(struct drm_device *dev, void *data, case I915_PARAM_LAST_DISPATCH: value = READ_BREADCRUMB(dev_priv); break; - case I915_PARAM_CHIPSET_ID: - value = dev->pci_device; - break; - case I915_PARAM_HAS_GEM: - value = 1; - break; default: DRM_ERROR("Unknown parameter %d\n", param->param); return -EINVAL; @@ -744,6 +697,8 @@ static int i915_setparam(struct drm_device *dev, void *data, switch (param->param) { case I915_SETPARAM_USE_MI_BATCHBUFFER_START: + if (!IS_I965G(dev)) + dev_priv->use_mi_batchbuffer_start = param->value; break; case I915_SETPARAM_TEX_LRU_LOG_GRANULARITY: dev_priv->tex_lru_log_granularity = param->value; @@ -794,8 +749,8 @@ static int i915_set_status_page(struct drm_device *dev, void *data, dev_priv->hw_status_page = dev_priv->hws_map.handle; memset(dev_priv->hw_status_page, 0, PAGE_SIZE); - I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr); - DRM_DEBUG("load hws HWS_PGA with gfx mem 0x%x\n", + I915_WRITE(0x02080, dev_priv->status_gfx_addr); + DRM_DEBUG("load hws 0x2080 with gfx mem 0x%x\n", dev_priv->status_gfx_addr); DRM_DEBUG("load hws at %p\n", dev_priv->hw_status_page); return 0; @@ -821,38 +776,14 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) memset(dev_priv, 0, sizeof(drm_i915_private_t)); dev->dev_private = (void *)dev_priv; - dev_priv->dev = dev; /* Add register map (needed for suspend/resume) */ base = drm_get_resource_start(dev, mmio_bar); size = drm_get_resource_len(dev, mmio_bar); - dev_priv->regs = ioremap(base, size); - - i915_gem_load(dev); - - /* Init HWS */ - if (!I915_NEED_GFX_HWS(dev)) { - ret = i915_init_phys_hws(dev); - if (ret != 0) - return ret; - } - - /* On the 945G/GM, the chipset reports the MSI capability on the - * integrated graphics even though the support isn't actually there - * according to the published specs. It doesn't appear to function - * correctly in testing on 945G. - * This may be a side effect of MSI having been made available for PEG - * and the registers being closely associated. - */ - if (!IS_I945G(dev) && !IS_I945GM(dev)) - if (pci_enable_msi(dev->pdev)) - DRM_ERROR("failed to enable MSI\n"); - - intel_opregion_init(dev); - - spin_lock_init(&dev_priv->user_irq_lock); - + ret = drm_addmap(dev, base, size, _DRM_REGISTERS, + _DRM_KERNEL | _DRM_DRIVER, + &dev_priv->mmio_map); return ret; } @@ -860,15 +791,8 @@ int i915_driver_unload(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - if (dev->pdev->msi_enabled) - pci_disable_msi(dev->pdev); - - i915_free_hws(dev); - - if (dev_priv->regs != NULL) - iounmap(dev_priv->regs); - - intel_opregion_free(dev); + if (dev_priv->mmio_map) + drm_rmmap(dev, dev_priv->mmio_map); drm_free(dev->dev_private, sizeof(drm_i915_private_t), DRM_MEM_DRIVER); @@ -876,25 +800,6 @@ int i915_driver_unload(struct drm_device *dev) return 0; } -int i915_driver_open(struct drm_device *dev, struct drm_file *file_priv) -{ - struct drm_i915_file_private *i915_file_priv; - - DRM_DEBUG("\n"); - i915_file_priv = (struct drm_i915_file_private *) - drm_alloc(sizeof(*i915_file_priv), DRM_MEM_FILES); - - if (!i915_file_priv) - return -ENOMEM; - - file_priv->driver_priv = i915_file_priv; - - i915_file_priv->mm.last_gem_seqno = 0; - i915_file_priv->mm.last_gem_throttle_seqno = 0; - - return 0; -} - void i915_driver_lastclose(struct drm_device * dev) { drm_i915_private_t *dev_priv = dev->dev_private; @@ -902,8 +807,6 @@ void i915_driver_lastclose(struct drm_device * dev) if (!dev_priv) return; - i915_gem_lastclose(dev); - if (dev_priv->agp_heap) i915_mem_takedown(&(dev_priv->agp_heap)); @@ -916,13 +819,6 @@ void i915_driver_preclose(struct drm_device * dev, struct drm_file *file_priv) i915_mem_release(dev, file_priv, dev_priv->agp_heap); } -void i915_driver_postclose(struct drm_device *dev, struct drm_file *file_priv) -{ - struct drm_i915_file_private *i915_file_priv = file_priv->driver_priv; - - drm_free(i915_file_priv, sizeof(*i915_file_priv), DRM_MEM_FILES); -} - struct drm_ioctl_desc i915_ioctls[] = { DRM_IOCTL_DEF(DRM_I915_INIT, i915_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), DRM_IOCTL_DEF(DRM_I915_FLUSH, i915_flush_ioctl, DRM_AUTH), @@ -940,23 +836,7 @@ struct drm_ioctl_desc i915_ioctls[] = { DRM_IOCTL_DEF(DRM_I915_SET_VBLANK_PIPE, i915_vblank_pipe_set, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY ), DRM_IOCTL_DEF(DRM_I915_GET_VBLANK_PIPE, i915_vblank_pipe_get, DRM_AUTH ), DRM_IOCTL_DEF(DRM_I915_VBLANK_SWAP, i915_vblank_swap, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I915_HWS_ADDR, i915_set_status_page, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_I915_GEM_INIT, i915_gem_init_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_I915_GEM_EXECBUFFER, i915_gem_execbuffer, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I915_GEM_PIN, i915_gem_pin_ioctl, DRM_AUTH|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_I915_GEM_UNPIN, i915_gem_unpin_ioctl, DRM_AUTH|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_I915_GEM_BUSY, i915_gem_busy_ioctl, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I915_GEM_THROTTLE, i915_gem_throttle_ioctl, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I915_GEM_ENTERVT, i915_gem_entervt_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_I915_GEM_LEAVEVT, i915_gem_leavevt_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_I915_GEM_CREATE, i915_gem_create_ioctl, 0), - DRM_IOCTL_DEF(DRM_I915_GEM_PREAD, i915_gem_pread_ioctl, 0), - DRM_IOCTL_DEF(DRM_I915_GEM_PWRITE, i915_gem_pwrite_ioctl, 0), - DRM_IOCTL_DEF(DRM_I915_GEM_MMAP, i915_gem_mmap_ioctl, 0), - DRM_IOCTL_DEF(DRM_I915_GEM_SET_DOMAIN, i915_gem_set_domain_ioctl, 0), - DRM_IOCTL_DEF(DRM_I915_GEM_SW_FINISH, i915_gem_sw_finish_ioctl, 0), - DRM_IOCTL_DEF(DRM_I915_GEM_SET_TILING, i915_gem_set_tiling, 0), - DRM_IOCTL_DEF(DRM_I915_GEM_GET_TILING, i915_gem_get_tiling, 0), + DRM_IOCTL_DEF(DRM_I915_HWS_ADDR, i915_set_status_page, DRM_AUTH), }; int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls); diff --git a/trunk/drivers/gpu/drm/i915/i915_drv.c b/trunk/drivers/gpu/drm/i915/i915_drv.c index a80ead215282..93aed1c38bd2 100644 --- a/trunk/drivers/gpu/drm/i915/i915_drv.c +++ b/trunk/drivers/gpu/drm/i915/i915_drv.c @@ -38,9 +38,211 @@ static struct pci_device_id pciidlist[] = { i915_PCI_IDS }; +enum pipe { + PIPE_A = 0, + PIPE_B, +}; + +static bool i915_pipe_enabled(struct drm_device *dev, enum pipe pipe) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + + if (pipe == PIPE_A) + return (I915_READ(DPLL_A) & DPLL_VCO_ENABLE); + else + return (I915_READ(DPLL_B) & DPLL_VCO_ENABLE); +} + +static void i915_save_palette(struct drm_device *dev, enum pipe pipe) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + unsigned long reg = (pipe == PIPE_A ? PALETTE_A : PALETTE_B); + u32 *array; + int i; + + if (!i915_pipe_enabled(dev, pipe)) + return; + + if (pipe == PIPE_A) + array = dev_priv->save_palette_a; + else + array = dev_priv->save_palette_b; + + for(i = 0; i < 256; i++) + array[i] = I915_READ(reg + (i << 2)); +} + +static void i915_restore_palette(struct drm_device *dev, enum pipe pipe) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + unsigned long reg = (pipe == PIPE_A ? PALETTE_A : PALETTE_B); + u32 *array; + int i; + + if (!i915_pipe_enabled(dev, pipe)) + return; + + if (pipe == PIPE_A) + array = dev_priv->save_palette_a; + else + array = dev_priv->save_palette_b; + + for(i = 0; i < 256; i++) + I915_WRITE(reg + (i << 2), array[i]); +} + +static u8 i915_read_indexed(u16 index_port, u16 data_port, u8 reg) +{ + outb(reg, index_port); + return inb(data_port); +} + +static u8 i915_read_ar(u16 st01, u8 reg, u16 palette_enable) +{ + inb(st01); + outb(palette_enable | reg, VGA_AR_INDEX); + return inb(VGA_AR_DATA_READ); +} + +static void i915_write_ar(u8 st01, u8 reg, u8 val, u16 palette_enable) +{ + inb(st01); + outb(palette_enable | reg, VGA_AR_INDEX); + outb(val, VGA_AR_DATA_WRITE); +} + +static void i915_write_indexed(u16 index_port, u16 data_port, u8 reg, u8 val) +{ + outb(reg, index_port); + outb(val, data_port); +} + +static void i915_save_vga(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + int i; + u16 cr_index, cr_data, st01; + + /* VGA color palette registers */ + dev_priv->saveDACMASK = inb(VGA_DACMASK); + /* DACCRX automatically increments during read */ + outb(0, VGA_DACRX); + /* Read 3 bytes of color data from each index */ + for (i = 0; i < 256 * 3; i++) + dev_priv->saveDACDATA[i] = inb(VGA_DACDATA); + + /* MSR bits */ + dev_priv->saveMSR = inb(VGA_MSR_READ); + if (dev_priv->saveMSR & VGA_MSR_CGA_MODE) { + cr_index = VGA_CR_INDEX_CGA; + cr_data = VGA_CR_DATA_CGA; + st01 = VGA_ST01_CGA; + } else { + cr_index = VGA_CR_INDEX_MDA; + cr_data = VGA_CR_DATA_MDA; + st01 = VGA_ST01_MDA; + } + + /* CRT controller regs */ + i915_write_indexed(cr_index, cr_data, 0x11, + i915_read_indexed(cr_index, cr_data, 0x11) & + (~0x80)); + for (i = 0; i <= 0x24; i++) + dev_priv->saveCR[i] = + i915_read_indexed(cr_index, cr_data, i); + /* Make sure we don't turn off CR group 0 writes */ + dev_priv->saveCR[0x11] &= ~0x80; + + /* Attribute controller registers */ + inb(st01); + dev_priv->saveAR_INDEX = inb(VGA_AR_INDEX); + for (i = 0; i <= 0x14; i++) + dev_priv->saveAR[i] = i915_read_ar(st01, i, 0); + inb(st01); + outb(dev_priv->saveAR_INDEX, VGA_AR_INDEX); + inb(st01); + + /* Graphics controller registers */ + for (i = 0; i < 9; i++) + dev_priv->saveGR[i] = + i915_read_indexed(VGA_GR_INDEX, VGA_GR_DATA, i); + + dev_priv->saveGR[0x10] = + i915_read_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x10); + dev_priv->saveGR[0x11] = + i915_read_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x11); + dev_priv->saveGR[0x18] = + i915_read_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x18); + + /* Sequencer registers */ + for (i = 0; i < 8; i++) + dev_priv->saveSR[i] = + i915_read_indexed(VGA_SR_INDEX, VGA_SR_DATA, i); +} + +static void i915_restore_vga(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + int i; + u16 cr_index, cr_data, st01; + + /* MSR bits */ + outb(dev_priv->saveMSR, VGA_MSR_WRITE); + if (dev_priv->saveMSR & VGA_MSR_CGA_MODE) { + cr_index = VGA_CR_INDEX_CGA; + cr_data = VGA_CR_DATA_CGA; + st01 = VGA_ST01_CGA; + } else { + cr_index = VGA_CR_INDEX_MDA; + cr_data = VGA_CR_DATA_MDA; + st01 = VGA_ST01_MDA; + } + + /* Sequencer registers, don't write SR07 */ + for (i = 0; i < 7; i++) + i915_write_indexed(VGA_SR_INDEX, VGA_SR_DATA, i, + dev_priv->saveSR[i]); + + /* CRT controller regs */ + /* Enable CR group 0 writes */ + i915_write_indexed(cr_index, cr_data, 0x11, dev_priv->saveCR[0x11]); + for (i = 0; i <= 0x24; i++) + i915_write_indexed(cr_index, cr_data, i, dev_priv->saveCR[i]); + + /* Graphics controller regs */ + for (i = 0; i < 9; i++) + i915_write_indexed(VGA_GR_INDEX, VGA_GR_DATA, i, + dev_priv->saveGR[i]); + + i915_write_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x10, + dev_priv->saveGR[0x10]); + i915_write_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x11, + dev_priv->saveGR[0x11]); + i915_write_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x18, + dev_priv->saveGR[0x18]); + + /* Attribute controller registers */ + inb(st01); + for (i = 0; i <= 0x14; i++) + i915_write_ar(st01, i, dev_priv->saveAR[i], 0); + inb(st01); /* switch back to index mode */ + outb(dev_priv->saveAR_INDEX | 0x20, VGA_AR_INDEX); + inb(st01); + + /* VGA color palette registers */ + outb(dev_priv->saveDACMASK, VGA_DACMASK); + /* DACCRX automatically increments during read */ + outb(0, VGA_DACWX); + /* Read 3 bytes of color data from each index */ + for (i = 0; i < 256 * 3; i++) + outb(dev_priv->saveDACDATA[i], VGA_DACDATA); + +} + static int i915_suspend(struct drm_device *dev, pm_message_t state) { struct drm_i915_private *dev_priv = dev->dev_private; + int i; if (!dev || !dev_priv) { printk(KERN_ERR "dev: %p, dev_priv: %p\n", dev, dev_priv); @@ -52,10 +254,122 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state) return 0; pci_save_state(dev->pdev); + pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB); + + /* Display arbitration control */ + dev_priv->saveDSPARB = I915_READ(DSPARB); + + /* Pipe & plane A info */ + dev_priv->savePIPEACONF = I915_READ(PIPEACONF); + dev_priv->savePIPEASRC = I915_READ(PIPEASRC); + dev_priv->saveFPA0 = I915_READ(FPA0); + dev_priv->saveFPA1 = I915_READ(FPA1); + dev_priv->saveDPLL_A = I915_READ(DPLL_A); + if (IS_I965G(dev)) + dev_priv->saveDPLL_A_MD = I915_READ(DPLL_A_MD); + dev_priv->saveHTOTAL_A = I915_READ(HTOTAL_A); + dev_priv->saveHBLANK_A = I915_READ(HBLANK_A); + dev_priv->saveHSYNC_A = I915_READ(HSYNC_A); + dev_priv->saveVTOTAL_A = I915_READ(VTOTAL_A); + dev_priv->saveVBLANK_A = I915_READ(VBLANK_A); + dev_priv->saveVSYNC_A = I915_READ(VSYNC_A); + dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A); + + dev_priv->saveDSPACNTR = I915_READ(DSPACNTR); + dev_priv->saveDSPASTRIDE = I915_READ(DSPASTRIDE); + dev_priv->saveDSPASIZE = I915_READ(DSPASIZE); + dev_priv->saveDSPAPOS = I915_READ(DSPAPOS); + dev_priv->saveDSPABASE = I915_READ(DSPABASE); + if (IS_I965G(dev)) { + dev_priv->saveDSPASURF = I915_READ(DSPASURF); + dev_priv->saveDSPATILEOFF = I915_READ(DSPATILEOFF); + } + i915_save_palette(dev, PIPE_A); + dev_priv->savePIPEASTAT = I915_READ(I915REG_PIPEASTAT); + + /* Pipe & plane B info */ + dev_priv->savePIPEBCONF = I915_READ(PIPEBCONF); + dev_priv->savePIPEBSRC = I915_READ(PIPEBSRC); + dev_priv->saveFPB0 = I915_READ(FPB0); + dev_priv->saveFPB1 = I915_READ(FPB1); + dev_priv->saveDPLL_B = I915_READ(DPLL_B); + if (IS_I965G(dev)) + dev_priv->saveDPLL_B_MD = I915_READ(DPLL_B_MD); + dev_priv->saveHTOTAL_B = I915_READ(HTOTAL_B); + dev_priv->saveHBLANK_B = I915_READ(HBLANK_B); + dev_priv->saveHSYNC_B = I915_READ(HSYNC_B); + dev_priv->saveVTOTAL_B = I915_READ(VTOTAL_B); + dev_priv->saveVBLANK_B = I915_READ(VBLANK_B); + dev_priv->saveVSYNC_B = I915_READ(VSYNC_B); + dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A); + + dev_priv->saveDSPBCNTR = I915_READ(DSPBCNTR); + dev_priv->saveDSPBSTRIDE = I915_READ(DSPBSTRIDE); + dev_priv->saveDSPBSIZE = I915_READ(DSPBSIZE); + dev_priv->saveDSPBPOS = I915_READ(DSPBPOS); + dev_priv->saveDSPBBASE = I915_READ(DSPBBASE); + if (IS_I965GM(dev) || IS_IGD_GM(dev)) { + dev_priv->saveDSPBSURF = I915_READ(DSPBSURF); + dev_priv->saveDSPBTILEOFF = I915_READ(DSPBTILEOFF); + } + i915_save_palette(dev, PIPE_B); + dev_priv->savePIPEBSTAT = I915_READ(I915REG_PIPEBSTAT); - i915_save_state(dev); + /* CRT state */ + dev_priv->saveADPA = I915_READ(ADPA); - intel_opregion_free(dev); + /* LVDS state */ + dev_priv->savePP_CONTROL = I915_READ(PP_CONTROL); + dev_priv->savePFIT_PGM_RATIOS = I915_READ(PFIT_PGM_RATIOS); + dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_CTL); + if (IS_I965G(dev)) + dev_priv->saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_CTL2); + if (IS_MOBILE(dev) && !IS_I830(dev)) + dev_priv->saveLVDS = I915_READ(LVDS); + if (!IS_I830(dev) && !IS_845G(dev)) + dev_priv->savePFIT_CONTROL = I915_READ(PFIT_CONTROL); + dev_priv->saveLVDSPP_ON = I915_READ(LVDSPP_ON); + dev_priv->saveLVDSPP_OFF = I915_READ(LVDSPP_OFF); + dev_priv->savePP_CYCLE = I915_READ(PP_CYCLE); + + /* FIXME: save TV & SDVO state */ + + /* FBC state */ + dev_priv->saveFBC_CFB_BASE = I915_READ(FBC_CFB_BASE); + dev_priv->saveFBC_LL_BASE = I915_READ(FBC_LL_BASE); + dev_priv->saveFBC_CONTROL2 = I915_READ(FBC_CONTROL2); + dev_priv->saveFBC_CONTROL = I915_READ(FBC_CONTROL); + + /* Interrupt state */ + dev_priv->saveIIR = I915_READ(I915REG_INT_IDENTITY_R); + dev_priv->saveIER = I915_READ(I915REG_INT_ENABLE_R); + dev_priv->saveIMR = I915_READ(I915REG_INT_MASK_R); + + /* VGA state */ + dev_priv->saveVCLK_DIVISOR_VGA0 = I915_READ(VCLK_DIVISOR_VGA0); + dev_priv->saveVCLK_DIVISOR_VGA1 = I915_READ(VCLK_DIVISOR_VGA1); + dev_priv->saveVCLK_POST_DIV = I915_READ(VCLK_POST_DIV); + dev_priv->saveVGACNTRL = I915_READ(VGACNTRL); + + /* Clock gating state */ + dev_priv->saveD_STATE = I915_READ(D_STATE); + dev_priv->saveDSPCLK_GATE_D = I915_READ(DSPCLK_GATE_D); + + /* Cache mode state */ + dev_priv->saveCACHE_MODE_0 = I915_READ(CACHE_MODE_0); + + /* Memory Arbitration state */ + dev_priv->saveMI_ARB_STATE = I915_READ(MI_ARB_STATE); + + /* Scratch space */ + for (i = 0; i < 16; i++) { + dev_priv->saveSWF0[i] = I915_READ(SWF0 + (i << 2)); + dev_priv->saveSWF1[i] = I915_READ(SWF10 + (i << 2)); + } + for (i = 0; i < 3; i++) + dev_priv->saveSWF2[i] = I915_READ(SWF30 + (i << 2)); + + i915_save_vga(dev); if (state.event == PM_EVENT_SUSPEND) { /* Shut down the device */ @@ -68,15 +382,155 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state) static int i915_resume(struct drm_device *dev) { + struct drm_i915_private *dev_priv = dev->dev_private; + int i; + pci_set_power_state(dev->pdev, PCI_D0); pci_restore_state(dev->pdev); if (pci_enable_device(dev->pdev)) return -1; pci_set_master(dev->pdev); - i915_restore_state(dev); + pci_write_config_byte(dev->pdev, LBB, dev_priv->saveLBB); + + I915_WRITE(DSPARB, dev_priv->saveDSPARB); + + /* Pipe & plane A info */ + /* Prime the clock */ + if (dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) { + I915_WRITE(DPLL_A, dev_priv->saveDPLL_A & + ~DPLL_VCO_ENABLE); + udelay(150); + } + I915_WRITE(FPA0, dev_priv->saveFPA0); + I915_WRITE(FPA1, dev_priv->saveFPA1); + /* Actually enable it */ + I915_WRITE(DPLL_A, dev_priv->saveDPLL_A); + udelay(150); + if (IS_I965G(dev)) + I915_WRITE(DPLL_A_MD, dev_priv->saveDPLL_A_MD); + udelay(150); + + /* Restore mode */ + I915_WRITE(HTOTAL_A, dev_priv->saveHTOTAL_A); + I915_WRITE(HBLANK_A, dev_priv->saveHBLANK_A); + I915_WRITE(HSYNC_A, dev_priv->saveHSYNC_A); + I915_WRITE(VTOTAL_A, dev_priv->saveVTOTAL_A); + I915_WRITE(VBLANK_A, dev_priv->saveVBLANK_A); + I915_WRITE(VSYNC_A, dev_priv->saveVSYNC_A); + I915_WRITE(BCLRPAT_A, dev_priv->saveBCLRPAT_A); + + /* Restore plane info */ + I915_WRITE(DSPASIZE, dev_priv->saveDSPASIZE); + I915_WRITE(DSPAPOS, dev_priv->saveDSPAPOS); + I915_WRITE(PIPEASRC, dev_priv->savePIPEASRC); + I915_WRITE(DSPABASE, dev_priv->saveDSPABASE); + I915_WRITE(DSPASTRIDE, dev_priv->saveDSPASTRIDE); + if (IS_I965G(dev)) { + I915_WRITE(DSPASURF, dev_priv->saveDSPASURF); + I915_WRITE(DSPATILEOFF, dev_priv->saveDSPATILEOFF); + } + + I915_WRITE(PIPEACONF, dev_priv->savePIPEACONF); + + i915_restore_palette(dev, PIPE_A); + /* Enable the plane */ + I915_WRITE(DSPACNTR, dev_priv->saveDSPACNTR); + I915_WRITE(DSPABASE, I915_READ(DSPABASE)); + + /* Pipe & plane B info */ + if (dev_priv->saveDPLL_B & DPLL_VCO_ENABLE) { + I915_WRITE(DPLL_B, dev_priv->saveDPLL_B & + ~DPLL_VCO_ENABLE); + udelay(150); + } + I915_WRITE(FPB0, dev_priv->saveFPB0); + I915_WRITE(FPB1, dev_priv->saveFPB1); + /* Actually enable it */ + I915_WRITE(DPLL_B, dev_priv->saveDPLL_B); + udelay(150); + if (IS_I965G(dev)) + I915_WRITE(DPLL_B_MD, dev_priv->saveDPLL_B_MD); + udelay(150); + + /* Restore mode */ + I915_WRITE(HTOTAL_B, dev_priv->saveHTOTAL_B); + I915_WRITE(HBLANK_B, dev_priv->saveHBLANK_B); + I915_WRITE(HSYNC_B, dev_priv->saveHSYNC_B); + I915_WRITE(VTOTAL_B, dev_priv->saveVTOTAL_B); + I915_WRITE(VBLANK_B, dev_priv->saveVBLANK_B); + I915_WRITE(VSYNC_B, dev_priv->saveVSYNC_B); + I915_WRITE(BCLRPAT_B, dev_priv->saveBCLRPAT_B); + + /* Restore plane info */ + I915_WRITE(DSPBSIZE, dev_priv->saveDSPBSIZE); + I915_WRITE(DSPBPOS, dev_priv->saveDSPBPOS); + I915_WRITE(PIPEBSRC, dev_priv->savePIPEBSRC); + I915_WRITE(DSPBBASE, dev_priv->saveDSPBBASE); + I915_WRITE(DSPBSTRIDE, dev_priv->saveDSPBSTRIDE); + if (IS_I965G(dev)) { + I915_WRITE(DSPBSURF, dev_priv->saveDSPBSURF); + I915_WRITE(DSPBTILEOFF, dev_priv->saveDSPBTILEOFF); + } + + I915_WRITE(PIPEBCONF, dev_priv->savePIPEBCONF); + + i915_restore_palette(dev, PIPE_B); + /* Enable the plane */ + I915_WRITE(DSPBCNTR, dev_priv->saveDSPBCNTR); + I915_WRITE(DSPBBASE, I915_READ(DSPBBASE)); + + /* CRT state */ + I915_WRITE(ADPA, dev_priv->saveADPA); + + /* LVDS state */ + if (IS_I965G(dev)) + I915_WRITE(BLC_PWM_CTL2, dev_priv->saveBLC_PWM_CTL2); + if (IS_MOBILE(dev) && !IS_I830(dev)) + I915_WRITE(LVDS, dev_priv->saveLVDS); + if (!IS_I830(dev) && !IS_845G(dev)) + I915_WRITE(PFIT_CONTROL, dev_priv->savePFIT_CONTROL); + + I915_WRITE(PFIT_PGM_RATIOS, dev_priv->savePFIT_PGM_RATIOS); + I915_WRITE(BLC_PWM_CTL, dev_priv->saveBLC_PWM_CTL); + I915_WRITE(LVDSPP_ON, dev_priv->saveLVDSPP_ON); + I915_WRITE(LVDSPP_OFF, dev_priv->saveLVDSPP_OFF); + I915_WRITE(PP_CYCLE, dev_priv->savePP_CYCLE); + I915_WRITE(PP_CONTROL, dev_priv->savePP_CONTROL); + + /* FIXME: restore TV & SDVO state */ + + /* FBC info */ + I915_WRITE(FBC_CFB_BASE, dev_priv->saveFBC_CFB_BASE); + I915_WRITE(FBC_LL_BASE, dev_priv->saveFBC_LL_BASE); + I915_WRITE(FBC_CONTROL2, dev_priv->saveFBC_CONTROL2); + I915_WRITE(FBC_CONTROL, dev_priv->saveFBC_CONTROL); + + /* VGA state */ + I915_WRITE(VGACNTRL, dev_priv->saveVGACNTRL); + I915_WRITE(VCLK_DIVISOR_VGA0, dev_priv->saveVCLK_DIVISOR_VGA0); + I915_WRITE(VCLK_DIVISOR_VGA1, dev_priv->saveVCLK_DIVISOR_VGA1); + I915_WRITE(VCLK_POST_DIV, dev_priv->saveVCLK_POST_DIV); + udelay(150); + + /* Clock gating state */ + I915_WRITE (D_STATE, dev_priv->saveD_STATE); + I915_WRITE (DSPCLK_GATE_D, dev_priv->saveDSPCLK_GATE_D); + + /* Cache mode state */ + I915_WRITE (CACHE_MODE_0, dev_priv->saveCACHE_MODE_0 | 0xffff0000); + + /* Memory arbitration state */ + I915_WRITE (MI_ARB_STATE, dev_priv->saveMI_ARB_STATE | 0xffff0000); + + for (i = 0; i < 16; i++) { + I915_WRITE(SWF0 + (i << 2), dev_priv->saveSWF0[i]); + I915_WRITE(SWF10 + (i << 2), dev_priv->saveSWF1[i+7]); + } + for (i = 0; i < 3; i++) + I915_WRITE(SWF30 + (i << 2), dev_priv->saveSWF2[i]); - intel_opregion_init(dev); + i915_restore_vga(dev); return 0; } @@ -87,19 +541,17 @@ static struct drm_driver driver = { */ .driver_features = DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | /* DRIVER_USE_MTRR |*/ - DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM, + DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL | + DRIVER_IRQ_VBL2, .load = i915_driver_load, .unload = i915_driver_unload, - .open = i915_driver_open, .lastclose = i915_driver_lastclose, .preclose = i915_driver_preclose, - .postclose = i915_driver_postclose, .suspend = i915_suspend, .resume = i915_resume, .device_is_agp = i915_driver_device_is_agp, - .get_vblank_counter = i915_get_vblank_counter, - .enable_vblank = i915_enable_vblank, - .disable_vblank = i915_disable_vblank, + .vblank_wait = i915_driver_vblank_wait, + .vblank_wait2 = i915_driver_vblank_wait2, .irq_preinstall = i915_driver_irq_preinstall, .irq_postinstall = i915_driver_irq_postinstall, .irq_uninstall = i915_driver_irq_uninstall, @@ -107,10 +559,6 @@ static struct drm_driver driver = { .reclaim_buffers = drm_core_reclaim_buffers, .get_map_ofs = drm_core_get_map_ofs, .get_reg_ofs = drm_core_get_reg_ofs, - .proc_init = i915_gem_proc_init, - .proc_cleanup = i915_gem_proc_cleanup, - .gem_init_object = i915_gem_init_object, - .gem_free_object = i915_gem_free_object, .ioctls = i915_ioctls, .fops = { .owner = THIS_MODULE, diff --git a/trunk/drivers/gpu/drm/i915/i915_drv.h b/trunk/drivers/gpu/drm/i915/i915_drv.h index eae4ed3956e0..d7326d92a237 100644 --- a/trunk/drivers/gpu/drm/i915/i915_drv.h +++ b/trunk/drivers/gpu/drm/i915/i915_drv.h @@ -30,8 +30,6 @@ #ifndef _I915_DRV_H_ #define _I915_DRV_H_ -#include "i915_reg.h" - /* General customization: */ @@ -39,12 +37,7 @@ #define DRIVER_NAME "i915" #define DRIVER_DESC "Intel Graphics" -#define DRIVER_DATE "20080730" - -enum pipe { - PIPE_A = 0, - PIPE_B, -}; +#define DRIVER_DATE "20060119" /* Interface history: * @@ -60,23 +53,16 @@ enum pipe { #define DRIVER_MINOR 6 #define DRIVER_PATCHLEVEL 0 -#define WATCH_COHERENCY 0 -#define WATCH_BUF 0 -#define WATCH_EXEC 0 -#define WATCH_LRU 0 -#define WATCH_RELOC 0 -#define WATCH_INACTIVE 0 -#define WATCH_PWRITE 0 - typedef struct _drm_i915_ring_buffer { int tail_mask; + unsigned long Start; + unsigned long End; unsigned long Size; u8 *virtual_start; int head; int tail; int space; drm_local_map_t map; - struct drm_gem_object *ring_obj; } drm_i915_ring_buffer_t; struct mem_block { @@ -90,28 +76,13 @@ struct mem_block { typedef struct _drm_i915_vbl_swap { struct list_head head; drm_drawable_t drw_id; - unsigned int plane; + unsigned int pipe; unsigned int sequence; } drm_i915_vbl_swap_t; -struct opregion_header; -struct opregion_acpi; -struct opregion_swsci; -struct opregion_asle; - -struct intel_opregion { - struct opregion_header *header; - struct opregion_acpi *acpi; - struct opregion_swsci *swsci; - struct opregion_asle *asle; - int enabled; -}; - typedef struct drm_i915_private { - struct drm_device *dev; - - void __iomem *regs; drm_local_map_t *sarea; + drm_local_map_t *mmio_map; drm_i915_sarea_t *sarea_priv; drm_i915_ring_buffer_t ring; @@ -119,25 +90,20 @@ typedef struct drm_i915_private { drm_dma_handle_t *status_page_dmah; void *hw_status_page; dma_addr_t dma_status_page; - uint32_t counter; + unsigned long counter; unsigned int status_gfx_addr; drm_local_map_t hws_map; - struct drm_gem_object *hws_obj; unsigned int cpp; int back_offset; int front_offset; int current_page; int page_flipping; + int use_mi_batchbuffer_start; wait_queue_head_t irq_queue; atomic_t irq_received; - /** Protects user_irq_refcount and irq_mask_reg */ - spinlock_t user_irq_lock; - /** Refcount for i915_user_irq_get() versus i915_user_irq_put(). */ - int user_irq_refcount; - /** Cached value of IMR to avoid reads in updating the bitfield */ - u32 irq_mask_reg; + atomic_t irq_emitted; int tex_lru_log_granularity; int allow_batchbuffer; @@ -149,8 +115,6 @@ typedef struct drm_i915_private { drm_i915_vbl_swap_t vbl_swaps; unsigned int swaps_pending; - struct intel_opregion opregion; - /* Register state */ u8 saveLBB; u32 saveDSPACNTR; @@ -175,7 +139,7 @@ typedef struct drm_i915_private { u32 saveDSPASTRIDE; u32 saveDSPASIZE; u32 saveDSPAPOS; - u32 saveDSPAADDR; + u32 saveDSPABASE; u32 saveDSPASURF; u32 saveDSPATILEOFF; u32 savePFIT_PGM_RATIOS; @@ -196,24 +160,24 @@ typedef struct drm_i915_private { u32 saveDSPBSTRIDE; u32 saveDSPBSIZE; u32 saveDSPBPOS; - u32 saveDSPBADDR; + u32 saveDSPBBASE; u32 saveDSPBSURF; u32 saveDSPBTILEOFF; - u32 saveVGA0; - u32 saveVGA1; - u32 saveVGA_PD; + u32 saveVCLK_DIVISOR_VGA0; + u32 saveVCLK_DIVISOR_VGA1; + u32 saveVCLK_POST_DIV; u32 saveVGACNTRL; u32 saveADPA; u32 saveLVDS; - u32 savePP_ON_DELAYS; - u32 savePP_OFF_DELAYS; + u32 saveLVDSPP_ON; + u32 saveLVDSPP_OFF; u32 saveDVOA; u32 saveDVOB; u32 saveDVOC; u32 savePP_ON; u32 savePP_OFF; u32 savePP_CONTROL; - u32 savePP_DIVISOR; + u32 savePP_CYCLE; u32 savePFIT_CONTROL; u32 save_palette_a[256]; u32 save_palette_b[256]; @@ -226,7 +190,7 @@ typedef struct drm_i915_private { u32 saveIMR; u32 saveCACHE_MODE_0; u32 saveD_STATE; - u32 saveCG_2D_DIS; + u32 saveDSPCLK_GATE_D; u32 saveMI_ARB_STATE; u32 saveSWF0[16]; u32 saveSWF1[16]; @@ -239,180 +203,8 @@ typedef struct drm_i915_private { u8 saveDACMASK; u8 saveDACDATA[256*3]; /* 256 3-byte colors */ u8 saveCR[37]; - - struct { - struct drm_mm gtt_space; - - /** - * List of objects currently involved in rendering from the - * ringbuffer. - * - * A reference is held on the buffer while on this list. - */ - struct list_head active_list; - - /** - * List of objects which are not in the ringbuffer but which - * still have a write_domain which needs to be flushed before - * unbinding. - * - * A reference is held on the buffer while on this list. - */ - struct list_head flushing_list; - - /** - * LRU list of objects which are not in the ringbuffer and - * are ready to unbind, but are still in the GTT. - * - * A reference is not held on the buffer while on this list, - * as merely being GTT-bound shouldn't prevent its being - * freed, and we'll pull it off the list in the free path. - */ - struct list_head inactive_list; - - /** - * List of breadcrumbs associated with GPU requests currently - * outstanding. - */ - struct list_head request_list; - - /** - * We leave the user IRQ off as much as possible, - * but this means that requests will finish and never - * be retired once the system goes idle. Set a timer to - * fire periodically while the ring is running. When it - * fires, go retire requests. - */ - struct delayed_work retire_work; - - /** Work task for vblank-related ring access */ - struct work_struct vblank_work; - - uint32_t next_gem_seqno; - - /** - * Waiting sequence number, if any - */ - uint32_t waiting_gem_seqno; - - /** - * Last seq seen at irq time - */ - uint32_t irq_gem_seqno; - - /** - * Flag if the X Server, and thus DRM, is not currently in - * control of the device. - * - * This is set between LeaveVT and EnterVT. It needs to be - * replaced with a semaphore. It also needs to be - * transitioned away from for kernel modesetting. - */ - int suspended; - - /** - * Flag if the hardware appears to be wedged. - * - * This is set when attempts to idle the device timeout. - * It prevents command submission from occuring and makes - * every pending request fail - */ - int wedged; - - /** Bit 6 swizzling required for X tiling */ - uint32_t bit_6_swizzle_x; - /** Bit 6 swizzling required for Y tiling */ - uint32_t bit_6_swizzle_y; - } mm; } drm_i915_private_t; -/** driver private structure attached to each drm_gem_object */ -struct drm_i915_gem_object { - struct drm_gem_object *obj; - - /** Current space allocated to this object in the GTT, if any. */ - struct drm_mm_node *gtt_space; - - /** This object's place on the active/flushing/inactive lists */ - struct list_head list; - - /** - * This is set if the object is on the active or flushing lists - * (has pending rendering), and is not set if it's on inactive (ready - * to be unbound). - */ - int active; - - /** - * This is set if the object has been written to since last bound - * to the GTT - */ - int dirty; - - /** AGP memory structure for our GTT binding. */ - DRM_AGP_MEM *agp_mem; - - struct page **page_list; - - /** - * Current offset of the object in GTT space. - * - * This is the same as gtt_space->start - */ - uint32_t gtt_offset; - - /** Boolean whether this object has a valid gtt offset. */ - int gtt_bound; - - /** How many users have pinned this object in GTT space */ - int pin_count; - - /** Breadcrumb of last rendering to the buffer. */ - uint32_t last_rendering_seqno; - - /** Current tiling mode for the object. */ - uint32_t tiling_mode; - - /** AGP mapping type (AGP_USER_MEMORY or AGP_USER_CACHED_MEMORY */ - uint32_t agp_type; - - /** - * Flagging of which individual pages are valid in GEM_DOMAIN_CPU when - * GEM_DOMAIN_CPU is not in the object's read domain. - */ - uint8_t *page_cpu_valid; -}; - -/** - * Request queue structure. - * - * The request queue allows us to note sequence numbers that have been emitted - * and may be associated with active buffers to be retired. - * - * By keeping this list, we can avoid having to do questionable - * sequence-number comparisons on buffer last_rendering_seqnos, and associate - * an emission time with seqnos for tracking how far ahead of the GPU we are. - */ -struct drm_i915_gem_request { - /** GEM sequence number associated with this request. */ - uint32_t seqno; - - /** Time at which this request was emitted, in jiffies. */ - unsigned long emitted_jiffies; - - /** Cache domains that were flushed at the start of the request. */ - uint32_t flush_domains; - - struct list_head list; -}; - -struct drm_i915_file_private { - struct { - uint32_t last_gem_seqno; - uint32_t last_gem_throttle_seqno; - } mm; -}; - extern struct drm_ioctl_desc i915_ioctls[]; extern int i915_max_ioctl; @@ -420,42 +212,31 @@ extern int i915_max_ioctl; extern void i915_kernel_lost_context(struct drm_device * dev); extern int i915_driver_load(struct drm_device *, unsigned long flags); extern int i915_driver_unload(struct drm_device *); -extern int i915_driver_open(struct drm_device *dev, struct drm_file *file_priv); extern void i915_driver_lastclose(struct drm_device * dev); extern void i915_driver_preclose(struct drm_device *dev, struct drm_file *file_priv); -extern void i915_driver_postclose(struct drm_device *dev, - struct drm_file *file_priv); extern int i915_driver_device_is_agp(struct drm_device * dev); extern long i915_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); -extern int i915_emit_box(struct drm_device *dev, - struct drm_clip_rect __user *boxes, - int i, int DR1, int DR4); /* i915_irq.c */ extern int i915_irq_emit(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int i915_irq_wait(struct drm_device *dev, void *data, struct drm_file *file_priv); -void i915_user_irq_get(struct drm_device *dev); -void i915_user_irq_put(struct drm_device *dev); -extern void i915_gem_vblank_work_handler(struct work_struct *work); +extern int i915_driver_vblank_wait(struct drm_device *dev, unsigned int *sequence); +extern int i915_driver_vblank_wait2(struct drm_device *dev, unsigned int *sequence); extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS); extern void i915_driver_irq_preinstall(struct drm_device * dev); -extern int i915_driver_irq_postinstall(struct drm_device *dev); +extern void i915_driver_irq_postinstall(struct drm_device * dev); extern void i915_driver_irq_uninstall(struct drm_device * dev); extern int i915_vblank_pipe_set(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int i915_vblank_pipe_get(struct drm_device *dev, void *data, struct drm_file *file_priv); -extern int i915_enable_vblank(struct drm_device *dev, int crtc); -extern void i915_disable_vblank(struct drm_device *dev, int crtc); -extern u32 i915_get_vblank_counter(struct drm_device *dev, int crtc); extern int i915_vblank_swap(struct drm_device *dev, void *data, struct drm_file *file_priv); -extern void i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask); /* i915_mem.c */ extern int i915_mem_alloc(struct drm_device *dev, void *data, @@ -469,99 +250,11 @@ extern int i915_mem_destroy_heap(struct drm_device *dev, void *data, extern void i915_mem_takedown(struct mem_block **heap); extern void i915_mem_release(struct drm_device * dev, struct drm_file *file_priv, struct mem_block *heap); -/* i915_gem.c */ -int i915_gem_init_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int i915_gem_create_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int i915_gem_pread_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int i915_gem_mmap_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int i915_gem_execbuffer(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int i915_gem_pin_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int i915_gem_unpin_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int i915_gem_busy_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int i915_gem_throttle_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int i915_gem_entervt_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int i915_gem_leavevt_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int i915_gem_set_tiling(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int i915_gem_get_tiling(struct drm_device *dev, void *data, - struct drm_file *file_priv); -void i915_gem_load(struct drm_device *dev); -int i915_gem_proc_init(struct drm_minor *minor); -void i915_gem_proc_cleanup(struct drm_minor *minor); -int i915_gem_init_object(struct drm_gem_object *obj); -void i915_gem_free_object(struct drm_gem_object *obj); -int i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment); -void i915_gem_object_unpin(struct drm_gem_object *obj); -void i915_gem_lastclose(struct drm_device *dev); -uint32_t i915_get_gem_seqno(struct drm_device *dev); -void i915_gem_retire_requests(struct drm_device *dev); -void i915_gem_retire_work_handler(struct work_struct *work); -void i915_gem_clflush_object(struct drm_gem_object *obj); - -/* i915_gem_tiling.c */ -void i915_gem_detect_bit_6_swizzle(struct drm_device *dev); - -/* i915_gem_debug.c */ -void i915_gem_dump_object(struct drm_gem_object *obj, int len, - const char *where, uint32_t mark); -#if WATCH_INACTIVE -void i915_verify_inactive(struct drm_device *dev, char *file, int line); -#else -#define i915_verify_inactive(dev, file, line) -#endif -void i915_gem_object_check_coherency(struct drm_gem_object *obj, int handle); -void i915_gem_dump_object(struct drm_gem_object *obj, int len, - const char *where, uint32_t mark); -void i915_dump_lru(struct drm_device *dev, const char *where); - -/* i915_suspend.c */ -extern int i915_save_state(struct drm_device *dev); -extern int i915_restore_state(struct drm_device *dev); - -/* i915_suspend.c */ -extern int i915_save_state(struct drm_device *dev); -extern int i915_restore_state(struct drm_device *dev); - -/* i915_opregion.c */ -extern int intel_opregion_init(struct drm_device *dev); -extern void intel_opregion_free(struct drm_device *dev); -extern void opregion_asle_intr(struct drm_device *dev); -extern void opregion_enable_asle(struct drm_device *dev); - -/** - * Lock test for when it's just for synchronization of ring access. - * - * In that case, we don't need to do it when GEM is initialized as nobody else - * has access to the ring. - */ -#define RING_LOCK_TEST_WITH_RETURN(dev, file_priv) do { \ - if (((drm_i915_private_t *)dev->dev_private)->ring.ring_obj == NULL) \ - LOCK_TEST_WITH_RETURN(dev, file_priv); \ -} while (0) -#define I915_READ(reg) readl(dev_priv->regs + (reg)) -#define I915_WRITE(reg, val) writel(val, dev_priv->regs + (reg)) -#define I915_READ16(reg) readw(dev_priv->regs + (reg)) -#define I915_WRITE16(reg, val) writel(val, dev_priv->regs + (reg)) -#define I915_READ8(reg) readb(dev_priv->regs + (reg)) -#define I915_WRITE8(reg, val) writeb(val, dev_priv->regs + (reg)) +#define I915_READ(reg) DRM_READ32(dev_priv->mmio_map, (reg)) +#define I915_WRITE(reg,val) DRM_WRITE32(dev_priv->mmio_map, (reg), (val)) +#define I915_READ16(reg) DRM_READ16(dev_priv->mmio_map, (reg)) +#define I915_WRITE16(reg,val) DRM_WRITE16(dev_priv->mmio_map, (reg), (val)) #define I915_VERBOSE 0 @@ -591,29 +284,816 @@ extern void opregion_enable_asle(struct drm_device *dev); if (I915_VERBOSE) DRM_DEBUG("ADVANCE_LP_RING %x\n", outring); \ dev_priv->ring.tail = outring; \ dev_priv->ring.space -= outcount * 4; \ - I915_WRITE(PRB0_TAIL, outring); \ + I915_WRITE(LP_RING + RING_TAIL, outring); \ } while(0) +extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); + +/* Extended config space */ +#define LBB 0xf4 + +/* VGA stuff */ + +#define VGA_ST01_MDA 0x3ba +#define VGA_ST01_CGA 0x3da + +#define VGA_MSR_WRITE 0x3c2 +#define VGA_MSR_READ 0x3cc +#define VGA_MSR_MEM_EN (1<<1) +#define VGA_MSR_CGA_MODE (1<<0) + +#define VGA_SR_INDEX 0x3c4 +#define VGA_SR_DATA 0x3c5 + +#define VGA_AR_INDEX 0x3c0 +#define VGA_AR_VID_EN (1<<5) +#define VGA_AR_DATA_WRITE 0x3c0 +#define VGA_AR_DATA_READ 0x3c1 + +#define VGA_GR_INDEX 0x3ce +#define VGA_GR_DATA 0x3cf +/* GR05 */ +#define VGA_GR_MEM_READ_MODE_SHIFT 3 +#define VGA_GR_MEM_READ_MODE_PLANE 1 +/* GR06 */ +#define VGA_GR_MEM_MODE_MASK 0xc +#define VGA_GR_MEM_MODE_SHIFT 2 +#define VGA_GR_MEM_A0000_AFFFF 0 +#define VGA_GR_MEM_A0000_BFFFF 1 +#define VGA_GR_MEM_B0000_B7FFF 2 +#define VGA_GR_MEM_B0000_BFFFF 3 + +#define VGA_DACMASK 0x3c6 +#define VGA_DACRX 0x3c7 +#define VGA_DACWX 0x3c8 +#define VGA_DACDATA 0x3c9 + +#define VGA_CR_INDEX_MDA 0x3b4 +#define VGA_CR_DATA_MDA 0x3b5 +#define VGA_CR_INDEX_CGA 0x3d4 +#define VGA_CR_DATA_CGA 0x3d5 + +#define GFX_OP_USER_INTERRUPT ((0<<29)|(2<<23)) +#define GFX_OP_BREAKPOINT_INTERRUPT ((0<<29)|(1<<23)) +#define CMD_REPORT_HEAD (7<<23) +#define CMD_STORE_DWORD_IDX ((0x21<<23) | 0x1) +#define CMD_OP_BATCH_BUFFER ((0x0<<29)|(0x30<<23)|0x1) + +#define INST_PARSER_CLIENT 0x00000000 +#define INST_OP_FLUSH 0x02000000 +#define INST_FLUSH_MAP_CACHE 0x00000001 + +#define BB1_START_ADDR_MASK (~0x7) +#define BB1_PROTECTED (1<<0) +#define BB1_UNPROTECTED (0<<0) +#define BB2_END_ADDR_MASK (~0x7) + +/* Framebuffer compression */ +#define FBC_CFB_BASE 0x03200 /* 4k page aligned */ +#define FBC_LL_BASE 0x03204 /* 4k page aligned */ +#define FBC_CONTROL 0x03208 +#define FBC_CTL_EN (1<<31) +#define FBC_CTL_PERIODIC (1<<30) +#define FBC_CTL_INTERVAL_SHIFT (16) +#define FBC_CTL_UNCOMPRESSIBLE (1<<14) +#define FBC_CTL_STRIDE_SHIFT (5) +#define FBC_CTL_FENCENO (1<<0) +#define FBC_COMMAND 0x0320c +#define FBC_CMD_COMPRESS (1<<0) +#define FBC_STATUS 0x03210 +#define FBC_STAT_COMPRESSING (1<<31) +#define FBC_STAT_COMPRESSED (1<<30) +#define FBC_STAT_MODIFIED (1<<29) +#define FBC_STAT_CURRENT_LINE (1<<0) +#define FBC_CONTROL2 0x03214 +#define FBC_CTL_FENCE_DBL (0<<4) +#define FBC_CTL_IDLE_IMM (0<<2) +#define FBC_CTL_IDLE_FULL (1<<2) +#define FBC_CTL_IDLE_LINE (2<<2) +#define FBC_CTL_IDLE_DEBUG (3<<2) +#define FBC_CTL_CPU_FENCE (1<<1) +#define FBC_CTL_PLANEA (0<<0) +#define FBC_CTL_PLANEB (1<<0) +#define FBC_FENCE_OFF 0x0321b + +#define FBC_LL_SIZE (1536) +#define FBC_LL_PAD (32) + +/* Interrupt bits: + */ +#define USER_INT_FLAG (1<<1) +#define VSYNC_PIPEB_FLAG (1<<5) +#define VSYNC_PIPEA_FLAG (1<<7) +#define HWB_OOM_FLAG (1<<13) /* binner out of memory */ + +#define I915REG_HWSTAM 0x02098 +#define I915REG_INT_IDENTITY_R 0x020a4 +#define I915REG_INT_MASK_R 0x020a8 +#define I915REG_INT_ENABLE_R 0x020a0 + +#define I915REG_PIPEASTAT 0x70024 +#define I915REG_PIPEBSTAT 0x71024 + +#define I915_VBLANK_INTERRUPT_ENABLE (1UL<<17) +#define I915_VBLANK_CLEAR (1UL<<1) + +#define SRX_INDEX 0x3c4 +#define SRX_DATA 0x3c5 +#define SR01 1 +#define SR01_SCREEN_OFF (1<<5) + +#define PPCR 0x61204 +#define PPCR_ON (1<<0) + +#define DVOB 0x61140 +#define DVOB_ON (1<<31) +#define DVOC 0x61160 +#define DVOC_ON (1<<31) +#define LVDS 0x61180 +#define LVDS_ON (1<<31) + +#define ADPA 0x61100 +#define ADPA_DPMS_MASK (~(3<<10)) +#define ADPA_DPMS_ON (0<<10) +#define ADPA_DPMS_SUSPEND (1<<10) +#define ADPA_DPMS_STANDBY (2<<10) +#define ADPA_DPMS_OFF (3<<10) + +#define NOPID 0x2094 +#define LP_RING 0x2030 +#define HP_RING 0x2040 +/* The binner has its own ring buffer: + */ +#define HWB_RING 0x2400 + +#define RING_TAIL 0x00 +#define TAIL_ADDR 0x001FFFF8 +#define RING_HEAD 0x04 +#define HEAD_WRAP_COUNT 0xFFE00000 +#define HEAD_WRAP_ONE 0x00200000 +#define HEAD_ADDR 0x001FFFFC +#define RING_START 0x08 +#define START_ADDR 0x0xFFFFF000 +#define RING_LEN 0x0C +#define RING_NR_PAGES 0x001FF000 +#define RING_REPORT_MASK 0x00000006 +#define RING_REPORT_64K 0x00000002 +#define RING_REPORT_128K 0x00000004 +#define RING_NO_REPORT 0x00000000 +#define RING_VALID_MASK 0x00000001 +#define RING_VALID 0x00000001 +#define RING_INVALID 0x00000000 + +/* Instruction parser error reg: + */ +#define IPEIR 0x2088 + +/* Scratch pad debug 0 reg: + */ +#define SCPD0 0x209c + +/* Error status reg: + */ +#define ESR 0x20b8 + +/* Secondary DMA fetch address debug reg: + */ +#define DMA_FADD_S 0x20d4 + +/* Memory Interface Arbitration State + */ +#define MI_ARB_STATE 0x20e4 + +/* Cache mode 0 reg. + * - Manipulating render cache behaviour is central + * to the concept of zone rendering, tuning this reg can help avoid + * unnecessary render cache reads and even writes (for z/stencil) + * at beginning and end of scene. + * + * - To change a bit, write to this reg with a mask bit set and the + * bit of interest either set or cleared. EG: (BIT<<16) | BIT to set. + */ +#define Cache_Mode_0 0x2120 +#define CACHE_MODE_0 0x2120 +#define CM0_MASK_SHIFT 16 +#define CM0_IZ_OPT_DISABLE (1<<6) +#define CM0_ZR_OPT_DISABLE (1<<5) +#define CM0_DEPTH_EVICT_DISABLE (1<<4) +#define CM0_COLOR_EVICT_DISABLE (1<<3) +#define CM0_DEPTH_WRITE_DISABLE (1<<1) +#define CM0_RC_OP_FLUSH_DISABLE (1<<0) + + +/* Graphics flush control. A CPU write flushes the GWB of all writes. + * The data is discarded. + */ +#define GFX_FLSH_CNTL 0x2170 + +/* Binner control. Defines the location of the bin pointer list: + */ +#define BINCTL 0x2420 +#define BC_MASK (1 << 9) + +/* Binned scene info. + */ +#define BINSCENE 0x2428 +#define BS_OP_LOAD (1 << 8) +#define BS_MASK (1 << 22) + +/* Bin command parser debug reg: + */ +#define BCPD 0x2480 + +/* Bin memory control debug reg: + */ +#define BMCD 0x2484 + +/* Bin data cache debug reg: + */ +#define BDCD 0x2488 + +/* Binner pointer cache debug reg: + */ +#define BPCD 0x248c + +/* Binner scratch pad debug reg: + */ +#define BINSKPD 0x24f0 + +/* HWB scratch pad debug reg: + */ +#define HWBSKPD 0x24f4 + +/* Binner memory pool reg: + */ +#define BMP_BUFFER 0x2430 +#define BMP_PAGE_SIZE_4K (0 << 10) +#define BMP_BUFFER_SIZE_SHIFT 1 +#define BMP_ENABLE (1 << 0) + +/* Get/put memory from the binner memory pool: + */ +#define BMP_GET 0x2438 +#define BMP_PUT 0x2440 +#define BMP_OFFSET_SHIFT 5 + +/* 3D state packets: + */ +#define GFX_OP_RASTER_RULES ((0x3<<29)|(0x7<<24)) + +#define GFX_OP_SCISSOR ((0x3<<29)|(0x1c<<24)|(0x10<<19)) +#define SC_UPDATE_SCISSOR (0x1<<1) +#define SC_ENABLE_MASK (0x1<<0) +#define SC_ENABLE (0x1<<0) + +#define GFX_OP_LOAD_INDIRECT ((0x3<<29)|(0x1d<<24)|(0x7<<16)) + +#define GFX_OP_SCISSOR_INFO ((0x3<<29)|(0x1d<<24)|(0x81<<16)|(0x1)) +#define SCI_YMIN_MASK (0xffff<<16) +#define SCI_XMIN_MASK (0xffff<<0) +#define SCI_YMAX_MASK (0xffff<<16) +#define SCI_XMAX_MASK (0xffff<<0) + +#define GFX_OP_SCISSOR_ENABLE ((0x3<<29)|(0x1c<<24)|(0x10<<19)) +#define GFX_OP_SCISSOR_RECT ((0x3<<29)|(0x1d<<24)|(0x81<<16)|1) +#define GFX_OP_COLOR_FACTOR ((0x3<<29)|(0x1d<<24)|(0x1<<16)|0x0) +#define GFX_OP_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16)) +#define GFX_OP_MAP_INFO ((0x3<<29)|(0x1d<<24)|0x4) +#define GFX_OP_DESTBUFFER_VARS ((0x3<<29)|(0x1d<<24)|(0x85<<16)|0x0) +#define GFX_OP_DRAWRECT_INFO ((0x3<<29)|(0x1d<<24)|(0x80<<16)|(0x3)) + +#define GFX_OP_DRAWRECT_INFO_I965 ((0x7900<<16)|0x2) + +#define SRC_COPY_BLT_CMD ((2<<29)|(0x43<<22)|4) +#define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6) +#define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21) +#define XY_SRC_COPY_BLT_WRITE_RGB (1<<20) +#define XY_SRC_COPY_BLT_SRC_TILED (1<<15) +#define XY_SRC_COPY_BLT_DST_TILED (1<<11) + +#define MI_BATCH_BUFFER ((0x30<<23)|1) +#define MI_BATCH_BUFFER_START (0x31<<23) +#define MI_BATCH_BUFFER_END (0xA<<23) +#define MI_BATCH_NON_SECURE (1) +#define MI_BATCH_NON_SECURE_I965 (1<<8) + +#define MI_WAIT_FOR_EVENT ((0x3<<23)) +#define MI_WAIT_FOR_PLANE_B_FLIP (1<<6) +#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2) +#define MI_WAIT_FOR_PLANE_A_SCANLINES (1<<1) + +#define MI_LOAD_SCAN_LINES_INCL ((0x12<<23)) + +#define CMD_OP_DISPLAYBUFFER_INFO ((0x0<<29)|(0x14<<23)|2) +#define ASYNC_FLIP (1<<22) +#define DISPLAY_PLANE_A (0<<20) +#define DISPLAY_PLANE_B (1<<20) + +/* Display regs */ +#define DSPACNTR 0x70180 +#define DSPBCNTR 0x71180 +#define DISPPLANE_SEL_PIPE_MASK (1<<24) + +/* Define the region of interest for the binner: + */ +#define CMD_OP_BIN_CONTROL ((0x3<<29)|(0x1d<<24)|(0x84<<16)|4) + +#define CMD_OP_DESTBUFFER_INFO ((0x3<<29)|(0x1d<<24)|(0x8e<<16)|1) + +#define CMD_MI_FLUSH (0x04 << 23) +#define MI_NO_WRITE_FLUSH (1 << 2) +#define MI_READ_FLUSH (1 << 0) +#define MI_EXE_FLUSH (1 << 1) +#define MI_END_SCENE (1 << 4) /* flush binner and incr scene count */ +#define MI_SCENE_COUNT (1 << 3) /* just increment scene count */ + +#define BREADCRUMB_BITS 31 +#define BREADCRUMB_MASK ((1U << BREADCRUMB_BITS) - 1) + +#define READ_BREADCRUMB(dev_priv) (((volatile u32*)(dev_priv->hw_status_page))[5]) +#define READ_HWSP(dev_priv, reg) (((volatile u32*)(dev_priv->hw_status_page))[reg]) + +#define BLC_PWM_CTL 0x61254 +#define BACKLIGHT_MODULATION_FREQ_SHIFT (17) + +#define BLC_PWM_CTL2 0x61250 /** - * Reads a dword out of the status page, which is written to from the command - * queue by automatic updates, MI_REPORT_HEAD, MI_STORE_DATA_INDEX, or - * MI_STORE_DATA_IMM. + * This is the most significant 15 bits of the number of backlight cycles in a + * complete cycle of the modulated backlight control. * - * The following dwords have a reserved meaning: - * 0x00: ISR copy, updated when an ISR bit not set in the HWSTAM changes. - * 0x04: ring 0 head pointer - * 0x05: ring 1 head pointer (915-class) - * 0x06: ring 2 head pointer (915-class) - * 0x10-0x1b: Context status DWords (GM45) - * 0x1f: Last written status offset. (GM45) + * The actual value is this field multiplied by two. + */ +#define BACKLIGHT_MODULATION_FREQ_MASK (0x7fff << 17) +#define BLM_LEGACY_MODE (1 << 16) +/** + * This is the number of cycles out of the backlight modulation cycle for which + * the backlight is on. * - * The area from dword 0x20 to 0x3ff is available for driver usage. + * This field must be no greater than the number of cycles in the complete + * backlight modulation cycle. */ -#define READ_HWSP(dev_priv, reg) (((volatile u32*)(dev_priv->hw_status_page))[reg]) -#define READ_BREADCRUMB(dev_priv) READ_HWSP(dev_priv, 5) -#define I915_GEM_HWS_INDEX 0x20 +#define BACKLIGHT_DUTY_CYCLE_SHIFT (0) +#define BACKLIGHT_DUTY_CYCLE_MASK (0xffff) + +#define I915_GCFGC 0xf0 +#define I915_LOW_FREQUENCY_ENABLE (1 << 7) +#define I915_DISPLAY_CLOCK_190_200_MHZ (0 << 4) +#define I915_DISPLAY_CLOCK_333_MHZ (4 << 4) +#define I915_DISPLAY_CLOCK_MASK (7 << 4) + +#define I855_HPLLCC 0xc0 +#define I855_CLOCK_CONTROL_MASK (3 << 0) +#define I855_CLOCK_133_200 (0 << 0) +#define I855_CLOCK_100_200 (1 << 0) +#define I855_CLOCK_100_133 (2 << 0) +#define I855_CLOCK_166_250 (3 << 0) + +/* p317, 319 + */ +#define VCLK2_VCO_M 0x6008 /* treat as 16 bit? (includes msbs) */ +#define VCLK2_VCO_N 0x600a +#define VCLK2_VCO_DIV_SEL 0x6012 + +#define VCLK_DIVISOR_VGA0 0x6000 +#define VCLK_DIVISOR_VGA1 0x6004 +#define VCLK_POST_DIV 0x6010 +/** Selects a post divisor of 4 instead of 2. */ +# define VGA1_PD_P2_DIV_4 (1 << 15) +/** Overrides the p2 post divisor field */ +# define VGA1_PD_P1_DIV_2 (1 << 13) +# define VGA1_PD_P1_SHIFT 8 +/** P1 value is 2 greater than this field */ +# define VGA1_PD_P1_MASK (0x1f << 8) +/** Selects a post divisor of 4 instead of 2. */ +# define VGA0_PD_P2_DIV_4 (1 << 7) +/** Overrides the p2 post divisor field */ +# define VGA0_PD_P1_DIV_2 (1 << 5) +# define VGA0_PD_P1_SHIFT 0 +/** P1 value is 2 greater than this field */ +# define VGA0_PD_P1_MASK (0x1f << 0) + +/* PCI D state control register */ +#define D_STATE 0x6104 +#define DSPCLK_GATE_D 0x6200 + +/* I830 CRTC registers */ +#define HTOTAL_A 0x60000 +#define HBLANK_A 0x60004 +#define HSYNC_A 0x60008 +#define VTOTAL_A 0x6000c +#define VBLANK_A 0x60010 +#define VSYNC_A 0x60014 +#define PIPEASRC 0x6001c +#define BCLRPAT_A 0x60020 +#define VSYNCSHIFT_A 0x60028 + +#define HTOTAL_B 0x61000 +#define HBLANK_B 0x61004 +#define HSYNC_B 0x61008 +#define VTOTAL_B 0x6100c +#define VBLANK_B 0x61010 +#define VSYNC_B 0x61014 +#define PIPEBSRC 0x6101c +#define BCLRPAT_B 0x61020 +#define VSYNCSHIFT_B 0x61028 + +#define PP_STATUS 0x61200 +# define PP_ON (1 << 31) +/** + * Indicates that all dependencies of the panel are on: + * + * - PLL enabled + * - pipe enabled + * - LVDS/DVOB/DVOC on + */ +# define PP_READY (1 << 30) +# define PP_SEQUENCE_NONE (0 << 28) +# define PP_SEQUENCE_ON (1 << 28) +# define PP_SEQUENCE_OFF (2 << 28) +# define PP_SEQUENCE_MASK 0x30000000 +#define PP_CONTROL 0x61204 +# define POWER_TARGET_ON (1 << 0) + +#define LVDSPP_ON 0x61208 +#define LVDSPP_OFF 0x6120c +#define PP_CYCLE 0x61210 + +#define PFIT_CONTROL 0x61230 +# define PFIT_ENABLE (1 << 31) +# define PFIT_PIPE_MASK (3 << 29) +# define PFIT_PIPE_SHIFT 29 +# define VERT_INTERP_DISABLE (0 << 10) +# define VERT_INTERP_BILINEAR (1 << 10) +# define VERT_INTERP_MASK (3 << 10) +# define VERT_AUTO_SCALE (1 << 9) +# define HORIZ_INTERP_DISABLE (0 << 6) +# define HORIZ_INTERP_BILINEAR (1 << 6) +# define HORIZ_INTERP_MASK (3 << 6) +# define HORIZ_AUTO_SCALE (1 << 5) +# define PANEL_8TO6_DITHER_ENABLE (1 << 3) + +#define PFIT_PGM_RATIOS 0x61234 +# define PFIT_VERT_SCALE_MASK 0xfff00000 +# define PFIT_HORIZ_SCALE_MASK 0x0000fff0 + +#define PFIT_AUTO_RATIOS 0x61238 + + +#define DPLL_A 0x06014 +#define DPLL_B 0x06018 +# define DPLL_VCO_ENABLE (1 << 31) +# define DPLL_DVO_HIGH_SPEED (1 << 30) +# define DPLL_SYNCLOCK_ENABLE (1 << 29) +# define DPLL_VGA_MODE_DIS (1 << 28) +# define DPLLB_MODE_DAC_SERIAL (1 << 26) /* i915 */ +# define DPLLB_MODE_LVDS (2 << 26) /* i915 */ +# define DPLL_MODE_MASK (3 << 26) +# define DPLL_DAC_SERIAL_P2_CLOCK_DIV_10 (0 << 24) /* i915 */ +# define DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 (1 << 24) /* i915 */ +# define DPLLB_LVDS_P2_CLOCK_DIV_14 (0 << 24) /* i915 */ +# define DPLLB_LVDS_P2_CLOCK_DIV_7 (1 << 24) /* i915 */ +# define DPLL_P2_CLOCK_DIV_MASK 0x03000000 /* i915 */ +# define DPLL_FPA01_P1_POST_DIV_MASK 0x00ff0000 /* i915 */ +/** + * The i830 generation, in DAC/serial mode, defines p1 as two plus this + * bitfield, or just 2 if PLL_P1_DIVIDE_BY_TWO is set. + */ +# define DPLL_FPA01_P1_POST_DIV_MASK_I830 0x001f0000 +/** + * The i830 generation, in LVDS mode, defines P1 as the bit number set within + * this field (only one bit may be set). + */ +# define DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS 0x003f0000 +# define DPLL_FPA01_P1_POST_DIV_SHIFT 16 +# define PLL_P2_DIVIDE_BY_4 (1 << 23) /* i830, required in DVO non-gang */ +# define PLL_P1_DIVIDE_BY_TWO (1 << 21) /* i830 */ +# define PLL_REF_INPUT_DREFCLK (0 << 13) +# define PLL_REF_INPUT_TVCLKINA (1 << 13) /* i830 */ +# define PLL_REF_INPUT_TVCLKINBC (2 << 13) /* SDVO TVCLKIN */ +# define PLLB_REF_INPUT_SPREADSPECTRUMIN (3 << 13) +# define PLL_REF_INPUT_MASK (3 << 13) +# define PLL_LOAD_PULSE_PHASE_SHIFT 9 +/* + * Parallel to Serial Load Pulse phase selection. + * Selects the phase for the 10X DPLL clock for the PCIe + * digital display port. The range is 4 to 13; 10 or more + * is just a flip delay. The default is 6 + */ +# define PLL_LOAD_PULSE_PHASE_MASK (0xf << PLL_LOAD_PULSE_PHASE_SHIFT) +# define DISPLAY_RATE_SELECT_FPA1 (1 << 8) -extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); +/** + * SDVO multiplier for 945G/GM. Not used on 965. + * + * \sa DPLL_MD_UDI_MULTIPLIER_MASK + */ +# define SDVO_MULTIPLIER_MASK 0x000000ff +# define SDVO_MULTIPLIER_SHIFT_HIRES 4 +# define SDVO_MULTIPLIER_SHIFT_VGA 0 + +/** @defgroup DPLL_MD + * @{ + */ +/** Pipe A SDVO/UDI clock multiplier/divider register for G965. */ +#define DPLL_A_MD 0x0601c +/** Pipe B SDVO/UDI clock multiplier/divider register for G965. */ +#define DPLL_B_MD 0x06020 +/** + * UDI pixel divider, controlling how many pixels are stuffed into a packet. + * + * Value is pixels minus 1. Must be set to 1 pixel for SDVO. + */ +# define DPLL_MD_UDI_DIVIDER_MASK 0x3f000000 +# define DPLL_MD_UDI_DIVIDER_SHIFT 24 +/** UDI pixel divider for VGA, same as DPLL_MD_UDI_DIVIDER_MASK. */ +# define DPLL_MD_VGA_UDI_DIVIDER_MASK 0x003f0000 +# define DPLL_MD_VGA_UDI_DIVIDER_SHIFT 16 +/** + * SDVO/UDI pixel multiplier. + * + * SDVO requires that the bus clock rate be between 1 and 2 Ghz, and the bus + * clock rate is 10 times the DPLL clock. At low resolution/refresh rate + * modes, the bus rate would be below the limits, so SDVO allows for stuffing + * dummy bytes in the datastream at an increased clock rate, with both sides of + * the link knowing how many bytes are fill. + * + * So, for a mode with a dotclock of 65Mhz, we would want to double the clock + * rate to 130Mhz to get a bus rate of 1.30Ghz. The DPLL clock rate would be + * set to 130Mhz, and the SDVO multiplier set to 2x in this register and + * through an SDVO command. + * + * This register field has values of multiplication factor minus 1, with + * a maximum multiplier of 5 for SDVO. + */ +# define DPLL_MD_UDI_MULTIPLIER_MASK 0x00003f00 +# define DPLL_MD_UDI_MULTIPLIER_SHIFT 8 +/** SDVO/UDI pixel multiplier for VGA, same as DPLL_MD_UDI_MULTIPLIER_MASK. + * This best be set to the default value (3) or the CRT won't work. No, + * I don't entirely understand what this does... + */ +# define DPLL_MD_VGA_UDI_MULTIPLIER_MASK 0x0000003f +# define DPLL_MD_VGA_UDI_MULTIPLIER_SHIFT 0 +/** @} */ + +#define DPLL_TEST 0x606c +# define DPLLB_TEST_SDVO_DIV_1 (0 << 22) +# define DPLLB_TEST_SDVO_DIV_2 (1 << 22) +# define DPLLB_TEST_SDVO_DIV_4 (2 << 22) +# define DPLLB_TEST_SDVO_DIV_MASK (3 << 22) +# define DPLLB_TEST_N_BYPASS (1 << 19) +# define DPLLB_TEST_M_BYPASS (1 << 18) +# define DPLLB_INPUT_BUFFER_ENABLE (1 << 16) +# define DPLLA_TEST_N_BYPASS (1 << 3) +# define DPLLA_TEST_M_BYPASS (1 << 2) +# define DPLLA_INPUT_BUFFER_ENABLE (1 << 0) + +#define ADPA 0x61100 +#define ADPA_DAC_ENABLE (1<<31) +#define ADPA_DAC_DISABLE 0 +#define ADPA_PIPE_SELECT_MASK (1<<30) +#define ADPA_PIPE_A_SELECT 0 +#define ADPA_PIPE_B_SELECT (1<<30) +#define ADPA_USE_VGA_HVPOLARITY (1<<15) +#define ADPA_SETS_HVPOLARITY 0 +#define ADPA_VSYNC_CNTL_DISABLE (1<<11) +#define ADPA_VSYNC_CNTL_ENABLE 0 +#define ADPA_HSYNC_CNTL_DISABLE (1<<10) +#define ADPA_HSYNC_CNTL_ENABLE 0 +#define ADPA_VSYNC_ACTIVE_HIGH (1<<4) +#define ADPA_VSYNC_ACTIVE_LOW 0 +#define ADPA_HSYNC_ACTIVE_HIGH (1<<3) +#define ADPA_HSYNC_ACTIVE_LOW 0 + +#define FPA0 0x06040 +#define FPA1 0x06044 +#define FPB0 0x06048 +#define FPB1 0x0604c +# define FP_N_DIV_MASK 0x003f0000 +# define FP_N_DIV_SHIFT 16 +# define FP_M1_DIV_MASK 0x00003f00 +# define FP_M1_DIV_SHIFT 8 +# define FP_M2_DIV_MASK 0x0000003f +# define FP_M2_DIV_SHIFT 0 + + +#define PORT_HOTPLUG_EN 0x61110 +# define SDVOB_HOTPLUG_INT_EN (1 << 26) +# define SDVOC_HOTPLUG_INT_EN (1 << 25) +# define TV_HOTPLUG_INT_EN (1 << 18) +# define CRT_HOTPLUG_INT_EN (1 << 9) +# define CRT_HOTPLUG_FORCE_DETECT (1 << 3) + +#define PORT_HOTPLUG_STAT 0x61114 +# define CRT_HOTPLUG_INT_STATUS (1 << 11) +# define TV_HOTPLUG_INT_STATUS (1 << 10) +# define CRT_HOTPLUG_MONITOR_MASK (3 << 8) +# define CRT_HOTPLUG_MONITOR_COLOR (3 << 8) +# define CRT_HOTPLUG_MONITOR_MONO (2 << 8) +# define CRT_HOTPLUG_MONITOR_NONE (0 << 8) +# define SDVOC_HOTPLUG_INT_STATUS (1 << 7) +# define SDVOB_HOTPLUG_INT_STATUS (1 << 6) + +#define SDVOB 0x61140 +#define SDVOC 0x61160 +#define SDVO_ENABLE (1 << 31) +#define SDVO_PIPE_B_SELECT (1 << 30) +#define SDVO_STALL_SELECT (1 << 29) +#define SDVO_INTERRUPT_ENABLE (1 << 26) +/** + * 915G/GM SDVO pixel multiplier. + * + * Programmed value is multiplier - 1, up to 5x. + * + * \sa DPLL_MD_UDI_MULTIPLIER_MASK + */ +#define SDVO_PORT_MULTIPLY_MASK (7 << 23) +#define SDVO_PORT_MULTIPLY_SHIFT 23 +#define SDVO_PHASE_SELECT_MASK (15 << 19) +#define SDVO_PHASE_SELECT_DEFAULT (6 << 19) +#define SDVO_CLOCK_OUTPUT_INVERT (1 << 18) +#define SDVOC_GANG_MODE (1 << 16) +#define SDVO_BORDER_ENABLE (1 << 7) +#define SDVOB_PCIE_CONCURRENCY (1 << 3) +#define SDVO_DETECTED (1 << 2) +/* Bits to be preserved when writing */ +#define SDVOB_PRESERVE_MASK ((1 << 17) | (1 << 16) | (1 << 14)) +#define SDVOC_PRESERVE_MASK (1 << 17) + +/** @defgroup LVDS + * @{ + */ +/** + * This register controls the LVDS output enable, pipe selection, and data + * format selection. + * + * All of the clock/data pairs are force powered down by power sequencing. + */ +#define LVDS 0x61180 +/** + * Enables the LVDS port. This bit must be set before DPLLs are enabled, as + * the DPLL semantics change when the LVDS is assigned to that pipe. + */ +# define LVDS_PORT_EN (1 << 31) +/** Selects pipe B for LVDS data. Must be set on pre-965. */ +# define LVDS_PIPEB_SELECT (1 << 30) + +/** + * Enables the A0-A2 data pairs and CLKA, containing 18 bits of color data per + * pixel. + */ +# define LVDS_A0A2_CLKA_POWER_MASK (3 << 8) +# define LVDS_A0A2_CLKA_POWER_DOWN (0 << 8) +# define LVDS_A0A2_CLKA_POWER_UP (3 << 8) +/** + * Controls the A3 data pair, which contains the additional LSBs for 24 bit + * mode. Only enabled if LVDS_A0A2_CLKA_POWER_UP also indicates it should be + * on. + */ +# define LVDS_A3_POWER_MASK (3 << 6) +# define LVDS_A3_POWER_DOWN (0 << 6) +# define LVDS_A3_POWER_UP (3 << 6) +/** + * Controls the CLKB pair. This should only be set when LVDS_B0B3_POWER_UP + * is set. + */ +# define LVDS_CLKB_POWER_MASK (3 << 4) +# define LVDS_CLKB_POWER_DOWN (0 << 4) +# define LVDS_CLKB_POWER_UP (3 << 4) + +/** + * Controls the B0-B3 data pairs. This must be set to match the DPLL p2 + * setting for whether we are in dual-channel mode. The B3 pair will + * additionally only be powered up when LVDS_A3_POWER_UP is set. + */ +# define LVDS_B0B3_POWER_MASK (3 << 2) +# define LVDS_B0B3_POWER_DOWN (0 << 2) +# define LVDS_B0B3_POWER_UP (3 << 2) + +#define PIPEACONF 0x70008 +#define PIPEACONF_ENABLE (1<<31) +#define PIPEACONF_DISABLE 0 +#define PIPEACONF_DOUBLE_WIDE (1<<30) +#define I965_PIPECONF_ACTIVE (1<<30) +#define PIPEACONF_SINGLE_WIDE 0 +#define PIPEACONF_PIPE_UNLOCKED 0 +#define PIPEACONF_PIPE_LOCKED (1<<25) +#define PIPEACONF_PALETTE 0 +#define PIPEACONF_GAMMA (1<<24) +#define PIPECONF_FORCE_BORDER (1<<25) +#define PIPECONF_PROGRESSIVE (0 << 21) +#define PIPECONF_INTERLACE_W_FIELD_INDICATION (6 << 21) +#define PIPECONF_INTERLACE_FIELD_0_ONLY (7 << 21) + +#define DSPARB 0x70030 +#define DSPARB_CSTART_MASK (0x7f << 7) +#define DSPARB_CSTART_SHIFT 7 +#define DSPARB_BSTART_MASK (0x7f) +#define DSPARB_BSTART_SHIFT 0 + +#define PIPEBCONF 0x71008 +#define PIPEBCONF_ENABLE (1<<31) +#define PIPEBCONF_DISABLE 0 +#define PIPEBCONF_DOUBLE_WIDE (1<<30) +#define PIPEBCONF_DISABLE 0 +#define PIPEBCONF_GAMMA (1<<24) +#define PIPEBCONF_PALETTE 0 + +#define PIPEBGCMAXRED 0x71010 +#define PIPEBGCMAXGREEN 0x71014 +#define PIPEBGCMAXBLUE 0x71018 +#define PIPEBSTAT 0x71024 +#define PIPEBFRAMEHIGH 0x71040 +#define PIPEBFRAMEPIXEL 0x71044 + +#define DSPACNTR 0x70180 +#define DSPBCNTR 0x71180 +#define DISPLAY_PLANE_ENABLE (1<<31) +#define DISPLAY_PLANE_DISABLE 0 +#define DISPPLANE_GAMMA_ENABLE (1<<30) +#define DISPPLANE_GAMMA_DISABLE 0 +#define DISPPLANE_PIXFORMAT_MASK (0xf<<26) +#define DISPPLANE_8BPP (0x2<<26) +#define DISPPLANE_15_16BPP (0x4<<26) +#define DISPPLANE_16BPP (0x5<<26) +#define DISPPLANE_32BPP_NO_ALPHA (0x6<<26) +#define DISPPLANE_32BPP (0x7<<26) +#define DISPPLANE_STEREO_ENABLE (1<<25) +#define DISPPLANE_STEREO_DISABLE 0 +#define DISPPLANE_SEL_PIPE_MASK (1<<24) +#define DISPPLANE_SEL_PIPE_A 0 +#define DISPPLANE_SEL_PIPE_B (1<<24) +#define DISPPLANE_SRC_KEY_ENABLE (1<<22) +#define DISPPLANE_SRC_KEY_DISABLE 0 +#define DISPPLANE_LINE_DOUBLE (1<<20) +#define DISPPLANE_NO_LINE_DOUBLE 0 +#define DISPPLANE_STEREO_POLARITY_FIRST 0 +#define DISPPLANE_STEREO_POLARITY_SECOND (1<<18) +/* plane B only */ +#define DISPPLANE_ALPHA_TRANS_ENABLE (1<<15) +#define DISPPLANE_ALPHA_TRANS_DISABLE 0 +#define DISPPLANE_SPRITE_ABOVE_DISPLAYA 0 +#define DISPPLANE_SPRITE_ABOVE_OVERLAY (1) + +#define DSPABASE 0x70184 +#define DSPASTRIDE 0x70188 + +#define DSPBBASE 0x71184 +#define DSPBADDR DSPBBASE +#define DSPBSTRIDE 0x71188 + +#define DSPAKEYVAL 0x70194 +#define DSPAKEYMASK 0x70198 + +#define DSPAPOS 0x7018C /* reserved */ +#define DSPASIZE 0x70190 +#define DSPBPOS 0x7118C +#define DSPBSIZE 0x71190 + +#define DSPASURF 0x7019C +#define DSPATILEOFF 0x701A4 + +#define DSPBSURF 0x7119C +#define DSPBTILEOFF 0x711A4 + +#define VGACNTRL 0x71400 +# define VGA_DISP_DISABLE (1 << 31) +# define VGA_2X_MODE (1 << 30) +# define VGA_PIPE_B_SELECT (1 << 29) + +/* + * Some BIOS scratch area registers. The 845 (and 830?) store the amount + * of video memory available to the BIOS in SWF1. + */ + +#define SWF0 0x71410 + +/* + * 855 scratch registers. + */ +#define SWF10 0x70410 + +#define SWF30 0x72414 + +/* + * Overlay registers. These are overlay registers accessed via MMIO. + * Those loaded via the overlay register page are defined in i830_video.c. + */ +#define OVADD 0x30000 + +#define DOVSTA 0x30008 +#define OC_BUF (0x3<<20) + +#define OGAMC5 0x30010 +#define OGAMC4 0x30014 +#define OGAMC3 0x30018 +#define OGAMC2 0x3001c +#define OGAMC1 0x30020 +#define OGAMC0 0x30024 +/* + * Palette registers + */ +#define PALETTE_A 0x0a000 +#define PALETTE_B 0x0a800 #define IS_I830(dev) ((dev)->pci_device == 0x3577) #define IS_845G(dev) ((dev)->pci_device == 0x2562) @@ -639,7 +1119,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); #define IS_I965GM(dev) ((dev)->pci_device == 0x2A02) -#define IS_GM45(dev) ((dev)->pci_device == 0x2A42) +#define IS_IGD_GM(dev) ((dev)->pci_device == 0x2A42) #define IS_G4X(dev) ((dev)->pci_device == 0x2E02 || \ (dev)->pci_device == 0x2E12 || \ @@ -653,9 +1133,9 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); IS_I945GM(dev) || IS_I965G(dev) || IS_G33(dev)) #define IS_MOBILE(dev) (IS_I830(dev) || IS_I85X(dev) || IS_I915GM(dev) || \ - IS_I945GM(dev) || IS_I965GM(dev) || IS_GM45(dev)) + IS_I945GM(dev) || IS_I965GM(dev) || IS_IGD_GM(dev)) -#define I915_NEED_GFX_HWS(dev) (IS_G33(dev) || IS_GM45(dev) || IS_G4X(dev)) +#define I915_NEED_GFX_HWS(dev) (IS_G33(dev) || IS_IGD_GM(dev) || IS_G4X(dev)) #define PRIMARY_RINGBUFFER_SIZE (128*1024) diff --git a/trunk/drivers/gpu/drm/i915/i915_gem.c b/trunk/drivers/gpu/drm/i915/i915_gem.c deleted file mode 100644 index 9ac73dd1b422..000000000000 --- a/trunk/drivers/gpu/drm/i915/i915_gem.c +++ /dev/null @@ -1,2558 +0,0 @@ -/* - * Copyright © 2008 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - * - * Authors: - * Eric Anholt - * - */ - -#include "drmP.h" -#include "drm.h" -#include "i915_drm.h" -#include "i915_drv.h" -#include - -static int -i915_gem_object_set_domain(struct drm_gem_object *obj, - uint32_t read_domains, - uint32_t write_domain); -static int -i915_gem_object_set_domain_range(struct drm_gem_object *obj, - uint64_t offset, - uint64_t size, - uint32_t read_domains, - uint32_t write_domain); -static int -i915_gem_set_domain(struct drm_gem_object *obj, - struct drm_file *file_priv, - uint32_t read_domains, - uint32_t write_domain); -static int i915_gem_object_get_page_list(struct drm_gem_object *obj); -static void i915_gem_object_free_page_list(struct drm_gem_object *obj); -static int i915_gem_object_wait_rendering(struct drm_gem_object *obj); - -static void -i915_gem_cleanup_ringbuffer(struct drm_device *dev); - -int -i915_gem_init_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_init *args = data; - - mutex_lock(&dev->struct_mutex); - - if (args->gtt_start >= args->gtt_end || - (args->gtt_start & (PAGE_SIZE - 1)) != 0 || - (args->gtt_end & (PAGE_SIZE - 1)) != 0) { - mutex_unlock(&dev->struct_mutex); - return -EINVAL; - } - - drm_mm_init(&dev_priv->mm.gtt_space, args->gtt_start, - args->gtt_end - args->gtt_start); - - dev->gtt_total = (uint32_t) (args->gtt_end - args->gtt_start); - - mutex_unlock(&dev->struct_mutex); - - return 0; -} - - -/** - * Creates a new mm object and returns a handle to it. - */ -int -i915_gem_create_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_i915_gem_create *args = data; - struct drm_gem_object *obj; - int handle, ret; - - args->size = roundup(args->size, PAGE_SIZE); - - /* Allocate the new object */ - obj = drm_gem_object_alloc(dev, args->size); - if (obj == NULL) - return -ENOMEM; - - ret = drm_gem_handle_create(file_priv, obj, &handle); - mutex_lock(&dev->struct_mutex); - drm_gem_object_handle_unreference(obj); - mutex_unlock(&dev->struct_mutex); - - if (ret) - return ret; - - args->handle = handle; - - return 0; -} - -/** - * Reads data from the object referenced by handle. - * - * On error, the contents of *data are undefined. - */ -int -i915_gem_pread_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_i915_gem_pread *args = data; - struct drm_gem_object *obj; - struct drm_i915_gem_object *obj_priv; - ssize_t read; - loff_t offset; - int ret; - - obj = drm_gem_object_lookup(dev, file_priv, args->handle); - if (obj == NULL) - return -EBADF; - obj_priv = obj->driver_private; - - /* Bounds check source. - * - * XXX: This could use review for overflow issues... - */ - if (args->offset > obj->size || args->size > obj->size || - args->offset + args->size > obj->size) { - drm_gem_object_unreference(obj); - return -EINVAL; - } - - mutex_lock(&dev->struct_mutex); - - ret = i915_gem_object_set_domain_range(obj, args->offset, args->size, - I915_GEM_DOMAIN_CPU, 0); - if (ret != 0) { - drm_gem_object_unreference(obj); - mutex_unlock(&dev->struct_mutex); - return ret; - } - - offset = args->offset; - - read = vfs_read(obj->filp, (char __user *)(uintptr_t)args->data_ptr, - args->size, &offset); - if (read != args->size) { - drm_gem_object_unreference(obj); - mutex_unlock(&dev->struct_mutex); - if (read < 0) - return read; - else - return -EINVAL; - } - - drm_gem_object_unreference(obj); - mutex_unlock(&dev->struct_mutex); - - return 0; -} - -static int -i915_gem_gtt_pwrite(struct drm_device *dev, struct drm_gem_object *obj, - struct drm_i915_gem_pwrite *args, - struct drm_file *file_priv) -{ - struct drm_i915_gem_object *obj_priv = obj->driver_private; - ssize_t remain; - loff_t offset; - char __user *user_data; - char __iomem *vaddr; - char *vaddr_atomic; - int i, o, l; - int ret = 0; - unsigned long pfn; - unsigned long unwritten; - - user_data = (char __user *) (uintptr_t) args->data_ptr; - remain = args->size; - if (!access_ok(VERIFY_READ, user_data, remain)) - return -EFAULT; - - - mutex_lock(&dev->struct_mutex); - ret = i915_gem_object_pin(obj, 0); - if (ret) { - mutex_unlock(&dev->struct_mutex); - return ret; - } - ret = i915_gem_set_domain(obj, file_priv, - I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT); - if (ret) - goto fail; - - obj_priv = obj->driver_private; - offset = obj_priv->gtt_offset + args->offset; - obj_priv->dirty = 1; - - while (remain > 0) { - /* Operation in this page - * - * i = page number - * o = offset within page - * l = bytes to copy - */ - i = offset >> PAGE_SHIFT; - o = offset & (PAGE_SIZE-1); - l = remain; - if ((o + l) > PAGE_SIZE) - l = PAGE_SIZE - o; - - pfn = (dev->agp->base >> PAGE_SHIFT) + i; - -#ifdef CONFIG_HIGHMEM - /* This is a workaround for the low performance of iounmap - * (approximate 10% cpu cost on normal 3D workloads). - * kmap_atomic on HIGHMEM kernels happens to let us map card - * memory without taking IPIs. When the vmap rework lands - * we should be able to dump this hack. - */ - vaddr_atomic = kmap_atomic_pfn(pfn, KM_USER0); -#if WATCH_PWRITE - DRM_INFO("pwrite i %d o %d l %d pfn %ld vaddr %p\n", - i, o, l, pfn, vaddr_atomic); -#endif - unwritten = __copy_from_user_inatomic_nocache(vaddr_atomic + o, - user_data, l); - kunmap_atomic(vaddr_atomic, KM_USER0); - - if (unwritten) -#endif /* CONFIG_HIGHMEM */ - { - vaddr = ioremap_wc(pfn << PAGE_SHIFT, PAGE_SIZE); -#if WATCH_PWRITE - DRM_INFO("pwrite slow i %d o %d l %d " - "pfn %ld vaddr %p\n", - i, o, l, pfn, vaddr); -#endif - if (vaddr == NULL) { - ret = -EFAULT; - goto fail; - } - unwritten = __copy_from_user(vaddr + o, user_data, l); -#if WATCH_PWRITE - DRM_INFO("unwritten %ld\n", unwritten); -#endif - iounmap(vaddr); - if (unwritten) { - ret = -EFAULT; - goto fail; - } - } - - remain -= l; - user_data += l; - offset += l; - } -#if WATCH_PWRITE && 1 - i915_gem_clflush_object(obj); - i915_gem_dump_object(obj, args->offset + args->size, __func__, ~0); - i915_gem_clflush_object(obj); -#endif - -fail: - i915_gem_object_unpin(obj); - mutex_unlock(&dev->struct_mutex); - - return ret; -} - -static int -i915_gem_shmem_pwrite(struct drm_device *dev, struct drm_gem_object *obj, - struct drm_i915_gem_pwrite *args, - struct drm_file *file_priv) -{ - int ret; - loff_t offset; - ssize_t written; - - mutex_lock(&dev->struct_mutex); - - ret = i915_gem_set_domain(obj, file_priv, - I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU); - if (ret) { - mutex_unlock(&dev->struct_mutex); - return ret; - } - - offset = args->offset; - - written = vfs_write(obj->filp, - (char __user *)(uintptr_t) args->data_ptr, - args->size, &offset); - if (written != args->size) { - mutex_unlock(&dev->struct_mutex); - if (written < 0) - return written; - else - return -EINVAL; - } - - mutex_unlock(&dev->struct_mutex); - - return 0; -} - -/** - * Writes data to the object referenced by handle. - * - * On error, the contents of the buffer that were to be modified are undefined. - */ -int -i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_i915_gem_pwrite *args = data; - struct drm_gem_object *obj; - struct drm_i915_gem_object *obj_priv; - int ret = 0; - - obj = drm_gem_object_lookup(dev, file_priv, args->handle); - if (obj == NULL) - return -EBADF; - obj_priv = obj->driver_private; - - /* Bounds check destination. - * - * XXX: This could use review for overflow issues... - */ - if (args->offset > obj->size || args->size > obj->size || - args->offset + args->size > obj->size) { - drm_gem_object_unreference(obj); - return -EINVAL; - } - - /* We can only do the GTT pwrite on untiled buffers, as otherwise - * it would end up going through the fenced access, and we'll get - * different detiling behavior between reading and writing. - * pread/pwrite currently are reading and writing from the CPU - * perspective, requiring manual detiling by the client. - */ - if (obj_priv->tiling_mode == I915_TILING_NONE && - dev->gtt_total != 0) - ret = i915_gem_gtt_pwrite(dev, obj, args, file_priv); - else - ret = i915_gem_shmem_pwrite(dev, obj, args, file_priv); - -#if WATCH_PWRITE - if (ret) - DRM_INFO("pwrite failed %d\n", ret); -#endif - - drm_gem_object_unreference(obj); - - return ret; -} - -/** - * Called when user space prepares to use an object - */ -int -i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_i915_gem_set_domain *args = data; - struct drm_gem_object *obj; - int ret; - - if (!(dev->driver->driver_features & DRIVER_GEM)) - return -ENODEV; - - obj = drm_gem_object_lookup(dev, file_priv, args->handle); - if (obj == NULL) - return -EBADF; - - mutex_lock(&dev->struct_mutex); -#if WATCH_BUF - DRM_INFO("set_domain_ioctl %p(%d), %08x %08x\n", - obj, obj->size, args->read_domains, args->write_domain); -#endif - ret = i915_gem_set_domain(obj, file_priv, - args->read_domains, args->write_domain); - drm_gem_object_unreference(obj); - mutex_unlock(&dev->struct_mutex); - return ret; -} - -/** - * Called when user space has done writes to this buffer - */ -int -i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_i915_gem_sw_finish *args = data; - struct drm_gem_object *obj; - struct drm_i915_gem_object *obj_priv; - int ret = 0; - - if (!(dev->driver->driver_features & DRIVER_GEM)) - return -ENODEV; - - mutex_lock(&dev->struct_mutex); - obj = drm_gem_object_lookup(dev, file_priv, args->handle); - if (obj == NULL) { - mutex_unlock(&dev->struct_mutex); - return -EBADF; - } - -#if WATCH_BUF - DRM_INFO("%s: sw_finish %d (%p %d)\n", - __func__, args->handle, obj, obj->size); -#endif - obj_priv = obj->driver_private; - - /* Pinned buffers may be scanout, so flush the cache */ - if ((obj->write_domain & I915_GEM_DOMAIN_CPU) && obj_priv->pin_count) { - i915_gem_clflush_object(obj); - drm_agp_chipset_flush(dev); - } - drm_gem_object_unreference(obj); - mutex_unlock(&dev->struct_mutex); - return ret; -} - -/** - * Maps the contents of an object, returning the address it is mapped - * into. - * - * While the mapping holds a reference on the contents of the object, it doesn't - * imply a ref on the object itself. - */ -int -i915_gem_mmap_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_i915_gem_mmap *args = data; - struct drm_gem_object *obj; - loff_t offset; - unsigned long addr; - - if (!(dev->driver->driver_features & DRIVER_GEM)) - return -ENODEV; - - obj = drm_gem_object_lookup(dev, file_priv, args->handle); - if (obj == NULL) - return -EBADF; - - offset = args->offset; - - down_write(¤t->mm->mmap_sem); - addr = do_mmap(obj->filp, 0, args->size, - PROT_READ | PROT_WRITE, MAP_SHARED, - args->offset); - up_write(¤t->mm->mmap_sem); - mutex_lock(&dev->struct_mutex); - drm_gem_object_unreference(obj); - mutex_unlock(&dev->struct_mutex); - if (IS_ERR((void *)addr)) - return addr; - - args->addr_ptr = (uint64_t) addr; - - return 0; -} - -static void -i915_gem_object_free_page_list(struct drm_gem_object *obj) -{ - struct drm_i915_gem_object *obj_priv = obj->driver_private; - int page_count = obj->size / PAGE_SIZE; - int i; - - if (obj_priv->page_list == NULL) - return; - - - for (i = 0; i < page_count; i++) - if (obj_priv->page_list[i] != NULL) { - if (obj_priv->dirty) - set_page_dirty(obj_priv->page_list[i]); - mark_page_accessed(obj_priv->page_list[i]); - page_cache_release(obj_priv->page_list[i]); - } - obj_priv->dirty = 0; - - drm_free(obj_priv->page_list, - page_count * sizeof(struct page *), - DRM_MEM_DRIVER); - obj_priv->page_list = NULL; -} - -static void -i915_gem_object_move_to_active(struct drm_gem_object *obj) -{ - struct drm_device *dev = obj->dev; - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv = obj->driver_private; - - /* Add a reference if we're newly entering the active list. */ - if (!obj_priv->active) { - drm_gem_object_reference(obj); - obj_priv->active = 1; - } - /* Move from whatever list we were on to the tail of execution. */ - list_move_tail(&obj_priv->list, - &dev_priv->mm.active_list); -} - - -static void -i915_gem_object_move_to_inactive(struct drm_gem_object *obj) -{ - struct drm_device *dev = obj->dev; - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv = obj->driver_private; - - i915_verify_inactive(dev, __FILE__, __LINE__); - if (obj_priv->pin_count != 0) - list_del_init(&obj_priv->list); - else - list_move_tail(&obj_priv->list, &dev_priv->mm.inactive_list); - - if (obj_priv->active) { - obj_priv->active = 0; - drm_gem_object_unreference(obj); - } - i915_verify_inactive(dev, __FILE__, __LINE__); -} - -/** - * Creates a new sequence number, emitting a write of it to the status page - * plus an interrupt, which will trigger i915_user_interrupt_handler. - * - * Must be called with struct_lock held. - * - * Returned sequence numbers are nonzero on success. - */ -static uint32_t -i915_add_request(struct drm_device *dev, uint32_t flush_domains) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_request *request; - uint32_t seqno; - int was_empty; - RING_LOCALS; - - request = drm_calloc(1, sizeof(*request), DRM_MEM_DRIVER); - if (request == NULL) - return 0; - - /* Grab the seqno we're going to make this request be, and bump the - * next (skipping 0 so it can be the reserved no-seqno value). - */ - seqno = dev_priv->mm.next_gem_seqno; - dev_priv->mm.next_gem_seqno++; - if (dev_priv->mm.next_gem_seqno == 0) - dev_priv->mm.next_gem_seqno++; - - BEGIN_LP_RING(4); - OUT_RING(MI_STORE_DWORD_INDEX); - OUT_RING(I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); - OUT_RING(seqno); - - OUT_RING(MI_USER_INTERRUPT); - ADVANCE_LP_RING(); - - DRM_DEBUG("%d\n", seqno); - - request->seqno = seqno; - request->emitted_jiffies = jiffies; - request->flush_domains = flush_domains; - was_empty = list_empty(&dev_priv->mm.request_list); - list_add_tail(&request->list, &dev_priv->mm.request_list); - - if (was_empty && !dev_priv->mm.suspended) - schedule_delayed_work(&dev_priv->mm.retire_work, HZ); - return seqno; -} - -/** - * Command execution barrier - * - * Ensures that all commands in the ring are finished - * before signalling the CPU - */ -static uint32_t -i915_retire_commands(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - uint32_t cmd = MI_FLUSH | MI_NO_WRITE_FLUSH; - uint32_t flush_domains = 0; - RING_LOCALS; - - /* The sampler always gets flushed on i965 (sigh) */ - if (IS_I965G(dev)) - flush_domains |= I915_GEM_DOMAIN_SAMPLER; - BEGIN_LP_RING(2); - OUT_RING(cmd); - OUT_RING(0); /* noop */ - ADVANCE_LP_RING(); - return flush_domains; -} - -/** - * Moves buffers associated only with the given active seqno from the active - * to inactive list, potentially freeing them. - */ -static void -i915_gem_retire_request(struct drm_device *dev, - struct drm_i915_gem_request *request) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - - /* Move any buffers on the active list that are no longer referenced - * by the ringbuffer to the flushing/inactive lists as appropriate. - */ - while (!list_empty(&dev_priv->mm.active_list)) { - struct drm_gem_object *obj; - struct drm_i915_gem_object *obj_priv; - - obj_priv = list_first_entry(&dev_priv->mm.active_list, - struct drm_i915_gem_object, - list); - obj = obj_priv->obj; - - /* If the seqno being retired doesn't match the oldest in the - * list, then the oldest in the list must still be newer than - * this seqno. - */ - if (obj_priv->last_rendering_seqno != request->seqno) - return; -#if WATCH_LRU - DRM_INFO("%s: retire %d moves to inactive list %p\n", - __func__, request->seqno, obj); -#endif - - if (obj->write_domain != 0) { - list_move_tail(&obj_priv->list, - &dev_priv->mm.flushing_list); - } else { - i915_gem_object_move_to_inactive(obj); - } - } - - if (request->flush_domains != 0) { - struct drm_i915_gem_object *obj_priv, *next; - - /* Clear the write domain and activity from any buffers - * that are just waiting for a flush matching the one retired. - */ - list_for_each_entry_safe(obj_priv, next, - &dev_priv->mm.flushing_list, list) { - struct drm_gem_object *obj = obj_priv->obj; - - if (obj->write_domain & request->flush_domains) { - obj->write_domain = 0; - i915_gem_object_move_to_inactive(obj); - } - } - - } -} - -/** - * Returns true if seq1 is later than seq2. - */ -static int -i915_seqno_passed(uint32_t seq1, uint32_t seq2) -{ - return (int32_t)(seq1 - seq2) >= 0; -} - -uint32_t -i915_get_gem_seqno(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - - return READ_HWSP(dev_priv, I915_GEM_HWS_INDEX); -} - -/** - * This function clears the request list as sequence numbers are passed. - */ -void -i915_gem_retire_requests(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - uint32_t seqno; - - seqno = i915_get_gem_seqno(dev); - - while (!list_empty(&dev_priv->mm.request_list)) { - struct drm_i915_gem_request *request; - uint32_t retiring_seqno; - - request = list_first_entry(&dev_priv->mm.request_list, - struct drm_i915_gem_request, - list); - retiring_seqno = request->seqno; - - if (i915_seqno_passed(seqno, retiring_seqno) || - dev_priv->mm.wedged) { - i915_gem_retire_request(dev, request); - - list_del(&request->list); - drm_free(request, sizeof(*request), DRM_MEM_DRIVER); - } else - break; - } -} - -void -i915_gem_retire_work_handler(struct work_struct *work) -{ - drm_i915_private_t *dev_priv; - struct drm_device *dev; - - dev_priv = container_of(work, drm_i915_private_t, - mm.retire_work.work); - dev = dev_priv->dev; - - mutex_lock(&dev->struct_mutex); - i915_gem_retire_requests(dev); - if (!dev_priv->mm.suspended && - !list_empty(&dev_priv->mm.request_list)) - schedule_delayed_work(&dev_priv->mm.retire_work, HZ); - mutex_unlock(&dev->struct_mutex); -} - -/** - * Waits for a sequence number to be signaled, and cleans up the - * request and object lists appropriately for that event. - */ -static int -i915_wait_request(struct drm_device *dev, uint32_t seqno) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - int ret = 0; - - BUG_ON(seqno == 0); - - if (!i915_seqno_passed(i915_get_gem_seqno(dev), seqno)) { - dev_priv->mm.waiting_gem_seqno = seqno; - i915_user_irq_get(dev); - ret = wait_event_interruptible(dev_priv->irq_queue, - i915_seqno_passed(i915_get_gem_seqno(dev), - seqno) || - dev_priv->mm.wedged); - i915_user_irq_put(dev); - dev_priv->mm.waiting_gem_seqno = 0; - } - if (dev_priv->mm.wedged) - ret = -EIO; - - if (ret && ret != -ERESTARTSYS) - DRM_ERROR("%s returns %d (awaiting %d at %d)\n", - __func__, ret, seqno, i915_get_gem_seqno(dev)); - - /* Directly dispatch request retiring. While we have the work queue - * to handle this, the waiter on a request often wants an associated - * buffer to have made it to the inactive list, and we would need - * a separate wait queue to handle that. - */ - if (ret == 0) - i915_gem_retire_requests(dev); - - return ret; -} - -static void -i915_gem_flush(struct drm_device *dev, - uint32_t invalidate_domains, - uint32_t flush_domains) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - uint32_t cmd; - RING_LOCALS; - -#if WATCH_EXEC - DRM_INFO("%s: invalidate %08x flush %08x\n", __func__, - invalidate_domains, flush_domains); -#endif - - if (flush_domains & I915_GEM_DOMAIN_CPU) - drm_agp_chipset_flush(dev); - - if ((invalidate_domains | flush_domains) & ~(I915_GEM_DOMAIN_CPU | - I915_GEM_DOMAIN_GTT)) { - /* - * read/write caches: - * - * I915_GEM_DOMAIN_RENDER is always invalidated, but is - * only flushed if MI_NO_WRITE_FLUSH is unset. On 965, it is - * also flushed at 2d versus 3d pipeline switches. - * - * read-only caches: - * - * I915_GEM_DOMAIN_SAMPLER is flushed on pre-965 if - * MI_READ_FLUSH is set, and is always flushed on 965. - * - * I915_GEM_DOMAIN_COMMAND may not exist? - * - * I915_GEM_DOMAIN_INSTRUCTION, which exists on 965, is - * invalidated when MI_EXE_FLUSH is set. - * - * I915_GEM_DOMAIN_VERTEX, which exists on 965, is - * invalidated with every MI_FLUSH. - * - * TLBs: - * - * On 965, TLBs associated with I915_GEM_DOMAIN_COMMAND - * and I915_GEM_DOMAIN_CPU in are invalidated at PTE write and - * I915_GEM_DOMAIN_RENDER and I915_GEM_DOMAIN_SAMPLER - * are flushed at any MI_FLUSH. - */ - - cmd = MI_FLUSH | MI_NO_WRITE_FLUSH; - if ((invalidate_domains|flush_domains) & - I915_GEM_DOMAIN_RENDER) - cmd &= ~MI_NO_WRITE_FLUSH; - if (!IS_I965G(dev)) { - /* - * On the 965, the sampler cache always gets flushed - * and this bit is reserved. - */ - if (invalidate_domains & I915_GEM_DOMAIN_SAMPLER) - cmd |= MI_READ_FLUSH; - } - if (invalidate_domains & I915_GEM_DOMAIN_INSTRUCTION) - cmd |= MI_EXE_FLUSH; - -#if WATCH_EXEC - DRM_INFO("%s: queue flush %08x to ring\n", __func__, cmd); -#endif - BEGIN_LP_RING(2); - OUT_RING(cmd); - OUT_RING(0); /* noop */ - ADVANCE_LP_RING(); - } -} - -/** - * Ensures that all rendering to the object has completed and the object is - * safe to unbind from the GTT or access from the CPU. - */ -static int -i915_gem_object_wait_rendering(struct drm_gem_object *obj) -{ - struct drm_device *dev = obj->dev; - struct drm_i915_gem_object *obj_priv = obj->driver_private; - int ret; - - /* If there are writes queued to the buffer, flush and - * create a new seqno to wait for. - */ - if (obj->write_domain & ~(I915_GEM_DOMAIN_CPU|I915_GEM_DOMAIN_GTT)) { - uint32_t write_domain = obj->write_domain; -#if WATCH_BUF - DRM_INFO("%s: flushing object %p from write domain %08x\n", - __func__, obj, write_domain); -#endif - i915_gem_flush(dev, 0, write_domain); - - i915_gem_object_move_to_active(obj); - obj_priv->last_rendering_seqno = i915_add_request(dev, - write_domain); - BUG_ON(obj_priv->last_rendering_seqno == 0); -#if WATCH_LRU - DRM_INFO("%s: flush moves to exec list %p\n", __func__, obj); -#endif - } - - /* If there is rendering queued on the buffer being evicted, wait for - * it. - */ - if (obj_priv->active) { -#if WATCH_BUF - DRM_INFO("%s: object %p wait for seqno %08x\n", - __func__, obj, obj_priv->last_rendering_seqno); -#endif - ret = i915_wait_request(dev, obj_priv->last_rendering_seqno); - if (ret != 0) - return ret; - } - - return 0; -} - -/** - * Unbinds an object from the GTT aperture. - */ -static int -i915_gem_object_unbind(struct drm_gem_object *obj) -{ - struct drm_device *dev = obj->dev; - struct drm_i915_gem_object *obj_priv = obj->driver_private; - int ret = 0; - -#if WATCH_BUF - DRM_INFO("%s:%d %p\n", __func__, __LINE__, obj); - DRM_INFO("gtt_space %p\n", obj_priv->gtt_space); -#endif - if (obj_priv->gtt_space == NULL) - return 0; - - if (obj_priv->pin_count != 0) { - DRM_ERROR("Attempting to unbind pinned buffer\n"); - return -EINVAL; - } - - /* Wait for any rendering to complete - */ - ret = i915_gem_object_wait_rendering(obj); - if (ret) { - DRM_ERROR("wait_rendering failed: %d\n", ret); - return ret; - } - - /* Move the object to the CPU domain to ensure that - * any possible CPU writes while it's not in the GTT - * are flushed when we go to remap it. This will - * also ensure that all pending GPU writes are finished - * before we unbind. - */ - ret = i915_gem_object_set_domain(obj, I915_GEM_DOMAIN_CPU, - I915_GEM_DOMAIN_CPU); - if (ret) { - DRM_ERROR("set_domain failed: %d\n", ret); - return ret; - } - - if (obj_priv->agp_mem != NULL) { - drm_unbind_agp(obj_priv->agp_mem); - drm_free_agp(obj_priv->agp_mem, obj->size / PAGE_SIZE); - obj_priv->agp_mem = NULL; - } - - BUG_ON(obj_priv->active); - - i915_gem_object_free_page_list(obj); - - if (obj_priv->gtt_space) { - atomic_dec(&dev->gtt_count); - atomic_sub(obj->size, &dev->gtt_memory); - - drm_mm_put_block(obj_priv->gtt_space); - obj_priv->gtt_space = NULL; - } - - /* Remove ourselves from the LRU list if present. */ - if (!list_empty(&obj_priv->list)) - list_del_init(&obj_priv->list); - - return 0; -} - -static int -i915_gem_evict_something(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_gem_object *obj; - struct drm_i915_gem_object *obj_priv; - int ret = 0; - - for (;;) { - /* If there's an inactive buffer available now, grab it - * and be done. - */ - if (!list_empty(&dev_priv->mm.inactive_list)) { - obj_priv = list_first_entry(&dev_priv->mm.inactive_list, - struct drm_i915_gem_object, - list); - obj = obj_priv->obj; - BUG_ON(obj_priv->pin_count != 0); -#if WATCH_LRU - DRM_INFO("%s: evicting %p\n", __func__, obj); -#endif - BUG_ON(obj_priv->active); - - /* Wait on the rendering and unbind the buffer. */ - ret = i915_gem_object_unbind(obj); - break; - } - - /* If we didn't get anything, but the ring is still processing - * things, wait for one of those things to finish and hopefully - * leave us a buffer to evict. - */ - if (!list_empty(&dev_priv->mm.request_list)) { - struct drm_i915_gem_request *request; - - request = list_first_entry(&dev_priv->mm.request_list, - struct drm_i915_gem_request, - list); - - ret = i915_wait_request(dev, request->seqno); - if (ret) - break; - - /* if waiting caused an object to become inactive, - * then loop around and wait for it. Otherwise, we - * assume that waiting freed and unbound something, - * so there should now be some space in the GTT - */ - if (!list_empty(&dev_priv->mm.inactive_list)) - continue; - break; - } - - /* If we didn't have anything on the request list but there - * are buffers awaiting a flush, emit one and try again. - * When we wait on it, those buffers waiting for that flush - * will get moved to inactive. - */ - if (!list_empty(&dev_priv->mm.flushing_list)) { - obj_priv = list_first_entry(&dev_priv->mm.flushing_list, - struct drm_i915_gem_object, - list); - obj = obj_priv->obj; - - i915_gem_flush(dev, - obj->write_domain, - obj->write_domain); - i915_add_request(dev, obj->write_domain); - - obj = NULL; - continue; - } - - DRM_ERROR("inactive empty %d request empty %d " - "flushing empty %d\n", - list_empty(&dev_priv->mm.inactive_list), - list_empty(&dev_priv->mm.request_list), - list_empty(&dev_priv->mm.flushing_list)); - /* If we didn't do any of the above, there's nothing to be done - * and we just can't fit it in. - */ - return -ENOMEM; - } - return ret; -} - -static int -i915_gem_object_get_page_list(struct drm_gem_object *obj) -{ - struct drm_i915_gem_object *obj_priv = obj->driver_private; - int page_count, i; - struct address_space *mapping; - struct inode *inode; - struct page *page; - int ret; - - if (obj_priv->page_list) - return 0; - - /* Get the list of pages out of our struct file. They'll be pinned - * at this point until we release them. - */ - page_count = obj->size / PAGE_SIZE; - BUG_ON(obj_priv->page_list != NULL); - obj_priv->page_list = drm_calloc(page_count, sizeof(struct page *), - DRM_MEM_DRIVER); - if (obj_priv->page_list == NULL) { - DRM_ERROR("Faled to allocate page list\n"); - return -ENOMEM; - } - - inode = obj->filp->f_path.dentry->d_inode; - mapping = inode->i_mapping; - for (i = 0; i < page_count; i++) { - page = read_mapping_page(mapping, i, NULL); - if (IS_ERR(page)) { - ret = PTR_ERR(page); - DRM_ERROR("read_mapping_page failed: %d\n", ret); - i915_gem_object_free_page_list(obj); - return ret; - } - obj_priv->page_list[i] = page; - } - return 0; -} - -/** - * Finds free space in the GTT aperture and binds the object there. - */ -static int -i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) -{ - struct drm_device *dev = obj->dev; - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv = obj->driver_private; - struct drm_mm_node *free_space; - int page_count, ret; - - if (alignment == 0) - alignment = PAGE_SIZE; - if (alignment & (PAGE_SIZE - 1)) { - DRM_ERROR("Invalid object alignment requested %u\n", alignment); - return -EINVAL; - } - - search_free: - free_space = drm_mm_search_free(&dev_priv->mm.gtt_space, - obj->size, alignment, 0); - if (free_space != NULL) { - obj_priv->gtt_space = drm_mm_get_block(free_space, obj->size, - alignment); - if (obj_priv->gtt_space != NULL) { - obj_priv->gtt_space->private = obj; - obj_priv->gtt_offset = obj_priv->gtt_space->start; - } - } - if (obj_priv->gtt_space == NULL) { - /* If the gtt is empty and we're still having trouble - * fitting our object in, we're out of memory. - */ -#if WATCH_LRU - DRM_INFO("%s: GTT full, evicting something\n", __func__); -#endif - if (list_empty(&dev_priv->mm.inactive_list) && - list_empty(&dev_priv->mm.flushing_list) && - list_empty(&dev_priv->mm.active_list)) { - DRM_ERROR("GTT full, but LRU list empty\n"); - return -ENOMEM; - } - - ret = i915_gem_evict_something(dev); - if (ret != 0) { - DRM_ERROR("Failed to evict a buffer %d\n", ret); - return ret; - } - goto search_free; - } - -#if WATCH_BUF - DRM_INFO("Binding object of size %d at 0x%08x\n", - obj->size, obj_priv->gtt_offset); -#endif - ret = i915_gem_object_get_page_list(obj); - if (ret) { - drm_mm_put_block(obj_priv->gtt_space); - obj_priv->gtt_space = NULL; - return ret; - } - - page_count = obj->size / PAGE_SIZE; - /* Create an AGP memory structure pointing at our pages, and bind it - * into the GTT. - */ - obj_priv->agp_mem = drm_agp_bind_pages(dev, - obj_priv->page_list, - page_count, - obj_priv->gtt_offset, - obj_priv->agp_type); - if (obj_priv->agp_mem == NULL) { - i915_gem_object_free_page_list(obj); - drm_mm_put_block(obj_priv->gtt_space); - obj_priv->gtt_space = NULL; - return -ENOMEM; - } - atomic_inc(&dev->gtt_count); - atomic_add(obj->size, &dev->gtt_memory); - - /* Assert that the object is not currently in any GPU domain. As it - * wasn't in the GTT, there shouldn't be any way it could have been in - * a GPU cache - */ - BUG_ON(obj->read_domains & ~(I915_GEM_DOMAIN_CPU|I915_GEM_DOMAIN_GTT)); - BUG_ON(obj->write_domain & ~(I915_GEM_DOMAIN_CPU|I915_GEM_DOMAIN_GTT)); - - return 0; -} - -void -i915_gem_clflush_object(struct drm_gem_object *obj) -{ - struct drm_i915_gem_object *obj_priv = obj->driver_private; - - /* If we don't have a page list set up, then we're not pinned - * to GPU, and we can ignore the cache flush because it'll happen - * again at bind time. - */ - if (obj_priv->page_list == NULL) - return; - - drm_clflush_pages(obj_priv->page_list, obj->size / PAGE_SIZE); -} - -/* - * Set the next domain for the specified object. This - * may not actually perform the necessary flushing/invaliding though, - * as that may want to be batched with other set_domain operations - * - * This is (we hope) the only really tricky part of gem. The goal - * is fairly simple -- track which caches hold bits of the object - * and make sure they remain coherent. A few concrete examples may - * help to explain how it works. For shorthand, we use the notation - * (read_domains, write_domain), e.g. (CPU, CPU) to indicate the - * a pair of read and write domain masks. - * - * Case 1: the batch buffer - * - * 1. Allocated - * 2. Written by CPU - * 3. Mapped to GTT - * 4. Read by GPU - * 5. Unmapped from GTT - * 6. Freed - * - * Let's take these a step at a time - * - * 1. Allocated - * Pages allocated from the kernel may still have - * cache contents, so we set them to (CPU, CPU) always. - * 2. Written by CPU (using pwrite) - * The pwrite function calls set_domain (CPU, CPU) and - * this function does nothing (as nothing changes) - * 3. Mapped by GTT - * This function asserts that the object is not - * currently in any GPU-based read or write domains - * 4. Read by GPU - * i915_gem_execbuffer calls set_domain (COMMAND, 0). - * As write_domain is zero, this function adds in the - * current read domains (CPU+COMMAND, 0). - * flush_domains is set to CPU. - * invalidate_domains is set to COMMAND - * clflush is run to get data out of the CPU caches - * then i915_dev_set_domain calls i915_gem_flush to - * emit an MI_FLUSH and drm_agp_chipset_flush - * 5. Unmapped from GTT - * i915_gem_object_unbind calls set_domain (CPU, CPU) - * flush_domains and invalidate_domains end up both zero - * so no flushing/invalidating happens - * 6. Freed - * yay, done - * - * Case 2: The shared render buffer - * - * 1. Allocated - * 2. Mapped to GTT - * 3. Read/written by GPU - * 4. set_domain to (CPU,CPU) - * 5. Read/written by CPU - * 6. Read/written by GPU - * - * 1. Allocated - * Same as last example, (CPU, CPU) - * 2. Mapped to GTT - * Nothing changes (assertions find that it is not in the GPU) - * 3. Read/written by GPU - * execbuffer calls set_domain (RENDER, RENDER) - * flush_domains gets CPU - * invalidate_domains gets GPU - * clflush (obj) - * MI_FLUSH and drm_agp_chipset_flush - * 4. set_domain (CPU, CPU) - * flush_domains gets GPU - * invalidate_domains gets CPU - * wait_rendering (obj) to make sure all drawing is complete. - * This will include an MI_FLUSH to get the data from GPU - * to memory - * clflush (obj) to invalidate the CPU cache - * Another MI_FLUSH in i915_gem_flush (eliminate this somehow?) - * 5. Read/written by CPU - * cache lines are loaded and dirtied - * 6. Read written by GPU - * Same as last GPU access - * - * Case 3: The constant buffer - * - * 1. Allocated - * 2. Written by CPU - * 3. Read by GPU - * 4. Updated (written) by CPU again - * 5. Read by GPU - * - * 1. Allocated - * (CPU, CPU) - * 2. Written by CPU - * (CPU, CPU) - * 3. Read by GPU - * (CPU+RENDER, 0) - * flush_domains = CPU - * invalidate_domains = RENDER - * clflush (obj) - * MI_FLUSH - * drm_agp_chipset_flush - * 4. Updated (written) by CPU again - * (CPU, CPU) - * flush_domains = 0 (no previous write domain) - * invalidate_domains = 0 (no new read domains) - * 5. Read by GPU - * (CPU+RENDER, 0) - * flush_domains = CPU - * invalidate_domains = RENDER - * clflush (obj) - * MI_FLUSH - * drm_agp_chipset_flush - */ -static int -i915_gem_object_set_domain(struct drm_gem_object *obj, - uint32_t read_domains, - uint32_t write_domain) -{ - struct drm_device *dev = obj->dev; - struct drm_i915_gem_object *obj_priv = obj->driver_private; - uint32_t invalidate_domains = 0; - uint32_t flush_domains = 0; - int ret; - -#if WATCH_BUF - DRM_INFO("%s: object %p read %08x -> %08x write %08x -> %08x\n", - __func__, obj, - obj->read_domains, read_domains, - obj->write_domain, write_domain); -#endif - /* - * If the object isn't moving to a new write domain, - * let the object stay in multiple read domains - */ - if (write_domain == 0) - read_domains |= obj->read_domains; - else - obj_priv->dirty = 1; - - /* - * Flush the current write domain if - * the new read domains don't match. Invalidate - * any read domains which differ from the old - * write domain - */ - if (obj->write_domain && obj->write_domain != read_domains) { - flush_domains |= obj->write_domain; - invalidate_domains |= read_domains & ~obj->write_domain; - } - /* - * Invalidate any read caches which may have - * stale data. That is, any new read domains. - */ - invalidate_domains |= read_domains & ~obj->read_domains; - if ((flush_domains | invalidate_domains) & I915_GEM_DOMAIN_CPU) { -#if WATCH_BUF - DRM_INFO("%s: CPU domain flush %08x invalidate %08x\n", - __func__, flush_domains, invalidate_domains); -#endif - /* - * If we're invaliding the CPU cache and flushing a GPU cache, - * then pause for rendering so that the GPU caches will be - * flushed before the cpu cache is invalidated - */ - if ((invalidate_domains & I915_GEM_DOMAIN_CPU) && - (flush_domains & ~(I915_GEM_DOMAIN_CPU | - I915_GEM_DOMAIN_GTT))) { - ret = i915_gem_object_wait_rendering(obj); - if (ret) - return ret; - } - i915_gem_clflush_object(obj); - } - - if ((write_domain | flush_domains) != 0) - obj->write_domain = write_domain; - - /* If we're invalidating the CPU domain, clear the per-page CPU - * domain list as well. - */ - if (obj_priv->page_cpu_valid != NULL && - (write_domain != 0 || - read_domains & I915_GEM_DOMAIN_CPU)) { - drm_free(obj_priv->page_cpu_valid, obj->size / PAGE_SIZE, - DRM_MEM_DRIVER); - obj_priv->page_cpu_valid = NULL; - } - obj->read_domains = read_domains; - - dev->invalidate_domains |= invalidate_domains; - dev->flush_domains |= flush_domains; -#if WATCH_BUF - DRM_INFO("%s: read %08x write %08x invalidate %08x flush %08x\n", - __func__, - obj->read_domains, obj->write_domain, - dev->invalidate_domains, dev->flush_domains); -#endif - return 0; -} - -/** - * Set the read/write domain on a range of the object. - * - * Currently only implemented for CPU reads, otherwise drops to normal - * i915_gem_object_set_domain(). - */ -static int -i915_gem_object_set_domain_range(struct drm_gem_object *obj, - uint64_t offset, - uint64_t size, - uint32_t read_domains, - uint32_t write_domain) -{ - struct drm_i915_gem_object *obj_priv = obj->driver_private; - int ret, i; - - if (obj->read_domains & I915_GEM_DOMAIN_CPU) - return 0; - - if (read_domains != I915_GEM_DOMAIN_CPU || - write_domain != 0) - return i915_gem_object_set_domain(obj, - read_domains, write_domain); - - /* Wait on any GPU rendering to the object to be flushed. */ - if (obj->write_domain & ~(I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT)) { - ret = i915_gem_object_wait_rendering(obj); - if (ret) - return ret; - } - - if (obj_priv->page_cpu_valid == NULL) { - obj_priv->page_cpu_valid = drm_calloc(1, obj->size / PAGE_SIZE, - DRM_MEM_DRIVER); - } - - /* Flush the cache on any pages that are still invalid from the CPU's - * perspective. - */ - for (i = offset / PAGE_SIZE; i <= (offset + size - 1) / PAGE_SIZE; i++) { - if (obj_priv->page_cpu_valid[i]) - continue; - - drm_clflush_pages(obj_priv->page_list + i, 1); - - obj_priv->page_cpu_valid[i] = 1; - } - - return 0; -} - -/** - * Once all of the objects have been set in the proper domain, - * perform the necessary flush and invalidate operations. - * - * Returns the write domains flushed, for use in flush tracking. - */ -static uint32_t -i915_gem_dev_set_domain(struct drm_device *dev) -{ - uint32_t flush_domains = dev->flush_domains; - - /* - * Now that all the buffers are synced to the proper domains, - * flush and invalidate the collected domains - */ - if (dev->invalidate_domains | dev->flush_domains) { -#if WATCH_EXEC - DRM_INFO("%s: invalidate_domains %08x flush_domains %08x\n", - __func__, - dev->invalidate_domains, - dev->flush_domains); -#endif - i915_gem_flush(dev, - dev->invalidate_domains, - dev->flush_domains); - dev->invalidate_domains = 0; - dev->flush_domains = 0; - } - - return flush_domains; -} - -/** - * Pin an object to the GTT and evaluate the relocations landing in it. - */ -static int -i915_gem_object_pin_and_relocate(struct drm_gem_object *obj, - struct drm_file *file_priv, - struct drm_i915_gem_exec_object *entry) -{ - struct drm_device *dev = obj->dev; - struct drm_i915_gem_relocation_entry reloc; - struct drm_i915_gem_relocation_entry __user *relocs; - struct drm_i915_gem_object *obj_priv = obj->driver_private; - int i, ret; - uint32_t last_reloc_offset = -1; - void __iomem *reloc_page = NULL; - - /* Choose the GTT offset for our buffer and put it there. */ - ret = i915_gem_object_pin(obj, (uint32_t) entry->alignment); - if (ret) - return ret; - - entry->offset = obj_priv->gtt_offset; - - relocs = (struct drm_i915_gem_relocation_entry __user *) - (uintptr_t) entry->relocs_ptr; - /* Apply the relocations, using the GTT aperture to avoid cache - * flushing requirements. - */ - for (i = 0; i < entry->relocation_count; i++) { - struct drm_gem_object *target_obj; - struct drm_i915_gem_object *target_obj_priv; - uint32_t reloc_val, reloc_offset; - uint32_t __iomem *reloc_entry; - - ret = copy_from_user(&reloc, relocs + i, sizeof(reloc)); - if (ret != 0) { - i915_gem_object_unpin(obj); - return ret; - } - - target_obj = drm_gem_object_lookup(obj->dev, file_priv, - reloc.target_handle); - if (target_obj == NULL) { - i915_gem_object_unpin(obj); - return -EBADF; - } - target_obj_priv = target_obj->driver_private; - - /* The target buffer should have appeared before us in the - * exec_object list, so it should have a GTT space bound by now. - */ - if (target_obj_priv->gtt_space == NULL) { - DRM_ERROR("No GTT space found for object %d\n", - reloc.target_handle); - drm_gem_object_unreference(target_obj); - i915_gem_object_unpin(obj); - return -EINVAL; - } - - if (reloc.offset > obj->size - 4) { - DRM_ERROR("Relocation beyond object bounds: " - "obj %p target %d offset %d size %d.\n", - obj, reloc.target_handle, - (int) reloc.offset, (int) obj->size); - drm_gem_object_unreference(target_obj); - i915_gem_object_unpin(obj); - return -EINVAL; - } - if (reloc.offset & 3) { - DRM_ERROR("Relocation not 4-byte aligned: " - "obj %p target %d offset %d.\n", - obj, reloc.target_handle, - (int) reloc.offset); - drm_gem_object_unreference(target_obj); - i915_gem_object_unpin(obj); - return -EINVAL; - } - - if (reloc.write_domain && target_obj->pending_write_domain && - reloc.write_domain != target_obj->pending_write_domain) { - DRM_ERROR("Write domain conflict: " - "obj %p target %d offset %d " - "new %08x old %08x\n", - obj, reloc.target_handle, - (int) reloc.offset, - reloc.write_domain, - target_obj->pending_write_domain); - drm_gem_object_unreference(target_obj); - i915_gem_object_unpin(obj); - return -EINVAL; - } - -#if WATCH_RELOC - DRM_INFO("%s: obj %p offset %08x target %d " - "read %08x write %08x gtt %08x " - "presumed %08x delta %08x\n", - __func__, - obj, - (int) reloc.offset, - (int) reloc.target_handle, - (int) reloc.read_domains, - (int) reloc.write_domain, - (int) target_obj_priv->gtt_offset, - (int) reloc.presumed_offset, - reloc.delta); -#endif - - target_obj->pending_read_domains |= reloc.read_domains; - target_obj->pending_write_domain |= reloc.write_domain; - - /* If the relocation already has the right value in it, no - * more work needs to be done. - */ - if (target_obj_priv->gtt_offset == reloc.presumed_offset) { - drm_gem_object_unreference(target_obj); - continue; - } - - /* Now that we're going to actually write some data in, - * make sure that any rendering using this buffer's contents - * is completed. - */ - i915_gem_object_wait_rendering(obj); - - /* As we're writing through the gtt, flush - * any CPU writes before we write the relocations - */ - if (obj->write_domain & I915_GEM_DOMAIN_CPU) { - i915_gem_clflush_object(obj); - drm_agp_chipset_flush(dev); - obj->write_domain = 0; - } - - /* Map the page containing the relocation we're going to - * perform. - */ - reloc_offset = obj_priv->gtt_offset + reloc.offset; - if (reloc_page == NULL || - (last_reloc_offset & ~(PAGE_SIZE - 1)) != - (reloc_offset & ~(PAGE_SIZE - 1))) { - if (reloc_page != NULL) - iounmap(reloc_page); - - reloc_page = ioremap_wc(dev->agp->base + - (reloc_offset & - ~(PAGE_SIZE - 1)), - PAGE_SIZE); - last_reloc_offset = reloc_offset; - if (reloc_page == NULL) { - drm_gem_object_unreference(target_obj); - i915_gem_object_unpin(obj); - return -ENOMEM; - } - } - - reloc_entry = (uint32_t __iomem *)(reloc_page + - (reloc_offset & (PAGE_SIZE - 1))); - reloc_val = target_obj_priv->gtt_offset + reloc.delta; - -#if WATCH_BUF - DRM_INFO("Applied relocation: %p@0x%08x %08x -> %08x\n", - obj, (unsigned int) reloc.offset, - readl(reloc_entry), reloc_val); -#endif - writel(reloc_val, reloc_entry); - - /* Write the updated presumed offset for this entry back out - * to the user. - */ - reloc.presumed_offset = target_obj_priv->gtt_offset; - ret = copy_to_user(relocs + i, &reloc, sizeof(reloc)); - if (ret != 0) { - drm_gem_object_unreference(target_obj); - i915_gem_object_unpin(obj); - return ret; - } - - drm_gem_object_unreference(target_obj); - } - - if (reloc_page != NULL) - iounmap(reloc_page); - -#if WATCH_BUF - if (0) - i915_gem_dump_object(obj, 128, __func__, ~0); -#endif - return 0; -} - -/** Dispatch a batchbuffer to the ring - */ -static int -i915_dispatch_gem_execbuffer(struct drm_device *dev, - struct drm_i915_gem_execbuffer *exec, - uint64_t exec_offset) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_clip_rect __user *boxes = (struct drm_clip_rect __user *) - (uintptr_t) exec->cliprects_ptr; - int nbox = exec->num_cliprects; - int i = 0, count; - uint32_t exec_start, exec_len; - RING_LOCALS; - - exec_start = (uint32_t) exec_offset + exec->batch_start_offset; - exec_len = (uint32_t) exec->batch_len; - - if ((exec_start | exec_len) & 0x7) { - DRM_ERROR("alignment\n"); - return -EINVAL; - } - - if (!exec_start) - return -EINVAL; - - count = nbox ? nbox : 1; - - for (i = 0; i < count; i++) { - if (i < nbox) { - int ret = i915_emit_box(dev, boxes, i, - exec->DR1, exec->DR4); - if (ret) - return ret; - } - - if (IS_I830(dev) || IS_845G(dev)) { - BEGIN_LP_RING(4); - OUT_RING(MI_BATCH_BUFFER); - OUT_RING(exec_start | MI_BATCH_NON_SECURE); - OUT_RING(exec_start + exec_len - 4); - OUT_RING(0); - ADVANCE_LP_RING(); - } else { - BEGIN_LP_RING(2); - if (IS_I965G(dev)) { - OUT_RING(MI_BATCH_BUFFER_START | - (2 << 6) | - MI_BATCH_NON_SECURE_I965); - OUT_RING(exec_start); - } else { - OUT_RING(MI_BATCH_BUFFER_START | - (2 << 6)); - OUT_RING(exec_start | MI_BATCH_NON_SECURE); - } - ADVANCE_LP_RING(); - } - } - - /* XXX breadcrumb */ - return 0; -} - -/* Throttle our rendering by waiting until the ring has completed our requests - * emitted over 20 msec ago. - * - * This should get us reasonable parallelism between CPU and GPU but also - * relatively low latency when blocking on a particular request to finish. - */ -static int -i915_gem_ring_throttle(struct drm_device *dev, struct drm_file *file_priv) -{ - struct drm_i915_file_private *i915_file_priv = file_priv->driver_priv; - int ret = 0; - uint32_t seqno; - - mutex_lock(&dev->struct_mutex); - seqno = i915_file_priv->mm.last_gem_throttle_seqno; - i915_file_priv->mm.last_gem_throttle_seqno = - i915_file_priv->mm.last_gem_seqno; - if (seqno) - ret = i915_wait_request(dev, seqno); - mutex_unlock(&dev->struct_mutex); - return ret; -} - -int -i915_gem_execbuffer(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_file_private *i915_file_priv = file_priv->driver_priv; - struct drm_i915_gem_execbuffer *args = data; - struct drm_i915_gem_exec_object *exec_list = NULL; - struct drm_gem_object **object_list = NULL; - struct drm_gem_object *batch_obj; - int ret, i, pinned = 0; - uint64_t exec_offset; - uint32_t seqno, flush_domains; - -#if WATCH_EXEC - DRM_INFO("buffers_ptr %d buffer_count %d len %08x\n", - (int) args->buffers_ptr, args->buffer_count, args->batch_len); -#endif - - if (args->buffer_count < 1) { - DRM_ERROR("execbuf with %d buffers\n", args->buffer_count); - return -EINVAL; - } - /* Copy in the exec list from userland */ - exec_list = drm_calloc(sizeof(*exec_list), args->buffer_count, - DRM_MEM_DRIVER); - object_list = drm_calloc(sizeof(*object_list), args->buffer_count, - DRM_MEM_DRIVER); - if (exec_list == NULL || object_list == NULL) { - DRM_ERROR("Failed to allocate exec or object list " - "for %d buffers\n", - args->buffer_count); - ret = -ENOMEM; - goto pre_mutex_err; - } - ret = copy_from_user(exec_list, - (struct drm_i915_relocation_entry __user *) - (uintptr_t) args->buffers_ptr, - sizeof(*exec_list) * args->buffer_count); - if (ret != 0) { - DRM_ERROR("copy %d exec entries failed %d\n", - args->buffer_count, ret); - goto pre_mutex_err; - } - - mutex_lock(&dev->struct_mutex); - - i915_verify_inactive(dev, __FILE__, __LINE__); - - if (dev_priv->mm.wedged) { - DRM_ERROR("Execbuf while wedged\n"); - mutex_unlock(&dev->struct_mutex); - return -EIO; - } - - if (dev_priv->mm.suspended) { - DRM_ERROR("Execbuf while VT-switched.\n"); - mutex_unlock(&dev->struct_mutex); - return -EBUSY; - } - - /* Zero the gloabl flush/invalidate flags. These - * will be modified as each object is bound to the - * gtt - */ - dev->invalidate_domains = 0; - dev->flush_domains = 0; - - /* Look up object handles and perform the relocations */ - for (i = 0; i < args->buffer_count; i++) { - object_list[i] = drm_gem_object_lookup(dev, file_priv, - exec_list[i].handle); - if (object_list[i] == NULL) { - DRM_ERROR("Invalid object handle %d at index %d\n", - exec_list[i].handle, i); - ret = -EBADF; - goto err; - } - - object_list[i]->pending_read_domains = 0; - object_list[i]->pending_write_domain = 0; - ret = i915_gem_object_pin_and_relocate(object_list[i], - file_priv, - &exec_list[i]); - if (ret) { - DRM_ERROR("object bind and relocate failed %d\n", ret); - goto err; - } - pinned = i + 1; - } - - /* Set the pending read domains for the batch buffer to COMMAND */ - batch_obj = object_list[args->buffer_count-1]; - batch_obj->pending_read_domains = I915_GEM_DOMAIN_COMMAND; - batch_obj->pending_write_domain = 0; - - i915_verify_inactive(dev, __FILE__, __LINE__); - - for (i = 0; i < args->buffer_count; i++) { - struct drm_gem_object *obj = object_list[i]; - struct drm_i915_gem_object *obj_priv = obj->driver_private; - - if (obj_priv->gtt_space == NULL) { - /* We evicted the buffer in the process of validating - * our set of buffers in. We could try to recover by - * kicking them everything out and trying again from - * the start. - */ - ret = -ENOMEM; - goto err; - } - - /* make sure all previous memory operations have passed */ - ret = i915_gem_object_set_domain(obj, - obj->pending_read_domains, - obj->pending_write_domain); - if (ret) - goto err; - } - - i915_verify_inactive(dev, __FILE__, __LINE__); - - /* Flush/invalidate caches and chipset buffer */ - flush_domains = i915_gem_dev_set_domain(dev); - - i915_verify_inactive(dev, __FILE__, __LINE__); - -#if WATCH_COHERENCY - for (i = 0; i < args->buffer_count; i++) { - i915_gem_object_check_coherency(object_list[i], - exec_list[i].handle); - } -#endif - - exec_offset = exec_list[args->buffer_count - 1].offset; - -#if WATCH_EXEC - i915_gem_dump_object(object_list[args->buffer_count - 1], - args->batch_len, - __func__, - ~0); -#endif - - (void)i915_add_request(dev, flush_domains); - - /* Exec the batchbuffer */ - ret = i915_dispatch_gem_execbuffer(dev, args, exec_offset); - if (ret) { - DRM_ERROR("dispatch failed %d\n", ret); - goto err; - } - - /* - * Ensure that the commands in the batch buffer are - * finished before the interrupt fires - */ - flush_domains = i915_retire_commands(dev); - - i915_verify_inactive(dev, __FILE__, __LINE__); - - /* - * Get a seqno representing the execution of the current buffer, - * which we can wait on. We would like to mitigate these interrupts, - * likely by only creating seqnos occasionally (so that we have - * *some* interrupts representing completion of buffers that we can - * wait on when trying to clear up gtt space). - */ - seqno = i915_add_request(dev, flush_domains); - BUG_ON(seqno == 0); - i915_file_priv->mm.last_gem_seqno = seqno; - for (i = 0; i < args->buffer_count; i++) { - struct drm_gem_object *obj = object_list[i]; - struct drm_i915_gem_object *obj_priv = obj->driver_private; - - i915_gem_object_move_to_active(obj); - obj_priv->last_rendering_seqno = seqno; -#if WATCH_LRU - DRM_INFO("%s: move to exec list %p\n", __func__, obj); -#endif - } -#if WATCH_LRU - i915_dump_lru(dev, __func__); -#endif - - i915_verify_inactive(dev, __FILE__, __LINE__); - - /* Copy the new buffer offsets back to the user's exec list. */ - ret = copy_to_user((struct drm_i915_relocation_entry __user *) - (uintptr_t) args->buffers_ptr, - exec_list, - sizeof(*exec_list) * args->buffer_count); - if (ret) - DRM_ERROR("failed to copy %d exec entries " - "back to user (%d)\n", - args->buffer_count, ret); -err: - if (object_list != NULL) { - for (i = 0; i < pinned; i++) - i915_gem_object_unpin(object_list[i]); - - for (i = 0; i < args->buffer_count; i++) - drm_gem_object_unreference(object_list[i]); - } - mutex_unlock(&dev->struct_mutex); - -pre_mutex_err: - drm_free(object_list, sizeof(*object_list) * args->buffer_count, - DRM_MEM_DRIVER); - drm_free(exec_list, sizeof(*exec_list) * args->buffer_count, - DRM_MEM_DRIVER); - - return ret; -} - -int -i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment) -{ - struct drm_device *dev = obj->dev; - struct drm_i915_gem_object *obj_priv = obj->driver_private; - int ret; - - i915_verify_inactive(dev, __FILE__, __LINE__); - if (obj_priv->gtt_space == NULL) { - ret = i915_gem_object_bind_to_gtt(obj, alignment); - if (ret != 0) { - DRM_ERROR("Failure to bind: %d", ret); - return ret; - } - } - obj_priv->pin_count++; - - /* If the object is not active and not pending a flush, - * remove it from the inactive list - */ - if (obj_priv->pin_count == 1) { - atomic_inc(&dev->pin_count); - atomic_add(obj->size, &dev->pin_memory); - if (!obj_priv->active && - (obj->write_domain & ~(I915_GEM_DOMAIN_CPU | - I915_GEM_DOMAIN_GTT)) == 0 && - !list_empty(&obj_priv->list)) - list_del_init(&obj_priv->list); - } - i915_verify_inactive(dev, __FILE__, __LINE__); - - return 0; -} - -void -i915_gem_object_unpin(struct drm_gem_object *obj) -{ - struct drm_device *dev = obj->dev; - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv = obj->driver_private; - - i915_verify_inactive(dev, __FILE__, __LINE__); - obj_priv->pin_count--; - BUG_ON(obj_priv->pin_count < 0); - BUG_ON(obj_priv->gtt_space == NULL); - - /* If the object is no longer pinned, and is - * neither active nor being flushed, then stick it on - * the inactive list - */ - if (obj_priv->pin_count == 0) { - if (!obj_priv->active && - (obj->write_domain & ~(I915_GEM_DOMAIN_CPU | - I915_GEM_DOMAIN_GTT)) == 0) - list_move_tail(&obj_priv->list, - &dev_priv->mm.inactive_list); - atomic_dec(&dev->pin_count); - atomic_sub(obj->size, &dev->pin_memory); - } - i915_verify_inactive(dev, __FILE__, __LINE__); -} - -int -i915_gem_pin_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_i915_gem_pin *args = data; - struct drm_gem_object *obj; - struct drm_i915_gem_object *obj_priv; - int ret; - - mutex_lock(&dev->struct_mutex); - - obj = drm_gem_object_lookup(dev, file_priv, args->handle); - if (obj == NULL) { - DRM_ERROR("Bad handle in i915_gem_pin_ioctl(): %d\n", - args->handle); - mutex_unlock(&dev->struct_mutex); - return -EBADF; - } - obj_priv = obj->driver_private; - - ret = i915_gem_object_pin(obj, args->alignment); - if (ret != 0) { - drm_gem_object_unreference(obj); - mutex_unlock(&dev->struct_mutex); - return ret; - } - - /* XXX - flush the CPU caches for pinned objects - * as the X server doesn't manage domains yet - */ - if (obj->write_domain & I915_GEM_DOMAIN_CPU) { - i915_gem_clflush_object(obj); - drm_agp_chipset_flush(dev); - obj->write_domain = 0; - } - args->offset = obj_priv->gtt_offset; - drm_gem_object_unreference(obj); - mutex_unlock(&dev->struct_mutex); - - return 0; -} - -int -i915_gem_unpin_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_i915_gem_pin *args = data; - struct drm_gem_object *obj; - - mutex_lock(&dev->struct_mutex); - - obj = drm_gem_object_lookup(dev, file_priv, args->handle); - if (obj == NULL) { - DRM_ERROR("Bad handle in i915_gem_unpin_ioctl(): %d\n", - args->handle); - mutex_unlock(&dev->struct_mutex); - return -EBADF; - } - - i915_gem_object_unpin(obj); - - drm_gem_object_unreference(obj); - mutex_unlock(&dev->struct_mutex); - return 0; -} - -int -i915_gem_busy_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_i915_gem_busy *args = data; - struct drm_gem_object *obj; - struct drm_i915_gem_object *obj_priv; - - mutex_lock(&dev->struct_mutex); - obj = drm_gem_object_lookup(dev, file_priv, args->handle); - if (obj == NULL) { - DRM_ERROR("Bad handle in i915_gem_busy_ioctl(): %d\n", - args->handle); - mutex_unlock(&dev->struct_mutex); - return -EBADF; - } - - obj_priv = obj->driver_private; - args->busy = obj_priv->active; - - drm_gem_object_unreference(obj); - mutex_unlock(&dev->struct_mutex); - return 0; -} - -int -i915_gem_throttle_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - return i915_gem_ring_throttle(dev, file_priv); -} - -int i915_gem_init_object(struct drm_gem_object *obj) -{ - struct drm_i915_gem_object *obj_priv; - - obj_priv = drm_calloc(1, sizeof(*obj_priv), DRM_MEM_DRIVER); - if (obj_priv == NULL) - return -ENOMEM; - - /* - * We've just allocated pages from the kernel, - * so they've just been written by the CPU with - * zeros. They'll need to be clflushed before we - * use them with the GPU. - */ - obj->write_domain = I915_GEM_DOMAIN_CPU; - obj->read_domains = I915_GEM_DOMAIN_CPU; - - obj_priv->agp_type = AGP_USER_MEMORY; - - obj->driver_private = obj_priv; - obj_priv->obj = obj; - INIT_LIST_HEAD(&obj_priv->list); - return 0; -} - -void i915_gem_free_object(struct drm_gem_object *obj) -{ - struct drm_i915_gem_object *obj_priv = obj->driver_private; - - while (obj_priv->pin_count > 0) - i915_gem_object_unpin(obj); - - i915_gem_object_unbind(obj); - - drm_free(obj_priv->page_cpu_valid, 1, DRM_MEM_DRIVER); - drm_free(obj->driver_private, 1, DRM_MEM_DRIVER); -} - -static int -i915_gem_set_domain(struct drm_gem_object *obj, - struct drm_file *file_priv, - uint32_t read_domains, - uint32_t write_domain) -{ - struct drm_device *dev = obj->dev; - int ret; - uint32_t flush_domains; - - BUG_ON(!mutex_is_locked(&dev->struct_mutex)); - - ret = i915_gem_object_set_domain(obj, read_domains, write_domain); - if (ret) - return ret; - flush_domains = i915_gem_dev_set_domain(obj->dev); - - if (flush_domains & ~(I915_GEM_DOMAIN_CPU|I915_GEM_DOMAIN_GTT)) - (void) i915_add_request(dev, flush_domains); - - return 0; -} - -/** Unbinds all objects that are on the given buffer list. */ -static int -i915_gem_evict_from_list(struct drm_device *dev, struct list_head *head) -{ - struct drm_gem_object *obj; - struct drm_i915_gem_object *obj_priv; - int ret; - - while (!list_empty(head)) { - obj_priv = list_first_entry(head, - struct drm_i915_gem_object, - list); - obj = obj_priv->obj; - - if (obj_priv->pin_count != 0) { - DRM_ERROR("Pinned object in unbind list\n"); - mutex_unlock(&dev->struct_mutex); - return -EINVAL; - } - - ret = i915_gem_object_unbind(obj); - if (ret != 0) { - DRM_ERROR("Error unbinding object in LeaveVT: %d\n", - ret); - mutex_unlock(&dev->struct_mutex); - return ret; - } - } - - - return 0; -} - -static int -i915_gem_idle(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - uint32_t seqno, cur_seqno, last_seqno; - int stuck, ret; - - mutex_lock(&dev->struct_mutex); - - if (dev_priv->mm.suspended || dev_priv->ring.ring_obj == NULL) { - mutex_unlock(&dev->struct_mutex); - return 0; - } - - /* Hack! Don't let anybody do execbuf while we don't control the chip. - * We need to replace this with a semaphore, or something. - */ - dev_priv->mm.suspended = 1; - - /* Cancel the retire work handler, wait for it to finish if running - */ - mutex_unlock(&dev->struct_mutex); - cancel_delayed_work_sync(&dev_priv->mm.retire_work); - mutex_lock(&dev->struct_mutex); - - i915_kernel_lost_context(dev); - - /* Flush the GPU along with all non-CPU write domains - */ - i915_gem_flush(dev, ~(I915_GEM_DOMAIN_CPU|I915_GEM_DOMAIN_GTT), - ~(I915_GEM_DOMAIN_CPU|I915_GEM_DOMAIN_GTT)); - seqno = i915_add_request(dev, ~(I915_GEM_DOMAIN_CPU | - I915_GEM_DOMAIN_GTT)); - - if (seqno == 0) { - mutex_unlock(&dev->struct_mutex); - return -ENOMEM; - } - - dev_priv->mm.waiting_gem_seqno = seqno; - last_seqno = 0; - stuck = 0; - for (;;) { - cur_seqno = i915_get_gem_seqno(dev); - if (i915_seqno_passed(cur_seqno, seqno)) - break; - if (last_seqno == cur_seqno) { - if (stuck++ > 100) { - DRM_ERROR("hardware wedged\n"); - dev_priv->mm.wedged = 1; - DRM_WAKEUP(&dev_priv->irq_queue); - break; - } - } - msleep(10); - last_seqno = cur_seqno; - } - dev_priv->mm.waiting_gem_seqno = 0; - - i915_gem_retire_requests(dev); - - /* Active and flushing should now be empty as we've - * waited for a sequence higher than any pending execbuffer - */ - BUG_ON(!list_empty(&dev_priv->mm.active_list)); - BUG_ON(!list_empty(&dev_priv->mm.flushing_list)); - - /* Request should now be empty as we've also waited - * for the last request in the list - */ - BUG_ON(!list_empty(&dev_priv->mm.request_list)); - - /* Move all buffers out of the GTT. */ - ret = i915_gem_evict_from_list(dev, &dev_priv->mm.inactive_list); - if (ret) { - mutex_unlock(&dev->struct_mutex); - return ret; - } - - BUG_ON(!list_empty(&dev_priv->mm.active_list)); - BUG_ON(!list_empty(&dev_priv->mm.flushing_list)); - BUG_ON(!list_empty(&dev_priv->mm.inactive_list)); - BUG_ON(!list_empty(&dev_priv->mm.request_list)); - - i915_gem_cleanup_ringbuffer(dev); - mutex_unlock(&dev->struct_mutex); - - return 0; -} - -static int -i915_gem_init_hws(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_gem_object *obj; - struct drm_i915_gem_object *obj_priv; - int ret; - - /* If we need a physical address for the status page, it's already - * initialized at driver load time. - */ - if (!I915_NEED_GFX_HWS(dev)) - return 0; - - obj = drm_gem_object_alloc(dev, 4096); - if (obj == NULL) { - DRM_ERROR("Failed to allocate status page\n"); - return -ENOMEM; - } - obj_priv = obj->driver_private; - obj_priv->agp_type = AGP_USER_CACHED_MEMORY; - - ret = i915_gem_object_pin(obj, 4096); - if (ret != 0) { - drm_gem_object_unreference(obj); - return ret; - } - - dev_priv->status_gfx_addr = obj_priv->gtt_offset; - - dev_priv->hw_status_page = kmap(obj_priv->page_list[0]); - if (dev_priv->hw_status_page == NULL) { - DRM_ERROR("Failed to map status page.\n"); - memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map)); - drm_gem_object_unreference(obj); - return -EINVAL; - } - dev_priv->hws_obj = obj; - memset(dev_priv->hw_status_page, 0, PAGE_SIZE); - I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr); - I915_READ(HWS_PGA); /* posting read */ - DRM_DEBUG("hws offset: 0x%08x\n", dev_priv->status_gfx_addr); - - return 0; -} - -static int -i915_gem_init_ringbuffer(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_gem_object *obj; - struct drm_i915_gem_object *obj_priv; - int ret; - u32 head; - - ret = i915_gem_init_hws(dev); - if (ret != 0) - return ret; - - obj = drm_gem_object_alloc(dev, 128 * 1024); - if (obj == NULL) { - DRM_ERROR("Failed to allocate ringbuffer\n"); - return -ENOMEM; - } - obj_priv = obj->driver_private; - - ret = i915_gem_object_pin(obj, 4096); - if (ret != 0) { - drm_gem_object_unreference(obj); - return ret; - } - - /* Set up the kernel mapping for the ring. */ - dev_priv->ring.Size = obj->size; - dev_priv->ring.tail_mask = obj->size - 1; - - dev_priv->ring.map.offset = dev->agp->base + obj_priv->gtt_offset; - dev_priv->ring.map.size = obj->size; - dev_priv->ring.map.type = 0; - dev_priv->ring.map.flags = 0; - dev_priv->ring.map.mtrr = 0; - - drm_core_ioremap_wc(&dev_priv->ring.map, dev); - if (dev_priv->ring.map.handle == NULL) { - DRM_ERROR("Failed to map ringbuffer.\n"); - memset(&dev_priv->ring, 0, sizeof(dev_priv->ring)); - drm_gem_object_unreference(obj); - return -EINVAL; - } - dev_priv->ring.ring_obj = obj; - dev_priv->ring.virtual_start = dev_priv->ring.map.handle; - - /* Stop the ring if it's running. */ - I915_WRITE(PRB0_CTL, 0); - I915_WRITE(PRB0_TAIL, 0); - I915_WRITE(PRB0_HEAD, 0); - - /* Initialize the ring. */ - I915_WRITE(PRB0_START, obj_priv->gtt_offset); - head = I915_READ(PRB0_HEAD) & HEAD_ADDR; - - /* G45 ring initialization fails to reset head to zero */ - if (head != 0) { - DRM_ERROR("Ring head not reset to zero " - "ctl %08x head %08x tail %08x start %08x\n", - I915_READ(PRB0_CTL), - I915_READ(PRB0_HEAD), - I915_READ(PRB0_TAIL), - I915_READ(PRB0_START)); - I915_WRITE(PRB0_HEAD, 0); - - DRM_ERROR("Ring head forced to zero " - "ctl %08x head %08x tail %08x start %08x\n", - I915_READ(PRB0_CTL), - I915_READ(PRB0_HEAD), - I915_READ(PRB0_TAIL), - I915_READ(PRB0_START)); - } - - I915_WRITE(PRB0_CTL, - ((obj->size - 4096) & RING_NR_PAGES) | - RING_NO_REPORT | - RING_VALID); - - head = I915_READ(PRB0_HEAD) & HEAD_ADDR; - - /* If the head is still not zero, the ring is dead */ - if (head != 0) { - DRM_ERROR("Ring initialization failed " - "ctl %08x head %08x tail %08x start %08x\n", - I915_READ(PRB0_CTL), - I915_READ(PRB0_HEAD), - I915_READ(PRB0_TAIL), - I915_READ(PRB0_START)); - return -EIO; - } - - /* Update our cache of the ring state */ - i915_kernel_lost_context(dev); - - return 0; -} - -static void -i915_gem_cleanup_ringbuffer(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - - if (dev_priv->ring.ring_obj == NULL) - return; - - drm_core_ioremapfree(&dev_priv->ring.map, dev); - - i915_gem_object_unpin(dev_priv->ring.ring_obj); - drm_gem_object_unreference(dev_priv->ring.ring_obj); - dev_priv->ring.ring_obj = NULL; - memset(&dev_priv->ring, 0, sizeof(dev_priv->ring)); - - if (dev_priv->hws_obj != NULL) { - struct drm_gem_object *obj = dev_priv->hws_obj; - struct drm_i915_gem_object *obj_priv = obj->driver_private; - - kunmap(obj_priv->page_list[0]); - i915_gem_object_unpin(obj); - drm_gem_object_unreference(obj); - dev_priv->hws_obj = NULL; - memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map)); - dev_priv->hw_status_page = NULL; - - /* Write high address into HWS_PGA when disabling. */ - I915_WRITE(HWS_PGA, 0x1ffff000); - } -} - -int -i915_gem_entervt_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - int ret; - - if (dev_priv->mm.wedged) { - DRM_ERROR("Reenabling wedged hardware, good luck\n"); - dev_priv->mm.wedged = 0; - } - - ret = i915_gem_init_ringbuffer(dev); - if (ret != 0) - return ret; - - mutex_lock(&dev->struct_mutex); - BUG_ON(!list_empty(&dev_priv->mm.active_list)); - BUG_ON(!list_empty(&dev_priv->mm.flushing_list)); - BUG_ON(!list_empty(&dev_priv->mm.inactive_list)); - BUG_ON(!list_empty(&dev_priv->mm.request_list)); - dev_priv->mm.suspended = 0; - mutex_unlock(&dev->struct_mutex); - - drm_irq_install(dev); - - return 0; -} - -int -i915_gem_leavevt_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - int ret; - - ret = i915_gem_idle(dev); - drm_irq_uninstall(dev); - - return ret; -} - -void -i915_gem_lastclose(struct drm_device *dev) -{ - int ret; - - ret = i915_gem_idle(dev); - if (ret) - DRM_ERROR("failed to idle hardware: %d\n", ret); -} - -void -i915_gem_load(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - - INIT_LIST_HEAD(&dev_priv->mm.active_list); - INIT_LIST_HEAD(&dev_priv->mm.flushing_list); - INIT_LIST_HEAD(&dev_priv->mm.inactive_list); - INIT_LIST_HEAD(&dev_priv->mm.request_list); - INIT_DELAYED_WORK(&dev_priv->mm.retire_work, - i915_gem_retire_work_handler); - INIT_WORK(&dev_priv->mm.vblank_work, - i915_gem_vblank_work_handler); - dev_priv->mm.next_gem_seqno = 1; - - i915_gem_detect_bit_6_swizzle(dev); -} diff --git a/trunk/drivers/gpu/drm/i915/i915_gem_debug.c b/trunk/drivers/gpu/drm/i915/i915_gem_debug.c deleted file mode 100644 index 131c088f8c8a..000000000000 --- a/trunk/drivers/gpu/drm/i915/i915_gem_debug.c +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Copyright © 2008 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - * - * Authors: - * Keith Packard - * - */ - -#include "drmP.h" -#include "drm.h" -#include "i915_drm.h" -#include "i915_drv.h" - -#if WATCH_INACTIVE -void -i915_verify_inactive(struct drm_device *dev, char *file, int line) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_gem_object *obj; - struct drm_i915_gem_object *obj_priv; - - list_for_each_entry(obj_priv, &dev_priv->mm.inactive_list, list) { - obj = obj_priv->obj; - if (obj_priv->pin_count || obj_priv->active || - (obj->write_domain & ~(I915_GEM_DOMAIN_CPU | - I915_GEM_DOMAIN_GTT))) - DRM_ERROR("inactive %p (p %d a %d w %x) %s:%d\n", - obj, - obj_priv->pin_count, obj_priv->active, - obj->write_domain, file, line); - } -} -#endif /* WATCH_INACTIVE */ - - -#if WATCH_BUF | WATCH_EXEC | WATCH_PWRITE -static void -i915_gem_dump_page(struct page *page, uint32_t start, uint32_t end, - uint32_t bias, uint32_t mark) -{ - uint32_t *mem = kmap_atomic(page, KM_USER0); - int i; - for (i = start; i < end; i += 4) - DRM_INFO("%08x: %08x%s\n", - (int) (bias + i), mem[i / 4], - (bias + i == mark) ? " ********" : ""); - kunmap_atomic(mem, KM_USER0); - /* give syslog time to catch up */ - msleep(1); -} - -void -i915_gem_dump_object(struct drm_gem_object *obj, int len, - const char *where, uint32_t mark) -{ - struct drm_i915_gem_object *obj_priv = obj->driver_private; - int page; - - DRM_INFO("%s: object at offset %08x\n", where, obj_priv->gtt_offset); - for (page = 0; page < (len + PAGE_SIZE-1) / PAGE_SIZE; page++) { - int page_len, chunk, chunk_len; - - page_len = len - page * PAGE_SIZE; - if (page_len > PAGE_SIZE) - page_len = PAGE_SIZE; - - for (chunk = 0; chunk < page_len; chunk += 128) { - chunk_len = page_len - chunk; - if (chunk_len > 128) - chunk_len = 128; - i915_gem_dump_page(obj_priv->page_list[page], - chunk, chunk + chunk_len, - obj_priv->gtt_offset + - page * PAGE_SIZE, - mark); - } - } -} -#endif - -#if WATCH_LRU -void -i915_dump_lru(struct drm_device *dev, const char *where) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv; - - DRM_INFO("active list %s {\n", where); - list_for_each_entry(obj_priv, &dev_priv->mm.active_list, - list) - { - DRM_INFO(" %p: %08x\n", obj_priv, - obj_priv->last_rendering_seqno); - } - DRM_INFO("}\n"); - DRM_INFO("flushing list %s {\n", where); - list_for_each_entry(obj_priv, &dev_priv->mm.flushing_list, - list) - { - DRM_INFO(" %p: %08x\n", obj_priv, - obj_priv->last_rendering_seqno); - } - DRM_INFO("}\n"); - DRM_INFO("inactive %s {\n", where); - list_for_each_entry(obj_priv, &dev_priv->mm.inactive_list, list) { - DRM_INFO(" %p: %08x\n", obj_priv, - obj_priv->last_rendering_seqno); - } - DRM_INFO("}\n"); -} -#endif - - -#if WATCH_COHERENCY -void -i915_gem_object_check_coherency(struct drm_gem_object *obj, int handle) -{ - struct drm_device *dev = obj->dev; - struct drm_i915_gem_object *obj_priv = obj->driver_private; - int page; - uint32_t *gtt_mapping; - uint32_t *backing_map = NULL; - int bad_count = 0; - - DRM_INFO("%s: checking coherency of object %p@0x%08x (%d, %dkb):\n", - __func__, obj, obj_priv->gtt_offset, handle, - obj->size / 1024); - - gtt_mapping = ioremap(dev->agp->base + obj_priv->gtt_offset, - obj->size); - if (gtt_mapping == NULL) { - DRM_ERROR("failed to map GTT space\n"); - return; - } - - for (page = 0; page < obj->size / PAGE_SIZE; page++) { - int i; - - backing_map = kmap_atomic(obj_priv->page_list[page], KM_USER0); - - if (backing_map == NULL) { - DRM_ERROR("failed to map backing page\n"); - goto out; - } - - for (i = 0; i < PAGE_SIZE / 4; i++) { - uint32_t cpuval = backing_map[i]; - uint32_t gttval = readl(gtt_mapping + - page * 1024 + i); - - if (cpuval != gttval) { - DRM_INFO("incoherent CPU vs GPU at 0x%08x: " - "0x%08x vs 0x%08x\n", - (int)(obj_priv->gtt_offset + - page * PAGE_SIZE + i * 4), - cpuval, gttval); - if (bad_count++ >= 8) { - DRM_INFO("...\n"); - goto out; - } - } - } - kunmap_atomic(backing_map, KM_USER0); - backing_map = NULL; - } - - out: - if (backing_map != NULL) - kunmap_atomic(backing_map, KM_USER0); - iounmap(gtt_mapping); - - /* give syslog time to catch up */ - msleep(1); - - /* Directly flush the object, since we just loaded values with the CPU - * from the backing pages and we don't want to disturb the cache - * management that we're trying to observe. - */ - - i915_gem_clflush_object(obj); -} -#endif diff --git a/trunk/drivers/gpu/drm/i915/i915_gem_proc.c b/trunk/drivers/gpu/drm/i915/i915_gem_proc.c deleted file mode 100644 index 15d4160415b0..000000000000 --- a/trunk/drivers/gpu/drm/i915/i915_gem_proc.c +++ /dev/null @@ -1,292 +0,0 @@ -/* - * Copyright © 2008 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - * - * Authors: - * Eric Anholt - * Keith Packard - * - */ - -#include "drmP.h" -#include "drm.h" -#include "i915_drm.h" -#include "i915_drv.h" - -static int i915_gem_active_info(char *buf, char **start, off_t offset, - int request, int *eof, void *data) -{ - struct drm_minor *minor = (struct drm_minor *) data; - struct drm_device *dev = minor->dev; - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv; - int len = 0; - - if (offset > DRM_PROC_LIMIT) { - *eof = 1; - return 0; - } - - *start = &buf[offset]; - *eof = 0; - DRM_PROC_PRINT("Active:\n"); - list_for_each_entry(obj_priv, &dev_priv->mm.active_list, - list) - { - struct drm_gem_object *obj = obj_priv->obj; - if (obj->name) { - DRM_PROC_PRINT(" %p(%d): %08x %08x %d\n", - obj, obj->name, - obj->read_domains, obj->write_domain, - obj_priv->last_rendering_seqno); - } else { - DRM_PROC_PRINT(" %p: %08x %08x %d\n", - obj, - obj->read_domains, obj->write_domain, - obj_priv->last_rendering_seqno); - } - } - if (len > request + offset) - return request; - *eof = 1; - return len - offset; -} - -static int i915_gem_flushing_info(char *buf, char **start, off_t offset, - int request, int *eof, void *data) -{ - struct drm_minor *minor = (struct drm_minor *) data; - struct drm_device *dev = minor->dev; - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv; - int len = 0; - - if (offset > DRM_PROC_LIMIT) { - *eof = 1; - return 0; - } - - *start = &buf[offset]; - *eof = 0; - DRM_PROC_PRINT("Flushing:\n"); - list_for_each_entry(obj_priv, &dev_priv->mm.flushing_list, - list) - { - struct drm_gem_object *obj = obj_priv->obj; - if (obj->name) { - DRM_PROC_PRINT(" %p(%d): %08x %08x %d\n", - obj, obj->name, - obj->read_domains, obj->write_domain, - obj_priv->last_rendering_seqno); - } else { - DRM_PROC_PRINT(" %p: %08x %08x %d\n", obj, - obj->read_domains, obj->write_domain, - obj_priv->last_rendering_seqno); - } - } - if (len > request + offset) - return request; - *eof = 1; - return len - offset; -} - -static int i915_gem_inactive_info(char *buf, char **start, off_t offset, - int request, int *eof, void *data) -{ - struct drm_minor *minor = (struct drm_minor *) data; - struct drm_device *dev = minor->dev; - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv; - int len = 0; - - if (offset > DRM_PROC_LIMIT) { - *eof = 1; - return 0; - } - - *start = &buf[offset]; - *eof = 0; - DRM_PROC_PRINT("Inactive:\n"); - list_for_each_entry(obj_priv, &dev_priv->mm.inactive_list, - list) - { - struct drm_gem_object *obj = obj_priv->obj; - if (obj->name) { - DRM_PROC_PRINT(" %p(%d): %08x %08x %d\n", - obj, obj->name, - obj->read_domains, obj->write_domain, - obj_priv->last_rendering_seqno); - } else { - DRM_PROC_PRINT(" %p: %08x %08x %d\n", obj, - obj->read_domains, obj->write_domain, - obj_priv->last_rendering_seqno); - } - } - if (len > request + offset) - return request; - *eof = 1; - return len - offset; -} - -static int i915_gem_request_info(char *buf, char **start, off_t offset, - int request, int *eof, void *data) -{ - struct drm_minor *minor = (struct drm_minor *) data; - struct drm_device *dev = minor->dev; - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_request *gem_request; - int len = 0; - - if (offset > DRM_PROC_LIMIT) { - *eof = 1; - return 0; - } - - *start = &buf[offset]; - *eof = 0; - DRM_PROC_PRINT("Request:\n"); - list_for_each_entry(gem_request, &dev_priv->mm.request_list, - list) - { - DRM_PROC_PRINT(" %d @ %d %08x\n", - gem_request->seqno, - (int) (jiffies - gem_request->emitted_jiffies), - gem_request->flush_domains); - } - if (len > request + offset) - return request; - *eof = 1; - return len - offset; -} - -static int i915_gem_seqno_info(char *buf, char **start, off_t offset, - int request, int *eof, void *data) -{ - struct drm_minor *minor = (struct drm_minor *) data; - struct drm_device *dev = minor->dev; - drm_i915_private_t *dev_priv = dev->dev_private; - int len = 0; - - if (offset > DRM_PROC_LIMIT) { - *eof = 1; - return 0; - } - - *start = &buf[offset]; - *eof = 0; - DRM_PROC_PRINT("Current sequence: %d\n", i915_get_gem_seqno(dev)); - DRM_PROC_PRINT("Waiter sequence: %d\n", - dev_priv->mm.waiting_gem_seqno); - DRM_PROC_PRINT("IRQ sequence: %d\n", dev_priv->mm.irq_gem_seqno); - if (len > request + offset) - return request; - *eof = 1; - return len - offset; -} - - -static int i915_interrupt_info(char *buf, char **start, off_t offset, - int request, int *eof, void *data) -{ - struct drm_minor *minor = (struct drm_minor *) data; - struct drm_device *dev = minor->dev; - drm_i915_private_t *dev_priv = dev->dev_private; - int len = 0; - - if (offset > DRM_PROC_LIMIT) { - *eof = 1; - return 0; - } - - *start = &buf[offset]; - *eof = 0; - DRM_PROC_PRINT("Interrupt enable: %08x\n", - I915_READ(IER)); - DRM_PROC_PRINT("Interrupt identity: %08x\n", - I915_READ(IIR)); - DRM_PROC_PRINT("Interrupt mask: %08x\n", - I915_READ(IMR)); - DRM_PROC_PRINT("Pipe A stat: %08x\n", - I915_READ(PIPEASTAT)); - DRM_PROC_PRINT("Pipe B stat: %08x\n", - I915_READ(PIPEBSTAT)); - DRM_PROC_PRINT("Interrupts received: %d\n", - atomic_read(&dev_priv->irq_received)); - DRM_PROC_PRINT("Current sequence: %d\n", - i915_get_gem_seqno(dev)); - DRM_PROC_PRINT("Waiter sequence: %d\n", - dev_priv->mm.waiting_gem_seqno); - DRM_PROC_PRINT("IRQ sequence: %d\n", - dev_priv->mm.irq_gem_seqno); - if (len > request + offset) - return request; - *eof = 1; - return len - offset; -} - -static struct drm_proc_list { - /** file name */ - const char *name; - /** proc callback*/ - int (*f) (char *, char **, off_t, int, int *, void *); -} i915_gem_proc_list[] = { - {"i915_gem_active", i915_gem_active_info}, - {"i915_gem_flushing", i915_gem_flushing_info}, - {"i915_gem_inactive", i915_gem_inactive_info}, - {"i915_gem_request", i915_gem_request_info}, - {"i915_gem_seqno", i915_gem_seqno_info}, - {"i915_gem_interrupt", i915_interrupt_info}, -}; - -#define I915_GEM_PROC_ENTRIES ARRAY_SIZE(i915_gem_proc_list) - -int i915_gem_proc_init(struct drm_minor *minor) -{ - struct proc_dir_entry *ent; - int i, j; - - for (i = 0; i < I915_GEM_PROC_ENTRIES; i++) { - ent = create_proc_entry(i915_gem_proc_list[i].name, - S_IFREG | S_IRUGO, minor->dev_root); - if (!ent) { - DRM_ERROR("Cannot create /proc/dri/.../%s\n", - i915_gem_proc_list[i].name); - for (j = 0; j < i; j++) - remove_proc_entry(i915_gem_proc_list[i].name, - minor->dev_root); - return -1; - } - ent->read_proc = i915_gem_proc_list[i].f; - ent->data = minor; - } - return 0; -} - -void i915_gem_proc_cleanup(struct drm_minor *minor) -{ - int i; - - if (!minor->dev_root) - return; - - for (i = 0; i < I915_GEM_PROC_ENTRIES; i++) - remove_proc_entry(i915_gem_proc_list[i].name, minor->dev_root); -} diff --git a/trunk/drivers/gpu/drm/i915/i915_gem_tiling.c b/trunk/drivers/gpu/drm/i915/i915_gem_tiling.c deleted file mode 100644 index e8b85ac4ca04..000000000000 --- a/trunk/drivers/gpu/drm/i915/i915_gem_tiling.c +++ /dev/null @@ -1,257 +0,0 @@ -/* - * Copyright © 2008 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - * - * Authors: - * Eric Anholt - * - */ - -#include "drmP.h" -#include "drm.h" -#include "i915_drm.h" -#include "i915_drv.h" - -/** @file i915_gem_tiling.c - * - * Support for managing tiling state of buffer objects. - * - * The idea behind tiling is to increase cache hit rates by rearranging - * pixel data so that a group of pixel accesses are in the same cacheline. - * Performance improvement from doing this on the back/depth buffer are on - * the order of 30%. - * - * Intel architectures make this somewhat more complicated, though, by - * adjustments made to addressing of data when the memory is in interleaved - * mode (matched pairs of DIMMS) to improve memory bandwidth. - * For interleaved memory, the CPU sends every sequential 64 bytes - * to an alternate memory channel so it can get the bandwidth from both. - * - * The GPU also rearranges its accesses for increased bandwidth to interleaved - * memory, and it matches what the CPU does for non-tiled. However, when tiled - * it does it a little differently, since one walks addresses not just in the - * X direction but also Y. So, along with alternating channels when bit - * 6 of the address flips, it also alternates when other bits flip -- Bits 9 - * (every 512 bytes, an X tile scanline) and 10 (every two X tile scanlines) - * are common to both the 915 and 965-class hardware. - * - * The CPU also sometimes XORs in higher bits as well, to improve - * bandwidth doing strided access like we do so frequently in graphics. This - * is called "Channel XOR Randomization" in the MCH documentation. The result - * is that the CPU is XORing in either bit 11 or bit 17 to bit 6 of its address - * decode. - * - * All of this bit 6 XORing has an effect on our memory management, - * as we need to make sure that the 3d driver can correctly address object - * contents. - * - * If we don't have interleaved memory, all tiling is safe and no swizzling is - * required. - * - * When bit 17 is XORed in, we simply refuse to tile at all. Bit - * 17 is not just a page offset, so as we page an objet out and back in, - * individual pages in it will have different bit 17 addresses, resulting in - * each 64 bytes being swapped with its neighbor! - * - * Otherwise, if interleaved, we have to tell the 3d driver what the address - * swizzling it needs to do is, since it's writing with the CPU to the pages - * (bit 6 and potentially bit 11 XORed in), and the GPU is reading from the - * pages (bit 6, 9, and 10 XORed in), resulting in a cumulative bit swizzling - * required by the CPU of XORing in bit 6, 9, 10, and potentially 11, in order - * to match what the GPU expects. - */ - -/** - * Detects bit 6 swizzling of address lookup between IGD access and CPU - * access through main memory. - */ -void -i915_gem_detect_bit_6_swizzle(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - uint32_t swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN; - uint32_t swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN; - - if (!IS_I9XX(dev)) { - /* As far as we know, the 865 doesn't have these bit 6 - * swizzling issues. - */ - swizzle_x = I915_BIT_6_SWIZZLE_NONE; - swizzle_y = I915_BIT_6_SWIZZLE_NONE; - } else if ((!IS_I965G(dev) && !IS_G33(dev)) || IS_I965GM(dev) || - IS_GM45(dev)) { - uint32_t dcc; - - /* On 915-945 and GM965, channel interleave by the CPU is - * determined by DCC. The CPU will alternate based on bit 6 - * in interleaved mode, and the GPU will then also alternate - * on bit 6, 9, and 10 for X, but the CPU may also optionally - * alternate based on bit 17 (XOR not disabled and XOR - * bit == 17). - */ - dcc = I915_READ(DCC); - switch (dcc & DCC_ADDRESSING_MODE_MASK) { - case DCC_ADDRESSING_MODE_SINGLE_CHANNEL: - case DCC_ADDRESSING_MODE_DUAL_CHANNEL_ASYMMETRIC: - swizzle_x = I915_BIT_6_SWIZZLE_NONE; - swizzle_y = I915_BIT_6_SWIZZLE_NONE; - break; - case DCC_ADDRESSING_MODE_DUAL_CHANNEL_INTERLEAVED: - if (IS_I915G(dev) || IS_I915GM(dev) || - dcc & DCC_CHANNEL_XOR_DISABLE) { - swizzle_x = I915_BIT_6_SWIZZLE_9_10; - swizzle_y = I915_BIT_6_SWIZZLE_9; - } else if (IS_I965GM(dev) || IS_GM45(dev)) { - /* GM965 only does bit 11-based channel - * randomization - */ - swizzle_x = I915_BIT_6_SWIZZLE_9_10_11; - swizzle_y = I915_BIT_6_SWIZZLE_9_11; - } else { - /* Bit 17 or perhaps other swizzling */ - swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN; - swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN; - } - break; - } - if (dcc == 0xffffffff) { - DRM_ERROR("Couldn't read from MCHBAR. " - "Disabling tiling.\n"); - swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN; - swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN; - } - } else { - /* The 965, G33, and newer, have a very flexible memory - * configuration. It will enable dual-channel mode - * (interleaving) on as much memory as it can, and the GPU - * will additionally sometimes enable different bit 6 - * swizzling for tiled objects from the CPU. - * - * Here's what I found on the G965: - * slot fill memory size swizzling - * 0A 0B 1A 1B 1-ch 2-ch - * 512 0 0 0 512 0 O - * 512 0 512 0 16 1008 X - * 512 0 0 512 16 1008 X - * 0 512 0 512 16 1008 X - * 1024 1024 1024 0 2048 1024 O - * - * We could probably detect this based on either the DRB - * matching, which was the case for the swizzling required in - * the table above, or from the 1-ch value being less than - * the minimum size of a rank. - */ - if (I915_READ16(C0DRB3) != I915_READ16(C1DRB3)) { - swizzle_x = I915_BIT_6_SWIZZLE_NONE; - swizzle_y = I915_BIT_6_SWIZZLE_NONE; - } else { - swizzle_x = I915_BIT_6_SWIZZLE_9_10; - swizzle_y = I915_BIT_6_SWIZZLE_9; - } - } - - dev_priv->mm.bit_6_swizzle_x = swizzle_x; - dev_priv->mm.bit_6_swizzle_y = swizzle_y; -} - -/** - * Sets the tiling mode of an object, returning the required swizzling of - * bit 6 of addresses in the object. - */ -int -i915_gem_set_tiling(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_i915_gem_set_tiling *args = data; - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_gem_object *obj; - struct drm_i915_gem_object *obj_priv; - - obj = drm_gem_object_lookup(dev, file_priv, args->handle); - if (obj == NULL) - return -EINVAL; - obj_priv = obj->driver_private; - - mutex_lock(&dev->struct_mutex); - - if (args->tiling_mode == I915_TILING_NONE) { - obj_priv->tiling_mode = I915_TILING_NONE; - args->swizzle_mode = I915_BIT_6_SWIZZLE_NONE; - } else { - if (args->tiling_mode == I915_TILING_X) - args->swizzle_mode = dev_priv->mm.bit_6_swizzle_x; - else - args->swizzle_mode = dev_priv->mm.bit_6_swizzle_y; - /* If we can't handle the swizzling, make it untiled. */ - if (args->swizzle_mode == I915_BIT_6_SWIZZLE_UNKNOWN) { - args->tiling_mode = I915_TILING_NONE; - args->swizzle_mode = I915_BIT_6_SWIZZLE_NONE; - } - } - obj_priv->tiling_mode = args->tiling_mode; - - mutex_unlock(&dev->struct_mutex); - - drm_gem_object_unreference(obj); - - return 0; -} - -/** - * Returns the current tiling mode and required bit 6 swizzling for the object. - */ -int -i915_gem_get_tiling(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_i915_gem_get_tiling *args = data; - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_gem_object *obj; - struct drm_i915_gem_object *obj_priv; - - obj = drm_gem_object_lookup(dev, file_priv, args->handle); - if (obj == NULL) - return -EINVAL; - obj_priv = obj->driver_private; - - mutex_lock(&dev->struct_mutex); - - args->tiling_mode = obj_priv->tiling_mode; - switch (obj_priv->tiling_mode) { - case I915_TILING_X: - args->swizzle_mode = dev_priv->mm.bit_6_swizzle_x; - break; - case I915_TILING_Y: - args->swizzle_mode = dev_priv->mm.bit_6_swizzle_y; - break; - case I915_TILING_NONE: - args->swizzle_mode = I915_BIT_6_SWIZZLE_NONE; - break; - default: - DRM_ERROR("unknown tiling mode\n"); - } - - mutex_unlock(&dev->struct_mutex); - - drm_gem_object_unreference(obj); - - return 0; -} diff --git a/trunk/drivers/gpu/drm/i915/i915_irq.c b/trunk/drivers/gpu/drm/i915/i915_irq.c index baae511c785b..df036118b8b1 100644 --- a/trunk/drivers/gpu/drm/i915/i915_irq.c +++ b/trunk/drivers/gpu/drm/i915/i915_irq.c @@ -31,91 +31,11 @@ #include "i915_drm.h" #include "i915_drv.h" -#define MAX_NOPID ((u32)~0) - -/** These are the interrupts used by the driver */ -#define I915_INTERRUPT_ENABLE_MASK (I915_USER_INTERRUPT | \ - I915_ASLE_INTERRUPT | \ - I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | \ - I915_DISPLAY_PIPE_B_EVENT_INTERRUPT) - -void -i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask) -{ - if ((dev_priv->irq_mask_reg & mask) != 0) { - dev_priv->irq_mask_reg &= ~mask; - I915_WRITE(IMR, dev_priv->irq_mask_reg); - (void) I915_READ(IMR); - } -} - -static inline void -i915_disable_irq(drm_i915_private_t *dev_priv, u32 mask) -{ - if ((dev_priv->irq_mask_reg & mask) != mask) { - dev_priv->irq_mask_reg |= mask; - I915_WRITE(IMR, dev_priv->irq_mask_reg); - (void) I915_READ(IMR); - } -} - -/** - * i915_get_pipe - return the the pipe associated with a given plane - * @dev: DRM device - * @plane: plane to look for - * - * The Intel Mesa & 2D drivers call the vblank routines with a plane number - * rather than a pipe number, since they may not always be equal. This routine - * maps the given @plane back to a pipe number. - */ -static int -i915_get_pipe(struct drm_device *dev, int plane) -{ - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - u32 dspcntr; - - dspcntr = plane ? I915_READ(DSPBCNTR) : I915_READ(DSPACNTR); - - return dspcntr & DISPPLANE_SEL_PIPE_MASK ? 1 : 0; -} - -/** - * i915_get_plane - return the the plane associated with a given pipe - * @dev: DRM device - * @pipe: pipe to look for - * - * The Intel Mesa & 2D drivers call the vblank routines with a plane number - * rather than a plane number, since they may not always be equal. This routine - * maps the given @pipe back to a plane number. - */ -static int -i915_get_plane(struct drm_device *dev, int pipe) -{ - if (i915_get_pipe(dev, 0) == pipe) - return 0; - return 1; -} - -/** - * i915_pipe_enabled - check if a pipe is enabled - * @dev: DRM device - * @pipe: pipe to check - * - * Reading certain registers when the pipe is disabled can hang the chip. - * Use this routine to make sure the PLL is running and the pipe is active - * before reading such registers if unsure. - */ -static int -i915_pipe_enabled(struct drm_device *dev, int pipe) -{ - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - unsigned long pipeconf = pipe ? PIPEBCONF : PIPEACONF; +#define USER_INT_FLAG (1<<1) +#define VSYNC_PIPEB_FLAG (1<<5) +#define VSYNC_PIPEA_FLAG (1<<7) - if (I915_READ(pipeconf) & PIPEACONF_ENABLE) - return 1; - - return 0; -} +#define MAX_NOPID ((u32)~0) /** * Emit blits for scheduled buffer swaps. @@ -128,7 +48,8 @@ static void i915_vblank_tasklet(struct drm_device *dev) unsigned long irqflags; struct list_head *list, *tmp, hits, *hit; int nhits, nrects, slice[2], upper[2], lower[2], i; - unsigned counter[2]; + unsigned counter[2] = { atomic_read(&dev->vbl_received), + atomic_read(&dev->vbl_received2) }; struct drm_drawable_info *drw; drm_i915_sarea_t *sarea_priv = dev_priv->sarea_priv; u32 cpp = dev_priv->cpp; @@ -150,9 +71,6 @@ static void i915_vblank_tasklet(struct drm_device *dev) src_pitch >>= 2; } - counter[0] = drm_vblank_count(dev, 0); - counter[1] = drm_vblank_count(dev, 1); - DRM_DEBUG("\n"); INIT_LIST_HEAD(&hits); @@ -165,14 +83,12 @@ static void i915_vblank_tasklet(struct drm_device *dev) list_for_each_safe(list, tmp, &dev_priv->vbl_swaps.head) { drm_i915_vbl_swap_t *vbl_swap = list_entry(list, drm_i915_vbl_swap_t, head); - int pipe = i915_get_pipe(dev, vbl_swap->plane); - if ((counter[pipe] - vbl_swap->sequence) > (1<<23)) + if ((counter[vbl_swap->pipe] - vbl_swap->sequence) > (1<<23)) continue; list_del(list); dev_priv->swaps_pending--; - drm_vblank_put(dev, pipe); spin_unlock(&dev_priv->swaps_lock); spin_lock(&dev->drw_lock); @@ -265,7 +181,7 @@ static void i915_vblank_tasklet(struct drm_device *dev) drm_i915_vbl_swap_t *swap_hit = list_entry(hit, drm_i915_vbl_swap_t, head); struct drm_clip_rect *rect; - int num_rects, plane; + int num_rects, pipe; unsigned short top, bottom; drw = drm_get_drawable_info(dev, swap_hit->drw_id); @@ -274,9 +190,9 @@ static void i915_vblank_tasklet(struct drm_device *dev) continue; rect = drw->rects; - plane = swap_hit->plane; - top = upper[plane]; - bottom = lower[plane]; + pipe = swap_hit->pipe; + top = upper[pipe]; + bottom = lower[pipe]; for (num_rects = drw->num_rects; num_rects--; rect++) { int y1 = max(rect->y1, top); @@ -313,139 +229,61 @@ static void i915_vblank_tasklet(struct drm_device *dev) } } -u32 i915_get_vblank_counter(struct drm_device *dev, int plane) -{ - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - unsigned long high_frame; - unsigned long low_frame; - u32 high1, high2, low, count; - int pipe; - - pipe = i915_get_pipe(dev, plane); - high_frame = pipe ? PIPEBFRAMEHIGH : PIPEAFRAMEHIGH; - low_frame = pipe ? PIPEBFRAMEPIXEL : PIPEAFRAMEPIXEL; - - if (!i915_pipe_enabled(dev, pipe)) { - DRM_ERROR("trying to get vblank count for disabled pipe %d\n", pipe); - return 0; - } - - /* - * High & low register fields aren't synchronized, so make sure - * we get a low value that's stable across two reads of the high - * register. - */ - do { - high1 = ((I915_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >> - PIPE_FRAME_HIGH_SHIFT); - low = ((I915_READ(low_frame) & PIPE_FRAME_LOW_MASK) >> - PIPE_FRAME_LOW_SHIFT); - high2 = ((I915_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >> - PIPE_FRAME_HIGH_SHIFT); - } while (high1 != high2); - - count = (high1 << 8) | low; - - return count; -} - -void -i915_gem_vblank_work_handler(struct work_struct *work) -{ - drm_i915_private_t *dev_priv; - struct drm_device *dev; - - dev_priv = container_of(work, drm_i915_private_t, - mm.vblank_work); - dev = dev_priv->dev; - - mutex_lock(&dev->struct_mutex); - i915_vblank_tasklet(dev); - mutex_unlock(&dev->struct_mutex); -} - irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) { struct drm_device *dev = (struct drm_device *) arg; drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - u32 iir; + u16 temp; u32 pipea_stats, pipeb_stats; - int vblank = 0; - atomic_inc(&dev_priv->irq_received); + pipea_stats = I915_READ(I915REG_PIPEASTAT); + pipeb_stats = I915_READ(I915REG_PIPEBSTAT); - if (dev->pdev->msi_enabled) - I915_WRITE(IMR, ~0); - iir = I915_READ(IIR); + temp = I915_READ16(I915REG_INT_IDENTITY_R); - if (iir == 0) { - if (dev->pdev->msi_enabled) { - I915_WRITE(IMR, dev_priv->irq_mask_reg); - (void) I915_READ(IMR); - } - return IRQ_NONE; - } + temp &= (USER_INT_FLAG | VSYNC_PIPEA_FLAG | VSYNC_PIPEB_FLAG); - /* - * Clear the PIPE(A|B)STAT regs before the IIR otherwise - * we may get extra interrupts. - */ - if (iir & I915_DISPLAY_PIPE_A_EVENT_INTERRUPT) { - pipea_stats = I915_READ(PIPEASTAT); - if (!(dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_A)) - pipea_stats &= ~(PIPE_START_VBLANK_INTERRUPT_ENABLE | - PIPE_VBLANK_INTERRUPT_ENABLE); - else if (pipea_stats & (PIPE_START_VBLANK_INTERRUPT_STATUS| - PIPE_VBLANK_INTERRUPT_STATUS)) { - vblank++; - drm_handle_vblank(dev, i915_get_plane(dev, 0)); - } - - I915_WRITE(PIPEASTAT, pipea_stats); - } - if (iir & I915_DISPLAY_PIPE_B_EVENT_INTERRUPT) { - pipeb_stats = I915_READ(PIPEBSTAT); - /* Ack the event */ - I915_WRITE(PIPEBSTAT, pipeb_stats); - - /* The vblank interrupt gets enabled even if we didn't ask for - it, so make sure it's shut down again */ - if (!(dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_B)) - pipeb_stats &= ~(PIPE_START_VBLANK_INTERRUPT_ENABLE | - PIPE_VBLANK_INTERRUPT_ENABLE); - else if (pipeb_stats & (PIPE_START_VBLANK_INTERRUPT_STATUS| - PIPE_VBLANK_INTERRUPT_STATUS)) { - vblank++; - drm_handle_vblank(dev, i915_get_plane(dev, 1)); - } + DRM_DEBUG("%s flag=%08x\n", __FUNCTION__, temp); - if (pipeb_stats & I915_LEGACY_BLC_EVENT_STATUS) - opregion_asle_intr(dev); - I915_WRITE(PIPEBSTAT, pipeb_stats); - } + if (temp == 0) + return IRQ_NONE; - I915_WRITE(IIR, iir); - if (dev->pdev->msi_enabled) - I915_WRITE(IMR, dev_priv->irq_mask_reg); - (void) I915_READ(IIR); /* Flush posted writes */ + I915_WRITE16(I915REG_INT_IDENTITY_R, temp); + (void) I915_READ16(I915REG_INT_IDENTITY_R); + DRM_READMEMORYBARRIER(); - if (dev_priv->sarea_priv) - dev_priv->sarea_priv->last_dispatch = - READ_BREADCRUMB(dev_priv); + dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); - if (iir & I915_USER_INTERRUPT) { - dev_priv->mm.irq_gem_seqno = i915_get_gem_seqno(dev); + if (temp & USER_INT_FLAG) DRM_WAKEUP(&dev_priv->irq_queue); - } - if (iir & I915_ASLE_INTERRUPT) - opregion_asle_intr(dev); - - if (vblank && dev_priv->swaps_pending > 0) { - if (dev_priv->ring.ring_obj == NULL) + if (temp & (VSYNC_PIPEA_FLAG | VSYNC_PIPEB_FLAG)) { + int vblank_pipe = dev_priv->vblank_pipe; + + if ((vblank_pipe & + (DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B)) + == (DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B)) { + if (temp & VSYNC_PIPEA_FLAG) + atomic_inc(&dev->vbl_received); + if (temp & VSYNC_PIPEB_FLAG) + atomic_inc(&dev->vbl_received2); + } else if (((temp & VSYNC_PIPEA_FLAG) && + (vblank_pipe & DRM_I915_VBLANK_PIPE_A)) || + ((temp & VSYNC_PIPEB_FLAG) && + (vblank_pipe & DRM_I915_VBLANK_PIPE_B))) + atomic_inc(&dev->vbl_received); + + DRM_WAKEUP(&dev->vbl_queue); + drm_vbl_send_signals(dev); + + if (dev_priv->swaps_pending > 0) drm_locked_tasklet(dev, i915_vblank_tasklet); - else - schedule_work(&dev_priv->mm.vblank_work); + I915_WRITE(I915REG_PIPEASTAT, + pipea_stats|I915_VBLANK_INTERRUPT_ENABLE| + I915_VBLANK_CLEAR); + I915_WRITE(I915REG_PIPEBSTAT, + pipeb_stats|I915_VBLANK_INTERRUPT_ENABLE| + I915_VBLANK_CLEAR); } return IRQ_HANDLED; @@ -460,45 +298,23 @@ static int i915_emit_irq(struct drm_device * dev) DRM_DEBUG("\n"); - dev_priv->counter++; + dev_priv->sarea_priv->last_enqueue = ++dev_priv->counter; + if (dev_priv->counter > 0x7FFFFFFFUL) - dev_priv->counter = 1; - if (dev_priv->sarea_priv) - dev_priv->sarea_priv->last_enqueue = dev_priv->counter; + dev_priv->sarea_priv->last_enqueue = dev_priv->counter = 1; BEGIN_LP_RING(6); - OUT_RING(MI_STORE_DWORD_INDEX); - OUT_RING(5 << MI_STORE_DWORD_INDEX_SHIFT); + OUT_RING(CMD_STORE_DWORD_IDX); + OUT_RING(20); OUT_RING(dev_priv->counter); OUT_RING(0); OUT_RING(0); - OUT_RING(MI_USER_INTERRUPT); + OUT_RING(GFX_OP_USER_INTERRUPT); ADVANCE_LP_RING(); return dev_priv->counter; } -void i915_user_irq_get(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - - spin_lock(&dev_priv->user_irq_lock); - if (dev->irq_enabled && (++dev_priv->user_irq_refcount == 1)) - i915_enable_irq(dev_priv, I915_USER_INTERRUPT); - spin_unlock(&dev_priv->user_irq_lock); -} - -void i915_user_irq_put(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - - spin_lock(&dev_priv->user_irq_lock); - BUG_ON(dev->irq_enabled && dev_priv->user_irq_refcount <= 0); - if (dev->irq_enabled && (--dev_priv->user_irq_refcount == 0)) - i915_disable_irq(dev_priv, I915_USER_INTERRUPT); - spin_unlock(&dev_priv->user_irq_lock); -} - static int i915_wait_irq(struct drm_device * dev, int irq_nr) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; @@ -507,34 +323,55 @@ static int i915_wait_irq(struct drm_device * dev, int irq_nr) DRM_DEBUG("irq_nr=%d breadcrumb=%d\n", irq_nr, READ_BREADCRUMB(dev_priv)); - if (READ_BREADCRUMB(dev_priv) >= irq_nr) { - if (dev_priv->sarea_priv) { - dev_priv->sarea_priv->last_dispatch = - READ_BREADCRUMB(dev_priv); - } + if (READ_BREADCRUMB(dev_priv) >= irq_nr) return 0; - } - if (dev_priv->sarea_priv) - dev_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT; + dev_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT; - i915_user_irq_get(dev); DRM_WAIT_ON(ret, dev_priv->irq_queue, 3 * DRM_HZ, READ_BREADCRUMB(dev_priv) >= irq_nr); - i915_user_irq_put(dev); if (ret == -EBUSY) { DRM_ERROR("EBUSY -- rec: %d emitted: %d\n", READ_BREADCRUMB(dev_priv), (int)dev_priv->counter); } - if (dev_priv->sarea_priv) - dev_priv->sarea_priv->last_dispatch = - READ_BREADCRUMB(dev_priv); + dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); + return ret; +} + +static int i915_driver_vblank_do_wait(struct drm_device *dev, unsigned int *sequence, + atomic_t *counter) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + unsigned int cur_vblank; + int ret = 0; + + if (!dev_priv) { + DRM_ERROR("called with no initialization\n"); + return -EINVAL; + } + + DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ, + (((cur_vblank = atomic_read(counter)) + - *sequence) <= (1<<23))); + + *sequence = cur_vblank; return ret; } + +int i915_driver_vblank_wait(struct drm_device *dev, unsigned int *sequence) +{ + return i915_driver_vblank_do_wait(dev, sequence, &dev->vbl_received); +} + +int i915_driver_vblank_wait2(struct drm_device *dev, unsigned int *sequence) +{ + return i915_driver_vblank_do_wait(dev, sequence, &dev->vbl_received2); +} + /* Needs the lock as it touches the ring. */ int i915_irq_emit(struct drm_device *dev, void *data, @@ -544,15 +381,14 @@ int i915_irq_emit(struct drm_device *dev, void *data, drm_i915_irq_emit_t *emit = data; int result; - RING_LOCK_TEST_WITH_RETURN(dev, file_priv); + LOCK_TEST_WITH_RETURN(dev, file_priv); if (!dev_priv) { DRM_ERROR("called with no initialization\n"); return -EINVAL; } - mutex_lock(&dev->struct_mutex); + result = i915_emit_irq(dev); - mutex_unlock(&dev->struct_mutex); if (DRM_COPY_TO_USER(emit->irq_seq, &result, sizeof(int))) { DRM_ERROR("copy_to_user\n"); @@ -578,74 +414,18 @@ int i915_irq_wait(struct drm_device *dev, void *data, return i915_wait_irq(dev, irqwait->irq_seq); } -int i915_enable_vblank(struct drm_device *dev, int plane) +static void i915_enable_interrupt (struct drm_device *dev) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - int pipe = i915_get_pipe(dev, plane); - u32 pipestat_reg = 0; - u32 pipestat; - - switch (pipe) { - case 0: - pipestat_reg = PIPEASTAT; - i915_enable_irq(dev_priv, I915_DISPLAY_PIPE_A_EVENT_INTERRUPT); - break; - case 1: - pipestat_reg = PIPEBSTAT; - i915_enable_irq(dev_priv, I915_DISPLAY_PIPE_B_EVENT_INTERRUPT); - break; - default: - DRM_ERROR("tried to enable vblank on non-existent pipe %d\n", - pipe); - break; - } - - if (pipestat_reg) { - pipestat = I915_READ(pipestat_reg); - if (IS_I965G(dev)) - pipestat |= PIPE_START_VBLANK_INTERRUPT_ENABLE; - else - pipestat |= PIPE_VBLANK_INTERRUPT_ENABLE; - /* Clear any stale interrupt status */ - pipestat |= (PIPE_START_VBLANK_INTERRUPT_STATUS | - PIPE_VBLANK_INTERRUPT_STATUS); - I915_WRITE(pipestat_reg, pipestat); - } - - return 0; -} + u16 flag; -void i915_disable_vblank(struct drm_device *dev, int plane) -{ - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - int pipe = i915_get_pipe(dev, plane); - u32 pipestat_reg = 0; - u32 pipestat; - - switch (pipe) { - case 0: - pipestat_reg = PIPEASTAT; - i915_disable_irq(dev_priv, I915_DISPLAY_PIPE_A_EVENT_INTERRUPT); - break; - case 1: - pipestat_reg = PIPEBSTAT; - i915_disable_irq(dev_priv, I915_DISPLAY_PIPE_B_EVENT_INTERRUPT); - break; - default: - DRM_ERROR("tried to disable vblank on non-existent pipe %d\n", - pipe); - break; - } + flag = 0; + if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_A) + flag |= VSYNC_PIPEA_FLAG; + if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_B) + flag |= VSYNC_PIPEB_FLAG; - if (pipestat_reg) { - pipestat = I915_READ(pipestat_reg); - pipestat &= ~(PIPE_START_VBLANK_INTERRUPT_ENABLE | - PIPE_VBLANK_INTERRUPT_ENABLE); - /* Clear any stale interrupt status */ - pipestat |= (PIPE_START_VBLANK_INTERRUPT_STATUS | - PIPE_VBLANK_INTERRUPT_STATUS); - I915_WRITE(pipestat_reg, pipestat); - } + I915_WRITE16(I915REG_INT_ENABLE_R, USER_INT_FLAG | flag); } /* Set the vblank monitor pipe @@ -654,12 +434,22 @@ int i915_vblank_pipe_set(struct drm_device *dev, void *data, struct drm_file *file_priv) { drm_i915_private_t *dev_priv = dev->dev_private; + drm_i915_vblank_pipe_t *pipe = data; if (!dev_priv) { DRM_ERROR("called with no initialization\n"); return -EINVAL; } + if (pipe->pipe & ~(DRM_I915_VBLANK_PIPE_A|DRM_I915_VBLANK_PIPE_B)) { + DRM_ERROR("called with invalid pipe 0x%x\n", pipe->pipe); + return -EINVAL; + } + + dev_priv->vblank_pipe = pipe->pipe; + + i915_enable_interrupt (dev); + return 0; } @@ -668,13 +458,19 @@ int i915_vblank_pipe_get(struct drm_device *dev, void *data, { drm_i915_private_t *dev_priv = dev->dev_private; drm_i915_vblank_pipe_t *pipe = data; + u16 flag; if (!dev_priv) { DRM_ERROR("called with no initialization\n"); return -EINVAL; } - pipe->pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B; + flag = I915_READ(I915REG_INT_ENABLE_R); + pipe->pipe = 0; + if (flag & VSYNC_PIPEA_FLAG) + pipe->pipe |= DRM_I915_VBLANK_PIPE_A; + if (flag & VSYNC_PIPEB_FLAG) + pipe->pipe |= DRM_I915_VBLANK_PIPE_B; return 0; } @@ -688,12 +484,11 @@ int i915_vblank_swap(struct drm_device *dev, void *data, drm_i915_private_t *dev_priv = dev->dev_private; drm_i915_vblank_swap_t *swap = data; drm_i915_vbl_swap_t *vbl_swap; - unsigned int pipe, seqtype, curseq, plane; + unsigned int pipe, seqtype, curseq; unsigned long irqflags; struct list_head *list; - int ret; - if (!dev_priv || !dev_priv->sarea_priv) { + if (!dev_priv) { DRM_ERROR("%s called with no initialization\n", __func__); return -EINVAL; } @@ -709,8 +504,7 @@ int i915_vblank_swap(struct drm_device *dev, void *data, return -EINVAL; } - plane = (swap->seqtype & _DRM_VBLANK_SECONDARY) ? 1 : 0; - pipe = i915_get_pipe(dev, plane); + pipe = (swap->seqtype & _DRM_VBLANK_SECONDARY) ? 1 : 0; seqtype = swap->seqtype & (_DRM_VBLANK_RELATIVE | _DRM_VBLANK_ABSOLUTE); @@ -729,14 +523,7 @@ int i915_vblank_swap(struct drm_device *dev, void *data, spin_unlock_irqrestore(&dev->drw_lock, irqflags); - /* - * We take the ref here and put it when the swap actually completes - * in the tasklet. - */ - ret = drm_vblank_get(dev, pipe); - if (ret) - return ret; - curseq = drm_vblank_count(dev, pipe); + curseq = atomic_read(pipe ? &dev->vbl_received2 : &dev->vbl_received); if (seqtype == _DRM_VBLANK_RELATIVE) swap->sequence += curseq; @@ -746,7 +533,6 @@ int i915_vblank_swap(struct drm_device *dev, void *data, swap->sequence = curseq + 1; } else { DRM_DEBUG("Missed target sequence\n"); - drm_vblank_put(dev, pipe); return -EINVAL; } } @@ -757,7 +543,7 @@ int i915_vblank_swap(struct drm_device *dev, void *data, vbl_swap = list_entry(list, drm_i915_vbl_swap_t, head); if (vbl_swap->drw_id == swap->drawable && - vbl_swap->plane == plane && + vbl_swap->pipe == pipe && vbl_swap->sequence == swap->sequence) { spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags); DRM_DEBUG("Already scheduled\n"); @@ -769,7 +555,6 @@ int i915_vblank_swap(struct drm_device *dev, void *data, if (dev_priv->swaps_pending >= 100) { DRM_DEBUG("Too many swaps queued\n"); - drm_vblank_put(dev, pipe); return -EBUSY; } @@ -777,14 +562,13 @@ int i915_vblank_swap(struct drm_device *dev, void *data, if (!vbl_swap) { DRM_ERROR("Failed to allocate memory to queue swap\n"); - drm_vblank_put(dev, pipe); return -ENOMEM; } DRM_DEBUG("\n"); vbl_swap->drw_id = swap->drawable; - vbl_swap->plane = plane; + vbl_swap->pipe = pipe; vbl_swap->sequence = swap->sequence; spin_lock_irqsave(&dev_priv->swaps_lock, irqflags); @@ -803,63 +587,37 @@ void i915_driver_irq_preinstall(struct drm_device * dev) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - I915_WRITE(HWSTAM, 0xeffe); - I915_WRITE(IMR, 0xffffffff); - I915_WRITE(IER, 0x0); + I915_WRITE16(I915REG_HWSTAM, 0xfffe); + I915_WRITE16(I915REG_INT_MASK_R, 0x0); + I915_WRITE16(I915REG_INT_ENABLE_R, 0x0); } -int i915_driver_irq_postinstall(struct drm_device *dev) +void i915_driver_irq_postinstall(struct drm_device * dev) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - int ret, num_pipes = 2; spin_lock_init(&dev_priv->swaps_lock); INIT_LIST_HEAD(&dev_priv->vbl_swaps.head); dev_priv->swaps_pending = 0; - /* Set initial unmasked IRQs to just the selected vblank pipes. */ - dev_priv->irq_mask_reg = ~0; - - ret = drm_vblank_init(dev, num_pipes); - if (ret) - return ret; - - dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B; - dev_priv->irq_mask_reg &= ~I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT; - dev_priv->irq_mask_reg &= ~I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT; - - dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ - - dev_priv->irq_mask_reg &= I915_INTERRUPT_ENABLE_MASK; - - I915_WRITE(IMR, dev_priv->irq_mask_reg); - I915_WRITE(IER, I915_INTERRUPT_ENABLE_MASK); - (void) I915_READ(IER); - - opregion_enable_asle(dev); + if (!dev_priv->vblank_pipe) + dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A; + i915_enable_interrupt(dev); DRM_INIT_WAITQUEUE(&dev_priv->irq_queue); - - return 0; } void i915_driver_irq_uninstall(struct drm_device * dev) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - u32 temp; + u16 temp; if (!dev_priv) return; - dev_priv->vblank_pipe = 0; - - I915_WRITE(HWSTAM, 0xffffffff); - I915_WRITE(IMR, 0xffffffff); - I915_WRITE(IER, 0x0); + I915_WRITE16(I915REG_HWSTAM, 0xffff); + I915_WRITE16(I915REG_INT_MASK_R, 0xffff); + I915_WRITE16(I915REG_INT_ENABLE_R, 0x0); - temp = I915_READ(PIPEASTAT); - I915_WRITE(PIPEASTAT, temp); - temp = I915_READ(PIPEBSTAT); - I915_WRITE(PIPEBSTAT, temp); - temp = I915_READ(IIR); - I915_WRITE(IIR, temp); + temp = I915_READ16(I915REG_INT_IDENTITY_R); + I915_WRITE16(I915REG_INT_IDENTITY_R, temp); } diff --git a/trunk/drivers/gpu/drm/i915/i915_opregion.c b/trunk/drivers/gpu/drm/i915/i915_opregion.c deleted file mode 100644 index 1787a0c7e3ab..000000000000 --- a/trunk/drivers/gpu/drm/i915/i915_opregion.c +++ /dev/null @@ -1,371 +0,0 @@ -/* - * Copyright 2008 Intel Corporation - * Copyright 2008 Red Hat - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NON-INFRINGEMENT. IN NO EVENT SHALL INTEL AND/OR ITS SUPPLIERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - -#include - -#include "drmP.h" -#include "i915_drm.h" -#include "i915_drv.h" - -#define PCI_ASLE 0xe4 -#define PCI_LBPC 0xf4 -#define PCI_ASLS 0xfc - -#define OPREGION_SZ (8*1024) -#define OPREGION_HEADER_OFFSET 0 -#define OPREGION_ACPI_OFFSET 0x100 -#define OPREGION_SWSCI_OFFSET 0x200 -#define OPREGION_ASLE_OFFSET 0x300 -#define OPREGION_VBT_OFFSET 0x1000 - -#define OPREGION_SIGNATURE "IntelGraphicsMem" -#define MBOX_ACPI (1<<0) -#define MBOX_SWSCI (1<<1) -#define MBOX_ASLE (1<<2) - -struct opregion_header { - u8 signature[16]; - u32 size; - u32 opregion_ver; - u8 bios_ver[32]; - u8 vbios_ver[16]; - u8 driver_ver[16]; - u32 mboxes; - u8 reserved[164]; -} __attribute__((packed)); - -/* OpRegion mailbox #1: public ACPI methods */ -struct opregion_acpi { - u32 drdy; /* driver readiness */ - u32 csts; /* notification status */ - u32 cevt; /* current event */ - u8 rsvd1[20]; - u32 didl[8]; /* supported display devices ID list */ - u32 cpdl[8]; /* currently presented display list */ - u32 cadl[8]; /* currently active display list */ - u32 nadl[8]; /* next active devices list */ - u32 aslp; /* ASL sleep time-out */ - u32 tidx; /* toggle table index */ - u32 chpd; /* current hotplug enable indicator */ - u32 clid; /* current lid state*/ - u32 cdck; /* current docking state */ - u32 sxsw; /* Sx state resume */ - u32 evts; /* ASL supported events */ - u32 cnot; /* current OS notification */ - u32 nrdy; /* driver status */ - u8 rsvd2[60]; -} __attribute__((packed)); - -/* OpRegion mailbox #2: SWSCI */ -struct opregion_swsci { - u32 scic; /* SWSCI command|status|data */ - u32 parm; /* command parameters */ - u32 dslp; /* driver sleep time-out */ - u8 rsvd[244]; -} __attribute__((packed)); - -/* OpRegion mailbox #3: ASLE */ -struct opregion_asle { - u32 ardy; /* driver readiness */ - u32 aslc; /* ASLE interrupt command */ - u32 tche; /* technology enabled indicator */ - u32 alsi; /* current ALS illuminance reading */ - u32 bclp; /* backlight brightness to set */ - u32 pfit; /* panel fitting state */ - u32 cblv; /* current brightness level */ - u16 bclm[20]; /* backlight level duty cycle mapping table */ - u32 cpfm; /* current panel fitting mode */ - u32 epfm; /* enabled panel fitting modes */ - u8 plut[74]; /* panel LUT and identifier */ - u32 pfmb; /* PWM freq and min brightness */ - u8 rsvd[102]; -} __attribute__((packed)); - -/* ASLE irq request bits */ -#define ASLE_SET_ALS_ILLUM (1 << 0) -#define ASLE_SET_BACKLIGHT (1 << 1) -#define ASLE_SET_PFIT (1 << 2) -#define ASLE_SET_PWM_FREQ (1 << 3) -#define ASLE_REQ_MSK 0xf - -/* response bits of ASLE irq request */ -#define ASLE_ALS_ILLUM_FAIL (2<<10) -#define ASLE_BACKLIGHT_FAIL (2<<12) -#define ASLE_PFIT_FAIL (2<<14) -#define ASLE_PWM_FREQ_FAIL (2<<16) - -/* ASLE backlight brightness to set */ -#define ASLE_BCLP_VALID (1<<31) -#define ASLE_BCLP_MSK (~(1<<31)) - -/* ASLE panel fitting request */ -#define ASLE_PFIT_VALID (1<<31) -#define ASLE_PFIT_CENTER (1<<0) -#define ASLE_PFIT_STRETCH_TEXT (1<<1) -#define ASLE_PFIT_STRETCH_GFX (1<<2) - -/* PWM frequency and minimum brightness */ -#define ASLE_PFMB_BRIGHTNESS_MASK (0xff) -#define ASLE_PFMB_BRIGHTNESS_VALID (1<<8) -#define ASLE_PFMB_PWM_MASK (0x7ffffe00) -#define ASLE_PFMB_PWM_VALID (1<<31) - -#define ASLE_CBLV_VALID (1<<31) - -static u32 asle_set_backlight(struct drm_device *dev, u32 bclp) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct opregion_asle *asle = dev_priv->opregion.asle; - u32 blc_pwm_ctl, blc_pwm_ctl2; - - if (!(bclp & ASLE_BCLP_VALID)) - return ASLE_BACKLIGHT_FAIL; - - bclp &= ASLE_BCLP_MSK; - if (bclp < 0 || bclp > 255) - return ASLE_BACKLIGHT_FAIL; - - blc_pwm_ctl = I915_READ(BLC_PWM_CTL); - blc_pwm_ctl &= ~BACKLIGHT_DUTY_CYCLE_MASK; - blc_pwm_ctl2 = I915_READ(BLC_PWM_CTL2); - - if (blc_pwm_ctl2 & BLM_COMBINATION_MODE) - pci_write_config_dword(dev->pdev, PCI_LBPC, bclp); - else - I915_WRITE(BLC_PWM_CTL, blc_pwm_ctl | ((bclp * 0x101)-1)); - - asle->cblv = (bclp*0x64)/0xff | ASLE_CBLV_VALID; - - return 0; -} - -static u32 asle_set_als_illum(struct drm_device *dev, u32 alsi) -{ - /* alsi is the current ALS reading in lux. 0 indicates below sensor - range, 0xffff indicates above sensor range. 1-0xfffe are valid */ - return 0; -} - -static u32 asle_set_pwm_freq(struct drm_device *dev, u32 pfmb) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - if (pfmb & ASLE_PFMB_PWM_VALID) { - u32 blc_pwm_ctl = I915_READ(BLC_PWM_CTL); - u32 pwm = pfmb & ASLE_PFMB_PWM_MASK; - blc_pwm_ctl &= BACKLIGHT_DUTY_CYCLE_MASK; - pwm = pwm >> 9; - /* FIXME - what do we do with the PWM? */ - } - return 0; -} - -static u32 asle_set_pfit(struct drm_device *dev, u32 pfit) -{ - /* Panel fitting is currently controlled by the X code, so this is a - noop until modesetting support works fully */ - if (!(pfit & ASLE_PFIT_VALID)) - return ASLE_PFIT_FAIL; - return 0; -} - -void opregion_asle_intr(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct opregion_asle *asle = dev_priv->opregion.asle; - u32 asle_stat = 0; - u32 asle_req; - - if (!asle) - return; - - asle_req = asle->aslc & ASLE_REQ_MSK; - - if (!asle_req) { - DRM_DEBUG("non asle set request??\n"); - return; - } - - if (asle_req & ASLE_SET_ALS_ILLUM) - asle_stat |= asle_set_als_illum(dev, asle->alsi); - - if (asle_req & ASLE_SET_BACKLIGHT) - asle_stat |= asle_set_backlight(dev, asle->bclp); - - if (asle_req & ASLE_SET_PFIT) - asle_stat |= asle_set_pfit(dev, asle->pfit); - - if (asle_req & ASLE_SET_PWM_FREQ) - asle_stat |= asle_set_pwm_freq(dev, asle->pfmb); - - asle->aslc = asle_stat; -} - -#define ASLE_ALS_EN (1<<0) -#define ASLE_BLC_EN (1<<1) -#define ASLE_PFIT_EN (1<<2) -#define ASLE_PFMB_EN (1<<3) - -void opregion_enable_asle(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct opregion_asle *asle = dev_priv->opregion.asle; - - if (asle) { - u32 pipeb_stats = I915_READ(PIPEBSTAT); - if (IS_MOBILE(dev)) { - /* Many devices trigger events with a write to the - legacy backlight controller, so we need to ensure - that it's able to generate interrupts */ - I915_WRITE(PIPEBSTAT, pipeb_stats |= - I915_LEGACY_BLC_EVENT_ENABLE); - i915_enable_irq(dev_priv, I915_ASLE_INTERRUPT | - I915_DISPLAY_PIPE_B_EVENT_INTERRUPT); - } else - i915_enable_irq(dev_priv, I915_ASLE_INTERRUPT); - - asle->tche = ASLE_ALS_EN | ASLE_BLC_EN | ASLE_PFIT_EN | - ASLE_PFMB_EN; - asle->ardy = 1; - } -} - -#define ACPI_EV_DISPLAY_SWITCH (1<<0) -#define ACPI_EV_LID (1<<1) -#define ACPI_EV_DOCK (1<<2) - -static struct intel_opregion *system_opregion; - -int intel_opregion_video_event(struct notifier_block *nb, unsigned long val, - void *data) -{ - /* The only video events relevant to opregion are 0x80. These indicate - either a docking event, lid switch or display switch request. In - Linux, these are handled by the dock, button and video drivers. - We might want to fix the video driver to be opregion-aware in - future, but right now we just indicate to the firmware that the - request has been handled */ - - struct opregion_acpi *acpi; - - if (!system_opregion) - return NOTIFY_DONE; - - acpi = system_opregion->acpi; - acpi->csts = 0; - - return NOTIFY_OK; -} - -static struct notifier_block intel_opregion_notifier = { - .notifier_call = intel_opregion_video_event, -}; - -int intel_opregion_init(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_opregion *opregion = &dev_priv->opregion; - void *base; - u32 asls, mboxes; - int err = 0; - - pci_read_config_dword(dev->pdev, PCI_ASLS, &asls); - DRM_DEBUG("graphic opregion physical addr: 0x%x\n", asls); - if (asls == 0) { - DRM_DEBUG("ACPI OpRegion not supported!\n"); - return -ENOTSUPP; - } - - base = ioremap(asls, OPREGION_SZ); - if (!base) - return -ENOMEM; - - opregion->header = base; - if (memcmp(opregion->header->signature, OPREGION_SIGNATURE, 16)) { - DRM_DEBUG("opregion signature mismatch\n"); - err = -EINVAL; - goto err_out; - } - - mboxes = opregion->header->mboxes; - if (mboxes & MBOX_ACPI) { - DRM_DEBUG("Public ACPI methods supported\n"); - opregion->acpi = base + OPREGION_ACPI_OFFSET; - } else { - DRM_DEBUG("Public ACPI methods not supported\n"); - err = -ENOTSUPP; - goto err_out; - } - opregion->enabled = 1; - - if (mboxes & MBOX_SWSCI) { - DRM_DEBUG("SWSCI supported\n"); - opregion->swsci = base + OPREGION_SWSCI_OFFSET; - } - if (mboxes & MBOX_ASLE) { - DRM_DEBUG("ASLE supported\n"); - opregion->asle = base + OPREGION_ASLE_OFFSET; - } - - /* Notify BIOS we are ready to handle ACPI video ext notifs. - * Right now, all the events are handled by the ACPI video module. - * We don't actually need to do anything with them. */ - opregion->acpi->csts = 0; - opregion->acpi->drdy = 1; - - system_opregion = opregion; - register_acpi_notifier(&intel_opregion_notifier); - - return 0; - -err_out: - iounmap(opregion->header); - opregion->header = NULL; - return err; -} - -void intel_opregion_free(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_opregion *opregion = &dev_priv->opregion; - - if (!opregion->enabled) - return; - - opregion->acpi->drdy = 0; - - system_opregion = NULL; - unregister_acpi_notifier(&intel_opregion_notifier); - - /* just clear all opregion memory pointers now */ - iounmap(opregion->header); - opregion->header = NULL; - opregion->acpi = NULL; - opregion->swsci = NULL; - opregion->asle = NULL; - - opregion->enabled = 0; -} diff --git a/trunk/drivers/gpu/drm/i915/i915_reg.h b/trunk/drivers/gpu/drm/i915/i915_reg.h deleted file mode 100644 index 5c2d9f206d05..000000000000 --- a/trunk/drivers/gpu/drm/i915/i915_reg.h +++ /dev/null @@ -1,1417 +0,0 @@ -/* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef _I915_REG_H_ -#define _I915_REG_H_ - -/* - * The Bridge device's PCI config space has information about the - * fb aperture size and the amount of pre-reserved memory. - */ -#define INTEL_GMCH_CTRL 0x52 -#define INTEL_GMCH_ENABLED 0x4 -#define INTEL_GMCH_MEM_MASK 0x1 -#define INTEL_GMCH_MEM_64M 0x1 -#define INTEL_GMCH_MEM_128M 0 - -#define INTEL_855_GMCH_GMS_MASK (0x7 << 4) -#define INTEL_855_GMCH_GMS_DISABLED (0x0 << 4) -#define INTEL_855_GMCH_GMS_STOLEN_1M (0x1 << 4) -#define INTEL_855_GMCH_GMS_STOLEN_4M (0x2 << 4) -#define INTEL_855_GMCH_GMS_STOLEN_8M (0x3 << 4) -#define INTEL_855_GMCH_GMS_STOLEN_16M (0x4 << 4) -#define INTEL_855_GMCH_GMS_STOLEN_32M (0x5 << 4) - -#define INTEL_915G_GMCH_GMS_STOLEN_48M (0x6 << 4) -#define INTEL_915G_GMCH_GMS_STOLEN_64M (0x7 << 4) - -/* PCI config space */ - -#define HPLLCC 0xc0 /* 855 only */ -#define GC_CLOCK_CONTROL_MASK (3 << 0) -#define GC_CLOCK_133_200 (0 << 0) -#define GC_CLOCK_100_200 (1 << 0) -#define GC_CLOCK_100_133 (2 << 0) -#define GC_CLOCK_166_250 (3 << 0) -#define GCFGC 0xf0 /* 915+ only */ -#define GC_LOW_FREQUENCY_ENABLE (1 << 7) -#define GC_DISPLAY_CLOCK_190_200_MHZ (0 << 4) -#define GC_DISPLAY_CLOCK_333_MHZ (4 << 4) -#define GC_DISPLAY_CLOCK_MASK (7 << 4) -#define LBB 0xf4 - -/* VGA stuff */ - -#define VGA_ST01_MDA 0x3ba -#define VGA_ST01_CGA 0x3da - -#define VGA_MSR_WRITE 0x3c2 -#define VGA_MSR_READ 0x3cc -#define VGA_MSR_MEM_EN (1<<1) -#define VGA_MSR_CGA_MODE (1<<0) - -#define VGA_SR_INDEX 0x3c4 -#define VGA_SR_DATA 0x3c5 - -#define VGA_AR_INDEX 0x3c0 -#define VGA_AR_VID_EN (1<<5) -#define VGA_AR_DATA_WRITE 0x3c0 -#define VGA_AR_DATA_READ 0x3c1 - -#define VGA_GR_INDEX 0x3ce -#define VGA_GR_DATA 0x3cf -/* GR05 */ -#define VGA_GR_MEM_READ_MODE_SHIFT 3 -#define VGA_GR_MEM_READ_MODE_PLANE 1 -/* GR06 */ -#define VGA_GR_MEM_MODE_MASK 0xc -#define VGA_GR_MEM_MODE_SHIFT 2 -#define VGA_GR_MEM_A0000_AFFFF 0 -#define VGA_GR_MEM_A0000_BFFFF 1 -#define VGA_GR_MEM_B0000_B7FFF 2 -#define VGA_GR_MEM_B0000_BFFFF 3 - -#define VGA_DACMASK 0x3c6 -#define VGA_DACRX 0x3c7 -#define VGA_DACWX 0x3c8 -#define VGA_DACDATA 0x3c9 - -#define VGA_CR_INDEX_MDA 0x3b4 -#define VGA_CR_DATA_MDA 0x3b5 -#define VGA_CR_INDEX_CGA 0x3d4 -#define VGA_CR_DATA_CGA 0x3d5 - -/* - * Memory interface instructions used by the kernel - */ -#define MI_INSTR(opcode, flags) (((opcode) << 23) | (flags)) - -#define MI_NOOP MI_INSTR(0, 0) -#define MI_USER_INTERRUPT MI_INSTR(0x02, 0) -#define MI_WAIT_FOR_EVENT MI_INSTR(0x03, 0) -#define MI_WAIT_FOR_PLANE_B_FLIP (1<<6) -#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2) -#define MI_WAIT_FOR_PLANE_A_SCANLINES (1<<1) -#define MI_FLUSH MI_INSTR(0x04, 0) -#define MI_READ_FLUSH (1 << 0) -#define MI_EXE_FLUSH (1 << 1) -#define MI_NO_WRITE_FLUSH (1 << 2) -#define MI_SCENE_COUNT (1 << 3) /* just increment scene count */ -#define MI_END_SCENE (1 << 4) /* flush binner and incr scene count */ -#define MI_BATCH_BUFFER_END MI_INSTR(0x0a, 0) -#define MI_REPORT_HEAD MI_INSTR(0x07, 0) -#define MI_LOAD_SCAN_LINES_INCL MI_INSTR(0x12, 0) -#define MI_STORE_DWORD_IMM MI_INSTR(0x20, 1) -#define MI_MEM_VIRTUAL (1 << 22) /* 965+ only */ -#define MI_STORE_DWORD_INDEX MI_INSTR(0x21, 1) -#define MI_STORE_DWORD_INDEX_SHIFT 2 -#define MI_LOAD_REGISTER_IMM MI_INSTR(0x22, 1) -#define MI_BATCH_BUFFER MI_INSTR(0x30, 1) -#define MI_BATCH_NON_SECURE (1) -#define MI_BATCH_NON_SECURE_I965 (1<<8) -#define MI_BATCH_BUFFER_START MI_INSTR(0x31, 0) - -/* - * 3D instructions used by the kernel - */ -#define GFX_INSTR(opcode, flags) ((0x3 << 29) | ((opcode) << 24) | (flags)) - -#define GFX_OP_RASTER_RULES ((0x3<<29)|(0x7<<24)) -#define GFX_OP_SCISSOR ((0x3<<29)|(0x1c<<24)|(0x10<<19)) -#define SC_UPDATE_SCISSOR (0x1<<1) -#define SC_ENABLE_MASK (0x1<<0) -#define SC_ENABLE (0x1<<0) -#define GFX_OP_LOAD_INDIRECT ((0x3<<29)|(0x1d<<24)|(0x7<<16)) -#define GFX_OP_SCISSOR_INFO ((0x3<<29)|(0x1d<<24)|(0x81<<16)|(0x1)) -#define SCI_YMIN_MASK (0xffff<<16) -#define SCI_XMIN_MASK (0xffff<<0) -#define SCI_YMAX_MASK (0xffff<<16) -#define SCI_XMAX_MASK (0xffff<<0) -#define GFX_OP_SCISSOR_ENABLE ((0x3<<29)|(0x1c<<24)|(0x10<<19)) -#define GFX_OP_SCISSOR_RECT ((0x3<<29)|(0x1d<<24)|(0x81<<16)|1) -#define GFX_OP_COLOR_FACTOR ((0x3<<29)|(0x1d<<24)|(0x1<<16)|0x0) -#define GFX_OP_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16)) -#define GFX_OP_MAP_INFO ((0x3<<29)|(0x1d<<24)|0x4) -#define GFX_OP_DESTBUFFER_VARS ((0x3<<29)|(0x1d<<24)|(0x85<<16)|0x0) -#define GFX_OP_DESTBUFFER_INFO ((0x3<<29)|(0x1d<<24)|(0x8e<<16)|1) -#define GFX_OP_DRAWRECT_INFO ((0x3<<29)|(0x1d<<24)|(0x80<<16)|(0x3)) -#define GFX_OP_DRAWRECT_INFO_I965 ((0x7900<<16)|0x2) -#define SRC_COPY_BLT_CMD ((2<<29)|(0x43<<22)|4) -#define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6) -#define XY_MONO_SRC_COPY_IMM_BLT ((2<<29)|(0x71<<22)|5) -#define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21) -#define XY_SRC_COPY_BLT_WRITE_RGB (1<<20) -#define BLT_DEPTH_8 (0<<24) -#define BLT_DEPTH_16_565 (1<<24) -#define BLT_DEPTH_16_1555 (2<<24) -#define BLT_DEPTH_32 (3<<24) -#define BLT_ROP_GXCOPY (0xcc<<16) -#define XY_SRC_COPY_BLT_SRC_TILED (1<<15) /* 965+ only */ -#define XY_SRC_COPY_BLT_DST_TILED (1<<11) /* 965+ only */ -#define CMD_OP_DISPLAYBUFFER_INFO ((0x0<<29)|(0x14<<23)|2) -#define ASYNC_FLIP (1<<22) -#define DISPLAY_PLANE_A (0<<20) -#define DISPLAY_PLANE_B (1<<20) - -/* - * Instruction and interrupt control regs - */ - -#define PRB0_TAIL 0x02030 -#define PRB0_HEAD 0x02034 -#define PRB0_START 0x02038 -#define PRB0_CTL 0x0203c -#define TAIL_ADDR 0x001FFFF8 -#define HEAD_WRAP_COUNT 0xFFE00000 -#define HEAD_WRAP_ONE 0x00200000 -#define HEAD_ADDR 0x001FFFFC -#define RING_NR_PAGES 0x001FF000 -#define RING_REPORT_MASK 0x00000006 -#define RING_REPORT_64K 0x00000002 -#define RING_REPORT_128K 0x00000004 -#define RING_NO_REPORT 0x00000000 -#define RING_VALID_MASK 0x00000001 -#define RING_VALID 0x00000001 -#define RING_INVALID 0x00000000 -#define PRB1_TAIL 0x02040 /* 915+ only */ -#define PRB1_HEAD 0x02044 /* 915+ only */ -#define PRB1_START 0x02048 /* 915+ only */ -#define PRB1_CTL 0x0204c /* 915+ only */ -#define ACTHD_I965 0x02074 -#define HWS_PGA 0x02080 -#define HWS_ADDRESS_MASK 0xfffff000 -#define HWS_START_ADDRESS_SHIFT 4 -#define IPEIR 0x02088 -#define NOPID 0x02094 -#define HWSTAM 0x02098 -#define SCPD0 0x0209c /* 915+ only */ -#define IER 0x020a0 -#define IIR 0x020a4 -#define IMR 0x020a8 -#define ISR 0x020ac -#define I915_PIPE_CONTROL_NOTIFY_INTERRUPT (1<<18) -#define I915_DISPLAY_PORT_INTERRUPT (1<<17) -#define I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT (1<<15) -#define I915_GMCH_THERMAL_SENSOR_EVENT_INTERRUPT (1<<14) -#define I915_HWB_OOM_INTERRUPT (1<<13) -#define I915_SYNC_STATUS_INTERRUPT (1<<12) -#define I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT (1<<11) -#define I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT (1<<10) -#define I915_OVERLAY_PLANE_FLIP_PENDING_INTERRUPT (1<<9) -#define I915_DISPLAY_PLANE_C_FLIP_PENDING_INTERRUPT (1<<8) -#define I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT (1<<7) -#define I915_DISPLAY_PIPE_A_EVENT_INTERRUPT (1<<6) -#define I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT (1<<5) -#define I915_DISPLAY_PIPE_B_EVENT_INTERRUPT (1<<4) -#define I915_DEBUG_INTERRUPT (1<<2) -#define I915_USER_INTERRUPT (1<<1) -#define I915_ASLE_INTERRUPT (1<<0) -#define EIR 0x020b0 -#define EMR 0x020b4 -#define ESR 0x020b8 -#define INSTPM 0x020c0 -#define ACTHD 0x020c8 -#define FW_BLC 0x020d8 -#define FW_BLC_SELF 0x020e0 /* 915+ only */ -#define MI_ARB_STATE 0x020e4 /* 915+ only */ -#define CACHE_MODE_0 0x02120 /* 915+ only */ -#define CM0_MASK_SHIFT 16 -#define CM0_IZ_OPT_DISABLE (1<<6) -#define CM0_ZR_OPT_DISABLE (1<<5) -#define CM0_DEPTH_EVICT_DISABLE (1<<4) -#define CM0_COLOR_EVICT_DISABLE (1<<3) -#define CM0_DEPTH_WRITE_DISABLE (1<<1) -#define CM0_RC_OP_FLUSH_DISABLE (1<<0) -#define GFX_FLSH_CNTL 0x02170 /* 915+ only */ - -/* - * Framebuffer compression (915+ only) - */ - -#define FBC_CFB_BASE 0x03200 /* 4k page aligned */ -#define FBC_LL_BASE 0x03204 /* 4k page aligned */ -#define FBC_CONTROL 0x03208 -#define FBC_CTL_EN (1<<31) -#define FBC_CTL_PERIODIC (1<<30) -#define FBC_CTL_INTERVAL_SHIFT (16) -#define FBC_CTL_UNCOMPRESSIBLE (1<<14) -#define FBC_CTL_STRIDE_SHIFT (5) -#define FBC_CTL_FENCENO (1<<0) -#define FBC_COMMAND 0x0320c -#define FBC_CMD_COMPRESS (1<<0) -#define FBC_STATUS 0x03210 -#define FBC_STAT_COMPRESSING (1<<31) -#define FBC_STAT_COMPRESSED (1<<30) -#define FBC_STAT_MODIFIED (1<<29) -#define FBC_STAT_CURRENT_LINE (1<<0) -#define FBC_CONTROL2 0x03214 -#define FBC_CTL_FENCE_DBL (0<<4) -#define FBC_CTL_IDLE_IMM (0<<2) -#define FBC_CTL_IDLE_FULL (1<<2) -#define FBC_CTL_IDLE_LINE (2<<2) -#define FBC_CTL_IDLE_DEBUG (3<<2) -#define FBC_CTL_CPU_FENCE (1<<1) -#define FBC_CTL_PLANEA (0<<0) -#define FBC_CTL_PLANEB (1<<0) -#define FBC_FENCE_OFF 0x0321b - -#define FBC_LL_SIZE (1536) - -/* - * GPIO regs - */ -#define GPIOA 0x5010 -#define GPIOB 0x5014 -#define GPIOC 0x5018 -#define GPIOD 0x501c -#define GPIOE 0x5020 -#define GPIOF 0x5024 -#define GPIOG 0x5028 -#define GPIOH 0x502c -# define GPIO_CLOCK_DIR_MASK (1 << 0) -# define GPIO_CLOCK_DIR_IN (0 << 1) -# define GPIO_CLOCK_DIR_OUT (1 << 1) -# define GPIO_CLOCK_VAL_MASK (1 << 2) -# define GPIO_CLOCK_VAL_OUT (1 << 3) -# define GPIO_CLOCK_VAL_IN (1 << 4) -# define GPIO_CLOCK_PULLUP_DISABLE (1 << 5) -# define GPIO_DATA_DIR_MASK (1 << 8) -# define GPIO_DATA_DIR_IN (0 << 9) -# define GPIO_DATA_DIR_OUT (1 << 9) -# define GPIO_DATA_VAL_MASK (1 << 10) -# define GPIO_DATA_VAL_OUT (1 << 11) -# define GPIO_DATA_VAL_IN (1 << 12) -# define GPIO_DATA_PULLUP_DISABLE (1 << 13) - -/* - * Clock control & power management - */ - -#define VGA0 0x6000 -#define VGA1 0x6004 -#define VGA_PD 0x6010 -#define VGA0_PD_P2_DIV_4 (1 << 7) -#define VGA0_PD_P1_DIV_2 (1 << 5) -#define VGA0_PD_P1_SHIFT 0 -#define VGA0_PD_P1_MASK (0x1f << 0) -#define VGA1_PD_P2_DIV_4 (1 << 15) -#define VGA1_PD_P1_DIV_2 (1 << 13) -#define VGA1_PD_P1_SHIFT 8 -#define VGA1_PD_P1_MASK (0x1f << 8) -#define DPLL_A 0x06014 -#define DPLL_B 0x06018 -#define DPLL_VCO_ENABLE (1 << 31) -#define DPLL_DVO_HIGH_SPEED (1 << 30) -#define DPLL_SYNCLOCK_ENABLE (1 << 29) -#define DPLL_VGA_MODE_DIS (1 << 28) -#define DPLLB_MODE_DAC_SERIAL (1 << 26) /* i915 */ -#define DPLLB_MODE_LVDS (2 << 26) /* i915 */ -#define DPLL_MODE_MASK (3 << 26) -#define DPLL_DAC_SERIAL_P2_CLOCK_DIV_10 (0 << 24) /* i915 */ -#define DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 (1 << 24) /* i915 */ -#define DPLLB_LVDS_P2_CLOCK_DIV_14 (0 << 24) /* i915 */ -#define DPLLB_LVDS_P2_CLOCK_DIV_7 (1 << 24) /* i915 */ -#define DPLL_P2_CLOCK_DIV_MASK 0x03000000 /* i915 */ -#define DPLL_FPA01_P1_POST_DIV_MASK 0x00ff0000 /* i915 */ - -#define I915_FIFO_UNDERRUN_STATUS (1UL<<31) -#define I915_CRC_ERROR_ENABLE (1UL<<29) -#define I915_CRC_DONE_ENABLE (1UL<<28) -#define I915_GMBUS_EVENT_ENABLE (1UL<<27) -#define I915_VSYNC_INTERRUPT_ENABLE (1UL<<25) -#define I915_DISPLAY_LINE_COMPARE_ENABLE (1UL<<24) -#define I915_DPST_EVENT_ENABLE (1UL<<23) -#define I915_LEGACY_BLC_EVENT_ENABLE (1UL<<22) -#define I915_ODD_FIELD_INTERRUPT_ENABLE (1UL<<21) -#define I915_EVEN_FIELD_INTERRUPT_ENABLE (1UL<<20) -#define I915_START_VBLANK_INTERRUPT_ENABLE (1UL<<18) /* 965 or later */ -#define I915_VBLANK_INTERRUPT_ENABLE (1UL<<17) -#define I915_OVERLAY_UPDATED_ENABLE (1UL<<16) -#define I915_CRC_ERROR_INTERRUPT_STATUS (1UL<<13) -#define I915_CRC_DONE_INTERRUPT_STATUS (1UL<<12) -#define I915_GMBUS_INTERRUPT_STATUS (1UL<<11) -#define I915_VSYNC_INTERRUPT_STATUS (1UL<<9) -#define I915_DISPLAY_LINE_COMPARE_STATUS (1UL<<8) -#define I915_DPST_EVENT_STATUS (1UL<<7) -#define I915_LEGACY_BLC_EVENT_STATUS (1UL<<6) -#define I915_ODD_FIELD_INTERRUPT_STATUS (1UL<<5) -#define I915_EVEN_FIELD_INTERRUPT_STATUS (1UL<<4) -#define I915_START_VBLANK_INTERRUPT_STATUS (1UL<<2) /* 965 or later */ -#define I915_VBLANK_INTERRUPT_STATUS (1UL<<1) -#define I915_OVERLAY_UPDATED_STATUS (1UL<<0) - -#define SRX_INDEX 0x3c4 -#define SRX_DATA 0x3c5 -#define SR01 1 -#define SR01_SCREEN_OFF (1<<5) - -#define PPCR 0x61204 -#define PPCR_ON (1<<0) - -#define DVOB 0x61140 -#define DVOB_ON (1<<31) -#define DVOC 0x61160 -#define DVOC_ON (1<<31) -#define LVDS 0x61180 -#define LVDS_ON (1<<31) - -#define ADPA 0x61100 -#define ADPA_DPMS_MASK (~(3<<10)) -#define ADPA_DPMS_ON (0<<10) -#define ADPA_DPMS_SUSPEND (1<<10) -#define ADPA_DPMS_STANDBY (2<<10) -#define ADPA_DPMS_OFF (3<<10) - -#define RING_TAIL 0x00 -#define TAIL_ADDR 0x001FFFF8 -#define RING_HEAD 0x04 -#define HEAD_WRAP_COUNT 0xFFE00000 -#define HEAD_WRAP_ONE 0x00200000 -#define HEAD_ADDR 0x001FFFFC -#define RING_START 0x08 -#define START_ADDR 0xFFFFF000 -#define RING_LEN 0x0C -#define RING_NR_PAGES 0x001FF000 -#define RING_REPORT_MASK 0x00000006 -#define RING_REPORT_64K 0x00000002 -#define RING_REPORT_128K 0x00000004 -#define RING_NO_REPORT 0x00000000 -#define RING_VALID_MASK 0x00000001 -#define RING_VALID 0x00000001 -#define RING_INVALID 0x00000000 - -/* Scratch pad debug 0 reg: - */ -#define DPLL_FPA01_P1_POST_DIV_MASK_I830 0x001f0000 -/* - * The i830 generation, in LVDS mode, defines P1 as the bit number set within - * this field (only one bit may be set). - */ -#define DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS 0x003f0000 -#define DPLL_FPA01_P1_POST_DIV_SHIFT 16 -/* i830, required in DVO non-gang */ -#define PLL_P2_DIVIDE_BY_4 (1 << 23) -#define PLL_P1_DIVIDE_BY_TWO (1 << 21) /* i830 */ -#define PLL_REF_INPUT_DREFCLK (0 << 13) -#define PLL_REF_INPUT_TVCLKINA (1 << 13) /* i830 */ -#define PLL_REF_INPUT_TVCLKINBC (2 << 13) /* SDVO TVCLKIN */ -#define PLLB_REF_INPUT_SPREADSPECTRUMIN (3 << 13) -#define PLL_REF_INPUT_MASK (3 << 13) -#define PLL_LOAD_PULSE_PHASE_SHIFT 9 -/* - * Parallel to Serial Load Pulse phase selection. - * Selects the phase for the 10X DPLL clock for the PCIe - * digital display port. The range is 4 to 13; 10 or more - * is just a flip delay. The default is 6 - */ -#define PLL_LOAD_PULSE_PHASE_MASK (0xf << PLL_LOAD_PULSE_PHASE_SHIFT) -#define DISPLAY_RATE_SELECT_FPA1 (1 << 8) -/* - * SDVO multiplier for 945G/GM. Not used on 965. - */ -#define SDVO_MULTIPLIER_MASK 0x000000ff -#define SDVO_MULTIPLIER_SHIFT_HIRES 4 -#define SDVO_MULTIPLIER_SHIFT_VGA 0 -#define DPLL_A_MD 0x0601c /* 965+ only */ -/* - * UDI pixel divider, controlling how many pixels are stuffed into a packet. - * - * Value is pixels minus 1. Must be set to 1 pixel for SDVO. - */ -#define DPLL_MD_UDI_DIVIDER_MASK 0x3f000000 -#define DPLL_MD_UDI_DIVIDER_SHIFT 24 -/* UDI pixel divider for VGA, same as DPLL_MD_UDI_DIVIDER_MASK. */ -#define DPLL_MD_VGA_UDI_DIVIDER_MASK 0x003f0000 -#define DPLL_MD_VGA_UDI_DIVIDER_SHIFT 16 -/* - * SDVO/UDI pixel multiplier. - * - * SDVO requires that the bus clock rate be between 1 and 2 Ghz, and the bus - * clock rate is 10 times the DPLL clock. At low resolution/refresh rate - * modes, the bus rate would be below the limits, so SDVO allows for stuffing - * dummy bytes in the datastream at an increased clock rate, with both sides of - * the link knowing how many bytes are fill. - * - * So, for a mode with a dotclock of 65Mhz, we would want to double the clock - * rate to 130Mhz to get a bus rate of 1.30Ghz. The DPLL clock rate would be - * set to 130Mhz, and the SDVO multiplier set to 2x in this register and - * through an SDVO command. - * - * This register field has values of multiplication factor minus 1, with - * a maximum multiplier of 5 for SDVO. - */ -#define DPLL_MD_UDI_MULTIPLIER_MASK 0x00003f00 -#define DPLL_MD_UDI_MULTIPLIER_SHIFT 8 -/* - * SDVO/UDI pixel multiplier for VGA, same as DPLL_MD_UDI_MULTIPLIER_MASK. - * This best be set to the default value (3) or the CRT won't work. No, - * I don't entirely understand what this does... - */ -#define DPLL_MD_VGA_UDI_MULTIPLIER_MASK 0x0000003f -#define DPLL_MD_VGA_UDI_MULTIPLIER_SHIFT 0 -#define DPLL_B_MD 0x06020 /* 965+ only */ -#define FPA0 0x06040 -#define FPA1 0x06044 -#define FPB0 0x06048 -#define FPB1 0x0604c -#define FP_N_DIV_MASK 0x003f0000 -#define FP_N_DIV_SHIFT 16 -#define FP_M1_DIV_MASK 0x00003f00 -#define FP_M1_DIV_SHIFT 8 -#define FP_M2_DIV_MASK 0x0000003f -#define FP_M2_DIV_SHIFT 0 -#define DPLL_TEST 0x606c -#define DPLLB_TEST_SDVO_DIV_1 (0 << 22) -#define DPLLB_TEST_SDVO_DIV_2 (1 << 22) -#define DPLLB_TEST_SDVO_DIV_4 (2 << 22) -#define DPLLB_TEST_SDVO_DIV_MASK (3 << 22) -#define DPLLB_TEST_N_BYPASS (1 << 19) -#define DPLLB_TEST_M_BYPASS (1 << 18) -#define DPLLB_INPUT_BUFFER_ENABLE (1 << 16) -#define DPLLA_TEST_N_BYPASS (1 << 3) -#define DPLLA_TEST_M_BYPASS (1 << 2) -#define DPLLA_INPUT_BUFFER_ENABLE (1 << 0) -#define D_STATE 0x6104 -#define CG_2D_DIS 0x6200 -#define CG_3D_DIS 0x6204 - -/* - * Palette regs - */ - -#define PALETTE_A 0x0a000 -#define PALETTE_B 0x0a800 - -/* MCH MMIO space */ - -/* - * MCHBAR mirror. - * - * This mirrors the MCHBAR MMIO space whose location is determined by - * device 0 function 0's pci config register 0x44 or 0x48 and matches it in - * every way. It is not accessible from the CP register read instructions. - * - */ -#define MCHBAR_MIRROR_BASE 0x10000 - -/** 915-945 and GM965 MCH register controlling DRAM channel access */ -#define DCC 0x10200 -#define DCC_ADDRESSING_MODE_SINGLE_CHANNEL (0 << 0) -#define DCC_ADDRESSING_MODE_DUAL_CHANNEL_ASYMMETRIC (1 << 0) -#define DCC_ADDRESSING_MODE_DUAL_CHANNEL_INTERLEAVED (2 << 0) -#define DCC_ADDRESSING_MODE_MASK (3 << 0) -#define DCC_CHANNEL_XOR_DISABLE (1 << 10) - -/** 965 MCH register controlling DRAM channel configuration */ -#define C0DRB3 0x10206 -#define C1DRB3 0x10606 - -/* - * Overlay regs - */ - -#define OVADD 0x30000 -#define DOVSTA 0x30008 -#define OC_BUF (0x3<<20) -#define OGAMC5 0x30010 -#define OGAMC4 0x30014 -#define OGAMC3 0x30018 -#define OGAMC2 0x3001c -#define OGAMC1 0x30020 -#define OGAMC0 0x30024 - -/* - * Display engine regs - */ - -/* Pipe A timing regs */ -#define HTOTAL_A 0x60000 -#define HBLANK_A 0x60004 -#define HSYNC_A 0x60008 -#define VTOTAL_A 0x6000c -#define VBLANK_A 0x60010 -#define VSYNC_A 0x60014 -#define PIPEASRC 0x6001c -#define BCLRPAT_A 0x60020 - -/* Pipe B timing regs */ -#define HTOTAL_B 0x61000 -#define HBLANK_B 0x61004 -#define HSYNC_B 0x61008 -#define VTOTAL_B 0x6100c -#define VBLANK_B 0x61010 -#define VSYNC_B 0x61014 -#define PIPEBSRC 0x6101c -#define BCLRPAT_B 0x61020 - -/* VGA port control */ -#define ADPA 0x61100 -#define ADPA_DAC_ENABLE (1<<31) -#define ADPA_DAC_DISABLE 0 -#define ADPA_PIPE_SELECT_MASK (1<<30) -#define ADPA_PIPE_A_SELECT 0 -#define ADPA_PIPE_B_SELECT (1<<30) -#define ADPA_USE_VGA_HVPOLARITY (1<<15) -#define ADPA_SETS_HVPOLARITY 0 -#define ADPA_VSYNC_CNTL_DISABLE (1<<11) -#define ADPA_VSYNC_CNTL_ENABLE 0 -#define ADPA_HSYNC_CNTL_DISABLE (1<<10) -#define ADPA_HSYNC_CNTL_ENABLE 0 -#define ADPA_VSYNC_ACTIVE_HIGH (1<<4) -#define ADPA_VSYNC_ACTIVE_LOW 0 -#define ADPA_HSYNC_ACTIVE_HIGH (1<<3) -#define ADPA_HSYNC_ACTIVE_LOW 0 -#define ADPA_DPMS_MASK (~(3<<10)) -#define ADPA_DPMS_ON (0<<10) -#define ADPA_DPMS_SUSPEND (1<<10) -#define ADPA_DPMS_STANDBY (2<<10) -#define ADPA_DPMS_OFF (3<<10) - -/* Hotplug control (945+ only) */ -#define PORT_HOTPLUG_EN 0x61110 -#define SDVOB_HOTPLUG_INT_EN (1 << 26) -#define SDVOC_HOTPLUG_INT_EN (1 << 25) -#define TV_HOTPLUG_INT_EN (1 << 18) -#define CRT_HOTPLUG_INT_EN (1 << 9) -#define CRT_HOTPLUG_FORCE_DETECT (1 << 3) - -#define PORT_HOTPLUG_STAT 0x61114 -#define CRT_HOTPLUG_INT_STATUS (1 << 11) -#define TV_HOTPLUG_INT_STATUS (1 << 10) -#define CRT_HOTPLUG_MONITOR_MASK (3 << 8) -#define CRT_HOTPLUG_MONITOR_COLOR (3 << 8) -#define CRT_HOTPLUG_MONITOR_MONO (2 << 8) -#define CRT_HOTPLUG_MONITOR_NONE (0 << 8) -#define SDVOC_HOTPLUG_INT_STATUS (1 << 7) -#define SDVOB_HOTPLUG_INT_STATUS (1 << 6) - -/* SDVO port control */ -#define SDVOB 0x61140 -#define SDVOC 0x61160 -#define SDVO_ENABLE (1 << 31) -#define SDVO_PIPE_B_SELECT (1 << 30) -#define SDVO_STALL_SELECT (1 << 29) -#define SDVO_INTERRUPT_ENABLE (1 << 26) -/** - * 915G/GM SDVO pixel multiplier. - * - * Programmed value is multiplier - 1, up to 5x. - * - * \sa DPLL_MD_UDI_MULTIPLIER_MASK - */ -#define SDVO_PORT_MULTIPLY_MASK (7 << 23) -#define SDVO_PORT_MULTIPLY_SHIFT 23 -#define SDVO_PHASE_SELECT_MASK (15 << 19) -#define SDVO_PHASE_SELECT_DEFAULT (6 << 19) -#define SDVO_CLOCK_OUTPUT_INVERT (1 << 18) -#define SDVOC_GANG_MODE (1 << 16) -#define SDVO_BORDER_ENABLE (1 << 7) -#define SDVOB_PCIE_CONCURRENCY (1 << 3) -#define SDVO_DETECTED (1 << 2) -/* Bits to be preserved when writing */ -#define SDVOB_PRESERVE_MASK ((1 << 17) | (1 << 16) | (1 << 14) | (1 << 26)) -#define SDVOC_PRESERVE_MASK ((1 << 17) | (1 << 26)) - -/* DVO port control */ -#define DVOA 0x61120 -#define DVOB 0x61140 -#define DVOC 0x61160 -#define DVO_ENABLE (1 << 31) -#define DVO_PIPE_B_SELECT (1 << 30) -#define DVO_PIPE_STALL_UNUSED (0 << 28) -#define DVO_PIPE_STALL (1 << 28) -#define DVO_PIPE_STALL_TV (2 << 28) -#define DVO_PIPE_STALL_MASK (3 << 28) -#define DVO_USE_VGA_SYNC (1 << 15) -#define DVO_DATA_ORDER_I740 (0 << 14) -#define DVO_DATA_ORDER_FP (1 << 14) -#define DVO_VSYNC_DISABLE (1 << 11) -#define DVO_HSYNC_DISABLE (1 << 10) -#define DVO_VSYNC_TRISTATE (1 << 9) -#define DVO_HSYNC_TRISTATE (1 << 8) -#define DVO_BORDER_ENABLE (1 << 7) -#define DVO_DATA_ORDER_GBRG (1 << 6) -#define DVO_DATA_ORDER_RGGB (0 << 6) -#define DVO_DATA_ORDER_GBRG_ERRATA (0 << 6) -#define DVO_DATA_ORDER_RGGB_ERRATA (1 << 6) -#define DVO_VSYNC_ACTIVE_HIGH (1 << 4) -#define DVO_HSYNC_ACTIVE_HIGH (1 << 3) -#define DVO_BLANK_ACTIVE_HIGH (1 << 2) -#define DVO_OUTPUT_CSTATE_PIXELS (1 << 1) /* SDG only */ -#define DVO_OUTPUT_SOURCE_SIZE_PIXELS (1 << 0) /* SDG only */ -#define DVO_PRESERVE_MASK (0x7<<24) -#define DVOA_SRCDIM 0x61124 -#define DVOB_SRCDIM 0x61144 -#define DVOC_SRCDIM 0x61164 -#define DVO_SRCDIM_HORIZONTAL_SHIFT 12 -#define DVO_SRCDIM_VERTICAL_SHIFT 0 - -/* LVDS port control */ -#define LVDS 0x61180 -/* - * Enables the LVDS port. This bit must be set before DPLLs are enabled, as - * the DPLL semantics change when the LVDS is assigned to that pipe. - */ -#define LVDS_PORT_EN (1 << 31) -/* Selects pipe B for LVDS data. Must be set on pre-965. */ -#define LVDS_PIPEB_SELECT (1 << 30) -/* - * Enables the A0-A2 data pairs and CLKA, containing 18 bits of color data per - * pixel. - */ -#define LVDS_A0A2_CLKA_POWER_MASK (3 << 8) -#define LVDS_A0A2_CLKA_POWER_DOWN (0 << 8) -#define LVDS_A0A2_CLKA_POWER_UP (3 << 8) -/* - * Controls the A3 data pair, which contains the additional LSBs for 24 bit - * mode. Only enabled if LVDS_A0A2_CLKA_POWER_UP also indicates it should be - * on. - */ -#define LVDS_A3_POWER_MASK (3 << 6) -#define LVDS_A3_POWER_DOWN (0 << 6) -#define LVDS_A3_POWER_UP (3 << 6) -/* - * Controls the CLKB pair. This should only be set when LVDS_B0B3_POWER_UP - * is set. - */ -#define LVDS_CLKB_POWER_MASK (3 << 4) -#define LVDS_CLKB_POWER_DOWN (0 << 4) -#define LVDS_CLKB_POWER_UP (3 << 4) -/* - * Controls the B0-B3 data pairs. This must be set to match the DPLL p2 - * setting for whether we are in dual-channel mode. The B3 pair will - * additionally only be powered up when LVDS_A3_POWER_UP is set. - */ -#define LVDS_B0B3_POWER_MASK (3 << 2) -#define LVDS_B0B3_POWER_DOWN (0 << 2) -#define LVDS_B0B3_POWER_UP (3 << 2) - -/* Panel power sequencing */ -#define PP_STATUS 0x61200 -#define PP_ON (1 << 31) -/* - * Indicates that all dependencies of the panel are on: - * - * - PLL enabled - * - pipe enabled - * - LVDS/DVOB/DVOC on - */ -#define PP_READY (1 << 30) -#define PP_SEQUENCE_NONE (0 << 28) -#define PP_SEQUENCE_ON (1 << 28) -#define PP_SEQUENCE_OFF (2 << 28) -#define PP_SEQUENCE_MASK 0x30000000 -#define PP_CONTROL 0x61204 -#define POWER_TARGET_ON (1 << 0) -#define PP_ON_DELAYS 0x61208 -#define PP_OFF_DELAYS 0x6120c -#define PP_DIVISOR 0x61210 - -/* Panel fitting */ -#define PFIT_CONTROL 0x61230 -#define PFIT_ENABLE (1 << 31) -#define PFIT_PIPE_MASK (3 << 29) -#define PFIT_PIPE_SHIFT 29 -#define VERT_INTERP_DISABLE (0 << 10) -#define VERT_INTERP_BILINEAR (1 << 10) -#define VERT_INTERP_MASK (3 << 10) -#define VERT_AUTO_SCALE (1 << 9) -#define HORIZ_INTERP_DISABLE (0 << 6) -#define HORIZ_INTERP_BILINEAR (1 << 6) -#define HORIZ_INTERP_MASK (3 << 6) -#define HORIZ_AUTO_SCALE (1 << 5) -#define PANEL_8TO6_DITHER_ENABLE (1 << 3) -#define PFIT_PGM_RATIOS 0x61234 -#define PFIT_VERT_SCALE_MASK 0xfff00000 -#define PFIT_HORIZ_SCALE_MASK 0x0000fff0 -#define PFIT_AUTO_RATIOS 0x61238 - -/* Backlight control */ -#define BLC_PWM_CTL 0x61254 -#define BACKLIGHT_MODULATION_FREQ_SHIFT (17) -#define BLC_PWM_CTL2 0x61250 /* 965+ only */ -#define BLM_COMBINATION_MODE (1 << 30) -/* - * This is the most significant 15 bits of the number of backlight cycles in a - * complete cycle of the modulated backlight control. - * - * The actual value is this field multiplied by two. - */ -#define BACKLIGHT_MODULATION_FREQ_MASK (0x7fff << 17) -#define BLM_LEGACY_MODE (1 << 16) -/* - * This is the number of cycles out of the backlight modulation cycle for which - * the backlight is on. - * - * This field must be no greater than the number of cycles in the complete - * backlight modulation cycle. - */ -#define BACKLIGHT_DUTY_CYCLE_SHIFT (0) -#define BACKLIGHT_DUTY_CYCLE_MASK (0xffff) - -/* TV port control */ -#define TV_CTL 0x68000 -/** Enables the TV encoder */ -# define TV_ENC_ENABLE (1 << 31) -/** Sources the TV encoder input from pipe B instead of A. */ -# define TV_ENC_PIPEB_SELECT (1 << 30) -/** Outputs composite video (DAC A only) */ -# define TV_ENC_OUTPUT_COMPOSITE (0 << 28) -/** Outputs SVideo video (DAC B/C) */ -# define TV_ENC_OUTPUT_SVIDEO (1 << 28) -/** Outputs Component video (DAC A/B/C) */ -# define TV_ENC_OUTPUT_COMPONENT (2 << 28) -/** Outputs Composite and SVideo (DAC A/B/C) */ -# define TV_ENC_OUTPUT_SVIDEO_COMPOSITE (3 << 28) -# define TV_TRILEVEL_SYNC (1 << 21) -/** Enables slow sync generation (945GM only) */ -# define TV_SLOW_SYNC (1 << 20) -/** Selects 4x oversampling for 480i and 576p */ -# define TV_OVERSAMPLE_4X (0 << 18) -/** Selects 2x oversampling for 720p and 1080i */ -# define TV_OVERSAMPLE_2X (1 << 18) -/** Selects no oversampling for 1080p */ -# define TV_OVERSAMPLE_NONE (2 << 18) -/** Selects 8x oversampling */ -# define TV_OVERSAMPLE_8X (3 << 18) -/** Selects progressive mode rather than interlaced */ -# define TV_PROGRESSIVE (1 << 17) -/** Sets the colorburst to PAL mode. Required for non-M PAL modes. */ -# define TV_PAL_BURST (1 << 16) -/** Field for setting delay of Y compared to C */ -# define TV_YC_SKEW_MASK (7 << 12) -/** Enables a fix for 480p/576p standard definition modes on the 915GM only */ -# define TV_ENC_SDP_FIX (1 << 11) -/** - * Enables a fix for the 915GM only. - * - * Not sure what it does. - */ -# define TV_ENC_C0_FIX (1 << 10) -/** Bits that must be preserved by software */ -# define TV_CTL_SAVE ((3 << 8) | (3 << 6)) -# define TV_FUSE_STATE_MASK (3 << 4) -/** Read-only state that reports all features enabled */ -# define TV_FUSE_STATE_ENABLED (0 << 4) -/** Read-only state that reports that Macrovision is disabled in hardware*/ -# define TV_FUSE_STATE_NO_MACROVISION (1 << 4) -/** Read-only state that reports that TV-out is disabled in hardware. */ -# define TV_FUSE_STATE_DISABLED (2 << 4) -/** Normal operation */ -# define TV_TEST_MODE_NORMAL (0 << 0) -/** Encoder test pattern 1 - combo pattern */ -# define TV_TEST_MODE_PATTERN_1 (1 << 0) -/** Encoder test pattern 2 - full screen vertical 75% color bars */ -# define TV_TEST_MODE_PATTERN_2 (2 << 0) -/** Encoder test pattern 3 - full screen horizontal 75% color bars */ -# define TV_TEST_MODE_PATTERN_3 (3 << 0) -/** Encoder test pattern 4 - random noise */ -# define TV_TEST_MODE_PATTERN_4 (4 << 0) -/** Encoder test pattern 5 - linear color ramps */ -# define TV_TEST_MODE_PATTERN_5 (5 << 0) -/** - * This test mode forces the DACs to 50% of full output. - * - * This is used for load detection in combination with TVDAC_SENSE_MASK - */ -# define TV_TEST_MODE_MONITOR_DETECT (7 << 0) -# define TV_TEST_MODE_MASK (7 << 0) - -#define TV_DAC 0x68004 -/** - * Reports that DAC state change logic has reported change (RO). - * - * This gets cleared when TV_DAC_STATE_EN is cleared -*/ -# define TVDAC_STATE_CHG (1 << 31) -# define TVDAC_SENSE_MASK (7 << 28) -/** Reports that DAC A voltage is above the detect threshold */ -# define TVDAC_A_SENSE (1 << 30) -/** Reports that DAC B voltage is above the detect threshold */ -# define TVDAC_B_SENSE (1 << 29) -/** Reports that DAC C voltage is above the detect threshold */ -# define TVDAC_C_SENSE (1 << 28) -/** - * Enables DAC state detection logic, for load-based TV detection. - * - * The PLL of the chosen pipe (in TV_CTL) must be running, and the encoder set - * to off, for load detection to work. - */ -# define TVDAC_STATE_CHG_EN (1 << 27) -/** Sets the DAC A sense value to high */ -# define TVDAC_A_SENSE_CTL (1 << 26) -/** Sets the DAC B sense value to high */ -# define TVDAC_B_SENSE_CTL (1 << 25) -/** Sets the DAC C sense value to high */ -# define TVDAC_C_SENSE_CTL (1 << 24) -/** Overrides the ENC_ENABLE and DAC voltage levels */ -# define DAC_CTL_OVERRIDE (1 << 7) -/** Sets the slew rate. Must be preserved in software */ -# define ENC_TVDAC_SLEW_FAST (1 << 6) -# define DAC_A_1_3_V (0 << 4) -# define DAC_A_1_1_V (1 << 4) -# define DAC_A_0_7_V (2 << 4) -# define DAC_A_OFF (3 << 4) -# define DAC_B_1_3_V (0 << 2) -# define DAC_B_1_1_V (1 << 2) -# define DAC_B_0_7_V (2 << 2) -# define DAC_B_OFF (3 << 2) -# define DAC_C_1_3_V (0 << 0) -# define DAC_C_1_1_V (1 << 0) -# define DAC_C_0_7_V (2 << 0) -# define DAC_C_OFF (3 << 0) - -/** - * CSC coefficients are stored in a floating point format with 9 bits of - * mantissa and 2 or 3 bits of exponent. The exponent is represented as 2**-n, - * where 2-bit exponents are unsigned n, and 3-bit exponents are signed n with - * -1 (0x3) being the only legal negative value. - */ -#define TV_CSC_Y 0x68010 -# define TV_RY_MASK 0x07ff0000 -# define TV_RY_SHIFT 16 -# define TV_GY_MASK 0x00000fff -# define TV_GY_SHIFT 0 - -#define TV_CSC_Y2 0x68014 -# define TV_BY_MASK 0x07ff0000 -# define TV_BY_SHIFT 16 -/** - * Y attenuation for component video. - * - * Stored in 1.9 fixed point. - */ -# define TV_AY_MASK 0x000003ff -# define TV_AY_SHIFT 0 - -#define TV_CSC_U 0x68018 -# define TV_RU_MASK 0x07ff0000 -# define TV_RU_SHIFT 16 -# define TV_GU_MASK 0x000007ff -# define TV_GU_SHIFT 0 - -#define TV_CSC_U2 0x6801c -# define TV_BU_MASK 0x07ff0000 -# define TV_BU_SHIFT 16 -/** - * U attenuation for component video. - * - * Stored in 1.9 fixed point. - */ -# define TV_AU_MASK 0x000003ff -# define TV_AU_SHIFT 0 - -#define TV_CSC_V 0x68020 -# define TV_RV_MASK 0x0fff0000 -# define TV_RV_SHIFT 16 -# define TV_GV_MASK 0x000007ff -# define TV_GV_SHIFT 0 - -#define TV_CSC_V2 0x68024 -# define TV_BV_MASK 0x07ff0000 -# define TV_BV_SHIFT 16 -/** - * V attenuation for component video. - * - * Stored in 1.9 fixed point. - */ -# define TV_AV_MASK 0x000007ff -# define TV_AV_SHIFT 0 - -#define TV_CLR_KNOBS 0x68028 -/** 2s-complement brightness adjustment */ -# define TV_BRIGHTNESS_MASK 0xff000000 -# define TV_BRIGHTNESS_SHIFT 24 -/** Contrast adjustment, as a 2.6 unsigned floating point number */ -# define TV_CONTRAST_MASK 0x00ff0000 -# define TV_CONTRAST_SHIFT 16 -/** Saturation adjustment, as a 2.6 unsigned floating point number */ -# define TV_SATURATION_MASK 0x0000ff00 -# define TV_SATURATION_SHIFT 8 -/** Hue adjustment, as an integer phase angle in degrees */ -# define TV_HUE_MASK 0x000000ff -# define TV_HUE_SHIFT 0 - -#define TV_CLR_LEVEL 0x6802c -/** Controls the DAC level for black */ -# define TV_BLACK_LEVEL_MASK 0x01ff0000 -# define TV_BLACK_LEVEL_SHIFT 16 -/** Controls the DAC level for blanking */ -# define TV_BLANK_LEVEL_MASK 0x000001ff -# define TV_BLANK_LEVEL_SHIFT 0 - -#define TV_H_CTL_1 0x68030 -/** Number of pixels in the hsync. */ -# define TV_HSYNC_END_MASK 0x1fff0000 -# define TV_HSYNC_END_SHIFT 16 -/** Total number of pixels minus one in the line (display and blanking). */ -# define TV_HTOTAL_MASK 0x00001fff -# define TV_HTOTAL_SHIFT 0 - -#define TV_H_CTL_2 0x68034 -/** Enables the colorburst (needed for non-component color) */ -# define TV_BURST_ENA (1 << 31) -/** Offset of the colorburst from the start of hsync, in pixels minus one. */ -# define TV_HBURST_START_SHIFT 16 -# define TV_HBURST_START_MASK 0x1fff0000 -/** Length of the colorburst */ -# define TV_HBURST_LEN_SHIFT 0 -# define TV_HBURST_LEN_MASK 0x0001fff - -#define TV_H_CTL_3 0x68038 -/** End of hblank, measured in pixels minus one from start of hsync */ -# define TV_HBLANK_END_SHIFT 16 -# define TV_HBLANK_END_MASK 0x1fff0000 -/** Start of hblank, measured in pixels minus one from start of hsync */ -# define TV_HBLANK_START_SHIFT 0 -# define TV_HBLANK_START_MASK 0x0001fff - -#define TV_V_CTL_1 0x6803c -/** XXX */ -# define TV_NBR_END_SHIFT 16 -# define TV_NBR_END_MASK 0x07ff0000 -/** XXX */ -# define TV_VI_END_F1_SHIFT 8 -# define TV_VI_END_F1_MASK 0x00003f00 -/** XXX */ -# define TV_VI_END_F2_SHIFT 0 -# define TV_VI_END_F2_MASK 0x0000003f - -#define TV_V_CTL_2 0x68040 -/** Length of vsync, in half lines */ -# define TV_VSYNC_LEN_MASK 0x07ff0000 -# define TV_VSYNC_LEN_SHIFT 16 -/** Offset of the start of vsync in field 1, measured in one less than the - * number of half lines. - */ -# define TV_VSYNC_START_F1_MASK 0x00007f00 -# define TV_VSYNC_START_F1_SHIFT 8 -/** - * Offset of the start of vsync in field 2, measured in one less than the - * number of half lines. - */ -# define TV_VSYNC_START_F2_MASK 0x0000007f -# define TV_VSYNC_START_F2_SHIFT 0 - -#define TV_V_CTL_3 0x68044 -/** Enables generation of the equalization signal */ -# define TV_EQUAL_ENA (1 << 31) -/** Length of vsync, in half lines */ -# define TV_VEQ_LEN_MASK 0x007f0000 -# define TV_VEQ_LEN_SHIFT 16 -/** Offset of the start of equalization in field 1, measured in one less than - * the number of half lines. - */ -# define TV_VEQ_START_F1_MASK 0x0007f00 -# define TV_VEQ_START_F1_SHIFT 8 -/** - * Offset of the start of equalization in field 2, measured in one less than - * the number of half lines. - */ -# define TV_VEQ_START_F2_MASK 0x000007f -# define TV_VEQ_START_F2_SHIFT 0 - -#define TV_V_CTL_4 0x68048 -/** - * Offset to start of vertical colorburst, measured in one less than the - * number of lines from vertical start. - */ -# define TV_VBURST_START_F1_MASK 0x003f0000 -# define TV_VBURST_START_F1_SHIFT 16 -/** - * Offset to the end of vertical colorburst, measured in one less than the - * number of lines from the start of NBR. - */ -# define TV_VBURST_END_F1_MASK 0x000000ff -# define TV_VBURST_END_F1_SHIFT 0 - -#define TV_V_CTL_5 0x6804c -/** - * Offset to start of vertical colorburst, measured in one less than the - * number of lines from vertical start. - */ -# define TV_VBURST_START_F2_MASK 0x003f0000 -# define TV_VBURST_START_F2_SHIFT 16 -/** - * Offset to the end of vertical colorburst, measured in one less than the - * number of lines from the start of NBR. - */ -# define TV_VBURST_END_F2_MASK 0x000000ff -# define TV_VBURST_END_F2_SHIFT 0 - -#define TV_V_CTL_6 0x68050 -/** - * Offset to start of vertical colorburst, measured in one less than the - * number of lines from vertical start. - */ -# define TV_VBURST_START_F3_MASK 0x003f0000 -# define TV_VBURST_START_F3_SHIFT 16 -/** - * Offset to the end of vertical colorburst, measured in one less than the - * number of lines from the start of NBR. - */ -# define TV_VBURST_END_F3_MASK 0x000000ff -# define TV_VBURST_END_F3_SHIFT 0 - -#define TV_V_CTL_7 0x68054 -/** - * Offset to start of vertical colorburst, measured in one less than the - * number of lines from vertical start. - */ -# define TV_VBURST_START_F4_MASK 0x003f0000 -# define TV_VBURST_START_F4_SHIFT 16 -/** - * Offset to the end of vertical colorburst, measured in one less than the - * number of lines from the start of NBR. - */ -# define TV_VBURST_END_F4_MASK 0x000000ff -# define TV_VBURST_END_F4_SHIFT 0 - -#define TV_SC_CTL_1 0x68060 -/** Turns on the first subcarrier phase generation DDA */ -# define TV_SC_DDA1_EN (1 << 31) -/** Turns on the first subcarrier phase generation DDA */ -# define TV_SC_DDA2_EN (1 << 30) -/** Turns on the first subcarrier phase generation DDA */ -# define TV_SC_DDA3_EN (1 << 29) -/** Sets the subcarrier DDA to reset frequency every other field */ -# define TV_SC_RESET_EVERY_2 (0 << 24) -/** Sets the subcarrier DDA to reset frequency every fourth field */ -# define TV_SC_RESET_EVERY_4 (1 << 24) -/** Sets the subcarrier DDA to reset frequency every eighth field */ -# define TV_SC_RESET_EVERY_8 (2 << 24) -/** Sets the subcarrier DDA to never reset the frequency */ -# define TV_SC_RESET_NEVER (3 << 24) -/** Sets the peak amplitude of the colorburst.*/ -# define TV_BURST_LEVEL_MASK 0x00ff0000 -# define TV_BURST_LEVEL_SHIFT 16 -/** Sets the increment of the first subcarrier phase generation DDA */ -# define TV_SCDDA1_INC_MASK 0x00000fff -# define TV_SCDDA1_INC_SHIFT 0 - -#define TV_SC_CTL_2 0x68064 -/** Sets the rollover for the second subcarrier phase generation DDA */ -# define TV_SCDDA2_SIZE_MASK 0x7fff0000 -# define TV_SCDDA2_SIZE_SHIFT 16 -/** Sets the increent of the second subcarrier phase generation DDA */ -# define TV_SCDDA2_INC_MASK 0x00007fff -# define TV_SCDDA2_INC_SHIFT 0 - -#define TV_SC_CTL_3 0x68068 -/** Sets the rollover for the third subcarrier phase generation DDA */ -# define TV_SCDDA3_SIZE_MASK 0x7fff0000 -# define TV_SCDDA3_SIZE_SHIFT 16 -/** Sets the increent of the third subcarrier phase generation DDA */ -# define TV_SCDDA3_INC_MASK 0x00007fff -# define TV_SCDDA3_INC_SHIFT 0 - -#define TV_WIN_POS 0x68070 -/** X coordinate of the display from the start of horizontal active */ -# define TV_XPOS_MASK 0x1fff0000 -# define TV_XPOS_SHIFT 16 -/** Y coordinate of the display from the start of vertical active (NBR) */ -# define TV_YPOS_MASK 0x00000fff -# define TV_YPOS_SHIFT 0 - -#define TV_WIN_SIZE 0x68074 -/** Horizontal size of the display window, measured in pixels*/ -# define TV_XSIZE_MASK 0x1fff0000 -# define TV_XSIZE_SHIFT 16 -/** - * Vertical size of the display window, measured in pixels. - * - * Must be even for interlaced modes. - */ -# define TV_YSIZE_MASK 0x00000fff -# define TV_YSIZE_SHIFT 0 - -#define TV_FILTER_CTL_1 0x68080 -/** - * Enables automatic scaling calculation. - * - * If set, the rest of the registers are ignored, and the calculated values can - * be read back from the register. - */ -# define TV_AUTO_SCALE (1 << 31) -/** - * Disables the vertical filter. - * - * This is required on modes more than 1024 pixels wide */ -# define TV_V_FILTER_BYPASS (1 << 29) -/** Enables adaptive vertical filtering */ -# define TV_VADAPT (1 << 28) -# define TV_VADAPT_MODE_MASK (3 << 26) -/** Selects the least adaptive vertical filtering mode */ -# define TV_VADAPT_MODE_LEAST (0 << 26) -/** Selects the moderately adaptive vertical filtering mode */ -# define TV_VADAPT_MODE_MODERATE (1 << 26) -/** Selects the most adaptive vertical filtering mode */ -# define TV_VADAPT_MODE_MOST (3 << 26) -/** - * Sets the horizontal scaling factor. - * - * This should be the fractional part of the horizontal scaling factor divided - * by the oversampling rate. TV_HSCALE should be less than 1, and set to: - * - * (src width - 1) / ((oversample * dest width) - 1) - */ -# define TV_HSCALE_FRAC_MASK 0x00003fff -# define TV_HSCALE_FRAC_SHIFT 0 - -#define TV_FILTER_CTL_2 0x68084 -/** - * Sets the integer part of the 3.15 fixed-point vertical scaling factor. - * - * TV_VSCALE should be (src height - 1) / ((interlace * dest height) - 1) - */ -# define TV_VSCALE_INT_MASK 0x00038000 -# define TV_VSCALE_INT_SHIFT 15 -/** - * Sets the fractional part of the 3.15 fixed-point vertical scaling factor. - * - * \sa TV_VSCALE_INT_MASK - */ -# define TV_VSCALE_FRAC_MASK 0x00007fff -# define TV_VSCALE_FRAC_SHIFT 0 - -#define TV_FILTER_CTL_3 0x68088 -/** - * Sets the integer part of the 3.15 fixed-point vertical scaling factor. - * - * TV_VSCALE should be (src height - 1) / (1/4 * (dest height - 1)) - * - * For progressive modes, TV_VSCALE_IP_INT should be set to zeroes. - */ -# define TV_VSCALE_IP_INT_MASK 0x00038000 -# define TV_VSCALE_IP_INT_SHIFT 15 -/** - * Sets the fractional part of the 3.15 fixed-point vertical scaling factor. - * - * For progressive modes, TV_VSCALE_IP_INT should be set to zeroes. - * - * \sa TV_VSCALE_IP_INT_MASK - */ -# define TV_VSCALE_IP_FRAC_MASK 0x00007fff -# define TV_VSCALE_IP_FRAC_SHIFT 0 - -#define TV_CC_CONTROL 0x68090 -# define TV_CC_ENABLE (1 << 31) -/** - * Specifies which field to send the CC data in. - * - * CC data is usually sent in field 0. - */ -# define TV_CC_FID_MASK (1 << 27) -# define TV_CC_FID_SHIFT 27 -/** Sets the horizontal position of the CC data. Usually 135. */ -# define TV_CC_HOFF_MASK 0x03ff0000 -# define TV_CC_HOFF_SHIFT 16 -/** Sets the vertical position of the CC data. Usually 21 */ -# define TV_CC_LINE_MASK 0x0000003f -# define TV_CC_LINE_SHIFT 0 - -#define TV_CC_DATA 0x68094 -# define TV_CC_RDY (1 << 31) -/** Second word of CC data to be transmitted. */ -# define TV_CC_DATA_2_MASK 0x007f0000 -# define TV_CC_DATA_2_SHIFT 16 -/** First word of CC data to be transmitted. */ -# define TV_CC_DATA_1_MASK 0x0000007f -# define TV_CC_DATA_1_SHIFT 0 - -#define TV_H_LUMA_0 0x68100 -#define TV_H_LUMA_59 0x681ec -#define TV_H_CHROMA_0 0x68200 -#define TV_H_CHROMA_59 0x682ec -#define TV_V_LUMA_0 0x68300 -#define TV_V_LUMA_42 0x683a8 -#define TV_V_CHROMA_0 0x68400 -#define TV_V_CHROMA_42 0x684a8 - -/* Display & cursor control */ - -/* Pipe A */ -#define PIPEADSL 0x70000 -#define PIPEACONF 0x70008 -#define PIPEACONF_ENABLE (1<<31) -#define PIPEACONF_DISABLE 0 -#define PIPEACONF_DOUBLE_WIDE (1<<30) -#define I965_PIPECONF_ACTIVE (1<<30) -#define PIPEACONF_SINGLE_WIDE 0 -#define PIPEACONF_PIPE_UNLOCKED 0 -#define PIPEACONF_PIPE_LOCKED (1<<25) -#define PIPEACONF_PALETTE 0 -#define PIPEACONF_GAMMA (1<<24) -#define PIPECONF_FORCE_BORDER (1<<25) -#define PIPECONF_PROGRESSIVE (0 << 21) -#define PIPECONF_INTERLACE_W_FIELD_INDICATION (6 << 21) -#define PIPECONF_INTERLACE_FIELD_0_ONLY (7 << 21) -#define PIPEASTAT 0x70024 -#define PIPE_FIFO_UNDERRUN_STATUS (1UL<<31) -#define PIPE_CRC_ERROR_ENABLE (1UL<<29) -#define PIPE_CRC_DONE_ENABLE (1UL<<28) -#define PIPE_GMBUS_EVENT_ENABLE (1UL<<27) -#define PIPE_HOTPLUG_INTERRUPT_ENABLE (1UL<<26) -#define PIPE_VSYNC_INTERRUPT_ENABLE (1UL<<25) -#define PIPE_DISPLAY_LINE_COMPARE_ENABLE (1UL<<24) -#define PIPE_DPST_EVENT_ENABLE (1UL<<23) -#define PIPE_LEGACY_BLC_EVENT_ENABLE (1UL<<22) -#define PIPE_ODD_FIELD_INTERRUPT_ENABLE (1UL<<21) -#define PIPE_EVEN_FIELD_INTERRUPT_ENABLE (1UL<<20) -#define PIPE_HOTPLUG_TV_INTERRUPT_ENABLE (1UL<<18) /* pre-965 */ -#define PIPE_START_VBLANK_INTERRUPT_ENABLE (1UL<<18) /* 965 or later */ -#define PIPE_VBLANK_INTERRUPT_ENABLE (1UL<<17) -#define PIPE_OVERLAY_UPDATED_ENABLE (1UL<<16) -#define PIPE_CRC_ERROR_INTERRUPT_STATUS (1UL<<13) -#define PIPE_CRC_DONE_INTERRUPT_STATUS (1UL<<12) -#define PIPE_GMBUS_INTERRUPT_STATUS (1UL<<11) -#define PIPE_HOTPLUG_INTERRUPT_STATUS (1UL<<10) -#define PIPE_VSYNC_INTERRUPT_STATUS (1UL<<9) -#define PIPE_DISPLAY_LINE_COMPARE_STATUS (1UL<<8) -#define PIPE_DPST_EVENT_STATUS (1UL<<7) -#define PIPE_LEGACY_BLC_EVENT_STATUS (1UL<<6) -#define PIPE_ODD_FIELD_INTERRUPT_STATUS (1UL<<5) -#define PIPE_EVEN_FIELD_INTERRUPT_STATUS (1UL<<4) -#define PIPE_HOTPLUG_TV_INTERRUPT_STATUS (1UL<<2) /* pre-965 */ -#define PIPE_START_VBLANK_INTERRUPT_STATUS (1UL<<2) /* 965 or later */ -#define PIPE_VBLANK_INTERRUPT_STATUS (1UL<<1) -#define PIPE_OVERLAY_UPDATED_STATUS (1UL<<0) - -#define DSPARB 0x70030 -#define DSPARB_CSTART_MASK (0x7f << 7) -#define DSPARB_CSTART_SHIFT 7 -#define DSPARB_BSTART_MASK (0x7f) -#define DSPARB_BSTART_SHIFT 0 -/* - * The two pipe frame counter registers are not synchronized, so - * reading a stable value is somewhat tricky. The following code - * should work: - * - * do { - * high1 = ((INREG(PIPEAFRAMEHIGH) & PIPE_FRAME_HIGH_MASK) >> - * PIPE_FRAME_HIGH_SHIFT; - * low1 = ((INREG(PIPEAFRAMEPIXEL) & PIPE_FRAME_LOW_MASK) >> - * PIPE_FRAME_LOW_SHIFT); - * high2 = ((INREG(PIPEAFRAMEHIGH) & PIPE_FRAME_HIGH_MASK) >> - * PIPE_FRAME_HIGH_SHIFT); - * } while (high1 != high2); - * frame = (high1 << 8) | low1; - */ -#define PIPEAFRAMEHIGH 0x70040 -#define PIPE_FRAME_HIGH_MASK 0x0000ffff -#define PIPE_FRAME_HIGH_SHIFT 0 -#define PIPEAFRAMEPIXEL 0x70044 -#define PIPE_FRAME_LOW_MASK 0xff000000 -#define PIPE_FRAME_LOW_SHIFT 24 -#define PIPE_PIXEL_MASK 0x00ffffff -#define PIPE_PIXEL_SHIFT 0 - -/* Cursor A & B regs */ -#define CURACNTR 0x70080 -#define CURSOR_MODE_DISABLE 0x00 -#define CURSOR_MODE_64_32B_AX 0x07 -#define CURSOR_MODE_64_ARGB_AX ((1 << 5) | CURSOR_MODE_64_32B_AX) -#define MCURSOR_GAMMA_ENABLE (1 << 26) -#define CURABASE 0x70084 -#define CURAPOS 0x70088 -#define CURSOR_POS_MASK 0x007FF -#define CURSOR_POS_SIGN 0x8000 -#define CURSOR_X_SHIFT 0 -#define CURSOR_Y_SHIFT 16 -#define CURBCNTR 0x700c0 -#define CURBBASE 0x700c4 -#define CURBPOS 0x700c8 - -/* Display A control */ -#define DSPACNTR 0x70180 -#define DISPLAY_PLANE_ENABLE (1<<31) -#define DISPLAY_PLANE_DISABLE 0 -#define DISPPLANE_GAMMA_ENABLE (1<<30) -#define DISPPLANE_GAMMA_DISABLE 0 -#define DISPPLANE_PIXFORMAT_MASK (0xf<<26) -#define DISPPLANE_8BPP (0x2<<26) -#define DISPPLANE_15_16BPP (0x4<<26) -#define DISPPLANE_16BPP (0x5<<26) -#define DISPPLANE_32BPP_NO_ALPHA (0x6<<26) -#define DISPPLANE_32BPP (0x7<<26) -#define DISPPLANE_STEREO_ENABLE (1<<25) -#define DISPPLANE_STEREO_DISABLE 0 -#define DISPPLANE_SEL_PIPE_MASK (1<<24) -#define DISPPLANE_SEL_PIPE_A 0 -#define DISPPLANE_SEL_PIPE_B (1<<24) -#define DISPPLANE_SRC_KEY_ENABLE (1<<22) -#define DISPPLANE_SRC_KEY_DISABLE 0 -#define DISPPLANE_LINE_DOUBLE (1<<20) -#define DISPPLANE_NO_LINE_DOUBLE 0 -#define DISPPLANE_STEREO_POLARITY_FIRST 0 -#define DISPPLANE_STEREO_POLARITY_SECOND (1<<18) -#define DSPAADDR 0x70184 -#define DSPASTRIDE 0x70188 -#define DSPAPOS 0x7018C /* reserved */ -#define DSPASIZE 0x70190 -#define DSPASURF 0x7019C /* 965+ only */ -#define DSPATILEOFF 0x701A4 /* 965+ only */ - -/* VBIOS flags */ -#define SWF00 0x71410 -#define SWF01 0x71414 -#define SWF02 0x71418 -#define SWF03 0x7141c -#define SWF04 0x71420 -#define SWF05 0x71424 -#define SWF06 0x71428 -#define SWF10 0x70410 -#define SWF11 0x70414 -#define SWF14 0x71420 -#define SWF30 0x72414 -#define SWF31 0x72418 -#define SWF32 0x7241c - -/* Pipe B */ -#define PIPEBDSL 0x71000 -#define PIPEBCONF 0x71008 -#define PIPEBSTAT 0x71024 -#define PIPEBFRAMEHIGH 0x71040 -#define PIPEBFRAMEPIXEL 0x71044 - -/* Display B control */ -#define DSPBCNTR 0x71180 -#define DISPPLANE_ALPHA_TRANS_ENABLE (1<<15) -#define DISPPLANE_ALPHA_TRANS_DISABLE 0 -#define DISPPLANE_SPRITE_ABOVE_DISPLAY 0 -#define DISPPLANE_SPRITE_ABOVE_OVERLAY (1) -#define DSPBADDR 0x71184 -#define DSPBSTRIDE 0x71188 -#define DSPBPOS 0x7118C -#define DSPBSIZE 0x71190 -#define DSPBSURF 0x7119C -#define DSPBTILEOFF 0x711A4 - -/* VBIOS regs */ -#define VGACNTRL 0x71400 -# define VGA_DISP_DISABLE (1 << 31) -# define VGA_2X_MODE (1 << 30) -# define VGA_PIPE_B_SELECT (1 << 29) - -#endif /* _I915_REG_H_ */ diff --git a/trunk/drivers/gpu/drm/i915/i915_suspend.c b/trunk/drivers/gpu/drm/i915/i915_suspend.c deleted file mode 100644 index 603fe742ccd4..000000000000 --- a/trunk/drivers/gpu/drm/i915/i915_suspend.c +++ /dev/null @@ -1,509 +0,0 @@ -/* - * - * Copyright 2008 (c) Intel Corporation - * Jesse Barnes - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#include "drmP.h" -#include "drm.h" -#include "i915_drm.h" -#include "i915_drv.h" - -static bool i915_pipe_enabled(struct drm_device *dev, enum pipe pipe) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - if (pipe == PIPE_A) - return (I915_READ(DPLL_A) & DPLL_VCO_ENABLE); - else - return (I915_READ(DPLL_B) & DPLL_VCO_ENABLE); -} - -static void i915_save_palette(struct drm_device *dev, enum pipe pipe) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - unsigned long reg = (pipe == PIPE_A ? PALETTE_A : PALETTE_B); - u32 *array; - int i; - - if (!i915_pipe_enabled(dev, pipe)) - return; - - if (pipe == PIPE_A) - array = dev_priv->save_palette_a; - else - array = dev_priv->save_palette_b; - - for(i = 0; i < 256; i++) - array[i] = I915_READ(reg + (i << 2)); -} - -static void i915_restore_palette(struct drm_device *dev, enum pipe pipe) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - unsigned long reg = (pipe == PIPE_A ? PALETTE_A : PALETTE_B); - u32 *array; - int i; - - if (!i915_pipe_enabled(dev, pipe)) - return; - - if (pipe == PIPE_A) - array = dev_priv->save_palette_a; - else - array = dev_priv->save_palette_b; - - for(i = 0; i < 256; i++) - I915_WRITE(reg + (i << 2), array[i]); -} - -static u8 i915_read_indexed(struct drm_device *dev, u16 index_port, u16 data_port, u8 reg) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - I915_WRITE8(index_port, reg); - return I915_READ8(data_port); -} - -static u8 i915_read_ar(struct drm_device *dev, u16 st01, u8 reg, u16 palette_enable) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - I915_READ8(st01); - I915_WRITE8(VGA_AR_INDEX, palette_enable | reg); - return I915_READ8(VGA_AR_DATA_READ); -} - -static void i915_write_ar(struct drm_device *dev, u16 st01, u8 reg, u8 val, u16 palette_enable) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - I915_READ8(st01); - I915_WRITE8(VGA_AR_INDEX, palette_enable | reg); - I915_WRITE8(VGA_AR_DATA_WRITE, val); -} - -static void i915_write_indexed(struct drm_device *dev, u16 index_port, u16 data_port, u8 reg, u8 val) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - I915_WRITE8(index_port, reg); - I915_WRITE8(data_port, val); -} - -static void i915_save_vga(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - int i; - u16 cr_index, cr_data, st01; - - /* VGA color palette registers */ - dev_priv->saveDACMASK = I915_READ8(VGA_DACMASK); - /* DACCRX automatically increments during read */ - I915_WRITE8(VGA_DACRX, 0); - /* Read 3 bytes of color data from each index */ - for (i = 0; i < 256 * 3; i++) - dev_priv->saveDACDATA[i] = I915_READ8(VGA_DACDATA); - - /* MSR bits */ - dev_priv->saveMSR = I915_READ8(VGA_MSR_READ); - if (dev_priv->saveMSR & VGA_MSR_CGA_MODE) { - cr_index = VGA_CR_INDEX_CGA; - cr_data = VGA_CR_DATA_CGA; - st01 = VGA_ST01_CGA; - } else { - cr_index = VGA_CR_INDEX_MDA; - cr_data = VGA_CR_DATA_MDA; - st01 = VGA_ST01_MDA; - } - - /* CRT controller regs */ - i915_write_indexed(dev, cr_index, cr_data, 0x11, - i915_read_indexed(dev, cr_index, cr_data, 0x11) & - (~0x80)); - for (i = 0; i <= 0x24; i++) - dev_priv->saveCR[i] = - i915_read_indexed(dev, cr_index, cr_data, i); - /* Make sure we don't turn off CR group 0 writes */ - dev_priv->saveCR[0x11] &= ~0x80; - - /* Attribute controller registers */ - I915_READ8(st01); - dev_priv->saveAR_INDEX = I915_READ8(VGA_AR_INDEX); - for (i = 0; i <= 0x14; i++) - dev_priv->saveAR[i] = i915_read_ar(dev, st01, i, 0); - I915_READ8(st01); - I915_WRITE8(VGA_AR_INDEX, dev_priv->saveAR_INDEX); - I915_READ8(st01); - - /* Graphics controller registers */ - for (i = 0; i < 9; i++) - dev_priv->saveGR[i] = - i915_read_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, i); - - dev_priv->saveGR[0x10] = - i915_read_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x10); - dev_priv->saveGR[0x11] = - i915_read_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x11); - dev_priv->saveGR[0x18] = - i915_read_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x18); - - /* Sequencer registers */ - for (i = 0; i < 8; i++) - dev_priv->saveSR[i] = - i915_read_indexed(dev, VGA_SR_INDEX, VGA_SR_DATA, i); -} - -static void i915_restore_vga(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - int i; - u16 cr_index, cr_data, st01; - - /* MSR bits */ - I915_WRITE8(VGA_MSR_WRITE, dev_priv->saveMSR); - if (dev_priv->saveMSR & VGA_MSR_CGA_MODE) { - cr_index = VGA_CR_INDEX_CGA; - cr_data = VGA_CR_DATA_CGA; - st01 = VGA_ST01_CGA; - } else { - cr_index = VGA_CR_INDEX_MDA; - cr_data = VGA_CR_DATA_MDA; - st01 = VGA_ST01_MDA; - } - - /* Sequencer registers, don't write SR07 */ - for (i = 0; i < 7; i++) - i915_write_indexed(dev, VGA_SR_INDEX, VGA_SR_DATA, i, - dev_priv->saveSR[i]); - - /* CRT controller regs */ - /* Enable CR group 0 writes */ - i915_write_indexed(dev, cr_index, cr_data, 0x11, dev_priv->saveCR[0x11]); - for (i = 0; i <= 0x24; i++) - i915_write_indexed(dev, cr_index, cr_data, i, dev_priv->saveCR[i]); - - /* Graphics controller regs */ - for (i = 0; i < 9; i++) - i915_write_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, i, - dev_priv->saveGR[i]); - - i915_write_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x10, - dev_priv->saveGR[0x10]); - i915_write_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x11, - dev_priv->saveGR[0x11]); - i915_write_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x18, - dev_priv->saveGR[0x18]); - - /* Attribute controller registers */ - I915_READ8(st01); /* switch back to index mode */ - for (i = 0; i <= 0x14; i++) - i915_write_ar(dev, st01, i, dev_priv->saveAR[i], 0); - I915_READ8(st01); /* switch back to index mode */ - I915_WRITE8(VGA_AR_INDEX, dev_priv->saveAR_INDEX | 0x20); - I915_READ8(st01); - - /* VGA color palette registers */ - I915_WRITE8(VGA_DACMASK, dev_priv->saveDACMASK); - /* DACCRX automatically increments during read */ - I915_WRITE8(VGA_DACWX, 0); - /* Read 3 bytes of color data from each index */ - for (i = 0; i < 256 * 3; i++) - I915_WRITE8(VGA_DACDATA, dev_priv->saveDACDATA[i]); - -} - -int i915_save_state(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - int i; - - pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB); - - /* Display arbitration control */ - dev_priv->saveDSPARB = I915_READ(DSPARB); - - /* Pipe & plane A info */ - dev_priv->savePIPEACONF = I915_READ(PIPEACONF); - dev_priv->savePIPEASRC = I915_READ(PIPEASRC); - dev_priv->saveFPA0 = I915_READ(FPA0); - dev_priv->saveFPA1 = I915_READ(FPA1); - dev_priv->saveDPLL_A = I915_READ(DPLL_A); - if (IS_I965G(dev)) - dev_priv->saveDPLL_A_MD = I915_READ(DPLL_A_MD); - dev_priv->saveHTOTAL_A = I915_READ(HTOTAL_A); - dev_priv->saveHBLANK_A = I915_READ(HBLANK_A); - dev_priv->saveHSYNC_A = I915_READ(HSYNC_A); - dev_priv->saveVTOTAL_A = I915_READ(VTOTAL_A); - dev_priv->saveVBLANK_A = I915_READ(VBLANK_A); - dev_priv->saveVSYNC_A = I915_READ(VSYNC_A); - dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A); - - dev_priv->saveDSPACNTR = I915_READ(DSPACNTR); - dev_priv->saveDSPASTRIDE = I915_READ(DSPASTRIDE); - dev_priv->saveDSPASIZE = I915_READ(DSPASIZE); - dev_priv->saveDSPAPOS = I915_READ(DSPAPOS); - dev_priv->saveDSPAADDR = I915_READ(DSPAADDR); - if (IS_I965G(dev)) { - dev_priv->saveDSPASURF = I915_READ(DSPASURF); - dev_priv->saveDSPATILEOFF = I915_READ(DSPATILEOFF); - } - i915_save_palette(dev, PIPE_A); - dev_priv->savePIPEASTAT = I915_READ(PIPEASTAT); - - /* Pipe & plane B info */ - dev_priv->savePIPEBCONF = I915_READ(PIPEBCONF); - dev_priv->savePIPEBSRC = I915_READ(PIPEBSRC); - dev_priv->saveFPB0 = I915_READ(FPB0); - dev_priv->saveFPB1 = I915_READ(FPB1); - dev_priv->saveDPLL_B = I915_READ(DPLL_B); - if (IS_I965G(dev)) - dev_priv->saveDPLL_B_MD = I915_READ(DPLL_B_MD); - dev_priv->saveHTOTAL_B = I915_READ(HTOTAL_B); - dev_priv->saveHBLANK_B = I915_READ(HBLANK_B); - dev_priv->saveHSYNC_B = I915_READ(HSYNC_B); - dev_priv->saveVTOTAL_B = I915_READ(VTOTAL_B); - dev_priv->saveVBLANK_B = I915_READ(VBLANK_B); - dev_priv->saveVSYNC_B = I915_READ(VSYNC_B); - dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A); - - dev_priv->saveDSPBCNTR = I915_READ(DSPBCNTR); - dev_priv->saveDSPBSTRIDE = I915_READ(DSPBSTRIDE); - dev_priv->saveDSPBSIZE = I915_READ(DSPBSIZE); - dev_priv->saveDSPBPOS = I915_READ(DSPBPOS); - dev_priv->saveDSPBADDR = I915_READ(DSPBADDR); - if (IS_I965GM(dev) || IS_GM45(dev)) { - dev_priv->saveDSPBSURF = I915_READ(DSPBSURF); - dev_priv->saveDSPBTILEOFF = I915_READ(DSPBTILEOFF); - } - i915_save_palette(dev, PIPE_B); - dev_priv->savePIPEBSTAT = I915_READ(PIPEBSTAT); - - /* CRT state */ - dev_priv->saveADPA = I915_READ(ADPA); - - /* LVDS state */ - dev_priv->savePP_CONTROL = I915_READ(PP_CONTROL); - dev_priv->savePFIT_PGM_RATIOS = I915_READ(PFIT_PGM_RATIOS); - dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_CTL); - if (IS_I965G(dev)) - dev_priv->saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_CTL2); - if (IS_MOBILE(dev) && !IS_I830(dev)) - dev_priv->saveLVDS = I915_READ(LVDS); - if (!IS_I830(dev) && !IS_845G(dev)) - dev_priv->savePFIT_CONTROL = I915_READ(PFIT_CONTROL); - dev_priv->savePP_ON_DELAYS = I915_READ(PP_ON_DELAYS); - dev_priv->savePP_OFF_DELAYS = I915_READ(PP_OFF_DELAYS); - dev_priv->savePP_DIVISOR = I915_READ(PP_DIVISOR); - - /* FIXME: save TV & SDVO state */ - - /* FBC state */ - dev_priv->saveFBC_CFB_BASE = I915_READ(FBC_CFB_BASE); - dev_priv->saveFBC_LL_BASE = I915_READ(FBC_LL_BASE); - dev_priv->saveFBC_CONTROL2 = I915_READ(FBC_CONTROL2); - dev_priv->saveFBC_CONTROL = I915_READ(FBC_CONTROL); - - /* Interrupt state */ - dev_priv->saveIIR = I915_READ(IIR); - dev_priv->saveIER = I915_READ(IER); - dev_priv->saveIMR = I915_READ(IMR); - - /* VGA state */ - dev_priv->saveVGA0 = I915_READ(VGA0); - dev_priv->saveVGA1 = I915_READ(VGA1); - dev_priv->saveVGA_PD = I915_READ(VGA_PD); - dev_priv->saveVGACNTRL = I915_READ(VGACNTRL); - - /* Clock gating state */ - dev_priv->saveD_STATE = I915_READ(D_STATE); - dev_priv->saveCG_2D_DIS = I915_READ(CG_2D_DIS); - - /* Cache mode state */ - dev_priv->saveCACHE_MODE_0 = I915_READ(CACHE_MODE_0); - - /* Memory Arbitration state */ - dev_priv->saveMI_ARB_STATE = I915_READ(MI_ARB_STATE); - - /* Scratch space */ - for (i = 0; i < 16; i++) { - dev_priv->saveSWF0[i] = I915_READ(SWF00 + (i << 2)); - dev_priv->saveSWF1[i] = I915_READ(SWF10 + (i << 2)); - } - for (i = 0; i < 3; i++) - dev_priv->saveSWF2[i] = I915_READ(SWF30 + (i << 2)); - - i915_save_vga(dev); - - return 0; -} - -int i915_restore_state(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - int i; - - pci_write_config_byte(dev->pdev, LBB, dev_priv->saveLBB); - - I915_WRITE(DSPARB, dev_priv->saveDSPARB); - - /* Pipe & plane A info */ - /* Prime the clock */ - if (dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) { - I915_WRITE(DPLL_A, dev_priv->saveDPLL_A & - ~DPLL_VCO_ENABLE); - DRM_UDELAY(150); - } - I915_WRITE(FPA0, dev_priv->saveFPA0); - I915_WRITE(FPA1, dev_priv->saveFPA1); - /* Actually enable it */ - I915_WRITE(DPLL_A, dev_priv->saveDPLL_A); - DRM_UDELAY(150); - if (IS_I965G(dev)) - I915_WRITE(DPLL_A_MD, dev_priv->saveDPLL_A_MD); - DRM_UDELAY(150); - - /* Restore mode */ - I915_WRITE(HTOTAL_A, dev_priv->saveHTOTAL_A); - I915_WRITE(HBLANK_A, dev_priv->saveHBLANK_A); - I915_WRITE(HSYNC_A, dev_priv->saveHSYNC_A); - I915_WRITE(VTOTAL_A, dev_priv->saveVTOTAL_A); - I915_WRITE(VBLANK_A, dev_priv->saveVBLANK_A); - I915_WRITE(VSYNC_A, dev_priv->saveVSYNC_A); - I915_WRITE(BCLRPAT_A, dev_priv->saveBCLRPAT_A); - - /* Restore plane info */ - I915_WRITE(DSPASIZE, dev_priv->saveDSPASIZE); - I915_WRITE(DSPAPOS, dev_priv->saveDSPAPOS); - I915_WRITE(PIPEASRC, dev_priv->savePIPEASRC); - I915_WRITE(DSPAADDR, dev_priv->saveDSPAADDR); - I915_WRITE(DSPASTRIDE, dev_priv->saveDSPASTRIDE); - if (IS_I965G(dev)) { - I915_WRITE(DSPASURF, dev_priv->saveDSPASURF); - I915_WRITE(DSPATILEOFF, dev_priv->saveDSPATILEOFF); - } - - I915_WRITE(PIPEACONF, dev_priv->savePIPEACONF); - - i915_restore_palette(dev, PIPE_A); - /* Enable the plane */ - I915_WRITE(DSPACNTR, dev_priv->saveDSPACNTR); - I915_WRITE(DSPAADDR, I915_READ(DSPAADDR)); - - /* Pipe & plane B info */ - if (dev_priv->saveDPLL_B & DPLL_VCO_ENABLE) { - I915_WRITE(DPLL_B, dev_priv->saveDPLL_B & - ~DPLL_VCO_ENABLE); - DRM_UDELAY(150); - } - I915_WRITE(FPB0, dev_priv->saveFPB0); - I915_WRITE(FPB1, dev_priv->saveFPB1); - /* Actually enable it */ - I915_WRITE(DPLL_B, dev_priv->saveDPLL_B); - DRM_UDELAY(150); - if (IS_I965G(dev)) - I915_WRITE(DPLL_B_MD, dev_priv->saveDPLL_B_MD); - DRM_UDELAY(150); - - /* Restore mode */ - I915_WRITE(HTOTAL_B, dev_priv->saveHTOTAL_B); - I915_WRITE(HBLANK_B, dev_priv->saveHBLANK_B); - I915_WRITE(HSYNC_B, dev_priv->saveHSYNC_B); - I915_WRITE(VTOTAL_B, dev_priv->saveVTOTAL_B); - I915_WRITE(VBLANK_B, dev_priv->saveVBLANK_B); - I915_WRITE(VSYNC_B, dev_priv->saveVSYNC_B); - I915_WRITE(BCLRPAT_B, dev_priv->saveBCLRPAT_B); - - /* Restore plane info */ - I915_WRITE(DSPBSIZE, dev_priv->saveDSPBSIZE); - I915_WRITE(DSPBPOS, dev_priv->saveDSPBPOS); - I915_WRITE(PIPEBSRC, dev_priv->savePIPEBSRC); - I915_WRITE(DSPBADDR, dev_priv->saveDSPBADDR); - I915_WRITE(DSPBSTRIDE, dev_priv->saveDSPBSTRIDE); - if (IS_I965G(dev)) { - I915_WRITE(DSPBSURF, dev_priv->saveDSPBSURF); - I915_WRITE(DSPBTILEOFF, dev_priv->saveDSPBTILEOFF); - } - - I915_WRITE(PIPEBCONF, dev_priv->savePIPEBCONF); - - i915_restore_palette(dev, PIPE_B); - /* Enable the plane */ - I915_WRITE(DSPBCNTR, dev_priv->saveDSPBCNTR); - I915_WRITE(DSPBADDR, I915_READ(DSPBADDR)); - - /* CRT state */ - I915_WRITE(ADPA, dev_priv->saveADPA); - - /* LVDS state */ - if (IS_I965G(dev)) - I915_WRITE(BLC_PWM_CTL2, dev_priv->saveBLC_PWM_CTL2); - if (IS_MOBILE(dev) && !IS_I830(dev)) - I915_WRITE(LVDS, dev_priv->saveLVDS); - if (!IS_I830(dev) && !IS_845G(dev)) - I915_WRITE(PFIT_CONTROL, dev_priv->savePFIT_CONTROL); - - I915_WRITE(PFIT_PGM_RATIOS, dev_priv->savePFIT_PGM_RATIOS); - I915_WRITE(BLC_PWM_CTL, dev_priv->saveBLC_PWM_CTL); - I915_WRITE(PP_ON_DELAYS, dev_priv->savePP_ON_DELAYS); - I915_WRITE(PP_OFF_DELAYS, dev_priv->savePP_OFF_DELAYS); - I915_WRITE(PP_DIVISOR, dev_priv->savePP_DIVISOR); - I915_WRITE(PP_CONTROL, dev_priv->savePP_CONTROL); - - /* FIXME: restore TV & SDVO state */ - - /* FBC info */ - I915_WRITE(FBC_CFB_BASE, dev_priv->saveFBC_CFB_BASE); - I915_WRITE(FBC_LL_BASE, dev_priv->saveFBC_LL_BASE); - I915_WRITE(FBC_CONTROL2, dev_priv->saveFBC_CONTROL2); - I915_WRITE(FBC_CONTROL, dev_priv->saveFBC_CONTROL); - - /* VGA state */ - I915_WRITE(VGACNTRL, dev_priv->saveVGACNTRL); - I915_WRITE(VGA0, dev_priv->saveVGA0); - I915_WRITE(VGA1, dev_priv->saveVGA1); - I915_WRITE(VGA_PD, dev_priv->saveVGA_PD); - DRM_UDELAY(150); - - /* Clock gating state */ - I915_WRITE (D_STATE, dev_priv->saveD_STATE); - I915_WRITE (CG_2D_DIS, dev_priv->saveCG_2D_DIS); - - /* Cache mode state */ - I915_WRITE (CACHE_MODE_0, dev_priv->saveCACHE_MODE_0 | 0xffff0000); - - /* Memory arbitration state */ - I915_WRITE (MI_ARB_STATE, dev_priv->saveMI_ARB_STATE | 0xffff0000); - - for (i = 0; i < 16; i++) { - I915_WRITE(SWF00 + (i << 2), dev_priv->saveSWF0[i]); - I915_WRITE(SWF10 + (i << 2), dev_priv->saveSWF1[i+7]); - } - for (i = 0; i < 3; i++) - I915_WRITE(SWF30 + (i << 2), dev_priv->saveSWF2[i]); - - i915_restore_vga(dev); - - return 0; -} - diff --git a/trunk/drivers/gpu/drm/mga/mga_drv.c b/trunk/drivers/gpu/drm/mga/mga_drv.c index 97ee566ef749..5572939fc7d1 100644 --- a/trunk/drivers/gpu/drm/mga/mga_drv.c +++ b/trunk/drivers/gpu/drm/mga/mga_drv.c @@ -45,16 +45,15 @@ static struct pci_device_id pciidlist[] = { static struct drm_driver driver = { .driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | - DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED, + DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | + DRIVER_IRQ_VBL, .dev_priv_size = sizeof(drm_mga_buf_priv_t), .load = mga_driver_load, .unload = mga_driver_unload, .lastclose = mga_driver_lastclose, .dma_quiescent = mga_driver_dma_quiescent, .device_is_agp = mga_driver_device_is_agp, - .get_vblank_counter = mga_get_vblank_counter, - .enable_vblank = mga_enable_vblank, - .disable_vblank = mga_disable_vblank, + .vblank_wait = mga_driver_vblank_wait, .irq_preinstall = mga_driver_irq_preinstall, .irq_postinstall = mga_driver_irq_postinstall, .irq_uninstall = mga_driver_irq_uninstall, @@ -65,20 +64,20 @@ static struct drm_driver driver = { .ioctls = mga_ioctls, .dma_ioctl = mga_dma_buffers, .fops = { - .owner = THIS_MODULE, - .open = drm_open, - .release = drm_release, - .ioctl = drm_ioctl, - .mmap = drm_mmap, - .poll = drm_poll, - .fasync = drm_fasync, + .owner = THIS_MODULE, + .open = drm_open, + .release = drm_release, + .ioctl = drm_ioctl, + .mmap = drm_mmap, + .poll = drm_poll, + .fasync = drm_fasync, #ifdef CONFIG_COMPAT - .compat_ioctl = mga_compat_ioctl, + .compat_ioctl = mga_compat_ioctl, #endif - }, + }, .pci_driver = { - .name = DRIVER_NAME, - .id_table = pciidlist, + .name = DRIVER_NAME, + .id_table = pciidlist, }, .name = DRIVER_NAME, diff --git a/trunk/drivers/gpu/drm/mga/mga_drv.h b/trunk/drivers/gpu/drm/mga/mga_drv.h index 88257c276eb9..f6ebd24bd587 100644 --- a/trunk/drivers/gpu/drm/mga/mga_drv.h +++ b/trunk/drivers/gpu/drm/mga/mga_drv.h @@ -120,7 +120,6 @@ typedef struct drm_mga_private { u32 clear_cmd; u32 maccess; - atomic_t vbl_received; /**< Number of vblanks received. */ wait_queue_head_t fence_queue; atomic_t last_fence_retired; u32 next_fence_to_post; @@ -182,14 +181,11 @@ extern int mga_warp_install_microcode(drm_mga_private_t * dev_priv); extern int mga_warp_init(drm_mga_private_t * dev_priv); /* mga_irq.c */ -extern int mga_enable_vblank(struct drm_device *dev, int crtc); -extern void mga_disable_vblank(struct drm_device *dev, int crtc); -extern u32 mga_get_vblank_counter(struct drm_device *dev, int crtc); extern int mga_driver_fence_wait(struct drm_device * dev, unsigned int *sequence); extern int mga_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence); extern irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS); extern void mga_driver_irq_preinstall(struct drm_device * dev); -extern int mga_driver_irq_postinstall(struct drm_device *dev); +extern void mga_driver_irq_postinstall(struct drm_device * dev); extern void mga_driver_irq_uninstall(struct drm_device * dev); extern long mga_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); diff --git a/trunk/drivers/gpu/drm/mga/mga_irq.c b/trunk/drivers/gpu/drm/mga/mga_irq.c index bab42f41188b..9302cb8f0f83 100644 --- a/trunk/drivers/gpu/drm/mga/mga_irq.c +++ b/trunk/drivers/gpu/drm/mga/mga_irq.c @@ -1,6 +1,5 @@ /* mga_irq.c -- IRQ handling for radeon -*- linux-c -*- - */ -/* + * * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. * * The Weather Channel (TM) funded Tungsten Graphics to develop the @@ -36,18 +35,6 @@ #include "mga_drm.h" #include "mga_drv.h" -u32 mga_get_vblank_counter(struct drm_device *dev, int crtc) -{ - const drm_mga_private_t *const dev_priv = - (drm_mga_private_t *) dev->dev_private; - - if (crtc != 0) - return 0; - - return atomic_read(&dev_priv->vbl_received); -} - - irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS) { struct drm_device *dev = (struct drm_device *) arg; @@ -60,8 +47,9 @@ irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS) /* VBLANK interrupt */ if (status & MGA_VLINEPEN) { MGA_WRITE(MGA_ICLEAR, MGA_VLINEICLR); - atomic_inc(&dev_priv->vbl_received); - drm_handle_vblank(dev, 0); + atomic_inc(&dev->vbl_received); + DRM_WAKEUP(&dev->vbl_queue); + drm_vbl_send_signals(dev); handled = 1; } @@ -70,7 +58,6 @@ irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS) const u32 prim_start = MGA_READ(MGA_PRIMADDRESS); const u32 prim_end = MGA_READ(MGA_PRIMEND); - MGA_WRITE(MGA_ICLEAR, MGA_SOFTRAPICLR); /* In addition to clearing the interrupt-pending bit, we @@ -85,39 +72,28 @@ irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS) handled = 1; } - if (handled) + if (handled) { return IRQ_HANDLED; + } return IRQ_NONE; } -int mga_enable_vblank(struct drm_device *dev, int crtc) +int mga_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence) { - drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; - - if (crtc != 0) { - DRM_ERROR("tried to enable vblank on non-existent crtc %d\n", - crtc); - return 0; - } - - MGA_WRITE(MGA_IEN, MGA_VLINEIEN | MGA_SOFTRAPEN); - return 0; -} + unsigned int cur_vblank; + int ret = 0; + /* Assume that the user has missed the current sequence number + * by about a day rather than she wants to wait for years + * using vertical blanks... + */ + DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ, + (((cur_vblank = atomic_read(&dev->vbl_received)) + - *sequence) <= (1 << 23))); -void mga_disable_vblank(struct drm_device *dev, int crtc) -{ - if (crtc != 0) { - DRM_ERROR("tried to disable vblank on non-existent crtc %d\n", - crtc); - } + *sequence = cur_vblank; - /* Do *NOT* disable the vertical refresh interrupt. MGA doesn't have - * a nice hardware counter that tracks the number of refreshes when - * the interrupt is disabled, and the kernel doesn't know the refresh - * rate to calculate an estimate. - */ - /* MGA_WRITE(MGA_IEN, MGA_VLINEIEN | MGA_SOFTRAPEN); */ + return ret; } int mga_driver_fence_wait(struct drm_device * dev, unsigned int *sequence) @@ -149,22 +125,14 @@ void mga_driver_irq_preinstall(struct drm_device * dev) MGA_WRITE(MGA_ICLEAR, ~0); } -int mga_driver_irq_postinstall(struct drm_device *dev) +void mga_driver_irq_postinstall(struct drm_device * dev) { drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; - int ret; - - ret = drm_vblank_init(dev, 1); - if (ret) - return ret; DRM_INIT_WAITQUEUE(&dev_priv->fence_queue); - /* Turn on soft trap interrupt. Vertical blank interrupts are enabled - * in mga_enable_vblank. - */ - MGA_WRITE(MGA_IEN, MGA_SOFTRAPEN); - return 0; + /* Turn on vertical blank interrupt and soft trap interrupt. */ + MGA_WRITE(MGA_IEN, MGA_VLINEIEN | MGA_SOFTRAPEN); } void mga_driver_irq_uninstall(struct drm_device * dev) diff --git a/trunk/drivers/gpu/drm/mga/mga_state.c b/trunk/drivers/gpu/drm/mga/mga_state.c index b710fab21cb3..d3f8aade07b3 100644 --- a/trunk/drivers/gpu/drm/mga/mga_state.c +++ b/trunk/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 switch (param->param) { case MGA_PARAM_IRQ_NR: - value = drm_dev_to_irq(dev); + value = dev->irq; break; case MGA_PARAM_CARD_TYPE: value = dev_priv->chipset; diff --git a/trunk/drivers/gpu/drm/r128/r128_drv.c b/trunk/drivers/gpu/drm/r128/r128_drv.c index 3265d53ba91f..6108e7587e12 100644 --- a/trunk/drivers/gpu/drm/r128/r128_drv.c +++ b/trunk/drivers/gpu/drm/r128/r128_drv.c @@ -43,13 +43,12 @@ static struct pci_device_id pciidlist[] = { static struct drm_driver driver = { .driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | - DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED, + DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | + DRIVER_IRQ_VBL, .dev_priv_size = sizeof(drm_r128_buf_priv_t), .preclose = r128_driver_preclose, .lastclose = r128_driver_lastclose, - .get_vblank_counter = r128_get_vblank_counter, - .enable_vblank = r128_enable_vblank, - .disable_vblank = r128_disable_vblank, + .vblank_wait = r128_driver_vblank_wait, .irq_preinstall = r128_driver_irq_preinstall, .irq_postinstall = r128_driver_irq_postinstall, .irq_uninstall = r128_driver_irq_uninstall, @@ -60,20 +59,21 @@ static struct drm_driver driver = { .ioctls = r128_ioctls, .dma_ioctl = r128_cce_buffers, .fops = { - .owner = THIS_MODULE, - .open = drm_open, - .release = drm_release, - .ioctl = drm_ioctl, - .mmap = drm_mmap, - .poll = drm_poll, - .fasync = drm_fasync, + .owner = THIS_MODULE, + .open = drm_open, + .release = drm_release, + .ioctl = drm_ioctl, + .mmap = drm_mmap, + .poll = drm_poll, + .fasync = drm_fasync, #ifdef CONFIG_COMPAT - .compat_ioctl = r128_compat_ioctl, + .compat_ioctl = r128_compat_ioctl, #endif }, + .pci_driver = { - .name = DRIVER_NAME, - .id_table = pciidlist, + .name = DRIVER_NAME, + .id_table = pciidlist, }, .name = DRIVER_NAME, @@ -87,7 +87,6 @@ static struct drm_driver driver = { static int __init r128_init(void) { driver.num_ioctls = r128_max_ioctl; - return drm_init(&driver); } diff --git a/trunk/drivers/gpu/drm/r128/r128_drv.h b/trunk/drivers/gpu/drm/r128/r128_drv.h index 5898b274279d..011105e51ac6 100644 --- a/trunk/drivers/gpu/drm/r128/r128_drv.h +++ b/trunk/drivers/gpu/drm/r128/r128_drv.h @@ -29,7 +29,7 @@ * Rickard E. (Rik) Faith * Kevin E. Martin * Gareth Hughes - * Michel D�zer + * Michel Dänzer */ #ifndef __R128_DRV_H__ @@ -97,8 +97,6 @@ typedef struct drm_r128_private { u32 crtc_offset; u32 crtc_offset_cntl; - atomic_t vbl_received; - u32 color_fmt; unsigned int front_offset; unsigned int front_pitch; @@ -151,12 +149,11 @@ extern int r128_wait_ring(drm_r128_private_t * dev_priv, int n); extern int r128_do_cce_idle(drm_r128_private_t * dev_priv); extern int r128_do_cleanup_cce(struct drm_device * dev); -extern int r128_enable_vblank(struct drm_device *dev, int crtc); -extern void r128_disable_vblank(struct drm_device *dev, int crtc); -extern u32 r128_get_vblank_counter(struct drm_device *dev, int crtc); +extern int r128_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence); + extern irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS); extern void r128_driver_irq_preinstall(struct drm_device * dev); -extern int r128_driver_irq_postinstall(struct drm_device *dev); +extern void r128_driver_irq_postinstall(struct drm_device * dev); extern void r128_driver_irq_uninstall(struct drm_device * dev); extern void r128_driver_lastclose(struct drm_device * dev); extern void r128_driver_preclose(struct drm_device * dev, diff --git a/trunk/drivers/gpu/drm/r128/r128_irq.c b/trunk/drivers/gpu/drm/r128/r128_irq.c index d7349012a680..c76fdca7662d 100644 --- a/trunk/drivers/gpu/drm/r128/r128_irq.c +++ b/trunk/drivers/gpu/drm/r128/r128_irq.c @@ -35,16 +35,6 @@ #include "r128_drm.h" #include "r128_drv.h" -u32 r128_get_vblank_counter(struct drm_device *dev, int crtc) -{ - const drm_r128_private_t *dev_priv = dev->dev_private; - - if (crtc != 0) - return 0; - - return atomic_read(&dev_priv->vbl_received); -} - irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS) { struct drm_device *dev = (struct drm_device *) arg; @@ -56,38 +46,30 @@ irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS) /* VBLANK interrupt */ if (status & R128_CRTC_VBLANK_INT) { R128_WRITE(R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK); - atomic_inc(&dev_priv->vbl_received); - drm_handle_vblank(dev, 0); + atomic_inc(&dev->vbl_received); + DRM_WAKEUP(&dev->vbl_queue); + drm_vbl_send_signals(dev); return IRQ_HANDLED; } return IRQ_NONE; } -int r128_enable_vblank(struct drm_device *dev, int crtc) +int r128_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence) { - drm_r128_private_t *dev_priv = dev->dev_private; - - if (crtc != 0) { - DRM_ERROR("%s: bad crtc %d\n", __func__, crtc); - return -EINVAL; - } + unsigned int cur_vblank; + int ret = 0; - R128_WRITE(R128_GEN_INT_CNTL, R128_CRTC_VBLANK_INT_EN); - return 0; -} + /* Assume that the user has missed the current sequence number + * by about a day rather than she wants to wait for years + * using vertical blanks... + */ + DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ, + (((cur_vblank = atomic_read(&dev->vbl_received)) + - *sequence) <= (1 << 23))); -void r128_disable_vblank(struct drm_device *dev, int crtc) -{ - if (crtc != 0) - DRM_ERROR("%s: bad crtc %d\n", __func__, crtc); + *sequence = cur_vblank; - /* - * FIXME: implement proper interrupt disable by using the vblank - * counter register (if available) - * - * R128_WRITE(R128_GEN_INT_CNTL, - * R128_READ(R128_GEN_INT_CNTL) & ~R128_CRTC_VBLANK_INT_EN); - */ + return ret; } void r128_driver_irq_preinstall(struct drm_device * dev) @@ -100,9 +82,12 @@ void r128_driver_irq_preinstall(struct drm_device * dev) R128_WRITE(R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK); } -int r128_driver_irq_postinstall(struct drm_device *dev) +void r128_driver_irq_postinstall(struct drm_device * dev) { - return drm_vblank_init(dev, 1); + drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private; + + /* Turn on VBL interrupt */ + R128_WRITE(R128_GEN_INT_CNTL, R128_CRTC_VBLANK_INT_EN); } void r128_driver_irq_uninstall(struct drm_device * dev) diff --git a/trunk/drivers/gpu/drm/r128/r128_state.c b/trunk/drivers/gpu/drm/r128/r128_state.c index f7a5b5740764..51a9afce7b9b 100644 --- a/trunk/drivers/gpu/drm/r128/r128_state.c +++ b/trunk/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 switch (param->param) { case R128_PARAM_IRQ_NR: - value = drm_dev_to_irq(dev); + value = dev->irq; break; default: return -EINVAL; diff --git a/trunk/drivers/gpu/drm/radeon/radeon_cp.c b/trunk/drivers/gpu/drm/radeon/radeon_cp.c index 59a2132a8f57..248ab4a7d39f 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_cp.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_cp.c @@ -71,8 +71,7 @@ static u32 RS690_READ_MCIND(drm_radeon_private_t *dev_priv, int addr) static u32 IGP_READ_MCIND(drm_radeon_private_t *dev_priv, int addr) { - if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) + if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) return RS690_READ_MCIND(dev_priv, addr); else return RS480_READ_MCIND(dev_priv, addr); @@ -83,8 +82,7 @@ u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv) if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) return R500_READ_MCIND(dev_priv, RV515_MC_FB_LOCATION); - else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) + else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) return RS690_READ_MCIND(dev_priv, RS690_MC_FB_LOCATION); else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) return R500_READ_MCIND(dev_priv, R520_MC_FB_LOCATION); @@ -96,8 +94,7 @@ static void radeon_write_fb_location(drm_radeon_private_t *dev_priv, u32 fb_loc) { if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) R500_WRITE_MCIND(RV515_MC_FB_LOCATION, fb_loc); - else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) + else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) RS690_WRITE_MCIND(RS690_MC_FB_LOCATION, fb_loc); else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) R500_WRITE_MCIND(R520_MC_FB_LOCATION, fb_loc); @@ -109,8 +106,7 @@ static void radeon_write_agp_location(drm_radeon_private_t *dev_priv, u32 agp_lo { if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) R500_WRITE_MCIND(RV515_MC_AGP_LOCATION, agp_loc); - else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) + else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) RS690_WRITE_MCIND(RS690_MC_AGP_LOCATION, agp_loc); else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) R500_WRITE_MCIND(R520_MC_AGP_LOCATION, agp_loc); @@ -126,17 +122,15 @@ static void radeon_write_agp_base(drm_radeon_private_t *dev_priv, u64 agp_base) if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) { R500_WRITE_MCIND(RV515_MC_AGP_BASE, agp_base_lo); R500_WRITE_MCIND(RV515_MC_AGP_BASE_2, agp_base_hi); - } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) { + } else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) { RS690_WRITE_MCIND(RS690_MC_AGP_BASE, agp_base_lo); RS690_WRITE_MCIND(RS690_MC_AGP_BASE_2, agp_base_hi); } else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) { R500_WRITE_MCIND(R520_MC_AGP_BASE, agp_base_lo); R500_WRITE_MCIND(R520_MC_AGP_BASE_2, agp_base_hi); - } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS400) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS480)) { + } else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS480) { RADEON_WRITE(RADEON_AGP_BASE, agp_base_lo); - RADEON_WRITE(RS480_AGP_BASE_2, agp_base_hi); + RADEON_WRITE(RS480_AGP_BASE_2, 0); } else { RADEON_WRITE(RADEON_AGP_BASE, agp_base_lo); if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R200) @@ -353,7 +347,6 @@ static void radeon_cp_load_microcode(drm_radeon_private_t * dev_priv) ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R350) || ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV350) || ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV380) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS400) || ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS480)) { DRM_INFO("Loading R300 Microcode\n"); for (i = 0; i < 256; i++) { @@ -363,7 +356,6 @@ static void radeon_cp_load_microcode(drm_radeon_private_t * dev_priv) R300_cp_microcode[i][0]); } } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R420) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R423) || ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV410)) { DRM_INFO("Loading R400 Microcode\n"); for (i = 0; i < 256; i++) { @@ -372,9 +364,8 @@ static void radeon_cp_load_microcode(drm_radeon_private_t * dev_priv) RADEON_WRITE(RADEON_CP_ME_RAM_DATAL, R420_cp_microcode[i][0]); } - } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) { - DRM_INFO("Loading RS690/RS740 Microcode\n"); + } else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) { + DRM_INFO("Loading RS690 Microcode\n"); for (i = 0; i < 256; i++) { RADEON_WRITE(RADEON_CP_ME_RAM_DATAH, RS690_cp_microcode[i][1]); @@ -635,6 +626,8 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev, dev_priv->ring.size_l2qw); #endif + /* Start with assuming that writeback doesn't work */ + dev_priv->writeback_works = 0; /* Initialize the scratch register pointer. This will cause * the scratch register values to be written out to memory @@ -653,18 +646,8 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev, RADEON_WRITE(RADEON_SCRATCH_UMSK, 0x7); /* Turn on bus mastering */ - if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS400) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) { - /* rs400, rs690/rs740 */ - tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RS400_BUS_MASTER_DIS; - RADEON_WRITE(RADEON_BUS_CNTL, tmp); - } else if (!(((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV380) || - ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R423))) { - /* r1xx, r2xx, r300, r(v)350, r420/r481, rs480 */ - tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS; - RADEON_WRITE(RADEON_BUS_CNTL, tmp); - } /* PCIE cards appears to not need this */ + tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS; + RADEON_WRITE(RADEON_BUS_CNTL, tmp); dev_priv->sarea_priv->last_frame = dev_priv->scratch[0] = 0; RADEON_WRITE(RADEON_LAST_FRAME_REG, dev_priv->sarea_priv->last_frame); @@ -691,9 +674,6 @@ static void radeon_test_writeback(drm_radeon_private_t * dev_priv) { u32 tmp; - /* Start with assuming that writeback doesn't work */ - dev_priv->writeback_works = 0; - /* Writeback doesn't seem to work everywhere, test it here and possibly * enable it if it appears to work */ @@ -739,8 +719,7 @@ static void radeon_set_igpgart(drm_radeon_private_t * dev_priv, int on) dev_priv->gart_size); temp = IGP_READ_MCIND(dev_priv, RS480_MC_MISC_CNTL); - if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) + if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) IGP_WRITE_MCIND(RS480_MC_MISC_CNTL, (RS480_GART_INDEX_REG_EN | RS690_BLOCK_GFX_D3_EN)); else @@ -833,7 +812,6 @@ static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on) u32 tmp; if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740) || (dev_priv->flags & RADEON_IS_IGPGART)) { radeon_set_igpgart(dev_priv, on); return; @@ -1308,7 +1286,7 @@ static int radeon_do_resume_cp(struct drm_device * dev) radeon_cp_init_ring_buffer(dev, dev_priv); radeon_do_engine_reset(dev); - radeon_irq_set_state(dev, RADEON_SW_INT_ENABLE, 1); + radeon_enable_interrupt(dev); DRM_DEBUG("radeon_do_resume_cp() complete\n"); @@ -1730,7 +1708,6 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags) case CHIP_R300: case CHIP_R350: case CHIP_R420: - case CHIP_R423: case CHIP_RV410: case CHIP_RV515: case CHIP_R520: diff --git a/trunk/drivers/gpu/drm/radeon/radeon_drv.c b/trunk/drivers/gpu/drm/radeon/radeon_drv.c index 71af746a4e47..637bd7faf132 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_drv.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_drv.c @@ -52,28 +52,6 @@ static int dri_library_name(struct drm_device *dev, char *buf) "r300")); } -static int radeon_suspend(struct drm_device *dev, pm_message_t state) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - - /* Disable *all* interrupts */ - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) - RADEON_WRITE(R500_DxMODE_INT_MASK, 0); - RADEON_WRITE(RADEON_GEN_INT_CNTL, 0); - return 0; -} - -static int radeon_resume(struct drm_device *dev) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - - /* Restore interrupt registers */ - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) - RADEON_WRITE(R500_DxMODE_INT_MASK, dev_priv->r500_disp_irq_reg); - RADEON_WRITE(RADEON_GEN_INT_CNTL, dev_priv->irq_enable_reg); - return 0; -} - static struct pci_device_id pciidlist[] = { radeon_PCI_IDS }; @@ -81,7 +59,8 @@ static struct pci_device_id pciidlist[] = { static struct drm_driver driver = { .driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | - DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED, + DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED | + DRIVER_IRQ_VBL | DRIVER_IRQ_VBL2, .dev_priv_size = sizeof(drm_radeon_buf_priv_t), .load = radeon_driver_load, .firstopen = radeon_driver_firstopen, @@ -90,11 +69,8 @@ static struct drm_driver driver = { .postclose = radeon_driver_postclose, .lastclose = radeon_driver_lastclose, .unload = radeon_driver_unload, - .suspend = radeon_suspend, - .resume = radeon_resume, - .get_vblank_counter = radeon_get_vblank_counter, - .enable_vblank = radeon_enable_vblank, - .disable_vblank = radeon_disable_vblank, + .vblank_wait = radeon_driver_vblank_wait, + .vblank_wait2 = radeon_driver_vblank_wait2, .dri_library_name = dri_library_name, .irq_preinstall = radeon_driver_irq_preinstall, .irq_postinstall = radeon_driver_irq_postinstall, diff --git a/trunk/drivers/gpu/drm/radeon/radeon_drv.h b/trunk/drivers/gpu/drm/radeon/radeon_drv.h index 4dbb813910c3..099381693175 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_drv.h +++ b/trunk/drivers/gpu/drm/radeon/radeon_drv.h @@ -122,12 +122,9 @@ enum radeon_family { CHIP_RV350, CHIP_RV380, CHIP_R420, - CHIP_R423, CHIP_RV410, - CHIP_RS400, CHIP_RS480, CHIP_RS690, - CHIP_RS740, CHIP_RV515, CHIP_R520, CHIP_RV530, @@ -381,17 +378,17 @@ extern void radeon_mem_release(struct drm_file *file_priv, struct mem_block *heap); /* radeon_irq.c */ -extern void radeon_irq_set_state(struct drm_device *dev, u32 mask, int state); extern int radeon_irq_emit(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int radeon_irq_wait(struct drm_device *dev, void *data, struct drm_file *file_priv); extern void radeon_do_release(struct drm_device * dev); -extern u32 radeon_get_vblank_counter(struct drm_device *dev, int crtc); -extern int radeon_enable_vblank(struct drm_device *dev, int crtc); -extern void radeon_disable_vblank(struct drm_device *dev, int crtc); +extern int radeon_driver_vblank_wait(struct drm_device * dev, + unsigned int *sequence); +extern int radeon_driver_vblank_wait2(struct drm_device * dev, + unsigned int *sequence); extern irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS); extern void radeon_driver_irq_preinstall(struct drm_device * dev); -extern int radeon_driver_irq_postinstall(struct drm_device *dev); +extern void radeon_driver_irq_postinstall(struct drm_device * dev); extern void radeon_driver_irq_uninstall(struct drm_device * dev); extern void radeon_enable_interrupt(struct drm_device *dev); extern int radeon_vblank_crtc_get(struct drm_device *dev); @@ -400,22 +397,19 @@ extern int radeon_vblank_crtc_set(struct drm_device *dev, int64_t value); extern int radeon_driver_load(struct drm_device *dev, unsigned long flags); extern int radeon_driver_unload(struct drm_device *dev); extern int radeon_driver_firstopen(struct drm_device *dev); -extern void radeon_driver_preclose(struct drm_device *dev, - struct drm_file *file_priv); -extern void radeon_driver_postclose(struct drm_device *dev, - struct drm_file *file_priv); +extern void radeon_driver_preclose(struct drm_device * dev, struct drm_file *file_priv); +extern void radeon_driver_postclose(struct drm_device * dev, struct drm_file * filp); extern void radeon_driver_lastclose(struct drm_device * dev); -extern int radeon_driver_open(struct drm_device *dev, - struct drm_file *file_priv); +extern int radeon_driver_open(struct drm_device * dev, struct drm_file * filp_priv); extern long radeon_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); /* r300_cmdbuf.c */ extern void r300_init_reg_flags(struct drm_device *dev); -extern int r300_do_cp_cmdbuf(struct drm_device *dev, +extern int r300_do_cp_cmdbuf(struct drm_device * dev, struct drm_file *file_priv, - drm_radeon_kcmd_buffer_t *cmdbuf); + drm_radeon_kcmd_buffer_t * cmdbuf); /* Flags for stats.boxes */ @@ -440,31 +434,8 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev, # define RADEON_SCISSOR_1_ENABLE (1 << 29) # define RADEON_SCISSOR_2_ENABLE (1 << 30) -/* - * PCIE radeons (rv370/rv380, rv410, r423/r430/r480, r5xx) - * don't have an explicit bus mastering disable bit. It's handled - * by the PCI D-states. PMI_BM_DIS disables D-state bus master - * handling, not bus mastering itself. - */ #define RADEON_BUS_CNTL 0x0030 -/* r1xx, r2xx, r300, r(v)350, r420/r481, rs480 */ # define RADEON_BUS_MASTER_DIS (1 << 6) -/* rs400, rs690/rs740 */ -# define RS400_BUS_MASTER_DIS (1 << 14) -# define RS400_MSI_REARM (1 << 20) -/* see RS480_MSI_REARM in AIC_CNTL for rs480 */ - -#define RADEON_BUS_CNTL1 0x0034 -# define RADEON_PMI_BM_DIS (1 << 2) -# define RADEON_PMI_INT_DIS (1 << 3) - -#define RV370_BUS_CNTL 0x004c -# define RV370_PMI_BM_DIS (1 << 5) -# define RV370_PMI_INT_DIS (1 << 6) - -#define RADEON_MSI_REARM_EN 0x0160 -/* rv370/rv380, rv410, r423/r430/r480, r5xx */ -# define RV370_MSI_REARM_EN (1 << 0) #define RADEON_CLOCK_CNTL_DATA 0x000c # define RADEON_PLL_WR_EN (1 << 7) @@ -652,7 +623,6 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev, # define RADEON_SW_INT_TEST (1 << 25) # define RADEON_SW_INT_TEST_ACK (1 << 25) # define RADEON_SW_INT_FIRE (1 << 26) -# define R500_DISPLAY_INT_STATUS (1 << 0) #define RADEON_HOST_PATH_CNTL 0x0130 # define RADEON_HDP_SOFT_RESET (1 << 26) @@ -937,7 +907,6 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev, #define RADEON_AIC_CNTL 0x01d0 # define RADEON_PCIGART_TRANSLATE_EN (1 << 0) -# define RS480_MSI_REARM (1 << 3) #define RADEON_AIC_STAT 0x01d4 #define RADEON_AIC_PT_BASE 0x01d8 #define RADEON_AIC_LO_ADDR 0x01dc @@ -1147,9 +1116,6 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev, #define R200_VAP_PVS_CNTL_1 0x22D0 -#define RADEON_CRTC_CRNT_FRAME 0x0214 -#define RADEON_CRTC2_CRNT_FRAME 0x0314 - #define R500_D1CRTC_STATUS 0x609c #define R500_D2CRTC_STATUS 0x689c #define R500_CRTC_V_BLANK (1<<0) @@ -1234,8 +1200,7 @@ do { \ #define IGP_WRITE_MCIND(addr, val) \ do { \ - if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || \ - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) \ + if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) \ RS690_WRITE_MCIND(addr, val); \ else \ RS480_WRITE_MCIND(addr, val); \ diff --git a/trunk/drivers/gpu/drm/radeon/radeon_irq.c b/trunk/drivers/gpu/drm/radeon/radeon_irq.c index 5079f7054a2f..ee40d197deb7 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_irq.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_irq.c @@ -27,7 +27,7 @@ * * Authors: * Keith Whitwell - * Michel D�zer + * Michel Dänzer */ #include "drmP.h" @@ -35,128 +35,12 @@ #include "radeon_drm.h" #include "radeon_drv.h" -void radeon_irq_set_state(struct drm_device *dev, u32 mask, int state) +static __inline__ u32 radeon_acknowledge_irqs(drm_radeon_private_t * dev_priv, + u32 mask) { - drm_radeon_private_t *dev_priv = dev->dev_private; - - if (state) - dev_priv->irq_enable_reg |= mask; - else - dev_priv->irq_enable_reg &= ~mask; - - RADEON_WRITE(RADEON_GEN_INT_CNTL, dev_priv->irq_enable_reg); -} - -static void r500_vbl_irq_set_state(struct drm_device *dev, u32 mask, int state) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - - if (state) - dev_priv->r500_disp_irq_reg |= mask; - else - dev_priv->r500_disp_irq_reg &= ~mask; - - RADEON_WRITE(R500_DxMODE_INT_MASK, dev_priv->r500_disp_irq_reg); -} - -int radeon_enable_vblank(struct drm_device *dev, int crtc) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) { - switch (crtc) { - case 0: - r500_vbl_irq_set_state(dev, R500_D1MODE_INT_MASK, 1); - break; - case 1: - r500_vbl_irq_set_state(dev, R500_D2MODE_INT_MASK, 1); - break; - default: - DRM_ERROR("tried to enable vblank on non-existent crtc %d\n", - crtc); - return EINVAL; - } - } else { - switch (crtc) { - case 0: - radeon_irq_set_state(dev, RADEON_CRTC_VBLANK_MASK, 1); - break; - case 1: - radeon_irq_set_state(dev, RADEON_CRTC2_VBLANK_MASK, 1); - break; - default: - DRM_ERROR("tried to enable vblank on non-existent crtc %d\n", - crtc); - return EINVAL; - } - } - - return 0; -} - -void radeon_disable_vblank(struct drm_device *dev, int crtc) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) { - switch (crtc) { - case 0: - r500_vbl_irq_set_state(dev, R500_D1MODE_INT_MASK, 0); - break; - case 1: - r500_vbl_irq_set_state(dev, R500_D2MODE_INT_MASK, 0); - break; - default: - DRM_ERROR("tried to enable vblank on non-existent crtc %d\n", - crtc); - break; - } - } else { - switch (crtc) { - case 0: - radeon_irq_set_state(dev, RADEON_CRTC_VBLANK_MASK, 0); - break; - case 1: - radeon_irq_set_state(dev, RADEON_CRTC2_VBLANK_MASK, 0); - break; - default: - DRM_ERROR("tried to enable vblank on non-existent crtc %d\n", - crtc); - break; - } - } -} - -static inline u32 radeon_acknowledge_irqs(drm_radeon_private_t *dev_priv, u32 *r500_disp_int) -{ - u32 irqs = RADEON_READ(RADEON_GEN_INT_STATUS); - u32 irq_mask = RADEON_SW_INT_TEST; - - *r500_disp_int = 0; - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) { - /* vbl interrupts in a different place */ - - if (irqs & R500_DISPLAY_INT_STATUS) { - /* if a display interrupt */ - u32 disp_irq; - - disp_irq = RADEON_READ(R500_DISP_INTERRUPT_STATUS); - - *r500_disp_int = disp_irq; - if (disp_irq & R500_D1_VBLANK_INTERRUPT) - RADEON_WRITE(R500_D1MODE_VBLANK_STATUS, R500_VBLANK_ACK); - if (disp_irq & R500_D2_VBLANK_INTERRUPT) - RADEON_WRITE(R500_D2MODE_VBLANK_STATUS, R500_VBLANK_ACK); - } - irq_mask |= R500_DISPLAY_INT_STATUS; - } else - irq_mask |= RADEON_CRTC_VBLANK_STAT | RADEON_CRTC2_VBLANK_STAT; - - irqs &= irq_mask; - + u32 irqs = RADEON_READ(RADEON_GEN_INT_STATUS) & mask; if (irqs) RADEON_WRITE(RADEON_GEN_INT_STATUS, irqs); - return irqs; } @@ -184,33 +68,44 @@ irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS) drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private; u32 stat; - u32 r500_disp_int; /* Only consider the bits we're interested in - others could be used * outside the DRM */ - stat = radeon_acknowledge_irqs(dev_priv, &r500_disp_int); + stat = radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK | + RADEON_CRTC_VBLANK_STAT | + RADEON_CRTC2_VBLANK_STAT)); if (!stat) return IRQ_NONE; stat &= dev_priv->irq_enable_reg; /* SW interrupt */ - if (stat & RADEON_SW_INT_TEST) + if (stat & RADEON_SW_INT_TEST) { DRM_WAKEUP(&dev_priv->swi_queue); + } /* VBLANK interrupt */ - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) { - if (r500_disp_int & R500_D1_VBLANK_INTERRUPT) - drm_handle_vblank(dev, 0); - if (r500_disp_int & R500_D2_VBLANK_INTERRUPT) - drm_handle_vblank(dev, 1); - } else { - if (stat & RADEON_CRTC_VBLANK_STAT) - drm_handle_vblank(dev, 0); - if (stat & RADEON_CRTC2_VBLANK_STAT) - drm_handle_vblank(dev, 1); + if (stat & (RADEON_CRTC_VBLANK_STAT|RADEON_CRTC2_VBLANK_STAT)) { + int vblank_crtc = dev_priv->vblank_crtc; + + if ((vblank_crtc & + (DRM_RADEON_VBLANK_CRTC1 | DRM_RADEON_VBLANK_CRTC2)) == + (DRM_RADEON_VBLANK_CRTC1 | DRM_RADEON_VBLANK_CRTC2)) { + if (stat & RADEON_CRTC_VBLANK_STAT) + atomic_inc(&dev->vbl_received); + if (stat & RADEON_CRTC2_VBLANK_STAT) + atomic_inc(&dev->vbl_received2); + } else if (((stat & RADEON_CRTC_VBLANK_STAT) && + (vblank_crtc & DRM_RADEON_VBLANK_CRTC1)) || + ((stat & RADEON_CRTC2_VBLANK_STAT) && + (vblank_crtc & DRM_RADEON_VBLANK_CRTC2))) + atomic_inc(&dev->vbl_received); + + DRM_WAKEUP(&dev->vbl_queue); + drm_vbl_send_signals(dev); } + return IRQ_HANDLED; } @@ -249,31 +144,54 @@ static int radeon_wait_irq(struct drm_device * dev, int swi_nr) return ret; } -u32 radeon_get_vblank_counter(struct drm_device *dev, int crtc) +static int radeon_driver_vblank_do_wait(struct drm_device * dev, + unsigned int *sequence, int crtc) { - drm_radeon_private_t *dev_priv = dev->dev_private; - + drm_radeon_private_t *dev_priv = + (drm_radeon_private_t *) dev->dev_private; + unsigned int cur_vblank; + int ret = 0; + int ack = 0; + atomic_t *counter; if (!dev_priv) { DRM_ERROR("called with no initialization\n"); return -EINVAL; } - if (crtc < 0 || crtc > 1) { - DRM_ERROR("Invalid crtc %d\n", crtc); + if (crtc == DRM_RADEON_VBLANK_CRTC1) { + counter = &dev->vbl_received; + ack |= RADEON_CRTC_VBLANK_STAT; + } else if (crtc == DRM_RADEON_VBLANK_CRTC2) { + counter = &dev->vbl_received2; + ack |= RADEON_CRTC2_VBLANK_STAT; + } else return -EINVAL; - } - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) { - if (crtc == 0) - return RADEON_READ(R500_D1CRTC_FRAME_COUNT); - else - return RADEON_READ(R500_D2CRTC_FRAME_COUNT); - } else { - if (crtc == 0) - return RADEON_READ(RADEON_CRTC_CRNT_FRAME); - else - return RADEON_READ(RADEON_CRTC2_CRNT_FRAME); - } + radeon_acknowledge_irqs(dev_priv, ack); + + dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; + + /* Assume that the user has missed the current sequence number + * by about a day rather than she wants to wait for years + * using vertical blanks... + */ + DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ, + (((cur_vblank = atomic_read(counter)) + - *sequence) <= (1 << 23))); + + *sequence = cur_vblank; + + return ret; +} + +int radeon_driver_vblank_wait(struct drm_device *dev, unsigned int *sequence) +{ + return radeon_driver_vblank_do_wait(dev, sequence, DRM_RADEON_VBLANK_CRTC1); +} + +int radeon_driver_vblank_wait2(struct drm_device *dev, unsigned int *sequence) +{ + return radeon_driver_vblank_do_wait(dev, sequence, DRM_RADEON_VBLANK_CRTC2); } /* Needs the lock as it touches the ring. @@ -316,41 +234,46 @@ int radeon_irq_wait(struct drm_device *dev, void *data, struct drm_file *file_pr return radeon_wait_irq(dev, irqwait->irq_seq); } +void radeon_enable_interrupt(struct drm_device *dev) +{ + drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private; + + dev_priv->irq_enable_reg = RADEON_SW_INT_ENABLE; + if (dev_priv->vblank_crtc & DRM_RADEON_VBLANK_CRTC1) + dev_priv->irq_enable_reg |= RADEON_CRTC_VBLANK_MASK; + + if (dev_priv->vblank_crtc & DRM_RADEON_VBLANK_CRTC2) + dev_priv->irq_enable_reg |= RADEON_CRTC2_VBLANK_MASK; + + RADEON_WRITE(RADEON_GEN_INT_CNTL, dev_priv->irq_enable_reg); + dev_priv->irq_enabled = 1; +} + /* drm_dma.h hooks */ void radeon_driver_irq_preinstall(struct drm_device * dev) { drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private; - u32 dummy; /* Disable *all* interrupts */ - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) - RADEON_WRITE(R500_DxMODE_INT_MASK, 0); RADEON_WRITE(RADEON_GEN_INT_CNTL, 0); /* Clear bits if they're already high */ - radeon_acknowledge_irqs(dev_priv, &dummy); + radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK | + RADEON_CRTC_VBLANK_STAT | + RADEON_CRTC2_VBLANK_STAT)); } -int radeon_driver_irq_postinstall(struct drm_device *dev) +void radeon_driver_irq_postinstall(struct drm_device * dev) { drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private; - int ret; atomic_set(&dev_priv->swi_emitted, 0); DRM_INIT_WAITQUEUE(&dev_priv->swi_queue); - ret = drm_vblank_init(dev, 2); - if (ret) - return ret; - - dev->max_vblank_count = 0x001fffff; - - radeon_irq_set_state(dev, RADEON_SW_INT_ENABLE, 1); - - return 0; + radeon_enable_interrupt(dev); } void radeon_driver_irq_uninstall(struct drm_device * dev) @@ -362,8 +285,6 @@ void radeon_driver_irq_uninstall(struct drm_device * dev) dev_priv->irq_enabled = 0; - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) - RADEON_WRITE(R500_DxMODE_INT_MASK, 0); /* Disable *all* interrupts */ RADEON_WRITE(RADEON_GEN_INT_CNTL, 0); } @@ -372,8 +293,18 @@ void radeon_driver_irq_uninstall(struct drm_device * dev) int radeon_vblank_crtc_get(struct drm_device *dev) { drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private; + u32 flag; + u32 value; + + flag = RADEON_READ(RADEON_GEN_INT_CNTL); + value = 0; + + if (flag & RADEON_CRTC_VBLANK_MASK) + value |= DRM_RADEON_VBLANK_CRTC1; - return dev_priv->vblank_crtc; + if (flag & RADEON_CRTC2_VBLANK_MASK) + value |= DRM_RADEON_VBLANK_CRTC2; + return value; } int radeon_vblank_crtc_set(struct drm_device *dev, int64_t value) @@ -384,5 +315,6 @@ int radeon_vblank_crtc_set(struct drm_device *dev, int64_t value) return -EINVAL; } dev_priv->vblank_crtc = (unsigned int)value; + radeon_enable_interrupt(dev); return 0; } diff --git a/trunk/drivers/gpu/drm/radeon/radeon_state.c b/trunk/drivers/gpu/drm/radeon/radeon_state.c index 5d7153fcc7b0..11c146b49211 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_state.c +++ b/trunk/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 value = GET_SCRATCH(2); break; case RADEON_PARAM_IRQ_NR: - value = drm_dev_to_irq(dev); + value = dev->irq; break; case RADEON_PARAM_GART_BASE: value = dev_priv->gart_vm_start; diff --git a/trunk/drivers/gpu/drm/sis/sis_mm.c b/trunk/drivers/gpu/drm/sis/sis_mm.c index af22111397d8..b3878770fce1 100644 --- a/trunk/drivers/gpu/drm/sis/sis_mm.c +++ b/trunk/drivers/gpu/drm/sis/sis_mm.c @@ -41,7 +41,7 @@ #define AGP_TYPE 1 -#if defined(CONFIG_FB_SIS) || defined(CONFIG_FB_SIS_MODULE) +#if defined(CONFIG_FB_SIS) /* fb management via fb device */ #define SIS_MM_ALIGN_SHIFT 0 @@ -57,7 +57,7 @@ static void *sis_sman_mm_allocate(void *private, unsigned long size, if (req.size == 0) return NULL; else - return (void *)(unsigned long)~req.offset; + return (void *)~req.offset; } 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) return ~((unsigned long)ref); } -#else /* CONFIG_FB_SIS[_MODULE] */ +#else /* CONFIG_FB_SIS */ #define SIS_MM_ALIGN_SHIFT 4 #define SIS_MM_ALIGN_MASK ( (1 << SIS_MM_ALIGN_SHIFT) - 1) -#endif /* CONFIG_FB_SIS[_MODULE] */ +#endif /* CONFIG_FB_SIS */ static int sis_fb_init(struct drm_device *dev, void *data, struct drm_file *file_priv) { @@ -89,7 +89,7 @@ static int sis_fb_init(struct drm_device *dev, void *data, struct drm_file *file int ret; mutex_lock(&dev->struct_mutex); -#if defined(CONFIG_FB_SIS) || defined(CONFIG_FB_SIS_MODULE) +#if defined(CONFIG_FB_SIS) { struct drm_sman_mm sman_mm; sman_mm.private = (void *)0xFFFFFFFF; diff --git a/trunk/drivers/gpu/drm/via/via_drv.c b/trunk/drivers/gpu/drm/via/via_drv.c index 0993b441fc42..80c01cdfa37d 100644 --- a/trunk/drivers/gpu/drm/via/via_drv.c +++ b/trunk/drivers/gpu/drm/via/via_drv.c @@ -40,13 +40,11 @@ static struct pci_device_id pciidlist[] = { static struct drm_driver driver = { .driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_IRQ | - DRIVER_IRQ_SHARED, + DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL, .load = via_driver_load, .unload = via_driver_unload, .context_dtor = via_final_context, - .get_vblank_counter = via_get_vblank_counter, - .enable_vblank = via_enable_vblank, - .disable_vblank = via_disable_vblank, + .vblank_wait = via_driver_vblank_wait, .irq_preinstall = via_driver_irq_preinstall, .irq_postinstall = via_driver_irq_postinstall, .irq_uninstall = via_driver_irq_uninstall, @@ -61,17 +59,17 @@ static struct drm_driver driver = { .get_reg_ofs = drm_core_get_reg_ofs, .ioctls = via_ioctls, .fops = { - .owner = THIS_MODULE, - .open = drm_open, - .release = drm_release, - .ioctl = drm_ioctl, - .mmap = drm_mmap, - .poll = drm_poll, - .fasync = drm_fasync, - }, + .owner = THIS_MODULE, + .open = drm_open, + .release = drm_release, + .ioctl = drm_ioctl, + .mmap = drm_mmap, + .poll = drm_poll, + .fasync = drm_fasync, + }, .pci_driver = { - .name = DRIVER_NAME, - .id_table = pciidlist, + .name = DRIVER_NAME, + .id_table = pciidlist, }, .name = DRIVER_NAME, diff --git a/trunk/drivers/gpu/drm/via/via_drv.h b/trunk/drivers/gpu/drm/via/via_drv.h index cafcb844a223..2daae81874cd 100644 --- a/trunk/drivers/gpu/drm/via/via_drv.h +++ b/trunk/drivers/gpu/drm/via/via_drv.h @@ -75,7 +75,6 @@ typedef struct drm_via_private { struct timeval last_vblank; int last_vblank_valid; unsigned usec_per_vblank; - atomic_t vbl_received; drm_via_state_t hc_state; char pci_buf[VIA_PCI_BUF_SIZE]; const uint32_t *fire_offsets[VIA_FIRE_BUF_SIZE]; @@ -131,24 +130,21 @@ extern int via_init_context(struct drm_device * dev, int context); extern int via_final_context(struct drm_device * dev, int context); extern int via_do_cleanup_map(struct drm_device * dev); -extern u32 via_get_vblank_counter(struct drm_device *dev, int crtc); -extern int via_enable_vblank(struct drm_device *dev, int crtc); -extern void via_disable_vblank(struct drm_device *dev, int crtc); +extern int via_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence); extern irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS); extern void via_driver_irq_preinstall(struct drm_device * dev); -extern int via_driver_irq_postinstall(struct drm_device *dev); +extern void via_driver_irq_postinstall(struct drm_device * dev); extern void via_driver_irq_uninstall(struct drm_device * dev); extern int via_dma_cleanup(struct drm_device * dev); extern void via_init_command_verifier(void); extern int via_driver_dma_quiescent(struct drm_device * dev); -extern void via_init_futex(drm_via_private_t *dev_priv); -extern void via_cleanup_futex(drm_via_private_t *dev_priv); -extern void via_release_futex(drm_via_private_t *dev_priv, int context); +extern void via_init_futex(drm_via_private_t * dev_priv); +extern void via_cleanup_futex(drm_via_private_t * dev_priv); +extern void via_release_futex(drm_via_private_t * dev_priv, int context); -extern void via_reclaim_buffers_locked(struct drm_device *dev, - struct drm_file *file_priv); +extern void via_reclaim_buffers_locked(struct drm_device *dev, struct drm_file *file_priv); extern void via_lastclose(struct drm_device *dev); extern void via_dmablit_handler(struct drm_device *dev, int engine, int from_irq); diff --git a/trunk/drivers/gpu/drm/via/via_irq.c b/trunk/drivers/gpu/drm/via/via_irq.c index 665d319b927b..c6bb978a1106 100644 --- a/trunk/drivers/gpu/drm/via/via_irq.c +++ b/trunk/drivers/gpu/drm/via/via_irq.c @@ -43,7 +43,7 @@ #define VIA_REG_INTERRUPT 0x200 /* VIA_REG_INTERRUPT */ -#define VIA_IRQ_GLOBAL (1 << 31) +#define VIA_IRQ_GLOBAL (1 << 31) #define VIA_IRQ_VBLANK_ENABLE (1 << 19) #define VIA_IRQ_VBLANK_PENDING (1 << 3) #define VIA_IRQ_HQV0_ENABLE (1 << 11) @@ -68,15 +68,16 @@ static maskarray_t via_pro_group_a_irqs[] = { {VIA_IRQ_HQV0_ENABLE, VIA_IRQ_HQV0_PENDING, 0x000003D0, 0x00008010, - 0x00000000 }, + 0x00000000}, {VIA_IRQ_HQV1_ENABLE, VIA_IRQ_HQV1_PENDING, 0x000013D0, 0x00008010, - 0x00000000 }, + 0x00000000}, {VIA_IRQ_DMA0_TD_ENABLE, VIA_IRQ_DMA0_TD_PENDING, VIA_PCI_DMA_CSR0, VIA_DMA_CSR_TA | VIA_DMA_CSR_TD, 0x00000008}, {VIA_IRQ_DMA1_TD_ENABLE, VIA_IRQ_DMA1_TD_PENDING, VIA_PCI_DMA_CSR1, VIA_DMA_CSR_TA | VIA_DMA_CSR_TD, 0x00000008}, }; -static int via_num_pro_group_a = ARRAY_SIZE(via_pro_group_a_irqs); +static int via_num_pro_group_a = + sizeof(via_pro_group_a_irqs) / sizeof(maskarray_t); static int via_irqmap_pro_group_a[] = {0, 1, -1, 2, -1, 3}; static maskarray_t via_unichrome_irqs[] = { @@ -85,24 +86,14 @@ static maskarray_t via_unichrome_irqs[] = { {VIA_IRQ_DMA1_TD_ENABLE, VIA_IRQ_DMA1_TD_PENDING, VIA_PCI_DMA_CSR1, VIA_DMA_CSR_TA | VIA_DMA_CSR_TD, 0x00000008} }; -static int via_num_unichrome = ARRAY_SIZE(via_unichrome_irqs); +static int via_num_unichrome = sizeof(via_unichrome_irqs) / sizeof(maskarray_t); static int via_irqmap_unichrome[] = {-1, -1, -1, 0, -1, 1}; - static unsigned time_diff(struct timeval *now, struct timeval *then) { return (now->tv_usec >= then->tv_usec) ? - now->tv_usec - then->tv_usec : - 1000000 - (then->tv_usec - now->tv_usec); -} - -u32 via_get_vblank_counter(struct drm_device *dev, int crtc) -{ - drm_via_private_t *dev_priv = dev->dev_private; - if (crtc != 0) - return 0; - - return atomic_read(&dev_priv->vbl_received); + now->tv_usec - then->tv_usec : + 1000000 - (then->tv_usec - now->tv_usec); } irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS) @@ -117,22 +108,23 @@ irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS) status = VIA_READ(VIA_REG_INTERRUPT); if (status & VIA_IRQ_VBLANK_PENDING) { - atomic_inc(&dev_priv->vbl_received); - if (!(atomic_read(&dev_priv->vbl_received) & 0x0F)) { + atomic_inc(&dev->vbl_received); + if (!(atomic_read(&dev->vbl_received) & 0x0F)) { do_gettimeofday(&cur_vblank); if (dev_priv->last_vblank_valid) { dev_priv->usec_per_vblank = - time_diff(&cur_vblank, - &dev_priv->last_vblank) >> 4; + time_diff(&cur_vblank, + &dev_priv->last_vblank) >> 4; } dev_priv->last_vblank = cur_vblank; dev_priv->last_vblank_valid = 1; } - if (!(atomic_read(&dev_priv->vbl_received) & 0xFF)) { + if (!(atomic_read(&dev->vbl_received) & 0xFF)) { DRM_DEBUG("US per vblank is: %u\n", dev_priv->usec_per_vblank); } - drm_handle_vblank(dev, 0); + DRM_WAKEUP(&dev->vbl_queue); + drm_vbl_send_signals(dev); handled = 1; } @@ -153,7 +145,6 @@ irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS) /* Acknowlege interrupts */ VIA_WRITE(VIA_REG_INTERRUPT, status); - if (handled) return IRQ_HANDLED; else @@ -172,34 +163,31 @@ static __inline__ void viadrv_acknowledge_irqs(drm_via_private_t * dev_priv) } } -int via_enable_vblank(struct drm_device *dev, int crtc) +int via_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence) { - drm_via_private_t *dev_priv = dev->dev_private; - u32 status; + drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; + unsigned int cur_vblank; + int ret = 0; - if (crtc != 0) { - DRM_ERROR("%s: bad crtc %d\n", __func__, crtc); + DRM_DEBUG("\n"); + if (!dev_priv) { + DRM_ERROR("called with no initialization\n"); return -EINVAL; } - status = VIA_READ(VIA_REG_INTERRUPT); - VIA_WRITE(VIA_REG_INTERRUPT, status & VIA_IRQ_VBLANK_ENABLE); - - VIA_WRITE8(0x83d4, 0x11); - VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) | 0x30); + viadrv_acknowledge_irqs(dev_priv); - return 0; -} - -void via_disable_vblank(struct drm_device *dev, int crtc) -{ - drm_via_private_t *dev_priv = dev->dev_private; + /* Assume that the user has missed the current sequence number + * by about a day rather than she wants to wait for years + * using vertical blanks... + */ - VIA_WRITE8(0x83d4, 0x11); - VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) & ~0x30); + DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ, + (((cur_vblank = atomic_read(&dev->vbl_received)) - + *sequence) <= (1 << 23))); - if (crtc != 0) - DRM_ERROR("%s: bad crtc %d\n", __func__, crtc); + *sequence = cur_vblank; + return ret; } static int @@ -251,7 +239,6 @@ via_driver_irq_wait(struct drm_device * dev, unsigned int irq, int force_sequenc return ret; } - /* * drm_dma.h hooks */ @@ -305,25 +292,23 @@ void via_driver_irq_preinstall(struct drm_device * dev) } } -int via_driver_irq_postinstall(struct drm_device *dev) +void via_driver_irq_postinstall(struct drm_device * dev) { drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; u32 status; - DRM_DEBUG("via_driver_irq_postinstall\n"); - if (!dev_priv) - return -EINVAL; + DRM_DEBUG("\n"); + if (dev_priv) { + status = VIA_READ(VIA_REG_INTERRUPT); + VIA_WRITE(VIA_REG_INTERRUPT, status | VIA_IRQ_GLOBAL + | dev_priv->irq_enable_mask); - drm_vblank_init(dev, 1); - status = VIA_READ(VIA_REG_INTERRUPT); - VIA_WRITE(VIA_REG_INTERRUPT, status | VIA_IRQ_GLOBAL - | dev_priv->irq_enable_mask); + /* Some magic, oh for some data sheets ! */ - /* Some magic, oh for some data sheets ! */ - VIA_WRITE8(0x83d4, 0x11); - VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) | 0x30); + VIA_WRITE8(0x83d4, 0x11); + VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) | 0x30); - return 0; + } } void via_driver_irq_uninstall(struct drm_device * dev) @@ -354,6 +339,9 @@ int via_wait_irq(struct drm_device *dev, void *data, struct drm_file *file_priv) drm_via_irq_t *cur_irq = dev_priv->via_irqs; int force_sequence; + if (!dev->irq) + return -EINVAL; + if (irqwait->request.irq >= dev_priv->num_irqs) { DRM_ERROR("Trying to wait on unknown irq %d\n", irqwait->request.irq); @@ -364,8 +352,7 @@ int via_wait_irq(struct drm_device *dev, void *data, struct drm_file *file_priv) switch (irqwait->request.type & ~VIA_IRQ_FLAGS_MASK) { case VIA_IRQ_RELATIVE: - irqwait->request.sequence += - atomic_read(&cur_irq->irq_received); + irqwait->request.sequence += atomic_read(&cur_irq->irq_received); irqwait->request.type &= ~_DRM_VBLANK_RELATIVE; case VIA_IRQ_ABSOLUTE: break; diff --git a/trunk/drivers/gpu/drm/via/via_mm.c b/trunk/drivers/gpu/drm/via/via_mm.c index f694cb5ededc..e64094916e4f 100644 --- a/trunk/drivers/gpu/drm/via/via_mm.c +++ b/trunk/drivers/gpu/drm/via/via_mm.c @@ -93,7 +93,8 @@ int via_final_context(struct drm_device *dev, int context) /* Last context, perform cleanup */ if (dev->ctx_count == 1 && dev->dev_private) { DRM_DEBUG("Last Context\n"); - drm_irq_uninstall(dev); + if (dev->irq) + drm_irq_uninstall(dev); via_cleanup_futex(dev_priv); via_do_cleanup_map(dev); } diff --git a/trunk/drivers/media/common/tuners/mxl5005s.c b/trunk/drivers/media/common/tuners/mxl5005s.c index a8878244bb3c..227642b044ae 100644 --- a/trunk/drivers/media/common/tuners/mxl5005s.c +++ b/trunk/drivers/media/common/tuners/mxl5005s.c @@ -3481,9 +3481,7 @@ static u16 MXL_ControlWrite_Group(struct dvb_frontend *fe, u16 controlNum, } ctrlVal = 0; for (k = 0; k < state->MXL_Ctrl[i].size; k++) - ctrlVal += state-> - MXL_Ctrl[i].val[k] * - (1 << k); + ctrlVal += state->MXL_Ctrl[i].val[k] * (1 << k); } else return -1; } @@ -3583,7 +3581,7 @@ static void MXL_RegWriteBit(struct dvb_frontend *fe, u8 address, u8 bit, static u32 MXL_Ceiling(u32 value, u32 resolution) { - return value / resolution + (value % resolution > 0 ? 1 : 0); + return (value/resolution + (value % resolution > 0 ? 1 : 0)); } /* Retrieve the Initialzation Registers */ @@ -3912,10 +3910,7 @@ static int mxl5005s_writeregs(struct dvb_frontend *fe, u8 *addrtable, static int mxl5005s_init(struct dvb_frontend *fe) { - struct mxl5005s_state *state = fe->tuner_priv; - dprintk(1, "%s()\n", __func__); - state->current_mode = MXL_QAM; return mxl5005s_reconfigure(fe, MXL_QAM, MXL5005S_BANDWIDTH_6MHZ); } @@ -4097,6 +4092,7 @@ struct dvb_frontend *mxl5005s_attach(struct dvb_frontend *fe, state->frontend = fe; state->config = config; state->i2c = i2c; + state->current_mode = MXL_QAM; printk(KERN_INFO "MXL5005S: Attached at address 0x%02x\n", config->i2c_address); diff --git a/trunk/drivers/media/common/tuners/tuner-simple.c b/trunk/drivers/media/common/tuners/tuner-simple.c index fb3f3b3adaba..2a1aac1cc755 100644 --- a/trunk/drivers/media/common/tuners/tuner-simple.c +++ b/trunk/drivers/media/common/tuners/tuner-simple.c @@ -493,7 +493,6 @@ static int simple_radio_bandswitch(struct dvb_frontend *fe, u8 *buffer) case TUNER_PHILIPS_FM1216ME_MK3: case TUNER_PHILIPS_FM1236_MK3: case TUNER_PHILIPS_FMD1216ME_MK3: - case TUNER_PHILIPS_FMD1216MEX_MK3: case TUNER_LG_NTSC_TAPE: case TUNER_PHILIPS_FM1256_IH3: case TUNER_TCL_MF02GIP_5N: @@ -768,7 +767,6 @@ static void simple_set_dvb(struct dvb_frontend *fe, u8 *buf, switch (priv->type) { case TUNER_PHILIPS_FMD1216ME_MK3: - case TUNER_PHILIPS_FMD1216MEX_MK3: if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ && params->frequency >= 158870000) buf[3] |= 0x08; diff --git a/trunk/drivers/media/common/tuners/tuner-types.c b/trunk/drivers/media/common/tuners/tuner-types.c index 7c0bc064c008..04961a1f44be 100644 --- a/trunk/drivers/media/common/tuners/tuner-types.c +++ b/trunk/drivers/media/common/tuners/tuner-types.c @@ -946,7 +946,7 @@ static struct tuner_params tuner_tena_9533_di_params[] = { }, }; -/* ------------ TUNER_PHILIPS_FMD1216ME(X)_MK3 - Philips PAL ------------ */ +/* ------------ TUNER_PHILIPS_FMD1216ME_MK3 - Philips PAL ------------ */ static struct tuner_range tuner_philips_fmd1216me_mk3_pal_ranges[] = { { 16 * 160.00 /*MHz*/, 0x86, 0x51, }, @@ -984,27 +984,6 @@ static struct tuner_params tuner_philips_fmd1216me_mk3_params[] = { }, }; -static struct tuner_params tuner_philips_fmd1216mex_mk3_params[] = { - { - .type = TUNER_PARAM_TYPE_PAL, - .ranges = tuner_philips_fmd1216me_mk3_pal_ranges, - .count = ARRAY_SIZE(tuner_philips_fmd1216me_mk3_pal_ranges), - .has_tda9887 = 1, - .port1_active = 1, - .port2_active = 1, - .port2_fm_high_sensitivity = 1, - .port2_invert_for_secam_lc = 1, - .port1_set_for_fm_mono = 1, - .radio_if = 1, - .fm_gain_normal = 1, - }, - { - .type = TUNER_PARAM_TYPE_DIGITAL, - .ranges = tuner_philips_fmd1216me_mk3_dvb_ranges, - .count = ARRAY_SIZE(tuner_philips_fmd1216me_mk3_dvb_ranges), - .iffreq = 16 * 36.125, /*MHz*/ - }, -}; /* ------ TUNER_LG_TDVS_H06XF - LG INNOTEK / INFINEON ATSC ----- */ @@ -1684,16 +1663,6 @@ struct tunertype tuners[] = { .params = tuner_tcl_mf02gip_5n_params, .count = ARRAY_SIZE(tuner_tcl_mf02gip_5n_params), }, - [TUNER_PHILIPS_FMD1216MEX_MK3] = { /* Philips PAL */ - .name = "Philips FMD1216MEX MK3 Hybrid Tuner", - .params = tuner_philips_fmd1216mex_mk3_params, - .count = ARRAY_SIZE(tuner_philips_fmd1216mex_mk3_params), - .min = 16 * 50.87, - .max = 16 * 858.00, - .stepsize = 166667, - .initdata = tua603x_agc112, - .sleepdata = (u8[]){ 4, 0x9c, 0x60, 0x85, 0x54 }, - }, }; EXPORT_SYMBOL(tuners); diff --git a/trunk/drivers/media/common/tuners/xc5000.c b/trunk/drivers/media/common/tuners/xc5000.c index e12d13e0cbe9..f9c2bb917f54 100644 --- a/trunk/drivers/media/common/tuners/xc5000.c +++ b/trunk/drivers/media/common/tuners/xc5000.c @@ -43,7 +43,7 @@ MODULE_PARM_DESC(init_fw, "Load firmware during driver initialization."); static DEFINE_MUTEX(xc5000_list_mutex); static LIST_HEAD(hybrid_tuner_instance_list); -#define dprintk(level, fmt, arg...) if (debug >= level) \ +#define dprintk(level,fmt, arg...) if (debug >= level) \ printk(KERN_INFO "%s: " fmt, "xc5000", ## arg) #define XC5000_DEFAULT_FIRMWARE "dvb-fe-xc5000-1.1.fw" @@ -138,11 +138,11 @@ struct xc5000_priv { immediately the length of the following transaction. */ -struct XC_TV_STANDARD { +typedef struct { char *Name; u16 AudioMode; u16 VideoMode; -}; +} XC_TV_STANDARD; /* Tuner standards */ #define MN_NTSC_PAL_BTSC 0 @@ -169,7 +169,7 @@ struct XC_TV_STANDARD { #define FM_Radio_INPUT2 21 #define FM_Radio_INPUT1 22 -static struct XC_TV_STANDARD XC5000_Standard[MAX_TV_STANDARD] = { +static XC_TV_STANDARD XC5000_Standard[MAX_TV_STANDARD] = { {"M/N-NTSC/PAL-BTSC", 0x0400, 0x8020}, {"M/N-NTSC/PAL-A2", 0x0600, 0x8020}, {"M/N-NTSC/PAL-EIAJ", 0x0440, 0x8020}, @@ -183,7 +183,7 @@ static struct XC_TV_STANDARD XC5000_Standard[MAX_TV_STANDARD] = { {"D/K-PAL-NICAM", 0x0E80, 0x8009}, {"D/K-PAL-MONO", 0x1478, 0x8009}, {"D/K-SECAM-A2 DK1", 0x1200, 0x8009}, - {"D/K-SECAM-A2 L/DK3", 0x0E00, 0x8009}, + {"D/K-SECAM-A2 L/DK3",0x0E00, 0x8009}, {"D/K-SECAM-A2 MONO", 0x1478, 0x8009}, {"L-SECAM-NICAM", 0x8E82, 0x0009}, {"L'-SECAM-NICAM", 0x8E82, 0x4009}, @@ -307,10 +307,9 @@ static int xc_load_i2c_sequence(struct dvb_frontend *fe, const u8 *i2c_sequence) unsigned int len, pos, index; u8 buf[XC_MAX_I2C_WRITE_LENGTH]; - index = 0; - while ((i2c_sequence[index] != 0xFF) || - (i2c_sequence[index + 1] != 0xFF)) { - len = i2c_sequence[index] * 256 + i2c_sequence[index+1]; + index=0; + while ((i2c_sequence[index]!=0xFF) || (i2c_sequence[index+1]!=0xFF)) { + len = i2c_sequence[index]* 256 + i2c_sequence[index+1]; if (len == 0x0000) { /* RESET command */ result = xc_reset(fe); @@ -330,17 +329,15 @@ static int xc_load_i2c_sequence(struct dvb_frontend *fe, const u8 *i2c_sequence) buf[1] = i2c_sequence[index + 1]; pos = 2; while (pos < len) { - if ((len - pos) > XC_MAX_I2C_WRITE_LENGTH - 2) - nbytes_to_send = - XC_MAX_I2C_WRITE_LENGTH; - else + if ((len - pos) > XC_MAX_I2C_WRITE_LENGTH - 2) { + nbytes_to_send = XC_MAX_I2C_WRITE_LENGTH; + } else { nbytes_to_send = (len - pos + 2); - for (i = 2; i < nbytes_to_send; i++) { - buf[i] = i2c_sequence[index + pos + - i - 2]; } - result = xc_send_i2c_data(priv, buf, - nbytes_to_send); + for (i=2; ii2c_props.adap, &msg, 1) != 1) { - printk(KERN_ERR "xc5000 I2C read failed (len=%i)\n", (int)len); + printk(KERN_ERR "xc5000 I2C read failed (len=%i)\n",(int)len); return -EREMOTEIO; } return 0; } -static int xc5000_fwupload(struct dvb_frontend *fe) +static int xc5000_fwupload(struct dvb_frontend* fe) { struct xc5000_priv *priv = fe->tuner_priv; const struct firmware *fw; @@ -578,8 +576,7 @@ static int xc5000_fwupload(struct dvb_frontend *fe) printk(KERN_INFO "xc5000: waiting for firmware upload (%s)...\n", XC5000_DEFAULT_FIRMWARE); - ret = request_firmware(&fw, XC5000_DEFAULT_FIRMWARE, - &priv->i2c_props.adap->dev); + ret = request_firmware(&fw, XC5000_DEFAULT_FIRMWARE, &priv->i2c_props.adap->dev); if (ret) { printk(KERN_ERR "xc5000: Upload failed. (file not found?)\n"); ret = XC_RESULT_RESET_FAILURE; @@ -595,7 +592,7 @@ static int xc5000_fwupload(struct dvb_frontend *fe) ret = XC_RESULT_RESET_FAILURE; } else { printk(KERN_INFO "xc5000: firmware upload\n"); - ret = xc_load_i2c_sequence(fe, fw->data); + ret = xc_load_i2c_sequence(fe, fw->data ); } out: @@ -654,7 +651,7 @@ static int xc5000_set_params(struct dvb_frontend *fe, dprintk(1, "%s() frequency=%d (Hz)\n", __func__, params->frequency); - switch (params->u.vsb.modulation) { + switch(params->u.vsb.modulation) { case VSB_8: case VSB_16: dprintk(1, "%s() VSB modulation\n", __func__); @@ -751,42 +748,42 @@ static int xc5000_set_analog_params(struct dvb_frontend *fe, /* FIX ME: Some video standards may have several possible audio standards. We simply default to one of them here. */ - if (params->std & V4L2_STD_MN) { + if(params->std & V4L2_STD_MN) { /* default to BTSC audio standard */ priv->video_standard = MN_NTSC_PAL_BTSC; goto tune_channel; } - if (params->std & V4L2_STD_PAL_BG) { + if(params->std & V4L2_STD_PAL_BG) { /* default to NICAM audio standard */ priv->video_standard = BG_PAL_NICAM; goto tune_channel; } - if (params->std & V4L2_STD_PAL_I) { + if(params->std & V4L2_STD_PAL_I) { /* default to NICAM audio standard */ priv->video_standard = I_PAL_NICAM; goto tune_channel; } - if (params->std & V4L2_STD_PAL_DK) { + if(params->std & V4L2_STD_PAL_DK) { /* default to NICAM audio standard */ priv->video_standard = DK_PAL_NICAM; goto tune_channel; } - if (params->std & V4L2_STD_SECAM_DK) { + if(params->std & V4L2_STD_SECAM_DK) { /* default to A2 DK1 audio standard */ priv->video_standard = DK_SECAM_A2DK1; goto tune_channel; } - if (params->std & V4L2_STD_SECAM_L) { + if(params->std & V4L2_STD_SECAM_L) { priv->video_standard = L_SECAM_NICAM; goto tune_channel; } - if (params->std & V4L2_STD_SECAM_LC) { + if(params->std & V4L2_STD_SECAM_LC) { priv->video_standard = LC_SECAM_NICAM; goto tune_channel; } @@ -794,7 +791,7 @@ static int xc5000_set_analog_params(struct dvb_frontend *fe, tune_channel: ret = xc_SetSignalSource(priv, priv->rf_mode); if (ret != XC_RESULT_SUCCESS) { - printk(KERN_ERR + printk(KERN_ERR "xc5000: xc_SetSignalSource(%d) failed\n", priv->rf_mode); return -EREMOTEIO; @@ -866,7 +863,7 @@ static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe) * I2C transactions until calibration is complete. This way we * don't have to rely on clock stretching working. */ - xc_wait(100); + xc_wait( 100 ); /* Default to "CABLE" mode */ ret |= xc_write_reg(priv, XREG_SIGNALSOURCE, XC_RF_MODE_CABLE); @@ -888,13 +885,15 @@ static int xc5000_sleep(struct dvb_frontend *fe) */ ret = xc_shutdown(priv); - if (ret != XC_RESULT_SUCCESS) { + if(ret != XC_RESULT_SUCCESS) { printk(KERN_ERR "xc5000: %s() unable to shutdown tuner\n", __func__); return -EREMOTEIO; - } else + } + else { return XC_RESULT_SUCCESS; + } } static int xc5000_init(struct dvb_frontend *fe) @@ -990,7 +989,7 @@ struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe, if (xc5000_readreg(priv, XREG_PRODUCT_ID, &id) != 0) goto fail; - switch (id) { + switch(id) { case XC_PRODUCT_ID_FW_LOADED: printk(KERN_INFO "xc5000: Successfully identified at address 0x%02x\n", diff --git a/trunk/drivers/media/common/tuners/xc5000.h b/trunk/drivers/media/common/tuners/xc5000.h index f4c146698a00..cf1a558e0e7f 100644 --- a/trunk/drivers/media/common/tuners/xc5000.h +++ b/trunk/drivers/media/common/tuners/xc5000.h @@ -45,17 +45,17 @@ struct xc5000_config { #if defined(CONFIG_MEDIA_TUNER_XC5000) || \ (defined(CONFIG_MEDIA_TUNER_XC5000_MODULE) && defined(MODULE)) -extern struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe, +extern struct dvb_frontend* xc5000_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct xc5000_config *cfg); #else -static inline struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe, +static inline struct dvb_frontend* xc5000_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct xc5000_config *cfg) { printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } -#endif +#endif // CONFIG_MEDIA_TUNER_XC5000 -#endif +#endif // __XC5000_H__ diff --git a/trunk/drivers/media/dvb/dm1105/dm1105.c b/trunk/drivers/media/dvb/dm1105/dm1105.c index 14e627ef6465..f7321448b4b1 100644 --- a/trunk/drivers/media/dvb/dm1105/dm1105.c +++ b/trunk/drivers/media/dvb/dm1105/dm1105.c @@ -595,18 +595,6 @@ static void dm1105dvb_hw_exit(struct dm1105dvb *dm1105dvb) dm1105dvb_dma_unmap(dm1105dvb); } -static struct stv0299_config sharp_z0194a_config = { - .demod_address = 0x68, - .inittab = sharp_z0194a_inittab, - .mclk = 88000000UL, - .invert = 1, - .skip_reinit = 0, - .lock_output = STV0299_LOCKOUTPUT_1, - .volt13_op0_op1 = STV0299_VOLT13_OP1, - .min_delay_ms = 100, - .set_symbol_rate = sharp_z0194a_set_symbol_rate, -}; - static struct stv0288_config earda_config = { .demod_address = 0x68, .min_delay_ms = 100, diff --git a/trunk/drivers/media/dvb/dvb-core/dvb_frontend.c b/trunk/drivers/media/dvb/dvb-core/dvb_frontend.c index 5689d1f1d444..f170e822fadc 100644 --- a/trunk/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/trunk/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -47,7 +47,6 @@ static int dvb_shutdown_timeout; static int dvb_force_auto_inversion; static int dvb_override_tune_delay; static int dvb_powerdown_on_sleep = 1; -static int dvb_mfe_wait_time = 5; module_param_named(frontend_debug, dvb_frontend_debug, int, 0644); MODULE_PARM_DESC(frontend_debug, "Turn on/off frontend core debugging (default:off)."); @@ -59,8 +58,6 @@ module_param(dvb_override_tune_delay, int, 0644); MODULE_PARM_DESC(dvb_override_tune_delay, "0: normal (default), >0 => delay in milliseconds to wait for lock after a tune attempt"); module_param(dvb_powerdown_on_sleep, int, 0644); MODULE_PARM_DESC(dvb_powerdown_on_sleep, "0: do not power down, 1: turn LNB voltage off on sleep (default)"); -module_param(dvb_mfe_wait_time, int, 0644); -MODULE_PARM_DESC(dvb_mfe_wait_time, "Wait up to seconds on open() for multi-frontend to become available (default:5 seconds)"); #define dprintk if (dvb_frontend_debug) printk @@ -215,9 +212,8 @@ static int dvb_frontend_get_event(struct dvb_frontend *fe, static void dvb_frontend_init(struct dvb_frontend *fe) { - dprintk ("DVB: initialising adapter %i frontend %i (%s)...\n", + dprintk ("DVB: initialising frontend %i (%s)...\n", fe->dvb->num, - fe->id, fe->ops.info.name); if (fe->ops.init) @@ -690,7 +686,7 @@ static int dvb_frontend_start(struct dvb_frontend *fe) mb(); fe_thread = kthread_run(dvb_frontend_thread, fe, - "kdvb-ad-%i-fe-%i", fe->dvb->num,fe->id); + "kdvb-fe-%i", fe->dvb->num); if (IS_ERR(fe_thread)) { ret = PTR_ERR(fe_thread); printk("dvb_frontend_start: failed to start kthread (%d)\n", ret); @@ -714,8 +710,8 @@ static void dvb_frontend_get_frequeny_limits(struct dvb_frontend *fe, *freq_max = min(fe->ops.info.frequency_max, fe->ops.tuner_ops.info.frequency_max); if (*freq_min == 0 || *freq_max == 0) - printk(KERN_WARNING "DVB: adapter %i frontend %u frequency limits undefined - fix the driver\n", - fe->dvb->num,fe->id); + printk(KERN_WARNING "DVB: frontend %u frequency limits undefined - fix the driver\n", + fe->dvb->num); } static int dvb_frontend_check_parameters(struct dvb_frontend *fe, @@ -728,8 +724,8 @@ static int dvb_frontend_check_parameters(struct dvb_frontend *fe, dvb_frontend_get_frequeny_limits(fe, &freq_min, &freq_max); if ((freq_min && parms->frequency < freq_min) || (freq_max && parms->frequency > freq_max)) { - printk(KERN_WARNING "DVB: adapter %i frontend %i frequency %u out of range (%u..%u)\n", - fe->dvb->num, fe->id, parms->frequency, freq_min, freq_max); + printk(KERN_WARNING "DVB: frontend %u frequency %u out of range (%u..%u)\n", + fe->dvb->num, parms->frequency, freq_min, freq_max); return -EINVAL; } @@ -739,8 +735,8 @@ static int dvb_frontend_check_parameters(struct dvb_frontend *fe, parms->u.qpsk.symbol_rate < fe->ops.info.symbol_rate_min) || (fe->ops.info.symbol_rate_max && parms->u.qpsk.symbol_rate > fe->ops.info.symbol_rate_max)) { - printk(KERN_WARNING "DVB: adapter %i frontend %i symbol rate %u out of range (%u..%u)\n", - fe->dvb->num, fe->id, parms->u.qpsk.symbol_rate, + printk(KERN_WARNING "DVB: frontend %u symbol rate %u out of range (%u..%u)\n", + fe->dvb->num, parms->u.qpsk.symbol_rate, fe->ops.info.symbol_rate_min, fe->ops.info.symbol_rate_max); return -EINVAL; } @@ -750,8 +746,8 @@ static int dvb_frontend_check_parameters(struct dvb_frontend *fe, parms->u.qam.symbol_rate < fe->ops.info.symbol_rate_min) || (fe->ops.info.symbol_rate_max && parms->u.qam.symbol_rate > fe->ops.info.symbol_rate_max)) { - printk(KERN_WARNING "DVB: adapter %i frontend %i symbol rate %u out of range (%u..%u)\n", - fe->dvb->num, fe->id, parms->u.qam.symbol_rate, + printk(KERN_WARNING "DVB: frontend %u symbol rate %u out of range (%u..%u)\n", + fe->dvb->num, parms->u.qam.symbol_rate, fe->ops.info.symbol_rate_min, fe->ops.info.symbol_rate_max); return -EINVAL; } @@ -903,30 +899,30 @@ void dtv_property_dump(struct dtv_property *tvp) int i; if (tvp->cmd <= 0 || tvp->cmd > DTV_MAX_COMMAND) { - printk(KERN_WARNING "%s: tvp.cmd = 0x%08x undefined\n", + printk("%s: tvp.cmd = 0x%08x (undefined/unknown/invalid)\n", __func__, tvp->cmd); return; } - dprintk("%s() tvp.cmd = 0x%08x (%s)\n" - ,__func__ + printk("%s() tvp.cmd = 0x%08x (%s)\n" + ,__FUNCTION__ ,tvp->cmd ,dtv_cmds[ tvp->cmd ].name); if(dtv_cmds[ tvp->cmd ].buffer) { - dprintk("%s() tvp.u.buffer.len = 0x%02x\n" - ,__func__ + printk("%s() tvp.u.buffer.len = 0x%02x\n" + ,__FUNCTION__ ,tvp->u.buffer.len); for(i = 0; i < tvp->u.buffer.len; i++) - dprintk("%s() tvp.u.buffer.data[0x%02x] = 0x%02x\n" - ,__func__ + printk("%s() tvp.u.buffer.data[0x%02x] = 0x%02x\n" + ,__FUNCTION__ ,i ,tvp->u.buffer.data[i]); } else - dprintk("%s() tvp.u.data = 0x%08x\n", __func__, tvp->u.data); + printk("%s() tvp.u.data = 0x%08x\n", __FUNCTION__, tvp->u.data); } int is_legacy_delivery_system(fe_delivery_system_t s) @@ -946,6 +942,8 @@ void dtv_property_cache_sync(struct dvb_frontend *fe, struct dvb_frontend_parame { struct dtv_frontend_properties *c = &fe->dtv_property_cache; + printk("%s()\n", __FUNCTION__); + c->frequency = p->frequency; c->inversion = p->inversion; @@ -1000,25 +998,27 @@ void dtv_property_legacy_params_sync(struct dvb_frontend *fe) struct dvb_frontend_private *fepriv = fe->frontend_priv; struct dvb_frontend_parameters *p = &fepriv->parameters; + printk("%s()\n", __FUNCTION__); + p->frequency = c->frequency; p->inversion = c->inversion; switch (fe->ops.info.type) { case FE_QPSK: - dprintk("%s() Preparing QPSK req\n", __func__); + printk("%s() Preparing QPSK req\n", __FUNCTION__); p->u.qpsk.symbol_rate = c->symbol_rate; p->u.qpsk.fec_inner = c->fec_inner; c->delivery_system = SYS_DVBS; break; case FE_QAM: - dprintk("%s() Preparing QAM req\n", __func__); + printk("%s() Preparing QAM req\n", __FUNCTION__); p->u.qam.symbol_rate = c->symbol_rate; p->u.qam.fec_inner = c->fec_inner; p->u.qam.modulation = c->modulation; c->delivery_system = SYS_DVBC_ANNEX_AC; break; case FE_OFDM: - dprintk("%s() Preparing OFDM req\n", __func__); + printk("%s() Preparing OFDM req\n", __FUNCTION__); if (c->bandwidth_hz == 6000000) p->u.ofdm.bandwidth = BANDWIDTH_6_MHZ; else if (c->bandwidth_hz == 7000000) @@ -1036,7 +1036,7 @@ void dtv_property_legacy_params_sync(struct dvb_frontend *fe) c->delivery_system = SYS_DVBT; break; case FE_ATSC: - dprintk("%s() Preparing VSB req\n", __func__); + printk("%s() Preparing VSB req\n", __FUNCTION__); p->u.vsb.modulation = c->modulation; if ((c->modulation == VSB_8) || (c->modulation == VSB_16)) c->delivery_system = SYS_ATSC; @@ -1055,13 +1055,14 @@ void dtv_property_adv_params_sync(struct dvb_frontend *fe) struct dvb_frontend_private *fepriv = fe->frontend_priv; struct dvb_frontend_parameters *p = &fepriv->parameters; + printk("%s()\n", __FUNCTION__); + p->frequency = c->frequency; p->inversion = c->inversion; switch(c->modulation) { case PSK_8: case APSK_16: - case APSK_32: case QPSK: p->u.qpsk.symbol_rate = c->symbol_rate; p->u.qpsk.fec_inner = c->fec_inner; @@ -1088,17 +1089,19 @@ void dtv_property_cache_submit(struct dvb_frontend *fe) { struct dtv_frontend_properties *c = &fe->dtv_property_cache; + printk("%s()\n", __FUNCTION__); + /* For legacy delivery systems we don't need the delivery_system to * be specified, but we populate the older structures from the cache * so we can call set_frontend on older drivers. */ if(is_legacy_delivery_system(c->delivery_system)) { - dprintk("%s() legacy, modulation = %d\n", __func__, c->modulation); + printk("%s() legacy, modulation = %d\n", __FUNCTION__, c->modulation); dtv_property_legacy_params_sync(fe); } else { - dprintk("%s() adv, modulation = %d\n", __func__, c->modulation); + printk("%s() adv, modulation = %d\n", __FUNCTION__, c->modulation); /* For advanced delivery systems / modulation types ... * we seed the lecacy dvb_frontend_parameters structure @@ -1120,6 +1123,8 @@ int dtv_property_process_get(struct dvb_frontend *fe, struct dtv_property *tvp, { int r = 0; + printk("%s()\n", __FUNCTION__); + dtv_property_dump(tvp); /* Allow the frontend to validate incoming properties */ @@ -1193,6 +1198,7 @@ int dtv_property_process_set(struct dvb_frontend *fe, struct dtv_property *tvp, { int r = 0; struct dvb_frontend_private *fepriv = fe->frontend_priv; + printk("%s()\n", __FUNCTION__); dtv_property_dump(tvp); /* Allow the frontend to validate incoming properties */ @@ -1207,7 +1213,7 @@ int dtv_property_process_set(struct dvb_frontend *fe, struct dtv_property *tvp, /* Reset a cache of data specific to the frontend here. This does * not effect hardware. */ - dprintk("%s() Flushing property cache\n", __func__); + printk("%s() Flushing property cache\n", __FUNCTION__); memset(&fe->dtv_property_cache, 0, sizeof(struct dtv_frontend_properties)); fe->dtv_property_cache.state = tvp->cmd; fe->dtv_property_cache.delivery_system = SYS_UNDEFINED; @@ -1218,7 +1224,7 @@ int dtv_property_process_set(struct dvb_frontend *fe, struct dtv_property *tvp, * ioctl. */ fe->dtv_property_cache.state = tvp->cmd; - dprintk("%s() Finalised property cache\n", __func__); + printk("%s() Finalised property cache\n", __FUNCTION__); dtv_property_cache_submit(fe); r |= dvb_frontend_ioctl_legacy(inode, file, FE_SET_FRONTEND, @@ -1329,10 +1335,12 @@ static int dvb_frontend_ioctl_properties(struct inode *inode, struct file *file, dprintk("%s\n", __func__); if(cmd == FE_SET_PROPERTY) { + printk("%s() FE_SET_PROPERTY\n", __FUNCTION__); + tvps = (struct dtv_properties __user *)parg; - dprintk("%s() properties.num = %d\n", __func__, tvps->num); - dprintk("%s() properties.props = %p\n", __func__, tvps->props); + printk("%s() properties.num = %d\n", __FUNCTION__, tvps->num); + printk("%s() properties.props = %p\n", __FUNCTION__, tvps->props); /* Put an arbitrary limit on the number of messages that can * be sent at once */ @@ -1356,16 +1364,18 @@ static int dvb_frontend_ioctl_properties(struct inode *inode, struct file *file, err |= (tvp + i)->result; } - if(fe->dtv_property_cache.state == DTV_TUNE) - dprintk("%s() Property cache is full, tuning\n", __func__); + if(fe->dtv_property_cache.state == DTV_TUNE) { + printk("%s() Property cache is full, tuning\n", __FUNCTION__); + } } else if(cmd == FE_GET_PROPERTY) { + printk("%s() FE_GET_PROPERTY\n", __FUNCTION__); tvps = (struct dtv_properties __user *)parg; - dprintk("%s() properties.num = %d\n", __func__, tvps->num); - dprintk("%s() properties.props = %p\n", __func__, tvps->props); + printk("%s() properties.num = %d\n", __FUNCTION__, tvps->num); + printk("%s() properties.props = %p\n", __FUNCTION__, tvps->props); /* Put an arbitrary limit on the number of messages that can * be sent at once */ @@ -1694,53 +1704,13 @@ static int dvb_frontend_open(struct inode *inode, struct file *file) struct dvb_device *dvbdev = file->private_data; struct dvb_frontend *fe = dvbdev->priv; struct dvb_frontend_private *fepriv = fe->frontend_priv; - struct dvb_adapter *adapter = fe->dvb; int ret; dprintk ("%s\n", __func__); - if (adapter->mfe_shared) { - mutex_lock (&adapter->mfe_lock); - - if (adapter->mfe_dvbdev == NULL) - adapter->mfe_dvbdev = dvbdev; - - else if (adapter->mfe_dvbdev != dvbdev) { - struct dvb_device - *mfedev = adapter->mfe_dvbdev; - struct dvb_frontend - *mfe = mfedev->priv; - struct dvb_frontend_private - *mfepriv = mfe->frontend_priv; - int mferetry = (dvb_mfe_wait_time << 1); - - mutex_unlock (&adapter->mfe_lock); - while (mferetry-- && (mfedev->users != -1 || - mfepriv->thread != NULL)) { - if(msleep_interruptible(500)) { - if(signal_pending(current)) - return -EINTR; - } - } - - mutex_lock (&adapter->mfe_lock); - if(adapter->mfe_dvbdev != dvbdev) { - mfedev = adapter->mfe_dvbdev; - mfe = mfedev->priv; - mfepriv = mfe->frontend_priv; - if (mfedev->users != -1 || - mfepriv->thread != NULL) { - mutex_unlock (&adapter->mfe_lock); - return -EBUSY; - } - adapter->mfe_dvbdev = dvbdev; - } - } - } - if (dvbdev->users == -1 && fe->ops.ts_bus_ctrl) { if ((ret = fe->ops.ts_bus_ctrl(fe, 1)) < 0) - goto err0; + return ret; } if ((ret = dvb_generic_open (inode, file)) < 0) @@ -1760,8 +1730,6 @@ static int dvb_frontend_open(struct inode *inode, struct file *file) fepriv->events.eventr = fepriv->events.eventw = 0; } - if (adapter->mfe_shared) - mutex_unlock (&adapter->mfe_lock); return ret; err2: @@ -1769,9 +1737,6 @@ static int dvb_frontend_open(struct inode *inode, struct file *file) err1: if (dvbdev->users == -1 && fe->ops.ts_bus_ctrl) fe->ops.ts_bus_ctrl(fe, 0); -err0: - if (adapter->mfe_shared) - mutex_unlock (&adapter->mfe_lock); return ret; } @@ -1841,9 +1806,8 @@ int dvb_register_frontend(struct dvb_adapter* dvb, fe->dvb = dvb; fepriv->inversion = INVERSION_OFF; - printk ("DVB: registering adapter %i frontend %i (%s)...\n", + printk ("DVB: registering frontend %i (%s)...\n", fe->dvb->num, - fe->id, fe->ops.info.name); dvb_register_device (fe->dvb, &fepriv->dvbdev, &dvbdev_template, diff --git a/trunk/drivers/media/dvb/dvb-core/dvb_frontend.h b/trunk/drivers/media/dvb/dvb-core/dvb_frontend.h index db4a63b0a32e..3055301ff3ca 100644 --- a/trunk/drivers/media/dvb/dvb-core/dvb_frontend.h +++ b/trunk/drivers/media/dvb/dvb-core/dvb_frontend.h @@ -222,7 +222,6 @@ struct dvb_frontend { struct dtv_frontend_properties dtv_property_cache; #define DVB_FRONTEND_COMPONENT_TUNER 0 int (*callback)(void *adapter_priv, int component, int cmd, int arg); - int id; }; extern int dvb_register_frontend(struct dvb_adapter *dvb, diff --git a/trunk/drivers/media/dvb/dvb-core/dvbdev.c b/trunk/drivers/media/dvb/dvb-core/dvbdev.c index a113744a56cc..665776d72a48 100644 --- a/trunk/drivers/media/dvb/dvb-core/dvbdev.c +++ b/trunk/drivers/media/dvb/dvb-core/dvbdev.c @@ -326,9 +326,6 @@ int dvb_register_adapter(struct dvb_adapter *adap, const char *name, adap->name = name; adap->module = module; adap->device = device; - adap->mfe_shared = 0; - adap->mfe_dvbdev = NULL; - mutex_init (&adap->mfe_lock); list_add_tail (&adap->list_head, &dvb_adapter_list); diff --git a/trunk/drivers/media/dvb/dvb-core/dvbdev.h b/trunk/drivers/media/dvb/dvb-core/dvbdev.h index 574e336bac35..89d12dc477a7 100644 --- a/trunk/drivers/media/dvb/dvb-core/dvbdev.h +++ b/trunk/drivers/media/dvb/dvb-core/dvbdev.h @@ -62,10 +62,6 @@ struct dvb_adapter { struct device *device; struct module *module; - - int mfe_shared; /* indicates mutually exclusive frontends */ - struct dvb_device *mfe_dvbdev; /* frontend device in use */ - struct mutex mfe_lock; /* access lock for thread creation */ }; diff --git a/trunk/drivers/media/dvb/dvb-usb/dw2102.c b/trunk/drivers/media/dvb/dvb-usb/dw2102.c index 6286fbbe7fb5..ca53df61caa8 100644 --- a/trunk/drivers/media/dvb/dvb-usb/dw2102.c +++ b/trunk/drivers/media/dvb/dvb-usb/dw2102.c @@ -422,18 +422,6 @@ static int dw210x_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) return 0; } -static struct stv0299_config sharp_z0194a_config = { - .demod_address = 0x68, - .inittab = sharp_z0194a_inittab, - .mclk = 88000000UL, - .invert = 1, - .skip_reinit = 0, - .lock_output = STV0299_LOCKOUTPUT_1, - .volt13_op0_op1 = STV0299_VOLT13_OP1, - .min_delay_ms = 100, - .set_symbol_rate = sharp_z0194a_set_symbol_rate, -}; - static struct cx24116_config dw2104_config = { .demod_address = 0x55, .mpg_clk_pos_pol = 0x01, diff --git a/trunk/drivers/media/dvb/frontends/cx22702.c b/trunk/drivers/media/dvb/frontends/cx22702.c index 5d1abe34bddb..9430e03dba6c 100644 --- a/trunk/drivers/media/dvb/frontends/cx22702.c +++ b/trunk/drivers/media/dvb/frontends/cx22702.c @@ -34,12 +34,13 @@ #include "dvb_frontend.h" #include "cx22702.h" + struct cx22702_state { - struct i2c_adapter *i2c; + struct i2c_adapter* i2c; /* configuration settings */ - const struct cx22702_config *config; + const struct cx22702_config* config; struct dvb_frontend frontend; @@ -48,13 +49,10 @@ struct cx22702_state { }; static int debug; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Enable verbose debug messages"); - #define dprintk if (debug) printk /* Register values to initialise the demod */ -static u8 init_tab[] = { +static u8 init_tab [] = { 0x00, 0x00, /* Stop aquisition */ 0x0B, 0x06, 0x09, 0x01, @@ -82,67 +80,65 @@ static u8 init_tab[] = { 0xfd, 0x00, }; -static int cx22702_writereg(struct cx22702_state *state, u8 reg, u8 data) +static int cx22702_writereg (struct cx22702_state* state, u8 reg, u8 data) { int ret; - u8 buf[] = { reg, data }; - struct i2c_msg msg = { - .addr = state->config->demod_address, .flags = 0, - .buf = buf, .len = 2 }; + u8 buf [] = { reg, data }; + struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 }; ret = i2c_transfer(state->i2c, &msg, 1); if (ret != 1) - printk(KERN_ERR - "%s: error (reg == 0x%02x, val == 0x%02x, ret == %i)\n", + printk("%s: writereg error (reg == 0x%02x, val == 0x%02x, ret == %i)\n", __func__, reg, data, ret); return (ret != 1) ? -1 : 0; } -static u8 cx22702_readreg(struct cx22702_state *state, u8 reg) +static u8 cx22702_readreg (struct cx22702_state* state, u8 reg) { int ret; - u8 b0[] = { reg }; - u8 b1[] = { 0 }; + u8 b0 [] = { reg }; + u8 b1 [] = { 0 }; - struct i2c_msg msg[] = { - { .addr = state->config->demod_address, .flags = 0, - .buf = b0, .len = 1 }, - { .addr = state->config->demod_address, .flags = I2C_M_RD, - .buf = b1, .len = 1 } }; + struct i2c_msg msg [] = { + { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 }, + { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } }; ret = i2c_transfer(state->i2c, msg, 2); if (ret != 2) - printk(KERN_ERR "%s: readreg error (ret == %i)\n", - __func__, ret); + printk("%s: readreg error (ret == %i)\n", __func__, ret); return b1[0]; } -static int cx22702_set_inversion(struct cx22702_state *state, int inversion) +static int cx22702_set_inversion (struct cx22702_state *state, int inversion) { u8 val; switch (inversion) { - case INVERSION_AUTO: - return -EOPNOTSUPP; - case INVERSION_ON: - val = cx22702_readreg(state, 0x0C); - return cx22702_writereg(state, 0x0C, val | 0x01); - case INVERSION_OFF: - val = cx22702_readreg(state, 0x0C); - return cx22702_writereg(state, 0x0C, val & 0xfe); - default: - return -EINVAL; + + case INVERSION_AUTO: + return -EOPNOTSUPP; + + case INVERSION_ON: + val = cx22702_readreg (state, 0x0C); + return cx22702_writereg (state, 0x0C, val | 0x01); + + case INVERSION_OFF: + val = cx22702_readreg (state, 0x0C); + return cx22702_writereg (state, 0x0C, val & 0xfe); + + default: + return -EINVAL; + } } /* Retrieve the demod settings */ -static int cx22702_get_tps(struct cx22702_state *state, - struct dvb_ofdm_parameters *p) +static int cx22702_get_tps (struct cx22702_state *state, struct dvb_ofdm_parameters *p) { u8 val; @@ -150,281 +146,180 @@ static int cx22702_get_tps(struct cx22702_state *state, if (!(cx22702_readreg(state, 0x0A) & 0x20)) return -EAGAIN; - val = cx22702_readreg(state, 0x01); - switch ((val & 0x18) >> 3) { - case 0: - p->constellation = QPSK; - break; - case 1: - p->constellation = QAM_16; - break; - case 2: - p->constellation = QAM_64; - break; + val = cx22702_readreg (state, 0x01); + switch( (val&0x18)>>3) { + case 0: p->constellation = QPSK; break; + case 1: p->constellation = QAM_16; break; + case 2: p->constellation = QAM_64; break; } - switch (val & 0x07) { - case 0: - p->hierarchy_information = HIERARCHY_NONE; - break; - case 1: - p->hierarchy_information = HIERARCHY_1; - break; - case 2: - p->hierarchy_information = HIERARCHY_2; - break; - case 3: - p->hierarchy_information = HIERARCHY_4; - break; + switch( val&0x07 ) { + case 0: p->hierarchy_information = HIERARCHY_NONE; break; + case 1: p->hierarchy_information = HIERARCHY_1; break; + case 2: p->hierarchy_information = HIERARCHY_2; break; + case 3: p->hierarchy_information = HIERARCHY_4; break; } - val = cx22702_readreg(state, 0x02); - switch ((val & 0x38) >> 3) { - case 0: - p->code_rate_HP = FEC_1_2; - break; - case 1: - p->code_rate_HP = FEC_2_3; - break; - case 2: - p->code_rate_HP = FEC_3_4; - break; - case 3: - p->code_rate_HP = FEC_5_6; - break; - case 4: - p->code_rate_HP = FEC_7_8; - break; + val = cx22702_readreg (state, 0x02); + switch( (val&0x38)>>3 ) { + case 0: p->code_rate_HP = FEC_1_2; break; + case 1: p->code_rate_HP = FEC_2_3; break; + case 2: p->code_rate_HP = FEC_3_4; break; + case 3: p->code_rate_HP = FEC_5_6; break; + case 4: p->code_rate_HP = FEC_7_8; break; } - switch (val & 0x07) { - case 0: - p->code_rate_LP = FEC_1_2; - break; - case 1: - p->code_rate_LP = FEC_2_3; - break; - case 2: - p->code_rate_LP = FEC_3_4; - break; - case 3: - p->code_rate_LP = FEC_5_6; - break; - case 4: - p->code_rate_LP = FEC_7_8; - break; + switch( val&0x07 ) { + case 0: p->code_rate_LP = FEC_1_2; break; + case 1: p->code_rate_LP = FEC_2_3; break; + case 2: p->code_rate_LP = FEC_3_4; break; + case 3: p->code_rate_LP = FEC_5_6; break; + case 4: p->code_rate_LP = FEC_7_8; break; } - val = cx22702_readreg(state, 0x03); - switch ((val & 0x0c) >> 2) { - case 0: - p->guard_interval = GUARD_INTERVAL_1_32; - break; - case 1: - p->guard_interval = GUARD_INTERVAL_1_16; - break; - case 2: - p->guard_interval = GUARD_INTERVAL_1_8; - break; - case 3: - p->guard_interval = GUARD_INTERVAL_1_4; - break; + + val = cx22702_readreg (state, 0x03); + switch( (val&0x0c)>>2 ) { + case 0: p->guard_interval = GUARD_INTERVAL_1_32; break; + case 1: p->guard_interval = GUARD_INTERVAL_1_16; break; + case 2: p->guard_interval = GUARD_INTERVAL_1_8; break; + case 3: p->guard_interval = GUARD_INTERVAL_1_4; break; } - switch (val & 0x03) { - case 0: - p->transmission_mode = TRANSMISSION_MODE_2K; - break; - case 1: - p->transmission_mode = TRANSMISSION_MODE_8K; - break; + switch( val&0x03 ) { + case 0: p->transmission_mode = TRANSMISSION_MODE_2K; break; + case 1: p->transmission_mode = TRANSMISSION_MODE_8K; break; } return 0; } -static int cx22702_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) +static int cx22702_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) { - struct cx22702_state *state = fe->demodulator_priv; - dprintk("%s(%d)\n", __func__, enable); + struct cx22702_state* state = fe->demodulator_priv; + dprintk ("%s(%d)\n", __func__, enable); if (enable) - return cx22702_writereg(state, 0x0D, - cx22702_readreg(state, 0x0D) & 0xfe); + return cx22702_writereg (state, 0x0D, cx22702_readreg(state, 0x0D) & 0xfe); else - return cx22702_writereg(state, 0x0D, - cx22702_readreg(state, 0x0D) | 1); + return cx22702_writereg (state, 0x0D, cx22702_readreg(state, 0x0D) | 1); } /* Talk to the demod, set the FEC, GUARD, QAM settings etc */ -static int cx22702_set_tps(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) +static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_parameters *p) { u8 val; - struct cx22702_state *state = fe->demodulator_priv; + struct cx22702_state* state = fe->demodulator_priv; if (fe->ops.tuner_ops.set_params) { fe->ops.tuner_ops.set_params(fe, p); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); + if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); } /* set inversion */ - cx22702_set_inversion(state, p->inversion); + cx22702_set_inversion (state, p->inversion); /* set bandwidth */ - switch (p->u.ofdm.bandwidth) { + switch(p->u.ofdm.bandwidth) { case BANDWIDTH_6_MHZ: - cx22702_writereg(state, 0x0C, - (cx22702_readreg(state, 0x0C) & 0xcf) | 0x20); + cx22702_writereg(state, 0x0C, (cx22702_readreg(state, 0x0C) & 0xcf) | 0x20 ); break; case BANDWIDTH_7_MHZ: - cx22702_writereg(state, 0x0C, - (cx22702_readreg(state, 0x0C) & 0xcf) | 0x10); + cx22702_writereg(state, 0x0C, (cx22702_readreg(state, 0x0C) & 0xcf) | 0x10 ); break; case BANDWIDTH_8_MHZ: - cx22702_writereg(state, 0x0C, - cx22702_readreg(state, 0x0C) & 0xcf); + cx22702_writereg(state, 0x0C, cx22702_readreg(state, 0x0C) &0xcf ); break; default: - dprintk("%s: invalid bandwidth\n", __func__); + dprintk ("%s: invalid bandwidth\n",__func__); return -EINVAL; } - p->u.ofdm.code_rate_LP = FEC_AUTO; /* temp hack as manual not working */ + + p->u.ofdm.code_rate_LP = FEC_AUTO; //temp hack as manual not working /* use auto configuration? */ - if ((p->u.ofdm.hierarchy_information == HIERARCHY_AUTO) || - (p->u.ofdm.constellation == QAM_AUTO) || - (p->u.ofdm.code_rate_HP == FEC_AUTO) || - (p->u.ofdm.code_rate_LP == FEC_AUTO) || - (p->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO) || - (p->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO)) { + if((p->u.ofdm.hierarchy_information==HIERARCHY_AUTO) || + (p->u.ofdm.constellation==QAM_AUTO) || + (p->u.ofdm.code_rate_HP==FEC_AUTO) || + (p->u.ofdm.code_rate_LP==FEC_AUTO) || + (p->u.ofdm.guard_interval==GUARD_INTERVAL_AUTO) || + (p->u.ofdm.transmission_mode==TRANSMISSION_MODE_AUTO) ) { /* TPS Source - use hardware driven values */ cx22702_writereg(state, 0x06, 0x10); cx22702_writereg(state, 0x07, 0x9); cx22702_writereg(state, 0x08, 0xC1); - cx22702_writereg(state, 0x0B, cx22702_readreg(state, 0x0B) - & 0xfc); - cx22702_writereg(state, 0x0C, - (cx22702_readreg(state, 0x0C) & 0xBF) | 0x40); + cx22702_writereg(state, 0x0B, cx22702_readreg(state, 0x0B) & 0xfc ); + cx22702_writereg(state, 0x0C, (cx22702_readreg(state, 0x0C) & 0xBF) | 0x40 ); cx22702_writereg(state, 0x00, 0x01); /* Begin aquisition */ - dprintk("%s: Autodetecting\n", __func__); + dprintk("%s: Autodetecting\n",__func__); return 0; } /* manually programmed values */ - val = 0; - switch (p->u.ofdm.constellation) { - case QPSK: - val = (val & 0xe7); - break; - case QAM_16: - val = (val & 0xe7) | 0x08; - break; - case QAM_64: - val = (val & 0xe7) | 0x10; - break; - default: - dprintk("%s: invalid constellation\n", __func__); - return -EINVAL; + val=0; + switch(p->u.ofdm.constellation) { + case QPSK: val = (val&0xe7); break; + case QAM_16: val = (val&0xe7)|0x08; break; + case QAM_64: val = (val&0xe7)|0x10; break; + default: + dprintk ("%s: invalid constellation\n",__func__); + return -EINVAL; } - switch (p->u.ofdm.hierarchy_information) { - case HIERARCHY_NONE: - val = (val & 0xf8); - break; - case HIERARCHY_1: - val = (val & 0xf8) | 1; - break; - case HIERARCHY_2: - val = (val & 0xf8) | 2; - break; - case HIERARCHY_4: - val = (val & 0xf8) | 3; - break; - default: - dprintk("%s: invalid hierarchy\n", __func__); - return -EINVAL; + switch(p->u.ofdm.hierarchy_information) { + case HIERARCHY_NONE: val = (val&0xf8); break; + case HIERARCHY_1: val = (val&0xf8)|1; break; + case HIERARCHY_2: val = (val&0xf8)|2; break; + case HIERARCHY_4: val = (val&0xf8)|3; break; + default: + dprintk ("%s: invalid hierarchy\n",__func__); + return -EINVAL; } - cx22702_writereg(state, 0x06, val); - - val = 0; - switch (p->u.ofdm.code_rate_HP) { - case FEC_NONE: - case FEC_1_2: - val = (val & 0xc7); - break; - case FEC_2_3: - val = (val & 0xc7) | 0x08; - break; - case FEC_3_4: - val = (val & 0xc7) | 0x10; - break; - case FEC_5_6: - val = (val & 0xc7) | 0x18; - break; - case FEC_7_8: - val = (val & 0xc7) | 0x20; - break; - default: - dprintk("%s: invalid code_rate_HP\n", __func__); - return -EINVAL; + cx22702_writereg (state, 0x06, val); + + val=0; + switch(p->u.ofdm.code_rate_HP) { + case FEC_NONE: + case FEC_1_2: val = (val&0xc7); break; + case FEC_2_3: val = (val&0xc7)|0x08; break; + case FEC_3_4: val = (val&0xc7)|0x10; break; + case FEC_5_6: val = (val&0xc7)|0x18; break; + case FEC_7_8: val = (val&0xc7)|0x20; break; + default: + dprintk ("%s: invalid code_rate_HP\n",__func__); + return -EINVAL; } - switch (p->u.ofdm.code_rate_LP) { - case FEC_NONE: - case FEC_1_2: - val = (val & 0xf8); - break; - case FEC_2_3: - val = (val & 0xf8) | 1; - break; - case FEC_3_4: - val = (val & 0xf8) | 2; - break; - case FEC_5_6: - val = (val & 0xf8) | 3; - break; - case FEC_7_8: - val = (val & 0xf8) | 4; - break; - default: - dprintk("%s: invalid code_rate_LP\n", __func__); - return -EINVAL; + switch(p->u.ofdm.code_rate_LP) { + case FEC_NONE: + case FEC_1_2: val = (val&0xf8); break; + case FEC_2_3: val = (val&0xf8)|1; break; + case FEC_3_4: val = (val&0xf8)|2; break; + case FEC_5_6: val = (val&0xf8)|3; break; + case FEC_7_8: val = (val&0xf8)|4; break; + default: + dprintk ("%s: invalid code_rate_LP\n",__func__); + return -EINVAL; } - cx22702_writereg(state, 0x07, val); - - val = 0; - switch (p->u.ofdm.guard_interval) { - case GUARD_INTERVAL_1_32: - val = (val & 0xf3); - break; - case GUARD_INTERVAL_1_16: - val = (val & 0xf3) | 0x04; - break; - case GUARD_INTERVAL_1_8: - val = (val & 0xf3) | 0x08; - break; - case GUARD_INTERVAL_1_4: - val = (val & 0xf3) | 0x0c; - break; - default: - dprintk("%s: invalid guard_interval\n", __func__); - return -EINVAL; + cx22702_writereg (state, 0x07, val); + + val=0; + switch(p->u.ofdm.guard_interval) { + case GUARD_INTERVAL_1_32: val = (val&0xf3); break; + case GUARD_INTERVAL_1_16: val = (val&0xf3)|0x04; break; + case GUARD_INTERVAL_1_8: val = (val&0xf3)|0x08; break; + case GUARD_INTERVAL_1_4: val = (val&0xf3)|0x0c; break; + default: + dprintk ("%s: invalid guard_interval\n",__func__); + return -EINVAL; } - switch (p->u.ofdm.transmission_mode) { - case TRANSMISSION_MODE_2K: - val = (val & 0xfc); - break; - case TRANSMISSION_MODE_8K: - val = (val & 0xfc) | 1; - break; - default: - dprintk("%s: invalid transmission_mode\n", __func__); - return -EINVAL; + switch(p->u.ofdm.transmission_mode) { + case TRANSMISSION_MODE_2K: val = (val&0xfc); break; + case TRANSMISSION_MODE_8K: val = (val&0xfc)|1; break; + default: + dprintk ("%s: invalid transmission_mode\n",__func__); + return -EINVAL; } cx22702_writereg(state, 0x08, val); - cx22702_writereg(state, 0x0B, - (cx22702_readreg(state, 0x0B) & 0xfc) | 0x02); - cx22702_writereg(state, 0x0C, - (cx22702_readreg(state, 0x0C) & 0xBF) | 0x40); + cx22702_writereg(state, 0x0B, (cx22702_readreg(state, 0x0B) & 0xfc) | 0x02 ); + cx22702_writereg(state, 0x0C, (cx22702_readreg(state, 0x0C) & 0xBF) | 0x40 ); /* Begin channel aquisition */ cx22702_writereg(state, 0x00, 0x01); @@ -434,111 +329,109 @@ static int cx22702_set_tps(struct dvb_frontend *fe, /* Reset the demod hardware and reset all of the configuration registers to a default state. */ -static int cx22702_init(struct dvb_frontend *fe) +static int cx22702_init (struct dvb_frontend* fe) { int i; - struct cx22702_state *state = fe->demodulator_priv; + struct cx22702_state* state = fe->demodulator_priv; - cx22702_writereg(state, 0x00, 0x02); + cx22702_writereg (state, 0x00, 0x02); msleep(10); - for (i = 0; i < ARRAY_SIZE(init_tab); i += 2) - cx22702_writereg(state, init_tab[i], init_tab[i + 1]); + for (i=0; iconfig->output_mode << 1) - & 0x02); + cx22702_writereg (state, 0xf8, (state->config->output_mode << 1) & 0x02); cx22702_i2c_gate_ctrl(fe, 0); return 0; } -static int cx22702_read_status(struct dvb_frontend *fe, fe_status_t *status) +static int cx22702_read_status(struct dvb_frontend* fe, fe_status_t* status) { - struct cx22702_state *state = fe->demodulator_priv; + struct cx22702_state* state = fe->demodulator_priv; u8 reg0A; u8 reg23; *status = 0; - reg0A = cx22702_readreg(state, 0x0A); - reg23 = cx22702_readreg(state, 0x23); + reg0A = cx22702_readreg (state, 0x0A); + reg23 = cx22702_readreg (state, 0x23); - dprintk("%s: status demod=0x%02x agc=0x%02x\n" - , __func__, reg0A, reg23); + dprintk ("%s: status demod=0x%02x agc=0x%02x\n" + ,__func__,reg0A,reg23); - if (reg0A & 0x10) { + if(reg0A & 0x10) { *status |= FE_HAS_LOCK; *status |= FE_HAS_VITERBI; *status |= FE_HAS_SYNC; } - if (reg0A & 0x20) + if(reg0A & 0x20) *status |= FE_HAS_CARRIER; - if (reg23 < 0xf0) + if(reg23 < 0xf0) *status |= FE_HAS_SIGNAL; return 0; } -static int cx22702_read_ber(struct dvb_frontend *fe, u32 *ber) +static int cx22702_read_ber(struct dvb_frontend* fe, u32* ber) { - struct cx22702_state *state = fe->demodulator_priv; + struct cx22702_state* state = fe->demodulator_priv; - if (cx22702_readreg(state, 0xE4) & 0x02) { + if(cx22702_readreg (state, 0xE4) & 0x02) { /* Realtime statistics */ - *ber = (cx22702_readreg(state, 0xDE) & 0x7F) << 7 - | (cx22702_readreg(state, 0xDF) & 0x7F); + *ber = (cx22702_readreg (state, 0xDE) & 0x7F) << 7 + | (cx22702_readreg (state, 0xDF)&0x7F); } else { /* Averagtine statistics */ - *ber = (cx22702_readreg(state, 0xDE) & 0x7F) << 7 - | cx22702_readreg(state, 0xDF); + *ber = (cx22702_readreg (state, 0xDE) & 0x7F) << 7 + | cx22702_readreg (state, 0xDF); } return 0; } -static int cx22702_read_signal_strength(struct dvb_frontend *fe, - u16 *signal_strength) +static int cx22702_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength) { - struct cx22702_state *state = fe->demodulator_priv; + struct cx22702_state* state = fe->demodulator_priv; u16 rs_ber = 0; - rs_ber = cx22702_readreg(state, 0x23); + rs_ber = cx22702_readreg (state, 0x23); *signal_strength = (rs_ber << 8) | rs_ber; return 0; } -static int cx22702_read_snr(struct dvb_frontend *fe, u16 *snr) +static int cx22702_read_snr(struct dvb_frontend* fe, u16* snr) { - struct cx22702_state *state = fe->demodulator_priv; + struct cx22702_state* state = fe->demodulator_priv; - u16 rs_ber = 0; - if (cx22702_readreg(state, 0xE4) & 0x02) { + u16 rs_ber=0; + if(cx22702_readreg (state, 0xE4) & 0x02) { /* Realtime statistics */ - rs_ber = (cx22702_readreg(state, 0xDE) & 0x7F) << 7 - | (cx22702_readreg(state, 0xDF) & 0x7F); + rs_ber = (cx22702_readreg (state, 0xDE) & 0x7F) << 7 + | (cx22702_readreg (state, 0xDF)& 0x7F); } else { /* Averagine statistics */ - rs_ber = (cx22702_readreg(state, 0xDE) & 0x7F) << 8 - | cx22702_readreg(state, 0xDF); + rs_ber = (cx22702_readreg (state, 0xDE) & 0x7F) << 8 + | cx22702_readreg (state, 0xDF); } *snr = ~rs_ber; return 0; } -static int cx22702_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) +static int cx22702_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) { - struct cx22702_state *state = fe->demodulator_priv; + struct cx22702_state* state = fe->demodulator_priv; u8 _ucblocks; /* RS Uncorrectable Packet Count then reset */ - _ucblocks = cx22702_readreg(state, 0xE3); + _ucblocks = cx22702_readreg (state, 0xE3); if (state->prevUCBlocks < _ucblocks) *ucblocks = (_ucblocks - state->prevUCBlocks); else @@ -548,36 +441,34 @@ static int cx22702_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) return 0; } -static int cx22702_get_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) +static int cx22702_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) { - struct cx22702_state *state = fe->demodulator_priv; + struct cx22702_state* state = fe->demodulator_priv; - u8 reg0C = cx22702_readreg(state, 0x0C); + u8 reg0C = cx22702_readreg (state, 0x0C); p->inversion = reg0C & 0x1 ? INVERSION_ON : INVERSION_OFF; - return cx22702_get_tps(state, &p->u.ofdm); + return cx22702_get_tps (state, &p->u.ofdm); } -static int cx22702_get_tune_settings(struct dvb_frontend *fe, - struct dvb_frontend_tune_settings *tune) +static int cx22702_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune) { tune->min_delay_ms = 1000; return 0; } -static void cx22702_release(struct dvb_frontend *fe) +static void cx22702_release(struct dvb_frontend* fe) { - struct cx22702_state *state = fe->demodulator_priv; + struct cx22702_state* state = fe->demodulator_priv; kfree(state); } static struct dvb_frontend_ops cx22702_ops; -struct dvb_frontend *cx22702_attach(const struct cx22702_config *config, - struct i2c_adapter *i2c) +struct dvb_frontend* cx22702_attach(const struct cx22702_config* config, + struct i2c_adapter* i2c) { - struct cx22702_state *state = NULL; + struct cx22702_state* state = NULL; /* allocate memory for the internal state */ state = kmalloc(sizeof(struct cx22702_state), GFP_KERNEL); @@ -594,8 +485,7 @@ struct dvb_frontend *cx22702_attach(const struct cx22702_config *config, goto error; /* create dvb_frontend */ - memcpy(&state->frontend.ops, &cx22702_ops, - sizeof(struct dvb_frontend_ops)); + memcpy(&state->frontend.ops, &cx22702_ops, sizeof(struct dvb_frontend_ops)); state->frontend.demodulator_priv = state; return &state->frontend; @@ -603,7 +493,6 @@ struct dvb_frontend *cx22702_attach(const struct cx22702_config *config, kfree(state); return NULL; } -EXPORT_SYMBOL(cx22702_attach); static struct dvb_frontend_ops cx22702_ops = { @@ -636,6 +525,11 @@ static struct dvb_frontend_ops cx22702_ops = { .read_ucblocks = cx22702_read_ucblocks, }; +module_param(debug, int, 0644); +MODULE_PARM_DESC(debug, "Enable verbose debug messages"); + MODULE_DESCRIPTION("Conexant CX22702 DVB-T Demodulator driver"); MODULE_AUTHOR("Steven Toth"); MODULE_LICENSE("GPL"); + +EXPORT_SYMBOL(cx22702_attach); diff --git a/trunk/drivers/media/dvb/frontends/cx22702.h b/trunk/drivers/media/dvb/frontends/cx22702.h index f154e1f428eb..b1e465c6c2ce 100644 --- a/trunk/drivers/media/dvb/frontends/cx22702.h +++ b/trunk/drivers/media/dvb/frontends/cx22702.h @@ -30,7 +30,8 @@ #include -struct cx22702_config { +struct cx22702_config +{ /* the demodulator's i2c address */ u8 demod_address; @@ -40,19 +41,16 @@ struct cx22702_config { u8 output_mode; }; -#if defined(CONFIG_DVB_CX22702) || (defined(CONFIG_DVB_CX22702_MODULE) \ - && defined(MODULE)) -extern struct dvb_frontend *cx22702_attach( - const struct cx22702_config *config, - struct i2c_adapter *i2c); +#if defined(CONFIG_DVB_CX22702) || (defined(CONFIG_DVB_CX22702_MODULE) && defined(MODULE)) +extern struct dvb_frontend* cx22702_attach(const struct cx22702_config* config, + struct i2c_adapter* i2c); #else -static inline struct dvb_frontend *cx22702_attach( - const struct cx22702_config *config, - struct i2c_adapter *i2c) +static inline struct dvb_frontend* cx22702_attach(const struct cx22702_config* config, + struct i2c_adapter* i2c) { printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } -#endif +#endif // CONFIG_DVB_CX22702 -#endif +#endif // CX22702_H diff --git a/trunk/drivers/media/dvb/frontends/cx24116.c b/trunk/drivers/media/dvb/frontends/cx24116.c index b144b308a4dd..deb36f469ada 100644 --- a/trunk/drivers/media/dvb/frontends/cx24116.c +++ b/trunk/drivers/media/dvb/frontends/cx24116.c @@ -41,14 +41,10 @@ #include "dvb_frontend.h" #include "cx24116.h" -static int debug; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)"); - +static int debug = 0; #define dprintk(args...) \ do { \ - if (debug) \ - printk(KERN_INFO "cx24116: " args); \ + if (debug) printk ("cx24116: " args); \ } while (0) #define CX24116_DEFAULT_FIRMWARE "dvb-fe-cx24116.fw" @@ -72,20 +68,13 @@ MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)"); #define CX24116_REG_UCB8 (0xca) #define CX24116_REG_CLKDIV (0xf3) #define CX24116_REG_RATEDIV (0xf9) - -/* configured fec (not tuned) or actual FEC (tuned) 1=1/2 2=2/3 etc */ -#define CX24116_REG_FECSTATUS (0x9c) +#define CX24116_REG_FECSTATUS (0x9c) /* configured fec (not tuned) or actual FEC (tuned) 1=1/2 2=2/3 etc */ /* FECSTATUS bits */ -/* mask to determine configured fec (not tuned) or actual fec (tuned) */ -#define CX24116_FEC_FECMASK (0x1f) - -/* Select DVB-S demodulator, else DVB-S2 */ -#define CX24116_FEC_DVBS (0x20) +#define CX24116_FEC_FECMASK (0x1f) /* mask to determine configured fec (not tuned) or actual fec (tuned) */ +#define CX24116_FEC_DVBS (0x20) /* Select DVB-S demodulator, else DVB-S2 */ #define CX24116_FEC_UNKNOWN (0x40) /* Unknown/unused */ - -/* Pilot mode requested when tuning else always reset when tuned */ -#define CX24116_FEC_PILOT (0x80) +#define CX24116_FEC_PILOT (0x80) /* Pilot mode requested when tuning else always reset when tuned */ /* arg buffer size */ #define CX24116_ARGLEN (0x1e) @@ -127,17 +116,12 @@ MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)"); /* DiSEqC tone burst */ static int toneburst = 1; -module_param(toneburst, int, 0644); -MODULE_PARM_DESC(toneburst, "DiSEqC toneburst 0=OFF, 1=TONE CACHE, "\ - "2=MESSAGE CACHE (default:1)"); /* SNR measurements */ -static int esno_snr; -module_param(esno_snr, int, 0644); -MODULE_PARM_DESC(debug, "SNR return units, 0=PERCENTAGE 0-100, "\ - "1=ESNO(db * 10) (default:0)"); +static int esno_snr = 0; -enum cmds { +enum cmds +{ CMD_SET_VCO = 0x10, CMD_TUNEREQUEST = 0x11, CMD_MPEGCONFIG = 0x13, @@ -154,7 +138,8 @@ enum cmds { }; /* The Demod/Tuner can't easily provide these, we cache them */ -struct cx24116_tuning { +struct cx24116_tuning +{ u32 frequency; u32 symbol_rate; fe_spectral_inversion_t inversion; @@ -173,14 +158,16 @@ struct cx24116_tuning { }; /* Basic commands that are sent to the firmware */ -struct cx24116_cmd { +struct cx24116_cmd +{ u8 len; u8 args[CX24116_ARGLEN]; }; -struct cx24116_state { - struct i2c_adapter *i2c; - const struct cx24116_config *config; +struct cx24116_state +{ + struct i2c_adapter* i2c; + const struct cx24116_config* config; struct dvb_frontend frontend; @@ -192,20 +179,19 @@ struct cx24116_state { struct cx24116_cmd dsec_cmd; }; -static int cx24116_writereg(struct cx24116_state *state, int reg, int data) +static int cx24116_writereg(struct cx24116_state* state, int reg, int data) { u8 buf[] = { reg, data }; struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 }; int err; - if (debug > 1) + if (debug>1) printk("cx24116: %s: write reg 0x%02x, value 0x%02x\n", - __func__, reg, data); + __func__,reg, data); - err = i2c_transfer(state->i2c, &msg, 1); - if (err != 1) { - printk(KERN_ERR "%s: writereg error(err == %i, reg == 0x%02x," + if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) { + printk("%s: writereg error(err == %i, reg == 0x%02x," " value == 0x%02x)\n", __func__, err, reg, data); return -EREMOTEIO; } @@ -214,8 +200,7 @@ static int cx24116_writereg(struct cx24116_state *state, int reg, int data) } /* Bulk byte writes to a single I2C address, for 32k firmware load */ -static int cx24116_writeregN(struct cx24116_state *state, int reg, - const u8 *data, u16 len) +static int cx24116_writeregN(struct cx24116_state* state, int reg, u8 *data, u16 len) { int ret = -EREMOTEIO; struct i2c_msg msg; @@ -236,13 +221,12 @@ static int cx24116_writeregN(struct cx24116_state *state, int reg, msg.buf = buf; msg.len = len + 1; - if (debug > 1) - printk(KERN_INFO "cx24116: %s: write regN 0x%02x, len = %d\n", - __func__, reg, len); + if (debug>1) + printk("cx24116: %s: write regN 0x%02x, len = %d\n", + __func__,reg, len); - ret = i2c_transfer(state->i2c, &msg, 1); - if (ret != 1) { - printk(KERN_ERR "%s: writereg error(err == %i, reg == 0x%02x\n", + if ((ret = i2c_transfer(state->i2c, &msg, 1)) != 1) { + printk("%s: writereg error(err == %i, reg == 0x%02x\n", __func__, ret, reg); ret = -EREMOTEIO; } @@ -253,35 +237,30 @@ static int cx24116_writeregN(struct cx24116_state *state, int reg, return ret; } -static int cx24116_readreg(struct cx24116_state *state, u8 reg) +static int cx24116_readreg(struct cx24116_state* state, u8 reg) { int ret; u8 b0[] = { reg }; u8 b1[] = { 0 }; struct i2c_msg msg[] = { - { .addr = state->config->demod_address, .flags = 0, - .buf = b0, .len = 1 }, - { .addr = state->config->demod_address, .flags = I2C_M_RD, - .buf = b1, .len = 1 } + { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 }, + { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } }; ret = i2c_transfer(state->i2c, msg, 2); if (ret != 2) { - printk(KERN_ERR "%s: reg=0x%x (error=%d)\n", - __func__, reg, ret); + printk("%s: reg=0x%x (error=%d)\n", __func__, reg, ret); return ret; } - if (debug > 1) - printk(KERN_INFO "cx24116: read reg 0x%02x, value 0x%02x\n", - reg, b1[0]); + if (debug>1) + printk("cx24116: read reg 0x%02x, value 0x%02x\n",reg, b1[0]); return b1[0]; } -static int cx24116_set_inversion(struct cx24116_state *state, - fe_spectral_inversion_t inversion) +static int cx24116_set_inversion(struct cx24116_state* state, fe_spectral_inversion_t inversion) { dprintk("%s(%d)\n", __func__, inversion); @@ -329,10 +308,10 @@ static int cx24116_set_inversion(struct cx24116_state *state, * Eg.(2/3) szap "Zone Horror" * * mask/val = 0x04, 0x20 - * status 1f | signal c3c0 | snr a333 | ber 00000098 | unc 0 | FE_HAS_LOCK + * status 1f | signal c3c0 | snr a333 | ber 00000098 | unc 00000000 | FE_HAS_LOCK * * mask/val = 0x04, 0x30 - * status 1f | signal c3c0 | snr a333 | ber 00000000 | unc 0 | FE_HAS_LOCK + * status 1f | signal c3c0 | snr a333 | ber 00000000 | unc 00000000 | FE_HAS_LOCK * * After tuning FECSTATUS contains actual FEC * in use numbered 1 through to 8 for 1/2 .. 2/3 etc @@ -410,16 +389,18 @@ struct cx24116_modfec { */ }; -static int cx24116_lookup_fecmod(struct cx24116_state *state, +static int cx24116_lookup_fecmod(struct cx24116_state* state, fe_modulation_t m, fe_code_rate_t f) { int i, ret = -EOPNOTSUPP; dprintk("%s(0x%02x,0x%02x)\n", __func__, m, f); - for (i = 0; i < ARRAY_SIZE(CX24116_MODFEC_MODES); i++) { - if ((m == CX24116_MODFEC_MODES[i].modulation) && - (f == CX24116_MODFEC_MODES[i].fec)) { + for(i=0 ; i < sizeof(CX24116_MODFEC_MODES) / sizeof(struct cx24116_modfec) ; i++) + { + if( (m == CX24116_MODFEC_MODES[i].modulation) && + (f == CX24116_MODFEC_MODES[i].fec) ) + { ret = i; break; } @@ -428,8 +409,7 @@ static int cx24116_lookup_fecmod(struct cx24116_state *state, return ret; } -static int cx24116_set_fec(struct cx24116_state *state, - fe_modulation_t mod, fe_code_rate_t fec) +static int cx24116_set_fec(struct cx24116_state* state, fe_modulation_t mod, fe_code_rate_t fec) { int ret = 0; @@ -437,7 +417,7 @@ static int cx24116_set_fec(struct cx24116_state *state, ret = cx24116_lookup_fecmod(state, mod, fec); - if (ret < 0) + if(ret < 0) return ret; state->dnxt.fec = fec; @@ -449,7 +429,7 @@ static int cx24116_set_fec(struct cx24116_state *state, return 0; } -static int cx24116_set_symbolrate(struct cx24116_state *state, u32 rate) +static int cx24116_set_symbolrate(struct cx24116_state* state, u32 rate) { dprintk("%s(%d)\n", __func__, rate); @@ -466,49 +446,42 @@ static int cx24116_set_symbolrate(struct cx24116_state *state, u32 rate) return 0; } -static int cx24116_load_firmware(struct dvb_frontend *fe, - const struct firmware *fw); +static int cx24116_load_firmware (struct dvb_frontend* fe, const struct firmware *fw); -static int cx24116_firmware_ondemand(struct dvb_frontend *fe) +static int cx24116_firmware_ondemand(struct dvb_frontend* fe) { struct cx24116_state *state = fe->demodulator_priv; const struct firmware *fw; int ret = 0; - dprintk("%s()\n", __func__); + dprintk("%s()\n",__func__); - if (cx24116_readreg(state, 0x20) > 0) { + if (cx24116_readreg(state, 0x20) > 0) + { if (state->skip_fw_load) return 0; /* Load firmware */ - /* request the firmware, this will block until loaded */ - printk(KERN_INFO "%s: Waiting for firmware upload (%s)...\n", - __func__, CX24116_DEFAULT_FIRMWARE); - ret = request_firmware(&fw, CX24116_DEFAULT_FIRMWARE, - &state->i2c->dev); - printk(KERN_INFO "%s: Waiting for firmware upload(2)...\n", - __func__); + /* request the firmware, this will block until someone uploads it */ + printk("%s: Waiting for firmware upload (%s)...\n", __func__, CX24116_DEFAULT_FIRMWARE); + ret = request_firmware(&fw, CX24116_DEFAULT_FIRMWARE, &state->i2c->dev); + printk("%s: Waiting for firmware upload(2)...\n", __func__); if (ret) { - printk(KERN_ERR "%s: No firmware uploaded " - "(timeout or file not found?)\n", __func__); + printk("%s: No firmware uploaded (timeout or file not found?)\n", __func__); return ret; } - /* Make sure we don't recurse back through here - * during loading */ + /* Make sure we don't recurse back through here during loading */ state->skip_fw_load = 1; ret = cx24116_load_firmware(fe, fw); if (ret) - printk(KERN_ERR "%s: Writing firmware to device failed\n", - __func__); + printk("%s: Writing firmware to device failed\n", __func__); release_firmware(fw); - printk(KERN_INFO "%s: Firmware upload %s\n", __func__, - ret == 0 ? "complete" : "failed"); + printk("%s: Firmware upload %s\n", __func__, ret == 0 ? "complete" : "failed"); /* Ensure firmware is always loaded if required */ state->skip_fw_load = 0; @@ -517,10 +490,8 @@ static int cx24116_firmware_ondemand(struct dvb_frontend *fe) return ret; } -/* Take a basic firmware command structure, format it - * and forward it for processing - */ -static int cx24116_cmd_execute(struct dvb_frontend *fe, struct cx24116_cmd *cmd) +/* Take a basic firmware command structure, format it and forward it for processing */ +static int cx24116_cmd_execute(struct dvb_frontend* fe, struct cx24116_cmd *cmd) { struct cx24116_state *state = fe->demodulator_priv; int i, ret; @@ -528,49 +499,49 @@ static int cx24116_cmd_execute(struct dvb_frontend *fe, struct cx24116_cmd *cmd) dprintk("%s()\n", __func__); /* Load the firmware if required */ - ret = cx24116_firmware_ondemand(fe); - if (ret != 0) { - printk(KERN_ERR "%s(): Unable initialise the firmware\n", - __func__); + if ( (ret = cx24116_firmware_ondemand(fe)) != 0) + { + printk("%s(): Unable initialise the firmware\n", __func__); return ret; } /* Write the command */ - for (i = 0; i < cmd->len ; i++) { + for(i = 0; i < cmd->len ; i++) + { dprintk("%s: 0x%02x == 0x%02x\n", __func__, i, cmd->args[i]); cx24116_writereg(state, i, cmd->args[i]); } /* Start execution and wait for cmd to terminate */ cx24116_writereg(state, CX24116_REG_EXECUTE, 0x01); - while (cx24116_readreg(state, CX24116_REG_EXECUTE)) { + while( cx24116_readreg(state, CX24116_REG_EXECUTE) ) + { msleep(10); - if (i++ > 64) { - /* Avoid looping forever if the firmware does - not respond */ - printk(KERN_WARNING "%s() Firmware not responding\n", - __func__); + if(i++ > 64) + { + /* Avoid looping forever if the firmware does no respond */ + printk("%s() Firmware not responding\n", __func__); return -EREMOTEIO; } } return 0; } -static int cx24116_load_firmware(struct dvb_frontend *fe, - const struct firmware *fw) +static int cx24116_load_firmware (struct dvb_frontend* fe, const struct firmware *fw) { - struct cx24116_state *state = fe->demodulator_priv; + struct cx24116_state* state = fe->demodulator_priv; struct cx24116_cmd cmd; int i, ret; unsigned char vers[4]; dprintk("%s\n", __func__); - dprintk("Firmware is %zu bytes (%02x %02x .. %02x %02x)\n", - fw->size, - fw->data[0], - fw->data[1], - fw->data[fw->size-2], - fw->data[fw->size-1]); + dprintk("Firmware is %zu bytes (%02x %02x .. %02x %02x)\n" + ,fw->size + ,fw->data[0] + ,fw->data[1] + ,fw->data[ fw->size-2 ] + ,fw->data[ fw->size-1 ] + ); /* Toggle 88x SRST pin to reset demod */ if (state->config->reset_device) @@ -616,7 +587,7 @@ static int cx24116_load_firmware(struct dvb_frontend *fe, cmd.args[0x07] = 0x9d; cmd.args[0x08] = 0xfc; cmd.args[0x09] = 0x06; - cmd.len = 0x0a; + cmd.len= 0x0a; ret = cx24116_cmd_execute(fe, &cmd); if (ret != 0) return ret; @@ -627,7 +598,7 @@ static int cx24116_load_firmware(struct dvb_frontend *fe, cmd.args[0x00] = CMD_TUNERINIT; cmd.args[0x01] = 0x00; cmd.args[0x02] = 0x00; - cmd.len = 0x03; + cmd.len= 0x03; ret = cx24116_cmd_execute(fe, &cmd); if (ret != 0) return ret; @@ -644,38 +615,36 @@ static int cx24116_load_firmware(struct dvb_frontend *fe, else cmd.args[0x04] = 0x02; cmd.args[0x05] = 0x00; - cmd.len = 0x06; + cmd.len= 0x06; ret = cx24116_cmd_execute(fe, &cmd); if (ret != 0) return ret; /* Firmware CMD 35: Get firmware version */ cmd.args[0x00] = CMD_UPDFWVERS; - cmd.len = 0x02; - for (i = 0; i < 4; i++) { + cmd.len= 0x02; + for(i=0; i<4; i++) { cmd.args[0x01] = i; ret = cx24116_cmd_execute(fe, &cmd); if (ret != 0) return ret; - vers[i] = cx24116_readreg(state, CX24116_REG_MAILBOX); + vers[i]= cx24116_readreg(state, CX24116_REG_MAILBOX); } - printk(KERN_INFO "%s: FW version %i.%i.%i.%i\n", __func__, + printk("%s: FW version %i.%i.%i.%i\n", __func__, vers[0], vers[1], vers[2], vers[3]); return 0; } -static int cx24116_set_voltage(struct dvb_frontend *fe, - fe_sec_voltage_t voltage) +static int cx24116_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) { /* The isl6421 module will override this function in the fops. */ - dprintk("%s() This should never appear if the isl6421 module " - "is loaded correctly\n", __func__); + dprintk("%s() This should never appear if the isl6421 module is loaded correctly\n",__func__); return -EOPNOTSUPP; } -static int cx24116_read_status(struct dvb_frontend *fe, fe_status_t *status) +static int cx24116_read_status(struct dvb_frontend* fe, fe_status_t* status) { struct cx24116_state *state = fe->demodulator_priv; @@ -697,23 +666,22 @@ static int cx24116_read_status(struct dvb_frontend *fe, fe_status_t *status) return 0; } -static int cx24116_read_ber(struct dvb_frontend *fe, u32 *ber) +static int cx24116_read_ber(struct dvb_frontend* fe, u32* ber) { struct cx24116_state *state = fe->demodulator_priv; dprintk("%s()\n", __func__); - *ber = (cx24116_readreg(state, CX24116_REG_BER24) << 24) | - (cx24116_readreg(state, CX24116_REG_BER16) << 16) | - (cx24116_readreg(state, CX24116_REG_BER8) << 8) | - cx24116_readreg(state, CX24116_REG_BER0); + *ber = ( cx24116_readreg(state, CX24116_REG_BER24) << 24 ) | + ( cx24116_readreg(state, CX24116_REG_BER16) << 16 ) | + ( cx24116_readreg(state, CX24116_REG_BER8 ) << 8 ) | + cx24116_readreg(state, CX24116_REG_BER0 ); return 0; } /* TODO Determine function and scale appropriately */ -static int cx24116_read_signal_strength(struct dvb_frontend *fe, - u16 *signal_strength) +static int cx24116_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength) { struct cx24116_state *state = fe->demodulator_priv; struct cx24116_cmd cmd; @@ -724,43 +692,39 @@ static int cx24116_read_signal_strength(struct dvb_frontend *fe, /* Firmware CMD 19: Get AGC */ cmd.args[0x00] = CMD_GETAGC; - cmd.len = 0x01; + cmd.len= 0x01; ret = cx24116_cmd_execute(fe, &cmd); if (ret != 0) return ret; - sig_reading = - (cx24116_readreg(state, - CX24116_REG_SSTATUS) & CX24116_SIGNAL_MASK) | - (cx24116_readreg(state, CX24116_REG_SIGNAL) << 6); - *signal_strength = 0 - sig_reading; + sig_reading = ( cx24116_readreg(state, CX24116_REG_SSTATUS) & CX24116_SIGNAL_MASK ) | + ( cx24116_readreg(state, CX24116_REG_SIGNAL) << 6 ); + *signal_strength= 0 - sig_reading; - dprintk("%s: raw / cooked = 0x%04x / 0x%04x\n", - __func__, sig_reading, *signal_strength); + dprintk("%s: raw / cooked = 0x%04x / 0x%04x\n", __func__, sig_reading, *signal_strength); return 0; } /* SNR (0..100)% = (sig & 0xf0) * 10 + (sig & 0x0f) * 10 / 16 */ -static int cx24116_read_snr_pct(struct dvb_frontend *fe, u16 *snr) +static int cx24116_read_snr_pct(struct dvb_frontend* fe, u16* snr) { struct cx24116_state *state = fe->demodulator_priv; u8 snr_reading; static const u32 snr_tab[] = { /* 10 x Table (rounded up) */ - 0x00000, 0x0199A, 0x03333, 0x04ccD, 0x06667, - 0x08000, 0x0999A, 0x0b333, 0x0cccD, 0x0e667, - 0x10000, 0x1199A, 0x13333, 0x14ccD, 0x16667, - 0x18000 }; + 0x00000,0x0199A,0x03333,0x04ccD,0x06667, + 0x08000,0x0999A,0x0b333,0x0cccD,0x0e667, + 0x10000,0x1199A,0x13333,0x14ccD,0x16667,0x18000 }; dprintk("%s()\n", __func__); snr_reading = cx24116_readreg(state, CX24116_REG_QUALITY0); - if (snr_reading >= 0xa0 /* 100% */) + if(snr_reading >= 0xa0 /* 100% */) *snr = 0xffff; else - *snr = snr_tab[(snr_reading & 0xf0) >> 4] + - (snr_tab[(snr_reading & 0x0f)] >> 4); + *snr = snr_tab [ ( snr_reading & 0xf0 ) >> 4 ] + + ( snr_tab [ ( snr_reading & 0x0f ) ] >> 4 ); dprintk("%s: raw / cooked = 0x%02x / 0x%04x\n", __func__, snr_reading, *snr); @@ -772,7 +736,7 @@ static int cx24116_read_snr_pct(struct dvb_frontend *fe, u16 *snr) * ESNO, from 0->30db (values 0->300). We provide this value by * default. */ -static int cx24116_read_snr_esno(struct dvb_frontend *fe, u16 *snr) +static int cx24116_read_snr_esno(struct dvb_frontend* fe, u16* snr) { struct cx24116_state *state = fe->demodulator_priv; @@ -786,7 +750,7 @@ static int cx24116_read_snr_esno(struct dvb_frontend *fe, u16 *snr) return 0; } -static int cx24116_read_snr(struct dvb_frontend *fe, u16 *snr) +static int cx24116_read_snr(struct dvb_frontend* fe, u16* snr) { if (esno_snr == 1) return cx24116_read_snr_esno(fe, snr); @@ -794,27 +758,27 @@ static int cx24116_read_snr(struct dvb_frontend *fe, u16 *snr) return cx24116_read_snr_pct(fe, snr); } -static int cx24116_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) +static int cx24116_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) { struct cx24116_state *state = fe->demodulator_priv; dprintk("%s()\n", __func__); - *ucblocks = (cx24116_readreg(state, CX24116_REG_UCB8) << 8) | + *ucblocks = ( cx24116_readreg(state, CX24116_REG_UCB8) << 8 ) | cx24116_readreg(state, CX24116_REG_UCB0); return 0; } /* Overwrite the current tuning params, we are about to tune */ -static void cx24116_clone_params(struct dvb_frontend *fe) +static void cx24116_clone_params(struct dvb_frontend* fe) { struct cx24116_state *state = fe->demodulator_priv; memcpy(&state->dcur, &state->dnxt, sizeof(state->dcur)); } /* Wait for LNB */ -static int cx24116_wait_for_lnb(struct dvb_frontend *fe) +static int cx24116_wait_for_lnb(struct dvb_frontend* fe) { struct cx24116_state *state = fe->demodulator_priv; int i; @@ -823,7 +787,7 @@ static int cx24116_wait_for_lnb(struct dvb_frontend *fe) cx24116_readreg(state, CX24116_REG_QSTATUS)); /* Wait for up to 300 ms */ - for (i = 0; i < 30 ; i++) { + for(i = 0; i < 30 ; i++) { if (cx24116_readreg(state, CX24116_REG_QSTATUS) & 0x20) return 0; msleep(10); @@ -834,21 +798,20 @@ static int cx24116_wait_for_lnb(struct dvb_frontend *fe) return -ETIMEDOUT; /* -EBUSY ? */ } -static int cx24116_set_tone(struct dvb_frontend *fe, - fe_sec_tone_mode_t tone) +static int cx24116_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) { struct cx24116_cmd cmd; int ret; dprintk("%s(%d)\n", __func__, tone); - if ((tone != SEC_TONE_ON) && (tone != SEC_TONE_OFF)) { - printk(KERN_ERR "%s: Invalid, tone=%d\n", __func__, tone); + if ( (tone != SEC_TONE_ON) && (tone != SEC_TONE_OFF) ) { + printk("%s: Invalid, tone=%d\n", __func__, tone); return -EINVAL; } /* Wait for LNB ready */ ret = cx24116_wait_for_lnb(fe); - if (ret != 0) + if(ret != 0) return ret; /* Min delay time after DiSEqC send */ @@ -857,7 +820,7 @@ static int cx24116_set_tone(struct dvb_frontend *fe, /* This is always done before the tone is set */ cmd.args[0x00] = CMD_SET_TONEPRE; cmd.args[0x01] = 0x00; - cmd.len = 0x02; + cmd.len= 0x02; ret = cx24116_cmd_execute(fe, &cmd); if (ret != 0) return ret; @@ -873,11 +836,11 @@ static int cx24116_set_tone(struct dvb_frontend *fe, cmd.args[0x03] = 0x01; break; case SEC_TONE_OFF: - dprintk("%s: setting tone off\n", __func__); + dprintk("%s: setting tone off\n",__func__); cmd.args[0x03] = 0x00; break; } - cmd.len = 0x04; + cmd.len= 0x04; /* Min delay time before DiSEqC send */ msleep(15); /* XXX determine is FW does this, see send_diseqc/burst */ @@ -886,7 +849,7 @@ static int cx24116_set_tone(struct dvb_frontend *fe, } /* Initialise DiSEqC */ -static int cx24116_diseqc_init(struct dvb_frontend *fe) +static int cx24116_diseqc_init(struct dvb_frontend* fe) { struct cx24116_state *state = fe->demodulator_priv; struct cx24116_cmd cmd; @@ -901,7 +864,7 @@ static int cx24116_diseqc_init(struct dvb_frontend *fe) cmd.args[0x05] = 0x28; cmd.args[0x06] = (toneburst == CX24116_DISEQC_TONEOFF) ? 0x00 : 0x01; cmd.args[0x07] = 0x01; - cmd.len = 0x08; + cmd.len= 0x08; ret = cx24116_cmd_execute(fe, &cmd); if (ret != 0) return ret; @@ -915,38 +878,36 @@ static int cx24116_diseqc_init(struct dvb_frontend *fe) /* Unknown */ state->dsec_cmd.args[CX24116_DISEQC_ARG2_2] = 0x02; state->dsec_cmd.args[CX24116_DISEQC_ARG3_0] = 0x00; - /* Continuation flag? */ - state->dsec_cmd.args[CX24116_DISEQC_ARG4_0] = 0x00; + state->dsec_cmd.args[CX24116_DISEQC_ARG4_0] = 0x00; /* Continuation flag? */ /* DiSEqC message length */ state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] = 0x00; /* Command length */ - state->dsec_cmd.len = CX24116_DISEQC_MSGOFS; + state->dsec_cmd.len= CX24116_DISEQC_MSGOFS; return 0; } /* Send DiSEqC message with derived burst (hack) || previous burst */ -static int cx24116_send_diseqc_msg(struct dvb_frontend *fe, - struct dvb_diseqc_master_cmd *d) +static int cx24116_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd *d) { struct cx24116_state *state = fe->demodulator_priv; int i, ret; /* Dump DiSEqC message */ if (debug) { - printk(KERN_INFO "cx24116: %s(", __func__); - for (i = 0 ; i < d->msg_len ;) { - printk(KERN_INFO "0x%02x", d->msg[i]); - if (++i < d->msg_len) - printk(KERN_INFO ", "); - } + printk("cx24116: %s(", __func__); + for(i = 0 ; i < d->msg_len ;) { + printk("0x%02x", d->msg[i]); + if(++i < d->msg_len) + printk(", "); + } printk(") toneburst=%d\n", toneburst); } /* Validate length */ - if (d->msg_len > (CX24116_ARGLEN - CX24116_DISEQC_MSGOFS)) + if(d->msg_len > (CX24116_ARGLEN - CX24116_DISEQC_MSGOFS)) return -EINVAL; /* DiSEqC message */ @@ -957,19 +918,18 @@ static int cx24116_send_diseqc_msg(struct dvb_frontend *fe, state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] = d->msg_len; /* Command length */ - state->dsec_cmd.len = CX24116_DISEQC_MSGOFS + - state->dsec_cmd.args[CX24116_DISEQC_MSGLEN]; + state->dsec_cmd.len= CX24116_DISEQC_MSGOFS + state->dsec_cmd.args[CX24116_DISEQC_MSGLEN]; /* DiSEqC toneburst */ - if (toneburst == CX24116_DISEQC_MESGCACHE) + if(toneburst == CX24116_DISEQC_MESGCACHE) /* Message is cached */ return 0; - else if (toneburst == CX24116_DISEQC_TONEOFF) + else if(toneburst == CX24116_DISEQC_TONEOFF) /* Message is sent without burst */ state->dsec_cmd.args[CX24116_DISEQC_BURST] = 0; - else if (toneburst == CX24116_DISEQC_TONECACHE) { + else if(toneburst == CX24116_DISEQC_TONECACHE) { /* * Message is sent with derived else cached burst * @@ -988,17 +948,15 @@ static int cx24116_send_diseqc_msg(struct dvb_frontend *fe, * Y = VOLTAGE (0=13V, 1=18V) * Z = BAND (0=LOW, 1=HIGH(22K)) */ - if (d->msg_len >= 4 && d->msg[2] == 0x38) - state->dsec_cmd.args[CX24116_DISEQC_BURST] = - ((d->msg[3] & 4) >> 2); - if (debug) - dprintk("%s burst=%d\n", __func__, - state->dsec_cmd.args[CX24116_DISEQC_BURST]); + if(d->msg_len >= 4 && d->msg[2] == 0x38) + state->dsec_cmd.args[CX24116_DISEQC_BURST] = ((d->msg[3] & 4) >> 2); + if(debug) + dprintk("%s burst=%d\n", __func__, state->dsec_cmd.args[CX24116_DISEQC_BURST]); } /* Wait for LNB ready */ ret = cx24116_wait_for_lnb(fe); - if (ret != 0) + if(ret != 0) return ret; /* Wait for voltage/min repeat delay */ @@ -1006,7 +964,7 @@ static int cx24116_send_diseqc_msg(struct dvb_frontend *fe, /* Command */ ret = cx24116_cmd_execute(fe, &state->dsec_cmd); - if (ret != 0) + if(ret != 0) return ret; /* * Wait for send @@ -1018,33 +976,29 @@ static int cx24116_send_diseqc_msg(struct dvb_frontend *fe, * 12.5ms burst + * >15ms delay (XXX determine if FW does this, see set_tone) */ - msleep((state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] << 4) + - ((toneburst == CX24116_DISEQC_TONEOFF) ? 30 : 60)); + msleep( (state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] << 4) + ((toneburst == CX24116_DISEQC_TONEOFF) ? 30 : 60) ); return 0; } /* Send DiSEqC burst */ -static int cx24116_diseqc_send_burst(struct dvb_frontend *fe, - fe_sec_mini_cmd_t burst) +static int cx24116_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t burst) { struct cx24116_state *state = fe->demodulator_priv; int ret; - dprintk("%s(%d) toneburst=%d\n", __func__, burst, toneburst); + dprintk("%s(%d) toneburst=%d\n",__func__, burst, toneburst); /* DiSEqC burst */ if (burst == SEC_MINI_A) - state->dsec_cmd.args[CX24116_DISEQC_BURST] = - CX24116_DISEQC_MINI_A; - else if (burst == SEC_MINI_B) - state->dsec_cmd.args[CX24116_DISEQC_BURST] = - CX24116_DISEQC_MINI_B; + state->dsec_cmd.args[CX24116_DISEQC_BURST] = CX24116_DISEQC_MINI_A; + else if(burst == SEC_MINI_B) + state->dsec_cmd.args[CX24116_DISEQC_BURST] = CX24116_DISEQC_MINI_B; else return -EINVAL; /* DiSEqC toneburst */ - if (toneburst != CX24116_DISEQC_MESGCACHE) + if(toneburst != CX24116_DISEQC_MESGCACHE) /* Burst is cached */ return 0; @@ -1052,7 +1006,7 @@ static int cx24116_diseqc_send_burst(struct dvb_frontend *fe, /* Wait for LNB ready */ ret = cx24116_wait_for_lnb(fe); - if (ret != 0) + if(ret != 0) return ret; /* Wait for voltage/min repeat delay */ @@ -1060,7 +1014,7 @@ static int cx24116_diseqc_send_burst(struct dvb_frontend *fe, /* Command */ ret = cx24116_cmd_execute(fe, &state->dsec_cmd); - if (ret != 0) + if(ret != 0) return ret; /* @@ -1073,32 +1027,34 @@ static int cx24116_diseqc_send_burst(struct dvb_frontend *fe, * 12.5ms burst + * >15ms delay (XXX determine if FW does this, see set_tone) */ - msleep((state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] << 4) + 60); + msleep( (state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] << 4) + 60 ); return 0; } -static void cx24116_release(struct dvb_frontend *fe) +static void cx24116_release(struct dvb_frontend* fe) { - struct cx24116_state *state = fe->demodulator_priv; - dprintk("%s\n", __func__); + struct cx24116_state* state = fe->demodulator_priv; + dprintk("%s\n",__func__); kfree(state); } static struct dvb_frontend_ops cx24116_ops; -struct dvb_frontend *cx24116_attach(const struct cx24116_config *config, - struct i2c_adapter *i2c) +struct dvb_frontend* cx24116_attach(const struct cx24116_config* config, + struct i2c_adapter* i2c) { - struct cx24116_state *state = NULL; + struct cx24116_state* state = NULL; int ret; - dprintk("%s\n", __func__); + dprintk("%s\n",__func__); /* allocate memory for the internal state */ state = kmalloc(sizeof(struct cx24116_state), GFP_KERNEL); - if (state == NULL) + if (state == NULL) { + printk("Unable to kmalloc\n"); goto error1; + } /* setup the state */ memset(state, 0, sizeof(struct cx24116_state)); @@ -1107,36 +1063,32 @@ struct dvb_frontend *cx24116_attach(const struct cx24116_config *config, state->i2c = i2c; /* check if the demod is present */ - ret = (cx24116_readreg(state, 0xFF) << 8) | - cx24116_readreg(state, 0xFE); + ret = (cx24116_readreg(state, 0xFF) << 8) | cx24116_readreg(state, 0xFE); if (ret != 0x0501) { - printk(KERN_INFO "Invalid probe, probably not a CX24116 device\n"); + printk("Invalid probe, probably not a CX24116 device\n"); goto error2; } /* create dvb_frontend */ - memcpy(&state->frontend.ops, &cx24116_ops, - sizeof(struct dvb_frontend_ops)); + memcpy(&state->frontend.ops, &cx24116_ops, sizeof(struct dvb_frontend_ops)); state->frontend.demodulator_priv = state; return &state->frontend; error2: kfree(state); error1: return NULL; } -EXPORT_SYMBOL(cx24116_attach); - /* * Initialise or wake up device * * Power config will reset and load initial firmware if required */ -static int cx24116_initfe(struct dvb_frontend *fe) +static int cx24116_initfe(struct dvb_frontend* fe) { - struct cx24116_state *state = fe->demodulator_priv; + struct cx24116_state* state = fe->demodulator_priv; struct cx24116_cmd cmd; int ret; - dprintk("%s()\n", __func__); + dprintk("%s()\n",__func__); /* Power on */ cx24116_writereg(state, 0xe0, 0); @@ -1146,9 +1098,9 @@ static int cx24116_initfe(struct dvb_frontend *fe) /* Firmware CMD 36: Power config */ cmd.args[0x00] = CMD_TUNERSLEEP; cmd.args[0x01] = 0; - cmd.len = 0x02; + cmd.len= 0x02; ret = cx24116_cmd_execute(fe, &cmd); - if (ret != 0) + if(ret != 0) return ret; return cx24116_diseqc_init(fe); @@ -1157,20 +1109,20 @@ static int cx24116_initfe(struct dvb_frontend *fe) /* * Put device to sleep */ -static int cx24116_sleep(struct dvb_frontend *fe) +static int cx24116_sleep(struct dvb_frontend* fe) { - struct cx24116_state *state = fe->demodulator_priv; + struct cx24116_state* state = fe->demodulator_priv; struct cx24116_cmd cmd; int ret; - dprintk("%s()\n", __func__); + dprintk("%s()\n",__func__); /* Firmware CMD 36: Power config */ cmd.args[0x00] = CMD_TUNERSLEEP; cmd.args[0x01] = 1; - cmd.len = 0x02; + cmd.len= 0x02; ret = cx24116_cmd_execute(fe, &cmd); - if (ret != 0) + if(ret != 0) return ret; /* Power off (Shutdown clocks) */ @@ -1181,15 +1133,13 @@ static int cx24116_sleep(struct dvb_frontend *fe) return 0; } -static int cx24116_set_property(struct dvb_frontend *fe, - struct dtv_property *tvp) +static int cx24116_set_property(struct dvb_frontend *fe, struct dtv_property* tvp) { dprintk("%s(..)\n", __func__); return 0; } -static int cx24116_get_property(struct dvb_frontend *fe, - struct dtv_property *tvp) +static int cx24116_get_property(struct dvb_frontend *fe, struct dtv_property* tvp) { dprintk("%s(..)\n", __func__); return 0; @@ -1198,8 +1148,7 @@ static int cx24116_get_property(struct dvb_frontend *fe, /* dvb-core told us to tune, the tv property cache will be complete, * it's safe for is to pull values and use them for tuning purposes. */ -static int cx24116_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) +static int cx24116_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) { struct cx24116_state *state = fe->demodulator_priv; struct dtv_frontend_properties *c = &fe->dtv_property_cache; @@ -1207,102 +1156,96 @@ static int cx24116_set_frontend(struct dvb_frontend *fe, fe_status_t tunerstat; int i, status, ret, retune; - dprintk("%s()\n", __func__); + dprintk("%s()\n",__func__); - switch (c->delivery_system) { - case SYS_DVBS: - dprintk("%s: DVB-S delivery system selected\n", __func__); + switch(c->delivery_system) { + case SYS_DVBS: + dprintk("%s: DVB-S delivery system selected\n",__func__); - /* Only QPSK is supported for DVB-S */ - if (c->modulation != QPSK) { - dprintk("%s: unsupported modulation selected (%d)\n", - __func__, c->modulation); - return -EOPNOTSUPP; - } + /* Only QPSK is supported for DVB-S */ + if(c->modulation != QPSK) { + dprintk("%s: unsupported modulation selected (%d)\n", + __func__, c->modulation); + return -EOPNOTSUPP; + } - /* Pilot doesn't exist in DVB-S, turn bit off */ - state->dnxt.pilot_val = CX24116_PILOT_OFF; - retune = 1; + /* Pilot doesn't exist in DVB-S, turn bit off */ + state->dnxt.pilot_val = CX24116_PILOT_OFF; + retune = 1; - /* DVB-S only supports 0.35 */ - if (c->rolloff != ROLLOFF_35) { - dprintk("%s: unsupported rolloff selected (%d)\n", - __func__, c->rolloff); - return -EOPNOTSUPP; - } - state->dnxt.rolloff_val = CX24116_ROLLOFF_035; - break; + /* DVB-S only supports 0.35 */ + if(c->rolloff != ROLLOFF_35) { + dprintk("%s: unsupported rolloff selected (%d)\n", + __func__, c->rolloff); + return -EOPNOTSUPP; + } + state->dnxt.rolloff_val = CX24116_ROLLOFF_035; + break; - case SYS_DVBS2: - dprintk("%s: DVB-S2 delivery system selected\n", __func__); + case SYS_DVBS2: + dprintk("%s: DVB-S2 delivery system selected\n",__func__); + + /* + * NBC 8PSK/QPSK with DVB-S is supported for DVB-S2, + * but not hardware auto detection + */ + if(c->modulation != PSK_8 && c->modulation != QPSK) { + dprintk("%s: unsupported modulation selected (%d)\n", + __func__, c->modulation); + return -EOPNOTSUPP; + } - /* - * NBC 8PSK/QPSK with DVB-S is supported for DVB-S2, - * but not hardware auto detection - */ - if (c->modulation != PSK_8 && c->modulation != QPSK) { - dprintk("%s: unsupported modulation selected (%d)\n", - __func__, c->modulation); - return -EOPNOTSUPP; - } + switch(c->pilot) { + case PILOT_AUTO: /* Not supported but emulated */ + retune = 2; /* Fall-through */ + case PILOT_OFF: + state->dnxt.pilot_val = CX24116_PILOT_OFF; + break; + case PILOT_ON: + state->dnxt.pilot_val = CX24116_PILOT_ON; + break; + default: + dprintk("%s: unsupported pilot mode selected (%d)\n", + __func__, c->pilot); + return -EOPNOTSUPP; + } - switch (c->pilot) { - case PILOT_AUTO: /* Not supported but emulated */ - state->dnxt.pilot_val = (c->modulation == QPSK) - ? CX24116_PILOT_OFF : CX24116_PILOT_ON; - retune = 2; - break; - case PILOT_OFF: - state->dnxt.pilot_val = CX24116_PILOT_OFF; - break; - case PILOT_ON: - state->dnxt.pilot_val = CX24116_PILOT_ON; + switch(c->rolloff) { + case ROLLOFF_20: + state->dnxt.rolloff_val= CX24116_ROLLOFF_020; + break; + case ROLLOFF_25: + state->dnxt.rolloff_val= CX24116_ROLLOFF_025; + break; + case ROLLOFF_35: + state->dnxt.rolloff_val= CX24116_ROLLOFF_035; + break; + case ROLLOFF_AUTO: /* Rolloff must be explicit */ + default: + dprintk("%s: unsupported rolloff selected (%d)\n", + __func__, c->rolloff); + return -EOPNOTSUPP; + } break; - default: - dprintk("%s: unsupported pilot mode selected (%d)\n", - __func__, c->pilot); - return -EOPNOTSUPP; - } - switch (c->rolloff) { - case ROLLOFF_20: - state->dnxt.rolloff_val = CX24116_ROLLOFF_020; - break; - case ROLLOFF_25: - state->dnxt.rolloff_val = CX24116_ROLLOFF_025; - break; - case ROLLOFF_35: - state->dnxt.rolloff_val = CX24116_ROLLOFF_035; - break; - case ROLLOFF_AUTO: /* Rolloff must be explicit */ default: - dprintk("%s: unsupported rolloff selected (%d)\n", - __func__, c->rolloff); + dprintk("%s: unsupported delivery system selected (%d)\n", + __func__, c->delivery_system); return -EOPNOTSUPP; - } - break; - - default: - dprintk("%s: unsupported delivery system selected (%d)\n", - __func__, c->delivery_system); - return -EOPNOTSUPP; } state->dnxt.modulation = c->modulation; state->dnxt.frequency = c->frequency; state->dnxt.pilot = c->pilot; state->dnxt.rolloff = c->rolloff; - ret = cx24116_set_inversion(state, c->inversion); - if (ret != 0) + if ((ret = cx24116_set_inversion(state, c->inversion)) != 0) return ret; /* FEC_NONE/AUTO for DVB-S2 is not supported and detected here */ - ret = cx24116_set_fec(state, c->modulation, c->fec_inner); - if (ret != 0) + if ((ret = cx24116_set_fec(state, c->modulation, c->fec_inner)) != 0) return ret; - ret = cx24116_set_symbolrate(state, c->symbol_rate); - if (ret != 0) + if ((ret = cx24116_set_symbolrate(state, c->symbol_rate)) != 0) return ret; /* discard the 'current' tuning parameters and prepare to tune */ @@ -1328,7 +1271,7 @@ static int cx24116_set_frontend(struct dvb_frontend *fe, /* Set/Reset B/W */ cmd.args[0x00] = CMD_BANDWIDTH; cmd.args[0x01] = 0x01; - cmd.len = 0x02; + cmd.len= 0x02; ret = cx24116_cmd_execute(fe, &cmd); if (ret != 0) return ret; @@ -1376,7 +1319,7 @@ static int cx24116_set_frontend(struct dvb_frontend *fe, cx24116_writereg(state, CX24116_REG_RATEDIV, 0x00); } - cmd.len = 0x13; + cmd.len= 0x13; /* We need to support pilot and non-pilot tuning in the * driver automatically. This is a workaround for because @@ -1384,13 +1327,12 @@ static int cx24116_set_frontend(struct dvb_frontend *fe, */ do { /* Reset status register */ - status = cx24116_readreg(state, CX24116_REG_SSTATUS) - & CX24116_SIGNAL_MASK; + status = cx24116_readreg(state, CX24116_REG_SSTATUS) & CX24116_SIGNAL_MASK; cx24116_writereg(state, CX24116_REG_SSTATUS, status); /* Tune */ ret = cx24116_cmd_execute(fe, &cmd); - if (ret != 0) + if( ret != 0 ) break; /* @@ -1399,27 +1341,28 @@ static int cx24116_set_frontend(struct dvb_frontend *fe, * If we are able to tune then generally it occurs within 100ms. * If it takes longer, try a different toneburst setting. */ - for (i = 0; i < 50 ; i++) { + for(i = 0; i < 50 ; i++) { cx24116_read_status(fe, &tunerstat); status = tunerstat & (FE_HAS_SIGNAL | FE_HAS_SYNC); - if (status == (FE_HAS_SIGNAL | FE_HAS_SYNC)) { - dprintk("%s: Tuned\n", __func__); + if(status == (FE_HAS_SIGNAL | FE_HAS_SYNC)) { + dprintk("%s: Tuned\n",__func__); goto tuned; } msleep(10); } - dprintk("%s: Not tuned\n", __func__); + dprintk("%s: Not tuned\n",__func__); /* Toggle pilot bit when in auto-pilot */ - if (state->dcur.pilot == PILOT_AUTO) + if(state->dcur.pilot == PILOT_AUTO) cmd.args[0x07] ^= CX24116_PILOT_ON; - } while (--retune); + } + while(--retune); tuned: /* Set/Reset B/W */ cmd.args[0x00] = CMD_BANDWIDTH; cmd.args[0x01] = 0x00; - cmd.len = 0x02; + cmd.len= 0x02; ret = cx24116_cmd_execute(fe, &cmd); if (ret != 0) return ret; @@ -1464,7 +1407,17 @@ static struct dvb_frontend_ops cx24116_ops = { .set_frontend = cx24116_set_frontend, }; +module_param(debug, int, 0644); +MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)"); + +module_param(toneburst, int, 0644); +MODULE_PARM_DESC(toneburst, "DiSEqC toneburst 0=OFF, 1=TONE CACHE, 2=MESSAGE CACHE (default:1)"); + +module_param(esno_snr, int, 0644); +MODULE_PARM_DESC(debug, "SNR return units, 0=PERCENTAGE 0-100, 1=ESNO(db * 10) (default:0)"); + MODULE_DESCRIPTION("DVB Frontend module for Conexant cx24116/cx24118 hardware"); MODULE_AUTHOR("Steven Toth"); MODULE_LICENSE("GPL"); +EXPORT_SYMBOL(cx24116_attach); diff --git a/trunk/drivers/media/dvb/frontends/cx24116.h b/trunk/drivers/media/dvb/frontends/cx24116.h index 4cb3ddd6c626..8dbcec268394 100644 --- a/trunk/drivers/media/dvb/frontends/cx24116.h +++ b/trunk/drivers/media/dvb/frontends/cx24116.h @@ -23,32 +23,31 @@ #include -struct cx24116_config { +struct cx24116_config +{ /* the demodulator's i2c address */ u8 demod_address; /* Need to set device param for start_dma */ - int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured); + int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured); /* Need to reset device during firmware loading */ - int (*reset_device)(struct dvb_frontend *fe); + int (*reset_device)(struct dvb_frontend* fe); /* Need to set MPEG parameters */ u8 mpg_clk_pos_pol:0x02; }; #if defined(CONFIG_DVB_CX24116) || defined(CONFIG_DVB_CX24116_MODULE) -extern struct dvb_frontend *cx24116_attach( - const struct cx24116_config *config, - struct i2c_adapter *i2c); +extern struct dvb_frontend* cx24116_attach(const struct cx24116_config* config, + struct i2c_adapter* i2c); #else -static inline struct dvb_frontend *cx24116_attach( - const struct cx24116_config *config, - struct i2c_adapter *i2c) +static inline struct dvb_frontend* cx24116_attach(const struct cx24116_config* config, + struct i2c_adapter* i2c) { - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); return NULL; } -#endif +#endif // CONFIG_DVB_CX24116 #endif /* CX24116_H */ diff --git a/trunk/drivers/media/dvb/frontends/cx24123.c b/trunk/drivers/media/dvb/frontends/cx24123.c index 1a8c36f76061..7156157cb34b 100644 --- a/trunk/drivers/media/dvb/frontends/cx24123.c +++ b/trunk/drivers/media/dvb/frontends/cx24123.c @@ -33,13 +33,7 @@ #define XTAL 10111000 static int force_band; -module_param(force_band, int, 0644); -MODULE_PARM_DESC(force_band, "Force a specific band select "\ - "(1-9, default:off)."); - static int debug; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)"); #define info(args...) do { printk(KERN_INFO "CX24123: " args); } while (0) #define err(args...) do { printk(KERN_ERR "CX24123: " args); } while (0) @@ -52,9 +46,10 @@ MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)"); } \ } while (0) -struct cx24123_state { - struct i2c_adapter *i2c; - const struct cx24123_config *config; +struct cx24123_state +{ + struct i2c_adapter* i2c; + const struct cx24123_config* config; struct dvb_frontend frontend; @@ -75,7 +70,8 @@ struct cx24123_state { }; /* Various tuner defaults need to be established for a given symbol rate Sps */ -static struct cx24123_AGC_val { +static struct +{ u32 symbolrate_low; u32 symbolrate_high; u32 VCAprogdata; @@ -113,7 +109,8 @@ static struct cx24123_AGC_val { * fixme: The bounds on the bands do not match the doc in real life. * fixme: Some of them have been moved, other might need adjustment. */ -static struct cx24123_bandselect_val { +static struct +{ u32 freq_low; u32 freq_high; u32 VCOdivider; @@ -252,8 +249,7 @@ static int cx24123_i2c_writereg(struct cx24123_state *state, /* printk(KERN_DEBUG "wr(%02x): %02x %02x\n", i2c_addr, reg, data); */ - err = i2c_transfer(state->i2c, &msg, 1); - if (err != 1) { + if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) { printk("%s: writereg error(err == %i, reg == 0x%02x," " data == 0x%02x)\n", __func__, err, reg, data); return err; @@ -288,8 +284,7 @@ static int cx24123_i2c_readreg(struct cx24123_state *state, u8 i2c_addr, u8 reg) #define cx24123_writereg(state, reg, val) \ cx24123_i2c_writereg(state, state->config->demod_address, reg, val) -static int cx24123_set_inversion(struct cx24123_state *state, - fe_spectral_inversion_t inversion) +static int cx24123_set_inversion(struct cx24123_state* state, fe_spectral_inversion_t inversion) { u8 nom_reg = cx24123_readreg(state, 0x0e); u8 auto_reg = cx24123_readreg(state, 0x10); @@ -316,8 +311,7 @@ static int cx24123_set_inversion(struct cx24123_state *state, return 0; } -static int cx24123_get_inversion(struct cx24123_state *state, - fe_spectral_inversion_t *inversion) +static int cx24123_get_inversion(struct cx24123_state* state, fe_spectral_inversion_t *inversion) { u8 val; @@ -334,20 +328,18 @@ static int cx24123_get_inversion(struct cx24123_state *state, return 0; } -static int cx24123_set_fec(struct cx24123_state *state, fe_code_rate_t fec) +static int cx24123_set_fec(struct cx24123_state* state, fe_code_rate_t fec) { u8 nom_reg = cx24123_readreg(state, 0x0e) & ~0x07; - if ((fec < FEC_NONE) || (fec > FEC_AUTO)) + if ( (fec < FEC_NONE) || (fec > FEC_AUTO) ) fec = FEC_AUTO; /* Set the soft decision threshold */ - if (fec == FEC_1_2) - cx24123_writereg(state, 0x43, - cx24123_readreg(state, 0x43) | 0x01); + if(fec == FEC_1_2) + cx24123_writereg(state, 0x43, cx24123_readreg(state, 0x43) | 0x01); else - cx24123_writereg(state, 0x43, - cx24123_readreg(state, 0x43) & ~0x01); + cx24123_writereg(state, 0x43, cx24123_readreg(state, 0x43) & ~0x01); switch (fec) { case FEC_1_2: @@ -396,11 +388,11 @@ static int cx24123_set_fec(struct cx24123_state *state, fe_code_rate_t fec) return 0; } -static int cx24123_get_fec(struct cx24123_state *state, fe_code_rate_t *fec) +static int cx24123_get_fec(struct cx24123_state* state, fe_code_rate_t *fec) { int ret; - ret = cx24123_readreg(state, 0x1b); + ret = cx24123_readreg (state, 0x1b); if (ret < 0) return ret; ret = ret & 0x07; @@ -441,16 +433,16 @@ static u32 cx24123_int_log2(u32 a, u32 b) { u32 exp, nearest = 0; u32 div = a / b; - if (a % b >= b / 2) - ++div; - if (div < (1 << 31)) { - for (exp = 1; div > exp; nearest++) + if(a % b >= b / 2) ++div; + if(div < (1 << 31)) + { + for(exp = 1; div > exp; nearest++) exp += exp; } return nearest; } -static int cx24123_set_symbolrate(struct cx24123_state *state, u32 srate) +static int cx24123_set_symbolrate(struct cx24123_state* state, u32 srate) { u32 tmp, sample_rate, ratio, sample_gain; u8 pll_mult; @@ -506,9 +498,9 @@ static int cx24123_set_symbolrate(struct cx24123_state *state, u32 srate) cx24123_writereg(state, 0x01, pll_mult * 6); - cx24123_writereg(state, 0x08, (ratio >> 16) & 0x3f); - cx24123_writereg(state, 0x09, (ratio >> 8) & 0xff); - cx24123_writereg(state, 0x0a, ratio & 0xff); + cx24123_writereg(state, 0x08, (ratio >> 16) & 0x3f ); + cx24123_writereg(state, 0x09, (ratio >> 8) & 0xff ); + cx24123_writereg(state, 0x0a, (ratio ) & 0xff ); /* also set the demodulator sample gain */ sample_gain = cx24123_int_log2(sample_rate, srate); @@ -522,12 +514,10 @@ static int cx24123_set_symbolrate(struct cx24123_state *state, u32 srate) } /* - * Based on the required frequency and symbolrate, the tuner AGC has - * to be configured and the correct band selected. - * Calculate those values. + * Based on the required frequency and symbolrate, the tuner AGC has to be configured + * and the correct band selected. Calculate those values */ -static int cx24123_pll_calculate(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) +static int cx24123_pll_calculate(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) { struct cx24123_state *state = fe->demodulator_priv; u32 ndiv = 0, adiv = 0, vco_div = 0; @@ -535,8 +525,6 @@ static int cx24123_pll_calculate(struct dvb_frontend *fe, int pump = 2; int band = 0; int num_bands = ARRAY_SIZE(cx24123_bandselect_vals); - struct cx24123_bandselect_val *bsv = NULL; - struct cx24123_AGC_val *agcv = NULL; /* Defaults for low freq, low rate */ state->VCAarg = cx24123_AGC_vals[0].VCAprogdata; @@ -544,65 +532,58 @@ static int cx24123_pll_calculate(struct dvb_frontend *fe, state->bandselectarg = cx24123_bandselect_vals[0].progdata; vco_div = cx24123_bandselect_vals[0].VCOdivider; - /* For the given symbol rate, determine the VCA, VGA and - * FILTUNE programming bits */ - for (i = 0; i < ARRAY_SIZE(cx24123_AGC_vals); i++) { - agcv = &cx24123_AGC_vals[i]; - if ((agcv->symbolrate_low <= p->u.qpsk.symbol_rate) && - (agcv->symbolrate_high >= p->u.qpsk.symbol_rate)) { - state->VCAarg = agcv->VCAprogdata; - state->VGAarg = agcv->VGAprogdata; - state->FILTune = agcv->FILTune; + /* For the given symbol rate, determine the VCA, VGA and FILTUNE programming bits */ + for (i = 0; i < ARRAY_SIZE(cx24123_AGC_vals); i++) + { + if ((cx24123_AGC_vals[i].symbolrate_low <= p->u.qpsk.symbol_rate) && + (cx24123_AGC_vals[i].symbolrate_high >= p->u.qpsk.symbol_rate) ) { + state->VCAarg = cx24123_AGC_vals[i].VCAprogdata; + state->VGAarg = cx24123_AGC_vals[i].VGAprogdata; + state->FILTune = cx24123_AGC_vals[i].FILTune; } } /* determine the band to use */ - if (force_band < 1 || force_band > num_bands) { - for (i = 0; i < num_bands; i++) { - bsv = &cx24123_bandselect_vals[i]; - if ((bsv->freq_low <= p->frequency) && - (bsv->freq_high >= p->frequency)) + if(force_band < 1 || force_band > num_bands) + { + for (i = 0; i < num_bands; i++) + { + if ((cx24123_bandselect_vals[i].freq_low <= p->frequency) && + (cx24123_bandselect_vals[i].freq_high >= p->frequency) ) band = i; } - } else + } + else band = force_band - 1; state->bandselectarg = cx24123_bandselect_vals[band].progdata; vco_div = cx24123_bandselect_vals[band].VCOdivider; /* determine the charge pump current */ - if (p->frequency < (cx24123_bandselect_vals[band].freq_low + - cx24123_bandselect_vals[band].freq_high) / 2) + if ( p->frequency < (cx24123_bandselect_vals[band].freq_low + cx24123_bandselect_vals[band].freq_high)/2 ) pump = 0x01; else pump = 0x02; /* Determine the N/A dividers for the requested lband freq (in kHz). */ - /* Note: the reference divider R=10, frequency is in KHz, - * XTAL is in Hz */ - ndiv = (((p->frequency * vco_div * 10) / - (2 * XTAL / 1000)) / 32) & 0x1ff; - adiv = (((p->frequency * vco_div * 10) / - (2 * XTAL / 1000)) % 32) & 0x1f; + /* Note: the reference divider R=10, frequency is in KHz, XTAL is in Hz */ + ndiv = ( ((p->frequency * vco_div * 10) / (2 * XTAL / 1000)) / 32) & 0x1ff; + adiv = ( ((p->frequency * vco_div * 10) / (2 * XTAL / 1000)) % 32) & 0x1f; if (adiv == 0 && ndiv > 0) ndiv--; - /* control bits 11, refdiv 11, charge pump polarity 1, - * charge pump current, ndiv, adiv */ - state->pllarg = (3 << 19) | (3 << 17) | (1 << 16) | - (pump << 14) | (ndiv << 5) | adiv; + /* control bits 11, refdiv 11, charge pump polarity 1, charge pump current, ndiv, adiv */ + state->pllarg = (3 << 19) | (3 << 17) | (1 << 16) | (pump << 14) | (ndiv << 5) | adiv; return 0; } /* * Tuner data is 21 bits long, must be left-aligned in data. - * Tuner cx24109 is written through a dedicated 3wire interface - * on the demod chip. + * Tuner cx24109 is written through a dedicated 3wire interface on the demod chip. */ -static int cx24123_pll_writereg(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p, u32 data) +static int cx24123_pll_writereg(struct dvb_frontend* fe, struct dvb_frontend_parameters *p, u32 data) { struct cx24123_state *state = fe->demodulator_priv; unsigned long timeout; @@ -629,7 +610,7 @@ static int cx24123_pll_writereg(struct dvb_frontend *fe, /* send another 8 bytes, wait for the send to be completed */ timeout = jiffies + msecs_to_jiffies(40); - cx24123_writereg(state, 0x22, (data >> 8) & 0xff); + cx24123_writereg(state, 0x22, (data>>8) & 0xff ); while ((cx24123_readreg(state, 0x20) & 0x40) == 0) { if (time_after(jiffies, timeout)) { err("%s: demodulator is not responding, "\ @@ -639,10 +620,9 @@ static int cx24123_pll_writereg(struct dvb_frontend *fe, msleep(10); } - /* send the lower 5 bits of this byte, padded with 3 LBB, - * wait for the send to be completed */ + /* send the lower 5 bits of this byte, padded with 3 LBB, wait for the send to be completed */ timeout = jiffies + msecs_to_jiffies(40); - cx24123_writereg(state, 0x22, (data) & 0xff); + cx24123_writereg(state, 0x22, (data) & 0xff ); while ((cx24123_readreg(state, 0x20) & 0x80)) { if (time_after(jiffies, timeout)) { err("%s: demodulator is not responding," \ @@ -659,8 +639,7 @@ static int cx24123_pll_writereg(struct dvb_frontend *fe, return 0; } -static int cx24123_pll_tune(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) +static int cx24123_pll_tune(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) { struct cx24123_state *state = fe->demodulator_priv; u8 val; @@ -711,7 +690,7 @@ static int cx24123_repeater_mode(struct cx24123_state *state, u8 mode, u8 start) return cx24123_writereg(state, 0x23, r); } -static int cx24123_initfe(struct dvb_frontend *fe) +static int cx24123_initfe(struct dvb_frontend* fe) { struct cx24123_state *state = fe->demodulator_priv; int i; @@ -720,22 +699,19 @@ static int cx24123_initfe(struct dvb_frontend *fe) /* Configure the demod to a good set of defaults */ for (i = 0; i < ARRAY_SIZE(cx24123_regdata); i++) - cx24123_writereg(state, cx24123_regdata[i].reg, - cx24123_regdata[i].data); + cx24123_writereg(state, cx24123_regdata[i].reg, cx24123_regdata[i].data); /* Set the LNB polarity */ - if (state->config->lnb_polarity) - cx24123_writereg(state, 0x32, - cx24123_readreg(state, 0x32) | 0x02); + if(state->config->lnb_polarity) + cx24123_writereg(state, 0x32, cx24123_readreg(state, 0x32) | 0x02); if (state->config->dont_use_pll) - cx24123_repeater_mode(state, 1, 0); + cx24123_repeater_mode(state, 1, 0); return 0; } -static int cx24123_set_voltage(struct dvb_frontend *fe, - fe_sec_voltage_t voltage) +static int cx24123_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) { struct cx24123_state *state = fe->demodulator_priv; u8 val; @@ -764,7 +740,7 @@ static void cx24123_wait_for_diseqc(struct cx24123_state *state) { unsigned long timeout = jiffies + msecs_to_jiffies(200); while (!(cx24123_readreg(state, 0x29) & 0x40)) { - if (time_after(jiffies, timeout)) { + if(time_after(jiffies, timeout)) { err("%s: diseqc queue not ready, " \ "command may be lost.\n", __func__); break; @@ -773,8 +749,7 @@ static void cx24123_wait_for_diseqc(struct cx24123_state *state) } } -static int cx24123_send_diseqc_msg(struct dvb_frontend *fe, - struct dvb_diseqc_master_cmd *cmd) +static int cx24123_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd *cmd) { struct cx24123_state *state = fe->demodulator_priv; int i, val, tone; @@ -796,21 +771,20 @@ static int cx24123_send_diseqc_msg(struct dvb_frontend *fe, cx24123_writereg(state, 0x2C + i, cmd->msg[i]); val = cx24123_readreg(state, 0x29); - cx24123_writereg(state, 0x29, ((val & 0x90) | 0x40) | - ((cmd->msg_len-3) & 3)); + cx24123_writereg(state, 0x29, ((val & 0x90) | 0x40) | ((cmd->msg_len-3) & 3)); /* wait for diseqc message to finish sending */ cx24123_wait_for_diseqc(state); /* restart continuous tone if enabled */ - if (tone & 0x10) + if (tone & 0x10) { cx24123_writereg(state, 0x29, tone & ~0x40); + } return 0; } -static int cx24123_diseqc_send_burst(struct dvb_frontend *fe, - fe_sec_mini_cmd_t burst) +static int cx24123_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t burst) { struct cx24123_state *state = fe->demodulator_priv; int val, tone; @@ -840,13 +814,13 @@ static int cx24123_diseqc_send_burst(struct dvb_frontend *fe, cx24123_writereg(state, 0x2a, cx24123_readreg(state, 0x2a) & 0xfb); /* restart continuous tone if enabled */ - if (tone & 0x10) + if (tone & 0x10) { cx24123_writereg(state, 0x29, tone & ~0x40); - + } return 0; } -static int cx24123_read_status(struct dvb_frontend *fe, fe_status_t *status) +static int cx24123_read_status(struct dvb_frontend* fe, fe_status_t* status) { struct cx24123_state *state = fe->demodulator_priv; int sync = cx24123_readreg(state, 0x14); @@ -879,9 +853,8 @@ static int cx24123_read_status(struct dvb_frontend *fe, fe_status_t *status) } /* - * Configured to return the measurement of errors in blocks, - * because no UCBLOCKS value is available, so this value doubles up - * to satisfy both measurements. + * Configured to return the measurement of errors in blocks, because no UCBLOCKS value + * is available, so this value doubles up to satisfy both measurements */ static int cx24123_read_ber(struct dvb_frontend *fe, u32 *ber) { @@ -903,8 +876,7 @@ static int cx24123_read_signal_strength(struct dvb_frontend *fe, { struct cx24123_state *state = fe->demodulator_priv; - /* larger = better */ - *signal_strength = cx24123_readreg(state, 0x3b) << 8; + *signal_strength = cx24123_readreg(state, 0x3b) << 8; /* larger = better */ dprintk("Signal strength = %d\n", *signal_strength); @@ -935,7 +907,7 @@ static int cx24123_set_frontend(struct dvb_frontend *fe, if (state->config->set_ts_params) state->config->set_ts_params(fe, 0); - state->currentfreq = p->frequency; + state->currentfreq=p->frequency; state->currentsymbolrate = p->u.qpsk.symbol_rate; cx24123_set_inversion(state, p->inversion); @@ -960,8 +932,7 @@ static int cx24123_set_frontend(struct dvb_frontend *fe, return 0; } -static int cx24123_get_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) +static int cx24123_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) { struct cx24123_state *state = fe->demodulator_priv; @@ -981,7 +952,7 @@ static int cx24123_get_frontend(struct dvb_frontend *fe, return 0; } -static int cx24123_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) +static int cx24123_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) { struct cx24123_state *state = fe->demodulator_priv; u8 val; @@ -1006,8 +977,8 @@ static int cx24123_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) return 0; } -static int cx24123_tune(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params, +static int cx24123_tune(struct dvb_frontend* fe, + struct dvb_frontend_parameters* params, unsigned int mode_flags, unsigned int *delay, fe_status_t *status) @@ -1026,12 +997,12 @@ static int cx24123_tune(struct dvb_frontend *fe, static int cx24123_get_algo(struct dvb_frontend *fe) { - return 1; /* FE_ALGO_HW */ + return 1; //FE_ALGO_HW } -static void cx24123_release(struct dvb_frontend *fe) +static void cx24123_release(struct dvb_frontend* fe) { - struct cx24123_state *state = fe->demodulator_priv; + struct cx24123_state* state = fe->demodulator_priv; dprintk("\n"); i2c_del_adapter(&state->tuner_i2c_adapter); kfree(state); @@ -1042,7 +1013,7 @@ static int cx24123_tuner_i2c_tuner_xfer(struct i2c_adapter *i2c_adap, { struct cx24123_state *state = i2c_get_adapdata(i2c_adap); /* this repeater closes after the first stop */ - cx24123_repeater_mode(state, 1, 1); + cx24123_repeater_mode(state, 1, 1); return i2c_transfer(state->i2c, msg, num); } @@ -1066,8 +1037,8 @@ EXPORT_SYMBOL(cx24123_get_tuner_i2c_adapter); static struct dvb_frontend_ops cx24123_ops; -struct dvb_frontend *cx24123_attach(const struct cx24123_config *config, - struct i2c_adapter *i2c) +struct dvb_frontend* cx24123_attach(const struct cx24123_config* config, + struct i2c_adapter* i2c) { struct cx24123_state *state = kzalloc(sizeof(struct cx24123_state), GFP_KERNEL); @@ -1086,25 +1057,20 @@ struct dvb_frontend *cx24123_attach(const struct cx24123_config *config, /* check if the demod is there */ state->demod_rev = cx24123_readreg(state, 0x00); switch (state->demod_rev) { - case 0xe1: - info("detected CX24123C\n"); - break; - case 0xd1: - info("detected CX24123\n"); - break; + case 0xe1: info("detected CX24123C\n"); break; + case 0xd1: info("detected CX24123\n"); break; default: err("wrong demod revision: %x\n", state->demod_rev); goto error; } /* create dvb_frontend */ - memcpy(&state->frontend.ops, &cx24123_ops, - sizeof(struct dvb_frontend_ops)); + memcpy(&state->frontend.ops, &cx24123_ops, sizeof(struct dvb_frontend_ops)); state->frontend.demodulator_priv = state; - /* create tuner i2c adapter */ - if (config->dont_use_pll) - cx24123_repeater_mode(state, 1, 0); + /* create tuner i2c adapter */ + if (config->dont_use_pll) + cx24123_repeater_mode(state, 1, 0); strlcpy(state->tuner_i2c_adapter.name, "CX24123 tuner I2C bus", sizeof(state->tuner_i2c_adapter.name)); @@ -1113,7 +1079,7 @@ struct dvb_frontend *cx24123_attach(const struct cx24123_config *config, state->tuner_i2c_adapter.algo_data = NULL; i2c_set_adapdata(&state->tuner_i2c_adapter, state); if (i2c_add_adapter(&state->tuner_i2c_adapter) < 0) { - err("tuner i2c bus could not be initialized\n"); + err("tuner i2c bus could not be initialized\n"); goto error; } @@ -1124,7 +1090,6 @@ struct dvb_frontend *cx24123_attach(const struct cx24123_config *config, return NULL; } -EXPORT_SYMBOL(cx24123_attach); static struct dvb_frontend_ops cx24123_ops = { @@ -1161,8 +1126,15 @@ static struct dvb_frontend_ops cx24123_ops = { .get_frontend_algo = cx24123_get_algo, }; +module_param(debug, int, 0644); +MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)"); + +module_param(force_band, int, 0644); +MODULE_PARM_DESC(force_band, "Force a specific band select (1-9, default:off)."); + MODULE_DESCRIPTION("DVB Frontend module for Conexant " \ "CX24123/CX24109/CX24113 hardware"); MODULE_AUTHOR("Steven Toth"); MODULE_LICENSE("GPL"); +EXPORT_SYMBOL(cx24123_attach); diff --git a/trunk/drivers/media/dvb/frontends/cx24123.h b/trunk/drivers/media/dvb/frontends/cx24123.h index 51ae866e9fed..cc6b411d6d20 100644 --- a/trunk/drivers/media/dvb/frontends/cx24123.h +++ b/trunk/drivers/media/dvb/frontends/cx24123.h @@ -23,12 +23,13 @@ #include -struct cx24123_config { +struct cx24123_config +{ /* the demodulator's i2c address */ u8 demod_address; /* Need to set device param for start_dma */ - int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured); + int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured); /* 0 = LNB voltage normal, 1 = LNB voltage inverted */ int lnb_polarity; @@ -38,8 +39,7 @@ struct cx24123_config { void (*agc_callback) (struct dvb_frontend *); }; -#if defined(CONFIG_DVB_CX24123) || (defined(CONFIG_DVB_CX24123_MODULE) \ - && defined(MODULE)) +#if defined(CONFIG_DVB_CX24123) || (defined(CONFIG_DVB_CX24123_MODULE) && defined(MODULE)) extern struct dvb_frontend *cx24123_attach(const struct cx24123_config *config, struct i2c_adapter *i2c); extern struct i2c_adapter *cx24123_get_tuner_i2c_adapter(struct dvb_frontend *); @@ -56,6 +56,6 @@ static struct i2c_adapter * printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } -#endif +#endif // CONFIG_DVB_CX24123 #endif /* CX24123_H */ diff --git a/trunk/drivers/media/dvb/frontends/s5h1409.c b/trunk/drivers/media/dvb/frontends/s5h1409.c index cf4d8936bb83..7500a1c53e68 100644 --- a/trunk/drivers/media/dvb/frontends/s5h1409.c +++ b/trunk/drivers/media/dvb/frontends/s5h1409.c @@ -30,10 +30,10 @@ struct s5h1409_state { - struct i2c_adapter *i2c; + struct i2c_adapter* i2c; /* configuration settings */ - const struct s5h1409_config *config; + const struct s5h1409_config* config; struct dvb_frontend frontend; @@ -48,9 +48,6 @@ struct s5h1409_state { }; static int debug; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Enable verbose debug messages"); - #define dprintk if (debug) printk /* Register values to initialise the demod, this will set VSB by default */ @@ -302,10 +299,10 @@ static struct qam256_snr_tab { }; /* 8 bit registers, 16 bit values */ -static int s5h1409_writereg(struct s5h1409_state *state, u8 reg, u16 data) +static int s5h1409_writereg(struct s5h1409_state* state, u8 reg, u16 data) { int ret; - u8 buf[] = { reg, data >> 8, data & 0xff }; + u8 buf [] = { reg, data >> 8, data & 0xff }; struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 3 }; @@ -313,19 +310,19 @@ static int s5h1409_writereg(struct s5h1409_state *state, u8 reg, u16 data) ret = i2c_transfer(state->i2c, &msg, 1); if (ret != 1) - printk(KERN_ERR "%s: error (reg == 0x%02x, val == 0x%04x, " + printk("%s: writereg error (reg == 0x%02x, val == 0x%04x, " "ret == %i)\n", __func__, reg, data, ret); return (ret != 1) ? -1 : 0; } -static u16 s5h1409_readreg(struct s5h1409_state *state, u8 reg) +static u16 s5h1409_readreg(struct s5h1409_state* state, u8 reg) { int ret; - u8 b0[] = { reg }; - u8 b1[] = { 0, 0 }; + u8 b0 [] = { reg }; + u8 b1 [] = { 0, 0 }; - struct i2c_msg msg[] = { + struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 }, { .addr = state->config->demod_address, .flags = I2C_M_RD, @@ -338,9 +335,9 @@ static u16 s5h1409_readreg(struct s5h1409_state *state, u8 reg) return (b1[0] << 8) | b1[1]; } -static int s5h1409_softreset(struct dvb_frontend *fe) +static int s5h1409_softreset(struct dvb_frontend* fe) { - struct s5h1409_state *state = fe->demodulator_priv; + struct s5h1409_state* state = fe->demodulator_priv; dprintk("%s()\n", __func__); @@ -352,11 +349,11 @@ static int s5h1409_softreset(struct dvb_frontend *fe) } #define S5H1409_VSB_IF_FREQ 5380 -#define S5H1409_QAM_IF_FREQ (state->config->qam_if) +#define S5H1409_QAM_IF_FREQ state->config->qam_if -static int s5h1409_set_if_freq(struct dvb_frontend *fe, int KHz) +static int s5h1409_set_if_freq(struct dvb_frontend* fe, int KHz) { - struct s5h1409_state *state = fe->demodulator_priv; + struct s5h1409_state* state = fe->demodulator_priv; dprintk("%s(%d KHz)\n", __func__, KHz); @@ -379,26 +376,26 @@ static int s5h1409_set_if_freq(struct dvb_frontend *fe, int KHz) return 0; } -static int s5h1409_set_spectralinversion(struct dvb_frontend *fe, int inverted) +static int s5h1409_set_spectralinversion(struct dvb_frontend* fe, int inverted) { - struct s5h1409_state *state = fe->demodulator_priv; + struct s5h1409_state* state = fe->demodulator_priv; dprintk("%s(%d)\n", __func__, inverted); - if (inverted == 1) + if(inverted == 1) return s5h1409_writereg(state, 0x1b, 0x1101); /* Inverted */ else return s5h1409_writereg(state, 0x1b, 0x0110); /* Normal */ } -static int s5h1409_enable_modulation(struct dvb_frontend *fe, +static int s5h1409_enable_modulation(struct dvb_frontend* fe, fe_modulation_t m) { - struct s5h1409_state *state = fe->demodulator_priv; + struct s5h1409_state* state = fe->demodulator_priv; dprintk("%s(0x%08x)\n", __func__, m); - switch (m) { + switch(m) { case VSB_8: dprintk("%s() VSB_8\n", __func__); if (state->if_freq != S5H1409_VSB_IF_FREQ) @@ -425,9 +422,9 @@ static int s5h1409_enable_modulation(struct dvb_frontend *fe, return 0; } -static int s5h1409_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) +static int s5h1409_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) { - struct s5h1409_state *state = fe->demodulator_priv; + struct s5h1409_state* state = fe->demodulator_priv; dprintk("%s(%d)\n", __func__, enable); @@ -437,9 +434,9 @@ static int s5h1409_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) return s5h1409_writereg(state, 0xf3, 0); } -static int s5h1409_set_gpio(struct dvb_frontend *fe, int enable) +static int s5h1409_set_gpio(struct dvb_frontend* fe, int enable) { - struct s5h1409_state *state = fe->demodulator_priv; + struct s5h1409_state* state = fe->demodulator_priv; dprintk("%s(%d)\n", __func__, enable); @@ -451,18 +448,18 @@ static int s5h1409_set_gpio(struct dvb_frontend *fe, int enable) s5h1409_readreg(state, 0xe3) & 0xfeff); } -static int s5h1409_sleep(struct dvb_frontend *fe, int enable) +static int s5h1409_sleep(struct dvb_frontend* fe, int enable) { - struct s5h1409_state *state = fe->demodulator_priv; + struct s5h1409_state* state = fe->demodulator_priv; dprintk("%s(%d)\n", __func__, enable); return s5h1409_writereg(state, 0xf2, enable); } -static int s5h1409_register_reset(struct dvb_frontend *fe) +static int s5h1409_register_reset(struct dvb_frontend* fe) { - struct s5h1409_state *state = fe->demodulator_priv; + struct s5h1409_state* state = fe->demodulator_priv; dprintk("%s()\n", __func__); @@ -486,7 +483,7 @@ static void s5h1409_set_qam_amhum_mode(struct dvb_frontend *fe) reg &= 0xff; s5h1409_writereg(state, 0x96, 0x00c); - if ((reg < 0x38) || (reg > 0x68)) { + if ((reg < 0x38) || (reg > 0x68) ) { s5h1409_writereg(state, 0x93, 0x3332); s5h1409_writereg(state, 0x9e, 0x2c37); } else { @@ -517,7 +514,7 @@ static void s5h1409_set_qam_interleave_mode(struct dvb_frontend *fe) s5h1409_writereg(state, 0x96, 0x20); s5h1409_writereg(state, 0xad, - (((reg1 & 0xf000) >> 4) | (reg2 & 0xf0ff))); + ( ((reg1 & 0xf000) >> 4) | (reg2 & 0xf0ff)) ); s5h1409_writereg(state, 0xab, s5h1409_readreg(state, 0xab) & 0xeffe); } @@ -532,10 +529,10 @@ static void s5h1409_set_qam_interleave_mode(struct dvb_frontend *fe) } /* Talk to the demod, set the FEC, GUARD, QAM settings etc */ -static int s5h1409_set_frontend(struct dvb_frontend *fe, +static int s5h1409_set_frontend (struct dvb_frontend* fe, struct dvb_frontend_parameters *p) { - struct s5h1409_state *state = fe->demodulator_priv; + struct s5h1409_state* state = fe->demodulator_priv; dprintk("%s(frequency=%d)\n", __func__, p->frequency); @@ -549,11 +546,9 @@ static int s5h1409_set_frontend(struct dvb_frontend *fe, msleep(100); if (fe->ops.tuner_ops.set_params) { - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); + if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); fe->ops.tuner_ops.set_params(fe, p); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); + if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); } /* Optimize the demod for QAM */ @@ -597,17 +592,17 @@ static int s5h1409_set_mpeg_timing(struct dvb_frontend *fe, int mode) /* Reset the demod hardware and reset all of the configuration registers to a default state. */ -static int s5h1409_init(struct dvb_frontend *fe) +static int s5h1409_init (struct dvb_frontend* fe) { int i; - struct s5h1409_state *state = fe->demodulator_priv; + struct s5h1409_state* state = fe->demodulator_priv; dprintk("%s()\n", __func__); s5h1409_sleep(fe, 0); s5h1409_register_reset(fe); - for (i = 0; i < ARRAY_SIZE(init_tab); i++) + for (i=0; i < ARRAY_SIZE(init_tab); i++) s5h1409_writereg(state, init_tab[i].reg, init_tab[i].data); /* The datasheet says that after initialisation, VSB is default */ @@ -632,9 +627,9 @@ static int s5h1409_init(struct dvb_frontend *fe) return 0; } -static int s5h1409_read_status(struct dvb_frontend *fe, fe_status_t *status) +static int s5h1409_read_status(struct dvb_frontend* fe, fe_status_t* status) { - struct s5h1409_state *state = fe->demodulator_priv; + struct s5h1409_state* state = fe->demodulator_priv; u16 reg; u32 tuner_status = 0; @@ -642,12 +637,12 @@ static int s5h1409_read_status(struct dvb_frontend *fe, fe_status_t *status) /* Get the demodulator status */ reg = s5h1409_readreg(state, 0xf1); - if (reg & 0x1000) + if(reg & 0x1000) *status |= FE_HAS_VITERBI; - if (reg & 0x8000) + if(reg & 0x8000) *status |= FE_HAS_LOCK | FE_HAS_SYNC; - switch (state->config->status_mode) { + switch(state->config->status_mode) { case S5H1409_DEMODLOCKING: if (*status & FE_HAS_VITERBI) *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL; @@ -673,12 +668,12 @@ static int s5h1409_read_status(struct dvb_frontend *fe, fe_status_t *status) return 0; } -static int s5h1409_qam256_lookup_snr(struct dvb_frontend *fe, u16 *snr, u16 v) +static int s5h1409_qam256_lookup_snr(struct dvb_frontend* fe, u16* snr, u16 v) { int i, ret = -EINVAL; dprintk("%s()\n", __func__); - for (i = 0; i < ARRAY_SIZE(qam256_snr_tab); i++) { + for (i=0; i < ARRAY_SIZE(qam256_snr_tab); i++) { if (v < qam256_snr_tab[i].val) { *snr = qam256_snr_tab[i].data; ret = 0; @@ -688,12 +683,12 @@ static int s5h1409_qam256_lookup_snr(struct dvb_frontend *fe, u16 *snr, u16 v) return ret; } -static int s5h1409_qam64_lookup_snr(struct dvb_frontend *fe, u16 *snr, u16 v) +static int s5h1409_qam64_lookup_snr(struct dvb_frontend* fe, u16* snr, u16 v) { int i, ret = -EINVAL; dprintk("%s()\n", __func__); - for (i = 0; i < ARRAY_SIZE(qam64_snr_tab); i++) { + for (i=0; i < ARRAY_SIZE(qam64_snr_tab); i++) { if (v < qam64_snr_tab[i].val) { *snr = qam64_snr_tab[i].data; ret = 0; @@ -703,12 +698,12 @@ static int s5h1409_qam64_lookup_snr(struct dvb_frontend *fe, u16 *snr, u16 v) return ret; } -static int s5h1409_vsb_lookup_snr(struct dvb_frontend *fe, u16 *snr, u16 v) +static int s5h1409_vsb_lookup_snr(struct dvb_frontend* fe, u16* snr, u16 v) { int i, ret = -EINVAL; dprintk("%s()\n", __func__); - for (i = 0; i < ARRAY_SIZE(vsb_snr_tab); i++) { + for (i=0; i < ARRAY_SIZE(vsb_snr_tab); i++) { if (v > vsb_snr_tab[i].val) { *snr = vsb_snr_tab[i].data; ret = 0; @@ -719,13 +714,13 @@ static int s5h1409_vsb_lookup_snr(struct dvb_frontend *fe, u16 *snr, u16 v) return ret; } -static int s5h1409_read_snr(struct dvb_frontend *fe, u16 *snr) +static int s5h1409_read_snr(struct dvb_frontend* fe, u16* snr) { - struct s5h1409_state *state = fe->demodulator_priv; + struct s5h1409_state* state = fe->demodulator_priv; u16 reg; dprintk("%s()\n", __func__); - switch (state->current_modulation) { + switch(state->current_modulation) { case QAM_64: reg = s5h1409_readreg(state, 0xf0) & 0xff; return s5h1409_qam64_lookup_snr(fe, snr, reg); @@ -742,30 +737,30 @@ static int s5h1409_read_snr(struct dvb_frontend *fe, u16 *snr) return -EINVAL; } -static int s5h1409_read_signal_strength(struct dvb_frontend *fe, - u16 *signal_strength) +static int s5h1409_read_signal_strength(struct dvb_frontend* fe, + u16* signal_strength) { return s5h1409_read_snr(fe, signal_strength); } -static int s5h1409_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) +static int s5h1409_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) { - struct s5h1409_state *state = fe->demodulator_priv; + struct s5h1409_state* state = fe->demodulator_priv; *ucblocks = s5h1409_readreg(state, 0xb5); return 0; } -static int s5h1409_read_ber(struct dvb_frontend *fe, u32 *ber) +static int s5h1409_read_ber(struct dvb_frontend* fe, u32* ber) { return s5h1409_read_ucblocks(fe, ber); } -static int s5h1409_get_frontend(struct dvb_frontend *fe, +static int s5h1409_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) { - struct s5h1409_state *state = fe->demodulator_priv; + struct s5h1409_state* state = fe->demodulator_priv; p->frequency = state->current_frequency; p->u.vsb.modulation = state->current_modulation; @@ -773,25 +768,25 @@ static int s5h1409_get_frontend(struct dvb_frontend *fe, return 0; } -static int s5h1409_get_tune_settings(struct dvb_frontend *fe, +static int s5h1409_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune) { tune->min_delay_ms = 1000; return 0; } -static void s5h1409_release(struct dvb_frontend *fe) +static void s5h1409_release(struct dvb_frontend* fe) { - struct s5h1409_state *state = fe->demodulator_priv; + struct s5h1409_state* state = fe->demodulator_priv; kfree(state); } static struct dvb_frontend_ops s5h1409_ops; -struct dvb_frontend *s5h1409_attach(const struct s5h1409_config *config, - struct i2c_adapter *i2c) +struct dvb_frontend* s5h1409_attach(const struct s5h1409_config* config, + struct i2c_adapter* i2c) { - struct s5h1409_state *state = NULL; + struct s5h1409_state* state = NULL; u16 reg; /* allocate memory for the internal state */ @@ -830,7 +825,6 @@ struct dvb_frontend *s5h1409_attach(const struct s5h1409_config *config, kfree(state); return NULL; } -EXPORT_SYMBOL(s5h1409_attach); static struct dvb_frontend_ops s5h1409_ops = { @@ -856,10 +850,14 @@ static struct dvb_frontend_ops s5h1409_ops = { .release = s5h1409_release, }; +module_param(debug, int, 0644); +MODULE_PARM_DESC(debug, "Enable verbose debug messages"); + MODULE_DESCRIPTION("Samsung S5H1409 QAM-B/ATSC Demodulator driver"); MODULE_AUTHOR("Steven Toth"); MODULE_LICENSE("GPL"); +EXPORT_SYMBOL(s5h1409_attach); /* * Local variables: diff --git a/trunk/drivers/media/dvb/frontends/s5h1409.h b/trunk/drivers/media/dvb/frontends/s5h1409.h index 070d9743e330..d1a1d2eb8e11 100644 --- a/trunk/drivers/media/dvb/frontends/s5h1409.h +++ b/trunk/drivers/media/dvb/frontends/s5h1409.h @@ -24,7 +24,8 @@ #include -struct s5h1409_config { +struct s5h1409_config +{ /* the demodulator's i2c address */ u8 demod_address; @@ -59,14 +60,12 @@ struct s5h1409_config { u16 mpeg_timing; }; -#if defined(CONFIG_DVB_S5H1409) || (defined(CONFIG_DVB_S5H1409_MODULE) \ - && defined(MODULE)) -extern struct dvb_frontend *s5h1409_attach(const struct s5h1409_config *config, - struct i2c_adapter *i2c); +#if defined(CONFIG_DVB_S5H1409) || (defined(CONFIG_DVB_S5H1409_MODULE) && defined(MODULE)) +extern struct dvb_frontend* s5h1409_attach(const struct s5h1409_config* config, + struct i2c_adapter* i2c); #else -static inline struct dvb_frontend *s5h1409_attach( - const struct s5h1409_config *config, - struct i2c_adapter *i2c) +static inline struct dvb_frontend* s5h1409_attach(const struct s5h1409_config* config, + struct i2c_adapter* i2c) { printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; diff --git a/trunk/drivers/media/dvb/frontends/s5h1411.c b/trunk/drivers/media/dvb/frontends/s5h1411.c index 2febfb5a846b..2da1a3763de9 100644 --- a/trunk/drivers/media/dvb/frontends/s5h1411.c +++ b/trunk/drivers/media/dvb/frontends/s5h1411.c @@ -343,7 +343,7 @@ static int s5h1411_writereg(struct s5h1411_state *state, u8 addr, u8 reg, u16 data) { int ret; - u8 buf[] = { reg, data >> 8, data & 0xff }; + u8 buf [] = { reg, data >> 8, data & 0xff }; struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = buf, .len = 3 }; @@ -359,10 +359,10 @@ static int s5h1411_writereg(struct s5h1411_state *state, static u16 s5h1411_readreg(struct s5h1411_state *state, u8 addr, u8 reg) { int ret; - u8 b0[] = { reg }; - u8 b1[] = { 0, 0 }; + u8 b0 [] = { reg }; + u8 b1 [] = { 0, 0 }; - struct i2c_msg msg[] = { + struct i2c_msg msg [] = { { .addr = addr, .flags = 0, .buf = b0, .len = 1 }, { .addr = addr, .flags = I2C_M_RD, .buf = b1, .len = 2 } }; diff --git a/trunk/drivers/media/dvb/frontends/tda10048.c b/trunk/drivers/media/dvb/frontends/tda10048.c index 2a8bbcd44cd0..04e7f1cc1403 100644 --- a/trunk/drivers/media/dvb/frontends/tda10048.c +++ b/trunk/drivers/media/dvb/frontends/tda10048.c @@ -195,7 +195,7 @@ static struct init_tab { static int tda10048_writereg(struct tda10048_state *state, u8 reg, u8 data) { int ret; - u8 buf[] = { reg, data }; + u8 buf [] = { reg, data }; struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 }; @@ -213,9 +213,9 @@ static int tda10048_writereg(struct tda10048_state *state, u8 reg, u8 data) static u8 tda10048_readreg(struct tda10048_state *state, u8 reg) { int ret; - u8 b0[] = { reg }; - u8 b1[] = { 0 }; - struct i2c_msg msg[] = { + u8 b0 [] = { reg }; + u8 b1 [] = { 0 }; + struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 }, { .addr = state->config->demod_address, @@ -393,89 +393,43 @@ static int tda10048_get_tps(struct tda10048_state *state, val = tda10048_readreg(state, TDA10048_OUT_CONF2); switch ((val & 0x60) >> 5) { - case 0: - p->constellation = QPSK; - break; - case 1: - p->constellation = QAM_16; - break; - case 2: - p->constellation = QAM_64; - break; + case 0: p->constellation = QPSK; break; + case 1: p->constellation = QAM_16; break; + case 2: p->constellation = QAM_64; break; } switch ((val & 0x18) >> 3) { - case 0: - p->hierarchy_information = HIERARCHY_NONE; - break; - case 1: - p->hierarchy_information = HIERARCHY_1; - break; - case 2: - p->hierarchy_information = HIERARCHY_2; - break; - case 3: - p->hierarchy_information = HIERARCHY_4; - break; + case 0: p->hierarchy_information = HIERARCHY_NONE; break; + case 1: p->hierarchy_information = HIERARCHY_1; break; + case 2: p->hierarchy_information = HIERARCHY_2; break; + case 3: p->hierarchy_information = HIERARCHY_4; break; } switch (val & 0x07) { - case 0: - p->code_rate_HP = FEC_1_2; - break; - case 1: - p->code_rate_HP = FEC_2_3; - break; - case 2: - p->code_rate_HP = FEC_3_4; - break; - case 3: - p->code_rate_HP = FEC_5_6; - break; - case 4: - p->code_rate_HP = FEC_7_8; - break; + case 0: p->code_rate_HP = FEC_1_2; break; + case 1: p->code_rate_HP = FEC_2_3; break; + case 2: p->code_rate_HP = FEC_3_4; break; + case 3: p->code_rate_HP = FEC_5_6; break; + case 4: p->code_rate_HP = FEC_7_8; break; } val = tda10048_readreg(state, TDA10048_OUT_CONF3); switch (val & 0x07) { - case 0: - p->code_rate_LP = FEC_1_2; - break; - case 1: - p->code_rate_LP = FEC_2_3; - break; - case 2: - p->code_rate_LP = FEC_3_4; - break; - case 3: - p->code_rate_LP = FEC_5_6; - break; - case 4: - p->code_rate_LP = FEC_7_8; - break; + case 0: p->code_rate_LP = FEC_1_2; break; + case 1: p->code_rate_LP = FEC_2_3; break; + case 2: p->code_rate_LP = FEC_3_4; break; + case 3: p->code_rate_LP = FEC_5_6; break; + case 4: p->code_rate_LP = FEC_7_8; break; } val = tda10048_readreg(state, TDA10048_OUT_CONF1); switch ((val & 0x0c) >> 2) { - case 0: - p->guard_interval = GUARD_INTERVAL_1_32; - break; - case 1: - p->guard_interval = GUARD_INTERVAL_1_16; - break; - case 2: - p->guard_interval = GUARD_INTERVAL_1_8; - break; - case 3: - p->guard_interval = GUARD_INTERVAL_1_4; - break; + case 0: p->guard_interval = GUARD_INTERVAL_1_32; break; + case 1: p->guard_interval = GUARD_INTERVAL_1_16; break; + case 2: p->guard_interval = GUARD_INTERVAL_1_8; break; + case 3: p->guard_interval = GUARD_INTERVAL_1_4; break; } switch (val & 0x02) { - case 0: - p->transmission_mode = TRANSMISSION_MODE_2K; - break; - case 1: - p->transmission_mode = TRANSMISSION_MODE_8K; - break; + case 0: p->transmission_mode = TRANSMISSION_MODE_2K; break; + case 1: p->transmission_mode = TRANSMISSION_MODE_8K; break; } return 0; diff --git a/trunk/drivers/media/dvb/frontends/z0194a.h b/trunk/drivers/media/dvb/frontends/z0194a.h index 07f3fc0998f6..d2876d2e1769 100644 --- a/trunk/drivers/media/dvb/frontends/z0194a.h +++ b/trunk/drivers/media/dvb/frontends/z0194a.h @@ -12,7 +12,7 @@ #ifndef Z0194A #define Z0194A -static int sharp_z0194a_set_symbol_rate(struct dvb_frontend *fe, +static int sharp_z0194a__set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ratio) { u8 aclk = 0; @@ -40,7 +40,7 @@ static int sharp_z0194a_set_symbol_rate(struct dvb_frontend *fe, return 0; } -static u8 sharp_z0194a_inittab[] = { +static u8 sharp_z0194a__inittab[] = { 0x01, 0x15, 0x02, 0x00, 0x03, 0x00, @@ -82,4 +82,16 @@ static u8 sharp_z0194a_inittab[] = { 0xff, 0xff }; +static struct stv0299_config sharp_z0194a_config = { + .demod_address = 0x68, + .inittab = sharp_z0194a__inittab, + .mclk = 88000000UL, + .invert = 1, + .skip_reinit = 0, + .lock_output = STV0299_LOCKOUTPUT_1, + .volt13_op0_op1 = STV0299_VOLT13_OP1, + .min_delay_ms = 100, + .set_symbol_rate = sharp_z0194a__set_symbol_rate, +}; + #endif diff --git a/trunk/drivers/media/dvb/siano/sms-cards.c b/trunk/drivers/media/dvb/siano/sms-cards.c index 6f9b77360440..9da260fe3fd1 100644 --- a/trunk/drivers/media/dvb/siano/sms-cards.c +++ b/trunk/drivers/media/dvb/siano/sms-cards.c @@ -42,10 +42,6 @@ struct usb_device_id smsusb_id_table[] = { .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, { USB_DEVICE(0x2040, 0x5510), .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, - { USB_DEVICE(0x2040, 0x5520), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, - { USB_DEVICE(0x2040, 0x5530), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, { USB_DEVICE(0x2040, 0x5580), .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, { USB_DEVICE(0x2040, 0x5590), diff --git a/trunk/drivers/media/radio/Kconfig b/trunk/drivers/media/radio/Kconfig index 04cd7c04bdde..e51d707e58d3 100644 --- a/trunk/drivers/media/radio/Kconfig +++ b/trunk/drivers/media/radio/Kconfig @@ -359,7 +359,7 @@ config USB_SI470X computer's USB port. To compile this driver as a module, choose M here: the - module will be called radio-si470x. + module will be called radio-silabs. config USB_MR800 tristate "AverMedia MR 800 USB FM radio support" diff --git a/trunk/drivers/media/radio/radio-si470x.c b/trunk/drivers/media/radio/radio-si470x.c index 5920cd306975..f6cedcd3ab97 100644 --- a/trunk/drivers/media/radio/radio-si470x.c +++ b/trunk/drivers/media/radio/radio-si470x.c @@ -104,7 +104,6 @@ * - hardware frequency seek support * - afc indication * - more safety checks, let si470x_get_freq return errno - * - vidioc behavior corrected according to v4l2 spec * * ToDo: * - add firmware download/update support @@ -142,9 +141,9 @@ /* USB Device ID List */ static struct usb_device_id si470x_usb_driver_id_table[] = { /* Silicon Labs USB FM Radio Reference Design */ - { USB_DEVICE_AND_INTERFACE_INFO(0x10c4, 0x818a, USB_CLASS_HID, 0, 0) }, + { USB_DEVICE_AND_INTERFACE_INFO(0x10c4, 0x818a, USB_CLASS_HID, 0, 0) }, /* ADS/Tech FM Radio Receiver (formerly Instant FM Music) */ - { USB_DEVICE_AND_INTERFACE_INFO(0x06e1, 0xa155, USB_CLASS_HID, 0, 0) }, + { USB_DEVICE_AND_INTERFACE_INFO(0x06e1, 0xa155, USB_CLASS_HID, 0, 0) }, /* Terminating entry */ { } }; @@ -158,7 +157,7 @@ MODULE_DEVICE_TABLE(usb, si470x_usb_driver_id_table); /* Radio Nr */ static int radio_nr = -1; -module_param(radio_nr, int, 0444); +module_param(radio_nr, int, 0); MODULE_PARM_DESC(radio_nr, "Radio Nr"); /* Spacing (kHz) */ @@ -166,42 +165,42 @@ MODULE_PARM_DESC(radio_nr, "Radio Nr"); /* 1: 100 kHz (Europe, Japan) */ /* 2: 50 kHz */ static unsigned short space = 2; -module_param(space, ushort, 0444); -MODULE_PARM_DESC(space, "Spacing: 0=200kHz 1=100kHz *2=50kHz*"); +module_param(space, ushort, 0); +MODULE_PARM_DESC(radio_nr, "Spacing: 0=200kHz 1=100kHz *2=50kHz*"); /* Bottom of Band (MHz) */ /* 0: 87.5 - 108 MHz (USA, Europe)*/ /* 1: 76 - 108 MHz (Japan wide band) */ /* 2: 76 - 90 MHz (Japan) */ static unsigned short band = 1; -module_param(band, ushort, 0444); -MODULE_PARM_DESC(band, "Band: 0=87.5..108MHz *1=76..108MHz* 2=76..90MHz"); +module_param(band, ushort, 0); +MODULE_PARM_DESC(radio_nr, "Band: 0=87.5..108MHz *1=76..108MHz* 2=76..90MHz"); /* De-emphasis */ /* 0: 75 us (USA) */ /* 1: 50 us (Europe, Australia, Japan) */ static unsigned short de = 1; -module_param(de, ushort, 0444); -MODULE_PARM_DESC(de, "De-emphasis: 0=75us *1=50us*"); +module_param(de, ushort, 0); +MODULE_PARM_DESC(radio_nr, "De-emphasis: 0=75us *1=50us*"); /* USB timeout */ static unsigned int usb_timeout = 500; -module_param(usb_timeout, uint, 0644); +module_param(usb_timeout, uint, 0); MODULE_PARM_DESC(usb_timeout, "USB timeout (ms): *500*"); /* Tune timeout */ static unsigned int tune_timeout = 3000; -module_param(tune_timeout, uint, 0644); +module_param(tune_timeout, uint, 0); MODULE_PARM_DESC(tune_timeout, "Tune timeout: *3000*"); /* Seek timeout */ static unsigned int seek_timeout = 5000; -module_param(seek_timeout, uint, 0644); +module_param(seek_timeout, uint, 0); MODULE_PARM_DESC(seek_timeout, "Seek timeout: *5000*"); /* RDS buffer blocks */ static unsigned int rds_buf = 100; -module_param(rds_buf, uint, 0444); +module_param(rds_buf, uint, 0); MODULE_PARM_DESC(rds_buf, "RDS buffer entries: *100*"); /* RDS maximum block errors */ @@ -210,7 +209,7 @@ static unsigned short max_rds_errors = 1; /* 1 means 1-2 errors requiring correction (used by original USBRadio.exe) */ /* 2 means 3-5 errors requiring correction */ /* 3 means 6+ errors or errors in checkword, correction not possible */ -module_param(max_rds_errors, ushort, 0644); +module_param(max_rds_errors, ushort, 0); MODULE_PARM_DESC(max_rds_errors, "RDS maximum block errors: *1*"); /* RDS poll frequency */ @@ -219,7 +218,7 @@ static unsigned int rds_poll_time = 40; /* 50 is used by radio-cadet */ /* 75 should be okay */ /* 80 is the usual RDS receive interval */ -module_param(rds_poll_time, uint, 0644); +module_param(rds_poll_time, uint, 0); MODULE_PARM_DESC(rds_poll_time, "RDS poll time (ms): *40*"); @@ -668,29 +667,23 @@ static int si470x_get_freq(struct si470x_device *radio, unsigned int *freq) int retval; /* Spacing (kHz) */ - switch ((radio->registers[SYSCONFIG2] & SYSCONFIG2_SPACE) >> 4) { + switch (space) { /* 0: 200 kHz (USA, Australia) */ - case 0: - spacing = 0.200 * FREQ_MUL; break; + case 0 : spacing = 0.200 * FREQ_MUL; break; /* 1: 100 kHz (Europe, Japan) */ - case 1: - spacing = 0.100 * FREQ_MUL; break; + case 1 : spacing = 0.100 * FREQ_MUL; break; /* 2: 50 kHz */ - default: - spacing = 0.050 * FREQ_MUL; break; + default: spacing = 0.050 * FREQ_MUL; break; }; /* Bottom of Band (MHz) */ - switch ((radio->registers[SYSCONFIG2] & SYSCONFIG2_BAND) >> 6) { + switch (band) { /* 0: 87.5 - 108 MHz (USA, Europe) */ - case 0: - band_bottom = 87.5 * FREQ_MUL; break; + case 0 : band_bottom = 87.5 * FREQ_MUL; break; /* 1: 76 - 108 MHz (Japan wide band) */ - default: - band_bottom = 76 * FREQ_MUL; break; + default: band_bottom = 76 * FREQ_MUL; break; /* 2: 76 - 90 MHz (Japan) */ - case 2: - band_bottom = 76 * FREQ_MUL; break; + case 2 : band_bottom = 76 * FREQ_MUL; break; }; /* read channel */ @@ -713,29 +706,23 @@ static int si470x_set_freq(struct si470x_device *radio, unsigned int freq) unsigned short chan; /* Spacing (kHz) */ - switch ((radio->registers[SYSCONFIG2] & SYSCONFIG2_SPACE) >> 4) { + switch (space) { /* 0: 200 kHz (USA, Australia) */ - case 0: - spacing = 0.200 * FREQ_MUL; break; + case 0 : spacing = 0.200 * FREQ_MUL; break; /* 1: 100 kHz (Europe, Japan) */ - case 1: - spacing = 0.100 * FREQ_MUL; break; + case 1 : spacing = 0.100 * FREQ_MUL; break; /* 2: 50 kHz */ - default: - spacing = 0.050 * FREQ_MUL; break; + default: spacing = 0.050 * FREQ_MUL; break; }; /* Bottom of Band (MHz) */ - switch ((radio->registers[SYSCONFIG2] & SYSCONFIG2_BAND) >> 6) { + switch (band) { /* 0: 87.5 - 108 MHz (USA, Europe) */ - case 0: - band_bottom = 87.5 * FREQ_MUL; break; + case 0 : band_bottom = 87.5 * FREQ_MUL; break; /* 1: 76 - 108 MHz (Japan wide band) */ - default: - band_bottom = 76 * FREQ_MUL; break; + default: band_bottom = 76 * FREQ_MUL; break; /* 2: 76 - 90 MHz (Japan) */ - case 2: - band_bottom = 76 * FREQ_MUL; break; + case 2 : band_bottom = 76 * FREQ_MUL; break; }; /* Chan = [ Freq (Mhz) - Bottom of Band (MHz) ] / Spacing (kHz) */ @@ -1177,6 +1164,7 @@ static const struct file_operations si470x_fops = { * si470x_v4l2_queryctrl - query control */ static struct v4l2_queryctrl si470x_v4l2_queryctrl[] = { +/* HINT: the disabled controls are only here to satify kradio and such apps */ { .id = V4L2_CID_AUDIO_VOLUME, .type = V4L2_CTRL_TYPE_INTEGER, @@ -1186,6 +1174,18 @@ static struct v4l2_queryctrl si470x_v4l2_queryctrl[] = { .step = 1, .default_value = 15, }, + { + .id = V4L2_CID_AUDIO_BALANCE, + .flags = V4L2_CTRL_FLAG_DISABLED, + }, + { + .id = V4L2_CID_AUDIO_BASS, + .flags = V4L2_CTRL_FLAG_DISABLED, + }, + { + .id = V4L2_CID_AUDIO_TREBLE, + .flags = V4L2_CTRL_FLAG_DISABLED, + }, { .id = V4L2_CID_AUDIO_MUTE, .type = V4L2_CTRL_TYPE_BOOLEAN, @@ -1195,6 +1195,10 @@ static struct v4l2_queryctrl si470x_v4l2_queryctrl[] = { .step = 1, .default_value = 1, }, + { + .id = V4L2_CID_AUDIO_LOUDNESS, + .flags = V4L2_CTRL_FLAG_DISABLED, + }, }; @@ -1215,35 +1219,57 @@ static int si470x_vidioc_querycap(struct file *file, void *priv, } +/* + * si470x_vidioc_g_input - get input + */ +static int si470x_vidioc_g_input(struct file *file, void *priv, + unsigned int *i) +{ + *i = 0; + + return 0; +} + + +/* + * si470x_vidioc_s_input - set input + */ +static int si470x_vidioc_s_input(struct file *file, void *priv, unsigned int i) +{ + int retval = 0; + + /* safety checks */ + if (i != 0) + retval = -EINVAL; + + if (retval < 0) + printk(KERN_WARNING DRIVER_NAME + ": set input failed with %d\n", retval); + return retval; +} + + /* * si470x_vidioc_queryctrl - enumerate control items */ static int si470x_vidioc_queryctrl(struct file *file, void *priv, struct v4l2_queryctrl *qc) { - unsigned char i = 0; + unsigned char i; int retval = -EINVAL; - /* abort if qc->id is below V4L2_CID_BASE */ - if (qc->id < V4L2_CID_BASE) + /* safety checks */ + if (!qc->id) goto done; - /* search video control */ for (i = 0; i < ARRAY_SIZE(si470x_v4l2_queryctrl); i++) { if (qc->id == si470x_v4l2_queryctrl[i].id) { memcpy(qc, &(si470x_v4l2_queryctrl[i]), sizeof(*qc)); - retval = 0; /* found */ + retval = 0; break; } } - /* disable unsupported base controls */ - /* to satisfy kradio and such apps */ - if ((retval == -EINVAL) && (qc->id < V4L2_CID_LASTP1)) { - qc->flags = V4L2_CTRL_FLAG_DISABLED; - retval = 0; - } - done: if (retval < 0) printk(KERN_WARNING DRIVER_NAME @@ -1334,13 +1360,44 @@ static int si470x_vidioc_s_ctrl(struct file *file, void *priv, static int si470x_vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *audio) { - /* driver constants */ - audio->index = 0; + int retval = 0; + + /* safety checks */ + if (audio->index != 0) { + retval = -EINVAL; + goto done; + } + strcpy(audio->name, "Radio"); audio->capability = V4L2_AUDCAP_STEREO; - audio->mode = 0; - return 0; +done: + if (retval < 0) + printk(KERN_WARNING DRIVER_NAME + ": get audio failed with %d\n", retval); + return retval; +} + + +/* + * si470x_vidioc_s_audio - set audio attributes + */ +static int si470x_vidioc_s_audio(struct file *file, void *priv, + struct v4l2_audio *audio) +{ + int retval = 0; + + /* safety checks */ + if (audio->index != 0) { + retval = -EINVAL; + goto done; + } + +done: + if (retval < 0) + printk(KERN_WARNING DRIVER_NAME + ": set audio failed with %d\n", retval); + return retval; } @@ -1358,7 +1415,7 @@ static int si470x_vidioc_g_tuner(struct file *file, void *priv, retval = -EIO; goto done; } - if (tuner->index != 0) { + if ((tuner->index != 0) && (tuner->type != V4L2_TUNER_RADIO)) { retval = -EINVAL; goto done; } @@ -1367,13 +1424,8 @@ static int si470x_vidioc_g_tuner(struct file *file, void *priv, if (retval < 0) goto done; - /* driver constants */ strcpy(tuner->name, "FM"); - tuner->type = V4L2_TUNER_RADIO; - tuner->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO; - - /* range limits */ - switch ((radio->registers[SYSCONFIG2] & SYSCONFIG2_BAND) >> 6) { + switch (band) { /* 0: 87.5 - 108 MHz (USA, Europe, default) */ default: tuner->rangelow = 87.5 * FREQ_MUL; @@ -1390,18 +1442,14 @@ static int si470x_vidioc_g_tuner(struct file *file, void *priv, tuner->rangehigh = 90 * FREQ_MUL; break; }; + tuner->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; + tuner->capability = V4L2_TUNER_CAP_LOW; - /* stereo indicator == stereo (instead of mono) */ + /* Stereo indicator == Stereo (instead of Mono) */ if ((radio->registers[STATUSRSSI] & STATUSRSSI_ST) == 1) - tuner->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; + tuner->audmode = V4L2_TUNER_MODE_STEREO; else - tuner->rxsubchans = V4L2_TUNER_SUB_MONO; - - /* mono/stereo selector */ - if ((radio->registers[POWERCFG] & POWERCFG_MONO) == 1) tuner->audmode = V4L2_TUNER_MODE_MONO; - else - tuner->audmode = V4L2_TUNER_MODE_STEREO; /* min is worst, max is best; signal:0..0xffff; rssi: 0..0xff */ tuner->signal = (radio->registers[STATUSRSSI] & STATUSRSSI_RSSI) @@ -1426,27 +1474,22 @@ static int si470x_vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *tuner) { struct si470x_device *radio = video_drvdata(file); - int retval = -EINVAL; + int retval = 0; /* safety checks */ if (radio->disconnected) { retval = -EIO; goto done; } - if (tuner->index != 0) + if ((tuner->index != 0) && (tuner->type != V4L2_TUNER_RADIO)) { + retval = -EINVAL; goto done; + } - /* mono/stereo selector */ - switch (tuner->audmode) { - case V4L2_TUNER_MODE_MONO: + if (tuner->audmode == V4L2_TUNER_MODE_MONO) radio->registers[POWERCFG] |= POWERCFG_MONO; /* force mono */ - break; - case V4L2_TUNER_MODE_STEREO: + else radio->registers[POWERCFG] &= ~POWERCFG_MONO; /* try stereo */ - break; - default: - goto done; - } retval = si470x_set_register(radio, POWERCFG); @@ -1472,12 +1515,11 @@ static int si470x_vidioc_g_frequency(struct file *file, void *priv, retval = -EIO; goto done; } - if (freq->tuner != 0) { + if ((freq->tuner != 0) && (freq->type != V4L2_TUNER_RADIO)) { retval = -EINVAL; goto done; } - freq->type = V4L2_TUNER_RADIO; retval = si470x_get_freq(radio, &freq->frequency); done: @@ -1502,7 +1544,7 @@ static int si470x_vidioc_s_frequency(struct file *file, void *priv, retval = -EIO; goto done; } - if (freq->tuner != 0) { + if ((freq->tuner != 0) && (freq->type != V4L2_TUNER_RADIO)) { retval = -EINVAL; goto done; } @@ -1531,7 +1573,7 @@ static int si470x_vidioc_s_hw_freq_seek(struct file *file, void *priv, retval = -EIO; goto done; } - if (seek->tuner != 0) { + if ((seek->tuner != 0) && (seek->type != V4L2_TUNER_RADIO)) { retval = -EINVAL; goto done; } @@ -1546,16 +1588,15 @@ static int si470x_vidioc_s_hw_freq_seek(struct file *file, void *priv, return retval; } - -/* - * si470x_ioctl_ops - video device ioctl operations - */ static const struct v4l2_ioctl_ops si470x_ioctl_ops = { .vidioc_querycap = si470x_vidioc_querycap, + .vidioc_g_input = si470x_vidioc_g_input, + .vidioc_s_input = si470x_vidioc_s_input, .vidioc_queryctrl = si470x_vidioc_queryctrl, .vidioc_g_ctrl = si470x_vidioc_g_ctrl, .vidioc_s_ctrl = si470x_vidioc_s_ctrl, .vidioc_g_audio = si470x_vidioc_g_audio, + .vidioc_s_audio = si470x_vidioc_s_audio, .vidioc_g_tuner = si470x_vidioc_g_tuner, .vidioc_s_tuner = si470x_vidioc_s_tuner, .vidioc_g_frequency = si470x_vidioc_g_frequency, @@ -1563,15 +1604,14 @@ static const struct v4l2_ioctl_ops si470x_ioctl_ops = { .vidioc_s_hw_freq_seek = si470x_vidioc_s_hw_freq_seek, }; - /* - * si470x_viddev_template - video device interface + * si470x_viddev_tamples - video device interface */ static struct video_device si470x_viddev_template = { .fops = &si470x_fops, + .ioctl_ops = &si470x_ioctl_ops, .name = DRIVER_NAME, .release = video_device_release, - .ioctl_ops = &si470x_ioctl_ops, }; diff --git a/trunk/drivers/media/video/adv7170.c b/trunk/drivers/media/video/adv7170.c index e0eb4f321442..f794f2dbfb32 100644 --- a/trunk/drivers/media/video/adv7170.c +++ b/trunk/drivers/media/video/adv7170.c @@ -29,24 +29,43 @@ */ #include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include -#include -#include #include -#include +#include +#include +#include +#include + #include #include -#include -#include MODULE_DESCRIPTION("Analog Devices ADV7170 video encoder driver"); MODULE_AUTHOR("Maxim Yevtyushkin"); MODULE_LICENSE("GPL"); + +#define I2C_NAME(x) (x)->name + + static int debug; module_param(debug, int, 0); MODULE_PARM_DESC(debug, "Debug level (0-1)"); +#define dprintk(num, format, args...) \ + do { \ + if (debug >= num) \ + printk(format, ##args); \ + } while (0) + /* ----------------------------------------------------------------------- */ struct adv7170 { @@ -61,12 +80,21 @@ struct adv7170 { int sat; }; +#define I2C_ADV7170 0xd4 +#define I2C_ADV7171 0x54 + +static char adv7170_name[] = "adv7170"; +static char adv7171_name[] = "adv7171"; + static char *inputs[] = { "pass_through", "play_back" }; static char *norms[] = { "PAL", "NTSC" }; /* ----------------------------------------------------------------------- */ -static inline int adv7170_write(struct i2c_client *client, u8 reg, u8 value) +static inline int +adv7170_write (struct i2c_client *client, + u8 reg, + u8 value) { struct adv7170 *encoder = i2c_get_clientdata(client); @@ -74,13 +102,17 @@ static inline int adv7170_write(struct i2c_client *client, u8 reg, u8 value) return i2c_smbus_write_byte_data(client, reg, value); } -static inline int adv7170_read(struct i2c_client *client, u8 reg) +static inline int +adv7170_read (struct i2c_client *client, + u8 reg) { return i2c_smbus_read_byte_data(client, reg); } -static int adv7170_write_block(struct i2c_client *client, - const u8 *data, unsigned int len) +static int +adv7170_write_block (struct i2c_client *client, + const u8 *data, + unsigned int len) { int ret = -1; u8 reg; @@ -101,25 +133,33 @@ static int adv7170_write_block(struct i2c_client *client, encoder->reg[reg++] = data[1]; len -= 2; data += 2; - } while (len >= 2 && data[0] == reg && block_len < 32); - ret = i2c_master_send(client, block_data, block_len); - if (ret < 0) + } while (len >= 2 && data[0] == reg && + block_len < 32); + if ((ret = i2c_master_send(client, block_data, + block_len)) < 0) break; } } else { /* do some slow I2C emulation kind of thing */ while (len >= 2) { reg = *data++; - ret = adv7170_write(client, reg, *data++); - if (ret < 0) + if ((ret = adv7170_write(client, reg, + *data++)) < 0) break; len -= 2; } } + return ret; } /* ----------------------------------------------------------------------- */ +// Output filter: S-Video Composite + +#define MR050 0x11 //0x09 +#define MR060 0x14 //0x0c + +//--------------------------------------------------------------------------- #define TR0MODE 0x4c #define TR0RST 0x80 @@ -127,6 +167,7 @@ static int adv7170_write_block(struct i2c_client *client, #define TR1CAPT 0x00 #define TR1PLAY 0x00 + static const unsigned char init_NTSC[] = { 0x00, 0x10, // MR0 0x01, 0x20, // MR1 @@ -186,11 +227,15 @@ static const unsigned char init_PAL[] = { }; -static int adv7170_command(struct i2c_client *client, unsigned cmd, void *arg) +static int +adv7170_command (struct i2c_client *client, + unsigned int cmd, + void * arg) { struct adv7170 *encoder = i2c_get_clientdata(client); switch (cmd) { + case 0: #if 0 /* This is just for testing!!! */ @@ -209,16 +254,18 @@ static int adv7170_command(struct i2c_client *client, unsigned cmd, void *arg) VIDEO_ENCODER_NTSC; cap->inputs = 2; cap->outputs = 1; - break; } + break; case ENCODER_SET_NORM: { int iarg = *(int *) arg; - v4l_dbg(1, debug, client, "set norm %d\n", iarg); + dprintk(1, KERN_DEBUG "%s_command: set norm %d", + I2C_NAME(client), iarg); switch (iarg) { + case VIDEO_MODE_NTSC: adv7170_write_block(client, init_NTSC, sizeof(init_NTSC)); @@ -238,13 +285,16 @@ static int adv7170_command(struct i2c_client *client, unsigned cmd, void *arg) break; default: - v4l_dbg(1, debug, client, "illegal norm: %d\n", iarg); + dprintk(1, KERN_ERR "%s: illegal norm: %d\n", + I2C_NAME(client), iarg); return -EINVAL; + } - v4l_dbg(1, debug, client, "switched to %s\n", norms[iarg]); + dprintk(1, KERN_DEBUG "%s: switched to %s\n", I2C_NAME(client), + norms[iarg]); encoder->norm = iarg; - break; } + break; case ENCODER_SET_INPUT: { @@ -254,17 +304,19 @@ static int adv7170_command(struct i2c_client *client, unsigned cmd, void *arg) *iarg = 1: input is from ZR36060 *iarg = 2: color bar */ - v4l_dbg(1, debug, client, "set input from %s\n", + dprintk(1, KERN_DEBUG "%s_command: set input from %s\n", + I2C_NAME(client), iarg == 0 ? "decoder" : "ZR36060"); switch (iarg) { + case 0: adv7170_write(client, 0x01, 0x20); adv7170_write(client, 0x08, TR1CAPT); /* TR1 */ adv7170_write(client, 0x02, 0x0e); // Enable genlock adv7170_write(client, 0x07, TR0MODE | TR0RST); adv7170_write(client, 0x07, TR0MODE); - /* udelay(10); */ + //udelay(10); break; case 1: @@ -273,17 +325,20 @@ static int adv7170_command(struct i2c_client *client, unsigned cmd, void *arg) adv7170_write(client, 0x02, 0x08); adv7170_write(client, 0x07, TR0MODE | TR0RST); adv7170_write(client, 0x07, TR0MODE); - /* udelay(10); */ + //udelay(10); break; default: - v4l_dbg(1, debug, client, "illegal input: %d\n", iarg); + dprintk(1, KERN_ERR "%s: illegal input: %d\n", + I2C_NAME(client), iarg); return -EINVAL; + } - v4l_dbg(1, debug, client, "switched to %s\n", inputs[iarg]); + dprintk(1, KERN_DEBUG "%s: switched to %s\n", I2C_NAME(client), + inputs[iarg]); encoder->input = iarg; - break; } + break; case ENCODER_SET_OUTPUT: { @@ -293,16 +348,16 @@ static int adv7170_command(struct i2c_client *client, unsigned cmd, void *arg) if (*iarg != 0) { return -EINVAL; } - break; } + break; case ENCODER_ENABLE_OUTPUT: { int *iarg = arg; encoder->enable = !!*iarg; - break; } + break; default: return -EINVAL; @@ -313,67 +368,149 @@ static int adv7170_command(struct i2c_client *client, unsigned cmd, void *arg) /* ----------------------------------------------------------------------- */ -static unsigned short normal_i2c[] = { - 0xd4 >> 1, 0xd6 >> 1, /* adv7170 IDs */ - 0x54 >> 1, 0x56 >> 1, /* adv7171 IDs */ +/* + * Generic i2c probe + * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1' + */ +static unsigned short normal_i2c[] = + { I2C_ADV7170 >> 1, (I2C_ADV7170 >> 1) + 1, + I2C_ADV7171 >> 1, (I2C_ADV7171 >> 1) + 1, I2C_CLIENT_END }; -I2C_CLIENT_INSMOD; +static unsigned short ignore = I2C_CLIENT_END; -static int adv7170_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static struct i2c_client_address_data addr_data = { + .normal_i2c = normal_i2c, + .probe = &ignore, + .ignore = &ignore, +}; + +static struct i2c_driver i2c_driver_adv7170; + +static int +adv7170_detect_client (struct i2c_adapter *adapter, + int address, + int kind) { - struct adv7170 *encoder; int i; + struct i2c_client *client; + struct adv7170 *encoder; + char *dname; + + dprintk(1, + KERN_INFO + "adv7170.c: detecting adv7170 client on address 0x%x\n", + address << 1); /* Check if the adapter supports the needed features */ - if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) - return -ENODEV; + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) + return 0; - v4l_info(client, "chip found @ 0x%x (%s)\n", - client->addr << 1, client->adapter->name); + client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); + if (!client) + return -ENOMEM; + client->addr = address; + client->adapter = adapter; + client->driver = &i2c_driver_adv7170; + if ((client->addr == I2C_ADV7170 >> 1) || + (client->addr == (I2C_ADV7170 >> 1) + 1)) { + dname = adv7170_name; + } else if ((client->addr == I2C_ADV7171 >> 1) || + (client->addr == (I2C_ADV7171 >> 1) + 1)) { + dname = adv7171_name; + } else { + /* We should never get here!!! */ + kfree(client); + return 0; + } + strlcpy(I2C_NAME(client), dname, sizeof(I2C_NAME(client))); encoder = kzalloc(sizeof(struct adv7170), GFP_KERNEL); - if (encoder == NULL) + if (encoder == NULL) { + kfree(client); return -ENOMEM; + } encoder->norm = VIDEO_MODE_NTSC; encoder->input = 0; encoder->enable = 1; i2c_set_clientdata(client, encoder); + i = i2c_attach_client(client); + if (i) { + kfree(client); + kfree(encoder); + return i; + } + i = adv7170_write_block(client, init_NTSC, sizeof(init_NTSC)); if (i >= 0) { i = adv7170_write(client, 0x07, TR0MODE | TR0RST); i = adv7170_write(client, 0x07, TR0MODE); i = adv7170_read(client, 0x12); - v4l_dbg(1, debug, client, "revision %d\n", i & 1); + dprintk(1, KERN_INFO "%s_attach: rev. %d at 0x%02x\n", + I2C_NAME(client), i & 1, client->addr << 1); + } + if (i < 0) { + dprintk(1, KERN_ERR "%s_attach: init error 0x%x\n", + I2C_NAME(client), i); } - if (i < 0) - v4l_dbg(1, debug, client, "init error 0x%x\n", i); + return 0; } -static int adv7170_remove(struct i2c_client *client) +static int +adv7170_attach_adapter (struct i2c_adapter *adapter) +{ + dprintk(1, + KERN_INFO + "adv7170.c: starting probe for adapter %s (0x%x)\n", + I2C_NAME(adapter), adapter->id); + return i2c_probe(adapter, &addr_data, &adv7170_detect_client); +} + +static int +adv7170_detach_client (struct i2c_client *client) { - kfree(i2c_get_clientdata(client)); + struct adv7170 *encoder = i2c_get_clientdata(client); + int err; + + err = i2c_detach_client(client); + if (err) { + return err; + } + + kfree(encoder); + kfree(client); + return 0; } /* ----------------------------------------------------------------------- */ -static const struct i2c_device_id adv7170_id[] = { - { "adv7170", 0 }, - { "adv7171", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, adv7170_id); +static struct i2c_driver i2c_driver_adv7170 = { + .driver = { + .name = "adv7170", /* name */ + }, + + .id = I2C_DRIVERID_ADV7170, -static struct v4l2_i2c_driver_data v4l2_i2c_data = { - .name = "adv7170", - .driverid = I2C_DRIVERID_ADV7170, + .attach_adapter = adv7170_attach_adapter, + .detach_client = adv7170_detach_client, .command = adv7170_command, - .probe = adv7170_probe, - .remove = adv7170_remove, - .id_table = adv7170_id, }; + +static int __init +adv7170_init (void) +{ + return i2c_add_driver(&i2c_driver_adv7170); +} + +static void __exit +adv7170_exit (void) +{ + i2c_del_driver(&i2c_driver_adv7170); +} + +module_init(adv7170_init); +module_exit(adv7170_exit); diff --git a/trunk/drivers/media/video/adv7175.c b/trunk/drivers/media/video/adv7175.c index 6008e84653f1..8ee07a68f702 100644 --- a/trunk/drivers/media/video/adv7175.c +++ b/trunk/drivers/media/video/adv7175.c @@ -25,24 +25,43 @@ */ #include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include -#include -#include #include -#include +#include +#include +#include +#include + #include #include -#include -#include MODULE_DESCRIPTION("Analog Devices ADV7175 video encoder driver"); MODULE_AUTHOR("Dave Perks"); MODULE_LICENSE("GPL"); + +#define I2C_NAME(s) (s)->name + + static int debug; module_param(debug, int, 0); MODULE_PARM_DESC(debug, "Debug level (0-1)"); +#define dprintk(num, format, args...) \ + do { \ + if (debug >= num) \ + printk(format, ##args); \ + } while (0) + /* ----------------------------------------------------------------------- */ struct adv7175 { @@ -58,23 +77,33 @@ struct adv7175 { #define I2C_ADV7175 0xd4 #define I2C_ADV7176 0x54 +static char adv7175_name[] = "adv7175"; +static char adv7176_name[] = "adv7176"; + static char *inputs[] = { "pass_through", "play_back", "color_bar" }; static char *norms[] = { "PAL", "NTSC", "SECAM->PAL (may not work!)" }; /* ----------------------------------------------------------------------- */ -static inline int adv7175_write(struct i2c_client *client, u8 reg, u8 value) +static inline int +adv7175_write (struct i2c_client *client, + u8 reg, + u8 value) { return i2c_smbus_write_byte_data(client, reg, value); } -static inline int adv7175_read(struct i2c_client *client, u8 reg) +static inline int +adv7175_read (struct i2c_client *client, + u8 reg) { return i2c_smbus_read_byte_data(client, reg); } -static int adv7175_write_block(struct i2c_client *client, - const u8 *data, unsigned int len) +static int +adv7175_write_block (struct i2c_client *client, + const u8 *data, + unsigned int len) { int ret = -1; u8 reg; @@ -94,17 +123,18 @@ static int adv7175_write_block(struct i2c_client *client, reg++; len -= 2; data += 2; - } while (len >= 2 && data[0] == reg && block_len < 32); - ret = i2c_master_send(client, block_data, block_len); - if (ret < 0) + } while (len >= 2 && data[0] == reg && + block_len < 32); + if ((ret = i2c_master_send(client, block_data, + block_len)) < 0) break; } } else { /* do some slow I2C emulation kind of thing */ while (len >= 2) { reg = *data++; - ret = adv7175_write(client, reg, *data++); - if (ret < 0) + if ((ret = adv7175_write(client, reg, + *data++)) < 0) break; len -= 2; } @@ -113,11 +143,13 @@ static int adv7175_write_block(struct i2c_client *client, return ret; } -static void set_subcarrier_freq(struct i2c_client *client, int pass_through) +static void +set_subcarrier_freq (struct i2c_client *client, + int pass_through) { /* for some reason pass_through NTSC needs * a different sub-carrier freq to remain stable. */ - if (pass_through) + if(pass_through) adv7175_write(client, 0x02, 0x00); else adv7175_write(client, 0x02, 0x55); @@ -128,12 +160,12 @@ static void set_subcarrier_freq(struct i2c_client *client, int pass_through) } /* ----------------------------------------------------------------------- */ -/* Output filter: S-Video Composite */ +// Output filter: S-Video Composite -#define MR050 0x11 /* 0x09 */ -#define MR060 0x14 /* 0x0c */ +#define MR050 0x11 //0x09 +#define MR060 0x14 //0x0c -/* ----------------------------------------------------------------------- */ +//--------------------------------------------------------------------------- #define TR0MODE 0x46 #define TR0RST 0x80 @@ -184,11 +216,15 @@ static const unsigned char init_ntsc[] = { 0x06, 0x1a, /* subc. phase */ }; -static int adv7175_command(struct i2c_client *client, unsigned cmd, void *arg) +static int +adv7175_command (struct i2c_client *client, + unsigned int cmd, + void *arg) { struct adv7175 *encoder = i2c_get_clientdata(client); switch (cmd) { + case 0: /* This is just for testing!!! */ adv7175_write_block(client, init_common, @@ -206,14 +242,15 @@ static int adv7175_command(struct i2c_client *client, unsigned cmd, void *arg) VIDEO_ENCODER_SECAM; /* well, hacky */ cap->inputs = 2; cap->outputs = 1; - break; } + break; case ENCODER_SET_NORM: { int iarg = *(int *) arg; switch (iarg) { + case VIDEO_MODE_NTSC: adv7175_write_block(client, init_ntsc, sizeof(init_ntsc)); @@ -247,13 +284,16 @@ static int adv7175_command(struct i2c_client *client, unsigned cmd, void *arg) adv7175_write(client, 0x07, TR0MODE); break; default: - v4l_dbg(1, debug, client, "illegal norm: %d\n", iarg); + dprintk(1, KERN_ERR "%s: illegal norm: %d\n", + I2C_NAME(client), iarg); return -EINVAL; + } - v4l_dbg(1, debug, client, "switched to %s\n", norms[iarg]); + dprintk(1, KERN_INFO "%s: switched to %s\n", I2C_NAME(client), + norms[iarg]); encoder->norm = iarg; - break; } + break; case ENCODER_SET_INPUT: { @@ -264,6 +304,7 @@ static int adv7175_command(struct i2c_client *client, unsigned cmd, void *arg) *iarg = 2: color bar */ switch (iarg) { + case 0: adv7175_write(client, 0x01, 0x00); @@ -290,7 +331,7 @@ static int adv7175_command(struct i2c_client *client, unsigned cmd, void *arg) adv7175_write(client, 0x0d, 0x49); adv7175_write(client, 0x07, TR0MODE | TR0RST); adv7175_write(client, 0x07, TR0MODE); - /* udelay(10); */ + //udelay(10); break; case 2: @@ -302,35 +343,39 @@ static int adv7175_command(struct i2c_client *client, unsigned cmd, void *arg) adv7175_write(client, 0x0d, 0x49); adv7175_write(client, 0x07, TR0MODE | TR0RST); adv7175_write(client, 0x07, TR0MODE); - /* udelay(10); */ + //udelay(10); break; default: - v4l_dbg(1, debug, client, "illegal input: %d\n", iarg); + dprintk(1, KERN_ERR "%s: illegal input: %d\n", + I2C_NAME(client), iarg); return -EINVAL; + } - v4l_dbg(1, debug, client, "switched to %s\n", inputs[iarg]); + dprintk(1, KERN_INFO "%s: switched to %s\n", I2C_NAME(client), + inputs[iarg]); encoder->input = iarg; - break; } + break; case ENCODER_SET_OUTPUT: { int *iarg = arg; /* not much choice of outputs */ - if (*iarg != 0) + if (*iarg != 0) { return -EINVAL; - break; + } } + break; case ENCODER_ENABLE_OUTPUT: { int *iarg = arg; encoder->enable = !!*iarg; - break; } + break; default: return -EINVAL; @@ -345,67 +390,145 @@ static int adv7175_command(struct i2c_client *client, unsigned cmd, void *arg) * Generic i2c probe * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1' */ -static unsigned short normal_i2c[] = { - I2C_ADV7175 >> 1, (I2C_ADV7175 >> 1) + 1, +static unsigned short normal_i2c[] = + { I2C_ADV7175 >> 1, (I2C_ADV7175 >> 1) + 1, I2C_ADV7176 >> 1, (I2C_ADV7176 >> 1) + 1, I2C_CLIENT_END }; -I2C_CLIENT_INSMOD; +static unsigned short ignore = I2C_CLIENT_END; + +static struct i2c_client_address_data addr_data = { + .normal_i2c = normal_i2c, + .probe = &ignore, + .ignore = &ignore, +}; + +static struct i2c_driver i2c_driver_adv7175; -static int adv7175_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int +adv7175_detect_client (struct i2c_adapter *adapter, + int address, + int kind) { int i; + struct i2c_client *client; struct adv7175 *encoder; + char *dname; + + dprintk(1, + KERN_INFO + "adv7175.c: detecting adv7175 client on address 0x%x\n", + address << 1); /* Check if the adapter supports the needed features */ - if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) - return -ENODEV; + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) + return 0; - v4l_info(client, "chip found @ 0x%x (%s)\n", - client->addr << 1, client->adapter->name); + client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); + if (!client) + return -ENOMEM; + client->addr = address; + client->adapter = adapter; + client->driver = &i2c_driver_adv7175; + if ((client->addr == I2C_ADV7175 >> 1) || + (client->addr == (I2C_ADV7175 >> 1) + 1)) { + dname = adv7175_name; + } else if ((client->addr == I2C_ADV7176 >> 1) || + (client->addr == (I2C_ADV7176 >> 1) + 1)) { + dname = adv7176_name; + } else { + /* We should never get here!!! */ + kfree(client); + return 0; + } + strlcpy(I2C_NAME(client), dname, sizeof(I2C_NAME(client))); encoder = kzalloc(sizeof(struct adv7175), GFP_KERNEL); - if (encoder == NULL) + if (encoder == NULL) { + kfree(client); return -ENOMEM; + } encoder->norm = VIDEO_MODE_PAL; encoder->input = 0; encoder->enable = 1; i2c_set_clientdata(client, encoder); + i = i2c_attach_client(client); + if (i) { + kfree(client); + kfree(encoder); + return i; + } + i = adv7175_write_block(client, init_common, sizeof(init_common)); if (i >= 0) { i = adv7175_write(client, 0x07, TR0MODE | TR0RST); i = adv7175_write(client, 0x07, TR0MODE); i = adv7175_read(client, 0x12); - v4l_dbg(1, debug, client, "revision %d\n", i & 1); + dprintk(1, KERN_INFO "%s_attach: rev. %d at 0x%x\n", + I2C_NAME(client), i & 1, client->addr << 1); } - if (i < 0) - v4l_dbg(1, debug, client, "init error 0x%x\n", i); + if (i < 0) { + dprintk(1, KERN_ERR "%s_attach: init error 0x%x\n", + I2C_NAME(client), i); + } + return 0; } -static int adv7175_remove(struct i2c_client *client) +static int +adv7175_attach_adapter (struct i2c_adapter *adapter) +{ + dprintk(1, + KERN_INFO + "adv7175.c: starting probe for adapter %s (0x%x)\n", + I2C_NAME(adapter), adapter->id); + return i2c_probe(adapter, &addr_data, &adv7175_detect_client); +} + +static int +adv7175_detach_client (struct i2c_client *client) { - kfree(i2c_get_clientdata(client)); + struct adv7175 *encoder = i2c_get_clientdata(client); + int err; + + err = i2c_detach_client(client); + if (err) { + return err; + } + + kfree(encoder); + kfree(client); + return 0; } /* ----------------------------------------------------------------------- */ -static const struct i2c_device_id adv7175_id[] = { - { "adv7175", 0 }, - { "adv7176", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, adv7175_id); +static struct i2c_driver i2c_driver_adv7175 = { + .driver = { + .name = "adv7175", /* name */ + }, + + .id = I2C_DRIVERID_ADV7175, -static struct v4l2_i2c_driver_data v4l2_i2c_data = { - .name = "adv7175", - .driverid = I2C_DRIVERID_ADV7175, + .attach_adapter = adv7175_attach_adapter, + .detach_client = adv7175_detach_client, .command = adv7175_command, - .probe = adv7175_probe, - .remove = adv7175_remove, - .id_table = adv7175_id, }; + +static int __init +adv7175_init (void) +{ + return i2c_add_driver(&i2c_driver_adv7175); +} + +static void __exit +adv7175_exit (void) +{ + i2c_del_driver(&i2c_driver_adv7175); +} + +module_init(adv7175_init); +module_exit(adv7175_exit); diff --git a/trunk/drivers/media/video/au0828/au0828-cards.c b/trunk/drivers/media/video/au0828/au0828-cards.c index d60123b413f5..5f07a8a072b6 100644 --- a/trunk/drivers/media/video/au0828/au0828-cards.c +++ b/trunk/drivers/media/video/au0828/au0828-cards.c @@ -90,7 +90,6 @@ static void hauppauge_eeprom(struct au0828_dev *dev, u8 *eeprom_data) case 72221: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and basic analog video */ case 72231: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and basic analog video */ case 72241: /* WinTV-HVR950q (OEM, No IR, ATSC/QAM and basic analog video */ - case 72251: /* WinTV-HVR950q (Retail, IR, ATSC/QAM and basic analog video */ case 72301: /* WinTV-HVR850 (Retail, IR, ATSC and basic analog video */ case 72500: /* WinTV-HVR950q (OEM, No IR, ATSC/QAM */ break; @@ -186,7 +185,7 @@ void au0828_gpio_setup(struct au0828_dev *dev) } /* table of devices that work with this driver */ -struct usb_device_id au0828_usb_id_table[] = { +struct usb_device_id au0828_usb_id_table [] = { { USB_DEVICE(0x2040, 0x7200), .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q }, { USB_DEVICE(0x2040, 0x7240), @@ -199,8 +198,6 @@ struct usb_device_id au0828_usb_id_table[] = { .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q }, { USB_DEVICE(0x2040, 0x721b), .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q }, - { USB_DEVICE(0x2040, 0x721e), - .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q }, { USB_DEVICE(0x2040, 0x721f), .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q }, { USB_DEVICE(0x2040, 0x7280), diff --git a/trunk/drivers/media/video/au0828/au0828-core.c b/trunk/drivers/media/video/au0828/au0828-core.c index 5765e8656376..d856de9f742f 100644 --- a/trunk/drivers/media/video/au0828/au0828-core.c +++ b/trunk/drivers/media/video/au0828/au0828-core.c @@ -91,8 +91,7 @@ static int send_control_msg(struct au0828_dev *dev, u16 request, u32 value, status = usb_control_msg(dev->usbdev, usb_sndctrlpipe(dev->usbdev, 0), request, - USB_DIR_OUT | USB_TYPE_VENDOR | - USB_RECIP_DEVICE, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, value, index, cp, size, 1000); diff --git a/trunk/drivers/media/video/au0828/au0828-dvb.c b/trunk/drivers/media/video/au0828/au0828-dvb.c index a882cf546d0a..f0fcdb4769d7 100644 --- a/trunk/drivers/media/video/au0828/au0828-dvb.c +++ b/trunk/drivers/media/video/au0828/au0828-dvb.c @@ -173,8 +173,7 @@ static int start_urb_transfer(struct au0828_dev *dev) purb->status = -EINPROGRESS; usb_fill_bulk_urb(purb, dev->usbdev, - usb_rcvbulkpipe(dev->usbdev, - _AU0828_BULKPIPE), + usb_rcvbulkpipe(dev->usbdev, _AU0828_BULKPIPE), purb->transfer_buffer, URB_BUFSIZE, urb_completion, diff --git a/trunk/drivers/media/video/bt819.c b/trunk/drivers/media/video/bt819.c index a07b7b88e5b8..ddd2a7964dec 100644 --- a/trunk/drivers/media/video/bt819.c +++ b/trunk/drivers/media/video/bt819.c @@ -29,25 +29,44 @@ */ #include +#include #include +#include +#include +#include +#include +#include +#include +#include #include -#include -#include #include -#include +#include +#include +#include +#include + #include #include -#include -#include + MODULE_DESCRIPTION("Brooktree-819 video decoder driver"); MODULE_AUTHOR("Mike Bernson & Dave Perks"); MODULE_LICENSE("GPL"); + +#define I2C_NAME(s) (s)->name + + static int debug; module_param(debug, int, 0); MODULE_PARM_DESC(debug, "Debug level (0-1)"); +#define dprintk(num, format, args...) \ + do { \ + if (debug >= num) \ + printk(format, ##args); \ + } while (0) + /* ----------------------------------------------------------------------- */ struct bt819 { @@ -78,9 +97,14 @@ static struct timing timing_data[] = { {858 - 24, 20, 525 - 2, 1, 0x00f8, 0x0000}, }; +#define I2C_BT819 0x8a + /* ----------------------------------------------------------------------- */ -static inline int bt819_write(struct i2c_client *client, u8 reg, u8 value) +static inline int +bt819_write (struct i2c_client *client, + u8 reg, + u8 value) { struct bt819 *decoder = i2c_get_clientdata(client); @@ -88,15 +112,24 @@ static inline int bt819_write(struct i2c_client *client, u8 reg, u8 value) return i2c_smbus_write_byte_data(client, reg, value); } -static inline int bt819_setbit(struct i2c_client *client, u8 reg, u8 bit, u8 value) +static inline int +bt819_setbit (struct i2c_client *client, + u8 reg, + u8 bit, + u8 value) { struct bt819 *decoder = i2c_get_clientdata(client); return bt819_write(client, reg, - (decoder->reg[reg] & ~(1 << bit)) | (value ? (1 << bit) : 0)); + (decoder-> + reg[reg] & ~(1 << bit)) | + (value ? (1 << bit) : 0)); } -static int bt819_write_block(struct i2c_client *client, const u8 *data, unsigned int len) +static int +bt819_write_block (struct i2c_client *client, + const u8 *data, + unsigned int len) { int ret = -1; u8 reg; @@ -117,9 +150,10 @@ static int bt819_write_block(struct i2c_client *client, const u8 *data, unsigned decoder->reg[reg++] = data[1]; len -= 2; data += 2; - } while (len >= 2 && data[0] == reg && block_len < 32); - ret = i2c_master_send(client, block_data, block_len); - if (ret < 0) + } while (len >= 2 && data[0] == reg && + block_len < 32); + if ((ret = i2c_master_send(client, block_data, + block_len)) < 0) break; } } else { @@ -135,17 +169,20 @@ static int bt819_write_block(struct i2c_client *client, const u8 *data, unsigned return ret; } -static inline int bt819_read(struct i2c_client *client, u8 reg) +static inline int +bt819_read (struct i2c_client *client, + u8 reg) { return i2c_smbus_read_byte_data(client, reg); } -static int bt819_init(struct i2c_client *client) +static int +bt819_init (struct i2c_client *client) { struct bt819 *decoder = i2c_get_clientdata(client); static unsigned char init[] = { - /*0x1f, 0x00,*/ /* Reset */ + //0x1f, 0x00, /* Reset */ 0x01, 0x59, /* 0x01 input format */ 0x02, 0x00, /* 0x02 temporal decimation */ 0x03, 0x12, /* 0x03 Cropping msb */ @@ -181,10 +218,12 @@ static int bt819_init(struct i2c_client *client) struct timing *timing = &timing_data[decoder->norm]; init[0x03 * 2 - 1] = - (((timing->vdelay >> 8) & 0x03) << 6) | - (((timing->vactive >> 8) & 0x03) << 4) | - (((timing->hdelay >> 8) & 0x03) << 2) | - ((timing->hactive >> 8) & 0x03); + (((timing->vdelay >> 8) & 0x03) << 6) | (((timing-> + vactive >> 8) & + 0x03) << 4) | + (((timing->hdelay >> 8) & 0x03) << 2) | ((timing-> + hactive >> 8) & + 0x03); init[0x04 * 2 - 1] = timing->vdelay & 0xff; init[0x05 * 2 - 1] = timing->vactive & 0xff; init[0x06 * 2 - 1] = timing->hdelay & 0xff; @@ -199,22 +238,27 @@ static int bt819_init(struct i2c_client *client) /* init */ return bt819_write_block(client, init, sizeof(init)); + } /* ----------------------------------------------------------------------- */ -static int bt819_command(struct i2c_client *client, unsigned cmd, void *arg) +static int +bt819_command (struct i2c_client *client, + unsigned int cmd, + void *arg) { int temp; struct bt819 *decoder = i2c_get_clientdata(client); - if (!decoder->initialized) { /* First call to bt819_init could be */ - bt819_init(client); /* without #FRST = 0 */ + if (!decoder->initialized) { // First call to bt819_init could be + bt819_init(client); // without #FRST = 0 decoder->initialized = 1; } switch (cmd) { + case 0: /* This is just for testing!!! */ bt819_init(client); @@ -230,8 +274,8 @@ static int bt819_command(struct i2c_client *client, unsigned cmd, void *arg) VIDEO_DECODER_CCIR; cap->inputs = 8; cap->outputs = 1; - break; } + break; case DECODER_GET_STATUS: { @@ -241,9 +285,9 @@ static int bt819_command(struct i2c_client *client, unsigned cmd, void *arg) status = bt819_read(client, 0x00); res = 0; - if ((status & 0x80)) + if ((status & 0x80)) { res |= DECODER_STATUS_GOOD; - + } switch (decoder->norm) { case VIDEO_MODE_NTSC: res |= DECODER_STATUS_NTSC; @@ -253,25 +297,28 @@ static int bt819_command(struct i2c_client *client, unsigned cmd, void *arg) break; default: case VIDEO_MODE_AUTO: - if ((status & 0x10)) + if ((status & 0x10)) { res |= DECODER_STATUS_PAL; - else + } else { res |= DECODER_STATUS_NTSC; + } break; } res |= DECODER_STATUS_COLOR; *iarg = res; - v4l_dbg(1, debug, client, "get status %x\n", *iarg); - break; + dprintk(1, KERN_INFO "%s: get status %x\n", I2C_NAME(client), + *iarg); } + break; case DECODER_SET_NORM: { int *iarg = arg; struct timing *timing = NULL; - v4l_dbg(1, debug, client, "set norm %x\n", *iarg); + dprintk(1, KERN_INFO "%s: set norm %x\n", I2C_NAME(client), + *iarg); switch (*iarg) { case VIDEO_MODE_NTSC: @@ -280,7 +327,7 @@ static int bt819_command(struct i2c_client *client, unsigned cmd, void *arg) bt819_setbit(client, 0x01, 5, 0); bt819_write(client, 0x18, 0x68); bt819_write(client, 0x19, 0x5d); - /* bt819_setbit(client, 0x1a, 5, 1); */ + //bt819_setbit(client, 0x1a, 5, 1); timing = &timing_data[VIDEO_MODE_NTSC]; break; case VIDEO_MODE_PAL: @@ -289,7 +336,7 @@ static int bt819_command(struct i2c_client *client, unsigned cmd, void *arg) bt819_setbit(client, 0x01, 5, 1); bt819_write(client, 0x18, 0x7f); bt819_write(client, 0x19, 0x72); - /* bt819_setbit(client, 0x1a, 5, 0); */ + //bt819_setbit(client, 0x1a, 5, 0); timing = &timing_data[VIDEO_MODE_PAL]; break; case VIDEO_MODE_AUTO: @@ -297,7 +344,10 @@ static int bt819_command(struct i2c_client *client, unsigned cmd, void *arg) bt819_setbit(client, 0x01, 1, 0); break; default: - v4l_dbg(1, debug, client, "unsupported norm %x\n", *iarg); + dprintk(1, + KERN_ERR + "%s: unsupported norm %d\n", + I2C_NAME(client), *iarg); return -EINVAL; } @@ -316,17 +366,19 @@ static int bt819_command(struct i2c_client *client, unsigned cmd, void *arg) } decoder->norm = *iarg; - break; } + break; case DECODER_SET_INPUT: { int *iarg = arg; - v4l_dbg(1, debug, client, "set input %x\n", *iarg); + dprintk(1, KERN_INFO "%s: set input %x\n", I2C_NAME(client), + *iarg); - if (*iarg < 0 || *iarg > 7) + if (*iarg < 0 || *iarg > 7) { return -EINVAL; + } if (decoder->input != *iarg) { decoder->input = *iarg; @@ -339,42 +391,52 @@ static int bt819_command(struct i2c_client *client, unsigned cmd, void *arg) bt819_setbit(client, 0x1a, 1, 0); } } - break; } + break; case DECODER_SET_OUTPUT: { int *iarg = arg; - v4l_dbg(1, debug, client, "set output %x\n", *iarg); + dprintk(1, KERN_INFO "%s: set output %x\n", I2C_NAME(client), + *iarg); /* not much choice of outputs */ - if (*iarg != 0) + if (*iarg != 0) { return -EINVAL; - break; + } } + break; case DECODER_ENABLE_OUTPUT: { int *iarg = arg; int enable = (*iarg != 0); - v4l_dbg(1, debug, client, "enable output %x\n", *iarg); + dprintk(1, KERN_INFO "%s: enable output %x\n", + I2C_NAME(client), *iarg); if (decoder->enable != enable) { decoder->enable = enable; - bt819_setbit(client, 0x16, 7, !enable); + + if (decoder->enable) { + bt819_setbit(client, 0x16, 7, 0); + } else { + bt819_setbit(client, 0x16, 7, 1); + } } - break; } + break; case DECODER_SET_PICTURE: { struct video_picture *pic = arg; - v4l_dbg(1, debug, client, - "set picture brightness %d contrast %d colour %d\n", - pic->brightness, pic->contrast, pic->colour); + dprintk(1, + KERN_INFO + "%s: set picture brightness %d contrast %d colour %d\n", + I2C_NAME(client), pic->brightness, pic->contrast, + pic->colour); if (decoder->bright != pic->brightness) { @@ -412,8 +474,8 @@ static int bt819_command(struct i2c_client *client, unsigned cmd, void *arg) bt819_write(client, 0x0f, 128 - (decoder->hue >> 8)); } - break; } + break; default: return -EINVAL; @@ -424,44 +486,55 @@ static int bt819_command(struct i2c_client *client, unsigned cmd, void *arg) /* ----------------------------------------------------------------------- */ -static unsigned short normal_i2c[] = { 0x8a >> 1, I2C_CLIENT_END }; +/* + * Generic i2c probe + * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1' + */ +static unsigned short normal_i2c[] = { + I2C_BT819 >> 1, + I2C_CLIENT_END, +}; + +static unsigned short ignore = I2C_CLIENT_END; + +static struct i2c_client_address_data addr_data = { + .normal_i2c = normal_i2c, + .probe = &ignore, + .ignore = &ignore, +}; -I2C_CLIENT_INSMOD; +static struct i2c_driver i2c_driver_bt819; -static int bt819_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int +bt819_detect_client (struct i2c_adapter *adapter, + int address, + int kind) { - int i, ver; + int i, id; struct bt819 *decoder; - const char *name; + struct i2c_client *client; - /* Check if the adapter supports the needed features */ - if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) - return -ENODEV; + dprintk(1, + KERN_INFO + "bt819: detecting bt819 client on address 0x%x\n", + address << 1); - ver = bt819_read(client, 0x17); - switch (ver & 0xf0) { - case 0x70: - name = "bt819a"; - break; - case 0x60: - name = "bt817a"; - break; - case 0x20: - name = "bt815a"; - break; - default: - v4l_dbg(1, debug, client, - "unknown chip version 0x%02x\n", ver); - return -ENODEV; - } + /* Check if the adapter supports the needed features */ + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) + return 0; - v4l_info(client, "%s found @ 0x%x (%s)\n", name, - client->addr << 1, client->adapter->name); + client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); + if (!client) + return -ENOMEM; + client->addr = address; + client->adapter = adapter; + client->driver = &i2c_driver_bt819; decoder = kzalloc(sizeof(struct bt819), GFP_KERNEL); - if (decoder == NULL) + if (decoder == NULL) { + kfree(client); return -ENOMEM; + } decoder->norm = VIDEO_MODE_NTSC; decoder->input = 0; decoder->enable = 1; @@ -472,33 +545,97 @@ static int bt819_probe(struct i2c_client *client, decoder->initialized = 0; i2c_set_clientdata(client, decoder); + id = bt819_read(client, 0x17); + switch (id & 0xf0) { + case 0x70: + strlcpy(I2C_NAME(client), "bt819a", sizeof(I2C_NAME(client))); + break; + case 0x60: + strlcpy(I2C_NAME(client), "bt817a", sizeof(I2C_NAME(client))); + break; + case 0x20: + strlcpy(I2C_NAME(client), "bt815a", sizeof(I2C_NAME(client))); + break; + default: + dprintk(1, + KERN_ERR + "bt819: unknown chip version 0x%x (ver 0x%x)\n", + id & 0xf0, id & 0x0f); + kfree(decoder); + kfree(client); + return 0; + } + + i = i2c_attach_client(client); + if (i) { + kfree(client); + kfree(decoder); + return i; + } + i = bt819_init(client); - if (i < 0) - v4l_dbg(1, debug, client, "init status %d\n", i); + if (i < 0) { + dprintk(1, KERN_ERR "%s_attach: init status %d\n", + I2C_NAME(client), i); + } else { + dprintk(1, + KERN_INFO + "%s_attach: chip version 0x%x at address 0x%x\n", + I2C_NAME(client), id & 0x0f, + client->addr << 1); + } + return 0; } -static int bt819_remove(struct i2c_client *client) +static int +bt819_attach_adapter (struct i2c_adapter *adapter) +{ + return i2c_probe(adapter, &addr_data, &bt819_detect_client); +} + +static int +bt819_detach_client (struct i2c_client *client) { - kfree(i2c_get_clientdata(client)); + struct bt819 *decoder = i2c_get_clientdata(client); + int err; + + err = i2c_detach_client(client); + if (err) { + return err; + } + + kfree(decoder); + kfree(client); + return 0; } /* ----------------------------------------------------------------------- */ -static const struct i2c_device_id bt819_id[] = { - { "bt819a", 0 }, - { "bt817a", 0 }, - { "bt815a", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, bt819_id); +static struct i2c_driver i2c_driver_bt819 = { + .driver = { + .name = "bt819", + }, + + .id = I2C_DRIVERID_BT819, -static struct v4l2_i2c_driver_data v4l2_i2c_data = { - .name = "bt819", - .driverid = I2C_DRIVERID_BT819, + .attach_adapter = bt819_attach_adapter, + .detach_client = bt819_detach_client, .command = bt819_command, - .probe = bt819_probe, - .remove = bt819_remove, - .id_table = bt819_id, }; + +static int __init +bt819_init_module (void) +{ + return i2c_add_driver(&i2c_driver_bt819); +} + +static void __exit +bt819_exit (void) +{ + i2c_del_driver(&i2c_driver_bt819); +} + +module_init(bt819_init_module); +module_exit(bt819_exit); diff --git a/trunk/drivers/media/video/bt856.c b/trunk/drivers/media/video/bt856.c index 4213867507f8..ab2ce4d7b5de 100644 --- a/trunk/drivers/media/video/bt856.c +++ b/trunk/drivers/media/video/bt856.c @@ -29,24 +29,43 @@ */ #include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include -#include -#include #include -#include -#include #include -#include -#include +#include +#include +#include +#include + +#include MODULE_DESCRIPTION("Brooktree-856A video encoder driver"); MODULE_AUTHOR("Mike Bernson & Dave Perks"); MODULE_LICENSE("GPL"); + +#define I2C_NAME(s) (s)->name + + static int debug; module_param(debug, int, 0); MODULE_PARM_DESC(debug, "Debug level (0-1)"); +#define dprintk(num, format, args...) \ + do { \ + if (debug >= num) \ + printk(format, ##args); \ + } while (0) + /* ----------------------------------------------------------------------- */ #define BT856_REG_OFFSET 0xDA @@ -59,9 +78,14 @@ struct bt856 { int enable; }; +#define I2C_BT856 0x88 + /* ----------------------------------------------------------------------- */ -static inline int bt856_write(struct i2c_client *client, u8 reg, u8 value) +static inline int +bt856_write (struct i2c_client *client, + u8 reg, + u8 value) { struct bt856 *encoder = i2c_get_clientdata(client); @@ -69,36 +93,46 @@ static inline int bt856_write(struct i2c_client *client, u8 reg, u8 value) return i2c_smbus_write_byte_data(client, reg, value); } -static inline int bt856_setbit(struct i2c_client *client, u8 reg, u8 bit, u8 value) +static inline int +bt856_setbit (struct i2c_client *client, + u8 reg, + u8 bit, + u8 value) { struct bt856 *encoder = i2c_get_clientdata(client); return bt856_write(client, reg, - (encoder->reg[reg - BT856_REG_OFFSET] & ~(1 << bit)) | - (value ? (1 << bit) : 0)); + (encoder-> + reg[reg - BT856_REG_OFFSET] & ~(1 << bit)) | + (value ? (1 << bit) : 0)); } -static void bt856_dump(struct i2c_client *client) +static void +bt856_dump (struct i2c_client *client) { int i; struct bt856 *encoder = i2c_get_clientdata(client); - v4l_info(client, "register dump:\n"); + printk(KERN_INFO "%s: register dump:", I2C_NAME(client)); for (i = 0; i < BT856_NR_REG; i += 2) - printk(KERN_CONT " %02x", encoder->reg[i]); - printk(KERN_CONT "\n"); + printk(" %02x", encoder->reg[i]); + printk("\n"); } /* ----------------------------------------------------------------------- */ -static int bt856_command(struct i2c_client *client, unsigned cmd, void *arg) +static int +bt856_command (struct i2c_client *client, + unsigned int cmd, + void *arg) { struct bt856 *encoder = i2c_get_clientdata(client); switch (cmd) { + case 0: /* This is just for testing!!! */ - v4l_dbg(1, debug, client, "init\n"); + dprintk(1, KERN_INFO "bt856: init\n"); bt856_write(client, 0xdc, 0x18); bt856_write(client, 0xda, 0); bt856_write(client, 0xde, 0); @@ -108,6 +142,7 @@ static int bt856_command(struct i2c_client *client, unsigned cmd, void *arg) bt856_setbit(client, 0xdc, 4, 1); switch (encoder->norm) { + case VIDEO_MODE_NTSC: bt856_setbit(client, 0xdc, 2, 0); break; @@ -128,23 +163,26 @@ static int bt856_command(struct i2c_client *client, unsigned cmd, void *arg) { struct video_encoder_capability *cap = arg; - v4l_dbg(1, debug, client, "get capabilities\n"); + dprintk(1, KERN_INFO "%s: get capabilities\n", + I2C_NAME(client)); cap->flags = VIDEO_ENCODER_PAL | VIDEO_ENCODER_NTSC | VIDEO_ENCODER_CCIR; cap->inputs = 2; cap->outputs = 1; - break; } + break; case ENCODER_SET_NORM: { int *iarg = arg; - v4l_dbg(1, debug, client, "set norm %d\n", *iarg); + dprintk(1, KERN_INFO "%s: set norm %d\n", I2C_NAME(client), + *iarg); switch (*iarg) { + case VIDEO_MODE_NTSC: bt856_setbit(client, 0xdc, 2, 0); break; @@ -157,23 +195,27 @@ static int bt856_command(struct i2c_client *client, unsigned cmd, void *arg) default: return -EINVAL; + } encoder->norm = *iarg; if (debug != 0) bt856_dump(client); - break; } + break; case ENCODER_SET_INPUT: { int *iarg = arg; - v4l_dbg(1, debug, client, "set input %d\n", *iarg); + dprintk(1, KERN_INFO "%s: set input %d\n", I2C_NAME(client), + *iarg); /* We only have video bus. * iarg = 0: input is from bt819 * iarg = 1: input is from ZR36060 */ + switch (*iarg) { + case 0: bt856_setbit(client, 0xde, 4, 0); bt856_setbit(client, 0xde, 3, 1); @@ -192,24 +234,27 @@ static int bt856_command(struct i2c_client *client, unsigned cmd, void *arg) break; default: return -EINVAL; + } if (debug != 0) bt856_dump(client); - break; } + break; case ENCODER_SET_OUTPUT: { int *iarg = arg; - v4l_dbg(1, debug, client, "set output %d\n", *iarg); + dprintk(1, KERN_INFO "%s: set output %d\n", I2C_NAME(client), + *iarg); /* not much choice of outputs */ - if (*iarg != 0) + if (*iarg != 0) { return -EINVAL; - break; + } } + break; case ENCODER_ENABLE_OUTPUT: { @@ -217,9 +262,10 @@ static int bt856_command(struct i2c_client *client, unsigned cmd, void *arg) encoder->enable = !!*iarg; - v4l_dbg(1, debug, client, "enable output %d\n", encoder->enable); - break; + dprintk(1, KERN_INFO "%s: enable output %d\n", + I2C_NAME(client), encoder->enable); } + break; default: return -EINVAL; @@ -230,29 +276,64 @@ static int bt856_command(struct i2c_client *client, unsigned cmd, void *arg) /* ----------------------------------------------------------------------- */ -static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END }; +/* + * Generic i2c probe + * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1' + */ +static unsigned short normal_i2c[] = { I2C_BT856 >> 1, I2C_CLIENT_END }; + +static unsigned short ignore = I2C_CLIENT_END; + +static struct i2c_client_address_data addr_data = { + .normal_i2c = normal_i2c, + .probe = &ignore, + .ignore = &ignore, +}; -I2C_CLIENT_INSMOD; +static struct i2c_driver i2c_driver_bt856; -static int bt856_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int +bt856_detect_client (struct i2c_adapter *adapter, + int address, + int kind) { + int i; + struct i2c_client *client; struct bt856 *encoder; + dprintk(1, + KERN_INFO + "bt856.c: detecting bt856 client on address 0x%x\n", + address << 1); + /* Check if the adapter supports the needed features */ - if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) - return -ENODEV; + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) + return 0; - v4l_info(client, "chip found @ 0x%x (%s)\n", - client->addr << 1, client->adapter->name); + client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); + if (!client) + return -ENOMEM; + client->addr = address; + client->adapter = adapter; + client->driver = &i2c_driver_bt856; + strlcpy(I2C_NAME(client), "bt856", sizeof(I2C_NAME(client))); encoder = kzalloc(sizeof(struct bt856), GFP_KERNEL); - if (encoder == NULL) + if (encoder == NULL) { + kfree(client); return -ENOMEM; + } encoder->norm = VIDEO_MODE_NTSC; encoder->enable = 1; i2c_set_clientdata(client, encoder); + i = i2c_attach_client(client); + if (i) { + kfree(client); + kfree(encoder); + return i; + } + bt856_write(client, 0xdc, 0x18); bt856_write(client, 0xda, 0); bt856_write(client, 0xde, 0); @@ -278,26 +359,65 @@ static int bt856_probe(struct i2c_client *client, if (debug != 0) bt856_dump(client); + + dprintk(1, KERN_INFO "%s_attach: at address 0x%x\n", I2C_NAME(client), + client->addr << 1); + return 0; } -static int bt856_remove(struct i2c_client *client) +static int +bt856_attach_adapter (struct i2c_adapter *adapter) { - kfree(i2c_get_clientdata(client)); + dprintk(1, + KERN_INFO + "bt856.c: starting probe for adapter %s (0x%x)\n", + I2C_NAME(adapter), adapter->id); + return i2c_probe(adapter, &addr_data, &bt856_detect_client); +} + +static int +bt856_detach_client (struct i2c_client *client) +{ + struct bt856 *encoder = i2c_get_clientdata(client); + int err; + + err = i2c_detach_client(client); + if (err) { + return err; + } + + kfree(encoder); + kfree(client); + return 0; } -static const struct i2c_device_id bt856_id[] = { - { "bt856", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, bt856_id); +/* ----------------------------------------------------------------------- */ + +static struct i2c_driver i2c_driver_bt856 = { + .driver = { + .name = "bt856", + }, + + .id = I2C_DRIVERID_BT856, -static struct v4l2_i2c_driver_data v4l2_i2c_data = { - .name = "bt856", - .driverid = I2C_DRIVERID_BT856, + .attach_adapter = bt856_attach_adapter, + .detach_client = bt856_detach_client, .command = bt856_command, - .probe = bt856_probe, - .remove = bt856_remove, - .id_table = bt856_id, }; + +static int __init +bt856_init (void) +{ + return i2c_add_driver(&i2c_driver_bt856); +} + +static void __exit +bt856_exit (void) +{ + i2c_del_driver(&i2c_driver_bt856); +} + +module_init(bt856_init); +module_exit(bt856_exit); diff --git a/trunk/drivers/media/video/bt866.c b/trunk/drivers/media/video/bt866.c index 596f9e2376be..96b415576f0d 100644 --- a/trunk/drivers/media/video/bt866.c +++ b/trunk/drivers/media/video/bt866.c @@ -29,28 +29,42 @@ */ #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include -#include -#include #include -#include + #include +#include + #include -#include -#include -MODULE_DESCRIPTION("Brooktree-866 video encoder driver"); -MODULE_AUTHOR("Mike Bernson & Dave Perks"); MODULE_LICENSE("GPL"); -static int debug; -module_param(debug, int, 0); -MODULE_PARM_DESC(debug, "Debug level (0-1)"); +#define BT866_DEVNAME "bt866" +#define I2C_BT866 0x88 + +MODULE_LICENSE("GPL"); + +#define DEBUG(x) /* Debug driver */ /* ----------------------------------------------------------------------- */ struct bt866 { - u8 reg[256]; + struct i2c_client *i2c; + int addr; + unsigned char reg[256]; int norm; int enable; @@ -60,45 +74,20 @@ struct bt866 { int sat; }; -static int bt866_write(struct i2c_client *client, u8 subaddr, u8 data) -{ - struct bt866 *encoder = i2c_get_clientdata(client); - u8 buffer[2]; - int err; - - buffer[0] = subaddr; - buffer[1] = data; - - encoder->reg[subaddr] = data; - - v4l_dbg(1, debug, client, "write 0x%02x = 0x%02x\n", subaddr, data); - - for (err = 0; err < 3;) { - if (i2c_master_send(client, buffer, 2) == 2) - break; - err++; - v4l_warn(client, "error #%d writing to 0x%02x\n", - err, subaddr); - schedule_timeout_interruptible(msecs_to_jiffies(100)); - } - if (err == 3) { - v4l_warn(client, "giving up\n"); - return -1; - } - - return 0; -} +static int bt866_write(struct bt866 *dev, + unsigned char subaddr, unsigned char data); -static int bt866_command(struct i2c_client *client, unsigned cmd, void *arg) +static int bt866_do_command(struct bt866 *encoder, + unsigned int cmd, void *arg) { - struct bt866 *encoder = i2c_get_clientdata(client); - switch (cmd) { case ENCODER_GET_CAPABILITIES: { struct video_encoder_capability *cap = arg; - v4l_dbg(1, debug, client, "get capabilities\n"); + DEBUG(printk + (KERN_INFO "%s: get capabilities\n", + encoder->i2c->name)); cap->flags = VIDEO_ENCODER_PAL @@ -106,16 +95,18 @@ static int bt866_command(struct i2c_client *client, unsigned cmd, void *arg) | VIDEO_ENCODER_CCIR; cap->inputs = 2; cap->outputs = 1; - break; } + break; case ENCODER_SET_NORM: { int *iarg = arg; - v4l_dbg(1, debug, client, "set norm %d\n", *iarg); + DEBUG(printk(KERN_INFO "%s: set norm %d\n", + encoder->i2c->name, *iarg)); switch (*iarg) { + case VIDEO_MODE_NTSC: break; @@ -124,10 +115,11 @@ static int bt866_command(struct i2c_client *client, unsigned cmd, void *arg) default: return -EINVAL; + } encoder->norm = *iarg; - break; } + break; case ENCODER_SET_INPUT: { @@ -163,7 +155,7 @@ static int bt866_command(struct i2c_client *client, unsigned cmd, void *arg) u8 val; for (i = 0; i < ARRAY_SIZE(init) / 2; i += 2) - bt866_write(client, init[i], init[i+1]); + bt866_write(encoder, init[i], init[i+1]); val = encoder->reg[0xdc]; @@ -172,16 +164,17 @@ static int bt866_command(struct i2c_client *client, unsigned cmd, void *arg) else val &= ~0x40; /* !CBSWAP */ - bt866_write(client, 0xdc, val); + bt866_write(encoder, 0xdc, val); val = encoder->reg[0xcc]; if (*iarg == 2) val |= 0x01; /* OSDBAR */ else val &= ~0x01; /* !OSDBAR */ - bt866_write(client, 0xcc, val); + bt866_write(encoder, 0xcc, val); - v4l_dbg(1, debug, client, "set input %d\n", *iarg); + DEBUG(printk(KERN_INFO "%s: set input %d\n", + encoder->i2c->name, *iarg)); switch (*iarg) { case 0: @@ -190,44 +183,48 @@ static int bt866_command(struct i2c_client *client, unsigned cmd, void *arg) break; default: return -EINVAL; + } - break; } + break; case ENCODER_SET_OUTPUT: { int *iarg = arg; - v4l_dbg(1, debug, client, "set output %d\n", *iarg); + DEBUG(printk(KERN_INFO "%s: set output %d\n", + encoder->i2c->name, *iarg)); /* not much choice of outputs */ if (*iarg != 0) return -EINVAL; - break; } + break; case ENCODER_ENABLE_OUTPUT: { int *iarg = arg; encoder->enable = !!*iarg; - v4l_dbg(1, debug, client, "enable output %d\n", encoder->enable); - break; + DEBUG(printk + (KERN_INFO "%s: enable output %d\n", + encoder->i2c->name, encoder->enable)); } + break; case 4711: { int *iarg = arg; __u8 val; - v4l_dbg(1, debug, client, "square %d\n", *iarg); + printk("bt866: square = %d\n", *iarg); val = encoder->reg[0xdc]; if (*iarg) val |= 1; /* SQUARE */ else val &= ~1; /* !SQUARE */ - bt866_write(client, 0xdc, val); + bt866_write(encoder, 0xdc, val); break; } @@ -238,49 +235,141 @@ static int bt866_command(struct i2c_client *client, unsigned cmd, void *arg) return 0; } -static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END }; +static int bt866_write(struct bt866 *encoder, + unsigned char subaddr, unsigned char data) +{ + unsigned char buffer[2]; + int err; -I2C_CLIENT_INSMOD; + buffer[0] = subaddr; + buffer[1] = data; + + encoder->reg[subaddr] = data; -static int bt866_probe(struct i2c_client *client, - const struct i2c_device_id *id) + DEBUG(printk + ("%s: write 0x%02X = 0x%02X\n", + encoder->i2c->name, subaddr, data)); + + for (err = 0; err < 3;) { + if (i2c_master_send(encoder->i2c, buffer, 2) == 2) + break; + err++; + printk(KERN_WARNING "%s: I/O error #%d " + "(write 0x%02x/0x%02x)\n", + encoder->i2c->name, err, encoder->addr, subaddr); + schedule_timeout_interruptible(msecs_to_jiffies(100)); + } + if (err == 3) { + printk(KERN_WARNING "%s: giving up\n", + encoder->i2c->name); + return -1; + } + + return 0; +} + +static int bt866_attach(struct i2c_adapter *adapter); +static int bt866_detach(struct i2c_client *client); +static int bt866_command(struct i2c_client *client, + unsigned int cmd, void *arg); + + +/* Addresses to scan */ +static unsigned short normal_i2c[] = {I2C_BT866>>1, I2C_CLIENT_END}; +static unsigned short probe[2] = {I2C_CLIENT_END, I2C_CLIENT_END}; +static unsigned short ignore[2] = {I2C_CLIENT_END, I2C_CLIENT_END}; + +static struct i2c_client_address_data addr_data = { + normal_i2c, + probe, + ignore, +}; + +static struct i2c_driver i2c_driver_bt866 = { + .driver.name = BT866_DEVNAME, + .id = I2C_DRIVERID_BT866, + .attach_adapter = bt866_attach, + .detach_client = bt866_detach, + .command = bt866_command +}; + + +static struct i2c_client bt866_client_tmpl = +{ + .name = "(nil)", + .addr = 0, + .adapter = NULL, + .driver = &i2c_driver_bt866, +}; + +static int bt866_found_proc(struct i2c_adapter *adapter, + int addr, int kind) { struct bt866 *encoder; + struct i2c_client *client; - v4l_info(client, "chip found @ 0x%x (%s)\n", - client->addr << 1, client->adapter->name); + client = kzalloc(sizeof(*client), GFP_KERNEL); + if (client == NULL) + return -ENOMEM; + memcpy(client, &bt866_client_tmpl, sizeof(*client)); encoder = kzalloc(sizeof(*encoder), GFP_KERNEL); - if (encoder == NULL) + if (encoder == NULL) { + kfree(client); return -ENOMEM; + } i2c_set_clientdata(client, encoder); + client->adapter = adapter; + client->addr = addr; + sprintf(client->name, "%s-%02x", BT866_DEVNAME, adapter->id); + + encoder->i2c = client; + encoder->addr = addr; + //encoder->encoder_type = ENCODER_TYPE_UNKNOWN; + + /* initialize */ + + i2c_attach_client(client); + return 0; } -static int bt866_remove(struct i2c_client *client) +static int bt866_attach(struct i2c_adapter *adapter) { - kfree(i2c_get_clientdata(client)); + if (adapter->id == I2C_HW_B_ZR36067) + return i2c_probe(adapter, &addr_data, bt866_found_proc); return 0; } -static int bt866_legacy_probe(struct i2c_adapter *adapter) +static int bt866_detach(struct i2c_client *client) { - return adapter->id == I2C_HW_B_ZR36067; + struct bt866 *encoder = i2c_get_clientdata(client); + + i2c_detach_client(client); + kfree(encoder); + kfree(client); + + return 0; } -static const struct i2c_device_id bt866_id[] = { - { "bt866", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, bt866_id); - -static struct v4l2_i2c_driver_data v4l2_i2c_data = { - .name = "bt866", - .driverid = I2C_DRIVERID_BT866, - .command = bt866_command, - .probe = bt866_probe, - .remove = bt866_remove, - .legacy_probe = bt866_legacy_probe, - .id_table = bt866_id, -}; +static int bt866_command(struct i2c_client *client, + unsigned int cmd, void *arg) +{ + struct bt866 *encoder = i2c_get_clientdata(client); + return bt866_do_command(encoder, cmd, arg); +} + +static int __devinit bt866_init(void) +{ + i2c_add_driver(&i2c_driver_bt866); + return 0; +} + +static void __devexit bt866_exit(void) +{ + i2c_del_driver(&i2c_driver_bt866); +} + +module_init(bt866_init); +module_exit(bt866_exit); diff --git a/trunk/drivers/media/video/cx23885/cx23885-cards.c b/trunk/drivers/media/video/cx23885/cx23885-cards.c index dac5ccc9ba72..2cda15f829fd 100644 --- a/trunk/drivers/media/video/cx23885/cx23885-cards.c +++ b/trunk/drivers/media/video/cx23885/cx23885-cards.c @@ -39,16 +39,16 @@ struct cx23885_board cx23885_boards[] = { .input = {{ .type = CX23885_VMUX_COMPOSITE1, .vmux = 0, - }, { + },{ .type = CX23885_VMUX_COMPOSITE2, .vmux = 1, - }, { + },{ .type = CX23885_VMUX_COMPOSITE3, .vmux = 2, - }, { + },{ .type = CX23885_VMUX_COMPOSITE4, .vmux = 3, - } }, + }}, }, [CX23885_BOARD_HAUPPAUGE_HVR1800lp] = { .name = "Hauppauge WinTV-HVR1800lp", @@ -57,19 +57,19 @@ struct cx23885_board cx23885_boards[] = { .type = CX23885_VMUX_TELEVISION, .vmux = 0, .gpio0 = 0xff00, - }, { + },{ .type = CX23885_VMUX_DEBUG, .vmux = 0, .gpio0 = 0xff01, - }, { + },{ .type = CX23885_VMUX_COMPOSITE1, .vmux = 1, .gpio0 = 0xff02, - }, { + },{ .type = CX23885_VMUX_SVIDEO, .vmux = 2, .gpio0 = 0xff02, - } }, + }}, }, [CX23885_BOARD_HAUPPAUGE_HVR1800] = { .name = "Hauppauge WinTV-HVR1800", @@ -84,20 +84,20 @@ struct cx23885_board cx23885_boards[] = { CX25840_VIN5_CH2 | CX25840_VIN2_CH1, .gpio0 = 0, - }, { + },{ .type = CX23885_VMUX_COMPOSITE1, .vmux = CX25840_VIN7_CH3 | CX25840_VIN4_CH2 | CX25840_VIN6_CH1, .gpio0 = 0, - }, { + },{ .type = CX23885_VMUX_SVIDEO, .vmux = CX25840_VIN7_CH3 | CX25840_VIN4_CH2 | CX25840_VIN8_CH1 | CX25840_SVIDEO_ON, .gpio0 = 0, - } }, + }}, }, [CX23885_BOARD_HAUPPAUGE_HVR1250] = { .name = "Hauppauge WinTV-HVR1250", @@ -106,19 +106,19 @@ struct cx23885_board cx23885_boards[] = { .type = CX23885_VMUX_TELEVISION, .vmux = 0, .gpio0 = 0xff00, - }, { + },{ .type = CX23885_VMUX_DEBUG, .vmux = 0, .gpio0 = 0xff01, - }, { + },{ .type = CX23885_VMUX_COMPOSITE1, .vmux = 1, .gpio0 = 0xff02, - }, { + },{ .type = CX23885_VMUX_SVIDEO, .vmux = 2, .gpio0 = 0xff02, - } }, + }}, }, [CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP] = { .name = "DViCO FusionHDTV5 Express", @@ -169,43 +169,43 @@ struct cx23885_subid cx23885_subids[] = { .subvendor = 0x0070, .subdevice = 0x3400, .card = CX23885_BOARD_UNKNOWN, - }, { + },{ .subvendor = 0x0070, .subdevice = 0x7600, .card = CX23885_BOARD_HAUPPAUGE_HVR1800lp, - }, { + },{ .subvendor = 0x0070, .subdevice = 0x7800, .card = CX23885_BOARD_HAUPPAUGE_HVR1800, - }, { + },{ .subvendor = 0x0070, .subdevice = 0x7801, .card = CX23885_BOARD_HAUPPAUGE_HVR1800, - }, { + },{ .subvendor = 0x0070, .subdevice = 0x7809, .card = CX23885_BOARD_HAUPPAUGE_HVR1800, - }, { + },{ .subvendor = 0x0070, .subdevice = 0x7911, .card = CX23885_BOARD_HAUPPAUGE_HVR1250, - }, { + },{ .subvendor = 0x18ac, .subdevice = 0xd500, .card = CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP, - }, { + },{ .subvendor = 0x0070, .subdevice = 0x7790, .card = CX23885_BOARD_HAUPPAUGE_HVR1500Q, - }, { + },{ .subvendor = 0x0070, .subdevice = 0x7797, .card = CX23885_BOARD_HAUPPAUGE_HVR1500Q, - }, { + },{ .subvendor = 0x0070, .subdevice = 0x7710, .card = CX23885_BOARD_HAUPPAUGE_HVR1500, - }, { + },{ .subvendor = 0x0070, .subdevice = 0x7717, .card = CX23885_BOARD_HAUPPAUGE_HVR1500, @@ -225,11 +225,11 @@ struct cx23885_subid cx23885_subids[] = { .subvendor = 0x0070, .subdevice = 0x8010, .card = CX23885_BOARD_HAUPPAUGE_HVR1400, - }, { + },{ .subvendor = 0x18ac, .subdevice = 0xd618, .card = CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP, - }, { + },{ .subvendor = 0x18ac, .subdevice = 0xdb78, .card = CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP, @@ -247,25 +247,23 @@ void cx23885_card_list(struct cx23885_dev *dev) if (0 == dev->pci->subsystem_vendor && 0 == dev->pci->subsystem_device) { - printk(KERN_INFO - "%s: Board has no valid PCIe Subsystem ID and can't\n" - "%s: be autodetected. Pass card= insmod option\n" - "%s: to workaround that. Redirect complaints to the\n" - "%s: vendor of the TV card. Best regards,\n" + printk("%s: Your board has no valid PCIe Subsystem ID and thus can't\n" + "%s: be autodetected. Please pass card= insmod option to\n" + "%s: workaround that. Redirect complaints to the vendor of\n" + "%s: the TV card. Best regards,\n" "%s: -- tux\n", dev->name, dev->name, dev->name, dev->name, dev->name); } else { - printk(KERN_INFO - "%s: Your board isn't known (yet) to the driver.\n" - "%s: Try to pick one of the existing card configs via\n" + printk("%s: Your board isn't known (yet) to the driver. You can\n" + "%s: try to pick one of the existing card configs via\n" "%s: card= insmod option. Updating to the latest\n" "%s: version might help as well.\n", dev->name, dev->name, dev->name, dev->name); } - printk(KERN_INFO "%s: Here is a list of valid choices for the card= insmod option:\n", + printk("%s: Here is a list of valid choices for the card= insmod option:\n", dev->name); for (i = 0; i < cx23885_bcount; i++) - printk(KERN_INFO "%s: card=%d -> %s\n", + printk("%s: card=%d -> %s\n", dev->name, i, cx23885_boards[i].name); } @@ -273,11 +271,11 @@ static void hauppauge_eeprom(struct cx23885_dev *dev, u8 *eeprom_data) { struct tveeprom tv; - tveeprom_hauppauge_analog(&dev->i2c_bus[0].i2c_client, &tv, - eeprom_data); + tveeprom_hauppauge_analog(&dev->i2c_bus[0].i2c_client, &tv, eeprom_data); /* Make sure we support the board model */ - switch (tv.model) { + switch (tv.model) + { case 71009: /* WinTV-HVR1200 (PCIe, Retail, full height) * DVB-T and basic analog */ @@ -305,51 +303,21 @@ static void hauppauge_eeprom(struct cx23885_dev *dev, u8 *eeprom_data) case 71999: /* WinTV-HVR1200 (PCIe, OEM, full height) * DVB-T and basic analog */ - case 76601: - /* WinTV-HVR1800lp (PCIe, Retail, No IR, Dual - channel ATSC and MPEG2 HW Encoder */ - case 77001: - /* WinTV-HVR1500 (Express Card, OEM, No IR, ATSC - and Basic analog */ - case 77011: - /* WinTV-HVR1500 (Express Card, Retail, No IR, ATSC - and Basic analog */ - case 77041: - /* WinTV-HVR1500Q (Express Card, OEM, No IR, ATSC/QAM - and Basic analog */ - case 77051: - /* WinTV-HVR1500Q (Express Card, Retail, No IR, ATSC/QAM - and Basic analog */ - case 78011: - /* WinTV-HVR1800 (PCIe, Retail, 3.5mm in, IR, No FM, - Dual channel ATSC and MPEG2 HW Encoder */ - case 78501: - /* WinTV-HVR1800 (PCIe, OEM, RCA in, No IR, FM, - Dual channel ATSC and MPEG2 HW Encoder */ - case 78521: - /* WinTV-HVR1800 (PCIe, OEM, RCA in, No IR, FM, - Dual channel ATSC and MPEG2 HW Encoder */ - case 78531: - /* WinTV-HVR1800 (PCIe, OEM, RCA in, No IR, No FM, - Dual channel ATSC and MPEG2 HW Encoder */ - case 78631: - /* WinTV-HVR1800 (PCIe, OEM, No IR, No FM, - Dual channel ATSC and MPEG2 HW Encoder */ - case 79001: - /* WinTV-HVR1250 (PCIe, Retail, IR, full height, - ATSC and Basic analog */ - case 79101: - /* WinTV-HVR1250 (PCIe, Retail, IR, half height, - ATSC and Basic analog */ - case 79561: - /* WinTV-HVR1250 (PCIe, OEM, No IR, half height, - ATSC and Basic analog */ - case 79571: - /* WinTV-HVR1250 (PCIe, OEM, No IR, full height, - ATSC and Basic analog */ - case 79671: - /* WinTV-HVR1250 (PCIe, OEM, No IR, half height, - ATSC and Basic analog */ + case 76601: /* WinTV-HVR1800lp (PCIe, Retail, No IR, Dual channel ATSC and MPEG2 HW Encoder */ + case 77001: /* WinTV-HVR1500 (Express Card, OEM, No IR, ATSC and Basic analog */ + case 77011: /* WinTV-HVR1500 (Express Card, Retail, No IR, ATSC and Basic analog */ + case 77041: /* WinTV-HVR1500Q (Express Card, OEM, No IR, ATSC/QAM and Basic analog */ + case 77051: /* WinTV-HVR1500Q (Express Card, Retail, No IR, ATSC/QAM and Basic analog */ + case 78011: /* WinTV-HVR1800 (PCIe, Retail, 3.5mm in, IR, No FM, Dual channel ATSC and MPEG2 HW Encoder */ + case 78501: /* WinTV-HVR1800 (PCIe, OEM, RCA in, No IR, FM, Dual channel ATSC and MPEG2 HW Encoder */ + case 78521: /* WinTV-HVR1800 (PCIe, OEM, RCA in, No IR, FM, Dual channel ATSC and MPEG2 HW Encoder */ + case 78531: /* WinTV-HVR1800 (PCIe, OEM, RCA in, No IR, No FM, Dual channel ATSC and MPEG2 HW Encoder */ + case 78631: /* WinTV-HVR1800 (PCIe, OEM, No IR, No FM, Dual channel ATSC and MPEG2 HW Encoder */ + case 79001: /* WinTV-HVR1250 (PCIe, Retail, IR, full height, ATSC and Basic analog */ + case 79101: /* WinTV-HVR1250 (PCIe, Retail, IR, half height, ATSC and Basic analog */ + case 79561: /* WinTV-HVR1250 (PCIe, OEM, No IR, half height, ATSC and Basic analog */ + case 79571: /* WinTV-HVR1250 (PCIe, OEM, No IR, full height, ATSC and Basic analog */ + case 79671: /* WinTV-HVR1250 (PCIe, OEM, No IR, half height, ATSC and Basic analog */ case 80019: /* WinTV-HVR1400 (Express Card, Retail, IR, * DVB-T and Basic analog */ @@ -361,8 +329,7 @@ static void hauppauge_eeprom(struct cx23885_dev *dev, u8 *eeprom_data) * DVB-T and MPEG2 HW Encoder */ break; default: - printk(KERN_WARNING "%s: warning: unknown hauppauge model #%d\n", - dev->name, tv.model); + printk("%s: warning: unknown hauppauge model #%d\n", dev->name, tv.model); break; } @@ -385,7 +352,7 @@ int cx23885_tuner_callback(void *priv, int component, int command, int arg) return -EINVAL; } - switch (dev->board) { + switch(dev->board) { case CX23885_BOARD_HAUPPAUGE_HVR1400: case CX23885_BOARD_HAUPPAUGE_HVR1500: case CX23885_BOARD_HAUPPAUGE_HVR1500Q: @@ -416,7 +383,7 @@ int cx23885_tuner_callback(void *priv, int component, int command, int arg) void cx23885_gpio_setup(struct cx23885_dev *dev) { - switch (dev->board) { + switch(dev->board) { case CX23885_BOARD_HAUPPAUGE_HVR1250: /* GPIO-0 cx24227 demodulator reset */ cx_set(GP0_IO, 0x00010001); /* Bring the part out of reset */ @@ -650,3 +617,10 @@ void cx23885_card_setup(struct cx23885_dev *dev) } /* ------------------------------------------------------------------ */ + +/* + * Local variables: + * c-basic-offset: 8 + * End: + * 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 + */ diff --git a/trunk/drivers/media/video/cx23885/cx23885-core.c b/trunk/drivers/media/video/cx23885/cx23885-core.c index 8f6fb2add7de..beb3e61669a3 100644 --- a/trunk/drivers/media/video/cx23885/cx23885-core.c +++ b/trunk/drivers/media/video/cx23885/cx23885-core.c @@ -37,12 +37,12 @@ MODULE_AUTHOR("Steven Toth "); MODULE_LICENSE("GPL"); static unsigned int debug; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "enable debug messages"); +module_param(debug,int,0644); +MODULE_PARM_DESC(debug,"enable debug messages"); static unsigned int card[] = {[0 ... (CX23885_MAXBOARDS - 1)] = UNSET }; module_param_array(card, int, NULL, 0444); -MODULE_PARM_DESC(card, "card type"); +MODULE_PARM_DESC(card,"card type"); #define dprintk(level, fmt, arg...)\ do { if (debug >= level)\ @@ -364,12 +364,13 @@ void cx23885_wakeup(struct cx23885_tsport *port, list_del(&buf->vb.queue); wake_up(&buf->vb.done); } - if (list_empty(&q->active)) + if (list_empty(&q->active)) { del_timer(&q->timeout); - else + } else { mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT); + } if (bc != 1) - printk(KERN_WARNING "%s: %d buffers handled (should be 1)\n", + printk("%s: %d buffers handled (should be 1)\n", __func__, bc); } @@ -380,7 +381,8 @@ int cx23885_sram_channel_setup(struct cx23885_dev *dev, unsigned int i, lines; u32 cdt; - if (ch->cmds_start == 0) { + if (ch->cmds_start == 0) + { dprintk(1, "%s() Erasing channel [%s]\n", __func__, ch->name); cx_write(ch->ptr1_reg, 0); @@ -416,15 +418,15 @@ int cx23885_sram_channel_setup(struct cx23885_dev *dev, /* write CMDS */ if (ch->jumponly) - cx_write(ch->cmds_start + 0, 8); + cx_write(ch->cmds_start + 0, 8); else - cx_write(ch->cmds_start + 0, risc); + cx_write(ch->cmds_start + 0, risc); cx_write(ch->cmds_start + 4, 0); /* 64 bits 63-32 */ cx_write(ch->cmds_start + 8, cdt); cx_write(ch->cmds_start + 12, (lines*16) >> 3); cx_write(ch->cmds_start + 16, ch->ctrl_start); if (ch->jumponly) - cx_write(ch->cmds_start + 20, 0x80000000 | (64 >> 2)); + cx_write(ch->cmds_start + 20, 0x80000000 | (64 >> 2) ); else cx_write(ch->cmds_start + 20, 64 >> 2); for (i = 24; i < 80; i += 4) @@ -434,9 +436,9 @@ int cx23885_sram_channel_setup(struct cx23885_dev *dev, cx_write(ch->ptr1_reg, ch->fifo_start); cx_write(ch->ptr2_reg, cdt); cx_write(ch->cnt2_reg, (lines*16) >> 3); - cx_write(ch->cnt1_reg, (bpl >> 3) - 1); + cx_write(ch->cnt1_reg, (bpl >> 3) -1); - dprintk(2, "[bridge %d] sram setup %s: bpl=%d lines=%d\n", + dprintk(2,"[bridge %d] sram setup %s: bpl=%d lines=%d\n", dev->bridge, ch->name, bpl, @@ -467,43 +469,43 @@ void cx23885_sram_channel_dump(struct cx23885_dev *dev, u32 risc; unsigned int i, j, n; - printk(KERN_WARNING "%s: %s - dma channel status dump\n", + printk("%s: %s - dma channel status dump\n", dev->name, ch->name); for (i = 0; i < ARRAY_SIZE(name); i++) - printk(KERN_WARNING "%s: cmds: %-15s: 0x%08x\n", + printk("%s: cmds: %-15s: 0x%08x\n", dev->name, name[i], cx_read(ch->cmds_start + 4*i)); for (i = 0; i < 4; i++) { risc = cx_read(ch->cmds_start + 4 * (i + 14)); - printk(KERN_WARNING "%s: risc%d: ", dev->name, i); + printk("%s: risc%d: ", dev->name, i); cx23885_risc_decode(risc); } for (i = 0; i < (64 >> 2); i += n) { risc = cx_read(ch->ctrl_start + 4 * i); /* No consideration for bits 63-32 */ - printk(KERN_WARNING "%s: (0x%08x) iq %x: ", dev->name, + printk("%s: (0x%08x) iq %x: ", dev->name, ch->ctrl_start + 4 * i, i); n = cx23885_risc_decode(risc); for (j = 1; j < n; j++) { risc = cx_read(ch->ctrl_start + 4 * (i + j)); - printk(KERN_WARNING "%s: iq %x: 0x%08x [ arg #%d ]\n", + printk("%s: iq %x: 0x%08x [ arg #%d ]\n", dev->name, i+j, risc, j); } } - printk(KERN_WARNING "%s: fifo: 0x%08x -> 0x%x\n", + printk("%s: fifo: 0x%08x -> 0x%x\n", dev->name, ch->fifo_start, ch->fifo_start+ch->fifo_size); - printk(KERN_WARNING "%s: ctrl: 0x%08x -> 0x%x\n", + printk("%s: ctrl: 0x%08x -> 0x%x\n", dev->name, ch->ctrl_start, ch->ctrl_start + 6*16); - printk(KERN_WARNING "%s: ptr1_reg: 0x%08x\n", + printk("%s: ptr1_reg: 0x%08x\n", dev->name, cx_read(ch->ptr1_reg)); - printk(KERN_WARNING "%s: ptr2_reg: 0x%08x\n", + printk("%s: ptr2_reg: 0x%08x\n", dev->name, cx_read(ch->ptr2_reg)); - printk(KERN_WARNING "%s: cnt1_reg: 0x%08x\n", + printk("%s: cnt1_reg: 0x%08x\n", dev->name, cx_read(ch->cnt1_reg)); - printk(KERN_WARNING "%s: cnt2_reg: 0x%08x\n", + printk("%s: cnt2_reg: 0x%08x\n", dev->name, cx_read(ch->cnt2_reg)); } @@ -513,13 +515,13 @@ static void cx23885_risc_disasm(struct cx23885_tsport *port, struct cx23885_dev *dev = port->dev; unsigned int i, j, n; - printk(KERN_INFO "%s: risc disasm: %p [dma=0x%08lx]\n", + printk("%s: risc disasm: %p [dma=0x%08lx]\n", dev->name, risc->cpu, (unsigned long)risc->dma); for (i = 0; i < (risc->size >> 2); i += n) { - printk(KERN_INFO "%s: %04d: ", dev->name, i); + printk("%s: %04d: ", dev->name, i); n = cx23885_risc_decode(le32_to_cpu(risc->cpu[i])); for (j = 1; j < n; j++) - printk(KERN_INFO "%s: %04d: 0x%08x [ arg #%d ]\n", + printk("%s: %04d: 0x%08x [ arg #%d ]\n", dev->name, i + j, risc->cpu[i + j], j); if (risc->cpu[i] == cpu_to_le32(RISC_JUMP)) break; @@ -598,7 +600,7 @@ static int cx23885_pci_quirks(struct cx23885_dev *dev) * when DMA begins if RDR_TLCTL0 bit4 is not cleared. It does not * occur on the cx23887 bridge. */ - if (dev->bridge == CX23885_BRIDGE_885) + if(dev->bridge == CX23885_BRIDGE_885) cx_clear(RDR_TLCTL0, 1 << 4); return 0; @@ -606,13 +608,13 @@ static int cx23885_pci_quirks(struct cx23885_dev *dev) static int get_resources(struct cx23885_dev *dev) { - if (request_mem_region(pci_resource_start(dev->pci, 0), - pci_resource_len(dev->pci, 0), + if (request_mem_region(pci_resource_start(dev->pci,0), + pci_resource_len(dev->pci,0), dev->name)) return 0; printk(KERN_ERR "%s: can't get MMIO memory @ 0x%llx\n", - dev->name, (unsigned long long)pci_resource_start(dev->pci, 0)); + dev->name, (unsigned long long)pci_resource_start(dev->pci,0)); return -EBUSY; } @@ -621,8 +623,7 @@ static void cx23885_timeout(unsigned long data); int cx23885_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc, u32 reg, u32 mask, u32 value); -static int cx23885_init_tsport(struct cx23885_dev *dev, - struct cx23885_tsport *port, int portno) +static int cx23885_init_tsport(struct cx23885_dev *dev, struct cx23885_tsport *port, int portno) { dprintk(1, "%s(portno=%d)\n", __func__, portno); @@ -642,18 +643,7 @@ static int cx23885_init_tsport(struct cx23885_dev *dev, port->mpegq.timeout.data = (unsigned long)port; init_timer(&port->mpegq.timeout); - mutex_init(&port->frontends.lock); - INIT_LIST_HEAD(&port->frontends.felist); - port->frontends.active_fe_id = 0; - - /* This should be hardcoded allow a single frontend - * attachment to this tsport, keeping the -dvb.c - * code clean and safe. - */ - if (!port->num_frontends) - port->num_frontends = 1; - - switch (portno) { + switch(portno) { case 1: port->reg_gpcnt = VID_B_GPCNT; port->reg_gpcnt_ctl = VID_B_GPCNT_CTL; @@ -754,13 +744,13 @@ static int cx23885_dev_setup(struct cx23885_dev *dev) mutex_unlock(&devlist); /* Configure the internal memory */ - if (dev->pci->device == 0x8880) { + if(dev->pci->device == 0x8880) { dev->bridge = CX23885_BRIDGE_887; /* Apply a sensible clock frequency for the PCIe bridge */ dev->clk_freq = 25000000; dev->sram_channels = cx23887_sram_channels; } else - if (dev->pci->device == 0x8852) { + if(dev->pci->device == 0x8852) { dev->bridge = CX23885_BRIDGE_885; /* Apply a sensible clock frequency for the PCIe bridge */ dev->clk_freq = 28000000; @@ -841,8 +831,8 @@ static int cx23885_dev_setup(struct cx23885_dev *dev) } /* PCIe stuff */ - dev->lmmio = ioremap(pci_resource_start(dev->pci, 0), - pci_resource_len(dev->pci, 0)); + dev->lmmio = ioremap(pci_resource_start(dev->pci,0), + pci_resource_len(dev->pci,0)); dev->bmmio = (u8 __iomem *)dev->lmmio; @@ -872,7 +862,7 @@ static int cx23885_dev_setup(struct cx23885_dev *dev) cx23885_i2c_register(&dev->i2c_bus[1]); cx23885_i2c_register(&dev->i2c_bus[2]); cx23885_card_setup(dev); - cx23885_call_i2c_clients(&dev->i2c_bus[0], TUNER_SET_STANDBY, NULL); + cx23885_call_i2c_clients (&dev->i2c_bus[0], TUNER_SET_STANDBY, NULL); cx23885_ir_init(dev); if (cx23885_boards[dev->board].porta == CX23885_ANALOG_VIDEO) { @@ -918,8 +908,8 @@ static int cx23885_dev_setup(struct cx23885_dev *dev) static void cx23885_dev_unregister(struct cx23885_dev *dev) { - release_mem_region(pci_resource_start(dev->pci, 0), - pci_resource_len(dev->pci, 0)); + release_mem_region(pci_resource_start(dev->pci,0), + pci_resource_len(dev->pci,0)); if (!atomic_dec_and_test(&dev->refcount)) return; @@ -946,7 +936,7 @@ static void cx23885_dev_unregister(struct cx23885_dev *dev) iounmap(dev->lmmio); } -static __le32 *cx23885_risc_field(__le32 *rp, struct scatterlist *sglist, +static __le32* cx23885_risc_field(__le32 *rp, struct scatterlist *sglist, unsigned int offset, u32 sync_line, unsigned int bpl, unsigned int padding, unsigned int lines) @@ -967,31 +957,31 @@ static __le32 *cx23885_risc_field(__le32 *rp, struct scatterlist *sglist, } if (bpl <= sg_dma_len(sg)-offset) { /* fits into current chunk */ - *(rp++) = cpu_to_le32(RISC_WRITE|RISC_SOL|RISC_EOL|bpl); - *(rp++) = cpu_to_le32(sg_dma_address(sg)+offset); - *(rp++) = cpu_to_le32(0); /* bits 63-32 */ - offset += bpl; + *(rp++)=cpu_to_le32(RISC_WRITE|RISC_SOL|RISC_EOL|bpl); + *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset); + *(rp++)=cpu_to_le32(0); /* bits 63-32 */ + offset+=bpl; } else { /* scanline needs to be split */ todo = bpl; - *(rp++) = cpu_to_le32(RISC_WRITE|RISC_SOL| + *(rp++)=cpu_to_le32(RISC_WRITE|RISC_SOL| (sg_dma_len(sg)-offset)); - *(rp++) = cpu_to_le32(sg_dma_address(sg)+offset); - *(rp++) = cpu_to_le32(0); /* bits 63-32 */ + *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset); + *(rp++)=cpu_to_le32(0); /* bits 63-32 */ todo -= (sg_dma_len(sg)-offset); offset = 0; sg++; while (todo > sg_dma_len(sg)) { - *(rp++) = cpu_to_le32(RISC_WRITE| + *(rp++)=cpu_to_le32(RISC_WRITE| sg_dma_len(sg)); - *(rp++) = cpu_to_le32(sg_dma_address(sg)); - *(rp++) = cpu_to_le32(0); /* bits 63-32 */ + *(rp++)=cpu_to_le32(sg_dma_address(sg)); + *(rp++)=cpu_to_le32(0); /* bits 63-32 */ todo -= sg_dma_len(sg); sg++; } - *(rp++) = cpu_to_le32(RISC_WRITE|RISC_EOL|todo); - *(rp++) = cpu_to_le32(sg_dma_address(sg)); - *(rp++) = cpu_to_le32(0); /* bits 63-32 */ + *(rp++)=cpu_to_le32(RISC_WRITE|RISC_EOL|todo); + *(rp++)=cpu_to_le32(sg_dma_address(sg)); + *(rp++)=cpu_to_le32(0); /* bits 63-32 */ offset += todo; } offset += padding; @@ -1020,11 +1010,9 @@ int cx23885_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc, can cause next bpl to start close to a page border. First DMA region may be smaller than PAGE_SIZE */ /* write and jump need and extra dword */ - instructions = fields * (1 + ((bpl + padding) * lines) - / PAGE_SIZE + lines); + instructions = fields * (1 + ((bpl + padding) * lines) / PAGE_SIZE + lines); instructions += 2; - rc = btcx_riscmem_alloc(pci, risc, instructions*12); - if (rc < 0) + if ((rc = btcx_riscmem_alloc(pci,risc,instructions*12)) < 0) return rc; /* write risc instructions */ @@ -1038,7 +1026,7 @@ int cx23885_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc, /* save pointer to jmp instruction address */ risc->jmp = rp; - BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size); + BUG_ON((risc->jmp - risc->cpu + 2) * sizeof (*risc->cpu) > risc->size); return 0; } @@ -1060,8 +1048,7 @@ static int cx23885_risc_databuffer(struct pci_dev *pci, instructions = 1 + (bpl * lines) / PAGE_SIZE + lines; instructions += 1; - rc = btcx_riscmem_alloc(pci, risc, instructions*12); - if (rc < 0) + if ((rc = btcx_riscmem_alloc(pci,risc,instructions*12)) < 0) return rc; /* write risc instructions */ @@ -1070,7 +1057,7 @@ static int cx23885_risc_databuffer(struct pci_dev *pci, /* save pointer to jmp instruction address */ risc->jmp = rp; - BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size); + BUG_ON((risc->jmp - risc->cpu + 2) * sizeof (*risc->cpu) > risc->size); return 0; } @@ -1080,8 +1067,7 @@ int cx23885_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc, __le32 *rp; int rc; - rc = btcx_riscmem_alloc(pci, risc, 4*16); - if (rc < 0) + if ((rc = btcx_riscmem_alloc(pci, risc, 4*16)) < 0) return rc; /* write risc instructions */ @@ -1175,23 +1161,22 @@ static int cx23885_start_dma(struct cx23885_tsport *port, /* setup fifo + format */ cx23885_sram_channel_setup(dev, - &dev->sram_channels[port->sram_chno], + &dev->sram_channels[ port->sram_chno ], port->ts_packet_size, buf->risc.dma); - if (debug > 5) { - cx23885_sram_channel_dump(dev, - &dev->sram_channels[port->sram_chno]); + if(debug > 5) { + cx23885_sram_channel_dump(dev, &dev->sram_channels[ port->sram_chno ] ); cx23885_risc_disasm(port, &buf->risc); } /* write TS length to chip */ cx_write(port->reg_lngth, buf->vb.width); - if ((!(cx23885_boards[dev->board].portb & CX23885_MPEG_DVB)) && - (!(cx23885_boards[dev->board].portc & CX23885_MPEG_DVB))) { - printk("%s() Unsupported .portb/c (0x%08x)/(0x%08x)\n", + if ( (!(cx23885_boards[dev->board].portb & CX23885_MPEG_DVB)) && + (!(cx23885_boards[dev->board].portc & CX23885_MPEG_DVB)) ) { + printk( "%s() Failed. Unsupported value in .portb/c (0x%08x)/(0x%08x)\n", __func__, cx23885_boards[dev->board].portb, - cx23885_boards[dev->board].portc); + cx23885_boards[dev->board].portc ); return -EINVAL; } @@ -1201,7 +1186,7 @@ static int cx23885_start_dma(struct cx23885_tsport *port, udelay(100); /* If the port supports SRC SELECT, configure it */ - if (port->reg_src_sel) + if(port->reg_src_sel) cx_write(port->reg_src_sel, port->src_sel_val); cx_write(port->reg_hw_sop_ctrl, port->hw_sop_ctrl_val); @@ -1210,7 +1195,7 @@ static int cx23885_start_dma(struct cx23885_tsport *port, cx_write(port->reg_gen_ctrl, port->gen_ctrl_val); udelay(100); - /* NOTE: this is 2 (reserved) for portb, does it matter? */ + // NOTE: this is 2 (reserved) for portb, does it matter? /* reset counter to zero */ cx_write(port->reg_gpcnt_ctl, 3); q->count = 1; @@ -1244,11 +1229,11 @@ static int cx23885_start_dma(struct cx23885_tsport *port, cx_write(ALT_PIN_OUT_SEL, 0x10100045); } - switch (dev->bridge) { + switch(dev->bridge) { case CX23885_BRIDGE_885: case CX23885_BRIDGE_887: /* enable irqs */ - dprintk(1, "%s() enabling TS int's and DMA\n", __func__); + dprintk(1, "%s() enabling TS int's and DMA\n", __func__ ); cx_set(port->reg_ts_int_msk, port->ts_int_msk_val); cx_set(port->reg_dma_ctl, port->dma_ctl_val); cx_set(PCI_INT_MSK, dev->pci_irqmask | port->pci_irqmask); @@ -1307,7 +1292,8 @@ int cx23885_restart_queue(struct cx23885_tsport *port, struct cx23885_buffer *buf; dprintk(5, "%s()\n", __func__); - if (list_empty(&q->active)) { + if (list_empty(&q->active)) + { struct cx23885_buffer *prev; prev = NULL; @@ -1325,7 +1311,7 @@ int cx23885_restart_queue(struct cx23885_tsport *port, buf->vb.state = VIDEOBUF_ACTIVE; buf->count = q->count++; mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); - dprintk(5, "[%p/%d] restart_queue - f/active\n", + dprintk(5, "[%p/%d] restart_queue - first active\n", buf, buf->vb.i); } else if (prev->vb.width == buf->vb.width && @@ -1336,9 +1322,8 @@ int cx23885_restart_queue(struct cx23885_tsport *port, buf->vb.state = VIDEOBUF_ACTIVE; buf->count = q->count++; prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); - /* 64 bit bits 63-32 */ - prev->risc.jmp[2] = cpu_to_le32(0); - dprintk(5, "[%p/%d] restart_queue - m/active\n", + prev->risc.jmp[2] = cpu_to_le32(0); /* 64 bit bits 63-32 */ + dprintk(5,"[%p/%d] restart_queue - move to active\n", buf, buf->vb.i); } else { return 0; @@ -1377,8 +1362,7 @@ int cx23885_buf_prepare(struct videobuf_queue *q, struct cx23885_tsport *port, buf->vb.size = size; buf->vb.field = field /*V4L2_FIELD_TOP*/; - rc = videobuf_iolock(q, &buf->vb, NULL); - if (0 != rc) + if (0 != (rc = videobuf_iolock(q, &buf->vb, NULL))) goto fail; cx23885_risc_databuffer(dev->pci, &buf->risc, videobuf_to_dma(&buf->vb)->sglist, @@ -1404,7 +1388,7 @@ void cx23885_buf_queue(struct cx23885_tsport *port, struct cx23885_buffer *buf) buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */ if (list_empty(&cx88q->active)) { - dprintk(1, "queue is empty - first active\n"); + dprintk( 1, "queue is empty - first active\n" ); list_add_tail(&buf->vb.queue, &cx88q->active); cx23885_start_dma(port, cx88q, buf); buf->vb.state = VIDEOBUF_ACTIVE; @@ -1413,7 +1397,7 @@ void cx23885_buf_queue(struct cx23885_tsport *port, struct cx23885_buffer *buf) dprintk(1, "[%p/%d] %s - first active\n", buf, buf->vb.i, __func__); } else { - dprintk(1, "queue is not empty - append to active\n"); + dprintk( 1, "queue is not empty - append to active\n" ); prev = list_entry(cx88q->active.prev, struct cx23885_buffer, vb.queue); list_add_tail(&buf->vb.queue, &cx88q->active); @@ -1421,7 +1405,7 @@ void cx23885_buf_queue(struct cx23885_tsport *port, struct cx23885_buffer *buf) buf->count = cx88q->count++; prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); prev->risc.jmp[2] = cpu_to_le32(0); /* 64 bit bits 63-32 */ - dprintk(1, "[%p/%d] %s - append to active\n", + dprintk( 1, "[%p/%d] %s - append to active\n", buf, buf->vb.i, __func__); } } @@ -1447,7 +1431,7 @@ static void do_cancel_buffers(struct cx23885_tsport *port, char *reason, buf, buf->vb.i, reason, (unsigned long)buf->risc.dma); } if (restart) { - dprintk(1, "restarting queue\n"); + dprintk(1, "restarting queue\n" ); cx23885_restart_queue(port, q); } spin_unlock_irqrestore(&port->slock, flags); @@ -1469,11 +1453,10 @@ static void cx23885_timeout(unsigned long data) struct cx23885_tsport *port = (struct cx23885_tsport *)data; struct cx23885_dev *dev = port->dev; - dprintk(1, "%s()\n", __func__); + dprintk(1, "%s()\n",__func__); if (debug > 5) - cx23885_sram_channel_dump(dev, - &dev->sram_channels[port->sram_chno]); + cx23885_sram_channel_dump(dev, &dev->sram_channels[ port->sram_chno ]); cx23885_stop_dma(port); do_cancel_buffers(port, "timeout", 1); @@ -1549,23 +1532,16 @@ static int cx23885_irq_ts(struct cx23885_tsport *port, u32 status) if ((status & VID_BC_MSK_OPC_ERR) || (status & VID_BC_MSK_BAD_PKT) || (status & VID_BC_MSK_SYNC) || - (status & VID_BC_MSK_OF)) { - + (status & VID_BC_MSK_OF)) + { if (status & VID_BC_MSK_OPC_ERR) - dprintk(7, " (VID_BC_MSK_OPC_ERR 0x%08x)\n", - VID_BC_MSK_OPC_ERR); - + dprintk(7, " (VID_BC_MSK_OPC_ERR 0x%08x)\n", VID_BC_MSK_OPC_ERR); if (status & VID_BC_MSK_BAD_PKT) - dprintk(7, " (VID_BC_MSK_BAD_PKT 0x%08x)\n", - VID_BC_MSK_BAD_PKT); - + dprintk(7, " (VID_BC_MSK_BAD_PKT 0x%08x)\n", VID_BC_MSK_BAD_PKT); if (status & VID_BC_MSK_SYNC) - dprintk(7, " (VID_BC_MSK_SYNC 0x%08x)\n", - VID_BC_MSK_SYNC); - + dprintk(7, " (VID_BC_MSK_SYNC 0x%08x)\n", VID_BC_MSK_SYNC); if (status & VID_BC_MSK_OF) - dprintk(7, " (VID_BC_MSK_OF 0x%08x)\n", - VID_BC_MSK_OF); + dprintk(7, " (VID_BC_MSK_OF 0x%08x)\n", VID_BC_MSK_OF); printk(KERN_ERR "%s: mpeg risc op code error\n", dev->name); @@ -1619,7 +1595,7 @@ static irqreturn_t cx23885_irq(int irq, void *dev_id) ts2_status = cx_read(VID_C_INT_STAT); ts2_mask = cx_read(VID_C_INT_MSK); - if ((pci_status == 0) && (ts2_status == 0) && (ts1_status == 0)) + if ( (pci_status == 0) && (ts2_status == 0) && (ts1_status == 0) ) goto out; vida_count = cx_read(VID_A_GPCNT); @@ -1634,56 +1610,38 @@ static irqreturn_t cx23885_irq(int irq, void *dev_id) dprintk(7, "ts2_status: 0x%08x ts2_mask: 0x%08x count: 0x%x\n", ts2_status, ts2_mask, ts2_count); - if ((pci_status & PCI_MSK_RISC_RD) || - (pci_status & PCI_MSK_RISC_WR) || - (pci_status & PCI_MSK_AL_RD) || - (pci_status & PCI_MSK_AL_WR) || - (pci_status & PCI_MSK_APB_DMA) || - (pci_status & PCI_MSK_VID_C) || - (pci_status & PCI_MSK_VID_B) || - (pci_status & PCI_MSK_VID_A) || - (pci_status & PCI_MSK_AUD_INT) || - (pci_status & PCI_MSK_AUD_EXT)) { + if ( (pci_status & PCI_MSK_RISC_RD) || + (pci_status & PCI_MSK_RISC_WR) || + (pci_status & PCI_MSK_AL_RD) || + (pci_status & PCI_MSK_AL_WR) || + (pci_status & PCI_MSK_APB_DMA) || + (pci_status & PCI_MSK_VID_C) || + (pci_status & PCI_MSK_VID_B) || + (pci_status & PCI_MSK_VID_A) || + (pci_status & PCI_MSK_AUD_INT) || + (pci_status & PCI_MSK_AUD_EXT) ) + { if (pci_status & PCI_MSK_RISC_RD) - dprintk(7, " (PCI_MSK_RISC_RD 0x%08x)\n", - PCI_MSK_RISC_RD); - + dprintk(7, " (PCI_MSK_RISC_RD 0x%08x)\n", PCI_MSK_RISC_RD); if (pci_status & PCI_MSK_RISC_WR) - dprintk(7, " (PCI_MSK_RISC_WR 0x%08x)\n", - PCI_MSK_RISC_WR); - + dprintk(7, " (PCI_MSK_RISC_WR 0x%08x)\n", PCI_MSK_RISC_WR); if (pci_status & PCI_MSK_AL_RD) - dprintk(7, " (PCI_MSK_AL_RD 0x%08x)\n", - PCI_MSK_AL_RD); - + dprintk(7, " (PCI_MSK_AL_RD 0x%08x)\n", PCI_MSK_AL_RD); if (pci_status & PCI_MSK_AL_WR) - dprintk(7, " (PCI_MSK_AL_WR 0x%08x)\n", - PCI_MSK_AL_WR); - + dprintk(7, " (PCI_MSK_AL_WR 0x%08x)\n", PCI_MSK_AL_WR); if (pci_status & PCI_MSK_APB_DMA) - dprintk(7, " (PCI_MSK_APB_DMA 0x%08x)\n", - PCI_MSK_APB_DMA); - + dprintk(7, " (PCI_MSK_APB_DMA 0x%08x)\n", PCI_MSK_APB_DMA); if (pci_status & PCI_MSK_VID_C) - dprintk(7, " (PCI_MSK_VID_C 0x%08x)\n", - PCI_MSK_VID_C); - + dprintk(7, " (PCI_MSK_VID_C 0x%08x)\n", PCI_MSK_VID_C); if (pci_status & PCI_MSK_VID_B) - dprintk(7, " (PCI_MSK_VID_B 0x%08x)\n", - PCI_MSK_VID_B); - + dprintk(7, " (PCI_MSK_VID_B 0x%08x)\n", PCI_MSK_VID_B); if (pci_status & PCI_MSK_VID_A) - dprintk(7, " (PCI_MSK_VID_A 0x%08x)\n", - PCI_MSK_VID_A); - + dprintk(7, " (PCI_MSK_VID_A 0x%08x)\n", PCI_MSK_VID_A); if (pci_status & PCI_MSK_AUD_INT) - dprintk(7, " (PCI_MSK_AUD_INT 0x%08x)\n", - PCI_MSK_AUD_INT); - + dprintk(7, " (PCI_MSK_AUD_INT 0x%08x)\n", PCI_MSK_AUD_INT); if (pci_status & PCI_MSK_AUD_EXT) - dprintk(7, " (PCI_MSK_AUD_EXT 0x%08x)\n", - PCI_MSK_AUD_EXT); + dprintk(7, " (PCI_MSK_AUD_EXT 0x%08x)\n", PCI_MSK_AUD_EXT); } @@ -1795,13 +1753,13 @@ static struct pci_device_id cx23885_pci_tbl[] = { .device = 0x8852, .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, - }, { + },{ /* CX23887 Rev 2 */ .vendor = 0x14f1, .device = 0x8880, .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, - }, { + },{ /* --- end of list --- */ } }; @@ -1839,3 +1797,9 @@ module_init(cx23885_init); module_exit(cx23885_fini); /* ----------------------------------------------------------- */ +/* + * Local variables: + * c-basic-offset: 8 + * End: + * 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 + */ diff --git a/trunk/drivers/media/video/cx23885/cx23885-dvb.c b/trunk/drivers/media/video/cx23885/cx23885-dvb.c index e1aac07b3158..24bd18327aa0 100644 --- a/trunk/drivers/media/video/cx23885/cx23885-dvb.c +++ b/trunk/drivers/media/video/cx23885/cx23885-dvb.c @@ -78,19 +78,19 @@ static int dvb_buf_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, enum v4l2_field field) { struct cx23885_tsport *port = q->priv_data; - return cx23885_buf_prepare(q, port, (struct cx23885_buffer *)vb, field); + return cx23885_buf_prepare(q, port, (struct cx23885_buffer*)vb, field); } static void dvb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb) { struct cx23885_tsport *port = q->priv_data; - cx23885_buf_queue(port, (struct cx23885_buffer *)vb); + cx23885_buf_queue(port, (struct cx23885_buffer*)vb); } static void dvb_buf_release(struct videobuf_queue *q, struct videobuf_buffer *vb) { - cx23885_free_buffer(q, (struct cx23885_buffer *)vb); + cx23885_free_buffer(q, (struct cx23885_buffer*)vb); } static struct videobuf_queue_ops dvb_qops = { @@ -312,25 +312,19 @@ static int dvb_register(struct cx23885_tsport *port) { struct cx23885_dev *dev = port->dev; struct cx23885_i2c *i2c_bus = NULL; - struct videobuf_dvb_frontend *fe0; - - /* Get the first frontend */ - fe0 = videobuf_dvb_get_frontend(&port->frontends, 1); - if (!fe0) - return -EINVAL; /* init struct videobuf_dvb */ - fe0->dvb.name = dev->name; + port->dvb.name = dev->name; /* init frontend */ switch (dev->board) { case CX23885_BOARD_HAUPPAUGE_HVR1250: i2c_bus = &dev->i2c_bus[0]; - fe0->dvb.frontend = dvb_attach(s5h1409_attach, + port->dvb.frontend = dvb_attach(s5h1409_attach, &hauppauge_generic_config, &i2c_bus->i2c_adap); - if (fe0->dvb.frontend != NULL) { - dvb_attach(mt2131_attach, fe0->dvb.frontend, + if (port->dvb.frontend != NULL) { + dvb_attach(mt2131_attach, port->dvb.frontend, &i2c_bus->i2c_adap, &hauppauge_generic_tunerconfig, 0); } @@ -339,27 +333,27 @@ static int dvb_register(struct cx23885_tsport *port) i2c_bus = &dev->i2c_bus[0]; switch (alt_tuner) { case 1: - fe0->dvb.frontend = + port->dvb.frontend = dvb_attach(s5h1409_attach, &hauppauge_ezqam_config, &i2c_bus->i2c_adap); - if (fe0->dvb.frontend != NULL) { - dvb_attach(tda829x_attach, fe0->dvb.frontend, + if (port->dvb.frontend != NULL) { + dvb_attach(tda829x_attach, port->dvb.frontend, &dev->i2c_bus[1].i2c_adap, 0x42, &tda829x_no_probe); - dvb_attach(tda18271_attach, fe0->dvb.frontend, + dvb_attach(tda18271_attach, port->dvb.frontend, 0x60, &dev->i2c_bus[1].i2c_adap, &hauppauge_tda18271_config); } break; case 0: default: - fe0->dvb.frontend = + port->dvb.frontend = dvb_attach(s5h1409_attach, &hauppauge_generic_config, &i2c_bus->i2c_adap); - if (fe0->dvb.frontend != NULL) - dvb_attach(mt2131_attach, fe0->dvb.frontend, + if (port->dvb.frontend != NULL) + dvb_attach(mt2131_attach, port->dvb.frontend, &i2c_bus->i2c_adap, &hauppauge_generic_tunerconfig, 0); break; @@ -367,42 +361,42 @@ static int dvb_register(struct cx23885_tsport *port) break; case CX23885_BOARD_HAUPPAUGE_HVR1800lp: i2c_bus = &dev->i2c_bus[0]; - fe0->dvb.frontend = dvb_attach(s5h1409_attach, + port->dvb.frontend = dvb_attach(s5h1409_attach, &hauppauge_hvr1800lp_config, &i2c_bus->i2c_adap); - if (fe0->dvb.frontend != NULL) { - dvb_attach(mt2131_attach, fe0->dvb.frontend, + if (port->dvb.frontend != NULL) { + dvb_attach(mt2131_attach, port->dvb.frontend, &i2c_bus->i2c_adap, &hauppauge_generic_tunerconfig, 0); } break; case CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP: i2c_bus = &dev->i2c_bus[0]; - fe0->dvb.frontend = dvb_attach(lgdt330x_attach, + port->dvb.frontend = dvb_attach(lgdt330x_attach, &fusionhdtv_5_express, &i2c_bus->i2c_adap); - if (fe0->dvb.frontend != NULL) { - dvb_attach(simple_tuner_attach, fe0->dvb.frontend, + if (port->dvb.frontend != NULL) { + dvb_attach(simple_tuner_attach, port->dvb.frontend, &i2c_bus->i2c_adap, 0x61, TUNER_LG_TDVS_H06XF); } break; case CX23885_BOARD_HAUPPAUGE_HVR1500Q: i2c_bus = &dev->i2c_bus[1]; - fe0->dvb.frontend = dvb_attach(s5h1409_attach, + port->dvb.frontend = dvb_attach(s5h1409_attach, &hauppauge_hvr1500q_config, &dev->i2c_bus[0].i2c_adap); - if (fe0->dvb.frontend != NULL) - dvb_attach(xc5000_attach, fe0->dvb.frontend, + if (port->dvb.frontend != NULL) + dvb_attach(xc5000_attach, port->dvb.frontend, &i2c_bus->i2c_adap, &hauppauge_hvr1500q_tunerconfig); break; case CX23885_BOARD_HAUPPAUGE_HVR1500: i2c_bus = &dev->i2c_bus[1]; - fe0->dvb.frontend = dvb_attach(s5h1409_attach, + port->dvb.frontend = dvb_attach(s5h1409_attach, &hauppauge_hvr1500_config, &dev->i2c_bus[0].i2c_adap); - if (fe0->dvb.frontend != NULL) { + if (port->dvb.frontend != NULL) { struct dvb_frontend *fe; struct xc2028_config cfg = { .i2c_adap = &i2c_bus->i2c_adap, @@ -415,7 +409,7 @@ static int dvb_register(struct cx23885_tsport *port) }; fe = dvb_attach(xc2028_attach, - fe0->dvb.frontend, &cfg); + port->dvb.frontend, &cfg); if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) fe->ops.tuner_ops.set_config(fe, &ctl); } @@ -423,24 +417,24 @@ static int dvb_register(struct cx23885_tsport *port) case CX23885_BOARD_HAUPPAUGE_HVR1200: case CX23885_BOARD_HAUPPAUGE_HVR1700: i2c_bus = &dev->i2c_bus[0]; - fe0->dvb.frontend = dvb_attach(tda10048_attach, + port->dvb.frontend = dvb_attach(tda10048_attach, &hauppauge_hvr1200_config, &i2c_bus->i2c_adap); - if (fe0->dvb.frontend != NULL) { - dvb_attach(tda829x_attach, fe0->dvb.frontend, + if (port->dvb.frontend != NULL) { + dvb_attach(tda829x_attach, port->dvb.frontend, &dev->i2c_bus[1].i2c_adap, 0x42, &tda829x_no_probe); - dvb_attach(tda18271_attach, fe0->dvb.frontend, + dvb_attach(tda18271_attach, port->dvb.frontend, 0x60, &dev->i2c_bus[1].i2c_adap, &hauppauge_hvr1200_tuner_config); } break; case CX23885_BOARD_HAUPPAUGE_HVR1400: i2c_bus = &dev->i2c_bus[0]; - fe0->dvb.frontend = dvb_attach(dib7000p_attach, + port->dvb.frontend = dvb_attach(dib7000p_attach, &i2c_bus->i2c_adap, 0x12, &hauppauge_hvr1400_dib7000_config); - if (fe0->dvb.frontend != NULL) { + if (port->dvb.frontend != NULL) { struct dvb_frontend *fe; struct xc2028_config cfg = { .i2c_adap = &dev->i2c_bus[1].i2c_adap, @@ -450,13 +444,12 @@ static int dvb_register(struct cx23885_tsport *port) .fname = XC3028L_DEFAULT_FIRMWARE, .max_len = 64, .demod = 5000, - /* This is true for all demods with - v36 firmware? */ + /* This is true for all demods with v36 firmware? */ .type = XC2028_D2633, }; fe = dvb_attach(xc2028_attach, - fe0->dvb.frontend, &cfg); + port->dvb.frontend, &cfg); if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) fe->ops.tuner_ops.set_config(fe, &ctl); } @@ -464,25 +457,25 @@ static int dvb_register(struct cx23885_tsport *port) case CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP: i2c_bus = &dev->i2c_bus[port->nr - 1]; - fe0->dvb.frontend = dvb_attach(s5h1409_attach, + port->dvb.frontend = dvb_attach(s5h1409_attach, &dvico_s5h1409_config, &i2c_bus->i2c_adap); - if (fe0->dvb.frontend == NULL) - fe0->dvb.frontend = dvb_attach(s5h1411_attach, + if (port->dvb.frontend == NULL) + port->dvb.frontend = dvb_attach(s5h1411_attach, &dvico_s5h1411_config, &i2c_bus->i2c_adap); - if (fe0->dvb.frontend != NULL) - dvb_attach(xc5000_attach, fe0->dvb.frontend, + if (port->dvb.frontend != NULL) + dvb_attach(xc5000_attach, port->dvb.frontend, &i2c_bus->i2c_adap, &dvico_xc5000_tunerconfig); break; case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP: { i2c_bus = &dev->i2c_bus[port->nr - 1]; - fe0->dvb.frontend = dvb_attach(zl10353_attach, + port->dvb.frontend = dvb_attach(zl10353_attach, &dvico_fusionhdtv_xc3028, &i2c_bus->i2c_adap); - if (fe0->dvb.frontend != NULL) { + if (port->dvb.frontend != NULL) { struct dvb_frontend *fe; struct xc2028_config cfg = { .i2c_adap = &i2c_bus->i2c_adap, @@ -494,7 +487,7 @@ static int dvb_register(struct cx23885_tsport *port) .demod = XC3028_FE_ZARLINK456, }; - fe = dvb_attach(xc2028_attach, fe0->dvb.frontend, + fe = dvb_attach(xc2028_attach, port->dvb.frontend, &cfg); if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) fe->ops.tuner_ops.set_config(fe, &ctl); @@ -504,10 +497,10 @@ static int dvb_register(struct cx23885_tsport *port) case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: i2c_bus = &dev->i2c_bus[0]; - fe0->dvb.frontend = dvb_attach(zl10353_attach, + port->dvb.frontend = dvb_attach(zl10353_attach, &dvico_fusionhdtv_xc3028, &i2c_bus->i2c_adap); - if (fe0->dvb.frontend != NULL) { + if (port->dvb.frontend != NULL) { struct dvb_frontend *fe; struct xc2028_config cfg = { .i2c_adap = &dev->i2c_bus[1].i2c_adap, @@ -519,108 +512,73 @@ static int dvb_register(struct cx23885_tsport *port) .demod = XC3028_FE_ZARLINK456, }; - fe = dvb_attach(xc2028_attach, fe0->dvb.frontend, + fe = dvb_attach(xc2028_attach, port->dvb.frontend, &cfg); if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) fe->ops.tuner_ops.set_config(fe, &ctl); } break; default: - printk(KERN_INFO "%s: The frontend of your DVB/ATSC card " - " isn't supported yet\n", + printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n", dev->name); break; } - if (NULL == fe0->dvb.frontend) { - printk(KERN_ERR "%s: frontend initialization failed\n", - dev->name); + if (NULL == port->dvb.frontend) { + printk("%s: frontend initialization failed\n", dev->name); return -1; } /* define general-purpose callback pointer */ - fe0->dvb.frontend->callback = cx23885_tuner_callback; + port->dvb.frontend->callback = cx23885_tuner_callback; /* Put the analog decoder in standby to keep it quiet */ cx23885_call_i2c_clients(i2c_bus, TUNER_SET_STANDBY, NULL); - if (fe0->dvb.frontend->ops.analog_ops.standby) - fe0->dvb.frontend->ops.analog_ops.standby(fe0->dvb.frontend); + if (port->dvb.frontend->ops.analog_ops.standby) + port->dvb.frontend->ops.analog_ops.standby(port->dvb.frontend); /* register everything */ - return videobuf_dvb_register_bus(&port->frontends, THIS_MODULE, port, - &dev->pci->dev, adapter_nr, 0); - + return videobuf_dvb_register(&port->dvb, THIS_MODULE, port, + &dev->pci->dev, adapter_nr); } int cx23885_dvb_register(struct cx23885_tsport *port) { - - struct videobuf_dvb_frontend *fe0; struct cx23885_dev *dev = port->dev; - int err, i; - - /* Here we need to allocate the correct number of frontends, - * as reflected in the cards struct. The reality is that currrently - * no cx23885 boards support this - yet. But, if we don't modify this - * code then the second frontend would never be allocated (later) - * and fail with error before the attach in dvb_register(). - * Without these changes we risk an OOPS later. The changes here - * are for safety, and should provide a good foundation for the - * future addition of any multi-frontend cx23885 based boards. - */ - printk(KERN_INFO "%s() allocating %d frontend(s)\n", __func__, - port->num_frontends); - - for (i = 1; i <= port->num_frontends; i++) { - if (videobuf_dvb_alloc_frontend( - &port->frontends, i) == NULL) { - printk(KERN_ERR "%s() failed to alloc\n", __func__); - return -ENOMEM; - } + int err; - fe0 = videobuf_dvb_get_frontend(&port->frontends, i); - if (!fe0) - err = -EINVAL; + dprintk(1, "%s\n", __func__); + dprintk(1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n", + dev->board, + dev->name, + dev->pci_bus, + dev->pci_slot); - dprintk(1, "%s\n", __func__); - dprintk(1, " ->probed by Card=%d Name=%s, PCI %02x:%02x\n", - dev->board, - dev->name, - dev->pci_bus, - dev->pci_slot); + err = -ENODEV; - err = -ENODEV; - - /* dvb stuff */ - /* We have to init the queue for each frontend on a port. */ - printk(KERN_INFO "%s: cx23885 based dvb card\n", dev->name); - videobuf_queue_sg_init(&fe0->dvb.dvbq, &dvb_qops, - &dev->pci->dev, &port->slock, + /* dvb stuff */ + printk("%s: cx23885 based dvb card\n", dev->name); + videobuf_queue_sg_init(&port->dvb.dvbq, &dvb_qops, &dev->pci->dev, &port->slock, V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_TOP, sizeof(struct cx23885_buffer), port); - } err = dvb_register(port); if (err != 0) - printk(KERN_ERR "%s() dvb_register failed err = %d\n", - __func__, err); + printk("%s() dvb_register failed err = %d\n", __func__, err); return err; } int cx23885_dvb_unregister(struct cx23885_tsport *port) { - struct videobuf_dvb_frontend *fe0; - - /* FIXME: in an error condition where the we have - * an expected number of frontends (attach problem) - * then this might not clean up correctly, if 1 - * is invalid. - * This comment only applies to future boards IF they - * implement MFE support. - */ - fe0 = videobuf_dvb_get_frontend(&port->frontends, 1); - if (fe0->dvb.frontend) - videobuf_dvb_unregister_bus(&port->frontends); + /* dvb */ + if(port->dvb.frontend) + videobuf_dvb_unregister(&port->dvb); return 0; } +/* + * Local variables: + * c-basic-offset: 8 + * End: + * 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 +*/ diff --git a/trunk/drivers/media/video/cx23885/cx23885-i2c.c b/trunk/drivers/media/video/cx23885/cx23885-i2c.c index bb7f71a1fcbe..f98e476e9617 100644 --- a/trunk/drivers/media/video/cx23885/cx23885-i2c.c +++ b/trunk/drivers/media/video/cx23885/cx23885-i2c.c @@ -131,7 +131,7 @@ static int i2c_sendbytes(struct i2c_adapter *i2c_adap, printk(" >\n"); } - for (cnt = 1; cnt < msg->len; cnt++) { + for (cnt = 1; cnt < msg->len; cnt++ ) { /* following bytes */ wdata = msg->buf[cnt]; ctrl = bus->i2c_period | (1 << 12) | (1 << 2); @@ -151,9 +151,9 @@ static int i2c_sendbytes(struct i2c_adapter *i2c_adap, if (retval == 0) goto eio; if (i2c_debug) { - dprintk(1, " %02x", msg->buf[cnt]); + printk(" %02x", msg->buf[cnt]); if (!(ctrl & I2C_NOSTOP)) - dprintk(1, " >\n"); + printk(" >\n"); } } return msg->len; @@ -162,7 +162,7 @@ static int i2c_sendbytes(struct i2c_adapter *i2c_adap, retval = -EIO; err: if (i2c_debug) - printk(KERN_ERR " ERR: %d\n", retval); + printk(" ERR: %d\n", retval); return retval; } @@ -194,12 +194,12 @@ static int i2c_readbytes(struct i2c_adapter *i2c_adap, if (i2c_debug) { if (joined) - dprintk(1, " R"); + printk(" R"); else - dprintk(1, " addr << 1) + 1); + printk(" addr << 1) + 1); } - for (cnt = 0; cnt < msg->len; cnt++) { + for(cnt = 0; cnt < msg->len; cnt++) { ctrl = bus->i2c_period | (1 << 12) | (1 << 2) | 1; @@ -216,9 +216,9 @@ static int i2c_readbytes(struct i2c_adapter *i2c_adap, goto eio; msg->buf[cnt] = cx_read(bus->reg_rdata) & 0xff; if (i2c_debug) { - dprintk(1, " %02x", msg->buf[cnt]); + printk(" %02x", msg->buf[cnt]); if (!(ctrl & I2C_NOSTOP)) - dprintk(1, " >\n"); + printk(" >\n"); } } return msg->len; @@ -227,7 +227,7 @@ static int i2c_readbytes(struct i2c_adapter *i2c_adap, retval = -EIO; err: if (i2c_debug) - printk(KERN_ERR " ERR: %d\n", retval); + printk(" ERR: %d\n", retval); return retval; } @@ -353,17 +353,17 @@ static struct i2c_client cx23885_i2c_client_template = { }; static char *i2c_devs[128] = { - [0x10 >> 1] = "tda10048", - [0x12 >> 1] = "dib7000pc", - [0x1c >> 1] = "lgdt3303", - [0x86 >> 1] = "tda9887", - [0x32 >> 1] = "cx24227", - [0x88 >> 1] = "cx25837", - [0x84 >> 1] = "tda8295", - [0xa0 >> 1] = "eeprom", - [0xc0 >> 1] = "tuner/mt2131/tda8275", + [0x10 >> 1] = "tda10048", + [0x12 >> 1] = "dib7000pc", + [ 0x1c >> 1 ] = "lgdt3303", + [ 0x86 >> 1 ] = "tda9887", + [ 0x32 >> 1 ] = "cx24227", + [ 0x88 >> 1 ] = "cx25837", + [ 0x84 >> 1 ] = "tda8295", + [ 0xa0 >> 1 ] = "eeprom", + [ 0xc0 >> 1 ] = "tuner/mt2131/tda8275", [0xc2 >> 1] = "tuner/mt2131/tda8275/xc5000/xc3028", - [0xc8 >> 1] = "tuner/xc3028L", + [0xc8 >> 1] = "tuner/xc3028L", }; 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) rc = i2c_master_recv(c, &buf, 0); if (rc < 0) continue; - printk(KERN_INFO "%s: i2c scan: found device @ 0x%x [%s]\n", + printk("%s: i2c scan: found device @ 0x%x [%s]\n", name, i << 1, i2c_devs[i] ? i2c_devs[i] : "???"); } } @@ -408,12 +408,11 @@ int cx23885_i2c_register(struct cx23885_i2c *bus) bus->i2c_client.adapter = &bus->i2c_adap; if (0 == bus->i2c_rc) { - dprintk(1, "%s: i2c bus %d registered\n", dev->name, bus->nr); + printk("%s: i2c bus %d registered\n", dev->name, bus->nr); if (i2c_scan) do_i2c_scan(dev->name, &bus->i2c_client); } else - printk(KERN_WARNING "%s: i2c bus %d register FAILED\n", - dev->name, bus->nr); + printk("%s: i2c bus %d register FAILED\n", dev->name, bus->nr); return bus->i2c_rc; } diff --git a/trunk/drivers/media/video/cx23885/cx23885-video.c b/trunk/drivers/media/video/cx23885/cx23885-video.c index ab3110d6046c..f75ed1c9b71a 100644 --- a/trunk/drivers/media/video/cx23885/cx23885-video.c +++ b/trunk/drivers/media/video/cx23885/cx23885-video.c @@ -285,10 +285,11 @@ static void cx23885_video_wakeup(struct cx23885_dev *dev, list_del(&buf->vb.queue); wake_up(&buf->vb.done); } - if (list_empty(&q->active)) + if (list_empty(&q->active)) { del_timer(&q->timeout); - else + } else { mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); + } if (bc != 1) printk(KERN_ERR "%s: %d buffers handled (should be 1)\n", __func__, bc); @@ -378,12 +379,12 @@ static int res_get(struct cx23885_dev *dev, struct cx23885_fh *fh, static int res_check(struct cx23885_fh *fh, unsigned int bit) { - return fh->resources & bit; + return (fh->resources & bit); } static int res_locked(struct cx23885_dev *dev, unsigned int bit) { - return dev->resources & bit; + return (dev->resources & bit); } static void res_free(struct cx23885_dev *dev, struct cx23885_fh *fh, @@ -886,16 +887,14 @@ static int video_mmap(struct file *file, struct vm_area_struct *vma) /* ------------------------------------------------------------------ */ /* VIDEO CTRL IOCTLS */ -static int cx23885_get_control(struct cx23885_dev *dev, - struct v4l2_control *ctl) +static int cx23885_get_control(struct cx23885_dev *dev, struct v4l2_control *ctl) { dprintk(1, "%s() calling cx25840(VIDIOC_G_CTRL)\n", __func__); cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_G_CTRL, ctl); return 0; } -static int cx23885_set_control(struct cx23885_dev *dev, - struct v4l2_control *ctl) +static int cx23885_set_control(struct cx23885_dev *dev, struct v4l2_control *ctl) { dprintk(1, "%s() calling cx25840(VIDIOC_S_CTRL)" " (disabled - no action)\n", __func__); @@ -1074,29 +1073,29 @@ static int vidioc_reqbufs(struct file *file, void *priv, struct v4l2_requestbuffers *p) { struct cx23885_fh *fh = priv; - return videobuf_reqbufs(get_queue(fh), p); + return (videobuf_reqbufs(get_queue(fh), p)); } static int vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *p) { struct cx23885_fh *fh = priv; - return videobuf_querybuf(get_queue(fh), p); + return (videobuf_querybuf(get_queue(fh), p)); } static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p) { struct cx23885_fh *fh = priv; - return videobuf_qbuf(get_queue(fh), p); + return (videobuf_qbuf(get_queue(fh), p)); } static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p) { struct cx23885_fh *fh = priv; - return videobuf_dqbuf(get_queue(fh), p, - file->f_flags & O_NONBLOCK); + return (videobuf_dqbuf(get_queue(fh), p, + file->f_flags & O_NONBLOCK)); } static int vidioc_streamon(struct file *file, void *priv, diff --git a/trunk/drivers/media/video/cx23885/cx23885.h b/trunk/drivers/media/video/cx23885/cx23885.h index 1d53f54cd943..ba4e0aaed463 100644 --- a/trunk/drivers/media/video/cx23885/cx23885.h +++ b/trunk/drivers/media/video/cx23885/cx23885.h @@ -37,7 +37,7 @@ #include #include -#define CX23885_VERSION_CODE KERNEL_VERSION(0, 0, 1) +#define CX23885_VERSION_CODE KERNEL_VERSION(0,0,1) #define UNSET (-1U) @@ -225,7 +225,7 @@ struct cx23885_tsport { int nr; int sram_chno; - struct videobuf_dvb_frontends frontends; + struct videobuf_dvb dvb; /* dma queues */ struct cx23885_dmaqueue mpegq; @@ -262,9 +262,6 @@ struct cx23885_tsport { u32 src_sel_val; u32 vld_misc_val; u32 hw_sop_ctrl_val; - - /* Allow a single tsport to have multiple frontends */ - u32 num_frontends; }; struct cx23885_dev { @@ -370,14 +367,14 @@ struct sram_channel { /* ----------------------------------------------------------- */ #define cx_read(reg) readl(dev->lmmio + ((reg)>>2)) -#define cx_write(reg, value) writel((value), dev->lmmio + ((reg)>>2)) +#define cx_write(reg,value) writel((value), dev->lmmio + ((reg)>>2)) -#define cx_andor(reg, mask, value) \ +#define cx_andor(reg,mask,value) \ writel((readl(dev->lmmio+((reg)>>2)) & ~(mask)) |\ ((value) & (mask)), dev->lmmio+((reg)>>2)) -#define cx_set(reg, bit) cx_andor((reg), (bit), (bit)) -#define cx_clear(reg, bit) cx_andor((reg), (bit), 0) +#define cx_set(reg,bit) cx_andor((reg),(bit),(bit)) +#define cx_clear(reg,bit) cx_andor((reg),(bit),0) /* ----------------------------------------------------------- */ /* cx23885-core.c */ @@ -414,8 +411,7 @@ extern const unsigned int cx23885_bcount; extern struct cx23885_subid cx23885_subids[]; extern const unsigned int cx23885_idcount; -extern int cx23885_tuner_callback(void *priv, int component, - int command, int arg); +extern int cx23885_tuner_callback(void *priv, int component, int command, int arg); extern void cx23885_card_list(struct cx23885_dev *dev); extern int cx23885_ir_init(struct cx23885_dev *dev); extern void cx23885_gpio_setup(struct cx23885_dev *dev); @@ -483,3 +479,11 @@ static inline unsigned int norm_swidth(v4l2_std_id norm) { return (norm & (V4L2_STD_MN & ~V4L2_STD_PAL_Nc)) ? 754 : 922; } + + +/* + * Local variables: + * c-basic-offset: 8 + * End: + * 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 + */ diff --git a/trunk/drivers/media/video/cx88/cx88-cards.c b/trunk/drivers/media/video/cx88/cx88-cards.c index fbc224f46e0e..5da04e811ca2 100644 --- a/trunk/drivers/media/video/cx88/cx88-cards.c +++ b/trunk/drivers/media/video/cx88/cx88-cards.c @@ -1270,40 +1270,27 @@ static const struct cx88_board cx88_boards[] = { .mpeg = CX88_MPEG_DVB, }, [CX88_BOARD_HAUPPAUGE_HVR3000] = { + /* FIXME: Add dvb & radio support */ .name = "Hauppauge WinTV-HVR3000 TriMode Analog/DVB-S/DVB-T", .tuner_type = TUNER_PHILIPS_FMD1216ME_MK3, .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, .tda9887_conf = TDA9887_PRESENT, - .audio_chip = V4L2_IDENT_WM8775, .input = {{ .type = CX88_VMUX_TELEVISION, .vmux = 0, .gpio0 = 0x84bf, - /* 1: TV Audio / FM Mono */ - .audioroute = 1, },{ .type = CX88_VMUX_COMPOSITE1, .vmux = 1, .gpio0 = 0x84bf, - /* 2: Line-In */ - .audioroute = 2, },{ .type = CX88_VMUX_SVIDEO, .vmux = 2, .gpio0 = 0x84bf, - /* 2: Line-In */ - .audioroute = 2, }}, - .radio = { - .type = CX88_RADIO, - .gpio0 = 0x84bf, - /* 4: FM Stereo (untested) */ - .audioroute = 8, - }, .mpeg = CX88_MPEG_DVB, - .num_frontends = 2, }, [CX88_BOARD_NORWOOD_MICRO] = { .name = "Norwood Micro TV Tuner", @@ -1369,27 +1356,23 @@ static const struct cx88_board cx88_boards[] = { .type = CX88_VMUX_TELEVISION, .vmux = 0, .gpio0 = 0xef88, - /* 1: TV Audio / FM Mono */ .audioroute = 1, },{ .type = CX88_VMUX_COMPOSITE1, .vmux = 1, .gpio0 = 0xef88, - /* 2: Line-In */ .audioroute = 2, },{ .type = CX88_VMUX_SVIDEO, .vmux = 2, .gpio0 = 0xef88, - /* 2: Line-In */ .audioroute = 2, }}, + /* fixme: Add radio support */ .mpeg = CX88_MPEG_DVB | CX88_MPEG_BLACKBIRD, .radio = { .type = CX88_RADIO, .gpio0 = 0xef88, - /* 4: FM Stereo (untested) */ - .audioroute = 8, }, }, [CX88_BOARD_ADSTECH_PTV_390] = { @@ -1733,7 +1716,6 @@ static const struct cx88_board cx88_boards[] = { .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, .tda9887_conf = TDA9887_PRESENT, - .audio_chip = V4L2_IDENT_WM8775, /* * GPIO0 (WINTV2000) * @@ -1747,7 +1729,7 @@ static const struct cx88_board cx88_boards[] = { * BIT VALUE FUNCTION GP{x}_IO * 0 1 I:? * 1 1 I:? - * 2 1 O:MPEG PORT 0=DVB-T 1=DVB-S + * 2 1 O:DVB-T DEMOD ENABLE LOW/ANALOG DEMOD ENABLE HIGH * 3 1 I:? * 4 1 I:? * 5 1 I:? @@ -1763,41 +1745,22 @@ static const struct cx88_board cx88_boards[] = { * d 0 I * e 1 O * f 1 O - * - * WM8775 ADC - * - * 1: TV Audio / FM Mono - * 2: Line-In - * 3: Line-In Expansion - * 4: FM Stereo */ .input = {{ .type = CX88_VMUX_TELEVISION, .vmux = 0, .gpio0 = 0xc4bf, - /* 1: TV Audio / FM Mono */ - .audioroute = 1, }, { .type = CX88_VMUX_COMPOSITE1, .vmux = 1, .gpio0 = 0xc4bf, - /* 2: Line-In */ - .audioroute = 2, }, { .type = CX88_VMUX_SVIDEO, .vmux = 2, .gpio0 = 0xc4bf, - /* 2: Line-In */ - .audioroute = 2, } }, - .radio = { - .type = CX88_RADIO, - .gpio0 = 0xc4bf, - /* 4: FM Stereo */ - .audioroute = 8, - }, + /* fixme: Add radio support */ .mpeg = CX88_MPEG_DVB, - .num_frontends = 2, }, [CX88_BOARD_HAUPPAUGE_HVR4000LITE] = { .name = "Hauppauge WinTV-HVR4000(Lite) DVB-S/S2", @@ -2699,13 +2662,10 @@ static void cx88_card_setup_pre_i2c(struct cx88_core *core) case CX88_BOARD_HAUPPAUGE_HVR3000: case CX88_BOARD_HAUPPAUGE_HVR4000: + case CX88_BOARD_HAUPPAUGE_HVR4000LITE: /* Init GPIO */ cx_write(MO_GP0_IO, core->board.input[0].gpio0); udelay(1000); - cx_clear(MO_GP0_IO, 0x00000080); - udelay(50); - cx_set(MO_GP0_IO, 0x00000080); /* 702 out of reset */ - udelay(1000); break; } } @@ -3044,14 +3004,10 @@ struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr) memcpy(&core->board, &cx88_boards[core->boardnr], sizeof(core->board)); - if (!core->board.num_frontends) - core->board.num_frontends=1; - - info_printk(core, "subsystem: %04x:%04x, board: %s [card=%d,%s], frontend(s): %d\n", + info_printk(core, "subsystem: %04x:%04x, board: %s [card=%d,%s]\n", pci->subsystem_vendor, pci->subsystem_device, core->board.name, core->boardnr, card[core->nr] == core->boardnr ? - "insmod option" : "autodetected", - core->board.num_frontends); + "insmod option" : "autodetected"); if (tuner[core->nr] != UNSET) core->board.tuner_type = tuner[core->nr]; diff --git a/trunk/drivers/media/video/cx88/cx88-core.c b/trunk/drivers/media/video/cx88/cx88-core.c index 60705b08bfe8..d656fec59010 100644 --- a/trunk/drivers/media/video/cx88/cx88-core.c +++ b/trunk/drivers/media/video/cx88/cx88-core.c @@ -549,8 +549,7 @@ void cx88_wakeup(struct cx88_core *core, mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); } if (bc != 1) - dprintk(2, "%s: %d buffers handled (should be 1)\n", - __func__, bc); + printk("%s: %d buffers handled (should be 1)\n",__func__,bc); } void cx88_shutdown(struct cx88_core *core) diff --git a/trunk/drivers/media/video/cx88/cx88-dvb.c b/trunk/drivers/media/video/cx88/cx88-dvb.c index 6968ab0181aa..344ed2626e59 100644 --- a/trunk/drivers/media/video/cx88/cx88-dvb.c +++ b/trunk/drivers/media/video/cx88/cx88-dvb.c @@ -116,23 +116,13 @@ static int cx88_dvb_bus_ctrl(struct dvb_frontend* fe, int acquire) struct cx8802_dev *dev= fe->dvb->priv; struct cx8802_driver *drv = NULL; int ret = 0; - int fe_id; - - fe_id = videobuf_dvb_find_frontend(&dev->frontends, fe); - if (!fe_id) { - printk(KERN_ERR "%s() No frontend found\n", __func__); - return -EINVAL; - } drv = cx8802_get_driver(dev, CX88_MPEG_DVB); if (drv) { - if (acquire){ - dev->frontends.active_fe_id = fe_id; + if (acquire) ret = drv->request_acquire(drv); - } else { + else ret = drv->request_release(drv); - dev->frontends.active_fe_id = 0; - } } return ret; @@ -406,7 +396,7 @@ static int tevii_dvbs_set_voltage(struct dvb_frontend *fe, cx_write(MO_GP0_IO, 0x00006060); break; case SEC_VOLTAGE_OFF: - printk("LNB Voltage SEC_VOLTAGE_off\n"); + printk("LNB Voltage SEC_VOLTAGE_off\n"); break; } @@ -493,7 +483,6 @@ static struct xc5000_config dvico_fusionhdtv7_tuner_config = { static int attach_xc3028(u8 addr, struct cx8802_dev *dev) { struct dvb_frontend *fe; - struct videobuf_dvb_frontend *fe0 = NULL; struct xc2028_ctrl ctl; struct xc2028_config cfg = { .i2c_adap = &dev->core->i2c_adap, @@ -501,12 +490,7 @@ static int attach_xc3028(u8 addr, struct cx8802_dev *dev) .ctrl = &ctl, }; - /* Get the first frontend */ - fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1); - if (!fe0) - return -EINVAL; - - if (!fe0->dvb.frontend) { + if (!dev->dvb.frontend) { printk(KERN_ERR "%s/2: dvb frontend not attached. " "Can't attach xc3028\n", dev->core->name); @@ -520,13 +504,10 @@ static int attach_xc3028(u8 addr, struct cx8802_dev *dev) */ cx88_setup_xc3028(dev->core, &ctl); - fe = dvb_attach(xc2028_attach, fe0->dvb.frontend, &cfg); + fe = dvb_attach(xc2028_attach, dev->dvb.frontend, &cfg); if (!fe) { printk(KERN_ERR "%s/2: xc3028 attach failed\n", dev->core->name); - dvb_frontend_detach(fe0->dvb.frontend); - dvb_unregister_frontend(fe0->dvb.frontend); - fe0->dvb.frontend = NULL; return -EINVAL; } @@ -551,10 +532,8 @@ static int cx24116_reset_device(struct dvb_frontend *fe) struct cx88_core *core = dev->core; /* Reset the part */ - /* Put the cx24116 into reset */ cx_write(MO_SRST_IO, 0); msleep(10); - /* Take the cx24116 out of reset */ cx_write(MO_SRST_IO, 1); msleep(10); @@ -575,14 +554,14 @@ static struct cx24116_config tevii_s460_config = { static struct stv0299_config tevii_tuner_sharp_config = { .demod_address = 0x68, - .inittab = sharp_z0194a_inittab, + .inittab = sharp_z0194a__inittab, .mclk = 88000000UL, .invert = 1, .skip_reinit = 0, .lock_output = 1, .volt13_op0_op1 = STV0299_VOLT13_OP1, .min_delay_ms = 100, - .set_symbol_rate = sharp_z0194a_set_symbol_rate, + .set_symbol_rate = sharp_z0194a__set_symbol_rate, .set_ts_params = cx24116_set_ts_param, }; @@ -595,25 +574,19 @@ static struct stv0288_config tevii_tuner_earda_config = { static int dvb_register(struct cx8802_dev *dev) { struct cx88_core *core = dev->core; - struct videobuf_dvb_frontend *fe0, *fe1 = NULL; - int mfe_shared = 0; /* bus not shared by default */ - - /* Get the first frontend */ - fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1); - if (!fe0) - return -EINVAL; - /* multi-frontend gate control is undefined or defaults to fe0 */ - dev->frontends.gate = 0; + /* init struct videobuf_dvb */ + dev->dvb.name = core->name; + dev->ts_gen_cntrl = 0x0c; - /* init frontend(s) */ + /* init frontend */ switch (core->boardnr) { case CX88_BOARD_HAUPPAUGE_DVB_T1: - fe0->dvb.frontend = dvb_attach(cx22702_attach, + dev->dvb.frontend = dvb_attach(cx22702_attach, &connexant_refboard_config, &core->i2c_adap); - if (fe0->dvb.frontend != NULL) { - if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, + if (dev->dvb.frontend != NULL) { + if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, &core->i2c_adap, DVB_PLL_THOMSON_DTT759X)) goto frontend_detach; @@ -623,11 +596,11 @@ static int dvb_register(struct cx8802_dev *dev) case CX88_BOARD_CONEXANT_DVB_T1: case CX88_BOARD_KWORLD_DVB_T_CX22702: case CX88_BOARD_WINFAST_DTV1000: - fe0->dvb.frontend = dvb_attach(cx22702_attach, + dev->dvb.frontend = dvb_attach(cx22702_attach, &connexant_refboard_config, &core->i2c_adap); - if (fe0->dvb.frontend != NULL) { - if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, + if (dev->dvb.frontend != NULL) { + if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60, &core->i2c_adap, DVB_PLL_THOMSON_DTT7579)) goto frontend_detach; @@ -637,67 +610,33 @@ static int dvb_register(struct cx8802_dev *dev) case CX88_BOARD_HAUPPAUGE_HVR1100: case CX88_BOARD_HAUPPAUGE_HVR1100LP: case CX88_BOARD_HAUPPAUGE_HVR1300: - fe0->dvb.frontend = dvb_attach(cx22702_attach, + case CX88_BOARD_HAUPPAUGE_HVR3000: + dev->dvb.frontend = dvb_attach(cx22702_attach, &hauppauge_hvr_config, &core->i2c_adap); - if (fe0->dvb.frontend != NULL) { - if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend, + if (dev->dvb.frontend != NULL) { + if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend, &core->i2c_adap, 0x61, TUNER_PHILIPS_FMD1216ME_MK3)) goto frontend_detach; } break; - case CX88_BOARD_HAUPPAUGE_HVR3000: - /* DVB-S init */ - fe0->dvb.frontend = dvb_attach(cx24123_attach, - &hauppauge_novas_config, - &dev->core->i2c_adap); - if (fe0->dvb.frontend) { - if (!dvb_attach(isl6421_attach, fe0->dvb.frontend, - &dev->core->i2c_adap, 0x08, ISL6421_DCL, 0x00)) { - dprintk( 1, "%s(): HVR3000 - DVB-S LNB Init: failed\n", __func__); - } - } else { - dprintk( 1, "%s(): HVR3000 - DVB-S Init: failed\n", __func__); - } - /* DVB-T init */ - fe1 = videobuf_dvb_get_frontend(&dev->frontends, 2); - if (fe1) { - dev->frontends.gate = 2; - mfe_shared = 1; - fe1->dvb.frontend = dvb_attach(cx22702_attach, - &hauppauge_hvr_config, - &dev->core->i2c_adap); - if (fe1->dvb.frontend) { - fe1->dvb.frontend->id = 1; - if(!dvb_attach(simple_tuner_attach, fe1->dvb.frontend, - &dev->core->i2c_adap, 0x61, - TUNER_PHILIPS_FMD1216ME_MK3)) { - dprintk( 1, "%s(): HVR3000 - DVB-T misc Init: failed\n", __func__); - } - } else { - dprintk( 1, "%s(): HVR3000 - DVB-T Init: failed\n", __func__); - } - } else { - dprintk( 1, "%s(): HVR3000 - DVB-T Init: can't find frontend 2.\n", __func__); - } - break; case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS: - fe0->dvb.frontend = dvb_attach(mt352_attach, + dev->dvb.frontend = dvb_attach(mt352_attach, &dvico_fusionhdtv, &core->i2c_adap); - if (fe0->dvb.frontend != NULL) { - if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, + if (dev->dvb.frontend != NULL) { + if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60, NULL, DVB_PLL_THOMSON_DTT7579)) goto frontend_detach; break; } /* ZL10353 replaces MT352 on later cards */ - fe0->dvb.frontend = dvb_attach(zl10353_attach, + dev->dvb.frontend = dvb_attach(zl10353_attach, &dvico_fusionhdtv_plus_v1_1, &core->i2c_adap); - if (fe0->dvb.frontend != NULL) { - if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, + if (dev->dvb.frontend != NULL) { + if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60, NULL, DVB_PLL_THOMSON_DTT7579)) goto frontend_detach; } @@ -705,31 +644,31 @@ static int dvb_register(struct cx8802_dev *dev) case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL: /* The tin box says DEE1601, but it seems to be DTT7579 * compatible, with a slightly different MT352 AGC gain. */ - fe0->dvb.frontend = dvb_attach(mt352_attach, + dev->dvb.frontend = dvb_attach(mt352_attach, &dvico_fusionhdtv_dual, &core->i2c_adap); - if (fe0->dvb.frontend != NULL) { - if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, + if (dev->dvb.frontend != NULL) { + if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, NULL, DVB_PLL_THOMSON_DTT7579)) goto frontend_detach; break; } /* ZL10353 replaces MT352 on later cards */ - fe0->dvb.frontend = dvb_attach(zl10353_attach, + dev->dvb.frontend = dvb_attach(zl10353_attach, &dvico_fusionhdtv_plus_v1_1, &core->i2c_adap); - if (fe0->dvb.frontend != NULL) { - if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, + if (dev->dvb.frontend != NULL) { + if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, NULL, DVB_PLL_THOMSON_DTT7579)) goto frontend_detach; } break; case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1: - fe0->dvb.frontend = dvb_attach(mt352_attach, + dev->dvb.frontend = dvb_attach(mt352_attach, &dvico_fusionhdtv, &core->i2c_adap); - if (fe0->dvb.frontend != NULL) { - if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, + if (dev->dvb.frontend != NULL) { + if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, NULL, DVB_PLL_LG_Z201)) goto frontend_detach; } @@ -737,11 +676,11 @@ static int dvb_register(struct cx8802_dev *dev) case CX88_BOARD_KWORLD_DVB_T: case CX88_BOARD_DNTV_LIVE_DVB_T: case CX88_BOARD_ADSTECH_DVB_T_PCI: - fe0->dvb.frontend = dvb_attach(mt352_attach, + dev->dvb.frontend = dvb_attach(mt352_attach, &dntv_live_dvbt_config, &core->i2c_adap); - if (fe0->dvb.frontend != NULL) { - if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, + if (dev->dvb.frontend != NULL) { + if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, NULL, DVB_PLL_UNKNOWN_1)) goto frontend_detach; } @@ -749,10 +688,10 @@ static int dvb_register(struct cx8802_dev *dev) case CX88_BOARD_DNTV_LIVE_DVB_T_PRO: #if defined(CONFIG_VIDEO_CX88_VP3054) || (defined(CONFIG_VIDEO_CX88_VP3054_MODULE) && defined(MODULE)) /* MT352 is on a secondary I2C bus made from some GPIO lines */ - fe0->dvb.frontend = dvb_attach(mt352_attach, &dntv_live_dvbt_pro_config, + dev->dvb.frontend = dvb_attach(mt352_attach, &dntv_live_dvbt_pro_config, &dev->vp3054->adap); - if (fe0->dvb.frontend != NULL) { - if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend, + if (dev->dvb.frontend != NULL) { + if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend, &core->i2c_adap, 0x61, TUNER_PHILIPS_FMD1216ME_MK3)) goto frontend_detach; @@ -763,22 +702,22 @@ static int dvb_register(struct cx8802_dev *dev) #endif break; case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID: - fe0->dvb.frontend = dvb_attach(zl10353_attach, + dev->dvb.frontend = dvb_attach(zl10353_attach, &dvico_fusionhdtv_hybrid, &core->i2c_adap); - if (fe0->dvb.frontend != NULL) { - if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend, + if (dev->dvb.frontend != NULL) { + if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend, &core->i2c_adap, 0x61, TUNER_THOMSON_FE6600)) goto frontend_detach; } break; case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO: - fe0->dvb.frontend = dvb_attach(zl10353_attach, + dev->dvb.frontend = dvb_attach(zl10353_attach, &dvico_fusionhdtv_xc3028, &core->i2c_adap); - if (fe0->dvb.frontend == NULL) - fe0->dvb.frontend = dvb_attach(mt352_attach, + if (dev->dvb.frontend == NULL) + dev->dvb.frontend = dvb_attach(mt352_attach, &dvico_fusionhdtv_mt352_xc3028, &core->i2c_adap); /* @@ -786,16 +725,16 @@ static int dvb_register(struct cx8802_dev *dev) * We must not permit gate_ctrl to be performed, or * the xc3028 cannot communicate on the bus. */ - if (fe0->dvb.frontend) - fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL; + if (dev->dvb.frontend) + dev->dvb.frontend->ops.i2c_gate_ctrl = NULL; if (attach_xc3028(0x61, dev) < 0) return -EINVAL; break; case CX88_BOARD_PCHDTV_HD3000: - fe0->dvb.frontend = dvb_attach(or51132_attach, &pchdtv_hd3000, + dev->dvb.frontend = dvb_attach(or51132_attach, &pchdtv_hd3000, &core->i2c_adap); - if (fe0->dvb.frontend != NULL) { - if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend, + if (dev->dvb.frontend != NULL) { + if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend, &core->i2c_adap, 0x61, TUNER_THOMSON_DTT761X)) goto frontend_detach; @@ -812,11 +751,11 @@ static int dvb_register(struct cx8802_dev *dev) /* Select RF connector callback */ fusionhdtv_3_gold.pll_rf_set = lgdt330x_pll_rf_set; - fe0->dvb.frontend = dvb_attach(lgdt330x_attach, + dev->dvb.frontend = dvb_attach(lgdt330x_attach, &fusionhdtv_3_gold, &core->i2c_adap); - if (fe0->dvb.frontend != NULL) { - if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend, + if (dev->dvb.frontend != NULL) { + if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend, &core->i2c_adap, 0x61, TUNER_MICROTUNE_4042FI5)) goto frontend_detach; @@ -830,11 +769,11 @@ static int dvb_register(struct cx8802_dev *dev) mdelay(100); cx_set(MO_GP0_IO, 9); mdelay(200); - fe0->dvb.frontend = dvb_attach(lgdt330x_attach, + dev->dvb.frontend = dvb_attach(lgdt330x_attach, &fusionhdtv_3_gold, &core->i2c_adap); - if (fe0->dvb.frontend != NULL) { - if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend, + if (dev->dvb.frontend != NULL) { + if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend, &core->i2c_adap, 0x61, TUNER_THOMSON_DTT761X)) goto frontend_detach; @@ -848,15 +787,15 @@ static int dvb_register(struct cx8802_dev *dev) mdelay(100); cx_set(MO_GP0_IO, 1); mdelay(200); - fe0->dvb.frontend = dvb_attach(lgdt330x_attach, + dev->dvb.frontend = dvb_attach(lgdt330x_attach, &fusionhdtv_5_gold, &core->i2c_adap); - if (fe0->dvb.frontend != NULL) { - if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend, + if (dev->dvb.frontend != NULL) { + if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend, &core->i2c_adap, 0x61, TUNER_LG_TDVS_H06XF)) goto frontend_detach; - if (!dvb_attach(tda9887_attach, fe0->dvb.frontend, + if (!dvb_attach(tda9887_attach, dev->dvb.frontend, &core->i2c_adap, 0x43)) goto frontend_detach; } @@ -869,25 +808,25 @@ static int dvb_register(struct cx8802_dev *dev) mdelay(100); cx_set(MO_GP0_IO, 1); mdelay(200); - fe0->dvb.frontend = dvb_attach(lgdt330x_attach, + dev->dvb.frontend = dvb_attach(lgdt330x_attach, &pchdtv_hd5500, &core->i2c_adap); - if (fe0->dvb.frontend != NULL) { - if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend, + if (dev->dvb.frontend != NULL) { + if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend, &core->i2c_adap, 0x61, TUNER_LG_TDVS_H06XF)) goto frontend_detach; - if (!dvb_attach(tda9887_attach, fe0->dvb.frontend, + if (!dvb_attach(tda9887_attach, dev->dvb.frontend, &core->i2c_adap, 0x43)) goto frontend_detach; } break; case CX88_BOARD_ATI_HDTVWONDER: - fe0->dvb.frontend = dvb_attach(nxt200x_attach, + dev->dvb.frontend = dvb_attach(nxt200x_attach, &ati_hdtvwonder, &core->i2c_adap); - if (fe0->dvb.frontend != NULL) { - if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend, + if (dev->dvb.frontend != NULL) { + if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend, &core->i2c_adap, 0x61, TUNER_PHILIPS_TUV1236D)) goto frontend_detach; @@ -895,49 +834,49 @@ static int dvb_register(struct cx8802_dev *dev) break; case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1: case CX88_BOARD_HAUPPAUGE_NOVASE2_S1: - fe0->dvb.frontend = dvb_attach(cx24123_attach, + dev->dvb.frontend = dvb_attach(cx24123_attach, &hauppauge_novas_config, &core->i2c_adap); - if (fe0->dvb.frontend) { - if (!dvb_attach(isl6421_attach, fe0->dvb.frontend, + if (dev->dvb.frontend) { + if (!dvb_attach(isl6421_attach, dev->dvb.frontend, &core->i2c_adap, 0x08, ISL6421_DCL, 0x00)) goto frontend_detach; } break; case CX88_BOARD_KWORLD_DVBS_100: - fe0->dvb.frontend = dvb_attach(cx24123_attach, + dev->dvb.frontend = dvb_attach(cx24123_attach, &kworld_dvbs_100_config, &core->i2c_adap); - if (fe0->dvb.frontend) { - core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage; - fe0->dvb.frontend->ops.set_voltage = kworld_dvbs_100_set_voltage; + if (dev->dvb.frontend) { + core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage; + dev->dvb.frontend->ops.set_voltage = kworld_dvbs_100_set_voltage; } break; case CX88_BOARD_GENIATECH_DVBS: - fe0->dvb.frontend = dvb_attach(cx24123_attach, + dev->dvb.frontend = dvb_attach(cx24123_attach, &geniatech_dvbs_config, &core->i2c_adap); - if (fe0->dvb.frontend) { - core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage; - fe0->dvb.frontend->ops.set_voltage = geniatech_dvbs_set_voltage; + if (dev->dvb.frontend) { + core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage; + dev->dvb.frontend->ops.set_voltage = geniatech_dvbs_set_voltage; } break; case CX88_BOARD_PINNACLE_PCTV_HD_800i: - fe0->dvb.frontend = dvb_attach(s5h1409_attach, + dev->dvb.frontend = dvb_attach(s5h1409_attach, &pinnacle_pctv_hd_800i_config, &core->i2c_adap); - if (fe0->dvb.frontend != NULL) { - if (!dvb_attach(xc5000_attach, fe0->dvb.frontend, + if (dev->dvb.frontend != NULL) { + if (!dvb_attach(xc5000_attach, dev->dvb.frontend, &core->i2c_adap, &pinnacle_pctv_hd_800i_tuner_config)) goto frontend_detach; } break; case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO: - fe0->dvb.frontend = dvb_attach(s5h1409_attach, + dev->dvb.frontend = dvb_attach(s5h1409_attach, &dvico_hdtv5_pci_nano_config, &core->i2c_adap); - if (fe0->dvb.frontend != NULL) { + if (dev->dvb.frontend != NULL) { struct dvb_frontend *fe; struct xc2028_config cfg = { .i2c_adap = &core->i2c_adap, @@ -950,17 +889,17 @@ static int dvb_register(struct cx8802_dev *dev) }; fe = dvb_attach(xc2028_attach, - fe0->dvb.frontend, &cfg); + dev->dvb.frontend, &cfg); if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) fe->ops.tuner_ops.set_config(fe, &ctl); } break; case CX88_BOARD_PINNACLE_HYBRID_PCTV: - fe0->dvb.frontend = dvb_attach(zl10353_attach, + dev->dvb.frontend = dvb_attach(zl10353_attach, &cx88_pinnacle_hybrid_pctv, &core->i2c_adap); - if (fe0->dvb.frontend) { - fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL; + if (dev->dvb.frontend) { + dev->dvb.frontend->ops.i2c_gate_ctrl = NULL; if (attach_xc3028(0x61, dev) < 0) goto frontend_detach; } @@ -968,118 +907,85 @@ static int dvb_register(struct cx8802_dev *dev) case CX88_BOARD_GENIATECH_X8000_MT: dev->ts_gen_cntrl = 0x00; - fe0->dvb.frontend = dvb_attach(zl10353_attach, + dev->dvb.frontend = dvb_attach(zl10353_attach, &cx88_geniatech_x8000_mt, &core->i2c_adap); if (attach_xc3028(0x61, dev) < 0) goto frontend_detach; break; case CX88_BOARD_KWORLD_ATSC_120: - fe0->dvb.frontend = dvb_attach(s5h1409_attach, + dev->dvb.frontend = dvb_attach(s5h1409_attach, &kworld_atsc_120_config, &core->i2c_adap); if (attach_xc3028(0x61, dev) < 0) goto frontend_detach; break; case CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD: - fe0->dvb.frontend = dvb_attach(s5h1411_attach, + dev->dvb.frontend = dvb_attach(s5h1411_attach, &dvico_fusionhdtv7_config, &core->i2c_adap); - if (fe0->dvb.frontend != NULL) { - if (!dvb_attach(xc5000_attach, fe0->dvb.frontend, + if (dev->dvb.frontend != NULL) { + if (!dvb_attach(xc5000_attach, dev->dvb.frontend, &core->i2c_adap, &dvico_fusionhdtv7_tuner_config)) goto frontend_detach; } break; case CX88_BOARD_HAUPPAUGE_HVR4000: - /* DVB-S/S2 Init */ - fe0->dvb.frontend = dvb_attach(cx24116_attach, - &hauppauge_hvr4000_config, - &dev->core->i2c_adap); - if (fe0->dvb.frontend) { - if(!dvb_attach(isl6421_attach, fe0->dvb.frontend, - &dev->core->i2c_adap, 0x08, ISL6421_DCL, 0x00)) { - dprintk( 1, "%s(): HVR4000 - DVB-S LNB Init: failed\n", __func__); - } - } else { - dprintk( 1, "%s(): HVR4000 - DVB-S Init: failed\n", __func__); - } - /* DVB-T Init */ - fe1 = videobuf_dvb_get_frontend(&dev->frontends, 2); - if (fe1) { - dev->frontends.gate = 2; - mfe_shared = 1; - fe1->dvb.frontend = dvb_attach(cx22702_attach, - &hauppauge_hvr_config, - &dev->core->i2c_adap); - if (fe1->dvb.frontend) { - fe1->dvb.frontend->id = 1; - if(!dvb_attach(simple_tuner_attach, fe1->dvb.frontend, - &dev->core->i2c_adap, 0x61, - TUNER_PHILIPS_FMD1216ME_MK3)) { - dprintk( 1, "%s(): HVR4000 - DVB-T misc Init: failed\n", __func__); - } - } else { - dprintk( 1, "%s(): HVR4000 - DVB-T Init: failed\n", __func__); - } - } else { - dprintk( 1, "%s(): HVR4000 - DVB-T Init: can't find frontend 2.\n", __func__); - } - break; case CX88_BOARD_HAUPPAUGE_HVR4000LITE: - fe0->dvb.frontend = dvb_attach(cx24116_attach, + /* Support for DVB-S only, not DVB-T support */ + dev->dvb.frontend = dvb_attach(cx24116_attach, &hauppauge_hvr4000_config, &dev->core->i2c_adap); - if (fe0->dvb.frontend) { - dvb_attach(isl6421_attach, fe0->dvb.frontend, + if (dev->dvb.frontend) { + dvb_attach(isl6421_attach, dev->dvb.frontend, &dev->core->i2c_adap, 0x08, ISL6421_DCL, 0x00); } break; case CX88_BOARD_TEVII_S420: - fe0->dvb.frontend = dvb_attach(stv0299_attach, + dev->dvb.frontend = dvb_attach(stv0299_attach, &tevii_tuner_sharp_config, &core->i2c_adap); - if (fe0->dvb.frontend != NULL) { - if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 0x60, + if (dev->dvb.frontend != NULL) { + if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60, &core->i2c_adap, DVB_PLL_OPERA1)) goto frontend_detach; - core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage; - fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage; + core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage; + dev->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage; } else { - fe0->dvb.frontend = dvb_attach(stv0288_attach, + dev->dvb.frontend = dvb_attach(stv0288_attach, &tevii_tuner_earda_config, &core->i2c_adap); - if (fe0->dvb.frontend != NULL) { - if (!dvb_attach(stb6000_attach, fe0->dvb.frontend, 0x61, + if (dev->dvb.frontend != NULL) { + if (!dvb_attach(stb6000_attach, dev->dvb.frontend, 0x61, &core->i2c_adap)) goto frontend_detach; - core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage; - fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage; + core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage; + dev->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage; } } break; case CX88_BOARD_TEVII_S460: - fe0->dvb.frontend = dvb_attach(cx24116_attach, + dev->dvb.frontend = dvb_attach(cx24116_attach, &tevii_s460_config, &core->i2c_adap); - if (fe0->dvb.frontend != NULL) { - core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage; - fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage; + if (dev->dvb.frontend != NULL) { + core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage; + dev->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage; } break; case CX88_BOARD_OMICOM_SS4_PCI: case CX88_BOARD_TBS_8920: case CX88_BOARD_PROF_7300: - fe0->dvb.frontend = dvb_attach(cx24116_attach, + dev->dvb.frontend = dvb_attach(cx24116_attach, &hauppauge_hvr4000_config, &core->i2c_adap); - if (fe0->dvb.frontend != NULL) { - core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage; - fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage; + if (dev->dvb.frontend != NULL) { + core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage; + dev->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage; } break; default: @@ -1087,32 +993,29 @@ static int dvb_register(struct cx8802_dev *dev) core->name); break; } - - if ( (NULL == fe0->dvb.frontend) || (fe1 && NULL == fe1->dvb.frontend) ) { + if (NULL == dev->dvb.frontend) { printk(KERN_ERR "%s/2: frontend initialization failed\n", core->name); return -EINVAL; } /* define general-purpose callback pointer */ - fe0->dvb.frontend->callback = cx88_tuner_callback; + dev->dvb.frontend->callback = cx88_tuner_callback; /* Ensure all frontends negotiate bus access */ - fe0->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl; - if (fe1) - fe1->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl; + dev->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl; /* Put the analog decoder in standby to keep it quiet */ cx88_call_i2c_clients(core, TUNER_SET_STANDBY, NULL); /* register everything */ - return videobuf_dvb_register_bus(&dev->frontends, THIS_MODULE, dev, - &dev->pci->dev, adapter_nr, mfe_shared); + return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev, + &dev->pci->dev, adapter_nr); frontend_detach: - if (fe0->dvb.frontend) { - dvb_frontend_detach(fe0->dvb.frontend); - fe0->dvb.frontend = NULL; + if (dev->dvb.frontend) { + dvb_frontend_detach(dev->dvb.frontend); + dev->dvb.frontend = NULL; } return -EINVAL; } @@ -1136,38 +1039,6 @@ static int cx8802_dvb_advise_acquire(struct cx8802_driver *drv) cx_clear(MO_GP0_IO, 0x00000004); udelay(1000); break; - - case CX88_BOARD_HAUPPAUGE_HVR3000: - case CX88_BOARD_HAUPPAUGE_HVR4000: - if(core->dvbdev->frontends.active_fe_id == 1) { - /* DVB-S/S2 Enabled */ - - /* Toggle reset on cx22702 leaving i2c active */ - cx_write(MO_GP0_IO, (core->board.input[0].gpio0 & 0x0000ff00) | 0x00000080); - udelay(1000); - cx_clear(MO_GP0_IO, 0x00000080); - udelay(50); - cx_set(MO_GP0_IO, 0x00000080); /* cx22702 out of reset */ - cx_set(MO_GP0_IO, 0x00000004); /* tri-state the cx22702 pins */ - udelay(1000); - - cx_write(MO_SRST_IO, 1); /* Take the cx24116/cx24123 out of reset */ - core->dvbdev->ts_gen_cntrl = 0x02; /* Parallel IO */ - } else - if (core->dvbdev->frontends.active_fe_id == 2) { - /* DVB-T Enabled */ - - /* Put the cx24116/cx24123 into reset */ - cx_write(MO_SRST_IO, 0); - - /* cx22702 out of reset and enable it */ - cx_set(MO_GP0_IO, 0x00000080); - cx_clear(MO_GP0_IO, 0x00000004); - core->dvbdev->ts_gen_cntrl = 0x0c; /* Serial IO */ - udelay(1000); - } - break; - default: err = -ENODEV; } @@ -1185,9 +1056,6 @@ static int cx8802_dvb_advise_release(struct cx8802_driver *drv) case CX88_BOARD_HAUPPAUGE_HVR1300: /* Do Nothing, leave the cx22702 on the bus. */ break; - case CX88_BOARD_HAUPPAUGE_HVR3000: - case CX88_BOARD_HAUPPAUGE_HVR4000: - break; default: err = -ENODEV; } @@ -1198,8 +1066,7 @@ static int cx8802_dvb_probe(struct cx8802_driver *drv) { struct cx88_core *core = drv->core; struct cx8802_dev *dev = drv->core->dvbdev; - int err, i; - struct videobuf_dvb_frontend *fe; + int err; dprintk( 1, "%s\n", __func__); dprintk( 1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n", @@ -1219,28 +1086,18 @@ static int cx8802_dvb_probe(struct cx8802_driver *drv) /* dvb stuff */ printk(KERN_INFO "%s/2: cx2388x based DVB/ATSC card\n", core->name); - dev->ts_gen_cntrl = 0x0c; - - for (i = 1; i <= core->board.num_frontends; i++) { - fe = videobuf_dvb_get_frontend(&core->dvbdev->frontends, i); - if (!fe) { - printk(KERN_ERR "%s() failed to get frontend(%d)\n", __func__, i); - continue; - } - videobuf_queue_sg_init(&fe->dvb.dvbq, &dvb_qops, + videobuf_queue_sg_init(&dev->dvb.dvbq, &dvb_qops, &dev->pci->dev, &dev->slock, V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_TOP, sizeof(struct cx88_buffer), dev); - /* init struct videobuf_dvb */ - fe->dvb.name = dev->core->name; - } err = dvb_register(dev); if (err != 0) printk(KERN_ERR "%s/2: dvb_register failed (err = %d)\n", core->name, err); -fail_core: + + fail_core: return err; } @@ -1248,7 +1105,9 @@ static int cx8802_dvb_remove(struct cx8802_driver *drv) { struct cx8802_dev *dev = drv->core->dvbdev; - videobuf_dvb_unregister_bus(&dev->frontends); + /* dvb */ + if (dev->dvb.frontend) + videobuf_dvb_unregister(&dev->dvb); vp3054_i2c_remove(dev); diff --git a/trunk/drivers/media/video/cx88/cx88-i2c.c b/trunk/drivers/media/video/cx88/cx88-i2c.c index 01de23007095..8e74d64fdcd2 100644 --- a/trunk/drivers/media/video/cx88/cx88-i2c.c +++ b/trunk/drivers/media/video/cx88/cx88-i2c.c @@ -116,25 +116,18 @@ static int detach_inform(struct i2c_client *client) void cx88_call_i2c_clients(struct cx88_core *core, unsigned int cmd, void *arg) { - struct videobuf_dvb_frontends *f = &core->dvbdev->frontends; - struct videobuf_dvb_frontend *fe = NULL; if (0 != core->i2c_rc) return; #if defined(CONFIG_VIDEO_CX88_DVB) || defined(CONFIG_VIDEO_CX88_DVB_MODULE) - if (core->dvbdev && f) { - if(f->gate <= 1) /* undefined or fe0 */ - fe = videobuf_dvb_get_frontend(f, 1); - else - fe = videobuf_dvb_get_frontend(f, f->gate); - - if (fe && fe->dvb.frontend && fe->dvb.frontend->ops.i2c_gate_ctrl) - fe->dvb.frontend->ops.i2c_gate_ctrl(fe->dvb.frontend, 1); + if ( (core->dvbdev) && (core->dvbdev->dvb.frontend) ) { + if (core->dvbdev->dvb.frontend->ops.i2c_gate_ctrl) + core->dvbdev->dvb.frontend->ops.i2c_gate_ctrl(core->dvbdev->dvb.frontend, 1); i2c_clients_command(&core->i2c_adap, cmd, arg); - if (fe && fe->dvb.frontend && fe->dvb.frontend->ops.i2c_gate_ctrl) - fe->dvb.frontend->ops.i2c_gate_ctrl(fe->dvb.frontend, 0); + if (core->dvbdev->dvb.frontend->ops.i2c_gate_ctrl) + core->dvbdev->dvb.frontend->ops.i2c_gate_ctrl(core->dvbdev->dvb.frontend, 0); } else #endif i2c_clients_command(&core->i2c_adap, cmd, arg); diff --git a/trunk/drivers/media/video/cx88/cx88-mpeg.c b/trunk/drivers/media/video/cx88/cx88-mpeg.c index 6df5cf314186..a6b061c2644a 100644 --- a/trunk/drivers/media/video/cx88/cx88-mpeg.c +++ b/trunk/drivers/media/video/cx88/cx88-mpeg.c @@ -768,8 +768,7 @@ static int __devinit cx8802_probe(struct pci_dev *pci_dev, { struct cx8802_dev *dev; struct cx88_core *core; - struct videobuf_dvb_frontend *demod; - int err,i; + int err; /* general setup */ core = cx88_core_get(pci_dev); @@ -782,11 +781,6 @@ static int __devinit cx8802_probe(struct pci_dev *pci_dev, if (!core->board.mpeg) goto fail_core; - if (!core->board.num_frontends) { - printk(KERN_ERR "%s() .num_frontends should be non-zero, err = %d\n", __func__, err); - goto fail_core; - } - err = -ENOMEM; dev = kzalloc(sizeof(*dev),GFP_KERNEL); if (NULL == dev) @@ -801,20 +795,6 @@ static int __devinit cx8802_probe(struct pci_dev *pci_dev, INIT_LIST_HEAD(&dev->drvlist); list_add_tail(&dev->devlist,&cx8802_devlist); - mutex_init(&dev->frontends.lock); - INIT_LIST_HEAD(&dev->frontends.felist); - - printk(KERN_INFO "%s() allocating %d frontend(s)\n", __func__, core->board.num_frontends); - - for (i = 1; i <= core->board.num_frontends; i++) { - demod = videobuf_dvb_alloc_frontend(&dev->frontends, i); - if(demod == NULL) { - printk(KERN_ERR "%s() failed to alloc\n", __func__); - err = -ENOMEM; - goto fail_free; - } - } - /* Maintain a reference so cx88-video can query the 8802 device. */ core->dvbdev = dev; diff --git a/trunk/drivers/media/video/cx88/cx88-tvaudio.c b/trunk/drivers/media/video/cx88/cx88-tvaudio.c index 7dd506b987fe..3a1977f41e27 100644 --- a/trunk/drivers/media/video/cx88/cx88-tvaudio.c +++ b/trunk/drivers/media/video/cx88/cx88-tvaudio.c @@ -767,14 +767,6 @@ void cx88_set_tvaudio(struct cx88_core *core) case WW_FM: set_audio_standard_FM(core, radio_deemphasis); break; - case WW_I2SADC: - set_audio_start(core, 0x01); - /* Slave/Philips/Autobaud */ - cx_write(AUD_I2SINPUTCNTL, 0); - /* Switch to "I2S ADC mode" */ - cx_write(AUD_I2SCNTL, 0x1); - set_audio_finish(core, EN_I2SIN_ENABLE); - break; case WW_NONE: default: printk("%s/0: unknown tv audio mode [%d]\n", @@ -903,9 +895,6 @@ void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual) break; } break; - case WW_I2SADC: - /* DO NOTHING */ - break; } if (UNSET != ctl) { diff --git a/trunk/drivers/media/video/cx88/cx88-video.c b/trunk/drivers/media/video/cx88/cx88-video.c index 3904b73f52ee..be45955dff68 100644 --- a/trunk/drivers/media/video/cx88/cx88-video.c +++ b/trunk/drivers/media/video/cx88/cx88-video.c @@ -426,7 +426,24 @@ int cx88_video_mux(struct cx88_core *core, unsigned int input) /* if there are audioroutes defined, we have an external ADC to deal with audio */ + if (INPUT(input).audioroute) { + + /* cx2388's C-ADC is connected to the tuner only. + When used with S-Video, that ADC is busy dealing with + chroma, so an external must be used for baseband audio */ + + if (INPUT(input).type != CX88_VMUX_TELEVISION && + INPUT(input).type != CX88_RADIO) { + /* "ADC mode" */ + cx_write(AUD_I2SCNTL, 0x1); + cx_set(AUD_CTL, EN_I2SIN_ENABLE); + } else { + /* Normal mode */ + cx_write(AUD_I2SCNTL, 0x0); + cx_clear(AUD_CTL, EN_I2SIN_ENABLE); + } + /* The wm8775 module has the "2" route hardwired into the initialization. Some boards may use different routes for different inputs. HVR-1300 surely does */ @@ -437,19 +454,9 @@ int cx88_video_mux(struct cx88_core *core, unsigned int input) route.input = INPUT(input).audioroute; cx88_call_i2c_clients(core, VIDIOC_INT_S_AUDIO_ROUTING, &route); + } - /* cx2388's C-ADC is connected to the tuner only. - When used with S-Video, that ADC is busy dealing with - chroma, so an external must be used for baseband audio */ - if (INPUT(input).type != CX88_VMUX_TELEVISION ) { - /* "I2S ADC mode" */ - core->tvaudio = WW_I2SADC; - cx88_set_tvaudio(core); - } else { - /* Normal mode */ - cx_write(AUD_I2SCNTL, 0x0); - cx_clear(AUD_CTL, EN_I2SIN_ENABLE); - } + } return 0; @@ -825,24 +832,9 @@ static int video_open(struct inode *inode, struct file *file) cx_write(MO_GP0_IO, core->board.radio.gpio0); cx_write(MO_GP1_IO, core->board.radio.gpio1); cx_write(MO_GP2_IO, core->board.radio.gpio2); - if (core->board.radio.audioroute) { - if(core->board.audio_chip && - core->board.audio_chip == V4L2_IDENT_WM8775) { - struct v4l2_routing route; - - route.input = core->board.radio.audioroute; - cx88_call_i2c_clients(core, - VIDIOC_INT_S_AUDIO_ROUTING, &route); - } - /* "I2S ADC mode" */ - core->tvaudio = WW_I2SADC; - cx88_set_tvaudio(core); - } else { - /* FM Mode */ - core->tvaudio = WW_FM; - cx88_set_tvaudio(core); - cx88_set_stereo(core,V4L2_TUNER_MODE_STEREO,1); - } + core->tvaudio = WW_FM; + cx88_set_tvaudio(core); + cx88_set_stereo(core,V4L2_TUNER_MODE_STEREO,1); cx88_call_i2c_clients(core,AUDC_SET_RADIO,NULL); } unlock_kernel(); diff --git a/trunk/drivers/media/video/cx88/cx88.h b/trunk/drivers/media/video/cx88/cx88.h index 76207c2856b7..dbf01b8b57a5 100644 --- a/trunk/drivers/media/video/cx88/cx88.h +++ b/trunk/drivers/media/video/cx88/cx88.h @@ -247,7 +247,7 @@ struct cx88_input { enum cx88_itype type; u32 gpio0, gpio1, gpio2, gpio3; unsigned int vmux:2; - unsigned int audioroute:4; + unsigned int audioroute:2; }; struct cx88_board { @@ -261,7 +261,6 @@ struct cx88_board { struct cx88_input radio; enum cx88_board_type mpeg; unsigned int audio_chip; - int num_frontends; }; struct cx88_subid { @@ -357,7 +356,6 @@ struct cx88_core { struct cx8802_dev *dvbdev; enum cx88_board_type active_type_id; int active_ref; - int active_fe_id; }; struct cx8800_dev; @@ -492,7 +490,7 @@ struct cx8802_dev { #if defined(CONFIG_VIDEO_CX88_DVB) || defined(CONFIG_VIDEO_CX88_DVB_MODULE) /* for dvb only */ - struct videobuf_dvb_frontends frontends; + struct videobuf_dvb dvb; #endif #if defined(CONFIG_VIDEO_CX88_VP3054) || \ @@ -630,7 +628,6 @@ extern void cx88_setup_xc3028(struct cx88_core *core, struct xc2028_ctrl *ctl); #define WW_EIAJ 7 #define WW_I2SPT 8 #define WW_FM 9 -#define WW_I2SADC 10 void cx88_set_tvaudio(struct cx88_core *core); void cx88_newstation(struct cx88_core *core); diff --git a/trunk/drivers/media/video/gspca/gspca.c b/trunk/drivers/media/video/gspca/gspca.c index e48fbfc8ad05..c21af312ee7c 100644 --- a/trunk/drivers/media/video/gspca/gspca.c +++ b/trunk/drivers/media/video/gspca/gspca.c @@ -21,7 +21,6 @@ #define MODULE_NAME "gspca" #include -#include #include #include #include @@ -404,7 +403,7 @@ static void destroy_urbs(struct gspca_dev *gspca_dev) unsigned int i; PDEBUG(D_STREAM, "kill transfer"); - for (i = 0; i < MAX_NURBS; i++) { + for (i = 0; i < MAX_NURBS; ++i) { urb = gspca_dev->urb[i]; if (urb == NULL) break; diff --git a/trunk/drivers/media/video/gspca/gspca.h b/trunk/drivers/media/video/gspca/gspca.h index 1d9dc90b4791..4779dd0b06da 100644 --- a/trunk/drivers/media/video/gspca/gspca.h +++ b/trunk/drivers/media/video/gspca/gspca.h @@ -2,6 +2,7 @@ #define GSPCAV2_H #include +#include #include #include #include diff --git a/trunk/drivers/media/video/gspca/m5602/m5602_bridge.h b/trunk/drivers/media/video/gspca/m5602/m5602_bridge.h index 1a37ae4bc82d..c786d7d3d44a 100644 --- a/trunk/drivers/media/video/gspca/m5602/m5602_bridge.h +++ b/trunk/drivers/media/video/gspca/m5602/m5602_bridge.h @@ -1,7 +1,7 @@ /* * USB Driver for ALi m5602 based webcams * - * Copyright (C) 2008 Erik Andrén + * Copyright (C) 2008 Erik Andren * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. * Copyright (C) 2005 m5603x Linux Driver Project * @@ -25,6 +25,33 @@ /*****************************************************************************/ +#undef PDEBUG +#undef info +#undef err + +#define err(format, arg...) printk(KERN_ERR KBUILD_MODNAME ": " \ + format "\n" , ## arg) +#define info(format, arg...) printk(KERN_INFO KBUILD_MODNAME ": " \ + format "\n" , ## arg) + +/* Debug parameters */ +#define DBG_INIT 0x1 +#define DBG_PROBE 0x2 +#define DBG_V4L2 0x4 +#define DBG_TRACE 0x8 +#define DBG_DATA 0x10 +#define DBG_V4L2_CID 0x20 +#define DBG_GSPCA 0x40 + +#define PDEBUG(level, fmt, args...) \ + do { \ + if (m5602_debug & level) \ + info("[%s:%d] " fmt, __func__, __LINE__ , \ + ## args); \ + } while (0) + +/*****************************************************************************/ + #define M5602_XB_SENSOR_TYPE 0x00 #define M5602_XB_SENSOR_CTRL 0x01 #define M5602_XB_LINE_OF_FRAME_H 0x02 diff --git a/trunk/drivers/media/video/gspca/m5602/m5602_core.c b/trunk/drivers/media/video/gspca/m5602/m5602_core.c index fd6ce384b487..19d5e351ccc1 100644 --- a/trunk/drivers/media/video/gspca/m5602/m5602_core.c +++ b/trunk/drivers/media/video/gspca/m5602/m5602_core.c @@ -1,7 +1,7 @@ - /* +/* * USB Driver for ALi m5602 based webcams * - * Copyright (C) 2008 Erik Andrén + * Copyright (C) 2008 Erik Andren * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. * Copyright (C) 2005 m5603x Linux Driver Project * @@ -26,6 +26,7 @@ int force_sensor; int dump_bridge; int dump_sensor; +unsigned int m5602_debug; static const __devinitdata struct usb_device_id m5602_table[] = { {USB_DEVICE(0x0402, 0x5602)}, @@ -47,7 +48,7 @@ int m5602_read_bridge(struct sd *sd, u8 address, u8 *i2c_data) 1, M5602_URB_MSG_TIMEOUT); *i2c_data = buf[0]; - PDEBUG(D_CONF, "Reading bridge register 0x%x containing 0x%x", + PDEBUG(DBG_TRACE, "Reading bridge register 0x%x containing 0x%x", address, *i2c_data); /* usb_control_msg(...) returns the number of bytes sent upon success, @@ -62,7 +63,7 @@ int m5602_write_bridge(struct sd *sd, u8 address, u8 i2c_data) struct usb_device *udev = sd->gspca_dev.dev; __u8 *buf = sd->gspca_dev.usb_buf; - PDEBUG(D_CONF, "Writing bridge register 0x%x with 0x%x", + PDEBUG(DBG_TRACE, "Writing bridge register 0x%x with 0x%x", address, i2c_data); memcpy(buf, bridge_urb_skeleton, @@ -90,8 +91,7 @@ static void m5602_dump_bridge(struct sd *sd) m5602_read_bridge(sd, i, &val); info("ALi m5602 address 0x%x contains 0x%x", i, val); } - info("Warning: The ALi m5602 webcam probably won't work " - "until it's power cycled"); + info("Warning: The camera probably won't work until it's power cycled"); } static int m5602_probe_sensor(struct sd *sd) @@ -135,7 +135,7 @@ static int m5602_init(struct gspca_dev *gspca_dev) struct sd *sd = (struct sd *) gspca_dev; int err; - PDEBUG(D_CONF, "Initializing ALi m5602 webcam"); + PDEBUG(DBG_TRACE, "Initializing ALi m5602 webcam"); /* Run the init sequence */ err = sd->sensor->init(sd); @@ -146,18 +146,16 @@ static int m5602_start_transfer(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; __u8 *buf = sd->gspca_dev.usb_buf; - int err; /* Send start command to the camera */ const u8 buffer[4] = {0x13, 0xf9, 0x0f, 0x01}; memcpy(buf, buffer, sizeof(buffer)); - err = usb_control_msg(gspca_dev->dev, - usb_sndctrlpipe(gspca_dev->dev, 0), - 0x04, 0x40, 0x19, 0x0000, buf, - 4, M5602_URB_MSG_TIMEOUT); + usb_control_msg(gspca_dev->dev, usb_sndctrlpipe(gspca_dev->dev, 0), + 0x04, 0x40, 0x19, 0x0000, buf, + 4, M5602_URB_MSG_TIMEOUT); - PDEBUG(D_STREAM, "Transfer started"); - return (err < 0) ? err : 0; + PDEBUG(DBG_V4L2, "Transfer started"); + return 0; } static void m5602_urb_complete(struct gspca_dev *gspca_dev, @@ -167,14 +165,14 @@ static void m5602_urb_complete(struct gspca_dev *gspca_dev, struct sd *sd = (struct sd *) gspca_dev; if (len < 6) { - PDEBUG(D_PACK, "Packet is less than 6 bytes"); + PDEBUG(DBG_DATA, "Packet is less than 6 bytes"); return; } /* Frame delimiter: ff xx xx xx ff ff */ if (data[0] == 0xff && data[4] == 0xff && data[5] == 0xff && data[2] != sd->frame_id) { - PDEBUG(D_FRAM, "Frame delimiter detected"); + PDEBUG(DBG_DATA, "Frame delimiter detected"); sd->frame_id = data[2]; /* Remove the extra fluff appended on each header */ @@ -189,7 +187,7 @@ static void m5602_urb_complete(struct gspca_dev *gspca_dev, /* Create a new frame */ gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len); - PDEBUG(D_FRAM, "Starting new frame %d", + PDEBUG(DBG_V4L2, "Starting new frame %d", sd->frame_count); } else { @@ -200,7 +198,7 @@ static void m5602_urb_complete(struct gspca_dev *gspca_dev, len -= 4; if (cur_frame_len + len <= frame->v4l2_buf.length) { - PDEBUG(D_FRAM, "Continuing frame %d copying %d bytes", + PDEBUG(DBG_DATA, "Continuing frame %d copying %d bytes", sd->frame_count, len); gspca_frame_add(gspca_dev, INTER_PACKET, frame, @@ -236,6 +234,8 @@ static int m5602_configure(struct gspca_dev *gspca_dev, struct cam *cam; int err; + PDEBUG(DBG_GSPCA, "m5602_configure start"); + cam = &gspca_dev->cam; cam->epaddr = M5602_ISOC_ENDPOINT_ADDR; sd->desc = &sd_desc; @@ -248,10 +248,11 @@ static int m5602_configure(struct gspca_dev *gspca_dev, if (err) goto fail; + PDEBUG(DBG_GSPCA, "m5602_configure end"); return 0; fail: - PDEBUG(D_ERR, "ALi m5602 webcam failed"); + PDEBUG(DBG_GSPCA, "m5602_configure failed"); cam->cam_mode = NULL; cam->nmodes = 0; @@ -281,13 +282,13 @@ static int __init mod_m5602_init(void) { if (usb_register(&sd_driver) < 0) return -1; - PDEBUG(D_PROBE, "registered"); + PDEBUG(D_PROBE, "m5602 module registered"); return 0; } static void __exit mod_m5602_exit(void) { usb_deregister(&sd_driver); - PDEBUG(D_PROBE, "deregistered"); + PDEBUG(D_PROBE, "m5602 module deregistered"); } module_init(mod_m5602_init); @@ -296,6 +297,9 @@ module_exit(mod_m5602_exit); MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); +module_param_named(debug, m5602_debug, int, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(debug, "toggles debug on/off"); + module_param(force_sensor, int, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(force_sensor, "force detection of sensor, " diff --git a/trunk/drivers/media/video/gspca/m5602/m5602_mt9m111.c b/trunk/drivers/media/video/gspca/m5602/m5602_mt9m111.c index fb700c2d055a..566d4925a0e8 100644 --- a/trunk/drivers/media/video/gspca/m5602/m5602_mt9m111.c +++ b/trunk/drivers/media/video/gspca/m5602/m5602_mt9m111.c @@ -1,7 +1,7 @@ /* * Driver for the mt9m111 sensor * - * Copyright (C) 2008 Erik Andrén + * Copyright (C) 2008 Erik Andren * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. * Copyright (C) 2005 m5603x Linux Driver Project * @@ -107,7 +107,7 @@ int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) err = mt9m111_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, data, 2); *val = data[0] & MT9M111_RMB_MIRROR_ROWS; - PDEBUG(D_V4L2, "Read vertical flip %d", *val); + PDEBUG(DBG_V4L2_CID, "Read vertical flip %d", *val); return (err < 0) ? err : 0; } @@ -118,7 +118,7 @@ int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val) u8 data[2] = {0x00, 0x00}; struct sd *sd = (struct sd *) gspca_dev; - PDEBUG(D_V4L2, "Set vertical flip to %d", val); + PDEBUG(DBG_V4L2_CID, "Set vertical flip to %d", val); /* Set the correct page map */ 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) err = mt9m111_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, data, 2); *val = data[0] & MT9M111_RMB_MIRROR_COLS; - PDEBUG(D_V4L2, "Read horizontal flip %d", *val); + PDEBUG(DBG_V4L2_CID, "Read horizontal flip %d", *val); return (err < 0) ? err : 0; } @@ -156,7 +156,7 @@ int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val) u8 data[2] = {0x00, 0x00}; struct sd *sd = (struct sd *) gspca_dev; - PDEBUG(D_V4L2, "Set horizontal flip to %d", val); + PDEBUG(DBG_V4L2_CID, "Set horizontal flip to %d", val); /* Set the correct page map */ 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) ((tmp & (1 << 8)) * 2) | (tmp & 0x7f); - PDEBUG(D_V4L2, "Read gain %d", *val); + PDEBUG(DBG_V4L2_CID, "Read gain %d", *val); return (err < 0) ? err : 0; } @@ -222,7 +222,7 @@ int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val) data[1] = (tmp & 0xff00) >> 8; data[0] = (tmp & 0xff); - PDEBUG(D_V4L2, "tmp=%d, data[1]=%d, data[0]=%d", tmp, + PDEBUG(DBG_V4L2_CID, "tmp=%d, data[1]=%d, data[0]=%d", tmp, data[1], data[0]); err = mt9m111_write_sensor(sd, MT9M111_SC_GLOBAL_GAIN, @@ -257,7 +257,7 @@ int mt9m111_read_sensor(struct sd *sd, const u8 address, for (i = 0; i < len && !err; i++) { err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i])); - PDEBUG(D_CONF, "Reading sensor register " + PDEBUG(DBG_TRACE, "Reading sensor register " "0x%x contains 0x%x ", address, *i2c_data); } out: @@ -290,7 +290,7 @@ int mt9m111_write_sensor(struct sd *sd, const u8 address, memcpy(p, sensor_urb_skeleton + 16, 4); p[3] = i2c_data[i]; p += 4; - PDEBUG(D_CONF, "Writing sensor register 0x%x with 0x%x", + PDEBUG(DBG_TRACE, "Writing sensor register 0x%x with 0x%x", address, i2c_data[i]); } diff --git a/trunk/drivers/media/video/gspca/m5602/m5602_mt9m111.h b/trunk/drivers/media/video/gspca/m5602/m5602_mt9m111.h index 315209d5aeef..79a5d8878190 100644 --- a/trunk/drivers/media/video/gspca/m5602/m5602_mt9m111.h +++ b/trunk/drivers/media/video/gspca/m5602/m5602_mt9m111.h @@ -1,7 +1,7 @@ /* * Driver for the mt9m111 sensor * - * Copyright (C) 2008 Erik Andrén + * Copyright (C) 2008 Erik Andren * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. * Copyright (C) 2005 m5603x Linux Driver Project * @@ -82,6 +82,7 @@ /* Kernel module parameters */ extern int force_sensor; extern int dump_sensor; +extern unsigned int m5602_debug; int mt9m111_probe(struct sd *sd); int mt9m111_init(struct sd *sd); @@ -151,8 +152,8 @@ static struct m5602_sensor mt9m111 = { .default_value = DEFAULT_GAIN, .flags = V4L2_CTRL_FLAG_SLIDER }, - .set = mt9m111_set_gain, - .get = mt9m111_get_gain + .set = mt9m111_set_hflip, + .get = mt9m111_get_hflip } }, diff --git a/trunk/drivers/media/video/gspca/m5602/m5602_ov9650.c b/trunk/drivers/media/video/gspca/m5602/m5602_ov9650.c index 837c7e47661c..31c5896250e7 100644 --- a/trunk/drivers/media/video/gspca/m5602/m5602_ov9650.c +++ b/trunk/drivers/media/video/gspca/m5602/m5602_ov9650.c @@ -1,7 +1,7 @@ /* * Driver for the ov9650 sensor * - * Copyright (C) 2008 Erik Andrén + * Copyright (C) 2008 Erik Andren * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. * Copyright (C) 2005 m5603x Linux Driver Project * @@ -40,7 +40,7 @@ int ov9650_read_sensor(struct sd *sd, const u8 address, for (i = 0; i < len; i++) { err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i])); - PDEBUG(D_CONF, "Reading sensor register " + PDEBUG(DBG_TRACE, "Reading sensor register " "0x%x containing 0x%x ", address, *i2c_data); } return (err < 0) ? err : 0; @@ -72,7 +72,7 @@ int ov9650_write_sensor(struct sd *sd, const u8 address, memcpy(p, sensor_urb_skeleton + 16, 4); p[3] = i2c_data[i]; p += 4; - PDEBUG(D_CONF, "Writing sensor register 0x%x with 0x%x", + PDEBUG(DBG_TRACE, "Writing sensor register 0x%x with 0x%x", address, i2c_data[i]); } @@ -199,7 +199,7 @@ int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) goto out; *val |= (i2c_data & 0x3f) << 10; - PDEBUG(D_V4L2, "Read exposure %d", *val); + PDEBUG(DBG_V4L2_CID, "Read exposure %d", *val); out: return (err < 0) ? err : 0; } @@ -210,7 +210,7 @@ int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val) u8 i2c_data; int err; - PDEBUG(D_V4L2, "Set exposure to %d", + PDEBUG(DBG_V4L2_CID, "Set exposure to %d", val & 0xffff); /* The 6 MSBs */ @@ -246,7 +246,7 @@ int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val) err = ov9650_read_sensor(sd, OV9650_GAIN, &i2c_data, 1); *val |= i2c_data; - PDEBUG(D_V4L2, "Read gain %d", *val); + PDEBUG(DBG_V4L2_CID, "Read gain %d", *val); return (err < 0) ? err : 0; } @@ -280,7 +280,7 @@ int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val) err = ov9650_read_sensor(sd, OV9650_RED, &i2c_data, 1); *val = i2c_data; - PDEBUG(D_V4L2, "Read red gain %d", *val); + PDEBUG(DBG_V4L2_CID, "Read red gain %d", *val); return (err < 0) ? err : 0; } @@ -291,7 +291,7 @@ int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) u8 i2c_data; struct sd *sd = (struct sd *) gspca_dev; - PDEBUG(D_V4L2, "Set red gain to %d", + PDEBUG(DBG_V4L2_CID, "Set red gain to %d", val & 0xff); i2c_data = val & 0xff; @@ -309,7 +309,7 @@ int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val) err = ov9650_read_sensor(sd, OV9650_BLUE, &i2c_data, 1); *val = i2c_data; - PDEBUG(D_V4L2, "Read blue gain %d", *val); + PDEBUG(DBG_V4L2_CID, "Read blue gain %d", *val); return (err < 0) ? err : 0; } @@ -320,7 +320,7 @@ int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val) u8 i2c_data; struct sd *sd = (struct sd *) gspca_dev; - PDEBUG(D_V4L2, "Set blue gain to %d", + PDEBUG(DBG_V4L2_CID, "Set blue gain to %d", val & 0xff); i2c_data = val & 0xff; @@ -340,7 +340,7 @@ int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) *val = ((i2c_data & OV9650_HFLIP) >> 5) ? 0 : 1; else *val = (i2c_data & OV9650_HFLIP) >> 5; - PDEBUG(D_V4L2, "Read horizontal flip %d", *val); + PDEBUG(DBG_V4L2_CID, "Read horizontal flip %d", *val); return (err < 0) ? err : 0; } @@ -351,7 +351,7 @@ int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val) u8 i2c_data; struct sd *sd = (struct sd *) gspca_dev; - PDEBUG(D_V4L2, "Set horizontal flip to %d", val); + PDEBUG(DBG_V4L2_CID, "Set horizontal flip to %d", val); err = ov9650_read_sensor(sd, OV9650_MVFP, &i2c_data, 1); if (err < 0) goto out; @@ -379,7 +379,7 @@ int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) *val = ((i2c_data & 0x10) >> 4) ? 0 : 1; else *val = (i2c_data & 0x10) >> 4; - PDEBUG(D_V4L2, "Read vertical flip %d", *val); + PDEBUG(DBG_V4L2_CID, "Read vertical flip %d", *val); return (err < 0) ? err : 0; } @@ -390,7 +390,7 @@ int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val) u8 i2c_data; struct sd *sd = (struct sd *) gspca_dev; - PDEBUG(D_V4L2, "Set vertical flip to %d", val); + PDEBUG(DBG_V4L2_CID, "Set vertical flip to %d", val); err = ov9650_read_sensor(sd, OV9650_MVFP, &i2c_data, 1); if (err < 0) goto out; @@ -420,7 +420,7 @@ int ov9650_get_brightness(struct gspca_dev *gspca_dev, __s32 *val) err = ov9650_read_sensor(sd, OV9650_GAIN, &i2c_data, 1); *val |= i2c_data; - PDEBUG(D_V4L2, "Read gain %d", *val); + PDEBUG(DBG_V4L2_CID, "Read gain %d", *val); out: return (err < 0) ? err : 0; } @@ -431,7 +431,7 @@ int ov9650_set_brightness(struct gspca_dev *gspca_dev, __s32 val) u8 i2c_data; struct sd *sd = (struct sd *) gspca_dev; - PDEBUG(D_V4L2, "Set gain to %d", val & 0x3ff); + PDEBUG(DBG_V4L2_CID, "Set gain to %d", val & 0x3ff); /* Read the OV9650_VREF register first to avoid corrupting the VREF high and low bits */ @@ -461,7 +461,7 @@ int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev, __s32 *val) err = ov9650_read_sensor(sd, OV9650_COM8, &i2c_data, 1); *val = (i2c_data & OV9650_AWB_EN) >> 1; - PDEBUG(D_V4L2, "Read auto white balance %d", *val); + PDEBUG(DBG_V4L2_CID, "Read auto white balance %d", *val); return (err < 0) ? err : 0; } @@ -472,7 +472,7 @@ int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, __s32 val) u8 i2c_data; struct sd *sd = (struct sd *) gspca_dev; - PDEBUG(D_V4L2, "Set auto white balance to %d", val); + PDEBUG(DBG_V4L2_CID, "Set auto white balance to %d", val); err = ov9650_read_sensor(sd, OV9650_COM8, &i2c_data, 1); if (err < 0) goto out; @@ -491,7 +491,7 @@ int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val) err = ov9650_read_sensor(sd, OV9650_COM8, &i2c_data, 1); *val = (i2c_data & OV9650_AGC_EN) >> 2; - PDEBUG(D_V4L2, "Read auto gain control %d", *val); + PDEBUG(DBG_V4L2_CID, "Read auto gain control %d", *val); return (err < 0) ? err : 0; } @@ -502,7 +502,7 @@ int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val) u8 i2c_data; struct sd *sd = (struct sd *) gspca_dev; - PDEBUG(D_V4L2, "Set auto gain control to %d", val); + PDEBUG(DBG_V4L2_CID, "Set auto gain control to %d", val); err = ov9650_read_sensor(sd, OV9650_COM8, &i2c_data, 1); if (err < 0) goto out; diff --git a/trunk/drivers/media/video/gspca/m5602/m5602_ov9650.h b/trunk/drivers/media/video/gspca/m5602/m5602_ov9650.h index 065632f0378e..2f29cb056f30 100644 --- a/trunk/drivers/media/video/gspca/m5602/m5602_ov9650.h +++ b/trunk/drivers/media/video/gspca/m5602/m5602_ov9650.h @@ -1,7 +1,7 @@ /* * Driver for the ov9650 sensor * - * Copyright (C) 2008 Erik Andrén + * Copyright (C) 2008 Erik Andren * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. * Copyright (C) 2005 m5603x Linux Driver Project * @@ -121,6 +121,7 @@ /* Kernel module parameters */ extern int force_sensor; extern int dump_sensor; +extern unsigned int m5602_debug; int ov9650_probe(struct sd *sd); int ov9650_init(struct sd *sd); diff --git a/trunk/drivers/media/video/gspca/m5602/m5602_po1030.c b/trunk/drivers/media/video/gspca/m5602/m5602_po1030.c index d17ac52566e6..08c015bde115 100644 --- a/trunk/drivers/media/video/gspca/m5602/m5602_po1030.c +++ b/trunk/drivers/media/video/gspca/m5602/m5602_po1030.c @@ -1,7 +1,7 @@ /* * Driver for the po1030 sensor * - * Copyright (c) 2008 Erik Andrén + * Copyright (c) 2008 Erik Andren * Copyright (c) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. * Copyright (c) 2005 m5603x Linux Driver Project * @@ -82,7 +82,7 @@ int po1030_read_sensor(struct sd *sd, const u8 address, for (i = 0; i < len; i++) { err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i])); - PDEBUG(D_CONF, "Reading sensor register " + PDEBUG(DBG_TRACE, "Reading sensor register " "0x%x containing 0x%x ", address, *i2c_data); } return (err < 0) ? err : 0; @@ -112,7 +112,7 @@ int po1030_write_sensor(struct sd *sd, const u8 address, memcpy(p, sensor_urb_skeleton + 16, 4); p[3] = i2c_data[i]; p += 4; - PDEBUG(D_CONF, "Writing sensor register 0x%x with 0x%x", + PDEBUG(DBG_TRACE, "Writing sensor register 0x%x with 0x%x", address, i2c_data[i]); } @@ -185,7 +185,7 @@ int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) &i2c_data, 1); *val |= i2c_data; - PDEBUG(D_V4L2, "Exposure read as %d", *val); + PDEBUG(DBG_V4L2_CID, "Exposure read as %d", *val); out: return (err < 0) ? err : 0; } @@ -196,10 +196,10 @@ int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val) u8 i2c_data; int err; - PDEBUG(D_V4L2, "Set exposure to %d", val & 0xffff); + PDEBUG(DBG_V4L2, "Set exposure to %d", val & 0xffff); i2c_data = ((val & 0xff00) >> 8); - PDEBUG(D_V4L2, "Set exposure to high byte to 0x%x", + PDEBUG(DBG_V4L2, "Set exposure to high byte to 0x%x", i2c_data); err = po1030_write_sensor(sd, PO1030_REG_INTEGLINES_H, @@ -208,7 +208,7 @@ int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val) goto out; i2c_data = (val & 0xff); - PDEBUG(D_V4L2, "Set exposure to low byte to 0x%x", + PDEBUG(DBG_V4L2, "Set exposure to low byte to 0x%x", i2c_data); err = po1030_write_sensor(sd, PO1030_REG_INTEGLINES_M, &i2c_data, 1); @@ -226,71 +226,7 @@ int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val) err = po1030_read_sensor(sd, PO1030_REG_GLOBALGAIN, &i2c_data, 1); *val = i2c_data; - PDEBUG(D_V4L2, "Read global gain %d", *val); - - return (err < 0) ? err : 0; -} - -int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - u8 i2c_data; - int err; - - err = po1030_read_sensor(sd, PO1030_REG_CONTROL2, - &i2c_data, 1); - - *val = (i2c_data >> 7) & 0x01 ; - - PDEBUG(D_V4L2, "Read hflip %d", *val); - - return (err < 0) ? err : 0; -} - -int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - u8 i2c_data; - int err; - - PDEBUG(D_V4L2, "Set hflip %d", val); - - i2c_data = (val & 0x01) << 7; - - err = po1030_write_sensor(sd, PO1030_REG_CONTROL2, - &i2c_data, 1); - - return (err < 0) ? err : 0; -} - -int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - u8 i2c_data; - int err; - - err = po1030_read_sensor(sd, PO1030_REG_GLOBALGAIN, - &i2c_data, 1); - - *val = (i2c_data >> 6) & 0x01; - - PDEBUG(D_V4L2, "Read vflip %d", *val); - - return (err < 0) ? err : 0; -} - -int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - u8 i2c_data; - int err; - - PDEBUG(D_V4L2, "Set vflip %d", val); - - i2c_data = (val & 0x01) << 6; - - err = po1030_write_sensor(sd, PO1030_REG_CONTROL2, - &i2c_data, 1); + PDEBUG(DBG_V4L2_CID, "Read global gain %d", *val); return (err < 0) ? err : 0; } @@ -302,7 +238,7 @@ int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val) int err; i2c_data = val & 0xff; - PDEBUG(D_V4L2, "Set global gain to %d", i2c_data); + PDEBUG(DBG_V4L2, "Set global gain to %d", i2c_data); err = po1030_write_sensor(sd, PO1030_REG_GLOBALGAIN, &i2c_data, 1); return (err < 0) ? err : 0; @@ -317,7 +253,7 @@ int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val) err = po1030_read_sensor(sd, PO1030_REG_RED_GAIN, &i2c_data, 1); *val = i2c_data; - PDEBUG(D_V4L2, "Read red gain %d", *val); + PDEBUG(DBG_V4L2_CID, "Read red gain %d", *val); return (err < 0) ? err : 0; } @@ -328,7 +264,7 @@ int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) int err; i2c_data = val & 0xff; - PDEBUG(D_V4L2, "Set red gain to %d", i2c_data); + PDEBUG(DBG_V4L2, "Set red gain to %d", i2c_data); err = po1030_write_sensor(sd, PO1030_REG_RED_GAIN, &i2c_data, 1); return (err < 0) ? err : 0; @@ -343,7 +279,7 @@ int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val) err = po1030_read_sensor(sd, PO1030_REG_BLUE_GAIN, &i2c_data, 1); *val = i2c_data; - PDEBUG(D_V4L2, "Read blue gain %d", *val); + PDEBUG(DBG_V4L2_CID, "Read blue gain %d", *val); return (err < 0) ? err : 0; } @@ -354,7 +290,7 @@ int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val) u8 i2c_data; int err; i2c_data = val & 0xff; - PDEBUG(D_V4L2, "Set blue gain to %d", i2c_data); + PDEBUG(DBG_V4L2, "Set blue gain to %d", i2c_data); err = po1030_write_sensor(sd, PO1030_REG_BLUE_GAIN, &i2c_data, 1); diff --git a/trunk/drivers/media/video/gspca/m5602/m5602_po1030.h b/trunk/drivers/media/video/gspca/m5602/m5602_po1030.h index a0b75ff61d79..68f34c97bf44 100644 --- a/trunk/drivers/media/video/gspca/m5602/m5602_po1030.h +++ b/trunk/drivers/media/video/gspca/m5602/m5602_po1030.h @@ -1,7 +1,8 @@ /* * Driver for the po1030 sensor. + * This is probably a pixel plus sensor but we haven't identified it yet * - * Copyright (c) 2008 Erik Andrén + * Copyright (c) 2008 Erik Andren * Copyright (c) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. * Copyright (c) 2005 m5603x Linux Driver Project * @@ -108,13 +109,10 @@ #define PO1030_REG_YCONTRAST 0x74 #define PO1030_REG_YSATURATION 0x75 -#define PO1030_HFLIP (1 << 7) -#define PO1030_VFLIP (1 << 6) - /*****************************************************************************/ #define PO1030_GLOBAL_GAIN_DEFAULT 0x12 -#define PO1030_EXPOSURE_DEFAULT 0x0085 +#define PO1030_EXPOSURE_DEFAULT 0xf0ff #define PO1030_BLUE_GAIN_DEFAULT 0x40 #define PO1030_RED_GAIN_DEFAULT 0x40 @@ -123,6 +121,7 @@ /* Kernel module parameters */ extern int force_sensor; extern int dump_sensor; +extern unsigned int m5602_debug; int po1030_probe(struct sd *sd); int po1030_init(struct sd *sd); @@ -143,10 +142,6 @@ int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val); int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val); int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val); int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val); -int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); -int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val); -int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); -int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val); static struct m5602_sensor po1030 = { .name = "PO1030", @@ -157,7 +152,7 @@ static struct m5602_sensor po1030 = { .init = po1030_init, .power_down = po1030_power_down, - .nctrls = 6, + .nctrls = 4, .ctrls = { { { @@ -165,7 +160,7 @@ static struct m5602_sensor po1030 = { .type = V4L2_CTRL_TYPE_INTEGER, .name = "gain", .minimum = 0x00, - .maximum = 0x4f, + .maximum = 0xff, .step = 0x1, .default_value = PO1030_GLOBAL_GAIN_DEFAULT, .flags = V4L2_CTRL_FLAG_SLIDER @@ -178,7 +173,7 @@ static struct m5602_sensor po1030 = { .type = V4L2_CTRL_TYPE_INTEGER, .name = "exposure", .minimum = 0x00, - .maximum = 0x02ff, + .maximum = 0xffff, .step = 0x1, .default_value = PO1030_EXPOSURE_DEFAULT, .flags = V4L2_CTRL_FLAG_SLIDER @@ -211,33 +206,8 @@ static struct m5602_sensor po1030 = { }, .set = po1030_set_blue_balance, .get = po1030_get_blue_balance - }, { - { - .id = V4L2_CID_HFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "horizontal flip", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - .set = po1030_set_hflip, - .get = po1030_get_hflip - }, { - { - .id = V4L2_CID_VFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "vertical flip", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - .set = po1030_set_vflip, - .get = po1030_get_vflip } }, - .nmodes = 1, .modes = { { @@ -411,7 +381,7 @@ static const unsigned char init_po1030[][4] = /* Set the y window to 1 */ {SENSOR, PO1030_REG_WINDOWY_H, 0x00}, - {SENSOR, PO1030_REG_WINDOWY_L, 0x01}, + {SENSOR, PO1030_REG_WINDOWX_L, 0x01}, {SENSOR, PO1030_REG_WINDOWWIDTH_H, 0x02}, {SENSOR, PO1030_REG_WINDOWWIDTH_L, 0x87}, diff --git a/trunk/drivers/media/video/gspca/m5602/m5602_s5k4aa.c b/trunk/drivers/media/video/gspca/m5602/m5602_s5k4aa.c index 14b1eac5b812..68202565325d 100644 --- a/trunk/drivers/media/video/gspca/m5602/m5602_s5k4aa.c +++ b/trunk/drivers/media/video/gspca/m5602/m5602_s5k4aa.c @@ -1,7 +1,7 @@ /* * Driver for the s5k4aa sensor * - * Copyright (C) 2008 Erik Andrén + * Copyright (C) 2008 Erik Andren * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. * Copyright (C) 2005 m5603x Linux Driver Project * @@ -117,7 +117,7 @@ int s5k4aa_read_sensor(struct sd *sd, const u8 address, for (i = 0; (i < len) & !err; i++) { err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i])); - PDEBUG(D_CONF, "Reading sensor register " + PDEBUG(DBG_TRACE, "Reading sensor register " "0x%x containing 0x%x ", address, *i2c_data); } out: @@ -150,7 +150,7 @@ int s5k4aa_write_sensor(struct sd *sd, const u8 address, memcpy(p, sensor_urb_skeleton + 16, 4); p[3] = i2c_data[i]; p += 4; - PDEBUG(D_CONF, "Writing sensor register 0x%x with 0x%x", + PDEBUG(DBG_TRACE, "Writing sensor register 0x%x with 0x%x", address, i2c_data[i]); } @@ -248,7 +248,7 @@ int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) *val = data << 8; err = s5k4aa_read_sensor(sd, S5K4AA_EXPOSURE_LO, &data, 1); *val |= data; - PDEBUG(D_V4L2, "Read exposure %d", *val); + PDEBUG(DBG_V4L2_CID, "Read exposure %d", *val); out: return (err < 0) ? err : 0; } @@ -259,7 +259,7 @@ int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val) u8 data = S5K4AA_PAGE_MAP_2; int err; - PDEBUG(D_V4L2, "Set exposure to %d", val); + PDEBUG(DBG_V4L2_CID, "Set exposure to %d", val); err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); if (err < 0) goto out; @@ -285,7 +285,7 @@ int s5k4aa_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) err = s5k4aa_read_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); *val = (data & S5K4AA_RM_V_FLIP) >> 7; - PDEBUG(D_V4L2, "Read vertical flip %d", *val); + PDEBUG(DBG_V4L2_CID, "Read vertical flip %d", *val); out: return (err < 0) ? err : 0; @@ -297,7 +297,7 @@ int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val) u8 data = S5K4AA_PAGE_MAP_2; int err; - PDEBUG(D_V4L2, "Set vertical flip to %d", val); + PDEBUG(DBG_V4L2_CID, "Set vertical flip to %d", val); err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); if (err < 0) goto out; @@ -341,7 +341,7 @@ int s5k4aa_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) err = s5k4aa_read_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); *val = (data & S5K4AA_RM_H_FLIP) >> 6; - PDEBUG(D_V4L2, "Read horizontal flip %d", *val); + PDEBUG(DBG_V4L2_CID, "Read horizontal flip %d", *val); out: return (err < 0) ? err : 0; } @@ -352,7 +352,7 @@ int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val) u8 data = S5K4AA_PAGE_MAP_2; int err; - PDEBUG(D_V4L2, "Set horizontal flip to %d", + PDEBUG(DBG_V4L2_CID, "Set horizontal flip to %d", val); err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); if (err < 0) @@ -397,7 +397,7 @@ int s5k4aa_get_gain(struct gspca_dev *gspca_dev, __s32 *val) err = s5k4aa_read_sensor(sd, S5K4AA_GAIN_2, &data, 1); *val = data; - PDEBUG(D_V4L2, "Read gain %d", *val); + PDEBUG(DBG_V4L2_CID, "Read gain %d", *val); out: return (err < 0) ? err : 0; @@ -409,7 +409,7 @@ int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val) u8 data = S5K4AA_PAGE_MAP_2; int err; - PDEBUG(D_V4L2, "Set gain to %d", val); + PDEBUG(DBG_V4L2_CID, "Set gain to %d", val); err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); if (err < 0) goto out; diff --git a/trunk/drivers/media/video/gspca/m5602/m5602_s5k4aa.h b/trunk/drivers/media/video/gspca/m5602/m5602_s5k4aa.h index eaef67655afa..bb7f7e3e90af 100644 --- a/trunk/drivers/media/video/gspca/m5602/m5602_s5k4aa.h +++ b/trunk/drivers/media/video/gspca/m5602/m5602_s5k4aa.h @@ -1,7 +1,7 @@ /* * Driver for the s5k4aa sensor * - * Copyright (C) 2008 Erik Andrén + * Copyright (C) 2008 Erik Andren * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. * Copyright (C) 2005 m5603x Linux Driver Project * @@ -63,6 +63,7 @@ /* Kernel module parameters */ extern int force_sensor; extern int dump_sensor; +extern unsigned int m5602_debug; int s5k4aa_probe(struct sd *sd); int s5k4aa_init(struct sd *sd); diff --git a/trunk/drivers/media/video/gspca/m5602/m5602_s5k83a.c b/trunk/drivers/media/video/gspca/m5602/m5602_s5k83a.c index 8988a728e0b4..b4b33c2d0499 100644 --- a/trunk/drivers/media/video/gspca/m5602/m5602_s5k83a.c +++ b/trunk/drivers/media/video/gspca/m5602/m5602_s5k83a.c @@ -1,7 +1,7 @@ /* * Driver for the s5k83a sensor * - * Copyright (C) 2008 Erik Andrén + * Copyright (C) 2008 Erik Andren * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. * Copyright (C) 2005 m5603x Linux Driver Project * @@ -101,7 +101,7 @@ int s5k83a_read_sensor(struct sd *sd, const u8 address, for (i = 0; i < len && !len; i++) { err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i])); - PDEBUG(D_CONF, "Reading sensor register " + PDEBUG(DBG_TRACE, "Reading sensor register " "0x%x containing 0x%x ", address, *i2c_data); } @@ -135,7 +135,7 @@ int s5k83a_write_sensor(struct sd *sd, const u8 address, memcpy(p, sensor_urb_skeleton + 16, 4); p[3] = i2c_data[i]; p += 4; - PDEBUG(D_CONF, "Writing sensor register 0x%x with 0x%x", + PDEBUG(DBG_TRACE, "Writing sensor register 0x%x with 0x%x", address, i2c_data[i]); } diff --git a/trunk/drivers/media/video/gspca/m5602/m5602_s5k83a.h b/trunk/drivers/media/video/gspca/m5602/m5602_s5k83a.h index ee3ee9cfca1d..833708eb5a42 100644 --- a/trunk/drivers/media/video/gspca/m5602/m5602_s5k83a.h +++ b/trunk/drivers/media/video/gspca/m5602/m5602_s5k83a.h @@ -1,7 +1,7 @@ /* * Driver for the s5k83a sensor * - * Copyright (C) 2008 Erik Andrén + * Copyright (C) 2008 Erik Andren * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. * Copyright (C) 2005 m5603x Linux Driver Project * @@ -41,6 +41,8 @@ /* Kernel module parameters */ extern int force_sensor; extern int dump_sensor; +extern unsigned int m5602_debug; + int s5k83a_probe(struct sd *sd); int s5k83a_init(struct sd *sd); diff --git a/trunk/drivers/media/video/gspca/m5602/m5602_sensor.h b/trunk/drivers/media/video/gspca/m5602/m5602_sensor.h index 60c9a48e0c02..930fcaab4416 100644 --- a/trunk/drivers/media/video/gspca/m5602/m5602_sensor.h +++ b/trunk/drivers/media/video/gspca/m5602/m5602_sensor.h @@ -1,7 +1,7 @@ /* * USB Driver for ALi m5602 based webcams * - * Copyright (C) 2008 Erik Andrén + * Copyright (C) 2008 Erik Andren * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. * Copyright (C) 2005 m5603x Linux Driver Project * diff --git a/trunk/drivers/media/video/gspca/t613.c b/trunk/drivers/media/video/gspca/t613.c index eac245d7a756..b561f7c4f066 100644 --- a/trunk/drivers/media/video/gspca/t613.c +++ b/trunk/drivers/media/video/gspca/t613.c @@ -50,7 +50,7 @@ struct sd { __u8 sensor; #define SENSOR_TAS5130A 0 -#define SENSOR_OM6802 1 +#define SENSOR_OTHER 1 }; /* V4L2 controls supported by the driver */ @@ -188,7 +188,7 @@ static struct ctrl sd_ctrls[] = { .minimum = 0, .maximum = 1, .step = 1, - .default_value = 0, + .default_value = 1, }, .set = sd_setwhitebalance, .get = sd_getwhitebalance @@ -261,59 +261,6 @@ static struct v4l2_pix_format vga_mode_t16[] = { .priv = 0}, }; -/* sensor specific data */ -struct additional_sensor_data { - const __u8 data1[20]; - const __u8 data2[18]; - const __u8 data3[18]; - const __u8 data4[4]; - const __u8 data5[6]; - const __u8 stream[4]; -}; - -const static struct additional_sensor_data sensor_data[] = { - { /* TAS5130A */ - .data1 = - {0xd0, 0xbb, 0xd1, 0x28, 0xd2, 0x10, 0xd3, 0x10, - 0xd4, 0xbb, 0xd5, 0x28, 0xd6, 0x1e, 0xd7, 0x27, - 0xd8, 0xc8, 0xd9, 0xfc}, - .data2 = - {0xe0, 0x60, 0xe1, 0xa8, 0xe2, 0xe0, 0xe3, 0x60, - 0xe4, 0xa8, 0xe5, 0xe0, 0xe6, 0x60, 0xe7, 0xa8, - 0xe8, 0xe0}, - .data3 = - {0xc7, 0x60, 0xc8, 0xa8, 0xc9, 0xe0, 0xca, 0x60, - 0xcb, 0xa8, 0xcc, 0xe0, 0xcd, 0x60, 0xce, 0xa8, - 0xcf, 0xe0}, - .data4 = /* Freq (50/60Hz). Splitted for test purpose */ - {0x66, 0x00, 0xa8, 0xe8}, - .data5 = - {0x0c, 0x03, 0xab, 0x10, 0x81, 0x20}, - .stream = - {0x0b, 0x04, 0x0a, 0x40}, - }, - { /* OM6802 */ - .data1 = - {0xd0, 0xc2, 0xd1, 0x28, 0xd2, 0x0f, 0xd3, 0x22, - 0xd4, 0xcd, 0xd5, 0x27, 0xd6, 0x2c, 0xd7, 0x06, - 0xd8, 0xb3, 0xd9, 0xfc}, - .data2 = - {0xe0, 0x80, 0xe1, 0xff, 0xe2, 0xff, 0xe3, 0x80, - 0xe4, 0xff, 0xe5, 0xff, 0xe6, 0x80, 0xe7, 0xff, - 0xe8, 0xff}, - .data3 = - {0xc7, 0x80, 0xc8, 0xff, 0xc9, 0xff, 0xca, 0x80, - 0xcb, 0xff, 0xcc, 0xff, 0xcd, 0x80, 0xce, 0xff, - 0xcf, 0xff}, - .data4 = /*Freq (50/60Hz). Splitted for test purpose */ - {0x66, 0xca, 0xa8, 0xf0 }, - .data5 = /* this could be removed later */ - {0x0c, 0x03, 0xab, 0x13, 0x81, 0x23}, - .stream = - {0x0b, 0x04, 0x0a, 0x78}, - } -}; - #define MAX_EFFECTS 7 /* easily done by soft, this table could be removed, * i keep it here just in case */ @@ -418,8 +365,6 @@ static const __u8 tas5130a_sensor_init[][8] = { {}, }; -static __u8 sensor_reset[] = {0x61, 0x68, 0x62, 0xff, 0x60, 0x07}; - /* read 1 byte */ static int reg_r(struct gspca_dev *gspca_dev, __u16 index) @@ -440,12 +385,12 @@ static void reg_w(struct gspca_dev *gspca_dev, usb_control_msg(gspca_dev->dev, usb_sndctrlpipe(gspca_dev->dev, 0), 0, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, 0, index, NULL, 0, 500); } -static void reg_w_buf(struct gspca_dev *gspca_dev, +static void i2c_w(struct gspca_dev *gspca_dev, const __u8 *buffer, __u16 len) { if (len <= USB_BUF_SZ) { @@ -453,7 +398,7 @@ static void reg_w_buf(struct gspca_dev *gspca_dev, usb_control_msg(gspca_dev->dev, usb_sndctrlpipe(gspca_dev->dev, 0), 0, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, 0x01, 0, gspca_dev->usb_buf, len, 500); } else { @@ -464,15 +409,14 @@ static void reg_w_buf(struct gspca_dev *gspca_dev, usb_control_msg(gspca_dev->dev, usb_sndctrlpipe(gspca_dev->dev, 0), 0, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, 0x01, 0, tmpbuf, len, 500); kfree(tmpbuf); } } -/* Reported as OM6802*/ -static void om6802_sensor_init(struct gspca_dev *gspca_dev) +static void other_sensor_init(struct gspca_dev *gspca_dev) { int i; const __u8 *p; @@ -492,32 +436,19 @@ static void om6802_sensor_init(struct gspca_dev *gspca_dev) 0x90, 0x24, 0x91, 0xb2, 0x82, 0x32, + 0xfd, 0x00, + 0xfd, 0x01, 0xfd, 0x41, 0x00 /* table end */ }; - reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset); - msleep(5); - i = 4; - while (--i < 0) { - byte = reg_r(gspca_dev, 0x0060); - if (!(byte & 0x01)) - break; - msleep(100); - } - byte = reg_r(gspca_dev, 0x0063); - if (byte != 0x17) { - err("Bad sensor reset %02x", byte); - /* continue? */ - } - p = sensor_init; while (*p != 0) { val[1] = *p++; val[3] = *p++; if (*p == 0) reg_w(gspca_dev, 0x3c80); - reg_w_buf(gspca_dev, val, sizeof val); + i2c_w(gspca_dev, val, sizeof val); i = 4; while (--i >= 0) { msleep(15); @@ -526,8 +457,7 @@ static void om6802_sensor_init(struct gspca_dev *gspca_dev) break; } } - msleep(15); - reg_w(gspca_dev, 0x3c80); + reg_w(gspca_dev, 0x3c80); } /* this function is called at probe time */ @@ -555,75 +485,12 @@ static int sd_config(struct gspca_dev *gspca_dev, return 0; } -static void setbrightness(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - unsigned int brightness; - __u8 set6[4] = { 0x8f, 0x24, 0xc3, 0x00 }; - - brightness = sd->brightness; - if (brightness < 7) { - set6[1] = 0x26; - set6[3] = 0x70 - brightness * 0x10; - } else { - set6[3] = 0x00 + ((brightness - 7) * 0x10); - } - - reg_w_buf(gspca_dev, set6, sizeof set6); -} - -static void setcontrast(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - unsigned int contrast = sd->contrast; - __u16 reg_to_write; - - if (contrast < 7) - reg_to_write = 0x8ea9 - contrast * 0x200; - else - reg_to_write = 0x00a9 + (contrast - 7) * 0x200; - - reg_w(gspca_dev, reg_to_write); -} - -static void setcolors(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - __u16 reg_to_write; - - reg_to_write = 0x80bb + sd->colors * 0x100; /* was 0xc0 */ - reg_w(gspca_dev, reg_to_write); -} - static void setgamma(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; PDEBUG(D_CONF, "Gamma: %d", sd->gamma); - reg_w_buf(gspca_dev, gamma_table[sd->gamma], sizeof gamma_table[0]); -} - -static void setwhitebalance(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - __u8 white_balance[8] = - {0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x80, 0x38}; - - if (sd->whitebalance) - white_balance[7] = 0x3c; - - reg_w_buf(gspca_dev, white_balance, sizeof white_balance); -} - -static void setsharpness(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - __u16 reg_to_write; - - reg_to_write = 0x0aa6 + 0x1000 * sd->sharpness; - - reg_w(gspca_dev, reg_to_write); + i2c_w(gspca_dev, gamma_table[sd->gamma], sizeof gamma_table[0]); } /* this function is called at probe and resume time */ @@ -644,6 +511,8 @@ static int sd_init(struct gspca_dev *gspca_dev) {0x08, 0x03, 0x09, 0x03, 0x12, 0x04}; static const __u8 n2[] = {0x08, 0x00}; + static const __u8 nset[] = + { 0x61, 0x68, 0x62, 0xff, 0x60, 0x07 }; static const __u8 n3[] = {0x61, 0x68, 0x65, 0x0a, 0x60, 0x04}; static const __u8 n4[] = @@ -656,29 +525,51 @@ static int sd_init(struct gspca_dev *gspca_dev) 0x65, 0x0a, 0xbb, 0x86, 0xaf, 0x58, 0xb0, 0x68, 0x87, 0x40, 0x89, 0x2b, 0x8d, 0xff, 0x83, 0x40, 0xac, 0x84, 0xad, 0x86, 0xaf, 0x46}; + static const __u8 nset4[] = { + 0xe0, 0x60, 0xe1, 0xa8, 0xe2, 0xe0, 0xe3, 0x60, 0xe4, 0xa8, + 0xe5, 0xe0, 0xe6, 0x60, 0xe7, 0xa8, + 0xe8, 0xe0 + }; + /* ojo puede ser 0xe6 en vez de 0xe9 */ + static const __u8 nset2[] = { + 0xd0, 0xbb, 0xd1, 0x28, 0xd2, 0x10, 0xd3, 0x10, 0xd4, 0xbb, + 0xd5, 0x28, 0xd6, 0x1e, 0xd7, 0x27, + 0xd8, 0xc8, 0xd9, 0xfc + }; + static const __u8 missing[] = + { 0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x80, 0x38 }; + static const __u8 nset3[] = { + 0xc7, 0x60, 0xc8, 0xa8, 0xc9, 0xe0, 0xca, 0x60, 0xcb, 0xa8, + 0xcc, 0xe0, 0xcd, 0x60, 0xce, 0xa8, + 0xcf, 0xe0 + }; + static const __u8 nset5[] = + { 0x8f, 0x24, 0xc3, 0x00 }; /* bright */ + static const __u8 nset7[4] = + { 0x66, 0xca, 0xa8, 0xf8 }; /* 50/60 Hz */ static const __u8 nset9[4] = { 0x0b, 0x04, 0x0a, 0x78 }; static const __u8 nset8[6] = { 0xa8, 0xf0, 0xc6, 0x88, 0xc0, 0x00 }; + static const __u8 nset10[6] = + { 0x0c, 0x03, 0xab, 0x10, 0x81, 0x20 }; byte = reg_r(gspca_dev, 0x06); test_byte = reg_r(gspca_dev, 0x07); if (byte == 0x08 && test_byte == 0x07) { - PDEBUG(D_CONF, "sensor om6802"); - sd->sensor = SENSOR_OM6802; - } else if (byte == 0x08 && test_byte == 0x01) { - PDEBUG(D_CONF, "sensor tas5130a"); - sd->sensor = SENSOR_TAS5130A; + PDEBUG(D_CONF, "other sensor"); + sd->sensor = SENSOR_OTHER; } else { - PDEBUG(D_CONF, "unknown sensor %02x %02x", byte, test_byte); + PDEBUG(D_CONF, "sensor %02x %02x", byte, test_byte); sd->sensor = SENSOR_TAS5130A; } - reg_w_buf(gspca_dev, n1, sizeof n1); + i2c_w(gspca_dev, n1, sizeof n1); test_byte = 0; i = 5; while (--i >= 0) { - reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset); + i2c_w(gspca_dev, nset, sizeof nset); + msleep(5); test_byte = reg_r(gspca_dev, 0x0063); msleep(100); if (test_byte == 0x17) @@ -689,7 +580,7 @@ static int sd_init(struct gspca_dev *gspca_dev) /* return -EIO; */ /*fixme: test - continue */ } - reg_w_buf(gspca_dev, n2, sizeof n2); + i2c_w(gspca_dev, n2, sizeof n2); i = 0; while (read_indexs[i] != 0x00) { @@ -699,52 +590,58 @@ static int sd_init(struct gspca_dev *gspca_dev) i++; } - reg_w_buf(gspca_dev, n3, sizeof n3); - reg_w_buf(gspca_dev, n4, sizeof n4); + i2c_w(gspca_dev, n3, sizeof n3); + i2c_w(gspca_dev, n4, sizeof n4); reg_r(gspca_dev, 0x0080); reg_w(gspca_dev, 0x2c80); - - reg_w_buf(gspca_dev, sensor_data[sd->sensor].data1, - sizeof sensor_data[sd->sensor].data1); - reg_w_buf(gspca_dev, sensor_data[sd->sensor].data3, - sizeof sensor_data[sd->sensor].data3); - reg_w_buf(gspca_dev, sensor_data[sd->sensor].data2, - sizeof sensor_data[sd->sensor].data2); - + i2c_w(gspca_dev, nset2, sizeof nset2); + i2c_w(gspca_dev, nset3, sizeof nset3); + i2c_w(gspca_dev, nset4, sizeof nset4); reg_w(gspca_dev, 0x3880); reg_w(gspca_dev, 0x3880); reg_w(gspca_dev, 0x338e); - - setbrightness(gspca_dev); - setcontrast(gspca_dev); + i2c_w(gspca_dev, nset5, sizeof nset5); + reg_w(gspca_dev, 0x00a9); setgamma(gspca_dev); - setcolors(gspca_dev); - setsharpness(gspca_dev); - setwhitebalance(gspca_dev); + reg_w(gspca_dev, 0x86bb); + reg_w(gspca_dev, 0x4aa6); + + i2c_w(gspca_dev, missing, sizeof missing); - reg_w(gspca_dev, 0x2087); /* tied to white balance? */ + reg_w(gspca_dev, 0x2087); reg_w(gspca_dev, 0x2088); reg_w(gspca_dev, 0x2089); - reg_w_buf(gspca_dev, sensor_data[sd->sensor].data4, - sizeof sensor_data[sd->sensor].data4); - reg_w_buf(gspca_dev, sensor_data[sd->sensor].data5, - sizeof sensor_data[sd->sensor].data5); - reg_w_buf(gspca_dev, nset8, sizeof nset8); - reg_w_buf(gspca_dev, nset9, sizeof nset9); + i2c_w(gspca_dev, nset7, sizeof nset7); + i2c_w(gspca_dev, nset10, sizeof nset10); + i2c_w(gspca_dev, nset8, sizeof nset8); + i2c_w(gspca_dev, nset9, sizeof nset9); reg_w(gspca_dev, 0x2880); - - reg_w_buf(gspca_dev, sensor_data[sd->sensor].data1, - sizeof sensor_data[sd->sensor].data1); - reg_w_buf(gspca_dev, sensor_data[sd->sensor].data3, - sizeof sensor_data[sd->sensor].data3); - reg_w_buf(gspca_dev, sensor_data[sd->sensor].data2, - sizeof sensor_data[sd->sensor].data2); + i2c_w(gspca_dev, nset2, sizeof nset2); + i2c_w(gspca_dev, nset3, sizeof nset3); + i2c_w(gspca_dev, nset4, sizeof nset4); return 0; } +static void setbrightness(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + unsigned int brightness; + __u8 set6[4] = { 0x8f, 0x26, 0xc3, 0x00 }; + + brightness = sd->brightness; + if (brightness < 7) { + set6[3] = 0x70 - brightness * 0x10; + } else { + set6[1] = 0x24; + set6[3] = 0x00 + ((brightness - 7) * 0x10); + } + + i2c_w(gspca_dev, set6, sizeof set6); +} + static void setflip(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; @@ -754,15 +651,14 @@ static void setflip(struct gspca_dev *gspca_dev) if (sd->mirror) flipcmd[3] = 0x01; - reg_w_buf(gspca_dev, flipcmd, sizeof flipcmd); + i2c_w(gspca_dev, flipcmd, sizeof flipcmd); } static void seteffect(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - reg_w_buf(gspca_dev, effects_table[sd->effect], - sizeof effects_table[0]); + i2c_w(gspca_dev, effects_table[sd->effect], sizeof effects_table[0]); if (sd->effect == 1 || sd->effect == 5) { PDEBUG(D_CONF, "This effect have been disabled for webcam \"safety\""); @@ -775,6 +671,19 @@ static void seteffect(struct gspca_dev *gspca_dev) reg_w(gspca_dev, 0xfaa6); } +static void setwhitebalance(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + + __u8 white_balance[8] = + { 0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x80, 0x38 }; + + if (sd->whitebalance == 1) + white_balance[7] = 0x3c; + + i2c_w(gspca_dev, white_balance, sizeof white_balance); +} + static void setlightfreq(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; @@ -783,46 +692,52 @@ static void setlightfreq(struct gspca_dev *gspca_dev) if (sd->freq == 2) /* 60hz */ freq[1] = 0x00; - reg_w_buf(gspca_dev, freq, sizeof freq); + i2c_w(gspca_dev, freq, sizeof freq); } -/* Is this really needed? - * i added some module parameters for test with some users */ -static void poll_sensor(struct gspca_dev *gspca_dev) +static void setcontrast(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - static const __u8 poll1[] = - {0x67, 0x05, 0x68, 0x81, 0x69, 0x80, 0x6a, 0x82, - 0x6b, 0x68, 0x6c, 0x69, 0x72, 0xd9, 0x73, 0x34, - 0x74, 0x32, 0x75, 0x92, 0x76, 0x00, 0x09, 0x01, - 0x60, 0x14}; - static const __u8 poll2[] = - {0x67, 0x02, 0x68, 0x71, 0x69, 0x72, 0x72, 0xa9, - 0x73, 0x02, 0x73, 0x02, 0x60, 0x14}; - static const __u8 poll3[] = - {0x87, 0x3f, 0x88, 0x20, 0x89, 0x2d}; - static const __u8 poll4[] = - {0xa6, 0x0a, 0xea, 0xcf, 0xbe, 0x26, 0xb1, 0x5f, - 0xa1, 0xb1, 0xda, 0x6b, 0xdb, 0x98, 0xdf, 0x0c, - 0xc2, 0x80, 0xc3, 0x10}; - - if (sd->sensor != SENSOR_TAS5130A) { - PDEBUG(D_STREAM, "[Sensor requires polling]"); - reg_w_buf(gspca_dev, poll1, sizeof poll1); - reg_w_buf(gspca_dev, poll2, sizeof poll2); - reg_w_buf(gspca_dev, poll3, sizeof poll3); - reg_w_buf(gspca_dev, poll4, sizeof poll4); - } + unsigned int contrast = sd->contrast; + __u16 reg_to_write; + + if (contrast < 7) + reg_to_write = 0x8ea9 - (0x200 * contrast); + else + reg_to_write = (0x00a9 + ((contrast - 7) * 0x200)); + + reg_w(gspca_dev, reg_to_write); +} + +static void setcolors(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + __u16 reg_to_write; + + reg_to_write = 0xc0bb + sd->colors * 0x100; + reg_w(gspca_dev, reg_to_write); +} + +static void setsharpness(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + __u16 reg_to_write; + + reg_to_write = 0x0aa6 + 0x1000 * sd->sharpness; + + reg_w(gspca_dev, reg_to_write); } static int sd_start(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; int i, mode; + static const __u8 t1[] = { 0x66, 0x00, 0xa8, 0xe8 }; __u8 t2[] = { 0x07, 0x00, 0x0d, 0x60, 0x0e, 0x80 }; static const __u8 t3[] = { 0xb3, 0x07, 0xb4, 0x00, 0xb5, 0x88, 0xb6, 0x02, 0xb7, 0x06, 0xb8, 0x00, 0xb9, 0xe7, 0xba, 0x01 }; + static const __u8 t4[] = { 0x0b, 0x04, 0x0a, 0x40 }; mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode]. priv; switch (mode) { @@ -845,29 +760,25 @@ static int sd_start(struct gspca_dev *gspca_dev) if (sd->sensor == SENSOR_TAS5130A) { i = 0; while (tas5130a_sensor_init[i][0] != 0) { - reg_w_buf(gspca_dev, tas5130a_sensor_init[i], + i2c_w(gspca_dev, tas5130a_sensor_init[i], sizeof tas5130a_sensor_init[0]); i++; } reg_w(gspca_dev, 0x3c80); /* just in case and to keep sync with logs (for mine) */ - reg_w_buf(gspca_dev, tas5130a_sensor_init[3], + i2c_w(gspca_dev, tas5130a_sensor_init[3], sizeof tas5130a_sensor_init[0]); reg_w(gspca_dev, 0x3c80); } else { - om6802_sensor_init(gspca_dev); + other_sensor_init(gspca_dev); } - reg_w_buf(gspca_dev, sensor_data[sd->sensor].data4, - sizeof sensor_data[sd->sensor].data4); + /* just in case and to keep sync with logs (for mine) */ + i2c_w(gspca_dev, t1, sizeof t1); + i2c_w(gspca_dev, t2, sizeof t2); reg_r(gspca_dev, 0x0012); - reg_w_buf(gspca_dev, t2, sizeof t2); - reg_w_buf(gspca_dev, t3, sizeof t3); + i2c_w(gspca_dev, t3, sizeof t3); reg_w(gspca_dev, 0x0013); - msleep(15); - reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream, - sizeof sensor_data[sd->sensor].stream); - poll_sensor(gspca_dev); - + i2c_w(gspca_dev, t4, sizeof t4); /* restart on each start, just in case, sometimes regs goes wrong * when using controls from app */ setbrightness(gspca_dev); @@ -876,19 +787,6 @@ static int sd_start(struct gspca_dev *gspca_dev) return 0; } -static void sd_stopN(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream, - sizeof sensor_data[sd->sensor].stream); - msleep(20); - reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream, - sizeof sensor_data[sd->sensor].stream); - msleep(20); - reg_w(gspca_dev, 0x0309); -} - static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, /* target */ __u8 *data, /* isoc packet */ @@ -1138,7 +1036,6 @@ static const struct sd_desc sd_desc = { .config = sd_config, .init = sd_init, .start = sd_start, - .stopN = sd_stopN, .pkt_scan = sd_pkt_scan, .querymenu = sd_querymenu, }; diff --git a/trunk/drivers/media/video/ivtv/ivtv-fileops.c b/trunk/drivers/media/video/ivtv/ivtv-fileops.c index 1c404e454a36..b7457fc60ba5 100644 --- a/trunk/drivers/media/video/ivtv/ivtv-fileops.c +++ b/trunk/drivers/media/video/ivtv/ivtv-fileops.c @@ -600,14 +600,13 @@ ssize_t ivtv_v4l2_write(struct file *filp, const char __user *user_buf, size_t c since we may get here before the stream has been fully set-up */ if (mode == OUT_YUV && s->q_full.length == 0 && itv->dma_data_req_size) { while (count >= itv->dma_data_req_size) { - rc = ivtv_yuv_udma_stream_frame(itv, (void __user *)user_buf); - - if (rc < 0) - return rc; - - bytes_written += itv->dma_data_req_size; - user_buf += itv->dma_data_req_size; - count -= itv->dma_data_req_size; + if (!ivtv_yuv_udma_stream_frame (itv, (void __user *)user_buf)) { + bytes_written += itv->dma_data_req_size; + user_buf += itv->dma_data_req_size; + count -= itv->dma_data_req_size; + } else { + break; + } } if (count == 0) { IVTV_DEBUG_HI_FILE("Wrote %d bytes to %s (%d)\n", bytes_written, s->name, s->q_full.bytesused); diff --git a/trunk/drivers/media/video/ivtv/ivtv-ioctl.c b/trunk/drivers/media/video/ivtv/ivtv-ioctl.c index 208fb54842f2..8696527ab134 100644 --- a/trunk/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/trunk/drivers/media/video/ivtv/ivtv-ioctl.c @@ -509,6 +509,7 @@ static int ivtv_try_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_ static int ivtv_try_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt) { struct ivtv_open_id *id = fh; + struct ivtv *itv = id->itv; s32 w = fmt->fmt.pix.width; s32 h = fmt->fmt.pix.height; int field = fmt->fmt.pix.field; @@ -516,22 +517,7 @@ static int ivtv_try_fmt_vid_out(struct file *file, void *fh, struct v4l2_format w = min(w, 720); w = max(w, 2); - /* Why can the height be 576 even when the output is NTSC? - - Internally the buffers of the PVR350 are always set to 720x576. The - decoded video frame will always be placed in the top left corner of - this buffer. For any video which is not 720x576, the buffer will - then be cropped to remove the unused right and lower areas, with - the remaining image being scaled by the hardware to fit the display - area. The video can be scaled both up and down, so a 720x480 video - can be displayed full-screen on PAL and a 720x576 video can be - displayed without cropping on NTSC. - - Note that the scaling only occurs on the video stream, the osd - resolution is locked to the broadcast standard and not scaled. - - Thanks to Ian Armstrong for this explanation. */ - h = min(h, 576); + h = min(h, itv->is_out_50hz ? 576 : 480); h = max(h, 2); if (id->type == IVTV_DEC_STREAM_TYPE_YUV) fmt->fmt.pix.field = field; diff --git a/trunk/drivers/media/video/ks0127.c b/trunk/drivers/media/video/ks0127.c index bae2d2beb709..2fd4b4a44aa9 100644 --- a/trunk/drivers/media/video/ks0127.c +++ b/trunk/drivers/media/video/ks0127.c @@ -33,20 +33,27 @@ * V1.1 Gerard v.d. Horst Added some debugoutput, reset the video-standard */ +#ifndef __KERNEL__ +#define __KERNEL__ +#endif + #include #include #include #include #include +#include +#include +#include "ks0127.h" + #include #include -#include -#include -#include "ks0127.h" -MODULE_DESCRIPTION("KS0127 video decoder driver"); -MODULE_AUTHOR("Ryan Drake"); -MODULE_LICENSE("GPL"); +#define dprintk if (debug) printk + +/* i2c identification */ +#define I2C_KS0127_ADDON 0xD8 +#define I2C_KS0127_ONBOARD 0xDA #define KS_TYPE_UNKNOWN 0 #define KS_TYPE_0122S 1 @@ -197,6 +204,8 @@ struct adjust { }; struct ks0127 { + struct i2c_client *client; + unsigned char addr; int format_width; int format_height; int cap_width; @@ -211,18 +220,16 @@ static int debug; /* insmod parameter */ module_param(debug, int, 0); MODULE_PARM_DESC(debug, "Debug output"); +MODULE_LICENSE("GPL"); static u8 reg_defaults[64]; + + static void init_reg_defaults(void) { - static int initialized; u8 *table = reg_defaults; - if (initialized) - return; - initialized = 1; - table[KS_CMDA] = 0x2c; /* VSE=0, CCIR 601, autodetect standard */ table[KS_CMDB] = 0x12; /* VALIGN=0, AGC control and input */ table[KS_CMDC] = 0x00; /* Test options */ @@ -301,53 +308,50 @@ static void init_reg_defaults(void) * An explanation from kayork@mail.utexas.edu: * * During I2C reads, the KS0127 only samples for a stop condition - * during the place where the acknowledge bit should be. Any standard + * during the place where the acknoledge bit should be. Any standard * I2C implementation (correctly) throws in another clock transition * at the 9th bit, and the KS0127 will not recognize the stop condition * and will continue to clock out data. * * So we have to do the read ourself. Big deal. - * workaround in i2c-algo-bit + workaround in i2c-algo-bit */ -static u8 ks0127_read(struct i2c_client *c, u8 reg) +static u8 ks0127_read(struct ks0127 *ks, u8 reg) { + struct i2c_client *c = ks->client; char val = 0; struct i2c_msg msgs[] = { - { c->addr, 0, sizeof(reg), ® }, - { c->addr, I2C_M_RD | I2C_M_NO_RD_ACK, sizeof(val), &val } - }; + {c->addr, 0, sizeof(reg), ®}, + {c->addr, I2C_M_RD | I2C_M_NO_RD_ACK, sizeof(val), &val}}; int ret; ret = i2c_transfer(c->adapter, msgs, ARRAY_SIZE(msgs)); if (ret != ARRAY_SIZE(msgs)) - v4l_dbg(1, debug, c, "read error\n"); + dprintk("ks0127_write error\n"); return val; } -static void ks0127_write(struct i2c_client *c, u8 reg, u8 val) +static void ks0127_write(struct ks0127 *ks, u8 reg, u8 val) { - struct ks0127 *ks = i2c_get_clientdata(c); - char msg[] = { reg, val }; + char msg[] = {reg, val}; - if (i2c_master_send(c, msg, sizeof(msg)) != sizeof(msg)) - v4l_dbg(1, debug, c, "write error\n"); + if (i2c_master_send(ks->client, msg, sizeof(msg)) != sizeof(msg)) + dprintk("ks0127_write error\n"); ks->regs[reg] = val; } /* generic bit-twiddling */ -static void ks0127_and_or(struct i2c_client *client, u8 reg, u8 and_v, u8 or_v) +static void ks0127_and_or(struct ks0127 *ks, u8 reg, u8 and_v, u8 or_v) { - struct ks0127 *ks = i2c_get_clientdata(client); - u8 val = ks->regs[reg]; val = (val & and_v) | or_v; - ks0127_write(client, reg, val); + ks0127_write(ks, reg, val); } @@ -355,69 +359,73 @@ static void ks0127_and_or(struct i2c_client *client, u8 reg, u8 and_v, u8 or_v) /**************************************************************************** * ks0127 private api ****************************************************************************/ -static void ks0127_reset(struct i2c_client *c) +static void ks0127_reset(struct ks0127* ks) { - struct ks0127 *ks = i2c_get_clientdata(c); - u8 *table = reg_defaults; int i; + u8 *table = reg_defaults; ks->ks_type = KS_TYPE_UNKNOWN; - v4l_dbg(1, debug, c, "reset\n"); + dprintk("ks0127: reset\n"); msleep(1); /* initialize all registers to known values */ /* (except STAT, 0x21, 0x22, TEST and 0x38,0x39) */ - for (i = 1; i < 33; i++) - ks0127_write(c, i, table[i]); + for(i = 1; i < 33; i++) + ks0127_write(ks, i, table[i]); - for (i = 35; i < 40; i++) - ks0127_write(c, i, table[i]); + for(i = 35; i < 40; i++) + ks0127_write(ks, i, table[i]); - for (i = 41; i < 56; i++) - ks0127_write(c, i, table[i]); + for(i = 41; i < 56; i++) + ks0127_write(ks, i, table[i]); - for (i = 58; i < 64; i++) - ks0127_write(c, i, table[i]); + for(i = 58; i < 64; i++) + ks0127_write(ks, i, table[i]); - if ((ks0127_read(c, KS_STAT) & 0x80) == 0) { + if ((ks0127_read(ks, KS_STAT) & 0x80) == 0) { ks->ks_type = KS_TYPE_0122S; - v4l_dbg(1, debug, c, "ks0122s found\n"); + dprintk("ks0127: ks0122s Found\n"); return; } - switch (ks0127_read(c, KS_CMDE) & 0x0f) { + switch(ks0127_read(ks, KS_CMDE) & 0x0f) { + case 0: ks->ks_type = KS_TYPE_0127; - v4l_dbg(1, debug, c, "ks0127 found\n"); + dprintk("ks0127: ks0127 found\n"); break; case 9: ks->ks_type = KS_TYPE_0127B; - v4l_dbg(1, debug, c, "ks0127B Revision A found\n"); + dprintk("ks0127: ks0127B Revision A found\n"); break; default: - v4l_dbg(1, debug, c, "unknown revision\n"); + dprintk("ks0127: unknown revision\n"); break; } } -static int ks0127_command(struct i2c_client *c, unsigned cmd, void *arg) +static int ks0127_command(struct i2c_client *client, + unsigned int cmd, void *arg) { - struct ks0127 *ks = i2c_get_clientdata(c); - int *iarg = (int *)arg; + struct ks0127 *ks = i2c_get_clientdata(client); + + int *iarg = (int*)arg; + int status; if (!ks) return -ENODEV; switch (cmd) { + case DECODER_INIT: - v4l_dbg(1, debug, c, "DECODER_INIT\n"); - ks0127_reset(c); + dprintk("ks0127: command DECODER_INIT\n"); + ks0127_reset(ks); break; case DECODER_SET_INPUT: @@ -428,160 +436,161 @@ static int ks0127_command(struct i2c_client *c, unsigned cmd, void *arg) case KS_INPUT_COMPOSITE_4: case KS_INPUT_COMPOSITE_5: case KS_INPUT_COMPOSITE_6: - v4l_dbg(1, debug, c, - "DECODER_SET_INPUT %d: Composite\n", *iarg); + dprintk("ks0127: command DECODER_SET_INPUT %d: " + "Composite\n", *iarg); /* autodetect 50/60 Hz */ - ks0127_and_or(c, KS_CMDA, 0xfc, 0x00); + ks0127_and_or(ks, KS_CMDA, 0xfc, 0x00); /* VSE=0 */ - ks0127_and_or(c, KS_CMDA, ~0x40, 0x00); + ks0127_and_or(ks, KS_CMDA, ~0x40, 0x00); /* set input line */ - ks0127_and_or(c, KS_CMDB, 0xb0, *iarg); + ks0127_and_or(ks, KS_CMDB, 0xb0, *iarg); /* non-freerunning mode */ - ks0127_and_or(c, KS_CMDC, 0x70, 0x0a); + ks0127_and_or(ks, KS_CMDC, 0x70, 0x0a); /* analog input */ - ks0127_and_or(c, KS_CMDD, 0x03, 0x00); + ks0127_and_or(ks, KS_CMDD, 0x03, 0x00); /* enable chroma demodulation */ - ks0127_and_or(c, KS_CTRACK, 0xcf, 0x00); + ks0127_and_or(ks, KS_CTRACK, 0xcf, 0x00); /* chroma trap, HYBWR=1 */ - ks0127_and_or(c, KS_LUMA, 0x00, + ks0127_and_or(ks, KS_LUMA, 0x00, (reg_defaults[KS_LUMA])|0x0c); /* scaler fullbw, luma comb off */ - ks0127_and_or(c, KS_VERTIA, 0x08, 0x81); + ks0127_and_or(ks, KS_VERTIA, 0x08, 0x81); /* manual chroma comb .25 .5 .25 */ - ks0127_and_or(c, KS_VERTIC, 0x0f, 0x90); + ks0127_and_or(ks, KS_VERTIC, 0x0f, 0x90); /* chroma path delay */ - ks0127_and_or(c, KS_CHROMB, 0x0f, 0x90); + ks0127_and_or(ks, KS_CHROMB, 0x0f, 0x90); - ks0127_write(c, KS_UGAIN, reg_defaults[KS_UGAIN]); - ks0127_write(c, KS_VGAIN, reg_defaults[KS_VGAIN]); - ks0127_write(c, KS_UVOFFH, reg_defaults[KS_UVOFFH]); - ks0127_write(c, KS_UVOFFL, reg_defaults[KS_UVOFFL]); + ks0127_write(ks, KS_UGAIN, reg_defaults[KS_UGAIN]); + ks0127_write(ks, KS_VGAIN, reg_defaults[KS_VGAIN]); + ks0127_write(ks, KS_UVOFFH, reg_defaults[KS_UVOFFH]); + ks0127_write(ks, KS_UVOFFL, reg_defaults[KS_UVOFFL]); break; case KS_INPUT_SVIDEO_1: case KS_INPUT_SVIDEO_2: case KS_INPUT_SVIDEO_3: - v4l_dbg(1, debug, c, - "DECODER_SET_INPUT %d: S-Video\n", *iarg); + dprintk("ks0127: command DECODER_SET_INPUT %d: " + "S-Video\n", *iarg); /* autodetect 50/60 Hz */ - ks0127_and_or(c, KS_CMDA, 0xfc, 0x00); + ks0127_and_or(ks, KS_CMDA, 0xfc, 0x00); /* VSE=0 */ - ks0127_and_or(c, KS_CMDA, ~0x40, 0x00); + ks0127_and_or(ks, KS_CMDA, ~0x40, 0x00); /* set input line */ - ks0127_and_or(c, KS_CMDB, 0xb0, *iarg); + ks0127_and_or(ks, KS_CMDB, 0xb0, *iarg); /* non-freerunning mode */ - ks0127_and_or(c, KS_CMDC, 0x70, 0x0a); + ks0127_and_or(ks, KS_CMDC, 0x70, 0x0a); /* analog input */ - ks0127_and_or(c, KS_CMDD, 0x03, 0x00); + ks0127_and_or(ks, KS_CMDD, 0x03, 0x00); /* enable chroma demodulation */ - ks0127_and_or(c, KS_CTRACK, 0xcf, 0x00); - ks0127_and_or(c, KS_LUMA, 0x00, + ks0127_and_or(ks, KS_CTRACK, 0xcf, 0x00); + ks0127_and_or(ks, KS_LUMA, 0x00, reg_defaults[KS_LUMA]); /* disable luma comb */ - ks0127_and_or(c, KS_VERTIA, 0x08, + ks0127_and_or(ks, KS_VERTIA, 0x08, (reg_defaults[KS_VERTIA]&0xf0)|0x01); - ks0127_and_or(c, KS_VERTIC, 0x0f, + ks0127_and_or(ks, KS_VERTIC, 0x0f, reg_defaults[KS_VERTIC]&0xf0); - ks0127_and_or(c, KS_CHROMB, 0x0f, + ks0127_and_or(ks, KS_CHROMB, 0x0f, reg_defaults[KS_CHROMB]&0xf0); - ks0127_write(c, KS_UGAIN, reg_defaults[KS_UGAIN]); - ks0127_write(c, KS_VGAIN, reg_defaults[KS_VGAIN]); - ks0127_write(c, KS_UVOFFH, reg_defaults[KS_UVOFFH]); - ks0127_write(c, KS_UVOFFL, reg_defaults[KS_UVOFFL]); + ks0127_write(ks, KS_UGAIN, reg_defaults[KS_UGAIN]); + ks0127_write(ks, KS_VGAIN, reg_defaults[KS_VGAIN]); + ks0127_write(ks, KS_UVOFFH, reg_defaults[KS_UVOFFH]); + ks0127_write(ks, KS_UVOFFL, reg_defaults[KS_UVOFFL]); break; case KS_INPUT_YUV656: - v4l_dbg(1, debug, c, - "DECODER_SET_INPUT 15: YUV656\n"); + dprintk("ks0127: command DECODER_SET_INPUT 15: " + "YUV656\n"); if (ks->norm == VIDEO_MODE_NTSC || ks->norm == KS_STD_PAL_M) /* force 60 Hz */ - ks0127_and_or(c, KS_CMDA, 0xfc, 0x03); + ks0127_and_or(ks, KS_CMDA, 0xfc, 0x03); else /* force 50 Hz */ - ks0127_and_or(c, KS_CMDA, 0xfc, 0x02); + ks0127_and_or(ks, KS_CMDA, 0xfc, 0x02); - ks0127_and_or(c, KS_CMDA, 0xff, 0x40); /* VSE=1 */ + ks0127_and_or(ks, KS_CMDA, 0xff, 0x40); /* VSE=1 */ /* set input line and VALIGN */ - ks0127_and_or(c, KS_CMDB, 0xb0, (*iarg | 0x40)); + ks0127_and_or(ks, KS_CMDB, 0xb0, (*iarg | 0x40)); /* freerunning mode, */ /* TSTGEN = 1 TSTGFR=11 TSTGPH=0 TSTGPK=0 VMEM=1*/ - ks0127_and_or(c, KS_CMDC, 0x70, 0x87); + ks0127_and_or(ks, KS_CMDC, 0x70, 0x87); /* digital input, SYNDIR = 0 INPSL=01 CLKDIR=0 EAV=0 */ - ks0127_and_or(c, KS_CMDD, 0x03, 0x08); + ks0127_and_or(ks, KS_CMDD, 0x03, 0x08); /* disable chroma demodulation */ - ks0127_and_or(c, KS_CTRACK, 0xcf, 0x30); + ks0127_and_or(ks, KS_CTRACK, 0xcf, 0x30); /* HYPK =01 CTRAP = 0 HYBWR=0 PED=1 RGBH=1 UNIT=1 */ - ks0127_and_or(c, KS_LUMA, 0x00, 0x71); - ks0127_and_or(c, KS_VERTIC, 0x0f, + ks0127_and_or(ks, KS_LUMA, 0x00, 0x71); + ks0127_and_or(ks, KS_VERTIC, 0x0f, reg_defaults[KS_VERTIC]&0xf0); /* scaler fullbw, luma comb off */ - ks0127_and_or(c, KS_VERTIA, 0x08, 0x81); + ks0127_and_or(ks, KS_VERTIA, 0x08, 0x81); - ks0127_and_or(c, KS_CHROMB, 0x0f, + ks0127_and_or(ks, KS_CHROMB, 0x0f, reg_defaults[KS_CHROMB]&0xf0); - ks0127_and_or(c, KS_CON, 0x00, 0x00); - ks0127_and_or(c, KS_BRT, 0x00, 32); /* spec: 34 */ + ks0127_and_or(ks, KS_CON, 0x00, 0x00); + ks0127_and_or(ks, KS_BRT, 0x00, 32); /* spec: 34 */ /* spec: 229 (e5) */ - ks0127_and_or(c, KS_SAT, 0x00, 0xe8); - ks0127_and_or(c, KS_HUE, 0x00, 0); + ks0127_and_or(ks, KS_SAT, 0x00, 0xe8); + ks0127_and_or(ks, KS_HUE, 0x00, 0); - ks0127_and_or(c, KS_UGAIN, 0x00, 238); - ks0127_and_or(c, KS_VGAIN, 0x00, 0x00); + ks0127_and_or(ks, KS_UGAIN, 0x00, 238); + ks0127_and_or(ks, KS_VGAIN, 0x00, 0x00); /*UOFF:0x30, VOFF:0x30, TSTCGN=1 */ - ks0127_and_or(c, KS_UVOFFH, 0x00, 0x4f); - ks0127_and_or(c, KS_UVOFFL, 0x00, 0x00); + ks0127_and_or(ks, KS_UVOFFH, 0x00, 0x4f); + ks0127_and_or(ks, KS_UVOFFL, 0x00, 0x00); break; default: - v4l_dbg(1, debug, c, - "DECODER_SET_INPUT: Unknown input %d\n", *iarg); + dprintk("ks0127: command DECODER_SET_INPUT: " + "Unknown input %d\n", *iarg); break; } /* hack: CDMLPF sometimes spontaneously switches on; */ /* force back off */ - ks0127_write(c, KS_DEMOD, reg_defaults[KS_DEMOD]); + ks0127_write(ks, KS_DEMOD, reg_defaults[KS_DEMOD]); break; case DECODER_SET_OUTPUT: switch(*iarg) { case KS_OUTPUT_YUV656E: - v4l_dbg(1, debug, c, - "DECODER_SET_OUTPUT: OUTPUT_YUV656E (Missing)\n"); + dprintk("ks0127: command DECODER_SET_OUTPUT: " + "OUTPUT_YUV656E (Missing)\n"); return -EINVAL; + break; case KS_OUTPUT_EXV: - v4l_dbg(1, debug, c, - "DECODER_SET_OUTPUT: OUTPUT_EXV\n"); - ks0127_and_or(c, KS_OFMTA, 0xf0, 0x09); + dprintk("ks0127: command DECODER_SET_OUTPUT: " + "OUTPUT_EXV\n"); + ks0127_and_or(ks, KS_OFMTA, 0xf0, 0x09); break; } break; - case DECODER_SET_NORM: /* sam This block mixes old and new norm names... */ + case DECODER_SET_NORM: //sam This block mixes old and new norm names... /* Set to automatic SECAM/Fsc mode */ - ks0127_and_or(c, KS_DEMOD, 0xf0, 0x00); + ks0127_and_or(ks, KS_DEMOD, 0xf0, 0x00); ks->norm = *iarg; - switch (*iarg) { + switch(*iarg) + { /* this is untested !! */ /* It just detects PAL_N/NTSC_M (no special frequencies) */ /* And you have to set the standard a second time afterwards */ case VIDEO_MODE_AUTO: - v4l_dbg(1, debug, c, - "DECODER_SET_NORM: AUTO\n"); + dprintk("ks0127: command DECODER_SET_NORM: AUTO\n"); /* The chip determines the format */ /* based on the current field rate */ - ks0127_and_or(c, KS_CMDA, 0xfc, 0x00); - ks0127_and_or(c, KS_CHROMA, 0x9f, 0x20); + ks0127_and_or(ks, KS_CMDA, 0xfc, 0x00); + ks0127_and_or(ks, KS_CHROMA, 0x9f, 0x20); /* This is wrong for PAL ! As I said, */ /* you need to set the standard once again !! */ ks->format_height = 240; @@ -589,86 +598,84 @@ static int ks0127_command(struct i2c_client *c, unsigned cmd, void *arg) break; case VIDEO_MODE_NTSC: - v4l_dbg(1, debug, c, - "DECODER_SET_NORM: NTSC_M\n"); - ks0127_and_or(c, KS_CHROMA, 0x9f, 0x20); + dprintk("ks0127: command DECODER_SET_NORM: NTSC_M\n"); + ks0127_and_or(ks, KS_CHROMA, 0x9f, 0x20); ks->format_height = 240; ks->format_width = 704; break; case KS_STD_NTSC_N: - v4l_dbg(1, debug, c, - "KS0127_SET_NORM: NTSC_N (fixme)\n"); - ks0127_and_or(c, KS_CHROMA, 0x9f, 0x40); + dprintk("ks0127: command KS0127_SET_STANDARD: " + "NTSC_N (fixme)\n"); + ks0127_and_or(ks, KS_CHROMA, 0x9f, 0x40); ks->format_height = 240; ks->format_width = 704; break; case VIDEO_MODE_PAL: - v4l_dbg(1, debug, c, - "DECODER_SET_NORM: PAL_N\n"); - ks0127_and_or(c, KS_CHROMA, 0x9f, 0x20); + dprintk("ks0127: command DECODER_SET_NORM: PAL_N\n"); + ks0127_and_or(ks, KS_CHROMA, 0x9f, 0x20); ks->format_height = 290; ks->format_width = 704; break; case KS_STD_PAL_M: - v4l_dbg(1, debug, c, - "KS0127_SET_NORM: PAL_M (fixme)\n"); - ks0127_and_or(c, KS_CHROMA, 0x9f, 0x40); + dprintk("ks0127: command KS0127_SET_STANDARD: " + "PAL_M (fixme)\n"); + ks0127_and_or(ks, KS_CHROMA, 0x9f, 0x40); ks->format_height = 290; ks->format_width = 704; break; case VIDEO_MODE_SECAM: - v4l_dbg(1, debug, c, - "KS0127_SET_NORM: SECAM\n"); + dprintk("ks0127: command KS0127_SET_STANDARD: " + "SECAM\n"); ks->format_height = 290; ks->format_width = 704; /* set to secam autodetection */ - ks0127_and_or(c, KS_CHROMA, 0xdf, 0x20); - ks0127_and_or(c, KS_DEMOD, 0xf0, 0x00); + ks0127_and_or(ks, KS_CHROMA, 0xdf, 0x20); + ks0127_and_or(ks, KS_DEMOD, 0xf0, 0x00); schedule_timeout_interruptible(HZ/10+1); /* did it autodetect? */ - if (ks0127_read(c, KS_DEMOD) & 0x40) + if (ks0127_read(ks, KS_DEMOD) & 0x40) break; /* force to secam mode */ - ks0127_and_or(c, KS_DEMOD, 0xf0, 0x0f); + ks0127_and_or(ks, KS_DEMOD, 0xf0, 0x0f); break; default: - v4l_dbg(1, debug, c, - "DECODER_SET_NORM: Unknown norm %d\n", *iarg); + dprintk("ks0127: command DECODER_SET_NORM: " + "Unknown norm %d\n", *iarg); break; } break; case DECODER_SET_PICTURE: - v4l_dbg(1, debug, c, - "DECODER_SET_PICTURE: not yet supported\n"); + dprintk("ks0127: command DECODER_SET_PICTURE " + "not yet supported (fixme)\n"); return -EINVAL; - /* sam todo: KS0127_SET_BRIGHTNESS: Merge into DECODER_SET_PICTURE */ - /* sam todo: KS0127_SET_CONTRAST: Merge into DECODER_SET_PICTURE */ - /* sam todo: KS0127_SET_HUE: Merge into DECODER_SET_PICTURE? */ - /* sam todo: KS0127_SET_SATURATION: Merge into DECODER_SET_PICTURE */ - /* sam todo: KS0127_SET_AGC_MODE: */ - /* sam todo: KS0127_SET_AGC: */ - /* sam todo: KS0127_SET_CHROMA_MODE: */ - /* sam todo: KS0127_SET_PIXCLK_MODE: */ - /* sam todo: KS0127_SET_GAMMA_MODE: */ - /* sam todo: KS0127_SET_UGAIN: */ - /* sam todo: KS0127_SET_VGAIN: */ - /* sam todo: KS0127_SET_INVALY: */ - /* sam todo: KS0127_SET_INVALU: */ - /* sam todo: KS0127_SET_INVALV: */ - /* sam todo: KS0127_SET_UNUSEY: */ - /* sam todo: KS0127_SET_UNUSEU: */ - /* sam todo: KS0127_SET_UNUSEV: */ - /* sam todo: KS0127_SET_VSALIGN_MODE: */ + //sam todo: KS0127_SET_BRIGHTNESS: Merge into DECODER_SET_PICTURE + //sam todo: KS0127_SET_CONTRAST: Merge into DECODER_SET_PICTURE + //sam todo: KS0127_SET_HUE: Merge into DECODER_SET_PICTURE? + //sam todo: KS0127_SET_SATURATION: Merge into DECODER_SET_PICTURE + //sam todo: KS0127_SET_AGC_MODE: + //sam todo: KS0127_SET_AGC: + //sam todo: KS0127_SET_CHROMA_MODE: + //sam todo: KS0127_SET_PIXCLK_MODE: + //sam todo: KS0127_SET_GAMMA_MODE: + //sam todo: KS0127_SET_UGAIN: + //sam todo: KS0127_SET_VGAIN: + //sam todo: KS0127_SET_INVALY: + //sam todo: KS0127_SET_INVALU: + //sam todo: KS0127_SET_INVALV: + //sam todo: KS0127_SET_UNUSEY: + //sam todo: KS0127_SET_UNUSEU: + //sam todo: KS0127_SET_UNUSEV: + //sam todo: KS0127_SET_VSALIGN_MODE: case DECODER_ENABLE_OUTPUT: { @@ -677,32 +684,34 @@ static int ks0127_command(struct i2c_client *c, unsigned cmd, void *arg) iarg = arg; enable = (*iarg != 0); if (enable) { - v4l_dbg(1, debug, c, - "DECODER_ENABLE_OUTPUT on\n"); + dprintk("ks0127: command " + "DECODER_ENABLE_OUTPUT on " + "(%d)\n", enable); /* All output pins on */ - ks0127_and_or(c, KS_OFMTA, 0xcf, 0x30); + ks0127_and_or(ks, KS_OFMTA, 0xcf, 0x30); /* Obey the OEN pin */ - ks0127_and_or(c, KS_CDEM, 0x7f, 0x00); + ks0127_and_or(ks, KS_CDEM, 0x7f, 0x00); } else { - v4l_dbg(1, debug, c, - "DECODER_ENABLE_OUTPUT off\n"); + dprintk("ks0127: command " + "DECODER_ENABLE_OUTPUT off " + "(%d)\n", enable); /* Video output pins off */ - ks0127_and_or(c, KS_OFMTA, 0xcf, 0x00); + ks0127_and_or(ks, KS_OFMTA, 0xcf, 0x00); /* Ignore the OEN pin */ - ks0127_and_or(c, KS_CDEM, 0x7f, 0x80); + ks0127_and_or(ks, KS_CDEM, 0x7f, 0x80); } - break; } + break; - /* sam todo: KS0127_SET_OUTPUT_MODE: */ - /* sam todo: KS0127_SET_WIDTH: */ - /* sam todo: KS0127_SET_HEIGHT: */ - /* sam todo: KS0127_SET_HSCALE: */ + //sam todo: KS0127_SET_OUTPUT_MODE: + //sam todo: KS0127_SET_WIDTH: + //sam todo: KS0127_SET_HEIGHT: + //sam todo: KS0127_SET_HSCALE: case DECODER_GET_STATUS: - v4l_dbg(1, debug, c, "DECODER_GET_STATUS\n"); + dprintk("ks0127: command DECODER_GET_STATUS\n"); *iarg = 0; - status = ks0127_read(c, KS_STAT); + status = ks0127_read(ks, KS_STAT); if (!(status & 0x20)) /* NOVID not set */ *iarg = (*iarg | DECODER_STATUS_GOOD); if ((status & 0x01)) /* CLOCK set */ @@ -713,81 +722,124 @@ static int ks0127_command(struct i2c_client *c, unsigned cmd, void *arg) *iarg = (*iarg | DECODER_STATUS_NTSC); break; - /* Catch any unknown command */ + //Catch any unknown command default: - v4l_dbg(1, debug, c, "unknown: 0x%08x\n", cmd); + dprintk("ks0127: command unknown: %04X\n", cmd); return -EINVAL; } return 0; } + + +static int ks0127_probe(struct i2c_adapter *adapter); +static int ks0127_detach(struct i2c_client *client); +static int ks0127_command(struct i2c_client *client, + unsigned int cmd, void *arg); + + + /* Addresses to scan */ -#define I2C_KS0127_ADDON 0xD8 -#define I2C_KS0127_ONBOARD 0xDA +static unsigned short normal_i2c[] = {I2C_KS0127_ADDON>>1, + I2C_KS0127_ONBOARD>>1, I2C_CLIENT_END}; +static unsigned short probe[2] = {I2C_CLIENT_END, I2C_CLIENT_END}; +static unsigned short ignore[2] = {I2C_CLIENT_END, I2C_CLIENT_END}; +static struct i2c_client_address_data addr_data = { + normal_i2c, + probe, + ignore, +}; -static unsigned short normal_i2c[] = { - I2C_KS0127_ADDON >> 1, - I2C_KS0127_ONBOARD >> 1, - I2C_CLIENT_END +static struct i2c_driver i2c_driver_ks0127 = { + .driver.name = "ks0127", + .id = I2C_DRIVERID_KS0127, + .attach_adapter = ks0127_probe, + .detach_client = ks0127_detach, + .command = ks0127_command }; -I2C_CLIENT_INSMOD; +static struct i2c_client ks0127_client_tmpl = +{ + .name = "(ks0127 unset)", + .addr = 0, + .adapter = NULL, + .driver = &i2c_driver_ks0127, +}; -static int ks0127_probe(struct i2c_client *c, const struct i2c_device_id *id) +static int ks0127_found_proc(struct i2c_adapter *adapter, int addr, int kind) { struct ks0127 *ks; + struct i2c_client *client; - v4l_info(c, "%s chip found @ 0x%x (%s)\n", - c->addr == (I2C_KS0127_ADDON >> 1) ? "addon" : "on-board", - c->addr << 1, c->adapter->name); + client = kzalloc(sizeof(*client), GFP_KERNEL); + if (client == NULL) + return -ENOMEM; + memcpy(client, &ks0127_client_tmpl, sizeof(*client)); ks = kzalloc(sizeof(*ks), GFP_KERNEL); - if (ks == NULL) + if (ks == NULL) { + kfree(client); return -ENOMEM; + } - i2c_set_clientdata(c, ks); + i2c_set_clientdata(client, ks); + client->adapter = adapter; + client->addr = addr; + sprintf(client->name, "ks0127-%02x", adapter->id); + ks->client = client; + ks->addr = addr; ks->ks_type = KS_TYPE_UNKNOWN; /* power up */ - init_reg_defaults(); - ks0127_write(c, KS_CMDA, 0x2c); + ks0127_write(ks, KS_CMDA, 0x2c); mdelay(10); /* reset the device */ - ks0127_reset(c); + ks0127_reset(ks); + printk(KERN_INFO "ks0127: attach: %s video decoder\n", + ks->addr==(I2C_KS0127_ADDON>>1) ? "addon" : "on-board"); + + i2c_attach_client(client); return 0; } -static int ks0127_remove(struct i2c_client *c) + +static int ks0127_probe(struct i2c_adapter *adapter) { - struct ks0127 *ks = i2c_get_clientdata(c); + if (adapter->id == I2C_HW_B_ZR36067) + return i2c_probe(adapter, &addr_data, ks0127_found_proc); + return 0; +} + +static int ks0127_detach(struct i2c_client *client) +{ + struct ks0127 *ks = i2c_get_clientdata(client); - ks0127_write(c, KS_OFMTA, 0x20); /* tristate */ - ks0127_write(c, KS_CMDA, 0x2c | 0x80); /* power down */ + ks0127_write(ks, KS_OFMTA, 0x20); /*tristate*/ + ks0127_write(ks, KS_CMDA, 0x2c | 0x80); /* power down */ + i2c_detach_client(client); kfree(ks); + kfree(client); + + dprintk("ks0127: detach\n"); return 0; } -static int ks0127_legacy_probe(struct i2c_adapter *adapter) + +static int __devinit ks0127_init_module(void) { - return adapter->id == I2C_HW_B_ZR36067; + init_reg_defaults(); + return i2c_add_driver(&i2c_driver_ks0127); } -static const struct i2c_device_id ks0127_id[] = { - { "ks0127", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, ks0127_id); - -static struct v4l2_i2c_driver_data v4l2_i2c_data = { - .name = "ks0127", - .driverid = I2C_DRIVERID_KS0127, - .command = ks0127_command, - .probe = ks0127_probe, - .remove = ks0127_remove, - .legacy_probe = ks0127_legacy_probe, - .id_table = ks0127_id, -}; +static void __devexit ks0127_cleanup_module(void) +{ + i2c_del_driver(&i2c_driver_ks0127); +} + + +module_init(ks0127_init_module); +module_exit(ks0127_cleanup_module); diff --git a/trunk/drivers/media/video/saa7110.c b/trunk/drivers/media/video/saa7110.c index adf2ba79496a..4aa82b310708 100644 --- a/trunk/drivers/media/video/saa7110.c +++ b/trunk/drivers/media/video/saa7110.c @@ -31,24 +31,36 @@ #include #include #include +#include #include -#include -#include -#include -#include -#include MODULE_DESCRIPTION("Philips SAA7110 video decoder driver"); MODULE_AUTHOR("Pauline Middelink"); MODULE_LICENSE("GPL"); +#include + +#define I2C_NAME(s) (s)->name + +#include +#include +#include + static int debug; module_param(debug, int, 0); MODULE_PARM_DESC(debug, "Debug level (0-1)"); +#define dprintk(num, format, args...) \ + do { \ + if (debug >= num) \ + printk(format, ##args); \ + } while (0) + #define SAA7110_MAX_INPUT 9 /* 6 CVBS, 3 SVHS */ #define SAA7110_MAX_OUTPUT 0 /* its a decoder only */ +#define I2C_SAA7110 0x9C /* or 0x9E */ + #define SAA7110_NR_REG 0x35 struct saa7110 { @@ -69,7 +81,10 @@ struct saa7110 { /* I2C support functions */ /* ----------------------------------------------------------------------- */ -static int saa7110_write(struct i2c_client *client, u8 reg, u8 value) +static int +saa7110_write (struct i2c_client *client, + u8 reg, + u8 value) { struct saa7110 *decoder = i2c_get_clientdata(client); @@ -77,7 +92,10 @@ static int saa7110_write(struct i2c_client *client, u8 reg, u8 value) return i2c_smbus_write_byte_data(client, reg, value); } -static int saa7110_write_block(struct i2c_client *client, const u8 *data, unsigned int len) +static int +saa7110_write_block (struct i2c_client *client, + const u8 *data, + unsigned int len) { int ret = -1; u8 reg = *data; /* first register to write to */ @@ -97,8 +115,8 @@ static int saa7110_write_block(struct i2c_client *client, const u8 *data, unsign memcpy(decoder->reg + reg, data + 1, len - 1); } else { for (++data, --len; len; len--) { - ret = saa7110_write(client, reg++, *data++); - if (ret < 0) + if ((ret = saa7110_write(client, reg++, + *data++)) < 0) break; } } @@ -106,7 +124,8 @@ static int saa7110_write_block(struct i2c_client *client, const u8 *data, unsign return ret; } -static inline int saa7110_read(struct i2c_client *client) +static inline int +saa7110_read (struct i2c_client *client) { return i2c_smbus_read_byte(client); } @@ -119,7 +138,9 @@ static inline int saa7110_read(struct i2c_client *client) #define FRESP_06H_SVIDEO 0x83 //0xC0 -static int saa7110_selmux(struct i2c_client *client, int chan) +static int +saa7110_selmux (struct i2c_client *client, + int chan) { static const unsigned char modes[9][8] = { /* mode 0 */ @@ -176,7 +197,8 @@ static const unsigned char initseq[1 + SAA7110_NR_REG] = { /* 0x30 */ 0x44, 0x71, 0x02, 0x8C, 0x02 }; -static int determine_norm(struct i2c_client *client) +static int +determine_norm (struct i2c_client *client) { DEFINE_WAIT(wait); struct saa7110 *decoder = i2c_get_clientdata(client); @@ -190,23 +212,29 @@ static int determine_norm(struct i2c_client *client) finish_wait(&decoder->wq, &wait); status = saa7110_read(client); if (status & 0x40) { - v4l_dbg(1, debug, client, "status=0x%02x (no signal)\n", status); + dprintk(1, KERN_INFO "%s: status=0x%02x (no signal)\n", + I2C_NAME(client), status); return decoder->norm; // no change } if ((status & 3) == 0) { saa7110_write(client, 0x06, 0x83); if (status & 0x20) { - v4l_dbg(1, debug, client, "status=0x%02x (NTSC/no color)\n", status); + dprintk(1, + KERN_INFO + "%s: status=0x%02x (NTSC/no color)\n", + I2C_NAME(client), status); //saa7110_write(client,0x2E,0x81); return VIDEO_MODE_NTSC; } - v4l_dbg(1, debug, client, "status=0x%02x (PAL/no color)\n", status); + dprintk(1, KERN_INFO "%s: status=0x%02x (PAL/no color)\n", + I2C_NAME(client), status); //saa7110_write(client,0x2E,0x9A); return VIDEO_MODE_PAL; } //saa7110_write(client,0x06,0x03); if (status & 0x20) { /* 60Hz */ - v4l_dbg(1, debug, client, "status=0x%02x (NTSC)\n", status); + dprintk(1, KERN_INFO "%s: status=0x%02x (NTSC)\n", + I2C_NAME(client), status); saa7110_write(client, 0x0D, 0x86); saa7110_write(client, 0x0F, 0x50); saa7110_write(client, 0x11, 0x2C); @@ -226,11 +254,13 @@ static int determine_norm(struct i2c_client *client) status = saa7110_read(client); if ((status & 0x03) == 0x01) { - v4l_dbg(1, debug, client, "status=0x%02x (SECAM)\n", status); + dprintk(1, KERN_INFO "%s: status=0x%02x (SECAM)\n", + I2C_NAME(client), status); saa7110_write(client, 0x0D, 0x87); return VIDEO_MODE_SECAM; } - v4l_dbg(1, debug, client, "status=0x%02x (PAL)\n", status); + dprintk(1, KERN_INFO "%s: status=0x%02x (PAL)\n", I2C_NAME(client), + status); return VIDEO_MODE_PAL; } @@ -256,8 +286,8 @@ saa7110_command (struct i2c_client *client, VIDEO_DECODER_SECAM | VIDEO_DECODER_AUTO; dc->inputs = SAA7110_MAX_INPUT; dc->outputs = SAA7110_MAX_OUTPUT; - break; } + break; case DECODER_GET_STATUS: { @@ -265,8 +295,8 @@ saa7110_command (struct i2c_client *client, int res = 0; status = saa7110_read(client); - v4l_dbg(1, debug, client, "status=0x%02x norm=%d\n", - status, decoder->norm); + dprintk(1, KERN_INFO "%s: status=0x%02x norm=%d\n", + I2C_NAME(client), status, decoder->norm); if (!(status & 0x40)) res |= DECODER_STATUS_GOOD; if (status & 0x03) @@ -284,8 +314,8 @@ saa7110_command (struct i2c_client *client, break; } *(int *) arg = res; - break; } + break; case DECODER_SET_NORM: v = *(int *) arg; @@ -298,24 +328,34 @@ saa7110_command (struct i2c_client *client, saa7110_write(client, 0x0F, 0x50); saa7110_write(client, 0x11, 0x2C); //saa7110_write(client, 0x2E, 0x81); - v4l_dbg(1, debug, client, "switched to NTSC\n"); + dprintk(1, + KERN_INFO "%s: switched to NTSC\n", + I2C_NAME(client)); break; case VIDEO_MODE_PAL: saa7110_write(client, 0x0D, 0x86); saa7110_write(client, 0x0F, 0x10); saa7110_write(client, 0x11, 0x59); //saa7110_write(client, 0x2E, 0x9A); - v4l_dbg(1, debug, client, "switched to PAL\n"); + dprintk(1, + KERN_INFO "%s: switched to PAL\n", + I2C_NAME(client)); break; case VIDEO_MODE_SECAM: saa7110_write(client, 0x0D, 0x87); saa7110_write(client, 0x0F, 0x10); saa7110_write(client, 0x11, 0x59); //saa7110_write(client, 0x2E, 0x9A); - v4l_dbg(1, debug, client, "switched to SECAM\n"); + dprintk(1, + KERN_INFO + "%s: switched to SECAM\n", + I2C_NAME(client)); break; case VIDEO_MODE_AUTO: - v4l_dbg(1, debug, client, "switched to AUTO\n"); + dprintk(1, + KERN_INFO + "%s: TV standard detection...\n", + I2C_NAME(client)); decoder->norm = determine_norm(client); *(int *) arg = decoder->norm; break; @@ -328,12 +368,15 @@ saa7110_command (struct i2c_client *client, case DECODER_SET_INPUT: v = *(int *) arg; if (v < 0 || v > SAA7110_MAX_INPUT) { - v4l_dbg(1, debug, client, "input=%d not available\n", v); + dprintk(1, + KERN_INFO "%s: input=%d not available\n", + I2C_NAME(client), v); return -EINVAL; } if (decoder->input != v) { saa7110_selmux(client, v); - v4l_dbg(1, debug, client, "switched to input=%d\n", v); + dprintk(1, KERN_INFO "%s: switched to input=%d\n", + I2C_NAME(client), v); } break; @@ -349,7 +392,8 @@ saa7110_command (struct i2c_client *client, if (decoder->enable != v) { decoder->enable = v; saa7110_write(client, 0x0E, v ? 0x18 : 0x80); - v4l_dbg(1, debug, client, "YUV %s\n", v ? "on" : "off"); + dprintk(1, KERN_INFO "%s: YUV %s\n", I2C_NAME(client), + v ? "on" : "off"); } break; @@ -379,23 +423,23 @@ saa7110_command (struct i2c_client *client, saa7110_write(client, 0x07, (decoder->hue >> 8) - 128); } - break; } + break; case DECODER_DUMP: - if (!debug) - break; for (v = 0; v < SAA7110_NR_REG; v += 16) { int j; - v4l_dbg(1, debug, client, "%02x:", v); + dprintk(1, KERN_DEBUG "%s: %02x:", I2C_NAME(client), + v); for (j = 0; j < 16 && v + j < SAA7110_NR_REG; j++) - printk(KERN_CONT " %02x", decoder->reg[v + j]); - printk(KERN_CONT "\n"); + dprintk(1, " %02x", decoder->reg[v + j]); + dprintk(1, "\n"); } break; default: - v4l_dbg(1, debug, client, "unknown command %08x\n", cmd); + dprintk(1, KERN_INFO "unknown saa7110_command??(%d)\n", + cmd); return -EINVAL; } return 0; @@ -407,28 +451,55 @@ saa7110_command (struct i2c_client *client, * Generic i2c probe * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1' */ +static unsigned short normal_i2c[] = { + I2C_SAA7110 >> 1, + (I2C_SAA7110 >> 1) + 1, + I2C_CLIENT_END +}; + +static unsigned short ignore = I2C_CLIENT_END; -static unsigned short normal_i2c[] = { 0x9c >> 1, 0x9e >> 1, I2C_CLIENT_END }; +static struct i2c_client_address_data addr_data = { + .normal_i2c = normal_i2c, + .probe = &ignore, + .ignore = &ignore, +}; -I2C_CLIENT_INSMOD; +static struct i2c_driver i2c_driver_saa7110; -static int saa7110_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int +saa7110_detect_client (struct i2c_adapter *adapter, + int address, + int kind) { + struct i2c_client *client; struct saa7110 *decoder; int rv; + dprintk(1, + KERN_INFO + "saa7110.c: detecting saa7110 client on address 0x%x\n", + address << 1); + /* Check if the adapter supports the needed features */ - if (!i2c_check_functionality(client->adapter, - I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) - return -ENODEV; + if (!i2c_check_functionality + (adapter, + I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) + return 0; - v4l_info(client, "chip found @ 0x%x (%s)\n", - client->addr << 1, client->adapter->name); + client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); + if (!client) + return -ENOMEM; + client->addr = address; + client->adapter = adapter; + client->driver = &i2c_driver_saa7110; + strlcpy(I2C_NAME(client), "saa7110", sizeof(I2C_NAME(client))); decoder = kzalloc(sizeof(struct saa7110), GFP_KERNEL); - if (!decoder) + if (!decoder) { + kfree(client); return -ENOMEM; + } decoder->norm = VIDEO_MODE_PAL; decoder->input = 0; decoder->enable = 1; @@ -439,10 +510,18 @@ static int saa7110_probe(struct i2c_client *client, init_waitqueue_head(&decoder->wq); i2c_set_clientdata(client, decoder); + rv = i2c_attach_client(client); + if (rv) { + kfree(client); + kfree(decoder); + return rv; + } + rv = saa7110_write_block(client, initseq, sizeof(initseq)); - if (rv < 0) { - v4l_dbg(1, debug, client, "init status %d\n", rv); - } else { + if (rv < 0) + dprintk(1, KERN_ERR "%s_attach: init status %d\n", + I2C_NAME(client), rv); + else { int ver, status; saa7110_write(client, 0x21, 0x10); saa7110_write(client, 0x0e, 0x18); @@ -451,8 +530,10 @@ static int saa7110_probe(struct i2c_client *client, saa7110_write(client, 0x0D, 0x06); //mdelay(150); status = saa7110_read(client); - v4l_dbg(1, debug, client, "version %x, status=0x%02x\n", - ver, status); + dprintk(1, + KERN_INFO + "%s_attach: SAA7110A version %x at 0x%02x, status=0x%02x\n", + I2C_NAME(client), ver, client->addr << 1, status); saa7110_write(client, 0x0D, 0x86); saa7110_write(client, 0x0F, 0x10); saa7110_write(client, 0x11, 0x59); @@ -466,25 +547,58 @@ static int saa7110_probe(struct i2c_client *client, return 0; } -static int saa7110_remove(struct i2c_client *client) +static int +saa7110_attach_adapter (struct i2c_adapter *adapter) +{ + dprintk(1, + KERN_INFO + "saa7110.c: starting probe for adapter %s (0x%x)\n", + I2C_NAME(adapter), adapter->id); + return i2c_probe(adapter, &addr_data, &saa7110_detect_client); +} + +static int +saa7110_detach_client (struct i2c_client *client) { - kfree(i2c_get_clientdata(client)); + struct saa7110 *decoder = i2c_get_clientdata(client); + int err; + + err = i2c_detach_client(client); + if (err) { + return err; + } + + kfree(decoder); + kfree(client); + return 0; } /* ----------------------------------------------------------------------- */ -static const struct i2c_device_id saa7110_id[] = { - { "saa7110", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, saa7110_id); +static struct i2c_driver i2c_driver_saa7110 = { + .driver = { + .name = "saa7110", + }, + + .id = I2C_DRIVERID_SAA7110, -static struct v4l2_i2c_driver_data v4l2_i2c_data = { - .name = "saa7110", - .driverid = I2C_DRIVERID_SAA7110, + .attach_adapter = saa7110_attach_adapter, + .detach_client = saa7110_detach_client, .command = saa7110_command, - .probe = saa7110_probe, - .remove = saa7110_remove, - .id_table = saa7110_id, }; + +static int __init +saa7110_init (void) +{ + return i2c_add_driver(&i2c_driver_saa7110); +} + +static void __exit +saa7110_exit (void) +{ + i2c_del_driver(&i2c_driver_saa7110); +} + +module_init(saa7110_init); +module_exit(saa7110_exit); diff --git a/trunk/drivers/media/video/saa7111.c b/trunk/drivers/media/video/saa7111.c index a4738a2fb4d3..96c3d4357722 100644 --- a/trunk/drivers/media/video/saa7111.c +++ b/trunk/drivers/media/video/saa7111.c @@ -28,24 +28,43 @@ */ #include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include -#include -#include #include -#include +#include +#include +#include +#include + #include #include -#include -#include MODULE_DESCRIPTION("Philips SAA7111 video decoder driver"); MODULE_AUTHOR("Dave Perks"); MODULE_LICENSE("GPL"); + +#define I2C_NAME(s) (s)->name + + static int debug; module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Debug level (0-1)"); +#define dprintk(num, format, args...) \ + do { \ + if (debug >= num) \ + printk(format, ##args); \ + } while (0) + /* ----------------------------------------------------------------------- */ #define SAA7111_NR_REG 0x18 @@ -58,9 +77,14 @@ struct saa7111 { int enable; }; +#define I2C_SAA7111 0x48 + /* ----------------------------------------------------------------------- */ -static inline int saa7111_write(struct i2c_client *client, u8 reg, u8 value) +static inline int +saa7111_write (struct i2c_client *client, + u8 reg, + u8 value) { struct saa7111 *decoder = i2c_get_clientdata(client); @@ -68,7 +92,8 @@ static inline int saa7111_write(struct i2c_client *client, u8 reg, u8 value) return i2c_smbus_write_byte_data(client, reg, value); } -static inline void saa7111_write_if_changed(struct i2c_client *client, u8 reg, u8 value) +static inline void +saa7111_write_if_changed(struct i2c_client *client, u8 reg, u8 value) { struct saa7111 *decoder = i2c_get_clientdata(client); @@ -78,7 +103,10 @@ static inline void saa7111_write_if_changed(struct i2c_client *client, u8 reg, u } } -static int saa7111_write_block(struct i2c_client *client, const u8 *data, unsigned int len) +static int +saa7111_write_block (struct i2c_client *client, + const u8 *data, + unsigned int len) { int ret = -1; u8 reg; @@ -99,17 +127,18 @@ static int saa7111_write_block(struct i2c_client *client, const u8 *data, unsign decoder->reg[reg++] = data[1]; len -= 2; data += 2; - } while (len >= 2 && data[0] == reg && block_len < 32); - ret = i2c_master_send(client, block_data, block_len); - if (ret < 0) + } while (len >= 2 && data[0] == reg && + block_len < 32); + if ((ret = i2c_master_send(client, block_data, + block_len)) < 0) break; } } else { /* do some slow I2C emulation kind of thing */ while (len >= 2) { reg = *data++; - ret = saa7111_write(client, reg, *data++); - if (ret < 0) + if ((ret = saa7111_write(client, reg, + *data++)) < 0) break; len -= 2; } @@ -118,13 +147,16 @@ static int saa7111_write_block(struct i2c_client *client, const u8 *data, unsign return ret; } -static int saa7111_init_decoder(struct i2c_client *client, - struct video_decoder_init *init) +static int +saa7111_init_decoder (struct i2c_client *client, + struct video_decoder_init *init) { return saa7111_write_block(client, init->data, init->len); } -static inline int saa7111_read(struct i2c_client *client, u8 reg) +static inline int +saa7111_read (struct i2c_client *client, + u8 reg) { return i2c_smbus_read_byte_data(client, reg); } @@ -171,23 +203,28 @@ static const unsigned char saa7111_i2c_init[] = { 0x17, 0x00, /* 17 - VBI */ }; -static int saa7111_command(struct i2c_client *client, unsigned cmd, void *arg) +static int +saa7111_command (struct i2c_client *client, + unsigned int cmd, + void *arg) { struct saa7111 *decoder = i2c_get_clientdata(client); switch (cmd) { + case 0: break; case DECODER_INIT: { struct video_decoder_init *init = arg; - struct video_decoder_init vdi; - if (NULL != init) return saa7111_init_decoder(client, init); - vdi.data = saa7111_i2c_init; - vdi.len = sizeof(saa7111_i2c_init); - return saa7111_init_decoder(client, &vdi); + else { + struct video_decoder_init vdi; + vdi.data = saa7111_i2c_init; + vdi.len = sizeof(saa7111_i2c_init); + return saa7111_init_decoder(client, &vdi); + } } case DECODER_DUMP: @@ -197,15 +234,15 @@ static int saa7111_command(struct i2c_client *client, unsigned cmd, void *arg) for (i = 0; i < SAA7111_NR_REG; i += 16) { int j; - v4l_info(client, "%03x", i); + printk(KERN_DEBUG "%s: %03x", I2C_NAME(client), i); for (j = 0; j < 16 && i + j < SAA7111_NR_REG; ++j) { - printk(KERN_CONT " %02x", + printk(" %02x", saa7111_read(client, i + j)); } - printk(KERN_CONT "\n"); + printk("\n"); } - break; } + break; case DECODER_GET_CAPABILITIES: { @@ -218,8 +255,8 @@ static int saa7111_command(struct i2c_client *client, unsigned cmd, void *arg) VIDEO_DECODER_CCIR; cap->inputs = 8; cap->outputs = 1; - break; } + break; case DECODER_GET_STATUS: { @@ -228,7 +265,8 @@ static int saa7111_command(struct i2c_client *client, unsigned cmd, void *arg) int res; status = saa7111_read(client, 0x1f); - v4l_dbg(1, debug, client, "status: 0x%02x\n", status); + dprintk(1, KERN_DEBUG "%s status: 0x%02x\n", I2C_NAME(client), + status); res = 0; if ((status & (1 << 6)) == 0) { res |= DECODER_STATUS_GOOD; @@ -256,8 +294,8 @@ static int saa7111_command(struct i2c_client *client, unsigned cmd, void *arg) res |= DECODER_STATUS_COLOR; } *iarg = res; - break; } + break; case DECODER_SET_GPIO: { @@ -324,8 +362,8 @@ static int saa7111_command(struct i2c_client *client, unsigned cmd, void *arg) } decoder->norm = *iarg; - break; } + break; case DECODER_SET_INPUT: { @@ -349,8 +387,8 @@ static int saa7111_command(struct i2c_client *client, unsigned cmd, void *arg) 3) ? 0x80 : 0)); } - break; } + break; case DECODER_SET_OUTPUT: { @@ -360,8 +398,8 @@ static int saa7111_command(struct i2c_client *client, unsigned cmd, void *arg) if (*iarg != 0) { return -EINVAL; } - break; } + break; case DECODER_ENABLE_OUTPUT: { @@ -401,8 +439,8 @@ static int saa7111_command(struct i2c_client *client, unsigned cmd, void *arg) (decoder->reg[0x11] & 0xf3)); } } - break; } + break; case DECODER_SET_PICTURE: { @@ -416,8 +454,8 @@ static int saa7111_command(struct i2c_client *client, unsigned cmd, void *arg) saa7111_write(client, 0x0c, pic->colour >> 9); /* We want -128 to 127 we get 0-65535 */ saa7111_write(client, 0x0d, (pic->hue - 32768) >> 8); - break; } + break; default: return -EINVAL; @@ -428,23 +466,48 @@ static int saa7111_command(struct i2c_client *client, unsigned cmd, void *arg) /* ----------------------------------------------------------------------- */ -static unsigned short normal_i2c[] = { 0x48 >> 1, I2C_CLIENT_END }; +/* + * Generic i2c probe + * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1' + */ +static unsigned short normal_i2c[] = { I2C_SAA7111 >> 1, I2C_CLIENT_END }; + +static unsigned short ignore = I2C_CLIENT_END; + +static struct i2c_client_address_data addr_data = { + .normal_i2c = normal_i2c, + .probe = &ignore, + .ignore = &ignore, +}; -I2C_CLIENT_INSMOD; +static struct i2c_driver i2c_driver_saa7111; -static int saa7111_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int +saa7111_detect_client (struct i2c_adapter *adapter, + int address, + int kind) { int i; + struct i2c_client *client; struct saa7111 *decoder; struct video_decoder_init vdi; + dprintk(1, + KERN_INFO + "saa7111.c: detecting saa7111 client on address 0x%x\n", + address << 1); + /* Check if the adapter supports the needed features */ - if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) - return -ENODEV; + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) + return 0; - v4l_info(client, "chip found @ 0x%x (%s)\n", - client->addr << 1, client->adapter->name); + client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); + if (!client) + return -ENOMEM; + client->addr = address; + client->adapter = adapter; + client->driver = &i2c_driver_saa7111; + strlcpy(I2C_NAME(client), "saa7111", sizeof(I2C_NAME(client))); decoder = kzalloc(sizeof(struct saa7111), GFP_KERNEL); if (decoder == NULL) { @@ -456,37 +519,82 @@ static int saa7111_probe(struct i2c_client *client, decoder->enable = 1; i2c_set_clientdata(client, decoder); + i = i2c_attach_client(client); + if (i) { + kfree(client); + kfree(decoder); + return i; + } + vdi.data = saa7111_i2c_init; vdi.len = sizeof(saa7111_i2c_init); i = saa7111_init_decoder(client, &vdi); if (i < 0) { - v4l_dbg(1, debug, client, "init status %d\n", i); + dprintk(1, KERN_ERR "%s_attach error: init status %d\n", + I2C_NAME(client), i); } else { - v4l_dbg(1, debug, client, "revision %x\n", - saa7111_read(client, 0x00) >> 4); + dprintk(1, + KERN_INFO + "%s_attach: chip version %x at address 0x%x\n", + I2C_NAME(client), saa7111_read(client, 0x00) >> 4, + client->addr << 1); } + return 0; } -static int saa7111_remove(struct i2c_client *client) +static int +saa7111_attach_adapter (struct i2c_adapter *adapter) { - kfree(i2c_get_clientdata(client)); + dprintk(1, + KERN_INFO + "saa7111.c: starting probe for adapter %s (0x%x)\n", + I2C_NAME(adapter), adapter->id); + return i2c_probe(adapter, &addr_data, &saa7111_detect_client); +} + +static int +saa7111_detach_client (struct i2c_client *client) +{ + struct saa7111 *decoder = i2c_get_clientdata(client); + int err; + + err = i2c_detach_client(client); + if (err) { + return err; + } + + kfree(decoder); + kfree(client); + return 0; } /* ----------------------------------------------------------------------- */ -static const struct i2c_device_id saa7111_id[] = { - { "saa7111_old", 0 }, /* "saa7111" maps to the saa7115 driver */ - { } -}; -MODULE_DEVICE_TABLE(i2c, saa7111_id); +static struct i2c_driver i2c_driver_saa7111 = { + .driver = { + .name = "saa7111", + }, + + .id = I2C_DRIVERID_SAA7111A, -static struct v4l2_i2c_driver_data v4l2_i2c_data = { - .name = "saa7111", - .driverid = I2C_DRIVERID_SAA7111A, + .attach_adapter = saa7111_attach_adapter, + .detach_client = saa7111_detach_client, .command = saa7111_command, - .probe = saa7111_probe, - .remove = saa7111_remove, - .id_table = saa7111_id, }; + +static int __init +saa7111_init (void) +{ + return i2c_add_driver(&i2c_driver_saa7111); +} + +static void __exit +saa7111_exit (void) +{ + i2c_del_driver(&i2c_driver_saa7111); +} + +module_init(saa7111_init); +module_exit(saa7111_exit); diff --git a/trunk/drivers/media/video/saa7114.c b/trunk/drivers/media/video/saa7114.c index 7ca709fda5f4..e79075533beb 100644 --- a/trunk/drivers/media/video/saa7114.c +++ b/trunk/drivers/media/video/saa7114.c @@ -29,24 +29,43 @@ */ #include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include -#include -#include #include -#include +#include +#include +#include +#include + #include #include -#include -#include MODULE_DESCRIPTION("Philips SAA7114H video decoder driver"); MODULE_AUTHOR("Maxim Yevtyushkin"); MODULE_LICENSE("GPL"); + +#define I2C_NAME(x) (x)->name + + static int debug; module_param(debug, int, 0); MODULE_PARM_DESC(debug, "Debug level (0-1)"); +#define dprintk(num, format, args...) \ + do { \ + if (debug >= num) \ + printk(format, ##args); \ + } while (0) + /* ----------------------------------------------------------------------- */ struct saa7114 { @@ -62,6 +81,9 @@ struct saa7114 { int playback; }; +#define I2C_SAA7114 0x42 +#define I2C_SAA7114A 0x40 + #define I2C_DELAY 10 @@ -107,12 +129,18 @@ struct saa7114 { /* ----------------------------------------------------------------------- */ -static inline int saa7114_write(struct i2c_client *client, u8 reg, u8 value) +static inline int +saa7114_write (struct i2c_client *client, + u8 reg, + u8 value) { return i2c_smbus_write_byte_data(client, reg, value); } -static int saa7114_write_block(struct i2c_client *client, const u8 *data, unsigned int len) +static int +saa7114_write_block (struct i2c_client *client, + const u8 *data, + unsigned int len) { int ret = -1; u8 reg; @@ -132,17 +160,18 @@ static int saa7114_write_block(struct i2c_client *client, const u8 *data, unsign reg++; len -= 2; data += 2; - } while (len >= 2 && data[0] == reg && block_len < 32); - ret = i2c_master_send(client, block_data, block_len); - if (ret < 0) + } while (len >= 2 && data[0] == reg && + block_len < 32); + if ((ret = i2c_master_send(client, block_data, + block_len)) < 0) break; } } else { /* do some slow I2C emulation kind of thing */ while (len >= 2) { reg = *data++; - ret = saa7114_write(client, reg, *data++); - if (ret < 0) + if ((ret = saa7114_write(client, reg, + *data++)) < 0) break; len -= 2; } @@ -151,7 +180,9 @@ static int saa7114_write_block(struct i2c_client *client, const u8 *data, unsign return ret; } -static inline int saa7114_read(struct i2c_client *client, u8 reg) +static inline int +saa7114_read (struct i2c_client *client, + u8 reg) { return i2c_smbus_read_byte_data(client, reg); } @@ -421,11 +452,15 @@ static const unsigned char init[] = { 0xef, 0x00 }; -static int saa7114_command(struct i2c_client *client, unsigned cmd, void *arg) +static int +saa7114_command (struct i2c_client *client, + unsigned int cmd, + void *arg) { struct saa7114 *decoder = i2c_get_clientdata(client); switch (cmd) { + case 0: //dprintk(1, KERN_INFO "%s: writing init\n", I2C_NAME(client)); //saa7114_write_block(client, init, sizeof(init)); @@ -435,28 +470,27 @@ static int saa7114_command(struct i2c_client *client, unsigned cmd, void *arg) { int i; - if (!debug) - break; - v4l_info(client, "decoder dump\n"); + dprintk(1, KERN_INFO "%s: decoder dump\n", I2C_NAME(client)); for (i = 0; i < 32; i += 16) { int j; - v4l_info(client, "%03x", i); + printk(KERN_DEBUG "%s: %03x", I2C_NAME(client), i); for (j = 0; j < 16; ++j) { - printk(KERN_CONT " %02x", + printk(" %02x", saa7114_read(client, i + j)); } - printk(KERN_CONT "\n"); + printk("\n"); } - break; } + break; case DECODER_GET_CAPABILITIES: { struct video_decoder_capability *cap = arg; - v4l_dbg(1, debug, client, "get capabilities\n"); + dprintk(1, KERN_DEBUG "%s: decoder get capabilities\n", + I2C_NAME(client)); cap->flags = VIDEO_DECODER_PAL | VIDEO_DECODER_NTSC | @@ -464,8 +498,8 @@ static int saa7114_command(struct i2c_client *client, unsigned cmd, void *arg) VIDEO_DECODER_CCIR; cap->inputs = 8; cap->outputs = 1; - break; } + break; case DECODER_GET_STATUS: { @@ -475,7 +509,8 @@ static int saa7114_command(struct i2c_client *client, unsigned cmd, void *arg) status = saa7114_read(client, 0x1f); - v4l_dbg(1, debug, client, "status: 0x%02x\n", status); + dprintk(1, KERN_DEBUG "%s status: 0x%02x\n", I2C_NAME(client), + status); res = 0; if ((status & (1 << 6)) == 0) { res |= DECODER_STATUS_GOOD; @@ -503,8 +538,8 @@ static int saa7114_command(struct i2c_client *client, unsigned cmd, void *arg) res |= DECODER_STATUS_COLOR; } *iarg = res; - break; } + break; case DECODER_SET_NORM: { @@ -512,11 +547,12 @@ static int saa7114_command(struct i2c_client *client, unsigned cmd, void *arg) short int hoff = 0, voff = 0, w = 0, h = 0; - v4l_dbg(1, debug, client, "set norm\n"); - + dprintk(1, KERN_DEBUG "%s: decoder set norm ", + I2C_NAME(client)); switch (*iarg) { + case VIDEO_MODE_NTSC: - v4l_dbg(1, debug, client, "NTSC\n"); + dprintk(1, "NTSC\n"); decoder->reg[REG_ADDR(0x06)] = SAA_7114_NTSC_HSYNC_START; decoder->reg[REG_ADDR(0x07)] = @@ -535,7 +571,7 @@ static int saa7114_command(struct i2c_client *client, unsigned cmd, void *arg) break; case VIDEO_MODE_PAL: - v4l_dbg(1, debug, client, "PAL\n"); + dprintk(1, "PAL\n"); decoder->reg[REG_ADDR(0x06)] = SAA_7114_PAL_HSYNC_START; decoder->reg[REG_ADDR(0x07)] = @@ -554,8 +590,9 @@ static int saa7114_command(struct i2c_client *client, unsigned cmd, void *arg) break; default: - v4l_dbg(1, debug, client, "Unknown video mode\n"); + dprintk(1, " Unknown video mode!!!\n"); return -EINVAL; + } @@ -607,20 +644,22 @@ static int saa7114_command(struct i2c_client *client, unsigned cmd, void *arg) saa7114_write(client, 0x80, 0x36); // i-port and scaler back end clock selection decoder->norm = *iarg; - break; } + break; case DECODER_SET_INPUT: { int *iarg = arg; - v4l_dbg(1, debug, client, "set input (%d)\n", *iarg); + dprintk(1, KERN_DEBUG "%s: decoder set input (%d)\n", + I2C_NAME(client), *iarg); if (*iarg < 0 || *iarg > 7) { return -EINVAL; } if (decoder->input != *iarg) { - v4l_dbg(1, debug, client, "now setting %s input\n", + dprintk(1, KERN_DEBUG "%s: now setting %s input\n", + I2C_NAME(client), *iarg >= 6 ? "S-Video" : "Composite"); decoder->input = *iarg; @@ -651,29 +690,30 @@ static int saa7114_command(struct i2c_client *client, unsigned cmd, void *arg) saa7114_write(client, 0x0e, decoder->reg[REG_ADDR(0x0e)]); } - break; } + break; case DECODER_SET_OUTPUT: { int *iarg = arg; - v4l_dbg(1, debug, client, "set output\n"); + dprintk(1, KERN_DEBUG "%s: decoder set output\n", + I2C_NAME(client)); /* not much choice of outputs */ if (*iarg != 0) { return -EINVAL; } - break; } + break; case DECODER_ENABLE_OUTPUT: { int *iarg = arg; int enable = (*iarg != 0); - v4l_dbg(1, debug, client, "%s output\n", - enable ? "enable" : "disable"); + dprintk(1, KERN_DEBUG "%s: decoder %s output\n", + I2C_NAME(client), enable ? "enable" : "disable"); decoder->playback = !enable; @@ -714,16 +754,18 @@ static int saa7114_command(struct i2c_client *client, unsigned cmd, void *arg) saa7114_write(client, 0x80, 0x36); } - break; } + break; case DECODER_SET_PICTURE: { struct video_picture *pic = arg; - v4l_dbg(1, debug, client, - "decoder set picture bright=%d contrast=%d saturation=%d hue=%d\n", - pic->brightness, pic->contrast, pic->colour, pic->hue); + dprintk(1, + KERN_DEBUG + "%s: decoder set picture bright=%d contrast=%d saturation=%d hue=%d\n", + I2C_NAME(client), pic->brightness, pic->contrast, + pic->colour, pic->hue); if (decoder->bright != pic->brightness) { /* We want 0 to 255 we get 0-65535 */ @@ -747,8 +789,8 @@ static int saa7114_command(struct i2c_client *client, unsigned cmd, void *arg) saa7114_write(client, 0x0d, (decoder->hue - 32768) >> 8); } - break; } + break; default: return -EINVAL; @@ -759,30 +801,58 @@ static int saa7114_command(struct i2c_client *client, unsigned cmd, void *arg) /* ----------------------------------------------------------------------- */ -static unsigned short normal_i2c[] = { 0x42 >> 1, 0x40 >> 1, I2C_CLIENT_END }; +/* + * Generic i2c probe + * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1' + */ +static unsigned short normal_i2c[] = + { I2C_SAA7114 >> 1, I2C_SAA7114A >> 1, I2C_CLIENT_END }; + +static unsigned short ignore = I2C_CLIENT_END; + +static struct i2c_client_address_data addr_data = { + .normal_i2c = normal_i2c, + .probe = &ignore, + .ignore = &ignore, +}; -I2C_CLIENT_INSMOD; +static struct i2c_driver i2c_driver_saa7114; -static int saa7114_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int +saa7114_detect_client (struct i2c_adapter *adapter, + int address, + int kind) { int i, err[30]; short int hoff = SAA_7114_NTSC_HOFFSET; short int voff = SAA_7114_NTSC_VOFFSET; short int w = SAA_7114_NTSC_WIDTH; short int h = SAA_7114_NTSC_HEIGHT; + struct i2c_client *client; struct saa7114 *decoder; + dprintk(1, + KERN_INFO + "saa7114.c: detecting saa7114 client on address 0x%x\n", + address << 1); + /* Check if the adapter supports the needed features */ - if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) - return -ENODEV; + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) + return 0; - v4l_info(client, "chip found @ 0x%x (%s)\n", - client->addr << 1, client->adapter->name); + client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); + if (!client) + return -ENOMEM; + client->addr = address; + client->adapter = adapter; + client->driver = &i2c_driver_saa7114; + strlcpy(I2C_NAME(client), "saa7114", sizeof(I2C_NAME(client))); decoder = kzalloc(sizeof(struct saa7114), GFP_KERNEL); - if (decoder == NULL) + if (decoder == NULL) { + kfree(client); return -ENOMEM; + } decoder->norm = VIDEO_MODE_NTSC; decoder->input = -1; decoder->enable = 1; @@ -867,7 +937,8 @@ static int saa7114_probe(struct i2c_client *client, decoder->reg[REG_ADDR(0x0e)] |= 1; // combfilter on - v4l_dbg(1, debug, client, "starting init\n"); + dprintk(1, KERN_DEBUG "%s_attach: starting decoder init\n", + I2C_NAME(client)); err[0] = saa7114_write_block(client, decoder->reg + (0x20 << 1), @@ -891,23 +962,28 @@ static int saa7114_probe(struct i2c_client *client, for (i = 0; i <= 5; i++) { if (err[i] < 0) { - v4l_dbg(1, debug, client, - "init error %d at stage %d, leaving attach.\n", - i, err[i]); + dprintk(1, + KERN_ERR + "%s_attach: init error %d at stage %d, leaving attach.\n", + I2C_NAME(client), i, err[i]); kfree(decoder); - return -EIO; + kfree(client); + return 0; } } for (i = 6; i < 8; i++) { - v4l_dbg(1, debug, client, - "reg[0x%02x] = 0x%02x (0x%02x)\n", - i, saa7114_read(client, i), + dprintk(1, + KERN_DEBUG + "%s_attach: reg[0x%02x] = 0x%02x (0x%02x)\n", + I2C_NAME(client), i, saa7114_read(client, i), decoder->reg[REG_ADDR(i)]); } - v4l_dbg(1, debug, client, - "performing decoder reset sequence\n"); + dprintk(1, + KERN_DEBUG + "%s_attach: performing decoder reset sequence\n", + I2C_NAME(client)); err[6] = saa7114_write(client, 0x80, 0x06); // i-port and scaler backend clock selection, task A&B off err[7] = saa7114_write(client, 0x88, 0xd8); // sw reset scaler @@ -915,15 +991,19 @@ static int saa7114_probe(struct i2c_client *client, for (i = 6; i <= 8; i++) { if (err[i] < 0) { - v4l_dbg(1, debug, client, - "init error %d at stage %d, leaving attach.\n", - i, err[i]); + dprintk(1, + KERN_ERR + "%s_attach: init error %d at stage %d, leaving attach.\n", + I2C_NAME(client), i, err[i]); kfree(decoder); - return -EIO; + kfree(client); + return 0; } } - v4l_dbg(1, debug, client, "performing the rest of init\n"); + dprintk(1, KERN_INFO "%s_attach: performing the rest of init\n", + I2C_NAME(client)); + err[9] = saa7114_write(client, 0x01, decoder->reg[REG_ADDR(0x01)]); err[10] = saa7114_write_block(client, decoder->reg + (0x03 << 1), (0x1e + 1 - 0x03) << 1); // big seq @@ -959,32 +1039,37 @@ static int saa7114_probe(struct i2c_client *client, for (i = 9; i <= 18; i++) { if (err[i] < 0) { - v4l_dbg(1, debug, client, - "init error %d at stage %d, leaving attach.\n", - i, err[i]); + dprintk(1, + KERN_ERR + "%s_attach: init error %d at stage %d, leaving attach.\n", + I2C_NAME(client), i, err[i]); kfree(decoder); - return -EIO; + kfree(client); + return 0; } } for (i = 6; i < 8; i++) { - v4l_dbg(1, debug, client, - "reg[0x%02x] = 0x%02x (0x%02x)\n", - i, saa7114_read(client, i), + dprintk(1, + KERN_DEBUG + "%s_attach: reg[0x%02x] = 0x%02x (0x%02x)\n", + I2C_NAME(client), i, saa7114_read(client, i), decoder->reg[REG_ADDR(i)]); } for (i = 0x11; i <= 0x13; i++) { - v4l_dbg(1, debug, client, - "reg[0x%02x] = 0x%02x (0x%02x)\n", - i, saa7114_read(client, i), + dprintk(1, + KERN_DEBUG + "%s_attach: reg[0x%02x] = 0x%02x (0x%02x)\n", + I2C_NAME(client), i, saa7114_read(client, i), decoder->reg[REG_ADDR(i)]); } - v4l_dbg(1, debug, client, "setting video input\n"); + dprintk(1, KERN_DEBUG "%s_attach: setting video input\n", + I2C_NAME(client)); err[19] = saa7114_write(client, 0x02, decoder->reg[REG_ADDR(0x02)]); @@ -995,15 +1080,20 @@ static int saa7114_probe(struct i2c_client *client, for (i = 19; i <= 21; i++) { if (err[i] < 0) { - v4l_dbg(1, debug, client, - "init error %d at stage %d, leaving attach.\n", - i, err[i]); + dprintk(1, + KERN_ERR + "%s_attach: init error %d at stage %d, leaving attach.\n", + I2C_NAME(client), i, err[i]); kfree(decoder); - return -EIO; + kfree(client); + return 0; } } - v4l_dbg(1, debug, client, "performing decoder reset sequence\n"); + dprintk(1, + KERN_DEBUG + "%s_attach: performing decoder reset sequence\n", + I2C_NAME(client)); err[22] = saa7114_write(client, 0x88, 0xd8); // sw reset scaler err[23] = saa7114_write(client, 0x88, 0xf8); // sw reset scaler release @@ -1012,11 +1102,13 @@ static int saa7114_probe(struct i2c_client *client, for (i = 22; i <= 24; i++) { if (err[i] < 0) { - v4l_dbg(1, debug, client, - "init error %d at stage %d, leaving attach.\n", - i, err[i]); + dprintk(1, + KERN_ERR + "%s_attach: init error %d at stage %d, leaving attach.\n", + I2C_NAME(client), i, err[i]); kfree(decoder); - return -EIO; + kfree(client); + return 0; } } @@ -1024,45 +1116,101 @@ static int saa7114_probe(struct i2c_client *client, err[26] = saa7114_write(client, 0x07, init[REG_ADDR(0x07)]); err[27] = saa7114_write(client, 0x10, init[REG_ADDR(0x10)]); - v4l_dbg(1, debug, client, "chip version %x, decoder status 0x%02x\n", - saa7114_read(client, 0x00) >> 4, + dprintk(1, + KERN_INFO + "%s_attach: chip version %x, decoder status 0x%02x\n", + I2C_NAME(client), saa7114_read(client, 0x00) >> 4, saa7114_read(client, 0x1f)); - v4l_dbg(1, debug, client, - "power save control: 0x%02x, scaler status: 0x%02x\n", - saa7114_read(client, 0x88), + dprintk(1, + KERN_DEBUG + "%s_attach: power save control: 0x%02x, scaler status: 0x%02x\n", + I2C_NAME(client), saa7114_read(client, 0x88), saa7114_read(client, 0x8f)); for (i = 0x94; i < 0x96; i++) { - v4l_dbg(1, debug, client, - "reg[0x%02x] = 0x%02x (0x%02x)\n", - i, saa7114_read(client, i), + dprintk(1, + KERN_DEBUG + "%s_attach: reg[0x%02x] = 0x%02x (0x%02x)\n", + I2C_NAME(client), i, saa7114_read(client, i), decoder->reg[REG_ADDR(i)]); } + i = i2c_attach_client(client); + if (i) { + kfree(client); + kfree(decoder); + return i; + } + //i = saa7114_write_block(client, init, sizeof(init)); + i = 0; + if (i < 0) { + dprintk(1, KERN_ERR "%s_attach error: init status %d\n", + I2C_NAME(client), i); + } else { + dprintk(1, + KERN_INFO + "%s_attach: chip version %x at address 0x%x\n", + I2C_NAME(client), saa7114_read(client, 0x00) >> 4, + client->addr << 1); + } + return 0; } -static int saa7114_remove(struct i2c_client *client) +static int +saa7114_attach_adapter (struct i2c_adapter *adapter) +{ + dprintk(1, + KERN_INFO + "saa7114.c: starting probe for adapter %s (0x%x)\n", + I2C_NAME(adapter), adapter->id); + return i2c_probe(adapter, &addr_data, &saa7114_detect_client); +} + +static int +saa7114_detach_client (struct i2c_client *client) { - kfree(i2c_get_clientdata(client)); + struct saa7114 *decoder = i2c_get_clientdata(client); + int err; + + err = i2c_detach_client(client); + if (err) { + return err; + } + + kfree(decoder); + kfree(client); + return 0; } /* ----------------------------------------------------------------------- */ -static const struct i2c_device_id saa7114_id[] = { - { "saa7114_old", 0 }, /* "saa7114" maps to the saa7115 driver */ - { } -}; -MODULE_DEVICE_TABLE(i2c, saa7114_id); +static struct i2c_driver i2c_driver_saa7114 = { + .driver = { + .name = "saa7114", + }, + + .id = I2C_DRIVERID_SAA7114, -static struct v4l2_i2c_driver_data v4l2_i2c_data = { - .name = "saa7114", - .driverid = I2C_DRIVERID_SAA7114, + .attach_adapter = saa7114_attach_adapter, + .detach_client = saa7114_detach_client, .command = saa7114_command, - .probe = saa7114_probe, - .remove = saa7114_remove, - .id_table = saa7114_id, }; + +static int __init +saa7114_init (void) +{ + return i2c_add_driver(&i2c_driver_saa7114); +} + +static void __exit +saa7114_exit (void) +{ + i2c_del_driver(&i2c_driver_saa7114); +} + +module_init(saa7114_init); +module_exit(saa7114_exit); diff --git a/trunk/drivers/media/video/saa7127.c b/trunk/drivers/media/video/saa7127.c index cc02fb18efa7..d0e83fe0ff51 100644 --- a/trunk/drivers/media/video/saa7127.c +++ b/trunk/drivers/media/video/saa7127.c @@ -29,7 +29,7 @@ * Note: the saa7126 is identical to the saa7127, and the saa7128 is * identical to the saa7129, except that the saa7126 and saa7128 have * macrovision anti-taping support. This driver will almost certainly - * work fine for those chips, except of course for the missing anti-taping + * work find for those chips, except of course for the missing anti-taping * support. * * This program is free software; you can redistribute it and/or modify diff --git a/trunk/drivers/media/video/saa7134/saa7134-dvb.c b/trunk/drivers/media/video/saa7134/saa7134-dvb.c index 8c46115d4c79..87c10983266f 100644 --- a/trunk/drivers/media/video/saa7134/saa7134-dvb.c +++ b/trunk/drivers/media/video/saa7134/saa7134-dvb.c @@ -535,16 +535,11 @@ static int configure_tda827x_fe(struct saa7134_dev *dev, struct tda1004x_config *cdec_conf, struct tda827x_config *tuner_conf) { - struct videobuf_dvb_frontend *fe0; - - /* Get the first frontend */ - fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1); - - fe0->dvb.frontend = dvb_attach(tda10046_attach, cdec_conf, &dev->i2c_adap); - if (fe0->dvb.frontend) { + dev->dvb.frontend = dvb_attach(tda10046_attach, cdec_conf, &dev->i2c_adap); + if (dev->dvb.frontend) { if (cdec_conf->i2c_gate) - fe0->dvb.frontend->ops.i2c_gate_ctrl = tda8290_i2c_gate_ctrl; - if (dvb_attach(tda827x_attach, fe0->dvb.frontend, + dev->dvb.frontend->ops.i2c_gate_ctrl = tda8290_i2c_gate_ctrl; + if (dvb_attach(tda827x_attach, dev->dvb.frontend, cdec_conf->tuner_address, &dev->i2c_adap, tuner_conf)) return 0; @@ -949,30 +944,12 @@ static int dvb_init(struct saa7134_dev *dev) { int ret; int attach_xc3028 = 0; - struct videobuf_dvb_frontend *fe0; - - /* FIXME: add support for multi-frontend */ - mutex_init(&dev->frontends.lock); - INIT_LIST_HEAD(&dev->frontends.felist); - dev->frontends.active_fe_id = 0; - - printk(KERN_INFO "%s() allocating 1 frontend\n", __func__); - - if (videobuf_dvb_alloc_frontend(&dev->frontends, 1) == NULL) { - printk(KERN_ERR "%s() failed to alloc\n", __func__); - return -ENOMEM; - } - - /* Get the first frontend */ - fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1); - if (!fe0) - return -EINVAL; /* init struct videobuf_dvb */ dev->ts.nr_bufs = 32; dev->ts.nr_packets = 32*4; - fe0->dvb.name = dev->name; - videobuf_queue_sg_init(&fe0->dvb.dvbq, &saa7134_ts_qops, + dev->dvb.name = dev->name; + videobuf_queue_sg_init(&dev->dvb.dvbq, &saa7134_ts_qops, &dev->pci->dev, &dev->slock, V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_ALTERNATE, @@ -982,47 +959,47 @@ static int dvb_init(struct saa7134_dev *dev) switch (dev->board) { case SAA7134_BOARD_PINNACLE_300I_DVBT_PAL: dprintk("pinnacle 300i dvb setup\n"); - fe0->dvb.frontend = dvb_attach(mt352_attach, &pinnacle_300i, + dev->dvb.frontend = dvb_attach(mt352_attach, &pinnacle_300i, &dev->i2c_adap); - if (fe0->dvb.frontend) { - fe0->dvb.frontend->ops.tuner_ops.set_params = mt352_pinnacle_tuner_set_params; + if (dev->dvb.frontend) { + dev->dvb.frontend->ops.tuner_ops.set_params = mt352_pinnacle_tuner_set_params; } break; case SAA7134_BOARD_AVERMEDIA_777: case SAA7134_BOARD_AVERMEDIA_A16AR: dprintk("avertv 777 dvb setup\n"); - fe0->dvb.frontend = dvb_attach(mt352_attach, &avermedia_777, + dev->dvb.frontend = dvb_attach(mt352_attach, &avermedia_777, &dev->i2c_adap); - if (fe0->dvb.frontend) { - dvb_attach(simple_tuner_attach, fe0->dvb.frontend, + if (dev->dvb.frontend) { + dvb_attach(simple_tuner_attach, dev->dvb.frontend, &dev->i2c_adap, 0x61, TUNER_PHILIPS_TD1316); } break; case SAA7134_BOARD_AVERMEDIA_A16D: dprintk("AverMedia A16D dvb setup\n"); - fe0->dvb.frontend = dvb_attach(mt352_attach, + dev->dvb.frontend = dvb_attach(mt352_attach, &avermedia_xc3028_mt352_dev, &dev->i2c_adap); attach_xc3028 = 1; break; case SAA7134_BOARD_MD7134: - fe0->dvb.frontend = dvb_attach(tda10046_attach, + dev->dvb.frontend = dvb_attach(tda10046_attach, &medion_cardbus, &dev->i2c_adap); - if (fe0->dvb.frontend) { - dvb_attach(simple_tuner_attach, fe0->dvb.frontend, + if (dev->dvb.frontend) { + dvb_attach(simple_tuner_attach, dev->dvb.frontend, &dev->i2c_adap, medion_cardbus.tuner_address, TUNER_PHILIPS_FMD1216ME_MK3); } break; case SAA7134_BOARD_PHILIPS_TOUGH: - fe0->dvb.frontend = dvb_attach(tda10046_attach, + dev->dvb.frontend = dvb_attach(tda10046_attach, &philips_tu1216_60_config, &dev->i2c_adap); - if (fe0->dvb.frontend) { - fe0->dvb.frontend->ops.tuner_ops.init = philips_tu1216_init; - fe0->dvb.frontend->ops.tuner_ops.set_params = philips_tda6651_pll_set; + if (dev->dvb.frontend) { + dev->dvb.frontend->ops.tuner_ops.init = philips_tu1216_init; + dev->dvb.frontend->ops.tuner_ops.set_params = philips_tda6651_pll_set; } break; case SAA7134_BOARD_FLYDVBTDUO: @@ -1033,24 +1010,24 @@ static int dvb_init(struct saa7134_dev *dev) break; case SAA7134_BOARD_PHILIPS_EUROPA: case SAA7134_BOARD_VIDEOMATE_DVBT_300: - fe0->dvb.frontend = dvb_attach(tda10046_attach, + dev->dvb.frontend = dvb_attach(tda10046_attach, &philips_europa_config, &dev->i2c_adap); - if (fe0->dvb.frontend) { - dev->original_demod_sleep = fe0->dvb.frontend->ops.sleep; - fe0->dvb.frontend->ops.sleep = philips_europa_demod_sleep; - fe0->dvb.frontend->ops.tuner_ops.init = philips_europa_tuner_init; - fe0->dvb.frontend->ops.tuner_ops.sleep = philips_europa_tuner_sleep; - fe0->dvb.frontend->ops.tuner_ops.set_params = philips_td1316_tuner_set_params; + if (dev->dvb.frontend) { + dev->original_demod_sleep = dev->dvb.frontend->ops.sleep; + dev->dvb.frontend->ops.sleep = philips_europa_demod_sleep; + dev->dvb.frontend->ops.tuner_ops.init = philips_europa_tuner_init; + dev->dvb.frontend->ops.tuner_ops.sleep = philips_europa_tuner_sleep; + dev->dvb.frontend->ops.tuner_ops.set_params = philips_td1316_tuner_set_params; } break; case SAA7134_BOARD_VIDEOMATE_DVBT_200: - fe0->dvb.frontend = dvb_attach(tda10046_attach, + dev->dvb.frontend = dvb_attach(tda10046_attach, &philips_tu1216_61_config, &dev->i2c_adap); - if (fe0->dvb.frontend) { - fe0->dvb.frontend->ops.tuner_ops.init = philips_tu1216_init; - fe0->dvb.frontend->ops.tuner_ops.set_params = philips_tda6651_pll_set; + if (dev->dvb.frontend) { + dev->dvb.frontend->ops.tuner_ops.init = philips_tu1216_init; + dev->dvb.frontend->ops.tuner_ops.set_params = philips_tda6651_pll_set; } break; case SAA7134_BOARD_KWORLD_DVBT_210: @@ -1089,14 +1066,14 @@ static int dvb_init(struct saa7134_dev *dev) &tda827x_cfg_0) < 0) goto dettach_frontend; } else { /* satellite */ - fe0->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs, &dev->i2c_adap); - if (fe0->dvb.frontend) { - if (dvb_attach(tda826x_attach, fe0->dvb.frontend, 0x63, + dev->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs, &dev->i2c_adap); + if (dev->dvb.frontend) { + if (dvb_attach(tda826x_attach, dev->dvb.frontend, 0x63, &dev->i2c_adap, 0) == NULL) { wprintk("%s: Lifeview Trio, No tda826x found!\n", __func__); goto dettach_frontend; } - if (dvb_attach(isl6421_attach, fe0->dvb.frontend, &dev->i2c_adap, + if (dvb_attach(isl6421_attach, dev->dvb.frontend, &dev->i2c_adap, 0x08, 0, 0) == NULL) { wprintk("%s: Lifeview Trio, No ISL6421 found!\n", __func__); goto dettach_frontend; @@ -1106,11 +1083,11 @@ static int dvb_init(struct saa7134_dev *dev) break; case SAA7134_BOARD_ADS_DUO_CARDBUS_PTV331: case SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS: - fe0->dvb.frontend = dvb_attach(tda10046_attach, + dev->dvb.frontend = dvb_attach(tda10046_attach, &ads_tech_duo_config, &dev->i2c_adap); - if (fe0->dvb.frontend) { - if (dvb_attach(tda827x_attach,fe0->dvb.frontend, + if (dev->dvb.frontend) { + if (dvb_attach(tda827x_attach,dev->dvb.frontend, ads_tech_duo_config.tuner_address, &dev->i2c_adap, &ads_duo_cfg) == NULL) { wprintk("no tda827x tuner found at addr: %02x\n", @@ -1131,15 +1108,15 @@ static int dvb_init(struct saa7134_dev *dev) &tda827x_cfg_0) < 0) goto dettach_frontend; } else { /* satellite */ - fe0->dvb.frontend = dvb_attach(tda10086_attach, + dev->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs, &dev->i2c_adap); - if (fe0->dvb.frontend) { - struct dvb_frontend *fe = fe0->dvb.frontend; + if (dev->dvb.frontend) { + struct dvb_frontend *fe = dev->dvb.frontend; u8 dev_id = dev->eedata[2]; u8 data = 0xc4; struct i2c_msg msg = {.addr = 0x08, .flags = 0, .len = 1}; - if (dvb_attach(tda826x_attach, fe0->dvb.frontend, + if (dvb_attach(tda826x_attach, dev->dvb.frontend, 0x60, &dev->i2c_adap, 0) == NULL) { wprintk("%s: Medion Quadro, no tda826x " "found !\n", __func__); @@ -1173,31 +1150,31 @@ static int dvb_init(struct saa7134_dev *dev) } break; case SAA7134_BOARD_AVERMEDIA_AVERTVHD_A180: - fe0->dvb.frontend = dvb_attach(nxt200x_attach, &avertvhda180, + dev->dvb.frontend = dvb_attach(nxt200x_attach, &avertvhda180, &dev->i2c_adap); - if (fe0->dvb.frontend) - dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 0x61, + if (dev->dvb.frontend) + dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, NULL, DVB_PLL_TDHU2); break; case SAA7134_BOARD_ADS_INSTANT_HDTV_PCI: case SAA7134_BOARD_KWORLD_ATSC110: - fe0->dvb.frontend = dvb_attach(nxt200x_attach, &kworldatsc110, + dev->dvb.frontend = dvb_attach(nxt200x_attach, &kworldatsc110, &dev->i2c_adap); - if (fe0->dvb.frontend) - dvb_attach(simple_tuner_attach, fe0->dvb.frontend, + if (dev->dvb.frontend) + dvb_attach(simple_tuner_attach, dev->dvb.frontend, &dev->i2c_adap, 0x61, TUNER_PHILIPS_TUV1236D); break; case SAA7134_BOARD_FLYDVBS_LR300: - fe0->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs, + dev->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs, &dev->i2c_adap); - if (fe0->dvb.frontend) { - if (dvb_attach(tda826x_attach, fe0->dvb.frontend, 0x60, + if (dev->dvb.frontend) { + if (dvb_attach(tda826x_attach, dev->dvb.frontend, 0x60, &dev->i2c_adap, 0) == NULL) { wprintk("%s: No tda826x found!\n", __func__); goto dettach_frontend; } - if (dvb_attach(isl6421_attach, fe0->dvb.frontend, + if (dvb_attach(isl6421_attach, dev->dvb.frontend, &dev->i2c_adap, 0x08, 0, 0) == NULL) { wprintk("%s: No ISL6421 found!\n", __func__); goto dettach_frontend; @@ -1205,25 +1182,25 @@ static int dvb_init(struct saa7134_dev *dev) } break; case SAA7134_BOARD_ASUS_EUROPA2_HYBRID: - fe0->dvb.frontend = dvb_attach(tda10046_attach, + dev->dvb.frontend = dvb_attach(tda10046_attach, &medion_cardbus, &dev->i2c_adap); - if (fe0->dvb.frontend) { - dev->original_demod_sleep = fe0->dvb.frontend->ops.sleep; - fe0->dvb.frontend->ops.sleep = philips_europa_demod_sleep; + if (dev->dvb.frontend) { + dev->original_demod_sleep = dev->dvb.frontend->ops.sleep; + dev->dvb.frontend->ops.sleep = philips_europa_demod_sleep; - dvb_attach(simple_tuner_attach, fe0->dvb.frontend, + dvb_attach(simple_tuner_attach, dev->dvb.frontend, &dev->i2c_adap, medion_cardbus.tuner_address, TUNER_PHILIPS_FMD1216ME_MK3); } break; case SAA7134_BOARD_VIDEOMATE_DVBT_200A: - fe0->dvb.frontend = dvb_attach(tda10046_attach, + dev->dvb.frontend = dvb_attach(tda10046_attach, &philips_europa_config, &dev->i2c_adap); - if (fe0->dvb.frontend) { - fe0->dvb.frontend->ops.tuner_ops.init = philips_td1316_tuner_init; - fe0->dvb.frontend->ops.tuner_ops.set_params = philips_td1316_tuner_set_params; + if (dev->dvb.frontend) { + dev->dvb.frontend->ops.tuner_ops.init = philips_td1316_tuner_init; + dev->dvb.frontend->ops.tuner_ops.set_params = philips_td1316_tuner_set_params; } break; case SAA7134_BOARD_CINERGY_HT_PCMCIA: @@ -1262,15 +1239,15 @@ static int dvb_init(struct saa7134_dev *dev) goto dettach_frontend; break; case SAA7134_BOARD_PHILIPS_SNAKE: - fe0->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs, + dev->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs, &dev->i2c_adap); - if (fe0->dvb.frontend) { - if (dvb_attach(tda826x_attach, fe0->dvb.frontend, 0x60, + if (dev->dvb.frontend) { + if (dvb_attach(tda826x_attach, dev->dvb.frontend, 0x60, &dev->i2c_adap, 0) == NULL) { wprintk("%s: No tda826x found!\n", __func__); goto dettach_frontend; } - if (dvb_attach(lnbp21_attach, fe0->dvb.frontend, + if (dvb_attach(lnbp21_attach, dev->dvb.frontend, &dev->i2c_adap, 0, 0) == NULL) { wprintk("%s: No lnbp21 found!\n", __func__); goto dettach_frontend; @@ -1292,24 +1269,24 @@ static int dvb_init(struct saa7134_dev *dev) saa7134_set_gpio(dev, 25, 0); msleep(10); saa7134_set_gpio(dev, 25, 1); - fe0->dvb.frontend = dvb_attach(mt352_attach, + dev->dvb.frontend = dvb_attach(mt352_attach, &avermedia_xc3028_mt352_dev, &dev->i2c_adap); attach_xc3028 = 1; break; case SAA7134_BOARD_MD7134_BRIDGE_2: - fe0->dvb.frontend = dvb_attach(tda10086_attach, + dev->dvb.frontend = dvb_attach(tda10086_attach, &sd1878_4m, &dev->i2c_adap); - if (fe0->dvb.frontend) { + if (dev->dvb.frontend) { struct dvb_frontend *fe; - if (dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 0x60, + if (dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60, &dev->i2c_adap, DVB_PLL_PHILIPS_SD1878_TDA8261) == NULL) { wprintk("%s: MD7134 DVB-S, no SD1878 " "found !\n", __func__); goto dettach_frontend; } /* we need to open the i2c gate (we know it exists) */ - fe = fe0->dvb.frontend; + fe = dev->dvb.frontend; fe->ops.i2c_gate_ctrl(fe, 1); if (dvb_attach(isl6405_attach, fe, &dev->i2c_adap, 0x08, 0, 0) == NULL) { @@ -1328,7 +1305,7 @@ static int dvb_init(struct saa7134_dev *dev) saa7134_set_gpio(dev, 25, 0); msleep(10); saa7134_set_gpio(dev, 25, 1); - fe0->dvb.frontend = dvb_attach(mt352_attach, + dev->dvb.frontend = dvb_attach(mt352_attach, &avermedia_xc3028_mt352_dev, &dev->i2c_adap); attach_xc3028 = 1; @@ -1339,17 +1316,17 @@ static int dvb_init(struct saa7134_dev *dev) &tda827x_cfg_2) < 0) goto dettach_frontend; } else { /* satellite */ - fe0->dvb.frontend = dvb_attach(tda10086_attach, + dev->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs, &dev->i2c_adap); - if (fe0->dvb.frontend) { + if (dev->dvb.frontend) { if (dvb_attach(tda826x_attach, - fe0->dvb.frontend, 0x60, + dev->dvb.frontend, 0x60, &dev->i2c_adap, 0) == NULL) { wprintk("%s: Asus Tiger 3in1, no " "tda826x found!\n", __func__); goto dettach_frontend; } - if (dvb_attach(lnbp21_attach, fe0->dvb.frontend, + if (dvb_attach(lnbp21_attach, dev->dvb.frontend, &dev->i2c_adap, 0, 0) == NULL) { wprintk("%s: Asus Tiger 3in1, no lnbp21" " found!\n", __func__); @@ -1375,10 +1352,10 @@ static int dvb_init(struct saa7134_dev *dev) .i2c_addr = 0x61, }; - if (!fe0->dvb.frontend) + if (!dev->dvb.frontend) return -1; - fe = dvb_attach(xc2028_attach, fe0->dvb.frontend, &cfg); + fe = dvb_attach(xc2028_attach, dev->dvb.frontend, &cfg); if (!fe) { printk(KERN_ERR "%s/2: xc3028 attach failed\n", dev->name); @@ -1386,47 +1363,40 @@ static int dvb_init(struct saa7134_dev *dev) } } - if (NULL == fe0->dvb.frontend) { + if (NULL == dev->dvb.frontend) { printk(KERN_ERR "%s/dvb: frontend initialization failed\n", dev->name); return -1; } /* define general-purpose callback pointer */ - fe0->dvb.frontend->callback = saa7134_tuner_callback; + dev->dvb.frontend->callback = saa7134_tuner_callback; /* register everything else */ - ret = videobuf_dvb_register_bus(&dev->frontends, THIS_MODULE, dev, - &dev->pci->dev, adapter_nr, 0); + ret = videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev, &dev->pci->dev, + adapter_nr); /* this sequence is necessary to make the tda1004x load its firmware * and to enter analog mode of hybrid boards */ if (!ret) { - if (fe0->dvb.frontend->ops.init) - fe0->dvb.frontend->ops.init(fe0->dvb.frontend); - if (fe0->dvb.frontend->ops.sleep) - fe0->dvb.frontend->ops.sleep(fe0->dvb.frontend); - if (fe0->dvb.frontend->ops.tuner_ops.sleep) - fe0->dvb.frontend->ops.tuner_ops.sleep(fe0->dvb.frontend); + if (dev->dvb.frontend->ops.init) + dev->dvb.frontend->ops.init(dev->dvb.frontend); + if (dev->dvb.frontend->ops.sleep) + dev->dvb.frontend->ops.sleep(dev->dvb.frontend); + if (dev->dvb.frontend->ops.tuner_ops.sleep) + dev->dvb.frontend->ops.tuner_ops.sleep(dev->dvb.frontend); } return ret; dettach_frontend: - if (fe0->dvb.frontend) - dvb_frontend_detach(fe0->dvb.frontend); - fe0->dvb.frontend = NULL; + if (dev->dvb.frontend) + dvb_frontend_detach(dev->dvb.frontend); + dev->dvb.frontend = NULL; return -1; } static int dvb_fini(struct saa7134_dev *dev) { - struct videobuf_dvb_frontend *fe0; - - /* Get the first frontend */ - fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1); - if (!fe0) - return -EINVAL; - /* FIXME: I suspect that this code is bogus, since the entry for Pinnacle 300I DVB-T PAL already defines the proper init to allow the detection of mt2032 (TDA9887_PORT2_INACTIVE) @@ -1446,7 +1416,7 @@ static int dvb_fini(struct saa7134_dev *dev) u8 data = 0x80; struct i2c_msg msg = {.addr = 0x08, .buf = &data, .flags = 0, .len = 1}; struct dvb_frontend *fe; - fe = fe0->dvb.frontend; + fe = dev->dvb.frontend; if (fe->ops.i2c_gate_ctrl) { fe->ops.i2c_gate_ctrl(fe, 1); i2c_transfer(&dev->i2c_adap, &msg, 1); @@ -1454,8 +1424,8 @@ static int dvb_fini(struct saa7134_dev *dev) } } } - if (fe0->dvb.frontend) - videobuf_dvb_unregister_bus(&dev->frontends); + if (dev->dvb.frontend) + videobuf_dvb_unregister(&dev->dvb); return 0; } diff --git a/trunk/drivers/media/video/saa7134/saa7134.h b/trunk/drivers/media/video/saa7134/saa7134.h index 24096d6e1ef8..491ab1f8fdd3 100644 --- a/trunk/drivers/media/video/saa7134/saa7134.h +++ b/trunk/drivers/media/video/saa7134/saa7134.h @@ -581,7 +581,7 @@ struct saa7134_dev { #if defined(CONFIG_VIDEO_SAA7134_DVB) || defined(CONFIG_VIDEO_SAA7134_DVB_MODULE) /* SAA7134_MPEG_DVB only */ - struct videobuf_dvb_frontends frontends; + struct videobuf_dvb dvb; int (*original_demod_sleep)(struct dvb_frontend *fe); int (*original_set_voltage)(struct dvb_frontend *fe, fe_sec_voltage_t voltage); int (*original_set_high_voltage)(struct dvb_frontend *fe, long arg); diff --git a/trunk/drivers/media/video/saa7185.c b/trunk/drivers/media/video/saa7185.c index 6debb65152ee..02fda4eecea3 100644 --- a/trunk/drivers/media/video/saa7185.c +++ b/trunk/drivers/media/video/saa7185.c @@ -25,25 +25,43 @@ */ #include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include -#include -#include #include -#include +#include +#include +#include +#include + #include #include -#include -#include MODULE_DESCRIPTION("Philips SAA7185 video encoder driver"); MODULE_AUTHOR("Dave Perks"); MODULE_LICENSE("GPL"); +#define I2C_NAME(s) (s)->name + + static int debug; module_param(debug, int, 0); MODULE_PARM_DESC(debug, "Debug level (0-1)"); +#define dprintk(num, format, args...) \ + do { \ + if (debug >= num) \ + printk(format, ##args); \ + } while (0) + /* ----------------------------------------------------------------------- */ struct saa7185 { @@ -57,24 +75,32 @@ struct saa7185 { int sat; }; +#define I2C_SAA7185 0x88 + /* ----------------------------------------------------------------------- */ -static inline int saa7185_read(struct i2c_client *client) +static inline int +saa7185_read (struct i2c_client *client) { return i2c_smbus_read_byte(client); } -static int saa7185_write(struct i2c_client *client, u8 reg, u8 value) +static int +saa7185_write (struct i2c_client *client, + u8 reg, + u8 value) { struct saa7185 *encoder = i2c_get_clientdata(client); - v4l_dbg(1, debug, client, "%02x set to %02x\n", reg, value); + dprintk(1, KERN_DEBUG "SAA7185: %02x set to %02x\n", reg, value); encoder->reg[reg] = value; return i2c_smbus_write_byte_data(client, reg, value); } -static int saa7185_write_block(struct i2c_client *client, - const u8 *data, unsigned int len) +static int +saa7185_write_block (struct i2c_client *client, + const u8 *data, + unsigned int len) { int ret = -1; u8 reg; @@ -95,17 +121,18 @@ static int saa7185_write_block(struct i2c_client *client, encoder->reg[reg++] = data[1]; len -= 2; data += 2; - } while (len >= 2 && data[0] == reg && block_len < 32); - ret = i2c_master_send(client, block_data, block_len); - if (ret < 0) + } while (len >= 2 && data[0] == reg && + block_len < 32); + if ((ret = i2c_master_send(client, block_data, + block_len)) < 0) break; } } else { /* do some slow I2C emulation kind of thing */ while (len >= 2) { reg = *data++; - ret = saa7185_write(client, reg, *data++); - if (ret < 0) + if ((ret = saa7185_write(client, reg, + *data++)) < 0) break; len -= 2; } @@ -213,11 +240,15 @@ static const unsigned char init_ntsc[] = { 0x66, 0x21, /* FSC3 */ }; -static int saa7185_command(struct i2c_client *client, unsigned cmd, void *arg) +static int +saa7185_command (struct i2c_client *client, + unsigned int cmd, + void *arg) { struct saa7185 *encoder = i2c_get_clientdata(client); switch (cmd) { + case 0: saa7185_write_block(client, init_common, sizeof(init_common)); @@ -233,6 +264,7 @@ static int saa7185_command(struct i2c_client *client, unsigned cmd, void *arg) sizeof(init_pal)); break; } + break; case ENCODER_GET_CAPABILITIES: @@ -244,8 +276,8 @@ static int saa7185_command(struct i2c_client *client, unsigned cmd, void *arg) VIDEO_ENCODER_SECAM | VIDEO_ENCODER_CCIR; cap->inputs = 1; cap->outputs = 1; - break; } + break; case ENCODER_SET_NORM: { @@ -254,6 +286,7 @@ static int saa7185_command(struct i2c_client *client, unsigned cmd, void *arg) //saa7185_write_block(client, init_common, sizeof(init_common)); switch (*iarg) { + case VIDEO_MODE_NTSC: saa7185_write_block(client, init_ntsc, sizeof(init_ntsc)); @@ -267,10 +300,11 @@ static int saa7185_command(struct i2c_client *client, unsigned cmd, void *arg) case VIDEO_MODE_SECAM: default: return -EINVAL; + } encoder->norm = *iarg; - break; } + break; case ENCODER_SET_INPUT: { @@ -280,6 +314,7 @@ static int saa7185_command(struct i2c_client *client, unsigned cmd, void *arg) *iarg = 1: input is from ZR36060 */ switch (*iarg) { + case 0: /* Switch RTCE to 1 */ saa7185_write(client, 0x61, @@ -297,19 +332,21 @@ static int saa7185_command(struct i2c_client *client, unsigned cmd, void *arg) default: return -EINVAL; + } - break; } + break; case ENCODER_SET_OUTPUT: { int *iarg = arg; /* not much choice of outputs */ - if (*iarg != 0) + if (*iarg != 0) { return -EINVAL; - break; + } } + break; case ENCODER_ENABLE_OUTPUT: { @@ -319,8 +356,8 @@ static int saa7185_command(struct i2c_client *client, unsigned cmd, void *arg) saa7185_write(client, 0x61, (encoder->reg[0x61] & 0xbf) | (encoder->enable ? 0x00 : 0x40)); - break; } + break; default: return -EINVAL; @@ -331,65 +368,138 @@ static int saa7185_command(struct i2c_client *client, unsigned cmd, void *arg) /* ----------------------------------------------------------------------- */ -static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END }; +/* + * Generic i2c probe + * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1' + */ +static unsigned short normal_i2c[] = { I2C_SAA7185 >> 1, I2C_CLIENT_END }; -I2C_CLIENT_INSMOD; +static unsigned short ignore = I2C_CLIENT_END; -static int saa7185_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static struct i2c_client_address_data addr_data = { + .normal_i2c = normal_i2c, + .probe = &ignore, + .ignore = &ignore, +}; + +static struct i2c_driver i2c_driver_saa7185; + +static int +saa7185_detect_client (struct i2c_adapter *adapter, + int address, + int kind) { int i; + struct i2c_client *client; struct saa7185 *encoder; + dprintk(1, + KERN_INFO + "saa7185.c: detecting saa7185 client on address 0x%x\n", + address << 1); + /* Check if the adapter supports the needed features */ - if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) - return -ENODEV; + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) + return 0; - v4l_info(client, "chip found @ 0x%x (%s)\n", - client->addr << 1, client->adapter->name); + client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); + if (!client) + return -ENOMEM; + client->addr = address; + client->adapter = adapter; + client->driver = &i2c_driver_saa7185; + strlcpy(I2C_NAME(client), "saa7185", sizeof(I2C_NAME(client))); encoder = kzalloc(sizeof(struct saa7185), GFP_KERNEL); - if (encoder == NULL) + if (encoder == NULL) { + kfree(client); return -ENOMEM; + } encoder->norm = VIDEO_MODE_NTSC; encoder->enable = 1; i2c_set_clientdata(client, encoder); + i = i2c_attach_client(client); + if (i) { + kfree(client); + kfree(encoder); + return i; + } + i = saa7185_write_block(client, init_common, sizeof(init_common)); - if (i >= 0) - i = saa7185_write_block(client, init_ntsc, sizeof(init_ntsc)); - if (i < 0) - v4l_dbg(1, debug, client, "init error %d\n", i); - else - v4l_dbg(1, debug, client, "revision 0x%x\n", - saa7185_read(client) >> 5); + if (i >= 0) { + i = saa7185_write_block(client, init_ntsc, + sizeof(init_ntsc)); + } + if (i < 0) { + dprintk(1, KERN_ERR "%s_attach: init error %d\n", + I2C_NAME(client), i); + } else { + dprintk(1, + KERN_INFO + "%s_attach: chip version %d at address 0x%x\n", + I2C_NAME(client), saa7185_read(client) >> 5, + client->addr << 1); + } + return 0; } -static int saa7185_remove(struct i2c_client *client) +static int +saa7185_attach_adapter (struct i2c_adapter *adapter) +{ + dprintk(1, + KERN_INFO + "saa7185.c: starting probe for adapter %s (0x%x)\n", + I2C_NAME(adapter), adapter->id); + return i2c_probe(adapter, &addr_data, &saa7185_detect_client); +} + +static int +saa7185_detach_client (struct i2c_client *client) { struct saa7185 *encoder = i2c_get_clientdata(client); + int err; + + err = i2c_detach_client(client); + if (err) { + return err; + } saa7185_write(client, 0x61, (encoder->reg[0x61]) | 0x40); /* SW: output off is active */ //saa7185_write(client, 0x3a, (encoder->reg[0x3a]) | 0x80); /* SW: color bar */ kfree(encoder); + kfree(client); + return 0; } /* ----------------------------------------------------------------------- */ -static const struct i2c_device_id saa7185_id[] = { - { "saa7185", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, saa7185_id); +static struct i2c_driver i2c_driver_saa7185 = { + .driver = { + .name = "saa7185", /* name */ + }, + + .id = I2C_DRIVERID_SAA7185B, -static struct v4l2_i2c_driver_data v4l2_i2c_data = { - .name = "saa7185", - .driverid = I2C_DRIVERID_SAA7185B, + .attach_adapter = saa7185_attach_adapter, + .detach_client = saa7185_detach_client, .command = saa7185_command, - .probe = saa7185_probe, - .remove = saa7185_remove, - .id_table = saa7185_id, }; + +static int __init +saa7185_init (void) +{ + return i2c_add_driver(&i2c_driver_saa7185); +} + +static void __exit +saa7185_exit (void) +{ + i2c_del_driver(&i2c_driver_saa7185); +} + +module_init(saa7185_init); +module_exit(saa7185_exit); diff --git a/trunk/drivers/media/video/sh_mobile_ceu_camera.c b/trunk/drivers/media/video/sh_mobile_ceu_camera.c index 2407607f2eff..76838091dc66 100644 --- a/trunk/drivers/media/video/sh_mobile_ceu_camera.c +++ b/trunk/drivers/media/video/sh_mobile_ceu_camera.c @@ -40,39 +40,39 @@ /* register offsets for sh7722 / sh7723 */ -#define CAPSR 0x00 /* Capture start register */ -#define CAPCR 0x04 /* Capture control register */ -#define CAMCR 0x08 /* Capture interface control register */ -#define CMCYR 0x0c /* Capture interface cycle register */ -#define CAMOR 0x10 /* Capture interface offset register */ -#define CAPWR 0x14 /* Capture interface width register */ -#define CAIFR 0x18 /* Capture interface input format register */ -#define CSTCR 0x20 /* Camera strobe control register (<= sh7722) */ -#define CSECR 0x24 /* Camera strobe emission count register (<= sh7722) */ -#define CRCNTR 0x28 /* CEU register control register */ -#define CRCMPR 0x2c /* CEU register forcible control register */ -#define CFLCR 0x30 /* Capture filter control register */ -#define CFSZR 0x34 /* Capture filter size clip register */ -#define CDWDR 0x38 /* Capture destination width register */ -#define CDAYR 0x3c /* Capture data address Y register */ -#define CDACR 0x40 /* Capture data address C register */ -#define CDBYR 0x44 /* Capture data bottom-field address Y register */ -#define CDBCR 0x48 /* Capture data bottom-field address C register */ -#define CBDSR 0x4c /* Capture bundle destination size register */ -#define CFWCR 0x5c /* Firewall operation control register */ -#define CLFCR 0x60 /* Capture low-pass filter control register */ -#define CDOCR 0x64 /* Capture data output control register */ -#define CDDCR 0x68 /* Capture data complexity level register */ -#define CDDAR 0x6c /* Capture data complexity level address register */ -#define CEIER 0x70 /* Capture event interrupt enable register */ -#define CETCR 0x74 /* Capture event flag clear register */ -#define CSTSR 0x7c /* Capture status register */ -#define CSRTR 0x80 /* Capture software reset register */ -#define CDSSR 0x84 /* Capture data size register */ -#define CDAYR2 0x90 /* Capture data address Y register 2 */ -#define CDACR2 0x94 /* Capture data address C register 2 */ -#define CDBYR2 0x98 /* Capture data bottom-field address Y register 2 */ -#define CDBCR2 0x9c /* Capture data bottom-field address C register 2 */ +#define CAPSR 0x00 +#define CAPCR 0x04 +#define CAMCR 0x08 +#define CMCYR 0x0c +#define CAMOR 0x10 +#define CAPWR 0x14 +#define CAIFR 0x18 +#define CSTCR 0x20 /* not on sh7723 */ +#define CSECR 0x24 /* not on sh7723 */ +#define CRCNTR 0x28 +#define CRCMPR 0x2c +#define CFLCR 0x30 +#define CFSZR 0x34 +#define CDWDR 0x38 +#define CDAYR 0x3c +#define CDACR 0x40 +#define CDBYR 0x44 +#define CDBCR 0x48 +#define CBDSR 0x4c +#define CFWCR 0x5c +#define CLFCR 0x60 +#define CDOCR 0x64 +#define CDDCR 0x68 +#define CDDAR 0x6c +#define CEIER 0x70 +#define CETCR 0x74 +#define CSTSR 0x7c +#define CSRTR 0x80 +#define CDSSR 0x84 +#define CDAYR2 0x90 +#define CDACR2 0x94 +#define CDBYR2 0x98 +#define CDBCR2 0x9c static DEFINE_MUTEX(camera_lock); @@ -165,7 +165,6 @@ static void sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev) ceu_write(pcdev, CETCR, 0x0317f313 ^ 0x10); if (pcdev->active) { - pcdev->active->state = VIDEOBUF_ACTIVE; ceu_write(pcdev, CDAYR, videobuf_to_dma_contig(pcdev->active)); ceu_write(pcdev, CAPSR, 0x1); /* start capture */ } @@ -237,7 +236,7 @@ static void sh_mobile_ceu_videobuf_queue(struct videobuf_queue *vq, dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__, vb, vb->baddr, vb->bsize); - vb->state = VIDEOBUF_QUEUED; + vb->state = VIDEOBUF_ACTIVE; spin_lock_irqsave(&pcdev->lock, flags); list_add_tail(&vb->queue, &pcdev->capture); @@ -324,24 +323,12 @@ static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd) { struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); struct sh_mobile_ceu_dev *pcdev = ici->priv; - unsigned long flags; BUG_ON(icd != pcdev->icd); /* disable capture, disable interrupts */ ceu_write(pcdev, CEIER, 0); ceu_write(pcdev, CAPSR, 1 << 16); /* reset */ - - /* make sure active buffer is canceled */ - spin_lock_irqsave(&pcdev->lock, flags); - if (pcdev->active) { - list_del(&pcdev->active->queue); - pcdev->active->state = VIDEOBUF_ERROR; - wake_up_all(&pcdev->active->done); - pcdev->active = NULL; - } - spin_unlock_irqrestore(&pcdev->lock, flags); - icd->ops->release(icd); dev_info(&icd->dev, @@ -404,20 +391,7 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd, ceu_write(pcdev, CFLCR, 0); /* data fetch mode - no scaling */ ceu_write(pcdev, CFSZR, (icd->height << 16) | cfszr_width); ceu_write(pcdev, CLFCR, 0); /* data fetch mode - no lowpass filter */ - - /* A few words about byte order (observed in Big Endian mode) - * - * In data fetch mode bytes are received in chunks of 8 bytes. - * D0, D1, D2, D3, D4, D5, D6, D7 (D0 received first) - * - * The data is however by default written to memory in reverse order: - * D7, D6, D5, D4, D3, D2, D1, D0 (D7 written to lowest byte) - * - * The lowest three bits of CDOCR allows us to do swapping, - * using 7 we swap the data bytes to match the incoming order: - * D0, D1, D2, D3, D4, D5, D6, D7 - */ - ceu_write(pcdev, CDOCR, 0x00000017); + ceu_write(pcdev, CDOCR, 0x00000016); ceu_write(pcdev, CDWDR, cdwdr_width); ceu_write(pcdev, CFWCR, 0); /* keep "datafetch firewall" disabled */ diff --git a/trunk/drivers/media/video/soc_camera_platform.c b/trunk/drivers/media/video/soc_camera_platform.c index bb7a9d480e8f..1adc257ebdb9 100644 --- a/trunk/drivers/media/video/soc_camera_platform.c +++ b/trunk/drivers/media/video/soc_camera_platform.c @@ -18,7 +18,15 @@ #include #include #include -#include + +struct soc_camera_platform_info { + int iface; + char *format_name; + unsigned long format_depth; + struct v4l2_pix_format format; + unsigned long bus_param; + int (*set_capture)(struct soc_camera_platform_info *info, int enable); +}; struct soc_camera_platform_priv { struct soc_camera_platform_info *info; @@ -36,21 +44,11 @@ soc_camera_platform_get_info(struct soc_camera_device *icd) static int soc_camera_platform_init(struct soc_camera_device *icd) { - struct soc_camera_platform_info *p = soc_camera_platform_get_info(icd); - - if (p->power) - p->power(1); - return 0; } static int soc_camera_platform_release(struct soc_camera_device *icd) { - struct soc_camera_platform_info *p = soc_camera_platform_get_info(icd); - - if (p->power) - p->power(0); - return 0; } diff --git a/trunk/drivers/media/video/stk-webcam.c b/trunk/drivers/media/video/stk-webcam.c index edaea4964513..db69bc5556d6 100644 --- a/trunk/drivers/media/video/stk-webcam.c +++ b/trunk/drivers/media/video/stk-webcam.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -559,7 +560,7 @@ static void stk_clean_iso(struct stk_camera *dev) urb = dev->isobufs[i].urb; if (urb) { - if (atomic_read(&dev->urbs_used) && is_present(dev)) + if (atomic_read(&dev->urbs_used)) usb_kill_urb(urb); usb_free_urb(urb); } @@ -688,14 +689,18 @@ static int v4l_stk_release(struct inode *inode, struct file *fp) { struct stk_camera *dev = fp->private_data; - if (dev->owner == fp) { - stk_stop_stream(dev); - stk_free_buffers(dev); - dev->owner = NULL; + if (dev->owner != fp) { + usb_autopm_put_interface(dev->interface); + return 0; } - if(is_present(dev)) - usb_autopm_put_interface(dev->interface); + stk_stop_stream(dev); + + stk_free_buffers(dev); + + dev->owner = NULL; + + usb_autopm_put_interface(dev->interface); return 0; } @@ -709,6 +714,9 @@ static ssize_t v4l_stk_read(struct file *fp, char __user *buf, struct stk_sio_buffer *sbuf; struct stk_camera *dev = fp->private_data; + if (dev == NULL) + return -EIO; + if (!is_present(dev)) return -EIO; if (dev->owner && dev->owner != fp) @@ -765,6 +773,9 @@ static unsigned int v4l_stk_poll(struct file *fp, poll_table *wait) { struct stk_camera *dev = fp->private_data; + if (dev == NULL) + return -ENODEV; + poll_wait(fp, &dev->wait_frame, wait); if (!is_present(dev)) @@ -1425,7 +1436,7 @@ static void stk_camera_disconnect(struct usb_interface *interface) wake_up_interruptible(&dev->wait_frame); stk_remove_sysfs_files(&dev->vdev); - STK_INFO("Syntek USB2.0 Camera release resources " + STK_INFO("Syntek USB2.0 Camera release resources" "video device /dev/video%d\n", dev->vdev.minor); video_unregister_device(&dev->vdev); diff --git a/trunk/drivers/media/video/stk-webcam.h b/trunk/drivers/media/video/stk-webcam.h index 9f6736637571..084a85bdd16e 100644 --- a/trunk/drivers/media/video/stk-webcam.h +++ b/trunk/drivers/media/video/stk-webcam.h @@ -122,6 +122,7 @@ struct stk_camera { #define vdev_to_camera(d) container_of(d, struct stk_camera, vdev) +void stk_camera_delete(struct kref *); int stk_camera_write_reg(struct stk_camera *, u16, u8); int stk_camera_read_reg(struct stk_camera *, u16, int *); diff --git a/trunk/drivers/media/video/tveeprom.c b/trunk/drivers/media/video/tveeprom.c index 3b0b84c2e451..bcc32fa92a81 100644 --- a/trunk/drivers/media/video/tveeprom.c +++ b/trunk/drivers/media/video/tveeprom.c @@ -242,7 +242,7 @@ hauppauge_tuner[] = { TUNER_ABSENT, "TCL M2523_3DBH_E"}, { TUNER_ABSENT, "TCL M2523_3DIH_E"}, { TUNER_ABSENT, "TCL MFPE05_2_U"}, - { TUNER_PHILIPS_FMD1216MEX_MK3, "Philips FMD1216MEX"}, + { TUNER_PHILIPS_FMD1216ME_MK3, "Philips FMD1216MEX"}, { TUNER_ABSENT, "Philips FRH2036B"}, { TUNER_ABSENT, "Panasonic ENGF75_01GF"}, { TUNER_ABSENT, "MaxLinear MXL5005"}, diff --git a/trunk/drivers/media/video/videobuf-dvb.c b/trunk/drivers/media/video/videobuf-dvb.c index 917277d36605..b56cffcbfd45 100644 --- a/trunk/drivers/media/video/videobuf-dvb.c +++ b/trunk/drivers/media/video/videobuf-dvb.c @@ -126,6 +126,7 @@ static int videobuf_dvb_stop_feed(struct dvb_demux_feed *feed) mutex_lock(&dvb->lock); dvb->nfeeds--; if (0 == dvb->nfeeds && NULL != dvb->thread) { + // FIXME: cx8802_cancel_buffers(dev); err = kthread_stop(dvb->thread); dvb->thread = NULL; } @@ -133,38 +134,30 @@ static int videobuf_dvb_stop_feed(struct dvb_demux_feed *feed) return err; } -static int videobuf_dvb_register_adapter(struct videobuf_dvb_frontends *fe, +/* ------------------------------------------------------------------ */ + +int videobuf_dvb_register(struct videobuf_dvb *dvb, struct module *module, void *adapter_priv, struct device *device, - char *adapter_name, - short *adapter_nr, - int mfe_shared) + short *adapter_nr) { int result; - mutex_init(&fe->lock); + mutex_init(&dvb->lock); /* register adapter */ - result = dvb_register_adapter(&fe->adapter, adapter_name, module, - device, adapter_nr); + result = dvb_register_adapter(&dvb->adapter, dvb->name, module, device, + adapter_nr); if (result < 0) { printk(KERN_WARNING "%s: dvb_register_adapter failed (errno = %d)\n", - adapter_name, result); + dvb->name, result); + goto fail_adapter; } - fe->adapter.priv = adapter_priv; - fe->adapter.mfe_shared = mfe_shared; - - return result; -} - -static int videobuf_dvb_register_frontend(struct dvb_adapter *adapter, - struct videobuf_dvb *dvb) -{ - int result; + dvb->adapter.priv = adapter_priv; /* register frontend */ - result = dvb_register_frontend(adapter, dvb->frontend); + result = dvb_register_frontend(&dvb->adapter, dvb->frontend); if (result < 0) { printk(KERN_WARNING "%s: dvb_register_frontend failed (errno = %d)\n", dvb->name, result); @@ -190,8 +183,7 @@ static int videobuf_dvb_register_frontend(struct dvb_adapter *adapter, dvb->dmxdev.filternum = 256; dvb->dmxdev.demux = &dvb->demux.dmx; dvb->dmxdev.capabilities = 0; - result = dvb_dmxdev_init(&dvb->dmxdev, adapter); - + result = dvb_dmxdev_init(&dvb->dmxdev, &dvb->adapter); if (result < 0) { printk(KERN_WARNING "%s: dvb_dmxdev_init failed (errno = %d)\n", dvb->name, result); @@ -222,11 +214,7 @@ static int videobuf_dvb_register_frontend(struct dvb_adapter *adapter, } /* register network adapter */ - dvb_net_init(adapter, &dvb->net, &dvb->demux.dmx); - if (dvb->net.dvbdev == NULL) { - result = -ENOMEM; - goto fail_fe_conn; - } + dvb_net_init(&dvb->adapter, &dvb->net, &dvb->demux.dmx); return 0; fail_fe_conn: @@ -241,151 +229,30 @@ static int videobuf_dvb_register_frontend(struct dvb_adapter *adapter, dvb_unregister_frontend(dvb->frontend); fail_frontend: dvb_frontend_detach(dvb->frontend); - dvb->frontend = NULL; - + dvb_unregister_adapter(&dvb->adapter); +fail_adapter: return result; } -/* ------------------------------------------------------------------ */ -/* Register a single adapter and one or more frontends */ -int videobuf_dvb_register_bus(struct videobuf_dvb_frontends *f, - struct module *module, - void *adapter_priv, - struct device *device, - short *adapter_nr, - int mfe_shared) -{ - struct list_head *list, *q; - struct videobuf_dvb_frontend *fe; - int res; - - fe = videobuf_dvb_get_frontend(f, 1); - if (!fe) { - printk(KERN_WARNING "Unable to register the adapter which has no frontends\n"); - return -EINVAL; - } - - /* Bring up the adapter */ - res = videobuf_dvb_register_adapter(f, module, adapter_priv, device, - fe->dvb.name, adapter_nr, mfe_shared); - if (res < 0) { - printk(KERN_WARNING "videobuf_dvb_register_adapter failed (errno = %d)\n", res); - return res; - } - - /* Attach all of the frontends to the adapter */ - mutex_lock(&f->lock); - list_for_each_safe(list, q, &f->felist) { - fe = list_entry(list, struct videobuf_dvb_frontend, felist); - res = videobuf_dvb_register_frontend(&f->adapter, &fe->dvb); - if (res < 0) { - printk(KERN_WARNING "%s: videobuf_dvb_register_frontend failed (errno = %d)\n", - fe->dvb.name, res); - goto err; - } - } - mutex_unlock(&f->lock); - return 0; - -err: - mutex_unlock(&f->lock); - videobuf_dvb_unregister_bus(f); - return res; -} -EXPORT_SYMBOL(videobuf_dvb_register_bus); - -void videobuf_dvb_unregister_bus(struct videobuf_dvb_frontends *f) +void videobuf_dvb_unregister(struct videobuf_dvb *dvb) { - struct list_head *list, *q; - struct videobuf_dvb_frontend *fe; - - mutex_lock(&f->lock); - list_for_each_safe(list, q, &f->felist) { - fe = list_entry(list, struct videobuf_dvb_frontend, felist); - if (fe->dvb.net.dvbdev) { - dvb_net_release(&fe->dvb.net); - fe->dvb.demux.dmx.remove_frontend(&fe->dvb.demux.dmx, - &fe->dvb.fe_mem); - fe->dvb.demux.dmx.remove_frontend(&fe->dvb.demux.dmx, - &fe->dvb.fe_hw); - dvb_dmxdev_release(&fe->dvb.dmxdev); - dvb_dmx_release(&fe->dvb.demux); - dvb_unregister_frontend(fe->dvb.frontend); - } - if (fe->dvb.frontend) - /* always allocated, may have been reset */ - dvb_frontend_detach(fe->dvb.frontend); - list_del(list); - kfree(fe); - } - mutex_unlock(&f->lock); - - dvb_unregister_adapter(&f->adapter); -} -EXPORT_SYMBOL(videobuf_dvb_unregister_bus); - -struct videobuf_dvb_frontend *videobuf_dvb_get_frontend( - struct videobuf_dvb_frontends *f, int id) -{ - struct list_head *list, *q; - struct videobuf_dvb_frontend *fe, *ret = NULL; - - mutex_lock(&f->lock); - - list_for_each_safe(list, q, &f->felist) { - fe = list_entry(list, struct videobuf_dvb_frontend, felist); - if (fe->id == id) { - ret = fe; - break; - } - } - - mutex_unlock(&f->lock); - - return ret; -} -EXPORT_SYMBOL(videobuf_dvb_get_frontend); - -int videobuf_dvb_find_frontend(struct videobuf_dvb_frontends *f, - struct dvb_frontend *p) -{ - struct list_head *list, *q; - struct videobuf_dvb_frontend *fe = NULL; - int ret = 0; - - mutex_lock(&f->lock); - - list_for_each_safe(list, q, &f->felist) { - fe = list_entry(list, struct videobuf_dvb_frontend, felist); - if (fe->dvb.frontend == p) { - ret = fe->id; - break; - } - } - - mutex_unlock(&f->lock); - - return ret; + dvb_net_release(&dvb->net); + dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem); + dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw); + dvb_dmxdev_release(&dvb->dmxdev); + dvb_dmx_release(&dvb->demux); + dvb_unregister_frontend(dvb->frontend); + dvb_frontend_detach(dvb->frontend); + dvb_unregister_adapter(&dvb->adapter); } -EXPORT_SYMBOL(videobuf_dvb_find_frontend); -struct videobuf_dvb_frontend *videobuf_dvb_alloc_frontend( - struct videobuf_dvb_frontends *f, int id) -{ - struct videobuf_dvb_frontend *fe; +EXPORT_SYMBOL(videobuf_dvb_register); +EXPORT_SYMBOL(videobuf_dvb_unregister); - fe = kzalloc(sizeof(struct videobuf_dvb_frontend), GFP_KERNEL); - if (fe == NULL) - goto fail_alloc; - - fe->id = id; - mutex_init(&fe->dvb.lock); - - mutex_lock(&f->lock); - list_add_tail(&fe->felist, &f->felist); - mutex_unlock(&f->lock); - -fail_alloc: - return fe; -} -EXPORT_SYMBOL(videobuf_dvb_alloc_frontend); +/* ------------------------------------------------------------------ */ +/* + * Local variables: + * c-basic-offset: 8 + * compile-command: "make DVB=1" + * End: + */ diff --git a/trunk/drivers/media/video/vivi.c b/trunk/drivers/media/video/vivi.c index 7d7e51def461..65c8af18e767 100644 --- a/trunk/drivers/media/video/vivi.c +++ b/trunk/drivers/media/video/vivi.c @@ -128,56 +128,12 @@ struct vivi_fmt { int depth; }; -static struct vivi_fmt formats[] = { - { - .name = "4:2:2, packed, YUYV", - .fourcc = V4L2_PIX_FMT_YUYV, - .depth = 16, - }, - { - .name = "4:2:2, packed, UYVY", - .fourcc = V4L2_PIX_FMT_UYVY, - .depth = 16, - }, - { - .name = "RGB565 (LE)", - .fourcc = V4L2_PIX_FMT_RGB565, /* gggbbbbb rrrrrggg */ - .depth = 16, - }, - { - .name = "RGB565 (BE)", - .fourcc = V4L2_PIX_FMT_RGB565X, /* rrrrrggg gggbbbbb */ - .depth = 16, - }, - { - .name = "RGB555 (LE)", - .fourcc = V4L2_PIX_FMT_RGB555, /* gggbbbbb arrrrrgg */ - .depth = 16, - }, - { - .name = "RGB555 (BE)", - .fourcc = V4L2_PIX_FMT_RGB555X, /* arrrrrgg gggbbbbb */ - .depth = 16, - }, +static struct vivi_fmt format = { + .name = "4:2:2, packed, YUYV", + .fourcc = V4L2_PIX_FMT_YUYV, + .depth = 16, }; -static struct vivi_fmt *get_format(struct v4l2_format *f) -{ - struct vivi_fmt *fmt; - unsigned int k; - - for (k = 0; k < ARRAY_SIZE(formats); k++) { - fmt = &formats[k]; - if (fmt->fourcc == f->fmt.pix.pixelformat) - break; - } - - if (k == ARRAY_SIZE(formats)) - return NULL; - - return &formats[k]; -} - struct sg_to_addr { int pos; struct scatterlist *sg; @@ -234,7 +190,6 @@ struct vivi_fh { struct videobuf_queue vb_vidq; enum v4l2_buf_type type; - unsigned char bars[8][3]; }; /* ------------------------------------------------------------------ @@ -279,118 +234,42 @@ static u8 bars[8][3] = { #define TSTAMP_MAX_Y TSTAMP_MIN_Y+15 #define TSTAMP_MIN_X 64 -static void gen_twopix(struct vivi_fh *fh, unsigned char *buf, int colorpos) +static void gen_line(char *basep, int inipos, int wmax, + int hmax, int line, int count, char *timestr) { - unsigned char r_y, g_u, b_v; - unsigned char *p; - int color; + int w, i, j, y; + int pos = inipos; + char *p, *s; + u8 chr, r, g, b, color; - r_y = fh->bars[colorpos][0]; /* R or precalculated Y */ - g_u = fh->bars[colorpos][1]; /* G or precalculated U */ - b_v = fh->bars[colorpos][2]; /* B or precalculated V */ + /* We will just duplicate the second pixel at the packet */ + wmax /= 2; - for (color = 0; color < 4; color++) { - p = buf + color; + /* Generate a standard color bar pattern */ + for (w = 0; w < wmax; w++) { + int colorpos = ((w + count) * 8/(wmax + 1)) % 8; + r = bars[colorpos][0]; + g = bars[colorpos][1]; + b = bars[colorpos][2]; + + for (color = 0; color < 4; color++) { + p = basep + pos; - switch (fh->fmt->fourcc) { - case V4L2_PIX_FMT_YUYV: - switch (color) { - case 0: - case 2: - *p = r_y; - break; - case 1: - *p = g_u; - break; - case 3: - *p = b_v; - break; - } - break; - case V4L2_PIX_FMT_UYVY: - switch (color) { - case 1: - case 3: - *p = r_y; - break; - case 0: - *p = g_u; - break; - case 2: - *p = b_v; - break; - } - break; - case V4L2_PIX_FMT_RGB565: - switch (color) { - case 0: - case 2: - *p = (g_u << 5) | b_v; - break; - case 1: - case 3: - *p = (r_y << 3) | (g_u >> 3); - break; - } - break; - case V4L2_PIX_FMT_RGB565X: switch (color) { case 0: case 2: - *p = (r_y << 3) | (g_u >> 3); + *p = TO_Y(r, g, b); /* Luma */ break; case 1: - case 3: - *p = (g_u << 5) | b_v; + *p = TO_U(r, g, b); /* Cb */ break; - } - break; - case V4L2_PIX_FMT_RGB555: - switch (color) { - case 0: - case 2: - *p = (g_u << 5) | b_v; - break; - case 1: case 3: - *p = (r_y << 2) | (g_u >> 3); + *p = TO_V(r, g, b); /* Cr */ break; } - break; - case V4L2_PIX_FMT_RGB555X: - switch (color) { - case 0: - case 2: - *p = (r_y << 2) | (g_u >> 3); - break; - case 1: - case 3: - *p = (g_u << 5) | b_v; - break; - } - break; + pos++; } } -} - -static void gen_line(struct vivi_fh *fh, char *basep, int inipos, int wmax, - int hmax, int line, int count, char *timestr) -{ - int w, i, j; - int pos = inipos; - char *s; - u8 chr; - - /* We will just duplicate the second pixel at the packet */ - wmax /= 2; - - /* Generate a standard color bar pattern */ - for (w = 0; w < wmax; w++) { - int colorpos = ((w + count) * 8/(wmax + 1)) % 8; - - gen_twopix(fh, basep + pos, colorpos); - pos += 4; /* only 16 bpp supported for now */ - } /* Checks if it is possible to show timestamp */ if (TSTAMP_MAX_Y >= hmax) @@ -404,12 +283,38 @@ static void gen_line(struct vivi_fh *fh, char *basep, int inipos, int wmax, for (s = timestr; *s; s++) { chr = rom8x16_bits[(*s-0x30)*16+line-TSTAMP_MIN_Y]; for (i = 0; i < 7; i++) { + if (chr & 1 << (7 - i)) { + /* Font color*/ + r = 0; + g = 198; + b = 0; + } else { + /* Background color */ + r = bars[BLACK][0]; + g = bars[BLACK][1]; + b = bars[BLACK][2]; + } + pos = inipos + j * 2; - /* Draw white font on black background */ - if (chr & 1 << (7 - i)) - gen_twopix(fh, basep + pos, WHITE); - else - gen_twopix(fh, basep + pos, BLACK); + for (color = 0; color < 4; color++) { + p = basep + pos; + + y = TO_Y(r, g, b); + + switch (color) { + case 0: + case 2: + *p = TO_Y(r, g, b); /* Luma */ + break; + case 1: + *p = TO_U(r, g, b); /* Cb */ + break; + case 3: + *p = TO_V(r, g, b); /* Cr */ + break; + } + pos++; + } j++; } } @@ -419,9 +324,8 @@ static void gen_line(struct vivi_fh *fh, char *basep, int inipos, int wmax, return; } -static void vivi_fillbuff(struct vivi_fh *fh, struct vivi_buffer *buf) +static void vivi_fillbuff(struct vivi_dev *dev, struct vivi_buffer *buf) { - struct vivi_dev *dev = fh->dev; int h , pos = 0; int hmax = buf->vb.height; int wmax = buf->vb.width; @@ -437,7 +341,7 @@ static void vivi_fillbuff(struct vivi_fh *fh, struct vivi_buffer *buf) return; for (h = 0; h < hmax; h++) { - gen_line(fh, tmpbuf, 0, wmax, hmax, h, dev->mv_count, + gen_line(tmpbuf, 0, wmax, hmax, h, dev->mv_count, dev->timestr); memcpy(vbuf + pos, tmpbuf, wmax * 2); pos += wmax*2; @@ -506,7 +410,7 @@ static void vivi_thread_tick(struct vivi_fh *fh) do_gettimeofday(&buf->vb.ts); /* Fill buffer */ - vivi_fillbuff(fh, buf); + vivi_fillbuff(dev, buf); dprintk(dev, 1, "filled buffer %p\n", buf); wake_up(&buf->vb.done); @@ -732,15 +636,11 @@ static int vidioc_querycap(struct file *file, void *priv, static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, struct v4l2_fmtdesc *f) { - struct vivi_fmt *fmt; - - if (f->index >= ARRAY_SIZE(formats)) + if (f->index > 0) return -EINVAL; - fmt = &formats[f->index]; - - strlcpy(f->description, fmt->name, sizeof(f->description)); - f->pixelformat = fmt->fourcc; + strlcpy(f->description, format.name, sizeof(f->description)); + f->pixelformat = format.fourcc; return 0; } @@ -770,12 +670,13 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, enum v4l2_field field; unsigned int maxw, maxh; - fmt = get_format(f); - if (!fmt) { - dprintk(dev, 1, "Fourcc format (0x%08x) invalid.\n", - f->fmt.pix.pixelformat); + if (format.fourcc != f->fmt.pix.pixelformat) { + dprintk(dev, 1, "Fourcc format (0x%08x) invalid. " + "Driver accepts only 0x%08x\n", + f->fmt.pix.pixelformat, format.fourcc); return -EINVAL; } + fmt = &format; field = f->fmt.pix.field; @@ -813,8 +714,6 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, { struct vivi_fh *fh = priv; struct videobuf_queue *q = &fh->vb_vidq; - unsigned char r, g, b; - int k, is_yuv; int ret = vidioc_try_fmt_vid_cap(file, fh, f); if (ret < 0) @@ -828,49 +727,12 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, goto out; } - fh->fmt = get_format(f); + fh->fmt = &format; fh->width = f->fmt.pix.width; fh->height = f->fmt.pix.height; fh->vb_vidq.field = f->fmt.pix.field; fh->type = f->type; - /* precalculate color bar values to speed up rendering */ - for (k = 0; k < 8; k++) { - r = bars[k][0]; - g = bars[k][1]; - b = bars[k][2]; - is_yuv = 0; - - switch (fh->fmt->fourcc) { - case V4L2_PIX_FMT_YUYV: - case V4L2_PIX_FMT_UYVY: - is_yuv = 1; - break; - case V4L2_PIX_FMT_RGB565: - case V4L2_PIX_FMT_RGB565X: - r >>= 3; - g >>= 2; - b >>= 3; - break; - case V4L2_PIX_FMT_RGB555: - case V4L2_PIX_FMT_RGB555X: - r >>= 3; - g >>= 3; - b >>= 3; - break; - } - - if (is_yuv) { - fh->bars[k][0] = TO_Y(r, g, b); /* Luma */ - fh->bars[k][1] = TO_U(r, g, b); /* Cb */ - fh->bars[k][2] = TO_V(r, g, b); /* Cr */ - } else { - fh->bars[k][0] = r; - fh->bars[k][1] = g; - fh->bars[k][2] = b; - } - } - ret = 0; out: mutex_unlock(&q->vb_lock); @@ -1024,6 +886,8 @@ static int vidioc_s_ctrl(struct file *file, void *priv, File operations for the device ------------------------------------------------------------------*/ +#define line_buf_size(norm) (norm_maxw(norm)*(format.depth+7)/8) + static int vivi_open(struct inode *inode, struct file *file) { int minor = iminor(inode); @@ -1072,7 +936,7 @@ static int vivi_open(struct inode *inode, struct file *file) fh->dev = dev; fh->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - fh->fmt = &formats[0]; + fh->fmt = &format; fh->width = 640; fh->height = 480; diff --git a/trunk/drivers/media/video/vpx3220.c b/trunk/drivers/media/video/vpx3220.c index 67aa0db4b81a..45be9ec8edc4 100644 --- a/trunk/drivers/media/video/vpx3220.c +++ b/trunk/drivers/media/video/vpx3220.c @@ -22,21 +22,32 @@ #include #include #include +#include + +#include #include + #include -#include -#include + +#define I2C_NAME(x) (x)->name + #include +#include #include -MODULE_DESCRIPTION("vpx3220a/vpx3216b/vpx3214c video decoder driver"); -MODULE_AUTHOR("Laurent Pinchart"); -MODULE_LICENSE("GPL"); +#define I2C_VPX3220 0x86 +#define VPX3220_DEBUG KERN_DEBUG "vpx3220: " static int debug; module_param(debug, int, 0); MODULE_PARM_DESC(debug, "Debug level (0-1)"); +#define dprintk(num, format, args...) \ + do { \ + if (debug >= num) \ + printk(format, ##args); \ + } while (0) + #define VPX_TIMEOUT_COUNT 10 /* ----------------------------------------------------------------------- */ @@ -56,8 +67,10 @@ struct vpx3220 { static char *inputs[] = { "internal", "composite", "svideo" }; /* ----------------------------------------------------------------------- */ - -static inline int vpx3220_write(struct i2c_client *client, u8 reg, u8 value) +static inline int +vpx3220_write (struct i2c_client *client, + u8 reg, + u8 value) { struct vpx3220 *decoder = i2c_get_clientdata(client); @@ -65,12 +78,15 @@ static inline int vpx3220_write(struct i2c_client *client, u8 reg, u8 value) return i2c_smbus_write_byte_data(client, reg, value); } -static inline int vpx3220_read(struct i2c_client *client, u8 reg) +static inline int +vpx3220_read (struct i2c_client *client, + u8 reg) { return i2c_smbus_read_byte_data(client, reg); } -static int vpx3220_fp_status(struct i2c_client *client) +static int +vpx3220_fp_status (struct i2c_client *client) { unsigned char status; unsigned int i; @@ -90,11 +106,14 @@ static int vpx3220_fp_status(struct i2c_client *client) return -1; } -static int vpx3220_fp_write(struct i2c_client *client, u8 fpaddr, u16 data) +static int +vpx3220_fp_write (struct i2c_client *client, + u8 fpaddr, + u16 data) { /* Write the 16-bit address to the FPWR register */ if (i2c_smbus_write_word_data(client, 0x27, swab16(fpaddr)) == -1) { - v4l_dbg(1, debug, client, "%s: failed\n", __func__); + dprintk(1, VPX3220_DEBUG "%s: failed\n", __func__); return -1; } @@ -103,20 +122,22 @@ static int vpx3220_fp_write(struct i2c_client *client, u8 fpaddr, u16 data) /* Write the 16-bit data to the FPDAT register */ if (i2c_smbus_write_word_data(client, 0x28, swab16(data)) == -1) { - v4l_dbg(1, debug, client, "%s: failed\n", __func__); + dprintk(1, VPX3220_DEBUG "%s: failed\n", __func__); return -1; } return 0; } -static u16 vpx3220_fp_read(struct i2c_client *client, u16 fpaddr) +static u16 +vpx3220_fp_read (struct i2c_client *client, + u16 fpaddr) { s16 data; /* Write the 16-bit address to the FPRD register */ if (i2c_smbus_write_word_data(client, 0x26, swab16(fpaddr)) == -1) { - v4l_dbg(1, debug, client, "%s: failed\n", __func__); + dprintk(1, VPX3220_DEBUG "%s: failed\n", __func__); return -1; } @@ -126,22 +147,25 @@ static u16 vpx3220_fp_read(struct i2c_client *client, u16 fpaddr) /* Read the 16-bit data from the FPDAT register */ data = i2c_smbus_read_word_data(client, 0x28); if (data == -1) { - v4l_dbg(1, debug, client, "%s: failed\n", __func__); + dprintk(1, VPX3220_DEBUG "%s: failed\n", __func__); return -1; } return swab16(data); } -static int vpx3220_write_block(struct i2c_client *client, const u8 *data, unsigned int len) +static int +vpx3220_write_block (struct i2c_client *client, + const u8 *data, + unsigned int len) { u8 reg; int ret = -1; while (len >= 2) { reg = *data++; - ret = vpx3220_write(client, reg, *data++); - if (ret < 0) + if ((ret = + vpx3220_write(client, reg, *data++)) < 0) break; len -= 2; } @@ -149,8 +173,10 @@ static int vpx3220_write_block(struct i2c_client *client, const u8 *data, unsign return ret; } -static int vpx3220_write_fp_block(struct i2c_client *client, - const u16 *data, unsigned int len) +static int +vpx3220_write_fp_block (struct i2c_client *client, + const u16 *data, + unsigned int len) { u8 reg; int ret = 0; @@ -259,20 +285,25 @@ static const unsigned short init_fp[] = { 0x4b, 0x298, /* PLL gain */ }; -static void vpx3220_dump_i2c(struct i2c_client *client) +static void +vpx3220_dump_i2c (struct i2c_client *client) { int len = sizeof(init_common); const unsigned char *data = init_common; while (len > 1) { - v4l_dbg(1, debug, client, "i2c reg 0x%02x data 0x%02x\n", + dprintk(1, + KERN_DEBUG "vpx3216b i2c reg 0x%02x data 0x%02x\n", *data, vpx3220_read(client, *data)); data += 2; len -= 2; } } -static int vpx3220_command(struct i2c_client *client, unsigned cmd, void *arg) +static int +vpx3220_command (struct i2c_client *client, + unsigned int cmd, + void *arg) { struct vpx3220 *decoder = i2c_get_clientdata(client); @@ -284,6 +315,7 @@ static int vpx3220_command(struct i2c_client *client, unsigned cmd, void *arg) vpx3220_write_fp_block(client, init_fp, sizeof(init_fp) >> 1); switch (decoder->norm) { + case VIDEO_MODE_NTSC: vpx3220_write_fp_block(client, init_ntsc, sizeof(init_ntsc) >> 1); @@ -302,20 +334,21 @@ static int vpx3220_command(struct i2c_client *client, unsigned cmd, void *arg) sizeof(init_pal) >> 1); break; } - break; } + break; case DECODER_DUMP: { vpx3220_dump_i2c(client); - break; } + break; case DECODER_GET_CAPABILITIES: { struct video_decoder_capability *cap = arg; - v4l_dbg(1, debug, client, "DECODER_GET_CAPABILITIES\n"); + dprintk(1, KERN_DEBUG "%s: DECODER_GET_CAPABILITIES\n", + I2C_NAME(client)); cap->flags = VIDEO_DECODER_PAL | VIDEO_DECODER_NTSC | @@ -324,18 +357,20 @@ static int vpx3220_command(struct i2c_client *client, unsigned cmd, void *arg) VIDEO_DECODER_CCIR; cap->inputs = 3; cap->outputs = 1; - break; } + break; case DECODER_GET_STATUS: { int res = 0, status; - v4l_dbg(1, debug, client, "DECODER_GET_STATUS\n"); + dprintk(1, KERN_INFO "%s: DECODER_GET_STATUS\n", + I2C_NAME(client)); status = vpx3220_fp_read(client, 0x0f3); - v4l_dbg(1, debug, client, "status: 0x%04x\n", status); + dprintk(1, KERN_INFO "%s: status: 0x%04x\n", I2C_NAME(client), + status); if (status < 0) return status; @@ -344,6 +379,7 @@ static int vpx3220_command(struct i2c_client *client, unsigned cmd, void *arg) res |= DECODER_STATUS_GOOD | DECODER_STATUS_COLOR; switch (status & 0x18) { + case 0x00: case 0x10: case 0x14: @@ -364,8 +400,8 @@ static int vpx3220_command(struct i2c_client *client, unsigned cmd, void *arg) } *(int *) arg = res; - break; } + break; case DECODER_SET_NORM: { @@ -377,43 +413,50 @@ static int vpx3220_command(struct i2c_client *client, unsigned cmd, void *arg) choosen video norm */ temp_input = vpx3220_fp_read(client, 0xf2); - v4l_dbg(1, debug, client, "DECODER_SET_NORM %d\n", *iarg); + dprintk(1, KERN_DEBUG "%s: DECODER_SET_NORM %d\n", + I2C_NAME(client), *iarg); switch (*iarg) { + case VIDEO_MODE_NTSC: vpx3220_write_fp_block(client, init_ntsc, sizeof(init_ntsc) >> 1); - v4l_dbg(1, debug, client, "norm switched to NTSC\n"); + dprintk(1, KERN_INFO "%s: norm switched to NTSC\n", + I2C_NAME(client)); break; case VIDEO_MODE_PAL: vpx3220_write_fp_block(client, init_pal, sizeof(init_pal) >> 1); - v4l_dbg(1, debug, client, "norm switched to PAL\n"); + dprintk(1, KERN_INFO "%s: norm switched to PAL\n", + I2C_NAME(client)); break; case VIDEO_MODE_SECAM: vpx3220_write_fp_block(client, init_secam, sizeof(init_secam) >> 1); - v4l_dbg(1, debug, client, "norm switched to SECAM\n"); + dprintk(1, KERN_INFO "%s: norm switched to SECAM\n", + I2C_NAME(client)); break; case VIDEO_MODE_AUTO: /* FIXME This is only preliminary support */ data = vpx3220_fp_read(client, 0xf2) & 0x20; vpx3220_fp_write(client, 0xf2, 0x00c0 | data); - v4l_dbg(1, debug, client, "norm switched to AUTO\n"); + dprintk(1, KERN_INFO "%s: norm switched to Auto\n", + I2C_NAME(client)); break; default: return -EINVAL; + } decoder->norm = *iarg; /* And here we set the backed up video input again */ vpx3220_fp_write(client, 0xf2, temp_input | 0x0010); udelay(10); - break; } + break; case DECODER_SET_INPUT: { @@ -432,7 +475,8 @@ static int vpx3220_command(struct i2c_client *client, unsigned cmd, void *arg) if (*iarg < 0 || *iarg > 2) return -EINVAL; - v4l_dbg(1, debug, client, "input switched to %s\n", inputs[*iarg]); + dprintk(1, KERN_INFO "%s: input switched to %s\n", + I2C_NAME(client), inputs[*iarg]); vpx3220_write(client, 0x33, input[*iarg][0]); @@ -444,8 +488,8 @@ static int vpx3220_command(struct i2c_client *client, unsigned cmd, void *arg) data | (input[*iarg][1] << 5) | 0x0010); udelay(10); - break; } + break; case DECODER_SET_OUTPUT: { @@ -455,18 +499,19 @@ static int vpx3220_command(struct i2c_client *client, unsigned cmd, void *arg) if (*iarg != 0) { return -EINVAL; } - break; } + break; case DECODER_ENABLE_OUTPUT: { int *iarg = arg; - v4l_dbg(1, debug, client, "DECODER_ENABLE_OUTPUT %d\n", *iarg); + dprintk(1, KERN_DEBUG "%s: DECODER_ENABLE_OUTPUT %d\n", + I2C_NAME(client), *iarg); vpx3220_write(client, 0xf2, (*iarg ? 0x1b : 0x00)); - break; } + break; case DECODER_SET_PICTURE: { @@ -497,8 +542,8 @@ static int vpx3220_command(struct i2c_client *client, unsigned cmd, void *arg) vpx3220_fp_write(client, 0x1c, ((decoder->hue - 32768) >> 6) & 0xFFF); } - break; } + break; default: return -EINVAL; @@ -507,7 +552,8 @@ static int vpx3220_command(struct i2c_client *client, unsigned cmd, void *arg) return 0; } -static int vpx3220_init_client(struct i2c_client *client) +static int +vpx3220_init_client (struct i2c_client *client) { vpx3220_write_block(client, init_common, sizeof(init_common)); vpx3220_write_fp_block(client, init_fp, sizeof(init_fp) >> 1); @@ -521,26 +567,115 @@ static int vpx3220_init_client(struct i2c_client *client) * Client management code */ -static unsigned short normal_i2c[] = { 0x86 >> 1, 0x8e >> 1, I2C_CLIENT_END }; +/* + * Generic i2c probe + * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1' + */ +static unsigned short normal_i2c[] = + { I2C_VPX3220 >> 1, (I2C_VPX3220 >> 1) + 4, + I2C_CLIENT_END +}; + +static unsigned short ignore = I2C_CLIENT_END; -I2C_CLIENT_INSMOD; +static struct i2c_client_address_data addr_data = { + .normal_i2c = normal_i2c, + .probe = &ignore, + .ignore = &ignore, +}; + +static struct i2c_driver vpx3220_i2c_driver; + +static int +vpx3220_detach_client (struct i2c_client *client) +{ + struct vpx3220 *decoder = i2c_get_clientdata(client); + int err; + + err = i2c_detach_client(client); + if (err) { + return err; + } + + kfree(decoder); + kfree(client); + + return 0; +} -static int vpx3220_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int +vpx3220_detect_client (struct i2c_adapter *adapter, + int address, + int kind) { + int err; + struct i2c_client *client; struct vpx3220 *decoder; - const char *name = NULL; - u8 ver; - u16 pn; + + dprintk(1, VPX3220_DEBUG "%s\n", __func__); /* Check if the adapter supports the needed features */ - if (!i2c_check_functionality(client->adapter, - I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA)) - return -ENODEV; + if (!i2c_check_functionality + (adapter, I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA)) + return 0; + + client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); + if (client == NULL) { + return -ENOMEM; + } + + client->addr = address; + client->adapter = adapter; + client->driver = &vpx3220_i2c_driver; + + /* Check for manufacture ID and part number */ + if (kind < 0) { + u8 id; + u16 pn; + + id = vpx3220_read(client, 0x00); + if (id != 0xec) { + dprintk(1, + KERN_INFO + "vpx3220_attach: Wrong manufacturer ID (0x%02x)\n", + id); + kfree(client); + return 0; + } + + pn = (vpx3220_read(client, 0x02) << 8) + + vpx3220_read(client, 0x01); + switch (pn) { + case 0x4680: + strlcpy(I2C_NAME(client), "vpx3220a", + sizeof(I2C_NAME(client))); + break; + case 0x4260: + strlcpy(I2C_NAME(client), "vpx3216b", + sizeof(I2C_NAME(client))); + break; + case 0x4280: + strlcpy(I2C_NAME(client), "vpx3214c", + sizeof(I2C_NAME(client))); + break; + default: + dprintk(1, + KERN_INFO + "%s: Wrong part number (0x%04x)\n", + __func__, pn); + kfree(client); + return 0; + } + } else { + strlcpy(I2C_NAME(client), "forced vpx32xx", + sizeof(I2C_NAME(client))); + } decoder = kzalloc(sizeof(struct vpx3220), GFP_KERNEL); - if (decoder == NULL) + if (decoder == NULL) { + kfree(client); return -ENOMEM; + } decoder->norm = VIDEO_MODE_PAL; decoder->input = 0; decoder->enable = 1; @@ -550,52 +685,63 @@ static int vpx3220_probe(struct i2c_client *client, decoder->sat = 32768; i2c_set_clientdata(client, decoder); - ver = i2c_smbus_read_byte_data(client, 0x00); - pn = (i2c_smbus_read_byte_data(client, 0x02) << 8) + - i2c_smbus_read_byte_data(client, 0x01); - if (ver == 0xec) { - switch (pn) { - case 0x4680: - name = "vpx3220a"; - break; - case 0x4260: - name = "vpx3216b"; - break; - case 0x4280: - name = "vpx3214c"; - break; - } + err = i2c_attach_client(client); + if (err) { + kfree(client); + kfree(decoder); + return err; } - if (name) - v4l_info(client, "%s found @ 0x%x (%s)\n", name, - client->addr << 1, client->adapter->name); - else - v4l_info(client, "chip (%02x:%04x) found @ 0x%x (%s)\n", - ver, pn, client->addr << 1, client->adapter->name); + + dprintk(1, KERN_INFO "%s: vpx32xx client found at address 0x%02x\n", + I2C_NAME(client), client->addr << 1); vpx3220_init_client(client); + return 0; } -static int vpx3220_remove(struct i2c_client *client) +static int +vpx3220_attach_adapter (struct i2c_adapter *adapter) { - kfree(i2c_get_clientdata(client)); - return 0; + int ret; + + ret = i2c_probe(adapter, &addr_data, &vpx3220_detect_client); + dprintk(1, VPX3220_DEBUG "%s: i2c_probe returned %d\n", + __func__, ret); + return ret; } -static const struct i2c_device_id vpx3220_id[] = { - { "vpx3220a", 0 }, - { "vpx3216b", 0 }, - { "vpx3214c", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, vpx3220_id); +/* ----------------------------------------------------------------------- + * Driver initialization and cleanup code + */ + +static struct i2c_driver vpx3220_i2c_driver = { + .driver = { + .name = "vpx3220", + }, -static struct v4l2_i2c_driver_data v4l2_i2c_data = { - .name = "vpx3220", - .driverid = I2C_DRIVERID_VPX3220, + .id = I2C_DRIVERID_VPX3220, + + .attach_adapter = vpx3220_attach_adapter, + .detach_client = vpx3220_detach_client, .command = vpx3220_command, - .probe = vpx3220_probe, - .remove = vpx3220_remove, - .id_table = vpx3220_id, }; + +static int __init +vpx3220_init (void) +{ + return i2c_add_driver(&vpx3220_i2c_driver); +} + +static void __exit +vpx3220_cleanup (void) +{ + i2c_del_driver(&vpx3220_i2c_driver); +} + +module_init(vpx3220_init); +module_exit(vpx3220_cleanup); + +MODULE_DESCRIPTION("vpx3220a/vpx3216b/vpx3214c video decoder driver"); +MODULE_AUTHOR("Laurent Pinchart"); +MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/media/video/zoran/zoran_card.c b/trunk/drivers/media/video/zoran/zoran_card.c index fa5f2f8f518a..3282be730298 100644 --- a/trunk/drivers/media/video/zoran/zoran_card.c +++ b/trunk/drivers/media/video/zoran/zoran_card.c @@ -817,7 +817,6 @@ zoran_register_i2c (struct zoran *zr) memcpy(&zr->i2c_algo, &zoran_i2c_bit_data_template, sizeof(struct i2c_algo_bit_data)); zr->i2c_algo.data = zr; - zr->i2c_adapter.class = I2C_CLASS_TV_ANALOG; zr->i2c_adapter.id = I2C_HW_B_ZR36067; zr->i2c_adapter.client_register = zoran_i2c_client_register; zr->i2c_adapter.client_unregister = zoran_i2c_client_unregister; diff --git a/trunk/drivers/media/video/zoran/zoran_driver.c b/trunk/drivers/media/video/zoran/zoran_driver.c index db11ab9e60da..25de7631443e 100644 --- a/trunk/drivers/media/video/zoran/zoran_driver.c +++ b/trunk/drivers/media/video/zoran/zoran_driver.c @@ -2996,6 +2996,7 @@ zoran_do_ioctl (struct inode *inode, break; default: + dprintk(3, "unsupported\n"); dprintk(1, KERN_ERR "%s: VIDIOC_S_FMT - unsupported type %d\n", diff --git a/trunk/drivers/usb/serial/option.c b/trunk/drivers/usb/serial/option.c index 6b1727e751e3..2d728e897b4d 100644 --- a/trunk/drivers/usb/serial/option.c +++ b/trunk/drivers/usb/serial/option.c @@ -220,6 +220,10 @@ static int option_send_setup(struct tty_struct *tty, struct usb_serial_port *po #define ZTE_PRODUCT_MF628 0x0015 #define ZTE_PRODUCT_CDMA_TECH 0xfffe +/* Ericsson products */ +#define ERICSSON_VENDOR_ID 0x0bdb +#define ERICSSON_PRODUCT_F3507G 0x1900 + static struct usb_device_id option_ids[] = { { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, @@ -318,6 +322,7 @@ static struct usb_device_id option_ids[] = { { USB_DEVICE(DELL_VENDOR_ID, 0x8136) }, /* Dell Wireless HSDPA 5520 == Novatel Expedite EU860D */ { USB_DEVICE(DELL_VENDOR_ID, 0x8137) }, /* Dell Wireless HSDPA 5520 */ { USB_DEVICE(DELL_VENDOR_ID, 0x8138) }, /* Dell Wireless 5520 Voda I Mobile Broadband (3G HSDPA) Minicard */ + { USB_DEVICE(DELL_VENDOR_ID, 0x8147) }, /* Dell Wireless 5530 Mobile Broadband (3G HSPA) Mini-Card */ { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) }, { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) }, { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_620UW) }, @@ -349,6 +354,7 @@ static struct usb_device_id option_ids[] = { { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) }, { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_MF628) }, { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH) }, + { USB_DEVICE(ERICSSON_VENDOR_ID, ERICSSON_PRODUCT_F3507G) }, { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, option_ids); diff --git a/trunk/fs/Kconfig b/trunk/fs/Kconfig index d0a1174fb516..9e9d70c02a07 100644 --- a/trunk/fs/Kconfig +++ b/trunk/fs/Kconfig @@ -160,7 +160,7 @@ config EXT4_FS filesystem initially. To compile this file system support as a module, choose M here. The - module will be called ext4. + module will be called ext4dev. If unsure, say N. diff --git a/trunk/fs/Makefile b/trunk/fs/Makefile index 2168c902d5ca..d0c69f57e5bf 100644 --- a/trunk/fs/Makefile +++ b/trunk/fs/Makefile @@ -71,7 +71,7 @@ obj-$(CONFIG_DLM) += dlm/ # Do not add any filesystems before this line obj-$(CONFIG_REISERFS_FS) += reiserfs/ obj-$(CONFIG_EXT3_FS) += ext3/ # Before ext2 so root fs can be ext3 -obj-$(CONFIG_EXT4_FS) += ext4/ # Before ext2 so root fs can be ext4 +obj-$(CONFIG_EXT4_FS) += ext4/ # Before ext2 so root fs can be ext4dev obj-$(CONFIG_JBD) += jbd/ obj-$(CONFIG_JBD2) += jbd2/ obj-$(CONFIG_EXT2_FS) += ext2/ diff --git a/trunk/fs/ext4/balloc.c b/trunk/fs/ext4/balloc.c index b9821be709bd..bd2ece228827 100644 --- a/trunk/fs/ext4/balloc.c +++ b/trunk/fs/ext4/balloc.c @@ -568,16 +568,8 @@ void ext4_free_blocks(handle_t *handle, struct inode *inode, /* this isn't the right place to decide whether block is metadata * inode.c/extents.c knows better, but for safety ... */ - if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)) - metadata = 1; - - /* We need to make sure we don't reuse - * block released untill the transaction commit. - * writeback mode have weak data consistency so - * don't force data as metadata when freeing block - * for writeback mode. - */ - if (metadata == 0 && !ext4_should_writeback_data(inode)) + if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode) || + ext4_should_journal_data(inode)) metadata = 1; sb = inode->i_sb; diff --git a/trunk/fs/ext4/ext4.h b/trunk/fs/ext4/ext4.h index 4880cc3e6727..6690a41cdd9f 100644 --- a/trunk/fs/ext4/ext4.h +++ b/trunk/fs/ext4/ext4.h @@ -511,6 +511,7 @@ do { \ /* * Mount flags */ +#define EXT4_MOUNT_CHECK 0x00001 /* Do mount-time checks */ #define EXT4_MOUNT_OLDALLOC 0x00002 /* Don't use the new Orlov allocator */ #define EXT4_MOUNT_GRPID 0x00004 /* Create files with directory's group */ #define EXT4_MOUNT_DEBUG 0x00008 /* Some debugging messages */ diff --git a/trunk/fs/ext4/ext4_sb.h b/trunk/fs/ext4/ext4_sb.h index 445fde603df8..6a0b40d43264 100644 --- a/trunk/fs/ext4/ext4_sb.h +++ b/trunk/fs/ext4/ext4_sb.h @@ -99,6 +99,9 @@ struct ext4_sb_info { struct inode *s_buddy_cache; long s_blocks_reserved; spinlock_t s_reserve_lock; + struct list_head s_active_transaction; + struct list_head s_closed_transaction; + struct list_head s_committed_transaction; spinlock_t s_md_lock; tid_t s_last_transaction; unsigned short *s_mb_offsets, *s_mb_maxs; diff --git a/trunk/fs/ext4/inode.c b/trunk/fs/ext4/inode.c index 8dbf6953845b..9b4ec9decfd1 100644 --- a/trunk/fs/ext4/inode.c +++ b/trunk/fs/ext4/inode.c @@ -1648,7 +1648,6 @@ static int mpage_da_submit_io(struct mpage_da_data *mpd) int ret = 0, err, nr_pages, i; unsigned long index, end; struct pagevec pvec; - long pages_skipped; BUG_ON(mpd->next_page <= mpd->first_page); pagevec_init(&pvec, 0); @@ -1656,30 +1655,20 @@ static int mpage_da_submit_io(struct mpage_da_data *mpd) end = mpd->next_page - 1; while (index <= end) { - /* - * We can use PAGECACHE_TAG_DIRTY lookup here because - * even though we have cleared the dirty flag on the page - * We still keep the page in the radix tree with tag - * PAGECACHE_TAG_DIRTY. See clear_page_dirty_for_io. - * The PAGECACHE_TAG_DIRTY is cleared in set_page_writeback - * which is called via the below writepage callback. - */ - nr_pages = pagevec_lookup_tag(&pvec, mapping, &index, - PAGECACHE_TAG_DIRTY, - min(end - index, - (pgoff_t)PAGEVEC_SIZE-1) + 1); + /* XXX: optimize tail */ + nr_pages = pagevec_lookup(&pvec, mapping, index, PAGEVEC_SIZE); if (nr_pages == 0) break; for (i = 0; i < nr_pages; i++) { struct page *page = pvec.pages[i]; - pages_skipped = mpd->wbc->pages_skipped; + index = page->index; + if (index > end) + break; + index++; + err = mapping->a_ops->writepage(page, mpd->wbc); - if (!err && (pages_skipped == mpd->wbc->pages_skipped)) - /* - * have successfully written the page - * without skipping the same - */ + if (!err) mpd->pages_written++; /* * In error case, we have to continue because @@ -2115,6 +2104,7 @@ static int mpage_da_writepages(struct address_space *mapping, struct writeback_control *wbc, struct mpage_da_data *mpd) { + long to_write; int ret; if (!mpd->get_block) @@ -2129,18 +2119,19 @@ static int mpage_da_writepages(struct address_space *mapping, mpd->pages_written = 0; mpd->retval = 0; + to_write = wbc->nr_to_write; + ret = write_cache_pages(mapping, wbc, __mpage_da_writepage, mpd); + /* * Handle last extent of pages */ if (!mpd->io_done && mpd->next_page != mpd->first_page) { if (mpage_da_map_blocks(mpd) == 0) mpage_da_submit_io(mpd); - - mpd->io_done = 1; - ret = MPAGE_DA_EXTENT_TAIL; } - wbc->nr_to_write -= mpd->pages_written; + + wbc->nr_to_write = to_write - mpd->pages_written; return ret; } @@ -2369,14 +2360,12 @@ static int ext4_da_writepages_trans_blocks(struct inode *inode) static int ext4_da_writepages(struct address_space *mapping, struct writeback_control *wbc) { - pgoff_t index; - int range_whole = 0; handle_t *handle = NULL; + loff_t range_start = 0; struct mpage_da_data mpd; struct inode *inode = mapping->host; - int no_nrwrite_index_update; - long pages_written = 0, pages_skipped; int needed_blocks, ret = 0, nr_to_writebump = 0; + long to_write, pages_skipped = 0; struct ext4_sb_info *sbi = EXT4_SB(mapping->host->i_sb); /* @@ -2396,26 +2385,23 @@ static int ext4_da_writepages(struct address_space *mapping, nr_to_writebump = sbi->s_mb_stream_request - wbc->nr_to_write; wbc->nr_to_write = sbi->s_mb_stream_request; } - if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX) - range_whole = 1; - if (wbc->range_cyclic) - index = mapping->writeback_index; - else - index = wbc->range_start >> PAGE_CACHE_SHIFT; + if (!wbc->range_cyclic) + /* + * If range_cyclic is not set force range_cont + * and save the old writeback_index + */ + wbc->range_cont = 1; + + range_start = wbc->range_start; + pages_skipped = wbc->pages_skipped; mpd.wbc = wbc; mpd.inode = mapping->host; - /* - * we don't want write_cache_pages to update - * nr_to_write and writeback_index - */ - no_nrwrite_index_update = wbc->no_nrwrite_index_update; - wbc->no_nrwrite_index_update = 1; - pages_skipped = wbc->pages_skipped; - - while (!ret && wbc->nr_to_write > 0) { +restart_loop: + to_write = wbc->nr_to_write; + while (!ret && to_write > 0) { /* * we insert one extent at a time. So we need @@ -2436,53 +2422,48 @@ static int ext4_da_writepages(struct address_space *mapping, dump_stack(); goto out_writepages; } + to_write -= wbc->nr_to_write; + mpd.get_block = ext4_da_get_block_write; ret = mpage_da_writepages(mapping, wbc, &mpd); ext4_journal_stop(handle); - if (mpd.retval == -ENOSPC) { - /* commit the transaction which would - * free blocks released in the transaction - * and try again - */ + if (mpd.retval == -ENOSPC) jbd2_journal_force_commit_nested(sbi->s_journal); - wbc->pages_skipped = pages_skipped; - ret = 0; - } else if (ret == MPAGE_DA_EXTENT_TAIL) { + + /* reset the retry count */ + if (ret == MPAGE_DA_EXTENT_TAIL) { /* * got one extent now try with * rest of the pages */ - pages_written += mpd.pages_written; - wbc->pages_skipped = pages_skipped; + to_write += wbc->nr_to_write; ret = 0; - } else if (wbc->nr_to_write) + } else if (wbc->nr_to_write) { /* * There is no more writeout needed * or we requested for a noblocking writeout * and we found the device congested */ + to_write += wbc->nr_to_write; break; + } + wbc->nr_to_write = to_write; + } + + if (wbc->range_cont && (pages_skipped != wbc->pages_skipped)) { + /* We skipped pages in this loop */ + wbc->range_start = range_start; + wbc->nr_to_write = to_write + + wbc->pages_skipped - pages_skipped; + wbc->pages_skipped = pages_skipped; + goto restart_loop; } - if (pages_skipped != wbc->pages_skipped) - printk(KERN_EMERG "This should not happen leaving %s " - "with nr_to_write = %ld ret = %d\n", - __func__, wbc->nr_to_write, ret); - - /* Update index */ - index += pages_written; - if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0)) - /* - * set the writeback_index so that range_cyclic - * mode will write it back later - */ - mapping->writeback_index = index; out_writepages: - if (!no_nrwrite_index_update) - wbc->no_nrwrite_index_update = 0; - wbc->nr_to_write -= nr_to_writebump; + wbc->nr_to_write = to_write - nr_to_writebump; + wbc->range_start = range_start; return ret; } @@ -4194,6 +4175,7 @@ static int ext4_inode_blocks_set(handle_t *handle, struct inode *inode = &(ei->vfs_inode); u64 i_blocks = inode->i_blocks; struct super_block *sb = inode->i_sb; + int err = 0; if (i_blocks <= ~0U) { /* @@ -4203,27 +4185,36 @@ static int ext4_inode_blocks_set(handle_t *handle, raw_inode->i_blocks_lo = cpu_to_le32(i_blocks); raw_inode->i_blocks_high = 0; ei->i_flags &= ~EXT4_HUGE_FILE_FL; - return 0; - } - if (!EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_HUGE_FILE)) - return -EFBIG; - - if (i_blocks <= 0xffffffffffffULL) { + } else if (i_blocks <= 0xffffffffffffULL) { /* * i_blocks can be represented in a 48 bit variable * as multiple of 512 bytes */ + err = ext4_update_rocompat_feature(handle, sb, + EXT4_FEATURE_RO_COMPAT_HUGE_FILE); + if (err) + goto err_out; + /* i_block is stored in the split 48 bit fields */ raw_inode->i_blocks_lo = cpu_to_le32(i_blocks); raw_inode->i_blocks_high = cpu_to_le16(i_blocks >> 32); ei->i_flags &= ~EXT4_HUGE_FILE_FL; } else { + /* + * i_blocks should be represented in a 48 bit variable + * as multiple of file system block size + */ + err = ext4_update_rocompat_feature(handle, sb, + EXT4_FEATURE_RO_COMPAT_HUGE_FILE); + if (err) + goto err_out; ei->i_flags |= EXT4_HUGE_FILE_FL; /* i_block is stored in file system block size */ i_blocks = i_blocks >> (inode->i_blkbits - 9); raw_inode->i_blocks_lo = cpu_to_le32(i_blocks); raw_inode->i_blocks_high = cpu_to_le16(i_blocks >> 32); } - return 0; +err_out: + return err; } /* diff --git a/trunk/fs/ext4/mballoc.c b/trunk/fs/ext4/mballoc.c index dfe17a134052..b580714f0d85 100644 --- a/trunk/fs/ext4/mballoc.c +++ b/trunk/fs/ext4/mballoc.c @@ -2300,7 +2300,6 @@ int ext4_mb_add_groupinfo(struct super_block *sb, ext4_group_t group, } INIT_LIST_HEAD(&meta_group_info[i]->bb_prealloc_list); - meta_group_info[i]->bb_free_root.rb_node = NULL;; #ifdef DOUBLE_CHECK { @@ -2523,6 +2522,9 @@ int ext4_mb_init(struct super_block *sb, int needs_recovery) } spin_lock_init(&sbi->s_md_lock); + INIT_LIST_HEAD(&sbi->s_active_transaction); + INIT_LIST_HEAD(&sbi->s_closed_transaction); + INIT_LIST_HEAD(&sbi->s_committed_transaction); spin_lock_init(&sbi->s_bal_lock); sbi->s_mb_max_to_scan = MB_DEFAULT_MAX_TO_SCAN; @@ -2551,8 +2553,6 @@ int ext4_mb_init(struct super_block *sb, int needs_recovery) ext4_mb_init_per_dev_proc(sb); ext4_mb_history_init(sb); - sbi->s_journal->j_commit_callback = release_blocks_on_commit; - printk(KERN_INFO "EXT4-fs: mballoc enabled\n"); return 0; } @@ -2568,7 +2568,7 @@ static void ext4_mb_cleanup_pa(struct ext4_group_info *grp) pa = list_entry(cur, struct ext4_prealloc_space, pa_group_list); list_del(&pa->pa_group_list); count++; - kmem_cache_free(ext4_pspace_cachep, pa); + kfree(pa); } if (count) mb_debug("mballoc: %u PAs left\n", count); @@ -2582,6 +2582,15 @@ int ext4_mb_release(struct super_block *sb) struct ext4_group_info *grinfo; struct ext4_sb_info *sbi = EXT4_SB(sb); + /* release freed, non-committed blocks */ + spin_lock(&sbi->s_md_lock); + list_splice_init(&sbi->s_closed_transaction, + &sbi->s_committed_transaction); + list_splice_init(&sbi->s_active_transaction, + &sbi->s_committed_transaction); + spin_unlock(&sbi->s_md_lock); + ext4_mb_free_committed_blocks(sb); + if (sbi->s_group_info) { for (i = 0; i < sbi->s_groups_count; i++) { grinfo = ext4_get_group_info(sb, i); @@ -2635,57 +2644,61 @@ int ext4_mb_release(struct super_block *sb) return 0; } -/* - * This function is called by the jbd2 layer once the commit has finished, - * so we know we can free the blocks that were released with that commit. - */ -static void release_blocks_on_commit(journal_t *journal, transaction_t *txn) +static noinline_for_stack void +ext4_mb_free_committed_blocks(struct super_block *sb) { - struct super_block *sb = journal->j_private; + struct ext4_sb_info *sbi = EXT4_SB(sb); + int err; + int i; + int count = 0; + int count2 = 0; + struct ext4_free_metadata *md; struct ext4_buddy e4b; - struct ext4_group_info *db; - int err, count = 0, count2 = 0; - struct ext4_free_data *entry; - ext4_fsblk_t discard_block; - struct list_head *l, *ltmp; - list_for_each_safe(l, ltmp, &txn->t_private_list) { - entry = list_entry(l, struct ext4_free_data, list); + if (list_empty(&sbi->s_committed_transaction)) + return; + + /* there is committed blocks to be freed yet */ + do { + /* get next array of blocks */ + md = NULL; + spin_lock(&sbi->s_md_lock); + if (!list_empty(&sbi->s_committed_transaction)) { + md = list_entry(sbi->s_committed_transaction.next, + struct ext4_free_metadata, list); + list_del(&md->list); + } + spin_unlock(&sbi->s_md_lock); + + if (md == NULL) + break; mb_debug("gonna free %u blocks in group %lu (0x%p):", - entry->count, entry->group, entry); + md->num, md->group, md); - err = ext4_mb_load_buddy(sb, entry->group, &e4b); + err = ext4_mb_load_buddy(sb, md->group, &e4b); /* we expect to find existing buddy because it's pinned */ BUG_ON(err != 0); - db = e4b.bd_info; /* there are blocks to put in buddy to make them really free */ - count += entry->count; + count += md->num; count2++; - ext4_lock_group(sb, entry->group); - /* Take it out of per group rb tree */ - rb_erase(&entry->node, &(db->bb_free_root)); - mb_free_blocks(NULL, &e4b, entry->start_blk, entry->count); - - if (!db->bb_free_root.rb_node) { - /* No more items in the per group rb tree - * balance refcounts from ext4_mb_free_metadata() - */ - page_cache_release(e4b.bd_buddy_page); - page_cache_release(e4b.bd_bitmap_page); + ext4_lock_group(sb, md->group); + for (i = 0; i < md->num; i++) { + mb_debug(" %u", md->blocks[i]); + mb_free_blocks(NULL, &e4b, md->blocks[i], 1); } - ext4_unlock_group(sb, entry->group); - discard_block = (ext4_fsblk_t) entry->group * EXT4_BLOCKS_PER_GROUP(sb) - + entry->start_blk - + le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block); - trace_mark(ext4_discard_blocks, "dev %s blk %llu count %u", sb->s_id, - (unsigned long long) discard_block, entry->count); - sb_issue_discard(sb, discard_block, entry->count); - - kmem_cache_free(ext4_free_ext_cachep, entry); + mb_debug("\n"); + ext4_unlock_group(sb, md->group); + + /* balance refcounts from ext4_mb_free_metadata() */ + page_cache_release(e4b.bd_buddy_page); + page_cache_release(e4b.bd_bitmap_page); + + kfree(md); ext4_mb_release_desc(&e4b); - } + + } while (md); mb_debug("freed %u blocks in %u structures\n", count, count2); } @@ -2699,7 +2712,6 @@ static void release_blocks_on_commit(journal_t *journal, transaction_t *txn) static int ext4_mb_init_per_dev_proc(struct super_block *sb) { -#ifdef CONFIG_PROC_FS mode_t mode = S_IFREG | S_IRUGO | S_IWUSR; struct ext4_sb_info *sbi = EXT4_SB(sb); struct proc_dir_entry *proc; @@ -2723,14 +2735,10 @@ static int ext4_mb_init_per_dev_proc(struct super_block *sb) remove_proc_entry(EXT4_MB_MAX_TO_SCAN_NAME, sbi->s_proc); remove_proc_entry(EXT4_MB_STATS_NAME, sbi->s_proc); return -ENOMEM; -#else - return 0; -#endif } static int ext4_mb_destroy_per_dev_proc(struct super_block *sb) { -#ifdef CONFIG_PROC_FS struct ext4_sb_info *sbi = EXT4_SB(sb); if (sbi->s_proc == NULL) @@ -2742,7 +2750,7 @@ static int ext4_mb_destroy_per_dev_proc(struct super_block *sb) remove_proc_entry(EXT4_MB_MIN_TO_SCAN_NAME, sbi->s_proc); remove_proc_entry(EXT4_MB_MAX_TO_SCAN_NAME, sbi->s_proc); remove_proc_entry(EXT4_MB_STATS_NAME, sbi->s_proc); -#endif + return 0; } @@ -2763,16 +2771,6 @@ int __init init_ext4_mballoc(void) kmem_cache_destroy(ext4_pspace_cachep); return -ENOMEM; } - - ext4_free_ext_cachep = - kmem_cache_create("ext4_free_block_extents", - sizeof(struct ext4_free_data), - 0, SLAB_RECLAIM_ACCOUNT, NULL); - if (ext4_free_ext_cachep == NULL) { - kmem_cache_destroy(ext4_pspace_cachep); - kmem_cache_destroy(ext4_ac_cachep); - return -ENOMEM; - } return 0; } @@ -2781,7 +2779,6 @@ void exit_ext4_mballoc(void) /* XXX: synchronize_rcu(); */ kmem_cache_destroy(ext4_pspace_cachep); kmem_cache_destroy(ext4_ac_cachep); - kmem_cache_destroy(ext4_free_ext_cachep); } @@ -4327,6 +4324,8 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle, goto out1; } + ext4_mb_poll_new_transaction(sb, handle); + *errp = ext4_mb_initialize_context(ac, ar); if (*errp) { ar->len = 0; @@ -4385,20 +4384,35 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle, return block; } - -/* - * We can merge two free data extents only if the physical blocks - * are contiguous, AND the extents were freed by the same transaction, - * AND the blocks are associated with the same group. - */ -static int can_merge(struct ext4_free_data *entry1, - struct ext4_free_data *entry2) +static void ext4_mb_poll_new_transaction(struct super_block *sb, + handle_t *handle) { - if ((entry1->t_tid == entry2->t_tid) && - (entry1->group == entry2->group) && - ((entry1->start_blk + entry1->count) == entry2->start_blk)) - return 1; - return 0; + struct ext4_sb_info *sbi = EXT4_SB(sb); + + if (sbi->s_last_transaction == handle->h_transaction->t_tid) + return; + + /* new transaction! time to close last one and free blocks for + * committed transaction. we know that only transaction can be + * active, so previos transaction can be being logged and we + * know that transaction before previous is known to be already + * logged. this means that now we may free blocks freed in all + * transactions before previous one. hope I'm clear enough ... */ + + spin_lock(&sbi->s_md_lock); + if (sbi->s_last_transaction != handle->h_transaction->t_tid) { + mb_debug("new transaction %lu, old %lu\n", + (unsigned long) handle->h_transaction->t_tid, + (unsigned long) sbi->s_last_transaction); + list_splice_init(&sbi->s_closed_transaction, + &sbi->s_committed_transaction); + list_splice_init(&sbi->s_active_transaction, + &sbi->s_closed_transaction); + sbi->s_last_transaction = handle->h_transaction->t_tid; + } + spin_unlock(&sbi->s_md_lock); + + ext4_mb_free_committed_blocks(sb); } static noinline_for_stack int @@ -4408,80 +4422,57 @@ ext4_mb_free_metadata(handle_t *handle, struct ext4_buddy *e4b, struct ext4_group_info *db = e4b->bd_info; struct super_block *sb = e4b->bd_sb; struct ext4_sb_info *sbi = EXT4_SB(sb); - struct ext4_free_data *entry, *new_entry; - struct rb_node **n = &db->bb_free_root.rb_node, *node; - struct rb_node *parent = NULL, *new_node; - + struct ext4_free_metadata *md; + int i; BUG_ON(e4b->bd_bitmap_page == NULL); BUG_ON(e4b->bd_buddy_page == NULL); - new_entry = kmem_cache_alloc(ext4_free_ext_cachep, GFP_NOFS); - new_entry->start_blk = block; - new_entry->group = group; - new_entry->count = count; - new_entry->t_tid = handle->h_transaction->t_tid; - new_node = &new_entry->node; - ext4_lock_group(sb, group); - if (!*n) { - /* first free block exent. We need to - protect buddy cache from being freed, - * otherwise we'll refresh it from - * on-disk bitmap and lose not-yet-available - * blocks */ - page_cache_get(e4b->bd_buddy_page); - page_cache_get(e4b->bd_bitmap_page); - } - while (*n) { - parent = *n; - entry = rb_entry(parent, struct ext4_free_data, node); - if (block < entry->start_blk) - n = &(*n)->rb_left; - else if (block >= (entry->start_blk + entry->count)) - n = &(*n)->rb_right; - else { - ext4_error(sb, __func__, - "Double free of blocks %d (%d %d)\n", - block, entry->start_blk, entry->count); - return 0; + for (i = 0; i < count; i++) { + md = db->bb_md_cur; + if (md && db->bb_tid != handle->h_transaction->t_tid) { + db->bb_md_cur = NULL; + md = NULL; } - } - rb_link_node(new_node, parent, n); - rb_insert_color(new_node, &db->bb_free_root); - - /* Now try to see the extent can be merged to left and right */ - node = rb_prev(new_node); - if (node) { - entry = rb_entry(node, struct ext4_free_data, node); - if (can_merge(entry, new_entry)) { - new_entry->start_blk = entry->start_blk; - new_entry->count += entry->count; - rb_erase(node, &(db->bb_free_root)); - spin_lock(&sbi->s_md_lock); - list_del(&entry->list); - spin_unlock(&sbi->s_md_lock); - kmem_cache_free(ext4_free_ext_cachep, entry); + if (md == NULL) { + ext4_unlock_group(sb, group); + md = kmalloc(sizeof(*md), GFP_NOFS); + if (md == NULL) + return -ENOMEM; + md->num = 0; + md->group = group; + + ext4_lock_group(sb, group); + if (db->bb_md_cur == NULL) { + spin_lock(&sbi->s_md_lock); + list_add(&md->list, &sbi->s_active_transaction); + spin_unlock(&sbi->s_md_lock); + /* protect buddy cache from being freed, + * otherwise we'll refresh it from + * on-disk bitmap and lose not-yet-available + * blocks */ + page_cache_get(e4b->bd_buddy_page); + page_cache_get(e4b->bd_bitmap_page); + db->bb_md_cur = md; + db->bb_tid = handle->h_transaction->t_tid; + mb_debug("new md 0x%p for group %lu\n", + md, md->group); + } else { + kfree(md); + md = db->bb_md_cur; + } } - } - node = rb_next(new_node); - if (node) { - entry = rb_entry(node, struct ext4_free_data, node); - if (can_merge(new_entry, entry)) { - new_entry->count += entry->count; - rb_erase(node, &(db->bb_free_root)); - spin_lock(&sbi->s_md_lock); - list_del(&entry->list); - spin_unlock(&sbi->s_md_lock); - kmem_cache_free(ext4_free_ext_cachep, entry); + BUG_ON(md->num >= EXT4_BB_MAX_BLOCKS); + md->blocks[md->num] = block + i; + md->num++; + if (md->num == EXT4_BB_MAX_BLOCKS) { + /* no more space, put full container on a sb's list */ + db->bb_md_cur = NULL; } } - /* Add the extent to transaction's private list */ - spin_lock(&sbi->s_md_lock); - list_add(&new_entry->list, &handle->h_transaction->t_private_list); - spin_unlock(&sbi->s_md_lock); ext4_unlock_group(sb, group); return 0; } @@ -4509,6 +4500,8 @@ void ext4_mb_free_blocks(handle_t *handle, struct inode *inode, *freed = 0; + ext4_mb_poll_new_transaction(sb, handle); + sbi = EXT4_SB(sb); es = EXT4_SB(sb)->s_es; if (block < le32_to_cpu(es->s_first_data_block) || diff --git a/trunk/fs/ext4/mballoc.h b/trunk/fs/ext4/mballoc.h index b5dff1fff1e5..b3b4828f8b89 100644 --- a/trunk/fs/ext4/mballoc.h +++ b/trunk/fs/ext4/mballoc.h @@ -18,8 +18,6 @@ #include #include #include -#include -#include #include "ext4_jbd2.h" #include "ext4.h" #include "group.h" @@ -100,29 +98,23 @@ static struct kmem_cache *ext4_pspace_cachep; static struct kmem_cache *ext4_ac_cachep; -static struct kmem_cache *ext4_free_ext_cachep; -struct ext4_free_data { - /* this links the free block information from group_info */ - struct rb_node node; - - /* this links the free block information from ext4_sb_info */ - struct list_head list; +#ifdef EXT4_BB_MAX_BLOCKS +#undef EXT4_BB_MAX_BLOCKS +#endif +#define EXT4_BB_MAX_BLOCKS 30 - /* group which free block extent belongs */ +struct ext4_free_metadata { ext4_group_t group; - - /* free block extent */ - ext4_grpblk_t start_blk; - ext4_grpblk_t count; - - /* transaction which freed this extent */ - tid_t t_tid; + unsigned short num; + ext4_grpblk_t blocks[EXT4_BB_MAX_BLOCKS]; + struct list_head list; }; struct ext4_group_info { unsigned long bb_state; - struct rb_root bb_free_root; + unsigned long bb_tid; + struct ext4_free_metadata *bb_md_cur; unsigned short bb_first_free; unsigned short bb_free; unsigned short bb_fragments; @@ -269,6 +261,8 @@ struct buffer_head *read_block_bitmap(struct super_block *, ext4_group_t); static void ext4_mb_generate_from_pa(struct super_block *sb, void *bitmap, ext4_group_t group); +static void ext4_mb_poll_new_transaction(struct super_block *, handle_t *); +static void ext4_mb_free_committed_blocks(struct super_block *); static void ext4_mb_return_to_preallocation(struct inode *inode, struct ext4_buddy *e4b, sector_t block, int count); @@ -276,7 +270,6 @@ static void ext4_mb_put_pa(struct ext4_allocation_context *, struct super_block *, struct ext4_prealloc_space *pa); static int ext4_mb_init_per_dev_proc(struct super_block *sb); static int ext4_mb_destroy_per_dev_proc(struct super_block *sb); -static void release_blocks_on_commit(journal_t *journal, transaction_t *txn); static inline void ext4_lock_group(struct super_block *sb, ext4_group_t group) diff --git a/trunk/fs/ext4/super.c b/trunk/fs/ext4/super.c index 9b2b2bc4ec17..dea8f13c2fd9 100644 --- a/trunk/fs/ext4/super.c +++ b/trunk/fs/ext4/super.c @@ -374,6 +374,66 @@ void ext4_update_dynamic_rev(struct super_block *sb) */ } +int ext4_update_compat_feature(handle_t *handle, + struct super_block *sb, __u32 compat) +{ + int err = 0; + if (!EXT4_HAS_COMPAT_FEATURE(sb, compat)) { + err = ext4_journal_get_write_access(handle, + EXT4_SB(sb)->s_sbh); + if (err) + return err; + EXT4_SET_COMPAT_FEATURE(sb, compat); + sb->s_dirt = 1; + handle->h_sync = 1; + BUFFER_TRACE(EXT4_SB(sb)->s_sbh, + "call ext4_journal_dirty_met adata"); + err = ext4_journal_dirty_metadata(handle, + EXT4_SB(sb)->s_sbh); + } + return err; +} + +int ext4_update_rocompat_feature(handle_t *handle, + struct super_block *sb, __u32 rocompat) +{ + int err = 0; + if (!EXT4_HAS_RO_COMPAT_FEATURE(sb, rocompat)) { + err = ext4_journal_get_write_access(handle, + EXT4_SB(sb)->s_sbh); + if (err) + return err; + EXT4_SET_RO_COMPAT_FEATURE(sb, rocompat); + sb->s_dirt = 1; + handle->h_sync = 1; + BUFFER_TRACE(EXT4_SB(sb)->s_sbh, + "call ext4_journal_dirty_met adata"); + err = ext4_journal_dirty_metadata(handle, + EXT4_SB(sb)->s_sbh); + } + return err; +} + +int ext4_update_incompat_feature(handle_t *handle, + struct super_block *sb, __u32 incompat) +{ + int err = 0; + if (!EXT4_HAS_INCOMPAT_FEATURE(sb, incompat)) { + err = ext4_journal_get_write_access(handle, + EXT4_SB(sb)->s_sbh); + if (err) + return err; + EXT4_SET_INCOMPAT_FEATURE(sb, incompat); + sb->s_dirt = 1; + handle->h_sync = 1; + BUFFER_TRACE(EXT4_SB(sb)->s_sbh, + "call ext4_journal_dirty_met adata"); + err = ext4_journal_dirty_metadata(handle, + EXT4_SB(sb)->s_sbh); + } + return err; +} + /* * Open the external journal device */ @@ -844,7 +904,7 @@ static const struct export_operations ext4_export_ops = { enum { Opt_bsd_df, Opt_minix_df, Opt_grpid, Opt_nogrpid, Opt_resgid, Opt_resuid, Opt_sb, Opt_err_cont, Opt_err_panic, Opt_err_ro, - Opt_nouid32, Opt_debug, Opt_oldalloc, Opt_orlov, + Opt_nouid32, Opt_nocheck, Opt_debug, Opt_oldalloc, Opt_orlov, Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl, Opt_reservation, Opt_noreservation, Opt_noload, Opt_nobh, Opt_bh, Opt_commit, Opt_journal_update, Opt_journal_inum, Opt_journal_dev, @@ -855,7 +915,7 @@ enum { Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota, Opt_ignore, Opt_barrier, Opt_err, Opt_resize, Opt_usrquota, Opt_grpquota, Opt_extents, Opt_noextents, Opt_i_version, - Opt_stripe, Opt_delalloc, Opt_nodelalloc, + Opt_mballoc, Opt_nomballoc, Opt_stripe, Opt_delalloc, Opt_nodelalloc, Opt_inode_readahead_blks }; @@ -873,6 +933,8 @@ static const match_table_t tokens = { {Opt_err_panic, "errors=panic"}, {Opt_err_ro, "errors=remount-ro"}, {Opt_nouid32, "nouid32"}, + {Opt_nocheck, "nocheck"}, + {Opt_nocheck, "check=none"}, {Opt_debug, "debug"}, {Opt_oldalloc, "oldalloc"}, {Opt_orlov, "orlov"}, @@ -911,6 +973,8 @@ static const match_table_t tokens = { {Opt_extents, "extents"}, {Opt_noextents, "noextents"}, {Opt_i_version, "i_version"}, + {Opt_mballoc, "mballoc"}, + {Opt_nomballoc, "nomballoc"}, {Opt_stripe, "stripe=%u"}, {Opt_resize, "resize"}, {Opt_delalloc, "delalloc"}, @@ -1009,6 +1073,9 @@ static int parse_options(char *options, struct super_block *sb, case Opt_nouid32: set_opt(sbi->s_mount_opt, NO_UID32); break; + case Opt_nocheck: + clear_opt(sbi->s_mount_opt, CHECK); + break; case Opt_debug: set_opt(sbi->s_mount_opt, DEBUG); break; @@ -1551,14 +1618,14 @@ static int ext4_check_descriptors(struct super_block *sb) if (block_bitmap < first_block || block_bitmap > last_block) { printk(KERN_ERR "EXT4-fs: ext4_check_descriptors: " "Block bitmap for group %lu not in group " - "(block %llu)!\n", i, block_bitmap); + "(block %llu)!", i, block_bitmap); return 0; } inode_bitmap = ext4_inode_bitmap(sb, gdp); if (inode_bitmap < first_block || inode_bitmap > last_block) { printk(KERN_ERR "EXT4-fs: ext4_check_descriptors: " "Inode bitmap for group %lu not in group " - "(block %llu)!\n", i, inode_bitmap); + "(block %llu)!", i, inode_bitmap); return 0; } inode_table = ext4_inode_table(sb, gdp); @@ -1566,7 +1633,7 @@ static int ext4_check_descriptors(struct super_block *sb) inode_table + sbi->s_itb_per_group - 1 > last_block) { printk(KERN_ERR "EXT4-fs: ext4_check_descriptors: " "Inode table for group %lu not in group " - "(block %llu)!\n", i, inode_table); + "(block %llu)!", i, inode_table); return 0; } spin_lock(sb_bgl_lock(sbi, i)); @@ -1711,13 +1778,13 @@ static void ext4_orphan_cleanup(struct super_block *sb, * * Note, this does *not* consider any metadata overhead for vfs i_blocks. */ -static loff_t ext4_max_size(int blkbits, int has_huge_files) +static loff_t ext4_max_size(int blkbits) { loff_t res; loff_t upper_limit = MAX_LFS_FILESIZE; /* small i_blocks in vfs inode? */ - if (!has_huge_files || sizeof(blkcnt_t) < sizeof(u64)) { + if (sizeof(blkcnt_t) < sizeof(u64)) { /* * CONFIG_LSF is not enabled implies the inode * i_block represent total blocks in 512 bytes @@ -1747,7 +1814,7 @@ static loff_t ext4_max_size(int blkbits, int has_huge_files) * block limit, and also a limit of (2^48 - 1) 512-byte sectors in i_blocks. * We need to be 1 filesystem block less than the 2^48 sector limit. */ -static loff_t ext4_max_bitmap_size(int bits, int has_huge_files) +static loff_t ext4_max_bitmap_size(int bits) { loff_t res = EXT4_NDIR_BLOCKS; int meta_blocks; @@ -1760,11 +1827,11 @@ static loff_t ext4_max_bitmap_size(int bits, int has_huge_files) * total number of 512 bytes blocks of the file */ - if (!has_huge_files || sizeof(blkcnt_t) < sizeof(u64)) { + if (sizeof(blkcnt_t) < sizeof(u64)) { /* - * !has_huge_files or CONFIG_LSF is not enabled - * implies the inode i_block represent total blocks in - * 512 bytes 32 == size of vfs inode i_blocks * 8 + * CONFIG_LSF is not enabled implies the inode + * i_block represent total blocks in 512 bytes + * 32 == size of vfs inode i_blocks * 8 */ upper_limit = (1LL << 32) - 1; @@ -1873,7 +1940,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) int blocksize; int db_count; int i; - int needs_recovery, has_huge_files; + int needs_recovery; __le32 features; __u64 blocks_count; int err; @@ -2014,9 +2081,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) sb->s_id, le32_to_cpu(features)); goto failed_mount; } - has_huge_files = EXT4_HAS_RO_COMPAT_FEATURE(sb, - EXT4_FEATURE_RO_COMPAT_HUGE_FILE); - if (has_huge_files) { + if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_HUGE_FILE)) { /* * Large file size enabled file system can only be * mount if kernel is build with CONFIG_LSF @@ -2066,9 +2131,8 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) } } - sbi->s_bitmap_maxbytes = ext4_max_bitmap_size(sb->s_blocksize_bits, - has_huge_files); - sb->s_maxbytes = ext4_max_size(sb->s_blocksize_bits, has_huge_files); + sbi->s_bitmap_maxbytes = ext4_max_bitmap_size(sb->s_blocksize_bits); + sb->s_maxbytes = ext4_max_size(sb->s_blocksize_bits); if (le32_to_cpu(es->s_rev_level) == EXT4_GOOD_OLD_REV) { sbi->s_inode_size = EXT4_GOOD_OLD_INODE_SIZE; @@ -2392,21 +2456,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) "available.\n"); } - if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA) { - printk(KERN_WARNING "EXT4-fs: Ignoring delalloc option - " - "requested data journaling mode\n"); - clear_opt(sbi->s_mount_opt, DELALLOC); - } else if (test_opt(sb, DELALLOC)) - printk(KERN_INFO "EXT4-fs: delayed allocation enabled\n"); - - ext4_ext_init(sb); - err = ext4_mb_init(sb, needs_recovery); - if (err) { - printk(KERN_ERR "EXT4-fs: failed to initalize mballoc (%d)\n", - err); - goto failed_mount4; - } - /* * akpm: core read_super() calls in here with the superblock locked. * That deadlocks, because orphan cleanup needs to lock the superblock @@ -2426,6 +2475,21 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_ORDERED_DATA ? "ordered": "writeback"); + if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA) { + printk(KERN_WARNING "EXT4-fs: Ignoring delalloc option - " + "requested data journaling mode\n"); + clear_opt(sbi->s_mount_opt, DELALLOC); + } else if (test_opt(sb, DELALLOC)) + printk(KERN_INFO "EXT4-fs: delayed allocation enabled\n"); + + ext4_ext_init(sb); + err = ext4_mb_init(sb, needs_recovery); + if (err) { + printk(KERN_ERR "EXT4-fs: failed to initalize mballoc (%d)\n", + err); + goto failed_mount4; + } + lock_kernel(); return 0; diff --git a/trunk/fs/jbd2/commit.c b/trunk/fs/jbd2/commit.c index 8b119e16aa36..0abe02c4242a 100644 --- a/trunk/fs/jbd2/commit.c +++ b/trunk/fs/jbd2/commit.c @@ -995,9 +995,6 @@ void jbd2_journal_commit_transaction(journal_t *journal) } spin_unlock(&journal->j_list_lock); - if (journal->j_commit_callback) - journal->j_commit_callback(journal, commit_transaction); - trace_mark(jbd2_end_commit, "dev %s transaction %d head %d", journal->j_devname, commit_transaction->t_tid, journal->j_tail_sequence); diff --git a/trunk/fs/jbd2/transaction.c b/trunk/fs/jbd2/transaction.c index 39b7805a599a..e5d540588fa9 100644 --- a/trunk/fs/jbd2/transaction.c +++ b/trunk/fs/jbd2/transaction.c @@ -52,7 +52,6 @@ jbd2_get_transaction(journal_t *journal, transaction_t *transaction) transaction->t_expires = jiffies + journal->j_commit_interval; spin_lock_init(&transaction->t_handle_lock); INIT_LIST_HEAD(&transaction->t_inode_list); - INIT_LIST_HEAD(&transaction->t_private_list); /* Set up the commit timer for the new transaction. */ journal->j_commit_timer.expires = round_jiffies(transaction->t_expires); diff --git a/trunk/include/drm/drm.h b/trunk/include/drm/drm.h index f46ba4b57da4..38d3c6b8276a 100644 --- a/trunk/include/drm/drm.h +++ b/trunk/include/drm/drm.h @@ -36,6 +36,7 @@ #ifndef _DRM_H_ #define _DRM_H_ +#if defined(__linux__) #if defined(__KERNEL__) #endif #include /* For _IO* macros */ @@ -45,6 +46,22 @@ #define DRM_IOC_WRITE _IOC_WRITE #define DRM_IOC_READWRITE _IOC_READ|_IOC_WRITE #define DRM_IOC(dir, group, nr, size) _IOC(dir, group, nr, size) +#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) +#if defined(__FreeBSD__) && defined(IN_MODULE) +/* Prevent name collision when including sys/ioccom.h */ +#undef ioctl +#include +#define ioctl(a,b,c) xf86ioctl(a,b,c) +#else +#include +#endif /* __FreeBSD__ && xf86ioctl */ +#define DRM_IOCTL_NR(n) ((n) & 0xff) +#define DRM_IOC_VOID IOC_VOID +#define DRM_IOC_READ IOC_OUT +#define DRM_IOC_WRITE IOC_IN +#define DRM_IOC_READWRITE IOC_INOUT +#define DRM_IOC(dir, group, nr, size) _IOC(dir, group, nr, size) +#endif #define DRM_MAJOR 226 #define DRM_MAX_MINOR 15 @@ -454,7 +471,6 @@ struct drm_irq_busid { enum drm_vblank_seq_type { _DRM_VBLANK_ABSOLUTE = 0x0, /**< Wait for specific vblank sequence number */ _DRM_VBLANK_RELATIVE = 0x1, /**< Wait for given number of vblanks */ - _DRM_VBLANK_FLIP = 0x8000000, /**< Scheduled buffer swap should flip */ _DRM_VBLANK_NEXTONMISS = 0x10000000, /**< If missed, wait for next vblank */ _DRM_VBLANK_SECONDARY = 0x20000000, /**< Secondary display controller */ _DRM_VBLANK_SIGNAL = 0x40000000 /**< Send signal instead of blocking */ @@ -487,19 +503,6 @@ union drm_wait_vblank { struct drm_wait_vblank_reply reply; }; -#define _DRM_PRE_MODESET 1 -#define _DRM_POST_MODESET 2 - -/** - * DRM_IOCTL_MODESET_CTL ioctl argument type - * - * \sa drmModesetCtl(). - */ -struct drm_modeset_ctl { - uint32_t crtc; - uint32_t cmd; -}; - /** * DRM_IOCTL_AGP_ENABLE ioctl argument type. * @@ -570,34 +573,6 @@ struct drm_set_version { int drm_dd_minor; }; -/** DRM_IOCTL_GEM_CLOSE ioctl argument type */ -struct drm_gem_close { - /** Handle of the object to be closed. */ - uint32_t handle; - uint32_t pad; -}; - -/** DRM_IOCTL_GEM_FLINK ioctl argument type */ -struct drm_gem_flink { - /** Handle for the object being named */ - uint32_t handle; - - /** Returned global name */ - uint32_t name; -}; - -/** DRM_IOCTL_GEM_OPEN ioctl argument type */ -struct drm_gem_open { - /** Name of object being opened */ - uint32_t name; - - /** Returned handle for the object */ - uint32_t handle; - - /** Returned size of the object */ - uint64_t size; -}; - #define DRM_IOCTL_BASE 'd' #define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr) #define DRM_IOR(nr,type) _IOR(DRM_IOCTL_BASE,nr,type) @@ -612,10 +587,6 @@ struct drm_gem_open { #define DRM_IOCTL_GET_CLIENT DRM_IOWR(0x05, struct drm_client) #define DRM_IOCTL_GET_STATS DRM_IOR( 0x06, struct drm_stats) #define DRM_IOCTL_SET_VERSION DRM_IOWR(0x07, struct drm_set_version) -#define DRM_IOCTL_MODESET_CTL DRM_IOW(0x08, struct drm_modeset_ctl) -#define DRM_IOCTL_GEM_CLOSE DRM_IOW (0x09, struct drm_gem_close) -#define DRM_IOCTL_GEM_FLINK DRM_IOWR(0x0a, struct drm_gem_flink) -#define DRM_IOCTL_GEM_OPEN DRM_IOWR(0x0b, struct drm_gem_open) #define DRM_IOCTL_SET_UNIQUE DRM_IOW( 0x10, struct drm_unique) #define DRM_IOCTL_AUTH_MAGIC DRM_IOW( 0x11, struct drm_auth) diff --git a/trunk/include/drm/drmP.h b/trunk/include/drm/drmP.h index 59c796b46ee7..1c1b13e29223 100644 --- a/trunk/include/drm/drmP.h +++ b/trunk/include/drm/drmP.h @@ -104,7 +104,6 @@ struct drm_device; #define DRIVER_DMA_QUEUE 0x200 #define DRIVER_FB_DMA 0x400 #define DRIVER_IRQ_VBL2 0x800 -#define DRIVER_GEM 0x1000 /***********************************************************************/ /** \name Begin the DRM... */ @@ -388,10 +387,6 @@ struct drm_file { struct drm_minor *minor; int remove_auth_on_close; unsigned long lock_count; - /** Mapping of mm object handles to object pointers. */ - struct idr object_idr; - /** Lock for synchronization of access to object_idr. */ - spinlock_t table_lock; struct file *filp; void *driver_priv; }; @@ -562,56 +557,6 @@ struct drm_ati_pcigart_info { int table_size; }; -/** - * This structure defines the drm_mm memory object, which will be used by the - * DRM for its buffer objects. - */ -struct drm_gem_object { - /** Reference count of this object */ - struct kref refcount; - - /** Handle count of this object. Each handle also holds a reference */ - struct kref handlecount; - - /** Related drm device */ - struct drm_device *dev; - - /** File representing the shmem storage */ - struct file *filp; - - /** - * Size of the object, in bytes. Immutable over the object's - * lifetime. - */ - size_t size; - - /** - * Global name for this object, starts at 1. 0 means unnamed. - * Access is covered by the object_name_lock in the related drm_device - */ - int name; - - /** - * Memory domains. These monitor which caches contain read/write data - * related to the object. When transitioning from one set of domains - * to another, the driver is called to ensure that caches are suitably - * flushed and invalidated - */ - uint32_t read_domains; - uint32_t write_domain; - - /** - * While validating an exec operation, the - * new read/write domain values are computed here. - * They will be transferred to the above values - * at the point that any cache flushing occurs - */ - uint32_t pending_read_domains; - uint32_t pending_write_domain; - - void *driver_private; -}; - /** * DRM driver structure. This structure represent the common code for * a family of cards. There will one drm_device for each card present @@ -635,53 +580,10 @@ struct drm_driver { int (*kernel_context_switch) (struct drm_device *dev, int old, int new); void (*kernel_context_switch_unlock) (struct drm_device *dev); + int (*vblank_wait) (struct drm_device *dev, unsigned int *sequence); + int (*vblank_wait2) (struct drm_device *dev, unsigned int *sequence); int (*dri_library_name) (struct drm_device *dev, char *buf); - /** - * get_vblank_counter - get raw hardware vblank counter - * @dev: DRM device - * @crtc: counter to fetch - * - * Driver callback for fetching a raw hardware vblank counter - * for @crtc. If a device doesn't have a hardware counter, the - * driver can simply return the value of drm_vblank_count and - * make the enable_vblank() and disable_vblank() hooks into no-ops, - * leaving interrupts enabled at all times. - * - * Wraparound handling and loss of events due to modesetting is dealt - * with in the DRM core code. - * - * RETURNS - * Raw vblank counter value. - */ - u32 (*get_vblank_counter) (struct drm_device *dev, int crtc); - - /** - * enable_vblank - enable vblank interrupt events - * @dev: DRM device - * @crtc: which irq to enable - * - * Enable vblank interrupts for @crtc. If the device doesn't have - * a hardware vblank counter, this routine should be a no-op, since - * interrupts will have to stay on to keep the count accurate. - * - * RETURNS - * Zero on success, appropriate errno if the given @crtc's vblank - * interrupt cannot be enabled. - */ - int (*enable_vblank) (struct drm_device *dev, int crtc); - - /** - * disable_vblank - disable vblank interrupt events - * @dev: DRM device - * @crtc: which irq to enable - * - * Disable vblank interrupts for @crtc. If the device doesn't have - * a hardware vblank counter, this routine should be a no-op, since - * interrupts will have to stay on to keep the count accurate. - */ - void (*disable_vblank) (struct drm_device *dev, int crtc); - /** * Called by \c drm_device_is_agp. Typically used to determine if a * card is really attached to AGP or not. @@ -699,7 +601,7 @@ struct drm_driver { irqreturn_t(*irq_handler) (DRM_IRQ_ARGS); void (*irq_preinstall) (struct drm_device *dev); - int (*irq_postinstall) (struct drm_device *dev); + void (*irq_postinstall) (struct drm_device *dev); void (*irq_uninstall) (struct drm_device *dev); void (*reclaim_buffers) (struct drm_device *dev, struct drm_file * file_priv); @@ -712,18 +614,6 @@ struct drm_driver { void (*set_version) (struct drm_device *dev, struct drm_set_version *sv); - int (*proc_init)(struct drm_minor *minor); - void (*proc_cleanup)(struct drm_minor *minor); - - /** - * Driver-specific constructor for drm_gem_objects, to set up - * obj->driver_private. - * - * Returns 0 on success. - */ - int (*gem_init_object) (struct drm_gem_object *obj); - void (*gem_free_object) (struct drm_gem_object *obj); - int major; int minor; int patchlevel; @@ -824,6 +714,7 @@ struct drm_device { /** \name Context support */ /*@{ */ + int irq; /**< Interrupt used by board */ int irq_enabled; /**< True if irq handler is enabled */ __volatile__ long context_flag; /**< Context swapping flag */ __volatile__ long interrupt_flag; /**< Interruption handler flag */ @@ -839,28 +730,13 @@ struct drm_device { /** \name VBLANK IRQ support */ /*@{ */ - /* - * At load time, disabling the vblank interrupt won't be allowed since - * old clients may not call the modeset ioctl and therefore misbehave. - * Once the modeset ioctl *has* been called though, we can safely - * disable them when unused. - */ - int vblank_disable_allowed; - - wait_queue_head_t *vbl_queue; /**< VBLANK wait queue */ - atomic_t *_vblank_count; /**< number of VBLANK interrupts (driver must alloc the right number of counters) */ + wait_queue_head_t vbl_queue; /**< VBLANK wait queue */ + atomic_t vbl_received; + atomic_t vbl_received2; /**< number of secondary VBLANK interrupts */ spinlock_t vbl_lock; - struct list_head *vbl_sigs; /**< signal list to send on VBLANK */ - atomic_t vbl_signal_pending; /* number of signals pending on all crtcs*/ - atomic_t *vblank_refcount; /* number of users of vblank interruptsper crtc */ - u32 *last_vblank; /* protected by dev->vbl_lock, used */ - /* for wraparound handling */ - int *vblank_enabled; /* so we don't call enable more than - once per disable */ - int *vblank_inmodeset; /* Display driver is setting mode */ - struct timer_list vblank_disable_timer; - - u32 max_vblank_count; /**< size of vblank counter register */ + struct list_head vbl_sigs; /**< signal list to send on VBLANK */ + struct list_head vbl_sigs2; /**< signals to send on secondary VBLANK */ + unsigned int vbl_pending; spinlock_t tasklet_lock; /**< For drm_locked_tasklet */ void (*locked_tasklet_func)(struct drm_device *dev); @@ -881,7 +757,6 @@ struct drm_device { struct pci_controller *hose; #endif struct drm_sg_mem *sg; /**< Scatter gather memory */ - int num_crtcs; /**< Number of CRTCs on this device */ void *dev_private; /**< device private data */ struct drm_sigdata sigdata; /**< For block_all_signals */ sigset_t sigmask; @@ -896,29 +771,8 @@ struct drm_device { spinlock_t drw_lock; struct idr drw_idr; /*@} */ - - /** \name GEM information */ - /*@{ */ - spinlock_t object_name_lock; - struct idr object_name_idr; - atomic_t object_count; - atomic_t object_memory; - atomic_t pin_count; - atomic_t pin_memory; - atomic_t gtt_count; - atomic_t gtt_memory; - uint32_t gtt_total; - uint32_t invalidate_domains; /* domains pending invalidation */ - uint32_t flush_domains; /* domains pending flush */ - /*@} */ - }; -static inline int drm_dev_to_irq(struct drm_device *dev) -{ - return dev->pdev->irq; -} - static __inline__ int drm_core_check_feature(struct drm_device *dev, int feature) { @@ -1013,11 +867,6 @@ extern void *drm_realloc(void *oldpt, size_t oldsize, size_t size, int area); extern DRM_AGP_MEM *drm_alloc_agp(struct drm_device *dev, int pages, u32 type); extern int drm_free_agp(DRM_AGP_MEM * handle, int pages); extern int drm_bind_agp(DRM_AGP_MEM * handle, unsigned int start); -extern DRM_AGP_MEM *drm_agp_bind_pages(struct drm_device *dev, - struct page **pages, - unsigned long num_pages, - uint32_t gtt_offset, - uint32_t type); extern int drm_unbind_agp(DRM_AGP_MEM * handle); /* Misc. IOCTL support (drm_ioctl.h) */ @@ -1080,9 +929,6 @@ extern int drm_getmagic(struct drm_device *dev, void *data, extern int drm_authmagic(struct drm_device *dev, void *data, struct drm_file *file_priv); -/* Cache management (drm_cache.c) */ -void drm_clflush_pages(struct page *pages[], unsigned long num_pages); - /* Locking IOCTL support (drm_lock.h) */ extern int drm_lock(struct drm_device *dev, void *data, struct drm_file *file_priv); @@ -1139,25 +985,15 @@ extern void drm_core_reclaim_buffers(struct drm_device *dev, extern int drm_control(struct drm_device *dev, void *data, struct drm_file *file_priv); extern irqreturn_t drm_irq_handler(DRM_IRQ_ARGS); -extern int drm_irq_install(struct drm_device *dev); extern int drm_irq_uninstall(struct drm_device *dev); extern void drm_driver_irq_preinstall(struct drm_device *dev); extern void drm_driver_irq_postinstall(struct drm_device *dev); extern void drm_driver_irq_uninstall(struct drm_device *dev); -extern int drm_vblank_init(struct drm_device *dev, int num_crtcs); extern int drm_wait_vblank(struct drm_device *dev, void *data, - struct drm_file *filp); -extern int drm_vblank_wait(struct drm_device *dev, unsigned int *vbl_seq); -extern void drm_locked_tasklet(struct drm_device *dev, - void(*func)(struct drm_device *)); -extern u32 drm_vblank_count(struct drm_device *dev, int crtc); -extern void drm_handle_vblank(struct drm_device *dev, int crtc); -extern int drm_vblank_get(struct drm_device *dev, int crtc); -extern void drm_vblank_put(struct drm_device *dev, int crtc); -/* Modesetting support */ -extern int drm_modeset_ctl(struct drm_device *dev, void *data, struct drm_file *file_priv); +extern int drm_vblank_wait(struct drm_device *dev, unsigned int *vbl_seq); +extern void drm_vbl_send_signals(struct drm_device *dev); extern void drm_locked_tasklet(struct drm_device *dev, void(*func)(struct drm_device*)); /* AGP/GART support (drm_agpsupport.h) */ @@ -1190,7 +1026,6 @@ extern DRM_AGP_MEM *drm_agp_allocate_memory(struct agp_bridge_data *bridge, size extern int drm_agp_free_memory(DRM_AGP_MEM * handle); extern int drm_agp_bind_memory(DRM_AGP_MEM * handle, off_t start); extern int drm_agp_unbind_memory(DRM_AGP_MEM * handle); -extern void drm_agp_chipset_flush(struct drm_device *dev); /* Stub support (drm_stub.h) */ extern int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, @@ -1253,66 +1088,6 @@ extern unsigned long drm_mm_tail_space(struct drm_mm *mm); extern int drm_mm_remove_space_from_tail(struct drm_mm *mm, unsigned long size); extern int drm_mm_add_space_to_tail(struct drm_mm *mm, unsigned long size); -/* Graphics Execution Manager library functions (drm_gem.c) */ -int drm_gem_init(struct drm_device *dev); -void drm_gem_object_free(struct kref *kref); -struct drm_gem_object *drm_gem_object_alloc(struct drm_device *dev, - size_t size); -void drm_gem_object_handle_free(struct kref *kref); - -static inline void -drm_gem_object_reference(struct drm_gem_object *obj) -{ - kref_get(&obj->refcount); -} - -static inline void -drm_gem_object_unreference(struct drm_gem_object *obj) -{ - if (obj == NULL) - return; - - kref_put(&obj->refcount, drm_gem_object_free); -} - -int drm_gem_handle_create(struct drm_file *file_priv, - struct drm_gem_object *obj, - int *handlep); - -static inline void -drm_gem_object_handle_reference(struct drm_gem_object *obj) -{ - drm_gem_object_reference(obj); - kref_get(&obj->handlecount); -} - -static inline void -drm_gem_object_handle_unreference(struct drm_gem_object *obj) -{ - if (obj == NULL) - return; - - /* - * Must bump handle count first as this may be the last - * ref, in which case the object would disappear before we - * checked for a name - */ - kref_put(&obj->handlecount, drm_gem_object_handle_free); - drm_gem_object_unreference(obj); -} - -struct drm_gem_object *drm_gem_object_lookup(struct drm_device *dev, - struct drm_file *filp, - int handle); -int drm_gem_close_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int drm_gem_flink_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int drm_gem_open_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -void drm_gem_open(struct drm_device *dev, struct drm_file *file_private); -void drm_gem_release(struct drm_device *dev, struct drm_file *file_private); - extern void drm_core_ioremap(struct drm_map *map, struct drm_device *dev); extern void drm_core_ioremap_wc(struct drm_map *map, struct drm_device *dev); extern void drm_core_ioremapfree(struct drm_map *map, struct drm_device *dev); diff --git a/trunk/include/drm/drm_pciids.h b/trunk/include/drm/drm_pciids.h index da04109741e8..135bd19499fc 100644 --- a/trunk/include/drm/drm_pciids.h +++ b/trunk/include/drm/drm_pciids.h @@ -84,18 +84,18 @@ {0x1002, 0x5462, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \ {0x1002, 0x5464, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \ {0x1002, 0x5657, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5548, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5549, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x554A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x554B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x554C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x554D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x554E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x554F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5550, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5551, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5552, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5554, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x5548, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x5549, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x554A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x554B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x554C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x554D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x554E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x554F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x5550, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x5551, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x5552, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x5554, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ {0x1002, 0x564A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ {0x1002, 0x564B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ {0x1002, 0x564F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ @@ -113,10 +113,8 @@ {0x1002, 0x5964, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ {0x1002, 0x5965, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ {0x1002, 0x5969, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \ - {0x1002, 0x5a41, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_IGPGART}, \ - {0x1002, 0x5a42, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \ - {0x1002, 0x5a61, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_IGPGART}, \ - {0x1002, 0x5a62, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \ + {0x1002, 0x5a61, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS480|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \ + {0x1002, 0x5a62, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS480|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \ {0x1002, 0x5b60, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \ {0x1002, 0x5b62, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \ {0x1002, 0x5b63, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \ @@ -124,16 +122,16 @@ {0x1002, 0x5b65, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \ {0x1002, 0x5c61, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|RADEON_IS_MOBILITY}, \ {0x1002, 0x5c63, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|RADEON_IS_MOBILITY}, \ - {0x1002, 0x5d48, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5d49, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5d4a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5d4c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5d4d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5d4e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5d4f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5d50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5d52, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5d57, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x5d48, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x5d49, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x5d4a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x5d4c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x5d4d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x5d4e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x5d4f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x5d50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x5d52, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x5d57, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ {0x1002, 0x5e48, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_NEW_MEMMAP}, \ {0x1002, 0x5e4a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_NEW_MEMMAP}, \ {0x1002, 0x5e4b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_NEW_MEMMAP}, \ @@ -239,10 +237,6 @@ {0x1002, 0x7835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ {0x1002, 0x791e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS690|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART}, \ {0x1002, 0x791f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS690|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART}, \ - {0x1002, 0x796c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS740|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART}, \ - {0x1002, 0x796d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS740|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART}, \ - {0x1002, 0x796e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS740|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART}, \ - {0x1002, 0x796f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS740|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART}, \ {0, 0, 0} #define r128_PCI_IDS \ diff --git a/trunk/include/drm/i915_drm.h b/trunk/include/drm/i915_drm.h index eb4b35031a55..05c66cf03a9e 100644 --- a/trunk/include/drm/i915_drm.h +++ b/trunk/include/drm/i915_drm.h @@ -143,22 +143,6 @@ typedef struct _drm_i915_sarea { #define DRM_I915_GET_VBLANK_PIPE 0x0e #define DRM_I915_VBLANK_SWAP 0x0f #define DRM_I915_HWS_ADDR 0x11 -#define DRM_I915_GEM_INIT 0x13 -#define DRM_I915_GEM_EXECBUFFER 0x14 -#define DRM_I915_GEM_PIN 0x15 -#define DRM_I915_GEM_UNPIN 0x16 -#define DRM_I915_GEM_BUSY 0x17 -#define DRM_I915_GEM_THROTTLE 0x18 -#define DRM_I915_GEM_ENTERVT 0x19 -#define DRM_I915_GEM_LEAVEVT 0x1a -#define DRM_I915_GEM_CREATE 0x1b -#define DRM_I915_GEM_PREAD 0x1c -#define DRM_I915_GEM_PWRITE 0x1d -#define DRM_I915_GEM_MMAP 0x1e -#define DRM_I915_GEM_SET_DOMAIN 0x1f -#define DRM_I915_GEM_SW_FINISH 0x20 -#define DRM_I915_GEM_SET_TILING 0x21 -#define DRM_I915_GEM_GET_TILING 0x22 #define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t) #define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH) @@ -176,20 +160,6 @@ typedef struct _drm_i915_sarea { #define DRM_IOCTL_I915_SET_VBLANK_PIPE DRM_IOW( DRM_COMMAND_BASE + DRM_I915_SET_VBLANK_PIPE, drm_i915_vblank_pipe_t) #define DRM_IOCTL_I915_GET_VBLANK_PIPE DRM_IOR( DRM_COMMAND_BASE + DRM_I915_GET_VBLANK_PIPE, drm_i915_vblank_pipe_t) #define DRM_IOCTL_I915_VBLANK_SWAP DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_VBLANK_SWAP, drm_i915_vblank_swap_t) -#define DRM_IOCTL_I915_GEM_PIN DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_PIN, struct drm_i915_gem_pin) -#define DRM_IOCTL_I915_GEM_UNPIN DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_UNPIN, struct drm_i915_gem_unpin) -#define DRM_IOCTL_I915_GEM_BUSY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_BUSY, struct drm_i915_gem_busy) -#define DRM_IOCTL_I915_GEM_THROTTLE DRM_IO ( DRM_COMMAND_BASE + DRM_I915_GEM_THROTTLE) -#define DRM_IOCTL_I915_GEM_ENTERVT DRM_IO(DRM_COMMAND_BASE + DRM_I915_GEM_ENTERVT) -#define DRM_IOCTL_I915_GEM_LEAVEVT DRM_IO(DRM_COMMAND_BASE + DRM_I915_GEM_LEAVEVT) -#define DRM_IOCTL_I915_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_CREATE, struct drm_i915_gem_create) -#define DRM_IOCTL_I915_GEM_PREAD DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_PREAD, struct drm_i915_gem_pread) -#define DRM_IOCTL_I915_GEM_PWRITE DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_PWRITE, struct drm_i915_gem_pwrite) -#define DRM_IOCTL_I915_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MMAP, struct drm_i915_gem_mmap) -#define DRM_IOCTL_I915_GEM_SET_DOMAIN DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_SET_DOMAIN, struct drm_i915_gem_set_domain) -#define DRM_IOCTL_I915_GEM_SW_FINISH DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_SW_FINISH, struct drm_i915_gem_sw_finish) -#define DRM_IOCTL_I915_GEM_SET_TILING DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_SET_TILING, struct drm_i915_gem_set_tiling) -#define DRM_IOCTL_I915_GEM_GET_TILING DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_GET_TILING, struct drm_i915_gem_get_tiling) /* Allow drivers to submit batchbuffers directly to hardware, relying * on the security mechanisms provided by hardware. @@ -230,8 +200,6 @@ typedef struct drm_i915_irq_wait { #define I915_PARAM_IRQ_ACTIVE 1 #define I915_PARAM_ALLOW_BATCHBUFFER 2 #define I915_PARAM_LAST_DISPATCH 3 -#define I915_PARAM_CHIPSET_ID 4 -#define I915_PARAM_HAS_GEM 5 typedef struct drm_i915_getparam { int param; @@ -299,305 +267,4 @@ typedef struct drm_i915_hws_addr { uint64_t addr; } drm_i915_hws_addr_t; -struct drm_i915_gem_init { - /** - * Beginning offset in the GTT to be managed by the DRM memory - * manager. - */ - uint64_t gtt_start; - /** - * Ending offset in the GTT to be managed by the DRM memory - * manager. - */ - uint64_t gtt_end; -}; - -struct drm_i915_gem_create { - /** - * Requested size for the object. - * - * The (page-aligned) allocated size for the object will be returned. - */ - uint64_t size; - /** - * Returned handle for the object. - * - * Object handles are nonzero. - */ - uint32_t handle; - uint32_t pad; -}; - -struct drm_i915_gem_pread { - /** Handle for the object being read. */ - uint32_t handle; - uint32_t pad; - /** Offset into the object to read from */ - uint64_t offset; - /** Length of data to read */ - uint64_t size; - /** - * Pointer to write the data into. - * - * This is a fixed-size type for 32/64 compatibility. - */ - uint64_t data_ptr; -}; - -struct drm_i915_gem_pwrite { - /** Handle for the object being written to. */ - uint32_t handle; - uint32_t pad; - /** Offset into the object to write to */ - uint64_t offset; - /** Length of data to write */ - uint64_t size; - /** - * Pointer to read the data from. - * - * This is a fixed-size type for 32/64 compatibility. - */ - uint64_t data_ptr; -}; - -struct drm_i915_gem_mmap { - /** Handle for the object being mapped. */ - uint32_t handle; - uint32_t pad; - /** Offset in the object to map. */ - uint64_t offset; - /** - * Length of data to map. - * - * The value will be page-aligned. - */ - uint64_t size; - /** - * Returned pointer the data was mapped at. - * - * This is a fixed-size type for 32/64 compatibility. - */ - uint64_t addr_ptr; -}; - -struct drm_i915_gem_set_domain { - /** Handle for the object */ - uint32_t handle; - - /** New read domains */ - uint32_t read_domains; - - /** New write domain */ - uint32_t write_domain; -}; - -struct drm_i915_gem_sw_finish { - /** Handle for the object */ - uint32_t handle; -}; - -struct drm_i915_gem_relocation_entry { - /** - * Handle of the buffer being pointed to by this relocation entry. - * - * It's appealing to make this be an index into the mm_validate_entry - * list to refer to the buffer, but this allows the driver to create - * a relocation list for state buffers and not re-write it per - * exec using the buffer. - */ - uint32_t target_handle; - - /** - * Value to be added to the offset of the target buffer to make up - * the relocation entry. - */ - uint32_t delta; - - /** Offset in the buffer the relocation entry will be written into */ - uint64_t offset; - - /** - * Offset value of the target buffer that the relocation entry was last - * written as. - * - * If the buffer has the same offset as last time, we can skip syncing - * and writing the relocation. This value is written back out by - * the execbuffer ioctl when the relocation is written. - */ - uint64_t presumed_offset; - - /** - * Target memory domains read by this operation. - */ - uint32_t read_domains; - - /** - * Target memory domains written by this operation. - * - * Note that only one domain may be written by the whole - * execbuffer operation, so that where there are conflicts, - * the application will get -EINVAL back. - */ - uint32_t write_domain; -}; - -/** @{ - * Intel memory domains - * - * Most of these just align with the various caches in - * the system and are used to flush and invalidate as - * objects end up cached in different domains. - */ -/** CPU cache */ -#define I915_GEM_DOMAIN_CPU 0x00000001 -/** Render cache, used by 2D and 3D drawing */ -#define I915_GEM_DOMAIN_RENDER 0x00000002 -/** Sampler cache, used by texture engine */ -#define I915_GEM_DOMAIN_SAMPLER 0x00000004 -/** Command queue, used to load batch buffers */ -#define I915_GEM_DOMAIN_COMMAND 0x00000008 -/** Instruction cache, used by shader programs */ -#define I915_GEM_DOMAIN_INSTRUCTION 0x00000010 -/** Vertex address cache */ -#define I915_GEM_DOMAIN_VERTEX 0x00000020 -/** GTT domain - aperture and scanout */ -#define I915_GEM_DOMAIN_GTT 0x00000040 -/** @} */ - -struct drm_i915_gem_exec_object { - /** - * User's handle for a buffer to be bound into the GTT for this - * operation. - */ - uint32_t handle; - - /** Number of relocations to be performed on this buffer */ - uint32_t relocation_count; - /** - * Pointer to array of struct drm_i915_gem_relocation_entry containing - * the relocations to be performed in this buffer. - */ - uint64_t relocs_ptr; - - /** Required alignment in graphics aperture */ - uint64_t alignment; - - /** - * Returned value of the updated offset of the object, for future - * presumed_offset writes. - */ - uint64_t offset; -}; - -struct drm_i915_gem_execbuffer { - /** - * List of buffers to be validated with their relocations to be - * performend on them. - * - * This is a pointer to an array of struct drm_i915_gem_validate_entry. - * - * These buffers must be listed in an order such that all relocations - * a buffer is performing refer to buffers that have already appeared - * in the validate list. - */ - uint64_t buffers_ptr; - uint32_t buffer_count; - - /** Offset in the batchbuffer to start execution from. */ - uint32_t batch_start_offset; - /** Bytes used in batchbuffer from batch_start_offset */ - uint32_t batch_len; - uint32_t DR1; - uint32_t DR4; - uint32_t num_cliprects; - /** This is a struct drm_clip_rect *cliprects */ - uint64_t cliprects_ptr; -}; - -struct drm_i915_gem_pin { - /** Handle of the buffer to be pinned. */ - uint32_t handle; - uint32_t pad; - - /** alignment required within the aperture */ - uint64_t alignment; - - /** Returned GTT offset of the buffer. */ - uint64_t offset; -}; - -struct drm_i915_gem_unpin { - /** Handle of the buffer to be unpinned. */ - uint32_t handle; - uint32_t pad; -}; - -struct drm_i915_gem_busy { - /** Handle of the buffer to check for busy */ - uint32_t handle; - - /** Return busy status (1 if busy, 0 if idle) */ - uint32_t busy; -}; - -#define I915_TILING_NONE 0 -#define I915_TILING_X 1 -#define I915_TILING_Y 2 - -#define I915_BIT_6_SWIZZLE_NONE 0 -#define I915_BIT_6_SWIZZLE_9 1 -#define I915_BIT_6_SWIZZLE_9_10 2 -#define I915_BIT_6_SWIZZLE_9_11 3 -#define I915_BIT_6_SWIZZLE_9_10_11 4 -/* Not seen by userland */ -#define I915_BIT_6_SWIZZLE_UNKNOWN 5 - -struct drm_i915_gem_set_tiling { - /** Handle of the buffer to have its tiling state updated */ - uint32_t handle; - - /** - * Tiling mode for the object (I915_TILING_NONE, I915_TILING_X, - * I915_TILING_Y). - * - * This value is to be set on request, and will be updated by the - * kernel on successful return with the actual chosen tiling layout. - * - * The tiling mode may be demoted to I915_TILING_NONE when the system - * has bit 6 swizzling that can't be managed correctly by GEM. - * - * Buffer contents become undefined when changing tiling_mode. - */ - uint32_t tiling_mode; - - /** - * Stride in bytes for the object when in I915_TILING_X or - * I915_TILING_Y. - */ - uint32_t stride; - - /** - * Returned address bit 6 swizzling required for CPU access through - * mmap mapping. - */ - uint32_t swizzle_mode; -}; - -struct drm_i915_gem_get_tiling { - /** Handle of the buffer to get tiling state for. */ - uint32_t handle; - - /** - * Current tiling mode for the object (I915_TILING_NONE, I915_TILING_X, - * I915_TILING_Y). - */ - uint32_t tiling_mode; - - /** - * Returned address bit 6 swizzling required for CPU access through - * mmap mapping. - */ - uint32_t swizzle_mode; -}; - #endif /* _I915_DRM_H_ */ diff --git a/trunk/include/linux/dvb/frontend.h b/trunk/include/linux/dvb/frontend.h index 79a8ed8e6a7d..6e4ace270276 100644 --- a/trunk/include/linux/dvb/frontend.h +++ b/trunk/include/linux/dvb/frontend.h @@ -166,7 +166,6 @@ typedef enum fe_modulation { VSB_16, PSK_8, APSK_16, - APSK_32, DQPSK, } fe_modulation_t; @@ -296,7 +295,6 @@ typedef enum fe_delivery_system { SYS_DVBC_ANNEX_AC, SYS_DVBC_ANNEX_B, SYS_DVBT, - SYS_DSS, SYS_DVBS, SYS_DVBS2, SYS_DVBH, diff --git a/trunk/include/linux/i2c-id.h b/trunk/include/linux/i2c-id.h index 01d67ba9e985..493435bcdbe5 100644 --- a/trunk/include/linux/i2c-id.h +++ b/trunk/include/linux/i2c-id.h @@ -60,7 +60,7 @@ #define I2C_DRIVERID_WM8775 69 /* wm8775 audio processor */ #define I2C_DRIVERID_CS53L32A 70 /* cs53l32a audio processor */ #define I2C_DRIVERID_CX25840 71 /* cx2584x video encoder */ -#define I2C_DRIVERID_SAA7127 72 /* saa7127 video encoder */ +#define I2C_DRIVERID_SAA7127 72 /* saa7124 video encoder */ #define I2C_DRIVERID_SAA711X 73 /* saa711x video encoders */ #define I2C_DRIVERID_AKITAIOEXP 74 /* IO Expander on Sharp SL-C1000 */ #define I2C_DRIVERID_INFRARED 75 /* I2C InfraRed on Video boards */ diff --git a/trunk/include/linux/jbd2.h b/trunk/include/linux/jbd2.h index c7d106ef22e2..463d6f10b64f 100644 --- a/trunk/include/linux/jbd2.h +++ b/trunk/include/linux/jbd2.h @@ -641,11 +641,6 @@ struct transaction_s */ int t_handle_count; - /* - * For use by the filesystem to store fs-specific data - * structures associated with the transaction - */ - struct list_head t_private_list; }; struct transaction_run_stats_s { @@ -940,10 +935,6 @@ struct journal_s pid_t j_last_sync_writer; - /* This function is called when a transaction is closed */ - void (*j_commit_callback)(journal_t *, - transaction_t *); - /* * Journal statistics */ diff --git a/trunk/include/linux/writeback.h b/trunk/include/linux/writeback.h index e585657e9831..12b15c561a1f 100644 --- a/trunk/include/linux/writeback.h +++ b/trunk/include/linux/writeback.h @@ -63,15 +63,7 @@ struct writeback_control { unsigned for_writepages:1; /* This is a writepages() call */ unsigned range_cyclic:1; /* range_start is cyclic */ unsigned more_io:1; /* more io to be dispatched */ - /* - * write_cache_pages() won't update wbc->nr_to_write and - * mapping->writeback_index if no_nrwrite_index_update - * is set. write_cache_pages() may write more than we - * requested and we want to make sure nr_to_write and - * writeback_index are updated in a consistent manner - * so we use a single control to update them - */ - unsigned no_nrwrite_index_update:1; + unsigned range_cont:1; }; /* diff --git a/trunk/include/media/soc_camera_platform.h b/trunk/include/media/soc_camera_platform.h index 1d092b4678aa..851f18220984 100644 --- a/trunk/include/media/soc_camera_platform.h +++ b/trunk/include/media/soc_camera_platform.h @@ -1,13 +1,3 @@ -/* - * Generic Platform Camera Driver Header - * - * Copyright (C) 2008 Magnus Damm - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - #ifndef __SOC_CAMERA_H__ #define __SOC_CAMERA_H__ @@ -19,7 +9,6 @@ struct soc_camera_platform_info { unsigned long format_depth; struct v4l2_pix_format format; unsigned long bus_param; - void (*power)(int); int (*set_capture)(struct soc_camera_platform_info *info, int enable); }; diff --git a/trunk/include/media/tuner.h b/trunk/include/media/tuner.h index 7d4e2db78076..67c1f514d0e2 100644 --- a/trunk/include/media/tuner.h +++ b/trunk/include/media/tuner.h @@ -123,7 +123,6 @@ #define TUNER_TEA5761 75 /* Only FM Radio Tuner */ #define TUNER_XC5000 76 /* Xceive Silicon Tuner */ #define TUNER_TCL_MF02GIP_5N 77 /* TCL MF02GIP_5N */ -#define TUNER_PHILIPS_FMD1216MEX_MK3 78 /* tv card specific */ #define TDA9887_PRESENT (1<<0) diff --git a/trunk/include/media/v4l2-i2c-drv-legacy.h b/trunk/include/media/v4l2-i2c-drv-legacy.h index e65dd9d84e8b..975ffbf4e2c5 100644 --- a/trunk/include/media/v4l2-i2c-drv-legacy.h +++ b/trunk/include/media/v4l2-i2c-drv-legacy.h @@ -21,17 +21,6 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* NOTE: the full version of this header is in the v4l-dvb repository - * and allows v4l i2c drivers to be compiled on older kernels as well. - * The version of this header as it appears in the kernel is a stripped - * version (without all the backwards compatibility stuff) and so it - * looks a bit odd. - * - * If you look at the full version then you will understand the reason - * for introducing this header since you really don't want to have all - * the tricky backwards compatibility code in each and every i2c driver. - */ - struct v4l2_i2c_driver_data { const char * const name; int driverid; diff --git a/trunk/include/media/v4l2-i2c-drv.h b/trunk/include/media/v4l2-i2c-drv.h index efdc8bf27f87..40ecef29801d 100644 --- a/trunk/include/media/v4l2-i2c-drv.h +++ b/trunk/include/media/v4l2-i2c-drv.h @@ -21,17 +21,6 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* NOTE: the full version of this header is in the v4l-dvb repository - * and allows v4l i2c drivers to be compiled on older kernels as well. - * The version of this header as it appears in the kernel is a stripped - * version (without all the backwards compatibility stuff) and so it - * looks a bit odd. - * - * If you look at the full version then you will understand the reason - * for introducing this header since you really don't want to have all - * the tricky backwards compatibility code in each and every i2c driver. - */ - #ifndef __V4L2_I2C_DRV_H__ #define __V4L2_I2C_DRV_H__ diff --git a/trunk/include/media/videobuf-dvb.h b/trunk/include/media/videobuf-dvb.h index 80471c2b6343..b77748696329 100644 --- a/trunk/include/media/videobuf-dvb.h +++ b/trunk/include/media/videobuf-dvb.h @@ -16,6 +16,7 @@ struct videobuf_dvb { int nfeeds; /* videobuf_dvb_(un)register manges this */ + struct dvb_adapter adapter; struct dvb_demux demux; struct dmxdev dmxdev; struct dmx_frontend fe_hw; @@ -23,34 +24,12 @@ struct videobuf_dvb { struct dvb_net net; }; -struct videobuf_dvb_frontend { - struct list_head felist; - int id; - struct videobuf_dvb dvb; -}; - -struct videobuf_dvb_frontends { - struct list_head felist; - struct mutex lock; - struct dvb_adapter adapter; - int active_fe_id; /* Indicates which frontend in the felist is in use */ - int gate; /* Frontend with gate control 0=!MFE,1=fe0,2=fe1 etc */ -}; - -int videobuf_dvb_register_bus(struct videobuf_dvb_frontends *f, +int videobuf_dvb_register(struct videobuf_dvb *dvb, struct module *module, void *adapter_priv, struct device *device, - short *adapter_nr, - int mfe_shared); - -void videobuf_dvb_unregister_bus(struct videobuf_dvb_frontends *f); - -struct videobuf_dvb_frontend * videobuf_dvb_alloc_frontend(struct videobuf_dvb_frontends *f, int id); - -struct videobuf_dvb_frontend * videobuf_dvb_get_frontend(struct videobuf_dvb_frontends *f, int id); -int videobuf_dvb_find_frontend(struct videobuf_dvb_frontends *f, struct dvb_frontend *p); - + short *adapter_nr); +void videobuf_dvb_unregister(struct videobuf_dvb *dvb); /* * Local variables: diff --git a/trunk/mm/page-writeback.c b/trunk/mm/page-writeback.c index b40f6d5f8fe9..c130a137c129 100644 --- a/trunk/mm/page-writeback.c +++ b/trunk/mm/page-writeback.c @@ -876,7 +876,6 @@ int write_cache_pages(struct address_space *mapping, pgoff_t end; /* Inclusive */ int scanned = 0; int range_whole = 0; - long nr_to_write = wbc->nr_to_write; if (wbc->nonblocking && bdi_write_congested(bdi)) { wbc->encountered_congestion = 1; @@ -940,7 +939,7 @@ int write_cache_pages(struct address_space *mapping, unlock_page(page); ret = 0; } - if (ret || (--nr_to_write <= 0)) + if (ret || (--(wbc->nr_to_write) <= 0)) done = 1; if (wbc->nonblocking && bdi_write_congested(bdi)) { wbc->encountered_congestion = 1; @@ -959,12 +958,11 @@ int write_cache_pages(struct address_space *mapping, index = 0; goto retry; } - if (!wbc->no_nrwrite_index_update) { - if (wbc->range_cyclic || (range_whole && nr_to_write > 0)) - mapping->writeback_index = index; - wbc->nr_to_write = nr_to_write; - } + if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0)) + mapping->writeback_index = index; + if (wbc->range_cont) + wbc->range_start = index << PAGE_CACHE_SHIFT; return ret; } EXPORT_SYMBOL(write_cache_pages); diff --git a/trunk/mm/shmem.c b/trunk/mm/shmem.c index d87958a5f03e..bf66d0191baf 100644 --- a/trunk/mm/shmem.c +++ b/trunk/mm/shmem.c @@ -2580,7 +2580,6 @@ struct file *shmem_file_setup(char *name, loff_t size, unsigned long flags) shmem_unacct_size(flags, size); return ERR_PTR(error); } -EXPORT_SYMBOL_GPL(shmem_file_setup); /** * shmem_zero_setup - setup a shared anonymous mapping