=== kernels/linux-2.6.15/include/linux/neuros_ir.h ================================================================== --- kernels/linux-2.6.15/include/linux/neuros_ir.h (revision 15) +++ kernels/linux-2.6.15/include/linux/neuros_ir.h (revision 17) @@ -0,0 +1,44 @@ +#ifndef NEUROS_IR__H +#define NEUROS_IR__H +/* + * Copyright(C) 2006-2007 Neuros Technology International LLC. + * + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2 of the License. + * + * This program is distributed in the hope that, in addition to its + * original purpose to support Neuros hardware, it will be useful + * otherwise, 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. + * + **************************************************************************** + * + * IR Receiver driver header. + * + * REVISION: + * + * 2) Split from irrtc driver ----------------------------- 2006-12-20 nerochiaro + * 1) Initial creation. ----------------------------------- 2005-06-02 MG + * + */ +#ifdef __KERNEL__ + #include + extern int i2c_write(uint8_t reg, uint16_t value); + extern int i2c_read(uint8_t reg); +#else + #include +#endif + +#define NEUROS_IR_MAJOR 110 +#define NEUROS_IR_IOC_MAGIC 'i' + +#endif /* NEUROS_IR__H */ + === kernels/linux-2.6.15/include/linux/neuros_generic.h ================================================================== --- kernels/linux-2.6.15/include/linux/neuros_generic.h (revision 15) +++ kernels/linux-2.6.15/include/linux/neuros_generic.h (revision 17) @@ -0,0 +1,43 @@ +#ifndef NEUROS_GENERIC__H +#define NEUROS_GENERIC__H +/* + * Copyright(C) 2006-2007 Neuros Technology International LLC. + * + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2 of the License. + * + * This program is distributed in the hope that, in addition to its + * original purpose to support Neuros hardware, it will be useful + * otherwise, 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. + * + **************************************************************************** + * + * Neuros generic driver header. + * + * REVISION: + * + * 1) Initial creation. ----------------------------------- 2005-06-02 MG + * + */ +#ifdef __KERNEL__ + #include +#else + #include +#endif + +#define NEUROS_GENERIC_MAJOR 104 +#define NEUROS_GENERIC_IOC_MAGIC 'g' + +#define NT_GENERIC_SET_ARM_CLOCK _IOW(NEUROS_GENERIC_IOC_MAGIC, 8, int) + +#endif /* NEUROS_GENERIC__H */ + === kernels/linux-2.6.15/include/linux/neuros_ir_blaster.h ================================================================== --- kernels/linux-2.6.15/include/linux/neuros_ir_blaster.h (revision 15) +++ kernels/linux-2.6.15/include/linux/neuros_ir_blaster.h (revision 17) @@ -0,0 +1,100 @@ +#ifndef NEUROS_IR_BLASTER__H +#define NEUROS_IR_BLASTER__H +/* + * Copyright(C) 2006-2007 Neuros Technology International LLC. + * + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2 of the License. + * + * This program is distributed in the hope that, in addition to its + * original purpose to support Neuros hardware, it will be useful + * otherwise, 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. + * + **************************************************************************** + * + * IR Blaster driver header. + * + * REVISION: + * + * 2) Split from irrtc driver ----------------------------- 2006-12-20 nerochiaro + * 1) Initial creation. ----------------------------------- 2005-06-02 MG + * + */ +#ifdef __KERNEL__ + #include + extern int i2c_write(uint8_t reg, uint16_t value); + extern int i2c_read(uint8_t reg); +#else + #include +#endif + +#define NEUROS_IR_BLASTER_MAJOR 111 +#define NEUROS_IR_BLASTER_IOC_MAGIC 'b' + +/* RRB registers definitions. */ +#define regCMND 0 // command register. +#define regIR 0x40 // IR receiver register. +#define regFLASH_DATA 0x06 // used to put blaster data{part2) +#define regBLASTER_DATA 0x1C // used to put blaster data(part1) + +// I2C command definitions. +#define cmdBLASTER_SEND 0x18 + +#define CAPTRUE_PRECISION 2 /*averaged off x*10% difference.*/ +#define the_same(x,y) \ + (((x*10<=y*(10+CAPTRUE_PRECISION))&&(y*10<=x*(10+CAPTRUE_PRECISION)))?1:0) + +#define BLASTER_MAX_CHANGE (8*12) /* maximum edge changes. */ +#define BLASTER_MAX_SBITS 10 /*special edge number min is 6*/ +#define BLASTER_MAX_BITS 96 /*maximum edge changes, use for uncompacted data structure*/ +#define END_COUNT 8 /*number of edges for end bit. */ + +struct blaster_data_pack { + uint16_t bitstimes; /*first[15] 1 bit 1=high level 0=low level; + [14-8]7 bit =how many bits; [2-0]3 bit=how many repeat times*/ + uint8_t mbits[BLASTER_MAX_CHANGE/8]; + uint8_t dbits[BLASTER_MAX_CHANGE/8]; + + uint16_t bit0; + uint16_t bit1; + uint16_t bit2; + + uint16_t specbits[BLASTER_MAX_SBITS]; +}; + +struct blaster_data_type { + uint16_t bitstimes; /*first[15] 1 bit 1=high level 0=low level; + [14-8]7 bit =how many bits; [2-0]3 bit=how many repeat times*/ + uint16_t start1; /*start mark first length */ + uint16_t start2; /*start mark second length*/ + uint16_t interval; /*interval for each times */ + + uint16_t bits[BLASTER_MAX_BITS]; /*each bit length*/ + uint16_t end[END_COUNT]; + uint16_t osd_key; +}; + +#define keybit_set(bi, base, val) \ + do {\ + if (val)\ + *(base + (bi / 8)) |=(1 << (bi % 8));\ + else\ + *(base + (bi / 8)) &=~(1 << (bi % 8));\ + } while(0) + +#define RRB_CAPTURE_KEY _IOR(NEUROS_IR_BLASTER_IOC_MAGIC, 7, \ + struct blaster_data_type) +#define RRB_BLASTER_KEY _IOW(NEUROS_IR_BLASTER_IOC_MAGIC, 8, \ + struct blaster_data_pack) + +#endif /* NEUROS_IR_BLASTER__H */ + === kernels/linux-2.6.15/arch/arm/configs/ntosd-dm320_defconfig ================================================================== --- kernels/linux-2.6.15/arch/arm/configs/ntosd-dm320_defconfig (revision 15) +++ kernels/linux-2.6.15/arch/arm/configs/ntosd-dm320_defconfig (revision 17) @@ -520,6 +520,8 @@ # Input device support # CONFIG_INPUT=y +CONFIG_INPUT_MISC=y +CONFIG_INPUT_NEUROS_IR=m # # Userland interfaces @@ -590,6 +592,7 @@ CONFIG_I2C_ALGOIT_POLL=y # CONFIG_I2C_ALGOBIT is not set # CONFIG_I2C_ALGOPCA is not set +CONFIG_I2C_ALGO_NEUROS_MSP430=m # # I2C Hardware Bus support @@ -644,6 +647,9 @@ # # Misc devices # +CONFIG_NEUROS_GENERIC=m +CONFIG_NEUROS_IR_BLASTER=m +CONFIG_XLOCK=m # # Multimedia Capabilities Port drivers === kernels/linux-2.6.15/drivers/input/misc/Kconfig ================================================================== --- kernels/linux-2.6.15/drivers/input/misc/Kconfig (revision 15) +++ kernels/linux-2.6.15/drivers/input/misc/Kconfig (revision 17) @@ -67,4 +67,17 @@ Say Y here if you want to support the built-in real time clock of the HP SDC controller. +config INPUT_NEUROS_IR + tristate "Neuros IR driver" + depends on ARCH_ITDM3XX + help + This option enables the Neuros IR driver. + + FIXME: This needs a better description. + + To compile this driver as a module (recommended), choose M here: the + module will be called neuros_ir. + + If unsure and targeting the Neuros OSD, say M. + endif === kernels/linux-2.6.15/drivers/input/misc/neuros_ir.c ================================================================== --- kernels/linux-2.6.15/drivers/input/misc/neuros_ir.c (revision 15) +++ kernels/linux-2.6.15/drivers/input/misc/neuros_ir.c (revision 17) @@ -0,0 +1,435 @@ +/* + * Copyright(C) 2006-2007 Neuros Technology International LLC. + * + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2 of the License. + * + * This program is distributed in the hope that, in addition to its + * original purpose to support Neuros hardware, it will be useful + * otherwise, 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. + * + **************************************************************************** + * + * IR Receiver driver. + * + * REVISION: + * 3) Split from irrtc driver ----------------------------- 2006-12-20 nerochiaro + * 2) proc interupt support ------------------------------- 2006-06-20 EY + * 1) Initial creation. ----------------------------------- 2005-06-02 MG + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include "neuros_keymaps.h" + +#define MOD_DESC "Neuros IR Driver (c) 2006" + +#if 0 + #define dbg(fmt, arg...) \ + printk(KERN_INFO "%s:%d> " fmt, __func__, __LINE__ , ## arg) +#else + #define dbg(fmt, arg...) +#endif + +extern void get_osd_key_wakeup(void); +extern void lock_data_protect(void); +extern void unlock_data_protect(void); + + +#define USE_WORKQUEUE 1 +#define READ_ONLY_ONE_KEY 1 +#define IR_RETRY_COUNT 3 + +struct irrtc_device { + int key; +}; +static struct irrtc_device device; + +static wait_queue_head_t wait; +static wait_queue_head_t poll_queue; + +static char *devname = "neuros_ir"; +static struct input_dev *ir_input_dev; + +#if USE_WORKQUEUE +#define KEYBUF_SIZE 1 +static int keybuf[KEYBUF_SIZE]; +static int roffset=0; +static int woffset=0; +static int numOfKeys=0; +#else +static int keyin=0; +#endif + +static void irrtc_report_key(int ir_key); + +DECLARE_MUTEX(keybuf_sem); + +static int read_keybuf(void) +{ + int key = 0; + + if (-EINTR == down_interruptible(&keybuf_sem)) + return 0; + + printk("numOfKeys = %d", numOfKeys); + if (numOfKeys > 0) + { + numOfKeys--; + key = keybuf[roffset]; + if(roffset+1 KEYBUF_SIZE)? KEYBUF_SIZE: numOfKeys; + + offset = woffset; + if(offset+1 KEYBUF_SIZE * sizeof(int)) { + if (roffset <= woffset) + count = (woffset - roffset) * sizeof(int); + else + count = (KEYBUF_SIZE - (roffset - woffset + 1)) * sizeof(int); + } + + if (count == 0) { + printk("buffer empty\n"); + goto out; + } + + if (roffset < woffset) + copy_to_user(buff, keybuf + roffset, count); + else { + copy_to_user(buff, &keybuf[roffset], (KEYBUF_SIZE - roffset + 1) * sizeof(int)); + copy_to_user(buff + (KEYBUF_SIZE - roffset + 1) * sizeof(int), keybuf, woffset * sizeof(int)); + } + +out: + up(&keybuf_sem); +#endif + return count; +} + +static ssize_t irrtc_write(struct file * file, const char __user * buf, size_t count, loff_t *ppos) +{ + int key; + if (copy_from_user(&key, buf, sizeof(int))) + return -1; + + //printk("-----------------%x\n",key); + irrtc_report_key(key); //before adding to keybuf we report this key to the input system + + write_keybuf(key); + wake_up_interruptible(&poll_queue); + return count; +} + +static unsigned int irrtc_poll(struct file*filp, poll_table*wait) +{ + unsigned int mask = 0; + poll_wait(filp, &poll_queue, wait); + if (numOfKeys) + mask |= POLLIN | POLLRDNORM; + return mask; +} + +static struct file_operations irrtc_fops = { + .open = irrtc_open, + .release = irrtc_release, + .read = irrtc_read, + .poll = irrtc_poll, + .write = irrtc_write, +}; + +//-------------------------------------------------- PROC FS ENTRY -------------------------------------------------------- +/* +static int irrtc_proc_read(char * page, char ** start, off_t offset, int count, int * eof, void * data) +{ + int key = 0; + int length = 0; + +#if USE_WORKQUEUE + key=read_keybuf(); +#else + if(keyin==1) + { + keyin=0; + key = i2c_read(0x40); + } +#endif + length += sprintf(page + length, "IR Key: %d\n", key); + *eof = 1; + return length; +} + +static void proc_irrtc_init( void ) +{ + create_proc_read_entry( "neuros_ir", 0, 0, irrtc_proc_read, &device ); +} + +static void proc_irrtc_exit( void ) +{ + remove_proc_entry("neuros_ir", 0); +} + +static void irqs_irrtc_exit( void ) +{ + free_irq(IRQ_GIO0, &device); +} +*///PROC: + +//-------------------------------------------------- LINUX INPUT DEVICE --------------------------------------------------- + +// setup all input device information and actually create the device +static void irrtc_inputdev_init(void) +{ + int i; + + ir_input_dev = input_allocate_device(); + ir_input_dev->name = devname; + ir_input_dev->evbit[0] = BIT(EV_KEY); //this is the type of events we will generate. only keys. + + // set a bit in the input device structure for each key that we are able to generate. + for (i = 0; i < NUM_KEYS; i++) + if (keymap[i] != 0) + set_bit(keymap[i], ir_input_dev->keybit); + + input_register_device(ir_input_dev); //done. we can now send events into the system. +} + +// close the input device +static void irrtc_inputdev_close(void) +{ + input_unregister_device(ir_input_dev); +} + +// gets an IR key code and reports it to the input system +static void irrtc_report_key(int key) +{ + int code; + + // Repeat keypresses on IR remote have different codes, but we treat all them as normal key + // presses by clearing away the modifiers. + if ((key & 0x80) == 0x80) key ^= 0x80; //START_REPEAT_MOD + if ((key & 0x40) == 0x40) key ^= 0x40; //REPEAT_MOD + + // Map the code to one of the standard keboard codes accepted by the input system. + // todo: allow keymap switching via ioctl (maybe custom remapping too) + code = (key > NUM_KEYS) ? 0 : keymap[key]; + if (code == 0) code = KEY_UNKNOWN; + + printk("neuros_ir -- I am reporting: %d\n", code); + + // Report a full key press + release for each even received from IR. I see no other way to do this + // until MSP430 can send us properly flagged "key release" codes. + input_report_key(ir_input_dev, code, 1); + input_report_key(ir_input_dev, code, 0); +} + +//-------------------------------------------------- INIT / EXIT ---------------------------------------------------------- + +static const char * pname = "NEUROS_IR(KM):"; + +static int __init irrtc_init(void) +{ + int status = 0; + + init_waitqueue_head (&wait); + init_waitqueue_head (&poll_queue); + + printk(KERN_INFO "\t" MOD_DESC "\n"); + + status = register_chrdev(NEUROS_IR_MAJOR, "neuros_ir", &irrtc_fops); + if (status != 0) + { + if (status == -EINVAL) printk(KERN_ERR "%s Couldn't register device: invalid major number %d.\n", pname, NEUROS_IR_MAJOR); + else if (status == -EBUSY) printk(KERN_ERR "%s Couldn't register device: major number %d already busy.\n", pname, NEUROS_IR_MAJOR); + else printk(KERN_ERR "%s Couldn't register device: error %d.\n", pname, status); + status = -1; + + goto out; + } + + irrtc_inputdev_init(); + + //proc_irrtc_init(); //PROC: + irqs_irrtc_init(); + +out: + return status; +} + +static void __exit irrtc_exit(void) +{ + //proc_irrtc_exit(); //PROC + irqs_irrtc_exit(); + irrtc_inputdev_close(); + unregister_chrdev(NEUROS_IR_MAJOR, "neuros_ir"); +} + +MODULE_AUTHOR("Neuros"); +MODULE_DESCRIPTION(MOD_DESC); +MODULE_LICENSE("Neuros Technology LLC"); + +module_init(irrtc_init); +module_exit(irrtc_exit); === kernels/linux-2.6.15/drivers/input/misc/neuros_keymaps.h ================================================================== --- kernels/linux-2.6.15/drivers/input/misc/neuros_keymaps.h (revision 15) +++ kernels/linux-2.6.15/drivers/input/misc/neuros_keymaps.h (revision 17) @@ -0,0 +1,72 @@ +/* + * Copyright(C) 2006-2007 Neuros Technology International LLC. + * + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2 of the License. + * + * This program is distributed in the hope that, in addition to its + * original purpose to support Neuros hardware, it will be useful + * otherwise, 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. + * + **************************************************************************** + * + * IR Receiver driver / key mappings file + * + * TODO: support 2 different mappings (current keyboard-area mapping and another mapping which uses media keys) + * TODO: make the 2 mappings switchable via ioctl. Maybe allow remapping at runtime via ioctl. + * + * REVISION: + * 1) Initial creation. ----------------------------------- 2006-12-20 nerochiaro + * + */ + +#define NUM_KEYS 36 + +static int keymap[NUM_KEYS] = { + 0, //0 + KEY_KP1, //1 + KEY_KP2, //2 + KEY_KP3, //3 + KEY_KP4, //4 + KEY_KP5, //5 + KEY_KP6, //6 + KEY_KP7, //7 + KEY_KP8, //8 + KEY_KP9, //9 + KEY_KP0, //10 + 0, //11 + 0, //12 + 0, //13 + 0, //14 + KEY_KPASTERISK, //15 "*" + KEY_KPDOT, //16 "#" //this was the only way. + KEY_PAGEUP, //17 CHAN_UP + KEY_PAGEDOWN, //18 CHAN_DN + KEY_BACKSPACE, //19 BACK + KEY_ESC, //20 HOME + KEY_UP, //21 UP + KEY_DOWN, //22 DOWN + KEY_LEFT, //23 LEFT + KEY_RIGHT, //24 RIGHT + KEY_ENTER, //25 ENTER + KEY_H, //26 HELP // no better idea than H + KEY_TAB, //27 XIM // TAB seems just better than X, no other reason + KEY_U, //28 UNLABELED_1 //this is a tiny "Unknown" and "Unlabeled" tiny key on remote + KEY_KPMINUS, //29 REW + KEY_KPPLUS, //30 FFW + KEY_SPACE, //31 PLAY //Most media apps use space for quick pause/play + KEY_HOME, //32 PREV + KEY_END, //33 NEXT + KEY_DELETE, //34 STOP + KEY_INSERT //35 RECORD +}; + === kernels/linux-2.6.15/drivers/input/misc/Makefile ================================================================== --- kernels/linux-2.6.15/drivers/input/misc/Makefile (revision 15) +++ kernels/linux-2.6.15/drivers/input/misc/Makefile (revision 17) @@ -11,3 +11,4 @@ obj-$(CONFIG_INPUT_UINPUT) += uinput.o obj-$(CONFIG_INPUT_WISTRON_BTNS) += wistron_btns.o obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o +obj-$(CONFIG_INPUT_NEUROS_IR) += neuros_ir.o === kernels/linux-2.6.15/drivers/misc/Kconfig ================================================================== --- kernels/linux-2.6.15/drivers/misc/Kconfig (revision 15) +++ kernels/linux-2.6.15/drivers/misc/Kconfig (revision 17) @@ -28,5 +28,45 @@ If unsure, say N. +config NEUROS_GENERIC + tristate "Neuros generic (multipurpose) driver" + depends on ARCH_ITDM3XX + ---help--- + This option enables a generic multipurpose driver intended for Neuros + products (mainly the OSD). + + Currently, this driver includes support for setting the system clock + frequency via the on-chip PLL. + + To compile this driver as a module (recommended), choose M here: the + module will be called neuros_generic. + + If unsure and targeting the Neuros OSD, say M. + +config NEUROS_IR_BLASTER + tristate "Neuros IR blaster driver" + depends on ARCH_ITDM3XX + ---help--- + This option enables the Neuros IR blaster driver. + + TODO: This needs a better description. + + To compile this driver as a module (recommended), choose M here: the + module will be called neuros_ir_blaster. + + If unsure and targeting the Neuros OSD, say M. + +config XLOCK + tristate "xlock driver" + ---help--- + This option enables the xlock driver. + + TODO: This needs a better description. + + To compile this driver as a module (recommended), choose M here: the + module will be called xlock. + + If unsure and targeting the Neuros OSD, say M. + endmenu === kernels/linux-2.6.15/drivers/misc/xlock.c ================================================================== --- kernels/linux-2.6.15/drivers/misc/xlock.c (revision 15) +++ kernels/linux-2.6.15/drivers/misc/xlock.c (revision 17) @@ -0,0 +1,84 @@ +/* + * Copyright(C) 2006 Neuros Technology International LLC. + * + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2 of the License. + * + * This program is distributed in the hope that, in addition to its + * original purpose to support Neuros hardware, it will be useful + * otherwise, 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. + * + **************************************************************************** + * + * A driver for lock + */ + +#include +#include +#include +#include +#include +#include + +#define DEVICE_NAME "xlock" +#define XLOCK_MAJOR 103 + +DECLARE_MUTEX(keybuf_sem); +static ssize_t flock_write(struct file * file, const char __user * buf, size_t count, + loff_t *ppos) +{ + int key; + + if (copy_from_user(&key, buf, sizeof(int))) + goto bail; + if (key == 0) + { + //printk("here is unlock\n"); + up(&keybuf_sem); + //printk("here is unlock returned\n"); + } + else + { + //printk("here is lock\n"); + down_interruptible(&keybuf_sem); + //printk("here is lock returned\n"); + + } + bail: + return count; +} + +static struct file_operations xlock_fops = +{ + .owner = THIS_MODULE, + .write = flock_write, +}; + +static int __init xlock_init(void) +{ + int ret; + ret = register_chrdev(XLOCK_MAJOR, DEVICE_NAME, &xlock_fops); + return ret; +} + +static void __exit xlock_exit(void) +{ + int ret; + + ret = unregister_chrdev(XLOCK_MAJOR, DEVICE_NAME); + if (ret < 0) + printk(KERN_ALERT "Unregister error: %d\n", ret); +} + +MODULE_AUTHOR("Neuros Technologies"); +module_init(xlock_init); +module_exit(xlock_exit); === kernels/linux-2.6.15/drivers/misc/neuros_ir_blaster.c ================================================================== --- kernels/linux-2.6.15/drivers/misc/neuros_ir_blaster.c (revision 15) +++ kernels/linux-2.6.15/drivers/misc/neuros_ir_blaster.c (revision 17) @@ -0,0 +1,419 @@ +/* + * Copyright(C) 2006-2007 Neuros Technology International LLC. + * + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2 of the License. + * + * This program is distributed in the hope that, in addition to its + * original purpose to support Neuros hardware, it will be useful + * otherwise, 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. + * + **************************************************************************** + * + * IR BLASTER driver. + * + * REVISION: + * 3) Split from irrtc driver ----------------------------- 2006-12-20 nerochiaro + * 2) proc interupt support ------------------------------- 2006-06-20 EY + * 1) Initial creation. ----------------------------------- 2005-06-02 MG + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#define MOD_DESC "Neuros IR Blaster Driver (c) 2006" + +#if 0 + #define dbg(fmt, arg...) \ + printk(KERN_INFO "%s:%d> " fmt, __func__, __LINE__ , ## arg) +#else + #define dbg(fmt, arg...) +#endif + +#define LEARNING_THROUGH_MSP430 0 +#define BLASTER_THROUGH_ARM 0 +#define LEANRING_COMPLETE_DELAY (HZ/10) + +static struct timer_list learning_key_timer; +static struct blaster_data_type BlsKey; +static uint8_t real_key = 0; + +struct irrtc_device { + int key; +}; +static struct irrtc_device device; +static wait_queue_head_t wait; +static spinlock_t data_protect = SPIN_LOCK_UNLOCKED; + +static void lock_data_protect(void) +{ + spin_lock(&data_protect); +} +EXPORT_SYMBOL(lock_data_protect); + +static void unlock_data_protect(void) +{ + spin_unlock(&data_protect); +} +EXPORT_SYMBOL(unlock_data_protect); + +static void get_osd_key_wakeup(void) +{ + BlsKey.osd_key = 0xff&i2c_read(0x40); + wake_up_interruptible(&wait); +} +EXPORT_SYMBOL(get_osd_key_wakeup); + +static int blaster_key(struct blaster_data_pack* blsdat) +{ + int i; + uint8_t *a = (uint8_t*)blsdat; + //compact_bls_data(blsdat); + for(i=0;ispecbits); + for(i=0;i<16;i++) + { + dbg("data = %X\n", *(a+i)); + i2c_write(regFLASH_DATA+i, *(a+i)); + } + i2c_write(regCMND, cmdBLASTER_SEND); +} + +void timer_handle(unsigned long data) +{ + int *a = (int*)data; + int atimes; + dbg("bitstimes=%d\n", BlsKey.bitstimes); + if( *a & 1) { + (*a) &= ~1; + learning_key_timer.expires = jiffies + LEANRING_COMPLETE_DELAY; + learning_key_timer.data = (unsigned long)a; + learning_key_timer.function = timer_handle; + add_timer(&learning_key_timer); + } + else if ((BlsKey.bitstimes & 7) || real_key) { + if (real_key) { + atimes = BlsKey.bitstimes & 7; + if ((++atimes) > 7) + atimes=7; + BlsKey.bitstimes &= (~7); + BlsKey.bitstimes |= atimes; + real_key=0; + } + + (*a) &= ~2; + mdelay(160); + outw( inw( IO_GIO_IRQPORT) & (~0x0008), IO_GIO_IRQPORT); // gio 3 external IRQ disable + lock_data_protect(); + if(!BlsKey.osd_key) + wake_up_interruptible(&wait); + unlock_data_protect(); + + } + else { + (*a) &= ~2; + } +} + +static int capture_key(struct blaster_data_type* blsdat) +{ +#if LEARNING_THROUGH_MSP430 + int i; + blsdat->bitstimes = i2c_read(regBITSTIMES); + blsdat->interval = i2c_read(regINTERVAL); + blsdat->start1 = i2c_read(regSTART1); + blsdat->start2 = i2c_read(regSTART2); + for (i = 0; i < BLASTER_MAX_BITS; i++) + blsdat->bits[i] = i2c_read(regBITS + i); +#else + /*static int start1=0; + static int start2=0;*/ + static int oldusec=0; + static int oldsec=0; + static int times=0; + static int oatimes; + static int atimes; + static struct timeval tm; + static struct timeval stm; + static int td; + static int timer_added = 0; + + timer_added |= 1; + if(!(timer_added&2)) + { + learning_key_timer.data = (unsigned long) &timer_added; + learning_key_timer.function = timer_handle; + mod_timer(&learning_key_timer, jiffies + LEANRING_COMPLETE_DELAY); + timer_added |= 2; + } + + do_gettimeofday(&tm); + if (tm.tv_sec != oldsec) + td = (tm.tv_sec-oldsec) * 1000000 + tm.tv_usec - oldusec; + else + td = tm.tv_usec-oldusec; + + oldsec = tm.tv_sec; + oldusec = tm.tv_usec; + if (/*(tm.tv_sec-stm.tv_sec)*1000000+(tm.tv_usec-stm.tv_usec)*/td > 100000) //500ms + { + times = 0; + atimes = 1; + memset(blsdat, 0, sizeof(struct blaster_data_type)); + } + if (0 == times++) + { + stm = tm; + oldusec = tm.tv_usec; + blsdat->bitstimes |= ((inw(IO_GIO_BITSET2) | 0x0004) << 13); + oatimes = BLASTER_MAX_BITS; + } + else + { + if (times > (BLASTER_MAX_CHANGE - 2)) + return 0; + if (td > 10000)//10ms + { + if (real_key) + { + real_key = 0; + oatimes = times; + blsdat->interval = td; + blsdat->bitstimes &= 0x8000; + if (atimes > 7) + atimes = 7; + blsdat->bitstimes |= ((((times - 1) & 0x7F) << 8) + (atimes & 0x07)); + atimes++; + } + times = 1; + stm = tm; + return 0; + } + + if (times == 2) + { + blsdat->bitstimes |= 0x80; + } + else if (times == 5) + { + blsdat->bitstimes &= ~0x0080; + } + if (times < 10) + blsdat->end[times-2] = td; + + else if (times == 10) + { + real_key = 1; + blsdat->start1 = blsdat->end[0]; + blsdat->start2 = blsdat->end[1]; + blsdat->bits[0] = blsdat->end[2]; + blsdat->bits[1] = blsdat->end[3]; + blsdat->bits[2] = blsdat->end[4]; + blsdat->bits[3] = blsdat->end[5]; + blsdat->bits[4] = blsdat->end[6]; + blsdat->bits[5] = blsdat->end[7]; + blsdat->bits[6] = td; + memset(blsdat->end, 0, 8); + } + else if (times > 10) + blsdat->bits[times-4] = td; + } +#endif + + return(0); +} + +static irqreturn_t handle_blaster_irqs(int irq, void * dev_id, struct pt_regs * regs) +{ +#if !LEARNING_THROUGH_MSP430 + capture_key(&BlsKey); +#endif + //printk("get interrupt blaster %d %d\n",tm.tv_sec,tm.tv_usec); + + return IRQ_HANDLED; +} + +static int blaster_init( void ) +{ + outw( inw( IO_GIO_DIR2 ) & (~(0x0002)), IO_GIO_DIR2 ); //gio 33 direction output + outw( inw( IO_GIO_FSEL3) | 0x0003, IO_GIO_FSEL3 ); //gio 33 fsel clkout1b + + outw( (inw( IO_CLK_OSEL) & 0xFF0F)| 0x0000, IO_CLK_OSEL ); //clk arm clock + //outw( inw( IO_CLK_OSEL) & (~(0x0000)), IO_CLK_OSEL ); //clk arm clock + + outw( 0x0530, IO_CLK_O1DIV); //clk div 2*(x+1) 38K:0x0A47 40K:0x09C3 +#if BLASTER_THROUGH_ARM + outw( inw( IO_GIO_DIR2 ) & (~(0x0004)), IO_GIO_DIR2 ); //gio 34 direction output + outw( inw( IO_GIO_FSEL3) & (~(0x000C)), IO_GIO_FSEL3 ); //gio 34 fsel clr 2:3 normal gio +#endif + + outw( inw( IO_GIO_DIR0 ) | 0x0008, IO_GIO_DIR0 ); //gio 3 direction input + //outw( inw( IO_GIO_INV0 ) | 0x0008, IO_GIO_INV0 ); //gio 3 inv + outw( inw( IO_GIO_IRQPORT) & (~0x0008), IO_GIO_IRQPORT); //gio 3 external IRQ disable + outw( inw( IO_GIO_IRQEDGE) | 0x0008, IO_GIO_IRQEDGE); // gio 3 any edge + + request_irq(IRQ_GIO3, handle_blaster_irqs,SA_INTERRUPT , "ir_blaster", &device); //SA_SHIRQSA_INTERRUPT +} + +//--------------------------------------------------- DEVICE -------------------------------------------------------------- + +static int irrtc_open(struct inode * inode, struct file * file) +{ +#ifdef ONLYOPENONE + if (opened) + return -EBUSY; + opened = 1; +#endif + + return 0; +} + +static int irrtc_release(struct inode * inode, struct file * file) +{ +#ifdef ONLYOPENONE + if (!opened) + return -ERESTARTSYS; + + opened = 0; +#endif + + return 0; +} + +static spinlock_t lock = SPIN_LOCK_UNLOCKED; +static int irrtc_ioctl(struct inode * inode, struct file * file, + unsigned int cmd, unsigned long arg) +{ + int ret = 0; + int arg_size; + + spin_lock(&lock); + + if (_IOC_TYPE(cmd) != NEUROS_IR_BLASTER_IOC_MAGIC) + { + ret = -EINVAL; + goto bail; + } + + arg_size = _IOC_SIZE(cmd); + if (_IOC_DIR(cmd) & _IOC_READ) + ret = !access_ok(VERIFY_WRITE, (void *)arg, arg_size); + else if (_IOC_DIR(cmd) & _IOC_WRITE) + ret = !access_ok(VERIFY_READ, (void *)arg, arg_size); + if (ret) goto bail; + + switch (cmd) + { + case RRB_BLASTER_KEY: + { + struct blaster_data_pack bls_key; + copy_from_user(&bls_key, (void*)arg, sizeof(bls_key)); + blaster_key(&bls_key); + } + break; + case RRB_CAPTURE_KEY: + { + //outw( inw( IO_GIO_IRQPORT) & ~0x0001, IO_GIO_IRQPORT); // gio 0 external IRQ(ir) disable when learning + spin_unlock(&lock); + BlsKey.osd_key=0; + outw( inw( IO_GIO_IRQPORT) | 0x0008, IO_GIO_IRQPORT); // gio 3 external IRQ enable + interruptible_sleep_on(&wait); + ret |= copy_to_user((void*)arg, &BlsKey, sizeof(BlsKey)); + return ret; + } + break; + + default: + ret = -EINVAL; + break; + } + +bail: + spin_unlock(&lock); + return ret; +} + +static struct file_operations irrtc_fops = { + .open = irrtc_open, + .release = irrtc_release, + .ioctl = irrtc_ioctl, +}; + +//-------------------------------------------------- INIT / EXIT ---------------------------------------------------------- + +static const char * pname = "NEUROS_IRBLAST(KM):"; + +//~ static void irqs_irrtc_init( void ) +//~ { + //~ outw( inw( IO_GIO_DIR0 ) | 0x0001, IO_GIO_DIR0 ); //gio 0 direction input + //~ outw( inw( IO_GIO_INV0 ) | 0x0001, IO_GIO_INV0 ); //gio 0 inv + //~ outw( inw( IO_GIO_IRQPORT) | 0x0001, IO_GIO_IRQPORT); // gio 0 external IRQ enable + //~ request_irq(IRQ_GIO0, handle_irrtc_irqs, 0, "irrtc", &device); +//~ } + +//~ static void irqs_irrtc_exit( void ) +//~ { + //~ free_irq(IRQ_GIO0, &device); +//~ } + +static int __init irrtc_init(void) +{ + int status = 0; + init_timer(&learning_key_timer); + init_waitqueue_head (&wait); + + printk(KERN_INFO "\t" MOD_DESC "\n"); + + status = register_chrdev(NEUROS_IR_BLASTER_MAJOR, "ir_blaster", &irrtc_fops); + if (status != 0) + { + if (status == -EINVAL) printk(KERN_ERR "%s Couldn't register device: invalid major number %d.\n", pname, NEUROS_IR_BLASTER_MAJOR); + else if (status == -EBUSY) printk(KERN_ERR "%s Couldn't register device: major number %d already busy.\n", pname, NEUROS_IR_BLASTER_MAJOR); + else printk(KERN_ERR "%s Couldn't register device: error %d.\n", pname, status); + status = -1; + goto out; + } + + //~ irqs_irrtc_init(); + blaster_init(); + +out: + return status; +} + +static void __exit irrtc_exit(void) +{ + //~ irqs_irrtc_exit(); + + unregister_chrdev(NEUROS_IR_BLASTER_MAJOR, "ir_blaster"); +} + +MODULE_AUTHOR("Neuros"); +MODULE_DESCRIPTION(MOD_DESC); +MODULE_LICENSE("Neuros Technology LLC"); + +module_init(irrtc_init); +module_exit(irrtc_exit); + + === kernels/linux-2.6.15/drivers/misc/neuros_generic.c ================================================================== --- kernels/linux-2.6.15/drivers/misc/neuros_generic.c (revision 15) +++ kernels/linux-2.6.15/drivers/misc/neuros_generic.c (revision 17) @@ -0,0 +1,217 @@ +/* + * Copyright(C) 2006-2007 Neuros Technology International LLC. + * + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2 of the License. + * + * This program is distributed in the hope that, in addition to its + * original purpose to support Neuros hardware, it will be useful + * otherwise, 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. + * + **************************************************************************** + * + * Neuros generic device driver, various system controls. + * + * REVISION: + * + * 1) Initial creation. ----------------------------------- 2006-01-20 MG + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include + +#define MOD_DESC "Neuros Neuros_Generic Driver (c) 2006" + +#if 1 + #define dbg(fmt, arg...) \ + printk(KERN_INFO "%s:%d> " fmt, __func__, __LINE__ , ## arg) +#else + #define dbg(fmt, arg...) +#endif + + +static void mem_outw (unsigned short val,unsigned long add) +{ + outw (val,add); + wmb(); +} + +static unsigned short mem_inw (unsigned long add) +{ + unsigned short val; + + val = inw (add); + rmb(); + return val; +} + + +// --- DEVICE ----------------------------------------------------------------- + +static int neuros_generic_open(struct inode * inode, struct file * file) +{ + return 0; +} + +static int neuros_generic_release(struct inode * inode, struct file * file) +{ + return 0; +} + +static ssize_t neuros_generic_read(struct file *filp, char __user *buff, size_t count, loff_t *ppos) +{ + return count; +} + +static ssize_t neuros_generic_write(struct file * file, const char __user * buf, size_t count, loff_t *ppos) +{ + return count; +} + +// clock in MHz +static void set_clock(int clock) +{ + dbg("clock = %d\n", clock); + + // WARNING: experimental, running clock above 202 is still risky, + // clock above 243 is dangerous. + + if (clock > 270) + { + // clock = 270MHz + mem_outw ((mem_inw (IO_CLK_PLLA) & 0xff00)|0x90, IO_CLK_PLLA); + } + else if (clock > 243) + { + // clock = 243MHz + mem_outw ((mem_inw (IO_CLK_PLLA) & 0xff00)|0x80, IO_CLK_PLLA); + } + else if (clock > 202) + { + // clock = 216MHz + mem_outw ((mem_inw (IO_CLK_PLLA) & 0xff00)|0x70, IO_CLK_PLLA); + } + else + { + // clock = 202MHz + mem_outw ((mem_inw (IO_CLK_PLLA) & 0xff00)|0xe1, IO_CLK_PLLA); + } + udelay(500); // wait till PLL stablized. +} + +static int neuros_generic_ioctl(struct inode * inode, struct file * file, + unsigned int cmd, unsigned long arg) +{ + int ret = 0; + int arg_size; + + if (_IOC_TYPE(cmd) != NEUROS_GENERIC_IOC_MAGIC) + { + ret = -EINVAL; + goto bail; + } + + arg_size = _IOC_SIZE(cmd); + if (_IOC_DIR(cmd) & _IOC_READ) + ret = !access_ok(VERIFY_WRITE, (void *)arg, arg_size); + else if (_IOC_DIR(cmd) & _IOC_WRITE) + ret = !access_ok(VERIFY_READ, (void *)arg, arg_size); + if (ret) goto bail; + + switch (cmd) + { + case NT_GENERIC_SET_ARM_CLOCK: + { + int clock; + copy_from_user(&clock, (void*)arg, sizeof(int)); + set_clock(clock); + break; + } + default: + ret = -EINVAL; + break; + } + +bail: + return ret; +} + +static unsigned int neuros_generic_poll(struct file*filp, poll_table*wait) +{ + return 0; +} + +static struct file_operations neuros_generic_fops = { + .open = neuros_generic_open, + .release = neuros_generic_release, + .read = neuros_generic_read, + .poll = neuros_generic_poll, + .write = neuros_generic_write, + .ioctl = neuros_generic_ioctl, +}; + + +// --- INIT / EXIT ------------------------------------------------------------ + +static const char * pname = "NEUROS_GENERIC(KM):"; + +static int __init neuros_generic_init(void) +{ + int status = 0; + + printk(KERN_INFO "\t" MOD_DESC "\n"); + status = register_chrdev(NEUROS_GENERIC_MAJOR, "neuros_ir", &neuros_generic_fops); + if (status != 0) + { + if (status == -EINVAL) + printk(KERN_ERR "%s Couldn't register device: invalid major number %d.\n", + pname, NEUROS_GENERIC_MAJOR); + else if (status == -EBUSY) + printk(KERN_ERR "%s Couldn't register device: major number %d already busy.\n", + pname, NEUROS_GENERIC_MAJOR); + else printk(KERN_ERR "%s Couldn't register device: error %d.\n", pname, status); + status = -1; + } + return status; +} + +static void __exit neuros_generic_exit(void) +{ + unregister_chrdev(NEUROS_GENERIC_MAJOR, "neuros_generic"); +} + +MODULE_AUTHOR("Neuros"); +MODULE_DESCRIPTION(MOD_DESC); +MODULE_LICENSE("Neuros Technology LLC"); + +module_init(neuros_generic_init); +module_exit(neuros_generic_exit); === kernels/linux-2.6.15/drivers/misc/Makefile ================================================================== --- kernels/linux-2.6.15/drivers/misc/Makefile (revision 15) +++ kernels/linux-2.6.15/drivers/misc/Makefile (revision 17) @@ -5,3 +5,6 @@ obj-$(CONFIG_IBM_ASM) += ibmasm/ obj-$(CONFIG_HDPU_FEATURES) += hdpuftrs/ +obj-$(CONFIG_NEUROS_GENERIC) += neuros_generic.o +obj-$(CONFIG_NEUROS_IR_BLASTER) += neuros_ir_blaster.o +obj-$(CONFIG_XLOCK) += xlock.o === kernels/linux-2.6.15/drivers/i2c/algos/Kconfig ================================================================== --- kernels/linux-2.6.15/drivers/i2c/algos/Kconfig (revision 15) +++ kernels/linux-2.6.15/drivers/i2c/algos/Kconfig (revision 17) @@ -81,5 +81,17 @@ Supports the SGI interfaces like the ones found on SGI Indy VINO or SGI O2 MACE. +config I2C_ALGO_NEUROS_MSP430 + tristate "Neuros MSP430 interface" + depends on I2C && ARCH_ITDM3XX + help + Supports the I2C interface found on the Neuros OSD (primarily used + for communicating with the MSP430 IR controller chip). + + To compile this driver as a module (recommended), choose M here: the + module will be called i2c-algo-neuros-msp430. + + If unsure and targeting the Neuros OSD, say M. + endmenu === kernels/linux-2.6.15/drivers/i2c/algos/i2c-algo-neuros-msp430.c ================================================================== --- kernels/linux-2.6.15/drivers/i2c/algos/i2c-algo-neuros-msp430.c (revision 15) +++ kernels/linux-2.6.15/drivers/i2c/algos/i2c-algo-neuros-msp430.c (revision 17) @@ -0,0 +1,259 @@ +/* + * Copyright(C) 2006-2007 Neuros Technology International LLC. + * + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2 of the License. + * + * This program is distributed in the hope that, in addition to its + * original purpose to support Neuros hardware, it will be useful + * otherwise, 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. + * + **************************************************************************** + * + * MSP430 i2c driver. + * + * REVISION: + * 3) Split from irrtc driver --------------------------- 2006-12-20 nerochiaro + * 2) proc interupt support------------------------------ 2006-06-20 EY + * 1) Initial creation. --------------------------------- 2005-06-02 MG + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#if 0 + #define dbg(fmt, arg...) \ + printk(KERN_INFO "%s:%d> " fmt, __func__, __LINE__ , ## arg) +#else + #define dbg(fmt, arg...) +#endif + +#define MG_HACK 0 + +#define I2C_RETRY_HACK 1 +#define I2C_RETRY_COUNT 3 + +#if MG_HACK // startof MG-HACK +void mem_outw (unsigned short val,unsigned long add){ + + outw (val,add); + wmb(); +} + +unsigned short mem_inw (unsigned long add){ + + unsigned short val; + + val = inw (add); + rmb(); + return val; +} +#endif // endof MG-HACK + +#define MOD_DESC "MSP430 I2C Driver (c) 2006" + +static int irrtc_attach_adapter(struct i2c_adapter * adapter); +static int irrtc_detach_client(struct i2c_client * client); + +static unsigned short normal_i2c[] = { + 0x59, /* 7-bit address does not require >> 1 */ + I2C_CLIENT_END +}; + +/* +static unsigned short normal_i2c_range[] = { + I2C_CLIENT_END +}; +*/ +I2C_CLIENT_INSMOD; + +static struct i2c_client* irrtc_client = NULL; + +static struct i2c_driver irrtc_driver = { + .owner = THIS_MODULE, + .name = "MSP430 I2C v.$Revision: 1.24 $", + .id = I2C_DRIVERID_IRRTC, + .flags = I2C_DF_NOTIFY, + .attach_adapter = &irrtc_attach_adapter, + .detach_client = &irrtc_detach_client, +}; + +static const char * pname = "MPS430_I2C(KM):"; + +static int i2c_write(u8 reg, u16 value) +{ +#if I2C_RETRY_HACK + int retry = I2C_RETRY_COUNT; + int ret = -1; + + while(retry--) + { + ret = i2c_smbus_write_byte_data(irrtc_client, reg, value & 0xFF); + if (-1 != ret) break; + printk("retrying count = [%d]\n", retry); + } + return ret; +#else + dbg("%s i2c_write %02x = %04x\n", pname, reg, value); + return i2c_smbus_write_byte_data(irrtc_client, reg, value & 0xFF); +#endif +} +EXPORT_SYMBOL(i2c_write); + +static int i2c_read(u8 reg) +{ +#if I2C_RETRY_HACK + int retry = I2C_RETRY_COUNT; + int dat; + while(retry--) + { + dat = i2c_smbus_read_byte_data(irrtc_client, reg); + if (-1 != dat) break; + printk("retrying count = [%d]\n", retry); + } + return dat; +#else + return(i2c_smbus_read_byte_data(irrtc_client, reg)); +#endif +} +EXPORT_SYMBOL(i2c_read); + +static int irrtc_detect_client(struct i2c_adapter * adapter, int address, int kind) +{ + int ret = 0; + struct i2c_client* client = NULL; + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE)) + { + dbg("ERROR returned from i2c_check_functionality"); + ret = -1; + goto out; + } + + if (!(client = kmalloc(sizeof(*client), GFP_KERNEL))) + { + dbg("ERROR error returned from kmalloc"); + ret = -ENOMEM; + goto out; + } + + memset(client, 0, sizeof(struct i2c_client)); + + client->addr = address; + client->adapter = adapter; + client->driver = &irrtc_driver; + client->flags = I2C_M_IGNORE_NAK; + + strcpy(client->name, "irrtc"); + + if ((ret = i2c_attach_client(client)) != 0) + { + dbg("%s Unable to attach client.\n", pname); + kfree(client); + ret = -1; + goto out; + } + + irrtc_client = client; + +#if 0 + printk("Reading remote ID\n"); + printk("Register:Value 0x%02X:0x%02X\n", 0x36, i2c_read(0x36)); +#endif +out: + return ret; +} + +static int irrtc_attach_adapter(struct i2c_adapter * adapter) +{ + return(i2c_probe(adapter, &addr_data, &irrtc_detect_client)); +} + +static int irrtc_detach_client(struct i2c_client * client) +{ + int ret = 0; + + if ((ret = i2c_detach_client(client)) != 0) + { + dbg("%s Unable to detach client.\n", pname); + goto out; + } + + kfree(client); + +out: + return ret; +} + +//---------------------------------------------------------- INIT / EXIT --------------------------------------------------------- + +static int __init irrtc_init(void) +{ + int status = 0; + +#if MG_HACK //MG -HACK to use PLL as I2C clock to slow down traffic. + printk(KERN_INFO "FIXME: I should not be here!!!\n"); + { + // disable I2C clock first. + mem_outw ((mem_inw (IO_CLK_MOD2) & (~(0x1000))),IO_CLK_MOD2); + + mem_outw ((mem_inw (IO_CLK_SEL0) | 0x0C00),IO_CLK_SEL0); + + mem_outw ((mem_inw (IO_CLK_DIV4) & (~(0x001F))) | 0x0A, IO_CLK_DIV4); + + // reenable I2C clock here. + mem_outw ((mem_inw (IO_CLK_MOD2) | 0x1000),IO_CLK_MOD2); + } +#endif + + printk(KERN_INFO "\t" MOD_DESC "\n"); + + if ((status = i2c_add_driver(&irrtc_driver)) < 0) + { + printk(KERN_INFO "%s Couldn't register MSP430 I2C driver.\n", pname); + goto out; + } + +out: + return status; +} + +static void __exit irrtc_exit(void) +{ + i2c_del_driver(&irrtc_driver); +} + +MODULE_AUTHOR("Neuros"); +MODULE_DESCRIPTION(MOD_DESC); +MODULE_LICENSE("Neuros Technology LLC"); + +module_init(irrtc_init); +module_exit(irrtc_exit); + + === kernels/linux-2.6.15/drivers/i2c/algos/Makefile ================================================================== --- kernels/linux-2.6.15/drivers/i2c/algos/Makefile (revision 15) +++ kernels/linux-2.6.15/drivers/i2c/algos/Makefile (revision 17) @@ -9,6 +9,7 @@ obj-$(CONFIG_I2C_ALGO_SIBYTE) += i2c-algo-sibyte.o obj-$(CONFIG_I2C_ALGO_SGI) += i2c-algo-sgi.o obj-$(CONFIG_I2C_ALGOIT) += i2c-algo-ingenient.o +obj-$(CONFIG_I2C_ALGO_NEUROS_MSP430) += i2c-algo-neuros-msp430.o ifeq ($(CONFIG_I2C_DEBUG_ALGO),y) EXTRA_CFLAGS += -DDEBUG === rootfs/base/etc/init.d/mainsetup ================================================================== --- rootfs/base/etc/init.d/mainsetup (revision 15) +++ rootfs/base/etc/init.d/mainsetup (revision 17) @@ -131,10 +131,7 @@ MODULE_DIR="/lib/modules/${MY_KERNVERSION}/kernel/drivers" echo "loading xlock driver ..." > ${OSDTMP} - if [ -e ${MODULE_DIR}/xlock/xlock.ko ] - then insmod xlock - fi fi if [ "${LOAD_MODULES}x" = "1x" ] @@ -215,16 +212,13 @@ done fi - MODULES_MISC="neuros_msp430_i2c" + MODULES_MISC="i2c-algo-neuros-msp430" if [ "${LOAD_MISC_MODULES}x" = "1x" ] then for MODULE in ${MODULES_MISC} do - if [ -e ${MODULE_DIR}/${MODULE}.ko ] - then - echo "loading ${MODULE} ..." > ${OSDTMP} - ${MODPROBE} ${MODULE} - fi + echo "loading ${MODULE} ..." > ${OSDTMP} + ${MODPROBE} ${MODULE} done fi @@ -234,11 +228,8 @@ then for MODULE in ${MODULES_MISC2} do - if [ -e ${MODULE_DIR}/${MODULE}.ko ] - then - echo "loading ${MODULE} ..." > ${OSDTMP} - ${MODPROBE} ${MODULE} & - fi + echo "loading ${MODULE} ..." > ${OSDTMP} + ${MODPROBE} ${MODULE} & done fi === rootfs/Makefile ================================================================== --- rootfs/Makefile (revision 15) +++ rootfs/Makefile (revision 17) @@ -22,9 +22,6 @@ MODULES_DO_NOT_STRIP := aic23.ko \ tvp5150.ko \ itfb.ko \ - neuros_msp430_i2c.ko \ - neuros_ir.ko \ - neuros_ir_blaster.ko \ neuros_rtc.ko MODULES_LIB_STRIP := libaacenc.so \