diff options
Diffstat (limited to 'drivers/staging')
335 files changed, 13868 insertions, 20395 deletions
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index e4f608815c05..c0901b96cfe4 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -56,8 +56,6 @@ source "drivers/staging/iio/Kconfig" source "drivers/staging/sm750fb/Kconfig" -source "drivers/staging/xgifb/Kconfig" - source "drivers/staging/emxx_udc/Kconfig" source "drivers/staging/speakup/Kconfig" @@ -104,12 +102,16 @@ source "drivers/staging/pi433/Kconfig" source "drivers/staging/mt7621-pci/Kconfig" +source "drivers/staging/mt7621-pci-phy/Kconfig" + source "drivers/staging/mt7621-pinctrl/Kconfig" source "drivers/staging/mt7621-spi/Kconfig" source "drivers/staging/mt7621-dma/Kconfig" +source "drivers/staging/ralink-gdma/Kconfig" + source "drivers/staging/mt7621-mmc/Kconfig" source "drivers/staging/mt7621-eth/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 5868631e8f1b..57c6bce13ff4 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -20,7 +20,6 @@ obj-$(CONFIG_VT6656) += vt6656/ obj-$(CONFIG_VME_BUS) += vme/ obj-$(CONFIG_IIO) += iio/ obj-$(CONFIG_FB_SM750) += sm750fb/ -obj-$(CONFIG_FB_XGI) += xgifb/ obj-$(CONFIG_USB_EMXX) += emxx_udc/ obj-$(CONFIG_SPEAKUP) += speakup/ obj-$(CONFIG_MFD_NVEC) += nvec/ @@ -41,12 +40,14 @@ obj-$(CONFIG_GREYBUS) += greybus/ obj-$(CONFIG_BCM2835_VCHIQ) += vc04_services/ obj-$(CONFIG_DRM_VBOXVIDEO) += vboxvideo/ obj-$(CONFIG_PI433) += pi433/ -obj-$(CONFIG_SOC_MT7621) += mt7621-pci/ -obj-$(CONFIG_SOC_MT7621) += mt7621-pinctrl/ -obj-$(CONFIG_SOC_MT7621) += mt7621-spi/ +obj-$(CONFIG_PCI_MT7621) += mt7621-pci/ +obj-$(CONFIG_PCI_MT7621_PHY) += mt7621-pci-phy/ +obj-$(CONFIG_PINCTRL_RT2880) += mt7621-pinctrl/ +obj-$(CONFIG_SPI_MT7621) += mt7621-spi/ obj-$(CONFIG_SOC_MT7621) += mt7621-dma/ -obj-$(CONFIG_SOC_MT7621) += mt7621-mmc/ -obj-$(CONFIG_SOC_MT7621) += mt7621-eth/ +obj-$(CONFIG_DMA_RALINK) += ralink-gdma/ +obj-$(CONFIG_MTK_MMC) += mt7621-mmc/ +obj-$(CONFIG_NET_MEDIATEK_SOC_STAGING) += mt7621-eth/ obj-$(CONFIG_SOC_MT7621) += mt7621-dts/ obj-$(CONFIG_STAGING_GASKET_FRAMEWORK) += gasket/ obj-$(CONFIG_XIL_AXIS_FIFO) += axis-fifo/ diff --git a/drivers/staging/android/ashmem.c b/drivers/staging/android/ashmem.c index 90a8a9f1ac7d..74d497d39c5a 100644 --- a/drivers/staging/android/ashmem.c +++ b/drivers/staging/android/ashmem.c @@ -75,6 +75,9 @@ struct ashmem_range { /* LRU list of unpinned pages, protected by ashmem_mutex */ static LIST_HEAD(ashmem_lru_list); +static atomic_t ashmem_shrink_inflight = ATOMIC_INIT(0); +static DECLARE_WAIT_QUEUE_HEAD(ashmem_shrink_wait); + /* * long lru_count - The count of pages on our LRU list. * @@ -126,7 +129,8 @@ static inline bool page_range_in_range(struct ashmem_range *range, page_range_subsumes_range(range, start, end); } -static inline bool range_before_page(struct ashmem_range *range, size_t page) +static inline bool range_before_page(struct ashmem_range *range, + size_t page) { return range->pgend < page; } @@ -168,19 +172,15 @@ static inline void lru_del(struct ashmem_range *range) * @end: The ending page (inclusive) * * This function is protected by ashmem_mutex. - * - * Return: 0 if successful, or -ENOMEM if there is an error */ -static int range_alloc(struct ashmem_area *asma, - struct ashmem_range *prev_range, unsigned int purged, - size_t start, size_t end) +static void range_alloc(struct ashmem_area *asma, + struct ashmem_range *prev_range, unsigned int purged, + size_t start, size_t end, + struct ashmem_range **new_range) { - struct ashmem_range *range; - - range = kmem_cache_zalloc(ashmem_range_cachep, GFP_KERNEL); - if (!range) - return -ENOMEM; + struct ashmem_range *range = *new_range; + *new_range = NULL; range->asma = asma; range->pgstart = start; range->pgend = end; @@ -190,8 +190,6 @@ static int range_alloc(struct ashmem_area *asma, if (range_on_lru(range)) lru_add(range); - - return 0; } /** @@ -438,7 +436,6 @@ out: static unsigned long ashmem_shrink_scan(struct shrinker *shrink, struct shrink_control *sc) { - struct ashmem_range *range, *next; unsigned long freed = 0; /* We might recurse into filesystem code, so bail out if necessary */ @@ -448,21 +445,33 @@ ashmem_shrink_scan(struct shrinker *shrink, struct shrink_control *sc) if (!mutex_trylock(&ashmem_mutex)) return -1; - list_for_each_entry_safe(range, next, &ashmem_lru_list, lru) { + while (!list_empty(&ashmem_lru_list)) { + struct ashmem_range *range = + list_first_entry(&ashmem_lru_list, typeof(*range), lru); loff_t start = range->pgstart * PAGE_SIZE; loff_t end = (range->pgend + 1) * PAGE_SIZE; + struct file *f = range->asma->file; - range->asma->file->f_op->fallocate(range->asma->file, - FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, - start, end - start); + get_file(f); + atomic_inc(&ashmem_shrink_inflight); range->purged = ASHMEM_WAS_PURGED; lru_del(range); freed += range_size(range); + mutex_unlock(&ashmem_mutex); + f->f_op->fallocate(f, + FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, + start, end - start); + fput(f); + if (atomic_dec_and_test(&ashmem_shrink_inflight)) + wake_up_all(&ashmem_shrink_wait); + if (!mutex_trylock(&ashmem_mutex)) + goto out; if (--sc->nr_to_scan <= 0) break; } mutex_unlock(&ashmem_mutex); +out: return freed; } @@ -582,7 +591,8 @@ static int get_name(struct ashmem_area *asma, void __user *name) * * Caller must hold ashmem_mutex. */ -static int ashmem_pin(struct ashmem_area *asma, size_t pgstart, size_t pgend) +static int ashmem_pin(struct ashmem_area *asma, size_t pgstart, size_t pgend, + struct ashmem_range **new_range) { struct ashmem_range *range, *next; int ret = ASHMEM_NOT_PURGED; @@ -635,7 +645,7 @@ static int ashmem_pin(struct ashmem_area *asma, size_t pgstart, size_t pgend) * second half and adjust the first chunk's endpoint. */ range_alloc(asma, range, range->purged, - pgend + 1, range->pgend); + pgend + 1, range->pgend, new_range); range_shrink(range, range->pgstart, pgstart - 1); break; } @@ -649,7 +659,8 @@ static int ashmem_pin(struct ashmem_area *asma, size_t pgstart, size_t pgend) * * Caller must hold ashmem_mutex. */ -static int ashmem_unpin(struct ashmem_area *asma, size_t pgstart, size_t pgend) +static int ashmem_unpin(struct ashmem_area *asma, size_t pgstart, size_t pgend, + struct ashmem_range **new_range) { struct ashmem_range *range, *next; unsigned int purged = ASHMEM_NOT_PURGED; @@ -675,7 +686,8 @@ restart: } } - return range_alloc(asma, range, purged, pgstart, pgend); + range_alloc(asma, range, purged, pgstart, pgend, new_range); + return 0; } /* @@ -708,11 +720,19 @@ static int ashmem_pin_unpin(struct ashmem_area *asma, unsigned long cmd, struct ashmem_pin pin; size_t pgstart, pgend; int ret = -EINVAL; + struct ashmem_range *range = NULL; if (copy_from_user(&pin, p, sizeof(pin))) return -EFAULT; + if (cmd == ASHMEM_PIN || cmd == ASHMEM_UNPIN) { + range = kmem_cache_zalloc(ashmem_range_cachep, GFP_KERNEL); + if (!range) + return -ENOMEM; + } + mutex_lock(&ashmem_mutex); + wait_event(ashmem_shrink_wait, !atomic_read(&ashmem_shrink_inflight)); if (!asma->file) goto out_unlock; @@ -735,10 +755,10 @@ static int ashmem_pin_unpin(struct ashmem_area *asma, unsigned long cmd, switch (cmd) { case ASHMEM_PIN: - ret = ashmem_pin(asma, pgstart, pgend); + ret = ashmem_pin(asma, pgstart, pgend, &range); break; case ASHMEM_UNPIN: - ret = ashmem_unpin(asma, pgstart, pgend); + ret = ashmem_unpin(asma, pgstart, pgend, &range); break; case ASHMEM_GET_PIN_STATUS: ret = ashmem_get_pin_status(asma, pgstart, pgend); @@ -747,6 +767,8 @@ static int ashmem_pin_unpin(struct ashmem_area *asma, unsigned long cmd, out_unlock: mutex_unlock(&ashmem_mutex); + if (range) + kmem_cache_free(ashmem_range_cachep, range); return ret; } diff --git a/drivers/staging/android/ion/Makefile b/drivers/staging/android/ion/Makefile index bb30bf8774a0..17f3a7569e3d 100644 --- a/drivers/staging/android/ion/Makefile +++ b/drivers/staging/android/ion/Makefile @@ -1,5 +1,5 @@ # SPDX-License-Identifier: GPL-2.0 -obj-$(CONFIG_ION) += ion.o ion-ioctl.o ion_heap.o +obj-$(CONFIG_ION) += ion.o ion_heap.o obj-$(CONFIG_ION_SYSTEM_HEAP) += ion_system_heap.o ion_page_pool.o obj-$(CONFIG_ION_CARVEOUT_HEAP) += ion_carveout_heap.o obj-$(CONFIG_ION_CHUNK_HEAP) += ion_chunk_heap.o diff --git a/drivers/staging/android/ion/ion-ioctl.c b/drivers/staging/android/ion/ion-ioctl.c deleted file mode 100644 index a8d3cc412fb9..000000000000 --- a/drivers/staging/android/ion/ion-ioctl.c +++ /dev/null @@ -1,98 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Copyright (C) 2011 Google, Inc. - */ - -#include <linux/kernel.h> -#include <linux/file.h> -#include <linux/fs.h> -#include <linux/uaccess.h> - -#include "ion.h" - -union ion_ioctl_arg { - struct ion_allocation_data allocation; - struct ion_heap_query query; -}; - -static int validate_ioctl_arg(unsigned int cmd, union ion_ioctl_arg *arg) -{ - switch (cmd) { - case ION_IOC_HEAP_QUERY: - if (arg->query.reserved0 || - arg->query.reserved1 || - arg->query.reserved2) - return -EINVAL; - break; - default: - break; - } - - return 0; -} - -/* fix up the cases where the ioctl direction bits are incorrect */ -static unsigned int ion_ioctl_dir(unsigned int cmd) -{ - switch (cmd) { - default: - return _IOC_DIR(cmd); - } -} - -long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -{ - int ret = 0; - unsigned int dir; - union ion_ioctl_arg data; - - dir = ion_ioctl_dir(cmd); - - if (_IOC_SIZE(cmd) > sizeof(data)) - return -EINVAL; - - /* - * The copy_from_user is unconditional here for both read and write - * to do the validate. If there is no write for the ioctl, the - * buffer is cleared - */ - if (copy_from_user(&data, (void __user *)arg, _IOC_SIZE(cmd))) - return -EFAULT; - - ret = validate_ioctl_arg(cmd, &data); - if (ret) { - pr_warn_once("%s: ioctl validate failed\n", __func__); - return ret; - } - - if (!(dir & _IOC_WRITE)) - memset(&data, 0, sizeof(data)); - - switch (cmd) { - case ION_IOC_ALLOC: - { - int fd; - - fd = ion_alloc(data.allocation.len, - data.allocation.heap_id_mask, - data.allocation.flags); - if (fd < 0) - return fd; - - data.allocation.fd = fd; - - break; - } - case ION_IOC_HEAP_QUERY: - ret = ion_query_heaps(&data.query); - break; - default: - return -ENOTTY; - } - - if (dir & _IOC_READ) { - if (copy_to_user((void __user *)arg, &data, _IOC_SIZE(cmd))) - return -EFAULT; - } - return ret; -} diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c index 6f5afab7c1a1..92c2914239e3 100644 --- a/drivers/staging/android/ion/ion.c +++ b/drivers/staging/android/ion/ion.c @@ -1,11 +1,10 @@ // SPDX-License-Identifier: GPL-2.0 /* - * drivers/staging/android/ion/ion.c + * ION Memory Allocator * * Copyright (C) 2011 Google, Inc. */ -#include <linux/anon_inodes.h> #include <linux/debugfs.h> #include <linux/device.h> #include <linux/dma-buf.h> @@ -14,10 +13,8 @@ #include <linux/file.h> #include <linux/freezer.h> #include <linux/fs.h> -#include <linux/idr.h> #include <linux/kthread.h> #include <linux/list.h> -#include <linux/memblock.h> #include <linux/miscdevice.h> #include <linux/mm.h> #include <linux/mm_types.h> @@ -390,7 +387,7 @@ static const struct dma_buf_ops dma_buf_ops = { .unmap = ion_dma_buf_kunmap, }; -int ion_alloc(size_t len, unsigned int heap_id_mask, unsigned int flags) +static int ion_alloc(size_t len, unsigned int heap_id_mask, unsigned int flags) { struct ion_device *dev = internal_dev; struct ion_buffer *buffer = NULL; @@ -447,7 +444,7 @@ int ion_alloc(size_t len, unsigned int heap_id_mask, unsigned int flags) return fd; } -int ion_query_heaps(struct ion_heap_query *query) +static int ion_query_heaps(struct ion_heap_query *query) { struct ion_device *dev = internal_dev; struct ion_heap_data __user *buffer = u64_to_user_ptr(query->heaps); @@ -492,6 +489,81 @@ out: return ret; } +union ion_ioctl_arg { + struct ion_allocation_data allocation; + struct ion_heap_query query; +}; + +static int validate_ioctl_arg(unsigned int cmd, union ion_ioctl_arg *arg) +{ + switch (cmd) { + case ION_IOC_HEAP_QUERY: + if (arg->query.reserved0 || + arg->query.reserved1 || + arg->query.reserved2) + return -EINVAL; + break; + default: + break; + } + + return 0; +} + +static long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + int ret = 0; + union ion_ioctl_arg data; + + if (_IOC_SIZE(cmd) > sizeof(data)) + return -EINVAL; + + /* + * The copy_from_user is unconditional here for both read and write + * to do the validate. If there is no write for the ioctl, the + * buffer is cleared + */ + if (copy_from_user(&data, (void __user *)arg, _IOC_SIZE(cmd))) + return -EFAULT; + + ret = validate_ioctl_arg(cmd, &data); + if (ret) { + pr_warn_once("%s: ioctl validate failed\n", __func__); + return ret; + } + + if (!(_IOC_DIR(cmd) & _IOC_WRITE)) + memset(&data, 0, sizeof(data)); + + switch (cmd) { + case ION_IOC_ALLOC: + { + int fd; + + fd = ion_alloc(data.allocation.len, + data.allocation.heap_id_mask, + data.allocation.flags); + if (fd < 0) + return fd; + + data.allocation.fd = fd; + + break; + } + case ION_IOC_HEAP_QUERY: + ret = ion_query_heaps(&data.query); + break; + default: + return -ENOTTY; + } + + if (_IOC_DIR(cmd) & _IOC_READ) { + if (copy_to_user((void __user *)arg, &data, _IOC_SIZE(cmd))) + return -EFAULT; + } + return ret; +} + static const struct file_operations ion_fops = { .owner = THIS_MODULE, .unlocked_ioctl = ion_ioctl, diff --git a/drivers/staging/android/ion/ion.h b/drivers/staging/android/ion/ion.h index 47b594cf1ac9..e291299fd35f 100644 --- a/drivers/staging/android/ion/ion.h +++ b/drivers/staging/android/ion/ion.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* - * drivers/staging/android/ion/ion.h + * ION Memory Allocator kernel interface header * * Copyright (C) 2011 Google, Inc. */ @@ -22,32 +22,9 @@ #include "../uapi/ion.h" /** - * struct ion_platform_heap - defines a heap in the given platform - * @type: type of the heap from ion_heap_type enum - * @id: unique identifier for heap. When allocating higher numb ers - * will be allocated from first. At allocation these are passed - * as a bit mask and therefore can not exceed ION_NUM_HEAP_IDS. - * @name: used for debug purposes - * @base: base address of heap in physical memory if applicable - * @size: size of the heap in bytes if applicable - * @priv: private info passed from the board file - * - * Provided by the board file. - */ -struct ion_platform_heap { - enum ion_heap_type type; - unsigned int id; - const char *name; - phys_addr_t base; - size_t size; - phys_addr_t align; - void *priv; -}; - -/** * struct ion_buffer - metadata for a particular buffer - * @ref: reference count * @node: node in the ion_device buffers tree + * @list: element in list of deferred freeable buffers * @dev: back pointer to the ion_device * @heap: back pointer to the heap the buffer came from * @flags: buffer specific flags @@ -58,7 +35,8 @@ struct ion_platform_heap { * @lock: protects the buffers cnt fields * @kmap_cnt: number of times the buffer is mapped to the kernel * @vaddr: the kernel mapping if kmap_cnt is not zero - * @sg_table: the sg table for the buffer if dmap_cnt is not zero + * @sg_table: the sg table for the buffer + * @attachments: list of devices attached to this buffer */ struct ion_buffer { union { @@ -174,12 +152,16 @@ struct ion_heap { unsigned long flags; unsigned int id; const char *name; + + /* deferred free support */ struct shrinker shrinker; struct list_head free_list; size_t free_list_size; spinlock_t free_lock; wait_queue_head_t waitqueue; struct task_struct *task; + + /* heap statistics */ u64 num_of_buffers; u64 num_of_alloc_bytes; u64 alloc_bytes_wm; @@ -205,10 +187,6 @@ int ion_heap_map_user(struct ion_heap *heap, struct ion_buffer *buffer, int ion_heap_buffer_zero(struct ion_buffer *buffer); int ion_heap_pages_zero(struct page *page, size_t size, pgprot_t pgprot); -int ion_alloc(size_t len, - unsigned int heap_id_mask, - unsigned int flags); - /** * ion_heap_init_shrinker * @heap: the heap @@ -330,8 +308,4 @@ void ion_page_pool_free(struct ion_page_pool *pool, struct page *page); int ion_page_pool_shrink(struct ion_page_pool *pool, gfp_t gfp_mask, int nr_to_scan); -long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); - -int ion_query_heaps(struct ion_heap_query *query); - #endif /* _ION_H */ diff --git a/drivers/staging/android/ion/ion_carveout_heap.c b/drivers/staging/android/ion/ion_carveout_heap.c index e129237a0417..bb9d614767a2 100644 --- a/drivers/staging/android/ion/ion_carveout_heap.c +++ b/drivers/staging/android/ion/ion_carveout_heap.c @@ -1,10 +1,10 @@ // SPDX-License-Identifier: GPL-2.0 /* - * drivers/staging/android/ion/ion_carveout_heap.c + * ION Memory Allocator carveout heap helper * * Copyright (C) 2011 Google, Inc. */ -#include <linux/spinlock.h> + #include <linux/dma-mapping.h> #include <linux/err.h> #include <linux/genalloc.h> @@ -12,7 +12,7 @@ #include <linux/mm.h> #include <linux/scatterlist.h> #include <linux/slab.h> -#include <linux/vmalloc.h> + #include "ion.h" #define ION_CARVEOUT_ALLOCATE_FAIL -1 @@ -20,7 +20,6 @@ struct ion_carveout_heap { struct ion_heap heap; struct gen_pool *pool; - phys_addr_t base; }; static phys_addr_t ion_carveout_allocate(struct ion_heap *heap, @@ -44,6 +43,7 @@ static void ion_carveout_free(struct ion_heap *heap, phys_addr_t addr, if (addr == ION_CARVEOUT_ALLOCATE_FAIL) return; + gen_pool_free(carveout_heap->pool, addr, size); } @@ -103,17 +103,14 @@ static struct ion_heap_ops carveout_heap_ops = { .unmap_kernel = ion_heap_unmap_kernel, }; -struct ion_heap *ion_carveout_heap_create(struct ion_platform_heap *heap_data) +struct ion_heap *ion_carveout_heap_create(phys_addr_t base, size_t size) { struct ion_carveout_heap *carveout_heap; int ret; struct page *page; - size_t size; - - page = pfn_to_page(PFN_DOWN(heap_data->base)); - size = heap_data->size; + page = pfn_to_page(PFN_DOWN(base)); ret = ion_heap_pages_zero(page, size, pgprot_writecombine(PAGE_KERNEL)); if (ret) return ERR_PTR(ret); @@ -127,9 +124,7 @@ struct ion_heap *ion_carveout_heap_create(struct ion_platform_heap *heap_data) kfree(carveout_heap); return ERR_PTR(-ENOMEM); } - carveout_heap->base = heap_data->base; - gen_pool_add(carveout_heap->pool, carveout_heap->base, heap_data->size, - -1); + gen_pool_add(carveout_heap->pool, base, size, -1); carveout_heap->heap.ops = &carveout_heap_ops; carveout_heap->heap.type = ION_HEAP_TYPE_CARVEOUT; carveout_heap->heap.flags = ION_HEAP_FLAG_DEFER_FREE; diff --git a/drivers/staging/android/ion/ion_chunk_heap.c b/drivers/staging/android/ion/ion_chunk_heap.c index 159d72f5bc42..3cdde9c1a717 100644 --- a/drivers/staging/android/ion/ion_chunk_heap.c +++ b/drivers/staging/android/ion/ion_chunk_heap.c @@ -1,23 +1,22 @@ // SPDX-License-Identifier: GPL-2.0 /* - * drivers/staging/android/ion/ion_chunk_heap.c + * ION memory allocator chunk heap helper * * Copyright (C) 2012 Google, Inc. */ + #include <linux/dma-mapping.h> #include <linux/err.h> #include <linux/genalloc.h> -#include <linux/io.h> #include <linux/mm.h> #include <linux/scatterlist.h> #include <linux/slab.h> -#include <linux/vmalloc.h> + #include "ion.h" struct ion_chunk_heap { struct ion_heap heap; struct gen_pool *pool; - phys_addr_t base; unsigned long chunk_size; unsigned long size; unsigned long allocated; @@ -108,16 +107,13 @@ static struct ion_heap_ops chunk_heap_ops = { .unmap_kernel = ion_heap_unmap_kernel, }; -struct ion_heap *ion_chunk_heap_create(struct ion_platform_heap *heap_data) +struct ion_heap *ion_chunk_heap_create(phys_addr_t base, size_t size, size_t chunk_size) { struct ion_chunk_heap *chunk_heap; int ret; struct page *page; - size_t size; - - page = pfn_to_page(PFN_DOWN(heap_data->base)); - size = heap_data->size; + page = pfn_to_page(PFN_DOWN(base)); ret = ion_heap_pages_zero(page, size, pgprot_writecombine(PAGE_KERNEL)); if (ret) return ERR_PTR(ret); @@ -126,23 +122,21 @@ struct ion_heap *ion_chunk_heap_create(struct ion_platform_heap *heap_data) if (!chunk_heap) return ERR_PTR(-ENOMEM); - chunk_heap->chunk_size = (unsigned long)heap_data->priv; + chunk_heap->chunk_size = chunk_size; chunk_heap->pool = gen_pool_create(get_order(chunk_heap->chunk_size) + PAGE_SHIFT, -1); if (!chunk_heap->pool) { ret = -ENOMEM; goto error_gen_pool_create; } - chunk_heap->base = heap_data->base; - chunk_heap->size = heap_data->size; + chunk_heap->size = size; chunk_heap->allocated = 0; - gen_pool_add(chunk_heap->pool, chunk_heap->base, heap_data->size, -1); + gen_pool_add(chunk_heap->pool, base, size, -1); chunk_heap->heap.ops = &chunk_heap_ops; chunk_heap->heap.type = ION_HEAP_TYPE_CHUNK; chunk_heap->heap.flags = ION_HEAP_FLAG_DEFER_FREE; - pr_debug("%s: base %pa size %zu\n", __func__, - &chunk_heap->base, heap_data->size); + pr_debug("%s: base %pa size %zu\n", __func__, &base, size); return &chunk_heap->heap; @@ -150,4 +144,3 @@ error_gen_pool_create: kfree(chunk_heap); return ERR_PTR(ret); } - diff --git a/drivers/staging/android/ion/ion_cma_heap.c b/drivers/staging/android/ion/ion_cma_heap.c index 3fafd013d80a..bf65e67ef9d8 100644 --- a/drivers/staging/android/ion/ion_cma_heap.c +++ b/drivers/staging/android/ion/ion_cma_heap.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 /* - * drivers/staging/android/ion/ion_cma_heap.c + * ION Memory Allocator CMA heap exporter * * Copyright (C) Linaro 2012 * Author: <benjamin.gaignard@linaro.org> for ST-Ericsson. @@ -111,10 +111,6 @@ static struct ion_heap *__ion_cma_heap_create(struct cma *cma) return ERR_PTR(-ENOMEM); cma_heap->heap.ops = &ion_cma_ops; - /* - * get device from private heaps data, later it will be - * used to make the link with reserved CMA memory - */ cma_heap->cma = cma; cma_heap->heap.type = ION_HEAP_TYPE_DMA; return &cma_heap->heap; diff --git a/drivers/staging/android/ion/ion_heap.c b/drivers/staging/android/ion/ion_heap.c index 31db510018a9..473b465724f1 100644 --- a/drivers/staging/android/ion/ion_heap.c +++ b/drivers/staging/android/ion/ion_heap.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 /* - * drivers/staging/android/ion/ion_heap.c + * ION Memory Allocator generic heap helpers * * Copyright (C) 2011 Google, Inc. */ @@ -14,6 +14,7 @@ #include <uapi/linux/sched/types.h> #include <linux/scatterlist.h> #include <linux/vmalloc.h> + #include "ion.h" void *ion_heap_map_kernel(struct ion_heap *heap, @@ -92,6 +93,7 @@ int ion_heap_map_user(struct ion_heap *heap, struct ion_buffer *buffer, if (addr >= vma->vm_end) return 0; } + return 0; } @@ -254,6 +256,7 @@ int ion_heap_init_deferred_free(struct ion_heap *heap) return PTR_ERR_OR_ZERO(heap->task); } sched_setscheduler(heap->task, SCHED_IDLE, ¶m); + return 0; } @@ -265,8 +268,10 @@ static unsigned long ion_heap_shrink_count(struct shrinker *shrinker, int total = 0; total = ion_heap_freelist_size(heap) / PAGE_SIZE; + if (heap->ops->shrink) total += heap->ops->shrink(heap, sc->gfp_mask, 0); + return total; } @@ -295,6 +300,7 @@ static unsigned long ion_heap_shrink_scan(struct shrinker *shrinker, if (heap->ops->shrink) freed += heap->ops->shrink(heap, sc->gfp_mask, to_scan); + return freed; } diff --git a/drivers/staging/android/ion/ion_page_pool.c b/drivers/staging/android/ion/ion_page_pool.c index 0d2a95957ee8..fd4995fb676e 100644 --- a/drivers/staging/android/ion/ion_page_pool.c +++ b/drivers/staging/android/ion/ion_page_pool.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 /* - * drivers/staging/android/ion/ion_mem_pool.c + * ION Memory Allocator page pool helpers * * Copyright (C) 2011 Google, Inc. */ diff --git a/drivers/staging/android/ion/ion_system_heap.c b/drivers/staging/android/ion/ion_system_heap.c index 0383f7548d48..aa8d8425be25 100644 --- a/drivers/staging/android/ion/ion_system_heap.c +++ b/drivers/staging/android/ion/ion_system_heap.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 /* - * drivers/staging/android/ion/ion_system_heap.c + * ION Memory Allocator system heap exporter * * Copyright (C) 2011 Google, Inc. */ @@ -13,6 +13,7 @@ #include <linux/scatterlist.h> #include <linux/slab.h> #include <linux/vmalloc.h> + #include "ion.h" #define NUM_ORDERS ARRAY_SIZE(orders) @@ -223,10 +224,10 @@ static void ion_system_heap_destroy_pools(struct ion_page_pool **pools) static int ion_system_heap_create_pools(struct ion_page_pool **pools) { int i; - gfp_t gfp_flags = low_order_gfp_flags; for (i = 0; i < NUM_ORDERS; i++) { struct ion_page_pool *pool; + gfp_t gfp_flags = low_order_gfp_flags; if (orders[i] > 4) gfp_flags = high_order_gfp_flags; @@ -236,6 +237,7 @@ static int ion_system_heap_create_pools(struct ion_page_pool **pools) goto err_create_pool; pools[i] = pool; } + return 0; err_create_pool: @@ -274,6 +276,7 @@ static int ion_system_heap_create(void) heap->name = "ion_system_heap"; ion_device_add_heap(heap); + return 0; } device_initcall(ion_system_heap_create); @@ -355,6 +358,7 @@ static struct ion_heap *__ion_system_contig_heap_create(void) heap->ops = &kmalloc_ops; heap->type = ION_HEAP_TYPE_SYSTEM_CONTIG; heap->name = "ion_system_contig_heap"; + return heap; } @@ -367,7 +371,7 @@ static int ion_system_contig_heap_create(void) return PTR_ERR(heap); ion_device_add_heap(heap); + return 0; } device_initcall(ion_system_contig_heap_create); - diff --git a/drivers/staging/android/uapi/ion.h b/drivers/staging/android/uapi/ion.h index 5d7009884c13..46c93fcb46d6 100644 --- a/drivers/staging/android/uapi/ion.h +++ b/drivers/staging/android/uapi/ion.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * drivers/staging/android/uapi/ion.h * diff --git a/drivers/staging/android/vsoc.c b/drivers/staging/android/vsoc.c index 22571abcaa4e..8a75bd27c413 100644 --- a/drivers/staging/android/vsoc.c +++ b/drivers/staging/android/vsoc.c @@ -29,7 +29,6 @@ #include <linux/syscalls.h> #include <linux/uaccess.h> #include <linux/interrupt.h> -#include <linux/mutex.h> #include <linux/cdev.h> #include <linux/file.h> #include "uapi/vsoc_shm.h" diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index 5d2fcbfe02af..0caae4a5c471 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -1605,9 +1605,8 @@ static int do_insn_ioctl(struct comedi_device *dev, unsigned int n_data = MIN_SAMPLES; int ret = 0; - if (copy_from_user(&insn, arg, sizeof(insn))) { + if (copy_from_user(&insn, arg, sizeof(insn))) return -EFAULT; - } n_data = max(n_data, insn.n); diff --git a/drivers/staging/comedi/drivers/cb_pcimdas.c b/drivers/staging/comedi/drivers/cb_pcimdas.c index 4e72a0778086..a9d052bfda38 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdas.c +++ b/drivers/staging/comedi/drivers/cb_pcimdas.c @@ -252,9 +252,9 @@ static int cb_pcimdas_di_insn_bits(struct comedi_device *dev, } static int cb_pcimdas_do_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct cb_pcimdas_private *devpriv = dev->private; diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index e70a461e723f..405573e927cf 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -656,6 +656,7 @@ static int ni_660x_set_pfi_routing(struct comedi_device *dev, case NI_660X_PFI_OUTPUT_DIO: if (chan > 31) return -EINVAL; + break; default: return -EINVAL; } diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c index b9a0dc6eac44..4bdef87d5dd7 100644 --- a/drivers/staging/comedi/drivers/ni_pcidio.c +++ b/drivers/staging/comedi/drivers/ni_pcidio.c @@ -49,116 +49,117 @@ /* defines for the PCI-DIO-32HS */ -#define Window_Address 4 /* W */ -#define Interrupt_And_Window_Status 4 /* R */ -#define IntStatus1 BIT(0) -#define IntStatus2 BIT(1) -#define WindowAddressStatus_mask 0x7c - -#define Master_DMA_And_Interrupt_Control 5 /* W */ -#define InterruptLine(x) ((x) & 3) -#define OpenInt BIT(2) -#define Group_Status 5 /* R */ -#define DataLeft BIT(0) -#define Req BIT(2) -#define StopTrig BIT(3) - -#define Group_1_Flags 6 /* R */ -#define Group_2_Flags 7 /* R */ -#define TransferReady BIT(0) -#define CountExpired BIT(1) -#define Waited BIT(5) -#define PrimaryTC BIT(6) -#define SecondaryTC BIT(7) +#define WINDOW_ADDRESS 4 /* W */ +#define INTERRUPT_AND_WINDOW_STATUS 4 /* R */ +#define INT_STATUS_1 BIT(0) +#define INT_STATUS_2 BIT(1) +#define WINDOW_ADDRESS_STATUS_MASK 0x7c + +#define MASTER_DMA_AND_INTERRUPT_CONTROL 5 /* W */ +#define INTERRUPT_LINE(x) ((x) & 3) +#define OPEN_INT BIT(2) +#define GROUP_STATUS 5 /* R */ +#define DATA_LEFT BIT(0) +#define REQ BIT(2) +#define STOP_TRIG BIT(3) + +#define GROUP_1_FLAGS 6 /* R */ +#define GROUP_2_FLAGS 7 /* R */ +#define TRANSFER_READY BIT(0) +#define COUNT_EXPIRED BIT(1) +#define WAITED BIT(5) +#define PRIMARY_TC BIT(6) +#define SECONDARY_TC BIT(7) /* #define SerialRose */ /* #define ReqRose */ /* #define Paused */ -#define Group_1_First_Clear 6 /* W */ -#define Group_2_First_Clear 7 /* W */ -#define ClearWaited BIT(3) -#define ClearPrimaryTC BIT(4) -#define ClearSecondaryTC BIT(5) -#define DMAReset BIT(6) -#define FIFOReset BIT(7) -#define ClearAll 0xf8 - -#define Group_1_FIFO 8 /* W */ -#define Group_2_FIFO 12 /* W */ - -#define Transfer_Count 20 -#define Chip_ID_D 24 -#define Chip_ID_I 25 -#define Chip_ID_O 26 -#define Chip_Version 27 -#define Port_IO(x) (28 + (x)) -#define Port_Pin_Directions(x) (32 + (x)) -#define Port_Pin_Mask(x) (36 + (x)) -#define Port_Pin_Polarities(x) (40 + (x)) - -#define Master_Clock_Routing 45 -#define RTSIClocking(x) (((x) & 3) << 4) - -#define Group_1_Second_Clear 46 /* W */ -#define Group_2_Second_Clear 47 /* W */ -#define ClearExpired BIT(0) - -#define Port_Pattern(x) (48 + (x)) - -#define Data_Path 64 -#define FIFOEnableA BIT(0) -#define FIFOEnableB BIT(1) -#define FIFOEnableC BIT(2) -#define FIFOEnableD BIT(3) -#define Funneling(x) (((x) & 3) << 4) -#define GroupDirection BIT(7) - -#define Protocol_Register_1 65 -#define OpMode Protocol_Register_1 -#define RunMode(x) ((x) & 7) -#define Numbered BIT(3) - -#define Protocol_Register_2 66 -#define ClockReg Protocol_Register_2 -#define ClockLine(x) (((x) & 3) << 5) -#define InvertStopTrig BIT(7) -#define DataLatching(x) (((x) & 3) << 5) - -#define Protocol_Register_3 67 -#define Sequence Protocol_Register_3 - -#define Protocol_Register_14 68 /* 16 bit */ -#define ClockSpeed Protocol_Register_14 - -#define Protocol_Register_4 70 -#define ReqReg Protocol_Register_4 -#define ReqConditioning(x) (((x) & 7) << 3) - -#define Protocol_Register_5 71 -#define BlockMode Protocol_Register_5 +#define GROUP_1_FIRST_CLEAR 6 /* W */ +#define GROUP_2_FIRST_CLEAR 7 /* W */ +#define CLEAR_WAITED BIT(3) +#define CLEAR_PRIMARY_TC BIT(4) +#define CLEAR_SECONDARY_TC BIT(5) +#define DMA_RESET BIT(6) +#define FIFO_RESET BIT(7) +#define CLEAR_ALL 0xf8 + +#define GROUP_1_FIFO 8 /* W */ +#define GROUP_2_FIFO 12 /* W */ + +#define TRANSFER_COUNT 20 +#define CHIP_ID_D 24 +#define CHIP_ID_I 25 +#define CHIP_ID_O 26 +#define CHIP_VERSION 27 +#define PORT_IO(x) (28 + (x)) +#define PORT_PIN_DIRECTIONS(x) (32 + (x)) +#define PORT_PIN_MASK(x) (36 + (x)) +#define PORT_PIN_POLARITIES(x) (40 + (x)) + +#define MASTER_CLOCK_ROUTING 45 +#define RTSI_CLOCKING(x) (((x) & 3) << 4) + +#define GROUP_1_SECOND_CLEAR 46 /* W */ +#define GROUP_2_SECOND_CLEAR 47 /* W */ +#define CLEAR_EXPIRED BIT(0) + +#define PORT_PATTERN(x) (48 + (x)) + +#define DATA_PATH 64 +#define FIFO_ENABLE_A BIT(0) +#define FIFO_ENABLE_B BIT(1) +#define FIFO_ENABLE_C BIT(2) +#define FIFO_ENABLE_D BIT(3) +#define FUNNELING(x) (((x) & 3) << 4) +#define GROUP_DIRECTION BIT(7) + +#define PROTOCOL_REGISTER_1 65 +#define OP_MODE PROTOCOL_REGISTER_1 +#define RUN_MODE(x) ((x) & 7) +#define NUMBERED BIT(3) + +#define PROTOCOL_REGISTER_2 66 +#define CLOCK_REG PROTOCOL_REGISTER_2 +#define CLOCK_LINE(x) (((x) & 3) << 5) +#define INVERT_STOP_TRIG BIT(7) +#define DATA_LATCHING(x) (((x) & 3) << 5) + +#define PROTOCOL_REGISTER_3 67 +#define SEQUENCE PROTOCOL_REGISTER_3 + +#define PROTOCOL_REGISTER_14 68 /* 16 bit */ +#define CLOCK_SPEED PROTOCOL_REGISTER_14 + +#define PROTOCOL_REGISTER_4 70 +#define REQ_REG PROTOCOL_REGISTER_4 +#define REQ_CONDITIONING(x) (((x) & 7) << 3) + +#define PROTOCOL_REGISTER_5 71 +#define BLOCK_MODE PROTOCOL_REGISTER_5 #define FIFO_Control 72 -#define ReadyLevel(x) ((x) & 7) - -#define Protocol_Register_6 73 -#define LinePolarities Protocol_Register_6 -#define InvertAck BIT(0) -#define InvertReq BIT(1) -#define InvertClock BIT(2) -#define InvertSerial BIT(3) -#define OpenAck BIT(4) -#define OpenClock BIT(5) - -#define Protocol_Register_7 74 -#define AckSer Protocol_Register_7 -#define AckLine(x) (((x) & 3) << 2) -#define ExchangePins BIT(7) - -#define Interrupt_Control 75 - /* bits same as flags */ - -#define DMA_Line_Control_Group1 76 -#define DMA_Line_Control_Group2 108 +#define READY_LEVEL(x) ((x) & 7) + +#define PROTOCOL_REGISTER_6 73 +#define LINE_POLARITIES PROTOCOL_REGISTER_6 +#define INVERT_ACK BIT(0) +#define INVERT_REQ BIT(1) +#define INVERT_CLOCK BIT(2) +#define INVERT_SERIAL BIT(3) +#define OPEN_ACK BIT(4) +#define OPEN_CLOCK BIT(5) + +#define PROTOCOL_REGISTER_7 74 +#define ACK_SER PROTOCOL_REGISTER_7 +#define ACK_LINE(x) (((x) & 3) << 2) +#define EXCHANGE_PINS BIT(7) + +#define INTERRUPT_CONTROL 75 +/* bits same as flags */ + +#define DMA_LINE_CONTROL_GROUP1 76 +#define DMA_LINE_CONTROL_GROUP2 108 + /* channel zero is none */ static inline unsigned int primary_DMAChannel_bits(unsigned int channel) { @@ -170,41 +171,41 @@ static inline unsigned int secondary_DMAChannel_bits(unsigned int channel) return (channel << 2) & 0xc; } -#define Transfer_Size_Control 77 -#define TransferWidth(x) ((x) & 3) -#define TransferLength(x) (((x) & 3) << 3) -#define RequireRLevel BIT(5) +#define TRANSFER_SIZE_CONTROL 77 +#define TRANSFER_WIDTH(x) ((x) & 3) +#define TRANSFER_LENGTH(x) (((x) & 3) << 3) +#define REQUIRE_R_LEVEL BIT(5) -#define Protocol_Register_15 79 -#define DAQOptions Protocol_Register_15 -#define StartSource(x) ((x) & 0x3) -#define InvertStart BIT(2) -#define StopSource(x) (((x) & 0x3) << 3) -#define ReqStart BIT(6) -#define PreStart BIT(7) +#define PROTOCOL_REGISTER_15 79 +#define DAQ_OPTIONS PROTOCOL_REGISTER_15 +#define START_SOURCE(x) ((x) & 0x3) +#define INVERT_START BIT(2) +#define STOP_SOURCE(x) (((x) & 0x3) << 3) +#define REQ_START BIT(6) +#define PRE_START BIT(7) -#define Pattern_Detection 81 -#define DetectionMethod BIT(0) -#define InvertMatch BIT(1) -#define IE_Pattern_Detection BIT(2) +#define PATTERN_DETECTION 81 +#define DETECTION_METHOD BIT(0) +#define INVERT_MATCH BIT(1) +#define IE_PATTERN_DETECTION BIT(2) -#define Protocol_Register_9 82 -#define ReqDelay Protocol_Register_9 +#define PROTOCOL_REGISTER_9 82 +#define REQ_DELAY PROTOCOL_REGISTER_9 -#define Protocol_Register_10 83 -#define ReqNotDelay Protocol_Register_10 +#define PROTOCOL_REGISTER_10 83 +#define REQ_NOT_DELAY PROTOCOL_REGISTER_10 -#define Protocol_Register_11 84 -#define AckDelay Protocol_Register_11 +#define PROTOCOL_REGISTER_11 84 +#define ACK_DELAY PROTOCOL_REGISTER_11 -#define Protocol_Register_12 85 -#define AckNotDelay Protocol_Register_12 +#define PROTOCOL_REGISTER_12 85 +#define ACK_NOT_DELAY PROTOCOL_REGISTER_12 -#define Protocol_Register_13 86 -#define Data1Delay Protocol_Register_13 +#define PROTOCOL_REGISTER_13 86 +#define DATA_1_DELAY PROTOCOL_REGISTER_13 -#define Protocol_Register_8 88 /* 32 bit */ -#define StartDelay Protocol_Register_8 +#define PROTOCOL_REGISTER_8 88 /* 32 bit */ +#define START_DELAY PROTOCOL_REGISTER_8 /* Firmware files for PCI-6524 */ #define FW_PCI_6534_MAIN "ni6534a.bin" @@ -246,9 +247,10 @@ enum FPGA_Control_Bits { #define TIMER_BASE 50 /* nanoseconds */ #ifdef USE_DMA -#define IntEn (CountExpired | Waited | PrimaryTC | SecondaryTC) +#define INT_EN (COUNT_EXPIRED | WAITED | PRIMARY_TC | SECONDARY_TC) #else -#define IntEn (TransferReady | CountExpired | Waited | PrimaryTC | SecondaryTC) +#define INT_EN (TRANSFER_READY | COUNT_EXPIRED | WAITED \ + | PRIMARY_TC | SECONDARY_TC) #endif enum nidio_boardid { @@ -283,7 +285,7 @@ struct nidio96_private { struct mite *mite; int boardtype; int dio; - unsigned short OpModeBits; + unsigned short OP_MODEBits; struct mite_channel *di_mite_chan; struct mite_ring *di_mite_ring; spinlock_t mite_channel_lock; @@ -307,7 +309,7 @@ static int ni_pcidio_request_di_mite_channel(struct comedi_device *dev) devpriv->di_mite_chan->dir = COMEDI_INPUT; writeb(primary_DMAChannel_bits(devpriv->di_mite_chan->channel) | secondary_DMAChannel_bits(devpriv->di_mite_chan->channel), - dev->mmio + DMA_Line_Control_Group1); + dev->mmio + DMA_LINE_CONTROL_GROUP1); mmiowb(); spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags); return 0; @@ -324,7 +326,7 @@ static void ni_pcidio_release_di_mite_channel(struct comedi_device *dev) devpriv->di_mite_chan = NULL; writeb(primary_DMAChannel_bits(0) | secondary_DMAChannel_bits(0), - dev->mmio + DMA_Line_Control_Group1); + dev->mmio + DMA_LINE_CONTROL_GROUP1); mmiowb(); } spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags); @@ -391,8 +393,8 @@ static irqreturn_t nidio_interrupt(int irq, void *d) /* Lock to avoid race with comedi_poll */ spin_lock(&dev->spinlock); - status = readb(dev->mmio + Interrupt_And_Window_Status); - flags = readb(dev->mmio + Group_1_Flags); + status = readb(dev->mmio + INTERRUPT_AND_WINDOW_STATUS); + flags = readb(dev->mmio + GROUP_1_FLAGS); spin_lock(&devpriv->mite_channel_lock); if (devpriv->di_mite_chan) { @@ -401,63 +403,63 @@ static irqreturn_t nidio_interrupt(int irq, void *d) } spin_unlock(&devpriv->mite_channel_lock); - while (status & DataLeft) { + while (status & DATA_LEFT) { work++; if (work > 20) { dev_dbg(dev->class_dev, "too much work in interrupt\n"); writeb(0x00, - dev->mmio + Master_DMA_And_Interrupt_Control); + dev->mmio + MASTER_DMA_AND_INTERRUPT_CONTROL); break; } - flags &= IntEn; + flags &= INT_EN; - if (flags & TransferReady) { - while (flags & TransferReady) { + if (flags & TRANSFER_READY) { + while (flags & TRANSFER_READY) { work++; if (work > 100) { dev_dbg(dev->class_dev, "too much work in interrupt\n"); writeb(0x00, dev->mmio + - Master_DMA_And_Interrupt_Control + MASTER_DMA_AND_INTERRUPT_CONTROL ); goto out; } - auxdata = readl(dev->mmio + Group_1_FIFO); + auxdata = readl(dev->mmio + GROUP_1_FIFO); comedi_buf_write_samples(s, &auxdata, 1); - flags = readb(dev->mmio + Group_1_Flags); + flags = readb(dev->mmio + GROUP_1_FLAGS); } } - if (flags & CountExpired) { - writeb(ClearExpired, dev->mmio + Group_1_Second_Clear); + if (flags & COUNT_EXPIRED) { + writeb(CLEAR_EXPIRED, dev->mmio + GROUP_1_SECOND_CLEAR); async->events |= COMEDI_CB_EOA; - writeb(0x00, dev->mmio + OpMode); + writeb(0x00, dev->mmio + OP_MODE); break; - } else if (flags & Waited) { - writeb(ClearWaited, dev->mmio + Group_1_First_Clear); + } else if (flags & WAITED) { + writeb(CLEAR_WAITED, dev->mmio + GROUP_1_FIRST_CLEAR); async->events |= COMEDI_CB_ERROR; break; - } else if (flags & PrimaryTC) { - writeb(ClearPrimaryTC, - dev->mmio + Group_1_First_Clear); + } else if (flags & PRIMARY_TC) { + writeb(CLEAR_PRIMARY_TC, + dev->mmio + GROUP_1_FIRST_CLEAR); async->events |= COMEDI_CB_EOA; - } else if (flags & SecondaryTC) { - writeb(ClearSecondaryTC, - dev->mmio + Group_1_First_Clear); + } else if (flags & SECONDARY_TC) { + writeb(CLEAR_SECONDARY_TC, + dev->mmio + GROUP_1_FIRST_CLEAR); async->events |= COMEDI_CB_EOA; } - flags = readb(dev->mmio + Group_1_Flags); - status = readb(dev->mmio + Interrupt_And_Window_Status); + flags = readb(dev->mmio + GROUP_1_FLAGS); + status = readb(dev->mmio + INTERRUPT_AND_WINDOW_STATUS); } out: comedi_handle_events(dev, s); #if 0 if (!tag) - writeb(0x03, dev->mmio + Master_DMA_And_Interrupt_Control); + writeb(0x03, dev->mmio + MASTER_DMA_AND_INTERRUPT_CONTROL); #endif spin_unlock(&dev->spinlock); @@ -484,7 +486,7 @@ static int ni_pcidio_insn_config(struct comedi_device *dev, if (ret) return ret; - writel(s->io_bits, dev->mmio + Port_Pin_Directions(0)); + writel(s->io_bits, dev->mmio + PORT_PIN_DIRECTIONS(0)); return insn->n; } @@ -495,9 +497,9 @@ static int ni_pcidio_insn_bits(struct comedi_device *dev, unsigned int *data) { if (comedi_dio_update_state(s, data)) - writel(s->state, dev->mmio + Port_IO(0)); + writel(s->state, dev->mmio + PORT_IO(0)); - data[1] = readl(dev->mmio + Port_IO(0)); + data[1] = readl(dev->mmio + PORT_IO(0)); return insn->n; } @@ -609,7 +611,7 @@ static int ni_pcidio_inttrig(struct comedi_device *dev, if (trig_num != cmd->start_arg) return -EINVAL; - writeb(devpriv->OpModeBits, dev->mmio + OpMode); + writeb(devpriv->OP_MODEBits, dev->mmio + OP_MODE); s->async->inttrig = NULL; return 1; @@ -621,78 +623,78 @@ static int ni_pcidio_cmd(struct comedi_device *dev, struct comedi_subdevice *s) struct comedi_cmd *cmd = &s->async->cmd; /* XXX configure ports for input */ - writel(0x0000, dev->mmio + Port_Pin_Directions(0)); + writel(0x0000, dev->mmio + PORT_PIN_DIRECTIONS(0)); if (1) { /* enable fifos A B C D */ - writeb(0x0f, dev->mmio + Data_Path); + writeb(0x0f, dev->mmio + DATA_PATH); /* set transfer width a 32 bits */ - writeb(TransferWidth(0) | TransferLength(0), - dev->mmio + Transfer_Size_Control); + writeb(TRANSFER_WIDTH(0) | TRANSFER_LENGTH(0), + dev->mmio + TRANSFER_SIZE_CONTROL); } else { - writeb(0x03, dev->mmio + Data_Path); - writeb(TransferWidth(3) | TransferLength(0), - dev->mmio + Transfer_Size_Control); + writeb(0x03, dev->mmio + DATA_PATH); + writeb(TRANSFER_WIDTH(3) | TRANSFER_LENGTH(0), + dev->mmio + TRANSFER_SIZE_CONTROL); } /* protocol configuration */ if (cmd->scan_begin_src == TRIG_TIMER) { /* page 4-5, "input with internal REQs" */ - writeb(0, dev->mmio + OpMode); - writeb(0x00, dev->mmio + ClockReg); - writeb(1, dev->mmio + Sequence); - writeb(0x04, dev->mmio + ReqReg); - writeb(4, dev->mmio + BlockMode); - writeb(3, dev->mmio + LinePolarities); - writeb(0xc0, dev->mmio + AckSer); + writeb(0, dev->mmio + OP_MODE); + writeb(0x00, dev->mmio + CLOCK_REG); + writeb(1, dev->mmio + SEQUENCE); + writeb(0x04, dev->mmio + REQ_REG); + writeb(4, dev->mmio + BLOCK_MODE); + writeb(3, dev->mmio + LINE_POLARITIES); + writeb(0xc0, dev->mmio + ACK_SER); writel(ni_pcidio_ns_to_timer(&cmd->scan_begin_arg, CMDF_ROUND_NEAREST), - dev->mmio + StartDelay); - writeb(1, dev->mmio + ReqDelay); - writeb(1, dev->mmio + ReqNotDelay); - writeb(1, dev->mmio + AckDelay); - writeb(0x0b, dev->mmio + AckNotDelay); - writeb(0x01, dev->mmio + Data1Delay); + dev->mmio + START_DELAY); + writeb(1, dev->mmio + REQ_DELAY); + writeb(1, dev->mmio + REQ_NOT_DELAY); + writeb(1, dev->mmio + ACK_DELAY); + writeb(0x0b, dev->mmio + ACK_NOT_DELAY); + writeb(0x01, dev->mmio + DATA_1_DELAY); /* * manual, page 4-5: - * ClockSpeed comment is incorrectly listed on DAQOptions + * CLOCK_SPEED comment is incorrectly listed on DAQ_OPTIONS */ - writew(0, dev->mmio + ClockSpeed); - writeb(0, dev->mmio + DAQOptions); + writew(0, dev->mmio + CLOCK_SPEED); + writeb(0, dev->mmio + DAQ_OPTIONS); } else { /* TRIG_EXT */ /* page 4-5, "input with external REQs" */ - writeb(0, dev->mmio + OpMode); - writeb(0x00, dev->mmio + ClockReg); - writeb(0, dev->mmio + Sequence); - writeb(0x00, dev->mmio + ReqReg); - writeb(4, dev->mmio + BlockMode); + writeb(0, dev->mmio + OP_MODE); + writeb(0x00, dev->mmio + CLOCK_REG); + writeb(0, dev->mmio + SEQUENCE); + writeb(0x00, dev->mmio + REQ_REG); + writeb(4, dev->mmio + BLOCK_MODE); if (!(cmd->scan_begin_arg & CR_INVERT)) /* Leading Edge */ - writeb(0, dev->mmio + LinePolarities); + writeb(0, dev->mmio + LINE_POLARITIES); else /* Trailing Edge */ - writeb(2, dev->mmio + LinePolarities); - writeb(0x00, dev->mmio + AckSer); - writel(1, dev->mmio + StartDelay); - writeb(1, dev->mmio + ReqDelay); - writeb(1, dev->mmio + ReqNotDelay); - writeb(1, dev->mmio + AckDelay); - writeb(0x0C, dev->mmio + AckNotDelay); - writeb(0x10, dev->mmio + Data1Delay); - writew(0, dev->mmio + ClockSpeed); - writeb(0x60, dev->mmio + DAQOptions); + writeb(2, dev->mmio + LINE_POLARITIES); + writeb(0x00, dev->mmio + ACK_SER); + writel(1, dev->mmio + START_DELAY); + writeb(1, dev->mmio + REQ_DELAY); + writeb(1, dev->mmio + REQ_NOT_DELAY); + writeb(1, dev->mmio + ACK_DELAY); + writeb(0x0C, dev->mmio + ACK_NOT_DELAY); + writeb(0x10, dev->mmio + DATA_1_DELAY); + writew(0, dev->mmio + CLOCK_SPEED); + writeb(0x60, dev->mmio + DAQ_OPTIONS); } if (cmd->stop_src == TRIG_COUNT) { writel(cmd->stop_arg, - dev->mmio + Transfer_Count); + dev->mmio + TRANSFER_COUNT); } else { /* XXX */ } #ifdef USE_DMA - writeb(ClearPrimaryTC | ClearSecondaryTC, - dev->mmio + Group_1_First_Clear); + writeb(CLEAR_PRIMARY_TC | CLEAR_SECONDARY_TC, + dev->mmio + GROUP_1_FIRST_CLEAR); { int retval = setup_mite_dma(dev, s); @@ -701,25 +703,25 @@ static int ni_pcidio_cmd(struct comedi_device *dev, struct comedi_subdevice *s) return retval; } #else - writeb(0x00, dev->mmio + DMA_Line_Control_Group1); + writeb(0x00, dev->mmio + DMA_LINE_CONTROL_GROUP1); #endif - writeb(0x00, dev->mmio + DMA_Line_Control_Group2); + writeb(0x00, dev->mmio + DMA_LINE_CONTROL_GROUP2); /* clear and enable interrupts */ - writeb(0xff, dev->mmio + Group_1_First_Clear); - /* writeb(ClearExpired, dev->mmio+Group_1_Second_Clear); */ + writeb(0xff, dev->mmio + GROUP_1_FIRST_CLEAR); + /* writeb(CLEAR_EXPIRED, dev->mmio+GROUP_1_SECOND_CLEAR); */ - writeb(IntEn, dev->mmio + Interrupt_Control); - writeb(0x03, dev->mmio + Master_DMA_And_Interrupt_Control); + writeb(INT_EN, dev->mmio + INTERRUPT_CONTROL); + writeb(0x03, dev->mmio + MASTER_DMA_AND_INTERRUPT_CONTROL); if (cmd->stop_src == TRIG_NONE) { - devpriv->OpModeBits = DataLatching(0) | RunMode(7); + devpriv->OP_MODEBits = DATA_LATCHING(0) | RUN_MODE(7); } else { /* TRIG_TIMER */ - devpriv->OpModeBits = Numbered | RunMode(7); + devpriv->OP_MODEBits = NUMBERED | RUN_MODE(7); } if (cmd->start_src == TRIG_NOW) { /* start */ - writeb(devpriv->OpModeBits, dev->mmio + OpMode); + writeb(devpriv->OP_MODEBits, dev->mmio + OP_MODE); s->async->inttrig = NULL; } else { /* TRIG_INT */ @@ -732,7 +734,7 @@ static int ni_pcidio_cmd(struct comedi_device *dev, struct comedi_subdevice *s) static int ni_pcidio_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { - writeb(0x00, dev->mmio + Master_DMA_And_Interrupt_Control); + writeb(0x00, dev->mmio + MASTER_DMA_AND_INTERRUPT_CONTROL); ni_pcidio_release_di_mite_channel(dev); return 0; @@ -869,12 +871,12 @@ static int pci_6534_upload_firmware(struct comedi_device *dev) static void nidio_reset_board(struct comedi_device *dev) { - writel(0, dev->mmio + Port_IO(0)); - writel(0, dev->mmio + Port_Pin_Directions(0)); - writel(0, dev->mmio + Port_Pin_Mask(0)); + writel(0, dev->mmio + PORT_IO(0)); + writel(0, dev->mmio + PORT_PIN_DIRECTIONS(0)); + writel(0, dev->mmio + PORT_PIN_MASK(0)); /* disable interrupts on board */ - writeb(0, dev->mmio + Master_DMA_And_Interrupt_Control); + writeb(0, dev->mmio + MASTER_DMA_AND_INTERRUPT_CONTROL); } static int nidio_auto_attach(struct comedi_device *dev, @@ -925,7 +927,7 @@ static int nidio_auto_attach(struct comedi_device *dev, return ret; dev_info(dev->class_dev, "%s rev=%d\n", dev->board_name, - readb(dev->mmio + Chip_Version)); + readb(dev->mmio + CHIP_VERSION)); s = &dev->subdevices[0]; diff --git a/drivers/staging/comedi/drivers/ni_tio.c b/drivers/staging/comedi/drivers/ni_tio.c index 0eb388c0e1f0..048cb35723ad 100644 --- a/drivers/staging/comedi/drivers/ni_tio.c +++ b/drivers/staging/comedi/drivers/ni_tio.c @@ -224,13 +224,16 @@ static void ni_tio_set_bits_transient(struct ni_gpct *counter, unsigned int transient) { struct ni_gpct_device *counter_dev = counter->counter_dev; + unsigned int chip = counter->chip_index; unsigned long flags; - if (reg < NITIO_NUM_REGS) { + if (reg < NITIO_NUM_REGS && chip < counter_dev->num_chips) { + unsigned int *regs = counter_dev->regs[chip]; + spin_lock_irqsave(&counter_dev->regs_lock, flags); - counter_dev->regs[reg] &= ~mask; - counter_dev->regs[reg] |= (value & mask); - ni_tio_write(counter, counter_dev->regs[reg] | transient, reg); + regs[reg] &= ~mask; + regs[reg] |= (value & mask); + ni_tio_write(counter, regs[reg] | transient, reg); mmiowb(); spin_unlock_irqrestore(&counter_dev->regs_lock, flags); } @@ -267,12 +270,13 @@ unsigned int ni_tio_get_soft_copy(const struct ni_gpct *counter, enum ni_gpct_register reg) { struct ni_gpct_device *counter_dev = counter->counter_dev; + unsigned int chip = counter->chip_index; unsigned int value = 0; unsigned long flags; - if (reg < NITIO_NUM_REGS) { + if (reg < NITIO_NUM_REGS && chip < counter_dev->num_chips) { spin_lock_irqsave(&counter_dev->regs_lock, flags); - value = counter_dev->regs[reg]; + value = counter_dev->regs[chip][reg]; spin_unlock_irqrestore(&counter_dev->regs_lock, flags); } return value; @@ -302,6 +306,7 @@ static int ni_m_series_clock_src_select(const struct ni_gpct *counter, { struct ni_gpct_device *counter_dev = counter->counter_dev; unsigned int cidx = counter->counter_index; + unsigned int chip = counter->chip_index; unsigned int second_gate_reg = NITIO_GATE2_REG(cidx); unsigned int clock_source = 0; unsigned int src; @@ -318,7 +323,7 @@ static int ni_m_series_clock_src_select(const struct ni_gpct *counter, clock_source = NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS; break; case NI_M_TIMEBASE_3_CLK: - if (counter_dev->regs[second_gate_reg] & GI_SRC_SUBSEL) + if (counter_dev->regs[chip][second_gate_reg] & GI_SRC_SUBSEL) clock_source = NI_GPCT_ANALOG_TRIGGER_OUT_CLOCK_SRC_BITS; else @@ -328,7 +333,7 @@ static int ni_m_series_clock_src_select(const struct ni_gpct *counter, clock_source = NI_GPCT_LOGIC_LOW_CLOCK_SRC_BITS; break; case NI_M_NEXT_GATE_CLK: - if (counter_dev->regs[second_gate_reg] & GI_SRC_SUBSEL) + if (counter_dev->regs[chip][second_gate_reg] & GI_SRC_SUBSEL) clock_source = NI_GPCT_PXI_STAR_TRIGGER_CLOCK_SRC_BITS; else clock_source = NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS; @@ -721,6 +726,7 @@ static void ni_tio_set_source_subselect(struct ni_gpct *counter, { struct ni_gpct_device *counter_dev = counter->counter_dev; unsigned int cidx = counter->counter_index; + unsigned int chip = counter->chip_index; unsigned int second_gate_reg = NITIO_GATE2_REG(cidx); if (counter_dev->variant != ni_gpct_variant_m_series) @@ -729,18 +735,18 @@ static void ni_tio_set_source_subselect(struct ni_gpct *counter, /* Gi_Source_Subselect is zero */ case NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS: case NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS: - counter_dev->regs[second_gate_reg] &= ~GI_SRC_SUBSEL; + counter_dev->regs[chip][second_gate_reg] &= ~GI_SRC_SUBSEL; break; /* Gi_Source_Subselect is one */ case NI_GPCT_ANALOG_TRIGGER_OUT_CLOCK_SRC_BITS: case NI_GPCT_PXI_STAR_TRIGGER_CLOCK_SRC_BITS: - counter_dev->regs[second_gate_reg] |= GI_SRC_SUBSEL; + counter_dev->regs[chip][second_gate_reg] |= GI_SRC_SUBSEL; break; /* Gi_Source_Subselect doesn't matter */ default: return; } - ni_tio_write(counter, counter_dev->regs[second_gate_reg], + ni_tio_write(counter, counter_dev->regs[chip][second_gate_reg], second_gate_reg); } @@ -1116,6 +1122,7 @@ static int ni_tio_set_other_src(struct ni_gpct *counter, unsigned int index, { struct ni_gpct_device *counter_dev = counter->counter_dev; unsigned int cidx = counter->counter_index; + unsigned int chip = counter->chip_index; unsigned int abz_reg, shift, mask; if (counter_dev->variant != ni_gpct_variant_m_series) @@ -1141,9 +1148,9 @@ static int ni_tio_set_other_src(struct ni_gpct *counter, unsigned int index, if (source > 0x1f) source = 0x1f; /* Disable gate */ - counter_dev->regs[abz_reg] &= ~mask; - counter_dev->regs[abz_reg] |= (source << shift) & mask; - ni_tio_write(counter, counter_dev->regs[abz_reg], abz_reg); + counter_dev->regs[chip][abz_reg] &= ~mask; + counter_dev->regs[chip][abz_reg] |= (source << shift) & mask; + ni_tio_write(counter, counter_dev->regs[chip][abz_reg], abz_reg); return 0; } @@ -1632,6 +1639,7 @@ int ni_tio_insn_read(struct comedi_device *dev, struct ni_gpct_device *counter_dev = counter->counter_dev; unsigned int channel = CR_CHAN(insn->chanspec); unsigned int cidx = counter->counter_index; + unsigned int chip = counter->chip_index; int i; for (i = 0; i < insn->n; i++) { @@ -1640,10 +1648,12 @@ int ni_tio_insn_read(struct comedi_device *dev, data[i] = ni_tio_read_sw_save_reg(dev, s); break; case 1: - data[i] = counter_dev->regs[NITIO_LOADA_REG(cidx)]; + data[i] = + counter_dev->regs[chip][NITIO_LOADA_REG(cidx)]; break; case 2: - data[i] = counter_dev->regs[NITIO_LOADB_REG(cidx)]; + data[i] = + counter_dev->regs[chip][NITIO_LOADB_REG(cidx)]; break; } } @@ -1670,6 +1680,7 @@ int ni_tio_insn_write(struct comedi_device *dev, struct ni_gpct_device *counter_dev = counter->counter_dev; unsigned int channel = CR_CHAN(insn->chanspec); unsigned int cidx = counter->counter_index; + unsigned int chip = counter->chip_index; unsigned int load_reg; if (insn->n < 1) @@ -1690,14 +1701,15 @@ int ni_tio_insn_write(struct comedi_device *dev, ni_tio_set_bits_transient(counter, NITIO_CMD_REG(cidx), 0, 0, GI_LOAD); /* restore load reg */ - ni_tio_write(counter, counter_dev->regs[load_reg], load_reg); + ni_tio_write(counter, counter_dev->regs[chip][load_reg], + load_reg); break; case 1: - counter_dev->regs[NITIO_LOADA_REG(cidx)] = data[0]; + counter_dev->regs[chip][NITIO_LOADA_REG(cidx)] = data[0]; ni_tio_write(counter, data[0], NITIO_LOADA_REG(cidx)); break; case 2: - counter_dev->regs[NITIO_LOADB_REG(cidx)] = data[0]; + counter_dev->regs[chip][NITIO_LOADB_REG(cidx)] = data[0]; ni_tio_write(counter, data[0], NITIO_LOADB_REG(cidx)); break; default: @@ -1711,11 +1723,12 @@ void ni_tio_init_counter(struct ni_gpct *counter) { struct ni_gpct_device *counter_dev = counter->counter_dev; unsigned int cidx = counter->counter_index; + unsigned int chip = counter->chip_index; ni_tio_reset_count_and_disarm(counter); /* initialize counter registers */ - counter_dev->regs[NITIO_AUTO_INC_REG(cidx)] = 0x0; + counter_dev->regs[chip][NITIO_AUTO_INC_REG(cidx)] = 0x0; ni_tio_write(counter, 0x0, NITIO_AUTO_INC_REG(cidx)); ni_tio_set_bits(counter, NITIO_CMD_REG(cidx), @@ -1723,10 +1736,10 @@ void ni_tio_init_counter(struct ni_gpct *counter) ni_tio_set_bits(counter, NITIO_MODE_REG(cidx), ~0, 0); - counter_dev->regs[NITIO_LOADA_REG(cidx)] = 0x0; + counter_dev->regs[chip][NITIO_LOADA_REG(cidx)] = 0x0; ni_tio_write(counter, 0x0, NITIO_LOADA_REG(cidx)); - counter_dev->regs[NITIO_LOADB_REG(cidx)] = 0x0; + counter_dev->regs[chip][NITIO_LOADB_REG(cidx)] = 0x0; ni_tio_write(counter, 0x0, NITIO_LOADB_REG(cidx)); ni_tio_set_bits(counter, NITIO_INPUT_SEL_REG(cidx), ~0, 0); @@ -1735,7 +1748,7 @@ void ni_tio_init_counter(struct ni_gpct *counter) ni_tio_set_bits(counter, NITIO_CNT_MODE_REG(cidx), ~0, 0); if (ni_tio_has_gate2_registers(counter_dev)) { - counter_dev->regs[NITIO_GATE2_REG(cidx)] = 0x0; + counter_dev->regs[chip][NITIO_GATE2_REG(cidx)] = 0x0; ni_tio_write(counter, 0x0, NITIO_GATE2_REG(cidx)); } @@ -1776,9 +1789,16 @@ ni_gpct_device_construct(struct comedi_device *dev, spin_lock_init(&counter_dev->regs_lock); + counter_dev->num_counters = num_counters; + counter_dev->num_chips = DIV_ROUND_UP(num_counters, counters_per_chip); + counter_dev->counters = kcalloc(num_counters, sizeof(*counter), GFP_KERNEL); - if (!counter_dev->counters) { + counter_dev->regs = kcalloc(counter_dev->num_chips, + sizeof(*counter_dev->regs), GFP_KERNEL); + if (!counter_dev->regs || !counter_dev->counters) { + kfree(counter_dev->regs); + kfree(counter_dev->counters); kfree(counter_dev); return NULL; } @@ -1790,8 +1810,6 @@ ni_gpct_device_construct(struct comedi_device *dev, counter->counter_index = i % counters_per_chip; spin_lock_init(&counter->lock); } - counter_dev->num_counters = num_counters; - counter_dev->counters_per_chip = counters_per_chip; return counter_dev; } @@ -1801,6 +1819,7 @@ void ni_gpct_device_destroy(struct ni_gpct_device *counter_dev) { if (!counter_dev) return; + kfree(counter_dev->regs); kfree(counter_dev->counters); kfree(counter_dev); } diff --git a/drivers/staging/comedi/drivers/ni_tio.h b/drivers/staging/comedi/drivers/ni_tio.h index 1e85d0a53715..e7b05718df9b 100644 --- a/drivers/staging/comedi/drivers/ni_tio.h +++ b/drivers/staging/comedi/drivers/ni_tio.h @@ -107,8 +107,8 @@ struct ni_gpct_device { enum ni_gpct_variant variant; struct ni_gpct *counters; unsigned int num_counters; - unsigned int counters_per_chip; - unsigned int regs[NITIO_NUM_REGS]; + unsigned int num_chips; + unsigned int (*regs)[NITIO_NUM_REGS]; /* [num_chips][NITIO_NUM_REGS] */ spinlock_t regs_lock; /* protects 'regs' */ const struct ni_route_tables *routing_tables; /* link to routes */ }; diff --git a/drivers/staging/comedi/drivers/usbduxfast.c b/drivers/staging/comedi/drivers/usbduxfast.c index e18c0723b760..0d54f394dbd2 100644 --- a/drivers/staging/comedi/drivers/usbduxfast.c +++ b/drivers/staging/comedi/drivers/usbduxfast.c @@ -61,7 +61,7 @@ #define USBDUXFASTSUB_CPUCS 0xE600 /* - * max lenghth of the transfer-buffer for software upload + * max length of the transfer-buffer for software upload */ #define TB_LEN 0x2000 diff --git a/drivers/staging/emxx_udc/emxx_udc.c b/drivers/staging/emxx_udc/emxx_udc.c index 8e8f57c4f029..a913d40f0801 100644 --- a/drivers/staging/emxx_udc/emxx_udc.c +++ b/drivers/staging/emxx_udc/emxx_udc.c @@ -27,7 +27,7 @@ #include <linux/usb/gadget.h> #include <linux/irq.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include "emxx_udc.h" @@ -2220,7 +2220,7 @@ static inline void _nbu2ss_check_vbus(struct nbu2ss_udc *udc) mdelay(VBUS_CHATTERING_MDELAY); /* wait (ms) */ /* VBUS ON Check*/ - reg_dt = gpio_get_value(VBUS_VALUE); + reg_dt = gpiod_get_value(vbus_gpio); if (reg_dt == 0) { udc->linux_suspended = 0; @@ -2247,7 +2247,7 @@ static inline void _nbu2ss_check_vbus(struct nbu2ss_udc *udc) } } else { mdelay(5); /* wait (5ms) */ - reg_dt = gpio_get_value(VBUS_VALUE); + reg_dt = gpiod_get_value(vbus_gpio); if (reg_dt == 0) return; @@ -2311,7 +2311,7 @@ static inline void _nbu2ss_int_usb_suspend(struct nbu2ss_udc *udc) u32 reg_dt; if (udc->usb_suspended == 0) { - reg_dt = gpio_get_value(VBUS_VALUE); + reg_dt = gpiod_get_value(vbus_gpio); if (reg_dt == 0) return; @@ -2351,7 +2351,7 @@ static irqreturn_t _nbu2ss_udc_irq(int irq, void *_udc) struct nbu2ss_udc *udc = (struct nbu2ss_udc *)_udc; struct fc_regs __iomem *preg = udc->p_regs; - if (gpio_get_value(VBUS_VALUE) == 0) { + if (gpiod_get_value(vbus_gpio) == 0) { _nbu2ss_writel(&preg->USB_INT_STA, ~USB_INT_STA_RW); _nbu2ss_writel(&preg->USB_INT_ENA, 0); return IRQ_HANDLED; @@ -2360,7 +2360,7 @@ static irqreturn_t _nbu2ss_udc_irq(int irq, void *_udc) spin_lock(&udc->lock); for (;;) { - if (gpio_get_value(VBUS_VALUE) == 0) { + if (gpiod_get_value(vbus_gpio) == 0) { _nbu2ss_writel(&preg->USB_INT_STA, ~USB_INT_STA_RW); _nbu2ss_writel(&preg->USB_INT_ENA, 0); status = 0; @@ -2750,7 +2750,7 @@ static int nbu2ss_ep_fifo_status(struct usb_ep *_ep) preg = udc->p_regs; - data = gpio_get_value(VBUS_VALUE); + data = gpiod_get_value(vbus_gpio); if (data == 0) return -EINVAL; @@ -2790,7 +2790,7 @@ static void nbu2ss_ep_fifo_flush(struct usb_ep *_ep) return; } - data = gpio_get_value(VBUS_VALUE); + data = gpiod_get_value(vbus_gpio); if (data == 0) return; @@ -2832,7 +2832,7 @@ static int nbu2ss_gad_get_frame(struct usb_gadget *pgadget) } udc = container_of(pgadget, struct nbu2ss_udc, gadget); - data = gpio_get_value(VBUS_VALUE); + data = gpiod_get_value(vbus_gpio); if (data == 0) return -EINVAL; @@ -2854,7 +2854,7 @@ static int nbu2ss_gad_wakeup(struct usb_gadget *pgadget) udc = container_of(pgadget, struct nbu2ss_udc, gadget); - data = gpio_get_value(VBUS_VALUE); + data = gpiod_get_value(vbus_gpio); if (data == 0) { dev_warn(&pgadget->dev, "VBUS LEVEL = %d\n", data); return -EINVAL; @@ -3119,12 +3119,13 @@ static int nbu2ss_drv_probe(struct platform_device *pdev) } /* VBUS Interrupt */ - irq_set_irq_type(INT_VBUS, IRQ_TYPE_EDGE_BOTH); - status = request_irq(INT_VBUS, + vbus_irq = gpiod_to_irq(vbus_gpio); + irq_set_irq_type(vbus_irq, IRQ_TYPE_EDGE_BOTH); + status = request_irq(vbus_irq, _nbu2ss_vbus_irq, IRQF_SHARED, driver_name, udc); if (status != 0) { - dev_err(udc->dev, "request_irq(INT_VBUS) failed\n"); + dev_err(udc->dev, "request_irq(vbus_irq) failed\n"); return status; } @@ -3160,7 +3161,7 @@ static int nbu2ss_drv_remove(struct platform_device *pdev) } /* Interrupt Handler - Release */ - free_irq(INT_VBUS, udc); + free_irq(vbus_irq, udc); return 0; } @@ -3201,7 +3202,7 @@ static int nbu2ss_drv_resume(struct platform_device *pdev) if (!udc) return 0; - data = gpio_get_value(VBUS_VALUE); + data = gpiod_get_value(vbus_gpio); if (data) { udc->vbus_active = 1; udc->devstate = USB_STATE_POWERED; diff --git a/drivers/staging/emxx_udc/emxx_udc.h b/drivers/staging/emxx_udc/emxx_udc.h index e28a74da9633..b8c3dee5626c 100644 --- a/drivers/staging/emxx_udc/emxx_udc.h +++ b/drivers/staging/emxx_udc/emxx_udc.h @@ -30,6 +30,8 @@ /* below hacked up for staging integration */ #define GPIO_VBUS 0 /* GPIO_P153 on KZM9D */ #define INT_VBUS 0 /* IRQ for GPIO_P153 */ +struct gpio_desc *vbus_gpio; +int vbus_irq; /*------------ Board dependence(Wait) */ diff --git a/drivers/staging/erofs/Documentation/filesystems/erofs.txt b/drivers/staging/erofs/Documentation/filesystems/erofs.txt new file mode 100644 index 000000000000..961ec4da7705 --- /dev/null +++ b/drivers/staging/erofs/Documentation/filesystems/erofs.txt @@ -0,0 +1,208 @@ +Overview +======== + +EROFS file-system stands for Enhanced Read-Only File System. Different +from other read-only file systems, it aims to be designed for flexibility, +scalability, but be kept simple and high performance. + +It is designed as a better filesystem solution for the following scenarios: + - read-only storage media or + + - part of a fully trusted read-only solution, which means it needs to be + immutable and bit-for-bit identical to the official golden image for + their releases due to security and other considerations and + + - hope to save some extra storage space with guaranteed end-to-end performance + by using reduced metadata and transparent file compression, especially + for those embedded devices with limited memory (ex, smartphone); + +Here is the main features of EROFS: + - Little endian on-disk design; + + - Currently 4KB block size (nobh) and therefore maximum 16TB address space; + + - Metadata & data could be mixed by design; + + - 2 inode versions for different requirements: + v1 v2 + Inode metadata size: 32 bytes 64 bytes + Max file size: 4 GB 16 EB (also limited by max. vol size) + Max uids/gids: 65536 4294967296 + File creation time: no yes (64 + 32-bit timestamp) + Max hardlinks: 65536 4294967296 + Metadata reserved: 4 bytes 14 bytes + + - Support extended attributes (xattrs) as an option; + + - Support xattr inline and tail-end data inline for all files; + + - Support POSIX.1e ACLs by using xattrs; + + - Support transparent file compression as an option: + LZ4 algorithm with 4 KB fixed-output compression for high performance; + +The following git tree provides the file system user-space tools under +development (ex, formatting tool mkfs.erofs): +>> git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs-utils.git + +Bugs and patches are welcome, please kindly help us and send to the following +linux-erofs mailing list: +>> linux-erofs mailing list <linux-erofs@lists.ozlabs.org> + +Note that EROFS is still working in progress as a Linux staging driver, +Cc the staging mailing list as well is highly recommended: +>> Linux Driver Project Developer List <devel@driverdev.osuosl.org> + +Mount options +============= + +fault_injection=%d Enable fault injection in all supported types with + specified injection rate. Supported injection type: + Type_Name Type_Value + FAULT_KMALLOC 0x000000001 +(no)user_xattr Setup Extended User Attributes. Note: xattr is enabled + by default if CONFIG_EROFS_FS_XATTR is selected. +(no)acl Setup POSIX Access Control List. Note: acl is enabled + by default if CONFIG_EROFS_FS_POSIX_ACL is selected. + +On-disk details +=============== + +Summary +------- +Different from other read-only file systems, an EROFS volume is designed +to be as simple as possible: + + |-> aligned with the block size + ____________________________________________________________ + | |SB| | ... | Metadata | ... | Data | Metadata | ... | Data | + |_|__|_|_____|__________|_____|______|__________|_____|______| + 0 +1K + +All data areas should be aligned with the block size, but metadata areas +may not. All metadatas can be now observed in two different spaces (views): + 1. Inode metadata space + Each valid inode should be aligned with an inode slot, which is a fixed + value (32 bytes) and designed to be kept in line with v1 inode size. + + Each inode can be directly found with the following formula: + inode offset = meta_blkaddr * block_size + 32 * nid + + |-> aligned with 8B + |-> followed closely + + meta_blkaddr blocks |-> another slot + _____________________________________________________________________ + | ... | inode | xattrs | extents | data inline | ... | inode ... + |________|_______|(optional)|(optional)|__(optional)_|_____|__________ + |-> aligned with the inode slot size + . . + . . + . . + . . + . . + . . + .____________________________________________________|-> aligned with 4B + | xattr_ibody_header | shared xattrs | inline xattrs | + |____________________|_______________|_______________| + |-> 12 bytes <-|->x * 4 bytes<-| . + . . . + . . . + . . . + ._______________________________.______________________. + | id | id | id | id | ... | id | ent | ... | ent| ... | + |____|____|____|____|______|____|_____|_____|____|_____| + |-> aligned with 4B + |-> aligned with 4B + + Inode could be 32 or 64 bytes, which can be distinguished from a common + field which all inode versions have -- i_advise: + + __________________ __________________ + | i_advise | | i_advise | + |__________________| |__________________| + | ... | | ... | + | | | | + |__________________| 32 bytes | | + | | + |__________________| 64 bytes + + Xattrs, extents, data inline are followed by the corresponding inode with + proper alignes, and they could be optional for different data mappings, + _currently_ there are totally 3 valid data mappings supported: + + 1) flat file data without data inline (no extent); + 2) fixed-output size data compression (must have extents); + 3) flat file data with tail-end data inline (no extent); + + The size of the optional xattrs is indicated by i_xattr_count in inode + header. Large xattrs or xattrs shared by many different files can be + stored in shared xattrs metadata rather than inlined right after inode. + + 2. Shared xattrs metadata space + Shared xattrs space is similar to the above inode space, started with + a specific block indicated by xattr_blkaddr, organized one by one with + proper align. + + Each share xattr can also be directly found by the following formula: + xattr offset = xattr_blkaddr * block_size + 4 * xattr_id + + |-> aligned by 4 bytes + + xattr_blkaddr blocks |-> aligned with 4 bytes + _________________________________________________________________________ + | ... | xattr_entry | xattr data | ... | xattr_entry | xattr data ... + |________|_____________|_____________|_____|______________|_______________ + +Directories +----------- +All directories are now organized in a compact on-disk format. Note that +each directory block is divided into index and name areas in order to support +random file lookup, and all directory entries are _strictly_ recorded in +alphabetical order in order to support improved prefix binary search +algorithm (could refer to the related source code). + + ___________________________ + / | + / ______________|________________ + / / | nameoff1 | nameoffN-1 + ____________.______________._______________v________________v__________ +| dirent | dirent | ... | dirent | filename | filename | ... | filename | +|___.0___|____1___|_____|___N-1__|____0_____|____1_____|_____|___N-1____| + \ ^ + \ | * could have + \ | trailing '\0' + \________________________| nameoff0 + + Directory block + +Note that apart from the offset of the first filename, nameoff0 also indicates +the total number of directory entries in this block since it is no need to +introduce another on-disk field at all. + +Compression +----------- +Currently, EROFS supports 4KB fixed-output clustersize transparent file +compression, as illustrated below: + + |---- Variant-Length Extent ----|-------- VLE --------|----- VLE ----- + clusterofs clusterofs clusterofs + | | | logical data +_________v_______________________________v_____________________v_______________ +... | . | | . | | . | ... +____|____.________|_____________|________.____|_____________|__.__________|____ + |-> cluster <-|-> cluster <-|-> cluster <-|-> cluster <-|-> cluster <-| + size size size size size + . . . . + . . . . + . . . . + _______._____________._____________._____________._____________________ + ... | | | | ... physical data + _______|_____________|_____________|_____________|_____________________ + |-> cluster <-|-> cluster <-|-> cluster <-| + size size size + +Currently each on-disk physical cluster can contain 4KB (un)compressed data +at most. For each logical cluster, there is a corresponding on-disk index to +describe its cluster type, physical cluster address, etc. + +See "struct z_erofs_vle_decompressed_index" in erofs_fs.h for more details. + diff --git a/drivers/staging/erofs/Makefile b/drivers/staging/erofs/Makefile index c91b65223f99..38ab344a285e 100644 --- a/drivers/staging/erofs/Makefile +++ b/drivers/staging/erofs/Makefile @@ -6,7 +6,7 @@ ccflags-y += -Wall -DEROFS_VERSION=\"$(EROFS_VERSION)\" obj-$(CONFIG_EROFS_FS) += erofs.o # staging requirement: to be self-contained in its own directory -ccflags-y += -I$(src)/include +ccflags-y += -I $(srctree)/$(src)/include erofs-objs := super.o inode.o data.o namei.o dir.o utils.o erofs-$(CONFIG_EROFS_FS_XATTR) += xattr.o erofs-$(CONFIG_EROFS_FS_ZIP) += unzip_vle.o unzip_vle_lz4.o diff --git a/drivers/staging/erofs/data.c b/drivers/staging/erofs/data.c index 5a55f0bfdfbb..526e0dbea5b5 100644 --- a/drivers/staging/erofs/data.c +++ b/drivers/staging/erofs/data.c @@ -20,8 +20,9 @@ static inline void read_endio(struct bio *bio) int i; struct bio_vec *bvec; const blk_status_t err = bio->bi_status; + struct bvec_iter_all iter_all; - bio_for_each_segment_all(bvec, bio, i) { + bio_for_each_segment_all(bvec, bio, i, iter_all) { struct page *page = bvec->bv_page; /* page is already locked */ @@ -165,43 +166,16 @@ err_out: return err; } -#ifdef CONFIG_EROFS_FS_ZIP -extern int z_erofs_map_blocks_iter(struct inode *, - struct erofs_map_blocks *, - struct page **, int); -#endif - -int erofs_map_blocks_iter(struct inode *inode, - struct erofs_map_blocks *map, - struct page **mpage_ret, int flags) -{ - /* by default, reading raw data never use erofs_map_blocks_iter */ - if (unlikely(!is_inode_layout_compression(inode))) { - if (*mpage_ret) - put_page(*mpage_ret); - *mpage_ret = NULL; - - return erofs_map_blocks(inode, map, flags); - } - -#ifdef CONFIG_EROFS_FS_ZIP - return z_erofs_map_blocks_iter(inode, map, mpage_ret, flags); -#else - /* data compression is not available */ - return -ENOTSUPP; -#endif -} - int erofs_map_blocks(struct inode *inode, struct erofs_map_blocks *map, int flags) { if (unlikely(is_inode_layout_compression(inode))) { - struct page *mpage = NULL; - int err; + int err = z_erofs_map_blocks_iter(inode, map, flags); - err = erofs_map_blocks_iter(inode, map, &mpage, flags); - if (mpage) - put_page(mpage); + if (map->mpage) { + put_page(map->mpage); + map->mpage = NULL; + } return err; } return erofs_map_blocks_flatmode(inode, map, flags); diff --git a/drivers/staging/erofs/dir.c b/drivers/staging/erofs/dir.c index 833f052f79d0..829f7b12e0dc 100644 --- a/drivers/staging/erofs/dir.c +++ b/drivers/staging/erofs/dir.c @@ -24,8 +24,8 @@ static const unsigned char erofs_filetype_table[EROFS_FT_MAX] = { }; static int erofs_fill_dentries(struct dir_context *ctx, - void *dentry_blk, unsigned int *ofs, - unsigned int nameoff, unsigned int maxsize) + void *dentry_blk, unsigned int *ofs, + unsigned int nameoff, unsigned int maxsize) { struct erofs_dirent *de = dentry_blk; const struct erofs_dirent *end = dentry_blk + nameoff; @@ -98,15 +98,14 @@ static int erofs_readdir(struct file *f, struct dir_context *ctx) if (IS_ERR(dentry_page)) continue; - lock_page(dentry_page); de = (struct erofs_dirent *)kmap(dentry_page); nameoff = le16_to_cpu(de->nameoff); if (unlikely(nameoff < sizeof(struct erofs_dirent) || - nameoff >= PAGE_SIZE)) { + nameoff >= PAGE_SIZE)) { errln("%s, invalid de[0].nameoff %u", - __func__, nameoff); + __func__, nameoff); err = -EIO; goto skip_this; @@ -128,7 +127,6 @@ static int erofs_readdir(struct file *f, struct dir_context *ctx) skip_this: kunmap(dentry_page); - unlock_page(dentry_page); put_page(dentry_page); ctx->pos = blknr_to_addr(i) + ofs; @@ -144,6 +142,6 @@ skip_this: const struct file_operations erofs_dir_fops = { .llseek = generic_file_llseek, .read = generic_read_dir, - .iterate = erofs_readdir, + .iterate_shared = erofs_readdir, }; diff --git a/drivers/staging/erofs/inode.c b/drivers/staging/erofs/inode.c index d7fbf5f4600f..924b8dfc7a8f 100644 --- a/drivers/staging/erofs/inode.c +++ b/drivers/staging/erofs/inode.c @@ -184,32 +184,18 @@ static int fill_inode(struct inode *inode, int isdir) if (!err) { /* setup the new inode */ if (S_ISREG(inode->i_mode)) { -#ifdef CONFIG_EROFS_FS_XATTR - if (vi->xattr_isize) - inode->i_op = &erofs_generic_xattr_iops; -#endif + inode->i_op = &erofs_generic_iops; inode->i_fop = &generic_ro_fops; } else if (S_ISDIR(inode->i_mode)) { - inode->i_op = -#ifdef CONFIG_EROFS_FS_XATTR - vi->xattr_isize ? &erofs_dir_xattr_iops : -#endif - &erofs_dir_iops; + inode->i_op = &erofs_dir_iops; inode->i_fop = &erofs_dir_fops; } else if (S_ISLNK(inode->i_mode)) { /* by default, page_get_link is used for symlink */ - inode->i_op = -#ifdef CONFIG_EROFS_FS_XATTR - &erofs_symlink_xattr_iops, -#else - &page_symlink_inode_operations; -#endif + inode->i_op = &erofs_symlink_iops; inode_nohighmem(inode); } else if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode) || S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) { -#ifdef CONFIG_EROFS_FS_XATTR - inode->i_op = &erofs_special_inode_operations; -#endif + inode->i_op = &erofs_generic_iops; init_special_inode(inode, inode->i_mode, inode->i_rdev); } else { err = -EIO; @@ -297,23 +283,26 @@ struct inode *erofs_iget(struct super_block *sb, return inode; } +const struct inode_operations erofs_generic_iops = { #ifdef CONFIG_EROFS_FS_XATTR -const struct inode_operations erofs_generic_xattr_iops = { .listxattr = erofs_listxattr, +#endif + .get_acl = erofs_get_acl, }; -const struct inode_operations erofs_symlink_xattr_iops = { +const struct inode_operations erofs_symlink_iops = { .get_link = page_get_link, +#ifdef CONFIG_EROFS_FS_XATTR .listxattr = erofs_listxattr, +#endif + .get_acl = erofs_get_acl, }; -const struct inode_operations erofs_special_inode_operations = { - .listxattr = erofs_listxattr, -}; - -const struct inode_operations erofs_fast_symlink_xattr_iops = { +const struct inode_operations erofs_fast_symlink_iops = { .get_link = simple_get_link, +#ifdef CONFIG_EROFS_FS_XATTR .listxattr = erofs_listxattr, -}; #endif + .get_acl = erofs_get_acl, +}; diff --git a/drivers/staging/erofs/internal.h b/drivers/staging/erofs/internal.h index e049d00c087a..e3bfde00c7d2 100644 --- a/drivers/staging/erofs/internal.h +++ b/drivers/staging/erofs/internal.h @@ -252,47 +252,20 @@ static inline int erofs_wait_on_workgroup_freezed(struct erofs_workgroup *grp) } #endif -static inline bool erofs_workgroup_get(struct erofs_workgroup *grp, int *ocnt) -{ - int o; - -repeat: - o = erofs_wait_on_workgroup_freezed(grp); - - if (unlikely(o <= 0)) - return -1; - - if (unlikely(atomic_cmpxchg(&grp->refcount, o, o + 1) != o)) - goto repeat; - - *ocnt = o; - return 0; -} - -#define __erofs_workgroup_get(grp) atomic_inc(&(grp)->refcount) -#define __erofs_workgroup_put(grp) atomic_dec(&(grp)->refcount) - -extern int erofs_workgroup_put(struct erofs_workgroup *grp); - -extern struct erofs_workgroup *erofs_find_workgroup( - struct super_block *sb, pgoff_t index, bool *tag); - -extern int erofs_register_workgroup(struct super_block *sb, - struct erofs_workgroup *grp, bool tag); - -extern unsigned long erofs_shrink_workstation(struct erofs_sb_info *sbi, - unsigned long nr_shrink, bool cleanup); - -static inline void erofs_workstation_cleanup_all(struct super_block *sb) -{ - erofs_shrink_workstation(EROFS_SB(sb), ~0UL, true); -} +int erofs_workgroup_put(struct erofs_workgroup *grp); +struct erofs_workgroup *erofs_find_workgroup(struct super_block *sb, + pgoff_t index, bool *tag); +int erofs_register_workgroup(struct super_block *sb, + struct erofs_workgroup *grp, bool tag); +unsigned long erofs_shrink_workstation(struct erofs_sb_info *sbi, + unsigned long nr_shrink, bool cleanup); +void erofs_workgroup_free_rcu(struct erofs_workgroup *grp); #ifdef EROFS_FS_HAS_MANAGED_CACHE -extern int erofs_try_to_free_all_cached_pages(struct erofs_sb_info *sbi, - struct erofs_workgroup *egrp); -extern int erofs_try_to_free_cached_page(struct address_space *mapping, - struct page *page); +int erofs_try_to_free_all_cached_pages(struct erofs_sb_info *sbi, + struct erofs_workgroup *egrp); +int erofs_try_to_free_cached_page(struct address_space *mapping, + struct page *page); #define MNGD_MAPPING(sbi) ((sbi)->managed_cache->i_mapping) #else @@ -354,12 +327,17 @@ static inline erofs_off_t iloc(struct erofs_sb_info *sbi, erofs_nid_t nid) return blknr_to_addr(sbi->meta_blkaddr) + (nid << sbi->islotbits); } -#define inode_set_inited_xattr(inode) (EROFS_V(inode)->flags |= 1) -#define inode_has_inited_xattr(inode) (EROFS_V(inode)->flags & 1) +/* atomic flag definitions */ +#define EROFS_V_EA_INITED_BIT 0 + +/* bitlock definitions (arranged in reverse order) */ +#define EROFS_V_BL_XATTR_BIT (BITS_PER_LONG - 1) struct erofs_vnode { erofs_nid_t nid; - unsigned int flags; + + /* atomic flags (including bitlocks) */ + unsigned long flags; unsigned char data_mapping_mode; /* inline size in bytes */ @@ -412,8 +390,6 @@ static inline bool is_inode_layout_inline(struct inode *inode) } extern const struct super_operations erofs_sops; -extern const struct inode_operations erofs_dir_iops; -extern const struct file_operations erofs_dir_fops; extern const struct address_space_operations erofs_raw_access_aops; #ifdef CONFIG_EROFS_FS_ZIP @@ -461,11 +437,26 @@ struct erofs_map_blocks { u64 m_plen, m_llen; unsigned int m_flags; + + struct page *mpage; }; /* Flags used by erofs_map_blocks() */ #define EROFS_GET_BLOCKS_RAW 0x0001 +#ifdef CONFIG_EROFS_FS_ZIP +int z_erofs_map_blocks_iter(struct inode *inode, + struct erofs_map_blocks *map, + int flags); +#else +static inline int z_erofs_map_blocks_iter(struct inode *inode, + struct erofs_map_blocks *map, + int flags) +{ + return -ENOTSUPP; +} +#endif + /* data.c */ static inline struct bio * erofs_grab_bio(struct super_block *sb, @@ -506,8 +497,8 @@ static inline void __submit_bio(struct bio *bio, unsigned op, unsigned op_flags) #define EROFS_IO_MAX_RETRIES_NOFAIL CONFIG_EROFS_FS_IO_MAX_RETRIES #endif -extern struct page *__erofs_get_meta_page(struct super_block *sb, - erofs_blk_t blkaddr, bool prio, bool nofail); +struct page *__erofs_get_meta_page(struct super_block *sb, erofs_blk_t blkaddr, + bool prio, bool nofail); static inline struct page *erofs_get_meta_page(struct super_block *sb, erofs_blk_t blkaddr, bool prio) @@ -521,15 +512,7 @@ static inline struct page *erofs_get_meta_page_nofail(struct super_block *sb, return __erofs_get_meta_page(sb, blkaddr, prio, true); } -extern int erofs_map_blocks(struct inode *, struct erofs_map_blocks *, int); -extern int erofs_map_blocks_iter(struct inode *, struct erofs_map_blocks *, - struct page **, int); - -struct erofs_map_blocks_iter { - struct erofs_map_blocks map; - struct page *mpage; -}; - +int erofs_map_blocks(struct inode *, struct erofs_map_blocks *, int); static inline struct page * erofs_get_inline_page(struct inode *inode, @@ -549,41 +532,31 @@ static inline unsigned long erofs_inode_hash(erofs_nid_t nid) #endif } -extern struct inode *erofs_iget(struct super_block *sb, - erofs_nid_t nid, bool dir); - -/* dir.c */ -int erofs_namei(struct inode *dir, struct qstr *name, - erofs_nid_t *nid, unsigned *d_type); - -#ifdef CONFIG_EROFS_FS_XATTR -/* xattr.c */ -extern const struct xattr_handler *erofs_xattr_handlers[]; - -/* symlink and special inode */ -extern const struct inode_operations erofs_symlink_xattr_iops; -extern const struct inode_operations erofs_fast_symlink_xattr_iops; -extern const struct inode_operations erofs_special_inode_operations; -#endif +extern const struct inode_operations erofs_generic_iops; +extern const struct inode_operations erofs_symlink_iops; +extern const struct inode_operations erofs_fast_symlink_iops; static inline void set_inode_fast_symlink(struct inode *inode) { -#ifdef CONFIG_EROFS_FS_XATTR - inode->i_op = &erofs_fast_symlink_xattr_iops; -#else - inode->i_op = &simple_symlink_inode_operations; -#endif + inode->i_op = &erofs_fast_symlink_iops; } static inline bool is_inode_fast_symlink(struct inode *inode) { -#ifdef CONFIG_EROFS_FS_XATTR - return inode->i_op == &erofs_fast_symlink_xattr_iops; -#else - return inode->i_op == &simple_symlink_inode_operations; -#endif + return inode->i_op == &erofs_fast_symlink_iops; } +struct inode *erofs_iget(struct super_block *sb, erofs_nid_t nid, bool dir); + +/* namei.c */ +extern const struct inode_operations erofs_dir_iops; + +int erofs_namei(struct inode *dir, struct qstr *name, + erofs_nid_t *nid, unsigned int *d_type); + +/* dir.c */ +extern const struct file_operations erofs_dir_fops; + static inline void *erofs_vmap(struct page **pages, unsigned int count) { #ifdef CONFIG_EROFS_FS_USE_VM_MAP_RAM @@ -612,15 +585,11 @@ static inline void erofs_vunmap(const void *mem, unsigned int count) } /* utils.c */ -extern struct page *erofs_allocpage(struct list_head *pool, gfp_t gfp); - -extern void erofs_register_super(struct super_block *sb); -extern void erofs_unregister_super(struct super_block *sb); +extern struct shrinker erofs_shrinker_info; -extern unsigned long erofs_shrink_count(struct shrinker *shrink, - struct shrink_control *sc); -extern unsigned long erofs_shrink_scan(struct shrinker *shrink, - struct shrink_control *sc); +struct page *erofs_allocpage(struct list_head *pool, gfp_t gfp); +void erofs_register_super(struct super_block *sb); +void erofs_unregister_super(struct super_block *sb); #ifndef lru_to_page #define lru_to_page(head) (list_entry((head)->prev, struct page, lru)) diff --git a/drivers/staging/erofs/namei.c b/drivers/staging/erofs/namei.c index 5596c52e246d..3f4fa52c10fa 100644 --- a/drivers/staging/erofs/namei.c +++ b/drivers/staging/erofs/namei.c @@ -15,74 +15,77 @@ #include <trace/events/erofs.h> -/* based on the value of qn->len is accurate */ -static inline int dirnamecmp(struct qstr *qn, - struct qstr *qd, unsigned int *matched) +struct erofs_qstr { + const unsigned char *name; + const unsigned char *end; +}; + +/* based on the end of qn is accurate and it must have the trailing '\0' */ +static inline int dirnamecmp(const struct erofs_qstr *qn, + const struct erofs_qstr *qd, + unsigned int *matched) { - unsigned int i = *matched, len = min(qn->len, qd->len); -loop: - if (unlikely(i >= len)) { - *matched = i; - if (qn->len < qd->len) { - /* - * actually (qn->len == qd->len) - * when qd->name[i] == '\0' - */ - return qd->name[i] == '\0' ? 0 : -1; + unsigned int i = *matched; + + /* + * on-disk error, let's only BUG_ON in the debugging mode. + * otherwise, it will return 1 to just skip the invalid name + * and go on (in consideration of the lookup performance). + */ + DBG_BUGON(qd->name > qd->end); + + /* qd could not have trailing '\0' */ + /* However it is absolutely safe if < qd->end */ + while (qd->name + i < qd->end && qd->name[i] != '\0') { + if (qn->name[i] != qd->name[i]) { + *matched = i; + return qn->name[i] > qd->name[i] ? 1 : -1; } - return (qn->len > qd->len); - } - - if (qn->name[i] != qd->name[i]) { - *matched = i; - return qn->name[i] > qd->name[i] ? 1 : -1; + ++i; } - - ++i; - goto loop; + *matched = i; + /* See comments in __d_alloc on the terminating NUL character */ + return qn->name[i] == '\0' ? 0 : 1; } -static struct erofs_dirent *find_target_dirent( - struct qstr *name, - u8 *data, int maxsize) +#define nameoff_from_disk(off, sz) (le16_to_cpu(off) & ((sz) - 1)) + +static struct erofs_dirent *find_target_dirent(struct erofs_qstr *name, + u8 *data, + unsigned int dirblksize, + const int ndirents) { - unsigned int ndirents, head, back; + int head, back; unsigned int startprfx, endprfx; struct erofs_dirent *const de = (struct erofs_dirent *)data; - /* make sure that maxsize is valid */ - BUG_ON(maxsize < sizeof(struct erofs_dirent)); - - ndirents = le16_to_cpu(de->nameoff) / sizeof(*de); - - /* corrupted dir (may be unnecessary...) */ - BUG_ON(!ndirents); - - head = 0; + /* since the 1st dirent has been evaluated previously */ + head = 1; back = ndirents - 1; startprfx = endprfx = 0; while (head <= back) { - unsigned int mid = head + (back - head) / 2; - unsigned int nameoff = le16_to_cpu(de[mid].nameoff); + const int mid = head + (back - head) / 2; + const int nameoff = nameoff_from_disk(de[mid].nameoff, + dirblksize); unsigned int matched = min(startprfx, endprfx); - - struct qstr dname = QSTR_INIT(data + nameoff, - unlikely(mid >= ndirents - 1) ? - maxsize - nameoff : - le16_to_cpu(de[mid + 1].nameoff) - nameoff); + struct erofs_qstr dname = { + .name = data + nameoff, + .end = unlikely(mid >= ndirents - 1) ? + data + dirblksize : + data + nameoff_from_disk(de[mid + 1].nameoff, + dirblksize) + }; /* string comparison without already matched prefix */ int ret = dirnamecmp(name, &dname, &matched); - if (unlikely(!ret)) + if (unlikely(!ret)) { return de + mid; - else if (ret > 0) { + } else if (ret > 0) { head = mid + 1; startprfx = matched; - } else if (unlikely(mid < 1)) /* fix "mid" overflow */ - break; - else { + } else { back = mid - 1; endprfx = matched; } @@ -91,12 +94,12 @@ static struct erofs_dirent *find_target_dirent( return ERR_PTR(-ENOENT); } -static struct page *find_target_block_classic( - struct inode *dir, - struct qstr *name, int *_diff) +static struct page *find_target_block_classic(struct inode *dir, + struct erofs_qstr *name, + int *_ndirents) { unsigned int startprfx, endprfx; - unsigned int head, back; + int head, back; struct address_space *const mapping = dir->i_mapping; struct page *candidate = ERR_PTR(-ENOENT); @@ -105,89 +108,97 @@ static struct page *find_target_block_classic( back = inode_datablocks(dir) - 1; while (head <= back) { - unsigned int mid = head + (back - head) / 2; + const int mid = head + (back - head) / 2; struct page *page = read_mapping_page(mapping, mid, NULL); - if (IS_ERR(page)) { -exact_out: - if (!IS_ERR(candidate)) /* valid candidate */ - put_page(candidate); - return page; - } else { - int diff; - unsigned int ndirents, matched; - struct qstr dname; + if (!IS_ERR(page)) { struct erofs_dirent *de = kmap_atomic(page); - unsigned int nameoff = le16_to_cpu(de->nameoff); - - ndirents = nameoff / sizeof(*de); + const int nameoff = nameoff_from_disk(de->nameoff, + EROFS_BLKSIZ); + const int ndirents = nameoff / sizeof(*de); + int diff; + unsigned int matched; + struct erofs_qstr dname; - /* corrupted dir (should have one entry at least) */ - BUG_ON(!ndirents || nameoff > PAGE_SIZE); + if (unlikely(!ndirents)) { + DBG_BUGON(1); + kunmap_atomic(de); + put_page(page); + page = ERR_PTR(-EIO); + goto out; + } matched = min(startprfx, endprfx); dname.name = (u8 *)de + nameoff; - dname.len = ndirents == 1 ? - /* since the rest of the last page is 0 */ - EROFS_BLKSIZ - nameoff - : le16_to_cpu(de[1].nameoff) - nameoff; + if (ndirents == 1) + dname.end = (u8 *)de + EROFS_BLKSIZ; + else + dname.end = (u8 *)de + + nameoff_from_disk(de[1].nameoff, + EROFS_BLKSIZ); /* string comparison without already matched prefix */ diff = dirnamecmp(name, &dname, &matched); kunmap_atomic(de); if (unlikely(!diff)) { - *_diff = 0; - goto exact_out; + *_ndirents = 0; + goto out; } else if (diff > 0) { head = mid + 1; startprfx = matched; - if (likely(!IS_ERR(candidate))) + if (!IS_ERR(candidate)) put_page(candidate); candidate = page; + *_ndirents = ndirents; } else { put_page(page); - if (unlikely(mid < 1)) /* fix "mid" overflow */ - break; - back = mid - 1; endprfx = matched; } + continue; } +out: /* free if the candidate is valid */ + if (!IS_ERR(candidate)) + put_page(candidate); + return page; } - *_diff = 1; return candidate; } int erofs_namei(struct inode *dir, - struct qstr *name, - erofs_nid_t *nid, unsigned int *d_type) + struct qstr *name, + erofs_nid_t *nid, unsigned int *d_type) { - int diff; + int ndirents; struct page *page; - u8 *data; + void *data; struct erofs_dirent *de; + struct erofs_qstr qn; if (unlikely(!dir->i_size)) return -ENOENT; - diff = 1; - page = find_target_block_classic(dir, name, &diff); + qn.name = name->name; + qn.end = name->name + name->len; + + ndirents = 0; + page = find_target_block_classic(dir, &qn, &ndirents); - if (unlikely(IS_ERR(page))) + if (IS_ERR(page)) return PTR_ERR(page); data = kmap_atomic(page); /* the target page has been mapped */ - de = likely(diff) ? - /* since the rest of the last page is 0 */ - find_target_dirent(name, data, EROFS_BLKSIZ) : - (struct erofs_dirent *)data; + if (ndirents) + de = find_target_dirent(&qn, data, EROFS_BLKSIZ, ndirents); + else + de = (struct erofs_dirent *)data; - if (likely(!IS_ERR(de))) { + if (!IS_ERR(de)) { *nid = le64_to_cpu(de->nid); *d_type = de->file_type; } @@ -235,12 +246,9 @@ static struct dentry *erofs_lookup(struct inode *dir, const struct inode_operations erofs_dir_iops = { .lookup = erofs_lookup, -}; - -const struct inode_operations erofs_dir_xattr_iops = { - .lookup = erofs_lookup, #ifdef CONFIG_EROFS_FS_XATTR .listxattr = erofs_listxattr, #endif + .get_acl = erofs_get_acl, }; diff --git a/drivers/staging/erofs/super.c b/drivers/staging/erofs/super.c index 1c2eb69682ef..15c784fba879 100644 --- a/drivers/staging/erofs/super.c +++ b/drivers/staging/erofs/super.c @@ -16,6 +16,7 @@ #include <linux/parser.h> #include <linux/seq_file.h> #include "internal.h" +#include "xattr.h" #define CREATE_TRACE_POINTS #include <trace/events/erofs.h> @@ -397,6 +398,11 @@ static int erofs_read_super(struct super_block *sb, if (!silent) infoln("root inode @ nid %llu", ROOT_NID(sbi)); + if (test_opt(sbi, POSIX_ACL)) + sb->s_flags |= SB_POSIXACL; + else + sb->s_flags &= ~SB_POSIXACL; + #ifdef CONFIG_EROFS_FS_ZIP INIT_RADIX_TREE(&sbi->workstn_tree, GFP_ATOMIC); #endif @@ -420,13 +426,14 @@ static int erofs_read_super(struct super_block *sb, errln("rootino(nid %llu) is not a directory(i_mode %o)", ROOT_NID(sbi), inode->i_mode); err = -EINVAL; - goto err_isdir; + iput(inode); + goto err_iget; } sb->s_root = d_make_root(inode); if (sb->s_root == NULL) { err = -ENOMEM; - goto err_makeroot; + goto err_iget; } /* save the device name to sbi */ @@ -452,10 +459,6 @@ static int erofs_read_super(struct super_block *sb, */ err_devname: dput(sb->s_root); -err_makeroot: -err_isdir: - if (sb->s_root == NULL) - iput(inode); err_iget: #ifdef EROFS_FS_HAS_MANAGED_CACHE iput(sbi->managed_cache); @@ -493,7 +496,8 @@ static void erofs_put_super(struct super_block *sb) mutex_lock(&sbi->umount_mutex); #ifdef CONFIG_EROFS_FS_ZIP - erofs_workstation_cleanup_all(sb); + /* clean up the compression space of this sb */ + erofs_shrink_workstation(EROFS_SB(sb), ~0UL, true); #endif erofs_unregister_super(sb); @@ -537,12 +541,6 @@ static void erofs_kill_sb(struct super_block *sb) kill_block_super(sb); } -static struct shrinker erofs_shrinker_info = { - .scan_objects = erofs_shrink_scan, - .count_objects = erofs_shrink_count, - .seeks = DEFAULT_SEEKS, -}; - static struct file_system_type erofs_fs_type = { .owner = THIS_MODULE, .name = "erofs", @@ -653,6 +651,11 @@ static int erofs_remount(struct super_block *sb, int *flags, char *data) if (err) goto out; + if (test_opt(sbi, POSIX_ACL)) + sb->s_flags |= SB_POSIXACL; + else + sb->s_flags &= ~SB_POSIXACL; + *flags |= SB_RDONLY; return 0; out: diff --git a/drivers/staging/erofs/unzip_vle.c b/drivers/staging/erofs/unzip_vle.c index 4ac1099a39c6..8715bc50e09c 100644 --- a/drivers/staging/erofs/unzip_vle.c +++ b/drivers/staging/erofs/unzip_vle.c @@ -107,15 +107,30 @@ enum z_erofs_vle_work_role { Z_EROFS_VLE_WORK_SECONDARY, Z_EROFS_VLE_WORK_PRIMARY, /* - * The current work has at least been linked with the following - * processed chained works, which means if the processing page - * is the tail partial page of the work, the current work can - * safely use the whole page, as illustrated below: - * +--------------+-------------------------------------------+ - * | tail page | head page (of the previous work) | - * +--------------+-------------------------------------------+ - * /\ which belongs to the current work - * [ (*) this page can be used for the current work itself. ] + * The current work was the tail of an exist chain, and the previous + * processed chained works are all decided to be hooked up to it. + * A new chain should be created for the remaining unprocessed works, + * therefore different from Z_EROFS_VLE_WORK_PRIMARY_FOLLOWED, + * the next work cannot reuse the whole page in the following scenario: + * ________________________________________________________________ + * | tail (partial) page | head (partial) page | + * | (belongs to the next work) | (belongs to the current work) | + * |_______PRIMARY_FOLLOWED_______|________PRIMARY_HOOKED___________| + */ + Z_EROFS_VLE_WORK_PRIMARY_HOOKED, + /* + * The current work has been linked with the processed chained works, + * and could be also linked with the potential remaining works, which + * means if the processing page is the tail partial page of the work, + * the current work can safely use the whole page (since the next work + * is under control) for in-place decompression, as illustrated below: + * ________________________________________________________________ + * | tail (partial) page | head (partial) page | + * | (of the current work) | (of the previous work) | + * | PRIMARY_FOLLOWED or | | + * |_____PRIMARY_HOOKED____|____________PRIMARY_FOLLOWED____________| + * + * [ (*) the above page can be used for the current work itself. ] */ Z_EROFS_VLE_WORK_PRIMARY_FOLLOWED, Z_EROFS_VLE_WORK_MAX @@ -238,14 +253,9 @@ int erofs_try_to_free_cached_page(struct address_space *mapping, { struct erofs_sb_info *const sbi = EROFS_SB(mapping->host->i_sb); const unsigned int clusterpages = erofs_clusterpages(sbi); - - struct z_erofs_vle_workgroup *grp; + struct z_erofs_vle_workgroup *const grp = (void *)page_private(page); int ret = 0; /* 0 - busy */ - /* prevent the workgroup from being freed */ - rcu_read_lock(); - grp = (void *)page_private(page); - if (erofs_workgroup_try_to_freeze(&grp->obj, 1)) { unsigned int i; @@ -257,12 +267,11 @@ int erofs_try_to_free_cached_page(struct address_space *mapping, } } erofs_workgroup_unfreeze(&grp->obj, 1); - } - rcu_read_unlock(); - if (ret) { - ClearPagePrivate(page); - put_page(page); + if (ret) { + ClearPagePrivate(page); + put_page(page); + } } return ret; } @@ -315,10 +324,10 @@ static int z_erofs_vle_work_add_page( return ret ? 0 : -EAGAIN; } -static inline bool try_to_claim_workgroup( - struct z_erofs_vle_workgroup *grp, - z_erofs_vle_owned_workgrp_t *owned_head, - bool *hosted) +static enum z_erofs_vle_work_role +try_to_claim_workgroup(struct z_erofs_vle_workgroup *grp, + z_erofs_vle_owned_workgrp_t *owned_head, + bool *hosted) { DBG_BUGON(*hosted == true); @@ -332,6 +341,9 @@ retry: *owned_head = &grp->next; *hosted = true; + /* lucky, I am the followee :) */ + return Z_EROFS_VLE_WORK_PRIMARY_FOLLOWED; + } else if (grp->next == Z_EROFS_VLE_WORKGRP_TAIL) { /* * type 2, link to the end of a existing open chain, @@ -341,12 +353,11 @@ retry: if (cmpxchg(&grp->next, Z_EROFS_VLE_WORKGRP_TAIL, *owned_head) != Z_EROFS_VLE_WORKGRP_TAIL) goto retry; - *owned_head = Z_EROFS_VLE_WORKGRP_TAIL; - } else - return false; /* :( better luck next time */ + return Z_EROFS_VLE_WORK_PRIMARY_HOOKED; + } - return true; /* lucky, I am the followee :) */ + return Z_EROFS_VLE_WORK_PRIMARY; /* :( better luck next time */ } struct z_erofs_vle_work_finder { @@ -424,12 +435,9 @@ z_erofs_vle_work_lookup(const struct z_erofs_vle_work_finder *f) *f->hosted = false; if (!primary) *f->role = Z_EROFS_VLE_WORK_SECONDARY; - /* claim the workgroup if possible */ - else if (try_to_claim_workgroup(grp, f->owned_head, f->hosted)) - *f->role = Z_EROFS_VLE_WORK_PRIMARY_FOLLOWED; - else - *f->role = Z_EROFS_VLE_WORK_PRIMARY; - + else /* claim the workgroup if possible */ + *f->role = try_to_claim_workgroup(grp, f->owned_head, + f->hosted); return work; } @@ -493,6 +501,9 @@ z_erofs_vle_work_register(const struct z_erofs_vle_work_finder *f, return work; } +#define builder_is_hooked(builder) \ + ((builder)->role >= Z_EROFS_VLE_WORK_PRIMARY_HOOKED) + #define builder_is_followed(builder) \ ((builder)->role >= Z_EROFS_VLE_WORK_PRIMARY_FOLLOWED) @@ -539,7 +550,7 @@ repeat: if (unlikely(work == ERR_PTR(-EAGAIN))) goto repeat; - if (unlikely(IS_ERR(work))) + if (IS_ERR(work)) return PTR_ERR(work); got_it: z_erofs_pagevec_ctor_init(&builder->vector, @@ -589,7 +600,7 @@ static void __z_erofs_vle_work_release(struct z_erofs_vle_workgroup *grp, erofs_workgroup_put(&grp->obj); } -void z_erofs_vle_work_release(struct z_erofs_vle_work *work) +static void z_erofs_vle_work_release(struct z_erofs_vle_work *work) { struct z_erofs_vle_workgroup *grp = z_erofs_vle_work_workgroup(work, true); @@ -636,7 +647,7 @@ struct z_erofs_vle_frontend { struct inode *const inode; struct z_erofs_vle_work_builder builder; - struct erofs_map_blocks_iter m_iter; + struct erofs_map_blocks map; z_erofs_vle_owned_workgrp_t owned_head; @@ -647,8 +658,9 @@ struct z_erofs_vle_frontend { #define VLE_FRONTEND_INIT(__i) { \ .inode = __i, \ - .m_iter = { \ - { .m_llen = 0, .m_plen = 0 }, \ + .map = { \ + .m_llen = 0, \ + .m_plen = 0, \ .mpage = NULL \ }, \ .builder = VLE_WORK_BUILDER_INIT(), \ @@ -681,12 +693,11 @@ static int z_erofs_do_read_page(struct z_erofs_vle_frontend *fe, { struct super_block *const sb = fe->inode->i_sb; struct erofs_sb_info *const sbi __maybe_unused = EROFS_SB(sb); - struct erofs_map_blocks_iter *const m = &fe->m_iter; - struct erofs_map_blocks *const map = &m->map; + struct erofs_map_blocks *const map = &fe->map; struct z_erofs_vle_work_builder *const builder = &fe->builder; const loff_t offset = page_offset(page); - bool tight = builder_is_followed(builder); + bool tight = builder_is_hooked(builder); struct z_erofs_vle_work *work = builder->work; enum z_erofs_cache_alloctype cache_strategy; @@ -704,8 +715,12 @@ repeat: /* lucky, within the range of the current map_blocks */ if (offset + cur >= map->m_la && - offset + cur < map->m_la + map->m_llen) + offset + cur < map->m_la + map->m_llen) { + /* didn't get a valid unzip work previously (very rare) */ + if (!builder->work) + goto restart_now; goto hitted; + } /* go ahead the next map_blocks */ debugln("%s: [out-of-range] pos %llu", __func__, offset + cur); @@ -715,10 +730,11 @@ repeat: map->m_la = offset + cur; map->m_llen = 0; - err = erofs_map_blocks_iter(fe->inode, map, &m->mpage, 0); + err = z_erofs_map_blocks_iter(fe->inode, map, 0); if (unlikely(err)) goto err_out; +restart_now: if (unlikely(!(map->m_flags & EROFS_MAP_MAPPED))) goto hitted; @@ -740,7 +756,7 @@ repeat: map->m_plen / PAGE_SIZE, cache_strategy, page_pool, GFP_KERNEL); - tight &= builder_is_followed(builder); + tight &= builder_is_hooked(builder); work = builder->work; hitted: cur = end - min_t(unsigned int, offset + end - map->m_la, end); @@ -755,6 +771,9 @@ hitted: (tight ? Z_EROFS_PAGE_TYPE_EXCLUSIVE : Z_EROFS_VLE_PAGE_TYPE_TAIL_SHARED)); + if (cur) + tight &= builder_is_followed(builder); + retry: err = z_erofs_vle_work_add_page(builder, page, page_type); /* should allocate an additional staging page for pagevec */ @@ -830,8 +849,9 @@ static inline void z_erofs_vle_read_endio(struct bio *bio) #ifdef EROFS_FS_HAS_MANAGED_CACHE struct address_space *mc = NULL; #endif + struct bvec_iter_all iter_all; - bio_for_each_segment_all(bvec, bio, i) { + bio_for_each_segment_all(bvec, bio, i, iter_all) { struct page *page = bvec->bv_page; bool cachemngd = false; @@ -992,11 +1012,10 @@ repeat: if (llen > grp->llen) llen = grp->llen; - err = z_erofs_vle_unzip_fast_percpu(compressed_pages, - clusterpages, pages, llen, work->pageofs, - z_erofs_onlinepage_endio); + err = z_erofs_vle_unzip_fast_percpu(compressed_pages, clusterpages, + pages, llen, work->pageofs); if (err != -ENOTSUPP) - goto out_percpu; + goto out; if (sparsemem_pages >= nr_pages) goto skip_allocpage; @@ -1017,8 +1036,25 @@ skip_allocpage: erofs_vunmap(vout, nr_pages); out: + /* must handle all compressed pages before endding pages */ + for (i = 0; i < clusterpages; ++i) { + page = compressed_pages[i]; + +#ifdef EROFS_FS_HAS_MANAGED_CACHE + if (page->mapping == MNGD_MAPPING(sbi)) + continue; +#endif + /* recycle all individual staging pages */ + (void)z_erofs_gather_if_stagingpage(page_pool, page); + + WRITE_ONCE(compressed_pages[i], NULL); + } + for (i = 0; i < nr_pages; ++i) { page = pages[i]; + if (!page) + continue; + DBG_BUGON(!page->mapping); /* recycle all individual staging pages */ @@ -1031,20 +1067,6 @@ out: z_erofs_onlinepage_endio(page); } -out_percpu: - for (i = 0; i < clusterpages; ++i) { - page = compressed_pages[i]; - -#ifdef EROFS_FS_HAS_MANAGED_CACHE - if (page->mapping == MNGD_MAPPING(sbi)) - continue; -#endif - /* recycle all individual staging pages */ - (void)z_erofs_gather_if_stagingpage(page_pool, page); - - WRITE_ONCE(compressed_pages[i], NULL); - } - if (pages == z_pagemap_global) mutex_unlock(&z_pagemap_global_lock); else if (unlikely(pages != pages_onstack)) @@ -1484,8 +1506,8 @@ static int z_erofs_vle_normalaccess_readpage(struct file *file, z_erofs_submit_and_unzip(&f, &pagepool, true); out: - if (f.m_iter.mpage) - put_page(f.m_iter.mpage); + if (f.map.mpage) + put_page(f.map.mpage); /* clean up the remaining free pages */ put_pages_list(&pagepool); @@ -1555,8 +1577,8 @@ static int z_erofs_vle_normalaccess_readpages(struct file *filp, z_erofs_submit_and_unzip(&f, &pagepool, sync); - if (f.m_iter.mpage) - put_page(f.m_iter.mpage); + if (f.map.mpage) + put_page(f.map.mpage); /* clean up the remaining free pages */ put_pages_list(&pagepool); @@ -1701,14 +1723,14 @@ vle_get_logical_extent_head(const struct vle_map_blocks_iter_ctx *ctx, int z_erofs_map_blocks_iter(struct inode *inode, struct erofs_map_blocks *map, - struct page **mpage_ret, int flags) + int flags) { void *kaddr; const struct vle_map_blocks_iter_ctx ctx = { .inode = inode, .sb = inode->i_sb, .clusterbits = EROFS_I_SB(inode)->clusterbits, - .mpage_ret = mpage_ret, + .mpage_ret = &map->mpage, .kaddr_ret = &kaddr }; const unsigned int clustersize = 1 << ctx.clusterbits; @@ -1722,7 +1744,7 @@ int z_erofs_map_blocks_iter(struct inode *inode, /* initialize `pblk' to keep gcc from printing foolish warnings */ erofs_blk_t mblk, pblk = 0; - struct page *mpage = *mpage_ret; + struct page *mpage = map->mpage; struct z_erofs_vle_decompressed_index *di; unsigned int cluster_type, logical_cluster_ofs; int err = 0; @@ -1758,7 +1780,7 @@ int z_erofs_map_blocks_iter(struct inode *inode, err = PTR_ERR(mpage); goto out; } - *mpage_ret = mpage; + map->mpage = mpage; } else { lock_page(mpage); DBG_BUGON(!PageUptodate(mpage)); @@ -1818,7 +1840,7 @@ int z_erofs_map_blocks_iter(struct inode *inode, /* get the correspoinding first chunk */ err = vle_get_logical_extent_head(&ctx, lcn, &ofs, &pblk, &map->m_flags); - mpage = *mpage_ret; + mpage = map->mpage; if (unlikely(err)) { if (mpage) diff --git a/drivers/staging/erofs/unzip_vle.h b/drivers/staging/erofs/unzip_vle.h index 5a4e1b62c0d1..517e5ce8c5e9 100644 --- a/drivers/staging/erofs/unzip_vle.h +++ b/drivers/staging/erofs/unzip_vle.h @@ -212,18 +212,17 @@ static inline void z_erofs_onlinepage_endio(struct page *page) #define Z_EROFS_VLE_VMAP_GLOBAL_PAGES 2048 /* unzip_vle_lz4.c */ -extern int z_erofs_vle_plain_copy(struct page **compressed_pages, - unsigned clusterpages, struct page **pages, - unsigned nr_pages, unsigned short pageofs); - -extern int z_erofs_vle_unzip_fast_percpu(struct page **compressed_pages, - unsigned clusterpages, struct page **pages, - unsigned outlen, unsigned short pageofs, - void (*endio)(struct page *)); - -extern int z_erofs_vle_unzip_vmap(struct page **compressed_pages, - unsigned clusterpages, void *vaddr, unsigned llen, - unsigned short pageofs, bool overlapped); +int z_erofs_vle_plain_copy(struct page **compressed_pages, + unsigned int clusterpages, struct page **pages, + unsigned int nr_pages, unsigned short pageofs); +int z_erofs_vle_unzip_fast_percpu(struct page **compressed_pages, + unsigned int clusterpages, + struct page **pages, unsigned int outlen, + unsigned short pageofs); +int z_erofs_vle_unzip_vmap(struct page **compressed_pages, + unsigned int clusterpages, + void *vaddr, unsigned int llen, + unsigned short pageofs, bool overlapped); #endif diff --git a/drivers/staging/erofs/unzip_vle_lz4.c b/drivers/staging/erofs/unzip_vle_lz4.c index 52797bd89da1..48b263a2731a 100644 --- a/drivers/staging/erofs/unzip_vle_lz4.c +++ b/drivers/staging/erofs/unzip_vle_lz4.c @@ -13,7 +13,7 @@ #include "unzip_vle.h" #include <linux/lz4.h> -int z_erofs_unzip_lz4(void *in, void *out, size_t inlen, size_t outlen) +static int z_erofs_unzip_lz4(void *in, void *out, size_t inlen, size_t outlen) { int ret = LZ4_decompress_safe_partial(in, out, inlen, outlen, outlen); @@ -125,8 +125,7 @@ int z_erofs_vle_unzip_fast_percpu(struct page **compressed_pages, unsigned int clusterpages, struct page **pages, unsigned int outlen, - unsigned short pageofs, - void (*endio)(struct page *)) + unsigned short pageofs) { void *vin, *vout; unsigned int nr_pages, i, j; @@ -148,19 +147,16 @@ int z_erofs_vle_unzip_fast_percpu(struct page **compressed_pages, ret = z_erofs_unzip_lz4(vin, vout + pageofs, clusterpages * PAGE_SIZE, outlen); - if (ret >= 0) { - outlen = ret; - ret = 0; - } + if (ret < 0) + goto out; + ret = 0; for (i = 0; i < nr_pages; ++i) { j = min((unsigned int)PAGE_SIZE - pageofs, outlen); if (pages[i]) { - if (ret < 0) { - SetPageError(pages[i]); - } else if (clusterpages == 1 && - pages[i] == compressed_pages[0]) { + if (clusterpages == 1 && + pages[i] == compressed_pages[0]) { memcpy(vin + pageofs, vout + pageofs, j); } else { void *dst = kmap_atomic(pages[i]); @@ -168,12 +164,13 @@ int z_erofs_vle_unzip_fast_percpu(struct page **compressed_pages, memcpy(dst + pageofs, vout + pageofs, j); kunmap_atomic(dst); } - endio(pages[i]); } vout += PAGE_SIZE; outlen -= j; pageofs = 0; } + +out: preempt_enable(); if (clusterpages == 1) diff --git a/drivers/staging/erofs/utils.c b/drivers/staging/erofs/utils.c index b535898ca753..5f61f99f4c10 100644 --- a/drivers/staging/erofs/utils.c +++ b/drivers/staging/erofs/utils.c @@ -31,13 +31,32 @@ struct page *erofs_allocpage(struct list_head *pool, gfp_t gfp) static atomic_long_t erofs_global_shrink_cnt; #ifdef CONFIG_EROFS_FS_ZIP +#define __erofs_workgroup_get(grp) atomic_inc(&(grp)->refcount) +#define __erofs_workgroup_put(grp) atomic_dec(&(grp)->refcount) -struct erofs_workgroup *erofs_find_workgroup( - struct super_block *sb, pgoff_t index, bool *tag) +static int erofs_workgroup_get(struct erofs_workgroup *grp) +{ + int o; + +repeat: + o = erofs_wait_on_workgroup_freezed(grp); + if (unlikely(o <= 0)) + return -1; + + if (unlikely(atomic_cmpxchg(&grp->refcount, o, o + 1) != o)) + goto repeat; + + /* decrease refcount paired by erofs_workgroup_put */ + if (unlikely(o == 1)) + atomic_long_dec(&erofs_global_shrink_cnt); + return 0; +} + +struct erofs_workgroup *erofs_find_workgroup(struct super_block *sb, + pgoff_t index, bool *tag) { struct erofs_sb_info *sbi = EROFS_SB(sb); struct erofs_workgroup *grp; - int oldcount; repeat: rcu_read_lock(); @@ -46,15 +65,12 @@ repeat: *tag = xa_pointer_tag(grp); grp = xa_untag_pointer(grp); - if (erofs_workgroup_get(grp, &oldcount)) { + if (erofs_workgroup_get(grp)) { /* prefer to relax rcu read side */ rcu_read_unlock(); goto repeat; } - /* decrease refcount added by erofs_workgroup_put */ - if (unlikely(oldcount == 1)) - atomic_long_dec(&erofs_global_shrink_cnt); DBG_BUGON(index != grp->index); } rcu_read_unlock(); @@ -104,8 +120,6 @@ int erofs_register_workgroup(struct super_block *sb, return err; } -extern void erofs_workgroup_free_rcu(struct erofs_workgroup *grp); - static void __erofs_workgroup_free(struct erofs_workgroup *grp) { atomic_long_dec(&erofs_global_shrink_cnt); @@ -131,9 +145,9 @@ static void erofs_workgroup_unfreeze_final(struct erofs_workgroup *grp) __erofs_workgroup_free(grp); } -bool erofs_try_to_release_workgroup(struct erofs_sb_info *sbi, - struct erofs_workgroup *grp, - bool cleanup) +static bool erofs_try_to_release_workgroup(struct erofs_sb_info *sbi, + struct erofs_workgroup *grp, + bool cleanup) { /* * for managed cache enabled, the refcount of workgroups @@ -172,9 +186,9 @@ bool erofs_try_to_release_workgroup(struct erofs_sb_info *sbi, #else /* for nocache case, no customized reclaim path at all */ -bool erofs_try_to_release_workgroup(struct erofs_sb_info *sbi, - struct erofs_workgroup *grp, - bool cleanup) +static bool erofs_try_to_release_workgroup(struct erofs_sb_info *sbi, + struct erofs_workgroup *grp, + bool cleanup) { int cnt = atomic_read(&grp->refcount); @@ -256,14 +270,14 @@ void erofs_unregister_super(struct super_block *sb) spin_unlock(&erofs_sb_list_lock); } -unsigned long erofs_shrink_count(struct shrinker *shrink, - struct shrink_control *sc) +static unsigned long erofs_shrink_count(struct shrinker *shrink, + struct shrink_control *sc) { return atomic_long_read(&erofs_global_shrink_cnt); } -unsigned long erofs_shrink_scan(struct shrinker *shrink, - struct shrink_control *sc) +static unsigned long erofs_shrink_scan(struct shrinker *shrink, + struct shrink_control *sc) { struct erofs_sb_info *sbi; struct list_head *p; @@ -319,3 +333,9 @@ unsigned long erofs_shrink_scan(struct shrinker *shrink, return freed; } +struct shrinker erofs_shrinker_info = { + .scan_objects = erofs_shrink_scan, + .count_objects = erofs_shrink_count, + .seeks = DEFAULT_SEEKS, +}; + diff --git a/drivers/staging/erofs/xattr.c b/drivers/staging/erofs/xattr.c index 80dca6a4adbe..f716ab0446e5 100644 --- a/drivers/staging/erofs/xattr.c +++ b/drivers/staging/erofs/xattr.c @@ -44,19 +44,48 @@ static inline void xattr_iter_end_final(struct xattr_iter *it) static int init_inode_xattrs(struct inode *inode) { + struct erofs_vnode *const vi = EROFS_V(inode); struct xattr_iter it; unsigned int i; struct erofs_xattr_ibody_header *ih; struct super_block *sb; struct erofs_sb_info *sbi; - struct erofs_vnode *vi; bool atomic_map; + int ret = 0; - if (likely(inode_has_inited_xattr(inode))) + /* the most case is that xattrs of this inode are initialized. */ + if (test_bit(EROFS_V_EA_INITED_BIT, &vi->flags)) return 0; - vi = EROFS_V(inode); - BUG_ON(!vi->xattr_isize); + if (wait_on_bit_lock(&vi->flags, EROFS_V_BL_XATTR_BIT, TASK_KILLABLE)) + return -ERESTARTSYS; + + /* someone has initialized xattrs for us? */ + if (test_bit(EROFS_V_EA_INITED_BIT, &vi->flags)) + goto out_unlock; + + /* + * bypass all xattr operations if ->xattr_isize is not greater than + * sizeof(struct erofs_xattr_ibody_header), in detail: + * 1) it is not enough to contain erofs_xattr_ibody_header then + * ->xattr_isize should be 0 (it means no xattr); + * 2) it is just to contain erofs_xattr_ibody_header, which is on-disk + * undefined right now (maybe use later with some new sb feature). + */ + if (vi->xattr_isize == sizeof(struct erofs_xattr_ibody_header)) { + errln("xattr_isize %d of nid %llu is not supported yet", + vi->xattr_isize, vi->nid); + ret = -ENOTSUPP; + goto out_unlock; + } else if (vi->xattr_isize < sizeof(struct erofs_xattr_ibody_header)) { + if (unlikely(vi->xattr_isize)) { + DBG_BUGON(1); + ret = -EIO; + goto out_unlock; /* xattr ondisk layout error */ + } + ret = -ENOATTR; + goto out_unlock; + } sb = inode->i_sb; sbi = EROFS_SB(sb); @@ -64,8 +93,10 @@ static int init_inode_xattrs(struct inode *inode) it.ofs = erofs_blkoff(iloc(sbi, vi->nid) + vi->inode_isize); it.page = erofs_get_inline_page(inode, it.blkaddr); - if (IS_ERR(it.page)) - return PTR_ERR(it.page); + if (IS_ERR(it.page)) { + ret = PTR_ERR(it.page); + goto out_unlock; + } /* read in shared xattr array (non-atomic, see kmalloc below) */ it.kaddr = kmap(it.page); @@ -78,7 +109,8 @@ static int init_inode_xattrs(struct inode *inode) sizeof(uint), GFP_KERNEL); if (vi->xattr_shared_xattrs == NULL) { xattr_iter_end(&it, atomic_map); - return -ENOMEM; + ret = -ENOMEM; + goto out_unlock; } /* let's skip ibody header */ @@ -92,8 +124,12 @@ static int init_inode_xattrs(struct inode *inode) it.page = erofs_get_meta_page(sb, ++it.blkaddr, S_ISDIR(inode->i_mode)); - if (IS_ERR(it.page)) - return PTR_ERR(it.page); + if (IS_ERR(it.page)) { + kfree(vi->xattr_shared_xattrs); + vi->xattr_shared_xattrs = NULL; + ret = PTR_ERR(it.page); + goto out_unlock; + } it.kaddr = kmap_atomic(it.page); atomic_map = true; @@ -105,8 +141,11 @@ static int init_inode_xattrs(struct inode *inode) } xattr_iter_end(&it, atomic_map); - inode_set_inited_xattr(inode); - return 0; + set_bit(EROFS_V_EA_INITED_BIT, &vi->flags); + +out_unlock: + clear_and_wake_up_bit(EROFS_V_BL_XATTR_BIT, &vi->flags); + return ret; } /* @@ -117,10 +156,12 @@ static int init_inode_xattrs(struct inode *inode) * and need to be handled */ struct xattr_iter_handlers { - int (*entry)(struct xattr_iter *, struct erofs_xattr_entry *); - int (*name)(struct xattr_iter *, unsigned int, char *, unsigned int); - int (*alloc_buffer)(struct xattr_iter *, unsigned int); - void (*value)(struct xattr_iter *, unsigned int, char *, unsigned int); + int (*entry)(struct xattr_iter *_it, struct erofs_xattr_entry *entry); + int (*name)(struct xattr_iter *_it, unsigned int processed, char *buf, + unsigned int len); + int (*alloc_buffer)(struct xattr_iter *_it, unsigned int value_sz); + void (*value)(struct xattr_iter *_it, unsigned int processed, char *buf, + unsigned int len); }; static inline int xattr_iter_fixup(struct xattr_iter *it) @@ -422,7 +463,6 @@ static int erofs_xattr_generic_get(const struct xattr_handler *handler, struct dentry *unused, struct inode *inode, const char *name, void *buffer, size_t size) { - struct erofs_vnode *const vi = EROFS_V(inode); struct erofs_sb_info *const sbi = EROFS_I_SB(inode); switch (handler->flags) { @@ -440,9 +480,6 @@ static int erofs_xattr_generic_get(const struct xattr_handler *handler, return -EINVAL; } - if (!vi->xattr_isize) - return -ENOATTR; - return erofs_getxattr(inode, handler->flags, name, buffer, size); } @@ -503,8 +540,7 @@ static int xattr_entrylist(struct xattr_iter *_it, if (h == NULL || (h->list != NULL && !h->list(it->dentry))) return 1; - /* Note that at least one of 'prefix' and 'name' should be non-NULL */ - prefix = h->prefix != NULL ? h->prefix : h->name; + prefix = xattr_prefix(h); prefix_len = strlen(prefix); if (it->buffer == NULL) { @@ -627,3 +663,40 @@ ssize_t erofs_listxattr(struct dentry *dentry, return shared_listxattr(&it); } +#ifdef CONFIG_EROFS_FS_POSIX_ACL +struct posix_acl *erofs_get_acl(struct inode *inode, int type) +{ + struct posix_acl *acl; + int prefix, rc; + char *value = NULL; + + switch (type) { + case ACL_TYPE_ACCESS: + prefix = EROFS_XATTR_INDEX_POSIX_ACL_ACCESS; + break; + case ACL_TYPE_DEFAULT: + prefix = EROFS_XATTR_INDEX_POSIX_ACL_DEFAULT; + break; + default: + return ERR_PTR(-EINVAL); + } + + rc = erofs_getxattr(inode, prefix, "", NULL, 0); + if (rc > 0) { + value = kmalloc(rc, GFP_KERNEL); + if (!value) + return ERR_PTR(-ENOMEM); + rc = erofs_getxattr(inode, prefix, "", value, rc); + } + + if (rc == -ENOATTR) + acl = NULL; + else if (rc < 0) + acl = ERR_PTR(rc); + else + acl = posix_acl_from_xattr(&init_user_ns, value, rc); + kfree(value); + return acl; +} +#endif + diff --git a/drivers/staging/erofs/xattr.h b/drivers/staging/erofs/xattr.h index 0c7379282fc5..35ba5ac2139a 100644 --- a/drivers/staging/erofs/xattr.h +++ b/drivers/staging/erofs/xattr.h @@ -68,9 +68,7 @@ static const struct xattr_handler *xattr_handler_map[] = { } #ifdef CONFIG_EROFS_FS_XATTR - -extern const struct inode_operations erofs_generic_xattr_iops; -extern const struct inode_operations erofs_dir_xattr_iops; +extern const struct xattr_handler *erofs_xattr_handlers[]; int erofs_getxattr(struct inode *, int, const char *, void *, size_t); ssize_t erofs_listxattr(struct dentry *, char *, size_t); @@ -89,5 +87,11 @@ static ssize_t __maybe_unused erofs_listxattr(struct dentry *dentry, } #endif +#ifdef CONFIG_EROFS_FS_POSIX_ACL +struct posix_acl *erofs_get_acl(struct inode *inode, int type); +#else +#define erofs_get_acl (NULL) +#endif + #endif diff --git a/drivers/staging/fbtft/fb_agm1264k-fl.c b/drivers/staging/fbtft/fb_agm1264k-fl.c index f6f30f5bf15a..8f27bd8da17d 100644 --- a/drivers/staging/fbtft/fb_agm1264k-fl.c +++ b/drivers/staging/fbtft/fb_agm1264k-fl.c @@ -8,7 +8,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/delay.h> #include <linux/slab.h> @@ -79,14 +79,14 @@ static int init_display(struct fbtft_par *par) static void reset(struct fbtft_par *par) { - if (par->gpio.reset == -1) + if (!par->gpio.reset) return; dev_dbg(par->info->device, "%s()\n", __func__); - gpio_set_value(par->gpio.reset, 0); + gpiod_set_value(par->gpio.reset, 0); udelay(20); - gpio_set_value(par->gpio.reset, 1); + gpiod_set_value(par->gpio.reset, 1); mdelay(120); } @@ -98,30 +98,30 @@ static int verify_gpios(struct fbtft_par *par) dev_dbg(par->info->device, "%s()\n", __func__); - if (par->EPIN < 0) { + if (!par->EPIN) { dev_err(par->info->device, "Missing info about 'wr' (aka E) gpio. Aborting.\n"); return -EINVAL; } for (i = 0; i < 8; ++i) { - if (par->gpio.db[i] < 0) { + if (!par->gpio.db[i]) { dev_err(par->info->device, "Missing info about 'db[%i]' gpio. Aborting.\n", i); return -EINVAL; } } - if (par->CS0 < 0) { + if (!par->CS0) { dev_err(par->info->device, "Missing info about 'cs0' gpio. Aborting.\n"); return -EINVAL; } - if (par->CS1 < 0) { + if (!par->CS1) { dev_err(par->info->device, "Missing info about 'cs1' gpio. Aborting.\n"); return -EINVAL; } - if (par->RW < 0) { + if (!par->RW) { dev_err(par->info->device, "Missing info about 'rw' gpio. Aborting.\n"); return -EINVAL; @@ -139,22 +139,22 @@ request_gpios_match(struct fbtft_par *par, const struct fbtft_gpio *gpio) if (strcasecmp(gpio->name, "wr") == 0) { /* left ks0108 E pin */ par->EPIN = gpio->gpio; - return GPIOF_OUT_INIT_LOW; + return GPIOD_OUT_LOW; } else if (strcasecmp(gpio->name, "cs0") == 0) { /* left ks0108 controller pin */ par->CS0 = gpio->gpio; - return GPIOF_OUT_INIT_HIGH; + return GPIOD_OUT_HIGH; } else if (strcasecmp(gpio->name, "cs1") == 0) { /* right ks0108 controller pin */ par->CS1 = gpio->gpio; - return GPIOF_OUT_INIT_HIGH; + return GPIOD_OUT_HIGH; } /* if write (rw = 0) e(1->0) perform write */ /* if read (rw = 1) e(0->1) set data on D0-7*/ else if (strcasecmp(gpio->name, "rw") == 0) { par->RW = gpio->gpio; - return GPIOF_OUT_INIT_LOW; + return GPIOD_OUT_LOW; } return FBTFT_GPIO_NO_MATCH; @@ -194,15 +194,15 @@ static void write_reg8_bus8(struct fbtft_par *par, int len, ...) /* select chip */ if (*buf) { /* cs1 */ - gpio_set_value(par->CS0, 1); - gpio_set_value(par->CS1, 0); + gpiod_set_value(par->CS0, 1); + gpiod_set_value(par->CS1, 0); } else { /* cs0 */ - gpio_set_value(par->CS0, 0); - gpio_set_value(par->CS1, 1); + gpiod_set_value(par->CS0, 0); + gpiod_set_value(par->CS1, 1); } - gpio_set_value(par->RS, 0); /* RS->0 (command mode) */ + gpiod_set_value(par->RS, 0); /* RS->0 (command mode) */ len--; if (len) { @@ -364,7 +364,7 @@ static int write_vmem(struct fbtft_par *par, size_t offset, size_t len) write_reg(par, 0x00, (0x17 << 3) | (u8)y); /* write bitmap */ - gpio_set_value(par->RS, 1); /* RS->1 (data mode) */ + gpiod_set_value(par->RS, 1); /* RS->1 (data mode) */ ret = par->fbtftops.write(par, buf, len); if (ret < 0) dev_err(par->info->device, @@ -387,7 +387,7 @@ static int write_vmem(struct fbtft_par *par, size_t offset, size_t len) write_reg(par, 0x01, (0x17 << 3) | (u8)y); /* write bitmap */ - gpio_set_value(par->RS, 1); /* RS->1 (data mode) */ + gpiod_set_value(par->RS, 1); /* RS->1 (data mode) */ par->fbtftops.write(par, buf, len); if (ret < 0) dev_err(par->info->device, @@ -397,8 +397,8 @@ static int write_vmem(struct fbtft_par *par, size_t offset, size_t len) } kfree(convert_buf); - gpio_set_value(par->CS0, 1); - gpio_set_value(par->CS1, 1); + gpiod_set_value(par->CS0, 1); + gpiod_set_value(par->CS1, 1); return ret; } @@ -408,7 +408,7 @@ static int write(struct fbtft_par *par, void *buf, size_t len) fbtft_par_dbg_hex(DEBUG_WRITE, par, par->info->device, u8, buf, len, "%s(len=%d): ", __func__, len); - gpio_set_value(par->RW, 0); /* set write mode */ + gpiod_set_value(par->RW, 0); /* set write mode */ while (len--) { u8 i, data; @@ -417,12 +417,12 @@ static int write(struct fbtft_par *par, void *buf, size_t len) /* set data bus */ for (i = 0; i < 8; ++i) - gpio_set_value(par->gpio.db[i], data & (1 << i)); + gpiod_set_value(par->gpio.db[i], data & (1 << i)); /* set E */ - gpio_set_value(par->EPIN, 1); + gpiod_set_value(par->EPIN, 1); udelay(5); /* unset E - write */ - gpio_set_value(par->EPIN, 0); + gpiod_set_value(par->EPIN, 0); udelay(1); } diff --git a/drivers/staging/fbtft/fb_bd663474.c b/drivers/staging/fbtft/fb_bd663474.c index a58c514f4721..b6c6d66e4eb1 100644 --- a/drivers/staging/fbtft/fb_bd663474.c +++ b/drivers/staging/fbtft/fb_bd663474.c @@ -12,7 +12,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/delay.h> #include "fbtft.h" @@ -24,8 +24,8 @@ static int init_display(struct fbtft_par *par) { - if (par->gpio.cs != -1) - gpio_set_value(par->gpio.cs, 0); /* Activate chip */ + if (!par->gpio.cs) + gpiod_set_value(par->gpio.cs, 0); /* Activate chip */ par->fbtftops.reset(par); diff --git a/drivers/staging/fbtft/fb_ili9163.c b/drivers/staging/fbtft/fb_ili9163.c index 86e140244aab..d609a2b67db9 100644 --- a/drivers/staging/fbtft/fb_ili9163.c +++ b/drivers/staging/fbtft/fb_ili9163.c @@ -11,7 +11,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/delay.h> #include <video/mipi_display.h> @@ -77,8 +77,8 @@ static int init_display(struct fbtft_par *par) { par->fbtftops.reset(par); - if (par->gpio.cs != -1) - gpio_set_value(par->gpio.cs, 0); /* Activate chip */ + if (!par->gpio.cs) + gpiod_set_value(par->gpio.cs, 0); /* Activate chip */ write_reg(par, MIPI_DCS_SOFT_RESET); /* software reset */ mdelay(500); diff --git a/drivers/staging/fbtft/fb_ili9320.c b/drivers/staging/fbtft/fb_ili9320.c index 740c0acbecd8..ea6e001288ce 100644 --- a/drivers/staging/fbtft/fb_ili9320.c +++ b/drivers/staging/fbtft/fb_ili9320.c @@ -8,7 +8,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/spi/spi.h> #include <linux/delay.h> diff --git a/drivers/staging/fbtft/fb_ili9325.c b/drivers/staging/fbtft/fb_ili9325.c index 2cf75f2e03e2..b090e7ab6fdd 100644 --- a/drivers/staging/fbtft/fb_ili9325.c +++ b/drivers/staging/fbtft/fb_ili9325.c @@ -10,7 +10,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/delay.h> #include "fbtft.h" @@ -85,8 +85,8 @@ static int init_display(struct fbtft_par *par) { par->fbtftops.reset(par); - if (par->gpio.cs != -1) - gpio_set_value(par->gpio.cs, 0); /* Activate chip */ + if (!par->gpio.cs) + gpiod_set_value(par->gpio.cs, 0); /* Activate chip */ bt &= 0x07; vc &= 0x07; diff --git a/drivers/staging/fbtft/fb_ili9340.c b/drivers/staging/fbtft/fb_ili9340.c index 430f21e50f4d..415183c7054a 100644 --- a/drivers/staging/fbtft/fb_ili9340.c +++ b/drivers/staging/fbtft/fb_ili9340.c @@ -8,7 +8,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/delay.h> #include <video/mipi_display.h> diff --git a/drivers/staging/fbtft/fb_pcd8544.c b/drivers/staging/fbtft/fb_pcd8544.c index 32172f8f79f0..ad49973ad594 100644 --- a/drivers/staging/fbtft/fb_pcd8544.c +++ b/drivers/staging/fbtft/fb_pcd8544.c @@ -11,7 +11,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/spi/spi.h> #include <linux/delay.h> @@ -119,7 +119,7 @@ static int write_vmem(struct fbtft_par *par, size_t offset, size_t len) } /* Write data */ - gpio_set_value(par->gpio.dc, 1); + gpiod_set_value(par->gpio.dc, 1); ret = par->fbtftops.write(par, par->txbuf.buf, 6 * 84); if (ret < 0) dev_err(par->info->device, "write failed and returned: %d\n", diff --git a/drivers/staging/fbtft/fb_ra8875.c b/drivers/staging/fbtft/fb_ra8875.c index 5d3b76ca74d8..70b37fc7fb66 100644 --- a/drivers/staging/fbtft/fb_ra8875.c +++ b/drivers/staging/fbtft/fb_ra8875.c @@ -9,7 +9,7 @@ #include <linux/init.h> #include <linux/delay.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include "fbtft.h" #define DRVNAME "fb_ra8875" @@ -39,7 +39,7 @@ static int write_spi(struct fbtft_par *par, void *buf, size_t len) static int init_display(struct fbtft_par *par) { - gpio_set_value(par->gpio.dc, 1); + gpiod_set_value(par->gpio.dc, 1); fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__); diff --git a/drivers/staging/fbtft/fb_s6d1121.c b/drivers/staging/fbtft/fb_s6d1121.c index aa716f33420a..b3d0701880fe 100644 --- a/drivers/staging/fbtft/fb_s6d1121.c +++ b/drivers/staging/fbtft/fb_s6d1121.c @@ -12,7 +12,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/delay.h> #include "fbtft.h" @@ -29,8 +29,8 @@ static int init_display(struct fbtft_par *par) { par->fbtftops.reset(par); - if (par->gpio.cs != -1) - gpio_set_value(par->gpio.cs, 0); /* Activate chip */ + if (!par->gpio.cs) + gpiod_set_value(par->gpio.cs, 0); /* Activate chip */ /* Initialization sequence from Lib_UTFT */ diff --git a/drivers/staging/fbtft/fb_sh1106.c b/drivers/staging/fbtft/fb_sh1106.c index 00096f8d249a..6f7249493ea3 100644 --- a/drivers/staging/fbtft/fb_sh1106.c +++ b/drivers/staging/fbtft/fb_sh1106.c @@ -9,7 +9,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/delay.h> #include "fbtft.h" diff --git a/drivers/staging/fbtft/fb_ssd1289.c b/drivers/staging/fbtft/fb_ssd1289.c index c9b18b3ba4ab..bbf75f795234 100644 --- a/drivers/staging/fbtft/fb_ssd1289.c +++ b/drivers/staging/fbtft/fb_ssd1289.c @@ -10,7 +10,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include "fbtft.h" @@ -28,8 +28,8 @@ static int init_display(struct fbtft_par *par) { par->fbtftops.reset(par); - if (par->gpio.cs != -1) - gpio_set_value(par->gpio.cs, 0); /* Activate chip */ + if (!par->gpio.cs) + gpiod_set_value(par->gpio.cs, 0); /* Activate chip */ write_reg(par, 0x00, 0x0001); write_reg(par, 0x03, 0xA8A4); diff --git a/drivers/staging/fbtft/fb_ssd1305.c b/drivers/staging/fbtft/fb_ssd1305.c index 3515888d94c9..020fe48fed0b 100644 --- a/drivers/staging/fbtft/fb_ssd1305.c +++ b/drivers/staging/fbtft/fb_ssd1305.c @@ -8,7 +8,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/delay.h> #include "fbtft.h" @@ -168,7 +168,7 @@ static int write_vmem(struct fbtft_par *par, size_t offset, size_t len) } /* Write data */ - gpio_set_value(par->gpio.dc, 1); + gpiod_set_value(par->gpio.dc, 1); ret = par->fbtftops.write(par, par->txbuf.buf, par->info->var.xres * par->info->var.yres / 8); diff --git a/drivers/staging/fbtft/fb_ssd1306.c b/drivers/staging/fbtft/fb_ssd1306.c index 50172ddd94ae..d7c5e2e0eee9 100644 --- a/drivers/staging/fbtft/fb_ssd1306.c +++ b/drivers/staging/fbtft/fb_ssd1306.c @@ -8,7 +8,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/delay.h> #include "fbtft.h" @@ -190,7 +190,7 @@ static int write_vmem(struct fbtft_par *par, size_t offset, size_t len) } /* Write data */ - gpio_set_value(par->gpio.dc, 1); + gpiod_set_value(par->gpio.dc, 1); ret = par->fbtftops.write(par, par->txbuf.buf, xres * yres / 8); if (ret < 0) dev_err(par->info->device, "write failed and returned: %d\n", diff --git a/drivers/staging/fbtft/fb_ssd1325.c b/drivers/staging/fbtft/fb_ssd1325.c index f974f7fc4d79..8a3140d41d8b 100644 --- a/drivers/staging/fbtft/fb_ssd1325.c +++ b/drivers/staging/fbtft/fb_ssd1325.c @@ -6,7 +6,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/delay.h> #include "fbtft.h" @@ -35,7 +35,7 @@ static int init_display(struct fbtft_par *par) { par->fbtftops.reset(par); - gpio_set_value(par->gpio.cs, 0); + gpiod_set_value(par->gpio.cs, 0); write_reg(par, 0xb3); write_reg(par, 0xf0); @@ -155,7 +155,7 @@ static int write_vmem(struct fbtft_par *par, size_t offset, size_t len) } } - gpio_set_value(par->gpio.dc, 1); + gpiod_set_value(par->gpio.dc, 1); /* Write data */ ret = par->fbtftops.write(par, par->txbuf.buf, diff --git a/drivers/staging/fbtft/fb_ssd1331.c b/drivers/staging/fbtft/fb_ssd1331.c index 0b614c84822e..9f54fe28d511 100644 --- a/drivers/staging/fbtft/fb_ssd1331.c +++ b/drivers/staging/fbtft/fb_ssd1331.c @@ -2,7 +2,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/spi/spi.h> #include <linux/delay.h> @@ -80,8 +80,8 @@ static void write_reg8_bus8(struct fbtft_par *par, int len, ...) va_start(args, len); *buf = (u8)va_arg(args, unsigned int); - if (par->gpio.dc != -1) - gpio_set_value(par->gpio.dc, 0); + if (!par->gpio.dc) + gpiod_set_value(par->gpio.dc, 0); ret = par->fbtftops.write(par, par->buf, sizeof(u8)); if (ret < 0) { va_end(args); @@ -103,8 +103,8 @@ static void write_reg8_bus8(struct fbtft_par *par, int len, ...) return; } } - if (par->gpio.dc != -1) - gpio_set_value(par->gpio.dc, 1); + if (!par->gpio.dc) + gpiod_set_value(par->gpio.dc, 1); va_end(args); } diff --git a/drivers/staging/fbtft/fb_ssd1351.c b/drivers/staging/fbtft/fb_ssd1351.c index 3da091b4d297..9ac78ce30619 100644 --- a/drivers/staging/fbtft/fb_ssd1351.c +++ b/drivers/staging/fbtft/fb_ssd1351.c @@ -2,7 +2,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/spi/spi.h> #include <linux/delay.h> @@ -164,7 +164,7 @@ static int set_gamma(struct fbtft_par *par, u32 *curves) static int blank(struct fbtft_par *par, bool on) { fbtft_par_dbg(DEBUG_BLANK, par, "(%s=%s)\n", - __func__, on ? "true" : "false"); + __func__, on ? "true" : "false"); if (on) write_reg(par, 0xAE); else diff --git a/drivers/staging/fbtft/fb_tinylcd.c b/drivers/staging/fbtft/fb_tinylcd.c index e463b0ddf16d..9469248f2c50 100644 --- a/drivers/staging/fbtft/fb_tinylcd.c +++ b/drivers/staging/fbtft/fb_tinylcd.c @@ -38,7 +38,7 @@ static int init_display(struct fbtft_par *par) write_reg(par, 0xE5, 0x00); write_reg(par, 0xF0, 0x36, 0xA5, 0x53); write_reg(par, 0xE0, 0x00, 0x35, 0x33, 0x00, 0x00, 0x00, - 0x00, 0x35, 0x33, 0x00, 0x00, 0x00); + 0x00, 0x35, 0x33, 0x00, 0x00, 0x00); write_reg(par, MIPI_DCS_SET_PIXEL_FORMAT, 0x55); write_reg(par, MIPI_DCS_EXIT_SLEEP_MODE); udelay(250); diff --git a/drivers/staging/fbtft/fb_tls8204.c b/drivers/staging/fbtft/fb_tls8204.c index 277b6ed9c725..bec6dd0ffb01 100644 --- a/drivers/staging/fbtft/fb_tls8204.c +++ b/drivers/staging/fbtft/fb_tls8204.c @@ -12,7 +12,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/spi/spi.h> #include <linux/delay.h> @@ -94,7 +94,7 @@ static int write_vmem(struct fbtft_par *par, size_t offset, size_t len) /* The display is 102x68 but the LCD is 84x48. * Set the write pointer at the start of each row. */ - gpio_set_value(par->gpio.dc, 0); + gpiod_set_value(par->gpio.dc, 0); write_reg(par, 0x80 | 0); write_reg(par, 0x40 | y); @@ -109,7 +109,7 @@ static int write_vmem(struct fbtft_par *par, size_t offset, size_t len) *buf++ = ch; } /* Write the row */ - gpio_set_value(par->gpio.dc, 1); + gpiod_set_value(par->gpio.dc, 1); ret = par->fbtftops.write(par, par->txbuf.buf, WIDTH); if (ret < 0) { dev_err(par->info->device, diff --git a/drivers/staging/fbtft/fb_uc1611.c b/drivers/staging/fbtft/fb_uc1611.c index dfaf8bc70f73..65681d0fe200 100644 --- a/drivers/staging/fbtft/fb_uc1611.c +++ b/drivers/staging/fbtft/fb_uc1611.c @@ -10,7 +10,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/spi/spi.h> #include <linux/delay.h> @@ -251,7 +251,7 @@ static int write_vmem(struct fbtft_par *par, size_t offset, size_t len) } break; } - gpio_set_value(par->gpio.dc, 1); + gpiod_set_value(par->gpio.dc, 1); /* Write data */ ret = par->fbtftops.write(par, par->txbuf.buf, len / 2); diff --git a/drivers/staging/fbtft/fb_uc1701.c b/drivers/staging/fbtft/fb_uc1701.c index 0a3531d6eb39..e4ccc73868a7 100644 --- a/drivers/staging/fbtft/fb_uc1701.c +++ b/drivers/staging/fbtft/fb_uc1701.c @@ -11,7 +11,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/spi/spi.h> #include <linux/delay.h> @@ -136,9 +136,9 @@ static int write_vmem(struct fbtft_par *par, size_t offset, size_t len) write_reg(par, LCD_PAGE_ADDRESS | (u8)y); write_reg(par, 0x00); write_reg(par, LCD_COL_ADDRESS); - gpio_set_value(par->gpio.dc, 1); + gpiod_set_value(par->gpio.dc, 1); ret = par->fbtftops.write(par, par->txbuf.buf, WIDTH); - gpio_set_value(par->gpio.dc, 0); + gpiod_set_value(par->gpio.dc, 0); } if (ret < 0) diff --git a/drivers/staging/fbtft/fb_upd161704.c b/drivers/staging/fbtft/fb_upd161704.c index acc425fdf34e..564a38e34440 100644 --- a/drivers/staging/fbtft/fb_upd161704.c +++ b/drivers/staging/fbtft/fb_upd161704.c @@ -12,7 +12,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/delay.h> #include "fbtft.h" @@ -26,8 +26,8 @@ static int init_display(struct fbtft_par *par) { par->fbtftops.reset(par); - if (par->gpio.cs != -1) - gpio_set_value(par->gpio.cs, 0); /* Activate chip */ + if (!par->gpio.cs) + gpiod_set_value(par->gpio.cs, 0); /* Activate chip */ /* Initialization sequence from Lib_UTFT */ diff --git a/drivers/staging/fbtft/fb_watterott.c b/drivers/staging/fbtft/fb_watterott.c index e77178157f1b..0a5206d28da4 100644 --- a/drivers/staging/fbtft/fb_watterott.c +++ b/drivers/staging/fbtft/fb_watterott.c @@ -8,7 +8,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/delay.h> #include "fbtft.h" @@ -213,7 +213,7 @@ static int set_var(struct fbtft_par *par) static int verify_gpios(struct fbtft_par *par) { - if (par->gpio.reset < 0) { + if (!par->gpio.reset) { dev_err(par->info->device, "Missing 'reset' gpio. Aborting.\n"); return -EINVAL; } diff --git a/drivers/staging/fbtft/fbtft-bus.c b/drivers/staging/fbtft/fbtft-bus.c index 8ce1ff9b6c2a..2ea814d0dca5 100644 --- a/drivers/staging/fbtft/fbtft-bus.c +++ b/drivers/staging/fbtft/fbtft-bus.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 #include <linux/export.h> #include <linux/errno.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/spi/spi.h> #include "fbtft.h" @@ -135,8 +135,8 @@ int fbtft_write_vmem16_bus8(struct fbtft_par *par, size_t offset, size_t len) remain = len / 2; vmem16 = (u16 *)(par->info->screen_buffer + offset); - if (par->gpio.dc != -1) - gpio_set_value(par->gpio.dc, 1); + if (!par->gpio.dc) + gpiod_set_value(par->gpio.dc, 1); /* non buffered write */ if (!par->txbuf.buf) diff --git a/drivers/staging/fbtft/fbtft-core.c b/drivers/staging/fbtft/fbtft-core.c index a2df02d97a8e..9b07badf4c6c 100644 --- a/drivers/staging/fbtft/fbtft-core.c +++ b/drivers/staging/fbtft/fbtft-core.c @@ -16,7 +16,7 @@ #include <linux/slab.h> #include <linux/init.h> #include <linux/fb.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/spi/spi.h> #include <linux/delay.h> #include <linux/uaccess.h> @@ -24,7 +24,6 @@ #include <linux/platform_device.h> #include <linux/spinlock.h> #include <linux/of.h> -#include <linux/of_gpio.h> #include <video/mipi_display.h> #include "fbtft.h" @@ -38,8 +37,8 @@ int fbtft_write_buf_dc(struct fbtft_par *par, void *buf, size_t len, int dc) { int ret; - if (gpio_is_valid(par->gpio.dc)) - gpio_set_value(par->gpio.dc, dc); + if (par->gpio.dc) + gpiod_set_value(par->gpio.dc, dc); ret = par->fbtftops.write(par, buf, len); if (ret < 0) @@ -71,127 +70,26 @@ void fbtft_dbg_hex(const struct device *dev, int groupsize, } EXPORT_SYMBOL(fbtft_dbg_hex); -static unsigned long fbtft_request_gpios_match(struct fbtft_par *par, - const struct fbtft_gpio *gpio) -{ - int ret; - unsigned int val; - - fbtft_par_dbg(DEBUG_REQUEST_GPIOS_MATCH, par, "%s('%s')\n", - __func__, gpio->name); - - if (strcasecmp(gpio->name, "reset") == 0) { - par->gpio.reset = gpio->gpio; - return GPIOF_OUT_INIT_HIGH; - } else if (strcasecmp(gpio->name, "dc") == 0) { - par->gpio.dc = gpio->gpio; - return GPIOF_OUT_INIT_LOW; - } else if (strcasecmp(gpio->name, "cs") == 0) { - par->gpio.cs = gpio->gpio; - return GPIOF_OUT_INIT_HIGH; - } else if (strcasecmp(gpio->name, "wr") == 0) { - par->gpio.wr = gpio->gpio; - return GPIOF_OUT_INIT_HIGH; - } else if (strcasecmp(gpio->name, "rd") == 0) { - par->gpio.rd = gpio->gpio; - return GPIOF_OUT_INIT_HIGH; - } else if (strcasecmp(gpio->name, "latch") == 0) { - par->gpio.latch = gpio->gpio; - return GPIOF_OUT_INIT_LOW; - } else if (gpio->name[0] == 'd' && gpio->name[1] == 'b') { - ret = kstrtouint(&gpio->name[2], 10, &val); - if (ret == 0 && val < 16) { - par->gpio.db[val] = gpio->gpio; - return GPIOF_OUT_INIT_LOW; - } - } else if (strcasecmp(gpio->name, "led") == 0) { - par->gpio.led[0] = gpio->gpio; - return GPIOF_OUT_INIT_LOW; - } else if (strcasecmp(gpio->name, "led_") == 0) { - par->gpio.led[0] = gpio->gpio; - return GPIOF_OUT_INIT_HIGH; - } - - return FBTFT_GPIO_NO_MATCH; -} - -static int fbtft_request_gpios(struct fbtft_par *par) -{ - struct fbtft_platform_data *pdata = par->pdata; - const struct fbtft_gpio *gpio; - unsigned long flags; - int ret; - - if (!(pdata && pdata->gpios)) - return 0; - - gpio = pdata->gpios; - while (gpio->name[0]) { - flags = FBTFT_GPIO_NO_MATCH; - /* if driver provides match function, try it first, - * if no match use our own - */ - if (par->fbtftops.request_gpios_match) - flags = par->fbtftops.request_gpios_match(par, gpio); - if (flags == FBTFT_GPIO_NO_MATCH) - flags = fbtft_request_gpios_match(par, gpio); - if (flags != FBTFT_GPIO_NO_MATCH) { - ret = devm_gpio_request_one(par->info->device, - gpio->gpio, flags, - par->info->device->driver->name); - if (ret < 0) { - dev_err(par->info->device, - "%s: gpio_request_one('%s'=%d) failed with %d\n", - __func__, gpio->name, - gpio->gpio, ret); - return ret; - } - fbtft_par_dbg(DEBUG_REQUEST_GPIOS, par, - "%s: '%s' = GPIO%d\n", - __func__, gpio->name, gpio->gpio); - } - gpio++; - } - - return 0; -} - #ifdef CONFIG_OF static int fbtft_request_one_gpio(struct fbtft_par *par, - const char *name, int index, int *gpiop) + const char *name, int index, + struct gpio_desc **gpiop) { struct device *dev = par->info->device; struct device_node *node = dev->of_node; - int gpio, flags, ret = 0; - enum of_gpio_flags of_flags; + int ret = 0; if (of_find_property(node, name, NULL)) { - gpio = of_get_named_gpio_flags(node, name, index, &of_flags); - if (gpio == -ENOENT) - return 0; - if (gpio == -EPROBE_DEFER) - return gpio; - if (gpio < 0) { - dev_err(dev, - "failed to get '%s' from DT\n", name); - return gpio; - } - - /* active low translates to initially low */ - flags = (of_flags & OF_GPIO_ACTIVE_LOW) ? GPIOF_OUT_INIT_LOW : - GPIOF_OUT_INIT_HIGH; - ret = devm_gpio_request_one(dev, gpio, flags, - dev->driver->name); - if (ret) { + *gpiop = devm_gpiod_get_index(dev, dev->driver->name, index, + GPIOD_OUT_HIGH); + if (IS_ERR(*gpiop)) { + ret = PTR_ERR(*gpiop); dev_err(dev, - "gpio_request_one('%s'=%d) failed with %d\n", - name, gpio, ret); + "Failed to request %s GPIO:%d\n", name, ret); return ret; } - if (gpiop) - *gpiop = gpio; - fbtft_par_dbg(DEBUG_REQUEST_GPIOS, par, "%s: '%s' = GPIO%d\n", - __func__, name, gpio); + fbtft_par_dbg(DEBUG_REQUEST_GPIOS, par, "%s: '%s' GPIO\n", + __func__, name); } return ret; @@ -254,9 +152,9 @@ static int fbtft_backlight_update_status(struct backlight_device *bd) if ((bd->props.power == FB_BLANK_UNBLANK) && (bd->props.fb_blank == FB_BLANK_UNBLANK)) - gpio_set_value(par->gpio.led[0], polarity); + gpiod_set_value(par->gpio.led[0], polarity); else - gpio_set_value(par->gpio.led[0], !polarity); + gpiod_set_value(par->gpio.led[0], !polarity); return 0; } @@ -286,7 +184,7 @@ void fbtft_register_backlight(struct fbtft_par *par) struct backlight_device *bd; struct backlight_properties bl_props = { 0, }; - if (par->gpio.led[0] == -1) { + if (!par->gpio.led[0]) { fbtft_par_dbg(DEBUG_BACKLIGHT, par, "%s(): led pin not set, exiting.\n", __func__); return; @@ -295,7 +193,7 @@ void fbtft_register_backlight(struct fbtft_par *par) bl_props.type = BACKLIGHT_RAW; /* Assume backlight is off, get polarity from current state of pin */ bl_props.power = FB_BLANK_POWERDOWN; - if (!gpio_get_value(par->gpio.led[0])) + if (!gpiod_get_value(par->gpio.led[0])) par->polarity = true; bd = backlight_device_register(dev_driver_string(par->info->device), @@ -333,12 +231,12 @@ static void fbtft_set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, static void fbtft_reset(struct fbtft_par *par) { - if (par->gpio.reset == -1) + if (!par->gpio.reset) return; fbtft_par_dbg(DEBUG_RESET, par, "%s()\n", __func__); - gpio_set_value_cansleep(par->gpio.reset, 0); + gpiod_set_value_cansleep(par->gpio.reset, 0); usleep_range(20, 40); - gpio_set_value_cansleep(par->gpio.reset, 1); + gpiod_set_value_cansleep(par->gpio.reset, 1); msleep(120); } @@ -538,9 +436,9 @@ static unsigned int chan_to_field(unsigned int chan, struct fb_bitfield *bf) return chan << bf->offset; } -static int fbtft_fb_setcolreg(unsigned int regno, unsigned int red, unsigned int green, - unsigned int blue, unsigned int transp, - struct fb_info *info) +static int fbtft_fb_setcolreg(unsigned int regno, unsigned int red, + unsigned int green, unsigned int blue, + unsigned int transp, struct fb_info *info) { unsigned int val; int ret = 1; @@ -663,7 +561,7 @@ struct fb_info *fbtft_framebuffer_alloc(struct fbtft_display *display, int txbuflen = display->txbuflen; unsigned int bpp = display->bpp; unsigned int fps = display->fps; - int vmem_size, i; + int vmem_size; const s16 *init_sequence = display->init_sequence; char *gamma = display->gamma; u32 *gamma_curves = NULL; @@ -841,19 +739,6 @@ struct fb_info *fbtft_framebuffer_alloc(struct fbtft_display *display, par->txbuf.len = txbuflen; } - /* Initialize gpios to disabled */ - par->gpio.reset = -1; - par->gpio.dc = -1; - par->gpio.rd = -1; - par->gpio.wr = -1; - par->gpio.cs = -1; - par->gpio.latch = -1; - for (i = 0; i < 16; i++) { - par->gpio.db[i] = -1; - par->gpio.led[i] = -1; - par->gpio.aux[i] = -1; - } - /* default fbtft operations */ par->fbtftops.write = fbtft_write_spi; par->fbtftops.read = fbtft_read_spi; @@ -863,7 +748,6 @@ struct fb_info *fbtft_framebuffer_alloc(struct fbtft_display *display, par->fbtftops.reset = fbtft_reset; par->fbtftops.mkdirty = fbtft_mkdirty; par->fbtftops.update_display = fbtft_update_display; - par->fbtftops.request_gpios = fbtft_request_gpios; if (display->backlight) par->fbtftops.register_backlight = fbtft_register_backlight; @@ -1035,8 +919,8 @@ static int fbtft_init_display_dt(struct fbtft_par *par) return -EINVAL; par->fbtftops.reset(par); - if (par->gpio.cs != -1) - gpio_set_value(par->gpio.cs, 0); /* Activate chip */ + if (!par->gpio.cs) + gpiod_set_value(par->gpio.cs, 0); /* Activate chip */ while (p) { if (val & FBTFT_OF_INIT_CMD) { @@ -1126,8 +1010,8 @@ int fbtft_init_display(struct fbtft_par *par) } par->fbtftops.reset(par); - if (par->gpio.cs != -1) - gpio_set_value(par->gpio.cs, 0); /* Activate chip */ + if (!par->gpio.cs) + gpiod_set_value(par->gpio.cs, 0); /* Activate chip */ i = 0; while (i < FBTFT_MAX_INIT_SEQUENCE) { @@ -1227,7 +1111,7 @@ static int fbtft_verify_gpios(struct fbtft_par *par) fbtft_par_dbg(DEBUG_VERIFY_GPIOS, par, "%s()\n", __func__); if (pdata->display.buswidth != 9 && par->startbyte == 0 && - par->gpio.dc < 0) { + !par->gpio.dc) { dev_err(par->info->device, "Missing info about 'dc' gpio. Aborting.\n"); return -EINVAL; @@ -1236,12 +1120,12 @@ static int fbtft_verify_gpios(struct fbtft_par *par) if (!par->pdev) return 0; - if (par->gpio.wr < 0) { + if (!par->gpio.wr) { dev_err(par->info->device, "Missing 'wr' gpio. Aborting.\n"); return -EINVAL; } for (i = 0; i < pdata->display.buswidth; i++) { - if (par->gpio.db[i] < 0) { + if (!par->gpio.db[i]) { dev_err(par->info->device, "Missing 'db%02d' gpio. Aborting.\n", i); return -EINVAL; diff --git a/drivers/staging/fbtft/fbtft-io.c b/drivers/staging/fbtft/fbtft-io.c index b5051d3d46a6..38cdad6203ea 100644 --- a/drivers/staging/fbtft/fbtft-io.c +++ b/drivers/staging/fbtft/fbtft-io.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 #include <linux/export.h> #include <linux/errno.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/spi/spi.h> #include "fbtft.h" @@ -142,30 +142,30 @@ int fbtft_write_gpio8_wr(struct fbtft_par *par, void *buf, size_t len) data = *(u8 *)buf; /* Start writing by pulling down /WR */ - gpio_set_value(par->gpio.wr, 0); + gpiod_set_value(par->gpio.wr, 0); /* Set data */ #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO if (data == prev_data) { - gpio_set_value(par->gpio.wr, 0); /* used as delay */ + gpiod_set_value(par->gpio.wr, 0); /* used as delay */ } else { for (i = 0; i < 8; i++) { if ((data & 1) != (prev_data & 1)) - gpio_set_value(par->gpio.db[i], - data & 1); + gpiod_set_value(par->gpio.db[i], + data & 1); data >>= 1; prev_data >>= 1; } } #else for (i = 0; i < 8; i++) { - gpio_set_value(par->gpio.db[i], data & 1); + gpiod_set_value(par->gpio.db[i], data & 1); data >>= 1; } #endif /* Pullup /WR */ - gpio_set_value(par->gpio.wr, 1); + gpiod_set_value(par->gpio.wr, 1); #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO prev_data = *(u8 *)buf; @@ -192,30 +192,30 @@ int fbtft_write_gpio16_wr(struct fbtft_par *par, void *buf, size_t len) data = *(u16 *)buf; /* Start writing by pulling down /WR */ - gpio_set_value(par->gpio.wr, 0); + gpiod_set_value(par->gpio.wr, 0); /* Set data */ #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO if (data == prev_data) { - gpio_set_value(par->gpio.wr, 0); /* used as delay */ + gpiod_set_value(par->gpio.wr, 0); /* used as delay */ } else { for (i = 0; i < 16; i++) { if ((data & 1) != (prev_data & 1)) - gpio_set_value(par->gpio.db[i], - data & 1); + gpiod_set_value(par->gpio.db[i], + data & 1); data >>= 1; prev_data >>= 1; } } #else for (i = 0; i < 16; i++) { - gpio_set_value(par->gpio.db[i], data & 1); + gpiod_set_value(par->gpio.db[i], data & 1); data >>= 1; } #endif /* Pullup /WR */ - gpio_set_value(par->gpio.wr, 1); + gpiod_set_value(par->gpio.wr, 1); #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO prev_data = *(u16 *)buf; diff --git a/drivers/staging/fbtft/fbtft.h b/drivers/staging/fbtft/fbtft.h index ac427baa464a..7fdd3b0851ef 100644 --- a/drivers/staging/fbtft/fbtft.h +++ b/drivers/staging/fbtft/fbtft.h @@ -27,7 +27,7 @@ */ struct fbtft_gpio { char name[FBTFT_GPIO_NAME_SIZE]; - unsigned int gpio; + struct gpio_desc *gpio; }; struct fbtft_par; @@ -134,7 +134,6 @@ struct fbtft_display { */ struct fbtft_platform_data { struct fbtft_display display; - const struct fbtft_gpio *gpios; unsigned int rotate; bool bgr; unsigned int fps; @@ -207,15 +206,15 @@ struct fbtft_par { unsigned int dirty_lines_start; unsigned int dirty_lines_end; struct { - int reset; - int dc; - int rd; - int wr; - int latch; - int cs; - int db[16]; - int led[16]; - int aux[16]; + struct gpio_desc *reset; + struct gpio_desc *dc; + struct gpio_desc *rd; + struct gpio_desc *wr; + struct gpio_desc *latch; + struct gpio_desc *cs; + struct gpio_desc *db[16]; + struct gpio_desc *led[16]; + struct gpio_desc *aux[16]; } gpio; const s16 *init_sequence; struct { diff --git a/drivers/staging/fbtft/fbtft_device.c b/drivers/staging/fbtft/fbtft_device.c index 046f9d355ecb..5f6cd0816d58 100644 --- a/drivers/staging/fbtft/fbtft_device.c +++ b/drivers/staging/fbtft/fbtft_device.c @@ -8,7 +8,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/spi/spi.h> #include <video/mipi_display.h> @@ -45,11 +45,6 @@ static int mode = -1; module_param(mode, int, 0000); MODULE_PARM_DESC(mode, "SPI mode (override device default)"); -static char *gpios; -module_param(gpios, charp, 0000); -MODULE_PARM_DESC(gpios, - "List of gpios. Comma separated with the form: reset:23,dc:24 (when overriding the default, all gpios must be specified)"); - static unsigned int fps; module_param(fps, uint, 0000); MODULE_PARM_DESC(fps, "Frames per second (override driver default)"); @@ -101,7 +96,7 @@ MODULE_PARM_DESC(debug, static unsigned int verbose = 3; module_param(verbose, uint, 0000); MODULE_PARM_DESC(verbose, - "0 silent, >0 show gpios, >1 show devices, >2 show devices before (default=3)"); + "0 silent, >1 show devices, >2 show devices before (default=3)"); struct fbtft_device_display { char *name; @@ -279,12 +274,6 @@ static struct fbtft_device_display displays[] = { .buswidth = 8, .backlight = 1, }, - .gpios = (const struct fbtft_gpio []) { - { "reset", 25 }, - { "dc", 24 }, - { "led", 18 }, - {}, - }, .gamma = ADAFRUIT18_GAMMA, } } @@ -302,12 +291,6 @@ static struct fbtft_device_display displays[] = { adafruit18_green_tab_set_addr_win, }, .bgr = true, - .gpios = (const struct fbtft_gpio []) { - { "reset", 25 }, - { "dc", 24 }, - { "led", 18 }, - {}, - }, .gamma = ADAFRUIT18_GAMMA, } } @@ -323,11 +306,6 @@ static struct fbtft_device_display displays[] = { .backlight = 1, }, .bgr = true, - .gpios = (const struct fbtft_gpio []) { - { "reset", 25 }, - { "led", 23 }, - {}, - }, } } }, { @@ -342,12 +320,6 @@ static struct fbtft_device_display displays[] = { .backlight = 1, }, .bgr = true, - .gpios = (const struct fbtft_gpio []) { - { "reset", 25 }, - { "dc", 24 }, - { "led", 18 }, - {}, - }, } } }, { @@ -362,12 +334,6 @@ static struct fbtft_device_display displays[] = { .backlight = 1, }, .bgr = true, - .gpios = (const struct fbtft_gpio []) { - { "reset", 25 }, - { "dc", 24 }, - { "led", 18 }, - {}, - }, } } }, { @@ -380,11 +346,6 @@ static struct fbtft_device_display displays[] = { .display = { .buswidth = 8, }, - .gpios = (const struct fbtft_gpio []) { - { "reset", 25 }, - { "dc", 24 }, - {}, - }, } } }, { @@ -399,12 +360,6 @@ static struct fbtft_device_display displays[] = { .backlight = 1, .init_sequence = cberry28_init_sequence, }, - .gpios = (const struct fbtft_gpio []) { - { "reset", 25 }, - { "dc", 22 }, - { "led", 18 }, - {}, - }, .gamma = CBERRY28_GAMMA, } } @@ -420,9 +375,6 @@ static struct fbtft_device_display displays[] = { .buswidth = 8, .backlight = FBTFT_ONBOARD_BACKLIGHT, }, - .gpios = (const struct fbtft_gpio []) { - {}, - }, }, } } @@ -437,11 +389,6 @@ static struct fbtft_device_display displays[] = { .buswidth = 8, }, .bgr = true, - .gpios = (const struct fbtft_gpio []) { - { "reset", 13 }, - { "dc", 6 }, - {}, - }, } } }, { @@ -458,11 +405,6 @@ static struct fbtft_device_display displays[] = { .height = 272, }, .bgr = true, - .gpios = (const struct fbtft_gpio []) { - { "reset", 25 }, - { "dc", 24 }, - {}, - }, } } }, { @@ -479,11 +421,6 @@ static struct fbtft_device_display displays[] = { .height = 480, }, .bgr = true, - .gpios = (const struct fbtft_gpio []) { - { "reset", 25 }, - { "dc", 24 }, - {}, - }, } } }, { @@ -496,10 +433,6 @@ static struct fbtft_device_display displays[] = { .display = { .buswidth = 8, }, - .gpios = (const struct fbtft_gpio []) { - { "dc", 24 }, - {}, - }, } } }, { @@ -512,9 +445,6 @@ static struct fbtft_device_display displays[] = { .display = { .buswidth = 9, }, - .gpios = (const struct fbtft_gpio []) { - {}, - }, } } }, { @@ -523,13 +453,6 @@ static struct fbtft_device_display displays[] = { .modalias = "flexfb", .max_speed_hz = 32000000, .mode = SPI_MODE_0, - .platform_data = &(struct fbtft_platform_data) { - .gpios = (const struct fbtft_gpio []) { - { "reset", 25 }, - { "dc", 24 }, - {}, - }, - } } }, { .name = "flexpfb", @@ -538,24 +461,6 @@ static struct fbtft_device_display displays[] = { .id = 0, .dev = { .release = fbtft_device_pdev_release, - .platform_data = &(struct fbtft_platform_data) { - .gpios = (const struct fbtft_gpio []) { - { "reset", 17 }, - { "dc", 1 }, - { "wr", 0 }, - { "cs", 21 }, - { "db00", 9 }, - { "db01", 11 }, - { "db02", 18 }, - { "db03", 23 }, - { "db04", 24 }, - { "db05", 25 }, - { "db06", 8 }, - { "db07", 7 }, - { "led", 4 }, - {}, - }, - }, } } }, { @@ -570,11 +475,6 @@ static struct fbtft_device_display displays[] = { .backlight = FBTFT_ONBOARD_BACKLIGHT, }, .bgr = true, - .gpios = (const struct fbtft_gpio []) { - { "reset", 24 }, - { "dc", 25 }, - {}, - }, } } }, { @@ -588,12 +488,6 @@ static struct fbtft_device_display displays[] = { .buswidth = 8, .backlight = 1, }, - .gpios = (const struct fbtft_gpio []) { - { "reset", 25 }, - { "dc", 24 }, - { "led", 23 }, - {}, - }, } } }, { @@ -609,11 +503,6 @@ static struct fbtft_device_display displays[] = { }, .startbyte = 0x70, .bgr = true, - .gpios = (const struct fbtft_gpio []) { - { "reset", 25 }, - { "led", 18 }, - {}, - }, } } }, { @@ -631,11 +520,6 @@ static struct fbtft_device_display displays[] = { .startbyte = 0x70, .bgr = true, .fps = 50, - .gpios = (const struct fbtft_gpio []) { - { "reset", 25 }, - { "led", 18 }, - {}, - }, .gamma = HY28B_GAMMA, } } @@ -652,12 +536,6 @@ static struct fbtft_device_display displays[] = { .backlight = 1, }, .bgr = true, - .gpios = (const struct fbtft_gpio []) { - { "reset", 25 }, - { "dc", 24 }, - { "led", 22 }, - {}, - }, } } }, { @@ -673,22 +551,6 @@ static struct fbtft_device_display displays[] = { .backlight = 1, }, .bgr = false, - .gpios = (const struct fbtft_gpio []) { - /* Wiring for LCD adapter kit */ - { "reset", 7 }, - { "dc", 0 }, /* rev 2: 2 */ - { "wr", 1 }, /* rev 2: 3 */ - { "cs", 8 }, - { "db00", 17 }, - { "db01", 18 }, - { "db02", 21 }, /* rev 2: 27 */ - { "db03", 22 }, - { "db04", 23 }, - { "db05", 24 }, - { "db06", 25 }, - { "db07", 4 }, - {} - }, }, } } @@ -705,9 +567,6 @@ static struct fbtft_device_display displays[] = { .backlight = 1, }, .bgr = true, - .gpios = (const struct fbtft_gpio []) { - {}, - }, }, } } @@ -723,11 +582,6 @@ static struct fbtft_device_display displays[] = { .backlight = 1, }, .bgr = true, - .gpios = (const struct fbtft_gpio []) { - { "reset", 25 }, - { "dc", 24 }, - {}, - }, } } }, { @@ -743,12 +597,6 @@ static struct fbtft_device_display displays[] = { }, .startbyte = 0x70, .bgr = true, - .gpios = (const struct fbtft_gpio []) { - { "reset", 25 }, - { "dc", 24 }, - { "led", 18 }, - {}, - }, } } }, { @@ -763,11 +611,6 @@ static struct fbtft_device_display displays[] = { .backlight = 1, }, .bgr = true, - .gpios = (const struct fbtft_gpio []) { - { "reset", 25 }, - { "led", 18 }, - {}, - }, } } }, { @@ -777,10 +620,6 @@ static struct fbtft_device_display displays[] = { .max_speed_hz = 4000000, .mode = SPI_MODE_3, .platform_data = &(struct fbtft_platform_data) { - .gpios = (const struct fbtft_gpio []) { - { "reset", 25 }, - {}, - }, } } }, { @@ -793,12 +632,6 @@ static struct fbtft_device_display displays[] = { .display = { .buswidth = 8, }, - .gpios = (const struct fbtft_gpio []) { - { "reset", 25 }, - { "dc", 24 }, - { "led", 23 }, - {}, - }, } } }, { @@ -811,12 +644,6 @@ static struct fbtft_device_display displays[] = { .display = { .buswidth = 8, }, - .gpios = (const struct fbtft_gpio []) { - { "reset", 25 }, - { "dc", 24 }, - { "led", 23 }, - {}, - }, } } }, { @@ -831,9 +658,6 @@ static struct fbtft_device_display displays[] = { .backlight = 1, }, .bgr = true, - .gpios = (const struct fbtft_gpio []) { - {}, - }, } } }, { @@ -849,12 +673,6 @@ static struct fbtft_device_display displays[] = { .backlight = 1, }, .bgr = true, - .gpios = (const struct fbtft_gpio []) { - { "reset", 25 }, - { "dc", 24 }, - { "led", 22 }, - {}, - }, } } }, { @@ -871,10 +689,6 @@ static struct fbtft_device_display displays[] = { .init_sequence = pitft_init_sequence, }, .bgr = true, - .gpios = (const struct fbtft_gpio []) { - { "dc", 25 }, - {}, - }, } } }, { @@ -888,11 +702,6 @@ static struct fbtft_device_display displays[] = { .buswidth = 8, }, .bgr = true, - .gpios = (const struct fbtft_gpio []) { - { "reset", 24 }, - { "dc", 25 }, - {}, - }, .gamma = PIOLED_GAMMA } } @@ -908,12 +717,6 @@ static struct fbtft_device_display displays[] = { .backlight = 1, }, .bgr = true, - .gpios = (const struct fbtft_gpio []) { - { "reset", 23 }, - { "dc", 24 }, - { "led", 18 }, - {}, - }, } } }, { @@ -928,12 +731,6 @@ static struct fbtft_device_display displays[] = { .backlight = 1, }, .bgr = true, - .gpios = (const struct fbtft_gpio []) { - { "reset", 25 }, - { "dc", 24 }, - { "led", 23 }, - {}, - }, } } }, { @@ -946,11 +743,6 @@ static struct fbtft_device_display displays[] = { .display = { .buswidth = 8, }, - .gpios = (const struct fbtft_gpio []) { - { "reset", 25 }, - { "dc", 24 }, - {}, - }, } } }, { @@ -968,9 +760,6 @@ static struct fbtft_device_display displays[] = { .fbtftops.write = write_gpio16_wr_slow, }, .bgr = true, - .gpios = (const struct fbtft_gpio []) { - {}, - }, }, }, } @@ -988,9 +777,6 @@ static struct fbtft_device_display displays[] = { .backlight = 1, }, .bgr = true, - .gpios = (const struct fbtft_gpio []) { - {}, - }, }, }, } @@ -1010,9 +796,6 @@ static struct fbtft_device_display displays[] = { fbtft_write_gpio16_wr_latched, }, .bgr = true, - .gpios = (const struct fbtft_gpio []) { - {}, - }, }, }, } @@ -1028,11 +811,6 @@ static struct fbtft_device_display displays[] = { .backlight = 1, }, .bgr = true, - .gpios = (const struct fbtft_gpio []) { - { "reset", 25 }, - { "dc", 24 }, - {}, - }, } } }, { @@ -1044,9 +822,6 @@ static struct fbtft_device_display displays[] = { .chip_select = 0, .mode = SPI_MODE_0, .platform_data = &(struct fbtft_platform_data) { - .gpios = (const struct fbtft_gpio []) { - {}, - }, } } }, { @@ -1059,11 +834,6 @@ static struct fbtft_device_display displays[] = { .display = { .buswidth = 8, }, - .gpios = (const struct fbtft_gpio []) { - { "reset", 24 }, - { "dc", 25 }, - {}, - }, } } }, { @@ -1078,12 +848,6 @@ static struct fbtft_device_display displays[] = { .backlight = 1, }, .bgr = true, - .gpios = (const struct fbtft_gpio []) { - { "reset", 25 }, - { "dc", 24 }, - { "led", 18 }, - {}, - }, } } }, { @@ -1098,12 +862,6 @@ static struct fbtft_device_display displays[] = { .backlight = 1, }, .bgr = true, - .gpios = (const struct fbtft_gpio []) { - { "reset", 25 }, - { "dc", 24 }, - { "led", 18 }, - {}, - }, } } }, { @@ -1118,12 +876,6 @@ static struct fbtft_device_display displays[] = { .backlight = 1, }, .bgr = true, - .gpios = (const struct fbtft_gpio []) { - { "reset", 15 }, - { "dc", 25 }, - { "led_", 18 }, - {}, - }, } } }, { @@ -1138,12 +890,6 @@ static struct fbtft_device_display displays[] = { .backlight = 1, }, .bgr = true, - .gpios = (const struct fbtft_gpio []) { - { "reset", 15 }, - { "dc", 25 }, - { "led_", 18 }, - {}, - }, } } }, { @@ -1156,11 +902,6 @@ static struct fbtft_device_display displays[] = { .display = { .buswidth = 8, }, - .gpios = (const struct fbtft_gpio []) { - { "reset", 24 }, - { "dc", 25 }, - {}, - }, } } }, { @@ -1177,11 +918,6 @@ static struct fbtft_device_display displays[] = { waveshare32b_init_sequence, }, .bgr = true, - .gpios = (const struct fbtft_gpio []) { - { "reset", 27 }, - { "dc", 22 }, - {}, - }, } } }, { @@ -1194,11 +930,6 @@ static struct fbtft_device_display displays[] = { .display = { .buswidth = 8, }, - .gpios = (const struct fbtft_gpio []) { - { "reset", 24 }, - { "dc", 25 }, - {}, - }, } } }, { @@ -1211,9 +942,6 @@ static struct fbtft_device_display displays[] = { .max_speed_hz = 0, .mode = SPI_MODE_0, .platform_data = &(struct fbtft_platform_data) { - .gpios = (const struct fbtft_gpio []) { - {}, - }, } }, .pdev = &(struct platform_device) { @@ -1222,9 +950,6 @@ static struct fbtft_device_display displays[] = { .dev = { .release = fbtft_device_pdev_release, .platform_data = &(struct fbtft_platform_data) { - .gpios = (const struct fbtft_gpio []) { - {}, - }, }, }, }, @@ -1246,30 +971,30 @@ static int write_gpio16_wr_slow(struct fbtft_par *par, void *buf, size_t len) data = *(u16 *)buf; /* Start writing by pulling down /WR */ - gpio_set_value(par->gpio.wr, 0); + gpiod_set_value(par->gpio.wr, 0); /* Set data */ #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO if (data == prev_data) { - gpio_set_value(par->gpio.wr, 0); /* used as delay */ + gpiod_set_value(par->gpio.wr, 0); /* used as delay */ } else { for (i = 0; i < 16; i++) { if ((data & 1) != (prev_data & 1)) - gpio_set_value(par->gpio.db[i], - data & 1); + gpiod_set_value(par->gpio.db[i], + data & 1); data >>= 1; prev_data >>= 1; } } #else for (i = 0; i < 16; i++) { - gpio_set_value(par->gpio.db[i], data & 1); + gpiod_set_value(par->gpio.db[i], data & 1); data >>= 1; } #endif /* Pullup /WR */ - gpio_set_value(par->gpio.wr, 1); + gpiod_set_value(par->gpio.wr, 1); #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO prev_data = *(u16 *)buf; @@ -1289,9 +1014,6 @@ static void adafruit18_green_tab_set_addr_win(struct fbtft_par *par, write_reg(par, 0x2C); } -/* used if gpios parameter is present */ -static struct fbtft_gpio fbtft_device_param_gpios[MAX_GPIOS + 1] = { }; - static void fbtft_device_pdev_release(struct device *dev) { /* Needed to silence this message: @@ -1382,11 +1104,8 @@ static int __init fbtft_device_init(void) { struct spi_board_info *spi = NULL; struct fbtft_platform_data *pdata; - const struct fbtft_gpio *gpio = NULL; - char *p_gpio, *p_name, *p_num; bool found = false; int i = 0; - long val; int ret = 0; if (!name) { @@ -1404,38 +1123,6 @@ static int __init fbtft_device_init(void) return -EINVAL; } - /* parse module parameter: gpios */ - while ((p_gpio = strsep(&gpios, ","))) { - if (!strchr(p_gpio, ':')) { - pr_err("error: missing ':' in gpios parameter: %s\n", - p_gpio); - return -EINVAL; - } - p_num = p_gpio; - p_name = strsep(&p_num, ":"); - if (!p_name || !p_num) { - pr_err("something bad happened parsing gpios parameter: %s\n", - p_gpio); - return -EINVAL; - } - ret = kstrtol(p_num, 10, &val); - if (ret) { - pr_err("could not parse number in gpios parameter: %s:%s\n", - p_name, p_num); - return -EINVAL; - } - strncpy(fbtft_device_param_gpios[i].name, p_name, - FBTFT_GPIO_NAME_SIZE - 1); - fbtft_device_param_gpios[i++].gpio = (int)val; - if (i == MAX_GPIOS) { - pr_err("gpios parameter: exceeded max array size: %d\n", - MAX_GPIOS); - return -EINVAL; - } - } - if (fbtft_device_param_gpios[0].name[0]) - gpio = fbtft_device_param_gpios; - if (verbose > 2) { pr_spi_devices(); /* print list of registered SPI devices */ pr_p_devices(); /* print list of 'fb' platform devices */ @@ -1516,8 +1203,6 @@ static int __init fbtft_device_init(void) pdata->txbuflen = txbuflen; if (init_num) pdata->display.init_sequence = init; - if (gpio) - pdata->gpios = gpio; if (custom) { pdata->display.width = width; pdata->display.height = height; @@ -1549,19 +1234,6 @@ static int __init fbtft_device_init(void) return -EINVAL; } - if (verbose && pdata && pdata->gpios) { - gpio = pdata->gpios; - pr_info("GPIOS used by '%s':\n", name); - found = false; - while (verbose && gpio->name[0]) { - pr_info("'%s' = GPIO%d\n", gpio->name, gpio->gpio); - gpio++; - found = true; - } - if (!found) - pr_info("(none)\n"); - } - if (spi_device && (verbose > 1)) pr_spi_devices(); if (p_device && (verbose > 1)) diff --git a/drivers/staging/fbtft/flexfb.c b/drivers/staging/fbtft/flexfb.c index 2af474469e7d..c5fa59105a43 100644 --- a/drivers/staging/fbtft/flexfb.c +++ b/drivers/staging/fbtft/flexfb.c @@ -9,7 +9,7 @@ #include <linux/kernel.h> #include <linux/init.h> #include <linux/vmalloc.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/spi/spi.h> #include <linux/delay.h> @@ -521,7 +521,7 @@ static int flexfb_verify_gpios_dc(struct fbtft_par *par) { fbtft_par_dbg(DEBUG_VERIFY_GPIOS, par, "%s()\n", __func__); - if (par->gpio.dc < 0) { + if (!par->gpio.dc) { dev_err(par->info->device, "Missing info about 'dc' gpio. Aborting.\n"); return -EINVAL; @@ -537,22 +537,22 @@ static int flexfb_verify_gpios_db(struct fbtft_par *par) fbtft_par_dbg(DEBUG_VERIFY_GPIOS, par, "%s()\n", __func__); - if (par->gpio.dc < 0) { + if (!par->gpio.dc) { dev_err(par->info->device, "Missing info about 'dc' gpio. Aborting.\n"); return -EINVAL; } - if (par->gpio.wr < 0) { + if (!par->gpio.wr) { dev_err(par->info->device, "Missing info about 'wr' gpio. Aborting.\n"); return -EINVAL; } - if (latched && (par->gpio.latch < 0)) { + if (latched && !par->gpio.latch) { dev_err(par->info->device, "Missing info about 'latch' gpio. Aborting.\n"); return -EINVAL; } if (latched) num_db = buswidth / 2; for (i = 0; i < num_db; i++) { - if (par->gpio.db[i] < 0) { + if (!par->gpio.db[i]) { dev_err(par->info->device, "Missing info about 'db%02d' gpio. Aborting.\n", i); diff --git a/drivers/staging/fsl-dpaa2/ethsw/dpsw-cmd.h b/drivers/staging/fsl-dpaa2/ethsw/dpsw-cmd.h index da744f2b0ee6..14b974defa3a 100644 --- a/drivers/staging/fsl-dpaa2/ethsw/dpsw-cmd.h +++ b/drivers/staging/fsl-dpaa2/ethsw/dpsw-cmd.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright 2014-2016 Freescale Semiconductor Inc. * Copyright 2017-2018 NXP diff --git a/drivers/staging/fsl-dpaa2/ethsw/dpsw.h b/drivers/staging/fsl-dpaa2/ethsw/dpsw.h index db43fa3782b8..25635259ce44 100644 --- a/drivers/staging/fsl-dpaa2/ethsw/dpsw.h +++ b/drivers/staging/fsl-dpaa2/ethsw/dpsw.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright 2014-2016 Freescale Semiconductor Inc. * Copyright 2017-2018 NXP diff --git a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c index daabaceeea52..ad577beeb052 100644 --- a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c +++ b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c @@ -505,6 +505,17 @@ static netdev_tx_t port_dropframe(struct sk_buff *skb, return NETDEV_TX_OK; } +static int swdev_get_port_parent_id(struct net_device *dev, + struct netdev_phys_item_id *ppid) +{ + struct ethsw_port_priv *port_priv = netdev_priv(dev); + + ppid->id_len = 1; + ppid->id[0] = port_priv->ethsw_data->dev_id; + + return 0; +} + static const struct net_device_ops ethsw_port_ops = { .ndo_open = port_open, .ndo_stop = port_stop, @@ -515,6 +526,7 @@ static const struct net_device_ops ethsw_port_ops = { .ndo_get_offload_stats = port_get_offload_stats, .ndo_start_xmit = port_dropframe, + .ndo_get_port_parent_id = swdev_get_port_parent_id, }; static void ethsw_links_state_update(struct ethsw_core *ethsw) @@ -628,31 +640,6 @@ static void ethsw_teardown_irqs(struct fsl_mc_device *sw_dev) fsl_mc_free_irqs(sw_dev); } -static int swdev_port_attr_get(struct net_device *netdev, - struct switchdev_attr *attr) -{ - struct ethsw_port_priv *port_priv = netdev_priv(netdev); - - switch (attr->id) { - case SWITCHDEV_ATTR_ID_PORT_PARENT_ID: - attr->u.ppid.id_len = 1; - attr->u.ppid.id[0] = port_priv->ethsw_data->dev_id; - break; - case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS: - attr->u.brport_flags = - (port_priv->ethsw_data->learning ? BR_LEARNING : 0) | - (port_priv->flood ? BR_FLOOD : 0); - break; - case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS_SUPPORT: - attr->u.brport_flags_support = BR_LEARNING | BR_FLOOD; - break; - default: - return -EOPNOTSUPP; - } - - return 0; -} - static int port_attr_stp_state_set(struct net_device *netdev, struct switchdev_trans *trans, u8 state) @@ -665,6 +652,16 @@ static int port_attr_stp_state_set(struct net_device *netdev, return ethsw_port_set_stp_state(port_priv, state); } +static int port_attr_br_flags_pre_set(struct net_device *netdev, + struct switchdev_trans *trans, + unsigned long flags) +{ + if (flags & ~(BR_LEARNING | BR_FLOOD)) + return -EINVAL; + + return 0; +} + static int port_attr_br_flags_set(struct net_device *netdev, struct switchdev_trans *trans, unsigned long flags) @@ -697,6 +694,10 @@ static int swdev_port_attr_set(struct net_device *netdev, err = port_attr_stp_state_set(netdev, trans, attr->u.stp_state); break; + case SWITCHDEV_ATTR_ID_PORT_PRE_BRIDGE_FLAGS: + err = port_attr_br_flags_pre_set(netdev, trans, + attr->u.brport_flags); + break; case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS: err = port_attr_br_flags_set(netdev, trans, attr->u.brport_flags); @@ -924,10 +925,18 @@ static int swdev_port_obj_del(struct net_device *netdev, return err; } -static const struct switchdev_ops ethsw_port_switchdev_ops = { - .switchdev_port_attr_get = swdev_port_attr_get, - .switchdev_port_attr_set = swdev_port_attr_set, -}; +static int +ethsw_switchdev_port_attr_set_event(struct net_device *netdev, + struct switchdev_notifier_port_attr_info *port_attr_info) +{ + int err; + + err = swdev_port_attr_set(netdev, port_attr_info->attr, + port_attr_info->trans); + + port_attr_info->handled = true; + return notifier_from_errno(err); +} /* For the moment, only flood setting needs to be updated */ static int port_bridge_join(struct net_device *netdev, @@ -1047,6 +1056,12 @@ static int port_switchdev_event(struct notifier_block *unused, struct ethsw_switchdev_event_work *switchdev_work; struct switchdev_notifier_fdb_info *fdb_info = ptr; + if (!ethsw_port_dev_check(dev)) + return NOTIFY_DONE; + + if (event == SWITCHDEV_PORT_ATTR_SET) + return ethsw_switchdev_port_attr_set_event(dev, ptr); + switchdev_work = kzalloc(sizeof(*switchdev_work), GFP_ATOMIC); if (!switchdev_work) return NOTIFY_BAD; @@ -1115,6 +1130,8 @@ static int port_switchdev_blocking_event(struct notifier_block *unused, case SWITCHDEV_PORT_OBJ_ADD: /* fall through */ case SWITCHDEV_PORT_OBJ_DEL: return ethsw_switchdev_port_obj_event(event, dev, ptr); + case SWITCHDEV_PORT_ATTR_SET: + return ethsw_switchdev_port_attr_set_event(dev, ptr); } return NOTIFY_DONE; @@ -1434,7 +1451,6 @@ static int ethsw_probe_port(struct ethsw_core *ethsw, u16 port_idx) SET_NETDEV_DEV(port_netdev, dev); port_netdev->netdev_ops = ðsw_port_ops; port_netdev->ethtool_ops = ðsw_port_ethtool_ops; - port_netdev->switchdev_ops = ðsw_port_switchdev_ops; /* Set MTU limits */ port_netdev->min_mtu = ETH_MIN_MTU; diff --git a/drivers/staging/fsl-dpaa2/ethsw/ethsw.h b/drivers/staging/fsl-dpaa2/ethsw/ethsw.h index 069c99bfba74..c48783680a05 100644 --- a/drivers/staging/fsl-dpaa2/ethsw/ethsw.h +++ b/drivers/staging/fsl-dpaa2/ethsw/ethsw.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +/* SPDX-License-Identifier: GPL-2.0 */ /* * DPAA2 Ethernet Switch declarations * diff --git a/drivers/staging/fwserial/fwserial.c b/drivers/staging/fwserial/fwserial.c index 3e416f5bbcba..a1b90ea7fcb8 100644 --- a/drivers/staging/fwserial/fwserial.c +++ b/drivers/staging/fwserial/fwserial.c @@ -1213,6 +1213,7 @@ static int get_serial_info(struct tty_struct *tty, struct serial_struct *ss) { struct fwtty_port *port = tty->driver_data; + mutex_lock(&port->port.mutex); ss->type = PORT_UNKNOWN; ss->line = port->port.tty->index; diff --git a/drivers/staging/gasket/gasket_interrupt.c b/drivers/staging/gasket/gasket_interrupt.c index ad5657d213f0..ff61b782df30 100644 --- a/drivers/staging/gasket/gasket_interrupt.c +++ b/drivers/staging/gasket/gasket_interrupt.c @@ -9,7 +9,6 @@ #include <linux/device.h> #include <linux/interrupt.h> #include <linux/printk.h> -#include <linux/version.h> #ifdef GASKET_KERNEL_TRACE_SUPPORT #define CREATE_TRACE_POINTS #include <trace/events/gasket_interrupt.h> diff --git a/drivers/staging/goldfish/goldfish_audio.c b/drivers/staging/goldfish/goldfish_audio.c index d4520490cf6d..24a738238f9f 100644 --- a/drivers/staging/goldfish/goldfish_audio.c +++ b/drivers/staging/goldfish/goldfish_audio.c @@ -4,16 +4,6 @@ * * Copyright (C) 2007 Google, Inc. * Copyright (C) 2012 Intel, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #include <linux/module.h> diff --git a/drivers/staging/greybus/Kconfig b/drivers/staging/greybus/Kconfig index ab096bcef98c..b571e4e8060b 100644 --- a/drivers/staging/greybus/Kconfig +++ b/drivers/staging/greybus/Kconfig @@ -148,6 +148,7 @@ if GREYBUS_BRIDGED_PHY config GREYBUS_GPIO tristate "Greybus GPIO Bridged PHY driver" depends on GPIOLIB + select GPIOLIB_IRQCHIP ---help--- Select this option if you have a device that follows the Greybus GPIO Bridged PHY Class specification. diff --git a/drivers/staging/greybus/TODO b/drivers/staging/greybus/TODO index 3b90a5711998..31f1f2cb401c 100644 --- a/drivers/staging/greybus/TODO +++ b/drivers/staging/greybus/TODO @@ -1,5 +1,3 @@ * Convert all uses of the old GPIO API from <linux/gpio.h> to the GPIO descriptor API in <linux/gpio/consumer.h> and look up GPIO lines from device tree or ACPI. -* Convert the GPIO driver to use the GPIO irqchip library - GPIOLIB_IRQCHIP instead of reimplementing the same. diff --git a/drivers/staging/greybus/arche-apb-ctrl.c b/drivers/staging/greybus/arche-apb-ctrl.c index be5ffed90bcf..bbf3ba744fc4 100644 --- a/drivers/staging/greybus/arche-apb-ctrl.c +++ b/drivers/staging/greybus/arche-apb-ctrl.c @@ -8,9 +8,8 @@ #include <linux/clk.h> #include <linux/delay.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/interrupt.h> -#include <linux/of_gpio.h> #include <linux/of_irq.h> #include <linux/module.h> #include <linux/pinctrl/consumer.h> @@ -24,12 +23,12 @@ static void apb_bootret_deassert(struct device *dev); struct arche_apb_ctrl_drvdata { /* Control GPIO signals to and from AP <=> AP Bridges */ - int resetn_gpio; - int boot_ret_gpio; - int pwroff_gpio; - int wake_in_gpio; - int wake_out_gpio; - int pwrdn_gpio; + struct gpio_desc *resetn; + struct gpio_desc *boot_ret; + struct gpio_desc *pwroff; + struct gpio_desc *wake_in; + struct gpio_desc *wake_out; + struct gpio_desc *pwrdn; enum arche_platform_state state; bool init_disabled; @@ -37,28 +36,28 @@ struct arche_apb_ctrl_drvdata { struct regulator *vcore; struct regulator *vio; - int clk_en_gpio; + struct gpio_desc *clk_en; struct clk *clk; struct pinctrl *pinctrl; struct pinctrl_state *pin_default; /* V2: SPI Bus control */ - int spi_en_gpio; + struct gpio_desc *spi_en; bool spi_en_polarity_high; }; /* * Note that these low level api's are active high */ -static inline void deassert_reset(unsigned int gpio) +static inline void deassert_reset(struct gpio_desc *gpio) { - gpio_set_value(gpio, 1); + gpiod_set_raw_value(gpio, 1); } -static inline void assert_reset(unsigned int gpio) +static inline void assert_reset(struct gpio_desc *gpio) { - gpio_set_value(gpio, 0); + gpiod_set_raw_value(gpio, 0); } /* @@ -75,11 +74,10 @@ static int coldboot_seq(struct platform_device *pdev) return 0; /* Hold APB in reset state */ - assert_reset(apb->resetn_gpio); + assert_reset(apb->resetn); - if (apb->state == ARCHE_PLATFORM_STATE_FW_FLASHING && - gpio_is_valid(apb->spi_en_gpio)) - devm_gpio_free(dev, apb->spi_en_gpio); + if (apb->state == ARCHE_PLATFORM_STATE_FW_FLASHING && apb->spi_en) + devm_gpiod_put(dev, apb->spi_en); /* Enable power to APB */ if (!IS_ERR(apb->vcore)) { @@ -101,13 +99,13 @@ static int coldboot_seq(struct platform_device *pdev) apb_bootret_deassert(dev); /* On DB3 clock was not mandatory */ - if (gpio_is_valid(apb->clk_en_gpio)) - gpio_set_value(apb->clk_en_gpio, 1); + if (apb->clk_en) + gpiod_set_value(apb->clk_en, 1); usleep_range(100, 200); /* deassert reset to APB : Active-low signal */ - deassert_reset(apb->resetn_gpio); + deassert_reset(apb->resetn); apb->state = ARCHE_PLATFORM_STATE_ACTIVE; @@ -136,25 +134,25 @@ static int fw_flashing_seq(struct platform_device *pdev) return ret; } - if (gpio_is_valid(apb->spi_en_gpio)) { + if (apb->spi_en) { unsigned long flags; if (apb->spi_en_polarity_high) - flags = GPIOF_OUT_INIT_HIGH; + flags = GPIOD_OUT_HIGH; else - flags = GPIOF_OUT_INIT_LOW; + flags = GPIOD_OUT_LOW; - ret = devm_gpio_request_one(dev, apb->spi_en_gpio, - flags, "apb_spi_en"); - if (ret) { - dev_err(dev, "Failed requesting SPI bus en gpio %d\n", - apb->spi_en_gpio); + apb->spi_en = devm_gpiod_get(dev, "spi-en", flags); + if (IS_ERR(apb->spi_en)) { + ret = PTR_ERR(apb->spi_en); + dev_err(dev, "Failed requesting SPI bus en GPIO: %d\n", + ret); return ret; } } /* for flashing device should be in reset state */ - assert_reset(apb->resetn_gpio); + assert_reset(apb->resetn); apb->state = ARCHE_PLATFORM_STATE_FW_FLASHING; return 0; @@ -176,9 +174,8 @@ static int standby_boot_seq(struct platform_device *pdev) apb->state == ARCHE_PLATFORM_STATE_OFF) return 0; - if (apb->state == ARCHE_PLATFORM_STATE_FW_FLASHING && - gpio_is_valid(apb->spi_en_gpio)) - devm_gpio_free(dev, apb->spi_en_gpio); + if (apb->state == ARCHE_PLATFORM_STATE_FW_FLASHING && apb->spi_en) + devm_gpiod_put(dev, apb->spi_en); /* * As per WDM spec, do nothing @@ -201,13 +198,12 @@ static void poweroff_seq(struct platform_device *pdev) if (apb->init_disabled || apb->state == ARCHE_PLATFORM_STATE_OFF) return; - if (apb->state == ARCHE_PLATFORM_STATE_FW_FLASHING && - gpio_is_valid(apb->spi_en_gpio)) - devm_gpio_free(dev, apb->spi_en_gpio); + if (apb->state == ARCHE_PLATFORM_STATE_FW_FLASHING && apb->spi_en) + devm_gpiod_put(dev, apb->spi_en); /* disable the clock */ - if (gpio_is_valid(apb->clk_en_gpio)) - gpio_set_value(apb->clk_en_gpio, 0); + if (apb->clk_en) + gpiod_set_value(apb->clk_en, 0); if (!IS_ERR(apb->vcore) && regulator_is_enabled(apb->vcore) > 0) regulator_disable(apb->vcore); @@ -216,7 +212,7 @@ static void poweroff_seq(struct platform_device *pdev) regulator_disable(apb->vio); /* As part of exit, put APB back in reset state */ - assert_reset(apb->resetn_gpio); + assert_reset(apb->resetn); apb->state = ARCHE_PLATFORM_STATE_OFF; /* TODO: May have to send an event to SVC about this exit */ @@ -226,7 +222,7 @@ static void apb_bootret_deassert(struct device *dev) { struct arche_apb_ctrl_drvdata *apb = dev_get_drvdata(dev); - gpio_set_value(apb->boot_ret_gpio, 0); + gpiod_set_value(apb->boot_ret, 0); } int apb_ctrl_coldboot(struct device *dev) @@ -322,66 +318,44 @@ static int apb_ctrl_get_devtree_data(struct platform_device *pdev, struct arche_apb_ctrl_drvdata *apb) { struct device *dev = &pdev->dev; - struct device_node *np = dev->of_node; int ret; - apb->resetn_gpio = of_get_named_gpio(np, "reset-gpios", 0); - if (apb->resetn_gpio < 0) { - dev_err(dev, "failed to get reset gpio\n"); - return apb->resetn_gpio; - } - ret = devm_gpio_request_one(dev, apb->resetn_gpio, - GPIOF_OUT_INIT_LOW, "apb-reset"); - if (ret) { - dev_err(dev, "Failed requesting reset gpio %d\n", - apb->resetn_gpio); + apb->resetn = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); + if (IS_ERR(apb->resetn)) { + ret = PTR_ERR(apb->resetn); + dev_err(dev, "Failed requesting reset GPIO: %d\n", ret); return ret; } - apb->boot_ret_gpio = of_get_named_gpio(np, "boot-ret-gpios", 0); - if (apb->boot_ret_gpio < 0) { - dev_err(dev, "failed to get boot retention gpio\n"); - return apb->boot_ret_gpio; - } - ret = devm_gpio_request_one(dev, apb->boot_ret_gpio, - GPIOF_OUT_INIT_LOW, "boot retention"); - if (ret) { - dev_err(dev, "Failed requesting bootret gpio %d\n", - apb->boot_ret_gpio); + apb->boot_ret = devm_gpiod_get(dev, "boot-ret", GPIOD_OUT_LOW); + if (IS_ERR(apb->boot_ret)) { + ret = PTR_ERR(apb->boot_ret); + dev_err(dev, "Failed requesting bootret GPIO: %d\n", ret); return ret; } /* It's not mandatory to support power management interface */ - apb->pwroff_gpio = of_get_named_gpio(np, "pwr-off-gpios", 0); - if (apb->pwroff_gpio < 0) { - dev_err(dev, "failed to get power off gpio\n"); - return apb->pwroff_gpio; - } - ret = devm_gpio_request_one(dev, apb->pwroff_gpio, - GPIOF_IN, "pwroff_n"); - if (ret) { - dev_err(dev, "Failed requesting pwroff_n gpio %d\n", - apb->pwroff_gpio); + apb->pwroff = devm_gpiod_get_optional(dev, "pwr-off", GPIOD_IN); + if (IS_ERR(apb->pwroff)) { + ret = PTR_ERR(apb->pwroff); + dev_err(dev, "Failed requesting pwroff_n GPIO: %d\n", ret); return ret; } /* Do not make clock mandatory as of now (for DB3) */ - apb->clk_en_gpio = of_get_named_gpio(np, "clock-en-gpio", 0); - if (apb->clk_en_gpio < 0) { - dev_warn(dev, "failed to get clock en gpio\n"); - } else if (gpio_is_valid(apb->clk_en_gpio)) { - ret = devm_gpio_request_one(dev, apb->clk_en_gpio, - GPIOF_OUT_INIT_LOW, "apb_clk_en"); - if (ret) { - dev_warn(dev, "Failed requesting APB clock en gpio %d\n", - apb->clk_en_gpio); - return ret; - } + apb->clk_en = devm_gpiod_get_optional(dev, "clock-en", GPIOD_OUT_LOW); + if (IS_ERR(apb->clk_en)) { + ret = PTR_ERR(apb->clk_en); + dev_err(dev, "Failed requesting APB clock en GPIO: %d\n", ret); + return ret; } - apb->pwrdn_gpio = of_get_named_gpio(np, "pwr-down-gpios", 0); - if (apb->pwrdn_gpio < 0) - dev_warn(dev, "failed to get power down gpio\n"); + apb->pwrdn = devm_gpiod_get(dev, "pwr-down", GPIOD_OUT_LOW); + if (IS_ERR(apb->pwrdn)) { + ret = PTR_ERR(apb->pwrdn); + dev_warn(dev, "Failed requesting power down GPIO: %d\n", ret); + return ret; + } /* Regulators are optional, as we may have fixed supply coming in */ apb->vcore = devm_regulator_get(dev, "vcore"); @@ -404,12 +378,8 @@ static int apb_ctrl_get_devtree_data(struct platform_device *pdev, } /* Only applicable for platform >= V2 */ - apb->spi_en_gpio = of_get_named_gpio(np, "spi-en-gpio", 0); - if (apb->spi_en_gpio >= 0) { - if (of_property_read_bool(pdev->dev.of_node, - "spi-en-active-high")) - apb->spi_en_polarity_high = true; - } + if (of_property_read_bool(pdev->dev.of_node, "gb,spi-en-active-high")) + apb->spi_en_polarity_high = true; return 0; } diff --git a/drivers/staging/greybus/arche-platform.c b/drivers/staging/greybus/arche-platform.c index 4c36e88766e7..6eb842040c22 100644 --- a/drivers/staging/greybus/arche-platform.c +++ b/drivers/staging/greybus/arche-platform.c @@ -8,10 +8,9 @@ #include <linux/clk.h> #include <linux/delay.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/init.h> #include <linux/module.h> -#include <linux/of_gpio.h> #include <linux/of_platform.h> #include <linux/pinctrl/consumer.h> #include <linux/platform_device.h> @@ -45,14 +44,14 @@ enum svc_wakedetect_state { struct arche_platform_drvdata { /* Control GPIO signals to and from AP <=> SVC */ - int svc_reset_gpio; + struct gpio_desc *svc_reset; bool is_reset_act_hi; - int svc_sysboot_gpio; - int wake_detect_gpio; /* bi-dir,maps to WAKE_MOD & WAKE_FRAME signals */ + struct gpio_desc *svc_sysboot; + struct gpio_desc *wake_detect; /* bi-dir,maps to WAKE_MOD & WAKE_FRAME signals */ enum arche_platform_state state; - int svc_refclk_req; + struct gpio_desc *svc_refclk_req; struct clk *svc_ref_clk; struct pinctrl *pinctrl; @@ -85,9 +84,9 @@ static void arche_platform_set_wake_detect_state( arche_pdata->wake_detect_state = state; } -static inline void svc_reset_onoff(unsigned int gpio, bool onoff) +static inline void svc_reset_onoff(struct gpio_desc *gpio, bool onoff) { - gpio_set_value(gpio, onoff); + gpiod_set_raw_value(gpio, onoff); } static int apb_cold_boot(struct device *dev, void *data) @@ -116,7 +115,6 @@ static int apb_poweroff(struct device *dev, void *data) static void arche_platform_wd_irq_en(struct arche_platform_drvdata *arche_pdata) { /* Enable interrupt here, to read event back from SVC */ - gpio_direction_input(arche_pdata->wake_detect_gpio); enable_irq(arche_pdata->wake_detect_irq); } @@ -160,7 +158,7 @@ static irqreturn_t arche_platform_wd_irq(int irq, void *devid) spin_lock_irqsave(&arche_pdata->wake_lock, flags); - if (gpio_get_value(arche_pdata->wake_detect_gpio)) { + if (gpiod_get_value(arche_pdata->wake_detect)) { /* wake/detect rising */ /* @@ -224,10 +222,9 @@ arche_platform_coldboot_seq(struct arche_platform_drvdata *arche_pdata) dev_info(arche_pdata->dev, "Booting from cold boot state\n"); - svc_reset_onoff(arche_pdata->svc_reset_gpio, - arche_pdata->is_reset_act_hi); + svc_reset_onoff(arche_pdata->svc_reset, arche_pdata->is_reset_act_hi); - gpio_set_value(arche_pdata->svc_sysboot_gpio, 0); + gpiod_set_value(arche_pdata->svc_sysboot, 0); usleep_range(100, 200); ret = clk_prepare_enable(arche_pdata->svc_ref_clk); @@ -238,8 +235,7 @@ arche_platform_coldboot_seq(struct arche_platform_drvdata *arche_pdata) } /* bring SVC out of reset */ - svc_reset_onoff(arche_pdata->svc_reset_gpio, - !arche_pdata->is_reset_act_hi); + svc_reset_onoff(arche_pdata->svc_reset, !arche_pdata->is_reset_act_hi); arche_platform_set_state(arche_pdata, ARCHE_PLATFORM_STATE_ACTIVE); @@ -259,10 +255,9 @@ arche_platform_fw_flashing_seq(struct arche_platform_drvdata *arche_pdata) dev_info(arche_pdata->dev, "Switching to FW flashing state\n"); - svc_reset_onoff(arche_pdata->svc_reset_gpio, - arche_pdata->is_reset_act_hi); + svc_reset_onoff(arche_pdata->svc_reset, arche_pdata->is_reset_act_hi); - gpio_set_value(arche_pdata->svc_sysboot_gpio, 1); + gpiod_set_value(arche_pdata->svc_sysboot, 1); usleep_range(100, 200); @@ -273,8 +268,7 @@ arche_platform_fw_flashing_seq(struct arche_platform_drvdata *arche_pdata) return ret; } - svc_reset_onoff(arche_pdata->svc_reset_gpio, - !arche_pdata->is_reset_act_hi); + svc_reset_onoff(arche_pdata->svc_reset, !arche_pdata->is_reset_act_hi); arche_platform_set_state(arche_pdata, ARCHE_PLATFORM_STATE_FW_FLASHING); @@ -305,8 +299,7 @@ arche_platform_poweroff_seq(struct arche_platform_drvdata *arche_pdata) clk_disable_unprepare(arche_pdata->svc_ref_clk); /* As part of exit, put APB back in reset state */ - svc_reset_onoff(arche_pdata->svc_reset_gpio, - arche_pdata->is_reset_act_hi); + svc_reset_onoff(arche_pdata->svc_reset, arche_pdata->is_reset_act_hi); arche_platform_set_state(arche_pdata, ARCHE_PLATFORM_STATE_OFF); } @@ -435,6 +428,7 @@ static int arche_platform_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct device_node *np = dev->of_node; int ret; + unsigned int flags; arche_pdata = devm_kzalloc(&pdev->dev, sizeof(*arche_pdata), GFP_KERNEL); @@ -444,61 +438,33 @@ static int arche_platform_probe(struct platform_device *pdev) /* setup svc reset gpio */ arche_pdata->is_reset_act_hi = of_property_read_bool(np, "svc,reset-active-high"); - arche_pdata->svc_reset_gpio = of_get_named_gpio(np, - "svc,reset-gpio", - 0); - if (!gpio_is_valid(arche_pdata->svc_reset_gpio)) { - dev_err(dev, "failed to get reset-gpio\n"); - return arche_pdata->svc_reset_gpio; - } - ret = devm_gpio_request(dev, arche_pdata->svc_reset_gpio, "svc-reset"); - if (ret) { - dev_err(dev, "failed to request svc-reset gpio:%d\n", ret); - return ret; - } - ret = gpio_direction_output(arche_pdata->svc_reset_gpio, - arche_pdata->is_reset_act_hi); - if (ret) { - dev_err(dev, "failed to set svc-reset gpio dir:%d\n", ret); + if (arche_pdata->is_reset_act_hi) + flags = GPIOD_OUT_HIGH; + else + flags = GPIOD_OUT_LOW; + + arche_pdata->svc_reset = devm_gpiod_get(dev, "svc,reset", flags); + if (IS_ERR(arche_pdata->svc_reset)) { + ret = PTR_ERR(arche_pdata->svc_reset); + dev_err(dev, "failed to request svc-reset GPIO: %d\n", ret); return ret; } arche_platform_set_state(arche_pdata, ARCHE_PLATFORM_STATE_OFF); - arche_pdata->svc_sysboot_gpio = of_get_named_gpio(np, - "svc,sysboot-gpio", - 0); - if (!gpio_is_valid(arche_pdata->svc_sysboot_gpio)) { - dev_err(dev, "failed to get sysboot gpio\n"); - return arche_pdata->svc_sysboot_gpio; - } - ret = devm_gpio_request(dev, arche_pdata->svc_sysboot_gpio, "sysboot0"); - if (ret) { - dev_err(dev, "failed to request sysboot0 gpio:%d\n", ret); - return ret; - } - ret = gpio_direction_output(arche_pdata->svc_sysboot_gpio, 0); - if (ret) { - dev_err(dev, "failed to set svc-reset gpio dir:%d\n", ret); + arche_pdata->svc_sysboot = devm_gpiod_get(dev, "svc,sysboot", + GPIOD_OUT_LOW); + if (IS_ERR(arche_pdata->svc_sysboot)) { + ret = PTR_ERR(arche_pdata->svc_sysboot); + dev_err(dev, "failed to request sysboot0 GPIO: %d\n", ret); return ret; } /* setup the clock request gpio first */ - arche_pdata->svc_refclk_req = of_get_named_gpio(np, - "svc,refclk-req-gpio", - 0); - if (!gpio_is_valid(arche_pdata->svc_refclk_req)) { - dev_err(dev, "failed to get svc clock-req gpio\n"); - return arche_pdata->svc_refclk_req; - } - ret = devm_gpio_request(dev, arche_pdata->svc_refclk_req, - "svc-clk-req"); - if (ret) { - dev_err(dev, "failed to request svc-clk-req gpio: %d\n", ret); - return ret; - } - ret = gpio_direction_input(arche_pdata->svc_refclk_req); - if (ret) { - dev_err(dev, "failed to set svc-clk-req gpio dir :%d\n", ret); + arche_pdata->svc_refclk_req = devm_gpiod_get(dev, "svc,refclk-req", + GPIOD_IN); + if (IS_ERR(arche_pdata->svc_refclk_req)) { + ret = PTR_ERR(arche_pdata->svc_refclk_req); + dev_err(dev, "failed to request svc-clk-req GPIO: %d\n", ret); return ret; } @@ -515,19 +481,11 @@ static int arche_platform_probe(struct platform_device *pdev) arche_pdata->num_apbs = of_get_child_count(np); dev_dbg(dev, "Number of APB's available - %d\n", arche_pdata->num_apbs); - arche_pdata->wake_detect_gpio = of_get_named_gpio(np, - "svc,wake-detect-gpio", - 0); - if (arche_pdata->wake_detect_gpio < 0) { - dev_err(dev, "failed to get wake detect gpio\n"); - return arche_pdata->wake_detect_gpio; - } - - ret = devm_gpio_request(dev, arche_pdata->wake_detect_gpio, - "wake detect"); - if (ret) { - dev_err(dev, "Failed requesting wake_detect gpio %d\n", - arche_pdata->wake_detect_gpio); + arche_pdata->wake_detect = devm_gpiod_get(dev, "svc,wake-detect", + GPIOD_IN); + if (IS_ERR(arche_pdata->wake_detect)) { + ret = PTR_ERR(arche_pdata->wake_detect); + dev_err(dev, "Failed requesting wake_detect GPIO: %d\n", ret); return ret; } @@ -538,7 +496,7 @@ static int arche_platform_probe(struct platform_device *pdev) spin_lock_init(&arche_pdata->wake_lock); mutex_init(&arche_pdata->platform_state_mutex); arche_pdata->wake_detect_irq = - gpio_to_irq(arche_pdata->wake_detect_gpio); + gpiod_to_irq(arche_pdata->wake_detect); ret = devm_request_threaded_irq(dev, arche_pdata->wake_detect_irq, arche_platform_wd_irq, diff --git a/drivers/staging/greybus/audio_topology.c b/drivers/staging/greybus/audio_topology.c index 8bcbc3c4588c..4ac30accf226 100644 --- a/drivers/staging/greybus/audio_topology.c +++ b/drivers/staging/greybus/audio_topology.c @@ -923,7 +923,6 @@ static int gbaudio_tplg_create_wcontrol(struct gbaudio_module_info *gb, break; default: return -EINVAL; - } dev_dbg(gb->dev, "%s:%d DAPM control created, ret:%d\n", ctl->name, diff --git a/drivers/staging/greybus/bundle.c b/drivers/staging/greybus/bundle.c index 81c018da1248..e97b2b87ba47 100644 --- a/drivers/staging/greybus/bundle.c +++ b/drivers/staging/greybus/bundle.c @@ -65,7 +65,7 @@ static struct attribute *bundle_attrs[] = { ATTRIBUTE_GROUPS(bundle); static struct gb_bundle *gb_bundle_find(struct gb_interface *intf, - u8 bundle_id) + u8 bundle_id) { struct gb_bundle *bundle; diff --git a/drivers/staging/greybus/connection.h b/drivers/staging/greybus/connection.h index 8deeb1d5f008..5ca3befc0636 100644 --- a/drivers/staging/greybus/connection.h +++ b/drivers/staging/greybus/connection.h @@ -88,7 +88,7 @@ void gb_connection_mode_switch_prepare(struct gb_connection *connection); void gb_connection_mode_switch_complete(struct gb_connection *connection); void greybus_data_rcvd(struct gb_host_device *hd, u16 cport_id, - u8 *data, size_t length); + u8 *data, size_t length); void gb_connection_latency_tag_enable(struct gb_connection *connection); void gb_connection_latency_tag_disable(struct gb_connection *connection); diff --git a/drivers/staging/greybus/control.c b/drivers/staging/greybus/control.c index ffa41d31896d..a9e8b6036cac 100644 --- a/drivers/staging/greybus/control.c +++ b/drivers/staging/greybus/control.c @@ -15,7 +15,6 @@ #define GB_CONTROL_VERSION_MAJOR 0 #define GB_CONTROL_VERSION_MINOR 1 - static int gb_control_get_version(struct gb_control *control) { struct gb_interface *intf = control->connection->intf; diff --git a/drivers/staging/greybus/core.c b/drivers/staging/greybus/core.c index 412337daf45c..d6b0d49130c0 100644 --- a/drivers/staging/greybus/core.c +++ b/drivers/staging/greybus/core.c @@ -266,7 +266,7 @@ static int greybus_remove(struct device *dev) } int greybus_register_driver(struct greybus_driver *driver, struct module *owner, - const char *mod_name) + const char *mod_name) { int retval; diff --git a/drivers/staging/greybus/gpio.c b/drivers/staging/greybus/gpio.c index e110681e6f86..3151004d26fb 100644 --- a/drivers/staging/greybus/gpio.c +++ b/drivers/staging/greybus/gpio.c @@ -9,9 +9,9 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/slab.h> -#include <linux/gpio.h> #include <linux/irq.h> #include <linux/irqdomain.h> +#include <linux/gpio/driver.h> #include <linux/mutex.h> #include "greybus.h" @@ -39,11 +39,6 @@ struct gb_gpio_controller { struct gpio_chip chip; struct irq_chip irqc; - struct irq_chip *irqchip; - struct irq_domain *irqdomain; - unsigned int irq_base; - irq_flow_handler_t irq_handler; - unsigned int irq_default_type; struct mutex irq_lock; }; #define gpio_chip_to_gb_gpio_controller(chip) \ @@ -391,7 +386,7 @@ static int gb_gpio_request_handler(struct gb_operation *op) return -EINVAL; } - irq = irq_find_mapping(ggc->irqdomain, event->which); + irq = irq_find_mapping(ggc->chip.irq.domain, event->which); if (!irq) { dev_err(dev, "failed to find IRQ\n"); return -EINVAL; @@ -506,135 +501,6 @@ static int gb_gpio_controller_setup(struct gb_gpio_controller *ggc) return ret; } -/** - * gb_gpio_irq_map() - maps an IRQ into a GB gpio irqchip - * @d: the irqdomain used by this irqchip - * @irq: the global irq number used by this GB gpio irqchip irq - * @hwirq: the local IRQ/GPIO line offset on this GB gpio - * - * This function will set up the mapping for a certain IRQ line on a - * GB gpio by assigning the GB gpio as chip data, and using the irqchip - * stored inside the GB gpio. - */ -static int gb_gpio_irq_map(struct irq_domain *domain, unsigned int irq, - irq_hw_number_t hwirq) -{ - struct gpio_chip *chip = domain->host_data; - struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip); - - irq_set_chip_data(irq, ggc); - irq_set_chip_and_handler(irq, ggc->irqchip, ggc->irq_handler); - irq_set_noprobe(irq); - /* - * No set-up of the hardware will happen if IRQ_TYPE_NONE - * is passed as default type. - */ - if (ggc->irq_default_type != IRQ_TYPE_NONE) - irq_set_irq_type(irq, ggc->irq_default_type); - - return 0; -} - -static void gb_gpio_irq_unmap(struct irq_domain *d, unsigned int irq) -{ - irq_set_chip_and_handler(irq, NULL, NULL); - irq_set_chip_data(irq, NULL); -} - -static const struct irq_domain_ops gb_gpio_domain_ops = { - .map = gb_gpio_irq_map, - .unmap = gb_gpio_irq_unmap, -}; - -/** - * gb_gpio_irqchip_remove() - removes an irqchip added to a gb_gpio_controller - * @ggc: the gb_gpio_controller to remove the irqchip from - * - * This is called only from gb_gpio_remove() - */ -static void gb_gpio_irqchip_remove(struct gb_gpio_controller *ggc) -{ - unsigned int offset; - - /* Remove all IRQ mappings and delete the domain */ - if (ggc->irqdomain) { - for (offset = 0; offset < (ggc->line_max + 1); offset++) - irq_dispose_mapping(irq_find_mapping(ggc->irqdomain, - offset)); - irq_domain_remove(ggc->irqdomain); - } - - if (ggc->irqchip) - ggc->irqchip = NULL; -} - -/** - * gb_gpio_irqchip_add() - adds an irqchip to a gpio chip - * @chip: the gpio chip to add the irqchip to - * @irqchip: the irqchip to add to the adapter - * @first_irq: if not dynamically assigned, the base (first) IRQ to - * allocate gpio irqs from - * @handler: the irq handler to use (often a predefined irq core function) - * @type: the default type for IRQs on this irqchip, pass IRQ_TYPE_NONE - * to have the core avoid setting up any default type in the hardware. - * - * This function closely associates a certain irqchip with a certain - * gpio chip, providing an irq domain to translate the local IRQs to - * global irqs, and making sure that the gpio chip - * is passed as chip data to all related functions. Driver callbacks - * need to use container_of() to get their local state containers back - * from the gpio chip passed as chip data. An irqdomain will be stored - * in the gpio chip that shall be used by the driver to handle IRQ number - * translation. The gpio chip will need to be initialized and registered - * before calling this function. - */ -static int gb_gpio_irqchip_add(struct gpio_chip *chip, - struct irq_chip *irqchip, - unsigned int first_irq, - irq_flow_handler_t handler, - unsigned int type) -{ - struct gb_gpio_controller *ggc; - unsigned int offset; - unsigned int irq_base; - - if (!chip || !irqchip) - return -EINVAL; - - ggc = gpio_chip_to_gb_gpio_controller(chip); - - ggc->irqchip = irqchip; - ggc->irq_handler = handler; - ggc->irq_default_type = type; - ggc->irqdomain = irq_domain_add_simple(NULL, - ggc->line_max + 1, first_irq, - &gb_gpio_domain_ops, chip); - if (!ggc->irqdomain) { - ggc->irqchip = NULL; - return -EINVAL; - } - - /* - * Prepare the mapping since the irqchip shall be orthogonal to - * any gpio calls. If the first_irq was zero, this is - * necessary to allocate descriptors for all IRQs. - */ - for (offset = 0; offset < (ggc->line_max + 1); offset++) { - irq_base = irq_create_mapping(ggc->irqdomain, offset); - if (offset == 0) - ggc->irq_base = irq_base; - } - - return 0; -} - -static int gb_gpio_to_irq(struct gpio_chip *chip, unsigned int offset) -{ - struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip); - - return irq_find_mapping(ggc->irqdomain, offset); -} - static int gb_gpio_probe(struct gbphy_device *gbphy_dev, const struct gbphy_device_id *id) { @@ -694,7 +560,6 @@ static int gb_gpio_probe(struct gbphy_device *gbphy_dev, gpio->get = gb_gpio_get; gpio->set = gb_gpio_set; gpio->set_config = gb_gpio_set_config; - gpio->to_irq = gb_gpio_to_irq; gpio->base = -1; /* Allocate base dynamically */ gpio->ngpio = ggc->line_max + 1; gpio->can_sleep = true; @@ -703,24 +568,24 @@ static int gb_gpio_probe(struct gbphy_device *gbphy_dev, if (ret) goto exit_line_free; - ret = gb_gpio_irqchip_add(gpio, irqc, 0, - handle_level_irq, IRQ_TYPE_NONE); + ret = gpiochip_add(gpio); if (ret) { - dev_err(&gbphy_dev->dev, "failed to add irq chip: %d\n", ret); + dev_err(&gbphy_dev->dev, "failed to add gpio chip: %d\n", ret); goto exit_line_free; } - ret = gpiochip_add(gpio); + ret = gpiochip_irqchip_add(gpio, irqc, 0, handle_level_irq, + IRQ_TYPE_NONE); if (ret) { - dev_err(&gbphy_dev->dev, "failed to add gpio chip: %d\n", ret); - goto exit_gpio_irqchip_remove; + dev_err(&gbphy_dev->dev, "failed to add irq chip: %d\n", ret); + goto exit_gpiochip_remove; } gbphy_runtime_put_autosuspend(gbphy_dev); return 0; -exit_gpio_irqchip_remove: - gb_gpio_irqchip_remove(ggc); +exit_gpiochip_remove: + gpiochip_remove(gpio); exit_line_free: kfree(ggc->lines); exit_connection_disable: @@ -744,7 +609,6 @@ static void gb_gpio_remove(struct gbphy_device *gbphy_dev) gb_connection_disable_rx(connection); gpiochip_remove(&ggc->chip); - gb_gpio_irqchip_remove(ggc); gb_connection_disable(connection); gb_connection_destroy(connection); kfree(ggc->lines); diff --git a/drivers/staging/gs_fpgaboot/gs_fpgaboot.c b/drivers/staging/gs_fpgaboot/gs_fpgaboot.c index fa8b27e091a2..3e154562c64d 100644 --- a/drivers/staging/gs_fpgaboot/gs_fpgaboot.c +++ b/drivers/staging/gs_fpgaboot/gs_fpgaboot.c @@ -1,14 +1,4 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ +// SPDX-License-Identifier: GPL-2.0+ #include <linux/kernel.h> #include <linux/init.h> diff --git a/drivers/staging/gs_fpgaboot/gs_fpgaboot.h b/drivers/staging/gs_fpgaboot/gs_fpgaboot.h index 986e841f6b5e..5cf12c14cca4 100644 --- a/drivers/staging/gs_fpgaboot/gs_fpgaboot.h +++ b/drivers/staging/gs_fpgaboot/gs_fpgaboot.h @@ -1,14 +1,4 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ +/* SPDX-License-Identifier: GPL-2.0+ */ #include <linux/firmware.h> diff --git a/drivers/staging/gs_fpgaboot/io.c b/drivers/staging/gs_fpgaboot/io.c index 83a13ca7259a..80903ec36b76 100644 --- a/drivers/staging/gs_fpgaboot/io.c +++ b/drivers/staging/gs_fpgaboot/io.c @@ -1,15 +1,4 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - */ +// SPDX-License-Identifier: GPL-2.0+ #include <linux/kernel.h> #include <linux/init.h> @@ -50,8 +39,7 @@ int xl_supported_prog_bus_width(enum wbus bus_bytes) case bus_2byte: break; default: - pr_err("unsupported program bus width %d\n", - bus_bytes); + pr_err("unsupported program bus width %d\n", bus_bytes); return 0; } diff --git a/drivers/staging/gs_fpgaboot/io.h b/drivers/staging/gs_fpgaboot/io.h index bc5d99cbda8f..9bd86a92e90f 100644 --- a/drivers/staging/gs_fpgaboot/io.h +++ b/drivers/staging/gs_fpgaboot/io.h @@ -1,14 +1,4 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ +/* SPDX-License-Identifier: GPL-2.0+ */ #define GPDIR 0 #define GPCFG 4 /* open drain or not */ diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig index fc23059f1673..7a93d3a5c113 100644 --- a/drivers/staging/iio/adc/Kconfig +++ b/drivers/staging/iio/adc/Kconfig @@ -3,40 +3,6 @@ # menu "Analog to digital converters" -config AD7606 - tristate "Analog Devices AD7606 ADC driver" - depends on GPIOLIB || COMPILE_TEST - depends on HAS_IOMEM - select IIO_BUFFER - select IIO_TRIGGERED_BUFFER - help - Say yes here to build support for Analog Devices: - ad7605-4, ad7606, ad7606-6, ad7606-4 analog to digital converters (ADC). - - To compile this driver as a module, choose M here: the - module will be called ad7606. - -config AD7606_IFACE_PARALLEL - tristate "parallel interface support" - depends on AD7606 - help - Say yes here to include parallel interface support on the AD7606 - ADC driver. - - To compile this driver as a module, choose M here: the - module will be called ad7606_parallel. - -config AD7606_IFACE_SPI - tristate "spi interface support" - depends on AD7606 - depends on SPI - help - Say yes here to include parallel interface support on the AD7606 - ADC driver. - - To compile this driver as a module, choose M here: the - module will be called ad7606_spi. - config AD7780 tristate "Analog Devices AD7780 and similar ADCs driver" depends on SPI diff --git a/drivers/staging/iio/adc/Makefile b/drivers/staging/iio/adc/Makefile index ebe83c1ad362..7a421088ff82 100644 --- a/drivers/staging/iio/adc/Makefile +++ b/drivers/staging/iio/adc/Makefile @@ -3,10 +3,6 @@ # Makefile for industrial I/O ADC drivers # -obj-$(CONFIG_AD7606_IFACE_PARALLEL) += ad7606_par.o -obj-$(CONFIG_AD7606_IFACE_SPI) += ad7606_spi.o -obj-$(CONFIG_AD7606) += ad7606.o - obj-$(CONFIG_AD7780) += ad7780.o obj-$(CONFIG_AD7816) += ad7816.o obj-$(CONFIG_AD7192) += ad7192.o diff --git a/drivers/staging/iio/adc/ad7280a.c b/drivers/staging/iio/adc/ad7280a.c index 14f6a3ced060..d9df12665176 100644 --- a/drivers/staging/iio/adc/ad7280a.c +++ b/drivers/staging/iio/adc/ad7280a.c @@ -97,6 +97,10 @@ #define AD7280A_NUM_CH (AD7280A_AUX_ADC_6 - \ AD7280A_CELL_VOLTAGE_1 + 1) +#define AD7280A_CALC_VOLTAGE_CHAN_NUM(d, c) ((d * AD7280A_CELLS_PER_DEV) + c) +#define AD7280A_CALC_TEMP_CHAN_NUM(d, c) ((d * AD7280A_CELLS_PER_DEV) + \ + c - AD7280A_CELLS_PER_DEV) + #define AD7280A_DEVADDR_MASTER 0 #define AD7280A_DEVADDR_ALL 0x1F /* 5-bit device address is sent LSB first */ @@ -496,72 +500,171 @@ static const struct attribute_group ad7280_attrs_group = { .attrs = ad7280_attributes, }; +static void ad7280_voltage_channel_init(struct iio_chan_spec *chan, int i) +{ + chan->type = IIO_VOLTAGE; + chan->differential = 1; + chan->channel = i; + chan->channel2 = chan->channel + 1; +} + +static void ad7280_temp_channel_init(struct iio_chan_spec *chan, int i) +{ + chan->type = IIO_TEMP; + chan->channel = i; +} + +static void ad7280_common_fields_init(struct iio_chan_spec *chan, int addr, + int cnt) +{ + chan->indexed = 1; + chan->info_mask_separate = BIT(IIO_CHAN_INFO_RAW); + chan->info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE); + chan->address = addr; + chan->scan_index = cnt; + chan->scan_type.sign = 'u'; + chan->scan_type.realbits = 12; + chan->scan_type.storagebits = 32; +} + +static void ad7280_total_voltage_channel_init(struct iio_chan_spec *chan, + int cnt, int dev) +{ + chan->type = IIO_VOLTAGE; + chan->differential = 1; + chan->channel = 0; + chan->channel2 = dev * AD7280A_CELLS_PER_DEV; + chan->address = AD7280A_ALL_CELLS; + chan->indexed = 1; + chan->info_mask_separate = BIT(IIO_CHAN_INFO_RAW); + chan->info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE); + chan->scan_index = cnt; + chan->scan_type.sign = 'u'; + chan->scan_type.realbits = 32; + chan->scan_type.storagebits = 32; +} + +static void ad7280_timestamp_channel_init(struct iio_chan_spec *chan, int cnt) +{ + chan->type = IIO_TIMESTAMP; + chan->channel = -1; + chan->scan_index = cnt; + chan->scan_type.sign = 's'; + chan->scan_type.realbits = 64; + chan->scan_type.storagebits = 64; +} + +static void ad7280_init_dev_channels(struct ad7280_state *st, int dev, int *cnt) +{ + int addr, ch, i; + struct iio_chan_spec *chan; + + for (ch = AD7280A_CELL_VOLTAGE_1; ch <= AD7280A_AUX_ADC_6; ch++) { + chan = &st->channels[*cnt]; + + if (ch < AD7280A_AUX_ADC_1) { + i = AD7280A_CALC_VOLTAGE_CHAN_NUM(dev, ch); + ad7280_voltage_channel_init(chan, i); + } else { + i = AD7280A_CALC_TEMP_CHAN_NUM(dev, ch); + ad7280_temp_channel_init(chan, i); + } + + addr = ad7280a_devaddr(dev) << 8 | ch; + ad7280_common_fields_init(chan, addr, *cnt); + + (*cnt)++; + } +} + static int ad7280_channel_init(struct ad7280_state *st) { - int dev, ch, cnt; + int dev, cnt = 0; st->channels = devm_kcalloc(&st->spi->dev, (st->slave_num + 1) * 12 + 2, sizeof(*st->channels), GFP_KERNEL); if (!st->channels) return -ENOMEM; - for (dev = 0, cnt = 0; dev <= st->slave_num; dev++) - for (ch = AD7280A_CELL_VOLTAGE_1; ch <= AD7280A_AUX_ADC_6; - ch++, cnt++) { - if (ch < AD7280A_AUX_ADC_1) { - st->channels[cnt].type = IIO_VOLTAGE; - st->channels[cnt].differential = 1; - st->channels[cnt].channel = (dev * 6) + ch; - st->channels[cnt].channel2 = - st->channels[cnt].channel + 1; - } else { - st->channels[cnt].type = IIO_TEMP; - st->channels[cnt].channel = (dev * 6) + ch - 6; - } - st->channels[cnt].indexed = 1; - st->channels[cnt].info_mask_separate = - BIT(IIO_CHAN_INFO_RAW); - st->channels[cnt].info_mask_shared_by_type = - BIT(IIO_CHAN_INFO_SCALE); - st->channels[cnt].address = - ad7280a_devaddr(dev) << 8 | ch; - st->channels[cnt].scan_index = cnt; - st->channels[cnt].scan_type.sign = 'u'; - st->channels[cnt].scan_type.realbits = 12; - st->channels[cnt].scan_type.storagebits = 32; - st->channels[cnt].scan_type.shift = 0; - } + for (dev = 0; dev <= st->slave_num; dev++) + ad7280_init_dev_channels(st, dev, &cnt); - st->channels[cnt].type = IIO_VOLTAGE; - st->channels[cnt].differential = 1; - st->channels[cnt].channel = 0; - st->channels[cnt].channel2 = dev * 6; - st->channels[cnt].address = AD7280A_ALL_CELLS; - st->channels[cnt].indexed = 1; - st->channels[cnt].info_mask_separate = BIT(IIO_CHAN_INFO_RAW); - st->channels[cnt].info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE); - st->channels[cnt].scan_index = cnt; - st->channels[cnt].scan_type.sign = 'u'; - st->channels[cnt].scan_type.realbits = 32; - st->channels[cnt].scan_type.storagebits = 32; - st->channels[cnt].scan_type.shift = 0; + ad7280_total_voltage_channel_init(&st->channels[cnt], cnt, dev); cnt++; - st->channels[cnt].type = IIO_TIMESTAMP; - st->channels[cnt].channel = -1; - st->channels[cnt].scan_index = cnt; - st->channels[cnt].scan_type.sign = 's'; - st->channels[cnt].scan_type.realbits = 64; - st->channels[cnt].scan_type.storagebits = 64; - st->channels[cnt].scan_type.shift = 0; + ad7280_timestamp_channel_init(&st->channels[cnt], cnt); return cnt + 1; } -static int ad7280_attr_init(struct ad7280_state *st) +static int ad7280_balance_switch_attr_init(struct iio_dev_attr *attr, + struct device *dev, int addr, int i) { - int dev, ch, cnt; - unsigned int index; + attr->address = addr; + attr->dev_attr.attr.mode = 0644; + attr->dev_attr.show = ad7280_show_balance_sw; + attr->dev_attr.store = ad7280_store_balance_sw; + attr->dev_attr.attr.name = devm_kasprintf(dev, GFP_KERNEL, + "in%d-in%d_balance_switch_en", + i, i + 1); + if (!attr->dev_attr.attr.name) + return -ENOMEM; + + return 0; +} + +static int ad7280_balance_timer_attr_init(struct iio_dev_attr *attr, + struct device *dev, int addr, int i) +{ + attr->address = addr; + attr->dev_attr.attr.mode = 0644; + attr->dev_attr.show = ad7280_show_balance_timer; + attr->dev_attr.store = ad7280_store_balance_timer; + attr->dev_attr.attr.name = devm_kasprintf(dev, GFP_KERNEL, + "in%d-in%d_balance_timer", + i, i + 1); + if (!attr->dev_attr.attr.name) + return -ENOMEM; + + return 0; +} + +static int ad7280_init_dev_attrs(struct ad7280_state *st, int dev, int *cnt) +{ + int addr, ch, i, ret; struct iio_dev_attr *iio_attr; + struct device *sdev = &st->spi->dev; + + for (ch = AD7280A_CELL_VOLTAGE_1; ch <= AD7280A_CELL_VOLTAGE_6; ch++) { + iio_attr = &st->iio_attr[*cnt]; + addr = ad7280a_devaddr(dev) << 8 | ch; + i = dev * AD7280A_CELLS_PER_DEV + ch; + + ret = ad7280_balance_switch_attr_init(iio_attr, sdev, addr, i); + if (ret < 0) + return ret; + + ad7280_attributes[*cnt] = &iio_attr->dev_attr.attr; + + (*cnt)++; + iio_attr = &st->iio_attr[*cnt]; + addr = ad7280a_devaddr(dev) << 8 | (AD7280A_CB1_TIMER + ch); + + ret = ad7280_balance_timer_attr_init(iio_attr, sdev, addr, i); + if (ret < 0) + return ret; + + ad7280_attributes[*cnt] = &iio_attr->dev_attr.attr; + (*cnt)++; + } + + ad7280_attributes[*cnt] = NULL; + + return 0; +} + +static int ad7280_attr_init(struct ad7280_state *st) +{ + int dev, cnt = 0, ret; st->iio_attr = devm_kcalloc(&st->spi->dev, 2, sizeof(*st->iio_attr) * (st->slave_num + 1) * AD7280A_CELLS_PER_DEV, @@ -569,41 +672,11 @@ static int ad7280_attr_init(struct ad7280_state *st) if (!st->iio_attr) return -ENOMEM; - for (dev = 0, cnt = 0; dev <= st->slave_num; dev++) - for (ch = AD7280A_CELL_VOLTAGE_1; ch <= AD7280A_CELL_VOLTAGE_6; - ch++, cnt++) { - iio_attr = &st->iio_attr[cnt]; - index = dev * AD7280A_CELLS_PER_DEV + ch; - iio_attr->address = ad7280a_devaddr(dev) << 8 | ch; - iio_attr->dev_attr.attr.mode = 0644; - iio_attr->dev_attr.show = ad7280_show_balance_sw; - iio_attr->dev_attr.store = ad7280_store_balance_sw; - iio_attr->dev_attr.attr.name = - devm_kasprintf(&st->spi->dev, GFP_KERNEL, - "in%d-in%d_balance_switch_en", - index, index + 1); - if (!iio_attr->dev_attr.attr.name) - return -ENOMEM; - - ad7280_attributes[cnt] = &iio_attr->dev_attr.attr; - cnt++; - iio_attr = &st->iio_attr[cnt]; - iio_attr->address = ad7280a_devaddr(dev) << 8 | - (AD7280A_CB1_TIMER + ch); - iio_attr->dev_attr.attr.mode = 0644; - iio_attr->dev_attr.show = ad7280_show_balance_timer; - iio_attr->dev_attr.store = ad7280_store_balance_timer; - iio_attr->dev_attr.attr.name = - devm_kasprintf(&st->spi->dev, GFP_KERNEL, - "in%d-in%d_balance_timer", - index, index + 1); - if (!iio_attr->dev_attr.attr.name) - return -ENOMEM; - - ad7280_attributes[cnt] = &iio_attr->dev_attr.attr; - } - - ad7280_attributes[cnt] = NULL; + for (dev = 0; dev <= st->slave_num; dev++) { + ret = ad7280_init_dev_attrs(st, dev, &cnt); + if (ret < 0) + return ret; + } return 0; } diff --git a/drivers/staging/iio/adc/ad7606.c b/drivers/staging/iio/adc/ad7606.c deleted file mode 100644 index 7308fa8fbb4c..000000000000 --- a/drivers/staging/iio/adc/ad7606.c +++ /dev/null @@ -1,563 +0,0 @@ -/* - * AD7606 SPI ADC driver - * - * Copyright 2011 Analog Devices Inc. - * - * Licensed under the GPL-2. - */ - -#include <linux/interrupt.h> -#include <linux/device.h> -#include <linux/kernel.h> -#include <linux/slab.h> -#include <linux/sysfs.h> -#include <linux/regulator/consumer.h> -#include <linux/err.h> -#include <linux/gpio/consumer.h> -#include <linux/delay.h> -#include <linux/sched.h> -#include <linux/module.h> - -#include <linux/iio/iio.h> -#include <linux/iio/sysfs.h> -#include <linux/iio/buffer.h> -#include <linux/iio/trigger_consumer.h> -#include <linux/iio/triggered_buffer.h> - -#include "ad7606.h" - -/* - * Scales are computed as 5000/32768 and 10000/32768 respectively, - * so that when applied to the raw values they provide mV values - */ -static const unsigned int scale_avail[2][2] = { - {0, 152588}, {0, 305176} -}; - -static int ad7606_reset(struct ad7606_state *st) -{ - if (st->gpio_reset) { - gpiod_set_value(st->gpio_reset, 1); - ndelay(100); /* t_reset >= 100ns */ - gpiod_set_value(st->gpio_reset, 0); - return 0; - } - - return -ENODEV; -} - -static int ad7606_read_samples(struct ad7606_state *st) -{ - unsigned int num = st->chip_info->num_channels; - u16 *data = st->data; - int ret; - - /* - * The frstdata signal is set to high while and after reading the sample - * of the first channel and low for all other channels. This can be used - * to check that the incoming data is correctly aligned. During normal - * operation the data should never become unaligned, but some glitch or - * electrostatic discharge might cause an extra read or clock cycle. - * Monitoring the frstdata signal allows to recover from such failure - * situations. - */ - - if (st->gpio_frstdata) { - ret = st->bops->read_block(st->dev, 1, data); - if (ret) - return ret; - - if (!gpiod_get_value(st->gpio_frstdata)) { - ad7606_reset(st); - return -EIO; - } - - data++; - num--; - } - - return st->bops->read_block(st->dev, num, data); -} - -static irqreturn_t ad7606_trigger_handler(int irq, void *p) -{ - struct iio_poll_func *pf = p; - struct ad7606_state *st = iio_priv(pf->indio_dev); - - gpiod_set_value(st->gpio_convst, 1); - - return IRQ_HANDLED; -} - -/** - * ad7606_poll_bh_to_ring() bh of trigger launched polling to ring buffer - * @work_s: the work struct through which this was scheduled - * - * Currently there is no option in this driver to disable the saving of - * timestamps within the ring. - * I think the one copy of this at a time was to avoid problems if the - * trigger was set far too high and the reads then locked up the computer. - **/ -static void ad7606_poll_bh_to_ring(struct work_struct *work_s) -{ - struct ad7606_state *st = container_of(work_s, struct ad7606_state, - poll_work); - struct iio_dev *indio_dev = iio_priv_to_dev(st); - int ret; - - ret = ad7606_read_samples(st); - if (ret == 0) - iio_push_to_buffers_with_timestamp(indio_dev, st->data, - iio_get_time_ns(indio_dev)); - - gpiod_set_value(st->gpio_convst, 0); - iio_trigger_notify_done(indio_dev->trig); -} - -static int ad7606_scan_direct(struct iio_dev *indio_dev, unsigned int ch) -{ - struct ad7606_state *st = iio_priv(indio_dev); - int ret; - - st->done = false; - gpiod_set_value(st->gpio_convst, 1); - - ret = wait_event_interruptible(st->wq_data_avail, st->done); - if (ret) - goto error_ret; - - ret = ad7606_read_samples(st); - if (ret == 0) - ret = st->data[ch]; - -error_ret: - gpiod_set_value(st->gpio_convst, 0); - - return ret; -} - -static int ad7606_read_raw(struct iio_dev *indio_dev, - struct iio_chan_spec const *chan, - int *val, - int *val2, - long m) -{ - int ret; - struct ad7606_state *st = iio_priv(indio_dev); - - switch (m) { - case IIO_CHAN_INFO_RAW: - ret = iio_device_claim_direct_mode(indio_dev); - if (ret) - return ret; - - ret = ad7606_scan_direct(indio_dev, chan->address); - iio_device_release_direct_mode(indio_dev); - - if (ret < 0) - return ret; - *val = (short)ret; - return IIO_VAL_INT; - case IIO_CHAN_INFO_SCALE: - *val = scale_avail[st->range][0]; - *val2 = scale_avail[st->range][1]; - return IIO_VAL_INT_PLUS_MICRO; - case IIO_CHAN_INFO_OVERSAMPLING_RATIO: - *val = st->oversampling; - return IIO_VAL_INT; - } - return -EINVAL; -} - -static ssize_t in_voltage_scale_available_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - int i, len = 0; - - for (i = 0; i < ARRAY_SIZE(scale_avail); i++) - len += scnprintf(buf + len, PAGE_SIZE - len, "%d.%06u ", - scale_avail[i][0], scale_avail[i][1]); - - buf[len - 1] = '\n'; - - return len; -} - -static IIO_DEVICE_ATTR_RO(in_voltage_scale_available, 0); - -static int ad7606_oversampling_get_index(unsigned int val) -{ - unsigned char supported[] = {1, 2, 4, 8, 16, 32, 64}; - int i; - - for (i = 0; i < ARRAY_SIZE(supported); i++) - if (val == supported[i]) - return i; - - return -EINVAL; -} - -static int ad7606_write_raw(struct iio_dev *indio_dev, - struct iio_chan_spec const *chan, - int val, - int val2, - long mask) -{ - struct ad7606_state *st = iio_priv(indio_dev); - DECLARE_BITMAP(values, 3); - int ret, i; - - switch (mask) { - case IIO_CHAN_INFO_SCALE: - ret = -EINVAL; - mutex_lock(&st->lock); - for (i = 0; i < ARRAY_SIZE(scale_avail); i++) - if (val2 == scale_avail[i][1]) { - gpiod_set_value(st->gpio_range, i); - st->range = i; - - ret = 0; - break; - } - mutex_unlock(&st->lock); - - return ret; - case IIO_CHAN_INFO_OVERSAMPLING_RATIO: - if (val2) - return -EINVAL; - ret = ad7606_oversampling_get_index(val); - if (ret < 0) - return ret; - - values[0] = ret; - - mutex_lock(&st->lock); - gpiod_set_array_value(3, st->gpio_os->desc, st->gpio_os->info, - values); - st->oversampling = val; - mutex_unlock(&st->lock); - - return 0; - default: - return -EINVAL; - } -} - -static IIO_CONST_ATTR(oversampling_ratio_available, "1 2 4 8 16 32 64"); - -static struct attribute *ad7606_attributes_os_and_range[] = { - &iio_dev_attr_in_voltage_scale_available.dev_attr.attr, - &iio_const_attr_oversampling_ratio_available.dev_attr.attr, - NULL, -}; - -static const struct attribute_group ad7606_attribute_group_os_and_range = { - .attrs = ad7606_attributes_os_and_range, -}; - -static struct attribute *ad7606_attributes_os[] = { - &iio_const_attr_oversampling_ratio_available.dev_attr.attr, - NULL, -}; - -static const struct attribute_group ad7606_attribute_group_os = { - .attrs = ad7606_attributes_os, -}; - -static struct attribute *ad7606_attributes_range[] = { - &iio_dev_attr_in_voltage_scale_available.dev_attr.attr, - NULL, -}; - -static const struct attribute_group ad7606_attribute_group_range = { - .attrs = ad7606_attributes_range, -}; - -#define AD760X_CHANNEL(num, mask) \ - { \ - .type = IIO_VOLTAGE, \ - .indexed = 1, \ - .channel = num, \ - .address = num, \ - .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ - .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),\ - .info_mask_shared_by_all = mask, \ - .scan_index = num, \ - .scan_type = { \ - .sign = 's', \ - .realbits = 16, \ - .storagebits = 16, \ - .endianness = IIO_CPU, \ - }, \ - } - -#define AD7605_CHANNEL(num) \ - AD760X_CHANNEL(num, 0) - -#define AD7606_CHANNEL(num) \ - AD760X_CHANNEL(num, BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO)) - -static const struct iio_chan_spec ad7605_channels[] = { - IIO_CHAN_SOFT_TIMESTAMP(4), - AD7605_CHANNEL(0), - AD7605_CHANNEL(1), - AD7605_CHANNEL(2), - AD7605_CHANNEL(3), -}; - -static const struct iio_chan_spec ad7606_channels[] = { - IIO_CHAN_SOFT_TIMESTAMP(8), - AD7606_CHANNEL(0), - AD7606_CHANNEL(1), - AD7606_CHANNEL(2), - AD7606_CHANNEL(3), - AD7606_CHANNEL(4), - AD7606_CHANNEL(5), - AD7606_CHANNEL(6), - AD7606_CHANNEL(7), -}; - -static const struct ad7606_chip_info ad7606_chip_info_tbl[] = { - /* - * More devices added in future - */ - [ID_AD7605_4] = { - .channels = ad7605_channels, - .num_channels = 5, - }, - [ID_AD7606_8] = { - .channels = ad7606_channels, - .num_channels = 9, - .has_oversampling = true, - }, - [ID_AD7606_6] = { - .channels = ad7606_channels, - .num_channels = 7, - .has_oversampling = true, - }, - [ID_AD7606_4] = { - .channels = ad7606_channels, - .num_channels = 5, - .has_oversampling = true, - }, -}; - -static int ad7606_request_gpios(struct ad7606_state *st) -{ - struct device *dev = st->dev; - - st->gpio_convst = devm_gpiod_get(dev, "conversion-start", - GPIOD_OUT_LOW); - if (IS_ERR(st->gpio_convst)) - return PTR_ERR(st->gpio_convst); - - st->gpio_reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW); - if (IS_ERR(st->gpio_reset)) - return PTR_ERR(st->gpio_reset); - - st->gpio_range = devm_gpiod_get_optional(dev, "range", GPIOD_OUT_LOW); - if (IS_ERR(st->gpio_range)) - return PTR_ERR(st->gpio_range); - - st->gpio_standby = devm_gpiod_get_optional(dev, "standby", - GPIOD_OUT_HIGH); - if (IS_ERR(st->gpio_standby)) - return PTR_ERR(st->gpio_standby); - - st->gpio_frstdata = devm_gpiod_get_optional(dev, "first-data", - GPIOD_IN); - if (IS_ERR(st->gpio_frstdata)) - return PTR_ERR(st->gpio_frstdata); - - if (!st->chip_info->has_oversampling) - return 0; - - st->gpio_os = devm_gpiod_get_array_optional(dev, "oversampling-ratio", - GPIOD_OUT_LOW); - return PTR_ERR_OR_ZERO(st->gpio_os); -} - -/** - * Interrupt handler - */ -static irqreturn_t ad7606_interrupt(int irq, void *dev_id) -{ - struct iio_dev *indio_dev = dev_id; - struct ad7606_state *st = iio_priv(indio_dev); - - if (iio_buffer_enabled(indio_dev)) { - schedule_work(&st->poll_work); - } else { - st->done = true; - wake_up_interruptible(&st->wq_data_avail); - } - - return IRQ_HANDLED; -}; - -static const struct iio_info ad7606_info_no_os_or_range = { - .read_raw = &ad7606_read_raw, -}; - -static const struct iio_info ad7606_info_os_and_range = { - .read_raw = &ad7606_read_raw, - .write_raw = &ad7606_write_raw, - .attrs = &ad7606_attribute_group_os_and_range, -}; - -static const struct iio_info ad7606_info_os = { - .read_raw = &ad7606_read_raw, - .write_raw = &ad7606_write_raw, - .attrs = &ad7606_attribute_group_os, -}; - -static const struct iio_info ad7606_info_range = { - .read_raw = &ad7606_read_raw, - .write_raw = &ad7606_write_raw, - .attrs = &ad7606_attribute_group_range, -}; - -int ad7606_probe(struct device *dev, int irq, void __iomem *base_address, - const char *name, unsigned int id, - const struct ad7606_bus_ops *bops) -{ - struct ad7606_state *st; - int ret; - struct iio_dev *indio_dev; - - indio_dev = devm_iio_device_alloc(dev, sizeof(*st)); - if (!indio_dev) - return -ENOMEM; - - st = iio_priv(indio_dev); - - st->dev = dev; - mutex_init(&st->lock); - st->bops = bops; - st->base_address = base_address; - /* tied to logic low, analog input range is +/- 5V */ - st->range = 0; - st->oversampling = 1; - INIT_WORK(&st->poll_work, &ad7606_poll_bh_to_ring); - - st->reg = devm_regulator_get(dev, "avcc"); - if (IS_ERR(st->reg)) - return PTR_ERR(st->reg); - - ret = regulator_enable(st->reg); - if (ret) { - dev_err(dev, "Failed to enable specified AVcc supply\n"); - return ret; - } - - st->chip_info = &ad7606_chip_info_tbl[id]; - - ret = ad7606_request_gpios(st); - if (ret) - goto error_disable_reg; - - indio_dev->dev.parent = dev; - if (st->gpio_os) { - if (st->gpio_range) - indio_dev->info = &ad7606_info_os_and_range; - else - indio_dev->info = &ad7606_info_os; - } else { - if (st->gpio_range) - indio_dev->info = &ad7606_info_range; - else - indio_dev->info = &ad7606_info_no_os_or_range; - } - indio_dev->modes = INDIO_DIRECT_MODE; - indio_dev->name = name; - indio_dev->channels = st->chip_info->channels; - indio_dev->num_channels = st->chip_info->num_channels; - - init_waitqueue_head(&st->wq_data_avail); - - ret = ad7606_reset(st); - if (ret) - dev_warn(st->dev, "failed to RESET: no RESET GPIO specified\n"); - - ret = request_irq(irq, ad7606_interrupt, IRQF_TRIGGER_FALLING, name, - indio_dev); - if (ret) - goto error_disable_reg; - - ret = iio_triggered_buffer_setup(indio_dev, &ad7606_trigger_handler, - NULL, NULL); - if (ret) - goto error_free_irq; - - ret = iio_device_register(indio_dev); - if (ret) - goto error_unregister_ring; - - dev_set_drvdata(dev, indio_dev); - - return 0; -error_unregister_ring: - iio_triggered_buffer_cleanup(indio_dev); - -error_free_irq: - free_irq(irq, indio_dev); - -error_disable_reg: - regulator_disable(st->reg); - return ret; -} -EXPORT_SYMBOL_GPL(ad7606_probe); - -int ad7606_remove(struct device *dev, int irq) -{ - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ad7606_state *st = iio_priv(indio_dev); - - iio_device_unregister(indio_dev); - iio_triggered_buffer_cleanup(indio_dev); - - free_irq(irq, indio_dev); - regulator_disable(st->reg); - - return 0; -} -EXPORT_SYMBOL_GPL(ad7606_remove); - -#ifdef CONFIG_PM_SLEEP - -static int ad7606_suspend(struct device *dev) -{ - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ad7606_state *st = iio_priv(indio_dev); - - if (st->gpio_standby) { - gpiod_set_value(st->gpio_range, 1); - gpiod_set_value(st->gpio_standby, 0); - } - - return 0; -} - -static int ad7606_resume(struct device *dev) -{ - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ad7606_state *st = iio_priv(indio_dev); - - if (st->gpio_standby) { - gpiod_set_value(st->gpio_range, st->range); - gpiod_set_value(st->gpio_standby, 1); - ad7606_reset(st); - } - - return 0; -} - -SIMPLE_DEV_PM_OPS(ad7606_pm_ops, ad7606_suspend, ad7606_resume); -EXPORT_SYMBOL_GPL(ad7606_pm_ops); - -#endif - -MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>"); -MODULE_DESCRIPTION("Analog Devices AD7606 ADC"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/adc/ad7606.h b/drivers/staging/iio/adc/ad7606.h deleted file mode 100644 index 86188054b60b..000000000000 --- a/drivers/staging/iio/adc/ad7606.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - * AD7606 ADC driver - * - * Copyright 2011 Analog Devices Inc. - * - * Licensed under the GPL-2. - */ - -#ifndef IIO_ADC_AD7606_H_ -#define IIO_ADC_AD7606_H_ - -/** - * struct ad7606_chip_info - chip specific information - * @channels: channel specification - * @num_channels: number of channels - * @has_oversampling: whether the device has oversampling support - */ - -struct ad7606_chip_info { - const struct iio_chan_spec *channels; - unsigned int num_channels; - bool has_oversampling; -}; - -/** - * struct ad7606_state - driver instance specific data - * @dev pointer to kernel device - * @chip_info entry in the table of chips that describes this device - * @reg regulator info for the the power supply of the device - * @poll_work work struct for continuously reading data from the device - * into an IIO triggered buffer - * @wq_data_avail wait queue struct for buffer mode - * @bops bus operations (SPI or parallel) - * @range voltage range selection, selects which scale to apply - * @oversampling oversampling selection - * @done marks whether reading data is done - * @base_address address from where to read data in parallel operation - * @lock protect sensor state from concurrent accesses to GPIOs - * @gpio_convst GPIO descriptor for conversion start signal (CONVST) - * @gpio_reset GPIO descriptor for device hard-reset - * @gpio_range GPIO descriptor for range selection - * @gpio_standby GPIO descriptor for stand-by signal (STBY), - * controls power-down mode of device - * @gpio_frstdata GPIO descriptor for reading from device when data - * is being read on the first channel - * @gpio_os GPIO descriptors to control oversampling on the device - * @data buffer for reading data from the device - */ - -struct ad7606_state { - struct device *dev; - const struct ad7606_chip_info *chip_info; - struct regulator *reg; - struct work_struct poll_work; - wait_queue_head_t wq_data_avail; - const struct ad7606_bus_ops *bops; - unsigned int range; - unsigned int oversampling; - bool done; - void __iomem *base_address; - - struct mutex lock; /* protect sensor state */ - struct gpio_desc *gpio_convst; - struct gpio_desc *gpio_reset; - struct gpio_desc *gpio_range; - struct gpio_desc *gpio_standby; - struct gpio_desc *gpio_frstdata; - struct gpio_descs *gpio_os; - - /* - * DMA (thus cache coherency maintenance) requires the - * transfer buffers to live in their own cache lines. - * 8 * 16-bit samples + 64-bit timestamp - */ - unsigned short data[12] ____cacheline_aligned; -}; - -/** - * struct ad7606_bus_ops - driver bus operations - * @read_block function pointer for reading blocks of data - */ -struct ad7606_bus_ops { - /* more methods added in future? */ - int (*read_block)(struct device *dev, int num, void *data); -}; - -int ad7606_probe(struct device *dev, int irq, void __iomem *base_address, - const char *name, unsigned int id, - const struct ad7606_bus_ops *bops); -int ad7606_remove(struct device *dev, int irq); - -enum ad7606_supported_device_ids { - ID_AD7605_4, - ID_AD7606_8, - ID_AD7606_6, - ID_AD7606_4 -}; - -#ifdef CONFIG_PM_SLEEP -extern const struct dev_pm_ops ad7606_pm_ops; -#define AD7606_PM_OPS (&ad7606_pm_ops) -#else -#define AD7606_PM_OPS NULL -#endif - -#endif /* IIO_ADC_AD7606_H_ */ diff --git a/drivers/staging/iio/adc/ad7606_par.c b/drivers/staging/iio/adc/ad7606_par.c deleted file mode 100644 index 8bd86e727b02..000000000000 --- a/drivers/staging/iio/adc/ad7606_par.c +++ /dev/null @@ -1,113 +0,0 @@ -/* - * AD7606 Parallel Interface ADC driver - * - * Copyright 2011 Analog Devices Inc. - * - * Licensed under the GPL-2. - */ - -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/types.h> -#include <linux/err.h> -#include <linux/io.h> - -#include <linux/iio/iio.h> -#include "ad7606.h" - -static int ad7606_par16_read_block(struct device *dev, - int count, void *buf) -{ - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ad7606_state *st = iio_priv(indio_dev); - - insw((unsigned long)st->base_address, buf, count); - - return 0; -} - -static const struct ad7606_bus_ops ad7606_par16_bops = { - .read_block = ad7606_par16_read_block, -}; - -static int ad7606_par8_read_block(struct device *dev, - int count, void *buf) -{ - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ad7606_state *st = iio_priv(indio_dev); - - insb((unsigned long)st->base_address, buf, count * 2); - - return 0; -} - -static const struct ad7606_bus_ops ad7606_par8_bops = { - .read_block = ad7606_par8_read_block, -}; - -static int ad7606_par_probe(struct platform_device *pdev) -{ - const struct platform_device_id *id = platform_get_device_id(pdev); - struct resource *res; - void __iomem *addr; - resource_size_t remap_size; - int irq; - - irq = platform_get_irq(pdev, 0); - if (irq < 0) { - dev_err(&pdev->dev, "no irq: %d\n", irq); - return irq; - } - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - addr = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(addr)) - return PTR_ERR(addr); - - remap_size = resource_size(res); - - return ad7606_probe(&pdev->dev, irq, addr, - id->name, id->driver_data, - remap_size > 1 ? &ad7606_par16_bops : - &ad7606_par8_bops); -} - -static int ad7606_par_remove(struct platform_device *pdev) -{ - return ad7606_remove(&pdev->dev, platform_get_irq(pdev, 0)); -} - -static const struct platform_device_id ad7606_driver_ids[] = { - { - .name = "ad7605-4", - .driver_data = ID_AD7605_4, - }, { - .name = "ad7606-8", - .driver_data = ID_AD7606_8, - }, { - .name = "ad7606-6", - .driver_data = ID_AD7606_6, - }, { - .name = "ad7606-4", - .driver_data = ID_AD7606_4, - }, - { } -}; - -MODULE_DEVICE_TABLE(platform, ad7606_driver_ids); - -static struct platform_driver ad7606_driver = { - .probe = ad7606_par_probe, - .remove = ad7606_par_remove, - .id_table = ad7606_driver_ids, - .driver = { - .name = "ad7606", - .pm = AD7606_PM_OPS, - }, -}; - -module_platform_driver(ad7606_driver); - -MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>"); -MODULE_DESCRIPTION("Analog Devices AD7606 ADC"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/adc/ad7606_spi.c b/drivers/staging/iio/adc/ad7606_spi.c deleted file mode 100644 index b76ca5a8c059..000000000000 --- a/drivers/staging/iio/adc/ad7606_spi.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * AD7606 SPI ADC driver - * - * Copyright 2011 Analog Devices Inc. - * - * Licensed under the GPL-2. - */ - -#include <linux/module.h> -#include <linux/spi/spi.h> -#include <linux/types.h> -#include <linux/err.h> - -#include <linux/iio/iio.h> -#include "ad7606.h" - -#define MAX_SPI_FREQ_HZ 23500000 /* VDRIVE above 4.75 V */ - -static int ad7606_spi_read_block(struct device *dev, - int count, void *buf) -{ - struct spi_device *spi = to_spi_device(dev); - int i, ret; - unsigned short *data = buf; - __be16 *bdata = buf; - - ret = spi_read(spi, buf, count * 2); - if (ret < 0) { - dev_err(&spi->dev, "SPI read error\n"); - return ret; - } - - for (i = 0; i < count; i++) - data[i] = be16_to_cpu(bdata[i]); - - return 0; -} - -static const struct ad7606_bus_ops ad7606_spi_bops = { - .read_block = ad7606_spi_read_block, -}; - -static int ad7606_spi_probe(struct spi_device *spi) -{ - const struct spi_device_id *id = spi_get_device_id(spi); - - return ad7606_probe(&spi->dev, spi->irq, NULL, - id->name, id->driver_data, - &ad7606_spi_bops); -} - -static int ad7606_spi_remove(struct spi_device *spi) -{ - return ad7606_remove(&spi->dev, spi->irq); -} - -static const struct spi_device_id ad7606_id[] = { - {"ad7605-4", ID_AD7605_4}, - {"ad7606-8", ID_AD7606_8}, - {"ad7606-6", ID_AD7606_6}, - {"ad7606-4", ID_AD7606_4}, - {} -}; -MODULE_DEVICE_TABLE(spi, ad7606_id); - -static struct spi_driver ad7606_driver = { - .driver = { - .name = "ad7606", - .pm = AD7606_PM_OPS, - }, - .probe = ad7606_spi_probe, - .remove = ad7606_spi_remove, - .id_table = ad7606_id, -}; -module_spi_driver(ad7606_driver); - -MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>"); -MODULE_DESCRIPTION("Analog Devices AD7606 ADC"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/adc/ad7816.c b/drivers/staging/iio/adc/ad7816.c index 5209651a1b25..ee50e7296795 100644 --- a/drivers/staging/iio/adc/ad7816.c +++ b/drivers/staging/iio/adc/ad7816.c @@ -65,7 +65,7 @@ enum ad7816_type { static int ad7816_spi_read(struct ad7816_chip_info *chip, u16 *data) { struct spi_device *spi_dev = chip->spi_dev; - int ret = 0; + int ret; __be16 buf; gpiod_set_value(chip->rdwr_pin, 1); @@ -106,7 +106,7 @@ static int ad7816_spi_read(struct ad7816_chip_info *chip, u16 *data) static int ad7816_spi_write(struct ad7816_chip_info *chip, u8 data) { struct spi_device *spi_dev = chip->spi_dev; - int ret = 0; + int ret; gpiod_set_value(chip->rdwr_pin, 1); gpiod_set_value(chip->rdwr_pin, 0); @@ -354,8 +354,7 @@ static int ad7816_probe(struct spi_device *spi_dev) { struct ad7816_chip_info *chip; struct iio_dev *indio_dev; - int ret = 0; - int i; + int i, ret; indio_dev = devm_iio_device_alloc(&spi_dev->dev, sizeof(*chip)); if (!indio_dev) diff --git a/drivers/staging/iio/addac/adt7316-i2c.c b/drivers/staging/iio/addac/adt7316-i2c.c index 2d51bd425662..0f26bc38edc6 100644 --- a/drivers/staging/iio/addac/adt7316-i2c.c +++ b/drivers/staging/iio/addac/adt7316-i2c.c @@ -43,7 +43,7 @@ static int adt7316_i2c_read(void *client, u8 reg, u8 *data) static int adt7316_i2c_write(void *client, u8 reg, u8 data) { struct i2c_client *cl = client; - int ret = 0; + int ret; ret = i2c_smbus_write_byte_data(cl, reg, data); if (ret < 0) @@ -55,7 +55,7 @@ static int adt7316_i2c_write(void *client, u8 reg, u8 data) static int adt7316_i2c_multi_read(void *client, u8 reg, u8 count, u8 *data) { struct i2c_client *cl = client; - int i, ret = 0; + int i, ret; if (count > ADT7316_REG_MAX_ADDR) count = ADT7316_REG_MAX_ADDR; @@ -74,7 +74,7 @@ static int adt7316_i2c_multi_read(void *client, u8 reg, u8 count, u8 *data) static int adt7316_i2c_multi_write(void *client, u8 reg, u8 count, u8 *data) { struct i2c_client *cl = client; - int i, ret = 0; + int i, ret; if (count > ADT7316_REG_MAX_ADDR) count = ADT7316_REG_MAX_ADDR; diff --git a/drivers/staging/iio/addac/adt7316-spi.c b/drivers/staging/iio/addac/adt7316-spi.c index e75827e326a6..8294b9c1e3c2 100644 --- a/drivers/staging/iio/addac/adt7316-spi.c +++ b/drivers/staging/iio/addac/adt7316-spi.c @@ -27,7 +27,7 @@ static int adt7316_spi_multi_read(void *client, u8 reg, u8 count, u8 *data) { struct spi_device *spi_dev = client; u8 cmd[2]; - int ret = 0; + int ret; if (count > ADT7316_REG_MAX_ADDR) count = ADT7316_REG_MAX_ADDR; @@ -56,7 +56,7 @@ static int adt7316_spi_multi_write(void *client, u8 reg, u8 count, u8 *data) { struct spi_device *spi_dev = client; u8 buf[ADT7316_REG_MAX_ADDR + 2]; - int i, ret = 0; + int i, ret; if (count > ADT7316_REG_MAX_ADDR) count = ADT7316_REG_MAX_ADDR; diff --git a/drivers/staging/iio/addac/adt7316.c b/drivers/staging/iio/addac/adt7316.c index dc93e85808e0..6f7891b567b9 100644 --- a/drivers/staging/iio/addac/adt7316.c +++ b/drivers/staging/iio/addac/adt7316.c @@ -47,6 +47,8 @@ #define ADT7516_MSB_AIN3 0xA #define ADT7516_MSB_AIN4 0xB #define ADT7316_DA_DATA_BASE 0x10 +#define ADT7316_DA_10_BIT_LSB_SHIFT 6 +#define ADT7316_DA_12_BIT_LSB_SHIFT 4 #define ADT7316_DA_MSB_DATA_REGS 4 #define ADT7316_LSB_DAC_A 0x10 #define ADT7316_MSB_DAC_A 0x11 @@ -59,8 +61,8 @@ #define ADT7316_CONFIG1 0x18 #define ADT7316_CONFIG2 0x19 #define ADT7316_CONFIG3 0x1A -#define ADT7316_LDAC_CONFIG 0x1B -#define ADT7316_DAC_CONFIG 0x1C +#define ADT7316_DAC_CONFIG 0x1B +#define ADT7316_LDAC_CONFIG 0x1C #define ADT7316_INT_MASK1 0x1D #define ADT7316_INT_MASK2 0x1E #define ADT7316_IN_TEMP_OFFSET 0x1F @@ -117,7 +119,7 @@ */ #define ADT7316_ADCLK_22_5 0x1 #define ADT7316_DA_HIGH_RESOLUTION 0x2 -#define ADT7316_DA_EN_VIA_DAC_LDCA 0x4 +#define ADT7316_DA_EN_VIA_DAC_LDAC 0x8 #define ADT7516_AIN_IN_VREF 0x10 #define ADT7316_EN_IN_TEMP_PROP_DACA 0x20 #define ADT7316_EN_EX_TEMP_PROP_DACB 0x40 @@ -127,6 +129,7 @@ */ #define ADT7316_DA_2VREF_CH_MASK 0xF #define ADT7316_DA_EN_MODE_MASK 0x30 +#define ADT7316_DA_EN_MODE_SHIFT 4 #define ADT7316_DA_EN_MODE_SINGLE 0x00 #define ADT7316_DA_EN_MODE_AB_CD 0x10 #define ADT7316_DA_EN_MODE_ABCD 0x20 @@ -632,9 +635,7 @@ static ssize_t adt7316_show_da_high_resolution(struct device *dev, struct adt7316_chip_info *chip = iio_priv(dev_info); if (chip->config3 & ADT7316_DA_HIGH_RESOLUTION) { - if (chip->id == ID_ADT7316 || chip->id == ID_ADT7516) - return sprintf(buf, "1 (12 bits)\n"); - if (chip->id == ID_ADT7317 || chip->id == ID_ADT7517) + if (chip->id != ID_ADT7318 && chip->id != ID_ADT7519) return sprintf(buf, "1 (10 bits)\n"); } @@ -651,17 +652,12 @@ static ssize_t adt7316_store_da_high_resolution(struct device *dev, u8 config3; int ret; - chip->dac_bits = 8; + if (chip->id == ID_ADT7318 || chip->id == ID_ADT7519) + return -EPERM; - if (buf[0] == '1') { - config3 = chip->config3 | ADT7316_DA_HIGH_RESOLUTION; - if (chip->id == ID_ADT7316 || chip->id == ID_ADT7516) - chip->dac_bits = 12; - else if (chip->id == ID_ADT7317 || chip->id == ID_ADT7517) - chip->dac_bits = 10; - } else { - config3 = chip->config3 & (~ADT7316_DA_HIGH_RESOLUTION); - } + config3 = chip->config3 & (~ADT7316_DA_HIGH_RESOLUTION); + if (buf[0] == '1') + config3 |= ADT7316_DA_HIGH_RESOLUTION; ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG3, config3); if (ret) @@ -851,7 +847,7 @@ static ssize_t adt7316_show_DAC_update_mode(struct device *dev, struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); - if (!(chip->config3 & ADT7316_DA_EN_VIA_DAC_LDCA)) + if (!(chip->config3 & ADT7316_DA_EN_VIA_DAC_LDAC)) return sprintf(buf, "manual\n"); switch (chip->dac_config & ADT7316_DA_EN_MODE_MASK) { @@ -880,15 +876,15 @@ static ssize_t adt7316_store_DAC_update_mode(struct device *dev, u8 data; int ret; - if (!(chip->config3 & ADT7316_DA_EN_VIA_DAC_LDCA)) + if (!(chip->config3 & ADT7316_DA_EN_VIA_DAC_LDAC)) return -EPERM; ret = kstrtou8(buf, 10, &data); - if (ret || data > ADT7316_DA_EN_MODE_MASK) + if (ret || data > (ADT7316_DA_EN_MODE_MASK >> ADT7316_DA_EN_MODE_SHIFT)) return -EINVAL; dac_config = chip->dac_config & (~ADT7316_DA_EN_MODE_MASK); - dac_config |= data; + dac_config |= data << ADT7316_DA_EN_MODE_SHIFT; ret = chip->bus.write(chip->bus.client, ADT7316_DAC_CONFIG, dac_config); if (ret) @@ -911,7 +907,7 @@ static ssize_t adt7316_show_all_DAC_update_modes(struct device *dev, struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); - if (chip->config3 & ADT7316_DA_EN_VIA_DAC_LDCA) + if (chip->config3 & ADT7316_DA_EN_VIA_DAC_LDAC) return sprintf(buf, "0 - auto at any MSB DAC writing\n" "1 - auto at MSB DAC AB and CD writing\n" "2 - auto at MSB DAC ABCD writing\n" @@ -933,7 +929,7 @@ static ssize_t adt7316_store_update_DAC(struct device *dev, u8 data; int ret; - if (chip->config3 & ADT7316_DA_EN_VIA_DAC_LDCA) { + if (chip->config3 & ADT7316_DA_EN_VIA_DAC_LDAC) { if ((chip->dac_config & ADT7316_DA_EN_MODE_MASK) != ADT7316_DA_EN_MODE_LDAC) return -EPERM; @@ -969,9 +965,6 @@ static ssize_t adt7316_show_DA_AB_Vref_bypass(struct device *dev, struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); - if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX) - return -EPERM; - return sprintf(buf, "%d\n", !!(chip->dac_config & ADT7316_VREF_BYPASS_DAC_AB)); } @@ -986,9 +979,6 @@ static ssize_t adt7316_store_DA_AB_Vref_bypass(struct device *dev, u8 dac_config; int ret; - if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX) - return -EPERM; - dac_config = chip->dac_config & (~ADT7316_VREF_BYPASS_DAC_AB); if (buf[0] == '1') dac_config |= ADT7316_VREF_BYPASS_DAC_AB; @@ -1014,9 +1004,6 @@ static ssize_t adt7316_show_DA_CD_Vref_bypass(struct device *dev, struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); - if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX) - return -EPERM; - return sprintf(buf, "%d\n", !!(chip->dac_config & ADT7316_VREF_BYPASS_DAC_CD)); } @@ -1031,9 +1018,6 @@ static ssize_t adt7316_store_DA_CD_Vref_bypass(struct device *dev, u8 dac_config; int ret; - if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX) - return -EPERM; - dac_config = chip->dac_config & (~ADT7316_VREF_BYPASS_DAC_CD); if (buf[0] == '1') dac_config |= ADT7316_VREF_BYPASS_DAC_CD; @@ -1061,10 +1045,10 @@ static ssize_t adt7316_show_DAC_internal_Vref(struct device *dev, if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX) return sprintf(buf, "0x%x\n", - (chip->dac_config & ADT7516_DAC_IN_VREF_MASK) >> + (chip->ldac_config & ADT7516_DAC_IN_VREF_MASK) >> ADT7516_DAC_IN_VREF_OFFSET); return sprintf(buf, "%d\n", - !!(chip->dac_config & ADT7316_DAC_IN_VREF)); + !!(chip->ldac_config & ADT7316_DAC_IN_VREF)); } static ssize_t adt7316_store_DAC_internal_Vref(struct device *dev, @@ -1086,7 +1070,7 @@ static ssize_t adt7316_store_DAC_internal_Vref(struct device *dev, ldac_config = chip->ldac_config & (~ADT7516_DAC_IN_VREF_MASK); if (data & 0x1) ldac_config |= ADT7516_DAC_AB_IN_VREF; - else if (data & 0x2) + if (data & 0x2) ldac_config |= ADT7516_DAC_CD_IN_VREF; } else { ret = kstrtou8(buf, 16, &data); @@ -1410,7 +1394,7 @@ static IIO_DEVICE_ATTR(ex_analog_temp_offset, 0644, static ssize_t adt7316_show_DAC(struct adt7316_chip_info *chip, int channel, char *buf) { - u16 data; + u16 data = 0; u8 msb, lsb, offset; int ret; @@ -1435,7 +1419,11 @@ static ssize_t adt7316_show_DAC(struct adt7316_chip_info *chip, if (ret) return -EIO; - data = (msb << offset) + (lsb & ((1 << offset) - 1)); + if (chip->dac_bits == 12) + data = lsb >> ADT7316_DA_12_BIT_LSB_SHIFT; + else if (chip->dac_bits == 10) + data = lsb >> ADT7316_DA_10_BIT_LSB_SHIFT; + data |= msb << offset; return sprintf(buf, "%d\n", data); } @@ -1443,7 +1431,7 @@ static ssize_t adt7316_show_DAC(struct adt7316_chip_info *chip, static ssize_t adt7316_store_DAC(struct adt7316_chip_info *chip, int channel, const char *buf, size_t len) { - u8 msb, lsb, offset; + u8 msb, lsb, lsb_reg, offset; u16 data; int ret; @@ -1461,9 +1449,13 @@ static ssize_t adt7316_store_DAC(struct adt7316_chip_info *chip, return -EINVAL; if (chip->dac_bits > 8) { - lsb = data & (1 << offset); + lsb = data & ((1 << offset) - 1); + if (chip->dac_bits == 12) + lsb_reg = lsb << ADT7316_DA_12_BIT_LSB_SHIFT; + else + lsb_reg = lsb << ADT7316_DA_10_BIT_LSB_SHIFT; ret = chip->bus.write(chip->bus.client, - ADT7316_DA_DATA_BASE + channel * 2, lsb); + ADT7316_DA_DATA_BASE + channel * 2, lsb_reg); if (ret) return -EIO; } @@ -1710,8 +1702,6 @@ static struct attribute *adt7516_attributes[] = { &iio_dev_attr_DAC_update_mode.dev_attr.attr, &iio_dev_attr_all_DAC_update_modes.dev_attr.attr, &iio_dev_attr_update_DAC.dev_attr.attr, - &iio_dev_attr_DA_AB_Vref_bypass.dev_attr.attr, - &iio_dev_attr_DA_CD_Vref_bypass.dev_attr.attr, &iio_dev_attr_DAC_internal_Vref.dev_attr.attr, &iio_dev_attr_VDD.dev_attr.attr, &iio_dev_attr_in_temp.dev_attr.attr, @@ -1809,6 +1799,43 @@ static irqreturn_t adt7316_event_handler(int irq, void *private) return IRQ_HANDLED; } +static int adt7316_setup_irq(struct iio_dev *indio_dev) +{ + struct adt7316_chip_info *chip = iio_priv(indio_dev); + int irq_type, ret; + + irq_type = irqd_get_trigger_type(irq_get_irq_data(chip->bus.irq)); + + switch (irq_type) { + case IRQF_TRIGGER_HIGH: + case IRQF_TRIGGER_RISING: + break; + case IRQF_TRIGGER_LOW: + case IRQF_TRIGGER_FALLING: + break; + default: + dev_info(&indio_dev->dev, "mode %d unsupported, using IRQF_TRIGGER_LOW\n", + irq_type); + irq_type = IRQF_TRIGGER_LOW; + break; + } + + ret = devm_request_threaded_irq(&indio_dev->dev, chip->bus.irq, + NULL, adt7316_event_handler, + irq_type | IRQF_ONESHOT, + indio_dev->name, indio_dev); + if (ret) { + dev_err(&indio_dev->dev, "failed to request irq %d\n", + chip->bus.irq); + return ret; + } + + if (irq_type & IRQF_TRIGGER_HIGH) + chip->config1 |= ADT7316_INT_POLARITY; + + return 0; +} + /* * Show mask of enabled interrupts in Hex. */ @@ -2103,9 +2130,7 @@ int adt7316_probe(struct device *dev, struct adt7316_bus *bus, { struct adt7316_chip_info *chip; struct iio_dev *indio_dev; - unsigned short *adt7316_platform_data = dev->platform_data; - int irq_type = IRQF_TRIGGER_LOW; - int ret = 0; + int ret; indio_dev = devm_iio_device_alloc(dev, sizeof(*chip)); if (!indio_dev) @@ -2123,6 +2148,13 @@ int adt7316_probe(struct device *dev, struct adt7316_bus *bus, else return -ENODEV; + if (chip->id == ID_ADT7316 || chip->id == ID_ADT7516) + chip->dac_bits = 12; + else if (chip->id == ID_ADT7317 || chip->id == ID_ADT7517) + chip->dac_bits = 10; + else + chip->dac_bits = 8; + chip->ldac_pin = devm_gpiod_get_optional(dev, "adi,ldac", GPIOD_OUT_LOW); if (IS_ERR(chip->ldac_pin)) { ret = PTR_ERR(chip->ldac_pin); @@ -2130,8 +2162,8 @@ int adt7316_probe(struct device *dev, struct adt7316_bus *bus, return ret; } - if (chip->ldac_pin) { - chip->config3 |= ADT7316_DA_EN_VIA_DAC_LDCA; + if (!chip->ldac_pin) { + chip->config3 |= ADT7316_DA_EN_VIA_DAC_LDAC; if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX) chip->config1 |= ADT7516_SEL_AIN3; } @@ -2148,20 +2180,9 @@ int adt7316_probe(struct device *dev, struct adt7316_bus *bus, indio_dev->modes = INDIO_DIRECT_MODE; if (chip->bus.irq > 0) { - if (adt7316_platform_data[0]) - irq_type = adt7316_platform_data[0]; - - ret = devm_request_threaded_irq(dev, chip->bus.irq, - NULL, - adt7316_event_handler, - irq_type | IRQF_ONESHOT, - indio_dev->name, - indio_dev); + ret = adt7316_setup_irq(indio_dev); if (ret) return ret; - - if (irq_type & IRQF_TRIGGER_HIGH) - chip->config1 |= ADT7316_INT_POLARITY; } ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG1, chip->config1); diff --git a/drivers/staging/iio/cdc/Kconfig b/drivers/staging/iio/cdc/Kconfig index 80211df8c577..b97478e7cbd0 100644 --- a/drivers/staging/iio/cdc/Kconfig +++ b/drivers/staging/iio/cdc/Kconfig @@ -13,16 +13,6 @@ config AD7150 To compile this driver as a module, choose M here: the module will be called ad7150. -config AD7152 - tristate "Analog Devices ad7152/3 capacitive sensor driver" - depends on I2C - help - Say yes here to build support for Analog Devices capacitive sensors. - (ad7152, ad7153) Provides direct access via sysfs. - - To compile this driver as a module, choose M here: the - module will be called ad7152. - config AD7746 tristate "Analog Devices AD7745, AD7746 AD7747 capacitive sensor driver" depends on I2C diff --git a/drivers/staging/iio/cdc/Makefile b/drivers/staging/iio/cdc/Makefile index a5fbabf5c8bf..1466bc31f244 100644 --- a/drivers/staging/iio/cdc/Makefile +++ b/drivers/staging/iio/cdc/Makefile @@ -3,5 +3,4 @@ # obj-$(CONFIG_AD7150) += ad7150.o -obj-$(CONFIG_AD7152) += ad7152.o obj-$(CONFIG_AD7746) += ad7746.o diff --git a/drivers/staging/iio/cdc/ad7152.c b/drivers/staging/iio/cdc/ad7152.c deleted file mode 100644 index 25f51db05d2d..000000000000 --- a/drivers/staging/iio/cdc/ad7152.c +++ /dev/null @@ -1,552 +0,0 @@ -/* - * AD7152 capacitive sensor driver supporting AD7152/3 - * - * Copyright 2010-2011a Analog Devices Inc. - * - * Licensed under the GPL-2 or later. - */ - -#include <linux/interrupt.h> -#include <linux/device.h> -#include <linux/kernel.h> -#include <linux/slab.h> -#include <linux/sysfs.h> -#include <linux/i2c.h> -#include <linux/module.h> -#include <linux/delay.h> - -#include <linux/iio/iio.h> -#include <linux/iio/sysfs.h> - -/* - * TODO: Check compliance of calibbias with abi (units) - */ -/* - * AD7152 registers definition - */ - -#define AD7152_REG_STATUS 0 -#define AD7152_REG_CH1_DATA_HIGH 1 -#define AD7152_REG_CH2_DATA_HIGH 3 -#define AD7152_REG_CH1_OFFS_HIGH 5 -#define AD7152_REG_CH2_OFFS_HIGH 7 -#define AD7152_REG_CH1_GAIN_HIGH 9 -#define AD7152_REG_CH1_SETUP 11 -#define AD7152_REG_CH2_GAIN_HIGH 12 -#define AD7152_REG_CH2_SETUP 14 -#define AD7152_REG_CFG 15 -#define AD7152_REG_RESEVERD 16 -#define AD7152_REG_CAPDAC_POS 17 -#define AD7152_REG_CAPDAC_NEG 18 -#define AD7152_REG_CFG2 26 - -/* Status Register Bit Designations (AD7152_REG_STATUS) */ -#define AD7152_STATUS_RDY1 BIT(0) -#define AD7152_STATUS_RDY2 BIT(1) -#define AD7152_STATUS_C1C2 BIT(2) -#define AD7152_STATUS_PWDN BIT(7) - -/* Setup Register Bit Designations (AD7152_REG_CHx_SETUP) */ -#define AD7152_SETUP_CAPDIFF BIT(5) -#define AD7152_SETUP_RANGE_2pF (0 << 6) -#define AD7152_SETUP_RANGE_0_5pF (1 << 6) -#define AD7152_SETUP_RANGE_1pF (2 << 6) -#define AD7152_SETUP_RANGE_4pF (3 << 6) -#define AD7152_SETUP_RANGE(x) ((x) << 6) - -/* Config Register Bit Designations (AD7152_REG_CFG) */ -#define AD7152_CONF_CH2EN BIT(3) -#define AD7152_CONF_CH1EN BIT(4) -#define AD7152_CONF_MODE_IDLE (0 << 0) -#define AD7152_CONF_MODE_CONT_CONV (1 << 0) -#define AD7152_CONF_MODE_SINGLE_CONV (2 << 0) -#define AD7152_CONF_MODE_OFFS_CAL (5 << 0) -#define AD7152_CONF_MODE_GAIN_CAL (6 << 0) - -/* Capdac Register Bit Designations (AD7152_REG_CAPDAC_XXX) */ -#define AD7152_CAPDAC_DACEN BIT(7) -#define AD7152_CAPDAC_DACP(x) ((x) & 0x1F) - -/* CFG2 Register Bit Designations (AD7152_REG_CFG2) */ -#define AD7152_CFG2_OSR(x) (((x) & 0x3) << 4) - -enum { - AD7152_DATA, - AD7152_OFFS, - AD7152_GAIN, - AD7152_SETUP -}; - -/* - * struct ad7152_chip_info - chip specific information - */ - -struct ad7152_chip_info { - struct i2c_client *client; - /* - * Capacitive channel digital filter setup; - * conversion time/update rate setup per channel - */ - u8 filter_rate_setup; - u8 setup[2]; - struct mutex state_lock; /* protect hardware state */ -}; - -static inline ssize_t ad7152_start_calib(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len, - u8 regval) -{ - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - struct ad7152_chip_info *chip = iio_priv(indio_dev); - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - bool doit; - int ret, timeout = 10; - - ret = strtobool(buf, &doit); - if (ret < 0) - return ret; - - if (!doit) - return 0; - - if (this_attr->address == 0) - regval |= AD7152_CONF_CH1EN; - else - regval |= AD7152_CONF_CH2EN; - - mutex_lock(&chip->state_lock); - ret = i2c_smbus_write_byte_data(chip->client, AD7152_REG_CFG, regval); - if (ret < 0) - goto unlock; - - do { - mdelay(20); - ret = i2c_smbus_read_byte_data(chip->client, AD7152_REG_CFG); - if (ret < 0) - goto unlock; - - } while ((ret == regval) && timeout--); - - mutex_unlock(&chip->state_lock); - return len; - -unlock: - mutex_unlock(&chip->state_lock); - return ret; -} - -static ssize_t ad7152_start_offset_calib(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - return ad7152_start_calib(dev, attr, buf, len, - AD7152_CONF_MODE_OFFS_CAL); -} - -static ssize_t ad7152_start_gain_calib(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - return ad7152_start_calib(dev, attr, buf, len, - AD7152_CONF_MODE_GAIN_CAL); -} - -static IIO_DEVICE_ATTR(in_capacitance0_calibbias_calibration, - 0200, NULL, ad7152_start_offset_calib, 0); -static IIO_DEVICE_ATTR(in_capacitance1_calibbias_calibration, - 0200, NULL, ad7152_start_offset_calib, 1); -static IIO_DEVICE_ATTR(in_capacitance0_calibscale_calibration, - 0200, NULL, ad7152_start_gain_calib, 0); -static IIO_DEVICE_ATTR(in_capacitance1_calibscale_calibration, - 0200, NULL, ad7152_start_gain_calib, 1); - -/* Values are Update Rate (Hz), Conversion Time (ms) + 1*/ -static const unsigned char ad7152_filter_rate_table[][2] = { - {200, 5 + 1}, {50, 20 + 1}, {20, 50 + 1}, {17, 60 + 1}, -}; - -static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("200 50 20 17"); - -static IIO_CONST_ATTR(in_capacitance_scale_available, - "0.000061050 0.000030525 0.000015263 0.000007631"); - -static struct attribute *ad7152_attributes[] = { - &iio_dev_attr_in_capacitance0_calibbias_calibration.dev_attr.attr, - &iio_dev_attr_in_capacitance1_calibbias_calibration.dev_attr.attr, - &iio_dev_attr_in_capacitance0_calibscale_calibration.dev_attr.attr, - &iio_dev_attr_in_capacitance1_calibscale_calibration.dev_attr.attr, - &iio_const_attr_in_capacitance_scale_available.dev_attr.attr, - &iio_const_attr_sampling_frequency_available.dev_attr.attr, - NULL, -}; - -static const struct attribute_group ad7152_attribute_group = { - .attrs = ad7152_attributes, -}; - -static const u8 ad7152_addresses[][4] = { - { AD7152_REG_CH1_DATA_HIGH, AD7152_REG_CH1_OFFS_HIGH, - AD7152_REG_CH1_GAIN_HIGH, AD7152_REG_CH1_SETUP }, - { AD7152_REG_CH2_DATA_HIGH, AD7152_REG_CH2_OFFS_HIGH, - AD7152_REG_CH2_GAIN_HIGH, AD7152_REG_CH2_SETUP }, -}; - -/* Values are nano relative to pf base. */ -static const int ad7152_scale_table[] = { - 30525, 7631, 15263, 61050 -}; - -/** - * read_raw handler for IIO_CHAN_INFO_SAMP_FREQ - * - * lock must be held - **/ -static int ad7152_read_raw_samp_freq(struct device *dev, int *val) -{ - struct ad7152_chip_info *chip = iio_priv(dev_to_iio_dev(dev)); - - *val = ad7152_filter_rate_table[chip->filter_rate_setup][0]; - - return 0; -} - -/** - * write_raw handler for IIO_CHAN_INFO_SAMP_FREQ - * - * lock must be held - **/ -static int ad7152_write_raw_samp_freq(struct device *dev, int val) -{ - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - struct ad7152_chip_info *chip = iio_priv(indio_dev); - int ret, i; - - for (i = 0; i < ARRAY_SIZE(ad7152_filter_rate_table); i++) - if (val >= ad7152_filter_rate_table[i][0]) - break; - - if (i >= ARRAY_SIZE(ad7152_filter_rate_table)) - i = ARRAY_SIZE(ad7152_filter_rate_table) - 1; - - ret = i2c_smbus_write_byte_data(chip->client, - AD7152_REG_CFG2, AD7152_CFG2_OSR(i)); - if (ret < 0) - return ret; - - chip->filter_rate_setup = i; - - return ret; -} - -static int ad7152_write_raw(struct iio_dev *indio_dev, - struct iio_chan_spec const *chan, - int val, - int val2, - long mask) -{ - struct ad7152_chip_info *chip = iio_priv(indio_dev); - int ret, i; - - mutex_lock(&chip->state_lock); - - switch (mask) { - case IIO_CHAN_INFO_CALIBSCALE: - if (val != 1) { - ret = -EINVAL; - goto out; - } - - val = (val2 * 1024) / 15625; - - ret = i2c_smbus_write_word_data(chip->client, - ad7152_addresses[chan->channel][AD7152_GAIN], - swab16(val)); - if (ret < 0) - goto out; - - ret = 0; - break; - - case IIO_CHAN_INFO_CALIBBIAS: - if ((val < 0) | (val > 0xFFFF)) { - ret = -EINVAL; - goto out; - } - ret = i2c_smbus_write_word_data(chip->client, - ad7152_addresses[chan->channel][AD7152_OFFS], - swab16(val)); - if (ret < 0) - goto out; - - ret = 0; - break; - case IIO_CHAN_INFO_SCALE: - if (val) { - ret = -EINVAL; - goto out; - } - for (i = 0; i < ARRAY_SIZE(ad7152_scale_table); i++) - if (val2 == ad7152_scale_table[i]) - break; - - chip->setup[chan->channel] &= ~AD7152_SETUP_RANGE_4pF; - chip->setup[chan->channel] |= AD7152_SETUP_RANGE(i); - - ret = i2c_smbus_write_byte_data(chip->client, - ad7152_addresses[chan->channel][AD7152_SETUP], - chip->setup[chan->channel]); - if (ret < 0) - goto out; - - ret = 0; - break; - case IIO_CHAN_INFO_SAMP_FREQ: - if (val2) { - ret = -EINVAL; - goto out; - } - ret = ad7152_write_raw_samp_freq(&indio_dev->dev, val); - if (ret < 0) - goto out; - - ret = 0; - break; - default: - ret = -EINVAL; - } - -out: - mutex_unlock(&chip->state_lock); - return ret; -} - -static int ad7152_read_raw(struct iio_dev *indio_dev, - struct iio_chan_spec const *chan, - int *val, int *val2, - long mask) -{ - struct ad7152_chip_info *chip = iio_priv(indio_dev); - int ret; - u8 regval = 0; - - mutex_lock(&chip->state_lock); - - switch (mask) { - case IIO_CHAN_INFO_RAW: - /* First set whether in differential mode */ - - regval = chip->setup[chan->channel]; - - if (chan->differential) - chip->setup[chan->channel] |= AD7152_SETUP_CAPDIFF; - else - chip->setup[chan->channel] &= ~AD7152_SETUP_CAPDIFF; - - if (regval != chip->setup[chan->channel]) { - ret = i2c_smbus_write_byte_data(chip->client, - ad7152_addresses[chan->channel][AD7152_SETUP], - chip->setup[chan->channel]); - if (ret < 0) - goto out; - } - /* Make sure the channel is enabled */ - if (chan->channel == 0) - regval = AD7152_CONF_CH1EN; - else - regval = AD7152_CONF_CH2EN; - - /* Trigger a single read */ - regval |= AD7152_CONF_MODE_SINGLE_CONV; - ret = i2c_smbus_write_byte_data(chip->client, AD7152_REG_CFG, - regval); - if (ret < 0) - goto out; - - msleep(ad7152_filter_rate_table[chip->filter_rate_setup][1]); - /* Now read the actual register */ - ret = i2c_smbus_read_word_data(chip->client, - ad7152_addresses[chan->channel][AD7152_DATA]); - if (ret < 0) - goto out; - *val = swab16(ret); - - if (chan->differential) - *val -= 0x8000; - - ret = IIO_VAL_INT; - break; - case IIO_CHAN_INFO_CALIBSCALE: - - ret = i2c_smbus_read_word_data(chip->client, - ad7152_addresses[chan->channel][AD7152_GAIN]); - if (ret < 0) - goto out; - /* 1 + gain_val / 2^16 */ - *val = 1; - *val2 = (15625 * swab16(ret)) / 1024; - - ret = IIO_VAL_INT_PLUS_MICRO; - break; - case IIO_CHAN_INFO_CALIBBIAS: - ret = i2c_smbus_read_word_data(chip->client, - ad7152_addresses[chan->channel][AD7152_OFFS]); - if (ret < 0) - goto out; - *val = swab16(ret); - - ret = IIO_VAL_INT; - break; - case IIO_CHAN_INFO_SCALE: - ret = i2c_smbus_read_byte_data(chip->client, - ad7152_addresses[chan->channel][AD7152_SETUP]); - if (ret < 0) - goto out; - *val = 0; - *val2 = ad7152_scale_table[ret >> 6]; - - ret = IIO_VAL_INT_PLUS_NANO; - break; - case IIO_CHAN_INFO_SAMP_FREQ: - ret = ad7152_read_raw_samp_freq(&indio_dev->dev, val); - if (ret < 0) - goto out; - - ret = IIO_VAL_INT; - break; - default: - ret = -EINVAL; - } -out: - mutex_unlock(&chip->state_lock); - return ret; -} - -static int ad7152_write_raw_get_fmt(struct iio_dev *indio_dev, - struct iio_chan_spec const *chan, - long mask) -{ - switch (mask) { - case IIO_CHAN_INFO_SCALE: - return IIO_VAL_INT_PLUS_NANO; - default: - return IIO_VAL_INT_PLUS_MICRO; - } -} - -static const struct iio_info ad7152_info = { - .attrs = &ad7152_attribute_group, - .read_raw = ad7152_read_raw, - .write_raw = ad7152_write_raw, - .write_raw_get_fmt = ad7152_write_raw_get_fmt, -}; - -static const struct iio_chan_spec ad7152_channels[] = { - { - .type = IIO_CAPACITANCE, - .indexed = 1, - .channel = 0, - .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | - BIT(IIO_CHAN_INFO_CALIBSCALE) | - BIT(IIO_CHAN_INFO_CALIBBIAS) | - BIT(IIO_CHAN_INFO_SCALE), - .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), - }, { - .type = IIO_CAPACITANCE, - .differential = 1, - .indexed = 1, - .channel = 0, - .channel2 = 2, - .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | - BIT(IIO_CHAN_INFO_CALIBSCALE) | - BIT(IIO_CHAN_INFO_CALIBBIAS) | - BIT(IIO_CHAN_INFO_SCALE), - .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), - }, { - .type = IIO_CAPACITANCE, - .indexed = 1, - .channel = 1, - .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | - BIT(IIO_CHAN_INFO_CALIBSCALE) | - BIT(IIO_CHAN_INFO_CALIBBIAS) | - BIT(IIO_CHAN_INFO_SCALE), - .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), - }, { - .type = IIO_CAPACITANCE, - .differential = 1, - .indexed = 1, - .channel = 1, - .channel2 = 3, - .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | - BIT(IIO_CHAN_INFO_CALIBSCALE) | - BIT(IIO_CHAN_INFO_CALIBBIAS) | - BIT(IIO_CHAN_INFO_SCALE), - .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), - } -}; - -/* - * device probe and remove - */ - -static int ad7152_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - int ret = 0; - struct ad7152_chip_info *chip; - struct iio_dev *indio_dev; - - indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*chip)); - if (!indio_dev) - return -ENOMEM; - chip = iio_priv(indio_dev); - /* this is only used for device removal purposes */ - i2c_set_clientdata(client, indio_dev); - - chip->client = client; - mutex_init(&chip->state_lock); - - /* Establish that the iio_dev is a child of the i2c device */ - indio_dev->name = id->name; - indio_dev->dev.parent = &client->dev; - indio_dev->info = &ad7152_info; - indio_dev->channels = ad7152_channels; - if (id->driver_data == 0) - indio_dev->num_channels = ARRAY_SIZE(ad7152_channels); - else - indio_dev->num_channels = 2; - indio_dev->num_channels = ARRAY_SIZE(ad7152_channels); - indio_dev->modes = INDIO_DIRECT_MODE; - - ret = devm_iio_device_register(indio_dev->dev.parent, indio_dev); - if (ret) - return ret; - - dev_err(&client->dev, "%s capacitive sensor registered\n", id->name); - - return 0; -} - -static const struct i2c_device_id ad7152_id[] = { - { "ad7152", 0 }, - { "ad7153", 1 }, - {} -}; - -MODULE_DEVICE_TABLE(i2c, ad7152_id); - -static struct i2c_driver ad7152_driver = { - .driver = { - .name = KBUILD_MODNAME, - }, - .probe = ad7152_probe, - .id_table = ad7152_id, -}; -module_i2c_driver(ad7152_driver); - -MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); -MODULE_DESCRIPTION("Analog Devices AD7152/3 capacitive sensor driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/frequency/ad9834.c b/drivers/staging/iio/frequency/ad9834.c index 1e977014fe5f..0b0287503fb4 100644 --- a/drivers/staging/iio/frequency/ad9834.c +++ b/drivers/staging/iio/frequency/ad9834.c @@ -6,6 +6,7 @@ * Licensed under the GPL-2. */ +#include <linux/clk.h> #include <linux/interrupt.h> #include <linux/workqueue.h> #include <linux/device.h> @@ -71,7 +72,7 @@ struct ad9834_state { struct spi_device *spi; struct regulator *reg; - unsigned int mclk; + struct clk *mclk; unsigned short control; unsigned short devid; struct spi_transfer xfer; @@ -110,12 +111,15 @@ static unsigned int ad9834_calc_freqreg(unsigned long mclk, unsigned long fout) static int ad9834_write_frequency(struct ad9834_state *st, unsigned long addr, unsigned long fout) { + unsigned long clk_freq; unsigned long regval; - if (fout > (st->mclk / 2)) + clk_freq = clk_get_rate(st->mclk); + + if (fout > (clk_freq / 2)) return -EINVAL; - regval = ad9834_calc_freqreg(st->mclk, fout); + regval = ad9834_calc_freqreg(clk_freq, fout); st->freq_data[0] = cpu_to_be16(addr | (regval & RES_MASK(AD9834_FREQ_BITS / 2))); @@ -389,16 +393,11 @@ static const struct iio_info ad9833_info = { static int ad9834_probe(struct spi_device *spi) { - struct ad9834_platform_data *pdata = dev_get_platdata(&spi->dev); struct ad9834_state *st; struct iio_dev *indio_dev; struct regulator *reg; int ret; - if (!pdata) { - dev_dbg(&spi->dev, "no platform data?\n"); - return -ENODEV; - } reg = devm_regulator_get(&spi->dev, "avdd"); if (IS_ERR(reg)) @@ -418,7 +417,14 @@ static int ad9834_probe(struct spi_device *spi) spi_set_drvdata(spi, indio_dev); st = iio_priv(indio_dev); mutex_init(&st->lock); - st->mclk = pdata->mclk; + st->mclk = devm_clk_get(&spi->dev, NULL); + + ret = clk_prepare_enable(st->mclk); + if (ret) { + dev_err(&spi->dev, "Failed to enable master clock\n"); + goto error_disable_reg; + } + st->spi = spi; st->devid = spi_get_device_id(spi)->driver_data; st->reg = reg; @@ -454,42 +460,41 @@ static int ad9834_probe(struct spi_device *spi) spi_message_add_tail(&st->freq_xfer[1], &st->freq_msg); st->control = AD9834_B28 | AD9834_RESET; + st->control |= AD9834_DIV2; - if (!pdata->en_div2) - st->control |= AD9834_DIV2; - - if (!pdata->en_signbit_msb_out && (st->devid == ID_AD9834)) + if (st->devid == ID_AD9834) st->control |= AD9834_SIGN_PIB; st->data = cpu_to_be16(AD9834_REG_CMD | st->control); ret = spi_sync(st->spi, &st->msg); if (ret) { dev_err(&spi->dev, "device init failed\n"); - goto error_disable_reg; + goto error_clock_unprepare; } - ret = ad9834_write_frequency(st, AD9834_REG_FREQ0, pdata->freq0); + ret = ad9834_write_frequency(st, AD9834_REG_FREQ0, 1000000); if (ret) - goto error_disable_reg; + goto error_clock_unprepare; - ret = ad9834_write_frequency(st, AD9834_REG_FREQ1, pdata->freq1); + ret = ad9834_write_frequency(st, AD9834_REG_FREQ1, 5000000); if (ret) - goto error_disable_reg; + goto error_clock_unprepare; - ret = ad9834_write_phase(st, AD9834_REG_PHASE0, pdata->phase0); + ret = ad9834_write_phase(st, AD9834_REG_PHASE0, 512); if (ret) - goto error_disable_reg; + goto error_clock_unprepare; - ret = ad9834_write_phase(st, AD9834_REG_PHASE1, pdata->phase1); + ret = ad9834_write_phase(st, AD9834_REG_PHASE1, 1024); if (ret) - goto error_disable_reg; + goto error_clock_unprepare; ret = iio_device_register(indio_dev); if (ret) - goto error_disable_reg; + goto error_clock_unprepare; return 0; - +error_clock_unprepare: + clk_disable_unprepare(st->mclk); error_disable_reg: regulator_disable(reg); @@ -502,6 +507,7 @@ static int ad9834_remove(struct spi_device *spi) struct ad9834_state *st = iio_priv(indio_dev); iio_device_unregister(indio_dev); + clk_disable_unprepare(st->mclk); regulator_disable(st->reg); return 0; diff --git a/drivers/staging/iio/frequency/ad9834.h b/drivers/staging/iio/frequency/ad9834.h index ae620f38eb49..da7e83ceedad 100644 --- a/drivers/staging/iio/frequency/ad9834.h +++ b/drivers/staging/iio/frequency/ad9834.h @@ -8,32 +8,4 @@ #ifndef IIO_DDS_AD9834_H_ #define IIO_DDS_AD9834_H_ -/* - * TODO: struct ad7887_platform_data needs to go into include/linux/iio - */ - -/** - * struct ad9834_platform_data - platform specific information - * @mclk: master clock in Hz - * @freq0: power up freq0 tuning word in Hz - * @freq1: power up freq1 tuning word in Hz - * @phase0: power up phase0 value [0..4095] correlates with 0..2PI - * @phase1: power up phase1 value [0..4095] correlates with 0..2PI - * @en_div2: digital output/2 is passed to the SIGN BIT OUT pin - * @en_signbit_msb_out: the MSB (or MSB/2) of the DAC data is connected to the - * SIGN BIT OUT pin. en_div2 controls whether it is the MSB - * or MSB/2 that is output. if en_signbit_msb_out=false, - * the on-board comparator is connected to SIGN BIT OUT - */ - -struct ad9834_platform_data { - unsigned int mclk; - unsigned int freq0; - unsigned int freq1; - unsigned short phase0; - unsigned short phase1; - bool en_div2; - bool en_signbit_msb_out; -}; - #endif /* IIO_DDS_AD9834_H_ */ diff --git a/drivers/staging/iio/impedance-analyzer/ad5933.c b/drivers/staging/iio/impedance-analyzer/ad5933.c index 9e52384f5370..3134295f014f 100644 --- a/drivers/staging/iio/impedance-analyzer/ad5933.c +++ b/drivers/staging/iio/impedance-analyzer/ad5933.c @@ -16,6 +16,7 @@ #include <linux/err.h> #include <linux/delay.h> #include <linux/module.h> +#include <linux/clk.h> #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> @@ -82,21 +83,10 @@ #define AD5933_POLL_TIME_ms 10 #define AD5933_INIT_EXCITATION_TIME_ms 100 -/** - * struct ad5933_platform_data - platform specific data - * @ext_clk_hz: the external clock frequency in Hz, if not set - * the driver uses the internal clock (16.776 MHz) - * @vref_mv: the external reference voltage in millivolt - */ - -struct ad5933_platform_data { - unsigned long ext_clk_hz; - unsigned short vref_mv; -}; - struct ad5933_state { struct i2c_client *client; struct regulator *reg; + struct clk *mclk; struct delayed_work work; struct mutex lock; /* Protect sensor state */ unsigned long mclk_hz; @@ -112,10 +102,6 @@ struct ad5933_state { unsigned int poll_time_jiffies; }; -static struct ad5933_platform_data ad5933_default_pdata = { - .vref_mv = 3300, -}; - #define AD5933_CHANNEL(_type, _extend_name, _info_mask_separate, _address, \ _scan_index, _realbits) { \ .type = (_type), \ @@ -691,10 +677,10 @@ static void ad5933_work(struct work_struct *work) static int ad5933_probe(struct i2c_client *client, const struct i2c_device_id *id) { - int ret, voltage_uv = 0; - struct ad5933_platform_data *pdata = dev_get_platdata(&client->dev); + int ret; struct ad5933_state *st; struct iio_dev *indio_dev; + unsigned long ext_clk_hz = 0; indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*st)); if (!indio_dev) @@ -706,9 +692,6 @@ static int ad5933_probe(struct i2c_client *client, mutex_init(&st->lock); - if (!pdata) - pdata = &ad5933_default_pdata; - st->reg = devm_regulator_get(&client->dev, "vdd"); if (IS_ERR(st->reg)) return PTR_ERR(st->reg); @@ -718,15 +701,28 @@ static int ad5933_probe(struct i2c_client *client, dev_err(&client->dev, "Failed to enable specified VDD supply\n"); return ret; } - voltage_uv = regulator_get_voltage(st->reg); + ret = regulator_get_voltage(st->reg); - if (voltage_uv) - st->vref_mv = voltage_uv / 1000; - else - st->vref_mv = pdata->vref_mv; + if (ret < 0) + goto error_disable_reg; + + st->vref_mv = ret / 1000; + + st->mclk = devm_clk_get(&client->dev, "mclk"); + if (IS_ERR(st->mclk) && PTR_ERR(st->mclk) != -ENOENT) { + ret = PTR_ERR(st->mclk); + goto error_disable_reg; + } - if (pdata->ext_clk_hz) { - st->mclk_hz = pdata->ext_clk_hz; + if (!IS_ERR(st->mclk)) { + ret = clk_prepare_enable(st->mclk); + if (ret < 0) + goto error_disable_reg; + ext_clk_hz = clk_get_rate(st->mclk); + } + + if (ext_clk_hz) { + st->mclk_hz = ext_clk_hz; st->ctrl_lb = AD5933_CTRL_EXT_SYSCLK; } else { st->mclk_hz = AD5933_INT_OSC_FREQ_Hz; @@ -746,7 +742,7 @@ static int ad5933_probe(struct i2c_client *client, ret = ad5933_register_ring_funcs_and_init(indio_dev); if (ret) - goto error_disable_reg; + goto error_disable_mclk; ret = ad5933_setup(st); if (ret) @@ -760,6 +756,8 @@ static int ad5933_probe(struct i2c_client *client, error_unreg_ring: iio_kfifo_free(indio_dev->buffer); +error_disable_mclk: + clk_disable_unprepare(st->mclk); error_disable_reg: regulator_disable(st->reg); @@ -774,6 +772,7 @@ static int ad5933_remove(struct i2c_client *client) iio_device_unregister(indio_dev); iio_kfifo_free(indio_dev->buffer); regulator_disable(st->reg); + clk_disable_unprepare(st->mclk); return 0; } diff --git a/drivers/staging/ks7010/Makefile b/drivers/staging/ks7010/Makefile index 07dc16cc86f5..412e2105a3a5 100644 --- a/drivers/staging/ks7010/Makefile +++ b/drivers/staging/ks7010/Makefile @@ -1,3 +1,3 @@ obj-$(CONFIG_KS7010) += ks7010.o -ks7010-y := michael_mic.o ks_hostif.o ks_wlan_net.o ks7010_sdio.o +ks7010-y := ks_hostif.o ks_wlan_net.o ks7010_sdio.o diff --git a/drivers/staging/ks7010/TODO b/drivers/staging/ks7010/TODO index d393ca58e231..87a6dac4890d 100644 --- a/drivers/staging/ks7010/TODO +++ b/drivers/staging/ks7010/TODO @@ -27,8 +27,6 @@ Now the TODOs: - fix the 'card removal' event when card is inserted when booting - check what other upstream wireless mechanisms can be used instead of the custom ones here -- replace custom Michael MIC implementation with the kernel - implementation. This task is only required for a *clean* WEXT interface. Please send any patches to: Greg Kroah-Hartman <gregkh@linuxfoundation.org> diff --git a/drivers/staging/ks7010/ks_hostif.c b/drivers/staging/ks7010/ks_hostif.c index 065bce193fac..06ebea0be118 100644 --- a/drivers/staging/ks7010/ks_hostif.c +++ b/drivers/staging/ks7010/ks_hostif.c @@ -6,15 +6,18 @@ * Copyright (C) 2009 Renesas Technology Corp. */ +#include <crypto/hash.h> #include <linux/circ_buf.h> #include <linux/if_arp.h> #include <net/iw_handler.h> #include <uapi/linux/llc.h> #include "eap_packet.h" #include "ks_wlan.h" -#include "michael_mic.h" #include "ks_hostif.h" +#define MICHAEL_MIC_KEY_LEN 8 +#define MICHAEL_MIC_LEN 8 + static inline void inc_smeqhead(struct ks_wlan_private *priv) { priv->sme_i.qhead = (priv->sme_i.qhead + 1) % SME_EVENT_BUFF_SIZE; @@ -35,7 +38,7 @@ static inline u8 get_byte(struct ks_wlan_private *priv) { u8 data; - data = *(priv->rxp)++; + data = *priv->rxp++; /* length check in advance ! */ --(priv->rx_size); return data; @@ -171,7 +174,7 @@ int get_current_ap(struct ks_wlan_private *priv, struct link_ap_info *ap_info) "- rate_set_size=%d\n", ap->bssid[0], ap->bssid[1], ap->bssid[2], ap->bssid[3], ap->bssid[4], ap->bssid[5], - &(ap->ssid.body[0]), + &ap->ssid.body[0], ap->rate_set.body[0], ap->rate_set.body[1], ap->rate_set.body[2], ap->rate_set.body[3], ap->rate_set.body[4], ap->rate_set.body[5], @@ -191,6 +194,68 @@ static u8 read_ie(unsigned char *bp, u8 max, u8 *body) return size; } +static int +michael_mic(u8 *key, u8 *data, unsigned int len, u8 priority, u8 *result) +{ + u8 pad_data[4] = { priority, 0, 0, 0 }; + struct crypto_shash *tfm = NULL; + struct shash_desc *desc = NULL; + int ret; + + tfm = crypto_alloc_shash("michael_mic", 0, 0); + if (IS_ERR(tfm)) { + ret = PTR_ERR(tfm); + goto err; + } + + ret = crypto_shash_setkey(tfm, key, MICHAEL_MIC_KEY_LEN); + if (ret < 0) + goto err_free_tfm; + + desc = kmalloc(sizeof(*desc) + crypto_shash_descsize(tfm), GFP_KERNEL); + if (!desc) { + ret = -ENOMEM; + goto err_free_tfm; + } + + desc->tfm = tfm; + desc->flags = 0; + + ret = crypto_shash_init(desc); + if (ret < 0) + goto err_free_desc; + + // Compute the MIC value + /* + * IEEE802.11i page 47 + * Figure 43g TKIP MIC processing format + * +--+--+--------+--+----+--+--+--+--+--+--+--+--+ + * |6 |6 |1 |3 |M |1 |1 |1 |1 |1 |1 |1 |1 | Octet + * +--+--+--------+--+----+--+--+--+--+--+--+--+--+ + * |DA|SA|Priority|0 |Data|M0|M1|M2|M3|M4|M5|M6|M7| + * +--+--+--------+--+----+--+--+--+--+--+--+--+--+ + */ + + ret = crypto_shash_update(desc, data, 12); + if (ret < 0) + goto err_free_desc; + + ret = crypto_shash_update(desc, pad_data, 4); + if (ret < 0) + goto err_free_desc; + + ret = crypto_shash_finup(desc, data + 12, len - 12, result); + +err_free_desc: + kzfree(desc); + +err_free_tfm: + crypto_free_shash(tfm); + +err: + return ret; +} + static int get_ap_information(struct ks_wlan_private *priv, struct ap_info *ap_info, struct local_ap *ap) @@ -273,11 +338,11 @@ int hostif_data_indication_wpa(struct ks_wlan_private *priv, { struct ether_hdr *eth_hdr; unsigned short eth_proto; - unsigned char recv_mic[8]; + unsigned char recv_mic[MICHAEL_MIC_LEN]; char buf[128]; unsigned long now; struct mic_failure *mic_failure; - struct michael_mic michael_mic; + u8 mic[MICHAEL_MIC_LEN]; union iwreq_data wrqu; unsigned int key_index = auth_type - 1; struct wpa_key *key = &priv->wpa.key[key_index]; @@ -300,14 +365,20 @@ int hostif_data_indication_wpa(struct ks_wlan_private *priv, netdev_dbg(priv->net_dev, "TKIP: protocol=%04X: size=%u\n", eth_proto, priv->rx_size); /* MIC save */ - memcpy(&recv_mic[0], (priv->rxp) + ((priv->rx_size) - 8), 8); - priv->rx_size = priv->rx_size - 8; + memcpy(&recv_mic[0], + (priv->rxp) + ((priv->rx_size) - sizeof(recv_mic)), + sizeof(recv_mic)); + priv->rx_size = priv->rx_size - sizeof(recv_mic); if (auth_type > 0 && auth_type < 4) { /* auth_type check */ - michael_mic_function(&michael_mic, key->rx_mic_key, - priv->rxp, priv->rx_size, - 0, michael_mic.result); + int ret; + + ret = michael_mic(key->rx_mic_key, + priv->rxp, priv->rx_size, + 0, mic); + if (ret < 0) + return ret; } - if (memcmp(michael_mic.result, recv_mic, 8) != 0) { + if (memcmp(mic, recv_mic, sizeof(mic)) != 0) { now = jiffies; mic_failure = &priv->wpa.mic_failure; /* MIC FAILURE */ @@ -730,9 +801,9 @@ void hostif_scan_indication(struct ks_wlan_private *priv) priv->scan_ind_count++; if (priv->scan_ind_count < LOCAL_APLIST_MAX + 1) { netdev_dbg(priv->net_dev, " scan_ind_count=%d :: aplist.size=%d\n", - priv->scan_ind_count, priv->aplist.size); + priv->scan_ind_count, priv->aplist.size); get_ap_information(priv, (struct ap_info *)(priv->rxp), - &(priv->aplist.ap[priv->scan_ind_count - 1])); + &priv->aplist.ap[priv->scan_ind_count - 1]); priv->aplist.size = priv->scan_ind_count; } else { netdev_dbg(priv->net_dev, " count over :: scan_ind_count=%d\n", @@ -1002,7 +1073,6 @@ int hostif_data_request(struct ks_wlan_private *priv, struct sk_buff *skb) int result = 0; unsigned short eth_proto; struct ether_hdr *eth_hdr; - struct michael_mic michael_mic; unsigned short keyinfo = 0; struct ieee802_1x_hdr *aa1x_hdr; struct wpa_eapol_key *eap_key; @@ -1109,17 +1179,20 @@ int hostif_data_request(struct ks_wlan_private *priv, struct sk_buff *skb) pp->auth_type = cpu_to_le16(TYPE_AUTH); } else { if (priv->wpa.pairwise_suite == IW_AUTH_CIPHER_TKIP) { - michael_mic_function(&michael_mic, - priv->wpa.key[0].tx_mic_key, - &pp->data[0], skb_len, - 0, michael_mic.result); - memcpy(p, michael_mic.result, 8); - length += 8; - skb_len += 8; - p += 8; + u8 mic[MICHAEL_MIC_LEN]; + + ret = michael_mic(priv->wpa.key[0].tx_mic_key, + &pp->data[0], skb_len, + 0, mic); + if (ret < 0) + goto err_kfree; + + memcpy(p, mic, sizeof(mic)); + length += sizeof(mic); + skb_len += sizeof(mic); + p += sizeof(mic); pp->auth_type = cpu_to_le16(TYPE_DATA); - } else if (priv->wpa.pairwise_suite == IW_AUTH_CIPHER_CCMP) { pp->auth_type = diff --git a/drivers/staging/ks7010/ks_wlan_net.c b/drivers/staging/ks7010/ks_wlan_net.c index dc5459ae0b51..3cffc8be6656 100644 --- a/drivers/staging/ks7010/ks_wlan_net.c +++ b/drivers/staging/ks7010/ks_wlan_net.c @@ -182,7 +182,7 @@ static int ks_wlan_set_freq(struct net_device *dev, /* for SLEEP MODE */ /* If setting by frequency, convert to a channel */ if ((fwrq->freq.e == 1) && - (fwrq->freq.m >= (int)2.412e8) && (fwrq->freq.m <= (int)2.487e8)) { + (fwrq->freq.m >= 241200000) && (fwrq->freq.m <= 248700000)) { int f = fwrq->freq.m / 100000; int c = 0; diff --git a/drivers/staging/ks7010/michael_mic.c b/drivers/staging/ks7010/michael_mic.c deleted file mode 100644 index 3acd79615f98..000000000000 --- a/drivers/staging/ks7010/michael_mic.c +++ /dev/null @@ -1,127 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Driver for KeyStream wireless LAN - * - * Copyright (C) 2005-2008 KeyStream Corp. - * Copyright (C) 2009 Renesas Technology Corp. - */ - -#include <asm/unaligned.h> -#include <linux/bitops.h> -#include <linux/string.h> -#include "michael_mic.h" - -// Reset the state to the empty message. -static inline void michael_clear(struct michael_mic *mic) -{ - mic->l = mic->k0; - mic->r = mic->k1; - mic->m_bytes = 0; -} - -static void michael_init(struct michael_mic *mic, u8 *key) -{ - // Set the key - mic->k0 = get_unaligned_le32(key); - mic->k1 = get_unaligned_le32(key + 4); - - //clear(); - michael_clear(mic); -} - -static inline void michael_block(struct michael_mic *mic) -{ - mic->r ^= rol32(mic->l, 17); - mic->l += mic->r; - mic->r ^= ((mic->l & 0xff00ff00) >> 8) | - ((mic->l & 0x00ff00ff) << 8); - mic->l += mic->r; - mic->r ^= rol32(mic->l, 3); - mic->l += mic->r; - mic->r ^= ror32(mic->l, 2); - mic->l += mic->r; -} - -static void michael_append(struct michael_mic *mic, u8 *src, int bytes) -{ - int addlen; - - if (mic->m_bytes) { - addlen = 4 - mic->m_bytes; - if (addlen > bytes) - addlen = bytes; - memcpy(&mic->m[mic->m_bytes], src, addlen); - mic->m_bytes += addlen; - src += addlen; - bytes -= addlen; - - if (mic->m_bytes < 4) - return; - - mic->l ^= get_unaligned_le32(mic->m); - michael_block(mic); - mic->m_bytes = 0; - } - - while (bytes >= 4) { - mic->l ^= get_unaligned_le32(src); - michael_block(mic); - src += 4; - bytes -= 4; - } - - if (bytes > 0) { - mic->m_bytes = bytes; - memcpy(mic->m, src, bytes); - } -} - -static void michael_get_mic(struct michael_mic *mic, u8 *dst) -{ - u8 *data = mic->m; - - switch (mic->m_bytes) { - case 0: - mic->l ^= 0x5a; - break; - case 1: - mic->l ^= data[0] | 0x5a00; - break; - case 2: - mic->l ^= data[0] | (data[1] << 8) | 0x5a0000; - break; - case 3: - mic->l ^= data[0] | (data[1] << 8) | (data[2] << 16) | - 0x5a000000; - break; - } - michael_block(mic); - michael_block(mic); - // The appendByte function has already computed the result. - put_unaligned_le32(mic->l, dst); - put_unaligned_le32(mic->r, dst + 4); - - // Reset to the empty message. - michael_clear(mic); -} - -void michael_mic_function(struct michael_mic *mic, u8 *key, - u8 *data, unsigned int len, u8 priority, u8 *result) -{ - u8 pad_data[4] = { priority, 0, 0, 0 }; - // Compute the MIC value - /* - * IEEE802.11i page 47 - * Figure 43g TKIP MIC processing format - * +--+--+--------+--+----+--+--+--+--+--+--+--+--+ - * |6 |6 |1 |3 |M |1 |1 |1 |1 |1 |1 |1 |1 | Octet - * +--+--+--------+--+----+--+--+--+--+--+--+--+--+ - * |DA|SA|Priority|0 |Data|M0|M1|M2|M3|M4|M5|M6|M7| - * +--+--+--------+--+----+--+--+--+--+--+--+--+--+ - */ - michael_init(mic, key); - michael_append(mic, data, 12); /* |DA|SA| */ - michael_append(mic, pad_data, 4); /* |Priority|0|0|0| */ - michael_append(mic, data + 12, len - 12); /* |Data| */ - michael_get_mic(mic, result); -} diff --git a/drivers/staging/ks7010/michael_mic.h b/drivers/staging/ks7010/michael_mic.h deleted file mode 100644 index f0ac164b999b..000000000000 --- a/drivers/staging/ks7010/michael_mic.h +++ /dev/null @@ -1,21 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Driver for KeyStream wireless LAN - * - * Copyright (C) 2005-2008 KeyStream Corp. - * Copyright (C) 2009 Renesas Technology Corp. - */ - -/* MichaelMIC routine define */ -struct michael_mic { - u32 k0; // Key - u32 k1; // Key - u32 l; // Current state - u32 r; // Current state - u8 m[4]; // Message accumulator (single word) - int m_bytes; // # bytes in M - u8 result[8]; -}; - -void michael_mic_function(struct michael_mic *mic, u8 *key, - u8 *data, unsigned int len, u8 priority, u8 *result); diff --git a/drivers/staging/media/Kconfig b/drivers/staging/media/Kconfig index 19cadd17e542..1da5c20d65c0 100644 --- a/drivers/staging/media/Kconfig +++ b/drivers/staging/media/Kconfig @@ -25,10 +25,6 @@ source "drivers/staging/media/davinci_vpfe/Kconfig" source "drivers/staging/media/imx/Kconfig" -source "drivers/staging/media/imx074/Kconfig" - -source "drivers/staging/media/mt9t031/Kconfig" - source "drivers/staging/media/omap4iss/Kconfig" source "drivers/staging/media/rockchip/vpu/Kconfig" @@ -41,4 +37,6 @@ source "drivers/staging/media/zoran/Kconfig" source "drivers/staging/media/ipu3/Kconfig" +source "drivers/staging/media/soc_camera/Kconfig" + endif diff --git a/drivers/staging/media/Makefile b/drivers/staging/media/Makefile index edde1960b030..0355e3030504 100644 --- a/drivers/staging/media/Makefile +++ b/drivers/staging/media/Makefile @@ -1,8 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_I2C_BCM2048) += bcm2048/ obj-$(CONFIG_VIDEO_IMX_MEDIA) += imx/ -obj-$(CONFIG_SOC_CAMERA_IMX074) += imx074/ -obj-$(CONFIG_SOC_CAMERA_MT9T031) += mt9t031/ obj-$(CONFIG_VIDEO_DM365_VPFE) += davinci_vpfe/ obj-$(CONFIG_VIDEO_OMAP4) += omap4iss/ obj-$(CONFIG_VIDEO_SUNXI) += sunxi/ @@ -10,3 +8,4 @@ obj-$(CONFIG_TEGRA_VDE) += tegra-vde/ obj-$(CONFIG_VIDEO_ZORAN) += zoran/ obj-$(CONFIG_VIDEO_ROCKCHIP_VPU) += rockchip/vpu/ obj-$(CONFIG_VIDEO_IPU3_IMGU) += ipu3/ +obj-$(CONFIG_SOC_CAMERA) += soc_camera/ diff --git a/drivers/staging/media/davinci_vpfe/Makefile b/drivers/staging/media/davinci_vpfe/Makefile index 9c57042c877d..9268e507f791 100644 --- a/drivers/staging/media/davinci_vpfe/Makefile +++ b/drivers/staging/media/davinci_vpfe/Makefile @@ -6,5 +6,5 @@ davinci-vfpe-objs := \ # Allow building it with COMPILE_TEST on other archs ifndef CONFIG_ARCH_DAVINCI -ccflags-y += -Iarch/arm/mach-davinci/include/ +ccflags-y += -I $(srctree)/arch/arm/mach-davinci/include/ endif diff --git a/drivers/staging/media/davinci_vpfe/dm365_ipipe_hw.c b/drivers/staging/media/davinci_vpfe/dm365_ipipe_hw.c index 5618c804c7e4..565a3dc5bed1 100644 --- a/drivers/staging/media/davinci_vpfe/dm365_ipipe_hw.c +++ b/drivers/staging/media/davinci_vpfe/dm365_ipipe_hw.c @@ -781,7 +781,7 @@ ipipe_set_3d_lut_regs(void __iomem *base_addr, void __iomem *isp5_base_addr, if (!lut_3d->en) return; - /* valied table */ + /* valid table */ tbl = lut_3d->table; for (i = 0; i < VPFE_IPIPE_MAX_SIZE_3D_LUT; i++) { /* diff --git a/drivers/staging/media/davinci_vpfe/dm365_isif.c b/drivers/staging/media/davinci_vpfe/dm365_isif.c index 625d0aa8367f..0a6d038fcec9 100644 --- a/drivers/staging/media/davinci_vpfe/dm365_isif.c +++ b/drivers/staging/media/davinci_vpfe/dm365_isif.c @@ -675,7 +675,7 @@ static void isif_config_bclamp(struct vpfe_isif_device *isif, val = (bc->bc_mode_color & ISIF_BC_MODE_COLOR_MASK) << ISIF_BC_MODE_COLOR_SHIFT; - /* Enable BC and horizontal clamp calculation paramaters */ + /* Enable BC and horizontal clamp calculation parameters */ val = val | 1 | ((bc->horz.mode & ISIF_HORZ_BC_MODE_MASK) << ISIF_HORZ_BC_MODE_SHIFT); @@ -712,7 +712,7 @@ static void isif_config_bclamp(struct vpfe_isif_device *isif, isif_write(isif->isif_cfg.base_addr, val, CLHWIN2); } - /* vertical clamp calculation paramaters */ + /* vertical clamp calculation parameters */ /* OB H Valid */ val = bc->vert.ob_h_sz_calc & ISIF_VERT_BC_OB_H_SZ_MASK; diff --git a/drivers/staging/media/davinci_vpfe/dm365_resizer.c b/drivers/staging/media/davinci_vpfe/dm365_resizer.c index 6098f43ac51b..9d726298b406 100644 --- a/drivers/staging/media/davinci_vpfe/dm365_resizer.c +++ b/drivers/staging/media/davinci_vpfe/dm365_resizer.c @@ -1284,7 +1284,7 @@ static int resizer_set_stream(struct v4l2_subdev *sd, int enable) * @cfg: V4L2 subdev pad config * @pad: pad number. * @which: wanted subdev format. - * Retun wanted mbus frame format. + * Return wanted mbus frame format. */ static struct v4l2_mbus_framefmt * __resizer_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, @@ -1785,7 +1785,7 @@ void vpfe_resizer_unregister_entities(struct vpfe_resizer_device *vpfe_rsz) /* * vpfe_resizer_register_entities() - Register entity - * @resizer - pointer to resizer devive. + * @resizer - pointer to resizer device. * @vdev: pointer to v4l2 device structure. */ int vpfe_resizer_register_entities(struct vpfe_resizer_device *resizer, diff --git a/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c b/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c index 34d63c2e9199..57b93605bc58 100644 --- a/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c +++ b/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c @@ -528,7 +528,7 @@ static void vpfe_cleanup_modules(struct vpfe_device *vpfe_dev, * @vpfe_dev - ptr to vpfe capture device * @pdev - pointer to platform device * - * intialize all v4l2 subdevs and media entities + * initialize all v4l2 subdevs and media entities */ static int vpfe_initialize_modules(struct vpfe_device *vpfe_dev, struct platform_device *pdev) diff --git a/drivers/staging/media/imx/Kconfig b/drivers/staging/media/imx/Kconfig index bfc17de56b17..36b276ea2ecc 100644 --- a/drivers/staging/media/imx/Kconfig +++ b/drivers/staging/media/imx/Kconfig @@ -11,7 +11,7 @@ config VIDEO_IMX_MEDIA driver for the i.MX5/6 SOC. if VIDEO_IMX_MEDIA -menu "i.MX5/6 Media Sub devices" +menu "i.MX5/6/7 Media Sub devices" config VIDEO_IMX_CSI tristate "i.MX5/6 Camera Sensor Interface driver" @@ -20,5 +20,12 @@ config VIDEO_IMX_CSI ---help--- A video4linux camera sensor interface driver for i.MX5/6. +config VIDEO_IMX7_CSI + tristate "i.MX7 Camera Sensor Interface driver" + depends on VIDEO_IMX_MEDIA && VIDEO_DEV && I2C + default y + help + Enable support for video4linux camera sensor interface driver for + i.MX7. endmenu endif diff --git a/drivers/staging/media/imx/Makefile b/drivers/staging/media/imx/Makefile index 698a4210316e..d2d909a36239 100644 --- a/drivers/staging/media/imx/Makefile +++ b/drivers/staging/media/imx/Makefile @@ -1,5 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 imx-media-objs := imx-media-dev.o imx-media-internal-sd.o imx-media-of.o +imx-media-objs += imx-media-dev-common.o imx-media-common-objs := imx-media-utils.o imx-media-fim.o imx-media-ic-objs := imx-ic-common.o imx-ic-prp.o imx-ic-prpencvf.o @@ -11,3 +12,6 @@ obj-$(CONFIG_VIDEO_IMX_MEDIA) += imx-media-ic.o obj-$(CONFIG_VIDEO_IMX_CSI) += imx-media-csi.o obj-$(CONFIG_VIDEO_IMX_CSI) += imx6-mipi-csi2.o + +obj-$(CONFIG_VIDEO_IMX7_CSI) += imx7-media-csi.o +obj-$(CONFIG_VIDEO_IMX7_CSI) += imx7-mipi-csis.o diff --git a/drivers/staging/media/imx/TODO b/drivers/staging/media/imx/TODO index aeeb15494a49..6f29b5ca5324 100644 --- a/drivers/staging/media/imx/TODO +++ b/drivers/staging/media/imx/TODO @@ -45,3 +45,12 @@ Which means a port must not contain mixed-use endpoints, they must all refer to media links between V4L2 subdevices. + +- i.MX7: all of the above, since it uses the imx media core + +- i.MX7: use Frame Interval Monitor + +- i.MX7: runtime testing with parallel sensor, links setup and streaming + +- i.MX7: runtime testing with different formats, for the time only 10-bit bayer + is tested diff --git a/drivers/staging/media/imx/imx-ic-common.c b/drivers/staging/media/imx/imx-ic-common.c index cfdd4900a3be..765919487a73 100644 --- a/drivers/staging/media/imx/imx-ic-common.c +++ b/drivers/staging/media/imx/imx-ic-common.c @@ -41,13 +41,13 @@ static int imx_ic_probe(struct platform_device *pdev) pdata = priv->dev->platform_data; priv->ipu_id = pdata->ipu_id; switch (pdata->grp_id) { - case IMX_MEDIA_GRP_ID_IC_PRP: + case IMX_MEDIA_GRP_ID_IPU_IC_PRP: priv->task_id = IC_TASK_PRP; break; - case IMX_MEDIA_GRP_ID_IC_PRPENC: + case IMX_MEDIA_GRP_ID_IPU_IC_PRPENC: priv->task_id = IC_TASK_ENCODER; break; - case IMX_MEDIA_GRP_ID_IC_PRPVF: + case IMX_MEDIA_GRP_ID_IPU_IC_PRPVF: priv->task_id = IC_TASK_VIEWFINDER; break; default: diff --git a/drivers/staging/media/imx/imx-ic-prp.c b/drivers/staging/media/imx/imx-ic-prp.c index 98923fc844ce..3d43cdcb4bb9 100644 --- a/drivers/staging/media/imx/imx-ic-prp.c +++ b/drivers/staging/media/imx/imx-ic-prp.c @@ -77,7 +77,7 @@ static int prp_start(struct prp_priv *priv) priv->ipu = priv->md->ipu[ic_priv->ipu_id]; /* set IC to receive from CSI or VDI depending on source */ - src_is_vdic = !!(priv->src_sd->grp_id & IMX_MEDIA_GRP_ID_VDIC); + src_is_vdic = !!(priv->src_sd->grp_id & IMX_MEDIA_GRP_ID_IPU_VDIC); ipu_set_ic_src_mux(priv->ipu, priv->csi_id, src_is_vdic); @@ -237,8 +237,8 @@ static int prp_link_setup(struct media_entity *entity, ret = -EBUSY; goto out; } - if (priv->sink_sd_prpenc && (remote_sd->grp_id & - IMX_MEDIA_GRP_ID_VDIC)) { + if (priv->sink_sd_prpenc && + (remote_sd->grp_id & IMX_MEDIA_GRP_ID_IPU_VDIC)) { ret = -EINVAL; goto out; } @@ -259,7 +259,7 @@ static int prp_link_setup(struct media_entity *entity, goto out; } if (priv->src_sd && (priv->src_sd->grp_id & - IMX_MEDIA_GRP_ID_VDIC)) { + IMX_MEDIA_GRP_ID_IPU_VDIC)) { ret = -EINVAL; goto out; } @@ -309,13 +309,13 @@ static int prp_link_validate(struct v4l2_subdev *sd, return ret; csi = imx_media_find_upstream_subdev(priv->md, &ic_priv->sd.entity, - IMX_MEDIA_GRP_ID_CSI); + IMX_MEDIA_GRP_ID_IPU_CSI); if (IS_ERR(csi)) csi = NULL; mutex_lock(&priv->lock); - if (priv->src_sd->grp_id & IMX_MEDIA_GRP_ID_VDIC) { + if (priv->src_sd->grp_id & IMX_MEDIA_GRP_ID_IPU_VDIC) { /* * the ->PRPENC link cannot be enabled if the source * is the VDIC @@ -334,10 +334,10 @@ static int prp_link_validate(struct v4l2_subdev *sd, if (csi) { switch (csi->grp_id) { - case IMX_MEDIA_GRP_ID_CSI0: + case IMX_MEDIA_GRP_ID_IPU_CSI0: priv->csi_id = 0; break; - case IMX_MEDIA_GRP_ID_CSI1: + case IMX_MEDIA_GRP_ID_IPU_CSI1: priv->csi_id = 1; break; default: @@ -422,9 +422,14 @@ static int prp_s_frame_interval(struct v4l2_subdev *sd, if (fi->pad >= PRP_NUM_PADS) return -EINVAL; - /* No limits on frame interval */ mutex_lock(&priv->lock); - priv->frame_interval = fi->interval; + + /* No limits on valid frame intervals */ + if (fi->interval.numerator == 0 || fi->interval.denominator == 0) + fi->interval = priv->frame_interval; + else + priv->frame_interval = fi->interval; + mutex_unlock(&priv->lock); return 0; diff --git a/drivers/staging/media/imx/imx-ic-prpencvf.c b/drivers/staging/media/imx/imx-ic-prpencvf.c index 28f41caba05d..5c8e6ad8c025 100644 --- a/drivers/staging/media/imx/imx-ic-prpencvf.c +++ b/drivers/staging/media/imx/imx-ic-prpencvf.c @@ -48,7 +48,7 @@ #define MAX_W_SRC 1024 #define MAX_H_SRC 1024 -#define W_ALIGN_SRC 4 /* multiple of 16 pixels */ +#define W_ALIGN_SRC 1 /* multiple of 2 pixels */ #define H_ALIGN_SRC 1 /* multiple of 2 lines */ #define S_ALIGN 1 /* multiple of 2 */ @@ -106,6 +106,7 @@ struct prp_priv { u32 frame_sequence; /* frame sequence counter */ bool last_eof; /* waiting for last EOF at stream off */ bool nfb4eof; /* NFB4EOF encountered during streaming */ + bool interweave_swap; /* swap top/bottom lines when interweaving */ struct completion last_eof_comp; }; @@ -235,6 +236,9 @@ static void prp_vb2_buf_done(struct prp_priv *priv, struct ipuv3_channel *ch) if (ipu_idmac_buffer_is_ready(ch, priv->ipu_buf_num)) ipu_idmac_clear_buffer(ch, priv->ipu_buf_num); + if (priv->interweave_swap && ch == priv->out_ch) + phys += vdev->fmt.fmt.pix.bytesperline; + ipu_cpmem_set_buffer(ch, priv->ipu_buf_num, phys); } @@ -354,20 +358,30 @@ static int prp_setup_channel(struct prp_priv *priv, { struct imx_media_video_dev *vdev = priv->vdev; const struct imx_media_pixfmt *outcc; - struct v4l2_mbus_framefmt *infmt; + struct v4l2_mbus_framefmt *outfmt; unsigned int burst_size; struct ipu_image image; + bool interweave; int ret; - infmt = &priv->format_mbus[PRPENCVF_SINK_PAD]; + outfmt = &priv->format_mbus[PRPENCVF_SRC_PAD]; outcc = vdev->cc; ipu_cpmem_zero(channel); memset(&image, 0, sizeof(image)); image.pix = vdev->fmt.fmt.pix; - image.rect.width = image.pix.width; - image.rect.height = image.pix.height; + image.rect = vdev->compose; + + /* + * If the field type at capture interface is interlaced, and + * the output IDMAC pad is sequential, enable interweave at + * the IDMAC output channel. + */ + interweave = V4L2_FIELD_IS_INTERLACED(image.pix.field) && + V4L2_FIELD_IS_SEQUENTIAL(outfmt->field); + priv->interweave_swap = interweave && + image.pix.field == V4L2_FIELD_INTERLACED_BT; if (rot_swap_width_height) { swap(image.pix.width, image.pix.height); @@ -378,15 +392,25 @@ static int prp_setup_channel(struct prp_priv *priv, (image.pix.width * outcc->bpp) >> 3; } + if (priv->interweave_swap && channel == priv->out_ch) { + /* start interweave scan at 1st top line (2nd line) */ + image.rect.top = 1; + } + image.phys0 = addr0; image.phys1 = addr1; - if (channel == priv->out_ch || channel == priv->rot_out_ch) { + /* + * Skip writing U and V components to odd rows in the output + * channels for planar 4:2:0 (but not when enabling IDMAC + * interweaving, they are incompatible). + */ + if ((channel == priv->out_ch && !interweave) || + channel == priv->rot_out_ch) { switch (image.pix.pixelformat) { case V4L2_PIX_FMT_YUV420: case V4L2_PIX_FMT_YVU420: case V4L2_PIX_FMT_NV12: - /* Skip writing U and V components to odd rows */ ipu_cpmem_skip_odd_chroma_rows(channel); break; } @@ -409,10 +433,12 @@ static int prp_setup_channel(struct prp_priv *priv, if (rot_mode) ipu_cpmem_set_rotation(channel, rot_mode); - if (image.pix.field == V4L2_FIELD_NONE && - V4L2_FIELD_HAS_BOTH(infmt->field) && - channel == priv->out_ch) - ipu_cpmem_interlaced_scan(channel, image.pix.bytesperline); + if (interweave && channel == priv->out_ch) + ipu_cpmem_interlaced_scan(channel, + priv->interweave_swap ? + -image.pix.bytesperline : + image.pix.bytesperline, + image.pix.pixelformat); ret = ipu_ic_task_idma_init(priv->ic, channel, image.pix.width, image.pix.height, @@ -680,12 +706,23 @@ static int prp_start(struct prp_priv *priv) goto out_free_nfb4eof_irq; } + /* start upstream */ + ret = v4l2_subdev_call(priv->src_sd, video, s_stream, 1); + ret = (ret && ret != -ENOIOCTLCMD) ? ret : 0; + if (ret) { + v4l2_err(&ic_priv->sd, + "upstream stream on failed: %d\n", ret); + goto out_free_eof_irq; + } + /* start the EOF timeout timer */ mod_timer(&priv->eof_timeout_timer, jiffies + msecs_to_jiffies(IMX_MEDIA_EOF_TIMEOUT)); return 0; +out_free_eof_irq: + devm_free_irq(ic_priv->dev, priv->eof_irq, priv); out_free_nfb4eof_irq: devm_free_irq(ic_priv->dev, priv->nfb4eof_irq, priv); out_unsetup: @@ -717,6 +754,12 @@ static void prp_stop(struct prp_priv *priv) if (ret == 0) v4l2_warn(&ic_priv->sd, "wait last EOF timeout\n"); + /* stop upstream */ + ret = v4l2_subdev_call(priv->src_sd, video, s_stream, 0); + if (ret && ret != -ENOIOCTLCMD) + v4l2_warn(&ic_priv->sd, + "upstream stream off failed: %d\n", ret); + devm_free_irq(ic_priv->dev, priv->eof_irq, priv); devm_free_irq(ic_priv->dev, priv->nfb4eof_irq, priv); @@ -838,8 +881,7 @@ static void prp_try_fmt(struct prp_priv *priv, infmt = __prp_get_fmt(priv, cfg, PRPENCVF_SINK_PAD, sdformat->which); if (sdformat->pad == PRPENCVF_SRC_PAD) { - if (sdformat->format.field != V4L2_FIELD_NONE) - sdformat->format.field = infmt->field; + sdformat->format.field = infmt->field; prp_bound_align_output(&sdformat->format, infmt, priv->rot_mode); @@ -870,6 +912,7 @@ static int prp_set_fmt(struct v4l2_subdev *sd, const struct imx_media_pixfmt *cc; struct v4l2_pix_format vdev_fmt; struct v4l2_mbus_framefmt *fmt; + struct v4l2_rect vdev_compose; int ret = 0; if (sdformat->pad >= PRPENCVF_NUM_PADS) @@ -911,11 +954,11 @@ static int prp_set_fmt(struct v4l2_subdev *sd, priv->cc[sdformat->pad] = cc; /* propagate output pad format to capture device */ - imx_media_mbus_fmt_to_pix_fmt(&vdev_fmt, + imx_media_mbus_fmt_to_pix_fmt(&vdev_fmt, &vdev_compose, &priv->format_mbus[PRPENCVF_SRC_PAD], priv->cc[PRPENCVF_SRC_PAD]); mutex_unlock(&priv->lock); - imx_media_capture_device_set_format(vdev, &vdev_fmt); + imx_media_capture_device_set_format(vdev, &vdev_fmt, &vdev_compose); return 0; out: @@ -1148,15 +1191,6 @@ static int prp_s_stream(struct v4l2_subdev *sd, int enable) if (ret) goto out; - /* start/stop upstream */ - ret = v4l2_subdev_call(priv->src_sd, video, s_stream, enable); - ret = (ret && ret != -ENOIOCTLCMD) ? ret : 0; - if (ret) { - if (enable) - prp_stop(priv); - goto out; - } - update_count: priv->stream_count += enable ? 1 : -1; if (priv->stream_count < 0) @@ -1189,9 +1223,14 @@ static int prp_s_frame_interval(struct v4l2_subdev *sd, if (fi->pad >= PRPENCVF_NUM_PADS) return -EINVAL; - /* No limits on frame interval */ mutex_lock(&priv->lock); - priv->frame_interval = fi->interval; + + /* No limits on valid frame intervals */ + if (fi->interval.numerator == 0 || fi->interval.denominator == 0) + fi->interval = priv->frame_interval; + else + priv->frame_interval = fi->interval; + mutex_unlock(&priv->lock); return 0; diff --git a/drivers/staging/media/imx/imx-media-capture.c b/drivers/staging/media/imx/imx-media-capture.c index b37e1186eb2f..9703c85b19c4 100644 --- a/drivers/staging/media/imx/imx-media-capture.c +++ b/drivers/staging/media/imx/imx-media-capture.c @@ -203,21 +203,14 @@ static int capture_g_fmt_vid_cap(struct file *file, void *fh, return 0; } -static int capture_try_fmt_vid_cap(struct file *file, void *fh, - struct v4l2_format *f) +static int __capture_try_fmt_vid_cap(struct capture_priv *priv, + struct v4l2_subdev_format *fmt_src, + struct v4l2_format *f, + struct v4l2_rect *compose) { - struct capture_priv *priv = video_drvdata(file); - struct v4l2_subdev_format fmt_src; const struct imx_media_pixfmt *cc, *cc_src; - int ret; - - fmt_src.pad = priv->src_sd_pad; - fmt_src.which = V4L2_SUBDEV_FORMAT_ACTIVE; - ret = v4l2_subdev_call(priv->src_sd, pad, get_fmt, NULL, &fmt_src); - if (ret) - return ret; - cc_src = imx_media_find_ipu_format(fmt_src.format.code, CS_SEL_ANY); + cc_src = imx_media_find_ipu_format(fmt_src->format.code, CS_SEL_ANY); if (cc_src) { u32 fourcc, cs_sel; @@ -231,7 +224,7 @@ static int capture_try_fmt_vid_cap(struct file *file, void *fh, cc = imx_media_find_format(fourcc, cs_sel, false); } } else { - cc_src = imx_media_find_mbus_format(fmt_src.format.code, + cc_src = imx_media_find_mbus_format(fmt_src->format.code, CS_SEL_ANY, true); if (WARN_ON(!cc_src)) return -EINVAL; @@ -239,15 +232,48 @@ static int capture_try_fmt_vid_cap(struct file *file, void *fh, cc = cc_src; } - imx_media_mbus_fmt_to_pix_fmt(&f->fmt.pix, &fmt_src.format, cc); + /* allow IDMAC interweave but enforce field order from source */ + if (V4L2_FIELD_IS_INTERLACED(f->fmt.pix.field)) { + switch (fmt_src->format.field) { + case V4L2_FIELD_SEQ_TB: + fmt_src->format.field = V4L2_FIELD_INTERLACED_TB; + break; + case V4L2_FIELD_SEQ_BT: + fmt_src->format.field = V4L2_FIELD_INTERLACED_BT; + break; + default: + break; + } + } + + imx_media_mbus_fmt_to_pix_fmt(&f->fmt.pix, compose, + &fmt_src->format, cc); return 0; } +static int capture_try_fmt_vid_cap(struct file *file, void *fh, + struct v4l2_format *f) +{ + struct capture_priv *priv = video_drvdata(file); + struct v4l2_subdev_format fmt_src; + int ret; + + fmt_src.pad = priv->src_sd_pad; + fmt_src.which = V4L2_SUBDEV_FORMAT_ACTIVE; + ret = v4l2_subdev_call(priv->src_sd, pad, get_fmt, NULL, &fmt_src); + if (ret) + return ret; + + return __capture_try_fmt_vid_cap(priv, &fmt_src, f, NULL); +} + static int capture_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f) { struct capture_priv *priv = video_drvdata(file); + struct v4l2_subdev_format fmt_src; + struct v4l2_rect compose; int ret; if (vb2_is_busy(&priv->q)) { @@ -255,13 +281,20 @@ static int capture_s_fmt_vid_cap(struct file *file, void *fh, return -EBUSY; } - ret = capture_try_fmt_vid_cap(file, priv, f); + fmt_src.pad = priv->src_sd_pad; + fmt_src.which = V4L2_SUBDEV_FORMAT_ACTIVE; + ret = v4l2_subdev_call(priv->src_sd, pad, get_fmt, NULL, &fmt_src); + if (ret) + return ret; + + ret = __capture_try_fmt_vid_cap(priv, &fmt_src, f, &compose); if (ret) return ret; priv->vdev.fmt.fmt.pix = f->fmt.pix; priv->vdev.cc = imx_media_find_format(f->fmt.pix.pixelformat, CS_SEL_ANY, true); + priv->vdev.compose = compose; return 0; } @@ -290,6 +323,36 @@ static int capture_s_std(struct file *file, void *fh, v4l2_std_id std) return v4l2_subdev_call(priv->src_sd, video, s_std, std); } +static int capture_g_selection(struct file *file, void *fh, + struct v4l2_selection *s) +{ + struct capture_priv *priv = video_drvdata(file); + + switch (s->target) { + case V4L2_SEL_TGT_COMPOSE: + case V4L2_SEL_TGT_COMPOSE_DEFAULT: + case V4L2_SEL_TGT_COMPOSE_BOUNDS: + /* The compose rectangle is fixed to the source format. */ + s->r = priv->vdev.compose; + break; + case V4L2_SEL_TGT_COMPOSE_PADDED: + /* + * The hardware writes with a configurable but fixed DMA burst + * size. If the source format width is not burst size aligned, + * the written frame contains padding to the right. + */ + s->r.left = 0; + s->r.top = 0; + s->r.width = priv->vdev.fmt.fmt.pix.width; + s->r.height = priv->vdev.fmt.fmt.pix.height; + break; + default: + return -EINVAL; + } + + return 0; +} + static int capture_g_parm(struct file *file, void *fh, struct v4l2_streamparm *a) { @@ -335,6 +398,21 @@ static int capture_s_parm(struct file *file, void *fh, return 0; } +static int capture_subscribe_event(struct v4l2_fh *fh, + const struct v4l2_event_subscription *sub) +{ + switch (sub->type) { + case V4L2_EVENT_IMX_FRAME_INTERVAL_ERROR: + return v4l2_event_subscribe(fh, sub, 0, NULL); + case V4L2_EVENT_SOURCE_CHANGE: + return v4l2_src_change_event_subscribe(fh, sub); + case V4L2_EVENT_CTRL: + return v4l2_ctrl_subscribe_event(fh, sub); + default: + return -EINVAL; + } +} + static const struct v4l2_ioctl_ops capture_ioctl_ops = { .vidioc_querycap = vidioc_querycap, @@ -350,6 +428,8 @@ static const struct v4l2_ioctl_ops capture_ioctl_ops = { .vidioc_g_std = capture_g_std, .vidioc_s_std = capture_s_std, + .vidioc_g_selection = capture_g_selection, + .vidioc_g_parm = capture_g_parm, .vidioc_s_parm = capture_s_parm, @@ -362,6 +442,9 @@ static const struct v4l2_ioctl_ops capture_ioctl_ops = { .vidioc_expbuf = vb2_ioctl_expbuf, .vidioc_streamon = vb2_ioctl_streamon, .vidioc_streamoff = vb2_ioctl_streamoff, + + .vidioc_subscribe_event = capture_subscribe_event, + .vidioc_unsubscribe_event = v4l2_event_unsubscribe, }; /* @@ -572,7 +655,8 @@ static struct video_device capture_videodev = { }; void imx_media_capture_device_set_format(struct imx_media_video_dev *vdev, - struct v4l2_pix_format *pix) + const struct v4l2_pix_format *pix, + const struct v4l2_rect *compose) { struct capture_priv *priv = to_capture_priv(vdev); @@ -580,6 +664,7 @@ void imx_media_capture_device_set_format(struct imx_media_video_dev *vdev, priv->vdev.fmt.fmt.pix = *pix; priv->vdev.cc = imx_media_find_format(pix->pixelformat, CS_SEL_ANY, true); + priv->vdev.compose = *compose; mutex_unlock(&priv->mutex); } EXPORT_SYMBOL_GPL(imx_media_capture_device_set_format); @@ -685,7 +770,7 @@ int imx_media_capture_device_register(struct imx_media_video_dev *vdev) } vdev->fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - imx_media_mbus_fmt_to_pix_fmt(&vdev->fmt.fmt.pix, + imx_media_mbus_fmt_to_pix_fmt(&vdev->fmt.fmt.pix, &vdev->compose, &fmt_src.format, NULL); vdev->cc = imx_media_find_format(vdev->fmt.fmt.pix.pixelformat, CS_SEL_ANY, false); diff --git a/drivers/staging/media/imx/imx-media-csi.c b/drivers/staging/media/imx/imx-media-csi.c index 4223f8d418ae..3b7517348666 100644 --- a/drivers/staging/media/imx/imx-media-csi.c +++ b/drivers/staging/media/imx/imx-media-csi.c @@ -41,7 +41,7 @@ #define MIN_H 144 #define MAX_W 4096 #define MAX_H 4096 -#define W_ALIGN 4 /* multiple of 16 pixels */ +#define W_ALIGN 1 /* multiple of 2 pixels */ #define H_ALIGN 1 /* multiple of 2 lines */ #define S_ALIGN 1 /* multiple of 2 */ @@ -114,6 +114,7 @@ struct csi_priv { u32 frame_sequence; /* frame sequence counter */ bool last_eof; /* waiting for last EOF at stream off */ bool nfb4eof; /* NFB4EOF encountered during streaming */ + bool interweave_swap; /* swap top/bottom lines when interweaving */ struct completion last_eof_comp; }; @@ -286,6 +287,9 @@ static void csi_vb2_buf_done(struct csi_priv *priv) if (ipu_idmac_buffer_is_ready(priv->idmac_ch, priv->ipu_buf_num)) ipu_idmac_clear_buffer(priv->idmac_ch, priv->ipu_buf_num); + if (priv->interweave_swap) + phys += vdev->fmt.fmt.pix.bytesperline; + ipu_cpmem_set_buffer(priv->idmac_ch, priv->ipu_buf_num, phys); } @@ -398,23 +402,24 @@ static int csi_idmac_setup_channel(struct csi_priv *priv) struct imx_media_video_dev *vdev = priv->vdev; const struct imx_media_pixfmt *incc; struct v4l2_mbus_framefmt *infmt; + struct v4l2_mbus_framefmt *outfmt; + bool passthrough, interweave; struct ipu_image image; u32 passthrough_bits; u32 passthrough_cycles; dma_addr_t phys[2]; - bool passthrough; u32 burst_size; int ret; infmt = &priv->format_mbus[CSI_SINK_PAD]; incc = priv->cc[CSI_SINK_PAD]; + outfmt = &priv->format_mbus[CSI_SRC_PAD_IDMAC]; ipu_cpmem_zero(priv->idmac_ch); memset(&image, 0, sizeof(image)); image.pix = vdev->fmt.fmt.pix; - image.rect.width = image.pix.width; - image.rect.height = image.pix.height; + image.rect = vdev->compose; csi_idmac_setup_vb2_buf(priv, phys); @@ -424,6 +429,16 @@ static int csi_idmac_setup_channel(struct csi_priv *priv) passthrough = requires_passthrough(&priv->upstream_ep, infmt, incc); passthrough_cycles = 1; + /* + * If the field type at capture interface is interlaced, and + * the output IDMAC pad is sequential, enable interweave at + * the IDMAC output channel. + */ + interweave = V4L2_FIELD_IS_INTERLACED(image.pix.field) && + V4L2_FIELD_IS_SEQUENTIAL(outfmt->field); + priv->interweave_swap = interweave && + image.pix.field == V4L2_FIELD_INTERLACED_BT; + switch (image.pix.pixelformat) { case V4L2_PIX_FMT_SBGGR8: case V4L2_PIX_FMT_SGBRG8: @@ -442,13 +457,18 @@ static int csi_idmac_setup_channel(struct csi_priv *priv) passthrough_bits = 16; break; case V4L2_PIX_FMT_YUV420: + case V4L2_PIX_FMT_YVU420: case V4L2_PIX_FMT_NV12: burst_size = (image.pix.width & 0x3f) ? ((image.pix.width & 0x1f) ? ((image.pix.width & 0xf) ? 8 : 16) : 32) : 64; passthrough_bits = 16; - /* Skip writing U and V components to odd rows */ - ipu_cpmem_skip_odd_chroma_rows(priv->idmac_ch); + /* + * Skip writing U and V components to odd rows (but not + * when enabling IDMAC interweaving, they are incompatible). + */ + if (!interweave) + ipu_cpmem_skip_odd_chroma_rows(priv->idmac_ch); break; case V4L2_PIX_FMT_YUYV: case V4L2_PIX_FMT_UYVY: @@ -471,6 +491,12 @@ static int csi_idmac_setup_channel(struct csi_priv *priv) } if (passthrough) { + if (priv->interweave_swap) { + /* start interweave scan at 1st top line (2nd line) */ + image.phys0 += image.pix.bytesperline; + image.phys1 += image.pix.bytesperline; + } + ipu_cpmem_set_resolution(priv->idmac_ch, image.rect.width * passthrough_cycles, image.rect.height); @@ -480,6 +506,11 @@ static int csi_idmac_setup_channel(struct csi_priv *priv) ipu_cpmem_set_format_passthrough(priv->idmac_ch, passthrough_bits); } else { + if (priv->interweave_swap) { + /* start interweave scan at 1st top line (2nd line) */ + image.rect.top = 1; + } + ret = ipu_cpmem_set_image(priv->idmac_ch, &image); if (ret) goto unsetup_vb2; @@ -509,10 +540,12 @@ static int csi_idmac_setup_channel(struct csi_priv *priv) ipu_smfc_set_burstsize(priv->smfc, burst_size); - if (image.pix.field == V4L2_FIELD_NONE && - V4L2_FIELD_HAS_BOTH(infmt->field)) + if (interweave) ipu_cpmem_interlaced_scan(priv->idmac_ch, - image.pix.bytesperline); + priv->interweave_swap ? + -image.pix.bytesperline : + image.pix.bytesperline, + image.pix.pixelformat); ipu_idmac_set_double_buffer(priv->idmac_ch, true); @@ -629,7 +662,7 @@ out_put_ipu: return ret; } -static void csi_idmac_stop(struct csi_priv *priv) +static void csi_idmac_wait_last_eof(struct csi_priv *priv) { unsigned long flags; int ret; @@ -646,7 +679,10 @@ static void csi_idmac_stop(struct csi_priv *priv) &priv->last_eof_comp, msecs_to_jiffies(IMX_MEDIA_EOF_TIMEOUT)); if (ret == 0) v4l2_warn(&priv->sd, "wait last EOF timeout\n"); +} +static void csi_idmac_stop(struct csi_priv *priv) +{ devm_free_irq(priv->dev, priv->eof_irq, priv); devm_free_irq(priv->dev, priv->nfb4eof_irq, priv); @@ -679,12 +715,7 @@ static int csi_setup(struct csi_priv *priv) priv->upstream_ep.bus.parallel.flags : priv->upstream_ep.bus.mipi_csi2.flags; - /* - * we need to pass input frame to CSI interface, but - * with translated field type from output format - */ if_fmt = *infmt; - if_fmt.field = outfmt->field; crop = priv->crop; /* @@ -702,7 +733,7 @@ static int csi_setup(struct csi_priv *priv) priv->crop.width == 2 * priv->compose.width, priv->crop.height == 2 * priv->compose.height); - ipu_csi_init_interface(priv->csi, &mbus_cfg, &if_fmt); + ipu_csi_init_interface(priv->csi, &mbus_cfg, &if_fmt, outfmt); ipu_csi_set_dest(priv->csi, priv->dest); @@ -722,10 +753,16 @@ static int csi_start(struct csi_priv *priv) output_fi = &priv->frame_interval[priv->active_output_pad]; + /* start upstream */ + ret = v4l2_subdev_call(priv->src_sd, video, s_stream, 1); + ret = (ret && ret != -ENOIOCTLCMD) ? ret : 0; + if (ret) + return ret; + if (priv->dest == IPU_CSI_DEST_IDMAC) { ret = csi_idmac_start(priv); if (ret) - return ret; + goto stop_upstream; } ret = csi_setup(priv); @@ -753,11 +790,26 @@ fim_off: idmac_stop: if (priv->dest == IPU_CSI_DEST_IDMAC) csi_idmac_stop(priv); +stop_upstream: + v4l2_subdev_call(priv->src_sd, video, s_stream, 0); return ret; } static void csi_stop(struct csi_priv *priv) { + if (priv->dest == IPU_CSI_DEST_IDMAC) + csi_idmac_wait_last_eof(priv); + + /* + * Disable the CSI asap, after syncing with the last EOF. + * Doing so after the IDMA channel is disabled has shown to + * create hard system-wide hangs. + */ + ipu_csi_disable(priv->csi); + + /* stop upstream */ + v4l2_subdev_call(priv->src_sd, video, s_stream, 0); + if (priv->dest == IPU_CSI_DEST_IDMAC) { csi_idmac_stop(priv); @@ -765,8 +817,6 @@ static void csi_stop(struct csi_priv *priv) if (priv->fim) imx_media_fim_set_stream(priv->fim, NULL, false); } - - ipu_csi_disable(priv->csi); } static const struct csi_skip_desc csi_skip[12] = { @@ -876,7 +926,10 @@ static int csi_s_frame_interval(struct v4l2_subdev *sd, switch (fi->pad) { case CSI_SINK_PAD: - /* No limits on input frame interval */ + /* No limits on valid input frame intervals */ + if (fi->interval.numerator == 0 || + fi->interval.denominator == 0) + fi->interval = *input_fi; /* Reset output intervals and frame skipping ratio to 1:1 */ priv->frame_interval[CSI_SRC_PAD_IDMAC] = fi->interval; priv->frame_interval[CSI_SRC_PAD_DIRECT] = fi->interval; @@ -927,23 +980,13 @@ static int csi_s_stream(struct v4l2_subdev *sd, int enable) goto update_count; if (enable) { - /* upstream must be started first, before starting CSI */ - ret = v4l2_subdev_call(priv->src_sd, video, s_stream, 1); - ret = (ret && ret != -ENOIOCTLCMD) ? ret : 0; - if (ret) - goto out; - dev_dbg(priv->dev, "stream ON\n"); ret = csi_start(priv); - if (ret) { - v4l2_subdev_call(priv->src_sd, video, s_stream, 0); + if (ret) goto out; - } } else { dev_dbg(priv->dev, "stream OFF\n"); - /* CSI must be stopped first, then stop upstream */ csi_stop(priv); - v4l2_subdev_call(priv->src_sd, video, s_stream, 0); } update_count: @@ -1001,6 +1044,8 @@ static int csi_link_setup(struct media_entity *entity, v4l2_ctrl_handler_free(&priv->ctrl_hdlr); v4l2_ctrl_handler_init(&priv->ctrl_hdlr, 0); priv->sink = NULL; + /* do not apply IC burst alignment in csi_try_crop */ + priv->active_output_pad = CSI_SRC_PAD_IDMAC; goto out; } @@ -1029,10 +1074,10 @@ static int csi_link_setup(struct media_entity *entity, remote_sd = media_entity_to_v4l2_subdev(remote->entity); switch (remote_sd->grp_id) { - case IMX_MEDIA_GRP_ID_VDIC: + case IMX_MEDIA_GRP_ID_IPU_VDIC: priv->dest = IPU_CSI_DEST_VDIC; break; - case IMX_MEDIA_GRP_ID_IC_PRP: + case IMX_MEDIA_GRP_ID_IPU_IC_PRP: priv->dest = IPU_CSI_DEST_IC; break; default: @@ -1137,12 +1182,21 @@ static void csi_try_crop(struct csi_priv *priv, struct v4l2_mbus_framefmt *infmt, struct v4l2_fwnode_endpoint *upstream_ep) { + u32 in_height; + crop->width = min_t(__u32, infmt->width, crop->width); if (crop->left + crop->width > infmt->width) crop->left = infmt->width - crop->width; /* adjust crop left/width to h/w alignment restrictions */ crop->left &= ~0x3; - crop->width &= ~0x7; + if (priv->active_output_pad == CSI_SRC_PAD_DIRECT) + crop->width &= ~0x7; /* multiple of 8 pixels (IC burst) */ + else + crop->width &= ~0x1; /* multiple of 2 pixels */ + + in_height = infmt->height; + if (infmt->field == V4L2_FIELD_ALTERNATE) + in_height *= 2; /* * FIXME: not sure why yet, but on interlaced bt.656, @@ -1153,12 +1207,12 @@ static void csi_try_crop(struct csi_priv *priv, if (upstream_ep->bus_type == V4L2_MBUS_BT656 && (V4L2_FIELD_HAS_BOTH(infmt->field) || infmt->field == V4L2_FIELD_ALTERNATE)) { - crop->height = infmt->height; - crop->top = (infmt->height == 480) ? 2 : 0; + crop->height = in_height; + crop->top = (in_height == 480) ? 2 : 0; } else { - crop->height = min_t(__u32, infmt->height, crop->height); - if (crop->top + crop->height > infmt->height) - crop->top = infmt->height - crop->height; + crop->height = min_t(__u32, in_height, crop->height); + if (crop->top + crop->height > in_height) + crop->top = in_height - crop->height; } } @@ -1308,6 +1362,49 @@ out: return ret; } +static void csi_try_field(struct csi_priv *priv, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *sdformat) +{ + struct v4l2_mbus_framefmt *infmt = + __csi_get_fmt(priv, cfg, CSI_SINK_PAD, sdformat->which); + + /* no restrictions on sink pad field type */ + if (sdformat->pad == CSI_SINK_PAD) + return; + + switch (infmt->field) { + case V4L2_FIELD_SEQ_TB: + case V4L2_FIELD_SEQ_BT: + /* + * If the user requests sequential at the source pad, + * allow it (along with possibly inverting field order). + * Otherwise passthrough the field type. + */ + if (!V4L2_FIELD_IS_SEQUENTIAL(sdformat->format.field)) + sdformat->format.field = infmt->field; + break; + case V4L2_FIELD_ALTERNATE: + /* + * This driver does not support alternate field mode, and + * the CSI captures a whole frame, so the CSI never presents + * alternate mode at its source pads. If user has not + * already requested sequential, translate ALTERNATE at + * sink pad to SEQ_TB or SEQ_BT at the source pad depending + * on input height (assume NTSC BT order if 480 total active + * frame lines, otherwise PAL TB order). + */ + if (!V4L2_FIELD_IS_SEQUENTIAL(sdformat->format.field)) + sdformat->format.field = (infmt->height == 480 / 2) ? + V4L2_FIELD_SEQ_BT : V4L2_FIELD_SEQ_TB; + break; + default: + /* Passthrough for all other input field types */ + sdformat->format.field = infmt->field; + break; + } +} + static void csi_try_fmt(struct csi_priv *priv, struct v4l2_fwnode_endpoint *upstream_ep, struct v4l2_subdev_pad_config *cfg, @@ -1347,42 +1444,20 @@ static void csi_try_fmt(struct csi_priv *priv, } } - if (sdformat->pad == CSI_SRC_PAD_DIRECT || - sdformat->format.field != V4L2_FIELD_NONE) - sdformat->format.field = infmt->field; - - /* - * translate V4L2_FIELD_ALTERNATE to SEQ_TB or SEQ_BT - * depending on input height (assume NTSC top-bottom - * order if 480 lines, otherwise PAL bottom-top order). - */ - if (sdformat->format.field == V4L2_FIELD_ALTERNATE) { - sdformat->format.field = (infmt->height == 480) ? - V4L2_FIELD_SEQ_TB : V4L2_FIELD_SEQ_BT; - } + csi_try_field(priv, cfg, sdformat); /* propagate colorimetry from sink */ sdformat->format.colorspace = infmt->colorspace; sdformat->format.xfer_func = infmt->xfer_func; sdformat->format.quantization = infmt->quantization; sdformat->format.ycbcr_enc = infmt->ycbcr_enc; + break; case CSI_SINK_PAD: v4l_bound_align_image(&sdformat->format.width, MIN_W, MAX_W, W_ALIGN, &sdformat->format.height, MIN_H, MAX_H, H_ALIGN, S_ALIGN); - /* Reset crop and compose rectangles */ - crop->left = 0; - crop->top = 0; - crop->width = sdformat->format.width; - crop->height = sdformat->format.height; - csi_try_crop(priv, crop, cfg, &sdformat->format, upstream_ep); - compose->left = 0; - compose->top = 0; - compose->width = crop->width; - compose->height = crop->height; - *cc = imx_media_find_mbus_format(sdformat->format.code, CS_SEL_ANY, true); if (!*cc) { @@ -1393,9 +1468,25 @@ static void csi_try_fmt(struct csi_priv *priv, sdformat->format.code = (*cc)->codes[0]; } + csi_try_field(priv, cfg, sdformat); + imx_media_fill_default_mbus_fields( &sdformat->format, infmt, priv->active_output_pad == CSI_SRC_PAD_DIRECT); + + /* Reset crop and compose rectangles */ + crop->left = 0; + crop->top = 0; + crop->width = sdformat->format.width; + crop->height = sdformat->format.height; + if (sdformat->format.field == V4L2_FIELD_ALTERNATE) + crop->height *= 2; + csi_try_crop(priv, crop, cfg, &sdformat->format, upstream_ep); + compose->left = 0; + compose->top = 0; + compose->width = crop->width; + compose->height = crop->height; + break; } } @@ -1411,6 +1502,7 @@ static int csi_set_fmt(struct v4l2_subdev *sd, struct v4l2_pix_format vdev_fmt; struct v4l2_mbus_framefmt *fmt; struct v4l2_rect *crop, *compose; + struct v4l2_rect vdev_compose; int ret; if (sdformat->pad >= CSI_NUM_PADS) @@ -1466,11 +1558,11 @@ static int csi_set_fmt(struct v4l2_subdev *sd, priv->cc[sdformat->pad] = cc; /* propagate IDMAC output pad format to capture device */ - imx_media_mbus_fmt_to_pix_fmt(&vdev_fmt, + imx_media_mbus_fmt_to_pix_fmt(&vdev_fmt, &vdev_compose, &priv->format_mbus[CSI_SRC_PAD_IDMAC], priv->cc[CSI_SRC_PAD_IDMAC]); mutex_unlock(&priv->lock); - imx_media_capture_device_set_format(vdev, &vdev_fmt); + imx_media_capture_device_set_format(vdev, &vdev_fmt, &vdev_compose); return 0; out: @@ -1502,6 +1594,8 @@ static int csi_get_selection(struct v4l2_subdev *sd, sel->r.top = 0; sel->r.width = infmt->width; sel->r.height = infmt->height; + if (infmt->field == V4L2_FIELD_ALTERNATE) + sel->r.height *= 2; break; case V4L2_SEL_TGT_CROP: sel->r = *crop; @@ -1787,7 +1881,7 @@ static int imx_csi_parse_endpoint(struct device *dev, struct v4l2_fwnode_endpoint *vep, struct v4l2_async_subdev *asd) { - return fwnode_device_is_available(asd->match.fwnode) ? 0 : -EINVAL; + return fwnode_device_is_available(asd->match.fwnode) ? 0 : -ENOTCONN; } static int imx_csi_async_register(struct csi_priv *priv) @@ -1864,6 +1958,8 @@ static int imx_csi_probe(struct platform_device *pdev) priv->csi_id = pdata->csi; priv->smfc_id = (priv->csi_id == 0) ? 0 : 2; + priv->active_output_pad = CSI_SRC_PAD_IDMAC; + timer_setup(&priv->eof_timeout_timer, csi_idmac_eof_timeout, 0); spin_lock_init(&priv->irqlock); @@ -1877,7 +1973,7 @@ static int imx_csi_probe(struct platform_device *pdev) priv->sd.owner = THIS_MODULE; priv->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS; priv->sd.grp_id = priv->csi_id ? - IMX_MEDIA_GRP_ID_CSI1 : IMX_MEDIA_GRP_ID_CSI0; + IMX_MEDIA_GRP_ID_IPU_CSI1 : IMX_MEDIA_GRP_ID_IPU_CSI0; imx_media_grp_id_to_sd_name(priv->sd.name, sizeof(priv->sd.name), priv->sd.grp_id, ipu_get_num(priv->ipu)); diff --git a/drivers/staging/media/imx/imx-media-dev-common.c b/drivers/staging/media/imx/imx-media-dev-common.c new file mode 100644 index 000000000000..910594125889 --- /dev/null +++ b/drivers/staging/media/imx/imx-media-dev-common.c @@ -0,0 +1,90 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * V4L2 Media Controller Driver for Freescale common i.MX5/6/7 SOC + * + * Copyright (c) 2019 Linaro Ltd + * Copyright (c) 2016 Mentor Graphics Inc. + */ + +#include <linux/of_graph.h> +#include <linux/of_platform.h> +#include "imx-media.h" + +static const struct v4l2_async_notifier_operations imx_media_subdev_ops = { + .bound = imx_media_subdev_bound, + .complete = imx_media_probe_complete, +}; + +static const struct media_device_ops imx_media_md_ops = { + .link_notify = imx_media_link_notify, +}; + +struct imx_media_dev *imx_media_dev_init(struct device *dev) +{ + struct imx_media_dev *imxmd; + int ret; + + imxmd = devm_kzalloc(dev, sizeof(*imxmd), GFP_KERNEL); + if (!imxmd) + return ERR_PTR(-ENOMEM); + + dev_set_drvdata(dev, imxmd); + + strlcpy(imxmd->md.model, "imx-media", sizeof(imxmd->md.model)); + imxmd->md.ops = &imx_media_md_ops; + imxmd->md.dev = dev; + + mutex_init(&imxmd->mutex); + + imxmd->v4l2_dev.mdev = &imxmd->md; + imxmd->v4l2_dev.notify = imx_media_notify; + strlcpy(imxmd->v4l2_dev.name, "imx-media", + sizeof(imxmd->v4l2_dev.name)); + + media_device_init(&imxmd->md); + + ret = v4l2_device_register(dev, &imxmd->v4l2_dev); + if (ret < 0) { + v4l2_err(&imxmd->v4l2_dev, + "Failed to register v4l2_device: %d\n", ret); + goto cleanup; + } + + dev_set_drvdata(imxmd->v4l2_dev.dev, imxmd); + + INIT_LIST_HEAD(&imxmd->vdev_list); + + v4l2_async_notifier_init(&imxmd->notifier); + + return imxmd; + +cleanup: + media_device_cleanup(&imxmd->md); + + return ERR_PTR(ret); +} +EXPORT_SYMBOL_GPL(imx_media_dev_init); + +int imx_media_dev_notifier_register(struct imx_media_dev *imxmd) +{ + int ret; + + /* no subdevs? just bail */ + if (list_empty(&imxmd->notifier.asd_list)) { + v4l2_err(&imxmd->v4l2_dev, "no subdevs\n"); + return -ENODEV; + } + + /* prepare the async subdev notifier and register it */ + imxmd->notifier.ops = &imx_media_subdev_ops; + ret = v4l2_async_notifier_register(&imxmd->v4l2_dev, + &imxmd->notifier); + if (ret) { + v4l2_err(&imxmd->v4l2_dev, + "v4l2_async_notifier_register failed with %d\n", ret); + return ret; + } + + return 0; +} +EXPORT_SYMBOL_GPL(imx_media_dev_notifier_register); diff --git a/drivers/staging/media/imx/imx-media-dev.c b/drivers/staging/media/imx/imx-media-dev.c index 4b344a4a3706..28a3d23aad5b 100644 --- a/drivers/staging/media/imx/imx-media-dev.c +++ b/drivers/staging/media/imx/imx-media-dev.c @@ -116,16 +116,16 @@ static int imx_media_get_ipu(struct imx_media_dev *imxmd, } /* async subdev bound notifier */ -static int imx_media_subdev_bound(struct v4l2_async_notifier *notifier, - struct v4l2_subdev *sd, - struct v4l2_async_subdev *asd) +int imx_media_subdev_bound(struct v4l2_async_notifier *notifier, + struct v4l2_subdev *sd, + struct v4l2_async_subdev *asd) { struct imx_media_dev *imxmd = notifier2dev(notifier); int ret = 0; mutex_lock(&imxmd->mutex); - if (sd->grp_id & IMX_MEDIA_GRP_ID_CSI) { + if (sd->grp_id & IMX_MEDIA_GRP_ID_IPU_CSI) { ret = imx_media_get_ipu(imxmd, sd); if (ret) goto out; @@ -149,13 +149,13 @@ static int imx_media_create_links(struct v4l2_async_notifier *notifier) list_for_each_entry(sd, &imxmd->v4l2_dev.subdevs, list) { switch (sd->grp_id) { - case IMX_MEDIA_GRP_ID_VDIC: - case IMX_MEDIA_GRP_ID_IC_PRP: - case IMX_MEDIA_GRP_ID_IC_PRPENC: - case IMX_MEDIA_GRP_ID_IC_PRPVF: - case IMX_MEDIA_GRP_ID_CSI0: - case IMX_MEDIA_GRP_ID_CSI1: - ret = imx_media_create_internal_links(imxmd, sd); + case IMX_MEDIA_GRP_ID_IPU_VDIC: + case IMX_MEDIA_GRP_ID_IPU_IC_PRP: + case IMX_MEDIA_GRP_ID_IPU_IC_PRPENC: + case IMX_MEDIA_GRP_ID_IPU_IC_PRPVF: + case IMX_MEDIA_GRP_ID_IPU_CSI0: + case IMX_MEDIA_GRP_ID_IPU_CSI1: + ret = imx_media_create_ipu_internal_links(imxmd, sd); if (ret) return ret; /* @@ -163,9 +163,13 @@ static int imx_media_create_links(struct v4l2_async_notifier *notifier) * internal entities, so create the external links * to the CSI sink pads. */ - if (sd->grp_id & IMX_MEDIA_GRP_ID_CSI) + if (sd->grp_id & IMX_MEDIA_GRP_ID_IPU_CSI) imx_media_create_csi_of_links(imxmd, sd); break; + case IMX_MEDIA_GRP_ID_CSI: + imx_media_create_csi_of_links(imxmd, sd); + + break; default: /* * if this subdev has fwnode links, create media @@ -302,7 +306,7 @@ static int imx_media_create_pad_vdev_lists(struct imx_media_dev *imxmd) } /* async subdev complete notifier */ -static int imx_media_probe_complete(struct v4l2_async_notifier *notifier) +int imx_media_probe_complete(struct v4l2_async_notifier *notifier) { struct imx_media_dev *imxmd = notifier2dev(notifier); int ret; @@ -326,11 +330,6 @@ unlock: return media_device_register(&imxmd->md); } -static const struct v4l2_async_notifier_operations imx_media_subdev_ops = { - .bound = imx_media_subdev_bound, - .complete = imx_media_probe_complete, -}; - /* * adds controls to a video device from an entity subdevice. * Continues upstream from the entity's sink pads. @@ -374,8 +373,8 @@ static int imx_media_inherit_controls(struct imx_media_dev *imxmd, return ret; } -static int imx_media_link_notify(struct media_link *link, u32 flags, - unsigned int notification) +int imx_media_link_notify(struct media_link *link, u32 flags, + unsigned int notification) { struct media_entity *source = link->source->entity; struct imx_media_pad_vdev *pad_vdev; @@ -438,9 +437,27 @@ static int imx_media_link_notify(struct media_link *link, u32 flags, return ret; } -static const struct media_device_ops imx_media_md_ops = { - .link_notify = imx_media_link_notify, -}; +void imx_media_notify(struct v4l2_subdev *sd, unsigned int notification, + void *arg) +{ + struct media_entity *entity = &sd->entity; + int i; + + if (notification != V4L2_DEVICE_NOTIFY_EVENT) + return; + + for (i = 0; i < entity->num_pads; i++) { + struct media_pad *pad = &entity->pads[i]; + struct imx_media_pad_vdev *pad_vdev; + struct list_head *pad_vdev_list; + + pad_vdev_list = to_pad_vdev_list(sd, pad->index); + if (!pad_vdev_list) + continue; + list_for_each_entry(pad_vdev, pad_vdev_list, list) + v4l2_event_queue(pad_vdev->vdev->vfd, arg); + } +} static int imx_media_probe(struct platform_device *pdev) { @@ -449,76 +466,37 @@ static int imx_media_probe(struct platform_device *pdev) struct imx_media_dev *imxmd; int ret; - imxmd = devm_kzalloc(dev, sizeof(*imxmd), GFP_KERNEL); - if (!imxmd) - return -ENOMEM; - - dev_set_drvdata(dev, imxmd); - - strscpy(imxmd->md.model, "imx-media", sizeof(imxmd->md.model)); - imxmd->md.ops = &imx_media_md_ops; - imxmd->md.dev = dev; - - mutex_init(&imxmd->mutex); - - imxmd->v4l2_dev.mdev = &imxmd->md; - strscpy(imxmd->v4l2_dev.name, "imx-media", - sizeof(imxmd->v4l2_dev.name)); - - media_device_init(&imxmd->md); - - ret = v4l2_device_register(dev, &imxmd->v4l2_dev); - if (ret < 0) { - v4l2_err(&imxmd->v4l2_dev, - "Failed to register v4l2_device: %d\n", ret); - goto cleanup; - } - - dev_set_drvdata(imxmd->v4l2_dev.dev, imxmd); - - INIT_LIST_HEAD(&imxmd->vdev_list); - - v4l2_async_notifier_init(&imxmd->notifier); + imxmd = imx_media_dev_init(dev); + if (IS_ERR(imxmd)) + return PTR_ERR(imxmd); ret = imx_media_add_of_subdevs(imxmd, node); if (ret) { v4l2_err(&imxmd->v4l2_dev, "add_of_subdevs failed with %d\n", ret); - goto notifier_cleanup; + goto cleanup; } ret = imx_media_add_internal_subdevs(imxmd); if (ret) { v4l2_err(&imxmd->v4l2_dev, "add_internal_subdevs failed with %d\n", ret); - goto notifier_cleanup; - } - - /* no subdevs? just bail */ - if (list_empty(&imxmd->notifier.asd_list)) { - ret = -ENODEV; - goto notifier_cleanup; + goto cleanup; } - /* prepare the async subdev notifier and register it */ - imxmd->notifier.ops = &imx_media_subdev_ops; - ret = v4l2_async_notifier_register(&imxmd->v4l2_dev, - &imxmd->notifier); - if (ret) { - v4l2_err(&imxmd->v4l2_dev, - "v4l2_async_notifier_register failed with %d\n", ret); + ret = imx_media_dev_notifier_register(imxmd); + if (ret) goto del_int; - } return 0; del_int: imx_media_remove_internal_subdevs(imxmd); -notifier_cleanup: +cleanup: v4l2_async_notifier_cleanup(&imxmd->notifier); v4l2_device_unregister(&imxmd->v4l2_dev); -cleanup: media_device_cleanup(&imxmd->md); + return ret; } @@ -532,8 +510,8 @@ static int imx_media_remove(struct platform_device *pdev) v4l2_async_notifier_unregister(&imxmd->notifier); imx_media_remove_internal_subdevs(imxmd); v4l2_async_notifier_cleanup(&imxmd->notifier); - v4l2_device_unregister(&imxmd->v4l2_dev); media_device_unregister(&imxmd->md); + v4l2_device_unregister(&imxmd->v4l2_dev); media_device_cleanup(&imxmd->md); return 0; diff --git a/drivers/staging/media/imx/imx-media-internal-sd.c b/drivers/staging/media/imx/imx-media-internal-sd.c index 0fdc45dbfb76..5e10d95e5529 100644 --- a/drivers/staging/media/imx/imx-media-internal-sd.c +++ b/drivers/staging/media/imx/imx-media-internal-sd.c @@ -30,32 +30,32 @@ static const struct internal_subdev_id { } isd_id[num_isd] = { [isd_csi0] = { .index = isd_csi0, - .grp_id = IMX_MEDIA_GRP_ID_CSI0, + .grp_id = IMX_MEDIA_GRP_ID_IPU_CSI0, .name = "imx-ipuv3-csi", }, [isd_csi1] = { .index = isd_csi1, - .grp_id = IMX_MEDIA_GRP_ID_CSI1, + .grp_id = IMX_MEDIA_GRP_ID_IPU_CSI1, .name = "imx-ipuv3-csi", }, [isd_vdic] = { .index = isd_vdic, - .grp_id = IMX_MEDIA_GRP_ID_VDIC, + .grp_id = IMX_MEDIA_GRP_ID_IPU_VDIC, .name = "imx-ipuv3-vdic", }, [isd_ic_prp] = { .index = isd_ic_prp, - .grp_id = IMX_MEDIA_GRP_ID_IC_PRP, + .grp_id = IMX_MEDIA_GRP_ID_IPU_IC_PRP, .name = "imx-ipuv3-ic", }, [isd_ic_prpenc] = { .index = isd_ic_prpenc, - .grp_id = IMX_MEDIA_GRP_ID_IC_PRPENC, + .grp_id = IMX_MEDIA_GRP_ID_IPU_IC_PRPENC, .name = "imx-ipuv3-ic", }, [isd_ic_prpvf] = { .index = isd_ic_prpvf, - .grp_id = IMX_MEDIA_GRP_ID_IC_PRPVF, + .grp_id = IMX_MEDIA_GRP_ID_IPU_IC_PRPVF, .name = "imx-ipuv3-ic", }, }; @@ -229,8 +229,8 @@ static int create_ipu_internal_link(struct imx_media_dev *imxmd, return ret; } -int imx_media_create_internal_links(struct imx_media_dev *imxmd, - struct v4l2_subdev *sd) +int imx_media_create_ipu_internal_links(struct imx_media_dev *imxmd, + struct v4l2_subdev *sd) { const struct internal_subdev *intsd; const struct internal_pad *intpad; @@ -312,8 +312,8 @@ static int add_ipu_internal_subdevs(struct imx_media_dev *imxmd, int ipu_id) * of_parse_subdev(). */ switch (isd->id->grp_id) { - case IMX_MEDIA_GRP_ID_CSI0: - case IMX_MEDIA_GRP_ID_CSI1: + case IMX_MEDIA_GRP_ID_IPU_CSI0: + case IMX_MEDIA_GRP_ID_IPU_CSI1: ret = 0; break; default: diff --git a/drivers/staging/media/imx/imx-media-of.c b/drivers/staging/media/imx/imx-media-of.c index a01327f6e045..03446335ac03 100644 --- a/drivers/staging/media/imx/imx-media-of.c +++ b/drivers/staging/media/imx/imx-media-of.c @@ -20,7 +20,8 @@ #include <video/imx-ipu-v3.h> #include "imx-media.h" -static int of_add_csi(struct imx_media_dev *imxmd, struct device_node *csi_np) +int imx_media_of_add_csi(struct imx_media_dev *imxmd, + struct device_node *csi_np) { int ret; @@ -45,6 +46,7 @@ static int of_add_csi(struct imx_media_dev *imxmd, struct device_node *csi_np) return 0; } +EXPORT_SYMBOL_GPL(imx_media_of_add_csi); int imx_media_add_of_subdevs(struct imx_media_dev *imxmd, struct device_node *np) @@ -57,7 +59,7 @@ int imx_media_add_of_subdevs(struct imx_media_dev *imxmd, if (!csi_np) break; - ret = of_add_csi(imxmd, csi_np); + ret = imx_media_of_add_csi(imxmd, csi_np); of_node_put(csi_np); if (ret) return ret; diff --git a/drivers/staging/media/imx/imx-media-utils.c b/drivers/staging/media/imx/imx-media-utils.c index 0eaa353d5cb3..1c63a2765a81 100644 --- a/drivers/staging/media/imx/imx-media-utils.c +++ b/drivers/staging/media/imx/imx-media-utils.c @@ -577,9 +577,11 @@ void imx_media_fill_default_mbus_fields(struct v4l2_mbus_framefmt *tryfmt, EXPORT_SYMBOL_GPL(imx_media_fill_default_mbus_fields); int imx_media_mbus_fmt_to_pix_fmt(struct v4l2_pix_format *pix, - struct v4l2_mbus_framefmt *mbus, + struct v4l2_rect *compose, + const struct v4l2_mbus_framefmt *mbus, const struct imx_media_pixfmt *cc) { + u32 width; u32 stride; if (!cc) { @@ -602,9 +604,16 @@ int imx_media_mbus_fmt_to_pix_fmt(struct v4l2_pix_format *pix, cc = imx_media_find_mbus_format(code, CS_SEL_YUV, false); } - stride = cc->planar ? mbus->width : (mbus->width * cc->bpp) >> 3; + /* Round up width for minimum burst size */ + width = round_up(mbus->width, 8); - pix->width = mbus->width; + /* Round up stride for IDMAC line start address alignment */ + if (cc->planar) + stride = round_up(width, 16); + else + stride = round_up((width * cc->bpp) >> 3, 8); + + pix->width = width; pix->height = mbus->height; pix->pixelformat = cc->fourcc; pix->colorspace = mbus->colorspace; @@ -613,7 +622,19 @@ int imx_media_mbus_fmt_to_pix_fmt(struct v4l2_pix_format *pix, pix->quantization = mbus->quantization; pix->field = mbus->field; pix->bytesperline = stride; - pix->sizeimage = (pix->width * pix->height * cc->bpp) >> 3; + pix->sizeimage = cc->planar ? ((stride * pix->height * cc->bpp) >> 3) : + stride * pix->height; + + /* + * set capture compose rectangle, which is fixed to the + * source subdevice mbus format. + */ + if (compose) { + compose->left = 0; + compose->top = 0; + compose->width = mbus->width; + compose->height = mbus->height; + } return 0; } @@ -626,13 +647,11 @@ int imx_media_mbus_fmt_to_ipu_image(struct ipu_image *image, memset(image, 0, sizeof(*image)); - ret = imx_media_mbus_fmt_to_pix_fmt(&image->pix, mbus, NULL); + ret = imx_media_mbus_fmt_to_pix_fmt(&image->pix, &image->rect, + mbus, NULL); if (ret) return ret; - image->rect.width = mbus->width; - image->rect.height = mbus->height; - return 0; } EXPORT_SYMBOL_GPL(imx_media_mbus_fmt_to_ipu_image); @@ -696,20 +715,20 @@ void imx_media_grp_id_to_sd_name(char *sd_name, int sz, u32 grp_id, int ipu_id) int id; switch (grp_id) { - case IMX_MEDIA_GRP_ID_CSI0...IMX_MEDIA_GRP_ID_CSI1: - id = (grp_id >> IMX_MEDIA_GRP_ID_CSI_BIT) - 1; + case IMX_MEDIA_GRP_ID_IPU_CSI0...IMX_MEDIA_GRP_ID_IPU_CSI1: + id = (grp_id >> IMX_MEDIA_GRP_ID_IPU_CSI_BIT) - 1; snprintf(sd_name, sz, "ipu%d_csi%d", ipu_id + 1, id); break; - case IMX_MEDIA_GRP_ID_VDIC: + case IMX_MEDIA_GRP_ID_IPU_VDIC: snprintf(sd_name, sz, "ipu%d_vdic", ipu_id + 1); break; - case IMX_MEDIA_GRP_ID_IC_PRP: + case IMX_MEDIA_GRP_ID_IPU_IC_PRP: snprintf(sd_name, sz, "ipu%d_ic_prp", ipu_id + 1); break; - case IMX_MEDIA_GRP_ID_IC_PRPENC: + case IMX_MEDIA_GRP_ID_IPU_IC_PRPENC: snprintf(sd_name, sz, "ipu%d_ic_prpenc", ipu_id + 1); break; - case IMX_MEDIA_GRP_ID_IC_PRPVF: + case IMX_MEDIA_GRP_ID_IPU_IC_PRPVF: snprintf(sd_name, sz, "ipu%d_ic_prpvf", ipu_id + 1); break; default: diff --git a/drivers/staging/media/imx/imx-media-vdic.c b/drivers/staging/media/imx/imx-media-vdic.c index 482250d47e7c..2808662e2597 100644 --- a/drivers/staging/media/imx/imx-media-vdic.c +++ b/drivers/staging/media/imx/imx-media-vdic.c @@ -219,26 +219,18 @@ static void __maybe_unused prepare_vdi_in_buffers(struct vdic_priv *priv, switch (priv->fieldtype) { case V4L2_FIELD_SEQ_TB: - prev_phys = vb2_dma_contig_plane_dma_addr(prev_vb, 0); - curr_phys = vb2_dma_contig_plane_dma_addr(curr_vb, 0) + fs; - next_phys = vb2_dma_contig_plane_dma_addr(curr_vb, 0); - break; case V4L2_FIELD_SEQ_BT: prev_phys = vb2_dma_contig_plane_dma_addr(prev_vb, 0) + fs; curr_phys = vb2_dma_contig_plane_dma_addr(curr_vb, 0); next_phys = vb2_dma_contig_plane_dma_addr(curr_vb, 0) + fs; break; + case V4L2_FIELD_INTERLACED_TB: case V4L2_FIELD_INTERLACED_BT: + case V4L2_FIELD_INTERLACED: prev_phys = vb2_dma_contig_plane_dma_addr(prev_vb, 0) + is; curr_phys = vb2_dma_contig_plane_dma_addr(curr_vb, 0); next_phys = vb2_dma_contig_plane_dma_addr(curr_vb, 0) + is; break; - default: - /* assume V4L2_FIELD_INTERLACED_TB */ - prev_phys = vb2_dma_contig_plane_dma_addr(prev_vb, 0); - curr_phys = vb2_dma_contig_plane_dma_addr(curr_vb, 0) + is; - next_phys = vb2_dma_contig_plane_dma_addr(curr_vb, 0); - break; } ipu_cpmem_set_buffer(priv->vdi_in_ch_p, 0, prev_phys); @@ -263,10 +255,10 @@ static int setup_vdi_channel(struct vdic_priv *priv, memset(&image, 0, sizeof(image)); image.pix = vdev->fmt.fmt.pix; + image.rect = vdev->compose; /* one field to VDIC channels */ image.pix.height /= 2; - image.rect.width = image.pix.width; - image.rect.height = image.pix.height; + image.rect.height /= 2; image.phys0 = phys0; image.phys1 = phys1; @@ -826,7 +818,10 @@ static int vdic_s_frame_interval(struct v4l2_subdev *sd, switch (fi->pad) { case VDIC_SINK_PAD_DIRECT: case VDIC_SINK_PAD_IDMAC: - /* No limits on input frame interval */ + /* No limits on valid input frame intervals */ + if (fi->interval.numerator == 0 || + fi->interval.denominator == 0) + fi->interval = priv->frame_interval[fi->pad]; /* Reset output interval */ *output_fi = fi->interval; if (priv->csi_direct) diff --git a/drivers/staging/media/imx/imx-media.h b/drivers/staging/media/imx/imx-media.h index bc7feb81937c..ae964c8d5be1 100644 --- a/drivers/staging/media/imx/imx-media.h +++ b/drivers/staging/media/imx/imx-media.h @@ -80,6 +80,8 @@ struct imx_media_video_dev { /* the user format */ struct v4l2_format fmt; + /* the compose rectangle */ + struct v4l2_rect compose; const struct imx_media_pixfmt *cc; /* links this vdev to master list */ @@ -178,7 +180,8 @@ void imx_media_fill_default_mbus_fields(struct v4l2_mbus_framefmt *tryfmt, struct v4l2_mbus_framefmt *fmt, bool ic_route); int imx_media_mbus_fmt_to_pix_fmt(struct v4l2_pix_format *pix, - struct v4l2_mbus_framefmt *mbus, + struct v4l2_rect *compose, + const struct v4l2_mbus_framefmt *mbus, const struct imx_media_pixfmt *cc); int imx_media_mbus_fmt_to_ipu_image(struct ipu_image *image, struct v4l2_mbus_framefmt *mbus); @@ -226,6 +229,18 @@ int imx_media_add_async_subdev(struct imx_media_dev *imxmd, struct fwnode_handle *fwnode, struct platform_device *pdev); +int imx_media_subdev_bound(struct v4l2_async_notifier *notifier, + struct v4l2_subdev *sd, + struct v4l2_async_subdev *asd); +int imx_media_link_notify(struct media_link *link, u32 flags, + unsigned int notification); +void imx_media_notify(struct v4l2_subdev *sd, unsigned int notification, + void *arg); +int imx_media_probe_complete(struct v4l2_async_notifier *notifier); + +struct imx_media_dev *imx_media_dev_init(struct device *dev); +int imx_media_dev_notifier_register(struct imx_media_dev *imxmd); + /* imx-media-fim.c */ struct imx_media_fim; void imx_media_fim_eof_monitor(struct imx_media_fim *fim, ktime_t timestamp); @@ -238,8 +253,8 @@ void imx_media_fim_free(struct imx_media_fim *fim); /* imx-media-internal-sd.c */ int imx_media_add_internal_subdevs(struct imx_media_dev *imxmd); -int imx_media_create_internal_links(struct imx_media_dev *imxmd, - struct v4l2_subdev *sd); +int imx_media_create_ipu_internal_links(struct imx_media_dev *imxmd, + struct v4l2_subdev *sd); void imx_media_remove_internal_subdevs(struct imx_media_dev *imxmd); /* imx-media-of.c */ @@ -249,6 +264,8 @@ int imx_media_create_of_links(struct imx_media_dev *imxmd, struct v4l2_subdev *sd); int imx_media_create_csi_of_links(struct imx_media_dev *imxmd, struct v4l2_subdev *csi); +int imx_media_of_add_csi(struct imx_media_dev *imxmd, + struct device_node *csi_np); /* imx-media-capture.c */ struct imx_media_video_dev * @@ -259,18 +276,20 @@ void imx_media_capture_device_unregister(struct imx_media_video_dev *vdev); struct imx_media_buffer * imx_media_capture_device_next_buf(struct imx_media_video_dev *vdev); void imx_media_capture_device_set_format(struct imx_media_video_dev *vdev, - struct v4l2_pix_format *pix); + const struct v4l2_pix_format *pix, + const struct v4l2_rect *compose); void imx_media_capture_device_error(struct imx_media_video_dev *vdev); /* subdev group ids */ -#define IMX_MEDIA_GRP_ID_CSI2 BIT(8) -#define IMX_MEDIA_GRP_ID_CSI_BIT 9 -#define IMX_MEDIA_GRP_ID_CSI (0x3 << IMX_MEDIA_GRP_ID_CSI_BIT) -#define IMX_MEDIA_GRP_ID_CSI0 BIT(IMX_MEDIA_GRP_ID_CSI_BIT) -#define IMX_MEDIA_GRP_ID_CSI1 (2 << IMX_MEDIA_GRP_ID_CSI_BIT) -#define IMX_MEDIA_GRP_ID_VDIC BIT(11) -#define IMX_MEDIA_GRP_ID_IC_PRP BIT(12) -#define IMX_MEDIA_GRP_ID_IC_PRPENC BIT(13) -#define IMX_MEDIA_GRP_ID_IC_PRPVF BIT(14) +#define IMX_MEDIA_GRP_ID_CSI2 BIT(8) +#define IMX_MEDIA_GRP_ID_CSI BIT(9) +#define IMX_MEDIA_GRP_ID_IPU_CSI_BIT 10 +#define IMX_MEDIA_GRP_ID_IPU_CSI (0x3 << IMX_MEDIA_GRP_ID_IPU_CSI_BIT) +#define IMX_MEDIA_GRP_ID_IPU_CSI0 BIT(IMX_MEDIA_GRP_ID_IPU_CSI_BIT) +#define IMX_MEDIA_GRP_ID_IPU_CSI1 (2 << IMX_MEDIA_GRP_ID_IPU_CSI_BIT) +#define IMX_MEDIA_GRP_ID_IPU_VDIC BIT(12) +#define IMX_MEDIA_GRP_ID_IPU_IC_PRP BIT(13) +#define IMX_MEDIA_GRP_ID_IPU_IC_PRPENC BIT(14) +#define IMX_MEDIA_GRP_ID_IPU_IC_PRPVF BIT(15) #endif diff --git a/drivers/staging/media/imx/imx7-media-csi.c b/drivers/staging/media/imx/imx7-media-csi.c new file mode 100644 index 000000000000..3fba7c27c0ec --- /dev/null +++ b/drivers/staging/media/imx/imx7-media-csi.c @@ -0,0 +1,1369 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * V4L2 Capture CSI Subdev for Freescale i.MX7 SOC + * + * Copyright (c) 2019 Linaro Ltd + * + */ + +#include <linux/clk.h> +#include <linux/delay.h> +#include <linux/gcd.h> +#include <linux/interrupt.h> +#include <linux/mfd/syscon.h> +#include <linux/module.h> +#include <linux/of_graph.h> +#include <linux/pinctrl/consumer.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> +#include <linux/types.h> + +#include <media/v4l2-ctrls.h> +#include <media/v4l2-device.h> +#include <media/v4l2-event.h> +#include <media/v4l2-fwnode.h> +#include <media/v4l2-mc.h> +#include <media/v4l2-subdev.h> +#include <media/videobuf2-dma-contig.h> + +#include <media/imx.h> +#include "imx-media.h" + +#define IMX7_CSI_PAD_SINK 0 +#define IMX7_CSI_PAD_SRC 1 +#define IMX7_CSI_PADS_NUM 2 + +/* reset values */ +#define CSICR1_RESET_VAL 0x40000800 +#define CSICR2_RESET_VAL 0x0 +#define CSICR3_RESET_VAL 0x0 + +/* csi control reg 1 */ +#define BIT_SWAP16_EN BIT(31) +#define BIT_EXT_VSYNC BIT(30) +#define BIT_EOF_INT_EN BIT(29) +#define BIT_PRP_IF_EN BIT(28) +#define BIT_CCIR_MODE BIT(27) +#define BIT_COF_INT_EN BIT(26) +#define BIT_SF_OR_INTEN BIT(25) +#define BIT_RF_OR_INTEN BIT(24) +#define BIT_SFF_DMA_DONE_INTEN BIT(22) +#define BIT_STATFF_INTEN BIT(21) +#define BIT_FB2_DMA_DONE_INTEN BIT(20) +#define BIT_FB1_DMA_DONE_INTEN BIT(19) +#define BIT_RXFF_INTEN BIT(18) +#define BIT_SOF_POL BIT(17) +#define BIT_SOF_INTEN BIT(16) +#define BIT_MCLKDIV (0xF << 12) +#define BIT_HSYNC_POL BIT(11) +#define BIT_CCIR_EN BIT(10) +#define BIT_MCLKEN BIT(9) +#define BIT_FCC BIT(8) +#define BIT_PACK_DIR BIT(7) +#define BIT_CLR_STATFIFO BIT(6) +#define BIT_CLR_RXFIFO BIT(5) +#define BIT_GCLK_MODE BIT(4) +#define BIT_INV_DATA BIT(3) +#define BIT_INV_PCLK BIT(2) +#define BIT_REDGE BIT(1) +#define BIT_PIXEL_BIT BIT(0) + +#define SHIFT_MCLKDIV 12 + +/* control reg 3 */ +#define BIT_FRMCNT (0xFFFF << 16) +#define BIT_FRMCNT_RST BIT(15) +#define BIT_DMA_REFLASH_RFF BIT(14) +#define BIT_DMA_REFLASH_SFF BIT(13) +#define BIT_DMA_REQ_EN_RFF BIT(12) +#define BIT_DMA_REQ_EN_SFF BIT(11) +#define BIT_STATFF_LEVEL (0x7 << 8) +#define BIT_HRESP_ERR_EN BIT(7) +#define BIT_RXFF_LEVEL (0x7 << 4) +#define BIT_TWO_8BIT_SENSOR BIT(3) +#define BIT_ZERO_PACK_EN BIT(2) +#define BIT_ECC_INT_EN BIT(1) +#define BIT_ECC_AUTO_EN BIT(0) + +#define SHIFT_FRMCNT 16 +#define SHIFT_RXFIFO_LEVEL 4 + +/* csi status reg */ +#define BIT_ADDR_CH_ERR_INT BIT(28) +#define BIT_FIELD0_INT BIT(27) +#define BIT_FIELD1_INT BIT(26) +#define BIT_SFF_OR_INT BIT(25) +#define BIT_RFF_OR_INT BIT(24) +#define BIT_DMA_TSF_DONE_SFF BIT(22) +#define BIT_STATFF_INT BIT(21) +#define BIT_DMA_TSF_DONE_FB2 BIT(20) +#define BIT_DMA_TSF_DONE_FB1 BIT(19) +#define BIT_RXFF_INT BIT(18) +#define BIT_EOF_INT BIT(17) +#define BIT_SOF_INT BIT(16) +#define BIT_F2_INT BIT(15) +#define BIT_F1_INT BIT(14) +#define BIT_COF_INT BIT(13) +#define BIT_HRESP_ERR_INT BIT(7) +#define BIT_ECC_INT BIT(1) +#define BIT_DRDY BIT(0) + +/* csi control reg 18 */ +#define BIT_CSI_HW_ENABLE BIT(31) +#define BIT_MIPI_DATA_FORMAT_RAW8 (0x2a << 25) +#define BIT_MIPI_DATA_FORMAT_RAW10 (0x2b << 25) +#define BIT_MIPI_DATA_FORMAT_RAW12 (0x2c << 25) +#define BIT_MIPI_DATA_FORMAT_RAW14 (0x2d << 25) +#define BIT_MIPI_DATA_FORMAT_YUV422_8B (0x1e << 25) +#define BIT_MIPI_DATA_FORMAT_MASK (0x3F << 25) +#define BIT_MIPI_DATA_FORMAT_OFFSET 25 +#define BIT_DATA_FROM_MIPI BIT(22) +#define BIT_MIPI_YU_SWAP BIT(21) +#define BIT_MIPI_DOUBLE_CMPNT BIT(20) +#define BIT_BASEADDR_CHG_ERR_EN BIT(9) +#define BIT_BASEADDR_SWITCH_SEL BIT(5) +#define BIT_BASEADDR_SWITCH_EN BIT(4) +#define BIT_PARALLEL24_EN BIT(3) +#define BIT_DEINTERLACE_EN BIT(2) +#define BIT_TVDECODER_IN_EN BIT(1) +#define BIT_NTSC_EN BIT(0) + +#define CSI_MCLK_VF 1 +#define CSI_MCLK_ENC 2 +#define CSI_MCLK_RAW 4 +#define CSI_MCLK_I2C 8 + +#define CSI_CSICR1 0x0 +#define CSI_CSICR2 0x4 +#define CSI_CSICR3 0x8 +#define CSI_STATFIFO 0xC +#define CSI_CSIRXFIFO 0x10 +#define CSI_CSIRXCNT 0x14 +#define CSI_CSISR 0x18 + +#define CSI_CSIDBG 0x1C +#define CSI_CSIDMASA_STATFIFO 0x20 +#define CSI_CSIDMATS_STATFIFO 0x24 +#define CSI_CSIDMASA_FB1 0x28 +#define CSI_CSIDMASA_FB2 0x2C +#define CSI_CSIFBUF_PARA 0x30 +#define CSI_CSIIMAG_PARA 0x34 + +#define CSI_CSICR18 0x48 +#define CSI_CSICR19 0x4c + +static const char * const imx7_csi_clk_id[] = {"axi", "dcic", "mclk"}; + +struct imx7_csi { + struct device *dev; + struct v4l2_subdev sd; + struct imx_media_video_dev *vdev; + struct imx_media_dev *imxmd; + struct media_pad pad[IMX7_CSI_PADS_NUM]; + + /* lock to protect members below */ + struct mutex lock; + /* lock to protect irq handler when stop streaming */ + spinlock_t irqlock; + + struct v4l2_subdev *src_sd; + + struct media_entity *sink; + + struct v4l2_fwnode_endpoint upstream_ep; + + struct v4l2_mbus_framefmt format_mbus[IMX7_CSI_PADS_NUM]; + const struct imx_media_pixfmt *cc[IMX7_CSI_PADS_NUM]; + struct v4l2_fract frame_interval[IMX7_CSI_PADS_NUM]; + + struct v4l2_ctrl_handler ctrl_hdlr; + + void __iomem *regbase; + int irq; + + int num_clks; + struct clk_bulk_data *clks; + + /* active vb2 buffers to send to video dev sink */ + struct imx_media_buffer *active_vb2_buf[2]; + struct imx_media_dma_buf underrun_buf; + + int buf_num; + u32 frame_sequence; + + bool last_eof; + bool is_init; + bool is_streaming; + bool is_csi2; + + struct completion last_eof_completion; +}; + +#define imx7_csi_reg_read(_csi, _offset) \ + __raw_readl((_csi)->regbase + (_offset)) +#define imx7_csi_reg_write(_csi, _val, _offset) \ + __raw_writel(_val, (_csi)->regbase + (_offset)) + +static void imx7_csi_clk_enable(struct imx7_csi *csi) +{ + int ret; + + ret = clk_bulk_prepare_enable(csi->num_clks, csi->clks); + if (ret < 0) + dev_err(csi->dev, "failed to enable clocks\n"); +} + +static void imx7_csi_clk_disable(struct imx7_csi *csi) +{ + clk_bulk_disable_unprepare(csi->num_clks, csi->clks); +} + +static void imx7_csi_hw_reset(struct imx7_csi *csi) +{ + imx7_csi_reg_write(csi, + imx7_csi_reg_read(csi, CSI_CSICR3) | BIT_FRMCNT_RST, + CSI_CSICR3); + + imx7_csi_reg_write(csi, CSICR1_RESET_VAL, CSI_CSICR1); + imx7_csi_reg_write(csi, CSICR2_RESET_VAL, CSI_CSICR2); + imx7_csi_reg_write(csi, CSICR3_RESET_VAL, CSI_CSICR3); +} + +static unsigned long imx7_csi_irq_clear(struct imx7_csi *csi) +{ + unsigned long isr; + + isr = imx7_csi_reg_read(csi, CSI_CSISR); + imx7_csi_reg_write(csi, isr, CSI_CSISR); + + return isr; +} + +static void imx7_csi_init_interface(struct imx7_csi *csi) +{ + unsigned int val = 0; + unsigned int imag_para; + + val = BIT_SOF_POL | BIT_REDGE | BIT_GCLK_MODE | BIT_HSYNC_POL | + BIT_FCC | 1 << SHIFT_MCLKDIV | BIT_MCLKEN; + imx7_csi_reg_write(csi, val, CSI_CSICR1); + + imag_para = (800 << 16) | 600; + imx7_csi_reg_write(csi, imag_para, CSI_CSIIMAG_PARA); + + val = BIT_DMA_REFLASH_RFF; + imx7_csi_reg_write(csi, val, CSI_CSICR3); +} + +static void imx7_csi_hw_enable_irq(struct imx7_csi *csi) +{ + unsigned long cr1 = imx7_csi_reg_read(csi, CSI_CSICR1); + + cr1 |= BIT_SOF_INTEN; + cr1 |= BIT_RFF_OR_INT; + + /* still capture needs DMA interrupt */ + cr1 |= BIT_FB1_DMA_DONE_INTEN; + cr1 |= BIT_FB2_DMA_DONE_INTEN; + + cr1 |= BIT_EOF_INT_EN; + + imx7_csi_reg_write(csi, cr1, CSI_CSICR1); +} + +static void imx7_csi_hw_disable_irq(struct imx7_csi *csi) +{ + unsigned long cr1 = imx7_csi_reg_read(csi, CSI_CSICR1); + + cr1 &= ~BIT_SOF_INTEN; + cr1 &= ~BIT_RFF_OR_INT; + cr1 &= ~BIT_FB1_DMA_DONE_INTEN; + cr1 &= ~BIT_FB2_DMA_DONE_INTEN; + cr1 &= ~BIT_EOF_INT_EN; + + imx7_csi_reg_write(csi, cr1, CSI_CSICR1); +} + +static void imx7_csi_hw_enable(struct imx7_csi *csi) +{ + unsigned long cr = imx7_csi_reg_read(csi, CSI_CSICR18); + + cr |= BIT_CSI_HW_ENABLE; + + imx7_csi_reg_write(csi, cr, CSI_CSICR18); +} + +static void imx7_csi_hw_disable(struct imx7_csi *csi) +{ + unsigned long cr = imx7_csi_reg_read(csi, CSI_CSICR18); + + cr &= ~BIT_CSI_HW_ENABLE; + + imx7_csi_reg_write(csi, cr, CSI_CSICR18); +} + +static void imx7_csi_dma_reflash(struct imx7_csi *csi) +{ + unsigned long cr3 = imx7_csi_reg_read(csi, CSI_CSICR18); + + cr3 = imx7_csi_reg_read(csi, CSI_CSICR3); + cr3 |= BIT_DMA_REFLASH_RFF; + imx7_csi_reg_write(csi, cr3, CSI_CSICR3); +} + +static void imx7_csi_rx_fifo_clear(struct imx7_csi *csi) +{ + unsigned long cr1; + + cr1 = imx7_csi_reg_read(csi, CSI_CSICR1); + imx7_csi_reg_write(csi, cr1 & ~BIT_FCC, CSI_CSICR1); + cr1 = imx7_csi_reg_read(csi, CSI_CSICR1); + imx7_csi_reg_write(csi, cr1 | BIT_CLR_RXFIFO, CSI_CSICR1); + + cr1 = imx7_csi_reg_read(csi, CSI_CSICR1); + imx7_csi_reg_write(csi, cr1 | BIT_FCC, CSI_CSICR1); +} + +static void imx7_csi_buf_stride_set(struct imx7_csi *csi, u32 stride) +{ + imx7_csi_reg_write(csi, stride, CSI_CSIFBUF_PARA); +} + +static void imx7_csi_deinterlace_enable(struct imx7_csi *csi, bool enable) +{ + unsigned long cr18 = imx7_csi_reg_read(csi, CSI_CSICR18); + + if (enable) + cr18 |= BIT_DEINTERLACE_EN; + else + cr18 &= ~BIT_DEINTERLACE_EN; + + imx7_csi_reg_write(csi, cr18, CSI_CSICR18); +} + +static void imx7_csi_dmareq_rff_enable(struct imx7_csi *csi) +{ + unsigned long cr3 = imx7_csi_reg_read(csi, CSI_CSICR3); + unsigned long cr2 = imx7_csi_reg_read(csi, CSI_CSICR2); + + /* Burst Type of DMA Transfer from RxFIFO. INCR16 */ + cr2 |= 0xC0000000; + + cr3 |= BIT_DMA_REQ_EN_RFF; + cr3 |= BIT_HRESP_ERR_EN; + cr3 &= ~BIT_RXFF_LEVEL; + cr3 |= 0x2 << 4; + + imx7_csi_reg_write(csi, cr3, CSI_CSICR3); + imx7_csi_reg_write(csi, cr2, CSI_CSICR2); +} + +static void imx7_csi_dmareq_rff_disable(struct imx7_csi *csi) +{ + unsigned long cr3 = imx7_csi_reg_read(csi, CSI_CSICR3); + + cr3 &= ~BIT_DMA_REQ_EN_RFF; + cr3 &= ~BIT_HRESP_ERR_EN; + imx7_csi_reg_write(csi, cr3, CSI_CSICR3); +} + +static void imx7_csi_set_imagpara(struct imx7_csi *csi, int width, int height) +{ + int imag_para; + int rx_count; + + rx_count = (width * height) >> 2; + imx7_csi_reg_write(csi, rx_count, CSI_CSIRXCNT); + + imag_para = (width << 16) | height; + imx7_csi_reg_write(csi, imag_para, CSI_CSIIMAG_PARA); + + /* reflash the embedded DMA controller */ + imx7_csi_dma_reflash(csi); +} + +static void imx7_csi_sw_reset(struct imx7_csi *csi) +{ + imx7_csi_hw_disable(csi); + + imx7_csi_rx_fifo_clear(csi); + + imx7_csi_dma_reflash(csi); + + usleep_range(2000, 3000); + + imx7_csi_irq_clear(csi); + + imx7_csi_hw_enable(csi); +} + +static void imx7_csi_error_recovery(struct imx7_csi *csi) +{ + imx7_csi_hw_disable(csi); + + imx7_csi_rx_fifo_clear(csi); + + imx7_csi_dma_reflash(csi); + + imx7_csi_hw_enable(csi); +} + +static void imx7_csi_init(struct imx7_csi *csi) +{ + if (csi->is_init) + return; + + imx7_csi_clk_enable(csi); + imx7_csi_hw_reset(csi); + imx7_csi_init_interface(csi); + imx7_csi_dmareq_rff_enable(csi); + + csi->is_init = true; +} + +static void imx7_csi_deinit(struct imx7_csi *csi) +{ + if (!csi->is_init) + return; + + imx7_csi_hw_reset(csi); + imx7_csi_init_interface(csi); + imx7_csi_dmareq_rff_disable(csi); + imx7_csi_clk_disable(csi); + + csi->is_init = false; +} + +static int imx7_csi_get_upstream_endpoint(struct imx7_csi *csi, + struct v4l2_fwnode_endpoint *ep, + bool skip_mux) +{ + struct device_node *endpoint, *port; + struct media_entity *src; + struct v4l2_subdev *sd; + struct media_pad *pad; + + if (!csi->src_sd) + return -EPIPE; + + src = &csi->src_sd->entity; + +skip_video_mux: + /* get source pad of entity directly upstream from src */ + pad = imx_media_find_upstream_pad(csi->imxmd, src, 0); + if (IS_ERR(pad)) + return PTR_ERR(pad); + + sd = media_entity_to_v4l2_subdev(pad->entity); + + /* To get bus type we may need to skip video mux */ + if (skip_mux && src->function == MEDIA_ENT_F_VID_MUX) { + src = &sd->entity; + goto skip_video_mux; + } + + /* + * NOTE: this assumes an OF-graph port id is the same as a + * media pad index. + */ + port = of_graph_get_port_by_id(sd->dev->of_node, pad->index); + if (!port) + return -ENODEV; + + endpoint = of_get_next_child(port, NULL); + of_node_put(port); + if (!endpoint) + return -ENODEV; + + v4l2_fwnode_endpoint_parse(of_fwnode_handle(endpoint), ep); + of_node_put(endpoint); + + return 0; +} + +static int imx7_csi_link_setup(struct media_entity *entity, + const struct media_pad *local, + const struct media_pad *remote, u32 flags) +{ + struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity); + struct imx7_csi *csi = v4l2_get_subdevdata(sd); + struct v4l2_subdev *remote_sd; + int ret = 0; + + dev_dbg(csi->dev, "link setup %s -> %s\n", remote->entity->name, + local->entity->name); + + mutex_lock(&csi->lock); + + if (local->flags & MEDIA_PAD_FL_SINK) { + if (!is_media_entity_v4l2_subdev(remote->entity)) { + ret = -EINVAL; + goto unlock; + } + + remote_sd = media_entity_to_v4l2_subdev(remote->entity); + + if (flags & MEDIA_LNK_FL_ENABLED) { + if (csi->src_sd) { + ret = -EBUSY; + goto unlock; + } + csi->src_sd = remote_sd; + } else { + csi->src_sd = NULL; + } + + goto init; + } + + /* source pad */ + if (flags & MEDIA_LNK_FL_ENABLED) { + if (csi->sink) { + ret = -EBUSY; + goto unlock; + } + csi->sink = remote->entity; + } else { + v4l2_ctrl_handler_free(&csi->ctrl_hdlr); + v4l2_ctrl_handler_init(&csi->ctrl_hdlr, 0); + csi->sink = NULL; + } + +init: + if (csi->sink || csi->src_sd) + imx7_csi_init(csi); + else + imx7_csi_deinit(csi); + +unlock: + mutex_unlock(&csi->lock); + + return ret; +} + +static int imx7_csi_pad_link_validate(struct v4l2_subdev *sd, + struct media_link *link, + struct v4l2_subdev_format *source_fmt, + struct v4l2_subdev_format *sink_fmt) +{ + struct imx7_csi *csi = v4l2_get_subdevdata(sd); + struct v4l2_fwnode_endpoint upstream_ep = {}; + int ret; + + ret = v4l2_subdev_link_validate_default(sd, link, source_fmt, sink_fmt); + if (ret) + return ret; + + ret = imx7_csi_get_upstream_endpoint(csi, &upstream_ep, true); + if (ret) { + v4l2_err(&csi->sd, "failed to find upstream endpoint\n"); + return ret; + } + + mutex_lock(&csi->lock); + + csi->upstream_ep = upstream_ep; + csi->is_csi2 = (upstream_ep.bus_type == V4L2_MBUS_CSI2_DPHY); + + mutex_unlock(&csi->lock); + + return 0; +} + +static void imx7_csi_update_buf(struct imx7_csi *csi, dma_addr_t phys, + int buf_num) +{ + if (buf_num == 1) + imx7_csi_reg_write(csi, phys, CSI_CSIDMASA_FB2); + else + imx7_csi_reg_write(csi, phys, CSI_CSIDMASA_FB1); +} + +static void imx7_csi_setup_vb2_buf(struct imx7_csi *csi) +{ + struct imx_media_video_dev *vdev = csi->vdev; + struct imx_media_buffer *buf; + struct vb2_buffer *vb2_buf; + dma_addr_t phys[2]; + int i; + + for (i = 0; i < 2; i++) { + buf = imx_media_capture_device_next_buf(vdev); + if (buf) { + csi->active_vb2_buf[i] = buf; + vb2_buf = &buf->vbuf.vb2_buf; + phys[i] = vb2_dma_contig_plane_dma_addr(vb2_buf, 0); + } else { + csi->active_vb2_buf[i] = NULL; + phys[i] = csi->underrun_buf.phys; + } + + imx7_csi_update_buf(csi, phys[i], i); + } +} + +static void imx7_csi_dma_unsetup_vb2_buf(struct imx7_csi *csi, + enum vb2_buffer_state return_status) +{ + struct imx_media_buffer *buf; + int i; + + /* return any remaining active frames with return_status */ + for (i = 0; i < 2; i++) { + buf = csi->active_vb2_buf[i]; + if (buf) { + struct vb2_buffer *vb = &buf->vbuf.vb2_buf; + + vb->timestamp = ktime_get_ns(); + vb2_buffer_done(vb, return_status); + } + } +} + +static void imx7_csi_vb2_buf_done(struct imx7_csi *csi) +{ + struct imx_media_video_dev *vdev = csi->vdev; + struct imx_media_buffer *done, *next; + struct vb2_buffer *vb; + dma_addr_t phys; + + done = csi->active_vb2_buf[csi->buf_num]; + if (done) { + done->vbuf.field = vdev->fmt.fmt.pix.field; + done->vbuf.sequence = csi->frame_sequence; + vb = &done->vbuf.vb2_buf; + vb->timestamp = ktime_get_ns(); + vb2_buffer_done(vb, VB2_BUF_STATE_DONE); + } + csi->frame_sequence++; + + /* get next queued buffer */ + next = imx_media_capture_device_next_buf(vdev); + if (next) { + phys = vb2_dma_contig_plane_dma_addr(&next->vbuf.vb2_buf, 0); + csi->active_vb2_buf[csi->buf_num] = next; + } else { + phys = csi->underrun_buf.phys; + csi->active_vb2_buf[csi->buf_num] = NULL; + } + + imx7_csi_update_buf(csi, phys, csi->buf_num); +} + +static irqreturn_t imx7_csi_irq_handler(int irq, void *data) +{ + struct imx7_csi *csi = data; + unsigned long status; + + spin_lock(&csi->irqlock); + + status = imx7_csi_irq_clear(csi); + + if (status & BIT_RFF_OR_INT) { + dev_warn(csi->dev, "Rx fifo overflow\n"); + imx7_csi_error_recovery(csi); + } + + if (status & BIT_HRESP_ERR_INT) { + dev_warn(csi->dev, "Hresponse error detected\n"); + imx7_csi_error_recovery(csi); + } + + if (status & BIT_ADDR_CH_ERR_INT) { + imx7_csi_hw_disable(csi); + + imx7_csi_dma_reflash(csi); + + imx7_csi_hw_enable(csi); + } + + if ((status & BIT_DMA_TSF_DONE_FB1) && + (status & BIT_DMA_TSF_DONE_FB2)) { + /* + * For both FB1 and FB2 interrupter bits set case, + * CSI DMA is work in one of FB1 and FB2 buffer, + * but software can not know the state. + * Skip it to avoid base address updated + * when csi work in field0 and field1 will write to + * new base address. + */ + } else if (status & BIT_DMA_TSF_DONE_FB1) { + csi->buf_num = 0; + } else if (status & BIT_DMA_TSF_DONE_FB2) { + csi->buf_num = 1; + } + + if ((status & BIT_DMA_TSF_DONE_FB1) || + (status & BIT_DMA_TSF_DONE_FB2)) { + imx7_csi_vb2_buf_done(csi); + + if (csi->last_eof) { + complete(&csi->last_eof_completion); + csi->last_eof = false; + } + } + + spin_unlock(&csi->irqlock); + + return IRQ_HANDLED; +} + +static int imx7_csi_dma_start(struct imx7_csi *csi) +{ + struct imx_media_video_dev *vdev = csi->vdev; + struct v4l2_pix_format *out_pix = &vdev->fmt.fmt.pix; + int ret; + + ret = imx_media_alloc_dma_buf(csi->imxmd, &csi->underrun_buf, + out_pix->sizeimage); + if (ret < 0) { + v4l2_warn(&csi->sd, "consider increasing the CMA area\n"); + return ret; + } + + csi->frame_sequence = 0; + csi->last_eof = false; + init_completion(&csi->last_eof_completion); + + imx7_csi_setup_vb2_buf(csi); + + return 0; +} + +static void imx7_csi_dma_stop(struct imx7_csi *csi) +{ + unsigned long timeout_jiffies; + unsigned long flags; + int ret; + + /* mark next EOF interrupt as the last before stream off */ + spin_lock_irqsave(&csi->irqlock, flags); + csi->last_eof = true; + spin_unlock_irqrestore(&csi->irqlock, flags); + + /* + * and then wait for interrupt handler to mark completion. + */ + timeout_jiffies = msecs_to_jiffies(IMX_MEDIA_EOF_TIMEOUT); + ret = wait_for_completion_timeout(&csi->last_eof_completion, + timeout_jiffies); + if (ret == 0) + v4l2_warn(&csi->sd, "wait last EOF timeout\n"); + + imx7_csi_hw_disable_irq(csi); + + imx7_csi_dma_unsetup_vb2_buf(csi, VB2_BUF_STATE_ERROR); + + imx_media_free_dma_buf(csi->imxmd, &csi->underrun_buf); +} + +static int imx7_csi_configure(struct imx7_csi *csi) +{ + struct imx_media_video_dev *vdev = csi->vdev; + struct v4l2_pix_format *out_pix = &vdev->fmt.fmt.pix; + __u32 in_code = csi->format_mbus[IMX7_CSI_PAD_SINK].code; + u32 cr1, cr18; + + if (out_pix->field == V4L2_FIELD_INTERLACED) { + imx7_csi_deinterlace_enable(csi, true); + imx7_csi_buf_stride_set(csi, out_pix->width); + } else { + imx7_csi_deinterlace_enable(csi, false); + imx7_csi_buf_stride_set(csi, 0); + } + + imx7_csi_set_imagpara(csi, out_pix->width, out_pix->height); + + if (!csi->is_csi2) + return 0; + + cr1 = imx7_csi_reg_read(csi, CSI_CSICR1); + cr1 &= ~BIT_GCLK_MODE; + + cr18 = imx7_csi_reg_read(csi, CSI_CSICR18); + cr18 &= BIT_MIPI_DATA_FORMAT_MASK; + cr18 |= BIT_DATA_FROM_MIPI; + + switch (out_pix->pixelformat) { + case V4L2_PIX_FMT_UYVY: + case V4L2_PIX_FMT_YUYV: + cr18 |= BIT_MIPI_DATA_FORMAT_YUV422_8B; + break; + case V4L2_PIX_FMT_SBGGR8: + cr18 |= BIT_MIPI_DATA_FORMAT_RAW8; + break; + case V4L2_PIX_FMT_SBGGR16: + if (in_code == MEDIA_BUS_FMT_SBGGR10_1X10) + cr18 |= BIT_MIPI_DATA_FORMAT_RAW10; + else if (in_code == MEDIA_BUS_FMT_SBGGR12_1X12) + cr18 |= BIT_MIPI_DATA_FORMAT_RAW12; + else if (in_code == MEDIA_BUS_FMT_SBGGR14_1X14) + cr18 |= BIT_MIPI_DATA_FORMAT_RAW14; + cr1 |= BIT_PIXEL_BIT; + break; + default: + return -EINVAL; + } + + imx7_csi_reg_write(csi, cr1, CSI_CSICR1); + imx7_csi_reg_write(csi, cr18, CSI_CSICR18); + + return 0; +} + +static int imx7_csi_enable(struct imx7_csi *csi) +{ + imx7_csi_sw_reset(csi); + + if (csi->is_csi2) { + imx7_csi_dmareq_rff_enable(csi); + imx7_csi_hw_enable_irq(csi); + imx7_csi_hw_enable(csi); + return 0; + } + + return 0; +} + +static void imx7_csi_disable(struct imx7_csi *csi) +{ + imx7_csi_dmareq_rff_disable(csi); + + imx7_csi_hw_disable_irq(csi); + + imx7_csi_buf_stride_set(csi, 0); + + imx7_csi_hw_disable(csi); +} + +static int imx7_csi_streaming_start(struct imx7_csi *csi) +{ + int ret; + + ret = imx7_csi_dma_start(csi); + if (ret < 0) + return ret; + + ret = imx7_csi_configure(csi); + if (ret < 0) + goto dma_stop; + + imx7_csi_enable(csi); + + return 0; + +dma_stop: + imx7_csi_dma_stop(csi); + + return ret; +} + +static int imx7_csi_streaming_stop(struct imx7_csi *csi) +{ + imx7_csi_dma_stop(csi); + + imx7_csi_disable(csi); + + return 0; +} + +static int imx7_csi_s_stream(struct v4l2_subdev *sd, int enable) +{ + struct imx7_csi *csi = v4l2_get_subdevdata(sd); + int ret = 0; + + mutex_lock(&csi->lock); + + if (!csi->src_sd || !csi->sink) { + ret = -EPIPE; + goto out_unlock; + } + + if (csi->is_streaming == !!enable) + goto out_unlock; + + if (enable) { + ret = v4l2_subdev_call(csi->src_sd, video, s_stream, 1); + if (ret < 0) + goto out_unlock; + + ret = imx7_csi_streaming_start(csi); + if (ret < 0) { + v4l2_subdev_call(csi->src_sd, video, s_stream, 0); + goto out_unlock; + } + } else { + imx7_csi_streaming_stop(csi); + + v4l2_subdev_call(csi->src_sd, video, s_stream, 0); + } + + csi->is_streaming = !!enable; + +out_unlock: + mutex_unlock(&csi->lock); + + return ret; +} + +static struct v4l2_mbus_framefmt * +imx7_csi_get_format(struct imx7_csi *csi, + struct v4l2_subdev_pad_config *cfg, + unsigned int pad, + enum v4l2_subdev_format_whence which) +{ + if (which == V4L2_SUBDEV_FORMAT_TRY) + return v4l2_subdev_get_try_format(&csi->sd, cfg, pad); + + return &csi->format_mbus[pad]; +} + +static int imx7_csi_enum_mbus_code(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_mbus_code_enum *code) +{ + struct imx7_csi *csi = v4l2_get_subdevdata(sd); + struct v4l2_mbus_framefmt *in_fmt; + int ret = 0; + + mutex_lock(&csi->lock); + + in_fmt = imx7_csi_get_format(csi, cfg, IMX7_CSI_PAD_SINK, code->which); + + switch (code->pad) { + case IMX7_CSI_PAD_SINK: + ret = imx_media_enum_mbus_format(&code->code, code->index, + CS_SEL_ANY, true); + break; + case IMX7_CSI_PAD_SRC: + if (code->index != 0) { + ret = -EINVAL; + goto out_unlock; + } + + code->code = in_fmt->code; + break; + default: + ret = -EINVAL; + } + +out_unlock: + mutex_unlock(&csi->lock); + + return ret; +} + +static int imx7_csi_get_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *sdformat) +{ + struct imx7_csi *csi = v4l2_get_subdevdata(sd); + struct v4l2_mbus_framefmt *fmt; + int ret = 0; + + mutex_lock(&csi->lock); + + fmt = imx7_csi_get_format(csi, cfg, sdformat->pad, sdformat->which); + if (!fmt) { + ret = -EINVAL; + goto out_unlock; + } + + sdformat->format = *fmt; + +out_unlock: + mutex_unlock(&csi->lock); + + return ret; +} + +static int imx7_csi_try_fmt(struct imx7_csi *csi, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *sdformat, + const struct imx_media_pixfmt **cc) +{ + const struct imx_media_pixfmt *in_cc; + struct v4l2_mbus_framefmt *in_fmt; + u32 code; + + in_fmt = imx7_csi_get_format(csi, cfg, IMX7_CSI_PAD_SINK, + sdformat->which); + if (!in_fmt) + return -EINVAL; + + switch (sdformat->pad) { + case IMX7_CSI_PAD_SRC: + in_cc = imx_media_find_mbus_format(in_fmt->code, CS_SEL_ANY, + true); + + sdformat->format.width = in_fmt->width; + sdformat->format.height = in_fmt->height; + sdformat->format.code = in_fmt->code; + *cc = in_cc; + + sdformat->format.colorspace = in_fmt->colorspace; + sdformat->format.xfer_func = in_fmt->xfer_func; + sdformat->format.quantization = in_fmt->quantization; + sdformat->format.ycbcr_enc = in_fmt->ycbcr_enc; + break; + case IMX7_CSI_PAD_SINK: + *cc = imx_media_find_mbus_format(sdformat->format.code, + CS_SEL_ANY, true); + if (!*cc) { + imx_media_enum_mbus_format(&code, 0, CS_SEL_ANY, false); + *cc = imx_media_find_mbus_format(code, CS_SEL_ANY, + false); + sdformat->format.code = (*cc)->codes[0]; + } + + imx_media_fill_default_mbus_fields(&sdformat->format, in_fmt, + false); + break; + default: + return -EINVAL; + break; + } + return 0; +} + +static int imx7_csi_set_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *sdformat) +{ + struct imx7_csi *csi = v4l2_get_subdevdata(sd); + struct imx_media_video_dev *vdev = csi->vdev; + const struct imx_media_pixfmt *outcc; + struct v4l2_mbus_framefmt *outfmt; + struct v4l2_pix_format vdev_fmt; + struct v4l2_rect vdev_compose; + const struct imx_media_pixfmt *cc; + struct v4l2_mbus_framefmt *fmt; + struct v4l2_subdev_format format; + int ret = 0; + + if (sdformat->pad >= IMX7_CSI_PADS_NUM) + return -EINVAL; + + mutex_lock(&csi->lock); + + if (csi->is_streaming) { + ret = -EBUSY; + goto out_unlock; + } + + imx7_csi_try_fmt(csi, cfg, sdformat, &cc); + + fmt = imx7_csi_get_format(csi, cfg, sdformat->pad, sdformat->which); + if (!fmt) { + ret = -EINVAL; + goto out_unlock; + } + + *fmt = sdformat->format; + + if (sdformat->pad == IMX7_CSI_PAD_SINK) { + /* propagate format to source pads */ + format.pad = IMX7_CSI_PAD_SRC; + format.which = sdformat->which; + format.format = sdformat->format; + if (imx7_csi_try_fmt(csi, cfg, &format, &outcc)) { + ret = -EINVAL; + goto out_unlock; + } + outfmt = imx7_csi_get_format(csi, cfg, IMX7_CSI_PAD_SRC, + sdformat->which); + *outfmt = format.format; + + if (sdformat->which == V4L2_SUBDEV_FORMAT_ACTIVE) + csi->cc[IMX7_CSI_PAD_SRC] = outcc; + } + + if (sdformat->which == V4L2_SUBDEV_FORMAT_TRY) + goto out_unlock; + + csi->cc[sdformat->pad] = cc; + + /* propagate output pad format to capture device */ + imx_media_mbus_fmt_to_pix_fmt(&vdev_fmt, &vdev_compose, + &csi->format_mbus[IMX7_CSI_PAD_SRC], + csi->cc[IMX7_CSI_PAD_SRC]); + mutex_unlock(&csi->lock); + imx_media_capture_device_set_format(vdev, &vdev_fmt, &vdev_compose); + + return 0; + +out_unlock: + mutex_unlock(&csi->lock); + + return ret; +} + +static int imx7_csi_registered(struct v4l2_subdev *sd) +{ + struct imx7_csi *csi = v4l2_get_subdevdata(sd); + int ret; + int i; + + for (i = 0; i < IMX7_CSI_PADS_NUM; i++) { + csi->pad[i].flags = (i == IMX7_CSI_PAD_SINK) ? + MEDIA_PAD_FL_SINK : MEDIA_PAD_FL_SOURCE; + + /* set a default mbus format */ + ret = imx_media_init_mbus_fmt(&csi->format_mbus[i], + 800, 600, 0, V4L2_FIELD_NONE, + &csi->cc[i]); + if (ret < 0) + return ret; + + /* init default frame interval */ + csi->frame_interval[i].numerator = 1; + csi->frame_interval[i].denominator = 30; + } + + ret = media_entity_pads_init(&sd->entity, IMX7_CSI_PADS_NUM, csi->pad); + if (ret < 0) + return ret; + + ret = imx_media_capture_device_register(csi->vdev); + if (ret < 0) + return ret; + + ret = imx_media_add_video_device(csi->imxmd, csi->vdev); + if (ret < 0) { + imx_media_capture_device_unregister(csi->vdev); + return ret; + } + + return 0; +} + +static void imx7_csi_unregistered(struct v4l2_subdev *sd) +{ + struct imx7_csi *csi = v4l2_get_subdevdata(sd); + + imx_media_capture_device_unregister(csi->vdev); +} + +static int imx7_csi_init_cfg(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg) +{ + struct imx7_csi *csi = v4l2_get_subdevdata(sd); + struct v4l2_mbus_framefmt *mf; + int ret; + int i; + + for (i = 0; i < IMX7_CSI_PADS_NUM; i++) { + mf = v4l2_subdev_get_try_format(sd, cfg, i); + + ret = imx_media_init_mbus_fmt(mf, 800, 600, 0, V4L2_FIELD_NONE, + &csi->cc[i]); + if (ret < 0) + return ret; + } + + return 0; +} + +static const struct media_entity_operations imx7_csi_entity_ops = { + .link_setup = imx7_csi_link_setup, + .link_validate = v4l2_subdev_link_validate, +}; + +static const struct v4l2_subdev_video_ops imx7_csi_video_ops = { + .s_stream = imx7_csi_s_stream, +}; + +static const struct v4l2_subdev_pad_ops imx7_csi_pad_ops = { + .init_cfg = imx7_csi_init_cfg, + .enum_mbus_code = imx7_csi_enum_mbus_code, + .get_fmt = imx7_csi_get_fmt, + .set_fmt = imx7_csi_set_fmt, + .link_validate = imx7_csi_pad_link_validate, +}; + +static const struct v4l2_subdev_ops imx7_csi_subdev_ops = { + .video = &imx7_csi_video_ops, + .pad = &imx7_csi_pad_ops, +}; + +static const struct v4l2_subdev_internal_ops imx7_csi_internal_ops = { + .registered = imx7_csi_registered, + .unregistered = imx7_csi_unregistered, +}; + +static int imx7_csi_parse_endpoint(struct device *dev, + struct v4l2_fwnode_endpoint *vep, + struct v4l2_async_subdev *asd) +{ + return fwnode_device_is_available(asd->match.fwnode) ? 0 : -EINVAL; +} + +static int imx7_csi_clocks_get(struct imx7_csi *csi) +{ + struct device *dev = csi->dev; + int i; + + csi->num_clks = ARRAY_SIZE(imx7_csi_clk_id); + csi->clks = devm_kcalloc(dev, csi->num_clks, sizeof(*csi->clks), + GFP_KERNEL); + + if (!csi->clks) + return -ENOMEM; + + for (i = 0; i < csi->num_clks; i++) + csi->clks[i].id = imx7_csi_clk_id[i]; + + return devm_clk_bulk_get(dev, csi->num_clks, csi->clks); +} + +static int imx7_csi_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *node = dev->of_node; + struct imx_media_dev *imxmd; + struct imx7_csi *csi; + struct resource *res; + int ret; + + csi = devm_kzalloc(&pdev->dev, sizeof(*csi), GFP_KERNEL); + if (!csi) + return -ENOMEM; + + csi->dev = dev; + + ret = imx7_csi_clocks_get(csi); + if (ret < 0) { + dev_err(dev, "Failed to get clocks"); + return -ENODEV; + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + csi->irq = platform_get_irq(pdev, 0); + if (!res || csi->irq < 0) { + dev_err(dev, "Missing platform resources data\n"); + return -ENODEV; + } + + csi->regbase = devm_ioremap_resource(dev, res); + if (IS_ERR(csi->regbase)) { + dev_err(dev, "Failed platform resources map\n"); + return -ENODEV; + } + + spin_lock_init(&csi->irqlock); + mutex_init(&csi->lock); + + /* install interrupt handler */ + ret = devm_request_irq(dev, csi->irq, imx7_csi_irq_handler, 0, "csi", + (void *)csi); + if (ret < 0) { + dev_err(dev, "Request CSI IRQ failed.\n"); + ret = -ENODEV; + goto destroy_mutex; + } + + /* add media device */ + imxmd = imx_media_dev_init(dev); + if (IS_ERR(imxmd)) { + ret = PTR_ERR(imxmd); + goto destroy_mutex; + } + platform_set_drvdata(pdev, &csi->sd); + + ret = imx_media_of_add_csi(imxmd, node); + if (ret < 0) + goto cleanup; + + ret = imx_media_dev_notifier_register(imxmd); + if (ret < 0) + goto cleanup; + + csi->imxmd = imxmd; + v4l2_subdev_init(&csi->sd, &imx7_csi_subdev_ops); + v4l2_set_subdevdata(&csi->sd, csi); + csi->sd.internal_ops = &imx7_csi_internal_ops; + csi->sd.entity.ops = &imx7_csi_entity_ops; + csi->sd.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE; + csi->sd.dev = &pdev->dev; + csi->sd.owner = THIS_MODULE; + csi->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE; + csi->sd.grp_id = IMX_MEDIA_GRP_ID_CSI; + snprintf(csi->sd.name, sizeof(csi->sd.name), "csi"); + + csi->vdev = imx_media_capture_device_init(&csi->sd, IMX7_CSI_PAD_SRC); + if (IS_ERR(csi->vdev)) + return PTR_ERR(csi->vdev); + + v4l2_ctrl_handler_init(&csi->ctrl_hdlr, 0); + csi->sd.ctrl_handler = &csi->ctrl_hdlr; + + ret = v4l2_async_register_fwnode_subdev(&csi->sd, + sizeof(struct v4l2_async_subdev), + NULL, 0, + imx7_csi_parse_endpoint); + if (ret) + goto free; + + return 0; + +free: + imx_media_capture_device_unregister(csi->vdev); + imx_media_capture_device_remove(csi->vdev); + v4l2_ctrl_handler_free(&csi->ctrl_hdlr); + +cleanup: + v4l2_async_notifier_cleanup(&imxmd->notifier); + v4l2_device_unregister(&imxmd->v4l2_dev); + media_device_unregister(&imxmd->md); + media_device_cleanup(&imxmd->md); + +destroy_mutex: + mutex_destroy(&csi->lock); + + return ret; +} + +static int imx7_csi_remove(struct platform_device *pdev) +{ + struct v4l2_subdev *sd = platform_get_drvdata(pdev); + struct imx7_csi *csi = v4l2_get_subdevdata(sd); + struct imx_media_dev *imxmd = csi->imxmd; + + v4l2_async_notifier_unregister(&imxmd->notifier); + v4l2_async_notifier_cleanup(&imxmd->notifier); + + media_device_unregister(&imxmd->md); + v4l2_device_unregister(&imxmd->v4l2_dev); + media_device_cleanup(&imxmd->md); + + imx_media_capture_device_unregister(csi->vdev); + imx_media_capture_device_remove(csi->vdev); + + v4l2_async_unregister_subdev(sd); + v4l2_ctrl_handler_free(&csi->ctrl_hdlr); + + mutex_destroy(&csi->lock); + + return 0; +} + +static const struct of_device_id imx7_csi_of_match[] = { + { .compatible = "fsl,imx7-csi" }, + { }, +}; +MODULE_DEVICE_TABLE(of, imx7_csi_of_match); + +static struct platform_driver imx7_csi_driver = { + .probe = imx7_csi_probe, + .remove = imx7_csi_remove, + .driver = { + .of_match_table = imx7_csi_of_match, + .name = "imx7-csi", + }, +}; +module_platform_driver(imx7_csi_driver); + +MODULE_DESCRIPTION("i.MX7 CSI subdev driver"); +MODULE_AUTHOR("Rui Miguel Silva <rui.silva@linaro.org>"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:imx7-csi"); diff --git a/drivers/staging/media/imx/imx7-mipi-csis.c b/drivers/staging/media/imx/imx7-mipi-csis.c new file mode 100644 index 000000000000..2ddcc42ab8ff --- /dev/null +++ b/drivers/staging/media/imx/imx7-mipi-csis.c @@ -0,0 +1,1160 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Freescale i.MX7 SoC series MIPI-CSI V3.3 receiver driver + * + * Copyright (C) 2019 Linaro Ltd + * Copyright (C) 2015-2016 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright (C) 2011 - 2013 Samsung Electronics Co., Ltd. + * + */ + +#include <linux/clk.h> +#include <linux/delay.h> +#include <linux/errno.h> +#include <linux/interrupt.h> +#include <linux/io.h> +#include <linux/irq.h> +#include <linux/kernel.h> +#include <linux/mfd/syscon.h> +#include <linux/module.h> +#include <linux/of_graph.h> +#include <linux/platform_device.h> +#include <linux/pm_runtime.h> +#include <linux/reset.h> +#include <linux/regulator/consumer.h> +#include <linux/spinlock.h> + +#include <media/v4l2-device.h> +#include <media/v4l2-fwnode.h> +#include <media/v4l2-subdev.h> + +#include "imx-media.h" + +#define CSIS_DRIVER_NAME "imx7-mipi-csis" +#define CSIS_SUBDEV_NAME CSIS_DRIVER_NAME + +#define CSIS_PAD_SINK 0 +#define CSIS_PAD_SOURCE 1 +#define CSIS_PADS_NUM 2 + +#define MIPI_CSIS_DEF_PIX_WIDTH 640 +#define MIPI_CSIS_DEF_PIX_HEIGHT 480 + +/* Register map definition */ + +/* CSIS common control */ +#define MIPI_CSIS_CMN_CTRL 0x04 +#define MIPI_CSIS_CMN_CTRL_UPDATE_SHADOW BIT(16) +#define MIPI_CSIS_CMN_CTRL_INTER_MODE BIT(10) +#define MIPI_CSIS_CMN_CTRL_UPDATE_SHADOW_CTRL BIT(2) +#define MIPI_CSIS_CMN_CTRL_RESET BIT(1) +#define MIPI_CSIS_CMN_CTRL_ENABLE BIT(0) + +#define MIPI_CSIS_CMN_CTRL_LANE_NR_OFFSET 8 +#define MIPI_CSIS_CMN_CTRL_LANE_NR_MASK (3 << 8) + +/* CSIS clock control */ +#define MIPI_CSIS_CLK_CTRL 0x08 +#define MIPI_CSIS_CLK_CTRL_CLKGATE_TRAIL_CH3(x) ((x) << 28) +#define MIPI_CSIS_CLK_CTRL_CLKGATE_TRAIL_CH2(x) ((x) << 24) +#define MIPI_CSIS_CLK_CTRL_CLKGATE_TRAIL_CH1(x) ((x) << 20) +#define MIPI_CSIS_CLK_CTRL_CLKGATE_TRAIL_CH0(x) ((x) << 16) +#define MIPI_CSIS_CLK_CTRL_CLKGATE_EN_MSK (0xf << 4) +#define MIPI_CSIS_CLK_CTRL_WCLK_SRC BIT(0) + +/* CSIS Interrupt mask */ +#define MIPI_CSIS_INTMSK 0x10 +#define MIPI_CSIS_INTMSK_EVEN_BEFORE BIT(31) +#define MIPI_CSIS_INTMSK_EVEN_AFTER BIT(30) +#define MIPI_CSIS_INTMSK_ODD_BEFORE BIT(29) +#define MIPI_CSIS_INTMSK_ODD_AFTER BIT(28) +#define MIPI_CSIS_INTMSK_FRAME_START BIT(24) +#define MIPI_CSIS_INTMSK_FRAME_END BIT(20) +#define MIPI_CSIS_INTMSK_ERR_SOT_HS BIT(16) +#define MIPI_CSIS_INTMSK_ERR_LOST_FS BIT(12) +#define MIPI_CSIS_INTMSK_ERR_LOST_FE BIT(8) +#define MIPI_CSIS_INTMSK_ERR_OVER BIT(4) +#define MIPI_CSIS_INTMSK_ERR_WRONG_CFG BIT(3) +#define MIPI_CSIS_INTMSK_ERR_ECC BIT(2) +#define MIPI_CSIS_INTMSK_ERR_CRC BIT(1) +#define MIPI_CSIS_INTMSK_ERR_UNKNOWN BIT(0) + +/* CSIS Interrupt source */ +#define MIPI_CSIS_INTSRC 0x14 +#define MIPI_CSIS_INTSRC_EVEN_BEFORE BIT(31) +#define MIPI_CSIS_INTSRC_EVEN_AFTER BIT(30) +#define MIPI_CSIS_INTSRC_EVEN BIT(30) +#define MIPI_CSIS_INTSRC_ODD_BEFORE BIT(29) +#define MIPI_CSIS_INTSRC_ODD_AFTER BIT(28) +#define MIPI_CSIS_INTSRC_ODD (0x3 << 28) +#define MIPI_CSIS_INTSRC_NON_IMAGE_DATA (0xf << 28) +#define MIPI_CSIS_INTSRC_FRAME_START BIT(24) +#define MIPI_CSIS_INTSRC_FRAME_END BIT(20) +#define MIPI_CSIS_INTSRC_ERR_SOT_HS BIT(16) +#define MIPI_CSIS_INTSRC_ERR_LOST_FS BIT(12) +#define MIPI_CSIS_INTSRC_ERR_LOST_FE BIT(8) +#define MIPI_CSIS_INTSRC_ERR_OVER BIT(4) +#define MIPI_CSIS_INTSRC_ERR_WRONG_CFG BIT(3) +#define MIPI_CSIS_INTSRC_ERR_ECC BIT(2) +#define MIPI_CSIS_INTSRC_ERR_CRC BIT(1) +#define MIPI_CSIS_INTSRC_ERR_UNKNOWN BIT(0) +#define MIPI_CSIS_INTSRC_ERRORS 0xfffff + +/* D-PHY status control */ +#define MIPI_CSIS_DPHYSTATUS 0x20 +#define MIPI_CSIS_DPHYSTATUS_ULPS_DAT BIT(8) +#define MIPI_CSIS_DPHYSTATUS_STOPSTATE_DAT BIT(4) +#define MIPI_CSIS_DPHYSTATUS_ULPS_CLK BIT(1) +#define MIPI_CSIS_DPHYSTATUS_STOPSTATE_CLK BIT(0) + +/* D-PHY common control */ +#define MIPI_CSIS_DPHYCTRL 0x24 +#define MIPI_CSIS_DPHYCTRL_HSS_MASK (0xff << 24) +#define MIPI_CSIS_DPHYCTRL_HSS_OFFSET 24 +#define MIPI_CSIS_DPHYCTRL_SCLKS_MASK (0x3 << 22) +#define MIPI_CSIS_DPHYCTRL_SCLKS_OFFSET 22 +#define MIPI_CSIS_DPHYCTRL_DPDN_SWAP_CLK BIT(6) +#define MIPI_CSIS_DPHYCTRL_DPDN_SWAP_DAT BIT(5) +#define MIPI_CSIS_DPHYCTRL_ENABLE_DAT BIT(1) +#define MIPI_CSIS_DPHYCTRL_ENABLE_CLK BIT(0) +#define MIPI_CSIS_DPHYCTRL_ENABLE (0x1f << 0) + +/* D-PHY Master and Slave Control register Low */ +#define MIPI_CSIS_DPHYBCTRL_L 0x30 +/* D-PHY Master and Slave Control register High */ +#define MIPI_CSIS_DPHYBCTRL_H 0x34 +/* D-PHY Slave Control register Low */ +#define MIPI_CSIS_DPHYSCTRL_L 0x38 +/* D-PHY Slave Control register High */ +#define MIPI_CSIS_DPHYSCTRL_H 0x3c + +/* ISP Configuration register */ +#define MIPI_CSIS_ISPCONFIG_CH0 0x40 +#define MIPI_CSIS_ISPCONFIG_CH1 0x50 +#define MIPI_CSIS_ISPCONFIG_CH2 0x60 +#define MIPI_CSIS_ISPCONFIG_CH3 0x70 + +#define MIPI_CSIS_ISPCFG_MEM_FULL_GAP_MSK (0xff << 24) +#define MIPI_CSIS_ISPCFG_MEM_FULL_GAP(x) ((x) << 24) +#define MIPI_CSIS_ISPCFG_DOUBLE_CMPNT BIT(12) +#define MIPI_CSIS_ISPCFG_ALIGN_32BIT BIT(11) +#define MIPI_CSIS_ISPCFG_FMT_YCBCR422_8BIT (0x1e << 2) +#define MIPI_CSIS_ISPCFG_FMT_RAW8 (0x2a << 2) +#define MIPI_CSIS_ISPCFG_FMT_RAW10 (0x2b << 2) +#define MIPI_CSIS_ISPCFG_FMT_RAW12 (0x2c << 2) + +/* User defined formats, x = 1...4 */ +#define MIPI_CSIS_ISPCFG_FMT_USER(x) ((0x30 + (x) - 1) << 2) +#define MIPI_CSIS_ISPCFG_FMT_MASK (0x3f << 2) + +/* ISP Image Resolution register */ +#define MIPI_CSIS_ISPRESOL_CH0 0x44 +#define MIPI_CSIS_ISPRESOL_CH1 0x54 +#define MIPI_CSIS_ISPRESOL_CH2 0x64 +#define MIPI_CSIS_ISPRESOL_CH3 0x74 +#define CSIS_MAX_PIX_WIDTH 0xffff +#define CSIS_MAX_PIX_HEIGHT 0xffff + +/* ISP SYNC register */ +#define MIPI_CSIS_ISPSYNC_CH0 0x48 +#define MIPI_CSIS_ISPSYNC_CH1 0x58 +#define MIPI_CSIS_ISPSYNC_CH2 0x68 +#define MIPI_CSIS_ISPSYNC_CH3 0x78 + +#define MIPI_CSIS_ISPSYNC_HSYNC_LINTV_OFFSET 18 +#define MIPI_CSIS_ISPSYNC_VSYNC_SINTV_OFFSET 12 +#define MIPI_CSIS_ISPSYNC_VSYNC_EINTV_OFFSET 0 + +/* Non-image packet data buffers */ +#define MIPI_CSIS_PKTDATA_ODD 0x2000 +#define MIPI_CSIS_PKTDATA_EVEN 0x3000 +#define MIPI_CSIS_PKTDATA_SIZE SZ_4K + +#define DEFAULT_SCLK_CSIS_FREQ 166000000UL + +enum { + ST_POWERED = 1, + ST_STREAMING = 2, + ST_SUSPENDED = 4, +}; + +struct mipi_csis_event { + u32 mask; + const char * const name; + unsigned int counter; +}; + +static const struct mipi_csis_event mipi_csis_events[] = { + /* Errors */ + { MIPI_CSIS_INTSRC_ERR_SOT_HS, "SOT Error" }, + { MIPI_CSIS_INTSRC_ERR_LOST_FS, "Lost Frame Start Error" }, + { MIPI_CSIS_INTSRC_ERR_LOST_FE, "Lost Frame End Error" }, + { MIPI_CSIS_INTSRC_ERR_OVER, "FIFO Overflow Error" }, + { MIPI_CSIS_INTSRC_ERR_WRONG_CFG, "Wrong Configuration Error" }, + { MIPI_CSIS_INTSRC_ERR_ECC, "ECC Error" }, + { MIPI_CSIS_INTSRC_ERR_CRC, "CRC Error" }, + { MIPI_CSIS_INTSRC_ERR_UNKNOWN, "Unknown Error" }, + /* Non-image data receive events */ + { MIPI_CSIS_INTSRC_EVEN_BEFORE, "Non-image data before even frame" }, + { MIPI_CSIS_INTSRC_EVEN_AFTER, "Non-image data after even frame" }, + { MIPI_CSIS_INTSRC_ODD_BEFORE, "Non-image data before odd frame" }, + { MIPI_CSIS_INTSRC_ODD_AFTER, "Non-image data after odd frame" }, + /* Frame start/end */ + { MIPI_CSIS_INTSRC_FRAME_START, "Frame Start" }, + { MIPI_CSIS_INTSRC_FRAME_END, "Frame End" }, +}; + +#define MIPI_CSIS_NUM_EVENTS ARRAY_SIZE(mipi_csis_events) + +static const char * const mipi_csis_clk_id[] = {"pclk", "wrap", "phy"}; + +struct csis_hw_reset { + struct regmap *src; + u8 req_src; + u8 rst_bit; +}; + +struct csi_state { + /* lock elements below */ + struct mutex lock; + /* lock for event handler */ + spinlock_t slock; + struct device *dev; + struct media_pad pads[CSIS_PADS_NUM]; + struct v4l2_subdev mipi_sd; + struct v4l2_subdev *src_sd; + + u8 index; + struct platform_device *pdev; + struct phy *phy; + void __iomem *regs; + struct clk *wrap_clk; + int irq; + u32 flags; + + struct dentry *debugfs_root; + bool debug; + + int num_clks; + struct clk_bulk_data *clks; + + u32 clk_frequency; + u32 hs_settle; + + struct reset_control *mrst; + + const struct csis_pix_format *csis_fmt; + struct v4l2_mbus_framefmt format_mbus; + + struct v4l2_fwnode_bus_mipi_csi2 bus; + + struct mipi_csis_event events[MIPI_CSIS_NUM_EVENTS]; + + struct v4l2_async_notifier subdev_notifier; + + struct csis_hw_reset hw_reset; + struct regulator *mipi_phy_regulator; + bool sink_linked; +}; + +struct csis_pix_format { + unsigned int pix_width_alignment; + u32 code; + u32 fmt_reg; + u8 data_alignment; +}; + +static const struct csis_pix_format mipi_csis_formats[] = { + { + .code = MEDIA_BUS_FMT_SBGGR10_1X10, + .fmt_reg = MIPI_CSIS_ISPCFG_FMT_RAW10, + .data_alignment = 16, + }, { + .code = MEDIA_BUS_FMT_VYUY8_2X8, + .fmt_reg = MIPI_CSIS_ISPCFG_FMT_YCBCR422_8BIT, + .data_alignment = 16, + }, { + .code = MEDIA_BUS_FMT_SBGGR8_1X8, + .fmt_reg = MIPI_CSIS_ISPCFG_FMT_RAW8, + .data_alignment = 8, + }, { + .code = MEDIA_BUS_FMT_YUYV8_2X8, + .fmt_reg = MIPI_CSIS_ISPCFG_FMT_YCBCR422_8BIT, + .data_alignment = 16, + } +}; + +#define mipi_csis_write(__csis, __r, __v) writel(__v, (__csis)->regs + (__r)) +#define mipi_csis_read(__csis, __r) readl((__csis)->regs + (__r)) + +static int mipi_csis_dump_regs(struct csi_state *state) +{ + struct device *dev = &state->pdev->dev; + unsigned int i; + u32 cfg; + struct { + u32 offset; + const char * const name; + } registers[] = { + { 0x04, "CTRL" }, + { 0x24, "DPHYCTRL" }, + { 0x08, "CLKCTRL" }, + { 0x20, "DPHYSTS" }, + { 0x10, "INTMSK" }, + { 0x40, "CONFIG_CH0" }, + { 0xC0, "DBG_CONFIG" }, + { 0x38, "DPHYSLAVE_L" }, + { 0x3C, "DPHYSLAVE_H" }, + }; + + dev_info(dev, "--- REGISTERS ---\n"); + + for (i = 0; i < ARRAY_SIZE(registers); i++) { + cfg = mipi_csis_read(state, registers[i].offset); + dev_info(dev, "%12s: 0x%08x\n", registers[i].name, cfg); + } + + return 0; +} + +static struct csi_state *mipi_sd_to_csis_state(struct v4l2_subdev *sdev) +{ + return container_of(sdev, struct csi_state, mipi_sd); +} + +static const struct csis_pix_format *find_csis_format(u32 code) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(mipi_csis_formats); i++) + if (code == mipi_csis_formats[i].code) + return &mipi_csis_formats[i]; + return NULL; +} + +static void mipi_csis_enable_interrupts(struct csi_state *state, bool on) +{ + mipi_csis_write(state, MIPI_CSIS_INTMSK, on ? 0xffffffff : 0); +} + +static void mipi_csis_sw_reset(struct csi_state *state) +{ + u32 val = mipi_csis_read(state, MIPI_CSIS_CMN_CTRL); + + mipi_csis_write(state, MIPI_CSIS_CMN_CTRL, + val | MIPI_CSIS_CMN_CTRL_RESET); + usleep_range(10, 20); +} + +static int mipi_csis_phy_init(struct csi_state *state) +{ + state->mipi_phy_regulator = devm_regulator_get(state->dev, "phy"); + + return regulator_set_voltage(state->mipi_phy_regulator, 1000000, + 1000000); +} + +static void mipi_csis_phy_reset(struct csi_state *state) +{ + reset_control_assert(state->mrst); + + msleep(20); + + reset_control_deassert(state->mrst); +} + +static void mipi_csis_system_enable(struct csi_state *state, int on) +{ + u32 val, mask; + + val = mipi_csis_read(state, MIPI_CSIS_CMN_CTRL); + if (on) + val |= MIPI_CSIS_CMN_CTRL_ENABLE; + else + val &= ~MIPI_CSIS_CMN_CTRL_ENABLE; + mipi_csis_write(state, MIPI_CSIS_CMN_CTRL, val); + + val = mipi_csis_read(state, MIPI_CSIS_DPHYCTRL); + val &= ~MIPI_CSIS_DPHYCTRL_ENABLE; + if (on) { + mask = (1 << (state->bus.num_data_lanes + 1)) - 1; + val |= (mask & MIPI_CSIS_DPHYCTRL_ENABLE); + } + mipi_csis_write(state, MIPI_CSIS_DPHYCTRL, val); +} + +/* Called with the state.lock mutex held */ +static void __mipi_csis_set_format(struct csi_state *state) +{ + struct v4l2_mbus_framefmt *mf = &state->format_mbus; + u32 val; + + /* Color format */ + val = mipi_csis_read(state, MIPI_CSIS_ISPCONFIG_CH0); + val = (val & ~MIPI_CSIS_ISPCFG_FMT_MASK) | state->csis_fmt->fmt_reg; + mipi_csis_write(state, MIPI_CSIS_ISPCONFIG_CH0, val); + + /* Pixel resolution */ + val = mf->width | (mf->height << 16); + mipi_csis_write(state, MIPI_CSIS_ISPRESOL_CH0, val); +} + +static void mipi_csis_set_hsync_settle(struct csi_state *state, int hs_settle) +{ + u32 val = mipi_csis_read(state, MIPI_CSIS_DPHYCTRL); + + val = ((val & ~MIPI_CSIS_DPHYCTRL_HSS_MASK) | (hs_settle << 24)); + + mipi_csis_write(state, MIPI_CSIS_DPHYCTRL, val); +} + +static void mipi_csis_set_params(struct csi_state *state) +{ + int lanes = state->bus.num_data_lanes; + u32 val; + + val = mipi_csis_read(state, MIPI_CSIS_CMN_CTRL); + val &= ~MIPI_CSIS_CMN_CTRL_LANE_NR_MASK; + val |= (lanes - 1) << MIPI_CSIS_CMN_CTRL_LANE_NR_OFFSET; + mipi_csis_write(state, MIPI_CSIS_CMN_CTRL, val); + + __mipi_csis_set_format(state); + + mipi_csis_set_hsync_settle(state, state->hs_settle); + + val = mipi_csis_read(state, MIPI_CSIS_ISPCONFIG_CH0); + if (state->csis_fmt->data_alignment == 32) + val |= MIPI_CSIS_ISPCFG_ALIGN_32BIT; + else + val &= ~MIPI_CSIS_ISPCFG_ALIGN_32BIT; + mipi_csis_write(state, MIPI_CSIS_ISPCONFIG_CH0, val); + + val = (0 << MIPI_CSIS_ISPSYNC_HSYNC_LINTV_OFFSET) | + (0 << MIPI_CSIS_ISPSYNC_VSYNC_SINTV_OFFSET) | + (0 << MIPI_CSIS_ISPSYNC_VSYNC_EINTV_OFFSET); + mipi_csis_write(state, MIPI_CSIS_ISPSYNC_CH0, val); + + val = mipi_csis_read(state, MIPI_CSIS_CLK_CTRL); + val &= ~MIPI_CSIS_CLK_CTRL_WCLK_SRC; + if (state->wrap_clk) + val |= MIPI_CSIS_CLK_CTRL_WCLK_SRC; + else + val &= ~MIPI_CSIS_CLK_CTRL_WCLK_SRC; + + val |= MIPI_CSIS_CLK_CTRL_CLKGATE_TRAIL_CH0(15); + val &= ~MIPI_CSIS_CLK_CTRL_CLKGATE_EN_MSK; + mipi_csis_write(state, MIPI_CSIS_CLK_CTRL, val); + + mipi_csis_write(state, MIPI_CSIS_DPHYBCTRL_L, 0x1f4); + mipi_csis_write(state, MIPI_CSIS_DPHYBCTRL_H, 0); + + /* Update the shadow register. */ + val = mipi_csis_read(state, MIPI_CSIS_CMN_CTRL); + mipi_csis_write(state, MIPI_CSIS_CMN_CTRL, + val | MIPI_CSIS_CMN_CTRL_UPDATE_SHADOW | + MIPI_CSIS_CMN_CTRL_UPDATE_SHADOW_CTRL); +} + +static void mipi_csis_clk_enable(struct csi_state *state) +{ + int ret; + + ret = clk_bulk_prepare_enable(state->num_clks, state->clks); + if (ret < 0) + dev_err(state->dev, "failed to enable clocks\n"); +} + +static void mipi_csis_clk_disable(struct csi_state *state) +{ + clk_bulk_disable_unprepare(state->num_clks, state->clks); +} + +static int mipi_csis_clk_get(struct csi_state *state) +{ + struct device *dev = &state->pdev->dev; + unsigned int i; + int ret; + + state->num_clks = ARRAY_SIZE(mipi_csis_clk_id); + state->clks = devm_kcalloc(dev, state->num_clks, sizeof(*state->clks), + GFP_KERNEL); + + if (!state->clks) + return -ENOMEM; + + for (i = 0; i < state->num_clks; i++) + state->clks[i].id = mipi_csis_clk_id[i]; + + ret = devm_clk_bulk_get(dev, state->num_clks, state->clks); + if (ret < 0) + return ret; + + state->wrap_clk = devm_clk_get(dev, "wrap"); + if (IS_ERR(state->wrap_clk)) + return IS_ERR(state->wrap_clk); + + /* Set clock rate */ + ret = clk_set_rate(state->wrap_clk, state->clk_frequency); + if (ret < 0) + dev_err(dev, "set rate=%d failed: %d\n", state->clk_frequency, + ret); + + return ret; +} + +static void mipi_csis_start_stream(struct csi_state *state) +{ + mipi_csis_sw_reset(state); + mipi_csis_set_params(state); + mipi_csis_system_enable(state, true); + mipi_csis_enable_interrupts(state, true); +} + +static void mipi_csis_stop_stream(struct csi_state *state) +{ + mipi_csis_enable_interrupts(state, false); + mipi_csis_system_enable(state, false); +} + +static void mipi_csis_clear_counters(struct csi_state *state) +{ + unsigned long flags; + unsigned int i; + + spin_lock_irqsave(&state->slock, flags); + for (i = 0; i < MIPI_CSIS_NUM_EVENTS; i++) + state->events[i].counter = 0; + spin_unlock_irqrestore(&state->slock, flags); +} + +static void mipi_csis_log_counters(struct csi_state *state, bool non_errors) +{ + int i = non_errors ? MIPI_CSIS_NUM_EVENTS : MIPI_CSIS_NUM_EVENTS - 4; + struct device *dev = &state->pdev->dev; + unsigned long flags; + + spin_lock_irqsave(&state->slock, flags); + + for (i--; i >= 0; i--) { + if (state->events[i].counter > 0 || state->debug) + dev_info(dev, "%s events: %d\n", state->events[i].name, + state->events[i].counter); + } + spin_unlock_irqrestore(&state->slock, flags); +} + +/* + * V4L2 subdev operations + */ +static int mipi_csis_s_stream(struct v4l2_subdev *mipi_sd, int enable) +{ + struct csi_state *state = mipi_sd_to_csis_state(mipi_sd); + int ret = 0; + + if (enable) { + mipi_csis_clear_counters(state); + ret = pm_runtime_get_sync(&state->pdev->dev); + if (ret < 0) { + pm_runtime_put_noidle(&state->pdev->dev); + return ret; + } + ret = v4l2_subdev_call(state->src_sd, core, s_power, 1); + if (ret < 0) + return ret; + } + + mutex_lock(&state->lock); + if (enable) { + if (state->flags & ST_SUSPENDED) { + ret = -EBUSY; + goto unlock; + } + + mipi_csis_start_stream(state); + ret = v4l2_subdev_call(state->src_sd, video, s_stream, 1); + if (ret < 0) + goto unlock; + + mipi_csis_log_counters(state, true); + + state->flags |= ST_STREAMING; + } else { + v4l2_subdev_call(state->src_sd, video, s_stream, 0); + ret = v4l2_subdev_call(state->src_sd, core, s_power, 1); + mipi_csis_stop_stream(state); + state->flags &= ~ST_STREAMING; + if (state->debug) + mipi_csis_log_counters(state, true); + } + +unlock: + mutex_unlock(&state->lock); + if (!enable) + pm_runtime_put(&state->pdev->dev); + + return ret; +} + +static int mipi_csis_link_setup(struct media_entity *entity, + const struct media_pad *local_pad, + const struct media_pad *remote_pad, u32 flags) +{ + struct v4l2_subdev *mipi_sd = media_entity_to_v4l2_subdev(entity); + struct csi_state *state = mipi_sd_to_csis_state(mipi_sd); + struct v4l2_subdev *remote_sd; + int ret = 0; + + dev_dbg(state->dev, "link setup %s -> %s", remote_pad->entity->name, + local_pad->entity->name); + + remote_sd = media_entity_to_v4l2_subdev(remote_pad->entity); + + mutex_lock(&state->lock); + + if (local_pad->flags & MEDIA_PAD_FL_SOURCE) { + if (flags & MEDIA_LNK_FL_ENABLED) { + if (state->sink_linked) { + ret = -EBUSY; + goto out; + } + state->sink_linked = true; + } else { + state->sink_linked = false; + } + } else { + if (flags & MEDIA_LNK_FL_ENABLED) { + if (state->src_sd) { + ret = -EBUSY; + goto out; + } + state->src_sd = remote_sd; + } else { + state->src_sd = NULL; + } + } + +out: + mutex_unlock(&state->lock); + return ret; +} + +static int mipi_csis_init_cfg(struct v4l2_subdev *mipi_sd, + struct v4l2_subdev_pad_config *cfg) +{ + struct v4l2_mbus_framefmt *mf; + unsigned int i; + int ret; + + for (i = 0; i < CSIS_PADS_NUM; i++) { + mf = v4l2_subdev_get_try_format(mipi_sd, cfg, i); + + ret = imx_media_init_mbus_fmt(mf, MIPI_CSIS_DEF_PIX_HEIGHT, + MIPI_CSIS_DEF_PIX_WIDTH, 0, + V4L2_FIELD_NONE, NULL); + if (ret < 0) + return ret; + } + + return 0; +} + +static struct csis_pix_format const * +mipi_csis_try_format(struct v4l2_subdev *mipi_sd, struct v4l2_mbus_framefmt *mf) +{ + struct csi_state *state = mipi_sd_to_csis_state(mipi_sd); + struct csis_pix_format const *csis_fmt; + + csis_fmt = find_csis_format(mf->code); + if (!csis_fmt) + csis_fmt = &mipi_csis_formats[0]; + + v4l_bound_align_image(&mf->width, 1, CSIS_MAX_PIX_WIDTH, + csis_fmt->pix_width_alignment, + &mf->height, 1, CSIS_MAX_PIX_HEIGHT, 1, + 0); + + state->format_mbus.code = csis_fmt->code; + state->format_mbus.width = mf->width; + state->format_mbus.height = mf->height; + + return csis_fmt; +} + +static struct v4l2_mbus_framefmt * +mipi_csis_get_format(struct csi_state *state, + struct v4l2_subdev_pad_config *cfg, + enum v4l2_subdev_format_whence which, + unsigned int pad) +{ + if (which == V4L2_SUBDEV_FORMAT_TRY) + return v4l2_subdev_get_try_format(&state->mipi_sd, cfg, pad); + + return &state->format_mbus; +} + +static int mipi_csis_set_fmt(struct v4l2_subdev *mipi_sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *sdformat) +{ + struct csi_state *state = mipi_sd_to_csis_state(mipi_sd); + struct csis_pix_format const *csis_fmt; + struct v4l2_mbus_framefmt *fmt; + + if (sdformat->pad >= CSIS_PADS_NUM) + return -EINVAL; + + fmt = mipi_csis_get_format(state, cfg, sdformat->which, sdformat->pad); + + mutex_lock(&state->lock); + if (fmt && sdformat->pad == CSIS_PAD_SOURCE) { + sdformat->format = *fmt; + goto unlock; + } + + csis_fmt = mipi_csis_try_format(mipi_sd, &sdformat->format); + + sdformat->format = *fmt; + + if (csis_fmt && sdformat->which == V4L2_SUBDEV_FORMAT_ACTIVE) + state->csis_fmt = csis_fmt; + else + cfg->try_fmt = sdformat->format; + +unlock: + mutex_unlock(&state->lock); + + return 0; +} + +static int mipi_csis_get_fmt(struct v4l2_subdev *mipi_sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *sdformat) +{ + struct csi_state *state = mipi_sd_to_csis_state(mipi_sd); + struct v4l2_mbus_framefmt *fmt; + + mutex_lock(&state->lock); + + fmt = mipi_csis_get_format(state, cfg, sdformat->which, sdformat->pad); + + sdformat->format = *fmt; + + mutex_unlock(&state->lock); + + return 0; +} + +static int mipi_csis_log_status(struct v4l2_subdev *mipi_sd) +{ + struct csi_state *state = mipi_sd_to_csis_state(mipi_sd); + + mutex_lock(&state->lock); + mipi_csis_log_counters(state, true); + if (state->debug && (state->flags & ST_POWERED)) + mipi_csis_dump_regs(state); + mutex_unlock(&state->lock); + + return 0; +} + +static irqreturn_t mipi_csis_irq_handler(int irq, void *dev_id) +{ + struct csi_state *state = dev_id; + unsigned long flags; + unsigned int i; + u32 status; + + status = mipi_csis_read(state, MIPI_CSIS_INTSRC); + + spin_lock_irqsave(&state->slock, flags); + + /* Update the event/error counters */ + if ((status & MIPI_CSIS_INTSRC_ERRORS) || state->debug) { + for (i = 0; i < MIPI_CSIS_NUM_EVENTS; i++) { + if (!(status & state->events[i].mask)) + continue; + state->events[i].counter++; + } + } + spin_unlock_irqrestore(&state->slock, flags); + + mipi_csis_write(state, MIPI_CSIS_INTSRC, status); + + return IRQ_HANDLED; +} + +static const struct v4l2_subdev_core_ops mipi_csis_core_ops = { + .log_status = mipi_csis_log_status, +}; + +static const struct media_entity_operations mipi_csis_entity_ops = { + .link_setup = mipi_csis_link_setup, + .link_validate = v4l2_subdev_link_validate, +}; + +static const struct v4l2_subdev_video_ops mipi_csis_video_ops = { + .s_stream = mipi_csis_s_stream, +}; + +static const struct v4l2_subdev_pad_ops mipi_csis_pad_ops = { + .init_cfg = mipi_csis_init_cfg, + .get_fmt = mipi_csis_get_fmt, + .set_fmt = mipi_csis_set_fmt, +}; + +static const struct v4l2_subdev_ops mipi_csis_subdev_ops = { + .core = &mipi_csis_core_ops, + .video = &mipi_csis_video_ops, + .pad = &mipi_csis_pad_ops, +}; + +static int mipi_csis_parse_dt(struct platform_device *pdev, + struct csi_state *state) +{ + struct device_node *node = pdev->dev.of_node; + + if (of_property_read_u32(node, "clock-frequency", + &state->clk_frequency)) + state->clk_frequency = DEFAULT_SCLK_CSIS_FREQ; + + /* Get MIPI PHY resets */ + state->mrst = devm_reset_control_get_exclusive(&pdev->dev, "mrst"); + if (IS_ERR(state->mrst)) + return PTR_ERR(state->mrst); + + /* Get MIPI CSI-2 bus configuration from the endpoint node. */ + of_property_read_u32(node, "fsl,csis-hs-settle", &state->hs_settle); + + return 0; +} + +static int mipi_csis_pm_resume(struct device *dev, bool runtime); + +static int mipi_csis_parse_endpoint(struct device *dev, + struct v4l2_fwnode_endpoint *ep, + struct v4l2_async_subdev *asd) +{ + struct v4l2_subdev *mipi_sd = dev_get_drvdata(dev); + struct csi_state *state = mipi_sd_to_csis_state(mipi_sd); + + if (ep->bus_type != V4L2_MBUS_CSI2_DPHY) { + dev_err(dev, "invalid bus type, must be MIPI CSI2\n"); + return -EINVAL; + } + + state->bus = ep->bus.mipi_csi2; + + dev_dbg(state->dev, "data lanes: %d\n", state->bus.num_data_lanes); + dev_dbg(state->dev, "flags: 0x%08x\n", state->bus.flags); + + return 0; +} + +static int mipi_csis_subdev_init(struct v4l2_subdev *mipi_sd, + struct platform_device *pdev, + const struct v4l2_subdev_ops *ops) +{ + struct csi_state *state = mipi_sd_to_csis_state(mipi_sd); + unsigned int sink_port = 0; + int ret; + + v4l2_subdev_init(mipi_sd, ops); + mipi_sd->owner = THIS_MODULE; + snprintf(mipi_sd->name, sizeof(mipi_sd->name), "%s.%d", + CSIS_SUBDEV_NAME, state->index); + + mipi_sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; + mipi_sd->ctrl_handler = NULL; + + mipi_sd->entity.function = MEDIA_ENT_F_VID_IF_BRIDGE; + mipi_sd->entity.ops = &mipi_csis_entity_ops; + + mipi_sd->dev = &pdev->dev; + + state->csis_fmt = &mipi_csis_formats[0]; + state->format_mbus.code = mipi_csis_formats[0].code; + state->format_mbus.width = MIPI_CSIS_DEF_PIX_WIDTH; + state->format_mbus.height = MIPI_CSIS_DEF_PIX_HEIGHT; + state->format_mbus.field = V4L2_FIELD_NONE; + + v4l2_set_subdevdata(mipi_sd, &pdev->dev); + + ret = v4l2_async_register_fwnode_subdev(mipi_sd, + sizeof(struct v4l2_async_subdev), + &sink_port, 1, + mipi_csis_parse_endpoint); + if (ret < 0) + dev_err(&pdev->dev, "async fwnode register failed: %d\n", ret); + + return ret; +} + +#ifdef CONFIG_DEBUG_FS +#include <linux/debugfs.h> + +static int mipi_csis_dump_regs_show(struct seq_file *m, void *private) +{ + struct csi_state *state = m->private; + + return mipi_csis_dump_regs(state); +} +DEFINE_SHOW_ATTRIBUTE(mipi_csis_dump_regs); + +static int __init_or_module mipi_csis_debugfs_init(struct csi_state *state) +{ + struct dentry *d; + + if (!debugfs_initialized()) + return -ENODEV; + + state->debugfs_root = debugfs_create_dir(dev_name(state->dev), NULL); + if (!state->debugfs_root) + return -ENOMEM; + + d = debugfs_create_bool("debug_enable", 0600, state->debugfs_root, + &state->debug); + if (!d) + goto remove_debugfs; + + d = debugfs_create_file("dump_regs", 0600, state->debugfs_root, + state, &mipi_csis_dump_regs_fops); + if (!d) + goto remove_debugfs; + + return 0; + +remove_debugfs: + debugfs_remove_recursive(state->debugfs_root); + + return -ENOMEM; +} + +static void mipi_csis_debugfs_exit(struct csi_state *state) +{ + debugfs_remove_recursive(state->debugfs_root); +} + +#else +static int mipi_csis_debugfs_init(struct csi_state *state __maybe_unused) +{ + return 0; +} + +static void mipi_csis_debugfs_exit(struct csi_state *state __maybe_unused) +{ +} +#endif + +static int mipi_csis_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct resource *mem_res; + struct csi_state *state; + int ret = -ENOMEM; + + state = devm_kzalloc(dev, sizeof(*state), GFP_KERNEL); + if (!state) + return -ENOMEM; + + spin_lock_init(&state->slock); + + state->pdev = pdev; + state->dev = dev; + + ret = mipi_csis_parse_dt(pdev, state); + if (ret < 0) { + dev_err(dev, "Failed to parse device tree: %d\n", ret); + return ret; + } + + mipi_csis_phy_init(state); + mipi_csis_phy_reset(state); + + mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + state->regs = devm_ioremap_resource(dev, mem_res); + if (IS_ERR(state->regs)) + return PTR_ERR(state->regs); + + state->irq = platform_get_irq(pdev, 0); + if (state->irq < 0) { + dev_err(dev, "Failed to get irq\n"); + return state->irq; + } + + ret = mipi_csis_clk_get(state); + if (ret < 0) + return ret; + + mipi_csis_clk_enable(state); + + ret = devm_request_irq(dev, state->irq, mipi_csis_irq_handler, + 0, dev_name(dev), state); + if (ret) { + dev_err(dev, "Interrupt request failed\n"); + goto disable_clock; + } + + platform_set_drvdata(pdev, &state->mipi_sd); + + mutex_init(&state->lock); + ret = mipi_csis_subdev_init(&state->mipi_sd, pdev, + &mipi_csis_subdev_ops); + if (ret < 0) + goto disable_clock; + + state->pads[CSIS_PAD_SINK].flags = MEDIA_PAD_FL_SINK; + state->pads[CSIS_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE; + ret = media_entity_pads_init(&state->mipi_sd.entity, CSIS_PADS_NUM, + state->pads); + if (ret < 0) + goto unregister_subdev; + + memcpy(state->events, mipi_csis_events, sizeof(state->events)); + + mipi_csis_debugfs_init(state); + pm_runtime_enable(dev); + if (!pm_runtime_enabled(dev)) { + ret = mipi_csis_pm_resume(dev, true); + if (ret < 0) + goto unregister_all; + } + + dev_info(&pdev->dev, "lanes: %d, hs_settle: %d, wclk: %d, freq: %u\n", + state->bus.num_data_lanes, state->hs_settle, + state->wrap_clk ? 1 : 0, state->clk_frequency); + + return 0; + +unregister_all: + mipi_csis_debugfs_exit(state); + media_entity_cleanup(&state->mipi_sd.entity); +unregister_subdev: + v4l2_async_unregister_subdev(&state->mipi_sd); +disable_clock: + mipi_csis_clk_disable(state); + mutex_destroy(&state->lock); + + return ret; +} + +static int mipi_csis_pm_suspend(struct device *dev, bool runtime) +{ + struct platform_device *pdev = to_platform_device(dev); + struct v4l2_subdev *mipi_sd = platform_get_drvdata(pdev); + struct csi_state *state = mipi_sd_to_csis_state(mipi_sd); + int ret = 0; + + mutex_lock(&state->lock); + if (state->flags & ST_POWERED) { + mipi_csis_stop_stream(state); + ret = regulator_disable(state->mipi_phy_regulator); + if (ret) + goto unlock; + mipi_csis_clk_disable(state); + state->flags &= ~ST_POWERED; + if (!runtime) + state->flags |= ST_SUSPENDED; + } + +unlock: + mutex_unlock(&state->lock); + + return ret ? -EAGAIN : 0; +} + +static int mipi_csis_pm_resume(struct device *dev, bool runtime) +{ + struct platform_device *pdev = to_platform_device(dev); + struct v4l2_subdev *mipi_sd = platform_get_drvdata(pdev); + struct csi_state *state = mipi_sd_to_csis_state(mipi_sd); + int ret = 0; + + mutex_lock(&state->lock); + if (!runtime && !(state->flags & ST_SUSPENDED)) + goto unlock; + + if (!(state->flags & ST_POWERED)) { + ret = regulator_enable(state->mipi_phy_regulator); + if (ret) + goto unlock; + + state->flags |= ST_POWERED; + mipi_csis_clk_enable(state); + } + if (state->flags & ST_STREAMING) + mipi_csis_start_stream(state); + + state->flags &= ~ST_SUSPENDED; + +unlock: + mutex_unlock(&state->lock); + + return ret ? -EAGAIN : 0; +} + +static int __maybe_unused mipi_csis_suspend(struct device *dev) +{ + return mipi_csis_pm_suspend(dev, false); +} + +static int __maybe_unused mipi_csis_resume(struct device *dev) +{ + return mipi_csis_pm_resume(dev, false); +} + +static int __maybe_unused mipi_csis_runtime_suspend(struct device *dev) +{ + return mipi_csis_pm_suspend(dev, true); +} + +static int __maybe_unused mipi_csis_runtime_resume(struct device *dev) +{ + return mipi_csis_pm_resume(dev, true); +} + +static int mipi_csis_remove(struct platform_device *pdev) +{ + struct v4l2_subdev *mipi_sd = platform_get_drvdata(pdev); + struct csi_state *state = mipi_sd_to_csis_state(mipi_sd); + + mipi_csis_debugfs_exit(state); + v4l2_async_unregister_subdev(&state->mipi_sd); + v4l2_async_notifier_unregister(&state->subdev_notifier); + + pm_runtime_disable(&pdev->dev); + mipi_csis_pm_suspend(&pdev->dev, true); + mipi_csis_clk_disable(state); + media_entity_cleanup(&state->mipi_sd.entity); + mutex_destroy(&state->lock); + pm_runtime_set_suspended(&pdev->dev); + + return 0; +} + +static const struct dev_pm_ops mipi_csis_pm_ops = { + SET_RUNTIME_PM_OPS(mipi_csis_runtime_suspend, mipi_csis_runtime_resume, + NULL) + SET_SYSTEM_SLEEP_PM_OPS(mipi_csis_suspend, mipi_csis_resume) +}; + +static const struct of_device_id mipi_csis_of_match[] = { + { .compatible = "fsl,imx7-mipi-csi2", }, + { /* sentinel */ }, +}; +MODULE_DEVICE_TABLE(of, mipi_csis_of_match); + +static struct platform_driver mipi_csis_driver = { + .probe = mipi_csis_probe, + .remove = mipi_csis_remove, + .driver = { + .of_match_table = mipi_csis_of_match, + .name = CSIS_DRIVER_NAME, + .pm = &mipi_csis_pm_ops, + }, +}; + +module_platform_driver(mipi_csis_driver); + +MODULE_DESCRIPTION("i.MX7 MIPI CSI-2 Receiver driver"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:imx7-mipi-csi2"); diff --git a/drivers/staging/media/imx074/Kconfig b/drivers/staging/media/imx074/Kconfig deleted file mode 100644 index 229cbeea580b..000000000000 --- a/drivers/staging/media/imx074/Kconfig +++ /dev/null @@ -1,5 +0,0 @@ -config SOC_CAMERA_IMX074 - tristate "imx074 support (DEPRECATED)" - depends on SOC_CAMERA && I2C - help - This driver supports IMX074 cameras from Sony diff --git a/drivers/staging/media/imx074/Makefile b/drivers/staging/media/imx074/Makefile deleted file mode 100644 index 7d183574aa84..000000000000 --- a/drivers/staging/media/imx074/Makefile +++ /dev/null @@ -1 +0,0 @@ -obj-$(CONFIG_SOC_CAMERA_IMX074) += imx074.o diff --git a/drivers/staging/media/imx074/TODO b/drivers/staging/media/imx074/TODO deleted file mode 100644 index 15580a4f950c..000000000000 --- a/drivers/staging/media/imx074/TODO +++ /dev/null @@ -1,5 +0,0 @@ -This sensor driver needs to be converted to a regular -v4l2 subdev driver. The soc_camera framework is deprecated and -will be removed in the future. Unless someone does this work this -sensor driver will be deleted when the soc_camera framework is -deleted. diff --git a/drivers/staging/media/ipu3/Makefile b/drivers/staging/media/ipu3/Makefile index fb146d178bd4..fa7fa3372bcb 100644 --- a/drivers/staging/media/ipu3/Makefile +++ b/drivers/staging/media/ipu3/Makefile @@ -9,3 +9,9 @@ ipu3-imgu-objs += \ ipu3-css.o ipu3-v4l2.o ipu3.o obj-$(CONFIG_VIDEO_IPU3_IMGU) += ipu3-imgu.o + +# HACK! While this driver is in bad shape, don't enable several warnings +# that would be otherwise enabled with W=1 +ccflags-y += $(call cc-disable-warning, packed-not-aligned) +ccflags-y += $(call cc-disable-warning, type-limits) +ccflags-y += $(call cc-disable-warning, unused-const-variable) diff --git a/drivers/staging/media/ipu3/TODO b/drivers/staging/media/ipu3/TODO index 905bbb190217..5e55baeaea1a 100644 --- a/drivers/staging/media/ipu3/TODO +++ b/drivers/staging/media/ipu3/TODO @@ -8,11 +8,6 @@ staging directory. - Using ENABLED and IMMUTABLE link flags for the links where those are relevant. (Sakari) -- Prefix imgu for all public APIs, i.e. change ipu3_v4l2_register() to - imgu_v4l2_register(). (Sakari) - -- Use V4L2_CTRL_TYPE_MENU for dual-pipe mode control. (Sakari) - - IPU3 driver documentation (Laurent) Add diagram in driver rst to describe output capability. Comments on configuring v4l2 subdevs for CIO2 and ImgU. @@ -32,3 +27,5 @@ staging directory. - Document different operation modes, and which buffer queues are relevant in each mode. To process an image, which queues require a buffer an in which ones is it optional? + +- Make sure it builds fine with no warnings with W=1 diff --git a/drivers/staging/media/ipu3/include/intel-ipu3.h b/drivers/staging/media/ipu3/include/intel-ipu3.h index ec0b74829351..1e7184e4311d 100644 --- a/drivers/staging/media/ipu3/include/intel-ipu3.h +++ b/drivers/staging/media/ipu3/include/intel-ipu3.h @@ -16,12 +16,6 @@ #define V4L2_CID_INTEL_IPU3_BASE (V4L2_CID_USER_BASE + 0x10c0) #define V4L2_CID_INTEL_IPU3_MODE (V4L2_CID_INTEL_IPU3_BASE + 1) -/* custom ctrl to set pipe mode */ -enum ipu3_running_mode { - IPU3_RUNNING_MODE_VIDEO = 0, - IPU3_RUNNING_MODE_STILL = 1, -}; - /******************* ipu3_uapi_stats_3a *******************/ #define IPU3_UAPI_MAX_STRIPES 2 @@ -438,11 +432,11 @@ struct ipu3_uapi_awb_fr_raw_buffer { * * @grid_cfg: grid config, default 16x16. * @bayer_coeff: 1D Filter 1x11 center symmetry/anti-symmetry. - * coeffcients defaults { 0, 0, 0, 0, 0, 128 }. + * coefficients defaults { 0, 0, 0, 0, 0, 128 }. * Applied on whole image for each Bayer channel separately * by a weighted sum of its 11x1 neighbors. * @reserved1: reserved - * @bayer_sign: sign of filter coeffcients, default 0. + * @bayer_sign: sign of filter coefficients, default 0. * @bayer_nf: normalization factor for the convolution coeffs, to make sure * total memory needed is within pre-determined range. * NF should be the log2 of the sum of the abs values of the diff --git a/drivers/staging/media/ipu3/ipu3-abi.h b/drivers/staging/media/ipu3/ipu3-abi.h index 25be56ff01c8..e1185602c7fd 100644 --- a/drivers/staging/media/ipu3/ipu3-abi.h +++ b/drivers/staging/media/ipu3/ipu3-abi.h @@ -1510,7 +1510,7 @@ struct imgu_abi_blob_info { /* offset wrt hdr in bytes */ u32 prog_name_offset; /* offset wrt hdr in bytes */ u32 size; /* Size of blob */ - u32 padding_size; /* total cummulative of bytes added + u32 padding_size; /* total cumulative of bytes added * due to section alignment */ u32 icache_source; /* Position of icache in blob */ diff --git a/drivers/staging/media/ipu3/ipu3-css-fw.c b/drivers/staging/media/ipu3/ipu3-css-fw.c index 55861aa8fb03..4122d4e42db6 100644 --- a/drivers/staging/media/ipu3/ipu3-css-fw.c +++ b/drivers/staging/media/ipu3/ipu3-css-fw.c @@ -10,7 +10,7 @@ #include "ipu3-css-fw.h" #include "ipu3-dmamap.h" -static void ipu3_css_fw_show_binary(struct device *dev, struct imgu_fw_info *bi, +static void imgu_css_fw_show_binary(struct device *dev, struct imgu_fw_info *bi, const char *name) { unsigned int i; @@ -54,7 +54,7 @@ static void ipu3_css_fw_show_binary(struct device *dev, struct imgu_fw_info *bi, dev_dbg(dev, "\n"); } -unsigned int ipu3_css_fw_obgrid_size(const struct imgu_fw_info *bi) +unsigned int imgu_css_fw_obgrid_size(const struct imgu_fw_info *bi) { unsigned int width = DIV_ROUND_UP(bi->info.isp.sp.internal.max_width, IMGU_OBGRID_TILE_SIZE * 2) + 1; @@ -69,7 +69,7 @@ unsigned int ipu3_css_fw_obgrid_size(const struct imgu_fw_info *bi) return obgrid_size; } -void *ipu3_css_fw_pipeline_params(struct ipu3_css *css, unsigned int pipe, +void *imgu_css_fw_pipeline_params(struct imgu_css *css, unsigned int pipe, enum imgu_abi_param_class cls, enum imgu_abi_memories mem, struct imgu_fw_isp_parameter *par, @@ -91,7 +91,7 @@ void *ipu3_css_fw_pipeline_params(struct ipu3_css *css, unsigned int pipe, return binary_params + par->offset; } -void ipu3_css_fw_cleanup(struct ipu3_css *css) +void imgu_css_fw_cleanup(struct imgu_css *css) { struct imgu_device *imgu = dev_get_drvdata(css->dev); @@ -99,7 +99,7 @@ void ipu3_css_fw_cleanup(struct ipu3_css *css) unsigned int i; for (i = 0; i < css->fwp->file_header.binary_nr; i++) - ipu3_dmamap_free(imgu, &css->binary[i]); + imgu_dmamap_free(imgu, &css->binary[i]); kfree(css->binary); } if (css->fw) @@ -109,7 +109,7 @@ void ipu3_css_fw_cleanup(struct ipu3_css *css) css->fw = NULL; } -int ipu3_css_fw_init(struct ipu3_css *css) +int imgu_css_fw_init(struct imgu_css *css) { static const u32 BLOCK_MAX = 65536; struct imgu_device *imgu = dev_get_drvdata(css->dev); @@ -227,7 +227,7 @@ int ipu3_css_fw_init(struct ipu3_css *css) css->fw->size) goto bad_fw; - ipu3_css_fw_show_binary(dev, bi, name); + imgu_css_fw_show_binary(dev, bi, name); } if (css->fw_bl == -1 || css->fw_sp[0] == -1 || css->fw_sp[1] == -1) @@ -246,7 +246,7 @@ int ipu3_css_fw_init(struct ipu3_css *css) void *blob = (void *)css->fwp + bi->blob.offset; size_t size = bi->blob.size; - if (!ipu3_dmamap_alloc(imgu, &css->binary[i], size)) { + if (!imgu_dmamap_alloc(imgu, &css->binary[i], size)) { r = -ENOMEM; goto error_out; } @@ -260,6 +260,6 @@ bad_fw: r = -ENODEV; error_out: - ipu3_css_fw_cleanup(css); + imgu_css_fw_cleanup(css); return r; } diff --git a/drivers/staging/media/ipu3/ipu3-css-fw.h b/drivers/staging/media/ipu3/ipu3-css-fw.h index 07d8bb8b25f3..79ffa7045139 100644 --- a/drivers/staging/media/ipu3/ipu3-css-fw.h +++ b/drivers/staging/media/ipu3/ipu3-css-fw.h @@ -175,11 +175,11 @@ struct imgu_fw_header { /******************* Firmware functions *******************/ -int ipu3_css_fw_init(struct ipu3_css *css); -void ipu3_css_fw_cleanup(struct ipu3_css *css); +int imgu_css_fw_init(struct imgu_css *css); +void imgu_css_fw_cleanup(struct imgu_css *css); -unsigned int ipu3_css_fw_obgrid_size(const struct imgu_fw_info *bi); -void *ipu3_css_fw_pipeline_params(struct ipu3_css *css, unsigned int pipe, +unsigned int imgu_css_fw_obgrid_size(const struct imgu_fw_info *bi); +void *imgu_css_fw_pipeline_params(struct imgu_css *css, unsigned int pipe, enum imgu_abi_param_class cls, enum imgu_abi_memories mem, struct imgu_fw_isp_parameter *par, diff --git a/drivers/staging/media/ipu3/ipu3-css-params.c b/drivers/staging/media/ipu3/ipu3-css-params.c index 776206ded83b..4533dacad4be 100644 --- a/drivers/staging/media/ipu3/ipu3-css-params.c +++ b/drivers/staging/media/ipu3/ipu3-css-params.c @@ -6,6 +6,7 @@ #include "ipu3-css.h" #include "ipu3-css-fw.h" #include "ipu3-tables.h" +#include "ipu3-css-params.h" #define DIV_ROUND_CLOSEST_DOWN(a, b) (((a) + ((b) / 2) - 1) / (b)) #define roundclosest_down(a, b) (DIV_ROUND_CLOSEST_DOWN(a, b) * (b)) @@ -13,7 +14,7 @@ #define IPU3_UAPI_ANR_MAX_RESET ((1 << 12) - 1) #define IPU3_UAPI_ANR_MIN_RESET (((-1) << 12) + 1) -struct ipu3_css_scaler_info { +struct imgu_css_scaler_info { unsigned int phase_step; /* Same for luma/chroma */ int exp_shift; @@ -24,7 +25,7 @@ struct ipu3_css_scaler_info { int crop_top; }; -static unsigned int ipu3_css_scaler_get_exp(unsigned int counter, +static unsigned int imgu_css_scaler_get_exp(unsigned int counter, unsigned int divider) { int i = fls(divider) - fls(counter); @@ -40,13 +41,13 @@ static unsigned int ipu3_css_scaler_get_exp(unsigned int counter, /* Set up the CSS scaler look up table */ static void -ipu3_css_scaler_setup_lut(unsigned int taps, unsigned int input_width, +imgu_css_scaler_setup_lut(unsigned int taps, unsigned int input_width, unsigned int output_width, int phase_step_correction, const int *coeffs, unsigned int coeffs_size, - s8 coeff_lut[], struct ipu3_css_scaler_info *info) + s8 coeff_lut[], struct imgu_css_scaler_info *info) { int tap, phase, phase_sum_left, phase_sum_right; - int exponent = ipu3_css_scaler_get_exp(output_width, input_width); + int exponent = imgu_css_scaler_get_exp(output_width, input_width); int mantissa = (1 << exponent) * output_width; unsigned int phase_step; @@ -113,8 +114,8 @@ ipu3_css_scaler_setup_lut(unsigned int taps, unsigned int input_width, * (must be perfectly aligned with hardware). */ static unsigned int -ipu3_css_scaler_calc_scaled_output(unsigned int input, - struct ipu3_css_scaler_info *info) +imgu_css_scaler_calc_scaled_output(unsigned int input, + struct imgu_css_scaler_info *info) { unsigned int arg1 = input * info->phase_step + (1 - IMGU_SCALER_TAPS_Y / 2) * IMGU_SCALER_FIR_PHASES - @@ -132,10 +133,10 @@ ipu3_css_scaler_calc_scaled_output(unsigned int input, * and chroma details of a scaler */ static void -ipu3_css_scaler_calc(u32 input_width, u32 input_height, u32 target_width, +imgu_css_scaler_calc(u32 input_width, u32 input_height, u32 target_width, u32 target_height, struct imgu_abi_osys_config *cfg, - struct ipu3_css_scaler_info *info_luma, - struct ipu3_css_scaler_info *info_chroma, + struct imgu_css_scaler_info *info_luma, + struct imgu_css_scaler_info *info_chroma, unsigned int *output_width, unsigned int *output_height, unsigned int *procmode) { @@ -164,24 +165,24 @@ ipu3_css_scaler_calc(u32 input_width, u32 input_height, u32 target_width, do { phase_step_correction++; - ipu3_css_scaler_setup_lut(IMGU_SCALER_TAPS_Y, + imgu_css_scaler_setup_lut(IMGU_SCALER_TAPS_Y, input_width, target_width, phase_step_correction, - ipu3_css_downscale_4taps, + imgu_css_downscale_4taps, IMGU_SCALER_DOWNSCALE_4TAPS_LEN, cfg->scaler_coeffs_luma, info_luma); - ipu3_css_scaler_setup_lut(IMGU_SCALER_TAPS_UV, + imgu_css_scaler_setup_lut(IMGU_SCALER_TAPS_UV, input_width, target_width, phase_step_correction, - ipu3_css_downscale_2taps, + imgu_css_downscale_2taps, IMGU_SCALER_DOWNSCALE_2TAPS_LEN, cfg->scaler_coeffs_chroma, info_chroma); - out_width = ipu3_css_scaler_calc_scaled_output(input_width, + out_width = imgu_css_scaler_calc_scaled_output(input_width, info_luma); - out_height = ipu3_css_scaler_calc_scaled_output(input_height, + out_height = imgu_css_scaler_calc_scaled_output(input_height, info_luma); } while ((out_width < target_width || out_height < target_height || !IS_ALIGNED(out_height, height_alignment)) && @@ -193,7 +194,7 @@ ipu3_css_scaler_calc(u32 input_width, u32 input_height, u32 target_width, /********************** Osys routines for scaler****************************/ -static void ipu3_css_osys_set_format(enum imgu_abi_frame_format host_format, +static void imgu_css_osys_set_format(enum imgu_abi_frame_format host_format, unsigned int *osys_format, unsigned int *osys_tiling) { @@ -230,7 +231,7 @@ static void ipu3_css_osys_set_format(enum imgu_abi_frame_format host_format, * Function calculates input frame stripe offset, based * on output frame stripe offset and filter parameters. */ -static int ipu3_css_osys_calc_stripe_offset(int stripe_offset_out, +static int imgu_css_osys_calc_stripe_offset(int stripe_offset_out, int fir_phases, int phase_init, int phase_step, int pad_left) { @@ -244,12 +245,12 @@ static int ipu3_css_osys_calc_stripe_offset(int stripe_offset_out, * Calculate input frame phase, given the output frame * stripe offset and filter parameters */ -static int ipu3_css_osys_calc_stripe_phase_init(int stripe_offset_out, +static int imgu_css_osys_calc_stripe_phase_init(int stripe_offset_out, int fir_phases, int phase_init, int phase_step, int pad_left) { int stripe_offset_inp = - ipu3_css_osys_calc_stripe_offset(stripe_offset_out, + imgu_css_osys_calc_stripe_offset(stripe_offset_out, fir_phases, phase_init, phase_step, pad_left); @@ -261,7 +262,7 @@ static int ipu3_css_osys_calc_stripe_phase_init(int stripe_offset_out, * This function calculates input frame stripe width, * based on output frame stripe offset and filter parameters */ -static int ipu3_css_osys_calc_inp_stripe_width(int stripe_width_out, +static int imgu_css_osys_calc_inp_stripe_width(int stripe_width_out, int fir_phases, int phase_init, int phase_step, int fir_taps, int pad_left, int pad_right) @@ -278,7 +279,7 @@ static int ipu3_css_osys_calc_inp_stripe_width(int stripe_width_out, * This function calculates output frame stripe width, basedi * on output frame stripe offset and filter parameters */ -static int ipu3_css_osys_out_stripe_width(int stripe_width_inp, int fir_phases, +static int imgu_css_osys_out_stripe_width(int stripe_width_inp, int fir_phases, int phase_init, int phase_step, int fir_taps, int pad_left, int pad_right, int column_offset) @@ -291,7 +292,7 @@ static int ipu3_css_osys_out_stripe_width(int stripe_width_inp, int fir_phases, return stripe_width_out - (fir_taps - 1); } -struct ipu3_css_reso { +struct imgu_css_reso { unsigned int input_width; unsigned int input_height; enum imgu_abi_frame_format input_format; @@ -305,7 +306,7 @@ struct ipu3_css_reso { int block_width; }; -struct ipu3_css_frame_params { +struct imgu_css_frame_params { /* Output pins */ unsigned int enable; unsigned int format; @@ -321,7 +322,7 @@ struct ipu3_css_frame_params { unsigned int crop_top; }; -struct ipu3_css_stripe_params { +struct imgu_css_stripe_params { unsigned int processing_mode; unsigned int phase_step; unsigned int exp_shift; @@ -358,20 +359,20 @@ struct ipu3_css_stripe_params { * frame_params - size IMGU_ABI_OSYS_PINS * stripe_params - size IPU3_UAPI_MAX_STRIPES */ -static int ipu3_css_osys_calc_frame_and_stripe_params( - struct ipu3_css *css, unsigned int stripes, +static int imgu_css_osys_calc_frame_and_stripe_params( + struct imgu_css *css, unsigned int stripes, struct imgu_abi_osys_config *osys, - struct ipu3_css_scaler_info *scaler_luma, - struct ipu3_css_scaler_info *scaler_chroma, - struct ipu3_css_frame_params frame_params[], - struct ipu3_css_stripe_params stripe_params[], + struct imgu_css_scaler_info *scaler_luma, + struct imgu_css_scaler_info *scaler_chroma, + struct imgu_css_frame_params frame_params[], + struct imgu_css_stripe_params stripe_params[], unsigned int pipe) { - struct ipu3_css_reso reso; + struct imgu_css_reso reso; unsigned int output_width, pin, s; u32 input_width, input_height, target_width, target_height; unsigned int procmode = 0; - struct ipu3_css_pipe *css_pipe = &css->pipes[pipe]; + struct imgu_css_pipe *css_pipe = &css->pipes[pipe]; input_width = css_pipe->rect[IPU3_CSS_RECT_GDC].width; input_height = css_pipe->rect[IPU3_CSS_RECT_GDC].height; @@ -463,7 +464,7 @@ static int ipu3_css_osys_calc_frame_and_stripe_params( scaled = 1; } } - ipu3_css_osys_set_format(reso.pin_format[pin], &format, + imgu_css_osys_set_format(reso.pin_format[pin], &format, &tiling); } else { enable = 0; @@ -475,7 +476,7 @@ static int ipu3_css_osys_calc_frame_and_stripe_params( frame_params[pin].scaled = scaled; } - ipu3_css_scaler_calc(input_width, input_height, target_width, + imgu_css_scaler_calc(input_width, input_height, target_width, target_height, osys, scaler_luma, scaler_chroma, &reso.pin_width[IMGU_ABI_OSYS_PIN_VF], &reso.pin_height[IMGU_ABI_OSYS_PIN_VF], &procmode); @@ -580,14 +581,14 @@ static int ipu3_css_osys_calc_frame_and_stripe_params( stripe_offset_out_uv = stripe_offset_out_y / IMGU_LUMA_TO_CHROMA_RATIO; stripe_offset_inp_y = - ipu3_css_osys_calc_stripe_offset( + imgu_css_osys_calc_stripe_offset( stripe_offset_out_y, IMGU_OSYS_FIR_PHASES, scaler_luma->phase_init, scaler_luma->phase_step, scaler_luma->pad_left); stripe_offset_inp_uv = - ipu3_css_osys_calc_stripe_offset( + imgu_css_osys_calc_stripe_offset( stripe_offset_out_uv, IMGU_OSYS_FIR_PHASES, scaler_chroma->phase_init, @@ -596,14 +597,14 @@ static int ipu3_css_osys_calc_frame_and_stripe_params( /* Calculate stripe phase init */ stripe_phase_init_y = - ipu3_css_osys_calc_stripe_phase_init( + imgu_css_osys_calc_stripe_phase_init( stripe_offset_out_y, IMGU_OSYS_FIR_PHASES, scaler_luma->phase_init, scaler_luma->phase_step, scaler_luma->pad_left); stripe_phase_init_uv = - ipu3_css_osys_calc_stripe_phase_init( + imgu_css_osys_calc_stripe_phase_init( stripe_offset_out_uv, IMGU_OSYS_FIR_PHASES, scaler_chroma->phase_init, @@ -707,7 +708,7 @@ static int ipu3_css_osys_calc_frame_and_stripe_params( IMGU_LUMA_TO_CHROMA_RATIO; /* Calculate input stripe width */ stripe_input_width_y = stripe_offset_col_y + - ipu3_css_osys_calc_inp_stripe_width( + imgu_css_osys_calc_inp_stripe_width( stripe_output_width_y, IMGU_OSYS_FIR_PHASES, stripe_phase_init_y, @@ -717,7 +718,7 @@ static int ipu3_css_osys_calc_frame_and_stripe_params( stripe_pad_right_y); stripe_input_width_uv = stripe_offset_col_uv + - ipu3_css_osys_calc_inp_stripe_width( + imgu_css_osys_calc_inp_stripe_width( stripe_output_width_uv, IMGU_OSYS_FIR_PHASES, stripe_phase_init_uv, @@ -752,7 +753,7 @@ static int ipu3_css_osys_calc_frame_and_stripe_params( */ stripe_input_width_y = ALIGN(stripe_input_width_y, 8); stripe_output_width_y = - ipu3_css_osys_out_stripe_width( + imgu_css_osys_out_stripe_width( stripe_input_width_y, IMGU_OSYS_FIR_PHASES, stripe_phase_init_y, @@ -846,23 +847,23 @@ static int ipu3_css_osys_calc_frame_and_stripe_params( * This function configures the Output Formatter System, given the number of * stripes, scaler luma and chrome parameters */ -static int ipu3_css_osys_calc(struct ipu3_css *css, unsigned int pipe, +static int imgu_css_osys_calc(struct imgu_css *css, unsigned int pipe, unsigned int stripes, struct imgu_abi_osys_config *osys, - struct ipu3_css_scaler_info *scaler_luma, - struct ipu3_css_scaler_info *scaler_chroma, + struct imgu_css_scaler_info *scaler_luma, + struct imgu_css_scaler_info *scaler_chroma, struct imgu_abi_stripes block_stripes[]) { - struct ipu3_css_frame_params frame_params[IMGU_ABI_OSYS_PINS]; - struct ipu3_css_stripe_params stripe_params[IPU3_UAPI_MAX_STRIPES]; + struct imgu_css_frame_params frame_params[IMGU_ABI_OSYS_PINS]; + struct imgu_css_stripe_params stripe_params[IPU3_UAPI_MAX_STRIPES]; struct imgu_abi_osys_formatter_params *param; unsigned int pin, s; - struct ipu3_css_pipe *css_pipe = &css->pipes[pipe]; + struct imgu_css_pipe *css_pipe = &css->pipes[pipe]; memset(osys, 0, sizeof(*osys)); /* Compute the frame and stripe params */ - if (ipu3_css_osys_calc_frame_and_stripe_params(css, stripes, osys, + if (imgu_css_osys_calc_frame_and_stripe_params(css, stripes, osys, scaler_luma, scaler_chroma, frame_params, @@ -1251,7 +1252,7 @@ static int ipu3_css_osys_calc(struct ipu3_css *css, unsigned int pipe, */ static int -ipu3_css_shd_ops_calc(struct imgu_abi_shd_intra_frame_operations_data *ops, +imgu_css_shd_ops_calc(struct imgu_abi_shd_intra_frame_operations_data *ops, const struct ipu3_uapi_shd_grid_config *grid, unsigned int image_height) { @@ -1495,7 +1496,7 @@ struct process_lines { /* Helper to config intra_frame_operations_data. */ static int -ipu3_css_acc_process_lines(const struct process_lines *pl, +imgu_css_acc_process_lines(const struct process_lines *pl, struct imgu_abi_acc_operation *p_op, struct imgu_abi_acc_process_lines_cmd_data *p_pl, struct imgu_abi_acc_transfer_op_data *p_tr) @@ -1632,12 +1633,12 @@ ipu3_css_acc_process_lines(const struct process_lines *pl, return 0; } -static int ipu3_css_af_ops_calc(struct ipu3_css *css, unsigned int pipe, +static int imgu_css_af_ops_calc(struct imgu_css *css, unsigned int pipe, struct imgu_abi_af_config *af_config) { struct imgu_abi_af_intra_frame_operations_data *to = &af_config->operations_data; - struct ipu3_css_pipe *css_pipe = &css->pipes[pipe]; + struct imgu_css_pipe *css_pipe = &css->pipes[pipe]; struct imgu_fw_info *bi = &css->fwp->binary_header[css_pipe->bindex]; @@ -1655,17 +1656,17 @@ static int ipu3_css_af_ops_calc(struct ipu3_css *css, unsigned int pipe, .acc_enable = bi->info.isp.sp.enable.af, }; - return ipu3_css_acc_process_lines(&pl, to->ops, to->process_lines_data, + return imgu_css_acc_process_lines(&pl, to->ops, to->process_lines_data, NULL); } static int -ipu3_css_awb_fr_ops_calc(struct ipu3_css *css, unsigned int pipe, +imgu_css_awb_fr_ops_calc(struct imgu_css *css, unsigned int pipe, struct imgu_abi_awb_fr_config *awb_fr_config) { struct imgu_abi_awb_fr_intra_frame_operations_data *to = &awb_fr_config->operations_data; - struct ipu3_css_pipe *css_pipe = &css->pipes[pipe]; + struct imgu_css_pipe *css_pipe = &css->pipes[pipe]; struct imgu_fw_info *bi = &css->fwp->binary_header[css_pipe->bindex]; struct process_lines pl = { @@ -1682,16 +1683,16 @@ ipu3_css_awb_fr_ops_calc(struct ipu3_css *css, unsigned int pipe, .acc_enable = bi->info.isp.sp.enable.awb_fr_acc, }; - return ipu3_css_acc_process_lines(&pl, to->ops, to->process_lines_data, + return imgu_css_acc_process_lines(&pl, to->ops, to->process_lines_data, NULL); } -static int ipu3_css_awb_ops_calc(struct ipu3_css *css, unsigned int pipe, +static int imgu_css_awb_ops_calc(struct imgu_css *css, unsigned int pipe, struct imgu_abi_awb_config *awb_config) { struct imgu_abi_awb_intra_frame_operations_data *to = &awb_config->operations_data; - struct ipu3_css_pipe *css_pipe = &css->pipes[pipe]; + struct imgu_css_pipe *css_pipe = &css->pipes[pipe]; struct imgu_fw_info *bi = &css->fwp->binary_header[css_pipe->bindex]; @@ -1708,33 +1709,33 @@ static int ipu3_css_awb_ops_calc(struct ipu3_css *css, unsigned int pipe, .acc_enable = bi->info.isp.sp.enable.awb_acc, }; - return ipu3_css_acc_process_lines(&pl, to->ops, to->process_lines_data, + return imgu_css_acc_process_lines(&pl, to->ops, to->process_lines_data, to->transfer_data); } -static u16 ipu3_css_grid_end(u16 start, u8 width, u8 block_width_log2) +static u16 imgu_css_grid_end(u16 start, u8 width, u8 block_width_log2) { return (start & IPU3_UAPI_GRID_START_MASK) + (width << block_width_log2) - 1; } -static void ipu3_css_grid_end_calc(struct ipu3_uapi_grid_config *grid_cfg) +static void imgu_css_grid_end_calc(struct ipu3_uapi_grid_config *grid_cfg) { - grid_cfg->x_end = ipu3_css_grid_end(grid_cfg->x_start, grid_cfg->width, + grid_cfg->x_end = imgu_css_grid_end(grid_cfg->x_start, grid_cfg->width, grid_cfg->block_width_log2); - grid_cfg->y_end = ipu3_css_grid_end(grid_cfg->y_start, grid_cfg->height, + grid_cfg->y_end = imgu_css_grid_end(grid_cfg->y_start, grid_cfg->height, grid_cfg->block_height_log2); } /****************** config computation *****************************/ -static int ipu3_css_cfg_acc_stripe(struct ipu3_css *css, unsigned int pipe, +static int imgu_css_cfg_acc_stripe(struct imgu_css *css, unsigned int pipe, struct imgu_abi_acc_param *acc) { - struct ipu3_css_pipe *css_pipe = &css->pipes[pipe]; + struct imgu_css_pipe *css_pipe = &css->pipes[pipe]; const struct imgu_fw_info *bi = &css->fwp->binary_header[css_pipe->bindex]; - struct ipu3_css_scaler_info scaler_luma, scaler_chroma; + struct imgu_css_scaler_info scaler_luma, scaler_chroma; const unsigned int stripes = bi->info.isp.sp.iterator.num_stripes; const unsigned int f = IPU3_UAPI_ISP_VEC_ELEMS * 2; unsigned int bds_ds, i; @@ -1743,7 +1744,7 @@ static int ipu3_css_cfg_acc_stripe(struct ipu3_css *css, unsigned int pipe, /* acc_param: osys_config */ - if (ipu3_css_osys_calc(css, pipe, stripes, &acc->osys, &scaler_luma, + if (imgu_css_osys_calc(css, pipe, stripes, &acc->osys, &scaler_luma, &scaler_chroma, acc->stripe.block_stripes)) return -EINVAL; @@ -1900,12 +1901,12 @@ static int ipu3_css_cfg_acc_stripe(struct ipu3_css *css, unsigned int pipe, return 0; } -static void ipu3_css_cfg_acc_dvs(struct ipu3_css *css, +static void imgu_css_cfg_acc_dvs(struct imgu_css *css, struct imgu_abi_acc_param *acc, unsigned int pipe) { unsigned int i; - struct ipu3_css_pipe *css_pipe = &css->pipes[pipe]; + struct imgu_css_pipe *css_pipe = &css->pipes[pipe]; /* Disable DVS statistics */ acc->dvs_stat.operations_data.process_lines_data[0].lines = @@ -1919,11 +1920,11 @@ static void ipu3_css_cfg_acc_dvs(struct ipu3_css *css, acc->dvs_stat.cfg.grd_config[i].enable = 0; } -static void acc_bds_per_stripe_data(struct ipu3_css *css, +static void acc_bds_per_stripe_data(struct imgu_css *css, struct imgu_abi_acc_param *acc, const int i, unsigned int pipe) { - struct ipu3_css_pipe *css_pipe = &css->pipes[pipe]; + struct imgu_css_pipe *css_pipe = &css->pipes[pipe]; acc->bds.per_stripe.aligned_data[i].data.crop.hor_crop_en = 0; acc->bds.per_stripe.aligned_data[i].data.crop.hor_crop_start = 0; @@ -1944,13 +1945,13 @@ static void acc_bds_per_stripe_data(struct ipu3_css *css, * telling which fields to take from the old values (or generate if it is NULL) * and which to take from the new user values. */ -int ipu3_css_cfg_acc(struct ipu3_css *css, unsigned int pipe, +int imgu_css_cfg_acc(struct imgu_css *css, unsigned int pipe, struct ipu3_uapi_flags *use, struct imgu_abi_acc_param *acc, struct imgu_abi_acc_param *acc_old, struct ipu3_uapi_acc_param *acc_user) { - struct ipu3_css_pipe *css_pipe = &css->pipes[pipe]; + struct imgu_css_pipe *css_pipe = &css->pipes[pipe]; const struct imgu_fw_info *bi = &css->fwp->binary_header[css_pipe->bindex]; const unsigned int stripes = bi->info.isp.sp.iterator.num_stripes; @@ -1959,7 +1960,7 @@ int ipu3_css_cfg_acc(struct ipu3_css *css, unsigned int pipe, const unsigned int min_overlap = 10; const struct v4l2_pix_format_mplane *pixm = &css_pipe->queue[IPU3_CSS_QUEUE_IN].fmt.mpix; - const struct ipu3_css_bds_config *cfg_bds; + const struct imgu_css_bds_config *cfg_bds; struct imgu_abi_input_feeder_data *feeder_data; unsigned int bds_ds, ofs_x, ofs_y, i, width, height; @@ -1967,7 +1968,7 @@ int ipu3_css_cfg_acc(struct ipu3_css *css, unsigned int pipe, /* Update stripe using chroma and luma */ - if (ipu3_css_cfg_acc_stripe(css, pipe, acc)) + if (imgu_css_cfg_acc_stripe(css, pipe, acc)) return -EINVAL; /* acc_param: input_feeder_config */ @@ -2021,7 +2022,7 @@ int ipu3_css_cfg_acc(struct ipu3_css *css, unsigned int pipe, acc->bnr = acc_old->bnr; } else { /* Calculate from scratch */ - acc->bnr = ipu3_css_bnr_defaults; + acc->bnr = imgu_css_bnr_defaults; } acc->bnr.column_size = tnr_frame_width; @@ -2049,7 +2050,7 @@ int ipu3_css_cfg_acc(struct ipu3_css *css, unsigned int pipe, acc->dm = acc_old->dm; } else { /* Calculate from scratch */ - acc->dm = ipu3_css_dm_defaults; + acc->dm = imgu_css_dm_defaults; } acc->dm.frame_width = tnr_frame_width; @@ -2064,7 +2065,7 @@ int ipu3_css_cfg_acc(struct ipu3_css *css, unsigned int pipe, acc->ccm = acc_old->ccm; } else { /* Calculate from scratch */ - acc->ccm = ipu3_css_ccm_defaults; + acc->ccm = imgu_css_ccm_defaults; } /* acc_param: gamma_config */ @@ -2078,7 +2079,7 @@ int ipu3_css_cfg_acc(struct ipu3_css *css, unsigned int pipe, } else { /* Calculate from scratch */ acc->gamma.gc_ctrl.enable = 1; - acc->gamma.gc_lut = ipu3_css_gamma_lut; + acc->gamma.gc_lut = imgu_css_gamma_lut; } /* acc_param: csc_mat_config */ @@ -2091,7 +2092,7 @@ int ipu3_css_cfg_acc(struct ipu3_css *css, unsigned int pipe, acc->csc = acc_old->csc; } else { /* Calculate from scratch */ - acc->csc = ipu3_css_csc_defaults; + acc->csc = imgu_css_csc_defaults; } /* acc_param: cds_params */ @@ -2104,7 +2105,7 @@ int ipu3_css_cfg_acc(struct ipu3_css *css, unsigned int pipe, acc->cds = acc_old->cds; } else { /* Calculate from scratch */ - acc->cds = ipu3_css_cds_defaults; + acc->cds = imgu_css_cds_defaults; } /* acc_param: shd_config */ @@ -2119,7 +2120,7 @@ int ipu3_css_cfg_acc(struct ipu3_css *css, unsigned int pipe, acc->shd.shd_lut = acc_old->shd.shd_lut; } else { /* Calculate from scratch */ - acc->shd.shd = ipu3_css_shd_defaults; + acc->shd.shd = imgu_css_shd_defaults; memset(&acc->shd.shd_lut, 0, sizeof(acc->shd.shd_lut)); } @@ -2137,12 +2138,12 @@ int ipu3_css_cfg_acc(struct ipu3_css *css, unsigned int pipe, acc->shd.shd.grid.block_height_log2) % acc->shd.shd.grid.grid_height_per_slice; - if (ipu3_css_shd_ops_calc(&acc->shd.shd_ops, &acc->shd.shd.grid, + if (imgu_css_shd_ops_calc(&acc->shd.shd_ops, &acc->shd.shd.grid, css_pipe->rect[IPU3_CSS_RECT_BDS].height)) return -EINVAL; /* acc_param: dvs_stat_config */ - ipu3_css_cfg_acc_dvs(css, acc, pipe); + imgu_css_cfg_acc_dvs(css, acc, pipe); /* acc_param: yuvp1_iefd_config */ @@ -2154,7 +2155,7 @@ int ipu3_css_cfg_acc(struct ipu3_css *css, unsigned int pipe, acc->iefd = acc_old->iefd; } else { /* Calculate from scratch */ - acc->iefd = ipu3_css_iefd_defaults; + acc->iefd = imgu_css_iefd_defaults; } /* acc_param: yuvp1_yds_config yds_c0 */ @@ -2167,7 +2168,7 @@ int ipu3_css_cfg_acc(struct ipu3_css *css, unsigned int pipe, acc->yds_c0 = acc_old->yds_c0; } else { /* Calculate from scratch */ - acc->yds_c0 = ipu3_css_yds_defaults; + acc->yds_c0 = imgu_css_yds_defaults; } /* acc_param: yuvp1_chnr_config chnr_c0 */ @@ -2180,7 +2181,7 @@ int ipu3_css_cfg_acc(struct ipu3_css *css, unsigned int pipe, acc->chnr_c0 = acc_old->chnr_c0; } else { /* Calculate from scratch */ - acc->chnr_c0 = ipu3_css_chnr_defaults; + acc->chnr_c0 = imgu_css_chnr_defaults; } /* acc_param: yuvp1_y_ee_nr_config */ @@ -2193,7 +2194,7 @@ int ipu3_css_cfg_acc(struct ipu3_css *css, unsigned int pipe, acc->y_ee_nr = acc_old->y_ee_nr; } else { /* Calculate from scratch */ - acc->y_ee_nr = ipu3_css_y_ee_nr_defaults; + acc->y_ee_nr = imgu_css_y_ee_nr_defaults; } /* acc_param: yuvp1_yds_config yds */ @@ -2206,7 +2207,7 @@ int ipu3_css_cfg_acc(struct ipu3_css *css, unsigned int pipe, acc->yds = acc_old->yds; } else { /* Calculate from scratch */ - acc->yds = ipu3_css_yds_defaults; + acc->yds = imgu_css_yds_defaults; } /* acc_param: yuvp1_chnr_config chnr */ @@ -2219,7 +2220,7 @@ int ipu3_css_cfg_acc(struct ipu3_css *css, unsigned int pipe, acc->chnr = acc_old->chnr; } else { /* Calculate from scratch */ - acc->chnr = ipu3_css_chnr_defaults; + acc->chnr = imgu_css_chnr_defaults; } /* acc_param: yuvp2_y_tm_lut_static_config */ @@ -2238,7 +2239,7 @@ int ipu3_css_cfg_acc(struct ipu3_css *css, unsigned int pipe, acc->yds2 = acc_old->yds2; } else { /* Calculate from scratch */ - acc->yds2 = ipu3_css_yds_defaults; + acc->yds2 = imgu_css_yds_defaults; } /* acc_param: yuvp2_tcc_static_config */ @@ -2270,8 +2271,8 @@ int ipu3_css_cfg_acc(struct ipu3_css *css, unsigned int pipe, for (i = 7; i < IPU3_UAPI_YUVP2_TCC_INV_Y_LUT_ELEMENTS; i++) acc->tcc.inv_y_lut.entries[i] = 1024 >> (i - 6); - acc->tcc.gain_pcwl = ipu3_css_tcc_gain_pcwl_lut; - acc->tcc.r_sqr_lut = ipu3_css_tcc_r_sqr_lut; + acc->tcc.gain_pcwl = imgu_css_tcc_gain_pcwl_lut; + acc->tcc.r_sqr_lut = imgu_css_tcc_r_sqr_lut; } /* acc_param: dpc_config */ @@ -2287,10 +2288,10 @@ int ipu3_css_cfg_acc(struct ipu3_css *css, unsigned int pipe, bds_ds = (css_pipe->rect[IPU3_CSS_RECT_EFFECTIVE].height * IMGU_BDS_GRANULARITY) / css_pipe->rect[IPU3_CSS_RECT_BDS].height; if (bds_ds < IMGU_BDS_MIN_SF_INV || - bds_ds - IMGU_BDS_MIN_SF_INV >= ARRAY_SIZE(ipu3_css_bds_configs)) + bds_ds - IMGU_BDS_MIN_SF_INV >= ARRAY_SIZE(imgu_css_bds_configs)) return -EINVAL; - cfg_bds = &ipu3_css_bds_configs[bds_ds - IMGU_BDS_MIN_SF_INV]; + cfg_bds = &imgu_css_bds_configs[bds_ds - IMGU_BDS_MIN_SF_INV]; acc->bds.hor.hor_ctrl1.hor_crop_en = 0; acc->bds.hor.hor_ctrl1.hor_crop_start = 0; acc->bds.hor.hor_ctrl1.hor_crop_end = 0; @@ -2339,7 +2340,7 @@ int ipu3_css_cfg_acc(struct ipu3_css *css, unsigned int pipe, sizeof(acc->anr.stitch.pyramid)); } else { /* Calculate from scratch */ - acc->anr = ipu3_css_anr_defaults; + acc->anr = imgu_css_anr_defaults; } /* Always enabled */ @@ -2377,10 +2378,10 @@ int ipu3_css_cfg_acc(struct ipu3_css *css, unsigned int pipe, acc->awb_fr.config = acc_old->awb_fr.config; } else { /* Set from scratch */ - acc->awb_fr.config = ipu3_css_awb_fr_defaults; + acc->awb_fr.config = imgu_css_awb_fr_defaults; } - ipu3_css_grid_end_calc(&acc->awb_fr.config.grid_cfg); + imgu_css_grid_end_calc(&acc->awb_fr.config.grid_cfg); if (acc->awb_fr.config.grid_cfg.width <= 0) return -EINVAL; @@ -2415,7 +2416,7 @@ int ipu3_css_cfg_acc(struct ipu3_css *css, unsigned int pipe, acc->awb_fr.stripes[0].grid_cfg.width; b_w_log2 = acc->awb_fr.stripes[0].grid_cfg.block_width_log2; - end = ipu3_css_grid_end(acc->awb_fr.stripes[0].grid_cfg.x_start, + end = imgu_css_grid_end(acc->awb_fr.stripes[0].grid_cfg.x_start, acc->awb_fr.stripes[0].grid_cfg.width, b_w_log2); acc->awb_fr.stripes[0].grid_cfg.x_end = end; @@ -2425,7 +2426,7 @@ int ipu3_css_cfg_acc(struct ipu3_css *css, unsigned int pipe, acc->stripe.down_scaled_stripes[1].offset) & IPU3_UAPI_GRID_START_MASK; b_w_log2 = acc->awb_fr.stripes[1].grid_cfg.block_width_log2; - end = ipu3_css_grid_end(acc->awb_fr.stripes[1].grid_cfg.x_start, + end = imgu_css_grid_end(acc->awb_fr.stripes[1].grid_cfg.x_start, acc->awb_fr.stripes[1].grid_cfg.width, b_w_log2); acc->awb_fr.stripes[1].grid_cfg.x_end = end; @@ -2439,7 +2440,7 @@ int ipu3_css_cfg_acc(struct ipu3_css *css, unsigned int pipe, acc->awb_fr.stripes[i].grid_cfg.height_per_slice = 1; } - if (ipu3_css_awb_fr_ops_calc(css, pipe, &acc->awb_fr)) + if (imgu_css_awb_fr_ops_calc(css, pipe, &acc->awb_fr)) return -EINVAL; /* acc_param: ae_config */ @@ -2461,18 +2462,18 @@ int ipu3_css_cfg_acc(struct ipu3_css *css, unsigned int pipe, static const struct ipu3_uapi_ae_weight_elem weight_def = { 1, 1, 1, 1, 1, 1, 1, 1 }; - acc->ae.grid_cfg = ipu3_css_ae_grid_defaults; - acc->ae.ae_ccm = ipu3_css_ae_ccm_defaults; + acc->ae.grid_cfg = imgu_css_ae_grid_defaults; + acc->ae.ae_ccm = imgu_css_ae_ccm_defaults; for (i = 0; i < IPU3_UAPI_AE_WEIGHTS; i++) acc->ae.weights[i] = weight_def; } b_w_log2 = acc->ae.grid_cfg.block_width_log2; - acc->ae.grid_cfg.x_end = ipu3_css_grid_end(acc->ae.grid_cfg.x_start, + acc->ae.grid_cfg.x_end = imgu_css_grid_end(acc->ae.grid_cfg.x_start, acc->ae.grid_cfg.width, b_w_log2); b_w_log2 = acc->ae.grid_cfg.block_height_log2; - acc->ae.grid_cfg.y_end = ipu3_css_grid_end(acc->ae.grid_cfg.y_start, + acc->ae.grid_cfg.y_end = imgu_css_grid_end(acc->ae.grid_cfg.y_start, acc->ae.grid_cfg.height, b_w_log2); @@ -2501,7 +2502,7 @@ int ipu3_css_cfg_acc(struct ipu3_css *css, unsigned int pipe, b_w_log2 = acc->ae.stripes[0].grid.block_width_log2; acc->ae.stripes[0].grid.x_end = - ipu3_css_grid_end(acc->ae.stripes[0].grid.x_start, + imgu_css_grid_end(acc->ae.stripes[0].grid.x_start, acc->ae.stripes[0].grid.width, b_w_log2); @@ -2511,7 +2512,7 @@ int ipu3_css_cfg_acc(struct ipu3_css *css, unsigned int pipe, IPU3_UAPI_GRID_START_MASK; b_w_log2 = acc->ae.stripes[1].grid.block_width_log2; acc->ae.stripes[1].grid.x_end = - ipu3_css_grid_end(acc->ae.stripes[1].grid.x_start, + imgu_css_grid_end(acc->ae.stripes[1].grid.x_start, acc->ae.stripes[1].grid.width, b_w_log2); } @@ -2528,11 +2529,11 @@ int ipu3_css_cfg_acc(struct ipu3_css *css, unsigned int pipe, } else { /* Set from scratch */ acc->af.config.filter_config = - ipu3_css_af_defaults.filter_config; - acc->af.config.grid_cfg = ipu3_css_af_defaults.grid_cfg; + imgu_css_af_defaults.filter_config; + acc->af.config.grid_cfg = imgu_css_af_defaults.grid_cfg; } - ipu3_css_grid_end_calc(&acc->af.config.grid_cfg); + imgu_css_grid_end_calc(&acc->af.config.grid_cfg); if (acc->af.config.grid_cfg.width <= 0) return -EINVAL; @@ -2578,7 +2579,7 @@ int ipu3_css_cfg_acc(struct ipu3_css *css, unsigned int pipe, b_w_log2 = acc->af.stripes[0].grid_cfg.block_width_log2; acc->af.stripes[0].grid_cfg.x_end = - ipu3_css_grid_end(acc->af.stripes[0].grid_cfg.x_start, + imgu_css_grid_end(acc->af.stripes[0].grid_cfg.x_start, acc->af.stripes[0].grid_cfg.width, b_w_log2); @@ -2589,7 +2590,7 @@ int ipu3_css_cfg_acc(struct ipu3_css *css, unsigned int pipe, b_w_log2 = acc->af.stripes[1].grid_cfg.block_width_log2; acc->af.stripes[1].grid_cfg.x_end = - ipu3_css_grid_end(acc->af.stripes[1].grid_cfg.x_start, + imgu_css_grid_end(acc->af.stripes[1].grid_cfg.x_start, acc->af.stripes[1].grid_cfg.width, b_w_log2); @@ -2601,7 +2602,7 @@ int ipu3_css_cfg_acc(struct ipu3_css *css, unsigned int pipe, acc->af.stripes[i].grid_cfg.height_per_slice = 1; } - if (ipu3_css_af_ops_calc(css, pipe, &acc->af)) + if (imgu_css_af_ops_calc(css, pipe, &acc->af)) return -EINVAL; /* acc_param: awb_config */ @@ -2614,7 +2615,7 @@ int ipu3_css_cfg_acc(struct ipu3_css *css, unsigned int pipe, acc->awb.config = acc_old->awb.config; } else { /* Set from scratch */ - acc->awb.config = ipu3_css_awb_defaults; + acc->awb.config = imgu_css_awb_defaults; } if (acc->awb.config.grid.width <= 0) @@ -2622,7 +2623,7 @@ int ipu3_css_cfg_acc(struct ipu3_css *css, unsigned int pipe, acc->awb.config.grid.height_per_slice = IMGU_ABI_AWB_MAX_CELLS_PER_SET / acc->awb.config.grid.width, - ipu3_css_grid_end_calc(&acc->awb.config.grid); + imgu_css_grid_end_calc(&acc->awb.config.grid); for (i = 0; i < stripes; i++) acc->awb.stripes[i] = acc->awb.config; @@ -2647,7 +2648,7 @@ int ipu3_css_cfg_acc(struct ipu3_css *css, unsigned int pipe, b_w_log2 = acc->awb.stripes[0].grid.block_width_log2; acc->awb.stripes[0].grid.x_end = - ipu3_css_grid_end(acc->awb.stripes[0].grid.x_start, + imgu_css_grid_end(acc->awb.stripes[0].grid.x_start, acc->awb.stripes[0].grid.width, b_w_log2); @@ -2658,7 +2659,7 @@ int ipu3_css_cfg_acc(struct ipu3_css *css, unsigned int pipe, b_w_log2 = acc->awb.stripes[1].grid.block_width_log2; acc->awb.stripes[1].grid.x_end = - ipu3_css_grid_end(acc->awb.stripes[1].grid.x_start, + imgu_css_grid_end(acc->awb.stripes[1].grid.x_start, acc->awb.stripes[1].grid.width, b_w_log2); @@ -2670,7 +2671,7 @@ int ipu3_css_cfg_acc(struct ipu3_css *css, unsigned int pipe, acc->awb.stripes[i].grid.height_per_slice = 1; } - if (ipu3_css_awb_ops_calc(css, pipe, &acc->awb)) + if (imgu_css_awb_ops_calc(css, pipe, &acc->awb)) return -EINVAL; return 0; @@ -2685,7 +2686,7 @@ int ipu3_css_cfg_acc(struct ipu3_css *css, unsigned int pipe, * to the structure inside `new_binary_params'. In that case the caller * should calculate and fill the structure from scratch. */ -static void *ipu3_css_cfg_copy(struct ipu3_css *css, +static void *imgu_css_cfg_copy(struct imgu_css *css, unsigned int pipe, bool use_user, void *user_setting, void *old_binary_params, void *new_binary_params, @@ -2696,7 +2697,7 @@ static void *ipu3_css_cfg_copy(struct ipu3_css *css, const enum imgu_abi_param_class c = IMGU_ABI_PARAM_CLASS_PARAM; void *new_setting, *old_setting; - new_setting = ipu3_css_fw_pipeline_params(css, pipe, c, m, par, + new_setting = imgu_css_fw_pipeline_params(css, pipe, c, m, par, par_size, new_binary_params); if (!new_setting) return ERR_PTR(-EPROTO); /* Corrupted firmware */ @@ -2706,7 +2707,7 @@ static void *ipu3_css_cfg_copy(struct ipu3_css *css, memcpy(new_setting, user_setting, par_size); } else if (old_binary_params) { /* Take previous value */ - old_setting = ipu3_css_fw_pipeline_params(css, pipe, c, m, par, + old_setting = imgu_css_fw_pipeline_params(css, pipe, c, m, par, par_size, old_binary_params); if (!old_setting) @@ -2722,7 +2723,7 @@ static void *ipu3_css_cfg_copy(struct ipu3_css *css, /* * Configure VMEM0 parameters (late binding parameters). */ -int ipu3_css_cfg_vmem0(struct ipu3_css *css, unsigned int pipe, +int imgu_css_cfg_vmem0(struct imgu_css *css, unsigned int pipe, struct ipu3_uapi_flags *use, void *vmem0, void *vmem0_old, struct ipu3_uapi_params *user) @@ -2744,7 +2745,7 @@ int ipu3_css_cfg_vmem0(struct ipu3_css *css, unsigned int pipe, /* Configure Linearization VMEM0 parameters */ - lin_vmem = ipu3_css_cfg_copy(css, pipe, use && use->lin_vmem_params, + lin_vmem = imgu_css_cfg_copy(css, pipe, use && use->lin_vmem_params, &user->lin_vmem_params, vmem0_old, vmem0, m, &pofs->vmem.lin, sizeof(*lin_vmem)); if (!IS_ERR_OR_NULL(lin_vmem)) { @@ -2764,7 +2765,7 @@ int ipu3_css_cfg_vmem0(struct ipu3_css *css, unsigned int pipe, /* Configure TNR3 VMEM parameters */ if (css->pipes[pipe].pipe_id == IPU3_CSS_PIPE_ID_VIDEO) { - tnr_vmem = ipu3_css_cfg_copy(css, pipe, + tnr_vmem = imgu_css_cfg_copy(css, pipe, use && use->tnr3_vmem_params, &user->tnr3_vmem_params, vmem0_old, vmem0, m, @@ -2780,17 +2781,17 @@ int ipu3_css_cfg_vmem0(struct ipu3_css *css, unsigned int pipe, /* Configure XNR3 VMEM parameters */ - xnr_vmem = ipu3_css_cfg_copy(css, pipe, use && use->xnr3_vmem_params, + xnr_vmem = imgu_css_cfg_copy(css, pipe, use && use->xnr3_vmem_params, &user->xnr3_vmem_params, vmem0_old, vmem0, m, &pofs->vmem.xnr3, sizeof(*xnr_vmem)); if (!IS_ERR_OR_NULL(xnr_vmem)) { - xnr_vmem->x[i] = ipu3_css_xnr3_vmem_defaults.x + xnr_vmem->x[i] = imgu_css_xnr3_vmem_defaults.x [i % IMGU_XNR3_VMEM_LUT_LEN]; - xnr_vmem->a[i] = ipu3_css_xnr3_vmem_defaults.a + xnr_vmem->a[i] = imgu_css_xnr3_vmem_defaults.a [i % IMGU_XNR3_VMEM_LUT_LEN]; - xnr_vmem->b[i] = ipu3_css_xnr3_vmem_defaults.b + xnr_vmem->b[i] = imgu_css_xnr3_vmem_defaults.b [i % IMGU_XNR3_VMEM_LUT_LEN]; - xnr_vmem->c[i] = ipu3_css_xnr3_vmem_defaults.c + xnr_vmem->c[i] = imgu_css_xnr3_vmem_defaults.c [i % IMGU_XNR3_VMEM_LUT_LEN]; } @@ -2801,12 +2802,12 @@ int ipu3_css_cfg_vmem0(struct ipu3_css *css, unsigned int pipe, /* * Configure DMEM0 parameters (late binding parameters). */ -int ipu3_css_cfg_dmem0(struct ipu3_css *css, unsigned int pipe, +int imgu_css_cfg_dmem0(struct imgu_css *css, unsigned int pipe, struct ipu3_uapi_flags *use, void *dmem0, void *dmem0_old, struct ipu3_uapi_params *user) { - struct ipu3_css_pipe *css_pipe = &css->pipes[pipe]; + struct imgu_css_pipe *css_pipe = &css->pipes[pipe]; const struct imgu_fw_info *bi = &css->fwp->binary_header[css_pipe->bindex]; struct imgu_fw_param_memory_offsets *pofs = (void *)css->fwp + @@ -2824,7 +2825,7 @@ int ipu3_css_cfg_dmem0(struct ipu3_css *css, unsigned int pipe, /* Configure TNR3 DMEM0 parameters */ if (css_pipe->pipe_id == IPU3_CSS_PIPE_ID_VIDEO) { - tnr_dmem = ipu3_css_cfg_copy(css, pipe, + tnr_dmem = imgu_css_cfg_copy(css, pipe, use && use->tnr3_dmem_params, &user->tnr3_dmem_params, dmem0_old, dmem0, m, @@ -2839,7 +2840,7 @@ int ipu3_css_cfg_dmem0(struct ipu3_css *css, unsigned int pipe, /* Configure XNR3 DMEM0 parameters */ - xnr_dmem = ipu3_css_cfg_copy(css, pipe, use && use->xnr3_dmem_params, + xnr_dmem = imgu_css_cfg_copy(css, pipe, use && use->xnr3_dmem_params, &user->xnr3_dmem_params, dmem0_old, dmem0, m, &pofs->dmem.xnr3, sizeof(*xnr_dmem)); if (!IS_ERR_OR_NULL(xnr_dmem)) { @@ -2853,7 +2854,7 @@ int ipu3_css_cfg_dmem0(struct ipu3_css *css, unsigned int pipe, } /* Generate unity morphing table without morphing effect */ -void ipu3_css_cfg_gdc_table(struct imgu_abi_gdc_warp_param *gdc, +void imgu_css_cfg_gdc_table(struct imgu_abi_gdc_warp_param *gdc, int frame_in_x, int frame_in_y, int frame_out_x, int frame_out_y, int env_w, int env_h) diff --git a/drivers/staging/media/ipu3/ipu3-css-params.h b/drivers/staging/media/ipu3/ipu3-css-params.h index f3a0a47117a4..ffaec6b7d5cc 100644 --- a/drivers/staging/media/ipu3/ipu3-css-params.h +++ b/drivers/staging/media/ipu3/ipu3-css-params.h @@ -4,23 +4,23 @@ #ifndef __IPU3_PARAMS_H #define __IPU3_PARAMS_H -int ipu3_css_cfg_acc(struct ipu3_css *css, unsigned int pipe, +int imgu_css_cfg_acc(struct imgu_css *css, unsigned int pipe, struct ipu3_uapi_flags *use, struct imgu_abi_acc_param *acc, struct imgu_abi_acc_param *acc_old, struct ipu3_uapi_acc_param *acc_user); -int ipu3_css_cfg_vmem0(struct ipu3_css *css, unsigned int pipe, +int imgu_css_cfg_vmem0(struct imgu_css *css, unsigned int pipe, struct ipu3_uapi_flags *use, void *vmem0, void *vmem0_old, struct ipu3_uapi_params *user); -int ipu3_css_cfg_dmem0(struct ipu3_css *css, unsigned int pipe, +int imgu_css_cfg_dmem0(struct imgu_css *css, unsigned int pipe, struct ipu3_uapi_flags *use, void *dmem0, void *dmem0_old, struct ipu3_uapi_params *user); -void ipu3_css_cfg_gdc_table(struct imgu_abi_gdc_warp_param *gdc, +void imgu_css_cfg_gdc_table(struct imgu_abi_gdc_warp_param *gdc, int frame_in_x, int frame_in_y, int frame_out_x, int frame_out_y, int env_w, int env_h); diff --git a/drivers/staging/media/ipu3/ipu3-css-pool.c b/drivers/staging/media/ipu3/ipu3-css-pool.c index 6f271f81669b..fa5b7d3acef2 100644 --- a/drivers/staging/media/ipu3/ipu3-css-pool.c +++ b/drivers/staging/media/ipu3/ipu3-css-pool.c @@ -7,30 +7,30 @@ #include "ipu3-css-pool.h" #include "ipu3-dmamap.h" -int ipu3_css_dma_buffer_resize(struct imgu_device *imgu, - struct ipu3_css_map *map, size_t size) +int imgu_css_dma_buffer_resize(struct imgu_device *imgu, + struct imgu_css_map *map, size_t size) { if (map->size < size && map->vaddr) { dev_warn(&imgu->pci_dev->dev, "dma buf resized from %zu to %zu", map->size, size); - ipu3_dmamap_free(imgu, map); - if (!ipu3_dmamap_alloc(imgu, map, size)) + imgu_dmamap_free(imgu, map); + if (!imgu_dmamap_alloc(imgu, map, size)) return -ENOMEM; } return 0; } -void ipu3_css_pool_cleanup(struct imgu_device *imgu, struct ipu3_css_pool *pool) +void imgu_css_pool_cleanup(struct imgu_device *imgu, struct imgu_css_pool *pool) { unsigned int i; for (i = 0; i < IPU3_CSS_POOL_SIZE; i++) - ipu3_dmamap_free(imgu, &pool->entry[i].param); + imgu_dmamap_free(imgu, &pool->entry[i].param); } -int ipu3_css_pool_init(struct imgu_device *imgu, struct ipu3_css_pool *pool, +int imgu_css_pool_init(struct imgu_device *imgu, struct imgu_css_pool *pool, size_t size) { unsigned int i; @@ -42,7 +42,7 @@ int ipu3_css_pool_init(struct imgu_device *imgu, struct ipu3_css_pool *pool, continue; } - if (!ipu3_dmamap_alloc(imgu, &pool->entry[i].param, size)) + if (!imgu_dmamap_alloc(imgu, &pool->entry[i].param, size)) goto fail; } @@ -51,14 +51,14 @@ int ipu3_css_pool_init(struct imgu_device *imgu, struct ipu3_css_pool *pool, return 0; fail: - ipu3_css_pool_cleanup(imgu, pool); + imgu_css_pool_cleanup(imgu, pool); return -ENOMEM; } /* * Allocate a new parameter via recycling the oldest entry in the pool. */ -void ipu3_css_pool_get(struct ipu3_css_pool *pool) +void imgu_css_pool_get(struct imgu_css_pool *pool) { /* Get the oldest entry */ u32 n = (pool->last + 1) % IPU3_CSS_POOL_SIZE; @@ -70,25 +70,25 @@ void ipu3_css_pool_get(struct ipu3_css_pool *pool) /* * Undo, for all practical purposes, the effect of pool_get(). */ -void ipu3_css_pool_put(struct ipu3_css_pool *pool) +void imgu_css_pool_put(struct imgu_css_pool *pool) { pool->entry[pool->last].valid = false; pool->last = (pool->last + IPU3_CSS_POOL_SIZE - 1) % IPU3_CSS_POOL_SIZE; } /** - * ipu3_css_pool_last - Retrieve the nth pool entry from last + * imgu_css_pool_last - Retrieve the nth pool entry from last * - * @pool: a pointer to &struct ipu3_css_pool. + * @pool: a pointer to &struct imgu_css_pool. * @n: the distance to the last index. * * Returns: * The nth entry from last or null map to indicate no frame stored. */ -const struct ipu3_css_map * -ipu3_css_pool_last(struct ipu3_css_pool *pool, unsigned int n) +const struct imgu_css_map * +imgu_css_pool_last(struct imgu_css_pool *pool, unsigned int n) { - static const struct ipu3_css_map null_map = { 0 }; + static const struct imgu_css_map null_map = { 0 }; int i = (pool->last + IPU3_CSS_POOL_SIZE - n) % IPU3_CSS_POOL_SIZE; WARN_ON(n >= IPU3_CSS_POOL_SIZE); diff --git a/drivers/staging/media/ipu3/ipu3-css-pool.h b/drivers/staging/media/ipu3/ipu3-css-pool.h index 2657c39a4d71..f4a60b41401b 100644 --- a/drivers/staging/media/ipu3/ipu3-css-pool.h +++ b/drivers/staging/media/ipu3/ipu3-css-pool.h @@ -10,15 +10,15 @@ struct imgu_device; #define IPU3_CSS_POOL_SIZE 4 /** - * ipu3_css_map - store DMA mapping info for buffer + * imgu_css_map - store DMA mapping info for buffer * * @size: size of the buffer in bytes. * @vaddr: kernel virtual address. * @daddr: iova dma address to access IPU3. * @vma: private, a pointer to &struct vm_struct, - * used for ipu3_dmamap_free. + * used for imgu_dmamap_free. */ -struct ipu3_css_map { +struct imgu_css_map { size_t size; void *vaddr; dma_addr_t daddr; @@ -26,30 +26,30 @@ struct ipu3_css_map { }; /** - * ipu3_css_pool - circular buffer pool definition + * imgu_css_pool - circular buffer pool definition * * @entry: array with IPU3_CSS_POOL_SIZE elements. - * @entry.param: a &struct ipu3_css_map for storing the mem mapping. + * @entry.param: a &struct imgu_css_map for storing the mem mapping. * @entry.valid: used to mark if the entry has valid data. * @last: write pointer, initialized to IPU3_CSS_POOL_SIZE. */ -struct ipu3_css_pool { +struct imgu_css_pool { struct { - struct ipu3_css_map param; + struct imgu_css_map param; bool valid; } entry[IPU3_CSS_POOL_SIZE]; u32 last; }; -int ipu3_css_dma_buffer_resize(struct imgu_device *imgu, - struct ipu3_css_map *map, size_t size); -void ipu3_css_pool_cleanup(struct imgu_device *imgu, - struct ipu3_css_pool *pool); -int ipu3_css_pool_init(struct imgu_device *imgu, struct ipu3_css_pool *pool, +int imgu_css_dma_buffer_resize(struct imgu_device *imgu, + struct imgu_css_map *map, size_t size); +void imgu_css_pool_cleanup(struct imgu_device *imgu, + struct imgu_css_pool *pool); +int imgu_css_pool_init(struct imgu_device *imgu, struct imgu_css_pool *pool, size_t size); -void ipu3_css_pool_get(struct ipu3_css_pool *pool); -void ipu3_css_pool_put(struct ipu3_css_pool *pool); -const struct ipu3_css_map *ipu3_css_pool_last(struct ipu3_css_pool *pool, +void imgu_css_pool_get(struct imgu_css_pool *pool); +void imgu_css_pool_put(struct imgu_css_pool *pool); +const struct imgu_css_map *imgu_css_pool_last(struct imgu_css_pool *pool, u32 last); #endif diff --git a/drivers/staging/media/ipu3/ipu3-css.c b/drivers/staging/media/ipu3/ipu3-css.c index 44c55639389a..15ab77e4b766 100644 --- a/drivers/staging/media/ipu3/ipu3-css.c +++ b/drivers/staging/media/ipu3/ipu3-css.c @@ -46,7 +46,7 @@ IPU3_CSS_QUEUE_TO_FLAGS(IPU3_CSS_QUEUE_VF) /* Formats supported by IPU3 Camera Sub System */ -static const struct ipu3_css_format ipu3_css_formats[] = { +static const struct imgu_css_format imgu_css_formats[] = { { .pixelformat = V4L2_PIX_FMT_NV12, .colorspace = V4L2_COLORSPACE_SRGB, @@ -100,7 +100,7 @@ static const struct ipu3_css_format ipu3_css_formats[] = { static const struct { enum imgu_abi_queue_id qid; size_t ptr_ofs; -} ipu3_css_queues[IPU3_CSS_QUEUES] = { +} imgu_css_queues[IPU3_CSS_QUEUES] = { [IPU3_CSS_QUEUE_IN] = { IMGU_ABI_QUEUE_C_ID, offsetof(struct imgu_abi_buffer, payload.frame.frame_data) @@ -120,7 +120,7 @@ static const struct { }; /* Initialize queue based on given format, adjust format as needed */ -static int ipu3_css_queue_init(struct ipu3_css_queue *queue, +static int imgu_css_queue_init(struct imgu_css_queue *queue, struct v4l2_pix_format_mplane *fmt, u32 flags) { struct v4l2_pix_format_mplane *const f = &queue->fmt.mpix; @@ -133,11 +133,11 @@ static int ipu3_css_queue_init(struct ipu3_css_queue *queue, if (!fmt) return 0; - for (i = 0; i < ARRAY_SIZE(ipu3_css_formats); i++) { - if (!(ipu3_css_formats[i].flags & flags)) + for (i = 0; i < ARRAY_SIZE(imgu_css_formats); i++) { + if (!(imgu_css_formats[i].flags & flags)) continue; - queue->css_fmt = &ipu3_css_formats[i]; - if (ipu3_css_formats[i].pixelformat == fmt->pixelformat) + queue->css_fmt = &imgu_css_formats[i]; + if (imgu_css_formats[i].pixelformat == fmt->pixelformat) break; } if (!queue->css_fmt) @@ -178,7 +178,7 @@ static int ipu3_css_queue_init(struct ipu3_css_queue *queue, return 0; } -static bool ipu3_css_queue_enabled(struct ipu3_css_queue *q) +static bool imgu_css_queue_enabled(struct imgu_css_queue *q) { return q->css_fmt; } @@ -200,7 +200,7 @@ static inline void writes(const void *mem, ssize_t count, void __iomem *addr) } /* Wait until register `reg', masked with `mask', becomes `cmp' */ -static int ipu3_hw_wait(void __iomem *base, int reg, u32 mask, u32 cmp) +static int imgu_hw_wait(void __iomem *base, int reg, u32 mask, u32 cmp) { u32 val; @@ -210,7 +210,7 @@ static int ipu3_hw_wait(void __iomem *base, int reg, u32 mask, u32 cmp) /* Initialize the IPU3 CSS hardware and associated h/w blocks */ -int ipu3_css_set_powerup(struct device *dev, void __iomem *base) +int imgu_css_set_powerup(struct device *dev, void __iomem *base) { static const unsigned int freq = 450; u32 pm_ctrl, state, val; @@ -221,7 +221,7 @@ int ipu3_css_set_powerup(struct device *dev, void __iomem *base) writel(0, base + IMGU_REG_GP_BUSY); /* Wait for idle signal */ - if (ipu3_hw_wait(base, IMGU_REG_STATE, IMGU_STATE_IDLE_STS, + if (imgu_hw_wait(base, IMGU_REG_STATE, IMGU_STATE_IDLE_STS, IMGU_STATE_IDLE_STS)) { dev_err(dev, "failed to set CSS idle\n"); goto fail; @@ -245,7 +245,7 @@ int ipu3_css_set_powerup(struct device *dev, void __iomem *base) if (state & IMGU_STATE_POWER_DOWN) { writel(IMGU_PM_CTRL_RACE_TO_HALT | IMGU_PM_CTRL_START, base + IMGU_REG_PM_CTRL); - if (ipu3_hw_wait(base, IMGU_REG_PM_CTRL, + if (imgu_hw_wait(base, IMGU_REG_PM_CTRL, IMGU_PM_CTRL_START, 0)) { dev_err(dev, "failed to power up CSS\n"); goto fail; @@ -263,7 +263,7 @@ int ipu3_css_set_powerup(struct device *dev, void __iomem *base) val = pm_ctrl & ~(IMGU_PM_CTRL_CSS_PWRDN | IMGU_PM_CTRL_RST_AT_EOF); writel(val, base + IMGU_REG_PM_CTRL); writel(0, base + IMGU_REG_GP_BUSY); - if (ipu3_hw_wait(base, IMGU_REG_STATE, + if (imgu_hw_wait(base, IMGU_REG_STATE, IMGU_STATE_PWRDNM_FSM_MASK, 0)) { dev_err(dev, "failed to pwrdn CSS\n"); goto fail; @@ -273,7 +273,7 @@ int ipu3_css_set_powerup(struct device *dev, void __iomem *base) writel(1, base + IMGU_REG_GP_BUSY); writel(readl(base + IMGU_REG_PM_CTRL) | IMGU_PM_CTRL_FORCE_HALT, base + IMGU_REG_PM_CTRL); - if (ipu3_hw_wait(base, IMGU_REG_STATE, IMGU_STATE_HALT_STS, + if (imgu_hw_wait(base, IMGU_REG_STATE, IMGU_STATE_HALT_STS, IMGU_STATE_HALT_STS)) { dev_err(dev, "failed to halt CSS\n"); goto fail; @@ -281,7 +281,7 @@ int ipu3_css_set_powerup(struct device *dev, void __iomem *base) writel(readl(base + IMGU_REG_PM_CTRL) | IMGU_PM_CTRL_START, base + IMGU_REG_PM_CTRL); - if (ipu3_hw_wait(base, IMGU_REG_PM_CTRL, IMGU_PM_CTRL_START, 0)) { + if (imgu_hw_wait(base, IMGU_REG_PM_CTRL, IMGU_PM_CTRL_START, 0)) { dev_err(dev, "failed to start CSS\n"); goto fail; } @@ -296,26 +296,26 @@ int ipu3_css_set_powerup(struct device *dev, void __iomem *base) return 0; fail: - ipu3_css_set_powerdown(dev, base); + imgu_css_set_powerdown(dev, base); return -EIO; } -void ipu3_css_set_powerdown(struct device *dev, void __iomem *base) +void imgu_css_set_powerdown(struct device *dev, void __iomem *base) { dev_dbg(dev, "%s\n", __func__); /* wait for cio idle signal */ - if (ipu3_hw_wait(base, IMGU_REG_CIO_GATE_BURST_STATE, + if (imgu_hw_wait(base, IMGU_REG_CIO_GATE_BURST_STATE, IMGU_CIO_GATE_BURST_MASK, 0)) dev_warn(dev, "wait cio gate idle timeout"); /* wait for css idle signal */ - if (ipu3_hw_wait(base, IMGU_REG_STATE, IMGU_STATE_IDLE_STS, + if (imgu_hw_wait(base, IMGU_REG_STATE, IMGU_STATE_IDLE_STS, IMGU_STATE_IDLE_STS)) dev_warn(dev, "wait css idle timeout\n"); /* do halt-halted handshake with css */ writel(1, base + IMGU_REG_GP_HALT); - if (ipu3_hw_wait(base, IMGU_REG_STATE, IMGU_STATE_HALT_STS, + if (imgu_hw_wait(base, IMGU_REG_STATE, IMGU_STATE_HALT_STS, IMGU_STATE_HALT_STS)) dev_warn(dev, "failed to halt css"); @@ -323,7 +323,7 @@ void ipu3_css_set_powerdown(struct device *dev, void __iomem *base) writel(0, base + IMGU_REG_GP_BUSY); } -static void ipu3_css_hw_enable_irq(struct ipu3_css *css) +static void imgu_css_hw_enable_irq(struct imgu_css *css) { void __iomem *const base = css->base; u32 val, i; @@ -371,7 +371,7 @@ static void ipu3_css_hw_enable_irq(struct ipu3_css *css) } } -static int ipu3_css_hw_init(struct ipu3_css *css) +static int imgu_css_hw_init(struct imgu_css *css) { /* For checking that streaming monitor statuses are valid */ static const struct { @@ -463,11 +463,11 @@ static int ipu3_css_hw_init(struct ipu3_css *css) /* Initialize GDC with default values */ - for (i = 0; i < ARRAY_SIZE(ipu3_css_gdc_lut[0]); i++) { - u32 val0 = ipu3_css_gdc_lut[0][i] & IMGU_GDC_LUT_MASK; - u32 val1 = ipu3_css_gdc_lut[1][i] & IMGU_GDC_LUT_MASK; - u32 val2 = ipu3_css_gdc_lut[2][i] & IMGU_GDC_LUT_MASK; - u32 val3 = ipu3_css_gdc_lut[3][i] & IMGU_GDC_LUT_MASK; + for (i = 0; i < ARRAY_SIZE(imgu_css_gdc_lut[0]); i++) { + u32 val0 = imgu_css_gdc_lut[0][i] & IMGU_GDC_LUT_MASK; + u32 val1 = imgu_css_gdc_lut[1][i] & IMGU_GDC_LUT_MASK; + u32 val2 = imgu_css_gdc_lut[2][i] & IMGU_GDC_LUT_MASK; + u32 val3 = imgu_css_gdc_lut[3][i] & IMGU_GDC_LUT_MASK; writel(val0 | (val1 << 16), base + IMGU_REG_GDC_LUT_BASE + i * 8); @@ -479,7 +479,7 @@ static int ipu3_css_hw_init(struct ipu3_css *css) } /* Boot the given IPU3 CSS SP */ -static int ipu3_css_hw_start_sp(struct ipu3_css *css, int sp) +static int imgu_css_hw_start_sp(struct imgu_css *css, int sp) { void __iomem *const base = css->base; struct imgu_fw_info *bi = &css->fwp->binary_header[css->fw_sp[sp]]; @@ -501,7 +501,7 @@ static int ipu3_css_hw_start_sp(struct ipu3_css *css, int sp) writel(readl(base + IMGU_REG_SP_CTRL(sp)) | IMGU_CTRL_START | IMGU_CTRL_RUN, base + IMGU_REG_SP_CTRL(sp)); - if (ipu3_hw_wait(css->base, IMGU_REG_SP_DMEM_BASE(sp) + if (imgu_hw_wait(css->base, IMGU_REG_SP_DMEM_BASE(sp) + bi->info.sp.sw_state, ~0, IMGU_ABI_SP_SWSTATE_INITIALIZED)) return -EIO; @@ -510,7 +510,7 @@ static int ipu3_css_hw_start_sp(struct ipu3_css *css, int sp) } /* Start the IPU3 CSS ImgU (Imaging Unit) and all the SPs */ -static int ipu3_css_hw_start(struct ipu3_css *css) +static int imgu_css_hw_start(struct imgu_css *css) { static const u32 event_mask = ((1 << IMGU_ABI_EVTTYPE_OUT_FRAME_DONE) | @@ -560,7 +560,7 @@ static int ipu3_css_hw_start(struct ipu3_css *css) writel(readl(base + IMGU_REG_ISP_CTRL) | IMGU_CTRL_START | IMGU_CTRL_RUN, base + IMGU_REG_ISP_CTRL); - if (ipu3_hw_wait(css->base, IMGU_REG_ISP_DMEM_BASE + if (imgu_hw_wait(css->base, IMGU_REG_ISP_DMEM_BASE + bl->info.bl.sw_state, ~0, IMGU_ABI_BL_SWSTATE_OK)) { dev_err(css->dev, "failed to start bootloader\n"); @@ -581,7 +581,7 @@ static int ipu3_css_hw_start(struct ipu3_css *css) base + IMGU_REG_SP_DMEM_BASE(0) + bi->info.sp.sw_state); writel(1, base + IMGU_REG_SP_DMEM_BASE(0) + bi->info.sp.invalidate_tlb); - if (ipu3_css_hw_start_sp(css, 0)) + if (imgu_css_hw_start_sp(css, 0)) return -EIO; writel(0, base + IMGU_REG_SP_DMEM_BASE(0) + bi->info.sp.isp_started); @@ -608,7 +608,7 @@ static int ipu3_css_hw_start(struct ipu3_css *css) writel(IMGU_ABI_SP_SWSTATE_TERMINATED, base + IMGU_REG_SP_DMEM_BASE(1) + bi->info.sp.sw_state); - if (ipu3_css_hw_start_sp(css, 1)) + if (imgu_css_hw_start_sp(css, 1)) return -EIO; writel(IMGU_ABI_SP_COMM_COMMAND_READY, base + IMGU_REG_SP_DMEM_BASE(1) @@ -617,7 +617,7 @@ static int ipu3_css_hw_start(struct ipu3_css *css) return 0; } -static void ipu3_css_hw_stop(struct ipu3_css *css) +static void imgu_css_hw_stop(struct imgu_css *css) { void __iomem *const base = css->base; struct imgu_fw_info *bi = &css->fwp->binary_header[css->fw_sp[0]]; @@ -626,18 +626,18 @@ static void ipu3_css_hw_stop(struct ipu3_css *css) writel(IMGU_ABI_SP_COMM_COMMAND_TERMINATE, base + IMGU_REG_SP_DMEM_BASE(0) + bi->info.sp.host_sp_com + IMGU_ABI_SP_COMM_COMMAND); - if (ipu3_hw_wait(css->base, IMGU_REG_SP_CTRL(0), + if (imgu_hw_wait(css->base, IMGU_REG_SP_CTRL(0), IMGU_CTRL_IDLE, IMGU_CTRL_IDLE)) dev_err(css->dev, "wait sp0 idle timeout.\n"); if (readl(base + IMGU_REG_SP_DMEM_BASE(0) + bi->info.sp.sw_state) != IMGU_ABI_SP_SWSTATE_TERMINATED) dev_err(css->dev, "sp0 is not terminated.\n"); - if (ipu3_hw_wait(css->base, IMGU_REG_ISP_CTRL, + if (imgu_hw_wait(css->base, IMGU_REG_ISP_CTRL, IMGU_CTRL_IDLE, IMGU_CTRL_IDLE)) dev_err(css->dev, "wait isp idle timeout\n"); } -static void ipu3_css_hw_cleanup(struct ipu3_css *css) +static void imgu_css_hw_cleanup(struct imgu_css *css) { void __iomem *const base = css->base; @@ -648,7 +648,7 @@ static void ipu3_css_hw_cleanup(struct ipu3_css *css) writel(0, base + IMGU_REG_GP_BUSY); /* Wait for idle signal */ - if (ipu3_hw_wait(css->base, IMGU_REG_STATE, IMGU_STATE_IDLE_STS, + if (imgu_hw_wait(css->base, IMGU_REG_STATE, IMGU_STATE_IDLE_STS, IMGU_STATE_IDLE_STS)) dev_err(css->dev, "failed to shut down hw cleanly\n"); @@ -659,19 +659,19 @@ static void ipu3_css_hw_cleanup(struct ipu3_css *css) usleep_range(200, 300); } -static void ipu3_css_pipeline_cleanup(struct ipu3_css *css, unsigned int pipe) +static void imgu_css_pipeline_cleanup(struct imgu_css *css, unsigned int pipe) { struct imgu_device *imgu = dev_get_drvdata(css->dev); unsigned int i; - ipu3_css_pool_cleanup(imgu, + imgu_css_pool_cleanup(imgu, &css->pipes[pipe].pool.parameter_set_info); - ipu3_css_pool_cleanup(imgu, &css->pipes[pipe].pool.acc); - ipu3_css_pool_cleanup(imgu, &css->pipes[pipe].pool.gdc); - ipu3_css_pool_cleanup(imgu, &css->pipes[pipe].pool.obgrid); + imgu_css_pool_cleanup(imgu, &css->pipes[pipe].pool.acc); + imgu_css_pool_cleanup(imgu, &css->pipes[pipe].pool.gdc); + imgu_css_pool_cleanup(imgu, &css->pipes[pipe].pool.obgrid); for (i = 0; i < IMGU_ABI_NUM_MEMORIES; i++) - ipu3_css_pool_cleanup(imgu, + imgu_css_pool_cleanup(imgu, &css->pipes[pipe].pool.binary_params_p[i]); } @@ -679,7 +679,7 @@ static void ipu3_css_pipeline_cleanup(struct ipu3_css *css, unsigned int pipe) * This function initializes various stages of the * IPU3 CSS ISP pipeline */ -static int ipu3_css_pipeline_init(struct ipu3_css *css, unsigned int pipe) +static int imgu_css_pipeline_init(struct imgu_css *css, unsigned int pipe) { static const int BYPC = 2; /* Bytes per component */ static const struct imgu_abi_buffer_sp buffer_sp_init = { @@ -697,7 +697,7 @@ static int ipu3_css_pipeline_init(struct ipu3_css *css, unsigned int pipe) const int stage = 0; unsigned int i, j; - struct ipu3_css_pipe *css_pipe = &css->pipes[pipe]; + struct imgu_css_pipe *css_pipe = &css->pipes[pipe]; const struct imgu_fw_info *bi = &css->fwp->binary_header[css_pipe->bindex]; const unsigned int stripes = bi->info.isp.sp.iterator.num_stripes; @@ -725,7 +725,7 @@ static int ipu3_css_pipeline_init(struct ipu3_css *css, unsigned int pipe) /* Configure iterator */ - cfg_iter = ipu3_css_fw_pipeline_params(css, pipe, cfg, m0, + cfg_iter = imgu_css_fw_pipeline_params(css, pipe, cfg, m0, &cofs->dmem.iterator, sizeof(*cfg_iter), vaddr); if (!cfg_iter) @@ -791,7 +791,7 @@ static int ipu3_css_pipeline_init(struct ipu3_css *css, unsigned int pipe) /* Configure reference (delay) frames */ - cfg_ref = ipu3_css_fw_pipeline_params(css, pipe, cfg, m0, + cfg_ref = imgu_css_fw_pipeline_params(css, pipe, cfg, m0, &cofs->dmem.ref, sizeof(*cfg_ref), vaddr); if (!cfg_ref) @@ -821,7 +821,7 @@ static int ipu3_css_pipeline_init(struct ipu3_css *css, unsigned int pipe) /* Configure DVS (digital video stabilization) */ - cfg_dvs = ipu3_css_fw_pipeline_params(css, pipe, cfg, m0, + cfg_dvs = imgu_css_fw_pipeline_params(css, pipe, cfg, m0, &cofs->dmem.dvs, sizeof(*cfg_dvs), vaddr); if (!cfg_dvs) @@ -837,7 +837,7 @@ static int ipu3_css_pipeline_init(struct ipu3_css *css, unsigned int pipe) /* Configure TNR (temporal noise reduction) */ if (css_pipe->pipe_id == IPU3_CSS_PIPE_ID_VIDEO) { - cfg_tnr = ipu3_css_fw_pipeline_params(css, pipe, cfg, m0, + cfg_tnr = imgu_css_fw_pipeline_params(css, pipe, cfg, m0, &cofs->dmem.tnr3, sizeof(*cfg_tnr), vaddr); @@ -868,7 +868,7 @@ static int ipu3_css_pipeline_init(struct ipu3_css *css, unsigned int pipe) cfg = IMGU_ABI_PARAM_CLASS_STATE; vaddr = css_pipe->binary_params_cs[cfg - 1][m0].vaddr; - cfg_ref_state = ipu3_css_fw_pipeline_params(css, pipe, cfg, m0, + cfg_ref_state = imgu_css_fw_pipeline_params(css, pipe, cfg, m0, &sofs->dmem.ref, sizeof(*cfg_ref_state), vaddr); @@ -881,7 +881,7 @@ static int ipu3_css_pipeline_init(struct ipu3_css *css, unsigned int pipe) /* Configure tnr dmem state parameters */ if (css_pipe->pipe_id == IPU3_CSS_PIPE_ID_VIDEO) { cfg_tnr_state = - ipu3_css_fw_pipeline_params(css, pipe, cfg, m0, + imgu_css_fw_pipeline_params(css, pipe, cfg, m0, &sofs->dmem.tnr3, sizeof(*cfg_tnr_state), vaddr); @@ -1068,21 +1068,21 @@ static int ipu3_css_pipeline_init(struct ipu3_css *css, unsigned int pipe) /* Initialize parameter pools */ - if (ipu3_css_pool_init(imgu, &css_pipe->pool.parameter_set_info, + if (imgu_css_pool_init(imgu, &css_pipe->pool.parameter_set_info, sizeof(struct imgu_abi_parameter_set_info)) || - ipu3_css_pool_init(imgu, &css_pipe->pool.acc, + imgu_css_pool_init(imgu, &css_pipe->pool.acc, sizeof(struct imgu_abi_acc_param)) || - ipu3_css_pool_init(imgu, &css_pipe->pool.gdc, + imgu_css_pool_init(imgu, &css_pipe->pool.gdc, sizeof(struct imgu_abi_gdc_warp_param) * 3 * cfg_dvs->num_horizontal_blocks / 2 * cfg_dvs->num_vertical_blocks) || - ipu3_css_pool_init(imgu, &css_pipe->pool.obgrid, - ipu3_css_fw_obgrid_size( + imgu_css_pool_init(imgu, &css_pipe->pool.obgrid, + imgu_css_fw_obgrid_size( &css->fwp->binary_header[css_pipe->bindex]))) goto out_of_memory; for (i = 0; i < IMGU_ABI_NUM_MEMORIES; i++) - if (ipu3_css_pool_init(imgu, + if (imgu_css_pool_init(imgu, &css_pipe->pool.binary_params_p[i], bi->info.isp.sp.mem_initializers.params [IMGU_ABI_PARAM_CLASS_PARAM][i].size)) @@ -1091,15 +1091,15 @@ static int ipu3_css_pipeline_init(struct ipu3_css *css, unsigned int pipe) return 0; bad_firmware: - ipu3_css_pipeline_cleanup(css, pipe); + imgu_css_pipeline_cleanup(css, pipe); return -EPROTO; out_of_memory: - ipu3_css_pipeline_cleanup(css, pipe); + imgu_css_pipeline_cleanup(css, pipe); return -ENOMEM; } -static u8 ipu3_css_queue_pos(struct ipu3_css *css, int queue, int thread) +static u8 imgu_css_queue_pos(struct imgu_css *css, int queue, int thread) { static const unsigned int sp; void __iomem *const base = css->base; @@ -1112,7 +1112,7 @@ static u8 ipu3_css_queue_pos(struct ipu3_css *css, int queue, int thread) } /* Sent data to sp using given buffer queue, or if queue < 0, event queue. */ -static int ipu3_css_queue_data(struct ipu3_css *css, +static int imgu_css_queue_data(struct imgu_css *css, int queue, int thread, u32 data) { static const unsigned int sp; @@ -1151,7 +1151,7 @@ static int ipu3_css_queue_data(struct ipu3_css *css, } /* Receive data using given buffer queue, or if queue < 0, event queue. */ -static int ipu3_css_dequeue_data(struct ipu3_css *css, int queue, u32 *data) +static int imgu_css_dequeue_data(struct imgu_css *css, int queue, u32 *data) { static const unsigned int sp; void __iomem *const base = css->base; @@ -1188,7 +1188,7 @@ static int ipu3_css_dequeue_data(struct ipu3_css *css, int queue, u32 *data) writeb(start2, &q->sp2host_evtq_info.start); /* Acknowledge events dequeued from event queue */ - r = ipu3_css_queue_data(css, queue, 0, + r = imgu_css_queue_data(css, queue, 0, IMGU_ABI_EVENT_EVENT_DEQUEUED); if (r < 0) return r; @@ -1198,52 +1198,52 @@ static int ipu3_css_dequeue_data(struct ipu3_css *css, int queue, u32 *data) } /* Free binary-specific resources */ -static void ipu3_css_binary_cleanup(struct ipu3_css *css, unsigned int pipe) +static void imgu_css_binary_cleanup(struct imgu_css *css, unsigned int pipe) { struct imgu_device *imgu = dev_get_drvdata(css->dev); unsigned int i, j; - struct ipu3_css_pipe *css_pipe = &css->pipes[pipe]; + struct imgu_css_pipe *css_pipe = &css->pipes[pipe]; for (j = 0; j < IMGU_ABI_PARAM_CLASS_NUM - 1; j++) for (i = 0; i < IMGU_ABI_NUM_MEMORIES; i++) - ipu3_dmamap_free(imgu, + imgu_dmamap_free(imgu, &css_pipe->binary_params_cs[j][i]); j = IPU3_CSS_AUX_FRAME_REF; for (i = 0; i < IPU3_CSS_AUX_FRAMES; i++) - ipu3_dmamap_free(imgu, + imgu_dmamap_free(imgu, &css_pipe->aux_frames[j].mem[i]); j = IPU3_CSS_AUX_FRAME_TNR; for (i = 0; i < IPU3_CSS_AUX_FRAMES; i++) - ipu3_dmamap_free(imgu, + imgu_dmamap_free(imgu, &css_pipe->aux_frames[j].mem[i]); } -static int ipu3_css_binary_preallocate(struct ipu3_css *css, unsigned int pipe) +static int imgu_css_binary_preallocate(struct imgu_css *css, unsigned int pipe) { struct imgu_device *imgu = dev_get_drvdata(css->dev); unsigned int i, j; - struct ipu3_css_pipe *css_pipe = &css->pipes[pipe]; + struct imgu_css_pipe *css_pipe = &css->pipes[pipe]; for (j = IMGU_ABI_PARAM_CLASS_CONFIG; j < IMGU_ABI_PARAM_CLASS_NUM; j++) for (i = 0; i < IMGU_ABI_NUM_MEMORIES; i++) - if (!ipu3_dmamap_alloc(imgu, + if (!imgu_dmamap_alloc(imgu, &css_pipe->binary_params_cs[j - 1][i], CSS_ABI_SIZE)) goto out_of_memory; for (i = 0; i < IPU3_CSS_AUX_FRAMES; i++) - if (!ipu3_dmamap_alloc(imgu, + if (!imgu_dmamap_alloc(imgu, &css_pipe->aux_frames[IPU3_CSS_AUX_FRAME_REF]. mem[i], CSS_BDS_SIZE)) goto out_of_memory; for (i = 0; i < IPU3_CSS_AUX_FRAMES; i++) - if (!ipu3_dmamap_alloc(imgu, + if (!imgu_dmamap_alloc(imgu, &css_pipe->aux_frames[IPU3_CSS_AUX_FRAME_TNR]. mem[i], CSS_GDC_SIZE)) goto out_of_memory; @@ -1251,14 +1251,14 @@ static int ipu3_css_binary_preallocate(struct ipu3_css *css, unsigned int pipe) return 0; out_of_memory: - ipu3_css_binary_cleanup(css, pipe); + imgu_css_binary_cleanup(css, pipe); return -ENOMEM; } /* allocate binary-specific resources */ -static int ipu3_css_binary_setup(struct ipu3_css *css, unsigned int pipe) +static int imgu_css_binary_setup(struct imgu_css *css, unsigned int pipe) { - struct ipu3_css_pipe *css_pipe = &css->pipes[pipe]; + struct imgu_css_pipe *css_pipe = &css->pipes[pipe]; struct imgu_fw_info *bi = &css->fwp->binary_header[css_pipe->bindex]; struct imgu_device *imgu = dev_get_drvdata(css->dev); int i, j, size; @@ -1269,7 +1269,7 @@ static int ipu3_css_binary_setup(struct ipu3_css *css, unsigned int pipe) for (j = IMGU_ABI_PARAM_CLASS_CONFIG; j < IMGU_ABI_PARAM_CLASS_NUM; j++) for (i = 0; i < IMGU_ABI_NUM_MEMORIES; i++) { - if (ipu3_css_dma_buffer_resize( + if (imgu_css_dma_buffer_resize( imgu, &css_pipe->binary_params_cs[j - 1][i], bi->info.isp.sp.mem_initializers.params[j][i].size)) @@ -1292,7 +1292,7 @@ static int ipu3_css_binary_setup(struct ipu3_css *css, unsigned int pipe) css_pipe->aux_frames[IPU3_CSS_AUX_FRAME_REF].bytesperpixel * w; size = w * h * BYPC + (w / 2) * (h / 2) * BYPC * 2; for (i = 0; i < IPU3_CSS_AUX_FRAMES; i++) - if (ipu3_css_dma_buffer_resize( + if (imgu_css_dma_buffer_resize( imgu, &css_pipe->aux_frames[IPU3_CSS_AUX_FRAME_REF].mem[i], size)) @@ -1313,7 +1313,7 @@ static int ipu3_css_binary_setup(struct ipu3_css *css, unsigned int pipe) h = css_pipe->aux_frames[IPU3_CSS_AUX_FRAME_TNR].height; size = w * ALIGN(h * 3 / 2 + 3, 2); /* +3 for vf_pp prefetch */ for (i = 0; i < IPU3_CSS_AUX_FRAMES; i++) - if (ipu3_css_dma_buffer_resize( + if (imgu_css_dma_buffer_resize( imgu, &css_pipe->aux_frames[IPU3_CSS_AUX_FRAME_TNR].mem[i], size)) @@ -1322,11 +1322,11 @@ static int ipu3_css_binary_setup(struct ipu3_css *css, unsigned int pipe) return 0; out_of_memory: - ipu3_css_binary_cleanup(css, pipe); + imgu_css_binary_cleanup(css, pipe); return -ENOMEM; } -int ipu3_css_start_streaming(struct ipu3_css *css) +int imgu_css_start_streaming(struct imgu_css *css) { u32 data; int r, pipe; @@ -1335,48 +1335,48 @@ int ipu3_css_start_streaming(struct ipu3_css *css) return -EPROTO; for_each_set_bit(pipe, css->enabled_pipes, IMGU_MAX_PIPE_NUM) { - r = ipu3_css_binary_setup(css, pipe); + r = imgu_css_binary_setup(css, pipe); if (r < 0) return r; } - r = ipu3_css_hw_init(css); + r = imgu_css_hw_init(css); if (r < 0) return r; - r = ipu3_css_hw_start(css); + r = imgu_css_hw_start(css); if (r < 0) goto fail; for_each_set_bit(pipe, css->enabled_pipes, IMGU_MAX_PIPE_NUM) { - r = ipu3_css_pipeline_init(css, pipe); + r = imgu_css_pipeline_init(css, pipe); if (r < 0) goto fail; } css->streaming = true; - ipu3_css_hw_enable_irq(css); + imgu_css_hw_enable_irq(css); /* Initialize parameters to default */ for_each_set_bit(pipe, css->enabled_pipes, IMGU_MAX_PIPE_NUM) { - r = ipu3_css_set_parameters(css, pipe, NULL); + r = imgu_css_set_parameters(css, pipe, NULL); if (r < 0) goto fail; } - while (!(r = ipu3_css_dequeue_data(css, IMGU_ABI_QUEUE_A_ID, &data))) + while (!(r = imgu_css_dequeue_data(css, IMGU_ABI_QUEUE_A_ID, &data))) ; if (r != -EBUSY) goto fail; - while (!(r = ipu3_css_dequeue_data(css, IMGU_ABI_QUEUE_B_ID, &data))) + while (!(r = imgu_css_dequeue_data(css, IMGU_ABI_QUEUE_B_ID, &data))) ; if (r != -EBUSY) goto fail; for_each_set_bit(pipe, css->enabled_pipes, IMGU_MAX_PIPE_NUM) { - r = ipu3_css_queue_data(css, IMGU_ABI_QUEUE_EVENT_ID, pipe, + r = imgu_css_queue_data(css, IMGU_ABI_QUEUE_EVENT_ID, pipe, IMGU_ABI_EVENT_START_STREAM | pipe << 16); if (r < 0) @@ -1387,22 +1387,22 @@ int ipu3_css_start_streaming(struct ipu3_css *css) fail: css->streaming = false; - ipu3_css_hw_cleanup(css); + imgu_css_hw_cleanup(css); for_each_set_bit(pipe, css->enabled_pipes, IMGU_MAX_PIPE_NUM) { - ipu3_css_pipeline_cleanup(css, pipe); - ipu3_css_binary_cleanup(css, pipe); + imgu_css_pipeline_cleanup(css, pipe); + imgu_css_binary_cleanup(css, pipe); } return r; } -void ipu3_css_stop_streaming(struct ipu3_css *css) +void imgu_css_stop_streaming(struct imgu_css *css) { - struct ipu3_css_buffer *b, *b0; + struct imgu_css_buffer *b, *b0; int q, r, pipe; for_each_set_bit(pipe, css->enabled_pipes, IMGU_MAX_PIPE_NUM) { - r = ipu3_css_queue_data(css, IMGU_ABI_QUEUE_EVENT_ID, pipe, + r = imgu_css_queue_data(css, IMGU_ABI_QUEUE_EVENT_ID, pipe, IMGU_ABI_EVENT_STOP_STREAM); if (r < 0) dev_warn(css->dev, "failed on stop stream event\n"); @@ -1411,14 +1411,14 @@ void ipu3_css_stop_streaming(struct ipu3_css *css) if (!css->streaming) return; - ipu3_css_hw_stop(css); + imgu_css_hw_stop(css); - ipu3_css_hw_cleanup(css); + imgu_css_hw_cleanup(css); for_each_set_bit(pipe, css->enabled_pipes, IMGU_MAX_PIPE_NUM) { - struct ipu3_css_pipe *css_pipe = &css->pipes[pipe]; + struct imgu_css_pipe *css_pipe = &css->pipes[pipe]; - ipu3_css_pipeline_cleanup(css, pipe); + imgu_css_pipeline_cleanup(css, pipe); spin_lock(&css_pipe->qlock); for (q = 0; q < IPU3_CSS_QUEUES; q++) @@ -1434,10 +1434,10 @@ void ipu3_css_stop_streaming(struct ipu3_css *css) css->streaming = false; } -bool ipu3_css_pipe_queue_empty(struct ipu3_css *css, unsigned int pipe) +bool imgu_css_pipe_queue_empty(struct imgu_css *css, unsigned int pipe) { int q; - struct ipu3_css_pipe *css_pipe = &css->pipes[pipe]; + struct imgu_css_pipe *css_pipe = &css->pipes[pipe]; spin_lock(&css_pipe->qlock); for (q = 0; q < IPU3_CSS_QUEUES; q++) @@ -1447,44 +1447,44 @@ bool ipu3_css_pipe_queue_empty(struct ipu3_css *css, unsigned int pipe) return (q == IPU3_CSS_QUEUES); } -bool ipu3_css_queue_empty(struct ipu3_css *css) +bool imgu_css_queue_empty(struct imgu_css *css) { unsigned int pipe; bool ret = 0; for (pipe = 0; pipe < IMGU_MAX_PIPE_NUM; pipe++) - ret &= ipu3_css_pipe_queue_empty(css, pipe); + ret &= imgu_css_pipe_queue_empty(css, pipe); return ret; } -bool ipu3_css_is_streaming(struct ipu3_css *css) +bool imgu_css_is_streaming(struct imgu_css *css) { return css->streaming; } -static int ipu3_css_map_init(struct ipu3_css *css, unsigned int pipe) +static int imgu_css_map_init(struct imgu_css *css, unsigned int pipe) { struct imgu_device *imgu = dev_get_drvdata(css->dev); - struct ipu3_css_pipe *css_pipe = &css->pipes[pipe]; + struct imgu_css_pipe *css_pipe = &css->pipes[pipe]; unsigned int p, q, i; /* Allocate and map common structures with imgu hardware */ for (p = 0; p < IPU3_CSS_PIPE_ID_NUM; p++) for (i = 0; i < IMGU_ABI_MAX_STAGES; i++) { - if (!ipu3_dmamap_alloc(imgu, + if (!imgu_dmamap_alloc(imgu, &css_pipe-> xmem_sp_stage_ptrs[p][i], sizeof(struct imgu_abi_sp_stage))) return -ENOMEM; - if (!ipu3_dmamap_alloc(imgu, + if (!imgu_dmamap_alloc(imgu, &css_pipe-> xmem_isp_stage_ptrs[p][i], sizeof(struct imgu_abi_isp_stage))) return -ENOMEM; } - if (!ipu3_dmamap_alloc(imgu, &css_pipe->sp_ddr_ptrs, + if (!imgu_dmamap_alloc(imgu, &css_pipe->sp_ddr_ptrs, ALIGN(sizeof(struct imgu_abi_ddr_address_map), IMGU_ABI_ISP_DDR_WORD_BYTES))) return -ENOMEM; @@ -1493,58 +1493,58 @@ static int ipu3_css_map_init(struct ipu3_css *css, unsigned int pipe) unsigned int abi_buf_num = ARRAY_SIZE(css_pipe->abi_buffers[q]); for (i = 0; i < abi_buf_num; i++) - if (!ipu3_dmamap_alloc(imgu, + if (!imgu_dmamap_alloc(imgu, &css_pipe->abi_buffers[q][i], sizeof(struct imgu_abi_buffer))) return -ENOMEM; } - if (ipu3_css_binary_preallocate(css, pipe)) { - ipu3_css_binary_cleanup(css, pipe); + if (imgu_css_binary_preallocate(css, pipe)) { + imgu_css_binary_cleanup(css, pipe); return -ENOMEM; } return 0; } -static void ipu3_css_pipe_cleanup(struct ipu3_css *css, unsigned int pipe) +static void imgu_css_pipe_cleanup(struct imgu_css *css, unsigned int pipe) { struct imgu_device *imgu = dev_get_drvdata(css->dev); - struct ipu3_css_pipe *css_pipe = &css->pipes[pipe]; + struct imgu_css_pipe *css_pipe = &css->pipes[pipe]; unsigned int p, q, i, abi_buf_num; - ipu3_css_binary_cleanup(css, pipe); + imgu_css_binary_cleanup(css, pipe); for (q = 0; q < IPU3_CSS_QUEUES; q++) { abi_buf_num = ARRAY_SIZE(css_pipe->abi_buffers[q]); for (i = 0; i < abi_buf_num; i++) - ipu3_dmamap_free(imgu, &css_pipe->abi_buffers[q][i]); + imgu_dmamap_free(imgu, &css_pipe->abi_buffers[q][i]); } for (p = 0; p < IPU3_CSS_PIPE_ID_NUM; p++) for (i = 0; i < IMGU_ABI_MAX_STAGES; i++) { - ipu3_dmamap_free(imgu, + imgu_dmamap_free(imgu, &css_pipe->xmem_sp_stage_ptrs[p][i]); - ipu3_dmamap_free(imgu, + imgu_dmamap_free(imgu, &css_pipe->xmem_isp_stage_ptrs[p][i]); } - ipu3_dmamap_free(imgu, &css_pipe->sp_ddr_ptrs); + imgu_dmamap_free(imgu, &css_pipe->sp_ddr_ptrs); } -void ipu3_css_cleanup(struct ipu3_css *css) +void imgu_css_cleanup(struct imgu_css *css) { struct imgu_device *imgu = dev_get_drvdata(css->dev); unsigned int pipe; - ipu3_css_stop_streaming(css); + imgu_css_stop_streaming(css); for (pipe = 0; pipe < IMGU_MAX_PIPE_NUM; pipe++) - ipu3_css_pipe_cleanup(css, pipe); - ipu3_dmamap_free(imgu, &css->xmem_sp_group_ptrs); - ipu3_css_fw_cleanup(css); + imgu_css_pipe_cleanup(css, pipe); + imgu_dmamap_free(imgu, &css->xmem_sp_group_ptrs); + imgu_css_fw_cleanup(css); } -int ipu3_css_init(struct device *dev, struct ipu3_css *css, +int imgu_css_init(struct device *dev, struct imgu_css *css, void __iomem *base, int length) { struct imgu_device *imgu = dev_get_drvdata(dev); @@ -1556,35 +1556,35 @@ int ipu3_css_init(struct device *dev, struct ipu3_css *css, css->iomem_length = length; for (pipe = 0; pipe < IMGU_MAX_PIPE_NUM; pipe++) { - struct ipu3_css_pipe *css_pipe = &css->pipes[pipe]; + struct imgu_css_pipe *css_pipe = &css->pipes[pipe]; css_pipe->vf_output_en = false; spin_lock_init(&css_pipe->qlock); css_pipe->bindex = IPU3_CSS_DEFAULT_BINARY; css_pipe->pipe_id = IPU3_CSS_PIPE_ID_VIDEO; for (q = 0; q < IPU3_CSS_QUEUES; q++) { - r = ipu3_css_queue_init(&css_pipe->queue[q], NULL, 0); + r = imgu_css_queue_init(&css_pipe->queue[q], NULL, 0); if (r) return r; } - r = ipu3_css_map_init(css, pipe); + r = imgu_css_map_init(css, pipe); if (r) { - ipu3_css_cleanup(css); + imgu_css_cleanup(css); return r; } } - if (!ipu3_dmamap_alloc(imgu, &css->xmem_sp_group_ptrs, + if (!imgu_dmamap_alloc(imgu, &css->xmem_sp_group_ptrs, sizeof(struct imgu_abi_sp_group))) return -ENOMEM; - r = ipu3_css_fw_init(css); + r = imgu_css_fw_init(css); if (r) return r; return 0; } -static u32 ipu3_css_adjust(u32 res, u32 align) +static u32 imgu_css_adjust(u32 res, u32 align) { u32 val = max_t(u32, IPU3_CSS_MIN_RES, res); @@ -1592,9 +1592,9 @@ static u32 ipu3_css_adjust(u32 res, u32 align) } /* Select a binary matching the required resolutions and formats */ -static int ipu3_css_find_binary(struct ipu3_css *css, +static int imgu_css_find_binary(struct imgu_css *css, unsigned int pipe, - struct ipu3_css_queue queue[IPU3_CSS_QUEUES], + struct imgu_css_queue queue[IPU3_CSS_QUEUES], struct v4l2_rect rects[IPU3_CSS_RECTS]) { const int binary_nr = css->fwp->file_header.binary_nr; @@ -1611,7 +1611,7 @@ static int ipu3_css_find_binary(struct ipu3_css *css, const char *name; int i, j; - if (!ipu3_css_queue_enabled(&queue[IPU3_CSS_QUEUE_IN])) + if (!imgu_css_queue_enabled(&queue[IPU3_CSS_QUEUE_IN])) return -EINVAL; /* Find out the strip size boundary */ @@ -1659,7 +1659,7 @@ static int ipu3_css_find_binary(struct ipu3_css *css, in->height > bi->info.isp.sp.input.max_height) continue; - if (ipu3_css_queue_enabled(&queue[IPU3_CSS_QUEUE_OUT])) { + if (imgu_css_queue_enabled(&queue[IPU3_CSS_QUEUE_OUT])) { if (bi->info.isp.num_output_pins <= 0) continue; @@ -1681,7 +1681,7 @@ static int ipu3_css_find_binary(struct ipu3_css *css, continue; } - if (ipu3_css_queue_enabled(&queue[IPU3_CSS_QUEUE_VF])) { + if (imgu_css_queue_enabled(&queue[IPU3_CSS_QUEUE_VF])) { if (bi->info.isp.num_output_pins <= 1) continue; @@ -1716,7 +1716,7 @@ static int ipu3_css_find_binary(struct ipu3_css *css, * found binary number. May modify the given parameters if not exact match * is found. */ -int ipu3_css_fmt_try(struct ipu3_css *css, +int imgu_css_fmt_try(struct imgu_css *css, struct v4l2_pix_format_mplane *fmts[IPU3_CSS_QUEUES], struct v4l2_rect *rects[IPU3_CSS_RECTS], unsigned int pipe) @@ -1744,14 +1744,14 @@ int ipu3_css_fmt_try(struct ipu3_css *css, struct v4l2_rect *const bds = &r[IPU3_CSS_RECT_BDS]; struct v4l2_rect *const env = &r[IPU3_CSS_RECT_ENVELOPE]; struct v4l2_rect *const gdc = &r[IPU3_CSS_RECT_GDC]; - struct ipu3_css_queue q[IPU3_CSS_QUEUES]; + struct imgu_css_queue q[IPU3_CSS_QUEUES]; struct v4l2_pix_format_mplane *const in = &q[IPU3_CSS_QUEUE_IN].fmt.mpix; struct v4l2_pix_format_mplane *const out = &q[IPU3_CSS_QUEUE_OUT].fmt.mpix; struct v4l2_pix_format_mplane *const vf = &q[IPU3_CSS_QUEUE_VF].fmt.mpix; - int i, s; + int i, s, ret; /* Adjust all formats, get statistics buffer sizes and formats */ for (i = 0; i < IPU3_CSS_QUEUES; i++) { @@ -1762,7 +1762,7 @@ int ipu3_css_fmt_try(struct ipu3_css *css, else dev_dbg(css->dev, "%s %s: (not set)\n", __func__, qnames[i]); - if (ipu3_css_queue_init(&q[i], fmts[i], + if (imgu_css_queue_init(&q[i], fmts[i], IPU3_CSS_QUEUE_TO_FLAGS(i))) { dev_notice(css->dev, "can not initialize queue %s\n", qnames[i]); @@ -1785,13 +1785,13 @@ int ipu3_css_fmt_try(struct ipu3_css *css, } /* Always require one input and vf only if out is also enabled */ - if (!ipu3_css_queue_enabled(&q[IPU3_CSS_QUEUE_IN]) || - !ipu3_css_queue_enabled(&q[IPU3_CSS_QUEUE_OUT])) { + if (!imgu_css_queue_enabled(&q[IPU3_CSS_QUEUE_IN]) || + !imgu_css_queue_enabled(&q[IPU3_CSS_QUEUE_OUT])) { dev_warn(css->dev, "required queues are disabled\n"); return -EINVAL; } - if (!ipu3_css_queue_enabled(&q[IPU3_CSS_QUEUE_OUT])) { + if (!imgu_css_queue_enabled(&q[IPU3_CSS_QUEUE_OUT])) { out->width = in->width; out->height = in->height; } @@ -1808,30 +1808,30 @@ int ipu3_css_fmt_try(struct ipu3_css *css, gdc->height = out->height; } - in->width = ipu3_css_adjust(in->width, 1); - in->height = ipu3_css_adjust(in->height, 1); - eff->width = ipu3_css_adjust(eff->width, EFF_ALIGN_W); - eff->height = ipu3_css_adjust(eff->height, 1); - bds->width = ipu3_css_adjust(bds->width, BDS_ALIGN_W); - bds->height = ipu3_css_adjust(bds->height, 1); - gdc->width = ipu3_css_adjust(gdc->width, OUT_ALIGN_W); - gdc->height = ipu3_css_adjust(gdc->height, OUT_ALIGN_H); - out->width = ipu3_css_adjust(out->width, OUT_ALIGN_W); - out->height = ipu3_css_adjust(out->height, OUT_ALIGN_H); - vf->width = ipu3_css_adjust(vf->width, VF_ALIGN_W); - vf->height = ipu3_css_adjust(vf->height, 1); + in->width = imgu_css_adjust(in->width, 1); + in->height = imgu_css_adjust(in->height, 1); + eff->width = imgu_css_adjust(eff->width, EFF_ALIGN_W); + eff->height = imgu_css_adjust(eff->height, 1); + bds->width = imgu_css_adjust(bds->width, BDS_ALIGN_W); + bds->height = imgu_css_adjust(bds->height, 1); + gdc->width = imgu_css_adjust(gdc->width, OUT_ALIGN_W); + gdc->height = imgu_css_adjust(gdc->height, OUT_ALIGN_H); + out->width = imgu_css_adjust(out->width, OUT_ALIGN_W); + out->height = imgu_css_adjust(out->height, OUT_ALIGN_H); + vf->width = imgu_css_adjust(vf->width, VF_ALIGN_W); + vf->height = imgu_css_adjust(vf->height, 1); s = (bds->width - gdc->width) / 2 - FILTER_SIZE; env->width = s < MIN_ENVELOPE ? MIN_ENVELOPE : s; s = (bds->height - gdc->height) / 2 - FILTER_SIZE; env->height = s < MIN_ENVELOPE ? MIN_ENVELOPE : s; - css->pipes[pipe].bindex = - ipu3_css_find_binary(css, pipe, q, r); - if (css->pipes[pipe].bindex < 0) { + ret = imgu_css_find_binary(css, pipe, q, r); + if (ret < 0) { dev_err(css->dev, "failed to find suitable binary\n"); return -EINVAL; } + css->pipes[pipe].bindex = ret; dev_dbg(css->dev, "Binary index %d for pipe %d found.", css->pipes[pipe].bindex, pipe); @@ -1839,7 +1839,7 @@ int ipu3_css_fmt_try(struct ipu3_css *css, /* Final adjustment and set back the queried formats */ for (i = 0; i < IPU3_CSS_QUEUES; i++) { if (fmts[i]) { - if (ipu3_css_queue_init(&q[i], &q[i].fmt.mpix, + if (imgu_css_queue_init(&q[i], &q[i].fmt.mpix, IPU3_CSS_QUEUE_TO_FLAGS(i))) { dev_err(css->dev, "final resolution adjustment failed\n"); @@ -1862,7 +1862,7 @@ int ipu3_css_fmt_try(struct ipu3_css *css, return 0; } -int ipu3_css_fmt_set(struct ipu3_css *css, +int imgu_css_fmt_set(struct imgu_css *css, struct v4l2_pix_format_mplane *fmts[IPU3_CSS_QUEUES], struct v4l2_rect *rects[IPU3_CSS_RECTS], unsigned int pipe) @@ -1870,7 +1870,7 @@ int ipu3_css_fmt_set(struct ipu3_css *css, struct v4l2_rect rect_data[IPU3_CSS_RECTS]; struct v4l2_rect *all_rects[IPU3_CSS_RECTS]; int i, r; - struct ipu3_css_pipe *css_pipe = &css->pipes[pipe]; + struct imgu_css_pipe *css_pipe = &css->pipes[pipe]; for (i = 0; i < IPU3_CSS_RECTS; i++) { if (rects[i]) @@ -1879,12 +1879,12 @@ int ipu3_css_fmt_set(struct ipu3_css *css, memset(&rect_data[i], 0, sizeof(rect_data[i])); all_rects[i] = &rect_data[i]; } - r = ipu3_css_fmt_try(css, fmts, all_rects, pipe); + r = imgu_css_fmt_try(css, fmts, all_rects, pipe); if (r < 0) return r; for (i = 0; i < IPU3_CSS_QUEUES; i++) - if (ipu3_css_queue_init(&css_pipe->queue[i], fmts[i], + if (imgu_css_queue_init(&css_pipe->queue[i], fmts[i], IPU3_CSS_QUEUE_TO_FLAGS(i))) return -EINVAL; for (i = 0; i < IPU3_CSS_RECTS; i++) { @@ -1896,7 +1896,7 @@ int ipu3_css_fmt_set(struct ipu3_css *css, return 0; } -int ipu3_css_meta_fmt_set(struct v4l2_meta_format *fmt) +int imgu_css_meta_fmt_set(struct v4l2_meta_format *fmt) { switch (fmt->dataformat) { case V4L2_META_FMT_IPU3_PARAMS: @@ -1913,27 +1913,27 @@ int ipu3_css_meta_fmt_set(struct v4l2_meta_format *fmt) } /* - * Queue given buffer to CSS. ipu3_css_buf_prepare() must have been first + * Queue given buffer to CSS. imgu_css_buf_prepare() must have been first * called for the buffer. May be called from interrupt context. * Returns 0 on success, -EBUSY if the buffer queue is full, or some other * code on error conditions. */ -int ipu3_css_buf_queue(struct ipu3_css *css, unsigned int pipe, - struct ipu3_css_buffer *b) +int imgu_css_buf_queue(struct imgu_css *css, unsigned int pipe, + struct imgu_css_buffer *b) { struct imgu_abi_buffer *abi_buf; struct imgu_addr_t *buf_addr; u32 data; int r; - struct ipu3_css_pipe *css_pipe = &css->pipes[pipe]; + struct imgu_css_pipe *css_pipe = &css->pipes[pipe]; if (!css->streaming) return -EPROTO; /* CSS or buffer in wrong state */ - if (b->queue >= IPU3_CSS_QUEUES || !ipu3_css_queues[b->queue].qid) + if (b->queue >= IPU3_CSS_QUEUES || !imgu_css_queues[b->queue].qid) return -EINVAL; - b->queue_pos = ipu3_css_queue_pos(css, ipu3_css_queues[b->queue].qid, + b->queue_pos = imgu_css_queue_pos(css, imgu_css_queues[b->queue].qid, pipe); if (b->queue_pos >= ARRAY_SIZE(css->pipes[pipe].abi_buffers[b->queue])) @@ -1943,7 +1943,7 @@ int ipu3_css_buf_queue(struct ipu3_css *css, unsigned int pipe, /* Fill struct abi_buffer for firmware */ memset(abi_buf, 0, sizeof(*abi_buf)); - buf_addr = (void *)abi_buf + ipu3_css_queues[b->queue].ptr_ofs; + buf_addr = (void *)abi_buf + imgu_css_queues[b->queue].ptr_ofs; *(imgu_addr_t *)buf_addr = b->daddr; if (b->queue == IPU3_CSS_QUEUE_STAT_3A) @@ -1963,14 +1963,14 @@ int ipu3_css_buf_queue(struct ipu3_css *css, unsigned int pipe, b->state = IPU3_CSS_BUFFER_QUEUED; data = css->pipes[pipe].abi_buffers[b->queue][b->queue_pos].daddr; - r = ipu3_css_queue_data(css, ipu3_css_queues[b->queue].qid, + r = imgu_css_queue_data(css, imgu_css_queues[b->queue].qid, pipe, data); if (r < 0) goto queueing_failed; data = IMGU_ABI_EVENT_BUFFER_ENQUEUED(pipe, - ipu3_css_queues[b->queue].qid); - r = ipu3_css_queue_data(css, IMGU_ABI_QUEUE_EVENT_ID, pipe, data); + imgu_css_queues[b->queue].qid); + r = imgu_css_queue_data(css, IMGU_ABI_QUEUE_EVENT_ID, pipe, data); if (r < 0) goto queueing_failed; @@ -1992,7 +1992,7 @@ queueing_failed: * should be called again, or -EBUSY which means that there are no more * buffers available. May be called from interrupt context. */ -struct ipu3_css_buffer *ipu3_css_buf_dequeue(struct ipu3_css *css) +struct imgu_css_buffer *imgu_css_buf_dequeue(struct imgu_css *css) { static const unsigned char evtype_to_queue[] = { [IMGU_ABI_EVTTYPE_INPUT_FRAME_DONE] = IPU3_CSS_QUEUE_IN, @@ -2000,15 +2000,15 @@ struct ipu3_css_buffer *ipu3_css_buf_dequeue(struct ipu3_css *css) [IMGU_ABI_EVTTYPE_VF_OUT_FRAME_DONE] = IPU3_CSS_QUEUE_VF, [IMGU_ABI_EVTTYPE_3A_STATS_DONE] = IPU3_CSS_QUEUE_STAT_3A, }; - struct ipu3_css_buffer *b = ERR_PTR(-EAGAIN); + struct imgu_css_buffer *b = ERR_PTR(-EAGAIN); u32 event, daddr; int evtype, pipe, pipeid, queue, qid, r; - struct ipu3_css_pipe *css_pipe; + struct imgu_css_pipe *css_pipe; if (!css->streaming) return ERR_PTR(-EPROTO); - r = ipu3_css_dequeue_data(css, IMGU_ABI_QUEUE_EVENT_ID, &event); + r = imgu_css_dequeue_data(css, IMGU_ABI_QUEUE_EVENT_ID, &event); if (r < 0) return ERR_PTR(r); @@ -2025,7 +2025,7 @@ struct ipu3_css_buffer *ipu3_css_buf_dequeue(struct ipu3_css *css) pipeid = (event & IMGU_ABI_EVTTYPE_PIPEID_MASK) >> IMGU_ABI_EVTTYPE_PIPEID_SHIFT; queue = evtype_to_queue[evtype]; - qid = ipu3_css_queues[queue].qid; + qid = imgu_css_queues[queue].qid; if (pipe >= IMGU_MAX_PIPE_NUM) { dev_err(css->dev, "Invalid pipe: %i\n", pipe); @@ -2041,14 +2041,14 @@ struct ipu3_css_buffer *ipu3_css_buf_dequeue(struct ipu3_css *css) "event: buffer done 0x%x queue %i pipe %i pipeid %i\n", event, queue, pipe, pipeid); - r = ipu3_css_dequeue_data(css, qid, &daddr); + r = imgu_css_dequeue_data(css, qid, &daddr); if (r < 0) { dev_err(css->dev, "failed to dequeue buffer\n"); /* Force real error, not -EBUSY */ return ERR_PTR(-EIO); } - r = ipu3_css_queue_data(css, IMGU_ABI_QUEUE_EVENT_ID, pipe, + r = imgu_css_queue_data(css, IMGU_ABI_QUEUE_EVENT_ID, pipe, IMGU_ABI_EVENT_BUFFER_DEQUEUED(qid)); if (r < 0) { dev_err(css->dev, "failed to queue event\n"); @@ -2062,7 +2062,7 @@ struct ipu3_css_buffer *ipu3_css_buf_dequeue(struct ipu3_css *css) return ERR_PTR(-EIO); } b = list_first_entry(&css_pipe->queue[queue].bufs, - struct ipu3_css_buffer, list); + struct imgu_css_buffer, list); if (queue != b->queue || daddr != css_pipe->abi_buffers [b->queue][b->queue_pos].daddr) { @@ -2090,7 +2090,7 @@ struct ipu3_css_buffer *ipu3_css_buf_dequeue(struct ipu3_css *css) event, pipe); break; case IMGU_ABI_EVTTYPE_TIMER: - r = ipu3_css_dequeue_data(css, IMGU_ABI_QUEUE_EVENT_ID, &event); + r = imgu_css_dequeue_data(css, IMGU_ABI_QUEUE_EVENT_ID, &event); if (r < 0) return ERR_PTR(r); @@ -2128,11 +2128,11 @@ struct ipu3_css_buffer *ipu3_css_buf_dequeue(struct ipu3_css *css) * Return index to css->parameter_set_info which has the newly created * parameters or negative value on error. */ -int ipu3_css_set_parameters(struct ipu3_css *css, unsigned int pipe, +int imgu_css_set_parameters(struct imgu_css *css, unsigned int pipe, struct ipu3_uapi_params *set_params) { static const unsigned int queue_id = IMGU_ABI_QUEUE_A_ID; - struct ipu3_css_pipe *css_pipe = &css->pipes[pipe]; + struct imgu_css_pipe *css_pipe = &css->pipes[pipe]; const int stage = 0; const struct imgu_fw_info *bi; int obgrid_size; @@ -2144,7 +2144,7 @@ int ipu3_css_set_parameters(struct ipu3_css *css, unsigned int pipe, struct imgu_abi_acc_param *acc = NULL; struct imgu_abi_gdc_warp_param *gdc = NULL; struct ipu3_uapi_obgrid_param *obgrid = NULL; - const struct ipu3_css_map *map; + const struct imgu_css_map *map; void *vmem0 = NULL; void *dmem0 = NULL; @@ -2157,7 +2157,7 @@ int ipu3_css_set_parameters(struct ipu3_css *css, unsigned int pipe, dev_dbg(css->dev, "%s for pipe %d", __func__, pipe); bi = &css->fwp->binary_header[css_pipe->bindex]; - obgrid_size = ipu3_css_fw_obgrid_size(bi); + obgrid_size = imgu_css_fw_obgrid_size(bi); stripes = bi->info.isp.sp.iterator.num_stripes ? : 1; /* @@ -2165,45 +2165,45 @@ int ipu3_css_set_parameters(struct ipu3_css *css, unsigned int pipe, * parameters from previous buffers will be overwritten. Fix the driver * not to allow this. */ - ipu3_css_pool_get(&css_pipe->pool.parameter_set_info); - param_set = ipu3_css_pool_last(&css_pipe->pool.parameter_set_info, + imgu_css_pool_get(&css_pipe->pool.parameter_set_info); + param_set = imgu_css_pool_last(&css_pipe->pool.parameter_set_info, 0)->vaddr; /* Get a new acc only if new parameters given, or none yet */ - map = ipu3_css_pool_last(&css_pipe->pool.acc, 0); + map = imgu_css_pool_last(&css_pipe->pool.acc, 0); if (set_params || !map->vaddr) { - ipu3_css_pool_get(&css_pipe->pool.acc); - map = ipu3_css_pool_last(&css_pipe->pool.acc, 0); + imgu_css_pool_get(&css_pipe->pool.acc); + map = imgu_css_pool_last(&css_pipe->pool.acc, 0); acc = map->vaddr; } /* Get new VMEM0 only if needed, or none yet */ m = IMGU_ABI_MEM_ISP_VMEM0; - map = ipu3_css_pool_last(&css_pipe->pool.binary_params_p[m], 0); + map = imgu_css_pool_last(&css_pipe->pool.binary_params_p[m], 0); if (!map->vaddr || (set_params && (set_params->use.lin_vmem_params || set_params->use.tnr3_vmem_params || set_params->use.xnr3_vmem_params))) { - ipu3_css_pool_get(&css_pipe->pool.binary_params_p[m]); - map = ipu3_css_pool_last(&css_pipe->pool.binary_params_p[m], 0); + imgu_css_pool_get(&css_pipe->pool.binary_params_p[m]); + map = imgu_css_pool_last(&css_pipe->pool.binary_params_p[m], 0); vmem0 = map->vaddr; } /* Get new DMEM0 only if needed, or none yet */ m = IMGU_ABI_MEM_ISP_DMEM0; - map = ipu3_css_pool_last(&css_pipe->pool.binary_params_p[m], 0); + map = imgu_css_pool_last(&css_pipe->pool.binary_params_p[m], 0); if (!map->vaddr || (set_params && (set_params->use.tnr3_dmem_params || set_params->use.xnr3_dmem_params))) { - ipu3_css_pool_get(&css_pipe->pool.binary_params_p[m]); - map = ipu3_css_pool_last(&css_pipe->pool.binary_params_p[m], 0); + imgu_css_pool_get(&css_pipe->pool.binary_params_p[m]); + map = imgu_css_pool_last(&css_pipe->pool.binary_params_p[m], 0); dmem0 = map->vaddr; } /* Configure acc parameter cluster */ if (acc) { /* get acc_old */ - map = ipu3_css_pool_last(&css_pipe->pool.acc, 1); + map = imgu_css_pool_last(&css_pipe->pool.acc, 1); /* user acc */ - r = ipu3_css_cfg_acc(css, pipe, use, acc, map->vaddr, + r = imgu_css_cfg_acc(css, pipe, use, acc, map->vaddr, set_params ? &set_params->acc_param : NULL); if (r < 0) goto fail; @@ -2212,8 +2212,8 @@ int ipu3_css_set_parameters(struct ipu3_css *css, unsigned int pipe, /* Configure late binding parameters */ if (vmem0) { m = IMGU_ABI_MEM_ISP_VMEM0; - map = ipu3_css_pool_last(&css_pipe->pool.binary_params_p[m], 1); - r = ipu3_css_cfg_vmem0(css, pipe, use, vmem0, + map = imgu_css_pool_last(&css_pipe->pool.binary_params_p[m], 1); + r = imgu_css_cfg_vmem0(css, pipe, use, vmem0, map->vaddr, set_params); if (r < 0) goto fail; @@ -2221,8 +2221,8 @@ int ipu3_css_set_parameters(struct ipu3_css *css, unsigned int pipe, if (dmem0) { m = IMGU_ABI_MEM_ISP_DMEM0; - map = ipu3_css_pool_last(&css_pipe->pool.binary_params_p[m], 1); - r = ipu3_css_cfg_dmem0(css, pipe, use, dmem0, + map = imgu_css_pool_last(&css_pipe->pool.binary_params_p[m], 1); + r = imgu_css_cfg_dmem0(css, pipe, use, dmem0, map->vaddr, set_params); if (r < 0) goto fail; @@ -2234,12 +2234,12 @@ int ipu3_css_set_parameters(struct ipu3_css *css, unsigned int pipe, unsigned int g = IPU3_CSS_RECT_GDC; unsigned int e = IPU3_CSS_RECT_ENVELOPE; - map = ipu3_css_pool_last(&css_pipe->pool.gdc, 0); + map = imgu_css_pool_last(&css_pipe->pool.gdc, 0); if (!map->vaddr) { - ipu3_css_pool_get(&css_pipe->pool.gdc); - map = ipu3_css_pool_last(&css_pipe->pool.gdc, 0); + imgu_css_pool_get(&css_pipe->pool.gdc); + map = imgu_css_pool_last(&css_pipe->pool.gdc, 0); gdc = map->vaddr; - ipu3_css_cfg_gdc_table(map->vaddr, + imgu_css_cfg_gdc_table(map->vaddr, css_pipe->aux_frames[a].bytesperline / css_pipe->aux_frames[a].bytesperpixel, css_pipe->aux_frames[a].height, @@ -2252,10 +2252,10 @@ int ipu3_css_set_parameters(struct ipu3_css *css, unsigned int pipe, } /* Get a new obgrid only if a new obgrid is given, or none yet */ - map = ipu3_css_pool_last(&css_pipe->pool.obgrid, 0); + map = imgu_css_pool_last(&css_pipe->pool.obgrid, 0); if (!map->vaddr || (set_params && set_params->use.obgrid_param)) { - ipu3_css_pool_get(&css_pipe->pool.obgrid); - map = ipu3_css_pool_last(&css_pipe->pool.obgrid, 0); + imgu_css_pool_get(&css_pipe->pool.obgrid); + map = imgu_css_pool_last(&css_pipe->pool.obgrid, 0); obgrid = map->vaddr; /* Configure optical black level grid (obgrid) */ @@ -2269,30 +2269,30 @@ int ipu3_css_set_parameters(struct ipu3_css *css, unsigned int pipe, /* Configure parameter set info, queued to `queue_id' */ memset(param_set, 0, sizeof(*param_set)); - map = ipu3_css_pool_last(&css_pipe->pool.acc, 0); + map = imgu_css_pool_last(&css_pipe->pool.acc, 0); param_set->mem_map.acc_cluster_params_for_sp = map->daddr; - map = ipu3_css_pool_last(&css_pipe->pool.gdc, 0); + map = imgu_css_pool_last(&css_pipe->pool.gdc, 0); param_set->mem_map.dvs_6axis_params_y = map->daddr; for (i = 0; i < stripes; i++) { - map = ipu3_css_pool_last(&css_pipe->pool.obgrid, 0); + map = imgu_css_pool_last(&css_pipe->pool.obgrid, 0); param_set->mem_map.obgrid_tbl[i] = map->daddr + (obgrid_size / stripes) * i; } for (m = 0; m < IMGU_ABI_NUM_MEMORIES; m++) { - map = ipu3_css_pool_last(&css_pipe->pool.binary_params_p[m], 0); + map = imgu_css_pool_last(&css_pipe->pool.binary_params_p[m], 0); param_set->mem_map.isp_mem_param[stage][m] = map->daddr; } /* Then queue the new parameter buffer */ - map = ipu3_css_pool_last(&css_pipe->pool.parameter_set_info, 0); - r = ipu3_css_queue_data(css, queue_id, pipe, map->daddr); + map = imgu_css_pool_last(&css_pipe->pool.parameter_set_info, 0); + r = imgu_css_queue_data(css, queue_id, pipe, map->daddr); if (r < 0) goto fail; - r = ipu3_css_queue_data(css, IMGU_ABI_QUEUE_EVENT_ID, pipe, + r = imgu_css_queue_data(css, IMGU_ABI_QUEUE_EVENT_ID, pipe, IMGU_ABI_EVENT_BUFFER_ENQUEUED(pipe, queue_id)); if (r < 0) @@ -2303,12 +2303,12 @@ int ipu3_css_set_parameters(struct ipu3_css *css, unsigned int pipe, do { u32 daddr; - r = ipu3_css_dequeue_data(css, queue_id, &daddr); + r = imgu_css_dequeue_data(css, queue_id, &daddr); if (r == -EBUSY) break; if (r) goto fail_no_put; - r = ipu3_css_queue_data(css, IMGU_ABI_QUEUE_EVENT_ID, pipe, + r = imgu_css_queue_data(css, IMGU_ABI_QUEUE_EVENT_ID, pipe, IMGU_ABI_EVENT_BUFFER_DEQUEUED (queue_id)); if (r < 0) { @@ -2326,19 +2326,19 @@ fail: * parameters again later. */ - ipu3_css_pool_put(&css_pipe->pool.parameter_set_info); + imgu_css_pool_put(&css_pipe->pool.parameter_set_info); if (acc) - ipu3_css_pool_put(&css_pipe->pool.acc); + imgu_css_pool_put(&css_pipe->pool.acc); if (gdc) - ipu3_css_pool_put(&css_pipe->pool.gdc); + imgu_css_pool_put(&css_pipe->pool.gdc); if (obgrid) - ipu3_css_pool_put(&css_pipe->pool.obgrid); + imgu_css_pool_put(&css_pipe->pool.obgrid); if (vmem0) - ipu3_css_pool_put( + imgu_css_pool_put( &css_pipe->pool.binary_params_p [IMGU_ABI_MEM_ISP_VMEM0]); if (dmem0) - ipu3_css_pool_put( + imgu_css_pool_put( &css_pipe->pool.binary_params_p [IMGU_ABI_MEM_ISP_DMEM0]); @@ -2346,7 +2346,7 @@ fail_no_put: return r; } -int ipu3_css_irq_ack(struct ipu3_css *css) +int imgu_css_irq_ack(struct imgu_css *css) { static const int NUM_SWIRQS = 3; struct imgu_fw_info *bi = &css->fwp->binary_header[css->fw_sp[0]]; diff --git a/drivers/staging/media/ipu3/ipu3-css.h b/drivers/staging/media/ipu3/ipu3-css.h index e88d60f1a0c3..6b8bab27ab1f 100644 --- a/drivers/staging/media/ipu3/ipu3-css.h +++ b/drivers/staging/media/ipu3/ipu3-css.h @@ -43,7 +43,7 @@ * The pipe id type, distinguishes the kind of pipes that * can be run in parallel. */ -enum ipu3_css_pipe_id { +enum imgu_css_pipe_id { IPU3_CSS_PIPE_ID_PREVIEW, IPU3_CSS_PIPE_ID_COPY, IPU3_CSS_PIPE_ID_VIDEO, @@ -53,29 +53,29 @@ enum ipu3_css_pipe_id { IPU3_CSS_PIPE_ID_NUM }; -struct ipu3_css_resolution { +struct imgu_css_resolution { u32 w; u32 h; }; -enum ipu3_css_buffer_state { +enum imgu_css_buffer_state { IPU3_CSS_BUFFER_NEW, /* Not yet queued */ IPU3_CSS_BUFFER_QUEUED, /* Queued, waiting to be filled */ IPU3_CSS_BUFFER_DONE, /* Finished processing, removed from queue */ IPU3_CSS_BUFFER_FAILED, /* Was not processed, removed from queue */ }; -struct ipu3_css_buffer { +struct imgu_css_buffer { /* Private fields: user doesn't touch */ dma_addr_t daddr; unsigned int queue; - enum ipu3_css_buffer_state state; + enum imgu_css_buffer_state state; struct list_head list; u8 queue_pos; unsigned int pipe; }; -struct ipu3_css_format { +struct imgu_css_format { u32 pixelformat; enum v4l2_colorspace colorspace; enum imgu_abi_frame_format frame_format; @@ -89,22 +89,22 @@ struct ipu3_css_format { u8 flags; }; -struct ipu3_css_queue { +struct imgu_css_queue { union { struct v4l2_pix_format_mplane mpix; struct v4l2_meta_format meta; } fmt; - const struct ipu3_css_format *css_fmt; + const struct imgu_css_format *css_fmt; unsigned int width_pad; struct list_head bufs; }; -struct ipu3_css_pipe { - enum ipu3_css_pipe_id pipe_id; +struct imgu_css_pipe { + enum imgu_css_pipe_id pipe_id; unsigned int bindex; - struct ipu3_css_queue queue[IPU3_CSS_QUEUES]; + struct imgu_css_queue queue[IPU3_CSS_QUEUES]; struct v4l2_rect rect[IPU3_CSS_RECTS]; bool vf_output_en; @@ -112,21 +112,21 @@ struct ipu3_css_pipe { spinlock_t qlock; /* Data structures shared with IMGU and driver, always allocated */ - struct ipu3_css_map sp_ddr_ptrs; - struct ipu3_css_map xmem_sp_stage_ptrs[IPU3_CSS_PIPE_ID_NUM] + struct imgu_css_map sp_ddr_ptrs; + struct imgu_css_map xmem_sp_stage_ptrs[IPU3_CSS_PIPE_ID_NUM] [IMGU_ABI_MAX_STAGES]; - struct ipu3_css_map xmem_isp_stage_ptrs[IPU3_CSS_PIPE_ID_NUM] + struct imgu_css_map xmem_isp_stage_ptrs[IPU3_CSS_PIPE_ID_NUM] [IMGU_ABI_MAX_STAGES]; /* * Data structures shared with IMGU and driver, binary specific. * PARAM_CLASS_CONFIG and PARAM_CLASS_STATE parameters. */ - struct ipu3_css_map binary_params_cs[IMGU_ABI_PARAM_CLASS_NUM - 1] + struct imgu_css_map binary_params_cs[IMGU_ABI_PARAM_CLASS_NUM - 1] [IMGU_ABI_NUM_MEMORIES]; struct { - struct ipu3_css_map mem[IPU3_CSS_AUX_FRAMES]; + struct imgu_css_map mem[IPU3_CSS_AUX_FRAMES]; unsigned int width; unsigned int height; unsigned int bytesperline; @@ -134,76 +134,76 @@ struct ipu3_css_pipe { } aux_frames[IPU3_CSS_AUX_FRAME_TYPES]; struct { - struct ipu3_css_pool parameter_set_info; - struct ipu3_css_pool acc; - struct ipu3_css_pool gdc; - struct ipu3_css_pool obgrid; + struct imgu_css_pool parameter_set_info; + struct imgu_css_pool acc; + struct imgu_css_pool gdc; + struct imgu_css_pool obgrid; /* PARAM_CLASS_PARAM parameters for binding while streaming */ - struct ipu3_css_pool binary_params_p[IMGU_ABI_NUM_MEMORIES]; + struct imgu_css_pool binary_params_p[IMGU_ABI_NUM_MEMORIES]; } pool; - struct ipu3_css_map abi_buffers[IPU3_CSS_QUEUES] + struct imgu_css_map abi_buffers[IPU3_CSS_QUEUES] [IMGU_ABI_HOST2SP_BUFQ_SIZE]; }; /* IPU3 Camera Sub System structure */ -struct ipu3_css { +struct imgu_css { struct device *dev; void __iomem *base; const struct firmware *fw; struct imgu_fw_header *fwp; int iomem_length; int fw_bl, fw_sp[IMGU_NUM_SP]; /* Indices of bl and SP binaries */ - struct ipu3_css_map *binary; /* fw binaries mapped to device */ + struct imgu_css_map *binary; /* fw binaries mapped to device */ bool streaming; /* true when streaming is enabled */ - struct ipu3_css_pipe pipes[IMGU_MAX_PIPE_NUM]; - struct ipu3_css_map xmem_sp_group_ptrs; + struct imgu_css_pipe pipes[IMGU_MAX_PIPE_NUM]; + struct imgu_css_map xmem_sp_group_ptrs; /* enabled pipe(s) */ DECLARE_BITMAP(enabled_pipes, IMGU_MAX_PIPE_NUM); }; /******************* css v4l *******************/ -int ipu3_css_init(struct device *dev, struct ipu3_css *css, +int imgu_css_init(struct device *dev, struct imgu_css *css, void __iomem *base, int length); -void ipu3_css_cleanup(struct ipu3_css *css); -int ipu3_css_fmt_try(struct ipu3_css *css, +void imgu_css_cleanup(struct imgu_css *css); +int imgu_css_fmt_try(struct imgu_css *css, struct v4l2_pix_format_mplane *fmts[IPU3_CSS_QUEUES], struct v4l2_rect *rects[IPU3_CSS_RECTS], unsigned int pipe); -int ipu3_css_fmt_set(struct ipu3_css *css, +int imgu_css_fmt_set(struct imgu_css *css, struct v4l2_pix_format_mplane *fmts[IPU3_CSS_QUEUES], struct v4l2_rect *rects[IPU3_CSS_RECTS], unsigned int pipe); -int ipu3_css_meta_fmt_set(struct v4l2_meta_format *fmt); -int ipu3_css_buf_queue(struct ipu3_css *css, unsigned int pipe, - struct ipu3_css_buffer *b); -struct ipu3_css_buffer *ipu3_css_buf_dequeue(struct ipu3_css *css); -int ipu3_css_start_streaming(struct ipu3_css *css); -void ipu3_css_stop_streaming(struct ipu3_css *css); -bool ipu3_css_queue_empty(struct ipu3_css *css); -bool ipu3_css_is_streaming(struct ipu3_css *css); -bool ipu3_css_pipe_queue_empty(struct ipu3_css *css, unsigned int pipe); +int imgu_css_meta_fmt_set(struct v4l2_meta_format *fmt); +int imgu_css_buf_queue(struct imgu_css *css, unsigned int pipe, + struct imgu_css_buffer *b); +struct imgu_css_buffer *imgu_css_buf_dequeue(struct imgu_css *css); +int imgu_css_start_streaming(struct imgu_css *css); +void imgu_css_stop_streaming(struct imgu_css *css); +bool imgu_css_queue_empty(struct imgu_css *css); +bool imgu_css_is_streaming(struct imgu_css *css); +bool imgu_css_pipe_queue_empty(struct imgu_css *css, unsigned int pipe); /******************* css hw *******************/ -int ipu3_css_set_powerup(struct device *dev, void __iomem *base); -void ipu3_css_set_powerdown(struct device *dev, void __iomem *base); -int ipu3_css_irq_ack(struct ipu3_css *css); +int imgu_css_set_powerup(struct device *dev, void __iomem *base); +void imgu_css_set_powerdown(struct device *dev, void __iomem *base); +int imgu_css_irq_ack(struct imgu_css *css); /******************* set parameters ************/ -int ipu3_css_set_parameters(struct ipu3_css *css, unsigned int pipe, +int imgu_css_set_parameters(struct imgu_css *css, unsigned int pipe, struct ipu3_uapi_params *set_params); /******************* auxiliary helpers *******************/ -static inline enum ipu3_css_buffer_state -ipu3_css_buf_state(struct ipu3_css_buffer *b) +static inline enum imgu_css_buffer_state +imgu_css_buf_state(struct imgu_css_buffer *b) { return b->state; } /* Initialize given buffer. May be called several times. */ -static inline void ipu3_css_buf_init(struct ipu3_css_buffer *b, +static inline void imgu_css_buf_init(struct imgu_css_buffer *b, unsigned int queue, dma_addr_t daddr) { b->state = IPU3_CSS_BUFFER_NEW; diff --git a/drivers/staging/media/ipu3/ipu3-dmamap.c b/drivers/staging/media/ipu3/ipu3-dmamap.c index 93a393d4e15e..d978a00e1e0b 100644 --- a/drivers/staging/media/ipu3/ipu3-dmamap.c +++ b/drivers/staging/media/ipu3/ipu3-dmamap.c @@ -12,11 +12,12 @@ #include "ipu3.h" #include "ipu3-css-pool.h" #include "ipu3-mmu.h" +#include "ipu3-dmamap.h" /* - * Free a buffer allocated by ipu3_dmamap_alloc_buffer() + * Free a buffer allocated by imgu_dmamap_alloc_buffer() */ -static void ipu3_dmamap_free_buffer(struct page **pages, +static void imgu_dmamap_free_buffer(struct page **pages, size_t size) { int count = size >> PAGE_SHIFT; @@ -30,7 +31,7 @@ static void ipu3_dmamap_free_buffer(struct page **pages, * Based on the implementation of __iommu_dma_alloc_pages() * defined in drivers/iommu/dma-iommu.c */ -static struct page **ipu3_dmamap_alloc_buffer(size_t size, +static struct page **imgu_dmamap_alloc_buffer(size_t size, unsigned long order_mask, gfp_t gfp) { @@ -73,7 +74,7 @@ static struct page **ipu3_dmamap_alloc_buffer(size_t size, __free_pages(page, order); } if (!page) { - ipu3_dmamap_free_buffer(pages, i << PAGE_SHIFT); + imgu_dmamap_free_buffer(pages, i << PAGE_SHIFT); return NULL; } count -= order_size; @@ -85,7 +86,7 @@ static struct page **ipu3_dmamap_alloc_buffer(size_t size, } /** - * ipu3_dmamap_alloc - allocate and map a buffer into KVA + * imgu_dmamap_alloc - allocate and map a buffer into KVA * @imgu: struct device pointer * @map: struct to store mapping variables * @len: size required @@ -94,7 +95,7 @@ static struct page **ipu3_dmamap_alloc_buffer(size_t size, * KVA on success * %NULL on failure */ -void *ipu3_dmamap_alloc(struct imgu_device *imgu, struct ipu3_css_map *map, +void *imgu_dmamap_alloc(struct imgu_device *imgu, struct imgu_css_map *map, size_t len) { unsigned long shift = iova_shift(&imgu->iova_domain); @@ -113,7 +114,7 @@ void *ipu3_dmamap_alloc(struct imgu_device *imgu, struct ipu3_css_map *map, if (!iova) return NULL; - pages = ipu3_dmamap_alloc_buffer(size, alloc_sizes >> PAGE_SHIFT, + pages = imgu_dmamap_alloc_buffer(size, alloc_sizes >> PAGE_SHIFT, GFP_KERNEL); if (!pages) goto out_free_iova; @@ -121,7 +122,7 @@ void *ipu3_dmamap_alloc(struct imgu_device *imgu, struct ipu3_css_map *map, /* Call IOMMU driver to setup pgt */ iovaddr = iova_dma_addr(&imgu->iova_domain, iova); for (i = 0; i < size / PAGE_SIZE; ++i) { - rval = ipu3_mmu_map(imgu->mmu, iovaddr, + rval = imgu_mmu_map(imgu->mmu, iovaddr, page_to_phys(pages[i]), PAGE_SIZE); if (rval) goto out_unmap; @@ -152,8 +153,8 @@ out_vunmap: vunmap(map->vma->addr); out_unmap: - ipu3_dmamap_free_buffer(pages, size); - ipu3_mmu_unmap(imgu->mmu, iova_dma_addr(&imgu->iova_domain, iova), + imgu_dmamap_free_buffer(pages, size); + imgu_mmu_unmap(imgu->mmu, iova_dma_addr(&imgu->iova_domain, iova), i * PAGE_SIZE); map->vma = NULL; @@ -163,7 +164,7 @@ out_free_iova: return NULL; } -void ipu3_dmamap_unmap(struct imgu_device *imgu, struct ipu3_css_map *map) +void imgu_dmamap_unmap(struct imgu_device *imgu, struct imgu_css_map *map) { struct iova *iova; @@ -172,16 +173,16 @@ void ipu3_dmamap_unmap(struct imgu_device *imgu, struct ipu3_css_map *map) if (WARN_ON(!iova)) return; - ipu3_mmu_unmap(imgu->mmu, iova_dma_addr(&imgu->iova_domain, iova), + imgu_mmu_unmap(imgu->mmu, iova_dma_addr(&imgu->iova_domain, iova), iova_size(iova) << iova_shift(&imgu->iova_domain)); __free_iova(&imgu->iova_domain, iova); } /* - * Counterpart of ipu3_dmamap_alloc + * Counterpart of imgu_dmamap_alloc */ -void ipu3_dmamap_free(struct imgu_device *imgu, struct ipu3_css_map *map) +void imgu_dmamap_free(struct imgu_device *imgu, struct imgu_css_map *map) { struct vm_struct *area = map->vma; @@ -191,18 +192,18 @@ void ipu3_dmamap_free(struct imgu_device *imgu, struct ipu3_css_map *map) if (!map->vaddr) return; - ipu3_dmamap_unmap(imgu, map); + imgu_dmamap_unmap(imgu, map); if (WARN_ON(!area) || WARN_ON(!area->pages)) return; - ipu3_dmamap_free_buffer(area->pages, map->size); + imgu_dmamap_free_buffer(area->pages, map->size); vunmap(map->vaddr); map->vaddr = NULL; } -int ipu3_dmamap_map_sg(struct imgu_device *imgu, struct scatterlist *sglist, - int nents, struct ipu3_css_map *map) +int imgu_dmamap_map_sg(struct imgu_device *imgu, struct scatterlist *sglist, + int nents, struct imgu_css_map *map) { unsigned long shift = iova_shift(&imgu->iova_domain); struct scatterlist *sg; @@ -232,7 +233,7 @@ int ipu3_dmamap_map_sg(struct imgu_device *imgu, struct scatterlist *sglist, dev_dbg(&imgu->pci_dev->dev, "dmamap: iova low pfn %lu, high pfn %lu\n", iova->pfn_lo, iova->pfn_hi); - if (ipu3_mmu_map_sg(imgu->mmu, iova_dma_addr(&imgu->iova_domain, iova), + if (imgu_mmu_map_sg(imgu->mmu, iova_dma_addr(&imgu->iova_domain, iova), sglist, nents) < size) goto out_fail; @@ -248,7 +249,7 @@ out_fail: return -EFAULT; } -int ipu3_dmamap_init(struct imgu_device *imgu) +int imgu_dmamap_init(struct imgu_device *imgu) { unsigned long order, base_pfn; int ret = iova_cache_get(); @@ -263,7 +264,7 @@ int ipu3_dmamap_init(struct imgu_device *imgu) return 0; } -void ipu3_dmamap_exit(struct imgu_device *imgu) +void imgu_dmamap_exit(struct imgu_device *imgu) { put_iova_domain(&imgu->iova_domain); iova_cache_put(); diff --git a/drivers/staging/media/ipu3/ipu3-dmamap.h b/drivers/staging/media/ipu3/ipu3-dmamap.h index b9d224a33273..9db513b3d603 100644 --- a/drivers/staging/media/ipu3/ipu3-dmamap.h +++ b/drivers/staging/media/ipu3/ipu3-dmamap.h @@ -8,15 +8,15 @@ struct imgu_device; struct scatterlist; -void *ipu3_dmamap_alloc(struct imgu_device *imgu, struct ipu3_css_map *map, +void *imgu_dmamap_alloc(struct imgu_device *imgu, struct imgu_css_map *map, size_t len); -void ipu3_dmamap_free(struct imgu_device *imgu, struct ipu3_css_map *map); +void imgu_dmamap_free(struct imgu_device *imgu, struct imgu_css_map *map); -int ipu3_dmamap_map_sg(struct imgu_device *imgu, struct scatterlist *sglist, - int nents, struct ipu3_css_map *map); -void ipu3_dmamap_unmap(struct imgu_device *imgu, struct ipu3_css_map *map); +int imgu_dmamap_map_sg(struct imgu_device *imgu, struct scatterlist *sglist, + int nents, struct imgu_css_map *map); +void imgu_dmamap_unmap(struct imgu_device *imgu, struct imgu_css_map *map); -int ipu3_dmamap_init(struct imgu_device *imgu); -void ipu3_dmamap_exit(struct imgu_device *imgu); +int imgu_dmamap_init(struct imgu_device *imgu); +void imgu_dmamap_exit(struct imgu_device *imgu); #endif diff --git a/drivers/staging/media/ipu3/ipu3-mmu.c b/drivers/staging/media/ipu3/ipu3-mmu.c index b9f209541f78..cfc2bdfb14b3 100644 --- a/drivers/staging/media/ipu3/ipu3-mmu.c +++ b/drivers/staging/media/ipu3/ipu3-mmu.c @@ -48,7 +48,7 @@ #define REG_GP_HALT (IMGU_REG_BASE + 0x5dc) #define REG_GP_HALTED (IMGU_REG_BASE + 0x5e0) -struct ipu3_mmu { +struct imgu_mmu { struct device *dev; void __iomem *base; /* protect access to l2pts, l1pt */ @@ -63,28 +63,28 @@ struct ipu3_mmu { u32 **l2pts; u32 *l1pt; - struct ipu3_mmu_info geometry; + struct imgu_mmu_info geometry; }; -static inline struct ipu3_mmu *to_ipu3_mmu(struct ipu3_mmu_info *info) +static inline struct imgu_mmu *to_imgu_mmu(struct imgu_mmu_info *info) { - return container_of(info, struct ipu3_mmu, geometry); + return container_of(info, struct imgu_mmu, geometry); } /** - * ipu3_mmu_tlb_invalidate - invalidate translation look-aside buffer + * imgu_mmu_tlb_invalidate - invalidate translation look-aside buffer * @mmu: MMU to perform the invalidate operation on * * This function invalidates the whole TLB. Must be called when the hardware * is powered on. */ -static void ipu3_mmu_tlb_invalidate(struct ipu3_mmu *mmu) +static void imgu_mmu_tlb_invalidate(struct imgu_mmu *mmu) { writel(TLB_INVALIDATE, mmu->base + REG_TLB_INVALIDATE); } -static void call_if_ipu3_is_powered(struct ipu3_mmu *mmu, - void (*func)(struct ipu3_mmu *mmu)) +static void call_if_imgu_is_powered(struct imgu_mmu *mmu, + void (*func)(struct imgu_mmu *mmu)) { if (!pm_runtime_get_if_in_use(mmu->dev)) return; @@ -94,14 +94,14 @@ static void call_if_ipu3_is_powered(struct ipu3_mmu *mmu, } /** - * ipu3_mmu_set_halt - set CIO gate halt bit + * imgu_mmu_set_halt - set CIO gate halt bit * @mmu: MMU to set the CIO gate bit in. * @halt: Desired state of the gate bit. * * This function sets the CIO gate bit that controls whether external memory * accesses are allowed. Must be called when the hardware is powered on. */ -static void ipu3_mmu_set_halt(struct ipu3_mmu *mmu, bool halt) +static void imgu_mmu_set_halt(struct imgu_mmu *mmu, bool halt) { int ret; u32 val; @@ -116,12 +116,12 @@ static void ipu3_mmu_set_halt(struct ipu3_mmu *mmu, bool halt) } /** - * ipu3_mmu_alloc_page_table - allocate a pre-filled page table + * imgu_mmu_alloc_page_table - allocate a pre-filled page table * @pteval: Value to initialize for page table entries with. * * Return: Pointer to allocated page table or NULL on failure. */ -static u32 *ipu3_mmu_alloc_page_table(u32 pteval) +static u32 *imgu_mmu_alloc_page_table(u32 pteval) { u32 *pt; int pte; @@ -139,10 +139,10 @@ static u32 *ipu3_mmu_alloc_page_table(u32 pteval) } /** - * ipu3_mmu_free_page_table - free page table + * imgu_mmu_free_page_table - free page table * @pt: Page table to free. */ -static void ipu3_mmu_free_page_table(u32 *pt) +static void imgu_mmu_free_page_table(u32 *pt) { set_memory_wb((unsigned long int)pt, IPU3_PT_ORDER); free_page((unsigned long)pt); @@ -168,7 +168,7 @@ static inline void address_to_pte_idx(unsigned long iova, u32 *l1pt_idx, *l1pt_idx = iova & IPU3_L1PT_MASK; } -static u32 *ipu3_mmu_get_l2pt(struct ipu3_mmu *mmu, u32 l1pt_idx) +static u32 *imgu_mmu_get_l2pt(struct imgu_mmu *mmu, u32 l1pt_idx) { unsigned long flags; u32 *l2pt, *new_l2pt; @@ -182,7 +182,7 @@ static u32 *ipu3_mmu_get_l2pt(struct ipu3_mmu *mmu, u32 l1pt_idx) spin_unlock_irqrestore(&mmu->lock, flags); - new_l2pt = ipu3_mmu_alloc_page_table(mmu->dummy_page_pteval); + new_l2pt = imgu_mmu_alloc_page_table(mmu->dummy_page_pteval); if (!new_l2pt) return NULL; @@ -193,7 +193,7 @@ static u32 *ipu3_mmu_get_l2pt(struct ipu3_mmu *mmu, u32 l1pt_idx) l2pt = mmu->l2pts[l1pt_idx]; if (l2pt) { - ipu3_mmu_free_page_table(new_l2pt); + imgu_mmu_free_page_table(new_l2pt); goto done; } @@ -208,7 +208,7 @@ done: return l2pt; } -static int __ipu3_mmu_map(struct ipu3_mmu *mmu, unsigned long iova, +static int __imgu_mmu_map(struct imgu_mmu *mmu, unsigned long iova, phys_addr_t paddr) { u32 l1pt_idx, l2pt_idx; @@ -220,7 +220,7 @@ static int __ipu3_mmu_map(struct ipu3_mmu *mmu, unsigned long iova, address_to_pte_idx(iova, &l1pt_idx, &l2pt_idx); - l2pt = ipu3_mmu_get_l2pt(mmu, l1pt_idx); + l2pt = imgu_mmu_get_l2pt(mmu, l1pt_idx); if (!l2pt) return -ENOMEM; @@ -238,11 +238,11 @@ static int __ipu3_mmu_map(struct ipu3_mmu *mmu, unsigned long iova, return 0; } -/** +/* * The following four functions are implemented based on iommu.c * drivers/iommu/iommu.c/iommu_pgsize(). */ -static size_t ipu3_mmu_pgsize(unsigned long pgsize_bitmap, +static size_t imgu_mmu_pgsize(unsigned long pgsize_bitmap, unsigned long addr_merge, size_t size) { unsigned int pgsize_idx; @@ -276,10 +276,10 @@ static size_t ipu3_mmu_pgsize(unsigned long pgsize_bitmap, } /* drivers/iommu/iommu.c/iommu_map() */ -int ipu3_mmu_map(struct ipu3_mmu_info *info, unsigned long iova, +int imgu_mmu_map(struct imgu_mmu_info *info, unsigned long iova, phys_addr_t paddr, size_t size) { - struct ipu3_mmu *mmu = to_ipu3_mmu(info); + struct imgu_mmu *mmu = to_imgu_mmu(info); unsigned int min_pagesz; int ret = 0; @@ -301,13 +301,13 @@ int ipu3_mmu_map(struct ipu3_mmu_info *info, unsigned long iova, iova, &paddr, size); while (size) { - size_t pgsize = ipu3_mmu_pgsize(mmu->geometry.pgsize_bitmap, + size_t pgsize = imgu_mmu_pgsize(mmu->geometry.pgsize_bitmap, iova | paddr, size); dev_dbg(mmu->dev, "mapping: iova 0x%lx pa %pa pgsize 0x%zx\n", iova, &paddr, pgsize); - ret = __ipu3_mmu_map(mmu, iova, paddr); + ret = __imgu_mmu_map(mmu, iova, paddr); if (ret) break; @@ -316,16 +316,16 @@ int ipu3_mmu_map(struct ipu3_mmu_info *info, unsigned long iova, size -= pgsize; } - call_if_ipu3_is_powered(mmu, ipu3_mmu_tlb_invalidate); + call_if_imgu_is_powered(mmu, imgu_mmu_tlb_invalidate); return ret; } /* drivers/iommu/iommu.c/default_iommu_map_sg() */ -size_t ipu3_mmu_map_sg(struct ipu3_mmu_info *info, unsigned long iova, +size_t imgu_mmu_map_sg(struct imgu_mmu_info *info, unsigned long iova, struct scatterlist *sg, unsigned int nents) { - struct ipu3_mmu *mmu = to_ipu3_mmu(info); + struct imgu_mmu *mmu = to_imgu_mmu(info); struct scatterlist *s; size_t s_length, mapped = 0; unsigned int i, min_pagesz; @@ -345,25 +345,25 @@ size_t ipu3_mmu_map_sg(struct ipu3_mmu_info *info, unsigned long iova, if (i == nents - 1 && !IS_ALIGNED(s->length, min_pagesz)) s_length = PAGE_ALIGN(s->length); - ret = ipu3_mmu_map(info, iova + mapped, phys, s_length); + ret = imgu_mmu_map(info, iova + mapped, phys, s_length); if (ret) goto out_err; mapped += s_length; } - call_if_ipu3_is_powered(mmu, ipu3_mmu_tlb_invalidate); + call_if_imgu_is_powered(mmu, imgu_mmu_tlb_invalidate); return mapped; out_err: /* undo mappings already done */ - ipu3_mmu_unmap(info, iova, mapped); + imgu_mmu_unmap(info, iova, mapped); return 0; } -static size_t __ipu3_mmu_unmap(struct ipu3_mmu *mmu, +static size_t __imgu_mmu_unmap(struct imgu_mmu *mmu, unsigned long iova, size_t size) { u32 l1pt_idx, l2pt_idx; @@ -395,10 +395,10 @@ static size_t __ipu3_mmu_unmap(struct ipu3_mmu *mmu, } /* drivers/iommu/iommu.c/iommu_unmap() */ -size_t ipu3_mmu_unmap(struct ipu3_mmu_info *info, unsigned long iova, +size_t imgu_mmu_unmap(struct imgu_mmu_info *info, unsigned long iova, size_t size) { - struct ipu3_mmu *mmu = to_ipu3_mmu(info); + struct imgu_mmu *mmu = to_imgu_mmu(info); size_t unmapped_page, unmapped = 0; unsigned int min_pagesz; @@ -423,10 +423,10 @@ size_t ipu3_mmu_unmap(struct ipu3_mmu_info *info, unsigned long iova, * or we hit an area that isn't mapped. */ while (unmapped < size) { - size_t pgsize = ipu3_mmu_pgsize(mmu->geometry.pgsize_bitmap, + size_t pgsize = imgu_mmu_pgsize(mmu->geometry.pgsize_bitmap, iova, size - unmapped); - unmapped_page = __ipu3_mmu_unmap(mmu, iova, pgsize); + unmapped_page = __imgu_mmu_unmap(mmu, iova, pgsize); if (!unmapped_page) break; @@ -437,20 +437,21 @@ size_t ipu3_mmu_unmap(struct ipu3_mmu_info *info, unsigned long iova, unmapped += unmapped_page; } - call_if_ipu3_is_powered(mmu, ipu3_mmu_tlb_invalidate); + call_if_imgu_is_powered(mmu, imgu_mmu_tlb_invalidate); return unmapped; } /** - * ipu3_mmu_init() - initialize IPU3 MMU block + * imgu_mmu_init() - initialize IPU3 MMU block + * @parent: struct device parent * @base: IOMEM base of hardware registers. * * Return: Pointer to IPU3 MMU private data pointer or ERR_PTR() on error. */ -struct ipu3_mmu_info *ipu3_mmu_init(struct device *parent, void __iomem *base) +struct imgu_mmu_info *imgu_mmu_init(struct device *parent, void __iomem *base) { - struct ipu3_mmu *mmu; + struct imgu_mmu *mmu; u32 pteval; mmu = kzalloc(sizeof(*mmu), GFP_KERNEL); @@ -462,7 +463,7 @@ struct ipu3_mmu_info *ipu3_mmu_init(struct device *parent, void __iomem *base) spin_lock_init(&mmu->lock); /* Disallow external memory access when having no valid page tables. */ - ipu3_mmu_set_halt(mmu, true); + imgu_mmu_set_halt(mmu, true); /* * The MMU does not have a "valid" bit, so we have to use a dummy @@ -478,7 +479,7 @@ struct ipu3_mmu_info *ipu3_mmu_init(struct device *parent, void __iomem *base) * Allocate a dummy L2 page table with all entries pointing to * the dummy page. */ - mmu->dummy_l2pt = ipu3_mmu_alloc_page_table(pteval); + mmu->dummy_l2pt = imgu_mmu_alloc_page_table(pteval); if (!mmu->dummy_l2pt) goto fail_dummy_page; pteval = IPU3_ADDR2PTE(virt_to_phys(mmu->dummy_l2pt)); @@ -493,14 +494,14 @@ struct ipu3_mmu_info *ipu3_mmu_init(struct device *parent, void __iomem *base) goto fail_l2pt; /* Allocate the L1 page table. */ - mmu->l1pt = ipu3_mmu_alloc_page_table(mmu->dummy_l2pt_pteval); + mmu->l1pt = imgu_mmu_alloc_page_table(mmu->dummy_l2pt_pteval); if (!mmu->l1pt) goto fail_l2pts; pteval = IPU3_ADDR2PTE(virt_to_phys(mmu->l1pt)); writel(pteval, mmu->base + REG_L1_PHYS); - ipu3_mmu_tlb_invalidate(mmu); - ipu3_mmu_set_halt(mmu, false); + imgu_mmu_tlb_invalidate(mmu); + imgu_mmu_set_halt(mmu, false); mmu->geometry.aperture_start = 0; mmu->geometry.aperture_end = DMA_BIT_MASK(IPU3_MMU_ADDRESS_BITS); @@ -511,7 +512,7 @@ struct ipu3_mmu_info *ipu3_mmu_init(struct device *parent, void __iomem *base) fail_l2pts: vfree(mmu->l2pts); fail_l2pt: - ipu3_mmu_free_page_table(mmu->dummy_l2pt); + imgu_mmu_free_page_table(mmu->dummy_l2pt); fail_dummy_page: free_page((unsigned long)mmu->dummy_page); fail_group: @@ -521,41 +522,41 @@ fail_group: } /** - * ipu3_mmu_exit() - clean up IPU3 MMU block - * @mmu: IPU3 MMU private data + * imgu_mmu_exit() - clean up IPU3 MMU block + * @info: IPU3 MMU private data */ -void ipu3_mmu_exit(struct ipu3_mmu_info *info) +void imgu_mmu_exit(struct imgu_mmu_info *info) { - struct ipu3_mmu *mmu = to_ipu3_mmu(info); + struct imgu_mmu *mmu = to_imgu_mmu(info); /* We are going to free our page tables, no more memory access. */ - ipu3_mmu_set_halt(mmu, true); - ipu3_mmu_tlb_invalidate(mmu); + imgu_mmu_set_halt(mmu, true); + imgu_mmu_tlb_invalidate(mmu); - ipu3_mmu_free_page_table(mmu->l1pt); + imgu_mmu_free_page_table(mmu->l1pt); vfree(mmu->l2pts); - ipu3_mmu_free_page_table(mmu->dummy_l2pt); + imgu_mmu_free_page_table(mmu->dummy_l2pt); free_page((unsigned long)mmu->dummy_page); kfree(mmu); } -void ipu3_mmu_suspend(struct ipu3_mmu_info *info) +void imgu_mmu_suspend(struct imgu_mmu_info *info) { - struct ipu3_mmu *mmu = to_ipu3_mmu(info); + struct imgu_mmu *mmu = to_imgu_mmu(info); - ipu3_mmu_set_halt(mmu, true); + imgu_mmu_set_halt(mmu, true); } -void ipu3_mmu_resume(struct ipu3_mmu_info *info) +void imgu_mmu_resume(struct imgu_mmu_info *info) { - struct ipu3_mmu *mmu = to_ipu3_mmu(info); + struct imgu_mmu *mmu = to_imgu_mmu(info); u32 pteval; - ipu3_mmu_set_halt(mmu, true); + imgu_mmu_set_halt(mmu, true); pteval = IPU3_ADDR2PTE(virt_to_phys(mmu->l1pt)); writel(pteval, mmu->base + REG_L1_PHYS); - ipu3_mmu_tlb_invalidate(mmu); - ipu3_mmu_set_halt(mmu, false); + imgu_mmu_tlb_invalidate(mmu); + imgu_mmu_set_halt(mmu, false); } diff --git a/drivers/staging/media/ipu3/ipu3-mmu.h b/drivers/staging/media/ipu3/ipu3-mmu.h index 8fe63b4c6e1c..fa58827eb19c 100644 --- a/drivers/staging/media/ipu3/ipu3-mmu.h +++ b/drivers/staging/media/ipu3/ipu3-mmu.h @@ -6,13 +6,13 @@ #define __IPU3_MMU_H /** - * struct ipu3_mmu_info - Describes mmu geometry + * struct imgu_mmu_info - Describes mmu geometry * * @aperture_start: First address that can be mapped * @aperture_end: Last address that can be mapped * @pgsize_bitmap: Bitmap of page sizes in use */ -struct ipu3_mmu_info { +struct imgu_mmu_info { dma_addr_t aperture_start; dma_addr_t aperture_end; unsigned long pgsize_bitmap; @@ -21,15 +21,15 @@ struct ipu3_mmu_info { struct device; struct scatterlist; -struct ipu3_mmu_info *ipu3_mmu_init(struct device *parent, void __iomem *base); -void ipu3_mmu_exit(struct ipu3_mmu_info *info); -void ipu3_mmu_suspend(struct ipu3_mmu_info *info); -void ipu3_mmu_resume(struct ipu3_mmu_info *info); +struct imgu_mmu_info *imgu_mmu_init(struct device *parent, void __iomem *base); +void imgu_mmu_exit(struct imgu_mmu_info *info); +void imgu_mmu_suspend(struct imgu_mmu_info *info); +void imgu_mmu_resume(struct imgu_mmu_info *info); -int ipu3_mmu_map(struct ipu3_mmu_info *info, unsigned long iova, +int imgu_mmu_map(struct imgu_mmu_info *info, unsigned long iova, phys_addr_t paddr, size_t size); -size_t ipu3_mmu_unmap(struct ipu3_mmu_info *info, unsigned long iova, +size_t imgu_mmu_unmap(struct imgu_mmu_info *info, unsigned long iova, size_t size); -size_t ipu3_mmu_map_sg(struct ipu3_mmu_info *info, unsigned long iova, +size_t imgu_mmu_map_sg(struct imgu_mmu_info *info, unsigned long iova, struct scatterlist *sg, unsigned int nents); #endif diff --git a/drivers/staging/media/ipu3/ipu3-tables.c b/drivers/staging/media/ipu3/ipu3-tables.c index 334517987eba..3a3730bd4395 100644 --- a/drivers/staging/media/ipu3/ipu3-tables.c +++ b/drivers/staging/media/ipu3/ipu3-tables.c @@ -5,8 +5,8 @@ #define X 0 /* Don't care value */ -const struct ipu3_css_bds_config - ipu3_css_bds_configs[IMGU_BDS_CONFIG_LEN] = { { +const struct imgu_css_bds_config + imgu_css_bds_configs[IMGU_BDS_CONFIG_LEN] = { { /* Scale factor 32 / (32 + 0) = 1 */ .hor_phase_arr = { .even = { { 0, 0, 64, 6, 0, 0, 0 } }, @@ -9015,7 +9015,7 @@ const struct ipu3_css_bds_config .ver_ds_en = 1 } }; -const s32 ipu3_css_downscale_4taps[IMGU_SCALER_DOWNSCALE_4TAPS_LEN] = { +const s32 imgu_css_downscale_4taps[IMGU_SCALER_DOWNSCALE_4TAPS_LEN] = { IMGU_SCALER_FP * -0.000000000000000, IMGU_SCALER_FP * -0.000249009327023, IMGU_SCALER_FP * -0.001022241683322, @@ -9146,7 +9146,7 @@ const s32 ipu3_css_downscale_4taps[IMGU_SCALER_DOWNSCALE_4TAPS_LEN] = { IMGU_SCALER_FP * -0.000249009327023 }; -const s32 ipu3_css_downscale_2taps[IMGU_SCALER_DOWNSCALE_2TAPS_LEN] = { +const s32 imgu_css_downscale_2taps[IMGU_SCALER_DOWNSCALE_2TAPS_LEN] = { IMGU_SCALER_FP * 0.074300676367033, IMGU_SCALER_FP * 0.094030234498392, IMGU_SCALER_FP * 0.115522859526596, @@ -9214,7 +9214,7 @@ const s32 ipu3_css_downscale_2taps[IMGU_SCALER_DOWNSCALE_2TAPS_LEN] = { }; /* settings for Geometric Distortion Correction */ -const s16 ipu3_css_gdc_lut[4][256] = { { +const s16 imgu_css_gdc_lut[4][256] = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, -2, -2, -2, -2, -3, -3, -3, -4, -4, -4, -5, -5, -5, -6, -6, -7, -7, -7, -8, -8, -9, -9, -10, -10, -11, -11, -12, -12, -13, -13, -14, -14, -15, -15, @@ -9292,7 +9292,7 @@ const s16 ipu3_css_gdc_lut[4][256] = { { -1, 0, 1, 0, 0, 0, 0, 0, 0, 0 } }; -const struct ipu3_css_xnr3_vmem_defaults ipu3_css_xnr3_vmem_defaults = { +const struct imgu_css_xnr3_vmem_defaults imgu_css_xnr3_vmem_defaults = { .x = { 1024, 1164, 1320, 1492, 1680, 1884, 2108, 2352, 2616, 2900, 3208, 3540, 3896, 4276, 4684, 5120 @@ -9311,7 +9311,7 @@ const struct ipu3_css_xnr3_vmem_defaults ipu3_css_xnr3_vmem_defaults = { }; /* settings for Bayer Noise Reduction */ -const struct ipu3_uapi_bnr_static_config ipu3_css_bnr_defaults = { +const struct ipu3_uapi_bnr_static_config imgu_css_bnr_defaults = { { 16, 16, 16, 16 }, /* wb_gains */ { 16, 16, 16, 16 }, /* wb_gains_thr */ { 0, X, 8, 6, X, 14 }, /* thr_coeffs */ @@ -9327,18 +9327,18 @@ const struct ipu3_uapi_bnr_static_config ipu3_css_bnr_defaults = { { 8, 4, 4, X, 8, X, 1, 1, 1, 1 }, /* dn_detect_ctrl */ }; -const struct ipu3_uapi_dm_config ipu3_css_dm_defaults = { +const struct ipu3_uapi_dm_config imgu_css_dm_defaults = { 1, 1, 1, X, X, 8, X, 7, X, 8, X, 8, X, 4, X }; -const struct ipu3_uapi_ccm_mat_config ipu3_css_ccm_defaults = { +const struct ipu3_uapi_ccm_mat_config imgu_css_ccm_defaults = { 9775, -2671, 1087, 0, -1071, 8303, 815, 0, -23, -7887, 16103, 0 }; /* settings for Gamma correction */ -const struct ipu3_uapi_gamma_corr_lut ipu3_css_gamma_lut = { { +const struct ipu3_uapi_gamma_corr_lut imgu_css_gamma_lut = { { 63, 79, 95, 111, 127, 143, 159, 175, 191, 207, 223, 239, 255, 271, 287, 303, 319, 335, 351, 367, 383, 399, 415, 431, 447, 463, 479, 495, 511, 527, 543, 559, 575, 591, 607, 623, 639, 655, 671, 687, 703, 719, 735, @@ -9362,13 +9362,13 @@ const struct ipu3_uapi_gamma_corr_lut ipu3_css_gamma_lut = { { 7807, 7871, 7935, 7999, 8063, 8127, 8191 } }; -const struct ipu3_uapi_csc_mat_config ipu3_css_csc_defaults = { +const struct ipu3_uapi_csc_mat_config imgu_css_csc_defaults = { 4898, 9617, 1867, 0, -2410, -4732, 7143, 0, 10076, -8437, -1638, 0 }; -const struct ipu3_uapi_cds_params ipu3_css_cds_defaults = { +const struct ipu3_uapi_cds_params imgu_css_cds_defaults = { 1, 3, 3, 1, 1, 3, 3, 1, 4, X, /* ds_nf */ @@ -9376,7 +9376,7 @@ const struct ipu3_uapi_cds_params ipu3_css_cds_defaults = { 0, X /* uv_bin_output */ }; -const struct ipu3_uapi_shd_config_static ipu3_css_shd_defaults = { +const struct ipu3_uapi_shd_config_static imgu_css_shd_defaults = { .grid = { .width = 73, .height = 55, @@ -9397,7 +9397,7 @@ const struct ipu3_uapi_shd_config_static ipu3_css_shd_defaults = { }, }; -const struct ipu3_uapi_yuvp1_iefd_config ipu3_css_iefd_defaults = { +const struct ipu3_uapi_yuvp1_iefd_config imgu_css_iefd_defaults = { .units = { .cu_1 = { 0, 150, 7, 0 }, .cu_ed = { 7, 110, 244, X, 307, 409, 511, X, @@ -9436,17 +9436,17 @@ const struct ipu3_uapi_yuvp1_iefd_config ipu3_css_iefd_defaults = { { 1, X, 2, X, 8, X } }, }; -const struct ipu3_uapi_yuvp1_yds_config ipu3_css_yds_defaults = { +const struct ipu3_uapi_yuvp1_yds_config imgu_css_yds_defaults = { 0, 1, 1, 0, 0, 1, 1, 0, 2, X, 0, X }; -const struct ipu3_uapi_yuvp1_chnr_config ipu3_css_chnr_defaults = { +const struct ipu3_uapi_yuvp1_chnr_config imgu_css_chnr_defaults = { .coring = { 0, X, 0, X }, .sense_gain = { 6, 6, 6, X, 4, 4, 4, X }, .iir_fir = { 8, X, 12, X, 0, 256 - 127, X }, }; -const struct ipu3_uapi_yuvp1_y_ee_nr_config ipu3_css_y_ee_nr_defaults = { +const struct ipu3_uapi_yuvp1_y_ee_nr_config imgu_css_y_ee_nr_defaults = { .lpf = { 4, X, 8, X, 16, X, 0 }, .sense = { 8191, X, 0, X, 8191, X, 0, X }, .gain = { 8, X, 0, X, 8, X, 0, X }, @@ -9457,7 +9457,7 @@ const struct ipu3_uapi_yuvp1_y_ee_nr_config ipu3_css_y_ee_nr_defaults = { }; const struct ipu3_uapi_yuvp2_tcc_gain_pcwl_lut_static_config - ipu3_css_tcc_gain_pcwl_lut = { { + imgu_css_tcc_gain_pcwl_lut = { { 1024, 1032, 1040, 1048, 1057, 1065, 1073, 1081, 1089, 1097, 1105, 1113, 1122, 1130, 1138, 1146, 1154, 1162, 1170, 1178, 1187, 1195, 1203, 1211, 1219, 1227, 1235, 1243, 1252, 1260, 1268, 1276, 1284, 1292, 1300, 1308, @@ -9483,12 +9483,12 @@ const struct ipu3_uapi_yuvp2_tcc_gain_pcwl_lut_static_config } }; const struct ipu3_uapi_yuvp2_tcc_r_sqr_lut_static_config - ipu3_css_tcc_r_sqr_lut = { { + imgu_css_tcc_r_sqr_lut = { { 32, 44, 64, 92, 128, 180, 256, 364, 512, 628, 724, 808, 888, 956, 1024, 1088, 1144, 1200, 1256, 1304, 1356, 1404, 1448 } }; -const struct imgu_abi_anr_config ipu3_css_anr_defaults = { +const struct imgu_abi_anr_config imgu_css_anr_defaults = { .transform = { .adaptive_treshhold_en = 1, .alpha = { { 13, 13, 13, 13, 0, 0, 0, 0}, @@ -9545,7 +9545,7 @@ const struct imgu_abi_anr_config ipu3_css_anr_defaults = { }; /* frame settings for Auto White Balance */ -const struct ipu3_uapi_awb_fr_config_s ipu3_css_awb_fr_defaults = { +const struct ipu3_uapi_awb_fr_config_s imgu_css_awb_fr_defaults = { .grid_cfg = { .width = 16, .height = 16, @@ -9560,7 +9560,7 @@ const struct ipu3_uapi_awb_fr_config_s ipu3_css_awb_fr_defaults = { }; /* settings for Auto Exposure */ -const struct ipu3_uapi_ae_grid_config ipu3_css_ae_grid_defaults = { +const struct ipu3_uapi_ae_grid_config imgu_css_ae_grid_defaults = { .width = 16, .height = 16, .block_width_log2 = 3, @@ -9571,13 +9571,13 @@ const struct ipu3_uapi_ae_grid_config ipu3_css_ae_grid_defaults = { }; /* settings for Auto Exposure color correction matrix */ -const struct ipu3_uapi_ae_ccm ipu3_css_ae_ccm_defaults = { +const struct ipu3_uapi_ae_ccm imgu_css_ae_ccm_defaults = { 256, 256, 256, 256, /* gain_gr/r/b/gb */ .mat = { 128, 0, 0, 0, 0, 128, 0, 0, 0, 0, 128, 0, 0, 0, 0, 128 }, }; /* settings for Auto Focus */ -const struct ipu3_uapi_af_config_s ipu3_css_af_defaults = { +const struct ipu3_uapi_af_config_s imgu_css_af_defaults = { .filter_config = { { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 128 }, 0, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 128 }, 0, @@ -9595,7 +9595,7 @@ const struct ipu3_uapi_af_config_s ipu3_css_af_defaults = { }; /* settings for Auto White Balance */ -const struct ipu3_uapi_awb_config_s ipu3_css_awb_defaults = { +const struct ipu3_uapi_awb_config_s imgu_css_awb_defaults = { 8191, 8191, 8191, 8191 | /* rgbs_thr_gr/r/gb/b */ IPU3_UAPI_AWB_RGBS_THR_B_EN | IPU3_UAPI_AWB_RGBS_THR_B_INCL_SAT, .grid = { diff --git a/drivers/staging/media/ipu3/ipu3-tables.h b/drivers/staging/media/ipu3/ipu3-tables.h index 6563782cbd22..a1bf3286f380 100644 --- a/drivers/staging/media/ipu3/ipu3-tables.h +++ b/drivers/staging/media/ipu3/ipu3-tables.h @@ -19,7 +19,7 @@ #define IMGU_GDC_LUT_UNIT 4 #define IMGU_GDC_LUT_LEN 256 -struct ipu3_css_bds_config { +struct imgu_css_bds_config { struct imgu_abi_bds_phase_arr hor_phase_arr; struct imgu_abi_bds_phase_arr ver_phase_arr; struct imgu_abi_bds_ptrn_arr ptrn_arr; @@ -28,39 +28,39 @@ struct ipu3_css_bds_config { u8 ver_ds_en; }; -struct ipu3_css_xnr3_vmem_defaults { +struct imgu_css_xnr3_vmem_defaults { s16 x[IMGU_XNR3_VMEM_LUT_LEN]; s16 a[IMGU_XNR3_VMEM_LUT_LEN]; s16 b[IMGU_XNR3_VMEM_LUT_LEN]; s16 c[IMGU_XNR3_VMEM_LUT_LEN]; }; -extern const struct ipu3_css_bds_config - ipu3_css_bds_configs[IMGU_BDS_CONFIG_LEN]; -extern const s32 ipu3_css_downscale_4taps[IMGU_SCALER_DOWNSCALE_4TAPS_LEN]; -extern const s32 ipu3_css_downscale_2taps[IMGU_SCALER_DOWNSCALE_2TAPS_LEN]; -extern const s16 ipu3_css_gdc_lut[IMGU_GDC_LUT_UNIT][IMGU_GDC_LUT_LEN]; -extern const struct ipu3_css_xnr3_vmem_defaults ipu3_css_xnr3_vmem_defaults; -extern const struct ipu3_uapi_bnr_static_config ipu3_css_bnr_defaults; -extern const struct ipu3_uapi_dm_config ipu3_css_dm_defaults; -extern const struct ipu3_uapi_ccm_mat_config ipu3_css_ccm_defaults; -extern const struct ipu3_uapi_gamma_corr_lut ipu3_css_gamma_lut; -extern const struct ipu3_uapi_csc_mat_config ipu3_css_csc_defaults; -extern const struct ipu3_uapi_cds_params ipu3_css_cds_defaults; -extern const struct ipu3_uapi_shd_config_static ipu3_css_shd_defaults; -extern const struct ipu3_uapi_yuvp1_iefd_config ipu3_css_iefd_defaults; -extern const struct ipu3_uapi_yuvp1_yds_config ipu3_css_yds_defaults; -extern const struct ipu3_uapi_yuvp1_chnr_config ipu3_css_chnr_defaults; -extern const struct ipu3_uapi_yuvp1_y_ee_nr_config ipu3_css_y_ee_nr_defaults; +extern const struct imgu_css_bds_config + imgu_css_bds_configs[IMGU_BDS_CONFIG_LEN]; +extern const s32 imgu_css_downscale_4taps[IMGU_SCALER_DOWNSCALE_4TAPS_LEN]; +extern const s32 imgu_css_downscale_2taps[IMGU_SCALER_DOWNSCALE_2TAPS_LEN]; +extern const s16 imgu_css_gdc_lut[IMGU_GDC_LUT_UNIT][IMGU_GDC_LUT_LEN]; +extern const struct imgu_css_xnr3_vmem_defaults imgu_css_xnr3_vmem_defaults; +extern const struct ipu3_uapi_bnr_static_config imgu_css_bnr_defaults; +extern const struct ipu3_uapi_dm_config imgu_css_dm_defaults; +extern const struct ipu3_uapi_ccm_mat_config imgu_css_ccm_defaults; +extern const struct ipu3_uapi_gamma_corr_lut imgu_css_gamma_lut; +extern const struct ipu3_uapi_csc_mat_config imgu_css_csc_defaults; +extern const struct ipu3_uapi_cds_params imgu_css_cds_defaults; +extern const struct ipu3_uapi_shd_config_static imgu_css_shd_defaults; +extern const struct ipu3_uapi_yuvp1_iefd_config imgu_css_iefd_defaults; +extern const struct ipu3_uapi_yuvp1_yds_config imgu_css_yds_defaults; +extern const struct ipu3_uapi_yuvp1_chnr_config imgu_css_chnr_defaults; +extern const struct ipu3_uapi_yuvp1_y_ee_nr_config imgu_css_y_ee_nr_defaults; extern const struct ipu3_uapi_yuvp2_tcc_gain_pcwl_lut_static_config - ipu3_css_tcc_gain_pcwl_lut; + imgu_css_tcc_gain_pcwl_lut; extern const struct ipu3_uapi_yuvp2_tcc_r_sqr_lut_static_config - ipu3_css_tcc_r_sqr_lut; -extern const struct imgu_abi_anr_config ipu3_css_anr_defaults; -extern const struct ipu3_uapi_awb_fr_config_s ipu3_css_awb_fr_defaults; -extern const struct ipu3_uapi_ae_grid_config ipu3_css_ae_grid_defaults; -extern const struct ipu3_uapi_ae_ccm ipu3_css_ae_ccm_defaults; -extern const struct ipu3_uapi_af_config_s ipu3_css_af_defaults; -extern const struct ipu3_uapi_awb_config_s ipu3_css_awb_defaults; + imgu_css_tcc_r_sqr_lut; +extern const struct imgu_abi_anr_config imgu_css_anr_defaults; +extern const struct ipu3_uapi_awb_fr_config_s imgu_css_awb_fr_defaults; +extern const struct ipu3_uapi_ae_grid_config imgu_css_ae_grid_defaults; +extern const struct ipu3_uapi_ae_ccm imgu_css_ae_ccm_defaults; +extern const struct ipu3_uapi_af_config_s imgu_css_af_defaults; +extern const struct ipu3_uapi_awb_config_s imgu_css_awb_defaults; #endif diff --git a/drivers/staging/media/ipu3/ipu3-v4l2.c b/drivers/staging/media/ipu3/ipu3-v4l2.c index c7936032beb9..9c0352b193a7 100644 --- a/drivers/staging/media/ipu3/ipu3-v4l2.c +++ b/drivers/staging/media/ipu3/ipu3-v4l2.c @@ -12,7 +12,10 @@ /******************** v4l2_subdev_ops ********************/ -static int ipu3_subdev_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) +#define IPU3_RUNNING_MODE_VIDEO 0 +#define IPU3_RUNNING_MODE_STILL 1 + +static int imgu_subdev_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) { struct imgu_v4l2_subdev *imgu_sd = container_of(sd, struct imgu_v4l2_subdev, @@ -47,7 +50,7 @@ static int ipu3_subdev_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) return 0; } -static int ipu3_subdev_s_stream(struct v4l2_subdev *sd, int enable) +static int imgu_subdev_s_stream(struct v4l2_subdev *sd, int enable) { int i; unsigned int node; @@ -60,7 +63,7 @@ static int ipu3_subdev_s_stream(struct v4l2_subdev *sd, int enable) struct device *dev = &imgu->pci_dev->dev; struct v4l2_pix_format_mplane *fmts[IPU3_CSS_QUEUES] = { NULL }; struct v4l2_rect *rects[IPU3_CSS_RECTS] = { NULL }; - struct ipu3_css_pipe *css_pipe = &imgu->css.pipes[pipe]; + struct imgu_css_pipe *css_pipe = &imgu->css.pipes[pipe]; struct imgu_media_pipe *imgu_pipe = &imgu->imgu_pipe[pipe]; dev_dbg(dev, "%s %d for pipe %d", __func__, enable, pipe); @@ -104,7 +107,7 @@ static int ipu3_subdev_s_stream(struct v4l2_subdev *sd, int enable) rects[IPU3_CSS_RECT_BDS] = &imgu_sd->rect.bds; rects[IPU3_CSS_RECT_GDC] = &imgu_sd->rect.gdc; - r = ipu3_css_fmt_set(&imgu->css, fmts, rects, pipe); + r = imgu_css_fmt_set(&imgu->css, fmts, rects, pipe); if (r) { dev_err(dev, "failed to set initial formats pipe %d with (%d)", pipe, r); @@ -116,7 +119,7 @@ static int ipu3_subdev_s_stream(struct v4l2_subdev *sd, int enable) return 0; } -static int ipu3_subdev_get_fmt(struct v4l2_subdev *sd, +static int imgu_subdev_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, struct v4l2_subdev_format *fmt) { @@ -140,7 +143,7 @@ static int ipu3_subdev_get_fmt(struct v4l2_subdev *sd, return 0; } -static int ipu3_subdev_set_fmt(struct v4l2_subdev *sd, +static int imgu_subdev_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, struct v4l2_subdev_format *fmt) { @@ -186,7 +189,7 @@ static int ipu3_subdev_set_fmt(struct v4l2_subdev *sd, return 0; } -static int ipu3_subdev_get_selection(struct v4l2_subdev *sd, +static int imgu_subdev_get_selection(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, struct v4l2_subdev_selection *sel) { @@ -219,7 +222,7 @@ static int ipu3_subdev_get_selection(struct v4l2_subdev *sd, return 0; } -static int ipu3_subdev_set_selection(struct v4l2_subdev *sd, +static int imgu_subdev_set_selection(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, struct v4l2_subdev_selection *sel) { @@ -260,7 +263,7 @@ static int ipu3_subdev_set_selection(struct v4l2_subdev *sd, /******************** media_entity_operations ********************/ -static int ipu3_link_setup(struct media_entity *entity, +static int imgu_link_setup(struct media_entity *entity, const struct media_pad *local, const struct media_pad *remote, u32 flags) { @@ -299,7 +302,7 @@ static int ipu3_link_setup(struct media_entity *entity, /******************** vb2_ops ********************/ -static int ipu3_vb2_buf_init(struct vb2_buffer *vb) +static int imgu_vb2_buf_init(struct vb2_buffer *vb) { struct sg_table *sg = vb2_dma_sg_plane_desc(vb, 0); struct imgu_device *imgu = vb2_get_drv_priv(vb->vb2_queue); @@ -312,11 +315,11 @@ static int ipu3_vb2_buf_init(struct vb2_buffer *vb) if (queue == IPU3_CSS_QUEUE_PARAMS) return 0; - return ipu3_dmamap_map_sg(imgu, sg->sgl, sg->nents, &buf->map); + return imgu_dmamap_map_sg(imgu, sg->sgl, sg->nents, &buf->map); } /* Called when each buffer is freed */ -static void ipu3_vb2_buf_cleanup(struct vb2_buffer *vb) +static void imgu_vb2_buf_cleanup(struct vb2_buffer *vb) { struct imgu_device *imgu = vb2_get_drv_priv(vb->vb2_queue); struct imgu_buffer *buf = container_of(vb, @@ -328,11 +331,11 @@ static void ipu3_vb2_buf_cleanup(struct vb2_buffer *vb) if (queue == IPU3_CSS_QUEUE_PARAMS) return; - ipu3_dmamap_unmap(imgu, &buf->map); + imgu_dmamap_unmap(imgu, &buf->map); } /* Transfer buffer ownership to me */ -static void ipu3_vb2_buf_queue(struct vb2_buffer *vb) +static void imgu_vb2_buf_queue(struct vb2_buffer *vb) { struct imgu_device *imgu = vb2_get_drv_priv(vb->vb2_queue); struct imgu_video_device *node = @@ -358,7 +361,7 @@ static void ipu3_vb2_buf_queue(struct vb2_buffer *vb) vb2_set_plane_payload(vb, 0, payload); } if (payload >= need_bytes) - r = ipu3_css_set_parameters(&imgu->css, pipe, + r = imgu_css_set_parameters(&imgu->css, pipe, vb2_plane_vaddr(vb, 0)); buf->flags = V4L2_BUF_FLAG_DONE; vb2_buffer_done(vb, r == 0 ? VB2_BUF_STATE_DONE @@ -369,7 +372,7 @@ static void ipu3_vb2_buf_queue(struct vb2_buffer *vb) vid_buf.vbb.vb2_buf); mutex_lock(&imgu->lock); - ipu3_css_buf_init(&buf->css_buf, queue, buf->map.daddr); + imgu_css_buf_init(&buf->css_buf, queue, buf->map.daddr); list_add_tail(&buf->vid_buf.list, &node->buffers); mutex_unlock(&imgu->lock); @@ -385,7 +388,7 @@ static void ipu3_vb2_buf_queue(struct vb2_buffer *vb) } -static int ipu3_vb2_queue_setup(struct vb2_queue *vq, +static int imgu_vb2_queue_setup(struct vb2_queue *vq, unsigned int *num_buffers, unsigned int *num_planes, unsigned int sizes[], @@ -422,7 +425,7 @@ static int ipu3_vb2_queue_setup(struct vb2_queue *vq, } /* Check if all enabled video nodes are streaming, exception ignored */ -static bool ipu3_all_nodes_streaming(struct imgu_device *imgu, +static bool imgu_all_nodes_streaming(struct imgu_device *imgu, struct imgu_video_device *except) { unsigned int i, pipe, p; @@ -451,11 +454,11 @@ static bool ipu3_all_nodes_streaming(struct imgu_device *imgu, return true; } -static void ipu3_return_all_buffers(struct imgu_device *imgu, +static void imgu_return_all_buffers(struct imgu_device *imgu, struct imgu_video_device *node, enum vb2_buffer_state state) { - struct ipu3_vb2_buffer *b, *b0; + struct imgu_vb2_buffer *b, *b0; /* Return all buffers */ mutex_lock(&imgu->lock); @@ -466,7 +469,7 @@ static void ipu3_return_all_buffers(struct imgu_device *imgu, mutex_unlock(&imgu->lock); } -static int ipu3_vb2_start_streaming(struct vb2_queue *vq, unsigned int count) +static int imgu_vb2_start_streaming(struct vb2_queue *vq, unsigned int count) { struct imgu_media_pipe *imgu_pipe; struct imgu_device *imgu = vb2_get_drv_priv(vq); @@ -497,7 +500,7 @@ static int ipu3_vb2_start_streaming(struct vb2_queue *vq, unsigned int count) goto fail_return_bufs; - if (!ipu3_all_nodes_streaming(imgu, node)) + if (!imgu_all_nodes_streaming(imgu, node)) return 0; for_each_set_bit(pipe, imgu->css.enabled_pipes, IMGU_MAX_PIPE_NUM) { @@ -518,12 +521,12 @@ static int ipu3_vb2_start_streaming(struct vb2_queue *vq, unsigned int count) fail_stop_pipeline: media_pipeline_stop(&node->vdev.entity); fail_return_bufs: - ipu3_return_all_buffers(imgu, node, VB2_BUF_STATE_QUEUED); + imgu_return_all_buffers(imgu, node, VB2_BUF_STATE_QUEUED); return r; } -static void ipu3_vb2_stop_streaming(struct vb2_queue *vq) +static void imgu_vb2_stop_streaming(struct vb2_queue *vq) { struct imgu_media_pipe *imgu_pipe; struct imgu_device *imgu = vb2_get_drv_priv(vq); @@ -544,7 +547,7 @@ static void ipu3_vb2_stop_streaming(struct vb2_queue *vq) "failed to stop subdev streaming\n"); /* Was this the first node with streaming disabled? */ - if (imgu->streaming && ipu3_all_nodes_streaming(imgu, node)) { + if (imgu->streaming && imgu_all_nodes_streaming(imgu, node)) { /* Yes, really stop streaming now */ dev_dbg(dev, "IMGU streaming is ready to stop"); r = imgu_s_stream(imgu, false); @@ -552,7 +555,7 @@ static void ipu3_vb2_stop_streaming(struct vb2_queue *vq) imgu->streaming = false; } - ipu3_return_all_buffers(imgu, node, VB2_BUF_STATE_ERROR); + imgu_return_all_buffers(imgu, node, VB2_BUF_STATE_ERROR); media_pipeline_stop(&node->vdev.entity); } @@ -563,13 +566,13 @@ static void ipu3_vb2_stop_streaming(struct vb2_queue *vq) #define DEF_VID_CAPTURE 0 #define DEF_VID_OUTPUT 1 -struct ipu3_fmt { +struct imgu_fmt { u32 fourcc; u16 type; /* VID_CAPTURE or VID_OUTPUT not both */ }; /* format descriptions for capture and preview */ -static const struct ipu3_fmt formats[] = { +static const struct imgu_fmt formats[] = { { V4L2_PIX_FMT_NV12, VID_CAPTURE }, { V4L2_PIX_FMT_IPU3_SGRBG10, VID_OUTPUT }, { V4L2_PIX_FMT_IPU3_SBGGR10, VID_OUTPUT }, @@ -578,7 +581,7 @@ static const struct ipu3_fmt formats[] = { }; /* Find the first matched format, return default if not found */ -static const struct ipu3_fmt *find_format(struct v4l2_format *f, u32 type) +static const struct imgu_fmt *find_format(struct v4l2_format *f, u32 type) { unsigned int i; @@ -592,10 +595,10 @@ static const struct ipu3_fmt *find_format(struct v4l2_format *f, u32 type) &formats[DEF_VID_OUTPUT]; } -static int ipu3_vidioc_querycap(struct file *file, void *fh, +static int imgu_vidioc_querycap(struct file *file, void *fh, struct v4l2_capability *cap) { - struct imgu_video_device *node = file_to_intel_ipu3_node(file); + struct imgu_video_device *node = file_to_intel_imgu_node(file); strscpy(cap->driver, IMGU_NAME, sizeof(cap->driver)); strscpy(cap->card, IMGU_NAME, sizeof(cap->card)); @@ -643,10 +646,10 @@ static int vidioc_enum_fmt_vid_out(struct file *file, void *priv, } /* Propagate forward always the format from the CIO2 subdev */ -static int ipu3_vidioc_g_fmt(struct file *file, void *fh, +static int imgu_vidioc_g_fmt(struct file *file, void *fh, struct v4l2_format *f) { - struct imgu_video_device *node = file_to_intel_ipu3_node(file); + struct imgu_video_device *node = file_to_intel_imgu_node(file); f->fmt = node->vdev_fmt.fmt; @@ -667,7 +670,7 @@ static int imgu_fmt(struct imgu_device *imgu, unsigned int pipe, int node, struct v4l2_mbus_framefmt pad_fmt; unsigned int i, css_q; int r; - struct ipu3_css_pipe *css_pipe = &imgu->css.pipes[pipe]; + struct imgu_css_pipe *css_pipe = &imgu->css.pipes[pipe]; struct imgu_media_pipe *imgu_pipe = &imgu->imgu_pipe[pipe]; struct imgu_v4l2_subdev *imgu_sd = &imgu_pipe->imgu_sd; @@ -733,9 +736,9 @@ static int imgu_fmt(struct imgu_device *imgu, unsigned int pipe, int node, return -EINVAL; if (try) - r = ipu3_css_fmt_try(&imgu->css, fmts, rects, pipe); + r = imgu_css_fmt_try(&imgu->css, fmts, rects, pipe); else - r = ipu3_css_fmt_set(&imgu->css, fmts, rects, pipe); + r = imgu_css_fmt_set(&imgu->css, fmts, rects, pipe); /* r is the binary number in the firmware blob */ if (r < 0) @@ -749,10 +752,10 @@ static int imgu_fmt(struct imgu_device *imgu, unsigned int pipe, int node, return 0; } -static int ipu3_try_fmt(struct file *file, void *fh, struct v4l2_format *f) +static int imgu_try_fmt(struct file *file, void *fh, struct v4l2_format *f) { struct v4l2_pix_format_mplane *pixm = &f->fmt.pix_mp; - const struct ipu3_fmt *fmt; + const struct imgu_fmt *fmt; if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) fmt = find_format(f, VID_CAPTURE); @@ -769,58 +772,58 @@ static int ipu3_try_fmt(struct file *file, void *fh, struct v4l2_format *f) return 0; } -static int ipu3_vidioc_try_fmt(struct file *file, void *fh, +static int imgu_vidioc_try_fmt(struct file *file, void *fh, struct v4l2_format *f) { struct imgu_device *imgu = video_drvdata(file); struct device *dev = &imgu->pci_dev->dev; - struct imgu_video_device *node = file_to_intel_ipu3_node(file); + struct imgu_video_device *node = file_to_intel_imgu_node(file); struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; int r; dev_dbg(dev, "%s [%ux%u] for node %d\n", __func__, pix_mp->width, pix_mp->height, node->id); - r = ipu3_try_fmt(file, fh, f); + r = imgu_try_fmt(file, fh, f); if (r) return r; return imgu_fmt(imgu, node->pipe, node->id, f, true); } -static int ipu3_vidioc_s_fmt(struct file *file, void *fh, struct v4l2_format *f) +static int imgu_vidioc_s_fmt(struct file *file, void *fh, struct v4l2_format *f) { struct imgu_device *imgu = video_drvdata(file); struct device *dev = &imgu->pci_dev->dev; - struct imgu_video_device *node = file_to_intel_ipu3_node(file); + struct imgu_video_device *node = file_to_intel_imgu_node(file); struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; int r; dev_dbg(dev, "%s [%ux%u] for node %d\n", __func__, pix_mp->width, pix_mp->height, node->id); - r = ipu3_try_fmt(file, fh, f); + r = imgu_try_fmt(file, fh, f); if (r) return r; return imgu_fmt(imgu, node->pipe, node->id, f, false); } -struct ipu3_meta_fmt { +struct imgu_meta_fmt { __u32 fourcc; char *name; }; /* From drivers/media/v4l2-core/v4l2-ioctl.c */ -static const struct ipu3_meta_fmt meta_fmts[] = { +static const struct imgu_meta_fmt meta_fmts[] = { { V4L2_META_FMT_IPU3_PARAMS, "IPU3 processing parameters" }, { V4L2_META_FMT_IPU3_STAT_3A, "IPU3 3A statistics" }, }; -static int ipu3_meta_enum_format(struct file *file, void *fh, +static int imgu_meta_enum_format(struct file *file, void *fh, struct v4l2_fmtdesc *fmt) { - struct imgu_video_device *node = file_to_intel_ipu3_node(file); + struct imgu_video_device *node = file_to_intel_imgu_node(file); unsigned int i = fmt->type == V4L2_BUF_TYPE_META_OUTPUT ? 0 : 1; /* Each node is dedicated to only one meta format */ @@ -833,10 +836,10 @@ static int ipu3_meta_enum_format(struct file *file, void *fh, return 0; } -static int ipu3_vidioc_g_meta_fmt(struct file *file, void *fh, +static int imgu_vidioc_g_meta_fmt(struct file *file, void *fh, struct v4l2_format *f) { - struct imgu_video_device *node = file_to_intel_ipu3_node(file); + struct imgu_video_device *node = file_to_intel_imgu_node(file); if (f->type != node->vbq.type) return -EINVAL; @@ -846,7 +849,7 @@ static int ipu3_vidioc_g_meta_fmt(struct file *file, void *fh, return 0; } -static int ipu3_vidioc_enum_input(struct file *file, void *fh, +static int imgu_vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *input) { if (input->index > 0) @@ -857,19 +860,19 @@ static int ipu3_vidioc_enum_input(struct file *file, void *fh, return 0; } -static int ipu3_vidioc_g_input(struct file *file, void *fh, unsigned int *input) +static int imgu_vidioc_g_input(struct file *file, void *fh, unsigned int *input) { *input = 0; return 0; } -static int ipu3_vidioc_s_input(struct file *file, void *fh, unsigned int input) +static int imgu_vidioc_s_input(struct file *file, void *fh, unsigned int input) { return input == 0 ? 0 : -EINVAL; } -static int ipu3_vidioc_enum_output(struct file *file, void *fh, +static int imgu_vidioc_enum_output(struct file *file, void *fh, struct v4l2_output *output) { if (output->index > 0) @@ -880,7 +883,7 @@ static int ipu3_vidioc_enum_output(struct file *file, void *fh, return 0; } -static int ipu3_vidioc_g_output(struct file *file, void *fh, +static int imgu_vidioc_g_output(struct file *file, void *fh, unsigned int *output) { *output = 0; @@ -888,7 +891,7 @@ static int ipu3_vidioc_g_output(struct file *file, void *fh, return 0; } -static int ipu3_vidioc_s_output(struct file *file, void *fh, +static int imgu_vidioc_s_output(struct file *file, void *fh, unsigned int output) { return output == 0 ? 0 : -EINVAL; @@ -896,54 +899,54 @@ static int ipu3_vidioc_s_output(struct file *file, void *fh, /******************** function pointers ********************/ -static struct v4l2_subdev_internal_ops ipu3_subdev_internal_ops = { - .open = ipu3_subdev_open, +static struct v4l2_subdev_internal_ops imgu_subdev_internal_ops = { + .open = imgu_subdev_open, }; -static const struct v4l2_subdev_core_ops ipu3_subdev_core_ops = { +static const struct v4l2_subdev_core_ops imgu_subdev_core_ops = { .subscribe_event = v4l2_ctrl_subdev_subscribe_event, .unsubscribe_event = v4l2_event_subdev_unsubscribe, }; -static const struct v4l2_subdev_video_ops ipu3_subdev_video_ops = { - .s_stream = ipu3_subdev_s_stream, +static const struct v4l2_subdev_video_ops imgu_subdev_video_ops = { + .s_stream = imgu_subdev_s_stream, }; -static const struct v4l2_subdev_pad_ops ipu3_subdev_pad_ops = { +static const struct v4l2_subdev_pad_ops imgu_subdev_pad_ops = { .link_validate = v4l2_subdev_link_validate_default, - .get_fmt = ipu3_subdev_get_fmt, - .set_fmt = ipu3_subdev_set_fmt, - .get_selection = ipu3_subdev_get_selection, - .set_selection = ipu3_subdev_set_selection, + .get_fmt = imgu_subdev_get_fmt, + .set_fmt = imgu_subdev_set_fmt, + .get_selection = imgu_subdev_get_selection, + .set_selection = imgu_subdev_set_selection, }; -static const struct v4l2_subdev_ops ipu3_subdev_ops = { - .core = &ipu3_subdev_core_ops, - .video = &ipu3_subdev_video_ops, - .pad = &ipu3_subdev_pad_ops, +static const struct v4l2_subdev_ops imgu_subdev_ops = { + .core = &imgu_subdev_core_ops, + .video = &imgu_subdev_video_ops, + .pad = &imgu_subdev_pad_ops, }; -static const struct media_entity_operations ipu3_media_ops = { - .link_setup = ipu3_link_setup, +static const struct media_entity_operations imgu_media_ops = { + .link_setup = imgu_link_setup, .link_validate = v4l2_subdev_link_validate, }; /****************** vb2_ops of the Q ********************/ -static const struct vb2_ops ipu3_vb2_ops = { - .buf_init = ipu3_vb2_buf_init, - .buf_cleanup = ipu3_vb2_buf_cleanup, - .buf_queue = ipu3_vb2_buf_queue, - .queue_setup = ipu3_vb2_queue_setup, - .start_streaming = ipu3_vb2_start_streaming, - .stop_streaming = ipu3_vb2_stop_streaming, +static const struct vb2_ops imgu_vb2_ops = { + .buf_init = imgu_vb2_buf_init, + .buf_cleanup = imgu_vb2_buf_cleanup, + .buf_queue = imgu_vb2_buf_queue, + .queue_setup = imgu_vb2_queue_setup, + .start_streaming = imgu_vb2_start_streaming, + .stop_streaming = imgu_vb2_stop_streaming, .wait_prepare = vb2_ops_wait_prepare, .wait_finish = vb2_ops_wait_finish, }; /****************** v4l2_file_operations *****************/ -static const struct v4l2_file_operations ipu3_v4l2_fops = { +static const struct v4l2_file_operations imgu_v4l2_fops = { .unlocked_ioctl = video_ioctl2, .open = v4l2_fh_open, .release = vb2_fop_release, @@ -953,26 +956,26 @@ static const struct v4l2_file_operations ipu3_v4l2_fops = { /******************** v4l2_ioctl_ops ********************/ -static const struct v4l2_ioctl_ops ipu3_v4l2_ioctl_ops = { - .vidioc_querycap = ipu3_vidioc_querycap, +static const struct v4l2_ioctl_ops imgu_v4l2_ioctl_ops = { + .vidioc_querycap = imgu_vidioc_querycap, .vidioc_enum_fmt_vid_cap_mplane = vidioc_enum_fmt_vid_cap, - .vidioc_g_fmt_vid_cap_mplane = ipu3_vidioc_g_fmt, - .vidioc_s_fmt_vid_cap_mplane = ipu3_vidioc_s_fmt, - .vidioc_try_fmt_vid_cap_mplane = ipu3_vidioc_try_fmt, + .vidioc_g_fmt_vid_cap_mplane = imgu_vidioc_g_fmt, + .vidioc_s_fmt_vid_cap_mplane = imgu_vidioc_s_fmt, + .vidioc_try_fmt_vid_cap_mplane = imgu_vidioc_try_fmt, .vidioc_enum_fmt_vid_out_mplane = vidioc_enum_fmt_vid_out, - .vidioc_g_fmt_vid_out_mplane = ipu3_vidioc_g_fmt, - .vidioc_s_fmt_vid_out_mplane = ipu3_vidioc_s_fmt, - .vidioc_try_fmt_vid_out_mplane = ipu3_vidioc_try_fmt, + .vidioc_g_fmt_vid_out_mplane = imgu_vidioc_g_fmt, + .vidioc_s_fmt_vid_out_mplane = imgu_vidioc_s_fmt, + .vidioc_try_fmt_vid_out_mplane = imgu_vidioc_try_fmt, - .vidioc_enum_output = ipu3_vidioc_enum_output, - .vidioc_g_output = ipu3_vidioc_g_output, - .vidioc_s_output = ipu3_vidioc_s_output, + .vidioc_enum_output = imgu_vidioc_enum_output, + .vidioc_g_output = imgu_vidioc_g_output, + .vidioc_s_output = imgu_vidioc_s_output, - .vidioc_enum_input = ipu3_vidioc_enum_input, - .vidioc_g_input = ipu3_vidioc_g_input, - .vidioc_s_input = ipu3_vidioc_s_input, + .vidioc_enum_input = imgu_vidioc_enum_input, + .vidioc_g_input = imgu_vidioc_g_input, + .vidioc_s_input = imgu_vidioc_s_input, /* buffer queue management */ .vidioc_reqbufs = vb2_ioctl_reqbufs, @@ -986,20 +989,20 @@ static const struct v4l2_ioctl_ops ipu3_v4l2_ioctl_ops = { .vidioc_expbuf = vb2_ioctl_expbuf, }; -static const struct v4l2_ioctl_ops ipu3_v4l2_meta_ioctl_ops = { - .vidioc_querycap = ipu3_vidioc_querycap, +static const struct v4l2_ioctl_ops imgu_v4l2_meta_ioctl_ops = { + .vidioc_querycap = imgu_vidioc_querycap, /* meta capture */ - .vidioc_enum_fmt_meta_cap = ipu3_meta_enum_format, - .vidioc_g_fmt_meta_cap = ipu3_vidioc_g_meta_fmt, - .vidioc_s_fmt_meta_cap = ipu3_vidioc_g_meta_fmt, - .vidioc_try_fmt_meta_cap = ipu3_vidioc_g_meta_fmt, + .vidioc_enum_fmt_meta_cap = imgu_meta_enum_format, + .vidioc_g_fmt_meta_cap = imgu_vidioc_g_meta_fmt, + .vidioc_s_fmt_meta_cap = imgu_vidioc_g_meta_fmt, + .vidioc_try_fmt_meta_cap = imgu_vidioc_g_meta_fmt, /* meta output */ - .vidioc_enum_fmt_meta_out = ipu3_meta_enum_format, - .vidioc_g_fmt_meta_out = ipu3_vidioc_g_meta_fmt, - .vidioc_s_fmt_meta_out = ipu3_vidioc_g_meta_fmt, - .vidioc_try_fmt_meta_out = ipu3_vidioc_g_meta_fmt, + .vidioc_enum_fmt_meta_out = imgu_meta_enum_format, + .vidioc_g_fmt_meta_out = imgu_vidioc_g_meta_fmt, + .vidioc_s_fmt_meta_out = imgu_vidioc_g_meta_fmt, + .vidioc_try_fmt_meta_out = imgu_vidioc_g_meta_fmt, .vidioc_reqbufs = vb2_ioctl_reqbufs, .vidioc_create_bufs = vb2_ioctl_create_bufs, @@ -1012,7 +1015,7 @@ static const struct v4l2_ioctl_ops ipu3_v4l2_meta_ioctl_ops = { .vidioc_expbuf = vb2_ioctl_expbuf, }; -static int ipu3_sd_s_ctrl(struct v4l2_ctrl *ctrl) +static int imgu_sd_s_ctrl(struct v4l2_ctrl *ctrl) { struct imgu_v4l2_subdev *imgu_sd = container_of(ctrl->handler, struct imgu_v4l2_subdev, ctrl_handler); @@ -1031,25 +1034,29 @@ static int ipu3_sd_s_ctrl(struct v4l2_ctrl *ctrl) } } -static const struct v4l2_ctrl_ops ipu3_subdev_ctrl_ops = { - .s_ctrl = ipu3_sd_s_ctrl, +static const struct v4l2_ctrl_ops imgu_subdev_ctrl_ops = { + .s_ctrl = imgu_sd_s_ctrl, +}; + +static const char * const imgu_ctrl_mode_strings[] = { + "Video mode", + "Still mode", }; -static const struct v4l2_ctrl_config ipu3_subdev_ctrl_mode = { - .ops = &ipu3_subdev_ctrl_ops, +static const struct v4l2_ctrl_config imgu_subdev_ctrl_mode = { + .ops = &imgu_subdev_ctrl_ops, .id = V4L2_CID_INTEL_IPU3_MODE, .name = "IPU3 Pipe Mode", - .type = V4L2_CTRL_TYPE_INTEGER, - .min = IPU3_RUNNING_MODE_VIDEO, - .max = IPU3_RUNNING_MODE_STILL, - .step = 1, + .type = V4L2_CTRL_TYPE_MENU, + .max = ARRAY_SIZE(imgu_ctrl_mode_strings) - 1, .def = IPU3_RUNNING_MODE_VIDEO, + .qmenu = imgu_ctrl_mode_strings, }; /******************** Framework registration ********************/ /* helper function to config node's video properties */ -static void ipu3_node_to_v4l2(u32 node, struct video_device *vdev, +static void imgu_node_to_v4l2(u32 node, struct video_device *vdev, struct v4l2_format *f) { u32 cap; @@ -1061,32 +1068,32 @@ static void ipu3_node_to_v4l2(u32 node, struct video_device *vdev, case IMGU_NODE_IN: cap = V4L2_CAP_VIDEO_OUTPUT_MPLANE; f->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - vdev->ioctl_ops = &ipu3_v4l2_ioctl_ops; + vdev->ioctl_ops = &imgu_v4l2_ioctl_ops; break; case IMGU_NODE_PARAMS: cap = V4L2_CAP_META_OUTPUT; f->type = V4L2_BUF_TYPE_META_OUTPUT; f->fmt.meta.dataformat = V4L2_META_FMT_IPU3_PARAMS; - vdev->ioctl_ops = &ipu3_v4l2_meta_ioctl_ops; - ipu3_css_meta_fmt_set(&f->fmt.meta); + vdev->ioctl_ops = &imgu_v4l2_meta_ioctl_ops; + imgu_css_meta_fmt_set(&f->fmt.meta); break; case IMGU_NODE_STAT_3A: cap = V4L2_CAP_META_CAPTURE; f->type = V4L2_BUF_TYPE_META_CAPTURE; f->fmt.meta.dataformat = V4L2_META_FMT_IPU3_STAT_3A; - vdev->ioctl_ops = &ipu3_v4l2_meta_ioctl_ops; - ipu3_css_meta_fmt_set(&f->fmt.meta); + vdev->ioctl_ops = &imgu_v4l2_meta_ioctl_ops; + imgu_css_meta_fmt_set(&f->fmt.meta); break; default: cap = V4L2_CAP_VIDEO_CAPTURE_MPLANE; f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - vdev->ioctl_ops = &ipu3_v4l2_ioctl_ops; + vdev->ioctl_ops = &imgu_v4l2_ioctl_ops; } vdev->device_caps = V4L2_CAP_STREAMING | cap; } -static int ipu3_v4l2_subdev_register(struct imgu_device *imgu, +static int imgu_v4l2_subdev_register(struct imgu_device *imgu, struct imgu_v4l2_subdev *imgu_sd, unsigned int pipe) { @@ -1102,16 +1109,16 @@ static int ipu3_v4l2_subdev_register(struct imgu_device *imgu, "failed initialize subdev media entity (%d)\n", r); return r; } - imgu_sd->subdev.entity.ops = &ipu3_media_ops; + imgu_sd->subdev.entity.ops = &imgu_media_ops; for (i = 0; i < IMGU_NODE_NUM; i++) { imgu_sd->subdev_pads[i].flags = imgu_pipe->nodes[i].output ? MEDIA_PAD_FL_SINK : MEDIA_PAD_FL_SOURCE; } /* Initialize subdev */ - v4l2_subdev_init(&imgu_sd->subdev, &ipu3_subdev_ops); + v4l2_subdev_init(&imgu_sd->subdev, &imgu_subdev_ops); imgu_sd->subdev.entity.function = MEDIA_ENT_F_PROC_VIDEO_STATISTICS; - imgu_sd->subdev.internal_ops = &ipu3_subdev_internal_ops; + imgu_sd->subdev.internal_ops = &imgu_subdev_internal_ops; imgu_sd->subdev.flags = V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS; snprintf(imgu_sd->subdev.name, sizeof(imgu_sd->subdev.name), @@ -1120,7 +1127,7 @@ static int ipu3_v4l2_subdev_register(struct imgu_device *imgu, atomic_set(&imgu_sd->running_mode, IPU3_RUNNING_MODE_VIDEO); v4l2_ctrl_handler_init(hdl, 1); imgu_sd->subdev.ctrl_handler = hdl; - imgu_sd->ctrl = v4l2_ctrl_new_custom(hdl, &ipu3_subdev_ctrl_mode, NULL); + imgu_sd->ctrl = v4l2_ctrl_new_custom(hdl, &imgu_subdev_ctrl_mode, NULL); if (hdl->error) { r = hdl->error; dev_err(&imgu->pci_dev->dev, @@ -1144,7 +1151,7 @@ fail_subdev: return r; } -static int ipu3_v4l2_node_setup(struct imgu_device *imgu, unsigned int pipe, +static int imgu_v4l2_node_setup(struct imgu_device *imgu, unsigned int pipe, int node_num) { int r; @@ -1189,7 +1196,7 @@ static int ipu3_v4l2_node_setup(struct imgu_device *imgu, unsigned int pipe, node->pad_fmt = def_bus_fmt; node->id = node_num; node->pipe = pipe; - ipu3_node_to_v4l2(node_num, vdev, &node->vdev_fmt); + imgu_node_to_v4l2(node_num, vdev, &node->vdev_fmt); if (node->vdev_fmt.type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE || node->vdev_fmt.type == @@ -1214,11 +1221,11 @@ static int ipu3_v4l2_node_setup(struct imgu_device *imgu, unsigned int pipe, /* Initialize vbq */ vbq->type = node->vdev_fmt.type; vbq->io_modes = VB2_USERPTR | VB2_MMAP | VB2_DMABUF; - vbq->ops = &ipu3_vb2_ops; + vbq->ops = &imgu_vb2_ops; vbq->mem_ops = &vb2_dma_sg_memops; if (imgu->buf_struct_size <= 0) imgu->buf_struct_size = - sizeof(struct ipu3_vb2_buffer); + sizeof(struct imgu_vb2_buffer); vbq->buf_struct_size = imgu->buf_struct_size; vbq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; /* can streamon w/o buffers */ @@ -1236,7 +1243,7 @@ static int ipu3_v4l2_node_setup(struct imgu_device *imgu, unsigned int pipe, snprintf(vdev->name, sizeof(vdev->name), "%s %d %s", IMGU_NAME, pipe, node->name); vdev->release = video_device_release_empty; - vdev->fops = &ipu3_v4l2_fops; + vdev->fops = &imgu_v4l2_fops; vdev->lock = &node->lock; vdev->v4l2_dev = &imgu->v4l2_dev; vdev->queue = &node->vbq; @@ -1269,7 +1276,7 @@ static int ipu3_v4l2_node_setup(struct imgu_device *imgu, unsigned int pipe, return 0; } -static void ipu3_v4l2_nodes_cleanup_pipe(struct imgu_device *imgu, +static void imgu_v4l2_nodes_cleanup_pipe(struct imgu_device *imgu, unsigned int pipe, int node) { int i; @@ -1282,12 +1289,12 @@ static void ipu3_v4l2_nodes_cleanup_pipe(struct imgu_device *imgu, } } -static int ipu3_v4l2_nodes_setup_pipe(struct imgu_device *imgu, int pipe) +static int imgu_v4l2_nodes_setup_pipe(struct imgu_device *imgu, int pipe) { int i, r; for (i = 0; i < IMGU_NODE_NUM; i++) { - r = ipu3_v4l2_node_setup(imgu, pipe, i); + r = imgu_v4l2_node_setup(imgu, pipe, i); if (r) goto cleanup; } @@ -1295,11 +1302,11 @@ static int ipu3_v4l2_nodes_setup_pipe(struct imgu_device *imgu, int pipe) return 0; cleanup: - ipu3_v4l2_nodes_cleanup_pipe(imgu, pipe, i); + imgu_v4l2_nodes_cleanup_pipe(imgu, pipe, i); return r; } -static void ipu3_v4l2_subdev_cleanup(struct imgu_device *imgu, unsigned int i) +static void imgu_v4l2_subdev_cleanup(struct imgu_device *imgu, unsigned int i) { struct imgu_media_pipe *imgu_pipe = &imgu->imgu_pipe[i]; @@ -1308,13 +1315,13 @@ static void ipu3_v4l2_subdev_cleanup(struct imgu_device *imgu, unsigned int i) media_entity_cleanup(&imgu_pipe->imgu_sd.subdev.entity); } -static void ipu3_v4l2_cleanup_pipes(struct imgu_device *imgu, unsigned int pipe) +static void imgu_v4l2_cleanup_pipes(struct imgu_device *imgu, unsigned int pipe) { int i; for (i = 0; i < pipe; i++) { - ipu3_v4l2_nodes_cleanup_pipe(imgu, i, IMGU_NODE_NUM); - ipu3_v4l2_subdev_cleanup(imgu, i); + imgu_v4l2_nodes_cleanup_pipe(imgu, i, IMGU_NODE_NUM); + imgu_v4l2_subdev_cleanup(imgu, i); } } @@ -1325,15 +1332,15 @@ static int imgu_v4l2_register_pipes(struct imgu_device *imgu) for (i = 0; i < IMGU_MAX_PIPE_NUM; i++) { imgu_pipe = &imgu->imgu_pipe[i]; - r = ipu3_v4l2_subdev_register(imgu, &imgu_pipe->imgu_sd, i); + r = imgu_v4l2_subdev_register(imgu, &imgu_pipe->imgu_sd, i); if (r) { dev_err(&imgu->pci_dev->dev, "failed to register subdev%d ret (%d)\n", i, r); goto pipes_cleanup; } - r = ipu3_v4l2_nodes_setup_pipe(imgu, i); + r = imgu_v4l2_nodes_setup_pipe(imgu, i); if (r) { - ipu3_v4l2_subdev_cleanup(imgu, i); + imgu_v4l2_subdev_cleanup(imgu, i); goto pipes_cleanup; } } @@ -1341,7 +1348,7 @@ static int imgu_v4l2_register_pipes(struct imgu_device *imgu) return 0; pipes_cleanup: - ipu3_v4l2_cleanup_pipes(imgu, i); + imgu_v4l2_cleanup_pipes(imgu, i); return r; } @@ -1389,7 +1396,7 @@ int imgu_v4l2_register(struct imgu_device *imgu) return 0; fail_subdevs: - ipu3_v4l2_cleanup_pipes(imgu, IMGU_MAX_PIPE_NUM); + imgu_v4l2_cleanup_pipes(imgu, IMGU_MAX_PIPE_NUM); fail_v4l2_pipes: v4l2_device_unregister(&imgu->v4l2_dev); fail_v4l2_dev: @@ -1401,7 +1408,7 @@ fail_v4l2_dev: int imgu_v4l2_unregister(struct imgu_device *imgu) { media_device_unregister(&imgu->media_dev); - ipu3_v4l2_cleanup_pipes(imgu, IMGU_MAX_PIPE_NUM); + imgu_v4l2_cleanup_pipes(imgu, IMGU_MAX_PIPE_NUM); v4l2_device_unregister(&imgu->v4l2_dev); media_device_cleanup(&imgu->media_dev); @@ -1411,8 +1418,8 @@ int imgu_v4l2_unregister(struct imgu_device *imgu) void imgu_v4l2_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state state) { - struct ipu3_vb2_buffer *b = - container_of(vb, struct ipu3_vb2_buffer, vbb.vb2_buf); + struct imgu_vb2_buffer *b = + container_of(vb, struct imgu_vb2_buffer, vbb.vb2_buf); list_del(&b->list); vb2_buffer_done(&b->vbb.vb2_buf, state); diff --git a/drivers/staging/media/ipu3/ipu3.c b/drivers/staging/media/ipu3/ipu3.c index d521b3afb8b1..d575ac78c8f0 100644 --- a/drivers/staging/media/ipu3/ipu3.c +++ b/drivers/staging/media/ipu3/ipu3.c @@ -72,7 +72,7 @@ static void imgu_dummybufs_cleanup(struct imgu_device *imgu, unsigned int pipe) struct imgu_media_pipe *imgu_pipe = &imgu->imgu_pipe[pipe]; for (i = 0; i < IPU3_CSS_QUEUES; i++) - ipu3_dmamap_free(imgu, + imgu_dmamap_free(imgu, &imgu_pipe->queues[i].dmap); } @@ -93,7 +93,7 @@ static int imgu_dummybufs_preallocate(struct imgu_device *imgu, if (i == IMGU_QUEUE_MASTER || size == 0) continue; - if (!ipu3_dmamap_alloc(imgu, + if (!imgu_dmamap_alloc(imgu, &imgu_pipe->queues[i].dmap, size)) { imgu_dummybufs_cleanup(imgu, pipe); return -ENOMEM; @@ -133,7 +133,7 @@ static int imgu_dummybufs_init(struct imgu_device *imgu, unsigned int pipe) else size = mpix->plane_fmt[0].sizeimage; - if (ipu3_css_dma_buffer_resize(imgu, + if (imgu_css_dma_buffer_resize(imgu, &imgu_pipe->queues[i].dmap, size)) { imgu_dummybufs_cleanup(imgu, pipe); @@ -141,7 +141,7 @@ static int imgu_dummybufs_init(struct imgu_device *imgu, unsigned int pipe) } for (k = 0; k < IMGU_MAX_QUEUE_DEPTH; k++) - ipu3_css_buf_init(&imgu_pipe->queues[i].dummybufs[k], i, + imgu_css_buf_init(&imgu_pipe->queues[i].dummybufs[k], i, imgu_pipe->queues[i].dmap.daddr); } @@ -149,7 +149,7 @@ static int imgu_dummybufs_init(struct imgu_device *imgu, unsigned int pipe) } /* May be called from atomic context */ -static struct ipu3_css_buffer *imgu_dummybufs_get(struct imgu_device *imgu, +static struct imgu_css_buffer *imgu_dummybufs_get(struct imgu_device *imgu, int queue, unsigned int pipe) { unsigned int i; @@ -164,14 +164,14 @@ static struct ipu3_css_buffer *imgu_dummybufs_get(struct imgu_device *imgu, return NULL; for (i = 0; i < IMGU_MAX_QUEUE_DEPTH; i++) - if (ipu3_css_buf_state(&imgu_pipe->queues[queue].dummybufs[i]) != + if (imgu_css_buf_state(&imgu_pipe->queues[queue].dummybufs[i]) != IPU3_CSS_BUFFER_QUEUED) break; if (i == IMGU_MAX_QUEUE_DEPTH) return NULL; - ipu3_css_buf_init(&imgu_pipe->queues[queue].dummybufs[i], queue, + imgu_css_buf_init(&imgu_pipe->queues[queue].dummybufs[i], queue, imgu_pipe->queues[queue].dmap.daddr); return &imgu_pipe->queues[queue].dummybufs[i]; @@ -179,7 +179,7 @@ static struct ipu3_css_buffer *imgu_dummybufs_get(struct imgu_device *imgu, /* Check if given buffer is a dummy buffer */ static bool imgu_dummybufs_check(struct imgu_device *imgu, - struct ipu3_css_buffer *buf, + struct imgu_css_buffer *buf, unsigned int pipe) { unsigned int i; @@ -200,7 +200,7 @@ static void imgu_buffer_done(struct imgu_device *imgu, struct vb2_buffer *vb, mutex_unlock(&imgu->lock); } -static struct ipu3_css_buffer *imgu_queue_getbuf(struct imgu_device *imgu, +static struct imgu_css_buffer *imgu_queue_getbuf(struct imgu_device *imgu, unsigned int node, unsigned int pipe) { @@ -212,7 +212,7 @@ static struct ipu3_css_buffer *imgu_queue_getbuf(struct imgu_device *imgu, /* Find first free buffer from the node */ list_for_each_entry(buf, &imgu_pipe->nodes[node].buffers, vid_buf.list) { - if (ipu3_css_buf_state(&buf->css_buf) == IPU3_CSS_BUFFER_NEW) + if (imgu_css_buf_state(&buf->css_buf) == IPU3_CSS_BUFFER_NEW) return &buf->css_buf; } @@ -230,7 +230,7 @@ int imgu_queue_buffers(struct imgu_device *imgu, bool initial, unsigned int pipe int r = 0; struct imgu_media_pipe *imgu_pipe = &imgu->imgu_pipe[pipe]; - if (!ipu3_css_is_streaming(&imgu->css)) + if (!imgu_css_is_streaming(&imgu->css)) return 0; dev_dbg(&imgu->pci_dev->dev, "Queue buffers to pipe %d", pipe); @@ -247,7 +247,7 @@ int imgu_queue_buffers(struct imgu_device *imgu, bool initial, unsigned int pipe "Vf not enabled, ignore queue"); continue; } else if (imgu_pipe->queue_enabled[node]) { - struct ipu3_css_buffer *buf = + struct imgu_css_buffer *buf = imgu_queue_getbuf(imgu, node, pipe); struct imgu_buffer *ibuf = NULL; bool dummy; @@ -255,7 +255,7 @@ int imgu_queue_buffers(struct imgu_device *imgu, bool initial, unsigned int pipe if (!buf) break; - r = ipu3_css_buf_queue(&imgu->css, pipe, buf); + r = imgu_css_buf_queue(&imgu->css, pipe, buf); if (r) break; dummy = imgu_dummybufs_check(imgu, buf, pipe); @@ -300,7 +300,7 @@ failed: list_for_each_entry_safe(buf, buf0, &imgu_pipe->nodes[node].buffers, vid_buf.list) { - if (ipu3_css_buf_state(&buf->css_buf) == + if (imgu_css_buf_state(&buf->css_buf) == IPU3_CSS_BUFFER_QUEUED) continue; /* Was already queued, skip */ @@ -317,18 +317,18 @@ static int imgu_powerup(struct imgu_device *imgu) { int r; - r = ipu3_css_set_powerup(&imgu->pci_dev->dev, imgu->base); + r = imgu_css_set_powerup(&imgu->pci_dev->dev, imgu->base); if (r) return r; - ipu3_mmu_resume(imgu->mmu); + imgu_mmu_resume(imgu->mmu); return 0; } static void imgu_powerdown(struct imgu_device *imgu) { - ipu3_mmu_suspend(imgu->mmu); - ipu3_css_set_powerdown(&imgu->pci_dev->dev, imgu->base); + imgu_mmu_suspend(imgu->mmu); + imgu_css_set_powerdown(&imgu->pci_dev->dev, imgu->base); } int imgu_s_stream(struct imgu_device *imgu, int enable) @@ -341,7 +341,7 @@ int imgu_s_stream(struct imgu_device *imgu, int enable) dev_dbg(dev, "stream off\n"); /* Block new buffers to be queued to CSS. */ atomic_set(&imgu->qbuf_barrier, 1); - ipu3_css_stop_streaming(&imgu->css); + imgu_css_stop_streaming(&imgu->css); synchronize_irq(imgu->pci_dev->irq); atomic_set(&imgu->qbuf_barrier, 0); imgu_powerdown(imgu); @@ -366,7 +366,7 @@ int imgu_s_stream(struct imgu_device *imgu, int enable) } /* Start CSS streaming */ - r = ipu3_css_start_streaming(&imgu->css); + r = imgu_css_start_streaming(&imgu->css); if (r) { dev_err(dev, "failed to start css streaming (%d)", r); goto fail_start_streaming; @@ -393,7 +393,7 @@ fail_queueing: for_each_set_bit(pipe, imgu->css.enabled_pipes, IMGU_MAX_PIPE_NUM) imgu_dummybufs_cleanup(imgu, pipe); fail_dummybufs: - ipu3_css_stop_streaming(&imgu->css); + imgu_css_stop_streaming(&imgu->css); fail_start_streaming: pm_runtime_put(dev); @@ -435,7 +435,7 @@ static int imgu_video_nodes_init(struct imgu_device *imgu) rects[IPU3_CSS_RECT_EFFECTIVE] = &imgu_pipe->imgu_sd.rect.eff; rects[IPU3_CSS_RECT_BDS] = &imgu_pipe->imgu_sd.rect.bds; - ipu3_css_fmt_set(&imgu->css, fmts, rects, j); + imgu_css_fmt_set(&imgu->css, fmts, rects, j); /* Pre-allocate dummy buffers */ r = imgu_dummybufs_preallocate(imgu, j); @@ -478,23 +478,22 @@ static irqreturn_t imgu_isr_threaded(int irq, void *imgu_ptr) /* Dequeue / queue buffers */ do { u64 ns = ktime_get_ns(); - struct ipu3_css_buffer *b; + struct imgu_css_buffer *b; struct imgu_buffer *buf = NULL; unsigned int node, pipe; bool dummy; do { mutex_lock(&imgu->lock); - b = ipu3_css_buf_dequeue(&imgu->css); + b = imgu_css_buf_dequeue(&imgu->css); mutex_unlock(&imgu->lock); } while (PTR_ERR(b) == -EAGAIN); - if (IS_ERR_OR_NULL(b)) { - if (!b || PTR_ERR(b) == -EBUSY) /* All done */ - break; - dev_err(&imgu->pci_dev->dev, - "failed to dequeue buffers (%ld)\n", - PTR_ERR(b)); + if (IS_ERR(b)) { + if (PTR_ERR(b) != -EBUSY) /* All done */ + dev_err(&imgu->pci_dev->dev, + "failed to dequeue buffers (%ld)\n", + PTR_ERR(b)); break; } @@ -526,12 +525,12 @@ static irqreturn_t imgu_isr_threaded(int irq, void *imgu_ptr) buf->vid_buf.vbb.sequence); } imgu_buffer_done(imgu, &buf->vid_buf.vbb.vb2_buf, - ipu3_css_buf_state(&buf->css_buf) == + imgu_css_buf_state(&buf->css_buf) == IPU3_CSS_BUFFER_DONE ? VB2_BUF_STATE_DONE : VB2_BUF_STATE_ERROR); mutex_lock(&imgu->lock); - if (ipu3_css_queue_empty(&imgu->css)) + if (imgu_css_queue_empty(&imgu->css)) wake_up_all(&imgu->buf_drain_wq); mutex_unlock(&imgu->lock); } while (1); @@ -553,7 +552,7 @@ static irqreturn_t imgu_isr(int irq, void *imgu_ptr) struct imgu_device *imgu = imgu_ptr; /* acknowledge interruption */ - if (ipu3_css_irq_ack(&imgu->css) < 0) + if (imgu_css_irq_ack(&imgu->css) < 0) return IRQ_NONE; return IRQ_WAKE_THREAD; @@ -638,21 +637,21 @@ static int imgu_pci_probe(struct pci_dev *pci_dev, atomic_set(&imgu->qbuf_barrier, 0); init_waitqueue_head(&imgu->buf_drain_wq); - r = ipu3_css_set_powerup(&pci_dev->dev, imgu->base); + r = imgu_css_set_powerup(&pci_dev->dev, imgu->base); if (r) { dev_err(&pci_dev->dev, "failed to power up CSS (%d)\n", r); goto out_mutex_destroy; } - imgu->mmu = ipu3_mmu_init(&pci_dev->dev, imgu->base); + imgu->mmu = imgu_mmu_init(&pci_dev->dev, imgu->base); if (IS_ERR(imgu->mmu)) { r = PTR_ERR(imgu->mmu); dev_err(&pci_dev->dev, "failed to initialize MMU (%d)\n", r); goto out_css_powerdown; } - r = ipu3_dmamap_init(imgu); + r = imgu_dmamap_init(imgu); if (r) { dev_err(&pci_dev->dev, "failed to initialize DMA mapping (%d)\n", r); @@ -660,7 +659,7 @@ static int imgu_pci_probe(struct pci_dev *pci_dev, } /* ISP programming */ - r = ipu3_css_init(&pci_dev->dev, &imgu->css, imgu->base, phys_len); + r = imgu_css_init(&pci_dev->dev, &imgu->css, imgu->base, phys_len); if (r) { dev_err(&pci_dev->dev, "failed to initialize CSS (%d)\n", r); goto out_dmamap_exit; @@ -690,13 +689,13 @@ static int imgu_pci_probe(struct pci_dev *pci_dev, out_video_exit: imgu_video_nodes_exit(imgu); out_css_cleanup: - ipu3_css_cleanup(&imgu->css); + imgu_css_cleanup(&imgu->css); out_dmamap_exit: - ipu3_dmamap_exit(imgu); + imgu_dmamap_exit(imgu); out_mmu_exit: - ipu3_mmu_exit(imgu->mmu); + imgu_mmu_exit(imgu->mmu); out_css_powerdown: - ipu3_css_set_powerdown(&pci_dev->dev, imgu->base); + imgu_css_set_powerdown(&pci_dev->dev, imgu->base); out_mutex_destroy: mutex_destroy(&imgu->lock); @@ -711,10 +710,10 @@ static void imgu_pci_remove(struct pci_dev *pci_dev) pm_runtime_get_noresume(&pci_dev->dev); imgu_video_nodes_exit(imgu); - ipu3_css_cleanup(&imgu->css); - ipu3_css_set_powerdown(&pci_dev->dev, imgu->base); - ipu3_dmamap_exit(imgu); - ipu3_mmu_exit(imgu->mmu); + imgu_css_cleanup(&imgu->css); + imgu_css_set_powerdown(&pci_dev->dev, imgu->base); + imgu_dmamap_exit(imgu); + imgu_mmu_exit(imgu->mmu); mutex_destroy(&imgu->lock); } @@ -724,7 +723,7 @@ static int __maybe_unused imgu_suspend(struct device *dev) struct imgu_device *imgu = pci_get_drvdata(pci_dev); dev_dbg(dev, "enter %s\n", __func__); - imgu->suspend_in_stream = ipu3_css_is_streaming(&imgu->css); + imgu->suspend_in_stream = imgu_css_is_streaming(&imgu->css); if (!imgu->suspend_in_stream) goto out; /* Block new buffers to be queued to CSS. */ @@ -736,10 +735,10 @@ static int __maybe_unused imgu_suspend(struct device *dev) synchronize_irq(pci_dev->irq); /* Wait until all buffers in CSS are done. */ if (!wait_event_timeout(imgu->buf_drain_wq, - ipu3_css_queue_empty(&imgu->css), msecs_to_jiffies(1000))) + imgu_css_queue_empty(&imgu->css), msecs_to_jiffies(1000))) dev_err(dev, "wait buffer drain timeout.\n"); - ipu3_css_stop_streaming(&imgu->css); + imgu_css_stop_streaming(&imgu->css); atomic_set(&imgu->qbuf_barrier, 0); imgu_powerdown(imgu); pm_runtime_force_suspend(dev); @@ -769,7 +768,7 @@ static int __maybe_unused imgu_resume(struct device *dev) } /* Start CSS streaming */ - r = ipu3_css_start_streaming(&imgu->css); + r = imgu_css_start_streaming(&imgu->css); if (r) { dev_err(dev, "failed to resume css streaming (%d)", r); goto out; diff --git a/drivers/staging/media/ipu3/ipu3.h b/drivers/staging/media/ipu3/ipu3.h index 04fc99f47ebb..73b123b2b8a2 100644 --- a/drivers/staging/media/ipu3/ipu3.h +++ b/drivers/staging/media/ipu3/ipu3.h @@ -32,7 +32,7 @@ #define IMGU_NODE_STAT_3A 4 /* 3A statistics */ #define IMGU_NODE_NUM 5 -#define file_to_intel_ipu3_node(__file) \ +#define file_to_intel_imgu_node(__file) \ container_of(video_devdata(__file), struct imgu_video_device, vdev) #define IPU3_INPUT_MIN_WIDTH 0U @@ -44,7 +44,7 @@ #define IPU3_OUTPUT_MAX_WIDTH 4480U #define IPU3_OUTPUT_MAX_HEIGHT 34004U -struct ipu3_vb2_buffer { +struct imgu_vb2_buffer { /* Public fields */ struct vb2_v4l2_buffer vbb; /* Must be the first field */ @@ -53,9 +53,9 @@ struct ipu3_vb2_buffer { }; struct imgu_buffer { - struct ipu3_vb2_buffer vid_buf; /* Must be the first field */ - struct ipu3_css_buffer css_buf; - struct ipu3_css_map map; + struct imgu_vb2_buffer vid_buf; /* Must be the first field */ + struct imgu_css_buffer css_buf; + struct imgu_css_map map; }; struct imgu_node_mapping { @@ -107,8 +107,8 @@ struct imgu_media_pipe { /* Internally enabled queues */ struct { - struct ipu3_css_map dmap; - struct ipu3_css_buffer dummybufs[IMGU_MAX_QUEUE_DEPTH]; + struct imgu_css_map dmap; + struct imgu_css_buffer dummybufs[IMGU_MAX_QUEUE_DEPTH]; } queues[IPU3_CSS_QUEUES]; struct imgu_video_device nodes[IMGU_NODE_NUM]; bool queue_enabled[IMGU_NODE_NUM]; @@ -135,18 +135,18 @@ struct imgu_device { struct v4l2_file_operations v4l2_file_ops; /* MMU driver for css */ - struct ipu3_mmu_info *mmu; + struct imgu_mmu_info *mmu; struct iova_domain iova_domain; /* css - Camera Sub-System */ - struct ipu3_css css; + struct imgu_css css; /* * Coarse-grained lock to protect * vid_buf.list and css->queue */ struct mutex lock; - /* Forbit streaming and buffer queuing during system suspend. */ + /* Forbid streaming and buffer queuing during system suspend. */ atomic_t qbuf_barrier; /* Indicate if system suspend take place while imgu is streaming. */ bool suspend_in_stream; diff --git a/drivers/staging/media/omap4iss/iss_csi2.c b/drivers/staging/media/omap4iss/iss_csi2.c index 059cf5bd3c36..a6dc2d2b1228 100644 --- a/drivers/staging/media/omap4iss/iss_csi2.c +++ b/drivers/staging/media/omap4iss/iss_csi2.c @@ -712,7 +712,7 @@ static void csi2_isr_ctx(struct iss_csi2_device *csi2, /* Skip interrupts until we reach the frame skip count. The CSI2 will be * automatically disabled, as the frame skip count has been programmed - * in the CSI2_CTx_CTRL1::COUNT field, so reenable it. + * in the CSI2_CTx_CTRL1::COUNT field, so re-enable it. * * It would have been nice to rely on the FRAME_NUMBER interrupt instead * but it turned out that the interrupt is only generated when the CSI2 diff --git a/drivers/staging/media/rockchip/vpu/rk3288_vpu_hw_jpeg_enc.c b/drivers/staging/media/rockchip/vpu/rk3288_vpu_hw_jpeg_enc.c index 5282236d1bb1..06daea66fb49 100644 --- a/drivers/staging/media/rockchip/vpu/rk3288_vpu_hw_jpeg_enc.c +++ b/drivers/staging/media/rockchip/vpu/rk3288_vpu_hw_jpeg_enc.c @@ -80,7 +80,7 @@ rk3288_vpu_jpeg_enc_set_qtable(struct rockchip_vpu_dev *vpu, void rk3288_vpu_jpeg_enc_run(struct rockchip_vpu_ctx *ctx) { struct rockchip_vpu_dev *vpu = ctx->dev; - struct vb2_buffer *src_buf, *dst_buf; + struct vb2_v4l2_buffer *src_buf, *dst_buf; struct rockchip_vpu_jpeg_ctx jpeg_ctx; u32 reg; @@ -88,7 +88,7 @@ void rk3288_vpu_jpeg_enc_run(struct rockchip_vpu_ctx *ctx) dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); memset(&jpeg_ctx, 0, sizeof(jpeg_ctx)); - jpeg_ctx.buffer = vb2_plane_vaddr(dst_buf, 0); + jpeg_ctx.buffer = vb2_plane_vaddr(&dst_buf->vb2_buf, 0); jpeg_ctx.width = ctx->dst_fmt.width; jpeg_ctx.height = ctx->dst_fmt.height; jpeg_ctx.quality = ctx->jpeg_quality; @@ -99,7 +99,7 @@ void rk3288_vpu_jpeg_enc_run(struct rockchip_vpu_ctx *ctx) VEPU_REG_ENC_CTRL); rk3288_vpu_set_src_img_ctrl(vpu, ctx); - rk3288_vpu_jpeg_enc_set_buffers(vpu, ctx, src_buf); + rk3288_vpu_jpeg_enc_set_buffers(vpu, ctx, &src_buf->vb2_buf); rk3288_vpu_jpeg_enc_set_qtable(vpu, rockchip_vpu_jpeg_get_qtable(&jpeg_ctx, 0), rockchip_vpu_jpeg_get_qtable(&jpeg_ctx, 1)); diff --git a/drivers/staging/media/rockchip/vpu/rk3399_vpu_hw_jpeg_enc.c b/drivers/staging/media/rockchip/vpu/rk3399_vpu_hw_jpeg_enc.c index dbc86d95fe3b..3d438797692e 100644 --- a/drivers/staging/media/rockchip/vpu/rk3399_vpu_hw_jpeg_enc.c +++ b/drivers/staging/media/rockchip/vpu/rk3399_vpu_hw_jpeg_enc.c @@ -111,7 +111,7 @@ rk3399_vpu_jpeg_enc_set_qtable(struct rockchip_vpu_dev *vpu, void rk3399_vpu_jpeg_enc_run(struct rockchip_vpu_ctx *ctx) { struct rockchip_vpu_dev *vpu = ctx->dev; - struct vb2_buffer *src_buf, *dst_buf; + struct vb2_v4l2_buffer *src_buf, *dst_buf; struct rockchip_vpu_jpeg_ctx jpeg_ctx; u32 reg; @@ -119,7 +119,7 @@ void rk3399_vpu_jpeg_enc_run(struct rockchip_vpu_ctx *ctx) dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); memset(&jpeg_ctx, 0, sizeof(jpeg_ctx)); - jpeg_ctx.buffer = vb2_plane_vaddr(dst_buf, 0); + jpeg_ctx.buffer = vb2_plane_vaddr(&dst_buf->vb2_buf, 0); jpeg_ctx.width = ctx->dst_fmt.width; jpeg_ctx.height = ctx->dst_fmt.height; jpeg_ctx.quality = ctx->jpeg_quality; @@ -130,7 +130,7 @@ void rk3399_vpu_jpeg_enc_run(struct rockchip_vpu_ctx *ctx) VEPU_REG_ENCODE_START); rk3399_vpu_set_src_img_ctrl(vpu, ctx); - rk3399_vpu_jpeg_enc_set_buffers(vpu, ctx, src_buf); + rk3399_vpu_jpeg_enc_set_buffers(vpu, ctx, &src_buf->vb2_buf); rk3399_vpu_jpeg_enc_set_qtable(vpu, rockchip_vpu_jpeg_get_qtable(&jpeg_ctx, 0), rockchip_vpu_jpeg_get_qtable(&jpeg_ctx, 1)); diff --git a/drivers/staging/media/soc_camera/Kconfig b/drivers/staging/media/soc_camera/Kconfig new file mode 100644 index 000000000000..bacd30f0348d --- /dev/null +++ b/drivers/staging/media/soc_camera/Kconfig @@ -0,0 +1,50 @@ +config SOC_CAMERA + tristate "SoC camera support" + depends on VIDEO_V4L2 && HAS_DMA && I2C && BROKEN + select VIDEOBUF2_CORE + help + SoC Camera is a common API to several cameras, not connecting + over a bus like PCI or USB. For example some i2c camera connected + directly to the data bus of an SoC. + +comment "soc_camera sensor drivers" + +config SOC_CAMERA_MT9M111 + tristate "legacy soc_camera mt9m111, mt9m112 and mt9m131 support" + depends on SOC_CAMERA && I2C + select VIDEO_MT9M111 + help + This driver supports MT9M111, MT9M112 and MT9M131 cameras from + Micron/Aptina. + This is the legacy configuration which shouldn't be used anymore, + while VIDEO_MT9M111 should be used instead. + +config SOC_CAMERA_MT9V022 + tristate "mt9v022 and mt9v024 support" + depends on SOC_CAMERA && I2C + help + This driver supports MT9V022 cameras from Micron + +config SOC_CAMERA_OV5642 + tristate "ov5642 camera support" + depends on SOC_CAMERA && I2C + help + This is a V4L2 camera driver for the OmniVision OV5642 sensor + +config SOC_CAMERA_OV9740 + tristate "ov9740 camera support" + depends on SOC_CAMERA && I2C + help + This is a ov9740 camera driver + +config SOC_CAMERA_IMX074 + tristate "imx074 support (DEPRECATED)" + depends on SOC_CAMERA && I2C + help + This driver supports IMX074 cameras from Sony + +config SOC_CAMERA_MT9T031 + tristate "mt9t031 support (DEPRECATED)" + depends on SOC_CAMERA && I2C + help + This driver supports MT9T031 cameras from Micron. diff --git a/drivers/staging/media/soc_camera/Makefile b/drivers/staging/media/soc_camera/Makefile new file mode 100644 index 000000000000..3a351bd629f5 --- /dev/null +++ b/drivers/staging/media/soc_camera/Makefile @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: GPL-2.0 +obj-$(CONFIG_SOC_CAMERA) += soc_camera.o soc_mediabus.o +obj-$(CONFIG_SOC_CAMERA_MT9V022) += soc_mt9v022.o +obj-$(CONFIG_SOC_CAMERA_OV5642) += soc_ov5642.o +obj-$(CONFIG_SOC_CAMERA_OV9740) += soc_ov9740.o +obj-$(CONFIG_SOC_CAMERA_IMX074) += imx074.o +obj-$(CONFIG_SOC_CAMERA_MT9T031) += mt9t031.o diff --git a/drivers/staging/media/imx074/imx074.c b/drivers/staging/media/soc_camera/imx074.c index 1676c166dc83..1676c166dc83 100644 --- a/drivers/staging/media/imx074/imx074.c +++ b/drivers/staging/media/soc_camera/imx074.c diff --git a/drivers/staging/media/mt9t031/mt9t031.c b/drivers/staging/media/soc_camera/mt9t031.c index 4ff179302b4f..4ff179302b4f 100644 --- a/drivers/staging/media/mt9t031/mt9t031.c +++ b/drivers/staging/media/soc_camera/mt9t031.c diff --git a/drivers/staging/media/soc_camera/soc_camera.c b/drivers/staging/media/soc_camera/soc_camera.c new file mode 100644 index 000000000000..1ab86a7499b9 --- /dev/null +++ b/drivers/staging/media/soc_camera/soc_camera.c @@ -0,0 +1,2170 @@ +/* + * camera image capture (abstract) bus driver + * + * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de> + * + * This driver provides an interface between platform-specific camera + * buses and camera devices. It should be used if the camera is + * connected not over a "proper" bus like PCI or USB, but over a + * special bus, like, for example, the Quick Capture interface on PXA270 + * SoCs. Later it should also be used for i.MX31 SoCs from Freescale. + * It can handle multiple cameras and / or multiple buses, which can + * be used, e.g., in stereo-vision applications. + * + * 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. + */ + +#include <linux/device.h> +#include <linux/err.h> +#include <linux/i2c.h> +#include <linux/init.h> +#include <linux/list.h> +#include <linux/module.h> +#include <linux/mutex.h> +#include <linux/of_graph.h> +#include <linux/platform_device.h> +#include <linux/pm_runtime.h> +#include <linux/regulator/consumer.h> +#include <linux/slab.h> +#include <linux/vmalloc.h> + +#include <media/soc_camera.h> +#include <media/drv-intf/soc_mediabus.h> +#include <media/v4l2-async.h> +#include <media/v4l2-clk.h> +#include <media/v4l2-common.h> +#include <media/v4l2-ioctl.h> +#include <media/v4l2-dev.h> +#include <media/v4l2-fwnode.h> +#include <media/videobuf2-v4l2.h> + +/* Default to VGA resolution */ +#define DEFAULT_WIDTH 640 +#define DEFAULT_HEIGHT 480 + +#define MAP_MAX_NUM 32 +static DECLARE_BITMAP(device_map, MAP_MAX_NUM); +static LIST_HEAD(hosts); +static LIST_HEAD(devices); +/* + * Protects lists and bitmaps of hosts and devices. + * Lock nesting: Ok to take ->host_lock under list_lock. + */ +static DEFINE_MUTEX(list_lock); + +struct soc_camera_async_client { + struct v4l2_async_subdev *sensor; + struct v4l2_async_notifier notifier; + struct platform_device *pdev; + struct list_head list; /* needed for clean up */ +}; + +static int soc_camera_video_start(struct soc_camera_device *icd); +static int video_dev_create(struct soc_camera_device *icd); + +int soc_camera_power_on(struct device *dev, struct soc_camera_subdev_desc *ssdd, + struct v4l2_clk *clk) +{ + int ret; + bool clock_toggle; + + if (clk && (!ssdd->unbalanced_power || + !test_and_set_bit(0, &ssdd->clock_state))) { + ret = v4l2_clk_enable(clk); + if (ret < 0) { + dev_err(dev, "Cannot enable clock: %d\n", ret); + return ret; + } + clock_toggle = true; + } else { + clock_toggle = false; + } + + ret = regulator_bulk_enable(ssdd->sd_pdata.num_regulators, + ssdd->sd_pdata.regulators); + if (ret < 0) { + dev_err(dev, "Cannot enable regulators\n"); + goto eregenable; + } + + if (ssdd->power) { + ret = ssdd->power(dev, 1); + if (ret < 0) { + dev_err(dev, + "Platform failed to power-on the camera.\n"); + goto epwron; + } + } + + return 0; + +epwron: + regulator_bulk_disable(ssdd->sd_pdata.num_regulators, + ssdd->sd_pdata.regulators); +eregenable: + if (clock_toggle) + v4l2_clk_disable(clk); + + return ret; +} +EXPORT_SYMBOL(soc_camera_power_on); + +int soc_camera_power_off(struct device *dev, struct soc_camera_subdev_desc *ssdd, + struct v4l2_clk *clk) +{ + int ret = 0; + int err; + + if (ssdd->power) { + err = ssdd->power(dev, 0); + if (err < 0) { + dev_err(dev, + "Platform failed to power-off the camera.\n"); + ret = err; + } + } + + err = regulator_bulk_disable(ssdd->sd_pdata.num_regulators, + ssdd->sd_pdata.regulators); + if (err < 0) { + dev_err(dev, "Cannot disable regulators\n"); + ret = ret ? : err; + } + + if (clk && (!ssdd->unbalanced_power || test_and_clear_bit(0, &ssdd->clock_state))) + v4l2_clk_disable(clk); + + return ret; +} +EXPORT_SYMBOL(soc_camera_power_off); + +int soc_camera_power_init(struct device *dev, struct soc_camera_subdev_desc *ssdd) +{ + /* Should not have any effect in synchronous case */ + return devm_regulator_bulk_get(dev, ssdd->sd_pdata.num_regulators, + ssdd->sd_pdata.regulators); +} +EXPORT_SYMBOL(soc_camera_power_init); + +static int __soc_camera_power_on(struct soc_camera_device *icd) +{ + struct v4l2_subdev *sd = soc_camera_to_subdev(icd); + int ret; + + ret = v4l2_subdev_call(sd, core, s_power, 1); + if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV) + return ret; + + return 0; +} + +static int __soc_camera_power_off(struct soc_camera_device *icd) +{ + struct v4l2_subdev *sd = soc_camera_to_subdev(icd); + int ret; + + ret = v4l2_subdev_call(sd, core, s_power, 0); + if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV) + return ret; + + return 0; +} + +static int soc_camera_clock_start(struct soc_camera_host *ici) +{ + int ret; + + if (!ici->ops->clock_start) + return 0; + + mutex_lock(&ici->clk_lock); + ret = ici->ops->clock_start(ici); + mutex_unlock(&ici->clk_lock); + + return ret; +} + +static void soc_camera_clock_stop(struct soc_camera_host *ici) +{ + if (!ici->ops->clock_stop) + return; + + mutex_lock(&ici->clk_lock); + ici->ops->clock_stop(ici); + mutex_unlock(&ici->clk_lock); +} + +const struct soc_camera_format_xlate *soc_camera_xlate_by_fourcc( + struct soc_camera_device *icd, unsigned int fourcc) +{ + unsigned int i; + + for (i = 0; i < icd->num_user_formats; i++) + if (icd->user_formats[i].host_fmt->fourcc == fourcc) + return icd->user_formats + i; + return NULL; +} +EXPORT_SYMBOL(soc_camera_xlate_by_fourcc); + +/** + * soc_camera_apply_board_flags() - apply platform SOCAM_SENSOR_INVERT_* flags + * @ssdd: camera platform parameters + * @cfg: media bus configuration + * @return: resulting flags + */ +unsigned long soc_camera_apply_board_flags(struct soc_camera_subdev_desc *ssdd, + const struct v4l2_mbus_config *cfg) +{ + unsigned long f, flags = cfg->flags; + + /* If only one of the two polarities is supported, switch to the opposite */ + if (ssdd->flags & SOCAM_SENSOR_INVERT_HSYNC) { + f = flags & (V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_LOW); + if (f == V4L2_MBUS_HSYNC_ACTIVE_HIGH || f == V4L2_MBUS_HSYNC_ACTIVE_LOW) + flags ^= V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_LOW; + } + + if (ssdd->flags & SOCAM_SENSOR_INVERT_VSYNC) { + f = flags & (V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_LOW); + if (f == V4L2_MBUS_VSYNC_ACTIVE_HIGH || f == V4L2_MBUS_VSYNC_ACTIVE_LOW) + flags ^= V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_LOW; + } + + if (ssdd->flags & SOCAM_SENSOR_INVERT_PCLK) { + f = flags & (V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_PCLK_SAMPLE_FALLING); + if (f == V4L2_MBUS_PCLK_SAMPLE_RISING || f == V4L2_MBUS_PCLK_SAMPLE_FALLING) + flags ^= V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_PCLK_SAMPLE_FALLING; + } + + return flags; +} +EXPORT_SYMBOL(soc_camera_apply_board_flags); + +#define pixfmtstr(x) (x) & 0xff, ((x) >> 8) & 0xff, ((x) >> 16) & 0xff, \ + ((x) >> 24) & 0xff + +static int soc_camera_try_fmt(struct soc_camera_device *icd, + struct v4l2_format *f) +{ + struct soc_camera_host *ici = to_soc_camera_host(icd->parent); + const struct soc_camera_format_xlate *xlate; + struct v4l2_pix_format *pix = &f->fmt.pix; + int ret; + + dev_dbg(icd->pdev, "TRY_FMT(%c%c%c%c, %ux%u)\n", + pixfmtstr(pix->pixelformat), pix->width, pix->height); + + if (pix->pixelformat != V4L2_PIX_FMT_JPEG && + !(ici->capabilities & SOCAM_HOST_CAP_STRIDE)) { + pix->bytesperline = 0; + pix->sizeimage = 0; + } + + ret = ici->ops->try_fmt(icd, f); + if (ret < 0) + return ret; + + xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); + if (!xlate) + return -EINVAL; + + ret = soc_mbus_bytes_per_line(pix->width, xlate->host_fmt); + if (ret < 0) + return ret; + + pix->bytesperline = max_t(u32, pix->bytesperline, ret); + + ret = soc_mbus_image_size(xlate->host_fmt, pix->bytesperline, + pix->height); + if (ret < 0) + return ret; + + pix->sizeimage = max_t(u32, pix->sizeimage, ret); + + return 0; +} + +static int soc_camera_try_fmt_vid_cap(struct file *file, void *priv, + struct v4l2_format *f) +{ + struct soc_camera_device *icd = file->private_data; + + WARN_ON(priv != file->private_data); + + /* Only single-plane capture is supported so far */ + if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + + /* limit format to hardware capabilities */ + return soc_camera_try_fmt(icd, f); +} + +static int soc_camera_enum_input(struct file *file, void *priv, + struct v4l2_input *inp) +{ + struct soc_camera_device *icd = file->private_data; + + if (inp->index != 0) + return -EINVAL; + + /* default is camera */ + inp->type = V4L2_INPUT_TYPE_CAMERA; + inp->std = icd->vdev->tvnorms; + strscpy(inp->name, "Camera", sizeof(inp->name)); + + return 0; +} + +static int soc_camera_g_input(struct file *file, void *priv, unsigned int *i) +{ + *i = 0; + + return 0; +} + +static int soc_camera_s_input(struct file *file, void *priv, unsigned int i) +{ + if (i > 0) + return -EINVAL; + + return 0; +} + +static int soc_camera_s_std(struct file *file, void *priv, v4l2_std_id a) +{ + struct soc_camera_device *icd = file->private_data; + struct v4l2_subdev *sd = soc_camera_to_subdev(icd); + + return v4l2_subdev_call(sd, video, s_std, a); +} + +static int soc_camera_g_std(struct file *file, void *priv, v4l2_std_id *a) +{ + struct soc_camera_device *icd = file->private_data; + struct v4l2_subdev *sd = soc_camera_to_subdev(icd); + + return v4l2_subdev_call(sd, video, g_std, a); +} + +static int soc_camera_enum_framesizes(struct file *file, void *fh, + struct v4l2_frmsizeenum *fsize) +{ + struct soc_camera_device *icd = file->private_data; + struct soc_camera_host *ici = to_soc_camera_host(icd->parent); + + return ici->ops->enum_framesizes(icd, fsize); +} + +static int soc_camera_reqbufs(struct file *file, void *priv, + struct v4l2_requestbuffers *p) +{ + int ret; + struct soc_camera_device *icd = file->private_data; + + WARN_ON(priv != file->private_data); + + if (icd->streamer && icd->streamer != file) + return -EBUSY; + + ret = vb2_reqbufs(&icd->vb2_vidq, p); + if (!ret) + icd->streamer = p->count ? file : NULL; + return ret; +} + +static int soc_camera_querybuf(struct file *file, void *priv, + struct v4l2_buffer *p) +{ + struct soc_camera_device *icd = file->private_data; + + WARN_ON(priv != file->private_data); + + return vb2_querybuf(&icd->vb2_vidq, p); +} + +static int soc_camera_qbuf(struct file *file, void *priv, + struct v4l2_buffer *p) +{ + struct soc_camera_device *icd = file->private_data; + + WARN_ON(priv != file->private_data); + + if (icd->streamer != file) + return -EBUSY; + + return vb2_qbuf(&icd->vb2_vidq, NULL, p); +} + +static int soc_camera_dqbuf(struct file *file, void *priv, + struct v4l2_buffer *p) +{ + struct soc_camera_device *icd = file->private_data; + + WARN_ON(priv != file->private_data); + + if (icd->streamer != file) + return -EBUSY; + + return vb2_dqbuf(&icd->vb2_vidq, p, file->f_flags & O_NONBLOCK); +} + +static int soc_camera_create_bufs(struct file *file, void *priv, + struct v4l2_create_buffers *create) +{ + struct soc_camera_device *icd = file->private_data; + int ret; + + if (icd->streamer && icd->streamer != file) + return -EBUSY; + + ret = vb2_create_bufs(&icd->vb2_vidq, create); + if (!ret) + icd->streamer = file; + return ret; +} + +static int soc_camera_prepare_buf(struct file *file, void *priv, + struct v4l2_buffer *b) +{ + struct soc_camera_device *icd = file->private_data; + + return vb2_prepare_buf(&icd->vb2_vidq, NULL, b); +} + +static int soc_camera_expbuf(struct file *file, void *priv, + struct v4l2_exportbuffer *p) +{ + struct soc_camera_device *icd = file->private_data; + + if (icd->streamer && icd->streamer != file) + return -EBUSY; + return vb2_expbuf(&icd->vb2_vidq, p); +} + +/* Always entered with .host_lock held */ +static int soc_camera_init_user_formats(struct soc_camera_device *icd) +{ + struct v4l2_subdev *sd = soc_camera_to_subdev(icd); + struct soc_camera_host *ici = to_soc_camera_host(icd->parent); + unsigned int i, fmts = 0, raw_fmts = 0; + int ret; + struct v4l2_subdev_mbus_code_enum code = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + }; + + while (!v4l2_subdev_call(sd, pad, enum_mbus_code, NULL, &code)) { + raw_fmts++; + code.index++; + } + + if (!ici->ops->get_formats) + /* + * Fallback mode - the host will have to serve all + * sensor-provided formats one-to-one to the user + */ + fmts = raw_fmts; + else + /* + * First pass - only count formats this host-sensor + * configuration can provide + */ + for (i = 0; i < raw_fmts; i++) { + ret = ici->ops->get_formats(icd, i, NULL); + if (ret < 0) + return ret; + fmts += ret; + } + + if (!fmts) + return -ENXIO; + + icd->user_formats = + vmalloc(array_size(fmts, + sizeof(struct soc_camera_format_xlate))); + if (!icd->user_formats) + return -ENOMEM; + + dev_dbg(icd->pdev, "Found %d supported formats.\n", fmts); + + /* Second pass - actually fill data formats */ + fmts = 0; + for (i = 0; i < raw_fmts; i++) + if (!ici->ops->get_formats) { + code.index = i; + v4l2_subdev_call(sd, pad, enum_mbus_code, NULL, &code); + icd->user_formats[fmts].host_fmt = + soc_mbus_get_fmtdesc(code.code); + if (icd->user_formats[fmts].host_fmt) + icd->user_formats[fmts++].code = code.code; + } else { + ret = ici->ops->get_formats(icd, i, + &icd->user_formats[fmts]); + if (ret < 0) + goto egfmt; + fmts += ret; + } + + icd->num_user_formats = fmts; + icd->current_fmt = &icd->user_formats[0]; + + return 0; + +egfmt: + vfree(icd->user_formats); + return ret; +} + +/* Always entered with .host_lock held */ +static void soc_camera_free_user_formats(struct soc_camera_device *icd) +{ + struct soc_camera_host *ici = to_soc_camera_host(icd->parent); + + if (ici->ops->put_formats) + ici->ops->put_formats(icd); + icd->current_fmt = NULL; + icd->num_user_formats = 0; + vfree(icd->user_formats); + icd->user_formats = NULL; +} + +/* Called with .vb_lock held, or from the first open(2), see comment there */ +static int soc_camera_set_fmt(struct soc_camera_device *icd, + struct v4l2_format *f) +{ + struct soc_camera_host *ici = to_soc_camera_host(icd->parent); + struct v4l2_pix_format *pix = &f->fmt.pix; + int ret; + + dev_dbg(icd->pdev, "S_FMT(%c%c%c%c, %ux%u)\n", + pixfmtstr(pix->pixelformat), pix->width, pix->height); + + /* We always call try_fmt() before set_fmt() or set_selection() */ + ret = soc_camera_try_fmt(icd, f); + if (ret < 0) + return ret; + + ret = ici->ops->set_fmt(icd, f); + if (ret < 0) { + return ret; + } else if (!icd->current_fmt || + icd->current_fmt->host_fmt->fourcc != pix->pixelformat) { + dev_err(icd->pdev, + "Host driver hasn't set up current format correctly!\n"); + return -EINVAL; + } + + icd->user_width = pix->width; + icd->user_height = pix->height; + icd->bytesperline = pix->bytesperline; + icd->sizeimage = pix->sizeimage; + icd->colorspace = pix->colorspace; + icd->field = pix->field; + + dev_dbg(icd->pdev, "set width: %d height: %d\n", + icd->user_width, icd->user_height); + + /* set physical bus parameters */ + return ici->ops->set_bus_param(icd); +} + +static int soc_camera_add_device(struct soc_camera_device *icd) +{ + struct soc_camera_host *ici = to_soc_camera_host(icd->parent); + int ret; + + if (ici->icd) + return -EBUSY; + + if (!icd->clk) { + ret = soc_camera_clock_start(ici); + if (ret < 0) + return ret; + } + + if (ici->ops->add) { + ret = ici->ops->add(icd); + if (ret < 0) + goto eadd; + } + + ici->icd = icd; + + return 0; + +eadd: + if (!icd->clk) + soc_camera_clock_stop(ici); + return ret; +} + +static void soc_camera_remove_device(struct soc_camera_device *icd) +{ + struct soc_camera_host *ici = to_soc_camera_host(icd->parent); + + if (WARN_ON(icd != ici->icd)) + return; + + if (ici->ops->remove) + ici->ops->remove(icd); + if (!icd->clk) + soc_camera_clock_stop(ici); + ici->icd = NULL; +} + +static int soc_camera_open(struct file *file) +{ + struct video_device *vdev = video_devdata(file); + struct soc_camera_device *icd; + struct soc_camera_host *ici; + int ret; + + /* + * Don't mess with the host during probe: wait until the loop in + * scan_add_host() completes. Also protect against a race with + * soc_camera_host_unregister(). + */ + if (mutex_lock_interruptible(&list_lock)) + return -ERESTARTSYS; + + if (!vdev || !video_is_registered(vdev)) { + mutex_unlock(&list_lock); + return -ENODEV; + } + + icd = video_get_drvdata(vdev); + ici = to_soc_camera_host(icd->parent); + + ret = try_module_get(ici->ops->owner) ? 0 : -ENODEV; + mutex_unlock(&list_lock); + + if (ret < 0) { + dev_err(icd->pdev, "Couldn't lock capture bus driver.\n"); + return ret; + } + + if (!to_soc_camera_control(icd)) { + /* No device driver attached */ + ret = -ENODEV; + goto econtrol; + } + + if (mutex_lock_interruptible(&ici->host_lock)) { + ret = -ERESTARTSYS; + goto elockhost; + } + icd->use_count++; + + /* Now we really have to activate the camera */ + if (icd->use_count == 1) { + struct soc_camera_desc *sdesc = to_soc_camera_desc(icd); + /* Restore parameters before the last close() per V4L2 API */ + struct v4l2_format f = { + .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, + .fmt.pix = { + .width = icd->user_width, + .height = icd->user_height, + .field = icd->field, + .colorspace = icd->colorspace, + .pixelformat = + icd->current_fmt->host_fmt->fourcc, + }, + }; + + /* The camera could have been already on, try to reset */ + if (sdesc->subdev_desc.reset) + if (icd->control) + sdesc->subdev_desc.reset(icd->control); + + ret = soc_camera_add_device(icd); + if (ret < 0) { + dev_err(icd->pdev, "Couldn't activate the camera: %d\n", ret); + goto eiciadd; + } + + ret = __soc_camera_power_on(icd); + if (ret < 0) + goto epower; + + pm_runtime_enable(&icd->vdev->dev); + ret = pm_runtime_resume(&icd->vdev->dev); + if (ret < 0 && ret != -ENOSYS) + goto eresume; + + /* + * Try to configure with default parameters. Notice: this is the + * very first open, so, we cannot race against other calls, + * apart from someone else calling open() simultaneously, but + * .host_lock is protecting us against it. + */ + ret = soc_camera_set_fmt(icd, &f); + if (ret < 0) + goto esfmt; + + ret = ici->ops->init_videobuf2(&icd->vb2_vidq, icd); + if (ret < 0) + goto einitvb; + v4l2_ctrl_handler_setup(&icd->ctrl_handler); + } + mutex_unlock(&ici->host_lock); + + file->private_data = icd; + dev_dbg(icd->pdev, "camera device open\n"); + + return 0; + + /* + * All errors are entered with the .host_lock held, first four also + * with use_count == 1 + */ +einitvb: +esfmt: + pm_runtime_disable(&icd->vdev->dev); +eresume: + __soc_camera_power_off(icd); +epower: + soc_camera_remove_device(icd); +eiciadd: + icd->use_count--; + mutex_unlock(&ici->host_lock); +elockhost: +econtrol: + module_put(ici->ops->owner); + + return ret; +} + +static int soc_camera_close(struct file *file) +{ + struct soc_camera_device *icd = file->private_data; + struct soc_camera_host *ici = to_soc_camera_host(icd->parent); + + mutex_lock(&ici->host_lock); + if (icd->streamer == file) { + if (ici->ops->init_videobuf2) + vb2_queue_release(&icd->vb2_vidq); + icd->streamer = NULL; + } + icd->use_count--; + if (!icd->use_count) { + pm_runtime_suspend(&icd->vdev->dev); + pm_runtime_disable(&icd->vdev->dev); + + __soc_camera_power_off(icd); + + soc_camera_remove_device(icd); + } + + mutex_unlock(&ici->host_lock); + + module_put(ici->ops->owner); + + dev_dbg(icd->pdev, "camera device close\n"); + + return 0; +} + +static ssize_t soc_camera_read(struct file *file, char __user *buf, + size_t count, loff_t *ppos) +{ + struct soc_camera_device *icd = file->private_data; + struct soc_camera_host *ici = to_soc_camera_host(icd->parent); + + dev_dbg(icd->pdev, "read called, buf %p\n", buf); + + if (ici->ops->init_videobuf2 && icd->vb2_vidq.io_modes & VB2_READ) + return vb2_read(&icd->vb2_vidq, buf, count, ppos, + file->f_flags & O_NONBLOCK); + + dev_err(icd->pdev, "camera device read not implemented\n"); + + return -EINVAL; +} + +static int soc_camera_mmap(struct file *file, struct vm_area_struct *vma) +{ + struct soc_camera_device *icd = file->private_data; + struct soc_camera_host *ici = to_soc_camera_host(icd->parent); + int err; + + dev_dbg(icd->pdev, "mmap called, vma=%p\n", vma); + + if (icd->streamer != file) + return -EBUSY; + + if (mutex_lock_interruptible(&ici->host_lock)) + return -ERESTARTSYS; + err = vb2_mmap(&icd->vb2_vidq, vma); + mutex_unlock(&ici->host_lock); + + dev_dbg(icd->pdev, "vma start=0x%08lx, size=%ld, ret=%d\n", + (unsigned long)vma->vm_start, + (unsigned long)vma->vm_end - (unsigned long)vma->vm_start, + err); + + return err; +} + +static __poll_t soc_camera_poll(struct file *file, poll_table *pt) +{ + struct soc_camera_device *icd = file->private_data; + struct soc_camera_host *ici = to_soc_camera_host(icd->parent); + __poll_t res = EPOLLERR; + + if (icd->streamer != file) + return EPOLLERR; + + mutex_lock(&ici->host_lock); + res = ici->ops->poll(file, pt); + mutex_unlock(&ici->host_lock); + return res; +} + +static const struct v4l2_file_operations soc_camera_fops = { + .owner = THIS_MODULE, + .open = soc_camera_open, + .release = soc_camera_close, + .unlocked_ioctl = video_ioctl2, + .read = soc_camera_read, + .mmap = soc_camera_mmap, + .poll = soc_camera_poll, +}; + +static int soc_camera_s_fmt_vid_cap(struct file *file, void *priv, + struct v4l2_format *f) +{ + struct soc_camera_device *icd = file->private_data; + int ret; + + WARN_ON(priv != file->private_data); + + if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { + dev_warn(icd->pdev, "Wrong buf-type %d\n", f->type); + return -EINVAL; + } + + if (icd->streamer && icd->streamer != file) + return -EBUSY; + + if (vb2_is_streaming(&icd->vb2_vidq)) { + dev_err(icd->pdev, "S_FMT denied: queue initialised\n"); + return -EBUSY; + } + + ret = soc_camera_set_fmt(icd, f); + + if (!ret && !icd->streamer) + icd->streamer = file; + + return ret; +} + +static int soc_camera_enum_fmt_vid_cap(struct file *file, void *priv, + struct v4l2_fmtdesc *f) +{ + struct soc_camera_device *icd = file->private_data; + const struct soc_mbus_pixelfmt *format; + + WARN_ON(priv != file->private_data); + + if (f->index >= icd->num_user_formats) + return -EINVAL; + + format = icd->user_formats[f->index].host_fmt; + + if (format->name) + strscpy(f->description, format->name, sizeof(f->description)); + f->pixelformat = format->fourcc; + return 0; +} + +static int soc_camera_g_fmt_vid_cap(struct file *file, void *priv, + struct v4l2_format *f) +{ + struct soc_camera_device *icd = file->private_data; + struct v4l2_pix_format *pix = &f->fmt.pix; + + WARN_ON(priv != file->private_data); + + if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + + pix->width = icd->user_width; + pix->height = icd->user_height; + pix->bytesperline = icd->bytesperline; + pix->sizeimage = icd->sizeimage; + pix->field = icd->field; + pix->pixelformat = icd->current_fmt->host_fmt->fourcc; + pix->colorspace = icd->colorspace; + dev_dbg(icd->pdev, "current_fmt->fourcc: 0x%08x\n", + icd->current_fmt->host_fmt->fourcc); + return 0; +} + +static int soc_camera_querycap(struct file *file, void *priv, + struct v4l2_capability *cap) +{ + struct soc_camera_device *icd = file->private_data; + struct soc_camera_host *ici = to_soc_camera_host(icd->parent); + + WARN_ON(priv != file->private_data); + + strscpy(cap->driver, ici->drv_name, sizeof(cap->driver)); + return ici->ops->querycap(ici, cap); +} + +static int soc_camera_streamon(struct file *file, void *priv, + enum v4l2_buf_type i) +{ + struct soc_camera_device *icd = file->private_data; + struct v4l2_subdev *sd = soc_camera_to_subdev(icd); + int ret; + + WARN_ON(priv != file->private_data); + + if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + + if (icd->streamer != file) + return -EBUSY; + + /* This calls buf_queue from host driver's videobuf2_queue_ops */ + ret = vb2_streamon(&icd->vb2_vidq, i); + if (!ret) + v4l2_subdev_call(sd, video, s_stream, 1); + + return ret; +} + +static int soc_camera_streamoff(struct file *file, void *priv, + enum v4l2_buf_type i) +{ + struct soc_camera_device *icd = file->private_data; + struct v4l2_subdev *sd = soc_camera_to_subdev(icd); + int ret; + + WARN_ON(priv != file->private_data); + + if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + + if (icd->streamer != file) + return -EBUSY; + + /* + * This calls buf_release from host driver's videobuf2_queue_ops for all + * remaining buffers. When the last buffer is freed, stop capture + */ + ret = vb2_streamoff(&icd->vb2_vidq, i); + + v4l2_subdev_call(sd, video, s_stream, 0); + + return ret; +} + +static int soc_camera_g_selection(struct file *file, void *fh, + struct v4l2_selection *s) +{ + struct soc_camera_device *icd = file->private_data; + struct soc_camera_host *ici = to_soc_camera_host(icd->parent); + + /* With a wrong type no need to try to fall back to cropping */ + if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + + return ici->ops->get_selection(icd, s); +} + +static int soc_camera_s_selection(struct file *file, void *fh, + struct v4l2_selection *s) +{ + struct soc_camera_device *icd = file->private_data; + struct soc_camera_host *ici = to_soc_camera_host(icd->parent); + int ret; + + /* In all these cases cropping emulation will not help */ + if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || + (s->target != V4L2_SEL_TGT_COMPOSE && + s->target != V4L2_SEL_TGT_CROP)) + return -EINVAL; + + if (s->target == V4L2_SEL_TGT_COMPOSE) { + /* No output size change during a running capture! */ + if (vb2_is_streaming(&icd->vb2_vidq) && + (icd->user_width != s->r.width || + icd->user_height != s->r.height)) + return -EBUSY; + + /* + * Only one user is allowed to change the output format, touch + * buffers, start / stop streaming, poll for data + */ + if (icd->streamer && icd->streamer != file) + return -EBUSY; + } + + if (s->target == V4L2_SEL_TGT_CROP && + vb2_is_streaming(&icd->vb2_vidq) && + ici->ops->set_liveselection) + ret = ici->ops->set_liveselection(icd, s); + else + ret = ici->ops->set_selection(icd, s); + if (!ret && + s->target == V4L2_SEL_TGT_COMPOSE) { + icd->user_width = s->r.width; + icd->user_height = s->r.height; + if (!icd->streamer) + icd->streamer = file; + } + + return ret; +} + +static int soc_camera_g_parm(struct file *file, void *fh, + struct v4l2_streamparm *a) +{ + struct soc_camera_device *icd = file->private_data; + struct soc_camera_host *ici = to_soc_camera_host(icd->parent); + + if (ici->ops->get_parm) + return ici->ops->get_parm(icd, a); + + return -ENOIOCTLCMD; +} + +static int soc_camera_s_parm(struct file *file, void *fh, + struct v4l2_streamparm *a) +{ + struct soc_camera_device *icd = file->private_data; + struct soc_camera_host *ici = to_soc_camera_host(icd->parent); + + if (ici->ops->set_parm) + return ici->ops->set_parm(icd, a); + + return -ENOIOCTLCMD; +} + +static int soc_camera_probe(struct soc_camera_host *ici, + struct soc_camera_device *icd); + +/* So far this function cannot fail */ +static void scan_add_host(struct soc_camera_host *ici) +{ + struct soc_camera_device *icd; + + mutex_lock(&list_lock); + + list_for_each_entry(icd, &devices, list) + if (icd->iface == ici->nr) { + struct soc_camera_desc *sdesc = to_soc_camera_desc(icd); + struct soc_camera_subdev_desc *ssdd = &sdesc->subdev_desc; + + /* The camera could have been already on, try to reset */ + if (ssdd->reset) + if (icd->control) + ssdd->reset(icd->control); + + icd->parent = ici->v4l2_dev.dev; + + /* Ignore errors */ + soc_camera_probe(ici, icd); + } + + mutex_unlock(&list_lock); +} + +/* + * It is invalid to call v4l2_clk_enable() after a successful probing + * asynchronously outside of V4L2 operations, i.e. with .host_lock not held. + */ +static int soc_camera_clk_enable(struct v4l2_clk *clk) +{ + struct soc_camera_device *icd = clk->priv; + struct soc_camera_host *ici; + + if (!icd || !icd->parent) + return -ENODEV; + + ici = to_soc_camera_host(icd->parent); + + if (!try_module_get(ici->ops->owner)) + return -ENODEV; + + /* + * If a different client is currently being probed, the host will tell + * you to go + */ + return soc_camera_clock_start(ici); +} + +static void soc_camera_clk_disable(struct v4l2_clk *clk) +{ + struct soc_camera_device *icd = clk->priv; + struct soc_camera_host *ici; + + if (!icd || !icd->parent) + return; + + ici = to_soc_camera_host(icd->parent); + + soc_camera_clock_stop(ici); + + module_put(ici->ops->owner); +} + +/* + * Eventually, it would be more logical to make the respective host the clock + * owner, but then we would have to copy this struct for each ici. Besides, it + * would introduce the circular dependency problem, unless we port all client + * drivers to release the clock, when not in use. + */ +static const struct v4l2_clk_ops soc_camera_clk_ops = { + .owner = THIS_MODULE, + .enable = soc_camera_clk_enable, + .disable = soc_camera_clk_disable, +}; + +static int soc_camera_dyn_pdev(struct soc_camera_desc *sdesc, + struct soc_camera_async_client *sasc) +{ + struct platform_device *pdev; + int ret, i; + + mutex_lock(&list_lock); + i = find_first_zero_bit(device_map, MAP_MAX_NUM); + if (i < MAP_MAX_NUM) + set_bit(i, device_map); + mutex_unlock(&list_lock); + if (i >= MAP_MAX_NUM) + return -ENOMEM; + + pdev = platform_device_alloc("soc-camera-pdrv", i); + if (!pdev) + return -ENOMEM; + + ret = platform_device_add_data(pdev, sdesc, sizeof(*sdesc)); + if (ret < 0) { + platform_device_put(pdev); + return ret; + } + + sasc->pdev = pdev; + + return 0; +} + +static struct soc_camera_device *soc_camera_add_pdev(struct soc_camera_async_client *sasc) +{ + struct platform_device *pdev = sasc->pdev; + int ret; + + ret = platform_device_add(pdev); + if (ret < 0 || !pdev->dev.driver) + return NULL; + + return platform_get_drvdata(pdev); +} + +/* Locking: called with .host_lock held */ +static int soc_camera_probe_finish(struct soc_camera_device *icd) +{ + struct v4l2_subdev *sd = soc_camera_to_subdev(icd); + struct v4l2_subdev_format fmt = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + }; + struct v4l2_mbus_framefmt *mf = &fmt.format; + int ret; + + sd->grp_id = soc_camera_grp_id(icd); + v4l2_set_subdev_hostdata(sd, icd); + + v4l2_subdev_call(sd, video, g_tvnorms, &icd->vdev->tvnorms); + + ret = v4l2_ctrl_add_handler(&icd->ctrl_handler, sd->ctrl_handler, + NULL, true); + if (ret < 0) + return ret; + + ret = soc_camera_add_device(icd); + if (ret < 0) { + dev_err(icd->pdev, "Couldn't activate the camera: %d\n", ret); + return ret; + } + + /* At this point client .probe() should have run already */ + ret = soc_camera_init_user_formats(icd); + if (ret < 0) + goto eusrfmt; + + icd->field = V4L2_FIELD_ANY; + + ret = soc_camera_video_start(icd); + if (ret < 0) + goto evidstart; + + /* Try to improve our guess of a reasonable window format */ + if (!v4l2_subdev_call(sd, pad, get_fmt, NULL, &fmt)) { + icd->user_width = mf->width; + icd->user_height = mf->height; + icd->colorspace = mf->colorspace; + icd->field = mf->field; + } + soc_camera_remove_device(icd); + + return 0; + +evidstart: + soc_camera_free_user_formats(icd); +eusrfmt: + soc_camera_remove_device(icd); + + return ret; +} + +#ifdef CONFIG_I2C_BOARDINFO +static int soc_camera_i2c_init(struct soc_camera_device *icd, + struct soc_camera_desc *sdesc) +{ + struct soc_camera_subdev_desc *ssdd; + struct i2c_client *client; + struct soc_camera_host *ici; + struct soc_camera_host_desc *shd = &sdesc->host_desc; + struct i2c_adapter *adap; + struct v4l2_subdev *subdev; + char clk_name[V4L2_CLK_NAME_SIZE]; + int ret; + + /* First find out how we link the main client */ + if (icd->sasc) { + /* Async non-OF probing handled by the subdevice list */ + return -EPROBE_DEFER; + } + + ici = to_soc_camera_host(icd->parent); + adap = i2c_get_adapter(shd->i2c_adapter_id); + if (!adap) { + dev_err(icd->pdev, "Cannot get I2C adapter #%d. No driver?\n", + shd->i2c_adapter_id); + return -ENODEV; + } + + ssdd = kmemdup(&sdesc->subdev_desc, sizeof(*ssdd), GFP_KERNEL); + if (!ssdd) { + ret = -ENOMEM; + goto ealloc; + } + /* + * In synchronous case we request regulators ourselves in + * soc_camera_pdrv_probe(), make sure the subdevice driver doesn't try + * to allocate them again. + */ + ssdd->sd_pdata.num_regulators = 0; + ssdd->sd_pdata.regulators = NULL; + shd->board_info->platform_data = ssdd; + + v4l2_clk_name_i2c(clk_name, sizeof(clk_name), + shd->i2c_adapter_id, shd->board_info->addr); + + icd->clk = v4l2_clk_register(&soc_camera_clk_ops, clk_name, icd); + if (IS_ERR(icd->clk)) { + ret = PTR_ERR(icd->clk); + goto eclkreg; + } + + subdev = v4l2_i2c_new_subdev_board(&ici->v4l2_dev, adap, + shd->board_info, NULL); + if (!subdev) { + ret = -ENODEV; + goto ei2cnd; + } + + client = v4l2_get_subdevdata(subdev); + + /* Use to_i2c_client(dev) to recover the i2c client */ + icd->control = &client->dev; + + return 0; +ei2cnd: + v4l2_clk_unregister(icd->clk); + icd->clk = NULL; +eclkreg: + kfree(ssdd); +ealloc: + i2c_put_adapter(adap); + return ret; +} + +static void soc_camera_i2c_free(struct soc_camera_device *icd) +{ + struct i2c_client *client = + to_i2c_client(to_soc_camera_control(icd)); + struct i2c_adapter *adap; + struct soc_camera_subdev_desc *ssdd; + + icd->control = NULL; + if (icd->sasc) + return; + + adap = client->adapter; + ssdd = client->dev.platform_data; + v4l2_device_unregister_subdev(i2c_get_clientdata(client)); + i2c_unregister_device(client); + i2c_put_adapter(adap); + kfree(ssdd); + v4l2_clk_unregister(icd->clk); + icd->clk = NULL; +} + +/* + * V4L2 asynchronous notifier callbacks. They are all called under a v4l2-async + * internal global mutex, therefore cannot race against other asynchronous + * events. Until notifier->complete() (soc_camera_async_complete()) is called, + * the video device node is not registered and no V4L fops can occur. Unloading + * of the host driver also calls a v4l2-async function, so also there we're + * protected. + */ +static int soc_camera_async_bound(struct v4l2_async_notifier *notifier, + struct v4l2_subdev *sd, + struct v4l2_async_subdev *asd) +{ + struct soc_camera_async_client *sasc = container_of(notifier, + struct soc_camera_async_client, notifier); + struct soc_camera_device *icd = platform_get_drvdata(sasc->pdev); + + if (asd == sasc->sensor && !WARN_ON(icd->control)) { + struct i2c_client *client = v4l2_get_subdevdata(sd); + + /* + * Only now we get subdevice-specific information like + * regulators, flags, callbacks, etc. + */ + if (client) { + struct soc_camera_desc *sdesc = to_soc_camera_desc(icd); + struct soc_camera_subdev_desc *ssdd = + soc_camera_i2c_to_desc(client); + if (ssdd) { + memcpy(&sdesc->subdev_desc, ssdd, + sizeof(sdesc->subdev_desc)); + if (ssdd->reset) + ssdd->reset(&client->dev); + } + + icd->control = &client->dev; + } + } + + return 0; +} + +static void soc_camera_async_unbind(struct v4l2_async_notifier *notifier, + struct v4l2_subdev *sd, + struct v4l2_async_subdev *asd) +{ + struct soc_camera_async_client *sasc = container_of(notifier, + struct soc_camera_async_client, notifier); + struct soc_camera_device *icd = platform_get_drvdata(sasc->pdev); + + icd->control = NULL; + + if (icd->clk) { + v4l2_clk_unregister(icd->clk); + icd->clk = NULL; + } +} + +static int soc_camera_async_complete(struct v4l2_async_notifier *notifier) +{ + struct soc_camera_async_client *sasc = container_of(notifier, + struct soc_camera_async_client, notifier); + struct soc_camera_device *icd = platform_get_drvdata(sasc->pdev); + + if (to_soc_camera_control(icd)) { + struct soc_camera_host *ici = to_soc_camera_host(icd->parent); + int ret; + + mutex_lock(&list_lock); + ret = soc_camera_probe(ici, icd); + mutex_unlock(&list_lock); + if (ret < 0) + return ret; + } + + return 0; +} + +static const struct v4l2_async_notifier_operations soc_camera_async_ops = { + .bound = soc_camera_async_bound, + .unbind = soc_camera_async_unbind, + .complete = soc_camera_async_complete, +}; + +static int scan_async_group(struct soc_camera_host *ici, + struct v4l2_async_subdev **asd, unsigned int size) +{ + struct soc_camera_async_subdev *sasd; + struct soc_camera_async_client *sasc; + struct soc_camera_device *icd; + struct soc_camera_desc sdesc = {.host_desc.bus_id = ici->nr,}; + char clk_name[V4L2_CLK_NAME_SIZE]; + unsigned int i; + int ret; + + /* First look for a sensor */ + for (i = 0; i < size; i++) { + sasd = container_of(asd[i], struct soc_camera_async_subdev, asd); + if (sasd->role == SOCAM_SUBDEV_DATA_SOURCE) + break; + } + + if (i >= size || asd[i]->match_type != V4L2_ASYNC_MATCH_I2C) { + /* All useless */ + dev_err(ici->v4l2_dev.dev, "No I2C data source found!\n"); + return -ENODEV; + } + + /* Or shall this be managed by the soc-camera device? */ + sasc = devm_kzalloc(ici->v4l2_dev.dev, sizeof(*sasc), GFP_KERNEL); + if (!sasc) + return -ENOMEM; + + /* HACK: just need a != NULL */ + sdesc.host_desc.board_info = ERR_PTR(-ENODATA); + + ret = soc_camera_dyn_pdev(&sdesc, sasc); + if (ret < 0) + goto eallocpdev; + + sasc->sensor = &sasd->asd; + + icd = soc_camera_add_pdev(sasc); + if (!icd) { + ret = -ENOMEM; + goto eaddpdev; + } + + v4l2_async_notifier_init(&sasc->notifier); + + for (i = 0; i < size; i++) { + ret = v4l2_async_notifier_add_subdev(&sasc->notifier, asd[i]); + if (ret) + goto eaddasd; + } + + sasc->notifier.ops = &soc_camera_async_ops; + + icd->sasc = sasc; + icd->parent = ici->v4l2_dev.dev; + + v4l2_clk_name_i2c(clk_name, sizeof(clk_name), + sasd->asd.match.i2c.adapter_id, + sasd->asd.match.i2c.address); + + icd->clk = v4l2_clk_register(&soc_camera_clk_ops, clk_name, icd); + if (IS_ERR(icd->clk)) { + ret = PTR_ERR(icd->clk); + goto eclkreg; + } + + ret = v4l2_async_notifier_register(&ici->v4l2_dev, &sasc->notifier); + if (!ret) + return 0; + + v4l2_clk_unregister(icd->clk); +eclkreg: + icd->clk = NULL; +eaddasd: + v4l2_async_notifier_cleanup(&sasc->notifier); + platform_device_del(sasc->pdev); +eaddpdev: + platform_device_put(sasc->pdev); +eallocpdev: + devm_kfree(ici->v4l2_dev.dev, sasc); + dev_err(ici->v4l2_dev.dev, "group probe failed: %d\n", ret); + + return ret; +} + +static void scan_async_host(struct soc_camera_host *ici) +{ + struct v4l2_async_subdev **asd; + int j; + + for (j = 0, asd = ici->asd; ici->asd_sizes[j]; j++) { + scan_async_group(ici, asd, ici->asd_sizes[j]); + asd += ici->asd_sizes[j]; + } +} +#else +#define soc_camera_i2c_init(icd, sdesc) (-ENODEV) +#define soc_camera_i2c_free(icd) do {} while (0) +#define scan_async_host(ici) do {} while (0) +#endif + +#ifdef CONFIG_OF + +struct soc_of_info { + struct soc_camera_async_subdev sasd; + struct soc_camera_async_client sasc; + struct v4l2_async_subdev *subdev; +}; + +static int soc_of_bind(struct soc_camera_host *ici, + struct device_node *ep, + struct device_node *remote) +{ + struct soc_camera_device *icd; + struct soc_camera_desc sdesc = {.host_desc.bus_id = ici->nr,}; + struct soc_camera_async_client *sasc; + struct soc_of_info *info; + struct i2c_client *client; + char clk_name[V4L2_CLK_NAME_SIZE]; + int ret; + + /* allocate a new subdev and add match info to it */ + info = devm_kzalloc(ici->v4l2_dev.dev, sizeof(struct soc_of_info), + GFP_KERNEL); + if (!info) + return -ENOMEM; + + info->sasd.asd.match.fwnode = of_fwnode_handle(remote); + info->sasd.asd.match_type = V4L2_ASYNC_MATCH_FWNODE; + info->subdev = &info->sasd.asd; + + /* Or shall this be managed by the soc-camera device? */ + sasc = &info->sasc; + + /* HACK: just need a != NULL */ + sdesc.host_desc.board_info = ERR_PTR(-ENODATA); + + ret = soc_camera_dyn_pdev(&sdesc, sasc); + if (ret < 0) + goto eallocpdev; + + sasc->sensor = &info->sasd.asd; + + icd = soc_camera_add_pdev(sasc); + if (!icd) { + ret = -ENOMEM; + goto eaddpdev; + } + + v4l2_async_notifier_init(&sasc->notifier); + + ret = v4l2_async_notifier_add_subdev(&sasc->notifier, info->subdev); + if (ret) { + of_node_put(remote); + goto eaddasd; + } + + sasc->notifier.ops = &soc_camera_async_ops; + + icd->sasc = sasc; + icd->parent = ici->v4l2_dev.dev; + + client = of_find_i2c_device_by_node(remote); + + if (client) + v4l2_clk_name_i2c(clk_name, sizeof(clk_name), + client->adapter->nr, client->addr); + else + v4l2_clk_name_of(clk_name, sizeof(clk_name), remote); + + icd->clk = v4l2_clk_register(&soc_camera_clk_ops, clk_name, icd); + if (IS_ERR(icd->clk)) { + ret = PTR_ERR(icd->clk); + goto eclkreg; + } + + ret = v4l2_async_notifier_register(&ici->v4l2_dev, &sasc->notifier); + if (!ret) + return 0; + + v4l2_clk_unregister(icd->clk); +eclkreg: + icd->clk = NULL; +eaddasd: + v4l2_async_notifier_cleanup(&sasc->notifier); + platform_device_del(sasc->pdev); +eaddpdev: + platform_device_put(sasc->pdev); +eallocpdev: + devm_kfree(ici->v4l2_dev.dev, info); + dev_err(ici->v4l2_dev.dev, "group probe failed: %d\n", ret); + + return ret; +} + +static void scan_of_host(struct soc_camera_host *ici) +{ + struct device *dev = ici->v4l2_dev.dev; + struct device_node *np = dev->of_node; + struct device_node *epn = NULL, *rem; + unsigned int i; + + for (i = 0; ; i++) { + epn = of_graph_get_next_endpoint(np, epn); + if (!epn) + break; + + rem = of_graph_get_remote_port_parent(epn); + if (!rem) { + dev_notice(dev, "no remote for %pOF\n", epn); + continue; + } + + /* so we now have a remote node to connect */ + if (!i) + soc_of_bind(ici, epn, rem); + + if (i) { + dev_err(dev, "multiple subdevices aren't supported yet!\n"); + break; + } + } + + of_node_put(epn); +} + +#else +static inline void scan_of_host(struct soc_camera_host *ici) { } +#endif + +/* Called during host-driver probe */ +static int soc_camera_probe(struct soc_camera_host *ici, + struct soc_camera_device *icd) +{ + struct soc_camera_desc *sdesc = to_soc_camera_desc(icd); + struct soc_camera_host_desc *shd = &sdesc->host_desc; + struct device *control = NULL; + int ret; + + dev_info(icd->pdev, "Probing %s\n", dev_name(icd->pdev)); + + /* + * Currently the subdev with the largest number of controls (13) is + * ov6550. So let's pick 16 as a hint for the control handler. Note + * that this is a hint only: too large and you waste some memory, too + * small and there is a (very) small performance hit when looking up + * controls in the internal hash. + */ + ret = v4l2_ctrl_handler_init(&icd->ctrl_handler, 16); + if (ret < 0) + return ret; + + /* Must have icd->vdev before registering the device */ + ret = video_dev_create(icd); + if (ret < 0) + goto evdc; + + /* + * ..._video_start() will create a device node, video_register_device() + * itself is protected against concurrent open() calls, but we also have + * to protect our data also during client probing. + */ + + /* Non-i2c cameras, e.g., soc_camera_platform, have no board_info */ + if (shd->board_info) { + ret = soc_camera_i2c_init(icd, sdesc); + if (ret < 0 && ret != -EPROBE_DEFER) + goto eadd; + } else if (!shd->add_device || !shd->del_device) { + ret = -EINVAL; + goto eadd; + } else { + ret = soc_camera_clock_start(ici); + if (ret < 0) + goto eadd; + + if (shd->module_name) + ret = request_module(shd->module_name); + + ret = shd->add_device(icd); + if (ret < 0) + goto eadddev; + + /* + * FIXME: this is racy, have to use driver-binding notification, + * when it is available + */ + control = to_soc_camera_control(icd); + if (!control || !control->driver || !dev_get_drvdata(control) || + !try_module_get(control->driver->owner)) { + shd->del_device(icd); + ret = -ENODEV; + goto enodrv; + } + } + + mutex_lock(&ici->host_lock); + ret = soc_camera_probe_finish(icd); + mutex_unlock(&ici->host_lock); + if (ret < 0) + goto efinish; + + return 0; + +efinish: + if (shd->board_info) { + soc_camera_i2c_free(icd); + } else { + shd->del_device(icd); + module_put(control->driver->owner); +enodrv: +eadddev: + soc_camera_clock_stop(ici); + } +eadd: + if (icd->vdev) { + video_device_release(icd->vdev); + icd->vdev = NULL; + } +evdc: + v4l2_ctrl_handler_free(&icd->ctrl_handler); + return ret; +} + +/* + * This is called on device_unregister, which only means we have to disconnect + * from the host, but not remove ourselves from the device list. With + * asynchronous client probing this can also be called without + * soc_camera_probe_finish() having run. Careful with clean up. + */ +static int soc_camera_remove(struct soc_camera_device *icd) +{ + struct soc_camera_desc *sdesc = to_soc_camera_desc(icd); + struct video_device *vdev = icd->vdev; + + v4l2_ctrl_handler_free(&icd->ctrl_handler); + if (vdev) { + video_unregister_device(vdev); + icd->vdev = NULL; + } + + if (sdesc->host_desc.board_info) { + soc_camera_i2c_free(icd); + } else { + struct device *dev = to_soc_camera_control(icd); + struct device_driver *drv = dev ? dev->driver : NULL; + if (drv) { + sdesc->host_desc.del_device(icd); + module_put(drv->owner); + } + } + + if (icd->num_user_formats) + soc_camera_free_user_formats(icd); + + if (icd->clk) { + /* For the synchronous case */ + v4l2_clk_unregister(icd->clk); + icd->clk = NULL; + } + + if (icd->sasc) + platform_device_unregister(icd->sasc->pdev); + + return 0; +} + +static int default_g_selection(struct soc_camera_device *icd, + struct v4l2_selection *sel) +{ + struct v4l2_subdev *sd = soc_camera_to_subdev(icd); + struct v4l2_subdev_selection sdsel = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + .target = sel->target, + }; + int ret; + + ret = v4l2_subdev_call(sd, pad, get_selection, NULL, &sdsel); + if (ret) + return ret; + sel->r = sdsel.r; + return 0; +} + +static int default_s_selection(struct soc_camera_device *icd, + struct v4l2_selection *sel) +{ + struct v4l2_subdev *sd = soc_camera_to_subdev(icd); + struct v4l2_subdev_selection sdsel = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + .target = sel->target, + .flags = sel->flags, + .r = sel->r, + }; + int ret; + + ret = v4l2_subdev_call(sd, pad, set_selection, NULL, &sdsel); + if (ret) + return ret; + sel->r = sdsel.r; + return 0; +} + +static int default_g_parm(struct soc_camera_device *icd, + struct v4l2_streamparm *a) +{ + struct v4l2_subdev *sd = soc_camera_to_subdev(icd); + + return v4l2_g_parm_cap(icd->vdev, sd, a); +} + +static int default_s_parm(struct soc_camera_device *icd, + struct v4l2_streamparm *a) +{ + struct v4l2_subdev *sd = soc_camera_to_subdev(icd); + + return v4l2_s_parm_cap(icd->vdev, sd, a); +} + +static int default_enum_framesizes(struct soc_camera_device *icd, + struct v4l2_frmsizeenum *fsize) +{ + int ret; + struct v4l2_subdev *sd = soc_camera_to_subdev(icd); + const struct soc_camera_format_xlate *xlate; + struct v4l2_subdev_frame_size_enum fse = { + .index = fsize->index, + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + }; + + xlate = soc_camera_xlate_by_fourcc(icd, fsize->pixel_format); + if (!xlate) + return -EINVAL; + fse.code = xlate->code; + + ret = v4l2_subdev_call(sd, pad, enum_frame_size, NULL, &fse); + if (ret < 0) + return ret; + + if (fse.min_width == fse.max_width && + fse.min_height == fse.max_height) { + fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; + fsize->discrete.width = fse.min_width; + fsize->discrete.height = fse.min_height; + return 0; + } + fsize->type = V4L2_FRMSIZE_TYPE_CONTINUOUS; + fsize->stepwise.min_width = fse.min_width; + fsize->stepwise.max_width = fse.max_width; + fsize->stepwise.min_height = fse.min_height; + fsize->stepwise.max_height = fse.max_height; + fsize->stepwise.step_width = 1; + fsize->stepwise.step_height = 1; + return 0; +} + +int soc_camera_host_register(struct soc_camera_host *ici) +{ + struct soc_camera_host *ix; + int ret; + + if (!ici || !ici->ops || + !ici->ops->try_fmt || + !ici->ops->set_fmt || + !ici->ops->set_bus_param || + !ici->ops->querycap || + !ici->ops->init_videobuf2 || + !ici->ops->poll || + !ici->v4l2_dev.dev) + return -EINVAL; + + if (!ici->ops->set_selection) + ici->ops->set_selection = default_s_selection; + if (!ici->ops->get_selection) + ici->ops->get_selection = default_g_selection; + if (!ici->ops->set_parm) + ici->ops->set_parm = default_s_parm; + if (!ici->ops->get_parm) + ici->ops->get_parm = default_g_parm; + if (!ici->ops->enum_framesizes) + ici->ops->enum_framesizes = default_enum_framesizes; + + mutex_lock(&list_lock); + list_for_each_entry(ix, &hosts, list) { + if (ix->nr == ici->nr) { + ret = -EBUSY; + goto edevreg; + } + } + + ret = v4l2_device_register(ici->v4l2_dev.dev, &ici->v4l2_dev); + if (ret < 0) + goto edevreg; + + list_add_tail(&ici->list, &hosts); + mutex_unlock(&list_lock); + + mutex_init(&ici->host_lock); + mutex_init(&ici->clk_lock); + + if (ici->v4l2_dev.dev->of_node) + scan_of_host(ici); + else if (ici->asd_sizes) + /* + * No OF, host with a list of subdevices. Don't try to mix + * modes by initialising some groups statically and some + * dynamically! + */ + scan_async_host(ici); + else + /* Legacy: static platform devices from board data */ + scan_add_host(ici); + + return 0; + +edevreg: + mutex_unlock(&list_lock); + return ret; +} +EXPORT_SYMBOL(soc_camera_host_register); + +/* Unregister all clients! */ +void soc_camera_host_unregister(struct soc_camera_host *ici) +{ + struct soc_camera_device *icd, *tmp; + struct soc_camera_async_client *sasc; + LIST_HEAD(notifiers); + + mutex_lock(&list_lock); + list_del(&ici->list); + list_for_each_entry(icd, &devices, list) + if (icd->iface == ici->nr && icd->sasc) { + /* as long as we hold the device, sasc won't be freed */ + get_device(icd->pdev); + list_add(&icd->sasc->list, ¬ifiers); + } + mutex_unlock(&list_lock); + + list_for_each_entry(sasc, ¬ifiers, list) { + /* Must call unlocked to avoid AB-BA dead-lock */ + v4l2_async_notifier_unregister(&sasc->notifier); + v4l2_async_notifier_cleanup(&sasc->notifier); + put_device(&sasc->pdev->dev); + } + + mutex_lock(&list_lock); + + list_for_each_entry_safe(icd, tmp, &devices, list) + if (icd->iface == ici->nr) + soc_camera_remove(icd); + + mutex_unlock(&list_lock); + + v4l2_device_unregister(&ici->v4l2_dev); +} +EXPORT_SYMBOL(soc_camera_host_unregister); + +/* Image capture device */ +static int soc_camera_device_register(struct soc_camera_device *icd) +{ + struct soc_camera_device *ix; + int num = -1, i; + + mutex_lock(&list_lock); + for (i = 0; i < 256 && num < 0; i++) { + num = i; + /* Check if this index is available on this interface */ + list_for_each_entry(ix, &devices, list) { + if (ix->iface == icd->iface && ix->devnum == i) { + num = -1; + break; + } + } + } + + if (num < 0) { + /* + * ok, we have 256 cameras on this host... + * man, stay reasonable... + */ + mutex_unlock(&list_lock); + return -ENOMEM; + } + + icd->devnum = num; + icd->use_count = 0; + icd->host_priv = NULL; + + /* + * Dynamically allocated devices set the bit earlier, but it doesn't hurt setting + * it again + */ + i = to_platform_device(icd->pdev)->id; + if (i < 0) + /* One static (legacy) soc-camera platform device */ + i = 0; + if (i >= MAP_MAX_NUM) { + mutex_unlock(&list_lock); + return -EBUSY; + } + set_bit(i, device_map); + list_add_tail(&icd->list, &devices); + mutex_unlock(&list_lock); + + return 0; +} + +static const struct v4l2_ioctl_ops soc_camera_ioctl_ops = { + .vidioc_querycap = soc_camera_querycap, + .vidioc_try_fmt_vid_cap = soc_camera_try_fmt_vid_cap, + .vidioc_g_fmt_vid_cap = soc_camera_g_fmt_vid_cap, + .vidioc_s_fmt_vid_cap = soc_camera_s_fmt_vid_cap, + .vidioc_enum_fmt_vid_cap = soc_camera_enum_fmt_vid_cap, + .vidioc_enum_input = soc_camera_enum_input, + .vidioc_g_input = soc_camera_g_input, + .vidioc_s_input = soc_camera_s_input, + .vidioc_s_std = soc_camera_s_std, + .vidioc_g_std = soc_camera_g_std, + .vidioc_enum_framesizes = soc_camera_enum_framesizes, + .vidioc_reqbufs = soc_camera_reqbufs, + .vidioc_querybuf = soc_camera_querybuf, + .vidioc_qbuf = soc_camera_qbuf, + .vidioc_dqbuf = soc_camera_dqbuf, + .vidioc_create_bufs = soc_camera_create_bufs, + .vidioc_prepare_buf = soc_camera_prepare_buf, + .vidioc_expbuf = soc_camera_expbuf, + .vidioc_streamon = soc_camera_streamon, + .vidioc_streamoff = soc_camera_streamoff, + .vidioc_g_selection = soc_camera_g_selection, + .vidioc_s_selection = soc_camera_s_selection, + .vidioc_g_parm = soc_camera_g_parm, + .vidioc_s_parm = soc_camera_s_parm, +}; + +static int video_dev_create(struct soc_camera_device *icd) +{ + struct soc_camera_host *ici = to_soc_camera_host(icd->parent); + struct video_device *vdev = video_device_alloc(); + + if (!vdev) + return -ENOMEM; + + strscpy(vdev->name, ici->drv_name, sizeof(vdev->name)); + + vdev->v4l2_dev = &ici->v4l2_dev; + vdev->fops = &soc_camera_fops; + vdev->ioctl_ops = &soc_camera_ioctl_ops; + vdev->release = video_device_release; + vdev->ctrl_handler = &icd->ctrl_handler; + vdev->lock = &ici->host_lock; + + icd->vdev = vdev; + + return 0; +} + +/* + * Called from soc_camera_probe() above with .host_lock held + */ +static int soc_camera_video_start(struct soc_camera_device *icd) +{ + const struct device_type *type = icd->vdev->dev.type; + int ret; + + if (!icd->parent) + return -ENODEV; + + video_set_drvdata(icd->vdev, icd); + if (icd->vdev->tvnorms == 0) { + /* disable the STD API if there are no tvnorms defined */ + v4l2_disable_ioctl(icd->vdev, VIDIOC_G_STD); + v4l2_disable_ioctl(icd->vdev, VIDIOC_S_STD); + v4l2_disable_ioctl(icd->vdev, VIDIOC_ENUMSTD); + } + ret = video_register_device(icd->vdev, VFL_TYPE_GRABBER, -1); + if (ret < 0) { + dev_err(icd->pdev, "video_register_device failed: %d\n", ret); + return ret; + } + + /* Restore device type, possibly set by the subdevice driver */ + icd->vdev->dev.type = type; + + return 0; +} + +static int soc_camera_pdrv_probe(struct platform_device *pdev) +{ + struct soc_camera_desc *sdesc = pdev->dev.platform_data; + struct soc_camera_subdev_desc *ssdd = &sdesc->subdev_desc; + struct soc_camera_device *icd; + int ret; + + if (!sdesc) + return -EINVAL; + + icd = devm_kzalloc(&pdev->dev, sizeof(*icd), GFP_KERNEL); + if (!icd) + return -ENOMEM; + + /* + * In the asynchronous case ssdd->num_regulators == 0 yet, so, the below + * regulator allocation is a dummy. They are actually requested by the + * subdevice driver, using soc_camera_power_init(). Also note, that in + * that case regulators are attached to the I2C device and not to the + * camera platform device. + */ + ret = devm_regulator_bulk_get(&pdev->dev, ssdd->sd_pdata.num_regulators, + ssdd->sd_pdata.regulators); + if (ret < 0) + return ret; + + icd->iface = sdesc->host_desc.bus_id; + icd->sdesc = sdesc; + icd->pdev = &pdev->dev; + platform_set_drvdata(pdev, icd); + + icd->user_width = DEFAULT_WIDTH; + icd->user_height = DEFAULT_HEIGHT; + + return soc_camera_device_register(icd); +} + +/* + * Only called on rmmod for each platform device, since they are not + * hot-pluggable. Now we know, that all our users - hosts and devices have + * been unloaded already + */ +static int soc_camera_pdrv_remove(struct platform_device *pdev) +{ + struct soc_camera_device *icd = platform_get_drvdata(pdev); + int i; + + if (!icd) + return -EINVAL; + + i = pdev->id; + if (i < 0) + i = 0; + + /* + * In synchronous mode with static platform devices this is called in a + * loop from drivers/base/dd.c::driver_detach(), no parallel execution, + * no need to lock. In asynchronous case the caller - + * soc_camera_host_unregister() - already holds the lock + */ + if (test_bit(i, device_map)) { + clear_bit(i, device_map); + list_del(&icd->list); + } + + return 0; +} + +static struct platform_driver __refdata soc_camera_pdrv = { + .probe = soc_camera_pdrv_probe, + .remove = soc_camera_pdrv_remove, + .driver = { + .name = "soc-camera-pdrv", + }, +}; + +module_platform_driver(soc_camera_pdrv); + +MODULE_DESCRIPTION("Image capture bus driver"); +MODULE_AUTHOR("Guennadi Liakhovetski <kernel@pengutronix.de>"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:soc-camera-pdrv"); diff --git a/drivers/staging/media/soc_camera/soc_mediabus.c b/drivers/staging/media/soc_camera/soc_mediabus.c new file mode 100644 index 000000000000..be74008ec0ca --- /dev/null +++ b/drivers/staging/media/soc_camera/soc_mediabus.c @@ -0,0 +1,533 @@ +/* + * soc-camera media bus helper routines + * + * Copyright (C) 2009, Guennadi Liakhovetski <g.liakhovetski@gmx.de> + * + * 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. + */ + +#include <linux/kernel.h> +#include <linux/module.h> + +#include <media/v4l2-device.h> +#include <media/v4l2-mediabus.h> +#include <media/drv-intf/soc_mediabus.h> + +static const struct soc_mbus_lookup mbus_fmt[] = { +{ + .code = MEDIA_BUS_FMT_YUYV8_2X8, + .fmt = { + .fourcc = V4L2_PIX_FMT_YUYV, + .name = "YUYV", + .bits_per_sample = 8, + .packing = SOC_MBUS_PACKING_2X8_PADHI, + .order = SOC_MBUS_ORDER_LE, + .layout = SOC_MBUS_LAYOUT_PACKED, + }, +}, { + .code = MEDIA_BUS_FMT_YVYU8_2X8, + .fmt = { + .fourcc = V4L2_PIX_FMT_YVYU, + .name = "YVYU", + .bits_per_sample = 8, + .packing = SOC_MBUS_PACKING_2X8_PADHI, + .order = SOC_MBUS_ORDER_LE, + .layout = SOC_MBUS_LAYOUT_PACKED, + }, +}, { + .code = MEDIA_BUS_FMT_UYVY8_2X8, + .fmt = { + .fourcc = V4L2_PIX_FMT_UYVY, + .name = "UYVY", + .bits_per_sample = 8, + .packing = SOC_MBUS_PACKING_2X8_PADHI, + .order = SOC_MBUS_ORDER_LE, + .layout = SOC_MBUS_LAYOUT_PACKED, + }, +}, { + .code = MEDIA_BUS_FMT_VYUY8_2X8, + .fmt = { + .fourcc = V4L2_PIX_FMT_VYUY, + .name = "VYUY", + .bits_per_sample = 8, + .packing = SOC_MBUS_PACKING_2X8_PADHI, + .order = SOC_MBUS_ORDER_LE, + .layout = SOC_MBUS_LAYOUT_PACKED, + }, +}, { + .code = MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE, + .fmt = { + .fourcc = V4L2_PIX_FMT_RGB555, + .name = "RGB555", + .bits_per_sample = 8, + .packing = SOC_MBUS_PACKING_2X8_PADHI, + .order = SOC_MBUS_ORDER_LE, + .layout = SOC_MBUS_LAYOUT_PACKED, + }, +}, { + .code = MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE, + .fmt = { + .fourcc = V4L2_PIX_FMT_RGB555X, + .name = "RGB555X", + .bits_per_sample = 8, + .packing = SOC_MBUS_PACKING_2X8_PADHI, + .order = SOC_MBUS_ORDER_BE, + .layout = SOC_MBUS_LAYOUT_PACKED, + }, +}, { + .code = MEDIA_BUS_FMT_RGB565_2X8_LE, + .fmt = { + .fourcc = V4L2_PIX_FMT_RGB565, + .name = "RGB565", + .bits_per_sample = 8, + .packing = SOC_MBUS_PACKING_2X8_PADHI, + .order = SOC_MBUS_ORDER_LE, + .layout = SOC_MBUS_LAYOUT_PACKED, + }, +}, { + .code = MEDIA_BUS_FMT_RGB565_2X8_BE, + .fmt = { + .fourcc = V4L2_PIX_FMT_RGB565X, + .name = "RGB565X", + .bits_per_sample = 8, + .packing = SOC_MBUS_PACKING_2X8_PADHI, + .order = SOC_MBUS_ORDER_BE, + .layout = SOC_MBUS_LAYOUT_PACKED, + }, +}, { + .code = MEDIA_BUS_FMT_RGB666_1X18, + .fmt = { + .fourcc = V4L2_PIX_FMT_RGB32, + .name = "RGB666/32bpp", + .bits_per_sample = 18, + .packing = SOC_MBUS_PACKING_EXTEND32, + .order = SOC_MBUS_ORDER_LE, + }, +}, { + .code = MEDIA_BUS_FMT_RGB888_1X24, + .fmt = { + .fourcc = V4L2_PIX_FMT_RGB32, + .name = "RGB888/32bpp", + .bits_per_sample = 24, + .packing = SOC_MBUS_PACKING_EXTEND32, + .order = SOC_MBUS_ORDER_LE, + }, +}, { + .code = MEDIA_BUS_FMT_RGB888_2X12_BE, + .fmt = { + .fourcc = V4L2_PIX_FMT_RGB32, + .name = "RGB888/32bpp", + .bits_per_sample = 12, + .packing = SOC_MBUS_PACKING_EXTEND32, + .order = SOC_MBUS_ORDER_BE, + }, +}, { + .code = MEDIA_BUS_FMT_RGB888_2X12_LE, + .fmt = { + .fourcc = V4L2_PIX_FMT_RGB32, + .name = "RGB888/32bpp", + .bits_per_sample = 12, + .packing = SOC_MBUS_PACKING_EXTEND32, + .order = SOC_MBUS_ORDER_LE, + }, +}, { + .code = MEDIA_BUS_FMT_SBGGR8_1X8, + .fmt = { + .fourcc = V4L2_PIX_FMT_SBGGR8, + .name = "Bayer 8 BGGR", + .bits_per_sample = 8, + .packing = SOC_MBUS_PACKING_NONE, + .order = SOC_MBUS_ORDER_LE, + .layout = SOC_MBUS_LAYOUT_PACKED, + }, +}, { + .code = MEDIA_BUS_FMT_SBGGR10_1X10, + .fmt = { + .fourcc = V4L2_PIX_FMT_SBGGR10, + .name = "Bayer 10 BGGR", + .bits_per_sample = 10, + .packing = SOC_MBUS_PACKING_EXTEND16, + .order = SOC_MBUS_ORDER_LE, + .layout = SOC_MBUS_LAYOUT_PACKED, + }, +}, { + .code = MEDIA_BUS_FMT_Y8_1X8, + .fmt = { + .fourcc = V4L2_PIX_FMT_GREY, + .name = "Grey", + .bits_per_sample = 8, + .packing = SOC_MBUS_PACKING_NONE, + .order = SOC_MBUS_ORDER_LE, + .layout = SOC_MBUS_LAYOUT_PACKED, + }, +}, { + .code = MEDIA_BUS_FMT_Y10_1X10, + .fmt = { + .fourcc = V4L2_PIX_FMT_Y10, + .name = "Grey 10bit", + .bits_per_sample = 10, + .packing = SOC_MBUS_PACKING_EXTEND16, + .order = SOC_MBUS_ORDER_LE, + .layout = SOC_MBUS_LAYOUT_PACKED, + }, +}, { + .code = MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE, + .fmt = { + .fourcc = V4L2_PIX_FMT_SBGGR10, + .name = "Bayer 10 BGGR", + .bits_per_sample = 8, + .packing = SOC_MBUS_PACKING_2X8_PADHI, + .order = SOC_MBUS_ORDER_LE, + .layout = SOC_MBUS_LAYOUT_PACKED, + }, +}, { + .code = MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_LE, + .fmt = { + .fourcc = V4L2_PIX_FMT_SBGGR10, + .name = "Bayer 10 BGGR", + .bits_per_sample = 8, + .packing = SOC_MBUS_PACKING_2X8_PADLO, + .order = SOC_MBUS_ORDER_LE, + .layout = SOC_MBUS_LAYOUT_PACKED, + }, +}, { + .code = MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_BE, + .fmt = { + .fourcc = V4L2_PIX_FMT_SBGGR10, + .name = "Bayer 10 BGGR", + .bits_per_sample = 8, + .packing = SOC_MBUS_PACKING_2X8_PADHI, + .order = SOC_MBUS_ORDER_BE, + .layout = SOC_MBUS_LAYOUT_PACKED, + }, +}, { + .code = MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_BE, + .fmt = { + .fourcc = V4L2_PIX_FMT_SBGGR10, + .name = "Bayer 10 BGGR", + .bits_per_sample = 8, + .packing = SOC_MBUS_PACKING_2X8_PADLO, + .order = SOC_MBUS_ORDER_BE, + .layout = SOC_MBUS_LAYOUT_PACKED, + }, +}, { + .code = MEDIA_BUS_FMT_JPEG_1X8, + .fmt = { + .fourcc = V4L2_PIX_FMT_JPEG, + .name = "JPEG", + .bits_per_sample = 8, + .packing = SOC_MBUS_PACKING_VARIABLE, + .order = SOC_MBUS_ORDER_LE, + .layout = SOC_MBUS_LAYOUT_PACKED, + }, +}, { + .code = MEDIA_BUS_FMT_RGB444_2X8_PADHI_BE, + .fmt = { + .fourcc = V4L2_PIX_FMT_RGB444, + .name = "RGB444", + .bits_per_sample = 8, + .packing = SOC_MBUS_PACKING_2X8_PADHI, + .order = SOC_MBUS_ORDER_BE, + .layout = SOC_MBUS_LAYOUT_PACKED, + }, +}, { + .code = MEDIA_BUS_FMT_YUYV8_1_5X8, + .fmt = { + .fourcc = V4L2_PIX_FMT_YUV420, + .name = "YUYV 4:2:0", + .bits_per_sample = 8, + .packing = SOC_MBUS_PACKING_1_5X8, + .order = SOC_MBUS_ORDER_LE, + .layout = SOC_MBUS_LAYOUT_PACKED, + }, +}, { + .code = MEDIA_BUS_FMT_YVYU8_1_5X8, + .fmt = { + .fourcc = V4L2_PIX_FMT_YVU420, + .name = "YVYU 4:2:0", + .bits_per_sample = 8, + .packing = SOC_MBUS_PACKING_1_5X8, + .order = SOC_MBUS_ORDER_LE, + .layout = SOC_MBUS_LAYOUT_PACKED, + }, +}, { + .code = MEDIA_BUS_FMT_UYVY8_1X16, + .fmt = { + .fourcc = V4L2_PIX_FMT_UYVY, + .name = "UYVY 16bit", + .bits_per_sample = 16, + .packing = SOC_MBUS_PACKING_EXTEND16, + .order = SOC_MBUS_ORDER_LE, + .layout = SOC_MBUS_LAYOUT_PACKED, + }, +}, { + .code = MEDIA_BUS_FMT_VYUY8_1X16, + .fmt = { + .fourcc = V4L2_PIX_FMT_VYUY, + .name = "VYUY 16bit", + .bits_per_sample = 16, + .packing = SOC_MBUS_PACKING_EXTEND16, + .order = SOC_MBUS_ORDER_LE, + .layout = SOC_MBUS_LAYOUT_PACKED, + }, +}, { + .code = MEDIA_BUS_FMT_YUYV8_1X16, + .fmt = { + .fourcc = V4L2_PIX_FMT_YUYV, + .name = "YUYV 16bit", + .bits_per_sample = 16, + .packing = SOC_MBUS_PACKING_EXTEND16, + .order = SOC_MBUS_ORDER_LE, + .layout = SOC_MBUS_LAYOUT_PACKED, + }, +}, { + .code = MEDIA_BUS_FMT_YVYU8_1X16, + .fmt = { + .fourcc = V4L2_PIX_FMT_YVYU, + .name = "YVYU 16bit", + .bits_per_sample = 16, + .packing = SOC_MBUS_PACKING_EXTEND16, + .order = SOC_MBUS_ORDER_LE, + .layout = SOC_MBUS_LAYOUT_PACKED, + }, +}, { + .code = MEDIA_BUS_FMT_SGRBG8_1X8, + .fmt = { + .fourcc = V4L2_PIX_FMT_SGRBG8, + .name = "Bayer 8 GRBG", + .bits_per_sample = 8, + .packing = SOC_MBUS_PACKING_NONE, + .order = SOC_MBUS_ORDER_LE, + .layout = SOC_MBUS_LAYOUT_PACKED, + }, +}, { + .code = MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8, + .fmt = { + .fourcc = V4L2_PIX_FMT_SGRBG10DPCM8, + .name = "Bayer 10 BGGR DPCM 8", + .bits_per_sample = 8, + .packing = SOC_MBUS_PACKING_NONE, + .order = SOC_MBUS_ORDER_LE, + .layout = SOC_MBUS_LAYOUT_PACKED, + }, +}, { + .code = MEDIA_BUS_FMT_SGBRG10_1X10, + .fmt = { + .fourcc = V4L2_PIX_FMT_SGBRG10, + .name = "Bayer 10 GBRG", + .bits_per_sample = 10, + .packing = SOC_MBUS_PACKING_EXTEND16, + .order = SOC_MBUS_ORDER_LE, + .layout = SOC_MBUS_LAYOUT_PACKED, + }, +}, { + .code = MEDIA_BUS_FMT_SGRBG10_1X10, + .fmt = { + .fourcc = V4L2_PIX_FMT_SGRBG10, + .name = "Bayer 10 GRBG", + .bits_per_sample = 10, + .packing = SOC_MBUS_PACKING_EXTEND16, + .order = SOC_MBUS_ORDER_LE, + .layout = SOC_MBUS_LAYOUT_PACKED, + }, +}, { + .code = MEDIA_BUS_FMT_SRGGB10_1X10, + .fmt = { + .fourcc = V4L2_PIX_FMT_SRGGB10, + .name = "Bayer 10 RGGB", + .bits_per_sample = 10, + .packing = SOC_MBUS_PACKING_EXTEND16, + .order = SOC_MBUS_ORDER_LE, + .layout = SOC_MBUS_LAYOUT_PACKED, + }, +}, { + .code = MEDIA_BUS_FMT_SBGGR12_1X12, + .fmt = { + .fourcc = V4L2_PIX_FMT_SBGGR12, + .name = "Bayer 12 BGGR", + .bits_per_sample = 12, + .packing = SOC_MBUS_PACKING_EXTEND16, + .order = SOC_MBUS_ORDER_LE, + .layout = SOC_MBUS_LAYOUT_PACKED, + }, +}, { + .code = MEDIA_BUS_FMT_SGBRG12_1X12, + .fmt = { + .fourcc = V4L2_PIX_FMT_SGBRG12, + .name = "Bayer 12 GBRG", + .bits_per_sample = 12, + .packing = SOC_MBUS_PACKING_EXTEND16, + .order = SOC_MBUS_ORDER_LE, + .layout = SOC_MBUS_LAYOUT_PACKED, + }, +}, { + .code = MEDIA_BUS_FMT_SGRBG12_1X12, + .fmt = { + .fourcc = V4L2_PIX_FMT_SGRBG12, + .name = "Bayer 12 GRBG", + .bits_per_sample = 12, + .packing = SOC_MBUS_PACKING_EXTEND16, + .order = SOC_MBUS_ORDER_LE, + .layout = SOC_MBUS_LAYOUT_PACKED, + }, +}, { + .code = MEDIA_BUS_FMT_SRGGB12_1X12, + .fmt = { + .fourcc = V4L2_PIX_FMT_SRGGB12, + .name = "Bayer 12 RGGB", + .bits_per_sample = 12, + .packing = SOC_MBUS_PACKING_EXTEND16, + .order = SOC_MBUS_ORDER_LE, + .layout = SOC_MBUS_LAYOUT_PACKED, + }, +}, +}; + +int soc_mbus_samples_per_pixel(const struct soc_mbus_pixelfmt *mf, + unsigned int *numerator, unsigned int *denominator) +{ + switch (mf->packing) { + case SOC_MBUS_PACKING_NONE: + case SOC_MBUS_PACKING_EXTEND16: + *numerator = 1; + *denominator = 1; + return 0; + case SOC_MBUS_PACKING_EXTEND32: + *numerator = 1; + *denominator = 1; + return 0; + case SOC_MBUS_PACKING_2X8_PADHI: + case SOC_MBUS_PACKING_2X8_PADLO: + *numerator = 2; + *denominator = 1; + return 0; + case SOC_MBUS_PACKING_1_5X8: + *numerator = 3; + *denominator = 2; + return 0; + case SOC_MBUS_PACKING_VARIABLE: + *numerator = 0; + *denominator = 1; + return 0; + } + return -EINVAL; +} +EXPORT_SYMBOL(soc_mbus_samples_per_pixel); + +s32 soc_mbus_bytes_per_line(u32 width, const struct soc_mbus_pixelfmt *mf) +{ + if (mf->layout != SOC_MBUS_LAYOUT_PACKED) + return width * mf->bits_per_sample / 8; + + switch (mf->packing) { + case SOC_MBUS_PACKING_NONE: + return width * mf->bits_per_sample / 8; + case SOC_MBUS_PACKING_2X8_PADHI: + case SOC_MBUS_PACKING_2X8_PADLO: + case SOC_MBUS_PACKING_EXTEND16: + return width * 2; + case SOC_MBUS_PACKING_1_5X8: + return width * 3 / 2; + case SOC_MBUS_PACKING_VARIABLE: + return 0; + case SOC_MBUS_PACKING_EXTEND32: + return width * 4; + } + return -EINVAL; +} +EXPORT_SYMBOL(soc_mbus_bytes_per_line); + +s32 soc_mbus_image_size(const struct soc_mbus_pixelfmt *mf, + u32 bytes_per_line, u32 height) +{ + if (mf->layout == SOC_MBUS_LAYOUT_PACKED) + return bytes_per_line * height; + + switch (mf->packing) { + case SOC_MBUS_PACKING_2X8_PADHI: + case SOC_MBUS_PACKING_2X8_PADLO: + return bytes_per_line * height * 2; + case SOC_MBUS_PACKING_1_5X8: + return bytes_per_line * height * 3 / 2; + default: + return -EINVAL; + } +} +EXPORT_SYMBOL(soc_mbus_image_size); + +const struct soc_mbus_pixelfmt *soc_mbus_find_fmtdesc( + u32 code, + const struct soc_mbus_lookup *lookup, + int n) +{ + int i; + + for (i = 0; i < n; i++) + if (lookup[i].code == code) + return &lookup[i].fmt; + + return NULL; +} +EXPORT_SYMBOL(soc_mbus_find_fmtdesc); + +const struct soc_mbus_pixelfmt *soc_mbus_get_fmtdesc( + u32 code) +{ + return soc_mbus_find_fmtdesc(code, mbus_fmt, ARRAY_SIZE(mbus_fmt)); +} +EXPORT_SYMBOL(soc_mbus_get_fmtdesc); + +unsigned int soc_mbus_config_compatible(const struct v4l2_mbus_config *cfg, + unsigned int flags) +{ + unsigned long common_flags; + bool hsync = true, vsync = true, pclk, data, mode; + bool mipi_lanes, mipi_clock; + + common_flags = cfg->flags & flags; + + switch (cfg->type) { + case V4L2_MBUS_PARALLEL: + hsync = common_flags & (V4L2_MBUS_HSYNC_ACTIVE_HIGH | + V4L2_MBUS_HSYNC_ACTIVE_LOW); + vsync = common_flags & (V4L2_MBUS_VSYNC_ACTIVE_HIGH | + V4L2_MBUS_VSYNC_ACTIVE_LOW); + /* fall through */ + case V4L2_MBUS_BT656: + pclk = common_flags & (V4L2_MBUS_PCLK_SAMPLE_RISING | + V4L2_MBUS_PCLK_SAMPLE_FALLING); + data = common_flags & (V4L2_MBUS_DATA_ACTIVE_HIGH | + V4L2_MBUS_DATA_ACTIVE_LOW); + mode = common_flags & (V4L2_MBUS_MASTER | V4L2_MBUS_SLAVE); + return (!hsync || !vsync || !pclk || !data || !mode) ? + 0 : common_flags; + case V4L2_MBUS_CSI2_DPHY: + mipi_lanes = common_flags & V4L2_MBUS_CSI2_LANES; + mipi_clock = common_flags & (V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK | + V4L2_MBUS_CSI2_CONTINUOUS_CLOCK); + return (!mipi_lanes || !mipi_clock) ? 0 : common_flags; + default: + WARN_ON(1); + return -EINVAL; + } + return 0; +} +EXPORT_SYMBOL(soc_mbus_config_compatible); + +static int __init soc_mbus_init(void) +{ + return 0; +} + +static void __exit soc_mbus_exit(void) +{ +} + +module_init(soc_mbus_init); +module_exit(soc_mbus_exit); + +MODULE_DESCRIPTION("soc-camera media bus interface"); +MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/media/soc_camera/soc_mt9v022.c b/drivers/staging/media/soc_camera/soc_mt9v022.c new file mode 100644 index 000000000000..6d922b17ea94 --- /dev/null +++ b/drivers/staging/media/soc_camera/soc_mt9v022.c @@ -0,0 +1,1012 @@ +/* + * Driver for MT9V022 CMOS Image Sensor from Micron + * + * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de> + * + * 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. + */ + +#include <linux/videodev2.h> +#include <linux/slab.h> +#include <linux/i2c.h> +#include <linux/delay.h> +#include <linux/log2.h> +#include <linux/module.h> + +#include <media/i2c/mt9v022.h> +#include <media/soc_camera.h> +#include <media/drv-intf/soc_mediabus.h> +#include <media/v4l2-subdev.h> +#include <media/v4l2-clk.h> +#include <media/v4l2-ctrls.h> + +/* + * mt9v022 i2c address 0x48, 0x4c, 0x58, 0x5c + * The platform has to define struct i2c_board_info objects and link to them + * from struct soc_camera_host_desc + */ + +static char *sensor_type; +module_param(sensor_type, charp, S_IRUGO); +MODULE_PARM_DESC(sensor_type, "Sensor type: \"colour\" or \"monochrome\""); + +/* mt9v022 selected register addresses */ +#define MT9V022_CHIP_VERSION 0x00 +#define MT9V022_COLUMN_START 0x01 +#define MT9V022_ROW_START 0x02 +#define MT9V022_WINDOW_HEIGHT 0x03 +#define MT9V022_WINDOW_WIDTH 0x04 +#define MT9V022_HORIZONTAL_BLANKING 0x05 +#define MT9V022_VERTICAL_BLANKING 0x06 +#define MT9V022_CHIP_CONTROL 0x07 +#define MT9V022_SHUTTER_WIDTH1 0x08 +#define MT9V022_SHUTTER_WIDTH2 0x09 +#define MT9V022_SHUTTER_WIDTH_CTRL 0x0a +#define MT9V022_TOTAL_SHUTTER_WIDTH 0x0b +#define MT9V022_RESET 0x0c +#define MT9V022_READ_MODE 0x0d +#define MT9V022_MONITOR_MODE 0x0e +#define MT9V022_PIXEL_OPERATION_MODE 0x0f +#define MT9V022_LED_OUT_CONTROL 0x1b +#define MT9V022_ADC_MODE_CONTROL 0x1c +#define MT9V022_REG32 0x20 +#define MT9V022_ANALOG_GAIN 0x35 +#define MT9V022_BLACK_LEVEL_CALIB_CTRL 0x47 +#define MT9V022_PIXCLK_FV_LV 0x74 +#define MT9V022_DIGITAL_TEST_PATTERN 0x7f +#define MT9V022_AEC_AGC_ENABLE 0xAF +#define MT9V022_MAX_TOTAL_SHUTTER_WIDTH 0xBD + +/* mt9v024 partial list register addresses changes with respect to mt9v022 */ +#define MT9V024_PIXCLK_FV_LV 0x72 +#define MT9V024_MAX_TOTAL_SHUTTER_WIDTH 0xAD + +/* Progressive scan, master, defaults */ +#define MT9V022_CHIP_CONTROL_DEFAULT 0x188 + +#define MT9V022_MAX_WIDTH 752 +#define MT9V022_MAX_HEIGHT 480 +#define MT9V022_MIN_WIDTH 48 +#define MT9V022_MIN_HEIGHT 32 +#define MT9V022_COLUMN_SKIP 1 +#define MT9V022_ROW_SKIP 4 + +#define MT9V022_HORIZONTAL_BLANKING_MIN 43 +#define MT9V022_HORIZONTAL_BLANKING_MAX 1023 +#define MT9V022_HORIZONTAL_BLANKING_DEF 94 +#define MT9V022_VERTICAL_BLANKING_MIN 2 +#define MT9V022_VERTICAL_BLANKING_MAX 3000 +#define MT9V022_VERTICAL_BLANKING_DEF 45 + +#define is_mt9v022_rev3(id) (id == 0x1313) +#define is_mt9v024(id) (id == 0x1324) + +/* MT9V022 has only one fixed colorspace per pixelcode */ +struct mt9v022_datafmt { + u32 code; + enum v4l2_colorspace colorspace; +}; + +/* Find a data format by a pixel code in an array */ +static const struct mt9v022_datafmt *mt9v022_find_datafmt( + u32 code, const struct mt9v022_datafmt *fmt, + int n) +{ + int i; + for (i = 0; i < n; i++) + if (fmt[i].code == code) + return fmt + i; + + return NULL; +} + +static const struct mt9v022_datafmt mt9v022_colour_fmts[] = { + /* + * Order important: first natively supported, + * second supported with a GPIO extender + */ + {MEDIA_BUS_FMT_SBGGR10_1X10, V4L2_COLORSPACE_SRGB}, + {MEDIA_BUS_FMT_SBGGR8_1X8, V4L2_COLORSPACE_SRGB}, +}; + +static const struct mt9v022_datafmt mt9v022_monochrome_fmts[] = { + /* Order important - see above */ + {MEDIA_BUS_FMT_Y10_1X10, V4L2_COLORSPACE_JPEG}, + {MEDIA_BUS_FMT_Y8_1X8, V4L2_COLORSPACE_JPEG}, +}; + +/* only registers with different addresses on different mt9v02x sensors */ +struct mt9v02x_register { + u8 max_total_shutter_width; + u8 pixclk_fv_lv; +}; + +static const struct mt9v02x_register mt9v022_register = { + .max_total_shutter_width = MT9V022_MAX_TOTAL_SHUTTER_WIDTH, + .pixclk_fv_lv = MT9V022_PIXCLK_FV_LV, +}; + +static const struct mt9v02x_register mt9v024_register = { + .max_total_shutter_width = MT9V024_MAX_TOTAL_SHUTTER_WIDTH, + .pixclk_fv_lv = MT9V024_PIXCLK_FV_LV, +}; + +enum mt9v022_model { + MT9V022IX7ATM, + MT9V022IX7ATC, +}; + +struct mt9v022 { + struct v4l2_subdev subdev; + struct v4l2_ctrl_handler hdl; + struct { + /* exposure/auto-exposure cluster */ + struct v4l2_ctrl *autoexposure; + struct v4l2_ctrl *exposure; + }; + struct { + /* gain/auto-gain cluster */ + struct v4l2_ctrl *autogain; + struct v4l2_ctrl *gain; + }; + struct v4l2_ctrl *hblank; + struct v4l2_ctrl *vblank; + struct v4l2_rect rect; /* Sensor window */ + struct v4l2_clk *clk; + const struct mt9v022_datafmt *fmt; + const struct mt9v022_datafmt *fmts; + const struct mt9v02x_register *reg; + int num_fmts; + enum mt9v022_model model; + u16 chip_control; + u16 chip_version; + unsigned short y_skip_top; /* Lines to skip at the top */ +}; + +static struct mt9v022 *to_mt9v022(const struct i2c_client *client) +{ + return container_of(i2c_get_clientdata(client), struct mt9v022, subdev); +} + +static int reg_read(struct i2c_client *client, const u8 reg) +{ + return i2c_smbus_read_word_swapped(client, reg); +} + +static int reg_write(struct i2c_client *client, const u8 reg, + const u16 data) +{ + return i2c_smbus_write_word_swapped(client, reg, data); +} + +static int reg_set(struct i2c_client *client, const u8 reg, + const u16 data) +{ + int ret; + + ret = reg_read(client, reg); + if (ret < 0) + return ret; + return reg_write(client, reg, ret | data); +} + +static int reg_clear(struct i2c_client *client, const u8 reg, + const u16 data) +{ + int ret; + + ret = reg_read(client, reg); + if (ret < 0) + return ret; + return reg_write(client, reg, ret & ~data); +} + +static int mt9v022_init(struct i2c_client *client) +{ + struct mt9v022 *mt9v022 = to_mt9v022(client); + int ret; + + /* + * Almost the default mode: master, parallel, simultaneous, and an + * undocumented bit 0x200, which is present in table 7, but not in 8, + * plus snapshot mode to disable scan for now + */ + mt9v022->chip_control |= 0x10; + ret = reg_write(client, MT9V022_CHIP_CONTROL, mt9v022->chip_control); + if (!ret) + ret = reg_write(client, MT9V022_READ_MODE, 0x300); + + /* All defaults */ + if (!ret) + /* AEC, AGC on */ + ret = reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x3); + if (!ret) + ret = reg_write(client, MT9V022_ANALOG_GAIN, 16); + if (!ret) + ret = reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH, 480); + if (!ret) + ret = reg_write(client, mt9v022->reg->max_total_shutter_width, 480); + if (!ret) + /* default - auto */ + ret = reg_clear(client, MT9V022_BLACK_LEVEL_CALIB_CTRL, 1); + if (!ret) + ret = reg_write(client, MT9V022_DIGITAL_TEST_PATTERN, 0); + if (!ret) + return v4l2_ctrl_handler_setup(&mt9v022->hdl); + + return ret; +} + +static int mt9v022_s_stream(struct v4l2_subdev *sd, int enable) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct mt9v022 *mt9v022 = to_mt9v022(client); + + if (enable) { + /* Switch to master "normal" mode */ + mt9v022->chip_control &= ~0x10; + if (is_mt9v022_rev3(mt9v022->chip_version) || + is_mt9v024(mt9v022->chip_version)) { + /* + * Unset snapshot mode specific settings: clear bit 9 + * and bit 2 in reg. 0x20 when in normal mode. + */ + if (reg_clear(client, MT9V022_REG32, 0x204)) + return -EIO; + } + } else { + /* Switch to snapshot mode */ + mt9v022->chip_control |= 0x10; + if (is_mt9v022_rev3(mt9v022->chip_version) || + is_mt9v024(mt9v022->chip_version)) { + /* + * Required settings for snapshot mode: set bit 9 + * (RST enable) and bit 2 (CR enable) in reg. 0x20 + * See TechNote TN0960 or TN-09-225. + */ + if (reg_set(client, MT9V022_REG32, 0x204)) + return -EIO; + } + } + + if (reg_write(client, MT9V022_CHIP_CONTROL, mt9v022->chip_control) < 0) + return -EIO; + return 0; +} + +static int mt9v022_set_selection(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_selection *sel) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct mt9v022 *mt9v022 = to_mt9v022(client); + struct v4l2_rect rect = sel->r; + int min_row, min_blank; + int ret; + + if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE || + sel->target != V4L2_SEL_TGT_CROP) + return -EINVAL; + + /* Bayer format - even size lengths */ + if (mt9v022->fmts == mt9v022_colour_fmts) { + rect.width = ALIGN(rect.width, 2); + rect.height = ALIGN(rect.height, 2); + /* Let the user play with the starting pixel */ + } + + soc_camera_limit_side(&rect.left, &rect.width, + MT9V022_COLUMN_SKIP, MT9V022_MIN_WIDTH, MT9V022_MAX_WIDTH); + + soc_camera_limit_side(&rect.top, &rect.height, + MT9V022_ROW_SKIP, MT9V022_MIN_HEIGHT, MT9V022_MAX_HEIGHT); + + /* Like in example app. Contradicts the datasheet though */ + ret = reg_read(client, MT9V022_AEC_AGC_ENABLE); + if (ret >= 0) { + if (ret & 1) /* Autoexposure */ + ret = reg_write(client, mt9v022->reg->max_total_shutter_width, + rect.height + mt9v022->y_skip_top + 43); + /* + * If autoexposure is off, there is no need to set + * MT9V022_TOTAL_SHUTTER_WIDTH here. Autoexposure can be off + * only if the user has set exposure manually, using the + * V4L2_CID_EXPOSURE_AUTO with the value V4L2_EXPOSURE_MANUAL. + * In this case the register MT9V022_TOTAL_SHUTTER_WIDTH + * already contains the correct value. + */ + } + /* Setup frame format: defaults apart from width and height */ + if (!ret) + ret = reg_write(client, MT9V022_COLUMN_START, rect.left); + if (!ret) + ret = reg_write(client, MT9V022_ROW_START, rect.top); + /* + * mt9v022: min total row time is 660 columns, min blanking is 43 + * mt9v024: min total row time is 690 columns, min blanking is 61 + */ + if (is_mt9v024(mt9v022->chip_version)) { + min_row = 690; + min_blank = 61; + } else { + min_row = 660; + min_blank = 43; + } + if (!ret) + ret = v4l2_ctrl_s_ctrl(mt9v022->hblank, + rect.width > min_row - min_blank ? + min_blank : min_row - rect.width); + if (!ret) + ret = v4l2_ctrl_s_ctrl(mt9v022->vblank, 45); + if (!ret) + ret = reg_write(client, MT9V022_WINDOW_WIDTH, rect.width); + if (!ret) + ret = reg_write(client, MT9V022_WINDOW_HEIGHT, + rect.height + mt9v022->y_skip_top); + + if (ret < 0) + return ret; + + dev_dbg(&client->dev, "Frame %dx%d pixel\n", rect.width, rect.height); + + mt9v022->rect = rect; + + return 0; +} + +static int mt9v022_get_selection(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_selection *sel) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct mt9v022 *mt9v022 = to_mt9v022(client); + + if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) + return -EINVAL; + + switch (sel->target) { + case V4L2_SEL_TGT_CROP_BOUNDS: + sel->r.left = MT9V022_COLUMN_SKIP; + sel->r.top = MT9V022_ROW_SKIP; + sel->r.width = MT9V022_MAX_WIDTH; + sel->r.height = MT9V022_MAX_HEIGHT; + return 0; + case V4L2_SEL_TGT_CROP: + sel->r = mt9v022->rect; + return 0; + default: + return -EINVAL; + } +} + +static int mt9v022_get_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) +{ + struct v4l2_mbus_framefmt *mf = &format->format; + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct mt9v022 *mt9v022 = to_mt9v022(client); + + if (format->pad) + return -EINVAL; + + mf->width = mt9v022->rect.width; + mf->height = mt9v022->rect.height; + mf->code = mt9v022->fmt->code; + mf->colorspace = mt9v022->fmt->colorspace; + mf->field = V4L2_FIELD_NONE; + + return 0; +} + +static int mt9v022_s_fmt(struct v4l2_subdev *sd, + const struct mt9v022_datafmt *fmt, + struct v4l2_mbus_framefmt *mf) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct mt9v022 *mt9v022 = to_mt9v022(client); + struct v4l2_subdev_selection sel = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + .target = V4L2_SEL_TGT_CROP, + .r.left = mt9v022->rect.left, + .r.top = mt9v022->rect.top, + .r.width = mf->width, + .r.height = mf->height, + }; + int ret; + + /* + * The caller provides a supported format, as verified per call to + * .set_fmt(FORMAT_TRY), datawidth is from our supported format list + */ + switch (mf->code) { + case MEDIA_BUS_FMT_Y8_1X8: + case MEDIA_BUS_FMT_Y10_1X10: + if (mt9v022->model != MT9V022IX7ATM) + return -EINVAL; + break; + case MEDIA_BUS_FMT_SBGGR8_1X8: + case MEDIA_BUS_FMT_SBGGR10_1X10: + if (mt9v022->model != MT9V022IX7ATC) + return -EINVAL; + break; + default: + return -EINVAL; + } + + /* No support for scaling on this camera, just crop. */ + ret = mt9v022_set_selection(sd, NULL, &sel); + if (!ret) { + mf->width = mt9v022->rect.width; + mf->height = mt9v022->rect.height; + mt9v022->fmt = fmt; + mf->colorspace = fmt->colorspace; + } + + return ret; +} + +static int mt9v022_set_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) +{ + struct v4l2_mbus_framefmt *mf = &format->format; + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct mt9v022 *mt9v022 = to_mt9v022(client); + const struct mt9v022_datafmt *fmt; + int align = mf->code == MEDIA_BUS_FMT_SBGGR8_1X8 || + mf->code == MEDIA_BUS_FMT_SBGGR10_1X10; + + if (format->pad) + return -EINVAL; + + v4l_bound_align_image(&mf->width, MT9V022_MIN_WIDTH, + MT9V022_MAX_WIDTH, align, + &mf->height, MT9V022_MIN_HEIGHT + mt9v022->y_skip_top, + MT9V022_MAX_HEIGHT + mt9v022->y_skip_top, align, 0); + + fmt = mt9v022_find_datafmt(mf->code, mt9v022->fmts, + mt9v022->num_fmts); + if (!fmt) { + fmt = mt9v022->fmt; + mf->code = fmt->code; + } + + mf->colorspace = fmt->colorspace; + + if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) + return mt9v022_s_fmt(sd, fmt, mf); + cfg->try_fmt = *mf; + return 0; +} + +#ifdef CONFIG_VIDEO_ADV_DEBUG +static int mt9v022_g_register(struct v4l2_subdev *sd, + struct v4l2_dbg_register *reg) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + + if (reg->reg > 0xff) + return -EINVAL; + + reg->size = 2; + reg->val = reg_read(client, reg->reg); + + if (reg->val > 0xffff) + return -EIO; + + return 0; +} + +static int mt9v022_s_register(struct v4l2_subdev *sd, + const struct v4l2_dbg_register *reg) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + + if (reg->reg > 0xff) + return -EINVAL; + + if (reg_write(client, reg->reg, reg->val) < 0) + return -EIO; + + return 0; +} +#endif + +static int mt9v022_s_power(struct v4l2_subdev *sd, int on) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); + struct mt9v022 *mt9v022 = to_mt9v022(client); + + return soc_camera_set_power(&client->dev, ssdd, mt9v022->clk, on); +} + +static int mt9v022_g_volatile_ctrl(struct v4l2_ctrl *ctrl) +{ + struct mt9v022 *mt9v022 = container_of(ctrl->handler, + struct mt9v022, hdl); + struct v4l2_subdev *sd = &mt9v022->subdev; + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct v4l2_ctrl *gain = mt9v022->gain; + struct v4l2_ctrl *exp = mt9v022->exposure; + unsigned long range; + int data; + + switch (ctrl->id) { + case V4L2_CID_AUTOGAIN: + data = reg_read(client, MT9V022_ANALOG_GAIN); + if (data < 0) + return -EIO; + + range = gain->maximum - gain->minimum; + gain->val = ((data - 16) * range + 24) / 48 + gain->minimum; + return 0; + case V4L2_CID_EXPOSURE_AUTO: + data = reg_read(client, MT9V022_TOTAL_SHUTTER_WIDTH); + if (data < 0) + return -EIO; + + range = exp->maximum - exp->minimum; + exp->val = ((data - 1) * range + 239) / 479 + exp->minimum; + return 0; + case V4L2_CID_HBLANK: + data = reg_read(client, MT9V022_HORIZONTAL_BLANKING); + if (data < 0) + return -EIO; + ctrl->val = data; + return 0; + case V4L2_CID_VBLANK: + data = reg_read(client, MT9V022_VERTICAL_BLANKING); + if (data < 0) + return -EIO; + ctrl->val = data; + return 0; + } + return -EINVAL; +} + +static int mt9v022_s_ctrl(struct v4l2_ctrl *ctrl) +{ + struct mt9v022 *mt9v022 = container_of(ctrl->handler, + struct mt9v022, hdl); + struct v4l2_subdev *sd = &mt9v022->subdev; + struct i2c_client *client = v4l2_get_subdevdata(sd); + int data; + + switch (ctrl->id) { + case V4L2_CID_VFLIP: + if (ctrl->val) + data = reg_set(client, MT9V022_READ_MODE, 0x10); + else + data = reg_clear(client, MT9V022_READ_MODE, 0x10); + if (data < 0) + return -EIO; + return 0; + case V4L2_CID_HFLIP: + if (ctrl->val) + data = reg_set(client, MT9V022_READ_MODE, 0x20); + else + data = reg_clear(client, MT9V022_READ_MODE, 0x20); + if (data < 0) + return -EIO; + return 0; + case V4L2_CID_AUTOGAIN: + if (ctrl->val) { + if (reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x2) < 0) + return -EIO; + } else { + struct v4l2_ctrl *gain = mt9v022->gain; + /* mt9v022 has minimum == default */ + unsigned long range = gain->maximum - gain->minimum; + /* Valid values 16 to 64, 32 to 64 must be even. */ + unsigned long gain_val = ((gain->val - (s32)gain->minimum) * + 48 + range / 2) / range + 16; + + if (gain_val >= 32) + gain_val &= ~1; + + /* + * The user wants to set gain manually, hope, she + * knows, what she's doing... Switch AGC off. + */ + if (reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x2) < 0) + return -EIO; + + dev_dbg(&client->dev, "Setting gain from %d to %lu\n", + reg_read(client, MT9V022_ANALOG_GAIN), gain_val); + if (reg_write(client, MT9V022_ANALOG_GAIN, gain_val) < 0) + return -EIO; + } + return 0; + case V4L2_CID_EXPOSURE_AUTO: + if (ctrl->val == V4L2_EXPOSURE_AUTO) { + data = reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x1); + } else { + struct v4l2_ctrl *exp = mt9v022->exposure; + unsigned long range = exp->maximum - exp->minimum; + unsigned long shutter = ((exp->val - (s32)exp->minimum) * + 479 + range / 2) / range + 1; + + /* + * The user wants to set shutter width manually, hope, + * she knows, what she's doing... Switch AEC off. + */ + data = reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x1); + if (data < 0) + return -EIO; + dev_dbg(&client->dev, "Shutter width from %d to %lu\n", + reg_read(client, MT9V022_TOTAL_SHUTTER_WIDTH), + shutter); + if (reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH, + shutter) < 0) + return -EIO; + } + return 0; + case V4L2_CID_HBLANK: + if (reg_write(client, MT9V022_HORIZONTAL_BLANKING, + ctrl->val) < 0) + return -EIO; + return 0; + case V4L2_CID_VBLANK: + if (reg_write(client, MT9V022_VERTICAL_BLANKING, + ctrl->val) < 0) + return -EIO; + return 0; + } + return -EINVAL; +} + +/* + * Interface active, can use i2c. If it fails, it can indeed mean, that + * this wasn't our capture interface, so, we wait for the right one + */ +static int mt9v022_video_probe(struct i2c_client *client) +{ + struct mt9v022 *mt9v022 = to_mt9v022(client); + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); + s32 data; + int ret; + unsigned long flags; + + ret = mt9v022_s_power(&mt9v022->subdev, 1); + if (ret < 0) + return ret; + + /* Read out the chip version register */ + data = reg_read(client, MT9V022_CHIP_VERSION); + + /* must be 0x1311, 0x1313 or 0x1324 */ + if (data != 0x1311 && data != 0x1313 && data != 0x1324) { + ret = -ENODEV; + dev_info(&client->dev, "No MT9V022 found, ID register 0x%x\n", + data); + goto ei2c; + } + + mt9v022->chip_version = data; + + mt9v022->reg = is_mt9v024(data) ? &mt9v024_register : + &mt9v022_register; + + /* Soft reset */ + ret = reg_write(client, MT9V022_RESET, 1); + if (ret < 0) + goto ei2c; + /* 15 clock cycles */ + udelay(200); + if (reg_read(client, MT9V022_RESET)) { + dev_err(&client->dev, "Resetting MT9V022 failed!\n"); + if (ret > 0) + ret = -EIO; + goto ei2c; + } + + /* Set monochrome or colour sensor type */ + if (sensor_type && (!strcmp("colour", sensor_type) || + !strcmp("color", sensor_type))) { + ret = reg_write(client, MT9V022_PIXEL_OPERATION_MODE, 4 | 0x11); + mt9v022->model = MT9V022IX7ATC; + mt9v022->fmts = mt9v022_colour_fmts; + } else { + ret = reg_write(client, MT9V022_PIXEL_OPERATION_MODE, 0x11); + mt9v022->model = MT9V022IX7ATM; + mt9v022->fmts = mt9v022_monochrome_fmts; + } + + if (ret < 0) + goto ei2c; + + mt9v022->num_fmts = 0; + + /* + * This is a 10bit sensor, so by default we only allow 10bit. + * The platform may support different bus widths due to + * different routing of the data lines. + */ + if (ssdd->query_bus_param) + flags = ssdd->query_bus_param(ssdd); + else + flags = SOCAM_DATAWIDTH_10; + + if (flags & SOCAM_DATAWIDTH_10) + mt9v022->num_fmts++; + else + mt9v022->fmts++; + + if (flags & SOCAM_DATAWIDTH_8) + mt9v022->num_fmts++; + + mt9v022->fmt = &mt9v022->fmts[0]; + + dev_info(&client->dev, "Detected a MT9V022 chip ID %x, %s sensor\n", + data, mt9v022->model == MT9V022IX7ATM ? + "monochrome" : "colour"); + + ret = mt9v022_init(client); + if (ret < 0) + dev_err(&client->dev, "Failed to initialise the camera\n"); + +ei2c: + mt9v022_s_power(&mt9v022->subdev, 0); + return ret; +} + +static int mt9v022_g_skip_top_lines(struct v4l2_subdev *sd, u32 *lines) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct mt9v022 *mt9v022 = to_mt9v022(client); + + *lines = mt9v022->y_skip_top; + + return 0; +} + +static const struct v4l2_ctrl_ops mt9v022_ctrl_ops = { + .g_volatile_ctrl = mt9v022_g_volatile_ctrl, + .s_ctrl = mt9v022_s_ctrl, +}; + +static const struct v4l2_subdev_core_ops mt9v022_subdev_core_ops = { +#ifdef CONFIG_VIDEO_ADV_DEBUG + .g_register = mt9v022_g_register, + .s_register = mt9v022_s_register, +#endif + .s_power = mt9v022_s_power, +}; + +static int mt9v022_enum_mbus_code(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_mbus_code_enum *code) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct mt9v022 *mt9v022 = to_mt9v022(client); + + if (code->pad || code->index >= mt9v022->num_fmts) + return -EINVAL; + + code->code = mt9v022->fmts[code->index].code; + return 0; +} + +static int mt9v022_g_mbus_config(struct v4l2_subdev *sd, + struct v4l2_mbus_config *cfg) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); + + cfg->flags = V4L2_MBUS_MASTER | V4L2_MBUS_SLAVE | + V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_PCLK_SAMPLE_FALLING | + V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_LOW | + V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_LOW | + V4L2_MBUS_DATA_ACTIVE_HIGH; + cfg->type = V4L2_MBUS_PARALLEL; + cfg->flags = soc_camera_apply_board_flags(ssdd, cfg); + + return 0; +} + +static int mt9v022_s_mbus_config(struct v4l2_subdev *sd, + const struct v4l2_mbus_config *cfg) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); + struct mt9v022 *mt9v022 = to_mt9v022(client); + unsigned long flags = soc_camera_apply_board_flags(ssdd, cfg); + unsigned int bps = soc_mbus_get_fmtdesc(mt9v022->fmt->code)->bits_per_sample; + int ret; + u16 pixclk = 0; + + if (ssdd->set_bus_param) { + ret = ssdd->set_bus_param(ssdd, 1 << (bps - 1)); + if (ret) + return ret; + } else if (bps != 10) { + /* + * Without board specific bus width settings we only support the + * sensors native bus width + */ + return -EINVAL; + } + + if (flags & V4L2_MBUS_PCLK_SAMPLE_FALLING) + pixclk |= 0x10; + + if (!(flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH)) + pixclk |= 0x1; + + if (!(flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH)) + pixclk |= 0x2; + + ret = reg_write(client, mt9v022->reg->pixclk_fv_lv, pixclk); + if (ret < 0) + return ret; + + if (!(flags & V4L2_MBUS_MASTER)) + mt9v022->chip_control &= ~0x8; + + ret = reg_write(client, MT9V022_CHIP_CONTROL, mt9v022->chip_control); + if (ret < 0) + return ret; + + dev_dbg(&client->dev, "Calculated pixclk 0x%x, chip control 0x%x\n", + pixclk, mt9v022->chip_control); + + return 0; +} + +static const struct v4l2_subdev_video_ops mt9v022_subdev_video_ops = { + .s_stream = mt9v022_s_stream, + .g_mbus_config = mt9v022_g_mbus_config, + .s_mbus_config = mt9v022_s_mbus_config, +}; + +static const struct v4l2_subdev_sensor_ops mt9v022_subdev_sensor_ops = { + .g_skip_top_lines = mt9v022_g_skip_top_lines, +}; + +static const struct v4l2_subdev_pad_ops mt9v022_subdev_pad_ops = { + .enum_mbus_code = mt9v022_enum_mbus_code, + .get_selection = mt9v022_get_selection, + .set_selection = mt9v022_set_selection, + .get_fmt = mt9v022_get_fmt, + .set_fmt = mt9v022_set_fmt, +}; + +static const struct v4l2_subdev_ops mt9v022_subdev_ops = { + .core = &mt9v022_subdev_core_ops, + .video = &mt9v022_subdev_video_ops, + .sensor = &mt9v022_subdev_sensor_ops, + .pad = &mt9v022_subdev_pad_ops, +}; + +static int mt9v022_probe(struct i2c_client *client, + const struct i2c_device_id *did) +{ + struct mt9v022 *mt9v022; + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); + struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); + struct mt9v022_platform_data *pdata; + int ret; + + if (!ssdd) { + dev_err(&client->dev, "MT9V022 driver needs platform data\n"); + return -EINVAL; + } + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) { + dev_warn(&adapter->dev, + "I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n"); + return -EIO; + } + + mt9v022 = devm_kzalloc(&client->dev, sizeof(struct mt9v022), GFP_KERNEL); + if (!mt9v022) + return -ENOMEM; + + pdata = ssdd->drv_priv; + v4l2_i2c_subdev_init(&mt9v022->subdev, client, &mt9v022_subdev_ops); + v4l2_ctrl_handler_init(&mt9v022->hdl, 6); + v4l2_ctrl_new_std(&mt9v022->hdl, &mt9v022_ctrl_ops, + V4L2_CID_VFLIP, 0, 1, 1, 0); + v4l2_ctrl_new_std(&mt9v022->hdl, &mt9v022_ctrl_ops, + V4L2_CID_HFLIP, 0, 1, 1, 0); + mt9v022->autogain = v4l2_ctrl_new_std(&mt9v022->hdl, &mt9v022_ctrl_ops, + V4L2_CID_AUTOGAIN, 0, 1, 1, 1); + mt9v022->gain = v4l2_ctrl_new_std(&mt9v022->hdl, &mt9v022_ctrl_ops, + V4L2_CID_GAIN, 0, 127, 1, 64); + + /* + * Simulated autoexposure. If enabled, we calculate shutter width + * ourselves in the driver based on vertical blanking and frame width + */ + mt9v022->autoexposure = v4l2_ctrl_new_std_menu(&mt9v022->hdl, + &mt9v022_ctrl_ops, V4L2_CID_EXPOSURE_AUTO, 1, 0, + V4L2_EXPOSURE_AUTO); + mt9v022->exposure = v4l2_ctrl_new_std(&mt9v022->hdl, &mt9v022_ctrl_ops, + V4L2_CID_EXPOSURE, 1, 255, 1, 255); + + mt9v022->hblank = v4l2_ctrl_new_std(&mt9v022->hdl, &mt9v022_ctrl_ops, + V4L2_CID_HBLANK, MT9V022_HORIZONTAL_BLANKING_MIN, + MT9V022_HORIZONTAL_BLANKING_MAX, 1, + MT9V022_HORIZONTAL_BLANKING_DEF); + + mt9v022->vblank = v4l2_ctrl_new_std(&mt9v022->hdl, &mt9v022_ctrl_ops, + V4L2_CID_VBLANK, MT9V022_VERTICAL_BLANKING_MIN, + MT9V022_VERTICAL_BLANKING_MAX, 1, + MT9V022_VERTICAL_BLANKING_DEF); + + mt9v022->subdev.ctrl_handler = &mt9v022->hdl; + if (mt9v022->hdl.error) { + int err = mt9v022->hdl.error; + + dev_err(&client->dev, "control initialisation err %d\n", err); + return err; + } + v4l2_ctrl_auto_cluster(2, &mt9v022->autoexposure, + V4L2_EXPOSURE_MANUAL, true); + v4l2_ctrl_auto_cluster(2, &mt9v022->autogain, 0, true); + + mt9v022->chip_control = MT9V022_CHIP_CONTROL_DEFAULT; + + /* + * On some platforms the first read out line is corrupted. + * Workaround it by skipping if indicated by platform data. + */ + mt9v022->y_skip_top = pdata ? pdata->y_skip_top : 0; + mt9v022->rect.left = MT9V022_COLUMN_SKIP; + mt9v022->rect.top = MT9V022_ROW_SKIP; + mt9v022->rect.width = MT9V022_MAX_WIDTH; + mt9v022->rect.height = MT9V022_MAX_HEIGHT; + + mt9v022->clk = v4l2_clk_get(&client->dev, "mclk"); + if (IS_ERR(mt9v022->clk)) { + ret = PTR_ERR(mt9v022->clk); + goto eclkget; + } + + ret = mt9v022_video_probe(client); + if (ret) { + v4l2_clk_put(mt9v022->clk); +eclkget: + v4l2_ctrl_handler_free(&mt9v022->hdl); + } + + return ret; +} + +static int mt9v022_remove(struct i2c_client *client) +{ + struct mt9v022 *mt9v022 = to_mt9v022(client); + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); + + v4l2_clk_put(mt9v022->clk); + v4l2_device_unregister_subdev(&mt9v022->subdev); + if (ssdd->free_bus) + ssdd->free_bus(ssdd); + v4l2_ctrl_handler_free(&mt9v022->hdl); + + return 0; +} +static const struct i2c_device_id mt9v022_id[] = { + { "mt9v022", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, mt9v022_id); + +static struct i2c_driver mt9v022_i2c_driver = { + .driver = { + .name = "mt9v022", + }, + .probe = mt9v022_probe, + .remove = mt9v022_remove, + .id_table = mt9v022_id, +}; + +module_i2c_driver(mt9v022_i2c_driver); + +MODULE_DESCRIPTION("Micron MT9V022 Camera driver"); +MODULE_AUTHOR("Guennadi Liakhovetski <kernel@pengutronix.de>"); +MODULE_LICENSE("GPL"); diff --git a/drivers/staging/media/soc_camera/soc_ov5642.c b/drivers/staging/media/soc_camera/soc_ov5642.c new file mode 100644 index 000000000000..0931898c79dd --- /dev/null +++ b/drivers/staging/media/soc_camera/soc_ov5642.c @@ -0,0 +1,1087 @@ +/* + * Driver for OV5642 CMOS Image Sensor from Omnivision + * + * Copyright (C) 2011, Bastian Hecht <hechtb@gmail.com> + * + * Based on Sony IMX074 Camera Driver + * Copyright (C) 2010, Guennadi Liakhovetski <g.liakhovetski@gmx.de> + * + * Based on Omnivision OV7670 Camera Driver + * Copyright (C) 2006-7 Jonathan Corbet <corbet@lwn.net> + * + * 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. + */ + +#include <linux/bitops.h> +#include <linux/delay.h> +#include <linux/i2c.h> +#include <linux/kernel.h> +#include <linux/slab.h> +#include <linux/videodev2.h> +#include <linux/module.h> +#include <linux/v4l2-mediabus.h> + +#include <media/soc_camera.h> +#include <media/v4l2-clk.h> +#include <media/v4l2-subdev.h> + +/* OV5642 registers */ +#define REG_CHIP_ID_HIGH 0x300a +#define REG_CHIP_ID_LOW 0x300b + +#define REG_WINDOW_START_X_HIGH 0x3800 +#define REG_WINDOW_START_X_LOW 0x3801 +#define REG_WINDOW_START_Y_HIGH 0x3802 +#define REG_WINDOW_START_Y_LOW 0x3803 +#define REG_WINDOW_WIDTH_HIGH 0x3804 +#define REG_WINDOW_WIDTH_LOW 0x3805 +#define REG_WINDOW_HEIGHT_HIGH 0x3806 +#define REG_WINDOW_HEIGHT_LOW 0x3807 +#define REG_OUT_WIDTH_HIGH 0x3808 +#define REG_OUT_WIDTH_LOW 0x3809 +#define REG_OUT_HEIGHT_HIGH 0x380a +#define REG_OUT_HEIGHT_LOW 0x380b +#define REG_OUT_TOTAL_WIDTH_HIGH 0x380c +#define REG_OUT_TOTAL_WIDTH_LOW 0x380d +#define REG_OUT_TOTAL_HEIGHT_HIGH 0x380e +#define REG_OUT_TOTAL_HEIGHT_LOW 0x380f +#define REG_OUTPUT_FORMAT 0x4300 +#define REG_ISP_CTRL_01 0x5001 +#define REG_AVG_WINDOW_END_X_HIGH 0x5682 +#define REG_AVG_WINDOW_END_X_LOW 0x5683 +#define REG_AVG_WINDOW_END_Y_HIGH 0x5686 +#define REG_AVG_WINDOW_END_Y_LOW 0x5687 + +/* active pixel array size */ +#define OV5642_SENSOR_SIZE_X 2592 +#define OV5642_SENSOR_SIZE_Y 1944 + +/* + * About OV5642 resolution, cropping and binning: + * This sensor supports it all, at least in the feature description. + * Unfortunately, no combination of appropriate registers settings could make + * the chip work the intended way. As it works with predefined register lists, + * some undocumented registers are presumably changed there to achieve their + * goals. + * This driver currently only works for resolutions up to 720 lines with a + * 1:1 scale. Hopefully these restrictions will be removed in the future. + */ +#define OV5642_MAX_WIDTH OV5642_SENSOR_SIZE_X +#define OV5642_MAX_HEIGHT 720 + +/* default sizes */ +#define OV5642_DEFAULT_WIDTH 1280 +#define OV5642_DEFAULT_HEIGHT OV5642_MAX_HEIGHT + +/* minimum extra blanking */ +#define BLANKING_EXTRA_WIDTH 500 +#define BLANKING_EXTRA_HEIGHT 20 + +/* + * the sensor's autoexposure is buggy when setting total_height low. + * It tries to expose longer than 1 frame period without taking care of it + * and this leads to weird output. So we set 1000 lines as minimum. + */ +#define BLANKING_MIN_HEIGHT 1000 + +struct regval_list { + u16 reg_num; + u8 value; +}; + +static struct regval_list ov5642_default_regs_init[] = { + { 0x3103, 0x93 }, + { 0x3008, 0x82 }, + { 0x3017, 0x7f }, + { 0x3018, 0xfc }, + { 0x3810, 0xc2 }, + { 0x3615, 0xf0 }, + { 0x3000, 0x0 }, + { 0x3001, 0x0 }, + { 0x3002, 0x0 }, + { 0x3003, 0x0 }, + { 0x3004, 0xff }, + { 0x3030, 0x2b }, + { 0x3011, 0x8 }, + { 0x3010, 0x10 }, + { 0x3604, 0x60 }, + { 0x3622, 0x60 }, + { 0x3621, 0x9 }, + { 0x3709, 0x0 }, + { 0x4000, 0x21 }, + { 0x401d, 0x22 }, + { 0x3600, 0x54 }, + { 0x3605, 0x4 }, + { 0x3606, 0x3f }, + { 0x3c01, 0x80 }, + { 0x300d, 0x22 }, + { 0x3623, 0x22 }, + { 0x5000, 0x4f }, + { 0x5020, 0x4 }, + { 0x5181, 0x79 }, + { 0x5182, 0x0 }, + { 0x5185, 0x22 }, + { 0x5197, 0x1 }, + { 0x5500, 0xa }, + { 0x5504, 0x0 }, + { 0x5505, 0x7f }, + { 0x5080, 0x8 }, + { 0x300e, 0x18 }, + { 0x4610, 0x0 }, + { 0x471d, 0x5 }, + { 0x4708, 0x6 }, + { 0x370c, 0xa0 }, + { 0x5687, 0x94 }, + { 0x501f, 0x0 }, + { 0x5000, 0x4f }, + { 0x5001, 0xcf }, + { 0x4300, 0x30 }, + { 0x4300, 0x30 }, + { 0x460b, 0x35 }, + { 0x471d, 0x0 }, + { 0x3002, 0xc }, + { 0x3002, 0x0 }, + { 0x4713, 0x3 }, + { 0x471c, 0x50 }, + { 0x4721, 0x2 }, + { 0x4402, 0x90 }, + { 0x460c, 0x22 }, + { 0x3815, 0x44 }, + { 0x3503, 0x7 }, + { 0x3501, 0x73 }, + { 0x3502, 0x80 }, + { 0x350b, 0x0 }, + { 0x3818, 0xc8 }, + { 0x3824, 0x11 }, + { 0x3a00, 0x78 }, + { 0x3a1a, 0x4 }, + { 0x3a13, 0x30 }, + { 0x3a18, 0x0 }, + { 0x3a19, 0x7c }, + { 0x3a08, 0x12 }, + { 0x3a09, 0xc0 }, + { 0x3a0a, 0xf }, + { 0x3a0b, 0xa0 }, + { 0x350c, 0x7 }, + { 0x350d, 0xd0 }, + { 0x3a0d, 0x8 }, + { 0x3a0e, 0x6 }, + { 0x3500, 0x0 }, + { 0x3501, 0x0 }, + { 0x3502, 0x0 }, + { 0x350a, 0x0 }, + { 0x350b, 0x0 }, + { 0x3503, 0x0 }, + { 0x3a0f, 0x3c }, + { 0x3a10, 0x32 }, + { 0x3a1b, 0x3c }, + { 0x3a1e, 0x32 }, + { 0x3a11, 0x80 }, + { 0x3a1f, 0x20 }, + { 0x3030, 0x2b }, + { 0x3a02, 0x0 }, + { 0x3a03, 0x7d }, + { 0x3a04, 0x0 }, + { 0x3a14, 0x0 }, + { 0x3a15, 0x7d }, + { 0x3a16, 0x0 }, + { 0x3a00, 0x78 }, + { 0x3a08, 0x9 }, + { 0x3a09, 0x60 }, + { 0x3a0a, 0x7 }, + { 0x3a0b, 0xd0 }, + { 0x3a0d, 0x10 }, + { 0x3a0e, 0xd }, + { 0x4407, 0x4 }, + { 0x5193, 0x70 }, + { 0x589b, 0x0 }, + { 0x589a, 0xc0 }, + { 0x401e, 0x20 }, + { 0x4001, 0x42 }, + { 0x401c, 0x6 }, + { 0x3825, 0xac }, + { 0x3827, 0xc }, + { 0x528a, 0x1 }, + { 0x528b, 0x4 }, + { 0x528c, 0x8 }, + { 0x528d, 0x10 }, + { 0x528e, 0x20 }, + { 0x528f, 0x28 }, + { 0x5290, 0x30 }, + { 0x5292, 0x0 }, + { 0x5293, 0x1 }, + { 0x5294, 0x0 }, + { 0x5295, 0x4 }, + { 0x5296, 0x0 }, + { 0x5297, 0x8 }, + { 0x5298, 0x0 }, + { 0x5299, 0x10 }, + { 0x529a, 0x0 }, + { 0x529b, 0x20 }, + { 0x529c, 0x0 }, + { 0x529d, 0x28 }, + { 0x529e, 0x0 }, + { 0x529f, 0x30 }, + { 0x5282, 0x0 }, + { 0x5300, 0x0 }, + { 0x5301, 0x20 }, + { 0x5302, 0x0 }, + { 0x5303, 0x7c }, + { 0x530c, 0x0 }, + { 0x530d, 0xc }, + { 0x530e, 0x20 }, + { 0x530f, 0x80 }, + { 0x5310, 0x20 }, + { 0x5311, 0x80 }, + { 0x5308, 0x20 }, + { 0x5309, 0x40 }, + { 0x5304, 0x0 }, + { 0x5305, 0x30 }, + { 0x5306, 0x0 }, + { 0x5307, 0x80 }, + { 0x5314, 0x8 }, + { 0x5315, 0x20 }, + { 0x5319, 0x30 }, + { 0x5316, 0x10 }, + { 0x5317, 0x0 }, + { 0x5318, 0x2 }, + { 0x5380, 0x1 }, + { 0x5381, 0x0 }, + { 0x5382, 0x0 }, + { 0x5383, 0x4e }, + { 0x5384, 0x0 }, + { 0x5385, 0xf }, + { 0x5386, 0x0 }, + { 0x5387, 0x0 }, + { 0x5388, 0x1 }, + { 0x5389, 0x15 }, + { 0x538a, 0x0 }, + { 0x538b, 0x31 }, + { 0x538c, 0x0 }, + { 0x538d, 0x0 }, + { 0x538e, 0x0 }, + { 0x538f, 0xf }, + { 0x5390, 0x0 }, + { 0x5391, 0xab }, + { 0x5392, 0x0 }, + { 0x5393, 0xa2 }, + { 0x5394, 0x8 }, + { 0x5480, 0x14 }, + { 0x5481, 0x21 }, + { 0x5482, 0x36 }, + { 0x5483, 0x57 }, + { 0x5484, 0x65 }, + { 0x5485, 0x71 }, + { 0x5486, 0x7d }, + { 0x5487, 0x87 }, + { 0x5488, 0x91 }, + { 0x5489, 0x9a }, + { 0x548a, 0xaa }, + { 0x548b, 0xb8 }, + { 0x548c, 0xcd }, + { 0x548d, 0xdd }, + { 0x548e, 0xea }, + { 0x548f, 0x1d }, + { 0x5490, 0x5 }, + { 0x5491, 0x0 }, + { 0x5492, 0x4 }, + { 0x5493, 0x20 }, + { 0x5494, 0x3 }, + { 0x5495, 0x60 }, + { 0x5496, 0x2 }, + { 0x5497, 0xb8 }, + { 0x5498, 0x2 }, + { 0x5499, 0x86 }, + { 0x549a, 0x2 }, + { 0x549b, 0x5b }, + { 0x549c, 0x2 }, + { 0x549d, 0x3b }, + { 0x549e, 0x2 }, + { 0x549f, 0x1c }, + { 0x54a0, 0x2 }, + { 0x54a1, 0x4 }, + { 0x54a2, 0x1 }, + { 0x54a3, 0xed }, + { 0x54a4, 0x1 }, + { 0x54a5, 0xc5 }, + { 0x54a6, 0x1 }, + { 0x54a7, 0xa5 }, + { 0x54a8, 0x1 }, + { 0x54a9, 0x6c }, + { 0x54aa, 0x1 }, + { 0x54ab, 0x41 }, + { 0x54ac, 0x1 }, + { 0x54ad, 0x20 }, + { 0x54ae, 0x0 }, + { 0x54af, 0x16 }, + { 0x54b0, 0x1 }, + { 0x54b1, 0x20 }, + { 0x54b2, 0x0 }, + { 0x54b3, 0x10 }, + { 0x54b4, 0x0 }, + { 0x54b5, 0xf0 }, + { 0x54b6, 0x0 }, + { 0x54b7, 0xdf }, + { 0x5402, 0x3f }, + { 0x5403, 0x0 }, + { 0x3406, 0x0 }, + { 0x5180, 0xff }, + { 0x5181, 0x52 }, + { 0x5182, 0x11 }, + { 0x5183, 0x14 }, + { 0x5184, 0x25 }, + { 0x5185, 0x24 }, + { 0x5186, 0x6 }, + { 0x5187, 0x8 }, + { 0x5188, 0x8 }, + { 0x5189, 0x7c }, + { 0x518a, 0x60 }, + { 0x518b, 0xb2 }, + { 0x518c, 0xb2 }, + { 0x518d, 0x44 }, + { 0x518e, 0x3d }, + { 0x518f, 0x58 }, + { 0x5190, 0x46 }, + { 0x5191, 0xf8 }, + { 0x5192, 0x4 }, + { 0x5193, 0x70 }, + { 0x5194, 0xf0 }, + { 0x5195, 0xf0 }, + { 0x5196, 0x3 }, + { 0x5197, 0x1 }, + { 0x5198, 0x4 }, + { 0x5199, 0x12 }, + { 0x519a, 0x4 }, + { 0x519b, 0x0 }, + { 0x519c, 0x6 }, + { 0x519d, 0x82 }, + { 0x519e, 0x0 }, + { 0x5025, 0x80 }, + { 0x3a0f, 0x38 }, + { 0x3a10, 0x30 }, + { 0x3a1b, 0x3a }, + { 0x3a1e, 0x2e }, + { 0x3a11, 0x60 }, + { 0x3a1f, 0x10 }, + { 0x5688, 0xa6 }, + { 0x5689, 0x6a }, + { 0x568a, 0xea }, + { 0x568b, 0xae }, + { 0x568c, 0xa6 }, + { 0x568d, 0x6a }, + { 0x568e, 0x62 }, + { 0x568f, 0x26 }, + { 0x5583, 0x40 }, + { 0x5584, 0x40 }, + { 0x5580, 0x2 }, + { 0x5000, 0xcf }, + { 0x5800, 0x27 }, + { 0x5801, 0x19 }, + { 0x5802, 0x12 }, + { 0x5803, 0xf }, + { 0x5804, 0x10 }, + { 0x5805, 0x15 }, + { 0x5806, 0x1e }, + { 0x5807, 0x2f }, + { 0x5808, 0x15 }, + { 0x5809, 0xd }, + { 0x580a, 0xa }, + { 0x580b, 0x9 }, + { 0x580c, 0xa }, + { 0x580d, 0xc }, + { 0x580e, 0x12 }, + { 0x580f, 0x19 }, + { 0x5810, 0xb }, + { 0x5811, 0x7 }, + { 0x5812, 0x4 }, + { 0x5813, 0x3 }, + { 0x5814, 0x3 }, + { 0x5815, 0x6 }, + { 0x5816, 0xa }, + { 0x5817, 0xf }, + { 0x5818, 0xa }, + { 0x5819, 0x5 }, + { 0x581a, 0x1 }, + { 0x581b, 0x0 }, + { 0x581c, 0x0 }, + { 0x581d, 0x3 }, + { 0x581e, 0x8 }, + { 0x581f, 0xc }, + { 0x5820, 0xa }, + { 0x5821, 0x5 }, + { 0x5822, 0x1 }, + { 0x5823, 0x0 }, + { 0x5824, 0x0 }, + { 0x5825, 0x3 }, + { 0x5826, 0x8 }, + { 0x5827, 0xc }, + { 0x5828, 0xe }, + { 0x5829, 0x8 }, + { 0x582a, 0x6 }, + { 0x582b, 0x4 }, + { 0x582c, 0x5 }, + { 0x582d, 0x7 }, + { 0x582e, 0xb }, + { 0x582f, 0x12 }, + { 0x5830, 0x18 }, + { 0x5831, 0x10 }, + { 0x5832, 0xc }, + { 0x5833, 0xa }, + { 0x5834, 0xb }, + { 0x5835, 0xe }, + { 0x5836, 0x15 }, + { 0x5837, 0x19 }, + { 0x5838, 0x32 }, + { 0x5839, 0x1f }, + { 0x583a, 0x18 }, + { 0x583b, 0x16 }, + { 0x583c, 0x17 }, + { 0x583d, 0x1e }, + { 0x583e, 0x26 }, + { 0x583f, 0x53 }, + { 0x5840, 0x10 }, + { 0x5841, 0xf }, + { 0x5842, 0xd }, + { 0x5843, 0xc }, + { 0x5844, 0xe }, + { 0x5845, 0x9 }, + { 0x5846, 0x11 }, + { 0x5847, 0x10 }, + { 0x5848, 0x10 }, + { 0x5849, 0x10 }, + { 0x584a, 0x10 }, + { 0x584b, 0xe }, + { 0x584c, 0x10 }, + { 0x584d, 0x10 }, + { 0x584e, 0x11 }, + { 0x584f, 0x10 }, + { 0x5850, 0xf }, + { 0x5851, 0xc }, + { 0x5852, 0xf }, + { 0x5853, 0x10 }, + { 0x5854, 0x10 }, + { 0x5855, 0xf }, + { 0x5856, 0xe }, + { 0x5857, 0xb }, + { 0x5858, 0x10 }, + { 0x5859, 0xd }, + { 0x585a, 0xd }, + { 0x585b, 0xc }, + { 0x585c, 0xc }, + { 0x585d, 0xc }, + { 0x585e, 0xb }, + { 0x585f, 0xc }, + { 0x5860, 0xc }, + { 0x5861, 0xc }, + { 0x5862, 0xd }, + { 0x5863, 0x8 }, + { 0x5864, 0x11 }, + { 0x5865, 0x18 }, + { 0x5866, 0x18 }, + { 0x5867, 0x19 }, + { 0x5868, 0x17 }, + { 0x5869, 0x19 }, + { 0x586a, 0x16 }, + { 0x586b, 0x13 }, + { 0x586c, 0x13 }, + { 0x586d, 0x12 }, + { 0x586e, 0x13 }, + { 0x586f, 0x16 }, + { 0x5870, 0x14 }, + { 0x5871, 0x12 }, + { 0x5872, 0x10 }, + { 0x5873, 0x11 }, + { 0x5874, 0x11 }, + { 0x5875, 0x16 }, + { 0x5876, 0x14 }, + { 0x5877, 0x11 }, + { 0x5878, 0x10 }, + { 0x5879, 0xf }, + { 0x587a, 0x10 }, + { 0x587b, 0x14 }, + { 0x587c, 0x13 }, + { 0x587d, 0x12 }, + { 0x587e, 0x11 }, + { 0x587f, 0x11 }, + { 0x5880, 0x12 }, + { 0x5881, 0x15 }, + { 0x5882, 0x14 }, + { 0x5883, 0x15 }, + { 0x5884, 0x15 }, + { 0x5885, 0x15 }, + { 0x5886, 0x13 }, + { 0x5887, 0x17 }, + { 0x3710, 0x10 }, + { 0x3632, 0x51 }, + { 0x3702, 0x10 }, + { 0x3703, 0xb2 }, + { 0x3704, 0x18 }, + { 0x370b, 0x40 }, + { 0x370d, 0x3 }, + { 0x3631, 0x1 }, + { 0x3632, 0x52 }, + { 0x3606, 0x24 }, + { 0x3620, 0x96 }, + { 0x5785, 0x7 }, + { 0x3a13, 0x30 }, + { 0x3600, 0x52 }, + { 0x3604, 0x48 }, + { 0x3606, 0x1b }, + { 0x370d, 0xb }, + { 0x370f, 0xc0 }, + { 0x3709, 0x1 }, + { 0x3823, 0x0 }, + { 0x5007, 0x0 }, + { 0x5009, 0x0 }, + { 0x5011, 0x0 }, + { 0x5013, 0x0 }, + { 0x519e, 0x0 }, + { 0x5086, 0x0 }, + { 0x5087, 0x0 }, + { 0x5088, 0x0 }, + { 0x5089, 0x0 }, + { 0x302b, 0x0 }, + { 0x3503, 0x7 }, + { 0x3011, 0x8 }, + { 0x350c, 0x2 }, + { 0x350d, 0xe4 }, + { 0x3621, 0xc9 }, + { 0x370a, 0x81 }, + { 0xffff, 0xff }, +}; + +static struct regval_list ov5642_default_regs_finalise[] = { + { 0x3810, 0xc2 }, + { 0x3818, 0xc9 }, + { 0x381c, 0x10 }, + { 0x381d, 0xa0 }, + { 0x381e, 0x5 }, + { 0x381f, 0xb0 }, + { 0x3820, 0x0 }, + { 0x3821, 0x0 }, + { 0x3824, 0x11 }, + { 0x3a08, 0x1b }, + { 0x3a09, 0xc0 }, + { 0x3a0a, 0x17 }, + { 0x3a0b, 0x20 }, + { 0x3a0d, 0x2 }, + { 0x3a0e, 0x1 }, + { 0x401c, 0x4 }, + { 0x5682, 0x5 }, + { 0x5683, 0x0 }, + { 0x5686, 0x2 }, + { 0x5687, 0xcc }, + { 0x5001, 0x4f }, + { 0x589b, 0x6 }, + { 0x589a, 0xc5 }, + { 0x3503, 0x0 }, + { 0x460c, 0x20 }, + { 0x460b, 0x37 }, + { 0x471c, 0xd0 }, + { 0x471d, 0x5 }, + { 0x3815, 0x1 }, + { 0x3818, 0xc1 }, + { 0x501f, 0x0 }, + { 0x5002, 0xe0 }, + { 0x4300, 0x32 }, /* UYVY */ + { 0x3002, 0x1c }, + { 0x4800, 0x14 }, + { 0x4801, 0xf }, + { 0x3007, 0x3b }, + { 0x300e, 0x4 }, + { 0x4803, 0x50 }, + { 0x3815, 0x1 }, + { 0x4713, 0x2 }, + { 0x4842, 0x1 }, + { 0x300f, 0xe }, + { 0x3003, 0x3 }, + { 0x3003, 0x1 }, + { 0xffff, 0xff }, +}; + +struct ov5642_datafmt { + u32 code; + enum v4l2_colorspace colorspace; +}; + +struct ov5642 { + struct v4l2_subdev subdev; + const struct ov5642_datafmt *fmt; + struct v4l2_rect crop_rect; + struct v4l2_clk *clk; + + /* blanking information */ + int total_width; + int total_height; +}; + +static const struct ov5642_datafmt ov5642_colour_fmts[] = { + {MEDIA_BUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG}, +}; + +static struct ov5642 *to_ov5642(const struct i2c_client *client) +{ + return container_of(i2c_get_clientdata(client), struct ov5642, subdev); +} + +/* Find a data format by a pixel code in an array */ +static const struct ov5642_datafmt + *ov5642_find_datafmt(u32 code) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(ov5642_colour_fmts); i++) + if (ov5642_colour_fmts[i].code == code) + return ov5642_colour_fmts + i; + + return NULL; +} + +static int reg_read(struct i2c_client *client, u16 reg, u8 *val) +{ + int ret; + /* We have 16-bit i2c addresses - care for endianness */ + unsigned char data[2] = { reg >> 8, reg & 0xff }; + + ret = i2c_master_send(client, data, 2); + if (ret < 2) { + dev_err(&client->dev, "%s: i2c read error, reg: %x\n", + __func__, reg); + return ret < 0 ? ret : -EIO; + } + + ret = i2c_master_recv(client, val, 1); + if (ret < 1) { + dev_err(&client->dev, "%s: i2c read error, reg: %x\n", + __func__, reg); + return ret < 0 ? ret : -EIO; + } + return 0; +} + +static int reg_write(struct i2c_client *client, u16 reg, u8 val) +{ + int ret; + unsigned char data[3] = { reg >> 8, reg & 0xff, val }; + + ret = i2c_master_send(client, data, 3); + if (ret < 3) { + dev_err(&client->dev, "%s: i2c write error, reg: %x\n", + __func__, reg); + return ret < 0 ? ret : -EIO; + } + + return 0; +} + +/* + * convenience function to write 16 bit register values that are split up + * into two consecutive high and low parts + */ +static int reg_write16(struct i2c_client *client, u16 reg, u16 val16) +{ + int ret; + + ret = reg_write(client, reg, val16 >> 8); + if (ret) + return ret; + return reg_write(client, reg + 1, val16 & 0x00ff); +} + +#ifdef CONFIG_VIDEO_ADV_DEBUG +static int ov5642_get_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + int ret; + u8 val; + + if (reg->reg & ~0xffff) + return -EINVAL; + + reg->size = 1; + + ret = reg_read(client, reg->reg, &val); + if (!ret) + reg->val = (__u64)val; + + return ret; +} + +static int ov5642_set_register(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + + if (reg->reg & ~0xffff || reg->val & ~0xff) + return -EINVAL; + + return reg_write(client, reg->reg, reg->val); +} +#endif + +static int ov5642_write_array(struct i2c_client *client, + struct regval_list *vals) +{ + while (vals->reg_num != 0xffff || vals->value != 0xff) { + int ret = reg_write(client, vals->reg_num, vals->value); + if (ret < 0) + return ret; + vals++; + } + dev_dbg(&client->dev, "Register list loaded\n"); + return 0; +} + +static int ov5642_set_resolution(struct v4l2_subdev *sd) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct ov5642 *priv = to_ov5642(client); + int width = priv->crop_rect.width; + int height = priv->crop_rect.height; + int total_width = priv->total_width; + int total_height = priv->total_height; + int start_x = (OV5642_SENSOR_SIZE_X - width) / 2; + int start_y = (OV5642_SENSOR_SIZE_Y - height) / 2; + int ret; + + /* + * This should set the starting point for cropping. + * Doesn't work so far. + */ + ret = reg_write16(client, REG_WINDOW_START_X_HIGH, start_x); + if (!ret) + ret = reg_write16(client, REG_WINDOW_START_Y_HIGH, start_y); + if (!ret) { + priv->crop_rect.left = start_x; + priv->crop_rect.top = start_y; + } + + if (!ret) + ret = reg_write16(client, REG_WINDOW_WIDTH_HIGH, width); + if (!ret) + ret = reg_write16(client, REG_WINDOW_HEIGHT_HIGH, height); + if (ret) + return ret; + priv->crop_rect.width = width; + priv->crop_rect.height = height; + + /* Set the output window size. Only 1:1 scale is supported so far. */ + ret = reg_write16(client, REG_OUT_WIDTH_HIGH, width); + if (!ret) + ret = reg_write16(client, REG_OUT_HEIGHT_HIGH, height); + + /* Total width = output size + blanking */ + if (!ret) + ret = reg_write16(client, REG_OUT_TOTAL_WIDTH_HIGH, total_width); + if (!ret) + ret = reg_write16(client, REG_OUT_TOTAL_HEIGHT_HIGH, total_height); + + /* Sets the window for AWB calculations */ + if (!ret) + ret = reg_write16(client, REG_AVG_WINDOW_END_X_HIGH, width); + if (!ret) + ret = reg_write16(client, REG_AVG_WINDOW_END_Y_HIGH, height); + + return ret; +} + +static int ov5642_set_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) +{ + struct v4l2_mbus_framefmt *mf = &format->format; + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct ov5642 *priv = to_ov5642(client); + const struct ov5642_datafmt *fmt = ov5642_find_datafmt(mf->code); + + if (format->pad) + return -EINVAL; + + mf->width = priv->crop_rect.width; + mf->height = priv->crop_rect.height; + + if (!fmt) { + if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) + return -EINVAL; + mf->code = ov5642_colour_fmts[0].code; + mf->colorspace = ov5642_colour_fmts[0].colorspace; + } + + mf->field = V4L2_FIELD_NONE; + + if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) + priv->fmt = fmt; + else + cfg->try_fmt = *mf; + return 0; +} + +static int ov5642_get_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) +{ + struct v4l2_mbus_framefmt *mf = &format->format; + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct ov5642 *priv = to_ov5642(client); + + const struct ov5642_datafmt *fmt = priv->fmt; + + if (format->pad) + return -EINVAL; + + mf->code = fmt->code; + mf->colorspace = fmt->colorspace; + mf->width = priv->crop_rect.width; + mf->height = priv->crop_rect.height; + mf->field = V4L2_FIELD_NONE; + + return 0; +} + +static int ov5642_enum_mbus_code(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_mbus_code_enum *code) +{ + if (code->pad || code->index >= ARRAY_SIZE(ov5642_colour_fmts)) + return -EINVAL; + + code->code = ov5642_colour_fmts[code->index].code; + return 0; +} + +static int ov5642_set_selection(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_selection *sel) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct ov5642 *priv = to_ov5642(client); + struct v4l2_rect rect = sel->r; + int ret; + + if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE || + sel->target != V4L2_SEL_TGT_CROP) + return -EINVAL; + + v4l_bound_align_image(&rect.width, 48, OV5642_MAX_WIDTH, 1, + &rect.height, 32, OV5642_MAX_HEIGHT, 1, 0); + + priv->crop_rect.width = rect.width; + priv->crop_rect.height = rect.height; + priv->total_width = rect.width + BLANKING_EXTRA_WIDTH; + priv->total_height = max_t(int, rect.height + + BLANKING_EXTRA_HEIGHT, + BLANKING_MIN_HEIGHT); + priv->crop_rect.width = rect.width; + priv->crop_rect.height = rect.height; + + ret = ov5642_write_array(client, ov5642_default_regs_init); + if (!ret) + ret = ov5642_set_resolution(sd); + if (!ret) + ret = ov5642_write_array(client, ov5642_default_regs_finalise); + + return ret; +} + +static int ov5642_get_selection(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_selection *sel) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct ov5642 *priv = to_ov5642(client); + + if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) + return -EINVAL; + + switch (sel->target) { + case V4L2_SEL_TGT_CROP_BOUNDS: + sel->r.left = 0; + sel->r.top = 0; + sel->r.width = OV5642_MAX_WIDTH; + sel->r.height = OV5642_MAX_HEIGHT; + return 0; + case V4L2_SEL_TGT_CROP: + sel->r = priv->crop_rect; + return 0; + default: + return -EINVAL; + } +} + +static int ov5642_g_mbus_config(struct v4l2_subdev *sd, + struct v4l2_mbus_config *cfg) +{ + cfg->type = V4L2_MBUS_CSI2_DPHY; + cfg->flags = V4L2_MBUS_CSI2_2_LANE | V4L2_MBUS_CSI2_CHANNEL_0 | + V4L2_MBUS_CSI2_CONTINUOUS_CLOCK; + + return 0; +} + +static int ov5642_s_power(struct v4l2_subdev *sd, int on) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); + struct ov5642 *priv = to_ov5642(client); + int ret; + + if (!on) + return soc_camera_power_off(&client->dev, ssdd, priv->clk); + + ret = soc_camera_power_on(&client->dev, ssdd, priv->clk); + if (ret < 0) + return ret; + + ret = ov5642_write_array(client, ov5642_default_regs_init); + if (!ret) + ret = ov5642_set_resolution(sd); + if (!ret) + ret = ov5642_write_array(client, ov5642_default_regs_finalise); + + return ret; +} + +static const struct v4l2_subdev_video_ops ov5642_subdev_video_ops = { + .g_mbus_config = ov5642_g_mbus_config, +}; + +static const struct v4l2_subdev_pad_ops ov5642_subdev_pad_ops = { + .enum_mbus_code = ov5642_enum_mbus_code, + .get_selection = ov5642_get_selection, + .set_selection = ov5642_set_selection, + .get_fmt = ov5642_get_fmt, + .set_fmt = ov5642_set_fmt, +}; + +static const struct v4l2_subdev_core_ops ov5642_subdev_core_ops = { + .s_power = ov5642_s_power, +#ifdef CONFIG_VIDEO_ADV_DEBUG + .g_register = ov5642_get_register, + .s_register = ov5642_set_register, +#endif +}; + +static const struct v4l2_subdev_ops ov5642_subdev_ops = { + .core = &ov5642_subdev_core_ops, + .video = &ov5642_subdev_video_ops, + .pad = &ov5642_subdev_pad_ops, +}; + +static int ov5642_video_probe(struct i2c_client *client) +{ + struct v4l2_subdev *subdev = i2c_get_clientdata(client); + int ret; + u8 id_high, id_low; + u16 id; + + ret = ov5642_s_power(subdev, 1); + if (ret < 0) + return ret; + + /* Read sensor Model ID */ + ret = reg_read(client, REG_CHIP_ID_HIGH, &id_high); + if (ret < 0) + goto done; + + id = id_high << 8; + + ret = reg_read(client, REG_CHIP_ID_LOW, &id_low); + if (ret < 0) + goto done; + + id |= id_low; + + dev_info(&client->dev, "Chip ID 0x%04x detected\n", id); + + if (id != 0x5642) { + ret = -ENODEV; + goto done; + } + + ret = 0; + +done: + ov5642_s_power(subdev, 0); + return ret; +} + +static int ov5642_probe(struct i2c_client *client, + const struct i2c_device_id *did) +{ + struct ov5642 *priv; + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); + int ret; + + if (!ssdd) { + dev_err(&client->dev, "OV5642: missing platform data!\n"); + return -EINVAL; + } + + priv = devm_kzalloc(&client->dev, sizeof(struct ov5642), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + v4l2_i2c_subdev_init(&priv->subdev, client, &ov5642_subdev_ops); + + priv->fmt = &ov5642_colour_fmts[0]; + + priv->crop_rect.width = OV5642_DEFAULT_WIDTH; + priv->crop_rect.height = OV5642_DEFAULT_HEIGHT; + priv->crop_rect.left = (OV5642_MAX_WIDTH - OV5642_DEFAULT_WIDTH) / 2; + priv->crop_rect.top = (OV5642_MAX_HEIGHT - OV5642_DEFAULT_HEIGHT) / 2; + priv->total_width = OV5642_DEFAULT_WIDTH + BLANKING_EXTRA_WIDTH; + priv->total_height = BLANKING_MIN_HEIGHT; + + priv->clk = v4l2_clk_get(&client->dev, "mclk"); + if (IS_ERR(priv->clk)) + return PTR_ERR(priv->clk); + + ret = ov5642_video_probe(client); + if (ret < 0) + v4l2_clk_put(priv->clk); + + return ret; +} + +static int ov5642_remove(struct i2c_client *client) +{ + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); + struct ov5642 *priv = to_ov5642(client); + + v4l2_clk_put(priv->clk); + if (ssdd->free_bus) + ssdd->free_bus(ssdd); + + return 0; +} + +static const struct i2c_device_id ov5642_id[] = { + { "ov5642", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, ov5642_id); + +#if IS_ENABLED(CONFIG_OF) +static const struct of_device_id ov5642_of_match[] = { + { .compatible = "ovti,ov5642" }, + { }, +}; +MODULE_DEVICE_TABLE(of, ov5642_of_match); +#endif + +static struct i2c_driver ov5642_i2c_driver = { + .driver = { + .name = "ov5642", + .of_match_table = of_match_ptr(ov5642_of_match), + }, + .probe = ov5642_probe, + .remove = ov5642_remove, + .id_table = ov5642_id, +}; + +module_i2c_driver(ov5642_i2c_driver); + +MODULE_DESCRIPTION("Omnivision OV5642 Camera driver"); +MODULE_AUTHOR("Bastian Hecht <hechtb@gmail.com>"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/media/soc_camera/soc_ov9740.c b/drivers/staging/media/soc_camera/soc_ov9740.c new file mode 100644 index 000000000000..a07d3145d1b4 --- /dev/null +++ b/drivers/staging/media/soc_camera/soc_ov9740.c @@ -0,0 +1,996 @@ +/* + * OmniVision OV9740 Camera Driver + * + * Copyright (C) 2011 NVIDIA Corporation + * + * Based on ov9640 camera driver. + * + * 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. + */ + +#include <linux/init.h> +#include <linux/module.h> +#include <linux/i2c.h> +#include <linux/slab.h> +#include <linux/v4l2-mediabus.h> + +#include <media/soc_camera.h> +#include <media/v4l2-clk.h> +#include <media/v4l2-ctrls.h> + +#define to_ov9740(sd) container_of(sd, struct ov9740_priv, subdev) + +/* General Status Registers */ +#define OV9740_MODEL_ID_HI 0x0000 +#define OV9740_MODEL_ID_LO 0x0001 +#define OV9740_REVISION_NUMBER 0x0002 +#define OV9740_MANUFACTURER_ID 0x0003 +#define OV9740_SMIA_VERSION 0x0004 + +/* General Setup Registers */ +#define OV9740_MODE_SELECT 0x0100 +#define OV9740_IMAGE_ORT 0x0101 +#define OV9740_SOFTWARE_RESET 0x0103 +#define OV9740_GRP_PARAM_HOLD 0x0104 +#define OV9740_MSK_CORRUP_FM 0x0105 + +/* Timing Setting */ +#define OV9740_FRM_LENGTH_LN_HI 0x0340 /* VTS */ +#define OV9740_FRM_LENGTH_LN_LO 0x0341 /* VTS */ +#define OV9740_LN_LENGTH_PCK_HI 0x0342 /* HTS */ +#define OV9740_LN_LENGTH_PCK_LO 0x0343 /* HTS */ +#define OV9740_X_ADDR_START_HI 0x0344 +#define OV9740_X_ADDR_START_LO 0x0345 +#define OV9740_Y_ADDR_START_HI 0x0346 +#define OV9740_Y_ADDR_START_LO 0x0347 +#define OV9740_X_ADDR_END_HI 0x0348 +#define OV9740_X_ADDR_END_LO 0x0349 +#define OV9740_Y_ADDR_END_HI 0x034a +#define OV9740_Y_ADDR_END_LO 0x034b +#define OV9740_X_OUTPUT_SIZE_HI 0x034c +#define OV9740_X_OUTPUT_SIZE_LO 0x034d +#define OV9740_Y_OUTPUT_SIZE_HI 0x034e +#define OV9740_Y_OUTPUT_SIZE_LO 0x034f + +/* IO Control Registers */ +#define OV9740_IO_CREL00 0x3002 +#define OV9740_IO_CREL01 0x3004 +#define OV9740_IO_CREL02 0x3005 +#define OV9740_IO_OUTPUT_SEL01 0x3026 +#define OV9740_IO_OUTPUT_SEL02 0x3027 + +/* AWB Registers */ +#define OV9740_AWB_MANUAL_CTRL 0x3406 + +/* Analog Control Registers */ +#define OV9740_ANALOG_CTRL01 0x3601 +#define OV9740_ANALOG_CTRL02 0x3602 +#define OV9740_ANALOG_CTRL03 0x3603 +#define OV9740_ANALOG_CTRL04 0x3604 +#define OV9740_ANALOG_CTRL10 0x3610 +#define OV9740_ANALOG_CTRL12 0x3612 +#define OV9740_ANALOG_CTRL15 0x3615 +#define OV9740_ANALOG_CTRL20 0x3620 +#define OV9740_ANALOG_CTRL21 0x3621 +#define OV9740_ANALOG_CTRL22 0x3622 +#define OV9740_ANALOG_CTRL30 0x3630 +#define OV9740_ANALOG_CTRL31 0x3631 +#define OV9740_ANALOG_CTRL32 0x3632 +#define OV9740_ANALOG_CTRL33 0x3633 + +/* Sensor Control */ +#define OV9740_SENSOR_CTRL03 0x3703 +#define OV9740_SENSOR_CTRL04 0x3704 +#define OV9740_SENSOR_CTRL05 0x3705 +#define OV9740_SENSOR_CTRL07 0x3707 + +/* Timing Control */ +#define OV9740_TIMING_CTRL17 0x3817 +#define OV9740_TIMING_CTRL19 0x3819 +#define OV9740_TIMING_CTRL33 0x3833 +#define OV9740_TIMING_CTRL35 0x3835 + +/* Banding Filter */ +#define OV9740_AEC_MAXEXPO_60_H 0x3a02 +#define OV9740_AEC_MAXEXPO_60_L 0x3a03 +#define OV9740_AEC_B50_STEP_HI 0x3a08 +#define OV9740_AEC_B50_STEP_LO 0x3a09 +#define OV9740_AEC_B60_STEP_HI 0x3a0a +#define OV9740_AEC_B60_STEP_LO 0x3a0b +#define OV9740_AEC_CTRL0D 0x3a0d +#define OV9740_AEC_CTRL0E 0x3a0e +#define OV9740_AEC_MAXEXPO_50_H 0x3a14 +#define OV9740_AEC_MAXEXPO_50_L 0x3a15 + +/* AEC/AGC Control */ +#define OV9740_AEC_ENABLE 0x3503 +#define OV9740_GAIN_CEILING_01 0x3a18 +#define OV9740_GAIN_CEILING_02 0x3a19 +#define OV9740_AEC_HI_THRESHOLD 0x3a11 +#define OV9740_AEC_3A1A 0x3a1a +#define OV9740_AEC_CTRL1B_WPT2 0x3a1b +#define OV9740_AEC_CTRL0F_WPT 0x3a0f +#define OV9740_AEC_CTRL10_BPT 0x3a10 +#define OV9740_AEC_CTRL1E_BPT2 0x3a1e +#define OV9740_AEC_LO_THRESHOLD 0x3a1f + +/* BLC Control */ +#define OV9740_BLC_AUTO_ENABLE 0x4002 +#define OV9740_BLC_MODE 0x4005 + +/* VFIFO */ +#define OV9740_VFIFO_READ_START_HI 0x4608 +#define OV9740_VFIFO_READ_START_LO 0x4609 + +/* DVP Control */ +#define OV9740_DVP_VSYNC_CTRL02 0x4702 +#define OV9740_DVP_VSYNC_MODE 0x4704 +#define OV9740_DVP_VSYNC_CTRL06 0x4706 + +/* PLL Setting */ +#define OV9740_PLL_MODE_CTRL01 0x3104 +#define OV9740_PRE_PLL_CLK_DIV 0x0305 +#define OV9740_PLL_MULTIPLIER 0x0307 +#define OV9740_VT_SYS_CLK_DIV 0x0303 +#define OV9740_VT_PIX_CLK_DIV 0x0301 +#define OV9740_PLL_CTRL3010 0x3010 +#define OV9740_VFIFO_CTRL00 0x460e + +/* ISP Control */ +#define OV9740_ISP_CTRL00 0x5000 +#define OV9740_ISP_CTRL01 0x5001 +#define OV9740_ISP_CTRL03 0x5003 +#define OV9740_ISP_CTRL05 0x5005 +#define OV9740_ISP_CTRL12 0x5012 +#define OV9740_ISP_CTRL19 0x5019 +#define OV9740_ISP_CTRL1A 0x501a +#define OV9740_ISP_CTRL1E 0x501e +#define OV9740_ISP_CTRL1F 0x501f +#define OV9740_ISP_CTRL20 0x5020 +#define OV9740_ISP_CTRL21 0x5021 + +/* AWB */ +#define OV9740_AWB_CTRL00 0x5180 +#define OV9740_AWB_CTRL01 0x5181 +#define OV9740_AWB_CTRL02 0x5182 +#define OV9740_AWB_CTRL03 0x5183 +#define OV9740_AWB_ADV_CTRL01 0x5184 +#define OV9740_AWB_ADV_CTRL02 0x5185 +#define OV9740_AWB_ADV_CTRL03 0x5186 +#define OV9740_AWB_ADV_CTRL04 0x5187 +#define OV9740_AWB_ADV_CTRL05 0x5188 +#define OV9740_AWB_ADV_CTRL06 0x5189 +#define OV9740_AWB_ADV_CTRL07 0x518a +#define OV9740_AWB_ADV_CTRL08 0x518b +#define OV9740_AWB_ADV_CTRL09 0x518c +#define OV9740_AWB_ADV_CTRL10 0x518d +#define OV9740_AWB_ADV_CTRL11 0x518e +#define OV9740_AWB_CTRL0F 0x518f +#define OV9740_AWB_CTRL10 0x5190 +#define OV9740_AWB_CTRL11 0x5191 +#define OV9740_AWB_CTRL12 0x5192 +#define OV9740_AWB_CTRL13 0x5193 +#define OV9740_AWB_CTRL14 0x5194 + +/* MIPI Control */ +#define OV9740_MIPI_CTRL00 0x4800 +#define OV9740_MIPI_3837 0x3837 +#define OV9740_MIPI_CTRL01 0x4801 +#define OV9740_MIPI_CTRL03 0x4803 +#define OV9740_MIPI_CTRL05 0x4805 +#define OV9740_VFIFO_RD_CTRL 0x4601 +#define OV9740_MIPI_CTRL_3012 0x3012 +#define OV9740_SC_CMMM_MIPI_CTR 0x3014 + +#define OV9740_MAX_WIDTH 1280 +#define OV9740_MAX_HEIGHT 720 + +/* Misc. structures */ +struct ov9740_reg { + u16 reg; + u8 val; +}; + +struct ov9740_priv { + struct v4l2_subdev subdev; + struct v4l2_ctrl_handler hdl; + struct v4l2_clk *clk; + + u16 model; + u8 revision; + u8 manid; + u8 smiaver; + + bool flag_vflip; + bool flag_hflip; + + /* For suspend/resume. */ + struct v4l2_mbus_framefmt current_mf; + bool current_enable; +}; + +static const struct ov9740_reg ov9740_defaults[] = { + /* Software Reset */ + { OV9740_SOFTWARE_RESET, 0x01 }, + + /* Banding Filter */ + { OV9740_AEC_B50_STEP_HI, 0x00 }, + { OV9740_AEC_B50_STEP_LO, 0xe8 }, + { OV9740_AEC_CTRL0E, 0x03 }, + { OV9740_AEC_MAXEXPO_50_H, 0x15 }, + { OV9740_AEC_MAXEXPO_50_L, 0xc6 }, + { OV9740_AEC_B60_STEP_HI, 0x00 }, + { OV9740_AEC_B60_STEP_LO, 0xc0 }, + { OV9740_AEC_CTRL0D, 0x04 }, + { OV9740_AEC_MAXEXPO_60_H, 0x18 }, + { OV9740_AEC_MAXEXPO_60_L, 0x20 }, + + /* LC */ + { 0x5842, 0x02 }, { 0x5843, 0x5e }, { 0x5844, 0x04 }, { 0x5845, 0x32 }, + { 0x5846, 0x03 }, { 0x5847, 0x29 }, { 0x5848, 0x02 }, { 0x5849, 0xcc }, + + /* Un-documented OV9740 registers */ + { 0x5800, 0x29 }, { 0x5801, 0x25 }, { 0x5802, 0x20 }, { 0x5803, 0x21 }, + { 0x5804, 0x26 }, { 0x5805, 0x2e }, { 0x5806, 0x11 }, { 0x5807, 0x0c }, + { 0x5808, 0x09 }, { 0x5809, 0x0a }, { 0x580a, 0x0e }, { 0x580b, 0x16 }, + { 0x580c, 0x06 }, { 0x580d, 0x02 }, { 0x580e, 0x00 }, { 0x580f, 0x00 }, + { 0x5810, 0x04 }, { 0x5811, 0x0a }, { 0x5812, 0x05 }, { 0x5813, 0x02 }, + { 0x5814, 0x00 }, { 0x5815, 0x00 }, { 0x5816, 0x03 }, { 0x5817, 0x09 }, + { 0x5818, 0x0f }, { 0x5819, 0x0a }, { 0x581a, 0x07 }, { 0x581b, 0x08 }, + { 0x581c, 0x0b }, { 0x581d, 0x14 }, { 0x581e, 0x28 }, { 0x581f, 0x23 }, + { 0x5820, 0x1d }, { 0x5821, 0x1e }, { 0x5822, 0x24 }, { 0x5823, 0x2a }, + { 0x5824, 0x4f }, { 0x5825, 0x6f }, { 0x5826, 0x5f }, { 0x5827, 0x7f }, + { 0x5828, 0x9f }, { 0x5829, 0x5f }, { 0x582a, 0x8f }, { 0x582b, 0x9e }, + { 0x582c, 0x8f }, { 0x582d, 0x9f }, { 0x582e, 0x4f }, { 0x582f, 0x87 }, + { 0x5830, 0x86 }, { 0x5831, 0x97 }, { 0x5832, 0xae }, { 0x5833, 0x3f }, + { 0x5834, 0x8e }, { 0x5835, 0x7c }, { 0x5836, 0x7e }, { 0x5837, 0xaf }, + { 0x5838, 0x8f }, { 0x5839, 0x8f }, { 0x583a, 0x9f }, { 0x583b, 0x7f }, + { 0x583c, 0x5f }, + + /* Y Gamma */ + { 0x5480, 0x07 }, { 0x5481, 0x18 }, { 0x5482, 0x2c }, { 0x5483, 0x4e }, + { 0x5484, 0x5e }, { 0x5485, 0x6b }, { 0x5486, 0x77 }, { 0x5487, 0x82 }, + { 0x5488, 0x8c }, { 0x5489, 0x95 }, { 0x548a, 0xa4 }, { 0x548b, 0xb1 }, + { 0x548c, 0xc6 }, { 0x548d, 0xd8 }, { 0x548e, 0xe9 }, + + /* UV Gamma */ + { 0x5490, 0x0f }, { 0x5491, 0xff }, { 0x5492, 0x0d }, { 0x5493, 0x05 }, + { 0x5494, 0x07 }, { 0x5495, 0x1a }, { 0x5496, 0x04 }, { 0x5497, 0x01 }, + { 0x5498, 0x03 }, { 0x5499, 0x53 }, { 0x549a, 0x02 }, { 0x549b, 0xeb }, + { 0x549c, 0x02 }, { 0x549d, 0xa0 }, { 0x549e, 0x02 }, { 0x549f, 0x67 }, + { 0x54a0, 0x02 }, { 0x54a1, 0x3b }, { 0x54a2, 0x02 }, { 0x54a3, 0x18 }, + { 0x54a4, 0x01 }, { 0x54a5, 0xe7 }, { 0x54a6, 0x01 }, { 0x54a7, 0xc3 }, + { 0x54a8, 0x01 }, { 0x54a9, 0x94 }, { 0x54aa, 0x01 }, { 0x54ab, 0x72 }, + { 0x54ac, 0x01 }, { 0x54ad, 0x57 }, + + /* AWB */ + { OV9740_AWB_CTRL00, 0xf0 }, + { OV9740_AWB_CTRL01, 0x00 }, + { OV9740_AWB_CTRL02, 0x41 }, + { OV9740_AWB_CTRL03, 0x42 }, + { OV9740_AWB_ADV_CTRL01, 0x8a }, + { OV9740_AWB_ADV_CTRL02, 0x61 }, + { OV9740_AWB_ADV_CTRL03, 0xce }, + { OV9740_AWB_ADV_CTRL04, 0xa8 }, + { OV9740_AWB_ADV_CTRL05, 0x17 }, + { OV9740_AWB_ADV_CTRL06, 0x1f }, + { OV9740_AWB_ADV_CTRL07, 0x27 }, + { OV9740_AWB_ADV_CTRL08, 0x41 }, + { OV9740_AWB_ADV_CTRL09, 0x34 }, + { OV9740_AWB_ADV_CTRL10, 0xf0 }, + { OV9740_AWB_ADV_CTRL11, 0x10 }, + { OV9740_AWB_CTRL0F, 0xff }, + { OV9740_AWB_CTRL10, 0x00 }, + { OV9740_AWB_CTRL11, 0xff }, + { OV9740_AWB_CTRL12, 0x00 }, + { OV9740_AWB_CTRL13, 0xff }, + { OV9740_AWB_CTRL14, 0x00 }, + + /* CIP */ + { 0x530d, 0x12 }, + + /* CMX */ + { 0x5380, 0x01 }, { 0x5381, 0x00 }, { 0x5382, 0x00 }, { 0x5383, 0x17 }, + { 0x5384, 0x00 }, { 0x5385, 0x01 }, { 0x5386, 0x00 }, { 0x5387, 0x00 }, + { 0x5388, 0x00 }, { 0x5389, 0xe0 }, { 0x538a, 0x00 }, { 0x538b, 0x20 }, + { 0x538c, 0x00 }, { 0x538d, 0x00 }, { 0x538e, 0x00 }, { 0x538f, 0x16 }, + { 0x5390, 0x00 }, { 0x5391, 0x9c }, { 0x5392, 0x00 }, { 0x5393, 0xa0 }, + { 0x5394, 0x18 }, + + /* 50/60 Detection */ + { 0x3c0a, 0x9c }, { 0x3c0b, 0x3f }, + + /* Output Select */ + { OV9740_IO_OUTPUT_SEL01, 0x00 }, + { OV9740_IO_OUTPUT_SEL02, 0x00 }, + { OV9740_IO_CREL00, 0x00 }, + { OV9740_IO_CREL01, 0x00 }, + { OV9740_IO_CREL02, 0x00 }, + + /* AWB Control */ + { OV9740_AWB_MANUAL_CTRL, 0x00 }, + + /* Analog Control */ + { OV9740_ANALOG_CTRL03, 0xaa }, + { OV9740_ANALOG_CTRL32, 0x2f }, + { OV9740_ANALOG_CTRL20, 0x66 }, + { OV9740_ANALOG_CTRL21, 0xc0 }, + { OV9740_ANALOG_CTRL31, 0x52 }, + { OV9740_ANALOG_CTRL33, 0x50 }, + { OV9740_ANALOG_CTRL30, 0xca }, + { OV9740_ANALOG_CTRL04, 0x0c }, + { OV9740_ANALOG_CTRL01, 0x40 }, + { OV9740_ANALOG_CTRL02, 0x16 }, + { OV9740_ANALOG_CTRL10, 0xa1 }, + { OV9740_ANALOG_CTRL12, 0x24 }, + { OV9740_ANALOG_CTRL22, 0x9f }, + { OV9740_ANALOG_CTRL15, 0xf0 }, + + /* Sensor Control */ + { OV9740_SENSOR_CTRL03, 0x42 }, + { OV9740_SENSOR_CTRL04, 0x10 }, + { OV9740_SENSOR_CTRL05, 0x45 }, + { OV9740_SENSOR_CTRL07, 0x14 }, + + /* Timing Control */ + { OV9740_TIMING_CTRL33, 0x04 }, + { OV9740_TIMING_CTRL35, 0x02 }, + { OV9740_TIMING_CTRL19, 0x6e }, + { OV9740_TIMING_CTRL17, 0x94 }, + + /* AEC/AGC Control */ + { OV9740_AEC_ENABLE, 0x10 }, + { OV9740_GAIN_CEILING_01, 0x00 }, + { OV9740_GAIN_CEILING_02, 0x7f }, + { OV9740_AEC_HI_THRESHOLD, 0xa0 }, + { OV9740_AEC_3A1A, 0x05 }, + { OV9740_AEC_CTRL1B_WPT2, 0x50 }, + { OV9740_AEC_CTRL0F_WPT, 0x50 }, + { OV9740_AEC_CTRL10_BPT, 0x4c }, + { OV9740_AEC_CTRL1E_BPT2, 0x4c }, + { OV9740_AEC_LO_THRESHOLD, 0x26 }, + + /* BLC Control */ + { OV9740_BLC_AUTO_ENABLE, 0x45 }, + { OV9740_BLC_MODE, 0x18 }, + + /* DVP Control */ + { OV9740_DVP_VSYNC_CTRL02, 0x04 }, + { OV9740_DVP_VSYNC_MODE, 0x00 }, + { OV9740_DVP_VSYNC_CTRL06, 0x08 }, + + /* PLL Setting */ + { OV9740_PLL_MODE_CTRL01, 0x20 }, + { OV9740_PRE_PLL_CLK_DIV, 0x03 }, + { OV9740_PLL_MULTIPLIER, 0x4c }, + { OV9740_VT_SYS_CLK_DIV, 0x01 }, + { OV9740_VT_PIX_CLK_DIV, 0x08 }, + { OV9740_PLL_CTRL3010, 0x01 }, + { OV9740_VFIFO_CTRL00, 0x82 }, + + /* Timing Setting */ + /* VTS */ + { OV9740_FRM_LENGTH_LN_HI, 0x03 }, + { OV9740_FRM_LENGTH_LN_LO, 0x07 }, + /* HTS */ + { OV9740_LN_LENGTH_PCK_HI, 0x06 }, + { OV9740_LN_LENGTH_PCK_LO, 0x62 }, + + /* MIPI Control */ + { OV9740_MIPI_CTRL00, 0x44 }, /* 0x64 for discontinuous clk */ + { OV9740_MIPI_3837, 0x01 }, + { OV9740_MIPI_CTRL01, 0x0f }, + { OV9740_MIPI_CTRL03, 0x05 }, + { OV9740_MIPI_CTRL05, 0x10 }, + { OV9740_VFIFO_RD_CTRL, 0x16 }, + { OV9740_MIPI_CTRL_3012, 0x70 }, + { OV9740_SC_CMMM_MIPI_CTR, 0x01 }, + + /* YUYV order */ + { OV9740_ISP_CTRL19, 0x02 }, +}; + +static u32 ov9740_codes[] = { + MEDIA_BUS_FMT_YUYV8_2X8, +}; + +/* read a register */ +static int ov9740_reg_read(struct i2c_client *client, u16 reg, u8 *val) +{ + int ret; + struct i2c_msg msg[] = { + { + .addr = client->addr, + .flags = 0, + .len = 2, + .buf = (u8 *)®, + }, + { + .addr = client->addr, + .flags = I2C_M_RD, + .len = 1, + .buf = val, + }, + }; + + reg = swab16(reg); + + ret = i2c_transfer(client->adapter, msg, 2); + if (ret < 0) { + dev_err(&client->dev, "Failed reading register 0x%04x!\n", reg); + return ret; + } + + return 0; +} + +/* write a register */ +static int ov9740_reg_write(struct i2c_client *client, u16 reg, u8 val) +{ + struct i2c_msg msg; + struct { + u16 reg; + u8 val; + } __packed buf; + int ret; + + reg = swab16(reg); + + buf.reg = reg; + buf.val = val; + + msg.addr = client->addr; + msg.flags = 0; + msg.len = 3; + msg.buf = (u8 *)&buf; + + ret = i2c_transfer(client->adapter, &msg, 1); + if (ret < 0) { + dev_err(&client->dev, "Failed writing register 0x%04x!\n", reg); + return ret; + } + + return 0; +} + + +/* Read a register, alter its bits, write it back */ +static int ov9740_reg_rmw(struct i2c_client *client, u16 reg, u8 set, u8 unset) +{ + u8 val; + int ret; + + ret = ov9740_reg_read(client, reg, &val); + if (ret < 0) { + dev_err(&client->dev, + "[Read]-Modify-Write of register 0x%04x failed!\n", + reg); + return ret; + } + + val |= set; + val &= ~unset; + + ret = ov9740_reg_write(client, reg, val); + if (ret < 0) { + dev_err(&client->dev, + "Read-Modify-[Write] of register 0x%04x failed!\n", + reg); + return ret; + } + + return 0; +} + +static int ov9740_reg_write_array(struct i2c_client *client, + const struct ov9740_reg *regarray, + int regarraylen) +{ + int i; + int ret; + + for (i = 0; i < regarraylen; i++) { + ret = ov9740_reg_write(client, + regarray[i].reg, regarray[i].val); + if (ret < 0) + return ret; + } + + return 0; +} + +/* Start/Stop streaming from the device */ +static int ov9740_s_stream(struct v4l2_subdev *sd, int enable) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct ov9740_priv *priv = to_ov9740(sd); + int ret; + + /* Program orientation register. */ + if (priv->flag_vflip) + ret = ov9740_reg_rmw(client, OV9740_IMAGE_ORT, 0x2, 0); + else + ret = ov9740_reg_rmw(client, OV9740_IMAGE_ORT, 0, 0x2); + if (ret < 0) + return ret; + + if (priv->flag_hflip) + ret = ov9740_reg_rmw(client, OV9740_IMAGE_ORT, 0x1, 0); + else + ret = ov9740_reg_rmw(client, OV9740_IMAGE_ORT, 0, 0x1); + if (ret < 0) + return ret; + + if (enable) { + dev_dbg(&client->dev, "Enabling Streaming\n"); + /* Start Streaming */ + ret = ov9740_reg_write(client, OV9740_MODE_SELECT, 0x01); + + } else { + dev_dbg(&client->dev, "Disabling Streaming\n"); + /* Software Reset */ + ret = ov9740_reg_write(client, OV9740_SOFTWARE_RESET, 0x01); + if (!ret) + /* Setting Streaming to Standby */ + ret = ov9740_reg_write(client, OV9740_MODE_SELECT, + 0x00); + } + + priv->current_enable = enable; + + return ret; +} + +/* select nearest higher resolution for capture */ +static void ov9740_res_roundup(u32 *width, u32 *height) +{ + /* Width must be a multiple of 4 pixels. */ + *width = ALIGN(*width, 4); + + /* Max resolution is 1280x720 (720p). */ + if (*width > OV9740_MAX_WIDTH) + *width = OV9740_MAX_WIDTH; + + if (*height > OV9740_MAX_HEIGHT) + *height = OV9740_MAX_HEIGHT; +} + +/* Setup registers according to resolution and color encoding */ +static int ov9740_set_res(struct i2c_client *client, u32 width, u32 height) +{ + u32 x_start; + u32 y_start; + u32 x_end; + u32 y_end; + bool scaling = false; + u32 scale_input_x; + u32 scale_input_y; + int ret; + + if ((width != OV9740_MAX_WIDTH) || (height != OV9740_MAX_HEIGHT)) + scaling = true; + + /* + * Try to use as much of the sensor area as possible when supporting + * smaller resolutions. Depending on the aspect ratio of the + * chosen resolution, we can either use the full width of the sensor, + * or the full height of the sensor (or both if the aspect ratio is + * the same as 1280x720. + */ + if ((OV9740_MAX_WIDTH * height) > (OV9740_MAX_HEIGHT * width)) { + scale_input_x = (OV9740_MAX_HEIGHT * width) / height; + scale_input_y = OV9740_MAX_HEIGHT; + } else { + scale_input_x = OV9740_MAX_WIDTH; + scale_input_y = (OV9740_MAX_WIDTH * height) / width; + } + + /* These describe the area of the sensor to use. */ + x_start = (OV9740_MAX_WIDTH - scale_input_x) / 2; + y_start = (OV9740_MAX_HEIGHT - scale_input_y) / 2; + x_end = x_start + scale_input_x - 1; + y_end = y_start + scale_input_y - 1; + + ret = ov9740_reg_write(client, OV9740_X_ADDR_START_HI, x_start >> 8); + if (ret) + goto done; + ret = ov9740_reg_write(client, OV9740_X_ADDR_START_LO, x_start & 0xff); + if (ret) + goto done; + ret = ov9740_reg_write(client, OV9740_Y_ADDR_START_HI, y_start >> 8); + if (ret) + goto done; + ret = ov9740_reg_write(client, OV9740_Y_ADDR_START_LO, y_start & 0xff); + if (ret) + goto done; + + ret = ov9740_reg_write(client, OV9740_X_ADDR_END_HI, x_end >> 8); + if (ret) + goto done; + ret = ov9740_reg_write(client, OV9740_X_ADDR_END_LO, x_end & 0xff); + if (ret) + goto done; + ret = ov9740_reg_write(client, OV9740_Y_ADDR_END_HI, y_end >> 8); + if (ret) + goto done; + ret = ov9740_reg_write(client, OV9740_Y_ADDR_END_LO, y_end & 0xff); + if (ret) + goto done; + + ret = ov9740_reg_write(client, OV9740_X_OUTPUT_SIZE_HI, width >> 8); + if (ret) + goto done; + ret = ov9740_reg_write(client, OV9740_X_OUTPUT_SIZE_LO, width & 0xff); + if (ret) + goto done; + ret = ov9740_reg_write(client, OV9740_Y_OUTPUT_SIZE_HI, height >> 8); + if (ret) + goto done; + ret = ov9740_reg_write(client, OV9740_Y_OUTPUT_SIZE_LO, height & 0xff); + if (ret) + goto done; + + ret = ov9740_reg_write(client, OV9740_ISP_CTRL1E, scale_input_x >> 8); + if (ret) + goto done; + ret = ov9740_reg_write(client, OV9740_ISP_CTRL1F, scale_input_x & 0xff); + if (ret) + goto done; + ret = ov9740_reg_write(client, OV9740_ISP_CTRL20, scale_input_y >> 8); + if (ret) + goto done; + ret = ov9740_reg_write(client, OV9740_ISP_CTRL21, scale_input_y & 0xff); + if (ret) + goto done; + + ret = ov9740_reg_write(client, OV9740_VFIFO_READ_START_HI, + (scale_input_x - width) >> 8); + if (ret) + goto done; + ret = ov9740_reg_write(client, OV9740_VFIFO_READ_START_LO, + (scale_input_x - width) & 0xff); + if (ret) + goto done; + + ret = ov9740_reg_write(client, OV9740_ISP_CTRL00, 0xff); + if (ret) + goto done; + ret = ov9740_reg_write(client, OV9740_ISP_CTRL01, 0xef | + (scaling << 4)); + if (ret) + goto done; + ret = ov9740_reg_write(client, OV9740_ISP_CTRL03, 0xff); + +done: + return ret; +} + +/* set the format we will capture in */ +static int ov9740_s_fmt(struct v4l2_subdev *sd, + struct v4l2_mbus_framefmt *mf) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct ov9740_priv *priv = to_ov9740(sd); + int ret; + + ret = ov9740_reg_write_array(client, ov9740_defaults, + ARRAY_SIZE(ov9740_defaults)); + if (ret < 0) + return ret; + + ret = ov9740_set_res(client, mf->width, mf->height); + if (ret < 0) + return ret; + + priv->current_mf = *mf; + return ret; +} + +static int ov9740_set_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) +{ + struct v4l2_mbus_framefmt *mf = &format->format; + + if (format->pad) + return -EINVAL; + + ov9740_res_roundup(&mf->width, &mf->height); + + mf->field = V4L2_FIELD_NONE; + mf->code = MEDIA_BUS_FMT_YUYV8_2X8; + mf->colorspace = V4L2_COLORSPACE_SRGB; + + if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) + return ov9740_s_fmt(sd, mf); + cfg->try_fmt = *mf; + return 0; +} + +static int ov9740_enum_mbus_code(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_mbus_code_enum *code) +{ + if (code->pad || code->index >= ARRAY_SIZE(ov9740_codes)) + return -EINVAL; + + code->code = ov9740_codes[code->index]; + + return 0; +} + +static int ov9740_get_selection(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_selection *sel) +{ + if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) + return -EINVAL; + + switch (sel->target) { + case V4L2_SEL_TGT_CROP_BOUNDS: + case V4L2_SEL_TGT_CROP: + sel->r.left = 0; + sel->r.top = 0; + sel->r.width = OV9740_MAX_WIDTH; + sel->r.height = OV9740_MAX_HEIGHT; + return 0; + default: + return -EINVAL; + } +} + +/* Set status of additional camera capabilities */ +static int ov9740_s_ctrl(struct v4l2_ctrl *ctrl) +{ + struct ov9740_priv *priv = + container_of(ctrl->handler, struct ov9740_priv, hdl); + + switch (ctrl->id) { + case V4L2_CID_VFLIP: + priv->flag_vflip = ctrl->val; + break; + case V4L2_CID_HFLIP: + priv->flag_hflip = ctrl->val; + break; + default: + return -EINVAL; + } + + return 0; +} + +static int ov9740_s_power(struct v4l2_subdev *sd, int on) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); + struct ov9740_priv *priv = to_ov9740(sd); + int ret; + + if (on) { + ret = soc_camera_power_on(&client->dev, ssdd, priv->clk); + if (ret < 0) + return ret; + + if (priv->current_enable) { + ov9740_s_fmt(sd, &priv->current_mf); + ov9740_s_stream(sd, 1); + } + } else { + if (priv->current_enable) { + ov9740_s_stream(sd, 0); + priv->current_enable = true; + } + + soc_camera_power_off(&client->dev, ssdd, priv->clk); + } + + return 0; +} + +#ifdef CONFIG_VIDEO_ADV_DEBUG +static int ov9740_get_register(struct v4l2_subdev *sd, + struct v4l2_dbg_register *reg) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + int ret; + u8 val; + + if (reg->reg & ~0xffff) + return -EINVAL; + + reg->size = 2; + + ret = ov9740_reg_read(client, reg->reg, &val); + if (ret) + return ret; + + reg->val = (__u64)val; + + return ret; +} + +static int ov9740_set_register(struct v4l2_subdev *sd, + const struct v4l2_dbg_register *reg) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + + if (reg->reg & ~0xffff || reg->val & ~0xff) + return -EINVAL; + + return ov9740_reg_write(client, reg->reg, reg->val); +} +#endif + +static int ov9740_video_probe(struct i2c_client *client) +{ + struct v4l2_subdev *sd = i2c_get_clientdata(client); + struct ov9740_priv *priv = to_ov9740(sd); + u8 modelhi, modello; + int ret; + + ret = ov9740_s_power(&priv->subdev, 1); + if (ret < 0) + return ret; + + /* + * check and show product ID and manufacturer ID + */ + ret = ov9740_reg_read(client, OV9740_MODEL_ID_HI, &modelhi); + if (ret < 0) + goto done; + + ret = ov9740_reg_read(client, OV9740_MODEL_ID_LO, &modello); + if (ret < 0) + goto done; + + priv->model = (modelhi << 8) | modello; + + ret = ov9740_reg_read(client, OV9740_REVISION_NUMBER, &priv->revision); + if (ret < 0) + goto done; + + ret = ov9740_reg_read(client, OV9740_MANUFACTURER_ID, &priv->manid); + if (ret < 0) + goto done; + + ret = ov9740_reg_read(client, OV9740_SMIA_VERSION, &priv->smiaver); + if (ret < 0) + goto done; + + if (priv->model != 0x9740) { + ret = -ENODEV; + goto done; + } + + dev_info(&client->dev, "ov9740 Model ID 0x%04x, Revision 0x%02x, Manufacturer 0x%02x, SMIA Version 0x%02x\n", + priv->model, priv->revision, priv->manid, priv->smiaver); + + ret = v4l2_ctrl_handler_setup(&priv->hdl); + +done: + ov9740_s_power(&priv->subdev, 0); + return ret; +} + +/* Request bus settings on camera side */ +static int ov9740_g_mbus_config(struct v4l2_subdev *sd, + struct v4l2_mbus_config *cfg) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); + + cfg->flags = V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_MASTER | + V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_HIGH | + V4L2_MBUS_DATA_ACTIVE_HIGH; + cfg->type = V4L2_MBUS_PARALLEL; + cfg->flags = soc_camera_apply_board_flags(ssdd, cfg); + + return 0; +} + +static const struct v4l2_subdev_video_ops ov9740_video_ops = { + .s_stream = ov9740_s_stream, + .g_mbus_config = ov9740_g_mbus_config, +}; + +static const struct v4l2_subdev_core_ops ov9740_core_ops = { + .s_power = ov9740_s_power, +#ifdef CONFIG_VIDEO_ADV_DEBUG + .g_register = ov9740_get_register, + .s_register = ov9740_set_register, +#endif +}; + +static const struct v4l2_subdev_pad_ops ov9740_pad_ops = { + .enum_mbus_code = ov9740_enum_mbus_code, + .get_selection = ov9740_get_selection, + .set_fmt = ov9740_set_fmt, +}; + +static const struct v4l2_subdev_ops ov9740_subdev_ops = { + .core = &ov9740_core_ops, + .video = &ov9740_video_ops, + .pad = &ov9740_pad_ops, +}; + +static const struct v4l2_ctrl_ops ov9740_ctrl_ops = { + .s_ctrl = ov9740_s_ctrl, +}; + +/* + * i2c_driver function + */ +static int ov9740_probe(struct i2c_client *client, + const struct i2c_device_id *did) +{ + struct ov9740_priv *priv; + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); + int ret; + + if (!ssdd) { + dev_err(&client->dev, "Missing platform_data for driver\n"); + return -EINVAL; + } + + priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + v4l2_i2c_subdev_init(&priv->subdev, client, &ov9740_subdev_ops); + v4l2_ctrl_handler_init(&priv->hdl, 13); + v4l2_ctrl_new_std(&priv->hdl, &ov9740_ctrl_ops, + V4L2_CID_VFLIP, 0, 1, 1, 0); + v4l2_ctrl_new_std(&priv->hdl, &ov9740_ctrl_ops, + V4L2_CID_HFLIP, 0, 1, 1, 0); + priv->subdev.ctrl_handler = &priv->hdl; + if (priv->hdl.error) + return priv->hdl.error; + + priv->clk = v4l2_clk_get(&client->dev, "mclk"); + if (IS_ERR(priv->clk)) { + ret = PTR_ERR(priv->clk); + goto eclkget; + } + + ret = ov9740_video_probe(client); + if (ret < 0) { + v4l2_clk_put(priv->clk); +eclkget: + v4l2_ctrl_handler_free(&priv->hdl); + } + + return ret; +} + +static int ov9740_remove(struct i2c_client *client) +{ + struct ov9740_priv *priv = i2c_get_clientdata(client); + + v4l2_clk_put(priv->clk); + v4l2_device_unregister_subdev(&priv->subdev); + v4l2_ctrl_handler_free(&priv->hdl); + return 0; +} + +static const struct i2c_device_id ov9740_id[] = { + { "ov9740", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, ov9740_id); + +static struct i2c_driver ov9740_i2c_driver = { + .driver = { + .name = "ov9740", + }, + .probe = ov9740_probe, + .remove = ov9740_remove, + .id_table = ov9740_id, +}; + +module_i2c_driver(ov9740_i2c_driver); + +MODULE_DESCRIPTION("SoC Camera driver for OmniVision OV9740"); +MODULE_AUTHOR("Andrew Chew <achew@nvidia.com>"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/media/sunxi/cedrus/TODO b/drivers/staging/media/sunxi/cedrus/TODO index a951b3fd1ea1..ec277ece47af 100644 --- a/drivers/staging/media/sunxi/cedrus/TODO +++ b/drivers/staging/media/sunxi/cedrus/TODO @@ -5,8 +5,3 @@ Before this stateless decoder driver can leave the staging area: * Userspace support for the Request API needs to be reviewed; * Another stateless decoder driver should be submitted; * At least one stateless encoder driver should be submitted. -* When queueing a request containing references to I frames, the - refcount of the memory for those I frames needs to be incremented - and decremented when the request is completed. This will likely - require some help from vb2. The driver should fail the request - if the memory/buffer is gone. diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.h b/drivers/staging/media/sunxi/cedrus/cedrus.h index 3acfdcf83691..4aedd24a9848 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus.h +++ b/drivers/staging/media/sunxi/cedrus/cedrus.h @@ -140,11 +140,14 @@ static inline dma_addr_t cedrus_buf_addr(struct vb2_buffer *buf, } static inline dma_addr_t cedrus_dst_buf_addr(struct cedrus_ctx *ctx, - unsigned int index, - unsigned int plane) + int index, unsigned int plane) { - struct vb2_buffer *buf = ctx->dst_bufs[index]; + struct vb2_buffer *buf; + if (index < 0) + return 0; + + buf = ctx->dst_bufs[index]; return buf ? cedrus_buf_addr(buf, &ctx->dst_fmt, plane) : 0; } diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c index 591d191d4286..4d6d602cdde6 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c +++ b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c @@ -50,6 +50,8 @@ void cedrus_device_run(void *priv) break; } + v4l2_m2m_buf_copy_metadata(run.src, run.dst, true); + dev->dec_ops[ctx->current_codec]->setup(ctx, &run); /* Complete request(s) controls if needed. */ diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_dec.h b/drivers/staging/media/sunxi/cedrus/cedrus_dec.h index 4f423d3a1cad..d1ae7903677b 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus_dec.h +++ b/drivers/staging/media/sunxi/cedrus/cedrus_dec.h @@ -16,12 +16,6 @@ #ifndef _CEDRUS_DEC_H_ #define _CEDRUS_DEC_H_ -extern const struct v4l2_ioctl_ops cedrus_ioctl_ops; - -void cedrus_device_work(struct work_struct *work); void cedrus_device_run(void *priv); -int cedrus_queue_init(void *priv, struct vb2_queue *src_vq, - struct vb2_queue *dst_vq); - #endif diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_hw.c b/drivers/staging/media/sunxi/cedrus/cedrus_hw.c index 300339fee1bc..0acf219a8c91 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus_hw.c +++ b/drivers/staging/media/sunxi/cedrus/cedrus_hw.c @@ -157,14 +157,14 @@ int cedrus_hw_probe(struct cedrus_dev *dev) irq_dec = platform_get_irq(dev->pdev, 0); if (irq_dec <= 0) { - v4l2_err(&dev->v4l2_dev, "Failed to get IRQ\n"); + dev_err(dev->dev, "Failed to get IRQ\n"); return irq_dec; } ret = devm_request_irq(dev->dev, irq_dec, cedrus_irq, 0, dev_name(dev->dev), dev); if (ret) { - v4l2_err(&dev->v4l2_dev, "Failed to request IRQ\n"); + dev_err(dev->dev, "Failed to request IRQ\n"); return ret; } @@ -182,21 +182,21 @@ int cedrus_hw_probe(struct cedrus_dev *dev) ret = of_reserved_mem_device_init(dev->dev); if (ret && ret != -ENODEV) { - v4l2_err(&dev->v4l2_dev, "Failed to reserve memory\n"); + dev_err(dev->dev, "Failed to reserve memory\n"); return ret; } ret = sunxi_sram_claim(dev->dev); if (ret) { - v4l2_err(&dev->v4l2_dev, "Failed to claim SRAM\n"); + dev_err(dev->dev, "Failed to claim SRAM\n"); goto err_mem; } dev->ahb_clk = devm_clk_get(dev->dev, "ahb"); if (IS_ERR(dev->ahb_clk)) { - v4l2_err(&dev->v4l2_dev, "Failed to get AHB clock\n"); + dev_err(dev->dev, "Failed to get AHB clock\n"); ret = PTR_ERR(dev->ahb_clk); goto err_sram; @@ -204,7 +204,7 @@ int cedrus_hw_probe(struct cedrus_dev *dev) dev->mod_clk = devm_clk_get(dev->dev, "mod"); if (IS_ERR(dev->mod_clk)) { - v4l2_err(&dev->v4l2_dev, "Failed to get MOD clock\n"); + dev_err(dev->dev, "Failed to get MOD clock\n"); ret = PTR_ERR(dev->mod_clk); goto err_sram; @@ -212,7 +212,7 @@ int cedrus_hw_probe(struct cedrus_dev *dev) dev->ram_clk = devm_clk_get(dev->dev, "ram"); if (IS_ERR(dev->ram_clk)) { - v4l2_err(&dev->v4l2_dev, "Failed to get RAM clock\n"); + dev_err(dev->dev, "Failed to get RAM clock\n"); ret = PTR_ERR(dev->ram_clk); goto err_sram; @@ -220,7 +220,7 @@ int cedrus_hw_probe(struct cedrus_dev *dev) dev->rstc = devm_reset_control_get(dev->dev, NULL); if (IS_ERR(dev->rstc)) { - v4l2_err(&dev->v4l2_dev, "Failed to get reset control\n"); + dev_err(dev->dev, "Failed to get reset control\n"); ret = PTR_ERR(dev->rstc); goto err_sram; @@ -229,7 +229,7 @@ int cedrus_hw_probe(struct cedrus_dev *dev) res = platform_get_resource(dev->pdev, IORESOURCE_MEM, 0); dev->base = devm_ioremap_resource(dev->dev, res); if (IS_ERR(dev->base)) { - v4l2_err(&dev->v4l2_dev, "Failed to map registers\n"); + dev_err(dev->dev, "Failed to map registers\n"); ret = PTR_ERR(dev->base); goto err_sram; @@ -237,35 +237,35 @@ int cedrus_hw_probe(struct cedrus_dev *dev) ret = clk_set_rate(dev->mod_clk, CEDRUS_CLOCK_RATE_DEFAULT); if (ret) { - v4l2_err(&dev->v4l2_dev, "Failed to set clock rate\n"); + dev_err(dev->dev, "Failed to set clock rate\n"); goto err_sram; } ret = clk_prepare_enable(dev->ahb_clk); if (ret) { - v4l2_err(&dev->v4l2_dev, "Failed to enable AHB clock\n"); + dev_err(dev->dev, "Failed to enable AHB clock\n"); goto err_sram; } ret = clk_prepare_enable(dev->mod_clk); if (ret) { - v4l2_err(&dev->v4l2_dev, "Failed to enable MOD clock\n"); + dev_err(dev->dev, "Failed to enable MOD clock\n"); goto err_ahb_clk; } ret = clk_prepare_enable(dev->ram_clk); if (ret) { - v4l2_err(&dev->v4l2_dev, "Failed to enable RAM clock\n"); + dev_err(dev->dev, "Failed to enable RAM clock\n"); goto err_mod_clk; } ret = reset_control_reset(dev->rstc); if (ret) { - v4l2_err(&dev->v4l2_dev, "Failed to apply reset\n"); + dev_err(dev->dev, "Failed to apply reset\n"); goto err_ram_clk; } diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c b/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c index 9abd39cae38c..13c34927bad5 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c +++ b/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c @@ -82,7 +82,10 @@ static void cedrus_mpeg2_setup(struct cedrus_ctx *ctx, struct cedrus_run *run) dma_addr_t fwd_luma_addr, fwd_chroma_addr; dma_addr_t bwd_luma_addr, bwd_chroma_addr; struct cedrus_dev *dev = ctx->dev; + struct vb2_queue *vq; const u8 *matrix; + int forward_idx; + int backward_idx; unsigned int i; u32 reg; @@ -157,22 +160,18 @@ static void cedrus_mpeg2_setup(struct cedrus_ctx *ctx, struct cedrus_run *run) /* Forward and backward prediction reference buffers. */ - fwd_luma_addr = cedrus_dst_buf_addr(ctx, - slice_params->forward_ref_index, - 0); - fwd_chroma_addr = cedrus_dst_buf_addr(ctx, - slice_params->forward_ref_index, - 1); + vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); + + forward_idx = vb2_find_timestamp(vq, slice_params->forward_ref_ts, 0); + fwd_luma_addr = cedrus_dst_buf_addr(ctx, forward_idx, 0); + fwd_chroma_addr = cedrus_dst_buf_addr(ctx, forward_idx, 1); cedrus_write(dev, VE_DEC_MPEG_FWD_REF_LUMA_ADDR, fwd_luma_addr); cedrus_write(dev, VE_DEC_MPEG_FWD_REF_CHROMA_ADDR, fwd_chroma_addr); - bwd_luma_addr = cedrus_dst_buf_addr(ctx, - slice_params->backward_ref_index, - 0); - bwd_chroma_addr = cedrus_dst_buf_addr(ctx, - slice_params->backward_ref_index, - 1); + backward_idx = vb2_find_timestamp(vq, slice_params->backward_ref_ts, 0); + bwd_luma_addr = cedrus_dst_buf_addr(ctx, backward_idx, 0); + bwd_chroma_addr = cedrus_dst_buf_addr(ctx, backward_idx, 1); cedrus_write(dev, VE_DEC_MPEG_BWD_REF_LUMA_ADDR, bwd_luma_addr); cedrus_write(dev, VE_DEC_MPEG_BWD_REF_CHROMA_ADDR, bwd_chroma_addr); diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_video.c b/drivers/staging/media/sunxi/cedrus/cedrus_video.c index 8721b4a7d496..b47854b3bce4 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus_video.c +++ b/drivers/staging/media/sunxi/cedrus/cedrus_video.c @@ -282,8 +282,13 @@ static int cedrus_s_fmt_vid_cap(struct file *file, void *priv, { struct cedrus_ctx *ctx = cedrus_file2ctx(file); struct cedrus_dev *dev = ctx->dev; + struct vb2_queue *vq; int ret; + vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type); + if (vb2_is_busy(vq)) + return -EBUSY; + ret = cedrus_try_fmt_vid_cap(file, priv, f); if (ret) return ret; @@ -299,8 +304,13 @@ static int cedrus_s_fmt_vid_out(struct file *file, void *priv, struct v4l2_format *f) { struct cedrus_ctx *ctx = cedrus_file2ctx(file); + struct vb2_queue *vq; int ret; + vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type); + if (vb2_is_busy(vq)) + return -EBUSY; + ret = cedrus_try_fmt_vid_out(file, priv, f); if (ret) return ret; @@ -416,6 +426,14 @@ static void cedrus_buf_cleanup(struct vb2_buffer *vb) ctx->dst_bufs[vb->index] = NULL; } +static int cedrus_buf_out_validate(struct vb2_buffer *vb) +{ + struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); + + vbuf->field = V4L2_FIELD_NONE; + return 0; +} + static int cedrus_buf_prepare(struct vb2_buffer *vb) { struct vb2_queue *vq = vb->vb2_queue; @@ -493,6 +511,7 @@ static struct vb2_ops cedrus_qops = { .buf_init = cedrus_buf_init, .buf_cleanup = cedrus_buf_cleanup, .buf_queue = cedrus_buf_queue, + .buf_out_validate = cedrus_buf_out_validate, .buf_request_complete = cedrus_buf_request_complete, .start_streaming = cedrus_start_streaming, .stop_streaming = cedrus_stop_streaming, diff --git a/drivers/staging/media/zoran/zoran.h b/drivers/staging/media/zoran/zoran.h index 9bb3c21aa275..e84fb604a689 100644 --- a/drivers/staging/media/zoran/zoran.h +++ b/drivers/staging/media/zoran/zoran.h @@ -35,7 +35,7 @@ struct zoran_sync { unsigned long frame; /* number of buffer that has been free'd */ unsigned long length; /* number of code bytes in buffer (capture only) */ unsigned long seq; /* frame sequence number */ - struct timeval timestamp; /* timestamp */ + u64 ts; /* timestamp */ }; diff --git a/drivers/staging/media/zoran/zoran_card.c b/drivers/staging/media/zoran/zoran_card.c index 94dadbba7cd5..ea10523194e8 100644 --- a/drivers/staging/media/zoran/zoran_card.c +++ b/drivers/staging/media/zoran/zoran_card.c @@ -1470,7 +1470,7 @@ static int __init zoran_init(void) v4l_nbufs = 2; if (v4l_nbufs > VIDEO_MAX_FRAME) v4l_nbufs = VIDEO_MAX_FRAME; - /* The user specfies the in KB, we want them in byte + /* The user specifies the in KB, we want them in byte * (and page aligned) */ v4l_bufsize = PAGE_ALIGN(v4l_bufsize * 1024); if (v4l_bufsize < 32768) diff --git a/drivers/staging/media/zoran/zoran_device.c b/drivers/staging/media/zoran/zoran_device.c index 40adceebca7e..22b27632762d 100644 --- a/drivers/staging/media/zoran/zoran_device.c +++ b/drivers/staging/media/zoran/zoran_device.c @@ -612,7 +612,7 @@ zr36057_set_memgrab (struct zoran *zr, zr->v4l_memgrab_active = 0; zr->v4l_grab_frame = NO_GRAB_ACTIVE; - /* reenable grabbing to screen if it was running */ + /* re-enable grabbing to screen if it was running */ if (zr->v4l_overlay_active) { zr36057_overlay(zr, 1); } else { @@ -1151,7 +1151,7 @@ zoran_reap_stat_com (struct zoran *zr) } frame = zr->jpg_pend[zr->jpg_dma_tail & BUZ_MASK_FRAME]; buffer = &zr->jpg_buffers.buffer[frame]; - v4l2_get_timestamp(&buffer->bs.timestamp); + buffer->bs.ts = ktime_get_ns(); if (zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) { buffer->bs.length = (stat_com & 0x7fffff) >> 1; @@ -1389,7 +1389,7 @@ zoran_irq (int irq, zr->v4l_buffers.buffer[zr->v4l_grab_frame].state = BUZ_STATE_DONE; zr->v4l_buffers.buffer[zr->v4l_grab_frame].bs.seq = zr->v4l_grab_seq; - v4l2_get_timestamp(&zr->v4l_buffers.buffer[zr->v4l_grab_frame].bs.timestamp); + zr->v4l_buffers.buffer[zr->v4l_grab_frame].bs.ts = ktime_get_ns(); zr->v4l_grab_frame = NO_GRAB_ACTIVE; zr->v4l_pend_tail++; } diff --git a/drivers/staging/media/zoran/zoran_driver.c b/drivers/staging/media/zoran/zoran_driver.c index 27c76e2eeb41..04f88f9d6bb4 100644 --- a/drivers/staging/media/zoran/zoran_driver.c +++ b/drivers/staging/media/zoran/zoran_driver.c @@ -1354,7 +1354,7 @@ static int zoran_v4l2_buffer_status(struct zoran_fh *fh, fh->buffers.buffer[num].state == BUZ_STATE_USER) { buf->sequence = fh->buffers.buffer[num].bs.seq; buf->flags |= V4L2_BUF_FLAG_DONE; - buf->timestamp = fh->buffers.buffer[num].bs.timestamp; + buf->timestamp = ns_to_timeval(fh->buffers.buffer[num].bs.ts); } else { buf->flags |= V4L2_BUF_FLAG_QUEUED; } @@ -1388,7 +1388,7 @@ static int zoran_v4l2_buffer_status(struct zoran_fh *fh, if (fh->buffers.buffer[num].state == BUZ_STATE_DONE || fh->buffers.buffer[num].state == BUZ_STATE_USER) { buf->sequence = fh->buffers.buffer[num].bs.seq; - buf->timestamp = fh->buffers.buffer[num].bs.timestamp; + buf->timestamp = ns_to_timeval(fh->buffers.buffer[num].bs.ts); buf->bytesused = fh->buffers.buffer[num].bs.length; buf->flags |= V4L2_BUF_FLAG_DONE; } else { diff --git a/drivers/staging/most/Makefile b/drivers/staging/most/Makefile index f8bcf488ecf2..c7662f65f6db 100644 --- a/drivers/staging/most/Makefile +++ b/drivers/staging/most/Makefile @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_MOST) += most_core.o most_core-y := core.o -ccflags-y += -Idrivers/staging/ +ccflags-y += -I $(srctree)/drivers/staging/ obj-$(CONFIG_MOST_CDEV) += cdev/ obj-$(CONFIG_MOST_NET) += net/ diff --git a/drivers/staging/most/cdev/Makefile b/drivers/staging/most/cdev/Makefile index afb9870eb50f..21b0bd72c01d 100644 --- a/drivers/staging/most/cdev/Makefile +++ b/drivers/staging/most/cdev/Makefile @@ -1,4 +1,4 @@ obj-$(CONFIG_MOST_CDEV) += most_cdev.o most_cdev-objs := cdev.o -ccflags-y += -Idrivers/staging/ +ccflags-y += -I $(srctree)/drivers/staging/ diff --git a/drivers/staging/most/cdev/cdev.c b/drivers/staging/most/cdev/cdev.c index ea64aabda94e..f2b347cda8b7 100644 --- a/drivers/staging/most/cdev/cdev.c +++ b/drivers/staging/most/cdev/cdev.c @@ -453,7 +453,9 @@ static int comp_probe(struct most_interface *iface, int channel_id, c->devno = MKDEV(comp.major, current_minor); cdev_init(&c->cdev, &channel_fops); c->cdev.owner = THIS_MODULE; - cdev_add(&c->cdev, c->devno, 1); + retval = cdev_add(&c->cdev, c->devno, 1); + if (retval < 0) + goto err_free_c; c->iface = iface; c->cfg = cfg; c->channel_id = channel_id; @@ -485,6 +487,7 @@ err_free_kfifo_and_del_list: list_del(&c->list); err_del_cdev_and_free_channel: cdev_del(&c->cdev); +err_free_c: kfree(c); err_remove_ida: ida_simple_remove(&comp.minor_id, current_minor); diff --git a/drivers/staging/most/dim2/Makefile b/drivers/staging/most/dim2/Makefile index 66676f5907ee..6d15f045a767 100644 --- a/drivers/staging/most/dim2/Makefile +++ b/drivers/staging/most/dim2/Makefile @@ -1,4 +1,4 @@ obj-$(CONFIG_MOST_DIM2) += most_dim2.o most_dim2-objs := dim2.o hal.o sysfs.o -ccflags-y += -Idrivers/staging/ +ccflags-y += -I $(srctree)/drivers/staging/ diff --git a/drivers/staging/most/i2c/Makefile b/drivers/staging/most/i2c/Makefile index a7d094c1e1c2..c032fea979b3 100644 --- a/drivers/staging/most/i2c/Makefile +++ b/drivers/staging/most/i2c/Makefile @@ -1,4 +1,4 @@ obj-$(CONFIG_MOST_I2C) += most_i2c.o most_i2c-objs := i2c.o -ccflags-y += -Idrivers/staging/ +ccflags-y += -I $(srctree)/drivers/staging/ diff --git a/drivers/staging/most/net/Makefile b/drivers/staging/most/net/Makefile index 54500aa77be8..820faec6b296 100644 --- a/drivers/staging/most/net/Makefile +++ b/drivers/staging/most/net/Makefile @@ -1,4 +1,4 @@ obj-$(CONFIG_MOST_NET) += most_net.o most_net-objs := net.o -ccflags-y += -Idrivers/staging/ +ccflags-y += -I $(srctree)/drivers/staging/ diff --git a/drivers/staging/most/sound/Makefile b/drivers/staging/most/sound/Makefile index eee8774e38cb..5bb55bb108fb 100644 --- a/drivers/staging/most/sound/Makefile +++ b/drivers/staging/most/sound/Makefile @@ -1,4 +1,4 @@ obj-$(CONFIG_MOST_SOUND) += most_sound.o most_sound-objs := sound.o -ccflags-y += -Idrivers/staging/ +ccflags-y += -I $(srctree)/drivers/staging/ diff --git a/drivers/staging/most/usb/Makefile b/drivers/staging/most/usb/Makefile index 18d28cba4fbf..910cd08bad7c 100644 --- a/drivers/staging/most/usb/Makefile +++ b/drivers/staging/most/usb/Makefile @@ -1,4 +1,4 @@ obj-$(CONFIG_MOST_USB) += most_usb.o most_usb-objs := usb.o -ccflags-y += -Idrivers/staging/ +ccflags-y += -I $(srctree)/drivers/staging/ diff --git a/drivers/staging/most/video/Makefile b/drivers/staging/most/video/Makefile index 1c8e520e02a2..c6e01b6ecfe6 100644 --- a/drivers/staging/most/video/Makefile +++ b/drivers/staging/most/video/Makefile @@ -1,4 +1,4 @@ obj-$(CONFIG_MOST_VIDEO) += most_video.o most_video-objs := video.o -ccflags-y += -Idrivers/staging/ +ccflags-y += -I $(srctree)/drivers/staging/ diff --git a/drivers/staging/mt7621-dma/Kconfig b/drivers/staging/mt7621-dma/Kconfig index 2423c40099d1..b6e48a682c44 100644 --- a/drivers/staging/mt7621-dma/Kconfig +++ b/drivers/staging/mt7621-dma/Kconfig @@ -1,9 +1,3 @@ -config DMA_RALINK - tristate "RALINK DMA support" - depends on RALINK && !SOC_RT288X - select DMA_ENGINE - select DMA_VIRTUAL_CHANNELS - config MTK_HSDMA tristate "MTK HSDMA support" depends on RALINK && SOC_MT7621 diff --git a/drivers/staging/mt7621-dma/Makefile b/drivers/staging/mt7621-dma/Makefile index d3152d45cf45..c9e3e1619ab0 100644 --- a/drivers/staging/mt7621-dma/Makefile +++ b/drivers/staging/mt7621-dma/Makefile @@ -1,4 +1,3 @@ -obj-$(CONFIG_DMA_RALINK) += ralink-gdma.o obj-$(CONFIG_MTK_HSDMA) += mtk-hsdma.o ccflags-y += -I$(srctree)/drivers/dma diff --git a/drivers/staging/mt7621-dma/mtk-hsdma.c b/drivers/staging/mt7621-dma/mtk-hsdma.c index d67a2504adb1..97571f1d697b 100644 --- a/drivers/staging/mt7621-dma/mtk-hsdma.c +++ b/drivers/staging/mt7621-dma/mtk-hsdma.c @@ -1,12 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (C) 2015, Michael Lee <igvtee@gmail.com> * MTK HSDMA support - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * */ #include <linux/dmaengine.h> @@ -191,7 +186,7 @@ static inline u32 mtk_hsdma_read(struct mtk_hsdam_engine *hsdma, u32 reg) } static inline void mtk_hsdma_write(struct mtk_hsdam_engine *hsdma, - unsigned reg, u32 val) + unsigned int reg, u32 val) { writel(val, hsdma->base + reg); } @@ -242,7 +237,7 @@ static void hsdma_dump_desc(struct mtk_hsdam_engine *hsdma, int i; dev_dbg(hsdma->ddev.dev, "tx idx: %d, rx idx: %d\n", - chan->tx_idx, chan->rx_idx); + chan->tx_idx, chan->rx_idx); for (i = 0; i < HSDMA_DESCS_NUM; i++) { tx_desc = &chan->tx_ring[i]; diff --git a/drivers/staging/mt7621-dts/gbpc1.dts b/drivers/staging/mt7621-dts/gbpc1.dts index 6a1699ce9455..b73385540216 100644 --- a/drivers/staging/mt7621-dts/gbpc1.dts +++ b/drivers/staging/mt7621-dts/gbpc1.dts @@ -136,8 +136,8 @@ &pinctrl { state_default: pinctrl0 { gpio { - ralink,group = "wdt", "rgmii2", "uart3"; - ralink,function = "gpio"; + groups = "wdt", "rgmii2", "uart3"; + function = "gpio"; }; }; }; diff --git a/drivers/staging/mt7621-dts/mt7621.dtsi b/drivers/staging/mt7621-dts/mt7621.dtsi index 71f069d59ad8..6aff3680ce4b 100644 --- a/drivers/staging/mt7621-dts/mt7621.dtsi +++ b/drivers/staging/mt7621-dts/mt7621.dtsi @@ -204,82 +204,82 @@ i2c_pins: i2c0 { i2c0 { - group = "i2c"; + groups = "i2c"; function = "i2c"; }; }; spi_pins: spi0 { spi0 { - group = "spi"; + groups = "spi"; function = "spi"; }; }; uart1_pins: uart1 { uart1 { - group = "uart1"; + groups = "uart1"; function = "uart1"; }; }; uart2_pins: uart2 { uart2 { - group = "uart2"; + groups = "uart2"; function = "uart2"; }; }; uart3_pins: uart3 { uart3 { - group = "uart3"; + groups = "uart3"; function = "uart3"; }; }; rgmii1_pins: rgmii1 { rgmii1 { - group = "rgmii1"; + groups = "rgmii1"; function = "rgmii1"; }; }; rgmii2_pins: rgmii2 { rgmii2 { - group = "rgmii2"; + groups = "rgmii2"; function = "rgmii2"; }; }; mdio_pins: mdio0 { mdio0 { - group = "mdio"; + groups = "mdio"; function = "mdio"; }; }; pcie_pins: pcie0 { pcie0 { - group = "pcie"; + groups = "pcie"; function = "pcie rst"; }; }; nand_pins: nand0 { spi-nand { - group = "spi"; + groups = "spi"; function = "nand1"; }; sdhci-nand { - group = "sdhci"; + groups = "sdhci"; function = "nand2"; }; }; sdhci_pins: sdhci0 { sdhci0 { - group = "sdhci"; + groups = "sdhci"; function = "sdhci"; }; }; @@ -420,10 +420,12 @@ status = "disabled"; - resets = <&rstctrl 24 &rstctrl 25 &rstctrl 26>; - reset-names = "pcie0", "pcie1", "pcie2"; + resets = <&rstctrl 23 &rstctrl 24 &rstctrl 25 &rstctrl 26>; + reset-names = "pcie", "pcie0", "pcie1", "pcie2"; clocks = <&clkctrl 24 &clkctrl 25 &clkctrl 26>; clock-names = "pcie0", "pcie1", "pcie2"; + phys = <&pcie0_port>, <&pcie1_port>, <&pcie2_port>; + phy-names = "pcie-phy0", "pcie-phy1", "pcie-phy2"; pcie@0,0 { reg = <0x0000 0 0 0 0>; @@ -449,4 +451,33 @@ bus-range = <0x00 0xff>; }; }; + + pcie0_phy: pcie-phy@1e149000 { + compatible = "mediatek,mt7621-pci-phy"; + reg = <0x1e149000 0x0700>; + #address-cells = <1>; + #size-cells = <0>; + + pcie0_port: pcie-phy@0 { + reg = <0>; + #phy-cells = <0>; + }; + + pcie1_port: pcie-phy@1 { + reg = <1>; + #phy-cells = <0>; + }; + }; + + pcie1_phy: pcie-phy@1e14a000 { + compatible = "mediatek,mt7621-pci-phy"; + reg = <0x1e14a000 0x0700>; + #address-cells = <1>; + #size-cells = <0>; + + pcie2_port: pcie-phy@0 { + reg = <0>; + #phy-cells = <0>; + }; + }; }; diff --git a/drivers/staging/mt7621-eth/ethtool.c b/drivers/staging/mt7621-eth/ethtool.c index 40a7d47be913..8c4228e2c987 100644 --- a/drivers/staging/mt7621-eth/ethtool.c +++ b/drivers/staging/mt7621-eth/ethtool.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; version 2 of the License diff --git a/drivers/staging/mt7621-eth/ethtool.h b/drivers/staging/mt7621-eth/ethtool.h index 40b4cf011660..0071469aea6c 100644 --- a/drivers/staging/mt7621-eth/ethtool.h +++ b/drivers/staging/mt7621-eth/ethtool.h @@ -1,12 +1,5 @@ -/* This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * +/* SPDX-License-Identifier: GPL-2.0 */ +/* * Copyright (C) 2009-2016 John Crispin <blogic@openwrt.org> * Copyright (C) 2009-2016 Felix Fietkau <nbd@openwrt.org> * Copyright (C) 2013-2016 Michael Lee <igvtee@gmail.com> diff --git a/drivers/staging/mt7621-mmc/Kconfig b/drivers/staging/mt7621-mmc/Kconfig index c6dfe8c637dc..1eb79cd6e22f 100644 --- a/drivers/staging/mt7621-mmc/Kconfig +++ b/drivers/staging/mt7621-mmc/Kconfig @@ -1,6 +1,6 @@ config MTK_MMC tristate "MTK SD/MMC" - depends on !MTD_NAND_RALINK && MMC + depends on RALINK && MMC config MTK_AEE_KDUMP bool "MTK AEE KDUMP" diff --git a/drivers/staging/mt7621-mmc/dbg.c b/drivers/staging/mt7621-mmc/dbg.c index eabe0595978b..c7c091fa1da0 100644 --- a/drivers/staging/mt7621-mmc/dbg.c +++ b/drivers/staging/mt7621-mmc/dbg.c @@ -36,7 +36,6 @@ * Inc. */ -#include <linux/version.h> #include <linux/kernel.h> #include <linux/sched.h> #include <linux/kthread.h> diff --git a/drivers/staging/mt7621-mmc/mt6575_sd.h b/drivers/staging/mt7621-mmc/mt6575_sd.h index 4e287c140acb..038a484a9476 100644 --- a/drivers/staging/mt7621-mmc/mt6575_sd.h +++ b/drivers/staging/mt7621-mmc/mt6575_sd.h @@ -363,7 +363,7 @@ enum { #define MSDC_CKGEN_MSDC_DLY_SEL (0x1F << 10) #define MSDC_INT_DAT_LATCH_CK_SEL (0x7 << 7) #define MSDC_CKGEN_MSDC_CK_SEL (0x1 << 6) -#define CARD_READY_FOR_DATA (1 << 8) +#define CARD_READY_FOR_DATA BIT(8) #define CARD_CURRENT_STATE(x) ((x & 0x00001E00) >> 9) /*--------------------------------------------------------------------------*/ diff --git a/drivers/staging/mt7621-pci-phy/Kconfig b/drivers/staging/mt7621-pci-phy/Kconfig new file mode 100644 index 000000000000..b9f6ab784ee8 --- /dev/null +++ b/drivers/staging/mt7621-pci-phy/Kconfig @@ -0,0 +1,7 @@ +config PCI_MT7621_PHY + tristate "MediaTek MT7621 PCI PHY Driver" + depends on RALINK && OF + select GENERIC_PHY + help + Say 'Y' here to add support for MediaTek MT7621 PCI PHY driver, + diff --git a/drivers/staging/mt7621-pci-phy/Makefile b/drivers/staging/mt7621-pci-phy/Makefile new file mode 100644 index 000000000000..a970056f05c1 --- /dev/null +++ b/drivers/staging/mt7621-pci-phy/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_PCI_MT7621_PHY) += pci-mt7621-phy.o diff --git a/drivers/staging/mt7621-pci-phy/TODO b/drivers/staging/mt7621-pci-phy/TODO new file mode 100644 index 000000000000..a255e8f753eb --- /dev/null +++ b/drivers/staging/mt7621-pci-phy/TODO @@ -0,0 +1,4 @@ + +- general code review and cleanup + +Cc: NeilBrown <neil@brown.name> and Sergio Paracuellos <sergio.paracuellos@gmail.com> diff --git a/drivers/staging/mt7621-pci-phy/mediatek,mt7621-pci-phy.txt b/drivers/staging/mt7621-pci-phy/mediatek,mt7621-pci-phy.txt new file mode 100644 index 000000000000..33a8a698bdd0 --- /dev/null +++ b/drivers/staging/mt7621-pci-phy/mediatek,mt7621-pci-phy.txt @@ -0,0 +1,54 @@ +Mediatek Mt7621 PCIe PHY + +Required properties: +- compatible: must be "mediatek,mt7621-pci-phy" +- reg: base address and length of the PCIe PHY block +- #address-cells: must be 1 +- #size-cells: must be 0 + +Each PCIe PHY should be represented by a child node + +Required properties For the child node: +- reg: the PHY ID +0 - PCIe RC 0 +1 - PCIe RC 1 +- #phy-cells: must be 0 + +Example: + pcie0_phy: pcie-phy@1a149000 { + compatible = "mediatek,mt7621-pci-phy"; + reg = <0x1a149000 0x0700>; + #address-cells = <1>; + #size-cells = <0>; + + pcie0_port: pcie-phy@0 { + reg = <0>; + #phy-cells = <0>; + }; + + pcie1_port: pcie-phy@1 { + reg = <1>; + #phy-cells = <0>; + }; + }; + + pcie1_phy: pcie-phy@1a14a000 { + compatible = "mediatek,mt7621-pci-phy"; + reg = <0x1a14a000 0x0700>; + #address-cells = <1>; + #size-cells = <0>; + + pcie2_port: pcie-phy@0 { + reg = <0>; + #phy-cells = <0>; + }; + }; + + /* users of the PCIe phy */ + + pcie: pcie@1e140000 { + ... + ... + phys = <&pcie0_port>, <&pcie1_port>, <&pcie2_port>; + phy-names = "pcie-phy0", "pcie-phy1", "pcie-phy2"; + };
\ No newline at end of file diff --git a/drivers/staging/mt7621-pci-phy/pci-mt7621-phy.c b/drivers/staging/mt7621-pci-phy/pci-mt7621-phy.c new file mode 100644 index 000000000000..d3ca2f019112 --- /dev/null +++ b/drivers/staging/mt7621-pci-phy/pci-mt7621-phy.c @@ -0,0 +1,387 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Mediatek MT7621 PCI PHY Driver + * Author: Sergio Paracuellos <sergio.paracuellos@gmail.com> + */ + +#include <dt-bindings/phy/phy.h> +#include <linux/bitops.h> +#include <linux/module.h> +#include <linux/of_address.h> +#include <linux/of_device.h> +#include <linux/phy/phy.h> +#include <linux/platform_device.h> +#include <mt7621.h> +#include <ralink_regs.h> + +#define RALINK_CLKCFG1 0x30 +#define CHIP_REV_MT7621_E2 0x0101 + +#define PCIE_PORT_CLK_EN(x) BIT(24 + (x)) + +#define RG_PE1_PIPE_REG 0x02c +#define RG_PE1_PIPE_RST BIT(12) +#define RG_PE1_PIPE_CMD_FRC BIT(4) + +#define RG_P0_TO_P1_WIDTH 0x100 +#define RG_PE1_H_LCDDS_REG 0x49c +#define RG_PE1_H_LCDDS_PCW GENMASK(30, 0) +#define RG_PE1_H_LCDDS_PCW_VAL(x) ((0x7fffffff & (x)) << 0) + +#define RG_PE1_FRC_H_XTAL_REG 0x400 +#define RG_PE1_FRC_H_XTAL_TYPE BIT(8) +#define RG_PE1_H_XTAL_TYPE GENMASK(10, 9) +#define RG_PE1_H_XTAL_TYPE_VAL(x) ((0x3 & (x)) << 9) + +#define RG_PE1_FRC_PHY_REG 0x000 +#define RG_PE1_FRC_PHY_EN BIT(4) +#define RG_PE1_PHY_EN BIT(5) + +#define RG_PE1_H_PLL_REG 0x490 +#define RG_PE1_H_PLL_BC GENMASK(23, 22) +#define RG_PE1_H_PLL_BC_VAL(x) ((0x3 & (x)) << 22) +#define RG_PE1_H_PLL_BP GENMASK(21, 18) +#define RG_PE1_H_PLL_BP_VAL(x) ((0xf & (x)) << 18) +#define RG_PE1_H_PLL_IR GENMASK(15, 12) +#define RG_PE1_H_PLL_IR_VAL(x) ((0xf & (x)) << 12) +#define RG_PE1_H_PLL_IC GENMASK(11, 8) +#define RG_PE1_H_PLL_IC_VAL(x) ((0xf & (x)) << 8) +#define RG_PE1_H_PLL_PREDIV GENMASK(7, 6) +#define RG_PE1_H_PLL_PREDIV_VAL(x) ((0x3 & (x)) << 6) +#define RG_PE1_PLL_DIVEN GENMASK(3, 1) +#define RG_PE1_PLL_DIVEN_VAL(x) ((0x7 & (x)) << 1) + +#define RG_PE1_H_PLL_FBKSEL_REG 0x4bc +#define RG_PE1_H_PLL_FBKSEL GENMASK(5, 4) +#define RG_PE1_H_PLL_FBKSEL_VAL(x) ((0x3 & (x)) << 4) + +#define RG_PE1_H_LCDDS_SSC_PRD_REG 0x4a4 +#define RG_PE1_H_LCDDS_SSC_PRD GENMASK(15, 0) +#define RG_PE1_H_LCDDS_SSC_PRD_VAL(x) ((0xffff & (x)) << 0) + +#define RG_PE1_H_LCDDS_SSC_DELTA_REG 0x4a8 +#define RG_PE1_H_LCDDS_SSC_DELTA GENMASK(11, 0) +#define RG_PE1_H_LCDDS_SSC_DELTA_VAL(x) ((0xfff & (x)) << 0) +#define RG_PE1_H_LCDDS_SSC_DELTA1 GENMASK(27, 16) +#define RG_PE1_H_LCDDS_SSC_DELTA1_VAL(x) ((0xff & (x)) << 16) + +#define RG_PE1_LCDDS_CLK_PH_INV_REG 0x4a0 +#define RG_PE1_LCDDS_CLK_PH_INV BIT(5) + +#define RG_PE1_H_PLL_BR_REG 0x4ac +#define RG_PE1_H_PLL_BR GENMASK(18, 16) +#define RG_PE1_H_PLL_BR_VAL(x) ((0x7 & (x)) << 16) + +#define RG_PE1_MSTCKDIV_REG 0x414 +#define RG_PE1_MSTCKDIV GENMASK(7, 6) +#define RG_PE1_MSTCKDIV_VAL(x) ((0x3 & (x)) << 6) + +#define RG_PE1_FRC_MSTCKDIV BIT(5) + +/** + * struct mt7621_pci_phy_instance - Mt7621 Pcie PHY device + * @phy: pointer to the kernel PHY device + * @port_base: base register + * @index: internal ID to identify the Mt7621 PCIe PHY + */ +struct mt7621_pci_phy_instance { + struct phy *phy; + void __iomem *port_base; + u32 index; +}; + +/** + * struct mt7621_pci_phy - Mt7621 Pcie PHY core + * @dev: pointer to device + * @phys: pointer to Mt7621 PHY device + * @nphys: number of PHY devices for this core + */ +struct mt7621_pci_phy { + struct device *dev; + struct mt7621_pci_phy_instance **phys; + int nphys; +}; + +static inline u32 phy_read(struct mt7621_pci_phy_instance *instance, u32 reg) +{ + return readl(instance->port_base + reg); +} + +static inline void phy_write(struct mt7621_pci_phy_instance *instance, + u32 val, u32 reg) +{ + writel(val, instance->port_base + reg); +} + +static void mt7621_bypass_pipe_rst(struct mt7621_pci_phy *phy, + struct mt7621_pci_phy_instance *instance) +{ + u32 offset = (instance->index != 1) ? + RG_PE1_PIPE_REG : RG_PE1_PIPE_REG + RG_P0_TO_P1_WIDTH; + u32 reg; + + reg = phy_read(instance, offset); + reg &= ~(RG_PE1_PIPE_RST | RG_PE1_PIPE_CMD_FRC); + reg |= (RG_PE1_PIPE_RST | RG_PE1_PIPE_CMD_FRC); + phy_write(instance, reg, offset); +} + +static void mt7621_set_phy_for_ssc(struct mt7621_pci_phy *phy, + struct mt7621_pci_phy_instance *instance) +{ + struct device *dev = phy->dev; + u32 reg = rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG0); + u32 offset; + u32 val; + + reg = (reg >> 6) & 0x7; + /* Set PCIe Port PHY to disable SSC */ + /* Debug Xtal Type */ + val = phy_read(instance, RG_PE1_FRC_H_XTAL_REG); + val &= ~(RG_PE1_FRC_H_XTAL_TYPE | RG_PE1_H_XTAL_TYPE); + val |= RG_PE1_FRC_H_XTAL_TYPE; + val |= RG_PE1_H_XTAL_TYPE_VAL(0x00); + phy_write(instance, val, RG_PE1_FRC_H_XTAL_REG); + + /* disable port */ + offset = (instance->index != 1) ? + RG_PE1_FRC_PHY_REG : RG_PE1_FRC_PHY_REG + RG_P0_TO_P1_WIDTH; + val = phy_read(instance, offset); + val &= ~(RG_PE1_FRC_PHY_EN | RG_PE1_PHY_EN); + val |= RG_PE1_FRC_PHY_EN; + phy_write(instance, val, offset); + + /* Set Pre-divider ratio (for host mode) */ + val = phy_read(instance, RG_PE1_H_PLL_REG); + val &= ~(RG_PE1_H_PLL_PREDIV); + + if (reg <= 5 && reg >= 3) { /* 40MHz Xtal */ + val |= RG_PE1_H_PLL_PREDIV_VAL(0x01); + phy_write(instance, val, RG_PE1_H_PLL_REG); + dev_info(dev, "Xtal is 40MHz\n"); + } else { /* 25MHz | 20MHz Xtal */ + val |= RG_PE1_H_PLL_PREDIV_VAL(0x00); + phy_write(instance, val, RG_PE1_H_PLL_REG); + if (reg >= 6) { + dev_info(dev, "Xtal is 25MHz\n"); + + /* Select feedback clock */ + val = phy_read(instance, RG_PE1_H_PLL_FBKSEL_REG); + val &= ~(RG_PE1_H_PLL_FBKSEL); + val |= RG_PE1_H_PLL_FBKSEL_VAL(0x01); + phy_write(instance, val, RG_PE1_H_PLL_FBKSEL_REG); + + /* DDS NCPO PCW (for host mode) */ + val = phy_read(instance, RG_PE1_H_LCDDS_SSC_PRD_REG); + val &= ~(RG_PE1_H_LCDDS_SSC_PRD); + val |= RG_PE1_H_LCDDS_SSC_PRD_VAL(0x18000000); + phy_write(instance, val, RG_PE1_H_LCDDS_SSC_PRD_REG); + + /* DDS SSC dither period control */ + val = phy_read(instance, RG_PE1_H_LCDDS_SSC_PRD_REG); + val &= ~(RG_PE1_H_LCDDS_SSC_PRD); + val |= RG_PE1_H_LCDDS_SSC_PRD_VAL(0x18d); + phy_write(instance, val, RG_PE1_H_LCDDS_SSC_PRD_REG); + + /* DDS SSC dither amplitude control */ + val = phy_read(instance, RG_PE1_H_LCDDS_SSC_DELTA_REG); + val &= ~(RG_PE1_H_LCDDS_SSC_DELTA | + RG_PE1_H_LCDDS_SSC_DELTA1); + val |= RG_PE1_H_LCDDS_SSC_DELTA_VAL(0x4a); + val |= RG_PE1_H_LCDDS_SSC_DELTA1_VAL(0x4a); + phy_write(instance, val, RG_PE1_H_LCDDS_SSC_DELTA_REG); + } else { + dev_info(dev, "Xtal is 20MHz\n"); + } + } + + /* DDS clock inversion */ + val = phy_read(instance, RG_PE1_LCDDS_CLK_PH_INV_REG); + val &= ~(RG_PE1_LCDDS_CLK_PH_INV); + val |= RG_PE1_LCDDS_CLK_PH_INV; + phy_write(instance, val, RG_PE1_LCDDS_CLK_PH_INV_REG); + + /* Set PLL bits */ + val = phy_read(instance, RG_PE1_H_PLL_REG); + val &= ~(RG_PE1_H_PLL_BC | RG_PE1_H_PLL_BP | RG_PE1_H_PLL_IR | + RG_PE1_H_PLL_IC | RG_PE1_PLL_DIVEN); + val |= RG_PE1_H_PLL_BC_VAL(0x02); + val |= RG_PE1_H_PLL_BP_VAL(0x06); + val |= RG_PE1_H_PLL_IR_VAL(0x02); + val |= RG_PE1_H_PLL_IC_VAL(0x01); + val |= RG_PE1_PLL_DIVEN_VAL(0x02); + phy_write(instance, val, RG_PE1_H_PLL_REG); + + val = phy_read(instance, RG_PE1_H_PLL_BR_REG); + val &= ~(RG_PE1_H_PLL_BR); + val |= RG_PE1_H_PLL_BR_VAL(0x00); + phy_write(instance, val, RG_PE1_H_PLL_BR_REG); + + if (reg <= 5 && reg >= 3) { /* 40MHz Xtal */ + /* set force mode enable of da_pe1_mstckdiv */ + val = phy_read(instance, RG_PE1_MSTCKDIV_REG); + val &= ~(RG_PE1_MSTCKDIV | RG_PE1_FRC_MSTCKDIV); + val |= (RG_PE1_MSTCKDIV_VAL(0x01) | RG_PE1_FRC_MSTCKDIV); + phy_write(instance, val, RG_PE1_MSTCKDIV_REG); + } +} + +static int mt7621_pci_phy_init(struct phy *phy) +{ + struct mt7621_pci_phy_instance *instance = phy_get_drvdata(phy); + struct mt7621_pci_phy *mphy = dev_get_drvdata(phy->dev.parent); + u32 chip_rev_id = rt_sysc_r32(SYSC_REG_CHIP_REV); + + if ((chip_rev_id & 0xFFFF) == CHIP_REV_MT7621_E2) + mt7621_bypass_pipe_rst(mphy, instance); + + mt7621_set_phy_for_ssc(mphy, instance); + + return 0; +} + +static int mt7621_pci_phy_power_on(struct phy *phy) +{ + struct mt7621_pci_phy_instance *instance = phy_get_drvdata(phy); + u32 offset = (instance->index != 1) ? + RG_PE1_FRC_PHY_REG : RG_PE1_FRC_PHY_REG + RG_P0_TO_P1_WIDTH; + u32 val; + + /* Enable PHY and disable force mode */ + val = phy_read(instance, offset); + val &= ~(RG_PE1_FRC_PHY_EN | RG_PE1_PHY_EN); + val |= (RG_PE1_FRC_PHY_EN | RG_PE1_PHY_EN); + phy_write(instance, val, offset); + + return 0; +} + +static int mt7621_pci_phy_power_off(struct phy *phy) +{ + struct mt7621_pci_phy_instance *instance = phy_get_drvdata(phy); + u32 offset = (instance->index != 1) ? + RG_PE1_FRC_PHY_REG : RG_PE1_FRC_PHY_REG + RG_P0_TO_P1_WIDTH; + u32 val; + + /* Disable PHY */ + val = phy_read(instance, offset); + val &= ~(RG_PE1_FRC_PHY_EN | RG_PE1_PHY_EN); + val |= RG_PE1_FRC_PHY_EN; + phy_write(instance, val, offset); + + return 0; +} + +static int mt7621_pci_phy_exit(struct phy *phy) +{ + struct mt7621_pci_phy_instance *instance = phy_get_drvdata(phy); + + rt_sysc_m32(PCIE_PORT_CLK_EN(instance->index), 0, RALINK_CLKCFG1); + + return 0; +} + +static const struct phy_ops mt7621_pci_phy_ops = { + .init = mt7621_pci_phy_init, + .exit = mt7621_pci_phy_exit, + .power_on = mt7621_pci_phy_power_on, + .power_off = mt7621_pci_phy_power_off, + .owner = THIS_MODULE, +}; + +static int mt7621_pci_phy_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + struct device_node *child_np; + struct phy_provider *provider; + struct mt7621_pci_phy *phy; + struct resource res; + int port, ret; + void __iomem *port_base; + + phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL); + if (!phy) + return -ENOMEM; + + phy->nphys = of_get_child_count(np); + phy->phys = devm_kcalloc(dev, phy->nphys, + sizeof(*phy->phys), GFP_KERNEL); + if (!phy->phys) + return -ENOMEM; + + phy->dev = dev; + platform_set_drvdata(pdev, phy); + + ret = of_address_to_resource(np, 0, &res); + if (ret) { + dev_err(dev, "failed to get address resource(id-%d)\n", port); + return ret; + } + + port_base = devm_ioremap_resource(dev, &res); + if (IS_ERR(port_base)) { + dev_err(dev, "failed to remap phy regs\n"); + return PTR_ERR(port_base); + } + + port = 0; + for_each_child_of_node(np, child_np) { + struct mt7621_pci_phy_instance *instance; + struct phy *pphy; + + instance = devm_kzalloc(dev, sizeof(*instance), GFP_KERNEL); + if (!instance) { + ret = -ENOMEM; + goto put_child; + } + + phy->phys[port] = instance; + + pphy = devm_phy_create(dev, child_np, &mt7621_pci_phy_ops); + if (IS_ERR(phy)) { + dev_err(dev, "failed to create phy\n"); + ret = PTR_ERR(phy); + goto put_child; + } + + instance->port_base = port_base; + instance->phy = pphy; + instance->index = port; + phy_set_drvdata(pphy, instance); + port++; + } + + provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); + + return PTR_ERR_OR_ZERO(provider); + +put_child: + of_node_put(child_np); + return ret; +} + +static const struct of_device_id mt7621_pci_phy_ids[] = { + { .compatible = "mediatek,mt7621-pci-phy" }, + {}, +}; +MODULE_DEVICE_TABLE(of, mt7621_pci_ids); + +static struct platform_driver mt7621_pci_phy_driver = { + .probe = mt7621_pci_phy_probe, + .driver = { + .name = "mt7621-pci-phy", + .of_match_table = of_match_ptr(mt7621_pci_phy_ids), + }, +}; + +static int __init mt7621_pci_phy_drv_init(void) +{ + return platform_driver_register(&mt7621_pci_phy_driver); +} + +module_init(mt7621_pci_phy_drv_init); + +MODULE_AUTHOR("Sergio Paracuellos <sergio.paracuellos@gmail.com>"); +MODULE_DESCRIPTION("MediaTek MT7621 PCIe PHY driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/mt7621-pci/Makefile b/drivers/staging/mt7621-pci/Makefile index 607b84bedcc3..d4655a726b61 100644 --- a/drivers/staging/mt7621-pci/Makefile +++ b/drivers/staging/mt7621-pci/Makefile @@ -1 +1 @@ -obj-$(CONFIG_SOC_MT7621) += pci-mt7621.o +obj-$(CONFIG_PCI_MT7621) += pci-mt7621.o diff --git a/drivers/staging/mt7621-pci/TODO b/drivers/staging/mt7621-pci/TODO index cf30f629b9fd..ccfd266db4ca 100644 --- a/drivers/staging/mt7621-pci/TODO +++ b/drivers/staging/mt7621-pci/TODO @@ -1,12 +1,4 @@ - general code review and cleanup -- can this be converted to not require PCI_DRIVERS_LEGACY ?? - The irq returned by pcibios_map_irq is a "hwirq" (hardware irq number) - and pci_assign_irq() assigns this directly to dev->irq, which - expects a "virq" (virtual irq number). These numbers are different - on MIPS. There is a gross hack to make it work on one - specific platform, so it can be tested. -- Should this be merged with arch/mips/pci/pci-mt7620.c ?? -- ensure device-tree requirements are documented Cc: NeilBrown <neil@brown.name> diff --git a/drivers/staging/mt7621-pci/pci-mt7621.c b/drivers/staging/mt7621-pci/pci-mt7621.c index 31310b6fb7db..379ae780c691 100644 --- a/drivers/staging/mt7621-pci/pci-mt7621.c +++ b/drivers/staging/mt7621-pci/pci-mt7621.c @@ -25,6 +25,7 @@ #include <linux/of_pci.h> #include <linux/of_platform.h> #include <linux/pci.h> +#include <linux/phy/phy.h> #include <linux/platform_device.h> #include <linux/reset.h> #include <mt7621.h> @@ -34,13 +35,8 @@ /* sysctl */ #define MT7621_CHIP_REV_ID 0x0c -#define RALINK_CLKCFG1 0x30 -#define RALINK_RSTCTRL 0x34 #define CHIP_REV_MT7621_E2 0x0101 -/* RALINK_RSTCTRL bits */ -#define RALINK_PCIE_RST BIT(23) - /* MediaTek specific configuration registers */ #define PCIE_FTS_NUM 0x70c #define PCIE_FTS_NUM_MASK GENMASK(15, 8) @@ -90,81 +86,16 @@ #define PCIE_CLK_GEN_EN BIT(31) #define PCIE_CLK_GEN_DIS 0 -#define PCIE_CLK_GEN1_DIS GENMASK(30,24) +#define PCIE_CLK_GEN1_DIS GENMASK(30, 24) #define PCIE_CLK_GEN1_EN (BIT(27) | BIT(25)) -#define RALINK_PCI_IO_MAP_BASE 0x1e160000 #define MEMORY_BASE 0x0 -/* pcie phy related macros */ -#define RALINK_PCIEPHY_P0P1_CTL_OFFSET 0x9000 -#define RALINK_PCIEPHY_P2_CTL_OFFSET 0xA000 - -#define RG_P0_TO_P1_WIDTH 0x100 - -#define RG_PE1_PIPE_REG 0x02c -#define RG_PE1_PIPE_RST BIT(12) -#define RG_PE1_PIPE_CMD_FRC BIT(4) - -#define RG_PE1_H_LCDDS_REG 0x49c -#define RG_PE1_H_LCDDS_PCW GENMASK(30, 0) -#define RG_PE1_H_LCDDS_PCW_VAL(x) ((0x7fffffff & (x)) << 0) - -#define RG_PE1_FRC_H_XTAL_REG 0x400 -#define RG_PE1_FRC_H_XTAL_TYPE BIT(8) -#define RG_PE1_H_XTAL_TYPE GENMASK(10, 9) -#define RG_PE1_H_XTAL_TYPE_VAL(x) ((0x3 & (x)) << 9) - -#define RG_PE1_FRC_PHY_REG 0x000 -#define RG_PE1_FRC_PHY_EN BIT(4) -#define RG_PE1_PHY_EN BIT(5) - -#define RG_PE1_H_PLL_REG 0x490 -#define RG_PE1_H_PLL_BC GENMASK(23, 22) -#define RG_PE1_H_PLL_BC_VAL(x) ((0x3 & (x)) << 22) -#define RG_PE1_H_PLL_BP GENMASK(21, 18) -#define RG_PE1_H_PLL_BP_VAL(x) ((0xf & (x)) << 18) -#define RG_PE1_H_PLL_IR GENMASK(15, 12) -#define RG_PE1_H_PLL_IR_VAL(x) ((0xf & (x)) << 12) -#define RG_PE1_H_PLL_IC GENMASK(11, 8) -#define RG_PE1_H_PLL_IC_VAL(x) ((0xf & (x)) << 8) -#define RG_PE1_H_PLL_PREDIV GENMASK(7, 6) -#define RG_PE1_H_PLL_PREDIV_VAL(x) ((0x3 & (x)) << 6) -#define RG_PE1_PLL_DIVEN GENMASK(3, 1) -#define RG_PE1_PLL_DIVEN_VAL(x) ((0x7 & (x)) << 1) - -#define RG_PE1_H_PLL_FBKSEL_REG 0x4bc -#define RG_PE1_H_PLL_FBKSEL GENMASK(5, 4) -#define RG_PE1_H_PLL_FBKSEL_VAL(x) ((0x3 & (x)) << 4) - -#define RG_PE1_H_LCDDS_SSC_PRD_REG 0x4a4 -#define RG_PE1_H_LCDDS_SSC_PRD GENMASK(15, 0) -#define RG_PE1_H_LCDDS_SSC_PRD_VAL(x) ((0xffff & (x)) << 0) - -#define RG_PE1_H_LCDDS_SSC_DELTA_REG 0x4a8 -#define RG_PE1_H_LCDDS_SSC_DELTA GENMASK(11, 0) -#define RG_PE1_H_LCDDS_SSC_DELTA_VAL(x) ((0xfff & (x)) << 0) -#define RG_PE1_H_LCDDS_SSC_DELTA1 GENMASK(27, 16) -#define RG_PE1_H_LCDDS_SSC_DELTA1_VAL(x) ((0xff & (x)) << 16) - -#define RG_PE1_LCDDS_CLK_PH_INV_REG 0x4a0 -#define RG_PE1_LCDDS_CLK_PH_INV BIT(5) - -#define RG_PE1_H_PLL_BR_REG 0x4ac -#define RG_PE1_H_PLL_BR GENMASK(18, 16) -#define RG_PE1_H_PLL_BR_VAL(x) ((0x7 & (x)) << 16) - -#define RG_PE1_MSTCKDIV_REG 0x414 -#define RG_PE1_MSTCKDIV GENMASK(7, 6) -#define RG_PE1_MSTCKDIV_VAL(x) ((0x3 & (x)) << 6) - -#define RG_PE1_FRC_MSTCKDIV BIT(5) - /** * struct mt7621_pcie_port - PCIe port information * @base: I/O mapped register base * @list: port list * @pcie: pointer to PCIe host info - * @phy_reg_offset: offset to related phy registers + * @phy: pointer to PHY control block * @pcie_rst: pointer to port reset control * @slot: port slot * @enabled: indicates if port is enabled @@ -173,7 +104,7 @@ struct mt7621_pcie_port { void __iomem *base; struct list_head list; struct mt7621_pcie *pcie; - u32 phy_reg_offset; + struct phy *phy; struct reset_control *pcie_rst; u32 slot; bool enabled; @@ -188,6 +119,7 @@ struct mt7621_pcie_port { * @offset: IO / Memory offset * @dev: Pointer to PCIe device * @ports: pointer to PCIe port information + * @rst: pointer to pcie reset */ struct mt7621_pcie { void __iomem *base; @@ -200,6 +132,7 @@ struct mt7621_pcie { resource_size_t io; } offset; struct list_head ports; + struct reset_control *rst; }; static inline u32 pcie_read(struct mt7621_pcie *pcie, u32 reg) @@ -265,150 +198,6 @@ static void write_config(struct mt7621_pcie *pcie, unsigned int dev, pcie_write(pcie, val, RALINK_PCI_CONFIG_DATA); } -static void bypass_pipe_rst(struct mt7621_pcie_port *port) -{ - struct mt7621_pcie *pcie = port->pcie; - u32 phy_offset = port->phy_reg_offset; - u32 offset = (port->slot != 1) ? - phy_offset + RG_PE1_PIPE_REG : - phy_offset + RG_PE1_PIPE_REG + RG_P0_TO_P1_WIDTH; - u32 reg = pcie_read(pcie, offset); - - reg &= ~(RG_PE1_PIPE_RST | RG_PE1_PIPE_CMD_FRC); - reg |= (RG_PE1_PIPE_RST | RG_PE1_PIPE_CMD_FRC); - pcie_write(pcie, reg, offset); -} - -static void set_phy_for_ssc(struct mt7621_pcie_port *port) -{ - struct mt7621_pcie *pcie = port->pcie; - struct device *dev = pcie->dev; - u32 phy_offset = port->phy_reg_offset; - u32 reg = rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG0); - u32 offset; - u32 val; - - reg = (reg >> 6) & 0x7; - /* Set PCIe Port PHY to disable SSC */ - /* Debug Xtal Type */ - offset = phy_offset + RG_PE1_FRC_H_XTAL_REG; - val = pcie_read(pcie, offset); - val &= ~(RG_PE1_FRC_H_XTAL_TYPE | RG_PE1_H_XTAL_TYPE); - val |= RG_PE1_FRC_H_XTAL_TYPE; - val |= RG_PE1_H_XTAL_TYPE_VAL(0x00); - pcie_write(pcie, val, offset); - - /* disable port */ - offset = (port->slot != 1) ? - phy_offset + RG_PE1_FRC_PHY_REG : - phy_offset + RG_PE1_FRC_PHY_REG + RG_P0_TO_P1_WIDTH; - val = pcie_read(pcie, offset); - val &= ~(RG_PE1_FRC_PHY_EN | RG_PE1_PHY_EN); - val |= RG_PE1_FRC_PHY_EN; - pcie_write(pcie, val, offset); - - /* Set Pre-divider ratio (for host mode) */ - offset = phy_offset + RG_PE1_H_PLL_REG; - val = pcie_read(pcie, offset); - val &= ~(RG_PE1_H_PLL_PREDIV); - - if (reg <= 5 && reg >= 3) { /* 40MHz Xtal */ - val |= RG_PE1_H_PLL_PREDIV_VAL(0x01); - pcie_write(pcie, val, offset); - dev_info(dev, "Xtal is 40MHz\n"); - } else { /* 25MHz | 20MHz Xtal */ - val |= RG_PE1_H_PLL_PREDIV_VAL(0x00); - pcie_write(pcie, val, offset); - if (reg >= 6) { - dev_info(dev, "Xtal is 25MHz\n"); - - /* Select feedback clock */ - offset = phy_offset + RG_PE1_H_PLL_FBKSEL_REG; - val = pcie_read(pcie, offset); - val &= ~(RG_PE1_H_PLL_FBKSEL); - val |= RG_PE1_H_PLL_FBKSEL_VAL(0x01); - pcie_write(pcie, val, offset); - - /* DDS NCPO PCW (for host mode) */ - offset = phy_offset + RG_PE1_H_LCDDS_SSC_PRD_REG; - val = pcie_read(pcie, offset); - val &= ~(RG_PE1_H_LCDDS_SSC_PRD); - val |= RG_PE1_H_LCDDS_SSC_PRD_VAL(0x18000000); - pcie_write(pcie, val, offset); - - /* DDS SSC dither period control */ - offset = phy_offset + RG_PE1_H_LCDDS_SSC_PRD_REG; - val = pcie_read(pcie, offset); - val &= ~(RG_PE1_H_LCDDS_SSC_PRD); - val |= RG_PE1_H_LCDDS_SSC_PRD_VAL(0x18d); - pcie_write(pcie, val, offset); - - /* DDS SSC dither amplitude control */ - offset = phy_offset + RG_PE1_H_LCDDS_SSC_DELTA_REG; - val = pcie_read(pcie, offset); - val &= ~(RG_PE1_H_LCDDS_SSC_DELTA | - RG_PE1_H_LCDDS_SSC_DELTA1); - val |= RG_PE1_H_LCDDS_SSC_DELTA_VAL(0x4a); - val |= RG_PE1_H_LCDDS_SSC_DELTA1_VAL(0x4a); - pcie_write(pcie, val, offset); - } else { - dev_info(dev, "Xtal is 20MHz\n"); - } - } - - /* DDS clock inversion */ - offset = phy_offset + RG_PE1_LCDDS_CLK_PH_INV_REG; - val = pcie_read(pcie, offset); - val &= ~(RG_PE1_LCDDS_CLK_PH_INV); - val |= RG_PE1_LCDDS_CLK_PH_INV; - pcie_write(pcie, val, offset); - - /* Set PLL bits */ - offset = phy_offset + RG_PE1_H_PLL_REG; - val = pcie_read(pcie, offset); - val &= ~(RG_PE1_H_PLL_BC | RG_PE1_H_PLL_BP | RG_PE1_H_PLL_IR | - RG_PE1_H_PLL_IC | RG_PE1_PLL_DIVEN); - val |= RG_PE1_H_PLL_BC_VAL(0x02); - val |= RG_PE1_H_PLL_BP_VAL(0x06); - val |= RG_PE1_H_PLL_IR_VAL(0x02); - val |= RG_PE1_H_PLL_IC_VAL(0x01); - val |= RG_PE1_PLL_DIVEN_VAL(0x02); - pcie_write(pcie, val, offset); - - offset = phy_offset + RG_PE1_H_PLL_BR_REG; - val = pcie_read(pcie, offset); - val &= ~(RG_PE1_H_PLL_BR); - val |= RG_PE1_H_PLL_BR_VAL(0x00); - pcie_write(pcie, val, offset); - - if (reg <= 5 && reg >= 3) { /* 40MHz Xtal */ - /* set force mode enable of da_pe1_mstckdiv */ - offset = phy_offset + RG_PE1_MSTCKDIV_REG; - val = pcie_read(pcie, offset); - val &= ~(RG_PE1_MSTCKDIV | RG_PE1_FRC_MSTCKDIV); - val |= (RG_PE1_MSTCKDIV_VAL(0x01) | RG_PE1_FRC_MSTCKDIV); - pcie_write(pcie, val, offset); - } - - /* Enable PHY and disable force mode */ - offset = (port->slot != 1) ? - phy_offset + RG_PE1_FRC_PHY_REG : - phy_offset + RG_PE1_FRC_PHY_REG + RG_P0_TO_P1_WIDTH; - val = pcie_read(pcie, offset); - val &= ~(RG_PE1_FRC_PHY_EN | RG_PE1_PHY_EN); - val |= (RG_PE1_FRC_PHY_EN | RG_PE1_PHY_EN); - pcie_write(pcie, val, offset); -} - -static void mt7621_enable_phy(struct mt7621_pcie_port *port) -{ - u32 chip_rev_id = rt_sysc_r32(MT7621_CHIP_REV_ID); - - if ((chip_rev_id & 0xFFFF) == CHIP_REV_MT7621_E2) - bypass_pipe_rst(port); - set_phy_for_ssc(port); -} - static inline void mt7621_control_assert(struct mt7621_pcie_port *port) { u32 chip_rev_id = rt_sysc_r32(MT7621_CHIP_REV_ID); @@ -510,7 +299,7 @@ static int mt7621_pcie_parse_port(struct mt7621_pcie *pcie, struct device *dev = pcie->dev; struct device_node *pnode = dev->of_node; struct resource regs; - char name[6]; + char name[10]; int err; port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL); @@ -534,11 +323,13 @@ static int mt7621_pcie_parse_port(struct mt7621_pcie *pcie, return PTR_ERR(port->pcie_rst); } + snprintf(name, sizeof(name), "pcie-phy%d", slot); + port->phy = devm_phy_get(dev, name); + if (IS_ERR(port->phy)) + return PTR_ERR(port->phy); + port->slot = slot; port->pcie = pcie; - port->phy_reg_offset = (slot != 2) ? - RALINK_PCIEPHY_P0P1_CTL_OFFSET : - RALINK_PCIEPHY_P2_CTL_OFFSET; INIT_LIST_HEAD(&port->list); list_add_tail(&port->list, &pcie->ports); @@ -563,6 +354,12 @@ static int mt7621_pcie_parse_dt(struct mt7621_pcie *pcie) if (IS_ERR(pcie->base)) return PTR_ERR(pcie->base); + pcie->rst = devm_reset_control_get_exclusive(dev, "pcie"); + if (PTR_ERR(pcie->rst) == -EPROBE_DEFER) { + dev_err(dev, "failed to get pcie reset control\n"); + return PTR_ERR(pcie->rst); + } + for_each_available_child_of_node(node, child) { int slot; @@ -588,6 +385,7 @@ static int mt7621_pcie_init_port(struct mt7621_pcie_port *port) struct device *dev = pcie->dev; u32 slot = port->slot; u32 val = 0; + int err; /* * Any MT7621 Ralink pcie controller that doesn't have 0x0101 at @@ -598,18 +396,36 @@ static int mt7621_pcie_init_port(struct mt7621_pcie_port *port) val = read_config(pcie, slot, PCIE_FTS_NUM); dev_info(dev, "Port %d N_FTS = %x\n", (unsigned int)val, slot); + err = phy_init(port->phy); + if (err) { + dev_err(dev, "failed to initialize port%d phy\n", slot); + goto err_phy_init; + } + + err = phy_power_on(port->phy); + if (err) { + dev_err(dev, "failed to power on port%d phy\n", slot); + goto err_phy_on; + } + if ((pcie_port_read(port, RALINK_PCI_STATUS) & PCIE_PORT_LINKUP) == 0) { dev_err(dev, "pcie%d no card, disable it (RST & CLK)\n", slot); mt7621_control_assert(port); - rt_sysc_m32(PCIE_PORT_CLK_EN(slot), 0, RALINK_CLKCFG1); port->enabled = false; - } else { - port->enabled = true; + err = -ENODEV; + goto err_no_link_up; } - mt7621_enable_phy(port); + port->enabled = true; return 0; + +err_no_link_up: + phy_power_off(port->phy); +err_phy_on: + phy_exit(port->phy); +err_phy_init: + return err; } static void mt7621_pcie_init_ports(struct mt7621_pcie *pcie) @@ -628,13 +444,13 @@ static void mt7621_pcie_init_ports(struct mt7621_pcie *pcie) } } - rt_sysc_m32(0, RALINK_PCIE_RST, RALINK_RSTCTRL); + reset_control_assert(pcie->rst); rt_sysc_m32(0x30, 2 << 4, SYSC_REG_SYSTEM_CONFIG1); rt_sysc_m32(PCIE_CLK_GEN_EN, PCIE_CLK_GEN_DIS, RALINK_PCIE_CLK_GEN); rt_sysc_m32(PCIE_CLK_GEN1_DIS, PCIE_CLK_GEN1_EN, RALINK_PCIE_CLK_GEN1); rt_sysc_m32(PCIE_CLK_GEN_DIS, PCIE_CLK_GEN_EN, RALINK_PCIE_CLK_GEN); msleep(50); - rt_sysc_m32(RALINK_PCIE_RST, 0, RALINK_RSTCTRL); + reset_control_deassert(pcie->rst); } static int mt7621_pcie_enable_port(struct mt7621_pcie_port *port) @@ -690,7 +506,7 @@ static void mt7621_pcie_enable_ports(struct mt7621_pcie *pcie) list_for_each_entry(port, &pcie->ports, list) { if (port->enabled) { - if (!mt7621_pcie_enable_port(port)) { + if (mt7621_pcie_enable_port(port)) { dev_err(dev, "de-assert port %d PERST_N\n", port->slot); continue; @@ -701,8 +517,9 @@ static void mt7621_pcie_enable_ports(struct mt7621_pcie *pcie) } for (slot = 0; slot < num_slots_enabled; slot++) { - val = read_config(pcie, slot, 0x4); - write_config(pcie, slot, 0x4, val | 0x4); + val = read_config(pcie, slot, PCI_COMMAND); + val |= PCI_COMMAND_MASTER; + write_config(pcie, slot, PCI_COMMAND, val); /* configure RC FTS number to 250 when it leaves L0s */ val = read_config(pcie, slot, PCIE_FTS_NUM); val &= ~PCIE_FTS_NUM_MASK; @@ -714,7 +531,7 @@ static void mt7621_pcie_enable_ports(struct mt7621_pcie *pcie) static int mt7621_pcie_init_virtual_bridges(struct mt7621_pcie *pcie) { u32 pcie_link_status = 0; - u32 val= 0; + u32 val = 0; struct mt7621_pcie_port *port; list_for_each_entry(port, &pcie->ports, list) { @@ -728,15 +545,15 @@ static int mt7621_pcie_init_virtual_bridges(struct mt7621_pcie *pcie) return -1; /* - * pcie(2/1/0) link status pcie2_num pcie1_num pcie0_num - * 3'b000 x x x - * 3'b001 x x 0 - * 3'b010 x 0 x - * 3'b011 x 1 0 - * 3'b100 0 x x - * 3'b101 1 x 0 - * 3'b110 1 0 x - * 3'b111 2 1 0 + * pcie(2/1/0) link status pcie2_num pcie1_num pcie0_num + * 3'b000 x x x + * 3'b001 x x 0 + * 3'b010 x 0 x + * 3'b011 x 1 0 + * 3'b100 0 x x + * 3'b101 1 x 0 + * 3'b110 1 0 x + * 3'b111 2 1 0 */ switch (pcie_link_status) { case 2: @@ -848,9 +665,6 @@ static int mt7621_pci_probe(struct platform_device *pdev) return 0; } - pcie_write(pcie, 0xffffffff, RALINK_PCI_MEMBASE); - pcie_write(pcie, RALINK_PCI_IO_MAP_BASE, RALINK_PCI_IOBASE); - mt7621_pcie_enable_ports(pcie); err = mt7621_pci_parse_request_of_pci_ranges(pcie); diff --git a/drivers/staging/mt7621-pinctrl/Kconfig b/drivers/staging/mt7621-pinctrl/Kconfig index 37cf9c3273be..fc3612711307 100644 --- a/drivers/staging/mt7621-pinctrl/Kconfig +++ b/drivers/staging/mt7621-pinctrl/Kconfig @@ -2,3 +2,4 @@ config PINCTRL_RT2880 bool "RT2800 pinctrl driver for RALINK/Mediatek SOCs" depends on RALINK select PINMUX + select GENERIC_PINCONF diff --git a/drivers/staging/mt7621-pinctrl/pinctrl-rt2880.c b/drivers/staging/mt7621-pinctrl/pinctrl-rt2880.c index aa98fbb17013..9b52d44abef1 100644 --- a/drivers/staging/mt7621-pinctrl/pinctrl-rt2880.c +++ b/drivers/staging/mt7621-pinctrl/pinctrl-rt2880.c @@ -11,6 +11,7 @@ #include <linux/of.h> #include <linux/pinctrl/pinctrl.h> #include <linux/pinctrl/pinconf.h> +#include <linux/pinctrl/pinconf-generic.h> #include <linux/pinctrl/pinmux.h> #include <linux/pinctrl/consumer.h> #include <linux/pinctrl/machine.h> @@ -73,48 +74,12 @@ static int rt2880_get_group_pins(struct pinctrl_dev *pctrldev, return 0; } -static int rt2880_pinctrl_dt_node_to_map(struct pinctrl_dev *pctrldev, - struct device_node *np_config, - struct pinctrl_map **map, - unsigned int *num_maps) -{ - struct rt2880_priv *p = pinctrl_dev_get_drvdata(pctrldev); - struct property *prop; - const char *function_name, *group_name; - int ret; - int ngroups = 0; - unsigned int reserved_maps = 0; - - for_each_node_with_property(np_config, "group") - ngroups++; - - *map = NULL; - ret = pinctrl_utils_reserve_map(pctrldev, map, &reserved_maps, - num_maps, ngroups); - if (ret) { - dev_err(p->dev, "can't reserve map: %d\n", ret); - return ret; - } - - of_property_for_each_string(np_config, "group", prop, group_name) { - ret = pinctrl_utils_add_map_mux(pctrldev, map, &reserved_maps, - num_maps, group_name, - function_name); - if (ret) { - dev_err(p->dev, "can't add map: %d\n", ret); - return ret; - } - } - - return 0; -} - static const struct pinctrl_ops rt2880_pctrl_ops = { .get_groups_count = rt2880_get_group_count, .get_group_name = rt2880_get_group_name, .get_group_pins = rt2880_get_group_pins, - .dt_node_to_map = rt2880_pinctrl_dt_node_to_map, - .dt_free_map = pinctrl_utils_free_map, + .dt_node_to_map = pinconf_generic_dt_node_to_map_all, + .dt_free_map = pinconf_generic_dt_free_map, }; static int rt2880_pmx_func_count(struct pinctrl_dev *pctrldev) @@ -385,7 +350,6 @@ static int rt2880_pinmux_probe(struct platform_device *pdev) for_each_compatible_node(np, NULL, "ralink,rt2880-gpio") { const __be32 *ngpio, *gpiobase; struct pinctrl_gpio_range *range; - char *name; if (!of_device_is_available(np)) continue; @@ -397,9 +361,10 @@ static int rt2880_pinmux_probe(struct platform_device *pdev) return -EINVAL; } - range = devm_kzalloc(p->dev, sizeof(*range) + 4, GFP_KERNEL); - range->name = name = (char *) &range[1]; - sprintf(name, "pio"); + range = devm_kzalloc(p->dev, sizeof(*range), GFP_KERNEL); + if (!range) + return -ENOMEM; + range->name = "pio"; range->npins = __be32_to_cpu(*ngpio); range->base = __be32_to_cpu(*gpiobase); range->pin_base = range->base; diff --git a/drivers/staging/mt7621-spi/spi-mt7621.c b/drivers/staging/mt7621-spi/spi-mt7621.c index 513b6e79b985..b509f9fe3346 100644 --- a/drivers/staging/mt7621-spi/spi-mt7621.c +++ b/drivers/staging/mt7621-spi/spi-mt7621.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * spi-mt7621.c -- MediaTek MT7621 SPI controller driver * @@ -8,34 +9,23 @@ * Some parts are based on spi-orion.c: * Author: Shadi Ammouri <shadi@marvell.com> * Copyright (C) 2007-2008 Marvell Ltd. - * - * 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. */ -#include <linux/init.h> -#include <linux/module.h> #include <linux/clk.h> -#include <linux/err.h> #include <linux/delay.h> #include <linux/io.h> +#include <linux/module.h> +#include <linux/of_device.h> #include <linux/reset.h> #include <linux/spi/spi.h> -#include <linux/of_device.h> -#include <linux/platform_device.h> -#include <linux/swab.h> - -#include <ralink_regs.h> -#define SPI_BPW_MASK(bits) BIT((bits) - 1) +#define DRIVER_NAME "spi-mt7621" -#define DRIVER_NAME "spi-mt7621" /* in usec */ -#define RALINK_SPI_WAIT_MAX_LOOP 2000 +#define RALINK_SPI_WAIT_MAX_LOOP 2000 /* SPISTAT register bit field */ -#define SPISTAT_BUSY BIT(0) +#define SPISTAT_BUSY BIT(0) #define MT7621_SPI_TRANS 0x00 #define SPITRANS_BUSY BIT(16) @@ -46,17 +36,21 @@ #define SPI_CTL_TX_RX_CNT_MASK 0xff #define SPI_CTL_START BIT(8) -#define MT7621_SPI_POLAR 0x38 #define MT7621_SPI_MASTER 0x28 +#define MASTER_MORE_BUFMODE BIT(2) +#define MASTER_FULL_DUPLEX BIT(10) +#define MASTER_RS_CLK_SEL GENMASK(27, 16) +#define MASTER_RS_CLK_SEL_SHIFT 16 +#define MASTER_RS_SLAVE_SEL GENMASK(31, 29) + #define MT7621_SPI_MOREBUF 0x2c +#define MT7621_SPI_POLAR 0x38 #define MT7621_SPI_SPACE 0x3c #define MT7621_CPHA BIT(5) #define MT7621_CPOL BIT(4) #define MT7621_LSB_FIRST BIT(3) -struct mt7621_spi; - struct mt7621_spi { struct spi_master *master; void __iomem *base; @@ -87,9 +81,13 @@ static void mt7621_spi_reset(struct mt7621_spi *rs) { u32 master = mt7621_spi_read(rs, MT7621_SPI_MASTER); - master |= 7 << 29; - master |= 1 << 2; - master &= ~(1 << 10); + /* + * Select SPI device 7, enable "more buffer mode" and disable + * full-duplex (only half-duplex really works on this chip + * reliably) + */ + master |= MASTER_RS_SLAVE_SEL | MASTER_MORE_BUFMODE; + master &= ~MASTER_FULL_DUPLEX; mt7621_spi_write(rs, MT7621_SPI_MASTER, master); rs->pending_write = 0; @@ -125,18 +123,18 @@ static int mt7621_spi_prepare(struct spi_device *spi, unsigned int speed) rate = 2; reg = mt7621_spi_read(rs, MT7621_SPI_MASTER); - reg &= ~(0xfff << 16); - reg |= (rate - 2) << 16; + reg &= ~MASTER_RS_CLK_SEL; + reg |= (rate - 2) << MASTER_RS_CLK_SEL_SHIFT; rs->speed = speed; reg &= ~MT7621_LSB_FIRST; if (spi->mode & SPI_LSB_FIRST) reg |= MT7621_LSB_FIRST; - /* This SPI controller seems to be tested on SPI flash only - * and some bits are swizzled under other SPI modes probably - * due to incorrect wiring inside the silicon. Only mode 0 - * works correctly. + /* + * This SPI controller seems to be tested on SPI flash only and some + * bits are swizzled under other SPI modes probably due to incorrect + * wiring inside the silicon. Only mode 0 works correctly. */ reg &= ~(MT7621_CPHA | MT7621_CPOL); @@ -165,9 +163,10 @@ static inline int mt7621_spi_wait_till_ready(struct mt7621_spi *rs) static void mt7621_spi_read_half_duplex(struct mt7621_spi *rs, int rx_len, u8 *buf) { - /* Combine with any pending write, and perform one or - * more half-duplex transactions reading 'len' bytes. - * Data to be written is already in MT7621_SPI_DATA* + /* + * Combine with any pending write, and perform one or more half-duplex + * transactions reading 'len' bytes. Data to be written is already in + * MT7621_SPI_DATA. */ int tx_len = rs->pending_write; @@ -197,6 +196,7 @@ static void mt7621_spi_read_half_duplex(struct mt7621_spi *rs, *buf++ = val & 0xff; val >>= 8; } + rx_len -= i; } } @@ -290,6 +290,7 @@ static int mt7621_spi_transfer_one_message(struct spi_master *master, mt7621_spi_flush(rs); mt7621_spi_set_cs(spi, 0); + msg_done: m->status = status; spi_finalize_current_message(master); @@ -330,6 +331,7 @@ static int mt7621_spi_probe(struct platform_device *pdev) int status = 0; struct clk *clk; struct mt7621_spi_ops *ops; + int ret; match = of_match_device(mt7621_spi_match, &pdev->dev); if (!match) @@ -353,7 +355,7 @@ static int mt7621_spi_probe(struct platform_device *pdev) return status; master = spi_alloc_master(&pdev->dev, sizeof(*rs)); - if (master == NULL) { + if (!master) { dev_info(&pdev->dev, "master allocation failed\n"); return -ENOMEM; } @@ -377,7 +379,11 @@ static int mt7621_spi_probe(struct platform_device *pdev) rs->pending_write = 0; dev_info(&pdev->dev, "sys_freq: %u\n", rs->sys_freq); - device_reset(&pdev->dev); + ret = device_reset(&pdev->dev); + if (ret) { + dev_err(&pdev->dev, "SPI reset failed!\n"); + return ret; + } mt7621_spi_reset(rs); diff --git a/drivers/staging/netlogic/Kconfig b/drivers/staging/netlogic/Kconfig index d660de51b541..c25a00dd2d5f 100644 --- a/drivers/staging/netlogic/Kconfig +++ b/drivers/staging/netlogic/Kconfig @@ -2,6 +2,6 @@ config NETLOGIC_XLR_NET tristate "Netlogic XLR/XLS network device" depends on CPU_XLR select PHYLIB - ---help--- + help This driver support Netlogic XLR/XLS on chip gigabit Ethernet. diff --git a/drivers/staging/netlogic/platform_net.c b/drivers/staging/netlogic/platform_net.c index abf4c71ee66b..8be9d0b0c22c 100644 --- a/drivers/staging/netlogic/platform_net.c +++ b/drivers/staging/netlogic/platform_net.c @@ -1,36 +1,7 @@ +// SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) /* * Copyright (c) 2003-2012 Broadcom Corporation * All Rights Reserved - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * 1. Redistributions of source code must retain the above copyright - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the Broadcom - * license below: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * THIS SOFTWARE IS PROVIDED BY BROADCOM ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include <linux/device.h> @@ -107,8 +78,9 @@ static struct platform_device *gmac_controller2_init(void *gmac0_addr) .dev.platform_data = &ndata1, }; - gmac4_addr = ioremap(CPHYSADDR( - nlm_mmio_base(NETLOGIC_IO_GMAC_4_OFFSET)), 0xfff); + gmac4_addr = + ioremap(CPHYSADDR(nlm_mmio_base(NETLOGIC_IO_GMAC_4_OFFSET)), + 0xfff); ndata1.serdes_addr = gmac4_addr; ndata1.pcs_addr = gmac4_addr; ndata1.mii_addr = gmac0_addr; @@ -134,8 +106,9 @@ static void xls_gmac_init(void) { int mac; struct platform_device *xlr_net_dev1; - void __iomem *gmac0_addr = ioremap(CPHYSADDR( - nlm_mmio_base(NETLOGIC_IO_GMAC_0_OFFSET)), 0xfff); + void __iomem *gmac0_addr = + ioremap(CPHYSADDR(nlm_mmio_base(NETLOGIC_IO_GMAC_0_OFFSET)), + 0xfff); static struct xlr_net_data ndata0 = { .rfr_station = FMN_STNID_GMACRFR_0, @@ -153,8 +126,9 @@ static void xls_gmac_init(void) ndata0.mii_addr = gmac0_addr; /* Passing GPIO base for serdes init. Only needed on sgmii ports */ - gpio_addr = ioremap(CPHYSADDR( - nlm_mmio_base(NETLOGIC_IO_GPIO_OFFSET)), 0xfff); + gpio_addr = + ioremap(CPHYSADDR(nlm_mmio_base(NETLOGIC_IO_GPIO_OFFSET)), + 0xfff); ndata0.gpio_addr = gpio_addr; ndata0.cpu_mask = nlm_current_node()->coremask; @@ -214,8 +188,9 @@ static void xlr_gmac_init(void) .id = 0, .dev.platform_data = &ndata0, }; - ndata0.mii_addr = ioremap(CPHYSADDR( - nlm_mmio_base(NETLOGIC_IO_GMAC_0_OFFSET)), 0xfff); + ndata0.mii_addr = + ioremap(CPHYSADDR(nlm_mmio_base(NETLOGIC_IO_GMAC_0_OFFSET)), + 0xfff); ndata0.cpu_mask = nlm_current_node()->coremask; diff --git a/drivers/staging/netlogic/platform_net.h b/drivers/staging/netlogic/platform_net.h index e1b27f649590..f152d84099a2 100644 --- a/drivers/staging/netlogic/platform_net.h +++ b/drivers/staging/netlogic/platform_net.h @@ -1,35 +1,7 @@ -/* +/* SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) + * * Copyright (c) 2003-2012 Broadcom Corporation * All Rights Reserved - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the Broadcom - * license below: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * THIS SOFTWARE IS PROVIDED BY BROADCOM ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #define PORTS_PER_CONTROLLER 4 diff --git a/drivers/staging/netlogic/xlr_net.c b/drivers/staging/netlogic/xlr_net.c index 4e6611e4c59b..8554fcf4321b 100644 --- a/drivers/staging/netlogic/xlr_net.c +++ b/drivers/staging/netlogic/xlr_net.c @@ -1,36 +1,9 @@ +// SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) /* * Copyright (c) 2003-2012 Broadcom Corporation * All Rights Reserved - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the Broadcom - * license below: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * THIS SOFTWARE IS PROVIDED BY BROADCOM ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + #include <linux/phy.h> #include <linux/delay.h> #include <linux/netdevice.h> diff --git a/drivers/staging/netlogic/xlr_net.h b/drivers/staging/netlogic/xlr_net.h index f76e16cfd15d..518ea809b8fa 100644 --- a/drivers/staging/netlogic/xlr_net.h +++ b/drivers/staging/netlogic/xlr_net.h @@ -1,36 +1,9 @@ -/* +/* SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) + * * Copyright (c) 2003-2012 Broadcom Corporation * All Rights Reserved - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the Broadcom - * license below: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * THIS SOFTWARE IS PROVIDED BY BROADCOM ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + /* #define MAC_SPLIT_MODE */ #define MAC_SPACING 0x400 diff --git a/drivers/staging/octeon-usb/octeon-hcd.h b/drivers/staging/octeon-usb/octeon-hcd.h index 769c36cf6614..ae7ae50071ae 100644 --- a/drivers/staging/octeon-usb/octeon-hcd.h +++ b/drivers/staging/octeon-usb/octeon-hcd.h @@ -1797,7 +1797,7 @@ union cvmx_usbnx_usbp_ctl_status { * This is a test signal. When the USB Core is * powered up (not in Susned Mode), an automatic * tester can use this to disable phy_clock and - * free_clk, then re-eanable them with an aligned + * free_clk, then re-enable them with an aligned * phase. * '1': The phy_clk and free_clk outputs are * disabled. "0": The phy_clock and free_clk outputs diff --git a/drivers/staging/ralink-gdma/Kconfig b/drivers/staging/ralink-gdma/Kconfig new file mode 100644 index 000000000000..a12b2c672d48 --- /dev/null +++ b/drivers/staging/ralink-gdma/Kconfig @@ -0,0 +1,6 @@ +config DMA_RALINK + tristate "RALINK DMA support" + depends on RALINK && !SOC_RT288X + select DMA_ENGINE + select DMA_VIRTUAL_CHANNELS + diff --git a/drivers/staging/ralink-gdma/Makefile b/drivers/staging/ralink-gdma/Makefile new file mode 100644 index 000000000000..5d917e0729bb --- /dev/null +++ b/drivers/staging/ralink-gdma/Makefile @@ -0,0 +1,3 @@ +obj-$(CONFIG_DMA_RALINK) += ralink-gdma.o + +ccflags-y += -I$(srctree)/drivers/dma diff --git a/drivers/staging/mt7621-dma/ralink-gdma.c b/drivers/staging/ralink-gdma/ralink-gdma.c index 792a63bd55d4..d78042eba6dd 100644 --- a/drivers/staging/mt7621-dma/ralink-gdma.c +++ b/drivers/staging/ralink-gdma/ralink-gdma.c @@ -821,9 +821,9 @@ static int gdma_dma_probe(struct platform_device *pdev) return -EINVAL; data = (struct gdma_data *) match->data; - dma_dev = devm_kzalloc(&pdev->dev, sizeof(*dma_dev) + - (sizeof(struct gdma_dmaengine_chan) * data->chancnt), - GFP_KERNEL); + dma_dev = devm_kzalloc(&pdev->dev, + struct_size(dma_dev, chan, data->chancnt), + GFP_KERNEL); if (!dma_dev) { dev_err(&pdev->dev, "alloc dma device failed\n"); return -EINVAL; diff --git a/drivers/staging/rtl8188eu/core/rtw_ap.c b/drivers/staging/rtl8188eu/core/rtw_ap.c index 1f232ba6651c..94c9d9f8ee5c 100644 --- a/drivers/staging/rtl8188eu/core/rtw_ap.c +++ b/drivers/staging/rtl8188eu/core/rtw_ap.c @@ -82,7 +82,7 @@ static void update_BCNTIM(struct adapter *padapter) /* calculate head_len */ offset = _FIXED_IE_LENGTH_; - offset += pnetwork_mlmeext->Ssid.SsidLength + 2; + offset += pnetwork_mlmeext->ssid.ssid_length + 2; /* get supported rates len */ p = rtw_get_ie(pie + _BEACON_IE_OFFSET_, _SUPPORTEDRATES_IE_, @@ -785,9 +785,9 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len) /* SSID */ p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _SSID_IE_, &ie_len, (pbss_network->ie_length - _BEACON_IE_OFFSET_)); if (p && ie_len > 0) { - memset(&pbss_network->Ssid, 0, sizeof(struct ndis_802_11_ssid)); - memcpy(pbss_network->Ssid.Ssid, (p + 2), ie_len); - pbss_network->Ssid.SsidLength = ie_len; + memset(&pbss_network->ssid, 0, sizeof(struct ndis_802_11_ssid)); + memcpy(pbss_network->ssid.ssid, (p + 2), ie_len); + pbss_network->ssid.ssid_length = ie_len; } /* channel */ diff --git a/drivers/staging/rtl8188eu/core/rtw_cmd.c b/drivers/staging/rtl8188eu/core/rtw_cmd.c index 407f65cf7150..83a2e58aef53 100644 --- a/drivers/staging/rtl8188eu/core/rtw_cmd.c +++ b/drivers/staging/rtl8188eu/core/rtw_cmd.c @@ -263,7 +263,7 @@ u8 rtw_sitesurvey_cmd(struct adapter *padapter, struct ndis_802_11_ssid *ssid, int i; for (i = 0; i < ssid_num && i < RTW_SSID_SCAN_AMOUNT; i++) { - if (ssid[i].SsidLength) { + if (ssid[i].ssid_length) { memcpy(&psurveyPara->ssid[i], &ssid[i], sizeof(struct ndis_802_11_ssid)); psurveyPara->ssid_num++; } @@ -316,10 +316,10 @@ u8 rtw_createbss_cmd(struct adapter *padapter) led_control_8188eu(padapter, LED_CTL_START_TO_LINK); - if (pmlmepriv->assoc_ssid.SsidLength == 0) - RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, (" createbss for Any SSid:%s\n", pmlmepriv->assoc_ssid.Ssid)); + if (pmlmepriv->assoc_ssid.ssid_length == 0) + RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, (" createbss for Any SSid:%s\n", pmlmepriv->assoc_ssid.ssid)); else - RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, (" createbss for SSid:%s\n", pmlmepriv->assoc_ssid.Ssid)); + RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, (" createbss for SSid:%s\n", pmlmepriv->assoc_ssid.ssid)); pcmd = kzalloc(sizeof(*pcmd), GFP_ATOMIC); if (!pcmd) { @@ -358,10 +358,10 @@ u8 rtw_joinbss_cmd(struct adapter *padapter, struct wlan_network *pnetwork) led_control_8188eu(padapter, LED_CTL_START_TO_LINK); - if (pmlmepriv->assoc_ssid.SsidLength == 0) + if (pmlmepriv->assoc_ssid.ssid_length == 0) RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, ("+Join cmd: Any SSid\n")); else - RT_TRACE(_module_rtl871x_cmd_c_, _drv_notice_, ("+Join cmd: SSid =[%s]\n", pmlmepriv->assoc_ssid.Ssid)); + RT_TRACE(_module_rtl871x_cmd_c_, _drv_notice_, ("+Join cmd: SSid =[%s]\n", pmlmepriv->assoc_ssid.ssid)); pcmd = kzalloc(sizeof(*pcmd), GFP_ATOMIC); if (!pcmd) { diff --git a/drivers/staging/rtl8188eu/core/rtw_efuse.c b/drivers/staging/rtl8188eu/core/rtw_efuse.c index b7be71f904ed..51c3dd6d7ffb 100644 --- a/drivers/staging/rtl8188eu/core/rtw_efuse.c +++ b/drivers/staging/rtl8188eu/core/rtw_efuse.c @@ -88,7 +88,9 @@ efuse_phymap_to_logical(u8 *phymap, u16 _offset, u16 _size_byte, u8 *pbuf) if (!efuseTbl) return; - tmp = kzalloc(EFUSE_MAX_SECTION_88E * (sizeof(void *) + EFUSE_MAX_WORD_UNIT * sizeof(u16)), GFP_KERNEL); + tmp = kcalloc(EFUSE_MAX_SECTION_88E, + sizeof(void *) + EFUSE_MAX_WORD_UNIT * sizeof(u16), + GFP_KERNEL); if (!tmp) { DBG_88E("%s: alloc eFuseWord fail!\n", __func__); goto eFuseWord_failed; diff --git a/drivers/staging/rtl8188eu/core/rtw_ieee80211.c b/drivers/staging/rtl8188eu/core/rtw_ieee80211.c index 5c4ff81987bd..094e8e78f0e8 100644 --- a/drivers/staging/rtl8188eu/core/rtw_ieee80211.c +++ b/drivers/staging/rtl8188eu/core/rtw_ieee80211.c @@ -234,7 +234,7 @@ int rtw_generate_ie(struct registry_priv *pregistrypriv) ie += 2; /* SSID */ - ie = rtw_set_ie(ie, _SSID_IE_, pdev_network->Ssid.SsidLength, pdev_network->Ssid.Ssid, &sz); + ie = rtw_set_ie(ie, _SSID_IE_, pdev_network->ssid.ssid_length, pdev_network->ssid.ssid, &sz); /* supported rates */ if (pregistrypriv->wireless_mode == WIRELESS_11ABGN) { @@ -927,7 +927,7 @@ static int rtw_get_cipher_info(struct wlan_network *pnetwork) if (pbuf && (wpa_ielen > 0)) { RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("%s: wpa_ielen: %d", __func__, wpa_ielen)); - if (_SUCCESS == rtw_parse_wpa_ie(pbuf, wpa_ielen + 2, &group_cipher, &pairwise_cipher, &is8021x)) { + if (rtw_parse_wpa_ie(pbuf, wpa_ielen + 2, &group_cipher, &pairwise_cipher, &is8021x) == _SUCCESS) { pnetwork->BcnInfo.pairwise_cipher = pairwise_cipher; pnetwork->BcnInfo.group_cipher = group_cipher; pnetwork->BcnInfo.is_8021x = is8021x; @@ -940,7 +940,7 @@ static int rtw_get_cipher_info(struct wlan_network *pnetwork) if (pbuf && (wpa_ielen > 0)) { RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("get RSN IE\n")); - if (_SUCCESS == rtw_parse_wpa2_ie(pbuf, wpa_ielen + 2, &group_cipher, &pairwise_cipher, &is8021x)) { + if (rtw_parse_wpa2_ie(pbuf, wpa_ielen + 2, &group_cipher, &pairwise_cipher, &is8021x) == _SUCCESS) { RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("get RSN IE OK!!!\n")); pnetwork->BcnInfo.pairwise_cipher = pairwise_cipher; pnetwork->BcnInfo.group_cipher = group_cipher; @@ -975,9 +975,9 @@ void rtw_get_bcn_info(struct wlan_network *pnetwork) pnetwork->BcnInfo.encryp_protocol = ENCRYP_PROTOCOL_OPENSYS; } rtw_get_sec_ie(pnetwork->network.ies, pnetwork->network.ie_length, NULL, &rsn_len, NULL, &wpa_len); - RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("%s: ssid =%s\n", __func__, pnetwork->network.Ssid.Ssid)); + RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("%s: ssid =%s\n", __func__, pnetwork->network.ssid.ssid)); RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("%s: wpa_len =%d rsn_len =%d\n", __func__, wpa_len, rsn_len)); - RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("%s: ssid =%s\n", __func__, pnetwork->network.Ssid.Ssid)); + RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("%s: ssid =%s\n", __func__, pnetwork->network.ssid.ssid)); RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("%s: wpa_len =%d rsn_len =%d\n", __func__, wpa_len, rsn_len)); if (rsn_len > 0) { diff --git a/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c b/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c index 0b3eb0b40975..7d56767cdff6 100644 --- a/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c +++ b/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c @@ -77,7 +77,7 @@ u8 rtw_do_join(struct adapter *padapter) pibss = padapter->registrypriv.dev_network.MacAddress; - memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid, sizeof(struct ndis_802_11_ssid)); + memcpy(&pdev_network->ssid, &pmlmepriv->assoc_ssid, sizeof(struct ndis_802_11_ssid)); rtw_update_registrypriv_dev_network(padapter); @@ -208,7 +208,7 @@ u8 rtw_set_802_11_ssid(struct adapter *padapter, struct ndis_802_11_ssid *ssid) struct wlan_network *pnetwork = &pmlmepriv->cur_network; DBG_88E_LEVEL(_drv_info_, "set ssid [%s] fw_state=0x%08x\n", - ssid->Ssid, get_fwstate(pmlmepriv)); + ssid->ssid, get_fwstate(pmlmepriv)); if (!padapter->hw_init_completed) { RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, @@ -229,8 +229,8 @@ u8 rtw_set_802_11_ssid(struct adapter *padapter, struct ndis_802_11_ssid *ssid) RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("set_ssid: _FW_LINKED||WIFI_ADHOC_MASTER_STATE\n")); - if (pmlmepriv->assoc_ssid.SsidLength == ssid->SsidLength && - !memcmp(&pmlmepriv->assoc_ssid.Ssid, ssid->Ssid, ssid->SsidLength)) { + if (pmlmepriv->assoc_ssid.ssid_length == ssid->ssid_length && + !memcmp(&pmlmepriv->assoc_ssid.ssid, ssid->ssid, ssid->ssid_length)) { if (!check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("Set SSID is the same ssid, fw_state = 0x%08x\n", @@ -257,8 +257,8 @@ u8 rtw_set_802_11_ssid(struct adapter *padapter, struct ndis_802_11_ssid *ssid) } } else { RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("Set SSID not the same ssid\n")); - RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("set_ssid =[%s] len = 0x%x\n", ssid->Ssid, (unsigned int)ssid->SsidLength)); - RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("assoc_ssid =[%s] len = 0x%x\n", pmlmepriv->assoc_ssid.Ssid, (unsigned int)pmlmepriv->assoc_ssid.SsidLength)); + RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("set_ssid =[%s] len = 0x%x\n", ssid->ssid, (unsigned int)ssid->ssid_length)); + RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("assoc_ssid =[%s] len = 0x%x\n", pmlmepriv->assoc_ssid.ssid, (unsigned int)pmlmepriv->assoc_ssid.ssid_length)); rtw_disassoc_cmd(padapter, 0, true); diff --git a/drivers/staging/rtl8188eu/core/rtw_mlme.c b/drivers/staging/rtl8188eu/core/rtw_mlme.c index 714f7a70ed64..ca0cf8a86671 100644 --- a/drivers/staging/rtl8188eu/core/rtw_mlme.c +++ b/drivers/staging/rtl8188eu/core/rtw_mlme.c @@ -300,8 +300,8 @@ int rtw_is_same_ibss(struct adapter *adapter, struct wlan_network *pnetwork) static int is_same_ess(struct wlan_bssid_ex *a, struct wlan_bssid_ex *b) { - return (a->Ssid.SsidLength == b->Ssid.SsidLength) && - !memcmp(a->Ssid.Ssid, b->Ssid.Ssid, a->Ssid.SsidLength); + return (a->ssid.ssid_length == b->ssid.ssid_length) && + !memcmp(a->ssid.ssid, b->ssid.ssid, a->ssid.ssid_length); } int is_same_network(struct wlan_bssid_ex *src, struct wlan_bssid_ex *dst) @@ -315,9 +315,9 @@ int is_same_network(struct wlan_bssid_ex *src, struct wlan_bssid_ex *dst) s_cap = le16_to_cpu(le_scap); d_cap = le16_to_cpu(le_dcap); - return ((src->Ssid.SsidLength == dst->Ssid.SsidLength) && + return ((src->ssid.ssid_length == dst->ssid.ssid_length) && (!memcmp(src->MacAddress, dst->MacAddress, ETH_ALEN)) && - (!memcmp(src->Ssid.Ssid, dst->Ssid.Ssid, src->Ssid.SsidLength)) && + (!memcmp(src->ssid.ssid, dst->ssid.ssid, src->ssid.ssid_length)) && ((s_cap & WLAN_CAPABILITY_IBSS) == (d_cap & WLAN_CAPABILITY_IBSS)) && ((s_cap & WLAN_CAPABILITY_ESS) == @@ -558,7 +558,7 @@ void rtw_survey_event_callback(struct adapter *adapter, u8 *pbuf) pnetwork = (struct wlan_bssid_ex *)pbuf; RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, - ("%s, ssid=%s\n", __func__, pnetwork->Ssid.Ssid)); + ("%s, ssid=%s\n", __func__, pnetwork->ssid.ssid)); len = get_wlan_bssid_ex_sz(pnetwork); if (len > (sizeof(struct wlan_bssid_ex))) { @@ -587,8 +587,8 @@ void rtw_survey_event_callback(struct adapter *adapter, u8 *pbuf) /* lock pmlmepriv->lock when you accessing network_q */ if (!check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) { - if (pnetwork->Ssid.Ssid[0] == 0) - pnetwork->Ssid.SsidLength = 0; + if (pnetwork->ssid.ssid[0] == 0) + pnetwork->ssid.ssid_length = 0; rtw_add_network(adapter, pnetwork); } @@ -636,7 +636,7 @@ void rtw_surveydone_event_callback(struct adapter *adapter, u8 *pbuf) RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("switching to adhoc master\n")); - memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid, sizeof(struct ndis_802_11_ssid)); + memcpy(&pdev_network->ssid, &pmlmepriv->assoc_ssid, sizeof(struct ndis_802_11_ssid)); rtw_update_registrypriv_dev_network(adapter); rtw_generate_random_ibss(pibss); @@ -741,7 +741,7 @@ void rtw_free_assoc_resources_locked(struct adapter *adapter) RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_, ("+rtw_free_assoc_resources\n")); RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("tgt_network->network.MacAddress=%pM ssid=%s\n", - tgt_network->network.MacAddress, tgt_network->network.Ssid.Ssid)); + tgt_network->network.MacAddress, tgt_network->network.ssid.ssid)); if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_AP_STATE)) { struct sta_info *psta; @@ -975,10 +975,10 @@ void rtw_joinbss_event_prehandle(struct adapter *adapter, u8 *pbuf) rtw_get_encrypt_decrypt_from_registrypriv(adapter); - if (pmlmepriv->assoc_ssid.SsidLength == 0) + if (pmlmepriv->assoc_ssid.ssid_length == 0) RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("@@@@@ joinbss event call back for Any SSid\n")); else - RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("@@@@@ rtw_joinbss_event_callback for SSid:%s\n", pmlmepriv->assoc_ssid.Ssid)); + RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("@@@@@ rtw_joinbss_event_callback for SSid:%s\n", pmlmepriv->assoc_ssid.ssid)); the_same_macaddr = !memcmp(pnetwork->network.MacAddress, cur_network->network.MacAddress, ETH_ALEN); @@ -1279,7 +1279,7 @@ void rtw_stadel_event_callback(struct adapter *adapter, u8 *pbuf) memcpy(pdev_network, &tgt_network->network, get_wlan_bssid_ex_sz(&tgt_network->network)); - memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid, sizeof(struct ndis_802_11_ssid)); + memcpy(&pdev_network->ssid, &pmlmepriv->assoc_ssid, sizeof(struct ndis_802_11_ssid)); rtw_update_registrypriv_dev_network(adapter); @@ -1422,9 +1422,9 @@ static int rtw_check_join_candidate(struct mlme_priv *pmlmepriv } /* check ssid, if needed */ - if (pmlmepriv->assoc_ssid.SsidLength) { - if (competitor->network.Ssid.SsidLength != pmlmepriv->assoc_ssid.SsidLength || - memcmp(competitor->network.Ssid.Ssid, pmlmepriv->assoc_ssid.Ssid, pmlmepriv->assoc_ssid.SsidLength)) + if (pmlmepriv->assoc_ssid.ssid_length) { + if (competitor->network.ssid.ssid_length != pmlmepriv->assoc_ssid.ssid_length || + memcmp(competitor->network.ssid.ssid, pmlmepriv->assoc_ssid.ssid, pmlmepriv->assoc_ssid.ssid_length)) goto exit; } @@ -1445,8 +1445,8 @@ static int rtw_check_join_candidate(struct mlme_priv *pmlmepriv if (updated) { DBG_88E("[by_bssid:%u][assoc_ssid:%s]new candidate: %s(%pM rssi:%d\n", pmlmepriv->assoc_by_bssid, - pmlmepriv->assoc_ssid.Ssid, - (*candidate)->network.Ssid.Ssid, + pmlmepriv->assoc_ssid.ssid, + (*candidate)->network.ssid.ssid, (*candidate)->network.MacAddress, (int)(*candidate)->network.Rssi); DBG_88E("[to_roaming:%u]\n", pmlmepriv->to_roaming); @@ -1493,7 +1493,7 @@ int rtw_select_and_join_from_scanned_queue(struct mlme_priv *pmlmepriv) goto exit; } else { DBG_88E("%s: candidate: %s(%pM ch:%u)\n", __func__, - candidate->network.Ssid.Ssid, candidate->network.MacAddress, + candidate->network.ssid.ssid, candidate->network.MacAddress, candidate->network.Configuration.DSConfig); } @@ -1772,7 +1772,7 @@ void rtw_init_registrypriv_dev_network(struct adapter *adapter) memcpy(pdev_network->MacAddress, myhwaddr, ETH_ALEN); - memcpy(&pdev_network->Ssid, &pregistrypriv->ssid, sizeof(struct ndis_802_11_ssid)); + memcpy(&pdev_network->ssid, &pregistrypriv->ssid, sizeof(struct ndis_802_11_ssid)); pdev_network->Configuration.Length = sizeof(struct ndis_802_11_config); pdev_network->Configuration.BeaconPeriod = 100; @@ -2049,9 +2049,9 @@ void _rtw_roaming(struct adapter *padapter, struct wlan_network *tgt_network) if (pmlmepriv->to_roaming > 0) { DBG_88E("roaming from %s(%pM length:%d\n", - pnetwork->network.Ssid.Ssid, pnetwork->network.MacAddress, - pnetwork->network.Ssid.SsidLength); - memcpy(&pmlmepriv->assoc_ssid, &pnetwork->network.Ssid, sizeof(struct ndis_802_11_ssid)); + pnetwork->network.ssid.ssid, pnetwork->network.MacAddress, + pnetwork->network.ssid.ssid_length); + memcpy(&pmlmepriv->assoc_ssid, &pnetwork->network.ssid, sizeof(struct ndis_802_11_ssid)); pmlmepriv->assoc_by_bssid = false; diff --git a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c index 7a36661ebbed..8f28aefbe6f9 100644 --- a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c @@ -402,7 +402,7 @@ static void issue_beacon(struct adapter *padapter, int timeout_ms) pattrib->pktlen += 2; /* SSID */ - pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pattrib->pktlen); + pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->ssid.ssid_length, cur_network->ssid.ssid, &pattrib->pktlen); /* supported rates... */ rate_len = rtw_get_rateset_len(cur_network->SupportedRates); @@ -562,7 +562,7 @@ static void issue_probersp(struct adapter *padapter, unsigned char *da) /* below for ad-hoc mode */ /* SSID */ - pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pattrib->pktlen); + pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->ssid.ssid_length, cur_network->ssid.ssid, &pattrib->pktlen); /* supported rates... */ rate_len = rtw_get_rateset_len(cur_network->SupportedRates); @@ -652,7 +652,7 @@ static int issue_probereq(struct adapter *padapter, pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr); if (pssid) - pframe = rtw_set_ie(pframe, _SSID_IE_, pssid->SsidLength, pssid->Ssid, &pattrib->pktlen); + pframe = rtw_set_ie(pframe, _SSID_IE_, pssid->ssid_length, pssid->ssid, &pattrib->pktlen); else pframe = rtw_set_ie(pframe, _SSID_IE_, 0, NULL, &pattrib->pktlen); @@ -1059,7 +1059,7 @@ static void issue_assocreq(struct adapter *padapter) pattrib->pktlen += 2; /* SSID */ - pframe = rtw_set_ie(pframe, _SSID_IE_, pmlmeinfo->network.Ssid.SsidLength, pmlmeinfo->network.Ssid.Ssid, &pattrib->pktlen); + pframe = rtw_set_ie(pframe, _SSID_IE_, pmlmeinfo->network.ssid.ssid_length, pmlmeinfo->network.ssid.ssid, &pattrib->pktlen); /* supported rate & extended supported rate */ @@ -1929,7 +1929,7 @@ static void site_survey(struct adapter *padapter) int i; for (i = 0; i < RTW_SSID_SCAN_AMOUNT; i++) { - if (pmlmeext->sitesurvey_res.ssid[i].SsidLength) { + if (pmlmeext->sitesurvey_res.ssid[i].ssid_length) { /* todo: to issue two probe req??? */ issue_probereq(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), @@ -2071,10 +2071,10 @@ static u8 collect_bss_info(struct adapter *padapter, DBG_88E("%s()-%d: IE too long (%d) for survey event\n", __func__, __LINE__, len); return _FAIL; } - memcpy(bssid->Ssid.Ssid, (p + 2), len); - bssid->Ssid.SsidLength = len; + memcpy(bssid->ssid.ssid, (p + 2), len); + bssid->ssid.ssid_length = len; } else { - bssid->Ssid.SsidLength = 0; + bssid->ssid.ssid_length = 0; } memset(bssid->SupportedRates, 0, NDIS_802_11_LENGTH_RATES_EX); @@ -2526,7 +2526,7 @@ static unsigned int OnProbeReq(struct adapter *padapter, /* check (wildcard) SSID */ if (p) { - if ((ielen != 0 && memcmp((void *)(p+2), (void *)cur->Ssid.Ssid, cur->Ssid.SsidLength)) || + if ((ielen != 0 && memcmp((void *)(p+2), (void *)cur->ssid.ssid, cur->ssid.ssid_length)) || (ielen == 0 && pmlmeinfo->hidden_ssid_mode)) return _SUCCESS; @@ -2975,10 +2975,10 @@ static unsigned int OnAssocReq(struct adapter *padapter, goto OnAssocReqFail; } else { /* check if ssid match */ - if (memcmp((void *)(p+2), cur->Ssid.Ssid, cur->Ssid.SsidLength)) + if (memcmp((void *)(p+2), cur->ssid.ssid, cur->ssid.ssid_length)) status = _STATS_FAILURE_; - if (ie_len != cur->Ssid.SsidLength) + if (ie_len != cur->ssid.ssid_length) status = _STATS_FAILURE_; } @@ -4658,7 +4658,7 @@ void linked_status_chk(struct adapter *padapter) } if (rx_chk != _SUCCESS) - issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, psta->hwaddr, 3, 1); + issue_probereq_ex(padapter, &pmlmeinfo->network.ssid, psta->hwaddr, 3, 1); if ((tx_chk != _SUCCESS && pmlmeinfo->link_count++ == 0xf) || rx_chk != _SUCCESS) { tx_chk = issue_nulldata(padapter, psta->hwaddr, 0, 3, 1); @@ -4674,15 +4674,15 @@ void linked_status_chk(struct adapter *padapter) if (rx_chk != _SUCCESS) { if (pmlmeext->retry == 0) { issue_probereq(padapter, - &pmlmeinfo->network.Ssid, + &pmlmeinfo->network.ssid, pmlmeinfo->network.MacAddress, false); issue_probereq(padapter, - &pmlmeinfo->network.Ssid, + &pmlmeinfo->network.ssid, pmlmeinfo->network.MacAddress, false); issue_probereq(padapter, - &pmlmeinfo->network.Ssid, + &pmlmeinfo->network.ssid, pmlmeinfo->network.MacAddress, false); } @@ -5136,11 +5136,11 @@ u8 sitesurvey_cmd_hdl(struct adapter *padapter, u8 *pbuf) pmlmeext->sitesurvey_res.channel_idx = 0; for (i = 0; i < RTW_SSID_SCAN_AMOUNT; i++) { - if (pparm->ssid[i].SsidLength) { - memcpy(pmlmeext->sitesurvey_res.ssid[i].Ssid, pparm->ssid[i].Ssid, IW_ESSID_MAX_SIZE); - pmlmeext->sitesurvey_res.ssid[i].SsidLength = pparm->ssid[i].SsidLength; + if (pparm->ssid[i].ssid_length) { + memcpy(pmlmeext->sitesurvey_res.ssid[i].ssid, pparm->ssid[i].ssid, IW_ESSID_MAX_SIZE); + pmlmeext->sitesurvey_res.ssid[i].ssid_length = pparm->ssid[i].ssid_length; } else { - pmlmeext->sitesurvey_res.ssid[i].SsidLength = 0; + pmlmeext->sitesurvey_res.ssid[i].ssid_length = 0; } } diff --git a/drivers/staging/rtl8188eu/core/rtw_wlan_util.c b/drivers/staging/rtl8188eu/core/rtw_wlan_util.c index 5f9c9de1f1da..4480deef95a1 100644 --- a/drivers/staging/rtl8188eu/core/rtw_wlan_util.c +++ b/drivers/staging/rtl8188eu/core/rtw_wlan_util.c @@ -935,17 +935,17 @@ int rtw_check_bcn_info(struct adapter *Adapter, u8 *pframe, u32 packet_len) if (ssid_len > NDIS_802_11_LENGTH_SSID) ssid_len = 0; } - memcpy(bssid->Ssid.Ssid, (p + 2), ssid_len); - bssid->Ssid.SsidLength = ssid_len; + memcpy(bssid->ssid.ssid, (p + 2), ssid_len); + bssid->ssid.ssid_length = ssid_len; - RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("%s bssid.Ssid.Ssid:%s bssid.Ssid.SsidLength:%d " - "cur_network->network.Ssid.Ssid:%s len:%d\n", __func__, bssid->Ssid.Ssid, - bssid->Ssid.SsidLength, cur_network->network.Ssid.Ssid, - cur_network->network.Ssid.SsidLength)); + RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("%s bssid.ssid.ssid:%s bssid.ssid.ssid_length:%d " + "cur_network->network.ssid.ssid:%s len:%d\n", __func__, bssid->ssid.ssid, + bssid->ssid.ssid_length, cur_network->network.ssid.ssid, + cur_network->network.ssid.ssid_length)); - if (memcmp(bssid->Ssid.Ssid, cur_network->network.Ssid.Ssid, 32) || - bssid->Ssid.SsidLength != cur_network->network.Ssid.SsidLength) { - if (bssid->Ssid.Ssid[0] != '\0' && bssid->Ssid.SsidLength != 0) { /* not hidden ssid */ + if (memcmp(bssid->ssid.ssid, cur_network->network.ssid.ssid, 32) || + bssid->ssid.ssid_length != cur_network->network.ssid.ssid_length) { + if (bssid->ssid.ssid[0] != '\0' && bssid->ssid.ssid_length != 0) { /* not hidden ssid */ DBG_88E("%s(), SSID is not match return FAIL\n", __func__); goto _mismatch; } diff --git a/drivers/staging/rtl8188eu/core/rtw_xmit.c b/drivers/staging/rtl8188eu/core/rtw_xmit.c index 3b1ccd138c3f..1723a47a96b4 100644 --- a/drivers/staging/rtl8188eu/core/rtw_xmit.c +++ b/drivers/staging/rtl8188eu/core/rtw_xmit.c @@ -626,7 +626,7 @@ static s32 xmitframe_addmic(struct adapter *padapter, struct xmit_frame *pxmitfr if (pframe[1] & 2) /* From Ds == 1 */ rtw_secmicappend(&micdata, &pframe[24], 6); else - rtw_secmicappend(&micdata, &pframe[10], 6); + rtw_secmicappend(&micdata, &pframe[10], 6); } else { /* ToDS == 0 */ rtw_secmicappend(&micdata, &pframe[4], 6); /* DA */ if (pframe[1] & 2) /* From Ds == 1 */ diff --git a/drivers/staging/rtl8188eu/hal/odm.c b/drivers/staging/rtl8188eu/hal/odm.c index 1165ee278536..ba3c3e5a8216 100644 --- a/drivers/staging/rtl8188eu/hal/odm.c +++ b/drivers/staging/rtl8188eu/hal/odm.c @@ -209,17 +209,8 @@ void ODM_DMWatchdog(struct odm_dm_struct *pDM_Odm) void ODM_CmnInfoPtrArrayHook(struct odm_dm_struct *pDM_Odm, enum odm_common_info_def CmnInfo, u16 Index, void *pValue) { - /* Hook call by reference pointer. */ - switch (CmnInfo) { - /* Dynamic call by reference pointer. */ - case ODM_CMNINFO_STA_STATUS: + if (CmnInfo == ODM_CMNINFO_STA_STATUS) pDM_Odm->pODM_StaInfo[Index] = (struct sta_info *)pValue; - break; - /* To remove the compiler warning, must add an empty default statement to handle the other values. */ - default: - /* do nothing */ - break; - } } void odm_CommonInfoSelfInit(struct odm_dm_struct *pDM_Odm) diff --git a/drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c b/drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c index 7022221136f6..47352f210c0b 100644 --- a/drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c +++ b/drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c @@ -22,7 +22,7 @@ static u8 _is_fw_read_cmd_down(struct adapter *adapt, u8 msgbox_num) { u8 read_down = false; - int retry_cnts = 100; + int retry_cnts = 100; u8 valid; @@ -118,7 +118,6 @@ exit: void rtw_hal_add_ra_tid(struct adapter *pAdapter, u32 bitmap, u8 arg, u8 rssi_level) { struct odm_dm_struct *odmpriv = &pAdapter->HalData->odmpriv; - u8 macid, init_rate, raid, shortGIrate = false; macid = arg&0x1f; @@ -211,9 +210,9 @@ static void ConstructBeacon(struct adapter *adapt, u8 *pframe, u32 *pLength) struct ieee80211_hdr *pwlanhdr; __le16 *fctrl; u32 rate_len, pktlen; - struct mlme_ext_priv *pmlmeext = &(adapt->mlmeextpriv); - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); - struct wlan_bssid_ex *cur_network = &(pmlmeinfo->network); + struct mlme_ext_priv *pmlmeext = &adapt->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; + struct wlan_bssid_ex *cur_network = &pmlmeinfo->network; u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; pwlanhdr = (struct ieee80211_hdr *)pframe; @@ -222,7 +221,7 @@ static void ConstructBeacon(struct adapter *adapt, u8 *pframe, u32 *pLength) *(fctrl) = 0; ether_addr_copy(pwlanhdr->addr1, bc_addr); - ether_addr_copy(pwlanhdr->addr2, myid(&(adapt->eeprompriv))); + ether_addr_copy(pwlanhdr->addr2, myid(&adapt->eeprompriv)); ether_addr_copy(pwlanhdr->addr3, cur_network->MacAddress); SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/); @@ -257,7 +256,7 @@ static void ConstructBeacon(struct adapter *adapt, u8 *pframe, u32 *pLength) /* below for ad-hoc mode */ /* SSID */ - pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pktlen); + pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->ssid.ssid_length, cur_network->ssid.ssid, &pktlen); /* supported rates... */ rate_len = rtw_get_rateset_len(cur_network->SupportedRates); @@ -294,10 +293,10 @@ _ConstructBeacon: static void ConstructPSPoll(struct adapter *adapt, u8 *pframe, u32 *pLength) { struct ieee80211_hdr *pwlanhdr; - struct mlme_ext_priv *pmlmeext = &(adapt->mlmeextpriv); - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_ext_priv *pmlmeext = &adapt->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; __le16 *fctrl; - struct wlan_bssid_ex *pnetwork = &(pmlmeinfo->network); + struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network; pwlanhdr = (struct ieee80211_hdr *)pframe; @@ -314,7 +313,7 @@ static void ConstructPSPoll(struct adapter *adapt, u8 *pframe, u32 *pLength) ether_addr_copy(pwlanhdr->addr1, pnetwork->MacAddress); /* TA. */ - ether_addr_copy(pwlanhdr->addr2, myid(&(adapt->eeprompriv))); + ether_addr_copy(pwlanhdr->addr2, myid(&adapt->eeprompriv)); *pLength = 16; } @@ -331,10 +330,10 @@ static void ConstructNullFunctionData(struct adapter *adapt, u8 *pframe, __le16 *fctrl; u32 pktlen; struct mlme_priv *pmlmepriv = &adapt->mlmepriv; - struct wlan_network *cur_network = &pmlmepriv->cur_network; - struct mlme_ext_priv *pmlmeext = &(adapt->mlmeextpriv); - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); - struct wlan_bssid_ex *pnetwork = &(pmlmeinfo->network); + struct wlan_network *cur_network = &pmlmepriv->cur_network; + struct mlme_ext_priv *pmlmeext = &adapt->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; + struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network; pwlanhdr = (struct ieee80211_hdr *)pframe; @@ -347,19 +346,19 @@ static void ConstructNullFunctionData(struct adapter *adapt, u8 *pframe, case Ndis802_11Infrastructure: SetToDs(fctrl); ether_addr_copy(pwlanhdr->addr1, pnetwork->MacAddress); - ether_addr_copy(pwlanhdr->addr2, myid(&(adapt->eeprompriv))); + ether_addr_copy(pwlanhdr->addr2, myid(&adapt->eeprompriv)); ether_addr_copy(pwlanhdr->addr3, StaAddr); break; case Ndis802_11APMode: SetFrDs(fctrl); ether_addr_copy(pwlanhdr->addr1, StaAddr); ether_addr_copy(pwlanhdr->addr2, pnetwork->MacAddress); - ether_addr_copy(pwlanhdr->addr3, myid(&(adapt->eeprompriv))); + ether_addr_copy(pwlanhdr->addr3, myid(&adapt->eeprompriv)); break; case Ndis802_11IBSS: default: ether_addr_copy(pwlanhdr->addr1, StaAddr); - ether_addr_copy(pwlanhdr->addr2, myid(&(adapt->eeprompriv))); + ether_addr_copy(pwlanhdr->addr2, myid(&adapt->eeprompriv)); ether_addr_copy(pwlanhdr->addr3, pnetwork->MacAddress); break; } @@ -391,13 +390,13 @@ static void ConstructProbeRsp(struct adapter *adapt, u8 *pframe, u32 *pLength, u __le16 *fctrl; u8 *mac, *bssid; u32 pktlen; - struct mlme_ext_priv *pmlmeext = &(adapt->mlmeextpriv); - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); - struct wlan_bssid_ex *cur_network = &(pmlmeinfo->network); + struct mlme_ext_priv *pmlmeext = &adapt->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; + struct wlan_bssid_ex *cur_network = &pmlmeinfo->network; pwlanhdr = (struct ieee80211_hdr *)pframe; - mac = myid(&(adapt->eeprompriv)); + mac = myid(&adapt->eeprompriv); bssid = cur_network->MacAddress; fctrl = &pwlanhdr->frame_control; @@ -434,11 +433,11 @@ static void ConstructProbeRsp(struct adapter *adapt, u8 *pframe, u32 *pLength, u /* 2009.10.15 by tynli. */ static void SetFwRsvdPagePkt(struct adapter *adapt, bool bDLFinished) { - struct xmit_frame *pmgntframe; - struct pkt_attrib *pattrib; + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; struct xmit_priv *pxmitpriv; struct mlme_ext_priv *pmlmeext; - struct mlme_ext_info *pmlmeinfo; + struct mlme_ext_info *pmlmeinfo; u32 BeaconLength = 0, ProbeRspLength = 0, PSPollLength; u32 NullDataLength, QosNullLength; u8 *ReservedPagePacket; @@ -458,7 +457,7 @@ static void SetFwRsvdPagePkt(struct adapter *adapt, bool bDLFinished) pxmitpriv = &adapt->xmitpriv; pmlmeext = &adapt->mlmeextpriv; pmlmeinfo = &pmlmeext->mlmext_info; - pnetwork = &(pmlmeinfo->network); + pnetwork = &pmlmeinfo->network; TxDescLen = TXDESC_SIZE; PageNum = 0; @@ -476,7 +475,7 @@ static void SetFwRsvdPagePkt(struct adapter *adapt, bool bDLFinished) PageNum += PageNeed; adapt->HalData->FwRsvdPageStartOffset = PageNum; - BufIndex += PageNeed*128; + BufIndex += PageNeed * 128; /* 3 (2) ps-poll *1 page */ RsvdPageLoc.LocPsPoll = PageNum; @@ -486,7 +485,7 @@ static void SetFwRsvdPagePkt(struct adapter *adapt, bool bDLFinished) PageNeed = (u8)PageNum_128(TxDescLen + PSPollLength); PageNum += PageNeed; - BufIndex += PageNeed*128; + BufIndex += PageNeed * 128; /* 3 (3) null data * 1 page */ RsvdPageLoc.LocNullData = PageNum; @@ -496,7 +495,7 @@ static void SetFwRsvdPagePkt(struct adapter *adapt, bool bDLFinished) PageNeed = (u8)PageNum_128(TxDescLen + NullDataLength); PageNum += PageNeed; - BufIndex += PageNeed*128; + BufIndex += PageNeed * 128; /* 3 (4) probe response * 1page */ RsvdPageLoc.LocProbeRsp = PageNum; @@ -506,7 +505,7 @@ static void SetFwRsvdPagePkt(struct adapter *adapt, bool bDLFinished) PageNeed = (u8)PageNum_128(TxDescLen + ProbeRspLength); PageNum += PageNeed; - BufIndex += PageNeed*128; + BufIndex += PageNeed * 128; /* 3 (5) Qos null data */ RsvdPageLoc.LocQosNull = PageNum; @@ -542,10 +541,10 @@ exit: void rtl8188e_set_FwJoinBssReport_cmd(struct adapter *adapt, u8 mstatus) { struct hal_data_8188e *haldata = adapt->HalData; - struct mlme_ext_priv *pmlmeext = &(adapt->mlmeextpriv); - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); - bool bSendBeacon = false; - bool bcn_valid = false; + struct mlme_ext_priv *pmlmeext = &adapt->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; + bool bSendBeacon = false; + bool bcn_valid = false; u8 DLBcnCount = 0; u32 poll = 0; diff --git a/drivers/staging/rtl8188eu/hal/rtl8188eu_xmit.c b/drivers/staging/rtl8188eu/hal/rtl8188eu_xmit.c index a72e069269b8..9e5f23392d58 100644 --- a/drivers/staging/rtl8188eu/hal/rtl8188eu_xmit.c +++ b/drivers/staging/rtl8188eu/hal/rtl8188eu_xmit.c @@ -440,14 +440,14 @@ bool rtl8188eu_xmitframe_complete(struct adapter *adapt, RT_TRACE(_module_rtl8192c_xmit_c_, _drv_info_, ("+xmitframe_complete\n")); pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv); - if (pxmitbuf == NULL) + if (!pxmitbuf) return false; /* 3 1. pick up first frame */ rtw_free_xmitframe(pxmitpriv, pxmitframe); pxmitframe = rtw_dequeue_xframe(pxmitpriv, pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry); - if (pxmitframe == NULL) { + if (!pxmitframe) { /* no more xmit frame, release xmit buffer */ rtw_free_xmitbuf(pxmitpriv, pxmitbuf); return false; diff --git a/drivers/staging/rtl8188eu/include/odm.h b/drivers/staging/rtl8188eu/include/odm.h index 947481de9cb1..8245cea2feef 100644 --- a/drivers/staging/rtl8188eu/include/odm.h +++ b/drivers/staging/rtl8188eu/include/odm.h @@ -1045,7 +1045,6 @@ extern u8 CCKSwingTable_Ch14[CCK_TABLE_SIZE][8]; void ODM_RF_Saving(struct odm_dm_struct *pDM_Odm, u8 bForceInNormal); void ODM_TXPowerTrackingCheck(struct odm_dm_struct *pDM_Odm); -void odm_DIGbyRSSI_LPS(struct odm_dm_struct *pDM_Odm); void ODM_Write_CCK_CCA_Thres(struct odm_dm_struct *pDM_Odm, u8 CurCCK_CCAThres); bool ODM_RAStateCheck(struct odm_dm_struct *pDM_Odm, s32 RSSI, bool bForceUpdate, u8 *pRATRState); diff --git a/drivers/staging/rtl8188eu/include/odm_hwconfig.h b/drivers/staging/rtl8188eu/include/odm_hwconfig.h index 8cef32dc6350..2cd8a47a3673 100644 --- a/drivers/staging/rtl8188eu/include/odm_hwconfig.h +++ b/drivers/staging/rtl8188eu/include/odm_hwconfig.h @@ -93,18 +93,9 @@ struct phy_status_rpt { #endif }; -void odm_Init_RSSIForDM(struct odm_dm_struct *pDM_Odm); - void ODM_PhyStatusQuery(struct odm_dm_struct *pDM_Odm, struct odm_phy_status_info *pPhyInfo, u8 *pPhyStatus, struct odm_per_pkt_info *pPktinfo); -void ODM_MacStatusQuery(struct odm_dm_struct *pDM_Odm, - u8 *pMacStatus, - u8 MacID, - bool bPacketMatchBSSID, - bool bPacketToSelf, - bool bPacketBeacon); - #endif diff --git a/drivers/staging/rtl8188eu/include/wifi.h b/drivers/staging/rtl8188eu/include/wifi.h index 0664d5f30a96..5e91b9428c16 100644 --- a/drivers/staging/rtl8188eu/include/wifi.h +++ b/drivers/staging/rtl8188eu/include/wifi.h @@ -791,18 +791,6 @@ enum ht_cap_ampdu_factor { #define WPS_CM_SW_DISPLAY_P 0x2008 #define WPS_CM_LCD_DISPLAY_P 0x4008 -#define P2P_PRIVATE_IOCTL_SET_LEN 64 - -enum P2P_PROTO_WK_ID { - P2P_FIND_PHASE_WK = 0, - P2P_RESTORE_STATE_WK = 1, - P2P_PRE_TX_PROVDISC_PROCESS_WK = 2, - P2P_PRE_TX_NEGOREQ_PROCESS_WK = 3, - P2P_PRE_TX_INVITEREQ_PROCESS_WK = 4, - P2P_AP_P2P_CH_SWITCH_PROCESS_WK = 5, - P2P_RO_CH_WK = 6, -}; - /* =====================WFD Section===================== */ /* For Wi-Fi Display */ #define WFD_ATTR_DEVICE_INFO 0x00 diff --git a/drivers/staging/rtl8188eu/include/wlan_bssdef.h b/drivers/staging/rtl8188eu/include/wlan_bssdef.h index 5e13a6ddf083..8462c9c2fd39 100644 --- a/drivers/staging/rtl8188eu/include/wlan_bssdef.h +++ b/drivers/staging/rtl8188eu/include/wlan_bssdef.h @@ -17,8 +17,8 @@ #define NDIS_802_11_RSSI long /* in dBm */ struct ndis_802_11_ssid { - u32 SsidLength; - u8 Ssid[32]; + u32 ssid_length; + u8 ssid[32]; }; enum NDIS_802_11_NETWORK_TYPE { @@ -180,7 +180,7 @@ struct wlan_bssid_ex { u32 Length; unsigned char MacAddress[ETH_ALEN]; u8 Reserved[2];/* 0]: IS beacon frame */ - struct ndis_802_11_ssid Ssid; + struct ndis_802_11_ssid ssid; u32 Privacy; NDIS_802_11_RSSI Rssi;/* in dBM,raw data ,get from PHY) */ enum NDIS_802_11_NETWORK_TYPE NetworkTypeInUse; diff --git a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c index efaa1c779f4b..eaa4adb32a0d 100644 --- a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c +++ b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c @@ -116,8 +116,8 @@ static char *translate_scan(struct adapter *padapter, /* Add the ESSID */ iwe.cmd = SIOCGIWESSID; iwe.u.data.flags = 1; - iwe.u.data.length = min_t(u16, pnetwork->network.Ssid.SsidLength, 32); - start = iwe_stream_add_point(info, start, stop, &iwe, pnetwork->network.Ssid.Ssid); + iwe.u.data.length = min_t(u16, pnetwork->network.ssid.ssid_length, 32); + start = iwe_stream_add_point(info, start, stop, &iwe, pnetwork->network.ssid.ssid); /* parsing HT_CAP_IE */ p = rtw_get_ie(&pnetwork->network.ies[12], _HT_CAPABILITY_IE_, &ht_ielen, pnetwork->network.ie_length-12); @@ -195,7 +195,7 @@ static char *translate_scan(struct adapter *padapter, else iwe.u.data.flags = IW_ENCODE_DISABLED; iwe.u.data.length = 0; - start = iwe_stream_add_point(info, start, stop, &iwe, pnetwork->network.Ssid.Ssid); + start = iwe_stream_add_point(info, start, stop, &iwe, pnetwork->network.ssid.ssid); /*Add basic and extended rates */ max_rate = 0; @@ -235,7 +235,7 @@ static char *translate_scan(struct adapter *padapter, u8 *p; rtw_get_sec_ie(pnetwork->network.ies, pnetwork->network.ie_length, rsn_ie, &rsn_len, wpa_ie, &wpa_len); - RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_get_scan: ssid =%s\n", pnetwork->network.Ssid.Ssid)); + RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_get_scan: ssid =%s\n", pnetwork->network.ssid.ssid)); RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_get_scan: wpa_len =%d rsn_len =%d\n", wpa_len, rsn_len)); if (wpa_len > 0) { @@ -1124,8 +1124,8 @@ static int rtw_wx_set_scan(struct net_device *dev, struct iw_request_info *a, int len = min_t(int, req->essid_len, IW_ESSID_MAX_SIZE); - memcpy(ssid[0].Ssid, req->essid, len); - ssid[0].SsidLength = len; + memcpy(ssid[0].ssid, req->essid, len); + ssid[0].ssid_length = len; DBG_88E("IW_SCAN_THIS_ESSID, ssid =%s, len =%d\n", req->essid, req->essid_len); @@ -1158,8 +1158,8 @@ static int rtw_wx_set_scan(struct net_device *dev, struct iw_request_info *a, } sec_len = *(pos++); len -= 1; if (sec_len > 0 && sec_len <= len) { - ssid[ssid_index].SsidLength = sec_len; - memcpy(ssid[ssid_index].Ssid, pos, ssid[ssid_index].SsidLength); + ssid[ssid_index].ssid_length = sec_len; + memcpy(ssid[ssid_index].ssid, pos, ssid[ssid_index].ssid_length); ssid_index++; } pos += sec_len; @@ -1310,9 +1310,9 @@ static int rtw_wx_set_essid(struct net_device *dev, DBG_88E("ssid =%s, len =%d\n", extra, wrqu->essid.length); memset(&ndis_ssid, 0, sizeof(struct ndis_802_11_ssid)); - ndis_ssid.SsidLength = len; - memcpy(ndis_ssid.Ssid, extra, len); - src_ssid = ndis_ssid.Ssid; + ndis_ssid.ssid_length = len; + memcpy(ndis_ssid.ssid, extra, len); + src_ssid = ndis_ssid.ssid; RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, ("rtw_wx_set_essid: ssid =[%s]\n", src_ssid)); spin_lock_bh(&queue->lock); @@ -1324,14 +1324,14 @@ static int rtw_wx_set_essid(struct net_device *dev, pmlmepriv->pscanned = pmlmepriv->pscanned->next; - dst_ssid = pnetwork->network.Ssid.Ssid; + dst_ssid = pnetwork->network.ssid.ssid; RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, ("rtw_wx_set_essid: dst_ssid =%s\n", - pnetwork->network.Ssid.Ssid)); + pnetwork->network.ssid.ssid)); - if ((!memcmp(dst_ssid, src_ssid, ndis_ssid.SsidLength)) && - (pnetwork->network.Ssid.SsidLength == ndis_ssid.SsidLength)) { + if ((!memcmp(dst_ssid, src_ssid, ndis_ssid.ssid_length)) && + (pnetwork->network.ssid.ssid_length == ndis_ssid.ssid_length)) { RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, ("rtw_wx_set_essid: find match, set infra mode\n")); @@ -1378,8 +1378,8 @@ static int rtw_wx_get_essid(struct net_device *dev, if ((check_fwstate(pmlmepriv, _FW_LINKED)) || (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE))) { - len = pcur_bss->Ssid.SsidLength; - memcpy(extra, pcur_bss->Ssid.Ssid, len); + len = pcur_bss->ssid.ssid_length; + memcpy(extra, pcur_bss->ssid.ssid, len); } else { len = 0; *extra = 0; diff --git a/drivers/staging/rtl8188eu/os_dep/mlme_linux.c b/drivers/staging/rtl8188eu/os_dep/mlme_linux.c index d5ceb3beabbc..9db11b16cb93 100644 --- a/drivers/staging/rtl8188eu/os_dep/mlme_linux.c +++ b/drivers/staging/rtl8188eu/os_dep/mlme_linux.c @@ -13,7 +13,7 @@ void rtw_init_mlme_timer(struct adapter *padapter) { - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; timer_setup(&pmlmepriv->assoc_timer, _rtw_join_timeout_handler, 0); timer_setup(&pmlmepriv->scan_to_timer, rtw_scan_timeout_handler, 0); @@ -36,34 +36,38 @@ static struct rt_pmkid_list backup_pmkid[NUM_PMKID_CACHE]; void rtw_reset_securitypriv(struct adapter *adapter) { - u8 backup_index = 0; - u8 backup_counter = 0x00; - u32 backup_time = 0; - - if (adapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) { - /* 802.1x */ - /* We have to backup the PMK information for WiFi PMK Caching test item. */ - /* Backup the btkip_countermeasure information. */ - /* When the countermeasure is trigger, the driver have to disconnect with AP for 60 seconds. */ - memcpy(&backup_pmkid[0], &adapter->securitypriv.PMKIDList[0], sizeof(struct rt_pmkid_list) * NUM_PMKID_CACHE); - backup_index = adapter->securitypriv.PMKIDIndex; - backup_counter = adapter->securitypriv.btkip_countermeasure; - backup_time = adapter->securitypriv.btkip_countermeasure_time; - memset((unsigned char *)&adapter->securitypriv, 0, sizeof(struct security_priv)); - - /* Restore the PMK information to securitypriv structure for the following connection. */ - memcpy(&adapter->securitypriv.PMKIDList[0], - &backup_pmkid[0], - sizeof(struct rt_pmkid_list) * NUM_PMKID_CACHE); - adapter->securitypriv.PMKIDIndex = backup_index; - adapter->securitypriv.btkip_countermeasure = backup_counter; - adapter->securitypriv.btkip_countermeasure_time = backup_time; - adapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen; - adapter->securitypriv.ndisencryptstatus = Ndis802_11WEPDisabled; + u8 backup_index; + u8 backup_counter; + u32 backup_time; + struct security_priv *psec_priv = &adapter->securitypriv; + + if (psec_priv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) { + /* 802.1x + * We have to backup the PMK information for WiFi PMK Caching + * test item. Backup the btkip_countermeasure information. When + * the countermeasure is trigger, the driver have to disconnect + * with AP for 60 seconds. + */ + memcpy(backup_pmkid, psec_priv->PMKIDList, + sizeof(struct rt_pmkid_list) * NUM_PMKID_CACHE); + backup_index = psec_priv->PMKIDIndex; + backup_counter = psec_priv->btkip_countermeasure; + backup_time = psec_priv->btkip_countermeasure_time; + + memset(psec_priv, 0, sizeof(*psec_priv)); + + /* Restore the PMK information to securitypriv structure + * for the following connection. + */ + memcpy(psec_priv->PMKIDList, backup_pmkid, + sizeof(struct rt_pmkid_list) * NUM_PMKID_CACHE); + psec_priv->PMKIDIndex = backup_index; + psec_priv->btkip_countermeasure = backup_counter; + psec_priv->btkip_countermeasure_time = backup_time; + psec_priv->ndisauthtype = Ndis802_11AuthModeOpen; + psec_priv->ndisencryptstatus = Ndis802_11WEPDisabled; } else { /* reset values in securitypriv */ - struct security_priv *psec_priv = &adapter->securitypriv; - psec_priv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open; psec_priv->dot11PrivacyAlgrthm = _NO_PRIVACY_; psec_priv->dot11PrivacyKeyIndex = 0; @@ -76,15 +80,16 @@ void rtw_reset_securitypriv(struct adapter *adapter) void rtw_os_indicate_disconnect(struct adapter *adapter) { - netif_carrier_off(adapter->pnetdev); /* Do it first for tx broadcast pkt after disconnection issue! */ + /* Do it first for tx broadcast pkt after disconnection issue! */ + netif_carrier_off(adapter->pnetdev); rtw_indicate_wx_disassoc_event(adapter); rtw_reset_securitypriv(adapter); } void rtw_report_sec_ie(struct adapter *adapter, u8 authmode, u8 *sec_ie) { - uint len; - u8 *buff, *p, i; + uint len; + u8 *buff, *p, i; union iwreq_data wrqu; RT_TRACE(_module_mlme_osdep_c_, _drv_info_, @@ -99,14 +104,13 @@ void rtw_report_sec_ie(struct adapter *adapter, u8 authmode, u8 *sec_ie) memset(buff, 0, IW_CUSTOM_MAX); p = buff; p += sprintf(p, "ASSOCINFO(ReqIEs ="); - len = sec_ie[1]+2; + len = sec_ie[1] + 2; len = min_t(uint, len, IW_CUSTOM_MAX); for (i = 0; i < len; i++) p += sprintf(p, "%02x", sec_ie[i]); p += sprintf(p, ")"); memset(&wrqu, 0, sizeof(wrqu)); - wrqu.data.length = p-buff; - wrqu.data.length = min_t(__u16, wrqu.data.length, IW_CUSTOM_MAX); + wrqu.data.length = min_t(__u16, p - buff, IW_CUSTOM_MAX); wireless_send_event(adapter->pnetdev, IWEVCUSTOM, &wrqu, buff); kfree(buff); } @@ -119,7 +123,7 @@ void init_addba_retry_timer(struct adapter *padapter, struct sta_info *psta) void init_mlme_ext_timer(struct adapter *padapter) { - struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; timer_setup(&pmlmeext->survey_timer, survey_timer_hdl, 0); timer_setup(&pmlmeext->link_timer, link_timer_hdl, 0); diff --git a/drivers/staging/rtl8188eu/os_dep/os_intfs.c b/drivers/staging/rtl8188eu/os_dep/os_intfs.c index abcce2240f15..8dde5a40e253 100644 --- a/drivers/staging/rtl8188eu/os_dep/os_intfs.c +++ b/drivers/staging/rtl8188eu/os_dep/os_intfs.c @@ -137,12 +137,12 @@ static int netdev_close(struct net_device *pnetdev); static void loadparam(struct adapter *padapter, struct net_device *pnetdev) { - struct registry_priv *registry_par = &padapter->registrypriv; + struct registry_priv *registry_par = &padapter->registrypriv; GlobalDebugLevel = rtw_debug; - memcpy(registry_par->ssid.Ssid, "ANY", 3); - registry_par->ssid.SsidLength = 3; + memcpy(registry_par->ssid.ssid, "ANY", 3); + registry_par->ssid.ssid_length = 3; registry_par->channel = (u8)rtw_channel; registry_par->wireless_mode = (u8)rtw_wireless_mode; @@ -198,8 +198,8 @@ static int rtw_net_set_mac_address(struct net_device *pnetdev, void *p) static struct net_device_stats *rtw_net_get_stats(struct net_device *pnetdev) { struct adapter *padapter = (struct adapter *)rtw_netdev_priv(pnetdev); - struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); - struct recv_priv *precvpriv = &(padapter->recvpriv); + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + struct recv_priv *precvpriv = &padapter->recvpriv; padapter->stats.tx_packets = pxmitpriv->tx_pkts; padapter->stats.rx_packets = precvpriv->rx_pkts; @@ -248,7 +248,7 @@ static u16 rtw_select_queue(struct net_device *dev, struct sk_buff *skb, struct net_device *sb_dev, select_queue_fallback_t fallback) { - struct adapter *padapter = rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); struct mlme_priv *pmlmepriv = &padapter->mlmepriv; skb->priority = rtw_classify8021d(skb); @@ -263,15 +263,15 @@ u16 rtw_recv_select_queue(struct sk_buff *skb) { struct iphdr *piphdr; unsigned int dscp; - __be16 eth_type; + __be16 eth_type; u32 priority; u8 *pdata = skb->data; - memcpy(ð_type, pdata+(ETH_ALEN<<1), 2); + memcpy(ð_type, pdata + (ETH_ALEN << 1), 2); switch (eth_type) { case htons(ETH_P_IP): - piphdr = (struct iphdr *)(pdata+ETH_HLEN); + piphdr = (struct iphdr *)(pdata + ETH_HLEN); dscp = piphdr->tos & 0xfc; priority = dscp >> 5; break; @@ -286,7 +286,7 @@ static const struct net_device_ops rtw_netdev_ops = { .ndo_open = netdev_open, .ndo_stop = netdev_close, .ndo_start_xmit = rtw_xmit_entry, - .ndo_select_queue = rtw_select_queue, + .ndo_select_queue = rtw_select_queue, .ndo_set_mac_address = rtw_net_set_mac_address, .ndo_get_stats = rtw_net_get_stats, .ndo_do_ioctl = rtw_ioctl, @@ -323,7 +323,7 @@ struct net_device *rtw_init_netdev(struct adapter *old_padapter) padapter->pnetdev = pnetdev; DBG_88E("register rtw_netdev_ops to netdev_ops\n"); pnetdev->netdev_ops = &rtw_netdev_ops; - pnetdev->watchdog_timeo = HZ*3; /* 3 second timeout */ + pnetdev->watchdog_timeo = HZ * 3; /* 3 second timeout */ pnetdev->wireless_handlers = (struct iw_handler_def *)&rtw_handlers_def; loadparam(padapter, pnetdev); @@ -361,7 +361,7 @@ void rtw_stop_drv_threads(struct adapter *padapter) static u8 rtw_init_default_value(struct adapter *padapter) { struct registry_priv *pregistrypriv = &padapter->registrypriv; - struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct security_priv *psecuritypriv = &padapter->securitypriv; @@ -431,7 +431,7 @@ u8 rtw_reset_drv_sw(struct adapter *padapter) u8 rtw_init_drv_sw(struct adapter *padapter) { - u8 ret8 = _SUCCESS; + u8 ret8 = _SUCCESS; RT_TRACE(_module_os_intfs_c_, _drv_info_, ("+rtw_init_drv_sw\n")); diff --git a/drivers/staging/rtl8188eu/os_dep/rtw_android.c b/drivers/staging/rtl8188eu/os_dep/rtw_android.c index 2ea2af3286bc..7a090615dcbc 100644 --- a/drivers/staging/rtl8188eu/os_dep/rtw_android.c +++ b/drivers/staging/rtl8188eu/os_dep/rtw_android.c @@ -84,7 +84,7 @@ static int rtw_android_get_rssi(struct net_device *net, char *command, if (check_fwstate(pmlmepriv, _FW_LINKED)) { bytes_written += snprintf(&command[bytes_written], total_len, "%s rssi %d", - pcur_network->network.Ssid.Ssid, + pcur_network->network.ssid.ssid, padapter->recvpriv.rssi); } return bytes_written; diff --git a/drivers/staging/rtl8188eu/os_dep/usb_intf.c b/drivers/staging/rtl8188eu/os_dep/usb_intf.c index dfee6985efa6..664d93a7f90d 100644 --- a/drivers/staging/rtl8188eu/os_dep/usb_intf.c +++ b/drivers/staging/rtl8188eu/os_dep/usb_intf.c @@ -228,10 +228,10 @@ static int rtw_suspend(struct usb_interface *pusb_intf, pm_message_t message) check_fwstate(pmlmepriv, _FW_LINKED)) { pr_debug("%s:%d %s(%pM), length:%d assoc_ssid.length:%d\n", __func__, __LINE__, - pmlmepriv->cur_network.network.Ssid.Ssid, + pmlmepriv->cur_network.network.ssid.ssid, pmlmepriv->cur_network.network.MacAddress, - pmlmepriv->cur_network.network.Ssid.SsidLength, - pmlmepriv->assoc_ssid.SsidLength); + pmlmepriv->cur_network.network.ssid.ssid_length, + pmlmepriv->assoc_ssid.ssid_length); pmlmepriv->to_roaming = 1; } diff --git a/drivers/staging/rtl8192e/dot11d.c b/drivers/staging/rtl8192e/dot11d.c index a1c096124683..68f53013cb95 100644 --- a/drivers/staging/rtl8192e/dot11d.c +++ b/drivers/staging/rtl8192e/dot11d.c @@ -15,11 +15,11 @@ #include "dot11d.h" struct channel_list { - u8 Channel[32]; - u8 Len; + u8 channel[32]; + u8 len; }; -static struct channel_list ChannelPlan[] = { +static struct channel_list channel_array[] = { {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165}, 24}, {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 11}, @@ -44,130 +44,130 @@ static struct channel_list ChannelPlan[] = { void dot11d_init(struct rtllib_device *ieee) { - struct rt_dot11d_info *pDot11dInfo = GET_DOT11D_INFO(ieee); + struct rt_dot11d_info *dot11d_info = GET_DOT11D_INFO(ieee); - pDot11dInfo->bEnabled = false; + dot11d_info->enabled = false; - pDot11dInfo->State = DOT11D_STATE_NONE; - pDot11dInfo->CountryIeLen = 0; - memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER + 1); - memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER + 1); + dot11d_info->state = DOT11D_STATE_NONE; + dot11d_info->country_len = 0; + memset(dot11d_info->channel_map, 0, MAX_CHANNEL_NUMBER + 1); + memset(dot11d_info->max_tx_power_list, 0xFF, MAX_CHANNEL_NUMBER + 1); RESET_CIE_WATCHDOG(ieee); } EXPORT_SYMBOL(dot11d_init); -void Dot11d_Channelmap(u8 channel_plan, struct rtllib_device *ieee) +void dot11d_channel_map(u8 channel_plan, struct rtllib_device *ieee) { int i, max_chan = 14, min_chan = 1; - ieee->bGlobalDomain = false; + ieee->global_domain = false; - if (ChannelPlan[channel_plan].Len != 0) { + if (channel_array[channel_plan].len != 0) { memset(GET_DOT11D_INFO(ieee)->channel_map, 0, sizeof(GET_DOT11D_INFO(ieee)->channel_map)); - for (i = 0; i < ChannelPlan[channel_plan].Len; i++) { - if (ChannelPlan[channel_plan].Channel[i] < min_chan || - ChannelPlan[channel_plan].Channel[i] > max_chan) + for (i = 0; i < channel_array[channel_plan].len; i++) { + if (channel_array[channel_plan].channel[i] < min_chan || + channel_array[channel_plan].channel[i] > max_chan) break; - GET_DOT11D_INFO(ieee)->channel_map[ChannelPlan - [channel_plan].Channel[i]] = 1; + GET_DOT11D_INFO(ieee)->channel_map[channel_array + [channel_plan].channel[i]] = 1; } } switch (channel_plan) { case COUNTRY_CODE_GLOBAL_DOMAIN: - ieee->bGlobalDomain = true; + ieee->global_domain = true; for (i = 12; i <= 14; i++) GET_DOT11D_INFO(ieee)->channel_map[i] = 2; - ieee->IbssStartChnl = 10; + ieee->bss_start_channel = 10; ieee->ibss_maxjoin_chal = 11; break; case COUNTRY_CODE_WORLD_WIDE_13: for (i = 12; i <= 13; i++) GET_DOT11D_INFO(ieee)->channel_map[i] = 2; - ieee->IbssStartChnl = 10; + ieee->bss_start_channel = 10; ieee->ibss_maxjoin_chal = 11; break; default: - ieee->IbssStartChnl = 1; + ieee->bss_start_channel = 1; ieee->ibss_maxjoin_chal = 14; break; } } -EXPORT_SYMBOL(Dot11d_Channelmap); +EXPORT_SYMBOL(dot11d_channel_map); -void Dot11d_Reset(struct rtllib_device *ieee) +void dot11d_reset(struct rtllib_device *ieee) { - struct rt_dot11d_info *pDot11dInfo = GET_DOT11D_INFO(ieee); + struct rt_dot11d_info *dot11d_info = GET_DOT11D_INFO(ieee); u32 i; - memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER + 1); - memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER + 1); + memset(dot11d_info->channel_map, 0, MAX_CHANNEL_NUMBER + 1); + memset(dot11d_info->max_tx_power_list, 0xFF, MAX_CHANNEL_NUMBER + 1); for (i = 1; i <= 11; i++) - (pDot11dInfo->channel_map)[i] = 1; + (dot11d_info->channel_map)[i] = 1; for (i = 12; i <= 14; i++) - (pDot11dInfo->channel_map)[i] = 2; - pDot11dInfo->State = DOT11D_STATE_NONE; - pDot11dInfo->CountryIeLen = 0; + (dot11d_info->channel_map)[i] = 2; + dot11d_info->state = DOT11D_STATE_NONE; + dot11d_info->country_len = 0; RESET_CIE_WATCHDOG(ieee); } -void Dot11d_UpdateCountryIe(struct rtllib_device *dev, u8 *pTaddr, - u16 CoutryIeLen, u8 *pCoutryIe) +void dot11d_update_country(struct rtllib_device *dev, u8 *address, + u16 country_len, u8 *country) { - struct rt_dot11d_info *pDot11dInfo = GET_DOT11D_INFO(dev); - u8 i, j, NumTriples, MaxChnlNum; - struct chnl_txpow_triple *pTriple; - - memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER + 1); - memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER + 1); - MaxChnlNum = 0; - NumTriples = (CoutryIeLen - 3) / 3; - pTriple = (struct chnl_txpow_triple *)(pCoutryIe + 3); - for (i = 0; i < NumTriples; i++) { - if (MaxChnlNum >= pTriple->FirstChnl) { + struct rt_dot11d_info *dot11d_info = GET_DOT11D_INFO(dev); + u8 i, j, number_of_triples, max_channel_number; + struct chnl_txpow_triple *triple; + + memset(dot11d_info->channel_map, 0, MAX_CHANNEL_NUMBER + 1); + memset(dot11d_info->max_tx_power_list, 0xFF, MAX_CHANNEL_NUMBER + 1); + max_channel_number = 0; + number_of_triples = (country_len - 3) / 3; + triple = (struct chnl_txpow_triple *)(country + 3); + for (i = 0; i < number_of_triples; i++) { + if (max_channel_number >= triple->first_channel) { netdev_info(dev->dev, "%s: Invalid country IE, skip it......1\n", __func__); return; } - if (MAX_CHANNEL_NUMBER < (pTriple->FirstChnl + - pTriple->NumChnls)) { + if (MAX_CHANNEL_NUMBER < (triple->first_channel + + triple->num_channels)) { netdev_info(dev->dev, "%s: Invalid country IE, skip it......2\n", __func__); return; } - for (j = 0; j < pTriple->NumChnls; j++) { - pDot11dInfo->channel_map[pTriple->FirstChnl + j] = 1; - pDot11dInfo->MaxTxPwrDbmList[pTriple->FirstChnl + j] = - pTriple->MaxTxPowerInDbm; - MaxChnlNum = pTriple->FirstChnl + j; + for (j = 0; j < triple->num_channels; j++) { + dot11d_info->channel_map[triple->first_channel + j] = 1; + dot11d_info->max_tx_power_list[triple->first_channel + j] = + triple->max_tx_power; + max_channel_number = triple->first_channel + j; } - pTriple = (struct chnl_txpow_triple *)((u8 *)pTriple + 3); + triple = (struct chnl_txpow_triple *)((u8 *)triple + 3); } - UPDATE_CIE_SRC(dev, pTaddr); + UPDATE_CIE_SRC(dev, address); - pDot11dInfo->CountryIeLen = CoutryIeLen; - memcpy(pDot11dInfo->CountryIeBuf, pCoutryIe, CoutryIeLen); - pDot11dInfo->State = DOT11D_STATE_LEARNED; + dot11d_info->country_len = country_len; + memcpy(dot11d_info->country_buffer, country, country_len); + dot11d_info->state = DOT11D_STATE_LEARNED; } -void DOT11D_ScanComplete(struct rtllib_device *dev) +void dot11d_scan_complete(struct rtllib_device *dev) { - struct rt_dot11d_info *pDot11dInfo = GET_DOT11D_INFO(dev); + struct rt_dot11d_info *dot11d_info = GET_DOT11D_INFO(dev); - switch (pDot11dInfo->State) { + switch (dot11d_info->state) { case DOT11D_STATE_LEARNED: - pDot11dInfo->State = DOT11D_STATE_DONE; + dot11d_info->state = DOT11D_STATE_DONE; break; case DOT11D_STATE_DONE: - Dot11d_Reset(dev); + dot11d_reset(dev); break; case DOT11D_STATE_NONE: break; diff --git a/drivers/staging/rtl8192e/dot11d.h b/drivers/staging/rtl8192e/dot11d.h index 7fa3c4d963c4..6d2b93acfa43 100644 --- a/drivers/staging/rtl8192e/dot11d.h +++ b/drivers/staging/rtl8192e/dot11d.h @@ -1,14 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /****************************************************************************** * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * * Contact Information: * wlanfae <wlanfae@realtek.com> ******************************************************************************/ @@ -18,9 +11,9 @@ #include "rtllib.h" struct chnl_txpow_triple { - u8 FirstChnl; - u8 NumChnls; - u8 MaxTxPowerInDbm; + u8 first_channel; + u8 num_channels; + u8 max_tx_power; }; enum dot11d_state { @@ -30,62 +23,62 @@ enum dot11d_state { }; /** - * struct rt_dot11d_info * @CountryIeLen: value greater than 0 if - * @CountryIeBuf contains valid country information element. + * struct rt_dot11d_info * @country_len: value greater than 0 if + * @country_buffer contains valid country information element. * @channel_map: holds channel values * 0 - invalid, * 1 - valid (active scan), * 2 - valid (passive scan) - * @CountryIeSrcAddr - Source AP of the country IE + * @country_src_addr - Source AP of the country IE */ struct rt_dot11d_info { - bool bEnabled; + bool enabled; - u16 CountryIeLen; - u8 CountryIeBuf[MAX_IE_LEN]; - u8 CountryIeSrcAddr[6]; - u8 CountryIeWatchdog; + u16 country_len; + u8 country_buffer[MAX_IE_LEN]; + u8 country_src_addr[6]; + u8 country_watchdog; u8 channel_map[MAX_CHANNEL_NUMBER + 1]; - u8 MaxTxPwrDbmList[MAX_CHANNEL_NUMBER + 1]; + u8 max_tx_power_list[MAX_CHANNEL_NUMBER + 1]; - enum dot11d_state State; + enum dot11d_state state; }; -static inline void cpMacAddr(unsigned char *des, unsigned char *src) +static inline void copy_mac_addr(unsigned char *des, unsigned char *src) { memcpy(des, src, 6); } -#define GET_DOT11D_INFO(__pIeeeDev) \ - ((struct rt_dot11d_info *)((__pIeeeDev)->pDot11dInfo)) +#define GET_DOT11D_INFO(__ieee_dev) \ + ((struct rt_dot11d_info *)((__ieee_dev)->dot11d_info)) -#define IS_DOT11D_ENABLE(__pIeeeDev) \ - (GET_DOT11D_INFO(__pIeeeDev)->bEnabled) -#define IS_COUNTRY_IE_VALID(__pIeeeDev) \ - (GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen > 0) +#define IS_DOT11D_ENABLE(__ieee_dev) \ + (GET_DOT11D_INFO(__ieee_dev)->enabled) +#define IS_COUNTRY_IE_VALID(__ieee_dev) \ + (GET_DOT11D_INFO(__ieee_dev)->country_len > 0) -#define IS_EQUAL_CIE_SRC(__pIeeeDev, __pTa) \ +#define IS_EQUAL_CIE_SRC(__ieee_dev, __address) \ ether_addr_equal_unaligned( \ - GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa) -#define UPDATE_CIE_SRC(__pIeeeDev, __pTa) \ - cpMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa) + GET_DOT11D_INFO(__ieee_dev)->country_src_addr, __address) +#define UPDATE_CIE_SRC(__ieee_dev, __address) \ + copy_mac_addr(GET_DOT11D_INFO(__ieee_dev)->country_src_addr, __address) -#define GET_CIE_WATCHDOG(__pIeeeDev) \ - (GET_DOT11D_INFO(__pIeeeDev)->CountryIeWatchdog) -static inline void RESET_CIE_WATCHDOG(struct rtllib_device *__pIeeeDev) +#define GET_CIE_WATCHDOG(__ieee_dev) \ + (GET_DOT11D_INFO(__ieee_dev)->country_watchdog) +static inline void RESET_CIE_WATCHDOG(struct rtllib_device *__ieee_dev) { - GET_CIE_WATCHDOG(__pIeeeDev) = 0; + GET_CIE_WATCHDOG(__ieee_dev) = 0; } -#define UPDATE_CIE_WATCHDOG(__pIeeeDev) (++GET_CIE_WATCHDOG(__pIeeeDev)) +#define UPDATE_CIE_WATCHDOG(__ieee_dev) (++GET_CIE_WATCHDOG(__ieee_dev)) void dot11d_init(struct rtllib_device *dev); -void Dot11d_Channelmap(u8 channel_plan, struct rtllib_device *ieee); -void Dot11d_Reset(struct rtllib_device *dev); -void Dot11d_UpdateCountryIe(struct rtllib_device *dev, u8 *pTaddr, - u16 CoutryIeLen, u8 *pCoutryIe); -void DOT11D_ScanComplete(struct rtllib_device *dev); +void dot11d_channel_map(u8 channel_plan, struct rtllib_device *ieee); +void dot11d_reset(struct rtllib_device *dev); +void dot11d_update_country(struct rtllib_device *dev, u8 *address, + u16 country_len, u8 *country); +void dot11d_scan_complete(struct rtllib_device *dev); #endif diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c b/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c index 1c6ed5b2a6f9..19bb04b3f097 100644 --- a/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c +++ b/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c @@ -660,9 +660,9 @@ static void _rtl92e_hwconfig(struct net_device *dev) case WIRELESS_MODE_AUTO: case WIRELESS_MODE_N_24G: regBwOpMode = BW_OPMODE_20MHZ; - regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | - RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS; - regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG; + regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | + RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS; + regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG; break; case WIRELESS_MODE_N_5G: regBwOpMode = BW_OPMODE_5G; @@ -961,7 +961,7 @@ static void _rtl92e_net_update(struct net_device *dev) net = &priv->rtllib->current_network; rtl92e_config_rate(dev, &rate_config); priv->dot11CurrentPreambleMode = PREAMBLE_AUTO; - priv->basic_rate = rate_config &= 0x15f; + priv->basic_rate = rate_config &= 0x15f; rtl92e_writew(dev, BSSIDR, *(u16 *)net->bssid); rtl92e_writel(dev, BSSIDR + 2, *(u32 *)(net->bssid + 2)); diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c index 96f265eee007..253f1911a3f4 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c @@ -436,7 +436,7 @@ static int _rtl92e_qos_handle_probe_response(struct r8192_priv *priv, network->qos_data.param_count)) { network->qos_data.old_param_count = network->qos_data.param_count; - priv->rtllib->wmm_acm = network->qos_data.wmm_acm; + priv->rtllib->wmm_acm = network->qos_data.wmm_acm; schedule_work(&priv->qos_activate); RT_TRACE(COMP_QOS, "QoS parameters change call qos_activate\n"); @@ -1049,7 +1049,7 @@ static short _rtl92e_get_channel_map(struct net_device *dev) } RT_TRACE(COMP_INIT, "Channel plan is %d\n", priv->ChannelPlan); dot11d_init(priv->rtllib); - Dot11d_Channelmap(priv->ChannelPlan, priv->rtllib); + dot11d_channel_map(priv->ChannelPlan, priv->rtllib); for (i = 1; i <= 11; i++) (priv->rtllib->active_channel_map)[i] = 1; (priv->rtllib->active_channel_map)[12] = 2; @@ -1573,7 +1573,7 @@ static void _rtl92e_free_rx_ring(struct net_device *dev) pci_unmap_single(priv->pdev, *((dma_addr_t *)skb->cb), priv->rxbuffersize, PCI_DMA_FROMDEVICE); - kfree_skb(skb); + kfree_skb(skb); } pci_free_consistent(priv->pdev, @@ -1728,8 +1728,7 @@ static short _rtl92e_tx(struct net_device *dev, struct sk_buff *skb) MAX_DEV_ADDR_SIZE); struct tx_desc *pdesc = NULL; struct rtllib_hdr_1addr *header = NULL; - u16 fc = 0, type = 0, stype = 0; - bool multi_addr = false, broad_addr = false, uni_addr = false; + u16 fc = 0, type = 0; u8 *pda_addr = NULL; int idx; u32 fwinfo_size = 0; @@ -1747,22 +1746,14 @@ static short _rtl92e_tx(struct net_device *dev, struct sk_buff *skb) header = (struct rtllib_hdr_1addr *)(((u8 *)skb->data) + fwinfo_size); fc = le16_to_cpu(header->frame_ctl); type = WLAN_FC_GET_TYPE(fc); - stype = WLAN_FC_GET_STYPE(fc); pda_addr = header->addr1; if (is_broadcast_ether_addr(pda_addr)) - broad_addr = true; + priv->stats.txbytesbroadcast += skb->len - fwinfo_size; else if (is_multicast_ether_addr(pda_addr)) - multi_addr = true; - else - uni_addr = true; - - if (uni_addr) - priv->stats.txbytesunicast += skb->len - fwinfo_size; - else if (multi_addr) priv->stats.txbytesmulticast += skb->len - fwinfo_size; else - priv->stats.txbytesbroadcast += skb->len - fwinfo_size; + priv->stats.txbytesunicast += skb->len - fwinfo_size; spin_lock_irqsave(&priv->irq_th_lock, flags); ring = &priv->tx_ring[tcb_desc->queue_index]; @@ -2515,7 +2506,7 @@ static int _rtl92e_pci_probe(struct pci_dev *pdev, if (dev_alloc_name(dev, ifname) < 0) { RT_TRACE(COMP_INIT, "Oops: devname already taken! Trying wlan%%d...\n"); - dev_alloc_name(dev, ifname); + dev_alloc_name(dev, ifname); } RT_TRACE(COMP_INIT, "Driver probe completed1\n"); diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c b/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c index 9bf95bd0ad13..157bcee34067 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c @@ -996,7 +996,7 @@ static void _rtl92e_dm_check_tx_power_tracking_tssi(struct net_device *dev) tx_power_track_counter++; - if (tx_power_track_counter >= 180) { + if (tx_power_track_counter >= 180) { schedule_delayed_work(&priv->txpower_tracking_wq, 0); tx_power_track_counter = 0; } diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c b/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c index 843e874b8a06..44e06cba7b7b 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c @@ -738,7 +738,7 @@ static int _rtl92e_wx_set_enc(struct net_device *dev, else if (wrqu->encoding.length == 0xd) { ieee->pairwise_key_type = KEY_TYPE_WEP104; - rtl92e_enable_hw_security_config(dev); + rtl92e_enable_hw_security_config(dev); rtl92e_set_key(dev, key_idx, key_idx, KEY_TYPE_WEP104, zero_addr[key_idx], 0, hwkey); rtl92e_set_swcam(dev, key_idx, key_idx, KEY_TYPE_WEP104, @@ -1049,9 +1049,9 @@ static int _rtl92e_wx_set_promisc_mode(struct net_device *dev, (bPromiscuousOn) ? (true) : (false); ieee->IntelPromiscuousModeInfo.bFilterSourceStationFrame = (bFilterSourceStationFrame) ? (true) : (false); - (bPromiscuousOn) ? - (rtllib_EnableIntelPromiscuousMode(dev, false)) : - (rtllib_DisableIntelPromiscuousMode(dev, false)); + (bPromiscuousOn) ? + (rtllib_EnableIntelPromiscuousMode(dev, false)) : + (rtllib_DisableIntelPromiscuousMode(dev, false)); netdev_info(dev, "=======>%s(), on = %d, filter src sta = %d\n", diff --git a/drivers/staging/rtl8192e/rtl819x_BAProc.c b/drivers/staging/rtl8192e/rtl819x_BAProc.c index 687dbb04ed2e..2d330d2bbf6d 100644 --- a/drivers/staging/rtl8192e/rtl819x_BAProc.c +++ b/drivers/staging/rtl8192e/rtl819x_BAProc.c @@ -139,7 +139,7 @@ static struct sk_buff *rtllib_DELBA(struct rtllib_device *ieee, u8 *dst, { union delba_param_set DelbaParamSet; struct sk_buff *skb = NULL; - struct rtllib_hdr_3addr *Delba = NULL; + struct rtllib_hdr_3addr *Delba = NULL; u8 *tag = NULL; u16 len = 6 + ieee->tx_headroom; @@ -316,7 +316,7 @@ OnADDBAReq_Fail: int rtllib_rx_ADDBARsp(struct rtllib_device *ieee, struct sk_buff *skb) { - struct rtllib_hdr_3addr *rsp = NULL; + struct rtllib_hdr_3addr *rsp = NULL; struct ba_record *pPendingBA, *pAdmittedBA; struct tx_ts_record *pTS = NULL; u8 *dst = NULL, *pDialogToken = NULL, *tag = NULL; @@ -420,7 +420,7 @@ OnADDBARsp_Reject: int rtllib_rx_DELBA(struct rtllib_device *ieee, struct sk_buff *skb) { - struct rtllib_hdr_3addr *delba = NULL; + struct rtllib_hdr_3addr *delba = NULL; union delba_param_set *pDelBaParamSet = NULL; u8 *dst = NULL; diff --git a/drivers/staging/rtl8192e/rtllib.h b/drivers/staging/rtl8192e/rtllib.h index c01474a6db1e..61ebd12831c3 100644 --- a/drivers/staging/rtl8192e/rtllib.h +++ b/drivers/staging/rtl8192e/rtllib.h @@ -1560,11 +1560,11 @@ struct rtllib_device { u16 scan_watch_dog; /* map of allowed channels. 0 is dummy */ - void *pDot11dInfo; - bool bGlobalDomain; + void *dot11d_info; + bool global_domain; u8 active_channel_map[MAX_CHANNEL_NUMBER+1]; - u8 IbssStartChnl; + u8 bss_start_channel; u8 ibss_maxjoin_chal; int rate; /* current rate */ diff --git a/drivers/staging/rtl8192e/rtllib_crypt_tkip.c b/drivers/staging/rtl8192e/rtllib_crypt_tkip.c index f38f1f74fcd6..55da8c9dfe50 100644 --- a/drivers/staging/rtl8192e/rtllib_crypt_tkip.c +++ b/drivers/staging/rtl8192e/rtllib_crypt_tkip.c @@ -285,7 +285,7 @@ static void tkip_mixing_phase2(u8 *WEPSeed, const u8 *TK, const u16 *TTAK, static int rtllib_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv) { struct rtllib_tkip_data *tkey = priv; - int len; + int len; u8 *pos; struct rtllib_hdr_4addr *hdr; struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + diff --git a/drivers/staging/rtl8192e/rtllib_rx.c b/drivers/staging/rtl8192e/rtllib_rx.c index fa580ce1cf43..debc2e40af00 100644 --- a/drivers/staging/rtl8192e/rtllib_rx.c +++ b/drivers/staging/rtl8192e/rtllib_rx.c @@ -913,7 +913,7 @@ static size_t rtllib_rx_get_hdrlen(struct rtllib_device *ieee, rx_stats->bContainHTC = true; } - if (RTLLIB_QOS_HAS_SEQ(fc)) + if (RTLLIB_QOS_HAS_SEQ(fc)) rx_stats->bIsQosData = true; return hdrlen; @@ -1812,7 +1812,7 @@ static inline void rtllib_extract_country_ie( netdev_info(ieee->dev, "Received beacon ContryIE, SSID: <%s>\n", network->ssid); - Dot11d_UpdateCountryIe(ieee, addr2, + dot11d_update_country(ieee, addr2, info_element->len, info_element->data); } diff --git a/drivers/staging/rtl8192e/rtllib_softmac.c b/drivers/staging/rtl8192e/rtllib_softmac.c index 287d0c11fa38..ee275857868f 100644 --- a/drivers/staging/rtl8192e/rtllib_softmac.c +++ b/drivers/staging/rtl8192e/rtllib_softmac.c @@ -564,7 +564,7 @@ out: if (ieee->state >= RTLLIB_LINKED) { if (IS_DOT11D_ENABLE(ieee)) - DOT11D_ScanComplete(ieee); + dot11d_scan_complete(ieee); } mutex_unlock(&ieee->scan_mutex); @@ -623,7 +623,7 @@ static void rtllib_softmac_scan_wq(void *data) out: if (IS_DOT11D_ENABLE(ieee)) - DOT11D_ScanComplete(ieee); + dot11d_scan_complete(ieee); ieee->current_network.channel = last_channel; out1: @@ -1688,8 +1688,8 @@ inline void rtllib_softmac_new_net(struct rtllib_device *ieee, ieee->current_network.ssid_len); tmp_ssid_len = ieee->current_network.ssid_len; } - memcpy(&ieee->current_network, net, - sizeof(ieee->current_network)); + memcpy(&ieee->current_network, net, + sizeof(ieee->current_network)); if (!ssidbroad) { memcpy(ieee->current_network.ssid, tmp_ssid, tmp_ssid_len); @@ -2627,7 +2627,7 @@ static void rtllib_start_ibss_wq(void *data) /* the network definitively is not here.. create a new cell */ if (ieee->state == RTLLIB_NOLINK) { netdev_info(ieee->dev, "creating new IBSS cell\n"); - ieee->current_network.channel = ieee->IbssStartChnl; + ieee->current_network.channel = ieee->bss_start_channel; if (!ieee->wap_set) eth_random_addr(ieee->current_network.bssid); @@ -2719,7 +2719,7 @@ static void rtllib_start_bss(struct rtllib_device *ieee) unsigned long flags; if (IS_DOT11D_ENABLE(ieee) && !IS_COUNTRY_IE_VALID(ieee)) { - if (!ieee->bGlobalDomain) + if (!ieee->global_domain) return; } /* check if we have already found the net we @@ -2759,7 +2759,7 @@ void rtllib_disassociate(struct rtllib_device *ieee) if (ieee->data_hard_stop) ieee->data_hard_stop(ieee->dev); if (IS_DOT11D_ENABLE(ieee)) - Dot11d_Reset(ieee); + dot11d_reset(ieee); ieee->state = RTLLIB_NOLINK; ieee->is_set_key = false; ieee->wap_set = 0; @@ -2974,8 +2974,8 @@ void rtllib_softmac_init(struct rtllib_device *ieee) ieee->state = RTLLIB_NOLINK; for (i = 0; i < 5; i++) ieee->seq_ctrl[i] = 0; - ieee->pDot11dInfo = kzalloc(sizeof(struct rt_dot11d_info), GFP_ATOMIC); - if (!ieee->pDot11dInfo) + ieee->dot11d_info = kzalloc(sizeof(struct rt_dot11d_info), GFP_ATOMIC); + if (!ieee->dot11d_info) netdev_err(ieee->dev, "Can't alloc memory for DOT11D\n"); ieee->LinkDetectInfo.SlotIndex = 0; ieee->LinkDetectInfo.SlotNum = 2; @@ -3049,8 +3049,8 @@ void rtllib_softmac_init(struct rtllib_device *ieee) void rtllib_softmac_free(struct rtllib_device *ieee) { mutex_lock(&ieee->wx_mutex); - kfree(ieee->pDot11dInfo); - ieee->pDot11dInfo = NULL; + kfree(ieee->dot11d_info); + ieee->dot11d_info = NULL; del_timer_sync(&ieee->associate_timer); cancel_delayed_work_sync(&ieee->associate_retry_wq); diff --git a/drivers/staging/rtl8192e/rtllib_wx.c b/drivers/staging/rtl8192e/rtllib_wx.c index 74d4d2df3eb3..4f4904a300e0 100644 --- a/drivers/staging/rtl8192e/rtllib_wx.c +++ b/drivers/staging/rtl8192e/rtllib_wx.c @@ -541,8 +541,8 @@ int rtllib_wx_set_encode_ext(struct rtllib_device *ieee, if (idx < 1 || idx > NUM_WEP_KEYS) return -EINVAL; idx--; - } else{ - idx = ieee->crypt_info.tx_keyidx; + } else { + idx = ieee->crypt_info.tx_keyidx; } if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) { crypt = &ieee->crypt_info.crypt[idx]; diff --git a/drivers/staging/rtl8192u/Makefile b/drivers/staging/rtl8192u/Makefile index 3022728a364c..dcd51bf4aed3 100644 --- a/drivers/staging/rtl8192u/Makefile +++ b/drivers/staging/rtl8192u/Makefile @@ -7,7 +7,7 @@ ccflags-y += -O2 ccflags-y += -DCONFIG_FORCE_HARD_FLOAT=y ccflags-y += -DJACKSON_NEW_8187 -DJACKSON_NEW_RX ccflags-y += -DTHOMAS_BEACON -DTHOMAS_TASKLET -DTHOMAS_SKB -DTHOMAS_TURBO -ccflags-y += -Idrivers/staging/rtl8192u/ieee80211 +ccflags-y += -I $(srctree)/$(src)/ieee80211 r8192u_usb-y := r8192U_core.o r8180_93cx6.o r8192U_wx.o \ r8190_rtl8256.o r819xU_phy.o r819xU_firmware.o \ diff --git a/drivers/staging/rtl8192u/r8192U_core.c b/drivers/staging/rtl8192u/r8192U_core.c index 0ac0bbf7d923..f1eaab337dca 100644 --- a/drivers/staging/rtl8192u/r8192U_core.c +++ b/drivers/staging/rtl8192u/r8192U_core.c @@ -4957,20 +4957,18 @@ static void rtl8192_usb_disconnect(struct usb_interface *intf) struct net_device *dev = usb_get_intfdata(intf); struct r8192_priv *priv = ieee80211_priv(dev); - if (dev) { - unregister_netdev(dev); - - RT_TRACE(COMP_DOWN, - "=============>wlan driver to be removed\n"); - rtl8192_proc_remove_one(dev); - - rtl8192_down(dev); - kfree(priv->pFirmware); - priv->pFirmware = NULL; - rtl8192_usb_deleteendpoints(dev); - usleep_range(10000, 11000); - } + unregister_netdev(dev); + + RT_TRACE(COMP_DOWN, "=============>wlan driver to be removed\n"); + rtl8192_proc_remove_one(dev); + + rtl8192_down(dev); + kfree(priv->pFirmware); + priv->pFirmware = NULL; + rtl8192_usb_deleteendpoints(dev); + usleep_range(10000, 11000); free_ieee80211(dev); + RT_TRACE(COMP_DOWN, "wlan driver removed\n"); } diff --git a/drivers/staging/rtl8712/ieee80211.c b/drivers/staging/rtl8712/ieee80211.c index bb4f56a5fb01..2eae11dd6b42 100644 --- a/drivers/staging/rtl8712/ieee80211.c +++ b/drivers/staging/rtl8712/ieee80211.c @@ -408,7 +408,7 @@ int r8712_get_wps_ie(u8 *in_ie, uint in_len, u8 *wps_ie, uint *wps_ielen) match = true; break; } - cnt += in_ie[cnt + 1] + 2; /* goto next */ + cnt += in_ie[cnt + 1] + 2; /* goto next */ } return match; } diff --git a/drivers/staging/rtl8712/rtl8712_efuse.c b/drivers/staging/rtl8712/rtl8712_efuse.c index 8bc45ffd3029..39eb74374d0b 100644 --- a/drivers/staging/rtl8712/rtl8712_efuse.c +++ b/drivers/staging/rtl8712/rtl8712_efuse.c @@ -358,7 +358,7 @@ u8 r8712_efuse_pg_packet_write(struct _adapter *padapter, const u8 offset, u8 pg_header = 0; u16 efuse_addr = 0, curr_size = 0; u8 efuse_data, target_word_cnts = 0; - static int repeat_times; + int repeat_times; int sub_repeat; u8 bResult = true; diff --git a/drivers/staging/rtl8712/rtl8712_led.c b/drivers/staging/rtl8712/rtl8712_led.c index 5b1004b2df47..07fcf9b9b811 100644 --- a/drivers/staging/rtl8712/rtl8712_led.c +++ b/drivers/staging/rtl8712/rtl8712_led.c @@ -939,7 +939,7 @@ static void SwLedControlMode1(struct _adapter *padapter, } if (pLed->bLedLinkBlinkInProgress) { del_timer(&pLed->BlinkTimer); - pLed->bLedLinkBlinkInProgress = false; + pLed->bLedLinkBlinkInProgress = false; } if (pLed->bLedBlinkInProgress) { del_timer(&pLed->BlinkTimer); @@ -991,7 +991,7 @@ static void SwLedControlMode1(struct _adapter *padapter, } if (pLed->bLedLinkBlinkInProgress) { del_timer(&pLed->BlinkTimer); - pLed->bLedLinkBlinkInProgress = false; + pLed->bLedLinkBlinkInProgress = false; } if (pLed->bLedBlinkInProgress) { del_timer(&pLed->BlinkTimer); @@ -1018,7 +1018,7 @@ static void SwLedControlMode1(struct _adapter *padapter, } if (pLed->bLedLinkBlinkInProgress) { del_timer(&pLed->BlinkTimer); - pLed->bLedLinkBlinkInProgress = false; + pLed->bLedLinkBlinkInProgress = false; } if (pLed->bLedBlinkInProgress) { del_timer(&pLed->BlinkTimer); diff --git a/drivers/staging/rtl8712/rtl871x_mlme.c b/drivers/staging/rtl8712/rtl871x_mlme.c index 986a1d526918..3f17ef6f7e39 100644 --- a/drivers/staging/rtl8712/rtl871x_mlme.c +++ b/drivers/staging/rtl8712/rtl871x_mlme.c @@ -259,7 +259,7 @@ int r8712_is_same_ibss(struct _adapter *adapter, struct wlan_network *pnetwork) static int is_same_network(struct wlan_bssid_ex *src, struct wlan_bssid_ex *dst) { - u16 s_cap, d_cap; + u16 s_cap, d_cap; memcpy((u8 *)&s_cap, r8712_get_capability_from_ie(src->IEs), 2); memcpy((u8 *)&d_cap, r8712_get_capability_from_ie(dst->IEs), 2); diff --git a/drivers/staging/rtl8712/rtl871x_recv.c b/drivers/staging/rtl8712/rtl871x_recv.c index f10896df094b..28f736913292 100644 --- a/drivers/staging/rtl8712/rtl871x_recv.c +++ b/drivers/staging/rtl8712/rtl871x_recv.c @@ -54,7 +54,7 @@ sint _r8712_init_recv_priv(struct recv_priv *precvpriv, sint i; union recv_frame *precvframe; - memset((unsigned char *)precvpriv, 0, sizeof(struct recv_priv)); + memset((unsigned char *)precvpriv, 0, sizeof(struct recv_priv)); spin_lock_init(&precvpriv->lock); _init_queue(&precvpriv->free_recv_queue); _init_queue(&precvpriv->recv_pending_queue); @@ -325,7 +325,7 @@ static sint sta2sta_data_frame(struct _adapter *adapter, */ if (memcmp(pattrib->bssid, pattrib->src, ETH_ALEN)) return _FAIL; - sta_addr = pattrib->bssid; + sta_addr = pattrib->bssid; } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { if (bmcast) { /* For AP mode, if DA == MCAST, then BSSID should @@ -404,7 +404,7 @@ static sint ap2sta_data_frame(struct _adapter *adapter, if (bmcast) *psta = r8712_get_bcmc_stainfo(adapter); else - *psta = r8712_get_stainfo(pstapriv, pattrib->bssid); + *psta = r8712_get_stainfo(pstapriv, pattrib->bssid); if (*psta == NULL) return _FAIL; } else if (check_fwstate(pmlmepriv, WIFI_MP_STATE) && diff --git a/drivers/staging/rtl8712/rtl871x_sta_mgt.c b/drivers/staging/rtl8712/rtl871x_sta_mgt.c index 9648ee15b40e..7c30b9e68e70 100644 --- a/drivers/staging/rtl8712/rtl871x_sta_mgt.c +++ b/drivers/staging/rtl8712/rtl871x_sta_mgt.c @@ -25,7 +25,7 @@ static void _init_stainfo(struct sta_info *psta) { memset((u8 *)psta, 0, sizeof(struct sta_info)); - spin_lock_init(&psta->lock); + spin_lock_init(&psta->lock); INIT_LIST_HEAD(&psta->list); INIT_LIST_HEAD(&psta->hash_list); _r8712_init_sta_xmit_priv(&psta->sta_xmitpriv); diff --git a/drivers/staging/rtl8712/rtl871x_xmit.c b/drivers/staging/rtl8712/rtl871x_xmit.c index 5c7dc9c6f76b..7c8857409916 100644 --- a/drivers/staging/rtl8712/rtl871x_xmit.c +++ b/drivers/staging/rtl8712/rtl871x_xmit.c @@ -193,8 +193,8 @@ sint r8712_update_attrib(struct _adapter *padapter, _pkt *pkt, pattrib->ether_type = ntohs(etherhdr.h_proto); -{ - /*If driver xmit ARP packet, driver can set ps mode to initial + /* + * If driver xmit ARP packet, driver can set ps mode to initial * setting. It stands for getting DHCP or fix IP. */ if (pattrib->ether_type == 0x0806) { @@ -206,7 +206,7 @@ sint r8712_update_attrib(struct _adapter *padapter, _pkt *pkt, padapter->registrypriv.smart_ps); } } -} + memcpy(pattrib->dst, ðerhdr.h_dest, ETH_ALEN); memcpy(pattrib->src, ðerhdr.h_source, ETH_ALEN); pattrib->pctrl = 0; @@ -949,7 +949,7 @@ static void alloc_hwxmits(struct _adapter *padapter) pxmitpriv->vo_txqueue.head = 0; hwxmits[1] .phwtxqueue = &pxmitpriv->vo_txqueue; hwxmits[1] .sta_queue = &pxmitpriv->vo_pending; - pxmitpriv->vi_txqueue.head = 0; + pxmitpriv->vi_txqueue.head = 0; hwxmits[2] .phwtxqueue = &pxmitpriv->vi_txqueue; hwxmits[2] .sta_queue = &pxmitpriv->vi_pending; pxmitpriv->bk_txqueue.head = 0; diff --git a/drivers/staging/rtl8712/usb_intf.c b/drivers/staging/rtl8712/usb_intf.c index 92d75d7c51ae..005010de9997 100644 --- a/drivers/staging/rtl8712/usb_intf.c +++ b/drivers/staging/rtl8712/usb_intf.c @@ -196,10 +196,6 @@ static int r871x_suspend(struct usb_interface *pusb_intf, pm_message_t state) struct _adapter *padapter = netdev_priv(pnetdev); netdev_info(pnetdev, "Suspending...\n"); - if (!pnetdev || !netif_running(pnetdev)) { - netdev_info(pnetdev, "Unable to suspend\n"); - return 0; - } padapter->bSuspended = true; rtl871x_intf_stop(padapter); if (pnetdev->netdev_ops->ndo_stop) @@ -221,10 +217,6 @@ static int r871x_resume(struct usb_interface *pusb_intf) struct _adapter *padapter = netdev_priv(pnetdev); netdev_info(pnetdev, "Resuming...\n"); - if (!pnetdev || !netif_running(pnetdev)) { - netdev_info(pnetdev, "Unable to resume\n"); - return 0; - } netif_device_attach(pnetdev); if (pnetdev->netdev_ops->ndo_open) pnetdev->netdev_ops->ndo_open(pnetdev); @@ -232,13 +224,6 @@ static int r871x_resume(struct usb_interface *pusb_intf) rtl871x_intf_resume(padapter); return 0; } - -static int r871x_reset_resume(struct usb_interface *pusb_intf) -{ - /* dummy routine */ - return 0; -} - #endif static struct drv_priv drvpriv = { @@ -249,7 +234,6 @@ static struct drv_priv drvpriv = { #ifdef CONFIG_PM .r871xu_drv.suspend = r871x_suspend, .r871xu_drv.resume = r871x_resume, - .r871xu_drv.reset_resume = r871x_reset_resume, #endif }; diff --git a/drivers/staging/rtl8723bs/core/rtw_cmd.c b/drivers/staging/rtl8723bs/core/rtw_cmd.c index ea2c187e56bd..91520ca3bbad 100644 --- a/drivers/staging/rtl8723bs/core/rtw_cmd.c +++ b/drivers/staging/rtl8723bs/core/rtw_cmd.c @@ -835,14 +835,6 @@ u8 rtw_joinbss_cmd(struct adapter *padapter, struct wlan_network *pnetwork) } psecnetwork = (struct wlan_bssid_ex *)&psecuritypriv->sec_bss; - if (psecnetwork == NULL) { - kfree(pcmd); - res = _FAIL; - - RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("rtw_joinbss_cmd :psecnetwork == NULL!!!\n")); - - goto exit; - } memset(psecnetwork, 0, t_len); diff --git a/drivers/staging/rtl8723bs/core/rtw_xmit.c b/drivers/staging/rtl8723bs/core/rtw_xmit.c index 625e67f39889..094d61bcb469 100644 --- a/drivers/staging/rtl8723bs/core/rtw_xmit.c +++ b/drivers/staging/rtl8723bs/core/rtw_xmit.c @@ -2389,7 +2389,7 @@ sint xmitframe_enqueue_for_sleeping_sta(struct adapter *padapter, struct xmit_fr if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == false) { DBG_COUNTER(padapter->tx_logs.core_tx_ap_enqueue_warn_fwstate); - return ret; + return ret; } /* if (pattrib->psta) diff --git a/drivers/staging/rtl8723bs/include/drv_types.h b/drivers/staging/rtl8723bs/include/drv_types.h index 062fda9962be..bafb2c30e7fb 100644 --- a/drivers/staging/rtl8723bs/include/drv_types.h +++ b/drivers/staging/rtl8723bs/include/drv_types.h @@ -65,7 +65,6 @@ enum _NIC_VERSION { #include <rtw_event.h> #include <rtw_mlme_ext.h> #include <rtw_ap.h> -#include <rtw_efuse.h> #include <rtw_version.h> #include <rtw_odm.h> diff --git a/drivers/staging/rtl8723bs/os_dep/osdep_service.c b/drivers/staging/rtl8723bs/os_dep/osdep_service.c index e14d7cc411c9..73b87da15eb2 100644 --- a/drivers/staging/rtl8723bs/os_dep/osdep_service.c +++ b/drivers/staging/rtl8723bs/os_dep/osdep_service.c @@ -137,7 +137,7 @@ static int isFileReadable(char *path) ret = PTR_ERR(fp); } else { - oldfs = get_fs(); set_fs(get_ds()); + oldfs = get_fs(); set_fs(KERNEL_DS); if (1!=readFile(fp, &buf, 1)) ret = -EINVAL; @@ -165,7 +165,7 @@ static int retriveFromFile(char *path, u8 *buf, u32 sz) if (0 == (ret =openFile(&fp, path, O_RDONLY, 0))) { DBG_871X("%s openFile path:%s fp =%p\n", __func__, path , fp); - oldfs = get_fs(); set_fs(get_ds()); + oldfs = get_fs(); set_fs(KERNEL_DS); ret =readFile(fp, buf, sz); set_fs(oldfs); closeFile(fp); diff --git a/drivers/staging/rtlwifi/Kconfig b/drivers/staging/rtlwifi/Kconfig index 7b4276f5c41f..28286a87a601 100644 --- a/drivers/staging/rtlwifi/Kconfig +++ b/drivers/staging/rtlwifi/Kconfig @@ -2,7 +2,7 @@ config R8822BE tristate "Realtek RTL8822BE Wireless Network Adapter" depends on PCI && MAC80211 && m select FW_LOADER - ---help--- + help This is the staging driver for Realtek RTL8822BE 802.11ac PCIe wireless network adapters. diff --git a/drivers/staging/rtlwifi/efuse.c b/drivers/staging/rtlwifi/efuse.c index abb0f720cf21..a7c9e186f2b2 100644 --- a/drivers/staging/rtlwifi/efuse.c +++ b/drivers/staging/rtlwifi/efuse.c @@ -919,7 +919,7 @@ static int efuse_pg_packet_write(struct ieee80211_hw *hw, struct rtl_priv *rtlpriv = rtl_priv(hw); struct pgpkt_struct target_pkt; u8 write_state = PG_STATE_HEADER; - int continual = true, dataempty = true, result = true; + int continual = true, result = true; u16 efuse_addr = 0; u8 efuse_data; u8 target_word_cnts = 0; @@ -946,7 +946,6 @@ static int efuse_pg_packet_write(struct ieee80211_hw *hw, while (continual && (efuse_addr < (EFUSE_MAX_SIZE - rtlpriv->cfg->maps[EFUSE_OOB_PROTECT_BYTES_LEN]))) { if (write_state == PG_STATE_HEADER) { - dataempty = true; badworden = 0x0F; RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, "efuse PG_STATE_HEADER\n"); @@ -1182,13 +1181,12 @@ static u16 efuse_get_current_size(struct ieee80211_hw *hw) { int continual = true; u16 efuse_addr = 0; - u8 hoffset, hworden; + u8 hworden; u8 efuse_data, word_cnts; while (continual && efuse_one_byte_read(hw, efuse_addr, &efuse_data) && (efuse_addr < EFUSE_MAX_SIZE)) { if (efuse_data != 0xFF) { - hoffset = (efuse_data >> 4) & 0x0F; hworden = efuse_data & 0x0F; word_cnts = efuse_calculate_word_cnts(hworden); efuse_addr = efuse_addr + (word_cnts * 2) + 1; diff --git a/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_func_88xx.c b/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_func_88xx.c index 53f55f129a76..ddbeff8224ab 100644 --- a/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_func_88xx.c +++ b/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_func_88xx.c @@ -2466,8 +2466,11 @@ halmac_parse_psd_data_88xx(struct halmac_adapter *halmac_adapter, u8 *c2h_buf, segment_size = (u8)PSD_DATA_GET_SEGMENT_SIZE(c2h_buf); psd_set->data_size = total_size; - if (!psd_set->data) + if (!psd_set->data) { psd_set->data = kzalloc(psd_set->data_size, GFP_KERNEL); + if (!psd_set->data) + return HALMAC_RET_MALLOC_FAIL; + } if (segment_id == 0) psd_set->segment_size = segment_size; diff --git a/drivers/staging/rtlwifi/pci.h b/drivers/staging/rtlwifi/pci.h index 7535ac24bfbb..0e55baec95a8 100644 --- a/drivers/staging/rtlwifi/pci.h +++ b/drivers/staging/rtlwifi/pci.h @@ -205,7 +205,8 @@ struct rtl_pci { /*Bcn control register setting */ u32 reg_bcn_ctrl_val; - /*ASPM*/ u8 const_pci_aspm; + /*ASPM*/ + u8 const_pci_aspm; u8 const_amdpci_aspm; u8 const_hwsw_rfoff_d3; u8 const_support_pciaspm; diff --git a/drivers/staging/rtlwifi/phydm/phydm_rainfo.c b/drivers/staging/rtlwifi/phydm/phydm_rainfo.c index b46791a727c7..ed740a93c8b6 100644 --- a/drivers/staging/rtlwifi/phydm/phydm_rainfo.c +++ b/drivers/staging/rtlwifi/phydm/phydm_rainfo.c @@ -124,7 +124,7 @@ void odm_c2h_ra_para_report_handler(void *dm_void, u8 *cmd_buf, u8 cmd_len) ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s %d\n", "VHT_EN =", cmd_buf[4]); ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s %d\n", - "Hightest rate =", cmd_buf[5]); + "Highest rate =", cmd_buf[5]); ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s 0x%x\n", "Lowest rate =", cmd_buf[6]); ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s 0x%x\n", diff --git a/drivers/staging/rtlwifi/rtl8822be/fw.c b/drivers/staging/rtlwifi/rtl8822be/fw.c index a40396614814..f061dd1382aa 100644 --- a/drivers/staging/rtlwifi/rtl8822be/fw.c +++ b/drivers/staging/rtlwifi/rtl8822be/fw.c @@ -486,6 +486,8 @@ bool rtl8822b_halmac_cb_write_data_h2c(struct rtl_priv *rtlpriv, u8 *buf, /* without GFP_DMA, pci_map_single() may not work */ skb = __netdev_alloc_skb(NULL, size, GFP_ATOMIC | GFP_DMA); + if (!skb) + return false; memcpy((u8 *)skb_put(skb, size), buf, size); return _rtl8822be_send_bcn_or_cmd_packet(rtlpriv->hw, skb, H2C_QUEUE); diff --git a/drivers/staging/rts5208/ms.c b/drivers/staging/rts5208/ms.c index e43f92080c20..1128eec3bd08 100644 --- a/drivers/staging/rts5208/ms.c +++ b/drivers/staging/rts5208/ms.c @@ -1665,7 +1665,10 @@ static int ms_copy_page(struct rtsx_chip *chip, u16 old_blk, u16 new_blk, return STATUS_FAIL; } - ms_read_extra_data(chip, old_blk, i, extra, MS_EXTRA_SIZE); + retval = ms_read_extra_data(chip, old_blk, i, extra, + MS_EXTRA_SIZE); + if (retval != STATUS_SUCCESS) + return STATUS_FAIL; retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, 6); diff --git a/drivers/staging/rts5208/sd.c b/drivers/staging/rts5208/sd.c index 2c47ae613ea1..c256a2398651 100644 --- a/drivers/staging/rts5208/sd.c +++ b/drivers/staging/rts5208/sd.c @@ -4437,7 +4437,12 @@ int sd_execute_write_data(struct scsi_cmnd *srb, struct rtsx_chip *chip) rtsx_init_cmd(chip); rtsx_add_cmd(chip, CHECK_REG_CMD, 0xFD30, 0x02, 0x02); - rtsx_send_cmd(chip, SD_CARD, 250); + retval = rtsx_send_cmd(chip, SD_CARD, 250); + if (retval < 0) { + write_err = true; + rtsx_clear_sd_error(chip); + goto sd_execute_write_cmd_failed; + } retval = sd_update_lock_status(chip); if (retval != STATUS_SUCCESS) { diff --git a/drivers/staging/sm750fb/ddk750_display.c b/drivers/staging/sm750fb/ddk750_display.c index 1273e7d18925..f38051eedb6c 100644 --- a/drivers/staging/sm750fb/ddk750_display.c +++ b/drivers/staging/sm750fb/ddk750_display.c @@ -5,7 +5,7 @@ #include "ddk750_power.h" #include "ddk750_dvi.h" -static void setDisplayControl(int ctrl, int disp_state) +static void set_display_control(int ctrl, int disp_state) { /* state != 0 means turn on both timing & plane en_bit */ unsigned long reg, val, reserved; @@ -137,12 +137,12 @@ void ddk750_setLogicalDispOut(enum disp_output output) if (output & PRI_TP_USAGE) { /* set primary timing and plane en_bit */ - setDisplayControl(0, (output & PRI_TP_MASK) >> PRI_TP_OFFSET); + set_display_control(0, (output & PRI_TP_MASK) >> PRI_TP_OFFSET); } if (output & SEC_TP_USAGE) { /* set secondary timing and plane en_bit*/ - setDisplayControl(1, (output & SEC_TP_MASK) >> SEC_TP_OFFSET); + set_display_control(1, (output & SEC_TP_MASK) >> SEC_TP_OFFSET); } if (output & PNL_SEQ_USAGE) { diff --git a/drivers/staging/speakup/Kconfig b/drivers/staging/speakup/Kconfig index efd6f4560d3e..d8ec780f7741 100644 --- a/drivers/staging/speakup/Kconfig +++ b/drivers/staging/speakup/Kconfig @@ -3,7 +3,7 @@ menu "Speakup console speech" config SPEAKUP depends on VT tristate "Speakup core" - ---help--- + help This is the Speakup screen reader. Think of it as a video console for blind people. If built in to the kernel, it can speak everything on the text console from @@ -43,7 +43,7 @@ config SPEAKUP if SPEAKUP config SPEAKUP_SYNTH_ACNTSA tristate "Accent SA synthesizer support" - ---help--- + help This is the Speakup driver for the Accent SA synthesizer. You can say y to build it into the kernel, or m to build it as a module. See the configuration @@ -52,7 +52,7 @@ config SPEAKUP_SYNTH_ACNTSA config SPEAKUP_SYNTH_ACNTPC tristate "Accent PC synthesizer support" depends on ISA || COMPILE_TEST - ---help--- + help This is the Speakup driver for the accent pc synthesizer. You can say y to build it into the kernel, or m to build it as a module. See the configuration @@ -60,7 +60,7 @@ config SPEAKUP_SYNTH_ACNTPC config SPEAKUP_SYNTH_APOLLO tristate "Apollo II synthesizer support" - ---help--- + help This is the Speakup driver for the Apollo II synthesizer. You can say y to build it into the kernel, or m to build it as a module. See the configuration @@ -68,7 +68,7 @@ config SPEAKUP_SYNTH_APOLLO config SPEAKUP_SYNTH_AUDPTR tristate "Audapter synthesizer support" - ---help--- + help This is the Speakup driver for the Audapter synthesizer. You can say y to build it into the kernel, or m to build it as a module. See the configuration help on the @@ -76,7 +76,7 @@ config SPEAKUP_SYNTH_AUDPTR config SPEAKUP_SYNTH_BNS tristate "Braille 'n' Speak synthesizer support" - ---help--- + help This is the Speakup driver for the Braille 'n' Speak synthesizer. You can say y to build it into the kernel, or m to build it as a module. See the configuration @@ -84,7 +84,7 @@ config SPEAKUP_SYNTH_BNS config SPEAKUP_SYNTH_DECTLK tristate "DECtalk Express synthesizer support" - ---help--- + help This is the Speakup driver for the DecTalk Express synthesizer. You can say y to build it into the kernel, @@ -93,7 +93,7 @@ config SPEAKUP_SYNTH_DECTLK config SPEAKUP_SYNTH_DECEXT tristate "DECtalk External (old) synthesizer support" - ---help--- + help This is the Speakup driver for the DecTalk External (old) synthesizer. You can say y to build it into the @@ -105,7 +105,7 @@ config SPEAKUP_SYNTH_DECPC depends on m depends on ISA || COMPILE_TEST tristate "DECtalk PC (big ISA card) synthesizer support" - ---help--- + help This is the Speakup driver for the DecTalk PC (full length ISA) synthesizer. You can say m to build it as @@ -127,7 +127,7 @@ config SPEAKUP_SYNTH_DECPC config SPEAKUP_SYNTH_DTLK tristate "DoubleTalk PC synthesizer support" depends on ISA || COMPILE_TEST - ---help--- + help This is the Speakup driver for the internal DoubleTalk PC synthesizer. You can say y to build it into the @@ -138,7 +138,7 @@ config SPEAKUP_SYNTH_DTLK config SPEAKUP_SYNTH_KEYPC tristate "Keynote Gold PC synthesizer support" depends on ISA || COMPILE_TEST - ---help--- + help This is the Speakup driver for the Keynote Gold PC synthesizer. You can say y to build it into the @@ -148,7 +148,7 @@ config SPEAKUP_SYNTH_KEYPC config SPEAKUP_SYNTH_LTLK tristate "DoubleTalk LT/LiteTalk synthesizer support" ----help--- +help This is the Speakup driver for the LiteTalk/DoubleTalk LT synthesizer. You can say y to build it into the @@ -158,7 +158,7 @@ config SPEAKUP_SYNTH_LTLK config SPEAKUP_SYNTH_SOFT tristate "Userspace software synthesizer support" - ---help--- + help This is the software synthesizer device node. It will register a device /dev/softsynth which midware programs @@ -169,7 +169,7 @@ config SPEAKUP_SYNTH_SOFT config SPEAKUP_SYNTH_SPKOUT tristate "Speak Out synthesizer support" - ---help--- + help This is the Speakup driver for the Speakout synthesizer. You can say y to build it into the kernel, or m to @@ -178,7 +178,7 @@ config SPEAKUP_SYNTH_SPKOUT config SPEAKUP_SYNTH_TXPRT tristate "Transport synthesizer support" - ---help--- + help This is the Speakup driver for the Transport synthesizer. You can say y to build it into the kernel, @@ -187,7 +187,7 @@ config SPEAKUP_SYNTH_TXPRT config SPEAKUP_SYNTH_DUMMY tristate "Dummy synthesizer driver (for testing)" - ---help--- + help This is a dummy Speakup driver for plugging a mere serial terminal. This is handy if you want to test speakup but diff --git a/drivers/staging/speakup/kobjects.c b/drivers/staging/speakup/kobjects.c index 2e36d872662c..11c704b27c3c 100644 --- a/drivers/staging/speakup/kobjects.c +++ b/drivers/staging/speakup/kobjects.c @@ -154,6 +154,7 @@ static ssize_t chars_chartab_store(struct kobject *kobj, continue; } + /* Do not replace with kstrtoul: here we need temp to be updated */ index = simple_strtoul(cp, &temp, 10); if (index > 255) { rejected++; @@ -787,6 +788,7 @@ static ssize_t message_store_helper(const char *buf, size_t count, continue; } + /* Do not replace with kstrtoul: here we need temp to be updated */ index = simple_strtoul(cp, &temp, 10); while ((temp < linefeed) && (*temp == ' ' || *temp == '\t')) diff --git a/drivers/staging/speakup/main.c b/drivers/staging/speakup/main.c index 869f40ebf1a7..b6a65b0c1896 100644 --- a/drivers/staging/speakup/main.c +++ b/drivers/staging/speakup/main.c @@ -901,7 +901,8 @@ static int get_sentence_buf(struct vc_data *vc, int read_punc) while (start < end) { sentbuf[bn][i] = get_char(vc, (u_short *)start, &tmp); if (i > 0) { - if (sentbuf[bn][i] == SPACE && sentbuf[bn][i - 1] == '.' && + if (sentbuf[bn][i] == SPACE && + sentbuf[bn][i - 1] == '.' && numsentences[bn] < 9) { /* Sentence Marker */ numsentences[bn]++; @@ -1235,7 +1236,8 @@ int spk_set_key_info(const u_char *key_info, u_char *k_buffer) key_data_len = (states + 1) * (num_keys + 1); if (key_data_len + SHIFT_TBL_SIZE + 4 >= sizeof(spk_key_buf)) { pr_debug("too many key_infos (%d over %u)\n", - key_data_len + SHIFT_TBL_SIZE + 4, (unsigned int)(sizeof(spk_key_buf))); + key_data_len + SHIFT_TBL_SIZE + 4, + (unsigned int)(sizeof(spk_key_buf))); return -EINVAL; } memset(k_buffer, 0, SHIFT_TBL_SIZE); @@ -1249,8 +1251,8 @@ int spk_set_key_info(const u_char *key_info, u_char *k_buffer) for (i = 1; i <= states; i++) { ch = *cp1++; if (ch >= SHIFT_TBL_SIZE) { - pr_debug("(%d) not valid shift state (max_allowed = %d)\n", ch, - SHIFT_TBL_SIZE); + pr_debug("(%d) not valid shift state (max_allowed = %d)\n", + ch, SHIFT_TBL_SIZE); return -EINVAL; } spk_shift_table[ch] = i; @@ -1258,7 +1260,8 @@ int spk_set_key_info(const u_char *key_info, u_char *k_buffer) keymap_flags = *cp1++; while ((ch = *cp1)) { if (ch >= MAX_KEY) { - pr_debug("(%d), not valid key, (max_allowed = %d)\n", ch, MAX_KEY); + pr_debug("(%d), not valid key, (max_allowed = %d)\n", + ch, MAX_KEY); return -EINVAL; } spk_our_keys[ch] = cp1; @@ -1979,6 +1982,7 @@ oops: return 1; } + /* Do not replace with kstrtoul: here we need cp to be updated */ goto_pos = simple_strtoul(goto_buf, &cp, 10); if (*cp == 'x') { diff --git a/drivers/staging/speakup/speakup_decext.c b/drivers/staging/speakup/speakup_decext.c index 3741c0fcf5bb..ddbb7e97d118 100644 --- a/drivers/staging/speakup/speakup_decext.c +++ b/drivers/staging/speakup/speakup_decext.c @@ -192,7 +192,8 @@ static void do_catch_up(struct spk_synth *synth) synth->io_ops->synth_out(synth, PROCSPEECH); if (time_after_eq(jiffies, jiff_max)) { if (!in_escape) - synth->io_ops->synth_out(synth, PROCSPEECH); + synth->io_ops->synth_out(synth, + PROCSPEECH); spin_lock_irqsave(&speakup_info.spinlock, flags); jiffy_delta_val = jiffy_delta->u.n.value; diff --git a/drivers/staging/speakup/speakup_dectlk.c b/drivers/staging/speakup/speakup_dectlk.c index a144f28ee1a8..dccb4ea29d37 100644 --- a/drivers/staging/speakup/speakup_dectlk.c +++ b/drivers/staging/speakup/speakup_dectlk.c @@ -260,7 +260,8 @@ static void do_catch_up(struct spk_synth *synth) synth->io_ops->synth_out(synth, PROCSPEECH); if (time_after_eq(jiffies, jiff_max)) { if (!in_escape) - synth->io_ops->synth_out(synth, PROCSPEECH); + synth->io_ops->synth_out(synth, + PROCSPEECH); spin_lock_irqsave(&speakup_info.spinlock, flags); jiffy_delta_val = jiffy_delta->u.n.value; diff --git a/drivers/staging/speakup/speakup_soft.c b/drivers/staging/speakup/speakup_soft.c index 947c79532e10..edff6ce85655 100644 --- a/drivers/staging/speakup/speakup_soft.c +++ b/drivers/staging/speakup/speakup_soft.c @@ -12,7 +12,9 @@ #include <linux/unistd.h> #include <linux/miscdevice.h> /* for misc_register, and SYNTH_MINOR */ #include <linux/poll.h> /* for poll_wait() */ -#include <linux/sched/signal.h> /* schedule(), signal_pending(), TASK_INTERRUPTIBLE */ + +/* schedule(), signal_pending(), TASK_INTERRUPTIBLE */ +#include <linux/sched/signal.h> #include "spk_priv.h" #include "speakup.h" diff --git a/drivers/staging/speakup/spk_priv_keyinfo.h b/drivers/staging/speakup/spk_priv_keyinfo.h index cc99fcd1bc6e..1f789bd1c678 100644 --- a/drivers/staging/speakup/spk_priv_keyinfo.h +++ b/drivers/staging/speakup/spk_priv_keyinfo.h @@ -61,11 +61,16 @@ #define SPEAKUP_HELP 0x2d #define TOGGLE_CURSORING 0x2e #define READ_ALL_DOC 0x2f -#define SPKUP_MAX_FUNC 0x30 /* one greater than the last func handler */ + +/* one greater than the last func handler */ +#define SPKUP_MAX_FUNC 0x30 + #define SPK_KEY 0x80 #define FIRST_EDIT_BITS 0x22 #define FIRST_SET_VAR SPELL_DELAY -#define VAR_START 0x40 /* increase if adding more than 0x3f functions */ + +/* increase if adding more than 0x3f functions */ +#define VAR_START 0x40 /* keys for setting variables, must be ordered same as the enum for var_ids */ /* with dec being even and inc being 1 greater */ diff --git a/drivers/staging/speakup/spk_ttyio.c b/drivers/staging/speakup/spk_ttyio.c index 005de0024dd4..0057eb980bec 100644 --- a/drivers/staging/speakup/spk_ttyio.c +++ b/drivers/staging/speakup/spk_ttyio.c @@ -128,7 +128,8 @@ struct spk_io_ops spk_ttyio_ops = { }; EXPORT_SYMBOL_GPL(spk_ttyio_ops); -static inline void get_termios(struct tty_struct *tty, struct ktermios *out_termios) +static inline void get_termios(struct tty_struct *tty, + struct ktermios *out_termios) { down_read(&tty->termios_rwsem); *out_termios = tty->termios; @@ -167,8 +168,9 @@ static int spk_ttyio_initialise_ldisc(struct spk_synth *synth) tmp_termios.c_cflag |= CRTSCTS; tty_set_termios(tty, &tmp_termios); /* - * check c_cflag to see if it's updated as tty_set_termios may not return - * error even when no tty bits are changed by the request. + * check c_cflag to see if it's updated as tty_set_termios + * may not return error even when no tty bits are + * changed by the request. */ get_termios(tty, &tmp_termios); if (!(tmp_termios.c_cflag & CRTSCTS)) @@ -207,10 +209,11 @@ static int spk_ttyio_out(struct spk_synth *in_synth, const char ch) /* No room */ return 0; if (ret < 0) { - pr_warn("%s: I/O error, deactivating speakup\n", in_synth->long_name); - /* No synth any more, so nobody will restart TTYs, and we thus - * need to do it ourselves. Now that there is no synth we can - * let application flood anyway + pr_warn("%s: I/O error, deactivating speakup\n", + in_synth->long_name); + /* No synth any more, so nobody will restart TTYs, + * and we thus need to do it ourselves. Now that there + * is no synth we can let application flood anyway */ in_synth->alive = 0; speakup_start_ttys(); @@ -371,7 +374,8 @@ const char *spk_ttyio_synth_immediate(struct spk_synth *synth, const char *buff) while ((ch = *buff)) { if (ch == '\n') ch = synth->procspeech; - if (tty_write_room(speakup_tty) < 1 || !synth->io_ops->synth_out(synth, ch)) + if (tty_write_room(speakup_tty) < 1 || + !synth->io_ops->synth_out(synth, ch)) return buff; buff++; } diff --git a/drivers/staging/speakup/varhandlers.c b/drivers/staging/speakup/varhandlers.c index 1b545152cc49..5741d1cb6227 100644 --- a/drivers/staging/speakup/varhandlers.c +++ b/drivers/staging/speakup/varhandlers.c @@ -238,7 +238,8 @@ int spk_set_num_var(int input, struct st_var_header *var, int how) if (!var_data->u.n.out_str) sprintf(cp, var_data->u.n.synth_fmt, (int)val); else - sprintf(cp, var_data->u.n.synth_fmt, var_data->u.n.out_str[val]); + sprintf(cp, var_data->u.n.synth_fmt, + var_data->u.n.out_str[val]); synth_printf("%s", cp); return 0; } @@ -328,6 +329,7 @@ char *spk_s2uchar(char *start, char *dest) { int val; + /* Do not replace with kstrtoul: here we need start to be updated */ val = simple_strtoul(skip_spaces(start), &start, 10); if (*start == ',') start++; diff --git a/drivers/staging/unisys/visorhba/Makefile b/drivers/staging/unisys/visorhba/Makefile index a8a8e0e0fb09..97e48757944a 100644 --- a/drivers/staging/unisys/visorhba/Makefile +++ b/drivers/staging/unisys/visorhba/Makefile @@ -6,5 +6,4 @@ obj-$(CONFIG_UNISYS_VISORHBA) += visorhba.o visorhba-y := visorhba_main.o -ccflags-y += -Idrivers/staging/unisys/include - +ccflags-y += -I $(srctree)/$(src)/../include diff --git a/drivers/staging/unisys/visornic/Makefile b/drivers/staging/unisys/visornic/Makefile index 439e95e03300..336a746f793b 100644 --- a/drivers/staging/unisys/visornic/Makefile +++ b/drivers/staging/unisys/visornic/Makefile @@ -6,5 +6,4 @@ obj-$(CONFIG_UNISYS_VISORNIC) += visornic.o visornic-y := visornic_main.o -ccflags-y += -Idrivers/staging/unisys/include - +ccflags-y += -I $(srctree)/$(src)/../include diff --git a/drivers/staging/unisys/visornic/visornic_main.c b/drivers/staging/unisys/visornic/visornic_main.c index 5eeb4b93b45b..1c1a470d2e50 100644 --- a/drivers/staging/unisys/visornic/visornic_main.c +++ b/drivers/staging/unisys/visornic/visornic_main.c @@ -896,9 +896,7 @@ static netdev_tx_t visornic_xmit(struct sk_buff *skb, struct net_device *netdev) ((skb_end_pointer(skb) - skb->data) >= ETH_MIN_PACKET_SIZE)) { /* pad the packet out to minimum size */ padlen = ETH_MIN_PACKET_SIZE - len; - memset(&skb->data[len], 0, padlen); - skb->tail += padlen; - skb->len += padlen; + skb_put_zero(skb, padlen); len += padlen; firstfraglen += padlen; } diff --git a/drivers/staging/vboxvideo/TODO b/drivers/staging/vboxvideo/TODO index 2e0f99c3f10c..7f97c47a4042 100644 --- a/drivers/staging/vboxvideo/TODO +++ b/drivers/staging/vboxvideo/TODO @@ -1,5 +1,8 @@ TODO: -Get a full review from the drm-maintainers on dri-devel done on this driver +-Drop all the logic around initial_mode_queried, the master_set and + master_drop callbacks and everything related to this. kms clients can handle + hotplugs. -Extend this TODO with the results of that review Please send any patches to Greg Kroah-Hartman <gregkh@linuxfoundation.org>, diff --git a/drivers/staging/vboxvideo/vbox_drv.c b/drivers/staging/vboxvideo/vbox_drv.c index cc6532d8c2fa..e7755a179850 100644 --- a/drivers/staging/vboxvideo/vbox_drv.c +++ b/drivers/staging/vboxvideo/vbox_drv.c @@ -7,11 +7,15 @@ * Michael Thayer <michael.thayer@oracle.com, * Hans de Goede <hdegoede@redhat.com> */ -#include <linux/module.h> #include <linux/console.h> +#include <linux/module.h> +#include <linux/pci.h> #include <linux/vt_kern.h> #include <drm/drm_crtc_helper.h> +#include <drm/drm_drv.h> +#include <drm/drm_file.h> +#include <drm/drm_ioctl.h> #include "vbox_drv.h" @@ -221,9 +225,7 @@ static void vbox_master_drop(struct drm_device *dev, struct drm_file *file_priv) static struct drm_driver driver = { .driver_features = - DRIVER_MODESET | DRIVER_GEM | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | - DRIVER_PRIME | DRIVER_ATOMIC, - .dev_priv_size = 0, + DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME | DRIVER_ATOMIC, .lastclose = drm_fb_helper_lastclose, .master_set = vbox_master_set, diff --git a/drivers/staging/vboxvideo/vbox_fb.c b/drivers/staging/vboxvideo/vbox_fb.c index 6b7aa23dfc0a..83a04afd1766 100644 --- a/drivers/staging/vboxvideo/vbox_fb.c +++ b/drivers/staging/vboxvideo/vbox_fb.c @@ -6,20 +6,22 @@ * Authors: Dave Airlie <airlied@redhat.com> * Michael Thayer <michael.thayer@oracle.com, */ -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/string.h> -#include <linux/mm.h> -#include <linux/tty.h> -#include <linux/sysrq.h> #include <linux/delay.h> +#include <linux/errno.h> #include <linux/fb.h> #include <linux/init.h> +#include <linux/kernel.h> +#include <linux/mm.h> +#include <linux/module.h> +#include <linux/pci.h> +#include <linux/string.h> +#include <linux/sysrq.h> +#include <linux/tty.h> #include <drm/drm_crtc.h> -#include <drm/drm_fb_helper.h> #include <drm/drm_crtc_helper.h> +#include <drm/drm_fb_helper.h> +#include <drm/drm_fourcc.h> #include "vbox_drv.h" #include "vboxvideo.h" @@ -95,11 +97,6 @@ int vboxfb_create(struct drm_fb_helper *helper, strcpy(info->fix.id, "vboxdrmfb"); - /* - * The last flag forces a mode set on VT switches even if the kernel - * does not think it is needed. - */ - info->flags = FBINFO_DEFAULT | FBINFO_MISC_ALWAYS_SETPAR; info->fbops = &vboxfb_ops; /* diff --git a/drivers/staging/vboxvideo/vbox_irq.c b/drivers/staging/vboxvideo/vbox_irq.c index f3d9895c79d8..195484713365 100644 --- a/drivers/staging/vboxvideo/vbox_irq.c +++ b/drivers/staging/vboxvideo/vbox_irq.c @@ -9,7 +9,9 @@ * Hans de Goede <hdegoede@redhat.com> */ -#include <drm/drm_crtc_helper.h> +#include <linux/pci.h> +#include <drm/drm_irq.h> +#include <drm/drm_probe_helper.h> #include "vbox_drv.h" #include "vboxvideo.h" diff --git a/drivers/staging/vboxvideo/vbox_mode.c b/drivers/staging/vboxvideo/vbox_mode.c index c43bec4628ae..213551394495 100644 --- a/drivers/staging/vboxvideo/vbox_mode.c +++ b/drivers/staging/vboxvideo/vbox_mode.c @@ -10,14 +10,17 @@ * Hans de Goede <hdegoede@redhat.com> */ #include <linux/export.h> + #include <drm/drm_atomic.h> -#include <drm/drm_crtc_helper.h> -#include <drm/drm_plane_helper.h> #include <drm/drm_atomic_helper.h> +#include <drm/drm_fourcc.h> +#include <drm/drm_plane_helper.h> +#include <drm/drm_probe_helper.h> +#include <drm/drm_vblank.h> +#include "hgsmi_channels.h" #include "vbox_drv.h" #include "vboxvideo.h" -#include "hgsmi_channels.h" /* * Set a graphics mode. Poke any required values into registers, do an HGSMI diff --git a/drivers/staging/vc04_services/bcm2835-audio/Makefile b/drivers/staging/vc04_services/bcm2835-audio/Makefile index d7b88d164d15..536bd0c11ddb 100644 --- a/drivers/staging/vc04_services/bcm2835-audio/Makefile +++ b/drivers/staging/vc04_services/bcm2835-audio/Makefile @@ -1,5 +1,4 @@ obj-$(CONFIG_SND_BCM2835) += snd-bcm2835.o snd-bcm2835-objs := bcm2835.o bcm2835-ctl.o bcm2835-pcm.o bcm2835-vchiq.o -ccflags-y += -Idrivers/staging/vc04_services -D__VCCOREVER__=0x04000000 - +ccflags-y += -I $(srctree)/$(src)/.. -D__VCCOREVER__=0x04000000 diff --git a/drivers/staging/vc04_services/bcm2835-camera/Makefile b/drivers/staging/vc04_services/bcm2835-camera/Makefile index 2a4565e682d8..472f21e1f2a1 100644 --- a/drivers/staging/vc04_services/bcm2835-camera/Makefile +++ b/drivers/staging/vc04_services/bcm2835-camera/Makefile @@ -7,5 +7,5 @@ bcm2835-v4l2-$(CONFIG_VIDEO_BCM2835) := \ obj-$(CONFIG_VIDEO_BCM2835) += bcm2835-v4l2.o ccflags-y += \ - -Idrivers/staging/vc04_services \ + -I $(srctree)/$(src)/.. \ -D__VCCOREVER__=0x04000000 diff --git a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c index 611a6ee2943a..7c6cf41645eb 100644 --- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c +++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c @@ -1370,10 +1370,6 @@ static int vidioc_g_parm(struct file *file, void *priv, return 0; } -#define FRACT_CMP(a, OP, b) \ - ((u64)(a).numerator * (b).denominator OP \ - (u64)(b).numerator * (a).denominator) - static int vidioc_s_parm(struct file *file, void *priv, struct v4l2_streamparm *parm) { @@ -1387,8 +1383,8 @@ static int vidioc_s_parm(struct file *file, void *priv, /* tpf: {*, 0} resets timing; clip to [min, max]*/ tpf = tpf.denominator ? tpf : tpf_default; - tpf = FRACT_CMP(tpf, <, tpf_min) ? tpf_min : tpf; - tpf = FRACT_CMP(tpf, >, tpf_max) ? tpf_max : tpf; + tpf = V4L2_FRACT_COMPARE(tpf, <, tpf_min) ? tpf_min : tpf; + tpf = V4L2_FRACT_COMPARE(tpf, >, tpf_max) ? tpf_max : tpf; dev->capture.timeperframe = tpf; parm->parm.capture.timeperframe = tpf; diff --git a/drivers/staging/vt6655/baseband.c b/drivers/staging/vt6655/baseband.c index b5ba0c76fb43..b4cdc0b7fee7 100644 --- a/drivers/staging/vt6655/baseband.c +++ b/drivers/staging/vt6655/baseband.c @@ -1704,13 +1704,9 @@ static const unsigned short awcFrameTime[MAX_RATE] = { * Return Value: FrameTime * */ -unsigned int -BBuGetFrameTime( - unsigned char byPreambleType, - unsigned char byPktType, - unsigned int cbFrameLength, - unsigned short wRate -) +unsigned int BBuGetFrameTime(unsigned char byPreambleType, + unsigned char byPktType, + unsigned int cbFrameLength, unsigned short wRate) { unsigned int uFrameTime; unsigned int uPreamble; diff --git a/drivers/staging/vt6655/baseband.h b/drivers/staging/vt6655/baseband.h index 30d9e9d20a39..0cc2e07829c5 100644 --- a/drivers/staging/vt6655/baseband.h +++ b/drivers/staging/vt6655/baseband.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. * All rights reserved. diff --git a/drivers/staging/vt6655/card.c b/drivers/staging/vt6655/card.c index 52e9e6b90b56..6ecbe925026d 100644 --- a/drivers/staging/vt6655/card.c +++ b/drivers/staging/vt6655/card.c @@ -60,14 +60,9 @@ static const unsigned short cwRXBCNTSFOff[MAX_RATE] = { /*--------------------- Static Functions --------------------------*/ -static -void -s_vCalculateOFDMRParameter( - unsigned char byRate, - u8 bb_type, - unsigned char *pbyTxRate, - unsigned char *pbyRsvTime -); +static void s_vCalculateOFDMRParameter(unsigned char byRate, u8 bb_type, + unsigned char *pbyTxRate, + unsigned char *pbyRsvTime); /*--------------------- Export Functions --------------------------*/ @@ -506,10 +501,7 @@ bool CARDbRadioPowerOn(struct vnt_private *priv) return bResult; } -void -CARDvSafeResetTx( - struct vnt_private *priv -) +void CARDvSafeResetTx(struct vnt_private *priv) { unsigned int uu; struct vnt_tx_desc *pCurrTD; diff --git a/drivers/staging/vt6655/card.h b/drivers/staging/vt6655/card.h index 5884fd56153e..d71022aa3f86 100644 --- a/drivers/staging/vt6655/card.h +++ b/drivers/staging/vt6655/card.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. * All rights reserved. diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index c9097e7367d8..b370985b58a1 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -805,12 +805,12 @@ static bool device_alloc_rx_buf(struct vnt_private *priv, } static void device_free_rx_buf(struct vnt_private *priv, - struct vnt_rx_desc *rd) + struct vnt_rx_desc *rd) { struct vnt_rd_info *rd_info = rd->rd_info; dma_unmap_single(&priv->pcid->dev, rd_info->skb_dma, - priv->rx_buf_sz, DMA_FROM_DEVICE); + priv->rx_buf_sz, DMA_FROM_DEVICE); dev_kfree_skb(rd_info->skb); } diff --git a/drivers/staging/vt6656/key.c b/drivers/staging/vt6656/key.c index 91dede54cc1f..dcd933a6b66e 100644 --- a/drivers/staging/vt6656/key.c +++ b/drivers/staging/vt6656/key.c @@ -63,17 +63,19 @@ static int vnt_set_keymode(struct ieee80211_hw *hw, u8 *mac_addr, } switch (key_type) { - /* fallthrough */ case VNT_KEY_DEFAULTKEY: /* default key last entry */ entry = MAX_KEY_TABLE - 1; key->hw_key_idx = entry; + /* fall through */ case VNT_KEY_ALLGROUP: key_mode |= VNT_KEY_ALLGROUP; if (onfly_latch) key_mode |= VNT_KEY_ONFLY_ALL; + /* fall through */ case VNT_KEY_GROUP_ADDRESS: key_mode |= mode; + /* fall through */ case VNT_KEY_GROUP: key_mode |= (mode << 4); key_mode |= VNT_KEY_GROUP; diff --git a/drivers/staging/vt6656/mac.h b/drivers/staging/vt6656/mac.h index 94e700fcd0b6..3fd87f95c524 100644 --- a/drivers/staging/vt6656/mac.h +++ b/drivers/staging/vt6656/mac.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. * All rights reserved. diff --git a/drivers/staging/wilc1000/Makefile b/drivers/staging/wilc1000/Makefile index 72a4daa05fdb..2ad3feed9725 100644 --- a/drivers/staging/wilc1000/Makefile +++ b/drivers/staging/wilc1000/Makefile @@ -4,7 +4,7 @@ obj-$(CONFIG_WILC1000) += wilc1000.o ccflags-y += -DFIRMWARE_1002=\"atmel/wilc1002_firmware.bin\" \ -DFIRMWARE_1003=\"atmel/wilc1003_firmware.bin\" -wilc1000-objs := wilc_wfi_cfgoperations.o linux_wlan.o linux_mon.o \ +wilc1000-objs := wilc_wfi_cfgoperations.o wilc_netdev.o wilc_mon.o \ host_interface.o wilc_wlan_cfg.o wilc_wlan.o obj-$(CONFIG_WILC1000_SDIO) += wilc1000-sdio.o diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 3d0badc34825..4dd9a20f6a0b 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -6,25 +6,23 @@ #include "wilc_wfi_netdevice.h" -#define HOST_IF_SCAN_TIMEOUT 4000 -#define HOST_IF_CONNECT_TIMEOUT 9500 +#define WILC_HIF_SCAN_TIMEOUT_MS 4000 +#define WILC_HIF_CONNECT_TIMEOUT_MS 9500 -#define FALSE_FRMWR_CHANNEL 100 +#define WILC_FALSE_FRMWR_CHANNEL 100 +#define WILC_MAX_RATES_SUPPORTED 12 -#define REAL_JOIN_REQ 0 - -struct rcvd_async_info { - u8 *buffer; - u32 len; +struct wilc_rcvd_mac_info { + u8 status; }; -struct set_multicast { - bool enabled; +struct wilc_set_multicast { + u32 enabled; u32 cnt; u8 *mc_list; }; -struct del_all_sta { +struct wilc_del_all_sta { u8 assoc_sta; u8 mac[WILC_MAX_NUM_STA][ETH_ALEN]; }; @@ -71,16 +69,16 @@ struct wilc_gtk_key { u8 key[0]; } __packed; -union message_body { - struct rcvd_net_info net_info; - struct rcvd_async_info async_info; - struct set_multicast multicast_info; - struct remain_ch remain_on_ch; +union wilc_message_body { + struct wilc_rcvd_net_info net_info; + struct wilc_rcvd_mac_info mac_info; + struct wilc_set_multicast mc_info; + struct wilc_remain_ch remain_on_ch; char *data; }; struct host_if_msg { - union message_body body; + union wilc_message_body body; struct wilc_vif *vif; struct work_struct work; void (*fn)(struct work_struct *ws); @@ -88,37 +86,50 @@ struct host_if_msg { bool is_sync; }; -struct join_bss_param { - enum bss_types bss_type; +struct wilc_noa_opp_enable { + u8 ct_window; + u8 cnt; + __le32 duration; + __le32 interval; + __le32 start_time; +} __packed; + +struct wilc_noa_opp_disable { + u8 cnt; + __le32 duration; + __le32 interval; + __le32 start_time; +} __packed; + +struct wilc_join_bss_param { + char ssid[IEEE80211_MAX_SSID_LEN]; + u8 ssid_terminator; + u8 bss_type; + u8 ch; + __le16 cap_info; + u8 sa[ETH_ALEN]; + u8 bssid[ETH_ALEN]; + __le16 beacon_period; u8 dtim_period; - u16 beacon_period; - u16 cap_info; - u8 bssid[6]; - char ssid[MAX_SSID_LEN]; - u8 ssid_len; - u8 supp_rates[MAX_RATES_SUPPORTED + 1]; - u8 ht_capable; + u8 supp_rates[WILC_MAX_RATES_SUPPORTED + 1]; u8 wmm_cap; u8 uapsd_cap; - bool rsn_found; + u8 ht_capable; + u8 rsn_found; u8 rsn_grp_policy; u8 mode_802_11i; - u8 rsn_pcip_policy[3]; - u8 rsn_auth_policy[3]; + u8 p_suites[3]; + u8 akm_suites[3]; u8 rsn_cap[2]; - u32 tsf; u8 noa_enabled; - u8 opp_enabled; - u8 ct_window; - u8 cnt; + __le32 tsf_lo; u8 idx; - u8 duration[4]; - u8 interval[4]; - u8 start_time[4]; -}; - -static struct host_if_drv *terminated_handle; -static struct mutex hif_deinit_lock; + u8 opp_enabled; + union { + struct wilc_noa_opp_disable opp_dis; + struct wilc_noa_opp_enable opp_en; + }; +} __packed; /* 'msg' should be free by the caller for syc */ static struct host_if_msg* @@ -185,7 +196,7 @@ static int handle_scan_done(struct wilc_vif *vif, enum scan_event evt) u8 abort_running_scan; struct wid wid; struct host_if_drv *hif_drv = vif->hif_drv; - struct user_scan_req *scan_req; + struct wilc_user_scan_req *scan_req; if (evt == SCAN_EVENT_ABORTED) { abort_running_scan = 1; @@ -210,7 +221,7 @@ static int handle_scan_done(struct wilc_vif *vif, enum scan_event evt) scan_req = &hif_drv->usr_scan_req; if (scan_req->scan_result) { - scan_req->scan_result(evt, NULL, scan_req->arg, NULL); + scan_req->scan_result(evt, NULL, scan_req->arg); scan_req->scan_result = NULL; } @@ -218,9 +229,10 @@ static int handle_scan_done(struct wilc_vif *vif, enum scan_event evt) } int wilc_scan(struct wilc_vif *vif, u8 scan_source, u8 scan_type, - u8 *ch_freq_list, u8 ch_list_len, const u8 *ies, - size_t ies_len, wilc_scan_result scan_result, void *user_arg, - struct hidden_network *hidden_net) + u8 *ch_freq_list, u8 ch_list_len, const u8 *ies, size_t ies_len, + void (*scan_result_fn)(enum scan_event, + struct wilc_rcvd_net_info *, void *), + void *user_arg, struct wilc_probe_ssid *search) { int result = 0; struct wid wid_list[5]; @@ -228,7 +240,7 @@ int wilc_scan(struct wilc_vif *vif, u8 scan_source, u8 scan_type, u32 i; u8 *buffer; u8 valuesize = 0; - u8 *hdn_ntwk_wid_val = NULL; + u8 *search_ssid_vals = NULL; struct host_if_drv *hif_drv = vif->hif_drv; if (hif_drv->hif_state >= HOST_IF_SCANNING && @@ -246,26 +258,24 @@ int wilc_scan(struct wilc_vif *vif, u8 scan_source, u8 scan_type, hif_drv->usr_scan_req.ch_cnt = 0; - if (hidden_net) { - wid_list[index].id = WID_SSID_PROBE_REQ; - wid_list[index].type = WID_STR; - - for (i = 0; i < hidden_net->n_ssids; i++) - valuesize += ((hidden_net->net_info[i].ssid_len) + 1); - hdn_ntwk_wid_val = kmalloc(valuesize + 1, GFP_KERNEL); - wid_list[index].val = hdn_ntwk_wid_val; - if (wid_list[index].val) { + if (search) { + for (i = 0; i < search->n_ssids; i++) + valuesize += ((search->ssid_info[i].ssid_len) + 1); + search_ssid_vals = kmalloc(valuesize + 1, GFP_KERNEL); + if (search_ssid_vals) { + wid_list[index].id = WID_SSID_PROBE_REQ; + wid_list[index].type = WID_STR; + wid_list[index].val = search_ssid_vals; buffer = wid_list[index].val; - *buffer++ = hidden_net->n_ssids; + *buffer++ = search->n_ssids; - for (i = 0; i < hidden_net->n_ssids; i++) { - *buffer++ = hidden_net->net_info[i].ssid_len; - memcpy(buffer, hidden_net->net_info[i].ssid, - hidden_net->net_info[i].ssid_len); - buffer += hidden_net->net_info[i].ssid_len; + for (i = 0; i < search->n_ssids; i++) { + *buffer++ = search->ssid_info[i].ssid_len; + memcpy(buffer, search->ssid_info[i].ssid, + search->ssid_info[i].ssid_len); + buffer += search->ssid_info[i].ssid_len; } - wid_list[index].size = (s32)(valuesize + 1); index++; } @@ -311,16 +321,16 @@ int wilc_scan(struct wilc_vif *vif, u8 scan_source, u8 scan_type, goto error; } - hif_drv->usr_scan_req.scan_result = scan_result; + hif_drv->usr_scan_req.scan_result = scan_result_fn; hif_drv->usr_scan_req.arg = user_arg; hif_drv->scan_timer_vif = vif; mod_timer(&hif_drv->scan_timer, - jiffies + msecs_to_jiffies(HOST_IF_SCAN_TIMEOUT)); + jiffies + msecs_to_jiffies(WILC_HIF_SCAN_TIMEOUT_MS)); error: - if (hidden_net) { - kfree(hidden_net->net_info); - kfree(hdn_ntwk_wid_val); + if (search) { + kfree(search->ssid_info); + kfree(search_ssid_vals); } return result; @@ -329,35 +339,16 @@ error: static int wilc_send_connect_wid(struct wilc_vif *vif) { int result = 0; - struct wid wid_list[8]; - u32 wid_cnt = 0, dummyval = 0; - u8 *cur_byte = NULL; + struct wid wid_list[4]; + u32 wid_cnt = 0; struct host_if_drv *hif_drv = vif->hif_drv; - struct user_conn_req *conn_attr = &hif_drv->usr_conn_req; - struct join_bss_param *bss_param = hif_drv->usr_conn_req.param; - - wid_list[wid_cnt].id = WID_SUCCESS_FRAME_COUNT; - wid_list[wid_cnt].type = WID_INT; - wid_list[wid_cnt].size = sizeof(u32); - wid_list[wid_cnt].val = (s8 *)(&(dummyval)); - wid_cnt++; - - wid_list[wid_cnt].id = WID_RECEIVED_FRAGMENT_COUNT; - wid_list[wid_cnt].type = WID_INT; - wid_list[wid_cnt].size = sizeof(u32); - wid_list[wid_cnt].val = (s8 *)(&(dummyval)); - wid_cnt++; - - wid_list[wid_cnt].id = WID_FAILED_COUNT; - wid_list[wid_cnt].type = WID_INT; - wid_list[wid_cnt].size = sizeof(u32); - wid_list[wid_cnt].val = (s8 *)(&(dummyval)); - wid_cnt++; + struct wilc_conn_info *conn_attr = &hif_drv->conn_info; + struct wilc_join_bss_param *bss_param = conn_attr->param; wid_list[wid_cnt].id = WID_INFO_ELEMENT_ASSOCIATE; wid_list[wid_cnt].type = WID_BIN_DATA; - wid_list[wid_cnt].val = conn_attr->ies; - wid_list[wid_cnt].size = conn_attr->ies_len; + wid_list[wid_cnt].val = conn_attr->req_ies; + wid_list[wid_cnt].size = conn_attr->req_ies_len; wid_cnt++; wid_list[wid_cnt].id = WID_11I_MODE; @@ -374,97 +365,8 @@ static int wilc_send_connect_wid(struct wilc_vif *vif) wid_list[wid_cnt].id = WID_JOIN_REQ_EXTENDED; wid_list[wid_cnt].type = WID_STR; - wid_list[wid_cnt].size = 112; - wid_list[wid_cnt].val = kmalloc(wid_list[wid_cnt].size, GFP_KERNEL); - - if (!wid_list[wid_cnt].val) { - result = -EFAULT; - goto error; - } - - cur_byte = wid_list[wid_cnt].val; - - if (conn_attr->ssid) { - memcpy(cur_byte, conn_attr->ssid, conn_attr->ssid_len); - cur_byte[conn_attr->ssid_len] = '\0'; - } - cur_byte += MAX_SSID_LEN; - *(cur_byte++) = WILC_FW_BSS_TYPE_INFRA; - - if (conn_attr->ch >= 1 && conn_attr->ch <= 14) { - *(cur_byte++) = conn_attr->ch; - } else { - netdev_err(vif->ndev, "Channel out of range\n"); - *(cur_byte++) = 0xFF; - } - put_unaligned_le16(bss_param->cap_info, cur_byte); - cur_byte += 2; - - if (conn_attr->bssid) - memcpy(cur_byte, conn_attr->bssid, 6); - cur_byte += 6; - - if (conn_attr->bssid) - memcpy(cur_byte, conn_attr->bssid, 6); - cur_byte += 6; - - put_unaligned_le16(bss_param->beacon_period, cur_byte); - cur_byte += 2; - *(cur_byte++) = bss_param->dtim_period; - - memcpy(cur_byte, bss_param->supp_rates, MAX_RATES_SUPPORTED + 1); - cur_byte += (MAX_RATES_SUPPORTED + 1); - - *(cur_byte++) = bss_param->wmm_cap; - *(cur_byte++) = bss_param->uapsd_cap; - - *(cur_byte++) = bss_param->ht_capable; - conn_attr->ht_capable = bss_param->ht_capable; - - *(cur_byte++) = bss_param->rsn_found; - *(cur_byte++) = bss_param->rsn_grp_policy; - *(cur_byte++) = bss_param->mode_802_11i; - - memcpy(cur_byte, bss_param->rsn_pcip_policy, - sizeof(bss_param->rsn_pcip_policy)); - cur_byte += sizeof(bss_param->rsn_pcip_policy); - - memcpy(cur_byte, bss_param->rsn_auth_policy, - sizeof(bss_param->rsn_auth_policy)); - cur_byte += sizeof(bss_param->rsn_auth_policy); - - memcpy(cur_byte, bss_param->rsn_cap, sizeof(bss_param->rsn_cap)); - cur_byte += sizeof(bss_param->rsn_cap); - - *(cur_byte++) = REAL_JOIN_REQ; - *(cur_byte++) = bss_param->noa_enabled; - - if (bss_param->noa_enabled) { - put_unaligned_le32(bss_param->tsf, cur_byte); - cur_byte += 4; - - *(cur_byte++) = bss_param->opp_enabled; - *(cur_byte++) = bss_param->idx; - - if (bss_param->opp_enabled) - *(cur_byte++) = bss_param->ct_window; - - *(cur_byte++) = bss_param->cnt; - - memcpy(cur_byte, bss_param->duration, - sizeof(bss_param->duration)); - cur_byte += sizeof(bss_param->duration); - - memcpy(cur_byte, bss_param->interval, - sizeof(bss_param->interval)); - cur_byte += sizeof(bss_param->interval); - - memcpy(cur_byte, bss_param->start_time, - sizeof(bss_param->start_time)); - cur_byte += sizeof(bss_param->start_time); - } - - cur_byte = wid_list[wid_cnt].val; + wid_list[wid_cnt].size = sizeof(*bss_param); + wid_list[wid_cnt].val = (u8 *)bss_param; wid_cnt++; result = wilc_send_config_pkt(vif, WILC_SET_CFG, wid_list, @@ -472,25 +374,17 @@ static int wilc_send_connect_wid(struct wilc_vif *vif) wilc_get_vif_idx(vif)); if (result) { netdev_err(vif->ndev, "failed to send config packet\n"); - kfree(cur_byte); goto error; } else { hif_drv->hif_state = HOST_IF_WAITING_CONN_RESP; } - kfree(cur_byte); return 0; error: - kfree(conn_attr->bssid); - conn_attr->bssid = NULL; - - kfree(conn_attr->ssid); - conn_attr->ssid = NULL; - - kfree(conn_attr->ies); - conn_attr->ies = NULL; + kfree(conn_attr->req_ies); + conn_attr->req_ies = NULL; return result; } @@ -500,7 +394,6 @@ static void handle_connect_timeout(struct work_struct *work) struct host_if_msg *msg = container_of(work, struct host_if_msg, work); struct wilc_vif *vif = msg->vif; int result; - struct connect_info info; struct wid wid; u16 dummy_reason_code = 0; struct host_if_drv *hif_drv = vif->hif_drv; @@ -512,31 +405,11 @@ static void handle_connect_timeout(struct work_struct *work) hif_drv->hif_state = HOST_IF_IDLE; - memset(&info, 0, sizeof(struct connect_info)); + if (hif_drv->conn_info.conn_result) { + hif_drv->conn_info.conn_result(CONN_DISCONN_EVENT_CONN_RESP, + WILC_MAC_STATUS_DISCONNECTED, + hif_drv->conn_info.arg); - if (hif_drv->usr_conn_req.conn_result) { - if (hif_drv->usr_conn_req.bssid) { - memcpy(info.bssid, - hif_drv->usr_conn_req.bssid, 6); - } - - if (hif_drv->usr_conn_req.ies) { - info.req_ies_len = hif_drv->usr_conn_req.ies_len; - info.req_ies = kmemdup(hif_drv->usr_conn_req.ies, - hif_drv->usr_conn_req.ies_len, - GFP_KERNEL); - if (!info.req_ies) - goto out; - } - - hif_drv->usr_conn_req.conn_result(CONN_DISCONN_EVENT_CONN_RESP, - &info, - WILC_MAC_STATUS_DISCONNECTED, - NULL, - hif_drv->usr_conn_req.arg); - - kfree(info.req_ies); - info.req_ies = NULL; } else { netdev_err(vif->ndev, "%s: conn_result is NULL\n", __func__); } @@ -551,346 +424,174 @@ static void handle_connect_timeout(struct work_struct *work) if (result) netdev_err(vif->ndev, "Failed to send disconnect\n"); - hif_drv->usr_conn_req.ssid_len = 0; - kfree(hif_drv->usr_conn_req.ssid); - hif_drv->usr_conn_req.ssid = NULL; - kfree(hif_drv->usr_conn_req.bssid); - hif_drv->usr_conn_req.bssid = NULL; - hif_drv->usr_conn_req.ies_len = 0; - kfree(hif_drv->usr_conn_req.ies); - hif_drv->usr_conn_req.ies = NULL; + hif_drv->conn_info.req_ies_len = 0; + kfree(hif_drv->conn_info.req_ies); + hif_drv->conn_info.req_ies = NULL; out: kfree(msg); } -static void host_int_fill_join_bss_param(struct join_bss_param *param, u8 *ies, - u16 *out_index, u8 *pcipher_tc, - u8 *auth_total_cnt, u32 tsf_lo, - u8 *rates_no) +void *wilc_parse_join_bss_param(struct cfg80211_bss *bss, + struct cfg80211_crypto_settings *crypto) { - u8 ext_rates_no; - u16 offset; - u8 pcipher_cnt; - u8 auth_cnt; - u8 i, j; - u16 index = *out_index; - - if (ies[index] == WLAN_EID_SUPP_RATES) { - *rates_no = ies[index + 1]; - param->supp_rates[0] = *rates_no; - index += 2; - - for (i = 0; i < *rates_no; i++) - param->supp_rates[i + 1] = ies[index + i]; - - index += *rates_no; - } else if (ies[index] == WLAN_EID_EXT_SUPP_RATES) { - ext_rates_no = ies[index + 1]; - if (ext_rates_no > (MAX_RATES_SUPPORTED - *rates_no)) - param->supp_rates[0] = MAX_RATES_SUPPORTED; - else - param->supp_rates[0] += ext_rates_no; - index += 2; - for (i = 0; i < (param->supp_rates[0] - *rates_no); i++) - param->supp_rates[*rates_no + i + 1] = ies[index + i]; - - index += ext_rates_no; - } else if (ies[index] == WLAN_EID_HT_CAPABILITY) { - param->ht_capable = true; - index += ies[index + 1] + 2; - } else if ((ies[index] == WLAN_EID_VENDOR_SPECIFIC) && - (ies[index + 2] == 0x00) && (ies[index + 3] == 0x50) && - (ies[index + 4] == 0xF2) && (ies[index + 5] == 0x02) && - ((ies[index + 6] == 0x00) || (ies[index + 6] == 0x01)) && - (ies[index + 7] == 0x01)) { - param->wmm_cap = true; - - if (ies[index + 8] & BIT(7)) - param->uapsd_cap = true; - index += ies[index + 1] + 2; - } else if ((ies[index] == WLAN_EID_VENDOR_SPECIFIC) && - (ies[index + 2] == 0x50) && (ies[index + 3] == 0x6f) && - (ies[index + 4] == 0x9a) && - (ies[index + 5] == 0x09) && (ies[index + 6] == 0x0c)) { - u16 p2p_cnt; - - param->tsf = tsf_lo; - param->noa_enabled = 1; - param->idx = ies[index + 9]; - - if (ies[index + 10] & BIT(7)) { - param->opp_enabled = 1; - param->ct_window = ies[index + 10]; - } else { - param->opp_enabled = 0; - } - - param->cnt = ies[index + 11]; - p2p_cnt = index + 12; - - memcpy(param->duration, ies + p2p_cnt, 4); - p2p_cnt += 4; - - memcpy(param->interval, ies + p2p_cnt, 4); - p2p_cnt += 4; - - memcpy(param->start_time, ies + p2p_cnt, 4); - - index += ies[index + 1] + 2; - } else if ((ies[index] == WLAN_EID_RSN) || - ((ies[index] == WLAN_EID_VENDOR_SPECIFIC) && - (ies[index + 2] == 0x00) && - (ies[index + 3] == 0x50) && (ies[index + 4] == 0xF2) && - (ies[index + 5] == 0x01))) { - u16 rsn_idx = index; - - if (ies[rsn_idx] == WLAN_EID_RSN) { - param->mode_802_11i = 2; - } else { - if (param->mode_802_11i == 0) - param->mode_802_11i = 1; - rsn_idx += 4; - } - - rsn_idx += 7; - param->rsn_grp_policy = ies[rsn_idx]; - rsn_idx++; - offset = ies[rsn_idx] * 4; - pcipher_cnt = (ies[rsn_idx] > 3) ? 3 : ies[rsn_idx]; - rsn_idx += 2; - - i = *pcipher_tc; - j = 0; - for (; i < (pcipher_cnt + *pcipher_tc) && i < 3; i++, j++) { - u8 *policy = ¶m->rsn_pcip_policy[i]; - - *policy = ies[rsn_idx + ((j + 1) * 4) - 1]; - } - - *pcipher_tc += pcipher_cnt; - rsn_idx += offset; - - offset = ies[rsn_idx] * 4; - - auth_cnt = (ies[rsn_idx] > 3) ? 3 : ies[rsn_idx]; - rsn_idx += 2; - i = *auth_total_cnt; - j = 0; - for (; i < (*auth_total_cnt + auth_cnt); i++, j++) { - u8 *policy = ¶m->rsn_auth_policy[i]; - - *policy = ies[rsn_idx + ((j + 1) * 4) - 1]; - } - - *auth_total_cnt += auth_cnt; - rsn_idx += offset; - - if (ies[index] == WLAN_EID_RSN) { - param->rsn_cap[0] = ies[rsn_idx]; - param->rsn_cap[1] = ies[rsn_idx + 1]; - rsn_idx += 2; - } - param->rsn_found = true; - index += ies[index + 1] + 2; - } else { - index += ies[index + 1] + 2; - } - - *out_index = index; -} - -static void *host_int_parse_join_bss_param(struct network_info *info) -{ - struct join_bss_param *param; - u16 index = 0; - u8 rates_no = 0; - u8 pcipher_total_cnt = 0; - u8 auth_total_cnt = 0; + struct wilc_join_bss_param *param; + struct ieee80211_p2p_noa_attr noa_attr; + u8 rates_len = 0; + const u8 *tim_elm, *ssid_elm, *rates_ie, *supp_rates_ie; + const u8 *ht_ie, *wpa_ie, *wmm_ie, *rsn_ie; + int ret; + const struct cfg80211_bss_ies *ies = rcu_dereference(bss->ies); param = kzalloc(sizeof(*param), GFP_KERNEL); if (!param) return NULL; - param->dtim_period = info->dtim_period; - param->beacon_period = info->beacon_period; - param->cap_info = info->cap_info; - memcpy(param->bssid, info->bssid, 6); - memcpy((u8 *)param->ssid, info->ssid, info->ssid_len + 1); - param->ssid_len = info->ssid_len; - memset(param->rsn_pcip_policy, 0xFF, 3); - memset(param->rsn_auth_policy, 0xFF, 3); - - while (index < info->ies_len) - host_int_fill_join_bss_param(param, info->ies, &index, - &pcipher_total_cnt, - &auth_total_cnt, info->tsf_lo, - &rates_no); - - return (void *)param; -} - -static inline u8 *get_bssid(struct ieee80211_mgmt *mgmt) -{ - if (ieee80211_has_fromds(mgmt->frame_control)) - return mgmt->sa; - else if (ieee80211_has_tods(mgmt->frame_control)) - return mgmt->da; - else - return mgmt->bssid; -} + param->beacon_period = cpu_to_le16(bss->beacon_interval); + param->cap_info = cpu_to_le16(bss->capability); + param->bss_type = WILC_FW_BSS_TYPE_INFRA; + param->ch = ieee80211_frequency_to_channel(bss->channel->center_freq); + ether_addr_copy(param->bssid, bss->bssid); -static s32 wilc_parse_network_info(u8 *msg_buffer, - struct network_info **ret_network_info) -{ - struct network_info *info; - struct ieee80211_mgmt *mgt; - u8 *wid_val, *msa, *ies; - u16 wid_len, rx_len, ies_len; - u8 msg_type; - size_t offset; - const u8 *ch_elm, *tim_elm, *ssid_elm; - - msg_type = msg_buffer[0]; - if ('N' != msg_type) - return -EFAULT; + ssid_elm = cfg80211_find_ie(WLAN_EID_SSID, ies->data, ies->len); + if (ssid_elm) { + if (ssid_elm[1] <= IEEE80211_MAX_SSID_LEN) + memcpy(param->ssid, ssid_elm + 2, ssid_elm[1]); + } - wid_len = get_unaligned_le16(&msg_buffer[6]); - wid_val = &msg_buffer[8]; + tim_elm = cfg80211_find_ie(WLAN_EID_TIM, ies->data, ies->len); + if (tim_elm && tim_elm[1] >= 2) + param->dtim_period = tim_elm[3]; - info = kzalloc(sizeof(*info), GFP_KERNEL); - if (!info) - return -ENOMEM; + memset(param->p_suites, 0xFF, 3); + memset(param->akm_suites, 0xFF, 3); - info->rssi = wid_val[0]; + rates_ie = cfg80211_find_ie(WLAN_EID_SUPP_RATES, ies->data, ies->len); + if (rates_ie) { + rates_len = rates_ie[1]; + param->supp_rates[0] = rates_len; + memcpy(¶m->supp_rates[1], rates_ie + 2, rates_len); + } - msa = &wid_val[1]; - mgt = (struct ieee80211_mgmt *)&wid_val[1]; - rx_len = wid_len - 1; + supp_rates_ie = cfg80211_find_ie(WLAN_EID_EXT_SUPP_RATES, ies->data, + ies->len); + if (supp_rates_ie) { + if (supp_rates_ie[1] > (WILC_MAX_RATES_SUPPORTED - rates_len)) + param->supp_rates[0] = WILC_MAX_RATES_SUPPORTED; + else + param->supp_rates[0] += supp_rates_ie[1]; - if (ieee80211_is_probe_resp(mgt->frame_control)) { - info->cap_info = le16_to_cpu(mgt->u.probe_resp.capab_info); - info->beacon_period = le16_to_cpu(mgt->u.probe_resp.beacon_int); - info->tsf = le64_to_cpu(mgt->u.probe_resp.timestamp); - info->tsf_lo = (u32)info->tsf; - offset = offsetof(struct ieee80211_mgmt, u.probe_resp.variable); - } else if (ieee80211_is_beacon(mgt->frame_control)) { - info->cap_info = le16_to_cpu(mgt->u.beacon.capab_info); - info->beacon_period = le16_to_cpu(mgt->u.beacon.beacon_int); - info->tsf = le64_to_cpu(mgt->u.beacon.timestamp); - info->tsf_lo = (u32)info->tsf; - offset = offsetof(struct ieee80211_mgmt, u.beacon.variable); - } else { - /* only process probe response and beacon frame */ - kfree(info); - return -EIO; + memcpy(¶m->supp_rates[rates_len + 1], supp_rates_ie + 2, + (param->supp_rates[0] - rates_len)); } - ether_addr_copy(info->bssid, get_bssid(mgt)); + ht_ie = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, ies->data, ies->len); + if (ht_ie) + param->ht_capable = true; - ies = mgt->u.beacon.variable; - ies_len = rx_len - offset; - if (ies_len <= 0) { - kfree(info); - return -EIO; + ret = cfg80211_get_p2p_attr(ies->data, ies->len, + IEEE80211_P2P_ATTR_ABSENCE_NOTICE, + (u8 *)&noa_attr, sizeof(noa_attr)); + if (ret > 0) { + param->tsf_lo = cpu_to_le32(ies->tsf); + param->noa_enabled = 1; + param->idx = noa_attr.index; + if (noa_attr.oppps_ctwindow & IEEE80211_P2P_OPPPS_ENABLE_BIT) { + param->opp_enabled = 1; + param->opp_en.ct_window = noa_attr.oppps_ctwindow; + param->opp_en.cnt = noa_attr.desc[0].count; + param->opp_en.duration = noa_attr.desc[0].duration; + param->opp_en.interval = noa_attr.desc[0].interval; + param->opp_en.start_time = noa_attr.desc[0].start_time; + } else { + param->opp_enabled = 0; + param->opp_dis.cnt = noa_attr.desc[0].count; + param->opp_dis.duration = noa_attr.desc[0].duration; + param->opp_dis.interval = noa_attr.desc[0].interval; + param->opp_dis.start_time = noa_attr.desc[0].start_time; + } + } + wmm_ie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT, + WLAN_OUI_TYPE_MICROSOFT_WMM, + ies->data, ies->len); + if (wmm_ie) { + struct ieee80211_wmm_param_ie *ie; + + ie = (struct ieee80211_wmm_param_ie *)wmm_ie; + if ((ie->oui_subtype == 0 || ie->oui_subtype == 1) && + ie->version == 1) { + param->wmm_cap = true; + if (ie->qos_info & BIT(7)) + param->uapsd_cap = true; + } } - info->ies = kmemdup(ies, ies_len, GFP_KERNEL); - if (!info->ies) { - kfree(info); - return -ENOMEM; + wpa_ie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT, + WLAN_OUI_TYPE_MICROSOFT_WPA, + ies->data, ies->len); + if (wpa_ie) { + param->mode_802_11i = 1; + param->rsn_found = true; } - info->ies_len = ies_len; + rsn_ie = cfg80211_find_ie(WLAN_EID_RSN, ies->data, ies->len); + if (rsn_ie) { + int offset = 8; - ssid_elm = cfg80211_find_ie(WLAN_EID_SSID, ies, ies_len); - if (ssid_elm) { - info->ssid_len = ssid_elm[1]; - if (info->ssid_len <= IEEE80211_MAX_SSID_LEN) - memcpy(info->ssid, ssid_elm + 2, info->ssid_len); - else - info->ssid_len = 0; + param->mode_802_11i = 2; + param->rsn_found = true; + //extract RSN capabilities + offset += (rsn_ie[offset] * 4) + 2; + offset += (rsn_ie[offset] * 4) + 2; + memcpy(param->rsn_cap, &rsn_ie[offset], 2); } - ch_elm = cfg80211_find_ie(WLAN_EID_DS_PARAMS, ies, ies_len); - if (ch_elm && ch_elm[1] > 0) - info->ch = ch_elm[2]; + if (param->rsn_found) { + int i; - tim_elm = cfg80211_find_ie(WLAN_EID_TIM, ies, ies_len); - if (tim_elm && tim_elm[1] >= 2) - info->dtim_period = tim_elm[3]; + param->rsn_grp_policy = crypto->cipher_group & 0xFF; + for (i = 0; i < crypto->n_ciphers_pairwise && i < 3; i++) + param->p_suites[i] = crypto->ciphers_pairwise[i] & 0xFF; - *ret_network_info = info; + for (i = 0; i < crypto->n_akm_suites && i < 3; i++) + param->akm_suites[i] = crypto->akm_suites[i] & 0xFF; + } - return 0; + return (void *)param; } static void handle_rcvd_ntwrk_info(struct work_struct *work) { struct host_if_msg *msg = container_of(work, struct host_if_msg, work); - struct wilc_vif *vif = msg->vif; - struct rcvd_net_info *rcvd_info = &msg->body.net_info; - u32 i; - bool found; - struct network_info *info = NULL; - void *params; - struct host_if_drv *hif_drv = vif->hif_drv; - struct user_scan_req *scan_req = &hif_drv->usr_scan_req; - - found = true; + struct wilc_rcvd_net_info *rcvd_info = &msg->body.net_info; + struct wilc_user_scan_req *scan_req = &msg->vif->hif_drv->usr_scan_req; + const u8 *ch_elm; + u8 *ies; + int ies_len; + size_t offset; - if (!scan_req->scan_result) + if (ieee80211_is_probe_resp(rcvd_info->mgmt->frame_control)) + offset = offsetof(struct ieee80211_mgmt, u.probe_resp.variable); + else if (ieee80211_is_beacon(rcvd_info->mgmt->frame_control)) + offset = offsetof(struct ieee80211_mgmt, u.beacon.variable); + else goto done; - wilc_parse_network_info(rcvd_info->buffer, &info); - if (!info || !scan_req->scan_result) { - netdev_err(vif->ndev, "%s: info or scan result NULL\n", - __func__); + ies = rcvd_info->mgmt->u.beacon.variable; + ies_len = rcvd_info->frame_len - offset; + if (ies_len <= 0) goto done; - } - - for (i = 0; i < scan_req->ch_cnt; i++) { - if (memcmp(scan_req->net_info[i].bssid, info->bssid, 6) == 0) { - if (info->rssi <= scan_req->net_info[i].rssi) { - goto done; - } else { - scan_req->net_info[i].rssi = info->rssi; - found = false; - break; - } - } - } - - if (found) { - if (scan_req->ch_cnt < MAX_NUM_SCANNED_NETWORKS) { - scan_req->net_info[scan_req->ch_cnt].rssi = info->rssi; - - memcpy(scan_req->net_info[scan_req->ch_cnt].bssid, - info->bssid, 6); - - scan_req->ch_cnt++; - info->new_network = true; - params = host_int_parse_join_bss_param(info); + ch_elm = cfg80211_find_ie(WLAN_EID_DS_PARAMS, ies, ies_len); + if (ch_elm && ch_elm[1] > 0) + rcvd_info->ch = ch_elm[2]; - scan_req->scan_result(SCAN_EVENT_NETWORK_FOUND, info, - scan_req->arg, params); - } - } else { - info->new_network = false; - scan_req->scan_result(SCAN_EVENT_NETWORK_FOUND, info, - scan_req->arg, NULL); - } + if (scan_req->scan_result) + scan_req->scan_result(SCAN_EVENT_NETWORK_FOUND, rcvd_info, + scan_req->arg); done: - kfree(rcvd_info->buffer); - rcvd_info->buffer = NULL; - - if (info) { - kfree(info->ies); - kfree(info); - } - + kfree(rcvd_info->mgmt); kfree(msg); } @@ -918,20 +619,8 @@ static void host_int_get_assoc_res_info(struct wilc_vif *vif, *rcvd_assoc_resp_info_len = wid.size; } -static inline void host_int_free_user_conn_req(struct host_if_drv *hif_drv) -{ - hif_drv->usr_conn_req.ssid_len = 0; - kfree(hif_drv->usr_conn_req.ssid); - hif_drv->usr_conn_req.ssid = NULL; - kfree(hif_drv->usr_conn_req.bssid); - hif_drv->usr_conn_req.bssid = NULL; - hif_drv->usr_conn_req.ies_len = 0; - kfree(hif_drv->usr_conn_req.ies); - hif_drv->usr_conn_req.ies = NULL; -} - static s32 wilc_parse_assoc_resp_info(u8 *buffer, u32 buffer_len, - struct connect_info *ret_conn_info) + struct wilc_conn_info *ret_conn_info) { u8 *ies; u16 ies_len; @@ -955,10 +644,8 @@ static s32 wilc_parse_assoc_resp_info(u8 *buffer, u32 buffer_len, static inline void host_int_parse_assoc_resp_info(struct wilc_vif *vif, u8 mac_status) { - struct connect_info conn_info; struct host_if_drv *hif_drv = vif->hif_drv; - - memset(&conn_info, 0, sizeof(struct connect_info)); + struct wilc_conn_info *conn_info = &hif_drv->conn_info; if (mac_status == WILC_MAC_STATUS_CONNECTED) { u32 assoc_resp_info_len; @@ -974,7 +661,7 @@ static inline void host_int_parse_assoc_resp_info(struct wilc_vif *vif, err = wilc_parse_assoc_resp_info(hif_drv->assoc_resp, assoc_resp_info_len, - &conn_info); + conn_info); if (err) netdev_err(vif->ndev, "wilc_parse_assoc_resp_info() returned error %d\n", @@ -982,31 +669,13 @@ static inline void host_int_parse_assoc_resp_info(struct wilc_vif *vif, } } - if (hif_drv->usr_conn_req.bssid) { - memcpy(conn_info.bssid, hif_drv->usr_conn_req.bssid, 6); - - if (mac_status == WILC_MAC_STATUS_CONNECTED && - conn_info.status == WLAN_STATUS_SUCCESS) { - memcpy(hif_drv->assoc_bssid, - hif_drv->usr_conn_req.bssid, ETH_ALEN); - } - } - - if (hif_drv->usr_conn_req.ies) { - conn_info.req_ies = kmemdup(hif_drv->usr_conn_req.ies, - hif_drv->usr_conn_req.ies_len, - GFP_KERNEL); - if (conn_info.req_ies) - conn_info.req_ies_len = hif_drv->usr_conn_req.ies_len; - } - del_timer(&hif_drv->connect_timer); - hif_drv->usr_conn_req.conn_result(CONN_DISCONN_EVENT_CONN_RESP, - &conn_info, mac_status, NULL, - hif_drv->usr_conn_req.arg); + conn_info->conn_result(CONN_DISCONN_EVENT_CONN_RESP, mac_status, + hif_drv->conn_info.arg); if (mac_status == WILC_MAC_STATUS_CONNECTED && - conn_info.status == WLAN_STATUS_SUCCESS) { + conn_info->status == WLAN_STATUS_SUCCESS) { + ether_addr_copy(hif_drv->assoc_bssid, conn_info->bssid); wilc_set_power_mgmt(vif, 0, 0); hif_drv->hif_state = HOST_IF_CONNECTED; @@ -1018,44 +687,39 @@ static inline void host_int_parse_assoc_resp_info(struct wilc_vif *vif, hif_drv->hif_state = HOST_IF_IDLE; } - kfree(conn_info.resp_ies); - conn_info.resp_ies = NULL; + kfree(conn_info->resp_ies); + conn_info->resp_ies = NULL; + conn_info->resp_ies_len = 0; - kfree(conn_info.req_ies); - conn_info.req_ies = NULL; - host_int_free_user_conn_req(hif_drv); + kfree(conn_info->req_ies); + conn_info->req_ies = NULL; + conn_info->req_ies_len = 0; } static inline void host_int_handle_disconnect(struct wilc_vif *vif) { - struct disconnect_info disconn_info; struct host_if_drv *hif_drv = vif->hif_drv; - wilc_connect_result conn_result = hif_drv->usr_conn_req.conn_result; - - memset(&disconn_info, 0, sizeof(struct disconnect_info)); if (hif_drv->usr_scan_req.scan_result) { del_timer(&hif_drv->scan_timer); handle_scan_done(vif, SCAN_EVENT_ABORTED); } - disconn_info.reason = 0; - disconn_info.ie = NULL; - disconn_info.ie_len = 0; - - if (conn_result) { + if (hif_drv->conn_info.conn_result) { vif->obtaining_ip = false; wilc_set_power_mgmt(vif, 0, 0); - conn_result(CONN_DISCONN_EVENT_DISCONN_NOTIF, NULL, 0, - &disconn_info, hif_drv->usr_conn_req.arg); + hif_drv->conn_info.conn_result(CONN_DISCONN_EVENT_DISCONN_NOTIF, + 0, hif_drv->conn_info.arg); } else { netdev_err(vif->ndev, "%s: conn_result is NULL\n", __func__); } eth_zero_addr(hif_drv->assoc_bssid); - host_int_free_user_conn_req(hif_drv); + hif_drv->conn_info.req_ies_len = 0; + kfree(hif_drv->conn_info.req_ies); + hif_drv->conn_info.req_ies = NULL; hif_drv->hif_state = HOST_IF_IDLE; } @@ -1063,55 +727,30 @@ static void handle_rcvd_gnrl_async_info(struct work_struct *work) { struct host_if_msg *msg = container_of(work, struct host_if_msg, work); struct wilc_vif *vif = msg->vif; - struct rcvd_async_info *rcvd_info = &msg->body.async_info; - u8 msg_type; - u8 mac_status; + struct wilc_rcvd_mac_info *mac_info = &msg->body.mac_info; struct host_if_drv *hif_drv = vif->hif_drv; - if (!rcvd_info->buffer) { - netdev_err(vif->ndev, "%s: buffer is NULL\n", __func__); - goto free_msg; - } - if (!hif_drv) { netdev_err(vif->ndev, "%s: hif driver is NULL\n", __func__); - goto free_rcvd_info; + goto free_msg; } - if (hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP || - hif_drv->hif_state == HOST_IF_CONNECTED || - hif_drv->usr_scan_req.scan_result) { - if (!hif_drv->usr_conn_req.conn_result) { - netdev_err(vif->ndev, "%s: conn_result is NULL\n", - __func__); - goto free_rcvd_info; - } - - msg_type = rcvd_info->buffer[0]; - - if ('I' != msg_type) { - netdev_err(vif->ndev, "Received Message incorrect.\n"); - goto free_rcvd_info; - } + if (!hif_drv->conn_info.conn_result) { + netdev_err(vif->ndev, "%s: conn_result is NULL\n", __func__); + goto free_msg; + } - mac_status = rcvd_info->buffer[7]; - if (hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP) { - host_int_parse_assoc_resp_info(vif, mac_status); - } else if ((mac_status == WILC_MAC_STATUS_DISCONNECTED) && - (hif_drv->hif_state == HOST_IF_CONNECTED)) { + if (hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP) { + host_int_parse_assoc_resp_info(vif, mac_info->status); + } else if (mac_info->status == WILC_MAC_STATUS_DISCONNECTED) { + if (hif_drv->hif_state == HOST_IF_CONNECTED) { host_int_handle_disconnect(vif); - } else if ((mac_status == WILC_MAC_STATUS_DISCONNECTED) && - (hif_drv->usr_scan_req.scan_result)) { + } else if (hif_drv->usr_scan_req.scan_result) { del_timer(&hif_drv->scan_timer); - if (hif_drv->usr_scan_req.scan_result) - handle_scan_done(vif, SCAN_EVENT_ABORTED); + handle_scan_done(vif, SCAN_EVENT_ABORTED); } } -free_rcvd_info: - kfree(rcvd_info->buffer); - rcvd_info->buffer = NULL; - free_msg: kfree(msg); } @@ -1120,9 +759,8 @@ int wilc_disconnect(struct wilc_vif *vif) { struct wid wid; struct host_if_drv *hif_drv = vif->hif_drv; - struct disconnect_info disconn_info; - struct user_scan_req *scan_req; - struct user_conn_req *conn_req; + struct wilc_user_scan_req *scan_req; + struct wilc_conn_info *conn_info; int result; u16 dummy_reason_code = 0; @@ -1141,27 +779,21 @@ int wilc_disconnect(struct wilc_vif *vif) return result; } - memset(&disconn_info, 0, sizeof(struct disconnect_info)); - - disconn_info.reason = 0; - disconn_info.ie = NULL; - disconn_info.ie_len = 0; scan_req = &hif_drv->usr_scan_req; - conn_req = &hif_drv->usr_conn_req; + conn_info = &hif_drv->conn_info; if (scan_req->scan_result) { del_timer(&hif_drv->scan_timer); - scan_req->scan_result(SCAN_EVENT_ABORTED, NULL, scan_req->arg, - NULL); + scan_req->scan_result(SCAN_EVENT_ABORTED, NULL, scan_req->arg); scan_req->scan_result = NULL; } - if (conn_req->conn_result) { + if (conn_info->conn_result) { if (hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP) del_timer(&hif_drv->connect_timer); - conn_req->conn_result(CONN_DISCONN_EVENT_DISCONN_NOTIF, NULL, - 0, &disconn_info, conn_req->arg); + conn_info->conn_result(CONN_DISCONN_EVENT_DISCONN_NOTIF, 0, + conn_info->arg); } else { netdev_err(vif->ndev, "%s: conn_result is NULL\n", __func__); } @@ -1170,14 +802,9 @@ int wilc_disconnect(struct wilc_vif *vif) eth_zero_addr(hif_drv->assoc_bssid); - conn_req->ssid_len = 0; - kfree(conn_req->ssid); - conn_req->ssid = NULL; - kfree(conn_req->bssid); - conn_req->bssid = NULL; - conn_req->ies_len = 0; - kfree(conn_req->ies); - conn_req->ies = NULL; + conn_info->req_ies_len = 0; + kfree(conn_info->req_ies); + conn_info->req_ies = NULL; return 0; } @@ -1285,47 +912,29 @@ static void wilc_hif_pack_sta_param(u8 *cur_byte, const u8 *mac, } static int handle_remain_on_chan(struct wilc_vif *vif, - struct remain_ch *hif_remain_ch) + struct wilc_remain_ch *hif_remain_ch) { int result; u8 remain_on_chan_flag; struct wid wid; struct host_if_drv *hif_drv = vif->hif_drv; - if (!hif_drv->remain_on_ch_pending) { - hif_drv->remain_on_ch.arg = hif_remain_ch->arg; - hif_drv->remain_on_ch.expired = hif_remain_ch->expired; - hif_drv->remain_on_ch.ready = hif_remain_ch->ready; - hif_drv->remain_on_ch.ch = hif_remain_ch->ch; - hif_drv->remain_on_ch.id = hif_remain_ch->id; - } else { - hif_remain_ch->ch = hif_drv->remain_on_ch.ch; - } + if (hif_drv->usr_scan_req.scan_result) + return -EBUSY; - if (hif_drv->usr_scan_req.scan_result) { - hif_drv->remain_on_ch_pending = 1; - result = -EBUSY; - goto error; - } - if (hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP) { - result = -EBUSY; - goto error; - } + if (hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP) + return -EBUSY; - if (vif->obtaining_ip || vif->connecting) { - result = -EBUSY; - goto error; - } + if (vif->obtaining_ip || vif->connecting) + return -EBUSY; remain_on_chan_flag = true; wid.id = WID_REMAIN_ON_CHAN; wid.type = WID_STR; wid.size = 2; wid.val = kmalloc(wid.size, GFP_KERNEL); - if (!wid.val) { - result = -ENOMEM; - goto error; - } + if (!wid.val) + return -ENOMEM; wid.val[0] = remain_on_chan_flag; wid.val[1] = (s8)hif_remain_ch->ch; @@ -1333,28 +942,23 @@ static int handle_remain_on_chan(struct wilc_vif *vif, result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1, wilc_get_vif_idx(vif)); kfree(wid.val); - if (result != 0) - netdev_err(vif->ndev, "Failed to set remain on channel\n"); + if (result) + return -EBUSY; -error: + hif_drv->remain_on_ch.arg = hif_remain_ch->arg; + hif_drv->remain_on_ch.expired = hif_remain_ch->expired; + hif_drv->remain_on_ch.ch = hif_remain_ch->ch; + hif_drv->remain_on_ch.cookie = hif_remain_ch->cookie; hif_drv->remain_on_ch_timer_vif = vif; - mod_timer(&hif_drv->remain_on_ch_timer, - jiffies + msecs_to_jiffies(hif_remain_ch->duration)); - - if (hif_drv->remain_on_ch.ready) - hif_drv->remain_on_ch.ready(hif_drv->remain_on_ch.arg); - - if (hif_drv->remain_on_ch_pending) - hif_drv->remain_on_ch_pending = 0; - return result; + return 0; } static void handle_listen_state_expired(struct work_struct *work) { struct host_if_msg *msg = container_of(work, struct host_if_msg, work); struct wilc_vif *vif = msg->vif; - struct remain_ch *hif_remain_ch = &msg->body.remain_on_ch; + struct wilc_remain_ch *hif_remain_ch = &msg->body.remain_on_ch; u8 remain_on_chan_flag; struct wid wid; int result; @@ -1372,7 +976,7 @@ static void handle_listen_state_expired(struct work_struct *work) goto free_msg; wid.val[0] = remain_on_chan_flag; - wid.val[1] = FALSE_FRMWR_CHANNEL; + wid.val[1] = WILC_FALSE_FRMWR_CHANNEL; result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1, wilc_get_vif_idx(vif)); @@ -1384,7 +988,7 @@ static void handle_listen_state_expired(struct work_struct *work) if (hif_drv->remain_on_ch.expired) { hif_drv->remain_on_ch.expired(hif_drv->remain_on_ch.arg, - hif_remain_ch->id); + hif_remain_ch->cookie); } } else { netdev_dbg(vif->ndev, "Not in listen state\n"); @@ -1408,7 +1012,7 @@ static void listen_timer_cb(struct timer_list *t) if (IS_ERR(msg)) return; - msg->body.remain_on_ch.id = vif->hif_drv->remain_on_ch.id; + msg->body.remain_on_ch.cookie = vif->hif_drv->remain_on_ch.cookie; result = wilc_enqueue_work(msg); if (result) { @@ -1421,32 +1025,27 @@ static void handle_set_mcast_filter(struct work_struct *work) { struct host_if_msg *msg = container_of(work, struct host_if_msg, work); struct wilc_vif *vif = msg->vif; - struct set_multicast *hif_set_mc = &msg->body.multicast_info; + struct wilc_set_multicast *set_mc = &msg->body.mc_info; int result; struct wid wid; u8 *cur_byte; wid.id = WID_SETUP_MULTICAST_FILTER; wid.type = WID_BIN; - wid.size = sizeof(struct set_multicast) + (hif_set_mc->cnt * ETH_ALEN); + wid.size = sizeof(struct wilc_set_multicast) + (set_mc->cnt * ETH_ALEN); wid.val = kmalloc(wid.size, GFP_KERNEL); if (!wid.val) goto error; cur_byte = wid.val; - *cur_byte++ = (hif_set_mc->enabled & 0xFF); - *cur_byte++ = 0; - *cur_byte++ = 0; - *cur_byte++ = 0; + put_unaligned_le32(set_mc->enabled, cur_byte); + cur_byte += 4; - *cur_byte++ = (hif_set_mc->cnt & 0xFF); - *cur_byte++ = ((hif_set_mc->cnt >> 8) & 0xFF); - *cur_byte++ = ((hif_set_mc->cnt >> 16) & 0xFF); - *cur_byte++ = ((hif_set_mc->cnt >> 24) & 0xFF); + put_unaligned_le32(set_mc->cnt, cur_byte); + cur_byte += 4; - if (hif_set_mc->cnt > 0 && hif_set_mc->mc_list) - memcpy(cur_byte, hif_set_mc->mc_list, - ((hif_set_mc->cnt) * ETH_ALEN)); + if (set_mc->cnt > 0 && set_mc->mc_list) + memcpy(cur_byte, set_mc->mc_list, set_mc->cnt * ETH_ALEN); result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1, wilc_get_vif_idx(vif)); @@ -1454,7 +1053,7 @@ static void handle_set_mcast_filter(struct work_struct *work) netdev_err(vif->ndev, "Failed to send setup multicast\n"); error: - kfree(hif_set_mc->mc_list); + kfree(set_mc->mc_list); kfree(wid.val); kfree(msg); } @@ -1479,9 +1078,6 @@ static void handle_scan_complete(struct work_struct *work) handle_scan_done(msg->vif, SCAN_EVENT_DONE); - if (msg->vif->hif_drv->remain_on_ch_pending) - handle_remain_on_chan(msg->vif, - &msg->vif->hif_drv->remain_on_ch); kfree(msg); } @@ -1629,7 +1225,7 @@ int wilc_add_ptk(struct wilc_vif *vif, const u8 *ptk, u8 ptk_key_len, u8 mode, u8 cipher_mode, u8 index) { int result = 0; - u8 t_key_len = ptk_key_len + RX_MIC_KEY_LEN + TX_MIC_KEY_LEN; + u8 t_key_len = ptk_key_len + WILC_RX_MIC_KEY_LEN + WILC_TX_MIC_KEY_LEN; if (mode == WILC_AP_MODE) { struct wid wid_list[2]; @@ -1651,11 +1247,11 @@ int wilc_add_ptk(struct wilc_vif *vif, const u8 *ptk, u8 ptk_key_len, if (rx_mic) memcpy(&key_buf->key[ptk_key_len], rx_mic, - RX_MIC_KEY_LEN); + WILC_RX_MIC_KEY_LEN); if (tx_mic) - memcpy(&key_buf->key[ptk_key_len + RX_MIC_KEY_LEN], - tx_mic, TX_MIC_KEY_LEN); + memcpy(&key_buf->key[ptk_key_len + WILC_RX_MIC_KEY_LEN], + tx_mic, WILC_TX_MIC_KEY_LEN); wid_list[1].id = WID_ADD_PTK; wid_list[1].type = WID_STR; @@ -1679,11 +1275,11 @@ int wilc_add_ptk(struct wilc_vif *vif, const u8 *ptk, u8 ptk_key_len, if (rx_mic) memcpy(&key_buf->key[ptk_key_len], rx_mic, - RX_MIC_KEY_LEN); + WILC_RX_MIC_KEY_LEN); if (tx_mic) - memcpy(&key_buf->key[ptk_key_len + RX_MIC_KEY_LEN], - tx_mic, TX_MIC_KEY_LEN); + memcpy(&key_buf->key[ptk_key_len + WILC_RX_MIC_KEY_LEN], + tx_mic, WILC_TX_MIC_KEY_LEN); wid.id = WID_ADD_PTK; wid.type = WID_STR; @@ -1704,7 +1300,7 @@ int wilc_add_rx_gtk(struct wilc_vif *vif, const u8 *rx_gtk, u8 gtk_key_len, { int result = 0; struct wilc_gtk_key *gtk_key; - int t_key_len = gtk_key_len + RX_MIC_KEY_LEN + TX_MIC_KEY_LEN; + int t_key_len = gtk_key_len + WILC_RX_MIC_KEY_LEN + WILC_TX_MIC_KEY_LEN; gtk_key = kzalloc(sizeof(*gtk_key) + t_key_len, GFP_KERNEL); if (!gtk_key) @@ -1722,11 +1318,11 @@ int wilc_add_rx_gtk(struct wilc_vif *vif, const u8 *rx_gtk, u8 gtk_key_len, memcpy(>k_key->key[0], rx_gtk, gtk_key_len); if (rx_mic) - memcpy(>k_key->key[gtk_key_len], rx_mic, RX_MIC_KEY_LEN); + memcpy(>k_key->key[gtk_key_len], rx_mic, WILC_RX_MIC_KEY_LEN); if (tx_mic) - memcpy(>k_key->key[gtk_key_len + RX_MIC_KEY_LEN], - tx_mic, TX_MIC_KEY_LEN); + memcpy(>k_key->key[gtk_key_len + WILC_RX_MIC_KEY_LEN], + tx_mic, WILC_TX_MIC_KEY_LEN); if (mode == WILC_AP_MODE) { struct wid wid_list[2]; @@ -1793,61 +1389,22 @@ int wilc_get_mac_address(struct wilc_vif *vif, u8 *mac_addr) return result; } -int wilc_set_join_req(struct wilc_vif *vif, u8 *bssid, const u8 *ssid, - size_t ssid_len, const u8 *ies, size_t ies_len, - wilc_connect_result connect_result, void *user_arg, - u8 security, enum authtype auth_type, - u8 channel, void *join_params) +int wilc_set_join_req(struct wilc_vif *vif, u8 *bssid, const u8 *ies, + size_t ies_len) { int result; struct host_if_drv *hif_drv = vif->hif_drv; - struct user_conn_req *con_info = &hif_drv->usr_conn_req; + struct wilc_conn_info *conn_info = &hif_drv->conn_info; - if (!hif_drv || !connect_result) { - netdev_err(vif->ndev, - "%s: hif driver or connect result is NULL", - __func__); - return -EFAULT; - } - - if (!join_params) { - netdev_err(vif->ndev, "%s: joinparams is NULL\n", __func__); - return -EFAULT; - } - - if (hif_drv->usr_scan_req.scan_result) { - netdev_err(vif->ndev, "%s: Scan in progress\n", __func__); - return -EBUSY; - } - - con_info->security = security; - con_info->auth_type = auth_type; - con_info->ch = channel; - con_info->conn_result = connect_result; - con_info->arg = user_arg; - con_info->param = join_params; - - if (bssid) { - con_info->bssid = kmemdup(bssid, 6, GFP_KERNEL); - if (!con_info->bssid) - return -ENOMEM; - } - - if (ssid) { - con_info->ssid_len = ssid_len; - con_info->ssid = kmemdup(ssid, ssid_len, GFP_KERNEL); - if (!con_info->ssid) { - result = -ENOMEM; - goto free_bssid; - } - } + if (bssid) + ether_addr_copy(conn_info->bssid, bssid); if (ies) { - con_info->ies_len = ies_len; - con_info->ies = kmemdup(ies, ies_len, GFP_KERNEL); - if (!con_info->ies) { + conn_info->req_ies_len = ies_len; + conn_info->req_ies = kmemdup(ies, ies_len, GFP_KERNEL); + if (!conn_info->req_ies) { result = -ENOMEM; - goto free_ssid; + return result; } } @@ -1857,18 +1414,12 @@ int wilc_set_join_req(struct wilc_vif *vif, u8 *bssid, const u8 *ssid, hif_drv->connect_timer_vif = vif; mod_timer(&hif_drv->connect_timer, - jiffies + msecs_to_jiffies(HOST_IF_CONNECT_TIMEOUT)); + jiffies + msecs_to_jiffies(WILC_HIF_CONNECT_TIMEOUT_MS)); return 0; free_ies: - kfree(con_info->ies); - -free_ssid: - kfree(con_info->ssid); - -free_bssid: - kfree(con_info->bssid); + kfree(conn_info->req_ies); return result; } @@ -1899,6 +1450,9 @@ int wilc_set_wfi_drv_handler(struct wilc_vif *vif, int index, u8 mode, int result; struct wilc_drv_handler drv; + if (!hif_drv) + return -EFAULT; + wid.id = WID_SET_DRV_HANDLER; wid.type = WID_STR; wid.size = sizeof(drv); @@ -1991,7 +1545,7 @@ int wilc_get_rssi(struct wilc_vif *vif, s8 *rssi_level) return result; } -int wilc_get_stats_async(struct wilc_vif *vif, struct rf_info *stats) +static int wilc_get_stats_async(struct wilc_vif *vif, struct rf_info *stats) { int result; struct host_if_msg *msg; @@ -2090,7 +1644,7 @@ int wilc_init(struct net_device *dev, struct host_if_drv **hif_drv_handler) vif->obtaining_ip = false; if (wilc->clients_count == 0) - mutex_init(&hif_deinit_lock); + mutex_init(&wilc->deinit_lock); timer_setup(&vif->periodic_rssi, get_periodic_rssi, 0); mod_timer(&vif->periodic_rssi, jiffies + msecs_to_jiffies(5000)); @@ -2118,9 +1672,7 @@ int wilc_deinit(struct wilc_vif *vif) return -EFAULT; } - mutex_lock(&hif_deinit_lock); - - terminated_handle = hif_drv; + mutex_lock(&vif->wilc->deinit_lock); del_timer_sync(&hif_drv->scan_timer); del_timer_sync(&hif_drv->connect_timer); @@ -2131,18 +1683,16 @@ int wilc_deinit(struct wilc_vif *vif) if (hif_drv->usr_scan_req.scan_result) { hif_drv->usr_scan_req.scan_result(SCAN_EVENT_ABORTED, NULL, - hif_drv->usr_scan_req.arg, - NULL); + hif_drv->usr_scan_req.arg); hif_drv->usr_scan_req.scan_result = NULL; } hif_drv->hif_state = HOST_IF_IDLE; kfree(hif_drv); - + vif->hif_drv = NULL; vif->wilc->clients_count--; - terminated_handle = NULL; - mutex_unlock(&hif_deinit_lock); + mutex_unlock(&vif->wilc->deinit_lock); return result; } @@ -2154,16 +1704,13 @@ void wilc_network_info_received(struct wilc *wilc, u8 *buffer, u32 length) struct host_if_drv *hif_drv; struct wilc_vif *vif; - id = buffer[length - 4]; - id |= (buffer[length - 3] << 8); - id |= (buffer[length - 2] << 16); - id |= (buffer[length - 1] << 24); + id = get_unaligned_le32(&buffer[length - 4]); vif = wilc_get_vif_from_idx(wilc, id); if (!vif) return; hif_drv = vif->hif_drv; - if (!hif_drv || hif_drv == terminated_handle) { + if (!hif_drv) { netdev_err(vif->ndev, "driver not init[%p]\n", hif_drv); return; } @@ -2172,9 +1719,12 @@ void wilc_network_info_received(struct wilc *wilc, u8 *buffer, u32 length) if (IS_ERR(msg)) return; - msg->body.net_info.len = length; - msg->body.net_info.buffer = kmemdup(buffer, length, GFP_KERNEL); - if (!msg->body.net_info.buffer) { + msg->body.net_info.frame_len = get_unaligned_le16(&buffer[6]) - 1; + msg->body.net_info.rssi = buffer[8]; + msg->body.net_info.mgmt = kmemdup(&buffer[9], + msg->body.net_info.frame_len, + GFP_KERNEL); + if (!msg->body.net_info.mgmt) { kfree(msg); return; } @@ -2182,7 +1732,7 @@ void wilc_network_info_received(struct wilc *wilc, u8 *buffer, u32 length) result = wilc_enqueue_work(msg); if (result) { netdev_err(vif->ndev, "%s: enqueue work failed\n", __func__); - kfree(msg->body.net_info.buffer); + kfree(msg->body.net_info.mgmt); kfree(msg); } } @@ -2195,53 +1745,42 @@ void wilc_gnrl_async_info_received(struct wilc *wilc, u8 *buffer, u32 length) struct host_if_drv *hif_drv; struct wilc_vif *vif; - mutex_lock(&hif_deinit_lock); + mutex_lock(&wilc->deinit_lock); - id = buffer[length - 4]; - id |= (buffer[length - 3] << 8); - id |= (buffer[length - 2] << 16); - id |= (buffer[length - 1] << 24); + id = get_unaligned_le32(&buffer[length - 4]); vif = wilc_get_vif_from_idx(wilc, id); if (!vif) { - mutex_unlock(&hif_deinit_lock); + mutex_unlock(&wilc->deinit_lock); return; } hif_drv = vif->hif_drv; - if (!hif_drv || hif_drv == terminated_handle) { - mutex_unlock(&hif_deinit_lock); + if (!hif_drv) { + mutex_unlock(&wilc->deinit_lock); return; } - if (!hif_drv->usr_conn_req.conn_result) { + if (!hif_drv->conn_info.conn_result) { netdev_err(vif->ndev, "%s: conn_result is NULL\n", __func__); - mutex_unlock(&hif_deinit_lock); + mutex_unlock(&wilc->deinit_lock); return; } msg = wilc_alloc_work(vif, handle_rcvd_gnrl_async_info, false); if (IS_ERR(msg)) { - mutex_unlock(&hif_deinit_lock); - return; - } - - msg->body.async_info.len = length; - msg->body.async_info.buffer = kmemdup(buffer, length, GFP_KERNEL); - if (!msg->body.async_info.buffer) { - kfree(msg); - mutex_unlock(&hif_deinit_lock); + mutex_unlock(&wilc->deinit_lock); return; } + msg->body.mac_info.status = buffer[7]; result = wilc_enqueue_work(msg); if (result) { netdev_err(vif->ndev, "%s: enqueue work failed\n", __func__); - kfree(msg->body.async_info.buffer); kfree(msg); } - mutex_unlock(&hif_deinit_lock); + mutex_unlock(&wilc->deinit_lock); } void wilc_scan_complete_received(struct wilc *wilc, u8 *buffer, u32 length) @@ -2251,16 +1790,13 @@ void wilc_scan_complete_received(struct wilc *wilc, u8 *buffer, u32 length) struct host_if_drv *hif_drv; struct wilc_vif *vif; - id = buffer[length - 4]; - id |= buffer[length - 3] << 8; - id |= buffer[length - 2] << 16; - id |= buffer[length - 1] << 24; + id = get_unaligned_le32(&buffer[length - 4]); vif = wilc_get_vif_from_idx(wilc, id); if (!vif) return; hif_drv = vif->hif_drv; - if (!hif_drv || hif_drv == terminated_handle) + if (!hif_drv) return; if (hif_drv->usr_scan_req.scan_result) { @@ -2279,21 +1815,19 @@ void wilc_scan_complete_received(struct wilc *wilc, u8 *buffer, u32 length) } } -int wilc_remain_on_channel(struct wilc_vif *vif, u32 session_id, +int wilc_remain_on_channel(struct wilc_vif *vif, u64 cookie, u32 duration, u16 chan, - wilc_remain_on_chan_expired expired, - wilc_remain_on_chan_ready ready, + void (*expired)(void *, u64), void *user_arg) { - struct remain_ch roc; + struct wilc_remain_ch roc; int result; roc.ch = chan; roc.expired = expired; - roc.ready = ready; roc.arg = user_arg; roc.duration = duration; - roc.id = session_id; + roc.cookie = cookie; result = handle_remain_on_chan(vif, &roc); if (result) netdev_err(vif->ndev, "%s: failed to set remain on channel\n", @@ -2302,7 +1836,7 @@ int wilc_remain_on_channel(struct wilc_vif *vif, u32 session_id, return result; } -int wilc_listen_state_expired(struct wilc_vif *vif, u32 session_id) +int wilc_listen_state_expired(struct wilc_vif *vif, u64 cookie) { int result; struct host_if_msg *msg; @@ -2319,7 +1853,7 @@ int wilc_listen_state_expired(struct wilc_vif *vif, u32 session_id) if (IS_ERR(msg)) return PTR_ERR(msg); - msg->body.remain_on_ch.id = session_id; + msg->body.remain_on_ch.cookie = cookie; result = wilc_enqueue_work(msg); if (result) { @@ -2484,7 +2018,7 @@ int wilc_del_allstation(struct wilc_vif *vif, u8 mac_addr[][ETH_ALEN]) int result; int i; u8 assoc_sta = 0; - struct del_all_sta del_sta; + struct wilc_del_all_sta del_sta; memset(&del_sta, 0x0, sizeof(del_sta)); for (i = 0; i < WILC_MAX_NUM_STA; i++) { @@ -2563,7 +2097,7 @@ int wilc_set_power_mgmt(struct wilc_vif *vif, bool enabled, u32 timeout) return result; } -int wilc_setup_multicast_filter(struct wilc_vif *vif, bool enabled, u32 count, +int wilc_setup_multicast_filter(struct wilc_vif *vif, u32 enabled, u32 count, u8 *mc_list) { int result; @@ -2573,9 +2107,9 @@ int wilc_setup_multicast_filter(struct wilc_vif *vif, bool enabled, u32 count, if (IS_ERR(msg)) return PTR_ERR(msg); - msg->body.multicast_info.enabled = enabled; - msg->body.multicast_info.cnt = count; - msg->body.multicast_info.mc_list = mc_list; + msg->body.mc_info.enabled = enabled; + msg->body.mc_info.cnt = count; + msg->body.mc_info.mc_list = mc_list; result = wilc_enqueue_work(msg); if (result) { diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 9b396a79b144..678e62312215 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -18,19 +18,16 @@ enum { }; #define WILC_MAX_NUM_STA 9 -#define MAX_NUM_SCANNED_NETWORKS 100 -#define MAX_NUM_SCANNED_NETWORKS_SHADOW 130 +#define WILC_MAX_NUM_SCANNED_CH 14 #define WILC_MAX_NUM_PROBED_SSID 10 -#define TX_MIC_KEY_LEN 8 -#define RX_MIC_KEY_LEN 8 +#define WILC_TX_MIC_KEY_LEN 8 +#define WILC_RX_MIC_KEY_LEN 8 #define WILC_MAX_NUM_PMKIDS 16 #define WILC_ADD_STA_LENGTH 40 #define WILC_NUM_CONCURRENT_IFC 2 -#define NUM_RSSI 5 - enum { WILC_SET_CFG = 0, WILC_GET_CFG @@ -38,48 +35,6 @@ enum { #define WILC_MAX_ASSOC_RESP_FRAME_SIZE 256 -struct rssi_history_buffer { - bool full; - u8 index; - s8 samples[NUM_RSSI]; -}; - -struct network_info { - s8 rssi; - u16 cap_info; - u8 ssid[MAX_SSID_LEN]; - u8 ssid_len; - u8 bssid[6]; - u16 beacon_period; - u8 dtim_period; - u8 ch; - unsigned long time_scan_cached; - unsigned long time_scan; - bool new_network; - u8 found; - u32 tsf_lo; - u8 *ies; - u16 ies_len; - void *join_params; - struct rssi_history_buffer rssi_history; - u64 tsf; -}; - -struct connect_info { - u8 bssid[6]; - u8 *req_ies; - size_t req_ies_len; - u8 *resp_ies; - u16 resp_ies_len; - u16 status; -}; - -struct disconnect_info { - u16 reason; - u8 *ie; - size_t ie_len; -}; - struct assoc_resp { __le16 capab_info; __le16 status_code; @@ -129,11 +84,6 @@ enum cfg_param { WILC_CFG_PARAM_RTS_THRESHOLD = BIT(3) }; -struct found_net_info { - u8 bssid[6]; - s8 rssi; -}; - enum scan_event { SCAN_EVENT_NETWORK_FOUND = 0, SCAN_EVENT_DONE = 1, @@ -147,72 +97,71 @@ enum conn_event { CONN_DISCONN_EVENT_FORCE_32BIT = 0xFFFFFFFF }; -typedef void (*wilc_scan_result)(enum scan_event, struct network_info *, - void *, void *); - -typedef void (*wilc_connect_result)(enum conn_event, - struct connect_info *, - u8, - struct disconnect_info *, - void *); +enum { + WILC_HIF_SDIO = 0, + WILC_HIF_SPI = BIT(0) +}; -typedef void (*wilc_remain_on_chan_expired)(void *, u32); -typedef void (*wilc_remain_on_chan_ready)(void *); +enum { + WILC_MAC_STATUS_INIT = -1, + WILC_MAC_STATUS_DISCONNECTED = 0, + WILC_MAC_STATUS_CONNECTED = 1 +}; -struct rcvd_net_info { - u8 *buffer; - u32 len; +struct wilc_rcvd_net_info { + s8 rssi; + u8 ch; + u16 frame_len; + struct ieee80211_mgmt *mgmt; }; -struct hidden_net_info { - u8 *ssid; +struct wilc_probe_ssid_info { u8 ssid_len; + u8 *ssid; }; -struct hidden_network { - struct hidden_net_info *net_info; +struct wilc_probe_ssid { + struct wilc_probe_ssid_info *ssid_info; u8 n_ssids; + u32 size; }; -struct user_scan_req { - wilc_scan_result scan_result; +struct wilc_user_scan_req { + void (*scan_result)(enum scan_event evt, + struct wilc_rcvd_net_info *info, void *priv); void *arg; u32 ch_cnt; - struct found_net_info net_info[MAX_NUM_SCANNED_NETWORKS]; }; -struct user_conn_req { - u8 *bssid; - u8 *ssid; +struct wilc_conn_info { + u8 bssid[ETH_ALEN]; u8 security; enum authtype auth_type; - size_t ssid_len; - u8 *ies; - size_t ies_len; - wilc_connect_result conn_result; - bool ht_capable; u8 ch; + u8 *req_ies; + size_t req_ies_len; + u8 *resp_ies; + u16 resp_ies_len; + u16 status; + void (*conn_result)(enum conn_event evt, u8 status, void *priv_data); void *arg; void *param; }; -struct remain_ch { +struct wilc_remain_ch { u16 ch; u32 duration; - wilc_remain_on_chan_expired expired; - wilc_remain_on_chan_ready ready; + void (*expired)(void *priv, u64 cookie); void *arg; - u32 id; + u32 cookie; }; struct wilc; struct host_if_drv { - struct user_scan_req usr_scan_req; - struct user_conn_req usr_conn_req; - struct remain_ch remain_on_ch; - u8 remain_on_ch_pending; + struct wilc_user_scan_req usr_scan_req; + struct wilc_conn_info conn_info; + struct wilc_remain_ch remain_on_ch; u64 p2p_timeout; - u8 p2p_connect; enum host_if_state hif_state; @@ -232,17 +181,6 @@ struct host_if_drv { u8 assoc_resp[WILC_MAX_ASSOC_RESP_FRAME_SIZE]; }; -struct add_sta_param { - u8 bssid[ETH_ALEN]; - u16 aid; - u8 rates_len; - const u8 *rates; - bool ht_supported; - struct ieee80211_ht_cap ht_capa; - u16 flags_mask; - u16 flags_set; -}; - struct wilc_vif; int wilc_remove_wep_key(struct wilc_vif *vif, u8 index); int wilc_set_wep_default_keyid(struct wilc_vif *vif, u8 index); @@ -261,18 +199,16 @@ int wilc_add_rx_gtk(struct wilc_vif *vif, const u8 *rx_gtk, u8 gtk_key_len, u8 cipher_mode); int wilc_set_pmkid_info(struct wilc_vif *vif, struct wilc_pmkid_attr *pmkid); int wilc_get_mac_address(struct wilc_vif *vif, u8 *mac_addr); -int wilc_set_join_req(struct wilc_vif *vif, u8 *bssid, const u8 *ssid, - size_t ssid_len, const u8 *ies, size_t ies_len, - wilc_connect_result connect_result, void *user_arg, - u8 security, enum authtype auth_type, - u8 channel, void *join_params); +int wilc_set_join_req(struct wilc_vif *vif, u8 *bssid, const u8 *ies, + size_t ies_len); int wilc_disconnect(struct wilc_vif *vif); int wilc_set_mac_chnl_num(struct wilc_vif *vif, u8 channel); int wilc_get_rssi(struct wilc_vif *vif, s8 *rssi_level); int wilc_scan(struct wilc_vif *vif, u8 scan_source, u8 scan_type, - u8 *ch_freq_list, u8 ch_list_len, const u8 *ies, - size_t ies_len, wilc_scan_result scan_result, void *user_arg, - struct hidden_network *hidden_network); + u8 *ch_freq_list, u8 ch_list_len, const u8 *ies, size_t ies_len, + void (*scan_result_fn)(enum scan_event, + struct wilc_rcvd_net_info *, void *), + void *user_arg, struct wilc_probe_ssid *search); int wilc_hif_set_cfg(struct wilc_vif *vif, struct cfg_param_attr *cfg_param); int wilc_init(struct net_device *dev, struct host_if_drv **hif_drv_handler); @@ -287,14 +223,13 @@ int wilc_del_station(struct wilc_vif *vif, const u8 *mac_addr); int wilc_edit_station(struct wilc_vif *vif, const u8 *mac, struct station_parameters *params); int wilc_set_power_mgmt(struct wilc_vif *vif, bool enabled, u32 timeout); -int wilc_setup_multicast_filter(struct wilc_vif *vif, bool enabled, u32 count, +int wilc_setup_multicast_filter(struct wilc_vif *vif, u32 enabled, u32 count, u8 *mc_list); -int wilc_remain_on_channel(struct wilc_vif *vif, u32 session_id, +int wilc_remain_on_channel(struct wilc_vif *vif, u64 cookie, u32 duration, u16 chan, - wilc_remain_on_chan_expired expired, - wilc_remain_on_chan_ready ready, + void (*expired)(void *, u64), void *user_arg); -int wilc_listen_state_expired(struct wilc_vif *vif, u32 session_id); +int wilc_listen_state_expired(struct wilc_vif *vif, u64 cookie); void wilc_frame_register(struct wilc_vif *vif, u16 frame_type, bool reg); int wilc_set_wfi_drv_handler(struct wilc_vif *vif, int index, u8 mode, u8 ifc_id); @@ -307,4 +242,6 @@ int wilc_get_tx_power(struct wilc_vif *vif, u8 *tx_power); void wilc_scan_complete_received(struct wilc *wilc, u8 *buffer, u32 length); void wilc_network_info_received(struct wilc *wilc, u8 *buffer, u32 length); void wilc_gnrl_async_info_received(struct wilc *wilc, u8 *buffer, u32 length); +void *wilc_parse_join_bss_param(struct cfg80211_bss *bss, + struct cfg80211_crypto_settings *crypto); #endif diff --git a/drivers/staging/wilc1000/linux_mon.c b/drivers/staging/wilc1000/wilc_mon.c index a63446818eac..9fe19a3e1dd4 100644 --- a/drivers/staging/wilc1000/linux_mon.c +++ b/drivers/staging/wilc1000/wilc_mon.c @@ -18,28 +18,20 @@ struct wilc_wfi_radiotap_cb_hdr { u16 tx_flags; } __packed; -static struct net_device *wilc_wfi_mon; /* global monitor netdev */ - -static u8 srcadd[6]; -static u8 bssid[6]; - -#define IEEE80211_RADIOTAP_F_TX_RTS 0x0004 /* used rts/cts handshake */ -#define IEEE80211_RADIOTAP_F_TX_FAIL 0x0001 /* failed due to excessive*/ - #define TX_RADIOTAP_PRESENT ((1 << IEEE80211_RADIOTAP_RATE) | \ (1 << IEEE80211_RADIOTAP_TX_FLAGS)) -void wilc_wfi_monitor_rx(u8 *buff, u32 size) +void wilc_wfi_monitor_rx(struct net_device *mon_dev, u8 *buff, u32 size) { u32 header, pkt_offset; struct sk_buff *skb = NULL; struct wilc_wfi_radiotap_hdr *hdr; struct wilc_wfi_radiotap_cb_hdr *cb_hdr; - if (!wilc_wfi_mon) + if (!mon_dev) return; - if (!netif_running(wilc_wfi_mon)) + if (!netif_running(mon_dev)) return; /* Get WILC header */ @@ -94,7 +86,7 @@ void wilc_wfi_monitor_rx(u8 *buff, u32 size) hdr->rate = 5; } - skb->dev = wilc_wfi_mon; + skb->dev = mon_dev; skb_reset_mac_header(skb); skb->ip_summed = CHECKSUM_UNNECESSARY; skb->pkt_type = PACKET_OTHERHOST; @@ -155,13 +147,13 @@ static netdev_tx_t wilc_wfi_mon_xmit(struct sk_buff *skb, struct wilc_wfi_mon_priv *mon_priv; struct sk_buff *skb2; struct wilc_wfi_radiotap_cb_hdr *cb_hdr; + u8 srcadd[ETH_ALEN]; + u8 bssid[ETH_ALEN]; - if (!wilc_wfi_mon) - return -EFAULT; - - mon_priv = netdev_priv(wilc_wfi_mon); + mon_priv = netdev_priv(dev); if (!mon_priv) return -EFAULT; + rtap_len = ieee80211_get_radiotap_len(skb->data); if (skb->len < rtap_len) return -1; @@ -187,7 +179,7 @@ static netdev_tx_t wilc_wfi_mon_xmit(struct sk_buff *skb, cb_hdr->rate = 5; cb_hdr->tx_flags = 0x0004; - skb2->dev = wilc_wfi_mon; + skb2->dev = dev; skb_reset_mac_header(skb2); skb2->ip_summed = CHECKSUM_UNNECESSARY; skb2->pkt_type = PACKET_OTHERHOST; @@ -200,8 +192,8 @@ static netdev_tx_t wilc_wfi_mon_xmit(struct sk_buff *skb, } skb->dev = mon_priv->real_ndev; - memcpy(srcadd, &skb->data[10], 6); - memcpy(bssid, &skb->data[16], 6); + ether_addr_copy(srcadd, &skb->data[10]); + ether_addr_copy(bssid, &skb->data[16]); /* * Identify if data or mgmt packet, if source address and bssid * fields are equal send it to mgmt frames handler @@ -223,51 +215,44 @@ static const struct net_device_ops wilc_wfi_netdev_ops = { }; -struct net_device *wilc_wfi_init_mon_interface(const char *name, +struct net_device *wilc_wfi_init_mon_interface(struct wilc *wl, + const char *name, struct net_device *real_dev) { struct wilc_wfi_mon_priv *priv; /*If monitor interface is already initialized, return it*/ - if (wilc_wfi_mon) - return wilc_wfi_mon; + if (wl->monitor_dev) + return wl->monitor_dev; - wilc_wfi_mon = alloc_etherdev(sizeof(struct wilc_wfi_mon_priv)); - if (!wilc_wfi_mon) + wl->monitor_dev = alloc_etherdev(sizeof(struct wilc_wfi_mon_priv)); + if (!wl->monitor_dev) return NULL; - wilc_wfi_mon->type = ARPHRD_IEEE80211_RADIOTAP; - strncpy(wilc_wfi_mon->name, name, IFNAMSIZ); - wilc_wfi_mon->name[IFNAMSIZ - 1] = 0; - wilc_wfi_mon->netdev_ops = &wilc_wfi_netdev_ops; - if (register_netdevice(wilc_wfi_mon)) { + wl->monitor_dev->type = ARPHRD_IEEE80211_RADIOTAP; + strncpy(wl->monitor_dev->name, name, IFNAMSIZ); + wl->monitor_dev->name[IFNAMSIZ - 1] = 0; + wl->monitor_dev->netdev_ops = &wilc_wfi_netdev_ops; + + if (register_netdevice(wl->monitor_dev)) { netdev_err(real_dev, "register_netdevice failed\n"); return NULL; } - priv = netdev_priv(wilc_wfi_mon); + priv = netdev_priv(wl->monitor_dev); if (!priv) return NULL; priv->real_ndev = real_dev; - return wilc_wfi_mon; + return wl->monitor_dev; } -void wilc_wfi_deinit_mon_interface(void) +void wilc_wfi_deinit_mon_interface(struct wilc *wl) { - bool rollback_lock = false; - - if (wilc_wfi_mon) { - if (rtnl_is_locked()) { - rtnl_unlock(); - rollback_lock = true; - } - unregister_netdev(wilc_wfi_mon); + if (!wl->monitor_dev) + return; - if (rollback_lock) { - rtnl_lock(); - rollback_lock = false; - } - wilc_wfi_mon = NULL; - } + unregister_netdev(wl->monitor_dev); + free_netdev(wl->monitor_dev); + wl->monitor_dev = NULL; } diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/wilc_netdev.c index 721689048648..1787154ee088 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/wilc_netdev.c @@ -12,86 +12,7 @@ #include "wilc_wfi_cfgoperations.h" -static int dev_state_ev_handler(struct notifier_block *this, - unsigned long event, void *ptr) -{ - struct in_ifaddr *dev_iface = ptr; - struct wilc_priv *priv; - struct host_if_drv *hif_drv; - struct net_device *dev; - u8 *ip_addr_buf; - struct wilc_vif *vif; - u8 null_ip[4] = {0}; - char wlan_dev_name[5] = "wlan0"; - - if (!dev_iface || !dev_iface->ifa_dev || !dev_iface->ifa_dev->dev) - return NOTIFY_DONE; - - if (memcmp(dev_iface->ifa_label, "wlan0", 5) && - memcmp(dev_iface->ifa_label, "p2p0", 4)) - return NOTIFY_DONE; - - dev = (struct net_device *)dev_iface->ifa_dev->dev; - if (!dev->ieee80211_ptr || !dev->ieee80211_ptr->wiphy) - return NOTIFY_DONE; - - priv = wiphy_priv(dev->ieee80211_ptr->wiphy); - if (!priv) - return NOTIFY_DONE; - - hif_drv = (struct host_if_drv *)priv->hif_drv; - vif = netdev_priv(dev); - if (!vif || !hif_drv) - return NOTIFY_DONE; - - switch (event) { - case NETDEV_UP: - if (vif->iftype == WILC_STATION_MODE || - vif->iftype == WILC_CLIENT_MODE) { - hif_drv->ifc_up = 1; - vif->obtaining_ip = false; - del_timer(&vif->during_ip_timer); - } - - if (vif->wilc->enable_ps) - wilc_set_power_mgmt(vif, 1, 0); - - netdev_dbg(dev, "[%s] Up IP\n", dev_iface->ifa_label); - - ip_addr_buf = (char *)&dev_iface->ifa_address; - netdev_dbg(dev, "IP add=%d:%d:%d:%d\n", - ip_addr_buf[0], ip_addr_buf[1], - ip_addr_buf[2], ip_addr_buf[3]); - - break; - - case NETDEV_DOWN: - if (vif->iftype == WILC_STATION_MODE || - vif->iftype == WILC_CLIENT_MODE) { - hif_drv->ifc_up = 0; - vif->obtaining_ip = false; - } - - if (memcmp(dev_iface->ifa_label, wlan_dev_name, 5) == 0) - wilc_set_power_mgmt(vif, 0, 0); - - wilc_resolve_disconnect_aberration(vif); - - netdev_dbg(dev, "[%s] Down IP\n", dev_iface->ifa_label); - - ip_addr_buf = null_ip; - netdev_dbg(dev, "IP add=%d:%d:%d:%d\n", - ip_addr_buf[0], ip_addr_buf[1], - ip_addr_buf[2], ip_addr_buf[3]); - - break; - - default: - break; - } - - return NOTIFY_DONE; -} +#define WILC_MULTICAST_TABLE_SIZE 8 static irqreturn_t isr_uh_routine(int irq, void *user_data) { @@ -198,7 +119,11 @@ void wilc_wlan_set_bssid(struct net_device *wilc_netdev, u8 *bssid, u8 mode) { struct wilc_vif *vif = netdev_priv(wilc_netdev); - memcpy(vif->bssid, bssid, 6); + if (bssid) + ether_addr_copy(vif->bssid, bssid); + else + eth_zero_addr(vif->bssid); + vif->mode = mode; } @@ -214,7 +139,7 @@ int wilc_wlan_get_num_conn_ifcs(struct wilc *wilc) return ret_val; } -static int linux_wlan_txq_task(void *vp) +static int wilc_txq_task(void *vp) { int ret; u32 txq_count; @@ -236,9 +161,11 @@ static int linux_wlan_txq_task(void *vp) do { ret = wilc_wlan_handle_txq(dev, &txq_count); if (txq_count < FLOW_CONTROL_LOWER_THRESHOLD) { - if (netif_queue_stopped(wl->vif[0]->ndev)) + if (wl->vif[0]->mac_opened && + netif_queue_stopped(wl->vif[0]->ndev)) netif_wake_queue(wl->vif[0]->ndev); - if (netif_queue_stopped(wl->vif[1]->ndev)) + if (wl->vif[1]->mac_opened && + netif_queue_stopped(wl->vif[1]->ndev)) netif_wake_queue(wl->vif[1]->ndev); } } while (ret == -ENOBUFS && !wl->close); @@ -275,7 +202,7 @@ fail: return ret; } -static int linux_wlan_start_firmware(struct net_device *dev) +static int wilc_start_firmware(struct net_device *dev) { struct wilc_vif *vif = netdev_priv(dev); struct wilc *wilc = vif->wilc; @@ -316,204 +243,169 @@ static int wilc1000_firmware_download(struct net_device *dev) return 0; } -static int linux_wlan_init_test_config(struct net_device *dev, - struct wilc_vif *vif) +static int wilc_init_fw_config(struct net_device *dev, struct wilc_vif *vif) { - unsigned char c_val[64]; - struct wilc *wilc = vif->wilc; struct wilc_priv *priv; struct host_if_drv *hif_drv; + u8 b; + u16 hw; + u32 w; netdev_dbg(dev, "Start configuring Firmware\n"); priv = wiphy_priv(dev->ieee80211_ptr->wiphy); hif_drv = (struct host_if_drv *)priv->hif_drv; netdev_dbg(dev, "Host = %p\n", hif_drv); - wilc_get_chipid(wilc, false); - - *(int *)c_val = 1; - - if (!wilc_wlan_cfg_set(vif, 1, WID_SET_DRV_HANDLER, c_val, 4, 0, 0)) - goto fail; - - c_val[0] = 0; - if (!wilc_wlan_cfg_set(vif, 0, WID_PC_TEST_MODE, c_val, 1, 0, 0)) - goto fail; - c_val[0] = WILC_FW_BSS_TYPE_INFRA; - if (!wilc_wlan_cfg_set(vif, 0, WID_BSS_TYPE, c_val, 1, 0, 0)) - goto fail; - - c_val[0] = WILC_FW_TX_RATE_AUTO; - if (!wilc_wlan_cfg_set(vif, 0, WID_CURRENT_TX_RATE, c_val, 1, 0, 0)) - goto fail; - - c_val[0] = WILC_FW_OPER_MODE_G_MIXED_11B_2; - if (!wilc_wlan_cfg_set(vif, 0, WID_11G_OPERATING_MODE, c_val, 1, 0, - 0)) - goto fail; - - c_val[0] = 1; - if (!wilc_wlan_cfg_set(vif, 0, WID_CURRENT_CHANNEL, c_val, 1, 0, 0)) - goto fail; - - c_val[0] = WILC_FW_PREAMBLE_SHORT; - if (!wilc_wlan_cfg_set(vif, 0, WID_PREAMBLE, c_val, 1, 0, 0)) + w = vif->iftype; + cpu_to_le32s(&w); + if (!wilc_wlan_cfg_set(vif, 1, WID_SET_OPERATION_MODE, (u8 *)&w, 4, + 0, 0)) goto fail; - c_val[0] = WILC_FW_11N_PROT_AUTO; - if (!wilc_wlan_cfg_set(vif, 0, WID_11N_PROT_MECH, c_val, 1, 0, 0)) + b = WILC_FW_BSS_TYPE_INFRA; + if (!wilc_wlan_cfg_set(vif, 0, WID_BSS_TYPE, &b, 1, 0, 0)) goto fail; - c_val[0] = WILC_FW_ACTIVE_SCAN; - if (!wilc_wlan_cfg_set(vif, 0, WID_SCAN_TYPE, c_val, 1, 0, 0)) + b = WILC_FW_TX_RATE_AUTO; + if (!wilc_wlan_cfg_set(vif, 0, WID_CURRENT_TX_RATE, &b, 1, 0, 0)) goto fail; - c_val[0] = WILC_FW_SITE_SURVEY_OFF; - if (!wilc_wlan_cfg_set(vif, 0, WID_SITE_SURVEY, c_val, 1, 0, 0)) + b = WILC_FW_OPER_MODE_G_MIXED_11B_2; + if (!wilc_wlan_cfg_set(vif, 0, WID_11G_OPERATING_MODE, &b, 1, 0, 0)) goto fail; - *((int *)c_val) = 0xffff; - if (!wilc_wlan_cfg_set(vif, 0, WID_RTS_THRESHOLD, c_val, 2, 0, 0)) + b = WILC_FW_PREAMBLE_SHORT; + if (!wilc_wlan_cfg_set(vif, 0, WID_PREAMBLE, &b, 1, 0, 0)) goto fail; - *((int *)c_val) = 2346; - if (!wilc_wlan_cfg_set(vif, 0, WID_FRAG_THRESHOLD, c_val, 2, 0, 0)) + b = WILC_FW_11N_PROT_AUTO; + if (!wilc_wlan_cfg_set(vif, 0, WID_11N_PROT_MECH, &b, 1, 0, 0)) goto fail; - c_val[0] = 0; - if (!wilc_wlan_cfg_set(vif, 0, WID_BCAST_SSID, c_val, 1, 0, 0)) + b = WILC_FW_ACTIVE_SCAN; + if (!wilc_wlan_cfg_set(vif, 0, WID_SCAN_TYPE, &b, 1, 0, 0)) goto fail; - c_val[0] = 1; - if (!wilc_wlan_cfg_set(vif, 0, WID_QOS_ENABLE, c_val, 1, 0, 0)) + b = WILC_FW_SITE_SURVEY_OFF; + if (!wilc_wlan_cfg_set(vif, 0, WID_SITE_SURVEY, &b, 1, 0, 0)) goto fail; - c_val[0] = WILC_FW_NO_POWERSAVE; - if (!wilc_wlan_cfg_set(vif, 0, WID_POWER_MANAGEMENT, c_val, 1, 0, 0)) + hw = 0xffff; + cpu_to_le16s(&hw); + if (!wilc_wlan_cfg_set(vif, 0, WID_RTS_THRESHOLD, (u8 *)&hw, 2, 0, 0)) goto fail; - c_val[0] = WILC_FW_SEC_NO; - if (!wilc_wlan_cfg_set(vif, 0, WID_11I_MODE, c_val, 1, 0, 0)) + hw = 2346; + cpu_to_le16s(&hw); + if (!wilc_wlan_cfg_set(vif, 0, WID_FRAG_THRESHOLD, (u8 *)&hw, 2, 0, 0)) goto fail; - c_val[0] = WILC_FW_AUTH_OPEN_SYSTEM; - if (!wilc_wlan_cfg_set(vif, 0, WID_AUTH_TYPE, c_val, 1, 0, 0)) + b = 0; + if (!wilc_wlan_cfg_set(vif, 0, WID_BCAST_SSID, &b, 1, 0, 0)) goto fail; - strcpy(c_val, "123456790abcdef1234567890"); - if (!wilc_wlan_cfg_set(vif, 0, WID_WEP_KEY_VALUE, c_val, - (strlen(c_val) + 1), 0, 0)) + b = 1; + if (!wilc_wlan_cfg_set(vif, 0, WID_QOS_ENABLE, &b, 1, 0, 0)) goto fail; - strcpy(c_val, "12345678"); - if (!wilc_wlan_cfg_set(vif, 0, WID_11I_PSK, c_val, (strlen(c_val)), 0, - 0)) + b = WILC_FW_NO_POWERSAVE; + if (!wilc_wlan_cfg_set(vif, 0, WID_POWER_MANAGEMENT, &b, 1, 0, 0)) goto fail; - strcpy(c_val, "password"); - if (!wilc_wlan_cfg_set(vif, 0, WID_1X_KEY, c_val, (strlen(c_val) + 1), - 0, 0)) + b = WILC_FW_SEC_NO; + if (!wilc_wlan_cfg_set(vif, 0, WID_11I_MODE, &b, 1, 0, 0)) goto fail; - c_val[0] = 192; - c_val[1] = 168; - c_val[2] = 1; - c_val[3] = 112; - if (!wilc_wlan_cfg_set(vif, 0, WID_1X_SERV_ADDR, c_val, 4, 0, 0)) + b = WILC_FW_AUTH_OPEN_SYSTEM; + if (!wilc_wlan_cfg_set(vif, 0, WID_AUTH_TYPE, &b, 1, 0, 0)) goto fail; - c_val[0] = 3; - if (!wilc_wlan_cfg_set(vif, 0, WID_LISTEN_INTERVAL, c_val, 1, 0, 0)) + b = 3; + if (!wilc_wlan_cfg_set(vif, 0, WID_LISTEN_INTERVAL, &b, 1, 0, 0)) goto fail; - c_val[0] = 3; - if (!wilc_wlan_cfg_set(vif, 0, WID_DTIM_PERIOD, c_val, 1, 0, 0)) + b = 3; + if (!wilc_wlan_cfg_set(vif, 0, WID_DTIM_PERIOD, &b, 1, 0, 0)) goto fail; - c_val[0] = WILC_FW_ACK_POLICY_NORMAL; - if (!wilc_wlan_cfg_set(vif, 0, WID_ACK_POLICY, c_val, 1, 0, 0)) + b = WILC_FW_ACK_POLICY_NORMAL; + if (!wilc_wlan_cfg_set(vif, 0, WID_ACK_POLICY, &b, 1, 0, 0)) goto fail; - c_val[0] = 0; - if (!wilc_wlan_cfg_set(vif, 0, WID_USER_CONTROL_ON_TX_POWER, c_val, 1, + b = 0; + if (!wilc_wlan_cfg_set(vif, 0, WID_USER_CONTROL_ON_TX_POWER, &b, 1, 0, 0)) goto fail; - c_val[0] = 48; - if (!wilc_wlan_cfg_set(vif, 0, WID_TX_POWER_LEVEL_11A, c_val, 1, 0, - 0)) + b = 48; + if (!wilc_wlan_cfg_set(vif, 0, WID_TX_POWER_LEVEL_11A, &b, 1, 0, 0)) goto fail; - c_val[0] = 28; - if (!wilc_wlan_cfg_set(vif, 0, WID_TX_POWER_LEVEL_11B, c_val, 1, 0, - 0)) + b = 28; + if (!wilc_wlan_cfg_set(vif, 0, WID_TX_POWER_LEVEL_11B, &b, 1, 0, 0)) goto fail; - *((int *)c_val) = 100; - if (!wilc_wlan_cfg_set(vif, 0, WID_BEACON_INTERVAL, c_val, 2, 0, 0)) + hw = 100; + cpu_to_le16s(&hw); + if (!wilc_wlan_cfg_set(vif, 0, WID_BEACON_INTERVAL, (u8 *)&hw, 2, 0, 0)) goto fail; - c_val[0] = WILC_FW_REKEY_POLICY_DISABLE; - if (!wilc_wlan_cfg_set(vif, 0, WID_REKEY_POLICY, c_val, 1, 0, 0)) + b = WILC_FW_REKEY_POLICY_DISABLE; + if (!wilc_wlan_cfg_set(vif, 0, WID_REKEY_POLICY, &b, 1, 0, 0)) goto fail; - *((int *)c_val) = 84600; - if (!wilc_wlan_cfg_set(vif, 0, WID_REKEY_PERIOD, c_val, 4, 0, 0)) + w = 84600; + cpu_to_le32s(&w); + if (!wilc_wlan_cfg_set(vif, 0, WID_REKEY_PERIOD, (u8 *)&w, 4, 0, 0)) goto fail; - *((int *)c_val) = 500; - if (!wilc_wlan_cfg_set(vif, 0, WID_REKEY_PACKET_COUNT, c_val, 4, 0, + w = 500; + cpu_to_le32s(&w); + if (!wilc_wlan_cfg_set(vif, 0, WID_REKEY_PACKET_COUNT, (u8 *)&w, 4, 0, 0)) goto fail; - c_val[0] = 1; - if (!wilc_wlan_cfg_set(vif, 0, WID_SHORT_SLOT_ALLOWED, c_val, 1, 0, + b = 1; + if (!wilc_wlan_cfg_set(vif, 0, WID_SHORT_SLOT_ALLOWED, &b, 1, 0, 0)) goto fail; - c_val[0] = WILC_FW_ERP_PROT_SELF_CTS; - if (!wilc_wlan_cfg_set(vif, 0, WID_11N_ERP_PROT_TYPE, c_val, 1, 0, 0)) + b = WILC_FW_ERP_PROT_SELF_CTS; + if (!wilc_wlan_cfg_set(vif, 0, WID_11N_ERP_PROT_TYPE, &b, 1, 0, 0)) goto fail; - c_val[0] = 1; - if (!wilc_wlan_cfg_set(vif, 0, WID_11N_ENABLE, c_val, 1, 0, 0)) + b = 1; + if (!wilc_wlan_cfg_set(vif, 0, WID_11N_ENABLE, &b, 1, 0, 0)) goto fail; - c_val[0] = WILC_FW_11N_OP_MODE_HT_MIXED; - if (!wilc_wlan_cfg_set(vif, 0, WID_11N_OPERATING_MODE, c_val, 1, 0, - 0)) + b = WILC_FW_11N_OP_MODE_HT_MIXED; + if (!wilc_wlan_cfg_set(vif, 0, WID_11N_OPERATING_MODE, &b, 1, 0, 0)) goto fail; - c_val[0] = 1; - if (!wilc_wlan_cfg_set(vif, 0, WID_11N_TXOP_PROT_DISABLE, c_val, 1, 0, - 0)) + b = 1; + if (!wilc_wlan_cfg_set(vif, 0, WID_11N_TXOP_PROT_DISABLE, &b, 1, 0, 0)) goto fail; - c_val[0] = WILC_FW_OBBS_NONHT_DETECT_PROTECT_REPORT; - if (!wilc_wlan_cfg_set(vif, 0, WID_11N_OBSS_NONHT_DETECTION, c_val, 1, + b = WILC_FW_OBBS_NONHT_DETECT_PROTECT_REPORT; + if (!wilc_wlan_cfg_set(vif, 0, WID_11N_OBSS_NONHT_DETECTION, &b, 1, 0, 0)) goto fail; - c_val[0] = WILC_FW_HT_PROT_RTS_CTS_NONHT; - if (!wilc_wlan_cfg_set(vif, 0, WID_11N_HT_PROT_TYPE, c_val, 1, 0, 0)) + b = WILC_FW_HT_PROT_RTS_CTS_NONHT; + if (!wilc_wlan_cfg_set(vif, 0, WID_11N_HT_PROT_TYPE, &b, 1, 0, 0)) goto fail; - c_val[0] = 0; - if (!wilc_wlan_cfg_set(vif, 0, WID_11N_RIFS_PROT_ENABLE, c_val, 1, 0, + b = 0; + if (!wilc_wlan_cfg_set(vif, 0, WID_11N_RIFS_PROT_ENABLE, &b, 1, 0, 0)) goto fail; - c_val[0] = WILC_FW_SMPS_MODE_MIMO; - if (!wilc_wlan_cfg_set(vif, 0, WID_11N_SMPS_MODE, c_val, 1, 0, 0)) - goto fail; - - c_val[0] = 7; - if (!wilc_wlan_cfg_set(vif, 0, WID_11N_CURRENT_TX_MCS, c_val, 1, 0, - 0)) + b = 7; + if (!wilc_wlan_cfg_set(vif, 0, WID_11N_CURRENT_TX_MCS, &b, 1, 0, 0)) goto fail; - c_val[0] = 1; - if (!wilc_wlan_cfg_set(vif, 0, WID_11N_IMMEDIATE_BA_ENABLED, c_val, 1, + b = 1; + if (!wilc_wlan_cfg_set(vif, 0, WID_11N_IMMEDIATE_BA_ENABLED, &b, 1, 1, 1)) goto fail; @@ -609,7 +501,7 @@ static int wlan_initialize_threads(struct net_device *dev) struct wilc_vif *vif = netdev_priv(dev); struct wilc *wilc = vif->wilc; - wilc->txq_thread = kthread_run(linux_wlan_txq_task, (void *)dev, + wilc->txq_thread = kthread_run(wilc_txq_task, (void *)dev, "K_TXQ_TASK"); if (IS_ERR(wilc->txq_thread)) { netdev_err(dev, "couldn't create TXQ thread\n"); @@ -667,7 +559,7 @@ static int wilc_wlan_initialize(struct net_device *dev, struct wilc_vif *vif) goto fail_irq_enable; } - ret = linux_wlan_start_firmware(dev); + ret = wilc_start_firmware(dev); if (ret < 0) { ret = -EIO; goto fail_irq_enable; @@ -683,7 +575,7 @@ static int wilc_wlan_initialize(struct net_device *dev, struct wilc_vif *vif) firmware_ver[size] = '\0'; netdev_dbg(dev, "Firmware Ver = %s\n", firmware_ver); } - ret = linux_wlan_init_test_config(dev, vif); + ret = wilc_init_fw_config(dev, vif); if (ret < 0) { netdev_err(dev, "Failed to configure firmware\n"); @@ -807,12 +699,12 @@ static void wilc_set_multicast_list(struct net_device *dev) if (dev->flags & IFF_ALLMULTI || dev->mc.count > WILC_MULTICAST_TABLE_SIZE) { - wilc_setup_multicast_filter(vif, false, 0, NULL); + wilc_setup_multicast_filter(vif, 0, 0, NULL); return; } if (dev->mc.count == 0) { - wilc_setup_multicast_filter(vif, true, 0, NULL); + wilc_setup_multicast_filter(vif, 1, 0, NULL); return; } @@ -829,11 +721,11 @@ static void wilc_set_multicast_list(struct net_device *dev) cur_mc += ETH_ALEN; } - if (wilc_setup_multicast_filter(vif, true, dev->mc.count, mc_list)) + if (wilc_setup_multicast_filter(vif, 1, dev->mc.count, mc_list)) kfree(mc_list); } -static void linux_wlan_tx_complete(void *priv, int status) +static void wilc_tx_complete(void *priv, int status) { struct tx_complete_data *pv_data = priv; @@ -847,9 +739,6 @@ netdev_tx_t wilc_mac_xmit(struct sk_buff *skb, struct net_device *ndev) struct wilc *wilc = vif->wilc; struct tx_complete_data *tx_data = NULL; int queue_count; - char *udp_buf; - struct iphdr *ih; - struct ethhdr *eth_h; if (skb->dev != ndev) { netdev_err(ndev, "Packet not destined to this device\n"); @@ -867,28 +756,18 @@ netdev_tx_t wilc_mac_xmit(struct sk_buff *skb, struct net_device *ndev) tx_data->size = skb->len; tx_data->skb = skb; - eth_h = (struct ethhdr *)(skb->data); - if (eth_h->h_proto == cpu_to_be16(0x8e88)) - netdev_dbg(ndev, "EAPOL transmitted\n"); - - ih = (struct iphdr *)(skb->data + sizeof(struct ethhdr)); - - udp_buf = (char *)ih + sizeof(struct iphdr); - if ((udp_buf[1] == 68 && udp_buf[3] == 67) || - (udp_buf[1] == 67 && udp_buf[3] == 68)) - netdev_dbg(ndev, "DHCP Message transmitted, type:%x %x %x\n", - udp_buf[248], udp_buf[249], udp_buf[250]); - vif->netstats.tx_packets++; vif->netstats.tx_bytes += tx_data->size; tx_data->bssid = wilc->vif[vif->idx]->bssid; queue_count = wilc_wlan_txq_add_net_pkt(ndev, (void *)tx_data, tx_data->buff, tx_data->size, - linux_wlan_tx_complete); + wilc_tx_complete); if (queue_count > FLOW_CONTROL_UPPER_THRESHOLD) { - netif_stop_queue(wilc->vif[0]->ndev); - netif_stop_queue(wilc->vif[1]->ndev); + if (wilc->vif[0]->mac_opened) + netif_stop_queue(wilc->vif[0]->ndev); + if (wilc->vif[1]->mac_opened) + netif_stop_queue(wilc->vif[1]->ndev); } return 0; @@ -916,7 +795,6 @@ static int wilc_mac_close(struct net_device *ndev) netdev_dbg(ndev, "Deinitializing wilc1000\n"); wl->close = 1; wilc_wlan_deinitialize(ndev); - wilc_wfi_deinit_mon_interface(); } vif->mac_opened = 0; @@ -924,7 +802,8 @@ static int wilc_mac_close(struct net_device *ndev) return 0; } -void wilc_frmw_to_linux(struct wilc *wilc, u8 *buff, u32 size, u32 pkt_offset) +void wilc_frmw_to_host(struct wilc *wilc, u8 *buff, u32 size, + u32 pkt_offset) { unsigned int frame_len = 0; int stats; @@ -972,7 +851,7 @@ void wilc_wfi_mgmt_rx(struct wilc *wilc, u8 *buff, u32 size) for (i = 0; i < wilc->vif_num; i++) { vif = netdev_priv(wilc->vif[i]->ndev); if (vif->monitor_flag) { - wilc_wfi_monitor_rx(buff, size); + wilc_wfi_monitor_rx(wilc->monitor_dev, buff, size); return; } } @@ -983,6 +862,76 @@ void wilc_wfi_mgmt_rx(struct wilc *wilc, u8 *buff, u32 size) wilc_wfi_p2p_rx(wilc->vif[1]->ndev, buff, size); } +static const struct net_device_ops wilc_netdev_ops = { + .ndo_init = mac_init_fn, + .ndo_open = wilc_mac_open, + .ndo_stop = wilc_mac_close, + .ndo_start_xmit = wilc_mac_xmit, + .ndo_get_stats = mac_stats, + .ndo_set_rx_mode = wilc_set_multicast_list, +}; + +static int dev_state_ev_handler(struct notifier_block *this, + unsigned long event, void *ptr) +{ + struct in_ifaddr *dev_iface = ptr; + struct wilc_priv *priv; + struct host_if_drv *hif_drv; + struct net_device *dev; + struct wilc_vif *vif; + + if (!dev_iface || !dev_iface->ifa_dev || !dev_iface->ifa_dev->dev) + return NOTIFY_DONE; + + dev = (struct net_device *)dev_iface->ifa_dev->dev; + if (dev->netdev_ops != &wilc_netdev_ops) + return NOTIFY_DONE; + + if (!dev->ieee80211_ptr || !dev->ieee80211_ptr->wiphy) + return NOTIFY_DONE; + + priv = wiphy_priv(dev->ieee80211_ptr->wiphy); + if (!priv) + return NOTIFY_DONE; + + hif_drv = (struct host_if_drv *)priv->hif_drv; + vif = netdev_priv(dev); + if (!vif || !hif_drv) + return NOTIFY_DONE; + + switch (event) { + case NETDEV_UP: + if (vif->iftype == WILC_STATION_MODE || + vif->iftype == WILC_CLIENT_MODE) { + hif_drv->ifc_up = 1; + vif->obtaining_ip = false; + del_timer(&vif->during_ip_timer); + } + + if (vif->wilc->enable_ps) + wilc_set_power_mgmt(vif, 1, 0); + + break; + + case NETDEV_DOWN: + if (vif->iftype == WILC_STATION_MODE || + vif->iftype == WILC_CLIENT_MODE) { + hif_drv->ifc_up = 0; + vif->obtaining_ip = false; + wilc_set_power_mgmt(vif, 0, 0); + } + + wilc_resolve_disconnect_aberration(vif); + + break; + + default: + break; + } + + return NOTIFY_DONE; +} + static struct notifier_block g_dev_notifier = { .notifier_call = dev_state_ev_handler }; @@ -1002,19 +951,15 @@ void wilc_netdev_cleanup(struct wilc *wilc) wilc->firmware = NULL; } - if (wilc->vif[0]->ndev || wilc->vif[1]->ndev) { - for (i = 0; i < WILC_NUM_CONCURRENT_IFC; i++) - if (wilc->vif[i]->ndev) - if (wilc->vif[i]->mac_opened) - wilc_mac_close(wilc->vif[i]->ndev); - - for (i = 0; i < WILC_NUM_CONCURRENT_IFC; i++) { + for (i = 0; i < WILC_NUM_CONCURRENT_IFC; i++) { + if (wilc->vif[i] && wilc->vif[i]->ndev) { unregister_netdev(wilc->vif[i]->ndev); wilc_free_wiphy(wilc->vif[i]->ndev); free_netdev(wilc->vif[i]->ndev); } } + wilc_wfi_deinit_mon_interface(wilc); flush_workqueue(wilc->hif_workqueue); destroy_workqueue(wilc->hif_workqueue); wilc_wlan_cfg_deinit(wilc); @@ -1023,15 +968,6 @@ void wilc_netdev_cleanup(struct wilc *wilc) } EXPORT_SYMBOL_GPL(wilc_netdev_cleanup); -static const struct net_device_ops wilc_netdev_ops = { - .ndo_init = mac_init_fn, - .ndo_open = wilc_mac_open, - .ndo_stop = wilc_mac_close, - .ndo_start_xmit = wilc_mac_xmit, - .ndo_get_stats = mac_stats, - .ndo_set_rx_mode = wilc_set_multicast_list, -}; - int wilc_netdev_init(struct wilc **wilc, struct device *dev, int io_type, const struct wilc_hif_func *ops) { @@ -1086,8 +1022,8 @@ int wilc_netdev_init(struct wilc **wilc, struct device *dev, int io_type, vif->wilc = *wilc; vif->ndev = ndev; wl->vif[i] = vif; - wl->vif_num = i; - vif->idx = wl->vif_num; + wl->vif_num = i + 1; + vif->idx = i; ndev->netdev_ops = &wilc_netdev_ops; diff --git a/drivers/staging/wilc1000/wilc_sdio.c b/drivers/staging/wilc1000/wilc_sdio.c index e2f739fef21c..b789c57d7e80 100644 --- a/drivers/staging/wilc1000/wilc_sdio.c +++ b/drivers/staging/wilc1000/wilc_sdio.c @@ -51,10 +51,6 @@ struct sdio_cmd53 { static const struct wilc_hif_func wilc_hif_sdio; -static int sdio_write_reg(struct wilc *wilc, u32 addr, u32 data); -static int sdio_read_reg(struct wilc *wilc, u32 addr, u32 *data); -static int sdio_init(struct wilc *wilc, bool resume); - static void wilc_sdio_interrupt(struct sdio_func *func) { sdio_release_host(func); @@ -121,8 +117,8 @@ static int wilc_sdio_cmd53(struct wilc *wilc, struct sdio_cmd53 *cmd) return ret; } -static int linux_sdio_probe(struct sdio_func *func, - const struct sdio_device_id *id) +static int wilc_sdio_probe(struct sdio_func *func, + const struct sdio_device_id *id) { struct wilc *wilc; int ret; @@ -160,7 +156,7 @@ static int linux_sdio_probe(struct sdio_func *func, return 0; } -static void linux_sdio_remove(struct sdio_func *func) +static void wilc_sdio_remove(struct sdio_func *func) { struct wilc *wilc = sdio_get_drvdata(func); @@ -170,7 +166,7 @@ static void linux_sdio_remove(struct sdio_func *func) wilc_netdev_cleanup(wilc); } -static int sdio_reset(struct wilc *wilc) +static int wilc_sdio_reset(struct wilc *wilc) { struct sdio_cmd52 cmd; int ret; @@ -205,7 +201,7 @@ static int wilc_sdio_suspend(struct device *dev) chip_allow_sleep(wilc); } - ret = sdio_reset(wilc); + ret = wilc_sdio_reset(wilc); if (ret) { dev_err(&func->dev, "Fail reset sdio\n"); return ret; @@ -215,50 +211,6 @@ static int wilc_sdio_suspend(struct device *dev) return 0; } -static int wilc_sdio_resume(struct device *dev) -{ - struct sdio_func *func = dev_to_sdio_func(dev); - struct wilc *wilc = sdio_get_drvdata(func); - - dev_info(dev, "sdio resume\n"); - sdio_release_host(func); - chip_wakeup(wilc); - sdio_init(wilc, true); - - if (wilc->suspend_event) - host_wakeup_notify(wilc); - - chip_allow_sleep(wilc); - - return 0; -} - -static const struct of_device_id wilc_of_match[] = { - { .compatible = "microchip,wilc1000-sdio", }, - { /* sentinel */ } -}; -MODULE_DEVICE_TABLE(of, wilc_of_match); - -static const struct dev_pm_ops wilc_sdio_pm_ops = { - .suspend = wilc_sdio_suspend, - .resume = wilc_sdio_resume, -}; - -static struct sdio_driver wilc_sdio_driver = { - .name = SDIO_MODALIAS, - .id_table = wilc_sdio_ids, - .probe = linux_sdio_probe, - .remove = linux_sdio_remove, - .drv = { - .pm = &wilc_sdio_pm_ops, - .of_match_table = wilc_of_match, - } -}; -module_driver(wilc_sdio_driver, - sdio_register_driver, - sdio_unregister_driver); -MODULE_LICENSE("GPL"); - static int wilc_sdio_enable_interrupt(struct wilc *dev) { struct sdio_func *func = container_of(dev->dev, struct sdio_func, dev); @@ -293,7 +245,7 @@ static void wilc_sdio_disable_interrupt(struct wilc *dev) * ********************************************/ -static int sdio_set_func0_csa_address(struct wilc *wilc, u32 adr) +static int wilc_sdio_set_func0_csa_address(struct wilc *wilc, u32 adr) { struct sdio_func *func = dev_to_sdio_func(wilc->dev); struct sdio_cmd52 cmd; @@ -334,7 +286,7 @@ fail: return 0; } -static int sdio_set_func0_block_size(struct wilc *wilc, u32 block_size) +static int wilc_sdio_set_func0_block_size(struct wilc *wilc, u32 block_size) { struct sdio_func *func = dev_to_sdio_func(wilc->dev); struct sdio_cmd52 cmd; @@ -370,7 +322,7 @@ fail: * ********************************************/ -static int sdio_set_func1_block_size(struct wilc *wilc, u32 block_size) +static int wilc_sdio_set_func1_block_size(struct wilc *wilc, u32 block_size) { struct sdio_func *func = dev_to_sdio_func(wilc->dev); struct sdio_cmd52 cmd; @@ -404,7 +356,7 @@ fail: * Sdio interfaces * ********************************************/ -static int sdio_write_reg(struct wilc *wilc, u32 addr, u32 data) +static int wilc_sdio_write_reg(struct wilc *wilc, u32 addr, u32 data) { struct sdio_func *func = dev_to_sdio_func(wilc->dev); struct wilc_sdio *sdio_priv = wilc->bus_data; @@ -432,7 +384,7 @@ static int sdio_write_reg(struct wilc *wilc, u32 addr, u32 data) /** * set the AHB address **/ - if (!sdio_set_func0_csa_address(wilc, addr)) + if (!wilc_sdio_set_func0_csa_address(wilc, addr)) goto fail; cmd.read_write = 1; @@ -458,7 +410,7 @@ fail: return 0; } -static int sdio_write(struct wilc *wilc, u32 addr, u8 *buf, u32 size) +static int wilc_sdio_write(struct wilc *wilc, u32 addr, u8 *buf, u32 size) { struct sdio_func *func = dev_to_sdio_func(wilc->dev); struct wilc_sdio *sdio_priv = wilc->bus_data; @@ -507,7 +459,7 @@ static int sdio_write(struct wilc *wilc, u32 addr, u8 *buf, u32 size) cmd.buffer = buf; cmd.block_size = block_size; if (addr > 0) { - if (!sdio_set_func0_csa_address(wilc, addr)) + if (!wilc_sdio_set_func0_csa_address(wilc, addr)) goto fail; } ret = wilc_sdio_cmd53(wilc, &cmd); @@ -530,7 +482,7 @@ static int sdio_write(struct wilc *wilc, u32 addr, u8 *buf, u32 size) cmd.block_size = block_size; if (addr > 0) { - if (!sdio_set_func0_csa_address(wilc, addr)) + if (!wilc_sdio_set_func0_csa_address(wilc, addr)) goto fail; } ret = wilc_sdio_cmd53(wilc, &cmd); @@ -548,7 +500,7 @@ fail: return 0; } -static int sdio_read_reg(struct wilc *wilc, u32 addr, u32 *data) +static int wilc_sdio_read_reg(struct wilc *wilc, u32 addr, u32 *data) { struct sdio_func *func = dev_to_sdio_func(wilc->dev); struct wilc_sdio *sdio_priv = wilc->bus_data; @@ -571,7 +523,7 @@ static int sdio_read_reg(struct wilc *wilc, u32 addr, u32 *data) } else { struct sdio_cmd53 cmd; - if (!sdio_set_func0_csa_address(wilc, addr)) + if (!wilc_sdio_set_func0_csa_address(wilc, addr)) goto fail; cmd.read_write = 0; @@ -600,7 +552,7 @@ fail: return 0; } -static int sdio_read(struct wilc *wilc, u32 addr, u8 *buf, u32 size) +static int wilc_sdio_read(struct wilc *wilc, u32 addr, u8 *buf, u32 size) { struct sdio_func *func = dev_to_sdio_func(wilc->dev); struct wilc_sdio *sdio_priv = wilc->bus_data; @@ -649,7 +601,7 @@ static int sdio_read(struct wilc *wilc, u32 addr, u8 *buf, u32 size) cmd.buffer = buf; cmd.block_size = block_size; if (addr > 0) { - if (!sdio_set_func0_csa_address(wilc, addr)) + if (!wilc_sdio_set_func0_csa_address(wilc, addr)) goto fail; } ret = wilc_sdio_cmd53(wilc, &cmd); @@ -672,7 +624,7 @@ static int sdio_read(struct wilc *wilc, u32 addr, u8 *buf, u32 size) cmd.block_size = block_size; if (addr > 0) { - if (!sdio_set_func0_csa_address(wilc, addr)) + if (!wilc_sdio_set_func0_csa_address(wilc, addr)) goto fail; } ret = wilc_sdio_cmd53(wilc, &cmd); @@ -696,12 +648,12 @@ fail: * ********************************************/ -static int sdio_deinit(struct wilc *wilc) +static int wilc_sdio_deinit(struct wilc *wilc) { return 1; } -static int sdio_init(struct wilc *wilc, bool resume) +static int wilc_sdio_init(struct wilc *wilc, bool resume) { struct sdio_func *func = dev_to_sdio_func(wilc->dev); struct wilc_sdio *sdio_priv = wilc->bus_data; @@ -729,7 +681,7 @@ static int sdio_init(struct wilc *wilc, bool resume) /** * function 0 block size **/ - if (!sdio_set_func0_block_size(wilc, WILC_SDIO_BLOCK_SIZE)) { + if (!wilc_sdio_set_func0_block_size(wilc, WILC_SDIO_BLOCK_SIZE)) { dev_err(&func->dev, "Fail cmd 52, set func 0 block size...\n"); goto fail; } @@ -778,7 +730,7 @@ static int sdio_init(struct wilc *wilc, bool resume) /** * func 1 is ready, set func 1 block size **/ - if (!sdio_set_func1_block_size(wilc, WILC_SDIO_BLOCK_SIZE)) { + if (!wilc_sdio_set_func1_block_size(wilc, WILC_SDIO_BLOCK_SIZE)) { dev_err(&func->dev, "Fail set func 1 block size...\n"); goto fail; } @@ -801,7 +753,7 @@ static int sdio_init(struct wilc *wilc, bool resume) * make sure can read back chip id correctly **/ if (!resume) { - if (!sdio_read_reg(wilc, 0x1000, &chipid)) { + if (!wilc_sdio_read_reg(wilc, 0x1000, &chipid)) { dev_err(&func->dev, "Fail cmd read chip id...\n"); goto fail; } @@ -821,7 +773,7 @@ fail: return 0; } -static int sdio_read_size(struct wilc *wilc, u32 *size) +static int wilc_sdio_read_size(struct wilc *wilc, u32 *size) { u32 tmp; struct sdio_cmd52 cmd; @@ -846,14 +798,14 @@ static int sdio_read_size(struct wilc *wilc, u32 *size) return 1; } -static int sdio_read_int(struct wilc *wilc, u32 *int_status) +static int wilc_sdio_read_int(struct wilc *wilc, u32 *int_status) { struct sdio_func *func = dev_to_sdio_func(wilc->dev); struct wilc_sdio *sdio_priv = wilc->bus_data; u32 tmp; struct sdio_cmd52 cmd; - sdio_read_size(wilc, &tmp); + wilc_sdio_read_size(wilc, &tmp); /** * Read IRQ flags @@ -905,7 +857,7 @@ static int sdio_read_int(struct wilc *wilc, u32 *int_status) return 1; } -static int sdio_clear_int_ext(struct wilc *wilc, u32 val) +static int wilc_sdio_clear_int_ext(struct wilc *wilc, u32 val) { struct sdio_func *func = dev_to_sdio_func(wilc->dev); struct wilc_sdio *sdio_priv = wilc->bus_data; @@ -1030,7 +982,7 @@ fail: return 0; } -static int sdio_sync_ext(struct wilc *wilc, int nint) +static int wilc_sdio_sync_ext(struct wilc *wilc, int nint) { struct sdio_func *func = dev_to_sdio_func(wilc->dev); struct wilc_sdio *sdio_priv = wilc->bus_data; @@ -1051,13 +1003,13 @@ static int sdio_sync_ext(struct wilc *wilc, int nint) /** * Disable power sequencer **/ - if (!sdio_read_reg(wilc, WILC_MISC, ®)) { + if (!wilc_sdio_read_reg(wilc, WILC_MISC, ®)) { dev_err(&func->dev, "Failed read misc reg...\n"); return 0; } reg &= ~BIT(8); - if (!sdio_write_reg(wilc, WILC_MISC, reg)) { + if (!wilc_sdio_write_reg(wilc, WILC_MISC, reg)) { dev_err(&func->dev, "Failed write misc reg...\n"); return 0; } @@ -1069,14 +1021,14 @@ static int sdio_sync_ext(struct wilc *wilc, int nint) /** * interrupt pin mux select **/ - ret = sdio_read_reg(wilc, WILC_PIN_MUX_0, ®); + ret = wilc_sdio_read_reg(wilc, WILC_PIN_MUX_0, ®); if (!ret) { dev_err(&func->dev, "Failed read reg (%08x)...\n", WILC_PIN_MUX_0); return 0; } reg |= BIT(8); - ret = sdio_write_reg(wilc, WILC_PIN_MUX_0, reg); + ret = wilc_sdio_write_reg(wilc, WILC_PIN_MUX_0, reg); if (!ret) { dev_err(&func->dev, "Failed write reg (%08x)...\n", WILC_PIN_MUX_0); @@ -1086,7 +1038,7 @@ static int sdio_sync_ext(struct wilc *wilc, int nint) /** * interrupt enable **/ - ret = sdio_read_reg(wilc, WILC_INTR_ENABLE, ®); + ret = wilc_sdio_read_reg(wilc, WILC_INTR_ENABLE, ®); if (!ret) { dev_err(&func->dev, "Failed read reg (%08x)...\n", WILC_INTR_ENABLE); @@ -1095,14 +1047,14 @@ static int sdio_sync_ext(struct wilc *wilc, int nint) for (i = 0; (i < 5) && (nint > 0); i++, nint--) reg |= BIT((27 + i)); - ret = sdio_write_reg(wilc, WILC_INTR_ENABLE, reg); + ret = wilc_sdio_write_reg(wilc, WILC_INTR_ENABLE, reg); if (!ret) { dev_err(&func->dev, "Failed write reg (%08x)...\n", WILC_INTR_ENABLE); return 0; } if (nint) { - ret = sdio_read_reg(wilc, WILC_INTR2_ENABLE, ®); + ret = wilc_sdio_read_reg(wilc, WILC_INTR2_ENABLE, ®); if (!ret) { dev_err(&func->dev, "Failed read reg (%08x)...\n", @@ -1113,7 +1065,7 @@ static int sdio_sync_ext(struct wilc *wilc, int nint) for (i = 0; (i < 3) && (nint > 0); i++, nint--) reg |= BIT(i); - ret = sdio_read_reg(wilc, WILC_INTR2_ENABLE, ®); + ret = wilc_sdio_read_reg(wilc, WILC_INTR2_ENABLE, ®); if (!ret) { dev_err(&func->dev, "Failed write reg (%08x)...\n", @@ -1127,19 +1079,62 @@ static int sdio_sync_ext(struct wilc *wilc, int nint) /* Global sdio HIF function table */ static const struct wilc_hif_func wilc_hif_sdio = { - .hif_init = sdio_init, - .hif_deinit = sdio_deinit, - .hif_read_reg = sdio_read_reg, - .hif_write_reg = sdio_write_reg, - .hif_block_rx = sdio_read, - .hif_block_tx = sdio_write, - .hif_read_int = sdio_read_int, - .hif_clear_int_ext = sdio_clear_int_ext, - .hif_read_size = sdio_read_size, - .hif_block_tx_ext = sdio_write, - .hif_block_rx_ext = sdio_read, - .hif_sync_ext = sdio_sync_ext, + .hif_init = wilc_sdio_init, + .hif_deinit = wilc_sdio_deinit, + .hif_read_reg = wilc_sdio_read_reg, + .hif_write_reg = wilc_sdio_write_reg, + .hif_block_rx = wilc_sdio_read, + .hif_block_tx = wilc_sdio_write, + .hif_read_int = wilc_sdio_read_int, + .hif_clear_int_ext = wilc_sdio_clear_int_ext, + .hif_read_size = wilc_sdio_read_size, + .hif_block_tx_ext = wilc_sdio_write, + .hif_block_rx_ext = wilc_sdio_read, + .hif_sync_ext = wilc_sdio_sync_ext, .enable_interrupt = wilc_sdio_enable_interrupt, .disable_interrupt = wilc_sdio_disable_interrupt, }; +static int wilc_sdio_resume(struct device *dev) +{ + struct sdio_func *func = dev_to_sdio_func(dev); + struct wilc *wilc = sdio_get_drvdata(func); + + dev_info(dev, "sdio resume\n"); + sdio_release_host(func); + chip_wakeup(wilc); + wilc_sdio_init(wilc, true); + + if (wilc->suspend_event) + host_wakeup_notify(wilc); + + chip_allow_sleep(wilc); + + return 0; +} + +static const struct of_device_id wilc_of_match[] = { + { .compatible = "microchip,wilc1000-sdio", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, wilc_of_match); + +static const struct dev_pm_ops wilc_sdio_pm_ops = { + .suspend = wilc_sdio_suspend, + .resume = wilc_sdio_resume, +}; + +static struct sdio_driver wilc_sdio_driver = { + .name = SDIO_MODALIAS, + .id_table = wilc_sdio_ids, + .probe = wilc_sdio_probe, + .remove = wilc_sdio_remove, + .drv = { + .pm = &wilc_sdio_pm_ops, + .of_match_table = wilc_of_match, + } +}; +module_driver(wilc_sdio_driver, + sdio_register_driver, + sdio_unregister_driver); +MODULE_LICENSE("GPL"); diff --git a/drivers/staging/wilc1000/wilc_spi.c b/drivers/staging/wilc1000/wilc_spi.c index 153e120eff00..4a1be9e60d74 100644 --- a/drivers/staging/wilc1000/wilc_spi.c +++ b/drivers/staging/wilc1000/wilc_spi.c @@ -814,7 +814,7 @@ static int wilc_spi_read(struct wilc *wilc, u32 addr, u8 *buf, u32 size) * ********************************************/ -static int _wilc_spi_deinit(struct wilc *wilc) +static int wilc_spi_deinit(struct wilc *wilc) { /* * TODO: @@ -1122,7 +1122,7 @@ static int wilc_spi_sync_ext(struct wilc *wilc, int nint) /* Global spi HIF function table */ static const struct wilc_hif_func wilc_hif_spi = { .hif_init = wilc_spi_init, - .hif_deinit = _wilc_spi_deinit, + .hif_deinit = wilc_spi_deinit, .hif_read_reg = wilc_spi_read_reg, .hif_write_reg = wilc_spi_write_reg, .hif_block_rx = wilc_spi_read, diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index ac47dda510e0..5e7a4676324e 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -27,10 +27,7 @@ #define GAS_INITIAL_REQ 0x0a #define GAS_INITIAL_RSP 0x0b -#define INVALID_CHANNEL 0 - -#define nl80211_SCAN_RESULT_EXPIRE (3 * HZ) -#define SCAN_RESULT_EXPIRE (40 * HZ) +#define WILC_INVALID_CHANNEL 0 static const struct ieee80211_txrx_stypes wilc_wfi_cfg80211_mgmt_types[NUM_NL80211_IFTYPES] = { @@ -65,124 +62,15 @@ static const struct wiphy_wowlan_support wowlan_support = { .flags = WIPHY_WOWLAN_ANY }; -struct p2p_mgmt_data { +struct wilc_p2p_mgmt_data { int size; u8 *buff; }; -static u8 wlan_channel = INVALID_CHANNEL; -static u8 curr_channel; -static u8 p2p_oui[] = {0x50, 0x6f, 0x9A, 0x09}; -static u8 p2p_vendor_spec[] = {0xdd, 0x05, 0x00, 0x08, 0x40, 0x03}; - -#define AGING_TIME (9 * 1000) -#define DURING_IP_TIME_OUT 15000 - -static void clear_shadow_scan(struct wilc_priv *priv) -{ - int i; - - for (i = 0; i < priv->scanned_cnt; i++) { - kfree(priv->scanned_shadow[i].ies); - priv->scanned_shadow[i].ies = NULL; - - kfree(priv->scanned_shadow[i].join_params); - priv->scanned_shadow[i].join_params = NULL; - } - priv->scanned_cnt = 0; -} - -static u32 get_rssi_avg(struct network_info *network_info) -{ - u8 i; - int rssi_v = 0; - u8 num_rssi = (network_info->rssi_history.full) ? - NUM_RSSI : (network_info->rssi_history.index); - - for (i = 0; i < num_rssi; i++) - rssi_v += network_info->rssi_history.samples[i]; - - rssi_v /= num_rssi; - return rssi_v; -} - -static void refresh_scan(struct wilc_priv *priv, bool direct_scan) -{ - struct wiphy *wiphy = priv->dev->ieee80211_ptr->wiphy; - int i; - - for (i = 0; i < priv->scanned_cnt; i++) { - struct network_info *network_info; - s32 freq; - struct ieee80211_channel *channel; - int rssi; - struct cfg80211_bss *bss; - - network_info = &priv->scanned_shadow[i]; - - if (!memcmp("DIRECT-", network_info->ssid, 7) && !direct_scan) - continue; - - freq = ieee80211_channel_to_frequency((s32)network_info->ch, - NL80211_BAND_2GHZ); - channel = ieee80211_get_channel(wiphy, freq); - rssi = get_rssi_avg(network_info); - bss = cfg80211_inform_bss(wiphy, - channel, - CFG80211_BSS_FTYPE_UNKNOWN, - network_info->bssid, - network_info->tsf, - network_info->cap_info, - network_info->beacon_period, - (const u8 *)network_info->ies, - (size_t)network_info->ies_len, - (s32)rssi * 100, - GFP_KERNEL); - cfg80211_put_bss(wiphy, bss); - } -} - -static void reset_shadow_found(struct wilc_priv *priv) -{ - int i; - - for (i = 0; i < priv->scanned_cnt; i++) - priv->scanned_shadow[i].found = 0; -} - -static void update_scan_time(struct wilc_priv *priv) -{ - int i; - - for (i = 0; i < priv->scanned_cnt; i++) - priv->scanned_shadow[i].time_scan = jiffies; -} - -static void remove_network_from_shadow(struct timer_list *t) -{ - struct wilc_priv *priv = from_timer(priv, t, aging_timer); - unsigned long now = jiffies; - int i, j; - - for (i = 0; i < priv->scanned_cnt; i++) { - if (!time_after(now, priv->scanned_shadow[i].time_scan + - (unsigned long)(SCAN_RESULT_EXPIRE))) - continue; - kfree(priv->scanned_shadow[i].ies); - priv->scanned_shadow[i].ies = NULL; - - kfree(priv->scanned_shadow[i].join_params); +static const u8 p2p_oui[] = {0x50, 0x6f, 0x9A, 0x09}; +static const u8 p2p_vendor_spec[] = {0xdd, 0x05, 0x00, 0x08, 0x40, 0x03}; - for (j = i; (j < priv->scanned_cnt - 1); j++) - priv->scanned_shadow[j] = priv->scanned_shadow[j + 1]; - - priv->scanned_cnt--; - } - - if (priv->scanned_cnt != 0) - mod_timer(&priv->aging_timer, - jiffies + msecs_to_jiffies(AGING_TIME)); -} +#define WILC_IP_TIMEOUT_MS 15000 static void clear_during_ip(struct timer_list *t) { @@ -191,151 +79,36 @@ static void clear_during_ip(struct timer_list *t) vif->obtaining_ip = false; } -static int is_network_in_shadow(struct network_info *nw_info, - struct wilc_priv *priv) -{ - int state = -1; - int i; - - if (priv->scanned_cnt == 0) { - mod_timer(&priv->aging_timer, - jiffies + msecs_to_jiffies(AGING_TIME)); - state = -1; - } else { - for (i = 0; i < priv->scanned_cnt; i++) { - if (memcmp(priv->scanned_shadow[i].bssid, - nw_info->bssid, 6) == 0) { - state = i; - break; - } - } - } - return state; -} - -static void add_network_to_shadow(struct network_info *nw_info, - struct wilc_priv *priv, void *join_params) -{ - int ap_found = is_network_in_shadow(nw_info, priv); - u32 ap_index = 0; - u8 rssi_index = 0; - struct network_info *shadow_nw_info; - - if (priv->scanned_cnt >= MAX_NUM_SCANNED_NETWORKS_SHADOW) - return; - - if (ap_found == -1) { - ap_index = priv->scanned_cnt; - priv->scanned_cnt++; - } else { - ap_index = ap_found; - } - shadow_nw_info = &priv->scanned_shadow[ap_index]; - rssi_index = shadow_nw_info->rssi_history.index; - shadow_nw_info->rssi_history.samples[rssi_index++] = nw_info->rssi; - if (rssi_index == NUM_RSSI) { - rssi_index = 0; - shadow_nw_info->rssi_history.full = true; - } - shadow_nw_info->rssi_history.index = rssi_index; - shadow_nw_info->rssi = nw_info->rssi; - shadow_nw_info->cap_info = nw_info->cap_info; - shadow_nw_info->ssid_len = nw_info->ssid_len; - memcpy(shadow_nw_info->ssid, nw_info->ssid, nw_info->ssid_len); - memcpy(shadow_nw_info->bssid, nw_info->bssid, ETH_ALEN); - shadow_nw_info->beacon_period = nw_info->beacon_period; - shadow_nw_info->dtim_period = nw_info->dtim_period; - shadow_nw_info->ch = nw_info->ch; - shadow_nw_info->tsf = nw_info->tsf; - if (ap_found != -1) - kfree(shadow_nw_info->ies); - shadow_nw_info->ies = kmemdup(nw_info->ies, nw_info->ies_len, - GFP_KERNEL); - if (shadow_nw_info->ies) - shadow_nw_info->ies_len = nw_info->ies_len; - else - shadow_nw_info->ies_len = 0; - shadow_nw_info->time_scan = jiffies; - shadow_nw_info->time_scan_cached = jiffies; - shadow_nw_info->found = 1; - if (ap_found != -1) - kfree(shadow_nw_info->join_params); - shadow_nw_info->join_params = join_params; -} - static void cfg_scan_result(enum scan_event scan_event, - struct network_info *network_info, - void *user_void, void *join_params) + struct wilc_rcvd_net_info *info, void *user_void) { - struct wilc_priv *priv; - struct wiphy *wiphy; - s32 freq; - struct ieee80211_channel *channel; - struct cfg80211_bss *bss = NULL; + struct wilc_priv *priv = user_void; - priv = user_void; if (!priv->cfg_scanning) return; if (scan_event == SCAN_EVENT_NETWORK_FOUND) { - wiphy = priv->dev->ieee80211_ptr->wiphy; - - if (!wiphy || !network_info) - return; + s32 freq; + struct ieee80211_channel *channel; + struct cfg80211_bss *bss; + struct wiphy *wiphy = priv->dev->ieee80211_ptr->wiphy; - if (wiphy->signal_type == CFG80211_SIGNAL_TYPE_UNSPEC && - (((s32)network_info->rssi * 100) < 0 || - ((s32)network_info->rssi * 100) > 100)) + if (!wiphy || !info) return; - freq = ieee80211_channel_to_frequency((s32)network_info->ch, + freq = ieee80211_channel_to_frequency((s32)info->ch, NL80211_BAND_2GHZ); channel = ieee80211_get_channel(wiphy, freq); - if (!channel) return; - if (network_info->new_network) { - if (priv->rcvd_ch_cnt >= MAX_NUM_SCANNED_NETWORKS) - return; - - priv->rcvd_ch_cnt++; - - add_network_to_shadow(network_info, priv, join_params); - - if (memcmp("DIRECT-", network_info->ssid, 7)) - return; - - bss = cfg80211_inform_bss(wiphy, - channel, - CFG80211_BSS_FTYPE_UNKNOWN, - network_info->bssid, - network_info->tsf, - network_info->cap_info, - network_info->beacon_period, - (const u8 *)network_info->ies, - (size_t)network_info->ies_len, - (s32)network_info->rssi * 100, - GFP_KERNEL); + bss = cfg80211_inform_bss_frame(wiphy, channel, info->mgmt, + info->frame_len, + (s32)info->rssi * 100, + GFP_KERNEL); + if (!bss) cfg80211_put_bss(wiphy, bss); - } else { - u32 i; - - for (i = 0; i < priv->rcvd_ch_cnt; i++) { - if (memcmp(priv->scanned_shadow[i].bssid, - network_info->bssid, 6) == 0) - break; - } - - if (i >= priv->rcvd_ch_cnt) - return; - - priv->scanned_shadow[i].rssi = network_info->rssi; - priv->scanned_shadow[i].time_scan = jiffies; - } } else if (scan_event == SCAN_EVENT_DONE) { - refresh_scan(priv, false); - mutex_lock(&priv->scan_req_lock); if (priv->scan_req) { @@ -344,7 +117,6 @@ static void cfg_scan_result(enum scan_event scan_event, }; cfg80211_scan_done(priv->scan_req, &info); - priv->rcvd_ch_cnt = 0; priv->cfg_scanning = false; priv->scan_req = NULL; } @@ -357,9 +129,6 @@ static void cfg_scan_result(enum scan_event scan_event, .aborted = false, }; - update_scan_time(priv); - refresh_scan(priv, false); - cfg80211_scan_done(priv->scan_req, &info); priv->cfg_scanning = false; priv->scan_req = NULL; @@ -368,21 +137,7 @@ static void cfg_scan_result(enum scan_event scan_event, } } -static inline bool wilc_cfg_scan_time_expired(struct wilc_priv *priv, int i) -{ - unsigned long now = jiffies; - - if (time_after(now, priv->scanned_shadow[i].time_scan_cached + - (unsigned long)(nl80211_SCAN_RESULT_EXPIRE - (1 * HZ)))) - return true; - else - return false; -} - -static void cfg_connect_result(enum conn_event conn_disconn_evt, - struct connect_info *conn_info, - u8 mac_status, - struct disconnect_info *disconn_info, +static void cfg_connect_result(enum conn_event conn_disconn_evt, u8 mac_status, void *priv_data) { struct wilc_priv *priv = priv_data; @@ -390,49 +145,28 @@ static void cfg_connect_result(enum conn_event conn_disconn_evt, struct wilc_vif *vif = netdev_priv(dev); struct wilc *wl = vif->wilc; struct host_if_drv *wfi_drv = priv->hif_drv; - u8 null_bssid[ETH_ALEN] = {0}; + struct wilc_conn_info *conn_info = &wfi_drv->conn_info; vif->connecting = false; if (conn_disconn_evt == CONN_DISCONN_EVENT_CONN_RESP) { - u16 connect_status; - - connect_status = conn_info->status; + u16 connect_status = conn_info->status; if (mac_status == WILC_MAC_STATUS_DISCONNECTED && - conn_info->status == WLAN_STATUS_SUCCESS) { + connect_status == WLAN_STATUS_SUCCESS) { connect_status = WLAN_STATUS_UNSPECIFIED_FAILURE; - wilc_wlan_set_bssid(priv->dev, null_bssid, - WILC_STATION_MODE); + wilc_wlan_set_bssid(priv->dev, NULL, WILC_STATION_MODE); - if (!wfi_drv->p2p_connect) - wlan_channel = INVALID_CHANNEL; + if (vif->iftype != WILC_CLIENT_MODE) + wl->sta_ch = WILC_INVALID_CHANNEL; netdev_err(dev, "Unspecified failure\n"); } - if (connect_status == WLAN_STATUS_SUCCESS) { - bool scan_refresh = false; - u32 i; - + if (connect_status == WLAN_STATUS_SUCCESS) memcpy(priv->associated_bss, conn_info->bssid, ETH_ALEN); - for (i = 0; i < priv->scanned_cnt; i++) { - if (memcmp(priv->scanned_shadow[i].bssid, - conn_info->bssid, - ETH_ALEN) == 0) { - if (wilc_cfg_scan_time_expired(priv, i)) - scan_refresh = true; - - break; - } - } - - if (scan_refresh) - refresh_scan(priv, true); - } - cfg80211_connect_result(dev, conn_info->bssid, conn_info->req_ies, conn_info->req_ies_len, @@ -440,23 +174,24 @@ static void cfg_connect_result(enum conn_event conn_disconn_evt, conn_info->resp_ies_len, connect_status, GFP_KERNEL); } else if (conn_disconn_evt == CONN_DISCONN_EVENT_DISCONN_NOTIF) { + u16 reason = 0; + vif->obtaining_ip = false; priv->p2p.local_random = 0x01; priv->p2p.recv_random = 0x00; priv->p2p.is_wilc_ie = false; eth_zero_addr(priv->associated_bss); - wilc_wlan_set_bssid(priv->dev, null_bssid, WILC_STATION_MODE); + wilc_wlan_set_bssid(priv->dev, NULL, WILC_STATION_MODE); + + if (vif->iftype != WILC_CLIENT_MODE) + wl->sta_ch = WILC_INVALID_CHANNEL; - if (!wfi_drv->p2p_connect) - wlan_channel = INVALID_CHANNEL; if (wfi_drv->ifc_up && dev == wl->vif[1]->ndev) - disconn_info->reason = 3; + reason = 3; else if (!wfi_drv->ifc_up && dev == wl->vif[1]->ndev) - disconn_info->reason = 1; + reason = 1; - cfg80211_disconnected(dev, disconn_info->reason, - disconn_info->ie, disconn_info->ie_len, - false, GFP_KERNEL); + cfg80211_disconnected(dev, reason, NULL, 0, false, GFP_KERNEL); } } @@ -470,7 +205,7 @@ static int set_channel(struct wiphy *wiphy, channelnum = ieee80211_frequency_to_channel(chandef->chan->center_freq); - curr_channel = channelnum; + vif->wilc->op_ch = channelnum; result = wilc_set_mac_chnl_num(vif, channelnum); if (result != 0) @@ -481,22 +216,23 @@ static int set_channel(struct wiphy *wiphy, static inline int wilc_wfi_cfg_alloc_fill_ssid(struct cfg80211_scan_request *request, - struct hidden_network *ntwk) + struct wilc_probe_ssid *search) { int i; int slot_id = 0; - ntwk->net_info = kcalloc(request->n_ssids, sizeof(*ntwk->net_info), - GFP_KERNEL); - if (!ntwk->net_info) + search->ssid_info = kcalloc(request->n_ssids, + sizeof(*search->ssid_info), GFP_KERNEL); + if (!search->ssid_info) goto out; - ntwk->n_ssids = request->n_ssids; + search->n_ssids = request->n_ssids; for (i = 0; i < request->n_ssids; i++) { if (request->ssids[i].ssid_len > 0) { - struct hidden_net_info *info = &ntwk->net_info[slot_id]; + struct wilc_probe_ssid_info *info; + info = &search->ssid_info[slot_id]; info->ssid = kmemdup(request->ssids[i].ssid, request->ssids[i].ssid_len, GFP_KERNEL); @@ -506,7 +242,7 @@ wilc_wfi_cfg_alloc_fill_ssid(struct cfg80211_scan_request *request, info->ssid_len = request->ssids[i].ssid_len; slot_id++; } else { - ntwk->n_ssids -= 1; + search->n_ssids -= 1; } } return 0; @@ -514,9 +250,9 @@ wilc_wfi_cfg_alloc_fill_ssid(struct cfg80211_scan_request *request, out_free: for (i = 0; i < slot_id; i++) - kfree(ntwk->net_info[i].ssid); + kfree(search->ssid_info[i].ssid); - kfree(ntwk->net_info); + kfree(search->ssid_info); out: return -ENOMEM; @@ -528,46 +264,41 @@ static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request) struct wilc_vif *vif = netdev_priv(priv->dev); u32 i; int ret = 0; - u8 scan_ch_list[MAX_NUM_SCANNED_NETWORKS]; - struct hidden_network hidden_ntwk; - - priv->scan_req = request; + u8 scan_ch_list[WILC_MAX_NUM_SCANNED_CH]; + struct wilc_probe_ssid probe_ssid; - priv->rcvd_ch_cnt = 0; - - reset_shadow_found(priv); + if (request->n_channels > WILC_MAX_NUM_SCANNED_CH) { + netdev_err(priv->dev, "Requested scanned channels over\n"); + return -EINVAL; + } + priv->scan_req = request; priv->cfg_scanning = true; - if (request->n_channels <= MAX_NUM_SCANNED_NETWORKS) { - for (i = 0; i < request->n_channels; i++) { - u16 freq = request->channels[i]->center_freq; + for (i = 0; i < request->n_channels; i++) { + u16 freq = request->channels[i]->center_freq; - scan_ch_list[i] = ieee80211_frequency_to_channel(freq); - } - - if (request->n_ssids >= 1) { - if (wilc_wfi_cfg_alloc_fill_ssid(request, - &hidden_ntwk)) { - ret = -ENOMEM; - goto out; - } + scan_ch_list[i] = ieee80211_frequency_to_channel(freq); + } - ret = wilc_scan(vif, WILC_FW_USER_SCAN, - WILC_FW_ACTIVE_SCAN, scan_ch_list, - request->n_channels, - (const u8 *)request->ie, - request->ie_len, cfg_scan_result, - (void *)priv, &hidden_ntwk); - } else { - ret = wilc_scan(vif, WILC_FW_USER_SCAN, - WILC_FW_ACTIVE_SCAN, scan_ch_list, - request->n_channels, - (const u8 *)request->ie, - request->ie_len, cfg_scan_result, - (void *)priv, NULL); + if (request->n_ssids >= 1) { + if (wilc_wfi_cfg_alloc_fill_ssid(request, &probe_ssid)) { + ret = -ENOMEM; + goto out; } + + ret = wilc_scan(vif, WILC_FW_USER_SCAN, + WILC_FW_ACTIVE_SCAN, scan_ch_list, + request->n_channels, + (const u8 *)request->ie, + request->ie_len, cfg_scan_result, + (void *)priv, &probe_ssid); } else { - netdev_err(priv->dev, "Requested scanned channels over\n"); + ret = wilc_scan(vif, WILC_FW_USER_SCAN, + WILC_FW_ACTIVE_SCAN, scan_ch_list, + request->n_channels, + (const u8 *)request->ie, + request->ie_len, cfg_scan_result, + (void *)priv, NULL); } out: @@ -585,54 +316,17 @@ static int connect(struct wiphy *wiphy, struct net_device *dev, struct wilc_priv *priv = wiphy_priv(wiphy); struct wilc_vif *vif = netdev_priv(priv->dev); struct host_if_drv *wfi_drv = priv->hif_drv; - struct network_info *nw_info; int ret; u32 i; - u32 sel_bssi_idx = UINT_MAX; u8 security = WILC_FW_SEC_NO; enum authtype auth_type = WILC_FW_AUTH_ANY; u32 cipher_group; + struct cfg80211_bss *bss; + void *join_params; + u8 ch; vif->connecting = true; - if (!(strncmp(sme->ssid, "DIRECT-", 7))) - wfi_drv->p2p_connect = 1; - else - wfi_drv->p2p_connect = 0; - - for (i = 0; i < priv->scanned_cnt; i++) { - if (sme->ssid_len == priv->scanned_shadow[i].ssid_len && - memcmp(priv->scanned_shadow[i].ssid, - sme->ssid, - sme->ssid_len) == 0) { - if (!sme->bssid) { - if (sel_bssi_idx == UINT_MAX || - priv->scanned_shadow[i].rssi > - priv->scanned_shadow[sel_bssi_idx].rssi) - sel_bssi_idx = i; - } else { - if (memcmp(priv->scanned_shadow[i].bssid, - sme->bssid, - ETH_ALEN) == 0) { - sel_bssi_idx = i; - break; - } - } - } - } - - if (sel_bssi_idx < priv->scanned_cnt) { - nw_info = &priv->scanned_shadow[sel_bssi_idx]; - } else { - ret = -ENOENT; - goto out_error; - } - - if (ether_addr_equal_unaligned(vif->bssid, nw_info->bssid)) { - ret = -EALREADY; - goto out_error; - } - memset(priv->wep_key, 0, sizeof(priv->wep_key)); memset(priv->wep_key_len, 0, sizeof(priv->wep_key_len)); @@ -706,31 +400,65 @@ static int connect(struct wiphy *wiphy, struct net_device *dev, auth_type = WILC_FW_AUTH_IEEE8021; } - curr_channel = nw_info->ch; + if (wfi_drv->usr_scan_req.scan_result) { + netdev_err(vif->ndev, "%s: Scan in progress\n", __func__); + ret = -EBUSY; + goto out_error; + } - if (!wfi_drv->p2p_connect) - wlan_channel = nw_info->ch; + bss = cfg80211_get_bss(wiphy, sme->channel, sme->bssid, sme->ssid, + sme->ssid_len, IEEE80211_BSS_TYPE_ANY, + IEEE80211_PRIVACY(sme->privacy)); + if (!bss) { + ret = -EINVAL; + goto out_error; + } - wilc_wlan_set_bssid(dev, nw_info->bssid, WILC_STATION_MODE); + if (ether_addr_equal_unaligned(vif->bssid, bss->bssid)) { + ret = -EALREADY; + goto out_put_bss; + } - ret = wilc_set_join_req(vif, nw_info->bssid, sme->ssid, - sme->ssid_len, sme->ie, sme->ie_len, - cfg_connect_result, (void *)priv, - security, auth_type, - nw_info->ch, - nw_info->join_params); - if (ret) { - u8 null_bssid[ETH_ALEN] = {0}; + join_params = wilc_parse_join_bss_param(bss, &sme->crypto); + if (!join_params) { + netdev_err(dev, "%s: failed to construct join param\n", + __func__); + ret = -EINVAL; + goto out_put_bss; + } + + ch = ieee80211_frequency_to_channel(bss->channel->center_freq); + vif->wilc->op_ch = ch; + if (vif->iftype != WILC_CLIENT_MODE) + vif->wilc->sta_ch = ch; + + wilc_wlan_set_bssid(dev, bss->bssid, WILC_STATION_MODE); + wfi_drv->conn_info.security = security; + wfi_drv->conn_info.auth_type = auth_type; + wfi_drv->conn_info.ch = ch; + wfi_drv->conn_info.conn_result = cfg_connect_result; + wfi_drv->conn_info.arg = priv; + wfi_drv->conn_info.param = join_params; + + ret = wilc_set_join_req(vif, bss->bssid, sme->ie, sme->ie_len); + if (ret) { netdev_err(dev, "wilc_set_join_req(): Error\n"); ret = -ENOENT; - if (!wfi_drv->p2p_connect) - wlan_channel = INVALID_CHANNEL; - wilc_wlan_set_bssid(dev, null_bssid, WILC_STATION_MODE); - goto out_error; - } + if (vif->iftype != WILC_CLIENT_MODE) + vif->wilc->sta_ch = WILC_INVALID_CHANNEL; + wilc_wlan_set_bssid(dev, NULL, WILC_STATION_MODE); + wfi_drv->conn_info.conn_result = NULL; + kfree(join_params); + goto out_put_bss; + } + kfree(join_params); + cfg80211_put_bss(wiphy, bss); return 0; +out_put_bss: + cfg80211_put_bss(wiphy, bss); + out_error: vif->connecting = false; return ret; @@ -742,9 +470,7 @@ static int disconnect(struct wiphy *wiphy, struct net_device *dev, struct wilc_priv *priv = wiphy_priv(wiphy); struct wilc_vif *vif = netdev_priv(priv->dev); struct wilc *wilc = vif->wilc; - struct host_if_drv *wfi_drv; int ret; - u8 null_bssid[ETH_ALEN] = {0}; vif->connecting = false; @@ -757,15 +483,14 @@ static int disconnect(struct wiphy *wiphy, struct net_device *dev, return 0; } - wfi_drv = (struct host_if_drv *)priv->hif_drv; - if (!wfi_drv->p2p_connect) - wlan_channel = INVALID_CHANNEL; - wilc_wlan_set_bssid(priv->dev, null_bssid, WILC_STATION_MODE); + if (vif->iftype != WILC_CLIENT_MODE) + wilc->sta_ch = WILC_INVALID_CHANNEL; + wilc_wlan_set_bssid(priv->dev, NULL, WILC_STATION_MODE); priv->p2p.local_random = 0x01; priv->p2p.recv_random = 0x00; priv->p2p.is_wilc_ie = false; - wfi_drv->p2p_timeout = 0; + priv->hif_drv->p2p_timeout = 0; ret = wilc_disconnect(vif); if (ret != 0) { @@ -1210,7 +935,7 @@ static int flush_pmksa(struct wiphy *wiphy, struct net_device *netdev) } static inline void wilc_wfi_cfg_parse_ch_attr(u8 *buf, u8 ch_list_attr_idx, - u8 op_ch_attr_idx) + u8 op_ch_attr_idx, u8 sta_ch) { int i = 0; int j = 0; @@ -1221,7 +946,7 @@ static inline void wilc_wfi_cfg_parse_ch_attr(u8 *buf, u8 ch_list_attr_idx, for (i = ch_list_attr_idx + 3; i < limit; i++) { if (buf[i] == 0x51) { for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) - buf[j] = wlan_channel; + buf[j] = sta_ch; break; } } @@ -1229,11 +954,11 @@ static inline void wilc_wfi_cfg_parse_ch_attr(u8 *buf, u8 ch_list_attr_idx, if (op_ch_attr_idx) { buf[op_ch_attr_idx + 6] = 0x51; - buf[op_ch_attr_idx + 7] = wlan_channel; + buf[op_ch_attr_idx + 7] = sta_ch; } } -static void wilc_wfi_cfg_parse_rx_action(u8 *buf, u32 len) +static void wilc_wfi_cfg_parse_rx_action(u8 *buf, u32 len, u8 sta_ch) { u32 index = 0; u8 op_channel_attr_index = 0; @@ -1249,13 +974,13 @@ static void wilc_wfi_cfg_parse_rx_action(u8 *buf, u32 len) op_channel_attr_index = index; index += buf[index + 1] + 3; } - if (wlan_channel != INVALID_CHANNEL) + if (sta_ch != WILC_INVALID_CHANNEL) wilc_wfi_cfg_parse_ch_attr(buf, channel_list_attr_index, - op_channel_attr_index); + op_channel_attr_index, sta_ch); } static void wilc_wfi_cfg_parse_tx_action(u8 *buf, u32 len, bool oper_ch, - u8 iftype) + u8 iftype, u8 sta_ch) { u32 index = 0; u8 op_channel_attr_index = 0; @@ -1274,9 +999,9 @@ static void wilc_wfi_cfg_parse_tx_action(u8 *buf, u32 len, bool oper_ch, op_channel_attr_index = index; index += buf[index + 1] + 3; } - if (wlan_channel != INVALID_CHANNEL && oper_ch) + if (sta_ch != WILC_INVALID_CHANNEL && oper_ch) wilc_wfi_cfg_parse_ch_attr(buf, channel_list_attr_index, - op_channel_attr_index); + op_channel_attr_index, sta_ch); } static void wilc_wfi_cfg_parse_rx_vendor_spec(struct wilc_priv *priv, u8 *buff, @@ -1311,7 +1036,8 @@ static void wilc_wfi_cfg_parse_rx_vendor_spec(struct wilc_priv *priv, u8 *buff, if (buff[i] == P2PELEM_ATTR_ID && !(memcmp(p2p_oui, &buff[i + 2], 4))) { wilc_wfi_cfg_parse_rx_action(&buff[i + 6], - size - (i + 6)); + size - (i + 6), + vif->wilc->sta_ch); break; } } @@ -1322,6 +1048,8 @@ void wilc_wfi_p2p_rx(struct net_device *dev, u8 *buff, u32 size) { struct wilc_priv *priv = wiphy_priv(dev->ieee80211_ptr->wiphy); struct host_if_drv *wfi_drv = priv->hif_drv; + struct wilc_vif *vif = netdev_priv(dev); + struct wilc *wl = vif->wilc; u32 header, pkt_offset; s32 freq; __le16 fc; @@ -1342,7 +1070,7 @@ void wilc_wfi_p2p_rx(struct net_device *dev, u8 *buff, u32 size) return; } - freq = ieee80211_channel_to_frequency(curr_channel, NL80211_BAND_2GHZ); + freq = ieee80211_channel_to_frequency(wl->op_ch, NL80211_BAND_2GHZ); fc = ((struct ieee80211_hdr *)buff)->frame_control; if (!ieee80211_is_action(fc)) { @@ -1387,33 +1115,18 @@ void wilc_wfi_p2p_rx(struct net_device *dev, u8 *buff, u32 size) static void wilc_wfi_mgmt_tx_complete(void *priv, int status) { - struct p2p_mgmt_data *pv_data = priv; + struct wilc_p2p_mgmt_data *pv_data = priv; kfree(pv_data->buff); kfree(pv_data); } -static void wilc_wfi_remain_on_channel_ready(void *priv_data) -{ - struct wilc_priv *priv; - - priv = priv_data; - - priv->p2p_listen_state = true; - - cfg80211_ready_on_channel(priv->wdev, - priv->remain_on_ch_params.listen_cookie, - priv->remain_on_ch_params.listen_ch, - priv->remain_on_ch_params.listen_duration, - GFP_KERNEL); -} - -static void wilc_wfi_remain_on_channel_expired(void *data, u32 session_id) +static void wilc_wfi_remain_on_channel_expired(void *data, u64 cookie) { struct wilc_priv *priv = data; struct wilc_wfi_p2p_listen_params *params = &priv->remain_on_ch_params; - if (session_id != params->listen_session_id) + if (cookie != params->listen_cookie) return; priv->p2p_listen_state = false; @@ -1430,24 +1143,36 @@ static int remain_on_channel(struct wiphy *wiphy, int ret = 0; struct wilc_priv *priv = wiphy_priv(wiphy); struct wilc_vif *vif = netdev_priv(priv->dev); + u64 id; if (wdev->iftype == NL80211_IFTYPE_AP) { netdev_dbg(vif->ndev, "Required while in AP mode\n"); return ret; } - curr_channel = chan->hw_value; + id = ++priv->inc_roc_cookie; + if (id == 0) + id = ++priv->inc_roc_cookie; + + ret = wilc_remain_on_channel(vif, id, duration, chan->hw_value, + wilc_wfi_remain_on_channel_expired, + (void *)priv); + if (ret) + return ret; + + vif->wilc->op_ch = chan->hw_value; priv->remain_on_ch_params.listen_ch = chan; - priv->remain_on_ch_params.listen_cookie = *cookie; + priv->remain_on_ch_params.listen_cookie = id; + *cookie = id; + priv->p2p_listen_state = true; priv->remain_on_ch_params.listen_duration = duration; - priv->remain_on_ch_params.listen_session_id++; - return wilc_remain_on_channel(vif, - priv->remain_on_ch_params.listen_session_id, - duration, chan->hw_value, - wilc_wfi_remain_on_channel_expired, - wilc_wfi_remain_on_channel_ready, (void *)priv); + cfg80211_ready_on_channel(wdev, *cookie, chan, duration, GFP_KERNEL); + mod_timer(&vif->hif_drv->remain_on_ch_timer, + jiffies + msecs_to_jiffies(duration)); + + return ret; } static int cancel_remain_on_channel(struct wiphy *wiphy, @@ -1457,12 +1182,14 @@ static int cancel_remain_on_channel(struct wiphy *wiphy, struct wilc_priv *priv = wiphy_priv(wiphy); struct wilc_vif *vif = netdev_priv(priv->dev); - return wilc_listen_state_expired(vif, - priv->remain_on_ch_params.listen_session_id); + if (cookie != priv->remain_on_ch_params.listen_cookie) + return -ENOENT; + + return wilc_listen_state_expired(vif, cookie); } static void wilc_wfi_cfg_tx_vendor_spec(struct wilc_priv *priv, - struct p2p_mgmt_data *mgmt_tx, + struct wilc_p2p_mgmt_data *mgmt_tx, struct cfg80211_mgmt_tx_params *params, u8 iftype, u32 buf_len) { @@ -1470,6 +1197,7 @@ static void wilc_wfi_cfg_tx_vendor_spec(struct wilc_priv *priv, size_t len = params->len; u32 i; u8 subtype = buf[P2P_PUB_ACTION_SUBTYPE]; + struct wilc_vif *vif = netdev_priv(priv->dev); if (subtype == GO_NEG_REQ || subtype == GO_NEG_RSP) { if (priv->p2p.local_random == 1 && @@ -1494,7 +1222,8 @@ static void wilc_wfi_cfg_tx_vendor_spec(struct wilc_priv *priv, oper_ch = true; wilc_wfi_cfg_parse_tx_action(tx_buff, len - (i + 6), - oper_ch, iftype); + oper_ch, iftype, + vif->wilc->sta_ch); break; } @@ -1520,14 +1249,14 @@ static int mgmt_tx(struct wiphy *wiphy, const u8 *buf = params->buf; size_t len = params->len; const struct ieee80211_mgmt *mgmt; - struct p2p_mgmt_data *mgmt_tx; + struct wilc_p2p_mgmt_data *mgmt_tx; struct wilc_priv *priv = wiphy_priv(wiphy); struct host_if_drv *wfi_drv = priv->hif_drv; struct wilc_vif *vif = netdev_priv(wdev->netdev); u32 buf_len = len + sizeof(p2p_vendor_spec) + sizeof(priv->p2p.local_random); int ret = 0; - *cookie = (unsigned long)buf; + *cookie = prandom_u32(); priv->tx_cookie = *cookie; mgmt = (const struct ieee80211_mgmt *)buf; @@ -1552,7 +1281,7 @@ static int mgmt_tx(struct wiphy *wiphy, if (ieee80211_is_probe_resp(mgmt->frame_control)) { wilc_set_mac_chnl_num(vif, chan->hw_value); - curr_channel = chan->hw_value; + vif->wilc->op_ch = chan->hw_value; goto out_txq_add_pkt; } @@ -1563,7 +1292,7 @@ static int mgmt_tx(struct wiphy *wiphy, if (buf[ACTION_SUBTYPE_ID] != PUBLIC_ACT_VENDORSPEC || buf[P2P_PUB_ACTION_SUBTYPE] != GO_NEG_CONF) { wilc_set_mac_chnl_num(vif, chan->hw_value); - curr_channel = chan->hw_value; + vif->wilc->op_ch = chan->hw_value; } switch (buf[ACTION_SUBTYPE_ID]) { case GAS_INITIAL_REQ: @@ -1755,7 +1484,7 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, case NL80211_IFTYPE_P2P_GO: vif->obtaining_ip = true; mod_timer(&vif->during_ip_timer, - jiffies + msecs_to_jiffies(DURING_IP_TIME_OUT)); + jiffies + msecs_to_jiffies(WILC_IP_TIMEOUT_MS)); wilc_set_operation_mode(vif, WILC_AP_MODE); dev->ieee80211_ptr->iftype = type; priv->wdev->iftype = type; @@ -1805,9 +1534,8 @@ static int stop_ap(struct wiphy *wiphy, struct net_device *dev) int ret; struct wilc_priv *priv = wiphy_priv(wiphy); struct wilc_vif *vif = netdev_priv(priv->dev); - u8 null_bssid[ETH_ALEN] = {0}; - wilc_wlan_set_bssid(dev, null_bssid, WILC_AP_MODE); + wilc_wlan_set_bssid(dev, NULL, WILC_AP_MODE); ret = wilc_del_beacon(vif); @@ -1884,7 +1612,8 @@ static struct wireless_dev *add_virtual_intf(struct wiphy *wiphy, struct net_device *new_ifc; if (type == NL80211_IFTYPE_MONITOR) { - new_ifc = wilc_wfi_init_mon_interface(name, vif->ndev); + new_ifc = wilc_wfi_init_mon_interface(vif->wilc, name, + vif->ndev); if (new_ifc) { vif = netdev_priv(priv->wdev->netdev); vif->monitor_flag = 1; @@ -2102,7 +1831,6 @@ int wilc_init_host_int(struct net_device *net) struct wilc_priv *priv = wdev_priv(net->ieee80211_ptr); struct wilc_vif *vif = netdev_priv(priv->dev); - timer_setup(&priv->aging_timer, remove_network_from_shadow, 0); timer_setup(&vif->during_ip_timer, clear_during_ip, 0); priv->p2p_listen_state = false; @@ -2126,8 +1854,6 @@ void wilc_deinit_host_int(struct net_device *net) mutex_destroy(&priv->scan_req_lock); ret = wilc_deinit(vif); - del_timer_sync(&priv->aging_timer); - clear_shadow_scan(priv); del_timer_sync(&vif->during_ip_timer); if (ret) diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.h b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.h index 4812c8e2c79b..31dfa1f141f1 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.h +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.h @@ -13,9 +13,10 @@ struct wireless_dev *wilc_create_wiphy(struct net_device *net, void wilc_free_wiphy(struct net_device *net); void wilc_deinit_host_int(struct net_device *net); int wilc_init_host_int(struct net_device *net); -void wilc_wfi_monitor_rx(u8 *buff, u32 size); -void wilc_wfi_deinit_mon_interface(void); -struct net_device *wilc_wfi_init_mon_interface(const char *name, +void wilc_wfi_monitor_rx(struct net_device *mon_dev, u8 *buff, u32 size); +void wilc_wfi_deinit_mon_interface(struct wilc *wl); +struct net_device *wilc_wfi_init_mon_interface(struct wilc *wl, + const char *name, struct net_device *real_dev); void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev, u16 frame_type, bool reg); diff --git a/drivers/staging/wilc1000/wilc_wfi_netdevice.h b/drivers/staging/wilc1000/wilc_wfi_netdevice.h index c6685c0c238b..df00762487c0 100644 --- a/drivers/staging/wilc1000/wilc_wfi_netdevice.h +++ b/drivers/staging/wilc1000/wilc_wfi_netdevice.h @@ -65,7 +65,6 @@ struct wilc_wfi_p2p_listen_params { struct ieee80211_channel *listen_ch; u32 listen_duration; u64 listen_cookie; - u32 listen_session_id; }; struct wilc_p2p_var { @@ -137,7 +136,6 @@ struct wilc_priv { u64 tx_cookie; bool cfg_scanning; - u32 rcvd_ch_cnt; u8 associated_bss[ETH_ALEN]; struct sta_info assoc_stainfo; @@ -155,8 +153,6 @@ struct wilc_priv { /* mutexes */ struct mutex scan_req_lock; bool p2p_listen_state; - struct timer_list aging_timer; - struct network_info scanned_shadow[MAX_NUM_SCANNED_NETWORKS_SHADOW]; int scanned_cnt; struct wilc_p2p_var p2p; @@ -164,6 +160,7 @@ struct wilc_priv { struct ieee80211_rate bitrates[ARRAY_SIZE(wilc_bitrates)]; struct ieee80211_supported_band band; u32 cipher_suites[ARRAY_SIZE(wilc_cipher_suites)]; + u64 inc_roc_cookie; }; struct frame_reg { @@ -251,7 +248,7 @@ struct wilc { struct mutex cfg_cmd_lock; struct wilc_cfg_frame cfg_frame; u32 cfg_frame_offset; - int cfg_seq_no; + u8 cfg_seq_no; u8 *rx_buffer; u32 rx_buffer_offset; @@ -273,13 +270,18 @@ struct wilc { enum chip_ps_states chip_ps_state; struct wilc_cfg cfg; void *bus_data; + struct net_device *monitor_dev; + /* deinit lock */ + struct mutex deinit_lock; + u8 sta_ch; + u8 op_ch; }; struct wilc_wfi_mon_priv { struct net_device *real_ndev; }; -void wilc_frmw_to_linux(struct wilc *wilc, u8 *buff, u32 size, u32 pkt_offset); +void wilc_frmw_to_host(struct wilc *wilc, u8 *buff, u32 size, u32 pkt_offset); void wilc_mac_indicate(struct wilc *wilc); void wilc_netdev_cleanup(struct wilc *wilc); int wilc_netdev_init(struct wilc **wilc, struct device *dev, int io_type, diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index 489e5a5038f8..c2389695fe20 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -274,7 +274,8 @@ static int wilc_wlan_txq_add_cfg_pkt(struct wilc_vif *vif, u8 *buffer, } int wilc_wlan_txq_add_net_pkt(struct net_device *dev, void *priv, u8 *buffer, - u32 buffer_size, wilc_tx_complete_func_t func) + u32 buffer_size, + void (*tx_complete_fn)(void *, int)) { struct txq_entry_t *tqe; struct wilc_vif *vif = netdev_priv(dev); @@ -292,7 +293,7 @@ int wilc_wlan_txq_add_net_pkt(struct net_device *dev, void *priv, u8 *buffer, tqe->type = WILC_NET_PKT; tqe->buffer = buffer; tqe->buffer_size = buffer_size; - tqe->tx_complete_func = func; + tqe->tx_complete_func = tx_complete_fn; tqe->priv = priv; tqe->ack_idx = NOT_TCP_ACK; @@ -303,7 +304,8 @@ int wilc_wlan_txq_add_net_pkt(struct net_device *dev, void *priv, u8 *buffer, } int wilc_wlan_txq_add_mgmt_pkt(struct net_device *dev, void *priv, u8 *buffer, - u32 buffer_size, wilc_tx_complete_func_t func) + u32 buffer_size, + void (*tx_complete_fn)(void *, int)) { struct txq_entry_t *tqe; struct wilc_vif *vif = netdev_priv(dev); @@ -321,7 +323,7 @@ int wilc_wlan_txq_add_mgmt_pkt(struct net_device *dev, void *priv, u8 *buffer, tqe->type = WILC_MGMT_PKT; tqe->buffer = buffer; tqe->buffer_size = buffer_size; - tqe->tx_complete_func = func; + tqe->tx_complete_func = tx_complete_fn; tqe->priv = priv; tqe->ack_idx = NOT_TCP_ACK; wilc_wlan_txq_add_to_tail(dev, tqe); @@ -521,7 +523,7 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count) if (vmm_sz & 0x3) vmm_sz = (vmm_sz + 4) & ~0x3; - if ((sum + vmm_sz) > LINUX_TX_SIZE) + if ((sum + vmm_sz) > WILC_TX_BUFF_SIZE) break; vmm_table[i] = vmm_sz / 4; @@ -715,9 +717,8 @@ static void wilc_wlan_handle_rx_buff(struct wilc *wilc, u8 *buffer, int size) } else { if (!is_cfg_packet) { if (pkt_len > 0) { - wilc_frmw_to_linux(wilc, buff_ptr, - pkt_len, - pkt_offset); + wilc_frmw_to_host(wilc, buff_ptr, + pkt_len, pkt_offset); } } else { struct wilc_cfg_rsp rsp; @@ -809,7 +810,7 @@ static void wilc_wlan_handle_isr_ext(struct wilc *wilc, u32 int_status) if (size <= 0) return; - if (LINUX_RX_SIZE - offset < size) + if (WILC_RX_BUFF_SIZE - offset < size) offset = 0; buffer = &wilc->rx_buffer[offset]; @@ -1092,24 +1093,19 @@ static int wilc_wlan_cfg_commit(struct wilc_vif *vif, int type, { struct wilc *wilc = vif->wilc; struct wilc_cfg_frame *cfg = &wilc->cfg_frame; - int total_len = wilc->cfg_frame_offset + 4 + DRIVER_HANDLER_SIZE; - int seq_no = wilc->cfg_seq_no % 256; - int driver_handler = (u32)drv_handler; + int t_len = wilc->cfg_frame_offset + sizeof(struct wilc_cfg_cmd_hdr); if (type == WILC_CFG_SET) - cfg->wid_header[0] = 'W'; + cfg->hdr.cmd_type = 'W'; else - cfg->wid_header[0] = 'Q'; - cfg->wid_header[1] = seq_no; - cfg->wid_header[2] = (u8)total_len; - cfg->wid_header[3] = (u8)(total_len >> 8); - cfg->wid_header[4] = (u8)driver_handler; - cfg->wid_header[5] = (u8)(driver_handler >> 8); - cfg->wid_header[6] = (u8)(driver_handler >> 16); - cfg->wid_header[7] = (u8)(driver_handler >> 24); - wilc->cfg_seq_no = seq_no; - - if (!wilc_wlan_txq_add_cfg_pkt(vif, &cfg->wid_header[0], total_len)) + cfg->hdr.cmd_type = 'Q'; + + cfg->hdr.seq_no = wilc->cfg_seq_no % 256; + cfg->hdr.total_len = cpu_to_le16(t_len); + cfg->hdr.driver_handler = cpu_to_le32(drv_handler); + wilc->cfg_seq_no = cfg->hdr.seq_no; + + if (!wilc_wlan_txq_add_cfg_pkt(vif, (u8 *)&cfg->hdr, t_len)) return -1; return 0; @@ -1144,7 +1140,7 @@ int wilc_wlan_cfg_set(struct wilc_vif *vif, int start, u16 wid, u8 *buffer, ret_size = 0; if (!wait_for_completion_timeout(&wilc->cfg_event, - msecs_to_jiffies(CFG_PKTS_TIMEOUT))) { + WILC_CFG_PKTS_TIMEOUT)) { netdev_dbg(vif->ndev, "%s: Timed Out\n", __func__); ret_size = 0; } @@ -1182,7 +1178,7 @@ int wilc_wlan_cfg_get(struct wilc_vif *vif, int start, u16 wid, int commit, ret_size = 0; if (!wait_for_completion_timeout(&wilc->cfg_event, - msecs_to_jiffies(CFG_PKTS_TIMEOUT))) { + WILC_CFG_PKTS_TIMEOUT)) { netdev_dbg(vif->ndev, "%s: Timed Out\n", __func__); ret_size = 0; } @@ -1317,7 +1313,7 @@ int wilc_wlan_init(struct net_device *dev) } if (!wilc->tx_buffer) - wilc->tx_buffer = kmalloc(LINUX_TX_SIZE, GFP_KERNEL); + wilc->tx_buffer = kmalloc(WILC_TX_BUFF_SIZE, GFP_KERNEL); if (!wilc->tx_buffer) { ret = -ENOBUFS; @@ -1325,7 +1321,7 @@ int wilc_wlan_init(struct net_device *dev) } if (!wilc->rx_buffer) - wilc->rx_buffer = kmalloc(LINUX_RX_SIZE, GFP_KERNEL); + wilc->rx_buffer = kmalloc(WILC_RX_BUFF_SIZE, GFP_KERNEL); if (!wilc->rx_buffer) { ret = -ENOBUFS; diff --git a/drivers/staging/wilc1000/wilc_wlan.h b/drivers/staging/wilc1000/wilc_wlan.h index 27667131de1a..1a27f62589a2 100644 --- a/drivers/staging/wilc1000/wilc_wlan.h +++ b/drivers/staging/wilc1000/wilc_wlan.h @@ -14,7 +14,6 @@ * Mac eth header length * ********************************************/ -#define DRIVER_HANDLER_SIZE 4 #define MAX_MAC_HDR_LEN 26 /* QOS_MAC_HDR_LEN */ #define SUB_MSDU_HEADER_LENGTH 14 #define SNAP_HDR_LEN 8 @@ -132,8 +131,8 @@ #define WILC_PLL_TO_SPI 2 #define ABORT_INT BIT(31) -#define LINUX_RX_SIZE (96 * 1024) -#define LINUX_TX_SIZE (64 * 1024) +#define WILC_RX_BUFF_SIZE (96 * 1024) +#define WILC_TX_BUFF_SIZE (64 * 1024) #define MODALIAS "WILC_SPI" #define GPIO_NUM 0x44 @@ -197,7 +196,7 @@ #define ENABLE_RX_VMM (SEL_VMM_TBL1 | EN_VMM) #define ENABLE_TX_VMM (SEL_VMM_TBL0 | EN_VMM) /*time for expiring the completion of cfg packets*/ -#define CFG_PKTS_TIMEOUT 2000 +#define WILC_CFG_PKTS_TIMEOUT msecs_to_jiffies(2000) #define IS_MANAGMEMENT 0x100 #define IS_MANAGMEMENT_CALLBACK 0x080 @@ -249,16 +248,30 @@ struct wilc_hif_func { void (*disable_interrupt)(struct wilc *nic); }; -#define MAX_CFG_FRAME_SIZE 1468 +#define WILC_MAX_CFG_FRAME_SIZE 1468 + +struct tx_complete_data { + int size; + void *buff; + u8 *bssid; + struct sk_buff *skb; +}; + +struct wilc_cfg_cmd_hdr { + u8 cmd_type; + u8 seq_no; + __le16 total_len; + __le32 driver_handler; +}; struct wilc_cfg_frame { - u8 wid_header[8]; - u8 frame[MAX_CFG_FRAME_SIZE]; + struct wilc_cfg_cmd_hdr hdr; + u8 frame[WILC_MAX_CFG_FRAME_SIZE]; }; struct wilc_cfg_rsp { - int type; - u32 seq_no; + u8 type; + u8 seq_no; }; struct wilc; @@ -269,7 +282,8 @@ int wilc_wlan_firmware_download(struct wilc *wilc, const u8 *buffer, int wilc_wlan_start(struct wilc *wilc); int wilc_wlan_stop(struct wilc *wilc); int wilc_wlan_txq_add_net_pkt(struct net_device *dev, void *priv, u8 *buffer, - u32 buffer_size, wilc_tx_complete_func_t func); + u32 buffer_size, + void (*tx_complete_fn)(void *, int)); int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count); void wilc_handle_isr(struct wilc *wilc); void wilc_wlan_cleanup(struct net_device *dev); @@ -280,7 +294,7 @@ int wilc_wlan_cfg_get(struct wilc_vif *vif, int start, u16 wid, int commit, int wilc_wlan_cfg_get_val(struct wilc *wl, u16 wid, u8 *buffer, u32 buffer_size); int wilc_wlan_txq_add_mgmt_pkt(struct net_device *dev, void *priv, u8 *buffer, - u32 buffer_size, wilc_tx_complete_func_t func); + u32 buffer_size, void (*func)(void *, int)); void wilc_chip_sleep_manually(struct wilc *wilc); void wilc_enable_tcp_ack_filter(struct wilc_vif *vif, bool value); @@ -294,4 +308,6 @@ void chip_allow_sleep(struct wilc *wilc); void chip_wakeup(struct wilc *wilc); int wilc_send_config_pkt(struct wilc_vif *vif, u8 mode, struct wid *wids, u32 count, u32 drv); +int wilc_wlan_init(struct net_device *dev); +u32 wilc_get_chipid(struct wilc *wilc, bool update); #endif diff --git a/drivers/staging/wilc1000/wilc_wlan_cfg.c b/drivers/staging/wilc1000/wilc_wlan_cfg.c index 8390766358da..9dc5de4eb08d 100644 --- a/drivers/staging/wilc1000/wilc_wlan_cfg.c +++ b/drivers/staging/wilc1000/wilc_wlan_cfg.c @@ -54,7 +54,7 @@ static int wilc_wlan_cfg_set_byte(u8 *frame, u32 offset, u16 id, u8 val8) { u8 *buf; - if ((offset + 4) >= MAX_CFG_FRAME_SIZE) + if ((offset + 4) >= WILC_MAX_CFG_FRAME_SIZE) return 0; buf = &frame[offset]; @@ -71,7 +71,7 @@ static int wilc_wlan_cfg_set_hword(u8 *frame, u32 offset, u16 id, u16 val16) { u8 *buf; - if ((offset + 5) >= MAX_CFG_FRAME_SIZE) + if ((offset + 5) >= WILC_MAX_CFG_FRAME_SIZE) return 0; buf = &frame[offset]; @@ -90,7 +90,7 @@ static int wilc_wlan_cfg_set_word(u8 *frame, u32 offset, u16 id, u32 val32) { u8 *buf; - if ((offset + 7) >= MAX_CFG_FRAME_SIZE) + if ((offset + 7) >= WILC_MAX_CFG_FRAME_SIZE) return 0; buf = &frame[offset]; @@ -112,7 +112,7 @@ static int wilc_wlan_cfg_set_str(u8 *frame, u32 offset, u16 id, u8 *str, { u8 *buf; - if ((offset + size + 4) >= MAX_CFG_FRAME_SIZE) + if ((offset + size + 4) >= WILC_MAX_CFG_FRAME_SIZE) return 0; buf = &frame[offset]; @@ -134,7 +134,7 @@ static int wilc_wlan_cfg_set_bin(u8 *frame, u32 offset, u16 id, u8 *b, u32 size) u32 i; u8 checksum = 0; - if ((offset + size + 5) >= MAX_CFG_FRAME_SIZE) + if ((offset + size + 5) >= WILC_MAX_CFG_FRAME_SIZE) return 0; buf = &frame[offset]; @@ -168,7 +168,7 @@ static void wilc_wlan_parse_response_frame(struct wilc *wl, u8 *info, int size) while (size > 0) { i = 0; - wid = info[0] | (info[1] << 8); + wid = get_unaligned_le16(info); switch (GET_WID_TYPE(wid)) { case WID_CHAR: @@ -187,12 +187,13 @@ static void wilc_wlan_parse_response_frame(struct wilc *wl, u8 *info, int size) case WID_SHORT: do { - if (wl->cfg.hw[i].id == WID_NIL) + struct wilc_cfg_hword *hw = &wl->cfg.hw[i]; + + if (hw->id == WID_NIL) break; - if (wl->cfg.hw[i].id == wid) { - wl->cfg.hw[i].val = (info[4] | - (info[5] << 8)); + if (hw->id == wid) { + hw->val = get_unaligned_le16(&info[4]); break; } i++; @@ -202,14 +203,13 @@ static void wilc_wlan_parse_response_frame(struct wilc *wl, u8 *info, int size) case WID_INT: do { - if (wl->cfg.w[i].id == WID_NIL) + struct wilc_cfg_word *w = &wl->cfg.w[i]; + + if (w->id == WID_NIL) break; - if (wl->cfg.w[i].id == wid) { - wl->cfg.w[i].val = (info[4] | - (info[5] << 8) | - (info[6] << 16) | - (info[7] << 24)); + if (w->id == wid) { + w->val = get_unaligned_le32(&info[4]); break; } i++; @@ -244,7 +244,7 @@ static void wilc_wlan_parse_info_frame(struct wilc *wl, u8 *info) { u32 wid, len; - wid = info[0] | (info[1] << 8); + wid = get_unaligned_le16(info); len = info[2]; @@ -309,7 +309,7 @@ int wilc_wlan_cfg_get_wid(u8 *frame, u32 offset, u16 id) { u8 *buf; - if ((offset + 2) >= MAX_CFG_FRAME_SIZE) + if ((offset + 2) >= WILC_MAX_CFG_FRAME_SIZE) return 0; buf = &frame[offset]; @@ -371,8 +371,7 @@ int wilc_wlan_cfg_get_wid_value(struct wilc *wl, u16 wid, u8 *buffer, break; if (id == wid) { - u32 size = (wl->cfg.s[i].str[0] | - (wl->cfg.s[i].str[1] << 8)); + u16 size = get_unaligned_le16(wl->cfg.s[i].str); if (buffer_size >= size) { memcpy(buffer, &wl->cfg.s[i].str[2], diff --git a/drivers/staging/wilc1000/wilc_wlan_if.h b/drivers/staging/wilc1000/wilc_wlan_if.h index e2310d860291..b15de36e32e0 100644 --- a/drivers/staging/wilc1000/wilc_wlan_if.h +++ b/drivers/staging/wilc1000/wilc_wlan_if.h @@ -11,44 +11,9 @@ /******************************************** * - * Host Interface Defines - * - ********************************************/ - -enum { - WILC_HIF_SDIO = 0, - WILC_HIF_SPI = BIT(0) -}; - -/******************************************** - * - * Wlan Interface Defines - * - ********************************************/ - -enum { - WILC_MAC_STATUS_INIT = -1, - WILC_MAC_STATUS_DISCONNECTED = 0, - WILC_MAC_STATUS_CONNECTED = 1 -}; - -struct tx_complete_data { - int size; - void *buff; - u8 *bssid; - struct sk_buff *skb; -}; - -typedef void (*wilc_tx_complete_func_t)(void *, int); - -/******************************************** - * * Wlan Configuration ID * ********************************************/ -#define WILC_MULTICAST_TABLE_SIZE 8 -#define MAX_SSID_LEN 33 -#define MAX_RATES_SUPPORTED 12 enum bss_types { WILC_FW_BSS_TYPE_INFRA = 0, @@ -689,7 +654,6 @@ enum { WID_TX_POWER_LEVEL_11N = 0x00B1, /* Custom Character WID list */ - WID_PC_TEST_MODE = 0x00C8, /* SCAN Complete notification WID*/ WID_SCAN_COMPLETE = 0x00C9, @@ -836,8 +800,4 @@ enum { WID_MAX = 0xFFFF }; -struct wilc; -int wilc_wlan_init(struct net_device *dev); -u32 wilc_get_chipid(struct wilc *wilc, bool update); - #endif diff --git a/drivers/staging/wlan-ng/Kconfig b/drivers/staging/wlan-ng/Kconfig index 426d4efbabc3..97238018b315 100644 --- a/drivers/staging/wlan-ng/Kconfig +++ b/drivers/staging/wlan-ng/Kconfig @@ -4,7 +4,7 @@ config PRISM2_USB select WIRELESS_EXT select WEXT_PRIV default n - ---help--- + help This is the wlan-ng prism 2.5/3 USB driver for a wide range of old USB wireless devices. diff --git a/drivers/staging/wlan-ng/cfg80211.c b/drivers/staging/wlan-ng/cfg80211.c index e5d7def1f366..8a862f718d5c 100644 --- a/drivers/staging/wlan-ng/cfg80211.c +++ b/drivers/staging/wlan-ng/cfg80211.c @@ -70,7 +70,8 @@ static int prism2_result2err(int prism2_result) return err; } -static int prism2_domibset_uint32(struct wlandevice *wlandev, u32 did, u32 data) +static int prism2_domibset_uint32(struct wlandevice *wlandev, + u32 did, u32 data) { struct p80211msg_dot11req_mibset msg; struct p80211item_uint32 *mibitem = diff --git a/drivers/staging/wlan-ng/prism2fw.c b/drivers/staging/wlan-ng/prism2fw.c index bb572b7fdfee..94800c007162 100644 --- a/drivers/staging/wlan-ng/prism2fw.c +++ b/drivers/staging/wlan-ng/prism2fw.c @@ -556,10 +556,9 @@ static int mkimage(struct imgchunk *clist, unsigned int *ccnt) /* Allocate buffer space for chunks */ for (i = 0; i < *ccnt; i++) { clist[i].data = kzalloc(clist[i].len, GFP_KERNEL); - if (!clist[i].data) { - pr_err("failed to allocate image space, exiting.\n"); + if (!clist[i].data) return 1; - } + pr_debug("chunk[%d]: addr=0x%06x len=%d\n", i, clist[i].addr, clist[i].len); } diff --git a/drivers/staging/xgifb/Kconfig b/drivers/staging/xgifb/Kconfig deleted file mode 100644 index bb0ca5974ea0..000000000000 --- a/drivers/staging/xgifb/Kconfig +++ /dev/null @@ -1,11 +0,0 @@ -config FB_XGI - tristate "XGI display support" - depends on FB && PCI - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - help - This driver supports notebooks with XGI Z7,Z9,Z11 PCI chips. - Say Y if you have such a graphics card. - To compile this driver as a module, choose M here: the - module will be called xgifb.ko diff --git a/drivers/staging/xgifb/Makefile b/drivers/staging/xgifb/Makefile deleted file mode 100644 index 964a843c4521..000000000000 --- a/drivers/staging/xgifb/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -obj-$(CONFIG_FB_XGI) += xgifb.o - -xgifb-y := XGI_main_26.o vb_init.o vb_setmode.o - diff --git a/drivers/staging/xgifb/TODO b/drivers/staging/xgifb/TODO deleted file mode 100644 index 7eb99140a399..000000000000 --- a/drivers/staging/xgifb/TODO +++ /dev/null @@ -1,13 +0,0 @@ -This drivers still needs a lot of work. I can list all cleanups to do but it's -going to be long. So, I'm writing "cleanups" and not the list. - -Arnaud - -TODO: -- clean ups -- sort out dup ids with SiS driver -- remove useless/wrong/unused code... -- get rid of non-linux related stuff - -Please send patches to: -Arnaud Patard <arnaud.patard@rtp-net.org> diff --git a/drivers/staging/xgifb/XGI_main.h b/drivers/staging/xgifb/XGI_main.h deleted file mode 100644 index e19a8291cb2a..000000000000 --- a/drivers/staging/xgifb/XGI_main.h +++ /dev/null @@ -1,365 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef _XGIFB_MAIN -#define _XGIFB_MAIN -/* ------------------- Constant Definitions ------------------------- */ -#include "XGIfb.h" -#include "vb_def.h" - -#define PCI_DEVICE_ID_XGI_42 0x042 -#define PCI_DEVICE_ID_XGI_27 0x027 - -static const struct pci_device_id xgifb_pci_table[] = { - {PCI_DEVICE(PCI_VENDOR_ID_XGI, PCI_DEVICE_ID_XGI_20)}, - {PCI_DEVICE(PCI_VENDOR_ID_XGI, PCI_DEVICE_ID_XGI_27)}, - {PCI_DEVICE(PCI_VENDOR_ID_XGI, PCI_DEVICE_ID_XGI_40)}, - {PCI_DEVICE(PCI_VENDOR_ID_XGI, PCI_DEVICE_ID_XGI_42)}, - {0} -}; - -MODULE_DEVICE_TABLE(pci, xgifb_pci_table); - -#define IND_XGI_SCRATCH_REG_CR30 0x30 /* CRs */ -#define IND_XGI_SCRATCH_REG_CR31 0x31 -#define IND_XGI_SCRATCH_REG_CR32 0x32 -#define IND_XGI_SCRATCH_REG_CR33 0x33 -#define IND_XGI_LCD_PANEL 0x36 -#define IND_XGI_SCRATCH_REG_CR37 0x37 - -#define XGI_DRAM_SIZE_MASK 0xF0 /*SR14 */ -#define XGI_DRAM_SIZE_1MB 0x00 -#define XGI_DRAM_SIZE_2MB 0x01 -#define XGI_DRAM_SIZE_4MB 0x02 -#define XGI_DRAM_SIZE_8MB 0x03 -#define XGI_DRAM_SIZE_16MB 0x04 -#define XGI_DRAM_SIZE_32MB 0x05 -#define XGI_DRAM_SIZE_64MB 0x06 -#define XGI_DRAM_SIZE_128MB 0x07 -#define XGI_DRAM_SIZE_256MB 0x08 - -/* ------------------- Global Variables ----------------------------- */ - -/* display status */ -static int XGIfb_crt1off; -static int XGIfb_forcecrt1 = -1; - -/* global flags */ -static int XGIfb_tvmode; -static int enable_dstn; -static int XGIfb_ypan = -1; - -/* TW: CRT2 type (for overriding autodetection) */ -static int XGIfb_crt2type = -1; -/* PR: Tv plug type (for overriding autodetection) */ -static int XGIfb_tvplug = -1; - -#define MD_XGI315 1 - -/* mode table */ -static const struct _XGIbios_mode { - u8 mode_no; - u16 vesa_mode_no_1; /* "XGI defined" VESA mode number */ - u16 vesa_mode_no_2; /* Real VESA mode numbers */ - u16 xres; - u16 yres; - u16 bpp; - u8 chipset; -} XGIbios_mode[] = { - { 0x56, 0x0000, 0x0000, 320, 240, 16, MD_XGI315 }, - { 0x5A, 0x0000, 0x0000, 320, 480, 8, MD_XGI315 }, - { 0x5B, 0x0000, 0x0000, 320, 480, 16, MD_XGI315 }, - { 0x2E, 0x0101, 0x0101, 640, 480, 8, MD_XGI315 }, - { 0x44, 0x0111, 0x0111, 640, 480, 16, MD_XGI315 }, - { 0x62, 0x013a, 0x0112, 640, 480, 32, MD_XGI315 }, - { 0x31, 0x0000, 0x0000, 720, 480, 8, MD_XGI315 }, - { 0x33, 0x0000, 0x0000, 720, 480, 16, MD_XGI315 }, - { 0x35, 0x0000, 0x0000, 720, 480, 32, MD_XGI315 }, - { 0x32, 0x0000, 0x0000, 720, 576, 8, MD_XGI315 }, - { 0x34, 0x0000, 0x0000, 720, 576, 16, MD_XGI315 }, - { 0x36, 0x0000, 0x0000, 720, 576, 32, MD_XGI315 }, - { 0x36, 0x0000, 0x0000, 720, 576, 32, MD_XGI315 }, - { 0x70, 0x0000, 0x0000, 800, 480, 8, MD_XGI315 }, - { 0x7a, 0x0000, 0x0000, 800, 480, 16, MD_XGI315 }, - { 0x76, 0x0000, 0x0000, 800, 480, 32, MD_XGI315 }, - { 0x30, 0x0103, 0x0103, 800, 600, 8, MD_XGI315 }, -#define DEFAULT_MODE 17 /* index for 800x600x16 */ - { 0x47, 0x0114, 0x0114, 800, 600, 16, MD_XGI315 }, - { 0x63, 0x013b, 0x0115, 800, 600, 32, MD_XGI315 }, - { 0x71, 0x0000, 0x0000, 1024, 576, 8, MD_XGI315 }, - { 0x74, 0x0000, 0x0000, 1024, 576, 16, MD_XGI315 }, - { 0x77, 0x0000, 0x0000, 1024, 576, 32, MD_XGI315 }, - { 0x77, 0x0000, 0x0000, 1024, 576, 32, MD_XGI315 }, - { 0x20, 0x0000, 0x0000, 1024, 600, 8, }, - { 0x21, 0x0000, 0x0000, 1024, 600, 16, }, - { 0x22, 0x0000, 0x0000, 1024, 600, 32, }, - { 0x38, 0x0105, 0x0105, 1024, 768, 8, MD_XGI315 }, - { 0x4A, 0x0117, 0x0117, 1024, 768, 16, MD_XGI315 }, - { 0x64, 0x013c, 0x0118, 1024, 768, 32, MD_XGI315 }, - { 0x64, 0x013c, 0x0118, 1024, 768, 32, MD_XGI315 }, - { 0x23, 0x0000, 0x0000, 1152, 768, 8, }, - { 0x24, 0x0000, 0x0000, 1152, 768, 16, }, - { 0x25, 0x0000, 0x0000, 1152, 768, 32, }, - { 0x79, 0x0000, 0x0000, 1280, 720, 8, MD_XGI315 }, - { 0x75, 0x0000, 0x0000, 1280, 720, 16, MD_XGI315 }, - { 0x78, 0x0000, 0x0000, 1280, 720, 32, MD_XGI315 }, - { 0x23, 0x0000, 0x0000, 1280, 768, 8, MD_XGI315 }, - { 0x24, 0x0000, 0x0000, 1280, 768, 16, MD_XGI315 }, - { 0x25, 0x0000, 0x0000, 1280, 768, 32, MD_XGI315 }, - { 0x7C, 0x0000, 0x0000, 1280, 960, 8, MD_XGI315 }, - { 0x7D, 0x0000, 0x0000, 1280, 960, 16, MD_XGI315 }, - { 0x7E, 0x0000, 0x0000, 1280, 960, 32, MD_XGI315 }, - { 0x3A, 0x0107, 0x0107, 1280, 1024, 8, MD_XGI315 }, - { 0x4D, 0x011a, 0x011a, 1280, 1024, 16, MD_XGI315 }, - { 0x65, 0x013d, 0x011b, 1280, 1024, 32, MD_XGI315 }, - { 0x26, 0x0000, 0x0000, 1400, 1050, 8, MD_XGI315 }, - { 0x27, 0x0000, 0x0000, 1400, 1050, 16, MD_XGI315 }, - { 0x28, 0x0000, 0x0000, 1400, 1050, 32, MD_XGI315 }, - { 0x3C, 0x0130, 0x011c, 1600, 1200, 8, MD_XGI315 }, - { 0x3D, 0x0131, 0x011e, 1600, 1200, 16, MD_XGI315 }, - { 0x66, 0x013e, 0x011f, 1600, 1200, 32, MD_XGI315 }, - { 0x68, 0x013f, 0x0000, 1920, 1440, 8, MD_XGI315 }, - { 0x69, 0x0140, 0x0000, 1920, 1440, 16, MD_XGI315 }, - { 0x6B, 0x0141, 0x0000, 1920, 1440, 32, MD_XGI315 }, - { 0x6c, 0x0000, 0x0000, 2048, 1536, 8, MD_XGI315 }, - { 0x6d, 0x0000, 0x0000, 2048, 1536, 16, MD_XGI315 }, - { 0x6e, 0x0000, 0x0000, 2048, 1536, 32, MD_XGI315 }, - { 0 }, -}; - -static const unsigned short XGI310paneltype[] = { - LCD_UNKNOWN, LCD_800x600, LCD_1024x768, LCD_1280x1024, - LCD_640x480, LCD_1024x600, LCD_1152x864, LCD_1280x960, - LCD_1152x768, LCD_1400x1050, LCD_1280x768, LCD_1600x1200, - LCD_1024x768, LCD_1024x768, LCD_1024x768}; - -static const struct _XGI_crt2type { - char name[10]; - int type_no; - int tvplug_no; -} XGI_crt2type[] = { - {"NONE", 0, -1}, - {"LCD", XGIFB_DISP_LCD, -1}, - {"TV", XGIFB_DISP_TV, -1}, - {"VGA", XGIFB_DISP_CRT, -1}, - {"SVIDEO", XGIFB_DISP_TV, TVPLUG_SVIDEO}, - {"COMPOSITE", XGIFB_DISP_TV, TVPLUG_COMPOSITE}, - {"SCART", XGIFB_DISP_TV, TVPLUG_SCART}, - {"none", 0, -1}, - {"lcd", XGIFB_DISP_LCD, -1}, - {"tv", XGIFB_DISP_TV, -1}, - {"vga", XGIFB_DISP_CRT, -1}, - {"svideo", XGIFB_DISP_TV, TVPLUG_SVIDEO}, - {"composite", XGIFB_DISP_TV, TVPLUG_COMPOSITE}, - {"scart", XGIFB_DISP_TV, TVPLUG_SCART}, - {"\0", -1, -1} -}; - -/* TV standard */ -static const struct _XGI_tvtype { - char name[6]; - int type_no; -} XGI_tvtype[] = { - {"PAL", 1}, - {"NTSC", 2}, - {"pal", 1}, - {"ntsc", 2}, - {"\0", -1} -}; - -static const struct _XGI_vrate { - u16 idx; - u16 xres; - u16 yres; - u16 refresh; -} XGIfb_vrate[] = { - {1, 640, 480, 60}, {2, 640, 480, 72}, - {3, 640, 480, 75}, {4, 640, 480, 85}, - - {5, 640, 480, 100}, {6, 640, 480, 120}, - {7, 640, 480, 160}, {8, 640, 480, 200}, - - {1, 720, 480, 60}, - {1, 720, 576, 58}, - {1, 800, 480, 60}, {2, 800, 480, 75}, {3, 800, 480, 85}, - {1, 800, 600, 60}, {2, 800, 600, 72}, {3, 800, 600, 75}, - {4, 800, 600, 85}, {5, 800, 600, 100}, - {6, 800, 600, 120}, {7, 800, 600, 160}, - - {1, 1024, 768, 60}, {2, 1024, 768, 70}, {3, 1024, 768, 75}, - {4, 1024, 768, 85}, {5, 1024, 768, 100}, {6, 1024, 768, 120}, - {1, 1024, 576, 60}, {2, 1024, 576, 75}, {3, 1024, 576, 85}, - {1, 1024, 600, 60}, - {1, 1152, 768, 60}, - {1, 1280, 720, 60}, {2, 1280, 720, 75}, {3, 1280, 720, 85}, - {1, 1280, 768, 60}, - {1, 1280, 1024, 60}, {2, 1280, 1024, 75}, {3, 1280, 1024, 85}, - {1, 1280, 960, 70}, - {1, 1400, 1050, 60}, - {1, 1600, 1200, 60}, {2, 1600, 1200, 65}, - {3, 1600, 1200, 70}, {4, 1600, 1200, 75}, - - {5, 1600, 1200, 85}, {6, 1600, 1200, 100}, - {7, 1600, 1200, 120}, - - {1, 1920, 1440, 60}, {2, 1920, 1440, 65}, - {3, 1920, 1440, 70}, {4, 1920, 1440, 75}, - - {5, 1920, 1440, 85}, {6, 1920, 1440, 100}, - {1, 2048, 1536, 60}, {2, 2048, 1536, 65}, - {3, 2048, 1536, 70}, {4, 2048, 1536, 75}, - - {5, 2048, 1536, 85}, - {0, 0, 0, 0} -}; - -static const struct _XGI_TV_filter { - u8 filter[9][4]; -} XGI_TV_filter[] = { - { { {0x00, 0x00, 0x00, 0x40}, /* NTSCFilter_0 */ - {0x00, 0xE0, 0x10, 0x60}, - {0x00, 0xEE, 0x10, 0x44}, - {0x00, 0xF4, 0x10, 0x38}, - {0xF8, 0xF4, 0x18, 0x38}, - {0xFC, 0xFB, 0x14, 0x2A}, - {0x00, 0x00, 0x10, 0x20}, - {0x00, 0x04, 0x10, 0x18}, - {0xFF, 0xFF, 0xFF, 0xFF} } }, - { { {0x00, 0x00, 0x00, 0x40}, /* NTSCFilter_1 */ - {0x00, 0xE0, 0x10, 0x60}, - {0x00, 0xEE, 0x10, 0x44}, - {0x00, 0xF4, 0x10, 0x38}, - {0xF8, 0xF4, 0x18, 0x38}, - {0xFC, 0xFB, 0x14, 0x2A}, - {0x00, 0x00, 0x10, 0x20}, - {0x00, 0x04, 0x10, 0x18}, - {0xFF, 0xFF, 0xFF, 0xFF} } }, - { { {0x00, 0x00, 0x00, 0x40}, /* NTSCFilter_2 */ - {0xF5, 0xEE, 0x1B, 0x44}, - {0xF8, 0xF4, 0x18, 0x38}, - {0xEB, 0x04, 0x25, 0x18}, - {0xF1, 0x05, 0x1F, 0x16}, - {0xF6, 0x06, 0x1A, 0x14}, - {0xFA, 0x06, 0x16, 0x14}, - {0x00, 0x04, 0x10, 0x18}, - {0xFF, 0xFF, 0xFF, 0xFF} } }, - { { {0x00, 0x00, 0x00, 0x40}, /* NTSCFilter_3 */ - {0xF1, 0x04, 0x1F, 0x18}, - {0xEE, 0x0D, 0x22, 0x06}, - {0xF7, 0x06, 0x19, 0x14}, - {0xF4, 0x0B, 0x1C, 0x0A}, - {0xFA, 0x07, 0x16, 0x12}, - {0xF9, 0x0A, 0x17, 0x0C}, - {0x00, 0x07, 0x10, 0x12}, - {0xFF, 0xFF, 0xFF, 0xFF} } }, - { { {0x00, 0x00, 0x00, 0x40}, /* NTSCFilter_4 */ - {0x00, 0xE0, 0x10, 0x60}, - {0x00, 0xEE, 0x10, 0x44}, - {0x00, 0xF4, 0x10, 0x38}, - {0xF8, 0xF4, 0x18, 0x38}, - {0xFC, 0xFB, 0x14, 0x2A}, - {0x00, 0x00, 0x10, 0x20}, - {0x00, 0x04, 0x10, 0x18}, - {0xFF, 0xFF, 0xFF, 0xFF} } }, - { { {0x00, 0x00, 0x00, 0x40}, /* NTSCFilter_5 */ - {0xF5, 0xEE, 0x1B, 0x44}, - {0xF8, 0xF4, 0x18, 0x38}, - {0xEB, 0x04, 0x25, 0x18}, - {0xF1, 0x05, 0x1F, 0x16}, - {0xF6, 0x06, 0x1A, 0x14}, - {0xFA, 0x06, 0x16, 0x14}, - {0x00, 0x04, 0x10, 0x18}, - {0xFF, 0xFF, 0xFF, 0xFF} } }, - { { {0x00, 0x00, 0x00, 0x40}, /* NTSCFilter_6 */ - {0xEB, 0x04, 0x25, 0x18}, - {0xE7, 0x0E, 0x29, 0x04}, - {0xEE, 0x0C, 0x22, 0x08}, - {0xF6, 0x0B, 0x1A, 0x0A}, - {0xF9, 0x0A, 0x17, 0x0C}, - {0xFC, 0x0A, 0x14, 0x0C}, - {0x00, 0x08, 0x10, 0x10}, - {0xFF, 0xFF, 0xFF, 0xFF} } }, - { { {0x00, 0x00, 0x00, 0x40}, /* NTSCFilter_7 */ - {0xEC, 0x02, 0x24, 0x1C}, - {0xF2, 0x04, 0x1E, 0x18}, - {0xEB, 0x15, 0x25, 0xF6}, - {0xF4, 0x10, 0x1C, 0x00}, - {0xF8, 0x0F, 0x18, 0x02}, - {0x00, 0x04, 0x10, 0x18}, - {0x01, 0x06, 0x0F, 0x14}, - {0xFF, 0xFF, 0xFF, 0xFF} } }, - { { {0x00, 0x00, 0x00, 0x40}, /* PALFilter_0 */ - {0x00, 0xE0, 0x10, 0x60}, - {0x00, 0xEE, 0x10, 0x44}, - {0x00, 0xF4, 0x10, 0x38}, - {0xF8, 0xF4, 0x18, 0x38}, - {0xFC, 0xFB, 0x14, 0x2A}, - {0x00, 0x00, 0x10, 0x20}, - {0x00, 0x04, 0x10, 0x18}, - {0xFF, 0xFF, 0xFF, 0xFF} } }, - { { {0x00, 0x00, 0x00, 0x40}, /* PALFilter_1 */ - {0x00, 0xE0, 0x10, 0x60}, - {0x00, 0xEE, 0x10, 0x44}, - {0x00, 0xF4, 0x10, 0x38}, - {0xF8, 0xF4, 0x18, 0x38}, - {0xFC, 0xFB, 0x14, 0x2A}, - {0x00, 0x00, 0x10, 0x20}, - {0x00, 0x04, 0x10, 0x18}, - {0xFF, 0xFF, 0xFF, 0xFF} } }, - { { {0x00, 0x00, 0x00, 0x40}, /* PALFilter_2 */ - {0xF5, 0xEE, 0x1B, 0x44}, - {0xF8, 0xF4, 0x18, 0x38}, - {0xF1, 0xF7, 0x01, 0x32}, - {0xF5, 0xFB, 0x1B, 0x2A}, - {0xF9, 0xFF, 0x17, 0x22}, - {0xFB, 0x01, 0x15, 0x1E}, - {0x00, 0x04, 0x10, 0x18}, - {0xFF, 0xFF, 0xFF, 0xFF} } }, - { { {0x00, 0x00, 0x00, 0x40}, /* PALFilter_3 */ - {0xF5, 0xFB, 0x1B, 0x2A}, - {0xEE, 0xFE, 0x22, 0x24}, - {0xF3, 0x00, 0x1D, 0x20}, - {0xF9, 0x03, 0x17, 0x1A}, - {0xFB, 0x02, 0x14, 0x1E}, - {0xFB, 0x04, 0x15, 0x18}, - {0x00, 0x06, 0x10, 0x14}, - {0xFF, 0xFF, 0xFF, 0xFF} } }, - { { {0x00, 0x00, 0x00, 0x40}, /* PALFilter_4 */ - {0x00, 0xE0, 0x10, 0x60}, - {0x00, 0xEE, 0x10, 0x44}, - {0x00, 0xF4, 0x10, 0x38}, - {0xF8, 0xF4, 0x18, 0x38}, - {0xFC, 0xFB, 0x14, 0x2A}, - {0x00, 0x00, 0x10, 0x20}, - {0x00, 0x04, 0x10, 0x18}, - {0xFF, 0xFF, 0xFF, 0xFF} } }, - { { {0x00, 0x00, 0x00, 0x40}, /* PALFilter_5 */ - {0xF5, 0xEE, 0x1B, 0x44}, - {0xF8, 0xF4, 0x18, 0x38}, - {0xF1, 0xF7, 0x1F, 0x32}, - {0xF5, 0xFB, 0x1B, 0x2A}, - {0xF9, 0xFF, 0x17, 0x22}, - {0xFB, 0x01, 0x15, 0x1E}, - {0x00, 0x04, 0x10, 0x18}, - {0xFF, 0xFF, 0xFF, 0xFF} } }, - { { {0x00, 0x00, 0x00, 0x40}, /* PALFilter_6 */ - {0xF5, 0xEE, 0x1B, 0x2A}, - {0xEE, 0xFE, 0x22, 0x24}, - {0xF3, 0x00, 0x1D, 0x20}, - {0xF9, 0x03, 0x17, 0x1A}, - {0xFB, 0x02, 0x14, 0x1E}, - {0xFB, 0x04, 0x15, 0x18}, - {0x00, 0x06, 0x10, 0x14}, - {0xFF, 0xFF, 0xFF, 0xFF} } }, - { { {0x00, 0x00, 0x00, 0x40}, /* PALFilter_7 */ - {0xF5, 0xEE, 0x1B, 0x44}, - {0xF8, 0xF4, 0x18, 0x38}, - {0xFC, 0xFB, 0x14, 0x2A}, - {0xEB, 0x05, 0x25, 0x16}, - {0xF1, 0x05, 0x1F, 0x16}, - {0xFA, 0x07, 0x16, 0x12}, - {0x00, 0x07, 0x10, 0x12}, - {0xFF, 0xFF, 0xFF, 0xFF} } } -}; - -static int filter = -1; - -#endif diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c deleted file mode 100644 index 217c6bb82c0d..000000000000 --- a/drivers/staging/xgifb/XGI_main_26.c +++ /dev/null @@ -1,2084 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * XG20, XG21, XG40, XG42 frame buffer device - * for Linux kernels 2.5.x, 2.6.x - * Base on TW's sis fbdev code. - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include <linux/sizes.h> -#include <linux/module.h> -#include <linux/pci.h> - -#include "XGI_main.h" -#include "vb_init.h" -#include "vb_util.h" -#include "vb_setmode.h" - -#define Index_CR_GPIO_Reg1 0x48 -#define Index_CR_GPIO_Reg3 0x4a - -#define GPIOG_EN BIT(6) -#define GPIOG_READ BIT(1) - -static char *forcecrt2type; -static char *mode; -static int vesa = -1; -static unsigned int refresh_rate; - -/* -------------------- Macro definitions ---------------------------- */ - -#ifdef DEBUG -static void dumpVGAReg(struct xgifb_video_info *xgifb_info) -{ - struct vb_device_info *vb = &xgifb_info->dev_info; - u8 i, reg; - - xgifb_reg_set(vb->P3c4, 0x05, 0x86); - - for (i = 0; i < 0x4f; i++) { - reg = xgifb_reg_get(vb->P3c4, i); - pr_debug("o 3c4 %x\n", i); - pr_debug("i 3c5 => %x\n", reg); - } - - for (i = 0; i < 0xF0; i++) { - reg = xgifb_reg_get(vb->P3d4, i); - pr_debug("o 3d4 %x\n", i); - pr_debug("i 3d5 => %x\n", reg); - } -} -#else -static inline void dumpVGAReg(struct xgifb_video_info *xgifb_info) -{ -} -#endif - -/* --------------- Hardware Access Routines -------------------------- */ - -static int XGIfb_mode_rate_to_dclock(struct vb_device_info *XGI_Pr, - struct xgi_hw_device_info *HwDeviceExtension, - unsigned char modeno) -{ - unsigned short ModeNo = modeno; - unsigned short ModeIdIndex = 0, ClockIndex = 0; - unsigned short RefreshRateTableIndex = 0; - - InitTo330Pointer(HwDeviceExtension->jChipType, XGI_Pr); - - XGI_SearchModeID(ModeNo, &ModeIdIndex); - - RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo, - ModeIdIndex, XGI_Pr); - - ClockIndex = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; - - return XGI_VCLKData[ClockIndex].CLOCK * 1000; -} - -static int XGIfb_mode_rate_to_ddata(struct vb_device_info *XGI_Pr, - struct xgi_hw_device_info *HwDeviceExtension, - unsigned char modeno, u32 *left_margin, - u32 *right_margin, u32 *upper_margin, - u32 *lower_margin, u32 *hsync_len, - u32 *vsync_len, u32 *sync, u32 *vmode) -{ - unsigned short ModeNo = modeno; - unsigned short ModeIdIndex, index = 0; - unsigned short RefreshRateTableIndex = 0; - - unsigned short VRE, VBE, VRS, VDE; - unsigned short HRE, HBE, HRS, HDE; - unsigned char sr_data, cr_data, cr_data2; - int B, C, D, F, temp, j; - - InitTo330Pointer(HwDeviceExtension->jChipType, XGI_Pr); - if (!XGI_SearchModeID(ModeNo, &ModeIdIndex)) - return 0; - RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo, - ModeIdIndex, XGI_Pr); - index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; - - sr_data = XGI_CRT1Table[index].CR[5]; - - HDE = XGI330_RefIndex[RefreshRateTableIndex].XRes >> 3; - - cr_data = XGI_CRT1Table[index].CR[3]; - - /* Horizontal retrace (=sync) start */ - HRS = (cr_data & 0xff) | ((unsigned short)(sr_data & 0xC0) << 2); - F = HRS - HDE - 3; - - sr_data = XGI_CRT1Table[index].CR[6]; - - cr_data = XGI_CRT1Table[index].CR[2]; - - cr_data2 = XGI_CRT1Table[index].CR[4]; - - /* Horizontal blank end */ - HBE = (cr_data & 0x1f) | ((unsigned short)(cr_data2 & 0x80) >> 2) - | ((unsigned short)(sr_data & 0x03) << 6); - - /* Horizontal retrace (=sync) end */ - HRE = (cr_data2 & 0x1f) | ((sr_data & 0x04) << 3); - - temp = HBE - ((HDE - 1) & 255); - B = (temp > 0) ? temp : (temp + 256); - - temp = HRE - ((HDE + F + 3) & 63); - C = (temp > 0) ? temp : (temp + 64); - - D = B - F - C; - - *left_margin = D * 8; - *right_margin = F * 8; - *hsync_len = C * 8; - - sr_data = XGI_CRT1Table[index].CR[14]; - - cr_data2 = XGI_CRT1Table[index].CR[9]; - - VDE = XGI330_RefIndex[RefreshRateTableIndex].YRes; - - cr_data = XGI_CRT1Table[index].CR[10]; - - /* Vertical retrace (=sync) start */ - VRS = (cr_data & 0xff) | ((unsigned short)(cr_data2 & 0x04) << 6) - | ((unsigned short)(cr_data2 & 0x80) << 2) - | ((unsigned short)(sr_data & 0x08) << 7); - F = VRS + 1 - VDE; - - cr_data = XGI_CRT1Table[index].CR[13]; - - /* Vertical blank end */ - VBE = (cr_data & 0xff) | ((unsigned short)(sr_data & 0x10) << 4); - temp = VBE - ((VDE - 1) & 511); - B = (temp > 0) ? temp : (temp + 512); - - cr_data = XGI_CRT1Table[index].CR[11]; - - /* Vertical retrace (=sync) end */ - VRE = (cr_data & 0x0f) | ((sr_data & 0x20) >> 1); - temp = VRE - ((VDE + F - 1) & 31); - C = (temp > 0) ? temp : (temp + 32); - - D = B - F - C; - - *upper_margin = D; - *lower_margin = F; - *vsync_len = C; - - if (XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x8000) - *sync &= ~FB_SYNC_VERT_HIGH_ACT; - else - *sync |= FB_SYNC_VERT_HIGH_ACT; - - if (XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x4000) - *sync &= ~FB_SYNC_HOR_HIGH_ACT; - else - *sync |= FB_SYNC_HOR_HIGH_ACT; - - *vmode = FB_VMODE_NONINTERLACED; - if (XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x0080) { - *vmode = FB_VMODE_INTERLACED; - } else { - j = 0; - while (XGI330_EModeIDTable[j].Ext_ModeID != 0xff) { - if (XGI330_EModeIDTable[j].Ext_ModeID == - XGI330_RefIndex[RefreshRateTableIndex].ModeID) { - if (XGI330_EModeIDTable[j].Ext_ModeFlag & - DoubleScanMode) { - *vmode = FB_VMODE_DOUBLE; - } - break; - } - j++; - } - } - - return 1; -} - -void XGIRegInit(struct vb_device_info *XGI_Pr, unsigned long BaseAddr) -{ - XGI_Pr->P3c4 = BaseAddr + 0x14; - XGI_Pr->P3d4 = BaseAddr + 0x24; - XGI_Pr->P3c0 = BaseAddr + 0x10; - XGI_Pr->P3ce = BaseAddr + 0x1e; - XGI_Pr->P3c2 = BaseAddr + 0x12; - XGI_Pr->P3cc = BaseAddr + 0x1c; - XGI_Pr->P3ca = BaseAddr + 0x1a; - XGI_Pr->P3c6 = BaseAddr + 0x16; - XGI_Pr->P3c7 = BaseAddr + 0x17; - XGI_Pr->P3c8 = BaseAddr + 0x18; - XGI_Pr->P3c9 = BaseAddr + 0x19; - XGI_Pr->P3da = BaseAddr + 0x2A; - XGI_Pr->Part0Port = BaseAddr + XGI_CRT2_PORT_00; - /* Digital video interface registers (LCD) */ - XGI_Pr->Part1Port = BaseAddr + SIS_CRT2_PORT_04; - /* 301 TV Encoder registers */ - XGI_Pr->Part2Port = BaseAddr + SIS_CRT2_PORT_10; - /* 301 Macrovision registers */ - XGI_Pr->Part3Port = BaseAddr + SIS_CRT2_PORT_12; - /* 301 VGA2 (and LCD) registers */ - XGI_Pr->Part4Port = BaseAddr + SIS_CRT2_PORT_14; - /* 301 palette address port registers */ - XGI_Pr->Part5Port = BaseAddr + SIS_CRT2_PORT_14 + 2; -} - -/* ------------------ Internal helper routines ----------------- */ - -static int XGIfb_GetXG21DefaultLVDSModeIdx(struct xgifb_video_info *xgifb_info) -{ - int i = 0; - - while ((XGIbios_mode[i].mode_no != 0) && - (XGIbios_mode[i].xres <= xgifb_info->lvds_data.LVDSHDE)) { - if ((XGIbios_mode[i].xres == xgifb_info->lvds_data.LVDSHDE) && - (XGIbios_mode[i].yres == xgifb_info->lvds_data.LVDSVDE) && - (XGIbios_mode[i].bpp == 8)) { - return i; - } - i++; - } - - return -1; -} - -static void XGIfb_search_mode(struct xgifb_video_info *xgifb_info, - const char *name) -{ - unsigned int xres; - unsigned int yres; - unsigned int bpp; - int i; - - if (sscanf(name, "%ux%ux%u", &xres, &yres, &bpp) != 3) - goto invalid_mode; - - if (bpp == 24) - bpp = 32; /* That's for people who mix up color and fb depth. */ - - for (i = 0; XGIbios_mode[i].mode_no != 0; i++) - if (XGIbios_mode[i].xres == xres && - XGIbios_mode[i].yres == yres && - XGIbios_mode[i].bpp == bpp) { - xgifb_info->mode_idx = i; - return; - } -invalid_mode: - pr_info("Invalid mode '%s'\n", name); -} - -static void XGIfb_search_vesamode(struct xgifb_video_info *xgifb_info, - unsigned int vesamode) -{ - int i = 0; - - if (vesamode == 0) - goto invalid; - - vesamode &= 0x1dff; /* Clean VESA mode number from other flags */ - - while (XGIbios_mode[i].mode_no != 0) { - if ((XGIbios_mode[i].vesa_mode_no_1 == vesamode) || - (XGIbios_mode[i].vesa_mode_no_2 == vesamode)) { - xgifb_info->mode_idx = i; - return; - } - i++; - } - -invalid: - pr_info("Invalid VESA mode 0x%x'\n", vesamode); -} - -static int XGIfb_validate_mode(struct xgifb_video_info *xgifb_info, int myindex) -{ - u16 xres, yres; - struct xgi_hw_device_info *hw_info = &xgifb_info->hw_info; - unsigned long required_mem; - - if (xgifb_info->chip == XG21) { - if (xgifb_info->display2 == XGIFB_DISP_LCD) { - xres = xgifb_info->lvds_data.LVDSHDE; - yres = xgifb_info->lvds_data.LVDSVDE; - if (XGIbios_mode[myindex].xres > xres) - return -1; - if (XGIbios_mode[myindex].yres > yres) - return -1; - if ((XGIbios_mode[myindex].xres < xres) && - (XGIbios_mode[myindex].yres < yres)) { - if (XGIbios_mode[myindex].bpp > 8) - return -1; - } - } - goto check_memory; - } - - /* FIXME: for now, all is valid on XG27 */ - if (xgifb_info->chip == XG27) - goto check_memory; - - if (!(XGIbios_mode[myindex].chipset & MD_XGI315)) - return -1; - - switch (xgifb_info->display2) { - case XGIFB_DISP_LCD: - switch (hw_info->ulCRT2LCDType) { - case LCD_640x480: - xres = 640; - yres = 480; - break; - case LCD_800x600: - xres = 800; - yres = 600; - break; - case LCD_1024x600: - xres = 1024; - yres = 600; - break; - case LCD_1024x768: - xres = 1024; - yres = 768; - break; - case LCD_1152x768: - xres = 1152; - yres = 768; - break; - case LCD_1280x960: - xres = 1280; - yres = 960; - break; - case LCD_1280x768: - xres = 1280; - yres = 768; - break; - case LCD_1280x1024: - xres = 1280; - yres = 1024; - break; - case LCD_1400x1050: - xres = 1400; - yres = 1050; - break; - case LCD_1600x1200: - xres = 1600; - yres = 1200; - break; - default: - xres = 0; - yres = 0; - break; - } - if (XGIbios_mode[myindex].xres > xres) - return -1; - if (XGIbios_mode[myindex].yres > yres) - return -1; - if ((hw_info->ulExternalChip == 0x01) || /* LVDS */ - (hw_info->ulExternalChip == 0x05)) { /* LVDS+Chrontel */ - switch (XGIbios_mode[myindex].xres) { - case 512: - if (XGIbios_mode[myindex].yres != 512) - return -1; - if (hw_info->ulCRT2LCDType == LCD_1024x600) - return -1; - break; - case 640: - if ((XGIbios_mode[myindex].yres != 400) && - (XGIbios_mode[myindex].yres != 480)) - return -1; - break; - case 800: - if (XGIbios_mode[myindex].yres != 600) - return -1; - break; - case 1024: - if ((XGIbios_mode[myindex].yres != 600) && - (XGIbios_mode[myindex].yres != 768)) - return -1; - if ((XGIbios_mode[myindex].yres == 600) && - (hw_info->ulCRT2LCDType != LCD_1024x600)) - return -1; - break; - case 1152: - if ((XGIbios_mode[myindex].yres) != 768) - return -1; - if (hw_info->ulCRT2LCDType != LCD_1152x768) - return -1; - break; - case 1280: - if ((XGIbios_mode[myindex].yres != 768) && - (XGIbios_mode[myindex].yres != 1024)) - return -1; - if ((XGIbios_mode[myindex].yres == 768) && - (hw_info->ulCRT2LCDType != LCD_1280x768)) - return -1; - break; - case 1400: - if (XGIbios_mode[myindex].yres != 1050) - return -1; - break; - case 1600: - if (XGIbios_mode[myindex].yres != 1200) - return -1; - break; - default: - return -1; - } - } else { - switch (XGIbios_mode[myindex].xres) { - case 512: - if (XGIbios_mode[myindex].yres != 512) - return -1; - break; - case 640: - if ((XGIbios_mode[myindex].yres != 400) && - (XGIbios_mode[myindex].yres != 480)) - return -1; - break; - case 800: - if (XGIbios_mode[myindex].yres != 600) - return -1; - break; - case 1024: - if (XGIbios_mode[myindex].yres != 768) - return -1; - break; - case 1280: - if ((XGIbios_mode[myindex].yres != 960) && - (XGIbios_mode[myindex].yres != 1024)) - return -1; - if (XGIbios_mode[myindex].yres == 960) { - if (hw_info->ulCRT2LCDType == - LCD_1400x1050) - return -1; - } - break; - case 1400: - if (XGIbios_mode[myindex].yres != 1050) - return -1; - break; - case 1600: - if (XGIbios_mode[myindex].yres != 1200) - return -1; - break; - default: - return -1; - } - } - break; - case XGIFB_DISP_TV: - switch (XGIbios_mode[myindex].xres) { - case 512: - case 640: - case 800: - break; - case 720: - if (xgifb_info->TV_type == TVMODE_NTSC) { - if (XGIbios_mode[myindex].yres != 480) - return -1; - } else if (xgifb_info->TV_type == TVMODE_PAL) { - if (XGIbios_mode[myindex].yres != 576) - return -1; - } - /* LVDS/CHRONTEL does not support 720 */ - if (xgifb_info->hasVB == HASVB_LVDS_CHRONTEL || - xgifb_info->hasVB == HASVB_CHRONTEL) { - return -1; - } - break; - case 1024: - if (xgifb_info->TV_type == TVMODE_NTSC) { - if (XGIbios_mode[myindex].bpp == 32) - return -1; - } - break; - default: - return -1; - } - break; - case XGIFB_DISP_CRT: - if (XGIbios_mode[myindex].xres > 1280) - return -1; - break; - case XGIFB_DISP_NONE: - break; - } - -check_memory: - required_mem = XGIbios_mode[myindex].xres * XGIbios_mode[myindex].yres * - XGIbios_mode[myindex].bpp / 8; - if (required_mem > xgifb_info->video_size) - return -1; - return myindex; -} - -static void XGIfb_search_crt2type(const char *name) -{ - int i = 0; - - if (!name) - return; - - while (XGI_crt2type[i].type_no != -1) { - if (!strcmp(name, XGI_crt2type[i].name)) { - XGIfb_crt2type = XGI_crt2type[i].type_no; - XGIfb_tvplug = XGI_crt2type[i].tvplug_no; - break; - } - i++; - } - if (XGIfb_crt2type < 0) - pr_info("Invalid CRT2 type: %s\n", name); -} - -static u8 XGIfb_search_refresh_rate(struct xgifb_video_info *xgifb_info, - unsigned int rate) -{ - u16 xres, yres; - int i = 0; - - xres = XGIbios_mode[xgifb_info->mode_idx].xres; - yres = XGIbios_mode[xgifb_info->mode_idx].yres; - - xgifb_info->rate_idx = 0; - - while (XGIfb_vrate[i].idx != 0 && XGIfb_vrate[i].xres <= xres) { - /* Skip values with xres or yres less than specified */ - if ((XGIfb_vrate[i].yres != yres) || - (XGIfb_vrate[i].xres != xres)) { - i++; - continue; - } - if (XGIfb_vrate[i].refresh == rate) { - xgifb_info->rate_idx = XGIfb_vrate[i].idx; - break; - } else if (XGIfb_vrate[i].refresh > rate) { - if (XGIfb_vrate[i].refresh - rate <= 3) { - pr_debug("Adjusting rate from %d up to %d\n", - rate, XGIfb_vrate[i].refresh); - xgifb_info->rate_idx = XGIfb_vrate[i].idx; - xgifb_info->refresh_rate = - XGIfb_vrate[i].refresh; - } else if ((XGIfb_vrate[i].idx != 1) && - (rate - XGIfb_vrate[i - 1].refresh <= 2)) { - pr_debug("Adjusting rate from %d down to %d\n", - rate, XGIfb_vrate[i - 1].refresh); - xgifb_info->rate_idx = XGIfb_vrate[i - 1].idx; - xgifb_info->refresh_rate = - XGIfb_vrate[i - 1].refresh; - } - break; - } else if (rate - XGIfb_vrate[i].refresh <= 2) { - pr_debug("Adjusting rate from %d down to %d\n", - rate, XGIfb_vrate[i].refresh); - xgifb_info->rate_idx = XGIfb_vrate[i].idx; - break; - } - i++; - } - - if (xgifb_info->rate_idx > 0) - return xgifb_info->rate_idx; - pr_info("Unsupported rate %d for %dx%d\n", - rate, xres, yres); - return 0; -} - -static void XGIfb_search_tvstd(const char *name) -{ - int i = 0; - - if (!name) - return; - - while (XGI_tvtype[i].type_no != -1) { - if (!strcmp(name, XGI_tvtype[i].name)) { - XGIfb_tvmode = XGI_tvtype[i].type_no; - break; - } - i++; - } -} - -/* ----------- FBDev related routines for all series ----------- */ - -static void XGIfb_bpp_to_var(struct xgifb_video_info *xgifb_info, - struct fb_var_screeninfo *var) -{ - switch (var->bits_per_pixel) { - case 8: - var->red.offset = 0; - var->green.offset = 0; - var->blue.offset = 0; - var->red.length = 6; - var->green.length = 6; - var->blue.length = 6; - xgifb_info->video_cmap_len = 256; - break; - case 16: - var->red.offset = 11; - var->red.length = 5; - var->green.offset = 5; - var->green.length = 6; - var->blue.offset = 0; - var->blue.length = 5; - var->transp.offset = 0; - var->transp.length = 0; - xgifb_info->video_cmap_len = 16; - break; - case 32: - var->red.offset = 16; - var->red.length = 8; - var->green.offset = 8; - var->green.length = 8; - var->blue.offset = 0; - var->blue.length = 8; - var->transp.offset = 24; - var->transp.length = 8; - xgifb_info->video_cmap_len = 16; - break; - } -} - -/* --------------------- SetMode routines ------------------------- */ - -static void XGIfb_pre_setmode(struct xgifb_video_info *xgifb_info) -{ - struct vb_device_info *vb = &xgifb_info->dev_info; - u8 cr30 = 0, cr31 = 0; - - cr31 = xgifb_reg_get(vb->P3d4, 0x31); - cr31 &= ~0x60; - - switch (xgifb_info->display2) { - case XGIFB_DISP_CRT: - cr30 = SIS_VB_OUTPUT_CRT2 | SIS_SIMULTANEOUS_VIEW_ENABLE; - cr31 |= SIS_DRIVER_MODE; - break; - case XGIFB_DISP_LCD: - cr30 = SIS_VB_OUTPUT_LCD | SIS_SIMULTANEOUS_VIEW_ENABLE; - cr31 |= SIS_DRIVER_MODE; - break; - case XGIFB_DISP_TV: - if (xgifb_info->TV_type == TVMODE_HIVISION) - cr30 = SIS_VB_OUTPUT_HIVISION - | SIS_SIMULTANEOUS_VIEW_ENABLE; - else if (xgifb_info->TV_plug == TVPLUG_SVIDEO) - cr30 = SIS_VB_OUTPUT_SVIDEO - | SIS_SIMULTANEOUS_VIEW_ENABLE; - else if (xgifb_info->TV_plug == TVPLUG_COMPOSITE) - cr30 = SIS_VB_OUTPUT_COMPOSITE - | SIS_SIMULTANEOUS_VIEW_ENABLE; - else if (xgifb_info->TV_plug == TVPLUG_SCART) - cr30 = SIS_VB_OUTPUT_SCART - | SIS_SIMULTANEOUS_VIEW_ENABLE; - cr31 |= SIS_DRIVER_MODE; - - if (XGIfb_tvmode == 1 || xgifb_info->TV_type == TVMODE_PAL) - cr31 |= 0x01; - else - cr31 &= ~0x01; - break; - default: /* disable CRT2 */ - cr30 = 0x00; - cr31 |= (SIS_DRIVER_MODE | SIS_VB_OUTPUT_DISABLE); - } - - xgifb_reg_set(vb->P3d4, IND_XGI_SCRATCH_REG_CR30, cr30); - xgifb_reg_set(vb->P3d4, IND_XGI_SCRATCH_REG_CR31, cr31); - xgifb_reg_set(vb->P3d4, IND_XGI_SCRATCH_REG_CR33, - (xgifb_info->rate_idx & 0x0F)); -} - -static void XGIfb_post_setmode(struct xgifb_video_info *xgifb_info) -{ - struct vb_device_info *vb = &xgifb_info->dev_info; - u8 reg; - unsigned char doit = 1; - - if (xgifb_info->video_bpp == 8) { - /* - * We can't switch off CRT1 on LVDS/Chrontel - * in 8bpp Modes - */ - if ((xgifb_info->hasVB == HASVB_LVDS) || - (xgifb_info->hasVB == HASVB_LVDS_CHRONTEL)) { - doit = 0; - } - /* - * We can't switch off CRT1 on 301B-DH - * in 8bpp Modes if using LCD - */ - if (xgifb_info->display2 == XGIFB_DISP_LCD) - doit = 0; - } - - /* We can't switch off CRT1 if bridge is in slave mode */ - if (xgifb_info->hasVB != HASVB_NONE) { - reg = xgifb_reg_get(vb->Part1Port, 0x00); - - if ((reg & 0x50) == 0x10) - doit = 0; - - } else { - XGIfb_crt1off = 0; - } - - reg = xgifb_reg_get(vb->P3d4, 0x17); - if ((XGIfb_crt1off) && (doit)) - reg &= ~0x80; - else - reg |= 0x80; - xgifb_reg_set(vb->P3d4, 0x17, reg); - - xgifb_reg_and(vb->P3c4, IND_SIS_RAMDAC_CONTROL, ~0x04); - - if (xgifb_info->display2 == XGIFB_DISP_TV && - xgifb_info->hasVB == HASVB_301) { - reg = xgifb_reg_get(vb->Part4Port, 0x01); - - if (reg < 0xB0) { /* Set filter for XGI301 */ - int filter_tb; - - switch (xgifb_info->video_width) { - case 320: - filter_tb = (xgifb_info->TV_type == - TVMODE_NTSC) ? 4 : 12; - break; - case 640: - filter_tb = (xgifb_info->TV_type == - TVMODE_NTSC) ? 5 : 13; - break; - case 720: - filter_tb = (xgifb_info->TV_type == - TVMODE_NTSC) ? 6 : 14; - break; - case 800: - filter_tb = (xgifb_info->TV_type == - TVMODE_NTSC) ? 7 : 15; - break; - default: - filter_tb = 0; - filter = -1; - break; - } - xgifb_reg_or(vb->Part1Port, SIS_CRT2_WENABLE_315, 0x01); - - if (xgifb_info->TV_type == TVMODE_NTSC) { - xgifb_reg_and(vb->Part2Port, 0x3a, 0x1f); - - if (xgifb_info->TV_plug == TVPLUG_SVIDEO) { - xgifb_reg_and(vb->Part2Port, 0x30, 0xdf); - - } else if (xgifb_info->TV_plug - == TVPLUG_COMPOSITE) { - xgifb_reg_or(vb->Part2Port, 0x30, 0x20); - - switch (xgifb_info->video_width) { - case 640: - xgifb_reg_set(vb->Part2Port, - 0x35, - 0xEB); - xgifb_reg_set(vb->Part2Port, - 0x36, - 0x04); - xgifb_reg_set(vb->Part2Port, - 0x37, - 0x25); - xgifb_reg_set(vb->Part2Port, - 0x38, - 0x18); - break; - case 720: - xgifb_reg_set(vb->Part2Port, - 0x35, - 0xEE); - xgifb_reg_set(vb->Part2Port, - 0x36, - 0x0C); - xgifb_reg_set(vb->Part2Port, - 0x37, - 0x22); - xgifb_reg_set(vb->Part2Port, - 0x38, - 0x08); - break; - case 800: - xgifb_reg_set(vb->Part2Port, - 0x35, - 0xEB); - xgifb_reg_set(vb->Part2Port, - 0x36, - 0x15); - xgifb_reg_set(vb->Part2Port, - 0x37, - 0x25); - xgifb_reg_set(vb->Part2Port, - 0x38, - 0xF6); - break; - } - } - - } else if (xgifb_info->TV_type == TVMODE_PAL) { - xgifb_reg_and(vb->Part2Port, 0x3A, 0x1F); - - if (xgifb_info->TV_plug == TVPLUG_SVIDEO) { - xgifb_reg_and(vb->Part2Port, 0x30, 0xDF); - - } else if (xgifb_info->TV_plug - == TVPLUG_COMPOSITE) { - xgifb_reg_or(vb->Part2Port, 0x30, 0x20); - - switch (xgifb_info->video_width) { - case 640: - xgifb_reg_set(vb->Part2Port, - 0x35, - 0xF1); - xgifb_reg_set(vb->Part2Port, - 0x36, - 0xF7); - xgifb_reg_set(vb->Part2Port, - 0x37, - 0x1F); - xgifb_reg_set(vb->Part2Port, - 0x38, - 0x32); - break; - case 720: - xgifb_reg_set(vb->Part2Port, - 0x35, - 0xF3); - xgifb_reg_set(vb->Part2Port, - 0x36, - 0x00); - xgifb_reg_set(vb->Part2Port, - 0x37, - 0x1D); - xgifb_reg_set(vb->Part2Port, - 0x38, - 0x20); - break; - case 800: - xgifb_reg_set(vb->Part2Port, - 0x35, - 0xFC); - xgifb_reg_set(vb->Part2Port, - 0x36, - 0xFB); - xgifb_reg_set(vb->Part2Port, - 0x37, - 0x14); - xgifb_reg_set(vb->Part2Port, - 0x38, - 0x2A); - break; - } - } - } - - if ((filter >= 0) && (filter <= 7)) { - const u8 *f = XGI_TV_filter[filter_tb].filter[filter]; - - pr_debug("FilterTable[%d]-%d: %*ph\n", - filter_tb, filter, 4, f); - xgifb_reg_set(vb->Part2Port, 0x35, f[0]); - xgifb_reg_set(vb->Part2Port, 0x36, f[1]); - xgifb_reg_set(vb->Part2Port, 0x37, f[2]); - xgifb_reg_set(vb->Part2Port, 0x38, f[3]); - } - } - } -} - -static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive, - struct fb_info *info) -{ - struct xgifb_video_info *xgifb_info = info->par; - struct vb_device_info *vb = &xgifb_info->dev_info; - struct xgi_hw_device_info *hw_info = &xgifb_info->hw_info; - unsigned int htotal = var->left_margin + var->xres + var->right_margin - + var->hsync_len; - unsigned int vtotal = var->upper_margin + var->yres + var->lower_margin - + var->vsync_len; -#if defined(__BIG_ENDIAN) - u8 cr_data; -#endif - unsigned int drate = 0, hrate = 0; - int found_mode = 0; - int old_mode; - - info->var.xres_virtual = var->xres_virtual; - info->var.yres_virtual = var->yres_virtual; - info->var.bits_per_pixel = var->bits_per_pixel; - - if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED) - vtotal <<= 1; - else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) - vtotal <<= 2; - - if (!htotal || !vtotal) { - pr_debug("Invalid 'var' information\n"); - return -EINVAL; - } - pr_debug("var->pixclock=%d, htotal=%d, vtotal=%d\n", - var->pixclock, htotal, vtotal); - - if (var->pixclock) { - drate = 1000000000 / var->pixclock; - hrate = (drate * 1000) / htotal; - xgifb_info->refresh_rate = (unsigned int)(hrate * 2 - / vtotal); - } else { - xgifb_info->refresh_rate = 60; - } - - pr_debug("Change mode to %dx%dx%d-%dHz\n", - var->xres, var->yres, var->bits_per_pixel, - xgifb_info->refresh_rate); - - old_mode = xgifb_info->mode_idx; - xgifb_info->mode_idx = 0; - - while ((XGIbios_mode[xgifb_info->mode_idx].mode_no != 0) && - (XGIbios_mode[xgifb_info->mode_idx].xres <= var->xres)) { - if ((XGIbios_mode[xgifb_info->mode_idx].xres == var->xres) && - (XGIbios_mode[xgifb_info->mode_idx].yres == var->yres) && - (XGIbios_mode[xgifb_info->mode_idx].bpp - == var->bits_per_pixel)) { - found_mode = 1; - break; - } - xgifb_info->mode_idx++; - } - - if (found_mode) - xgifb_info->mode_idx = XGIfb_validate_mode(xgifb_info, - xgifb_info->mode_idx); - else - xgifb_info->mode_idx = -1; - - if (xgifb_info->mode_idx < 0) { - pr_err("Mode %dx%dx%d not supported\n", - var->xres, var->yres, var->bits_per_pixel); - xgifb_info->mode_idx = old_mode; - return -EINVAL; - } - - if (XGIfb_search_refresh_rate(xgifb_info, - xgifb_info->refresh_rate) == 0) { - xgifb_info->rate_idx = 1; - xgifb_info->refresh_rate = 60; - } - - if (isactive) { - XGIfb_pre_setmode(xgifb_info); - if (XGISetModeNew(xgifb_info, hw_info, - XGIbios_mode[xgifb_info->mode_idx].mode_no) - == 0) { - pr_err("Setting mode[0x%x] failed\n", - XGIbios_mode[xgifb_info->mode_idx].mode_no); - return -EINVAL; - } - info->fix.line_length = (info->var.xres_virtual - * info->var.bits_per_pixel) >> 6; - - xgifb_reg_set(vb->P3c4, IND_SIS_PASSWORD, SIS_PASSWORD); - - xgifb_reg_set(vb->P3d4, 0x13, (info->fix.line_length & 0x00ff)); - xgifb_reg_set(vb->P3c4, 0x0E, - (info->fix.line_length & 0xff00) >> 8); - - XGIfb_post_setmode(xgifb_info); - - pr_debug("Set new mode: %dx%dx%d-%d\n", - XGIbios_mode[xgifb_info->mode_idx].xres, - XGIbios_mode[xgifb_info->mode_idx].yres, - XGIbios_mode[xgifb_info->mode_idx].bpp, - xgifb_info->refresh_rate); - - xgifb_info->video_bpp = XGIbios_mode[xgifb_info->mode_idx].bpp; - xgifb_info->video_vwidth = info->var.xres_virtual; - xgifb_info->video_width = - XGIbios_mode[xgifb_info->mode_idx].xres; - xgifb_info->video_vheight = info->var.yres_virtual; - xgifb_info->video_height = - XGIbios_mode[xgifb_info->mode_idx].yres; - xgifb_info->org_x = 0; - xgifb_info->org_y = 0; - xgifb_info->video_linelength = info->var.xres_virtual - * (xgifb_info->video_bpp >> 3); - switch (xgifb_info->video_bpp) { - case 8: - xgifb_info->DstColor = 0x0000; - xgifb_info->XGI310_AccelDepth = 0x00000000; - xgifb_info->video_cmap_len = 256; -#if defined(__BIG_ENDIAN) - cr_data = xgifb_reg_get(vb->P3d4, 0x4D); - xgifb_reg_set(vb->P3d4, 0x4D, (cr_data & 0xE0)); -#endif - break; - case 16: - xgifb_info->DstColor = 0x8000; - xgifb_info->XGI310_AccelDepth = 0x00010000; -#if defined(__BIG_ENDIAN) - cr_data = xgifb_reg_get(vb->P3d4, 0x4D); - xgifb_reg_set(vb->P3d4, 0x4D, ((cr_data & 0xE0) | 0x0B)); -#endif - xgifb_info->video_cmap_len = 16; - break; - case 32: - xgifb_info->DstColor = 0xC000; - xgifb_info->XGI310_AccelDepth = 0x00020000; - xgifb_info->video_cmap_len = 16; -#if defined(__BIG_ENDIAN) - cr_data = xgifb_reg_get(vb->P3d4, 0x4D); - xgifb_reg_set(vb->P3d4, 0x4D, ((cr_data & 0xE0) | 0x15)); -#endif - break; - default: - xgifb_info->video_cmap_len = 16; - pr_err("Unsupported depth %d\n", - xgifb_info->video_bpp); - break; - } - } - XGIfb_bpp_to_var(xgifb_info, var); /* update ARGB info */ - - dumpVGAReg(xgifb_info); - return 0; -} - -static int XGIfb_pan_var(struct fb_var_screeninfo *var, struct fb_info *info) -{ - struct xgifb_video_info *xgifb_info = info->par; - struct vb_device_info *vb = &xgifb_info->dev_info; - unsigned int base; - - base = var->yoffset * info->var.xres_virtual + var->xoffset; - - /* calculate base bpp dep. */ - switch (info->var.bits_per_pixel) { - case 16: - base >>= 1; - break; - case 32: - break; - case 8: - default: - base >>= 2; - break; - } - - xgifb_reg_set(vb->P3c4, IND_SIS_PASSWORD, SIS_PASSWORD); - - xgifb_reg_set(vb->P3d4, 0x0D, base & 0xFF); - xgifb_reg_set(vb->P3d4, 0x0C, (base >> 8) & 0xFF); - xgifb_reg_set(vb->P3c4, 0x0D, (base >> 16) & 0xFF); - xgifb_reg_set(vb->P3c4, 0x37, (base >> 24) & 0x03); - xgifb_reg_and_or(vb->P3c4, 0x37, 0xDF, (base >> 21) & 0x04); - - if (xgifb_info->display2 != XGIFB_DISP_NONE) { - xgifb_reg_or(vb->Part1Port, SIS_CRT2_WENABLE_315, 0x01); - xgifb_reg_set(vb->Part1Port, 0x06, (base & 0xFF)); - xgifb_reg_set(vb->Part1Port, 0x05, ((base >> 8) & 0xFF)); - xgifb_reg_set(vb->Part1Port, 0x04, ((base >> 16) & 0xFF)); - xgifb_reg_and_or(vb->Part1Port, 0x02, 0x7F, - ((base >> 24) & 0x01) << 7); - } - return 0; -} - -static int XGIfb_open(struct fb_info *info, int user) -{ - return 0; -} - -static int XGIfb_release(struct fb_info *info, int user) -{ - return 0; -} - -/* similar to sisfb_get_cmap_len */ -static int XGIfb_get_cmap_len(const struct fb_var_screeninfo *var) -{ - return (var->bits_per_pixel == 8) ? 256 : 16; -} - -static int XGIfb_setcolreg(unsigned int regno, unsigned int red, - unsigned int green, unsigned int blue, - unsigned int transp, struct fb_info *info) -{ - struct xgifb_video_info *xgifb_info = info->par; - struct vb_device_info *vb = &xgifb_info->dev_info; - - if (regno >= XGIfb_get_cmap_len(&info->var)) - return 1; - - switch (info->var.bits_per_pixel) { - case 8: - outb(regno, vb->P3c8); - outb((red >> 10), vb->P3c9); - outb((green >> 10), vb->P3c9); - outb((blue >> 10), vb->P3c9); - if (xgifb_info->display2 != XGIFB_DISP_NONE) { - outb(regno, vb->Part5Port); - outb((red >> 8), (vb->Part5Port + 1)); - outb((green >> 8), (vb->Part5Port + 1)); - outb((blue >> 8), (vb->Part5Port + 1)); - } - break; - case 16: - ((u32 *)(info->pseudo_palette))[regno] = ((red & 0xf800)) - | ((green & 0xfc00) >> 5) | ((blue & 0xf800) - >> 11); - break; - case 32: - red >>= 8; - green >>= 8; - blue >>= 8; - ((u32 *)(info->pseudo_palette))[regno] = (red << 16) | (green - << 8) | (blue); - break; - } - return 0; -} - -/* ----------- FBDev related routines for all series ---------- */ - -static int XGIfb_get_fix(struct fb_fix_screeninfo *fix, int con, - struct fb_info *info) -{ - struct xgifb_video_info *xgifb_info = info->par; - - memset(fix, 0, sizeof(struct fb_fix_screeninfo)); - - strncpy(fix->id, "XGI", sizeof(fix->id) - 1); - - /* if register_framebuffer has been called, we must lock */ - if (atomic_read(&info->count)) - mutex_lock(&info->mm_lock); - - fix->smem_start = xgifb_info->video_base; - fix->smem_len = xgifb_info->video_size; - - /* if register_framebuffer has been called, we can unlock */ - if (atomic_read(&info->count)) - mutex_unlock(&info->mm_lock); - - fix->type = FB_TYPE_PACKED_PIXELS; - fix->type_aux = 0; - if (xgifb_info->video_bpp == 8) - fix->visual = FB_VISUAL_PSEUDOCOLOR; - else - fix->visual = FB_VISUAL_DIRECTCOLOR; - fix->xpanstep = 0; - if (XGIfb_ypan) - fix->ypanstep = 1; - fix->ywrapstep = 0; - fix->line_length = xgifb_info->video_linelength; - fix->mmio_start = xgifb_info->mmio_base; - fix->mmio_len = xgifb_info->mmio_size; - fix->accel = FB_ACCEL_SIS_XABRE; - - return 0; -} - -static int XGIfb_set_par(struct fb_info *info) -{ - int err; - - err = XGIfb_do_set_var(&info->var, 1, info); - if (err) - return err; - XGIfb_get_fix(&info->fix, -1, info); - return 0; -} - -static int XGIfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) -{ - struct xgifb_video_info *xgifb_info = info->par; - unsigned int htotal = var->left_margin + var->xres + var->right_margin - + var->hsync_len; - unsigned int vtotal = 0; - unsigned int drate = 0, hrate = 0; - int found_mode = 0; - int search_idx; - - if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED) { - vtotal = var->upper_margin + var->yres + var->lower_margin - + var->vsync_len; - vtotal <<= 1; - } else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) { - vtotal = var->upper_margin + var->yres + var->lower_margin - + var->vsync_len; - vtotal <<= 2; - } else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) { - vtotal = var->upper_margin + (var->yres / 2) - + var->lower_margin + var->vsync_len; - } else - vtotal = var->upper_margin + var->yres + var->lower_margin - + var->vsync_len; - - if (!(htotal) || !(vtotal)) { - pr_debug("No valid timing data\n"); - return -EINVAL; - } - - if (var->pixclock && htotal && vtotal) { - drate = 1000000000 / var->pixclock; - hrate = (drate * 1000) / htotal; - xgifb_info->refresh_rate = - (unsigned int)(hrate * 2 / vtotal); - pr_debug( - "%s: pixclock = %d ,htotal=%d, vtotal=%d\n" - "%s: drate=%d, hrate=%d, refresh_rate=%d\n", - __func__, var->pixclock, htotal, vtotal, - __func__, drate, hrate, xgifb_info->refresh_rate); - } else { - xgifb_info->refresh_rate = 60; - } - - search_idx = 0; - while ((XGIbios_mode[search_idx].mode_no != 0) && - (XGIbios_mode[search_idx].xres <= var->xres)) { - if ((XGIbios_mode[search_idx].xres == var->xres) && - (XGIbios_mode[search_idx].yres == var->yres) && - (XGIbios_mode[search_idx].bpp == var->bits_per_pixel)) { - if (XGIfb_validate_mode(xgifb_info, search_idx) > 0) { - found_mode = 1; - break; - } - } - search_idx++; - } - - if (!found_mode) { - pr_err("%dx%dx%d is no valid mode\n", - var->xres, var->yres, var->bits_per_pixel); - search_idx = 0; - while (XGIbios_mode[search_idx].mode_no != 0) { - if ((var->xres <= XGIbios_mode[search_idx].xres) && - (var->yres <= XGIbios_mode[search_idx].yres) && - (var->bits_per_pixel == - XGIbios_mode[search_idx].bpp)) { - if (XGIfb_validate_mode(xgifb_info, - search_idx) > 0) { - found_mode = 1; - break; - } - } - search_idx++; - } - if (found_mode) { - var->xres = XGIbios_mode[search_idx].xres; - var->yres = XGIbios_mode[search_idx].yres; - pr_debug("Adapted to mode %dx%dx%d\n", - var->xres, var->yres, var->bits_per_pixel); - - } else { - pr_err("Failed to find similar mode to %dx%dx%d\n", - var->xres, var->yres, var->bits_per_pixel); - return -EINVAL; - } - } - - /* Adapt RGB settings */ - XGIfb_bpp_to_var(xgifb_info, var); - - if (!XGIfb_ypan) { - if (var->xres != var->xres_virtual) - var->xres_virtual = var->xres; - if (var->yres != var->yres_virtual) - var->yres_virtual = var->yres; - } - - /* Truncate offsets to maximum if too high */ - if (var->xoffset > var->xres_virtual - var->xres) - var->xoffset = var->xres_virtual - var->xres - 1; - - if (var->yoffset > var->yres_virtual - var->yres) - var->yoffset = var->yres_virtual - var->yres - 1; - - /* Set everything else to 0 */ - var->red.msb_right = 0; - var->green.msb_right = 0; - var->blue.msb_right = 0; - var->transp.offset = 0; - var->transp.length = 0; - var->transp.msb_right = 0; - - return 0; -} - -static int XGIfb_pan_display(struct fb_var_screeninfo *var, - struct fb_info *info) -{ - int err; - - if (var->xoffset > (info->var.xres_virtual - info->var.xres)) - return -EINVAL; - if (var->yoffset > (info->var.yres_virtual - info->var.yres)) - return -EINVAL; - - if (var->vmode & FB_VMODE_YWRAP) { - if (var->yoffset >= info->var.yres_virtual || var->xoffset) - return -EINVAL; - } else if (var->xoffset + info->var.xres > info->var.xres_virtual || - var->yoffset + info->var.yres > info->var.yres_virtual) { - return -EINVAL; - } - err = XGIfb_pan_var(var, info); - if (err < 0) - return err; - - info->var.xoffset = var->xoffset; - info->var.yoffset = var->yoffset; - if (var->vmode & FB_VMODE_YWRAP) - info->var.vmode |= FB_VMODE_YWRAP; - else - info->var.vmode &= ~FB_VMODE_YWRAP; - - return 0; -} - -static int XGIfb_blank(int blank, struct fb_info *info) -{ - struct xgifb_video_info *xgifb_info = info->par; - struct vb_device_info *vb = &xgifb_info->dev_info; - u8 reg; - - reg = xgifb_reg_get(vb->P3d4, 0x17); - - if (blank > 0) - reg &= 0x7f; - else - reg |= 0x80; - - xgifb_reg_set(vb->P3d4, 0x17, reg); - xgifb_reg_set(vb->P3c4, 0x00, 0x01); /* Synchronous Reset */ - xgifb_reg_set(vb->P3c4, 0x00, 0x03); /* End Reset */ - return 0; -} - -static struct fb_ops XGIfb_ops = { - .owner = THIS_MODULE, - .fb_open = XGIfb_open, - .fb_release = XGIfb_release, - .fb_check_var = XGIfb_check_var, - .fb_set_par = XGIfb_set_par, - .fb_setcolreg = XGIfb_setcolreg, - .fb_pan_display = XGIfb_pan_display, - .fb_blank = XGIfb_blank, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, -}; - -/* ---------------- Chip generation dependent routines ---------------- */ - -/* for XGI 315/550/650/740/330 */ - -static int XGIfb_get_dram_size(struct xgifb_video_info *xgifb_info) -{ - struct vb_device_info *vb = &xgifb_info->dev_info; - u8 ChannelNum, tmp; - u8 reg = 0; - - /* xorg driver sets 32MB * 1 channel */ - if (xgifb_info->chip == XG27) - xgifb_reg_set(vb->P3c4, IND_SIS_DRAM_SIZE, 0x51); - - reg = xgifb_reg_get(vb->P3c4, IND_SIS_DRAM_SIZE); - if (!reg) - return -1; - - switch ((reg & XGI_DRAM_SIZE_MASK) >> 4) { - case XGI_DRAM_SIZE_1MB: - xgifb_info->video_size = 0x100000; - break; - case XGI_DRAM_SIZE_2MB: - xgifb_info->video_size = 0x200000; - break; - case XGI_DRAM_SIZE_4MB: - xgifb_info->video_size = 0x400000; - break; - case XGI_DRAM_SIZE_8MB: - xgifb_info->video_size = 0x800000; - break; - case XGI_DRAM_SIZE_16MB: - xgifb_info->video_size = 0x1000000; - break; - case XGI_DRAM_SIZE_32MB: - xgifb_info->video_size = 0x2000000; - break; - case XGI_DRAM_SIZE_64MB: - xgifb_info->video_size = 0x4000000; - break; - case XGI_DRAM_SIZE_128MB: - xgifb_info->video_size = 0x8000000; - break; - case XGI_DRAM_SIZE_256MB: - xgifb_info->video_size = 0x10000000; - break; - default: - return -1; - } - - tmp = (reg & 0x0c) >> 2; - switch (xgifb_info->chip) { - case XG20: - case XG21: - case XG27: - ChannelNum = 1; - break; - - case XG42: - if (reg & 0x04) - ChannelNum = 2; - else - ChannelNum = 1; - break; - - case XG40: - default: - if (tmp == 2) - ChannelNum = 2; - else if (tmp == 3) - ChannelNum = 3; - else - ChannelNum = 1; - break; - } - - xgifb_info->video_size = xgifb_info->video_size * ChannelNum; - - pr_info("SR14=%x DramSzie %x ChannelNum %x\n", - reg, xgifb_info->video_size, ChannelNum); - return 0; -} - -static void XGIfb_detect_VB(struct xgifb_video_info *xgifb_info) -{ - struct vb_device_info *vb = &xgifb_info->dev_info; - u8 cr32, temp = 0; - - xgifb_info->TV_plug = 0; - xgifb_info->TV_type = 0; - - cr32 = xgifb_reg_get(vb->P3d4, IND_XGI_SCRATCH_REG_CR32); - - if ((cr32 & SIS_CRT1) && !XGIfb_crt1off) { - XGIfb_crt1off = 0; - } else { - if (cr32 & 0x5F) - XGIfb_crt1off = 1; - else - XGIfb_crt1off = 0; - } - - if (!xgifb_info->display2_force) { - if (cr32 & SIS_VB_TV) - xgifb_info->display2 = XGIFB_DISP_TV; - else if (cr32 & SIS_VB_LCD) - xgifb_info->display2 = XGIFB_DISP_LCD; - else if (cr32 & SIS_VB_CRT2) - xgifb_info->display2 = XGIFB_DISP_CRT; - else - xgifb_info->display2 = XGIFB_DISP_NONE; - } - - if (XGIfb_tvplug != -1) { - /* Override with option */ - xgifb_info->TV_plug = XGIfb_tvplug; - } else if (cr32 & SIS_VB_HIVISION) { - xgifb_info->TV_type = TVMODE_HIVISION; - xgifb_info->TV_plug = TVPLUG_SVIDEO; - } else if (cr32 & SIS_VB_SVIDEO) { - xgifb_info->TV_plug = TVPLUG_SVIDEO; - } else if (cr32 & SIS_VB_COMPOSITE) { - xgifb_info->TV_plug = TVPLUG_COMPOSITE; - } else if (cr32 & SIS_VB_SCART) { - xgifb_info->TV_plug = TVPLUG_SCART; - } - - if (xgifb_info->TV_type == 0) { - temp = xgifb_reg_get(vb->P3d4, 0x38); - if (temp & 0x10) - xgifb_info->TV_type = TVMODE_PAL; - else - xgifb_info->TV_type = TVMODE_NTSC; - } - - /* Copy forceCRT1 option to CRT1off if option is given */ - if (XGIfb_forcecrt1 != -1) { - if (XGIfb_forcecrt1) - XGIfb_crt1off = 0; - else - XGIfb_crt1off = 1; - } -} - -static bool XGIfb_has_VB(struct xgifb_video_info *xgifb_info) -{ - u8 vb_chipid; - - vb_chipid = xgifb_reg_get(xgifb_info->dev_info.Part4Port, 0x00); - switch (vb_chipid) { - case 0x01: - xgifb_info->hasVB = HASVB_301; - break; - case 0x02: - xgifb_info->hasVB = HASVB_302; - break; - default: - xgifb_info->hasVB = HASVB_NONE; - return false; - } - return true; -} - -static void XGIfb_get_VB_type(struct xgifb_video_info *xgifb_info) -{ - u8 reg; - - if (!XGIfb_has_VB(xgifb_info)) { - reg = xgifb_reg_get(xgifb_info->dev_info.P3d4, - IND_XGI_SCRATCH_REG_CR37); - switch ((reg & SIS_EXTERNAL_CHIP_MASK) >> 1) { - case SIS_EXTERNAL_CHIP_LVDS: - xgifb_info->hasVB = HASVB_LVDS; - break; - case SIS_EXTERNAL_CHIP_LVDS_CHRONTEL: - xgifb_info->hasVB = HASVB_LVDS_CHRONTEL; - break; - default: - break; - } - } -} - -static int __init xgifb_optval(char *fullopt, int validx) -{ - unsigned long lres; - - if (kstrtoul(fullopt + validx, 0, &lres) < 0 || lres > INT_MAX) { - pr_err("Invalid value for option: %s\n", fullopt); - return 0; - } - return lres; -} - -static int __init XGIfb_setup(char *options) -{ - char *this_opt; - - if (!options || !*options) - return 0; - - pr_info("Options: %s\n", options); - - while ((this_opt = strsep(&options, ",")) != NULL) { - if (!*this_opt) - continue; - - if (!strncmp(this_opt, "mode:", 5)) { - mode = this_opt + 5; - } else if (!strncmp(this_opt, "vesa:", 5)) { - vesa = xgifb_optval(this_opt, 5); - } else if (!strncmp(this_opt, "vrate:", 6)) { - refresh_rate = xgifb_optval(this_opt, 6); - } else if (!strncmp(this_opt, "rate:", 5)) { - refresh_rate = xgifb_optval(this_opt, 5); - } else if (!strncmp(this_opt, "crt1off", 7)) { - XGIfb_crt1off = 1; - } else if (!strncmp(this_opt, "filter:", 7)) { - filter = xgifb_optval(this_opt, 7); - } else if (!strncmp(this_opt, "forcecrt2type:", 14)) { - XGIfb_search_crt2type(this_opt + 14); - } else if (!strncmp(this_opt, "forcecrt1:", 10)) { - XGIfb_forcecrt1 = xgifb_optval(this_opt, 10); - } else if (!strncmp(this_opt, "tvmode:", 7)) { - XGIfb_search_tvstd(this_opt + 7); - } else if (!strncmp(this_opt, "tvstandard:", 11)) { - XGIfb_search_tvstd(this_opt + 7); - } else if (!strncmp(this_opt, "dstn", 4)) { - enable_dstn = 1; - /* DSTN overrules forcecrt2type */ - XGIfb_crt2type = XGIFB_DISP_LCD; - } else if (!strncmp(this_opt, "noypan", 6)) { - XGIfb_ypan = 0; - } else { - mode = this_opt; - } - } - return 0; -} - -static int xgifb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) -{ - u8 reg, reg1; - u8 CR48, CR38; - int ret; - struct fb_info *fb_info; - struct xgifb_video_info *xgifb_info; - struct vb_device_info *vb; - struct xgi_hw_device_info *hw_info; - unsigned long video_size_max; - - fb_info = framebuffer_alloc(sizeof(*xgifb_info), &pdev->dev); - if (!fb_info) - return -ENOMEM; - - xgifb_info = fb_info->par; - vb = &xgifb_info->dev_info; - hw_info = &xgifb_info->hw_info; - xgifb_info->fb_info = fb_info; - xgifb_info->chip_id = pdev->device; - pci_read_config_byte(pdev, - PCI_REVISION_ID, - &xgifb_info->revision_id); - hw_info->jChipRevision = xgifb_info->revision_id; - - xgifb_info->pcibus = pdev->bus->number; - xgifb_info->pcislot = PCI_SLOT(pdev->devfn); - xgifb_info->pcifunc = PCI_FUNC(pdev->devfn); - xgifb_info->subsysvendor = pdev->subsystem_vendor; - xgifb_info->subsysdevice = pdev->subsystem_device; - - video_size_max = pci_resource_len(pdev, 0); - xgifb_info->video_base = pci_resource_start(pdev, 0); - xgifb_info->mmio_base = pci_resource_start(pdev, 1); - xgifb_info->mmio_size = pci_resource_len(pdev, 1); - xgifb_info->vga_base = pci_resource_start(pdev, 2) + 0x30; - dev_info(&pdev->dev, "Relocate IO address: %llx [%08lx]\n", - (u64)pci_resource_start(pdev, 2), - xgifb_info->vga_base); - - if (pci_enable_device(pdev)) { - ret = -EIO; - goto error; - } - - if (XGIfb_crt2type != -1) { - xgifb_info->display2 = XGIfb_crt2type; - xgifb_info->display2_force = true; - } - - XGIRegInit(vb, xgifb_info->vga_base); - - xgifb_reg_set(vb->P3c4, - IND_SIS_PASSWORD, SIS_PASSWORD); - reg1 = xgifb_reg_get(vb->P3c4, IND_SIS_PASSWORD); - - if (reg1 != 0xa1) { /* I/O error */ - dev_err(&pdev->dev, "I/O error\n"); - ret = -EIO; - goto error_disable; - } - - switch (xgifb_info->chip_id) { - case PCI_DEVICE_ID_XGI_20: - xgifb_reg_or(vb->P3d4, - Index_CR_GPIO_Reg3, GPIOG_EN); - CR48 = xgifb_reg_get(vb->P3d4, - Index_CR_GPIO_Reg1); - if (CR48 & GPIOG_READ) - xgifb_info->chip = XG21; - else - xgifb_info->chip = XG20; - break; - case PCI_DEVICE_ID_XGI_40: - xgifb_info->chip = XG40; - break; - case PCI_DEVICE_ID_XGI_42: - xgifb_info->chip = XG42; - break; - case PCI_DEVICE_ID_XGI_27: - xgifb_info->chip = XG27; - break; - default: - ret = -ENODEV; - goto error_disable; - } - - dev_info(&pdev->dev, "chipid = %x\n", xgifb_info->chip); - hw_info->jChipType = xgifb_info->chip; - - if (XGIfb_get_dram_size(xgifb_info)) { - xgifb_info->video_size = min_t(unsigned long, video_size_max, - SZ_16M); - } else if (xgifb_info->video_size > video_size_max) { - xgifb_info->video_size = video_size_max; - } - - /* Enable PCI_LINEAR_ADDRESSING and MMIO_ENABLE */ - xgifb_reg_or(vb->P3c4, - IND_SIS_PCI_ADDRESS_SET, - (SIS_PCI_ADDR_ENABLE | SIS_MEM_MAP_IO_ENABLE)); - /* Enable 2D accelerator engine */ - xgifb_reg_or(vb->P3c4, - IND_SIS_MODULE_ENABLE, SIS_ENABLE_2D); - - hw_info->ulVideoMemorySize = xgifb_info->video_size; - - if (!request_mem_region(xgifb_info->video_base, - xgifb_info->video_size, - "XGIfb FB")) { - dev_err(&pdev->dev, "Unable request memory size %x\n", - xgifb_info->video_size); - dev_err(&pdev->dev, - "Fatal error: Unable to reserve frame buffer memory. Is there another framebuffer driver active?\n"); - ret = -ENODEV; - goto error_disable; - } - - if (!request_mem_region(xgifb_info->mmio_base, - xgifb_info->mmio_size, - "XGIfb MMIO")) { - dev_err(&pdev->dev, - "Fatal error: Unable to reserve MMIO region\n"); - ret = -ENODEV; - goto error_0; - } - - xgifb_info->video_vbase = - ioremap_wc(xgifb_info->video_base, xgifb_info->video_size); - hw_info->pjVideoMemoryAddress = - ioremap_wc(xgifb_info->video_base, xgifb_info->video_size); - xgifb_info->mmio_vbase = ioremap(xgifb_info->mmio_base, - xgifb_info->mmio_size); - - dev_info(&pdev->dev, - "Framebuffer at 0x%llx, mapped to 0x%p, size %dk\n", - (u64)xgifb_info->video_base, - xgifb_info->video_vbase, - xgifb_info->video_size / 1024); - - dev_info(&pdev->dev, - "MMIO at 0x%llx, mapped to 0x%p, size %ldk\n", - (u64)xgifb_info->mmio_base, xgifb_info->mmio_vbase, - xgifb_info->mmio_size / 1024); - - pci_set_drvdata(pdev, xgifb_info); - if (!XGIInitNew(pdev)) - dev_err(&pdev->dev, "XGIInitNew() failed!\n"); - - xgifb_info->mtrr = -1; - - xgifb_info->hasVB = HASVB_NONE; - if ((xgifb_info->chip == XG20) || - (xgifb_info->chip == XG27)) { - xgifb_info->hasVB = HASVB_NONE; - } else if (xgifb_info->chip == XG21) { - CR38 = xgifb_reg_get(vb->P3d4, 0x38); - if ((CR38 & 0xE0) == 0xC0) - xgifb_info->display2 = XGIFB_DISP_LCD; - else if ((CR38 & 0xE0) == 0x60) - xgifb_info->hasVB = HASVB_CHRONTEL; - else - xgifb_info->hasVB = HASVB_NONE; - } else { - XGIfb_get_VB_type(xgifb_info); - } - - hw_info->ujVBChipID = VB_CHIP_UNKNOWN; - - hw_info->ulExternalChip = 0; - - switch (xgifb_info->hasVB) { - case HASVB_301: - reg = xgifb_reg_get(vb->Part4Port, 0x01); - if (reg >= 0xE0) { - hw_info->ujVBChipID = VB_CHIP_302LV; - dev_info(&pdev->dev, - "XGI302LV bridge detected (revision 0x%02x)\n", - reg); - } else if (reg >= 0xD0) { - hw_info->ujVBChipID = VB_CHIP_301LV; - dev_info(&pdev->dev, - "XGI301LV bridge detected (revision 0x%02x)\n", - reg); - } else { - hw_info->ujVBChipID = VB_CHIP_301; - dev_info(&pdev->dev, "XGI301 bridge detected\n"); - } - break; - case HASVB_302: - reg = xgifb_reg_get(vb->Part4Port, 0x01); - if (reg >= 0xE0) { - hw_info->ujVBChipID = VB_CHIP_302LV; - dev_info(&pdev->dev, - "XGI302LV bridge detected (revision 0x%02x)\n", - reg); - } else if (reg >= 0xD0) { - hw_info->ujVBChipID = VB_CHIP_301LV; - dev_info(&pdev->dev, - "XGI302LV bridge detected (revision 0x%02x)\n", - reg); - } else if (reg >= 0xB0) { - reg1 = xgifb_reg_get(vb->Part4Port, - 0x23); - - hw_info->ujVBChipID = VB_CHIP_302B; - - } else { - hw_info->ujVBChipID = VB_CHIP_302; - dev_info(&pdev->dev, "XGI302 bridge detected\n"); - } - break; - case HASVB_LVDS: - hw_info->ulExternalChip = 0x1; - dev_info(&pdev->dev, "LVDS transmitter detected\n"); - break; - case HASVB_TRUMPION: - hw_info->ulExternalChip = 0x2; - dev_info(&pdev->dev, "Trumpion Zurac LVDS scaler detected\n"); - break; - case HASVB_CHRONTEL: - hw_info->ulExternalChip = 0x4; - dev_info(&pdev->dev, "Chrontel TV encoder detected\n"); - break; - case HASVB_LVDS_CHRONTEL: - hw_info->ulExternalChip = 0x5; - dev_info(&pdev->dev, - "LVDS transmitter and Chrontel TV encoder detected\n"); - break; - default: - dev_info(&pdev->dev, "No or unknown bridge type detected\n"); - break; - } - - if (xgifb_info->hasVB != HASVB_NONE) - XGIfb_detect_VB(xgifb_info); - else if (xgifb_info->chip != XG21) - xgifb_info->display2 = XGIFB_DISP_NONE; - - if (xgifb_info->display2 == XGIFB_DISP_LCD) { - if (!enable_dstn) { - reg = xgifb_reg_get(vb->P3d4, - IND_XGI_LCD_PANEL); - reg &= 0x0f; - hw_info->ulCRT2LCDType = XGI310paneltype[reg]; - } - } - - xgifb_info->mode_idx = -1; - - if (mode) - XGIfb_search_mode(xgifb_info, mode); - else if (vesa != -1) - XGIfb_search_vesamode(xgifb_info, vesa); - - if (xgifb_info->mode_idx >= 0) - xgifb_info->mode_idx = - XGIfb_validate_mode(xgifb_info, xgifb_info->mode_idx); - - if (xgifb_info->mode_idx < 0) { - if (xgifb_info->display2 == XGIFB_DISP_LCD && - xgifb_info->chip == XG21) - xgifb_info->mode_idx = - XGIfb_GetXG21DefaultLVDSModeIdx(xgifb_info); - else - xgifb_info->mode_idx = DEFAULT_MODE; - } - - if (xgifb_info->mode_idx < 0) { - dev_err(&pdev->dev, "No supported video mode found\n"); - ret = -EINVAL; - goto error_1; - } - - /* set default refresh rate */ - xgifb_info->refresh_rate = refresh_rate; - if (xgifb_info->refresh_rate == 0) - xgifb_info->refresh_rate = 60; - if (XGIfb_search_refresh_rate(xgifb_info, xgifb_info->refresh_rate) == 0) { - xgifb_info->rate_idx = 1; - xgifb_info->refresh_rate = 60; - } - - xgifb_info->video_bpp = XGIbios_mode[xgifb_info->mode_idx].bpp; - xgifb_info->video_vwidth = - xgifb_info->video_width = - XGIbios_mode[xgifb_info->mode_idx].xres; - xgifb_info->video_vheight = - xgifb_info->video_height = - XGIbios_mode[xgifb_info->mode_idx].yres; - xgifb_info->org_x = 0; - xgifb_info->org_y = 0; - xgifb_info->video_linelength = - xgifb_info->video_width * - (xgifb_info->video_bpp >> 3); - switch (xgifb_info->video_bpp) { - case 8: - xgifb_info->DstColor = 0x0000; - xgifb_info->XGI310_AccelDepth = 0x00000000; - xgifb_info->video_cmap_len = 256; - break; - case 16: - xgifb_info->DstColor = 0x8000; - xgifb_info->XGI310_AccelDepth = 0x00010000; - xgifb_info->video_cmap_len = 16; - break; - case 32: - xgifb_info->DstColor = 0xC000; - xgifb_info->XGI310_AccelDepth = 0x00020000; - xgifb_info->video_cmap_len = 16; - break; - default: - xgifb_info->video_cmap_len = 16; - pr_info("Unsupported depth %d\n", - xgifb_info->video_bpp); - break; - } - - pr_info("Default mode is %dx%dx%d (%dHz)\n", - xgifb_info->video_width, xgifb_info->video_height, - xgifb_info->video_bpp, xgifb_info->refresh_rate); - - fb_info->var.red.length = 8; - fb_info->var.green.length = 8; - fb_info->var.blue.length = 8; - fb_info->var.activate = FB_ACTIVATE_NOW; - fb_info->var.height = -1; - fb_info->var.width = -1; - fb_info->var.vmode = FB_VMODE_NONINTERLACED; - fb_info->var.xres = xgifb_info->video_width; - fb_info->var.xres_virtual = xgifb_info->video_width; - fb_info->var.yres = xgifb_info->video_height; - fb_info->var.yres_virtual = xgifb_info->video_height; - fb_info->var.bits_per_pixel = xgifb_info->video_bpp; - - XGIfb_bpp_to_var(xgifb_info, &fb_info->var); - - fb_info->var.pixclock = (u32)(1000000000 / XGIfb_mode_rate_to_dclock - (vb, hw_info, - XGIbios_mode[xgifb_info->mode_idx].mode_no)); - - if (XGIfb_mode_rate_to_ddata(vb, hw_info, - XGIbios_mode[xgifb_info->mode_idx].mode_no, - &fb_info->var.left_margin, - &fb_info->var.right_margin, - &fb_info->var.upper_margin, - &fb_info->var.lower_margin, - &fb_info->var.hsync_len, - &fb_info->var.vsync_len, - &fb_info->var.sync, - &fb_info->var.vmode)) { - if ((fb_info->var.vmode & FB_VMODE_MASK) == - FB_VMODE_INTERLACED) { - fb_info->var.yres <<= 1; - fb_info->var.yres_virtual <<= 1; - } else if ((fb_info->var.vmode & FB_VMODE_MASK) == - FB_VMODE_DOUBLE) { - fb_info->var.pixclock >>= 1; - fb_info->var.yres >>= 1; - fb_info->var.yres_virtual >>= 1; - } - } - - fb_info->flags = FBINFO_FLAG_DEFAULT; - fb_info->screen_base = xgifb_info->video_vbase; - fb_info->fbops = &XGIfb_ops; - XGIfb_get_fix(&fb_info->fix, -1, fb_info); - fb_info->pseudo_palette = xgifb_info->pseudo_palette; - - fb_alloc_cmap(&fb_info->cmap, 256, 0); - - xgifb_info->mtrr = arch_phys_wc_add(xgifb_info->video_base, - xgifb_info->video_size); - - if (register_framebuffer(fb_info) < 0) { - ret = -EINVAL; - goto error_mtrr; - } - - dumpVGAReg(xgifb_info); - - return 0; - -error_mtrr: - arch_phys_wc_del(xgifb_info->mtrr); -error_1: - iounmap(xgifb_info->mmio_vbase); - iounmap(xgifb_info->video_vbase); - release_mem_region(xgifb_info->mmio_base, xgifb_info->mmio_size); -error_0: - release_mem_region(xgifb_info->video_base, xgifb_info->video_size); -error_disable: - pci_disable_device(pdev); -error: - framebuffer_release(fb_info); - return ret; -} - -/* -------------------- PCI DEVICE HANDLING -------------------- */ - -static void xgifb_remove(struct pci_dev *pdev) -{ - struct xgifb_video_info *xgifb_info = pci_get_drvdata(pdev); - struct fb_info *fb_info = xgifb_info->fb_info; - - unregister_framebuffer(fb_info); - arch_phys_wc_del(xgifb_info->mtrr); - iounmap(xgifb_info->mmio_vbase); - iounmap(xgifb_info->video_vbase); - release_mem_region(xgifb_info->mmio_base, xgifb_info->mmio_size); - release_mem_region(xgifb_info->video_base, xgifb_info->video_size); - pci_disable_device(pdev); - framebuffer_release(fb_info); -} - -static struct pci_driver xgifb_driver = { - .name = "xgifb", - .id_table = xgifb_pci_table, - .probe = xgifb_probe, - .remove = xgifb_remove -}; - -/* -------------------- MODULE -------------------- */ - -module_param(mode, charp, 0000); -MODULE_PARM_DESC(mode, - "Selects the desired default display mode in the format XxYxDepth (eg. 1024x768x16)."); - -module_param(forcecrt2type, charp, 0000); -MODULE_PARM_DESC(forcecrt2type, - "Force the second display output type. Possible values are NONE, LCD, TV, VGA, SVIDEO or COMPOSITE."); - -module_param(vesa, int, 0000); -MODULE_PARM_DESC(vesa, - "Selects the desired default display mode by VESA mode number (eg. 0x117)."); - -module_param(filter, int, 0000); -MODULE_PARM_DESC(filter, - "Selects TV flicker filter type (only for systems with a SiS301 video bridge). Possible values 0-7. Default: [no filter])."); - -static int __init xgifb_init(void) -{ - char *option = NULL; - - if (forcecrt2type) - XGIfb_search_crt2type(forcecrt2type); - if (fb_get_options("xgifb", &option)) - return -ENODEV; - XGIfb_setup(option); - - return pci_register_driver(&xgifb_driver); -} - -static void __exit xgifb_remove_module(void) -{ - pci_unregister_driver(&xgifb_driver); - pr_debug("Module unloaded\n"); -} - -MODULE_DESCRIPTION("Z7 Z9 Z9S Z11 framebuffer device driver"); -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("XGITECH , Others"); -module_init(xgifb_init); -module_exit(xgifb_remove_module); diff --git a/drivers/staging/xgifb/XGIfb.h b/drivers/staging/xgifb/XGIfb.h deleted file mode 100644 index 982c676c16c6..000000000000 --- a/drivers/staging/xgifb/XGIfb.h +++ /dev/null @@ -1,109 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef _LINUX_XGIFB -#define _LINUX_XGIFB -#include "vgatypes.h" -#include "vb_struct.h" - -enum xgifb_display_type { - XGIFB_DISP_NONE = 0, - XGIFB_DISP_CRT, - XGIFB_DISP_LCD, - XGIFB_DISP_TV, -}; - -#define HASVB_NONE 0x00 -#define HASVB_301 0x01 -#define HASVB_LVDS 0x02 -#define HASVB_TRUMPION 0x04 -#define HASVB_LVDS_CHRONTEL 0x10 -#define HASVB_302 0x20 -#define HASVB_CHRONTEL 0x80 - -enum XGI_CHIP_TYPE { - XG40 = 32, - XG42, - XG20 = 48, - XG21, - XG27, -}; - -enum xgi_tvtype { - TVMODE_NTSC = 0, - TVMODE_PAL, - TVMODE_HIVISION, - TVTYPE_PALM, - TVTYPE_PALN, - TVTYPE_NTSCJ, - TVMODE_TOTAL -}; - -enum xgi_tv_plug { - TVPLUG_UNKNOWN = 0, - TVPLUG_COMPOSITE = 1, - TVPLUG_SVIDEO = 2, - TVPLUG_COMPOSITE_AND_SVIDEO = 3, - TVPLUG_SCART = 4, - TVPLUG_YPBPR_525i = 5, - TVPLUG_YPBPR_525P = 6, - TVPLUG_YPBPR_750P = 7, - TVPLUG_YPBPR_1080i = 8, - TVPLUG_TOTAL -}; - -struct xgifb_video_info { - struct fb_info *fb_info; - struct xgi_hw_device_info hw_info; - struct vb_device_info dev_info; - - int mode_idx; - int rate_idx; - - u32 pseudo_palette[17]; - - int chip_id; - unsigned int video_size; - phys_addr_t video_base; - void __iomem *video_vbase; - phys_addr_t mmio_base; - unsigned long mmio_size; - void __iomem *mmio_vbase; - unsigned long vga_base; - int mtrr; - - int video_bpp; - int video_cmap_len; - int video_width; - int video_height; - int video_vwidth; - int video_vheight; - int org_x; - int org_y; - int video_linelength; - unsigned int refresh_rate; - - enum xgifb_display_type display2; /* the second display output type */ - bool display2_force; - unsigned char hasVB; - unsigned char TV_type; - unsigned char TV_plug; - - struct XGI21_LVDSCapStruct lvds_data; - - enum XGI_CHIP_TYPE chip; - unsigned char revision_id; - - unsigned short DstColor; - unsigned long XGI310_AccelDepth; - unsigned long CommandReg; - - unsigned int pcibus; - unsigned int pcislot; - unsigned int pcifunc; - - unsigned short subsysvendor; - unsigned short subsysdevice; - - char reserved[236]; -}; - -#endif diff --git a/drivers/staging/xgifb/vb_def.h b/drivers/staging/xgifb/vb_def.h deleted file mode 100644 index 0311e2682d27..000000000000 --- a/drivers/staging/xgifb/vb_def.h +++ /dev/null @@ -1,257 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef _VB_DEF_ -#define _VB_DEF_ -#include "../../video/fbdev/sis/initdef.h" - -#define VB_XGI301C 0x0020 /* for 301C */ - -#define SupportCRT2in301C 0x0100 /* for 301C */ -#define SetCHTVOverScan 0x8000 - -#define PanelResInfo 0x1F /* CR36 Panel Type/LCDResInfo */ -#define Panel_1024x768x75 0x22 -#define Panel_1280x1024x75 0x23 - -#define PanelRef60Hz 0x00 -#define PanelRef75Hz 0x20 - -#define YPbPr525iVCLK 0x03B -#define YPbPr525iVCLK_2 0x03A - -#define XGI_CRT2_PORT_00 (0x00 - 0x030) - -#define SupportAllCRT2 0x0078 -#define NoSupportTV 0x0070 -#define NoSupportHiVisionTV 0x0060 -#define NoSupportLCD 0x0058 - -/* -------------- SetMode Stack/Scratch */ -#define XGI_SetCRT2ToLCDA 0x0100 -#define SetCRT2ToDualEdge 0x8000 - -#define ReserveTVOption 0x0008 - -#define SetTVLowResolution 0x0400 -#define TVSimuMode 0x0800 -#define RPLLDIV2XO 0x1000 -#define NTSC1024x768 0x2000 -#define SetTVLockMode 0x4000 - -#define XGI_LCDVESATiming 0x0001 /* LCD Info/CR37 */ -#define XGI_EnableLVDSDDA 0x0002 -#define EnableScalingLCD 0x0008 -#define SetPWDEnable 0x0004 -#define SetLCDtoNonExpanding 0x0010 -#define SetLCDDualLink 0x0100 -#define SetLCDLowResolution 0x0200 - -/* LCD Capability shampoo */ -#define DefaultLCDCap 0x80ea -#define EnableLCD24bpp 0x0004 /* default */ -#define LCDPolarity 0x00c0 /* default: SyncNN */ -#define XGI_LCDDualLink 0x0100 -#define EnableSpectrum 0x0200 -#define PWDEnable 0x0400 -#define EnableVBCLKDRVLOW 0x4000 -#define EnablePLLSPLOW 0x8000 - -#define AVIDEOSense 0x01 /* CR32 */ -#define SVIDEOSense 0x02 -#define SCARTSense 0x04 -#define LCDSense 0x08 -#define Monitor2Sense 0x10 -#define Monitor1Sense 0x20 -#define HiTVSense 0x40 - -#define YPbPrSense 0x80 /* NEW SCRATCH */ - -#define TVSense 0xc7 - -#define YPbPrMode 0xe0 -#define YPbPrMode525i 0x00 -#define YPbPrMode525p 0x20 -#define YPbPrMode750p 0x40 -#define YPbPrMode1080i 0x60 - -#define ScalingLCD 0x08 - -#define SetYPbPr 0x04 - -/* ---------------------- VUMA Information */ -#define DisplayDeviceFromCMOS 0x10 - -/* ---------------------- HK Evnet Definition */ -#define XGI_ModeSwitchStatus 0xf0 -#define ActiveCRT1 0x10 -#define ActiveLCD 0x0020 -#define ActiveTV 0x40 -#define ActiveCRT2 0x80 - -#define ActiveAVideo 0x01 -#define ActiveSVideo 0x02 -#define ActiveSCART 0x04 -#define ActiveHiTV 0x08 -#define ActiveYPbPr 0x10 - -#define NTSC1024x768HT 1908 - -#define YPbPrTV525iHT 1716 /* YPbPr */ -#define YPbPrTV525iVT 525 -#define YPbPrTV525pHT 1716 -#define YPbPrTV525pVT 525 -#define YPbPrTV750pHT 1650 -#define YPbPrTV750pVT 750 - -#define VCLK25_175 0x00 -#define VCLK28_322 0x01 -#define VCLK31_5 0x02 -#define VCLK36 0x03 -#define VCLK43_163 0x05 -#define VCLK44_9 0x06 -#define VCLK49_5 0x07 -#define VCLK50 0x08 -#define VCLK52_406 0x09 -#define VCLK56_25 0x0A -#define VCLK68_179 0x0D -#define VCLK72_852 0x0E -#define VCLK75 0x0F -#define VCLK78_75 0x11 -#define VCLK79_411 0x12 -#define VCLK83_95 0x13 -#define VCLK86_6 0x15 -#define VCLK94_5 0x16 -#define VCLK113_309 0x1B -#define VCLK116_406 0x1C -#define VCLK135_5 0x1E -#define VCLK139_054 0x1F -#define VCLK157_5 0x20 -#define VCLK162 0x21 -#define VCLK175 0x22 -#define VCLK189 0x23 -#define VCLK202_5 0x25 -#define VCLK229_5 0x26 -#define VCLK234 0x27 -#define VCLK254_817 0x29 -#define VCLK266_952 0x2B -#define VCLK269_655 0x2C -#define VCLK277_015 0x2E -#define VCLK291_132 0x30 -#define VCLK291_766 0x31 -#define VCLK315_195 0x33 -#define VCLK323_586 0x34 -#define VCLK330_615 0x35 -#define VCLK340_477 0x37 -#define VCLK375_847 0x38 -#define VCLK388_631 0x39 -#define VCLK125_999 0x51 -#define VCLK148_5 0x52 -#define VCLK217_325 0x55 -#define XGI_YPbPr750pVCLK 0x57 - -#define VCLK39_77 0x40 -#define YPbPr525pVCLK 0x3A -#define NTSC1024VCLK 0x41 -#define VCLK35_2 0x49 /* ; 800x480 */ -#define VCLK122_61 0x4A -#define VCLK80_350 0x4B -#define VCLK107_385 0x4C - -#define RES320x200 0x00 -#define RES320x240 0x01 -#define RES400x300 0x02 -#define RES512x384 0x03 -#define RES640x400 0x04 -#define RES640x480x60 0x05 -#define RES640x480x72 0x06 -#define RES640x480x75 0x07 -#define RES640x480x85 0x08 -#define RES640x480x100 0x09 -#define RES640x480x120 0x0A -#define RES640x480x160 0x0B -#define RES640x480x200 0x0C -#define RES800x600x56 0x0D -#define RES800x600x60 0x0E -#define RES800x600x72 0x0F -#define RES800x600x75 0x10 -#define RES800x600x85 0x11 -#define RES800x600x100 0x12 -#define RES800x600x120 0x13 -#define RES800x600x160 0x14 -#define RES1024x768x43 0x15 -#define RES1024x768x60 0x16 -#define RES1024x768x70 0x17 -#define RES1024x768x75 0x18 -#define RES1024x768x85 0x19 -#define RES1024x768x100 0x1A -#define RES1024x768x120 0x1B -#define RES1280x1024x43 0x1C -#define RES1280x1024x60 0x1D -#define RES1280x1024x75 0x1E -#define RES1280x1024x85 0x1F -#define RES1600x1200x60 0x20 -#define RES1600x1200x65 0x21 -#define RES1600x1200x70 0x22 -#define RES1600x1200x75 0x23 -#define RES1600x1200x85 0x24 -#define RES1600x1200x100 0x25 -#define RES1600x1200x120 0x26 -#define RES1920x1440x60 0x27 -#define RES1920x1440x65 0x28 -#define RES1920x1440x70 0x29 -#define RES1920x1440x75 0x2A -#define RES1920x1440x85 0x2B -#define RES1920x1440x100 0x2C -#define RES2048x1536x60 0x2D -#define RES2048x1536x65 0x2E -#define RES2048x1536x70 0x2F -#define RES2048x1536x75 0x30 -#define RES2048x1536x85 0x31 -#define RES800x480x60 0x32 -#define RES800x480x75 0x33 -#define RES800x480x85 0x34 -#define RES1024x576x60 0x35 -#define RES1024x576x75 0x36 -#define RES1024x576x85 0x37 -#define RES1280x720x60 0x38 -#define RES1280x720x75 0x39 -#define RES1280x720x85 0x3A -#define RES1280x960x60 0x3B -#define RES720x480x60 0x3C -#define RES720x576x56 0x3D -#define RES856x480x79I 0x3E -#define RES856x480x60 0x3F -#define RES1280x768x60 0x40 -#define RES1400x1050x60 0x41 -#define RES1152x864x60 0x42 -#define RES1152x864x75 0x43 -#define RES1024x768x160 0x44 -#define RES1280x960x75 0x45 -#define RES1280x960x85 0x46 -#define RES1280x960x120 0x47 - -#define XG27_CR8F 0x0C -#define XG27_SR36 0x30 -#define XG27_SR40 0x04 -#define XG27_SR41 0x00 -#define XG40_CRCF 0x13 -#define XGI330_CRT2Data_1_2 0 -#define XGI330_CRT2Data_4_D 0 -#define XGI330_CRT2Data_4_E 0 -#define XGI330_CRT2Data_4_10 0x80 -#define XGI330_SR07 0x18 -#define XGI330_SR1F 0 -#define XGI330_SR23 0xf6 -#define XGI330_SR24 0x0d -#define XGI330_SR31 0xc0 -#define XGI330_SR32 0x11 -#define XGI330_SR33 0 - -extern const struct XGI_ExtStruct XGI330_EModeIDTable[]; -extern const struct XGI_Ext2Struct XGI330_RefIndex[]; -extern const struct XGI_CRT1TableStruct XGI_CRT1Table[]; -extern const struct XGI_ECLKDataStruct XGI340_ECLKData[]; -extern const struct SiS_VCLKData XGI_VCLKData[]; -extern const unsigned char XGI340_CR6B[][4]; -extern const unsigned char XGI340_AGPReg[]; - -#endif diff --git a/drivers/staging/xgifb/vb_init.c b/drivers/staging/xgifb/vb_init.c deleted file mode 100644 index ac1c815a3c5e..000000000000 --- a/drivers/staging/xgifb/vb_init.c +++ /dev/null @@ -1,1367 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include <linux/delay.h> -#include <linux/vmalloc.h> - -#include "XGIfb.h" -#include "vb_def.h" -#include "vb_util.h" -#include "vb_setmode.h" -#include "vb_init.h" -static const unsigned short XGINew_DDRDRAM_TYPE340[4][2] = { - { 16, 0x45}, - { 8, 0x35}, - { 4, 0x31}, - { 2, 0x21} }; - -static const unsigned short XGINew_DDRDRAM_TYPE20[12][2] = { - { 128, 0x5D}, - { 64, 0x59}, - { 64, 0x4D}, - { 32, 0x55}, - { 32, 0x49}, - { 32, 0x3D}, - { 16, 0x51}, - { 16, 0x45}, - { 16, 0x39}, - { 8, 0x41}, - { 8, 0x35}, - { 4, 0x31} }; - -#define XGIFB_ROM_SIZE 65536 - -static unsigned char -XGINew_GetXG20DRAMType(struct xgi_hw_device_info *HwDeviceExtension, - struct vb_device_info *pVBInfo) -{ - unsigned char data, temp; - - if (HwDeviceExtension->jChipType < XG20) { - data = xgifb_reg_get(pVBInfo->P3c4, 0x39) & 0x02; - if (data == 0) - data = (xgifb_reg_get(pVBInfo->P3c4, 0x3A) & - 0x02) >> 1; - return data; - } else if (HwDeviceExtension->jChipType == XG27) { - temp = xgifb_reg_get(pVBInfo->P3c4, 0x3B); - /* SR3B[7][3]MAA15 MAA11 (Power on Trapping) */ - if (((temp & 0x88) == 0x80) || ((temp & 0x88) == 0x08)) - data = 0; /* DDR */ - else - data = 1; /* DDRII */ - return data; - } else if (HwDeviceExtension->jChipType == XG21) { - /* Independent GPIO control */ - xgifb_reg_and(pVBInfo->P3d4, 0xB4, ~0x02); - usleep_range(800, 1800); - xgifb_reg_or(pVBInfo->P3d4, 0x4A, 0x80); /* Enable GPIOH read */ - /* GPIOF 0:DVI 1:DVO */ - data = xgifb_reg_get(pVBInfo->P3d4, 0x48); - /* - * HOTPLUG_SUPPORT - * for current XG20 & XG21, GPIOH is floating, driver will - * fix DDR temporarily - */ - /* DVI read GPIOH */ - data &= 0x01; /* 1=DDRII, 0=DDR */ - /* ~HOTPLUG_SUPPORT */ - xgifb_reg_or(pVBInfo->P3d4, 0xB4, 0x02); - return data; - } - data = xgifb_reg_get(pVBInfo->P3d4, 0x97) & 0x01; - - if (data == 1) - data++; - - return data; -} - -static void XGINew_DDR1x_MRS_340(unsigned long P3c4, - struct vb_device_info *pVBInfo) -{ - xgifb_reg_set(P3c4, 0x18, 0x01); - xgifb_reg_set(P3c4, 0x19, 0x20); - xgifb_reg_set(P3c4, 0x16, 0x00); - xgifb_reg_set(P3c4, 0x16, 0x80); - - usleep_range(3, 1003); - xgifb_reg_set(P3c4, 0x18, 0x00); - xgifb_reg_set(P3c4, 0x19, 0x20); - xgifb_reg_set(P3c4, 0x16, 0x00); - xgifb_reg_set(P3c4, 0x16, 0x80); - - usleep_range(60, 1060); - xgifb_reg_set(P3c4, 0x18, pVBInfo->SR18[pVBInfo->ram_type]); /* SR18 */ - xgifb_reg_set(P3c4, 0x19, 0x01); - xgifb_reg_set(P3c4, 0x16, 0x03); - xgifb_reg_set(P3c4, 0x16, 0x83); - usleep_range(1, 1001); - xgifb_reg_set(P3c4, 0x1B, 0x03); - usleep_range(500, 1500); - xgifb_reg_set(P3c4, 0x18, pVBInfo->SR18[pVBInfo->ram_type]); /* SR18 */ - xgifb_reg_set(P3c4, 0x19, 0x00); - xgifb_reg_set(P3c4, 0x16, 0x03); - xgifb_reg_set(P3c4, 0x16, 0x83); - xgifb_reg_set(P3c4, 0x1B, 0x00); -} - -static void XGINew_SetMemoryClock(struct vb_device_info *pVBInfo) -{ - xgifb_reg_set(pVBInfo->P3c4, - 0x28, - pVBInfo->MCLKData[pVBInfo->ram_type].SR28); - xgifb_reg_set(pVBInfo->P3c4, - 0x29, - pVBInfo->MCLKData[pVBInfo->ram_type].SR29); - xgifb_reg_set(pVBInfo->P3c4, - 0x2A, - pVBInfo->MCLKData[pVBInfo->ram_type].SR2A); - - xgifb_reg_set(pVBInfo->P3c4, - 0x2E, - XGI340_ECLKData[pVBInfo->ram_type].SR2E); - xgifb_reg_set(pVBInfo->P3c4, - 0x2F, - XGI340_ECLKData[pVBInfo->ram_type].SR2F); - xgifb_reg_set(pVBInfo->P3c4, - 0x30, - XGI340_ECLKData[pVBInfo->ram_type].SR30); -} - -static void XGINew_DDRII_Bootup_XG27( - struct xgi_hw_device_info *HwDeviceExtension, - unsigned long P3c4, struct vb_device_info *pVBInfo) -{ - unsigned long P3d4 = P3c4 + 0x10; - - pVBInfo->ram_type = XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo); - XGINew_SetMemoryClock(pVBInfo); - - /* Set Double Frequency */ - xgifb_reg_set(P3d4, 0x97, pVBInfo->XGINew_CR97); /* CR97 */ - - usleep_range(200, 1200); - - xgifb_reg_set(P3c4, 0x18, 0x00); /* Set SR18 */ /* EMRS2 */ - xgifb_reg_set(P3c4, 0x19, 0x80); /* Set SR19 */ - xgifb_reg_set(P3c4, 0x16, 0x20); /* Set SR16 */ - usleep_range(15, 1015); - xgifb_reg_set(P3c4, 0x16, 0xA0); /* Set SR16 */ - usleep_range(15, 1015); - - xgifb_reg_set(P3c4, 0x18, 0x00); /* Set SR18 */ /* EMRS3 */ - xgifb_reg_set(P3c4, 0x19, 0xC0); /* Set SR19 */ - xgifb_reg_set(P3c4, 0x16, 0x20); /* Set SR16 */ - usleep_range(15, 1015); - xgifb_reg_set(P3c4, 0x16, 0xA0); /* Set SR16 */ - usleep_range(15, 1015); - - xgifb_reg_set(P3c4, 0x18, 0x00); /* Set SR18 */ /* EMRS1 */ - xgifb_reg_set(P3c4, 0x19, 0x40); /* Set SR19 */ - xgifb_reg_set(P3c4, 0x16, 0x20); /* Set SR16 */ - usleep_range(30, 1030); - xgifb_reg_set(P3c4, 0x16, 0xA0); /* Set SR16 */ - usleep_range(15, 1015); - - xgifb_reg_set(P3c4, 0x18, 0x42); /* Set SR18 */ /* MRS, DLL Enable */ - xgifb_reg_set(P3c4, 0x19, 0x0A); /* Set SR19 */ - xgifb_reg_set(P3c4, 0x16, 0x00); /* Set SR16 */ - usleep_range(30, 1030); - xgifb_reg_set(P3c4, 0x16, 0x00); /* Set SR16 */ - xgifb_reg_set(P3c4, 0x16, 0x80); /* Set SR16 */ - - xgifb_reg_set(P3c4, 0x1B, 0x04); /* Set SR1B */ - usleep_range(60, 1060); - xgifb_reg_set(P3c4, 0x1B, 0x00); /* Set SR1B */ - - xgifb_reg_set(P3c4, 0x18, 0x42); /* Set SR18 */ /* MRS, DLL Reset */ - xgifb_reg_set(P3c4, 0x19, 0x08); /* Set SR19 */ - xgifb_reg_set(P3c4, 0x16, 0x00); /* Set SR16 */ - - usleep_range(30, 1030); - xgifb_reg_set(P3c4, 0x16, 0x83); /* Set SR16 */ - usleep_range(15, 1015); - - xgifb_reg_set(P3c4, 0x18, 0x80); /* Set SR18 */ /* MRS, ODT */ - xgifb_reg_set(P3c4, 0x19, 0x46); /* Set SR19 */ - xgifb_reg_set(P3c4, 0x16, 0x20); /* Set SR16 */ - usleep_range(30, 1030); - xgifb_reg_set(P3c4, 0x16, 0xA0); /* Set SR16 */ - usleep_range(15, 1015); - - xgifb_reg_set(P3c4, 0x18, 0x00); /* Set SR18 */ /* EMRS */ - xgifb_reg_set(P3c4, 0x19, 0x40); /* Set SR19 */ - xgifb_reg_set(P3c4, 0x16, 0x20); /* Set SR16 */ - usleep_range(30, 1030); - xgifb_reg_set(P3c4, 0x16, 0xA0); /* Set SR16 */ - usleep_range(15, 1015); - - /* Set SR1B refresh control 000:close; 010:open */ - xgifb_reg_set(P3c4, 0x1B, 0x04); - usleep_range(200, 1200); -} - -static void XGINew_DDR2_MRS_XG20(struct xgi_hw_device_info *HwDeviceExtension, - unsigned long P3c4, - struct vb_device_info *pVBInfo) -{ - unsigned long P3d4 = P3c4 + 0x10; - - pVBInfo->ram_type = XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo); - XGINew_SetMemoryClock(pVBInfo); - - xgifb_reg_set(P3d4, 0x97, 0x11); /* CR97 */ - - usleep_range(200, 1200); - xgifb_reg_set(P3c4, 0x18, 0x00); /* EMRS2 */ - xgifb_reg_set(P3c4, 0x19, 0x80); - xgifb_reg_set(P3c4, 0x16, 0x05); - xgifb_reg_set(P3c4, 0x16, 0x85); - - xgifb_reg_set(P3c4, 0x18, 0x00); /* EMRS3 */ - xgifb_reg_set(P3c4, 0x19, 0xC0); - xgifb_reg_set(P3c4, 0x16, 0x05); - xgifb_reg_set(P3c4, 0x16, 0x85); - - xgifb_reg_set(P3c4, 0x18, 0x00); /* EMRS1 */ - xgifb_reg_set(P3c4, 0x19, 0x40); - xgifb_reg_set(P3c4, 0x16, 0x05); - xgifb_reg_set(P3c4, 0x16, 0x85); - - xgifb_reg_set(P3c4, 0x18, 0x42); /* MRS1 */ - xgifb_reg_set(P3c4, 0x19, 0x02); - xgifb_reg_set(P3c4, 0x16, 0x05); - xgifb_reg_set(P3c4, 0x16, 0x85); - - usleep_range(15, 1015); - xgifb_reg_set(P3c4, 0x1B, 0x04); /* SR1B */ - usleep_range(30, 1030); - xgifb_reg_set(P3c4, 0x1B, 0x00); /* SR1B */ - usleep_range(100, 1100); - - xgifb_reg_set(P3c4, 0x18, 0x42); /* MRS1 */ - xgifb_reg_set(P3c4, 0x19, 0x00); - xgifb_reg_set(P3c4, 0x16, 0x05); - xgifb_reg_set(P3c4, 0x16, 0x85); - - usleep_range(200, 1200); -} - -static void XGINew_DDR1x_MRS_XG20(unsigned long P3c4, - struct vb_device_info *pVBInfo) -{ - xgifb_reg_set(P3c4, 0x18, 0x01); - xgifb_reg_set(P3c4, 0x19, 0x40); - xgifb_reg_set(P3c4, 0x16, 0x00); - xgifb_reg_set(P3c4, 0x16, 0x80); - usleep_range(60, 1060); - - xgifb_reg_set(P3c4, 0x18, 0x00); - xgifb_reg_set(P3c4, 0x19, 0x40); - xgifb_reg_set(P3c4, 0x16, 0x00); - xgifb_reg_set(P3c4, 0x16, 0x80); - usleep_range(60, 1060); - xgifb_reg_set(P3c4, 0x18, pVBInfo->SR18[pVBInfo->ram_type]); /* SR18 */ - xgifb_reg_set(P3c4, 0x19, 0x01); - xgifb_reg_set(P3c4, 0x16, 0x03); - xgifb_reg_set(P3c4, 0x16, 0x83); - usleep_range(1, 1001); - xgifb_reg_set(P3c4, 0x1B, 0x03); - usleep_range(500, 1500); - xgifb_reg_set(P3c4, 0x18, pVBInfo->SR18[pVBInfo->ram_type]); /* SR18 */ - xgifb_reg_set(P3c4, 0x19, 0x00); - xgifb_reg_set(P3c4, 0x16, 0x03); - xgifb_reg_set(P3c4, 0x16, 0x83); - xgifb_reg_set(P3c4, 0x1B, 0x00); -} - -static void XGINew_DDR1x_DefaultRegister( - struct xgi_hw_device_info *HwDeviceExtension, - unsigned long Port, struct vb_device_info *pVBInfo) -{ - unsigned long P3d4 = Port, P3c4 = Port - 0x10; - - if (HwDeviceExtension->jChipType >= XG20) { - XGINew_SetMemoryClock(pVBInfo); - xgifb_reg_set(P3d4, - 0x82, - pVBInfo->CR40[11][pVBInfo->ram_type]); /* CR82 */ - xgifb_reg_set(P3d4, - 0x85, - pVBInfo->CR40[12][pVBInfo->ram_type]); /* CR85 */ - xgifb_reg_set(P3d4, - 0x86, - pVBInfo->CR40[13][pVBInfo->ram_type]); /* CR86 */ - - xgifb_reg_set(P3d4, 0x98, 0x01); - xgifb_reg_set(P3d4, 0x9A, 0x02); - - XGINew_DDR1x_MRS_XG20(P3c4, pVBInfo); - } else { - XGINew_SetMemoryClock(pVBInfo); - - switch (HwDeviceExtension->jChipType) { - case XG42: - /* CR82 */ - xgifb_reg_set(P3d4, - 0x82, - pVBInfo->CR40[11][pVBInfo->ram_type]); - /* CR85 */ - xgifb_reg_set(P3d4, - 0x85, - pVBInfo->CR40[12][pVBInfo->ram_type]); - /* CR86 */ - xgifb_reg_set(P3d4, - 0x86, - pVBInfo->CR40[13][pVBInfo->ram_type]); - break; - default: - xgifb_reg_set(P3d4, 0x82, 0x88); - xgifb_reg_set(P3d4, 0x86, 0x00); - /* Insert read command for delay */ - xgifb_reg_get(P3d4, 0x86); - xgifb_reg_set(P3d4, 0x86, 0x88); - xgifb_reg_get(P3d4, 0x86); - xgifb_reg_set(P3d4, - 0x86, - pVBInfo->CR40[13][pVBInfo->ram_type]); - xgifb_reg_set(P3d4, 0x82, 0x77); - xgifb_reg_set(P3d4, 0x85, 0x00); - - /* Insert read command for delay */ - xgifb_reg_get(P3d4, 0x85); - xgifb_reg_set(P3d4, 0x85, 0x88); - - /* Insert read command for delay */ - xgifb_reg_get(P3d4, 0x85); - /* CR85 */ - xgifb_reg_set(P3d4, - 0x85, - pVBInfo->CR40[12][pVBInfo->ram_type]); - /* CR82 */ - xgifb_reg_set(P3d4, - 0x82, - pVBInfo->CR40[11][pVBInfo->ram_type]); - break; - } - - xgifb_reg_set(P3d4, 0x97, 0x00); - xgifb_reg_set(P3d4, 0x98, 0x01); - xgifb_reg_set(P3d4, 0x9A, 0x02); - XGINew_DDR1x_MRS_340(P3c4, pVBInfo); - } -} - -static void XGINew_DDR2_DefaultRegister( - struct xgi_hw_device_info *HwDeviceExtension, - unsigned long Port, struct vb_device_info *pVBInfo) -{ - unsigned long P3d4 = Port, P3c4 = Port - 0x10; - /* - * keep following setting sequence, each setting in - * the same reg insert idle - */ - xgifb_reg_set(P3d4, 0x82, 0x77); - xgifb_reg_set(P3d4, 0x86, 0x00); - xgifb_reg_get(P3d4, 0x86); /* Insert read command for delay */ - xgifb_reg_set(P3d4, 0x86, 0x88); - xgifb_reg_get(P3d4, 0x86); /* Insert read command for delay */ - /* CR86 */ - xgifb_reg_set(P3d4, 0x86, pVBInfo->CR40[13][pVBInfo->ram_type]); - xgifb_reg_set(P3d4, 0x82, 0x77); - xgifb_reg_set(P3d4, 0x85, 0x00); - xgifb_reg_get(P3d4, 0x85); /* Insert read command for delay */ - xgifb_reg_set(P3d4, 0x85, 0x88); - xgifb_reg_get(P3d4, 0x85); /* Insert read command for delay */ - xgifb_reg_set(P3d4, - 0x85, - pVBInfo->CR40[12][pVBInfo->ram_type]); /* CR85 */ - if (HwDeviceExtension->jChipType == XG27) - /* CR82 */ - xgifb_reg_set(P3d4, 0x82, pVBInfo->CR40[11][pVBInfo->ram_type]); - else - xgifb_reg_set(P3d4, 0x82, 0xA8); /* CR82 */ - - xgifb_reg_set(P3d4, 0x98, 0x01); - xgifb_reg_set(P3d4, 0x9A, 0x02); - if (HwDeviceExtension->jChipType == XG27) - XGINew_DDRII_Bootup_XG27(HwDeviceExtension, P3c4, pVBInfo); - else - XGINew_DDR2_MRS_XG20(HwDeviceExtension, P3c4, pVBInfo); -} - -static void XGI_SetDRAM_Helper(unsigned long P3d4, u8 seed, u8 temp2, u8 reg, - u8 shift_factor, u8 mask1, u8 mask2) -{ - u8 j; - - for (j = 0; j < 4; j++) { - temp2 |= (((seed >> (2 * j)) & 0x03) << shift_factor); - xgifb_reg_set(P3d4, reg, temp2); - xgifb_reg_get(P3d4, reg); - temp2 &= mask1; - temp2 += mask2; - } -} - -static void XGINew_SetDRAMDefaultRegister340( - struct xgi_hw_device_info *HwDeviceExtension, - unsigned long Port, struct vb_device_info *pVBInfo) -{ - unsigned char temp, temp1, temp2, temp3, j, k; - - unsigned long P3d4 = Port, P3c4 = Port - 0x10; - - xgifb_reg_set(P3d4, 0x6D, pVBInfo->CR40[8][pVBInfo->ram_type]); - xgifb_reg_set(P3d4, 0x68, pVBInfo->CR40[5][pVBInfo->ram_type]); - xgifb_reg_set(P3d4, 0x69, pVBInfo->CR40[6][pVBInfo->ram_type]); - xgifb_reg_set(P3d4, 0x6A, pVBInfo->CR40[7][pVBInfo->ram_type]); - - /* CR6B DQS fine tune delay */ - temp = 0xaa; - XGI_SetDRAM_Helper(P3d4, temp, 0, 0x6B, 2, 0xF0, 0x10); - - /* CR6E DQM fine tune delay */ - XGI_SetDRAM_Helper(P3d4, 0, 0, 0x6E, 2, 0xF0, 0x10); - - temp3 = 0; - for (k = 0; k < 4; k++) { - /* CR6E_D[1:0] select channel */ - xgifb_reg_and_or(P3d4, 0x6E, 0xFC, temp3); - XGI_SetDRAM_Helper(P3d4, 0, 0, 0x6F, 0, 0xF8, 0x08); - temp3 += 0x01; - } - - xgifb_reg_set(P3d4, - 0x80, - pVBInfo->CR40[9][pVBInfo->ram_type]); /* CR80 */ - xgifb_reg_set(P3d4, - 0x81, - pVBInfo->CR40[10][pVBInfo->ram_type]); /* CR81 */ - - temp2 = 0x80; - /* CR89 terminator type select */ - XGI_SetDRAM_Helper(P3d4, 0, temp2, 0x89, 0, 0xF0, 0x10); - - temp = 0; - temp1 = temp & 0x03; - temp2 |= temp1; - xgifb_reg_set(P3d4, 0x89, temp2); - - temp = pVBInfo->CR40[3][pVBInfo->ram_type]; - temp1 = temp & 0x0F; - temp2 = (temp >> 4) & 0x07; - temp3 = temp & 0x80; - xgifb_reg_set(P3d4, 0x45, temp1); /* CR45 */ - xgifb_reg_set(P3d4, 0x99, temp2); /* CR99 */ - xgifb_reg_or(P3d4, 0x40, temp3); /* CR40_D[7] */ - xgifb_reg_set(P3d4, - 0x41, - pVBInfo->CR40[0][pVBInfo->ram_type]); /* CR41 */ - - if (HwDeviceExtension->jChipType == XG27) - xgifb_reg_set(P3d4, 0x8F, XG27_CR8F); /* CR8F */ - - for (j = 0; j <= 6; j++) /* CR90 - CR96 */ - xgifb_reg_set(P3d4, (0x90 + j), - pVBInfo->CR40[14 + j][pVBInfo->ram_type]); - - for (j = 0; j <= 2; j++) /* CRC3 - CRC5 */ - xgifb_reg_set(P3d4, (0xC3 + j), - pVBInfo->CR40[21 + j][pVBInfo->ram_type]); - - for (j = 0; j < 2; j++) /* CR8A - CR8B */ - xgifb_reg_set(P3d4, (0x8A + j), - pVBInfo->CR40[1 + j][pVBInfo->ram_type]); - - if (HwDeviceExtension->jChipType == XG42) - xgifb_reg_set(P3d4, 0x8C, 0x87); - - xgifb_reg_set(P3d4, - 0x59, - pVBInfo->CR40[4][pVBInfo->ram_type]); /* CR59 */ - - xgifb_reg_set(P3d4, 0x83, 0x09); /* CR83 */ - xgifb_reg_set(P3d4, 0x87, 0x00); /* CR87 */ - xgifb_reg_set(P3d4, 0xCF, XG40_CRCF); /* CRCF */ - if (pVBInfo->ram_type) { - xgifb_reg_set(P3c4, 0x17, 0x80); /* SR17 DDRII */ - if (HwDeviceExtension->jChipType == XG27) - xgifb_reg_set(P3c4, 0x17, 0x02); /* SR17 DDRII */ - - } else { - xgifb_reg_set(P3c4, 0x17, 0x00); /* SR17 DDR */ - } - xgifb_reg_set(P3c4, 0x1A, 0x87); /* SR1A */ - - temp = XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo); - if (temp == 0) { - XGINew_DDR1x_DefaultRegister(HwDeviceExtension, P3d4, pVBInfo); - } else { - xgifb_reg_set(P3d4, 0xB0, 0x80); /* DDRII Dual frequency mode */ - XGINew_DDR2_DefaultRegister(HwDeviceExtension, P3d4, pVBInfo); - } - xgifb_reg_set(P3c4, 0x1B, 0x03); /* SR1B */ -} - -static unsigned short XGINew_SetDRAMSize20Reg( - unsigned short dram_size, - struct vb_device_info *pVBInfo) -{ - unsigned short data = 0, memsize = 0; - int RankSize; - unsigned char ChannelNo; - - RankSize = dram_size * pVBInfo->ram_bus / 8; - data = xgifb_reg_get(pVBInfo->P3c4, 0x13); - data &= 0x80; - - if (data == 0x80) - RankSize *= 2; - - data = 0; - - if (pVBInfo->ram_channel == 3) - ChannelNo = 4; - else - ChannelNo = pVBInfo->ram_channel; - - if (ChannelNo * RankSize <= 256) { - while ((RankSize >>= 1) > 0) - data += 0x10; - - memsize = data >> 4; - - /* Fix DRAM Sizing Error */ - xgifb_reg_set(pVBInfo->P3c4, - 0x14, - (xgifb_reg_get(pVBInfo->P3c4, 0x14) & 0x0F) | - (data & 0xF0)); - usleep_range(15, 1015); - } - return memsize; -} - -static int XGINew_ReadWriteRest(unsigned short StopAddr, - unsigned short StartAddr, - struct vb_device_info *pVBInfo) -{ - int i; - unsigned long Position = 0; - void __iomem *fbaddr = pVBInfo->FBAddr; - - writel(Position, fbaddr + Position); - - for (i = StartAddr; i <= StopAddr; i++) { - Position = 1 << i; - writel(Position, fbaddr + Position); - } - - /* Fix #1759 Memory Size error in Multi-Adapter. */ - usleep_range(500, 1500); - - Position = 0; - - if (readl(fbaddr + Position) != Position) - return 0; - - for (i = StartAddr; i <= StopAddr; i++) { - Position = 1 << i; - if (readl(fbaddr + Position) != Position) - return 0; - } - return 1; -} - -static unsigned char XGINew_CheckFrequence(struct vb_device_info *pVBInfo) -{ - unsigned char data; - - data = xgifb_reg_get(pVBInfo->P3d4, 0x97); - - if ((data & 0x10) == 0) { - data = xgifb_reg_get(pVBInfo->P3c4, 0x39); - return (data & 0x02) >> 1; - } - return data & 0x01; -} - -static void XGINew_CheckChannel(struct xgi_hw_device_info *HwDeviceExtension, - struct vb_device_info *pVBInfo) -{ - unsigned char data; - - switch (HwDeviceExtension->jChipType) { - case XG20: - case XG21: - data = xgifb_reg_get(pVBInfo->P3d4, 0x97); - data = data & 0x01; - pVBInfo->ram_channel = 1; /* XG20 "JUST" one channel */ - - if (data == 0) { /* Single_32_16 */ - - if ((HwDeviceExtension->ulVideoMemorySize - 1) - > 0x1000000) { - pVBInfo->ram_bus = 32; /* 32 bits */ - /* 22bit + 2 rank + 32bit */ - xgifb_reg_set(pVBInfo->P3c4, 0x13, 0xB1); - xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x52); - usleep_range(15, 1015); - - if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1) - return; - - if ((HwDeviceExtension->ulVideoMemorySize - 1) > - 0x800000) { - /* 22bit + 1 rank + 32bit */ - xgifb_reg_set(pVBInfo->P3c4, - 0x13, - 0x31); - xgifb_reg_set(pVBInfo->P3c4, - 0x14, - 0x42); - usleep_range(15, 1015); - - if (XGINew_ReadWriteRest(23, - 23, - pVBInfo) == 1) - return; - } - } - - if ((HwDeviceExtension->ulVideoMemorySize - 1) > - 0x800000) { - pVBInfo->ram_bus = 16; /* 16 bits */ - /* 22bit + 2 rank + 16bit */ - xgifb_reg_set(pVBInfo->P3c4, 0x13, 0xB1); - xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x41); - usleep_range(15, 1015); - - if (XGINew_ReadWriteRest(23, 22, pVBInfo) == 1) - return; - xgifb_reg_set(pVBInfo->P3c4, - 0x13, - 0x31); - usleep_range(15, 1015); - } - - } else { /* Dual_16_8 */ - if ((HwDeviceExtension->ulVideoMemorySize - 1) > - 0x800000) { - pVBInfo->ram_bus = 16; /* 16 bits */ - /* (0x31:12x8x2) 22bit + 2 rank */ - xgifb_reg_set(pVBInfo->P3c4, 0x13, 0xB1); - /* 0x41:16Mx16 bit */ - xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x41); - usleep_range(15, 1015); - - if (XGINew_ReadWriteRest(23, 22, pVBInfo) == 1) - return; - - if ((HwDeviceExtension->ulVideoMemorySize - 1) > - 0x400000) { - /* (0x31:12x8x2) 22bit + 1 rank */ - xgifb_reg_set(pVBInfo->P3c4, - 0x13, - 0x31); - /* 0x31:8Mx16 bit */ - xgifb_reg_set(pVBInfo->P3c4, - 0x14, - 0x31); - usleep_range(15, 1015); - - if (XGINew_ReadWriteRest(22, - 22, - pVBInfo) == 1) - return; - } - } - - if ((HwDeviceExtension->ulVideoMemorySize - 1) > - 0x400000) { - pVBInfo->ram_bus = 8; /* 8 bits */ - /* (0x31:12x8x2) 22bit + 2 rank */ - xgifb_reg_set(pVBInfo->P3c4, 0x13, 0xB1); - /* 0x30:8Mx8 bit */ - xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x30); - usleep_range(15, 1015); - - if (XGINew_ReadWriteRest(22, 21, pVBInfo) == 1) - return; - - /* (0x31:12x8x2) 22bit + 1 rank */ - xgifb_reg_set(pVBInfo->P3c4, - 0x13, - 0x31); - usleep_range(15, 1015); - } - } - break; - - case XG27: - pVBInfo->ram_bus = 16; /* 16 bits */ - pVBInfo->ram_channel = 1; /* Single channel */ - xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x51); /* 32Mx16 bit */ - break; - case XG42: - /* - * XG42 SR14 D[3] Reserve - * D[2] = 1, Dual Channel - * = 0, Single Channel - * - * It's Different from Other XG40 Series. - */ - if (XGINew_CheckFrequence(pVBInfo) == 1) { /* DDRII, DDR2x */ - pVBInfo->ram_bus = 32; /* 32 bits */ - pVBInfo->ram_channel = 2; /* 2 Channel */ - xgifb_reg_set(pVBInfo->P3c4, 0x13, 0xA1); - xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x44); - - if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1) - return; - - xgifb_reg_set(pVBInfo->P3c4, 0x13, 0x21); - xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x34); - if (XGINew_ReadWriteRest(23, 22, pVBInfo) == 1) - return; - - pVBInfo->ram_channel = 1; /* Single Channel */ - xgifb_reg_set(pVBInfo->P3c4, 0x13, 0xA1); - xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x40); - - if (XGINew_ReadWriteRest(23, 22, pVBInfo) == 1) - return; - xgifb_reg_set(pVBInfo->P3c4, 0x13, 0x21); - xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x30); - } else { /* DDR */ - pVBInfo->ram_bus = 64; /* 64 bits */ - pVBInfo->ram_channel = 1; /* 1 channels */ - xgifb_reg_set(pVBInfo->P3c4, 0x13, 0xA1); - xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x52); - - if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1) - return; - xgifb_reg_set(pVBInfo->P3c4, 0x13, 0x21); - xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x42); - } - - break; - - default: /* XG40 */ - - if (XGINew_CheckFrequence(pVBInfo) == 1) { /* DDRII */ - pVBInfo->ram_bus = 32; /* 32 bits */ - pVBInfo->ram_channel = 3; - xgifb_reg_set(pVBInfo->P3c4, 0x13, 0xA1); - xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x4C); - - if (XGINew_ReadWriteRest(25, 23, pVBInfo) == 1) - return; - - pVBInfo->ram_channel = 2; /* 2 channels */ - xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x48); - - if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1) - return; - - xgifb_reg_set(pVBInfo->P3c4, 0x13, 0x21); - xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x3C); - - if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1) { - pVBInfo->ram_channel = 3; /* 4 channels */ - } else { - pVBInfo->ram_channel = 2; /* 2 channels */ - xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x38); - } - } else { /* DDR */ - pVBInfo->ram_bus = 64; /* 64 bits */ - pVBInfo->ram_channel = 2; /* 2 channels */ - xgifb_reg_set(pVBInfo->P3c4, 0x13, 0xA1); - xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x5A); - - if (XGINew_ReadWriteRest(25, 24, pVBInfo) == 1) - return; - xgifb_reg_set(pVBInfo->P3c4, 0x13, 0x21); - xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x4A); - } - break; - } -} - -static int XGINew_DDRSizing340(struct xgi_hw_device_info *HwDeviceExtension, - struct vb_device_info *pVBInfo) -{ - u8 i, size; - unsigned short memsize, start_addr; - const unsigned short (*dram_table)[2]; - - xgifb_reg_set(pVBInfo->P3c4, 0x15, 0x00); /* noninterleaving */ - xgifb_reg_set(pVBInfo->P3c4, 0x1C, 0x00); /* nontiling */ - XGINew_CheckChannel(HwDeviceExtension, pVBInfo); - - if (HwDeviceExtension->jChipType >= XG20) { - dram_table = XGINew_DDRDRAM_TYPE20; - size = ARRAY_SIZE(XGINew_DDRDRAM_TYPE20); - start_addr = 5; - } else { - dram_table = XGINew_DDRDRAM_TYPE340; - size = ARRAY_SIZE(XGINew_DDRDRAM_TYPE340); - start_addr = 9; - } - - for (i = 0; i < size; i++) { - /* SetDRAMSizingType */ - xgifb_reg_and_or(pVBInfo->P3c4, 0x13, 0x80, dram_table[i][1]); - usleep_range(50, 1050); /* should delay 50 ns */ - - memsize = XGINew_SetDRAMSize20Reg(dram_table[i][0], pVBInfo); - - if (memsize == 0) - continue; - - memsize += (pVBInfo->ram_channel - 2) + 20; - if ((HwDeviceExtension->ulVideoMemorySize - 1) < - (unsigned long)(1 << memsize)) - continue; - - if (XGINew_ReadWriteRest(memsize, start_addr, pVBInfo) == 1) - return 1; - } - return 0; -} - -static void XGINew_SetDRAMSize_340(struct xgifb_video_info *xgifb_info, - struct xgi_hw_device_info *HwDeviceExtension, - struct vb_device_info *pVBInfo) -{ - unsigned short data; - - pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress; - - XGISetModeNew(xgifb_info, HwDeviceExtension, 0x2e); - - data = xgifb_reg_get(pVBInfo->P3c4, 0x21); - /* disable read cache */ - xgifb_reg_set(pVBInfo->P3c4, 0x21, (unsigned short)(data & 0xDF)); - XGI_DisplayOff(xgifb_info, HwDeviceExtension, pVBInfo); - - XGINew_DDRSizing340(HwDeviceExtension, pVBInfo); - data = xgifb_reg_get(pVBInfo->P3c4, 0x21); - /* enable read cache */ - xgifb_reg_set(pVBInfo->P3c4, 0x21, (unsigned short)(data | 0x20)); -} - -static u8 *xgifb_copy_rom(struct pci_dev *dev, size_t *rom_size) -{ - void __iomem *rom_address; - u8 *rom_copy; - - rom_address = pci_map_rom(dev, rom_size); - if (!rom_address) - return NULL; - - rom_copy = vzalloc(XGIFB_ROM_SIZE); - if (!rom_copy) - goto done; - - *rom_size = min_t(size_t, *rom_size, XGIFB_ROM_SIZE); - memcpy_fromio(rom_copy, rom_address, *rom_size); - -done: - pci_unmap_rom(dev, rom_address); - return rom_copy; -} - -static bool xgifb_read_vbios(struct pci_dev *pdev) -{ - struct xgifb_video_info *xgifb_info = pci_get_drvdata(pdev); - u8 *vbios; - unsigned long i; - unsigned char j; - struct XGI21_LVDSCapStruct *lvds; - size_t vbios_size; - int entry; - - vbios = xgifb_copy_rom(pdev, &vbios_size); - if (!vbios) { - dev_err(&pdev->dev, "Video BIOS not available\n"); - return false; - } - if (vbios_size <= 0x65) - goto error; - /* - * The user can ignore the LVDS bit in the BIOS and force the display - * type. - */ - if (!(vbios[0x65] & 0x1) && - (!xgifb_info->display2_force || - xgifb_info->display2 != XGIFB_DISP_LCD)) { - vfree(vbios); - return false; - } - if (vbios_size <= 0x317) - goto error; - i = vbios[0x316] | (vbios[0x317] << 8); - if (vbios_size <= i - 1) - goto error; - j = vbios[i - 1]; - if (j == 0) - goto error; - if (j == 0xff) - j = 1; - - /* Read the LVDS table index scratch register set by the BIOS. */ - - entry = xgifb_reg_get(xgifb_info->dev_info.P3d4, 0x36); - if (entry >= j) - entry = 0; - i += entry * 25; - lvds = &xgifb_info->lvds_data; - if (vbios_size <= i + 24) - goto error; - lvds->LVDS_Capability = vbios[i] | (vbios[i + 1] << 8); - lvds->LVDSHT = vbios[i + 2] | (vbios[i + 3] << 8); - lvds->LVDSVT = vbios[i + 4] | (vbios[i + 5] << 8); - lvds->LVDSHDE = vbios[i + 6] | (vbios[i + 7] << 8); - lvds->LVDSVDE = vbios[i + 8] | (vbios[i + 9] << 8); - lvds->LVDSHFP = vbios[i + 10] | (vbios[i + 11] << 8); - lvds->LVDSVFP = vbios[i + 12] | (vbios[i + 13] << 8); - lvds->LVDSHSYNC = vbios[i + 14] | (vbios[i + 15] << 8); - lvds->LVDSVSYNC = vbios[i + 16] | (vbios[i + 17] << 8); - lvds->VCLKData1 = vbios[i + 18]; - lvds->VCLKData2 = vbios[i + 19]; - lvds->PSC_S1 = vbios[i + 20]; - lvds->PSC_S2 = vbios[i + 21]; - lvds->PSC_S3 = vbios[i + 22]; - lvds->PSC_S4 = vbios[i + 23]; - lvds->PSC_S5 = vbios[i + 24]; - vfree(vbios); - return true; -error: - dev_err(&pdev->dev, "Video BIOS corrupted\n"); - vfree(vbios); - return false; -} - -static void XGINew_ChkSenseStatus(struct vb_device_info *pVBInfo) -{ - unsigned short tempbx = 0, temp, tempcx, CR3CData; - - temp = xgifb_reg_get(pVBInfo->P3d4, 0x32); - - if (temp & Monitor1Sense) - tempbx |= ActiveCRT1; - if (temp & LCDSense) - tempbx |= ActiveLCD; - if (temp & Monitor2Sense) - tempbx |= ActiveCRT2; - if (temp & TVSense) { - tempbx |= ActiveTV; - if (temp & AVIDEOSense) - tempbx |= (ActiveAVideo << 8); - if (temp & SVIDEOSense) - tempbx |= (ActiveSVideo << 8); - if (temp & SCARTSense) - tempbx |= (ActiveSCART << 8); - if (temp & HiTVSense) - tempbx |= (ActiveHiTV << 8); - if (temp & YPbPrSense) - tempbx |= (ActiveYPbPr << 8); - } - - tempcx = xgifb_reg_get(pVBInfo->P3d4, 0x3d); - tempcx |= (xgifb_reg_get(pVBInfo->P3d4, 0x3e) << 8); - - if (tempbx & tempcx) { - CR3CData = xgifb_reg_get(pVBInfo->P3d4, 0x3c); - if (!(CR3CData & DisplayDeviceFromCMOS)) - tempcx = 0x1FF0; - } else { - tempcx = 0x1FF0; - } - - tempbx &= tempcx; - xgifb_reg_set(pVBInfo->P3d4, 0x3d, (tempbx & 0x00FF)); - xgifb_reg_set(pVBInfo->P3d4, 0x3e, ((tempbx & 0xFF00) >> 8)); -} - -static void XGINew_SetModeScratch(struct vb_device_info *pVBInfo) -{ - unsigned short temp, tempcl = 0, tempch = 0, CR31Data, CR38Data; - - temp = xgifb_reg_get(pVBInfo->P3d4, 0x3d); - temp |= xgifb_reg_get(pVBInfo->P3d4, 0x3e) << 8; - temp |= (xgifb_reg_get(pVBInfo->P3d4, 0x31) & (DriverMode >> 8)) << 8; - - if (pVBInfo->IF_DEF_CRT2Monitor == 1) { - if (temp & ActiveCRT2) - tempcl = SetCRT2ToRAMDAC; - } - - if (temp & ActiveLCD) { - tempcl |= SetCRT2ToLCD; - if (temp & DriverMode) { - if (temp & ActiveTV) { - tempch = SetToLCDA | EnableDualEdge; - temp ^= SetCRT2ToLCD; - - if ((temp >> 8) & ActiveAVideo) - tempcl |= SetCRT2ToAVIDEO; - if ((temp >> 8) & ActiveSVideo) - tempcl |= SetCRT2ToSVIDEO; - if ((temp >> 8) & ActiveSCART) - tempcl |= SetCRT2ToSCART; - - if (pVBInfo->IF_DEF_HiVision == 1) { - if ((temp >> 8) & ActiveHiTV) - tempcl |= SetCRT2ToHiVision; - } - - if (pVBInfo->IF_DEF_YPbPr == 1) { - if ((temp >> 8) & ActiveYPbPr) - tempch |= SetYPbPr; - } - } - } - } else { - if ((temp >> 8) & ActiveAVideo) - tempcl |= SetCRT2ToAVIDEO; - if ((temp >> 8) & ActiveSVideo) - tempcl |= SetCRT2ToSVIDEO; - if ((temp >> 8) & ActiveSCART) - tempcl |= SetCRT2ToSCART; - - if (pVBInfo->IF_DEF_HiVision == 1) { - if ((temp >> 8) & ActiveHiTV) - tempcl |= SetCRT2ToHiVision; - } - - if (pVBInfo->IF_DEF_YPbPr == 1) { - if ((temp >> 8) & ActiveYPbPr) - tempch |= SetYPbPr; - } - } - - tempcl |= SetSimuScanMode; - if ((!(temp & ActiveCRT1)) && ((temp & ActiveLCD) || - (temp & ActiveTV) || - (temp & ActiveCRT2))) - tempcl ^= (SetSimuScanMode | SwitchCRT2); - if ((temp & ActiveLCD) && (temp & ActiveTV)) - tempcl ^= (SetSimuScanMode | SwitchCRT2); - xgifb_reg_set(pVBInfo->P3d4, 0x30, tempcl); - - CR31Data = xgifb_reg_get(pVBInfo->P3d4, 0x31); - CR31Data &= ~(SetNotSimuMode >> 8); - if (!(temp & ActiveCRT1)) - CR31Data |= (SetNotSimuMode >> 8); - CR31Data &= ~(DisableCRT2Display >> 8); - if (!((temp & ActiveLCD) || (temp & ActiveTV) || (temp & ActiveCRT2))) - CR31Data |= (DisableCRT2Display >> 8); - xgifb_reg_set(pVBInfo->P3d4, 0x31, CR31Data); - - CR38Data = xgifb_reg_get(pVBInfo->P3d4, 0x38); - CR38Data &= ~SetYPbPr; - CR38Data |= tempch; - xgifb_reg_set(pVBInfo->P3d4, 0x38, CR38Data); -} - -static unsigned short XGINew_SenseLCD(struct xgi_hw_device_info - *HwDeviceExtension, - struct vb_device_info *pVBInfo) -{ - unsigned short temp = HwDeviceExtension->ulCRT2LCDType; - - switch (HwDeviceExtension->ulCRT2LCDType) { - case LCD_640x480: - case LCD_1024x600: - case LCD_1152x864: - case LCD_1280x960: - case LCD_1152x768: - case LCD_1920x1440: - case LCD_2048x1536: - temp = 0; /* overwrite used ulCRT2LCDType */ - break; - case LCD_UNKNOWN: /* unknown lcd, do nothing */ - return 0; - } - xgifb_reg_and_or(pVBInfo->P3d4, 0x36, 0xF0, temp); - return 1; -} - -static void XGINew_GetXG21Sense(struct pci_dev *pdev, - struct vb_device_info *pVBInfo) -{ - struct xgifb_video_info *xgifb_info = pci_get_drvdata(pdev); - unsigned char Temp; - - if (xgifb_read_vbios(pdev)) { /* For XG21 LVDS */ - xgifb_reg_or(pVBInfo->P3d4, 0x32, LCDSense); - /* LVDS on chip */ - xgifb_reg_and_or(pVBInfo->P3d4, 0x38, ~0xE0, 0xC0); - } else { - /* Enable GPIOA/B read */ - xgifb_reg_and_or(pVBInfo->P3d4, 0x4A, ~0x03, 0x03); - Temp = xgifb_reg_get(pVBInfo->P3d4, 0x48) & 0xC0; - if (Temp == 0xC0) { /* DVI & DVO GPIOA/B pull high */ - XGINew_SenseLCD(&xgifb_info->hw_info, pVBInfo); - xgifb_reg_or(pVBInfo->P3d4, 0x32, LCDSense); - /* Enable read GPIOF */ - xgifb_reg_and_or(pVBInfo->P3d4, 0x4A, ~0x20, 0x20); - if (xgifb_reg_get(pVBInfo->P3d4, 0x48) & 0x04) - Temp = 0xA0; /* Only DVO on chip */ - else - Temp = 0x80; /* TMDS on chip */ - xgifb_reg_and_or(pVBInfo->P3d4, 0x38, ~0xE0, Temp); - /* Disable read GPIOF */ - xgifb_reg_and(pVBInfo->P3d4, 0x4A, ~0x20); - } - } -} - -static void XGINew_GetXG27Sense(struct vb_device_info *pVBInfo) -{ - unsigned char Temp, bCR4A; - - bCR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A); - /* Enable GPIOA/B/C read */ - xgifb_reg_and_or(pVBInfo->P3d4, 0x4A, ~0x07, 0x07); - Temp = xgifb_reg_get(pVBInfo->P3d4, 0x48) & 0x07; - xgifb_reg_set(pVBInfo->P3d4, 0x4A, bCR4A); - - if (Temp <= 0x02) { - /* LVDS setting */ - xgifb_reg_and_or(pVBInfo->P3d4, 0x38, ~0xE0, 0xC0); - xgifb_reg_set(pVBInfo->P3d4, 0x30, 0x21); - } else { - /* TMDS/DVO setting */ - xgifb_reg_and_or(pVBInfo->P3d4, 0x38, ~0xE0, 0xA0); - } - xgifb_reg_or(pVBInfo->P3d4, 0x32, LCDSense); -} - -static unsigned char GetXG21FPBits(struct vb_device_info *pVBInfo) -{ - unsigned char CR38, CR4A, temp; - - CR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A); - /* enable GPIOE read */ - xgifb_reg_and_or(pVBInfo->P3d4, 0x4A, ~0x10, 0x10); - CR38 = xgifb_reg_get(pVBInfo->P3d4, 0x38); - temp = 0; - if ((CR38 & 0xE0) > 0x80) { - temp = xgifb_reg_get(pVBInfo->P3d4, 0x48); - temp &= 0x08; - temp >>= 3; - } - - xgifb_reg_set(pVBInfo->P3d4, 0x4A, CR4A); - - return temp; -} - -static unsigned char GetXG27FPBits(struct vb_device_info *pVBInfo) -{ - unsigned char CR4A, temp; - - CR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A); - /* enable GPIOA/B/C read */ - xgifb_reg_and_or(pVBInfo->P3d4, 0x4A, ~0x03, 0x03); - temp = xgifb_reg_get(pVBInfo->P3d4, 0x48); - if (temp > 2) - temp = ((temp & 0x04) >> 1) | ((~temp) & 0x01); - - xgifb_reg_set(pVBInfo->P3d4, 0x4A, CR4A); - - return temp; -} - -static bool xgifb_bridge_is_on(struct vb_device_info *vb_info) -{ - u8 flag; - - flag = xgifb_reg_get(vb_info->Part4Port, 0x00); - return flag == 1 || flag == 2; -} - -unsigned char XGIInitNew(struct pci_dev *pdev) -{ - struct xgifb_video_info *xgifb_info = pci_get_drvdata(pdev); - struct xgi_hw_device_info *HwDeviceExtension = &xgifb_info->hw_info; - struct vb_device_info VBINF; - struct vb_device_info *pVBInfo = &VBINF; - unsigned char i, temp = 0, temp1; - - pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress; - - if (!pVBInfo->FBAddr) { - dev_dbg(&pdev->dev, "pVBInfo->FBAddr == 0\n"); - return 0; - } - - XGIRegInit(pVBInfo, xgifb_info->vga_base); - - outb(0x67, pVBInfo->P3c2); - - InitTo330Pointer(HwDeviceExtension->jChipType, pVBInfo); - - /* Openkey */ - xgifb_reg_set(pVBInfo->P3c4, 0x05, 0x86); - - /* GetXG21Sense (GPIO) */ - if (HwDeviceExtension->jChipType == XG21) - XGINew_GetXG21Sense(pdev, pVBInfo); - - if (HwDeviceExtension->jChipType == XG27) - XGINew_GetXG27Sense(pVBInfo); - - /* Reset Extended register */ - - for (i = 0x06; i < 0x20; i++) - xgifb_reg_set(pVBInfo->P3c4, i, 0); - - for (i = 0x21; i <= 0x27; i++) - xgifb_reg_set(pVBInfo->P3c4, i, 0); - - for (i = 0x31; i <= 0x3B; i++) - xgifb_reg_set(pVBInfo->P3c4, i, 0); - - /* Auto over driver for XG42 */ - if (HwDeviceExtension->jChipType == XG42) - xgifb_reg_set(pVBInfo->P3c4, 0x3B, 0xC0); - - for (i = 0x79; i <= 0x7C; i++) - xgifb_reg_set(pVBInfo->P3d4, i, 0); - - if (HwDeviceExtension->jChipType >= XG20) - xgifb_reg_set(pVBInfo->P3d4, 0x97, pVBInfo->XGINew_CR97); - - /* SetDefExt1Regs begin */ - xgifb_reg_set(pVBInfo->P3c4, 0x07, XGI330_SR07); - if (HwDeviceExtension->jChipType == XG27) { - xgifb_reg_set(pVBInfo->P3c4, 0x40, XG27_SR40); - xgifb_reg_set(pVBInfo->P3c4, 0x41, XG27_SR41); - } - xgifb_reg_set(pVBInfo->P3c4, 0x11, 0x0F); - xgifb_reg_set(pVBInfo->P3c4, 0x1F, XGI330_SR1F); - /* Frame buffer can read/write SR20 */ - xgifb_reg_set(pVBInfo->P3c4, 0x20, 0xA0); - /* H/W request for slow corner chip */ - xgifb_reg_set(pVBInfo->P3c4, 0x36, 0x70); - if (HwDeviceExtension->jChipType == XG27) - xgifb_reg_set(pVBInfo->P3c4, 0x36, XG27_SR36); - - if (HwDeviceExtension->jChipType < XG20) { - u32 Temp; - - /* Set AGP customize registers (in SetDefAGPRegs) Start */ - for (i = 0x47; i <= 0x4C; i++) - xgifb_reg_set(pVBInfo->P3d4, - i, - XGI340_AGPReg[i - 0x47]); - - for (i = 0x70; i <= 0x71; i++) - xgifb_reg_set(pVBInfo->P3d4, - i, - XGI340_AGPReg[6 + i - 0x70]); - - for (i = 0x74; i <= 0x77; i++) - xgifb_reg_set(pVBInfo->P3d4, - i, - XGI340_AGPReg[8 + i - 0x74]); - - pci_read_config_dword(pdev, 0x50, &Temp); - Temp >>= 20; - Temp &= 0xF; - - if (Temp == 1) - xgifb_reg_set(pVBInfo->P3d4, 0x48, 0x20); /* CR48 */ - } /* != XG20 */ - - /* Set PCI */ - xgifb_reg_set(pVBInfo->P3c4, 0x23, XGI330_SR23); - xgifb_reg_set(pVBInfo->P3c4, 0x24, XGI330_SR24); - xgifb_reg_set(pVBInfo->P3c4, 0x25, 0); - - if (HwDeviceExtension->jChipType < XG20) { - /* Set VB */ - XGI_UnLockCRT2(pVBInfo); - /* disable VideoCapture */ - xgifb_reg_and_or(pVBInfo->Part0Port, 0x3F, 0xEF, 0x00); - xgifb_reg_set(pVBInfo->Part1Port, 0x00, 0x00); - /* chk if BCLK>=100MHz */ - temp1 = xgifb_reg_get(pVBInfo->P3d4, 0x7B); - - xgifb_reg_set(pVBInfo->Part1Port, - 0x02, XGI330_CRT2Data_1_2); - - xgifb_reg_set(pVBInfo->Part1Port, 0x2E, 0x08); /* use VB */ - } /* != XG20 */ - - xgifb_reg_set(pVBInfo->P3c4, 0x27, 0x1F); - - if ((HwDeviceExtension->jChipType == XG42) && - XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo) != 0) { - /* Not DDR */ - xgifb_reg_set(pVBInfo->P3c4, - 0x31, - (XGI330_SR31 & 0x3F) | 0x40); - xgifb_reg_set(pVBInfo->P3c4, - 0x32, - (XGI330_SR32 & 0xFC) | 0x01); - } else { - xgifb_reg_set(pVBInfo->P3c4, 0x31, XGI330_SR31); - xgifb_reg_set(pVBInfo->P3c4, 0x32, XGI330_SR32); - } - xgifb_reg_set(pVBInfo->P3c4, 0x33, XGI330_SR33); - - if (HwDeviceExtension->jChipType < XG20) { - if (xgifb_bridge_is_on(pVBInfo)) { - xgifb_reg_set(pVBInfo->Part2Port, 0x00, 0x1C); - xgifb_reg_set(pVBInfo->Part4Port, - 0x0D, XGI330_CRT2Data_4_D); - xgifb_reg_set(pVBInfo->Part4Port, - 0x0E, XGI330_CRT2Data_4_E); - xgifb_reg_set(pVBInfo->Part4Port, - 0x10, XGI330_CRT2Data_4_10); - xgifb_reg_set(pVBInfo->Part4Port, 0x0F, 0x3F); - XGI_LockCRT2(pVBInfo); - } - } /* != XG20 */ - - XGI_SenseCRT1(pVBInfo); - - if (HwDeviceExtension->jChipType == XG21) { - xgifb_reg_and_or(pVBInfo->P3d4, - 0x32, - ~Monitor1Sense, - Monitor1Sense); /* Z9 default has CRT */ - temp = GetXG21FPBits(pVBInfo); - xgifb_reg_and_or(pVBInfo->P3d4, 0x37, ~0x01, temp); - } - if (HwDeviceExtension->jChipType == XG27) { - xgifb_reg_and_or(pVBInfo->P3d4, - 0x32, - ~Monitor1Sense, - Monitor1Sense); /* Z9 default has CRT */ - temp = GetXG27FPBits(pVBInfo); - xgifb_reg_and_or(pVBInfo->P3d4, 0x37, ~0x03, temp); - } - - pVBInfo->ram_type = XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo); - - XGINew_SetDRAMDefaultRegister340(HwDeviceExtension, - pVBInfo->P3d4, - pVBInfo); - - XGINew_SetDRAMSize_340(xgifb_info, HwDeviceExtension, pVBInfo); - - xgifb_reg_set(pVBInfo->P3c4, 0x22, 0xfa); - xgifb_reg_set(pVBInfo->P3c4, 0x21, 0xa3); - - XGINew_ChkSenseStatus(pVBInfo); - XGINew_SetModeScratch(pVBInfo); - - xgifb_reg_set(pVBInfo->P3d4, 0x8c, 0x87); - - return 1; -} /* end of init */ diff --git a/drivers/staging/xgifb/vb_init.h b/drivers/staging/xgifb/vb_init.h deleted file mode 100644 index 2f8a70133ebd..000000000000 --- a/drivers/staging/xgifb/vb_init.h +++ /dev/null @@ -1,6 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef _VBINIT_ -#define _VBINIT_ -unsigned char XGIInitNew(struct pci_dev *pdev); -void XGIRegInit(struct vb_device_info *XGI_Pr, unsigned long BaseAddr); -#endif diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c deleted file mode 100644 index 3782f8641bf2..000000000000 --- a/drivers/staging/xgifb/vb_setmode.c +++ /dev/null @@ -1,5528 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include <linux/delay.h> -#include "XGIfb.h" - -#include "vb_def.h" -#include "vb_init.h" -#include "vb_util.h" -#include "vb_table.h" -#include "vb_setmode.h" - -#define IndexMask 0xff -#define TVCLKBASE_315_25 (TVCLKBASE_315 + 25) - -static const unsigned short XGINew_VGA_DAC[] = { - 0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15, - 0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F, - 0x00, 0x05, 0x08, 0x0B, 0x0E, 0x11, 0x14, 0x18, - 0x1C, 0x20, 0x24, 0x28, 0x2D, 0x32, 0x38, 0x3F, - 0x00, 0x10, 0x1F, 0x2F, 0x3F, 0x1F, 0x27, 0x2F, - 0x37, 0x3F, 0x2D, 0x31, 0x36, 0x3A, 0x3F, 0x00, - 0x07, 0x0E, 0x15, 0x1C, 0x0E, 0x11, 0x15, 0x18, - 0x1C, 0x14, 0x16, 0x18, 0x1A, 0x1C, 0x00, 0x04, - 0x08, 0x0C, 0x10, 0x08, 0x0A, 0x0C, 0x0E, 0x10, - 0x0B, 0x0C, 0x0D, 0x0F, 0x10}; - -void InitTo330Pointer(unsigned char ChipType, struct vb_device_info *pVBInfo) -{ - pVBInfo->MCLKData = XGI340New_MCLKData; - - pVBInfo->LCDResInfo = 0; - pVBInfo->LCDTypeInfo = 0; - pVBInfo->LCDInfo = 0; - pVBInfo->VBInfo = 0; - pVBInfo->TVInfo = 0; - - pVBInfo->SR18 = XGI340_SR18; - pVBInfo->CR40 = XGI340_cr41; - - if (ChipType < XG20) - XGI_GetVBType(pVBInfo); - - /* 310 customization related */ - if ((pVBInfo->VBType & VB_SIS301LV) || (pVBInfo->VBType & VB_SIS302LV)) - pVBInfo->LCDCapList = XGI_LCDDLCapList; - else - pVBInfo->LCDCapList = XGI_LCDCapList; - - if (ChipType >= XG20) - pVBInfo->XGINew_CR97 = 0x10; - - if (ChipType == XG27) { - unsigned char temp; - - pVBInfo->MCLKData = XGI27New_MCLKData; - pVBInfo->CR40 = XGI27_cr41; - pVBInfo->XGINew_CR97 = 0xc1; - pVBInfo->SR18 = XG27_SR18; - - /* Z11m DDR */ - temp = xgifb_reg_get(pVBInfo->P3c4, 0x3B); - /* SR3B[7][3]MAA15 MAA11 (Power on Trapping) */ - if (((temp & 0x88) == 0x80) || ((temp & 0x88) == 0x08)) - pVBInfo->XGINew_CR97 = 0x80; - } -} - -static void XGI_SetSeqRegs(struct vb_device_info *pVBInfo) -{ - unsigned char SRdata, i; - - xgifb_reg_set(pVBInfo->P3c4, 0x00, 0x03); /* Set SR0 */ - - for (i = 0; i < 4; i++) { - /* Get SR1,2,3,4 from file */ - /* SR1 is with screen off 0x20 */ - SRdata = XGI330_StandTable.SR[i]; - /* Set SR 1 2 3 4 */ - xgifb_reg_set(pVBInfo->P3c4, i + 1, SRdata); - } -} - -static void XGI_SetCRTCRegs(struct vb_device_info *pVBInfo) -{ - unsigned char CRTCdata; - unsigned short i; - - CRTCdata = xgifb_reg_get(pVBInfo->P3d4, 0x11); - CRTCdata &= 0x7f; - xgifb_reg_set(pVBInfo->P3d4, 0x11, CRTCdata); /* Unlock CRTC */ - - for (i = 0; i <= 0x18; i++) { - /* Get CRTC from file */ - CRTCdata = XGI330_StandTable.CRTC[i]; - xgifb_reg_set(pVBInfo->P3d4, i, CRTCdata); /* Set CRTC(3d4) */ - } -} - -static void XGI_SetATTRegs(unsigned short ModeIdIndex, - struct vb_device_info *pVBInfo) -{ - unsigned char ARdata; - unsigned short i, modeflag; - - modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; - - for (i = 0; i <= 0x13; i++) { - ARdata = XGI330_StandTable.ATTR[i]; - - if ((modeflag & Charx8Dot) && i == 0x13) { /* ifndef Dot9 */ - if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) { - ARdata = 0; - } else if ((pVBInfo->VBInfo & - (SetCRT2ToTV | SetCRT2ToLCD)) && - (pVBInfo->VBInfo & SetInSlaveMode)) { - ARdata = 0; - } - } - - inb(pVBInfo->P3da); /* reset 3da */ - outb(i, pVBInfo->P3c0); /* set index */ - outb(ARdata, pVBInfo->P3c0); /* set data */ - } - - inb(pVBInfo->P3da); /* reset 3da */ - outb(0x14, pVBInfo->P3c0); /* set index */ - outb(0x00, pVBInfo->P3c0); /* set data */ - inb(pVBInfo->P3da); /* Enable Attribute */ - outb(0x20, pVBInfo->P3c0); -} - -static void XGI_SetGRCRegs(struct vb_device_info *pVBInfo) -{ - unsigned char GRdata; - unsigned short i; - - for (i = 0; i <= 0x08; i++) { - /* Get GR from file */ - GRdata = XGI330_StandTable.GRC[i]; - xgifb_reg_set(pVBInfo->P3ce, i, GRdata); /* Set GR(3ce) */ - } - - if (pVBInfo->ModeType > ModeVGA) { - GRdata = xgifb_reg_get(pVBInfo->P3ce, 0x05); - GRdata &= 0xBF; /* 256 color disable */ - xgifb_reg_set(pVBInfo->P3ce, 0x05, GRdata); - } -} - -static void XGI_ClearExt1Regs(struct vb_device_info *pVBInfo) -{ - unsigned short i; - - for (i = 0x0A; i <= 0x0E; i++) - xgifb_reg_set(pVBInfo->P3c4, i, 0x00); /* Clear SR0A-SR0E */ -} - -static unsigned char XGI_SetDefaultVCLK(struct vb_device_info *pVBInfo) -{ - xgifb_reg_and_or(pVBInfo->P3c4, 0x31, ~0x30, 0x20); - xgifb_reg_set(pVBInfo->P3c4, 0x2B, XGI_VCLKData[0].SR2B); - xgifb_reg_set(pVBInfo->P3c4, 0x2C, XGI_VCLKData[0].SR2C); - - xgifb_reg_and_or(pVBInfo->P3c4, 0x31, ~0x30, 0x10); - xgifb_reg_set(pVBInfo->P3c4, 0x2B, XGI_VCLKData[1].SR2B); - xgifb_reg_set(pVBInfo->P3c4, 0x2C, XGI_VCLKData[1].SR2C); - - xgifb_reg_and(pVBInfo->P3c4, 0x31, ~0x30); - return 0; -} - -static unsigned char XGI_AjustCRT2Rate(unsigned short ModeIdIndex, - unsigned short RefreshRateTableIndex, - unsigned short *i, - struct vb_device_info *pVBInfo) -{ - unsigned short tempax, tempbx, resinfo, modeflag, infoflag; - - modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; - resinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO; - tempbx = XGI330_RefIndex[RefreshRateTableIndex + (*i)].ModeID; - tempax = 0; - - if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) { - tempax |= SupportRAMDAC2; - - if (pVBInfo->VBType & VB_XGI301C) - tempax |= SupportCRT2in301C; - } - - /* 301b */ - if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) { - tempax |= SupportLCD; - - if (pVBInfo->LCDResInfo != Panel_1280x1024 && - pVBInfo->LCDResInfo != Panel_1280x960 && - (pVBInfo->LCDInfo & LCDNonExpanding) && - resinfo >= 9) - return 0; - } - - if (pVBInfo->VBInfo & SetCRT2ToHiVision) { /* for HiTV */ - tempax |= SupportHiVision; - if ((pVBInfo->VBInfo & SetInSlaveMode) && - ((resinfo == 4) || - (resinfo == 3 && (pVBInfo->SetFlag & TVSimuMode)) || - (resinfo > 7))) - return 0; - } else if (pVBInfo->VBInfo & (SetCRT2ToAVIDEO | SetCRT2ToSVIDEO | - SetCRT2ToSCART | SetCRT2ToYPbPr525750 | - SetCRT2ToHiVision)) { - tempax |= SupportTV; - - if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV | - VB_SIS302LV | VB_XGI301C)) - tempax |= SupportTV1024; - - if (!(pVBInfo->VBInfo & TVSetPAL) && - (modeflag & NoSupportSimuTV) && - (pVBInfo->VBInfo & SetInSlaveMode) && - !(pVBInfo->VBInfo & SetNotSimuMode)) - return 0; - } - - for (; XGI330_RefIndex[RefreshRateTableIndex + (*i)].ModeID == - tempbx; (*i)--) { - infoflag = XGI330_RefIndex[RefreshRateTableIndex + (*i)].Ext_InfoFlag; - if (infoflag & tempax) - return 1; - - if ((*i) == 0) - break; - } - - for ((*i) = 0;; (*i)++) { - infoflag = XGI330_RefIndex[RefreshRateTableIndex + (*i)].Ext_InfoFlag; - if (XGI330_RefIndex[RefreshRateTableIndex + (*i)].ModeID - != tempbx) { - return 0; - } - - if (infoflag & tempax) - return 1; - } - return 1; -} - -static void XGI_SetSync(unsigned short RefreshRateTableIndex, - struct vb_device_info *pVBInfo) -{ - unsigned short sync, temp; - - /* di+0x00 */ - sync = XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag >> 8; - sync &= 0xC0; - temp = 0x2F; - temp |= sync; - outb(temp, pVBInfo->P3c2); /* Set Misc(3c2) */ -} - -static void XGI_SetCRT1Timing_H(struct vb_device_info *pVBInfo, - struct xgi_hw_device_info *HwDeviceExtension) -{ - unsigned char data, data1, pushax; - unsigned short i, j; - - /* unlock cr0-7 */ - data = xgifb_reg_get(pVBInfo->P3d4, 0x11); - data &= 0x7F; - xgifb_reg_set(pVBInfo->P3d4, 0x11, data); - - data = pVBInfo->TimingH.data[0]; - xgifb_reg_set(pVBInfo->P3d4, 0, data); - - for (i = 0x01; i <= 0x04; i++) { - data = pVBInfo->TimingH.data[i]; - xgifb_reg_set(pVBInfo->P3d4, (unsigned short)(i + 1), data); - } - - for (i = 0x05; i <= 0x06; i++) { - data = pVBInfo->TimingH.data[i]; - xgifb_reg_set(pVBInfo->P3c4, (unsigned short)(i + 6), data); - } - - j = xgifb_reg_get(pVBInfo->P3c4, 0x0e); - j &= 0x1F; - data = pVBInfo->TimingH.data[7]; - data &= 0xE0; - data |= j; - xgifb_reg_set(pVBInfo->P3c4, 0x0e, data); - - if (HwDeviceExtension->jChipType >= XG20) { - data = xgifb_reg_get(pVBInfo->P3d4, 0x04); - data = data - 1; - xgifb_reg_set(pVBInfo->P3d4, 0x04, data); - data = xgifb_reg_get(pVBInfo->P3d4, 0x05); - data1 = data; - data1 &= 0xE0; - data &= 0x1F; - if (data == 0) { - pushax = data; - data = xgifb_reg_get(pVBInfo->P3c4, 0x0c); - data &= 0xFB; - xgifb_reg_set(pVBInfo->P3c4, 0x0c, data); - data = pushax; - } - data = data - 1; - data |= data1; - xgifb_reg_set(pVBInfo->P3d4, 0x05, data); - data = xgifb_reg_get(pVBInfo->P3c4, 0x0e); - data >>= 5; - data = data + 3; - if (data > 7) - data = data - 7; - data <<= 5; - xgifb_reg_and_or(pVBInfo->P3c4, 0x0e, ~0xE0, data); - } -} - -static void XGI_SetCRT1Timing_V(unsigned short ModeIdIndex, - struct vb_device_info *pVBInfo) -{ - unsigned char data; - unsigned short i, j; - - for (i = 0x00; i <= 0x01; i++) { - data = pVBInfo->TimingV.data[i]; - xgifb_reg_set(pVBInfo->P3d4, (unsigned short)(i + 6), data); - } - - for (i = 0x02; i <= 0x03; i++) { - data = pVBInfo->TimingV.data[i]; - xgifb_reg_set(pVBInfo->P3d4, (unsigned short)(i + 0x0e), data); - } - - for (i = 0x04; i <= 0x05; i++) { - data = pVBInfo->TimingV.data[i]; - xgifb_reg_set(pVBInfo->P3d4, (unsigned short)(i + 0x11), data); - } - - j = xgifb_reg_get(pVBInfo->P3c4, 0x0a); - j &= 0xC0; - data = pVBInfo->TimingV.data[6]; - data &= 0x3F; - data |= j; - xgifb_reg_set(pVBInfo->P3c4, 0x0a, data); - - data = pVBInfo->TimingV.data[6]; - data &= 0x80; - data >>= 2; - - i = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; - i &= DoubleScanMode; - if (i) - data |= 0x80; - - j = xgifb_reg_get(pVBInfo->P3d4, 0x09); - j &= 0x5F; - data |= j; - xgifb_reg_set(pVBInfo->P3d4, 0x09, data); -} - -static void XGI_SetCRT1CRTC(unsigned short ModeIdIndex, - unsigned short RefreshRateTableIndex, - struct vb_device_info *pVBInfo, - struct xgi_hw_device_info *HwDeviceExtension) -{ - unsigned char index, data; - unsigned short i; - - /* Get index */ - index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; - index = index & IndexMask; - - data = xgifb_reg_get(pVBInfo->P3d4, 0x11); - data &= 0x7F; - xgifb_reg_set(pVBInfo->P3d4, 0x11, data); /* Unlock CRTC */ - - for (i = 0; i < 8; i++) - pVBInfo->TimingH.data[i] - = XGI_CRT1Table[index].CR[i]; - - for (i = 0; i < 7; i++) - pVBInfo->TimingV.data[i] - = XGI_CRT1Table[index].CR[i + 8]; - - XGI_SetCRT1Timing_H(pVBInfo, HwDeviceExtension); - - XGI_SetCRT1Timing_V(ModeIdIndex, pVBInfo); - - if (pVBInfo->ModeType > 0x03) - xgifb_reg_set(pVBInfo->P3d4, 0x14, 0x4F); -} - -/* - * Function : XGI_SetXG21CRTC - * Input : Stand or enhance CRTC table - * Output : Fill CRT Hsync/Vsync to SR2E/SR2F/SR30/SR33/SR34/SR3F - * Description : Set LCD timing - */ -static void XGI_SetXG21CRTC(unsigned short RefreshRateTableIndex, - struct vb_device_info *pVBInfo) -{ - unsigned char index, Tempax, Tempbx, Tempcx, Tempdx; - unsigned short Temp1, Temp2, Temp3; - - index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; - /* Tempax: CR4 HRS */ - Tempax = XGI_CRT1Table[index].CR[3]; - Tempcx = Tempax; /* Tempcx: HRS */ - /* SR2E[7:0]->HRS */ - xgifb_reg_set(pVBInfo->P3c4, 0x2E, Tempax); - - Tempdx = XGI_CRT1Table[index].CR[5]; /* SRB */ - Tempdx &= 0xC0; /* Tempdx[7:6]: SRB[7:6] */ - Temp1 = Tempdx; /* Temp1[7:6]: HRS[9:8] */ - Temp1 <<= 2; /* Temp1[9:8]: HRS[9:8] */ - Temp1 |= Tempax; /* Temp1[9:0]: HRS[9:0] */ - - Tempax = XGI_CRT1Table[index].CR[4]; /* CR5 HRE */ - Tempax &= 0x1F; /* Tempax[4:0]: HRE[4:0] */ - - Tempbx = XGI_CRT1Table[index].CR[6]; /* SRC */ - Tempbx &= 0x04; /* Tempbx[2]: HRE[5] */ - Tempbx <<= 3; /* Tempbx[5]: HRE[5] */ - Tempax |= Tempbx; /* Tempax[5:0]: HRE[5:0] */ - - Temp2 = Temp1 & 0x3C0; /* Temp2[9:6]: HRS[9:6] */ - Temp2 |= Tempax; /* Temp2[9:0]: HRE[9:0] */ - - Tempcx &= 0x3F; /* Tempcx[5:0]: HRS[5:0] */ - if (Tempax < Tempcx) /* HRE < HRS */ - Temp2 |= 0x40; /* Temp2 + 0x40 */ - - Temp2 &= 0xFF; - Tempax = (unsigned char)Temp2; /* Tempax: HRE[7:0] */ - Tempax <<= 2; /* Tempax[7:2]: HRE[5:0] */ - Tempdx >>= 6; /* Tempdx[7:6]->[1:0] HRS[9:8] */ - Tempax |= Tempdx; /* HRE[5:0]HRS[9:8] */ - /* SR2F D[7:2]->HRE, D[1:0]->HRS */ - xgifb_reg_set(pVBInfo->P3c4, 0x2F, Tempax); - xgifb_reg_and_or(pVBInfo->P3c4, 0x30, 0xE3, 00); - - /* CR10 VRS */ - Tempax = XGI_CRT1Table[index].CR[10]; - Tempbx = Tempax; /* Tempbx: VRS */ - Tempax &= 0x01; /* Tempax[0]: VRS[0] */ - xgifb_reg_or(pVBInfo->P3c4, 0x33, Tempax); /* SR33[0]->VRS[0] */ - /* CR7[2][7] VRE */ - Tempax = XGI_CRT1Table[index].CR[9]; - Tempcx = Tempbx >> 1; /* Tempcx[6:0]: VRS[7:1] */ - Tempdx = Tempax & 0x04; /* Tempdx[2]: CR7[2] */ - Tempdx <<= 5; /* Tempdx[7]: VRS[8] */ - Tempcx |= Tempdx; /* Tempcx[7:0]: VRS[8:1] */ - xgifb_reg_set(pVBInfo->P3c4, 0x34, Tempcx); /* SR34[8:1]->VRS */ - - Temp1 = Tempdx; /* Temp1[7]: Tempdx[7] */ - Temp1 <<= 1; /* Temp1[8]: VRS[8] */ - Temp1 |= Tempbx; /* Temp1[8:0]: VRS[8:0] */ - Tempax &= 0x80; - Temp2 = Tempax << 2; /* Temp2[9]: VRS[9] */ - Temp1 |= Temp2; /* Temp1[9:0]: VRS[9:0] */ - /* Tempax: SRA */ - Tempax = XGI_CRT1Table[index].CR[14]; - Tempax &= 0x08; /* Tempax[3]: VRS[3] */ - Temp2 = Tempax; - Temp2 <<= 7; /* Temp2[10]: VRS[10] */ - Temp1 |= Temp2; /* Temp1[10:0]: VRS[10:0] */ - - /* Tempax: CR11 VRE */ - Tempax = XGI_CRT1Table[index].CR[11]; - Tempax &= 0x0F; /* Tempax[3:0]: VRE[3:0] */ - /* Tempbx: SRA */ - Tempbx = XGI_CRT1Table[index].CR[14]; - Tempbx &= 0x20; /* Tempbx[5]: VRE[5] */ - Tempbx >>= 1; /* Tempbx[4]: VRE[4] */ - Tempax |= Tempbx; /* Tempax[4:0]: VRE[4:0] */ - Temp2 = Temp1 & 0x7E0; /* Temp2[10:5]: VRS[10:5] */ - Temp2 |= Tempax; /* Temp2[10:5]: VRE[10:5] */ - - Temp3 = Temp1 & 0x1F; /* Temp3[4:0]: VRS[4:0] */ - if (Tempax < Temp3) /* VRE < VRS */ - Temp2 |= 0x20; /* VRE + 0x20 */ - - Temp2 &= 0xFF; - Tempax = (unsigned char)Temp2; /* Tempax: VRE[7:0] */ - Tempax <<= 2; /* Tempax[7:0]; VRE[5:0]00 */ - Temp1 &= 0x600; /* Temp1[10:9]: VRS[10:9] */ - Temp1 >>= 9; /* Temp1[1:0]: VRS[10:9] */ - Tempbx = (unsigned char)Temp1; - Tempax |= Tempbx; /* Tempax[7:0]: VRE[5:0]VRS[10:9] */ - Tempax &= 0x7F; - /* SR3F D[7:2]->VRE D[1:0]->VRS */ - xgifb_reg_set(pVBInfo->P3c4, 0x3F, Tempax); -} - -static void XGI_SetXG27CRTC(unsigned short RefreshRateTableIndex, - struct vb_device_info *pVBInfo) -{ - unsigned short index, Tempax, Tempbx, Tempcx; - - index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; - /* Tempax: CR4 HRS */ - Tempax = XGI_CRT1Table[index].CR[3]; - Tempbx = Tempax; /* Tempbx: HRS[7:0] */ - /* SR2E[7:0]->HRS */ - xgifb_reg_set(pVBInfo->P3c4, 0x2E, Tempax); - - /* SR0B */ - Tempax = XGI_CRT1Table[index].CR[5]; - Tempax &= 0xC0; /* Tempax[7:6]: SR0B[7:6]: HRS[9:8] */ - Tempbx |= Tempax << 2; /* Tempbx: HRS[9:0] */ - - Tempax = XGI_CRT1Table[index].CR[4]; /* CR5 HRE */ - Tempax &= 0x1F; /* Tempax[4:0]: HRE[4:0] */ - Tempcx = Tempax; /* Tempcx: HRE[4:0] */ - - Tempax = XGI_CRT1Table[index].CR[6]; /* SRC */ - Tempax &= 0x04; /* Tempax[2]: HRE[5] */ - Tempax <<= 3; /* Tempax[5]: HRE[5] */ - Tempcx |= Tempax; /* Tempcx[5:0]: HRE[5:0] */ - - Tempbx = Tempbx & 0x3C0; /* Tempbx[9:6]: HRS[9:6] */ - Tempbx |= Tempcx; /* Tempbx: HRS[9:6]HRE[5:0] */ - - /* Tempax: CR4 HRS */ - Tempax = XGI_CRT1Table[index].CR[3]; - Tempax &= 0x3F; /* Tempax: HRS[5:0] */ - if (Tempcx <= Tempax) /* HRE[5:0] < HRS[5:0] */ - Tempbx += 0x40; /* Tempbx= Tempbx + 0x40 : HRE[9:0]*/ - - Tempax = XGI_CRT1Table[index].CR[5]; /* SR0B */ - Tempax &= 0xC0; /* Tempax[7:6]: SR0B[7:6]: HRS[9:8]*/ - Tempax >>= 6; /* Tempax[1:0]: HRS[9:8]*/ - Tempax |= (Tempbx << 2) & 0xFF; /* Tempax[7:2]: HRE[5:0] */ - /* SR2F [7:2][1:0]: HRE[5:0]HRS[9:8] */ - xgifb_reg_set(pVBInfo->P3c4, 0x2F, Tempax); - xgifb_reg_and_or(pVBInfo->P3c4, 0x30, 0xE3, 00); - - /* CR10 VRS */ - Tempax = XGI_CRT1Table[index].CR[10]; - /* SR34[7:0]->VRS[7:0] */ - xgifb_reg_set(pVBInfo->P3c4, 0x34, Tempax); - - Tempcx = Tempax; /* Tempcx <= VRS[7:0] */ - /* CR7[7][2] VRS[9][8] */ - Tempax = XGI_CRT1Table[index].CR[9]; - Tempbx = Tempax; /* Tempbx <= CR07[7:0] */ - Tempax = Tempax & 0x04; /* Tempax[2]: CR7[2]: VRS[8] */ - Tempax >>= 2; /* Tempax[0]: VRS[8] */ - /* SR35[0]: VRS[8] */ - xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x01, Tempax); - Tempcx |= Tempax << 8; /* Tempcx <= VRS[8:0] */ - Tempcx |= (Tempbx & 0x80) << 2; /* Tempcx <= VRS[9:0] */ - /* Tempax: SR0A */ - Tempax = XGI_CRT1Table[index].CR[14]; - Tempax &= 0x08; /* SR0A[3] VRS[10] */ - Tempcx |= Tempax << 7; /* Tempcx <= VRS[10:0] */ - - /* Tempax: CR11 VRE */ - Tempax = XGI_CRT1Table[index].CR[11]; - Tempax &= 0x0F; /* Tempax[3:0]: VRE[3:0] */ - /* Tempbx: SR0A */ - Tempbx = XGI_CRT1Table[index].CR[14]; - Tempbx &= 0x20; /* Tempbx[5]: SR0A[5]: VRE[4] */ - Tempbx >>= 1; /* Tempbx[4]: VRE[4] */ - Tempax |= Tempbx; /* Tempax[4:0]: VRE[4:0] */ - Tempbx = Tempcx; /* Tempbx: VRS[10:0] */ - Tempbx &= 0x7E0; /* Tempbx[10:5]: VRS[10:5] */ - Tempbx |= Tempax; /* Tempbx: VRS[10:5]VRE[4:0] */ - - if (Tempbx <= Tempcx) /* VRE <= VRS */ - Tempbx |= 0x20; /* VRE + 0x20 */ - - /* Tempax: Tempax[7:0]; VRE[5:0]00 */ - Tempax = (Tempbx << 2) & 0xFF; - /* SR3F[7:2]:VRE[5:0] */ - xgifb_reg_and_or(pVBInfo->P3c4, 0x3F, ~0xFC, Tempax); - Tempax = Tempcx >> 8; - /* SR35[2:0]:VRS[10:8] */ - xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x07, Tempax); -} - -static void XGI_SetXG27FPBits(struct vb_device_info *pVBInfo) -{ - unsigned char temp; - - /* D[1:0] 01: 18bit, 00: dual 12, 10: single 24 */ - temp = xgifb_reg_get(pVBInfo->P3d4, 0x37); - temp = (temp & 3) << 6; - /* SR06[7]0: dual 12/1: single 24 [6] 18bit Dither <= 0 h/w recommend */ - xgifb_reg_and_or(pVBInfo->P3c4, 0x06, ~0xc0, temp & 0x80); - /* SR09[7] enable FP output, SR09[6] 1: sigle 18bits, 0: 24bits */ - xgifb_reg_and_or(pVBInfo->P3c4, 0x09, ~0xc0, temp | 0x80); -} - -static void xgifb_set_lcd(int chip_id, - struct vb_device_info *pVBInfo, - unsigned short RefreshRateTableIndex) -{ - unsigned short temp; - - xgifb_reg_set(pVBInfo->P3d4, 0x2E, 0x00); - xgifb_reg_set(pVBInfo->P3d4, 0x2F, 0x00); - xgifb_reg_set(pVBInfo->P3d4, 0x46, 0x00); - xgifb_reg_set(pVBInfo->P3d4, 0x47, 0x00); - - if (chip_id == XG27) { - temp = xgifb_reg_get(pVBInfo->P3d4, 0x37); - if ((temp & 0x03) == 0) { /* dual 12 */ - xgifb_reg_set(pVBInfo->P3d4, 0x46, 0x13); - xgifb_reg_set(pVBInfo->P3d4, 0x47, 0x13); - } - } - - if (chip_id == XG27) { - XGI_SetXG27FPBits(pVBInfo); - } else { - temp = xgifb_reg_get(pVBInfo->P3d4, 0x37); - if (temp & 0x01) { - /* 18 bits FP */ - xgifb_reg_or(pVBInfo->P3c4, 0x06, 0x40); - xgifb_reg_or(pVBInfo->P3c4, 0x09, 0x40); - } - } - - xgifb_reg_or(pVBInfo->P3c4, 0x1E, 0x01); /* Negative blank polarity */ - - xgifb_reg_and(pVBInfo->P3c4, 0x30, ~0x20); /* Hsync polarity */ - xgifb_reg_and(pVBInfo->P3c4, 0x35, ~0x80); /* Vsync polarity */ - - temp = XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag; - if (temp & 0x4000) { - /* Hsync polarity */ - xgifb_reg_or(pVBInfo->P3c4, 0x30, 0x20); - } - if (temp & 0x8000) { - /* Vsync polarity */ - xgifb_reg_or(pVBInfo->P3c4, 0x35, 0x80); - } -} - -/* - * Function : XGI_UpdateXG21CRTC - * Input : - * Output : CRT1 CRTC - * Description : Modify CRT1 Hsync/Vsync to fix LCD mode timing - */ -static void XGI_UpdateXG21CRTC(unsigned short ModeNo, - struct vb_device_info *pVBInfo, - unsigned short RefreshRateTableIndex) -{ - int index = -1; - - xgifb_reg_and(pVBInfo->P3d4, 0x11, 0x7F); /* Unlock CR0~7 */ - if (ModeNo == 0x2E && - (XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC == - RES640x480x60)) - index = 12; - else if (ModeNo == 0x2E && - (XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC == - RES640x480x72)) - index = 13; - else if (ModeNo == 0x2F) - index = 14; - else if (ModeNo == 0x50) - index = 15; - else if (ModeNo == 0x59) - index = 16; - - if (index != -1) { - xgifb_reg_set(pVBInfo->P3d4, 0x02, - XGI_UpdateCRT1Table[index].CR02); - xgifb_reg_set(pVBInfo->P3d4, 0x03, - XGI_UpdateCRT1Table[index].CR03); - xgifb_reg_set(pVBInfo->P3d4, 0x15, - XGI_UpdateCRT1Table[index].CR15); - xgifb_reg_set(pVBInfo->P3d4, 0x16, - XGI_UpdateCRT1Table[index].CR16); - } -} - -static void XGI_SetCRT1DE(unsigned short ModeIdIndex, - unsigned short RefreshRateTableIndex, - struct vb_device_info *pVBInfo) -{ - unsigned short resindex, tempax, tempbx, tempcx, temp, modeflag; - - unsigned char data; - - resindex = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO; - - modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; - tempax = XGI330_ModeResInfo[resindex].HTotal; - tempbx = XGI330_ModeResInfo[resindex].VTotal; - - if (modeflag & HalfDCLK) - tempax >>= 1; - - if (modeflag & HalfDCLK) - tempax <<= 1; - - temp = XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag; - - if (temp & InterlaceMode) - tempbx >>= 1; - - if (modeflag & DoubleScanMode) - tempbx <<= 1; - - tempcx = 8; - - tempax /= tempcx; - tempax -= 1; - tempbx -= 1; - tempcx = tempax; - temp = xgifb_reg_get(pVBInfo->P3d4, 0x11); - data = xgifb_reg_get(pVBInfo->P3d4, 0x11); - data &= 0x7F; - xgifb_reg_set(pVBInfo->P3d4, 0x11, data); /* Unlock CRTC */ - xgifb_reg_set(pVBInfo->P3d4, 0x01, (unsigned short)(tempcx & 0xff)); - xgifb_reg_and_or(pVBInfo->P3d4, 0x0b, ~0x0c, - (unsigned short)((tempcx & 0x0ff00) >> 10)); - xgifb_reg_set(pVBInfo->P3d4, 0x12, (unsigned short)(tempbx & 0xff)); - tempax = 0; - tempbx >>= 8; - - if (tempbx & 0x01) - tempax |= 0x02; - - if (tempbx & 0x02) - tempax |= 0x40; - - xgifb_reg_and_or(pVBInfo->P3d4, 0x07, ~0x42, tempax); - data = xgifb_reg_get(pVBInfo->P3d4, 0x07); - tempax = 0; - - if (tempbx & 0x04) - tempax |= 0x02; - - xgifb_reg_and_or(pVBInfo->P3d4, 0x0a, ~0x02, tempax); - xgifb_reg_set(pVBInfo->P3d4, 0x11, temp); -} - -static void XGI_SetCRT1Offset(unsigned short ModeNo, - unsigned short ModeIdIndex, - unsigned short RefreshRateTableIndex, - struct xgi_hw_device_info *HwDeviceExtension, - struct vb_device_info *pVBInfo) -{ - unsigned short temp, ah, al, temp2, i, DisplayUnit; - - /* GetOffset */ - temp = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeInfo; - temp >>= 8; - temp = XGI330_ScreenOffset[temp]; - - temp2 = XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag; - temp2 &= InterlaceMode; - - if (temp2) - temp <<= 1; - - temp2 = pVBInfo->ModeType - ModeEGA; - - switch (temp2) { - case 0: - temp2 = 1; - break; - case 1: - temp2 = 2; - break; - case 2: - temp2 = 4; - break; - case 3: - temp2 = 4; - break; - case 4: - temp2 = 6; - break; - case 5: - temp2 = 8; - break; - default: - break; - } - - if ((ModeNo >= 0x26) && (ModeNo <= 0x28)) - temp = temp * temp2 + temp2 / 2; - else - temp *= temp2; - - /* SetOffset */ - DisplayUnit = temp; - temp2 = temp; - temp >>= 8; /* ah */ - temp &= 0x0F; - i = xgifb_reg_get(pVBInfo->P3c4, 0x0E); - i &= 0xF0; - i |= temp; - xgifb_reg_set(pVBInfo->P3c4, 0x0E, i); - - temp = (unsigned char)temp2; - temp &= 0xFF; /* al */ - xgifb_reg_set(pVBInfo->P3d4, 0x13, temp); - - /* SetDisplayUnit */ - temp2 = XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag; - temp2 &= InterlaceMode; - if (temp2) - DisplayUnit >>= 1; - - DisplayUnit <<= 5; - ah = (DisplayUnit & 0xff00) >> 8; - al = DisplayUnit & 0x00ff; - if (al == 0) - ah += 1; - else - ah += 2; - - if (HwDeviceExtension->jChipType >= XG20) - if ((ModeNo == 0x4A) | (ModeNo == 0x49)) - ah -= 1; - - xgifb_reg_set(pVBInfo->P3c4, 0x10, ah); -} - -static unsigned short XGI_GetVCLK2Ptr(unsigned short ModeIdIndex, - unsigned short RefreshRateTableIndex, - struct vb_device_info *pVBInfo) -{ - unsigned short VCLKIndex, modeflag; - - /* si+Ext_ResInfo */ - modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; - - if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) { /* 301b */ - if (pVBInfo->LCDResInfo != Panel_1024x768) - /* LCDXlat2VCLK */ - VCLKIndex = VCLK108_2_315 + 5; - else - VCLKIndex = VCLK65_315 + 2; /* LCDXlat1VCLK */ - } else if (pVBInfo->VBInfo & SetCRT2ToHiVision) { - if (pVBInfo->SetFlag & RPLLDIV2XO) - VCLKIndex = TVCLKBASE_315_25 + HiTVVCLKDIV2; - else - VCLKIndex = TVCLKBASE_315_25 + HiTVVCLK; - - if (pVBInfo->SetFlag & TVSimuMode) { - if (modeflag & Charx8Dot) - VCLKIndex = TVCLKBASE_315_25 + HiTVSimuVCLK; - else - VCLKIndex = TVCLKBASE_315_25 + HiTVTextVCLK; - } - - /* 301lv */ - if (pVBInfo->VBType & VB_SIS301LV) { - if (pVBInfo->SetFlag & RPLLDIV2XO) - VCLKIndex = YPbPr525iVCLK_2; - else - VCLKIndex = YPbPr525iVCLK; - } - } else if (pVBInfo->VBInfo & SetCRT2ToTV) { - if (pVBInfo->SetFlag & RPLLDIV2XO) - VCLKIndex = TVCLKBASE_315_25 + TVVCLKDIV2; - else - VCLKIndex = TVCLKBASE_315_25 + TVVCLK; - } else { /* for CRT2 */ - /* di+Ext_CRTVCLK */ - VCLKIndex = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; - VCLKIndex &= IndexMask; - } - - return VCLKIndex; -} - -static void XGI_SetCRT1VCLK(unsigned short ModeIdIndex, - struct xgi_hw_device_info *HwDeviceExtension, - unsigned short RefreshRateTableIndex, - struct vb_device_info *pVBInfo) -{ - unsigned char index, data; - unsigned short vclkindex; - - if ((pVBInfo->IF_DEF_LVDS == 0) && - (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV | - VB_SIS302LV | VB_XGI301C)) && - (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)) { - vclkindex = XGI_GetVCLK2Ptr(ModeIdIndex, RefreshRateTableIndex, - pVBInfo); - data = xgifb_reg_get(pVBInfo->P3c4, 0x31) & 0xCF; - xgifb_reg_set(pVBInfo->P3c4, 0x31, data); - data = XGI_VBVCLKData[vclkindex].Part4_A; - xgifb_reg_set(pVBInfo->P3c4, 0x2B, data); - data = XGI_VBVCLKData[vclkindex].Part4_B; - xgifb_reg_set(pVBInfo->P3c4, 0x2C, data); - xgifb_reg_set(pVBInfo->P3c4, 0x2D, 0x01); - } else { - index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; - data = xgifb_reg_get(pVBInfo->P3c4, 0x31) & 0xCF; - xgifb_reg_set(pVBInfo->P3c4, 0x31, data); - xgifb_reg_set(pVBInfo->P3c4, 0x2B, XGI_VCLKData[index].SR2B); - xgifb_reg_set(pVBInfo->P3c4, 0x2C, XGI_VCLKData[index].SR2C); - xgifb_reg_set(pVBInfo->P3c4, 0x2D, 0x01); - } - - if (HwDeviceExtension->jChipType >= XG20) { - if (XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag & - HalfDCLK) { - data = xgifb_reg_get(pVBInfo->P3c4, 0x2B); - xgifb_reg_set(pVBInfo->P3c4, 0x2B, data); - data = xgifb_reg_get(pVBInfo->P3c4, 0x2C); - index = data; - index &= 0xE0; - data &= 0x1F; - data <<= 1; - data += 1; - data |= index; - xgifb_reg_set(pVBInfo->P3c4, 0x2C, data); - } - } -} - -static void XGI_SetXG21FPBits(struct vb_device_info *pVBInfo) -{ - unsigned char temp; - - temp = xgifb_reg_get(pVBInfo->P3d4, 0x37); /* D[0] 1: 18bit */ - temp = (temp & 1) << 6; - /* SR06[6] 18bit Dither */ - xgifb_reg_and_or(pVBInfo->P3c4, 0x06, ~0x40, temp); - /* SR09[7] enable FP output, SR09[6] 1: sigle 18bits, 0: dual 12bits */ - xgifb_reg_and_or(pVBInfo->P3c4, 0x09, ~0xc0, temp | 0x80); -} - -static void XGI_SetCRT1FIFO(struct xgi_hw_device_info *HwDeviceExtension, - struct vb_device_info *pVBInfo) -{ - unsigned short data; - - data = xgifb_reg_get(pVBInfo->P3c4, 0x3D); - data &= 0xfe; - xgifb_reg_set(pVBInfo->P3c4, 0x3D, data); /* disable auto-threshold */ - - xgifb_reg_set(pVBInfo->P3c4, 0x08, 0x34); - data = xgifb_reg_get(pVBInfo->P3c4, 0x09); - data &= 0xC0; - xgifb_reg_set(pVBInfo->P3c4, 0x09, data | 0x30); - data = xgifb_reg_get(pVBInfo->P3c4, 0x3D); - data |= 0x01; - xgifb_reg_set(pVBInfo->P3c4, 0x3D, data); - - if (HwDeviceExtension->jChipType == XG21) - XGI_SetXG21FPBits(pVBInfo); /* Fix SR9[7:6] can't read back */ -} - -static void XGI_SetVCLKState(struct xgi_hw_device_info *HwDeviceExtension, - unsigned short RefreshRateTableIndex, - struct vb_device_info *pVBInfo) -{ - unsigned short data, data2 = 0; - short VCLK; - - unsigned char index; - - index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; - index &= IndexMask; - VCLK = XGI_VCLKData[index].CLOCK; - - data = xgifb_reg_get(pVBInfo->P3c4, 0x32); - data &= 0xf3; - if (VCLK >= 200) - data |= 0x0c; /* VCLK > 200 */ - - if (HwDeviceExtension->jChipType >= XG20) - data &= ~0x04; /* 2 pixel mode */ - - xgifb_reg_set(pVBInfo->P3c4, 0x32, data); - - if (HwDeviceExtension->jChipType < XG20) { - data = xgifb_reg_get(pVBInfo->P3c4, 0x1F); - data &= 0xE7; - if (VCLK < 200) - data |= 0x10; - xgifb_reg_set(pVBInfo->P3c4, 0x1F, data); - } - - data2 = 0x00; - - xgifb_reg_and_or(pVBInfo->P3c4, 0x07, 0xFC, data2); - if (HwDeviceExtension->jChipType >= XG27) - xgifb_reg_and_or(pVBInfo->P3c4, 0x40, 0xFC, data2 & 0x03); -} - -static void XGI_SetCRT1ModeRegs(struct xgi_hw_device_info *HwDeviceExtension, - unsigned short ModeIdIndex, - unsigned short RefreshRateTableIndex, - struct vb_device_info *pVBInfo) -{ - unsigned short data, data2, data3, infoflag = 0, modeflag, resindex, - xres; - - modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; - infoflag = XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag; - - if (xgifb_reg_get(pVBInfo->P3d4, 0x31) & 0x01) - xgifb_reg_and_or(pVBInfo->P3c4, 0x1F, 0x3F, 0x00); - - data = infoflag; - data2 = 0; - data2 |= 0x02; - data3 = pVBInfo->ModeType - ModeVGA; - data3 <<= 2; - data2 |= data3; - data &= InterlaceMode; - - if (data) - data2 |= 0x20; - - xgifb_reg_and_or(pVBInfo->P3c4, 0x06, ~0x3F, data2); - resindex = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO; - xres = XGI330_ModeResInfo[resindex].HTotal; /* xres->ax */ - - data = 0x0000; - if (infoflag & InterlaceMode) { - if (xres == 1024) - data = 0x0035; - else if (xres == 1280) - data = 0x0048; - } - - xgifb_reg_and_or(pVBInfo->P3d4, 0x19, 0xFF, data); - xgifb_reg_and_or(pVBInfo->P3d4, 0x19, 0xFC, 0); - - if (modeflag & HalfDCLK) - xgifb_reg_and_or(pVBInfo->P3c4, 0x01, 0xF7, 0x08); - - data2 = 0; - - if (modeflag & LineCompareOff) - data2 |= 0x08; - - xgifb_reg_and_or(pVBInfo->P3c4, 0x0F, ~0x48, data2); - data = 0x60; - data = data ^ 0x60; - data = data ^ 0xA0; - xgifb_reg_and_or(pVBInfo->P3c4, 0x21, 0x1F, data); - - XGI_SetVCLKState(HwDeviceExtension, RefreshRateTableIndex, pVBInfo); - - data = xgifb_reg_get(pVBInfo->P3d4, 0x31); - - if (HwDeviceExtension->jChipType == XG27) { - if (data & 0x40) - data = 0x2c; - else - data = 0x6c; - xgifb_reg_set(pVBInfo->P3d4, 0x52, data); - xgifb_reg_or(pVBInfo->P3d4, 0x51, 0x10); - } else if (HwDeviceExtension->jChipType >= XG20) { - if (data & 0x40) - data = 0x33; - else - data = 0x73; - xgifb_reg_set(pVBInfo->P3d4, 0x52, data); - xgifb_reg_set(pVBInfo->P3d4, 0x51, 0x02); - } else { - if (data & 0x40) - data = 0x2c; - else - data = 0x6c; - xgifb_reg_set(pVBInfo->P3d4, 0x52, data); - } -} - -static void XGI_WriteDAC(unsigned short dl, - unsigned short ah, - unsigned short al, - unsigned short dh, - struct vb_device_info *pVBInfo) -{ - unsigned short bh, bl; - - bh = ah; - bl = al; - - if (dl != 0) { - swap(bh, dh); - if (dl == 1) - swap(bl, dh); - else - swap(bl, bh); - } - outb((unsigned short)dh, pVBInfo->P3c9); - outb((unsigned short)bh, pVBInfo->P3c9); - outb((unsigned short)bl, pVBInfo->P3c9); -} - -static void XGI_LoadDAC(struct vb_device_info *pVBInfo) -{ - unsigned short data, data2, i, k, m, n, o, si, di, bx, dl, al, ah, dh; - const unsigned short *table = XGINew_VGA_DAC; - - outb(0xFF, pVBInfo->P3c6); - outb(0x00, pVBInfo->P3c8); - - for (i = 0; i < 16; i++) { - data = table[i]; - - for (k = 0; k < 3; k++) { - data2 = 0; - - if (data & 0x01) - data2 = 0x2A; - - if (data & 0x02) - data2 += 0x15; - - outb(data2, pVBInfo->P3c9); - data >>= 2; - } - } - - for (i = 16; i < 32; i++) { - data = table[i]; - - for (k = 0; k < 3; k++) - outb(data, pVBInfo->P3c9); - } - - si = 32; - - for (m = 0; m < 9; m++) { - di = si; - bx = si + 0x04; - dl = 0; - - for (n = 0; n < 3; n++) { - for (o = 0; o < 5; o++) { - dh = table[si]; - ah = table[di]; - al = table[bx]; - si++; - XGI_WriteDAC(dl, ah, al, dh, pVBInfo); - } - - si -= 2; - - for (o = 0; o < 3; o++) { - dh = table[bx]; - ah = table[di]; - al = table[si]; - si--; - XGI_WriteDAC(dl, ah, al, dh, pVBInfo); - } - - dl++; - } - - si += 5; - } -} - -static void XGI_GetLVDSResInfo(unsigned short ModeIdIndex, - struct vb_device_info *pVBInfo) -{ - unsigned short resindex, xres, yres, modeflag; - - /* si+Ext_ResInfo */ - modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO; - - /* si+Ext_ResInfo */ - resindex = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO; - - xres = XGI330_ModeResInfo[resindex].HTotal; - yres = XGI330_ModeResInfo[resindex].VTotal; - - if (modeflag & HalfDCLK) - xres <<= 1; - - if (modeflag & DoubleScanMode) - yres <<= 1; - - if (xres == 720) - xres = 640; - - pVBInfo->VGAHDE = xres; - pVBInfo->HDE = xres; - pVBInfo->VGAVDE = yres; - pVBInfo->VDE = yres; -} - -static void const *XGI_GetLcdPtr(struct XGI330_LCDDataTablStruct const *table, - unsigned short ModeIdIndex, - struct vb_device_info *pVBInfo) -{ - unsigned short i, tempdx, tempbx, modeflag; - - tempbx = 0; - - modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; - - i = 0; - - while (table[i].PANELID != 0xff) { - tempdx = pVBInfo->LCDResInfo; - if (tempbx & 0x0080) { /* OEMUtil */ - tempbx &= ~0x0080; - tempdx = pVBInfo->LCDTypeInfo; - } - - if (pVBInfo->LCDInfo & EnableScalingLCD) - tempdx &= ~PanelResInfo; - - if (table[i].PANELID == tempdx) { - tempbx = table[i].MASK; - tempdx = pVBInfo->LCDInfo; - - if (modeflag & HalfDCLK) - tempdx |= SetLCDLowResolution; - - tempbx &= tempdx; - if (tempbx == table[i].CAP) - break; - } - i++; - } - - return table[i].DATAPTR; -} - -static struct SiS_TVData const *XGI_GetTVPtr( - unsigned short ModeIdIndex, - unsigned short RefreshRateTableIndex, - struct vb_device_info *pVBInfo) -{ - unsigned short i, tempdx, tempal, modeflag; - - modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; - tempal = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; - tempal = tempal & 0x3f; - tempdx = pVBInfo->TVInfo; - - if (pVBInfo->VBInfo & SetInSlaveMode) - tempdx = tempdx | SetTVLockMode; - - if (modeflag & HalfDCLK) - tempdx = tempdx | SetTVLowResolution; - - i = 0; - - while (XGI_TVDataTable[i].MASK != 0xffff) { - if ((tempdx & XGI_TVDataTable[i].MASK) == - XGI_TVDataTable[i].CAP) - break; - i++; - } - - return &XGI_TVDataTable[i].DATAPTR[tempal]; -} - -static void XGI_GetLVDSData(unsigned short ModeIdIndex, - struct vb_device_info *pVBInfo) -{ - struct SiS_LVDSData const *LCDPtr; - - if (!(pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA))) - return; - - LCDPtr = XGI_GetLcdPtr(XGI_EPLLCDDataPtr, ModeIdIndex, pVBInfo); - pVBInfo->VGAHT = LCDPtr->VGAHT; - pVBInfo->VGAVT = LCDPtr->VGAVT; - pVBInfo->HT = LCDPtr->LCDHT; - pVBInfo->VT = LCDPtr->LCDVT; - - if (pVBInfo->LCDInfo & (SetLCDtoNonExpanding | EnableScalingLCD)) - return; - - if ((pVBInfo->LCDResInfo == Panel_1024x768) || - (pVBInfo->LCDResInfo == Panel_1024x768x75)) { - pVBInfo->HDE = 1024; - pVBInfo->VDE = 768; - } else if ((pVBInfo->LCDResInfo == Panel_1280x1024) || - (pVBInfo->LCDResInfo == Panel_1280x1024x75)) { - pVBInfo->HDE = 1280; - pVBInfo->VDE = 1024; - } else if (pVBInfo->LCDResInfo == Panel_1400x1050) { - pVBInfo->HDE = 1400; - pVBInfo->VDE = 1050; - } else { - pVBInfo->HDE = 1600; - pVBInfo->VDE = 1200; - } -} - -static void XGI_ModCRT1Regs(unsigned short ModeIdIndex, - struct xgi_hw_device_info *HwDeviceExtension, - struct vb_device_info *pVBInfo) -{ - unsigned short i; - struct XGI_LVDSCRT1HDataStruct const *LCDPtr = NULL; - struct XGI_LVDSCRT1VDataStruct const *LCDPtr1 = NULL; - - if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) { - LCDPtr = XGI_GetLcdPtr(xgifb_epllcd_crt1_h, ModeIdIndex, - pVBInfo); - - for (i = 0; i < 8; i++) - pVBInfo->TimingH.data[i] = LCDPtr[0].Reg[i]; - } - - XGI_SetCRT1Timing_H(pVBInfo, HwDeviceExtension); - - if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) { - LCDPtr1 = XGI_GetLcdPtr(xgifb_epllcd_crt1_v, ModeIdIndex, - pVBInfo); - for (i = 0; i < 7; i++) - pVBInfo->TimingV.data[i] = LCDPtr1[0].Reg[i]; - } - - XGI_SetCRT1Timing_V(ModeIdIndex, pVBInfo); -} - -static unsigned short XGI_GetLCDCapPtr(struct vb_device_info *pVBInfo) -{ - unsigned char tempal, tempah, tempbl, i; - - tempah = xgifb_reg_get(pVBInfo->P3d4, 0x36); - tempal = tempah & 0x0F; - tempah = tempah & 0xF0; - i = 0; - tempbl = pVBInfo->LCDCapList[i].LCD_ID; - - while (tempbl != 0xFF) { - if (tempbl & 0x80) { /* OEMUtil */ - tempal = tempah; - tempbl = tempbl & ~(0x80); - } - - if (tempal == tempbl) - break; - - i++; - - tempbl = pVBInfo->LCDCapList[i].LCD_ID; - } - - return i; -} - -static unsigned short XGI_GetLCDCapPtr1(struct vb_device_info *pVBInfo) -{ - unsigned short tempah, tempal, tempbl, i; - - tempal = pVBInfo->LCDResInfo; - tempah = pVBInfo->LCDTypeInfo; - - i = 0; - tempbl = pVBInfo->LCDCapList[i].LCD_ID; - - while (tempbl != 0xFF) { - if ((tempbl & 0x80) && (tempbl != 0x80)) { - tempal = tempah; - tempbl &= ~0x80; - } - - if (tempal == tempbl) - break; - - i++; - tempbl = pVBInfo->LCDCapList[i].LCD_ID; - } - - if (tempbl == 0xFF) { - pVBInfo->LCDResInfo = Panel_1024x768; - pVBInfo->LCDTypeInfo = 0; - i = 0; - } - - return i; -} - -static void XGI_GetLCDSync(unsigned short *HSyncWidth, - unsigned short *VSyncWidth, - struct vb_device_info *pVBInfo) -{ - unsigned short Index; - - Index = XGI_GetLCDCapPtr(pVBInfo); - *HSyncWidth = pVBInfo->LCDCapList[Index].LCD_HSyncWidth; - *VSyncWidth = pVBInfo->LCDCapList[Index].LCD_VSyncWidth; -} - -static void XGI_SetLVDSRegs(unsigned short ModeIdIndex, - struct vb_device_info *pVBInfo) -{ - unsigned short tempbx, tempax, tempcx, tempdx, push1, push2, modeflag; - unsigned long temp, temp1, temp2, temp3, push3; - struct XGI330_LCDDataDesStruct2 const *LCDPtr1 = NULL; - - modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; - LCDPtr1 = XGI_GetLcdPtr(XGI_EPLLCDDesDataPtr, ModeIdIndex, pVBInfo); - - XGI_GetLCDSync(&tempax, &tempbx, pVBInfo); - push1 = tempbx; - push2 = tempax; - - /* GetLCDResInfo */ - if ((pVBInfo->LCDResInfo == Panel_1024x768) || - (pVBInfo->LCDResInfo == Panel_1024x768x75)) { - tempax = 1024; - tempbx = 768; - } else if ((pVBInfo->LCDResInfo == Panel_1280x1024) || - (pVBInfo->LCDResInfo == Panel_1280x1024x75)) { - tempax = 1280; - tempbx = 1024; - } else if (pVBInfo->LCDResInfo == Panel_1400x1050) { - tempax = 1400; - tempbx = 1050; - } else { - tempax = 1600; - tempbx = 1200; - } - - if (pVBInfo->LCDInfo & SetLCDtoNonExpanding) { - pVBInfo->HDE = tempax; - pVBInfo->VDE = tempbx; - pVBInfo->VGAHDE = tempax; - pVBInfo->VGAVDE = tempbx; - } - - tempax = pVBInfo->HT; - - tempbx = LCDPtr1->LCDHDES; - - tempcx = pVBInfo->HDE; - tempbx = tempbx & 0x0fff; - tempcx += tempbx; - - if (tempcx >= tempax) - tempcx -= tempax; - - xgifb_reg_set(pVBInfo->Part1Port, 0x1A, tempbx & 0x07); - - tempcx >>= 3; - tempbx >>= 3; - - xgifb_reg_set(pVBInfo->Part1Port, 0x16, - (unsigned short)(tempbx & 0xff)); - xgifb_reg_set(pVBInfo->Part1Port, 0x17, - (unsigned short)(tempcx & 0xff)); - - tempax = pVBInfo->HT; - - tempbx = LCDPtr1->LCDHRS; - - tempcx = push2; - - if (pVBInfo->LCDInfo & EnableScalingLCD) - tempcx = LCDPtr1->LCDHSync; - - tempcx += tempbx; - - if (tempcx >= tempax) - tempcx -= tempax; - - tempax = tempbx & 0x07; - tempax >>= 5; - tempcx >>= 3; - tempbx >>= 3; - - tempcx &= 0x1f; - tempax |= tempcx; - - xgifb_reg_set(pVBInfo->Part1Port, 0x15, tempax); - xgifb_reg_set(pVBInfo->Part1Port, 0x14, - (unsigned short)(tempbx & 0xff)); - - tempax = pVBInfo->VT; - tempbx = LCDPtr1->LCDVDES; - tempcx = pVBInfo->VDE; - - tempbx = tempbx & 0x0fff; - tempcx += tempbx; - if (tempcx >= tempax) - tempcx -= tempax; - - xgifb_reg_set(pVBInfo->Part1Port, 0x1b, - (unsigned short)(tempbx & 0xff)); - xgifb_reg_set(pVBInfo->Part1Port, 0x1c, - (unsigned short)(tempcx & 0xff)); - - tempbx = (tempbx >> 8) & 0x07; - tempcx = (tempcx >> 8) & 0x07; - - xgifb_reg_set(pVBInfo->Part1Port, 0x1d, - (unsigned short)((tempcx << 3) | tempbx)); - - tempax = pVBInfo->VT; - tempbx = LCDPtr1->LCDVRS; - - tempcx = push1; - - if (pVBInfo->LCDInfo & EnableScalingLCD) - tempcx = LCDPtr1->LCDVSync; - - tempcx += tempbx; - if (tempcx >= tempax) - tempcx -= tempax; - - xgifb_reg_set(pVBInfo->Part1Port, 0x18, - (unsigned short)(tempbx & 0xff)); - xgifb_reg_and_or(pVBInfo->Part1Port, 0x19, ~0x0f, - (unsigned short)(tempcx & 0x0f)); - - tempax = ((tempbx >> 8) & 0x07) << 3; - - tempbx = pVBInfo->VGAVDE; - if (tempbx != pVBInfo->VDE) - tempax |= 0x40; - - if (pVBInfo->LCDInfo & XGI_EnableLVDSDDA) - tempax |= 0x40; - - xgifb_reg_and_or(pVBInfo->Part1Port, 0x1a, 0x07, tempax); - - tempbx = pVBInfo->VDE; - tempax = pVBInfo->VGAVDE; - - temp = tempax; /* 0430 ylshieh */ - temp1 = (temp << 18) / tempbx; - - tempdx = (unsigned short)((temp << 18) % tempbx); - - if (tempdx != 0) - temp1 += 1; - - temp2 = temp1; - push3 = temp2; - - xgifb_reg_set(pVBInfo->Part1Port, 0x37, (unsigned short)(temp2 & 0xff)); - xgifb_reg_set(pVBInfo->Part1Port, 0x36, (unsigned short)((temp2 >> 8) & 0xff)); - - tempbx = (unsigned short)(temp2 >> 16); - tempax = tempbx & 0x03; - - tempbx = pVBInfo->VGAVDE; - if (tempbx == pVBInfo->VDE) - tempax |= 0x04; - - xgifb_reg_set(pVBInfo->Part1Port, 0x35, tempax); - - if (pVBInfo->VBType & VB_XGI301C) { - temp2 = push3; - xgifb_reg_set(pVBInfo->Part4Port, - 0x3c, - (unsigned short)(temp2 & 0xff)); - xgifb_reg_set(pVBInfo->Part4Port, - 0x3b, - (unsigned short)((temp2 >> 8) & - 0xff)); - tempbx = (unsigned short)(temp2 >> 16); - xgifb_reg_and_or(pVBInfo->Part4Port, 0x3a, ~0xc0, - (unsigned short)((tempbx & 0xff) << 6)); - - tempcx = pVBInfo->VGAVDE; - if (tempcx == pVBInfo->VDE) - xgifb_reg_and_or(pVBInfo->Part4Port, 0x30, ~0x0c, 0x00); - else - xgifb_reg_and_or(pVBInfo->Part4Port, 0x30, ~0x0c, 0x08); - } - - tempcx = pVBInfo->VGAHDE; - tempbx = pVBInfo->HDE; - - temp1 = tempcx << 16; - - tempax = (unsigned short)(temp1 / tempbx); - - if ((tempbx & 0xffff) == (tempcx & 0xffff)) - tempax = 65535; - - temp3 = tempax; - temp1 = pVBInfo->VGAHDE << 16; - - temp1 /= temp3; - temp3 <<= 16; - temp1 -= 1; - - temp3 = (temp3 & 0xffff0000) + (temp1 & 0xffff); - - tempax = (unsigned short)(temp3 & 0xff); - xgifb_reg_set(pVBInfo->Part1Port, 0x1f, tempax); - - temp1 = pVBInfo->VGAVDE << 18; - temp1 = temp1 / push3; - tempbx = (unsigned short)(temp1 & 0xffff); - - if (pVBInfo->LCDResInfo == Panel_1024x768) - tempbx -= 1; - - tempax = ((tempbx >> 8) & 0xff) << 3; - tempax |= (unsigned short)((temp3 >> 8) & 0x07); - xgifb_reg_set(pVBInfo->Part1Port, 0x20, - (unsigned short)(tempax & 0xff)); - xgifb_reg_set(pVBInfo->Part1Port, 0x21, - (unsigned short)(tempbx & 0xff)); - - temp3 >>= 16; - - if (modeflag & HalfDCLK) - temp3 >>= 1; - - xgifb_reg_set(pVBInfo->Part1Port, 0x22, - (unsigned short)((temp3 >> 8) & 0xff)); - xgifb_reg_set(pVBInfo->Part1Port, 0x23, - (unsigned short)(temp3 & 0xff)); -} - -/* - * Function : XGI_GETLCDVCLKPtr - * Input : - * Output : al -> VCLK Index - * Description : - */ -static void XGI_GetLCDVCLKPtr(unsigned char *di_0, unsigned char *di_1, - struct vb_device_info *pVBInfo) -{ - unsigned short index; - - if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) { - index = XGI_GetLCDCapPtr1(pVBInfo); - - if (pVBInfo->VBInfo & SetCRT2ToLCD) { /* LCDB */ - *di_0 = pVBInfo->LCDCapList[index].LCUCHAR_VCLKData1; - *di_1 = pVBInfo->LCDCapList[index].LCUCHAR_VCLKData2; - } else { /* LCDA */ - *di_0 = pVBInfo->LCDCapList[index].LCDA_VCLKData1; - *di_1 = pVBInfo->LCDCapList[index].LCDA_VCLKData2; - } - } -} - -static unsigned char XGI_GetVCLKPtr(unsigned short RefreshRateTableIndex, - unsigned short ModeIdIndex, - struct vb_device_info *pVBInfo) -{ - unsigned short index, modeflag; - unsigned char tempal; - - /* si+Ext_ResInfo */ - modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; - - if ((pVBInfo->SetFlag & ProgrammingCRT2) && - !(pVBInfo->LCDInfo & EnableScalingLCD)) { /* {LCDA/LCDB} */ - index = XGI_GetLCDCapPtr(pVBInfo); - tempal = pVBInfo->LCDCapList[index].LCD_VCLK; - - if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) - return tempal; - - /* {TV} */ - if (pVBInfo->VBType & - (VB_SIS301B | - VB_SIS302B | - VB_SIS301LV | - VB_SIS302LV | - VB_XGI301C)) { - if (pVBInfo->VBInfo & SetCRT2ToHiVision) { - tempal = TVCLKBASE_315 + HiTVVCLKDIV2; - if (!(pVBInfo->TVInfo & RPLLDIV2XO)) - tempal = TVCLKBASE_315 + HiTVVCLK; - if (pVBInfo->TVInfo & TVSimuMode) { - tempal = TVCLKBASE_315 + HiTVSimuVCLK; - if (!(modeflag & Charx8Dot)) - tempal = TVCLKBASE_315 + - HiTVTextVCLK; - } - return tempal; - } - - if (pVBInfo->TVInfo & TVSetYPbPr750p) - return XGI_YPbPr750pVCLK; - - if (pVBInfo->TVInfo & TVSetYPbPr525p) - return YPbPr525pVCLK; - - tempal = NTSC1024VCLK; - - if (!(pVBInfo->TVInfo & NTSC1024x768)) { - tempal = TVCLKBASE_315 + TVVCLKDIV2; - if (!(pVBInfo->TVInfo & RPLLDIV2XO)) - tempal = TVCLKBASE_315 + TVVCLK; - } - - if (pVBInfo->VBInfo & SetCRT2ToTV) - return tempal; - } - } /* {End of VB} */ - - inb((pVBInfo->P3ca + 0x02)); - return XGI330_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; -} - -static void XGI_GetVCLKLen(unsigned char tempal, unsigned char *di_0, - unsigned char *di_1, struct vb_device_info *pVBInfo) -{ - if (pVBInfo->VBType & (VB_SIS301 | VB_SIS301B | VB_SIS302B - | VB_SIS301LV | VB_SIS302LV | VB_XGI301C)) { - if (!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) && - (pVBInfo->SetFlag & ProgrammingCRT2)) { - *di_0 = XGI_VBVCLKData[tempal].Part4_A; - *di_1 = XGI_VBVCLKData[tempal].Part4_B; - } - } else { - *di_0 = XGI_VCLKData[tempal].SR2B; - *di_1 = XGI_VCLKData[tempal].SR2C; - } -} - -static void XGI_SetCRT2ECLK(unsigned short ModeIdIndex, - unsigned short RefreshRateTableIndex, - struct vb_device_info *pVBInfo) -{ - unsigned char di_0, di_1, tempal; - int i; - - tempal = XGI_GetVCLKPtr(RefreshRateTableIndex, ModeIdIndex, pVBInfo); - XGI_GetVCLKLen(tempal, &di_0, &di_1, pVBInfo); - XGI_GetLCDVCLKPtr(&di_0, &di_1, pVBInfo); - - for (i = 0; i < 4; i++) { - xgifb_reg_and_or(pVBInfo->P3d4, 0x31, ~0x30, - (unsigned short)(0x10 * i)); - if (!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) && - !(pVBInfo->VBInfo & SetInSlaveMode)) { - xgifb_reg_set(pVBInfo->P3c4, 0x2e, di_0); - xgifb_reg_set(pVBInfo->P3c4, 0x2f, di_1); - } else { - xgifb_reg_set(pVBInfo->P3c4, 0x2b, di_0); - xgifb_reg_set(pVBInfo->P3c4, 0x2c, di_1); - } - } -} - -static void XGI_UpdateModeInfo(struct vb_device_info *pVBInfo) -{ - unsigned short tempcl, tempch, temp, tempbl, tempax; - - if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV - | VB_SIS302LV | VB_XGI301C)) { - tempcl = 0; - tempch = 0; - temp = xgifb_reg_get(pVBInfo->P3c4, 0x01); - - if (!(temp & 0x20)) { - temp = xgifb_reg_get(pVBInfo->P3d4, 0x17); - if (temp & 0x80) { - temp = xgifb_reg_get(pVBInfo->P3d4, 0x53); - if (!(temp & 0x40)) - tempcl |= ActiveCRT1; - } - } - - temp = xgifb_reg_get(pVBInfo->Part1Port, 0x2e); - temp &= 0x0f; - - if (!(temp == 0x08)) { - /* Check ChannelA */ - tempax = xgifb_reg_get(pVBInfo->Part1Port, 0x13); - if (tempax & 0x04) - tempcl = tempcl | ActiveLCD; - - temp &= 0x05; - - if (!(tempcl & ActiveLCD)) { - if (temp == 0x01) - tempcl |= ActiveCRT2; - } - - if (temp == 0x04) - tempcl |= ActiveLCD; - - if (temp == 0x05) { - temp = xgifb_reg_get(pVBInfo->Part2Port, 0x00); - - if (!(temp & 0x08)) - tempch |= ActiveAVideo; - - if (!(temp & 0x04)) - tempch |= ActiveSVideo; - - if (temp & 0x02) - tempch |= ActiveSCART; - - if (pVBInfo->VBInfo & SetCRT2ToHiVision) { - if (temp & 0x01) - tempch |= ActiveHiTV; - } - - if (pVBInfo->VBInfo & SetCRT2ToYPbPr525750) { - temp = xgifb_reg_get( - pVBInfo->Part2Port, - 0x4d); - - if (temp & 0x10) - tempch |= ActiveYPbPr; - } - - if (tempch != 0) - tempcl |= ActiveTV; - } - } - - temp = xgifb_reg_get(pVBInfo->P3d4, 0x3d); - if (tempcl & ActiveLCD) { - if ((pVBInfo->SetFlag & ReserveTVOption)) { - if (temp & ActiveTV) - tempcl |= ActiveTV; - } - } - temp = tempcl; - tempbl = ~XGI_ModeSwitchStatus; - xgifb_reg_and_or(pVBInfo->P3d4, 0x3d, tempbl, temp); - - if (!(pVBInfo->SetFlag & ReserveTVOption)) - xgifb_reg_set(pVBInfo->P3d4, 0x3e, tempch); - } -} - -void XGI_GetVBType(struct vb_device_info *pVBInfo) -{ - unsigned short flag, tempbx, tempah; - - tempbx = VB_SIS302B; - flag = xgifb_reg_get(pVBInfo->Part4Port, 0x00); - if (flag == 0x02) - goto finish; - - tempbx = VB_SIS301; - flag = xgifb_reg_get(pVBInfo->Part4Port, 0x01); - if (flag < 0xB0) - goto finish; - - tempbx = VB_SIS301B; - if (flag < 0xC0) - goto bigger_than_0xB0; - - tempbx = VB_XGI301C; - if (flag < 0xD0) - goto bigger_than_0xB0; - - tempbx = VB_SIS301LV; - if (flag < 0xE0) - goto bigger_than_0xB0; - - tempbx = VB_SIS302LV; - tempah = xgifb_reg_get(pVBInfo->Part4Port, 0x39); - if (tempah != 0xFF) - tempbx = VB_XGI301C; - -bigger_than_0xB0: - if (tempbx & (VB_SIS301B | VB_SIS302B)) { - flag = xgifb_reg_get(pVBInfo->Part4Port, 0x23); - if (!(flag & 0x02)) - tempbx = tempbx | VB_NoLCD; - } - -finish: - pVBInfo->VBType = tempbx; -} - -static void XGI_GetVBInfo(unsigned short ModeIdIndex, - struct vb_device_info *pVBInfo) -{ - unsigned short tempax, push, tempbx, temp, modeflag; - - modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; - pVBInfo->SetFlag = 0; - pVBInfo->ModeType = modeflag & ModeTypeMask; - tempbx = 0; - - if (!(pVBInfo->VBType & 0xFFFF)) - return; - - /* Check Display Device */ - temp = xgifb_reg_get(pVBInfo->P3d4, 0x30); - tempbx = tempbx | temp; - temp = xgifb_reg_get(pVBInfo->P3d4, 0x31); - push = temp; - push <<= 8; - tempax = temp << 8; - tempbx = tempbx | tempax; - temp = SetCRT2ToDualEdge | SetCRT2ToYPbPr525750 | XGI_SetCRT2ToLCDA - | SetInSlaveMode | DisableCRT2Display; - temp = 0xFFFF ^ temp; - tempbx &= temp; - - temp = xgifb_reg_get(pVBInfo->P3d4, 0x38); - - if (pVBInfo->VBType & (VB_SIS302B | VB_SIS301LV | VB_SIS302LV | - VB_XGI301C)) { - if (temp & EnableDualEdge) { - tempbx |= SetCRT2ToDualEdge; - if (temp & SetToLCDA) - tempbx |= XGI_SetCRT2ToLCDA; - } - } - - if (pVBInfo->VBType & (VB_SIS301LV | VB_SIS302LV | VB_XGI301C)) { - if (temp & SetYPbPr) { - /* shampoo add for new scratch */ - temp = xgifb_reg_get(pVBInfo->P3d4, 0x35); - temp &= YPbPrMode; - tempbx |= SetCRT2ToHiVision; - - if (temp != YPbPrMode1080i) { - tempbx &= ~SetCRT2ToHiVision; - tempbx |= SetCRT2ToYPbPr525750; - } - } - } - - tempax = push; /* restore CR31 */ - - temp = 0x09FC; - - if (!(tempbx & temp)) { - tempax |= DisableCRT2Display; - tempbx = 0; - } - - if (!(pVBInfo->VBType & VB_NoLCD)) { - if (tempbx & XGI_SetCRT2ToLCDA) { - if (tempbx & SetSimuScanMode) - tempbx &= (~(SetCRT2ToLCD | SetCRT2ToRAMDAC | - SwitchCRT2)); - else - tempbx &= (~(SetCRT2ToLCD | SetCRT2ToRAMDAC | - SetCRT2ToTV | SwitchCRT2)); - } - } - - /* shampoo add */ - /* for driver abnormal */ - if (!(tempbx & (SwitchCRT2 | SetSimuScanMode))) { - if (tempbx & SetCRT2ToRAMDAC) { - tempbx &= (0xFF00 | SetCRT2ToRAMDAC | - SwitchCRT2 | SetSimuScanMode); - tempbx &= (0x00FF | (~SetCRT2ToYPbPr525750)); - } - } - - if (!(pVBInfo->VBType & VB_NoLCD)) { - if (tempbx & SetCRT2ToLCD) { - tempbx &= (0xFF00 | SetCRT2ToLCD | SwitchCRT2 | - SetSimuScanMode); - tempbx &= (0x00FF | (~SetCRT2ToYPbPr525750)); - } - } - - if (tempbx & SetCRT2ToSCART) { - tempbx &= (0xFF00 | SetCRT2ToSCART | SwitchCRT2 | - SetSimuScanMode); - tempbx &= (0x00FF | (~SetCRT2ToYPbPr525750)); - } - - if (tempbx & SetCRT2ToYPbPr525750) - tempbx &= (0xFF00 | SwitchCRT2 | SetSimuScanMode); - - if (tempbx & SetCRT2ToHiVision) - tempbx &= (0xFF00 | SetCRT2ToHiVision | SwitchCRT2 | - SetSimuScanMode); - - if (tempax & DisableCRT2Display) { /* Set Display Device Info */ - if (!(tempbx & (SwitchCRT2 | SetSimuScanMode))) - tempbx = DisableCRT2Display; - } - - if (!(tempbx & DisableCRT2Display)) { - if (!(tempbx & DriverMode) || !(modeflag & CRT2Mode)) { - if (!(tempbx & XGI_SetCRT2ToLCDA)) - tempbx |= (SetInSlaveMode | SetSimuScanMode); - } - - /* LCD+TV can't support in slave mode - * (Force LCDA+TV->LCDB) - */ - if ((tempbx & SetInSlaveMode) && (tempbx & XGI_SetCRT2ToLCDA)) { - tempbx ^= (SetCRT2ToLCD | XGI_SetCRT2ToLCDA | - SetCRT2ToDualEdge); - pVBInfo->SetFlag |= ReserveTVOption; - } - } - - pVBInfo->VBInfo = tempbx; -} - -static void XGI_GetTVInfo(unsigned short ModeIdIndex, - struct vb_device_info *pVBInfo) -{ - unsigned short tempbx = 0, resinfo = 0, modeflag, index1; - - if (pVBInfo->VBInfo & SetCRT2ToTV) { - modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; - resinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO; - - tempbx = xgifb_reg_get(pVBInfo->P3d4, 0x35); - if (tempbx & TVSetPAL) { - tempbx &= (SetCHTVOverScan | - TVSetPALM | - TVSetPALN | - TVSetPAL); - if (tempbx & TVSetPALM) - /* set to NTSC if PAL-M */ - tempbx &= ~TVSetPAL; - } else { - tempbx &= (SetCHTVOverScan | - TVSetNTSCJ | - TVSetPAL); - } - - if (pVBInfo->VBInfo & SetCRT2ToSCART) - tempbx |= TVSetPAL; - - if (pVBInfo->VBInfo & SetCRT2ToYPbPr525750) { - index1 = xgifb_reg_get(pVBInfo->P3d4, 0x35); - index1 &= YPbPrMode; - - if (index1 == YPbPrMode525i) - tempbx |= TVSetYPbPr525i; - - if (index1 == YPbPrMode525p) - tempbx = tempbx | TVSetYPbPr525p; - if (index1 == YPbPrMode750p) - tempbx = tempbx | TVSetYPbPr750p; - } - - if (pVBInfo->VBInfo & SetCRT2ToHiVision) - tempbx = tempbx | TVSetHiVision | TVSetPAL; - - if ((pVBInfo->VBInfo & SetInSlaveMode) && - (!(pVBInfo->VBInfo & SetNotSimuMode))) - tempbx |= TVSimuMode; - - if (!(tempbx & TVSetPAL) && (modeflag > 13) && (resinfo == 8)) { - /* NTSC 1024x768, */ - tempbx |= NTSC1024x768; - } - - tempbx |= RPLLDIV2XO; - - if (pVBInfo->VBInfo & SetCRT2ToHiVision) { - if (pVBInfo->VBInfo & SetInSlaveMode) - tempbx &= (~RPLLDIV2XO); - } else if (tempbx & (TVSetYPbPr525p | TVSetYPbPr750p)) { - tempbx &= (~RPLLDIV2XO); - } else if (!(pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | - VB_SIS301LV | VB_SIS302LV | - VB_XGI301C))) { - if (tempbx & TVSimuMode) - tempbx &= (~RPLLDIV2XO); - } - } - pVBInfo->TVInfo = tempbx; -} - -static unsigned char XGI_GetLCDInfo(unsigned short ModeIdIndex, - struct vb_device_info *pVBInfo) -{ - unsigned short temp, tempax, tempbx, resinfo = 0, LCDIdIndex; - - pVBInfo->LCDResInfo = 0; - pVBInfo->LCDTypeInfo = 0; - pVBInfo->LCDInfo = 0; - - /* si+Ext_ResInfo */ - resinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO; - temp = xgifb_reg_get(pVBInfo->P3d4, 0x36); /* Get LCD Res.Info */ - tempbx = temp & 0x0F; - - if (tempbx == 0) - tempbx = Panel_1024x768; /* default */ - - /* LCD75 */ - if ((tempbx == Panel_1024x768) || (tempbx == Panel_1280x1024)) { - if (pVBInfo->VBInfo & DriverMode) { - tempax = xgifb_reg_get(pVBInfo->P3d4, 0x33); - if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) - tempax &= 0x0F; - else - tempax >>= 4; - - if ((resinfo == 6) || (resinfo == 9)) { - if (tempax >= 3) - tempbx |= PanelRef75Hz; - } else if ((resinfo == 7) || (resinfo == 8)) { - if (tempax >= 4) - tempbx |= PanelRef75Hz; - } - } - } - - pVBInfo->LCDResInfo = tempbx; - - /* End of LCD75 */ - - if (!(pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA))) - return 0; - - tempbx = 0; - - temp = xgifb_reg_get(pVBInfo->P3d4, 0x37); - - temp &= (ScalingLCD | LCDNonExpanding | LCDSyncBit | SetPWDEnable); - - tempbx |= temp; - - LCDIdIndex = XGI_GetLCDCapPtr1(pVBInfo); - - tempax = pVBInfo->LCDCapList[LCDIdIndex].LCD_Capability; - - if (((pVBInfo->VBType & VB_SIS302LV) || - (pVBInfo->VBType & VB_XGI301C)) && (tempax & XGI_LCDDualLink)) - tempbx |= SetLCDDualLink; - - if ((pVBInfo->LCDResInfo == Panel_1400x1050) && - (pVBInfo->VBInfo & SetCRT2ToLCD) && (resinfo == 9) && - !(tempbx & EnableScalingLCD)) - /* - * set to center in 1280x1024 LCDB - * for Panel_1400x1050 - */ - tempbx |= SetLCDtoNonExpanding; - - if (pVBInfo->VBInfo & SetInSlaveMode) { - if (pVBInfo->VBInfo & SetNotSimuMode) - tempbx |= XGI_LCDVESATiming; - } else { - tempbx |= XGI_LCDVESATiming; - } - - pVBInfo->LCDInfo = tempbx; - - return 1; -} - -unsigned char XGI_SearchModeID(unsigned short ModeNo, - unsigned short *ModeIdIndex) -{ - for (*ModeIdIndex = 0;; (*ModeIdIndex)++) { - if (XGI330_EModeIDTable[*ModeIdIndex].Ext_ModeID == ModeNo) - break; - if (XGI330_EModeIDTable[*ModeIdIndex].Ext_ModeID == 0xFF) - return 0; - } - - return 1; -} - -static unsigned char XG21GPIODataTransfer(unsigned char ujDate) -{ - unsigned char ujRet = 0; - unsigned char i = 0; - - for (i = 0; i < 8; i++) { - ujRet <<= 1; - ujRet |= (ujDate >> i) & 1; - } - - return ujRet; -} - -/* - * output - * bl[5] : LVDS signal - * bl[1] : LVDS backlight - * bl[0] : LVDS VDD - */ -static unsigned char XGI_XG21GetPSCValue(struct vb_device_info *pVBInfo) -{ - unsigned char CR4A, temp; - - CR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A); - xgifb_reg_and(pVBInfo->P3d4, 0x4A, ~0x23); /* enable GPIO write */ - - temp = xgifb_reg_get(pVBInfo->P3d4, 0x48); - - temp = XG21GPIODataTransfer(temp); - temp &= 0x23; - xgifb_reg_set(pVBInfo->P3d4, 0x4A, CR4A); - return temp; -} - -/* - * output - * bl[5] : LVDS signal - * bl[1] : LVDS backlight - * bl[0] : LVDS VDD - */ -static unsigned char XGI_XG27GetPSCValue(struct vb_device_info *pVBInfo) -{ - unsigned char CR4A, CRB4, temp; - - CR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A); - xgifb_reg_and(pVBInfo->P3d4, 0x4A, ~0x0C); /* enable GPIO write */ - - temp = xgifb_reg_get(pVBInfo->P3d4, 0x48); - - temp &= 0x0C; - temp >>= 2; - xgifb_reg_set(pVBInfo->P3d4, 0x4A, CR4A); - CRB4 = xgifb_reg_get(pVBInfo->P3d4, 0xB4); - temp |= ((CRB4 & 0x04) << 3); - return temp; -} - -/* - * input - * bl[5] : 1;LVDS signal on - * bl[1] : 1;LVDS backlight on - * bl[0] : 1:LVDS VDD on - * bh: 100000b : clear bit 5, to set bit5 - * 000010b : clear bit 1, to set bit1 - * 000001b : clear bit 0, to set bit0 - */ -static void XGI_XG21BLSignalVDD(unsigned short tempbh, unsigned short tempbl, - struct vb_device_info *pVBInfo) -{ - unsigned char CR4A, temp; - - CR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A); - tempbh &= 0x23; - tempbl &= 0x23; - xgifb_reg_and(pVBInfo->P3d4, 0x4A, ~tempbh); /* enable GPIO write */ - - if (tempbh & 0x20) { - temp = (tempbl >> 4) & 0x02; - - /* CR B4[1] */ - xgifb_reg_and_or(pVBInfo->P3d4, 0xB4, ~0x02, temp); - } - - temp = xgifb_reg_get(pVBInfo->P3d4, 0x48); - - temp = XG21GPIODataTransfer(temp); - temp &= ~tempbh; - temp |= tempbl; - xgifb_reg_set(pVBInfo->P3d4, 0x48, temp); -} - -static void XGI_XG27BLSignalVDD(unsigned short tempbh, unsigned short tempbl, - struct vb_device_info *pVBInfo) -{ - unsigned char CR4A, temp; - unsigned short tempbh0, tempbl0; - - tempbh0 = tempbh; - tempbl0 = tempbl; - tempbh0 &= 0x20; - tempbl0 &= 0x20; - tempbh0 >>= 3; - tempbl0 >>= 3; - - if (tempbh & 0x20) { - temp = (tempbl >> 4) & 0x02; - - /* CR B4[1] */ - xgifb_reg_and_or(pVBInfo->P3d4, 0xB4, ~0x02, temp); - } - xgifb_reg_and_or(pVBInfo->P3d4, 0xB4, ~tempbh0, tempbl0); - - CR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A); - tempbh &= 0x03; - tempbl &= 0x03; - tempbh <<= 2; - tempbl <<= 2; /* GPIOC,GPIOD */ - xgifb_reg_and(pVBInfo->P3d4, 0x4A, ~tempbh); /* enable GPIO write */ - xgifb_reg_and_or(pVBInfo->P3d4, 0x48, ~tempbh, tempbl); -} - -static void XGI_DisplayOn(struct xgifb_video_info *xgifb_info, - struct xgi_hw_device_info *pXGIHWDE, - struct vb_device_info *pVBInfo) -{ - xgifb_reg_and_or(pVBInfo->P3c4, 0x01, 0xDF, 0x00); - if (pXGIHWDE->jChipType == XG21) { - if (pVBInfo->IF_DEF_LVDS == 1) { - if (!(XGI_XG21GetPSCValue(pVBInfo) & 0x1)) { - /* LVDS VDD on */ - XGI_XG21BLSignalVDD(0x01, 0x01, pVBInfo); - mdelay(xgifb_info->lvds_data.PSC_S2); - } - if (!(XGI_XG21GetPSCValue(pVBInfo) & 0x20)) - /* LVDS signal on */ - XGI_XG21BLSignalVDD(0x20, 0x20, pVBInfo); - mdelay(xgifb_info->lvds_data.PSC_S3); - /* LVDS backlight on */ - XGI_XG21BLSignalVDD(0x02, 0x02, pVBInfo); - } else { - /* DVO/DVI signal on */ - XGI_XG21BLSignalVDD(0x20, 0x20, pVBInfo); - } - } - - if (pXGIHWDE->jChipType == XG27) { - if (pVBInfo->IF_DEF_LVDS == 1) { - if (!(XGI_XG27GetPSCValue(pVBInfo) & 0x1)) { - /* LVDS VDD on */ - XGI_XG27BLSignalVDD(0x01, 0x01, pVBInfo); - mdelay(xgifb_info->lvds_data.PSC_S2); - } - if (!(XGI_XG27GetPSCValue(pVBInfo) & 0x20)) - /* LVDS signal on */ - XGI_XG27BLSignalVDD(0x20, 0x20, pVBInfo); - mdelay(xgifb_info->lvds_data.PSC_S3); - /* LVDS backlight on */ - XGI_XG27BLSignalVDD(0x02, 0x02, pVBInfo); - } else { - /* DVO/DVI signal on */ - XGI_XG27BLSignalVDD(0x20, 0x20, pVBInfo); - } - } -} - -void XGI_DisplayOff(struct xgifb_video_info *xgifb_info, - struct xgi_hw_device_info *pXGIHWDE, - struct vb_device_info *pVBInfo) -{ - if (pXGIHWDE->jChipType == XG21) { - if (pVBInfo->IF_DEF_LVDS == 1) { - /* LVDS backlight off */ - XGI_XG21BLSignalVDD(0x02, 0x00, pVBInfo); - mdelay(xgifb_info->lvds_data.PSC_S3); - } else { - /* DVO/DVI signal off */ - XGI_XG21BLSignalVDD(0x20, 0x00, pVBInfo); - } - } - - if (pXGIHWDE->jChipType == XG27) { - if ((XGI_XG27GetPSCValue(pVBInfo) & 0x2)) { - /* LVDS backlight off */ - XGI_XG27BLSignalVDD(0x02, 0x00, pVBInfo); - mdelay(xgifb_info->lvds_data.PSC_S3); - } - - if (pVBInfo->IF_DEF_LVDS == 0) { - /* DVO/DVI signal off */ - XGI_XG27BLSignalVDD(0x20, 0x00, pVBInfo); - } - } - - xgifb_reg_and_or(pVBInfo->P3c4, 0x01, 0xDF, 0x20); -} - -static void XGI_WaitDisply(struct vb_device_info *pVBInfo) -{ - while ((inb(pVBInfo->P3da) & 0x01)) - break; - - while (!(inb(pVBInfo->P3da) & 0x01)) - break; -} - -static void XGI_AutoThreshold(struct vb_device_info *pVBInfo) -{ - xgifb_reg_or(pVBInfo->Part1Port, 0x01, 0x40); -} - -static void XGI_SaveCRT2Info(unsigned short ModeNo, - struct vb_device_info *pVBInfo) -{ - unsigned short temp1, temp2; - - /* reserve CR34 for CRT1 Mode No */ - xgifb_reg_set(pVBInfo->P3d4, 0x34, ModeNo); - temp1 = (pVBInfo->VBInfo & SetInSlaveMode) >> 8; - temp2 = ~(SetInSlaveMode >> 8); - xgifb_reg_and_or(pVBInfo->P3d4, 0x31, temp2, temp1); -} - -static void XGI_GetCRT2ResInfo(unsigned short ModeIdIndex, - struct vb_device_info *pVBInfo) -{ - unsigned short xres, yres, modeflag, resindex; - - resindex = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO; - xres = XGI330_ModeResInfo[resindex].HTotal; /* xres->ax */ - yres = XGI330_ModeResInfo[resindex].VTotal; /* yres->bx */ - /* si+St_ModeFlag */ - modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; - - if (modeflag & HalfDCLK) - xres *= 2; - - if (modeflag & DoubleScanMode) - yres *= 2; - - if (!(pVBInfo->VBInfo & SetCRT2ToLCD)) - goto exit; - - if (pVBInfo->LCDResInfo == Panel_1600x1200) { - if (!(pVBInfo->LCDInfo & XGI_LCDVESATiming)) { - if (yres == 1024) - yres = 1056; - } - } - - if (pVBInfo->LCDResInfo == Panel_1280x1024) { - if (yres == 400) - yres = 405; - else if (yres == 350) - yres = 360; - - if (pVBInfo->LCDInfo & XGI_LCDVESATiming) { - if (yres == 360) - yres = 375; - } - } - - if (pVBInfo->LCDResInfo == Panel_1024x768) { - if (!(pVBInfo->LCDInfo & XGI_LCDVESATiming)) { - if (!(pVBInfo->LCDInfo & LCDNonExpanding)) { - if (yres == 350) - yres = 357; - else if (yres == 400) - yres = 420; - else if (yres == 480) - yres = 525; - } - } - } - - if (xres == 720) - xres = 640; - -exit: - pVBInfo->VGAHDE = xres; - pVBInfo->HDE = xres; - pVBInfo->VGAVDE = yres; - pVBInfo->VDE = yres; -} - -static unsigned char XGI_IsLCDDualLink(struct vb_device_info *pVBInfo) -{ - if ((pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) && - (pVBInfo->LCDInfo & SetLCDDualLink)) /* shampoo0129 */ - return 1; - - return 0; -} - -static void XGI_GetRAMDAC2DATA(unsigned short ModeIdIndex, - unsigned short RefreshRateTableIndex, - struct vb_device_info *pVBInfo) -{ - unsigned short tempax, tempbx, temp1, temp2, modeflag = 0, tempcx, - CRT1Index; - - pVBInfo->RVBHCMAX = 1; - pVBInfo->RVBHCFACT = 1; - modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; - CRT1Index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; - CRT1Index &= IndexMask; - temp1 = (unsigned short)XGI_CRT1Table[CRT1Index].CR[0]; - temp2 = (unsigned short)XGI_CRT1Table[CRT1Index].CR[5]; - tempax = (temp1 & 0xFF) | ((temp2 & 0x03) << 8); - tempbx = (unsigned short)XGI_CRT1Table[CRT1Index].CR[8]; - tempcx = (unsigned short)XGI_CRT1Table[CRT1Index].CR[14] << 8; - tempcx &= 0x0100; - tempcx <<= 2; - tempbx |= tempcx; - temp1 = (unsigned short)XGI_CRT1Table[CRT1Index].CR[9]; - - if (temp1 & 0x01) - tempbx |= 0x0100; - - if (temp1 & 0x20) - tempbx |= 0x0200; - tempax += 5; - - if (modeflag & Charx8Dot) - tempax *= 8; - else - tempax *= 9; - - pVBInfo->VGAHT = tempax; - pVBInfo->HT = tempax; - tempbx++; - pVBInfo->VGAVT = tempbx; - pVBInfo->VT = tempbx; -} - -static void XGI_GetCRT2Data(unsigned short ModeIdIndex, - unsigned short RefreshRateTableIndex, - struct vb_device_info *pVBInfo) -{ - unsigned short tempax = 0, tempbx = 0, modeflag, resinfo; - - struct SiS_LCDData const *LCDPtr = NULL; - - /* si+Ext_ResInfo */ - modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; - resinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO; - pVBInfo->NewFlickerMode = 0; - pVBInfo->RVBHRS = 50; - - if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) { - XGI_GetRAMDAC2DATA(ModeIdIndex, RefreshRateTableIndex, pVBInfo); - return; - } - - if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) { - LCDPtr = XGI_GetLcdPtr(XGI_LCDDataTable, ModeIdIndex, - pVBInfo); - - pVBInfo->RVBHCMAX = LCDPtr->RVBHCMAX; - pVBInfo->RVBHCFACT = LCDPtr->RVBHCFACT; - pVBInfo->VGAHT = LCDPtr->VGAHT; - pVBInfo->VGAVT = LCDPtr->VGAVT; - pVBInfo->HT = LCDPtr->LCDHT; - pVBInfo->VT = LCDPtr->LCDVT; - - if (pVBInfo->LCDResInfo == Panel_1024x768) { - tempax = 1024; - tempbx = 768; - - if (!(pVBInfo->LCDInfo & XGI_LCDVESATiming)) { - if (pVBInfo->VGAVDE == 357) - tempbx = 527; - else if (pVBInfo->VGAVDE == 420) - tempbx = 620; - else if (pVBInfo->VGAVDE == 525) - tempbx = 775; - else if (pVBInfo->VGAVDE == 600) - tempbx = 775; - } - } else if (pVBInfo->LCDResInfo == Panel_1024x768x75) { - tempax = 1024; - tempbx = 768; - } else if (pVBInfo->LCDResInfo == Panel_1280x1024) { - tempax = 1280; - if (pVBInfo->VGAVDE == 360) - tempbx = 768; - else if (pVBInfo->VGAVDE == 375) - tempbx = 800; - else if (pVBInfo->VGAVDE == 405) - tempbx = 864; - else - tempbx = 1024; - } else if (pVBInfo->LCDResInfo == Panel_1280x1024x75) { - tempax = 1280; - tempbx = 1024; - } else if (pVBInfo->LCDResInfo == Panel_1280x960) { - tempax = 1280; - if (pVBInfo->VGAVDE == 350) - tempbx = 700; - else if (pVBInfo->VGAVDE == 400) - tempbx = 800; - else if (pVBInfo->VGAVDE == 1024) - tempbx = 960; - else - tempbx = 960; - } else if (pVBInfo->LCDResInfo == Panel_1400x1050) { - tempax = 1400; - tempbx = 1050; - - if (pVBInfo->VGAVDE == 1024) { - tempax = 1280; - tempbx = 1024; - } - } else if (pVBInfo->LCDResInfo == Panel_1600x1200) { - tempax = 1600; - tempbx = 1200; /* alan 10/14/2003 */ - if (!(pVBInfo->LCDInfo & XGI_LCDVESATiming)) { - if (pVBInfo->VGAVDE == 350) - tempbx = 875; - else if (pVBInfo->VGAVDE == 400) - tempbx = 1000; - } - } - - if (pVBInfo->LCDInfo & LCDNonExpanding) { - tempax = pVBInfo->VGAHDE; - tempbx = pVBInfo->VGAVDE; - } - - pVBInfo->HDE = tempax; - pVBInfo->VDE = tempbx; - return; - } - - if (pVBInfo->VBInfo & (SetCRT2ToTV)) { - struct SiS_TVData const *TVPtr; - - TVPtr = XGI_GetTVPtr(ModeIdIndex, RefreshRateTableIndex, - pVBInfo); - - pVBInfo->RVBHCMAX = TVPtr->RVBHCMAX; - pVBInfo->RVBHCFACT = TVPtr->RVBHCFACT; - pVBInfo->VGAHT = TVPtr->VGAHT; - pVBInfo->VGAVT = TVPtr->VGAVT; - pVBInfo->HDE = TVPtr->TVHDE; - pVBInfo->VDE = TVPtr->TVVDE; - pVBInfo->RVBHRS = TVPtr->RVBHRS; - pVBInfo->NewFlickerMode = TVPtr->FlickerMode; - - if (pVBInfo->VBInfo & SetCRT2ToHiVision) { - if (resinfo == 0x08) - pVBInfo->NewFlickerMode = 0x40; - else if (resinfo == 0x09) - pVBInfo->NewFlickerMode = 0x40; - else if (resinfo == 0x12) - pVBInfo->NewFlickerMode = 0x40; - - if (pVBInfo->VGAVDE == 350) - pVBInfo->TVInfo |= TVSimuMode; - - tempax = ExtHiTVHT; - tempbx = ExtHiTVVT; - - if (pVBInfo->VBInfo & SetInSlaveMode) { - if (pVBInfo->TVInfo & TVSimuMode) { - tempax = StHiTVHT; - tempbx = StHiTVVT; - - if (!(modeflag & Charx8Dot)) { - tempax = StHiTextTVHT; - tempbx = StHiTextTVVT; - } - } - } - } else if (pVBInfo->VBInfo & SetCRT2ToYPbPr525750) { - if (pVBInfo->TVInfo & TVSetYPbPr750p) { - tempax = YPbPrTV750pHT; /* Ext750pTVHT */ - tempbx = YPbPrTV750pVT; /* Ext750pTVVT */ - } - - if (pVBInfo->TVInfo & TVSetYPbPr525p) { - tempax = YPbPrTV525pHT; /* Ext525pTVHT */ - tempbx = YPbPrTV525pVT; /* Ext525pTVVT */ - } else if (pVBInfo->TVInfo & TVSetYPbPr525i) { - tempax = YPbPrTV525iHT; /* Ext525iTVHT */ - tempbx = YPbPrTV525iVT; /* Ext525iTVVT */ - if (pVBInfo->TVInfo & NTSC1024x768) - tempax = NTSC1024x768HT; - } - } else { - tempax = PALHT; - tempbx = PALVT; - if (!(pVBInfo->TVInfo & TVSetPAL)) { - tempax = NTSCHT; - tempbx = NTSCVT; - if (pVBInfo->TVInfo & NTSC1024x768) - tempax = NTSC1024x768HT; - } - } - - pVBInfo->HT = tempax; - pVBInfo->VT = tempbx; - } -} - -static void XGI_SetCRT2VCLK(unsigned short ModeIdIndex, - unsigned short RefreshRateTableIndex, - struct vb_device_info *pVBInfo) -{ - unsigned char di_0, di_1, tempal; - - tempal = XGI_GetVCLKPtr(RefreshRateTableIndex, ModeIdIndex, pVBInfo); - XGI_GetVCLKLen(tempal, &di_0, &di_1, pVBInfo); - XGI_GetLCDVCLKPtr(&di_0, &di_1, pVBInfo); - - if (pVBInfo->VBType & VB_SIS301) { /* shampoo 0129 */ - /* 301 */ - xgifb_reg_set(pVBInfo->Part4Port, 0x0A, 0x10); - xgifb_reg_set(pVBInfo->Part4Port, 0x0B, di_1); - xgifb_reg_set(pVBInfo->Part4Port, 0x0A, di_0); - } else { /* 301b/302b/301lv/302lv */ - xgifb_reg_set(pVBInfo->Part4Port, 0x0A, di_0); - xgifb_reg_set(pVBInfo->Part4Port, 0x0B, di_1); - } - - xgifb_reg_set(pVBInfo->Part4Port, 0x00, 0x12); - - if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) - xgifb_reg_or(pVBInfo->Part4Port, 0x12, 0x28); - else - xgifb_reg_or(pVBInfo->Part4Port, 0x12, 0x08); -} - -static unsigned short XGI_GetColorDepth(unsigned short ModeIdIndex) -{ - unsigned short ColorDepth[6] = { 1, 2, 4, 4, 6, 8 }; - short index; - unsigned short modeflag; - - modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; - index = (modeflag & ModeTypeMask) - ModeEGA; - - if (index < 0) - index = 0; - - return ColorDepth[index]; -} - -static unsigned short XGI_GetOffset(unsigned short ModeNo, - unsigned short ModeIdIndex, - unsigned short RefreshRateTableIndex) -{ - unsigned short temp, colordepth, modeinfo, index, infoflag, - ColorDepth[] = { 0x01, 0x02, 0x04 }; - - modeinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeInfo; - infoflag = XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag; - - index = (modeinfo >> 8) & 0xFF; - - temp = XGI330_ScreenOffset[index]; - - if (infoflag & InterlaceMode) - temp <<= 1; - - colordepth = XGI_GetColorDepth(ModeIdIndex); - - if ((ModeNo >= 0x7C) && (ModeNo <= 0x7E)) { - temp = ModeNo - 0x7C; - colordepth = ColorDepth[temp]; - temp = 0x6B; - if (infoflag & InterlaceMode) - temp <<= 1; - } - return temp * colordepth; -} - -static void XGI_SetCRT2Offset(unsigned short ModeNo, - unsigned short ModeIdIndex, - unsigned short RefreshRateTableIndex, - struct vb_device_info *pVBInfo) -{ - unsigned short offset; - unsigned char temp; - - if (pVBInfo->VBInfo & SetInSlaveMode) - return; - - offset = XGI_GetOffset(ModeNo, ModeIdIndex, RefreshRateTableIndex); - temp = (unsigned char)(offset & 0xFF); - xgifb_reg_set(pVBInfo->Part1Port, 0x07, temp); - temp = (unsigned char)((offset & 0xFF00) >> 8); - xgifb_reg_set(pVBInfo->Part1Port, 0x09, temp); - temp = (unsigned char)(((offset >> 3) & 0xFF) + 1); - xgifb_reg_set(pVBInfo->Part1Port, 0x03, temp); -} - -static void XGI_SetCRT2FIFO(struct vb_device_info *pVBInfo) -{ - /* threshold high ,disable auto threshold */ - xgifb_reg_set(pVBInfo->Part1Port, 0x01, 0x3B); - /* threshold low default 04h */ - xgifb_reg_and_or(pVBInfo->Part1Port, 0x02, ~(0x3F), 0x04); -} - -static void XGI_PreSetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex, - unsigned short RefreshRateTableIndex, - struct vb_device_info *pVBInfo) -{ - u8 tempcx; - - XGI_SetCRT2Offset(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo); - XGI_SetCRT2FIFO(pVBInfo); - - for (tempcx = 4; tempcx < 7; tempcx++) - xgifb_reg_set(pVBInfo->Part1Port, tempcx, 0x0); - - xgifb_reg_set(pVBInfo->Part1Port, 0x50, 0x00); - xgifb_reg_set(pVBInfo->Part1Port, 0x02, 0x44); /* temp 0206 */ -} - -static void XGI_SetGroup1(unsigned short ModeIdIndex, - unsigned short RefreshRateTableIndex, - struct vb_device_info *pVBInfo) -{ - unsigned short temp = 0, tempax = 0, tempbx = 0, tempcx = 0, - pushbx = 0, CRT1Index, modeflag; - - CRT1Index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; - CRT1Index &= IndexMask; - modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; - - /* bainy change table name */ - if (modeflag & HalfDCLK) { - /* BTVGA2HT 0x08,0x09 */ - temp = (pVBInfo->VGAHT / 2 - 1) & 0x0FF; - xgifb_reg_set(pVBInfo->Part1Port, 0x08, temp); - temp = (((pVBInfo->VGAHT / 2 - 1) & 0xFF00) >> 8) << 4; - xgifb_reg_and_or(pVBInfo->Part1Port, 0x09, ~0x0F0, temp); - /* BTVGA2HDEE 0x0A,0x0C */ - temp = (pVBInfo->VGAHDE / 2 + 16) & 0x0FF; - xgifb_reg_set(pVBInfo->Part1Port, 0x0A, temp); - tempcx = ((pVBInfo->VGAHT - pVBInfo->VGAHDE) / 2) >> 2; - pushbx = pVBInfo->VGAHDE / 2 + 16; - tempcx >>= 1; - tempbx = pushbx + tempcx; /* bx BTVGA@HRS 0x0B,0x0C */ - tempcx += tempbx; - - if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) { - tempbx = XGI_CRT1Table[CRT1Index].CR[4]; - tempbx |= ((XGI_CRT1Table[CRT1Index].CR[14] & - 0xC0) << 2); - tempbx = (tempbx - 3) << 3; /* (VGAHRS-3)*8 */ - tempcx = XGI_CRT1Table[CRT1Index].CR[5]; - tempcx &= 0x1F; - temp = XGI_CRT1Table[CRT1Index].CR[15]; - temp = (temp & 0x04) << (5 - 2); /* VGAHRE D[5] */ - tempcx = ((tempcx | temp) - 3) << 3; /* (VGAHRE-3)*8 */ - } - - tempbx += 4; - tempcx += 4; - - if (tempcx > (pVBInfo->VGAHT / 2)) - tempcx = pVBInfo->VGAHT / 2; - - temp = tempbx & 0x00FF; - - xgifb_reg_set(pVBInfo->Part1Port, 0x0B, temp); - } else { - temp = (pVBInfo->VGAHT - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */ - xgifb_reg_set(pVBInfo->Part1Port, 0x08, temp); - temp = (((pVBInfo->VGAHT - 1) & 0xFF00) >> 8) << 4; - xgifb_reg_and_or(pVBInfo->Part1Port, 0x09, ~0x0F0, temp); - /* BTVGA2HDEE 0x0A,0x0C */ - temp = (pVBInfo->VGAHDE + 16) & 0x0FF; - xgifb_reg_set(pVBInfo->Part1Port, 0x0A, temp); - tempcx = (pVBInfo->VGAHT - pVBInfo->VGAHDE) >> 2; /* cx */ - pushbx = pVBInfo->VGAHDE + 16; - tempcx >>= 1; - tempbx = pushbx + tempcx; /* bx BTVGA@HRS 0x0B,0x0C */ - tempcx += tempbx; - - if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) { - tempbx = XGI_CRT1Table[CRT1Index].CR[3]; - tempbx |= ((XGI_CRT1Table[CRT1Index].CR[5] & - 0xC0) << 2); - tempbx = (tempbx - 3) << 3; /* (VGAHRS-3)*8 */ - tempcx = XGI_CRT1Table[CRT1Index].CR[4]; - tempcx &= 0x1F; - temp = XGI_CRT1Table[CRT1Index].CR[6]; - temp = (temp & 0x04) << (5 - 2); /* VGAHRE D[5] */ - tempcx = ((tempcx | temp) - 3) << 3; /* (VGAHRE-3)*8 */ - tempbx += 16; - tempcx += 16; - } - - if (tempcx > pVBInfo->VGAHT) - tempcx = pVBInfo->VGAHT; - - temp = tempbx & 0x00FF; - xgifb_reg_set(pVBInfo->Part1Port, 0x0B, temp); - } - - tempax = (tempax & 0x00FF) | (tempbx & 0xFF00); - tempbx = pushbx; - tempbx = (tempbx & 0x00FF) | ((tempbx & 0xFF00) << 4); - tempax |= (tempbx & 0xFF00); - temp = (tempax & 0xFF00) >> 8; - xgifb_reg_set(pVBInfo->Part1Port, 0x0C, temp); - temp = tempcx & 0x00FF; - xgifb_reg_set(pVBInfo->Part1Port, 0x0D, temp); - tempcx = pVBInfo->VGAVT - 1; - temp = tempcx & 0x00FF; - - xgifb_reg_set(pVBInfo->Part1Port, 0x0E, temp); - tempbx = pVBInfo->VGAVDE - 1; - temp = tempbx & 0x00FF; - xgifb_reg_set(pVBInfo->Part1Port, 0x0F, temp); - temp = ((tempbx & 0xFF00) << 3) >> 8; - temp |= ((tempcx & 0xFF00) >> 8); - xgifb_reg_set(pVBInfo->Part1Port, 0x12, temp); - - /* BTVGA2VRS 0x10,0x11 */ - tempbx = (pVBInfo->VGAVT + pVBInfo->VGAVDE) >> 1; - /* BTVGA2VRE 0x11 */ - tempcx = ((pVBInfo->VGAVT - pVBInfo->VGAVDE) >> 4) + tempbx + 1; - - if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) { - tempbx = XGI_CRT1Table[CRT1Index].CR[10]; - temp = XGI_CRT1Table[CRT1Index].CR[9]; - - if (temp & 0x04) - tempbx |= 0x0100; - - if (temp & 0x080) - tempbx |= 0x0200; - - temp = XGI_CRT1Table[CRT1Index].CR[14]; - - if (temp & 0x08) - tempbx |= 0x0400; - - temp = XGI_CRT1Table[CRT1Index].CR[11]; - tempcx = (tempcx & 0xFF00) | (temp & 0x00FF); - } - - temp = tempbx & 0x00FF; - xgifb_reg_set(pVBInfo->Part1Port, 0x10, temp); - temp = ((tempbx & 0xFF00) >> 8) << 4; - temp = (tempcx & 0x000F) | (temp); - xgifb_reg_set(pVBInfo->Part1Port, 0x11, temp); - tempax = 0; - - if (modeflag & DoubleScanMode) - tempax |= 0x80; - - if (modeflag & HalfDCLK) - tempax |= 0x40; - - xgifb_reg_and_or(pVBInfo->Part1Port, 0x2C, ~0x0C0, tempax); -} - -static unsigned short XGI_GetVGAHT2(struct vb_device_info *pVBInfo) -{ - unsigned long tempax, tempbx; - - tempbx = ((pVBInfo->VGAVT - pVBInfo->VGAVDE) * pVBInfo->RVBHCMAX) - & 0xFFFF; - tempax = (pVBInfo->VT - pVBInfo->VDE) * pVBInfo->RVBHCFACT; - tempax = (tempax * pVBInfo->HT) / tempbx; - - return (unsigned short)tempax; -} - -static void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex, - struct vb_device_info *pVBInfo) -{ - unsigned short push1, push2, tempax, tempbx = 0, tempcx, temp, resinfo, - modeflag; - - /* si+Ext_ResInfo */ - modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; - resinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO; - - if (!(pVBInfo->VBInfo & SetInSlaveMode)) - return; - - temp = 0xFF; /* set MAX HT */ - xgifb_reg_set(pVBInfo->Part1Port, 0x03, temp); - tempcx = 0x08; - - if (pVBInfo->VBType & (VB_SIS301LV | VB_SIS302LV | VB_XGI301C)) - modeflag |= Charx8Dot; - - tempax = pVBInfo->VGAHDE; /* 0x04 Horizontal Display End */ - - if (modeflag & HalfDCLK) - tempax >>= 1; - - tempax = (tempax / tempcx) - 1; - tempbx |= ((tempax & 0x00FF) << 8); - temp = tempax & 0x00FF; - xgifb_reg_set(pVBInfo->Part1Port, 0x04, temp); - - temp = (tempbx & 0xFF00) >> 8; - - if (pVBInfo->VBInfo & SetCRT2ToTV) { - if (!(pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV - | VB_SIS302LV | VB_XGI301C))) - temp += 2; - - if ((pVBInfo->VBInfo & SetCRT2ToHiVision) && - !(pVBInfo->VBType & VB_SIS301LV) && (resinfo == 7)) - temp -= 2; - } - - /* 0x05 Horizontal Display Start */ - xgifb_reg_set(pVBInfo->Part1Port, 0x05, temp); - /* 0x06 Horizontal Blank end */ - xgifb_reg_set(pVBInfo->Part1Port, 0x06, 0x03); - - if (!(pVBInfo->VBInfo & DisableCRT2Display)) { /* 030226 bainy */ - if (pVBInfo->VBInfo & SetCRT2ToTV) - tempax = pVBInfo->VGAHT; - else - tempax = XGI_GetVGAHT2(pVBInfo); - } - - if (tempax >= pVBInfo->VGAHT) - tempax = pVBInfo->VGAHT; - - if (modeflag & HalfDCLK) - tempax >>= 1; - - tempax = (tempax / tempcx) - 5; - tempcx = tempax; /* 20030401 0x07 horizontal Retrace Start */ - if (pVBInfo->VBInfo & SetCRT2ToHiVision) { - temp = (tempbx & 0x00FF) - 1; - if (!(modeflag & HalfDCLK)) { - temp -= 6; - if (pVBInfo->TVInfo & TVSimuMode) { - temp -= 4; - temp -= 10; - } - } - } else { - tempbx = (tempbx & 0xFF00) >> 8; - tempcx = (tempcx + tempbx) >> 1; - temp = (tempcx & 0x00FF) + 2; - - if (pVBInfo->VBInfo & SetCRT2ToTV) { - temp -= 1; - if (!(modeflag & HalfDCLK)) { - if ((modeflag & Charx8Dot)) { - temp += 4; - if (pVBInfo->VGAHDE >= 800) - temp -= 6; - } - } - } else if (!(modeflag & HalfDCLK)) { - temp -= 4; - if (pVBInfo->LCDResInfo != Panel_1280x960 && - pVBInfo->VGAHDE >= 800) { - temp -= 7; - if (pVBInfo->VGAHDE >= 1280 && - pVBInfo->LCDResInfo != Panel_1280x960 && - (pVBInfo->LCDInfo & LCDNonExpanding)) - temp += 28; - } - } - } - - /* 0x07 Horizontal Retrace Start */ - xgifb_reg_set(pVBInfo->Part1Port, 0x07, temp); - /* 0x08 Horizontal Retrace End */ - xgifb_reg_set(pVBInfo->Part1Port, 0x08, 0); - - if (pVBInfo->VBInfo & SetCRT2ToTV) { - if (pVBInfo->TVInfo & TVSimuMode) { - if (ModeNo == 0x50) { - if (pVBInfo->TVInfo == SetNTSCTV) { - xgifb_reg_set(pVBInfo->Part1Port, - 0x07, 0x30); - xgifb_reg_set(pVBInfo->Part1Port, - 0x08, 0x03); - } else { - xgifb_reg_set(pVBInfo->Part1Port, - 0x07, 0x2f); - xgifb_reg_set(pVBInfo->Part1Port, - 0x08, 0x02); - } - } - } - } - - xgifb_reg_set(pVBInfo->Part1Port, 0x18, 0x03); /* 0x18 SR0B */ - xgifb_reg_and_or(pVBInfo->Part1Port, 0x19, 0xF0, 0x00); - xgifb_reg_set(pVBInfo->Part1Port, 0x09, 0xFF); /* 0x09 Set Max VT */ - - tempbx = pVBInfo->VGAVT; - push1 = tempbx; - tempcx = 0x121; - tempbx = pVBInfo->VGAVDE; /* 0x0E Vertical Display End */ - - if (tempbx == 357) - tempbx = 350; - if (tempbx == 360) - tempbx = 350; - if (tempbx == 375) - tempbx = 350; - if (tempbx == 405) - tempbx = 400; - if (tempbx == 525) - tempbx = 480; - - push2 = tempbx; - - if (pVBInfo->VBInfo & SetCRT2ToLCD) { - if (pVBInfo->LCDResInfo == Panel_1024x768) { - if (!(pVBInfo->LCDInfo & XGI_LCDVESATiming)) { - if (tempbx == 350) - tempbx += 5; - if (tempbx == 480) - tempbx += 5; - } - } - } - tempbx--; - tempbx--; - temp = tempbx & 0x00FF; - /* 0x10 vertical Blank Start */ - xgifb_reg_set(pVBInfo->Part1Port, 0x10, temp); - tempbx = push2; - tempbx--; - temp = tempbx & 0x00FF; - xgifb_reg_set(pVBInfo->Part1Port, 0x0E, temp); - - if (tempbx & 0x0100) - tempcx |= 0x0002; - - tempax = 0x000B; - - if (modeflag & DoubleScanMode) - tempax |= 0x08000; - - if (tempbx & 0x0200) - tempcx |= 0x0040; - - temp = (tempax & 0xFF00) >> 8; - xgifb_reg_set(pVBInfo->Part1Port, 0x0B, temp); - - if (tempbx & 0x0400) - tempcx |= 0x0600; - - /* 0x11 Vertical Blank End */ - xgifb_reg_set(pVBInfo->Part1Port, 0x11, 0x00); - - tempax = push1; - tempax -= tempbx; /* 0x0C Vertical Retrace Start */ - tempax >>= 2; - push1 = tempax; /* push ax */ - - if (resinfo != 0x09) { - tempax <<= 1; - tempbx += tempax; - } - - if (pVBInfo->VBInfo & SetCRT2ToHiVision) { - if ((pVBInfo->VBType & VB_SIS301LV) && - !(pVBInfo->TVInfo & TVSetHiVision)) { - if ((pVBInfo->TVInfo & TVSimuMode) && - (pVBInfo->TVInfo & TVSetPAL)) { - if (!(pVBInfo->VBType & VB_SIS301LV) || - !(pVBInfo->TVInfo & - (TVSetYPbPr525p | - TVSetYPbPr750p | - TVSetHiVision))) - tempbx += 40; - } - } else { - tempbx -= 10; - } - } else if (pVBInfo->TVInfo & TVSimuMode) { - if (pVBInfo->TVInfo & TVSetPAL) { - if (pVBInfo->VBType & VB_SIS301LV) { - if (!(pVBInfo->TVInfo & - (TVSetYPbPr525p | - TVSetYPbPr750p | - TVSetHiVision))) - tempbx += 40; - } else { - tempbx += 40; - } - } - } - tempax = push1; - tempax >>= 2; - tempax++; - tempax += tempbx; - push1 = tempax; /* push ax */ - - if ((pVBInfo->TVInfo & TVSetPAL)) { - if (tempbx <= 513) { - if (tempax >= 513) - tempbx = 513; - } - } - - temp = tempbx & 0x00FF; - xgifb_reg_set(pVBInfo->Part1Port, 0x0C, temp); - tempbx--; - temp = tempbx & 0x00FF; - xgifb_reg_set(pVBInfo->Part1Port, 0x10, temp); - - if (tempbx & 0x0100) - tempcx |= 0x0008; - - if (tempbx & 0x0200) - xgifb_reg_and_or(pVBInfo->Part1Port, 0x0B, 0x0FF, 0x20); - - tempbx++; - - if (tempbx & 0x0100) - tempcx |= 0x0004; - - if (tempbx & 0x0200) - tempcx |= 0x0080; - - if (tempbx & 0x0400) - tempcx |= 0x0C00; - - tempbx = push1; /* pop ax */ - temp = tempbx & 0x00FF; - temp &= 0x0F; - /* 0x0D vertical Retrace End */ - xgifb_reg_set(pVBInfo->Part1Port, 0x0D, temp); - - if (tempbx & 0x0010) - tempcx |= 0x2000; - - temp = tempcx & 0x00FF; - xgifb_reg_set(pVBInfo->Part1Port, 0x0A, temp); /* 0x0A CR07 */ - temp = (tempcx & 0x0FF00) >> 8; - xgifb_reg_set(pVBInfo->Part1Port, 0x17, temp); /* 0x17 SR0A */ - tempax = modeflag; - temp = (tempax & 0xFF00) >> 8; - - temp = (temp >> 1) & 0x09; - - if (pVBInfo->VBType & (VB_SIS301LV | VB_SIS302LV | VB_XGI301C)) - temp |= 0x01; - - xgifb_reg_set(pVBInfo->Part1Port, 0x16, temp); /* 0x16 SR01 */ - xgifb_reg_set(pVBInfo->Part1Port, 0x0F, 0); /* 0x0F CR14 */ - xgifb_reg_set(pVBInfo->Part1Port, 0x12, 0); /* 0x12 CR17 */ - - if (pVBInfo->LCDInfo & LCDRGB18Bit) - temp = 0x80; - else - temp = 0x00; - - xgifb_reg_set(pVBInfo->Part1Port, 0x1A, temp); /* 0x1A SR0E */ -} - -static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, - struct vb_device_info *pVBInfo) -{ - unsigned short i, j, tempax, tempbx, tempcx, temp, push1, push2, - modeflag; - unsigned char const *TimingPoint; - - unsigned long longtemp, tempeax, tempebx, temp2, tempecx; - - /* si+Ext_ResInfo */ - modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; - - tempax = 0; - - if (!(pVBInfo->VBInfo & SetCRT2ToAVIDEO)) - tempax |= 0x0800; - - if (!(pVBInfo->VBInfo & SetCRT2ToSVIDEO)) - tempax |= 0x0400; - - if (pVBInfo->VBInfo & SetCRT2ToSCART) - tempax |= 0x0200; - - if (!(pVBInfo->TVInfo & TVSetPAL)) - tempax |= 0x1000; - - if (pVBInfo->VBInfo & SetCRT2ToHiVision) - tempax |= 0x0100; - - if (pVBInfo->TVInfo & (TVSetYPbPr525p | TVSetYPbPr750p)) - tempax &= 0xfe00; - - tempax = (tempax & 0xff00) >> 8; - - xgifb_reg_set(pVBInfo->Part2Port, 0x0, tempax); - TimingPoint = XGI330_NTSCTiming; - - if (pVBInfo->TVInfo & TVSetPAL) - TimingPoint = XGI330_PALTiming; - - if (pVBInfo->VBInfo & SetCRT2ToHiVision) { - TimingPoint = XGI330_HiTVExtTiming; - - if (pVBInfo->VBInfo & SetInSlaveMode) - TimingPoint = XGI330_HiTVSt2Timing; - - if (pVBInfo->SetFlag & TVSimuMode) - TimingPoint = XGI330_HiTVSt1Timing; - - if (!(modeflag & Charx8Dot)) - TimingPoint = XGI330_HiTVTextTiming; - } - - if (pVBInfo->VBInfo & SetCRT2ToYPbPr525750) { - if (pVBInfo->TVInfo & TVSetYPbPr525i) - TimingPoint = XGI330_YPbPr525iTiming; - - if (pVBInfo->TVInfo & TVSetYPbPr525p) - TimingPoint = XGI330_YPbPr525pTiming; - - if (pVBInfo->TVInfo & TVSetYPbPr750p) - TimingPoint = XGI330_YPbPr750pTiming; - } - - for (i = 0x01, j = 0; i <= 0x2D; i++, j++) - xgifb_reg_set(pVBInfo->Part2Port, i, TimingPoint[j]); - - for (i = 0x39; i <= 0x45; i++, j++) - /* di->temp2[j] */ - xgifb_reg_set(pVBInfo->Part2Port, i, TimingPoint[j]); - - if (pVBInfo->VBInfo & SetCRT2ToTV) - xgifb_reg_and_or(pVBInfo->Part2Port, 0x3A, 0x1F, 0x00); - - temp = pVBInfo->NewFlickerMode; - temp &= 0x80; - xgifb_reg_and_or(pVBInfo->Part2Port, 0x0A, 0xFF, temp); - - if (pVBInfo->TVInfo & TVSetPAL) - tempax = 520; - else - tempax = 440; - - if (pVBInfo->VDE <= tempax) { - tempax -= pVBInfo->VDE; - tempax >>= 2; - tempax = (tempax & 0x00FF) | ((tempax & 0x00FF) << 8); - push1 = tempax; - temp = (tempax & 0xFF00) >> 8; - temp += (unsigned short)TimingPoint[0]; - - if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV - | VB_SIS302LV | VB_XGI301C)) { - if (pVBInfo->VBInfo & (SetCRT2ToAVIDEO - | SetCRT2ToSVIDEO | SetCRT2ToSCART - | SetCRT2ToYPbPr525750)) { - tempcx = pVBInfo->VGAHDE; - if (tempcx >= 1024) { - temp = 0x17; /* NTSC */ - if (pVBInfo->TVInfo & TVSetPAL) - temp = 0x19; /* PAL */ - } - } - } - - xgifb_reg_set(pVBInfo->Part2Port, 0x01, temp); - tempax = push1; - temp = (tempax & 0xFF00) >> 8; - temp += TimingPoint[1]; - - if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV - | VB_SIS302LV | VB_XGI301C)) { - if ((pVBInfo->VBInfo & (SetCRT2ToAVIDEO - | SetCRT2ToSVIDEO | SetCRT2ToSCART - | SetCRT2ToYPbPr525750))) { - tempcx = pVBInfo->VGAHDE; - if (tempcx >= 1024) { - temp = 0x1D; /* NTSC */ - if (pVBInfo->TVInfo & TVSetPAL) - temp = 0x52; /* PAL */ - } - } - } - xgifb_reg_set(pVBInfo->Part2Port, 0x02, temp); - } - - /* 301b */ - tempcx = pVBInfo->HT; - - if (XGI_IsLCDDualLink(pVBInfo)) - tempcx >>= 1; - - tempcx -= 2; - temp = tempcx & 0x00FF; - xgifb_reg_set(pVBInfo->Part2Port, 0x1B, temp); - - temp = (tempcx & 0xFF00) >> 8; - xgifb_reg_and_or(pVBInfo->Part2Port, 0x1D, ~0x0F, temp); - - tempcx = pVBInfo->HT >> 1; - push1 = tempcx; /* push cx */ - tempcx += 7; - - if (pVBInfo->VBInfo & SetCRT2ToHiVision) - tempcx -= 4; - - temp = tempcx & 0x00FF; - temp <<= 4; - xgifb_reg_and_or(pVBInfo->Part2Port, 0x22, 0x0F, temp); - - tempbx = TimingPoint[j] | ((TimingPoint[j + 1]) << 8); - tempbx += tempcx; - push2 = tempbx; - temp = tempbx & 0x00FF; - xgifb_reg_set(pVBInfo->Part2Port, 0x24, temp); - temp = (tempbx & 0xFF00) >> 8; - temp <<= 4; - xgifb_reg_and_or(pVBInfo->Part2Port, 0x25, 0x0F, temp); - - tempbx = push2; - tempbx = tempbx + 8; - if (pVBInfo->VBInfo & SetCRT2ToHiVision) { - tempbx = tempbx - 4; - tempcx = tempbx; - } - - temp = (tempbx & 0x00FF) << 4; - xgifb_reg_and_or(pVBInfo->Part2Port, 0x29, 0x0F, temp); - - j += 2; - tempcx += (TimingPoint[j] | ((TimingPoint[j + 1]) << 8)); - temp = tempcx & 0x00FF; - xgifb_reg_set(pVBInfo->Part2Port, 0x27, temp); - temp = ((tempcx & 0xFF00) >> 8) << 4; - xgifb_reg_and_or(pVBInfo->Part2Port, 0x28, 0x0F, temp); - - tempcx += 8; - if (pVBInfo->VBInfo & SetCRT2ToHiVision) - tempcx -= 4; - - temp = tempcx & 0xFF; - temp <<= 4; - xgifb_reg_and_or(pVBInfo->Part2Port, 0x2A, 0x0F, temp); - - tempcx = push1; /* pop cx */ - j += 2; - temp = TimingPoint[j] | ((TimingPoint[j + 1]) << 8); - tempcx -= temp; - temp = tempcx & 0x00FF; - temp <<= 4; - xgifb_reg_and_or(pVBInfo->Part2Port, 0x2D, 0x0F, temp); - - tempcx -= 11; - - if (!(pVBInfo->VBInfo & SetCRT2ToTV)) { - tempax = XGI_GetVGAHT2(pVBInfo); - tempcx = tempax - 1; - } - temp = tempcx & 0x00FF; - xgifb_reg_set(pVBInfo->Part2Port, 0x2E, temp); - - tempbx = pVBInfo->VDE; - - if (pVBInfo->VGAVDE == 360) - tempbx = 746; - if (pVBInfo->VGAVDE == 375) - tempbx = 746; - if (pVBInfo->VGAVDE == 405) - tempbx = 853; - - if (pVBInfo->VBInfo & SetCRT2ToTV) { - if (pVBInfo->VBType & - (VB_SIS301LV | VB_SIS302LV | VB_XGI301C)) { - if (!(pVBInfo->TVInfo & - (TVSetYPbPr525p | TVSetYPbPr750p))) - tempbx >>= 1; - } else { - tempbx >>= 1; - } - } - - tempbx -= 2; - temp = tempbx & 0x00FF; - - if (pVBInfo->VBInfo & SetCRT2ToHiVision) { - if (pVBInfo->VBType & VB_SIS301LV) { - if (pVBInfo->TVInfo & TVSetHiVision) { - if (pVBInfo->VBInfo & SetInSlaveMode) { - if (ModeNo == 0x2f) - temp += 1; - } - } - } else if (pVBInfo->VBInfo & SetInSlaveMode) { - if (ModeNo == 0x2f) - temp += 1; - } - } - - xgifb_reg_set(pVBInfo->Part2Port, 0x2F, temp); - - temp = (tempcx & 0xFF00) >> 8; - temp |= ((tempbx & 0xFF00) >> 8) << 6; - - if (!(pVBInfo->VBInfo & SetCRT2ToHiVision)) { - if (pVBInfo->VBType & VB_SIS301LV) { - if (pVBInfo->TVInfo & TVSetHiVision) { - temp |= 0x10; - - if (!(pVBInfo->VBInfo & SetCRT2ToSVIDEO)) - temp |= 0x20; - } - } else { - temp |= 0x10; - if (!(pVBInfo->VBInfo & SetCRT2ToSVIDEO)) - temp |= 0x20; - } - } - - xgifb_reg_set(pVBInfo->Part2Port, 0x30, temp); - - if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV - | VB_SIS302LV | VB_XGI301C)) { /* TV gatingno */ - tempbx = pVBInfo->VDE; - tempcx = tempbx - 2; - - if (pVBInfo->VBInfo & SetCRT2ToTV) { - if (!(pVBInfo->TVInfo & (TVSetYPbPr525p - | TVSetYPbPr750p))) - tempbx >>= 1; - } - - if (pVBInfo->VBType & (VB_SIS302LV | VB_XGI301C)) { - temp = 0; - if (tempcx & 0x0400) - temp |= 0x20; - - if (tempbx & 0x0400) - temp |= 0x40; - - xgifb_reg_set(pVBInfo->Part4Port, 0x10, temp); - } - - temp = (((tempbx - 3) & 0x0300) >> 8) << 5; - xgifb_reg_set(pVBInfo->Part2Port, 0x46, temp); - temp = (tempbx - 3) & 0x00FF; - xgifb_reg_set(pVBInfo->Part2Port, 0x47, temp); - } - - tempbx = tempbx & 0x00FF; - - if (!(modeflag & HalfDCLK)) { - tempcx = pVBInfo->VGAHDE; - if (tempcx >= pVBInfo->HDE) { - tempbx |= 0x2000; - tempax &= 0x00FF; - } - } - - tempcx = 0x0101; - - if (pVBInfo->VBInfo & SetCRT2ToTV) { /* 301b */ - if (pVBInfo->VGAHDE >= 1024) { - tempcx = 0x1920; - if (pVBInfo->VGAHDE >= 1280) { - tempcx = 0x1420; - tempbx = tempbx & 0xDFFF; - } - } - } - - if (!(tempbx & 0x2000)) { - if (modeflag & HalfDCLK) - tempcx = (tempcx & 0xFF00) | ((tempcx & 0x00FF) << 1); - - push1 = tempbx; - tempeax = pVBInfo->VGAHDE; - tempebx = (tempcx & 0xFF00) >> 8; - longtemp = tempeax * tempebx; - tempecx = tempcx & 0x00FF; - longtemp = longtemp / tempecx; - - /* 301b */ - tempecx = 8 * 1024; - - if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV - | VB_SIS302LV | VB_XGI301C)) { - tempecx = tempecx * 8; - } - - longtemp = longtemp * tempecx; - tempecx = pVBInfo->HDE; - temp2 = longtemp % tempecx; - tempeax = longtemp / tempecx; - if (temp2 != 0) - tempeax += 1; - - tempax = (unsigned short)tempeax; - - /* 301b */ - if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV - | VB_SIS302LV | VB_XGI301C)) { - tempcx = ((tempax & 0xFF00) >> 5) >> 8; - } - /* end 301b */ - - tempbx = push1; - tempbx = (unsigned short)(((tempeax & 0x0000FF00) & 0x1F00) - | (tempbx & 0x00FF)); - tempax = (unsigned short)(((tempeax & 0x000000FF) << 8) - | (tempax & 0x00FF)); - temp = (tempax & 0xFF00) >> 8; - } else { - temp = (tempax & 0x00FF) >> 8; - } - - xgifb_reg_set(pVBInfo->Part2Port, 0x44, temp); - temp = (tempbx & 0xFF00) >> 8; - xgifb_reg_and_or(pVBInfo->Part2Port, 0x45, ~0x03F, temp); - temp = tempcx & 0x00FF; - - if (tempbx & 0x2000) - temp = 0; - - if (!(pVBInfo->VBInfo & SetCRT2ToLCD)) - temp |= 0x18; - - xgifb_reg_and_or(pVBInfo->Part2Port, 0x46, ~0x1F, temp); - if (pVBInfo->TVInfo & TVSetPAL) { - tempbx = 0x0382; - tempcx = 0x007e; - } else { - tempbx = 0x0369; - tempcx = 0x0061; - } - - temp = tempbx & 0x00FF; - xgifb_reg_set(pVBInfo->Part2Port, 0x4b, temp); - temp = tempcx & 0x00FF; - xgifb_reg_set(pVBInfo->Part2Port, 0x4c, temp); - - temp = ((tempcx & 0xFF00) >> 8) & 0x03; - temp <<= 2; - temp |= ((tempbx & 0xFF00) >> 8) & 0x03; - - if (pVBInfo->VBInfo & SetCRT2ToYPbPr525750) { - temp |= 0x10; - - if (pVBInfo->TVInfo & TVSetYPbPr525p) - temp |= 0x20; - - if (pVBInfo->TVInfo & TVSetYPbPr750p) - temp |= 0x60; - } - - xgifb_reg_set(pVBInfo->Part2Port, 0x4d, temp); - temp = xgifb_reg_get(pVBInfo->Part2Port, 0x43); /* 301b change */ - xgifb_reg_set(pVBInfo->Part2Port, 0x43, (unsigned short)(temp - 3)); - - if (!(pVBInfo->TVInfo & (TVSetYPbPr525p | TVSetYPbPr750p))) { - if (pVBInfo->TVInfo & NTSC1024x768) { - TimingPoint = XGI_NTSC1024AdjTime; - for (i = 0x1c, j = 0; i <= 0x30; i++, j++) { - xgifb_reg_set(pVBInfo->Part2Port, i, - TimingPoint[j]); - } - xgifb_reg_set(pVBInfo->Part2Port, 0x43, 0x72); - } - } - - /* Modify for 301C PALM Support */ - if (pVBInfo->VBType & VB_XGI301C) { - if (pVBInfo->TVInfo & TVSetPALM) - xgifb_reg_and_or(pVBInfo->Part2Port, 0x4E, ~0x08, - 0x08); /* PALM Mode */ - } - - if (pVBInfo->TVInfo & TVSetPALM) { - tempax = xgifb_reg_get(pVBInfo->Part2Port, 0x01); - tempax--; - xgifb_reg_and(pVBInfo->Part2Port, 0x01, tempax); - - xgifb_reg_and(pVBInfo->Part2Port, 0x00, 0xEF); - } - - if (pVBInfo->VBInfo & SetCRT2ToHiVision) { - if (!(pVBInfo->VBInfo & SetInSlaveMode)) - xgifb_reg_set(pVBInfo->Part2Port, 0x0B, 0x00); - } -} - -static void XGI_SetLCDRegs(unsigned short ModeIdIndex, - struct vb_device_info *pVBInfo) -{ - unsigned short pushbx, tempax, tempbx, tempcx, temp, tempah, - tempbh, tempch; - - struct XGI_LCDDesStruct const *LCDBDesPtr = NULL; - - /* si+Ext_ResInfo */ - if (!(pVBInfo->VBInfo & SetCRT2ToLCD)) - return; - - tempbx = pVBInfo->HDE; /* RHACTE=HDE-1 */ - - if (XGI_IsLCDDualLink(pVBInfo)) - tempbx >>= 1; - - tempbx -= 1; - temp = tempbx & 0x00FF; - xgifb_reg_set(pVBInfo->Part2Port, 0x2C, temp); - temp = (tempbx & 0xFF00) >> 8; - temp <<= 4; - xgifb_reg_and_or(pVBInfo->Part2Port, 0x2B, 0x0F, temp); - temp = 0x01; - - xgifb_reg_set(pVBInfo->Part2Port, 0x0B, temp); - tempbx = pVBInfo->VDE; /* RTVACTEO=(VDE-1)&0xFF */ - tempbx--; - temp = tempbx & 0x00FF; - xgifb_reg_set(pVBInfo->Part2Port, 0x03, temp); - temp = ((tempbx & 0xFF00) >> 8) & 0x07; - xgifb_reg_and_or(pVBInfo->Part2Port, 0x0C, ~0x07, temp); - - tempcx = pVBInfo->VT - 1; - temp = tempcx & 0x00FF; /* RVTVT=VT-1 */ - xgifb_reg_set(pVBInfo->Part2Port, 0x19, temp); - temp = (tempcx & 0xFF00) >> 8; - temp <<= 5; - xgifb_reg_set(pVBInfo->Part2Port, 0x1A, temp); - xgifb_reg_and_or(pVBInfo->Part2Port, 0x09, 0xF0, 0x00); - xgifb_reg_and_or(pVBInfo->Part2Port, 0x0A, 0xF0, 0x00); - xgifb_reg_and_or(pVBInfo->Part2Port, 0x17, 0xFB, 0x00); - xgifb_reg_and_or(pVBInfo->Part2Port, 0x18, 0xDF, 0x00); - - /* Customized LCDB Does not add */ - if ((pVBInfo->VBType & VB_SIS301LV) || (pVBInfo->VBType & VB_SIS302LV)) - LCDBDesPtr = XGI_GetLcdPtr(xgifb_lcddldes, ModeIdIndex, - pVBInfo); - else - LCDBDesPtr = XGI_GetLcdPtr(XGI_LCDDesDataTable, ModeIdIndex, - pVBInfo); - - tempah = pVBInfo->LCDResInfo; - tempah &= PanelResInfo; - - if ((tempah == Panel_1024x768) || (tempah == Panel_1024x768x75)) { - tempbx = 1024; - tempcx = 768; - } else if ((tempah == Panel_1280x1024) || - (tempah == Panel_1280x1024x75)) { - tempbx = 1280; - tempcx = 1024; - } else if (tempah == Panel_1400x1050) { - tempbx = 1400; - tempcx = 1050; - } else { - tempbx = 1600; - tempcx = 1200; - } - - if (pVBInfo->LCDInfo & EnableScalingLCD) { - tempbx = pVBInfo->HDE; - tempcx = pVBInfo->VDE; - } - - pushbx = tempbx; - tempax = pVBInfo->VT; - pVBInfo->LCDHDES = LCDBDesPtr->LCDHDES; - pVBInfo->LCDHRS = LCDBDesPtr->LCDHRS; - pVBInfo->LCDVDES = LCDBDesPtr->LCDVDES; - pVBInfo->LCDVRS = LCDBDesPtr->LCDVRS; - tempbx = pVBInfo->LCDVDES; - tempcx += tempbx; - - if (tempcx >= tempax) - tempcx -= tempax; /* lcdvdes */ - - temp = tempbx & 0x00FF; /* RVEQ1EQ=lcdvdes */ - xgifb_reg_set(pVBInfo->Part2Port, 0x05, temp); - temp = tempcx & 0x00FF; - xgifb_reg_set(pVBInfo->Part2Port, 0x06, temp); - tempch = ((tempcx & 0xFF00) >> 8) & 0x07; - tempbh = ((tempbx & 0xFF00) >> 8) & 0x07; - tempah = tempch; - tempah <<= 3; - tempah |= tempbh; - xgifb_reg_set(pVBInfo->Part2Port, 0x02, tempah); - - /* getlcdsync() */ - XGI_GetLCDSync(&tempax, &tempbx, pVBInfo); - tempcx = tempbx; - tempax = pVBInfo->VT; - tempbx = pVBInfo->LCDVRS; - - tempcx += tempbx; - if (tempcx >= tempax) - tempcx -= tempax; - - temp = tempbx & 0x00FF; /* RTVACTEE=lcdvrs */ - xgifb_reg_set(pVBInfo->Part2Port, 0x04, temp); - temp = (tempbx & 0xFF00) >> 8; - temp <<= 4; - temp |= (tempcx & 0x000F); - xgifb_reg_set(pVBInfo->Part2Port, 0x01, temp); - tempcx = pushbx; - tempax = pVBInfo->HT; - tempbx = pVBInfo->LCDHDES; - tempbx &= 0x0FFF; - - if (XGI_IsLCDDualLink(pVBInfo)) { - tempax >>= 1; - tempbx >>= 1; - tempcx >>= 1; - } - - if (pVBInfo->VBType & VB_SIS302LV) - tempbx += 1; - - if (pVBInfo->VBType & VB_XGI301C) /* tap4 */ - tempbx += 1; - - tempcx += tempbx; - - if (tempcx >= tempax) - tempcx -= tempax; - - temp = tempbx & 0x00FF; - xgifb_reg_set(pVBInfo->Part2Port, 0x1F, temp); /* RHBLKE=lcdhdes */ - temp = ((tempbx & 0xFF00) >> 8) << 4; - xgifb_reg_set(pVBInfo->Part2Port, 0x20, temp); - temp = tempcx & 0x00FF; - xgifb_reg_set(pVBInfo->Part2Port, 0x23, temp); /* RHEQPLE=lcdhdee */ - temp = (tempcx & 0xFF00) >> 8; - xgifb_reg_set(pVBInfo->Part2Port, 0x25, temp); - - XGI_GetLCDSync(&tempax, &tempbx, pVBInfo); - tempcx = tempax; - tempax = pVBInfo->HT; - tempbx = pVBInfo->LCDHRS; - if (XGI_IsLCDDualLink(pVBInfo)) { - tempax >>= 1; - tempbx >>= 1; - tempcx >>= 1; - } - - if (pVBInfo->VBType & VB_SIS302LV) - tempbx += 1; - - tempcx += tempbx; - - if (tempcx >= tempax) - tempcx -= tempax; - - temp = tempbx & 0x00FF; /* RHBURSTS=lcdhrs */ - xgifb_reg_set(pVBInfo->Part2Port, 0x1C, temp); - - temp = (tempbx & 0xFF00) >> 8; - temp <<= 4; - xgifb_reg_and_or(pVBInfo->Part2Port, 0x1D, ~0x0F0, temp); - temp = tempcx & 0x00FF; /* RHSYEXP2S=lcdhre */ - xgifb_reg_set(pVBInfo->Part2Port, 0x21, temp); - - if (!(pVBInfo->LCDInfo & XGI_LCDVESATiming)) { - if (pVBInfo->VGAVDE == 525) { - if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B - | VB_SIS301LV | VB_SIS302LV - | VB_XGI301C)) - temp = 0xC6; - else - temp = 0xC4; - - xgifb_reg_set(pVBInfo->Part2Port, 0x2f, temp); - xgifb_reg_set(pVBInfo->Part2Port, 0x30, 0xB3); - } - - if (pVBInfo->VGAVDE == 420) { - if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B - | VB_SIS301LV | VB_SIS302LV - | VB_XGI301C)) - temp = 0x4F; - else - temp = 0x4E; - xgifb_reg_set(pVBInfo->Part2Port, 0x2f, temp); - } - } -} - -/* - * Function : XGI_GetTap4Ptr - * Input : - * Output : di -> Tap4 Reg. Setting Pointer - * Description : - */ -static struct XGI301C_Tap4TimingStruct const -*XGI_GetTap4Ptr(unsigned short tempcx, struct vb_device_info *pVBInfo) -{ - unsigned short tempax, tempbx, i; - struct XGI301C_Tap4TimingStruct const *Tap4TimingPtr; - - if (tempcx == 0) { - tempax = pVBInfo->VGAHDE; - tempbx = pVBInfo->HDE; - } else { - tempax = pVBInfo->VGAVDE; - tempbx = pVBInfo->VDE; - } - - if (tempax <= tempbx) - return &xgifb_tap4_timing[0]; - Tap4TimingPtr = xgifb_ntsc_525_tap4_timing; /* NTSC */ - - if (pVBInfo->TVInfo & TVSetPAL) - Tap4TimingPtr = PALTap4Timing; - - if (pVBInfo->VBInfo & SetCRT2ToYPbPr525750) { - if ((pVBInfo->TVInfo & TVSetYPbPr525i) || - (pVBInfo->TVInfo & TVSetYPbPr525p)) - Tap4TimingPtr = xgifb_ntsc_525_tap4_timing; - if (pVBInfo->TVInfo & TVSetYPbPr750p) - Tap4TimingPtr = YPbPr750pTap4Timing; - } - - if (pVBInfo->VBInfo & SetCRT2ToHiVision) - Tap4TimingPtr = xgifb_tap4_timing; - - i = 0; - while (Tap4TimingPtr[i].DE != 0xFFFF) { - if (Tap4TimingPtr[i].DE == tempax) - break; - i++; - } - return &Tap4TimingPtr[i]; -} - -static void XGI_SetTap4Regs(struct vb_device_info *pVBInfo) -{ - unsigned short i, j; - struct XGI301C_Tap4TimingStruct const *Tap4TimingPtr; - - if (!(pVBInfo->VBType & VB_XGI301C)) - return; - - Tap4TimingPtr = XGI_GetTap4Ptr(0, pVBInfo); /* Set Horizontal Scaling */ - for (i = 0x80, j = 0; i <= 0xBF; i++, j++) - xgifb_reg_set(pVBInfo->Part2Port, i, Tap4TimingPtr->Reg[j]); - - if ((pVBInfo->VBInfo & SetCRT2ToTV) && - !(pVBInfo->VBInfo & SetCRT2ToHiVision)) { - /* Set Vertical Scaling */ - Tap4TimingPtr = XGI_GetTap4Ptr(1, pVBInfo); - for (i = 0xC0, j = 0; i < 0xFF; i++, j++) - xgifb_reg_set(pVBInfo->Part2Port, - i, - Tap4TimingPtr->Reg[j]); - } - - if ((pVBInfo->VBInfo & SetCRT2ToTV) && - !(pVBInfo->VBInfo & SetCRT2ToHiVision)) - /* Enable V.Scaling */ - xgifb_reg_and_or(pVBInfo->Part2Port, 0x4E, ~0x14, 0x04); - else - /* Enable H.Scaling */ - xgifb_reg_and_or(pVBInfo->Part2Port, 0x4E, ~0x14, 0x10); -} - -static void XGI_SetGroup3(unsigned short ModeIdIndex, - struct vb_device_info *pVBInfo) -{ - unsigned short i; - unsigned char const *tempdi; - unsigned short modeflag; - - /* si+Ext_ResInfo */ - modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; - - xgifb_reg_set(pVBInfo->Part3Port, 0x00, 0x00); - if (pVBInfo->TVInfo & TVSetPAL) { - xgifb_reg_set(pVBInfo->Part3Port, 0x13, 0xFA); - xgifb_reg_set(pVBInfo->Part3Port, 0x14, 0xC8); - } else { - xgifb_reg_set(pVBInfo->Part3Port, 0x13, 0xF5); - xgifb_reg_set(pVBInfo->Part3Port, 0x14, 0xB7); - } - - if (!(pVBInfo->VBInfo & SetCRT2ToTV)) - return; - - if (pVBInfo->TVInfo & TVSetPALM) { - xgifb_reg_set(pVBInfo->Part3Port, 0x13, 0xFA); - xgifb_reg_set(pVBInfo->Part3Port, 0x14, 0xC8); - xgifb_reg_set(pVBInfo->Part3Port, 0x3D, 0xA8); - } - - if ((pVBInfo->VBInfo & SetCRT2ToHiVision) || (pVBInfo->VBInfo - & SetCRT2ToYPbPr525750)) { - if (pVBInfo->TVInfo & TVSetYPbPr525i) - return; - - tempdi = XGI330_HiTVGroup3Data; - if (pVBInfo->SetFlag & TVSimuMode) { - tempdi = XGI330_HiTVGroup3Simu; - if (!(modeflag & Charx8Dot)) - tempdi = XGI330_HiTVGroup3Text; - } - - if (pVBInfo->TVInfo & TVSetYPbPr525p) - tempdi = XGI330_Ren525pGroup3; - - if (pVBInfo->TVInfo & TVSetYPbPr750p) - tempdi = XGI330_Ren750pGroup3; - - for (i = 0; i <= 0x3E; i++) - xgifb_reg_set(pVBInfo->Part3Port, i, tempdi[i]); - - if (pVBInfo->VBType & VB_XGI301C) { /* Marcovision */ - if (pVBInfo->TVInfo & TVSetYPbPr525p) - xgifb_reg_set(pVBInfo->Part3Port, 0x28, 0x3f); - } - } -} - -static void XGI_SetGroup4(unsigned short ModeIdIndex, - unsigned short RefreshRateTableIndex, - struct vb_device_info *pVBInfo) -{ - unsigned short tempax, tempcx, tempbx, modeflag, temp, temp2; - - unsigned long tempebx, tempeax, templong; - - /* si+Ext_ResInfo */ - modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; - temp = pVBInfo->RVBHCFACT; - xgifb_reg_set(pVBInfo->Part4Port, 0x13, temp); - - tempbx = pVBInfo->RVBHCMAX; - temp = tempbx & 0x00FF; - xgifb_reg_set(pVBInfo->Part4Port, 0x14, temp); - temp2 = ((tempbx & 0xFF00) >> 8) << 7; - tempcx = pVBInfo->VGAHT - 1; - temp = tempcx & 0x00FF; - xgifb_reg_set(pVBInfo->Part4Port, 0x16, temp); - - temp = ((tempcx & 0xFF00) >> 8) << 3; - temp2 |= temp; - - tempcx = pVBInfo->VGAVT - 1; - if (!(pVBInfo->VBInfo & SetCRT2ToTV)) - tempcx -= 5; - - temp = tempcx & 0x00FF; - xgifb_reg_set(pVBInfo->Part4Port, 0x17, temp); - temp = temp2 | ((tempcx & 0xFF00) >> 8); - xgifb_reg_set(pVBInfo->Part4Port, 0x15, temp); - xgifb_reg_or(pVBInfo->Part4Port, 0x0D, 0x08); - tempcx = pVBInfo->VBInfo; - tempbx = pVBInfo->VGAHDE; - - if (modeflag & HalfDCLK) - tempbx >>= 1; - - if (XGI_IsLCDDualLink(pVBInfo)) - tempbx >>= 1; - - if (tempcx & SetCRT2ToHiVision) { - temp = 0; - if (tempbx <= 1024) - temp = 0xA0; - if (tempbx == 1280) - temp = 0xC0; - } else if (tempcx & SetCRT2ToTV) { - temp = 0xA0; - if (tempbx <= 800) - temp = 0x80; - } else { - temp = 0x80; - if (pVBInfo->VBInfo & SetCRT2ToLCD) { - temp = 0; - if (tempbx > 800) - temp = 0x60; - } - } - - if (pVBInfo->TVInfo & (TVSetYPbPr525p | TVSetYPbPr750p)) { - temp = 0x00; - if (pVBInfo->VGAHDE == 1280) - temp = 0x40; - if (pVBInfo->VGAHDE == 1024) - temp = 0x20; - } - xgifb_reg_and_or(pVBInfo->Part4Port, 0x0E, ~0xEF, temp); - - tempebx = pVBInfo->VDE; - - tempcx = pVBInfo->RVBHRS; - temp = tempcx & 0x00FF; - xgifb_reg_set(pVBInfo->Part4Port, 0x18, temp); - - tempeax = pVBInfo->VGAVDE; - tempcx |= 0x04000; - - if (tempeax <= tempebx) { - tempcx = tempcx & (~0x4000); - tempeax = pVBInfo->VGAVDE; - } else { - tempeax -= tempebx; - } - - templong = (tempeax * 256 * 1024) % tempebx; - tempeax = (tempeax * 256 * 1024) / tempebx; - tempebx = tempeax; - - if (templong != 0) - tempebx++; - - temp = (unsigned short)(tempebx & 0x000000FF); - xgifb_reg_set(pVBInfo->Part4Port, 0x1B, temp); - - temp = (unsigned short)((tempebx & 0x0000FF00) >> 8); - xgifb_reg_set(pVBInfo->Part4Port, 0x1A, temp); - tempbx = (unsigned short)(tempebx >> 16); - temp = tempbx & 0x00FF; - temp <<= 4; - temp |= ((tempcx & 0xFF00) >> 8); - xgifb_reg_set(pVBInfo->Part4Port, 0x19, temp); - - /* 301b */ - if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV - | VB_SIS302LV | VB_XGI301C)) { - temp = 0x0028; - xgifb_reg_set(pVBInfo->Part4Port, 0x1C, temp); - tempax = pVBInfo->VGAHDE; - if (modeflag & HalfDCLK) - tempax >>= 1; - - if (XGI_IsLCDDualLink(pVBInfo)) - tempax >>= 1; - - if (pVBInfo->VBInfo & SetCRT2ToLCD) { - if (tempax > 800) - tempax -= 800; - } else if (pVBInfo->VGAHDE > 800) { - if (pVBInfo->VGAHDE == 1024) - tempax = (tempax * 25 / 32) - 1; - else - tempax = (tempax * 20 / 32) - 1; - } - tempax -= 1; - - temp = (tempax & 0xFF00) >> 8; - temp = (temp & 0x0003) << 4; - xgifb_reg_set(pVBInfo->Part4Port, 0x1E, temp); - temp = tempax & 0x00FF; - xgifb_reg_set(pVBInfo->Part4Port, 0x1D, temp); - - if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToHiVision)) { - if (pVBInfo->VGAHDE > 800) - xgifb_reg_or(pVBInfo->Part4Port, 0x1E, 0x08); - } - temp = 0x0036; - - if (pVBInfo->VBInfo & SetCRT2ToTV) { - if (!(pVBInfo->TVInfo & (NTSC1024x768 - | TVSetYPbPr525p | TVSetYPbPr750p - | TVSetHiVision))) { - temp |= 0x0001; - if ((pVBInfo->VBInfo & SetInSlaveMode) && - !(pVBInfo->TVInfo & TVSimuMode)) - temp &= (~0x0001); - } - } - - xgifb_reg_and_or(pVBInfo->Part4Port, 0x1F, 0x00C0, temp); - tempbx = pVBInfo->HT; - if (XGI_IsLCDDualLink(pVBInfo)) - tempbx >>= 1; - tempbx = (tempbx >> 1) - 2; - temp = ((tempbx & 0x0700) >> 8) << 3; - xgifb_reg_and_or(pVBInfo->Part4Port, 0x21, 0x00C0, temp); - temp = tempbx & 0x00FF; - xgifb_reg_set(pVBInfo->Part4Port, 0x22, temp); - } - /* end 301b */ - - XGI_SetCRT2VCLK(ModeIdIndex, RefreshRateTableIndex, pVBInfo); -} - -static void XGINew_EnableCRT2(struct vb_device_info *pVBInfo) -{ - xgifb_reg_and_or(pVBInfo->P3c4, 0x1E, 0xFF, 0x20); -} - -static void XGI_SetGroup5(struct vb_device_info *pVBInfo) -{ - if (pVBInfo->ModeType == ModeVGA) { - if (!(pVBInfo->VBInfo & (SetInSlaveMode | LoadDACFlag - | DisableCRT2Display))) { - XGINew_EnableCRT2(pVBInfo); - } - } -} - -static void XGI_DisableGatingCRT(struct vb_device_info *pVBInfo) -{ - xgifb_reg_and_or(pVBInfo->P3d4, 0x63, 0xBF, 0x00); -} - -static unsigned char XGI_XG21CheckLVDSMode(struct xgifb_video_info *xgifb_info, - unsigned short ModeNo, - unsigned short ModeIdIndex) -{ - unsigned short xres, yres, colordepth, modeflag, resindex; - - resindex = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO; - xres = XGI330_ModeResInfo[resindex].HTotal; /* xres->ax */ - yres = XGI330_ModeResInfo[resindex].VTotal; /* yres->bx */ - /* si+St_ModeFlag */ - modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; - - if (!(modeflag & Charx8Dot)) { - xres /= 9; - xres *= 8; - } - - if ((ModeNo > 0x13) && (modeflag & HalfDCLK)) - xres *= 2; - - if ((ModeNo > 0x13) && (modeflag & DoubleScanMode)) - yres *= 2; - - if (xres > xgifb_info->lvds_data.LVDSHDE) - return 0; - - if (yres > xgifb_info->lvds_data.LVDSVDE) - return 0; - - if (xres != xgifb_info->lvds_data.LVDSHDE || - yres != xgifb_info->lvds_data.LVDSVDE) { - colordepth = XGI_GetColorDepth(ModeIdIndex); - if (colordepth > 2) - return 0; - } - return 1; -} - -static void xgifb_set_lvds(struct xgifb_video_info *xgifb_info, - int chip_id, - unsigned short ModeIdIndex, - struct vb_device_info *pVBInfo) -{ - unsigned char temp, Miscdata; - unsigned short xres, yres, modeflag, resindex; - unsigned short LVDSHT, LVDSHBS, LVDSHRS, LVDSHRE, LVDSHBE; - unsigned short LVDSVT, LVDSVBS, LVDSVRS, LVDSVRE, LVDSVBE; - unsigned short value; - - temp = (unsigned char)((xgifb_info->lvds_data.LVDS_Capability & - (LCDPolarity << 8)) >> 8); - temp &= LCDPolarity; - Miscdata = inb(pVBInfo->P3cc); - - outb((Miscdata & 0x3F) | temp, pVBInfo->P3c2); - - temp = xgifb_info->lvds_data.LVDS_Capability & LCDPolarity; - /* SR35[7] FP VSync polarity */ - xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x80, temp & 0x80); - /* SR30[5] FP HSync polarity */ - xgifb_reg_and_or(pVBInfo->P3c4, 0x30, ~0x20, (temp & 0x40) >> 1); - - if (chip_id == XG27) - XGI_SetXG27FPBits(pVBInfo); - else - XGI_SetXG21FPBits(pVBInfo); - - resindex = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO; - xres = XGI330_ModeResInfo[resindex].HTotal; /* xres->ax */ - yres = XGI330_ModeResInfo[resindex].VTotal; /* yres->bx */ - /* si+St_ModeFlag */ - modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; - - if (!(modeflag & Charx8Dot)) - xres = xres * 8 / 9; - - LVDSHT = xgifb_info->lvds_data.LVDSHT; - - LVDSHBS = xres + (xgifb_info->lvds_data.LVDSHDE - xres) / 2; - - if (LVDSHBS > LVDSHT) - LVDSHBS -= LVDSHT; - - LVDSHRS = LVDSHBS + xgifb_info->lvds_data.LVDSHFP; - if (LVDSHRS > LVDSHT) - LVDSHRS -= LVDSHT; - - LVDSHRE = LVDSHRS + xgifb_info->lvds_data.LVDSHSYNC; - if (LVDSHRE > LVDSHT) - LVDSHRE -= LVDSHT; - - LVDSHBE = LVDSHBS + LVDSHT - xgifb_info->lvds_data.LVDSHDE; - - LVDSVT = xgifb_info->lvds_data.LVDSVT; - - LVDSVBS = yres + (xgifb_info->lvds_data.LVDSVDE - yres) / 2; - if (modeflag & DoubleScanMode) - LVDSVBS += yres / 2; - - if (LVDSVBS > LVDSVT) - LVDSVBS -= LVDSVT; - - LVDSVRS = LVDSVBS + xgifb_info->lvds_data.LVDSVFP; - if (LVDSVRS > LVDSVT) - LVDSVRS -= LVDSVT; - - LVDSVRE = LVDSVRS + xgifb_info->lvds_data.LVDSVSYNC; - if (LVDSVRE > LVDSVT) - LVDSVRE -= LVDSVT; - - LVDSVBE = LVDSVBS + LVDSVT - xgifb_info->lvds_data.LVDSVDE; - - temp = xgifb_reg_get(pVBInfo->P3d4, 0x11); - xgifb_reg_set(pVBInfo->P3d4, 0x11, temp & 0x7f); /* Unlock CRTC */ - - if (!(modeflag & Charx8Dot)) - xgifb_reg_or(pVBInfo->P3c4, 0x1, 0x1); - - /* HT SR0B[1:0] CR00 */ - value = (LVDSHT >> 3) - 5; - xgifb_reg_and_or(pVBInfo->P3c4, 0x0B, ~0x03, (value & 0x300) >> 8); - xgifb_reg_set(pVBInfo->P3d4, 0x0, (value & 0xFF)); - - /* HBS SR0B[5:4] CR02 */ - value = (LVDSHBS >> 3) - 1; - xgifb_reg_and_or(pVBInfo->P3c4, 0x0B, ~0x30, (value & 0x300) >> 4); - xgifb_reg_set(pVBInfo->P3d4, 0x2, (value & 0xFF)); - - /* HBE SR0C[1:0] CR05[7] CR03[4:0] */ - value = (LVDSHBE >> 3) - 1; - xgifb_reg_and_or(pVBInfo->P3c4, 0x0C, ~0x03, (value & 0xC0) >> 6); - xgifb_reg_and_or(pVBInfo->P3d4, 0x05, ~0x80, (value & 0x20) << 2); - xgifb_reg_and_or(pVBInfo->P3d4, 0x03, ~0x1F, value & 0x1F); - - /* HRS SR0B[7:6] CR04 */ - value = (LVDSHRS >> 3) + 2; - xgifb_reg_and_or(pVBInfo->P3c4, 0x0B, ~0xC0, (value & 0x300) >> 2); - xgifb_reg_set(pVBInfo->P3d4, 0x4, (value & 0xFF)); - - /* Panel HRS SR2F[1:0] SR2E[7:0] */ - value--; - xgifb_reg_and_or(pVBInfo->P3c4, 0x2F, ~0x03, (value & 0x300) >> 8); - xgifb_reg_set(pVBInfo->P3c4, 0x2E, (value & 0xFF)); - - /* HRE SR0C[2] CR05[4:0] */ - value = (LVDSHRE >> 3) + 2; - xgifb_reg_and_or(pVBInfo->P3c4, 0x0C, ~0x04, (value & 0x20) >> 3); - xgifb_reg_and_or(pVBInfo->P3d4, 0x05, ~0x1F, value & 0x1F); - - /* Panel HRE SR2F[7:2] */ - value--; - xgifb_reg_and_or(pVBInfo->P3c4, 0x2F, ~0xFC, value << 2); - - /* VT SR0A[0] CR07[5][0] CR06 */ - value = LVDSVT - 2; - xgifb_reg_and_or(pVBInfo->P3c4, 0x0A, ~0x01, (value & 0x400) >> 10); - xgifb_reg_and_or(pVBInfo->P3d4, 0x07, ~0x20, (value & 0x200) >> 4); - xgifb_reg_and_or(pVBInfo->P3d4, 0x07, ~0x01, (value & 0x100) >> 8); - xgifb_reg_set(pVBInfo->P3d4, 0x06, (value & 0xFF)); - - /* VBS SR0A[2] CR09[5] CR07[3] CR15 */ - value = LVDSVBS - 1; - xgifb_reg_and_or(pVBInfo->P3c4, 0x0A, ~0x04, (value & 0x400) >> 8); - xgifb_reg_and_or(pVBInfo->P3d4, 0x09, ~0x20, (value & 0x200) >> 4); - xgifb_reg_and_or(pVBInfo->P3d4, 0x07, ~0x08, (value & 0x100) >> 5); - xgifb_reg_set(pVBInfo->P3d4, 0x15, (value & 0xFF)); - - /* VBE SR0A[4] CR16 */ - value = LVDSVBE - 1; - xgifb_reg_and_or(pVBInfo->P3c4, 0x0A, ~0x10, (value & 0x100) >> 4); - xgifb_reg_set(pVBInfo->P3d4, 0x16, (value & 0xFF)); - - /* VRS SR0A[3] CR7[7][2] CR10 */ - value = LVDSVRS - 1; - xgifb_reg_and_or(pVBInfo->P3c4, 0x0A, ~0x08, (value & 0x400) >> 7); - xgifb_reg_and_or(pVBInfo->P3d4, 0x07, ~0x80, (value & 0x200) >> 2); - xgifb_reg_and_or(pVBInfo->P3d4, 0x07, ~0x04, (value & 0x100) >> 6); - xgifb_reg_set(pVBInfo->P3d4, 0x10, (value & 0xFF)); - - if (chip_id == XG27) { - /* Panel VRS SR35[2:0] SR34[7:0] */ - xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x07, - (value & 0x700) >> 8); - xgifb_reg_set(pVBInfo->P3c4, 0x34, value & 0xFF); - } else { - /* Panel VRS SR3F[1:0] SR34[7:0] SR33[0] */ - xgifb_reg_and_or(pVBInfo->P3c4, 0x3F, ~0x03, - (value & 0x600) >> 9); - xgifb_reg_set(pVBInfo->P3c4, 0x34, (value >> 1) & 0xFF); - xgifb_reg_and_or(pVBInfo->P3d4, 0x33, ~0x01, value & 0x01); - } - - /* VRE SR0A[5] CR11[3:0] */ - value = LVDSVRE - 1; - xgifb_reg_and_or(pVBInfo->P3c4, 0x0A, ~0x20, (value & 0x10) << 1); - xgifb_reg_and_or(pVBInfo->P3d4, 0x11, ~0x0F, value & 0x0F); - - /* Panel VRE SR3F[7:2] */ - if (chip_id == XG27) - xgifb_reg_and_or(pVBInfo->P3c4, 0x3F, ~0xFC, - (value << 2) & 0xFC); - else - /* SR3F[7] has to be 0, h/w bug */ - xgifb_reg_and_or(pVBInfo->P3c4, 0x3F, ~0xFC, - (value << 2) & 0x7C); - - for (temp = 0, value = 0; temp < 3; temp++) { - xgifb_reg_and_or(pVBInfo->P3c4, 0x31, ~0x30, value); - xgifb_reg_set(pVBInfo->P3c4, - 0x2B, xgifb_info->lvds_data.VCLKData1); - xgifb_reg_set(pVBInfo->P3c4, - 0x2C, xgifb_info->lvds_data.VCLKData2); - value += 0x10; - } - - if (!(modeflag & Charx8Dot)) { - inb(pVBInfo->P3da); /* reset 3da */ - outb(0x13, pVBInfo->P3c0); /* set index */ - /* set data, panning = 0, shift left 1 dot*/ - outb(0x00, pVBInfo->P3c0); - - inb(pVBInfo->P3da); /* Enable Attribute */ - outb(0x20, pVBInfo->P3c0); - - inb(pVBInfo->P3da); /* reset 3da */ - } -} - -/* - * Function : XGI_IsLCDON - * Input : - * Output : 0 : Skip PSC Control - * 1: Disable PSC - * Description : - */ -static unsigned char XGI_IsLCDON(struct vb_device_info *pVBInfo) -{ - unsigned short tempax; - - tempax = pVBInfo->VBInfo; - if (tempax & SetCRT2ToDualEdge) - return 0; - else if (tempax & (DisableCRT2Display | SwitchCRT2 | SetSimuScanMode)) - return 1; - - return 0; -} - -static void XGI_DisableBridge(struct xgifb_video_info *xgifb_info, - struct xgi_hw_device_info *HwDeviceExtension, - struct vb_device_info *pVBInfo) -{ - unsigned short tempah = 0; - - if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV - | VB_SIS302LV | VB_XGI301C)) { - tempah = 0x3F; - if (!(pVBInfo->VBInfo & - (DisableCRT2Display | SetSimuScanMode))) { - if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) { - if (pVBInfo->VBInfo & SetCRT2ToDualEdge) - tempah = 0x7F; /* Disable Channel A */ - } - } - - /* disable part4_1f */ - xgifb_reg_and(pVBInfo->Part4Port, 0x1F, tempah); - - if (pVBInfo->VBType & (VB_SIS302LV | VB_XGI301C)) { - if (((pVBInfo->VBInfo & - (SetCRT2ToLCD | XGI_SetCRT2ToLCDA))) || - (XGI_IsLCDON(pVBInfo))) - /* LVDS Driver power down */ - xgifb_reg_or(pVBInfo->Part4Port, 0x30, 0x80); - } - - if (pVBInfo->VBInfo & (DisableCRT2Display | XGI_SetCRT2ToLCDA | - SetSimuScanMode)) - XGI_DisplayOff(xgifb_info, HwDeviceExtension, pVBInfo); - - if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) - /* Power down */ - xgifb_reg_and(pVBInfo->Part1Port, 0x1e, 0xdf); - - /* disable TV as primary VGA swap */ - xgifb_reg_and(pVBInfo->P3c4, 0x32, 0xdf); - - if ((pVBInfo->VBInfo & (SetSimuScanMode | SetCRT2ToDualEdge))) - xgifb_reg_and(pVBInfo->Part2Port, 0x00, 0xdf); - - if ((pVBInfo->VBInfo & - (DisableCRT2Display | SetSimuScanMode)) || - (!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) && - (pVBInfo->VBInfo & - (SetCRT2ToRAMDAC | SetCRT2ToLCD | SetCRT2ToTV)))) - xgifb_reg_or(pVBInfo->Part1Port, 0x00, 0x80); - - if ((pVBInfo->VBInfo & - (DisableCRT2Display | SetSimuScanMode)) || - (!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)) || - (pVBInfo->VBInfo & - (SetCRT2ToRAMDAC | SetCRT2ToLCD | SetCRT2ToTV))) { - /* save Part1 index 0 */ - tempah = xgifb_reg_get(pVBInfo->Part1Port, 0x00); - /* BTDAC = 1, avoid VB reset */ - xgifb_reg_or(pVBInfo->Part1Port, 0x00, 0x10); - /* disable CRT2 */ - xgifb_reg_and(pVBInfo->Part1Port, 0x1E, 0xDF); - /* restore Part1 index 0 */ - xgifb_reg_set(pVBInfo->Part1Port, 0x00, tempah); - } - } else { /* {301} */ - if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) { - xgifb_reg_or(pVBInfo->Part1Port, 0x00, 0x80); - /* Disable CRT2 */ - xgifb_reg_and(pVBInfo->Part1Port, 0x1E, 0xDF); - /* Disable TV asPrimary VGA swap */ - xgifb_reg_and(pVBInfo->P3c4, 0x32, 0xDF); - } - - if (pVBInfo->VBInfo & (DisableCRT2Display | XGI_SetCRT2ToLCDA - | SetSimuScanMode)) - XGI_DisplayOff(xgifb_info, HwDeviceExtension, pVBInfo); - } -} - -/* - * Function : XGI_GetTVPtrIndex - * Input : - * Output : - * Description : bx 0 : ExtNTSC - * 1 : StNTSC - * 2 : ExtPAL - * 3 : StPAL - * 4 : ExtHiTV - * 5 : StHiTV - * 6 : Ext525i - * 7 : St525i - * 8 : Ext525p - * 9 : St525p - * A : Ext750p - * B : St750p - */ -static unsigned short XGI_GetTVPtrIndex(struct vb_device_info *pVBInfo) -{ - unsigned short tempbx = 0; - - if (pVBInfo->TVInfo & TVSetPAL) - tempbx = 2; - if (pVBInfo->TVInfo & TVSetHiVision) - tempbx = 4; - if (pVBInfo->TVInfo & TVSetYPbPr525i) - tempbx = 6; - if (pVBInfo->TVInfo & TVSetYPbPr525p) - tempbx = 8; - if (pVBInfo->TVInfo & TVSetYPbPr750p) - tempbx = 10; - if (pVBInfo->TVInfo & TVSimuMode) - tempbx++; - - return tempbx; -} - -/* - * Function : XGI_GetTVPtrIndex2 - * Input : - * Output : bx 0 : NTSC - * 1 : PAL - * 2 : PALM - * 3 : PALN - * 4 : NTSC1024x768 - * 5 : PAL-M 1024x768 - * 6-7: reserved - * cl 0 : YFilter1 - * 1 : YFilter2 - * ch 0 : 301A - * 1 : 301B/302B/301LV/302LV - * Description : - */ -static void XGI_GetTVPtrIndex2(unsigned short *tempbx, - unsigned char *tempcl, - unsigned char *tempch, - struct vb_device_info *pVBInfo) -{ - *tempbx = 0; - *tempcl = 0; - *tempch = 0; - - if (pVBInfo->TVInfo & TVSetPAL) - *tempbx = 1; - - if (pVBInfo->TVInfo & TVSetPALM) - *tempbx = 2; - - if (pVBInfo->TVInfo & TVSetPALN) - *tempbx = 3; - - if (pVBInfo->TVInfo & NTSC1024x768) { - *tempbx = 4; - if (pVBInfo->TVInfo & TVSetPALM) - *tempbx = 5; - } - - if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV - | VB_SIS302LV | VB_XGI301C)) { - if (!(pVBInfo->VBInfo & SetInSlaveMode) || (pVBInfo->TVInfo - & TVSimuMode)) { - *tempbx += 8; - *tempcl += 1; - } - } - - if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV - | VB_SIS302LV | VB_XGI301C)) - (*tempch)++; -} - -static void XGI_SetDelayComp(struct vb_device_info *pVBInfo) -{ - unsigned char tempah, tempbl, tempbh; - - if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV - | VB_SIS302LV | VB_XGI301C)) { - if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA - | SetCRT2ToTV | SetCRT2ToRAMDAC)) { - tempbh = 0; - tempbl = XGI301TVDelay; - - if (pVBInfo->VBInfo & SetCRT2ToDualEdge) - tempbl >>= 4; - if (pVBInfo->VBInfo & - (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) { - tempbh = XGI301LCDDelay; - - if (!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)) - tempbl = tempbh; - } - - tempbl &= 0x0F; - tempbh &= 0xF0; - tempah = xgifb_reg_get(pVBInfo->Part1Port, 0x2D); - - if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD - | SetCRT2ToTV)) { /* Channel B */ - tempah &= 0xF0; - tempah |= tempbl; - } - - if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) { - /* Channel A */ - tempah &= 0x0F; - tempah |= tempbh; - } - xgifb_reg_set(pVBInfo->Part1Port, 0x2D, tempah); - } - } -} - -static void XGI_SetLCDCap_A(unsigned short tempcx, - struct vb_device_info *pVBInfo) -{ - unsigned short temp; - - temp = xgifb_reg_get(pVBInfo->P3d4, 0x37); - - if (temp & LCDRGB18Bit) { - xgifb_reg_and_or(pVBInfo->Part1Port, 0x19, 0x0F, - /* Enable Dither */ - (unsigned short)(0x20 | (tempcx & 0x00C0))); - xgifb_reg_and_or(pVBInfo->Part1Port, 0x1A, 0x7F, 0x80); - } else { - xgifb_reg_and_or(pVBInfo->Part1Port, 0x19, 0x0F, - (unsigned short)(0x30 | (tempcx & 0x00C0))); - xgifb_reg_and_or(pVBInfo->Part1Port, 0x1A, 0x7F, 0x00); - } -} - -/* - * Function : XGI_SetLCDCap_B - * Input : cx -> LCD Capability - * Output : - * Description : - */ -static void XGI_SetLCDCap_B(unsigned short tempcx, - struct vb_device_info *pVBInfo) -{ - if (tempcx & EnableLCD24bpp) { /* 24bits */ - xgifb_reg_and_or(pVBInfo->Part2Port, 0x1A, 0xE0, - (unsigned short)(((tempcx & 0x00ff) >> 6) | 0x0c)); - } else { - xgifb_reg_and_or(pVBInfo->Part2Port, 0x1A, 0xE0, - (unsigned short)(((tempcx & 0x00ff) >> 6) | 0x18)); - /* Enable Dither */ - } -} - -static void XGI_LongWait(struct vb_device_info *pVBInfo) -{ - unsigned short i; - - i = xgifb_reg_get(pVBInfo->P3c4, 0x1F); - - if (!(i & 0xC0)) { - for (i = 0; i < 0xFFFF; i++) { - if (!(inb(pVBInfo->P3da) & 0x08)) - break; - } - - for (i = 0; i < 0xFFFF; i++) { - if ((inb(pVBInfo->P3da) & 0x08)) - break; - } - } -} - -static void SetSpectrum(struct vb_device_info *pVBInfo) -{ - unsigned short index; - - index = XGI_GetLCDCapPtr(pVBInfo); - - /* disable down spectrum D[4] */ - xgifb_reg_and(pVBInfo->Part4Port, 0x30, 0x8F); - XGI_LongWait(pVBInfo); - xgifb_reg_or(pVBInfo->Part4Port, 0x30, 0x20); /* reset spectrum */ - XGI_LongWait(pVBInfo); - - xgifb_reg_set(pVBInfo->Part4Port, 0x31, - pVBInfo->LCDCapList[index].Spectrum_31); - xgifb_reg_set(pVBInfo->Part4Port, 0x32, - pVBInfo->LCDCapList[index].Spectrum_32); - xgifb_reg_set(pVBInfo->Part4Port, 0x33, - pVBInfo->LCDCapList[index].Spectrum_33); - xgifb_reg_set(pVBInfo->Part4Port, 0x34, - pVBInfo->LCDCapList[index].Spectrum_34); - XGI_LongWait(pVBInfo); - xgifb_reg_or(pVBInfo->Part4Port, 0x30, 0x40); /* enable spectrum */ -} - -static void XGI_SetLCDCap(struct vb_device_info *pVBInfo) -{ - unsigned short tempcx; - - tempcx = pVBInfo->LCDCapList[XGI_GetLCDCapPtr(pVBInfo)].LCD_Capability; - - if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV | - VB_SIS302LV | VB_XGI301C)) { - if (pVBInfo->VBType & - (VB_SIS301LV | VB_SIS302LV | VB_XGI301C)) { - /* Set 301LV Capability */ - xgifb_reg_set(pVBInfo->Part4Port, 0x24, - (unsigned char)(tempcx & 0x1F)); - } - /* VB Driving */ - xgifb_reg_and_or(pVBInfo->Part4Port, 0x0D, - ~((EnableVBCLKDRVLOW | EnablePLLSPLOW) >> 8), - (unsigned short)((tempcx & (EnableVBCLKDRVLOW | - EnablePLLSPLOW)) >> 8)); - - if (pVBInfo->VBInfo & SetCRT2ToLCD) - XGI_SetLCDCap_B(tempcx, pVBInfo); - else if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) - XGI_SetLCDCap_A(tempcx, pVBInfo); - - if (pVBInfo->VBType & (VB_SIS302LV | VB_XGI301C)) { - if (tempcx & EnableSpectrum) - SetSpectrum(pVBInfo); - } - } else { - /* LVDS,CH7017 */ - XGI_SetLCDCap_A(tempcx, pVBInfo); - } -} - -/* - * Function : XGI_SetAntiFlicker - * Input : - * Output : - * Description : Set TV Customized Param. - */ -static void XGI_SetAntiFlicker(struct vb_device_info *pVBInfo) -{ - unsigned short tempbx; - - unsigned char tempah; - - if (pVBInfo->TVInfo & (TVSetYPbPr525p | TVSetYPbPr750p)) - return; - - tempbx = XGI_GetTVPtrIndex(pVBInfo); - tempbx &= 0xFE; - tempah = TVAntiFlickList[tempbx]; - tempah <<= 4; - - xgifb_reg_and_or(pVBInfo->Part2Port, 0x0A, 0x8F, tempah); -} - -static void XGI_SetEdgeEnhance(struct vb_device_info *pVBInfo) -{ - unsigned short tempbx; - - unsigned char tempah; - - tempbx = XGI_GetTVPtrIndex(pVBInfo); - tempbx &= 0xFE; - tempah = TVEdgeList[tempbx]; - tempah <<= 5; - - xgifb_reg_and_or(pVBInfo->Part2Port, 0x3A, 0x1F, tempah); -} - -static void XGI_SetPhaseIncr(struct vb_device_info *pVBInfo) -{ - unsigned short tempbx; - - unsigned char tempcl, tempch; - - unsigned long tempData; - - XGI_GetTVPtrIndex2(&tempbx, &tempcl, &tempch, pVBInfo); /* bx, cl, ch */ - tempData = TVPhaseList[tempbx]; - - xgifb_reg_set(pVBInfo->Part2Port, 0x31, (unsigned short)(tempData - & 0x000000FF)); - xgifb_reg_set(pVBInfo->Part2Port, 0x32, (unsigned short)((tempData - & 0x0000FF00) >> 8)); - xgifb_reg_set(pVBInfo->Part2Port, 0x33, (unsigned short)((tempData - & 0x00FF0000) >> 16)); - xgifb_reg_set(pVBInfo->Part2Port, 0x34, (unsigned short)((tempData - & 0xFF000000) >> 24)); -} - -static void XGI_SetYFilter(unsigned short ModeIdIndex, - struct vb_device_info *pVBInfo) -{ - unsigned short tempbx, index; - unsigned char const *filterPtr; - unsigned char tempcl, tempch, tempal; - - XGI_GetTVPtrIndex2(&tempbx, &tempcl, &tempch, pVBInfo); /* bx, cl, ch */ - - switch (tempbx) { - case 0x00: - case 0x04: - filterPtr = NTSCYFilter1; - break; - - case 0x01: - filterPtr = PALYFilter1; - break; - - case 0x02: - case 0x05: - case 0x0D: - case 0x03: - filterPtr = xgifb_palmn_yfilter1; - break; - - case 0x08: - case 0x0C: - case 0x0A: - case 0x0B: - case 0x09: - filterPtr = xgifb_yfilter2; - break; - - default: - return; - } - - tempal = XGI330_EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex; - if (tempcl == 0) - index = tempal * 4; - else - index = tempal * 7; - - if ((tempcl == 0) && (tempch == 1)) { - xgifb_reg_set(pVBInfo->Part2Port, 0x35, 0); - xgifb_reg_set(pVBInfo->Part2Port, 0x36, 0); - xgifb_reg_set(pVBInfo->Part2Port, 0x37, 0); - xgifb_reg_set(pVBInfo->Part2Port, 0x38, filterPtr[index++]); - } else { - xgifb_reg_set(pVBInfo->Part2Port, 0x35, filterPtr[index++]); - xgifb_reg_set(pVBInfo->Part2Port, 0x36, filterPtr[index++]); - xgifb_reg_set(pVBInfo->Part2Port, 0x37, filterPtr[index++]); - xgifb_reg_set(pVBInfo->Part2Port, 0x38, filterPtr[index++]); - } - - if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV - | VB_SIS302LV | VB_XGI301C)) { - xgifb_reg_set(pVBInfo->Part2Port, 0x48, filterPtr[index++]); - xgifb_reg_set(pVBInfo->Part2Port, 0x49, filterPtr[index++]); - xgifb_reg_set(pVBInfo->Part2Port, 0x4A, filterPtr[index++]); - } -} - -/* - * Function : XGI_OEM310Setting - * Input : - * Output : - * Description : Customized Param. for 301 - */ -static void XGI_OEM310Setting(unsigned short ModeIdIndex, - struct vb_device_info *pVBInfo) -{ - XGI_SetDelayComp(pVBInfo); - - if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) - XGI_SetLCDCap(pVBInfo); - - if (pVBInfo->VBInfo & SetCRT2ToTV) { - XGI_SetPhaseIncr(pVBInfo); - XGI_SetYFilter(ModeIdIndex, pVBInfo); - XGI_SetAntiFlicker(pVBInfo); - - if (pVBInfo->VBType & VB_SIS301) - XGI_SetEdgeEnhance(pVBInfo); - } -} - -/* - * Function : XGI_SetCRT2ModeRegs - * Input : - * Output : - * Description : Origin code for crt2group - */ -static void XGI_SetCRT2ModeRegs(struct vb_device_info *pVBInfo) -{ - unsigned short tempbl; - short tempcl; - - unsigned char tempah; - - tempah = 0; - if (!(pVBInfo->VBInfo & DisableCRT2Display)) { - tempah = xgifb_reg_get(pVBInfo->Part1Port, 0x00); - tempah &= ~0x10; /* BTRAMDAC */ - tempah |= 0x40; /* BTRAM */ - - if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV - | SetCRT2ToLCD)) { - tempah = 0x40; /* BTDRAM */ - tempcl = pVBInfo->ModeType; - tempcl -= ModeVGA; - if (tempcl >= 0) { - /* BT Color */ - tempah = 0x008 >> tempcl; - if (tempah == 0) - tempah = 1; - tempah |= 0x040; - } - if (pVBInfo->VBInfo & SetInSlaveMode) - tempah ^= 0x50; /* BTDAC */ - } - } - - xgifb_reg_set(pVBInfo->Part1Port, 0x00, tempah); - tempah = 0x08; - tempbl = 0xf0; - - if (pVBInfo->VBInfo & DisableCRT2Display) - goto reg_and_or; - - tempah = 0x00; - tempbl = 0xff; - - if (!(pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV | - SetCRT2ToLCD | XGI_SetCRT2ToLCDA))) - goto reg_and_or; - - if ((pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) && - (!(pVBInfo->VBInfo & SetSimuScanMode))) { - tempbl &= 0xf7; - tempah |= 0x01; - goto reg_and_or; - } - - if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) { - tempbl &= 0xf7; - tempah |= 0x01; - } - - if (!(pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV | SetCRT2ToLCD))) - goto reg_and_or; - - tempbl &= 0xf8; - tempah = 0x01; - - if (!(pVBInfo->VBInfo & SetInSlaveMode)) - tempah |= 0x02; - - if (!(pVBInfo->VBInfo & SetCRT2ToRAMDAC)) { - tempah = tempah ^ 0x05; - if (!(pVBInfo->VBInfo & SetCRT2ToLCD)) - tempah = tempah ^ 0x01; - } - - if (!(pVBInfo->VBInfo & SetCRT2ToDualEdge)) - tempah |= 0x08; - -reg_and_or: - xgifb_reg_and_or(pVBInfo->Part1Port, 0x2e, tempbl, tempah); - - if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV | SetCRT2ToLCD - | XGI_SetCRT2ToLCDA)) { - tempah &= (~0x08); - if ((pVBInfo->ModeType == ModeVGA) && !(pVBInfo->VBInfo - & SetInSlaveMode)) { - tempah |= 0x010; - } - tempah |= 0x080; - - if (pVBInfo->VBInfo & SetCRT2ToTV) { - tempah |= 0x020; - if (pVBInfo->VBInfo & DriverMode) - tempah = tempah ^ 0x20; - } - - xgifb_reg_and_or(pVBInfo->Part4Port, 0x0D, ~0x0BF, tempah); - tempah = 0; - - if (pVBInfo->LCDInfo & SetLCDDualLink) - tempah |= 0x40; - - if (pVBInfo->VBInfo & SetCRT2ToTV) { - if (pVBInfo->TVInfo & RPLLDIV2XO) - tempah |= 0x40; - } - - if ((pVBInfo->LCDResInfo == Panel_1280x1024) || - (pVBInfo->LCDResInfo == Panel_1280x1024x75)) - tempah |= 0x80; - - if (pVBInfo->LCDResInfo == Panel_1280x960) - tempah |= 0x80; - - xgifb_reg_set(pVBInfo->Part4Port, 0x0C, tempah); - } - - if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV - | VB_SIS302LV | VB_XGI301C)) { - tempah = 0; - tempbl = 0xfb; - - if (pVBInfo->VBInfo & SetCRT2ToDualEdge) { - tempbl = 0xff; - if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) - tempah |= 0x04; /* shampoo 0129 */ - } - - xgifb_reg_and_or(pVBInfo->Part1Port, 0x13, tempbl, tempah); - tempah = 0x00; - tempbl = 0xcf; - if (!(pVBInfo->VBInfo & DisableCRT2Display)) { - if (pVBInfo->VBInfo & SetCRT2ToDualEdge) - tempah |= 0x30; - } - - xgifb_reg_and_or(pVBInfo->Part1Port, 0x2c, tempbl, tempah); - tempah = 0; - tempbl = 0x3f; - - if (!(pVBInfo->VBInfo & DisableCRT2Display)) { - if (pVBInfo->VBInfo & SetCRT2ToDualEdge) - tempah |= 0xc0; - } - xgifb_reg_and_or(pVBInfo->Part4Port, 0x21, tempbl, tempah); - } - - tempah = 0; - tempbl = 0x7f; - if (!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)) { - tempbl = 0xff; - if (!(pVBInfo->VBInfo & SetCRT2ToDualEdge)) - tempah |= 0x80; - } - - xgifb_reg_and_or(pVBInfo->Part4Port, 0x23, tempbl, tempah); - - if (pVBInfo->VBType & (VB_SIS302LV | VB_XGI301C)) { - if (pVBInfo->LCDInfo & SetLCDDualLink) { - xgifb_reg_or(pVBInfo->Part4Port, 0x27, 0x20); - xgifb_reg_or(pVBInfo->Part4Port, 0x34, 0x10); - } - } -} - -void XGI_UnLockCRT2(struct vb_device_info *pVBInfo) -{ - xgifb_reg_and_or(pVBInfo->Part1Port, 0x2f, 0xFF, 0x01); -} - -void XGI_LockCRT2(struct vb_device_info *pVBInfo) -{ - xgifb_reg_and_or(pVBInfo->Part1Port, 0x2F, 0xFE, 0x00); -} - -unsigned short XGI_GetRatePtrCRT2(struct xgi_hw_device_info *pXGIHWDE, - unsigned short ModeNo, - unsigned short ModeIdIndex, - struct vb_device_info *pVBInfo) -{ - static const u8 LCDARefreshIndex[] = { - 0x00, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x00 }; - - unsigned short RefreshRateTableIndex, i, index, temp; - - index = xgifb_reg_get(pVBInfo->P3d4, 0x33); - index >>= pVBInfo->SelectCRT2Rate; - index &= 0x0F; - - if (pVBInfo->LCDInfo & LCDNonExpanding) - index = 0; - - if (index > 0) - index--; - - if (pVBInfo->SetFlag & ProgrammingCRT2) { - if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) { - temp = LCDARefreshIndex[pVBInfo->LCDResInfo & 0x07]; - - if (index > temp) - index = temp; - } - } - - RefreshRateTableIndex = XGI330_EModeIDTable[ModeIdIndex].REFindex; - ModeNo = XGI330_RefIndex[RefreshRateTableIndex].ModeID; - if (pXGIHWDE->jChipType >= XG20) { /* for XG20, XG21, XG27 */ - if ((XGI330_RefIndex[RefreshRateTableIndex].XRes == 800) && - (XGI330_RefIndex[RefreshRateTableIndex].YRes == 600)) { - index++; - } - /* do the similar adjustment like XGISearchCRT1Rate() */ - if ((XGI330_RefIndex[RefreshRateTableIndex].XRes == 1024) && - (XGI330_RefIndex[RefreshRateTableIndex].YRes == 768)) { - index++; - } - if ((XGI330_RefIndex[RefreshRateTableIndex].XRes == 1280) && - (XGI330_RefIndex[RefreshRateTableIndex].YRes == 1024)) { - index++; - } - } - - i = 0; - do { - if (XGI330_RefIndex[RefreshRateTableIndex + i].ModeID != ModeNo) - break; - temp = XGI330_RefIndex[RefreshRateTableIndex + i].Ext_InfoFlag; - temp &= ModeTypeMask; - if (temp < pVBInfo->ModeType) - break; - i++; - index--; - - } while (index != 0xFFFF); - if (!(pVBInfo->VBInfo & SetCRT2ToRAMDAC)) { - if (pVBInfo->VBInfo & SetInSlaveMode) { - temp = XGI330_RefIndex[RefreshRateTableIndex + i - 1].Ext_InfoFlag; - if (temp & InterlaceMode) - i++; - } - } - i--; - if ((pVBInfo->SetFlag & ProgrammingCRT2)) { - temp = XGI_AjustCRT2Rate(ModeIdIndex, RefreshRateTableIndex, - &i, pVBInfo); - } - return RefreshRateTableIndex + i; -} - -static void XGI_SetLCDAGroup(unsigned short ModeNo, unsigned short ModeIdIndex, - struct xgi_hw_device_info *HwDeviceExtension, - struct vb_device_info *pVBInfo) -{ - unsigned short RefreshRateTableIndex; - - pVBInfo->SetFlag |= ProgrammingCRT2; - RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo, - ModeIdIndex, pVBInfo); - XGI_GetLVDSResInfo(ModeIdIndex, pVBInfo); - XGI_GetLVDSData(ModeIdIndex, pVBInfo); - XGI_ModCRT1Regs(ModeIdIndex, HwDeviceExtension, pVBInfo); - XGI_SetLVDSRegs(ModeIdIndex, pVBInfo); - XGI_SetCRT2ECLK(ModeIdIndex, RefreshRateTableIndex, pVBInfo); -} - -static unsigned char XGI_SetCRT2Group301(unsigned short ModeNo, - struct xgi_hw_device_info *HwDeviceExtension, - struct vb_device_info *pVBInfo) -{ - unsigned short ModeIdIndex, RefreshRateTableIndex; - - pVBInfo->SetFlag |= ProgrammingCRT2; - XGI_SearchModeID(ModeNo, &ModeIdIndex); - pVBInfo->SelectCRT2Rate = 4; - RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo, - ModeIdIndex, pVBInfo); - XGI_SaveCRT2Info(ModeNo, pVBInfo); - XGI_GetCRT2ResInfo(ModeIdIndex, pVBInfo); - XGI_GetCRT2Data(ModeIdIndex, RefreshRateTableIndex, pVBInfo); - XGI_PreSetGroup1(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo); - XGI_SetGroup1(ModeIdIndex, RefreshRateTableIndex, pVBInfo); - XGI_SetLockRegs(ModeNo, ModeIdIndex, pVBInfo); - XGI_SetGroup2(ModeNo, ModeIdIndex, pVBInfo); - XGI_SetLCDRegs(ModeIdIndex, pVBInfo); - XGI_SetTap4Regs(pVBInfo); - XGI_SetGroup3(ModeIdIndex, pVBInfo); - XGI_SetGroup4(ModeIdIndex, RefreshRateTableIndex, pVBInfo); - XGI_SetCRT2VCLK(ModeIdIndex, RefreshRateTableIndex, pVBInfo); - XGI_SetGroup5(pVBInfo); - XGI_AutoThreshold(pVBInfo); - return 1; -} - -void XGI_SenseCRT1(struct vb_device_info *pVBInfo) -{ - unsigned char CRTCData[17] = { 0x5F, 0x4F, 0x50, 0x82, 0x55, 0x81, - 0x0B, 0x3E, 0xE9, 0x0B, 0xDF, 0xE7, 0x04, 0x00, 0x00, - 0x05, 0x00 }; - - unsigned char SR01 = 0, SR1F = 0, SR07 = 0, SR06 = 0; - - unsigned char CR17, CR63, SR31; - unsigned short temp; - - int i; - - xgifb_reg_set(pVBInfo->P3c4, 0x05, 0x86); - - /* to fix XG42 single LCD sense to CRT+LCD */ - xgifb_reg_set(pVBInfo->P3d4, 0x57, 0x4A); - xgifb_reg_set(pVBInfo->P3d4, 0x53, (xgifb_reg_get( - pVBInfo->P3d4, 0x53) | 0x02)); - - SR31 = xgifb_reg_get(pVBInfo->P3c4, 0x31); - CR63 = xgifb_reg_get(pVBInfo->P3d4, 0x63); - SR01 = xgifb_reg_get(pVBInfo->P3c4, 0x01); - - xgifb_reg_set(pVBInfo->P3c4, 0x01, (unsigned char)(SR01 & 0xDF)); - xgifb_reg_set(pVBInfo->P3d4, 0x63, (unsigned char)(CR63 & 0xBF)); - - CR17 = xgifb_reg_get(pVBInfo->P3d4, 0x17); - xgifb_reg_set(pVBInfo->P3d4, 0x17, (unsigned char)(CR17 | 0x80)); - - SR1F = xgifb_reg_get(pVBInfo->P3c4, 0x1F); - xgifb_reg_set(pVBInfo->P3c4, 0x1F, (unsigned char)(SR1F | 0x04)); - - SR07 = xgifb_reg_get(pVBInfo->P3c4, 0x07); - xgifb_reg_set(pVBInfo->P3c4, 0x07, (unsigned char)(SR07 & 0xFB)); - SR06 = xgifb_reg_get(pVBInfo->P3c4, 0x06); - xgifb_reg_set(pVBInfo->P3c4, 0x06, (unsigned char)(SR06 & 0xC3)); - - xgifb_reg_set(pVBInfo->P3d4, 0x11, 0x00); - - for (i = 0; i < 8; i++) - xgifb_reg_set(pVBInfo->P3d4, (unsigned short)i, CRTCData[i]); - - for (i = 8; i < 11; i++) - xgifb_reg_set(pVBInfo->P3d4, (unsigned short)(i + 8), - CRTCData[i]); - - for (i = 11; i < 13; i++) - xgifb_reg_set(pVBInfo->P3d4, (unsigned short)(i + 4), - CRTCData[i]); - - for (i = 13; i < 16; i++) - xgifb_reg_set(pVBInfo->P3c4, (unsigned short)(i - 3), - CRTCData[i]); - - xgifb_reg_set(pVBInfo->P3c4, 0x0E, (unsigned char)(CRTCData[16] - & 0xE0)); - - xgifb_reg_set(pVBInfo->P3c4, 0x31, 0x00); - xgifb_reg_set(pVBInfo->P3c4, 0x2B, 0x1B); - xgifb_reg_set(pVBInfo->P3c4, 0x2C, 0xE1); - - outb(0x00, pVBInfo->P3c8); - - for (i = 0; i < 256 * 3; i++) - outb(0x0F, (pVBInfo->P3c8 + 1)); /* DAC_TEST_PARMS */ - - mdelay(1); - - XGI_WaitDisply(pVBInfo); - temp = inb(pVBInfo->P3c2); - - if (temp & 0x10) - xgifb_reg_and_or(pVBInfo->P3d4, 0x32, 0xDF, 0x20); - else - xgifb_reg_and_or(pVBInfo->P3d4, 0x32, 0xDF, 0x00); - - /* avoid display something, set BLACK DAC if not restore DAC */ - outb(0x00, pVBInfo->P3c8); - - for (i = 0; i < 256 * 3; i++) - outb(0, (pVBInfo->P3c8 + 1)); - - xgifb_reg_set(pVBInfo->P3c4, 0x01, SR01); - xgifb_reg_set(pVBInfo->P3d4, 0x63, CR63); - xgifb_reg_set(pVBInfo->P3c4, 0x31, SR31); - - xgifb_reg_set(pVBInfo->P3d4, 0x53, (xgifb_reg_get( - pVBInfo->P3d4, 0x53) & 0xFD)); - xgifb_reg_set(pVBInfo->P3c4, 0x1F, (unsigned char)SR1F); -} - -static void XGI_EnableBridge(struct xgifb_video_info *xgifb_info, - struct xgi_hw_device_info *HwDeviceExtension, - struct vb_device_info *pVBInfo) -{ - unsigned short tempah; - - if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV - | VB_SIS302LV | VB_XGI301C)) { - if (pVBInfo->VBInfo & SetCRT2ToDualEdge) - /* Power on */ - xgifb_reg_set(pVBInfo->Part1Port, 0x1E, 0x20); - - if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToTV | - SetCRT2ToRAMDAC)) { - tempah = xgifb_reg_get(pVBInfo->P3c4, 0x32); - tempah &= 0xDF; - if (pVBInfo->VBInfo & SetInSlaveMode) { - if (!(pVBInfo->VBInfo & SetCRT2ToRAMDAC)) - tempah |= 0x20; - } - xgifb_reg_set(pVBInfo->P3c4, 0x32, tempah); - xgifb_reg_or(pVBInfo->P3c4, 0x1E, 0x20); - - tempah = xgifb_reg_get(pVBInfo->Part1Port, 0x2E); - - if (!(tempah & 0x80)) - xgifb_reg_or(pVBInfo->Part1Port, 0x2E, 0x80); - xgifb_reg_and(pVBInfo->Part1Port, 0x00, 0x7F); - } - - if (!(pVBInfo->VBInfo & DisableCRT2Display)) { - xgifb_reg_and_or(pVBInfo->Part2Port, 0x00, ~0xE0, - 0x20); /* shampoo 0129 */ - if (pVBInfo->VBType & (VB_SIS302LV | VB_XGI301C)) { - if (pVBInfo->VBInfo & - (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) - /* LVDS PLL power on */ - xgifb_reg_and(pVBInfo->Part4Port, 0x2A, - 0x7F); - /* LVDS Driver power on */ - xgifb_reg_and(pVBInfo->Part4Port, 0x30, 0x7F); - } - } - - tempah = 0x00; - - if (!(pVBInfo->VBInfo & DisableCRT2Display)) { - tempah = 0xc0; - - if (!(pVBInfo->VBInfo & SetSimuScanMode) && - (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) && - (pVBInfo->VBInfo & SetCRT2ToDualEdge)) { - tempah = tempah & 0x40; - if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) - tempah = tempah ^ 0xC0; - } - } - - /* EnablePart4_1F */ - xgifb_reg_or(pVBInfo->Part4Port, 0x1F, tempah); - - XGI_DisableGatingCRT(pVBInfo); - XGI_DisplayOn(xgifb_info, HwDeviceExtension, pVBInfo); - } /* 301 */ - else { /* LVDS */ - if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToLCD - | XGI_SetCRT2ToLCDA)) - /* enable CRT2 */ - xgifb_reg_or(pVBInfo->Part1Port, 0x1E, 0x20); - - tempah = xgifb_reg_get(pVBInfo->Part1Port, 0x2E); - if (!(tempah & 0x80)) - xgifb_reg_or(pVBInfo->Part1Port, 0x2E, 0x80); - - xgifb_reg_and(pVBInfo->Part1Port, 0x00, 0x7F); - XGI_DisplayOn(xgifb_info, HwDeviceExtension, pVBInfo); - } /* End of VB */ -} - -static void XGI_SetCRT1Group(struct xgifb_video_info *xgifb_info, - struct xgi_hw_device_info *HwDeviceExtension, - unsigned short ModeNo, unsigned short ModeIdIndex, - struct vb_device_info *pVBInfo) -{ - unsigned short RefreshRateTableIndex, temp; - - XGI_SetSeqRegs(pVBInfo); - outb(XGI330_StandTable.MISC, pVBInfo->P3c2); - XGI_SetCRTCRegs(pVBInfo); - XGI_SetATTRegs(ModeIdIndex, pVBInfo); - XGI_SetGRCRegs(pVBInfo); - XGI_ClearExt1Regs(pVBInfo); - - if (HwDeviceExtension->jChipType == XG27) { - if (pVBInfo->IF_DEF_LVDS == 0) - XGI_SetDefaultVCLK(pVBInfo); - } - - temp = ~ProgrammingCRT2; - pVBInfo->SetFlag &= temp; - pVBInfo->SelectCRT2Rate = 0; - - if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV - | VB_SIS302LV | VB_XGI301C)) { - if (pVBInfo->VBInfo & (SetSimuScanMode | XGI_SetCRT2ToLCDA - | SetInSlaveMode)) { - pVBInfo->SetFlag |= ProgrammingCRT2; - } - } - - RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo, - ModeIdIndex, pVBInfo); - if (RefreshRateTableIndex != 0xFFFF) { - XGI_SetSync(RefreshRateTableIndex, pVBInfo); - XGI_SetCRT1CRTC(ModeIdIndex, RefreshRateTableIndex, - pVBInfo, HwDeviceExtension); - XGI_SetCRT1DE(ModeIdIndex, RefreshRateTableIndex, pVBInfo); - XGI_SetCRT1Offset(ModeNo, ModeIdIndex, RefreshRateTableIndex, - HwDeviceExtension, pVBInfo); - XGI_SetCRT1VCLK(ModeIdIndex, HwDeviceExtension, - RefreshRateTableIndex, pVBInfo); - } - - if (HwDeviceExtension->jChipType >= XG21) { - temp = xgifb_reg_get(pVBInfo->P3d4, 0x38); - if (temp & 0xA0) { - if (HwDeviceExtension->jChipType == XG27) - XGI_SetXG27CRTC(RefreshRateTableIndex, pVBInfo); - else - XGI_SetXG21CRTC(RefreshRateTableIndex, pVBInfo); - - XGI_UpdateXG21CRTC(ModeNo, pVBInfo, - RefreshRateTableIndex); - - xgifb_set_lcd(HwDeviceExtension->jChipType, - pVBInfo, RefreshRateTableIndex); - - if (pVBInfo->IF_DEF_LVDS == 1) - xgifb_set_lvds(xgifb_info, - HwDeviceExtension->jChipType, - ModeIdIndex, pVBInfo); - } - } - - pVBInfo->SetFlag &= (~ProgrammingCRT2); - XGI_SetCRT1FIFO(HwDeviceExtension, pVBInfo); - XGI_SetCRT1ModeRegs(HwDeviceExtension, ModeIdIndex, - RefreshRateTableIndex, pVBInfo); - XGI_LoadDAC(pVBInfo); -} - -unsigned char XGISetModeNew(struct xgifb_video_info *xgifb_info, - struct xgi_hw_device_info *HwDeviceExtension, - unsigned short ModeNo) -{ - unsigned short ModeIdIndex; - struct vb_device_info VBINF; - struct vb_device_info *pVBInfo = &VBINF; - - pVBInfo->IF_DEF_LVDS = 0; - - if (HwDeviceExtension->jChipType >= XG20) - pVBInfo->VBType = 0; /* set VBType default 0 */ - - XGIRegInit(pVBInfo, xgifb_info->vga_base); - - /* for x86 Linux, XG21 LVDS */ - if (HwDeviceExtension->jChipType == XG21) { - if ((xgifb_reg_get(pVBInfo->P3d4, 0x38) & 0xE0) == 0xC0) - pVBInfo->IF_DEF_LVDS = 1; - } - if (HwDeviceExtension->jChipType == XG27) { - if ((xgifb_reg_get(pVBInfo->P3d4, 0x38) & 0xE0) == 0xC0) { - if (xgifb_reg_get(pVBInfo->P3d4, 0x30) & 0x20) - pVBInfo->IF_DEF_LVDS = 1; - } - } - - InitTo330Pointer(HwDeviceExtension->jChipType, pVBInfo); - if (ModeNo & 0x80) - ModeNo = ModeNo & 0x7F; - xgifb_reg_set(pVBInfo->P3c4, 0x05, 0x86); - - if (HwDeviceExtension->jChipType < XG20) - XGI_UnLockCRT2(pVBInfo); - - XGI_SearchModeID(ModeNo, &ModeIdIndex); - - if (HwDeviceExtension->jChipType < XG20) { - XGI_GetVBInfo(ModeIdIndex, pVBInfo); - XGI_GetTVInfo(ModeIdIndex, pVBInfo); - XGI_GetLCDInfo(ModeIdIndex, pVBInfo); - XGI_DisableBridge(xgifb_info, HwDeviceExtension, pVBInfo); - - if (pVBInfo->VBInfo & (SetSimuScanMode | XGI_SetCRT2ToLCDA) || - !(pVBInfo->VBInfo & SwitchCRT2)) { - XGI_SetCRT1Group(xgifb_info, HwDeviceExtension, ModeNo, - ModeIdIndex, pVBInfo); - - if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) { - XGI_SetLCDAGroup(ModeNo, ModeIdIndex, - HwDeviceExtension, pVBInfo); - } - } - - if (pVBInfo->VBInfo & (SetSimuScanMode | SwitchCRT2)) { - switch (HwDeviceExtension->ujVBChipID) { - case VB_CHIP_301: /* fall through */ - case VB_CHIP_302: - /* add for CRT2 */ - XGI_SetCRT2Group301(ModeNo, HwDeviceExtension, - pVBInfo); - break; - - default: - break; - } - } - - XGI_SetCRT2ModeRegs(pVBInfo); - XGI_OEM310Setting(ModeIdIndex, pVBInfo); /* 0212 */ - XGI_EnableBridge(xgifb_info, HwDeviceExtension, pVBInfo); - } /* !XG20 */ - else { - if (pVBInfo->IF_DEF_LVDS == 1) - if (!XGI_XG21CheckLVDSMode(xgifb_info, ModeNo, - ModeIdIndex)) - return 0; - - pVBInfo->ModeType = - XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag - & ModeTypeMask; - - pVBInfo->SetFlag = 0; - pVBInfo->VBInfo = DisableCRT2Display; - - XGI_DisplayOff(xgifb_info, HwDeviceExtension, pVBInfo); - - XGI_SetCRT1Group(xgifb_info, HwDeviceExtension, ModeNo, - ModeIdIndex, pVBInfo); - - XGI_DisplayOn(xgifb_info, HwDeviceExtension, pVBInfo); - } - - XGI_UpdateModeInfo(pVBInfo); - - if (HwDeviceExtension->jChipType < XG20) - XGI_LockCRT2(pVBInfo); - - return 1; -} diff --git a/drivers/staging/xgifb/vb_setmode.h b/drivers/staging/xgifb/vb_setmode.h deleted file mode 100644 index 5904ed1f2686..000000000000 --- a/drivers/staging/xgifb/vb_setmode.h +++ /dev/null @@ -1,24 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef _VBSETMODE_ -#define _VBSETMODE_ - -void InitTo330Pointer(unsigned char ChipType, struct vb_device_info *pVBInfo); -void XGI_UnLockCRT2(struct vb_device_info *pVBInfo); -void XGI_LockCRT2(struct vb_device_info *pVBInfo); -void XGI_DisplayOff(struct xgifb_video_info *xgifb_info, - struct xgi_hw_device_info *pXGIHWDE, - struct vb_device_info *pVBInfo); -void XGI_GetVBType(struct vb_device_info *pVBInfo); -void XGI_SenseCRT1(struct vb_device_info *pVBInfo); -unsigned char XGISetModeNew(struct xgifb_video_info *xgifb_info, - struct xgi_hw_device_info *HwDeviceExtension, - unsigned short ModeNo); - -unsigned char XGI_SearchModeID(unsigned short ModeNo, - unsigned short *ModeIdIndex); -unsigned short XGI_GetRatePtrCRT2(struct xgi_hw_device_info *pXGIHWDE, - unsigned short ModeNo, - unsigned short ModeIdIndex, - struct vb_device_info *pVBInfo); - -#endif diff --git a/drivers/staging/xgifb/vb_struct.h b/drivers/staging/xgifb/vb_struct.h deleted file mode 100644 index e256f72f6d8a..000000000000 --- a/drivers/staging/xgifb/vb_struct.h +++ /dev/null @@ -1,165 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef _VB_STRUCT_ -#define _VB_STRUCT_ -#include "../../video/fbdev/sis/vstruct.h" - -struct XGI_LVDSCRT1HDataStruct { - unsigned char Reg[8]; -}; - -struct XGI_LVDSCRT1VDataStruct { - unsigned char Reg[7]; -}; - -struct XGI_ExtStruct { - unsigned char Ext_ModeID; - unsigned short Ext_ModeFlag; - unsigned short Ext_ModeInfo; - unsigned char Ext_RESINFO; - unsigned char VB_ExtTVYFilterIndex; - unsigned char REFindex; -}; - -struct XGI_Ext2Struct { - unsigned short Ext_InfoFlag; - unsigned char Ext_CRT1CRTC; - unsigned char Ext_CRTVCLK; - unsigned char Ext_CRT2CRTC; - unsigned char Ext_CRT2CRTC2; - unsigned char ModeID; - unsigned short XRes; - unsigned short YRes; -}; - -struct XGI_ECLKDataStruct { - unsigned char SR2E, SR2F, SR30; - unsigned short CLOCK; -}; - -/*add for new UNIVGABIOS*/ -struct XGI_LCDDesStruct { - unsigned short LCDHDES; - unsigned short LCDHRS; - unsigned short LCDVDES; - unsigned short LCDVRS; -}; - -struct XGI330_LCDDataDesStruct2 { - unsigned short LCDHDES; - unsigned short LCDHRS; - unsigned short LCDVDES; - unsigned short LCDVRS; - unsigned short LCDHSync; - unsigned short LCDVSync; -}; - -struct XGI330_LCDDataTablStruct { - unsigned char PANELID; - unsigned short MASK; - unsigned short CAP; - void const *DATAPTR; -}; - -struct XGI330_TVDataTablStruct { - unsigned short MASK; - unsigned short CAP; - struct SiS_TVData const *DATAPTR; -}; - -struct XGI_TimingHStruct { - unsigned char data[8]; -}; - -struct XGI_TimingVStruct { - unsigned char data[7]; -}; - -struct XGI_XG21CRT1Struct { - unsigned char ModeID, CR02, CR03, CR15, CR16; -}; - -struct XGI330_LCDCapStruct { - unsigned char LCD_ID; - unsigned short LCD_Capability; - unsigned char LCD_HSyncWidth; - unsigned char LCD_VSyncWidth; - unsigned char LCD_VCLK; - unsigned char LCDA_VCLKData1; - unsigned char LCDA_VCLKData2; - unsigned char LCUCHAR_VCLKData1; - unsigned char LCUCHAR_VCLKData2; - unsigned char Spectrum_31; - unsigned char Spectrum_32; - unsigned char Spectrum_33; - unsigned char Spectrum_34; -}; - -struct XGI21_LVDSCapStruct { - unsigned short LVDS_Capability; - unsigned short LVDSHT; - unsigned short LVDSVT; - unsigned short LVDSHDE; - unsigned short LVDSVDE; - unsigned short LVDSHFP; - unsigned short LVDSVFP; - unsigned short LVDSHSYNC; - unsigned short LVDSVSYNC; - unsigned char VCLKData1; - unsigned char VCLKData2; - unsigned char PSC_S1; /* Duration between CPL on and signal on */ - unsigned char PSC_S2; /* Duration signal on and Vdd on */ - unsigned char PSC_S3; /* Duration between CPL off and signal off */ - unsigned char PSC_S4; /* Duration signal off and Vdd off */ - unsigned char PSC_S5; -}; - -struct XGI_CRT1TableStruct { - unsigned char CR[16]; -}; - -struct XGI301C_Tap4TimingStruct { - unsigned short DE; - unsigned char Reg[64]; /* C0-FF */ -}; - -struct vb_device_info { - unsigned long P3c4, P3d4, P3c0, P3ce, P3c2, P3cc; - unsigned long P3ca, P3c6, P3c7, P3c8, P3c9, P3da; - unsigned long Part0Port, Part1Port, Part2Port; - unsigned long Part3Port, Part4Port, Part5Port; - unsigned short RVBHCFACT, RVBHCMAX, RVBHRS; - unsigned short VGAVT, VGAHT, VGAVDE, VGAHDE; - unsigned short VT, HT, VDE, HDE; - unsigned short LCDHRS, LCDVRS, LCDHDES, LCDVDES; - - unsigned short ModeType; - unsigned short IF_DEF_LVDS; - unsigned short IF_DEF_CRT2Monitor; - unsigned short IF_DEF_YPbPr; - unsigned short IF_DEF_HiVision; - unsigned short LCDResInfo, LCDTypeInfo, VBType;/*301b*/ - unsigned short VBInfo, TVInfo, LCDInfo; - unsigned short SetFlag; - unsigned short NewFlickerMode; - unsigned short SelectCRT2Rate; - - void __iomem *FBAddr; - - unsigned char const *SR18; - unsigned char const (*CR40)[3]; - - struct SiS_MCLKData const *MCLKData; - - unsigned char XGINew_CR97; - - struct XGI330_LCDCapStruct const *LCDCapList; - - struct XGI_TimingHStruct TimingH; - struct XGI_TimingVStruct TimingV; - - int ram_type; - int ram_channel; - int ram_bus; -}; /* _struct vb_device_info */ - -#endif /* _VB_STRUCT_ */ diff --git a/drivers/staging/xgifb/vb_table.h b/drivers/staging/xgifb/vb_table.h deleted file mode 100644 index 42ecf7fe6766..000000000000 --- a/drivers/staging/xgifb/vb_table.h +++ /dev/null @@ -1,2513 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef _VB_TABLE_ -#define _VB_TABLE_ -static const struct SiS_MCLKData XGI340New_MCLKData[] = { - {0x16, 0x01, 0x01, 166}, - {0x19, 0x02, 0x01, 124}, - {0x7C, 0x08, 0x01, 200}, -}; - -static const struct SiS_MCLKData XGI27New_MCLKData[] = { - {0x5c, 0x23, 0x01, 166}, - {0x19, 0x02, 0x01, 124}, - {0x7C, 0x08, 0x80, 200}, -}; - -const struct XGI_ECLKDataStruct XGI340_ECLKData[] = { - {0x5c, 0x23, 0x01, 166}, - {0x55, 0x84, 0x01, 123}, - {0x7C, 0x08, 0x01, 200}, -}; - -static const unsigned char XG27_SR18[3] = { - 0x32, 0x32, 0x42 /* SR18 */ -}; - -static const unsigned char XGI340_SR18[3] = { - 0x31, 0x42, 0x42 /* SR18 */ -}; - -static const unsigned char XGI340_cr41[24][3] = { - {0x20, 0x50, 0x60}, /* 0 CR41 */ - {0xc4, 0x40, 0x84}, /* 1 CR8A */ - {0xc4, 0x40, 0x84}, /* 2 CR8B */ - {0xb5, 0xa4, 0xa4}, - {0xf0, 0xf0, 0xf0}, - {0x90, 0x90, 0x24}, /* 5 CR68 */ - {0x77, 0x77, 0x44}, /* 6 CR69 */ - {0x77, 0x77, 0x44}, /* 7 CR6A */ - {0xff, 0xff, 0xff}, /* 8 CR6D */ - {0x55, 0x55, 0x55}, /* 9 CR80 */ - {0x00, 0x00, 0x00}, /* 10 CR81 */ - {0x88, 0xa8, 0x48}, /* 11 CR82 */ - {0x44, 0x44, 0x77}, /* 12 CR85 */ - {0x48, 0x48, 0x88}, /* 13 CR86 */ - {0x54, 0x54, 0x44}, /* 14 CR90 */ - {0x54, 0x54, 0x44}, /* 15 CR91 */ - {0x0a, 0x0a, 0x07}, /* 16 CR92 */ - {0x44, 0x44, 0x44}, /* 17 CR93 */ - {0x10, 0x10, 0x0A}, /* 18 CR94 */ - {0x11, 0x11, 0x0a}, /* 19 CR95 */ - {0x05, 0x05, 0x05}, /* 20 CR96 */ - {0xf0, 0xf0, 0xf0}, /* 21 CRC3 */ - {0x05, 0x00, 0x02}, /* 22 CRC4 */ - {0x00, 0x00, 0x00} /* 23 CRC5 */ -}; - -static const unsigned char XGI27_cr41[24][3] = { - {0x20, 0x40, 0x60}, /* 0 CR41 */ - {0xC4, 0x40, 0x84}, /* 1 CR8A */ - {0xC4, 0x40, 0x84}, /* 2 CR8B */ - {0xB3, 0x13, 0xa4}, /* 3 CR40[7], - * CR99[2:0], - * CR45[3:0] - */ - {0xf0, 0xf5, 0xf0}, /* 4 CR59 */ - {0x90, 0x90, 0x24}, /* 5 CR68 */ - {0x77, 0x67, 0x44}, /* 6 CR69 */ - {0x77, 0x77, 0x44}, /* 7 CR6A */ - {0xff, 0xff, 0xff}, /* 8 CR6D */ - {0x55, 0x55, 0x55}, /* 9 CR80 */ - {0x00, 0x00, 0x00}, /* 10 CR81 */ - {0x88, 0xcc, 0x48}, /* 11 CR82 */ - {0x44, 0x88, 0x77}, /* 12 CR85 */ - {0x48, 0x88, 0x88}, /* 13 CR86 */ - {0x54, 0x32, 0x44}, /* 14 CR90 */ - {0x54, 0x33, 0x44}, /* 15 CR91 */ - {0x0a, 0x07, 0x07}, /* 16 CR92 */ - {0x44, 0x63, 0x44}, /* 17 CR93 */ - {0x10, 0x14, 0x0A}, /* 18 CR94 */ - {0x11, 0x0B, 0x0C}, /* 19 CR95 */ - {0x05, 0x22, 0x05}, /* 20 CR96 */ - {0xf0, 0xf0, 0x00}, /* 21 CRC3 */ - {0x05, 0x00, 0x02}, /* 22 CRC4 */ - {0x00, 0x00, 0x00} /* 23 CRC5 */ -}; - -/* CR47,CR48,CR49,CR4A,CR4B,CR4C,CR70,CR71,CR74,CR75,CR76,CR77 */ -const unsigned char XGI340_AGPReg[12] = { - 0x28, 0x23, 0x00, 0x20, 0x00, 0x20, - 0x00, 0x05, 0xd0, 0x10, 0x10, 0x00 -}; - -const struct XGI_ExtStruct XGI330_EModeIDTable[] = { - {0x2e, 0x0a1b, 0x0306, 0x06, 0x05, 0x06}, - {0x2f, 0x0a1b, 0x0305, 0x05, 0x05, 0x05}, - {0x30, 0x2a1b, 0x0407, 0x07, 0x07, 0x0e}, - {0x31, 0x0a1b, 0x030d, 0x0d, 0x06, 0x3d}, - {0x32, 0x0a1b, 0x0a0e, 0x0e, 0x06, 0x3e}, - {0x33, 0x0a1d, 0x0a0d, 0x0d, 0x06, 0x3d}, - {0x34, 0x2a1d, 0x0a0e, 0x0e, 0x06, 0x3e}, - {0x35, 0x0a1f, 0x0a0d, 0x0d, 0x06, 0x3d}, - {0x36, 0x2a1f, 0x0a0e, 0x0e, 0x06, 0x3e}, - {0x38, 0x0a1b, 0x0508, 0x08, 0x00, 0x16}, - {0x3a, 0x0e3b, 0x0609, 0x09, 0x00, 0x1e}, - {0x3c, 0x0e3b, 0x070a, 0x0a, 0x00, 0x22}, /* mode 1600x1200 - * add CRT2MODE [2003/10/07] - */ - {0x3d, 0x0e7d, 0x070a, 0x0a, 0x00, 0x22}, /* mode 1600x1200 - * add CRT2MODE - */ - {0x40, 0x9a1c, 0x0000, 0x00, 0x04, 0x00}, - {0x41, 0x9a1d, 0x0000, 0x00, 0x04, 0x00}, - {0x43, 0x0a1c, 0x0306, 0x06, 0x05, 0x06}, - {0x44, 0x0a1d, 0x0306, 0x06, 0x05, 0x06}, - {0x46, 0x2a1c, 0x0407, 0x07, 0x07, 0x0e}, - {0x47, 0x2a1d, 0x0407, 0x07, 0x07, 0x0e}, - {0x49, 0x0a3c, 0x0508, 0x08, 0x00, 0x16}, - {0x4a, 0x0a3d, 0x0508, 0x08, 0x00, 0x16}, - {0x4c, 0x0e7c, 0x0609, 0x09, 0x00, 0x1e}, - {0x4d, 0x0e7d, 0x0609, 0x09, 0x00, 0x1e}, - {0x50, 0x9a1b, 0x0001, 0x01, 0x04, 0x02}, - {0x51, 0xba1b, 0x0103, 0x03, 0x07, 0x03}, - {0x52, 0x9a1b, 0x0204, 0x04, 0x00, 0x04}, - {0x56, 0x9a1d, 0x0001, 0x01, 0x04, 0x02}, - {0x57, 0xba1d, 0x0103, 0x03, 0x07, 0x03}, - {0x58, 0x9a1d, 0x0204, 0x04, 0x00, 0x04}, - {0x59, 0x9a1b, 0x0000, 0x00, 0x04, 0x00}, - {0x5A, 0x021b, 0x0014, 0x01, 0x04, 0x3f}, - {0x5B, 0x0a1d, 0x0014, 0x01, 0x04, 0x3f}, - {0x5d, 0x0a1d, 0x0305, 0x05, 0x07, 0x05}, - {0x62, 0x0a3f, 0x0306, 0x06, 0x05, 0x06}, - {0x63, 0x2a3f, 0x0407, 0x07, 0x07, 0x0e}, - {0x64, 0x0a7f, 0x0508, 0x08, 0x00, 0x16}, - {0x65, 0x0eff, 0x0609, 0x09, 0x00, 0x1e}, - {0x66, 0x0eff, 0x070a, 0x0a, 0x00, 0x22}, /* mode 1600x1200 - * add CRT2MODE - */ - {0x68, 0x067b, 0x080b, 0x0b, 0x00, 0x29}, - {0x69, 0x06fd, 0x080b, 0x0b, 0x00, 0x29}, - {0x6b, 0x07ff, 0x080b, 0x0b, 0x00, 0x29}, - {0x6c, 0x067b, 0x090c, 0x0c, 0x00, 0x2f}, - {0x6d, 0x06fd, 0x090c, 0x0c, 0x00, 0x2f}, - {0x6e, 0x07ff, 0x090c, 0x0c, 0x00, 0x2f}, - {0x70, 0x2a1b, 0x0410, 0x10, 0x07, 0x34}, - {0x71, 0x0a1b, 0x0511, 0x11, 0x00, 0x37}, - {0x74, 0x0a1d, 0x0511, 0x11, 0x00, 0x37}, - {0x75, 0x0a3d, 0x0612, 0x12, 0x00, 0x3a}, - {0x76, 0x2a1f, 0x0410, 0x10, 0x07, 0x34}, - {0x77, 0x0a1f, 0x0511, 0x11, 0x00, 0x37}, - {0x78, 0x0a3f, 0x0612, 0x12, 0x00, 0x3a}, - {0x79, 0x0a3b, 0x0612, 0x12, 0x00, 0x3a}, - {0x7a, 0x2a1d, 0x0410, 0x10, 0x07, 0x34}, - {0x7b, 0x0e3b, 0x060f, 0x0f, 0x00, 0x1d}, - {0x7c, 0x0e7d, 0x060f, 0x0f, 0x00, 0x1d}, - {0x7d, 0x0eff, 0x060f, 0x0f, 0x00, 0x1d}, - {0x20, 0x0e3b, 0x0D16, 0x16, 0x00, 0x43}, - {0x21, 0x0e7d, 0x0D16, 0x16, 0x00, 0x43}, - {0x22, 0x0eff, 0x0D16, 0x16, 0x00, 0x43}, - {0x23, 0x0e3b, 0x0614, 0x14, 0x00, 0x41}, - {0x24, 0x0e7d, 0x0614, 0x14, 0x00, 0x41}, - {0x25, 0x0eff, 0x0614, 0x14, 0x00, 0x41}, - {0x26, 0x063b, 0x0c15, 0x15, 0x00, 0x42}, - {0x27, 0x067d, 0x0c15, 0x15, 0x00, 0x42}, - {0x28, 0x06ff, 0x0c15, 0x15, 0x00, 0x42}, - {0xff, 0x0000, 0x0000, 0x00, 0x00, 0x00} -}; - -static const struct SiS_StandTable_S XGI330_StandTable = { -/* ExtVGATable */ - 0x00, 0x00, 0x00, 0x0000, - {0x21, 0x0f, 0x00, 0x0e}, /* 0x21 = 0x01 | (0x20 = screen off) */ - 0x23, - {0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0x0b, 0x3e, - 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xea, 0x8c, 0xdf, 0x28, 0x40, 0xe7, 0x04, 0xa3, - 0xff}, - {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x01, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0f, - 0xff} -}; - -static const struct XGI_XG21CRT1Struct XGI_UpdateCRT1Table[] = { - {0x01, 0x27, 0x91, 0x8f, 0xc0}, /* 00 */ - {0x03, 0x4f, 0x83, 0x8f, 0xc0}, /* 01 */ - {0x05, 0x27, 0x91, 0x8f, 0xc0}, /* 02 */ - {0x06, 0x4f, 0x83, 0x8f, 0xc0}, /* 03 */ - {0x07, 0x4f, 0x83, 0x8f, 0xc0}, /* 04 */ - {0x0d, 0x27, 0x91, 0x8f, 0xc0}, /* 05 */ - {0x0e, 0x4f, 0x83, 0x8f, 0xc0}, /* 06 */ - {0x0f, 0x4f, 0x83, 0x5d, 0xc0}, /* 07 */ - {0x10, 0x4f, 0x83, 0x5d, 0xc0}, /* 08 */ - {0x11, 0x4f, 0x83, 0xdf, 0x0c}, /* 09 */ - {0x12, 0x4f, 0x83, 0xdf, 0x0c}, /* 10 */ - {0x13, 0x4f, 0x83, 0x8f, 0xc0}, /* 11 */ - {0x2e, 0x4f, 0x83, 0xdf, 0x0c}, /* 12 */ - {0x2e, 0x4f, 0x87, 0xdf, 0xc0}, /* 13 */ - {0x2f, 0x4f, 0x83, 0x8f, 0xc0}, /* 14 */ - {0x50, 0x27, 0x91, 0xdf, 0x0c}, /* 15 */ - {0x59, 0x27, 0x91, 0x8f, 0xc0} /* 16 */ -}; - -const struct XGI_CRT1TableStruct XGI_CRT1Table[] = { - { {0x2d, 0x28, 0x90, 0x2c, 0x90, 0x00, 0x04, 0x00, - 0xbf, 0x1f, 0x9c, 0x8e, 0x96, 0xb9, 0x30} }, /* 0x0 */ - { {0x2d, 0x28, 0x90, 0x2c, 0x90, 0x00, 0x04, 0x00, - 0x0b, 0x3e, 0xe9, 0x8b, 0xe7, 0x04, 0x00} }, /* 0x1 */ - { {0x3D, 0x31, 0x81, 0x37, 0x1F, 0x00, 0x05, 0x00, - 0x72, 0xF0, 0x58, 0x8C, 0x57, 0x73, 0xA0} }, /* 0x2 */ - { {0x4F, 0x3F, 0x93, 0x45, 0x0D, 0x00, 0x01, 0x00, - 0x24, 0xF5, 0x02, 0x88, 0xFF, 0x25, 0x90} }, /* 0x3 */ - { {0x5F, 0x50, 0x82, 0x55, 0x81, 0x00, 0x05, 0x00, - 0xBF, 0x1F, 0x9C, 0x8E, 0x96, 0xB9, 0x30} }, /* 0x4 */ - { {0x5F, 0x50, 0x82, 0x55, 0x81, 0x00, 0x05, 0x00, - 0x0B, 0x3E, 0xE9, 0x8B, 0xE7, 0x04, 0x00} }, /* 0x5 */ - { {0x63, 0x50, 0x86, 0x56, 0x9B, 0x00, 0x01, 0x00, - 0x06, 0x3E, 0xE8, 0x8B, 0xE7, 0xFF, 0x10} }, /* 0x6 */ - { {0x64, 0x4F, 0x88, 0x55, 0x9D, 0x00, 0x01, 0x00, - 0xF2, 0x1F, 0xE0, 0x83, 0xDF, 0xF3, 0x10} }, /* 0x7 */ - { {0x63, 0x4F, 0x87, 0x5A, 0x81, 0x00, 0x05, 0x00, - 0xFB, 0x1F, 0xE0, 0x83, 0xDF, 0xFC, 0x10} }, /* 0x8 */ - { {0x65, 0x4F, 0x89, 0x58, 0x80, 0x00, 0x05, 0x60, - 0xFB, 0x1F, 0xE0, 0x83, 0xDF, 0xFC, 0x80} }, /* 0x9 */ - { {0x65, 0x4F, 0x89, 0x58, 0x80, 0x00, 0x05, 0x60, - 0x01, 0x3E, 0xE0, 0x83, 0xDF, 0x02, 0x80} }, /* 0xa */ - { {0x67, 0x4F, 0x8B, 0x58, 0x81, 0x00, 0x05, 0x60, - 0x0D, 0x3E, 0xE0, 0x83, 0xDF, 0x0E, 0x90} }, /* 0xb */ - { {0x65, 0x4F, 0x89, 0x57, 0x9F, 0x00, 0x01, 0x00, - 0xFB, 0x1F, 0xE6, 0x8A, 0xDF, 0xFC, 0x10} }, /* 0xc */ - /* 0D (800x600,56Hz) */ - { {0x7B, 0x63, 0x9F, 0x6A, 0x93, 0x00, 0x05, 0x00, - /* (VCLK 36.0MHz) */ - 0x6F, 0xF0, 0x58, 0x8A, 0x57, 0x70, 0xA0} }, - /* 0E (800x600,60Hz) */ - { {0x7F, 0x63, 0x83, 0x6C, 0x1C, 0x00, 0x06, 0x00, - /* (VCLK 40.0MHz) */ - 0x72, 0xF0, 0x58, 0x8C, 0x57, 0x73, 0xA0} }, - /* 0F (800x600,72Hz) */ - { {0x7D, 0x63, 0x81, 0x6E, 0x1D, 0x00, 0x06, 0x00, - /* (VCLK 50.0MHz) */ - 0x98, 0xF0, 0x7C, 0x82, 0x57, 0x99, 0x80} }, - /* 10 (800x600,75Hz) */ - { {0x7F, 0x63, 0x83, 0x69, 0x13, 0x00, 0x06, 0x00, - /* (VCLK 49.5MHz) */ - 0x6F, 0xF0, 0x58, 0x8B, 0x57, 0x70, 0xA0} }, - /* 11 (800x600,85Hz) */ - { {0x7E, 0x63, 0x82, 0x6B, 0x13, 0x00, 0x06, 0x00, - /* (VCLK 56.25MHz) */ - 0x75, 0xF0, 0x58, 0x8B, 0x57, 0x76, 0xA0} }, - /* 12 (800x600,100Hz) */ - { {0x81, 0x63, 0x85, 0x6D, 0x18, 0x00, 0x06, 0x60, - /* (VCLK 75.8MHz) */ - 0x7A, 0xF0, 0x58, 0x8B, 0x57, 0x7B, 0xA0} }, - /* 13 (800x600,120Hz) */ - { {0x83, 0x63, 0x87, 0x6E, 0x19, 0x00, 0x06, 0x60, - /* (VCLK 79.411MHz) */ - 0x81, 0xF0, 0x58, 0x8B, 0x57, 0x82, 0xA0} }, - /* 14 (800x600,160Hz) */ - { {0x85, 0x63, 0x89, 0x6F, 0x1A, 0x00, 0x06, 0x60, - /* (VCLK 105.822MHz) */ - 0x91, 0xF0, 0x58, 0x8B, 0x57, 0x92, 0xA0} }, - { {0x99, 0x7F, 0x9D, 0x84, 0x1A, 0x00, 0x02, 0x00, - 0x96, 0x1F, 0x7F, 0x83, 0x7F, 0x97, 0x10} }, /* 0x15 */ - { {0xA3, 0x7F, 0x87, 0x86, 0x97, 0x00, 0x02, 0x00, - 0x24, 0xF5, 0x02, 0x88, 0xFF, 0x25, 0x90} }, /* 0x16 */ - { {0xA1, 0x7F, 0x85, 0x86, 0x97, 0x00, 0x02, 0x00, - 0x24, 0xF5, 0x02, 0x88, 0xFF, 0x25, 0x90} }, /* 0x17 */ - { {0x9F, 0x7F, 0x83, 0x85, 0x91, 0x00, 0x02, 0x00, - 0x1E, 0xF5, 0x00, 0x83, 0xFF, 0x1F, 0x90} }, /* 0x18 */ - { {0xA7, 0x7F, 0x8B, 0x89, 0x95, 0x00, 0x02, 0x00, - 0x26, 0xF5, 0x00, 0x83, 0xFF, 0x27, 0x90} }, /* 0x19 */ - { {0xA9, 0x7F, 0x8D, 0x8C, 0x9A, 0x00, 0x02, 0x62, - 0x2C, 0xF5, 0x00, 0x83, 0xFF, 0x2D, 0x14} }, /* 0x1a */ - { {0xAB, 0x7F, 0x8F, 0x8D, 0x9B, 0x00, 0x02, 0x62, - 0x35, 0xF5, 0x00, 0x83, 0xFF, 0x36, 0x14} }, /* 0x1b */ - { {0xCF, 0x9F, 0x93, 0xB2, 0x01, 0x00, 0x03, 0x00, - 0x14, 0xBA, 0x00, 0x83, 0xFF, 0x15, 0x00} }, /* 0x1c */ - { {0xCE, 0x9F, 0x92, 0xA9, 0x17, 0x00, 0x07, 0x00, - 0x28, 0x5A, 0x00, 0x83, 0xFF, 0x29, 0x89} }, /* 0x1d */ - { {0xCE, 0x9F, 0x92, 0xA5, 0x17, 0x00, 0x07, 0x00, - 0x28, 0x5A, 0x00, 0x83, 0xFF, 0x29, 0x89} }, /* 0x1e */ - { {0xD3, 0x9F, 0x97, 0xAB, 0x1F, 0x00, 0x07, 0x00, - 0x2E, 0x5A, 0x00, 0x83, 0xFF, 0x2F, 0x89} }, /* 0x1f */ - { {0x09, 0xC7, 0x8D, 0xD3, 0x0B, 0x01, 0x04, 0x00, - 0xE0, 0x10, 0xB0, 0x83, 0xAF, 0xE1, 0x2F} }, /* 0x20 */ - { {0x09, 0xC7, 0x8D, 0xD3, 0x0B, 0x01, 0x04, 0x00, - 0xE0, 0x10, 0xB0, 0x83, 0xAF, 0xE1, 0x2F} }, /* 0x21 */ - { {0x09, 0xC7, 0x8D, 0xD3, 0x0B, 0x01, 0x04, 0x00, - 0xE0, 0x10, 0xB0, 0x83, 0xAF, 0xE1, 0x2F} }, /* 0x22 */ - { {0x09, 0xC7, 0x8D, 0xD3, 0x0B, 0x01, 0x04, 0x00, - 0xE0, 0x10, 0xB0, 0x83, 0xAF, 0xE1, 0x2F} }, /* 0x23 */ - { {0x09, 0xC7, 0x8D, 0xD3, 0x0B, 0x01, 0x04, 0x00, - 0xE0, 0x10, 0xB0, 0x83, 0xAF, 0xE1, 0x2F} }, /* 0x24 */ - { {0x09, 0xC7, 0x8D, 0xD3, 0x0B, 0x01, 0x04, 0x00, - 0xE0, 0x10, 0xB0, 0x83, 0xAF, 0xE1, 0x2F} }, /* 0x25 */ - { {0x09, 0xC7, 0x8D, 0xD3, 0x0B, 0x01, 0x04, 0x00, - 0xE0, 0x10, 0xB0, 0x83, 0xAF, 0xE1, 0x2F} }, /* 0x26 */ - { {0x40, 0xEF, 0x84, 0x03, 0x1D, 0x41, 0x01, 0x00, - 0xDA, 0x1F, 0xA0, 0x83, 0x9F, 0xDB, 0x1F} }, /* 0x27 */ - { {0x43, 0xEF, 0x87, 0x06, 0x00, 0x41, 0x05, 0x62, - 0xD4, 0x1F, 0xA0, 0x83, 0x9F, 0xD5, 0x9F} }, /* 0x28 */ - { {0x45, 0xEF, 0x89, 0x07, 0x01, 0x41, 0x05, 0x62, - 0xD9, 0x1F, 0xA0, 0x83, 0x9F, 0xDA, 0x9F} }, /* 0x29 */ - { {0x40, 0xEF, 0x84, 0x03, 0x1D, 0x41, 0x01, 0x00, - 0xDA, 0x1F, 0xA0, 0x83, 0x9F, 0xDB, 0x1F} }, /* 0x2a */ - { {0x40, 0xEF, 0x84, 0x03, 0x1D, 0x41, 0x01, 0x00, - 0xDA, 0x1F, 0xA0, 0x83, 0x9F, 0xDB, 0x1F} }, /* 0x2b */ - { {0x40, 0xEF, 0x84, 0x03, 0x1D, 0x41, 0x01, 0x00, - 0xDA, 0x1F, 0xA0, 0x83, 0x9F, 0xDB, 0x1F} }, /* 0x2c */ - { {0x59, 0xFF, 0x9D, 0x17, 0x13, 0x41, 0x05, 0x44, - 0x33, 0xBA, 0x00, 0x83, 0xFF, 0x34, 0x0F} }, /* 0x2d */ - { {0x5B, 0xFF, 0x9F, 0x18, 0x14, 0x41, 0x05, 0x44, - 0x38, 0xBA, 0x00, 0x83, 0xFF, 0x39, 0x0F} }, /* 0x2e */ - { {0x5B, 0xFF, 0x9F, 0x18, 0x14, 0x41, 0x05, 0x44, - 0x3D, 0xBA, 0x00, 0x83, 0xFF, 0x3E, 0x0F} }, /* 0x2f */ - { {0x5D, 0xFF, 0x81, 0x19, 0x95, 0x41, 0x05, 0x44, - 0x41, 0xBA, 0x00, 0x84, 0xFF, 0x42, 0x0F} }, /* 0x30 */ - { {0x55, 0xFF, 0x99, 0x0D, 0x0C, 0x41, 0x05, 0x00, - 0x3E, 0xBA, 0x00, 0x84, 0xFF, 0x3F, 0x0F} }, /* 0x31 */ - { {0x7F, 0x63, 0x83, 0x6C, 0x1C, 0x00, 0x06, 0x00, - 0x72, 0xBA, 0x27, 0x8B, 0xDF, 0x73, 0x80} }, /* 0x32 */ - { {0x7F, 0x63, 0x83, 0x69, 0x13, 0x00, 0x06, 0x00, - 0x6F, 0xBA, 0x26, 0x89, 0xDF, 0x6F, 0x80} }, /* 0x33 */ - { {0x7F, 0x63, 0x82, 0x6B, 0x13, 0x00, 0x06, 0x00, - 0x75, 0xBA, 0x29, 0x8C, 0xDF, 0x75, 0x80} }, /* 0x34 */ - { {0xA3, 0x7F, 0x87, 0x86, 0x97, 0x00, 0x02, 0x00, - 0x24, 0xF1, 0xAF, 0x85, 0x3F, 0x25, 0xB0} }, /* 0x35 */ - { {0x9F, 0x7F, 0x83, 0x85, 0x91, 0x00, 0x02, 0x00, - 0x1E, 0xF1, 0xAD, 0x81, 0x3F, 0x1F, 0xB0} }, /* 0x36 */ - { {0xA7, 0x7F, 0x88, 0x89, 0x15, 0x00, 0x02, 0x00, - 0x26, 0xF1, 0xB1, 0x85, 0x3F, 0x27, 0xB0} }, /* 0x37 */ - { {0xCE, 0x9F, 0x92, 0xA9, 0x17, 0x00, 0x07, 0x00, - 0x28, 0xC4, 0x7A, 0x8E, 0xCF, 0x29, 0xA1} }, /* 0x38 */ - { {0xCE, 0x9F, 0x92, 0xA5, 0x17, 0x00, 0x07, 0x00, - 0x28, 0xD4, 0x7A, 0x8E, 0xCF, 0x29, 0xA1} }, /* 0x39 */ - { {0xD3, 0x9F, 0x97, 0xAB, 0x1F, 0x00, 0x07, 0x00, - 0x2E, 0xD4, 0x7D, 0x81, 0xCF, 0x2F, 0xA1} }, /* 0x3a */ - { {0xDC, 0x9F, 0x00, 0xAB, 0x19, 0x00, 0x07, 0x00, - 0xE6, 0xEF, 0xC0, 0xC3, 0xBF, 0xE7, 0x90} }, /* 0x3b */ - { {0x6B, 0x59, 0x8F, 0x5E, 0x8C, 0x00, 0x05, 0x00, - 0x0B, 0x3E, 0xE9, 0x8B, 0xE7, 0x04, 0x00} }, /* 0x3c */ - { {0x7B, 0x63, 0x9F, 0x6A, 0x93, 0x00, 0x05, 0x00, - 0x6F, 0xF0, 0x58, 0x8A, 0x57, 0x70, 0xA0} }, /* 0x3d */ - { {0x86, 0x6A, 0x8a, 0x74, 0x06, 0x00, 0x02, 0x00, - 0x8c, 0x15, 0x4f, 0x83, 0xef, 0x8d, 0x30} }, /* 0x3e */ - { {0x81, 0x6A, 0x85, 0x70, 0x00, 0x00, 0x02, 0x00, - 0x0f, 0x3e, 0xeb, 0x8e, 0xdf, 0x10, 0x00} }, /* 0x3f */ - { {0xCE, 0x9F, 0x92, 0xA9, 0x17, 0x00, 0x07, 0x00, - 0x20, 0xF5, 0x03, 0x88, 0xFF, 0x21, 0x90} }, /* 0x40 */ - { {0xE6, 0xAE, 0x8A, 0xBD, 0x90, 0x00, 0x03, 0x00, - 0x3D, 0x10, 0x1A, 0x8D, 0x19, 0x3E, 0x2F} }, /* 0x41 */ - { {0xB9, 0x8F, 0x9D, 0x9B, 0x8A, 0x00, 0x06, 0x00, - 0x7D, 0xFF, 0x60, 0x83, 0x5F, 0x7E, 0x90} }, /* 0x42 */ - { {0xC3, 0x8F, 0x87, 0x9B, 0x0B, 0x00, 0x07, 0x00, - 0x82, 0xFF, 0x60, 0x83, 0x5F, 0x83, 0x90} }, /* 0x43 */ - { {0xAD, 0x7F, 0x91, 0x8E, 0x9C, 0x00, 0x02, 0x82, - 0x49, 0xF5, 0x00, 0x83, 0xFF, 0x4A, 0x90} }, /* 0x44 */ - { {0xCD, 0x9F, 0x91, 0xA7, 0x19, 0x00, 0x07, 0x60, - 0xE6, 0xFF, 0xC0, 0x83, 0xBF, 0xE7, 0x90} }, /* 0x45 */ - { {0xD3, 0x9F, 0x97, 0xAB, 0x1F, 0x00, 0x07, 0x60, - 0xF1, 0xFF, 0xC0, 0x83, 0xBF, 0xF2, 0x90} }, /* 0x46 */ - { {0xD7, 0x9F, 0x9B, 0xAC, 0x1E, 0x00, 0x07, 0x00, - 0x03, 0xDE, 0xC0, 0x84, 0xBF, 0x04, 0x90} } /* 0x47 */ -}; - -/*add for new UNIVGABIOS*/ -static const struct SiS_LCDData XGI_StLCD1024x768Data[] = { - {62, 25, 800, 546, 1344, 806}, - {32, 15, 930, 546, 1344, 806}, - {62, 25, 800, 546, 1344, 806}, /*chiawenfordot9->dot8*/ - {104, 45, 945, 496, 1344, 806}, - {62, 25, 800, 546, 1344, 806}, - {31, 18, 1008, 624, 1344, 806}, - {1, 1, 1344, 806, 1344, 806} -}; - -static const struct SiS_LCDData XGI_ExtLCD1024x768Data[] = { - {42, 25, 1536, 419, 1344, 806}, - {48, 25, 1536, 369, 1344, 806}, - {42, 25, 1536, 419, 1344, 806}, - {48, 25, 1536, 369, 1344, 806}, - {12, 5, 896, 500, 1344, 806}, - {42, 25, 1024, 625, 1344, 806}, - {1, 1, 1344, 806, 1344, 806}, - {12, 5, 896, 500, 1344, 806}, - {42, 25, 1024, 625, 1344, 806}, - {1, 1, 1344, 806, 1344, 806}, - {12, 5, 896, 500, 1344, 806}, - {42, 25, 1024, 625, 1344, 806}, - {1, 1, 1344, 806, 1344, 806} -}; - -static const struct SiS_LCDData XGI_CetLCD1024x768Data[] = { - {1, 1, 1344, 806, 1344, 806}, /* ; 00 (320x200,320x400, - * 640x200,640x400) - */ - {1, 1, 1344, 806, 1344, 806}, /* 01 (320x350,640x350) */ - {1, 1, 1344, 806, 1344, 806}, /* 02 (360x400,720x400) */ - {1, 1, 1344, 806, 1344, 806}, /* 03 (720x350) */ - {1, 1, 1344, 806, 1344, 806}, /* 04 (640x480x60Hz) */ - {1, 1, 1344, 806, 1344, 806}, /* 05 (800x600x60Hz) */ - {1, 1, 1344, 806, 1344, 806} /* 06 (1024x768x60Hz) */ -}; - -static const struct SiS_LCDData XGI_StLCD1280x1024Data[] = { - {22, 5, 800, 510, 1650, 1088}, - {22, 5, 800, 510, 1650, 1088}, - {176, 45, 900, 510, 1650, 1088}, - {176, 45, 900, 510, 1650, 1088}, - {22, 5, 800, 510, 1650, 1088}, - {13, 5, 1024, 675, 1560, 1152}, - {16, 9, 1266, 804, 1688, 1072}, - {1, 1, 1688, 1066, 1688, 1066} -}; - -static const struct SiS_LCDData XGI_ExtLCD1280x1024Data[] = { - {211, 60, 1024, 501, 1688, 1066}, - {211, 60, 1024, 508, 1688, 1066}, - {211, 60, 1024, 501, 1688, 1066}, - {211, 60, 1024, 508, 1688, 1066}, - {211, 60, 1024, 500, 1688, 1066}, - {211, 75, 1024, 625, 1688, 1066}, - {211, 120, 1280, 798, 1688, 1066}, - {1, 1, 1688, 1066, 1688, 1066} -}; - -static const struct SiS_LCDData XGI_CetLCD1280x1024Data[] = { - {1, 1, 1688, 1066, 1688, 1066}, /* 00 (320x200,320x400, - * 640x200,640x400) - */ - {1, 1, 1688, 1066, 1688, 1066}, /* 01 (320x350,640x350) */ - {1, 1, 1688, 1066, 1688, 1066}, /* 02 (360x400,720x400) */ - {1, 1, 1688, 1066, 1688, 1066}, /* 03 (720x350) */ - {1, 1, 1688, 1066, 1688, 1066}, /* 04 (640x480x60Hz) */ - {1, 1, 1688, 1066, 1688, 1066}, /* 05 (800x600x60Hz) */ - {1, 1, 1688, 1066, 1688, 1066}, /* 06 (1024x768x60Hz) */ - {1, 1, 1688, 1066, 1688, 1066}, /* 07 (1280x1024x60Hz) */ - {1, 1, 1688, 1066, 1688, 1066} /* 08 (1400x1050x60Hz) */ -}; - -static const struct SiS_LCDData xgifb_lcd_1400x1050[] = { - {211, 100, 2100, 408, 1688, 1066}, /* 00 (320x200,320x400, - * 640x200,640x400) - */ - {211, 64, 1536, 358, 1688, 1066}, /* 01 (320x350,640x350) */ - {211, 100, 2100, 408, 1688, 1066}, /* 02 (360x400,720x400) */ - {211, 64, 1536, 358, 1688, 1066}, /* 03 (720x350) */ - {211, 48, 840, 488, 1688, 1066}, /* 04 (640x480x60Hz) */ - {211, 72, 1008, 609, 1688, 1066}, /* 05 (800x600x60Hz) */ - {211, 128, 1400, 776, 1688, 1066}, /* 06 (1024x768x60Hz) */ - {1, 1, 1688, 1066, 1688, 1066}, /* 07 (1280x1024x60Hz - * w/o Scaling) - */ - {1, 1, 1688, 1066, 1688, 1066} /* 08 (1400x1050x60Hz) */ -}; - -static const struct SiS_LCDData XGI_ExtLCD1600x1200Data[] = { - {4, 1, 1620, 420, 2160, 1250}, /* 00 (320x200,320x400, - * 640x200,640x400) - */ - {27, 7, 1920, 375, 2160, 1250}, /* 01 (320x350,640x350) */ - {4, 1, 1620, 420, 2160, 1250}, /* 02 (360x400,720x400)*/ - {27, 7, 1920, 375, 2160, 1250}, /* 03 (720x350) */ - {27, 4, 800, 500, 2160, 1250}, /* 04 (640x480x60Hz) */ - {4, 1, 1080, 625, 2160, 1250}, /* 05 (800x600x60Hz) */ - {5, 2, 1350, 800, 2160, 1250}, /* 06 (1024x768x60Hz) */ - {27, 16, 1500, 1064, 2160, 1250}, /* 07 (1280x1024x60Hz) */ - {9, 7, 1920, 1106, 2160, 1250}, /* 08 (1400x1050x60Hz) */ - {1, 1, 2160, 1250, 2160, 1250} /* 09 (1600x1200x60Hz) ;302lv */ -}; - -static const struct SiS_LCDData XGI_StLCD1600x1200Data[] = { - {27, 4, 800, 500, 2160, 1250}, /* 00 (320x200,320x400, - * 640x200,640x400) - */ - {27, 4, 800, 500, 2160, 1250}, /* 01 (320x350,640x350) */ - {27, 4, 800, 500, 2160, 1250}, /* 02 (360x400,720x400) */ - {27, 4, 800, 500, 2160, 1250}, /* 03 (720x350) */ - {27, 4, 800, 500, 2160, 1250}, /* 04 (320x240,640x480) */ - {4, 1, 1080, 625, 2160, 1250}, /* 05 (400x300,800x600) */ - {5, 2, 1350, 800, 2160, 1250}, /* 06 (512x384,1024x768) */ - {135, 88, 1600, 1100, 2160, 1250}, /* 07 (1280x1024) */ - {1, 1, 1800, 1500, 2160, 1250}, /* 08 (1400x1050) */ - {1, 1, 2160, 1250, 2160, 1250} /* 09 (1600x1200) */ -}; - -#define XGI_CetLCD1400x1050Data XGI_CetLCD1280x1024Data - -static const struct SiS_LCDData XGI_NoScalingData[] = { - {1, 1, 800, 449, 800, 449}, - {1, 1, 800, 449, 800, 449}, - {1, 1, 900, 449, 900, 449}, - {1, 1, 900, 449, 900, 449}, - {1, 1, 800, 525, 800, 525}, - {1, 1, 1056, 628, 1056, 628}, - {1, 1, 1344, 806, 1344, 806}, - {1, 1, 1688, 1066, 1688, 1066} -}; - -static const struct SiS_LCDData XGI_ExtLCD1024x768x75Data[] = { - {42, 25, 1536, 419, 1344, 806}, /* ; 00 (320x200,320x400, - * 640x200,640x400) - */ - {48, 25, 1536, 369, 1344, 806}, /* ; 01 (320x350,640x350) */ - {42, 25, 1536, 419, 1344, 806}, /* ; 02 (360x400,720x400) */ - {48, 25, 1536, 369, 1344, 806}, /* ; 03 (720x350) */ - {8, 5, 1312, 500, 1312, 800}, /* ; 04 (640x480x75Hz) */ - {41, 25, 1024, 625, 1312, 800}, /* ; 05 (800x600x75Hz) */ - {1, 1, 1312, 800, 1312, 800} /* ; 06 (1024x768x75Hz) */ -}; - -static const struct SiS_LCDData XGI_CetLCD1024x768x75Data[] = { - {1, 1, 1312, 800, 1312, 800}, /* ; 00 (320x200,320x400, - * 640x200,640x400) - */ - {1, 1, 1312, 800, 1312, 800}, /* ; 01 (320x350,640x350) */ - {1, 1, 1312, 800, 1312, 800}, /* ; 02 (360x400,720x400) */ - {1, 1, 1312, 800, 1312, 800}, /* ; 03 (720x350) */ - {1, 1, 1312, 800, 1312, 800}, /* ; 04 (640x480x75Hz) */ - {1, 1, 1312, 800, 1312, 800}, /* ; 05 (800x600x75Hz) */ - {1, 1, 1312, 800, 1312, 800} /* ; 06 (1024x768x75Hz) */ -}; - -static const struct SiS_LCDData xgifb_lcd_1280x1024x75[] = { - {211, 60, 1024, 501, 1688, 1066}, /* ; 00 (320x200,320x400, - * 640x200,640x400) - */ - {211, 60, 1024, 508, 1688, 1066}, /* ; 01 (320x350,640x350) */ - {211, 60, 1024, 501, 1688, 1066}, /* ; 02 (360x400,720x400) */ - {211, 60, 1024, 508, 1688, 1066}, /* ; 03 (720x350) */ - {211, 45, 768, 498, 1688, 1066}, /* ; 04 (640x480x75Hz) */ - {211, 75, 1024, 625, 1688, 1066}, /* ; 05 (800x600x75Hz) */ - {211, 120, 1280, 798, 1688, 1066}, /* ; 06 (1024x768x75Hz) */ - {1, 1, 1688, 1066, 1688, 1066} /* ; 07 (1280x1024x75Hz) */ -}; - -#define XGI_CetLCD1280x1024x75Data XGI_CetLCD1280x1024Data - -static const struct SiS_LCDData XGI_NoScalingDatax75[] = { - {1, 1, 800, 449, 800, 449}, /* ; 00 (320x200, 320x400, - * 640x200, 640x400) - */ - {1, 1, 800, 449, 800, 449}, /* ; 01 (320x350, 640x350) */ - {1, 1, 900, 449, 900, 449}, /* ; 02 (360x400, 720x400) */ - {1, 1, 900, 449, 900, 449}, /* ; 03 (720x350) */ - {1, 1, 840, 500, 840, 500}, /* ; 04 (640x480x75Hz) */ - {1, 1, 1056, 625, 1056, 625}, /* ; 05 (800x600x75Hz) */ - {1, 1, 1312, 800, 1312, 800}, /* ; 06 (1024x768x75Hz) */ - {1, 1, 1688, 1066, 1688, 1066}, /* ; 07 (1280x1024x75Hz) */ - {1, 1, 1688, 1066, 1688, 1066}, /* ; 08 (1400x1050x75Hz)*/ - {1, 1, 2160, 1250, 2160, 1250}, /* ; 09 (1600x1200x75Hz) */ - {1, 1, 1688, 806, 1688, 806} /* ; 0A (1280x768x75Hz) */ -}; - -static const struct XGI_LCDDesStruct XGI_ExtLCDDes1024x768Data[] = { - {9, 1057, 0, 771}, /* ; 00 (320x200,320x400,640x200,640x400) */ - {9, 1057, 0, 771}, /* ; 01 (320x350,640x350) */ - {9, 1057, 0, 771}, /* ; 02 (360x400,720x400) */ - {9, 1057, 0, 771}, /* ; 03 (720x350) */ - {9, 1057, 0, 771}, /* ; 04 (640x480x60Hz) */ - {9, 1057, 0, 771}, /* ; 05 (800x600x60Hz) */ - {9, 1057, 805, 770} /* ; 06 (1024x768x60Hz) */ -}; - -static const struct XGI_LCDDesStruct XGI_StLCDDes1024x768Data[] = { - {9, 1057, 737, 703}, /* ; 00 (320x200,320x400,640x200,640x400) */ - {9, 1057, 686, 651}, /* ; 01 (320x350,640x350) */ - {9, 1057, 737, 703}, /* ; 02 (360x400,720x400) */ - {9, 1057, 686, 651}, /* ; 03 (720x350) */ - {9, 1057, 776, 741}, /* ; 04 (640x480x60Hz) */ - {9, 1057, 0, 771}, /* ; 05 (800x600x60Hz) */ - {9, 1057, 805, 770} /* ; 06 (1024x768x60Hz) */ -}; - -static const struct XGI_LCDDesStruct XGI_CetLCDDes1024x768Data[] = { - {1152, 856, 622, 587}, /* ; 00 (320x200,320x400,640x200,640x400) */ - {1152, 856, 597, 562}, /* ; 01 (320x350,640x350) */ - {1152, 856, 622, 587}, /* ; 02 (360x400,720x400) */ - {1152, 856, 597, 562}, /* ; 03 (720x350) */ - {1152, 856, 662, 627}, /* ; 04 (640x480x60Hz) */ - {1232, 936, 722, 687}, /* ; 05 (800x600x60Hz) */ - {0, 1048, 805, 770} /* ; 06 (1024x768x60Hz) */ -}; - -static const struct XGI_LCDDesStruct XGI_ExtLCDDLDes1280x1024Data[] = { - {18, 1346, 981, 940}, /* 00 (320x200,320x400,640x200,640x400) */ - {18, 1346, 926, 865}, /* 01 (320x350,640x350) */ - {18, 1346, 981, 940}, /* 02 (360x400,720x400) */ - {18, 1346, 926, 865}, /* 03 (720x350) */ - {18, 1346, 0, 1025}, /* 04 (640x480x60Hz) */ - {18, 1346, 0, 1025}, /* 05 (800x600x60Hz) */ - {18, 1346, 1065, 1024}, /* 06 (1024x768x60Hz) */ - {18, 1346, 1065, 1024} /* 07 (1280x1024x60Hz) */ -}; - -static const struct XGI_LCDDesStruct XGI_StLCDDLDes1280x1024Data[] = { - {18, 1346, 970, 907}, /* 00 (320x200,320x400,640x200,640x400) */ - {18, 1346, 917, 854}, /* 01 (320x350,640x350) */ - {18, 1346, 970, 907}, /* 02 (360x400,720x400) */ - {18, 1346, 917, 854}, /* 03 (720x350) */ - {18, 1346, 0, 1025}, /* 04 (640x480x60Hz) */ - {18, 1346, 0, 1025}, /* 05 (800x600x60Hz) */ - {18, 1346, 1065, 1024}, /* 06 (1024x768x60Hz) */ - {18, 1346, 1065, 1024} /* 07 (1280x1024x60Hz) */ -}; - -static const struct XGI_LCDDesStruct XGI_CetLCDDLDes1280x1024Data[] = { - {1368, 1008, 752, 711}, /* 00 (320x200,320x400,640x200,640x400) */ - {1368, 1008, 729, 688}, /* 01 (320x350,640x350) */ - {1368, 1008, 752, 711}, /* 02 (360x400,720x400) */ - {1368, 1008, 729, 688}, /* 03 (720x350) */ - {1368, 1008, 794, 753}, /* 04 (640x480x60Hz) */ - {1448, 1068, 854, 813}, /* 05 (800x600x60Hz) */ - {1560, 1200, 938, 897}, /* 06 (1024x768x60Hz) */ - {18, 1346, 1065, 1024} /* 07 (1280x1024x60Hz) */ -}; - -static const struct XGI_LCDDesStruct XGI_ExtLCDDes1280x1024Data[] = { - {9, 1337, 981, 940}, /* ; 00 (320x200,320x400,640x200,640x400) */ - {9, 1337, 926, 884}, /* ; 01 (320x350,640x350) alan, 2003/09/30 */ - {9, 1337, 981, 940}, /* ; 02 (360x400,720x400) */ - {9, 1337, 926, 884}, /* ; 03 (720x350) alan, 2003/09/30 */ - {9, 1337, 0, 1025}, /* ; 04 (640x480x60Hz) */ - {9, 1337, 0, 1025}, /* ; 05 (800x600x60Hz) */ - {9, 1337, 1065, 1024}, /* ; 06 (1024x768x60Hz) */ - {9, 1337, 1065, 1024} /* ; 07 (1280x1024x60Hz) */ -}; - -static const struct XGI_LCDDesStruct XGI_StLCDDes1280x1024Data[] = { - {9, 1337, 970, 907}, /* ; 00 (320x200,320x400,640x200,640x400) */ - {9, 1337, 917, 854}, /* ; 01 (320x350,640x350) */ - {9, 1337, 970, 907}, /* ; 02 (360x400,720x400) */ - {9, 1337, 917, 854}, /* ; 03 (720x350) */ - {9, 1337, 0, 1025}, /* ; 04 (640x480x60Hz) */ - {9, 1337, 0, 1025}, /* ; 05 (800x600x60Hz) */ - {9, 1337, 1065, 1024}, /* ; 06 (1024x768x60Hz) */ - {9, 1337, 1065, 1024} /* ; 07 (1280x1024x60Hz) */ -}; - -static const struct XGI_LCDDesStruct XGI_CetLCDDes1280x1024Data[] = { - {1368, 1008, 752, 711}, /* 00 (320x200,320x400,640x200,640x400) */ - {1368, 1008, 729, 688}, /* 01 (320x350,640x350) */ - {1368, 1008, 752, 711}, /* 02 (360x400,720x400) */ - {1368, 1008, 729, 688}, /* 03 (720x350) */ - {1368, 1008, 794, 753}, /* 04 (640x480x60Hz) */ - {1448, 1068, 854, 813}, /* 05 (800x600x60Hz) */ - {1560, 1200, 938, 897}, /* 06 (1024x768x60Hz) */ - {9, 1337, 1065, 1024} /* 07 (1280x1024x60Hz) */ -}; - -static const struct XGI_LCDDesStruct xgifb_lcddldes_1400x1050[] = { - {18, 1464, 0, 1051}, /* 00 (320x200,320x400,640x200,640x400) */ - {18, 1464, 0, 1051}, /* 01 (320x350,640x350) */ - {18, 1464, 0, 1051}, /* 02 (360x400,720x400) */ - {18, 1464, 0, 1051}, /* 03 (720x350) */ - {18, 1464, 0, 1051}, /* 04 (640x480x60Hz) */ - {18, 1464, 0, 1051}, /* 05 (800x600x60Hz) */ - {18, 1464, 0, 1051}, /* 06 (1024x768x60Hz) */ - {1646, 1406, 1053, 1038}, /* 07 (1280x1024x60Hz) */ - {18, 1464, 0, 1051} /* 08 (1400x1050x60Hz) */ -}; - -static const struct XGI_LCDDesStruct xgifb_lcddes_1400x1050[] = { - {9, 1455, 0, 1051}, /* 00 (320x200,320x400,640x200,640x400) */ - {9, 1455, 0, 1051}, /* 01 (320x350,640x350) */ - {9, 1455, 0, 1051}, /* 02 (360x400,720x400) */ - {9, 1455, 0, 1051}, /* 03 (720x350) */ - {9, 1455, 0, 1051}, /* 04 (640x480x60Hz) */ - {9, 1455, 0, 1051}, /* 05 (800x600x60Hz) */ - {9, 1455, 0, 1051}, /* 06 (1024x768x60Hz) */ - {1637, 1397, 1053, 1038}, /* 07 (1280x1024x60Hz) */ - {9, 1455, 0, 1051} /* 08 (1400x1050x60Hz) */ -}; - -static const struct XGI_LCDDesStruct XGI_CetLCDDes1400x1050Data[] = { - {1308, 1068, 781, 766}, /* 00 (320x200,320x400,640x200,640x400) */ - {1308, 1068, 781, 766}, /* 01 (320x350,640x350) */ - {1308, 1068, 781, 766}, /* 02 (360x400,720x400) */ - {1308, 1068, 781, 766}, /* 03 (720x350) */ - {1308, 1068, 781, 766}, /* 04 (640x480x60Hz) */ - {1388, 1148, 841, 826}, /* 05 (800x600x60Hz) */ - {1490, 1250, 925, 910}, /* 06 (1024x768x60Hz) */ - {1646, 1406, 1053, 1038}, /* 07 (1280x1024x60Hz) */ - {18, 1464, 0, 1051} /* 08 (1400x1050x60Hz) */ -}; - -static const struct XGI_LCDDesStruct XGI_CetLCDDes1400x1050Data2[] = { - {0, 1448, 0, 1051}, /* 00 (320x200,320x400,640x200,640x400) */ - {0, 1448, 0, 1051}, /* 01 (320x350,640x350) */ - {0, 1448, 0, 1051}, /* 02 (360x400,720x400) */ - {0, 1448, 0, 1051}, /* 03 (720x350) */ - {0, 1448, 0, 1051} /* 04 (640x480x60Hz) */ -}; - -static const struct XGI_LCDDesStruct XGI_ExtLCDDLDes1600x1200Data[] = { - {18, 1682, 0, 1201}, /* 00 (320x200,320x400,640x200,640x400) */ - {18, 1682, 0, 1201}, /* 01 (320x350,640x350) */ - {18, 1682, 0, 1201}, /* 02 (360x400,720x400) */ - {18, 1682, 0, 1201}, /* 03 (720x350) */ - {18, 1682, 0, 1201}, /* 04 (640x480x60Hz) */ - {18, 1682, 0, 1201}, /* 05 (800x600x60Hz) */ - {18, 1682, 0, 1201}, /* 06 (1024x768x60Hz) */ - {18, 1682, 0, 1201}, /* 07 (1280x1024x60Hz) */ - {18, 1682, 0, 1201}, /* 08 (1400x1050x60Hz) */ - {18, 1682, 0, 1201} /* 09 (1600x1200x60Hz) */ -}; - -static const struct XGI_LCDDesStruct XGI_StLCDDLDes1600x1200Data[] = { - {18, 1682, 1150, 1101}, /* 00 (320x200,320x400,640x200,640x400) */ - {18, 1682, 1083, 1034}, /* 01 (320x350,640x350) */ - {18, 1682, 1150, 1101}, /* 02 (360x400,720x400) */ - {18, 1682, 1083, 1034}, /* 03 (720x350) */ - {18, 1682, 0, 1201}, /* 04 (640x480x60Hz) */ - {18, 1682, 0, 1201}, /* 05 (800x600x60Hz) */ - {18, 1682, 0, 1201}, /* 06 (1024x768x60Hz) */ - {18, 1682, 1232, 1183}, /* 07 (1280x1024x60Hz) */ - {18, 1682, 0, 1201}, /* 08 (1400x1050x60Hz) */ - {18, 1682, 0, 1201} /* 09 (1600x1200x60Hz) */ -}; - -static const struct XGI_LCDDesStruct XGI_ExtLCDDes1600x1200Data[] = { - {9, 1673, 0, 1201}, /* 00 (320x200,320x400,640x200,640x400) */ - {9, 1673, 0, 1201}, /* 01 (320x350,640x350) */ - {9, 1673, 0, 1201}, /* 02 (360x400,720x400) */ - {9, 1673, 0, 1201}, /* 03 (720x350) */ - {9, 1673, 0, 1201}, /* 04 (640x480x60Hz) */ - {9, 1673, 0, 1201}, /* 05 (800x600x60Hz) */ - {9, 1673, 0, 1201}, /* 06 (1024x768x60Hz) */ - {9, 1673, 0, 1201}, /* 07 (1280x1024x60Hz) */ - {9, 1673, 0, 1201}, /* 08 (1400x1050x60Hz) */ - {9, 1673, 0, 1201} /* 09 (1600x1200x60Hz) */ -}; - -static const struct XGI_LCDDesStruct XGI_StLCDDes1600x1200Data[] = { - {9, 1673, 1150, 1101}, /* 00 (320x200,320x400,640x200,640x400) */ - {9, 1673, 1083, 1034}, /* 01 (320x350,640x350) */ - {9, 1673, 1150, 1101}, /* 02 (360x400,720x400) */ - {9, 1673, 1083, 1034}, /* 03 (720x350) */ - {9, 1673, 0, 1201}, /* 04 (640x480x60Hz) */ - {9, 1673, 0, 1201}, /* 05 (800x600x60Hz) */ - {9, 1673, 0, 1201}, /* 06 (1024x768x60Hz) */ - {9, 1673, 1232, 1183}, /* 07 (1280x1024x60Hz) */ - {9, 1673, 0, 1201}, /* 08 (1400x1050x60Hz) */ - {9, 1673, 0, 1201} /* 09 (1600x1200x60Hz) */ -}; - -static const struct XGI330_LCDDataDesStruct2 XGI_NoScalingDesData[] = { - {9, 657, 448, 405, 96, 2}, /* 00 (320x200,320x400, - * 640x200,640x400) - */ - {9, 657, 448, 355, 96, 2}, /* 01 (320x350,640x350) */ - {9, 657, 448, 405, 96, 2}, /* 02 (360x400,720x400) */ - {9, 657, 448, 355, 96, 2}, /* 03 (720x350) */ - {9, 657, 1, 483, 96, 2}, /* 04 (640x480x60Hz) */ - {9, 849, 627, 600, 128, 4}, /* 05 (800x600x60Hz) */ - {9, 1057, 805, 770, 0136, 6}, /* 06 (1024x768x60Hz) */ - {9, 1337, 0, 1025, 112, 3}, /* 07 (1280x1024x60Hz) */ - {9, 1457, 0, 1051, 112, 3}, /* 08 (1400x1050x60Hz)*/ - {9, 1673, 0, 1201, 192, 3}, /* 09 (1600x1200x60Hz) */ - {9, 1337, 0, 771, 112, 6} /* 0A (1280x768x60Hz) */ -}; - -/* ;;1024x768x75Hz */ -static const struct XGI_LCDDesStruct xgifb_lcddes_1024x768x75[] = { - {9, 1049, 0, 769}, /* ; 00 (320x200,320x400,640x200,640x400) */ - {9, 1049, 0, 769}, /* ; 01 (320x350,640x350) */ - {9, 1049, 0, 769}, /* ; 02 (360x400,720x400) */ - {9, 1049, 0, 769}, /* ; 03 (720x350) */ - {9, 1049, 0, 769}, /* ; 04 (640x480x75Hz) */ - {9, 1049, 0, 769}, /* ; 05 (800x600x75Hz) */ - {9, 1049, 0, 769} /* ; 06 (1024x768x75Hz) */ -}; - -/* ;;1024x768x75Hz */ -static const struct XGI_LCDDesStruct XGI_CetLCDDes1024x768x75Data[] = { - {1152, 856, 622, 587}, /* ; 00 (320x200,320x400,640x200,640x400) */ - {1152, 856, 597, 562}, /* ; 01 (320x350,640x350) */ - {1192, 896, 622, 587}, /* ; 02 (360x400,720x400) */ - {1192, 896, 597, 562}, /* ; 03 (720x350) */ - {1129, 857, 656, 625}, /* ; 04 (640x480x75Hz) */ - {1209, 937, 716, 685}, /* ; 05 (800x600x75Hz) */ - {9, 1049, 0, 769} /* ; 06 (1024x768x75Hz) */ -}; - -/* ;;1280x1024x75Hz */ -static const struct XGI_LCDDesStruct xgifb_lcddldes_1280x1024x75[] = { - {18, 1314, 0, 1025}, /* ; 00 (320x200,320x400,640x200,640x400) */ - {18, 1314, 0, 1025}, /* ; 01 (320x350,640x350) */ - {18, 1314, 0, 1025}, /* ; 02 (360x400,720x400) */ - {18, 1314, 0, 1025}, /* ; 03 (720x350) */ - {18, 1314, 0, 1025}, /* ; 04 (640x480x60Hz) */ - {18, 1314, 0, 1025}, /* ; 05 (800x600x60Hz) */ - {18, 1314, 0, 1025}, /* ; 06 (1024x768x60Hz) */ - {18, 1314, 0, 1025} /* ; 07 (1280x1024x60Hz) */ -}; - -/* 1280x1024x75Hz */ -static const struct XGI_LCDDesStruct XGI_CetLCDDLDes1280x1024x75Data[] = { - {1368, 1008, 752, 711}, /* ; 00 (320x200,320x400,640x200,640x400) */ - {1368, 1008, 729, 688}, /* ; 01 (320x350,640x350) */ - {1408, 1048, 752, 711}, /* ; 02 (360x400,720x400) */ - {1408, 1048, 729, 688}, /* ; 03 (720x350) */ - {1377, 985, 794, 753}, /* ; 04 (640x480x75Hz) */ - {1457, 1065, 854, 813}, /* ; 05 (800x600x75Hz) */ - {1569, 1177, 938, 897}, /* ; 06 (1024x768x75Hz) */ - {18, 1314, 0, 1025} /* ; 07 (1280x1024x75Hz) */ -}; - -/* ;;1280x1024x75Hz */ -static const struct XGI_LCDDesStruct xgifb_lcddes_1280x1024x75[] = { - {9, 1305, 0, 1025}, /* ; 00 (320x200,320x400,640x200,640x400) */ - {9, 1305, 0, 1025}, /* ; 01 (320x350,640x350) */ - {9, 1305, 0, 1025}, /* ; 02 (360x400,720x400) */ - {9, 1305, 0, 1025}, /* ; 03 (720x350) */ - {9, 1305, 0, 1025}, /* ; 04 (640x480x60Hz) */ - {9, 1305, 0, 1025}, /* ; 05 (800x600x60Hz) */ - {9, 1305, 0, 1025}, /* ; 06 (1024x768x60Hz) */ - {9, 1305, 0, 1025} /* ; 07 (1280x1024x60Hz) */ -}; - -/* 1280x1024x75Hz */ -static const struct XGI_LCDDesStruct XGI_CetLCDDes1280x1024x75Data[] = { - {1368, 1008, 752, 711}, /* ; 00 (320x200,320x400,640x200,640x400) */ - {1368, 1008, 729, 688}, /* ; 01 (320x350,640x350) */ - {1408, 1048, 752, 711}, /* ; 02 (360x400,720x400) */ - {1408, 1048, 729, 688}, /* ; 03 (720x350) */ - {1377, 985, 794, 753}, /* ; 04 (640x480x75Hz) */ - {1457, 1065, 854, 813}, /* ; 05 (800x600x75Hz) */ - {1569, 1177, 938, 897}, /* ; 06 (1024x768x75Hz) */ - {9, 1305, 0, 1025} /* ; 07 (1280x1024x75Hz) */ -}; - -/* Scaling LCD 75Hz */ -static const struct XGI330_LCDDataDesStruct2 XGI_NoScalingDesDatax75[] = { - {9, 657, 448, 405, 96, 2}, /* ; 00 (320x200,320x400, - * 640x200,640x400) - */ - {9, 657, 448, 355, 96, 2}, /* ; 01 (320x350,640x350) */ - {9, 738, 448, 405, 108, 2}, /* ; 02 (360x400,720x400) */ - {9, 738, 448, 355, 108, 2}, /* ; 03 (720x350) */ - {9, 665, 0, 481, 64, 3}, /* ; 04 (640x480x75Hz) */ - {9, 825, 0, 601, 80, 3}, /* ; 05 (800x600x75Hz) */ - {9, 1049, 0, 769, 96, 3}, /* ; 06 (1024x768x75Hz) */ - {9, 1305, 0, 1025, 144, 3}, /* ; 07 (1280x1024x75Hz) */ - {9, 1457, 0, 1051, 112, 3}, /* ; 08 (1400x1050x60Hz)*/ - {9, 1673, 0, 1201, 192, 3}, /* ; 09 (1600x1200x75Hz) */ - {9, 1337, 0, 771, 112, 6} /* ; 0A (1280x768x60Hz) */ -}; - -static const struct SiS_TVData XGI_StPALData[] = { - {1, 1, 864, 525, 1270, 400, 100, 0, 760}, - {1, 1, 864, 525, 1270, 350, 100, 0, 760}, - {1, 1, 864, 525, 1270, 400, 0, 0, 720}, - {1, 1, 864, 525, 1270, 350, 0, 0, 720}, - {1, 1, 864, 525, 1270, 480, 50, 0, 760}, - {1, 1, 864, 525, 1270, 600, 50, 0, 0} -}; - -static const struct SiS_TVData XGI_ExtPALData[] = { - {2, 1, 1080, 463, 1270, 500, 50, 0, 50}, - {15, 7, 1152, 413, 1270, 500, 50, 0, 50}, - {2, 1, 1080, 463, 1270, 500, 50, 0, 50}, - {15, 7, 1152, 413, 1270, 500, 50, 0, 50}, - {2, 1, 900, 543, 1270, 500, 0, 0, 50}, - {4, 3, 1080, 663, 1270, 500, 438, 0, 438}, - {1, 1, 1125, 831, 1270, 500, 686, 0, 686}, /*301b*/ - {3, 2, 1080, 619, 1270, 540, 438, 0, 438} -}; - -static const struct SiS_TVData XGI_StNTSCData[] = { - {1, 1, 858, 525, 1270, 400, 50, 0, 760}, - {1, 1, 858, 525, 1270, 350, 50, 0, 640}, - {1, 1, 858, 525, 1270, 400, 0, 0, 720}, - {1, 1, 858, 525, 1270, 350, 0, 0, 720}, - {1, 1, 858, 525, 1270, 480, 0, 0, 760} -}; - -static const struct SiS_TVData XGI_ExtNTSCData[] = { - {9, 5, 1001, 453, 1270, 420, 171, 0, 171}, - {12, 5, 858, 403, 1270, 420, 171, 0, 171}, - {9, 5, 1001, 453, 1270, 420, 171, 0, 171}, - {12, 5, 858, 403, 1270, 420, 171, 0, 171}, - {143, 80, 836, 523, 1270, 420, 224, 0, 0}, - {143, 120, 1008, 643, 1270, 420, 0, 1, 0}, - {1, 1, 1120, 821, 1516, 420, 0, 1, 0}, /*301b*/ - {2, 1, 858, 503, 1584, 480, 0, 1, 0}, - {3, 2, 1001, 533, 1270, 420, 0, 0, 0} -}; - -static const struct SiS_TVData XGI_St1HiTVData[] = { - {1, 1, 892, 563, 690, 800, 0, 0, 0}, /* 00 (320x200,320x400, - * 640x200,640x400) - */ - {1, 1, 892, 563, 690, 700, 0, 0, 0}, /* 01 (320x350,640x350) */ - {1, 1, 1000, 563, 785, 800, 0, 0, 0}, /* 02 (360x400,720x400) */ - {1, 1, 1000, 563, 785, 700, 0, 0, 0}, /* 03 (720x350) */ - {1, 1, 892, 563, 690, 960, 0, 0, 0}, /* 04 (320x240,640x480) */ - {8, 5, 1050, 683, 1648, 960, 0x150, 1, 0} /* 05 (400x300,800x600) */ -}; - -static const struct SiS_TVData XGI_St2HiTVData[] = { - {3, 1, 840, 483, 1648, 960, 0x032, 0, 0}, /* 00 (320x200,320x400, - * 640x200,640x400) - */ - {1, 1, 892, 563, 690, 700, 0, 0, 0}, /* 01 (320x350,640x350) */ - {3, 1, 840, 483, 1648, 960, 0x032, 0, 0}, /* 02 (360x400,720x400) */ - {1, 1, 1000, 563, 785, 700, 0, 0, 0}, /* 03 (720x350) */ - {5, 2, 840, 563, 1648, 960, 0x08D, 1, 0}, /* 04 (320x240,640x480) */ - {8, 5, 1050, 683, 1648, 960, 0x17C, 1, 0} /* 05 (400x300,800x600) */ -}; - -static const struct SiS_TVData XGI_ExtHiTVData[] = { - {6, 1, 840, 563, 1632, 960, 0, 0, 0}, /* 00 (320x200,320x400, - * 640x200,640x400) - */ - {3, 1, 960, 563, 1632, 960, 0, 0, 0}, /* 01 (320x350,640x350) */ - {3, 1, 840, 483, 1632, 960, 0, 0, 0}, /* 02 (360x400,720x400) */ - {3, 1, 960, 563, 1632, 960, 0, 0, 0}, /* 03 (720x350) */ - {5, 1, 840, 563, 1648, 960, 0x166, 1, 0}, /* 04 (320x240,640x480) */ - {16, 5, 1050, 683, 1648, 960, 0x143, 1, 0}, /* 05 (400x300,800x600) */ - {25, 12, 1260, 851, 1648, 960, 0x032, 0, 0}, /* 06 (512x384,1024x768)*/ - {5, 4, 1575, 1124, 1648, 960, 0x128, 0, 0}, /* 07 (1280x1024) */ - {4, 1, 1050, 563, 1548, 960, 0x143, 1, 0}, /* 08 (800x480) */ - {5, 2, 1400, 659, 1648, 960, 0x032, 0, 0}, /* 09 (1024x576) */ - {8, 5, 1750, 803, 1648, 960, 0x128, 0, 0} /* 0A (1280x720) */ -}; - -static const struct SiS_TVData XGI_ExtYPbPr525iData[] = { - { 9, 5, 1001, 453, 1270, 420, 171, 0, 171}, - { 12, 5, 858, 403, 1270, 420, 171, 0, 171}, - { 9, 5, 1001, 453, 1270, 420, 171, 0, 171}, - { 12, 5, 858, 403, 1270, 420, 171, 0, 171}, - {143, 80, 836, 523, 1250, 420, 224, 0, 0}, - {143, 120, 1008, 643, 1250, 420, 0, 1, 0}, - { 1, 1, 1120, 821, 1516, 420, 0, 1, 0}, /*301b*/ - { 2, 1, 858, 503, 1584, 480, 0, 1, 0}, - { 3, 2, 1001, 533, 1250, 420, 0, 0, 0} -}; - -static const struct SiS_TVData XGI_StYPbPr525iData[] = { - {1, 1, 858, 525, 1270, 400, 50, 0, 760}, - {1, 1, 858, 525, 1270, 350, 50, 0, 640}, - {1, 1, 858, 525, 1270, 400, 0, 0, 720}, - {1, 1, 858, 525, 1270, 350, 0, 0, 720}, - {1, 1, 858, 525, 1270, 480, 0, 0, 760}, -}; - -static const struct SiS_TVData XGI_ExtYPbPr525pData[] = { - { 9, 5, 1001, 453, 1270, 420, 171, 0, 171}, - { 12, 5, 858, 403, 1270, 420, 171, 0, 171}, - { 9, 5, 1001, 453, 1270, 420, 171, 0, 171}, - { 12, 5, 858, 403, 1270, 420, 171, 0, 171}, - {143, 80, 836, 523, 1270, 420, 224, 0, 0}, - {143, 120, 1008, 643, 1270, 420, 0, 1, 0}, - { 1, 1, 1120, 821, 1516, 420, 0, 1, 0}, /*301b*/ - { 2, 1, 858, 503, 1584, 480, 0, 1, 0}, - { 3, 2, 1001, 533, 1270, 420, 0, 0, 0} -}; - -static const struct SiS_TVData XGI_StYPbPr525pData[] = { - {1, 1, 1716, 525, 1270, 400, 50, 0, 760}, - {1, 1, 1716, 525, 1270, 350, 50, 0, 640}, - {1, 1, 1716, 525, 1270, 400, 0, 0, 720}, - {1, 1, 1716, 525, 1270, 350, 0, 0, 720}, - {1, 1, 1716, 525, 1270, 480, 0, 0, 760}, -}; - -static const struct SiS_TVData XGI_ExtYPbPr750pData[] = { - { 3, 1, 935, 470, 1130, 680, 50, 0, 0}, /* 00 (320x200,320x400, - * 640x200,640x400) - */ - {24, 7, 935, 420, 1130, 680, 50, 0, 0}, /* 01 (320x350,640x350) */ - { 3, 1, 935, 470, 1130, 680, 50, 0, 0}, /* 02 (360x400,720x400) */ - {24, 7, 935, 420, 1130, 680, 50, 0, 0}, /* 03 (720x350) */ - { 2, 1, 1100, 590, 1130, 640, 50, 0, 0}, /* 04 (320x240,640x480) */ - { 3, 2, 1210, 690, 1130, 660, 50, 0, 0}, /* 05 (400x300,800x600) */ - { 1, 1, 1375, 878, 1130, 640, 638, 0, 0}, /* 06 (1024x768) */ - { 2, 1, 858, 503, 1130, 480, 0, 1, 0}, /* 07 (720x480) */ - { 5, 4, 1815, 570, 1130, 660, 50, 0, 0}, - { 5, 3, 1100, 686, 1130, 640, 50, 1, 0}, - {10, 9, 1320, 830, 1130, 640, 50, 0, 0} -}; - -static const struct SiS_TVData XGI_StYPbPr750pData[] = { - {1, 1, 1650, 750, 1280, 400, 50, 0, 760}, - {1, 1, 1650, 750, 1280, 350, 50, 0, 640}, - {1, 1, 1650, 750, 1280, 400, 0, 0, 720}, - {1, 1, 1650, 750, 1280, 350, 0, 0, 720}, - {1, 1, 1650, 750, 1280, 480, 0, 0, 760}, -}; - -static const unsigned char XGI330_NTSCTiming[] = { - 0x17, 0x1d, 0x03, 0x09, 0x05, 0x06, 0x0c, 0x0c, - 0x94, 0x49, 0x01, 0x0a, 0x06, 0x0d, 0x04, 0x0a, - 0x06, 0x14, 0x0d, 0x04, 0x0a, 0x00, 0x85, 0x1b, - 0x0c, 0x50, 0x00, 0x97, 0x00, 0xda, 0x4a, 0x17, - 0x7d, 0x05, 0x4b, 0x00, 0x00, 0xe2, 0x00, 0x02, - 0x03, 0x0a, 0x65, 0x9d, 0x08, 0x92, 0x8f, 0x40, - 0x60, 0x80, 0x14, 0x90, 0x8c, 0x60, 0x14, 0x50, - 0x00, 0x40, 0x44, 0x00, 0xdb, 0x02, 0x3b, 0x00 -}; - -static const unsigned char XGI330_PALTiming[] = { - 0x21, 0x5A, 0x35, 0x6e, 0x04, 0x38, 0x3d, 0x70, - 0x94, 0x49, 0x01, 0x12, 0x06, 0x3e, 0x35, 0x6d, - 0x06, 0x14, 0x3e, 0x35, 0x6d, 0x00, 0x45, 0x2b, - 0x70, 0x50, 0x00, 0x9b, 0x00, 0xd9, 0x5d, 0x17, - 0x7d, 0x05, 0x45, 0x00, 0x00, 0xe8, 0x00, 0x02, - 0x0d, 0x00, 0x68, 0xb0, 0x0b, 0x92, 0x8f, 0x40, - 0x60, 0x80, 0x14, 0x90, 0x8c, 0x60, 0x14, 0x63, - 0x00, 0x40, 0x3e, 0x00, 0xe1, 0x02, 0x28, 0x00 -}; - -static const unsigned char XGI330_HiTVExtTiming[] = { - 0x2D, 0x60, 0x2C, 0x5F, 0x08, 0x31, 0x3A, 0x64, - 0x28, 0x02, 0x01, 0x3D, 0x06, 0x3E, 0x35, 0x6D, - 0x06, 0x14, 0x3E, 0x35, 0x6D, 0x00, 0xC5, 0x3F, - 0x64, 0x90, 0x33, 0x8C, 0x18, 0x36, 0x3E, 0x13, - 0x2A, 0xDE, 0x2A, 0x44, 0x40, 0x2A, 0x44, 0x40, - 0x8E, 0x8E, 0x82, 0x07, 0x0B, - 0x92, 0x0F, 0x40, 0x60, 0x80, 0x14, 0x90, 0x8C, - 0x60, 0x14, 0x3D, 0x63, 0x4F, - 0x27, 0x00, 0xfc, 0xff, 0x6a, 0x00 -}; - -static const unsigned char XGI330_HiTVSt1Timing[] = { - 0x32, 0x65, 0x2C, 0x5F, 0x08, 0x31, 0x3A, 0x65, - 0x28, 0x02, 0x01, 0x3D, 0x06, 0x3E, 0x35, 0x6D, - 0x06, 0x14, 0x3E, 0x35, 0x6D, 0x00, 0xC5, 0x3F, - 0x65, 0x90, 0x7B, 0xA8, 0x03, 0xF0, 0x87, 0x03, - 0x11, 0x15, 0x11, 0xCF, 0x10, 0x11, 0xCF, 0x10, - 0x35, 0x35, 0x3B, 0x69, 0x1D, - 0x92, 0x0F, 0x40, 0x60, 0x80, 0x14, 0x90, 0x8C, - 0x60, 0x04, 0x86, 0xAF, 0x5D, - 0x0E, 0x00, 0xfc, 0xff, 0x2d, 0x00 -}; - -static const unsigned char XGI330_HiTVSt2Timing[] = { - 0x32, 0x65, 0x2C, 0x5F, 0x08, 0x31, 0x3A, 0x64, - 0x28, 0x02, 0x01, 0x3D, 0x06, 0x3E, 0x35, 0x6D, - 0x06, 0x14, 0x3E, 0x35, 0x6D, 0x00, 0xC5, 0x3F, - 0x64, 0x90, 0x33, 0x8C, 0x18, 0x36, 0x3E, 0x13, - 0x2A, 0xDE, 0x2A, 0x44, 0x40, 0x2A, 0x44, 0x40, - 0x8E, 0x8E, 0x82, 0x07, 0x0B, - 0x92, 0x0F, 0x40, 0x60, 0x80, 0x14, 0x90, 0x8C, - 0x60, 0x14, 0x3D, 0x63, 0x4F, - 0x27, 0x00, 0xFC, 0xff, 0x6a, 0x00 -}; - -static const unsigned char XGI330_HiTVTextTiming[] = { - 0x32, 0x65, 0x2C, 0x5F, 0x08, 0x31, 0x3A, 0x65, - 0x28, 0x02, 0x01, 0x3D, 0x06, 0x3E, 0x35, 0x6D, - 0x06, 0x14, 0x3E, 0x35, 0x6D, 0x00, 0xC5, 0x3F, - 0x65, 0x90, 0xE7, 0xBC, 0x03, 0x0C, 0x97, 0x03, - 0x14, 0x78, 0x14, 0x08, 0x20, 0x14, 0x08, 0x20, - 0xC8, 0xC8, 0x3B, 0xD2, 0x26, - 0x92, 0x0F, 0x40, 0x60, 0x80, 0x14, 0x90, 0x8C, - 0x60, 0x04, 0x96, 0x72, 0x5C, - 0x11, 0x00, 0xFC, 0xFF, 0x32, 0x00 -}; - -static const unsigned char XGI330_YPbPr750pTiming[] = { - 0x30, 0x1d, 0xe8, 0x09, 0x09, 0xed, 0x0c, 0x0c, - 0x98, 0x0a, 0x01, 0x0c, 0x06, 0x0d, 0x04, 0x0a, - 0x06, 0x14, 0x0d, 0x04, 0x0a, 0x00, 0x85, 0x3f, - 0xed, 0x50, 0x70, 0x9f, 0x16, 0x59, 0x60, 0x13, - 0x27, 0x0b, 0x27, 0xfc, 0x30, 0x27, 0x1c, 0xb0, - 0x4b, 0x4b, 0x6f, 0x2f, 0x63, - 0x92, 0x0F, 0x40, 0x60, 0x80, 0x14, 0x90, 0x8C, - 0x60, 0x14, 0x73, 0x00, 0x40, - 0x11, 0x00, 0xfc, 0xff, 0x32, 0x00 -}; - -static const unsigned char XGI330_YPbPr525pTiming[] = { - 0x3E, 0x11, 0x06, 0x09, 0x0b, 0x0c, 0x0c, 0x0c, - 0x98, 0x0a, 0x01, 0x0d, 0x06, 0x0d, 0x04, 0x0a, - 0x06, 0x14, 0x0d, 0x04, 0x0a, 0x00, 0x85, 0x3f, - 0x0c, 0x50, 0xb2, 0x9f, 0x16, 0x59, 0x4f, 0x13, - 0xad, 0x11, 0xad, 0x1d, 0x40, 0x8a, 0x3d, 0xb8, - 0x51, 0x5e, 0x60, 0x49, 0x7d, - 0x92, 0x0F, 0x40, 0x60, 0x80, 0x14, 0x90, 0x8C, - 0x60, 0x14, 0x4B, 0x43, 0x41, - 0x11, 0x00, 0xFC, 0xFF, 0x32, 0x00 -}; - -static const unsigned char XGI330_YPbPr525iTiming[] = { - 0x1B, 0x21, 0x03, 0x09, 0x05, 0x06, 0x0C, 0x0C, - 0x94, 0x49, 0x01, 0x0A, 0x06, 0x0D, 0x04, 0x0A, - 0x06, 0x14, 0x0D, 0x04, 0x0A, 0x00, 0x85, 0x1B, - 0x0C, 0x50, 0x00, 0x97, 0x00, 0xDA, 0x4A, 0x17, - 0x7D, 0x05, 0x4B, 0x00, 0x00, 0xE2, 0x00, 0x02, - 0x03, 0x0A, 0x65, 0x9D, 0x08, - 0x92, 0x8F, 0x40, 0x60, 0x80, 0x14, 0x90, 0x8C, - 0x60, 0x14, 0x4B, 0x00, 0x40, - 0x44, 0x00, 0xDB, 0x02, 0x3B, 0x00 -}; - -static const unsigned char XGI330_HiTVGroup3Data[] = { - 0x00, 0x1A, 0x22, 0x63, 0x62, 0x22, 0x08, 0x5F, - 0x05, 0x21, 0xB2, 0xB2, 0x55, 0x77, 0x2A, 0xA6, - 0x25, 0x2F, 0x47, 0xFA, 0xC8, 0xFF, 0x8E, 0x20, - 0x8C, 0x6E, 0x60, 0x2E, 0x58, 0x48, 0x72, 0x44, - 0x56, 0x36, 0x4F, 0x6E, 0x3F, 0x80, 0x00, 0x80, - 0x4F, 0x7F, 0x03, 0xA8, 0x7D, 0x20, 0x1A, 0xA9, - 0x14, 0x05, 0x03, 0x7E, 0x64, 0x31, 0x14, 0x75, - 0x18, 0x05, 0x18, 0x05, 0x4C, 0xA8, 0x01 -}; - -static const unsigned char XGI330_HiTVGroup3Simu[] = { - 0x00, 0x1A, 0x22, 0x63, 0x62, 0x22, 0x08, 0x95, - 0xDB, 0x20, 0xB8, 0xB8, 0x55, 0x47, 0x2A, 0xA6, - 0x25, 0x2F, 0x47, 0xFA, 0xC8, 0xFF, 0x8E, 0x20, - 0x8C, 0x6E, 0x60, 0x15, 0x26, 0xD3, 0xE4, 0x11, - 0x56, 0x36, 0x4F, 0x6E, 0x3F, 0x80, 0x00, 0x80, - 0x67, 0x36, 0x01, 0x47, 0x0E, 0x10, 0xBE, 0xB4, - 0x01, 0x05, 0x03, 0x7E, 0x65, 0x31, 0x14, 0x75, - 0x18, 0x05, 0x18, 0x05, 0x4C, 0xA8, 0x01 -}; - -static const unsigned char XGI330_HiTVGroup3Text[] = { - 0x00, 0x1A, 0x22, 0x63, 0x62, 0x22, 0x08, 0xA7, - 0xF5, 0x20, 0xCE, 0xCE, 0x55, 0x47, 0x2A, 0xA6, - 0x25, 0x2F, 0x47, 0xFA, 0xC8, 0xFF, 0x8E, 0x20, - 0x8C, 0x6E, 0x60, 0x18, 0x2C, 0x0C, 0x20, 0x22, - 0x56, 0x36, 0x4F, 0x6E, 0x3F, 0x80, 0x00, 0x80, - 0x93, 0x3C, 0x01, 0x50, 0x2F, 0x10, 0xF4, 0xCA, - 0x01, 0x05, 0x03, 0x7E, 0x65, 0x31, 0x14, 0x75, - 0x18, 0x05, 0x18, 0x05, 0x4C, 0xA8, 0x01 -}; - -static const unsigned char XGI330_Ren525pGroup3[] = { - 0x00, 0x14, 0x15, 0x25, 0x55, 0x15, 0x0b, 0x13, - 0xB1, 0x41, 0x62, 0x62, 0xFF, 0xF4, 0x45, 0xa6, - 0x25, 0x2F, 0x67, 0xF6, 0xbf, 0xFF, 0x8E, 0x20, - 0xAC, 0xDA, 0x60, 0xFe, 0x6A, 0x9A, 0x06, 0x10, - 0xd1, 0x04, 0x18, 0x0a, 0xFF, 0x80, 0x00, 0x80, - 0x3c, 0x77, 0x00, 0xEF, 0xE0, 0x10, 0xB0, 0xE0, - 0x10, 0x4F, 0x0F, 0x0F, 0x05, 0x0F, 0x08, 0x6E, - 0x1a, 0x1F, 0x25, 0x2a, 0x4C, 0xAA, 0x01 -}; - -static const unsigned char XGI330_Ren750pGroup3[] = { - 0x00, 0x14, 0x15, 0x25, 0x55, 0x15, 0x0b, 0x7a, - 0x54, 0x41, 0xE7, 0xE7, 0xFF, 0xF4, 0x45, 0xa6, - 0x25, 0x2F, 0x67, 0xF6, 0xbf, 0xFF, 0x8E, 0x20, - 0xAC, 0x6A, 0x60, 0x2b, 0x52, 0xCD, 0x61, 0x10, - 0x51, 0x04, 0x18, 0x0a, 0x1F, 0x80, 0x00, 0x80, - 0xFF, 0xA4, 0x04, 0x2B, 0x94, 0x21, 0x72, 0x94, - 0x26, 0x05, 0x01, 0x0F, 0xed, 0x0F, 0x0A, 0x64, - 0x18, 0x1D, 0x23, 0x28, 0x4C, 0xAA, 0x01 -}; - -static const struct SiS_LVDSData XGI_LVDS1024x768Data_1[] = { - { 960, 438, 1344, 806}, /* 00 (320x200,320x400,640x200,640x400) */ - { 960, 388, 1344, 806}, /* 01 (320x350,640x350) */ - {1040, 438, 1344, 806}, /* 02 (360x400,720x400) */ - {1040, 388, 1344, 806}, /* 03 (720x350) */ - { 960, 518, 1344, 806}, /* 04 (320x240,640x480) */ - {1120, 638, 1344, 806}, /* 05 (400x300,800x600) */ - {1344, 806, 1344, 806} /* 06 (512x384,1024x768) */ -}; - -static const struct SiS_LVDSData XGI_LVDS1024x768Data_2[] = { - {1344, 806, 1344, 806}, - {1344, 806, 1344, 806}, - {1344, 806, 1344, 806}, - {1344, 806, 1344, 806}, - {1344, 806, 1344, 806}, - {1344, 806, 1344, 806}, - {1344, 806, 1344, 806}, - {800, 449, 1280, 801}, - {800, 525, 1280, 813} -}; - -static const struct SiS_LVDSData XGI_LVDS1280x1024Data_1[] = { - {1048, 442, 1688, 1066}, - {1048, 392, 1688, 1066}, - {1048, 442, 1688, 1066}, - {1048, 392, 1688, 1066}, - {1048, 522, 1688, 1066}, - {1208, 642, 1688, 1066}, - {1432, 810, 1688, 1066}, - {1688, 1066, 1688, 1066} -}; - -#define XGI_LVDS1280x1024Data_2 XGI_LVDS1024x768Data_2 - -static const struct SiS_LVDSData XGI_LVDS1400x1050Data_1[] = { - {928, 416, 1688, 1066}, - {928, 366, 1688, 1066}, - {928, 416, 1688, 1066}, - {928, 366, 1688, 1066}, - {928, 496, 1688, 1066}, - {1088, 616, 1688, 1066}, - {1312, 784, 1688, 1066}, - {1568, 1040, 1688, 1066}, - {1688, 1066, 1688, 1066} -}; - -static const struct SiS_LVDSData XGI_LVDS1400x1050Data_2[] = { - {1688, 1066, 1688, 1066}, - {1688, 1066, 1688, 1066}, - {1688, 1066, 1688, 1066}, - {1688, 1066, 1688, 1066}, - {1688, 1066, 1688, 1066}, - {1688, 1066, 1688, 1066}, - {1688, 1066, 1688, 1066}, - {1688, 1066, 1688, 1066}, - {1688, 1066, 1688, 1066} -}; - -/* ;;[ycchen] 12/05/02 LCDHTxLCDVT=2048x1320 */ -static const struct SiS_LVDSData XGI_LVDS1600x1200Data_1[] = { - {1088, 520, 2048, 1320}, /* 00 (320x200,320x400,640x200,640x400) */ - {1088, 470, 2048, 1320}, /* 01 (320x350,640x350) */ - {1088, 520, 2048, 1320}, /* 02 (360x400,720x400) */ - {1088, 470, 2048, 1320}, /* 03 (720x350) */ - {1088, 600, 2048, 1320}, /* 04 (320x240,640x480) */ - {1248, 720, 2048, 1320}, /* 05 (400x300,800x600) */ - {1472, 888, 2048, 1320}, /* 06 (512x384,1024x768) */ - {1728, 1144, 2048, 1320}, /* 07 (640x512,1280x1024) */ - {1848, 1170, 2048, 1320}, /* 08 (1400x1050) */ - {2048, 1320, 2048, 1320} /* 09 (1600x1200) */ -}; - -static const struct SiS_LVDSData XGI_LVDSNoScalingData[] = { - { 800, 449, 800, 449}, /* 00 (320x200,320x400,640x200,640x400) */ - { 800, 449, 800, 449}, /* 01 (320x350,640x350) */ - { 800, 449, 800, 449}, /* 02 (360x400,720x400) */ - { 800, 449, 800, 449}, /* 03 (720x350) */ - { 800, 525, 800, 525}, /* 04 (640x480x60Hz) */ - {1056, 628, 1056, 628}, /* 05 (800x600x60Hz) */ - {1344, 806, 1344, 806}, /* 06 (1024x768x60Hz) */ - {1688, 1066, 1688, 1066}, /* 07 (1280x1024x60Hz) */ - {1688, 1066, 1688, 1066}, /* 08 (1400x1050x60Hz) */ - {2160, 1250, 2160, 1250}, /* 09 (1600x1200x60Hz) */ - {1688, 806, 1688, 806} /* 0A (1280x768x60Hz) */ -}; - -static const struct SiS_LVDSData XGI_LVDS1024x768Data_1x75[] = { - { 960, 438, 1312, 800}, /* 00 (320x200,320x400,640x200,640x400) */ - { 960, 388, 1312, 800}, /* 01 (320x350,640x350) */ - {1040, 438, 1312, 800}, /* 02 (360x400,720x400) */ - {1040, 388, 1312, 800}, /* 03 (720x350) */ - { 928, 512, 1312, 800}, /* 04 (320x240,640x480) */ - {1088, 632, 1312, 800}, /* 05 (400x300,800x600) */ - {1312, 800, 1312, 800}, /* 06 (512x384,1024x768) */ -}; - -static const struct SiS_LVDSData XGI_LVDS1024x768Data_2x75[] = { - {1312, 800, 1312, 800}, /* ; 00 (320x200,320x400,640x200,640x400) */ - {1312, 800, 1312, 800}, /* ; 01 (320x350,640x350) */ - {1312, 800, 1312, 800}, /* ; 02 (360x400,720x400) */ - {1312, 800, 1312, 800}, /* ; 03 (720x350) */ - {1312, 800, 1312, 800}, /* ; 04 (320x240,640x480) */ - {1312, 800, 1312, 800}, /* ; 05 (400x300,800x600) */ - {1312, 800, 1312, 800}, /* ; 06 (512x384,1024x768) */ -}; - -static const struct SiS_LVDSData XGI_LVDS1280x1024Data_1x75[] = { - {1048, 442, 1688, 1066 }, /* ; 00 (320x200,320x400,640x200,640x400) */ - {1048, 392, 1688, 1066 }, /* ; 01 (320x350,640x350) */ - {1128, 442, 1688, 1066 }, /* ; 02 (360x400,720x400) */ - {1128, 392, 1688, 1066 }, /* ; 03 (720x350) */ - {1048, 522, 1688, 1066 }, /* ; 04 (320x240,640x480) */ - {1208, 642, 1688, 1066 }, /* ; 05 (400x300,800x600) */ - {1432, 810, 1688, 1066 }, /* ; 06 (512x384,1024x768) */ - {1688, 1066, 1688, 1066 }, /* ; 06; 07 (640x512,1280x1024) */ -}; - -static const struct SiS_LVDSData XGI_LVDS1280x1024Data_2x75[] = { - {1688, 1066, 1688, 1066 }, /* ; 00 (320x200,320x400,640x200,640x400) */ - {1688, 1066, 1688, 1066 }, /* ; 01 (320x350,640x350) */ - {1688, 1066, 1688, 1066 }, /* ; 02 (360x400,720x400) */ - {1688, 1066, 1688, 1066 }, /* ; 03 (720x350) */ - {1688, 1066, 1688, 1066 }, /* ; 04 (320x240,640x480) */ - {1688, 1066, 1688, 1066 }, /* ; 05 (400x300,800x600) */ - {1688, 1066, 1688, 1066 }, /* ; 06 (512x384,1024x768) */ - {1688, 1066, 1688, 1066 }, /* ; 06; 07 (640x512,1280x1024) */ -}; - -static const struct SiS_LVDSData XGI_LVDSNoScalingDatax75[] = { - { 800, 449, 800, 449}, /* ; 00 (320x200,320x400,640x200,640x400) */ - { 800, 449, 800, 449}, /* ; 01 (320x350,640x350) */ - { 900, 449, 900, 449}, /* ; 02 (360x400,720x400) */ - { 900, 449, 900, 449}, /* ; 03 (720x350) */ - { 800, 500, 800, 500}, /* ; 04 (640x480x75Hz) */ - {1056, 625, 1056, 625}, /* ; 05 (800x600x75Hz) */ - {1312, 800, 1312, 800}, /* ; 06 (1024x768x75Hz) */ - {1688, 1066, 1688, 1066}, /* ; 07 (1280x1024x75Hz) */ - {1688, 1066, 1688, 1066}, /* ; 08 (1400x1050x75Hz) - * ;;[ycchen] 12/19/02 - */ - {2160, 1250, 2160, 1250}, /* ; 09 (1600x1200x75Hz) */ - {1688, 806, 1688, 806}, /* ; 0A (1280x768x75Hz) */ -}; - -static const struct SiS_LVDSData XGI_LVDS1024x768Des_1[] = { - {0, 1048, 0, 771}, /* 00 (320x200,320x400,640x200,640x400) */ - {0, 1048, 0, 771}, /* 01 (320x350,640x350) */ - {0, 1048, 0, 771}, /* 02 (360x400,720x400) */ - {0, 1048, 0, 771}, /* 03 (720x350) */ - {0, 1048, 0, 771}, /* 04 (640x480x60Hz) */ - {0, 1048, 0, 771}, /* 05 (800x600x60Hz) */ - {0, 1048, 805, 770} /* 06 (1024x768x60Hz) */ -}; - -static const struct SiS_LVDSData XGI_LVDS1024x768Des_2[] = { - {1142, 856, 622, 587}, /* 00 (320x200,320x400,640x200,640x400) */ - {1142, 856, 597, 562}, /* 01 (320x350,640x350) */ - {1142, 856, 622, 587}, /* 02 (360x400,720x400) */ - {1142, 856, 597, 562}, /* 03 (720x350) */ - {1142, 1048, 722, 687}, /* 04 (640x480x60Hz) */ - {1232, 936, 722, 687}, /* 05 (800x600x60Hz) */ - { 0, 1048, 805, 771} /* 06 (1024x768x60Hz) */ -}; - -static const struct SiS_LVDSData XGI_LVDS1024x768Des_3[] = { - {320, 24, 622, 587}, /* 00 (320x200,320x400,640x200,640x400) */ - {320, 24, 597, 562}, /* 01 (320x350,640x350) */ - {320, 24, 622, 587}, /* 02 (360x400,720x400) */ - {320, 24, 597, 562}, /* 03 (720x350) */ - {320, 24, 722, 687} /* 04 (640x480x60Hz) */ -}; - -static const struct SiS_LVDSData XGI_LVDS1280x1024Des_1[] = { - {0, 1328, 0, 1025}, /* 00 (320x200,320x400,640x200,640x400) */ - {0, 1328, 0, 1025}, /* 01 (320x350,640x350) */ - {0, 1328, 0, 1025}, /* 02 (360x400,720x400) */ - {0, 1328, 0, 1025}, /* 03 (720x350) */ - {0, 1328, 0, 1025}, /* 04 (640x480x60Hz) */ - {0, 1328, 0, 1025}, /* 05 (800x600x60Hz) */ - {0, 1328, 0, 1025}, /* 06 (1024x768x60Hz) */ - {0, 1328, 1065, 1024} /* 07 (1280x1024x60Hz) */ -}; - - /* The Display setting for DE Mode Panel */ -static const struct SiS_LVDSData XGI_LVDS1280x1024Des_2[] = { - {1368, 1008, 752, 711}, /* 00 (320x200,320x400,640x200,640x400) */ - {1368, 1008, 729, 688}, /* 01 (320x350,640x350) */ - {1408, 1048, 752, 711}, /* 02 (360x400,720x400) */ - {1408, 1048, 729, 688}, /* 03 (720x350) */ - {1368, 1008, 794, 753}, /* 04 (640x480x60Hz) */ - {1448, 1068, 854, 813}, /* 05 (800x600x60Hz) */ - {1560, 1200, 938, 897}, /* 06 (1024x768x60Hz) */ - {0000, 1328, 0, 1025} /* 07 (1280x1024x60Hz) */ -}; - -static const struct SiS_LVDSData XGI_LVDS1400x1050Des_1[] = { - {0, 1448, 0, 1051}, /* 00 (320x200,320x400,640x200,640x400) */ - {0, 1448, 0, 1051}, /* 01 (320x350,640x350) */ - {0, 1448, 0, 1051}, /* 02 (360x400,720x400) */ - {0, 1448, 0, 1051}, /* 03 (720x350) */ - {0, 1448, 0, 1051}, /* 04 (640x480x60Hz) */ - {0, 1448, 0, 1051}, /* 05 (800x600x60Hz) */ - {0, 1448, 0, 1051}, /* 06 (1024x768x60Hz) */ - {0, 1448, 0, 1051}, /* 07 (1280x1024x60Hz) */ - {0, 1448, 0, 1051} /* 08 (1400x1050x60Hz) */ -}; - -static const struct SiS_LVDSData XGI_LVDS1400x1050Des_2[] = { - {1308, 1068, 781, 766}, /* 00 (320x200,320x400,640x200,640x400) */ - {1308, 1068, 781, 766}, /* 01 (320x350,640x350) */ - {1308, 1068, 781, 766}, /* 02 (360x400,720x400) */ - {1308, 1068, 781, 766}, /* 03 (720x350) */ - {1308, 1068, 781, 766}, /* 04 (640x480x60Hz) */ - {1388, 1148, 841, 826}, /* 05 (800x600x60Hz) */ - {1490, 1250, 925, 910}, /* 06 (1024x768x60Hz) */ - {1608, 1368, 1053, 1038}, /* 07 (1280x1024x60Hz) */ - { 0, 1448, 0, 1051} /* 08 (1400x1050x60Hz) */ -}; - -static const struct SiS_LVDSData XGI_LVDS1600x1200Des_1[] = { - {0, 1664, 0, 1201}, /* 00 (320x200,320x400,640x200,640x400) */ - {0, 1664, 0, 1201}, /* 01 (320x350,640x350) */ - {0, 1664, 0, 1201}, /* 02 (360x400,720x400) */ - {0, 1664, 0, 1201}, /* 03 (720x350) */ - {0, 1664, 0, 1201}, /* 04 (640x480x60Hz) */ - {0, 1664, 0, 1201}, /* 05 (800x600x60Hz) */ - {0, 1664, 0, 1201}, /* 06 (1024x768x60Hz) */ - {0, 1664, 0, 1201}, /* 07 (1280x1024x60Hz) */ - {0, 1664, 0, 1201}, /* 08 (1400x1050x60Hz) */ - {0, 1664, 0, 1201} /* 09 (1600x1200x60Hz) */ -}; - -static const struct XGI330_LCDDataDesStruct2 XGI_LVDSNoScalingDesData[] = { - {0, 648, 448, 405, 96, 2}, /* 00 (320x200,320x400, - * 640x200,640x400) - */ - {0, 648, 448, 355, 96, 2}, /* 01 (320x350,640x350) */ - {0, 648, 448, 405, 96, 2}, /* 02 (360x400,720x400) */ - {0, 648, 448, 355, 96, 2}, /* 03 (720x350) */ - {0, 648, 1, 483, 96, 2}, /* 04 (640x480x60Hz) */ - {0, 840, 627, 600, 128, 4}, /* 05 (800x600x60Hz) */ - {0, 1048, 805, 770, 136, 6}, /* 06 (1024x768x60Hz) */ - {0, 1328, 0, 1025, 112, 3}, /* 07 (1280x1024x60Hz) */ - {0, 1438, 0, 1051, 112, 3}, /* 08 (1400x1050x60Hz)*/ - {0, 1664, 0, 1201, 192, 3}, /* 09 (1600x1200x60Hz) */ - {0, 1328, 0, 0771, 112, 6} /* 0A (1280x768x60Hz) */ -}; - -/* ; 1024x768 Full-screen */ -static const struct SiS_LVDSData XGI_LVDS1024x768Des_1x75[] = { - {0, 1040, 0, 769}, /* ; 00 (320x200,320x400,640x200,640x400) */ - {0, 1040, 0, 769}, /* ; 01 (320x350,640x350) */ - {0, 1040, 0, 769}, /* ; 02 (360x400,720x400) */ - {0, 1040, 0, 769}, /* ; 03 (720x350) */ - {0, 1040, 0, 769}, /* ; 04 (640x480x75Hz) */ - {0, 1040, 0, 769}, /* ; 05 (800x600x75Hz) */ - {0, 1040, 0, 769} /* ; 06 (1024x768x75Hz) */ -}; - -/* ; 1024x768 center-screen (Enh. Mode) */ -static const struct SiS_LVDSData XGI_LVDS1024x768Des_2x75[] = { - {1142, 856, 622, 587}, /* 00 (320x200,320x400,640x200,640x400) */ - {1142, 856, 597, 562}, /* 01 (320x350,640x350) */ - {1142, 856, 622, 587}, /* 02 (360x400,720x400) */ - {1142, 856, 597, 562}, /* 03 (720x350) */ - {1142, 1048, 722, 687}, /* 04 (640x480x60Hz) */ - {1232, 936, 722, 687}, /* 05 (800x600x60Hz) */ - { 0, 1048, 805, 771} /* 06 (1024x768x60Hz) */ -}; - -/* ; 1024x768 center-screen (St.Mode) */ -static const struct SiS_LVDSData XGI_LVDS1024x768Des_3x75[] = { - {320, 24, 622, 587}, /* ; 00 (320x200,320x400,640x200,640x400) */ - {320, 24, 597, 562}, /* ; 01 (320x350,640x350) */ - {320, 24, 622, 587}, /* ; 02 (360x400,720x400) */ - {320, 24, 597, 562}, /* ; 03 (720x350) */ - {320, 24, 722, 687} /* ; 04 (640x480x60Hz) */ -}; - -static const struct SiS_LVDSData XGI_LVDS1280x1024Des_1x75[] = { - {0, 1296, 0, 1025}, /* ; 00 (320x200,320x400,640x200,640x400) */ - {0, 1296, 0, 1025}, /* ; 01 (320x350,640x350) */ - {0, 1296, 0, 1025}, /* ; 02 (360x400,720x400) */ - {0, 1296, 0, 1025}, /* ; 03 (720x350) */ - {0, 1296, 0, 1025}, /* ; 04 (640x480x75Hz) */ - {0, 1296, 0, 1025}, /* ; 05 (800x600x75Hz) */ - {0, 1296, 0, 1025}, /* ; 06 (1024x768x75Hz) */ - {0, 1296, 0, 1025} /* ; 07 (1280x1024x75Hz) */ -}; - -/* The Display setting for DE Mode Panel */ -/* Set DE as default */ -static const struct SiS_LVDSData XGI_LVDS1280x1024Des_2x75[] = { - {1368, 976, 752, 711}, /* ; 00 (320x200,320x400,640x200,640x400) */ - {1368, 976, 729, 688}, /* ; 01 (320x350,640x350) */ - {1408, 976, 752, 711}, /* ; 02 (360x400,720x400) */ - {1408, 976, 729, 688}, /* ; 03 (720x350) */ - {1368, 976, 794, 753}, /* ; 04 (640x480x75Hz) */ - {1448, 1036, 854, 813}, /* ; 05 (800x600x75Hz) */ - {1560, 1168, 938, 897}, /* ; 06 (1024x768x75Hz) */ - { 0, 1296, 0, 1025} /* ; 07 (1280x1024x75Hz) */ -}; - -/* Scaling LCD 75Hz */ -static const struct XGI330_LCDDataDesStruct2 XGI_LVDSNoScalingDesDatax75[] = { - {0, 648, 448, 405, 96, 2}, /* ; 00 (320x200,320x400, - * 640x200,640x400) - */ - {0, 648, 448, 355, 96, 2}, /* ; 01 (320x350,640x350) */ - {0, 729, 448, 405, 108, 2}, /* ; 02 (360x400,720x400) */ - {0, 729, 448, 355, 108, 2}, /* ; 03 (720x350) */ - {0, 656, 0, 481, 64, 3}, /* ; 04 (640x480x75Hz) */ - {0, 816, 0, 601, 80, 3}, /* ; 05 (800x600x75Hz) */ - {0, 1040, 0, 769, 96, 3}, /* ; 06 (1024x768x75Hz) */ - {0, 1296, 0, 1025, 144, 3}, /* ; 07 (1280x1024x75Hz) */ - {0, 1448, 0, 1051, 112, 3}, /* ; 08 (1400x1050x75Hz) */ - {0, 1664, 0, 1201, 192, 3}, /* ; 09 (1600x1200x75Hz) */ - {0, 1328, 0, 771, 112, 6} /* ; 0A (1280x768x75Hz) */ -}; - -/* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */ -static const struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11024x768_1_H[] = { - { {0x4B, 0x27, 0x8F, 0x32, 0x1B, 0x00, 0x45, 0x00} }, /* 00 (320x) */ - { {0x4B, 0x27, 0x8F, 0x2B, 0x03, 0x00, 0x44, 0x00} }, /* 01 (360x) */ - { {0x55, 0x31, 0x99, 0x46, 0x1D, 0x00, 0x55, 0x00} }, /* 02 (400x) */ - { {0x63, 0x3F, 0x87, 0x4A, 0x93, 0x00, 0x01, 0x00} }, /* 03 (512x) */ - { {0x73, 0x4F, 0x97, 0x55, 0x86, 0x00, 0x05, 0x00} }, /* 04 (640x) */ - { {0x73, 0x4F, 0x97, 0x55, 0x86, 0x00, 0x05, 0x00} }, /* 05 (720x) */ - { {0x87, 0x63, 0x8B, 0x69, 0x1A, 0x00, 0x26, 0x00} }, /* 06 (800x) */ - { {0xA3, 0x7F, 0x87, 0x86, 0x97, 0x00, 0x02, 0x00} } /* 07 (1024x) */ -}; - -/* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */ -static const struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11280x1024_1_H[] = { - { {0x56, 0x27, 0x9A, 0x30, 0x1E, 0x00, 0x05, 0x00 } }, /* 00 (320x) */ - { {0x56, 0x27, 0x9A, 0x30, 0x1E, 0x00, 0x05, 0x00 } }, /* 01 (360x) */ - { {0x60, 0x31, 0x84, 0x3A, 0x88, 0x00, 0x01, 0x00 } }, /* 02 (400x) */ - { {0x6E, 0x3F, 0x92, 0x48, 0x96, 0x00, 0x01, 0x00 } }, /* 03 (512x) */ - { {0x7E, 0x4F, 0x82, 0x58, 0x06, 0x00, 0x06, 0x00 } }, /* 04 (640x) */ - { {0x7E, 0x4F, 0x82, 0x58, 0x06, 0x00, 0x06, 0x00 } }, /* 05 (720x) */ - { {0x92, 0x63, 0x96, 0x6C, 0x1A, 0x00, 0x06, 0x00 } }, /* 06 (800x) */ - { {0xAE, 0x7F, 0x92, 0x88, 0x96, 0x00, 0x02, 0x00 } }, /* 07 (1024x) */ - { {0xCE, 0x9F, 0x92, 0xA8, 0x16, 0x00, 0x07, 0x00 } } /* 08 (1280x) */ -}; - -/* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */ -static const struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11024x768_2_H[] = { - { {0x63, 0x27, 0x87, 0x3B, 0x8C, 0x00, 0x01, 0x00} }, /* 00 (320x) */ - { {0x63, 0x27, 0x87, 0x3B, 0x8C, 0x00, 0x01, 0x00} }, /* 01 (360x) */ - { {0x63, 0x31, 0x87, 0x3D, 0x8E, 0x00, 0x01, 0x00} }, /* 02 (400x) */ - { {0x63, 0x3F, 0x87, 0x45, 0x96, 0x00, 0x01, 0x00} }, /* 03 (512x) */ - { {0xA3, 0x4F, 0x87, 0x6E, 0x9F, 0x00, 0x06, 0x00} }, /* 04 (640x) */ - { {0xA3, 0x4F, 0x87, 0x6E, 0x9F, 0x00, 0x06, 0x00} }, /* 05 (720x) */ - { {0xA3, 0x63, 0x87, 0x78, 0x89, 0x00, 0x02, 0x00} }, /* 06 (800x) */ - { {0xA3, 0x7F, 0x87, 0x86, 0x97, 0x00, 0x02, 0x00} } /* 07 (1024x) */ -}; - -/* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */ -static const struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11280x1024_2_H[] = { - { {0x7E, 0x3B, 0x9A, 0x44, 0x12, 0x00, 0x01, 0x00} }, /* 00 (320x) */ - { {0x7E, 0x3B, 0x9A, 0x44, 0x12, 0x00, 0x01, 0x00} }, /* 01 (360x) */ - { {0x7E, 0x40, 0x84, 0x49, 0x91, 0x00, 0x01, 0x00} }, /* 02 (400x) */ - { {0x7E, 0x47, 0x93, 0x50, 0x9E, 0x00, 0x01, 0x00} }, /* 03 (512x) */ - { {0xCE, 0x77, 0x8A, 0x80, 0x8E, 0x00, 0x02, 0x00} }, /* 04 (640x) */ - { {0xCE, 0x77, 0x8A, 0x80, 0x8E, 0x00, 0x02, 0x00} }, /* 05 (720x) */ - { {0xCE, 0x81, 0x94, 0x8A, 0x98, 0x00, 0x02, 0x00} }, /* 06 (800x) */ - { {0xCE, 0x8F, 0x82, 0x98, 0x06, 0x00, 0x07, 0x00} }, /* 07 (1024x) */ - { {0xCE, 0x9F, 0x92, 0xA8, 0x16, 0x00, 0x07, 0x00} } /* 08 (1280x) */ -}; - -/* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */ -static const struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11400x1050_1_H[] = { - { {0x47, 0x27, 0x8B, 0x2C, 0x1A, 0x00, 0x05, 0x00} }, /* 00 (320x) */ - { {0x47, 0x27, 0x8B, 0x30, 0x1E, 0x00, 0x05, 0x00} }, /* 01 (360x) */ - { {0x51, 0x31, 0x95, 0x36, 0x04, 0x00, 0x01, 0x00} }, /* 02 (400x) */ - { {0x5F, 0x3F, 0x83, 0x44, 0x92, 0x00, 0x01, 0x00} }, /* 03 (512x) */ - { {0x6F, 0x4F, 0x93, 0x54, 0x82, 0x00, 0x05, 0x00} }, /* 04 (640x) */ - { {0x6F, 0x4F, 0x93, 0x54, 0x82, 0x00, 0x05, 0x00} }, /* 05 (720x) */ - { {0x83, 0x63, 0x87, 0x68, 0x16, 0x00, 0x06, 0x00} }, /* 06 (800x) */ - { {0x9F, 0x7F, 0x83, 0x84, 0x92, 0x00, 0x02, 0x00} }, /* 07 (1024x) */ - { {0xBF, 0x9F, 0x83, 0xA4, 0x12, 0x00, 0x07, 0x00} }, /* 08 (1280x) */ - { {0xCE, 0xAE, 0x92, 0xB3, 0x01, 0x00, 0x03, 0x00} } /* 09 (1400x) */ -}; - -/* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */ -static const struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11400x1050_2_H[] = { - { {0x76, 0x3F, 0x83, 0x45, 0x8C, 0x00, 0x41, 0x00} }, /* 00 (320x) */ - { {0x76, 0x3F, 0x83, 0x45, 0x8C, 0x00, 0x41, 0x00} }, /* 01 (360x) */ - { {0x76, 0x31, 0x9A, 0x48, 0x9F, 0x00, 0x41, 0x00} }, /* 02 (400x) */ - { {0x76, 0x3F, 0x9A, 0x4F, 0x96, 0x00, 0x41, 0x00} }, /* 03 (512x) */ - { {0xCE, 0x7E, 0x82, 0x87, 0x9E, 0x00, 0x02, 0x00} }, /* 04 (640x) */ - { {0xCE, 0x7E, 0x82, 0x87, 0x9E, 0x00, 0x02, 0x00} }, /* 05 (720x) */ - { {0xCE, 0x63, 0x92, 0x96, 0x04, 0x00, 0x07, 0x00} }, /* 06 (800x) */ - { {0xCE, 0x7F, 0x92, 0xA4, 0x12, 0x00, 0x07, 0x00} }, /* 07 (1024x) */ - { {0xCE, 0x9F, 0x92, 0xB4, 0x02, 0x00, 0x03, 0x00} }, /* 08 (1280x) */ - { {0xCE, 0xAE, 0x92, 0xBC, 0x0A, 0x00, 0x03, 0x00} } /* 09 (1400x) */ -}; - -/* ;302lv channelA [ycchen] 12/05/02 LCDHT=2048 */ -/* ; CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */ -static const struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11600x1200_1_H[] = { - { {0x5B, 0x27, 0x9F, 0x32, 0x0A, 0x00, 0x01, 0x00} }, /* 00 (320x) */ - { {0x5B, 0x27, 0x9F, 0x32, 0x0A, 0x00, 0x01, 0x00} }, /* 01 (360x) */ - { {0x65, 0x31, 0x89, 0x3C, 0x94, 0x00, 0x01, 0x00} }, /* 02 (400x) */ - { {0x73, 0x3F, 0x97, 0x4A, 0x82, 0x00, 0x05, 0x00} }, /* 03 (512x) */ - { {0x83, 0x4F, 0x87, 0x51, 0x09, 0x00, 0x06, 0x00} }, /* 04 (640x) */ - { {0x83, 0x4F, 0x87, 0x51, 0x09, 0x00, 0x06, 0x00} }, /* 05 (720x) */ - { {0x97, 0x63, 0x9B, 0x65, 0x1D, 0x00, 0x06, 0xF0} }, /* 06 (800x) */ - { {0xB3, 0x7F, 0x97, 0x81, 0x99, 0x00, 0x02, 0x00} }, /* 07 (1024x) */ - { {0xD3, 0x9F, 0x97, 0xA1, 0x19, 0x00, 0x07, 0x00} }, /* 08 (1280x) */ - { {0xE2, 0xAE, 0x86, 0xB9, 0x91, 0x00, 0x03, 0x00} }, /* 09 (1400x) */ - { {0xFB, 0xC7, 0x9F, 0xC9, 0x81, 0x00, 0x07, 0x00} } /* 0A (1600x) */ -}; - -/* CR06,CR07,CR10,CR11,CR15,CR16,SR0A+CR09(5->7) */ -static const struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_1_V[] = { - { {0x97, 0x1F, 0x60, 0x87, 0x5D, 0x83, 0x10} }, /* 00 (x350) */ - { {0xB4, 0x1F, 0x92, 0x89, 0x8F, 0xB5, 0x30} }, /* 01 (x400) */ - { {0x04, 0x3E, 0xE2, 0x89, 0xDF, 0x05, 0x00} }, /* 02 (x480) */ - { {0x7C, 0xF0, 0x5A, 0x8F, 0x57, 0x7D, 0xA0} }, /* 03 (x600) */ - { {0x24, 0xF5, 0x02, 0x88, 0xFF, 0x25, 0x90} } /* 04 (x768) */ -}; - -/* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */ -static const struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_2_V[] = { - { {0x24, 0xBB, 0x31, 0x87, 0x5D, 0x25, 0x30} }, /* 00 (x350) */ - { {0x24, 0xBB, 0x4A, 0x80, 0x8F, 0x25, 0x30} }, /* 01 (x400) */ - { {0x24, 0xBB, 0x72, 0x88, 0xDF, 0x25, 0x30} }, /* 02 (x480) */ - { {0x24, 0xF1, 0xAE, 0x84, 0x57, 0x25, 0xB0} }, /* 03 (x600) */ - { {0x24, 0xF5, 0x02, 0x88, 0xFF, 0x25, 0x90} } /* 04 (x768) */ -}; - -/* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */ -static const struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_1_V[] = { - { {0x86, 0x1F, 0x5E, 0x82, 0x5D, 0x87, 0x00} }, /* 00 (x350) */ - { {0xB8, 0x1F, 0x90, 0x84, 0x8F, 0xB9, 0x30} }, /* 01 (x400) */ - { {0x08, 0x3E, 0xE0, 0x84, 0xDF, 0x09, 0x00} }, /* 02 (x480) */ - { {0x80, 0xF0, 0x58, 0x8C, 0x57, 0x81, 0xA0} }, /* 03 (x600) */ - { {0x28, 0xF5, 0x00, 0x84, 0xFF, 0x29, 0x90} }, /* 04 (x768) */ - { {0x28, 0x5A, 0x13, 0x87, 0xFF, 0x29, 0xA9} } /* 05 (x1024) */ -}; - -/* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */ -static const struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_2_V[] = { - { {0x28, 0xD2, 0xAF, 0x83, 0xAE, 0xD8, 0xA1} }, /* 00 (x350) */ - { {0x28, 0xD2, 0xC8, 0x8C, 0xC7, 0xF2, 0x81} }, /* 01 (x400) */ - { {0x28, 0xD2, 0xF0, 0x84, 0xEF, 0x1A, 0xB1} }, /* 02 (x480) */ - { {0x28, 0xDE, 0x2C, 0x8F, 0x2B, 0x56, 0x91} }, /* 03 (x600) */ - { {0x28, 0xDE, 0x80, 0x83, 0x7F, 0xAA, 0x91} }, /* 04 (x768) */ - { {0x28, 0x5A, 0x13, 0x87, 0xFF, 0x29, 0xA9} } /* 05 (x1024) */ -}; - -/* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */ -static const struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11400x1050_1_V[] = { - { {0x6C, 0x1F, 0x60, 0x84, 0x5D, 0x6D, 0x10} }, /* 00 (x350) */ - { {0x9E, 0x1F, 0x93, 0x86, 0x8F, 0x9F, 0x30} }, /* 01 (x400) */ - { {0xEE, 0x1F, 0xE2, 0x86, 0xDF, 0xEF, 0x10} }, /* 02 (x480) */ - { {0x66, 0xF0, 0x5A, 0x8e, 0x57, 0x67, 0xA0} }, /* 03 (x600) */ - { {0x0E, 0xF5, 0x02, 0x86, 0xFF, 0x0F, 0x90} }, /* 04 (x768) */ - { {0x0E, 0x5A, 0x02, 0x86, 0xFF, 0x0F, 0x89} }, /* 05 (x1024) */ - { {0x28, 0x10, 0x1A, 0x80, 0x19, 0x29, 0x0F} } /* 06 (x1050) */ -}; - -/* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */ -static const struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11400x1050_2_V[] = { - { {0x28, 0x92, 0xB6, 0x83, 0xB5, 0xCF, 0x81} }, /* 00 (x350) */ - { {0x28, 0x92, 0xD5, 0x82, 0xD4, 0xEE, 0x81} }, /* 01 (x400) */ - { {0x28, 0x92, 0xFD, 0x8A, 0xFC, 0x16, 0xB1} }, /* 02 (x480) */ - { {0x28, 0xD4, 0x39, 0x86, 0x57, 0x29, 0x81} }, /* 03 (x600) */ - { {0x28, 0xD4, 0x8D, 0x9A, 0xFF, 0x29, 0xA1} }, /* 04 (x768) */ - { {0x28, 0x5A, 0x0D, 0x9A, 0xFF, 0x29, 0xA9} }, /* 05 (x1024) */ - { {0x28, 0x10, 0x1A, 0x87, 0x19, 0x29, 0x8F} } /* 06 (x1050) */ -}; - -/* CR06,CR07,CR10,CR11,CR15,CR16,SR0A+CR09(5->7) */ -static const struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11600x1200_1_V[] = { - { {0xd4, 0x1F, 0x81, 0x84, 0x5D, 0xd5, 0x10} }, /* 00 (x350) */ - { {0x06, 0x3e, 0xb3, 0x86, 0x8F, 0x07, 0x20} }, /* 01 (x400) */ - { {0x56, 0xba, 0x03, 0x86, 0xDF, 0x57, 0x00} }, /* 02 (x480) */ - { {0xce, 0xF0, 0x7b, 0x8e, 0x57, 0xcf, 0xa0} }, /* 03 (x600) */ - { {0x76, 0xF5, 0x23, 0x86, 0xFF, 0x77, 0x90} }, /* 04 (x768) */ - { {0x76, 0x5A, 0x23, 0x86, 0xFF, 0x77, 0x89} }, /* 05 (x1024) */ - { {0x90, 0x10, 0x1A, 0x8E, 0x19, 0x91, 0x2F} }, /* 06 (x1050) */ - { {0x26, 0x11, 0xd3, 0x86, 0xaF, 0x27, 0x3f} } /* 07 (x1200) */ -}; - -/* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */ -static const struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11024x768_1_Hx75[] = { - { {0x4B, 0x27, 0x8F, 0x32, 0x1B, 0x00, 0x45, 0x00} },/* ; 00 (320x) */ - { {0x4B, 0x27, 0x8F, 0x2B, 0x03, 0x00, 0x44, 0x00} },/* ; 01 (360x) */ - { {0x55, 0x31, 0x99, 0x46, 0x1D, 0x00, 0x55, 0x00} },/* ; 02 (400x) */ - { {0x63, 0x3F, 0x87, 0x4A, 0x93, 0x00, 0x01, 0x00} },/* ; 03 (512x) */ - { {0x6F, 0x4F, 0x93, 0x54, 0x80, 0x00, 0x05, 0x00} },/* ; 04 (640x) */ - { {0x6F, 0x4F, 0x93, 0x54, 0x80, 0x00, 0x05, 0x00} },/* ; 05 (720x) */ - { {0x83, 0x63, 0x87, 0x68, 0x14, 0x00, 0x26, 0x00} },/* ; 06 (800x) */ - { {0x9F, 0x7F, 0x83, 0x85, 0x91, 0x00, 0x02, 0x00} } /* ; 07 (1024x) */ -}; - -/* CR06,CR07,CR10,CR11,CR15,CR16,SR0A+CR09(5->7) */ -static const struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_1_Vx75[] = { - { {0x97, 0x1F, 0x60, 0x87, 0x5D, 0x83, 0x10} },/* ; 00 (x350) */ - { {0xB4, 0x1F, 0x92, 0x89, 0x8F, 0xB5, 0x30} },/* ; 01 (x400) */ - { {0xFE, 0x1F, 0xE0, 0x84, 0xDF, 0xFF, 0x10} },/* ; 02 (x480) */ - { {0x76, 0xF0, 0x58, 0x8C, 0x57, 0x77, 0xA0} },/* ; 03 (x600) */ - { {0x1E, 0xF5, 0x00, 0x83, 0xFF, 0x1F, 0x90} } /* ; 04 (x768) */ -}; - -/* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */ -static const struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11024x768_2_Hx75[] = { - { {0x63, 0x27, 0x87, 0x3B, 0x8C, 0x00, 0x01, 0x00} },/* ; 00 (320x) */ - { {0x63, 0x27, 0x87, 0x3B, 0x8C, 0x00, 0x01, 0x00} },/* ; 01 (360x) */ - { {0x63, 0x31, 0x87, 0x3D, 0x8E, 0x00, 0x01, 0x00} },/* ; 02 (400x) */ - { {0x63, 0x3F, 0x87, 0x45, 0x96, 0x00, 0x01, 0x00} },/* ; 03 (512x) */ - { {0xA3, 0x4F, 0x87, 0x6E, 0x9F, 0x00, 0x06, 0x00} },/* ; 04 (640x) */ - { {0xA3, 0x4F, 0x87, 0x6E, 0x9F, 0x00, 0x06, 0x00} },/* ; 05 (720x) */ - { {0xA3, 0x63, 0x87, 0x78, 0x89, 0x00, 0x02, 0x00} },/* ; 06 (800x) */ - { {0xA3, 0x7F, 0x87, 0x86, 0x97, 0x00, 0x02, 0x00} } /* ; 07 (1024x) */ -}; - -/* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */ -static const struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_2_Vx75[] = { - { {0x24, 0xBB, 0x31, 0x87, 0x5D, 0x25, 0x30} },/* ; 00 (x350) */ - { {0x24, 0xBB, 0x4A, 0x80, 0x8F, 0x25, 0x30} },/* ; 01 (x400) */ - { {0x24, 0xBB, 0x72, 0x88, 0xDF, 0x25, 0x30} },/* ; 02 (x480) */ - { {0x24, 0xF1, 0xAE, 0x84, 0x57, 0x25, 0xB0} },/* ; 03 (x600) */ - { {0x24, 0xF5, 0x02, 0x88, 0xFF, 0x25, 0x90} } /* ; 04 (x768) */ -}; - -/* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */ -static const struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11280x1024_1_Hx75[] = { - { {0x56, 0x27, 0x9A, 0x30, 0x1E, 0x00, 0x05, 0x00} },/* ; 00 (320x) */ - { {0x56, 0x27, 0x9A, 0x30, 0x1E, 0x00, 0x05, 0x00} },/* ; 01 (360x) */ - { {0x60, 0x31, 0x84, 0x3A, 0x88, 0x00, 0x01, 0x00} },/* ; 02 (400x) */ - { {0x6E, 0x3F, 0x92, 0x48, 0x96, 0x00, 0x01, 0x00} },/* ; 03 (512x) */ - { {0x7E, 0x4F, 0x82, 0x54, 0x06, 0x00, 0x06, 0x00} },/* ; 04 (640x) */ - { {0x7E, 0x4F, 0x82, 0x54, 0x06, 0x00, 0x06, 0x00} },/* ; 05 (720x) */ - { {0x92, 0x63, 0x96, 0x68, 0x1A, 0x00, 0x06, 0x00} },/* ; 06 (800x) */ - { {0xAE, 0x7F, 0x92, 0x84, 0x96, 0x00, 0x02, 0x00} },/* ; 07 (1024x) */ - { {0xCE, 0x9F, 0x92, 0xA5, 0x17, 0x00, 0x07, 0x00} } /* ; 08 (1280x) */ -}; - -/* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */ -static const struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_1_Vx75[] = { - { {0x86, 0xD1, 0xBC, 0x80, 0xBB, 0xE5, 0x00} },/* ; 00 (x350) */ - { {0xB8, 0x1F, 0x90, 0x84, 0x8F, 0xB9, 0x30} },/* ; 01 (x400) */ - { {0x08, 0x3E, 0xE0, 0x84, 0xDF, 0x09, 0x00} },/* ; 02 (x480) */ - { {0x80, 0xF0, 0x58, 0x8C, 0x57, 0x81, 0xA0} },/* ; 03 (x600) */ - { {0x28, 0xF5, 0x00, 0x84, 0xFF, 0x29, 0x90} },/* ; 04 (x768) */ - { {0x28, 0x5A, 0x13, 0x87, 0xFF, 0x29, 0xA9} } /* ; 05 (x1024) */ -}; - -/* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */ -static const struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11280x1024_2_Hx75[] = { - { {0x7E, 0x3B, 0x9A, 0x44, 0x12, 0x00, 0x01, 0x00} },/* ; 00 (320x) */ - { {0x7E, 0x3B, 0x9A, 0x44, 0x12, 0x00, 0x01, 0x00} },/* ; 01 (360x) */ - { {0x7E, 0x40, 0x84, 0x49, 0x91, 0x00, 0x01, 0x00} },/* ; 02 (400x) */ - { {0x7E, 0x47, 0x93, 0x50, 0x9E, 0x00, 0x01, 0x00} },/* ; 03 (512x) */ - { {0xCE, 0x77, 0x8A, 0x80, 0x8E, 0x00, 0x02, 0x00} },/* ; 04 (640x) */ - { {0xCE, 0x77, 0x8A, 0x80, 0x8E, 0x00, 0x02, 0x00} },/* ; 05 (720x) */ - { {0xCE, 0x81, 0x94, 0x8A, 0x98, 0x00, 0x02, 0x00} },/* ; 06 (800x) */ - { {0xCE, 0x8F, 0x82, 0x98, 0x06, 0x00, 0x07, 0x00} },/* ; 07 (1024x) */ - { {0xCE, 0x9F, 0x92, 0xA8, 0x16, 0x00, 0x07, 0x00} } /* ; 08 (1280x) */ -}; - -/* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */ -static const struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_2_Vx75[] = { - { {0x28, 0xD2, 0xAF, 0x83, 0xAE, 0xD8, 0xA1} },/* ; 00 (x350) */ - { {0x28, 0xD2, 0xC8, 0x8C, 0xC7, 0xF2, 0x81} },/* ; 01 (x400) */ - { {0x28, 0xD2, 0xF0, 0x84, 0xEF, 0x1A, 0xB1} },/* ; 02 (x480) */ - { {0x28, 0xDE, 0x2C, 0x8F, 0x2B, 0x56, 0x91} },/* ; 03 (x600) */ - { {0x28, 0xDE, 0x80, 0x83, 0x7F, 0xAA, 0x91} },/* ; 04 (x768) */ - { {0x28, 0x5A, 0x13, 0x87, 0xFF, 0x29, 0xA9} } /* ; 05 (x1024) */ -}; - -/*add for new UNIVGABIOS*/ -static const struct XGI330_LCDDataTablStruct XGI_LCDDataTable[] = { - {Panel_1024x768, 0x0019, 0x0001, XGI_ExtLCD1024x768Data }, - {Panel_1024x768, 0x0019, 0x0000, XGI_StLCD1024x768Data }, - {Panel_1024x768, 0x0018, 0x0010, XGI_CetLCD1024x768Data }, - {Panel_1280x1024, 0x0019, 0x0001, XGI_ExtLCD1280x1024Data }, - {Panel_1280x1024, 0x0019, 0x0000, XGI_StLCD1280x1024Data }, - {Panel_1280x1024, 0x0018, 0x0010, XGI_CetLCD1280x1024Data }, - {Panel_1400x1050, 0x0019, 0x0001, xgifb_lcd_1400x1050 }, - {Panel_1400x1050, 0x0019, 0x0000, xgifb_lcd_1400x1050 }, - {Panel_1400x1050, 0x0018, 0x0010, XGI_CetLCD1400x1050Data }, - {Panel_1600x1200, 0x0019, 0x0001, XGI_ExtLCD1600x1200Data }, - {Panel_1600x1200, 0x0019, 0x0000, XGI_StLCD1600x1200Data }, - {PanelRef60Hz, 0x0008, 0x0008, XGI_NoScalingData }, - {Panel_1024x768x75, 0x0019, 0x0001, XGI_ExtLCD1024x768x75Data }, - {Panel_1024x768x75, 0x0019, 0x0000, XGI_ExtLCD1024x768x75Data }, - {Panel_1024x768x75, 0x0018, 0x0010, XGI_CetLCD1024x768x75Data }, - {Panel_1280x1024x75, 0x0019, 0x0001, xgifb_lcd_1280x1024x75 }, - {Panel_1280x1024x75, 0x0019, 0x0000, xgifb_lcd_1280x1024x75 }, - {Panel_1280x1024x75, 0x0018, 0x0010, XGI_CetLCD1280x1024x75Data }, - {PanelRef75Hz, 0x0008, 0x0008, XGI_NoScalingDatax75 }, - {0xFF, 0x0000, 0x0000, NULL } /* End of table */ -}; - -static const struct XGI330_LCDDataTablStruct XGI_LCDDesDataTable[] = { - {Panel_1024x768, 0x0019, 0x0001, XGI_ExtLCDDes1024x768Data }, - {Panel_1024x768, 0x0019, 0x0000, XGI_StLCDDes1024x768Data }, - {Panel_1024x768, 0x0018, 0x0010, XGI_CetLCDDes1024x768Data }, - {Panel_1280x1024, 0x0019, 0x0001, XGI_ExtLCDDes1280x1024Data }, - {Panel_1280x1024, 0x0019, 0x0000, XGI_StLCDDes1280x1024Data }, - {Panel_1280x1024, 0x0018, 0x0010, XGI_CetLCDDes1280x1024Data }, - {Panel_1400x1050, 0x0019, 0x0001, xgifb_lcddes_1400x1050 }, - {Panel_1400x1050, 0x0019, 0x0000, xgifb_lcddes_1400x1050 }, - {Panel_1400x1050, 0x0418, 0x0010, XGI_CetLCDDes1400x1050Data }, - {Panel_1400x1050, 0x0418, 0x0410, XGI_CetLCDDes1400x1050Data2 }, - {Panel_1600x1200, 0x0019, 0x0001, XGI_ExtLCDDes1600x1200Data }, - {Panel_1600x1200, 0x0019, 0x0000, XGI_StLCDDes1600x1200Data }, - {PanelRef60Hz, 0x0008, 0x0008, XGI_NoScalingDesData }, - {Panel_1024x768x75, 0x0019, 0x0001, xgifb_lcddes_1024x768x75 }, - {Panel_1024x768x75, 0x0019, 0x0000, xgifb_lcddes_1024x768x75 }, - {Panel_1024x768x75, 0x0018, 0x0010, XGI_CetLCDDes1024x768x75Data }, - {Panel_1280x1024x75, 0x0019, 0x0001, xgifb_lcddes_1280x1024x75 }, - {Panel_1280x1024x75, 0x0019, 0x0000, xgifb_lcddes_1280x1024x75 }, - {Panel_1280x1024x75, 0x0018, 0x0010, XGI_CetLCDDes1280x1024x75Data }, - {PanelRef75Hz, 0x0008, 0x0008, XGI_NoScalingDesDatax75 }, - {0xFF, 0x0000, 0x0000, NULL } -}; - -static const struct XGI330_LCDDataTablStruct xgifb_lcddldes[] = { - {Panel_1024x768, 0x0019, 0x0001, XGI_ExtLCDDes1024x768Data }, - {Panel_1024x768, 0x0019, 0x0000, XGI_StLCDDes1024x768Data }, - {Panel_1024x768, 0x0018, 0x0010, XGI_CetLCDDes1024x768Data }, - {Panel_1280x1024, 0x0019, 0x0001, XGI_ExtLCDDLDes1280x1024Data }, - {Panel_1280x1024, 0x0019, 0x0000, XGI_StLCDDLDes1280x1024Data }, - {Panel_1280x1024, 0x0018, 0x0010, XGI_CetLCDDLDes1280x1024Data }, - {Panel_1400x1050, 0x0019, 0x0001, xgifb_lcddldes_1400x1050 }, - {Panel_1400x1050, 0x0019, 0x0000, xgifb_lcddldes_1400x1050 }, - {Panel_1400x1050, 0x0418, 0x0010, XGI_CetLCDDes1400x1050Data }, - {Panel_1400x1050, 0x0418, 0x0410, XGI_CetLCDDes1400x1050Data2 }, - {Panel_1600x1200, 0x0019, 0x0001, XGI_ExtLCDDLDes1600x1200Data }, - {Panel_1600x1200, 0x0019, 0x0000, XGI_StLCDDLDes1600x1200Data }, - {PanelRef60Hz, 0x0008, 0x0008, XGI_NoScalingDesData }, - {Panel_1024x768x75, 0x0019, 0x0001, xgifb_lcddes_1024x768x75 }, - {Panel_1024x768x75, 0x0019, 0x0000, xgifb_lcddes_1024x768x75 }, - {Panel_1024x768x75, 0x0018, 0x0010, XGI_CetLCDDes1024x768x75Data }, - {Panel_1280x1024x75, 0x0019, 0x0001, xgifb_lcddldes_1280x1024x75 }, - {Panel_1280x1024x75, 0x0019, 0x0000, xgifb_lcddldes_1280x1024x75 }, - {Panel_1280x1024x75, 0x0018, 0x0010, XGI_CetLCDDLDes1280x1024x75Data }, - {PanelRef75Hz, 0x0008, 0x0008, XGI_NoScalingDesDatax75 }, - {0xFF, 0x0000, 0x0000, NULL } -}; - -static const struct XGI330_LCDDataTablStruct xgifb_epllcd_crt1_h[] = { - {Panel_1024x768, 0x0018, 0x0000, XGI_LVDSCRT11024x768_1_H }, - {Panel_1024x768, 0x0018, 0x0010, XGI_LVDSCRT11024x768_2_H }, - {Panel_1280x1024, 0x0018, 0x0000, XGI_LVDSCRT11280x1024_1_H }, - {Panel_1280x1024, 0x0018, 0x0010, XGI_LVDSCRT11280x1024_2_H }, - {Panel_1400x1050, 0x0018, 0x0000, XGI_LVDSCRT11400x1050_1_H }, - {Panel_1400x1050, 0x0018, 0x0010, XGI_LVDSCRT11400x1050_2_H }, - {Panel_1600x1200, 0x0018, 0x0000, XGI_LVDSCRT11600x1200_1_H }, - {Panel_1024x768x75, 0x0018, 0x0000, XGI_LVDSCRT11024x768_1_Hx75 }, - {Panel_1024x768x75, 0x0018, 0x0010, XGI_LVDSCRT11024x768_2_Hx75 }, - {Panel_1280x1024x75, 0x0018, 0x0000, XGI_LVDSCRT11280x1024_1_Hx75 }, - {Panel_1280x1024x75, 0x0018, 0x0010, XGI_LVDSCRT11280x1024_2_Hx75 }, - {0xFF, 0x0000, 0x0000, NULL } -}; - -static const struct XGI330_LCDDataTablStruct xgifb_epllcd_crt1_v[] = { - {Panel_1024x768, 0x0018, 0x0000, XGI_LVDSCRT11024x768_1_V }, - {Panel_1024x768, 0x0018, 0x0010, XGI_LVDSCRT11024x768_2_V }, - {Panel_1280x1024, 0x0018, 0x0000, XGI_LVDSCRT11280x1024_1_V }, - {Panel_1280x1024, 0x0018, 0x0010, XGI_LVDSCRT11280x1024_2_V }, - {Panel_1400x1050, 0x0018, 0x0000, XGI_LVDSCRT11400x1050_1_V }, - {Panel_1400x1050, 0x0018, 0x0010, XGI_LVDSCRT11400x1050_2_V }, - {Panel_1600x1200, 0x0018, 0x0000, XGI_LVDSCRT11600x1200_1_V }, - {Panel_1024x768x75, 0x0018, 0x0000, XGI_LVDSCRT11024x768_1_Vx75 }, - {Panel_1024x768x75, 0x0018, 0x0010, XGI_LVDSCRT11024x768_2_Vx75 }, - {Panel_1280x1024x75, 0x0018, 0x0000, XGI_LVDSCRT11280x1024_1_Vx75 }, - {Panel_1280x1024x75, 0x0018, 0x0010, XGI_LVDSCRT11280x1024_2_Vx75 }, - {0xFF, 0x0000, 0x0000, NULL } -}; - -static const struct XGI330_LCDDataTablStruct XGI_EPLLCDDataPtr[] = { - {Panel_1024x768, 0x0018, 0x0000, XGI_LVDS1024x768Data_1 }, - {Panel_1024x768, 0x0018, 0x0010, XGI_LVDS1024x768Data_2 }, - {Panel_1280x1024, 0x0018, 0x0000, XGI_LVDS1280x1024Data_1 }, - {Panel_1280x1024, 0x0018, 0x0010, XGI_LVDS1280x1024Data_2 }, - {Panel_1400x1050, 0x0018, 0x0000, XGI_LVDS1400x1050Data_1 }, - {Panel_1400x1050, 0x0018, 0x0010, XGI_LVDS1400x1050Data_2 }, - {Panel_1600x1200, 0x0018, 0x0000, XGI_LVDS1600x1200Data_1 }, - {PanelRef60Hz, 0x0008, 0x0008, XGI_LVDSNoScalingData }, - {Panel_1024x768x75, 0x0018, 0x0000, XGI_LVDS1024x768Data_1x75 }, - {Panel_1024x768x75, 0x0018, 0x0010, XGI_LVDS1024x768Data_2x75 }, - {Panel_1280x1024x75, 0x0018, 0x0000, XGI_LVDS1280x1024Data_1x75 }, - {Panel_1280x1024x75, 0x0018, 0x0010, XGI_LVDS1280x1024Data_2x75 }, - {PanelRef75Hz, 0x0008, 0x0008, XGI_LVDSNoScalingDatax75 }, - {0xFF, 0x0000, 0x0000, NULL } -}; - -static const struct XGI330_LCDDataTablStruct XGI_EPLLCDDesDataPtr[] = { - {Panel_1024x768, 0x0018, 0x0000, XGI_LVDS1024x768Des_1 }, - {Panel_1024x768, 0x0618, 0x0410, XGI_LVDS1024x768Des_3 }, - {Panel_1024x768, 0x0018, 0x0010, XGI_LVDS1024x768Des_2 }, - {Panel_1280x1024, 0x0018, 0x0000, XGI_LVDS1280x1024Des_1 }, - {Panel_1280x1024, 0x0018, 0x0010, XGI_LVDS1280x1024Des_2 }, - {Panel_1400x1050, 0x0018, 0x0000, XGI_LVDS1400x1050Des_1 }, - {Panel_1400x1050, 0x0018, 0x0010, XGI_LVDS1400x1050Des_2 }, - {Panel_1600x1200, 0x0018, 0x0000, XGI_LVDS1600x1200Des_1 }, - {PanelRef60Hz, 0x0008, 0x0008, XGI_LVDSNoScalingDesData }, - {Panel_1024x768x75, 0x0018, 0x0000, XGI_LVDS1024x768Des_1x75 }, - {Panel_1024x768x75, 0x0618, 0x0410, XGI_LVDS1024x768Des_3x75 }, - {Panel_1024x768x75, 0x0018, 0x0010, XGI_LVDS1024x768Des_2x75 }, - {Panel_1280x1024x75, 0x0018, 0x0000, XGI_LVDS1280x1024Des_1x75 }, - {Panel_1280x1024x75, 0x0018, 0x0010, XGI_LVDS1280x1024Des_2x75 }, - {PanelRef75Hz, 0x0008, 0x0008, XGI_LVDSNoScalingDesDatax75 }, - {0xFF, 0x0000, 0x0000, NULL } -}; - -static const struct XGI330_TVDataTablStruct XGI_TVDataTable[] = { - {0x09E1, 0x0001, XGI_ExtPALData}, - {0x09E1, 0x0000, XGI_ExtNTSCData}, - {0x09E1, 0x0801, XGI_StPALData}, - {0x09E1, 0x0800, XGI_StNTSCData}, - {0x49E0, 0x0100, XGI_ExtHiTVData}, - {0x49E0, 0x4100, XGI_St2HiTVData}, - {0x49E0, 0x4900, XGI_St1HiTVData}, - {0x09E0, 0x0020, XGI_ExtYPbPr525iData}, - {0x09E0, 0x0040, XGI_ExtYPbPr525pData}, - {0x09E0, 0x0080, XGI_ExtYPbPr750pData}, - {0x09E0, 0x0820, XGI_StYPbPr525iData}, - {0x09E0, 0x0840, XGI_StYPbPr525pData}, - {0x09E0, 0x0880, XGI_StYPbPr750pData}, - {0xffff, 0x0000, XGI_ExtNTSCData}, -}; - -/* Dual link only */ -static const struct XGI330_LCDCapStruct XGI_LCDDLCapList[] = { -/* LCDCap1024x768 */ - {Panel_1024x768, DefaultLCDCap, 0x88, 0x06, VCLK65_315, - 0x6C, 0xC3, 0x35, 0x62, - 0x0A, 0xC0, 0x28, 0x10}, -/* LCDCap1280x1024 */ - {Panel_1280x1024, XGI_LCDDualLink + DefaultLCDCap, - 0x70, 0x03, VCLK108_2_315, - 0x70, 0x44, 0xF8, 0x2F, - 0x0A, 0xC0, 0x30, 0x10}, -/* LCDCap1400x1050 */ - {Panel_1400x1050, XGI_LCDDualLink + DefaultLCDCap, - 0x70, 0x03, VCLK108_2_315, - 0x70, 0x44, 0xF8, 0x2F, - 0x0A, 0xC0, 0x30, 0x10}, -/* LCDCap1600x1200 */ - {Panel_1600x1200, XGI_LCDDualLink + DefaultLCDCap, - 0xC0, 0x03, VCLK162, - 0x43, 0x22, 0x70, 0x24, - 0x0A, 0xC0, 0x30, 0x10}, -/* LCDCap1024x768x75 */ - {Panel_1024x768x75, DefaultLCDCap, 0x60, 0, VCLK78_75, - 0x2B, 0x61, 0x2B, 0x61, - 0x0A, 0xC0, 0x28, 0x10}, -/* LCDCap1280x1024x75 */ - {Panel_1280x1024x75, XGI_LCDDualLink + DefaultLCDCap, - 0x90, 0x03, VCLK135_5, - 0x54, 0x42, 0x4A, 0x61, - 0x0A, 0xC0, 0x30, 0x10}, -/* LCDCapDefault */ - {0xFF, DefaultLCDCap, 0x88, 0x06, VCLK65_315, - 0x6C, 0xC3, 0x35, 0x62, - 0x0A, 0xC0, 0x28, 0x10} -}; - -static const struct XGI330_LCDCapStruct XGI_LCDCapList[] = { -/* LCDCap1024x768 */ - {Panel_1024x768, DefaultLCDCap, 0x88, 0x06, VCLK65_315, - 0x6C, 0xC3, 0x35, 0x62, - 0x0A, 0xC0, 0x28, 0x10}, -/* LCDCap1280x1024 */ - {Panel_1280x1024, DefaultLCDCap, - 0x70, 0x03, VCLK108_2_315, - 0x70, 0x44, 0xF8, 0x2F, - 0x0A, 0xC0, 0x30, 0x10}, -/* LCDCap1400x1050 */ - {Panel_1400x1050, DefaultLCDCap, - 0x70, 0x03, VCLK108_2_315, - 0x70, 0x44, 0xF8, 0x2F, - 0x0A, 0xC0, 0x30, 0x10}, -/* LCDCap1600x1200 */ - {Panel_1600x1200, DefaultLCDCap, - 0xC0, 0x03, VCLK162, - 0x5A, 0x23, 0x5A, 0x23, - 0x0A, 0xC0, 0x30, 0x10}, -/* LCDCap1024x768x75 */ - {Panel_1024x768x75, DefaultLCDCap, 0x60, 0, VCLK78_75, - 0x2B, 0x61, 0x2B, 0x61, - 0x0A, 0xC0, 0x28, 0x10}, -/* LCDCap1280x1024x75 */ - {Panel_1280x1024x75, DefaultLCDCap, - 0x90, 0x03, VCLK135_5, - 0x54, 0x42, 0x4A, 0x61, - 0x0A, 0xC0, 0x30, 0x10}, -/* LCDCapDefault */ - {0xFF, DefaultLCDCap, 0x88, 0x06, VCLK65_315, - 0x6C, 0xC3, 0x35, 0x62, - 0x0A, 0xC0, 0x28, 0x10} -}; - -const struct XGI_Ext2Struct XGI330_RefIndex[] = { - {Mode32Bpp + SupportAllCRT2 + SyncPN, RES320x200, VCLK25_175, - 0x00, 0x10, 0x59, 320, 200},/* 00 */ - {Mode32Bpp + SupportAllCRT2 + SyncPN, RES320x200, VCLK25_175, - 0x00, 0x10, 0x00, 320, 400},/* 01 */ - {Mode32Bpp + SupportAllCRT2 + SyncNN, RES320x240, VCLK25_175, - 0x04, 0x20, 0x50, 320, 240},/* 02 */ - {Mode32Bpp + SupportAllCRT2 + SyncPP, RES400x300, VCLK40, - 0x05, 0x32, 0x51, 400, 300},/* 03 */ - {Mode32Bpp + NoSupportTV + SyncNN + SupportTV1024, RES512x384, - VCLK65_315, 0x06, 0x43, 0x52, 512, 384},/* 04 */ - {Mode32Bpp + SupportAllCRT2 + SyncPN, RES640x400, VCLK25_175, - 0x00, 0x14, 0x2f, 640, 400},/* 05 */ - {Mode32Bpp + SupportAllCRT2 + SyncNN, RES640x480x60, VCLK25_175, - 0x04, 0x24, 0x2e, 640, 480},/* 06 640x480x60Hz (LCD 640x480x60z) */ - {Mode32Bpp + NoSupportHiVisionTV + SyncNN, RES640x480x72, VCLK31_5, - 0x04, 0x24, 0x2e, 640, 480},/* 07 640x480x72Hz (LCD 640x480x70Hz) */ - {Mode32Bpp + NoSupportHiVisionTV + SyncNN, RES640x480x75, VCLK31_5, - 0x47, 0x24, 0x2e, 640, 480},/* 08 640x480x75Hz (LCD 640x480x75Hz) */ - {Mode32Bpp + SupportRAMDAC2 + SyncNN, RES640x480x85, VCLK36, - 0x8A, 0x24, 0x2e, 640, 480},/* 09 640x480x85Hz */ - {Mode32Bpp + SupportRAMDAC2 + SyncPN, RES640x480x100, VCLK43_163, - 0x00, 0x24, 0x2e, 640, 480},/* 0a 640x480x100Hz */ - {Mode32Bpp + SupportRAMDAC2 + SyncPN, RES640x480x120, VCLK52_406, - 0x00, 0x24, 0x2e, 640, 480},/* 0b 640x480x120Hz */ - {Mode32Bpp + SupportRAMDAC2 + SyncPN, RES640x480x160, VCLK72_852, - 0x00, 0x24, 0x2e, 640, 480},/* 0c 640x480x160Hz */ - {Mode32Bpp + SupportRAMDAC2 + SyncNN, RES640x480x200, VCLK86_6, - 0x00, 0x24, 0x2e, 640, 480},/* 0d 640x480x200Hz */ - {Mode32Bpp + NoSupportLCD + SyncPP, RES800x600x56, VCLK36, - 0x05, 0x36, 0x6a, 800, 600},/* 0e 800x600x56Hz */ - {Mode32Bpp + NoSupportTV + SyncPP, RES800x600x60, VCLK40, - 0x05, 0x36, 0x6a, 800, 600},/* 0f 800x600x60Hz (LCD 800x600x60Hz) */ - {Mode32Bpp + NoSupportHiVisionTV + SyncPP, RES800x600x72, VCLK50, - 0x48, 0x36, 0x6a, 800, 600},/* 10 800x600x72Hz (LCD 800x600x70Hz) */ - {Mode32Bpp + NoSupportHiVisionTV + SyncPP, RES800x600x75, VCLK49_5, - 0x8B, 0x36, 0x6a, 800, 600},/* 11 800x600x75Hz (LCD 800x600x75Hz) */ - {Mode32Bpp + SupportRAMDAC2 + SyncPP, RES800x600x85, VCLK56_25, - 0x00, 0x36, 0x6a, 800, 600},/* 12 800x600x85Hz */ - {Mode32Bpp + SupportRAMDAC2 + SyncPN, RES800x600x100, VCLK68_179, - 0x00, 0x36, 0x6a, 800, 600},/* 13 800x600x100Hz */ - {Mode32Bpp + SupportRAMDAC2 + SyncPN, RES800x600x120, VCLK83_95, - 0x00, 0x36, 0x6a, 800, 600},/* 14 800x600x120Hz */ - {Mode32Bpp + SupportRAMDAC2 + SyncPN, RES800x600x160, VCLK116_406, - 0x00, 0x36, 0x6a, 800, 600},/* 15 800x600x160Hz */ - {Mode32Bpp + InterlaceMode + SyncPP, RES1024x768x43, VCLK44_9, - 0x00, 0x47, 0x37, 1024, 768},/* 16 1024x768x43Hz */ - /* 17 1024x768x60Hz (LCD 1024x768x60Hz) */ - {Mode32Bpp + NoSupportTV + SyncNN + SupportTV1024, RES1024x768x60, - VCLK65_315, 0x06, 0x47, 0x37, 1024, 768}, - {Mode32Bpp + NoSupportHiVisionTV + SyncNN, RES1024x768x70, VCLK75, - 0x49, 0x47, 0x37, 1024, 768},/* 18 1024x768x70Hz (LCD 1024x768x70Hz) */ - {Mode32Bpp + NoSupportHiVisionTV + SyncPP, RES1024x768x75, VCLK78_75, - 0x00, 0x47, 0x37, 1024, 768},/* 19 1024x768x75Hz (LCD 1024x768x75Hz) */ - {Mode32Bpp + SupportRAMDAC2 + SyncPP, RES1024x768x85, VCLK94_5, - 0x8C, 0x47, 0x37, 1024, 768},/* 1a 1024x768x85Hz */ - {Mode32Bpp + SupportRAMDAC2 + SyncPN, RES1024x768x100, VCLK113_309, - 0x00, 0x47, 0x37, 1024, 768},/* 1b 1024x768x100Hz */ - {Mode32Bpp + SupportRAMDAC2 + SyncPN, RES1024x768x120, VCLK139_054, - 0x00, 0x47, 0x37, 1024, 768},/* 1c 1024x768x120Hz */ - {Mode32Bpp + SupportLCD + SyncPP, RES1280x960x60, VCLK108_2_315, - 0x08, 0x58, 0x7b, 1280, 960},/* 1d 1280x960x60Hz */ - {Mode32Bpp + InterlaceMode + SyncPP, RES1280x1024x43, VCLK78_75, - 0x00, 0x58, 0x3a, 1280, 1024},/* 1e 1280x1024x43Hz */ - {Mode32Bpp + NoSupportTV + SyncPP, RES1280x1024x60, VCLK108_2_315, - 0x07, 0x58, 0x3a, 1280, 1024},/*1f 1280x1024x60Hz (LCD 1280x1024x60Hz)*/ - {Mode32Bpp + NoSupportTV + SyncPP, RES1280x1024x75, VCLK135_5, - 0x00, 0x58, 0x3a, 1280, 1024},/*20 1280x1024x75Hz (LCD 1280x1024x75Hz)*/ - {Mode32Bpp + SyncPP, RES1280x1024x85, VCLK157_5, - 0x00, 0x58, 0x3a, 1280, 1024},/* 21 1280x1024x85Hz */ - /* 22 1600x1200x60Hz */ - {Mode32Bpp + SupportLCD + SyncPP + SupportCRT2in301C, - RES1600x1200x60, VCLK162, 0x09, 0x7A, 0x3c, 1600, 1200}, - {Mode32Bpp + SyncPP + SupportCRT2in301C, RES1600x1200x65, VCLK175, - 0x00, 0x69, 0x3c, 1600, 1200},/* 23 1600x1200x65Hz */ - {Mode32Bpp + SyncPP + SupportCRT2in301C, RES1600x1200x70, VCLK189, - 0x00, 0x69, 0x3c, 1600, 1200},/* 24 1600x1200x70Hz */ - {Mode32Bpp + SyncPP + SupportCRT2in301C, RES1600x1200x75, VCLK202_5, - 0x00, 0x69, 0x3c, 1600, 1200},/* 25 1600x1200x75Hz */ - {Mode32Bpp + SyncPP, RES1600x1200x85, VCLK229_5, - 0x00, 0x69, 0x3c, 1600, 1200},/* 26 1600x1200x85Hz */ - {Mode32Bpp + SyncPP, RES1600x1200x100, VCLK269_655, - 0x00, 0x69, 0x3c, 1600, 1200},/* 27 1600x1200x100Hz */ - {Mode32Bpp + SyncPP, RES1600x1200x120, VCLK323_586, - 0x00, 0x69, 0x3c, 1600, 1200},/* 28 1600x1200x120Hz */ - {Mode32Bpp + SupportLCD + SyncNP, RES1920x1440x60, VCLK234, - 0x00, 0x00, 0x68, 1920, 1440},/* 29 1920x1440x60Hz */ - {Mode32Bpp + SyncPN, RES1920x1440x65, VCLK254_817, - 0x00, 0x00, 0x68, 1920, 1440},/* 2a 1920x1440x65Hz */ - {Mode32Bpp + SyncPN, RES1920x1440x70, VCLK277_015, - 0x00, 0x00, 0x68, 1920, 1440},/* 2b 1920x1440x70Hz */ - {Mode32Bpp + SyncPN, RES1920x1440x75, VCLK291_132, - 0x00, 0x00, 0x68, 1920, 1440},/* 2c 1920x1440x75Hz */ - {Mode32Bpp + SyncPN, RES1920x1440x85, VCLK330_615, - 0x00, 0x00, 0x68, 1920, 1440},/* 2d 1920x1440x85Hz */ - {Mode16Bpp + SyncPN, RES1920x1440x100, VCLK388_631, - 0x00, 0x00, 0x68, 1920, 1440},/* 2e 1920x1440x100Hz */ - {Mode32Bpp + SupportLCD + SyncPN, RES2048x1536x60, VCLK266_952, - 0x00, 0x00, 0x6c, 2048, 1536},/* 2f 2048x1536x60Hz */ - {Mode32Bpp + SyncPN, RES2048x1536x65, VCLK291_766, - 0x00, 0x00, 0x6c, 2048, 1536},/* 30 2048x1536x65Hz */ - {Mode32Bpp + SyncPN, RES2048x1536x70, VCLK315_195, - 0x00, 0x00, 0x6c, 2048, 1536},/* 31 2048x1536x70Hz */ - {Mode32Bpp + SyncPN, RES2048x1536x75, VCLK340_477, - 0x00, 0x00, 0x6c, 2048, 1536},/* 32 2048x1536x75Hz */ - {Mode16Bpp + SyncPN, RES2048x1536x85, VCLK375_847, - 0x00, 0x00, 0x6c, 2048, 1536},/* 33 2048x1536x85Hz */ - {Mode32Bpp + SupportHiVision + SupportRAMDAC2 + - SyncPP + SupportYPbPr750p, RES800x480x60, VCLK39_77, - 0x08, 0x00, 0x70, 800, 480},/* 34 800x480x60Hz */ - {Mode32Bpp + SupportRAMDAC2 + SyncPP, RES800x480x75, VCLK49_5, - 0x08, 0x00, 0x70, 800, 480},/* 35 800x480x75Hz */ - {Mode32Bpp + SupportRAMDAC2 + SyncPP, RES800x480x85, VCLK56_25, - 0x08, 0x00, 0x70, 800, 480},/* 36 800x480x85Hz */ - {Mode32Bpp + SupportHiVision + SupportRAMDAC2 + - SyncPP + SupportYPbPr750p, RES1024x576x60, VCLK65_315, - 0x09, 0x00, 0x71, 1024, 576},/* 37 1024x576x60Hz */ - {Mode32Bpp + SupportRAMDAC2 + SyncPP, RES1024x576x75, VCLK78_75, - 0x09, 0x00, 0x71, 1024, 576},/* 38 1024x576x75Hz */ - {Mode32Bpp + SupportRAMDAC2 + SyncPP, RES1024x576x85, VCLK94_5, - 0x09, 0x00, 0x71, 1024, 576},/* 39 1024x576x85Hz */ - {Mode32Bpp + SupportHiVision + SupportRAMDAC2 + - SyncPP + SupportYPbPr750p, RES1280x720x60, VCLK108_2_315, - 0x0A, 0x00, 0x75, 1280, 720},/* 3a 1280x720x60Hz*/ - {Mode32Bpp + SupportRAMDAC2 + SyncPP, RES1280x720x75, VCLK135_5, - 0x0A, 0x00, 0x75, 1280, 720},/* 3b 1280x720x75Hz */ - {Mode32Bpp + SupportRAMDAC2 + SyncPP, RES1280x720x85, VCLK157_5, - 0x0A, 0x00, 0x75, 1280, 720},/* 3c 1280x720x85Hz */ - {Mode32Bpp + SupportTV + SyncNN, RES720x480x60, VCLK28_322, - 0x06, 0x00, 0x31, 720, 480},/* 3d 720x480x60Hz */ - {Mode32Bpp + SupportTV + SyncPP, RES720x576x56, VCLK36, - 0x06, 0x00, 0x32, 720, 576},/* 3e 720x576x56Hz */ - {Mode32Bpp + InterlaceMode + NoSupportLCD + SyncPP, RES856x480x79I, - VCLK35_2, 0x00, 0x00, 0x00, 856, 480},/* 3f 856x480x79I */ - {Mode32Bpp + NoSupportLCD + SyncNN, RES856x480x60, VCLK35_2, - 0x00, 0x00, 0x00, 856, 480},/* 40 856x480x60Hz */ - {Mode32Bpp + NoSupportHiVisionTV + SyncPP, RES1280x768x60, - VCLK79_411, 0x08, 0x48, 0x23, 1280, 768},/* 41 1280x768x60Hz */ - {Mode32Bpp + NoSupportHiVisionTV + SyncPP, RES1400x1050x60, - VCLK122_61, 0x08, 0x69, 0x26, 1400, 1050},/* 42 1400x1050x60Hz */ - {Mode32Bpp + SupportRAMDAC2 + SyncPP, RES1152x864x60, VCLK80_350, - 0x37, 0x00, 0x20, 1152, 864},/* 43 1152x864x60Hz */ - {Mode32Bpp + SupportRAMDAC2 + SyncPP, RES1152x864x75, VCLK107_385, - 0x37, 0x00, 0x20, 1152, 864},/* 44 1152x864x75Hz */ - {Mode32Bpp + SupportLCD + SupportRAMDAC2 + SyncPP, RES1280x960x75, - VCLK125_999, 0x3A, 0x88, 0x7b, 1280, 960},/* 45 1280x960x75Hz */ - {Mode32Bpp + SupportLCD + SupportRAMDAC2 + SyncPP, RES1280x960x85, - VCLK148_5, 0x0A, 0x88, 0x7b, 1280, 960},/* 46 1280x960x85Hz */ - {Mode32Bpp + SupportLCD + SupportRAMDAC2 + SyncPP, RES1280x960x120, - VCLK217_325, 0x3A, 0x88, 0x7b, 1280, 960},/* 47 1280x960x120Hz */ - {Mode32Bpp + SupportRAMDAC2 + SyncPN, RES1024x768x160, VCLK139_054, - 0x30, 0x47, 0x37, 1024, 768},/* 48 1024x768x160Hz */ -}; - -static const unsigned char XGI330_ScreenOffset[] = { - 0x14, 0x19, 0x20, 0x28, 0x32, 0x40, - 0x50, 0x64, 0x78, 0x80, 0x2d, 0x35, - 0x57, 0x48 -}; - -static const struct SiS_ModeResInfo_S XGI330_ModeResInfo[] = { - { 320, 200, 8, 8}, - { 320, 240, 8, 8}, - { 320, 400, 8, 8}, - { 400, 300, 8, 8}, - { 512, 384, 8, 8}, - { 640, 400, 8, 16}, - { 640, 480, 8, 16}, - { 800, 600, 8, 16}, - {1024, 768, 8, 16}, - {1280, 1024, 8, 16}, - {1600, 1200, 8, 16}, - {1920, 1440, 8, 16}, - {2048, 1536, 8, 16}, - { 720, 480, 8, 16}, - { 720, 576, 8, 16}, - {1280, 960, 8, 16}, - { 800, 480, 8, 16}, - {1024, 576, 8, 16}, - {1280, 720, 8, 16}, - { 856, 480, 8, 16}, - {1280, 768, 8, 16}, - {1400, 1050, 8, 16}, - {1152, 864, 8, 16} -}; - -const struct SiS_VCLKData XGI_VCLKData[] = { - /* SR2B,SR2C,SR2D */ - {0x1B, 0xE1, 25}, /* 00 (25.175MHz) */ - {0x4E, 0xE4, 28}, /* 01 (28.322MHz) */ - {0x57, 0xE4, 31}, /* 02 (31.500MHz) */ - {0xC3, 0xC8, 36}, /* 03 (36.000MHz) */ - {0x42, 0xE2, 40}, /* 04 (40.000MHz) */ - {0xFE, 0xCD, 43}, /* 05 (43.163MHz) */ - {0x5D, 0xC4, 44}, /* 06 (44.900MHz) */ - {0x52, 0xE2, 49}, /* 07 (49.500MHz) */ - {0x53, 0xE2, 50}, /* 08 (50.000MHz) */ - {0x74, 0x67, 52}, /* 09 (52.406MHz) */ - {0x6D, 0x66, 56}, /* 0A (56.250MHz) */ - {0x6C, 0xC3, 65}, /* 0B (65.000MHz) */ - {0x46, 0x44, 67}, /* 0C (67.765MHz) */ - {0xB1, 0x46, 68}, /* 0D (68.179MHz) */ - {0xD3, 0x4A, 72}, /* 0E (72.852MHz) */ - {0x29, 0x61, 75}, /* 0F (75.000MHz) */ - {0x6E, 0x46, 76}, /* 10 (75.800MHz) */ - {0x2B, 0x61, 78}, /* 11 (78.750MHz) */ - {0x31, 0x42, 79}, /* 12 (79.411MHz) */ - {0xAB, 0x44, 83}, /* 13 (83.950MHz) */ - {0x46, 0x25, 84}, /* 14 (84.800MHz) */ - {0x78, 0x29, 86}, /* 15 (86.600MHz) */ - {0x62, 0x44, 94}, /* 16 (94.500MHz) */ - {0x2B, 0x41, 104}, /* 17 (104.998MHz) */ - {0x3A, 0x23, 105}, /* 18 (105.882MHz) */ - {0x70, 0x44, 108}, /* 19 (107.862MHz) */ - {0x3C, 0x23, 109}, /* 1A (109.175MHz) */ - {0x5E, 0x43, 113}, /* 1B (113.309MHz) */ - {0xBC, 0x44, 116}, /* 1C (116.406MHz) */ - {0xE0, 0x46, 132}, /* 1D (132.258MHz) */ - {0x54, 0x42, 135}, /* 1E (135.500MHz) */ - {0x9C, 0x22, 139}, /* 1F (139.275MHz) */ - {0x41, 0x22, 157}, /* 20 (157.500MHz) */ - {0x70, 0x24, 162}, /* 21 (161.793MHz) */ - {0x30, 0x21, 175}, /* 22 (175.000MHz) */ - {0x4E, 0x22, 189}, /* 23 (188.520MHz) */ - {0xDE, 0x26, 194}, /* 24 (194.400MHz) */ - {0x62, 0x06, 202}, /* 25 (202.500MHz) */ - {0x3F, 0x03, 229}, /* 26 (229.500MHz) */ - {0xB8, 0x06, 234}, /* 27 (233.178MHz) */ - {0x34, 0x02, 253}, /* 28 (252.699MHz) */ - {0x58, 0x04, 255}, /* 29 (254.817MHz) */ - {0x24, 0x01, 265}, /* 2A (265.728MHz) */ - {0x9B, 0x02, 267}, /* 2B (266.952MHz) */ - {0x70, 0x05, 270}, /* 2C (269.65567MHz) */ - {0x25, 0x01, 272}, /* 2D (272.04199MHz) */ - {0x9C, 0x02, 277}, /* 2E (277.015MHz) */ - {0x27, 0x01, 286}, /* 2F (286.359985MHz) */ - {0xB3, 0x04, 291}, /* 30 (291.13266MHz) */ - {0xBC, 0x05, 292}, /* 31 (291.766MHz) */ - {0xF6, 0x0A, 310}, /* 32 (309.789459MHz) */ - {0x95, 0x01, 315}, /* 33 (315.195MHz) */ - {0xF0, 0x09, 324}, /* 34 (323.586792MHz) */ - {0xFE, 0x0A, 331}, /* 35 (330.615631MHz) */ - {0xF3, 0x09, 332}, /* 36 (332.177612MHz) */ - {0x5E, 0x03, 340}, /* 37 (340.477MHz) */ - {0xE8, 0x07, 376}, /* 38 (375.847504MHz) */ - {0xDE, 0x06, 389}, /* 39 (388.631439MHz) */ - {0x52, 0x2A, 54}, /* 3A (54.000MHz) */ - {0x52, 0x6A, 27}, /* 3B (27.000MHz) */ - {0x62, 0x24, 70}, /* 3C (70.874991MHz) */ - {0x62, 0x64, 70}, /* 3D (70.1048912MHz) */ - {0xA8, 0x4C, 30}, /* 3E (30.1048912MHz) */ - {0x20, 0x26, 33}, /* 3F (33.7499957MHz) */ - {0x31, 0xc2, 39}, /* 40 (39.77MHz) */ - {0x11, 0x21, 30}, /* 41 (30MHz) }// NTSC 1024X768 */ - {0x2E, 0x48, 25}, /* 42 (25.175MHz) }// ScaleLCD */ - {0x24, 0x46, 25}, /* 43 (25.175MHz) */ - {0x26, 0x64, 28}, /* 44 (28.322MHz) */ - {0x37, 0x64, 40}, /* 45 (40.000MHz) */ - {0xA1, 0x42, 108}, /* 46 (95.000MHz) }// QVGA */ - {0x37, 0x61, 100}, /* 47 (100.00MHz) */ - {0x78, 0x27, 108}, /* 48 (108.200MHz) */ - {0xBF, 0xC8, 35}, /* 49 (35.2MHz) */ - {0x66, 0x43, 123}, /* 4A (122.61Mhz) */ - {0x2C, 0x61, 80}, /* 4B (80.350Mhz) */ - {0x3B, 0x61, 108}, /* 4C (107.385Mhz) */ - {0x69, 0x61, 191}, /* 4D (190.96MHz ) */ - {0x4F, 0x22, 192}, /* 4E (192.069MHz) */ - {0x28, 0x26, 322}, /* 4F (322.273MHz) */ - {0x5C, 0x6B, 27}, /* 50 (27.74HMz) */ - {0x57, 0x24, 126}, /* 51 (125.999MHz) */ - {0x5C, 0x42, 148}, /* 52 (148.5MHz) */ - {0x42, 0x61, 120}, /* 53 (120.839MHz) */ - {0x62, 0x61, 178}, /* 54 (178.992MHz) */ - {0x59, 0x22, 217}, /* 55 (217.325MHz) */ - {0x29, 0x01, 300}, /* 56 (299.505Mhz) */ - {0x52, 0x63, 74}, /* 57 (74.25MHz) */ - {0xFF, 0x00, 0} /* End mark */ -}; - -static const struct SiS_VBVCLKData XGI_VBVCLKData[] = { - {0x1B, 0xE1, 25}, /* 00 (25.175MHz) */ - {0x4E, 0xE4, 28}, /* 01 (28.322MHz) */ - {0x57, 0xE4, 31}, /* 02 (31.500MHz) */ - {0xC3, 0xC8, 36}, /* 03 (36.000MHz) */ - {0x42, 0x47, 40}, /* 04 (40.000MHz) */ - {0xFE, 0xCD, 43}, /* 05 (43.163MHz) */ - {0x5D, 0xC4, 44}, /* 06 (44.900MHz) */ - {0x52, 0x47, 49}, /* 07 (49.500MHz) */ - {0x53, 0x47, 50}, /* 08 (50.000MHz) */ - {0x74, 0x67, 52}, /* 09 (52.406MHz) */ - {0x6D, 0x66, 56}, /* 0A (56.250MHz) */ - {0x35, 0x62, 65}, /* 0B (65.000MHz) */ - {0x46, 0x44, 67}, /* 0C (67.765MHz) */ - {0xB1, 0x46, 68}, /* 0D (68.179MHz) */ - {0xD3, 0x4A, 72}, /* 0E (72.852MHz) */ - {0x29, 0x61, 75}, /* 0F (75.000MHz) */ - {0x6D, 0x46, 75}, /* 10 (75.800MHz) */ - {0x41, 0x43, 78}, /* 11 (78.750MHz) */ - {0x31, 0x42, 79}, /* 12 (79.411MHz) */ - {0xAB, 0x44, 83}, /* 13 (83.950MHz) */ - {0x46, 0x25, 84}, /* 14 (84.800MHz) */ - {0x78, 0x29, 86}, /* 15 (86.600MHz) */ - {0x62, 0x44, 94}, /* 16 (94.500MHz) */ - {0x2B, 0x22, 104}, /* 17 (104.998MHz) */ - {0x49, 0x24, 105}, /* 18 (105.882MHz) */ - {0xF8, 0x2F, 108}, /* 19 (108.279MHz) */ - {0x3C, 0x23, 109}, /* 1A (109.175MHz) */ - {0x5E, 0x43, 113}, /* 1B (113.309MHz) */ - {0xBC, 0x44, 116}, /* 1C (116.406MHz) */ - {0xE0, 0x46, 132}, /* 1D (132.258MHz) */ - {0xD4, 0x28, 135}, /* 1E (135.220MHz) */ - {0xEA, 0x2A, 139}, /* 1F (139.275MHz) */ - {0x41, 0x22, 157}, /* 20 (157.500MHz) */ - {0x70, 0x24, 162}, /* 21 (161.793MHz) */ - {0x30, 0x21, 175}, /* 22 (175.000MHz) */ - {0x4E, 0x22, 189}, /* 23 (188.520MHz) */ - {0xDE, 0x26, 194}, /* 24 (194.400MHz) */ - {0x70, 0x07, 202}, /* 25 (202.500MHz) */ - {0x3F, 0x03, 229}, /* 26 (229.500MHz) */ - {0xB8, 0x06, 234}, /* 27 (233.178MHz) */ - {0x34, 0x02, 253}, /* 28 (252.699997 MHz) */ - {0x58, 0x04, 255}, /* 29 (254.817MHz) */ - {0x24, 0x01, 265}, /* 2A (265.728MHz) */ - {0x9B, 0x02, 267}, /* 2B (266.952MHz) */ - {0x70, 0x05, 270}, /* 2C (269.65567 MHz) */ - {0x25, 0x01, 272}, /* 2D (272.041992 MHz) */ - {0x9C, 0x02, 277}, /* 2E (277.015MHz) */ - {0x27, 0x01, 286}, /* 2F (286.359985 MHz) */ - {0x3C, 0x02, 291}, /* 30 (291.132660 MHz) */ - {0xEF, 0x0A, 292}, /* 31 (291.766MHz) */ - {0xF6, 0x0A, 310}, /* 32 (309.789459 MHz) */ - {0x95, 0x01, 315}, /* 33 (315.195MHz) */ - {0xF0, 0x09, 324}, /* 34 (323.586792 MHz) */ - {0xFE, 0x0A, 331}, /* 35 (330.615631 MHz) */ - {0xF3, 0x09, 332}, /* 36 (332.177612 MHz) */ - {0xEA, 0x08, 340}, /* 37 (340.477MHz) */ - {0xE8, 0x07, 376}, /* 38 (375.847504 MHz) */ - {0xDE, 0x06, 389}, /* 39 (388.631439 MHz) */ - {0x52, 0x2A, 54}, /* 3A (54.000MHz) */ - {0x52, 0x6A, 27}, /* 3B (27.000MHz) */ - {0x62, 0x24, 70}, /* 3C (70.874991MHz) */ - {0x62, 0x64, 70}, /* 3D (70.1048912MHz) */ - {0xA8, 0x4C, 30}, /* 3E (30.1048912MHz) */ - {0x20, 0x26, 33}, /* 3F (33.7499957MHz) */ - {0x31, 0xc2, 39}, /* 40 (39.77MHz) */ - {0x11, 0x21, 30}, /* 41 (30MHz) }// NTSC 1024X768 */ - {0x2E, 0x48, 25}, /* 42 (25.175MHz) }// ScaleLCD */ - {0x24, 0x46, 25}, /* 43 (25.175MHz) */ - {0x26, 0x64, 28}, /* 44 (28.322MHz) */ - {0x37, 0x64, 40}, /* 45 (40.000MHz) */ - {0xA1, 0x42, 108}, /* 46 (95.000MHz) }// QVGA */ - {0x37, 0x61, 100}, /* 47 (100.00MHz) */ - {0x78, 0x27, 108}, /* 48 (108.200MHz) */ - {0xBF, 0xC8, 35 }, /* 49 (35.2MHz) */ - {0x66, 0x43, 123}, /* 4A (122.61Mhz) */ - {0x2C, 0x61, 80 }, /* 4B (80.350Mhz) */ - {0x3B, 0x61, 108}, /* 4C (107.385Mhz) */ - {0x69, 0x61, 191}, /* 4D (190.96MHz ) */ - {0x4F, 0x22, 192}, /* 4E (192.069MHz) */ - {0x28, 0x26, 322}, /* 4F (322.273MHz) */ - {0x5C, 0x6B, 27}, /* 50 (27.74HMz) */ - {0x57, 0x24, 126}, /* 51 (125.999MHz) */ - {0x5C, 0x42, 148}, /* 52 (148.5MHz) */ - {0x42, 0x61, 120}, /* 53 (120.839MHz) */ - {0x62, 0x61, 178}, /* 54 (178.992MHz) */ - {0x59, 0x22, 217}, /* 55 (217.325MHz) */ - {0x29, 0x01, 300}, /* 56 (299.505Mhz) */ - {0x52, 0x63, 74}, /* 57 (74.25MHz) */ - {0xFF, 0x00, 0} /* End mark */ -}; - -#define XGI301TVDelay 0x22 -#define XGI301LCDDelay 0x12 - -static const unsigned char TVAntiFlickList[] = {/* NTSCAntiFlicker */ - 0x04, /* ; 0 Adaptive */ - 0x00, /* ; 1 new anti-flicker ? */ - - 0x04, /* ; 0 Adaptive */ - 0x08, /* ; 1 new anti-flicker ? */ - - 0x04, /* ; 0 ? */ - 0x00 /* ; 1 new anti-flicker ? */ -}; - -static const unsigned char TVEdgeList[] = { - 0x00, /* ; 0 NTSC No Edge enhance */ - 0x04, /* ; 1 NTSC Adaptive Edge enhance */ - 0x00, /* ; 0 PAL No Edge enhance */ - 0x04, /* ; 1 PAL Adaptive Edge enhance */ - 0x00, /* ; 0 HiTV */ - 0x00 /* ; 1 HiTV */ -}; - -static const unsigned long TVPhaseList[] = { - 0x08BAED21, /* ; 0 NTSC phase */ - 0x00E3052A, /* ; 1 PAL phase */ - 0x9B2EE421, /* ; 2 PAL-M phase */ - 0xBA3EF421, /* ; 3 PAL-N phase */ - 0xA7A28B1E, /* ; 4 NTSC 1024x768 */ - 0xE00A831E, /* ; 5 PAL-M 1024x768 */ - 0x00000000, /* ; 6 reserved */ - 0x00000000, /* ; 7 reserved */ - 0xD67BF021, /* ; 8 NTSC phase */ - 0xE986092A, /* ; 9 PAL phase */ - 0xA4EFE621, /* ; A PAL-M phase */ - 0x4694F621, /* ; B PAL-N phase */ - 0x8BDE711C, /* ; C NTSC 1024x768 */ - 0xE00A831E /* ; D PAL-M 1024x768 */ -}; - -static const unsigned char NTSCYFilter1[] = { - 0x00, 0xF4, 0x10, 0x38, /* 0 : 320x text mode */ - 0x00, 0xF4, 0x10, 0x38, /* 1 : 360x text mode */ - 0xEB, 0x04, 0x25, 0x18, /* 2 : 640x text mode */ - 0xF1, 0x04, 0x1F, 0x18, /* 3 : 720x text mode */ - 0x00, 0xF4, 0x10, 0x38, /* 4 : 320x gra. mode */ - 0xEB, 0x04, 0x25, 0x18, /* 5 : 640x gra. mode */ - 0xEB, 0x15, 0x25, 0xF6 /* 6 : 800x gra. mode */ -}; - -static const unsigned char PALYFilter1[] = { - 0x00, 0xF4, 0x10, 0x38, /* 0 : 320x text mode */ - 0x00, 0xF4, 0x10, 0x38, /* 1 : 360x text mode */ - 0xF1, 0xF7, 0x1F, 0x32, /* 2 : 640x text mode */ - 0xF3, 0x00, 0x1D, 0x20, /* 3 : 720x text mode */ - 0x00, 0xF4, 0x10, 0x38, /* 4 : 320x gra. mode */ - 0xF1, 0xF7, 0x1F, 0x32, /* 5 : 640x gra. mode */ - 0xFC, 0xFB, 0x14, 0x2A /* 6 : 800x gra. mode */ -}; - -static const unsigned char xgifb_palmn_yfilter1[] = { - 0x00, 0xF4, 0x10, 0x38, /* 0 : 320x text mode */ - 0x00, 0xF4, 0x10, 0x38, /* 1 : 360x text mode */ - 0xEB, 0x04, 0x10, 0x18, /* 2 : 640x text mode */ - 0xF7, 0x06, 0x19, 0x14, /* 3 : 720x text mode */ - 0x00, 0xF4, 0x10, 0x38, /* 4 : 320x gra. mode */ - 0xEB, 0x04, 0x25, 0x18, /* 5 : 640x gra. mode */ - 0xEB, 0x15, 0x25, 0xF6, /* 6 : 800x gra. mode */ - 0xFF, 0xFF, 0xFF, 0xFF /* End of Table */ -}; - -static const unsigned char xgifb_yfilter2[] = { - 0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46, /* 0 : 320x text mode */ - 0x01, 0x02, 0xFE, 0xF7, 0x03, 0x27, 0x3C, /* 1 : 360x text mode */ - 0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46, /* 2 : 640x text mode */ - 0x01, 0x02, 0xFE, 0xF7, 0x03, 0x27, 0x3C, /* 3 : 720x text mode */ - 0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46, /* 4 : 320x gra. mode */ - 0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46, /* 5 : 640x gra. mode */ - 0x01, 0x01, 0xFC, 0xF8, 0x08, 0x26, 0x38, /* 6 : 800x gra. mode */ - 0xFF, 0xFF, 0xFC, 0x00, 0x0F, 0x22, 0x28 /* 7 : 1024xgra. mode */ -}; - -static const unsigned char XGI_NTSC1024AdjTime[] = { - 0xa7, 0x07, 0xf2, 0x6e, 0x17, 0x8b, 0x73, 0x53, - 0x13, 0x40, 0x34, 0xF4, 0x63, 0xBB, 0xCC, 0x7A, - 0x58, 0xe4, 0x73, 0xd0, 0x13 -}; - -static const struct XGI301C_Tap4TimingStruct xgifb_tap4_timing[] = { - {0, { - 0x00, 0x20, 0x00, 0x00, 0x7F, 0x20, 0x02, 0x7F, /* ; C0-C7 */ - 0x7D, 0x20, 0x04, 0x7F, 0x7D, 0x1F, 0x06, 0x7E, /* ; C8-CF */ - 0x7C, 0x1D, 0x09, 0x7E, 0x7C, 0x1B, 0x0B, 0x7E, /* ; D0-D7 */ - 0x7C, 0x19, 0x0E, 0x7D, 0x7C, 0x17, 0x11, 0x7C, /* ; D8-DF */ - 0x7C, 0x14, 0x14, 0x7C, 0x7C, 0x11, 0x17, 0x7C, /* ; E0-E7 */ - 0x7D, 0x0E, 0x19, 0x7C, 0x7E, 0x0B, 0x1B, 0x7C, /* ; EA-EF */ - 0x7E, 0x09, 0x1D, 0x7C, 0x7F, 0x06, 0x1F, 0x7C, /* ; F0-F7 */ - 0x7F, 0x04, 0x20, 0x7D, 0x00, 0x02, 0x20, 0x7E /* ; F8-FF */ - } - } -}; - -static const struct XGI301C_Tap4TimingStruct PALTap4Timing[] = { - {600, { - 0x05, 0x19, 0x05, 0x7D, 0x03, 0x19, 0x06, 0x7E, /* ; C0-C7 */ - 0x02, 0x19, 0x08, 0x7D, 0x01, 0x18, 0x0A, 0x7D, /* ; C8-CF */ - 0x00, 0x18, 0x0C, 0x7C, 0x7F, 0x17, 0x0E, 0x7C, /* ; D0-D7 */ - 0x7E, 0x16, 0x0F, 0x7D, 0x7E, 0x14, 0x11, 0x7D, /* ; D8-DF */ - 0x7D, 0x13, 0x13, 0x7D, 0x7D, 0x11, 0x14, 0x7E, /* ; E0-E7 */ - 0x7D, 0x0F, 0x16, 0x7E, 0x7D, 0x0E, 0x17, 0x7E, /* ; EA-EF */ - 0x7D, 0x0C, 0x18, 0x7F, 0x7D, 0x0A, 0x18, 0x01, /* ; F0-F7 */ - 0x7D, 0x08, 0x19, 0x02, 0x7D, 0x06, 0x19, 0x04 /* ; F8-FF */ - } - }, - {768, { - 0x08, 0x12, 0x08, 0x7E, 0x07, 0x12, 0x09, 0x7E, /* ; C0-C7 */ - 0x06, 0x12, 0x0A, 0x7E, 0x05, 0x11, 0x0B, 0x7F, /* ; C8-CF */ - 0x04, 0x11, 0x0C, 0x7F, 0x03, 0x11, 0x0C, 0x00, /* ; D0-D7 */ - 0x03, 0x10, 0x0D, 0x00, 0x02, 0x0F, 0x0E, 0x01, /* ; D8-DF */ - 0x01, 0x0F, 0x0F, 0x01, 0x01, 0x0E, 0x0F, 0x02, /* ; E0-E7 */ - 0x00, 0x0D, 0x10, 0x03, 0x7F, 0x0C, 0x11, 0x04, /* ; EA-EF */ - 0x7F, 0x0C, 0x11, 0x04, 0x7F, 0x0B, 0x11, 0x05, /* ; F0-F7 */ - 0x7E, 0x0A, 0x12, 0x06, 0x7E, 0x09, 0x12, 0x07 /* ; F8-FF */ - } - }, - {0xFFFF, { - 0x04, 0x1A, 0x04, 0x7E, 0x02, 0x1B, 0x05, 0x7E, /* ; C0-C7 */ - 0x01, 0x1A, 0x07, 0x7E, 0x00, 0x1A, 0x09, 0x7D, /* ; C8-CF */ - 0x7F, 0x19, 0x0B, 0x7D, 0x7E, 0x18, 0x0D, 0x7D, /* ; D0-D7 */ - 0x7D, 0x17, 0x10, 0x7C, 0x7D, 0x15, 0x12, 0x7C, /* ; D8-DF */ - 0x7C, 0x14, 0x14, 0x7C, 0x7C, 0x12, 0x15, 0x7D, /* ; E0-E7 */ - 0x7C, 0x10, 0x17, 0x7D, 0x7C, 0x0D, 0x18, 0x7F, /* ; EA-EF */ - 0x7D, 0x0B, 0x19, 0x7F, 0x7D, 0x09, 0x1A, 0x00, /* ; F0-F7 */ - 0x7D, 0x07, 0x1A, 0x02, 0x7E, 0x05, 0x1B, 0x02 /* ; F8-FF */ - } - } -}; - -static const struct XGI301C_Tap4TimingStruct xgifb_ntsc_525_tap4_timing[] = { - {480, { - 0x04, 0x1A, 0x04, 0x7E, 0x03, 0x1A, 0x06, 0x7D, /* ; C0-C7 */ - 0x01, 0x1A, 0x08, 0x7D, 0x00, 0x19, 0x0A, 0x7D, /* ; C8-CF */ - 0x7F, 0x19, 0x0C, 0x7C, 0x7E, 0x18, 0x0E, 0x7C, /* ; D0-D7 */ - 0x7E, 0x17, 0x10, 0x7B, 0x7D, 0x15, 0x12, 0x7C, /* ; D8-DF */ - 0x7D, 0x13, 0x13, 0x7D, 0x7C, 0x12, 0x15, 0x7D, /* ; E0-E7 */ - 0x7C, 0x10, 0x17, 0x7D, 0x7C, 0x0E, 0x18, 0x7E, /* ; EA-EF */ - 0x7D, 0x0C, 0x19, 0x7E, 0x7D, 0x0A, 0x19, 0x00, /* ; F0-F7 */ - 0x7D, 0x08, 0x1A, 0x01, 0x7E, 0x06, 0x1A, 0x02 /* ; F8-FF */ - } - }, - {600, { - 0x07, 0x14, 0x07, 0x7E, 0x06, 0x14, 0x09, 0x7D, /* ; C0-C7 */ - 0x05, 0x14, 0x0A, 0x7D, 0x04, 0x13, 0x0B, 0x7E, /* ; C8-CF */ - 0x03, 0x13, 0x0C, 0x7E, 0x02, 0x12, 0x0D, 0x7F, /* ; D0-D7 */ - 0x01, 0x12, 0x0E, 0x7F, 0x01, 0x11, 0x0F, 0x7F, /* ; D8-DF */ - 0x01, 0x10, 0x10, 0x00, 0x7F, 0x0F, 0x11, 0x01, /* ; E0-E7 */ - 0x7F, 0x0E, 0x12, 0x01, 0x7E, 0x0D, 0x12, 0x03, /* ; EA-EF */ - 0x7E, 0x0C, 0x13, 0x03, 0x7E, 0x0B, 0x13, 0x04, /* ; F0-F7 */ - 0x7E, 0x0A, 0x14, 0x04, 0x7D, 0x09, 0x14, 0x06 /* ; F8-FF */ - } - }, - {0xFFFF, { - 0x09, 0x0F, 0x09, 0x7F, 0x08, 0x0F, 0x09, 0x00, /* ; C0-C7 */ - 0x07, 0x0F, 0x0A, 0x00, 0x06, 0x0F, 0x0A, 0x01, /* ; C8-CF */ - 0x06, 0x0E, 0x0B, 0x01, 0x05, 0x0E, 0x0B, 0x02, /* ; D0-D7 */ - 0x04, 0x0E, 0x0C, 0x02, 0x04, 0x0D, 0x0C, 0x03, /* ; D8-DF */ - 0x03, 0x0D, 0x0D, 0x03, 0x02, 0x0C, 0x0D, 0x05, /* ; E0-E7 */ - 0x02, 0x0C, 0x0E, 0x04, 0x01, 0x0B, 0x0E, 0x06, /* ; EA-EF */ - 0x01, 0x0B, 0x0E, 0x06, 0x00, 0x0A, 0x0F, 0x07, /* ; F0-F7 */ - 0x00, 0x0A, 0x0F, 0x07, 0x00, 0x09, 0x0F, 0x08 /* ; F8-FF */ - } - } -}; - -static const struct XGI301C_Tap4TimingStruct YPbPr750pTap4Timing[] = { - {0xFFFF, { - 0x05, 0x19, 0x05, 0x7D, 0x03, 0x19, 0x06, 0x7E, /* ; C0-C7 */ - 0x02, 0x19, 0x08, 0x7D, 0x01, 0x18, 0x0A, 0x7D, /* ; C8-CF */ - 0x00, 0x18, 0x0C, 0x7C, 0x7F, 0x17, 0x0E, 0x7C, /* ; D0-D7 */ - 0x7E, 0x16, 0x0F, 0x7D, 0x7E, 0x14, 0x11, 0x7D, /* ; D8-DF */ - 0x7D, 0x13, 0x13, 0x7D, 0x7D, 0x11, 0x14, 0x7E, /* ; E0-E7 */ - 0x7D, 0x0F, 0x16, 0x7E, 0x7D, 0x0E, 0x17, 0x7E, /* ; EA-EF */ - 0x7D, 0x0C, 0x18, 0x7F, 0x7D, 0x0A, 0x18, 0x01, /* ; F0-F7 */ - 0x7D, 0x08, 0x19, 0x02, 0x7D, 0x06, 0x19, 0x04 /* F8-FF */ - } - } -}; -#endif diff --git a/drivers/staging/xgifb/vb_util.h b/drivers/staging/xgifb/vb_util.h deleted file mode 100644 index 0f6d5aac04f6..000000000000 --- a/drivers/staging/xgifb/vb_util.h +++ /dev/null @@ -1,46 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef _VBUTIL_ -#define _VBUTIL_ -static inline void xgifb_reg_set(unsigned long port, u8 index, u8 data) -{ - outb(index, port); - outb(data, port + 1); -} - -static inline u8 xgifb_reg_get(unsigned long port, u8 index) -{ - outb(index, port); - return inb(port + 1); -} - -static inline void xgifb_reg_and_or(unsigned long port, u8 index, - unsigned int data_and, unsigned int data_or) -{ - u8 temp; - - temp = xgifb_reg_get(port, index); - temp = (u8)((temp & data_and) | data_or); - xgifb_reg_set(port, index, temp); -} - -static inline void xgifb_reg_and(unsigned long port, u8 index, - unsigned int data_and) -{ - u8 temp; - - temp = xgifb_reg_get(port, index); - temp = (u8)(temp & data_and); - xgifb_reg_set(port, index, temp); -} - -static inline void xgifb_reg_or(unsigned long port, u8 index, - unsigned int data_or) -{ - u8 temp; - - temp = xgifb_reg_get(port, index); - temp |= data_or; - xgifb_reg_set(port, index, temp); -} -#endif - diff --git a/drivers/staging/xgifb/vgatypes.h b/drivers/staging/xgifb/vgatypes.h deleted file mode 100644 index 22919f2368d5..000000000000 --- a/drivers/staging/xgifb/vgatypes.h +++ /dev/null @@ -1,51 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef _VGATYPES_ -#define _VGATYPES_ - -#include <linux/fb.h> /* for struct fb_var_screeninfo for sis.h */ -#include "../../video/fbdev/sis/vgatypes.h" -#include "../../video/fbdev/sis/sis.h" /* for LCD_TYPE */ - -enum XGI_VB_CHIP_TYPE { - VB_CHIP_Legacy = 0, - VB_CHIP_301, - VB_CHIP_301B, - VB_CHIP_301LV, - VB_CHIP_302, - VB_CHIP_302B, - VB_CHIP_302LV, - VB_CHIP_301C, - VB_CHIP_302ELV, - VB_CHIP_UNKNOWN, /* other video bridge or no video bridge */ - MAX_VB_CHIP -}; - -struct xgi_hw_device_info { - unsigned long ulExternalChip; /* NO VB or other video bridge*/ - /* if ujVBChipID = VB_CHIP_UNKNOWN, */ - - void __iomem *pjVideoMemoryAddress;/* base virtual memory address */ - /* of Linear VGA memory */ - - unsigned long ulVideoMemorySize; /* size, in bytes, of the - * memory on the board - */ - - unsigned char jChipType; /* Used to Identify Graphics Chip */ - /* defined in the data structure type */ - /* "XGI_CHIP_TYPE" */ - - unsigned char jChipRevision; /* Used to Identify Graphics - * Chip Revision - */ - - unsigned char ujVBChipID; /* the ID of video bridge */ - /* defined in the data structure type */ - /* "XGI_VB_CHIP_TYPE" */ - - unsigned long ulCRT2LCDType; /* defined in the data structure type */ -}; - -/* Additional IOCTL for communication xgifb <> X driver */ -/* If changing this, xgifb.h must also be changed (for xgifb) */ -#endif |