/****************************************************************************** * 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 * * 16 Dec 2003 Updates for 5.7 Sharath Kumar * * 07 Jan 2004 Wrapper for DSL Sharath Kumar * * (C) Copyright 2002, Texas Instruments, Inc *******************************************************************************/ #include "led_platform.h" #include "led_config.h" #include "led_hal.h" /* include for gpio APIs */ #include "avalanche_misc.h" /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ #if 0 #define DEB_ERR(args...) printk(KERN_ERR args) #define DEB_WARN(args...) printk(KERN_WARNING args) #define DEB_INFO(args...) printk(KERN_INFO args) #define DEB_TRACE(args...) printk(KERN_INFO args) #else #define DEB_ERR(args...) printk(KERN_ERR args) #define DEB_WARN(args...) #define DEB_INFO(args...) #define DEB_TRACE(args...) #endif #define REQUIRES_TIMER(x) ( (x == LED_ONESHOT_ON) || (x == LED_ONESHOT_OFF) || (x == LED_FLASH) || (x == LED_BLINK_CODE)) /*******************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 instance; 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; /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ #define MAX_LATE_ACTIONS 20 static unsigned int avalanche_led_configurated = 0; static struct _avalanche_led_late_action { void *handle; int state; } avalanche_led_late_action[MAX_LATE_ACTIONS]; /******************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; } unsigned led_state[2][MAX_MODULE_INSTANCES][32]; /*--- fuer 64 LEDs ---*/ /*------------------------------------------------------------------------------------------*\ *STATE_ENTRY_T * state \*------------------------------------------------------------------------------------------*/ static void avalanche_gpio_set(int * set_map,int *pos_map, STATE_ENTRY_T *state) { unsigned int output_set_map; int i, index; #if 0 int i; for(i = 0; i < num_gpios ; i += 32) { int index = i/32; /*--- DEB_INFO("[avalanche_led/avalanche_gpio_set]: set mask 0x%x clear mask 0x%x index %u\n", set_map[index], pos_map[index], index); ---*/ avalanche_gpio_out_value(set_map[index], pos_map[index],index); } #endif DEB_INFO("avalanche_gpio_set(set: 0x%x pos: 0x%x id=%u)\n", set_map[0], pos_map[0], state->module_id); /*--------------------------------------------------------------------------------------*\ \*--------------------------------------------------------------------------------------*/ if(state->instance == 0) { for( i = 0 ; i < MAX_MODULE_ENTRIES ; i++) { int ii; if(modules[i] == 0) continue; for(ii = 0 ; ii < MAX_MODULE_INSTANCES ; ii++) { int iii; if(modules[i]->module_instance[ii] == 0) continue; for( iii = 0 ; iii < MAX_STATE_ENTRIES ; iii++) { if(modules[i]->module_instance[ii]->states[iii] == state) { DEB_INFO("[%s] module_id %u instance %u\n", (char *)(modules[i]->name ? modules[i]->name : "no name"), modules[i]->module_instance[ii]->module_id, modules[i]->module_instance[ii]->instance); state->instance = modules[i]->module_instance[ii]->instance + 1; goto found; } } } } } found: /*--------------------------------------------------------------------------------------*\ * fuer alle möglichen LEDs \*--------------------------------------------------------------------------------------*/ for(index = 0 ; index < (num_gpios / 32) ; index++) { unsigned int bit_pos = state->module_id; output_set_map = 0; if(bit_pos >= 32) { DEB_INFO("[avalanche_gpio_set] ERROR: led_state Bit mask to large %u\n", bit_pos); return; } for(i = 0 ; i < 32 ; i++) { int ii; /*----------------------------------------------------------------------------------*\ * fuer jede LED die in pos_map gesetzt ist das zur instanz gehöhrende Bit in * led_state löschen \*----------------------------------------------------------------------------------*/ if(pos_map[index] & (1 << i)) { led_state[index][state->instance - 1][i] &= ~(1 << bit_pos); } else { continue; } /*----------------------------------------------------------------------------------*\ * fuer jede LED die in set_map gesetzt ist das zur instanz gehöhrende Bit in * led_state setzen \*----------------------------------------------------------------------------------*/ if((set_map[index] & (1 << i)) == 0) { led_state[index][state->instance - 1][i] |= (1 << bit_pos); } /*----------------------------------------------------------------------------------*\ * das Bit in der output set mask setzen wenn irgend ein Bit in dem entsprechenden * led_state gesetzt ist. \*----------------------------------------------------------------------------------*/ for(ii = 0 ; ii < MAX_MODULE_INSTANCES ; ii++) { if(led_state[index][ii][i]) { output_set_map |= 1 << i; break; } } } output_set_map = ~output_set_map & pos_map[index]; DEB_INFO("avalanche_gpio_set(output: 0x%x pos: 0x%x id=%u, index=%u)\n", output_set_map, pos_map[index], state->module_id, index); avalanche_gpio_out_value(output_set_map, pos_map[index], index); } } /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ static MODULE_INSTANCE_T *get_module (char *name, int instance) { int module_id; MODULE_INSTANCE_T *mod_inst; DEB_INFO("[avalanche_led/get_module]: find: name=%s instance=%u\n", name, instance); if (instance >= MAX_MODULE_INSTANCES) { DEB_ERR("[avalanche_led/get_module]: instance > MAX_MODULE_INSTANCES (%u)\n", 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)) { DEB_INFO("[avalanche_led/get_module]: module found module_id=%u name=%s\n", 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]) { DEB_ERR("[avalanche_led/get_module]: module (%u) not vallid\n", module_id); return NULL; } modules[module_id]->name = led_malloc (os_strlen (name) + 1); if (!modules[module_id]->name) { DEB_ERR("[avalanche_led/get_module]: module (%u) has no name\n", module_id); 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]) { DEB_ERR("[avalanche_led/get_module]: instance (%u) not vallid\n", instance); return NULL; } mod_inst = modules[module_id]->module_instance[instance]; mod_inst->module_id = module_id; mod_inst->instance = instance; DEB_INFO("[avalanche_led/get_module]: handle=0x%x\n", (void *)mod_inst); 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; MUTEX_GET (led_lock); state->timer_running = 0; led->state = LED_OFF; avalanche_gpio_set (state->map2, led->pos_map, state); 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; MUTEX_GET (led_lock); state->timer_running = 0; led->state = LED_ON; avalanche_gpio_set(state->map2, led->pos_map, state); 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; MUTEX_GET (led_lock); if (led->state != LED_FLASH) { state->timer_running = 0; MUTEX_RELEASE (led_lock); DEB_INFO("[led_flash_timer_func] state != LED_FLASH: stop timer\n"); return; } if (state->timer_running == 1) { state->timer_running = 2; avalanche_gpio_set(state->map2, led->pos_map, state); os_timer_add (state->os_timer, state->param2, (int)state); } else { state->timer_running = 1; avalanche_gpio_set(state->map1, led->pos_map, state); os_timer_add (state->os_timer, state->param1, (int)state); } MUTEX_RELEASE (led_lock); } /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ static void led_blink_code_timer_func (int arg) { STATE_ENTRY_T *state = (STATE_ENTRY_T *) arg; LED_OBJ_T *led = state->led; MUTEX_GET (led_lock); if (led->state != LED_BLINK_CODE) { state->timer_running = 0; MUTEX_RELEASE (led_lock); DEB_INFO("[led_blink_code_timer_func] state != LED_FLASH: stop timer\n"); return; } if(state->timer_running <= (state->param2 << 1)) { if (state->timer_running & 0x01) { /*--- ausschalten ---*/ state->timer_running++; avalanche_gpio_set(state->map2, led->pos_map, state); os_timer_add (state->os_timer, state->param1, (int)state); } else { /*--- einschalten ---*/ state->timer_running++; avalanche_gpio_set(state->map1, led->pos_map, state); os_timer_add (state->os_timer, state->param1, (int)state); } } else { /*--- ausschalten und pause ---*/ state->timer_running = 1; avalanche_gpio_set(state->map2, led->pos_map, state); os_timer_add (state->os_timer, state->param1 * 4, (int)state); } MUTEX_RELEASE (led_lock); } /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ static void led_on(STATE_ENTRY_T * state) { LED_OBJ_T *led = state->led; DEB_INFO("[led_on]: pos 0x%X\n", led->pos_map[0]); led->state = LED_ON; avalanche_gpio_set(state->map1, led->pos_map, state); led->module_map |= (1 << (state->module_id)); } /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ static void led_off (STATE_ENTRY_T * state) { LED_OBJ_T *led = state->led; DEB_INFO("[led_off]: pos 0x%X\n", led->pos_map[0]); led->module_map &= ~(1 << (state->module_id)); if (!led->module_map) { led->state = LED_OFF; avalanche_gpio_set(state->map1, led->pos_map, state); } } /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ static void led_oneshot_on (STATE_ENTRY_T * state) { LED_OBJ_T *led = state->led; DEB_INFO("[led_oneshot_on]: pos 0x%X\n", led->pos_map[0]); if (state->timer_running) { DEB_WARN("[led_oneshot_on]: pos 0x%X, cancel: timer still running\n", led->pos_map[0]); return; } state->timer_running = 1; led->state = LED_ON; avalanche_gpio_set(state->map1, led->pos_map, state); 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; DEB_INFO("[led_oneshot_off]: pos 0x%X\n", led->pos_map[0]); if (state->timer_running) { DEB_WARN("[led_oneshot_off]: pos 0x%X, cancel: timer still running\n", led->pos_map[0]); return; } state->timer_running = 1; led->state = LED_OFF; avalanche_gpio_set(state->map1, led->pos_map, state); os_timer_add (state->os_timer, state->param1,(int) state); } /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ static void led_flash (STATE_ENTRY_T * state) { LED_OBJ_T *led = state->led; DEB_INFO("[led_flash]: pos 0x%X\n", led->pos_map[0]); if (state->timer_running) { DEB_WARN("[led_flash]: pos 0x%X, cancel: timer still running\n", led->pos_map[0]); return; } state->timer_running = 1; led->state = LED_FLASH; avalanche_gpio_set(state->map1, led->pos_map, state); os_timer_add (state->os_timer, state->param1,(int) state); } /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ static void led_blink_code (STATE_ENTRY_T * state) { LED_OBJ_T *led = state->led; DEB_INFO("[led_blink_code]: pos 0x%Xn", led->pos_map[0]); if (state->timer_running) { DEB_WARN("[led_blink_code]: pos 0x%X cancel: timer still running\n", led->pos_map[0]); return; } state->timer_running = 1; led->state = LED_BLINK_CODE; avalanche_gpio_set(state->map1, led->pos_map, state); 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; case LED_BLINK_CODE: state_entry->os_timer = os_timer_init(led_blink_code_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: case LED_BLINK_CODE: 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++) { avalanche_gpio_ctrl(led_cfg->gpio[i], GPIO_PIN, GPIO_OUTPUT_PIN); } 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; led_mode_handler[LED_BLINK_CODE] = led_blink_code; memset(&led_state, 0, sizeof(led_state)); 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; } /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ void avalanche_led_late_actions(void) { int i; avalanche_led_configurated = 1; for(i = 0 ; i < MAX_LATE_ACTIONS ; i++) { if(avalanche_led_late_action[i].handle) { DEB_INFO("[avalanche_led_late_actions]: set state %u for handle 0x%x\n", avalanche_led_late_action[i].state, avalanche_led_late_action[i].handle); avalanche_led_action(avalanche_led_late_action[i].handle, avalanche_led_late_action[i].state | 0x8000); avalanche_led_late_action[i].handle = NULL; } } avalanche_led_configurated = 2; } /************************************************************************** * 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(avalanche_led_configurated == 0) { int i; if(module == NULL) { DEB_ERR("[avalanche_led_action] no handle\n"); MUTEX_RELEASE (led_lock); return; } for(i = 0 ; i < MAX_LATE_ACTIONS ; i++) { if(avalanche_led_late_action[i].handle == module) { avalanche_led_late_action[i].state = state_id; DEB_INFO("[avalanche_led_action]: save state %u for known handle 0x%x\n", avalanche_led_late_action[i].state, avalanche_led_late_action[i].handle); break; } if(avalanche_led_late_action[i].handle == NULL) { avalanche_led_late_action[i].handle = module; avalanche_led_late_action[i].state = state_id; DEB_INFO("[avalanche_led_action]: save state %u for new handle 0x%x\n", avalanche_led_late_action[i].state, avalanche_led_late_action[i].handle); break; } } MUTEX_RELEASE (led_lock); return; } if(avalanche_led_configurated == 1) { if(state_id & 0x8000) { state_id &= ~0x8000; } else { MUTEX_RELEASE (led_lock); return; } } if (module && (state_id < MAX_STATE_ENTRIES)) { STATE_ENTRY_T *state = ((MODULE_INSTANCE_T *) (module))->states[state_id]; if (state) { state->handler (state); } else { #if 0 int id = ((MODULE_INSTANCE_T *) (module))->module_id; char *name = modules[id]->name; name = name ? name : "unknown"; DEB_WARN("[avalanche_led_action]: '%s' state_id %u not vallid\n", name, state_id); #endif } } else { DEB_ERR("[avalanche_led_action]: ERROR: module = 0x%x (null) or state_id(%u) >= MAX(%u)\n", module, state_id, MAX_STATE_ENTRIES); } 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(void) { free_all_states(); } /************************************************************************** * FUNCTION NAME : avalanche_led_hal_exit ************************************************************************** * DESCRIPTION : * The function releases all the allocated memory * ***************************************************************************/ void avalanche_led_hal_exit(void) { 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; }