/****************************************************************************** * 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 * * 16 Dec 2003 Updates for 5.7 Sharath Kumar * * 07 Jan 2004 Wrapper for DSL Sharath Kumar * * (C) Copyright 2002, Texas Instruments, Inc *******************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "led_config.h" #include "led_hal.h" #include "led_ioctl.h" #include "led_platform.h" /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ MODULE_LICENSE("\n(C) Copyright 2003, Texas Instruments, Inc\n(C) Copyright 2004, AVM"); /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ #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 TI_LED_VERSION "1.0" #define GPIO_MAP_LEN ((MAX_GPIO_PIN_NUM/32) + 1) static int gpio_off_state[GPIO_MAP_LEN] = AVALANCHE_GPIO_OFF_MAP; static int led_ioctl( struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg ) { int ret = 0; // char name[80]; DEB_TRACE("[led_ioctl]: cmd = %u\n", cmd); switch ( cmd ) { case LED_CONFIG: { LED_CONFIG_T led_cfg; if (copy_from_user((char *)&led_cfg, (char *)arg, sizeof(led_cfg))) { ret = -EFAULT; break; } DEB_TRACE("[led_ioctl/LED_CONFIG]: led_cfg: name=%s instance=%u state=%u gpio_num=%u param1=%u param2=%u\n", led_cfg.name, led_cfg.instance, led_cfg.state, /*--- unsigned int gpio[MAX_GPIOS_PER_STATE]; ---*/ /*--- unsigned int mode[MAX_GPIOS_PER_STATE]; ---*/ led_cfg.gpio_num, led_cfg.param1, led_cfg.param2); ret = avalanche_led_config_set(&led_cfg); } break; case LED_CONFIG_DONE: DEB_TRACE("[led_ioctl/LED_CONFIG_DONE]: \n"); avalanche_led_late_actions(); ret = 0; 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; } DEB_TRACE("[led_ioctl/LED_GET_HANDLE]: led_mod: name=%s instance=%u\n", led_mod.name, led_mod.instance); 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; } DEB_TRACE("[led_ioctl/LED_GET_HANDLE]: led_mod: handle=0x%x\n", handle); 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; } DEB_TRACE("[led_ioctl/LED_ACTION]: led_state: handle=0x%x state=%u\n", led_state.handle, led_state.state_id); avalanche_led_action((void *)led_state.handle, led_state.state_id); } break; case LED_RELEASE_HANDLE: DEB_TRACE("[led_ioctl/LED_RELEASE_HANDLE]: handle=0x%x\n", arg); 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,"TI 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 i; int len=0; int limit = count - 80; char *msg[NUM_LED_MODES] = { "LED OFF", "LED_ON", "LED_ONESHOT_OFF", "LED_ONESHOT_ON", "LED_FLASH", "LED_BLINK_CODE" }; for(mod_count = 0;mod_count 1) { if(len <= limit) len += sprintf(buf + len, " number of gpios: %u\n", led_cfg.gpio_num); } for(i = 0 ; i < led_cfg.gpio_num ; i++) { if(len <= limit) len+= sprintf(buf+len, " mode: %s\n", msg[led_cfg.mode[0] % NUM_LED_MODES]); if(len <= limit) len+= sprintf(buf+len, " gpio: %d\n",led_cfg.gpio[0]); } if(len <= limit) { char *text = "param1"; switch(led_cfg.mode[0]) { case LED_ONESHOT_OFF: text = "off-time [ms]"; break; case LED_ONESHOT_ON: case LED_FLASH: case LED_BLINK_CODE: text = "on-time [ms]"; break; } len+= sprintf(buf+len, " %s: %d\n", text, led_cfg.param1); } if(len <= limit) { char *text = "param2"; switch(led_cfg.mode[0]) { case LED_FLASH: text = "off-time [ms]"; break; case LED_BLINK_CODE: text = "blink code"; break; } len+= sprintf(buf+len, " %s: %d\n", text, 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); hardware_error_init(); 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);