diff options
author | nbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2005-07-10 09:44:28 +0000 |
---|---|---|
committer | nbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2005-07-10 09:44:28 +0000 |
commit | c132dc87067ddf8607f254642aa3b8c3609783ed (patch) | |
tree | ecbce4b273f3b35f1b4612a45d015f11793c9f4e /target/linux/linux-2.4/patches/ar7/002-led_driver.patch | |
parent | a4a0c48042e240d42bbf68e9711a6e6cb0747e18 (diff) |
clean up patches, add atm driver proc support, add real led driver
git-svn-id: svn://svn.openwrt.org/openwrt/trunk/openwrt@1388 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target/linux/linux-2.4/patches/ar7/002-led_driver.patch')
-rw-r--r-- | target/linux/linux-2.4/patches/ar7/002-led_driver.patch | 2140 |
1 files changed, 2140 insertions, 0 deletions
diff --git a/target/linux/linux-2.4/patches/ar7/002-led_driver.patch b/target/linux/linux-2.4/patches/ar7/002-led_driver.patch new file mode 100644 index 000000000..dbf1932f5 --- /dev/null +++ b/target/linux/linux-2.4/patches/ar7/002-led_driver.patch @@ -0,0 +1,2140 @@ +diff -urN kernel-old/drivers/char/avalanche_led/led_drv.c kernel-current/drivers/char/avalanche_led/led_drv.c +--- kernel-old/drivers/char/avalanche_led/led_drv.c 1970-01-01 01:00:00.000000000 +0100 ++++ kernel-current/drivers/char/avalanche_led/led_drv.c 2005-07-10 18:40:23.008730752 +0200 +@@ -0,0 +1,375 @@ ++/****************************************************************************** ++ * FILE PURPOSE: - LED driver module Source ++ ****************************************************************************** ++ * FILE NAME: led_drv.c ++ * ++ * DESCRIPTION: Linux LED character driver implementation ++ * ++ * REVISION HISTORY: ++ * 27 Aug 2003 Initial Creation Sharath Kumar<krs@ti.com> ++ * ++ * 16 Dec 2003 Updates for 5.7 Sharath Kumar<krs@ti.com> ++ * ++ * 07 Jan 2004 Wrapper for DSL Sharath Kumar<krs@ti.com> ++ * ++ * (C) Copyright 2002, Texas Instruments, Inc ++ *******************************************************************************/ ++ ++#include <linux/config.h> ++#include <linux/module.h> ++#include <linux/init.h> ++#include <linux/types.h> ++#include <linux/errno.h> ++#include <linux/slab.h> ++#include <linux/ioport.h> ++#include <linux/fcntl.h> ++#include <linux/interrupt.h> ++#include <linux/sched.h> ++#include <linux/mm.h> ++#include <asm/io.h> ++#include <asm/uaccess.h> ++#include <asm/system.h> ++#include <linux/delay.h> ++#include <linux/devfs_fs_kernel.h> ++#include <linux/wait.h> ++#include <linux/proc_fs.h> ++#include <linux/timer.h> ++#include <asm/ar7/sangam.h> ++#include <asm/ar7/avalanche_misc.h> ++ ++#include "led_config.h" ++#include "led_hal.h" ++#include "led_ioctl.h" ++#include "led_platform.h" ++ ++//#define tnetd73xx_gpio_ctrl(gpio_pin, pin_mode, pin_direction) avalanche_gpio_ctrl(gpio_pin, pin_mode, pin_direction) ++#define tnetd73xx_gpio_out(gpio_pin, value) avalanche_gpio_out_bit(gpio_pin, value) ++//#define avalanche_gpio_in_bit(gpio_pin) tnetd73xx_gpio_in(gpio_pin) ++ ++#define TI_LED_VERSION "0.1" ++#define GPIO_MAP_LEN ((MAX_GPIO_PIN_NUM/32) + 1) ++ ++static int gpio_off_state[GPIO_MAP_LEN] = AVALANCHE_GPIO_OFF_MAP; ++ ++#define TRUE 1 ++#define FALSE 0 ++#define FLICK_TIME (HZ*100/1000) ++static unsigned int wan_txrx_state = 0; ++static unsigned int wlan_txrx_state = 0; ++struct timer_list *pWanTimer = NULL; ++ ++static void wan_led_func(unsigned long data) ++{ ++ avalanche_gpio_ctrl(2, GPIO_PIN, GPIO_OUTPUT_PIN); ++ avalanche_gpio_ctrl(3, GPIO_PIN, GPIO_OUTPUT_PIN); ++ ++ if (wan_txrx_state == 0) ++ { ++ tnetd73xx_gpio_out(2, TRUE); ++ tnetd73xx_gpio_out(3, FALSE); ++ wan_txrx_state = 1; ++ } ++ else ++ { ++ tnetd73xx_gpio_out(2, FALSE); ++ tnetd73xx_gpio_out(3, FALSE); ++ wan_txrx_state = 0; ++ } ++ pWanTimer->expires = jiffies + FLICK_TIME; ++ add_timer(pWanTimer); ++ ++} ++ ++static int led_ioctl( struct inode * inode, struct file * file, ++ unsigned int cmd, unsigned long arg ) ++{ ++ ++ int ret = 0; ++// char name[80]; ++ ++ switch ( cmd ) ++ { ++ case LED_CONFIG: ++ { ++ LED_CONFIG_T led_cfg; ++ if (copy_from_user((char *)&led_cfg, (char *)arg, sizeof(led_cfg))) ++ { ++ printk("in led config error\n"); ++ ret = -EFAULT; ++ break; ++ } ++ printk("in led config\n"); ++ ret = avalanche_led_config_set(&led_cfg); ++ } ++ break; ++ ++ case LED_GET_HANDLE: ++ { ++ LED_MODULE_T led_mod; ++ int handle; ++ ++ if (copy_from_user((char *)&led_mod, (char *)arg, sizeof(led_mod))) ++ { ++ ret = -EFAULT; ++ break; ++ } ++ ++ handle = (int)avalanche_led_register(led_mod.name,led_mod.instance); ++ ++ if (copy_to_user((char *)(&(((LED_MODULE_T *)arg)->handle)), (char *)(&handle), sizeof(int))) ++ { ++ ret = -EFAULT; ++ break; ++ } ++ ++ if(handle) ++ ret = 0; ++ else ++ ret = -1; ++ } ++ break; ++ ++ case LED_ACTION: ++ { ++ LED_STATE_T led_state; ++ if (copy_from_user((char *)&led_state, (char *)arg, sizeof(led_state))) ++ { ++ ret = -EFAULT; ++ break; ++ } ++ else { ++ printk("led action : handle = %d, id = %d\n", led_state.handle, led_state.state_id); ++ //add by leijun ++ if (led_state.handle == 2) //system led ++ { ++ switch (led_state.state_id) ++ { ++ case 1: ++ break; ++ case 2: /*sys led flashing green */ ++ tnetd73xx_gpio_out(4, FALSE); ++ tnetd73xx_gpio_out(5, TRUE); ++ tnetd73xx_gpio_out(8, TRUE); ++ break; ++ case 3: /*sys led solid green */ ++ tnetd73xx_gpio_out(4, TRUE); ++ tnetd73xx_gpio_out(5, TRUE); ++ tnetd73xx_gpio_out(8, TRUE); ++ ++ break; ++ case 4: /*sys fail red */ ++ tnetd73xx_gpio_out(4, TRUE); ++ tnetd73xx_gpio_out(5, FALSE); ++ tnetd73xx_gpio_out(8, FALSE); ++ break; ++ default: ++ break; ++ ++ } ++ }else if (led_state.handle == 3) ++ { ++ printk("led action : handle = %d, id = %d\n", led_state.handle, led_state.state_id); ++ avalanche_gpio_ctrl(2, GPIO_PIN, GPIO_OUTPUT_PIN); ++ avalanche_gpio_ctrl(3, GPIO_PIN, GPIO_OUTPUT_PIN); ++ ++ switch (led_state.state_id) ++ { ++ case 1: /*no wan interface*/ ++ if (pWanTimer) ++ { ++ del_timer(pWanTimer); ++ kfree(pWanTimer); ++ pWanTimer = NULL; ++ } ++ tnetd73xx_gpio_out(2, FALSE); ++ tnetd73xx_gpio_out(3, FALSE); ++ break; ++ case 2: /*wan connected */ ++ if (pWanTimer) ++ { ++ del_timer(pWanTimer); ++ kfree(pWanTimer); ++ pWanTimer = NULL; ++ } ++ tnetd73xx_gpio_out(2, TRUE); ++ tnetd73xx_gpio_out(3, FALSE); ++ break; ++ case 3: /*rx/tx activity */ ++ if (pWanTimer != NULL) ++ break; ++ ++ pWanTimer = kmalloc(sizeof(struct timer_list), GFP_KERNEL); ++ init_timer(pWanTimer); ++ ++ pWanTimer->function = wan_led_func; ++ pWanTimer->data = 0; ++ pWanTimer->expires = jiffies + FLICK_TIME; ++ tnetd73xx_gpio_out(2, FALSE); ++ tnetd73xx_gpio_out(3, FALSE); ++ wan_txrx_state = 0; ++ add_timer(pWanTimer); ++ ++ break; ++ case 4: /*no ipaddress */ ++ if (pWanTimer) ++ { ++ del_timer(pWanTimer); ++ kfree(pWanTimer); ++ pWanTimer = NULL; ++ } ++ tnetd73xx_gpio_out(2, FALSE); ++ tnetd73xx_gpio_out(3, TRUE); ++ break; ++ default: ++ if (pWanTimer) ++ { ++ del_timer(pWanTimer); ++ kfree(pWanTimer); ++ pWanTimer = NULL; ++ } ++ break; ++ } ++ }else if (led_state.handle == 4) //test ++ { ++ int high, low; ++ high = (led_state.state_id & 0xf0) >> 4; ++ low = (led_state.state_id & 0x0f); ++ tnetd73xx_gpio_out(high, (low > 0)?1:0); ++ }else avalanche_led_action((void *)led_state.handle,led_state.state_id); ++ } ++ ++ } ++ break; ++ ++ case LED_RELEASE_HANDLE: ++ ret = avalanche_led_unregister((void *)arg); ++ break; ++ ++ default: ++ ret = -EINVAL; ++ } ++ return ret; ++ ++} ++ ++static int led_open( struct inode * inode, struct file * file ) ++{ ++ return 0; ++} ++ ++static int led_close( struct inode * inode, struct file * file ) ++{ ++ return 0; ++} ++ ++struct file_operations led_fops = { ++ ioctl: led_ioctl, ++ open: led_open, ++ release: led_close ++}; ++ ++ ++/* Proc function to display driver version */ ++static int ++led_ver_info(char *buf, char **start, off_t offset, int count, int *eof, void *data) ++{ ++// int instance; ++ int len=0; ++ ++ len += sprintf(buf +len,"\nTI Linux LED Driver Version %s\n",TI_LED_VERSION); ++ return len; ++} ++ ++ ++/* proc interface /proc/avalanche/led */ ++int led_cfg_info(char* buf, char **start, off_t offset, int count, ++ int *eof, void *data) ++{ ++ int mod_count = 0; ++ int len=0; ++ int limit = count - 80; ++ char *msg[5]={"LED OFF", "LED_ON", "LED_ONESHOT_OFF", "LED_ONESHOT_ON","LED_FLASH"}; ++ ++ for(mod_count = 0;mod_count<MAX_MODULE_ENTRIES;mod_count++) ++ { ++ int instance; ++ ++ for(instance = 0; instance < MAX_MODULE_INSTANCES; instance++) ++ { ++ int state_id; ++ int flag = 0; ++ ++ for(state_id =0 ;state_id < MAX_STATE_ENTRIES; state_id++) ++ { ++ LED_CONFIG_T led_cfg; ++ if(avalanche_led_config_get(&led_cfg,mod_count,instance,state_id) == 0) ++ { ++ if(flag == 0) ++ { ++ flag = 1; ++ if(len <= limit) ++ len+= sprintf(buf+len, "\nModule:%s\n",led_cfg.name); ++ ++ if(len <= limit) ++ len+= sprintf(buf+len, "\n Instance:%d\n",instance); ++ ++ } ++ ++ if(len <= limit) ++ len+= sprintf(buf+len, "\n State: %d\n",state_id); ++ ++ if(len <= limit) ++ len+= sprintf(buf+len, "\n mode: %s\n",msg[led_cfg.mode[0]% 5 ]); ++ ++ if(len <= limit) ++ len+= sprintf(buf+len, "\n gpio: %d\n",led_cfg.gpio[0]); ++ ++ if(len <= limit) ++ len+= sprintf(buf+len, "\n param1: %d\n",led_cfg.param1); ++ ++ if(len <= limit) ++ len+= sprintf(buf+len, "\n param2: %d\n",led_cfg.param2); ++ } ++ } ++ } ++ } ++ ++ ++ ++ return len; ++} ++ ++ ++ ++int __init led_init(void) ++{ ++ ++ /* register LED device */ ++ devfs_register(NULL, "led", DEVFS_FL_AUTO_DEVNUM, 0, 0, ++ S_IFCHR | S_IRUGO | S_IWUGO, &led_fops,NULL); ++ ++ ++ avalanche_led_hal_init(gpio_off_state,AVALANCHE_GPIO_PIN_COUNT); ++ ++ /* create proc entry */ ++ create_proc_read_entry("avalanche/led_cfg", 0, NULL, led_cfg_info, NULL); ++ create_proc_read_entry("avalanche/led_ver", 0, NULL, led_ver_info, NULL); ++ ++ return 0; ++} ++ ++void led_exit(void) ++{ ++ avalanche_led_hal_exit(); ++ return; ++} ++ ++module_init(led_init); ++module_exit(led_exit); ++ ++ ++EXPORT_SYMBOL_NOVERS(avalanche_led_register); ++EXPORT_SYMBOL_NOVERS(avalanche_led_action); ++EXPORT_SYMBOL_NOVERS(avalanche_led_unregister); ++EXPORT_SYMBOL_NOVERS(avalanche_led_config_set); ++EXPORT_SYMBOL_NOVERS(avalanche_led_config_get); +diff -urN kernel-old/drivers/char/avalanche_led/led_hal.c kernel-current/drivers/char/avalanche_led/led_hal.c +--- kernel-old/drivers/char/avalanche_led/led_hal.c 1970-01-01 01:00:00.000000000 +0100 ++++ kernel-current/drivers/char/avalanche_led/led_hal.c 2005-07-10 18:24:22.242038232 +0200 +@@ -0,0 +1,821 @@ ++/****************************************************************************** ++ * FILE PURPOSE: - LED HAL module source ++ ****************************************************************************** ++ * FILE NAME: led_hal.c ++ * ++ * DESCRIPTION: LED HAL API's source. ++ * ++ * REVISION HISTORY: ++ * 27 Aug 2003 Initial Creation Sharath Kumar<krs@ti.com> ++ * ++ * 16 Dec 2003 Updates for 5.7 Sharath Kumar<krs@ti.com> ++ * ++ * 07 Jan 2004 Wrapper for DSL Sharath Kumar<krs@ti.com> ++ * ++ * (C) Copyright 2002, Texas Instruments, Inc ++ *******************************************************************************/ ++ ++#include "led_platform.h" ++#include "led_config.h" ++#include "led_hal.h" ++ ++/* include for gpio APIs */ ++#include <asm/ar7/avalanche_misc.h> ++ ++ ++#define REQUIRES_TIMER(x) ( (x == LED_ONESHOT_ON) || (x == LED_ONESHOT_OFF) || (x == LED_FLASH) ) ++ ++/*******************TYPEDEFs**************************************************/ ++typedef struct ++{ ++ unsigned int state; ++ unsigned int module_map; ++ unsigned int pos_map[2]; ++} ++LED_OBJ_T; ++ ++typedef struct state_entry STATE_ENTRY_T; ++ ++struct state_entry ++{ ++ void (*handler) (STATE_ENTRY_T * state); ++ unsigned int timer_running; ++ LED_OBJ_T *led; ++ unsigned int map1[2]; ++ unsigned int map2[2]; ++ void *os_timer; ++ unsigned int param1; ++ unsigned int param2; ++ unsigned int module_id; ++ unsigned int mode; ++}; ++ ++typedef struct module_instance ++{ ++ int module_id; ++ int instance; ++ STATE_ENTRY_T *states[MAX_STATE_ENTRIES]; ++} ++MODULE_INSTANCE_T; ++ ++typedef struct module_entry ++{ ++ unsigned char *name; ++ MODULE_INSTANCE_T *module_instance[MAX_MODULE_INSTANCES]; ++} ++MODULE_ENTRY_T; ++ ++ ++ ++/******************variable defn/declns***************************************/ ++ ++static LED_OBJ_T *leds[MAX_LED_ENTRIES]; ++static MODULE_ENTRY_T *modules[MAX_MODULE_ENTRIES]; ++ ++/* Declare Mutex lock */ ++MUTEX_DECLARE (led_lock); ++ ++/* GPIO OFF STATE */ ++static unsigned int gpio_offstate_map[2]; ++ ++/* Number of GPIO pins in the system */ ++static unsigned int num_gpios; ++ ++/* LED handlers */ ++static void (*led_mode_handler[NUM_LED_MODES]) (STATE_ENTRY_T * state); ++ ++ ++ ++/******************static functions*****************************************/ ++ ++static void *led_malloc (int n) ++{ ++ void *p; ++ p = os_malloc (n); ++ ++ if (p) ++ os_memset (p, 0, n); ++ ++ return p; ++} ++ ++static void avalanche_gpio_set(int * set_map,int *pos_map) ++{ ++ int i; ++ ++ for(i = 0;i <num_gpios ;i+=32) ++ { ++ int index = i/32; ++ avalanche_gpio_out_value(set_map[index],pos_map[index],index); ++ ++ } ++ ++} ++ ++ ++static MODULE_INSTANCE_T *get_module (char *name, int instance) ++{ ++ int module_id; ++ MODULE_INSTANCE_T *mod_inst; ++ ++ ++ if (instance >= MAX_MODULE_INSTANCES) ++ return NULL; ++ ++ for (module_id = 0; module_id < MAX_MODULE_ENTRIES; module_id++) ++ { ++ if (modules[module_id] ++ && !os_strcmp (name, modules[module_id]->name)) ++ break; ++ } ++ ++ if (module_id == MAX_MODULE_ENTRIES) ++ { ++ for (module_id = 0; ++ (module_id < MAX_MODULE_ENTRIES) && modules[module_id]; ++ module_id++); ++ ++ if (module_id < MAX_MODULE_ENTRIES) ++ { ++ modules[module_id] = led_malloc (sizeof (MODULE_ENTRY_T)); ++ ++ if (!modules[module_id]) ++ return NULL; ++ ++ modules[module_id]->name = led_malloc (os_strlen (name) + 1); ++ ++ if (!modules[module_id]->name) ++ return NULL; ++ ++ os_strcpy (modules[module_id]->name, name); ++ } ++ else ++ { ++ log_msg ("ERROR:Module Count exceeded\n"); ++ return NULL; ++ } ++ } ++ ++ if (!modules[module_id]->module_instance[instance]) ++ modules[module_id]->module_instance[instance] = ++ led_malloc (sizeof (MODULE_INSTANCE_T)); ++ ++ if (!modules[module_id]->module_instance[instance]) ++ return NULL; ++ ++ mod_inst = modules[module_id]->module_instance[instance]; ++ mod_inst->module_id = module_id; ++ mod_inst->instance = instance; ++ ++ return mod_inst; ++} ++ ++ ++static void assign_map(int *to, int *from) ++{ ++ int i; ++ ++ for(i = 0;i <num_gpios ;i+=32) ++ { ++ int index = i/32; ++ to[index] = from[index]; ++ } ++} ++ ++ ++ ++ ++static LED_OBJ_T *get_led (int * pos_map) ++{ ++ int led_id; ++ ++ for (led_id = 0; led_id < MAX_LED_ENTRIES; led_id++) ++ { ++ if (leds[led_id]) ++ { ++ int i; ++ int flag=0; ++ ++ for(i = 0;i <num_gpios ;i+=32) ++ { ++ int index = i/32; ++ if(leds[led_id]->pos_map[index] != pos_map[index]) ++ flag =1; ++ } ++ if(flag == 0) ++ break; ++ } ++ } ++ ++ if (led_id == MAX_LED_ENTRIES) ++ { ++ for (led_id = 0; (led_id < MAX_LED_ENTRIES) && leds[led_id]; ++ led_id++); ++ ++ if (led_id < MAX_LED_ENTRIES) ++ { ++ leds[led_id] = led_malloc (sizeof (LED_OBJ_T)); ++ ++ if (!leds[led_id]) ++ return NULL; ++ ++ assign_map(leds[led_id]->pos_map,pos_map); ++ } ++ else ++ { ++ log_msg ("ERROR:Module Count exceeded\n"); ++ return NULL; ++ } ++ } ++ ++ return leds[led_id]; ++} ++ ++static void led_oneshot_on_timer_func (int arg) ++{ ++ STATE_ENTRY_T *state = (STATE_ENTRY_T *) arg; ++ LED_OBJ_T *led = state->led; ++ ++ state->timer_running = 0; ++ MUTEX_GET (led_lock); ++ if (led->state == LED_ONESHOT_ON) ++ { ++ led->state = LED_OFF; ++ avalanche_gpio_set (state->map2,led->pos_map); ++ } ++ MUTEX_RELEASE (led_lock); ++ ++} ++ ++static void led_oneshot_off_timer_func (int arg) ++{ ++ STATE_ENTRY_T *state = (STATE_ENTRY_T *) arg; ++ LED_OBJ_T *led = state->led; ++ ++ state->timer_running = 0; ++ ++ MUTEX_GET (led_lock); ++ if (led->state == LED_ONESHOT_OFF) ++ { ++ led->state = LED_ON; ++ avalanche_gpio_set(state->map2,led->pos_map); ++ } ++ MUTEX_RELEASE (led_lock); ++ ++} ++ ++static void led_flash_timer_func (int arg) ++{ ++ STATE_ENTRY_T *state = (STATE_ENTRY_T *) arg; ++ LED_OBJ_T *led = state->led; ++ ++ ++ if (led->state != LED_FLASH) ++ return; ++ ++ MUTEX_GET (led_lock); ++ ++ if (state->timer_running == 1) ++ { ++ state->timer_running = 2; ++ avalanche_gpio_set(state->map2,led->pos_map); ++ os_timer_add (state->os_timer, state->param2, (int)state); ++ } ++ else ++ { ++ state->timer_running = 1; ++ avalanche_gpio_set(state->map1,led->pos_map); ++ os_timer_add (state->os_timer, state->param1, (int)state); ++ } ++ ++ MUTEX_RELEASE (led_lock); ++} ++ ++static void led_on(STATE_ENTRY_T * state) ++{ ++ LED_OBJ_T *led = state->led; ++ ++ led->state = LED_ON; ++ avalanche_gpio_set(state->map1,led->pos_map); ++ led->module_map |= (1 << (state->module_id)); ++ ++} ++ ++static void led_off (STATE_ENTRY_T * state) ++{ ++ LED_OBJ_T *led = state->led; ++ ++ led->module_map &= ~(1 << (state->module_id)); ++ if (!led->module_map) ++ { ++ led->state = LED_OFF; ++ avalanche_gpio_set(state->map1,led->pos_map); ++ } ++ ++} ++ ++static void led_oneshot_on (STATE_ENTRY_T * state) ++{ ++ LED_OBJ_T *led = state->led; ++ ++ if (state->timer_running) ++ return; ++ ++ state->timer_running = 1; ++ led->state = LED_ONESHOT_ON; ++ avalanche_gpio_set(state->map1,led->pos_map); ++ os_timer_add (state->os_timer, state->param1,(int) state); ++} ++ ++static void led_oneshot_off (STATE_ENTRY_T * state) ++{ ++ ++ LED_OBJ_T *led = state->led; ++ ++ if (state->timer_running) ++ return; ++ ++ state->timer_running = 1; ++ led->state = LED_ONESHOT_OFF; ++ avalanche_gpio_set(state->map1,led->pos_map); ++ os_timer_add (state->os_timer, state->param1,(int) state); ++} ++ ++static void led_flash (STATE_ENTRY_T * state) ++{ ++ LED_OBJ_T *led = state->led; ++ ++ if (state->timer_running) ++ return; ++ ++ state->timer_running = 1; ++ led->state = LED_FLASH; ++ avalanche_gpio_set(state->map1,led->pos_map); ++ os_timer_add (state->os_timer, state->param1,(int) state); ++} ++ ++ ++ ++static int led_get_mode(LED_CONFIG_T *led_cfg) ++{ ++ int num_gpio = led_cfg->gpio_num; ++ int i; ++ int *led_mode = led_cfg->mode; ++ int max = -1; ++ ++ /* Return Max of available modes */ ++ for(i = 0; i<num_gpio; i++) ++ { ++ max = (max > led_mode[i]) ? max : led_mode[i]; ++ } ++ ++ return max; ++} ++ ++static void led_assign_timer(STATE_ENTRY_T *state_entry) ++{ ++ ++ if (state_entry->os_timer) ++ { ++ os_timer_delete(state_entry->os_timer); ++ } ++ ++ switch(state_entry->mode) ++ { ++ case LED_ONESHOT_ON: ++ state_entry->os_timer = os_timer_init(led_oneshot_on_timer_func); ++ break; ++ ++ case LED_ONESHOT_OFF: ++ state_entry->os_timer = os_timer_init(led_oneshot_off_timer_func); ++ break; ++ ++ case LED_FLASH: ++ state_entry->os_timer = os_timer_init(led_flash_timer_func); ++ break; ++ ++ default: ++ log_msg("invalid mode in function led_assign timer\n"); ++ } ++ ++} ++ ++static int led_get_map(LED_CONFIG_T *led_cfg,int *p_pos_map,int *p_map1,int *p_map2) ++{ ++ int i; ++ int map1[2] = {0,0}; ++ int pos_map[2] = {0,0}; ++ int map2[2] = {0,0}; ++ int requires_timer = REQUIRES_TIMER(led_get_mode(led_cfg)); ++ ++ for (i = 0; i < led_cfg->gpio_num; i++) ++ { ++ int gpio_map; ++ int index = led_cfg->gpio[i]/32; ++ int pos = led_cfg->gpio[i] % 32; ++ ++ if (led_cfg->gpio[i] >= num_gpios) ++ { ++ log_msg ("Error: gpio number out of range\n"); ++ return -1; ++ } ++ ++ gpio_map = 1 << pos; ++ ++ pos_map[index] |= gpio_map; ++ ++ ++ switch (led_cfg->mode[i]) ++ { ++ case LED_OFF: ++ if(gpio_offstate_map[index] & gpio_map) ++ map1[index] |= gpio_map; ++ ++ if (requires_timer && (gpio_offstate_map[index] & gpio_map)) ++ map2[index] |= gpio_map; ++ break; ++ ++ case LED_ON: ++ ++ if(!(gpio_offstate_map[index] & gpio_map)) ++ map1[index] |= gpio_map; ++ ++ if (requires_timer && !(gpio_offstate_map[index] & gpio_map)) ++ map2[index] |= gpio_map; ++ break; ++ ++ case LED_ONESHOT_OFF: ++ ++ if ((gpio_offstate_map[index] & gpio_map)) ++ map1[index] |= gpio_map; ++ else ++ map2[index] |= gpio_map; ++ break; ++ ++ case LED_ONESHOT_ON: ++ case LED_FLASH: ++ ++ if (!(gpio_offstate_map[index] & gpio_map)) ++ map1[index] |= gpio_map; ++ else ++ map2[index] |= gpio_map; ++ break; ++ ++ default: ++ log_msg ("Error: Invalid mode\n"); ++ return -1; ++ } ++ } ++ ++ assign_map(p_pos_map,pos_map); ++ assign_map(p_map1,map1); ++ assign_map(p_map2,map2); ++ ++ return 0; ++} ++ ++ ++ ++ ++static int configure_state(STATE_ENTRY_T *state_entry,LED_CONFIG_T *led_cfg) ++{ ++// int state = led_cfg->state; ++ int i; ++ int map1[2] ; ++ int pos_map[2]; ++ int map2[2]; ++ ++ if((state_entry->mode = led_get_mode(led_cfg)) >= NUM_LED_MODES) ++ { ++ log_msg ("Error: Invalid mode in func configure_state\n"); ++ return -1; ++ } ++ ++ state_entry->handler = led_mode_handler[state_entry->mode]; ++ ++ ++ if(led_get_map(led_cfg,pos_map,map1,map2)) ++ { ++ log_msg ("Error: gpio number out of range\n"); ++ return -1; ++ } ++ ++ assign_map(state_entry->map1,map1); ++ assign_map(state_entry->map2,map2); ++ state_entry->led = get_led(pos_map); ++ ++ /* Check if the state requires timer */ ++ if(REQUIRES_TIMER(state_entry->mode)) ++ { ++ state_entry->timer_running = 0; ++ state_entry->param1 = led_cfg->param1; ++ state_entry->param2 = led_cfg->param2; ++ led_assign_timer(state_entry); ++ } ++ ++ /* enable gpio pins */ ++ for(i = 0;i<led_cfg->gpio_num;i++) ++ { ++ int value; ++ int index; ++ int pos; ++ avalanche_gpio_ctrl (led_cfg->gpio[i],GPIO_PIN,GPIO_OUTPUT_PIN); ++ ++ /* Turn off the led */ ++ index = led_cfg->gpio[i]/32; ++ pos = led_cfg->gpio[i] % 32; ++ value = (gpio_offstate_map[index] & (1 << pos))?1:0; ++ avalanche_gpio_out_bit(led_cfg->gpio[i],value); ++ } ++ ++ return 0; ++} ++ ++ ++static void free_all_states(void) ++{ ++ int module_id; ++ ++ for(module_id = 0; module_id < MAX_MODULE_ENTRIES; module_id++) ++ { ++ if(modules[module_id]) ++ { ++ int i; ++ for(i = 0; i< MAX_MODULE_INSTANCES; i++) ++ { ++ MODULE_INSTANCE_T *module_instance = modules[module_id]->module_instance[i]; ++ ++ if(module_instance) ++ { ++ int state_id; ++ ++ for(state_id =0; state_id < MAX_STATE_ENTRIES; state_id++) ++ { ++ STATE_ENTRY_T *state= module_instance->states[state_id]; ++ ++ if(state) ++ { ++ if(state->os_timer) ++ os_timer_delete(state->os_timer); ++ ++ os_free(state); ++ module_instance->states[state_id] = NULL; ++ } ++ ++ } ++ } ++ ++ } ++ os_free(modules[module_id]->name); ++ os_free(modules[module_id]); ++ modules[module_id] = NULL; ++ } ++ } ++} ++ ++/***********************************HAL APIS************************************/ ++ ++/************************************************************************** ++ * FUNCTION NAME : avalanche_led_hal_init ++ ************************************************************************** ++ * DESCRIPTION : ++ * The function initializes led hal module ++ * ++ * RETURNS : ++ * 0 on Success ++ * Negative value on Error ++ ***************************************************************************/ ++ ++ ++int avalanche_led_hal_init (int *gpio_off_value, int num_gpio_pins) ++{ ++ //int i; ++ ++ num_gpios = num_gpio_pins + 4; ++ assign_map(gpio_offstate_map, gpio_off_value); ++ ++ MUTEX_INIT (led_lock); ++ ++ /* initialize led state function handlers */ ++ led_mode_handler[LED_ON] = led_on; ++ led_mode_handler[LED_OFF] = led_off; ++ led_mode_handler[LED_ONESHOT_ON] = led_oneshot_on; ++ led_mode_handler[LED_ONESHOT_OFF] = led_oneshot_off; ++ led_mode_handler[LED_FLASH] = led_flash; ++ ++ return 0; ++} ++ ++ ++/************************************************************************** ++ * FUNCTION NAME : avalanche_led_config_set ++ ************************************************************************** ++ * DESCRIPTION : ++ * The function configures LED state object ++ * ++ * RETURNS : ++ * 0 on Success ++ * Negative value on Error ++ ***************************************************************************/ ++ ++int avalanche_led_config_set(LED_CONFIG_T * led_cfg) ++{ ++ MODULE_INSTANCE_T *module; ++ MUTEX_GET (led_lock); ++ module = get_module (led_cfg->name, led_cfg->instance); ++ ++ if (!module) ++ goto config_failed; ++ ++ if (led_cfg->state < MAX_STATE_ENTRIES) ++ { ++ int state = led_cfg->state; ++ ++ if (!(module->states[state])) ++ { ++ module->states[state] = led_malloc (sizeof (STATE_ENTRY_T)); ++ } ++ ++ if (!(module->states[state])) ++ goto config_failed; ++ ++ module->states[state]->module_id = module->module_id; ++ ++ if(configure_state(module->states[state],led_cfg)) ++ { ++ os_free(module->states[state]); ++ module->states[state] = NULL; ++ goto config_failed; ++ } ++ ++ } ++ else ++ { ++ log_msg ("ERROR:State Count exceeded\n"); ++ goto config_failed; ++ } ++ ++ MUTEX_RELEASE (led_lock); ++ return 0; ++ ++ config_failed: ++ ++ MUTEX_RELEASE (led_lock); ++ return -1; ++ ++} ++ ++/************************************************************************** ++ * FUNCTION NAME : avalanche_led_register ++ ************************************************************************** ++ * DESCRIPTION : ++ * The function creates handle to the given module and returns it. ++ * ++ * RETURNS : ++ * Handle to the module instance on success. ++ * NULL on failure. ++ ***************************************************************************/ ++ ++void *avalanche_led_register (const char *mod_name, int instance) ++{ ++ void *p; ++ MUTEX_GET (led_lock); ++ p = (void *)get_module ((char *)mod_name, instance); ++ MUTEX_RELEASE (led_lock); ++ return p; ++} ++ ++ ++/************************************************************************** ++ * FUNCTION NAME : avalanche_led_action ++ ************************************************************************** ++ * DESCRIPTION : ++ * The function triggers action on LED ++ * ++ ***************************************************************************/ ++ ++void avalanche_led_action (void *module, int state_id) ++{ ++ ++ MUTEX_GET (led_lock); ++ if (module && (state_id < MAX_STATE_ENTRIES)) ++ { ++ ++ STATE_ENTRY_T *state = ++ ((MODULE_INSTANCE_T *) (module))->states[state_id]; ++ if (state) ++ { ++ state->handler (state); ++ } ++ } ++ MUTEX_RELEASE (led_lock); ++ return; ++} ++ ++ ++/************************************************************************** ++ * FUNCTION NAME : avalanche_led_unregister ++ ************************************************************************** ++ * DESCRIPTION : ++ * The function unregisters the module ++ * ++ * RETURNS : ++ * 0 on Success ++ * Negative value on Error ++ ***************************************************************************/ ++ ++int avalanche_led_unregister (void *mod_inst) ++{ ++ ++ return 0; ++} ++ ++ ++/************************************************************************** ++ * FUNCTION NAME : led_free_all ++ ************************************************************************** ++ * DESCRIPTION : ++ * The function frees the memory allocated for holding state ++ * configuration data ++ * ++ ***************************************************************************/ ++ ++void avalanche_led_free_all() ++{ ++ free_all_states(); ++} ++ ++/************************************************************************** ++ * FUNCTION NAME : avalanche_led_hal_exit ++ ************************************************************************** ++ * DESCRIPTION : ++ * The function releases all the allocated memory ++ * ++ ***************************************************************************/ ++ ++void avalanche_led_hal_exit () ++{ ++ free_all_states(); ++} ++ ++/***************************************************************************** ++ * FUNCTION NAME : avalanche_led_config_get ++ ***************************************************************************** ++ * DESCRIPTION : ++ * The function returns configuration information corresponding to module ++ * state. ++ * ++ * RETURNS : ++ * 0 on Success ++ * Negative value on Error ++ ***************************************************************************/ ++int avalanche_led_config_get(LED_CONFIG_T *led_cfg,int module_id,int instance, int state_id) ++{ ++ if(module_id == -1) ++ { ++ /* The module info is passed through field of led_cfg */ ++ MODULE_INSTANCE_T *mod = get_module (led_cfg->name, instance); ++ if(mod) ++ module_id = mod->module_id; ++ ++ } ++ if(module_id >= MAX_MODULE_ENTRIES || module_id < 0) ++ return -1; ++ ++ if(state_id >= MAX_STATE_ENTRIES || module_id < 0) ++ return -1; ++ ++ if(instance >= MAX_MODULE_INSTANCES || module_id < 0) ++ return -1; ++ ++ if(modules[module_id]) ++ { ++ MODULE_INSTANCE_T *module = modules[module_id]->module_instance[instance]; ++ if(module) ++ { ++ STATE_ENTRY_T *state = module->states[state_id]; ++ if(state) ++ { ++ int i; ++ LED_OBJ_T *led; ++ strcpy(led_cfg->name, modules[module_id]->name); ++ led_cfg->state = state_id; ++ led_cfg->instance = instance; ++ led_cfg->param1 = state->param1; ++ led_cfg->param2 = state->param2; ++ led_cfg->mode[0] = state->mode; ++ led = state->led; ++ ++ /* needs to be modified for multi-pin leds */ ++ for(i = 0;i < num_gpios && !(led->pos_map[i/32] & (1 << i)); i++); ++ ++ led_cfg->gpio[0] = i; ++ led_cfg->gpio_num = 1; ++ ++ return 0; ++ } ++ } ++ } ++ ++ return -1; ++} +diff -urN kernel-old/drivers/char/avalanche_led/led_hal.h kernel-current/drivers/char/avalanche_led/led_hal.h +--- kernel-old/drivers/char/avalanche_led/led_hal.h 1970-01-01 01:00:00.000000000 +0100 ++++ kernel-current/drivers/char/avalanche_led/led_hal.h 2005-07-10 18:03:46.120957200 +0200 +@@ -0,0 +1,28 @@ ++/****************************************************************************** ++ * FILE PURPOSE: - LED HAL module Header ++ ****************************************************************************** ++ * FILE NAME: led_hal.h ++ * ++ * DESCRIPTION: LED HAL API's. ++ * ++ * REVISION HISTORY: ++ * 11 Oct 03 - PSP TII ++ * ++ * (C) Copyright 2002, Texas Instruments, Inc ++ *******************************************************************************/ ++ ++#ifndef __LED_HAL__ ++#define __LED_HAL__ ++ ++/* Interface prototypes */ ++ ++int avalanche_led_hal_init (int *gpio_off_value, int num_gpio_pins); ++int avalanche_led_config_set (LED_CONFIG_T * led_cfg); ++int avalanche_led_config_get (LED_CONFIG_T *led_cfg,int module_id,int instance, int state); ++void *avalanche_led_register (const char *module_name, int instance_num); ++void avalanche_led_action (void *handle, int state_id); ++int avalanche_led_unregister (void *handle); ++void avalanche_led_free_all(void); ++void avalanche_led_hal_exit (void); ++ ++#endif /*__LED_HAL__ */ +diff -urN kernel-old/drivers/char/avalanche_led/led_platform.h kernel-current/drivers/char/avalanche_led/led_platform.h +--- kernel-old/drivers/char/avalanche_led/led_platform.h 1970-01-01 01:00:00.000000000 +0100 ++++ kernel-current/drivers/char/avalanche_led/led_platform.h 2005-07-10 18:03:46.120957200 +0200 +@@ -0,0 +1,117 @@ ++/****************************************************************************** ++ * FILE PURPOSE: - LED Platform specific Header file ++ ****************************************************************************** ++ * FILE NAME: led_platform.h ++ * ++ * DESCRIPTION: Linux specific implementation for OS abstracted function calls ++ * made by LED HAL module. This file has functions defined for ++ * Memory allocation calls, Mutex calls, String and Timer ++ * operations. ++ * ++ * REVISION HISTORY: ++ * 11 Oct 03 - PSP TII ++ * ++ * (C) Copyright 2002, Texas Instruments, Inc ++ *******************************************************************************/ ++ ++#ifndef __LED_PLATFORM__ ++#define __LED_PLATFORM__ ++ ++#include <linux/mm.h> ++#include <linux/slab.h> ++#include <asm/string.h> ++#include <linux/param.h> ++#include <linux/sched.h> ++#include <linux/timer.h> ++#include <linux/spinlock.h> ++ ++ ++#define os_malloc(x) kmalloc(x,GFP_KERNEL) ++#define os_memset memset ++#define os_free(x) kfree(x) ++#define os_strcmp os_strcasecmp ++#define os_strcpy strcpy ++ ++#if defined(DEBUG) ++#define log_msg printk ++#else ++#define log_msg(x) ++#endif ++ ++/* defines for Mutex */ ++typedef struct { ++ spinlock_t lock; ++ int flags; ++}OS_SPINLOCK_T; ++ ++#define MUTEX_DECLARE(x) static OS_SPINLOCK_T x ++#define MUTEX_INIT(x) x.lock = SPIN_LOCK_UNLOCKED ++#define MUTEX_GET(x) spin_lock_irqsave(&x.lock, x.flags) ++#define MUTEX_RELEASE(x) spin_unlock_irqrestore(&x.lock, x.flags) ++ ++ ++ ++/* String handling functions not defined in asm/string.h */ ++static __inline__ int os_strlen(char *str) ++{ ++ int i; ++ for(i=0;str[i];i++); ++ return i; ++} ++ ++ ++#define LOWER(x) ((x < 'a') ? (x - 'A' + 'a'):(x)) ++#define ISALPHA(x) ((( x >= 'a') && (x <= 'z')) || (( x >= 'A') && (x <= 'Z'))) ++#define COMP(x,y) ((x == y) || ((ISALPHA(x) && ISALPHA(y)) && (LOWER(x) == LOWER(y)))) ++ ++ ++static __inline__ int os_strcasecmp(char *str1, char *str2) ++{ ++ int i; ++ ++ for(i=0;str1[i] && str2[i];i++) ++ { ++ char x,y; ++ ++ x = str1[i]; ++ y = str2[i]; ++ ++ if(!COMP(x,y)) ++ break; ++ } ++ ++ return(str1[i] || str2[i]); ++} ++ ++ ++ ++/* Functions for timer related operations */ ++static __inline__ void * os_timer_init(void (*func)(int)) ++{ ++ struct timer_list *ptimer; ++ ptimer = (struct timer_list *) kmalloc(sizeof(struct timer_list),GFP_KERNEL); ++ init_timer( ptimer ); ++ (void *)ptimer->function = (void *)func; ++ return (void *)ptimer; ++} ++ ++static __inline__ int os_timer_add(void *timer_handle,int milisec,int arg) ++{ ++ struct timer_list *ptimer=timer_handle; ++ ptimer->expires = ((HZ * milisec)/1000) + jiffies; ++ ptimer->data = arg; ++ add_timer(ptimer); ++ return 0; ++ ++} ++ ++static __inline__ int os_timer_delete(void *timer_handle) ++{ ++ struct timer_list *ptimer=timer_handle; ++ del_timer(ptimer); ++ kfree(ptimer); ++ return 0; ++} ++ ++ ++#endif /* __LED_PLATFORM__ */ +diff -urN kernel-old/drivers/char/avalanche_led/led_wrapper.c kernel-current/drivers/char/avalanche_led/led_wrapper.c +--- kernel-old/drivers/char/avalanche_led/led_wrapper.c 1970-01-01 01:00:00.000000000 +0100 ++++ kernel-current/drivers/char/avalanche_led/led_wrapper.c 2005-07-10 18:25:14.657069936 +0200 +@@ -0,0 +1,561 @@ ++/****************************************************************************** ++ * FILE PURPOSE: - LED Wrapper file for DSL module support ++ ****************************************************************************** ++ * FILE NAME: led_wrapper.c ++ * ++ * DESCRIPTION: LED Wrapper file for DSL module support ++ * This is to provide backward compatibility to the ADSL module ++ * using OLD LED driver. The numbers mapped for DSL LEDs in the ++ * previous implementation is 3,4,5,6. Since these numbers overlap ++ * with the existing numbering scheme, the following numbers need to ++ * be used in the led configuration file - 32,33,34,35. ++ * ++ * (C) Copyright 2002, Texas Instruments, Inc ++ *******************************************************************************/ ++#include <linux/config.h> ++#include <linux/init.h> ++#include <linux/module.h> ++#include <asm/ar7/sangam.h> ++#include "led_platform.h" ++#include "led_config.h" ++ ++#define BITS_PER_INT (8 * sizeof(int)) ++#define GPIOS_PER_INT BITS_PER_INT ++#define GPIO_MAP_LEN ((MAX_GPIO_PIN_NUM + GPIOS_PER_INT -1)/GPIOS_PER_INT) ++#define MODULE_MAP_LEN ((MAX_MODULE_ENTRIES + BITS_PER_INT -1)/BITS_PER_INT) ++ ++ ++#define REQUIRES_TIMER(x) (x > 1) ++ ++#define gpio_on(gpio) do \ ++ { \ ++ if(gpio >= 32 && adsl_led_objs[gpio - 32].onfunc) \ ++ adsl_led_objs[gpio - 32].onfunc(adsl_led_objs[gpio - 32].param);\ ++ } while(0) ++ ++ ++ ++#define gpio_off(gpio) \ ++ do \ ++ { \ ++ if(gpio >= 32 && adsl_led_objs[gpio - 32].offfunc) \ ++ adsl_led_objs[gpio - 32].offfunc(adsl_led_objs[gpio - 32].param);\ ++ } while(0) ++ ++ ++ ++ ++ ++ ++/********************TYPEDEFS***********************************************/ ++ ++typedef struct gpio_module ++{ ++ volatile unsigned int *gpio_write_reg; ++ volatile unsigned int *gpio_dir_reg; ++ volatile unsigned int *gpio_mode_reg; ++}GPIO_REGS_T; ++ ++typedef struct { ++ unsigned int gpio_id; ++ unsigned int gpio_state; ++ int module_map[MODULE_MAP_LEN]; ++}GPIO_OBJ_T; ++ ++ ++typedef struct state_entry STATE_ENTRY_T; ++ ++struct state_entry{ ++ unsigned int timer_running; ++ STATE_ENTRY_T *next; ++ void (*handler)(STATE_ENTRY_T *state); ++ GPIO_OBJ_T *gpio; ++ void *os_timer; ++ unsigned int param; ++ unsigned int module_id; ++ unsigned int mode; ++}; ++ ++ ++typedef struct module_instance{ ++ int module_id; ++ int instance; ++ STATE_ENTRY_T *states[MAX_STATE_ENTRIES]; ++}MODULE_INSTANCE_T; ++ ++typedef struct module_entry{ ++ unsigned char *name; ++ MODULE_INSTANCE_T *module_instance[MAX_MODULE_INSTANCES]; ++}MODULE_ENTRY_T; ++ ++ ++ ++typedef struct led_reg{ ++ unsigned int param; ++ void (*init)(unsigned long param); ++ void (*onfunc)(unsigned long param); ++ void (*offfunc)(unsigned long param); ++}led_reg_t; ++ ++ ++ ++/* Interface prototypes */ ++static int led_hal_init(GPIO_REGS_T gpio_mod, unsigned int *gpio_off_value,int num_gpio_pins); ++static int avalanche_led_set_config(LED_CONFIG_T *led_cfg); ++static void *avalanche_led_register(const char *module_name, int instance_num); ++static int avalanche_led_action(void *handle,int state_id); ++int avalanche_led_config_get (LED_CONFIG_T *led_cfg,int module_id,int instance, int state); ++ ++led_reg_t adsl_led_objs[4]; ++MODULE_INSTANCE_T *dsl_mod = NULL; ++static int gpio_off_state[GPIO_MAP_LEN] = AVALANCHE_GPIO_OFF_MAP; ++ ++ ++ ++static unsigned int num_gpios; ++static GPIO_OBJ_T *gpio_arr; ++GPIO_REGS_T gpio_regs; ++ ++/* GPIO OFF STATE */ ++static unsigned int gpio_off_val[GPIO_MAP_LEN]; ++ ++ ++MODULE_ENTRY_T *modules[MAX_MODULE_ENTRIES]; ++ ++/* LED handlers */ ++void (*led_mode_handler[NUM_LED_MODES])(STATE_ENTRY_T *state); ++ ++ ++/******************static functions*****************************************/ ++static void *led_malloc(int n) ++{ ++ void *p; ++ p=kmalloc(n,GFP_ATOMIC); ++ ++ if(p) ++ os_memset(p,0,n); ++ return p; ++} ++ ++static void free_state(STATE_ENTRY_T *state) ++{ ++ ++ STATE_ENTRY_T *prev = NULL; ++ STATE_ENTRY_T *curr = NULL ; ++ while(curr != state) ++ { ++ curr = state; ++ prev = NULL; ++ ++ while(curr->next != NULL) ++ { ++ prev = curr; ++ curr = curr->next; ++ } ++ ++ os_free(curr); ++ if(prev) ++ { ++ prev->next = NULL; ++ } ++ ++ } ++ ++} ++ ++static MODULE_INSTANCE_T* get_module(char * name,int instance) ++{ ++ int module_id; ++ MODULE_INSTANCE_T *mod_inst; ++ ++ if(instance >= MAX_MODULE_INSTANCES) ++ return NULL; ++ ++ for(module_id=0;module_id <MAX_MODULE_ENTRIES;module_id++) ++ { ++ if(modules[module_id] && !os_strcmp(name,modules[module_id]->name)) ++ break; ++ } ++ ++ if(module_id == MAX_MODULE_ENTRIES) ++ { ++ for(module_id = 0; (module_id < MAX_MODULE_ENTRIES) && modules[module_id] ; module_id++); ++ ++ if(module_id < MAX_MODULE_ENTRIES) ++ { ++ modules[module_id]=led_malloc(sizeof(MODULE_ENTRY_T)); ++ modules[module_id]->name = led_malloc(os_strlen(name)); ++ os_strcpy(modules[module_id]->name,name); ++ } ++ else ++ { ++ log_msg("ERROR:Module Count exceeded\n"); ++ return NULL; ++ } ++ } ++ ++ if(!modules[module_id]->module_instance[instance]) ++ modules[module_id]->module_instance[instance] = led_malloc(sizeof(MODULE_INSTANCE_T)); ++ ++ mod_inst = modules[module_id]->module_instance[instance]; ++ mod_inst->module_id = module_id; ++ mod_inst->instance = instance; ++ ++ return mod_inst; ++} ++ ++ ++static void led_timer_func(int arg) ++{ ++ STATE_ENTRY_T *state = (STATE_ENTRY_T *) arg; ++ GPIO_OBJ_T *gpio; ++ ++ ++ gpio = state->gpio; ++ ++ switch(gpio->gpio_state) ++ { ++ case LED_ONESHOT_ON: ++ gpio->gpio_state = LED_OFF; ++ gpio_off(gpio->gpio_id); ++ break; ++ ++ case LED_ONESHOT_OFF: ++ gpio->gpio_state = LED_ON; ++ gpio_on(gpio->gpio_id); ++ break; ++ ++ case LED_FLASH: ++ { ++ ++ if(state->timer_running == 1) ++ { ++ state->timer_running = 2; ++ gpio_off(gpio->gpio_id); ++ os_timer_add(state->os_timer,(state->param >> 16),(int)state); ++ } ++ else ++ { ++ state->timer_running = 1; ++ gpio_on(gpio->gpio_id); ++ os_timer_add(state->os_timer, (state->param & 0xffff),(int)state); ++ } ++ return; ++ } ++ default: ++ break; ++ ++ } ++ ++ state->timer_running = 0; ++ ++ ++} ++ ++ ++static void led_on(STATE_ENTRY_T *state) ++{ ++ int mod_index = state->module_id >> 5; ++ GPIO_OBJ_T *gpio = state->gpio; ++ ++ gpio->gpio_state = LED_ON; ++ gpio_on(gpio->gpio_id); ++ gpio->module_map[mod_index] |= (1 << (state->module_id % BITS_PER_INT)); ++ ++} ++ ++static void led_off(STATE_ENTRY_T *state) ++{ ++ ++ int mod_index = state->module_id >> 5; ++ GPIO_OBJ_T *gpio = state->gpio; ++ ++ gpio->module_map[mod_index] &= ~(1 << (state->module_id % BITS_PER_INT) ); ++ if(!gpio->module_map[mod_index]) ++ { ++ gpio->gpio_state = LED_OFF; ++ gpio_off(gpio->gpio_id); ++ } ++ ++} ++ ++static void led_oneshot_on(STATE_ENTRY_T *state) ++{ ++ GPIO_OBJ_T *gpio = state->gpio; ++ ++ state->timer_running = 1; ++ gpio->gpio_state = LED_ONESHOT_ON; ++ gpio_on(gpio->gpio_id); ++ os_timer_add(state->os_timer,state->param,(int)state); ++} ++ ++static void led_oneshot_off(STATE_ENTRY_T *state) ++{ ++ ++ GPIO_OBJ_T *gpio = state->gpio; ++ ++ state->timer_running = 1; ++ gpio->gpio_state = LED_ONESHOT_OFF; ++ gpio_off(gpio->gpio_id); ++ os_timer_add(state->os_timer,state->param,(int)state); ++} ++ ++static void led_flash(STATE_ENTRY_T *state) ++{ ++ ++ GPIO_OBJ_T *gpio = state->gpio; ++ ++ state->timer_running = 1; ++ gpio->gpio_state = LED_FLASH; ++ gpio_on(gpio->gpio_id); ++ os_timer_add(state->os_timer,(state->param & 0xffff),(int)state); ++} ++ ++ ++/****************HAL APIS***********************************************/ ++int led_hal_init(GPIO_REGS_T gpio_reg,unsigned int *gpio_off_value,int num_gpio_pins) ++{ ++ int i; ++ unsigned int *p_gpio=gpio_off_val; ++ ++ gpio_regs = gpio_reg; ++ num_gpios = num_gpio_pins; ++ ++ gpio_arr = led_malloc((num_gpio_pins + 4) * sizeof(GPIO_OBJ_T)); /* 4 added for ADSL gpio pins */ ++ ++ /* get gpios off state */ ++ for(i=0; i < num_gpio_pins; i+=GPIOS_PER_INT) ++ { ++ *p_gpio = *gpio_off_value; ++ gpio_off_value++; ++ p_gpio++; ++ } ++ ++ /* initialize gpio objects */ ++ for(i=0; i<num_gpio_pins + 4;i++) /* 4 added for ADSL gpio pins */ ++ { ++ gpio_arr[i].gpio_id = i; ++ } ++ ++ ++ ++ /* initialize led state function handlers */ ++ led_mode_handler[LED_ON] = led_on; ++ led_mode_handler[LED_OFF] = led_off; ++ led_mode_handler[LED_ONESHOT_ON] = led_oneshot_on; ++ led_mode_handler[LED_ONESHOT_OFF] = led_oneshot_off; ++ led_mode_handler[LED_FLASH] = led_flash; ++ ++ ++ return 0; ++} ++ ++ ++ /*********************************************************/ ++ ++int avalanche_led_set_config(LED_CONFIG_T *led_cfg) ++{ ++ MODULE_INSTANCE_T *module; ++ module = get_module(led_cfg->name,led_cfg->instance); ++ ++ if(!module ) ++ goto config_failed; ++ ++ if(led_cfg->state < MAX_STATE_ENTRIES) ++ { ++ STATE_ENTRY_T *state_entry; ++ int state=led_cfg->state; ++ int i; ++ ++ if(!(module->states[state])) ++ { ++ module->states[state] = led_malloc(sizeof(STATE_ENTRY_T)); ++ } ++ ++ state_entry = module->states[state]; ++ ++ for(i=0;i<led_cfg->gpio_num;i++) ++ { ++ if(led_cfg->gpio[i] >= (num_gpios + 4) ) /* 4 added for ADSL */ ++ { ++ log_msg("Error: gpio number out of range\n"); ++ goto config_failed; ++ } ++ ++ state_entry->gpio = &gpio_arr[led_cfg->gpio[i]]; ++ state_entry->mode = led_cfg->mode[i]; ++ state_entry->module_id = module->module_id; ++ state_entry->handler = led_mode_handler[state_entry->mode]; ++ state_entry->timer_running = 0; ++ ++ if(REQUIRES_TIMER(led_cfg->mode[i])) /* requires timer */ ++ { ++ ++ state_entry->param = led_cfg->param1; ++ ++ if(led_cfg->mode[i] == LED_FLASH) ++ state_entry->param |= (led_cfg->param2 << 16); ++ ++ if(!(state_entry->os_timer)) ++ state_entry->os_timer = os_timer_init(led_timer_func); ++ } ++ ++ if(i == led_cfg->gpio_num - 1) ++ { ++ free_state(state_entry->next); ++ state_entry->next = NULL; ++ break; ++ } ++ ++ ++ /* allocate next node */ ++ else if( !(state_entry->next)) ++ { ++ state_entry->next = led_malloc(sizeof(STATE_ENTRY_T)); ++ } ++ ++ state_entry = state_entry->next; ++ ++ ++ } ++ ++ } ++ else ++ { ++ log_msg("ERROR:State Count exceeded\n"); ++ goto config_failed; ++ } ++ ++ return 0; ++ ++ config_failed: ++ ++ return -1; ++ ++ ++ ++} ++ ++ /*********************************************************/ ++ ++void *avalanche_led_register(const char * mod_name,int instance) ++{ ++ void *p; ++ p = get_module((void * )mod_name,instance); ++ return p; ++ } ++ ++ ++int avalanche_led_action(void *module, int state_id) ++{ ++ ++ if(module && state_id < MAX_STATE_ENTRIES) ++ { ++ ++ STATE_ENTRY_T *state =((MODULE_INSTANCE_T *)(module))->states[state_id]; ++ while(state) ++ { ++ if(state->timer_running == 0) ++ { ++ state->handler(state); ++ } ++ state = state->next; ++ ++ } ++ } ++ return 0; ++} ++ ++ ++ ++int led_get_dsl_config(void) ++{ ++ ++ int state_id = 0; ++ LED_CONFIG_T led_cfg; ++ int state_count = 0; ++ ++ os_strcpy(led_cfg.name,"adsl"); ++ ++ for(state_id = 0; state_id < MAX_STATE_ENTRIES;state_id++) ++ { ++ if(avalanche_led_config_get(&led_cfg,-1,0,state_id) == 0) ++ { ++ /* call configure */ ++ avalanche_led_set_config(&led_cfg); ++ state_count++; ++ } ++ ++ } ++ return state_count; ++ ++ ++} ++ ++ ++void register_led_drv(int led_num,led_reg_t *led) ++{ ++ ++ /* DSL leds are numbered from 3 to 6 */ ++ int led_index = led_num - 3; ++ ++ if(led_index >=0 && led_index <= 2) ++ { ++ adsl_led_objs[led_index] = *led; ++ ++ if(adsl_led_objs[led_index].init) ++ adsl_led_objs[led_index].init(adsl_led_objs[led_index].param); ++ } ++ ++} ++ ++void deregister_led_drv( int led_num) ++{ ++ /* DSL leds are numbered from 3 to 6 */ ++ int led_index = led_num - 3; ++ ++ if(led_index >=0 && led_index <= 2) ++ { ++ adsl_led_objs[led_index].onfunc = NULL; ++ adsl_led_objs[led_index].offfunc = NULL; ++ } ++ return; ++} ++ ++void led_operation(int mod,int state_id) ++{ ++ static int configured = 0; ++ ++ if(configured == 0) ++ { ++ configured = led_get_dsl_config(); ++ } ++ ++ avalanche_led_action(dsl_mod,state_id); ++} ++ ++static int __init led_init(void) ++{ ++ GPIO_REGS_T gpio_regs; ++ ++ gpio_regs.gpio_write_reg = NULL; ++ gpio_regs.gpio_dir_reg = NULL; ++ gpio_regs.gpio_mode_reg = NULL; ++ ++ led_hal_init(gpio_regs,gpio_off_state,AVALANCHE_GPIO_PIN_COUNT); ++ ++ /* register instance 0 of adsl module */ ++ dsl_mod = avalanche_led_register("adsl",0); ++ return 0; ++ ++} ++ ++__initcall(led_init); ++ ++ ++ ++EXPORT_SYMBOL_NOVERS(led_init); ++EXPORT_SYMBOL_NOVERS(led_operation); ++EXPORT_SYMBOL_NOVERS(register_led_drv); ++EXPORT_SYMBOL_NOVERS(deregister_led_drv); ++ +diff -urN kernel-old/drivers/char/avalanche_led/Makefile kernel-current/drivers/char/avalanche_led/Makefile +--- kernel-old/drivers/char/avalanche_led/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ kernel-current/drivers/char/avalanche_led/Makefile 2005-07-10 18:25:32.692328160 +0200 +@@ -0,0 +1,23 @@ ++# File: drivers/char/avalanche_led/Makefile ++# ++# Makefile for the Linux LED device driver. ++# ++ ++ ++O_TARGET := avalanche_led.o ++obj-m := avalanche_led.o ++list-multi := avalanche_led.o ++ ++EXTRA_CFLAGS := -I$(TOPDIR)/include/asm/ar7 ++ ++export-objs := led_drv.o led_wrapper.o ++ ++avalanche_led-objs := led_hal.o led_drv.o led_wrapper.o ++ ++include $(TOPDIR)/Rules.make ++ ++avalanche_led.o: $(avalanche_led-objs) ++ $(LD) -r -o $@ $(avalanche_led-objs) ++ ++clean: ++ rm -f core *.o *.a *.s +diff -urN kernel-old/drivers/char/Config.in kernel-current/drivers/char/Config.in +--- kernel-old/drivers/char/Config.in 2005-07-10 02:55:18.318811000 +0200 ++++ kernel-current/drivers/char/Config.in 2005-07-10 18:03:46.121957048 +0200 +@@ -133,6 +133,10 @@ + fi + fi + fi ++if [ "$CONFIG_AR7" = "y" ]; then ++ bool 'Enable LED support' CONFIG_MIPS_AVALANCHE_LED ++fi ++ + if [ "$CONFIG_EXPERIMENTAL" = "y" -a "$CONFIG_ZORRO" = "y" ]; then + tristate 'Commodore A2232 serial support (EXPERIMENTAL)' CONFIG_A2232 + fi +diff -urN kernel-old/drivers/char/Makefile kernel-current/drivers/char/Makefile +--- kernel-old/drivers/char/Makefile 2005-07-10 02:55:18.319811000 +0200 ++++ kernel-current/drivers/char/Makefile 2005-07-10 18:03:46.122956896 +0200 +@@ -190,6 +190,19 @@ + obj-$(CONFIG_PCI) += keyboard.o $(KEYMAP) + endif + ++# ++# Texas Intruments LED driver ++# ++ifeq ($(CONFIG_MIPS_AVALANCHE_LED),y) ++obj-$(CONFIG_MIPS_AVALANCHE_LED) += avalanche_led/avalanche_led.o ++subdir-$(CONFIG_MIPS_AVALANCHE_LED) += avalanche_led ++endif ++ ++ifeq ($(CONFIG_MIPS_AVALANCHE_LED),m) ++obj-$(CONFIG_MIPS_AVALANCHE_LED) += avalanche_led/avalanche_led.o ++subdir-$(CONFIG_MIPS_AVALANCHE_LED) += avalanche_led ++endif ++ + obj-$(CONFIG_HIL) += hp_keyb.o + obj-$(CONFIG_MAGIC_SYSRQ) += sysrq.o + obj-$(CONFIG_ATARI_DSP56K) += dsp56k.o +diff -urN kernel-old/include/asm-mips/ar7/ledapp.h kernel-current/include/asm-mips/ar7/ledapp.h +--- kernel-old/include/asm-mips/ar7/ledapp.h 1970-01-01 01:00:00.000000000 +0100 ++++ kernel-current/include/asm-mips/ar7/ledapp.h 2005-07-10 18:49:37.556426688 +0200 +@@ -0,0 +1,59 @@ ++#ifndef __LED_APP__ ++#define __LED_APP__ ++ ++#define CONF_FILE "/etc/led.conf" ++#define LED_PROC_FILE "/proc/led_mod/led" ++ ++#define CONFIG_LED_MODULE ++ ++#define MAX_MOD_ID 25 ++#define MAX_STATE_ID 25 ++#define MAX_LED_ID 25 ++ ++#define MOD_ADSL 1 ++#define DEF_ADSL_IDLE 1 ++#define DEF_ADSL_TRAINING 2 ++#define DEF_ADSL_SYNC 3 ++#define DEF_ADSL_ACTIVITY 4 ++ ++#define MOD_WAN 2 ++#define DEF_WAN_IDLE 1 ++#define DEF_WAN_NEGOTIATE 2 ++#define DEF_WAN_SESSION 3 ++ ++#define MOD_LAN 3 ++#define DEF_LAN_IDLE 1 ++#define DEF_LAN_LINK_UP 2 ++#define DEF_LAN_ACTIVITY 3 ++ ++#define MOD_WLAN 4 ++#define DEF_WLAN_IDLE 1 ++#define DEF_WLAN_LINK_UP 2 ++#define DEF_WLAN_ACTIVITY 3 ++ ++#define MOD_USB 5 ++#define DEF_USB_IDLE 1 ++#define DEF_USB_LINK_UP 2 ++#define DEF_USB_ACTIVITY 3 ++ ++#define MOD_ETH 6 ++#define DEF_ETH_IDLE 1 ++#define DEF_ETH_LINK_UP 2 ++#define DEF_ETH_ACTIVITY 3 ++ ++typedef struct config_elem{ ++ unsigned char name; ++ unsigned char state; ++ unsigned char mode; ++ unsigned char led; ++ int param; ++}config_elem_t; ++ ++typedef struct led_reg{ ++ unsigned int param; ++ void (*init)(unsigned long param); ++ void (*onfunc)(unsigned long param); ++ void (*offfunc)(unsigned long param); ++}led_reg_t; ++ ++#endif +diff -urN kernel-old/include/asm-mips/ar7/led_config.h kernel-current/include/asm-mips/ar7/led_config.h +--- kernel-old/include/asm-mips/ar7/led_config.h 1970-01-01 01:00:00.000000000 +0100 ++++ kernel-current/include/asm-mips/ar7/led_config.h 2005-07-10 18:03:46.122956896 +0200 +@@ -0,0 +1,51 @@ ++/****************************************************************************** ++ * FILE PURPOSE: - LED config Header ++ ****************************************************************************** ++ * FILE NAME: led_config.h ++ * ++ * DESCRIPTION: Header file for LED configuration parameters ++ * and data structures ++ * ++ * REVISION HISTORY: ++ * 11 Oct 03 - PSP TII ++ * ++ * (C) Copyright 2002, Texas Instruments, Inc ++ *******************************************************************************/ ++ ++ ++#ifndef __LED_CONFIG__ ++#define __LED_CONFIG__ ++ ++/* LED config parameters */ ++#define MAX_GPIO_PIN_NUM 64 ++#define MAX_GPIOS_PER_STATE 2 ++#define MAX_MODULE_ENTRIES 25 ++#define MAX_MODULE_INSTANCES 2 ++#define MAX_STATE_ENTRIES 25 ++#define NUM_LED_MODES 5 ++#define MAX_LED_ENTRIES 25 ++ ++ ++/* LED modes */ ++#define LED_OFF 0 ++#define LED_ON 1 ++#define LED_ONESHOT_OFF 2 ++#define LED_ONESHOT_ON 3 ++#define LED_FLASH 4 ++ ++ ++ ++/* Data structure for LED configuration */ ++typedef struct led_config{ ++ unsigned char name[80]; ++ unsigned int instance; ++ unsigned int state; ++ unsigned int gpio[MAX_GPIOS_PER_STATE]; ++ unsigned int mode[MAX_GPIOS_PER_STATE]; ++ unsigned int gpio_num; ++ unsigned int param1; ++ unsigned int param2; ++}LED_CONFIG_T; ++ ++ ++#endif /* __LED_CONFIG__ */ +diff -urN kernel-old/include/asm-mips/ar7/led_ioctl.h kernel-current/include/asm-mips/ar7/led_ioctl.h +--- kernel-old/include/asm-mips/ar7/led_ioctl.h 1970-01-01 01:00:00.000000000 +0100 ++++ kernel-current/include/asm-mips/ar7/led_ioctl.h 2005-07-10 18:03:46.122956896 +0200 +@@ -0,0 +1,32 @@ ++/****************************************************************************** ++ * FILE PURPOSE: - LED ioctl Header ++ ****************************************************************************** ++ * FILE NAME: led_ioctl.h ++ * ++ * DESCRIPTION: Header file defining macros for ioctl commands. ++ * ++ * REVISION HISTORY: ++ * 11 Oct 03 - PSP TII ++ * ++ * (C) Copyright 2002, Texas Instruments, Inc ++ *******************************************************************************/ ++#ifndef __LED_IOCTL__ ++#define __LED_IOCTL__ ++ ++typedef struct led_mod{ ++unsigned char *name; ++unsigned int instance; ++unsigned int handle; ++}LED_MODULE_T; ++ ++typedef struct led_state{ ++unsigned int handle; ++unsigned int state_id; ++}LED_STATE_T; ++ ++#define LED_CONFIG 0 ++#define LED_GET_HANDLE 1 ++#define LED_ACTION 2 ++#define LED_RELEASE_HANDLE 3 ++ ++#endif /* __LED_IOCTL__ */ |