diff -Nru nct677x-dkms-1.0.1/debian/changelog nct677x-dkms-1.0.4/debian/changelog --- nct677x-dkms-1.0.1/debian/changelog 2010-04-14 09:16:27.000000000 +0000 +++ nct677x-dkms-1.0.4/debian/changelog 2010-10-29 11:38:45.000000000 +0000 @@ -1,3 +1,9 @@ +nct677x-dkms (1.0.4-1yavdr1) lucid; urgency=low + + * new upstream version + + -- Gerald Dachs Fri, 29 Oct 2010 13:37:59 +0200 + nct677x-dkms (1.0.1-8yavdr1) lucid; urgency=low * add lirc-nct677x-src as dummy-package diff -Nru nct677x-dkms-1.0.1/debian/rules nct677x-dkms-1.0.4/debian/rules --- nct677x-dkms-1.0.1/debian/rules 2010-03-31 15:56:51.000000000 +0000 +++ nct677x-dkms-1.0.4/debian/rules 2010-10-29 11:39:07.000000000 +0000 @@ -6,7 +6,7 @@ DEB_NAME=nct677x NAME=nct677x -VERSION=1.0.1 +VERSION=1.0.4 configure: configure-stamp configure-stamp: diff -Nru nct677x-dkms-1.0.1/dkms_binaries_only/dkms.conf nct677x-dkms-1.0.4/dkms_binaries_only/dkms.conf --- nct677x-dkms-1.0.1/dkms_binaries_only/dkms.conf 2010-03-30 21:42:35.000000000 +0000 +++ nct677x-dkms-1.0.4/dkms_binaries_only/dkms.conf 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -PACKAGE_NAME="nct677x" -PACKAGE_VERSION="1.0.1" -CLEAN="rm -f *.*o" -MAKE[0]="make -C src KSRC=$kernel_source_dir KVER=$kernelver modules" -AUTOINSTALL="yes" - -BUILT_MODULE_NAME[0]="lirc_wb677" -BUILT_MODULE_LOCATION[0]="src" -DEST_MODULE_LOCATION[0]="/updates" - diff -Nru nct677x-dkms-1.0.1/dkms_binaries_only/PACKAGE_NAME nct677x-dkms-1.0.4/dkms_binaries_only/PACKAGE_NAME --- nct677x-dkms-1.0.1/dkms_binaries_only/PACKAGE_NAME 2010-03-30 21:42:35.000000000 +0000 +++ nct677x-dkms-1.0.4/dkms_binaries_only/PACKAGE_NAME 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -nct677x diff -Nru nct677x-dkms-1.0.1/dkms_binaries_only/PACKAGE_VERSION nct677x-dkms-1.0.4/dkms_binaries_only/PACKAGE_VERSION --- nct677x-dkms-1.0.1/dkms_binaries_only/PACKAGE_VERSION 2010-03-30 21:42:35.000000000 +0000 +++ nct677x-dkms-1.0.4/dkms_binaries_only/PACKAGE_VERSION 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -1.0.1 diff -Nru nct677x-dkms-1.0.1/dkms_main_tree/2.6.32-18-generic/i686/log/make.log nct677x-dkms-1.0.4/dkms_main_tree/2.6.32-18-generic/i686/log/make.log --- nct677x-dkms-1.0.1/dkms_main_tree/2.6.32-18-generic/i686/log/make.log 2010-03-30 21:42:35.000000000 +0000 +++ nct677x-dkms-1.0.4/dkms_main_tree/2.6.32-18-generic/i686/log/make.log 1970-01-01 00:00:00.000000000 +0000 @@ -1,14 +0,0 @@ -DKMS make.log for nct677x-1.0.1 for kernel 2.6.32-18-generic (i686) -Di 30. Mär 23:36:46 CEST 2010 -make: Gehe in Verzeichnis '/var/lib/dkms/nct677x/1.0.1/build/src' -echo KERNELDIR=/lib/modules/2.6.32-18-generic/build -KERNELDIR=/lib/modules/2.6.32-18-generic/build -make -C /lib/modules/2.6.32-18-generic/build -I ../include M=/var/lib/dkms/nct677x/1.0.1/build/src modules -make[1]: Betrete Verzeichnis '/usr/src/linux-headers-2.6.32-18-generic' - CC [M] /var/lib/dkms/nct677x/1.0.1/build/src/lirc_wb677.o - Building modules, stage 2. - MODPOST 1 modules - CC /var/lib/dkms/nct677x/1.0.1/build/src/lirc_wb677.mod.o - LD [M] /var/lib/dkms/nct677x/1.0.1/build/src/lirc_wb677.ko -make[1]: Verlasse Verzeichnis '/usr/src/linux-headers-2.6.32-18-generic' -make: Verlasse Verzeichnis '/var/lib/dkms/nct677x/1.0.1/build/src' Binary files /tmp/k1JEjavQlr/nct677x-dkms-1.0.1/dkms_main_tree/2.6.32-18-generic/i686/module/lirc_wb677.ko and /tmp/Tw6xwgpSAd/nct677x-dkms-1.0.4/dkms_main_tree/2.6.32-18-generic/i686/module/lirc_wb677.ko differ diff -Nru nct677x-dkms-1.0.1/dkms_main_tree/dkms_dbversion nct677x-dkms-1.0.4/dkms_main_tree/dkms_dbversion --- nct677x-dkms-1.0.1/dkms_main_tree/dkms_dbversion 2010-03-30 21:42:35.000000000 +0000 +++ nct677x-dkms-1.0.4/dkms_main_tree/dkms_dbversion 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -2.0.0 diff -Nru nct677x-dkms-1.0.1/nct677x-1.0.1/dkms.conf nct677x-dkms-1.0.4/nct677x-1.0.1/dkms.conf --- nct677x-dkms-1.0.1/nct677x-1.0.1/dkms.conf 2010-03-31 15:56:50.000000000 +0000 +++ nct677x-dkms-1.0.4/nct677x-1.0.1/dkms.conf 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -PACKAGE_NAME="nct677x" -PACKAGE_VERSION="1.0.1" -CLEAN="rm -f *.*o" -MAKE[0]="make -C src KSRC=$kernel_source_dir KVER=$kernelver modules" -AUTOINSTALL="yes" - -BUILT_MODULE_NAME[0]="lirc_wb677" -BUILT_MODULE_LOCATION[0]="src" -DEST_MODULE_LOCATION[0]="/updates" - diff -Nru nct677x-dkms-1.0.1/nct677x-1.0.1/include/kcompat.h nct677x-dkms-1.0.4/nct677x-1.0.1/include/kcompat.h --- nct677x-dkms-1.0.1/nct677x-1.0.1/include/kcompat.h 2010-03-31 15:56:50.000000000 +0000 +++ nct677x-dkms-1.0.4/nct677x-1.0.1/include/kcompat.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,408 +0,0 @@ -/* $Id: kcompat.h,v 5.45 2009/08/02 11:15:28 lirc Exp $ */ - -#ifndef _KCOMPAT_H -#define _KCOMPAT_H - -#include - -#ifndef __func__ -#define __func__ __FUNCTION__ -#endif - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 16) -#define LIRC_THIS_MODULE(x) x, -#else /* >= 2.6.16 */ -#define LIRC_THIS_MODULE(x) -#endif - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) - -#include - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18) -#define LIRC_HAVE_DEVFS -#define LIRC_HAVE_DEVFS_26 -#endif - -#define LIRC_HAVE_SYSFS - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 13) - -typedef struct class_simple lirc_class_t; - -static inline lirc_class_t *class_create(struct module *owner, char *name) -{ - return class_simple_create(owner, name); -} - -static inline void class_destroy(lirc_class_t *cls) -{ - class_simple_destroy(cls); -} - -#define lirc_device_create(cs, parent, dev, drvdata, fmt, args...) \ - class_simple_device_add(cs, dev, parent, fmt, ## args) - -static inline void lirc_device_destroy(lirc_class_t *cls, dev_t devt) -{ - class_simple_device_remove(devt); -} - -#else /* >= 2.6.13 */ - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 15) - -#define lirc_device_create(cs, parent, dev, drvdata, fmt, args...) \ - class_device_create(cs, dev, parent, fmt, ## args) - -#else /* >= 2.6.15 */ - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26) - -#define lirc_device_create(cs, parent, dev, drvdata, fmt, args...) \ - class_device_create(cs, NULL, dev, parent, fmt, ## args) - -#else /* >= 2.6.26 */ - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 27) - -#define lirc_device_create(cs, parent, dev, drvdata, fmt, args...) \ - device_create(cs, parent, dev, fmt, ## args) - -#else /* >= 2.6.27 */ - -#define lirc_device_create device_create - -#endif /* >= 2.6.27 */ - -#endif /* >= 2.6.26 */ - -#define LIRC_DEVFS_PREFIX - -#endif /* >= 2.6.15 */ - -typedef struct class lirc_class_t; - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26) - -#define lirc_device_destroy class_device_destroy - -#else - -#define lirc_device_destroy device_destroy - -#endif - -#endif /* >= 2.6.13 */ - -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0) -#define LIRC_HAVE_DEVFS -#define LIRC_HAVE_DEVFS_24 -#endif - -#ifndef LIRC_DEVFS_PREFIX -#define LIRC_DEVFS_PREFIX "usb/" -#endif - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 0) -#include -#include -static inline void del_timer_sync(struct timer_list *timerlist) -{ - start_bh_atomic(); - del_timer(timerlist); - end_bh_atomic(); -} -#endif - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) -#ifdef daemonize -#undef daemonize -#endif -#define daemonize(name) do { \ - \ - lock_kernel(); \ - \ - exit_mm(current); \ - exit_files(current); \ - exit_fs(current); \ - current->session = 1; \ - current->pgrp = 1; \ - current->euid = 0; \ - current->tty = NULL; \ - sigfillset(¤t->blocked); \ - \ - strcpy(current->comm, name); \ - \ - unlock_kernel(); \ - \ -} while (0) - -/* Not sure when this was introduced, sometime during 2.5.X */ -#define MODULE_PARM_int(x) MODULE_PARM(x, "i") -#define MODULE_PARM_bool(x) MODULE_PARM(x, "i") -#define MODULE_PARM_long(x) MODULE_PARM(x, "l") -#define module_param(x, y, z) MODULE_PARM_##y(x) -#else -#include -#endif /* Linux < 2.6.0 */ - -/* DevFS header */ -#if defined(LIRC_HAVE_DEVFS) -#include -#endif - -#ifdef LIRC_HAVE_DEVFS_24 -#ifdef register_chrdev -#undef register_chrdev -#endif -#define register_chrdev devfs_register_chrdev -#ifdef unregister_chrdev -#undef unregister_chrdev -#endif -#define unregister_chrdev devfs_unregister_chrdev -#endif /* DEVFS 2.4 */ - -#ifndef LIRC_HAVE_SYSFS -#define class_destroy(x) do { } while (0) -#define class_create(x, y) NULL -#define lirc_device_destroy(x, y) do { } while (0) -#define lirc_device_create(x, y, z, xx, yy, zz) 0 -#define IS_ERR(x) 0 -typedef struct class_simple -{ - int notused; -} lirc_class_t; -#endif /* No SYSFS */ - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0) -#define KERNEL_2_5 - -/* - * We still are using MOD_INC_USE_COUNT/MOD_DEC_USE_COUNT in the set_use_inc - * function of all modules for 2.4 kernel compatibility. - * - * For 2.6 kernels reference counting is done in lirc_dev by - * try_module_get()/module_put() because the old approach is racy. - * - */ -#ifdef MOD_INC_USE_COUNT -#undef MOD_INC_USE_COUNT -#endif -#define MOD_INC_USE_COUNT - -#ifdef MOD_DEC_USE_COUNT -#undef MOD_DEC_USE_COUNT -#endif -#define MOD_DEC_USE_COUNT - -#ifdef EXPORT_NO_SYMBOLS -#undef EXPORT_NO_SYMBOLS -#endif -#define EXPORT_NO_SYMBOLS - -#else /* Kernel < 2.5.0 */ - -static inline int try_module_get(struct module *module) -{ - return 1; -} - -static inline void module_put(struct module *module) -{ -} - -#endif /* Kernel >= 2.5.0 */ - -#ifndef MODULE_LICENSE -#define MODULE_LICENSE(x) -#endif - -#ifndef MODULE_PARM_DESC -#define MODULE_PARM_DESC(x, y) -#endif - -#ifndef MODULE_ALIAS_CHARDEV_MAJOR -#define MODULE_ALIAS_CHARDEV_MAJOR(x) -#endif - -#ifndef MODULE_DEVICE_TABLE -#define MODULE_DEVICE_TABLE(x, y) -#endif - -#include -#ifndef IRQ_RETVAL -typedef void irqreturn_t; -#define IRQ_NONE -#define IRQ_HANDLED -#define IRQ_RETVAL(x) -#endif - -#ifndef MOD_IN_USE -#ifdef CONFIG_MODULE_UNLOAD -#define MOD_IN_USE module_refcount(THIS_MODULE) -#else -#error "LIRC modules currently require" -#error " 'Loadable module support ---> Module unloading'" -#error "to be enabled in the kernel" -#endif -#endif - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18) -#if !defined(local_irq_save) -#define local_irq_save(flags) do { save_flags(flags); cli(); } while (0) -#endif -#if !defined(local_irq_restore) -#define local_irq_restore(flags) do { restore_flags(flags); } while (0) -#endif -#endif - -#if KERNEL_VERSION(2, 4, 0) <= LINUX_VERSION_CODE -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 22) -#include -static inline char *pci_name(struct pci_dev *pdev) -{ - return pdev->slot_name; -} -#endif /* kernel < 2.4.22 */ -#endif /* kernel >= 2.4.0 */ - -/*************************** I2C specific *****************************/ -#include - -#ifndef I2C_CLIENT_END -#error "********************************************************" -#error " Sorry, this driver needs the new I2C stack. " -#error " You can get it at http://www2.lm-sensors.nu/~lm78/. " -#error "********************************************************" -#endif - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) - -#undef i2c_get_clientdata -#define i2c_get_clientdata(client) ((client)->data) - - -#undef i2c_set_clientdata -#define i2c_set_clientdata(client_ptr, new_data) do { \ - (client_ptr)->data = new_data; \ -} while (0) - - -#endif - -/* removed in 2.6.14 */ -#ifndef I2C_ALGO_BIT -# define I2C_ALGO_BIT 0 -#endif - -/* removed in 2.6.16 */ -#ifndef I2C_DRIVERID_EXP3 -# define I2C_DRIVERID_EXP3 0xf003 -#endif - -/*************************** USB specific *****************************/ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0) -#include - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 8) -static inline int usb_kill_urb(struct urb *urb) -{ - return usb_unlink_urb(urb); -} -#endif - -/* removed in 2.6.14 */ -#ifndef URB_ASYNC_UNLINK -#define URB_ASYNC_UNLINK 0 -#endif -#endif - -/*************************** bttv specific ****************************/ - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 15) /* BTTV_* -> BTTV_BOARD_* */ -#define BTTV_BOARD_UNKNOWN BTTV_UNKNOWN -#define BTTV_BOARD_PXELVWPLTVPAK BTTV_PXELVWPLTVPAK -#define BTTV_BOARD_PXELVWPLTVPRO BTTV_PXELVWPLTVPRO -#define BTTV_BOARD_PV_BT878P_9B BTTV_PV_BT878P_9B -#define BTTV_BOARD_PV_BT878P_PLUS BTTV_PV_BT878P_PLUS -#define BTTV_BOARD_AVERMEDIA BTTV_AVERMEDIA -#define BTTV_BOARD_AVPHONE98 BTTV_AVPHONE98 -#define BTTV_BOARD_AVERMEDIA98 BTTV_AVERMEDIA98 -#define BTTV_BOARD_CHRONOS_VS2 BTTV_CHRONOS_VS2 -#define BTTV_BOARD_MIRO BTTV_MIRO -#define BTTV_BOARD_DYNALINK BTTV_DYNALINK -#define BTTV_BOARD_WINVIEW_601 BTTV_WINVIEW_601 -#ifdef BTTV_KWORLD -#define BTTV_BOARD_KWORLD BTTV_KWORLD -#endif -#define BTTV_BOARD_MAGICTVIEW061 BTTV_MAGICTVIEW061 -#define BTTV_BOARD_MAGICTVIEW063 BTTV_MAGICTVIEW063 -#define BTTV_BOARD_PHOEBE_TVMAS BTTV_PHOEBE_TVMAS -#ifdef BTTV_BESTBUY_EASYTV2 -#define BTTV_BOARD_BESTBUY_EASYTV BTTV_BESTBUY_EASYTV -#define BTTV_BOARD_BESTBUY_EASYTV2 BTTV_BESTBUY_EASYTV2 -#endif -#define BTTV_BOARD_FLYVIDEO BTTV_FLYVIDEO -#define BTTV_BOARD_FLYVIDEO_98 BTTV_FLYVIDEO_98 -#define BTTV_BOARD_TYPHOON_TVIEW BTTV_TYPHOON_TVIEW -#ifdef BTTV_FLYVIDEO_98FM -#define BTTV_BOARD_FLYVIDEO_98FM BTTV_FLYVIDEO_98FM -#endif -#define BTTV_BOARD_WINFAST2000 BTTV_WINFAST2000 -#ifdef BTTV_GVBCTV5PCI -#define BTTV_BOARD_GVBCTV5PCI BTTV_GVBCTV5PCI -#endif -#endif /* end BTTV_* -> BTTV_BOARD_* */ - - -/******************************* pm.h *********************************/ - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 11) -typedef u32 pm_message_t; -#endif /* kernel < 2.6.11 */ -#endif /* kernel >= 2.6.0 */ - -/*************************** interrupt.h ******************************/ -/* added in 2.6.18, old defines removed in 2.6.24 */ -#ifndef IRQF_DISABLED -#define IRQF_DISABLED SA_INTERRUPT -#endif -#ifndef IRQF_SHARED -#define IRQF_SHARED SA_SHIRQ -#endif - -/*************************** spinlock.h *******************************/ -/* added in 2.6.11 */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 11) -#define DEFINE_SPINLOCK(x) spinlock_t x = SPIN_LOCK_UNLOCKED -#endif - -/***************************** slab.h *********************************/ -/* added in 2.6.14 */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 14) -static inline void *kzalloc(size_t size, gfp_t flags) -{ - void *ret = kmalloc(size, flags); - if (ret) - memset(ret, 0, size); - return ret; -} -#endif - -/****************************** fs.h **********************************/ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) -static inline unsigned iminor(struct inode *inode) -{ - return MINOR(inode->i_rdev); -} -#endif - -/****************************** bitops.h **********************************/ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24) -#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG)) -#define BIT_WORD(nr) ((nr) / BITS_PER_LONG) -#endif - -#endif /* _KCOMPAT_H */ diff -Nru nct677x-dkms-1.0.1/nct677x-1.0.1/include/lirc_dev.h nct677x-dkms-1.0.4/nct677x-1.0.1/include/lirc_dev.h --- nct677x-dkms-1.0.1/nct677x-1.0.1/include/lirc_dev.h 2010-03-31 15:56:50.000000000 +0000 +++ nct677x-dkms-1.0.4/nct677x-1.0.1/include/lirc_dev.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,342 +0,0 @@ -/* - * LIRC base driver - * - * (L) by Artur Lipowski - * This code is licensed under GNU GPL - * - * $Id: lirc_dev.h,v 1.37 2009/03/15 09:34:00 lirc Exp $ - * - */ - -#ifndef _LINUX_LIRC_DEV_H -#define _LINUX_LIRC_DEV_H - -#ifndef LIRC_REMOVE_DURING_EXPORT -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11) -/* when was it really introduced? */ -#define LIRC_HAVE_KFIFO -#endif -#endif -#define MAX_IRCTL_DEVICES 4 -#define BUFLEN 16 - -#define mod(n, div) ((n) % (div)) - -#include -#include -#ifdef LIRC_HAVE_KFIFO -#include -#endif - -struct lirc_buffer { - wait_queue_head_t wait_poll; - spinlock_t lock; - unsigned int chunk_size; - unsigned int size; /* in chunks */ - /* Using chunks instead of bytes pretends to simplify boundary checking - * And should allow for some performance fine tunning later */ -#ifdef LIRC_HAVE_KFIFO - struct kfifo *fifo; -#else - unsigned int fill; /* in chunks */ - int head, tail; /* in chunks */ - unsigned char *data; -#endif -}; -#ifndef LIRC_HAVE_KFIFO -static inline void lirc_buffer_lock(struct lirc_buffer *buf, - unsigned long *flags) -{ - spin_lock_irqsave(&buf->lock, *flags); -} -static inline void lirc_buffer_unlock(struct lirc_buffer *buf, - unsigned long *flags) -{ - spin_unlock_irqrestore(&buf->lock, *flags); -} -static inline void _lirc_buffer_clear(struct lirc_buffer *buf) -{ - buf->head = 0; - buf->tail = 0; - buf->fill = 0; -} -#endif -static inline void lirc_buffer_clear(struct lirc_buffer *buf) -{ -#ifdef LIRC_HAVE_KFIFO - if (buf->fifo) - kfifo_reset(buf->fifo); -#else - unsigned long flags; - lirc_buffer_lock(buf, &flags); - _lirc_buffer_clear(buf); - lirc_buffer_unlock(buf, &flags); -#endif -} -static inline int lirc_buffer_init(struct lirc_buffer *buf, - unsigned int chunk_size, - unsigned int size) -{ - init_waitqueue_head(&buf->wait_poll); - spin_lock_init(&buf->lock); -#ifndef LIRC_HAVE_KFIFO - _lirc_buffer_clear(buf); -#endif - buf->chunk_size = chunk_size; - buf->size = size; -#ifdef LIRC_HAVE_KFIFO - buf->fifo = kfifo_alloc(size*chunk_size, GFP_KERNEL, &buf->lock); - if (!buf->fifo) - return -ENOMEM; -#else - buf->data = kmalloc(size*chunk_size, GFP_KERNEL); - if (buf->data == NULL) - return -ENOMEM; - memset(buf->data, 0, size*chunk_size); -#endif - return 0; -} -static inline void lirc_buffer_free(struct lirc_buffer *buf) -{ -#ifdef LIRC_HAVE_KFIFO - if (buf->fifo) - kfifo_free(buf->fifo); -#else - kfree(buf->data); - buf->data = NULL; - buf->head = 0; - buf->tail = 0; - buf->fill = 0; - buf->chunk_size = 0; - buf->size = 0; -#endif -} -#ifndef LIRC_HAVE_KFIFO -static inline int _lirc_buffer_full(struct lirc_buffer *buf) -{ - return (buf->fill >= buf->size); -} -#endif -static inline int lirc_buffer_full(struct lirc_buffer *buf) -{ -#ifdef LIRC_HAVE_KFIFO - return kfifo_len(buf->fifo) == buf->size * buf->chunk_size; -#else - unsigned long flags; - int ret; - lirc_buffer_lock(buf, &flags); - ret = _lirc_buffer_full(buf); - lirc_buffer_unlock(buf, &flags); - return ret; -#endif -} -#ifndef LIRC_HAVE_KFIFO -static inline int _lirc_buffer_empty(struct lirc_buffer *buf) -{ - return !(buf->fill); -} -#endif -static inline int lirc_buffer_empty(struct lirc_buffer *buf) -{ -#ifdef LIRC_HAVE_KFIFO - return !kfifo_len(buf->fifo); -#else - unsigned long flags; - int ret; - lirc_buffer_lock(buf, &flags); - ret = _lirc_buffer_empty(buf); - lirc_buffer_unlock(buf, &flags); - return ret; -#endif -} -#ifndef LIRC_HAVE_KFIFO -static inline int _lirc_buffer_available(struct lirc_buffer *buf) -{ - return (buf->size - buf->fill); -} -#endif -static inline int lirc_buffer_available(struct lirc_buffer *buf) -{ -#ifdef LIRC_HAVE_KFIFO - return buf->size - (kfifo_len(buf->fifo) / buf->chunk_size); -#else - unsigned long flags; - int ret; - lirc_buffer_lock(buf, &flags); - ret = _lirc_buffer_available(buf); - lirc_buffer_unlock(buf, &flags); - return ret; -#endif -} -#ifndef LIRC_HAVE_KFIFO -static inline void _lirc_buffer_read_1(struct lirc_buffer *buf, - unsigned char *dest) -{ - memcpy(dest, &buf->data[buf->head*buf->chunk_size], buf->chunk_size); - buf->head = mod(buf->head+1, buf->size); - buf->fill -= 1; -} -#endif -static inline void lirc_buffer_read(struct lirc_buffer *buf, - unsigned char *dest) -{ -#ifdef LIRC_HAVE_KFIFO - if (kfifo_len(buf->fifo) >= buf->chunk_size) - kfifo_get(buf->fifo, dest, buf->chunk_size); -#else - unsigned long flags; - lirc_buffer_lock(buf, &flags); - _lirc_buffer_read_1(buf, dest); - lirc_buffer_unlock(buf, &flags); -#endif -} -#ifndef LIRC_HAVE_KFIFO -static inline void _lirc_buffer_write_1(struct lirc_buffer *buf, - unsigned char *orig) -{ - memcpy(&buf->data[buf->tail*buf->chunk_size], orig, buf->chunk_size); - buf->tail = mod(buf->tail+1, buf->size); - buf->fill++; -} -#endif -static inline void lirc_buffer_write(struct lirc_buffer *buf, - unsigned char *orig) -{ -#ifdef LIRC_HAVE_KFIFO - kfifo_put(buf->fifo, orig, buf->chunk_size); -#else - unsigned long flags; - lirc_buffer_lock(buf, &flags); - _lirc_buffer_write_1(buf, orig); - lirc_buffer_unlock(buf, &flags); -#endif -} -#ifndef LIRC_HAVE_KFIFO -static inline void _lirc_buffer_write_n(struct lirc_buffer *buf, - unsigned char *orig, int count) -{ - int space1; - if (buf->head > buf->tail) - space1 = buf->head - buf->tail; - else - space1 = buf->size - buf->tail; - - if (count > space1) { - memcpy(&buf->data[buf->tail * buf->chunk_size], orig, - space1 * buf->chunk_size); - memcpy(&buf->data[0], orig + (space1 * buf->chunk_size), - (count - space1) * buf->chunk_size); - } else { - memcpy(&buf->data[buf->tail * buf->chunk_size], orig, - count * buf->chunk_size); - } - buf->tail = mod(buf->tail + count, buf->size); - buf->fill += count; -} -#endif -static inline void lirc_buffer_write_n(struct lirc_buffer *buf, - unsigned char *orig, int count) -{ -#ifdef LIRC_HAVE_KFIFO - kfifo_put(buf->fifo, orig, count * buf->chunk_size); -#else - unsigned long flags; - lirc_buffer_lock(buf, &flags); - _lirc_buffer_write_n(buf, orig, count); - lirc_buffer_unlock(buf, &flags); -#endif -} - -struct lirc_driver { - char name[40]; - int minor; - unsigned long code_length; - unsigned int buffer_size; /* in chunks holding one code each */ - int sample_rate; - unsigned long features; - void *data; - int (*add_to_buf) (void *data, struct lirc_buffer *buf); -#ifndef LIRC_REMOVE_DURING_EXPORT - wait_queue_head_t* (*get_queue) (void *data); -#endif - struct lirc_buffer *rbuf; - int (*set_use_inc) (void *data); - void (*set_use_dec) (void *data); - struct file_operations *fops; - struct device *dev; - struct module *owner; -}; -/* name: - * this string will be used for logs - * - * minor: - * indicates minor device (/dev/lirc) number for registered driver - * if caller fills it with negative value, then the first free minor - * number will be used (if available) - * - * code_length: - * length of the remote control key code expressed in bits - * - * sample_rate: - * sample_rate equal to 0 means that no polling will be performed and - * add_to_buf will be triggered by external events (through task queue - * returned by get_queue) - * - * data: - * it may point to any driver data and this pointer will be passed to - * all callback functions - * - * add_to_buf: - * add_to_buf will be called after specified period of the time or - * triggered by the external event, this behavior depends on value of - * the sample_rate this function will be called in user context. This - * routine should return 0 if data was added to the buffer and - * -ENODATA if none was available. This should add some number of bits - * evenly divisible by code_length to the buffer - * - * get_queue: - * this callback should return a pointer to the task queue which will - * be used for external event waiting - * - * rbuf: - * if not NULL, it will be used as a read buffer, you will have to - * write to the buffer by other means, like irq's (see also - * lirc_serial.c). - * - * set_use_inc: - * set_use_inc will be called after device is opened - * - * set_use_dec: - * set_use_dec will be called after device is closed - * - * fops: - * file_operations for drivers which don't fit the current driver model. - * - * Some ioctl's can be directly handled by lirc_dev if the driver's - * ioctl function is NULL or if it returns -ENOIOCTLCMD (see also - * lirc_serial.c). - * - * owner: - * the module owning this struct - * - */ - - -/* following functions can be called ONLY from user context - * - * returns negative value on error or minor number - * of the registered device if success - * contents of the structure pointed by d is copied - */ -extern int lirc_register_driver(struct lirc_driver *d); - -/* returns negative value on error or 0 if success -*/ -extern int lirc_unregister_driver(int minor); - -/* Returns the private data stored in the lirc_driver - * associated with the given device file pointer. - */ -void *lirc_get_pdata(struct file *file); - -#endif diff -Nru nct677x-dkms-1.0.1/nct677x-1.0.1/include/lirc.h nct677x-dkms-1.0.4/nct677x-1.0.1/include/lirc.h --- nct677x-dkms-1.0.1/nct677x-1.0.1/include/lirc.h 2010-03-31 15:56:50.000000000 +0000 +++ nct677x-dkms-1.0.4/nct677x-1.0.1/include/lirc.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,105 +0,0 @@ -/* $Id: lirc.h,v 5.19 2009/08/29 07:52:41 lirc Exp $ */ - -#ifndef _LINUX_LIRC_H -#define _LINUX_LIRC_H - -#if defined(__linux__) -#include -#elif defined(_NetBSD_) -#include -#elif defined(_CYGWIN_) -#define __USE_LINUX_IOCTL_DEFS -#include -#endif - -#define PULSE_BIT 0x01000000 -#define PULSE_MASK 0x00FFFFFF - -typedef int lirc_t; - -/*** lirc compatible hardware features ***/ - -#define LIRC_MODE2SEND(x) (x) -#define LIRC_SEND2MODE(x) (x) -#define LIRC_MODE2REC(x) ((x) << 16) -#define LIRC_REC2MODE(x) ((x) >> 16) - -#define LIRC_MODE_RAW 0x00000001 -#define LIRC_MODE_PULSE 0x00000002 -#define LIRC_MODE_MODE2 0x00000004 -#define LIRC_MODE_CODE 0x00000008 -#define LIRC_MODE_LIRCCODE 0x00000010 -#define LIRC_MODE_STRING 0x00000020 - - -#define LIRC_CAN_SEND_RAW LIRC_MODE2SEND(LIRC_MODE_RAW) -#define LIRC_CAN_SEND_PULSE LIRC_MODE2SEND(LIRC_MODE_PULSE) -#define LIRC_CAN_SEND_MODE2 LIRC_MODE2SEND(LIRC_MODE_MODE2) -#define LIRC_CAN_SEND_CODE LIRC_MODE2SEND(LIRC_MODE_CODE) -#define LIRC_CAN_SEND_LIRCCODE LIRC_MODE2SEND(LIRC_MODE_LIRCCODE) -#define LIRC_CAN_SEND_STRING LIRC_MODE2SEND(LIRC_MODE_STRING) - -#define LIRC_CAN_SEND_MASK 0x0000003f - -#define LIRC_CAN_SET_SEND_CARRIER 0x00000100 -#define LIRC_CAN_SET_SEND_DUTY_CYCLE 0x00000200 -#define LIRC_CAN_SET_TRANSMITTER_MASK 0x00000400 - -#define LIRC_CAN_REC_RAW LIRC_MODE2REC(LIRC_MODE_RAW) -#define LIRC_CAN_REC_PULSE LIRC_MODE2REC(LIRC_MODE_PULSE) -#define LIRC_CAN_REC_MODE2 LIRC_MODE2REC(LIRC_MODE_MODE2) -#define LIRC_CAN_REC_CODE LIRC_MODE2REC(LIRC_MODE_CODE) -#define LIRC_CAN_REC_LIRCCODE LIRC_MODE2REC(LIRC_MODE_LIRCCODE) -#define LIRC_CAN_REC_STRING LIRC_MODE2REC(LIRC_MODE_STRING) - -#define LIRC_CAN_REC_MASK LIRC_MODE2REC(LIRC_CAN_SEND_MASK) - -#define LIRC_CAN_SET_REC_CARRIER (LIRC_CAN_SET_SEND_CARRIER << 16) -#define LIRC_CAN_SET_REC_DUTY_CYCLE (LIRC_CAN_SET_SEND_DUTY_CYCLE << 16) - -#define LIRC_CAN_SET_REC_DUTY_CYCLE_RANGE 0x40000000 -#define LIRC_CAN_SET_REC_CARRIER_RANGE 0x80000000 -#define LIRC_CAN_GET_REC_RESOLUTION 0x20000000 - -#define LIRC_CAN_SEND(x) ((x)&LIRC_CAN_SEND_MASK) -#define LIRC_CAN_REC(x) ((x)&LIRC_CAN_REC_MASK) - -#define LIRC_CAN_NOTIFY_DECODE 0x01000000 - -/*** IOCTL commands for lirc driver ***/ - -#define LIRC_GET_FEATURES _IOR('i', 0x00000000, unsigned long) - -#define LIRC_GET_SEND_MODE _IOR('i', 0x00000001, unsigned long) -#define LIRC_GET_REC_MODE _IOR('i', 0x00000002, unsigned long) -#define LIRC_GET_SEND_CARRIER _IOR('i', 0x00000003, unsigned int) -#define LIRC_GET_REC_CARRIER _IOR('i', 0x00000004, unsigned int) -#define LIRC_GET_SEND_DUTY_CYCLE _IOR('i', 0x00000005, unsigned int) -#define LIRC_GET_REC_DUTY_CYCLE _IOR('i', 0x00000006, unsigned int) -#define LIRC_GET_REC_RESOLUTION _IOR('i', 0x00000007, unsigned int) - -/* code length in bits, currently only for LIRC_MODE_LIRCCODE */ -#define LIRC_GET_LENGTH _IOR('i', 0x0000000f, unsigned long) - -#define LIRC_SET_SEND_MODE _IOW('i', 0x00000011, unsigned long) -#define LIRC_SET_REC_MODE _IOW('i', 0x00000012, unsigned long) -/* Note: these can reset the according pulse_width */ -#define LIRC_SET_SEND_CARRIER _IOW('i', 0x00000013, unsigned int) -#define LIRC_SET_REC_CARRIER _IOW('i', 0x00000014, unsigned int) -#define LIRC_SET_SEND_DUTY_CYCLE _IOW('i', 0x00000015, unsigned int) -#define LIRC_SET_REC_DUTY_CYCLE _IOW('i', 0x00000016, unsigned int) -#define LIRC_SET_TRANSMITTER_MASK _IOW('i', 0x00000017, unsigned int) - -/* - * to set a range use - * LIRC_SET_REC_DUTY_CYCLE_RANGE/LIRC_SET_REC_CARRIER_RANGE with the - * lower bound first and later - * LIRC_SET_REC_DUTY_CYCLE/LIRC_SET_REC_CARRIER with the upper bound - */ - -#define LIRC_SET_REC_DUTY_CYCLE_RANGE _IOW('i', 0x0000001e, unsigned int) -#define LIRC_SET_REC_CARRIER_RANGE _IOW('i', 0x0000001f, unsigned int) - -#define LIRC_NOTIFY_DECODE _IO('i', 0x00000020) - -#endif diff -Nru nct677x-dkms-1.0.1/nct677x-1.0.1/src/kcompat.h nct677x-dkms-1.0.4/nct677x-1.0.1/src/kcompat.h --- nct677x-dkms-1.0.1/nct677x-1.0.1/src/kcompat.h 2010-03-31 15:56:50.000000000 +0000 +++ nct677x-dkms-1.0.4/nct677x-1.0.1/src/kcompat.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,408 +0,0 @@ -/* $Id: kcompat.h,v 5.45 2009/08/02 11:15:28 lirc Exp $ */ - -#ifndef _KCOMPAT_H -#define _KCOMPAT_H - -#include - -#ifndef __func__ -#define __func__ __FUNCTION__ -#endif - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 16) -#define LIRC_THIS_MODULE(x) x, -#else /* >= 2.6.16 */ -#define LIRC_THIS_MODULE(x) -#endif - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) - -#include - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18) -#define LIRC_HAVE_DEVFS -#define LIRC_HAVE_DEVFS_26 -#endif - -#define LIRC_HAVE_SYSFS - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 13) - -typedef struct class_simple lirc_class_t; - -static inline lirc_class_t *class_create(struct module *owner, char *name) -{ - return class_simple_create(owner, name); -} - -static inline void class_destroy(lirc_class_t *cls) -{ - class_simple_destroy(cls); -} - -#define lirc_device_create(cs, parent, dev, drvdata, fmt, args...) \ - class_simple_device_add(cs, dev, parent, fmt, ## args) - -static inline void lirc_device_destroy(lirc_class_t *cls, dev_t devt) -{ - class_simple_device_remove(devt); -} - -#else /* >= 2.6.13 */ - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 15) - -#define lirc_device_create(cs, parent, dev, drvdata, fmt, args...) \ - class_device_create(cs, dev, parent, fmt, ## args) - -#else /* >= 2.6.15 */ - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26) - -#define lirc_device_create(cs, parent, dev, drvdata, fmt, args...) \ - class_device_create(cs, NULL, dev, parent, fmt, ## args) - -#else /* >= 2.6.26 */ - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 27) - -#define lirc_device_create(cs, parent, dev, drvdata, fmt, args...) \ - device_create(cs, parent, dev, fmt, ## args) - -#else /* >= 2.6.27 */ - -#define lirc_device_create device_create - -#endif /* >= 2.6.27 */ - -#endif /* >= 2.6.26 */ - -#define LIRC_DEVFS_PREFIX - -#endif /* >= 2.6.15 */ - -typedef struct class lirc_class_t; - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26) - -#define lirc_device_destroy class_device_destroy - -#else - -#define lirc_device_destroy device_destroy - -#endif - -#endif /* >= 2.6.13 */ - -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0) -#define LIRC_HAVE_DEVFS -#define LIRC_HAVE_DEVFS_24 -#endif - -#ifndef LIRC_DEVFS_PREFIX -#define LIRC_DEVFS_PREFIX "usb/" -#endif - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 0) -#include -#include -static inline void del_timer_sync(struct timer_list *timerlist) -{ - start_bh_atomic(); - del_timer(timerlist); - end_bh_atomic(); -} -#endif - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) -#ifdef daemonize -#undef daemonize -#endif -#define daemonize(name) do { \ - \ - lock_kernel(); \ - \ - exit_mm(current); \ - exit_files(current); \ - exit_fs(current); \ - current->session = 1; \ - current->pgrp = 1; \ - current->euid = 0; \ - current->tty = NULL; \ - sigfillset(¤t->blocked); \ - \ - strcpy(current->comm, name); \ - \ - unlock_kernel(); \ - \ -} while (0) - -/* Not sure when this was introduced, sometime during 2.5.X */ -#define MODULE_PARM_int(x) MODULE_PARM(x, "i") -#define MODULE_PARM_bool(x) MODULE_PARM(x, "i") -#define MODULE_PARM_long(x) MODULE_PARM(x, "l") -#define module_param(x, y, z) MODULE_PARM_##y(x) -#else -#include -#endif /* Linux < 2.6.0 */ - -/* DevFS header */ -#if defined(LIRC_HAVE_DEVFS) -#include -#endif - -#ifdef LIRC_HAVE_DEVFS_24 -#ifdef register_chrdev -#undef register_chrdev -#endif -#define register_chrdev devfs_register_chrdev -#ifdef unregister_chrdev -#undef unregister_chrdev -#endif -#define unregister_chrdev devfs_unregister_chrdev -#endif /* DEVFS 2.4 */ - -#ifndef LIRC_HAVE_SYSFS -#define class_destroy(x) do { } while (0) -#define class_create(x, y) NULL -#define lirc_device_destroy(x, y) do { } while (0) -#define lirc_device_create(x, y, z, xx, yy, zz) 0 -#define IS_ERR(x) 0 -typedef struct class_simple -{ - int notused; -} lirc_class_t; -#endif /* No SYSFS */ - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0) -#define KERNEL_2_5 - -/* - * We still are using MOD_INC_USE_COUNT/MOD_DEC_USE_COUNT in the set_use_inc - * function of all modules for 2.4 kernel compatibility. - * - * For 2.6 kernels reference counting is done in lirc_dev by - * try_module_get()/module_put() because the old approach is racy. - * - */ -#ifdef MOD_INC_USE_COUNT -#undef MOD_INC_USE_COUNT -#endif -#define MOD_INC_USE_COUNT - -#ifdef MOD_DEC_USE_COUNT -#undef MOD_DEC_USE_COUNT -#endif -#define MOD_DEC_USE_COUNT - -#ifdef EXPORT_NO_SYMBOLS -#undef EXPORT_NO_SYMBOLS -#endif -#define EXPORT_NO_SYMBOLS - -#else /* Kernel < 2.5.0 */ - -static inline int try_module_get(struct module *module) -{ - return 1; -} - -static inline void module_put(struct module *module) -{ -} - -#endif /* Kernel >= 2.5.0 */ - -#ifndef MODULE_LICENSE -#define MODULE_LICENSE(x) -#endif - -#ifndef MODULE_PARM_DESC -#define MODULE_PARM_DESC(x, y) -#endif - -#ifndef MODULE_ALIAS_CHARDEV_MAJOR -#define MODULE_ALIAS_CHARDEV_MAJOR(x) -#endif - -#ifndef MODULE_DEVICE_TABLE -#define MODULE_DEVICE_TABLE(x, y) -#endif - -#include -#ifndef IRQ_RETVAL -typedef void irqreturn_t; -#define IRQ_NONE -#define IRQ_HANDLED -#define IRQ_RETVAL(x) -#endif - -#ifndef MOD_IN_USE -#ifdef CONFIG_MODULE_UNLOAD -#define MOD_IN_USE module_refcount(THIS_MODULE) -#else -#error "LIRC modules currently require" -#error " 'Loadable module support ---> Module unloading'" -#error "to be enabled in the kernel" -#endif -#endif - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18) -#if !defined(local_irq_save) -#define local_irq_save(flags) do { save_flags(flags); cli(); } while (0) -#endif -#if !defined(local_irq_restore) -#define local_irq_restore(flags) do { restore_flags(flags); } while (0) -#endif -#endif - -#if KERNEL_VERSION(2, 4, 0) <= LINUX_VERSION_CODE -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 22) -#include -static inline char *pci_name(struct pci_dev *pdev) -{ - return pdev->slot_name; -} -#endif /* kernel < 2.4.22 */ -#endif /* kernel >= 2.4.0 */ - -/*************************** I2C specific *****************************/ -#include - -#ifndef I2C_CLIENT_END -#error "********************************************************" -#error " Sorry, this driver needs the new I2C stack. " -#error " You can get it at http://www2.lm-sensors.nu/~lm78/. " -#error "********************************************************" -#endif - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) - -#undef i2c_get_clientdata -#define i2c_get_clientdata(client) ((client)->data) - - -#undef i2c_set_clientdata -#define i2c_set_clientdata(client_ptr, new_data) do { \ - (client_ptr)->data = new_data; \ -} while (0) - - -#endif - -/* removed in 2.6.14 */ -#ifndef I2C_ALGO_BIT -# define I2C_ALGO_BIT 0 -#endif - -/* removed in 2.6.16 */ -#ifndef I2C_DRIVERID_EXP3 -# define I2C_DRIVERID_EXP3 0xf003 -#endif - -/*************************** USB specific *****************************/ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0) -#include - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 8) -static inline int usb_kill_urb(struct urb *urb) -{ - return usb_unlink_urb(urb); -} -#endif - -/* removed in 2.6.14 */ -#ifndef URB_ASYNC_UNLINK -#define URB_ASYNC_UNLINK 0 -#endif -#endif - -/*************************** bttv specific ****************************/ - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 15) /* BTTV_* -> BTTV_BOARD_* */ -#define BTTV_BOARD_UNKNOWN BTTV_UNKNOWN -#define BTTV_BOARD_PXELVWPLTVPAK BTTV_PXELVWPLTVPAK -#define BTTV_BOARD_PXELVWPLTVPRO BTTV_PXELVWPLTVPRO -#define BTTV_BOARD_PV_BT878P_9B BTTV_PV_BT878P_9B -#define BTTV_BOARD_PV_BT878P_PLUS BTTV_PV_BT878P_PLUS -#define BTTV_BOARD_AVERMEDIA BTTV_AVERMEDIA -#define BTTV_BOARD_AVPHONE98 BTTV_AVPHONE98 -#define BTTV_BOARD_AVERMEDIA98 BTTV_AVERMEDIA98 -#define BTTV_BOARD_CHRONOS_VS2 BTTV_CHRONOS_VS2 -#define BTTV_BOARD_MIRO BTTV_MIRO -#define BTTV_BOARD_DYNALINK BTTV_DYNALINK -#define BTTV_BOARD_WINVIEW_601 BTTV_WINVIEW_601 -#ifdef BTTV_KWORLD -#define BTTV_BOARD_KWORLD BTTV_KWORLD -#endif -#define BTTV_BOARD_MAGICTVIEW061 BTTV_MAGICTVIEW061 -#define BTTV_BOARD_MAGICTVIEW063 BTTV_MAGICTVIEW063 -#define BTTV_BOARD_PHOEBE_TVMAS BTTV_PHOEBE_TVMAS -#ifdef BTTV_BESTBUY_EASYTV2 -#define BTTV_BOARD_BESTBUY_EASYTV BTTV_BESTBUY_EASYTV -#define BTTV_BOARD_BESTBUY_EASYTV2 BTTV_BESTBUY_EASYTV2 -#endif -#define BTTV_BOARD_FLYVIDEO BTTV_FLYVIDEO -#define BTTV_BOARD_FLYVIDEO_98 BTTV_FLYVIDEO_98 -#define BTTV_BOARD_TYPHOON_TVIEW BTTV_TYPHOON_TVIEW -#ifdef BTTV_FLYVIDEO_98FM -#define BTTV_BOARD_FLYVIDEO_98FM BTTV_FLYVIDEO_98FM -#endif -#define BTTV_BOARD_WINFAST2000 BTTV_WINFAST2000 -#ifdef BTTV_GVBCTV5PCI -#define BTTV_BOARD_GVBCTV5PCI BTTV_GVBCTV5PCI -#endif -#endif /* end BTTV_* -> BTTV_BOARD_* */ - - -/******************************* pm.h *********************************/ - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 11) -typedef u32 pm_message_t; -#endif /* kernel < 2.6.11 */ -#endif /* kernel >= 2.6.0 */ - -/*************************** interrupt.h ******************************/ -/* added in 2.6.18, old defines removed in 2.6.24 */ -#ifndef IRQF_DISABLED -#define IRQF_DISABLED SA_INTERRUPT -#endif -#ifndef IRQF_SHARED -#define IRQF_SHARED SA_SHIRQ -#endif - -/*************************** spinlock.h *******************************/ -/* added in 2.6.11 */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 11) -#define DEFINE_SPINLOCK(x) spinlock_t x = SPIN_LOCK_UNLOCKED -#endif - -/***************************** slab.h *********************************/ -/* added in 2.6.14 */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 14) -static inline void *kzalloc(size_t size, gfp_t flags) -{ - void *ret = kmalloc(size, flags); - if (ret) - memset(ret, 0, size); - return ret; -} -#endif - -/****************************** fs.h **********************************/ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) -static inline unsigned iminor(struct inode *inode) -{ - return MINOR(inode->i_rdev); -} -#endif - -/****************************** bitops.h **********************************/ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24) -#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG)) -#define BIT_WORD(nr) ((nr) / BITS_PER_LONG) -#endif - -#endif /* _KCOMPAT_H */ diff -Nru nct677x-dkms-1.0.1/nct677x-1.0.1/src/lirc_dev.h nct677x-dkms-1.0.4/nct677x-1.0.1/src/lirc_dev.h --- nct677x-dkms-1.0.1/nct677x-1.0.1/src/lirc_dev.h 2010-03-31 15:56:50.000000000 +0000 +++ nct677x-dkms-1.0.4/nct677x-1.0.1/src/lirc_dev.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,342 +0,0 @@ -/* - * LIRC base driver - * - * (L) by Artur Lipowski - * This code is licensed under GNU GPL - * - * $Id: lirc_dev.h,v 1.37 2009/03/15 09:34:00 lirc Exp $ - * - */ - -#ifndef _LINUX_LIRC_DEV_H -#define _LINUX_LIRC_DEV_H - -#ifndef LIRC_REMOVE_DURING_EXPORT -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11) -/* when was it really introduced? */ -#define LIRC_HAVE_KFIFO -#endif -#endif -#define MAX_IRCTL_DEVICES 4 -#define BUFLEN 16 - -#define mod(n, div) ((n) % (div)) - -#include -#include -#ifdef LIRC_HAVE_KFIFO -#include -#endif - -struct lirc_buffer { - wait_queue_head_t wait_poll; - spinlock_t lock; - unsigned int chunk_size; - unsigned int size; /* in chunks */ - /* Using chunks instead of bytes pretends to simplify boundary checking - * And should allow for some performance fine tunning later */ -#ifdef LIRC_HAVE_KFIFO - struct kfifo *fifo; -#else - unsigned int fill; /* in chunks */ - int head, tail; /* in chunks */ - unsigned char *data; -#endif -}; -#ifndef LIRC_HAVE_KFIFO -static inline void lirc_buffer_lock(struct lirc_buffer *buf, - unsigned long *flags) -{ - spin_lock_irqsave(&buf->lock, *flags); -} -static inline void lirc_buffer_unlock(struct lirc_buffer *buf, - unsigned long *flags) -{ - spin_unlock_irqrestore(&buf->lock, *flags); -} -static inline void _lirc_buffer_clear(struct lirc_buffer *buf) -{ - buf->head = 0; - buf->tail = 0; - buf->fill = 0; -} -#endif -static inline void lirc_buffer_clear(struct lirc_buffer *buf) -{ -#ifdef LIRC_HAVE_KFIFO - if (buf->fifo) - kfifo_reset(buf->fifo); -#else - unsigned long flags; - lirc_buffer_lock(buf, &flags); - _lirc_buffer_clear(buf); - lirc_buffer_unlock(buf, &flags); -#endif -} -static inline int lirc_buffer_init(struct lirc_buffer *buf, - unsigned int chunk_size, - unsigned int size) -{ - init_waitqueue_head(&buf->wait_poll); - spin_lock_init(&buf->lock); -#ifndef LIRC_HAVE_KFIFO - _lirc_buffer_clear(buf); -#endif - buf->chunk_size = chunk_size; - buf->size = size; -#ifdef LIRC_HAVE_KFIFO - buf->fifo = kfifo_alloc(size*chunk_size, GFP_KERNEL, &buf->lock); - if (!buf->fifo) - return -ENOMEM; -#else - buf->data = kmalloc(size*chunk_size, GFP_KERNEL); - if (buf->data == NULL) - return -ENOMEM; - memset(buf->data, 0, size*chunk_size); -#endif - return 0; -} -static inline void lirc_buffer_free(struct lirc_buffer *buf) -{ -#ifdef LIRC_HAVE_KFIFO - if (buf->fifo) - kfifo_free(buf->fifo); -#else - kfree(buf->data); - buf->data = NULL; - buf->head = 0; - buf->tail = 0; - buf->fill = 0; - buf->chunk_size = 0; - buf->size = 0; -#endif -} -#ifndef LIRC_HAVE_KFIFO -static inline int _lirc_buffer_full(struct lirc_buffer *buf) -{ - return (buf->fill >= buf->size); -} -#endif -static inline int lirc_buffer_full(struct lirc_buffer *buf) -{ -#ifdef LIRC_HAVE_KFIFO - return kfifo_len(buf->fifo) == buf->size * buf->chunk_size; -#else - unsigned long flags; - int ret; - lirc_buffer_lock(buf, &flags); - ret = _lirc_buffer_full(buf); - lirc_buffer_unlock(buf, &flags); - return ret; -#endif -} -#ifndef LIRC_HAVE_KFIFO -static inline int _lirc_buffer_empty(struct lirc_buffer *buf) -{ - return !(buf->fill); -} -#endif -static inline int lirc_buffer_empty(struct lirc_buffer *buf) -{ -#ifdef LIRC_HAVE_KFIFO - return !kfifo_len(buf->fifo); -#else - unsigned long flags; - int ret; - lirc_buffer_lock(buf, &flags); - ret = _lirc_buffer_empty(buf); - lirc_buffer_unlock(buf, &flags); - return ret; -#endif -} -#ifndef LIRC_HAVE_KFIFO -static inline int _lirc_buffer_available(struct lirc_buffer *buf) -{ - return (buf->size - buf->fill); -} -#endif -static inline int lirc_buffer_available(struct lirc_buffer *buf) -{ -#ifdef LIRC_HAVE_KFIFO - return buf->size - (kfifo_len(buf->fifo) / buf->chunk_size); -#else - unsigned long flags; - int ret; - lirc_buffer_lock(buf, &flags); - ret = _lirc_buffer_available(buf); - lirc_buffer_unlock(buf, &flags); - return ret; -#endif -} -#ifndef LIRC_HAVE_KFIFO -static inline void _lirc_buffer_read_1(struct lirc_buffer *buf, - unsigned char *dest) -{ - memcpy(dest, &buf->data[buf->head*buf->chunk_size], buf->chunk_size); - buf->head = mod(buf->head+1, buf->size); - buf->fill -= 1; -} -#endif -static inline void lirc_buffer_read(struct lirc_buffer *buf, - unsigned char *dest) -{ -#ifdef LIRC_HAVE_KFIFO - if (kfifo_len(buf->fifo) >= buf->chunk_size) - kfifo_get(buf->fifo, dest, buf->chunk_size); -#else - unsigned long flags; - lirc_buffer_lock(buf, &flags); - _lirc_buffer_read_1(buf, dest); - lirc_buffer_unlock(buf, &flags); -#endif -} -#ifndef LIRC_HAVE_KFIFO -static inline void _lirc_buffer_write_1(struct lirc_buffer *buf, - unsigned char *orig) -{ - memcpy(&buf->data[buf->tail*buf->chunk_size], orig, buf->chunk_size); - buf->tail = mod(buf->tail+1, buf->size); - buf->fill++; -} -#endif -static inline void lirc_buffer_write(struct lirc_buffer *buf, - unsigned char *orig) -{ -#ifdef LIRC_HAVE_KFIFO - kfifo_put(buf->fifo, orig, buf->chunk_size); -#else - unsigned long flags; - lirc_buffer_lock(buf, &flags); - _lirc_buffer_write_1(buf, orig); - lirc_buffer_unlock(buf, &flags); -#endif -} -#ifndef LIRC_HAVE_KFIFO -static inline void _lirc_buffer_write_n(struct lirc_buffer *buf, - unsigned char *orig, int count) -{ - int space1; - if (buf->head > buf->tail) - space1 = buf->head - buf->tail; - else - space1 = buf->size - buf->tail; - - if (count > space1) { - memcpy(&buf->data[buf->tail * buf->chunk_size], orig, - space1 * buf->chunk_size); - memcpy(&buf->data[0], orig + (space1 * buf->chunk_size), - (count - space1) * buf->chunk_size); - } else { - memcpy(&buf->data[buf->tail * buf->chunk_size], orig, - count * buf->chunk_size); - } - buf->tail = mod(buf->tail + count, buf->size); - buf->fill += count; -} -#endif -static inline void lirc_buffer_write_n(struct lirc_buffer *buf, - unsigned char *orig, int count) -{ -#ifdef LIRC_HAVE_KFIFO - kfifo_put(buf->fifo, orig, count * buf->chunk_size); -#else - unsigned long flags; - lirc_buffer_lock(buf, &flags); - _lirc_buffer_write_n(buf, orig, count); - lirc_buffer_unlock(buf, &flags); -#endif -} - -struct lirc_driver { - char name[40]; - int minor; - unsigned long code_length; - unsigned int buffer_size; /* in chunks holding one code each */ - int sample_rate; - unsigned long features; - void *data; - int (*add_to_buf) (void *data, struct lirc_buffer *buf); -#ifndef LIRC_REMOVE_DURING_EXPORT - wait_queue_head_t* (*get_queue) (void *data); -#endif - struct lirc_buffer *rbuf; - int (*set_use_inc) (void *data); - void (*set_use_dec) (void *data); - struct file_operations *fops; - struct device *dev; - struct module *owner; -}; -/* name: - * this string will be used for logs - * - * minor: - * indicates minor device (/dev/lirc) number for registered driver - * if caller fills it with negative value, then the first free minor - * number will be used (if available) - * - * code_length: - * length of the remote control key code expressed in bits - * - * sample_rate: - * sample_rate equal to 0 means that no polling will be performed and - * add_to_buf will be triggered by external events (through task queue - * returned by get_queue) - * - * data: - * it may point to any driver data and this pointer will be passed to - * all callback functions - * - * add_to_buf: - * add_to_buf will be called after specified period of the time or - * triggered by the external event, this behavior depends on value of - * the sample_rate this function will be called in user context. This - * routine should return 0 if data was added to the buffer and - * -ENODATA if none was available. This should add some number of bits - * evenly divisible by code_length to the buffer - * - * get_queue: - * this callback should return a pointer to the task queue which will - * be used for external event waiting - * - * rbuf: - * if not NULL, it will be used as a read buffer, you will have to - * write to the buffer by other means, like irq's (see also - * lirc_serial.c). - * - * set_use_inc: - * set_use_inc will be called after device is opened - * - * set_use_dec: - * set_use_dec will be called after device is closed - * - * fops: - * file_operations for drivers which don't fit the current driver model. - * - * Some ioctl's can be directly handled by lirc_dev if the driver's - * ioctl function is NULL or if it returns -ENOIOCTLCMD (see also - * lirc_serial.c). - * - * owner: - * the module owning this struct - * - */ - - -/* following functions can be called ONLY from user context - * - * returns negative value on error or minor number - * of the registered device if success - * contents of the structure pointed by d is copied - */ -extern int lirc_register_driver(struct lirc_driver *d); - -/* returns negative value on error or 0 if success -*/ -extern int lirc_unregister_driver(int minor); - -/* Returns the private data stored in the lirc_driver - * associated with the given device file pointer. - */ -void *lirc_get_pdata(struct file *file); - -#endif diff -Nru nct677x-dkms-1.0.1/nct677x-1.0.1/src/lirc.h nct677x-dkms-1.0.4/nct677x-1.0.1/src/lirc.h --- nct677x-dkms-1.0.1/nct677x-1.0.1/src/lirc.h 2010-03-31 15:56:50.000000000 +0000 +++ nct677x-dkms-1.0.4/nct677x-1.0.1/src/lirc.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,105 +0,0 @@ -/* $Id: lirc.h,v 5.19 2009/08/29 07:52:41 lirc Exp $ */ - -#ifndef _LINUX_LIRC_H -#define _LINUX_LIRC_H - -#if defined(__linux__) -#include -#elif defined(_NetBSD_) -#include -#elif defined(_CYGWIN_) -#define __USE_LINUX_IOCTL_DEFS -#include -#endif - -#define PULSE_BIT 0x01000000 -#define PULSE_MASK 0x00FFFFFF - -typedef int lirc_t; - -/*** lirc compatible hardware features ***/ - -#define LIRC_MODE2SEND(x) (x) -#define LIRC_SEND2MODE(x) (x) -#define LIRC_MODE2REC(x) ((x) << 16) -#define LIRC_REC2MODE(x) ((x) >> 16) - -#define LIRC_MODE_RAW 0x00000001 -#define LIRC_MODE_PULSE 0x00000002 -#define LIRC_MODE_MODE2 0x00000004 -#define LIRC_MODE_CODE 0x00000008 -#define LIRC_MODE_LIRCCODE 0x00000010 -#define LIRC_MODE_STRING 0x00000020 - - -#define LIRC_CAN_SEND_RAW LIRC_MODE2SEND(LIRC_MODE_RAW) -#define LIRC_CAN_SEND_PULSE LIRC_MODE2SEND(LIRC_MODE_PULSE) -#define LIRC_CAN_SEND_MODE2 LIRC_MODE2SEND(LIRC_MODE_MODE2) -#define LIRC_CAN_SEND_CODE LIRC_MODE2SEND(LIRC_MODE_CODE) -#define LIRC_CAN_SEND_LIRCCODE LIRC_MODE2SEND(LIRC_MODE_LIRCCODE) -#define LIRC_CAN_SEND_STRING LIRC_MODE2SEND(LIRC_MODE_STRING) - -#define LIRC_CAN_SEND_MASK 0x0000003f - -#define LIRC_CAN_SET_SEND_CARRIER 0x00000100 -#define LIRC_CAN_SET_SEND_DUTY_CYCLE 0x00000200 -#define LIRC_CAN_SET_TRANSMITTER_MASK 0x00000400 - -#define LIRC_CAN_REC_RAW LIRC_MODE2REC(LIRC_MODE_RAW) -#define LIRC_CAN_REC_PULSE LIRC_MODE2REC(LIRC_MODE_PULSE) -#define LIRC_CAN_REC_MODE2 LIRC_MODE2REC(LIRC_MODE_MODE2) -#define LIRC_CAN_REC_CODE LIRC_MODE2REC(LIRC_MODE_CODE) -#define LIRC_CAN_REC_LIRCCODE LIRC_MODE2REC(LIRC_MODE_LIRCCODE) -#define LIRC_CAN_REC_STRING LIRC_MODE2REC(LIRC_MODE_STRING) - -#define LIRC_CAN_REC_MASK LIRC_MODE2REC(LIRC_CAN_SEND_MASK) - -#define LIRC_CAN_SET_REC_CARRIER (LIRC_CAN_SET_SEND_CARRIER << 16) -#define LIRC_CAN_SET_REC_DUTY_CYCLE (LIRC_CAN_SET_SEND_DUTY_CYCLE << 16) - -#define LIRC_CAN_SET_REC_DUTY_CYCLE_RANGE 0x40000000 -#define LIRC_CAN_SET_REC_CARRIER_RANGE 0x80000000 -#define LIRC_CAN_GET_REC_RESOLUTION 0x20000000 - -#define LIRC_CAN_SEND(x) ((x)&LIRC_CAN_SEND_MASK) -#define LIRC_CAN_REC(x) ((x)&LIRC_CAN_REC_MASK) - -#define LIRC_CAN_NOTIFY_DECODE 0x01000000 - -/*** IOCTL commands for lirc driver ***/ - -#define LIRC_GET_FEATURES _IOR('i', 0x00000000, unsigned long) - -#define LIRC_GET_SEND_MODE _IOR('i', 0x00000001, unsigned long) -#define LIRC_GET_REC_MODE _IOR('i', 0x00000002, unsigned long) -#define LIRC_GET_SEND_CARRIER _IOR('i', 0x00000003, unsigned int) -#define LIRC_GET_REC_CARRIER _IOR('i', 0x00000004, unsigned int) -#define LIRC_GET_SEND_DUTY_CYCLE _IOR('i', 0x00000005, unsigned int) -#define LIRC_GET_REC_DUTY_CYCLE _IOR('i', 0x00000006, unsigned int) -#define LIRC_GET_REC_RESOLUTION _IOR('i', 0x00000007, unsigned int) - -/* code length in bits, currently only for LIRC_MODE_LIRCCODE */ -#define LIRC_GET_LENGTH _IOR('i', 0x0000000f, unsigned long) - -#define LIRC_SET_SEND_MODE _IOW('i', 0x00000011, unsigned long) -#define LIRC_SET_REC_MODE _IOW('i', 0x00000012, unsigned long) -/* Note: these can reset the according pulse_width */ -#define LIRC_SET_SEND_CARRIER _IOW('i', 0x00000013, unsigned int) -#define LIRC_SET_REC_CARRIER _IOW('i', 0x00000014, unsigned int) -#define LIRC_SET_SEND_DUTY_CYCLE _IOW('i', 0x00000015, unsigned int) -#define LIRC_SET_REC_DUTY_CYCLE _IOW('i', 0x00000016, unsigned int) -#define LIRC_SET_TRANSMITTER_MASK _IOW('i', 0x00000017, unsigned int) - -/* - * to set a range use - * LIRC_SET_REC_DUTY_CYCLE_RANGE/LIRC_SET_REC_CARRIER_RANGE with the - * lower bound first and later - * LIRC_SET_REC_DUTY_CYCLE/LIRC_SET_REC_CARRIER with the upper bound - */ - -#define LIRC_SET_REC_DUTY_CYCLE_RANGE _IOW('i', 0x0000001e, unsigned int) -#define LIRC_SET_REC_CARRIER_RANGE _IOW('i', 0x0000001f, unsigned int) - -#define LIRC_NOTIFY_DECODE _IO('i', 0x00000020) - -#endif diff -Nru nct677x-dkms-1.0.1/nct677x-1.0.1/src/lirc_nct667x-src-1.0.0-ubuntu9.10.patch nct677x-dkms-1.0.4/nct677x-1.0.1/src/lirc_nct667x-src-1.0.0-ubuntu9.10.patch --- nct677x-dkms-1.0.1/nct677x-1.0.1/src/lirc_nct667x-src-1.0.0-ubuntu9.10.patch 2010-03-31 15:56:50.000000000 +0000 +++ nct677x-dkms-1.0.4/nct677x-1.0.1/src/lirc_nct667x-src-1.0.0-ubuntu9.10.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,7 +0,0 @@ ---- lirc.hwdb 2009-12-17 12:31:07.539760680 +0100 -+++ lirc.hwdb.new 2009-12-18 09:18:02.584041023 +0100 -@@ -147,3 +147,4 @@ - VLSystem MPlay Blast;mplay;none;hw_mplay;vlsystem/lircd.conf.mplay; - VLSystem MPlay Mini;mplay;none;hw_mplay;vlsystem/lircd.conf.mplay; - Windows Media Center Transceivers/Remotes (all);mceusb;lirc_dev lirc_mceusb;hw_default;mceusb/lircd.conf.mceusb; -+Nuvoton Transceivers/Remotes;lirc_wb677;lirc_dev lirc_wb677;hw_default;lirc_wb677/lircd.conf.wb677; diff -Nru nct677x-dkms-1.0.1/nct677x-1.0.1/src/lirc_wb677.c nct677x-dkms-1.0.4/nct677x-1.0.1/src/lirc_wb677.c --- nct677x-dkms-1.0.1/nct677x-1.0.1/src/lirc_wb677.c 2010-03-31 15:56:50.000000000 +0000 +++ nct677x-dkms-1.0.4/nct677x-1.0.1/src/lirc_wb677.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,2660 +0,0 @@ -#define _GNU_SOURCE -#include "lirc_wb677.h" -#include "wb83677hg_ir.h" - - -/* enter extended function mode */ -static inline void cr_enter_ext(void) -{ - outb(0x87, CFG_idx); - outb(0x87, CFG_idx); - - if (0xff == cr_read(0x20)) { - CFG_idx = cr_cfg_idx2; - CFG_dat = cr_cfg_dat2; - outb(0x87, CFG_idx); - outb(0x87, CFG_idx); - } -} - - -/* exit extended function mode */ -static inline void cr_exit_ext(void) -{ - outb(0xaa, CFG_idx); -} - -/* select logical device */ -static inline void cr_select_log_dev(int cr) -{ - outb(0x07, CFG_idx); - outb(cr, CFG_dat); -} - -static inline void cr_update(int dat, int cr) -{ - outb(cr, CFG_idx); - outb(dat, CFG_dat); -} - -static inline u8 cr_read(int cr) -{ - outb(cr, CFG_idx); - return inb(CFG_dat); -} - -static inline void cr_safe_update(u8 dat, int cr) -{ - cr_update(cr_read(cr) | dat, cr); -} - -static inline void cr_safe_clear(u8 dat, int cr) -{ - cr_update(cr_read(cr) & dat, cr); -} - - -/* read/write cir registers */ - -static inline void cir_update(u8 dat, int cir) -{ - outb(dat, cir_address + (cir & 0xff)); -} - -static u8 cir_read(int cir) -{ - u8 val; - - val = inb(cir_address + (cir & 0xff)); - - return val; -} - -static inline void cir_wake_update(u8 dat, int cir) -{ - outb(dat, cir_wake_address + (cir & 0xff)); -} - -static u8 cir_wake_read(int cir) -{ - u8 val; - - val = inb(cir_wake_address + (cir & 0xff)); - - return val; -} - -static void cir_dump_reg(void) -{ - cr_enter_ext(); - printk("Dump CIR CR logical device:\n"); - cr_select_log_dev(CIR_LOG_DEV); - printk("CR CIR ACTIVE : 0x%x\n", cr_read(0x30)); - printk("CR CIR BASE ADDR: 0x%x\n", (cr_read(0x61) << 8)|cr_read(0x60)); - printk("CR CIR IRQ NUM: 0x%x\n", cr_read(0x70)); - cr_exit_ext(); - - printk("Dump CIR Registers\n"); - printk("CIR IRCON: 0x%x\n", cir_read(CIR_IRCON)); - printk("CIR IRSTS: 0x%x\n", cir_read(CIR_IRSTS)); - printk("CIR IREN: 0x%x\n", cir_read(CIR_IREN)); - printk("CIR RXFCONT: 0x%x\n", cir_read(CIR_RXFCONT)); - printk("CIR CP: 0x%x\n", cir_read(CIR_CP)); - printk("CIR CC: 0x%x\n", cir_read(CIR_CC)); - printk("CIR SLCH: 0x%x\n", cir_read(CIR_SLCH)); - printk("CIR SLCL: 0x%x\n", cir_read(CIR_SLCL)); - printk("CIR FIFOCON: 0x%x\n", cir_read(CIR_FIFOCON)); - printk("CIR IRFIFOSTS: 0x%x\n", cir_read(CIR_IRFIFOSTS)); - printk("CIR SRXFIFO: 0x%x\n", cir_read(CIR_SRXFIFO)); - printk("CIR TXFCONT: 0x%x\n", cir_read(CIR_TXFCONT)); - printk("CIR STXFIFO: 0x%x\n", cir_read(CIR_STXFIFO)); - printk("CIR FCCH: 0x%x\n", cir_read(CIR_FCCH)); - printk("CIR FCCL: 0x%x\n", cir_read(CIR_FCCL)); - printk("CIR IRFSM: 0x%x\n", cir_read(CIR_IRFSM)); - -} - -static void cir_wake_dump_reg(void) -{ - u8 i = 0; - - cr_enter_ext(); - printk("Dump CIR WKAE CR logical device:\n"); - cr_select_log_dev(CIR_WAKE_LOG_DEV); - printk("CR CIR WAKE ACTIVE : 0x%x \n", cr_read(0x30)); - printk("CR CIR WAKE BASE ADDR: 0x%x\n", (cr_read(0x61) << 8)|cr_read(0x60)); - printk("CR CIR WAKE IRQ NUM: 0x%x\n", cr_read(0x70)); - cr_exit_ext(); - - printk("Dump CIR WAKE Registers\n"); - printk("CIR WAKE IRCON: 0x%x\n", cir_wake_read(CIR_WAKE_IRCON)); - printk("CIR IRSTS: 0x%x\n", cir_wake_read(CIR_WAKE_IRSTS)); - printk("CIR IREN: 0x%x\n", cir_wake_read(CIR_WAKE_IREN)); - printk("CIR WAKE FIFO CMP DEEP: 0x%x\n", cir_wake_read(CIR_WAKE_FIFO_CMP_DEEP)); - printk("CIR WAKE FIFO CMP TOL: 0x%x\n", cir_wake_read(CIR_WAKE_FIFO_CMP_TOL)); - printk("CIR WAKE FIFO COUNT: 0x%x\n", cir_wake_read(CIR_WAKE_FIFO_COUNT)); - printk("CIR WAKE SLCH: 0x%x\n", cir_wake_read(CIR_WAKE_SLCH)); - printk("CIR WAKE SLCL: 0x%x\n", cir_wake_read(CIR_WAKE_SLCL)); - printk("CIR WAKE FIFOCON: 0x%x\n", cir_wake_read(CIR_WAKE_FIFOCON)); - printk("CIR WAKE SRXFSTS: 0x%x\n", cir_wake_read(CIR_WAKE_SRXFSTS)); - printk("CIR WAKE SAMPLE RX FIFO: 0x%x\n", cir_wake_read(CIR_WAKE_SAMPLE_RX_FIFO)); - printk("CIR WAKE WR FIFO DATA: 0x%x\n", cir_wake_read(CIR_WAKE_WR_FIFO_DATA)); - printk("CIR WAKE RD FIFO ONLY: 0x%x\n", cir_wake_read(CIR_WAKE_RD_FIFO_ONLY)); - printk("CIR WAKE RD FIFO ONLY IDX: 0x%x\n", cir_wake_read(CIR_WAKE_RD_FIFO_ONLY_IDX)); - printk("CIR WAKE FIFO IGNORE: 0x%x\n", cir_wake_read(CIR_WAKE_FIFO_IGNORE)); - printk("CIR WAKE IRFSM: 0x%x\n", cir_wake_read(CIR_WAKE_IRFSM)); - - printk("Dump CIR WAKE keys\n"); - printk("%s FIFO count len = %d\n", DRVNAME, cir_wake_read(CIR_WAKE_FIFO_COUNT)); - i = 0; - for (; i < 67; i ++) { - printk("%s FIFO = 0x%x\n", DRVNAME, cir_wake_read(CIR_WAKE_RD_FIFO_ONLY)); - } - -} - - -/* 1. */ -/* 667 HG Config Registers init */ -static int w83667hg_cr_init(void) -{ - int val = 0; - - cr_enter_ext(); - - /* Check 667 CHIP ID first */ - val = cr_read(CHIP_ID_HIGH_ADDR); - if (val != CHIP_ID_HIGH) { - printk("%s %s: chip id high: 0x%x expect:0x%x\n", DRVNAME, chip_id, val, CHIP_ID_HIGH); - // cr_exit_ext(); - // return -ENODEV; - } - else{ - printk("%s %s: chip id high: 0x%x\n", DRVNAME, chip_id, val); - } - - /* now check chip id, LSB */ - val = cr_read(CHIP_ID_LOW_ADDR); - if (CHIP_ID_LOW == (val & CHIP_ID_LOW)) { - printk("%s %s: chip id low: 0x%x expect:0x%x\n", DRVNAME, chip_id, val, CHIP_ID_LOW); - // cr_exit_ext(); - // return -ENODEV; - } - else{ - printk("%s %s: chip id low: 0x%x\n", DRVNAME, chip_id, val); - } - - /* for multi-function pin selection */ - val = cr_read(0x27); - val = (val&0xbc) | 0x41; - cr_update(val, 0x27); //For W83677, CIR TX,RX, CIRWB pin selection - - - - // FIXME - /* set Logical Dev 1: LPT */ - /* not sure really need it or not, find it in 667 wake up windows driver */ - cr_select_log_dev(0x01); - cr_update(DEACTIVE_LOG_DEV, 0x30); - cr_update(0, 0x70); - - /* Then set Logical Dev 6: CIR */ - cr_select_log_dev(CIR_LOG_DEV); - cr_update(ACTIVE_LOG_DEV, 0x30); - - cir_address = CIR_BASE; - cr_update(((CIR_BASE & 0xff00) >> 8), 0x60); - cr_update((CIR_BASE & 0xff), 0x61); -#ifdef IR_667_DEBUG - printk("%s base io port address: 0x%x\n", DRVNAME, cir_address); -#endif - - cr_update(CIR_IRQ_NUM, 0x70); -#ifdef IR_667_DEBUG - printk("%s irq number: %d\n", DRVNAME, CIR_IRQ_NUM); -#endif - - - /* Then set Logical Dev A: ACPI */ - cr_select_log_dev(ACPI_LOG_DEV); - - cr_update(ACTIVE_LOG_DEV, 0x30); - - /* enable cir wake up via PSOUT# (pin 60) */ - cr_safe_update(ENABLE_CIR_WAKE, 0xe0); - - /* enable cir interrupt of mouse IRQ event */ - //cr_safe_update(ENABLE_CIR_INTR_OF_MOUSE_IRQ, 0xf6); - - /* enable pme interrupt of cir password event */ - //cr_safe_update(ENABLE_PME_INTR_OF_CIR_PASS, 0xf7); - - - /* Then set Logical Dev E: CIR WAKE */ - cr_select_log_dev(CIR_WAKE_LOG_DEV); - cr_update(ACTIVE_LOG_DEV, 0x30); - - cir_wake_address = CIR_WAKE_BASE; - cr_update(((CIR_WAKE_BASE & 0xff00) >> 8), 0x60); - cr_update((CIR_WAKE_BASE & 0xff), 0x61); -#ifdef IR_667_DEBUG - printk("%s cir wake up base io port address: 0x%x\n", DRVNAME, cir_wake_address); -#endif - -#ifdef ENABLE_CIR_WAKE_IRQ - cr_update(CIR_WAKE_IRQ_NUM, 0x70); -#ifdef IR_667_DEBUG - printk("%s cir wake up irq number: %d\n", DRVNAME, CIR_WAKE_IRQ_NUM); -#endif -#endif - - cr_exit_ext(); - - return 0; -} - -static void w83667hg_cr_uninit(void) -{ - cr_enter_ext(); - - /* close CIR */ - /* Don't close CIR Wake. When wake-up at power-on, it needs the function. 20091224 - cr_select_log_dev(CIR_WAKE_LOG_DEV); - cr_update(DEACTIVE_LOG_DEV, 0x30); - */ - - - /* Close Logical Dev A: ACPI */ - //cr_select_log_dev(ACPI_LOG_DEV); - - /* enable cir wake up via PSOUT# (pin 60) */ - //cr_safe_clear(DISABLE_CIR_WAKE, 0xe0); - - /* enable cir interrupt of mouse IRQ event */ - //cr_safe_clear(DISABLE_CIR_INTR_OF_MOUSE_IRQ, 0xf6); - - /* enable pme interrupt of cir password event */ - //cr_safe_clear(DISABLE_PME_INTR_OF_CIR_PASS, 0xf7); - - - /* close CIR wake up XXX */ - //cr_select_log_dev(CIR_WAKE_LOG_DEV); - //cr_update(DEACTIVE_LOG_DEV, 0x30); - - cr_exit_ext(); -} - -static int w83667hg_input_open(struct input_dev *cur_input_dev) -{ - return 0; -} - -static void w83667hg_input_close(struct input_dev *cur_input_dev) -{ -} - -/* 2. */ -/* init linux input structure */ -static struct input_dev *w83667hg_input_init(void) -{ - int i; - struct input_dev *cur_input_dev = NULL; - - cur_input_dev = input_allocate_device(); - if (NULL == cur_input_dev) { - printk("alloc input device error\n"); - return NULL; - } - - cur_input_dev->name = INPUTNAME; - cur_input_dev->phys = DRVNAME; - memcpy(&cur_input_dev->id, &w83667hg_input_id, sizeof(struct input_id)); - - cur_input_dev->open = w83667hg_input_open; - cur_input_dev->close = w83667hg_input_close; - - //cur_input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); - //cur_input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y); - cur_input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); - cur_input_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y); - for (i=0; i<256; i++) { - set_bit(usb_kbd_keycode[i], cur_input_dev->keybit); - } - clear_bit(0, cur_input_dev->keybit); -// cur_input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT); - cur_input_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_RIGHT); - - - if (input_register_device(cur_input_dev)) { - printk("register input device error\n"); - return NULL; - } - - return cur_input_dev; -} - -static void w83667hg_input_uninit(struct input_dev *cur_input_dev) -{ - input_get_device(cur_input_dev); - input_unregister_device(cur_input_dev); - input_free_device(cur_input_dev); - cur_input_dev = NULL; -} - - -/* internal call for register lirc */ -static int lirc_set_use_inc(void *data) -{ - struct irctl *ir = data; - - if (!ir) { - printk("%s: set_use_inc called with no context\n", DRVNAME); - return -EIO; - } -#ifdef IR_667_DEBUG - printk("%s : set use inc\n", DRVNAME); -#endif - spin_lock(&ir->lock); - ir->ctrl_fix_head = 1; - spin_unlock(&ir->lock); - - - MOD_INC_USE_COUNT; - - return 0; -} - -static void lirc_set_use_dec(void *data) -{ - struct irctl *ir = data; - - if (!ir) { - printk("%s: set_use_dec called with no context\n", DRVNAME); - return; - } -#ifdef IR_667_DEBUG - printk("%s : set use dec\n", DRVNAME); -#endif - - MOD_DEC_USE_COUNT; -} - - -static int lirc_ioctl(struct inode *node, struct file *filep, unsigned int cmd, unsigned long arg) -{ - int ret = 0; - void __user *uptr = (void __user *)arg; - - int mode = 0; - struct irctl *ir = &w83667hg_irctl; - struct ir_recv_t *ir_recv = &w83667hg_ir_recv; - -#ifdef ALLOW_DEBUG_IOCTL - printk("%s: IO Ctrl Code:%d\n", DRVNAME, cmd); -#endif - - switch(cmd) - { - /* lirc ioctl commands */ - case LIRC_GET_FEATURES: - ret = put_user(w83667hg_lirc_plugin->features, (unsigned long*)arg); - break; - case LIRC_GET_SEND_MODE: - if(!(w83667hg_lirc_plugin->features & LIRC_CAN_REC_MASK)) - return(-ENOSYS); - - ret = put_user(LIRC_REC2MODE - (w83667hg_lirc_plugin->features & LIRC_CAN_REC_MASK), - (unsigned long*)arg); - if (ret) - return ret; - break; - case LIRC_SET_SEND_MODE: - ret = get_user(mode, (unsigned long*)arg); - if (ret) - return ret; - if(mode != (LIRC_MODE_PULSE&LIRC_CAN_SEND_MASK)) - return -EINVAL; - break; - case LIRC_GET_LENGTH: - ret = put_user((unsigned long)w83667hg_lirc_plugin->code_length, - (unsigned long *)arg); - break; - - /* ioctl commands for lirc_wb667 */ - case IR_DUMPCIRREG: - cir_dump_reg(); - break; - case IR_DUMPWAKEREG: - cir_wake_dump_reg(); - break; - case IR_IOLEARNWAKE: - spin_lock(&ir_recv->lock); - if (ir_recv->wake_state) { - spin_unlock(&ir_recv->lock); - ret = -EFAULT; - break; - } - ir_recv->wake_state = ST_WAKE_START; - spin_unlock(&ir_recv->lock); - - /* close cir first */ - cr_enter_ext(); - cr_select_log_dev(CIR_LOG_DEV); - cr_update(DEACTIVE_LOG_DEV, 0x30); - cr_exit_ext(); - //cir_update(0, CIR_IREN); - cir_update(0xff, CIR_IRSTS); - - /* set cir wake */ - cir_wake_update(CIR_WAKE_IRCON_RXEN | CIR_WAKE_IRCON_RXINV | CIR_WAKE_IRCON_SAMPLE_PERIOD_SEL, CIR_WAKE_IRCON); - cir_wake_update(0xff, CIR_WAKE_IRSTS); - cir_wake_update(0xff, CIR_WAKE_FIFOCON); - cir_wake_update(0, CIR_WAKE_FIFOCON); -#ifdef ALLOW_DEBUG_WAKE - printk("%s FIFO count len = %d\n", DRVNAME, cir_wake_read(CIR_WAKE_FIFO_COUNT)); -#endif - cir_wake_update(CIR_WAKE_IREN_PE, CIR_WAKE_IREN); - - wait_event(ir_recv->queue, ir_recv->wake_state == ST_WAKE_FINISH); - while ((cir_wake_read(CIR_WAKE_RD_FIFO_ONLY_IDX)) != 0) { -#ifdef ALLOW_DEBUG_WAKE - printk("%s setting wake up key: 0x%x\n", DRVNAME, cir_wake_read(CIR_WAKE_RD_FIFO_ONLY)); -#else - cir_wake_read(CIR_WAKE_RD_FIFO_ONLY); -#endif - } - - /* learn wake up complete */ - spin_lock(&ir_recv->lock); - ir_recv->wake_state = ST_WAKE_NONE; - spin_unlock(&ir_recv->lock); - -#ifdef ALLOW_DEBUG_WAKE - ret = 0; - for (; ret < 67; ret ++) { - printk("%s FIFO count = 0x%x\n", DRVNAME, cir_wake_read(CIR_WAKE_RD_FIFO_ONLY)); - } - printk("%s FIFO count len = %d\n", DRVNAME, cir_wake_read(CIR_WAKE_FIFO_COUNT)); -#endif - - /* cir wake interrupt stop, resume cir */ - cir_wake_update(CIR_WAKE_IRCON_MODE0 | CIR_WAKE_IRCON_RXEN | CIR_WAKE_IRCON_R | CIR_WAKE_IRCON_RXINV | CIR_WAKE_IRCON_SAMPLE_PERIOD_SEL, CIR_WAKE_IRCON); - cir_wake_update(0xff, CIR_WAKE_IRSTS); - cir_wake_update(0, CIR_WAKE_IREN); - cr_enter_ext(); - cr_select_log_dev(CIR_LOG_DEV); - cr_update(ACTIVE_LOG_DEV, 0x30); - cr_exit_ext(); - ret = 0; - - break; - case IR_IOUNSETWAKE: - cir_wake_update(0, CIR_WAKE_IRCON); - cir_wake_update(0, CIR_WAKE_IREN); - cir_wake_update(0xFF, CIR_WAKE_IRSTS); - cir_wake_update(0, CIR_WAKE_IRSTS); - cr_enter_ext(); - cr_select_log_dev(CIR_WAKE_LOG_DEV); - cr_update(DEACTIVE_LOG_DEV, 0x30); - cr_exit_ext(); - //cir_wake_update(CIR_WAKE_IRCON_MODE0 | CIR_WAKE_IRCON_RXEN | CIR_WAKE_IRCON_R | CIR_WAKE_IRCON_RXINV | CIR_WAKE_IRCON_SAMPLE_PERIOD_SEL, CIR_WAKE_IRCON); - break; - case IR_IOSETWAKE: - cr_enter_ext(); - cr_select_log_dev(CIR_WAKE_LOG_DEV); - cr_update(ACTIVE_LOG_DEV, 0x30); - cr_exit_ext(); - cir_wake_update(CIR_WAKE_IRCON_MODE0 | CIR_WAKE_IRCON_RXEN | CIR_WAKE_IRCON_R | CIR_WAKE_IRCON_RXINV | CIR_WAKE_IRCON_SAMPLE_PERIOD_SEL, CIR_WAKE_IRCON); - cir_wake_update(0xFF, CIR_WAKE_IRSTS); - cir_wake_update(0, CIR_WAKE_IRSTS); - cir_wake_update(0, CIR_WAKE_IREN); - break; - case IR_IOCLEANDATA: - w83667hg_clean_data(&w83667hg_ir_recv, &w83667hg_irctl); - break; - case IR_IOSTARTSTUDY: - spin_lock(&ir->lock); - ir->study_state = ST_STUDY_START; - spin_unlock(&ir->lock); - //cir_update(cir_read(CIR_IRCON) | CIR_IRCON_WIREN, CIR_IRCON); - cir_update(CIR_IRCON_WIREN | CIR_IRCON_RXEN | CIR_IRCON_SAMPLE_PERIOD_SEL, CIR_IRCON); - -/* for WRX RTR - cir_update(CIR_FIFOCON_RX_TRIGGER_LEV_8, CIR_FIFOCON); - //cir_update(CIR_IREN_RTR, CIR_IREN); - cir_update(0, CIR_IREN); -*/ - break; - case IR_IOSTOPSTUDY: - cir_update(CIR_IRCON_TXEN | CIR_IRCON_RXEN | CIR_IRCON_RXINV | CIR_IRCON_SAMPLE_PERIOD_SEL, CIR_IRCON); - spin_lock(&ir->lock); - ir->study_state = ST_STUDY_NONE; - ir->buf_count = 0; - ir->cur_buf_num = 0; - wake_up(&ir->queue); - spin_unlock(&ir->lock); - break; - case IR_IOGETCARRIER: - spin_lock(&ir->lock); - if (!(ir->study_state > ST_STUDY_NONE)) { - ret = -EFAULT; - spin_unlock(&ir->lock); - break; - } - //w83667hg_record_study_carrier(ir); -#ifdef ALLOW_DEBUG_IOCTL - printk("%s: current get carrier: %d\n", DRVNAME, ir->carrier); -#endif - if (copy_to_user(uptr, &ir->carrier, sizeof(unsigned int))) { - ret = -EFAULT; - } - spin_unlock(&ir->lock); - break; - case IR_IOSETCARRIER: - spin_lock(&ir->lock); - /* you can set carrier at any time */ - /* - if (~(ir->send_state)) { - ret = -EFAULT; - up(&ir->lock); - break; - } - */ - if (copy_from_user(&ir->carrier, uptr, sizeof(unsigned int))) { - ret = -EFAULT; - spin_unlock(&ir->lock); - break; - } -#ifdef ALLOW_DEBUG_IOCTL - printk("%s: current set carrier: %x\n", DRVNAME, ir->carrier); -#endif - w83667hg_set_carrier(&ir->carrier); - spin_unlock(&ir->lock); - break; - case IR_IOSTUDYLEN: - spin_lock(&ir->lock); - if (ir->study_state == ST_STUDY_NONE) { - spin_unlock(&ir->lock); -#ifdef ALLOW_DEBUG_IOCTL - printk("%s: open STUDY first\n", DRVNAME); -#endif - ret = -EFAULT; - break; - } - ir->study_state = ST_STUDY_START; - spin_unlock(&ir->lock); - wait_event(ir->queue, ir->study_state == ST_STUDY_ALL_RECV); - spin_lock(&ir->lock); - - /* in STUDY, copy data buf len to user space for read() */ - ir->cur_buf_num = 0; - if (ir->buf_count == 0) { - ret = -EFAULT; - } - else if (copy_to_user(uptr, &ir->buf_count, sizeof(unsigned int))) { - ret = -EFAULT; - } - /* copy data to lirc plugin buffer, ready copy to user space */ - spin_unlock(&ir->lock); - break; - case IR_IOSTUDYBUF: - spin_lock(&ir->lock); - if (ir->study_state != ST_STUDY_ALL_RECV) { - spin_unlock(&ir->lock); - ret = -EFAULT; - break; - } - if (copy_to_user(uptr, &ir->buf[ir->cur_buf_num], sizeof(unsigned char))) { - spin_unlock(&ir->lock); - ret = -EFAULT; - break; - } - if (ir->cur_buf_num < ir->buf_count) { - ir->cur_buf_num ++; - } - spin_unlock(&ir->lock); - break; - case IR_IORESTUDYBUF: - spin_lock(&ir->lock); - ir->cur_buf_num = 0; - spin_unlock(&ir->lock); - break; - case IR_CHECKCHIP: - if (copy_to_user(uptr, chip_id, sizeof(unsigned long long))) { - ret = -EFAULT; - } - break; - default: - return (-ENOIOCTLCMD); - } - - return ret; -} - -static int w83667hg_set_carrier(unsigned int *carrier) -{ - u16 val; - - cir_update(1, CIR_CP); - val = 3000000 / (*carrier) - 1; - cir_update(val & 0xff, CIR_CC); - -#ifdef ALLOW_DEBUG_STUDY - printk("cp: 0x%x cc: 0x%x\n", cir_read(CIR_CP), cir_read(CIR_CC)); -#endif - return 0; -} - -static ssize_t lirc_write(struct file *file, const char *buf, size_t n, loff_t * ppos) -{ - size_t cur_count; - struct ir_send_t *ir_send = &w83667hg_ir_send; - unsigned int i; - ssize_t ret; - - spin_lock(&ir_send->lock); - - if (n >= IRCTL_BUF_LIMIT) { - ir_send->buf_count = cur_count = IRCTL_BUF_LIMIT; - ret = IRCTL_BUF_LIMIT; - } else { - ir_send->buf_count = cur_count = n; - ret = n; - } - - /* the first copy from user and open interrupt for TX */ - if (copy_from_user(ir_send->buf, buf, ir_send->buf_count)) { - ir_send->buf_count = 0; - spin_unlock(&ir_send->lock); - return (-EFAULT); - } - - ir_send->cur_buf_num = 0; - - /* for safety, close RX while TX */ - cir_update(CIR_IREN_TFU | CIR_IREN_TTR, CIR_IREN); - - ir_send->send_state = ST_SEND_REPLY; - - cir_update(CIR_FIFOCON_TX_TRIGGER_LEV_8 | CIR_FIFOCON_RXFIFOCLR, CIR_FIFOCON); - /* turn on TTR interrupt, it's ugly */ - i = 0; - for (; i < 9; i ++) { - cir_update(0x01, CIR_STXFIFO); - } - spin_unlock(&ir_send->lock); - - wait_event(ir_send->queue, ir_send->send_state == ST_SEND_REQUEST); - - spin_lock(&ir_send->lock); - ir_send->send_state = ST_SEND_NONE; - spin_unlock(&ir_send->lock); - - cir_update(CIR_IREN_RDR | CIR_IREN_PE, CIR_IREN); - - return ret; -} - -static void w83667hg_clean_data(struct ir_recv_t *ir_recv, struct irctl *ir) -{ - spin_lock(&ir_recv->lock); - ir_recv->buf_count = 0; - //ir_recv->wake_state = ST_WAKE_NONE; - wake_up(&ir_recv->queue); - spin_unlock(&ir_recv->lock); - - spin_lock(&ir->lock); - ir->lircdata = 0; - /* - for (i = 0; i < IRCTL_BUF_LIMIT; i ++) { - ir->buf = 0; - } - */ - ir->pressed_keycode = 0; - ir->pressed_shiftmask = 0; - ir->buf_count = 0; - ir->cur_buf_num = 0; - /* - ir->study_state = ST_STUDY_NONE; - ir->send_state = ST_SEND_NONE; - */ - wake_up(&ir->queue); - spin_unlock(&ir->lock); - - cir_update(cir_read(CIR_FIFOCON) | 0x88, CIR_FIFOCON); - cir_wake_update(cir_wake_read(CIR_WAKE_FIFOCON) | 0x8, CIR_WAKE_FIFOCON); - -} - -/* 3. */ -static void w83667hg_ir_recv_init(struct ir_recv_t *ir_recv) -{ - ir_recv->buf_count = 0; - spin_lock_init(&ir_recv->lock); - ir_recv->wake_state = ST_WAKE_NONE; - init_waitqueue_head(&ir_recv->queue); - ir_recv->recv_state = ST_RECV_WAIT_7F; -} - -static void w83667hg_ir_send_init(struct ir_send_t *ir_send) -{ - ir_send->buf_count = 0; - spin_lock_init(&ir_send->lock); - ir_send->send_state = ST_SEND_NONE; - init_waitqueue_head(&ir_send->queue); -} - - -/* lirc_fops - * - * 1) it's LIRC's fops, so NOT allow add owner in it - * 2) define lirc functions at here will replace the lirc original fops functions, so lirc_write() in lirc_dev will not work - * 3) lirc has its own ioctl, lirc_ioctl() in current file not register in lirc_fops, so it only work for lirc_wb667 - * lirc_ioctl() in current file register in w83667hg_irctl_init() as lirc_plugin's ioctl while initial driver, and it does not effect on lirc_dev - */ -static struct file_operations lirc_fops = { - write: lirc_write, - ioctl: lirc_ioctl, -}; - - -/* init lirc buffer, register, irctl */ -static int w83667hg_irctl_init(struct irctl *ir) -{ - int err = 0, minor = -1; - - w83667hg_lirc_buffer = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL); - if (!w83667hg_lirc_buffer) { - err = -ENOMEM; - goto out_lirc_buffer; - } - memset(w83667hg_lirc_buffer, 0, sizeof(struct lirc_buffer)); - - if (lirc_buffer_init(w83667hg_lirc_buffer, sizeof(lirc_t), LIRCBUF_SIZE)) { - err = -ENOMEM; - goto out_lirc_buffer; - } - - w83667hg_lirc_plugin = kmalloc(sizeof(struct lirc_driver), GFP_KERNEL); - if (!w83667hg_lirc_plugin) { - err = -ENOMEM; - goto out_lirc_plugin; - } - memset(w83667hg_lirc_plugin, 0, sizeof(struct lirc_driver)); - - ir->lirc_plugin = w83667hg_lirc_plugin; - - strcpy(w83667hg_lirc_plugin->name, DRVNAME); - w83667hg_lirc_plugin->minor = -1; - w83667hg_lirc_plugin->features = LIRC_CAN_SEND_PULSE | - LIRC_CAN_SET_TRANSMITTER_MASK | - LIRC_CAN_REC_MODE2; - // LIRC_CAN_SET_SEND_DUTY_CYCLE | - // LIRC_CAN_SET_SEND_CARRIER; - w83667hg_lirc_plugin->data = &w83667hg_irctl; - w83667hg_lirc_plugin->rbuf = w83667hg_lirc_buffer; - w83667hg_lirc_plugin->set_use_inc = &lirc_set_use_inc; - w83667hg_lirc_plugin->set_use_dec = &lirc_set_use_dec; - w83667hg_lirc_plugin->code_length = sizeof(lirc_t) * 8; -// w83667hg_lirc_plugin->ioctl = lirc_ioctl; - w83667hg_lirc_plugin->fops = &lirc_fops; - w83667hg_lirc_plugin->dev = NULL; - w83667hg_lirc_plugin->owner = THIS_MODULE; - - //if ((minor = lirc_register_plugin(w83667hg_lirc_plugin)) < 0) { - if ((minor = lirc_register_driver(w83667hg_lirc_plugin)) < 0) { - err = -ENOMEM; - goto out_lirc_plugin_register; - } -#ifdef IR_667_DEBUG - printk("%s register lirc minor: %d\n", DRVNAME, minor); -#endif - - w83667hg_lirc_plugin->minor = minor; - ir->lirc_plugin = w83667hg_lirc_plugin; - - /* init irctl */ - ir->pressed_keycode = 0; - ir->pressed_shiftmask = 0; - ir->buf_count = 0; - ir->ctrl_fix_head = 1; - spin_lock_init(&ir->lock); - ir->study_state = ST_STUDY_NONE; - init_waitqueue_head(&ir->queue); - - goto out; - - out_lirc_plugin_register: - kfree(w83667hg_lirc_plugin); - out_lirc_plugin: - lirc_buffer_free(w83667hg_lirc_buffer); - out_lirc_buffer: - kfree(w83667hg_lirc_buffer); - out: - return err; -} - -static void w83667hg_irctl_uninit(struct irctl *ir) -{ - //lirc_unregister_plugin(w83667hg_lirc_plugin->minor); - lirc_unregister_driver(w83667hg_lirc_plugin->minor); - kfree(w83667hg_lirc_plugin); - ir->lirc_plugin = NULL; - lirc_buffer_free(w83667hg_lirc_buffer); - kfree(w83667hg_lirc_buffer); - ir->lirc_buffer = NULL; -} - -#ifdef ALLOW_DEBUG_PRINT_PULSE -void debug_print_pulse(void) -{ - u8 count, i; - - count = cir_read(CIR_RXFCONT); - for (i = 0; i < count; i ++) { - printk("%s current cir pluse: 0x%x\n", DRVNAME, cir_read(CIR_SRXFIFO)); - } -} - -void debug_print_wake_pulse(void) -{ - u8 count, i; - - count = cir_wake_read(CIR_WAKE_FIFO_COUNT); - for (i = 0; i < count; i ++) { - printk("%s current cir wake pluse: 0x%x\n", DRVNAME, cir_wake_read(CIR_WAKE_SRXFSTS)); - } -} -#endif - -static void w83667hg_study_recv(struct ir_recv_t *ir_recv, struct irctl *ir) -{ - unsigned int i = 0; - unsigned int packet_on_dur = 0; - - spin_lock(&ir_recv->lock); - ir_recv->buf[ir_recv->buf_count] = cir_read(CIR_SRXFIFO); - if (ir_recv->buf[ir_recv->buf_count] == 0x80) { - /* close interrupt now */ - //cir_wake_update(0, CIR_WAKE_IREN); - - spin_lock(&ir->lock); - - /* 1. get carrier */ - ir->carrier = cir_read(CIR_FCCL); - ir->carrier |= cir_read(CIR_FCCH) << 8; - - if (ir->carrier == 0) { - printk("%s: get carrier error!\n", DRVNAME); - } - - i = 0; - for (; i < ir_recv->buf_count; i ++) { - if(ir_recv->buf[i] & BIT_PULSE_MASK) { - packet_on_dur += ir_recv->buf[i] & BIT_LEN; - } - } - packet_on_dur *= MCE_TIME_UNIT; - -#ifdef ALLOW_DEBUG_STUDY - printk("%s: carrier count: 0x%x\n", DRVNAME, ir->carrier); - printk("%s: packet on duration: %u\n", DRVNAME, packet_on_dur); -#endif - ir->carrier *= 1000000; - ir->carrier /= packet_on_dur; -#ifdef ALLOW_DEBUG_STUDY - printk("%s: final carrier frequency: %u\n", DRVNAME, ir->carrier); -#endif - if ((ir->carrier > MAX_CARRIER) || (ir->carrier < MIN_CARRIER)) { - /* carrier is too large or too small */ -#ifdef ALLOW_DEBUG_STUDY - printk("%s: current received carrier is too large or too small\n", DRVNAME); -#endif - ir_recv->buf_count = 0; - spin_unlock(&ir_recv->lock); - - ir->buf_count = 0; - ir->study_state = ST_STUDY_ALL_RECV; - wake_up(&ir->queue); - spin_unlock(&ir->lock); - return; - } - - /* 2. get pulse */ - i = 0; - /* 1) find sync head */ - while (!((ir_recv->buf[i] & BIT_PULSE_MASK) & 0x80)) { - i ++; - } - /* 2) find 0x7f */ - // FIXME, the silent part of infrared signal may change by protocol or sample period. but current value fits MCE RC-6 - while ((ir_recv->buf[i] != 0x7f) || - (ir_recv->buf[i + 1] != 0x7f) || - (ir_recv->buf[i + 2] != 0x7f)) { - i ++; - } - /* 3) find next head */ - while (!((ir_recv->buf[i] & BIT_PULSE_MASK) & 0x80)) { - i ++; - } - //ir->buf_count = --i; - /* now buf_count direct to next pulse sync head */ - ir->buf_count = i; - /* 4) copy pluse from recv to ir */ - i = 0; - for (; i <= ir->buf_count; i ++) { - ir->buf[i] = ir_recv->buf[i]; - } - - - ir_recv->buf_count = 0; - spin_unlock(&ir_recv->lock); - - ir->study_state = ST_STUDY_ALL_RECV; - wake_up(&ir->queue); - spin_unlock(&ir->lock); - } else { - ir_recv->buf_count ++; - spin_unlock(&ir_recv->lock); - } -} - - -static void w83667hg_recv(struct ir_recv_t *ir_recv, struct irctl *ir) -{ - u8 buf; - unsigned int i = 0, rlc = 0; - - spin_lock(&ir_recv->lock); - - ir_recv->buf[ir_recv->buf_count] = cir_read(CIR_SRXFIFO); - if (ir_recv->buf[ir_recv->buf_count] == 0x7f) { - if (ir_recv->recv_state & ST_RECV_WAIT_7F) { - ir_recv->recv_state = ST_RECV_WAIT_HEAD; - ir_recv->buf_count ++; - { // decode begin - spin_lock(&ir->lock); - - ir->buf_count = ir_recv->buf_count; - for (; i < ir->buf_count; i ++) { - ir->buf[i] = ir_recv->buf[i]; - } - ir->cur_buf_num = 0; - - //ir_recv->buf_count ++; - spin_unlock(&ir_recv->lock); - - i = 0; - while (i < ir->buf_count) { - rlc += ir->buf[i] & BIT_LEN; - i ++; - } -#ifdef ALLOW_DEBUG_DECODE - printk("\n%s cur rlc len: %d\n", DRVNAME, rlc); -#endif - - if (rlc >= CONTROLLER_BUF_LEN_MIN) { - // lirc controller - w83667hg_submit_controller(ir); - } else if ((rlc >= KEYBOARD_BUF_LEN_MIN) && - (rlc < KEYBOARD_BUF_LEN_MAX)) { - w83667hg_submit_key(ir); - input_sync(ir->input_dev); - } else if ((rlc >= MOUSE_BUF_LEN_MIN) && - (rlc < KEYBOARD_BUF_LEN_MIN)) { - w83667hg_submit_mouse(ir); - input_sync(ir->input_dev); - } - - ir->buf_count = 0; - spin_unlock(&ir->lock); - } // decode end - } else { - ir_recv->buf_count ++; - spin_unlock(&ir_recv->lock); - } - } else { // normal recv - if (ir_recv->recv_state & ST_RECV_WAIT_HEAD) { - if (ir_recv->buf[ir_recv->buf_count] & BIT_PULSE_MASK) { - ir_recv->recv_state = ST_RECV_WAIT_7F; - buf = ir_recv->buf[ir_recv->buf_count]; - ir_recv->buf_count = 0; - ir_recv->buf[0] = buf; - } - } - ir_recv->buf_count ++; - spin_unlock(&ir_recv->lock); - } -} - - -static void w83667hg_set_key(u8 *set_frame, u8 val, u8 *keycode, u8 *shiftmask) -{ -#ifdef ALLOW_DEBUG_DECODE - printk("%s set key: %d\n", DRVNAME, val); -#endif - - if (*set_frame <= KEY_SUBMIT_KEYCODE_FRAME_NUM + 1) { - *keycode <<= 1; - *keycode |= val; -#ifdef ALLOW_DEBUG_DECODE - printk("%s set key keycode:0x%x\n", DRVNAME, *keycode); - printk("set frame: %d\n", *set_frame); -#endif - } else { - *shiftmask <<= 1; - *shiftmask |= val; -#ifdef ALLOW_DEBUG_DECODE - printk("%s set key mask:0x%x\n", DRVNAME, *shiftmask); - printk("set frame: %d\n", *set_frame); -#endif - } - (*set_frame) ++; -} - - -static int w83667hg_jump_frame(struct irctl *ir, u8 frame_num, unsigned int *buf_num, u8 *out_bit, u8 *decode_status) -{ - unsigned int rlc = 0, cur_buf_num = *buf_num; - u8 bit = *out_bit, buf; - u8 cur_decode_status = *decode_status; - u8 cur_frame_num; - - cur_frame_num = 1; - for (; cur_frame_num <= frame_num; cur_buf_num ++) { - buf = ir->buf[cur_buf_num]; - if (cur_buf_num > ir->buf_count) { -#ifdef ALLOW_DEBUG_DECODE - printk("%s: jump frame error\n", DRVNAME); - printk("current buf num: %d\n", cur_buf_num); - printk("current jumped frame: %d\n", cur_frame_num); - printk("current frame length: %d\n", rlc); - printk("total cir signal:\n"); - for (cur_buf_num = 0; cur_buf_num < ir->buf_count; cur_buf_num ++) { - printk("0x%x ", ir->buf[cur_buf_num]); - if (cur_buf_num % 6 == 5) { - printk("\n"); - } - } -#endif - return (-1); - } - if (bit == (buf & BIT_PULSE_MASK)) { - rlc += buf & BIT_LEN; - } else { - - // decode - switch (cur_decode_status) { - case ST_DECODE_NEW: - if ((rlc > ONE_PULSE_LEN_LOW) && - (rlc < ONE_PULSE_LEN_HIGH)) { - if (bit & BIT_PULSE_MASK) { - cur_decode_status = ST_DECODE_ONE; - } else { - cur_decode_status = ST_DECODE_ZERO; - } - } - else if ((rlc > TWO_PULSE_LEN_LOW) && - (rlc < TWO_PULSE_LEN_HIGH)) { - /* error occur, just ignore */ - cur_decode_status = ST_DECODE_NEW; - cur_frame_num ++; - } - break; - case ST_DECODE_ZERO: - if ((rlc > ONE_PULSE_LEN_LOW) && - (rlc < ONE_PULSE_LEN_HIGH)) { - if (bit & BIT_PULSE_MASK) { - /* "01" => 0 */ - cur_decode_status = ST_DECODE_NEW; - cur_frame_num ++; - } else { - /* error */ - cur_decode_status = ST_DECODE_NEW; - cur_frame_num ++; - } - } - else if ((rlc > TWO_PULSE_LEN_LOW) && - (rlc < TWO_PULSE_LEN_HIGH)) { - if (bit & BIT_PULSE_MASK) { - /* "01" => 0 */ - cur_decode_status = ST_DECODE_ONE; - cur_frame_num ++; - } else { - /* error */ - cur_decode_status = ST_DECODE_ZERO; - cur_frame_num ++; - } - } - break; - case ST_DECODE_ONE: - if ((rlc > ONE_PULSE_LEN_LOW) && - (rlc < ONE_PULSE_LEN_HIGH)) { - if (bit & BIT_PULSE_MASK) { - /* "11" => error */ - cur_decode_status = ST_DECODE_NEW; - cur_frame_num ++; - } else { - /* "10" => 1 */ - cur_decode_status = ST_DECODE_NEW; - cur_frame_num ++; - } - } - else if (rlc > TWO_PULSE_LEN_LOW) { - if (bit & BIT_PULSE_MASK) { - /* "11" => error */ - cur_decode_status = ST_DECODE_ONE; - cur_frame_num ++; - } else { - /* "10" => 1 */ - cur_decode_status = ST_DECODE_ZERO; - cur_frame_num ++; - } - } - break; - }// switch - - bit = buf & BIT_PULSE_MASK; - rlc = buf & BIT_LEN; - } - } // for decode - -/* - bit = ir->buf[cur_buf_num] & BIT_MASK; - if (cur_decode_status & ST_DECODE_NEW) { - if (bit) { - *decode_status = ST_DECODE_ONE; - } else { - *decode_status = ST_DECODE_ZERO; - } - } else { - *decode_status = ST_DECODE_NEW; - } - *out_bit = bit; -*/ - - /* Fix problem 1 */ - if ((ir->buf[cur_buf_num] & BIT_LEN) > TWO_PULSE_LEN_LOW) { -#ifdef ALLOW_DEBUG_DECODE - printk("%s: fix problem 1 in jump_frame()\n", DRVNAME); -#endif -#ifdef ALLOW_DEBUG_DECODE - if (cur_frame_num > frame_num + 1) { - printk("%s error: jump_frame() get a too long frame\n", DRVNAME); - } -#endif - cur_buf_num --; - } - - /* copy from jump_iden */ - if (cur_decode_status & ST_DECODE_NEW) { -#ifdef ALLOW_DEBUG_DECODE - printk("hey man, it's NEW in jump_frame\n"); -printk("cur buf: 0x%x\n", ir->buf[cur_buf_num]); -printk("cur state: 0x%x\n", cur_decode_status); -#endif - *buf_num = -- cur_buf_num; - //cur_buf_num --; - *out_bit = ir->buf[cur_buf_num] & BIT_PULSE_MASK; - if (*out_bit) { - *decode_status = ST_DECODE_ONE; - } else { - *decode_status = ST_DECODE_ZERO; - } - } else { -#ifdef ALLOW_DEBUG_DECODE -printk("cur buf: 0x%x\n", ir->buf[cur_buf_num]); -printk("cur state: 0x%x\n", cur_decode_status); -#endif - *buf_num = cur_buf_num; - *out_bit = ir->buf[cur_buf_num] & BIT_PULSE_MASK; - *decode_status = ST_DECODE_NEW; -/* - if (*out_bit) { - *decode_status = ST_DECODE_ONE; - } else { - *decode_status = ST_DECODE_ZERO; - } -*/ - } - - return 0; -} - -static int w83667hg_jump_head(struct irctl *ir, unsigned int *buf_num) -{ - unsigned int i, rlc = 0, max_buf_count = ir->buf_count; - u8 bit = BIT_PULSE_MASK, buf; - - for (i = 0; i < max_buf_count; i ++) { - buf = ir->buf[i]; - if (bit == (buf & BIT_PULSE_MASK)) { - rlc += buf & BIT_LEN; - } else { - if ((rlc > HEAD_SYNC_LEN_LOW) && - (rlc < HEAD_SYNC_LEN_HIGH) && - (bit & BIT_PULSE_MASK)) { - break; - } - bit = buf & BIT_PULSE_MASK; - rlc = buf & BIT_LEN; - } - } // for decode - - if (i >= max_buf_count) { -//#ifdef ALLOW_DEBUG_DECODE -#if 0 - printk("%s jump pulse error\n", DRVNAME); - printk("current buf num: %d\n", *buf_num); - printk("current jumped pulse: %d\n", i); - printk("current pulse length: %d\n", rlc); - printk("total cir signal:\n"); - for (i = 0; i < max_buf_count; i ++) { - printk("0x%x ", ir->buf[i]); - if (i % 6 == 5) { - printk("\n"); - } - } -#endif - return (-1); - } - - *buf_num = i; - - return 0; -} - - -static int w83667hg_check_identification(u8 val, u8 identification, u8 *cur_iden) -{ - *cur_iden <<= 1; - *cur_iden |= val ; -#ifdef ALLOW_DEBUG_DECODE - printk("%s current check iden recv: %d\n", DRVNAME, val); - printk("%s current iden value: 0x%x\n", DRVNAME, *cur_iden); -#endif - - if (identification == (*cur_iden & IDENTIFICATION_CHECK_BIT)) { -#ifdef ALLOW_DEBUG_DECODE - printk("%s find identification\n\n", DRVNAME); -#endif - return 0; - } else { - return (-1); - } -} - -static int w83667hg_jump_identification(struct irctl *ir, u8 identification, unsigned int *buf_num, u8 *out_bit, u8 *decode_status) -{ - unsigned int rlc = 0, i = 1; - u8 bit = *out_bit, buf; - u8 cur_iden = 0; - u8 cur_decode_status = *decode_status; - - bit = BIT_PULSE_MASK; - cur_decode_status = ST_DECODE_NEW; - - for (; i < ir->buf_count; i ++) { - buf = ir->buf[i]; -#ifdef ALLOW_DEBUG_DECODE -printk("buf: 0x%x\n", buf); -#endif - if (bit == (buf & BIT_PULSE_MASK)) { - rlc += buf & BIT_LEN; - } else { - // decode - switch (cur_decode_status) { - case ST_DECODE_NEW: - if ((rlc > ONE_PULSE_LEN_LOW) && - (rlc < ONE_PULSE_LEN_HIGH)) { - if (bit & BIT_PULSE_MASK) { - cur_decode_status = ST_DECODE_ONE; - } else { - cur_decode_status = ST_DECODE_ZERO; - } - } - else if ((rlc > TWO_PULSE_LEN_LOW) && - (rlc < TWO_PULSE_LEN_HIGH)) { - /* error occur, just ignore */ - cur_decode_status = ST_DECODE_NEW; - if (!w83667hg_check_identification(0, identification, &cur_iden)) { - goto find_iden; - } - } - break; - case ST_DECODE_ZERO: - if ((rlc > ONE_PULSE_LEN_LOW) && - (rlc < ONE_PULSE_LEN_HIGH)) { - if (bit & BIT_PULSE_MASK) { - /* "01" => 0 */ - cur_decode_status = ST_DECODE_NEW; - if (!w83667hg_check_identification(0, identification, &cur_iden)) { - goto find_iden; - } - } else { - /* error */ - cur_decode_status = ST_DECODE_NEW; - if (!w83667hg_check_identification(0, identification, &cur_iden)) { - goto find_iden; - } - } - } - else if ((rlc > TWO_PULSE_LEN_LOW) && - (rlc < TWO_PULSE_LEN_HIGH)) { - if (bit & BIT_PULSE_MASK) { - /* "01" => 0 */ - cur_decode_status = ST_DECODE_ONE; - if (!w83667hg_check_identification(0, identification, &cur_iden)) { - goto find_iden; - } - } else { - /* error */ - cur_decode_status = ST_DECODE_ZERO; - if (!w83667hg_check_identification(0, identification, &cur_iden)) { - goto find_iden; - } - } - } - break; - case ST_DECODE_ONE: - if ((rlc > ONE_PULSE_LEN_LOW) && - (rlc < ONE_PULSE_LEN_HIGH)) { - if (bit & BIT_PULSE_MASK) { - /* "11" => error */ - cur_decode_status = ST_DECODE_NEW; - if (!w83667hg_check_identification(0, identification, &cur_iden)) { - goto find_iden; - } - } else { - /* "10" => 1 */ - cur_decode_status = ST_DECODE_NEW; - if (!w83667hg_check_identification(1, identification, &cur_iden)) { - goto find_iden; - } - } - } - else if (rlc > TWO_PULSE_LEN_LOW) { - if (bit & BIT_PULSE_MASK) { - /* "11" => error */ - cur_decode_status = ST_DECODE_ONE; - if (!w83667hg_check_identification(0, identification, &cur_iden)) { - goto find_iden; - } - } else { - /* "10" => 1 */ - cur_decode_status = ST_DECODE_ZERO; - if (!w83667hg_check_identification(1, identification, &cur_iden)) { - goto find_iden; - } - } - } - break; - }// switch - bit = buf & BIT_PULSE_MASK; - rlc = buf & BIT_LEN; - } - } - - if (i >= ir->buf_count) { -#ifdef ALLOW_DEBUG_DECODE - printk("%s jump iden error\n", DRVNAME); - printk("current buf num: %d\n", i); - printk("current pulse length: %d\n", rlc); - printk("total cir signal:\n"); - for (i = 0; i < ir->buf_count; i ++) { - printk("0x%x ", ir->buf[i]); - if (i % 6 == 5) { - printk("\n"); - } - } -#endif - return (-1); - } - - find_iden: -#ifdef ALLOW_DEBUG_DECODE - printk("current buf num after iden: %d\n", i); - printk("current pulse length: %d\n", rlc); -#endif - /* try fix problem 1 */ - if ((rlc & BIT_LEN) >= TWO_PULSE_LEN_LOW) { -#ifdef ALLOW_DEBUG_DECODE - printk("%s fix problem 1 in jump iden\n", DRVNAME); - printk("cur pulse len: %d\n", ir->buf[i] & BIT_LEN); -#endif - *buf_num = i + 1; - *out_bit = ir->buf[i] & BIT_PULSE_MASK; - if (*out_bit) { - *decode_status = ST_DECODE_ZERO; - } else { - *decode_status = ST_DECODE_ONE; - } - - return 0; - } - - /* now find identification successful! */ - { - *buf_num = i; - i --; - *out_bit = ir->buf[i] & BIT_PULSE_MASK; - if (bit) { - *decode_status = ST_DECODE_ONE; - } else { - *decode_status = ST_DECODE_ZERO; - } - } -#ifdef ALLOW_DEBUG_DECODE - printk("total cir signal:\n"); - for (i = 0; i < ir->buf_count; i ++) { - printk("0x%x ", ir->buf[i]); - if (i % 7 == 6) { - printk("\n"); - } - } - printk("\n"); -#endif - - return 0; -} - -static void w83667hg_submit_key(struct irctl *ir) -{ - unsigned int rlc = 0, buf_num = 0, i; - /* current usb keyboard key code setting, usb_kbd_keycode[keycode] */ - unsigned int input_code; - u8 bit, buf; - /* keycode and shiftmask parts in mce keyboard protocol*/ - u8 keycode = 0, shiftmask = 0; - u8 decode_status; - u8 frame_num, set_frame; - - /* 1) jump head */ - if (w83667hg_jump_head(ir, &buf_num)) { -#ifdef ALLOW_DEBUG_DECODE - printk("%s: decode key jump head error\n", DRVNAME); -#endif - return; - } -#ifdef ALLOW_DEBUG_DECODE - printk("%s buf_num after jump head: %d\n", DRVNAME, buf_num); -#endif - - /* 2) jump identification */ - if (w83667hg_jump_identification(ir, KEY_IDENTIFICATION, &buf_num, &bit, &decode_status)) { -#ifdef ALLOW_DEBUG_DECODE - printk("%s: decode key jump identification error\n", DRVNAME); -#endif - return; - } - -#ifdef ALLOW_DEBUG_DECODE - printk("%s jump iden success\n\n", DRVNAME); - printk("%s buf_num after jump iden: %d\n", DRVNAME, buf_num); - printk("decode status: 0x%x, bit: 0x%x\n", decode_status, bit); -#endif - - /* 3) jump "unknown", "C" and "CodeSet" parts in mce keyboard signal */ - if (w83667hg_jump_frame(ir, KEY_KEYCODE_FRAME_AFTER_I_START, &buf_num, &bit, &decode_status)) { -#ifdef ALLOW_DEBUG_DECODE - printk("%s: decode key jump pulse error\n", DRVNAME); -#endif - return; - } - -#ifdef ALLOW_DEBUG_DECODE - printk("%s buf_num after jump pulse: %d\n", DRVNAME, buf_num); - printk("decode status: 0x%x, bit: 0x%x\n", decode_status, bit); - frame_num = buf_num; - for (; frame_num < ir->buf_count; frame_num ++) { - printk("0x%x\t", ir->buf[frame_num]); - if (frame_num % 7 == 6) { - printk("\n"); - } - } - printk("\n"); -#endif -#ifdef ALLOW_DEBUG_DECODE - printk("%s: decode status before check key: %x\n", DRVNAME, decode_status); -#endif - - - /* 4) deocde "KeyCode" and "ShiftMask" parts in mce key signal */ - frame_num = 1, set_frame = 1; - for (; frame_num < KEY_FRAME_AFTER_JUMP + 2; buf_num ++) { - if (bit != (ir->buf[buf_num] & BIT_PULSE_MASK)) { - // decode - if (rlc > PULSE_SILENT_LEN_LOW) { -#ifdef ALLOW_DEBUG_DECODE - printk("%s error: cir signal end before received all key pulses\n", DRVNAME); - printk("bit: %d ", bit); - printk("rlc: %d\n", rlc); - printk("current pulse number: %d\n", frame_num); -#endif - if (decode_status == ST_DECODE_ONE) { - /* must set the last one */ - w83667hg_set_key(&set_frame, 1, &keycode, &shiftmask); - } - break; - } - switch (decode_status) { - case ST_DECODE_NEW: - if ((rlc > ONE_PULSE_LEN_LOW) && - (rlc < ONE_PULSE_LEN_HIGH)) { - if (bit & BIT_PULSE_MASK) { - decode_status = ST_DECODE_ONE; - } else { - decode_status = ST_DECODE_ZERO; - } - } - else if ((rlc > TWO_PULSE_LEN_LOW) && - (rlc < TWO_PULSE_LEN_HIGH)) { - /* error occur, just ignore */ - decode_status = ST_DECODE_NEW; - w83667hg_set_key(&set_frame, 0, &keycode, &shiftmask); - frame_num += 1; - } -#ifdef ALLOW_DEBUG_DECODE - printk("%s cur state: %x\n", DRVNAME, decode_status); -#endif - break; - case ST_DECODE_ZERO: - if ((rlc > ONE_PULSE_LEN_LOW) && - (rlc < ONE_PULSE_LEN_HIGH)) { - if (bit & BIT_PULSE_MASK) { - /* "01" => 0 */ - decode_status = ST_DECODE_NEW; - w83667hg_set_key(&set_frame, 0, &keycode, &shiftmask); - frame_num += 1; - } else { - /* error */ - decode_status = ST_DECODE_NEW; - w83667hg_set_key(&set_frame, 0, &keycode, &shiftmask); - } - } - else if ((rlc > TWO_PULSE_LEN_LOW) && - (rlc < TWO_PULSE_LEN_HIGH)) { - if (bit & BIT_PULSE_MASK) { - /* "01" => 0 */ - decode_status = ST_DECODE_ONE; - w83667hg_set_key(&set_frame, 0, &keycode, &shiftmask); - frame_num += 1; - } else { - /* error */ - decode_status = ST_DECODE_ZERO; - w83667hg_set_key(&set_frame, 0, &keycode, &shiftmask); - } - } -#ifdef ALLOW_DEBUG_DECODE - printk("%s cur state: %x\n", DRVNAME, decode_status); -#endif - break; - case ST_DECODE_ONE: - if ((rlc > ONE_PULSE_LEN_LOW) && - (rlc < ONE_PULSE_LEN_HIGH)) { - if (bit & BIT_PULSE_MASK) { - /* "11" => error */ - decode_status = ST_DECODE_NEW; - w83667hg_set_key(&set_frame, 0, &keycode, &shiftmask); - } else { - /* "10" => 1 */ - decode_status = ST_DECODE_NEW; - w83667hg_set_key(&set_frame, 1, &keycode, &shiftmask); - frame_num += 1; - } - } - else if (rlc > TWO_PULSE_LEN_LOW) { - if (bit & BIT_PULSE_MASK) { - /* "11" => error */ - decode_status = ST_DECODE_ONE; - w83667hg_set_key(&set_frame, 0, &keycode, &shiftmask); - } else { - /* "10" => 1 */ - decode_status = ST_DECODE_ZERO; - w83667hg_set_key(&set_frame, 1, &keycode, &shiftmask); - frame_num += 1; - } - } -#ifdef ALLOW_DEBUG_DECODE - printk("%s cur state %x\n", DRVNAME, decode_status); -#endif - break; - }// switch - bit = ir->buf[buf_num] & BIT_PULSE_MASK; - rlc = ir->buf[buf_num] & BIT_LEN; -#ifdef ALLOW_DEBUG_DECODE - printk("%s: decode keyboard buf: 0x%x\n", DRVNAME, ir->buf[buf_num]); -#endif - - } else { - // continue last pulse - rlc += ir->buf[buf_num] & BIT_LEN; - } - - } // for - -#ifdef ALLOW_DEBUG_DECODE - printk("%s: after decode keyboard:\n", DRVNAME); - printk("keycode: 0x%x ", keycode); - printk("shiftmask: 0x%x\n\n", shiftmask); -#endif - - /* 5) submit keycode to input */ - - if (keycode != ir->pressed_keycode) { - if (ir->pressed_keycode) { - input_code = (unsigned int)usb_kbd_keycode[ir->pressed_keycode]; - input_report_key(ir->input_dev, input_code, 0); - } - ir->pressed_keycode = keycode; - if (keycode) { - input_code = (unsigned int)usb_kbd_keycode[keycode]; - input_report_key(ir->input_dev, input_code, 1); - } - } - - /* 6) submit shiftmask to input */ - - if (shiftmask != ir->pressed_shiftmask) { - for (i = 0; i < 7; i ++) { - buf = 1<pressed_shiftmask) && (!(buf & shiftmask))) { - input_code = (unsigned int)usb_kbd_keycode[0xE0 + i]; - input_report_key(ir->input_dev, input_code, 0); - } - else if (!(buf & ir->pressed_shiftmask) && (buf & shiftmask)) { - input_code = (unsigned int)usb_kbd_keycode[0xE0 + i]; - input_report_key(ir->input_dev, input_code, 1); - } - } // for - ir->pressed_shiftmask = shiftmask; - } - -} - -static void w83667hg_set_mouse(u8 *set_frame, u8 val, u8 *deltay, u8 *deltax, u8 *clickrl) -{ -#ifdef ALLOW_DEBUG_DECODE - printk("%s set mouse val:%d\n", DRVNAME, val); -#endif - if (*set_frame <= MOUSE_SUBMIT_DELTAY_FRAME_NUM + 1) { - *deltay <<= 1; - *deltay |= val; -#ifdef ALLOW_DEBUG_DECODE - printk("%s set mouse delta y:0x%x\n", DRVNAME, *deltay); -#endif - } else if (*set_frame <= MOUSE_SUBMIT_DELTAX_FRAME_NUM) { - *deltax <<= 1; - *deltax |= val; -#ifdef ALLOW_DEBUG_DECODE - printk("%s set mouse delta x:0x%x\n", DRVNAME, *deltax); -#endif - } else if (*set_frame <= MOUSE_SUBMIT_L_FRAME_NUM) { - /* move right key, then set left key */ - *clickrl <<= 1; - *clickrl |= val; -#ifdef ALLOW_DEBUG_DECODE - printk("%s set mouse l:0x%x\n", DRVNAME, *clickrl); - printk("set pulse: %d\n", *set_frame); -#endif - } - (*set_frame) ++; -} - -static void w83667hg_submit_mouse(struct irctl *ir) -{ - unsigned int rlc = 0, buf_num = 0; - u8 bit; - /* deltax, deltay and clickrl parts in mce mouse protocol*/ - u8 deltax = 0, deltay = 0, clickrl = 0; - signed char x, y; - u8 decode_status; - u8 frame_num, set_frame; - - /* 1) jump head */ - if (w83667hg_jump_head(ir, &buf_num)) { -#ifdef ALLOW_DEBUG_DECODE - printk("%s: decode mouse jump head error\n", DRVNAME); -#endif - return; - } - - /* 2) jump identification */ - if (w83667hg_jump_identification(ir, MOUSE_IDENTIFICATION, &buf_num, &bit, &decode_status)) { -#ifdef ALLOW_DEBUG_DECODE - printk("%s: decode mouse jump identification error\n", DRVNAME); -#endif - return; - } -#ifdef ALLOW_DEBUG_DECODE - printk("%s: after iden mouse:\n", DRVNAME); - printk("decode status: 0x%x, bit: 0x%x\n", decode_status, bit); - frame_num = buf_num; - for (; frame_num < ir->buf_count; frame_num ++) { - printk("0x%x ", ir->buf[frame_num]); - if (frame_num % 7 == 6) { - printk("\n"); - } - } - printk("\n"); -#endif - - /* 3) jump "unknown" part in mce mouse signal */ - if (w83667hg_jump_frame(ir, MOUSE_DELTAY_PULSE_AFTER_I_START, &buf_num, &bit, &decode_status)) { -#ifdef ALLOW_DEBUG_DECODE - printk("%s: decode mouse jump pulse error\n", DRVNAME); -#endif - return; - } -#ifdef ALLOW_DEBUG_DECODE - printk("%s: after jump pulse buf num: %d\n", DRVNAME, buf_num); - printk("decode status: 0x%x, bit: 0x%x\n", decode_status, bit); - frame_num = buf_num; - for (; frame_num < ir->buf_count; frame_num ++) { - printk("0x%x ", ir->buf[frame_num]); - if (frame_num % 7 == 6) { - printk("\n"); - } - } - printk("\n"); -#endif - - /* 4) deocde "deltay", "deltax", "r" and "l" parts in mce mouse signal */ - frame_num = 1, set_frame = 1; - for (; frame_num < MOUSE_CHECKSUM_FRAME_AFTER_JUMP + 1; buf_num ++) { -#ifdef ALLOW_DEBUG_DECODE - printk("%s: cur buf: 0x%x, pulse num: %d\n", DRVNAME, ir->buf[buf_num], frame_num); - printk("decode status: 0x%x\n", decode_status); -#endif - if (bit != (ir->buf[buf_num] & BIT_PULSE_MASK)) { - // decode - if (rlc > PULSE_SILENT_LEN_LOW) { -#ifdef ALLOW_DEBUG_DECODE - printk("%s error: cir signal end before received all mouse pulses\n", DRVNAME); - printk("bit: %d ", bit); - printk("rlc: %d\n", rlc); -#endif - break; - } - switch (decode_status) { - case ST_DECODE_NEW: - if ((rlc > ONE_PULSE_LEN_LOW) && - (rlc < ONE_PULSE_LEN_HIGH)) { - if (bit & BIT_PULSE_MASK) { - decode_status = ST_DECODE_ONE; - } else { - decode_status = ST_DECODE_ZERO; - } - } else - if ((rlc > TWO_PULSE_LEN_LOW) && - (rlc < TWO_PULSE_LEN_HIGH)) { - /* error occur, just ignore */ - decode_status = ST_DECODE_NEW; - w83667hg_set_mouse(&set_frame, 0, &deltay, &deltax, &clickrl); - frame_num += 1; - } - break; - case ST_DECODE_ZERO: - if ((rlc > ONE_PULSE_LEN_LOW) && - (rlc < ONE_PULSE_LEN_HIGH)) { - if (bit & BIT_PULSE_MASK) { - /* "01" => 0 */ - decode_status = ST_DECODE_NEW; - w83667hg_set_mouse(&set_frame, 0, &deltay, &deltax, &clickrl); - frame_num += 1; - } else { - /* error */ - decode_status = ST_DECODE_NEW; - w83667hg_set_mouse(&set_frame, 0, &deltay, &deltax, &clickrl); - } - } - else if ((rlc > TWO_PULSE_LEN_LOW) && - (rlc < TWO_PULSE_LEN_HIGH)) { - if (bit & BIT_PULSE_MASK) { - /* "01" => 0 */ - decode_status = ST_DECODE_ONE; - w83667hg_set_mouse(&set_frame, 0, &deltay, &deltax, &clickrl); - frame_num += 1; - } else { - /* error */ - decode_status = ST_DECODE_ZERO; - w83667hg_set_mouse(&set_frame, 0, &deltay, &deltax, &clickrl); - } - } - break; - case ST_DECODE_ONE: - if ((rlc > ONE_PULSE_LEN_LOW) && - (rlc < ONE_PULSE_LEN_HIGH)) { - if (bit & BIT_PULSE_MASK) { - /* "11" => error */ - decode_status = ST_DECODE_NEW; - w83667hg_set_mouse(&set_frame, 0, &deltay, &deltax, &clickrl); - } else { - /* "10" => 1 */ - decode_status = ST_DECODE_NEW; - w83667hg_set_mouse(&set_frame, 1, &deltay, &deltax, &clickrl); - frame_num += 1; - } - } -/* - else if ((rlc > TWO_PULSE_LEN_LOW) && - (rlc < TWO_PULSE_LEN_HIGH)) -*/ - else if (rlc > TWO_PULSE_LEN_LOW) { - if (bit & BIT_PULSE_MASK) { - /* "11" => error */ - decode_status = ST_DECODE_ONE; - w83667hg_set_mouse(&set_frame, 0, &deltay, &deltax, &clickrl); - frame_num += 1; - } else { - /* "10" => 1 */ - decode_status = ST_DECODE_ZERO; - w83667hg_set_mouse(&set_frame, 1, &deltay, &deltax, &clickrl); - frame_num += 1; - } - } - break; - }// switch - bit = ir->buf[buf_num] & BIT_PULSE_MASK; - rlc = ir->buf[buf_num] & BIT_LEN; - } else { - // continue last pulse - rlc += ir->buf[buf_num] & BIT_LEN; - } - - } // for - -#ifdef ALLOW_DEBUG_DECODE - printk("%s: after decode mouse:\n", DRVNAME); - frame_num = buf_num; - for (; frame_num < ir->buf_count; frame_num ++) { - printk("0x%x ", ir->buf[frame_num]); - if (frame_num % 7 == 6) { - printk("\n"); - } - } - printk("\n"); -#endif - - /* fix deltax lost problem */ - if (deltax) { - deltax <<= 1; - deltax |= 1; - } - -#ifdef ALLOW_DEBUG_DECODE - printk("%s: after decode mouse:\n", DRVNAME); - printk("deltay: 0x%x ", deltay); - printk("deltax: 0x%x ", deltax); - printk("click rl: 0x%x \n\n", clickrl); -#endif - if (deltay & 0x40) { - y = -((~deltay & 0x7f) + 1); - } else { - y = deltay; - } - if (deltax & 0x40) { - x = -((~deltax & 0x7f) + 1); - } else { - x = deltax; - } - - /* 5) send to input */ - -#ifdef ALLOW_DEBUG_DECODE - printk("%s: after decode mouse and rebuild:\n", DRVNAME); - printk("y: %d ", y); - printk("x: %d ", x); - printk("click rl: 0x%x \n\n", clickrl); -#endif - - input_report_rel(ir->input_dev, REL_X, x); - input_report_rel(ir->input_dev, REL_Y, y); - - input_report_key(ir->input_dev, BTN_LEFT, clickrl & 1); - input_report_key(ir->input_dev, BTN_RIGHT, (clickrl >> 1) & 1); -} - -static void w83667hg_send_packet_to_lirc_1(struct irctl *ir, lirc_t *val) -{ -#ifdef ALLOW_DEBUG_DECODE - printk("%s: send data to lirc : 0x%x\n", DRVNAME, (*val)); -#endif -// lirc_buffer_write_1(ir->lirc_plugin->rbuf, (char *)val); - lirc_buffer_write(ir->lirc_plugin->rbuf, (char *)val); - wake_up(&ir->lirc_plugin->rbuf->wait_poll); -} - -static void w83667hg_submit_controller(struct irctl *ir) -{ - unsigned int buf_num; - u8 bit; - - /* fix controller head not sync problem */ - /* lirc doesn't response DK MCE controller signal until press several times, not find same problem on M$ MCE controller keyboard */ - if (ir->ctrl_fix_head) { - ir->lircdata = 50000; - w83667hg_send_packet_to_lirc_1(ir, &ir->lircdata); - ir->ctrl_fix_head = 0; - } - - buf_num = 0; - bit = BIT_PULSE_MASK; - ir->lircdata = 0; - for (; buf_num < ir->buf_count; buf_num ++) { - if (bit == (ir->buf[buf_num] & BIT_PULSE_MASK)) { - ir->lircdata += (ir->buf[buf_num] & BIT_LEN) * MCE_TIME_UNIT; - } else { - if (bit) { - ir->lircdata |= PULSE_BIT; - } - w83667hg_send_packet_to_lirc_1(ir, &ir->lircdata); - bit = ir->buf[buf_num] & BIT_PULSE_MASK; - ir->lircdata = (ir->buf[buf_num] & BIT_LEN) * MCE_TIME_UNIT; - } - } - /* for final silent pulse */ - ir->lircdata = 50000; - w83667hg_send_packet_to_lirc_1(ir, &ir->lircdata); - -#ifdef ALLOW_DEBUG_DECODE - printk("\n"); -#endif -} - -static irqreturn_t w83667hg_interrupt_handler(int irq, void *dev) -{ - u8 tmp; - struct irctl *ir = (struct irctl *)dev; - struct ir_send_t *ir_send = &w83667hg_ir_send; - - - //Because interrupt is shared, check IREN first. - tmp = cir_read(CIR_IREN); - if (!tmp) { - return IRQ_RETVAL(IRQ_NONE); - } - - - tmp = cir_read(CIR_IRSTS); - cir_update(0xff, CIR_IRSTS); - if (!tmp) { - return IRQ_NONE; - } - if (tmp & CIR_IRSTS_RDR) { -#ifdef ALLOW_DEBUG_INTERRUPT - printk("get CIR_IRSTS_RDR\n"); -#endif -#ifdef ALLOW_DEBUG_PRINT_PULSE - debug_print_pulse(); -#else - spin_lock(&ir_send->lock); - if (ir_send->send_state == ST_SEND_NONE) { - spin_unlock(&ir_send->lock); - if (ir->study_state & ST_STUDY_START) { - w83667hg_study_recv(&w83667hg_ir_recv, &w83667hg_irctl); - } else { - w83667hg_recv(&w83667hg_ir_recv, &w83667hg_irctl); - } - } else { - spin_unlock(&ir_send->lock); - } -#endif - } - if (tmp & CIR_IRSTS_RTR) { -#ifdef ALLOW_DEBUG_INTERRUPT - printk("get CIR_IRSTS_RTR\n"); -#endif - } - if (tmp & CIR_IRSTS_PE) { -#ifdef ALLOW_DEBUG_INTERRUPT - printk("get CIR_IRSTS_PE\n"); -#endif -#ifdef ALLOW_DEBUG_PRINT_PULSE - printk("\n now get interrupt PE\n\n"); - debug_print_pulse(); -#else - if (ir->study_state == ST_STUDY_NONE) { - w83667hg_clean_data(&w83667hg_ir_recv, &w83667hg_irctl); - } -#endif - } - if (tmp & CIR_IRSTS_RFO) { -#ifdef ALLOW_DEBUG_INTERRUPT - printk("get CIR_IRSTS_RFO\n"); -#endif - } - if (tmp & CIR_IRSTS_TE) { -#ifdef ALLOW_DEBUG_INTERRUPT - printk("get CIR_IRSTS_TE\n"); -#endif - } - if (tmp & CIR_IRSTS_TTR) { -#ifdef ALLOW_DEBUG_INTERRUPT - printk("get CIR_IRSTS_TTR\n"); -#endif - - spin_lock(&ir_send->lock); - if (ir_send->cur_buf_num < ir_send->buf_count) { - cir_update(ir_send->buf[ir_send->cur_buf_num++], CIR_STXFIFO); - } else { - cir_update(cir_read(CIR_IREN) & (~CIR_IREN_TTR), CIR_IREN); - } - spin_unlock(&ir_send->lock); - - } - if (tmp & CIR_IRSTS_TFU) { -#ifdef ALLOW_DEBUG_INTERRUPT - printk("get CIR_IRSTS_TFU\n"); -#endif - spin_lock(&ir_send->lock); - if (ST_SEND_REPLY == ir_send->send_state) { - ir_send->send_state = ST_SEND_REQUEST; - wake_up(&ir_send->queue); - } - spin_unlock(&ir_send->lock); - } - if (tmp & CIR_IRSTS_GH) { -#ifdef ALLOW_DEBUG_INTERRUPT - printk("get CIR_IRSTS_GH\n"); -#endif - } - - return IRQ_HANDLED; -} - -static irqreturn_t w83667hg_wake_interrupt_handler(int irq, void *dev) -{ - u8 tmp; - struct ir_recv_t *ir_recv = (struct ir_recv_t *)dev; - - - //Because interrupt is shared, check IREN first. - tmp = cir_wake_read(CIR_WAKE_IREN); - if (!tmp) { - return IRQ_RETVAL(IRQ_NONE); - } - - tmp = cir_wake_read(CIR_WAKE_IRSTS); - if (!tmp) { - return IRQ_NONE; - } - cir_wake_update(0xff, CIR_WAKE_IRSTS); - - if (tmp & CIR_WAKE_IRSTS_RDR) { -#ifdef ALLOW_DEBUG_INTERRUPT - printk("get CIR_WAKE_IRSTS_RDR\n"); -#endif -#ifdef ALLOW_DEBUG_PRINT_PULSE - debug_print_wake_pulse(); -#endif - } - if (tmp & CIR_WAKE_IRSTS_RTR) { -#ifdef ALLOW_DEBUG_INTERRUPT - printk("get CIR_WAKE_IRSTS_RTR\n"); -#endif - } - if ((tmp & CIR_WAKE_IRSTS_PE) && - (ST_WAKE_START == ir_recv->wake_state)) { -#ifdef ALLOW_DEBUG_INTERRUPT - printk("get CIR_WAKE_IRSTS_PE\n"); -#endif -#ifdef ALLOW_DEBUG_PRINT_PULSE - printk("\n now get interrupt PE\n\n"); - debug_print_wake_pulse(); -#else - while ((cir_wake_read(CIR_WAKE_RD_FIFO_ONLY_IDX)) != 0) { -#ifdef ALLOW_DEBUG_WAKE - printk("%s setting wake up key: 0x%x\n", DRVNAME, cir_wake_read(CIR_WAKE_RD_FIFO_ONLY)); -#else - cir_wake_read(CIR_WAKE_RD_FIFO_ONLY); -#endif - } - - cir_wake_update(0, CIR_WAKE_IREN); - spin_lock(&ir_recv->lock); - ir_recv->wake_state = ST_WAKE_FINISH; - wake_up(&ir_recv->queue); - spin_unlock(&ir_recv->lock); -#endif - } - if (tmp & CIR_WAKE_IRSTS_RFO) { -#ifdef ALLOW_DEBUG_INTERRUPT - printk("get CIR_WAKE_IRSTS_RFO\n"); -#endif - } - if (tmp & CIR_WAKE_IRSTS_GH) { -#ifdef ALLOW_DEBUG_INTERRUPT - printk("get CIR_WAKE_IRSTS_GH\n"); -#endif - } - - return IRQ_HANDLED; -} - -/* 4. */ -/* init 667 cir dev, req_region, req_irq */ -static int w83667hg_cir_probe(void) -{ - int err = 0; - - if(!request_region(cir_address, CIR_IOREG_LENGTH, DRVNAME)) { - err = -EBUSY; -#ifdef IR_667_DEBUG - printk("%s request 667 cir io port error! \n", DRVNAME); -#endif - goto exit; - } - - cir_update(CIR_IRCON_RXINV | CIR_IRCON_SAMPLE_PERIOD_SEL, CIR_IRCON); - cir_update(0xFF, CIR_IRSTS); - cir_update(CIR_RX_LIMIT_COUNT >> 8, CIR_SLCH); - cir_update(CIR_RX_LIMIT_COUNT & 0xff, CIR_SLCL); - cir_update(CIR_FIFOCON_TXFIFOCLR | CIR_FIFOCON_TX_TRIGGER_LEV_24 | CIR_FIFOCON_RXFIFOCLR, CIR_FIFOCON); - cir_update(CIR_IRCON_RECV | CIR_IRCON_RXINV | CIR_IRCON_SAMPLE_PERIOD_SEL, CIR_IRCON); - cir_update(CIR_IRCON_TXEN | CIR_IRCON_RXEN | CIR_IRCON_RXINV | CIR_IRCON_SAMPLE_PERIOD_SEL, CIR_IRCON); - - if(0 != request_irq(CIR_IRQ_NUM, w83667hg_interrupt_handler, IRQF_SHARED, - DRVNAME, &w83667hg_irctl)) { - err = -EINTR; -#ifdef IR_667_DEBUG - printk("%s : request cir irq error\n", DRVNAME); -#endif - goto rel_irq_exit; - } - /* open interrupt */ - cir_update(CIR_IREN_RDR | CIR_IREN_PE, CIR_IREN); - - if(!request_region(cir_wake_address, CIR_IOREG_LENGTH, DRVNAME)) { - err = -EBUSY; -#ifdef IR_667_DEBUG - printk("%s request 667 cir wake io port error! \n", DRVNAME); -#endif - goto rel_wake_exit; - } - - cir_wake_update(0xff, CIR_WAKE_IRSTS); - /* Modify it as more safe values: CIR_WAKE_FIFO_CMP_DEEP reg:0x41, - CIR_WAKE_FIFO_CMP_TOL reg: 0x05. 20091224 - */ - cir_wake_update(0x41, CIR_WAKE_FIFO_CMP_DEEP); /* 0x41 = 65 */ - cir_wake_update(0x05, CIR_WAKE_FIFO_CMP_TOL); - cir_wake_update(CIR_RX_LIMIT_COUNT >> 8, CIR_WAKE_SLCH); - cir_wake_update(CIR_RX_LIMIT_COUNT & 0xff, CIR_WAKE_SLCL); - cir_wake_update(0xff, CIR_WAKE_FIFOCON); - cir_wake_update(0, CIR_WAKE_FIFOCON); - cir_wake_update(CIR_WAKE_IRCON_MODE0 | CIR_WAKE_IRCON_RXEN | CIR_WAKE_IRCON_R | CIR_WAKE_IRCON_RXINV | CIR_WAKE_IRCON_SAMPLE_PERIOD_SEL, CIR_WAKE_IRCON); - - /* cir wake has irq_handler, open interrupt after received ioctl IR_IOLEARNWAKE */ - if(0 != request_irq(CIR_WAKE_IRQ_NUM, w83667hg_wake_interrupt_handler, IRQF_SHARED, - DRVNAME, &w83667hg_ir_recv)) { - err = -EINTR; -#ifdef IR_667_DEBUG - printk("%s : request cir wake irq error\n", DRVNAME); -#endif - goto rel_wake_irq_exit; - } - -#ifdef IR_667_DEBUG - printk("%s : init cir success\n", DRVNAME); -#endif - goto exit; - - /* error exit */ - rel_wake_irq_exit: - release_region(cir_wake_address, CIR_IOREG_LENGTH); - rel_wake_exit: - cir_update(0, CIR_IREN); - free_irq(CIR_IRQ_NUM, &w83667hg_irctl); - rel_irq_exit: - release_region(cir_address, CIR_IOREG_LENGTH); - - /* final exit */ - exit: - return err; -} - -static void w83667hg_cir_remove(void) -{ - /* Don't clean CIR_WAKE_IRCON. When wake-up at power-on, it needs the function. 20091224 - cir_wake_update(0, CIR_WAKE_IRCON); - */ - free_irq(CIR_WAKE_IRQ_NUM, &w83667hg_ir_recv); - release_region(cir_wake_address, CIR_IOREG_LENGTH); - cir_update(0, CIR_IRCON); - free_irq(CIR_IRQ_NUM, &w83667hg_irctl); - release_region(cir_address, CIR_IOREG_LENGTH); -} - -static int lirc_wb667_init(void) -{ - int err = 0; - - /* 1. init cr */ - if (w83667hg_cr_init()) { - printk("%s: Unable to init device.\n", DRVNAME); - err = -ENODEV; - goto out; - } - - /* 2. init input */ - w83667hg_input_dev = w83667hg_input_init(); - if (!w83667hg_input_dev) { - printk("%s: Unable to register input device.\n", DRVNAME); - err = -ENODEV; - goto out_input; - } - w83667hg_irctl.input_dev = w83667hg_input_dev; - - /* 3. init lirc buffer, register, irctl */ - w83667hg_ir_recv_init(&w83667hg_ir_recv); - w83667hg_ir_send_init(&w83667hg_ir_send); - err = w83667hg_irctl_init(&w83667hg_irctl); - if (err) { - printk("%s: Unable to register lirc.\n", DRVNAME); - goto out_irctl; - } - - /* 4. init 667 cir dev, req_region, req_irq */ - err = w83667hg_cir_probe(); - if (err) { - printk("%s: Unable to probe cir device.\n", DRVNAME); - goto out_cir_probe; - } - - goto out; - - /* error exit */ - out_cir_probe: - w83667hg_irctl_uninit(&w83667hg_irctl); - w83667hg_irctl.input_dev = NULL; - out_irctl: - w83667hg_input_uninit(w83667hg_input_dev); - out_input: - w83667hg_cr_uninit(); - - /* final exit */ - out: - return err; -} - -void lirc_wb667_uninit(void) -{ - w83667hg_cir_remove(); - w83667hg_irctl_uninit(&w83667hg_irctl); - w83667hg_irctl.input_dev = NULL; - w83667hg_input_uninit(w83667hg_input_dev); - w83667hg_cr_uninit(); - -} - -static struct platform_driver lirc_wb667_driver = { - .probe = lirc_wb667_probe, - .remove = __devexit_p(lirc_wb667_remove), - .suspend = lirc_wb667_suspend, - .resume = lirc_wb667_resume, - .driver = { - .name = PLATNAME, - .owner = THIS_MODULE, - }, -}; - - -static int __devinit lirc_wb667_probe(struct platform_device *dev) -{ - return 0; -} - -static int __devexit lirc_wb667_remove(struct platform_device *dev) -{ - return 0; -} - -static int lirc_wb667_suspend(struct platform_device *dev, pm_message_t state) -{ - struct irctl *ir = &w83667hg_irctl; - struct ir_recv_t *ir_recv = &w83667hg_ir_recv; - struct ir_send_t *ir_send = &w83667hg_ir_send; - -#ifdef IR_667_DEBUG - printk("%s receive suspend\n", DRVNAME); -#endif - - /* 1. */ - spin_lock(&ir->lock); - ir->study_state = ST_STUDY_NONE; - spin_unlock(&ir->lock); - - spin_lock(&ir_recv->lock); - ir_recv->wake_state = ST_WAKE_NONE; - spin_unlock(&ir_recv->lock); - - spin_lock(&ir_send->lock); - ir_send->send_state = ST_SEND_NONE; - spin_unlock(&ir_send->lock); - - /* 2. */ - cir_update(0, CIR_IREN); - cir_wake_update(0, CIR_WAKE_IREN); - - /* 3. */ - cr_enter_ext(); - cr_select_log_dev(CIR_LOG_DEV); - cr_update(DEACTIVE_LOG_DEV, 0x30); - - /* Don't close CIR Wake. When wake-up at power-on, it needs the function. 20091224 - cr_select_log_dev(CIR_WAKE_LOG_DEV); - cr_update(DEACTIVE_LOG_DEV, 0x30); - */ - cr_exit_ext(); - - /* 4. */ - lirc_wb667_uninit(); - - return 0; -} - -static int lirc_wb667_resume(struct platform_device *dev) -{ - int ret; - -#ifdef IR_667_DEBUG - printk("%s receive suspend\n", DRVNAME); -#endif - - /* resume */ - ret = lirc_wb667_init(); - - return ret; -} - - -#ifdef CONFIG_PNP - -/* CIR and CIR WAKE */ - -static struct pnp_driver lirc_wb667_pnp_driver = { - .name = PLATNAME, - .id_table = pnp_dev_table, - .probe = lirc_wb667_pnp_probe, - .remove = __devexit_p(lirc_wb667_pnp_remove), - .suspend = lirc_wb667_pnp_suspend, - .resume = lirc_wb667_pnp_resume, -}; - -static int __devinit lirc_wb667_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id) -{ - /* CIR */ - - if (!pnp_port_valid(dev, 0)) - return -ENODEV; - CIR_BASE = (unsigned int)pnp_port_start(dev, 0); - CIR_IRQ_NUM = (unsigned short)pnp_irq(dev, 0); - - - /* CIR WAKE*/ - - if (!pnp_port_valid(dev, 1)) - return -ENODEV; - CIR_WAKE_BASE = (unsigned int)pnp_port_start(dev, 1); - CIR_WAKE_IRQ_NUM = (unsigned short)pnp_irq(dev, 0); // share the same irq with CIR device. - - return 0; -} - -static void __devexit lirc_wb667_pnp_remove(struct pnp_dev *dev) -{ -} - - - -static int lirc_wb667_pnp_suspend(struct pnp_dev *dev, pm_message_t state) -{ - struct irctl *ir = &w83667hg_irctl; - struct ir_recv_t *ir_recv = &w83667hg_ir_recv; - struct ir_send_t *ir_send = &w83667hg_ir_send; - -#ifdef IR_667_DEBUG - printk("%s receive suspend\n", DRVNAME); -#endif - - /* 1. */ - spin_lock(&ir->lock); - ir->study_state = ST_STUDY_NONE; - spin_unlock(&ir->lock); - - spin_lock(&ir_recv->lock); - ir_recv->wake_state = ST_WAKE_NONE; - spin_unlock(&ir_recv->lock); - - spin_lock(&ir_send->lock); - ir_send->send_state = ST_SEND_NONE; - spin_unlock(&ir_send->lock); - - /* 2. */ - cir_update(0, CIR_IREN); - cir_wake_update(0, CIR_WAKE_IREN); - - /* 3. */ - cr_enter_ext(); - cr_select_log_dev(CIR_LOG_DEV); - cr_update(DEACTIVE_LOG_DEV, 0x30); - - /* Don't close CIR Wake. When wake-up at power-on, it needs the function. 20091224 - cr_select_log_dev(CIR_WAKE_LOG_DEV); - cr_update(DEACTIVE_LOG_DEV, 0x30); - */ - cr_exit_ext(); - - /* 4. */ - lirc_wb667_uninit(); - - return 0; -} - -static int lirc_wb667_pnp_resume(struct pnp_dev *dev) -{ - int ret; - -#ifdef IR_667_DEBUG - printk("%s receive suspend\n", DRVNAME); -#endif - - /* resume */ - ret = lirc_wb667_init(); - - return ret; -} - - - - - #if 0 - - -/* CIR */ - -static struct pnp_driver lirc_wb667_pnp_cir_driver = { - .name = PLATNAME, - .id_table = pnp_dev_cir_table, - .probe = lirc_wb667_pnp_cir_probe, - .remove = __devexit_p(lirc_wb667_pnp_cir_remove), - .suspend = lirc_wb667_pnp_cir_suspend, - .resume = lirc_wb667_pnp_cir_resume, -}; - -static int __devinit lirc_wb667_pnp_cir_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id) -{ - CIR_BASE = (unsigned int)pnp_port_start(dev, 0); - CIR_IRQ_NUM = (unsigned short)pnp_irq(dev, 0); - return 0; -} - -static void __devexit lirc_wb667_pnp_cir_remove(struct pnp_dev *dev) -{ -} - -static int lirc_wb667_pnp_cir_suspend(struct pnp_dev *dev, pm_message_t state) -{ - struct irctl *ir = &w83667hg_irctl; - struct ir_recv_t *ir_recv = &w83667hg_ir_recv; - struct ir_send_t *ir_send = &w83667hg_ir_send; - -#ifdef IR_667_DEBUG - printk("%s receive suspend\n", DRVNAME); -#endif - - /* 1. */ - spin_lock(&ir->lock); - ir->study_state = ST_STUDY_NONE; - spin_unlock(&ir->lock); - - spin_lock(&ir_recv->lock); - ir_recv->wake_state = ST_WAKE_NONE; - spin_unlock(&ir_recv->lock); - - spin_lock(&ir_send->lock); - ir_send->send_state = ST_SEND_NONE; - spin_unlock(&ir_send->lock); - - /* 2. */ - cir_update(0, CIR_IREN); - cir_wake_update(0, CIR_WAKE_IREN); - - /* 3. */ - cr_enter_ext(); - cr_select_log_dev(CIR_LOG_DEV); - cr_update(DEACTIVE_LOG_DEV, 0x30); - - cr_select_log_dev(CIR_WAKE_LOG_DEV); - cr_update(DEACTIVE_LOG_DEV, 0x30); - cr_exit_ext(); - - /* 4. */ - lirc_wb667_uninit(); - - return 0; -} - -static int lirc_wb667_pnp_cir_resume(struct pnp_dev *dev) -{ - int ret; - -#ifdef IR_667_DEBUG - printk("%s receive suspend\n", DRVNAME); -#endif - - /* resume */ - ret = lirc_wb667_init(); - - return ret; -} - - -/* CIR WAKE */ - -static struct pnp_driver lirc_wb667_pnp_cir_wake_driver = { - .name = PLATNAME_W, - .id_table = pnp_dev_cir_wake_table, - .probe = lirc_wb667_pnp_cir_wake_probe, - .remove = __devexit_p(lirc_wb667_pnp_cir_wake_remove), -}; - -static int __devinit lirc_wb667_pnp_cir_wake_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id) -{ - CIR_WAKE_BASE = (unsigned int)pnp_port_start(dev, 0); - CIR_WAKE_IRQ_NUM = (unsigned short)pnp_irq(dev, 0); - if (CIR_WAKE_IRQ_NUM > 15) { - CIR_WAKE_IRQ_NUM = CIR_IRQ_NUM; - } - return 0; -} - -static void __devexit lirc_wb667_pnp_cir_wake_remove(struct pnp_dev *dev) -{ -} - #endif - - -#endif - - -//int init_module(void) -int init_module_wb667(void) -{ - int ret; - -#ifdef CONFIG_PNP - if (!nopnp) { - - ret = pnp_register_driver(&lirc_wb667_pnp_driver); - if (ret < 0) - return ret; - - #if 0 - ret = pnp_register_driver(&lirc_wb667_pnp_cir_driver); - if (ret < 0) - return ret; - ret = pnp_register_driver(&lirc_wb667_pnp_cir_wake_driver); - if (ret < 0) - return ret; - #endif - - } -#endif /* CONFIG_PNP */ - - if (nopnp) { - lirc_wb667_dev = platform_device_alloc(PLATNAME, 0); - if (!lirc_wb667_dev) - return -ENOMEM; - ret = platform_device_add(lirc_wb667_dev); - if (ret) { - platform_device_put(lirc_wb667_dev); - return ret; - } - ret = platform_driver_register(&lirc_wb667_driver); - if (ret) { - printk("%s platform register returned %d\n", DRVNAME, ret); - platform_device_del(lirc_wb667_dev); - platform_device_put(lirc_wb667_dev); - return ret; - } - } - - ret = lirc_wb667_init(); - if (ret) { - return ret; - } - - return 0; -} - -//void cleanup_module(void) -void cleanup_module_wb667(void) -{ - struct platform_device *pdev = lirc_wb667_dev; - lirc_wb667_dev = NULL; - -#ifdef CONFIG_PNP - if (!nopnp) { - pnp_unregister_driver(&lirc_wb667_pnp_driver); - #if 0 - pnp_unregister_driver(&lirc_wb667_pnp_cir_driver); - pnp_unregister_driver(&lirc_wb667_pnp_cir_wake_driver); - #endif - } -#endif /* CONFIG_PNP */ - - if (nopnp) { - platform_driver_unregister(&lirc_wb667_driver); - platform_device_unregister(pdev); - } - - lirc_wb667_uninit(); -} - -module_init(init_module_wb667); -module_exit(cleanup_module_wb667); - - diff -Nru nct677x-dkms-1.0.1/nct677x-1.0.1/src/lirc_wb677.h nct677x-dkms-1.0.4/nct677x-1.0.1/src/lirc_wb677.h --- nct677x-dkms-1.0.1/nct677x-1.0.1/src/lirc_wb677.h 2010-03-31 15:56:50.000000000 +0000 +++ nct677x-dkms-1.0.4/nct677x-1.0.1/src/lirc_wb677.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,992 +0,0 @@ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -//#include -#include - -#include -#include - -#include -#include -#include - -#include "lirc.h" -#include "lirc_dev.h" -#include "kcompat.h" - - - - -/* allow show debug messages - * without additional debug setting, only show current IRQ number, I/O port and final decode output */ -//#define IR_667_DEBUG - -/* show debug message while decode mce keyboard and mouse signals */ -#ifdef IR_667_DEBUG -//#define ALLOW_DEBUG_DECODE -#endif - -/* show incoming interrupt signals - * may block machine, mask it if sure interrupt signal is good */ -#ifdef IR_667_DEBUG -//#define ALLOW_DEBUG_INTERRUPT -#endif - -/* show received infrared pulse and cancel decode functions, mask it in stable version - * it will stop decode MCE controller, keyboard and mouse - * mask it if want to decode incoming signals - */ -#ifdef IR_667_DEBUG -//#define ALLOW_DEBUG_PRINT_PULSE -#endif - -/* show debug message while set WAKE UP key - * it will print cir_wake buf message while setting wake up key - * mask it in stable version - */ -#ifdef IR_667_DEBUG -#define ALLOW_DEBUG_WAKE -#endif - -/* show STUDY debug messages */ -#ifdef IR_667_DEBUG -#define ALLOW_DEBUG_STUDY -#endif - -/* show ioctl debug messages */ -#ifdef IR_667_DEBUG -#define ALLOW_DEBUG_IOCTL -#endif - -/* step debug */ -#ifdef IR_667_DEBUG -#define ALLOW_DEBUG_STEP -#endif - -#ifdef ALLOW_DEBUG_STEP -#define STEP_DBG \ - do { \ - printk("w83667hg_ir step debug: %s, %d\n", __FILE__, __LINE__); \ - } while (0); -#else -#define STEP_DBG -#endif - -#ifdef ALLOW_DEBUG_PRINT_PULSE -/* print current received ir pulse - * it will output all data, clean CIR_IRSTS so make all following irq_handler ignore - */ -void debug_print_pulse(void); - -void debug_print_wake_pulse(void); -#endif - - -/* CIR settings */ - -/* total length of CIR and CIR WAKE */ -#define CIR_IOREG_LENGTH 0x0f - -/* RX limit length, 8 high bits for SLCH, 8 low bits for SLCL - * 0x7d0 = 2000 */ -#define CIR_RX_LIMIT_COUNT 0x7d0 - -/* CIR Regs */ -#define CIR_IRCON 0x00 -#define CIR_IRSTS 0x01 -#define CIR_IREN 0x02 -#define CIR_RXFCONT 0x03 -#define CIR_CP 0x04 -#define CIR_CC 0x05 -#define CIR_SLCH 0x06 -#define CIR_SLCL 0x07 -#define CIR_FIFOCON 0x08 -#define CIR_IRFIFOSTS 0x09 -#define CIR_SRXFIFO 0x0A -#define CIR_TXFCONT 0x0B -#define CIR_STXFIFO 0x0C -#define CIR_FCCH 0x0D -#define CIR_FCCL 0x0E -#define CIR_IRFSM 0x0F - -/* CIR IRCON settings */ -#define CIR_IRCON_RECV 0x80 -#define CIR_IRCON_WIREN 0x40 -#define CIR_IRCON_TXEN 0x20 -#define CIR_IRCON_RXEN 0x10 -#define CIR_IRCON_WRXINV 0x08 -#define CIR_IRCON_RXINV 0x04 - -#define CIR_IRCON_SAMPLE_PERIOD_SEL_1 0x00 -#define CIR_IRCON_SAMPLE_PERIOD_SEL_25 0x01 -#define CIR_IRCON_SAMPLE_PERIOD_SEL_50 0x02 -#define CIR_IRCON_SAMPLE_PERIOD_SEL_100 0x03 - -/* select sample period as 50us */ -#define CIR_IRCON_SAMPLE_PERIOD_SEL CIR_IRCON_SAMPLE_PERIOD_SEL_50 - -/* CIR IRSTS settings */ -#define CIR_IRSTS_RDR 0x80 -#define CIR_IRSTS_RTR 0x40 -#define CIR_IRSTS_PE 0x20 -#define CIR_IRSTS_RFO 0x10 -#define CIR_IRSTS_TE 0x08 -#define CIR_IRSTS_TTR 0x04 -#define CIR_IRSTS_TFU 0x02 -#define CIR_IRSTS_GH 0x01 - -/* CIR IREN settings */ -#define CIR_IREN_RDR 0x80 -#define CIR_IREN_RTR 0x40 -#define CIR_IREN_PE 0x20 -#define CIR_IREN_RFO 0x10 -#define CIR_IREN_TE 0x08 -#define CIR_IREN_TTR 0x04 -#define CIR_IREN_TFU 0x02 -#define CIR_IREN_GH 0x01 - -/* CIR FIFOCON settings */ -#define CIR_FIFOCON_TXFIFOCLR 0x80 - -#define CIR_FIFOCON_TX_TRIGGER_LEV_31 0x00 -#define CIR_FIFOCON_TX_TRIGGER_LEV_24 0x10 -#define CIR_FIFOCON_TX_TRIGGER_LEV_16 0x20 -#define CIR_FIFOCON_TX_TRIGGER_LEV_8 0x30 - -/* select TX trigger level as 16 */ -#define CIR_FIFOCON_TX_TRIGGER_LEV CIR_FIFOCON_TX_TRIGGER_LEV_16 - -#define CIR_FIFOCON_RXFIFOCLR 0x08 - -#define CIR_FIFOCON_RX_TRIGGER_LEV_1 0x00 -#define CIR_FIFOCON_RX_TRIGGER_LEV_8 0x01 -#define CIR_FIFOCON_RX_TRIGGER_LEV_16 0x02 -#define CIR_FIFOCON_RX_TRIGGER_LEV_24 0x03 - -/* select RX trigger level as 1 */ -#define CIR_FIFOCON_RX_TRIGGER_LEV CIR_FIFOCON_RX_TRIGGER_LEV_1 - -/* CIR IRFIFOSTS settings */ -#define CIR_IRFIFOSTS_IR_PENDING 0x80 -#define CIR_IRFIFOSTS_RX_GS 0x40 -#define CIR_IRFIFOSTS_RX_FTA 0x20 -#define CIR_IRFIFOSTS_RX_EMPTY 0x10 -#define CIR_IRFIFOSTS_RX_FULL 0x08 -#define CIR_IRFIFOSTS_TX_FTA 0x04 -#define CIR_IRFIFOSTS_TX_EMPTY 0x02 -#define CIR_IRFIFOSTS_TX_FULL 0x01 - - -/* CIR WAKE UP Regs */ -#define CIR_WAKE_IRCON 0x00 -#define CIR_WAKE_IRSTS 0x01 -#define CIR_WAKE_IREN 0x02 -#define CIR_WAKE_FIFO_CMP_DEEP 0x03 -#define CIR_WAKE_FIFO_CMP_TOL 0x04 -#define CIR_WAKE_FIFO_COUNT 0x05 -#define CIR_WAKE_SLCH 0x06 -#define CIR_WAKE_SLCL 0x07 -#define CIR_WAKE_FIFOCON 0x08 -#define CIR_WAKE_SRXFSTS 0x09 -#define CIR_WAKE_SAMPLE_RX_FIFO 0x0A -#define CIR_WAKE_WR_FIFO_DATA 0x0B -#define CIR_WAKE_RD_FIFO_ONLY 0x0C -#define CIR_WAKE_RD_FIFO_ONLY_IDX 0x0D -#define CIR_WAKE_FIFO_IGNORE 0x0E -#define CIR_WAKE_IRFSM 0x0F - -/* CIR WAKE UP IRCON settings */ -#define CIR_WAKE_IRCON_DEC_RST 0x80 -#define CIR_WAKE_IRCON_MODE1 0x40 -#define CIR_WAKE_IRCON_MODE0 0x20 -#define CIR_WAKE_IRCON_RXEN 0x10 -#define CIR_WAKE_IRCON_R 0x08 -#define CIR_WAKE_IRCON_RXINV 0x04 - -/* select a same sample period like cir register */ -#define CIR_WAKE_IRCON_SAMPLE_PERIOD_SEL CIR_IRCON_SAMPLE_PERIOD_SEL_50 - -/* CIR WAKE UP IRSTS settings */ -#define CIR_WAKE_IRSTS_RDR 0x80 -#define CIR_WAKE_IRSTS_RTR 0x40 -#define CIR_WAKE_IRSTS_PE 0x20 -#define CIR_WAKE_IRSTS_RFO 0x10 -#define CIR_WAKE_IRSTS_GH 0x08 -#define CIR_WAKE_IRSTS_IR_PENDING 0x01 - -/* CIR WAKE UP IREN settings */ -#define CIR_WAKE_IREN_RDR 0x80 -#define CIR_WAKE_IREN_RTR 0x40 -#define CIR_WAKE_IREN_PE 0x20 -#define CIR_WAKE_IREN_RFO 0x10 -#define CIR_WAKE_IREN_TE 0x08 -#define CIR_WAKE_IREN_TTR 0x04 -#define CIR_WAKE_IREN_TFU 0x02 -#define CIR_WAKE_IREN_GH 0x01 - -/* CIR WAKE FIFOCON settings */ -#define CIR_WAKE_FIFOCON_RXFIFOCLR 0x08 - -#define CIR_WAKE_FIFOCON_RX_TRIGGER_LEV_67 0x00 -#define CIR_WAKE_FIFOCON_RX_TRIGGER_LEV_66 0x01 -#define CIR_WAKE_FIFOCON_RX_TRIGGER_LEV_65 0x02 -#define CIR_WAKE_FIFOCON_RX_TRIGGER_LEV_64 0x03 - -/* select WAKE UP RX trigger level as 67 */ -#define CIR_WAKE_FIFOCON_RX_TRIGGER_LEV CIR_WAKE_FIFOCON_RX_TRIGGER_LEV_67 - -/* CIR WAKE SRXFSTS settings */ -#define CIR_WAKE_IRFIFOSTS_RX_GS 0x80 -#define CIR_WAKE_IRFIFOSTS_RX_FTA 0x40 -#define CIR_WAKE_IRFIFOSTS_RX_EMPTY 0x20 -#define CIR_WAKE_IRFIFOSTS_RX_FULL 0x10 - - - - -/* Config Regs */ - -/* Chip Control Regs */ -#define cr_cfg_idx 0x2e -#define cr_cfg_dat 0x2f - -#define cr_cfg_idx2 0x4e -#define cr_cfg_dat2 0x4f - -static u8 CFG_idx = cr_cfg_idx; -static u8 CFG_dat = cr_cfg_dat; - -#define CHIP_ID_HIGH_ADDR 0x20 -#define CHIP_ID_LOW_ADDR 0x21 - -#define CHIP_ID_HIGH 0xB4 -#define CHIP_ID_LOW 0x73 - -#define ACTIVE_LOG_DEV 0x01 -#define DEACTIVE_LOG_DEV 0x0 - -#define CIR_LOG_DEV 0x06 - -#define ACPI_LOG_DEV 0x0A - -#define ENABLE_CIR_WAKE 0x08 -#define DISABLE_CIR_WAKE 0xF7 - -#define ENABLE_CIR_INTR_OF_MOUSE_IRQ 0x80 -#define DISABLE_CIR_INTR_OF_MOUSE_IRQ 0x7F - -#define ENABLE_PME_INTR_OF_CIR_PASS 0x08 -#define DISABLE_PME_INTR_OF_CIR_PASS 0xF7 - -#define CIR_WAKE_LOG_DEV 0x0E - - -/* read/update registers functions */ - -/* enter extended function mode */ -static inline void cr_enter_ext(void); - -/* exit extended function mode */ -static inline void cr_exit_ext(void); - -/* select logical device */ -static inline void cr_select_log_dev(int cr); - -static inline void cr_update(int dat, int cr); - -static inline u8 cr_read(int cr); - -/* update cr register without change other bits */ -static inline void cr_safe_update(u8 dat, int cr); - -/* clear cr register without change other bits */ -static inline void cr_safe_clear(u8 dat, int cr); - - - -/* read/write cir registers */ - -static inline void cir_update(u8 dat, int cir); - -static u8 cir_read(int cir); - -/* read/write cir wake registers */ - -static inline void cir_wake_update(u8 dat, int cir); - -static u8 cir_wake_read(int cir); - - -/* dump current cir registers */ -static void cir_dump_reg(void); - -/* dump current cir wake up registers */ -static void cir_wake_dump_reg(void); - - - - - -/* driver module load/unload functions */ - -/* Config Registers init */ -/* - * initialize cr, cir, apci, cir wake logical devices - * open these devices and irq - */ -static int w83667hg_cr_init(void); - -/* Config Registers uninit */ -/* - * close cir and cir wake logical devices - */ -static void w83667hg_cr_uninit(void); - - -/* register input device (keyboard and mouse) - * - */ - -/* this is the keycode table of US-EN layout keyboard - * modify it to support other layout keyboard - */ -static unsigned int usb_kbd_keycode[256] = { - 0, 0, 0, 0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38, - 50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44, 2, 3, - 4, 5, 6, 7, 8, 9, 10, 11, 28, 1, 14, 15, 57, 12, 13, 26, - 27, 43, 43, 39, 40, 41, 51, 52, 53, 58, 59, 60, 61, 62, 63, 64, - 65, 66, 67, 68, 87, 88, 99, 70,119,110,102,104,111,107,109,106, - 105,108,103, 69, 98, 55, 74, 78, 96, 79, 80, 81, 75, 76, 77, 71, - 72, 73, 82, 83, 86,127,116,117,183,184,185,186,187,188,189,190, - 191,192,193,194,134,138,130,132,128,129,131,137,133,135,136,113, - 115,114, 0, 0, 0,121, 0, 89, 93,124, 92, 94, 95, 0, 0, 0, - 122,123, 90, 91, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 29, 42, 56,125, 97, 54,100,126,164,166,165,163,161,115,114,113, - 150,158,159,128,136,177,178,176,142,152,173,140 -}; - -/* input device name, locate in /sys/input/inputNUM/name */ -static char *INPUTNAME = "MCE Remote Keyboard"; - -static struct input_id w83667hg_input_id = { - .bustype = BUS_HOST, /* comunicate 667 by HOST, or I2C ? */ - .vendor = 0x1050, /* Winbond PCI VENDOR ID */ - .product = 1, /* for basic devices, like keyboard & mouse */ - .version = 0, /* ignore it */ -}; - - -static int w83667hg_input_open(struct input_dev *cur_input_dev); - -static void w83667hg_input_close(struct input_dev *cur_input_dev); - -static struct input_dev *w83667hg_input_init(void); - -static void w83667hg_input_uninit(struct input_dev *cur_input_dev); - -/* internal call for register lirc */ -static int lirc_set_use_inc(void *data); - -static void lirc_set_use_dec(void *data); - -/* register lirc device & buffer */ - -/* mininum value 76, recommend 256 */ -#define IRCTL_BUF_LIMIT 2048 - -static struct irctl { - struct input_dev *input_dev; /* allocate by input_init */ - struct lirc_buffer *lirc_buffer; - struct lirc_driver *lirc_plugin; - spinlock_t lock; - /* for controller */ - lirc_t lircdata; - u8 ctrl_fix_head; // fix controller not sync problem - /* for keyboard */ - u8 pressed_keycode; // initialize as 0 - u8 pressed_shiftmask; // initialize as 0 - /* for decode */ - u8 buf[IRCTL_BUF_LIMIT]; - unsigned int buf_count; // init as 0, reset 0 after decode - unsigned int cur_buf_num; // init as 0, set as 0 while clean - /* for study */ -#define ST_STUDY_NONE 0x0 -#define ST_STUDY_START 0x01 -#define ST_STUDY_CARRIER 0x02 -#define ST_STUDY_ALL_RECV 0x04 - u8 study_state; - /* carrier period = 1 / frequency */ - unsigned int carrier; - wait_queue_head_t queue; -} w83667hg_irctl; - -static struct ir_recv_t { - spinlock_t lock; - u8 buf[IRCTL_BUF_LIMIT]; - unsigned int buf_count; - wait_queue_head_t queue; - /* for wake */ -#define ST_WAKE_NONE 0x0 -#define ST_WAKE_START 0x01 -#define ST_WAKE_FINISH 0x02 - u8 wake_state; - /* for recv */ -#define ST_RECV_WAIT_7F 0x01 -#define ST_RECV_WAIT_HEAD 0x02 -#define ST_RECV_WAIT_SILENT_END 0x04 - u8 recv_state; -} w83667hg_ir_recv; - -static struct ir_send_t { - spinlock_t lock; - u8 buf[IRCTL_BUF_LIMIT]; - unsigned int buf_count; - unsigned int cur_buf_num; - wait_queue_head_t queue; - /* for send */ -#define ST_SEND_NONE 0x0 -#define ST_SEND_REQUEST 0x02 -#define ST_SEND_REPLY 0x04 - u8 send_state; -} w83667hg_ir_send; - -static struct input_dev *w83667hg_input_dev = NULL; - -//static struct lirc_plugin *w83667hg_lirc_plugin = NULL; -static struct lirc_driver *w83667hg_lirc_plugin = NULL; - -#define LIRCBUF_SIZE 256 - -static struct lirc_buffer *w83667hg_lirc_buffer = NULL; - -static void w83667hg_ir_recv_init(struct ir_recv_t *ir_recv); - -static void w83667hg_ir_send_init(struct ir_send_t *ir_send); - -static int w83667hg_irctl_init(struct irctl *ir); - -static void w83667hg_irctl_uninit(struct irctl *ir); - - -#define BIT_PULSE_MASK 0x80 -#define BIT_LEN 0x7f - -/* MCE CIR signal length, related on sample period */ - -/* MCE CIR controller signal length: about 43ms - * 43ms / 50us (sample period) * 0.85 (inaccuracy) - */ -#define CONTROLLER_BUF_LEN_MIN 830 - -/* MCE CIR keyboard signal length: about 26ms - * 26ms / 50us (sample period) * 0.85 (inaccuracy) - */ -#define KEYBOARD_BUF_LEN_MAX 650 -#define KEYBOARD_BUF_LEN_MIN 610 - -/* MCE CIR mouse signal length: about 24ms - * 24ms / 50us (sample period) * 0.85 (inaccuracy) - */ -#define MOUSE_BUF_LEN_MIN 565 - - -#define CIR_SAMPLE_PERIOD 50 -#define CIR_SAMPLE_LOW_INACCURACY 0.85 - - -/* "10"=>1 (+2), "01"=>0 (+2) */ -#define ST_DECODE_NEW 0x01 -#define ST_DECODE_ZERO 0x02 -#define ST_DECODE_ONE 0x04 - -/* RC6 sync head: 1111 11 - * 6 * 444us / 50us (sample period) * 0.85 (inaccuracy) - */ -#define HEAD_SYNC_LEN_LOW 45 -/* 7 pulses long, for inaccuracy */ -#define HEAD_SYNC_LEN_HIGH 71 - -#define ONE_PULSE_LEN_LOW 2 -#define ONE_PULSE_LEN_HIGH 10 -#define TWO_PULSE_LEN_LOW 10 -#define TWO_PULSE_LEN_HIGH 15 - - -/* fops */ -/* set carrier frequency by ioctl IR_IOSETCARRIER - * - * that value can be get by ioctl value IR_IOGETCARRIER - * on 667, set carrier on 2 registers: CP & CC - * always set CP as 0x81 - * set CC by SPEC, CC = 3MHz/carrier - 1 - */ -static int w83667hg_set_carrier(unsigned int *carrier); - -static int lirc_ioctl(struct inode *node,struct file *filep,unsigned int cmd, - unsigned long arg); - -/* lirc_write - * - * 1) clean TX fifo first (handled by AP) - * 2) copy data from user space - * 3) open TX interrupt: TTR & TFU - * 4) send 9 pulses to open TTR - * in interrupt_handler: - * 5) send all data out - * go back to write(): - * 6) close TX interrupt - * - * The key problem of this function is user space data may larger than - * driver's data buf length. So lirc_wirte() only copy IRCTL_BUF_LIMIT data to - * buf. And keep current copied data buf num in cur_buf_num. But driver's buf - * number may larger than TXFCONT (0xFF). So in interrupt_handler, it has to - * set TXFCONT as 0xff, until buf_count less than 0xff. - * The confustion is cur_buf_num in decode, study and send is designed on - * different meaning. - * - */ -static ssize_t lirc_write(struct file *file, const char *buf, size_t n, loff_t * ppos); - - - -/* 1) clean lircdata and buf_count in irctl struct - * 2) clean RX and TX fifo - */ -static void w83667hg_clean_data(struct ir_recv_t *ir_recv, struct irctl *ir); - - - -/* jump asked frame number, can use on key, mouse and controller signals - * - * after jump frame_num, current frame number = frame_num + 1 - * record current buf number of irctl buf - * record current pulse's bit and decode_status - * - * problem 1: - * When jump_frame() stops on a two_width_len pulse, the buf_num will be the - * second pulse of the double_width_len pulse. - * So jump_frame() must increase buf_num 1 on problem 1. - * For sample period is 50us, a 444us piulse's minimal sample value is 7, and - * two piulses' minimal sample value is 15. So just increase buf_num 1 works - * fine. If sample period changes, this solution also need change. - * - * one_width_len pulse: - * _ _ - * .| |_| |_. (1010) - * ^ - * | - * stop: jumped frame_num - * - * - * problem 1: double_width_len pulse: - * __ _ - * .| |__| |. (11001) - * ^ - * | - * stop: jumped frame_num + 1, buf_num + 1 - * - * so if cur buf len > TWO_PULSE_LEN_LOW, buf_num -- - * and recheck polar bit and decode_status - * decode_status go back 1 buf, - * NEW -> ONE/ZERO; ONE/ZERO -> NEW - * - * jump out of buf limit, return < 0 - */ -static int w83667hg_jump_frame(struct irctl *ir, u8 frame_num, unsigned int *buf_num, u8 *out_bit, u8 *decode_status); - -/* jump MCE head sync signal (1111 11) - * - * after jump signal head, current pulse number = 7 - * record current buf number of irctl buf - * record current pulse's bit and decode_status - * - * jump out of buf limit, return < 0 - */ -static int w83667hg_jump_head(struct irctl *ir, unsigned int *buf_num); - -#define KEY_IDENTIFICATION 0x04 -#define MOUSE_IDENTIFICATION 0x01 -#define IDENTIFICATION_CHECK_BIT 0xF - -/* check mce identification - * - * compare identification and cur_iden - * same return 0 - * else return < 0, need continue check - */ -static int w83667hg_check_identification(u8 val, u8 identification, u8 *cur_iden); - -/* jump mce identification - * can use on key, mouse and controller signals - * - * jump and search identification parts - * record current buf number of irctl buf - * - * jump all pulse until find identification - * - * - * - * problem 1: - * When jump_identification() stops on a double_width_len pulse, the buf_num will be the - * second pulse of the doule_width_len frame. - * - * one_width_len pulse: - * _ _ - * .| |_| |_. (1010) - * ^ - * | - * stop: jumped frame_num - * - * - * problem 1: double_width_len pulse: - * __ _ - * .| |__| |. (11001) - * ^ - * | - * stop: jumped frame_num + 1, buf_num + 2 - * - * solution: - * Now buf_num is the next double-pulse-width buf. - * Just decrease buf_num by one can fix this problem. - * - * - * After jump iden, output may diff by decode status: - * 1) - * For status ONE and ZERO, all decode work is done. - * Set status as NEW and inverse out_bit - * in fact, bit is not important, for a buf can indicate one frame, whether its - * length is one or two, the bit can be ignored - * - * after jump frame, all status is NEW! reset them as inverse polar bit - * - * - * - * - * can not find identification, return < 0 - */ -static int w83667hg_jump_identification(struct irctl *ir, u8 identification, unsigned int *buf_num, u8 *out_bit, u8 *decode_status); - - -/* the frame number between identification and code */ -#define KEY_KEYCODE_FRAME_AFTER_I_START 16 //32 -#define KEY_FRAME_AFTER_JUMP 16//64 -#define KEY_SUBMIT_KEYCODE_FRAME_NUM 8 - - -#define MOUSE_DELTAY_PULSE_AFTER_I_START 8 -#define MOUSE_CHECKSUM_FRAME_AFTER_JUMP 16 -#define MOUSE_SUBMIT_DELTAY_FRAME_NUM 7 -#define MOUSE_SUBMIT_DELTAX_FRAME_NUM 14 -#define MOUSE_SUBMIT_R_FRAME_NUM 15 -#define MOUSE_SUBMIT_L_FRAME_NUM 16 - - -// FIXME, not sure this value, select a large number -#define PULSE_SILENT_LEN_LOW 90 - - -/* set keycode and shiftmask for keyboard */ -static void w83667hg_set_key(u8 *set_frame, u8 val, u8 *keycode, u8 *shiftmask); - -/* decode mce keyboard signal and send data to input - * - * 1) jump mce keyboard signal sync head (1111 11) - * 2) jump identification (0100) - * pulse number before identification is not sure - * 3) jump "unknown", "C" and "CodeSet" parts in mce keyboard signal - * 4) deocde "KeyCode" and "ShiftMask" parts in mce key signal - * 5) send keycode to input by array usb_kbd_keycode - * 6) send shiftmask to input by array usb_kbd_keycode - */ -static void w83667hg_submit_key(struct irctl *ir); - -/* set deltax, deltay, x, y for mce mouse */ -static void w83667hg_set_mouse(u8 *set_frame, u8 val, u8 *deltay, u8 *deltax, u8 *clickrl); - -/* decode mce mouse signal and send data to input - * - * 1) jump mce mouse signal sync head (1111 11) - * 2) jump identification (0001) - * pulse number before identification is not sure - * 3) jump "unknown" part in mce mouse signal - * 4) deocde "deltay", "deltax", "r" and "l" parts in mce mouse signal - * 5) send these parts to input - */ -static void w83667hg_submit_mouse(struct irctl *ir); - - -/* send 1 recorded controller signal to lirc */ -static void w83667hg_send_packet_to_lirc_1(struct irctl *ir, lirc_t *val); - -/* this value copy from lirc_mod_mce */ -#if CIR_IRCON_SAMPLE_PERIOD_SEL == CIR_IRCON_SAMPLE_PERIOD_SEL_100 - #define MCE_TIME_UNIT 100 -#elif CIR_IRCON_SAMPLE_PERIOD_SEL == CIR_IRCON_SAMPLE_PERIOD_SEL_50 - #define MCE_TIME_UNIT 50 -#elif CIR_IRCON_SAMPLE_PERIOD_SEL == CIR_IRCON_SAMPLE_PERIOD_SEL_25 - #define MCE_TIME_UNIT 25 -#else - #define MCE_TIME_UNIT 1 -#endif - -/* recode mce controller signal and send to lirc - * - * recode steps: - * 1) high pulse, +128 - * 2) low pulse, do nothing - * 3) keycode = pulse * 50 - * 4) sync head: PULSE_MASK (0xFF FFFF) - * 5) 1, |PULSE_BIT (0x100 0000) - * 0, +keycode - * - * function steps: - * 0) clean lircdata[] - * 1) jump head, put PULSE_BIT in lircdata[0] - * 2) normal decode, "10"=>1 |PULSE_BIT - * save in lircdata[] - * 3) send lircdata[] to lirc - */ -static void w83667hg_submit_controller(struct irctl *ir); - - -/* copy data from hardware fifo to driver buf - * - * 1. initial state is WAIT_7F - * 2. if data is not 0x7f, copy data from hardware fifo to struct ir_recv buf - * 3. if data is 0x7f, set recv_state as WAIT_HEAD, copy data from ir_recv to irctl - * 4. depend on received buf length to select submit_ function - * 5. set irctl buf len as 0 - * 5. receive data until data is not 0x7f, drop received 0x7f data, set recv_state as WAIT_7F again - * - * in normal, there are 3 parts in one infrared signal: - * 1. not silent pulse (ST_WAIT_7F) - * 2. 0x7f silent pulse (ST_WAIT_HEAD) - * 3. silent pulse shorter than 0x7f (ST_WAIT_HEAD) - * - * so this function copy signal part 1 and a 0x7f (for decode) to submit_() functions. - * when receive 0x7f, this function copy data from ir_recv to irctl, and wait for next high pulse. - */ -static void w83667hg_recv(struct ir_recv_t *ir_recv, struct irctl *ir); - - -/* as VISTA MCE definition, valid carrier value */ -#define MAX_CARRIER 60000 -#define MIN_CARRIER 30000 - -/* receive function for STUDY - * - * 0. not receive 0x80, copy received data to ir_recv buf - * when get 0x80, it means user released controller, and only need process received data - * 1. get carrier - * 2. get pulse - */ -static void w83667hg_study_recv(struct ir_recv_t *ir_recv, struct irctl *ir); - -static irqreturn_t w83667hg_wake_interrupt_handler(int irq, void *dev); - -static irqreturn_t w83667hg_interrupt_handler(int irq, void *dev); - - -/* platform device, NON-PNP */ - -static struct platform_device *lirc_wb667_dev; - -static int __devinit lirc_wb667_probe(struct platform_device *dev); - -static int __devexit lirc_wb667_remove(struct platform_device *dev); - -/* before suspend - * 1. set all states as NONE - * 2. close CIR and WAKE interrupt - * 3. close CIR and WAKE cr - * 4. close input - */ -static int lirc_wb667_suspend(struct platform_device *dev, pm_message_t state); - -/* resume all register and input device - */ -static int lirc_wb667_resume(struct platform_device *dev); - - -/* pnp device */ -#ifdef CONFIG_PNP - - -/* CIR and CIR WAKE */ -static const struct pnp_device_id pnp_dev_table[] = { - { "WEC0530", 0 }, /* CIR */ - { "NTN0530", 0 }, /* CIR for new chip's pnp id*/ - { "", 0 }, -}; - - -MODULE_DEVICE_TABLE(pnp, pnp_dev_table); - -static int __devinit lirc_wb667_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id); - -static void __devexit lirc_wb667_pnp_remove(struct pnp_dev *dev); - -/* before suspend - * 1. set all states as NONE - * 2. close CIR and WAKE interrupt - * 3. close CIR and WAKE cr - * 4. close input - */ -static int lirc_wb667_pnp_suspend(struct pnp_dev *dev, pm_message_t state); - -/* resume all register and input device - */ -static int lirc_wb667_pnp_resume(struct pnp_dev *dev); - - - #if 0 - -/* CIR */ - -static const struct pnp_device_id pnp_dev_cir_table[] = { - { "WEC0530", 0 }, /* CIR */ - { "", 0 }, -}; - -MODULE_DEVICE_TABLE(pnp, pnp_dev_cir_table); - -static int __devinit lirc_wb667_pnp_cir_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id); - -static void __devexit lirc_wb667_pnp_cir_remove(struct pnp_dev *dev); - -/* before suspend - * 1. set all states as NONE - * 2. close CIR and WAKE interrupt - * 3. close CIR and WAKE cr - * 4. close input - */ -static int lirc_wb667_pnp_cir_suspend(struct pnp_dev *dev, pm_message_t state); - -/* resume all register and input device - */ -static int lirc_wb667_pnp_cir_resume(struct pnp_dev *dev); - - -/* CIR WAKE */ - -static const struct pnp_device_id pnp_dev_cir_wake_table[] = { - { "WEC0531", 0 }, /* CIR WAKE */ - { "", 0 }, -}; - -MODULE_DEVICE_TABLE(pnp, pnp_dev_cir_wake_table); - -static int __devinit lirc_wb667_pnp_cir_wake_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id); - -static void __devexit lirc_wb667_pnp_cir_wake_remove(struct pnp_dev *dev); - - #endif - -static unsigned int nopnp = 0; - -#else - -static const unsigned int nopnp = 1; - -#endif - - -/* create io region for cir and cir wake - * create irq handler - * create dev and data struct - */ -static int w83667hg_cir_probe(void); - -/* uninit cir, cir wake, dev and data struct, release irq and io port */ -static void w83667hg_cir_remove(void); - - -static int lirc_wb667_init(void); - -void lirc_wb667_uninit(void); - - -/* - * 1. init cr - * 2. init input - * 3. init lirc buffer, register, irctl - * 4. init 667 cir dev, req_region, req_irq - */ -//int init_module(void); -//void cleanup_module(void); -int init_module_wb667(void); -void cleanup_module_wb667(void); - -MODULE_DESCRIPTION("LIRC driver for Winbond W83677HG CIR"); -MODULE_AUTHOR(""); -MODULE_LICENSE("GPL"); - -/* device file name, locate in /dev/ directory */ -//static char *DRVNAME = "w83667hg_ir"; -// FIXME, stable name -static char *DRVNAME = "lirc_wb677"; -module_param(DRVNAME, charp, S_IRUGO); -MODULE_PARM_DESC(DRVNAME, "Device file name in /dev/ and /sys/class/."); - -/* platform driver name to register */ -#define PLATNAME "lirc_wb667_cir" -#define PLATNAME_W "lirc_wb667_wake" - -/* device file major number */ -#define CIR_MAJOR 229 - -/* cir device base address */ -//static u16 CIR_BASE = 0x380; -static u16 CIR_BASE = 0x240; -module_param(CIR_BASE, ushort, S_IRUGO); -MODULE_PARM_DESC(CIR_BASE, "Base IO port address of 667 CIR device."); - -/* cir base i/o address */ -static unsigned int cir_address; - -/* cir irq */ -static ushort CIR_IRQ_NUM = 5; -module_param(CIR_IRQ_NUM, ushort, S_IRUGO); -MODULE_PARM_DESC(CIR_IRQ_NUM, "IRQ number for 667 CIR device."); - -/* handle cir wake up request in driver or not */ -#define ENABLE_CIR_WAKE_IRQ - -/* cir wake up device base address */ -static u16 CIR_WAKE_BASE = 0x250; -//static u16 CIR_WAKE_BASE = 0x380; -module_param(CIR_WAKE_BASE, ushort, S_IRUGO); -MODULE_PARM_DESC(CIR_WAKE_BASE, "Base IO port address of 667 CIR WAKE device."); - -/* cir wake up base i/o address */ -static unsigned int cir_wake_address; - -/* cir wake up irq */ -//static ushort CIR_WAKE_IRQ_NUM = 10; -static ushort CIR_WAKE_IRQ_NUM = 5; -module_param(CIR_WAKE_IRQ_NUM, ushort, S_IRUGO); -MODULE_PARM_DESC(CIR_WAKE_IRQ_NUM, "IRQ number for 667 CIR WAKE device."); - -/* nopnp option */ -#ifdef CONFIG_PNP -module_param(nopnp, uint, S_IRUGO); -MODULE_PARM_DESC(nopnp, "Scan for device instead of relying on PNP. (default 0)"); -#endif - -//EXPORT_NO_SYMBOLS; - - - diff -Nru nct677x-dkms-1.0.1/nct677x-1.0.1/src/lirc_wb677.mod.c nct677x-dkms-1.0.4/nct677x-1.0.1/src/lirc_wb677.mod.c --- nct677x-dkms-1.0.1/nct677x-1.0.1/src/lirc_wb677.mod.c 2010-03-31 15:56:50.000000000 +0000 +++ nct677x-dkms-1.0.4/nct677x-1.0.1/src/lirc_wb677.mod.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,87 +0,0 @@ -#include -#include -#include - -MODULE_INFO(vermagic, VERMAGIC_STRING); - -struct module __this_module -__attribute__((section(".gnu.linkonce.this_module"))) = { - .name = KBUILD_MODNAME, - .init = init_module, -#ifdef CONFIG_MODULE_UNLOAD - .exit = cleanup_module, -#endif - .arch = MODULE_ARCH_INIT, -}; - -static const struct modversion_info ____versions[] -__used -__attribute__((section("__versions"))) = { - { 0xec5ba0f9, "module_layout" }, - { 0x41344088, "param_get_charp" }, - { 0x6ad065f4, "param_set_charp" }, - { 0x52ebb126, "param_get_ushort" }, - { 0xe0bc24a1, "param_set_ushort" }, - { 0x108e8985, "param_get_uint" }, - { 0x3285cc48, "param_set_uint" }, - { 0x19724b32, "pnp_register_driver" }, - { 0xc323e586, "platform_device_put" }, - { 0xd344e9a2, "platform_device_del" }, - { 0xaf1da581, "platform_driver_register" }, - { 0xfcfeaf96, "platform_device_add" }, - { 0x1701e0fb, "platform_device_alloc" }, - { 0xfda85a7d, "request_threaded_irq" }, - { 0xadf42bd5, "__request_region" }, - { 0xdc7a3ca1, "lirc_register_driver" }, - { 0xe914e41e, "strcpy" }, - { 0x3da5eb6d, "kfifo_alloc" }, - { 0x4661e311, "__tracepoint_kmalloc" }, - { 0x142c23f8, "kmem_cache_alloc" }, - { 0x28849590, "kmalloc_caches" }, - { 0xffc7c184, "__init_waitqueue_head" }, - { 0x541ab510, "input_register_device" }, - { 0x8a86d20f, "input_allocate_device" }, - { 0x6ce3f20d, "pnp_unregister_driver" }, - { 0x5a37ed92, "platform_device_unregister" }, - { 0xe6aa1dbb, "platform_driver_unregister" }, - { 0x9bce482f, "__release_region" }, - { 0x59d8223a, "ioport_resource" }, - { 0xf20dabd8, "free_irq" }, - { 0x15ef2dd9, "kfifo_free" }, - { 0x37a0cba, "kfree" }, - { 0x4dca738, "lirc_unregister_driver" }, - { 0x6729d3df, "__get_user_4" }, - { 0xb2fd5ceb, "__put_user_4" }, - { 0xa1c76e0a, "_cond_resched" }, - { 0x2f287f0d, "copy_to_user" }, - { 0x4b07e779, "_spin_unlock_irqrestore" }, - { 0x231f3a66, "__kfifo_put" }, - { 0x712aa29b, "_spin_lock_irqsave" }, - { 0x1eb392e8, "pnp_get_resource" }, - { 0x4163ef55, "input_free_device" }, - { 0x1721eec3, "input_unregister_device" }, - { 0x6f0c693a, "get_device" }, - { 0xeab3f26e, "input_event" }, - { 0x9ccb2622, "finish_wait" }, - { 0x33d92f9a, "prepare_to_wait" }, - { 0x4292364c, "schedule" }, - { 0xc8b57c27, "autoremove_wake_function" }, - { 0xb281b25f, "per_cpu__current_task" }, - { 0xd6c963c, "copy_from_user" }, - { 0x642e54ac, "__wake_up" }, - { 0xb279da12, "pv_lock_ops" }, - { 0x973873ab, "_spin_lock" }, - { 0xb72397d5, "printk" }, -}; - -static const char __module_depends[] -__used -__attribute__((section(".modinfo"))) = -"depends=lirc_dev"; - -MODULE_ALIAS("pnp:dWEC0530*"); -MODULE_ALIAS("acpi*:WEC0530:*"); -MODULE_ALIAS("pnp:dNTN0530*"); -MODULE_ALIAS("acpi*:NTN0530:*"); - -MODULE_INFO(srcversion, "05F8848914AD40BBC9300C1"); diff -Nru nct677x-dkms-1.0.1/nct677x-1.0.1/src/Makefile nct677x-dkms-1.0.4/nct677x-1.0.1/src/Makefile --- nct677x-dkms-1.0.1/nct677x-1.0.1/src/Makefile 2010-03-31 15:56:50.000000000 +0000 +++ nct677x-dkms-1.0.4/nct677x-1.0.1/src/Makefile 1970-01-01 00:00:00.000000000 +0000 @@ -1,64 +0,0 @@ -#!/bin/bash - -# Notice : -# for dkms, make cmd was defined in dkms.conf as MAKE[0]. generally we define it as -# MAKE[0] = "make ..." -# however, when dkms build this target, it was invoked by "make KERNELRELEASE=xxx ..." instead -# that cause the plain make file below can not work again : -# -# ifneq ($(KERNELRELEASE),) -# obj-m := lirc_wb667.o -# lirc_wb667-objs := lirc_wb667.o -# else -# KERNEL_SRC_TREE ?= /lib/modules/$(shell uname -r)/build -# PWD := $(shell pwd) -# modules modules_install clean: -# make -C $(KERNEL_SRC_TREE) M=$(PWD) $@ -# endif -# -# it can not work because KERNELRELEASE was defined in dkms's case. so we should merge the two -# cases together : - -# on Linux 2.6 kernel -# If KERNELRELEASE is defined, we've been invoked from the -# kernel build system and can use its language. - - - - LIRC_DIR := ../include - - obj-m := lirc_wb677.o - - KSRC ?= /lib/modules/$(shell uname -r)/build - - PWD := $(shell pwd) -modules: - echo KERNELDIR=$(KSRC) - $(MAKE) -C $(KSRC) -I $(LIRC_DIR) M=$(PWD) modules - - -# Following "install", "uninstall" and "clean" are not for dkms. - -install: - /etc/init.d/lirc stop - rmmod lirc_wb677 || echo "lirc_wb677.ko is not executing" - file="lirc_wb677.ko"; \ - dir="/lib/modules/$(shell uname -r)/kernel/ubuntu/lirc/lirc_wb677"; \ - if test -d "$$dir"; then echo ""; else mkdir -p $$dir; fi; \ - cp -vf *.ko $$dir - depmod -a - patch -p0 /usr/share/lirc/lirc.hwdb < /usr/share/lirc/lirc_nct667x-src-1.0.0-ubuntu9.10.patch - @echo "" - @echo "Hint: You can execute \"dpkg-reconfigure lirc\" to configure lirc." - @echo " And start lirc by executing \"/etc/init.d/lirc start\"" - -uninstall: - /etc/init.d/lirc stop - ( rmmod lirc_wb677 ) || echo "lirc_wb677.ko is not executing" - dir="/lib/modules/$(shell uname -r)/kernel/ubuntu/lirc/lirc_wb677"; \ - if test -d "$$dir"; then rm -R $$dir; fi; - depmod -a - patch -R -p0 /usr/share/lirc/lirc.hwdb < /usr/share/lirc/lirc_nct667x-src-1.0.0-ubuntu9.10.patch - -clean: - rm -rf *.o *.ko *.mod.c Module.symvers .tmp_versions .*.cmd diff -Nru nct677x-dkms-1.0.1/nct677x-1.0.1/src/modules.order nct677x-dkms-1.0.4/nct677x-1.0.1/src/modules.order --- nct677x-dkms-1.0.1/nct677x-1.0.1/src/modules.order 2010-03-31 15:56:50.000000000 +0000 +++ nct677x-dkms-1.0.4/nct677x-1.0.1/src/modules.order 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -kernel//home/gda/Entwicklung/VDR/lirc-nct677x-src-1.0.1/src/lirc_wb677.ko diff -Nru nct677x-dkms-1.0.1/nct677x-1.0.1/src/wb83677hg_ir.h nct677x-dkms-1.0.4/nct677x-1.0.1/src/wb83677hg_ir.h --- nct677x-dkms-1.0.1/nct677x-1.0.1/src/wb83677hg_ir.h 2010-03-31 15:56:50.000000000 +0000 +++ nct677x-dkms-1.0.4/nct677x-1.0.1/src/wb83677hg_ir.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,46 +0,0 @@ -#define IR_IOC_MAGIC 'i' - -/* output chip registers for debug */ -#define IR_DUMPCIRREG _IO(IR_IOC_MAGIC, 0x80) -#define IR_DUMPWAKEREG _IO(IR_IOC_MAGIC, 0x81) - - -/* study wake key on MCE CIR controller */ -#define IR_IOLEARNWAKE _IO(IR_IOC_MAGIC, 0x82) - -/* disable cir wake */ -#define IR_IOUNSETWAKE _IO(IR_IOC_MAGIC, 0x83) - -/* enable cir wake */ -#define IR_IOSETWAKE _IO(IR_IOC_MAGIC, 0x84) - - -/* get carrier for study ir signal */ -#define IR_IOGETCARRIER _IOR(IR_IOC_MAGIC, 0x85, unsigned int) - -/* set carrier for send ir signal */ -#define IR_IOSETCARRIER _IOW(IR_IOC_MAGIC, 0x86, unsigned int) - -/* start/stop study key */ -#define IR_IOSTARTSTUDY _IO(IR_IOC_MAGIC, 0x88) -#define IR_IOSTOPSTUDY _IO(IR_IOC_MAGIC, 0x89) - -/* study key buf len */ -#define IR_IOSTUDYLEN _IOR(IR_IOC_MAGIC, 0x8A, unsigned int) - -/* study key buf data */ -#define IR_IOSTUDYBUF _IOR(IR_IOC_MAGIC, 0x8B, unsigned char) - -/* restudy key buf data */ -#define IR_IORESTUDYBUF _IO(IR_IOC_MAGIC, 0x8C) - - -/* clean data */ -#define IR_IOCLEANDATA _IO(IR_IOC_MAGIC, 0x8E) - -/* chip id string, at most 7 characters */ -char *chip_id = "w677hga"; - -/* check chip identification for the applications which are related to hardware */ -#define IR_CHECKCHIP _IOR(IR_IOC_MAGIC, 0x8F, unsigned long long) - Binary files /tmp/k1JEjavQlr/nct677x-dkms-1.0.1/nct677x-1.0.1.dkms.tar.gz and /tmp/Tw6xwgpSAd/nct677x-dkms-1.0.4/nct677x-1.0.1.dkms.tar.gz differ diff -Nru nct677x-dkms-1.0.1/nct677x-1.0.4/dkms.conf nct677x-dkms-1.0.4/nct677x-1.0.4/dkms.conf --- nct677x-dkms-1.0.1/nct677x-1.0.4/dkms.conf 1970-01-01 00:00:00.000000000 +0000 +++ nct677x-dkms-1.0.4/nct677x-1.0.4/dkms.conf 2010-10-29 11:47:01.000000000 +0000 @@ -0,0 +1,10 @@ +PACKAGE_NAME="nct677x" +PACKAGE_VERSION="1.0.4" +CLEAN="rm -f *.*o" +MAKE[0]="make -C src KSRC=$kernel_source_dir KVER=$kernelver modules" +AUTOINSTALL="yes" + +BUILT_MODULE_NAME[0]="lirc_wb677" +BUILT_MODULE_LOCATION[0]="src" +DEST_MODULE_LOCATION[0]="/updates" + diff -Nru nct677x-dkms-1.0.1/nct677x-1.0.4/include/kcompat.h nct677x-dkms-1.0.4/nct677x-1.0.4/include/kcompat.h --- nct677x-dkms-1.0.1/nct677x-1.0.4/include/kcompat.h 1970-01-01 00:00:00.000000000 +0000 +++ nct677x-dkms-1.0.4/nct677x-1.0.4/include/kcompat.h 2010-10-29 11:46:39.000000000 +0000 @@ -0,0 +1,408 @@ +/* $Id: kcompat.h,v 5.45 2009/08/02 11:15:28 lirc Exp $ */ + +#ifndef _KCOMPAT_H +#define _KCOMPAT_H + +#include + +#ifndef __func__ +#define __func__ __FUNCTION__ +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 16) +#define LIRC_THIS_MODULE(x) x, +#else /* >= 2.6.16 */ +#define LIRC_THIS_MODULE(x) +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) + +#include + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18) +#define LIRC_HAVE_DEVFS +#define LIRC_HAVE_DEVFS_26 +#endif + +#define LIRC_HAVE_SYSFS + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 13) + +typedef struct class_simple lirc_class_t; + +static inline lirc_class_t *class_create(struct module *owner, char *name) +{ + return class_simple_create(owner, name); +} + +static inline void class_destroy(lirc_class_t *cls) +{ + class_simple_destroy(cls); +} + +#define lirc_device_create(cs, parent, dev, drvdata, fmt, args...) \ + class_simple_device_add(cs, dev, parent, fmt, ## args) + +static inline void lirc_device_destroy(lirc_class_t *cls, dev_t devt) +{ + class_simple_device_remove(devt); +} + +#else /* >= 2.6.13 */ + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 15) + +#define lirc_device_create(cs, parent, dev, drvdata, fmt, args...) \ + class_device_create(cs, dev, parent, fmt, ## args) + +#else /* >= 2.6.15 */ + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26) + +#define lirc_device_create(cs, parent, dev, drvdata, fmt, args...) \ + class_device_create(cs, NULL, dev, parent, fmt, ## args) + +#else /* >= 2.6.26 */ + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 27) + +#define lirc_device_create(cs, parent, dev, drvdata, fmt, args...) \ + device_create(cs, parent, dev, fmt, ## args) + +#else /* >= 2.6.27 */ + +#define lirc_device_create device_create + +#endif /* >= 2.6.27 */ + +#endif /* >= 2.6.26 */ + +#define LIRC_DEVFS_PREFIX + +#endif /* >= 2.6.15 */ + +typedef struct class lirc_class_t; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26) + +#define lirc_device_destroy class_device_destroy + +#else + +#define lirc_device_destroy device_destroy + +#endif + +#endif /* >= 2.6.13 */ + +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0) +#define LIRC_HAVE_DEVFS +#define LIRC_HAVE_DEVFS_24 +#endif + +#ifndef LIRC_DEVFS_PREFIX +#define LIRC_DEVFS_PREFIX "usb/" +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 0) +#include +#include +static inline void del_timer_sync(struct timer_list *timerlist) +{ + start_bh_atomic(); + del_timer(timerlist); + end_bh_atomic(); +} +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) +#ifdef daemonize +#undef daemonize +#endif +#define daemonize(name) do { \ + \ + lock_kernel(); \ + \ + exit_mm(current); \ + exit_files(current); \ + exit_fs(current); \ + current->session = 1; \ + current->pgrp = 1; \ + current->euid = 0; \ + current->tty = NULL; \ + sigfillset(¤t->blocked); \ + \ + strcpy(current->comm, name); \ + \ + unlock_kernel(); \ + \ +} while (0) + +/* Not sure when this was introduced, sometime during 2.5.X */ +#define MODULE_PARM_int(x) MODULE_PARM(x, "i") +#define MODULE_PARM_bool(x) MODULE_PARM(x, "i") +#define MODULE_PARM_long(x) MODULE_PARM(x, "l") +#define module_param(x, y, z) MODULE_PARM_##y(x) +#else +#include +#endif /* Linux < 2.6.0 */ + +/* DevFS header */ +#if defined(LIRC_HAVE_DEVFS) +#include +#endif + +#ifdef LIRC_HAVE_DEVFS_24 +#ifdef register_chrdev +#undef register_chrdev +#endif +#define register_chrdev devfs_register_chrdev +#ifdef unregister_chrdev +#undef unregister_chrdev +#endif +#define unregister_chrdev devfs_unregister_chrdev +#endif /* DEVFS 2.4 */ + +#ifndef LIRC_HAVE_SYSFS +#define class_destroy(x) do { } while (0) +#define class_create(x, y) NULL +#define lirc_device_destroy(x, y) do { } while (0) +#define lirc_device_create(x, y, z, xx, yy, zz) 0 +#define IS_ERR(x) 0 +typedef struct class_simple +{ + int notused; +} lirc_class_t; +#endif /* No SYSFS */ + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0) +#define KERNEL_2_5 + +/* + * We still are using MOD_INC_USE_COUNT/MOD_DEC_USE_COUNT in the set_use_inc + * function of all modules for 2.4 kernel compatibility. + * + * For 2.6 kernels reference counting is done in lirc_dev by + * try_module_get()/module_put() because the old approach is racy. + * + */ +#ifdef MOD_INC_USE_COUNT +#undef MOD_INC_USE_COUNT +#endif +#define MOD_INC_USE_COUNT + +#ifdef MOD_DEC_USE_COUNT +#undef MOD_DEC_USE_COUNT +#endif +#define MOD_DEC_USE_COUNT + +#ifdef EXPORT_NO_SYMBOLS +#undef EXPORT_NO_SYMBOLS +#endif +#define EXPORT_NO_SYMBOLS + +#else /* Kernel < 2.5.0 */ + +static inline int try_module_get(struct module *module) +{ + return 1; +} + +static inline void module_put(struct module *module) +{ +} + +#endif /* Kernel >= 2.5.0 */ + +#ifndef MODULE_LICENSE +#define MODULE_LICENSE(x) +#endif + +#ifndef MODULE_PARM_DESC +#define MODULE_PARM_DESC(x, y) +#endif + +#ifndef MODULE_ALIAS_CHARDEV_MAJOR +#define MODULE_ALIAS_CHARDEV_MAJOR(x) +#endif + +#ifndef MODULE_DEVICE_TABLE +#define MODULE_DEVICE_TABLE(x, y) +#endif + +#include +#ifndef IRQ_RETVAL +typedef void irqreturn_t; +#define IRQ_NONE +#define IRQ_HANDLED +#define IRQ_RETVAL(x) +#endif + +#ifndef MOD_IN_USE +#ifdef CONFIG_MODULE_UNLOAD +#define MOD_IN_USE module_refcount(THIS_MODULE) +#else +#error "LIRC modules currently require" +#error " 'Loadable module support ---> Module unloading'" +#error "to be enabled in the kernel" +#endif +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18) +#if !defined(local_irq_save) +#define local_irq_save(flags) do { save_flags(flags); cli(); } while (0) +#endif +#if !defined(local_irq_restore) +#define local_irq_restore(flags) do { restore_flags(flags); } while (0) +#endif +#endif + +#if KERNEL_VERSION(2, 4, 0) <= LINUX_VERSION_CODE +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 22) +#include +static inline char *pci_name(struct pci_dev *pdev) +{ + return pdev->slot_name; +} +#endif /* kernel < 2.4.22 */ +#endif /* kernel >= 2.4.0 */ + +/*************************** I2C specific *****************************/ +#include + +#ifndef I2C_CLIENT_END +#error "********************************************************" +#error " Sorry, this driver needs the new I2C stack. " +#error " You can get it at http://www2.lm-sensors.nu/~lm78/. " +#error "********************************************************" +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) + +#undef i2c_get_clientdata +#define i2c_get_clientdata(client) ((client)->data) + + +#undef i2c_set_clientdata +#define i2c_set_clientdata(client_ptr, new_data) do { \ + (client_ptr)->data = new_data; \ +} while (0) + + +#endif + +/* removed in 2.6.14 */ +#ifndef I2C_ALGO_BIT +# define I2C_ALGO_BIT 0 +#endif + +/* removed in 2.6.16 */ +#ifndef I2C_DRIVERID_EXP3 +# define I2C_DRIVERID_EXP3 0xf003 +#endif + +/*************************** USB specific *****************************/ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0) +#include + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 8) +static inline int usb_kill_urb(struct urb *urb) +{ + return usb_unlink_urb(urb); +} +#endif + +/* removed in 2.6.14 */ +#ifndef URB_ASYNC_UNLINK +#define URB_ASYNC_UNLINK 0 +#endif +#endif + +/*************************** bttv specific ****************************/ + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 15) /* BTTV_* -> BTTV_BOARD_* */ +#define BTTV_BOARD_UNKNOWN BTTV_UNKNOWN +#define BTTV_BOARD_PXELVWPLTVPAK BTTV_PXELVWPLTVPAK +#define BTTV_BOARD_PXELVWPLTVPRO BTTV_PXELVWPLTVPRO +#define BTTV_BOARD_PV_BT878P_9B BTTV_PV_BT878P_9B +#define BTTV_BOARD_PV_BT878P_PLUS BTTV_PV_BT878P_PLUS +#define BTTV_BOARD_AVERMEDIA BTTV_AVERMEDIA +#define BTTV_BOARD_AVPHONE98 BTTV_AVPHONE98 +#define BTTV_BOARD_AVERMEDIA98 BTTV_AVERMEDIA98 +#define BTTV_BOARD_CHRONOS_VS2 BTTV_CHRONOS_VS2 +#define BTTV_BOARD_MIRO BTTV_MIRO +#define BTTV_BOARD_DYNALINK BTTV_DYNALINK +#define BTTV_BOARD_WINVIEW_601 BTTV_WINVIEW_601 +#ifdef BTTV_KWORLD +#define BTTV_BOARD_KWORLD BTTV_KWORLD +#endif +#define BTTV_BOARD_MAGICTVIEW061 BTTV_MAGICTVIEW061 +#define BTTV_BOARD_MAGICTVIEW063 BTTV_MAGICTVIEW063 +#define BTTV_BOARD_PHOEBE_TVMAS BTTV_PHOEBE_TVMAS +#ifdef BTTV_BESTBUY_EASYTV2 +#define BTTV_BOARD_BESTBUY_EASYTV BTTV_BESTBUY_EASYTV +#define BTTV_BOARD_BESTBUY_EASYTV2 BTTV_BESTBUY_EASYTV2 +#endif +#define BTTV_BOARD_FLYVIDEO BTTV_FLYVIDEO +#define BTTV_BOARD_FLYVIDEO_98 BTTV_FLYVIDEO_98 +#define BTTV_BOARD_TYPHOON_TVIEW BTTV_TYPHOON_TVIEW +#ifdef BTTV_FLYVIDEO_98FM +#define BTTV_BOARD_FLYVIDEO_98FM BTTV_FLYVIDEO_98FM +#endif +#define BTTV_BOARD_WINFAST2000 BTTV_WINFAST2000 +#ifdef BTTV_GVBCTV5PCI +#define BTTV_BOARD_GVBCTV5PCI BTTV_GVBCTV5PCI +#endif +#endif /* end BTTV_* -> BTTV_BOARD_* */ + + +/******************************* pm.h *********************************/ + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 11) +typedef u32 pm_message_t; +#endif /* kernel < 2.6.11 */ +#endif /* kernel >= 2.6.0 */ + +/*************************** interrupt.h ******************************/ +/* added in 2.6.18, old defines removed in 2.6.24 */ +#ifndef IRQF_DISABLED +#define IRQF_DISABLED SA_INTERRUPT +#endif +#ifndef IRQF_SHARED +#define IRQF_SHARED SA_SHIRQ +#endif + +/*************************** spinlock.h *******************************/ +/* added in 2.6.11 */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 11) +#define DEFINE_SPINLOCK(x) spinlock_t x = SPIN_LOCK_UNLOCKED +#endif + +/***************************** slab.h *********************************/ +/* added in 2.6.14 */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 14) +static inline void *kzalloc(size_t size, gfp_t flags) +{ + void *ret = kmalloc(size, flags); + if (ret) + memset(ret, 0, size); + return ret; +} +#endif + +/****************************** fs.h **********************************/ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) +static inline unsigned iminor(struct inode *inode) +{ + return MINOR(inode->i_rdev); +} +#endif + +/****************************** bitops.h **********************************/ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24) +#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG)) +#define BIT_WORD(nr) ((nr) / BITS_PER_LONG) +#endif + +#endif /* _KCOMPAT_H */ diff -Nru nct677x-dkms-1.0.1/nct677x-1.0.4/include/lirc_dev.h nct677x-dkms-1.0.4/nct677x-1.0.4/include/lirc_dev.h --- nct677x-dkms-1.0.1/nct677x-1.0.4/include/lirc_dev.h 1970-01-01 00:00:00.000000000 +0000 +++ nct677x-dkms-1.0.4/nct677x-1.0.4/include/lirc_dev.h 2010-10-29 11:46:39.000000000 +0000 @@ -0,0 +1,342 @@ +/* + * LIRC base driver + * + * (L) by Artur Lipowski + * This code is licensed under GNU GPL + * + * $Id: lirc_dev.h,v 1.37 2009/03/15 09:34:00 lirc Exp $ + * + */ + +#ifndef _LINUX_LIRC_DEV_H +#define _LINUX_LIRC_DEV_H + +#ifndef LIRC_REMOVE_DURING_EXPORT +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11) +/* when was it really introduced? */ +#define LIRC_HAVE_KFIFO +#endif +#endif +#define MAX_IRCTL_DEVICES 4 +#define BUFLEN 16 + +#define mod(n, div) ((n) % (div)) + +#include +#include +#ifdef LIRC_HAVE_KFIFO +#include +#endif + +struct lirc_buffer { + wait_queue_head_t wait_poll; + spinlock_t lock; + unsigned int chunk_size; + unsigned int size; /* in chunks */ + /* Using chunks instead of bytes pretends to simplify boundary checking + * And should allow for some performance fine tunning later */ +#ifdef LIRC_HAVE_KFIFO + struct kfifo *fifo; +#else + unsigned int fill; /* in chunks */ + int head, tail; /* in chunks */ + unsigned char *data; +#endif +}; +#ifndef LIRC_HAVE_KFIFO +static inline void lirc_buffer_lock(struct lirc_buffer *buf, + unsigned long *flags) +{ + spin_lock_irqsave(&buf->lock, *flags); +} +static inline void lirc_buffer_unlock(struct lirc_buffer *buf, + unsigned long *flags) +{ + spin_unlock_irqrestore(&buf->lock, *flags); +} +static inline void _lirc_buffer_clear(struct lirc_buffer *buf) +{ + buf->head = 0; + buf->tail = 0; + buf->fill = 0; +} +#endif +static inline void lirc_buffer_clear(struct lirc_buffer *buf) +{ +#ifdef LIRC_HAVE_KFIFO + if (buf->fifo) + kfifo_reset(buf->fifo); +#else + unsigned long flags; + lirc_buffer_lock(buf, &flags); + _lirc_buffer_clear(buf); + lirc_buffer_unlock(buf, &flags); +#endif +} +static inline int lirc_buffer_init(struct lirc_buffer *buf, + unsigned int chunk_size, + unsigned int size) +{ + init_waitqueue_head(&buf->wait_poll); + spin_lock_init(&buf->lock); +#ifndef LIRC_HAVE_KFIFO + _lirc_buffer_clear(buf); +#endif + buf->chunk_size = chunk_size; + buf->size = size; +#ifdef LIRC_HAVE_KFIFO + buf->fifo = kfifo_alloc(size*chunk_size, GFP_KERNEL, &buf->lock); + if (!buf->fifo) + return -ENOMEM; +#else + buf->data = kmalloc(size*chunk_size, GFP_KERNEL); + if (buf->data == NULL) + return -ENOMEM; + memset(buf->data, 0, size*chunk_size); +#endif + return 0; +} +static inline void lirc_buffer_free(struct lirc_buffer *buf) +{ +#ifdef LIRC_HAVE_KFIFO + if (buf->fifo) + kfifo_free(buf->fifo); +#else + kfree(buf->data); + buf->data = NULL; + buf->head = 0; + buf->tail = 0; + buf->fill = 0; + buf->chunk_size = 0; + buf->size = 0; +#endif +} +#ifndef LIRC_HAVE_KFIFO +static inline int _lirc_buffer_full(struct lirc_buffer *buf) +{ + return (buf->fill >= buf->size); +} +#endif +static inline int lirc_buffer_full(struct lirc_buffer *buf) +{ +#ifdef LIRC_HAVE_KFIFO + return kfifo_len(buf->fifo) == buf->size * buf->chunk_size; +#else + unsigned long flags; + int ret; + lirc_buffer_lock(buf, &flags); + ret = _lirc_buffer_full(buf); + lirc_buffer_unlock(buf, &flags); + return ret; +#endif +} +#ifndef LIRC_HAVE_KFIFO +static inline int _lirc_buffer_empty(struct lirc_buffer *buf) +{ + return !(buf->fill); +} +#endif +static inline int lirc_buffer_empty(struct lirc_buffer *buf) +{ +#ifdef LIRC_HAVE_KFIFO + return !kfifo_len(buf->fifo); +#else + unsigned long flags; + int ret; + lirc_buffer_lock(buf, &flags); + ret = _lirc_buffer_empty(buf); + lirc_buffer_unlock(buf, &flags); + return ret; +#endif +} +#ifndef LIRC_HAVE_KFIFO +static inline int _lirc_buffer_available(struct lirc_buffer *buf) +{ + return (buf->size - buf->fill); +} +#endif +static inline int lirc_buffer_available(struct lirc_buffer *buf) +{ +#ifdef LIRC_HAVE_KFIFO + return buf->size - (kfifo_len(buf->fifo) / buf->chunk_size); +#else + unsigned long flags; + int ret; + lirc_buffer_lock(buf, &flags); + ret = _lirc_buffer_available(buf); + lirc_buffer_unlock(buf, &flags); + return ret; +#endif +} +#ifndef LIRC_HAVE_KFIFO +static inline void _lirc_buffer_read_1(struct lirc_buffer *buf, + unsigned char *dest) +{ + memcpy(dest, &buf->data[buf->head*buf->chunk_size], buf->chunk_size); + buf->head = mod(buf->head+1, buf->size); + buf->fill -= 1; +} +#endif +static inline void lirc_buffer_read(struct lirc_buffer *buf, + unsigned char *dest) +{ +#ifdef LIRC_HAVE_KFIFO + if (kfifo_len(buf->fifo) >= buf->chunk_size) + kfifo_get(buf->fifo, dest, buf->chunk_size); +#else + unsigned long flags; + lirc_buffer_lock(buf, &flags); + _lirc_buffer_read_1(buf, dest); + lirc_buffer_unlock(buf, &flags); +#endif +} +#ifndef LIRC_HAVE_KFIFO +static inline void _lirc_buffer_write_1(struct lirc_buffer *buf, + unsigned char *orig) +{ + memcpy(&buf->data[buf->tail*buf->chunk_size], orig, buf->chunk_size); + buf->tail = mod(buf->tail+1, buf->size); + buf->fill++; +} +#endif +static inline void lirc_buffer_write(struct lirc_buffer *buf, + unsigned char *orig) +{ +#ifdef LIRC_HAVE_KFIFO + kfifo_put(buf->fifo, orig, buf->chunk_size); +#else + unsigned long flags; + lirc_buffer_lock(buf, &flags); + _lirc_buffer_write_1(buf, orig); + lirc_buffer_unlock(buf, &flags); +#endif +} +#ifndef LIRC_HAVE_KFIFO +static inline void _lirc_buffer_write_n(struct lirc_buffer *buf, + unsigned char *orig, int count) +{ + int space1; + if (buf->head > buf->tail) + space1 = buf->head - buf->tail; + else + space1 = buf->size - buf->tail; + + if (count > space1) { + memcpy(&buf->data[buf->tail * buf->chunk_size], orig, + space1 * buf->chunk_size); + memcpy(&buf->data[0], orig + (space1 * buf->chunk_size), + (count - space1) * buf->chunk_size); + } else { + memcpy(&buf->data[buf->tail * buf->chunk_size], orig, + count * buf->chunk_size); + } + buf->tail = mod(buf->tail + count, buf->size); + buf->fill += count; +} +#endif +static inline void lirc_buffer_write_n(struct lirc_buffer *buf, + unsigned char *orig, int count) +{ +#ifdef LIRC_HAVE_KFIFO + kfifo_put(buf->fifo, orig, count * buf->chunk_size); +#else + unsigned long flags; + lirc_buffer_lock(buf, &flags); + _lirc_buffer_write_n(buf, orig, count); + lirc_buffer_unlock(buf, &flags); +#endif +} + +struct lirc_driver { + char name[40]; + int minor; + unsigned long code_length; + unsigned int buffer_size; /* in chunks holding one code each */ + int sample_rate; + unsigned long features; + void *data; + int (*add_to_buf) (void *data, struct lirc_buffer *buf); +#ifndef LIRC_REMOVE_DURING_EXPORT + wait_queue_head_t* (*get_queue) (void *data); +#endif + struct lirc_buffer *rbuf; + int (*set_use_inc) (void *data); + void (*set_use_dec) (void *data); + struct file_operations *fops; + struct device *dev; + struct module *owner; +}; +/* name: + * this string will be used for logs + * + * minor: + * indicates minor device (/dev/lirc) number for registered driver + * if caller fills it with negative value, then the first free minor + * number will be used (if available) + * + * code_length: + * length of the remote control key code expressed in bits + * + * sample_rate: + * sample_rate equal to 0 means that no polling will be performed and + * add_to_buf will be triggered by external events (through task queue + * returned by get_queue) + * + * data: + * it may point to any driver data and this pointer will be passed to + * all callback functions + * + * add_to_buf: + * add_to_buf will be called after specified period of the time or + * triggered by the external event, this behavior depends on value of + * the sample_rate this function will be called in user context. This + * routine should return 0 if data was added to the buffer and + * -ENODATA if none was available. This should add some number of bits + * evenly divisible by code_length to the buffer + * + * get_queue: + * this callback should return a pointer to the task queue which will + * be used for external event waiting + * + * rbuf: + * if not NULL, it will be used as a read buffer, you will have to + * write to the buffer by other means, like irq's (see also + * lirc_serial.c). + * + * set_use_inc: + * set_use_inc will be called after device is opened + * + * set_use_dec: + * set_use_dec will be called after device is closed + * + * fops: + * file_operations for drivers which don't fit the current driver model. + * + * Some ioctl's can be directly handled by lirc_dev if the driver's + * ioctl function is NULL or if it returns -ENOIOCTLCMD (see also + * lirc_serial.c). + * + * owner: + * the module owning this struct + * + */ + + +/* following functions can be called ONLY from user context + * + * returns negative value on error or minor number + * of the registered device if success + * contents of the structure pointed by d is copied + */ +extern int lirc_register_driver(struct lirc_driver *d); + +/* returns negative value on error or 0 if success +*/ +extern int lirc_unregister_driver(int minor); + +/* Returns the private data stored in the lirc_driver + * associated with the given device file pointer. + */ +void *lirc_get_pdata(struct file *file); + +#endif diff -Nru nct677x-dkms-1.0.1/nct677x-1.0.4/include/lirc.h nct677x-dkms-1.0.4/nct677x-1.0.4/include/lirc.h --- nct677x-dkms-1.0.1/nct677x-1.0.4/include/lirc.h 1970-01-01 00:00:00.000000000 +0000 +++ nct677x-dkms-1.0.4/nct677x-1.0.4/include/lirc.h 2010-10-29 11:46:39.000000000 +0000 @@ -0,0 +1,105 @@ +/* $Id: lirc.h,v 5.19 2009/08/29 07:52:41 lirc Exp $ */ + +#ifndef _LINUX_LIRC_H +#define _LINUX_LIRC_H + +#if defined(__linux__) +#include +#elif defined(_NetBSD_) +#include +#elif defined(_CYGWIN_) +#define __USE_LINUX_IOCTL_DEFS +#include +#endif + +#define PULSE_BIT 0x01000000 +#define PULSE_MASK 0x00FFFFFF + +typedef int lirc_t; + +/*** lirc compatible hardware features ***/ + +#define LIRC_MODE2SEND(x) (x) +#define LIRC_SEND2MODE(x) (x) +#define LIRC_MODE2REC(x) ((x) << 16) +#define LIRC_REC2MODE(x) ((x) >> 16) + +#define LIRC_MODE_RAW 0x00000001 +#define LIRC_MODE_PULSE 0x00000002 +#define LIRC_MODE_MODE2 0x00000004 +#define LIRC_MODE_CODE 0x00000008 +#define LIRC_MODE_LIRCCODE 0x00000010 +#define LIRC_MODE_STRING 0x00000020 + + +#define LIRC_CAN_SEND_RAW LIRC_MODE2SEND(LIRC_MODE_RAW) +#define LIRC_CAN_SEND_PULSE LIRC_MODE2SEND(LIRC_MODE_PULSE) +#define LIRC_CAN_SEND_MODE2 LIRC_MODE2SEND(LIRC_MODE_MODE2) +#define LIRC_CAN_SEND_CODE LIRC_MODE2SEND(LIRC_MODE_CODE) +#define LIRC_CAN_SEND_LIRCCODE LIRC_MODE2SEND(LIRC_MODE_LIRCCODE) +#define LIRC_CAN_SEND_STRING LIRC_MODE2SEND(LIRC_MODE_STRING) + +#define LIRC_CAN_SEND_MASK 0x0000003f + +#define LIRC_CAN_SET_SEND_CARRIER 0x00000100 +#define LIRC_CAN_SET_SEND_DUTY_CYCLE 0x00000200 +#define LIRC_CAN_SET_TRANSMITTER_MASK 0x00000400 + +#define LIRC_CAN_REC_RAW LIRC_MODE2REC(LIRC_MODE_RAW) +#define LIRC_CAN_REC_PULSE LIRC_MODE2REC(LIRC_MODE_PULSE) +#define LIRC_CAN_REC_MODE2 LIRC_MODE2REC(LIRC_MODE_MODE2) +#define LIRC_CAN_REC_CODE LIRC_MODE2REC(LIRC_MODE_CODE) +#define LIRC_CAN_REC_LIRCCODE LIRC_MODE2REC(LIRC_MODE_LIRCCODE) +#define LIRC_CAN_REC_STRING LIRC_MODE2REC(LIRC_MODE_STRING) + +#define LIRC_CAN_REC_MASK LIRC_MODE2REC(LIRC_CAN_SEND_MASK) + +#define LIRC_CAN_SET_REC_CARRIER (LIRC_CAN_SET_SEND_CARRIER << 16) +#define LIRC_CAN_SET_REC_DUTY_CYCLE (LIRC_CAN_SET_SEND_DUTY_CYCLE << 16) + +#define LIRC_CAN_SET_REC_DUTY_CYCLE_RANGE 0x40000000 +#define LIRC_CAN_SET_REC_CARRIER_RANGE 0x80000000 +#define LIRC_CAN_GET_REC_RESOLUTION 0x20000000 + +#define LIRC_CAN_SEND(x) ((x)&LIRC_CAN_SEND_MASK) +#define LIRC_CAN_REC(x) ((x)&LIRC_CAN_REC_MASK) + +#define LIRC_CAN_NOTIFY_DECODE 0x01000000 + +/*** IOCTL commands for lirc driver ***/ + +#define LIRC_GET_FEATURES _IOR('i', 0x00000000, unsigned long) + +#define LIRC_GET_SEND_MODE _IOR('i', 0x00000001, unsigned long) +#define LIRC_GET_REC_MODE _IOR('i', 0x00000002, unsigned long) +#define LIRC_GET_SEND_CARRIER _IOR('i', 0x00000003, unsigned int) +#define LIRC_GET_REC_CARRIER _IOR('i', 0x00000004, unsigned int) +#define LIRC_GET_SEND_DUTY_CYCLE _IOR('i', 0x00000005, unsigned int) +#define LIRC_GET_REC_DUTY_CYCLE _IOR('i', 0x00000006, unsigned int) +#define LIRC_GET_REC_RESOLUTION _IOR('i', 0x00000007, unsigned int) + +/* code length in bits, currently only for LIRC_MODE_LIRCCODE */ +#define LIRC_GET_LENGTH _IOR('i', 0x0000000f, unsigned long) + +#define LIRC_SET_SEND_MODE _IOW('i', 0x00000011, unsigned long) +#define LIRC_SET_REC_MODE _IOW('i', 0x00000012, unsigned long) +/* Note: these can reset the according pulse_width */ +#define LIRC_SET_SEND_CARRIER _IOW('i', 0x00000013, unsigned int) +#define LIRC_SET_REC_CARRIER _IOW('i', 0x00000014, unsigned int) +#define LIRC_SET_SEND_DUTY_CYCLE _IOW('i', 0x00000015, unsigned int) +#define LIRC_SET_REC_DUTY_CYCLE _IOW('i', 0x00000016, unsigned int) +#define LIRC_SET_TRANSMITTER_MASK _IOW('i', 0x00000017, unsigned int) + +/* + * to set a range use + * LIRC_SET_REC_DUTY_CYCLE_RANGE/LIRC_SET_REC_CARRIER_RANGE with the + * lower bound first and later + * LIRC_SET_REC_DUTY_CYCLE/LIRC_SET_REC_CARRIER with the upper bound + */ + +#define LIRC_SET_REC_DUTY_CYCLE_RANGE _IOW('i', 0x0000001e, unsigned int) +#define LIRC_SET_REC_CARRIER_RANGE _IOW('i', 0x0000001f, unsigned int) + +#define LIRC_NOTIFY_DECODE _IO('i', 0x00000020) + +#endif diff -Nru nct677x-dkms-1.0.1/nct677x-1.0.4/src/lirc-nct677x-lirc0.8.6.patch nct677x-dkms-1.0.4/nct677x-1.0.4/src/lirc-nct677x-lirc0.8.6.patch --- nct677x-dkms-1.0.1/nct677x-1.0.4/src/lirc-nct677x-lirc0.8.6.patch 1970-01-01 00:00:00.000000000 +0000 +++ nct677x-dkms-1.0.4/nct677x-1.0.4/src/lirc-nct677x-lirc0.8.6.patch 2009-12-31 00:38:46.000000000 +0000 @@ -0,0 +1,7 @@ +--- lirc.hwdb 2009-12-17 12:31:07.539760680 +0100 ++++ lirc.hwdb.new 2009-12-18 09:18:02.584041023 +0100 +@@ -147,3 +147,4 @@ + VLSystem MPlay Blast;mplay;none;hw_mplay;vlsystem/lircd.conf.mplay; + VLSystem MPlay Mini;mplay;none;hw_mplay;vlsystem/lircd.conf.mplay; + Windows Media Center Transceivers/Remotes (all);mceusb;lirc_dev lirc_mceusb;hw_default;mceusb/lircd.conf.mceusb; ++Nuvoton Transceivers/Remotes;lirc_wb677;lirc_dev lirc_wb677;hw_default;lirc_wb677/lircd.conf.wb677; diff -Nru nct677x-dkms-1.0.1/nct677x-1.0.4/src/lirc_wb677_common_extern.h nct677x-dkms-1.0.4/nct677x-1.0.4/src/lirc_wb677_common_extern.h --- nct677x-dkms-1.0.1/nct677x-1.0.4/src/lirc_wb677_common_extern.h 1970-01-01 00:00:00.000000000 +0000 +++ nct677x-dkms-1.0.4/nct677x-1.0.4/src/lirc_wb677_common_extern.h 2010-10-29 11:53:10.000000000 +0000 @@ -0,0 +1,119 @@ +#ifndef __LIRC_WB677_COMMON_EXTERN_HEADER__ +#define __LIRC_WB677_COMMON_EXTERN_HEADER__ + +#include + +#include "../include/lirc.h" +#include "../include/kcompat.h" +#include "../include/lirc_dev.h" + +extern char *DRVNAME; + +/* chip id string, at most 7 characters */ +extern char *chip_id; + + + + +/* allow show debug messages + * without additional debug setting, only show current IRQ number, I/O port and final decode output */ +/*//#define IR_667_DEBUG*/ + +/* show debug message while decode mce keyboard and mouse signals */ +#ifdef IR_667_DEBUG +/*//#define ALLOW_DEBUG_DECODE*/ +#endif + +/* show incoming interrupt signals + * may block machine, mask it if sure interrupt signal is good */ +#ifdef IR_667_DEBUG +/*//#define ALLOW_DEBUG_INTERRUPT*/ +#endif + +/* show received infrared pulse and cancel decode functions, mask it in stable version + * it will stop decode MCE controller, keyboard and mouse + * mask it if want to decode incoming signals + */ +#ifdef IR_667_DEBUG +/*//#define ALLOW_DEBUG_PRINT_PULSE*/ +#endif + +/* show debug message while set WAKE UP key + * it will print cir_wake buf message while setting wake up key + * mask it in stable version + */ +#ifdef IR_667_DEBUG +#define ALLOW_DEBUG_WAKE +#endif + +/* show STUDY debug messages */ +#ifdef IR_667_DEBUG +#define ALLOW_DEBUG_STUDY +#endif + +/* show ioctl debug messages */ +#ifdef IR_667_DEBUG +#define ALLOW_DEBUG_IOCTL +#endif + +/* step debug */ +#ifdef IR_667_DEBUG +#define ALLOW_DEBUG_STEP +#endif + +#ifdef ALLOW_DEBUG_STEP +#define STEP_DBG \ + do { \ + printk("w83667hg_ir step debug: %s, %d\n", __FILE__, __LINE__); \ + } while (0); +#else +#define STEP_DBG +#endif + +#ifdef ALLOW_DEBUG_PRINT_PULSE +/* print current received ir pulse + * it will output all data, clean CIR_IRSTS so make all following irq_handler ignore + */ +void debug_print_pulse(void); + +void debug_print_wake_pulse(void); +#endif + + + + +/* register lirc device & buffer */ + +/* mininum value 76, recommend 256 */ +#define IRCTL_BUF_LIMIT 2048 + + +struct irctl { + struct input_dev *input_dev; /* allocate by input_init */ + struct lirc_buffer *lirc_buffer; + struct lirc_driver *lirc_plugin; + spinlock_t lock; + /* for controller */ + lirc_t lircdata; + u8 ctrl_fix_head; /* fix controller not sync problem*/ + /* for keyboard */ + u8 pressed_keycode; /* initialize as 0*/ + u8 pressed_shiftmask; /* initialize as 0*/ + /* for decode */ + u8 buf[IRCTL_BUF_LIMIT]; + unsigned int buf_count; /* init as 0, reset 0 after decode*/ + unsigned int cur_buf_num; /* init as 0, set as 0 while clean*/ + /* for study */ +#define ST_STUDY_NONE 0x0 +#define ST_STUDY_START 0x01 +#define ST_STUDY_CARRIER 0x02 +#define ST_STUDY_ALL_RECV 0x04 + u8 study_state; + /* carrier period = 1 / frequency */ + unsigned int carrier; + wait_queue_head_t queue; +}; + +extern unsigned int usb_kbd_keycode[256]; + +#endif diff -Nru nct677x-dkms-1.0.1/nct677x-1.0.4/src/lirc_wb677.h nct677x-dkms-1.0.4/nct677x-1.0.4/src/lirc_wb677.h --- nct677x-dkms-1.0.1/nct677x-1.0.4/src/lirc_wb677.h 1970-01-01 00:00:00.000000000 +0000 +++ nct677x-dkms-1.0.4/nct677x-1.0.4/src/lirc_wb677.h 2010-01-19 09:33:28.000000000 +0000 @@ -0,0 +1,683 @@ +/* +* LIRC driver for Nuvoton w83667hg/w83677hg-i +* +* Copyright (C) 2009 Nuvoton PS Team +* +* 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. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +* USA +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*//#include */ +#include + +#include +#include + +#include +#include +#include + + + +#include "lirc_wb677_common_extern.h" + + + +/* CIR settings */ + +/* total length of CIR and CIR WAKE */ +#define CIR_IOREG_LENGTH 0x0f + +/* RX limit length, 8 high bits for SLCH, 8 low bits for SLCL + * 0x7d0 = 2000 */ +#define CIR_RX_LIMIT_COUNT 0x7d0 + +/* CIR Regs */ +#define CIR_IRCON 0x00 +#define CIR_IRSTS 0x01 +#define CIR_IREN 0x02 +#define CIR_RXFCONT 0x03 +#define CIR_CP 0x04 +#define CIR_CC 0x05 +#define CIR_SLCH 0x06 +#define CIR_SLCL 0x07 +#define CIR_FIFOCON 0x08 +#define CIR_IRFIFOSTS 0x09 +#define CIR_SRXFIFO 0x0A +#define CIR_TXFCONT 0x0B +#define CIR_STXFIFO 0x0C +#define CIR_FCCH 0x0D +#define CIR_FCCL 0x0E +#define CIR_IRFSM 0x0F + +/* CIR IRCON settings */ +#define CIR_IRCON_RECV 0x80 +#define CIR_IRCON_WIREN 0x40 +#define CIR_IRCON_TXEN 0x20 +#define CIR_IRCON_RXEN 0x10 +#define CIR_IRCON_WRXINV 0x08 +#define CIR_IRCON_RXINV 0x04 + +#define CIR_IRCON_SAMPLE_PERIOD_SEL_1 0x00 +#define CIR_IRCON_SAMPLE_PERIOD_SEL_25 0x01 +#define CIR_IRCON_SAMPLE_PERIOD_SEL_50 0x02 +#define CIR_IRCON_SAMPLE_PERIOD_SEL_100 0x03 + +/* select sample period as 50us */ +#define CIR_IRCON_SAMPLE_PERIOD_SEL CIR_IRCON_SAMPLE_PERIOD_SEL_50 + +/* CIR IRSTS settings */ +#define CIR_IRSTS_RDR 0x80 +#define CIR_IRSTS_RTR 0x40 +#define CIR_IRSTS_PE 0x20 +#define CIR_IRSTS_RFO 0x10 +#define CIR_IRSTS_TE 0x08 +#define CIR_IRSTS_TTR 0x04 +#define CIR_IRSTS_TFU 0x02 +#define CIR_IRSTS_GH 0x01 + +/* CIR IREN settings */ +#define CIR_IREN_RDR 0x80 +#define CIR_IREN_RTR 0x40 +#define CIR_IREN_PE 0x20 +#define CIR_IREN_RFO 0x10 +#define CIR_IREN_TE 0x08 +#define CIR_IREN_TTR 0x04 +#define CIR_IREN_TFU 0x02 +#define CIR_IREN_GH 0x01 + +/* CIR FIFOCON settings */ +#define CIR_FIFOCON_TXFIFOCLR 0x80 + +#define CIR_FIFOCON_TX_TRIGGER_LEV_31 0x00 +#define CIR_FIFOCON_TX_TRIGGER_LEV_24 0x10 +#define CIR_FIFOCON_TX_TRIGGER_LEV_16 0x20 +#define CIR_FIFOCON_TX_TRIGGER_LEV_8 0x30 + +/* select TX trigger level as 16 */ +#define CIR_FIFOCON_TX_TRIGGER_LEV CIR_FIFOCON_TX_TRIGGER_LEV_16 + +#define CIR_FIFOCON_RXFIFOCLR 0x08 + +#define CIR_FIFOCON_RX_TRIGGER_LEV_1 0x00 +#define CIR_FIFOCON_RX_TRIGGER_LEV_8 0x01 +#define CIR_FIFOCON_RX_TRIGGER_LEV_16 0x02 +#define CIR_FIFOCON_RX_TRIGGER_LEV_24 0x03 + +/* select RX trigger level as 1 */ +#define CIR_FIFOCON_RX_TRIGGER_LEV CIR_FIFOCON_RX_TRIGGER_LEV_1 + +/* CIR IRFIFOSTS settings */ +#define CIR_IRFIFOSTS_IR_PENDING 0x80 +#define CIR_IRFIFOSTS_RX_GS 0x40 +#define CIR_IRFIFOSTS_RX_FTA 0x20 +#define CIR_IRFIFOSTS_RX_EMPTY 0x10 +#define CIR_IRFIFOSTS_RX_FULL 0x08 +#define CIR_IRFIFOSTS_TX_FTA 0x04 +#define CIR_IRFIFOSTS_TX_EMPTY 0x02 +#define CIR_IRFIFOSTS_TX_FULL 0x01 + + +/* CIR WAKE UP Regs */ +#define CIR_WAKE_IRCON 0x00 +#define CIR_WAKE_IRSTS 0x01 +#define CIR_WAKE_IREN 0x02 +#define CIR_WAKE_FIFO_CMP_DEEP 0x03 +#define CIR_WAKE_FIFO_CMP_TOL 0x04 +#define CIR_WAKE_FIFO_COUNT 0x05 +#define CIR_WAKE_SLCH 0x06 +#define CIR_WAKE_SLCL 0x07 +#define CIR_WAKE_FIFOCON 0x08 +#define CIR_WAKE_SRXFSTS 0x09 +#define CIR_WAKE_SAMPLE_RX_FIFO 0x0A +#define CIR_WAKE_WR_FIFO_DATA 0x0B +#define CIR_WAKE_RD_FIFO_ONLY 0x0C +#define CIR_WAKE_RD_FIFO_ONLY_IDX 0x0D +#define CIR_WAKE_FIFO_IGNORE 0x0E +#define CIR_WAKE_IRFSM 0x0F + +/* CIR WAKE UP IRCON settings */ +#define CIR_WAKE_IRCON_DEC_RST 0x80 +#define CIR_WAKE_IRCON_MODE1 0x40 +#define CIR_WAKE_IRCON_MODE0 0x20 +#define CIR_WAKE_IRCON_RXEN 0x10 +#define CIR_WAKE_IRCON_R 0x08 +#define CIR_WAKE_IRCON_RXINV 0x04 + +/* select a same sample period like cir register */ +#define CIR_WAKE_IRCON_SAMPLE_PERIOD_SEL CIR_IRCON_SAMPLE_PERIOD_SEL_50 + +/* CIR WAKE UP IRSTS settings */ +#define CIR_WAKE_IRSTS_RDR 0x80 +#define CIR_WAKE_IRSTS_RTR 0x40 +#define CIR_WAKE_IRSTS_PE 0x20 +#define CIR_WAKE_IRSTS_RFO 0x10 +#define CIR_WAKE_IRSTS_GH 0x08 +#define CIR_WAKE_IRSTS_IR_PENDING 0x01 + +/* CIR WAKE UP IREN settings */ +#define CIR_WAKE_IREN_RDR 0x80 +#define CIR_WAKE_IREN_RTR 0x40 +#define CIR_WAKE_IREN_PE 0x20 +#define CIR_WAKE_IREN_RFO 0x10 +#define CIR_WAKE_IREN_TE 0x08 +#define CIR_WAKE_IREN_TTR 0x04 +#define CIR_WAKE_IREN_TFU 0x02 +#define CIR_WAKE_IREN_GH 0x01 + +/* CIR WAKE FIFOCON settings */ +#define CIR_WAKE_FIFOCON_RXFIFOCLR 0x08 + +#define CIR_WAKE_FIFOCON_RX_TRIGGER_LEV_67 0x00 +#define CIR_WAKE_FIFOCON_RX_TRIGGER_LEV_66 0x01 +#define CIR_WAKE_FIFOCON_RX_TRIGGER_LEV_65 0x02 +#define CIR_WAKE_FIFOCON_RX_TRIGGER_LEV_64 0x03 + +/* select WAKE UP RX trigger level as 67 */ +#define CIR_WAKE_FIFOCON_RX_TRIGGER_LEV CIR_WAKE_FIFOCON_RX_TRIGGER_LEV_67 + +/* CIR WAKE SRXFSTS settings */ +#define CIR_WAKE_IRFIFOSTS_RX_GS 0x80 +#define CIR_WAKE_IRFIFOSTS_RX_FTA 0x40 +#define CIR_WAKE_IRFIFOSTS_RX_EMPTY 0x20 +#define CIR_WAKE_IRFIFOSTS_RX_FULL 0x10 + + + + +/* Config Regs */ + +/* Chip Control Regs */ +#define cr_cfg_idx 0x2e +#define cr_cfg_dat 0x2f + +#define cr_cfg_idx2 0x4e +#define cr_cfg_dat2 0x4f + +static u8 CFG_idx = cr_cfg_idx; +static u8 CFG_dat = cr_cfg_dat; + +#define CHIP_ID_HIGH_ADDR 0x20 +#define CHIP_ID_LOW_ADDR 0x21 + +#define CHIP_ID_HIGH 0xB4 +#define CHIP_ID_LOW 0x73 + +#define ACTIVE_LOG_DEV 0x01 +#define DEACTIVE_LOG_DEV 0x0 + +#define CIR_LOG_DEV 0x06 + +#define ACPI_LOG_DEV 0x0A + +#define ENABLE_CIR_WAKE 0x08 +#define DISABLE_CIR_WAKE 0xF7 + +#define ENABLE_CIR_INTR_OF_MOUSE_IRQ 0x80 +#define DISABLE_CIR_INTR_OF_MOUSE_IRQ 0x7F + +#define ENABLE_PME_INTR_OF_CIR_PASS 0x08 +#define DISABLE_PME_INTR_OF_CIR_PASS 0xF7 + +#define CIR_WAKE_LOG_DEV 0x0E + + +/* read/update registers functions */ + +/* enter extended function mode */ +static inline void cr_enter_ext(void); + +/* exit extended function mode */ +static inline void cr_exit_ext(void); + +/* select logical device */ +static inline void cr_select_log_dev(int cr); + +static inline void cr_update(int dat, int cr); + +static inline u8 cr_read(int cr); + +/* update cr register without change other bits */ +static inline void cr_safe_update(u8 dat, int cr); + +/* clear cr register without change other bits */ +static inline void cr_safe_clear(u8 dat, int cr); + + + +/* read/write cir registers */ + +static inline void cir_update(u8 dat, int cir); + +static u8 cir_read(int cir); + +/* read/write cir wake registers */ + +static inline void cir_wake_update(u8 dat, int cir); + +static u8 cir_wake_read(int cir); + + +/* dump current cir registers */ +static void cir_dump_reg(void); + +/* dump current cir wake up registers */ +static void cir_wake_dump_reg(void); + + + + + +/* driver module load/unload functions */ + +/* Config Registers init */ +/* + * initialize cr, cir, apci, cir wake logical devices + * open these devices and irq + */ +static int w83667hg_cr_init(void); + +/* Config Registers uninit */ +/* + * close cir and cir wake logical devices + */ +static void w83667hg_cr_uninit(void); + + +/* register input device (keyboard and mouse) + * + */ + +/* Define it for decoding keyboard and mouse in driver */ +#define DECODE_KEYBOARD_MOUSE + +/* this is the keycode table of US-EN layout keyboard + * modify it to support other layout keyboard + */ +unsigned int usb_kbd_keycode[256] = { + 0, 0, 0, 0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38, + 50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44, 2, 3, + 4, 5, 6, 7, 8, 9, 10, 11, 28, 1, 14, 15, 57, 12, 13, 26, + 27, 43, 43, 39, 40, 41, 51, 52, 53, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 87, 88, 99, 70, 119, 110, 102, 104, 111, 107, 109, 106, + 105, 108, 103, 69, 98, 55, 74, 78, 96, 79, 80, 81, 75, 76, 77, 71, + 72, 73, 82, 83, 86, 127, 116, 117, 183, 184, 185, 186, 187, 188, 189, 190, + 191, 192, 193, 194, 134, 138, 130, 132, 128, 129, 131, 137, 133, 135, 136, 113, + 115, 114, 0, 0, 0, 121, 0, 89, 93, 124, 92, 94, 95, 0, 0, 0, + 122, 123, 90, 91, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 29, 42, 56, 125, 97, 54, 100, 126, 164, 166, 165, 163, 161, 115, 114, 113, + 150, 158, 159, 128, 136, 177, 178, 176, 142, 152, 173, 140 +}; + +/* input device name, locate in /sys/input/inputNUM/name */ +static char *INPUTNAME = "MCE Remote Keyboard"; + +static struct input_id w83667hg_input_id = { + .bustype = BUS_HOST, /* comunicate 667 by HOST, or I2C ? */ + .vendor = 0x1050, /* Winbond PCI VENDOR ID */ + .product = 1, /* for basic devices, like keyboard & mouse */ + .version = 0, /* ignore it */ +}; + + +static int w83667hg_input_open(struct input_dev *cur_input_dev); + +static void w83667hg_input_close(struct input_dev *cur_input_dev); + +static struct input_dev *w83667hg_input_init(void); + +static void w83667hg_input_uninit(struct input_dev *cur_input_dev); + +/* internal call for register lirc */ +static int lirc_set_use_inc(void *data); + +static void lirc_set_use_dec(void *data); + + + +static struct ir_recv_t { + spinlock_t lock; + u8 buf[IRCTL_BUF_LIMIT]; + unsigned int buf_count; + wait_queue_head_t queue; + /* for wake */ +#define ST_WAKE_NONE 0x0 +#define ST_WAKE_START 0x01 +#define ST_WAKE_FINISH 0x02 + u8 wake_state; + /* for recv */ +#define ST_RECV_WAIT_7F 0x01 +#define ST_RECV_WAIT_HEAD 0x02 +#define ST_RECV_WAIT_SILENT_END 0x04 + u8 recv_state; +} w83667hg_ir_recv; + +static struct ir_send_t { + spinlock_t lock; + u8 buf[IRCTL_BUF_LIMIT]; + unsigned int buf_count; + unsigned int cur_buf_num; + wait_queue_head_t queue; + /* for send */ +#define ST_SEND_NONE 0x0 +#define ST_SEND_REQUEST 0x02 +#define ST_SEND_REPLY 0x04 + u8 send_state; +} w83667hg_ir_send; + +/* We initialise it at lirc_wb667_init() becuase of lirc group does not allow to initialise static varialbe to null.*/ +static struct input_dev *w83667hg_input_dev; + +/* We initialise it at lirc_wb667_init() becuase of lirc group does not allow to initialise static varialbe to null.*/ +static struct lirc_driver *w83667hg_lirc_plugin; + +#define LIRCBUF_SIZE 256 + +/* We initialise it at lirc_wb667_init() becuase of lirc group does not allow to initialise static varialbe to null.*/ +static struct lirc_buffer *w83667hg_lirc_buffer; + +static void w83667hg_ir_recv_init(struct ir_recv_t *ir_recv); + +static void w83667hg_ir_send_init(struct ir_send_t *ir_send); + +static int w83667hg_irctl_init(struct irctl *ir); + +static void w83667hg_irctl_uninit(struct irctl *ir); + + + + +/* MCE CIR signal length, related on sample period */ + +/* MCE CIR controller signal length: about 43ms + * 43ms / 50us (sample period) * 0.85 (inaccuracy) + */ +#define CONTROLLER_BUF_LEN_MIN 830 + +/* MCE CIR keyboard signal length: about 26ms + * 26ms / 50us (sample period) * 0.85 (inaccuracy) + */ +#define KEYBOARD_BUF_LEN_MAX 650 +#define KEYBOARD_BUF_LEN_MIN 610 + +/* MCE CIR mouse signal length: about 24ms + * 24ms / 50us (sample period) * 0.85 (inaccuracy) + */ +#define MOUSE_BUF_LEN_MIN 565 + + +#define CIR_SAMPLE_PERIOD 50 +#define CIR_SAMPLE_LOW_INACCURACY 0.85 + + +/* MAX silence time that driver will sent to lirc */ +#define MAX_SILENCE_TIME 60000 + + +/* fops */ +/* set carrier frequency by ioctl IR_IOSETCARRIER + * + * that value can be get by ioctl value IR_IOGETCARRIER + * on 667, set carrier on 2 registers: CP & CC + * always set CP as 0x81 + * set CC by SPEC, CC = 3MHz/carrier - 1 + */ +static int w83667hg_set_carrier(unsigned int *carrier); + +static int lirc_ioctl(struct inode *node, struct file *filep, unsigned int cmd, + unsigned long arg); + +/* lirc_write + * + * 1) clean TX fifo first (handled by AP) + * 2) copy data from user space + * 3) open TX interrupt: TTR & TFU + * 4) send 9 pulses to open TTR + * in interrupt_handler: + * 5) send all data out + * go back to write(): + * 6) close TX interrupt + * + * The key problem of this function is user space data may larger than + * driver's data buf length. So lirc_wirte() only copy IRCTL_BUF_LIMIT data to + * buf. And keep current copied data buf num in cur_buf_num. But driver's buf + * number may larger than TXFCONT (0xFF). So in interrupt_handler, it has to + * set TXFCONT as 0xff, until buf_count less than 0xff. + * The confustion is cur_buf_num in decode, study and send is designed on + * different meaning. + * + */ +static ssize_t lirc_write(struct file *file, const char *buf, size_t n, loff_t * ppos); + + + +/* 1) clean lircdata and buf_count in irctl struct + * 2) clean RX and TX fifo + */ +static void w83667hg_clean_data(struct ir_recv_t *ir_recv, struct irctl *ir); + + + + +/* send 1 recorded controller signal to lirc */ +static void w83667hg_send_packet_to_lirc_1(struct irctl *ir, lirc_t *val); + +/* this value copy from lirc_mod_mce */ +#if CIR_IRCON_SAMPLE_PERIOD_SEL == CIR_IRCON_SAMPLE_PERIOD_SEL_100 + #define MCE_TIME_UNIT 100 +#elif CIR_IRCON_SAMPLE_PERIOD_SEL == CIR_IRCON_SAMPLE_PERIOD_SEL_50 + #define MCE_TIME_UNIT 50 +#elif CIR_IRCON_SAMPLE_PERIOD_SEL == CIR_IRCON_SAMPLE_PERIOD_SEL_25 + #define MCE_TIME_UNIT 25 +#else + #define MCE_TIME_UNIT 1 +#endif + +/* recode mce controller signal and send to lirc + * + * recode steps: + * 1) high pulse, +128 + * 2) low pulse, do nothing + * 3) keycode = pulse * 50 + * 4) sync head: PULSE_MASK (0xFF FFFF) + * 5) 1, |PULSE_BIT (0x100 0000) + * 0, +keycode + * + * function steps: + * 0) clean lircdata[] + * 1) jump head, put PULSE_BIT in lircdata[0] + * 2) normal decode, "10"=>1 |PULSE_BIT + * save in lircdata[] + * 3) send lircdata[] to lirc + */ +static void w83667hg_submit_controller(struct irctl *ir); + + +/* copy data from hardware fifo to driver buf + * + * 1. initial state is WAIT_7F + * 2. if data is not 0x7f, copy data from hardware fifo to struct ir_recv buf + * 3. if data is 0x7f, set recv_state as WAIT_HEAD, copy data from ir_recv to irctl + * 4. depend on received buf length to select submit_ function + * 5. set irctl buf len as 0 + * 5. receive data until data is not 0x7f, drop received 0x7f data, set recv_state as WAIT_7F again + * + * in normal, there are 3 parts in one infrared signal: + * 1. not silent pulse (ST_WAIT_7F) + * 2. 0x7f silent pulse (ST_WAIT_HEAD) + * 3. silent pulse shorter than 0x7f (ST_WAIT_HEAD) + * + * so this function copy signal part 1 and a 0x7f (for decode) to submit_() functions. + * when receive 0x7f, this function copy data from ir_recv to irctl, and wait for next high pulse. + */ +static void w83667hg_recv(struct ir_recv_t *ir_recv, struct irctl *ir); + + +/* as VISTA MCE definition, valid carrier value */ +#define MAX_CARRIER 60000 +#define MIN_CARRIER 30000 + +/* receive function for STUDY + * + * 0. not receive 0x80, copy received data to ir_recv buf + * when get 0x80, it means user released controller, and only need process received data + * 1. get carrier + * 2. get pulse + */ +static void w83667hg_study_recv(struct ir_recv_t *ir_recv, struct irctl *ir); + +static irqreturn_t w83667hg_wake_interrupt_handler(int irq, void *dev); + +static irqreturn_t w83667hg_interrupt_handler(int irq, void *dev); + + +/* pnp device */ +#ifdef CONFIG_PNP + + +/* CIR and CIR WAKE */ +static const struct pnp_device_id pnp_dev_table[] = { + { "WEC0530", 0 }, /* CIR */ + { "NTN0530", 0 }, /* CIR for new chip's pnp id*/ + { "", 0 }, +}; + + +MODULE_DEVICE_TABLE(pnp, pnp_dev_table); + +static int __devinit lirc_wb667_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id); + +static void __devexit lirc_wb667_pnp_remove(struct pnp_dev *dev); + +/* before suspend + * 1. set all states as NONE + * 2. close CIR and WAKE interrupt + * 3. close CIR and WAKE cr + * 4. close input + */ +static int lirc_wb667_pnp_suspend(struct pnp_dev *dev, pm_message_t state); + +/* resume all register and input device + */ +static int lirc_wb667_pnp_resume(struct pnp_dev *dev); + +/* We initialise it as lirc_wb667_init because lirc group does not allow us to initialise static vaiable as 0 here. */ +static unsigned int nopnp; + +#else + +/* We initialise it as lirc_lirc_wb667_init because lirc group does not allow us to initialise static vaiable as 0 here. */ +static unsigned int nopnp; + +#endif + + +/* create io region for cir and cir wake + * create irq handler + * create dev and data struct + */ +static int w83667hg_cir_probe(void); + +/* uninit cir, cir wake, dev and data struct, release irq and io port */ +static void w83667hg_cir_remove(void); + + +static int lirc_wb667_init(void); + +void lirc_wb667_uninit(void); + + +/* + * 1. init cr + * 2. init input + * 3. init lirc buffer, register, irctl + * 4. init 667 cir dev, req_region, req_irq + */ +/*int init_module(void); +void cleanup_module(void);*/ +int init_module_wb667(void); +void cleanup_module_wb667(void); + +MODULE_DESCRIPTION("LIRC driver for Nuvoton W83667HG-A & W83677HG CIR"); +MODULE_AUTHOR("Nuvoton PS Team"); +MODULE_LICENSE("GPL"); + +/* device file name, locate in /dev/ directory */ +/*//static char *DRVNAME = "w83667hg_ir";*/ +/* FIXME, stable name*/ +char *DRVNAME = "lirc_wb677"; +module_param(DRVNAME, charp, S_IRUGO); +MODULE_PARM_DESC(DRVNAME, "Device file name in /dev/ and /sys/class/."); + +/* platform driver name to register */ +#define PLATNAME "lirc_wb677_cir" +#define PLATNAME_W "lirc_wb667_wake" + +/* device file major number */ +#define CIR_MAJOR 229 + +/* cir device base address */ +static u16 CIR_BASE = 0x240; +module_param(CIR_BASE, ushort, S_IRUGO); +MODULE_PARM_DESC(CIR_BASE, "Base IO port address of 667/677 CIR device."); + +/* cir base i/o address */ +static unsigned int cir_address; + +/* cir irq */ +static ushort CIR_IRQ_NUM = 5; +module_param(CIR_IRQ_NUM, ushort, S_IRUGO); +MODULE_PARM_DESC(CIR_IRQ_NUM, "IRQ number for 667/677 CIR device."); + +/* handle cir wake up request in driver or not */ +#define ENABLE_CIR_WAKE_IRQ + +/* cir wake up device base address */ +static u16 CIR_WAKE_BASE = 0x250; +module_param(CIR_WAKE_BASE, ushort, S_IRUGO); +MODULE_PARM_DESC(CIR_WAKE_BASE, "Base IO port address of 667/677 CIR WAKE device."); + +/* cir wake up base i/o address */ +static unsigned int cir_wake_address; + +/* cir wake up irq */ +static ushort CIR_WAKE_IRQ_NUM = 5; +module_param(CIR_WAKE_IRQ_NUM, ushort, S_IRUGO); +MODULE_PARM_DESC(CIR_WAKE_IRQ_NUM, "IRQ number for 667/677 CIR WAKE device."); + +/* nopnp option */ +#ifdef CONFIG_PNP +module_param(nopnp, uint, S_IRUGO); +MODULE_PARM_DESC(nopnp, "Scan for device instead of relying on PNP. (default 0)"); +#endif + +/*//EXPORT_NO_SYMBOLS;*/ + + + diff -Nru nct677x-dkms-1.0.1/nct677x-1.0.4/src/lirc_wb677_main.c nct677x-dkms-1.0.4/nct677x-1.0.4/src/lirc_wb677_main.c --- nct677x-dkms-1.0.1/nct677x-1.0.4/src/lirc_wb677_main.c 1970-01-01 00:00:00.000000000 +0000 +++ nct677x-dkms-1.0.4/nct677x-1.0.4/src/lirc_wb677_main.c 2010-01-21 13:40:36.000000000 +0000 @@ -0,0 +1,1717 @@ +#define _GNU_SOURCE +#include "lirc_wb677.h" +#include "lirc_wb677_mouse_kbd.h" +#include "wb83677hg_ir.h" + +struct irctl w83667hg_irctl; + +/* chip id string, at most 7 characters */ +char *chip_id = "w677hga"; + + + + +/* enter extended function mode */ +static inline void cr_enter_ext(void) +{ + outb(0x87, CFG_idx); + outb(0x87, CFG_idx); + + if (0xff == cr_read(0x20)) { + CFG_idx = cr_cfg_idx2; + CFG_dat = cr_cfg_dat2; + outb(0x87, CFG_idx); + outb(0x87, CFG_idx); + } +} + + +/* exit extended function mode */ +static inline void cr_exit_ext(void) +{ + outb(0xaa, CFG_idx); +} + +/* select logical device */ +static inline void cr_select_log_dev(int cr) +{ + outb(0x07, CFG_idx); + outb(cr, CFG_dat); +} + +static inline void cr_update(int dat, int cr) +{ + outb(cr, CFG_idx); + outb(dat, CFG_dat); +} + +static inline u8 cr_read(int cr) +{ + outb(cr, CFG_idx); + return inb(CFG_dat); +} + +static inline void cr_safe_update(u8 dat, int cr) +{ + cr_update(cr_read(cr) | dat, cr); +} + +static inline void cr_safe_clear(u8 dat, int cr) +{ + cr_update(cr_read(cr) & dat, cr); +} + + +/* read/write cir registers */ + +static inline void cir_update(u8 dat, int cir) +{ + outb(dat, cir_address + (cir & 0xff)); +} + +static u8 cir_read(int cir) +{ + u8 val; + + val = inb(cir_address + (cir & 0xff)); + + return val; +} + +static inline void cir_wake_update(u8 dat, int cir) +{ + + outb(dat, cir_wake_address + (cir & 0xff)); + +} + +static u8 cir_wake_read(int cir) +{ + u8 val; + + val = inb(cir_wake_address + (cir & 0xff)); + + return val; +} + +static void cir_dump_reg(void) +{ + cr_enter_ext(); + printk("Dump CIR CR logical device:\n"); + cr_select_log_dev(CIR_LOG_DEV); + printk("CR CIR ACTIVE : 0x%x\n", cr_read(0x30)); + printk("CR CIR BASE ADDR: 0x%x\n", (cr_read(0x61) << 8)|cr_read(0x60)); + printk("CR CIR IRQ NUM: 0x%x\n", cr_read(0x70)); + cr_exit_ext(); + + printk("Dump CIR Registers\n"); + printk("CIR IRCON: 0x%x\n", cir_read(CIR_IRCON)); + printk("CIR IRSTS: 0x%x\n", cir_read(CIR_IRSTS)); + printk("CIR IREN: 0x%x\n", cir_read(CIR_IREN)); + printk("CIR RXFCONT: 0x%x\n", cir_read(CIR_RXFCONT)); + printk("CIR CP: 0x%x\n", cir_read(CIR_CP)); + printk("CIR CC: 0x%x\n", cir_read(CIR_CC)); + printk("CIR SLCH: 0x%x\n", cir_read(CIR_SLCH)); + printk("CIR SLCL: 0x%x\n", cir_read(CIR_SLCL)); + printk("CIR FIFOCON: 0x%x\n", cir_read(CIR_FIFOCON)); + printk("CIR IRFIFOSTS: 0x%x\n", cir_read(CIR_IRFIFOSTS)); + printk("CIR SRXFIFO: 0x%x\n", cir_read(CIR_SRXFIFO)); + printk("CIR TXFCONT: 0x%x\n", cir_read(CIR_TXFCONT)); + printk("CIR STXFIFO: 0x%x\n", cir_read(CIR_STXFIFO)); + printk("CIR FCCH: 0x%x\n", cir_read(CIR_FCCH)); + printk("CIR FCCL: 0x%x\n", cir_read(CIR_FCCL)); + printk("CIR IRFSM: 0x%x\n", cir_read(CIR_IRFSM)); + +} + +static void cir_wake_dump_reg(void) +{ + u8 i = 0; + + cr_enter_ext(); + printk("Dump CIR WKAE CR logical device:\n"); + cr_select_log_dev(CIR_WAKE_LOG_DEV); + printk("CR CIR WAKE ACTIVE : 0x%x \n", cr_read(0x30)); + printk("CR CIR WAKE BASE ADDR: 0x%x\n", (cr_read(0x61) << 8)|cr_read(0x60)); + printk("CR CIR WAKE IRQ NUM: 0x%x\n", cr_read(0x70)); + cr_exit_ext(); + + printk("Dump CIR WAKE Registers\n"); + printk("CIR WAKE IRCON: 0x%x\n", cir_wake_read(CIR_WAKE_IRCON)); + printk("CIR IRSTS: 0x%x\n", cir_wake_read(CIR_WAKE_IRSTS)); + printk("CIR IREN: 0x%x\n", cir_wake_read(CIR_WAKE_IREN)); + printk("CIR WAKE FIFO CMP DEEP: 0x%x\n", cir_wake_read(CIR_WAKE_FIFO_CMP_DEEP)); + printk("CIR WAKE FIFO CMP TOL: 0x%x\n", cir_wake_read(CIR_WAKE_FIFO_CMP_TOL)); + printk("CIR WAKE FIFO COUNT: 0x%x\n", cir_wake_read(CIR_WAKE_FIFO_COUNT)); + printk("CIR WAKE SLCH: 0x%x\n", cir_wake_read(CIR_WAKE_SLCH)); + printk("CIR WAKE SLCL: 0x%x\n", cir_wake_read(CIR_WAKE_SLCL)); + printk("CIR WAKE FIFOCON: 0x%x\n", cir_wake_read(CIR_WAKE_FIFOCON)); + printk("CIR WAKE SRXFSTS: 0x%x\n", cir_wake_read(CIR_WAKE_SRXFSTS)); + printk("CIR WAKE SAMPLE RX FIFO: 0x%x\n", cir_wake_read(CIR_WAKE_SAMPLE_RX_FIFO)); + printk("CIR WAKE WR FIFO DATA: 0x%x\n", cir_wake_read(CIR_WAKE_WR_FIFO_DATA)); + printk("CIR WAKE RD FIFO ONLY: 0x%x\n", cir_wake_read(CIR_WAKE_RD_FIFO_ONLY)); + printk("CIR WAKE RD FIFO ONLY IDX: 0x%x\n", cir_wake_read(CIR_WAKE_RD_FIFO_ONLY_IDX)); + printk("CIR WAKE FIFO IGNORE: 0x%x\n", cir_wake_read(CIR_WAKE_FIFO_IGNORE)); + printk("CIR WAKE IRFSM: 0x%x\n", cir_wake_read(CIR_WAKE_IRFSM)); + + printk("Dump CIR WAKE keys\n"); + printk("%s FIFO count len = %d\n", DRVNAME, cir_wake_read(CIR_WAKE_FIFO_COUNT)); + i = 0; + for (; i < 67; i++) { + printk("%s FIFO = 0x%x\n", DRVNAME, cir_wake_read(CIR_WAKE_RD_FIFO_ONLY)); + } + +} + + +/* 1. */ +/* 677HG Config Registers init */ +static int w83667hg_cr_init(void) +{ + int val = 0; + + cr_enter_ext(); + + /* Check 677 CHIP ID first */ + val = cr_read(CHIP_ID_HIGH_ADDR); + if (val != CHIP_ID_HIGH) { + printk("%s %s: chip id high: 0x%x expect:0x%x\n", DRVNAME, chip_id, val, CHIP_ID_HIGH); + /*// cr_exit_ext(); + // return -ENODEV;*/ + } + else{ + printk("%s %s: chip id high: 0x%x\n", DRVNAME, chip_id, val); + } + + /* now check chip id, LSB */ + val = cr_read(CHIP_ID_LOW_ADDR); + if (CHIP_ID_LOW == (val & CHIP_ID_LOW)) { + printk("%s %s: chip id low: 0x%x expect:0x%x\n", DRVNAME, chip_id, val, CHIP_ID_LOW); + /*// cr_exit_ext(); + // return -ENODEV;*/ + } else{ + printk("%s %s: chip id low: 0x%x\n", DRVNAME, chip_id, val); + } + + /* for multi-function pin selection */ + val = cr_read(0x27); + val = (val&0xbc) | 0x41; + cr_update(val, 0x27); /*For W83677, CIR TX,RX, CIRWB pin selection*/ + + + + /* FIXME*/ + /* set Logical Dev 1: LPT */ + /* not sure really need it or not, find it in 667 wake up windows driver */ + cr_select_log_dev(0x01); + cr_update(DEACTIVE_LOG_DEV, 0x30); + cr_update(0, 0x70); + + /* Then set Logical Dev 6: CIR */ + cr_select_log_dev(CIR_LOG_DEV); + cr_update(ACTIVE_LOG_DEV, 0x30); + + cir_address = CIR_BASE; + cr_update(((CIR_BASE & 0xff00) >> 8), 0x60); + cr_update((CIR_BASE & 0xff), 0x61); +#ifdef IR_667_DEBUG + printk("%s base io port address: 0x%x\n", DRVNAME, cir_address); +#endif + + cr_update(CIR_IRQ_NUM, 0x70); +#ifdef IR_667_DEBUG + printk("%s irq number: %d\n", DRVNAME, CIR_IRQ_NUM); +#endif + + + /* Then set Logical Dev A: ACPI */ + cr_select_log_dev(ACPI_LOG_DEV); + + cr_update(ACTIVE_LOG_DEV, 0x30); + + /* enable cir wake up via PSOUT# (pin 60) */ + cr_safe_update(ENABLE_CIR_WAKE, 0xe0); + + /* enable cir interrupt of mouse IRQ event */ + /*//cr_safe_update(ENABLE_CIR_INTR_OF_MOUSE_IRQ, 0xf6);*/ + + /* enable pme interrupt of cir password event */ + /*//cr_safe_update(ENABLE_PME_INTR_OF_CIR_PASS, 0xf7);*/ + + + /* Then set Logical Dev E: CIR WAKE */ + cr_select_log_dev(CIR_WAKE_LOG_DEV); + cr_update(ACTIVE_LOG_DEV, 0x30); + + cir_wake_address = CIR_WAKE_BASE; + cr_update(((CIR_WAKE_BASE & 0xff00) >> 8), 0x60); + cr_update((CIR_WAKE_BASE & 0xff), 0x61); +#ifdef IR_667_DEBUG + printk("%s cir wake up base io port address: 0x%x\n", DRVNAME, cir_wake_address); +#endif + +#ifdef ENABLE_CIR_WAKE_IRQ + cr_update(CIR_WAKE_IRQ_NUM, 0x70); +#ifdef IR_667_DEBUG + printk("%s cir wake up irq number: %d\n", DRVNAME, CIR_WAKE_IRQ_NUM); +#endif +#endif + + cr_exit_ext(); + + return 0; +} + +static void w83667hg_cr_uninit(void) +{ + cr_enter_ext(); + + /* close CIR */ + /* Don't close CIR Wake. When wake-up at power-on, it needs the function. 20091224 + cr_select_log_dev(CIR_WAKE_LOG_DEV); + cr_update(DEACTIVE_LOG_DEV, 0x30); + */ + + + /* Close Logical Dev A: ACPI */ + /*//cr_select_log_dev(ACPI_LOG_DEV);*/ + + /* enable cir wake up via PSOUT# (pin 60) */ + /*//cr_safe_clear(DISABLE_CIR_WAKE, 0xe0);*/ + + /* enable cir interrupt of mouse IRQ event */ + /*//cr_safe_clear(DISABLE_CIR_INTR_OF_MOUSE_IRQ, 0xf6);*/ + + /* enable pme interrupt of cir password event */ + /*//cr_safe_clear(DISABLE_PME_INTR_OF_CIR_PASS, 0xf7);*/ + + + /* close CIR wake up XXX */ + /*//cr_select_log_dev(CIR_WAKE_LOG_DEV); + //cr_update(DEACTIVE_LOG_DEV, 0x30);*/ + + cr_exit_ext(); +} + +static int w83667hg_input_open(struct input_dev *cur_input_dev) +{ + return 0; +} + +static void w83667hg_input_close(struct input_dev *cur_input_dev) +{ +} + +/* 2. */ +/* init linux input structure */ +static struct input_dev *w83667hg_input_init(void) +{ + int i; + struct input_dev *cur_input_dev = NULL; + + cur_input_dev = input_allocate_device(); + if (NULL == cur_input_dev) { + printk("alloc input device error\n"); + return NULL; + } + + cur_input_dev->name = INPUTNAME; + cur_input_dev->phys = DRVNAME; + memcpy(&cur_input_dev->id, &w83667hg_input_id, sizeof(struct input_id)); + + cur_input_dev->open = w83667hg_input_open; + cur_input_dev->close = w83667hg_input_close; + + /*//cur_input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); + //cur_input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y);*/ + cur_input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); + cur_input_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y); + for (i = 0; i < 256; i++) { + set_bit(usb_kbd_keycode[i], cur_input_dev->keybit); + } + clear_bit(0, cur_input_dev->keybit); +/*// cur_input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT);*/ + cur_input_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_RIGHT); + + + if (input_register_device(cur_input_dev)) { + printk("register input device error\n"); + return NULL; + } + + return cur_input_dev; +} + +static void w83667hg_input_uninit(struct input_dev *cur_input_dev) +{ + input_get_device(cur_input_dev); + input_unregister_device(cur_input_dev); + input_free_device(cur_input_dev); + cur_input_dev = NULL; +} + + +/* internal call for register lirc */ +static int lirc_set_use_inc(void *data) +{ + struct irctl *ir = data; + + if (!ir) { + printk("%s: set_use_inc called with no context\n", DRVNAME); + return -EIO; + } +#ifdef IR_667_DEBUG + printk("%s : set use inc\n", DRVNAME); +#endif + spin_lock(&ir->lock); + ir->ctrl_fix_head = 1; + spin_unlock(&ir->lock); + + + MOD_INC_USE_COUNT; + + return 0; +} + +static void lirc_set_use_dec(void *data) +{ + struct irctl *ir = data; + + if (!ir) { + printk("%s: set_use_dec called with no context\n", DRVNAME); + return; + } +#ifdef IR_667_DEBUG + printk("%s : set use dec\n", DRVNAME); +#endif + + MOD_DEC_USE_COUNT; +} + + +static int lirc_ioctl(struct inode *node, struct file *filep, unsigned int cmd, unsigned long arg) +{ + int ret = 0; + void __user *uptr = (void __user *)arg; + + int mode = 0; + struct irctl *ir = &w83667hg_irctl; + struct ir_recv_t *ir_recv = &w83667hg_ir_recv; + +#ifdef ALLOW_DEBUG_IOCTL + printk("%s: IO Ctrl Code:%d\n", DRVNAME, cmd); +#endif + + switch (cmd) { + /* lirc ioctl commands */ + case LIRC_GET_FEATURES: + ret = put_user(w83667hg_lirc_plugin->features, (unsigned long *)arg); + break; + case LIRC_GET_SEND_MODE: + if (!(w83667hg_lirc_plugin->features & LIRC_CAN_REC_MASK)) + return -ENOSYS; + + ret = put_user(LIRC_REC2MODE + (w83667hg_lirc_plugin->features & LIRC_CAN_REC_MASK), + (unsigned long *)arg); + if (ret) + return ret; + break; + case LIRC_SET_SEND_MODE: + ret = get_user(mode, (unsigned long *)arg); + if (ret) + return ret; + if (mode != (LIRC_MODE_PULSE&LIRC_CAN_SEND_MASK)) + return -EINVAL; + break; + case LIRC_GET_LENGTH: + ret = put_user((unsigned long)w83667hg_lirc_plugin->code_length, + (unsigned long *)arg); + break; + + /* ioctl commands for lirc_wb667 */ + case IR_DUMPCIRREG: + cir_dump_reg(); + break; + case IR_DUMPWAKEREG: + cir_wake_dump_reg(); + break; + case IR_IOLEARNWAKE: + spin_lock(&ir_recv->lock); + if (ir_recv->wake_state) { + spin_unlock(&ir_recv->lock); + ret = -EFAULT; + break; + } + ir_recv->wake_state = ST_WAKE_START; + spin_unlock(&ir_recv->lock); + + /* close cir first */ + cr_enter_ext(); + cr_select_log_dev(CIR_LOG_DEV); + cr_update(DEACTIVE_LOG_DEV, 0x30); + cr_exit_ext(); + /*//cir_update(0, CIR_IREN);*/ + cir_update(0xff, CIR_IRSTS); + + /* set cir wake */ + cir_wake_update(CIR_WAKE_IRCON_RXEN | CIR_WAKE_IRCON_RXINV | CIR_WAKE_IRCON_SAMPLE_PERIOD_SEL, CIR_WAKE_IRCON); + cir_wake_update(0xff, CIR_WAKE_IRSTS); + cir_wake_update(0xff, CIR_WAKE_FIFOCON); + cir_wake_update(0, CIR_WAKE_FIFOCON); +#ifdef ALLOW_DEBUG_WAKE + printk("%s FIFO count len = %d\n", DRVNAME, cir_wake_read(CIR_WAKE_FIFO_COUNT)); +#endif + cir_wake_update(CIR_WAKE_IREN_PE, CIR_WAKE_IREN); + + wait_event(ir_recv->queue, ir_recv->wake_state == ST_WAKE_FINISH); + while ((cir_wake_read(CIR_WAKE_RD_FIFO_ONLY_IDX)) != 0) { +#ifdef ALLOW_DEBUG_WAKE + printk("%s setting wake up key: 0x%x\n", DRVNAME, cir_wake_read(CIR_WAKE_RD_FIFO_ONLY)); +#else + cir_wake_read(CIR_WAKE_RD_FIFO_ONLY); +#endif + } + + /* learn wake up complete */ + spin_lock(&ir_recv->lock); + ir_recv->wake_state = ST_WAKE_NONE; + spin_unlock(&ir_recv->lock); + +#ifdef ALLOW_DEBUG_WAKE + ret = 0; + for (; ret < 67; ret++) { + printk("%s FIFO count = 0x%x\n", DRVNAME, cir_wake_read(CIR_WAKE_RD_FIFO_ONLY)); + } + printk("%s FIFO count len = %d\n", DRVNAME, cir_wake_read(CIR_WAKE_FIFO_COUNT)); +#endif + + /* cir wake interrupt stop, resume cir */ + cir_wake_update(CIR_WAKE_IRCON_MODE0 | CIR_WAKE_IRCON_RXEN | CIR_WAKE_IRCON_R | CIR_WAKE_IRCON_RXINV | CIR_WAKE_IRCON_SAMPLE_PERIOD_SEL, CIR_WAKE_IRCON); + cir_wake_update(0xff, CIR_WAKE_IRSTS); + cir_wake_update(0, CIR_WAKE_IREN); + cr_enter_ext(); + cr_select_log_dev(CIR_LOG_DEV); + cr_update(ACTIVE_LOG_DEV, 0x30); + cr_exit_ext(); + ret = 0; + + break; + case IR_IOUNSETWAKE: + cir_wake_update(0, CIR_WAKE_IRCON); + cir_wake_update(0, CIR_WAKE_IREN); + cir_wake_update(0xFF, CIR_WAKE_IRSTS); + cir_wake_update(0, CIR_WAKE_IRSTS); + cr_enter_ext(); + cr_select_log_dev(CIR_WAKE_LOG_DEV); + cr_update(DEACTIVE_LOG_DEV, 0x30); + cr_exit_ext(); + /*//cir_wake_update(CIR_WAKE_IRCON_MODE0 | CIR_WAKE_IRCON_RXEN | CIR_WAKE_IRCON_R | CIR_WAKE_IRCON_RXINV | CIR_WAKE_IRCON_SAMPLE_PERIOD_SEL, CIR_WAKE_IRCON);*/ + break; + case IR_IOSETWAKE: + cr_enter_ext(); + cr_select_log_dev(CIR_WAKE_LOG_DEV); + cr_update(ACTIVE_LOG_DEV, 0x30); + cr_exit_ext(); + cir_wake_update(CIR_WAKE_IRCON_MODE0 | CIR_WAKE_IRCON_RXEN | CIR_WAKE_IRCON_R | CIR_WAKE_IRCON_RXINV | CIR_WAKE_IRCON_SAMPLE_PERIOD_SEL, CIR_WAKE_IRCON); + cir_wake_update(0xFF, CIR_WAKE_IRSTS); + cir_wake_update(0, CIR_WAKE_IRSTS); + cir_wake_update(0, CIR_WAKE_IREN); + break; + case IR_IOCLEANDATA: + w83667hg_clean_data(&w83667hg_ir_recv, &w83667hg_irctl); + break; + case IR_IOSTARTSTUDY: + spin_lock(&ir->lock); + ir->study_state = ST_STUDY_START; + spin_unlock(&ir->lock); + /*//cir_update(cir_read(CIR_IRCON) | CIR_IRCON_WIREN, CIR_IRCON);*/ + cir_update(CIR_IRCON_WIREN | CIR_IRCON_RXEN | CIR_IRCON_SAMPLE_PERIOD_SEL, CIR_IRCON); + +/* for WRX RTR + cir_update(CIR_FIFOCON_RX_TRIGGER_LEV_8, CIR_FIFOCON); + //cir_update(CIR_IREN_RTR, CIR_IREN); + cir_update(0, CIR_IREN); +*/ + break; + case IR_IOSTOPSTUDY: + cir_update(CIR_IRCON_TXEN | CIR_IRCON_RXEN | CIR_IRCON_RXINV | CIR_IRCON_SAMPLE_PERIOD_SEL, CIR_IRCON); + spin_lock(&ir->lock); + ir->study_state = ST_STUDY_NONE; + ir->buf_count = 0; + ir->cur_buf_num = 0; + wake_up(&ir->queue); + spin_unlock(&ir->lock); + break; + case IR_IOGETCARRIER: + spin_lock(&ir->lock); + if (!(ir->study_state > ST_STUDY_NONE)) { + ret = -EFAULT; + spin_unlock(&ir->lock); + break; + } + /*//w83667hg_record_study_carrier(ir);*/ +#ifdef ALLOW_DEBUG_IOCTL + printk("%s: current get carrier: %d\n", DRVNAME, ir->carrier); +#endif + if (copy_to_user(uptr, &ir->carrier, sizeof(unsigned int))) { + ret = -EFAULT; + } + spin_unlock(&ir->lock); + break; + case IR_IOSETCARRIER: + spin_lock(&ir->lock); + /* you can set carrier at any time */ + /* + if (~(ir->send_state)) { + ret = -EFAULT; + up(&ir->lock); + break; + } + */ + if (copy_from_user(&ir->carrier, uptr, sizeof(unsigned int))) { + ret = -EFAULT; + spin_unlock(&ir->lock); + break; + } +#ifdef ALLOW_DEBUG_IOCTL + printk("%s: current set carrier: %x\n", DRVNAME, ir->carrier); +#endif + w83667hg_set_carrier(&ir->carrier); + spin_unlock(&ir->lock); + break; + case IR_IOSTUDYLEN: + spin_lock(&ir->lock); + if (ir->study_state == ST_STUDY_NONE) { + spin_unlock(&ir->lock); +#ifdef ALLOW_DEBUG_IOCTL + printk("%s: open STUDY first\n", DRVNAME); +#endif + ret = -EFAULT; + break; + } + ir->study_state = ST_STUDY_START; + spin_unlock(&ir->lock); + wait_event(ir->queue, ir->study_state == ST_STUDY_ALL_RECV); + spin_lock(&ir->lock); + + /* in STUDY, copy data buf len to user space for read() */ + ir->cur_buf_num = 0; + if (ir->buf_count == 0) { + ret = -EFAULT; + } else if (copy_to_user(uptr, &ir->buf_count, sizeof(unsigned int))) { + ret = -EFAULT; + } + /* copy data to lirc plugin buffer, ready copy to user space */ + spin_unlock(&ir->lock); + break; + case IR_IOSTUDYBUF: + spin_lock(&ir->lock); + if (ir->study_state != ST_STUDY_ALL_RECV) { + spin_unlock(&ir->lock); + ret = -EFAULT; + break; + } + if (copy_to_user(uptr, &ir->buf[ir->cur_buf_num], sizeof(unsigned char))) { + spin_unlock(&ir->lock); + ret = -EFAULT; + break; + } + if (ir->cur_buf_num < ir->buf_count) { + ir->cur_buf_num++; + } + spin_unlock(&ir->lock); + break; + case IR_IORESTUDYBUF: + spin_lock(&ir->lock); + ir->cur_buf_num = 0; + spin_unlock(&ir->lock); + break; + case IR_CHECKCHIP: + if (copy_to_user(uptr, chip_id, sizeof(unsigned long long))) { + ret = -EFAULT; + } + break; + default: + return -ENOIOCTLCMD; + } + + return ret; +} + +static int w83667hg_set_carrier(unsigned int *carrier) +{ + u16 val; + + cir_update(1, CIR_CP); + val = 3000000 / (*carrier) - 1; + cir_update(val & 0xff, CIR_CC); + +#ifdef ALLOW_DEBUG_STUDY + printk("cp: 0x%x cc: 0x%x\n", cir_read(CIR_CP), cir_read(CIR_CC)); +#endif + return 0; +} + +static ssize_t lirc_write(struct file *file, const char *buf, size_t n, loff_t * ppos) +{ + size_t cur_count; + struct ir_send_t *ir_send = &w83667hg_ir_send; + unsigned int i; + ssize_t ret; + + spin_lock(&ir_send->lock); + + if (n >= IRCTL_BUF_LIMIT) { + ir_send->buf_count = cur_count = IRCTL_BUF_LIMIT; + ret = IRCTL_BUF_LIMIT; + } else { + ir_send->buf_count = cur_count = n; + ret = n; + } + + /* the first copy from user and open interrupt for TX */ + if (copy_from_user(ir_send->buf, buf, ir_send->buf_count)) { + ir_send->buf_count = 0; + spin_unlock(&ir_send->lock); + return -EFAULT; + } + + ir_send->cur_buf_num = 0; + + /* for safety, close RX while TX */ + cir_update(CIR_IREN_TFU | CIR_IREN_TTR, CIR_IREN); + + ir_send->send_state = ST_SEND_REPLY; + + cir_update(CIR_FIFOCON_TX_TRIGGER_LEV_8 | CIR_FIFOCON_RXFIFOCLR, CIR_FIFOCON); + /* turn on TTR interrupt, it's ugly */ + i = 0; + for (; i < 9; i++) { + cir_update(0x01, CIR_STXFIFO); + } + spin_unlock(&ir_send->lock); + + wait_event(ir_send->queue, ir_send->send_state == ST_SEND_REQUEST); + + spin_lock(&ir_send->lock); + ir_send->send_state = ST_SEND_NONE; + spin_unlock(&ir_send->lock); + + cir_update(CIR_IREN_RDR | CIR_IREN_PE, CIR_IREN); + + return ret; +} + +static void w83667hg_clean_data(struct ir_recv_t *ir_recv, struct irctl *ir) +{ + spin_lock(&ir_recv->lock); + ir_recv->buf_count = 0; + /*//ir_recv->wake_state = ST_WAKE_NONE;*/ + wake_up(&ir_recv->queue); + spin_unlock(&ir_recv->lock); + + spin_lock(&ir->lock); + ir->lircdata = 0; + /* + for (i = 0; i < IRCTL_BUF_LIMIT; i++) { + ir->buf = 0; + } + */ + ir->pressed_keycode = 0; + ir->pressed_shiftmask = 0; + ir->buf_count = 0; + ir->cur_buf_num = 0; + /* + ir->study_state = ST_STUDY_NONE; + ir->send_state = ST_SEND_NONE; + */ + wake_up(&ir->queue); + spin_unlock(&ir->lock); + + cir_update(cir_read(CIR_FIFOCON) | 0x88, CIR_FIFOCON); + cir_wake_update(cir_wake_read(CIR_WAKE_FIFOCON) | 0x8, CIR_WAKE_FIFOCON); + +} + +/* 3. */ +static void w83667hg_ir_recv_init(struct ir_recv_t *ir_recv) +{ + ir_recv->buf_count = 0; + spin_lock_init(&ir_recv->lock); + ir_recv->wake_state = ST_WAKE_NONE; + init_waitqueue_head(&ir_recv->queue); + ir_recv->recv_state = ST_RECV_WAIT_7F; +} + +static void w83667hg_ir_send_init(struct ir_send_t *ir_send) +{ + ir_send->buf_count = 0; + spin_lock_init(&ir_send->lock); + ir_send->send_state = ST_SEND_NONE; + init_waitqueue_head(&ir_send->queue); +} + + +/* lirc_fops + * + * 1) it's LIRC's fops, so NOT allow add owner in it + * 2) define lirc functions at here will replace the lirc original fops functions, so lirc_write() in lirc_dev will not work + * 3) lirc has its own ioctl, lirc_ioctl() in current file not register in lirc_fops, so it only work for lirc_wb667 + * lirc_ioctl() in current file register in w83667hg_irctl_init() as lirc_plugin's ioctl while initial driver, and it does not effect on lirc_dev + */ +static struct file_operations lirc_fops = { + write: lirc_write, + ioctl : lirc_ioctl, +}; + + +/* init lirc buffer, register, irctl */ +static int w83667hg_irctl_init(struct irctl *ir) +{ + int err = 0, minor = -1; + + w83667hg_lirc_buffer = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL); + if (!w83667hg_lirc_buffer) { + err = -ENOMEM; + goto out_lirc_buffer; + } + memset(w83667hg_lirc_buffer, 0, sizeof(struct lirc_buffer)); + + if (lirc_buffer_init(w83667hg_lirc_buffer, sizeof(lirc_t), LIRCBUF_SIZE)) { + err = -ENOMEM; + goto out_lirc_buffer; + } + + w83667hg_lirc_plugin = kmalloc(sizeof(struct lirc_driver), GFP_KERNEL); + if (!w83667hg_lirc_plugin) { + err = -ENOMEM; + goto out_lirc_plugin; + } + memset(w83667hg_lirc_plugin, 0, sizeof(struct lirc_driver)); + + ir->lirc_plugin = w83667hg_lirc_plugin; + + strcpy(w83667hg_lirc_plugin->name, DRVNAME); + w83667hg_lirc_plugin->minor = -1; + w83667hg_lirc_plugin->features = LIRC_CAN_SEND_PULSE | + LIRC_CAN_SET_TRANSMITTER_MASK | + LIRC_CAN_REC_MODE2; + /*// LIRC_CAN_SET_SEND_DUTY_CYCLE | + // LIRC_CAN_SET_SEND_CARRIER;*/ + w83667hg_lirc_plugin->data = &w83667hg_irctl; + w83667hg_lirc_plugin->rbuf = w83667hg_lirc_buffer; + w83667hg_lirc_plugin->set_use_inc = &lirc_set_use_inc; + w83667hg_lirc_plugin->set_use_dec = &lirc_set_use_dec; + w83667hg_lirc_plugin->code_length = sizeof(lirc_t) * 8; +/*// w83667hg_lirc_plugin->ioctl = lirc_ioctl;*/ + w83667hg_lirc_plugin->fops = &lirc_fops; + w83667hg_lirc_plugin->dev = NULL; + w83667hg_lirc_plugin->owner = THIS_MODULE; + + minor = lirc_register_driver(w83667hg_lirc_plugin); + if (minor < 0) { + err = -ENOMEM; + goto out_lirc_plugin_register; + } +#ifdef IR_667_DEBUG + printk("%s register lirc minor: %d\n", DRVNAME, minor); +#endif + + w83667hg_lirc_plugin->minor = minor; + ir->lirc_plugin = w83667hg_lirc_plugin; + + /* init irctl */ + ir->pressed_keycode = 0; + ir->pressed_shiftmask = 0; + ir->buf_count = 0; + ir->ctrl_fix_head = 1; + spin_lock_init(&ir->lock); + ir->study_state = ST_STUDY_NONE; + init_waitqueue_head(&ir->queue); + + goto out; + + out_lirc_plugin_register: + kfree(w83667hg_lirc_plugin); + out_lirc_plugin: + lirc_buffer_free(w83667hg_lirc_buffer); + out_lirc_buffer: + kfree(w83667hg_lirc_buffer); + out: + return err; +} + +static void w83667hg_irctl_uninit(struct irctl *ir) +{ + /*//lirc_unregister_plugin(w83667hg_lirc_plugin->minor);*/ + lirc_unregister_driver(w83667hg_lirc_plugin->minor); + kfree(w83667hg_lirc_plugin); + ir->lirc_plugin = NULL; + lirc_buffer_free(w83667hg_lirc_buffer); + kfree(w83667hg_lirc_buffer); + ir->lirc_buffer = NULL; +} + +#ifdef ALLOW_DEBUG_PRINT_PULSE +void debug_print_pulse(void) +{ + u8 count, i; + + count = cir_read(CIR_RXFCONT); + for (i = 0; i < count; i++) { + printk("%s current cir pluse: 0x%x\n", DRVNAME, cir_read(CIR_SRXFIFO)); + } +} + +void debug_print_wake_pulse(void) +{ + u8 count, i; + + count = cir_wake_read(CIR_WAKE_FIFO_COUNT); + for (i = 0; i < count; i++) { + printk("%s current cir wake pluse: 0x%x\n", DRVNAME, cir_wake_read(CIR_WAKE_SRXFSTS)); + } +} +#endif + +static void w83667hg_study_recv(struct ir_recv_t *ir_recv, struct irctl *ir) +{ + unsigned int i = 0; + unsigned int packet_on_dur = 0; + + spin_lock(&ir_recv->lock); + ir_recv->buf[ir_recv->buf_count] = cir_read(CIR_SRXFIFO); + if (ir_recv->buf[ir_recv->buf_count] == 0x80) { + /* close interrupt now */ + /*//cir_wake_update(0, CIR_WAKE_IREN);*/ + + spin_lock(&ir->lock); + + /* 1. get carrier */ + ir->carrier = cir_read(CIR_FCCL); + ir->carrier |= cir_read(CIR_FCCH) << 8; + + if (ir->carrier == 0) { + printk("%s: get carrier error!\n", DRVNAME); + } + + i = 0; + for (; i < ir_recv->buf_count; i++) { + if (ir_recv->buf[i] & BIT_PULSE_MASK) { + packet_on_dur += ir_recv->buf[i] & BIT_LEN; + } + } + packet_on_dur *= MCE_TIME_UNIT; + +#ifdef ALLOW_DEBUG_STUDY + printk("%s: carrier count: 0x%x\n", DRVNAME, ir->carrier); + printk("%s: packet on duration: %u\n", DRVNAME, packet_on_dur); +#endif + ir->carrier *= 1000000; + ir->carrier /= packet_on_dur; +#ifdef ALLOW_DEBUG_STUDY + printk("%s: final carrier frequency: %u\n", DRVNAME, ir->carrier); +#endif + if ((ir->carrier > MAX_CARRIER) || (ir->carrier < MIN_CARRIER)) { + /* carrier is too large or too small */ +#ifdef ALLOW_DEBUG_STUDY + printk("%s: current received carrier is too large or too small\n", DRVNAME); +#endif + ir_recv->buf_count = 0; + spin_unlock(&ir_recv->lock); + + ir->buf_count = 0; + ir->study_state = ST_STUDY_ALL_RECV; + wake_up(&ir->queue); + spin_unlock(&ir->lock); + return; + } + + /* 2. get pulse */ + i = 0; + /* 1) find sync head */ + while (!((ir_recv->buf[i] & BIT_PULSE_MASK) & 0x80)) { + i++; + } + /* 2) find 0x7f */ + /* FIXME, the silent part of infrared signal may change by protocol or sample period. but current value fits MCE RC-6*/ + while ((ir_recv->buf[i] != 0x7f) || + (ir_recv->buf[i + 1] != 0x7f) || + (ir_recv->buf[i + 2] != 0x7f)) { + i++; + } + /* 3) find next head */ + while (!((ir_recv->buf[i] & BIT_PULSE_MASK) & 0x80)) { + i++; + } + /*//ir->buf_count = --i;*/ + /* now buf_count direct to next pulse sync head */ + ir->buf_count = i; + /* 4) copy pluse from recv to ir */ + i = 0; + for (; i <= ir->buf_count; i++) { + ir->buf[i] = ir_recv->buf[i]; + } + + + ir_recv->buf_count = 0; + spin_unlock(&ir_recv->lock); + + ir->study_state = ST_STUDY_ALL_RECV; + wake_up(&ir->queue); + spin_unlock(&ir->lock); + } else { + ir_recv->buf_count++; + spin_unlock(&ir_recv->lock); + } +} + + +static void w83667hg_recv(struct ir_recv_t *ir_recv, struct irctl *ir) +{ + u8 buf; + unsigned int i = 0, rlc = 0; + + spin_lock(&ir_recv->lock); + + ir_recv->buf[ir_recv->buf_count] = cir_read(CIR_SRXFIFO); + if (ir_recv->buf[ir_recv->buf_count] == 0x7f) { + if (ir_recv->recv_state & ST_RECV_WAIT_7F) { + ir_recv->recv_state = ST_RECV_WAIT_HEAD; + ir_recv->buf_count++; + { /* decode begin*/ + spin_lock(&ir->lock); + + ir->buf_count = ir_recv->buf_count; + for (; i < ir->buf_count; i++) { + ir->buf[i] = ir_recv->buf[i]; + } + ir->cur_buf_num = 0; + + /*//ir_recv->buf_count++;*/ + spin_unlock(&ir_recv->lock); + + i = 0; + while (i < ir->buf_count) { + rlc += ir->buf[i] & BIT_LEN; + i++; + } +#ifdef ALLOW_DEBUG_DECODE + printk("\n%s cur rlc len: %d\n", DRVNAME, rlc); +#endif + +#ifdef DECODE_KEYBOARD_MOUSE + if (rlc >= CONTROLLER_BUF_LEN_MIN) { +#endif + /* lirc controller*/ + w83667hg_submit_controller(ir); + +#ifdef DECODE_KEYBOARD_MOUSE + } else if ((rlc >= KEYBOARD_BUF_LEN_MIN) && + (rlc < KEYBOARD_BUF_LEN_MAX)) { + w83667hg_submit_key(ir); + input_sync(ir->input_dev); + } else if ((rlc >= MOUSE_BUF_LEN_MIN) && + (rlc < KEYBOARD_BUF_LEN_MIN)) { + w83667hg_submit_mouse(ir); + input_sync(ir->input_dev); + } +#endif + + ir->buf_count = 0; + spin_unlock(&ir->lock); + } /* decode end*/ + } else { + ir_recv->buf_count++; + spin_unlock(&ir_recv->lock); + } + } else { /* normal recv*/ + if (ir_recv->recv_state & ST_RECV_WAIT_HEAD) { + if (ir_recv->buf[ir_recv->buf_count] & BIT_PULSE_MASK) { + ir_recv->recv_state = ST_RECV_WAIT_7F; + buf = ir_recv->buf[ir_recv->buf_count]; + ir_recv->buf_count = 0; + ir_recv->buf[0] = buf; + } + } + ir_recv->buf_count++; + spin_unlock(&ir_recv->lock); + } +} + + + +static void w83667hg_send_packet_to_lirc_1(struct irctl *ir, lirc_t *val) +{ +#ifdef ALLOW_DEBUG_DECODE + printk("%s: send data to lirc : 0x%x\n", DRVNAME, (*val)); +#endif +/*// lirc_buffer_write_1(ir->lirc_plugin->rbuf, (char *)val);*/ + lirc_buffer_write(ir->lirc_plugin->rbuf, (char *)val); + wake_up(&ir->lirc_plugin->rbuf->wait_poll); +} + + +static void w83667hg_submit_controller(struct irctl *ir) +{ + unsigned int buf_num; + u8 bit; + + static struct timeval last_time; + static bool is_not_initialed_yet = true; /* lirc group does not allow to initialize static variable to false(0) */ + struct timeval curr_time; + long duration; + + /* silence time */ + + ir->lircdata = 0; + + if (is_not_initialed_yet == true) { + duration = MAX_SILENCE_TIME; + is_not_initialed_yet = false; + } else{ + do_gettimeofday(&curr_time); + duration = (curr_time.tv_usec - last_time.tv_usec) + + (curr_time.tv_sec - last_time.tv_sec) * 1000000; + } + + if (duration >= MAX_SILENCE_TIME) { + ir->lircdata = MAX_SILENCE_TIME; + } else{ + ir->lircdata = duration; + } + w83667hg_send_packet_to_lirc_1(ir, &ir->lircdata); + + + /* fix controller head not sync problem */ + /* lirc doesn't response DK MCE controller signal until press several times, not find same problem on M$ MCE controller keyboard */ + /* for lirc group's suggestion, we need not add these code to prevent from this problem. + Just make it as comment. If we do not get any problem report from our customer, we will remove it at next some version. + if (ir->ctrl_fix_head) { + ir->lircdata = 50000; + w83667hg_send_packet_to_lirc_1(ir, &ir->lircdata); + ir->ctrl_fix_head = 0; + } + */ + + + buf_num = 0; + bit = BIT_PULSE_MASK; + ir->lircdata = 0; + for (; buf_num < ir->buf_count; buf_num++) { + if (bit == (ir->buf[buf_num] & BIT_PULSE_MASK)) { + ir->lircdata += (ir->buf[buf_num] & BIT_LEN) * MCE_TIME_UNIT; + } else { + if (bit) { + ir->lircdata |= PULSE_BIT; + } + w83667hg_send_packet_to_lirc_1(ir, &ir->lircdata); + bit = ir->buf[buf_num] & BIT_PULSE_MASK; + ir->lircdata = (ir->buf[buf_num] & BIT_LEN) * MCE_TIME_UNIT; + } + } + + /* update last_time for measure silence time*/ + do_gettimeofday(&last_time); + + /* for final silent pulse */ + /*ir->lircdata = 50000; + w83667hg_send_packet_to_lirc_1(ir, &ir->lircdata);*/ + +#ifdef ALLOW_DEBUG_DECODE + printk("\n"); +#endif +} + +static irqreturn_t w83667hg_interrupt_handler(int irq, void *dev) +{ + u8 tmp = 0; + struct irctl *ir = (struct irctl *)dev; + struct ir_send_t *ir_send = &w83667hg_ir_send; + + + /*Because interrupt is shared, check IREN first. */ + tmp = cir_read(CIR_IREN); + if (!tmp) { + return IRQ_RETVAL(IRQ_NONE); + } + tmp = cir_read(CIR_IRSTS); + cir_update(0xff, CIR_IRSTS); + if (!tmp) { + return IRQ_NONE; + } + if (tmp & CIR_IRSTS_RDR) { + + +#ifdef ALLOW_DEBUG_INTERRUPT + printk("get CIR_IRSTS_RDR\n"); +#endif +#ifdef ALLOW_DEBUG_PRINT_PULSE + debug_print_pulse(); +#else + spin_lock(&ir_send->lock); + if (ir_send->send_state == ST_SEND_NONE) { + spin_unlock(&ir_send->lock); + if (ir->study_state & ST_STUDY_START) { + w83667hg_study_recv(&w83667hg_ir_recv, &w83667hg_irctl); + } else { + w83667hg_recv(&w83667hg_ir_recv, &w83667hg_irctl); + } + } else { + spin_unlock(&ir_send->lock); + } +#endif + } + if (tmp & CIR_IRSTS_RTR) { +#ifdef ALLOW_DEBUG_INTERRUPT + printk("get CIR_IRSTS_RTR\n"); +#endif + } + if (tmp & CIR_IRSTS_PE) { +#ifdef ALLOW_DEBUG_INTERRUPT + printk("get CIR_IRSTS_PE\n"); +#endif +#ifdef ALLOW_DEBUG_PRINT_PULSE + printk("\n now get interrupt PE\n\n"); + debug_print_pulse(); +#else + if (ir->study_state == ST_STUDY_NONE) { + w83667hg_clean_data(&w83667hg_ir_recv, &w83667hg_irctl); + } +#endif + } + if (tmp & CIR_IRSTS_RFO) { +#ifdef ALLOW_DEBUG_INTERRUPT + printk("get CIR_IRSTS_RFO\n"); +#endif + } + if (tmp & CIR_IRSTS_TE) { +#ifdef ALLOW_DEBUG_INTERRUPT + printk("get CIR_IRSTS_TE\n"); +#endif + } + if (tmp & CIR_IRSTS_TTR) { +#ifdef ALLOW_DEBUG_INTERRUPT + printk("get CIR_IRSTS_TTR\n"); +#endif + + spin_lock(&ir_send->lock); + if (ir_send->cur_buf_num < ir_send->buf_count) { + cir_update(ir_send->buf[ir_send->cur_buf_num++], CIR_STXFIFO); + } else { + cir_update(cir_read(CIR_IREN) & (~CIR_IREN_TTR), CIR_IREN); + } + spin_unlock(&ir_send->lock); + + } + if (tmp & CIR_IRSTS_TFU) { +#ifdef ALLOW_DEBUG_INTERRUPT + printk("get CIR_IRSTS_TFU\n"); +#endif + spin_lock(&ir_send->lock); + if (ST_SEND_REPLY == ir_send->send_state) { + ir_send->send_state = ST_SEND_REQUEST; + wake_up(&ir_send->queue); + } + spin_unlock(&ir_send->lock); + } + if (tmp & CIR_IRSTS_GH) { +#ifdef ALLOW_DEBUG_INTERRUPT + printk("get CIR_IRSTS_GH\n"); +#endif + } + + return IRQ_HANDLED; +} + +static irqreturn_t w83667hg_wake_interrupt_handler(int irq, void *dev) +{ + u8 tmp; + struct ir_recv_t *ir_recv = (struct ir_recv_t *)dev; + + + /*Because interrupt is shared, check IREN first. */ + tmp = cir_wake_read(CIR_WAKE_IREN); + if (!tmp) { + return IRQ_RETVAL(IRQ_NONE); + } + + tmp = cir_wake_read(CIR_WAKE_IRSTS); + if (!tmp) { + return IRQ_NONE; + } + cir_wake_update(0xff, CIR_WAKE_IRSTS); + + if (tmp & CIR_WAKE_IRSTS_RDR) { +#ifdef ALLOW_DEBUG_INTERRUPT + printk("get CIR_WAKE_IRSTS_RDR\n"); +#endif +#ifdef ALLOW_DEBUG_PRINT_PULSE + debug_print_wake_pulse(); +#endif + } + if (tmp & CIR_WAKE_IRSTS_RTR) { +#ifdef ALLOW_DEBUG_INTERRUPT + printk("get CIR_WAKE_IRSTS_RTR\n"); +#endif + } + if ((tmp & CIR_WAKE_IRSTS_PE) && + (ST_WAKE_START == ir_recv->wake_state)) { +#ifdef ALLOW_DEBUG_INTERRUPT + printk("get CIR_WAKE_IRSTS_PE\n"); +#endif +#ifdef ALLOW_DEBUG_PRINT_PULSE + printk("\n now get interrupt PE\n\n"); + debug_print_wake_pulse(); +#else + while ((cir_wake_read(CIR_WAKE_RD_FIFO_ONLY_IDX)) != 0) { +#ifdef ALLOW_DEBUG_WAKE + printk("%s setting wake up key: 0x%x\n", DRVNAME, cir_wake_read(CIR_WAKE_RD_FIFO_ONLY)); +#else + cir_wake_read(CIR_WAKE_RD_FIFO_ONLY); +#endif + } + + cir_wake_update(0, CIR_WAKE_IREN); + spin_lock(&ir_recv->lock); + ir_recv->wake_state = ST_WAKE_FINISH; + wake_up(&ir_recv->queue); + spin_unlock(&ir_recv->lock); +#endif + } + if (tmp & CIR_WAKE_IRSTS_RFO) { +#ifdef ALLOW_DEBUG_INTERRUPT + printk("get CIR_WAKE_IRSTS_RFO\n"); +#endif + } + if (tmp & CIR_WAKE_IRSTS_GH) { +#ifdef ALLOW_DEBUG_INTERRUPT + printk("get CIR_WAKE_IRSTS_GH\n"); +#endif + } + + return IRQ_HANDLED; +} + +/* 4. */ +/* init 667 cir dev, req_region, req_irq */ +static int w83667hg_cir_probe(void) +{ + int err = 0; + + if (!request_region(cir_address, CIR_IOREG_LENGTH, DRVNAME)) { + err = -EBUSY; +#ifdef IR_667_DEBUG + printk("%s request 667 cir io port error! \n", DRVNAME); +#endif + goto exit; + } + + cir_update(CIR_IRCON_RXINV | CIR_IRCON_SAMPLE_PERIOD_SEL, CIR_IRCON); + cir_update(0xFF, CIR_IRSTS); + cir_update(CIR_RX_LIMIT_COUNT >> 8, CIR_SLCH); + cir_update(CIR_RX_LIMIT_COUNT & 0xff, CIR_SLCL); + cir_update(CIR_FIFOCON_TXFIFOCLR | CIR_FIFOCON_TX_TRIGGER_LEV_24 | CIR_FIFOCON_RXFIFOCLR, CIR_FIFOCON); + cir_update(CIR_IRCON_RECV | CIR_IRCON_RXINV | CIR_IRCON_SAMPLE_PERIOD_SEL, CIR_IRCON); + cir_update(CIR_IRCON_TXEN | CIR_IRCON_RXEN | CIR_IRCON_RXINV | CIR_IRCON_SAMPLE_PERIOD_SEL, CIR_IRCON); + + if (0 != request_irq(CIR_IRQ_NUM, w83667hg_interrupt_handler, IRQF_SHARED, + DRVNAME, &w83667hg_irctl)) { + err = -EINTR; +#ifdef IR_667_DEBUG + printk("%s : request cir irq error\n", DRVNAME); +#endif + goto rel_irq_exit; + } + /* open interrupt */ + cir_update(CIR_IREN_RDR | CIR_IREN_PE, CIR_IREN); + + if (!request_region(cir_wake_address, CIR_IOREG_LENGTH, DRVNAME)) { + err = -EBUSY; +#ifdef IR_667_DEBUG + printk("%s request 667 cir wake io port error! \n", DRVNAME); +#endif + goto rel_wake_exit; + } + + cir_wake_update(0xff, CIR_WAKE_IRSTS); + /* Modify it as more safe values: CIR_WAKE_FIFO_CMP_DEEP reg:0x41, + CIR_WAKE_FIFO_CMP_TOL reg: 0x05. 20091224 + */ + cir_wake_update(0x41, CIR_WAKE_FIFO_CMP_DEEP); /* 0x41 = 65 */ + cir_wake_update(0x05, CIR_WAKE_FIFO_CMP_TOL); + cir_wake_update(CIR_RX_LIMIT_COUNT >> 8, CIR_WAKE_SLCH); + cir_wake_update(CIR_RX_LIMIT_COUNT & 0xff, CIR_WAKE_SLCL); + cir_wake_update(0xff, CIR_WAKE_FIFOCON); + cir_wake_update(0, CIR_WAKE_FIFOCON); + cir_wake_update(CIR_WAKE_IRCON_MODE0 | CIR_WAKE_IRCON_RXEN | CIR_WAKE_IRCON_R | CIR_WAKE_IRCON_RXINV | CIR_WAKE_IRCON_SAMPLE_PERIOD_SEL, CIR_WAKE_IRCON); + + /* cir wake has irq_handler, open interrupt after received ioctl IR_IOLEARNWAKE */ + if (0 != request_irq(CIR_WAKE_IRQ_NUM, w83667hg_wake_interrupt_handler, IRQF_SHARED, + DRVNAME, &w83667hg_ir_recv)) { + err = -EINTR; +#ifdef IR_667_DEBUG + printk("%s : request cir wake irq error\n", DRVNAME); +#endif + goto rel_wake_irq_exit; + } + +#ifdef IR_667_DEBUG + printk("%s : init cir success\n", DRVNAME); +#endif + goto exit; + + /* error exit */ + rel_wake_irq_exit: + release_region(cir_wake_address, CIR_IOREG_LENGTH); + rel_wake_exit: + cir_update(0, CIR_IREN); + free_irq(CIR_IRQ_NUM, &w83667hg_irctl); + rel_irq_exit: + release_region(cir_address, CIR_IOREG_LENGTH); + + /* final exit */ + exit: + return err; +} + +static void w83667hg_cir_remove(void) +{ + /* Don't clean CIR_WAKE_IRCON. When wake-up at power-on, it needs the function. 20091224 + cir_wake_update(0, CIR_WAKE_IRCON); + */ + free_irq(CIR_WAKE_IRQ_NUM, &w83667hg_ir_recv); + release_region(cir_wake_address, CIR_IOREG_LENGTH); + cir_update(0, CIR_IRCON); + free_irq(CIR_IRQ_NUM, &w83667hg_irctl); + release_region(cir_address, CIR_IOREG_LENGTH); +} + +static int lirc_wb667_init(void) +{ + int err = 0; + + /* Initialise global static variables here instead of at declaration becuase of + lirc group does not allow it.*/ +#ifdef CONFIG_PNP + nopnp = 0; +#else + nopnp = 1; +#endif + w83667hg_input_dev = NULL; + w83667hg_lirc_plugin = NULL; + w83667hg_lirc_buffer = NULL; + + /* 1. init cr */ + if (w83667hg_cr_init()) { + printk("%s: Unable to init device.\n", DRVNAME); + err = -ENODEV; + goto out; + } + + /* 2. init input */ + w83667hg_input_dev = w83667hg_input_init(); + if (!w83667hg_input_dev) { + printk("%s: Unable to register input device.\n", DRVNAME); + err = -ENODEV; + goto out_input; + } + w83667hg_irctl.input_dev = w83667hg_input_dev; + + /* 3. init lirc buffer, register, irctl */ + w83667hg_ir_recv_init(&w83667hg_ir_recv); + w83667hg_ir_send_init(&w83667hg_ir_send); + err = w83667hg_irctl_init(&w83667hg_irctl); + if (err) { + printk("%s: Unable to register lirc.\n", DRVNAME); + goto out_irctl; + } + + + /* 4. init 667 cir dev, req_region, req_irq */ + err = w83667hg_cir_probe(); + if (err) { + printk("%s: Unable to probe cir device.\n", DRVNAME); + goto out_cir_probe; + } + + goto out; + + /* error exit */ + out_cir_probe: + w83667hg_irctl_uninit(&w83667hg_irctl); + w83667hg_irctl.input_dev = NULL; + out_irctl: + w83667hg_input_uninit(w83667hg_input_dev); + out_input: + w83667hg_cr_uninit(); + + /* final exit */ + out: + return err; +} + +void lirc_wb667_uninit(void) +{ + w83667hg_cir_remove(); + w83667hg_irctl_uninit(&w83667hg_irctl); + w83667hg_irctl.input_dev = NULL; + w83667hg_input_uninit(w83667hg_input_dev); + w83667hg_cr_uninit(); + +} + + + +/* For resume function use only. 20100119*/ +static void w83667hg_irctl_resume_reset(struct irctl *ir) +{ + /* init irctl */ + ir->pressed_keycode = 0; + ir->pressed_shiftmask = 0; + ir->buf_count = 0; + ir->ctrl_fix_head = 1; + spin_lock_init(&ir->lock); + ir->study_state = ST_STUDY_NONE; + init_waitqueue_head(&ir->queue); +} + + +/* For resume function use only. 20100119*/ +static int w83667hg_cir_resume_reset(void) +{ + int err = 0; + + cir_update(CIR_IRCON_RXINV | CIR_IRCON_SAMPLE_PERIOD_SEL, CIR_IRCON); + cir_update(0xFF, CIR_IRSTS); + cir_update(CIR_RX_LIMIT_COUNT >> 8, CIR_SLCH); + cir_update(CIR_RX_LIMIT_COUNT & 0xff, CIR_SLCL); + cir_update(CIR_FIFOCON_TXFIFOCLR | CIR_FIFOCON_TX_TRIGGER_LEV_24 | CIR_FIFOCON_RXFIFOCLR, CIR_FIFOCON); + cir_update(CIR_IRCON_RECV | CIR_IRCON_RXINV | CIR_IRCON_SAMPLE_PERIOD_SEL, CIR_IRCON); + cir_update(CIR_IRCON_TXEN | CIR_IRCON_RXEN | CIR_IRCON_RXINV | CIR_IRCON_SAMPLE_PERIOD_SEL, CIR_IRCON); + + /* open interrupt */ + cir_update(CIR_IREN_RDR | CIR_IREN_PE, CIR_IREN); + + + cir_wake_update(0xff, CIR_WAKE_IRSTS); + + cir_wake_update(0x41, CIR_WAKE_FIFO_CMP_DEEP); /* 0x41 = 65 */ + cir_wake_update(0x05, CIR_WAKE_FIFO_CMP_TOL); + cir_wake_update(CIR_RX_LIMIT_COUNT >> 8, CIR_WAKE_SLCH); + cir_wake_update(CIR_RX_LIMIT_COUNT & 0xff, CIR_WAKE_SLCL); + cir_wake_update(0xff, CIR_WAKE_FIFOCON); + cir_wake_update(0, CIR_WAKE_FIFOCON); + cir_wake_update(CIR_WAKE_IRCON_MODE0 | CIR_WAKE_IRCON_RXEN | CIR_WAKE_IRCON_R | CIR_WAKE_IRCON_RXINV | CIR_WAKE_IRCON_SAMPLE_PERIOD_SEL, CIR_WAKE_IRCON); + + +#ifdef IR_667_DEBUG + printk("%s : cir_resume_reset finish\n", DRVNAME); +#endif + + return err; +} + + +/* For resume function use only. 20100119*/ +static int lirc_wb667_resume_init(void) +{ + int err = 0; + + /* init lirc buffer */ + w83667hg_ir_recv_init(&w83667hg_ir_recv); + w83667hg_ir_send_init(&w83667hg_ir_send); + + /* reset variables in irctl, but no re-locate and no re-register 20100119*/ + w83667hg_irctl_resume_reset(&w83667hg_irctl); + + + /* init 667 cir dev */ + + w83667hg_cir_resume_reset(); + + + return err; +} + + + +#ifdef CONFIG_PNP + +/* CIR and CIR WAKE */ + +static struct pnp_driver lirc_wb667_pnp_driver = { + .name = PLATNAME, + .id_table = pnp_dev_table, + .probe = lirc_wb667_pnp_probe, + .remove = __devexit_p(lirc_wb667_pnp_remove), + .suspend = lirc_wb667_pnp_suspend, + .resume = lirc_wb667_pnp_resume, +}; + +static int __devinit lirc_wb667_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id) +{ + /* CIR */ + + #ifdef IR_667_DEBUG + printk("%s receive probe\n", DRVNAME); + #endif + + if (!pnp_port_valid(dev, 0)) + return -ENODEV; + + + CIR_BASE = (unsigned int)pnp_port_start(dev, 0); + CIR_IRQ_NUM = (unsigned short)pnp_irq(dev, 0); + + + /* CIR WAKE*/ + if (!pnp_port_valid(dev, 1)) + return -ENODEV; + CIR_WAKE_BASE = (unsigned int)pnp_port_start(dev, 1); + CIR_WAKE_IRQ_NUM = (unsigned short)pnp_irq(dev, 0); /* share the same irq with CIR device.*/ + + return 0; +} + +static void __devexit lirc_wb667_pnp_remove(struct pnp_dev *dev) +{ +} + + + +static int lirc_wb667_pnp_suspend(struct pnp_dev *dev, pm_message_t state) +{ + struct irctl *ir = &w83667hg_irctl; + struct ir_recv_t *ir_recv = &w83667hg_ir_recv; + struct ir_send_t *ir_send = &w83667hg_ir_send; + +#ifdef IR_667_DEBUG + printk("%s receive suspend\n", DRVNAME); +#endif + + /* 1. */ + spin_lock(&ir->lock); + ir->study_state = ST_STUDY_NONE; + spin_unlock(&ir->lock); + + spin_lock(&ir_recv->lock); + ir_recv->wake_state = ST_WAKE_NONE; + spin_unlock(&ir_recv->lock); + + spin_lock(&ir_send->lock); + ir_send->send_state = ST_SEND_NONE; + spin_unlock(&ir_send->lock); + + /* 2. */ + cir_update(0, CIR_IREN); + cir_wake_update(0, CIR_WAKE_IREN); + + + /* 3. */ + cr_enter_ext(); + cr_select_log_dev(CIR_LOG_DEV); + cr_update(DEACTIVE_LOG_DEV, 0x30); + + /*Don't close CIR Wake. When wake-up at power-on, it needs the function. 20091224 + cr_select_log_dev(CIR_WAKE_LOG_DEV); + cr_update(DEACTIVE_LOG_DEV, 0x30); + */ + + cr_exit_ext(); + + + return 0; +} + +static int lirc_wb667_pnp_resume(struct pnp_dev *dev) +{ + int ret = 0; + +#ifdef IR_667_DEBUG + printk("%s receive resume\n", DRVNAME); +#endif + + + /* open interrupt */ + cir_update(CIR_IREN_RDR | CIR_IREN_PE, CIR_IREN); + + + /* Enable CIR logical device */ + cr_enter_ext(); + cr_select_log_dev(CIR_LOG_DEV); + cr_update(ACTIVE_LOG_DEV, 0x30); + + + /*Don't close CIR Wake. When wake-up at power-on, it needs the function. 20091224 + cr_select_log_dev(CIR_WAKE_LOG_DEV); + cr_update(ACTIVE_LOG_DEV, 0x30); + */ + cr_exit_ext(); + + /* special uninit function for resume only. 20100119 */ + lirc_wb667_resume_init(); + + return ret; +} + + + + + + +#endif + + +/*//int init_module(void)*/ +int init_module_wb667(void) +{ + int ret; + + if (nopnp) { + printk("%s does not support Non-PNP kernel now.\n", DRVNAME); + } + +#ifdef CONFIG_PNP + if (!nopnp) { + + ret = pnp_register_driver(&lirc_wb667_pnp_driver); + if (ret < 0) + return ret; + + + + } +#endif /* CONFIG_PNP */ + + + + + ret = lirc_wb667_init(); + if (ret) { + return ret; + } + + return 0; +} + +/*//void cleanup_module(void)*/ +void cleanup_module_wb667(void) +{ + +#ifdef CONFIG_PNP + if (!nopnp) { + pnp_unregister_driver(&lirc_wb667_pnp_driver); + + } +#endif /* CONFIG_PNP */ + + + lirc_wb667_uninit(); +} + +module_init(init_module_wb667); +module_exit(cleanup_module_wb667); + + diff -Nru nct677x-dkms-1.0.1/nct677x-1.0.4/src/lirc_wb677_mouse_kbd.c nct677x-dkms-1.0.4/nct677x-1.0.4/src/lirc_wb677_mouse_kbd.c --- nct677x-dkms-1.0.1/nct677x-1.0.4/src/lirc_wb677_mouse_kbd.c 1970-01-01 00:00:00.000000000 +0000 +++ nct677x-dkms-1.0.4/nct677x-1.0.4/src/lirc_wb677_mouse_kbd.c 2010-01-13 06:49:34.000000000 +0000 @@ -0,0 +1,881 @@ +/* Notice: + Do NOT merge this file with other file. + According to lirc group's suggestion, they hope that + we should put keyboard/mouse decoding into a separate file if we want to preserve it. +*/ + +#include +#include "lirc_wb677_common_extern.h" +#include "lirc_wb677_mouse_kbd.h" + + +void w83667hg_set_key(u8 *set_frame, u8 val, u8 *keycode, u8 *shiftmask) +{ +#ifdef ALLOW_DEBUG_DECODE + printk("%s set key: %d\n", DRVNAME, val); +#endif + + if (*set_frame <= KEY_SUBMIT_KEYCODE_FRAME_NUM + 1) { + *keycode <<= 1; + *keycode |= val; +#ifdef ALLOW_DEBUG_DECODE + printk("%s set key keycode:0x%x\n", DRVNAME, *keycode); + printk("set frame: %d\n", *set_frame); +#endif + } else { + *shiftmask <<= 1; + *shiftmask |= val; +#ifdef ALLOW_DEBUG_DECODE + printk("%s set key mask:0x%x\n", DRVNAME, *shiftmask); + printk("set frame: %d\n", *set_frame); +#endif + } + (*set_frame)++; +} + + +int w83667hg_jump_frame(struct irctl *ir, u8 frame_num, unsigned int *buf_num, u8 *out_bit, u8 *decode_status) +{ + unsigned int rlc = 0, cur_buf_num = *buf_num; + u8 bit = *out_bit, buf; + u8 cur_decode_status = *decode_status; + u8 cur_frame_num; + + cur_frame_num = 1; + for (; cur_frame_num <= frame_num; cur_buf_num++) { + buf = ir->buf[cur_buf_num]; + if (cur_buf_num > ir->buf_count) { +#ifdef ALLOW_DEBUG_DECODE + printk("%s: jump frame error\n", DRVNAME); + printk("current buf num: %d\n", cur_buf_num); + printk("current jumped frame: %d\n", cur_frame_num); + printk("current frame length: %d\n", rlc); + printk("total cir signal:\n"); + for (cur_buf_num = 0; cur_buf_num < ir->buf_count; cur_buf_num++) { + printk("0x%x ", ir->buf[cur_buf_num]); + if (cur_buf_num % 6 == 5) { + printk("\n"); + } + } +#endif + return -1; + } + if (bit == (buf & BIT_PULSE_MASK)) { + rlc += buf & BIT_LEN; + } else { + + /* decode*/ + switch (cur_decode_status) { + case ST_DECODE_NEW: + if ((rlc > ONE_PULSE_LEN_LOW) && + (rlc < ONE_PULSE_LEN_HIGH)) { + if (bit & BIT_PULSE_MASK) { + cur_decode_status = ST_DECODE_ONE; + } else { + cur_decode_status = ST_DECODE_ZERO; + } + } else if ((rlc > TWO_PULSE_LEN_LOW) && + (rlc < TWO_PULSE_LEN_HIGH)) { + /* error occur, just ignore */ + cur_decode_status = ST_DECODE_NEW; + cur_frame_num++; + } + break; + case ST_DECODE_ZERO: + if ((rlc > ONE_PULSE_LEN_LOW) && + (rlc < ONE_PULSE_LEN_HIGH)) { + if (bit & BIT_PULSE_MASK) { + /* "01" => 0 */ + cur_decode_status = ST_DECODE_NEW; + cur_frame_num++; + } else { + /* error */ + cur_decode_status = ST_DECODE_NEW; + cur_frame_num++; + } + } else if ((rlc > TWO_PULSE_LEN_LOW) && + (rlc < TWO_PULSE_LEN_HIGH)) { + if (bit & BIT_PULSE_MASK) { + /* "01" => 0 */ + cur_decode_status = ST_DECODE_ONE; + cur_frame_num++; + } else { + /* error */ + cur_decode_status = ST_DECODE_ZERO; + cur_frame_num++; + } + } + break; + case ST_DECODE_ONE: + if ((rlc > ONE_PULSE_LEN_LOW) && + (rlc < ONE_PULSE_LEN_HIGH)) { + if (bit & BIT_PULSE_MASK) { + /* "11" => error */ + cur_decode_status = ST_DECODE_NEW; + cur_frame_num++; + } else { + /* "10" => 1 */ + cur_decode_status = ST_DECODE_NEW; + cur_frame_num++; + } + } else if (rlc > TWO_PULSE_LEN_LOW) { + if (bit & BIT_PULSE_MASK) { + /* "11" => error */ + cur_decode_status = ST_DECODE_ONE; + cur_frame_num++; + } else { + /* "10" => 1 */ + cur_decode_status = ST_DECODE_ZERO; + cur_frame_num++; + } + } + break; + } /* switch*/ + + bit = buf & BIT_PULSE_MASK; + rlc = buf & BIT_LEN; + } + } /* for decode*/ + +/* + bit = ir->buf[cur_buf_num] & BIT_PULSE_MASK; + if (cur_decode_status & ST_DECODE_NEW) { + if (bit) { + *decode_status = ST_DECODE_ONE; + } else { + *decode_status = ST_DECODE_ZERO; + } + } else { + *decode_status = ST_DECODE_NEW; + } + *out_bit = bit; +*/ + + /* Fix problem 1 */ + if ((ir->buf[cur_buf_num] & BIT_LEN) > TWO_PULSE_LEN_LOW) { +#ifdef ALLOW_DEBUG_DECODE + printk("%s: fix problem 1 in jump_frame()\n", DRVNAME); +#endif +#ifdef ALLOW_DEBUG_DECODE + if (cur_frame_num > frame_num + 1) { + printk("%s error: jump_frame() get a too long frame\n", DRVNAME); + } +#endif + cur_buf_num--; + } + + /* copy from jump_iden */ + if (cur_decode_status & ST_DECODE_NEW) { +#ifdef ALLOW_DEBUG_DECODE + printk("hey man, it's NEW in jump_frame\n"); +printk("cur buf: 0x%x\n", ir->buf[cur_buf_num]); +printk("cur state: 0x%x\n", cur_decode_status); +#endif + *buf_num = --cur_buf_num; + /*//cur_buf_num--;*/ + *out_bit = ir->buf[cur_buf_num] & BIT_PULSE_MASK; + if (*out_bit) { + *decode_status = ST_DECODE_ONE; + } else { + *decode_status = ST_DECODE_ZERO; + } + } else { +#ifdef ALLOW_DEBUG_DECODE +printk("cur buf: 0x%x\n", ir->buf[cur_buf_num]); +printk("cur state: 0x%x\n", cur_decode_status); +#endif + *buf_num = cur_buf_num; + *out_bit = ir->buf[cur_buf_num] & BIT_PULSE_MASK; + *decode_status = ST_DECODE_NEW; +/* + if (*out_bit) { + *decode_status = ST_DECODE_ONE; + } else { + *decode_status = ST_DECODE_ZERO; + } +*/ + } + + return 0; +} + +int w83667hg_jump_head(struct irctl *ir, unsigned int *buf_num) +{ + unsigned int i, rlc = 0, max_buf_count = ir->buf_count; + u8 bit = BIT_PULSE_MASK, buf; + + for (i = 0; i < max_buf_count; i++) { + buf = ir->buf[i]; + if (bit == (buf & BIT_PULSE_MASK)) { + rlc += buf & BIT_LEN; + } else { + if ((rlc > HEAD_SYNC_LEN_LOW) && + (rlc < HEAD_SYNC_LEN_HIGH) && + (bit & BIT_PULSE_MASK)) { + break; + } + bit = buf & BIT_PULSE_MASK; + rlc = buf & BIT_LEN; + } + } /* for decode*/ + + if (i >= max_buf_count) { +/*//#ifdef ALLOW_DEBUG_DECODE*/ +#if 0 + printk("%s jump pulse error\n", DRVNAME); + printk("current buf num: %d\n", *buf_num); + printk("current jumped pulse: %d\n", i); + printk("current pulse length: %d\n", rlc); + printk("total cir signal:\n"); + for (i = 0; i < max_buf_count; i++) { + printk("0x%x ", ir->buf[i]); + if (i % 6 == 5) { + printk("\n"); + } + } +#endif + return -1; + } + + *buf_num = i; + + return 0; +} + + +int w83667hg_check_identification(u8 val, u8 identification, u8 *cur_iden) +{ + *cur_iden <<= 1; + *cur_iden |= val ; +#ifdef ALLOW_DEBUG_DECODE + printk("%s current check iden recv: %d\n", DRVNAME, val); + printk("%s current iden value: 0x%x\n", DRVNAME, *cur_iden); +#endif + + if (identification == (*cur_iden & IDENTIFICATION_CHECK_BIT)) { +#ifdef ALLOW_DEBUG_DECODE + printk("%s find identification\n\n", DRVNAME); +#endif + return 0; + } else { + return -1; + } +} + +int w83667hg_jump_identification(struct irctl *ir, u8 identification, unsigned int *buf_num, u8 *out_bit, u8 *decode_status) +{ + unsigned int rlc = 0, i = 1; + u8 bit = *out_bit, buf; + u8 cur_iden = 0; + u8 cur_decode_status = *decode_status; + + bit = BIT_PULSE_MASK; + cur_decode_status = ST_DECODE_NEW; + + for (; i < ir->buf_count; i++) { + buf = ir->buf[i]; +#ifdef ALLOW_DEBUG_DECODE +printk("buf: 0x%x\n", buf); +#endif + if (bit == (buf & BIT_PULSE_MASK)) { + rlc += buf & BIT_LEN; + } else { + /* decode*/ + switch (cur_decode_status) { + case ST_DECODE_NEW: + if ((rlc > ONE_PULSE_LEN_LOW) && + (rlc < ONE_PULSE_LEN_HIGH)) { + if (bit & BIT_PULSE_MASK) { + cur_decode_status = ST_DECODE_ONE; + } else { + cur_decode_status = ST_DECODE_ZERO; + } + } else if ((rlc > TWO_PULSE_LEN_LOW) && + (rlc < TWO_PULSE_LEN_HIGH)) { + /* error occur, just ignore */ + cur_decode_status = ST_DECODE_NEW; + if (!w83667hg_check_identification(0, identification, &cur_iden)) { + goto find_iden; + } + } + break; + case ST_DECODE_ZERO: + if ((rlc > ONE_PULSE_LEN_LOW) && + (rlc < ONE_PULSE_LEN_HIGH)) { + if (bit & BIT_PULSE_MASK) { + /* "01" => 0 */ + cur_decode_status = ST_DECODE_NEW; + if (!w83667hg_check_identification(0, identification, &cur_iden)) { + goto find_iden; + } + } else { + /* error */ + cur_decode_status = ST_DECODE_NEW; + if (!w83667hg_check_identification(0, identification, &cur_iden)) { + goto find_iden; + } + } + } else if ((rlc > TWO_PULSE_LEN_LOW) && + (rlc < TWO_PULSE_LEN_HIGH)) { + if (bit & BIT_PULSE_MASK) { + /* "01" => 0 */ + cur_decode_status = ST_DECODE_ONE; + if (!w83667hg_check_identification(0, identification, &cur_iden)) { + goto find_iden; + } + } else { + /* error */ + cur_decode_status = ST_DECODE_ZERO; + if (!w83667hg_check_identification(0, identification, &cur_iden)) { + goto find_iden; + } + } + } + break; + case ST_DECODE_ONE: + if ((rlc > ONE_PULSE_LEN_LOW) && + (rlc < ONE_PULSE_LEN_HIGH)) { + if (bit & BIT_PULSE_MASK) { + /* "11" => error */ + cur_decode_status = ST_DECODE_NEW; + if (!w83667hg_check_identification(0, identification, &cur_iden)) { + goto find_iden; + } + } else { + /* "10" => 1 */ + cur_decode_status = ST_DECODE_NEW; + if (!w83667hg_check_identification(1, identification, &cur_iden)) { + goto find_iden; + } + } + } else if (rlc > TWO_PULSE_LEN_LOW) { + if (bit & BIT_PULSE_MASK) { + /* "11" => error */ + cur_decode_status = ST_DECODE_ONE; + if (!w83667hg_check_identification(0, identification, &cur_iden)) { + goto find_iden; + } + } else { + /* "10" => 1 */ + cur_decode_status = ST_DECODE_ZERO; + if (!w83667hg_check_identification(1, identification, &cur_iden)) { + goto find_iden; + } + } + } + break; + } /* switch*/ + bit = buf & BIT_PULSE_MASK; + rlc = buf & BIT_LEN; + } + } + + if (i >= ir->buf_count) { +#ifdef ALLOW_DEBUG_DECODE + printk("%s jump iden error\n", DRVNAME); + printk("current buf num: %d\n", i); + printk("current pulse length: %d\n", rlc); + printk("total cir signal:\n"); + for (i = 0; i < ir->buf_count; i++) { + printk("0x%x ", ir->buf[i]); + if (i % 6 == 5) { + printk("\n"); + } + } +#endif + return -1; + } + + find_iden: +#ifdef ALLOW_DEBUG_DECODE + printk("current buf num after iden: %d\n", i); + printk("current pulse length: %d\n", rlc); +#endif + /* try fix problem 1 */ + if ((rlc & BIT_LEN) >= TWO_PULSE_LEN_LOW) { +#ifdef ALLOW_DEBUG_DECODE + printk("%s fix problem 1 in jump iden\n", DRVNAME); + printk("cur pulse len: %d\n", ir->buf[i] & BIT_LEN); +#endif + *buf_num = i + 1; + *out_bit = ir->buf[i] & BIT_PULSE_MASK; + if (*out_bit) { + *decode_status = ST_DECODE_ZERO; + } else { + *decode_status = ST_DECODE_ONE; + } + + return 0; + } + + /* now find identification successful! */ + { + *buf_num = i; + i--; + *out_bit = ir->buf[i] & BIT_PULSE_MASK; + if (bit) { + *decode_status = ST_DECODE_ONE; + } else { + *decode_status = ST_DECODE_ZERO; + } + } +#ifdef ALLOW_DEBUG_DECODE + printk("total cir signal:\n"); + for (i = 0; i < ir->buf_count; i++) { + printk("0x%x ", ir->buf[i]); + if (i % 7 == 6) { + printk("\n"); + } + } + printk("\n"); +#endif + + return 0; +} + +void w83667hg_submit_key(struct irctl *ir) +{ + unsigned int rlc = 0, buf_num = 0, i; + /* current usb keyboard key code setting, usb_kbd_keycode[keycode] */ + unsigned int input_code; + u8 bit, buf; + /* keycode and shiftmask parts in mce keyboard protocol*/ + u8 keycode = 0, shiftmask = 0; + u8 decode_status; + u8 frame_num, set_frame; + + /* 1) jump head */ + if (w83667hg_jump_head(ir, &buf_num)) { +#ifdef ALLOW_DEBUG_DECODE + printk("%s: decode key jump head error\n", DRVNAME); +#endif + return; + } +#ifdef ALLOW_DEBUG_DECODE + printk("%s buf_num after jump head: %d\n", DRVNAME, buf_num); +#endif + + /* 2) jump identification */ + if (w83667hg_jump_identification(ir, KEY_IDENTIFICATION, &buf_num, &bit, &decode_status)) { +#ifdef ALLOW_DEBUG_DECODE + printk("%s: decode key jump identification error\n", DRVNAME); +#endif + return; + } + +#ifdef ALLOW_DEBUG_DECODE + printk("%s jump iden success\n\n", DRVNAME); + printk("%s buf_num after jump iden: %d\n", DRVNAME, buf_num); + printk("decode status: 0x%x, bit: 0x%x\n", decode_status, bit); +#endif + + /* 3) jump "unknown", "C" and "CodeSet" parts in mce keyboard signal */ + if (w83667hg_jump_frame(ir, KEY_KEYCODE_FRAME_AFTER_I_START, &buf_num, &bit, &decode_status)) { +#ifdef ALLOW_DEBUG_DECODE + printk("%s: decode key jump pulse error\n", DRVNAME); +#endif + return; + } + +#ifdef ALLOW_DEBUG_DECODE + printk("%s buf_num after jump pulse: %d\n", DRVNAME, buf_num); + printk("decode status: 0x%x, bit: 0x%x\n", decode_status, bit); + frame_num = buf_num; + for (; frame_num < ir->buf_count; frame_num++) { + printk("0x%x\t", ir->buf[frame_num]); + if (frame_num % 7 == 6) { + printk("\n"); + } + } + printk("\n"); +#endif +#ifdef ALLOW_DEBUG_DECODE + printk("%s: decode status before check key: %x\n", DRVNAME, decode_status); +#endif + + + /* 4) deocde "KeyCode" and "ShiftMask" parts in mce key signal */ + frame_num = 1, set_frame = 1; + for (; frame_num < KEY_FRAME_AFTER_JUMP + 2; buf_num++) { + if (bit != (ir->buf[buf_num] & BIT_PULSE_MASK)) { + /* decode*/ + if (rlc > PULSE_SILENT_LEN_LOW) { +#ifdef ALLOW_DEBUG_DECODE + printk("%s error: cir signal end before received all key pulses\n", DRVNAME); + printk("bit: %d ", bit); + printk("rlc: %d\n", rlc); + printk("current pulse number: %d\n", frame_num); +#endif + if (decode_status == ST_DECODE_ONE) { + /* must set the last one */ + w83667hg_set_key(&set_frame, 1, &keycode, &shiftmask); + } + break; + } + switch (decode_status) { + case ST_DECODE_NEW: + if ((rlc > ONE_PULSE_LEN_LOW) && + (rlc < ONE_PULSE_LEN_HIGH)) { + if (bit & BIT_PULSE_MASK) { + decode_status = ST_DECODE_ONE; + } else { + decode_status = ST_DECODE_ZERO; + } + } else if ((rlc > TWO_PULSE_LEN_LOW) && + (rlc < TWO_PULSE_LEN_HIGH)) { + /* error occur, just ignore */ + decode_status = ST_DECODE_NEW; + w83667hg_set_key(&set_frame, 0, &keycode, &shiftmask); + frame_num += 1; + } +#ifdef ALLOW_DEBUG_DECODE + printk("%s cur state: %x\n", DRVNAME, decode_status); +#endif + break; + case ST_DECODE_ZERO: + if ((rlc > ONE_PULSE_LEN_LOW) && + (rlc < ONE_PULSE_LEN_HIGH)) { + if (bit & BIT_PULSE_MASK) { + /* "01" => 0 */ + decode_status = ST_DECODE_NEW; + w83667hg_set_key(&set_frame, 0, &keycode, &shiftmask); + frame_num += 1; + } else { + /* error */ + decode_status = ST_DECODE_NEW; + w83667hg_set_key(&set_frame, 0, &keycode, &shiftmask); + } + } else if ((rlc > TWO_PULSE_LEN_LOW) && + (rlc < TWO_PULSE_LEN_HIGH)) { + if (bit & BIT_PULSE_MASK) { + /* "01" => 0 */ + decode_status = ST_DECODE_ONE; + w83667hg_set_key(&set_frame, 0, &keycode, &shiftmask); + frame_num += 1; + } else { + /* error */ + decode_status = ST_DECODE_ZERO; + w83667hg_set_key(&set_frame, 0, &keycode, &shiftmask); + } + } +#ifdef ALLOW_DEBUG_DECODE + printk("%s cur state: %x\n", DRVNAME, decode_status); +#endif + break; + case ST_DECODE_ONE: + if ((rlc > ONE_PULSE_LEN_LOW) && + (rlc < ONE_PULSE_LEN_HIGH)) { + if (bit & BIT_PULSE_MASK) { + /* "11" => error */ + decode_status = ST_DECODE_NEW; + w83667hg_set_key(&set_frame, 0, &keycode, &shiftmask); + } else { + /* "10" => 1 */ + decode_status = ST_DECODE_NEW; + w83667hg_set_key(&set_frame, 1, &keycode, &shiftmask); + frame_num += 1; + } + } else if (rlc > TWO_PULSE_LEN_LOW) { + if (bit & BIT_PULSE_MASK) { + /* "11" => error */ + decode_status = ST_DECODE_ONE; + w83667hg_set_key(&set_frame, 0, &keycode, &shiftmask); + } else { + /* "10" => 1 */ + decode_status = ST_DECODE_ZERO; + w83667hg_set_key(&set_frame, 1, &keycode, &shiftmask); + frame_num += 1; + } + } +#ifdef ALLOW_DEBUG_DECODE + printk("%s cur state %x\n", DRVNAME, decode_status); +#endif + break; + } /* switch*/ + bit = ir->buf[buf_num] & BIT_PULSE_MASK; + rlc = ir->buf[buf_num] & BIT_LEN; +#ifdef ALLOW_DEBUG_DECODE + printk("%s: decode keyboard buf: 0x%x\n", DRVNAME, ir->buf[buf_num]); +#endif + + } else { + /* continue last pulse*/ + rlc += ir->buf[buf_num] & BIT_LEN; + } + + } /* for*/ + +#ifdef ALLOW_DEBUG_DECODE + printk("%s: after decode keyboard:\n", DRVNAME); + printk("keycode: 0x%x ", keycode); + printk("shiftmask: 0x%x\n\n", shiftmask); +#endif + + /* 5) submit keycode to input */ + if (keycode != ir->pressed_keycode) { + if (ir->pressed_keycode) { + input_code = (unsigned int)usb_kbd_keycode[ir->pressed_keycode]; + input_report_key(ir->input_dev, input_code, 0); + } + ir->pressed_keycode = keycode; + if (keycode) { + input_code = (unsigned int)usb_kbd_keycode[keycode]; + input_report_key(ir->input_dev, input_code, 1); + } + } + + /* 6) submit shiftmask to input */ + + if (shiftmask != ir->pressed_shiftmask) { + for (i = 0; i < 7; i++) { + buf = 1<pressed_shiftmask) && (!(buf & shiftmask))) { + input_code = (unsigned int)usb_kbd_keycode[0xE0 + i]; + input_report_key(ir->input_dev, input_code, 0); + } else if (!(buf & ir->pressed_shiftmask) && (buf & shiftmask)) { + input_code = (unsigned int)usb_kbd_keycode[0xE0 + i]; + input_report_key(ir->input_dev, input_code, 1); + } + } /* for*/ + ir->pressed_shiftmask = shiftmask; + } +} + +void w83667hg_set_mouse(u8 *set_frame, u8 val, u8 *deltay, u8 *deltax, u8 *clickrl) +{ +#ifdef ALLOW_DEBUG_DECODE + printk("%s set mouse val:%d\n", DRVNAME, val); +#endif + if (*set_frame <= MOUSE_SUBMIT_DELTAY_FRAME_NUM + 1) { + *deltay <<= 1; + *deltay |= val; +#ifdef ALLOW_DEBUG_DECODE + printk("%s set mouse delta y:0x%x\n", DRVNAME, *deltay); +#endif + } else if (*set_frame <= MOUSE_SUBMIT_DELTAX_FRAME_NUM) { + *deltax <<= 1; + *deltax |= val; +#ifdef ALLOW_DEBUG_DECODE + printk("%s set mouse delta x:0x%x\n", DRVNAME, *deltax); +#endif + } else if (*set_frame <= MOUSE_SUBMIT_L_FRAME_NUM) { + /* move right key, then set left key */ + *clickrl <<= 1; + *clickrl |= val; +#ifdef ALLOW_DEBUG_DECODE + printk("%s set mouse l:0x%x\n", DRVNAME, *clickrl); + printk("set pulse: %d\n", *set_frame); +#endif + } + (*set_frame)++; +} + +void w83667hg_submit_mouse(struct irctl *ir) +{ + unsigned int rlc = 0, buf_num = 0; + u8 bit; + /* deltax, deltay and clickrl parts in mce mouse protocol*/ + u8 deltax = 0, deltay = 0, clickrl = 0; + signed char x, y; + u8 decode_status; + u8 frame_num, set_frame; + + /* 1) jump head */ + if (w83667hg_jump_head(ir, &buf_num)) { +#ifdef ALLOW_DEBUG_DECODE + printk("%s: decode mouse jump head error\n", DRVNAME); +#endif + return; + } + + /* 2) jump identification */ + if (w83667hg_jump_identification(ir, MOUSE_IDENTIFICATION, &buf_num, &bit, &decode_status)) { +#ifdef ALLOW_DEBUG_DECODE + printk("%s: decode mouse jump identification error\n", DRVNAME); +#endif + return; + } +#ifdef ALLOW_DEBUG_DECODE + printk("%s: after iden mouse:\n", DRVNAME); + printk("decode status: 0x%x, bit: 0x%x\n", decode_status, bit); + frame_num = buf_num; + for (; frame_num < ir->buf_count; frame_num++) { + printk("0x%x ", ir->buf[frame_num]); + if (frame_num % 7 == 6) { + printk("\n"); + } + } + printk("\n"); +#endif + + /* 3) jump "unknown" part in mce mouse signal */ + if (w83667hg_jump_frame(ir, MOUSE_DELTAY_PULSE_AFTER_I_START, &buf_num, &bit, &decode_status)) { +#ifdef ALLOW_DEBUG_DECODE + printk("%s: decode mouse jump pulse error\n", DRVNAME); +#endif + return; + } +#ifdef ALLOW_DEBUG_DECODE + printk("%s: after jump pulse buf num: %d\n", DRVNAME, buf_num); + printk("decode status: 0x%x, bit: 0x%x\n", decode_status, bit); + frame_num = buf_num; + for (; frame_num < ir->buf_count; frame_num++) { + printk("0x%x ", ir->buf[frame_num]); + if (frame_num % 7 == 6) { + printk("\n"); + } + } + printk("\n"); +#endif + + /* 4) deocde "deltay", "deltax", "r" and "l" parts in mce mouse signal */ + frame_num = 1, set_frame = 1; + for (; frame_num < MOUSE_CHECKSUM_FRAME_AFTER_JUMP + 1; buf_num++) { +#ifdef ALLOW_DEBUG_DECODE + printk("%s: cur buf: 0x%x, pulse num: %d\n", DRVNAME, ir->buf[buf_num], frame_num); + printk("decode status: 0x%x\n", decode_status); +#endif + if (bit != (ir->buf[buf_num] & BIT_PULSE_MASK)) { + /* decode*/ + if (rlc > PULSE_SILENT_LEN_LOW) { +#ifdef ALLOW_DEBUG_DECODE + printk("%s error: cir signal end before received all mouse pulses\n", DRVNAME); + printk("bit: %d ", bit); + printk("rlc: %d\n", rlc); +#endif + break; + } + switch (decode_status) { + case ST_DECODE_NEW: + if ((rlc > ONE_PULSE_LEN_LOW) && + (rlc < ONE_PULSE_LEN_HIGH)) { + if (bit & BIT_PULSE_MASK) { + decode_status = ST_DECODE_ONE; + } else { + decode_status = ST_DECODE_ZERO; + } + } else + if ((rlc > TWO_PULSE_LEN_LOW) && + (rlc < TWO_PULSE_LEN_HIGH)) { + /* error occur, just ignore */ + decode_status = ST_DECODE_NEW; + w83667hg_set_mouse(&set_frame, 0, &deltay, &deltax, &clickrl); + frame_num += 1; + } + break; + case ST_DECODE_ZERO: + if ((rlc > ONE_PULSE_LEN_LOW) && + (rlc < ONE_PULSE_LEN_HIGH)) { + if (bit & BIT_PULSE_MASK) { + /* "01" => 0 */ + decode_status = ST_DECODE_NEW; + w83667hg_set_mouse(&set_frame, 0, &deltay, &deltax, &clickrl); + frame_num += 1; + } else { + /* error */ + decode_status = ST_DECODE_NEW; + w83667hg_set_mouse(&set_frame, 0, &deltay, &deltax, &clickrl); + } + } else if ((rlc > TWO_PULSE_LEN_LOW) && + (rlc < TWO_PULSE_LEN_HIGH)) { + if (bit & BIT_PULSE_MASK) { + /* "01" => 0 */ + decode_status = ST_DECODE_ONE; + w83667hg_set_mouse(&set_frame, 0, &deltay, &deltax, &clickrl); + frame_num += 1; + } else { + /* error */ + decode_status = ST_DECODE_ZERO; + w83667hg_set_mouse(&set_frame, 0, &deltay, &deltax, &clickrl); + } + } + break; + case ST_DECODE_ONE: + if ((rlc > ONE_PULSE_LEN_LOW) && + (rlc < ONE_PULSE_LEN_HIGH)) { + if (bit & BIT_PULSE_MASK) { + /* "11" => error */ + decode_status = ST_DECODE_NEW; + w83667hg_set_mouse(&set_frame, 0, &deltay, &deltax, &clickrl); + } else { + /* "10" => 1 */ + decode_status = ST_DECODE_NEW; + w83667hg_set_mouse(&set_frame, 1, &deltay, &deltax, &clickrl); + frame_num += 1; + } + } else if (rlc > TWO_PULSE_LEN_LOW) { + if (bit & BIT_PULSE_MASK) { + /* "11" => error */ + decode_status = ST_DECODE_ONE; + w83667hg_set_mouse(&set_frame, 0, &deltay, &deltax, &clickrl); + frame_num += 1; + } else { + /* "10" => 1 */ + decode_status = ST_DECODE_ZERO; + w83667hg_set_mouse(&set_frame, 1, &deltay, &deltax, &clickrl); + frame_num += 1; + } + } + break; + } /* switch*/ + bit = ir->buf[buf_num] & BIT_PULSE_MASK; + rlc = ir->buf[buf_num] & BIT_LEN; + } else { + /* continue last pulse*/ + rlc += ir->buf[buf_num] & BIT_LEN; + } + + } /* for*/ + +#ifdef ALLOW_DEBUG_DECODE + printk("%s: after decode mouse:\n", DRVNAME); + frame_num = buf_num; + for (; frame_num < ir->buf_count; frame_num++) { + printk("0x%x ", ir->buf[frame_num]); + if (frame_num % 7 == 6) { + printk("\n"); + } + } + printk("\n"); +#endif + + /* fix deltax lost problem */ + if (deltax) { + deltax <<= 1; + deltax |= 1; + } + +#ifdef ALLOW_DEBUG_DECODE + printk("%s: after decode mouse:\n", DRVNAME); + printk("deltay: 0x%x ", deltay); + printk("deltax: 0x%x ", deltax); + printk("click rl: 0x%x \n\n", clickrl); +#endif + if (deltay & 0x40) { + y = -((~deltay & 0x7f) + 1); + } else { + y = deltay; + } + if (deltax & 0x40) { + x = -((~deltax & 0x7f) + 1); + } else { + x = deltax; + } + + /* 5) send to input */ + +#ifdef ALLOW_DEBUG_DECODE + printk("%s: after decode mouse and rebuild:\n", DRVNAME); + printk("y: %d ", y); + printk("x: %d ", x); + printk("click rl: 0x%x \n\n", clickrl); +#endif + + input_report_rel(ir->input_dev, REL_X, x); + input_report_rel(ir->input_dev, REL_Y, y); + + input_report_key(ir->input_dev, BTN_LEFT, clickrl & 1); + input_report_key(ir->input_dev, BTN_RIGHT, (clickrl >> 1) & 1); +} + + diff -Nru nct677x-dkms-1.0.1/nct677x-1.0.4/src/lirc_wb677_mouse_kbd.h nct677x-dkms-1.0.4/nct677x-1.0.4/src/lirc_wb677_mouse_kbd.h --- nct677x-dkms-1.0.1/nct677x-1.0.4/src/lirc_wb677_mouse_kbd.h 1970-01-01 00:00:00.000000000 +0000 +++ nct677x-dkms-1.0.4/nct677x-1.0.4/src/lirc_wb677_mouse_kbd.h 2010-01-19 03:27:24.000000000 +0000 @@ -0,0 +1,190 @@ +#ifndef __LIRC_WB677_MOUSE_KBD_HEADER__ +#define __LIRC_WB677_MOUSE_KBD_HEADER__ + + + + +/* jump asked frame number, can use on key, mouse and controller signals + * + * after jump frame_num, current frame number = frame_num + 1 + * record current buf number of irctl buf + * record current pulse's bit and decode_status + * + * problem 1: + * When jump_frame() stops on a two_width_len pulse, the buf_num will be the + * second pulse of the double_width_len pulse. + * So jump_frame() must increase buf_num 1 on problem 1. + * For sample period is 50us, a 444us piulse's minimal sample value is 7, and + * two piulses' minimal sample value is 15. So just increase buf_num 1 works + * fine. If sample period changes, this solution also need change. + * + * one_width_len pulse: + * _ _ + * .| |_| |_. (1010) + * ^ + * | + * stop: jumped frame_num + * + * + * problem 1: double_width_len pulse: + * __ _ + * .| |__| |. (11001) + * ^ + * | + * stop: jumped frame_num + 1, buf_num + 1 + * + * so if cur buf len > TWO_PULSE_LEN_LOW, buf_num -- + * and recheck polar bit and decode_status + * decode_status go back 1 buf, + * NEW -> ONE/ZERO; ONE/ZERO -> NEW + * + * jump out of buf limit, return < 0 + */ +int w83667hg_jump_frame(struct irctl *ir, u8 frame_num, unsigned int *buf_num, u8 *out_bit, u8 *decode_status); + +/* jump MCE head sync signal (1111 11) + * + * after jump signal head, current pulse number = 7 + * record current buf number of irctl buf + * record current pulse's bit and decode_status + * + * jump out of buf limit, return < 0 + */ +int w83667hg_jump_head(struct irctl *ir, unsigned int *buf_num); + +#define KEY_IDENTIFICATION 0x04 +#define MOUSE_IDENTIFICATION 0x01 +#define IDENTIFICATION_CHECK_BIT 0xF + +/* check mce identification + * + * compare identification and cur_iden + * same return 0 + * else return < 0, need continue check + */ +int w83667hg_check_identification(u8 val, u8 identification, u8 *cur_iden); + +/* jump mce identification + * can use on key, mouse and controller signals + * + * jump and search identification parts + * record current buf number of irctl buf + * + * jump all pulse until find identification + * + * + * + * problem 1: + * When jump_identification() stops on a double_width_len pulse, the buf_num will be the + * second pulse of the doule_width_len frame. + * + * one_width_len pulse: + * _ _ + * .| |_| |_. (1010) + * ^ + * | + * stop: jumped frame_num + * + * + * problem 1: double_width_len pulse: + * __ _ + * .| |__| |. (11001) + * ^ + * | + * stop: jumped frame_num + 1, buf_num + 2 + * + * solution: + * Now buf_num is the next double-pulse-width buf. + * Just decrease buf_num by one can fix this problem. + * + * + * After jump iden, output may diff by decode status: + * 1) + * For status ONE and ZERO, all decode work is done. + * Set status as NEW and inverse out_bit + * in fact, bit is not important, for a buf can indicate one frame, whether its + * length is one or two, the bit can be ignored + * + * after jump frame, all status is NEW! reset them as inverse polar bit + * + * + * + * + * can not find identification, return < 0 + */ +int w83667hg_jump_identification(struct irctl *ir, u8 identification, unsigned int *buf_num, u8 *out_bit, u8 *decode_status); + + +/* the frame number between identification and code */ +#define KEY_KEYCODE_FRAME_AFTER_I_START 16 /*//32*/ +#define KEY_FRAME_AFTER_JUMP 16 /*//64*/ +#define KEY_SUBMIT_KEYCODE_FRAME_NUM 8 + + +#define MOUSE_DELTAY_PULSE_AFTER_I_START 8 +#define MOUSE_CHECKSUM_FRAME_AFTER_JUMP 16 +#define MOUSE_SUBMIT_DELTAY_FRAME_NUM 7 +#define MOUSE_SUBMIT_DELTAX_FRAME_NUM 14 +#define MOUSE_SUBMIT_R_FRAME_NUM 15 +#define MOUSE_SUBMIT_L_FRAME_NUM 16 + + +/* FIXME, not sure this value, select a large number*/ +#define PULSE_SILENT_LEN_LOW 90 + + +/* set keycode and shiftmask for keyboard */ +void w83667hg_set_key(u8 *set_frame, u8 val, u8 *keycode, u8 *shiftmask); + +/* decode mce keyboard signal and send data to input + * + * 1) jump mce keyboard signal sync head (1111 11) + * 2) jump identification (0100) + * pulse number before identification is not sure + * 3) jump "unknown", "C" and "CodeSet" parts in mce keyboard signal + * 4) deocde "KeyCode" and "ShiftMask" parts in mce key signal + * 5) send keycode to input by array usb_kbd_keycode + * 6) send shiftmask to input by array usb_kbd_keycode + */ +void w83667hg_submit_key(struct irctl *ir); + +/* set deltax, deltay, x, y for mce mouse */ +void w83667hg_set_mouse(u8 *set_frame, u8 val, u8 *deltay, u8 *deltax, u8 *clickrl); + +/* decode mce mouse signal and send data to input + * + * 1) jump mce mouse signal sync head (1111 11) + * 2) jump identification (0001) + * pulse number before identification is not sure + * 3) jump "unknown" part in mce mouse signal + * 4) deocde "deltay", "deltax", "r" and "l" parts in mce mouse signal + * 5) send these parts to input + */ +void w83667hg_submit_mouse(struct irctl *ir); + + + +#define BIT_PULSE_MASK 0x80 +#define BIT_LEN 0x7f + + + +/* "10"=>1 (+2), "01"=>0 (+2) */ +#define ST_DECODE_NEW 0x01 +#define ST_DECODE_ZERO 0x02 +#define ST_DECODE_ONE 0x04 + +/* RC6 sync head: 1111 11 + * 6 * 444us / 50us (sample period) * 0.85 (inaccuracy) + */ +#define HEAD_SYNC_LEN_LOW 45 +/* 7 pulses long, for inaccuracy */ +#define HEAD_SYNC_LEN_HIGH 71 + +#define ONE_PULSE_LEN_LOW 2 +#define ONE_PULSE_LEN_HIGH 10 +#define TWO_PULSE_LEN_LOW 10 +#define TWO_PULSE_LEN_HIGH 15 + + +#endif diff -Nru nct677x-dkms-1.0.1/nct677x-1.0.4/src/Makefile nct677x-dkms-1.0.4/nct677x-1.0.4/src/Makefile --- nct677x-dkms-1.0.1/nct677x-1.0.4/src/Makefile 1970-01-01 00:00:00.000000000 +0000 +++ nct677x-dkms-1.0.4/nct677x-1.0.4/src/Makefile 2010-01-13 06:36:56.000000000 +0000 @@ -0,0 +1,66 @@ +#!/bin/bash + +# Notice : +# for dkms, make cmd was defined in dkms.conf as MAKE[0]. generally we define it as +# MAKE[0] = "make ..." +# however, when dkms build this target, it was invoked by "make KERNELRELEASE=xxx ..." instead +# that cause the plain make file below can not work again : +# +# ifneq ($(KERNELRELEASE),) +# obj-m := lirc_wb667.o +# lirc_wb667-objs := lirc_wb667.o +# else +# KERNEL_SRC_TREE ?= /lib/modules/$(shell uname -r)/build +# PWD := $(shell pwd) +# modules modules_install clean: +# make -C $(KERNEL_SRC_TREE) M=$(PWD) $@ +# endif +# +# it can not work because KERNELRELEASE was defined in dkms's case. so we should merge the two +# cases together : + +# on Linux 2.6 kernel +# If KERNELRELEASE is defined, we've been invoked from the +# kernel build system and can use its language. + + + + LIRC_DIR := /usr/src/lirc-0.8.6 + + obj-m += lirc_wb677.o + + lirc_wb677-objs := lirc_wb677_main.o lirc_wb677_mouse_kbd.o + + KSRC ?= /lib/modules/$(shell uname -r)/build + + PWD := $(shell pwd) +modules: + echo KERNELDIR=$(KSRC) + $(MAKE) -C $(KSRC) -I $(LIRC_DIR) M=$(PWD) modules + + +# Following "install", "uninstall" and "clean" are not for dkms. + +install: + /etc/init.d/lirc stop + rmmod lirc_wb677 || echo "lirc_wb677.ko is not executing" + file="lirc_wb677.ko"; \ + dir="/lib/modules/$(shell uname -r)/kernel/ubuntu/lirc/lirc_wb677"; \ + if test -d "$$dir"; then echo ""; else mkdir -p $$dir; fi; \ + cp -vf *.ko $$dir + depmod -a + patch -p0 /usr/share/lirc/lirc.hwdb < /usr/share/lirc/lirc_nct667x-src-1.0.0-ubuntu9.10.patch + @echo "" + @echo "Hint: You can execute \"dpkg-reconfigure lirc\" to configure lirc." + @echo " And start lirc by executing \"/etc/init.d/lirc start\"" + +uninstall: + /etc/init.d/lirc stop + ( rmmod lirc_wb677 ) || echo "lirc_wb677.ko is not executing" + dir="/lib/modules/$(shell uname -r)/kernel/ubuntu/lirc/lirc_wb677"; \ + if test -d "$$dir"; then rm -R $$dir; fi; + depmod -a + patch -R -p0 /usr/share/lirc/lirc.hwdb < /usr/share/lirc/lirc_nct667x-src-1.0.0-ubuntu9.10.patch + +clean: + rm -rf *.o *.ko *.mod.c Module.symvers .tmp_versions .*.cmd diff -Nru nct677x-dkms-1.0.1/nct677x-1.0.4/src/wb83677hg_ir.h nct677x-dkms-1.0.4/nct677x-1.0.4/src/wb83677hg_ir.h --- nct677x-dkms-1.0.1/nct677x-1.0.4/src/wb83677hg_ir.h 1970-01-01 00:00:00.000000000 +0000 +++ nct677x-dkms-1.0.4/nct677x-1.0.4/src/wb83677hg_ir.h 2010-01-13 06:36:56.000000000 +0000 @@ -0,0 +1,44 @@ +#define IR_IOC_MAGIC 'i' + +/* output chip registers for debug */ +#define IR_DUMPCIRREG _IO(IR_IOC_MAGIC, 0x80) +#define IR_DUMPWAKEREG _IO(IR_IOC_MAGIC, 0x81) + + +/* study wake key on MCE CIR controller */ +#define IR_IOLEARNWAKE _IO(IR_IOC_MAGIC, 0x82) + +/* disable cir wake */ +#define IR_IOUNSETWAKE _IO(IR_IOC_MAGIC, 0x83) + +/* enable cir wake */ +#define IR_IOSETWAKE _IO(IR_IOC_MAGIC, 0x84) + + +/* get carrier for study ir signal */ +#define IR_IOGETCARRIER _IOR(IR_IOC_MAGIC, 0x85, unsigned int) + +/* set carrier for send ir signal */ +#define IR_IOSETCARRIER _IOW(IR_IOC_MAGIC, 0x86, unsigned int) + +/* start/stop study key */ +#define IR_IOSTARTSTUDY _IO(IR_IOC_MAGIC, 0x88) +#define IR_IOSTOPSTUDY _IO(IR_IOC_MAGIC, 0x89) + +/* study key buf len */ +#define IR_IOSTUDYLEN _IOR(IR_IOC_MAGIC, 0x8A, unsigned int) + +/* study key buf data */ +#define IR_IOSTUDYBUF _IOR(IR_IOC_MAGIC, 0x8B, unsigned char) + +/* restudy key buf data */ +#define IR_IORESTUDYBUF _IO(IR_IOC_MAGIC, 0x8C) + + +/* clean data */ +#define IR_IOCLEANDATA _IO(IR_IOC_MAGIC, 0x8E) + + +/* check chip identification for the applications which are related to hardware */ +#define IR_CHECKCHIP _IOR(IR_IOC_MAGIC, 0x8F, unsigned long long) +